Dark Bit Factory & Gravity
PROGRAMMING => General coding questions => Topic started by: Clyde on May 05, 2009
-
What I've been upto recently is designing for the very first time an un-proportional Bitmap Font.
In lamens terms images with different sizes set out in a grid to be split up for drawing to the screen.
What I am trying to put into place, is a routine that works out the start X position as an offset to be dealt with in the drawing routine.
The tiles of letter images are centered in each one based on the width, im having difficulties in working out the offsets, if there's black say on the first 4-5 lines it needs to ignore these ( it'll be different for each image tile ), plus it needs to know the shortest amount of empty / black pixels before a solid colour is reached for the OffsetX( LetterNo ) to be exact.
I'm also wondering if i need to put offsets for both the left justified and the right justified?
I am very sorry too my font is a 3rd from complete, so if you'd be so kind, can you imagine the font when thinking up a master plan.
the code is Freebasic orientated, i put it in here on the off chance someone with a different language has done similar.
Dim As Integer OffsetX( TilesAcross*TilesDown )
Sub Offsetter( ByVal WWidth, ByVal Height)
Dim as integer x,y
Dim As UInteger col
Dim As Integer FrameNum
For FrameNum=1 to TotalTiles-1 // Start at 1 as in ascii Tile at 0 is used for space.
for y=0 to Height-1
for x=0 to WWidth-1
Col=ImageTileBank[x+y*WWidth ]
If Col= 0 Then
OffsetX(FrameNum)+=1
Else
OffsetX(FrameNum)=OffsetX(FrameNum)
End If
next
next
next
End Sub
Thanks and have a great day,
Clyde.
-
Hmm ... just thinking, if you create the fonts by yourself and they
are not monosized, why not let them start at the top left corner of
the grid.
If you center them you need to check both sizes (from left,top and
from right, bottom). But maybe I didn't get something ???
Here an example, letter "L" in a grid
##......
##......
##......
####..
####..
..........
Just loop through all lines, get the X coordinate of the right-most
pixel (#) and the Y coordinate of the bottom-most pixel. Then you
can clip the letter from 0,0 to X,Y.
Guess this is not what you wanted, eh ? ::)
-
Good idea but doesn't work with " for example.
-
Good idea but doesn't work with " for example.
Doh ... well spotted, Hellfire. Guess a fixed height is required!
-
I think its a bad idea to have each character centered in a grid, it makes it much more difficult to deal with than needed. If it was me, then I would stick with a fixed height of the entire font, have all characters start at the top left, then in an array note down the top left coordinate of each character and the width. Then when you need to draw, you look into the array, find the x/y position of the top left, and your width. The height is fixed so that you have already, and you should have the information needed.
You can still position the characters in a grid on the image if you wanted to, but this isn't really needed since you store the x/y/w and you can save a lot of space by packing the characters tightly on the image. I can look for an example made with blitzbasic tomorrow I could post if you want me to.
-
Thanks all, for your wisdom.
Yeah would appreciate that Zawran dude and thanks.
I would like for the height to be variable too. I guess this would be easy to adapt. What Im after essentially too, is a tool to do this working out and save as a releveant file.
Big thanks,
Clyde.
-
Please consider spacing characters depending on context (see kerning (http://en.wikipedia.org/wiki/Kerning#Examples_of_kerned_letters)), especially when using serif fonts.
-
Most game programmers end up writing a 'chopper'. This is a program that solves these kinds of problems.
One way to make the chopper's job easier is to draw a box, say in white, around each character which defines the extents of each character. The chopper then only has to scan for the boxes and cut the characters out from inside.
Or perhaps something like this http://creators.xna.com/assets/cms/images/XNA_BitmapFontMaker_02_large.jpg (http://creators.xna.com/assets/cms/images/XNA_BitmapFontMaker_02_large.jpg)
Jim
-
here is a chopper i wrote a while back i remember i took me ages of fiddling around to get it right this is only part of the code to show you if you would like more then just ask it produces proportianal fonts no matter where the font lies in each cell or how big small each font is.
Sub NinosPrint( Font As FontEngine Ptr )
Dim As Integer Min , Max , NonPropFontSpgs
Dim As Zstring Ptr temp
Dim Posi As Integer
Dim StrPos As Integer
Temp = Allocate( Len( Font->Message ) + 1 )
*Temp = Font->Message
StrPos=0
Do
Max = FindCharEnd( Font , Temp[ StrPos ] )
Min = FindCharStart( Font , Temp[ StrPos ] )
NonPropFontSpgs = ( Max - Min )+1
DrawChar( Font , ( Font->Xpos + Posi ) - Min , Font->Ypos , Temp[ StrPos ] )
Posi += NonPropFontSpgs
StrPos += 1
Loop Until ( StrPos = Len( Font->Message ) )
DeAllocate ( Temp )
Font->YAngle += Font->SinWaveSpeed
End Sub
Function FindCharStart( Font As FontEngine Ptr , Byval Letter As String ) As Integer
Dim As Integer TmpBanks
Dim As Integer X , Y
Dim As Integer Last = Font->Width-1 , Switch = 0
Dim As Integer Ptr Drw
Drw = @Font->FontBuffer[ ( Asc( Letter ) - 32 ) * ( Font->Width * Font->Height ) ]
For Y = 0 To Font->Height - 1
For X = 0 To Font->Width-1
If ( *Drw>0 ) And Switch = 0 Then
TmpBanks = X
Switch = 1
EndIf
Drw += 1
Next
Switch = 0
If TmpBanks = 0 Then
TmpBanks = Font->Width - 1
EndIf
If TmpBanks<Last Then Last = TmpBanks
Next
If Asc( Letter ) - 32 = 0 Then Return(0)
Return Last
End Function
Function FindCharEnd( Font As FontEngine Ptr , Byval Letter As String ) As Integer
Dim As Integer TmpBanks
Dim As Integer X , Y
Dim As Integer Last = 0
Dim As Integer Ptr Drw
Drw = @Font->FontBuffer[ ( Asc( Letter ) - 32 ) * ( Font->Width * Font->Height ) ]
For Y = 0 To Font->Height - 1
For X = 0 TO Font->Width - 1
Drw += 1
If ( *Drw ) > 0 Then
TmpBanks = X
EndIf
Next
If TmpBanks>Last Then Last = TmpBanks
Next
If Asc( Letter ) - 32 = 0 Then Return( Font->Width/2 )
Return Last+1
End Function
-
Thanks ever so much Nino dude :)
Plus thanks for heads up about Choppers.
Clyde.
-
I didn't have time last night, but I found some time tonight, so here an example of doing a variable width bitmap font using BlitzPlus or Blitz3d.
http://zac-interactive.dk/temp/variablewidthbitmapfont.zip (http://zac-interactive.dk/temp/variablewidthbitmapfont.zip)
There are no kerning or other fancy stuff, just some variable width characters, thats all.
-
Thanks again gents; means alot.
Appologies for not replying sooner, have spent since Friday reformatting and installing XP And Vista with all their updates and service packs, due to a corrupted boot file; have lost a heck of a lot of code too due to this, it always seems to happen before your about to backup files. And unfortuneatly will have to re-do the entire new gravity demo at some stage, makes you want to smash up the bloody PC & Vista OS. :(
Zawran did you use a tool, or manually create your graphics map and enter the data by hand?
And Nino, I have tried to convert some of your listing, but I failed with it. I dont quite know how your setting stuff up, mainly the font. If its in one of your posted sources, I'll have a hunt for them.
Cheers and enourmous thanks,
Clyde.
-
Zawran did you use a tool, or manually create your graphics map and enter the data by hand?
The font image was made using a font creation tool I made a few years ago.