stride3d/stride · error · Exception

SDF Font from image is not supported!

Error message

SDF Font from image is not supported!

What it means

SignedDistanceFieldFontCompiler.ImportFont classifies the font source by file extension: .bmp, .png, or .gif are treated as bitmap sources, and generating signed distance fields from raster images is not supported by this importer, so it throws immediately. SDF fonts must be generated from a vector font file (TTF/OTF).

Solutions

  1. Set FontSource to the original vector font file (.ttf, .otf) the image was derived from.
  2. If only the image exists, obtain the matching font file — an SDF font cannot be generated from a bitmap.
  3. Use the regular rasterized sprite font pipeline for image-based sources instead.
  4. Check the FontSource path for a wrong extension or a file that was renamed to an image extension.

Example fix

// before (font asset)
<FontSource>ui_font.png</FontSource>
// after
<FontSource>ui_font.ttf</FontSource>
Defensive patterns

Strategy: validation

Validate before calling

var ext = (Path.GetExtension(fontAsset.FontSource.GetFontPath()) ?? "").ToLowerInvariant();
if (new[] { ".bmp", ".png", ".gif" }.Contains(ext))
    throw new InvalidOperationException($"SDF compilation requires a vector font (.ttf/.otf), got '{ext}'");

Type guard

bool IsVectorFontSource(SpriteFontAsset asset) =>
    !new[] { ".bmp", ".png", ".gif" }.Contains((Path.GetExtension(asset.FontSource.GetFontPath()) ?? "").ToLowerInvariant());

Try / catch

try
{
    var font = SignedDistanceFieldFontCompiler.Compile(factory, fontAsset);
}
catch (Exception ex) when (ex.Message == "SDF Font from image is not supported!")
{
    logger.LogError("FontSource for {Name} is a bitmap; supply the original vector font file", fontAsset.Name);
    throw; // fail the build — a bitmap source cannot be auto-converted
}

Prevention

When it happens

Trigger: Compiling an SDF font whose FontSource path ends in .bmp, .png, or .gif — the extension check flags importFromBitmap and throws before the SignedDistanceFieldFontImporter is even created.

Common situations: Pointing an SDF font asset at a texture image instead of the original TTF; migrating a legacy rasterized font project that referenced PNG atlases to SDF; a wrong FontSource path/extension.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/cd63b8e35305ed25. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Assets/SpriteFont/Compiler/SignedDistanceFieldFontCompiler.cs:129

            var glyphs = ImportFont(fontAsset, out lineSpacing, out baseLine);

            Image<Rgba32> bitmap = GlyphPacker.ArrangeGlyphs(glyphs);

            return SignedDistanceFieldFontWriter.CreateSpriteFontData(fontFactory, fontAsset, glyphs, lineSpacing, baseLine, bitmap);
        }

        static Glyph[] ImportFont(SpriteFontAsset options, out float lineSpacing, out float baseLine)
        {
            // Which importer knows how to read this source font?
            IFontImporter importer;

            var sourceExtension = (Path.GetExtension(options.FontSource.GetFontPath()) ?? "").ToLowerInvariant();
            var bitmapFileExtensions = new List<string> { ".bmp", ".png", ".gif" };
            var importFromBitmap = bitmapFileExtensions.Contains(sourceExtension);
            if (importFromBitmap)
            {
                throw new Exception("SDF Font from image is not supported!");
            }

            importer = new SignedDistanceFieldFontImporter();

            // create the list of character to import
            var characters = GetCharactersToImport(options);

            // Import the source font data.
            importer.Import(options, characters);

            lineSpacing = importer.LineSpacing;
            baseLine = importer.BaseLine;

            // Get all glyphs
            var glyphs = new List<Glyph>(importer.Glyphs);

            // Validate.
            if (glyphs.Count == 0)

View on GitHub (pinned to 96fad776d2)