Browse Source

Fix TextBlock re-measure in infinite container (#17638)

* Add failing test for TextBlock

* Fix TextBlock re-measure in infinite container

* Fix outdated test

---------

Co-authored-by: Max Katz <maxkatz6@outlook.com>
release/11.2.3
Julien Lebosquain 1 year ago
committed by Max Katz
parent
commit
cc4dbdaeb4
  1. 6
      src/Avalonia.Controls/SelectableTextBlock.cs
  2. 15
      src/Avalonia.Controls/TextBlock.cs
  3. 23
      tests/Avalonia.Controls.UnitTests/TextBlockTests.cs

6
src/Avalonia.Controls/SelectableTextBlock.cs

@ -224,12 +224,14 @@ namespace Avalonia.Controls
textSource = new FormattedTextSource(text ?? "", defaultProperties, textStyleOverrides); textSource = new FormattedTextSource(text ?? "", defaultProperties, textStyleOverrides);
} }
var maxSize = GetMaxSizeFromConstraint();
return new TextLayout( return new TextLayout(
textSource, textSource,
paragraphProperties, paragraphProperties,
TextTrimming, TextTrimming,
_constraint.Width, maxSize.Width,
_constraint.Height, maxSize.Height,
MaxLines); MaxLines);
} }

15
src/Avalonia.Controls/TextBlock.cs

@ -162,7 +162,7 @@ namespace Avalonia.Controls
nameof(Inlines), t => t.Inlines, (t, v) => t.Inlines = v); nameof(Inlines), t => t.Inlines, (t, v) => t.Inlines = v);
private TextLayout? _textLayout; private TextLayout? _textLayout;
protected Size _constraint = Size.Infinity; protected Size _constraint = new(double.NaN, double.NaN);
protected IReadOnlyList<TextRun>? _textRuns; protected IReadOnlyList<TextRun>? _textRuns;
private InlineCollection? _inlines; private InlineCollection? _inlines;
@ -366,6 +366,13 @@ namespace Avalonia.Controls
internal bool HasComplexContent => Inlines != null && Inlines.Count > 0; internal bool HasComplexContent => Inlines != null && Inlines.Count > 0;
private protected Size GetMaxSizeFromConstraint()
{
var maxWidth = double.IsNaN(_constraint.Width) ? 0.0 : _constraint.Width;
var maxHeight = double.IsNaN(_constraint.Height) ? 0.0 : _constraint.Height;
return new Size(maxWidth, maxHeight);
}
/// <summary> /// <summary>
/// The BaselineOffset property provides an adjustment to baseline offset /// The BaselineOffset property provides an adjustment to baseline offset
/// </summary> /// </summary>
@ -670,12 +677,14 @@ namespace Avalonia.Controls
textSource = new SimpleTextSource(text ?? "", defaultProperties); textSource = new SimpleTextSource(text ?? "", defaultProperties);
} }
var maxSize = GetMaxSizeFromConstraint();
return new TextLayout( return new TextLayout(
textSource, textSource,
paragraphProperties, paragraphProperties,
TextTrimming, TextTrimming,
_constraint.Width, maxSize.Width,
_constraint.Height, maxSize.Height,
MaxLines); MaxLines);
} }

23
tests/Avalonia.Controls.UnitTests/TextBlockTests.cs

@ -1,3 +1,4 @@
using System;
using Avalonia.Controls.Documents; using Avalonia.Controls.Documents;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.Data; using Avalonia.Data;
@ -33,7 +34,9 @@ namespace Avalonia.Controls.UnitTests
{ {
var textBlock = new TestTextBlock { Text = "Hello World" }; var textBlock = new TestTextBlock { Text = "Hello World" };
Assert.Equal(Size.Infinity, textBlock.Constraint); var constraint = textBlock.Constraint;
Assert.True(double.IsNaN(constraint.Width));
Assert.True(double.IsNaN(constraint.Height));
textBlock.Measure(new Size(100, 100)); textBlock.Measure(new Size(100, 100));
@ -413,6 +416,24 @@ namespace Avalonia.Controls.UnitTests
} }
} }
[Fact]
public void TextBlock_With_Infinite_Size_Should_Be_Remeasured_After_TextLayout_Created()
{
using var app = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface);
var target = new TextBlock { Text = "" };
var layout = target.TextLayout;
Assert.Equal(0.0, layout.MaxWidth);
Assert.Equal(0.0, layout.MaxHeight);
target.Text = "foo";
target.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
Assert.True(target.DesiredSize.Width > 0);
Assert.True(target.DesiredSize.Height > 0);
}
private class TestTextBlock : TextBlock private class TestTextBlock : TextBlock
{ {
public Size Constraint => _constraint; public Size Constraint => _constraint;

Loading…
Cancel
Save