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