dotnet/wpf · error · ArgumentException
SR.CharacterMetrics_NegativeHorizontalAdvance
Error message
SR.CharacterMetrics_NegativeHorizontalAdvance
What it means
The CharacterMetrics(string) constructor parses a composite-font metrics string and computes horizontalAdvance = BlackBoxWidth + LeftSideBearing + RightSideBearing. A negative total is geometrically meaningless, so the constructor throws ArgumentException with SR.CharacterMetrics_NegativeHorizontalAdvance.
Solutions
- Correct the metrics string so BlackBoxWidth + LeftSideBearing + RightSideBearing >= 0.
- Clamp side bearings in the source data before constructing CharacterMetrics.
- Validate the composite font section with CompositeFontParser before use.
Example fix
// before
var m = new CharacterMetrics("0,-5,0,-10,10,0"); // negative advance
// after
var parts = Parse(str);
if (parts.BlackBoxWidth + parts.LeftSideBearing + parts.RightSideBearing < 0)
parts.LeftSideBearing = 0;
var m = new CharacterMetrics(Format(parts)); Defensive patterns
Strategy: validation
Validate before calling
static bool HasValidHorizontalAdvance(double blackBoxWidth, double left, double right)
=> blackBoxWidth + left + right >= 0; Try / catch
try { var m = new CharacterMetrics(str); }
catch (ArgumentException ex) { Log(ex.Message); m = CharacterMetrics.Default; } Prevention
- Validate BlackBoxWidth + LeftSideBearing + RightSideBearing >= 0 before constructing.
- Sanitize font metric files at import time; reject or clamp negative totals.
- Keep composite-font metrics machine-generated, not hand-edited.
When it happens
Trigger: Constructing CharacterMetrics from a metrics string whose BlackBoxWidth plus side bearings sums to a negative number, e.g. a huge negative left/right side bearing exceeding the black-box width.
Common situations: Hand-edited or corrupted DeviceFont/CompositeFont .ini metric files; font vendor data with sign errors; parsing malformed embedded font metadata.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.CharacterMetrics_NegativeVerticalAdvance
- ArgumentOutOfRangeException (timeout was Duration.Automatic)
- Collection_BadRank
- Collection_CopyTo_ArrayCannotBeMultidimensional
- Collection_CopyTo_ArrayCannotBeMultidimensional
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/5778cfd1f432a682.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/CharacterMetrics.cs:104
set
{
double[] metrics = ParseMetrics(value);
// Validate all the values before we assign to any field.
CompositeFontParser.VerifyNonNegativeMultiplierOfEm(nameof(BlackBoxWidth), ref metrics[(int)FieldIndex.BlackBoxWidth]);
CompositeFontParser.VerifyNonNegativeMultiplierOfEm(nameof(BlackBoxHeight), ref metrics[(int)FieldIndex.BlackBoxHeight]);
CompositeFontParser.VerifyMultiplierOfEm(nameof(Baseline), ref metrics[(int)FieldIndex.Baseline]);
CompositeFontParser.VerifyMultiplierOfEm(nameof(LeftSideBearing), ref metrics[(int)FieldIndex.LeftSideBearing]);
CompositeFontParser.VerifyMultiplierOfEm(nameof(RightSideBearing), ref metrics[(int)FieldIndex.RightSideBearing]);
CompositeFontParser.VerifyMultiplierOfEm(nameof(TopSideBearing), ref metrics[(int)FieldIndex.TopSideBearing]);
CompositeFontParser.VerifyMultiplierOfEm(nameof(BottomSideBearing), ref metrics[(int)FieldIndex.BottomSideBearing]);
double horizontalAdvance = metrics[(int)FieldIndex.BlackBoxWidth]
+ metrics[(int)FieldIndex.LeftSideBearing]
+ metrics[(int)FieldIndex.RightSideBearing];
if (horizontalAdvance < 0)
throw new ArgumentException(SR.CharacterMetrics_NegativeHorizontalAdvance);
double verticalAdvance = metrics[(int)FieldIndex.BlackBoxHeight]
+ metrics[(int)FieldIndex.TopSideBearing]
+ metrics[(int)FieldIndex.BottomSideBearing];
if (verticalAdvance < 0)
throw new ArgumentException(SR.CharacterMetrics_NegativeVerticalAdvance);
// Set all the properties.
_blackBoxWidth = metrics[(int)FieldIndex.BlackBoxWidth];
_blackBoxHeight = metrics[(int)FieldIndex.BlackBoxHeight];
_baseline = metrics[(int)FieldIndex.Baseline];
_leftSideBearing = metrics[(int)FieldIndex.LeftSideBearing];
_rightSideBearing = metrics[(int)FieldIndex.RightSideBearing];
_topSideBearing = metrics[(int)FieldIndex.TopSideBearing];
_bottomSideBearing = metrics[(int)FieldIndex.BottomSideBearing];
}
}
View on GitHub (pinned to 81131a70a4)