BASIC

Author Topic: BMFont system (tested with Glyph Designer to Mac)  (Read 2951 times)

Offline spacefractal

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 3652
    • View Profile
    • Space Fractal
here recently im have found a font editor with name Glyph Designer (https://71squared.com/glyphdesigner). Its a excellent bitmap font designer app and im dedicated to uses that for my Spot Race game and replace the old font system im used for the other games.

Here im uses the txt version of the format (not xml) and kernal is not need to been included, which is not supported. Otherwice its seen the editor uses bmfont based.

Im have not wrote any examples, but the code below should explain its own (and its also uses Android Extras for Check Assest thing, if you not uses that, just uncomment it).

Code: GLBasic [Select]
// --------------------------------- //
// Project: SpotOut
// Start: Saturday, August 09, 2014
// IDE Version: 12.096


TYPE letters
        id
        x
        y
        w
        h
        xoff
        yoff
        xadv
        time
        letter$
ENDTYPE

TYPE font
        bitmapid
        letterFont[] AS letters
        LineHeight
        size
        start=0
        maxkerning

        FUNCTION Load: file$
                LOCAL line$
                IF LEN(self.letterFont)=0 THEN DIM self.letterFont[255]

                // load the bitmap
                self.bitmapid=GENSPRITE()
                IF device$="a" OR device$="ak" THEN Android.Check_Asset(file$)
                LOADSPRITE file$, self.bitmapid

                LOCAL width, height
                GETSPRITESIZE self.bitmapid, width, height


                // load the font discribtion
                file$=REPLACE$(file$, "png", "fnt")
                IF device$="a" OR device$="ak" THEN Android.Check_Asset(file$)

                LOCAL filenr=GENFILE()
                file$=GETCURRENTDIR$()+file$
                IF device$="a" OR device$="ak" THEN Android.Check_Asset(file$)

                LOCAL ok=OPENFILE(filenr, file$, 1)
                IF ok=1
                        REPEAT
                                READLINE filenr, line$
                                line$=LCASE$(line$)
                                line$=TRIM$(line$)
                                IF LEFT$(line$, 4)="char"
                                        LOCAL chr=self.Tag$(line$, "id", 1)
                                        self.letterFont[chr].x=self.Tag$(line$, "x")
                                        self.letterFont[chr].y=self.Tag$(line$, "y")
                                        self.letterFont[chr].w=self.Tag$(line$, "width")
                                        self.letterFont[chr].h=self.Tag$(line$, "height")
                                        self.letterFont[chr].xoff=self.Tag$(line$, "xoffset")
                                        self.letterFont[chr].yoff=self.Tag$(line$, "yoffset")
                                        self.letterFont[chr].xadv=self.Tag$(line$, "xadvance")

                                        IF self.letterFont[chr].xadv>self.maxkerning
                                                self.maxkerning=self.letterFont[chr].xadv
                                        ENDIF


                                        IF chr=34 THEN self.letterFont[chr].letter$="ยค"
                                        IF chr<>34
                                                self.letterFont[chr].letter$=self.Tag$(line$, "letter")
                                                IF self.letterFont[chr].letter$="space" THEN self.letterFont[chr].letter$=" "
                                        ENDIF
                                ELSEIF LEFT$(line$, 6)="common"
                                        self.LineHeight=self.Tag$(line$, "lineheight", 1)
                                ELSEIF LEFT$(line$, 6)="kernin"
                                        BREAK
                                ENDIF
                        UNTIL ENDOFFILE(filenr)
                ENDIF
                CLOSEFILE filenr

                LOCAL chr=ASC(".")
                LOCAL num=ASC("0")

                FOR i=0 TO 254
                        self.letterFont[i].time=self.letterFont[i].xadv
                NEXT

                LOCAL chr2=ASC(" ")
                self.letterFont[chr2].time=self.letterFont[chr].xadv

                LOCAL lettrs$="123456789"

                FOR i=0 TO 8
                        LOCAL chr2=ASC(MID$(lettrs$, i, 1))
                        self.letterFont[chr2].time=self.letterFont[num].xadv
                NEXT
        ENDFUNCTION

        FUNCTION Length: txt$, spacer=0, zoom=1, effect$=""
                LOCAL posxx=0
                LOCAL nokernal=0
                IF effect$="nokernal" THEN nokernal=1
                IF effect$="time" THEN nokernal=2

                FOR i=0 TO LEN(txt$)-1
                        LOCAL c$=MID$(txt$, i, 1)
                        LOCAL chr=ASC(c$)
                        IF nokernal=1 THEN chr=ASC("E")
                        IF nokernal<2
                                posxx=posxx+(self.letterFont[chr].xadv+spacer)*zoom
                        ELSE
                                posxx=posxx+(self.letterFont[chr].time+spacer)*zoom
                        ENDIF
                NEXT
                RETURN posxx

        ENDFUNCTION


        FUNCTION DrawStart:
                self.start=1
                STARTPOLY self.bitmapid, 2;
        ENDFUNCTION

        FUNCTION DrawText: txt$, x, y, zoom, zoomy, xspot, yspot, spacer, effect$=""
                LOCAL lx, ly, lw, lh // letter from the font file
                LOCAL cx, cy, cw, ch // current letter
                LOCAL xajd=0
                LOCAL nokernal=0
                LOCAL buttondown=0
                LOCAL timefont=0
                //IF effect$="nokernal" THEN nokernal=1

                IF effect$<>"notrim"
                        IF effect$<>"button" OR S_Status$="Twitter" THEN txt$=TRIM$(txt$)
                        IF effect$="time" THEN timefont=1
                ENDIF

                IF effect$="menu"
                        IF LEFT$(txt$, 1)="."
                                buttondown=1
                                txt$=RIGHT$(txt$, LEN(txt$)-1)
                        ENDIF
                        IF S_Status$<>"Options" THEN buttondown=1
                        FOR r=1 TO 3
                                IF LEN(txt$)<8
                                        txt$=" "+txt$+" "
                                ENDIF
                        NEXT
                ENDIF

                LOCAL h, w
                h=ScreenHeight
                w=ScreenWidth
                xajd=self.Length(txt$, spacer, zoom, effect$)

                IF xspot=0 THEN x=ScreenWidth/2-xajd/2+x
                IF xspot=1 THEN x=ScreenWidth-xajd-x
                IF yspot=1 THEN y=ScreenHeight-y-self.LineHeight*zoomy
                IF yspot=0 THEN y=ScreenHeight/2-self.LineHeight*zoomy/2+y

                LOCAL posx=x
                LOCAL posy=y

//              DRAWRECT posx, posy, xajd, 2, RGB(255, 0, 0)

                PX=posx-20*zoom
                PY=posy-20*zoomy
                PW=xajd+40*zoom
                PH=self.LineHeight*zoomy+40*zoomy

                IF effect$="button" OR buttondown=1
                        IF device$="a" OR device$="ak"
                                SetAlphaMode(0.2)
                                PaintColorRectRGB("colors", posx-20*zoom, posy-20*zoomy, xajd+40*zoom, self.LineHeight*zoomy+20*zoomy, 240, 240, 240)
                        ELSE
                                SetAlphaMode(0.1)
                                DRAWRECT posx-20*zoom, posy-20*zoomy, xajd+40*zoom, self.LineHeight*zoomy+20*zoomy, RGB(255, 255, 255)
                        ENDIF
                        SetAlphaMode(1)
                ENDIF

                IF self.start=0 THEN STARTPOLY self.bitmapid, 2;
                FOR i=0 TO LEN(txt$)-1
                        LOCAL c$=MID$(txt$, i, 1)
                        LOCAL chr=ASC(c$)


                        cx=(posx+letterFont[chr].xoff*zoom)
                        IF chr=46 AND  effect$="nokernal"
                                cx=cx+letterFont[chr].xadv*zoom/3
                                cy=cy-letterFont[chr].xadv*zoom
                        ENDIF
                        cy=(posy+letterFont[chr].yoff*zoomy)
                        cw=(self.letterFont[chr].w)*zoom
                        ch=(self.letterFont[chr].h)*zoomy

                        lx=self.letterFont[chr].x
                        ly=self.letterFont[chr].y
                        lw=self.letterFont[chr].w
                        lh=self.letterFont[chr].h

                        POLYVECTOR cx+cw, cy,     lx+lw, ly
                        POLYVECTOR cx, cy,        lx, ly
                        POLYVECTOR cx+cw, cy+ch,  lx+lw, ly+lh
                        POLYVECTOR cx, cy+ch,     lx, ly+lh

                        IF nokernal=1 THEN chr=ASC("E")
                        IF timefont=0
                                posx=posx+(self.letterFont[chr].xadv+spacer)*zoom
                        ELSE
                                posx=posx+(self.letterFont[chr].time+spacer)*zoom
                        ENDIF
                        POLYNEWSTRIP
                NEXT

                IF self.start=0 THEN ENDPOLY
        ENDFUNCTION

        FUNCTION DrawEnd:
                self.start=0
                ENDPOLY
        ENDFUNCTION


        FUNCTION Tag$: Line$, Name$, start=0
                LOCAL name$
                STATIC spr$[]
                IF start=1
                        SPLITSTR(Line$, spr$[], " ", TRUE)
                ENDIF

                FOR i=0 TO LEN(spr$)-1
                        name$=StringField$(spr$[i], 1, "=")
                        IF name$=Name$
                                name$=StringField$(spr$[i], 2, "=")
                                name$=REPLACE$(name$, CHR$(34), "")
                                RETURN name$
                        ENDIF
                NEXT
        ENDFUNCTION
ENDTYPE
 

a simple example could something like this:

Code: GLBasic [Select]
GLOBAL BMFont AS font
BMFont.Load("mainfont.png")
BMFont.DrawText("LOADING "+UCASE$(Title$), 0, SCALING*120, (SCALING)/2, (SCALING*ISZOOM)/2, 0, -1, 0)
 

hope this is something uses for others which search for a nice bitmap editor. The editor here im found is also Mac only throught.

This code is nowhere perfect, but can been used as its are.

helper functions:
Code: GLBasic [Select]
FUNCTION StringField$: TXT$, index%, Delimeter$
        LOCAL i, char$
        LOCAL RESULT$=""
        FOR i=0 TO LEN(TXT$)
                LOCAL char$=MID$(TXT$, i, 1)
                IF char$=Delimeter$ OR i=LEN(TXT$)
                        index%=index%-1
                        IF index%=0 AND i=LEN(TXT$)
                                RETURN RESULT$+char$
                        ENDIF
                        IF index%=0 THEN RETURN RESULT$
                        IF i=LEN(TXT$) THEN RETURN ""
                        RESULT$=""
                ELSE
                        RESULT$=RESULT$+char$
                ENDIF
        NEXT
        RETURN ""
ENDFUNCTION
 

PS. This code is wrote by me, but anyone can uses this code without pay me and also in a commercial software to. So fell free use it.
« Last Edit: 2014-Aug-25 by spacefractal »
Greedy Mouse - Karma Miwa - Spot Race - CatchOut - Android Extras - is on a vacation trip, home before end of few days in jan.