Browse Source

Added support for opacity masks into Cairo.

pull/553/head
Jeremy Koritzinsky 10 years ago
parent
commit
180e3bf21d
  1. 80
      src/Gtk/Avalonia.Cairo/Media/DrawingContext.cs

80
src/Gtk/Avalonia.Cairo/Media/DrawingContext.cs

@ -15,7 +15,7 @@ namespace Avalonia.Cairo.Media
using Cairo = global::Cairo; using Cairo = global::Cairo;
/// <summary> /// <summary>
/// Draws using Direct2D1. /// Draws using Cairo.
/// </summary> /// </summary>
public class DrawingContext : IDrawingContextImpl, IDisposable public class DrawingContext : IDrawingContextImpl, IDisposable
{ {
@ -24,6 +24,8 @@ namespace Avalonia.Cairo.Media
/// </summary> /// </summary>
private readonly Cairo.Context _context; private readonly Cairo.Context _context;
private readonly Stack<BrushImpl> _maskStack = new Stack<BrushImpl>();
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DrawingContext"/> class. /// Initializes a new instance of the <see cref="DrawingContext"/> class.
/// </summary> /// </summary>
@ -273,46 +275,53 @@ namespace Avalonia.Cairo.Media
private IDisposable SetBrush(IBrush brush, Size destinationSize) 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 solid = brush as SolidColorBrush;
var linearGradientBrush = brush as LinearGradientBrush; var linearGradientBrush = brush as LinearGradientBrush;
var radialGradientBrush = brush as RadialGradientBrush; var radialGradientBrush = brush as RadialGradientBrush;
var imageBrush = brush as ImageBrush; var imageBrush = brush as ImageBrush;
var visualBrush = brush as VisualBrush; var visualBrush = brush as VisualBrush;
BrushImpl impl = null; BrushImpl impl = null;
if (solid != null) if (solid != null)
{ {
impl = new SolidColorBrushImpl(solid, opacityOverride); impl = new SolidColorBrushImpl(solid, opacityOverride);
} }
else if (linearGradientBrush != null) else if (linearGradientBrush != null)
{ {
impl = new LinearGradientBrushImpl(linearGradientBrush, destinationSize); impl = new LinearGradientBrushImpl(linearGradientBrush, destinationSize);
} }
else if (radialGradientBrush != null) else if (radialGradientBrush != null)
{ {
impl = new RadialGradientBrushImpl(radialGradientBrush, destinationSize); impl = new RadialGradientBrushImpl(radialGradientBrush, destinationSize);
} }
else if (imageBrush != null) else if (imageBrush != null)
{ {
impl = new ImageBrushImpl(imageBrush, destinationSize); impl = new ImageBrushImpl(imageBrush, destinationSize);
} }
else if (visualBrush != null) else if (visualBrush != null)
{ {
impl = new VisualBrushImpl(visualBrush, destinationSize); impl = new VisualBrushImpl(visualBrush, destinationSize);
} }
else else
{ {
impl = new SolidColorBrushImpl(null, opacityOverride); impl = new SolidColorBrushImpl(null, opacityOverride);
} }
_context.SetSource(impl.PlatformBrush); return impl;
return Disposable.Create(() =>
{
impl.Dispose();
_context.Restore();
});
} }
private IDisposable SetPen(Pen pen, Size destinationSize) private IDisposable SetPen(Pen pen, Size destinationSize)
@ -352,5 +361,18 @@ namespace Avalonia.Cairo.Media
{ {
_context.Restore(); _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);
}
} }
} }

Loading…
Cancel
Save