Color Fonts
Color fonts are one of the clearest signs of how much richer modern text rendering has become. Instead of a single monochrome outline, a glyph can carry layers, gradients, or even SVG content, and Fonts exposes that support explicitly through ColorFontSupport.
Fonts has comprehensive support for the major OpenType color-font technologies it exposes publicly:
ColorFontSupport.ColrV0for layered solid-color glyphs defined by COLR and CPAL tablesColorFontSupport.ColrV1for paint-graph glyphs with gradients, transforms, and richer compositionColorFontSupport.Svgfor color glyphs stored in the OpenType SVG table
Enable or restrict color-font support
TextOptions.ColorFontSupport controls which color-font technologies are honored during layout and rendering.
using SixLabors.Fonts;
FontCollection collection = new();
FontFamily family = collection.Add("fonts/NotoColorEmoji-Regular.ttf");
Font font = family.CreateFont(32);
TextOptions options = new(font)
{
ColorFontSupport = ColorFontSupport.ColrV1 | ColorFontSupport.ColrV0 | ColorFontSupport.Svg
};
TextOptions enables all three by default, so you usually only need to set this property when you want to disable color glyphs or restrict the allowed formats.
Force monochrome output
Set ColorFontSupport.None when you want color-font-capable text to fall back to monochrome outline rendering.
using SixLabors.Fonts;
FontCollection collection = new();
FontFamily family = collection.Add("fonts/NotoColorEmoji-Regular.ttf");
Font font = family.CreateFont(32);
TextOptions options = new(font)
{
ColorFontSupport = ColorFontSupport.None
};
What happens in custom renderers
When a resolved glyph is a painted color glyph, Fonts streams it through IGlyphRenderer as one or more layers.
That means custom renderers should pay attention to:
Depending on the font technology in use, the Paint passed to BeginLayer(...) may be:
If your renderer ignores paint information, the glyph can still be drawn, but it will no longer preserve the font's intended color presentation.
Inspect color glyphs directly
If you need to inspect a glyph without running full text layout, use Font.TryGetGlyphs(...) with explicit color support.
using SixLabors.Fonts;
using SixLabors.Fonts.Unicode;
FontCollection collection = new();
FontFamily family = collection.Add("fonts/NotoColorEmoji-Regular.ttf");
Font font = family.CreateFont(32);
if (font.TryGetGlyphs(
new CodePoint(0x1F600), // 😀 GRINNING FACE
ColorFontSupport.ColrV1 | ColorFontSupport.ColrV0 | ColorFontSupport.Svg,
out Glyph? glyph))
{
bool isPainted = glyph.GlyphMetrics.GlyphType == GlyphType.Painted;
}
COLR vs SVG in practice
At a high level:
- COLR v0 uses layered shapes with palette colors
- COLR v1 extends that model with richer paint graphs, gradients, transforms, and clipping
- SVG glyphs carry SVG-authored painted content
Fonts resolves those technologies into a common painted-glyph rendering flow, which is why custom renderers can consume them through the same layer and paint callbacks.
Measurement and rendering stay aligned
Color-font support is part of text layout, not just final painting. If you measure text with one ColorFontSupport configuration and render with another, you can create drift between the measured and rendered result.
Use the same TextOptions instance for both TextMeasurer and TextRenderer when you want a guaranteed match.
For renderer implementation details, see Custom Rendering. For fallback across multiple families, see Fallback Fonts and Multilingual Text.
Practical guidance
- Use the same
ColorFontSupportsetting when measuring and rendering. - Test the actual emoji or color glyph set you intend to support; technologies vary by font.
- Decide fallback order deliberately when both monochrome and color families can cover the same text.
- Custom renderers should handle painted glyph callbacks even if most text is outline-based.