dotnet/wpf · error · ArgumentException

PropertyOfClassCannotBeGreaterThan (FontRenderingEmSize…

Error message

PropertyOfClassCannotBeGreaterThan (FontRenderingEmSize, TextRunProperties, realMaxFontRenderingEmSize)

What it means

FetchTextRun caps FontRenderingEmSize at Constants.RealInfiniteWidth / Constants.GreatestMutiplierOfEm to keep layout arithmetic safe. It throws ArgumentException(SR.PropertyOfClassCannotBeGreaterThan with FontRenderingEmSize, TextRunProperties, max) when the em size exceeds that maximum.

Solutions

  1. Clamp FontRenderingEmSize to Constants.RealInfiniteWidth / Constants.GreatestMutiplierOfEm before creating the run
  2. Sanitize scale factors so em size stays within the allowed maximum
  3. Validate in your TextRunProperties setter to reject oversized em sizes early

Example fix

// before
props.FontRenderingEmSize = scale * 1000000; // may exceed max
// after
var max = Constants.RealInfiniteWidth / Constants.GreatestMutiplierOfEm;
props.FontRenderingEmSize = Math.Min(scale * baseSize, max);
Defensive patterns

Strategy: validation

Validate before calling

var max = Constants.RealInfiniteWidth / Constants.GreatestMutiplierOfEm;
if (run.Properties.FontRenderingEmSize > max) run.Properties.FontRenderingEmSize = max;

Type guard

bool EmSizeWithinMax(TextRunProperties p) => p.FontRenderingEmSize <= Constants.RealInfiniteWidth / Constants.GreatestMutiplierOfEm;

Try / catch

try { formatter.FormatLine(...); } catch (ArgumentException) { /* clamp em size and retry */ }

Prevention

When it happens

Trigger: TextRun.Properties.FontRenderingEmSize larger than the maximum allowed (RealInfiniteWidth divided by GreatestMutiplierOfEm), returned by a TextSource during formatting.

Common situations: Enormous scale/zoom factors applied to text; unbounded data-driven font sizes; missing clamping after transformation math.

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


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/TextRunCacheImp.cs:123

                ArgumentOutOfRangeException.ThrowIfNegativeOrZero(textRun.Length, "textRun.Length");

                Plsrun plsrun = TextRunInfo.GetRunType(textRun);

                if (plsrun == Plsrun.Text || plsrun == Plsrun.InlineObject)
                {
                    TextRunProperties properties = textRun.Properties;

                    if (properties == null)
                        throw new ArgumentException(SR.TextRunPropertiesCannotBeNull);

                    if (properties.FontRenderingEmSize <= 0)
                        throw new ArgumentException(SR.Format(SR.PropertyOfClassMustBeGreaterThanZero, "FontRenderingEmSize", "TextRunProperties"));

                    double realMaxFontRenderingEmSize = Constants.RealInfiniteWidth / Constants.GreatestMutiplierOfEm;

                    if (properties.FontRenderingEmSize > realMaxFontRenderingEmSize)
                        throw new ArgumentException(SR.Format(SR.PropertyOfClassCannotBeGreaterThan, "FontRenderingEmSize", "TextRunProperties", realMaxFontRenderingEmSize));

                    CultureInfo culture = CultureMapper.GetSpecificCulture(properties.CultureInfo);

                    if (culture == null)
                        throw new ArgumentException(SR.Format(SR.PropertyOfClassCannotBeNull, "CultureInfo", "TextRunProperties"));

                    if (properties.Typeface == null)
                        throw new ArgumentException(SR.Format(SR.PropertyOfClassCannotBeNull, "Typeface", "TextRunProperties"));
                }


                //
                // TextRun is specifial to SpanVector because TextRun also encodes position which needs to be 
                // consistent with the positions encoded by SpanVector. In run cache, the begining of a span 
                // should always correspond to the begining of a cached text run. If the end of the currently fetched 
                // run overlaps with the begining of an already cached run, the begining of the cached run needs to be 
                // adjusted as well as its span. Because we can't gurantee the correctness of the overlapped range 
                // so we'll simply remove the overlapped runs here.

View on GitHub (pinned to 81131a70a4)