Browse Source

Added simple fixed size bitmap font support.

Mark Sibly 7 years ago
parent
commit
14f8f9eb44
1 changed files with 83 additions and 16 deletions
  1. 83 16
      modules/mojo/graphics/font.monkey2

+ 83 - 16
modules/mojo/graphics/font.monkey2

@@ -75,7 +75,7 @@ Class Font Extends Resource
 		Local gpage:=_pages[page]
 		If Not gpage Return Null
 		
-		If Not gpage.image LoadGlyphPage( page )
+		If Not gpage.image OnLoadGlyphPage( page,gpage )
 				
 		Local index:=char & 255
 		If index>=gpage.glyphs.Length Return Null
@@ -95,7 +95,7 @@ Class Font Extends Resource
 		Local gpage:=_pages[page]
 		If Not gpage Return _nullGlyph
 
-		If Not gpage.image LoadGlyphPage( page )
+		If Not gpage.image OnLoadGlyphPage( page,gpage )
 				
 		Local index:=char & 255
 		If index>=gpage.glyphs.Length Return _nullGlyph
@@ -104,28 +104,103 @@ Class Font Extends Resource
 	End
 	
 	#rem monkeydoc Loads a font from a file.
+	
+	For the constructor with a `fontPath` parameter, the font must be a valid .ttf, .otf or .fon format font.
+		
+	For the constructor with an `imagePath` parameter, the font must be a valid image file containing a fixed size font with the characters laid out in left-to-right, top-to-bottom order.
+		
 	#end
-	Function Load:Font( path:String,height:Float,shader:Shader=Null,textureFlags:TextureFlags=TextureFlags.FilterMipmap )
+	Function Load:Font( fontPath:String,height:Float,shader:Shader=Null,textureFlags:TextureFlags=TextureFlags.FilterMipmap )
 	
 		If Not shader shader=Shader.GetShader( "font" )
 		
-		Local font:=FreeTypeFont.Load( path,height,shader,textureFlags )
-		If Not font And Not ExtractRootDir( path ) font=FreeTypeFont.Load( "font::"+path,height,shader,textureFlags )
+		Local font:=FreeTypeFont.Load( fontPath,height,shader,textureFlags )
+		If Not font And Not ExtractRootDir( fontPath ) font=FreeTypeFont.Load( "font::"+fontPath,height,shader,textureFlags )
+		
+		Return font
+	End
+	
+	Function Load:Font( imagePath:String,charWidth:Int,charHeight:Int,firstChar:Int=32,numChars:Int=96,padding:Int=1,shader:Shader=Null,textureFlags:TextureFlags=TextureFlags.FilterMipmap )
+		
+		Local pixmap:=Pixmap.Load( imagePath,Null,True )
+		
+		If Not pixmap And Not ExtractRootDir( imagePath )
+			pixmap=Pixmap.Load( "font::"+imagePath,Null,True )
+			If Not pixmap Return Null
+		Endif
+		
+		Local charsPerRow:=pixmap.Width/charWidth
+		Local numRows:=(numChars-1)/charsPerRow+1
+		
+		Local ipixmap:Pixmap
+		If padding
+			ipixmap=New Pixmap( charsPerRow*(charWidth+padding),numRows*(charHeight+padding),pixmap.Format )
+			ipixmap.Clear( Color.None )
+		Endif
+		
+		Local npages:=((firstChar+numChars-1) Shr 8)+1
+		
+		Local pages:=New GlyphPage[npages]
+		
+		Local page:GlyphPage,spos:=New Vec2i,gpos:=New Vec2i,gsize:=New Vec2i( charWidth,charHeight )
+		
+		For Local char:=firstChar Until firstChar+numChars
+			
+			If Not page Or (char & 255)=0
+				page=New GlyphPage
+				page.glyphs=New Glyph[256]
+				pages[char Shr 8]=page
+			Endif
+			
+			Local glyph:=New Glyph( New Recti( gpos,gpos+gsize ),Null,charWidth )
+			
+			page.glyphs[char&255]=glyph
+			
+			If ipixmap
+				Local src:=pixmap.Window( spos.x,spos.y,charWidth,charHeight )
+				ipixmap.Paste( src,gpos.x,gpos.y )
+			Endif
+			
+			spos.x+=charWidth
+			gpos.x+=charWidth+padding
+			If spos.x+charWidth>pixmap.Width
+				spos.y+=charHeight
+				gpos.y+=charHeight+padding
+				spos.x=0
+				gpos.x=0
+			Endif
+		Next
+		
+		If Not pages[0]
+			page=New GlyphPage
+			page.glyphs=New Glyph[1]
+			pages[0]=page
+		Endif
+		
+		pages[0].glyphs[0]=pages[firstChar Shr 8].glyphs[firstChar & 255]
+		
+		Local image:=New Image( ipixmap ?Else pixmap,textureFlags,shader )
+		For Local page:=Eachin pages
+			page?.image=image
+		Next
+		
+		Local font:=New Font
+		
+		font.InitFont( charHeight,pages )
 		
 		Return font
 	End
 	
 	Protected
 	
-	Method OnLoadGlyphPage( page:Int,gpage:GlyphPage ) Abstract
+	Method OnLoadGlyphPage( page:Int,gpage:GlyphPage ) Virtual
+	End
 	
 	Method InitFont( height:Float,pages:GlyphPage[] )
 	
 		_height=height
 		_pages=pages
 		
-		LoadGlyphPage( 0 )
-		
 		_nullGlyph=GetGlyph( 0 )
 	End
 	
@@ -145,14 +220,6 @@ Class Font Extends Resource
 	Field _pages:GlyphPage[]
 	
 	Field _nullGlyph:Glyph
-	
-	Method LoadGlyphPage( page:Int )
-	
-		Local gpage:=_pages[page]
-		
-		If Not gpage.image OnLoadGlyphPage( page,gpage )
-	End
-
 End
 
 Class ResourceManager Extension