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); ClipToBoundsProperty.OverrideDefaultValue<TextBlock>(true);
AffectsRender<TextBlock>(BackgroundProperty);
Observable.Merge( Observable.Merge(
TextProperty.Changed, TextProperty.Changed,
ForegroundProperty.Changed, ForegroundProperty.Changed,
@ -438,7 +440,9 @@ namespace Avalonia.Controls
_constraint = availableSize; _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) 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 availableWidth = paragraphWidth;
var currentWidth = 0.0; var currentWidth = 0.0;
var runIndex = 0; var runIndex = 0;
var length = 0;
while (runIndex < textRuns.Count) while (runIndex < textRuns.Count)
{ {
var currentRun = textRuns[runIndex]; var currentRun = textRuns[runIndex];
currentWidth += currentRun.GlyphRun.Bounds.Width; if (currentWidth + currentRun.GlyphRun.Bounds.Width > availableWidth)
if (currentWidth > availableWidth)
{ {
var measuredLength = MeasureText(currentRun, paragraphWidth); var measuredLength = MeasureText(currentRun, paragraphWidth - currentWidth);
if (measuredLength < text.End) if (measuredLength < currentRun.Text.Length)
{ {
var currentBreakPosition = -1; 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 = var textLineMetrics =
TextLineMetrics.Create(splitResult.First, paragraphWidth, paragraphProperties.TextAlignment); 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++; runIndex++;
} }
@ -281,12 +284,18 @@ namespace Avalonia.Media.TextFormatting
if (measuredWidth + advance > availableWidth) if (measuredWidth + advance > availableWidth)
{ {
index--;
break; break;
} }
measuredWidth += advance; measuredWidth += advance;
} }
if(index < 0)
{
return 0;
}
var cluster = textRun.GlyphRun.GlyphClusters[index]; var cluster = textRun.GlyphRun.GlyphClusters[index];
var characterHit = textRun.GlyphRun.FindNearestCharacterHit(cluster, out _); var characterHit = textRun.GlyphRun.FindNearestCharacterHit(cluster, out _);
@ -355,7 +364,7 @@ namespace Avalonia.Media.TextFormatting
continue; 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]; 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); 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); UpdateBounds(textLine, ref left, ref right, ref bottom);
textLines.Add(textLine); textLines.Add(textLine);
@ -253,17 +258,17 @@ namespace Avalonia.Media.TextFormatting
{ {
var emptyTextLine = CreateEmptyTextLine(currentPosition); var emptyTextLine = CreateEmptyTextLine(currentPosition);
if (!double.IsPositiveInfinity(MaxHeight) && bottom + emptyTextLine.LineMetrics.Size.Height > MaxHeight)
{
break;
}
UpdateBounds(emptyTextLine, ref left, ref right, ref bottom); UpdateBounds(emptyTextLine, ref left, ref right, ref bottom);
textLines.Add(emptyTextLine); textLines.Add(emptyTextLine);
break; break;
} }
if (!double.IsPositiveInfinity(MaxHeight) && MaxHeight < Bounds.Height)
{
break;
}
} }
Bounds = new Rect(left, 0, right, bottom); Bounds = new Rect(left, 0, right, bottom);

Loading…
Cancel
Save