Browse Source

Fix text wrapping behavior (#7397)

* Allow one-character runs line breaks

* Remove unuseful ignored nullable

* Prevent redundant allocations

* Fix empty line handling

* Update TextFormatterImpl.cs

Co-authored-by: Benedikt Stebner <b.stebner@outlook.de>
Co-authored-by: Benedikt Stebner <Gillibald@users.noreply.github.com>
pull/7411/head
ingen084 4 years ago
committed by GitHub
parent
commit
3908e4d71d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      src/Avalonia.Visuals/Media/TextFormatting/TextFormatterImpl.cs
  2. 10
      src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs

23
src/Avalonia.Visuals/Media/TextFormatting/TextFormatterImpl.cs

@ -193,7 +193,7 @@ namespace Avalonia.Media.TextFormatting
{
var currentRun = textRuns[i];
if (currentLength + currentRun.GlyphRun.Characters.Length < length)
if (currentLength + currentRun.GlyphRun.Characters.Length <= length)
{
currentLength += currentRun.GlyphRun.Characters.Length;
continue;
@ -283,26 +283,26 @@ namespace Avalonia.Media.TextFormatting
{
var shapedCharacters = previousLineBreak.RemainingCharacters[index];
if (shapedCharacters == null)
{
continue;
}
textRuns.Add(shapedCharacters);
if (TryGetLineBreak(shapedCharacters, out var runLineBreak))
{
var splitResult = SplitTextRuns(textRuns, currentLength + runLineBreak.PositionWrap);
if (splitResult.Second == null)
{
return splitResult.First;
}
if (++index < previousLineBreak.RemainingCharacters.Count)
{
for (; index < previousLineBreak.RemainingCharacters.Count; index++)
{
splitResult.Second!.Add(previousLineBreak.RemainingCharacters[index]);
splitResult.Second.Add(previousLineBreak.RemainingCharacters[index]);
}
}
nextLineBreak = new TextLineBreak(splitResult.Second!);
nextLineBreak = new TextLineBreak(splitResult.Second);
return splitResult.First;
}
@ -346,7 +346,10 @@ namespace Avalonia.Media.TextFormatting
{
var splitResult = SplitTextRuns(textRuns, currentLength + runLineBreak.PositionWrap);
nextLineBreak = new TextLineBreak(splitResult.Second!);
if (splitResult.Second != null)
{
nextLineBreak = new TextLineBreak(splitResult.Second);
}
return splitResult.First;
}
@ -532,7 +535,7 @@ namespace Avalonia.Media.TextFormatting
/// <returns>The text range that is covered by the text runs.</returns>
private static TextRange GetTextRange(IReadOnlyList<TextRun> textRuns)
{
if (textRuns is null || textRuns.Count == 0)
if (textRuns.Count == 0)
{
return new TextRange();
}

10
src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs

@ -401,14 +401,12 @@ namespace Avalonia.Media.TextFormatting
previousLine = textLine;
if (currentPosition != _text.Length || textLine.TextLineBreak?.RemainingCharacters == null)
if (currentPosition == _text.Length && textLine.NewLineLength > 0)
{
continue;
}
var emptyTextLine = CreateEmptyTextLine(currentPosition);
var emptyTextLine = CreateEmptyTextLine(currentPosition);
textLines.Add(emptyTextLine);
textLines.Add(emptyTextLine);
}
}
Size = new Size(width, height);

Loading…
Cancel
Save