TFontImage; Image- & B3D TTFs nutzen können

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

DivineDominion

Betreff: TFontImage; Image- & B3D TTFs nutzen können

BeitragFr, Apr 01, 2005 1:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Habe mich geärgert das Fonts in Bmax nicht mehr in Pixelhöhe angegeben werden und deswegen "Arial 13px" aus B3D damals nicht umzusetzen war.

Darum nahm ich mir meine Imagefontangelegenheit und schrieb so ein Teil mit dynamischen Breiten hinzu.
Und einen passenden Exporter für B3D.

Schrecklich gecodeter exporter:
BlitzBasic: [AUSKLAPPEN]
Graphics 640, 480, 0, 2

Color 0, 0, 0
ClsColor 255, 0, 255

Font = LoadFont( \"Arial\", 13 )
SetFont font

maxBreite = StringWidth( \"W\" )
maxHoehe = StringHeight( \"Ij\" )

chars$ = \"\"
framecount = 126-33
img = CreateImage( maxBreite * framecount, maxHoehe )
SetBuffer ImageBuffer( img )
Cls

file = WriteFile( \"arial.txt\" )
WriteLine file, \"DYNAMIC\"
WriteInt file, framecount


For i = 33 To 125

buchstabe$ = Chr$( i )

chars$ = chars$ + buchstabe$

breite = StringWidth(buchstabe$)
Print breite
WriteInt file, breite

differenz = ( maxBreite - breite ) / 2
x = ( i - 33 ) * maxBreite + maxBreite - breite ;rechtsbündig
Text x, 0, buchstabe$

Next

WriteLine file, chars$

;Das hier wird später eh nicht beachtet beim auslesen:
WriteLine file, \"Maße für den Code: \" + maxBreite + \"*\" + maxHoehe

SaveImage (img, \"arial.bmp\" )


Und hier die Datei fürs importieren (TFontImage.bmx):
Code: [AUSKLAPPEN]

Strict

Import brl.basic
Import brl.system
Import brl.glmax2d
Import brl.pngloader
Import brl.bmploader


Const FONT_UPPERCASE = 1
Const FONT_LOWERCASE = 2
Const FONT_MIXEDCASE = 0
Const FONT_DYNAMIC = 3

Type TFontImage
   
   Field _image:TImage
   Field _charset:String
   Field _case:Int
   Field _w:Int, _h:Int
   
   Field _charSize:Int[]
   
   Function load:TFontImage( sImageFile:String, w:Int, h:Int, sFile:String )
      
      Local temp:TFontImage = New TFontImage
      
      Local hFile:TStream = ReadFile( sFile )
      
      If Not hFile
         
         temp = Null
         Return Null
         
      EndIf
      
      'Zeichenmodus
      Local sCase:String = ReadLine( hFile )
      sCase = sCase.toUpper(  )
      
      If sCase = "UPPERCASE"
      
         temp._case = FONT_UPPERCASE
      
      ElseIf sCase = "LOWERCASE"
         
         temp._case = FONT_LOWERCASE
      
      ElseIf sCase = "MIXEDCASE"
         
         temp._case = FONT_MIXEDCASE         
         
      ElseIf sCase = "DYNAMIC"
         
         temp._case = FONT_DYNAMIC
         
         'Local bla:Int = Readint( hFile )
         'Local bla:Int = Readint( hFile )
         Local iCount:Int = Readint( hFile )
         
         temp._charSize = New Int[iCount]
         
         For Local i:Int = 0 Until iCount
            
            Local iW:Int = Readint( hFile )
            temp._charSize[i] = iW
            
         Next
         
      EndIf
      
      'Zeichen im Bild
      temp._charset = ReadLine( hFile )      
            
      temp._image = LoadAnimImage( sImageFile, w, h, 0, temp._charset.length - 1, MASKEDIMAGE | DYNAMICIMAGE )
      temp._w = w
      temp._h = h
      
      Return temp
      
   EndFunction
   
   Method draw( sText:String, x:Int, y:Int  )
      
      For Local i:Int = 0 Until sText.length
         
         Local c:String = Chr( sText[i] )
            
         'Leerzeichen überspringen
         If c = " " And _case = FONT_DYNAMIC Then x:+_w/2; Continue
         If c = " " Then Continue
         
         
         If _case = FONT_DYNAMIC
            
            'Frame anhand des Charsets rausfinden
            Local iFrame:Int = Self._charset.find( c )
            
            If iFrame = -1 Then Continue
            
            Local iWidth:Int = _charSize[iFrame]
            Local iDiff:Int = _w - iWidth
            
            DrawImage Self._image, x - iDiff, y, iFrame
            
            x :+ iWidth
            
         Else
            
            'In Groß-/Kleinbuchstaben umwandeln
            Select Self._case
            
               Case FONT_UPPERCASE
                  c = c.toUpper(  )
                  If c = "ü"
                     c = "Ü"
                  ElseIf c = "ö"
                     c = "Ö"
                  ElseIf c = "ä"
                     c = "Ä"
                  EndIf
               
               Case FONT_LOWERCASE
                  c = c.toLower(  )
                  If c = "Ü"
                     c = "ü"
                  ElseIf c = "Ö"
                     c = "ö"
                  ElseIf c = "Ä"
                     c = "ä"
                  EndIf
                  
            EndSelect
            
            'Frame anhand des Charsets rausfinden
            Local iFrame:Int = Self._charset.find( c )
            
            If iFrame > -1 Then DrawImage Self._image, x + i * Self._w, y, iFrame
            
         EndIf
         
      Next
      
   EndMethod
   
   Method getLength:Int(  )
      
      Return _charset.length
      
   EndMethod
   
   Method getCharset:String(  )
      
      Return _charset
      
   EndMethod
   
EndType



Nutzen tut man das ganze relativ einfach:
Code: [AUSKLAPPEN]

'Maße aus der Datei entnommen
Local font:TFontImage = TFontImage.load( "arial.bmp", 9, 13, "arial.txt" )

'...

font.draw( "Hallo!", 0, 0 )



Für normale ImageFont's mit fixer Breite tut es eine Textdatei mit beispielsweise folgendem Inhalt:
Code: [AUSKLAPPEN]
UPPERCASE
ABCDEFGHIJKLMNOPQRSTUVWXYZ!.,-?


In das Charset kann man anfangs mehrere Stadien eintragen: UPPERCASE und LOWERCASE, wenn eine Font nur eine Auswahl hat (dann werden eingegebene Strings umgewandelt), oder MIXEDCASE für Groß- und Kleinschreibung zusammen.
Dann gibt es noch DYNAMIC. Dort wird wie bei MIXEDCASE gearbeitet, dafür aber mit Variabler Zeichenbreite. Die wird aus dem Charset ausgelesen, in Form zweier Integer, was das obige BB-Beispiel einträgt.

Die letzte Zeile da beinhaltet übrigens den String der festlegt, an welcher Frame im Bild welches Zeichen zu finden ist. Kann ein Zeichen nicht gefunden werden wird ein Leerzeichen eingefügt. Umlaute fehlen im Uppercase-Beispiel oben z.B..


Wer's gebrauchen kann - bitte sehr Smile

bmx: http://divinedominion.art-fx.o...tImage.bmx
Bild: http://divinedominion.art-fx.o...e/font.png
"Charset": http://divinedominion.art-fx.o...e/font.txt
christian.tietze@gmail.com - https://christiantietze.de
macOS
  • Zuletzt bearbeitet von DivineDominion am Mi, Mai 18, 2005 16:53, insgesamt 4-mal bearbeitet

wunderkind

BeitragFr, Apr 01, 2005 8:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr nett. Aber einen Solchen Generator mit variablen Breiten gibt's auch von Angelcode und zwar hier: http://www.angelcode.com/products/bmfont .

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group