diff --git a/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs b/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs index c1dc7274a4..09042b9d60 100644 --- a/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs +++ b/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs @@ -1328,7 +1328,9 @@ namespace Avalonia.Media.TextFormatting } var start = GetParagraphOffsetX(width, widthIncludingWhitespace); - var overhangLeading = Math.Max(0, bounds.Left - start); + //The width of overhanging pixels at the origin + var overhangLeading = Math.Max(0, start - bounds.Left); + //The width of overhanging pixels at the end var overhangTrailing = Math.Max(0, bounds.Width - widthIncludingWhitespace); var hasOverflowed = width > _paragraphWidth; diff --git a/tests/Avalonia.Skia.UnitTests/Media/GlyphRunTests.cs b/tests/Avalonia.Skia.UnitTests/Media/GlyphRunTests.cs index 4eddfd44f6..b807e1389b 100644 --- a/tests/Avalonia.Skia.UnitTests/Media/GlyphRunTests.cs +++ b/tests/Avalonia.Skia.UnitTests/Media/GlyphRunTests.cs @@ -175,6 +175,22 @@ namespace Avalonia.Skia.UnitTests.Media } } + [Fact] + public void GlyphRun_With_Leading_Space_Has_Correct_InkBounds() + { + using (Start()) + { + var typeface = new Typeface("resm:Avalonia.Skia.UnitTests.Assets?assembly=Avalonia.Skia.UnitTests#Inter"); + var options = new TextShaperOptions(typeface.GlyphTypeface, 14); + var shapedBuffer = TextShaper.Current.ShapeText(" I", options); + + var glyphRun1 = CreateGlyphRun(shapedBuffer); + var bounds = glyphRun1.InkBounds; + + Assert.True(bounds.Left > 0); + } + } + private static List BuildRects(GlyphRun glyphRun) { var height = glyphRun.Bounds.Height; diff --git a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs index 21e283e949..7a5a1ca0c8 100644 --- a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs +++ b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs @@ -1259,6 +1259,29 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting } } + + + [Fact] + public void Should_GetPreviousCharacterHit_Non_Trailing() + { + var text = "123.45.67.•"; + + using (Start()) + { + var defaultProperties = new GenericTextRunProperties(Typeface.Default); + var textSource = new SingleBufferTextSource(text, defaultProperties, true); + + var formatter = new TextFormatterImpl(); + + var textLine = + formatter.FormatLine(textSource, 0, double.PositiveInfinity, + new GenericTextParagraphProperties(FlowDirection.LeftToRight, TextAlignment.Left, + true, true, defaultProperties, TextWrapping.NoWrap, 0, 0, 0)); + + var characterHit = textLine.GetPreviousCaretCharacterHit(new CharacterHit(10, 1)); + } + } + private class FixedRunsTextSource : ITextSource { private readonly IReadOnlyList _textRuns; diff --git a/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png b/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png index c8320cdb97..30e2ca8662 100644 Binary files a/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png and b/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png differ