Browse Source

Fix TextWrapping

pull/3652/head
Benedikt Schroeder 7 years ago
parent
commit
6c948af49d
  1. 6
      src/Avalonia.Controls/TextBlock.cs
  2. 27
      src/Avalonia.Visuals/Media/TextFormatting/SimpleTextFormatter.cs
  3. 15
      src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs

6
src/Avalonia.Controls/TextBlock.cs

@ -118,6 +118,8 @@ namespace Avalonia.Controls
{
ClipToBoundsProperty.OverrideDefaultValue<TextBlock>(true);
AffectsRender<TextBlock>(BackgroundProperty);
Observable.Merge(
TextProperty.Changed,
ForegroundProperty.Changed,
@ -438,7 +440,9 @@ namespace Avalonia.Controls
_constraint = availableSize;
return TextLayout?.Bounds.Size ?? Size.Empty;
var measuredSize = TextLayout?.Bounds.Size ?? Size.Empty;
return measuredSize.Inflate(padding);
}
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)

27
src/Avalonia.Visuals/Media/TextFormatting/SimpleTextFormatter.cs

@ -201,18 +201,17 @@ namespace Avalonia.Media.TextFormatting
var availableWidth = paragraphWidth;
var currentWidth = 0.0;
var runIndex = 0;
var length = 0;
while (runIndex < textRuns.Count)
{
var currentRun = textRuns[runIndex];
currentWidth += currentRun.GlyphRun.Bounds.Width;
if (currentWidth > availableWidth)
if (currentWidth + currentRun.GlyphRun.Bounds.Width > availableWidth)
{
var measuredLength = MeasureText(currentRun, paragraphWidth);
var measuredLength = MeasureText(currentRun, paragraphWidth - currentWidth);
if (measuredLength < text.End)
if (measuredLength < currentRun.Text.Length)
{
var currentBreakPosition = -1;
@ -241,15 +240,19 @@ namespace Avalonia.Media.TextFormatting
}
}
var splitResult = SplitTextRuns(textRuns, measuredLength);
length += measuredLength;
var splitResult = SplitTextRuns(textRuns, length);
var textLineMetrics =
TextLineMetrics.Create(splitResult.First, paragraphWidth, paragraphProperties.TextAlignment);
return new SimpleTextLine(text.Take(measuredLength), splitResult.First, textLineMetrics);
return new SimpleTextLine(text.Take(length), splitResult.First, textLineMetrics);
}
availableWidth -= currentRun.GlyphRun.Bounds.Width;
currentWidth += currentRun.GlyphRun.Bounds.Width;
length += currentRun.GlyphRun.Characters.Length;
runIndex++;
}
@ -281,12 +284,18 @@ namespace Avalonia.Media.TextFormatting
if (measuredWidth + advance > availableWidth)
{
index--;
break;
}
measuredWidth += advance;
}
if(index < 0)
{
return 0;
}
var cluster = textRun.GlyphRun.GlyphClusters[index];
var characterHit = textRun.GlyphRun.FindNearestCharacterHit(cluster, out _);
@ -355,7 +364,7 @@ namespace Avalonia.Media.TextFormatting
continue;
}
var firstCount = currentRun.GlyphRun.Characters.Length > 1 ? i + 1 : i;
var firstCount = currentRun.GlyphRun.Characters.Length >= 1 ? i + 1 : i;
var first = new ShapedTextRun[firstCount];

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

@ -233,6 +233,11 @@ namespace Avalonia.Media.TextFormatting
var textLine = TextFormatter.Current.FormatLine(textSource, 0, MaxWidth, _paragraphProperties);
if (!double.IsPositiveInfinity(MaxHeight) && bottom + textLine.LineMetrics.Size.Height > MaxHeight)
{
break;
}
UpdateBounds(textLine, ref left, ref right, ref bottom);
textLines.Add(textLine);
@ -253,17 +258,17 @@ namespace Avalonia.Media.TextFormatting
{
var emptyTextLine = CreateEmptyTextLine(currentPosition);
if (!double.IsPositiveInfinity(MaxHeight) && bottom + emptyTextLine.LineMetrics.Size.Height > MaxHeight)
{
break;
}
UpdateBounds(emptyTextLine, ref left, ref right, ref bottom);
textLines.Add(emptyTextLine);
break;
}
if (!double.IsPositiveInfinity(MaxHeight) && MaxHeight < Bounds.Height)
{
break;
}
}
Bounds = new Rect(left, 0, right, bottom);

Loading…
Cancel
Save