dotnet/wpf · error · ArgumentException

SR.GlyphsUnicodeStringIsTooShort

Error message

SR.GlyphsUnicodeStringIsTooShort

What it means

Thrown by Glyphs.SetClusterMapEntry, the guarded writer for the clusterMap array built during Glyphs parsing. If the caller tries to write a cluster-map entry at an index at or beyond the array length, the UnicodeString is shorter than the glyph/cluster data implies. It is a validation guard meaning the Characters/UnicodeString supplied does not cover all parsed glyph indices.

Solutions

  1. Extend Glyphs.UnicodeString so it has at least as many characters as the cluster map requires.
  2. Reduce the number of glyph indices/clusters in GlyphIndices to match the UnicodeString length.
  3. Compute/check that parsedCharacterCount stays < UnicodeString.Length before writing cluster-map entries.

Example fix

// before
glyphs.UnicodeString = "AB";      // 2 chars
glyphs.GlyphIndices = ";(1:1);(2:1);(3:1)"; // needs >= 4 chars
// after
glyphs.UnicodeString = "ABCD";
glyphs.GlyphIndices = ";(1:1);(2:1);(3:1)";
Defensive patterns

Strategy: validation

Validate before calling

int impliedChars = CountClusterCharacters(glyphIndices); // sum characterClusterSize over cluster tokens
if (glyphs.UnicodeString == null || glyphs.UnicodeString.Length < impliedChars)
    throw new InvalidOperationException("UnicodeString shorter than glyph cluster data");

Type guard

static bool UnicodeCoversClusters(string unicode, string indices) => unicode != null && unicode.Length >= indices.Split(';').Length;

Try / catch

try { ApplyGlyphs(glyphs, indices, unicode); }
catch (ArgumentException ex) { RegenerateIndicesFromUnicode(glyphs); }
// recovery: rebuild GlyphIndices from the UnicodeString so lengths always agree

Prevention

When it happens

Trigger: Calling ParseGlyphsProperty (via Glyphs.GlyphIndices/UnicodeString assignment) where the number of characters implied by glyph clusters exceeds Glyphs.UnicodeString.Length — i.e. more cluster-map entries than characters.

Common situations: GlyphIndices and UnicodeString edited out of sync in XAML; adding a glyph cluster without adding corresponding characters to UnicodeString.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/1eaa0f52eef3c14b. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/Glyphs.cs:466

            return advance * EmMultiplier;
        }

        private ushort GetGlyphFromCharacter(GlyphTypeface glyphTypeface, char character)
        {
            ushort glyphIndex;
            // TryGetValue will return zero glyph index for missing code points,
            // which is the right thing to display per http://www.microsoft.com/typography/otspec/cmap.htm
            glyphTypeface.CharacterToGlyphMap.TryGetValue(character, out glyphIndex);
            return glyphIndex;
        }

        /// <summary>
        /// Performs validation against cluster map size and throws a well defined exception.
        /// </summary>
        private static void SetClusterMapEntry(ushort[] clusterMap, int index, ushort value)
        {
            if (index < 0 || index >= clusterMap.Length)
                throw new ArgumentException(SR.GlyphsUnicodeStringIsTooShort);
            clusterMap[index] = value;
        }

        private class ParsedGlyphData
        {
            public ushort   glyphIndex;
            public double   advanceWidth;
            public double   offsetX;
            public double   offsetY;
        };

        // -----------------------------------------------------------------------------
        // Parses a semicolon-delimited list of glyph specifiers, each of which consists
        // of up to 4 comma-delimited values:
        //   - glyph index (ushort)
        //   - glyph advance (double)
        //   - glyph offset X (double)
        //   - glyph offset Y (double)

View on GitHub (pinned to 81131a70a4)