StbTrueType
Managed-only rasterizer backend for KernSmith using StbTrueTypeSharp. No native dependencies -- verified on Windows, Linux x64 and arm64, macOS, Android, iOS, and Mac Catalyst, builds for Blazor WASM, and suited to NativeAOT and serverless environments -- see the platform support table.
Installation
dotnet add package KernSmith.Rasterizers.StbTrueType
Platform: Cross-platform (net8.0, net10.0). No native binaries required.
Usage
The rasterizer auto-registers via [ModuleInitializer] -- referencing the package is sufficient. Select it in options:
var options = new FontGeneratorOptions
{
Size = 32,
Backend = RasterizerBackend.StbTrueType
};
var result = BmFont.Generate("path/to/font.ttf", options);
Capabilities
- TTF input
- Anti-aliasing (Grayscale and None modes)
- SDF (Signed Distance Field) rendering
- Super sampling
- Synthetic bold and italic
- Fractional font sizes (e.g.
Size = 32.5f) honored natively
Synthetic Bold and Italic
StbTrueType supports synthetic bold and italic through outline-level post-processors that modify glyph outlines before rasterization. This works with both normal and SDF rendering modes.
- Synthetic bold applies emboldening at a strength of ppem/24, matching FreeType's
FT_GlyphSlot_Emboldenalgorithm. The post-processor widens glyph outlines and adjusts advance widths and bearings accordingly. - Synthetic italic applies a horizontal shear of tan(12 degrees) (~0.2126), matching FreeType's
FT_GlyphSlot_Obliquealgorithm. The post-processor skews glyph outlines and adjusts metrics to account for the added width. - SDF support uses a vendored SDF rasterization function so that bold/italic outline modifications are captured in the distance field output.
This is novel work -- no other StbTrueTypeSharp consumer (including FontStashSharp) implements outline-level synthetic bold or italic.
Limitations
- No TrueType hinting (lower quality at small sizes < 16px)
- No color font support (COLR/CPAL, CBDT/sbix)
- No variable font axis support
- No vector outlines (
OutlineMode.Vectorfalls back to core's bitmap outline effect, which works as usual), and noWidthPercentor non-defaultItalicAngle(NotSupportedException) - No system font loading -- provide font file bytes directly
- TrueType and CFF (
.otf) outlines, but not CFF2 (variable.otf); WOFF/WOFF2 work because core decompresses them first
Native AOT and Trimming
StbTrueType is the recommended backend for Native AOT and trimming -- it is pure C#, has no native dependencies, and is the only published backend marked AOT-compatible. (The experimental Native backend is also AOT-annotated, but it is not published to NuGet.)
KernSmith's auto-discovery resolves backends by name via reflection, which does not work under Native AOT or trimming: the backend may be trimmed away or cannot be resolved by name, so generation fails with a "backend is not registered" error. You must register the backend explicitly.
Force the backend assembly to load so its module initializer registers the rasterizer, and reference the public StbTrueTypeRasterizer type by name so it is not trimmed:
using System.Runtime.CompilerServices;
using KernSmith;
using KernSmith.Rasterizers.StbTrueType;
// Required under Native AOT / trimming -- auto-discovery cannot find the backend.
RuntimeHelpers.RunClassConstructor(typeof(StbTrueTypeRasterizer).TypeHandle);
var result = BmFont.Generate("path/to/font.ttf", new FontGeneratorOptions
{
Size = 32,
Characters = CharacterSet.Ascii,
Backend = RasterizerBackend.StbTrueType
});
Or register a factory directly through the public RasterizerFactory API:
using KernSmith.Rasterizer;
using KernSmith.Rasterizers.StbTrueType;
RasterizerFactory.Register(RasterizerBackend.StbTrueType, () => new StbTrueTypeRasterizer());
See the rasterizers overview for more detail. The FreeType, GDI, and DirectWrite backends use native interop and are not targeted for AOT (FreeType has been verified in fully trimmed Android Release builds when registered explicitly).
When to Use
Use StbTrueType when you need bitmap font generation on platforms where native FreeType binaries are unavailable: Blazor WebAssembly, NativeAOT trimmed deployments, Linux arm64, Mac Catalyst, serverless containers, or any environment where zero native dependencies is a requirement. For full-featured rendering, use the FreeType backend instead (not on iOS, where it fails to link). See the platform support table.
Blazor WASM
StbTrueType is the recommended backend for Blazor WebAssembly. A complete working sample is available in samples/KernSmith.Samples.BlazorWasm/.
Setup
- Reference
KernSmithandKernSmith.Rasterizers.StbTrueType(do NOT reference FreeType) - Force assembly load in
Program.csto prevent trimming:
RuntimeHelpers.RunClassConstructor(
typeof(KernSmith.Rasterizers.StbTrueType.StbTrueTypeRasterizer).TypeHandle);
- Enable AOT compilation for production performance:
<RunAOTCompilation>true</RunAOTCompilation>
WASM Considerations
- Use in-memory APIs (
FntText,GetPngData()) —ToFile()is not available in the browser - System font loading is unavailable — use
LoadFont()with font bytes orBmFont.RegisterFont() - The WASM runtime is single-threaded — batch parallelism is automatically disabled
- Default heap is ~127 MB — subsetting is recommended for large CJK fonts
- AOT compilation improves performance ~5-18x over the interpreter
Performance (Roboto-Regular, 32px, ASCII)
| Mode | AOT (warm) | Interpreter |
|---|---|---|
| Normal | ~14 ms | ~256 ms |
| SDF | ~51 ms | ~1,344 ms |