This library was inspired by Motion Twin's original HashLink FreeType binding
Native FreeType support for HashLink, with optional Heaps font integration.
- adds
freetype.Libraryfor plain HashLink projects - loads TTF/OTF fonts from memory
- renders glyphs through FreeType into HashLink bytes
- adds
freetype.heaps.FreeTypeFontfor creatingh2d.Fontfrom one or more TTF files
ttfttcotf
final library = new freetype.Library();
final face = library.loadFace(sys.io.File.getBytes("font.ttf"));
face.setPixelSize(0, 32);
final glyph = face.renderCodepoint("A".code);
trace(face.familyName);
trace(glyph.bitmap.width + "x" + glyph.bitmap.height);
face.dispose();
library.dispose();Useful API:
Library.loadFace(bytes, ?index)Library.describeLastError()Face.setPixelSize(width, height)Face.setSize(points, ?dpi)Face.glyphIndex(codepoint)Face.hasGlyph(codepoint)Face.kerning(leftGlyph, rightGlyph)Face.renderCodepoint(codepoint, ?loadFlags, ?renderMode, ?out)
Public data and enum types live in freetype.types, for example:
freetype.types.Bitmapfreetype.types.Glyphfreetype.types.FaceMetricsfreetype.types.LoadFlagsfreetype.types.RenderModefreetype.types.PixelMode
Create an h2d.Font directly from a TTF file:
final font = freetype.heaps.FreeTypeFont.fromFile("font.ttf", 24, {
chars: "Hello Привет こんにちは",
kerning: true,
});
final text = new h2d.Text(font, s2d);
text.text = "Hello Привет こんにちは";Use multiple font files when your text spans scripts that one font does not cover:
final font = freetype.heaps.FreeTypeFont.fromFiles([
// windows
"C:/Windows/Fonts/segoeui.ttf",
"C:/Windows/Fonts/seguisym.ttf",
"C:/Windows/Fonts/arial.ttf",
"C:/Windows/Fonts/Nirmala.ttf",
// linux
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
"/usr/share/fonts/truetype/dejavu/DejaVuSansCondensed.ttf",
"/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc"
], 24, {
chars: "Hello Привет हिन्दी 中文 日本語 한국어",
kerning: true,
});fromFiles() bakes one atlas and chooses the first font that contains each requested character.
It does not magically cover all Unicode; the provided font files must contain the glyphs you want to render.
TTC collections load all contained faces by default. With dynamicFromSources(), set faceIndex on a source to load only one face from a collection.
Use dynamicFromFiles() when text can contain characters that were not known up front.
Characters listed in chars are preloaded, and later missing glyphs are rendered into the atlas on demand.
Create from bytes:
final bytes = sys.io.File.getBytes("font.ttf");
final font = freetype.heaps.FreeTypeFont.fromBytes(bytes, 24);Register TTF/OTF/TTC files as Heaps resources:
--macro freetype.heaps.Macro.main()Then load them through hxd.Res:
final font = hxd.Res.fonts.my_font.toFont(24);
final dynamicFont = hxd.Res.fonts.my_font.toDynamicFont(24);If you need access to the generated atlas pixels:
final atlas = freetype.heaps.FreeTypeFont.buildAtlas(bytes, 24, {
chars: hxd.Charset.DEFAULT_CHARS,
uploadTexture: true,
});
final font = atlas.font;
final pixels = atlas.pixels;For multi-font atlases:
final atlas = freetype.heaps.FreeTypeFont.buildAtlasFromFiles(paths, 24, {
chars: textToRender,
});Options:
chars: characters to bake into the atlasantiAliasing: render grayscale glyphs when enabledkerning: add FreeType kerning pairspadding: glyph padding in the atlasatlasWidth: fixed atlas width, or auto when omitteduploadTexture: create a real Heaps texture when enabled
FreeType is fetched and built automatically by CMake.
The same FreeType version is used on Windows and Linux.
FreeType is linked statically into freetype.hdll, so users do not need a separate FreeType DLL or shared library.
Common requirements:
- CMake 3.10+
- Ninja
- Git
HASHLINKenvironment variable pointing to a HashLink installation or source tree
Windows additionally requires:
- Visual Studio / MSVC build tools
Linux additionally requires:
- GCC or Clang
- standard build tools
Set HASHLINK to your HashLink directory:
$env:HASHLINK = "C:\Path\To\HashLink"Configure:
cmake --preset windows-release --freshBuild:
cmake --build --preset windows-releaseOutput:
out/build/windows-release/extension/freetype.hdll
out/build/windows-release/extension/freetype.lib
The native module is:
freetype.hdll
Place it next to your .hl output, or otherwise make sure HashLink can load it.
Install the basic build dependencies.
Ubuntu/Debian:
sudo apt-get update
sudo apt-get install -y build-essential git cmake ninja-buildSet HASHLINK to your HashLink installation or source tree:
export HASHLINK=/path/to/hashlinkConfigure:
cmake --preset linux-release --freshBuild:
cmake --build --preset linux-releaseOutput:
out/build/linux-release/extension/freetype.hdll
Place freetype.hdll next to your .hl output, or otherwise make sure HashLink can load it.
If libhl.so is not installed system-wide, make sure it can also be found at runtime, for example:
export LD_LIBRARY_PATH="$HASHLINK:${LD_LIBRARY_PATH:-}"The test suite covers:
- FreeType initialization
- font loading
- face metrics
- kerning
- glyph lookup
- glyph rendering
- TTF/OTF support
- TTC collections when a TTC test font is available
- invalid input handling
- deterministic Heaps atlas creation
Compile:
cd tests/testMain
haxe test-hl.hxmlRun:
hl test.hlCompile:
cd tests/testMain
haxe test-heaps.hxmlRun:
hl test-heaps.hlConvenience launchers are also available on Windows:
tests/test-hl.battests/test-heaps.battests/test-heaps-window.bat
test-hl checks plain FreeType loading, metrics, kerning, glyph rendering and invalid input.
test-heaps checks deterministic h2d.Font atlas creation without opening a window.
test-heaps-window opens a Heaps window and renders multilingual Unicode sample text using multiple fallback fonts. Press Escape to close.
Tests first look for explicitly configured test fonts and then fall back to common system fonts.
To specify a TTF or OTF test font:
$env:HLFREETYPE_TEST_FONT = "C:\Path\To\font.ttf"or in cmd.exe:
set HLFREETYPE_TEST_FONT=C:\Path\To\font.ttfexport HLFREETYPE_TEST_FONT=/path/to/font.ttfFor example:
export HLFREETYPE_TEST_FONT=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttfTo explicitly specify a TTC collection:
$env:HLFREETYPE_TEST_TTC = "C:\Windows\Fonts\msyh.ttc"export HLFREETYPE_TEST_TTC=/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttcOn Ubuntu/Debian, useful test fonts can be installed with:
sudo apt-get install -y fonts-dejavu-core fonts-noto-cjkGitHub Actions builds and tests the native extension on both Windows and Linux.
The workflow runs against:
- Windows x86_64
- Linux x86_64
- Haxe 4.3.7
- latest Haxe
Nightly builds are published when changes are pushed to main.
Release artifacts:
hlfreetype-windows.zip
hlfreetype-linux.tar.gz
The Windows archive contains:
freetype.hdll
freetype.lib
The Linux archive contains:
freetype.hdll
FreeType itself is statically linked into the native module.
HashLink must still be installed or otherwise available on the target system.
- macOS support