True Type Fonts for Android and HTML5

Monkey Forums/Monkey Code/True Type Fonts for Android and HTML5

therevills(Posted 2014) [#1]
Inspired by a blog post by fractious:
http://fractiousg.blogspot.com.au/2012/04/rendering-text-in-opengl-on-android.html

This module allows you to load a true type font (ttf) in MonkeyX. The basic idea is that the module loads in the ttf and then displays it in the background, where it is rendered and captured to a Monkey surface so you can draw it later.

Android code:
GLText.java


HTML5 Code:
GLText.js


MonkeyX Code:
gltext.monkey


Example code:


For some reason I can't call c_GraphicsContext.p_Validate(), so I've copied the Matrix code in the Draw method...

I think this method could be used for the other targets to allow all of them to load TTF somehow...

Oh and this module is part of Diddy.


Midimaster(Posted 2014) [#2]
Oh my god, what a feature! This would be so helpful!!! Thank you for sharing this. But what about the other targets? This could stop this boaring limitation with texts in monkey.

I would like to see this as a part of monkey kernel. Mark, could you please think about it?


Supertino(Posted 2014) [#3]
WoW really nice, FontMachine is good and all that but nothing beats TTF support IMHO.


therevills(Posted 2014) [#4]
Just to be clear this is loading a TTF and converting it into a bitmap font. This allows you to only supply the ttfs which are small and saves generating multiple bitmasp fonts.

Also I was thinking this technique could be used to generate single images for full words or sentences, which would help performance.


therevills(Posted 2014) [#5]
Also I was thinking this technique could be used to generate single images for full words or sentences, which would help performance.

I've implemented this in the Diddy version:
http://code.google.com/p/diddy/source/detail?r=30562b12cf5cf9b726174bd62fd078e2b65d7ed2

So the commands are:
' Load in font for dynamic text
font20 = GLText.GetNewInstance() ' instantiate the GLText object
font20.Load("Roboto-Regular.ttf", 20, 2, 2) '  load the font, set the size and padding using method Load(fontfile, fontsize, xpadding, ypadding)
font20.Draw("Hello, World!", 100, 100) ' draws the text on screen using method Draw(text, x, y)

' Create a static text texture
staticScoreText  = GLText.GetNewInstance() '  instantiate the GLText object
staticScoreText.CreateText("Roboto-Regular.ttf", "SCORE:", 30) ' load the font, set the text and set the size using method CreateText(fontfile, text, size)
staticScoreText.DrawTexture(10, 200) ' draws the text on screen using DrawTexture(x, y)



therevills(Posted 2014) [#6]
Update to have WIP HTML5 support...


Samah(Posted 2014) [#7]
Be aware of licenses when distributing TTF files with your game. I would suggest grabbing one from here:
http://openfontlibrary.org/


MikeHart(Posted 2014) [#8]
Are webfonts supported with HTML5 too? Some sponsors only accept games which use webfonts.


CopperCircle(Posted 2014) [#9]
This is great, I was hoping to do a similar thing with SVG fonts. I hope you can get other platforms working...


therevills(Posted 2014) [#10]
Are webfonts supported with HTML5 too?

From what I've read you should be able to change the code to support them, with the HTML5 code we are actually drawing the text directly with the font (no bitmap fonts).

I hope you can get other platforms working...

My target is Android and I have that working, but I prototype in HTML5 and that's nearly fully working - so I wont be adding anymore targets myself.


therevills(Posted 2015) [#11]
I'm now reusing this for the HTML5 version of my game due to the slowness happening with Chrome v47 and SetColor/MouseDrag.

I have found and fixed an issue with the matrix for HTML5 and also added a new method to calculate the width of the text (for HTML5):

https://github.com/swoolcock/diddy/commit/b43e80c51e0ff741d4d4b208e6b4fde1b784bc90

The important HTML5 fix is needed in the Draw method, we need to call bb_graphics_context.p_Validate(); so that the matrix is set correctly:

GLText.prototype.Draw=function(text, x, y)
{
	var canvas = document.getElementById( "GameCanvas" );
	var ctx = canvas.getContext('2d');
	bb_graphics_context.p_Validate();
	
	ctx.font = this.size + 'px "'+this.font+'"';
	ctx.textBaseline = 'top';
	ctx.fillText(text, x, y);
}


I'm also going to add a way to change the font size on the fly for HTML5, since its just property of the GLText class it should be pretty easy. The Android version cant do this as it is an actual image (bitmap font). Something like this should do it(untested):
GLText.prototype.SetSize=function(size)
{
	this.size = size;
}

Class GLText Extends Null = "GLText"
	Function GetNewInstance:GLText()
	Method Load:bool(file:String, size:Int, padX:Int, padY:Int)
	Method CreateText:bool(file:String, text:String, size:Int)
	Method Draw:Void(text:String, x:Float, y:Float)
	Method DrawTexture:Void(x:Float, y:Float)
	Method CalcWidth:Int(text:String)
	Method SetSize:Void(size:Int)
End


Actually the Android version maybe able to do this, but it would require we loading and recreating the bitmap font all the time...


CopperCircle(Posted 2015) [#12]
Hi, I have extended this module with Skn3 and added an iOS version, I can email you the code if you want to merge it in?


therevills(Posted 2015) [#13]
That'll be great CopperCircle or you could post the code here :)

BTW the SetSize method works well for HTML5.


Soap(Posted 2015) [#14]
Thank you for making this. Going to try to switch from using rendered fonts to this. I wonder if the features in mojo2 would make good looking fonts without using tons of memory. https://www.youtube.com/watch?v=CGZRHJvJYIg

https://github.com/libgdx/libgdx/wiki/Distance-field-fonts