Skip to content

Commit 1c90c0e

Browse files
committed
feat(fillrule): Correctly implement FillRule for iOS & macOS
1 parent d0b9213 commit 1c90c0e

File tree

4 files changed

+25
-9
lines changed

4 files changed

+25
-9
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Windows.UI.Xaml.Media;
2+
using CoreAnimation;
3+
using Foundation;
4+
5+
namespace Uno.UI.UI.Xaml.Media
6+
{
7+
internal static class FillRuleExtensions
8+
{
9+
internal static NSString ToCAShapeLayerFillRule(this FillRule fillRule)
10+
{
11+
return fillRule == FillRule.EvenOdd ? CAShapeLayer.FillRuleEvenOdd : CAShapeLayer.FillRuleNonZero;
12+
}
13+
}
14+
}

src/Uno.UI/UI/Xaml/Shapes/Path.iOSmacOS.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@ public partial class Path : Shape
1111

1212
/// <inheritdoc />
1313
protected override Size MeasureOverride(Size availableSize)
14-
=> MeasureAbsoluteShape(availableSize, GetPath());
14+
=> MeasureAbsoluteShape(availableSize, GetPathAndFillRule(out _));
1515

1616
/// <inheritdoc />
1717
protected override Size ArrangeOverride(Size finalSize)
18-
=> ArrangeAbsoluteShape(finalSize, GetPath());
18+
=> ArrangeAbsoluteShape(finalSize, GetPathAndFillRule(out var fillRule), fillRule);
1919

20-
private CGPath GetPath()
20+
private CGPath GetPathAndFillRule(out FillRule fillRule)
2121
{
2222
var streamGeometry = Data?.ToStreamGeometry();
23+
fillRule = streamGeometry?.FillRule ?? FillRule.EvenOdd;
2324
return streamGeometry?.ToCGPath();
2425
}
2526
}

src/Uno.UI/UI/Xaml/Shapes/Shape.iOSmacOS.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Uno.Extensions;
88
using Uno.Logging;
99
using Uno.UI;
10+
using Uno.UI.UI.Xaml.Media;
1011
using static System.Double;
1112

1213
#if __IOS__
@@ -37,7 +38,7 @@ public Shape()
3738

3839

3940
#region Rendering (Native)
40-
private protected void Render(CGPath path)
41+
private protected void Render(CGPath path, FillRule fillRule = FillRule.EvenOdd)
4142
{
4243
// Remove the old layer if any
4344
_shapeLayer?.RemoveFromSuperLayer();
@@ -49,7 +50,7 @@ private protected void Render(CGPath path)
4950
return;
5051
}
5152

52-
_shapeLayer = CreateLayer(path);
53+
_shapeLayer = CreateLayer(path, fillRule);
5354
Layer.AddSublayer(_shapeLayer);
5455
}
5556

@@ -132,9 +133,9 @@ void RemoveSublayers()
132133
}
133134
}
134135

135-
private CAShapeLayer CreateLayer(CGPath path)
136+
private CAShapeLayer CreateLayer(CGPath path, FillRule fillRule)
136137
{
137-
var pathLayer = new CAShapeLayer() { Path = path };
138+
var pathLayer = new CAShapeLayer() { Path = path, FillRule = fillRule.ToCAShapeLayerFillRule()};
138139

139140
SetFillAndStroke(pathLayer);
140141

src/Uno.UI/UI/Xaml/Shapes/Shape.layout.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ private protected Size MeasureAbsoluteShape(Size availableSize, NativePath path)
328328
return size;
329329
}
330330

331-
private protected Size ArrangeAbsoluteShape(Size finalSize, NativePath path)
331+
private protected Size ArrangeAbsoluteShape(Size finalSize, NativePath path, FillRule fillRule = FillRule.EvenOdd)
332332
{
333333
if (path == null)
334334
{
@@ -536,7 +536,7 @@ private protected Size ArrangeAbsoluteShape(Size finalSize, NativePath path)
536536

537537
var renderPath = new CoreGraphics.CGPath(path, renderTransform);
538538

539-
Render(renderPath);
539+
Render(renderPath, fillRule);
540540
#if __IOS__
541541
// If the Shape does not have size defined, and natural size of the geometry is lower than the finalSize,
542542
// then we don't clip the shape!

0 commit comments

Comments
 (0)