Code archives/Graphics/Basic ASCII text module
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| Module for drawing text using a fixed width, ASCII ordered image font. It's very basic, but some might find it useful. Updated 18 NOV 2010: Now includes block text functionality. Updated 19 NOV 2010: Draw now recognises the new line escape character(~n) and Null strings. You can also download it here complete with example. | |||||
'Ascii bitmap font rendering
SuperStrict
Rem
bbdoc: Gaphics/AsciiFont
End Rem
Module ODD.AsciiFont
ModuleInfo "Version: 1.3"
ModuleInfo "Author: David Williamson"
ModuleInfo "License: Public Domain"
ModuleInfo "History: 1.3"
ModuleInfo " : Draw now recognises the newline escape character and Null strings."
ModuleInfo "History: 1.2"
ModuleInfo " : Added block text and line-spacing."
ModuleInfo "History: 1.1"
ModuleInfo " : Added letter-spacing."
ModuleInfo "History: 1.0"
ModuleInfo " : Initial release."
Import BRL.Max2D
Const ASCII_PADDED:Int=16
Const ASCII_EXTENDED:Int=32
Const ALIGN_LEFT:Int=-1
Const ALIGN_RIGHT:Int=1
Const ALIGN_TOP:Int=-1
Const ALIGN_BOTTOM:Int=1
Const ALIGN_CENTER:Int=0
Type TAsciiFont
Field img:TImage, _width:Int, _height:Int, _letterSpacing:Int, _lineSpacing:Int
Field frontPad:Int, extended:Int
Rem
bbdoc: Loads an ascii font from an image file
returns: An ascii font object
about: Loads a fixed width ascii ordered font for rendering.
@flags are the standard #LoadImage flags with two ascii font specific additions
[ @ASCII_PADDED | The image contains the first 32 unprintable characters
* @ASCII_EXTENDED | The image contains the extended ascii characters(128-255)
]
End Rem
Function Load:TAsciiFont( url:Object, width:Int, height:Int, flags:Int=0 )
Local af:TAsciiFont=New TAsciiFont
af.frontPad=flags&ASCII_PADDED
af.extended=flags&ASCII_EXTENDED
Local fCount:Int=96
If af.frontPad Then fCount:+32
If af.extended Then fCount:+128
af.img=LoadAnimImage(url,width,height,0,fCount,flags)
af._width=width;af._height=height;af._letterSpacing=0;af._lineSpacing=0
If af.img Then Return af Else Return Null
End Function
Rem
bbdoc: Sets the font's letter-spacing and line-spacing
about: Sets the letter-spacing and line-spacing of the font. A negative spacing will cause the letters to overlap.
EndRem
Method SetSpacing( letterSpacing:Int, lineSpacing:Int=0 )
_letterSpacing=letterSpacing
_lineSpacing=lineSpacing
End Method
Rem
bbdoc: Draws text on the screen
about: Draws text at position @x, @y. @horAlign and @vertAlign discribes how the text is aligned. The values are @ALIGN_LEFT, @ALIGN_RIGHT, @ALIGN_TOP, @ALIGN_BOTTOM, @ALIGN_CENTER.
If a width, @w, is specified then the text exeeding that value will be displayed over multiple lines, otherwise text is displayed on a single line.
Draw ignores the current Max2D rotation.
EndRem
Method Draw( text:String, x:Float, y:Float, horAlign:Int=ALIGN_LEFT, vertAlign:Int=ALIGN_TOP, w:Int=0 )
If text="" Then Return
If text.Contains("~n")
Local blocks:String[]=text.Split("~n")
Local xScale:Float, yScale:Float
GetScale xScale, yScale
Local h:Int[]=New Int[blocks.length]
Local align:Float
For Local count:Int=0 Until blocks.length
h[count]=height(blocks[count],w)
align:+(h[count]+_lineSpacing)*yScale
Next
align:-_lineSpacing*yScale
align:*.5
y:-(align+align*vertAlign)
For Local count:Int=0 Until blocks.length
Draw blocks[count],x,y,horAlign,vertAlign,w
y:+h[count]*yScale
Next
ElseIf w>0
Local lineWidth:Int
lineWidth=Floor(w/Float(_width+_letterSpacing))
If lineWidth<2 Then Return
Local words:String[]=text.Split(" ")
Local lines:String[]=New String[text.length]
Local lIndex:Int=0
Local wIndex:Int=0
While wIndex<words.length
lines[lIndex]=words[wIndex]
While lines[lIndex].length>lineWidth
lines[lIndex+1]=lines[lIndex][lineWidth-1..]
lines[lIndex]=lines[lIndex][..lineWidth-1]+"-"
lIndex:+1
Wend
wIndex:+1
While wIndex<words.length And lines[lIndex].length+words[wIndex].length+1<lineWidth
lines[lIndex]:+" "+words[wIndex]
wIndex:+1
Wend
lIndex:+1
Wend
Local xScale:Float, yScale:Float
GetScale xScale, yScale
Local align:Float=(((_height+_lineSpacing)*lIndex)-_lineSpacing)*.5*yScale
y:-(align+align*vertAlign)
For Local count:Int=0 To lIndex
Draw lines[count],x,y+(count*(_height+_lineSpacing)*yScale),horAlign
Next
Else
Local rot:Float=GetRotation()
Local xScale:Float, yScale:Float
GetScale xScale, yScale
Local fOffset:Int=0
If Not frontPad Then fOffset=-32
Local a:Int
Local align:Float=Width(text)*.5*xScale
x:-(align+align*horAlign)
align=_height*.5*yScale
y:-(align+align*vertAlign)
For Local count:Int=0 Until text.length
a=text[count]
If Not(extended) And a>=128 Then Continue
DrawImage img,x+(count*(_width+_letterSpacing)*xScale),y,a+fOffset
Next
SetRotation rot
EndIf
End Method
Rem
bbdoc: Gets the total width of text
returns: The pixel width of text
about: If @text is blank then #Width returns the width of a single character.
EndRem
Method Width:Int( text:String="" )
If text Then Return ((_width+_letterSpacing)*text.length)-_letterSpacing Else Return _width
End Method
Rem
bbdoc: Gets the total height of text
returns: The pixel height of text
about: If @text is blank or @w=0 then #Height returns the height of a single character.
EndRem
Method Height:Int( text:String="", w:Int=0 )
If text="" Or w=0 Then Return _height
If text.Contains("~n")
Local blocks:String[]=text.Split("~n")
Local h:Int
For Local count:Int=0 Until blocks.length
height(blocks[count],w)
h:+height(blocks[count],w)+_lineSpacing
Next
Return h-_lineSpacing
Else
Local lineWidth:Int
lineWidth=Floor(w/Float(_width+_letterSpacing))
If lineWidth<2 Then Return 0
Local words:String[]=text.Split(" ")
Local lines:String[]=New String[text.length]
Local lIndex:Int=0
Local wIndex:Int=0
While wIndex<words.length
lines[lIndex]=words[wIndex]
While lines[lIndex].length>lineWidth
lines[lIndex+1]=lines[lIndex][lineWidth-1..]
lines[lIndex]=lines[lIndex][..lineWidth-1]+"-"
lIndex:+1
Wend
wIndex:+1
While wIndex<words.length And lines[lIndex].length+words[wIndex].length+1<lineWidth
lines[lIndex]:+" "+words[wIndex]
wIndex:+1
Wend
lIndex:+1
Wend
Return ((_height+_lineSpacing)*lIndex)-_lineSpacing
EndIf
End Method
End Type
Rem
bbdoc: Loads an ascii font from an image file
returns: An ascii font object
about: Loads a fixed width ascii ordered font for rendering.
@flags are the standard #LoadImage flags with two ascii font specific additions
[ @ASCII_PADDED | The image contains the first 32 unprintable characters
* @ASCII_EXTENDED | The image contains the extended ascii characters(128-255)
]
End Rem
Function LoadAsciiFont:TAsciiFont( url:Object, width:Int, height:Int, flags:Int=0 )
Return TAsciiFont.Load(url,width,height,flags)
End Function |
Comments
| ||
| An example of it in use Requires an ascii font image like the one below. asciifont.png |
| ||
| I have updated this to include block text functionality. Here's an example of it in use Requires the same font image in the post above. |
| ||
| Another update. Draw now recognises the new line escape character(~n) and Null strings. And here's the obligatory example of it in use |
Code Archives Forum
