Advanced game related topics
mahan
 
Posts: 19
Joined: Sun Nov 15, 2015 9:44 pm

Rendering text on screen (bitmap font)

by mahan Tue May 17, 2016 6:54 am

I've created a small lib for SpiderBasic to render text based on bitmap fonts on the active "Screen".

The project (with a small demo) is available here: https://github.com/mahan/bitmapfont

Since SpiderBasic does not support the command ScreenOutput() like in PureBasic for drawing operations, the only things that are drawable on a Screen (OpenScreen/OpenWindowedScreen) are sprites (DisplaySprite/DisplayTransparentSprite).

The lib basically adds the function DisplayText() to your program, which you can use during the Screen rendering to write out any text(s) you like on the screen in real time.
User avatar
MrTAToad
 
Posts: 256
Joined: Sun Apr 20, 2014 11:43 am
Location: Chichester, England

Re: Rendering text on screen (bitmap font)

by MrTAToad Wed Oct 26, 2016 10:48 am

What would be the best way to do this for variable width characters, where the character layout is stored in a separate file ?
User avatar
MrTAToad
 
Posts: 256
Joined: Sun Apr 20, 2014 11:43 am
Location: Chichester, England

Re: Rendering text on screen (bitmap font)

by MrTAToad Sun Oct 30, 2016 12:59 pm

I've got the base system going for proportional bitmap font system, and as such it works well.

The main problem is how everything is loaded - it can either from a file (and get the user to select the correct file for dimensions), or either convert the bitmap to raw data, and put it, along with the dimension data into a datasection or load the graphic and then process the dimension data from a datasection.
mahan
 
Posts: 19
Joined: Sun Nov 15, 2015 9:44 pm

Re: Rendering text on screen (bitmap font)

by mahan Tue Nov 15, 2016 9:42 am

MrTAToad wrote:I've got the base system going for proportional bitmap font system, and as such it works well.


Sounds useful. Is this something you'd care to share?
User avatar
MrTAToad
 
Posts: 256
Joined: Sun Apr 20, 2014 11:43 am
Location: Chichester, England

Re: Rendering text on screen (bitmap font)

by MrTAToad Wed Nov 16, 2016 7:34 pm

