From 4bac7fd953fc7a38a5a4663d36d712939b7c4fa3 Mon Sep 17 00:00:00 2001 From: Benedikt Stebner Date: Tue, 1 Feb 2022 07:42:45 +0100 Subject: [PATCH] Fix HitTestTextRange bidi --- .../Media/TextFormatting/TextLayout.cs | 69 +++++++++++++------ 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs index 08821c3523..ea0ba4d0df 100644 --- a/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs +++ b/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs @@ -223,31 +223,47 @@ namespace Avalonia.Media.TextFormatting for (var index = 0; index < textLine.TextRuns.Count; index++) { var currentRun = (ShapedTextCharacters)textLine.TextRuns[index]; + ShapedTextCharacters? nextRun = null; if (index + 1 < textLine.TextRuns.Count) { - if (currentRun.ShapedBuffer.IsLeftToRight) - { - if (currentRun.Text.End < start) - { - startX += currentRun.Size.Width; + nextRun = (ShapedTextCharacters)textLine.TextRuns[index + 1]; + } - currentPosition = currentRun.Text.End; + if (nextRun != null) + { + if (nextRun.Text.Start < currentRun.Text.Start && start + length < currentRun.Text.End) + { + goto skip; + } - continue; - } + if (currentRun.Text.Start >= start + length) + { + goto skip; } - else + + if (currentRun.Text.Start > nextRun.Text.Start && currentRun.Text.Start < start) { - if (currentRun.Text.Start < start || currentRun.Text.End >= start + length) - { - startX += currentRun.Size.Width; + goto skip; + } - currentPosition = currentRun.Text.Start; + if (currentRun.Text.End < start) + { + goto skip; + } + + goto noop; + + skip: + { + startX += currentRun.Size.Width; - continue; - } + currentPosition = currentRun.Text.Start; } + + continue; + + noop:{ } } var endOffset = currentRun.GlyphRun.GetDistanceFromCharacterHit( @@ -270,10 +286,8 @@ namespace Avalonia.Media.TextFormatting currentPosition = characterHit.FirstCharacterIndex + characterHit.TrailingLength; - if(index + 1 < textLine.TextRuns.Count) + if(nextRun != null) { - var nextRun = (ShapedTextCharacters)textLine.TextRuns[index + 1]; - if (currentRun.ShapedBuffer.IsLeftToRight == nextRun.ShapedBuffer.IsLeftToRight) { endOffset = nextRun.GlyphRun.GetDistanceFromCharacterHit( @@ -296,7 +310,7 @@ namespace Avalonia.Media.TextFormatting } } - if (endX < startX) +u if (endX < startX) { (endX, startX) = (startX, endX); } @@ -307,11 +321,22 @@ namespace Avalonia.Media.TextFormatting if (currentRun.ShapedBuffer.IsLeftToRight) { - if (currentPosition >= start + length) + if (nextRun != null) { - break; + if (nextRun.Text.Start > currentRun.Text.Start) + { + break; + } + + currentPosition = nextRun.Text.End; + } + else + { + if (currentPosition >= start + length) + { + break; + } } - } else {