Browse Source

Merge pull request #4524 from Gillibald/fixes/TextLineCharacterHit

Fix TextLine GetPrevious/NextCharacterHit
pull/4532/head
danwalmsley 6 years ago
committed by GitHub
parent
commit
57dcf30afb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs
  2. 60
      tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs

16
src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs

@ -181,6 +181,17 @@ namespace Avalonia.Media.TextFormatting
return nextCharacterHit;
}
if (characterHit.FirstCharacterIndex + characterHit.TrailingLength <= TextRange.Start + TextRange.Length)
{
return characterHit; // Can't move, we're after the last character
}
var runIndex = GetRunIndexAtCodepointIndex(TextRange.End);
var textRun = _textRuns[runIndex];
characterHit = textRun.GlyphRun.GetNextCaretCharacterHit(characterHit);
return characterHit; // Can't move, we're after the last character
}
@ -192,6 +203,11 @@ namespace Avalonia.Media.TextFormatting
return previousCharacterHit;
}
if (characterHit.FirstCharacterIndex < TextRange.Start)
{
characterHit = new CharacterHit(TextRange.Start);
}
return characterHit; // Can't move, we're before the first character
}

60
tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Media;
using Avalonia.Media.TextFormatting;
@ -10,6 +9,65 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
{
public class TextLineTests
{
private static readonly string s_multiLineText = "012345678\r\r0123456789";
[Fact]
public void Should_Get_First_CharacterHit()
{
using (Start())
{
var defaultProperties = new GenericTextRunProperties(Typeface.Default);
var textSource = new SingleBufferTextSource(s_multiLineText, defaultProperties);
var formatter = new TextFormatterImpl();
var currentIndex = 0;
while (currentIndex < s_multiLineText.Length)
{
var textLine =
formatter.FormatLine(textSource, currentIndex, double.PositiveInfinity,
new GenericTextParagraphProperties(defaultProperties));
var firstCharacterHit = textLine.GetPreviousCaretCharacterHit(new CharacterHit(int.MinValue));
Assert.Equal(textLine.TextRange.Start, firstCharacterHit.FirstCharacterIndex);
currentIndex += textLine.TextRange.Length;
}
}
}
[Fact]
public void Should_Get_Last_CharacterHit()
{
using (Start())
{
var defaultProperties = new GenericTextRunProperties(Typeface.Default);
var textSource = new SingleBufferTextSource(s_multiLineText, defaultProperties);
var formatter = new TextFormatterImpl();
var currentIndex = 0;
while (currentIndex < s_multiLineText.Length)
{
var textLine =
formatter.FormatLine(textSource, currentIndex, double.PositiveInfinity,
new GenericTextParagraphProperties(defaultProperties));
var lastCharacterHit = textLine.GetNextCaretCharacterHit(new CharacterHit(int.MaxValue));
Assert.Equal(textLine.TextRange.Start + textLine.TextRange.Length,
lastCharacterHit.FirstCharacterIndex + lastCharacterHit.TrailingLength);
currentIndex += textLine.TextRange.Length;
}
}
}
[InlineData("𐐷𐐷𐐷𐐷𐐷")]
[InlineData("𐐷1234")]
[Theory]

Loading…
Cancel
Save