Browse Source

Merge branch 'master' into platform-options

pull/2368/head
Steven Kirk 7 years ago
committed by GitHub
parent
commit
92a279c2d2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/Avalonia.Controls/Presenters/TextPresenter.cs
  2. 2
      src/Avalonia.Controls/TextBlock.cs
  3. 3
      src/Avalonia.Controls/UserControl.cs
  4. 2
      src/Avalonia.Themes.Default/UserControl.xaml
  5. 15
      src/Avalonia.Visuals/Media/FormattedText.cs
  6. 5
      src/Avalonia.Visuals/Platform/IFormattedTextImpl.cs
  7. 2
      src/Avalonia.Visuals/Rendering/RendererBase.cs
  8. 2
      src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs
  9. 36
      src/Avalonia.Visuals/VisualTree/TransformedBounds.cs
  10. 2
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs
  11. 26
      src/Skia/Avalonia.Skia/FormattedTextImpl.cs
  12. 2
      src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
  13. 12
      src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs
  14. 2
      tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs
  15. 4
      tests/Avalonia.RenderTests/Media/FormattedTextImplTests.cs
  16. 25
      tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/TextNodeTests.cs

2
src/Avalonia.Controls/Presenters/TextPresenter.cs

@ -275,7 +275,7 @@ namespace Avalonia.Controls.Presenters
Typeface = new Typeface(FontFamily, FontSize, FontStyle, FontWeight), Typeface = new Typeface(FontFamily, FontSize, FontStyle, FontWeight),
TextAlignment = TextAlignment, TextAlignment = TextAlignment,
Constraint = availableSize, Constraint = availableSize,
}.Measure(); }.Bounds.Size;
} }
} }

2
src/Avalonia.Controls/TextBlock.cs

@ -396,7 +396,7 @@ namespace Avalonia.Controls
FormattedText.Constraint = Size.Infinity; FormattedText.Constraint = Size.Infinity;
} }
return FormattedText.Measure(); return FormattedText.Bounds.Size;
} }
return new Size(); return new Size();

3
src/Avalonia.Controls/UserControl.cs

