Rasterizers
KernSmith supports multiple rasterizer backends through a pluggable IRasterizer interface. All backends are available as separate NuGet packages -- two cross-platform (FreeType, StbTrueType) and two Windows-only (GDI, DirectWrite). 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) |
Capability Comparison
| Feature | FreeType | GDI | DirectWrite | StbTrueType |
|---|---|---|---|---|
| Cross-platform | Yes | No | No | Yes |
| Color fonts (COLR/CPAL) | No | No | Yes | No |
| Variable fonts | No | No | Yes | No |
| SDF rendering | Yes | No | No | Yes |
| Outline stroke | Yes | No | No | No |
| System font loading | No | Yes | Yes | No |
| BMFont.exe parity | No | Yes | No | No |
| ClearType / subpixel | No | No | Yes | No |
| Synthetic bold/italic | Yes | Partial | Yes | Yes |
| Font formats | TTF, OTF, WOFF, WOFF2 | System fonts only | TTF, OTF, WOFF, WOFF2 | TTF only |
| Native dependencies | Yes | Yes | Yes | None |
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 backend marked AOT-compatible.
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. The core KernSmith library itself is AOT- and trim-compatible.
Choosing a Backend
Use this decision tree to pick the right backend:
- Need cross-platform support? Use FreeType -- it is the only backend that runs on Linux, macOS, and Windows.
- Need pixel-perfect BMFont.exe compatibility? Use GDI -- it matches BMFont's native rasterizer output.
- Need color fonts or variable font axes? Use DirectWrite -- it is the only backend with COLR/CPAL and fvar support.
- Need SDF (Signed Distance Field) output? Use FreeType or StbTrueType -- they are the only backends with SDF rendering.
- Need cross-platform SDF without native binaries? Use StbTrueType -- it supports SDF and runs fully managed.
- Need WASM/Blazor or NativeAOT without native binaries? Use StbTrueType -- it is the only fully managed backend with zero native dependencies. See the Blazor WASM sample for a working example. Enable AOT compilation for production performance.
- 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,
RasterizerBackend = RasterizerBackend.FreeType // default
// RasterizerBackend = RasterizerBackend.Gdi // Windows GDI
// RasterizerBackend = RasterizerBackend.DirectWrite // Windows DirectWrite
// RasterizerBackend = RasterizerBackend.StbTrueType // managed, no native deps
};
From the CLI, use kernsmith list-rasterizers to see which backends are available on the current machine.