dotnet/wpf · error · NotSupportedException

NotSupportedException

Error message

NotSupportedException

What it means

GlyphTypeface implements IDictionary<ushort,double> to expose glyph-to-advance metrics, but this dictionary is read-only: the Add(ushort,double) implementation is an explicit stub that always throws NotSupportedException. The library never supports mutating glyph metrics through this interface because the values come from the underlying font file's glyph data and cannot be modified.

Solutions

  1. Do not mutate the dictionary; build a separate Dictionary<ushort,double> copy and modify that
  2. Check IDictionary.IsReadOnly (or ICollection<KeyValuePair<ushort,double>>.IsReadOnly) before calling Add and skip or copy
  3. If you need different advance widths, apply them at the text-formatting level (e.g. GlyphRun/Typeface APIs) rather than editing GlyphTypeface

Example fix

// before
IDictionary<ushort,double> metrics = glyphTypeface.AdvanceHeights;
metrics.Add(42, 0.5); // NotSupportedException
// after
var metrics = new Dictionary<ushort,double>(glyphTypeface.AdvanceHeights);
metrics[42] = 0.5; // modify your own copy
Defensive patterns

Strategy: try-catch

Validate before calling

// check before mutating
var dict = (IDictionary<ushort,double>)glyphTypeface.AdvanceHeights;
if (dict.IsReadOnly)
    dict = new Dictionary<ushort,double>(dict); // editable copy

Type guard

bool IsMutable(IDictionary<ushort,double> d) => !d.IsReadOnly;

Try / catch

try {
    metrics.Add(glyphIndex, value);
} catch (NotSupportedException) {
    var copy = new Dictionary<ushort,double>(metrics);
    copy[glyphIndex] = value; // fall back to a copy
}

Prevention

When it happens

Trigger: Casting a GlyphTypeface's glyph-metrics dictionary (e.g. its AdvanceHeights/IDictionary<ushort,double> view) to IDictionary<ushort,double> or IDictionary and calling Add(key, value) on it.

Common situations: Developers treating GlyphTypeface as a writable dictionary — e.g. copying metrics with collection-initializer syntax, writing custom glyph-override code, or generic code that populates an IDictionary<ushort,double> passed in from the caller.

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 dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/67c9bc9a6339e27c. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphTypeface.cs:1737

        private delegate double GlyphAccessor(ushort glyphIndex, float pixelsPerDip, TextFormattingMode textFormattingMode, bool isSideways);

        /// <summary>
        /// This class is a helper to implement named indexers
        /// for glyph metrics.
        /// </summary>
        private class GlyphIndexer : IDictionary<ushort, double>
        {
            internal GlyphIndexer(GlyphAccessor accessor, ushort numberOfGlyphs)
            {
                _accessor = accessor;
                _numberOfGlyphs = numberOfGlyphs;
            }

            #region IDictionary<ushort,double> Members

            public void Add(ushort key, double value)
            {
                throw new NotSupportedException();
            }

            public bool ContainsKey(ushort key)
            {
                return (key < _numberOfGlyphs);
            }

            public ICollection<ushort> Keys
            {
                get { return new SequentialUshortCollection(_numberOfGlyphs); }
            }

            public bool Remove(ushort key)
            {
                throw new NotSupportedException();
            }

            public bool TryGetValue(ushort key, out double value)

View on GitHub (pinned to 81131a70a4)