1
0
Эх сурвалжийг харах

fix: Selecting multiple lines in RTL textbox (#19093)

* Reverse text runs for RTL flow direction

* Optimize text run traversal.

* Remove unused LINQ directive from TextLineImpl.cs

* Add RTL newline handling test in TextLineTests

* Add RTL newline handling tests for text formatting.
Ahmed Elsayed 3 сар өмнө
parent
commit
dc19c39df5

+ 4 - 2
src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs

@@ -1415,10 +1415,12 @@ namespace Avalonia.Media.TextFormatting
             }
 
             var width = widthIncludingWhitespace;
+            var isRtl = _paragraphProperties.FlowDirection == FlowDirection.RightToLeft;
 
-            for (var i = _textRuns.Length - 1; i >= 0; i--)
+            for (int i = 0; i < _textRuns.Length; i++)
             {
-                var currentRun = _textRuns[i];
+                var index = isRtl ? i : _textRuns.Length - 1 - i;
+                var currentRun = _textRuns[index];
 
                 if (currentRun is ShapedTextRun shapedText)
                 {

+ 51 - 0
tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs

@@ -1163,6 +1163,57 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
             }
         }
 
+
+        [Fact]
+        public void Should_Handle_NewLine_In_RTL_Text()
+        {
+            using (Start())
+            {
+                var typeface = Typeface.Default;
+
+                var defaultProperties = new GenericTextRunProperties(typeface);
+
+                var textSource = new SingleBufferTextSource("test\r\n", defaultProperties);
+
+                var formatter = new TextFormatterImpl();
+
+                var textLine =
+                    formatter.FormatLine(textSource, 0, double.PositiveInfinity,
+                        new GenericTextParagraphProperties(FlowDirection.RightToLeft, TextAlignment.Right,
+                        true, true, defaultProperties, TextWrapping.Wrap, 0, 0, 0));
+
+                Assert.NotNull(textLine);
+
+                Assert.NotEqual(textLine.NewLineLength, 0);
+
+            }
+        }
+
+        [Theory]
+        [InlineData("hello\r\nworld")]
+        [InlineData("مرحباً\r\nبالعالم")]
+        [InlineData("hello مرحباً\r\nworld بالعالم")]
+        [InlineData("مرحباً hello\r\nبالعالم nworld")]
+        public void Should_Set_NewLineLength_For_CRLF_In_RTL_Text(string text)
+        {
+            using (Start())
+            {
+                var typeface = Typeface.Default;
+                var defaultProperties = new GenericTextRunProperties(typeface);
+                var textSource = new SingleBufferTextSource(text, defaultProperties);
+
+                var formatter = new TextFormatterImpl();
+
+                var textLine =
+      formatter.FormatLine(textSource, 0, double.PositiveInfinity,
+          new GenericTextParagraphProperties(FlowDirection.RightToLeft, TextAlignment.Right,
+          true, true, defaultProperties, TextWrapping.Wrap, 0, 0, 0));
+
+                Assert.NotNull(textLine);
+                Assert.NotEqual(0, textLine.NewLineLength);
+            }
+        }
+
         private class TextHidden : TextRun
         {
             public TextHidden(int length)