Freetype bitmap font plugins for jMonkeyEngine3.
source code:
resources:
Library | Usage |
---|---|
FreeType | font raster library |
Harfbuzz | text shaping library |
ICU | unicode support |
Fontconfig | find best match font |
Algorithm | Usage |
---|---|
rectangle bin packing | how to pack small font bitmap into large texture atlas |
SDF | signed distance field font generation and shading |
MSDF | multi-channel signed distance field font generation and shading |
Core (in plan):
Other important features(in plan):
maven:
<dependencies>
<dependency>
<groupId>io.github.jmecn</groupId>
<artifactId>jme3-freetype-font</artifactId>
<version>0.1.2</version>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-freetype</artifactId>
<version>3.3.2</version>
<classifier>natives-windows</classifier>
<scope>runtime</scope>
</dependency>
</dependencies>
gradle:
repositories {
mavenCentral()
}
dependencies {
implementation "io.github.jmecn:jme3-freetype-font:0.1.2"
implementation "org.lwjgl:lwjgl-freetype::natives-windows:3.3.2"
}
Use FtFontKey
and FtFontLoader
, you can specify many parameters to load a font.
public void simpleInitApp() {
assetManager.registerLoader(FtFontLoader.class, "ttf", "otf");
FtFontKey key = new FtFontKey("fonts/NotoSans-Regular.ttf", 16);
// set the payload characters. It's optional.
key.setCharacters("abcdefghijklmnopqrstuvwxyz");
// enable real-time glyph generation.
key.setIncremental(true);
BitmapFont font = assetManager.loadFont(key);
BitmapText text = new BitmapText(font);
}
Use FtBitmapFont
to create a font quickly. All parameters ara default.
public void simpleInitApp() {
FtBitmapFont font = new FtBitmapFont(assetManager, "fonts/NotoSans-Regular.ttf", 16);
BitmapText text = new BitmapText(font);
}
Use FtFontGenerater
and FtFontParameter
to create a font manually.
public void simpleInitApp() {
FtFontGenerater generater = new FtFontGenerater(new File("fonts/NotoSans-Regular.ttf"));
FtFontParameter params = new FtFontParameter();
params.setSize(16);
params.setIncremental(true);
params.setRenderMode(RenderMode.MONO);
params.setMagFilter(Texture.MagFilter.Nearest);
params.setMinFilter(Texture.MinFilter.NearestNoMipMap);
params.setBorderWidth(1);
params.setBorderColor(ColorRGBA.Black);
params.setShadowOffsetX(3);
params.setShadowOffsetY(3);
params.setShadowColor(ColorRGBA.DaryGray);
FtBitmapCharacterSet charSet = generater.generateData(params);
BitmapFont font = new BitmapFont();
font.setCharSet(charSet);
}
Use Distance-field font. You need to change the default MatDef to any other SDF font support shader. I copied on from freetype-gl as a default MatDef.
DON'T set BorderWidth or ShadowOffsetX/Y with SDF font.
public void simpleInitApp() {
assetManager.registerLoader(FtFontLoader.class, "otf");
FtFontKey key = new FtFontKey("Font/NotoSerifSC-Regular.otf", 64, true);
key.setRenderMode(RenderMode.SDF);// specify the render mode
key.setSpread(8);// specify the spread, range in [2, 32]
key.setMatDefName("Shaders/Font/SdFont.j3md");// specify the Shader
key.setColorMapParamName("ColorMap");
key.setUseVertexColor(false);// SdFont currently doesn't support vertex color, so turn it off
BitmapFont fnt = assetManager.loadAsset(key);
}
Enjoy yourself.
As this library depends on lwjgl-freetype, it's a module of lwjgl3. User should use jme3-lwjgl3 instead of jme3-lwjgl for jme3 application.
For jme3 version 3.6.1-stable, the jme3-lwjgl3 module depends on lwjgl3 3.3.2. So the version of lwjgl-freetype now is 3.3.2 too.
If your jme3-lwjgl3 version is newer or older, you should check the version of lwjgl-freetype, keep it the same to lwjgl3 version.
lwjgl3 support natives for windows, macos and linux. You can find the natives at https://www.lwjgl.org/customize
maven:
<properties>
<lwjgl.version>3.3.2</lwjgl.version>
</properties>
<profiles>
<profile>
<id>lwjgl-natives-linux-amd64</id>
<activation>
<os>
<family>unix</family>
<name>linux</name>
<arch>amd64</arch>
</os>
</activation>
<properties>
<lwjgl.natives>natives-linux</lwjgl.natives>
</properties>
</profile>
<profile>
<id>lwjgl-natives-macos-x86_64</id>
<activation>
<os>
<family>mac</family>
<arch>x86_64</arch>
</os>
</activation>
<properties>
<lwjgl.natives>natives-macos</lwjgl.natives>
</properties>
</profile>
<profile>
<id>lwjgl-natives-windows-amd64</id>
<activation>
<os>
<family>windows</family>
<arch>amd64</arch>
</os>
</activation>
<properties>
<lwjgl.natives>natives-windows</lwjgl.natives>
</properties>
</profile>
</profiles>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-bom</artifactId>
<version>${lwjgl.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-freetype</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-freetype</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
</dependencies>
gradle:
import org.gradle.internal.os.OperatingSystem
project.ext.lwjglVersion = "3.3.2"
switch (OperatingSystem.current()) {
case OperatingSystem.LINUX:
project.ext.lwjglNatives = "natives-linux"
def osArch = System.getProperty("os.arch")
if (osArch.startsWith("arm") || osArch.startsWith("aarch64")) {
project.ext.lwjglNatives += osArch.contains("64") || osArch.startsWith("armv8") ? "-arm64" : "-arm32"
} else if (osArch.startsWith("ppc")) {
project.ext.lwjglNatives += "-ppc64le"
} else if (osArch.startsWith("riscv")) {
project.ext.lwjglNatives += "-riscv64"
}
break
case OperatingSystem.MAC_OS:
project.ext.lwjglNatives = "natives-macos"
break
case OperatingSystem.WINDOWS:
project.ext.lwjglNatives = "natives-windows"
break
}
repositories {
mavenCentral()
}
dependencies {
implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
implementation "org.lwjgl:lwjgl"
implementation "org.lwjgl:lwjgl-freetype"
runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives"
runtimeOnly "org.lwjgl:lwjgl-freetype::$lwjglNatives"
}