diff --git a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs
index a1fee1a2e3..afb024b4cb 100644
--- a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs
+++ b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs
@@ -148,6 +148,10 @@ namespace Perspex.Cairo.Media
_context.AppendPath(impl.Path);
using (var b = SetBrush(brush, geometry.Bounds.Size))
{
+ _context.FillRule = impl.FillRule == FillRule.EvenOdd
+ ? Cairo.FillRule.EvenOdd
+ : Cairo.FillRule.Winding;
+
if (pen != null)
_context.FillPreserve();
else
diff --git a/src/Gtk/Perspex.Cairo/Media/StreamGeometryContextImpl.cs b/src/Gtk/Perspex.Cairo/Media/StreamGeometryContextImpl.cs
index 2c5cce2653..f4cf9294dc 100644
--- a/src/Gtk/Perspex.Cairo/Media/StreamGeometryContextImpl.cs
+++ b/src/Gtk/Perspex.Cairo/Media/StreamGeometryContextImpl.cs
@@ -13,11 +13,13 @@ namespace Perspex.Cairo.Media
public class StreamGeometryContextImpl : IStreamGeometryContextImpl
{
+ private readonly StreamGeometryImpl _target;
private Point _currentPoint;
- public StreamGeometryContextImpl(Cairo.Path path = null)
+ public StreamGeometryContextImpl(StreamGeometryImpl target, Cairo.Path path)
{
+ _target = target;
- _surf = new Cairo.ImageSurface (Cairo.Format.Argb32, 0, 0);
+ _surf = new Cairo.ImageSurface (Cairo.Format.Argb32, 0, 0);
_context = new Cairo.Context (_surf);
this.Path = path;
@@ -86,6 +88,12 @@ namespace Perspex.Cairo.Media
}
}
+ public void SetFillRule(FillRule fillRule)
+ {
+ _target.FillRule = fillRule;
+ }
+
+
public void Dispose()
{
_context.Dispose ();
diff --git a/src/Gtk/Perspex.Cairo/Media/StreamGeometryImpl.cs b/src/Gtk/Perspex.Cairo/Media/StreamGeometryImpl.cs
index a408cba039..2dd844c687 100644
--- a/src/Gtk/Perspex.Cairo/Media/StreamGeometryImpl.cs
+++ b/src/Gtk/Perspex.Cairo/Media/StreamGeometryImpl.cs
@@ -14,7 +14,7 @@ namespace Perspex.Cairo.Media
{
public StreamGeometryImpl()
{
- _impl = new StreamGeometryContextImpl(null);
+ _impl = new StreamGeometryContextImpl(this, null);
}
public StreamGeometryImpl(StreamGeometryContextImpl impl)
@@ -50,6 +50,8 @@ namespace Perspex.Cairo.Media
}
}
+ public FillRule FillRule { get; set; }
+
public IStreamGeometryImpl Clone()
{
return new StreamGeometryImpl(_impl);
diff --git a/src/Perspex.SceneGraph/Media/FillRule.cs b/src/Perspex.SceneGraph/Media/FillRule.cs
new file mode 100644
index 0000000000..5e2eb078c9
--- /dev/null
+++ b/src/Perspex.SceneGraph/Media/FillRule.cs
@@ -0,0 +1,8 @@
+namespace Perspex.Media
+{
+ public enum FillRule
+ {
+ EvenOdd,
+ NonZero
+ }
+}
\ No newline at end of file
diff --git a/src/Perspex.SceneGraph/Media/StreamGeometryContext.cs b/src/Perspex.SceneGraph/Media/StreamGeometryContext.cs
index dcb000544f..8e32debb21 100644
--- a/src/Perspex.SceneGraph/Media/StreamGeometryContext.cs
+++ b/src/Perspex.SceneGraph/Media/StreamGeometryContext.cs
@@ -28,6 +28,16 @@ namespace Perspex.Media
_impl = impl;
}
+ ///
+ /// Sets path's winding rule (default is EvenOdd). You should call this method before any calls to BeginFigure. If you wonder why, ask Direct2D guys about their design decisions.
+ ///
+ ///
+
+ public void SetFillRule(FillRule fillRule)
+ {
+ _impl.SetFillRule(fillRule);
+ }
+
///
/// Draws an arc to the specified point.
///
diff --git a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj
index f3079729e3..05f22c4ccf 100644
--- a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj
+++ b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj
@@ -67,6 +67,7 @@
+
diff --git a/src/Perspex.SceneGraph/Platform/IStreamGeometryContextImpl.cs b/src/Perspex.SceneGraph/Platform/IStreamGeometryContextImpl.cs
index 182a3ec174..33c2285730 100644
--- a/src/Perspex.SceneGraph/Platform/IStreamGeometryContextImpl.cs
+++ b/src/Perspex.SceneGraph/Platform/IStreamGeometryContextImpl.cs
@@ -56,5 +56,7 @@ namespace Perspex.Platform
///
/// Whether the figure is closed.
void EndFigure(bool isClosed);
+
+ void SetFillRule(FillRule fillRule);
}
}
diff --git a/src/Skia/Perspex.Skia/DrawingContextImpl.cs b/src/Skia/Perspex.Skia/DrawingContextImpl.cs
index fee6499f01..405f021515 100644
--- a/src/Skia/Perspex.Skia/DrawingContextImpl.cs
+++ b/src/Skia/Perspex.Skia/DrawingContextImpl.cs
@@ -46,7 +46,7 @@ namespace Perspex.Skia
using (var stroke = pen?.Brush != null ? CreateBrush(pen, size) : null)
{
MethodTable.Instance.DrawGeometry(Handle, impl.Path.Handle, fill != null ? fill.Brush : null,
- stroke != null ? stroke.Brush : null);
+ stroke != null ? stroke.Brush : null, impl.FillRule == FillRule.EvenOdd);
}
Transform = oldTransform;
}
diff --git a/src/Skia/Perspex.Skia/MethodTable.cs b/src/Skia/Perspex.Skia/MethodTable.cs
index cee36bbded..ba21588333 100644
--- a/src/Skia/Perspex.Skia/MethodTable.cs
+++ b/src/Skia/Perspex.Skia/MethodTable.cs
@@ -67,7 +67,7 @@ namespace Perspex.Skia
public _DisposePath DisposePath;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate void _DrawGeometry(IntPtr ctx, IntPtr path, void* fill, void* stroke);
+ public delegate void _DrawGeometry(IntPtr ctx, IntPtr path, void* fill, void* stroke, bool useEvenOdd);
public _DrawGeometry DrawGeometry;
diff --git a/src/Skia/Perspex.Skia/StreamGeometryImpl.cs b/src/Skia/Perspex.Skia/StreamGeometryImpl.cs
index d18a3c55c5..3c62e65e7d 100644
--- a/src/Skia/Perspex.Skia/StreamGeometryImpl.cs
+++ b/src/Skia/Perspex.Skia/StreamGeometryImpl.cs
@@ -140,6 +140,13 @@ namespace Perspex.Skia
Flag = isClosed
});
}
+
+ public void SetFillRule(FillRule fillRule)
+ {
+ _geometryImpl.FillRule = fillRule;
+ }
}
+
+ public FillRule FillRule { get; set; }
}
}
diff --git a/src/Skia/native.url b/src/Skia/native.url
index 697513ae7a..737e1d3d06 100644
--- a/src/Skia/native.url
+++ b/src/Skia/native.url
@@ -1 +1 @@
-https://dl.dropboxusercontent.com/u/18301199/Perspex.Skia/abi-0002.zip
+https://dl.dropboxusercontent.com/u/18301199/Perspex.Skia/abi-0003.zip
diff --git a/src/Windows/Perspex.Direct2D1/Media/StreamGeometryContextImpl.cs b/src/Windows/Perspex.Direct2D1/Media/StreamGeometryContextImpl.cs
index e18e61f94a..8dc3c6231d 100644
--- a/src/Windows/Perspex.Direct2D1/Media/StreamGeometryContextImpl.cs
+++ b/src/Windows/Perspex.Direct2D1/Media/StreamGeometryContextImpl.cs
@@ -1,8 +1,10 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
+using Perspex.Media;
using Perspex.Platform;
using SharpDX.Direct2D1;
+using SweepDirection = SharpDX.Direct2D1.SweepDirection;
namespace Perspex.Direct2D1.Media
{
@@ -66,6 +68,11 @@ namespace Perspex.Direct2D1.Media
_sink.EndFigure(isClosed ? FigureEnd.Closed : FigureEnd.Open);
}
+ public void SetFillRule(FillRule fillRule)
+ {
+ _sink.SetFillMode(fillRule == FillRule.EvenOdd ? FillMode.Alternate : FillMode.Winding);
+ }
+
public void Dispose()
{
_sink.Close();