Table of Contents

Rasterizers

KernSmith supports multiple rasterizer backends through a pluggable IRasterizer interface. Four backends are available as separate NuGet packages -- two cross-platform (FreeType, StbTrueType) and two Windows-only (GDI, DirectWrite). A fifth, Native, is experimental and not published to NuGet yet. You can also write your own.

Backends

Backend Package Platform
FreeType KernSmith.Rasterizers.FreeType Cross-platform
GDI KernSmith.Rasterizers.Gdi Windows only
DirectWrite KernSmith.Rasterizers.DirectWrite.TerraFX Windows only
StbTrueType KernSmith.Rasterizers.StbTrueType Cross-platform (managed)
Native (experimental) KernSmith.Rasterizers.Native -- not published yet Cross-platform (managed)

For per-OS status (Windows, Linux, macOS, Android, iOS, Mac Catalyst, Blazor WASM), see the platform support table.

Capability Comparison

Feature FreeType GDI DirectWrite StbTrueType Native
Cross-platform Yes No No Yes Yes
Color fonts Yes (COLR v0, CBDT/sbix) No No No Yes (COLR v0 and v1, CBDT/sbix)
Variable fonts Yes No No No Yes
SDF rendering Yes No No Yes Yes
MSDF / MTSDF No No No No Yes
Vector outline (OutlineMode.Vector) No No No No Yes
Synthetic width / italic angle No No No No Yes
System font loading No Yes Yes No No
BMFont.exe parity No Yes No No No
ClearType-hinted grayscale No No Yes No No
Synthetic bold/italic Yes Yes Yes Yes Yes
Hinting Yes Yes Yes No Light only (own vertical auto-hinter)
Anti-aliasing modes Grayscale, Light, LCD, None Grayscale, None Grayscale, None Grayscale, None Grayscale, Light, LCD, None
LCD subpixel order / filter No No No No Yes
Font formats TTF, OTF, WOFF, WOFF2 TTF, OTF, WOFF, WOFF2 TTF, OTF, WOFF, WOFF2 TTF, OTF (not CFF2), WOFF, WOFF2 TTF, OTF, WOFF, WOFF2
Native dependencies Yes Yes Yes None None
Published on NuGet Yes Yes Yes Yes No

WOFF and WOFF2 are decompressed by KernSmith core before rasterization, so all backends accept them for fonts whose outlines they otherwise support. Outlines (Outline) work on every backend as core's bitmap effect; OutlineMode.Vector falls back to it on backends without a vector outline, while a non-default WidthPercent or ItalicAngle there throws NotSupportedException.

Auto-Registration

All built-in backend packages are auto-discovered by RasterizerFactory on first call to Create(), GetAvailableBackends(), or IsRegistered(). Simply referencing the NuGet package is enough -- no manual setup code is required. Third-party backends use [ModuleInitializer] for self-registration.

How Auto-Discovery Works

RasterizerFactory.DiscoverBackends() resolves a known, fixed set of backend assemblies by name using reflection (Type.GetType(typeName)). For each backend type it resolves, it invokes that type's Register() method via reflection (falling back to running the assembly's module constructor) so the backend registers itself. The first backend successfully registered becomes the default.

Because this discovery relies on reflection and name-based type resolution, it does not work under Native AOT or trimming -- see Native AOT and Trimming.

Native AOT and Trimming

Auto-discovery resolves backend assemblies by name via reflection, which is not compatible with Native AOT or trimming. Under AOT or trimming the backend types may be removed from the published output or cannot be resolved by name, so auto-discovery finds nothing and generation fails with a "backend is not registered" error.

You must register a backend explicitly before generating a font. The recommended AOT backend is StbTrueType: it is pure C#, has no native dependencies, and is the only published backend marked AOT-compatible. (The experimental Native backend is also pure C# and AOT-annotated, but it is not published to NuGet.)

Force the backend assembly to load so its module initializer registers the rasterizer. Reference its public StbTrueTypeRasterizer type by name to keep it from being trimmed away:

using System.Runtime.CompilerServices;
using KernSmith;
using KernSmith.Rasterizers.StbTrueType;

// Required under Native AOT / trimming -- auto-discovery cannot find the backend.
// Touching the type triggers its [ModuleInitializer] registration and prevents trimming.
RuntimeHelpers.RunClassConstructor(typeof(StbTrueTypeRasterizer).TypeHandle);

var result = BmFont.Generate("path/to/font.ttf", new FontGeneratorOptions
{
    Size = 32,
    Characters = CharacterSet.Ascii,
    Backend = RasterizerBackend.StbTrueType
});

Alternatively, register a factory directly through the public RasterizerFactory API:

using KernSmith.Rasterizer;
using KernSmith.Rasterizers.StbTrueType;

RasterizerFactory.Register(RasterizerBackend.StbTrueType, () => new StbTrueTypeRasterizer());

The FreeType, GDI, and DirectWrite backends use P/Invoke and native interop and are not targeted for AOT, so prefer StbTrueType in AOT or trimmed apps. FreeType has nonetheless been verified working in fully trimmed Android Release builds when registered explicitly with RasterizerFactory.Register(...). The core KernSmith library itself is AOT- and trim-compatible.

Choosing a Backend

Use this decision tree to pick the right backend:

  1. Need cross-platform support? Use FreeType, StbTrueType, or Native -- all three run on Windows, Linux x64, macOS, and Android. FreeType has the richest feature set; StbTrueType also runs in Blazor WASM. See the platform support table.
  2. Need pixel-perfect BMFont.exe compatibility? Use GDI -- it matches BMFont's native rasterizer output.
  3. Need color fonts or variable font axes? Use FreeType -- it is the only published backend that implements COLR/CPAL color glyphs and fvar variable font axes (the experimental Native backend also renders COLR version 0 and 1 and CBDT/sbix color glyphs and variable fonts). (DirectWrite's real niche is ClearType-hinted grayscale rendering and loading system fonts on Windows; its color and variable font paths are currently stubbed.)
  4. Need SDF (Signed Distance Field) output? Use FreeType or StbTrueType -- the published backends with SDF rendering. The experimental Native backend renders SDF too, and is the only one with multi-channel MSDF/MTSDF.
  5. Need cross-platform SDF without native binaries? Use StbTrueType -- it supports SDF and runs fully managed.
  6. Need WASM/Blazor or NativeAOT without native binaries? Use StbTrueType -- it is the only published fully managed backend with zero native dependencies. See the Blazor WASM sample for a working example. Enable AOT compilation for production performance.
  7. Want zero third-party code, and building from source? Try Native -- KernSmith's own rasterizer. It renders TrueType and OpenType (CFF/CFF2) fonts, variable and color fonts, SDF and MSDF, vector outlines and synthetic width/italic angle with no external dependencies at all, but it is experimental and unpublished and hints only in Light mode.
  8. Not sure? Start with FreeType. It covers the majority of use cases.

Selecting a Backend in Code

Pass the RasterizerBackend enum in your options:

var options = new FontGeneratorOptions
{
    Size = 32,
    Backend = RasterizerBackend.FreeType      // default
    // Backend = RasterizerBackend.Gdi         // Windows GDI
    // Backend = RasterizerBackend.DirectWrite  // Windows DirectWrite
    // Backend = RasterizerBackend.StbTrueType  // managed, no native deps
    // Backend = RasterizerBackend.Native       // experimental, not on NuGet yet
};

From the CLI, use kernsmith list-rasterizers to see which backends are available on the current machine.