diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs index f73a335de55..fbdf8857093 100644 --- a/src/Avalonia.Controls/Presenters/TextPresenter.cs +++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs @@ -275,7 +275,7 @@ protected override Size MeasureOverride(Size availableSize) Typeface = new Typeface(FontFamily, FontSize, FontStyle, FontWeight), TextAlignment = TextAlignment, Constraint = availableSize, - }.Measure(); + }.Bounds.Size; } } diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs index af7b0f835e2..6b0c48b97b5 100644 --- a/src/Avalonia.Controls/TextBlock.cs +++ b/src/Avalonia.Controls/TextBlock.cs @@ -396,7 +396,7 @@ protected override Size MeasureOverride(Size availableSize) FormattedText.Constraint = Size.Infinity; } - return FormattedText.Measure(); + return FormattedText.Bounds.Size; } return new Size(); diff --git a/src/Avalonia.Visuals/Media/FormattedText.cs b/src/Avalonia.Visuals/Media/FormattedText.cs index 0d456eb3b70..e20e03e2969 100644 --- a/src/Avalonia.Visuals/Media/FormattedText.cs +++ b/src/Avalonia.Visuals/Media/FormattedText.cs @@ -37,6 +37,12 @@ public FormattedText(IPlatformRenderInterface platform) _platform = platform; } + /// + /// Gets the bounds of the text within the . + /// + /// The bounds of the text. + public Rect Bounds => PlatformImpl.Bounds; + /// /// Gets or sets the constraint of the text. /// @@ -158,15 +164,6 @@ public IEnumerable HitTestTextRange(int index, int length) return PlatformImpl.HitTestTextRange(index, length); } - /// - /// Gets the size of the text, taking into account. - /// - /// The bounds box of the text. - public Size Measure() - { - return PlatformImpl.Size; - } - private void Set(ref T field, T value) { field = value; diff --git a/src/Avalonia.Visuals/Platform/IFormattedTextImpl.cs b/src/Avalonia.Visuals/Platform/IFormattedTextImpl.cs index 2a4e9cde4f2..2543e4f3630 100644 --- a/src/Avalonia.Visuals/Platform/IFormattedTextImpl.cs +++ b/src/Avalonia.Visuals/Platform/IFormattedTextImpl.cs @@ -1,6 +1,7 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System; using System.Collections.Generic; using Avalonia.Media; @@ -17,9 +18,9 @@ public interface IFormattedTextImpl Size Constraint { get; } /// - /// The measured size of the text. + /// The measured bounds of the text. /// - Size Size { get; } + Rect Bounds{ get; } /// /// Gets the text. diff --git a/src/Avalonia.Visuals/Rendering/RendererBase.cs b/src/Avalonia.Visuals/Rendering/RendererBase.cs index ed464ec7f93..7b10fc1212f 100644 --- a/src/Avalonia.Visuals/Rendering/RendererBase.cs +++ b/src/Avalonia.Visuals/Rendering/RendererBase.cs @@ -45,7 +45,7 @@ protected void RenderFps(IDrawingContextImpl context, Rect clientRect, int? laye _fpsText.Text = string.Format("FPS: {0:000}", _fps); } - var size = _fpsText.Measure(); + var size = _fpsText.Bounds.Size; var rect = new Rect(clientRect.Right - size.Width, 0, size.Width, size.Height); context.Transform = Matrix.Identity; diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs index c06d0d26b46..dec5c382c9e 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs @@ -27,7 +27,7 @@ public TextNode( Point origin, IFormattedTextImpl text, IDictionary childScenes = null) - : base(new Rect(origin, text.Size), transform, null) + : base(text.Bounds, transform, null) { Transform = transform; Foreground = foreground?.ToImmutable(); diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index 10e746cbd5f..e69d1553059 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -218,7 +218,7 @@ public void FillRectangle(IBrush brush, Rect rect, float cornerRadius = 0) /// public void DrawText(IBrush foreground, Point origin, IFormattedTextImpl text) { - using (var paint = CreatePaint(foreground, text.Size)) + using (var paint = CreatePaint(foreground, text.Bounds.Size)) { var textImpl = (FormattedTextImpl) text; textImpl.Draw(this, Canvas, origin.ToSKPoint(), paint, _canTextUseLcdRendering); diff --git a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs index 7e3f4aa40a4..c83d5f26fb3 100644 --- a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs +++ b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs @@ -89,7 +89,7 @@ public FormattedTextImpl( public Size Constraint => _constraint; - public Size Size => _size; + public Rect Bounds => _bounds; public IEnumerable GetLines() { @@ -135,7 +135,7 @@ public TextHitTestResult HitTestPoint(Point point) }; } - bool end = point.X > _size.Width || point.Y > _lines.Sum(l => l.Height); + bool end = point.X > _bounds.Width || point.Y > _lines.Sum(l => l.Height); return new TextHitTestResult() { @@ -323,7 +323,7 @@ internal void Draw(DrawingContextImpl context, private Size _constraint = new Size(double.PositiveInfinity, double.PositiveInfinity); private float _lineHeight = 0; private float _lineOffset = 0; - private Size _size; + private Rect _bounds; private List _skiaLines; private static void ApplyWrapperTo(ref SKPaint current, DrawingContextImpl.PaintWrapper wrapper, @@ -639,12 +639,26 @@ private void Rebuild() if (_skiaLines.Count == 0) { _lines.Add(new FormattedTextLine(0, _lineHeight)); - _size = new Size(0, _lineHeight); + _bounds = new Rect(0, 0, 0, _lineHeight); } else { var lastLine = _skiaLines[_skiaLines.Count - 1]; - _size = new Size(maxX, lastLine.Top + lastLine.Height); + _bounds = new Rect(0, 0, maxX, lastLine.Top + lastLine.Height); + + switch (_paint.TextAlign) + { + case SKTextAlign.Center: + _bounds = new Rect(Constraint).CenterRect(_bounds); + break; + case SKTextAlign.Right: + _bounds = new Rect( + Constraint.Width - _bounds.Width, + 0, + _bounds.Width, + _bounds.Height); + break; + } } } @@ -660,7 +674,7 @@ private float TransformX(float originX, float lineWidth, SKTextAlign align) { double width = Constraint.Width > 0 && !double.IsPositiveInfinity(Constraint.Width) ? Constraint.Width : - _size.Width; + _bounds.Width; switch (align) { diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs index 5e150ff647e..6123088d7ec 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs @@ -274,7 +274,7 @@ public void DrawText(IBrush foreground, Point origin, IFormattedTextImpl text) { var impl = (FormattedTextImpl)text; - using (var brush = CreateBrush(foreground, impl.Size)) + using (var brush = CreateBrush(foreground, impl.Bounds.Size)) using (var renderer = new AvaloniaTextRenderer(this, _deviceContext, brush.PlatformBrush)) { if (brush.PlatformBrush != null) diff --git a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs index 7164ec7c0d1..b3cc4c8e0d8 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs @@ -45,12 +45,12 @@ public FormattedTextImpl( } } - Size = Measure(); + Bounds = Measure(); } public Size Constraint => new Size(TextLayout.MaxWidth, TextLayout.MaxHeight); - public Size Size { get; } + public Rect Bounds { get; } public string Text { get; } @@ -104,7 +104,7 @@ private void ApplySpan(FormattedTextStyleSpan span) } } - private Size Measure() + private Rect Measure() { var metrics = TextLayout.Metrics; @@ -115,7 +115,11 @@ private Size Measure() width = metrics.Width; } - return new Size(width, TextLayout.Metrics.Height); + return new Rect( + TextLayout.Metrics.Left, + TextLayout.Metrics.Top, + width, + TextLayout.Metrics.Height); } } } diff --git a/tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs b/tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs index ffdb146eecb..6cf38b6121e 100644 --- a/tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs +++ b/tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs @@ -146,7 +146,7 @@ public FormattedTextMock(string text) public string Text { get; } - public Size Size => new Size(); + public Rect Bounds => Rect.Empty; public void Dispose() { diff --git a/tests/Avalonia.RenderTests/Media/FormattedTextImplTests.cs b/tests/Avalonia.RenderTests/Media/FormattedTextImplTests.cs index a8f9d42c1e8..353123ab2a7 100644 --- a/tests/Avalonia.RenderTests/Media/FormattedTextImplTests.cs +++ b/tests/Avalonia.RenderTests/Media/FormattedTextImplTests.cs @@ -100,7 +100,7 @@ private IFormattedTextImpl Create(string text, double fontSize, TextWrapping wra public void Should_Measure_String_Correctly(string input, double fontSize, double expWidth, double expHeight) { var fmt = Create(input, fontSize); - var size = fmt.Size; + var size = fmt.Bounds.Size; Assert.Equal(expWidth, size.Width, 2); Assert.Equal(expHeight, size.Height, 2); @@ -265,4 +265,4 @@ public void Should_HitTestRange_Correctly(string input, } } } -} \ No newline at end of file +}