SeasonMSDF 0.1.0
dotnet add package SeasonMSDF --version 0.1.0
NuGet\Install-Package SeasonMSDF -Version 0.1.0
<PackageReference Include="SeasonMSDF" Version="0.1.0" />
<PackageVersion Include="SeasonMSDF" Version="0.1.0" />
<PackageReference Include="SeasonMSDF" />
paket add SeasonMSDF --version 0.1.0
#r "nuget: SeasonMSDF, 0.1.0"
#:package SeasonMSDF@0.1.0
#addin nuget:?package=SeasonMSDF&version=0.1.0
#tool nuget:?package=SeasonMSDF&version=0.1.0
SeasonMSDF
SeasonMSDF is a fully managed C# MSDF/MTSDF generation library based on the
msdfgen pipeline and bundled Typography.OpenFont outline loading.
Project repository:
Highlights
- Pure C# backend for shape loading, edge coloring, and MSDF/MTSDF generation
- Built-in OpenType/TrueType outline reading through
Typography.OpenFont - API structure closely aligned with
msdfgenconcepts such asShape,Projection,Range, andMSDFGeneratorConfig - Suitable for font atlas generation, offline tooling, and custom text renderers
Installation
dotnet add package SeasonMSDF
Minimal Example
The example below uses the pure managed backend only.
using SeasonMSDF;
using Typography.OpenFont;
static (float[] pixels, int width, int height) GenerateGlyphMtsdf(
string fontPath,
int codePoint,
int fontSize = 32,
float pixelRange = 8f,
float angleThreshold = 3f)
{
using FileStream stream = File.OpenRead(fontPath);
Typeface typeface = new OpenFontReader().Read(stream)
?? throw new InvalidOperationException("Failed to read font.");
ushort glyphIndex = typeface.GetGlyphIndex(codePoint);
Glyph glyph = typeface.GetGlyph(glyphIndex);
if (glyph.GlyphPoints == null || glyph.EndPoints == null)
throw new InvalidOperationException("Glyph outline is not available.");
var builder = new GlyphShapeBuilder();
float geometryScale = 1.0f / typeface.UnitsPerEm;
builder.Read(glyph.GlyphPoints, glyph.EndPoints, geometryScale);
Shape shape = builder.Shape;
if (shape.Contours.Count == 0)
throw new InvalidOperationException("Glyph has no contours.");
shape.OrientContours();
shape.Normalize();
EdgeColoring.EdgeColoringInkTrap(shape, angleThreshold, seed: 0);
float glyphScale = fontSize * 2.0f;
Shape.Bounds bounds = shape.GetBounds();
double border = pixelRange / glyphScale;
int width = (int)Math.Ceiling((bounds.R - bounds.L + 2.0 * border) * glyphScale);
int height = (int)Math.Ceiling((bounds.T - bounds.B + 2.0 * border) * glyphScale);
var bitmap = new Bitmap(width, height, 4);
var projection = new Projection(
new Vector2(glyphScale, glyphScale),
new Vector2(border - bounds.L, border - bounds.B));
var range = new Range(pixelRange / glyphScale);
Msdfgen.GenerateMTSDF(bitmap.Section(), shape, projection, range, new MSDFGeneratorConfig());
return (bitmap.GetRawData(), width, height);
}
Notes:
- The returned
float[]contains 4 channels per pixel in linear float form. - You can convert the result into your own texture format or preview it with your own renderer.
- The sample intentionally uses only the managed backend and does not depend on the optional native interop path.
Root Cause Found During Validation
During validation against native msdfgen, several implementation differences
were investigated. Most of them were secondary and had limited impact on the
main rendering mismatch.
The actual root cause was in GlyphShapeBuilder.CloseContour().
The managed glyph importer did not always emit an explicit closing edge from the current contour endpoint back to the contour start. That caused some managed contours to remain open while the native pipeline used closed contours for the same glyphs.
The effective fix was straightforward:
- record the contour start in
MoveTo() - keep tracking the current point during edge construction
- add a closing line in
CloseContour()when the contour endpoint has not yet returned to the recorded start point
Once this was fixed, the managed and native outputs became highly similar both visually and in stage-by-stage pipeline logs.
Current Status
- The major glyph-import topology mismatch has been resolved
- Managed output is now much closer to native
msdfgen - Remaining differences are mostly small numeric or channel-level deviations
Key File
SeasonMSDF/core/GlyphShapeBuilder.cs
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 80 | 7/11/2026 |