I'm looking for a simple example that loads a ttf file (in my case, Inconsolata.ttf
) and creates a text layer.
Is it possible to do this in a platform-agnostic way? From this response here, I get the impression it is not.
I am working on a simple proof-of-concept using the TextDemo sample from the playn-samples showcase as a reference.
I'm presently a little confused on how to register the ttf file. Here's my code:
private void testCustomFont() {
// text
String text = "Hello, Cleveland!";
// load font
String fontName = "Inconsolata";
Font.Style fontStyle = Font.Style.BOLD;
Float fontSize = 24f;
Font myFont = graphics().createFont(fontName, fontStyle, fontSize);
// format text
Integer fontColor = Color.rgb(0, 0, 255);
TextFormat textFormat = new TextFormat().withFont(myFont).withTextColor(fontColor);
// create font image layer
ImageLayer textLayer = graphics().createImageLayer();
TextLayout textLayout = graphics().layoutText(text, textFormat);
CanvasImage textImage = graphics().createImage((int)Math.ceil(textLayout.width()),
(int)Math.ceil(textLayout.height()));
textImage.canvas().drawText(textLayout, 0, 0);
textLayer.setImage(textImage);
// position text layer and add to root layer
textLayer.setTranslation(20, 20);
graphics().rootLayer().add(textLayer);
}
The projects is laid out like so:
/project
├── core
│ └── MyProject.java
└── resources
└── fonts
└── Inconsolata.ttf
This displays the text but, as expected, not in the desired typeface.
Ideally, I would have like font-loading to have worked like image-loading with the asset manager:
String fontPath = "fonts/Inconsolata.ttf";
Font.Style fontStyle = Font.Style.BOLD;
Float fontSize = 24f;
Font myFont = assetManager().getFont(fontPath, fontStyle, fontSize);
That wasn't possible, so I looked into doing something like this:
private void registerFont() {
if (platformType().equals(Platform.Type.JAVA)) {
Platform platform = Platform.getJavaPlatformApi();
platform.assets().setPathPrefix("com/klenwell/myproject/resources");
platform.graphics().registerFont("Inconsolata", "fonts/Inconsolata.ttf");
}
else if (platformType().equals(Platform.Type.ANDROID)) {
Platform platform = Platform.getAndroidPlatformApi();
platform.assets().setPathPrefix("com/klenwell/myproject/resources");
platform.graphics().registerFont("Inconsolata", "fonts/Inconsolata.ttf");
}
else if (platformType().equals(Platform.Type.HTML)) {
// rely on CSS setting in HTML host file
}
}
But there is no method like getJavaPlatformApi in the core Platform class. So as noted here, "you have to register the font manually on each backend that you intend to use."
Following the example of the TextDemo sample, this is how I would load the font in my example above for the Java and HTML platforms:
Update game class in Java dir:
public class MyProjectJava {
public static void main(String[] args) {
JavaPlatform platform = JavaPlatform.register();
platform.assets().setPathPrefix("com/klenwell/myproject/resources");
platform.graphics().registerFont("Inconsolata", "fonts/Inconsolata.ttf");
PlayN.run(new MyProject());
}
}
Edit the HTML host file under HTML snapshot directory:
<!DOCTYPE html>
<html>
<head>
<title>MyProject Font Loading Example</title>
<style>
@font-face {
font-family: "Inconsolata";
src: url(myproject/resources/fonts/Inconsolata.ttf);
}
</style>
</head>
<body bgcolor="black">
<script src="myproject/myproject.nocache.js"></script>
</body>
</html>
To Be Announced
To Be Announced
I haven't yet ventured into Android or iOS compilation yet, so I can't offer an example of those at present.