About Monkey 2 › Forums › Monkey 2 Projects › Mac font Class/module
This topic contains 6 replies, has 3 voices, and was last updated by 
 Jesse
 2 years, 6 months ago.
- 
		AuthorPosts
 - 
		
			
				
September 24, 2016 at 3:15 am #4081
I just made a simple font Class to work with Glyph Designer for Mac
its pretty basic. It displays text based on the Angel Font format and it should work with any program that produces the angel code font format.
the code does what I need for now so I am posting what I got so far.here it is in case it’s useful to anybody:
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174[crayon-5cba823fbc448526626090 inline="true" ]#import "<mojo>"#import "<std>"#import "mygliph.fnt"#import "mygliph.png"Using mojo..Using std..Class MyGameWindow Extends WindowField font:FontMethod New(title:String, width:Int, height:Int)ClearColor = Color.Blackfont = New Font()font.LoadFont("mygliph")EndMethod OnRender( canvas:Canvas ) Overridecanvas.PushMatrix()canvas.Translate(100,300)canvas.Scale(.5,.5)canvas.Rotate(1)font.Render(canvas,"This is a test...",0,0)canvas.Translate(0,0)canvas.PopMatrix()End MethodEnd ClassFunction Main()New AppInstanceNew MyGameWindow("test",640,480 )App.Run()End FunctionClass FontMethod New()font = New Map<Int,Glyph>End MethodMethod LoadFont(url:String)Local text:string = LoadString("asset::"+url+".fnt")If text = Null Print "unable to load text"Local lines:= text.Split(String.FromChar(10))font.Clear()For Local line := Eachin linesSelect TrueCase line.Contains("info face")Local i := 10If line[i] = 34i += 1Local n:String = ""While line[i]<>34n += line.Mid(i,1)i+=1WendfontName = nEndifsize = Int(GetString(line,"Size="))Case line.Contains("common")lineHeight = Float(GetString(line,"lineHeight="))atlasWidth = Float(GetString(line,"scaleW="))atlasHeight = Float(GetString(line,"scaleH="))pages = Float(GetString(line,"pages="))atlas = New Image[pages]Case line.Contains("page id")atlasName = GetString(line,"file=")atlasName = atlasName.Mid(1,atlasName.Length-2)atlas[0] = Image.Load("asset::"+atlasName)If atlas[0] = Null Print "invalid image "+atlasNameCase line.Contains("chars count")charsCount = Int(GetString(line,"chars count="))Case line.Contains("char id")Local glyph := New Glyphglyph.id = Int( GetString(line,"char id="))glyph.x = Int(GetString(line,"x="))glyph.y = Int(GetString(line,"y="))glyph.width = Int(GetString(line,"width="))glyph.height = Int(GetString(line,"height="))glyph.xOffset = Int(GetString(line,"xoffset="))glyph.yOffset = Int(GetString(line,"yoffset="))glyph.xAdvance = Int(GetString(line,"xadvance="))glyph.page = Int( GetString(line,"page="))glyph.characterName = GetString(line,"letter=")glyph.characterName = glyph.characterName.Mid(1,glyph.characterName.Length-2)glyph.atlas = atlas[glyph.page]font.Add(glyph.id,glyph)End SelectNextEnd MethodProperty Name:String()Return fontNameEndProperty Height:Float()Return sizeEndProperty CharacterCount:int()Return charsCountEndMethod TextWidth:Int(text:string)Local width := 0For Local char := Eachin textLocal glyph := font.Get(char)If glyphwidth += glyph.xAdvanceElsewidth += 8EndifNextReturn widthEnd MethodMethod Render(canvas:Canvas,txt:String,x:float,y:Float)For Local char := Eachin txtLocal glyph := font.Get(char)If glyph = NullPrint "Invalid Character in text " + txtElseglyph.Render(canvas,x,y)x += glyph.xAdvanceEndifNextEnd MethodPrivateMethod GetString:String(line:String,s:String)Local index:Int = s.Length + line.Find(s)Local text:String = ""While line[index] <> 32 And index < line.Lengthtext += line.Mid(index,1)index += 1WendReturn textEnd MethodField fontName:stringField size:FloatField lineHeight:FloatField atlasWidth:FloatField atlasHeight:FloatField pages:FloatField charsCount:IntField atlas:Image[]Field atlasName:stringField font:Map<Int,Glyph>End ClassClass GlyphField id:IntField x:IntField y:IntField width:IntField height:IntField xOffset:FloatField yOffset:FloatField xAdvance:FloatField page:IntField characterName:StringField atlas:ImageMethod Render(canvas:Canvas,px:Float,py:Float,angle:float = 0)canvas.DrawRect(px+xOffset,py+yOffset,width,height,atlas,x,y)End MethodEnd ClassYou will need the “*.png” and “*.fnt” file produced by GLyphDesigner.
September 25, 2016 at 8:36 pm #4093Nice!
September 25, 2016 at 11:52 pm #4094Thanks Mark!
I think It works with any program that produces the angel code font format, as long as it’s one page atlas. it’s not set up to work with multiple pages as Glyph Designer only produces a single page. so I can’t test it other wise I would set it up for multiple pages.
September 26, 2016 at 9:30 am #4098Excellent!
I’ve done some tests with bmGlyph exported fnt and it works. I did need to make some modification to the code though.
Here’s the code modified into a more compact class:
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154class BitmapFontclass BitmapGlyphmethod New()End methodField id:IntField x:IntField y:IntField width:IntField height:IntField xOffset:FloatField yOffset:FloatField xAdvance:FloatField page:IntField characterName:StringEndField font:Map<Int, BitmapGlyph>Method New( fontName:string )font = New Map<Int, BitmapGlyph>LoadFont( fontName )End methodProperty Name:String()Return fontNameEndProperty Height:Float()Return fontHeightEndProperty CharacterCount:int()Return charsCountEndMethod TextWidth:Int(text:string, xscale:float = 1 )Local width:int = 0For Local char := Eachin textLocal glyph := font.Get(char)If glyph <> null Thenwidth += glyph.xAdvanceElsewidth += 8EndifNextReturn width * xscaleEnd Methodmethod LoadFont( fontName:string )fontName = StripExt( fontName )Local text:string = LoadString( fontName+".fnt" )If text = Null Print "unable to load text"Local img:string = fontName+".png"_fontImage = Image.Load( img )Local lines := text.Split( String.FromChar(10) )For Local line := Eachin linesSelect TrueCase line.Contains( "info face" )Local i:int = 10If line[i] = 34i += 1Local n:String = ""While line[i]<>34n += line.Mid(i,1)i+=1WendfontName = nEndifsize = Int(GetString(line,"Size="))Case line.Contains("common")lineHeight = Float(GetString(line,"lineHeight="))atlasWidth = Float(GetString(line,"scaleW="))atlasHeight = Float(GetString(line,"scaleH="))pages = Float(GetString(line,"pages="))atlas = New Image[pages]Case line.Contains("page id")atlasName = GetString(line,"file=")atlasName = atlasName.Mid(1,atlasName.Length-2)atlas[0] = Image.Load("asset::"+atlasName)If atlas[0] = Null Print "invalid image "+atlasNameCase line.Contains("chars count")charsCount = Int(GetString(line,"chars count="))Case line.Contains("char id")' Print Int( GetString(line,"char id="))Local glyph:BitmapGlyph = New BitmapGlyph()glyph.id = Int( GetString(line,"char id=") )glyph.x = Int( GetString(line,"x=") )glyph.y = Int( GetString(line,"y=") )glyph.width = Int( GetString(line,"width=") )glyph.height = Int( GetString(line,"height=") )If glyph.height > fontHeight Then fontHeight = glyph.heightglyph.xOffset = Int( GetString(line,"xoffset=") )glyph.yOffset = Int( GetString(line,"yoffset=") )glyph.xAdvance = Int( GetString(line,"xadvance=") )glyph.page = Int( GetString(line,"page=") )glyph.characterName = GetString(line,"letter=" )glyph.characterName = glyph.characterName.Mid( 1, glyph.characterName.Length-2 )font.Add( glyph.id, glyph )End SelectNextEnd MethodMethod Render(canvas:Canvas, txt:String, x:float, y:Float, xscale:float = 1, yscale:float = 1)canvas.TextureFilteringEnabled = FalseFor Local char := Eachin txtLocal glyph := font.Get(char)If glyph = Null ThenPrint "Invalid Character in text " + txtElsecanvas.DrawRect( x + (glyph.xOffset*xscale), y + (glyph.yOffset*yscale), glyph.width * xscale, glyph.height*yscale, _fontImage, glyph.x, glyph.y, glyph.width, glyph.height )x += glyph.xAdvance * xscaleEndifNextEnd MethodprivateField fontName:stringField size:FloatField lineHeight:FloatField atlasWidth:FloatField atlasHeight:FloatField pages:FloatField charsCount:IntField atlas:Image[]Field atlasName:stringfield fontHeight:int = 0field _fontImage:ImageMethod GetString:String( line:String ,s:String )Local index:Int = s.Length + line.Find( s )Local text:String = ""While line[index] <> 32 And index < line.Lengthtext += line.Mid(index, 1)index += 1WendReturn textEnd MethodEndit’s basically the same but with the font rendering moved about a bit and the class names renamed so they don’t clash with any mojo stuff
P.S. I’ve also added the ability to scale in the x and y direction and corrected the height property
September 26, 2016 at 3:22 pm #4101Good job Adam! I didn’t think about putting the glyph class inside the font class but I like it.
September 27, 2016 at 5:08 am #4107If you’re like I can add italics and some other bits n bobs?
September 30, 2016 at 11:06 pm #4189I just saw your last post. Yes, that would help.
 - 
		AuthorPosts
 
You must be logged in to reply to this topic.