Browse Source

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.
pull/19230/head
Ahmed Elsayed 7 months ago
committed by GitHub
parent
commit
dc19c39df5
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 6
      src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
  2. 51
      tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs

6
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
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)

Loading…
Cancel
Save