Browse Source

Refactored brushes.

`SolidColorBrush` is now mutable. There are immutable versions of
brushes in the `Avalona.Media.Immutable` namespace and the static
`Brushes.Xxx` properties return these.
scenegraph-after-breakage
Steven Kirk 9 years ago
parent
commit
b20ced7c2b
  1. 1
      src/Avalonia.Themes.Default/Accents/BaseLight.xaml
  2. 11
      src/Avalonia.Visuals/Avalonia.Visuals.csproj
  3. 3
      src/Avalonia.Visuals/Media/Brush.cs
  4. 566
      src/Avalonia.Visuals/Media/Brushes.cs
  5. 16
      src/Avalonia.Visuals/Media/IMutableBrush.cs
  6. 12
      src/Avalonia.Visuals/Media/ImageBush.cs
  7. 58
      src/Avalonia.Visuals/Media/Immutable/ImmutableImageBrush.cs
  8. 59
      src/Avalonia.Visuals/Media/Immutable/ImmutableSolidColorBrush.cs
  9. 77
      src/Avalonia.Visuals/Media/Immutable/ImmutableTileBrush.cs
  10. 58
      src/Avalonia.Visuals/Media/Immutable/ImmutableVisualBrush.cs
  11. 35
      src/Avalonia.Visuals/Media/Mutable/SolidColorBrush.cs
  12. 36
      src/Avalonia.Visuals/Media/SolidColorBrush.cs
  13. 8
      src/Avalonia.Visuals/Media/VisualBrush.cs
  14. 3
      src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
  15. 26
      src/Avalonia.Visuals/Rendering/SceneGraph/BrushDrawOperation.cs
  16. 4
      src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs
  17. 2
      src/Avalonia.Visuals/Rendering/SceneGraph/LineNode.cs
  18. 37
      src/Avalonia.Visuals/Rendering/SceneGraph/Media/SceneImageBrush.cs
  19. 37
      src/Avalonia.Visuals/Rendering/SceneGraph/Media/SceneVisualBrush.cs
  20. 4
      src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs
  21. 12
      src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs
  22. 9
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/Style2.xaml
  23. 20
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs
  24. 76
      tests/Avalonia.RenderTests/Avalonia.Cairo.RenderTests.v3.ncrunchproject
  25. 9
      tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject

1
src/Avalonia.Themes.Default/Accents/BaseLight.xaml

@ -1,6 +1,5 @@
<Style xmlns="https://github.com/avaloniaui" <Style xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mut="https://github.com/avaloniaui/mutable"
xmlns:sys="clr-namespace:System;assembly=mscorlib"> xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Style.Resources> <Style.Resources>
<SolidColorBrush x:Key="ThemeBackgroundBrush">#FFFFFFFF</SolidColorBrush> <SolidColorBrush x:Key="ThemeBackgroundBrush">#FFFFFFFF</SolidColorBrush>

11
src/Avalonia.Visuals/Avalonia.Visuals.csproj

@ -70,6 +70,9 @@
<Compile Include="Media\Color.cs" /> <Compile Include="Media\Color.cs" />
<Compile Include="Media\Colors.cs" /> <Compile Include="Media\Colors.cs" />
<Compile Include="Media\IImageBrush.cs" /> <Compile Include="Media\IImageBrush.cs" />
<Compile Include="Media\Immutable\ImmutableTileBrush.cs" />
<Compile Include="Media\Immutable\ImmutableSolidColorBrush.cs" />
<Compile Include="Media\IMutableBrush.cs" />
<Compile Include="Media\ITileBrush.cs" /> <Compile Include="Media\ITileBrush.cs" />
<Compile Include="Media\IVisualBrush.cs" /> <Compile Include="Media\IVisualBrush.cs" />
<Compile Include="Media\TextWrapping.cs" /> <Compile Include="Media\TextWrapping.cs" />
@ -84,7 +87,6 @@
<Compile Include="Media\ISolidColorBrush.cs" /> <Compile Include="Media\ISolidColorBrush.cs" />
<Compile Include="Media\LineGeometry.cs" /> <Compile Include="Media\LineGeometry.cs" />
<Compile Include="Media\LineSegment.cs" /> <Compile Include="Media\LineSegment.cs" />
<Compile Include="Media\Mutable\SolidColorBrush.cs" />
<Compile Include="Media\PathGeometryCollections.cs" /> <Compile Include="Media\PathGeometryCollections.cs" />
<Compile Include="Media\PathFigure.cs" /> <Compile Include="Media\PathFigure.cs" />
<Compile Include="Media\PathGeometry.cs" /> <Compile Include="Media\PathGeometry.cs" />
@ -134,8 +136,8 @@
<Compile Include="Rendering\SceneGraph\ISceneBuilder.cs" /> <Compile Include="Rendering\SceneGraph\ISceneBuilder.cs" />
<Compile Include="Rendering\SceneGraph\IVisualNode.cs" /> <Compile Include="Rendering\SceneGraph\IVisualNode.cs" />
<Compile Include="Rendering\SceneGraph\LineNode.cs" /> <Compile Include="Rendering\SceneGraph\LineNode.cs" />
<Compile Include="Rendering\SceneGraph\Media\SceneVisualBrush.cs" /> <Compile Include="Media\Immutable\ImmutableVisualBrush.cs" />
<Compile Include="Rendering\SceneGraph\Media\SceneImageBrush.cs" /> <Compile Include="Media\Immutable\ImmutableImageBrush.cs" />
<Compile Include="Rendering\SceneGraph\RectangleNode.cs" /> <Compile Include="Rendering\SceneGraph\RectangleNode.cs" />
<Compile Include="Rendering\SceneGraph\Scene.cs" /> <Compile Include="Rendering\SceneGraph\Scene.cs" />
<Compile Include="Rendering\SceneGraph\SceneBuilder.cs" /> <Compile Include="Rendering\SceneGraph\SceneBuilder.cs" />
@ -211,6 +213,9 @@
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Rendering\SceneGraph\Media\" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