The TTF to PNG program will be on my website soon (its just a modified version of Microsoft's routine), and the source can be here soon.

The good thing about this is that it should be able to handle up to 65535 characters.
User avatar
MrTAToad
 
Posts: 256
Joined: Sun Apr 20, 2014 11:43 am
Location: Chichester, England

Re: Rendering text on screen (bitmap font)

by MrTAToad Wed Nov 16, 2016 8:51 pm

This is an example of the data produced from my TTF to PNG program :

Code: Select all
; Upgraded the TTF2BMP Microsoft project to allow proportional fonts to be used with SpiderBasic
; Modified by Nicholas Kingsley
DeclareModule hiscoreFont
  Declare.s OnInitialise()
EndDeclareModule

Module hiscoreFont
  Procedure.s OnInitialise()
    Restore hiscoreFont_Data
  EndProcedure

  DataSection
  hiscoreFont_Data:

  ; This is the filename of the graphics file
    Data.s "1,HiscoreText.png"
  ; Minimum character, maximum character, number of characters
    Data.s "2,32,127,95"
  ; Character, xpos, ypos, width, height
    Data.s "3,32,8,8,6,22"
    Data.s "3,33,22,8,5,22"
    Data.s "3,34,35,8,7,22"
    Data.s "3,35,50,8,14,22"
    Data.s "3,36,72,8,12,22"
    Data.s "3,37,92,8,17,22"
    Data.s "3,38,117,8,15,22"
    Data.s "3,39,140,8,5,22"
    Data.s "3,40,153,8,7,22"
    Data.s "3,41,168,8,7,22"
    Data.s "3,42,183,8,11,22"
    Data.s "3,43,202,8,13,22"
    Data.s "3,44,223,8,5,22"
    Data.s "3,45,236,8,8,22"
    Data.s "3,46,252,8,5,22"
    Data.s "3,47,265,8,9,22"
    Data.s "3,48,8,38,12,22"
    Data.s "3,49,28,38,8,22"
    Data.s "3,50,44,38,12,22"
    Data.s "3,51,64,38,12,22"
    Data.s "3,52,84,38,14,22"
    Data.s "3,53,106,38,12,22"
    Data.s "3,54,126,38,12,22"
    Data.s "3,55,146,38,12,22"
    Data.s "3,56,166,38,12,22"
    Data.s "3,57,186,38,12,22"
    Data.s "3,58,206,38,5,22"
    Data.s "3,59,219,38,5,22"
    Data.s "3,60,232,38,13,22"
    Data.s "3,61,253,38,13,22"
    Data.s "3,62,274,38,13,22"
    Data.s "3,63,295,38,11,22"
    Data.s "3,64,8,68,18,22"
    Data.s "3,65,34,68,14,22"
    Data.s "3,66,56,68,13,22"
    Data.s "3,67,77,68,13,22"
    Data.s "3,68,98,68,13,22"
    Data.s "3,69,119,68,12,22"
    Data.s "3,70,139,68,11,22"
    Data.s "3,71,158,68,13,22"
    Data.s "3,72,179,68,13,22"
    Data.s "3,73,200,68,5,22"
    Data.s "3,74,213,68,12,22"
    Data.s "3,75,233,68,13,22"
    Data.s "3,76,254,68,12,22"
    Data.s "3,77,274,68,16,22"
    Data.s "3,78,298,68,13,22"
    Data.s "3,79,319,68,13,22"
    Data.s "3,80,8,98,12,22"
    Data.s "3,81,28,98,13,22"
    Data.s "3,82,49,98,13,22"
    Data.s "3,83,70,98,14,22"
    Data.s "3,84,92,98,13,22"
    Data.s "3,85,113,98,13,22"
    Data.s "3,86,134,98,14,22"
    Data.s "3,87,156,98,19,22"
    Data.s "3,88,183,98,15,22"
    Data.s "3,89,206,98,15,22"
    Data.s "3,90,229,98,12,22"
    Data.s "3,91,249,98,7,22"
    Data.s "3,92,264,98,9,22"
    Data.s "3,93,281,98,7,22"
    Data.s "3,94,296,98,13,22"
    Data.s "3,95,317,98,11,22"
    Data.s "3,96,8,128,6,22"
    Data.s "3,97,22,128,10,22"
    Data.s "3,98,40,128,11,22"
    Data.s "3,99,59,128,11,22"
    Data.s "3,100,78,128,10,22"
    Data.s "3,101,96,128,11,22"
    Data.s "3,102,115,128,9,22"
    Data.s "3,103,132,128,10,22"
    Data.s "3,104,150,128,10,22"
    Data.s "3,105,168,128,5,22"
    Data.s "3,106,181,128,6,22"
    Data.s "3,107,195,128,10,22"
    Data.s "3,108,213,128,5,22"
    Data.s "3,109,226,128,15,22"
    Data.s "3,110,249,128,10,22"
    Data.s "3,111,267,128,11,22"
    Data.s "3,112,8,158,11,22"
    Data.s "3,113,27,158,10,22"
    Data.s "3,114,45,158,10,22"
    Data.s "3,115,63,158,11,22"
    Data.s "3,116,82,158,10,22"
    Data.s "3,117,100,158,10,22"
    Data.s "3,118,118,158,11,22"
    Data.s "3,119,137,158,15,22"
    Data.s "3,120,160,158,11,22"
    Data.s "3,121,179,158,11,22"
    Data.s "3,122,198,158,10,22"
    Data.s "3,123,216,158,9,22"
    Data.s "3,124,233,158,5,22"
    Data.s "3,125,246,158,9,22"
    Data.s "3,126,263,158,14,22"
    Data.s ""
  EndDataSection
EndModule


The actual bitmap printing is :

Code: Select all
  Procedure.b ProcessBitmapFonts(*loadingManager._LOADINGMANAGER)
    Define line.s
    Define code.s
    Define char.i
    Define mapName.s  = ""
    ;Define minCode.i,maxCode.i,char.i
   
    If *loadingManager<>#Null
       If *loadingManager\bitmapFontInit<>#Null
        mapName=*loadingManager\bitmapFontInit()
        If Len(mapName)>0       
            Read.s line
            While Len(line)>0
              If Left(line,1)<>";"
                ; Ignore comments
                code=StringField(line,1,",")
                Select code
                  Case  "1" ; Graphic filename
                              bitmapFonts(mapName)\spriteID=loadingManager()\index
                   
                  Case  "2" ; Range of characters
                              bitmapFonts(mapName)\minChar=Val(StringField(line,2,","))
                              bitmapFonts(mapName)\maxChar=Val(StringField(line,3,","))
                              bitmapFonts(mapName)\numChars=bitmapFonts(mapName)\maxChar-bitmapFonts(mapName)\minChar
                              Dim bitmapFonts(mapName)\chars(bitmapFonts(mapName)\numChars)
                             
                  Case  "3" ; Data
                              char=Val(StringField(line,2,","))-bitmapFonts(mapName)\minChar
                              Debug "Char : "+Str(char)+" "+line
                              If char>=0 And char<ArraySize(bitmapFonts(mapName)\chars())
                                bitmapFonts(mapName)\chars(char)\x=Val(StringField(line,3,","))
                                bitmapFonts(mapName)\chars(char)\y=Val(StringField(line,4,","))
                                bitmapFonts(mapName)\chars(char)\w=Val(StringField(line,5,","))
                                bitmapFonts(mapName)\chars(char)\h=Val(StringField(line,6,","))
                              EndIf
                  EndSelect
              EndIf
              Read.s line
            Wend
   
            ProcedureReturn #True
          EndIf
       EndIf
    EndIf
   
    ProcedureReturn #False
  EndProcedure
 
  Procedure.i ProTextHeight(mapName.s,text.s,*callBack.bitmapFontCallBack=#Null)
    Define loop.i,one.i
    Define height.i
    Define bitmapInfo._BITMAPINFO
   
    height=0
    If Len(mapName)>0 And FindMapElement(bitmapFonts(),mapName)
      For loop=1 To Len(text)
        one=Asc(Mid(text,loop,1))-bitmapFonts(mapName)\minChar
        CopyStructure(bitmapFonts(mapName)\chars(one),@bitmapInfo\clip,RECT)
       
        bitmapInfo\scaleX=1.0
        bitmapInfo\scaleY=1.0
       
        If *callBack<>#Null
          callBack(one,#Null,@bitmapInfo)
        EndIf
       
        height=Routines::Max(bitmapInfo\clip\h*bitmapInfo\scaleY,height)
      Next
    EndIf
   
    ProcedureReturn height
  EndProcedure     
 
  Procedure.i ProTextWidth(mapName.s,text.s,*callBack.bitmapFontCallBack=#Null)
    Define loop.i,one.i
    Define width.i
    Define bitmapInfo._BITMAPINFO
   
    width=0
    If Len(mapName)>0 And FindMapElement(bitmapFonts(),mapName)
      For loop=1 To Len(text)
        one=Asc(Mid(text,loop,1))-bitmapFonts(mapName)\minChar
        CopyStructure(bitmapFonts(mapName)\chars(one),@bitmapInfo\clip,RECT)
       
        bitmapInfo\scaleX=1.0
        bitmapInfo\scaleY=1.0
       
        If *callBack<>#Null
          callBack(one,#Null,@bitmapInfo)
        EndIf
       
        width+Int(bitmapInfo\clip\w*bitmapInfo\scaleX)
      Next
    EndIf
   
    ProcedureReturn width
  EndProcedure 
   
  Procedure.b DrawBitmapFontString(mapName.s,text.s,x.i,y.i,colour.i,scaleX.f=1.0,scaleY.f=1.0,intensity.i=255,*callBack.bitmapFontCallBack=#Null)
    Define loop.i,size.i
    Define one.i
   
    If Len(mapName)>0
      size=Len(text)
      If size>0
        For loop=1 To size
          x+DrawBitmapFontChar(mapName,Asc(Mid(text,loop,1)),x,y,colour,scaleX,scaleY,intensity,*callBack)
        Next
      EndIf
   
      ProcedureReturn #True
    EndIf
   
    ProcedureReturn #False
  EndProcedure
 
  Procedure.i DrawBitmapFontChar(mapName.s,one.i,x.i,y.i,colour.i,scaleX.f=1.0,scaleY.f=1.0,intensity.i=255,*callBack.bitmapFontCallBack=#Null)
    Define index.i
    Define bitmapInfo._BITMAPINFO
    Define point.POINT
    ;Define clip.RECT
    ;Define tempColour
    ;Define tempScaleX.f,tempScaleY.f
    ;Define tempX.i,tempY.i
   
    If FindMapElement(bitmapFonts(),mapName)
      point\x=x
      point\y=y
   
      index=one-bitmapFonts(mapName)\minChar
      If index>=0 And index<ArraySize(bitmapFonts(mapName)\chars())
        CopyStructure(bitmapFonts(mapName)\chars(index),@bitmapInfo\clip,RECT)
        bitmapInfo\colour=colour
        bitmapInfo\scaleX=scaleX
        bitmapInfo\scaleY=scaleY
        bitmapInfo\intensity=intensity
       
        If *callBack<>#Null
          callBack(one,@point,@bitmapInfo)
        EndIf
       
        ClipSprite(bitmapFonts(mapName)\spriteID,bitmapInfo\clip\x,bitmapInfo\clip\y,bitmapInfo\clip\w,bitmapInfo\clip\h)
        DisplayTransparentSprite(bitmapFonts(mapName)\spriteID,point\x,point\y,bitmapInfo\intensity,bitmapInfo\colour)
        ProcedureReturn (bitmapInfo\clip\w*bitmapInfo\scaleX)
     EndIf
   EndIf
   
   ProcedureReturn 0
  EndProcedure


It will need upgrading so that other sprites can be used in place of certain characters - but that can come later.
poshu
 
Posts: 37
Joined: Mon Feb 24, 2014 11:46 pm

Re: Rendering text on screen (bitmap font)

by poshu Tue Dec 13, 2016 11:53 am

I did my own, I'll post it here as soon as I can find some time to clean the code :
Image
User avatar
MrTAToad
 
Posts: 256
Joined: Sun Apr 20, 2014 11:43 am
Location: Chichester, England

Re: Rendering text on screen (bitmap font)

by MrTAToad Mon Dec 19, 2016 5:51 pm

Will be interesting to see the code...
Return to Game Programming

Who is online

Users browsing this forum: No registered users and 1 guest