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>
This commit is contained in:
Julien Lebosquain 2024-11-30 15:21:32 +01:00 коммит произвёл GitHub
Родитель 1583de3e33
Коммит f4633e210c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
3 изменённых файлов: 38 добавлений и 6 удалений

Просмотреть файл

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

Просмотреть файл

@ -162,7 +162,7 @@ namespace Avalonia.Controls
nameof(Inlines), t => t.Inlines, (t, v) => t.Inlines = v);
private TextLayout? _textLayout;
protected Size _constraint = Size.Infinity;
protected Size _constraint = new(double.NaN, double.NaN);
protected IReadOnlyList<TextRun>? _textRuns;
private InlineCollection? _inlines;
@ -366,6 +366,13 @@ namespace Avalonia.Controls
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>
/// The BaselineOffset property provides an adjustment to baseline offset
/// </summary>
@ -670,12 +677,14 @@ namespace Avalonia.Controls
textSource = new SimpleTextSource(text ?? "", defaultProperties);
}
var maxSize = GetMaxSizeFromConstraint();
return new TextLayout(
textSource,
paragraphProperties,
TextTrimming,
_constraint.Width,
_constraint.Height,
maxSize.Width,
maxSize.Height,
MaxLines);
}

Просмотреть файл

@ -1,3 +1,4 @@
using System;
using Avalonia.Controls.Documents;
using Avalonia.Controls.Templates;
using Avalonia.Data;
@ -33,7 +34,9 @@ namespace Avalonia.Controls.UnitTests
{
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));
@ -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
{
public Size Constraint => _constraint;