3
src/Avalonia.Visuals/Media/Brush.cs

@ -46,7 +46,8 @@ namespace Avalonia.Media
if (member != null) if (member != null)
{ {
return (IBrush)member.GetValue(null); var brush = (ISolidColorBrush)member.GetValue(null);
return new SolidColorBrush(brush.Color, brush.Opacity);
} }
else else
{ {

566
src/Avalonia.Visuals/Media/Brushes.cs

File diff suppressed because it is too large

16
src/Avalonia.Visuals/Media/IMutableBrush.cs

@ -0,0 +1,16 @@
using System;
namespace Avalonia.Media
{
/// <summary>
/// Represents a mutable brush which can return an immutable clone of itself.
/// </summary>
public interface IMutableBrush : IBrush
{
/// <summary>
/// Creates an immutable clone of the brush.
/// </summary>
/// <returns>The immutable clone.</returns>
IBrush ToImmutable();
}
}

12
src/Avalonia.Visuals/Media/ImageBush.cs

@ -8,7 +8,7 @@ namespace Avalonia.Media
/// <summary> /// <summary>
/// Paints an area with an <see cref="IBitmap"/>. /// Paints an area with an <see cref="IBitmap"/>.
/// </summary> /// </summary>
public class ImageBrush : TileBrush, IImageBrush public class ImageBrush : TileBrush, IImageBrush, IMutableBrush
{ {
/// <summary> /// <summary>
/// Defines the <see cref="Visual"/> property. /// Defines the <see cref="Visual"/> property.
@ -17,14 +17,14 @@ namespace Avalonia.Media
AvaloniaProperty.Register<ImageBrush, IBitmap>("Source"); AvaloniaProperty.Register<ImageBrush, IBitmap>("Source");
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="VisualBrush"/> class. /// Initializes a new instance of the <see cref="ImageBrush"/> class.
/// </summary> /// </summary>
public ImageBrush() public ImageBrush()
{ {
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="VisualBrush"/> class. /// Initializes a new instance of the <see cref="ImageBrush"/> class.
/// </summary> /// </summary>
/// <param name="source">The image to draw.</param> /// <param name="source">The image to draw.</param>
public ImageBrush(IBitmap source) public ImageBrush(IBitmap source)
@ -40,5 +40,11 @@ namespace Avalonia.Media
get { return GetValue(SourceProperty); } get { return GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); } set { SetValue(SourceProperty, value); }
} }
/// <inheritdoc/>
IBrush IMutableBrush.ToImmutable()
{
return new Immutable.ImmutableImageBrush(this);
}
} }
} }

58
src/Avalonia.Visuals/Media/Immutable/ImmutableImageBrush.cs

@ -0,0 +1,58 @@
using System;
using Avalonia.Media.Imaging;
namespace Avalonia.Media.Immutable
{
/// <summary>
/// Paints an area with an <see cref="IBitmap"/>.
/// </summary>
internal class ImmutableImageBrush : ImmutableTileBrush, IImageBrush
{
/// <summary>
/// Initializes a new instance of the <see cref="ImmutableImageBrush"/> class.
/// </summary>
/// <param name="source">The image to draw.</param>
/// <param name="alignmentX">The horizontal alignment of a tile in the destination.</param>
/// <param name="alignmentY">The vertical alignment of a tile in the destination.</param>
/// <param name="destinationRect">The rectangle on the destination in which to paint a tile.</param>
/// <param name="opacity">The opacity of the brush.</param>
/// <param name="sourceRect">The rectangle of the source image that will be displayed.</param>
/// <param name="stretch">
/// How the source rectangle will be stretched to fill the destination rect.
/// </param>
/// <param name="tileMode">The tile mode.</param>
public ImmutableImageBrush(
IBitmap source,
AlignmentX alignmentX = AlignmentX.Center,
AlignmentY alignmentY = AlignmentY.Center,
RelativeRect? destinationRect = null,
double opacity = 1,
RelativeRect? sourceRect = null,
Stretch stretch = Stretch.Uniform,
TileMode tileMode = TileMode.None)
: base(
alignmentX,
alignmentY,
destinationRect ?? RelativeRect.Fill,
opacity,
sourceRect ?? RelativeRect.Fill,
stretch,
tileMode)
{
Source = source;
}
/// <summary>
/// Initializes a new instance of the <see cref="ImmutableImageBrush"/> class.
/// </summary>
/// <param name="source">The brush from which this brush's properties should be copied.</param>
public ImmutableImageBrush(IImageBrush source)
: base(source)
{
Source = source.Source;
}
/// <inheritdoc/>
public IBitmap Source { get; }
}
}

