From bfdd3fa325880fa88bce9047b817ab2eb2435e60 Mon Sep 17 00:00:00 2001 From: Benedikt Stebner Date: Thu, 1 Jun 2023 07:13:36 +0200 Subject: [PATCH] Prevent infinite loop --- samples/Sandbox/MainWindow.axaml | 1 + .../Media/TextFormatting/TextLineImpl.cs | 22 +++++++++------ .../Media/TextFormatting/TextLineTests.cs | 28 ++++++++++++++++++- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/samples/Sandbox/MainWindow.axaml b/samples/Sandbox/MainWindow.axaml index 6929f192c7..f0f099b95b 100644 --- a/samples/Sandbox/MainWindow.axaml +++ b/samples/Sandbox/MainWindow.axaml @@ -1,4 +1,5 @@ + diff --git a/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs b/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs index c2ec78e187..0b1bd2e189 100644 --- a/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs +++ b/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs @@ -371,14 +371,16 @@ namespace Avalonia.Media.TextFormatting IndexedTextRun currentIndexedRun = _indexedTextRuns[i]; - while(currentIndexedRun.TextSourceCharacterIndex != currentPosition) + while (currentIndexedRun.TextSourceCharacterIndex != currentPosition) { - if(i + 1 < _indexedTextRuns.Count) + if (i + 1 == _indexedTextRuns.Count) { - i++; - - currentIndexedRun = _indexedTextRuns[i]; + break; } + + i++; + + currentIndexedRun = _indexedTextRuns[i]; } return currentIndexedRun; @@ -604,12 +606,14 @@ namespace Avalonia.Media.TextFormatting while (currentIndexedRun.TextSourceCharacterIndex != currentPosition) { - if (i + 1 < _indexedTextRuns.Count) + if (i + 1 == _indexedTextRuns.Count) { - i++; - - currentIndexedRun = _indexedTextRuns[i]; + break; } + + i++; + + currentIndexedRun = _indexedTextRuns[i]; } return currentIndexedRun; diff --git a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs index 1d07e780e6..6373fb4e91 100644 --- a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs +++ b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs @@ -9,6 +9,7 @@ using Avalonia.Media.TextFormatting; using Avalonia.UnitTests; using Avalonia.Utilities; using Xunit; +using static System.Net.Mime.MediaTypeNames; namespace Avalonia.Skia.UnitTests.Media.TextFormatting { @@ -1072,7 +1073,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting } [Fact] - public void Should_GetTextBounds_BiDi() + public void Should_GetTextBounds_Bidi() { var text = "אבגדה 12345 ABCDEF אבגדה"; @@ -1120,6 +1121,31 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting } } + [Fact] + public void Should_GetTextBounds_Bidi_2() + { + var text = "אבג ABC אבג 123"; + + 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 bounds = textLine.GetTextBounds(0, text.Length); + + Assert.Equal(5, bounds.Count); + + Assert.Equal(textLine.WidthIncludingTrailingWhitespace, bounds.Last().Rectangle.Right); + } + } + private class FixedRunsTextSource : ITextSource { private readonly IReadOnlyList _textRuns;