dotnet/wpf · error · ArgumentException
SR.CollectionNumberOfElementsMustBeLessOrEqualTo
Error message
SR.CollectionNumberOfElementsMustBeLessOrEqualTo
What it means
GlyphTypeface.ComputeSubset throws ArgumentException with SR.CollectionNumberOfElementsMustBeLessOrEqualTo when the glyphs collection has more than ushort.MaxValue (65535) elements. Glyph indices in TrueType fonts are 16-bit, so the subset request cannot exceed 65535 entries; larger requests are rejected before any font parsing occurs.
Solutions
- Deduplicate the glyph index collection (Distinct()) before calling ComputeSubset
- Cap the collection at 65535 entries; if more glyphs are genuinely needed, skip subsetting and embed the full font
- Build the glyph set from distinct characters via CharacterToGlyphMap instead of per-occurrence mapping
Example fix
// before glyphTypeface.ComputeSubset(outStream, allGlyphs); // after var unique = allGlyphs.Distinct().Take(ushort.MaxValue).ToArray(); glyphTypeface.ComputeSubset(outStream, unique);
Defensive patterns
Strategy: validation
Validate before calling
var uniqueGlyphs = glyphs.Distinct().Take(ushort.MaxValue).ToArray();
if (uniqueGlyphs.Length < glyphs.Count)
log.Warn($"Glyph set reduced from {glyphs.Count} to {uniqueGlyphs.Length}");
glyphTypeface.ComputeSubset(outStream, uniqueGlyphs); Try / catch
try { glyphTypeface.ComputeSubset(outStream, glyphs); }
catch (ArgumentException ex) when (ex.ParamName == "glyphs")
{
log.Warn("Subset skipped: glyph count exceeds 65535; falling back to full font", ex);
CopyFullFont(outStream);
} Prevention
- Always deduplicate glyph indices before subsetting
- Map distinct characters (a HashSet<char>) to glyphs, not each text occurrence
- For very large glyph sets, embed the full font instead of subsetting
When it happens
Trigger: Calling ComputeSubset with ICollection<ushort>.Count > 65535 — e.g. passing every glyph index in a range without deduplication, or appending indices for each character occurrence instead of each unique glyph.
Common situations: Subsetting a large CJK font by iterating all characters in a document and adding a glyph per character occurrence rather than per distinct glyph; a font with the full 65536 glyph space enumerated wholesale.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- SR.CollectionNumberOfElementsMustBeGreaterThanZero
- SR.Collection_BadRank
- ArgumentOutOfRangeException (timeout was Duration.Automatic)
- Collection_BadRank
- Collection_CopyTo_ArrayCannotBeMultidimensional
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/a1d91fe01c591ae2.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphTypeface.cs:231
/// </summary>
/// <param name="glyphs">Collection of glyph indices to be included into the subset.</param>
/// <returns>Binary image of font subset.</returns>
/// <remarks>
/// Callers must have UnmanagedCode permission to call this API.
/// Callers must have FileIOPermission or WebPermission to font location to call this API.
/// </remarks>
[CLSCompliant(false)]
public byte[] ComputeSubset(ICollection<ushort> glyphs)
{
CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
ArgumentNullException.ThrowIfNull(glyphs);
if (glyphs.Count <= 0)
throw new ArgumentException(SR.CollectionNumberOfElementsMustBeGreaterThanZero, nameof(glyphs));
if (glyphs.Count > ushort.MaxValue)
throw new ArgumentException(SR.Format(SR.CollectionNumberOfElementsMustBeLessOrEqualTo, ushort.MaxValue), nameof(glyphs));
UnmanagedMemoryStream pinnedFontSource = FontSource.GetUnmanagedStream();
try
{
TrueTypeFontDriver trueTypeDriver = new TrueTypeFontDriver(pinnedFontSource, _originalUri);
trueTypeDriver.SetFace(FaceIndex);
return trueTypeDriver.ComputeFontSubset(glyphs);
}
catch (SEHException e)
{
throw Util.ConvertInPageException(FontSource, e);
}
finally
{
pinnedFontSource.Close();
}View on GitHub (pinned to 81131a70a4)