59
src/Avalonia.Visuals/Media/Immutable/ImmutableSolidColorBrush.cs

@ -0,0 +1,59 @@
// 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.
namespace Avalonia.Media.Immutable
{
/// <summary>
/// Fills an area with a solid color.
/// </summary>
public struct ImmutableSolidColorBrush : ISolidColorBrush
{
/// <summary>
/// Initializes a new instance of the <see cref="ImmutableSolidColorBrush"/> class.
/// </summary>
/// <param name="color">The color to use.</param>
/// <param name="opacity">The opacity of the brush.</param>
public ImmutableSolidColorBrush(Color color, double opacity = 1)
{
Color = color;
Opacity = opacity;
}
/// <summary>
/// Initializes a new instance of the <see cref="ImmutableSolidColorBrush"/> class.
/// </summary>
/// <param name="color">The color to use.</param>
public ImmutableSolidColorBrush(uint color)
: this(Color.FromUInt32(color))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ImmutableSolidColorBrush"/> class.
/// </summary>
/// <param name="source">The brush from which this brush's properties should be copied.</param>
public ImmutableSolidColorBrush(ISolidColorBrush source)
: this(source.Color, source.Opacity)
{
}
/// <summary>
/// Gets the color of the brush.
/// </summary>
public Color Color { get; }
/// <summary>
/// Gets the opacity of the brush.
/// </summary>
public double Opacity { get; }
/// <summary>
/// Returns a string representation of the brush.
/// </summary>
/// <returns>A string representation of the brush.</returns>
public override string ToString()
{
return Color.ToString();
}
}
}

77
src/Avalonia.Visuals/Media/Immutable/ImmutableTileBrush.cs

@ -0,0 +1,77 @@
using System;
namespace Avalonia.Media.Immutable
{
/// <summary>
/// A brush which displays a repeating image.
/// </summary>
public abstract class ImmutableTileBrush : ITileBrush
{
/// <summary>
/// Initializes a new instance of the <see cref="ImageBrush"/> class.
/// </summary>
/// <param name="alignmentX">The horizontal alignment of a tile in the destination.</param>
/// <param name="alignmentY">The vertical alignment of a tile in the destination.</param>
/// <param name="destinationRect">The rectangle on the destination in which to paint a tile.</param>
/// <param name="opacity">The opacity of the brush.</param>
/// <param name="sourceRect">The rectangle of the source image that will be displayed.</param>
/// <param name="stretch">
/// How the source rectangle will be stretched to fill the destination rect.
/// </param>
/// <param name="tileMode">The tile mode.</param>
protected ImmutableTileBrush(
AlignmentX alignmentX,
AlignmentY alignmentY,
RelativeRect destinationRect,
double opacity,
RelativeRect sourceRect,
Stretch stretch,
TileMode tileMode)
{
AlignmentX = alignmentX;
AlignmentY = alignmentY;
DestinationRect = destinationRect;
Opacity = opacity;
SourceRect = sourceRect;
Stretch = stretch;
TileMode = tileMode;
}
/// <summary>
/// Initializes a new instance of the <see cref="ImageBrush"/> class.
/// </summary>
/// <param name="source">The brush from which this brush's properties should be copied.</param>
protected ImmutableTileBrush(ITileBrush source)
: this(
source.AlignmentX,
source.AlignmentY,
source.DestinationRect,
source.Opacity,
source.SourceRect,
source.Stretch,
source.TileMode)
{
}
/// <inheritdoc/>
public AlignmentX AlignmentX { get; }
/// <inheritdoc/>
public AlignmentY AlignmentY { get; }
/// <inheritdoc/>
public RelativeRect DestinationRect { get; }
/// <inheritdoc/>
public double Opacity { get; }
/// <inheritdoc/>
public RelativeRect SourceRect { get; }
/// <inheritdoc/>
public Stretch Stretch { get; }
/// <inheritdoc/>
public TileMode TileMode { get; }
}
}

58
src/Avalonia.Visuals/Media/Immutable/ImmutableVisualBrush.cs

