diff --git a/src/Avalonia.Base/Media/DrawingContext.cs b/src/Avalonia.Base/Media/DrawingContext.cs
index 02294368c5..c55d6de10f 100644
--- a/src/Avalonia.Base/Media/DrawingContext.cs
+++ b/src/Avalonia.Base/Media/DrawingContext.cs
@@ -360,16 +360,15 @@ namespace Avalonia.Media
/// Pushes an opacity value.
///
/// The opacity.
- /// The bounds.
/// A disposable used to undo the opacity.
- public PushedState PushOpacity(double opacity, Rect bounds)
+ public PushedState PushOpacity(double opacity)
{
- PushOpacityCore(opacity, bounds);
+ PushOpacityCore(opacity);
_states ??= StateStackPool.Get();
_states.Push(new RestoreState(this, RestoreState.PushedStateType.Opacity));
return new PushedState(this);
}
- protected abstract void PushOpacityCore(double opacity, Rect bounds);
+ protected abstract void PushOpacityCore(double opacity);
///
/// Pushes an opacity mask.
diff --git a/src/Avalonia.Base/Media/DrawingGroup.cs b/src/Avalonia.Base/Media/DrawingGroup.cs
index f72bcd554c..1f3c74c51c 100644
--- a/src/Avalonia.Base/Media/DrawingGroup.cs
+++ b/src/Avalonia.Base/Media/DrawingGroup.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using Avalonia.Media.Imaging;
using Avalonia.Metadata;
using Avalonia.Platform;
using Avalonia.Rendering.SceneGraph;
@@ -72,9 +71,8 @@ namespace Avalonia.Media
internal override void DrawCore(DrawingContext context)
{
var bounds = GetBounds();
-
using (context.PushTransform(Transform?.Value ?? Matrix.Identity))
- using (context.PushOpacity(Opacity, bounds))
+ using (context.PushOpacity(Opacity))
using (ClipGeometry != null ? context.PushGeometryClip(ClipGeometry) : default)
using (OpacityMask != null ? context.PushOpacityMask(OpacityMask, bounds) : default)
{
@@ -178,22 +176,30 @@ namespace Avalonia.Media
protected override void PushClipCore(Rect rect)
{
- throw new NotImplementedException();
+ var drawingGroup = PushNewDrawingGroup();
+
+ drawingGroup.ClipGeometry = new RectangleGeometry(rect);
}
protected override void PushGeometryClipCore(Geometry clip)
{
- throw new NotImplementedException();
+ var drawingGroup = PushNewDrawingGroup();
+
+ drawingGroup.ClipGeometry = clip;
}
- protected override void PushOpacityCore(double opacity, Rect bounds)
+ protected override void PushOpacityCore(double opacity)
{
- throw new NotImplementedException();
+ var drawingGroup = PushNewDrawingGroup();
+
+ drawingGroup.Opacity = opacity;
}
protected override void PushOpacityMaskCore(IBrush mask, Rect bounds)
{
- throw new NotImplementedException();
+ var drawingGroup = PushNewDrawingGroup();
+
+ drawingGroup.OpacityMask = mask;
}
internal override void DrawBitmap(IRef source, double opacity, Rect sourceRect, Rect destRect)
diff --git a/src/Avalonia.Base/Media/PlatformDrawingContext.cs b/src/Avalonia.Base/Media/PlatformDrawingContext.cs
index 1c1f202532..b81582f845 100644
--- a/src/Avalonia.Base/Media/PlatformDrawingContext.cs
+++ b/src/Avalonia.Base/Media/PlatformDrawingContext.cs
@@ -76,8 +76,8 @@ internal sealed class PlatformDrawingContext : DrawingContext
protected override void PushGeometryClipCore(Geometry clip) =>
_impl.PushGeometryClip(clip.PlatformImpl ?? throw new ArgumentException());
- protected override void PushOpacityCore(double opacity, Rect bounds) =>
- _impl.PushOpacity(opacity, bounds);
+ protected override void PushOpacityCore(double opacity) =>
+ _impl.PushOpacity(opacity, null);
protected override void PushOpacityMaskCore(IBrush mask, Rect bounds) =>
_impl.PushOpacityMask(mask, bounds);
diff --git a/src/Avalonia.Base/Platform/IDrawingContextImpl.cs b/src/Avalonia.Base/Platform/IDrawingContextImpl.cs
index 8416354bc2..a0cd2a8dcd 100644
--- a/src/Avalonia.Base/Platform/IDrawingContextImpl.cs
+++ b/src/Avalonia.Base/Platform/IDrawingContextImpl.cs
@@ -132,7 +132,7 @@ namespace Avalonia.Platform
///
/// The opacity.
/// where to apply the opacity.
- void PushOpacity(double opacity, Rect bounds);
+ void PushOpacity(double opacity, Rect? bounds);
///
/// Pops the latest pushed opacity value.
diff --git a/src/Avalonia.Base/Rendering/Composition/Drawing/Nodes/RenderDataNodes.cs b/src/Avalonia.Base/Rendering/Composition/Drawing/Nodes/RenderDataNodes.cs
index 3012432e12..2d3b5b0f22 100644
--- a/src/Avalonia.Base/Rendering/Composition/Drawing/Nodes/RenderDataNodes.cs
+++ b/src/Avalonia.Base/Rendering/Composition/Drawing/Nodes/RenderDataNodes.cs
@@ -182,11 +182,10 @@ class RenderDataGeometryClipNode : RenderDataPushNode
class RenderDataOpacityNode : RenderDataPushNode
{
public double Opacity { get; set; }
- public Rect BoundsRect { get; set; }
public override void Push(ref RenderDataNodeRenderContext context)
{
if (Opacity != 1)
- context.Context.PushOpacity(Opacity, BoundsRect);
+ context.Context.PushOpacity(Opacity, null);
}
public override void Pop(ref RenderDataNodeRenderContext context)
@@ -211,4 +210,4 @@ abstract class RenderDataBrushAndPenNode : IRenderDataItemWithServerResources
public abstract void Invoke(ref RenderDataNodeRenderContext context);
public abstract Rect? Bounds { get; }
public abstract bool HitTest(Point p);
-}
\ No newline at end of file
+}
diff --git a/src/Avalonia.Base/Rendering/Composition/Drawing/RenderDataDrawingContext.cs b/src/Avalonia.Base/Rendering/Composition/Drawing/RenderDataDrawingContext.cs
index 3d96dc6bbb..e7b14f138d 100644
--- a/src/Avalonia.Base/Rendering/Composition/Drawing/RenderDataDrawingContext.cs
+++ b/src/Avalonia.Base/Rendering/Composition/Drawing/RenderDataDrawingContext.cs
@@ -222,15 +222,14 @@ internal class RenderDataDrawingContext : DrawingContext
});
}
- protected override void PushOpacityCore(double opacity, Rect bounds)
+ protected override void PushOpacityCore(double opacity)
{
if (opacity == 1)
Push();
else
Push(new RenderDataOpacityNode
{
- Opacity = opacity,
- BoundsRect = bounds
+ Opacity = opacity
});
}
@@ -356,4 +355,4 @@ internal class RenderDataDrawingContext : DrawingContext
if (_resourcesHashSet != null)
s_hashSetPool.ReturnAndSetNull(ref _resourcesHashSet);
}
-}
\ No newline at end of file
+}
diff --git a/src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs b/src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs
index b735b106d8..14dd59b7e3 100644
--- a/src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs
+++ b/src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs
@@ -109,7 +109,7 @@ internal class CompositorDrawingContextProxy : IDrawingContextImpl,
_impl.PopClip();
}
- public void PushOpacity(double opacity, Rect bounds)
+ public void PushOpacity(double opacity, Rect? bounds)
{
_impl.PushOpacity(opacity, bounds);
}
diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs
index 853b90be5e..0eeffda123 100644
--- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs
+++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs
@@ -58,7 +58,7 @@ namespace Avalonia.Rendering.Composition.Server
canvas.PushEffect(Effect);
if (Opacity != 1)
- canvas.PushOpacity(Opacity, boundsRect);
+ canvas.PushOpacity(Opacity, ClipToBounds ? boundsRect : null);
if (ClipToBounds && !HandlesClipToBounds)
canvas.PushClip(Root!.SnapToDevicePixels(boundsRect));
if (Clip != null)
diff --git a/src/Avalonia.Base/Rendering/ImmediateRenderer.cs b/src/Avalonia.Base/Rendering/ImmediateRenderer.cs
index 3462b1008a..37c5e0a2c6 100644
--- a/src/Avalonia.Base/Rendering/ImmediateRenderer.cs
+++ b/src/Avalonia.Base/Rendering/ImmediateRenderer.cs
@@ -96,7 +96,7 @@ namespace Avalonia.Rendering
}
using (context.PushTransform(m))
- using (context.PushOpacity(opacity, bounds))
+ using (context.PushOpacity(opacity))
using (clipToBounds
#pragma warning disable CS0618 // Type or member is obsolete
? visual is IVisualWithRoundRectClip roundClipVisual
diff --git a/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs b/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
index f99bebb5fe..7293874671 100644
--- a/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
+++ b/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
@@ -457,7 +457,7 @@ namespace Avalonia.Headless
}
- public void PushOpacity(double opacity, Rect rect)
+ public void PushOpacity(double opacity, Rect? rect)
{
}
diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
index f74ba179c1..fbff4ab4e7 100644
--- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
+++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
@@ -588,14 +588,21 @@ namespace Avalonia.Skia
}
///
- public void PushOpacity(double opacity, Rect bounds)
+ public void PushOpacity(double opacity, Rect? bounds)
{
CheckLease();
if(_useOpacitySaveLayer)
{
- var rect = bounds.ToSKRect();
- Canvas.SaveLayer(rect, new SKPaint { ColorF = new SKColorF(0, 0, 0, (float)opacity)});
+ if (bounds.HasValue)
+ {
+ var rect = bounds.Value.ToSKRect();
+ Canvas.SaveLayer(rect, new SKPaint { ColorF = new SKColorF(0, 0, 0, (float)opacity) });
+ }
+ else
+ {
+ Canvas.SaveLayer(new SKPaint { ColorF = new SKColorF(0, 0, 0, (float)opacity) });
+ }
}
else
{
diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
index 407fadb9f5..5579278f21 100644
--- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
+++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
@@ -454,17 +454,26 @@ namespace Avalonia.Direct2D1.Media
/// The opacity.
/// The bounds.
/// A disposable used to undo the opacity.
- public void PushOpacity(double opacity, Rect bounds)
+ public void PushOpacity(double opacity, Rect? bounds)
{
if (opacity < 1)
{
+ if(bounds == null || bounds == default(Rect))
+ {
+ bounds = new Rect(0, 0, _renderTarget.PixelSize.Width, _renderTarget.PixelSize.Height);
+ }
+
var parameters = new LayerParameters
{
- ContentBounds = bounds.ToDirect2D(),
MaskTransform = PrimitiveExtensions.Matrix3x2Identity,
- Opacity = (float)opacity,
+ Opacity = (float)opacity
};
+ if(bounds.HasValue)
+ {
+ parameters.ContentBounds = bounds.Value.ToDirect2D();
+ }
+
var layer = _layerPool.Count != 0 ? _layerPool.Pop() : new Layer(_deviceContext);
_deviceContext.PushLayer(ref parameters, layer);
diff --git a/tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs b/tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs
index 7a2c60baf4..ff36877d9a 100644
--- a/tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs
+++ b/tests/Avalonia.RenderTests/Controls/CustomRenderTests.cs
@@ -141,7 +141,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls
new Rect(control.Bounds.Size),
4);
- using (context.PushOpacity(0.5, control.Bounds))
+ using (context.PushOpacity(0.5))
{
context.FillRectangle(
Brushes.Blue,