diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs index 560c1952ac..a7ec6457fa 100644 --- a/src/Avalonia.Controls/TextBlock.cs +++ b/src/Avalonia.Controls/TextBlock.cs @@ -118,6 +118,8 @@ namespace Avalonia.Controls { ClipToBoundsProperty.OverrideDefaultValue(true); + AffectsRender(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) diff --git a/src/Avalonia.Visuals/Media/TextFormatting/SimpleTextFormatter.cs b/src/Avalonia.Visuals/Media/TextFormatting/SimpleTextFormatter.cs index e84242c628..30d513386e 100644 --- a/src/Avalonia.Visuals/Media/TextFormatting/SimpleTextFormatter.cs +++ b/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]; diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs index 0c9013e6f7..2ef7322eaa 100644 --- a/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs +++ b/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);