dotnet/wpf · error · ArgumentException
SR.CharacterMetrics_NegativeVerticalAdvance
Error message
SR.CharacterMetrics_NegativeVerticalAdvance
What it means
CharacterMetrics' constructor also computes verticalAdvance = BlackBoxHeight + TopSideBearing + BottomSideBearing and throws ArgumentException (SR.CharacterMetrics_NegativeVerticalAdvance) when that sum is negative, since a glyph's vertical advance cannot be negative in this model.
Solutions
- Fix the metrics string so BlackBoxHeight + TopSideBearing + BottomSideBearing >= 0.
- Sanitize/clamp negative vertical bearings in the data source.
- Regenerate metrics from the actual font rather than editing them manually.
Example fix
// before
var m = new CharacterMetrics("0,0,0,10,-10,0"); // negative vertical advance
// after
var m = new CharacterMetrics("0,0,0,10,0,0"); Defensive patterns
Strategy: validation
Validate before calling
static bool HasValidVerticalAdvance(double blackBoxHeight, double top, double bottom)
=> blackBoxHeight + top + bottom >= 0; Try / catch
try { var m = new CharacterMetrics(str); }
catch (ArgumentException ex) { Log(ex.Message); m = CharacterMetrics.Default; } Prevention
- Check BlackBoxHeight + TopSideBearing + BottomSideBearing >= 0 before construction.
- Clamp negative vertical bearings in the metrics source.
- Regenerate metrics from font files instead of manual edits.
When it happens
Trigger: Constructing CharacterMetrics from a string where BlackBoxHeight plus top/bottom side bearings totals below zero.
Common situations: Corrupt or hand-edited composite font metric sections; automated metric extraction writing negative heights; copy/paste sign errors in font metadata files.
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_NegativeHorizontalAdvance
- 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/e0383f245cccfcba.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/CharacterMetrics.cs:110
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];
}
}
private static void AppendField(double value, FieldIndex fieldIndex, ref int lastIndex, StringBuilder s)
{
if (value != 0)
{
s.Append(',', (int)fieldIndex - lastIndex);
lastIndex = (int)fieldIndex;View on GitHub (pinned to 81131a70a4)