Browse Source

Merge branch 'master' into 9612-duplicate-setters

pull/10113/head
Dan Walmsley 3 years ago
committed by GitHub
parent
commit
354d1d8a18
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 75
      src/Avalonia.Base/Media/TextFormatting/TextFormatterImpl.cs
  2. 14
      src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
  3. 8
      tests/Avalonia.Skia.UnitTests/Media/TextFormatting/SingleBufferTextSource.cs
  4. 11
      tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs

75
src/Avalonia.Base/Media/TextFormatting/TextFormatterImpl.cs

@ -57,7 +57,7 @@ namespace Avalonia.Media.TextFormatting
textSourceLength,
paragraphWidth, paragraphProperties, resolvedFlowDirection, nextLineBreak);
textLine.FinalizeLine();
textLine.FinalizeLine();
return textLine;
}
@ -236,49 +236,49 @@ namespace Avalonia.Media.TextFormatting
switch (currentRun)
{
case UnshapedTextRun shapeableRun:
{
groupedRuns.Clear();
groupedRuns.Add(shapeableRun);
{
groupedRuns.Clear();
groupedRuns.Add(shapeableRun);
var text = shapeableRun.Text;
var properties = shapeableRun.Properties;
var text = shapeableRun.Text;
var properties = shapeableRun.Properties;
while (index + 1 < processedRuns.Count)
{
if (processedRuns[index + 1] is not UnshapedTextRun nextRun)
while (index + 1 < processedRuns.Count)
{
if (processedRuns[index + 1] is not UnshapedTextRun nextRun)
{
break;
}
if (shapeableRun.BidiLevel == nextRun.BidiLevel
&& TryJoinContiguousMemories(text, nextRun.Text, out var joinedText)
&& CanShapeTogether(properties, nextRun.Properties))
{
groupedRuns.Add(nextRun);
index++;
shapeableRun = nextRun;
text = joinedText;
continue;
}
break;
}
if (shapeableRun.BidiLevel == nextRun.BidiLevel
&& TryJoinContiguousMemories(text, nextRun.Text, out var joinedText)
&& CanShapeTogether(properties, nextRun.Properties))
{
groupedRuns.Add(nextRun);
index++;
shapeableRun = nextRun;
text = joinedText;
continue;
}
var shaperOptions = new TextShaperOptions(
properties.CachedGlyphTypeface,
properties.FontRenderingEmSize, shapeableRun.BidiLevel, properties.CultureInfo,
paragraphProperties.DefaultIncrementalTab, paragraphProperties.LetterSpacing);
ShapeTogether(groupedRuns, text, shaperOptions, textShaper, shapedRuns);
break;
}
var shaperOptions = new TextShaperOptions(
properties.CachedGlyphTypeface,
properties.FontRenderingEmSize, shapeableRun.BidiLevel, properties.CultureInfo,
paragraphProperties.DefaultIncrementalTab, paragraphProperties.LetterSpacing);
ShapeTogether(groupedRuns, text, shaperOptions, textShaper, shapedRuns);
break;
}
default:
{
shapedRuns.Add(currentRun);
{
shapedRuns.Add(currentRun);
break;
}
break;
}
}
}
}
@ -699,7 +699,7 @@ namespace Avalonia.Media.TextFormatting
switch (currentRun)
{
case ShapedTextRun:
{
{
var lineBreaker = new LineBreakEnumerator(currentRun.Text.Span);
while (lineBreaker.MoveNext(out var lineBreak))
@ -741,7 +741,7 @@ namespace Avalonia.Media.TextFormatting
break;
}
while (lineBreaker.MoveNext(out lineBreak) && index < textRuns.Count)
while (lineBreaker.MoveNext(out lineBreak))
{
currentPosition += lineBreak.PositionWrap;
@ -767,6 +767,11 @@ namespace Avalonia.Media.TextFormatting
currentPosition = currentLength + lineBreak.PositionWrap;
}
if (currentPosition == 0 && measuredLength > 0)
{
currentPosition = measuredLength;
}
breakFound = true;
break;

14
src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs

@ -172,9 +172,21 @@ namespace Avalonia.Media.TextFormatting
distance -= Start;
var firstRunIndex = 0;
if (_textRuns[firstRunIndex] is TextEndOfLine)
{
firstRunIndex++;
}
if(firstRunIndex >= _textRuns.Length)
{
return new CharacterHit(FirstTextSourceIndex);
}
if (distance <= 0)
{
var firstRun = _textRuns[0];
var firstRun = _textRuns[firstRunIndex];
return GetRunCharacterHit(firstRun, FirstTextSourceIndex, 0);
}

8
tests/Avalonia.Skia.UnitTests/Media/TextFormatting/SingleBufferTextSource.cs

@ -7,25 +7,27 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
{
private readonly string _text;
private readonly GenericTextRunProperties _defaultGenericPropertiesRunProperties;
private readonly bool _addEndOfParagraph;
public SingleBufferTextSource(string text, GenericTextRunProperties defaultProperties)
public SingleBufferTextSource(string text, GenericTextRunProperties defaultProperties, bool addEndOfParagraph = false)
{
_text = text;
_defaultGenericPropertiesRunProperties = defaultProperties;
_addEndOfParagraph = addEndOfParagraph;
}
public TextRun GetTextRun(int textSourceIndex)
{
if (textSourceIndex >= _text.Length)
{
return null;
return _addEndOfParagraph ? new TextEndOfParagraph() : null;
}
var runText = _text.AsMemory(textSourceIndex);
if (runText.IsEmpty)
{
return null;
return _addEndOfParagraph ? new TextEndOfParagraph() : null;
}
return new TextCharacters(runText, _defaultGenericPropertiesRunProperties);

11
tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs

@ -242,10 +242,16 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
{
var defaultProperties = new GenericTextRunProperties(Typeface.Default);
var textSource = new SingleBufferTextSource(text, defaultProperties);
var paragraphProperties = new GenericTextParagraphProperties(defaultProperties, textWrap: TextWrapping.WrapWithOverflow);
var textSource = new SingleBufferTextSource("ABCDEFHFFHFJHKHFK", defaultProperties, true);
var formatter = new TextFormatterImpl();
var line = formatter.FormatLine(textSource, 0, 33, paragraphProperties);
textSource = new SingleBufferTextSource(text, defaultProperties);
var numberOfLines = 0;
var currentPosition = 0;
@ -253,8 +259,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
while (currentPosition < text.Length)
{
var textLine =
formatter.FormatLine(textSource, currentPosition, 1,
new GenericTextParagraphProperties(defaultProperties, textWrap: TextWrapping.WrapWithOverflow));
formatter.FormatLine(textSource, currentPosition, 1, paragraphProperties);
if (text.Length - currentPosition > expectedCharactersPerLine)
{

Loading…
Cancel
Save