@ -27,9 +27,6 @@ namespace Avalonia.Controls
remove { _nameScope.Unregistered -= value; } remove { _nameScope.Unregistered -= value; }
} }
/// <inheritdoc/>
Type IStyleable.StyleKey => typeof(UserControl);
/// <inheritdoc/> /// <inheritdoc/>
void INameScope.Register(string name, object element) void INameScope.Register(string name, object element)
{ {

2
src/Avalonia.Themes.Default/UserControl.xaml

@ -1,4 +1,4 @@
<Style xmlns="https://github.com/avaloniaui" Selector="UserControl"> <Style xmlns="https://github.com/avaloniaui" Selector=":is(UserControl)">
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<ContentPresenter Name="PART_ContentPresenter" <ContentPresenter Name="PART_ContentPresenter"

15
src/Avalonia.Visuals/Media/FormattedText.cs

@ -37,6 +37,12 @@ namespace Avalonia.Media
_platform = platform; _platform = platform;
} }
/// <summary>
/// Gets the bounds of the text within the <see cref="Constraint"/>.
/// </summary>
/// <returns>The bounds of the text.</returns>
public Rect Bounds => PlatformImpl.Bounds;
/// <summary> /// <summary>
/// Gets or sets the constraint of the text. /// Gets or sets the constraint of the text.
/// </summary> /// </summary>
@ -158,15 +164,6 @@ namespace Avalonia.Media
return PlatformImpl.HitTestTextRange(index, length); return PlatformImpl.HitTestTextRange(index, length);
} }
/// <summary>
/// Gets the size of the text, taking <see cref="Constraint"/> into account.
/// </summary>
/// <returns>The bounds box of the text.</returns>
public Size Measure()
{
return PlatformImpl.Size;
}
private void Set<T>(ref T field, T value) private void Set<T>(ref T field, T value)
{ {
field = value; field = value;

5
src/Avalonia.Visuals/Platform/IFormattedTextImpl.cs

@ -1,6 +1,7 @@
// Copyright (c) The Avalonia Project. All rights reserved. // 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. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Media; using Avalonia.Media;
@ -17,9 +18,9 @@ namespace Avalonia.Platform
Size Constraint { get; } Size Constraint { get; }
/// <summary> /// <summary>
/// The measured size of the text. /// The measured bounds of the text.
/// </summary> /// </summary>
Size Size { get; } Rect Bounds{ get; }
/// <summary> /// <summary>
/// Gets the text. /// Gets the text.

2
src/Avalonia.Visuals/Rendering/RendererBase.cs

@ -45,7 +45,7 @@ namespace Avalonia.Rendering
_fpsText.Text = string.Format("FPS: {0:000}", _fps); _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); var rect = new Rect(clientRect.Right - size.Width, 0, size.Width, size.Height);
context.Transform = Matrix.Identity; context.Transform = Matrix.Identity;

2
src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs

@ -27,7 +27,7 @@ namespace Avalonia.Rendering.SceneGraph
Point origin, Point origin,
IFormattedTextImpl text, IFormattedTextImpl text,
IDictionary<IVisual, Scene> childScenes = null) IDictionary<IVisual, Scene> childScenes = null)
: base(new Rect(origin, text.Size), transform, null) : base(text.Bounds.Translate(origin), transform, null)
{ {
Transform = transform; Transform = transform;
Foreground = foreground?.ToImmutable(); Foreground = foreground?.ToImmutable();

36
src/Avalonia.Visuals/VisualTree/TransformedBounds.cs

@ -50,5 +50,41 @@ namespace Avalonia.VisualTree
return Bounds.Contains(point); return Bounds.Contains(point);
} }
} }
public bool Equals(TransformedBounds other)
{
return Bounds == other.Bounds && Clip == other.Clip && Transform == other.Transform;
}
public override bool Equals(object obj)
{
if (obj is null)
{
return false;
}
return obj is TransformedBounds other && Equals(other);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = Bounds.GetHashCode();
hashCode = (hashCode * 397) ^ Clip.GetHashCode();
hashCode = (hashCode * 397) ^ Transform.GetHashCode();
return hashCode;
}
}
public static bool operator ==(TransformedBounds left, TransformedBounds right)
{
return left.Equals(right);
}
public static bool operator !=(TransformedBounds left, TransformedBounds right)
{
return !left.Equals(right);
}
} }
} }

2
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -218,7 +218,7 @@ namespace Avalonia.Skia
/// <inheritdoc /> /// <inheritdoc />
public void DrawText(IBrush foreground, Point origin, IFormattedTextImpl text) 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; var textImpl = (FormattedTextImpl) text;
textImpl.Draw(this, Canvas, origin.ToSKPoint(), paint, _canTextUseLcdRendering); textImpl.Draw(this, Canvas, origin.ToSKPoint(), paint, _canTextUseLcdRendering);

26
src/Skia/Avalonia.Skia/FormattedTextImpl.cs

