I want to have clipped drawing on my CGContext
but I need it just the other way round, i.e. I want to add several rectangles to my clipping path using CGContextAddRect()
and the clipping should be done in the way that all the rectangles that I have added to my clipping path stay unaffected by any drawing operations. Normally, it's just the other way round, i.e. drawing functions draw to the rectangles that have been added to the clipping path and leave the areas that haven't been added to the clipping path unaffected. So I guess what I need is just a way to reverse the clipping path before calling CGContextClip()
. Back in the QuickDraw days, this could by easily done by using regions and then calling XorRgn()
for every rectangle. But with Quartz it seems to be more complicated. Does anyone have an easy solution for achieving this or do I need to do all these path reversing calculations on my own?
You could add your entire bounds as a rectangle, then add the rectangles you want to exclude from drawing and use CGContextEOClip
.
Example:
- (void)drawRect:(NSRect)dirtyRect
CGContextRef ctx = [[NSGraphicsContext currentContext] graphicsPort];
//Fill the background with gray:
CGContextSetRGBFillColor(ctx, 0.5, 0.5, 0.5, 1);
CGContextFillRect(ctx, NSRectToCGRect(self.bounds));
CGContextAddRect(ctx, NSRectToCGRect(self.bounds));
//Add some rectangles:
CGContextAddRect(ctx, CGRectMake(10, 10, 100, 100));
CGContextAddRect(ctx, CGRectMake(120, 120, 50, 100));
//Clip:
CGContextEOClip(ctx);
//Fill the entire bounds with red:
CGContextSetRGBFillColor(ctx, 1.0, 0.0, 0.0, 1.0);
CGContextFillRect(ctx, NSRectToCGRect(self.bounds));
}
The effect becomes more obvious if you draw an image at the end instead of filling a red rectangle.
One way would be to draw the clipping path to a bitmap context, invert the resulting bitmap, and use it as a mask on the original image by calling CGContextClipToMask()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With