{"record":{"id":"5778cfd1f432a682","repo":"dotnet/wpf","slug":"sr-charactermetrics-negativehorizontaladvance","errorCode":null,"errorMessage":"SR.CharacterMetrics_NegativeHorizontalAdvance","messagePattern":"SR\\.CharacterMetrics_NegativeHorizontalAdvance","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/CharacterMetrics.cs","lineNumber":104,"sourceCode":"\n            set\n            {\n                double[] metrics = ParseMetrics(value);\n\n                // Validate all the values before we assign to any field.\n                CompositeFontParser.VerifyNonNegativeMultiplierOfEm(nameof(BlackBoxWidth), ref metrics[(int)FieldIndex.BlackBoxWidth]);\n                CompositeFontParser.VerifyNonNegativeMultiplierOfEm(nameof(BlackBoxHeight), ref metrics[(int)FieldIndex.BlackBoxHeight]);\n                CompositeFontParser.VerifyMultiplierOfEm(nameof(Baseline), ref metrics[(int)FieldIndex.Baseline]);\n                CompositeFontParser.VerifyMultiplierOfEm(nameof(LeftSideBearing), ref metrics[(int)FieldIndex.LeftSideBearing]);\n                CompositeFontParser.VerifyMultiplierOfEm(nameof(RightSideBearing), ref metrics[(int)FieldIndex.RightSideBearing]);\n                CompositeFontParser.VerifyMultiplierOfEm(nameof(TopSideBearing), ref metrics[(int)FieldIndex.TopSideBearing]);\n                CompositeFontParser.VerifyMultiplierOfEm(nameof(BottomSideBearing), ref metrics[(int)FieldIndex.BottomSideBearing]);\n\n                double horizontalAdvance = metrics[(int)FieldIndex.BlackBoxWidth]\n                    + metrics[(int)FieldIndex.LeftSideBearing]\n                    + metrics[(int)FieldIndex.RightSideBearing];\n                if (horizontalAdvance < 0)\n                    throw new ArgumentException(SR.CharacterMetrics_NegativeHorizontalAdvance);\n\n                double verticalAdvance = metrics[(int)FieldIndex.BlackBoxHeight]\n                    + metrics[(int)FieldIndex.TopSideBearing]\n                    + metrics[(int)FieldIndex.BottomSideBearing];\n                if (verticalAdvance < 0)\n                    throw new ArgumentException(SR.CharacterMetrics_NegativeVerticalAdvance);\n\n                // Set all the properties.\n                _blackBoxWidth = metrics[(int)FieldIndex.BlackBoxWidth];\n                _blackBoxHeight = metrics[(int)FieldIndex.BlackBoxHeight];\n                _baseline = metrics[(int)FieldIndex.Baseline];\n                _leftSideBearing = metrics[(int)FieldIndex.LeftSideBearing];\n                _rightSideBearing = metrics[(int)FieldIndex.RightSideBearing];\n                _topSideBearing = metrics[(int)FieldIndex.TopSideBearing];\n                _bottomSideBearing = metrics[(int)FieldIndex.BottomSideBearing];\n            }\n        }\n","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/CharacterMetrics.cs#L86-L122","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hand-edited or corrupted DeviceFont/CompositeFont .ini metric files; font vendor data with sign errors; parsing malformed embedded font metadata.","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."],"exampleFix":"// before\nvar m = new CharacterMetrics(\"0,-5,0,-10,10,0\"); // negative advance\n\n// after\nvar parts = Parse(str);\nif (parts.BlackBoxWidth + parts.LeftSideBearing + parts.RightSideBearing < 0)\n    parts.LeftSideBearing = 0;\nvar m = new CharacterMetrics(Format(parts));","handlingStrategy":"validation","validationCode":"static bool HasValidHorizontalAdvance(double blackBoxWidth, double left, double right)\n    => blackBoxWidth + left + right >= 0;","typeGuard":null,"tryCatchPattern":"try { var m = new CharacterMetrics(str); }\ncatch (ArgumentException ex) { Log(ex.Message); m = CharacterMetrics.Default; }","preventionTips":["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."],"tags":["wpf","typography","argument-exception","metrics"],"backgroundTag":"invalid-argument-value","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"}