diff --git a/src/Avalonia.Visuals/Media/GlyphRun.cs b/src/Avalonia.Visuals/Media/GlyphRun.cs
index a5e70ae2b1..43151deece 100644
--- a/src/Avalonia.Visuals/Media/GlyphRun.cs
+++ b/src/Avalonia.Visuals/Media/GlyphRun.cs
@@ -193,16 +193,15 @@ namespace Avalonia.Media
{
var distance = 0.0;
- var end = _glyphClusters.AsSpan().BinarySearch((ushort)characterHit.FirstCharacterIndex);
+ var end = characterHit.FirstCharacterIndex + characterHit.TrailingLength;
- if (end < 0)
+ for (var i = 0; i < _glyphClusters.Length; i++)
{
- return 0;
- }
+ if (_glyphClusters[i] >= end)
+ {
+ break;
+ }
- // If TrailingLength > 0 we have to use the next cluster while TrailingLength != 0
- for (var i = 0; i < end + characterHit.TrailingLength; i++)
- {
if (GlyphAdvances.IsEmpty)
{
var glyph = GlyphIndices[i];
@@ -279,7 +278,6 @@ namespace Avalonia.Media
public CharacterHit GetNextCaretCharacterHit(CharacterHit characterHit)
{
-
if (characterHit.TrailingLength == 0)
{
return FindNearestCharacterHit(characterHit.FirstCharacterIndex, out _);
@@ -412,7 +410,7 @@ namespace Avalonia.Media
{
if (_glyphRunImpl != null)
{
- throw new InvalidOperationException("GlyphRun can't be changed after is has been initialized.'");
+ throw new InvalidOperationException("GlyphRun can't be changed after it has been initialized.'");
}
field = value;
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/GlyphRunNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/GlyphRunNode.cs
index b862dc218f..b3c4fdbac0 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/GlyphRunNode.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/GlyphRunNode.cs
@@ -10,7 +10,7 @@ using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph
{
///
- /// A node in the scene graph which represents a text draw.
+ /// A node in the scene graph which represents a glyph run draw.
///
internal class GlyphRunNode : BrushDrawOperation
{
@@ -48,7 +48,7 @@ namespace Avalonia.Rendering.SceneGraph
public IBrush Foreground { get; }
///
- /// Gets the text to draw.
+ /// Gets the glyph run to draw.
///
public GlyphRun GlyphRun { get; }
@@ -72,7 +72,7 @@ namespace Avalonia.Rendering.SceneGraph
///
/// The transform of the other draw operation.
/// The foreground of the other draw operation.
- /// The text of the other draw operation.
+ /// The glyph run of the other draw operation.
/// True if the draw operations are the same, otherwise false.
///
/// The properties of the other draw operation are passed in as arguments to prevent
diff --git a/tests/Avalonia.Visuals.UnitTests/Media/GlyphRunTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/GlyphRunTests.cs
index c0820f2046..f5e4cdc099 100644
--- a/tests/Avalonia.Visuals.UnitTests/Media/GlyphRunTests.cs
+++ b/tests/Avalonia.Visuals.UnitTests/Media/GlyphRunTests.cs
@@ -13,12 +13,30 @@ namespace Avalonia.Visuals.UnitTests.Media
.Bind().ToSingleton();
}
+ [InlineData(new double[] { 10, 10, 10 }, new ushort[] { 0, 0, 0 }, 0, 0, 0)]
+ [InlineData(new double[] { 10, 10, 10 }, new ushort[] { 0, 0, 0 }, 0, 3, 30)]
+ [InlineData(new double[] { 10, 10, 10 }, new ushort[] { 0, 1, 2 }, 1, 0, 10)]
+ [InlineData(new double[] { 10, 10, 10 }, new ushort[] { 0, 1, 2 }, 2, 0, 20)]
+ [InlineData(new double[] { 10, 10, 10 }, new ushort[] { 0, 1, 2 }, 2, 1, 30)]
+ [Theory]
+ public void Should_Get_Distance_From_CharacterHit(double[] advances, ushort[] clusters, int start, int trailingLength, double expectedDistance)
+ {
+ using (var glyphRun = CreateGlyphRun(advances, clusters))
+ {
+ var characterHit = new CharacterHit(start, trailingLength);
+
+ var distance = glyphRun.GetDistanceFromCharacterHit(characterHit);
+
+ Assert.Equal(expectedDistance, distance);
+ }
+ }
+
[InlineData(new double[] { 10, 10, 10 }, new ushort[] { 0, 0, 0 }, 25.0, 0, 3, true)]
[InlineData(new double[] { 10, 10, 10 }, new ushort[] { 0, 1, 2 }, 20.0, 2, 0, true)]
[InlineData(new double[] { 10, 10, 10 }, new ushort[] { 0, 1, 2 }, 26.0, 2, 1, true)]
[InlineData(new double[] { 10, 10, 10 }, new ushort[] { 0, 1, 2 }, 35.0, 2, 1, false)]
[Theory]
- public void Should_Get_TextBounds_FromDistance(double[] advances, ushort[] clusters, double distance, int start,
+ public void Should_Get_CharacterHit_FromDistance(double[] advances, ushort[] clusters, double distance, int start,
int trailingLengthExpected, bool isInsideExpected)
{
using (var glyphRun = CreateGlyphRun(advances, clusters))