Table of Contents

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_Embolden algorithm. 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_Oblique algorithm. 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.Vector falls back to core's bitmap outline effect, which works as usual), and no WidthPercent or non-default ItalicAngle (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

  1. Reference KernSmith and KernSmith.Rasterizers.StbTrueType (do NOT reference FreeType)
  2. Force assembly load in Program.cs to prevent trimming:
RuntimeHelpers.RunClassConstructor(
    typeof(KernSmith.Rasterizers.StbTrueType.StbTrueTypeRasterizer).TypeHandle);
  1. 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 or BmFont.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