@ -0,0 +1,58 @@
using System;
using Avalonia.VisualTree;
namespace Avalonia.Media.Immutable
{
/// <summary>
/// Paints an area with an <see cref="IVisual"/>.
/// </summary>
internal class ImmutableVisualBrush : ImmutableTileBrush, IVisualBrush
{
/// <summary>
/// Initializes a new instance of the <see cref="ImmutableImageBrush"/> class.
/// </summary>
/// <param name="visual">The visual to draw.</param>
/// <param name="alignmentX">The horizontal alignment of a tile in the destination.</param>
/// <param name="alignmentY">The vertical alignment of a tile in the destination.</param>
/// <param name="destinationRect">The rectangle on the destination in which to paint a tile.</param>
/// <param name="opacity">The opacity of the brush.</param>
/// <param name="sourceRect">The rectangle of the source image that will be displayed.</param>
/// <param name="stretch">
/// How the source rectangle will be stretched to fill the destination rect.
/// </param>
/// <param name="tileMode">The tile mode.</param>
public ImmutableVisualBrush(
IVisual visual,
AlignmentX alignmentX = AlignmentX.Center,
AlignmentY alignmentY = AlignmentY.Center,
RelativeRect? destinationRect = null,
double opacity = 1,
RelativeRect? sourceRect = null,
Stretch stretch = Stretch.Uniform,
TileMode tileMode = TileMode.None)
: base(
alignmentX,
alignmentY,
destinationRect ?? RelativeRect.Fill,
opacity,
sourceRect ?? RelativeRect.Fill,
stretch,
tileMode)
{
Visual = visual;
}
/// <summary>
/// Initializes a new instance of the <see cref="ImmutableVisualBrush"/> class.
/// </summary>
/// <param name="source">The brush from which this brush's properties should be copied.</param>
public ImmutableVisualBrush(IVisualBrush source)
: base(source)
{
Visual = source.Visual;
}
/// <inheritdoc/>
public IVisual Visual { get; }
}
}

35
src/Avalonia.Visuals/Media/Mutable/SolidColorBrush.cs

@ -1,35 +0,0 @@
// 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.
namespace Avalonia.Media.Mutable
{
/// <summary>
/// Fills an area with a solid color.
/// </summary>
/// <remarks>
/// This is a mutable version of the normal immutable <see cref="Avalonia.Media.SolidColorBrush"/>
/// for use in XAML. XAML really needs support for immutable data...
/// </remarks>
public class SolidColorBrush : Brush, ISolidColorBrush
{
public static readonly DirectProperty<SolidColorBrush, Color> ColorProperty =
AvaloniaProperty.RegisterDirect<SolidColorBrush, Color>(
"Color",
o => o.Color,
(o, v) => o.Color = v);
/// <summary>
/// Gets the color of the brush.
/// </summary>
public Color Color { get; set; }
/// <summary>
/// Returns a string representation of the brush.
/// </summary>
/// <returns>A string representation of the brush.</returns>
public override string ToString()
{
return Color.ToString();
}
}
}

36
src/Avalonia.Visuals/Media/SolidColorBrush.cs

@ -1,13 +1,28 @@
// 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;
namespace Avalonia.Media namespace Avalonia.Media
{ {
/// <summary> /// <summary>
/// Fills an area with a solid color. /// Fills an area with a solid color.
/// </summary> /// </summary>
public class SolidColorBrush : ISolidColorBrush public class SolidColorBrush : Brush, ISolidColorBrush, IMutableBrush
{ {
/// <summary>
/// Defines the <see cref="Color"/> property.
/// </summary>
public static readonly StyledProperty<Color> ColorProperty =
AvaloniaProperty.Register<SolidColorBrush, Color>(nameof(Color));
/// <summary>
/// Initializes a new instance of the <see cref="SolidColorBrush"/> class.
/// </summary>
public SolidColorBrush()
{
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SolidColorBrush"/> class. /// Initializes a new instance of the <see cref="SolidColorBrush"/> class.
/// </summary> /// </summary>
@ -29,14 +44,13 @@ namespace Avalonia.Media
} }
/// <summary> /// <summary>
/// Gets the color of the brush. /// Gets or sets the color of the brush.
/// </summary> /// </summary>
public Color Color { get; } public Color Color
{
/// <summary> get { return GetValue(ColorProperty); }
/// Gets the opacity of the brush. set { SetValue(ColorProperty, value); }
/// </summary> }
public double Opacity { get; }
/// <summary> /// <summary>
/// Returns a string representation of the brush. /// Returns a string representation of the brush.
@ -46,5 +60,11 @@ namespace Avalonia.Media
{ {
return Color.ToString(); return Color.ToString();
} }
/// <inheritdoc/>
IBrush IMutableBrush.ToImmutable()
{
return new Immutable.ImmutableSolidColorBrush(this);
}
} }
} }

8
src/Avalonia.Visuals/Media/VisualBrush.cs

