Browse Source

Pass correct node bounds to PushOpacityMask. (#1870)

* Pass correct node bounds.

Use node bounds not clip bounds for opacity mask rect.

Fixes #1118.

* Use layout bounds for opacity mask.

And added a new render test to make sure that the render transform is applied to it.

* Fix bad XAML formatting.
pull/1886/head
Steven Kirk 8 years ago
committed by Nelson Carrillo
parent
commit
d15e86c2a7
  1. 3
      samples/ControlCatalog/Pages/CanvasPage.xaml
  2. 11
      src/Avalonia.Visuals/Rendering/SceneGraph/IVisualNode.cs
  3. 4
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
  4. 5
      src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs
  5. 37
      tests/Avalonia.RenderTests/OpacityMaskTests.cs
  6. BIN
      tests/TestFiles/Direct2D1/OpacityMask/RenderTansform_Applies_To_Opacity_Mask.expected.png
  7. BIN
      tests/TestFiles/Skia/OpacityMask/RenderTansform_Applies_To_Opacity_Mask.expected.png

3
samples/ControlCatalog/Pages/CanvasPage.xaml

@ -11,7 +11,8 @@
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.OpacityMask> </Rectangle>
</Rectangle.OpacityMask>
</Rectangle>
<Ellipse Fill="Green" Width="58" Height="58" Canvas.Left="88" Canvas.Top="100"/>
<Path Fill="Orange" Data="M 0,0 c 0,0 50,0 50,-50 c 0,0 50,0 50,50 h -50 v 50 l -50,-50 Z" Canvas.Left="30" Canvas.Top="250"/>
<Path Fill="OrangeRed" Canvas.Left="180" Canvas.Top="250">

11
src/Avalonia.Visuals/Rendering/SceneGraph/IVisualNode.cs

@ -30,19 +30,20 @@ namespace Avalonia.Rendering.SceneGraph
Matrix Transform { get; }
/// <summary>
/// Gets the bounds for the node's geometry in global coordinates.
/// Gets the bounds of the node's geometry in global coordinates.
/// </summary>
Rect Bounds { get; }
/// <summary>
/// Gets the clip bounds for the node in global coordinates.
/// </summary>
/// <remarks>
/// This clip does not take into account parent clips, to find the absolute clip bounds
/// it is necessary to traverse the tree.
/// </remarks>
Rect ClipBounds { get; }
/// <summary>
/// Gets the layout bounds for the node in global coordinates.
/// </summary>
Rect LayoutBounds { get; }
/// <summary>
/// Whether the node is clipped to <see cref="ClipBounds"/>.
/// </summary>

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

@ -167,8 +167,9 @@ namespace Avalonia.Rendering.SceneGraph
using (context.PushPostTransform(m))
using (context.PushTransformContainer())
{
var globalBounds = bounds.TransformToAABB(contextImpl.Transform);
var clipBounds = clipToBounds ?
bounds.TransformToAABB(contextImpl.Transform).Intersect(clip) :
globalBounds.Intersect(clip) :
clip;
forceRecurse = forceRecurse ||
@ -179,6 +180,7 @@ namespace Avalonia.Rendering.SceneGraph
node.Transform = contextImpl.Transform;
node.ClipBounds = clipBounds;
node.ClipToBounds = clipToBounds;
node.LayoutBounds = globalBounds;
node.GeometryClip = visual.Clip?.PlatformImpl;
node.Opacity = opacity;

5
src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs

@ -58,6 +58,9 @@ namespace Avalonia.Rendering.SceneGraph
/// <inheritdoc/>
public Rect ClipBounds { get; set; }
/// <inheritdoc/>
public Rect LayoutBounds { get; set; }
/// <inheritdoc/>
public bool ClipToBounds { get; set; }
@ -266,7 +269,7 @@ namespace Avalonia.Rendering.SceneGraph
if (OpacityMask != null)
{
context.PushOpacityMask(OpacityMask, ClipBounds);
context.PushOpacityMask(OpacityMask, LayoutBounds);
}
}

37
tests/Avalonia.RenderTests/OpacityMaskTests.cs

@ -55,5 +55,42 @@ namespace Avalonia.Direct2D1.RenderTests
await RenderToFile(target);
CompareImages();
}
[Fact]
public async Task RenderTansform_Applies_To_Opacity_Mask()
{
var target = new Canvas
{
OpacityMask = new LinearGradientBrush
{
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative),
GradientStops = new List<GradientStop>
{
new GradientStop(Color.FromUInt32(0xffffffff), 0),
new GradientStop(Color.FromUInt32(0x00ffffff), 1)
}
},
RenderTransform = new RotateTransform(90),
Width = 76,
Height = 76,
Children =
{
new Path
{
Width = 32,
Height = 40,
[Canvas.LeftProperty] = 23,
[Canvas.TopProperty] = 18,
Stretch = Stretch.Fill,
Fill = Brushes.Red,
Data = StreamGeometry.Parse("F1 M 27,18L 23,26L 33,30L 24,38L 33,46L 23,50L 27,58L 45,58L 55,38L 45,18L 27,18 Z")
}
}
};
await RenderToFile(target);
CompareImages();
}
}
}

BIN
tests/TestFiles/Direct2D1/OpacityMask/RenderTansform_Applies_To_Opacity_Mask.expected.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
tests/TestFiles/Skia/OpacityMask/RenderTansform_Applies_To_Opacity_Mask.expected.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

Loading…
Cancel
Save