dotnet/wpf · error · ArgumentOutOfRangeException
SR.GlyphIndexOutOfRange
Error message
SR.GlyphIndexOutOfRange
What it means
The GlyphMetrics helper throws ArgumentOutOfRangeException with SR.GlyphIndexOutOfRange when the supplied glyphIndex is greater than or equal to the font's GlyphCount as reported by DirectWrite. Glyph indices are font-specific and bounded by the font's glyph table size; querying metrics, sidebearings, or advance geometry for an out-of-bounds index would access undefined data.
Solutions
- Verify glyphIndex < GlyphTypeface... glyph count before calling; expose the count via the underlying FontFace GlyphCount and guard the call
- Obtain glyph indices from the same GlyphTypeface instance via its CharacterToGlyphMap, never across different faces
- Reset/recompute cached glyph indices whenever the font face changes
- Catch ArgumentOutOfRangeException around metric queries and treat them as missing-glyph cases
Example fix
// before
var metrics = glyphTypeface.GlyphMetrics(glyphIndex, textFormattingMode, pixelsPerDip);
// after
if (glyphIndex < fontFaceGlyphCount)
var metrics = glyphTypeface.GlyphMetrics(glyphIndex, textFormattingMode, pixelsPerDip);
else
/* treat as missing glyph / use 0 index */; Defensive patterns
Strategy: validation
Validate before calling
bool IsValidGlyphIndex(GlyphTypeface face, ushort glyphIndex)
{
// DirectWrite bounds: must be < GlyphCount of the underlying font face
return glyphIndex < face.CharToFriendlyGlyphNameMap.Count; // or cache face's GlyphCount via _font.GetFontFace().GlyphCount
} Type guard
static bool IsInGlyphRange(ushort glyphIndex, ushort glyphCount) => glyphIndex < glyphCount;
Try / catch
try
{
var metrics = glyphTypeface.GlyphMetrics(glyphIndex, mode, pixelsPerDip);
}
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "glyphIndex")
{
// treat as missing glyph: fall back to index 0 (.notdef)
var metrics = glyphTypeface.GlyphMetrics(0, mode, pixelsPerDip);
} Prevention
- Only reuse glyph indices with the same GlyphTypeface they were derived from
- Clear caches of glyph indices when the font face/family changes
- Fall back to glyph index 0 (.notdef) for unmapped or invalid indices
- Validate CharacterToGlyphMap lookups for sentinel/miss values before querying metrics
When it happens
Trigger: Calling glyphMetrics, GetLeftSidebearing, GetRightSidebearing, GetTopSidebearing, or GetBottomSidebearing with a glyphIndex that came from a different font, from an unvalidated CharacterToGlyphMap miss, or from hardcoded assumptions about glyph numbering.
Common situations: Reusing cached glyph indices after switching the GlyphTypeface/font family; mapping a character to a glyph in one font and using the index against another font; fonts loaded via font fallback where indices differ per face; corrupted CharacterToGlyphMap lookups returning sentinel values.
Related errors
- Argument out of range (position not contained in view)
- Count must be 1 when CommitPolicies is set to…
- FileFormatException
- FileFormatException
- FileFormatException(new Uri(fileName…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/82110cd359683eac.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphTypeface.cs:1061
out bsb,
out baseline
);
return ah;
}
private unsafe MS.Internal.Text.TextInterface.GlyphMetrics GlyphMetrics(ushort glyphIndex,
double emSize,
float pixelsPerDip,
TextFormattingMode textFormattingMode,
bool isSideways)
{
MS.Internal.Text.TextInterface.GlyphMetrics glyphMetrics;
MS.Internal.Text.TextInterface.FontFace fontFaceDWrite = _font.GetFontFace();
try
{
if (glyphIndex >= fontFaceDWrite.GlyphCount)
throw new ArgumentOutOfRangeException(nameof(glyphIndex), SR.Format(SR.GlyphIndexOutOfRange, glyphIndex));
glyphMetrics = new MS.Internal.Text.TextInterface.GlyphMetrics();
if (textFormattingMode == TextFormattingMode.Ideal)
{
// We can safely pass pointers to glyphIndex and glyphMetrics since both are value types and are allocated on the stack.
fontFaceDWrite.GetDesignGlyphMetrics(&glyphIndex, 1, &glyphMetrics);
}
else
{
// We can safely pass pointers to glyphIndex and glyphMetrics since both are value types and are allocated on the stack.
fontFaceDWrite.GetDisplayGlyphMetrics(&glyphIndex, 1, &glyphMetrics, checked((float)emSize),
textFormattingMode != TextFormattingMode.Display, isSideways, pixelsPerDip);
}
}
finally
{
fontFaceDWrite.Release();View on GitHub (pinned to 81131a70a4)