@ -8,7 +8,7 @@ namespace Avalonia.Media
/// <summary> /// <summary>
/// Paints an area with an <see cref="IVisual"/>. /// Paints an area with an <see cref="IVisual"/>.
/// </summary> /// </summary>
public class VisualBrush : TileBrush, IVisualBrush public class VisualBrush : TileBrush, IVisualBrush, IMutableBrush
{ {
/// <summary> /// <summary>
/// Defines the <see cref="Visual"/> property. /// Defines the <see cref="Visual"/> property.
@ -40,5 +40,11 @@ namespace Avalonia.Media
get { return GetValue(VisualProperty); } get { return GetValue(VisualProperty); }
set { SetValue(VisualProperty, value); } set { SetValue(VisualProperty, value); }
} }
/// <inheritdoc/>
IBrush IMutableBrush.ToImmutable()
{
return new Immutable.ImmutableVisualBrush(this);
}
} }
} }

3
src/Avalonia.Visuals/Rendering/DeferredRenderer.cs

@ -10,6 +10,7 @@ using Avalonia.Threading;
using Avalonia.VisualTree; using Avalonia.VisualTree;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Avalonia.Media.Immutable;
namespace Avalonia.Rendering namespace Avalonia.Rendering
{ {
@ -239,7 +240,7 @@ namespace Avalonia.Rendering
{ {
foreach (var r in _dirtyRectsDisplay) foreach (var r in _dirtyRectsDisplay)
{ {
var brush = new SolidColorBrush(Colors.Magenta, r.Opacity); var brush = new ImmutableSolidColorBrush(Colors.Magenta, r.Opacity);
context.FillRectangle(brush, r.Rect); context.FillRectangle(brush, r.Rect);
} }
} }

26
src/Avalonia.Visuals/Rendering/SceneGraph/BrushDrawOperation.cs

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Rendering.SceneGraph.Media; using Avalonia.Media.Immutable;
using Avalonia.VisualTree; using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph namespace Avalonia.Rendering.SceneGraph
@ -14,32 +14,18 @@ namespace Avalonia.Rendering.SceneGraph
public abstract void Render(IDrawingContextImpl context); public abstract void Render(IDrawingContextImpl context);
protected IBrush Convert(IBrush brush) protected IBrush ToImmutable(IBrush brush)
{ {
var imageBrush = brush as ImageBrush; return (brush as IMutableBrush)?.ToImmutable() ?? brush;
var visualBrush = brush as VisualBrush;
if (imageBrush != null)
{
return new SceneImageBrush(imageBrush);
}
else if (visualBrush != null)
{
return new SceneVisualBrush(visualBrush);
}
else
{
return brush;
}
} }
protected Pen Convert(Pen pen) protected Pen ToImmutable(Pen pen)
{ {
var brush = pen?.Brush != null ? Convert(pen.Brush) : null; var brush = pen?.Brush != null ? ToImmutable(pen.Brush) : null;
return ReferenceEquals(pen?.Brush, brush) ? return ReferenceEquals(pen?.Brush, brush) ?
pen : pen :
new Pen( new Pen(
pen.Brush, brush,
thickness: pen.Thickness, thickness: pen.Thickness,
dashStyle: pen.DashStyle, dashStyle: pen.DashStyle,
dashCap: pen.DashCap, dashCap: pen.DashCap,

4
src/Avalonia.Visuals/Rendering/SceneGraph/GeometryNode.cs

@ -20,8 +20,8 @@ namespace Avalonia.Rendering.SceneGraph
{ {
Bounds = geometry.GetRenderBounds(pen.Thickness).TransformToAABB(transform); Bounds = geometry.GetRenderBounds(pen.Thickness).TransformToAABB(transform);
Transform = transform; Transform = transform;
Brush = Convert(brush); Brush = ToImmutable(brush);
Pen = Convert(pen); Pen = ToImmutable(pen);
Geometry = geometry; Geometry = geometry;
ChildScenes = childScenes; ChildScenes = childScenes;
} }

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

@ -14,7 +14,7 @@ namespace Avalonia.Rendering.SceneGraph
{ {
Bounds = new Rect(P1, P2); Bounds = new Rect(P1, P2);
Transform = transform; Transform = transform;
Pen = Convert(pen); Pen = ToImmutable(pen);
P1 = p1; P1 = p1;
P2 = p2; P2 = p2;
} }

37
src/Avalonia.Visuals/Rendering/SceneGraph/Media/SceneImageBrush.cs

@ -1,37 +0,0 @@
using System;
using Avalonia.Media;
using Avalonia.Media.Imaging;
namespace Avalonia.Rendering.SceneGraph.Media
{
internal class SceneImageBrush : IImageBrush
{
public SceneImageBrush(IImageBrush source)
{
AlignmentX = source.AlignmentX;
AlignmentY = source.AlignmentY;
DestinationRect = source.DestinationRect;
Opacity = source.Opacity;
Source = source.Source;
SourceRect = source.SourceRect;
Stretch = source.Stretch;
TileMode = source.TileMode;
}
public AlignmentX AlignmentX { get; }
public AlignmentY AlignmentY { get; }
public RelativeRect DestinationRect { get; }
public double Opacity { get; }
public IBitmap Source { get; }
public RelativeRect SourceRect { get; }
public Stretch Stretch { get; }
public TileMode TileMode { get; }
}
}

37
src/Avalonia.Visuals/Rendering/SceneGraph/Media/SceneVisualBrush.cs

@ -1,37 +0,0 @@
using System;
using Avalonia.Media;
using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph.Media
{
internal class SceneVisualBrush : IVisualBrush
{
public SceneVisualBrush(IVisualBrush source)
{
AlignmentX = source.AlignmentX;
AlignmentY = source.AlignmentY;
DestinationRect = source.DestinationRect;
Opacity = source.Opacity;
SourceRect = source.SourceRect;
Stretch = source.Stretch;
TileMode = source.TileMode;
Visual = source.Visual;
}
public AlignmentX AlignmentX { get; }
public AlignmentY AlignmentY { get; }
public RelativeRect DestinationRect { get; }
public double Opacity { get; }
public RelativeRect SourceRect { get; }
public Stretch Stretch { get; }
public TileMode TileMode { get; }
public IVisual Visual { get; }
}
}

4
src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs

@ -20,8 +20,8 @@ namespace Avalonia.Rendering.SceneGraph
{ {
Bounds = rect.TransformToAABB(transform).Inflate(pen?.Thickness ?? 0); Bounds = rect.TransformToAABB(transform).Inflate(pen?.Thickness ?? 0);
Transform = transform; Transform = transform;
Brush = Convert(brush); Brush = ToImmutable(brush);
Pen = Convert(pen); Pen = ToImmutable(pen);
Rect = rect; Rect = rect;
CornerRadius = cornerRadius; CornerRadius = cornerRadius;
ChildScenes = childScenes; ChildScenes = childScenes;

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

@ -9,25 +9,25 @@ using Avalonia.VisualTree;
namespace Avalonia.Rendering.SceneGraph namespace Avalonia.Rendering.SceneGraph
{ {
internal class TextNode : IDrawOperation internal class TextNode : BrushDrawOperation
{ {
public TextNode(Matrix transform, IBrush foreground, Point origin, IFormattedTextImpl text) public TextNode(Matrix transform, IBrush foreground, Point origin, IFormattedTextImpl text)
{ {
Bounds = new Rect(origin, text.Size).TransformToAABB(transform); Bounds = new Rect(origin, text.Size).TransformToAABB(transform);
Transform = transform; Transform = transform;
Foreground = foreground; Foreground = ToImmutable(foreground);
Origin = origin; Origin = origin;
Text = text; Text = text;
} }
public Rect Bounds { get; } public override Rect Bounds { get; }
public Matrix Transform { get; } public Matrix Transform { get; }
public IBrush Foreground { get; } public IBrush Foreground { get; }
public Point Origin { get; } public Point Origin { get; }
public IFormattedTextImpl Text { get; } public IFormattedTextImpl Text { get; }
public IDictionary<VisualBrush, Scene> ChildScenes => null; public override IDictionary<IVisual, Scene> ChildScenes => null;
public void Render(IDrawingContextImpl context) public override void Render(IDrawingContextImpl context)
{ {
context.Transform = Transform; context.Transform = Transform;
context.DrawText(Foreground, Origin, Text); context.DrawText(Foreground, Origin, Text);
@ -41,6 +41,6 @@ namespace Avalonia.Rendering.SceneGraph
Equals(text, Text); Equals(text, Text);
} }
public bool HitTest(Point p) => Bounds.Contains(p); public override bool HitTest(Point p) => Bounds.Contains(p);
} }
} }

9
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/Style2.xaml

@ -1,9 +1,8 @@
<Style xmlns="https://github.com/avaloniaui" <Style xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:mut="https://github.com/avaloniaui/mutable">
<Style.Resources> <Style.Resources>
<mut:SolidColorBrush x:Key="RedBrush" Color="{StyleResource Red}"/> <SolidColorBrush x:Key="RedBrush" Color="{StyleResource Red}"/>
<mut:SolidColorBrush x:Key="GreenBrush" Color="{StyleResource Green}"/> <SolidColorBrush x:Key="GreenBrush" Color="{StyleResource Green}"/>
<mut:SolidColorBrush x:Key="BlueBrush" Color="{StyleResource Blue}"/> <SolidColorBrush x:Key="BlueBrush" Color="{StyleResource Blue}"/>
</Style.Resources> </Style.Resources>
</Style> </Style>

20
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs

@ -124,13 +124,12 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
{ {
var xaml = @" var xaml = @"
<Window xmlns='https://github.com/avaloniaui' <Window xmlns='https://github.com/avaloniaui'
xmlns:mut='https://github.com/avaloniaui/mutable'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'> xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Window.Styles> <Window.Styles>
<Style> <Style>
<Style.Resources> <Style.Resources>
<Color x:Key='color'>#ff506070</Color> <Color x:Key='color'>#ff506070</Color>
<mut:SolidColorBrush x:Key='brush' Color='{StyleResource color}'/> <SolidColorBrush x:Key='brush' Color='{StyleResource color}'/>
</Style.Resources> </Style.Resources>
</Style> </Style>
</Window.Styles> </Window.Styles>
@ -139,12 +138,12 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
var loader = new AvaloniaXamlLoader(); var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml); var window = (Window)loader.Load(xaml);
var brush = (Avalonia.Media.Mutable.SolidColorBrush)window.FindStyleResource("brush"); var brush = (Avalonia.Media.ISolidColorBrush)window.FindStyleResource("brush");
var button = window.FindControl<Button>("button"); var button = window.FindControl<Button>("button");
DelayedBinding.ApplyBindings(button); DelayedBinding.ApplyBindings(button);
var buttonBrush = (Avalonia.Media.Mutable.SolidColorBrush)button.Background; var buttonBrush = (Avalonia.Media.ISolidColorBrush)button.Background;
Assert.Equal(0xff506070, brush.Color.ToUint32()); Assert.Equal(0xff506070, brush.Color.ToUint32());
Assert.Equal(0xff506070, buttonBrush.Color.ToUint32()); Assert.Equal(0xff506070, buttonBrush.Color.ToUint32());
@ -156,19 +155,18 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
{ {
var xaml = @" var xaml = @"
<Styles xmlns='https://github.com/avaloniaui' <Styles xmlns='https://github.com/avaloniaui'
xmlns:mut='https://github.com/avaloniaui/mutable'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'> xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Style> <Style>
<Style.Resources> <Style.Resources>
<Color x:Key='color'>#ff506070</Color> <Color x:Key='color'>#ff506070</Color>
<mut:SolidColorBrush x:Key='brush' Color='{StyleResource color}'/> <SolidColorBrush x:Key='brush' Color='{StyleResource color}'/>
</Style.Resources> </Style.Resources>
</Style> </Style>
</Styles>"; </Styles>";
var loader = new AvaloniaXamlLoader(); var loader = new AvaloniaXamlLoader();
var styles = (Styles)loader.Load(xaml); var styles = (Styles)loader.Load(xaml);
var brush = (Avalonia.Media.Mutable.SolidColorBrush)styles.FindResource("brush"); var brush = (Avalonia.Media.ISolidColorBrush)styles.FindResource("brush");
Assert.Equal(0xff506070, brush.Color.ToUint32()); Assert.Equal(0xff506070, brush.Color.ToUint32());
} }
@ -178,7 +176,6 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
{ {
var xaml = @" var xaml = @"
<Styles xmlns='https://github.com/avaloniaui' <Styles xmlns='https://github.com/avaloniaui'
xmlns:mut='https://github.com/avaloniaui/mutable'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'> xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Style> <Style>
<Style.Resources> <Style.Resources>
@ -187,14 +184,14 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
</Style> </Style>
<Style> <Style>
<Style.Resources> <Style.Resources>
<mut:SolidColorBrush x:Key='brush' Color='{StyleResource color}'/> <SolidColorBrush x:Key='brush' Color='{StyleResource color}'/>
</Style.Resources> </Style.Resources>
</Style> </Style>
</Styles>"; </Styles>";
var loader = new AvaloniaXamlLoader(); var loader = new AvaloniaXamlLoader();
var styles = (Styles)loader.Load(xaml); var styles = (Styles)loader.Load(xaml);
var brush = (Avalonia.Media.Mutable.SolidColorBrush)styles.FindResource("brush"); var brush = (Avalonia.Media.ISolidColorBrush)styles.FindResource("brush");
Assert.Equal(0xff506070, brush.Color.ToUint32()); Assert.Equal(0xff506070, brush.Color.ToUint32());
} }
@ -206,7 +203,6 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
{ {
var xaml = @" var xaml = @"
<Window xmlns='https://github.com/avaloniaui' <Window xmlns='https://github.com/avaloniaui'
xmlns:mut='https://github.com/avaloniaui/mutable'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'> xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Window.Styles> <Window.Styles>
<StyleInclude Source='resm:Avalonia.Markup.Xaml.UnitTests.Xaml.Style1.xaml?assembly=Avalonia.Markup.Xaml.UnitTests'/> <StyleInclude Source='resm:Avalonia.Markup.Xaml.UnitTests.Xaml.Style1.xaml?assembly=Avalonia.Markup.Xaml.UnitTests'/>
@ -218,7 +214,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
var loader = new AvaloniaXamlLoader(); var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml); var window = (Window)loader.Load(xaml);
var border = window.FindControl<Border>("border"); var border = window.FindControl<Border>("border");
var borderBrush = (Avalonia.Media.Mutable.SolidColorBrush)border.Background; var borderBrush = (Avalonia.Media.ISolidColorBrush)border.Background;
Assert.NotNull(borderBrush); Assert.NotNull(borderBrush);
Assert.Equal(0xffff0000, borderBrush.Color.ToUint32()); Assert.Equal(0xffff0000, borderBrush.Color.ToUint32());

76
tests/Avalonia.RenderTests/Avalonia.Cairo.RenderTests.v3.ncrunchproject

@ -0,0 +1,76 @@
<ProjectConfiguration>
<Settings>
<HiddenComponentWarnings>
<Value>AbnormalReferenceResolution</Value>
</HiddenComponentWarnings>
<IgnoredTests>
<FixtureTestSelector>
<FixtureName>Avalonia.Cairo.RenderTests.Controls.BorderTests</FixtureName>
</FixtureTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.ImageBrushTests.ImageBrush_Fill_NoTile</TestName>
</NamedTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_FlipXY_TopLeftDest</TestName>
</NamedTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_NoTile_Alignment_BottomRight</TestName>
</NamedTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_NoTile_Alignment_Center</TestName>
</NamedTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_NoTile_BottomRightQuarterDest</TestName>
</NamedTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_NoTile_BottomRightQuarterSource</TestName>
</NamedTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest</TestName>
</NamedTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest</TestName>
</NamedTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.ImageBrushTests.ImageBrush_Uniform_NoTile</TestName>
</NamedTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.ImageBrushTests.ImageBrush_UniformToFill_NoTile</TestName>
</NamedTestSelector>
<FixtureTestSelector>
<FixtureName>Avalonia.Cairo.RenderTests.Controls.ImageTests</FixtureName>
</FixtureTestSelector>
<FixtureTestSelector>
<FixtureName>Avalonia.Cairo.RenderTests.GeometryClippingTests</FixtureName>
</FixtureTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.LinearGradientBrushTests.LinearGradientBrush_RedBlue_Vertical_Fill</TestName>
</NamedTestSelector>
<FixtureTestSelector>
<FixtureName>Avalonia.Cairo.RenderTests.Media.VisualBrushTests</FixtureName>
</FixtureTestSelector>
<FixtureTestSelector>
<FixtureName>Avalonia.Cairo.RenderTests.OpacityMaskTests</FixtureName>
</FixtureTestSelector>
<FixtureTestSelector>
<FixtureName>Avalonia.Cairo.RenderTests.Shapes.EllipseTests</FixtureName>
</FixtureTestSelector>
<FixtureTestSelector>
<FixtureName>Avalonia.Cairo.RenderTests.Shapes.LineTests</FixtureName>
</FixtureTestSelector>
<FixtureTestSelector>
<FixtureName>Avalonia.Cairo.RenderTests.Shapes.PathTests</FixtureName>
</FixtureTestSelector>
<FixtureTestSelector>
<FixtureName>Avalonia.Cairo.RenderTests.Shapes.RectangleTests</FixtureName>
</FixtureTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.ImageBrushTests.ImageBrush_NoStretch_NoTile_Alignment_TopLeft</TestName>
</NamedTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Cairo.RenderTests.Media.LinearGradientBrushTests.LinearGradientBrush_RedBlue_Horizontal_Fill</TestName>
</NamedTestSelector>
</IgnoredTests>
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
</Settings>
</ProjectConfiguration>

9
tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject

@ -2,9 +2,9 @@
<Settings> <Settings>
<DefaultTestTimeout>1000</DefaultTestTimeout> <DefaultTestTimeout>1000</DefaultTestTimeout>
<IgnoredTests> <IgnoredTests>
<FixtureTestSelector> <NamedTestSelector>
<FixtureName>Avalonia.Direct2D1.RenderTests.Media.LinearGradientBrushTests</FixtureName> <TestName>Avalonia.Direct2D1.RenderTests.Media.LinearGradientBrushTests.LinearGradientBrush_RedBlue_Vertical_Fill</TestName>
</FixtureTestSelector> </NamedTestSelector>
<FixtureTestSelector> <FixtureTestSelector>
<FixtureName>Avalonia.Direct2D1.RenderTests.Controls.BorderTests</FixtureName> <FixtureName>Avalonia.Direct2D1.RenderTests.Controls.BorderTests</FixtureName>
</FixtureTestSelector> </FixtureTestSelector>
@ -38,6 +38,9 @@
<FixtureTestSelector> <FixtureTestSelector>
<FixtureName>Avalonia.Direct2D1.RenderTests.Shapes.RectangleTests</FixtureName> <FixtureName>Avalonia.Direct2D1.RenderTests.Shapes.RectangleTests</FixtureName>
</FixtureTestSelector> </FixtureTestSelector>
<NamedTestSelector>
<TestName>Avalonia.Direct2D1.RenderTests.Media.LinearGradientBrushTests.LinearGradientBrush_RedBlue_Horizontal_Fill</TestName>
</NamedTestSelector>
</IgnoredTests> </IgnoredTests>
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully> <PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
</Settings> </Settings>

Loading…
Cancel
Save