@ -89,7 +89,7 @@ namespace Avalonia.Skia
public Size Constraint => _constraint; public Size Constraint => _constraint;
public Size Size => _size; public Rect Bounds => _bounds;
public IEnumerable<FormattedTextLine> GetLines() public IEnumerable<FormattedTextLine> GetLines()
{ {
@ -135,7 +135,7 @@ namespace Avalonia.Skia
}; };
} }
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() return new TextHitTestResult()
{ {
@ -323,7 +323,7 @@ namespace Avalonia.Skia
private Size _constraint = new Size(double.PositiveInfinity, double.PositiveInfinity); private Size _constraint = new Size(double.PositiveInfinity, double.PositiveInfinity);
private float _lineHeight = 0; private float _lineHeight = 0;
private float _lineOffset = 0; private float _lineOffset = 0;
private Size _size; private Rect _bounds;
private List<AvaloniaFormattedTextLine> _skiaLines; private List<AvaloniaFormattedTextLine> _skiaLines;
private static void ApplyWrapperTo(ref SKPaint current, DrawingContextImpl.PaintWrapper wrapper, private static void ApplyWrapperTo(ref SKPaint current, DrawingContextImpl.PaintWrapper wrapper,
@ -639,12 +639,26 @@ namespace Avalonia.Skia
if (_skiaLines.Count == 0) if (_skiaLines.Count == 0)
{ {
_lines.Add(new FormattedTextLine(0, _lineHeight)); _lines.Add(new FormattedTextLine(0, _lineHeight));
_size = new Size(0, _lineHeight); _bounds = new Rect(0, 0, 0, _lineHeight);
} }
else else
{ {
var lastLine = _skiaLines[_skiaLines.Count - 1]; 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 @@ namespace Avalonia.Skia
{ {
double width = Constraint.Width > 0 && !double.IsPositiveInfinity(Constraint.Width) ? double width = Constraint.Width > 0 && !double.IsPositiveInfinity(Constraint.Width) ?
Constraint.Width : Constraint.Width :
_size.Width; _bounds.Width;
switch (align) switch (align)
{ {

2
src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs

@ -274,7 +274,7 @@ namespace Avalonia.Direct2D1.Media
{ {
var impl = (FormattedTextImpl)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)) using (var renderer = new AvaloniaTextRenderer(this, _deviceContext, brush.PlatformBrush))
{ {
if (brush.PlatformBrush != null) if (brush.PlatformBrush != null)

12
src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs

@ -45,12 +45,12 @@ namespace Avalonia.Direct2D1.Media
} }
} }
Size = Measure(); Bounds = Measure();
} }
public Size Constraint => new Size(TextLayout.MaxWidth, TextLayout.MaxHeight); public Size Constraint => new Size(TextLayout.MaxWidth, TextLayout.MaxHeight);
public Size Size { get; } public Rect Bounds { get; }
public string Text { get; } public string Text { get; }
@ -104,7 +104,7 @@ namespace Avalonia.Direct2D1.Media
} }
} }
private Size Measure() private Rect Measure()
{ {
var metrics = TextLayout.Metrics; var metrics = TextLayout.Metrics;
@ -115,7 +115,11 @@ namespace Avalonia.Direct2D1.Media
width = metrics.Width; width = metrics.Width;
} }
return new Size(width, TextLayout.Metrics.Height); return new Rect(
TextLayout.Metrics.Left,
TextLayout.Metrics.Top,
width,
TextLayout.Metrics.Height);
} }
} }
} }

2
tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs

@ -146,7 +146,7 @@ namespace Avalonia.Layout.UnitTests
public string Text { get; } public string Text { get; }
public Size Size => new Size(); public Rect Bounds => Rect.Empty;
public void Dispose() public void Dispose()
{ {

4
tests/Avalonia.RenderTests/Media/FormattedTextImplTests.cs

@ -100,7 +100,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media
public void Should_Measure_String_Correctly(string input, double fontSize, double expWidth, double expHeight) public void Should_Measure_String_Correctly(string input, double fontSize, double expWidth, double expHeight)
{ {
var fmt = Create(input, fontSize); var fmt = Create(input, fontSize);
var size = fmt.Size; var size = fmt.Bounds.Size;
Assert.Equal(expWidth, size.Width, 2); Assert.Equal(expWidth, size.Width, 2);
Assert.Equal(expHeight, size.Height, 2); Assert.Equal(expHeight, size.Height, 2);
@ -265,4 +265,4 @@ namespace Avalonia.Direct2D1.RenderTests.Media
} }
} }
} }
} }

25
tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/TextNodeTests.cs

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;
using Avalonia.Platform;
using Avalonia.Rendering.SceneGraph;
using Moq;
using Xunit;
namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
{
public class TextNodeTests
{
[Fact]
public void Bounds_Should_Be_Offset_By_Origin()
{
var target = new TextNode(
Matrix.Identity,
null,
new Point(10, 10),
Mock.Of<IFormattedTextImpl>(x => x.Bounds == new Rect(5, 5, 50, 50)));
Assert.Equal(new Rect(15, 15, 50, 50), target.Bounds);
}
}
}
Loading…
Cancel
Save