Question

I have the following drawing code:

[[NSColor redColor] set];
NSRect fillRect = NSMakeRect(bounds.size.width - 20.0f, 0.0f, 20.0f, 20.0f);
NSBezierPath *bezier1 = [NSBezierPath bezierPathWithRoundedRect:fillRect xRadius:10.0f yRadius:10.0f];

[bezier1 fill];

NSRect fill2 = fillRect;
fill2.origin.x += 5;
fill2.origin.y += 5;

fill2.size.width -= 10.0f;
fill2.size.height -= 10.0f;

NSBezierPath *bezier2 = [NSBezierPath bezierPathWithRoundedRect:fill2 xRadius:5.0f yRadius:5.0f];
[[NSColor greenColor] set];

[bezier2 fill];

Which result in this:

Screenshot

How do I reach that the inner green circle is transparent? Replacing the green NSColor with a transparent color doesn't work, logical ;-)

Is there a way to intersect instances of NSBezierPath or solve this with another approach?

Was it helpful?

Solution

I think what you're looking for is a bezier path for a ring, you can do that by creating a single NSBezierPath and setting the winding rule:

[[NSColor redColor] set];
NSRect fillRect = NSMakeRect(bounds.size.width - 20.0f, 0.0f, 20.0f, 20.0f);
NSBezierPath *bezier1 = [NSBezierPath new];
[bezier1 setWindingRule:NSEvenOddWindingRule];   // set the winding rule for filling
[bezier1 appendBezierPathWithRoundedRect:fillRect xRadius:10.0f yRadius:10.0f];

NSRect innerRect = NSInsetRect(fillRect, 5, 5);  // the bounding rect for the hole
[bezier1 appendBezierPathWithRoundedRect:innerRect xRadius:5.0f yRadius:5.0f];

[bezier1 fill];

The NSEvenOddWindingRule rule determines whether to fill a particular point by considering a line from that point to outside the overall path bounds; if that line crosses an even number of paths it is not filled, otherwise it is. So any point in the inner circle will not be filled, while points between the two will be - result a ring.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top