diff --git a/src/Gtk/Avalonia.Cairo/Media/DrawingContext.cs b/src/Gtk/Avalonia.Cairo/Media/DrawingContext.cs
index 07b544ad3b..c2f703918d 100644
--- a/src/Gtk/Avalonia.Cairo/Media/DrawingContext.cs
+++ b/src/Gtk/Avalonia.Cairo/Media/DrawingContext.cs
@@ -15,7 +15,7 @@ namespace Avalonia.Cairo.Media
using Cairo = global::Cairo;
///
- /// Draws using Direct2D1.
+ /// Draws using Cairo.
///
public class DrawingContext : IDrawingContextImpl, IDisposable
{
@@ -24,6 +24,8 @@ namespace Avalonia.Cairo.Media
///
private readonly Cairo.Context _context;
+ private readonly Stack _maskStack = new Stack();
+
///
/// Initializes a new instance of the class.
///
@@ -273,46 +275,53 @@ namespace Avalonia.Cairo.Media
private IDisposable SetBrush(IBrush brush, Size destinationSize)
{
- _context.Save ();
+ _context.Save();
+
+ BrushImpl impl = CreateBrushImpl(brush, destinationSize);
+ _context.SetSource(impl.PlatformBrush);
+ return Disposable.Create(() =>
+ {
+ impl.Dispose();
+ _context.Restore();
+ });
+ }
+
+ private BrushImpl CreateBrushImpl(IBrush brush, Size destinationSize)
+ {
var solid = brush as SolidColorBrush;
var linearGradientBrush = brush as LinearGradientBrush;
var radialGradientBrush = brush as RadialGradientBrush;
var imageBrush = brush as ImageBrush;
var visualBrush = brush as VisualBrush;
- BrushImpl impl = null;
+ BrushImpl impl = null;
- if (solid != null)
- {
- impl = new SolidColorBrushImpl(solid, opacityOverride);
- }
- else if (linearGradientBrush != null)
- {
- impl = new LinearGradientBrushImpl(linearGradientBrush, destinationSize);
- }
+ if (solid != null)
+ {
+ impl = new SolidColorBrushImpl(solid, opacityOverride);
+ }
+ else if (linearGradientBrush != null)
+ {
+ impl = new LinearGradientBrushImpl(linearGradientBrush, destinationSize);
+ }
else if (radialGradientBrush != null)
{
impl = new RadialGradientBrushImpl(radialGradientBrush, destinationSize);
}
- else if (imageBrush != null)
- {
- impl = new ImageBrushImpl(imageBrush, destinationSize);
- }
- else if (visualBrush != null)
- {
- impl = new VisualBrushImpl(visualBrush, destinationSize);
- }
- else
- {
- impl = new SolidColorBrushImpl(null, opacityOverride);
- }
+ else if (imageBrush != null)
+ {
+ impl = new ImageBrushImpl(imageBrush, destinationSize);
+ }
+ else if (visualBrush != null)
+ {
+ impl = new VisualBrushImpl(visualBrush, destinationSize);
+ }
+ else
+ {
+ impl = new SolidColorBrushImpl(null, opacityOverride);
+ }
- _context.SetSource(impl.PlatformBrush);
- return Disposable.Create(() =>
- {
- impl.Dispose();
- _context.Restore();
- });
+ return impl;
}
private IDisposable SetPen(Pen pen, Size destinationSize)
@@ -352,5 +361,18 @@ namespace Avalonia.Cairo.Media
{
_context.Restore();
}
+
+ public void PushOpacityMask(IBrush mask, Rect bounds)
+ {
+ _context.PushGroup();
+ var impl = CreateBrushImpl(mask, bounds.Size);
+ _maskStack.Push(impl);
+ }
+
+ public void PopOpacityMask()
+ {
+ _context.PopGroupToSource();
+ _context.Mask(_maskStack.Pop().PlatformBrush);
+ }
}
}