diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/ClipNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/ClipNode.cs new file mode 100644 index 0000000000..cea2c9e633 --- /dev/null +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/ClipNode.cs @@ -0,0 +1,64 @@ +using System; +using Avalonia.Platform; + +namespace Avalonia.Rendering.SceneGraph +{ + /// + /// A node in the scene graph which represents a clip push or pop. + /// + internal class ClipNode : IDrawOperation + { + /// + /// Initializes a new instance of the class that represents an + /// clip push. + /// + /// The clip to push. + public ClipNode(Rect clip) + { + Clip = clip; + } + + /// + /// Initializes a new instance of the class that represents an + /// opacity pop. + /// + public ClipNode() + { + } + + /// + public Rect Bounds => Rect.Empty; + + /// + /// Gets the opacity to be pushed or null if the operation represents a pop. + /// + public Rect? Clip { get; } + + /// + public bool HitTest(Point p) => false; + + /// + /// Determines if this draw operation equals another. + /// + /// The clip of the other draw operation. + /// True if the draw operations are the same, otherwise false. + /// + /// The properties of the other draw operation are passed in as arguments to prevent + /// allocation of a not-yet-constructed draw operation object. + /// + public bool Equals(Rect? clip) => Clip == clip; + + /// + public void Render(IDrawingContextImpl context) + { + if (Clip.HasValue) + { + context.PushClip(Clip.Value); + } + else + { + context.PopClip(); + } + } + } +} diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs index 5659bda1d9..2dfd26bca5 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs @@ -196,7 +196,16 @@ namespace Avalonia.Rendering.SceneGraph /// public void PopClip() { - // TODO: Implement + var next = NextDrawAs(); + + if (next == null || !next.Equals(null)) + { + Add(new ClipNode()); + } + else + { + ++_drawOperationindex; + } } /// @@ -229,7 +238,16 @@ namespace Avalonia.Rendering.SceneGraph /// public void PushClip(Rect clip) { - // TODO: Implement + var next = NextDrawAs(); + + if (next == null || !next.Equals(clip)) + { + Add(new ClipNode(clip)); + } + else + { + ++_drawOperationindex; + } } /// diff --git a/tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs b/tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs index 995b285df1..2f311f4800 100644 --- a/tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs +++ b/tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs @@ -35,14 +35,14 @@ namespace Avalonia.Direct2D1.RenderTests.Controls { context.FillRectangle( Brushes.Red, - control.Bounds, + new Rect(control.Bounds.Size), 4); - using (context.PushClip(control.Bounds.Deflate(20))) + using (context.PushClip(new Rect(control.Bounds.Size).Deflate(20))) { context.FillRectangle( Brushes.Blue, - control.Bounds, + new Rect(control.Bounds.Size), 4); } }), @@ -64,14 +64,14 @@ namespace Avalonia.Direct2D1.RenderTests.Controls { context.FillRectangle( Brushes.Red, - control.Bounds, + new Rect(control.Bounds.Size), 4); using (context.PushOpacity(0.5)) { context.FillRectangle( Brushes.Blue, - control.Bounds.Deflate(20), + new Rect(control.Bounds.Size).Deflate(20), 4); } }), diff --git a/tests/TestFiles/Cairo/Controls/CustomRender/Clip.expected.png b/tests/TestFiles/Cairo/Controls/CustomRender/Clip.expected.png index 3347370368..c64045d17e 100644 Binary files a/tests/TestFiles/Cairo/Controls/CustomRender/Clip.expected.png and b/tests/TestFiles/Cairo/Controls/CustomRender/Clip.expected.png differ diff --git a/tests/TestFiles/Cairo/Controls/CustomRender/Opacity.expected.png b/tests/TestFiles/Cairo/Controls/CustomRender/Opacity.expected.png index 159f428344..66d12819f4 100644 Binary files a/tests/TestFiles/Cairo/Controls/CustomRender/Opacity.expected.png and b/tests/TestFiles/Cairo/Controls/CustomRender/Opacity.expected.png differ diff --git a/tests/TestFiles/Direct2D1/Controls/CustomRender/Clip.expected.png b/tests/TestFiles/Direct2D1/Controls/CustomRender/Clip.expected.png index 3347370368..c64045d17e 100644 Binary files a/tests/TestFiles/Direct2D1/Controls/CustomRender/Clip.expected.png and b/tests/TestFiles/Direct2D1/Controls/CustomRender/Clip.expected.png differ diff --git a/tests/TestFiles/Direct2D1/Controls/CustomRender/Opacity.expected.png b/tests/TestFiles/Direct2D1/Controls/CustomRender/Opacity.expected.png index 399d502a56..66d12819f4 100644 Binary files a/tests/TestFiles/Direct2D1/Controls/CustomRender/Opacity.expected.png and b/tests/TestFiles/Direct2D1/Controls/CustomRender/Opacity.expected.png differ diff --git a/tests/TestFiles/Skia/Controls/CustomRender/Clip.expected.png b/tests/TestFiles/Skia/Controls/CustomRender/Clip.expected.png index 3347370368..c64045d17e 100644 Binary files a/tests/TestFiles/Skia/Controls/CustomRender/Clip.expected.png and b/tests/TestFiles/Skia/Controls/CustomRender/Clip.expected.png differ diff --git a/tests/TestFiles/Skia/Controls/CustomRender/Opacity.expected.png b/tests/TestFiles/Skia/Controls/CustomRender/Opacity.expected.png index 399d502a56..66d12819f4 100644 Binary files a/tests/TestFiles/Skia/Controls/CustomRender/Opacity.expected.png and b/tests/TestFiles/Skia/Controls/CustomRender/Opacity.expected.png differ