{"record":{"id":"a1d91fe01c591ae2","repo":"dotnet/wpf","slug":"sr-collectionnumberofelementsmustbelessorequalto","errorCode":null,"errorMessage":"SR.CollectionNumberOfElementsMustBeLessOrEqualTo","messagePattern":"SR\\.CollectionNumberOfElementsMustBeLessOrEqualTo","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphTypeface.cs","lineNumber":231,"sourceCode":"        /// </summary>\n        /// <param name=\"glyphs\">Collection of glyph indices to be included into the subset.</param>\n        /// <returns>Binary image of font subset.</returns>\n        /// <remarks>\n        ///     Callers must have UnmanagedCode permission to call this API.\n        ///     Callers must have FileIOPermission or WebPermission to font location to call this API.\n        /// </remarks>\n        [CLSCompliant(false)]\n        public byte[] ComputeSubset(ICollection<ushort> glyphs)\n        {\n            CheckInitialized(); // This can only be called on fully initialized GlyphTypeface\n\n            ArgumentNullException.ThrowIfNull(glyphs);\n\n            if (glyphs.Count <= 0)\n                throw new ArgumentException(SR.CollectionNumberOfElementsMustBeGreaterThanZero, nameof(glyphs));\n\n            if (glyphs.Count > ushort.MaxValue)\n                throw new ArgumentException(SR.Format(SR.CollectionNumberOfElementsMustBeLessOrEqualTo, ushort.MaxValue), nameof(glyphs));\n\n            UnmanagedMemoryStream pinnedFontSource = FontSource.GetUnmanagedStream();\n\n            try\n            {\n                TrueTypeFontDriver trueTypeDriver = new TrueTypeFontDriver(pinnedFontSource, _originalUri);\n                trueTypeDriver.SetFace(FaceIndex);\n\n                return trueTypeDriver.ComputeFontSubset(glyphs);\n            }\n            catch (SEHException e)\n            {\n                throw Util.ConvertInPageException(FontSource, e);\n            }\n            finally\n            {\n                pinnedFontSource.Close();\n            }","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphTypeface.cs#L213-L249","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nglyphTypeface.ComputeSubset(outStream, allGlyphs);\n// after\nvar unique = allGlyphs.Distinct().Take(ushort.MaxValue).ToArray();\nglyphTypeface.ComputeSubset(outStream, unique);","handlingStrategy":"validation","validationCode":"var uniqueGlyphs = glyphs.Distinct().Take(ushort.MaxValue).ToArray();\nif (uniqueGlyphs.Length < glyphs.Count)\n    log.Warn($\"Glyph set reduced from {glyphs.Count} to {uniqueGlyphs.Length}\");\n\nglyphTypeface.ComputeSubset(outStream, uniqueGlyphs);","typeGuard":null,"tryCatchPattern":"try { glyphTypeface.ComputeSubset(outStream, glyphs); }\ncatch (ArgumentException ex) when (ex.ParamName == \"glyphs\")\n{\n    log.Warn(\"Subset skipped: glyph count exceeds 65535; falling back to full font\", ex);\n    CopyFullFont(outStream);\n}","preventionTips":["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"],"tags":["wpf","fonts","argument-exception","collection-size","font-subsetting"],"backgroundTag":"value-out-of-range","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}