Quartz uses clipping to limit drawing in a graphics context. Quartz functions that clip (CGContextClip, CGContextEOClip) intersect the clip with the current clip, “trimming” the clipping area in a cookie-cutter-like manner. The primary differences between clipping in Quartz and QuickDraw are as follows:
When your application creates a graphics context or obtains a context that’s created elsewhere, the clipping area in the context is already configured for a specific use. The default clipping area in a new graphics context is typically the entire page or window content area.
You cannot directly access the clipping area. Instead, Quartz provides clipping functions that modify the clipping area for you. You can save and later restore the current clipping area, along with the entire graphics state, by using the functions CGContextSaveGState and CGContextRestoreGState.
When you call one of the Quartz clipping functions, the new clipping area is the intersection of the current clipping area with (1) the area inside a filled path or (2) a grayscale image or image mask.
Because of how intersection works, clipping functions can’t extend the clipping area beyond its current bounds.
Quartz Clipping Functions
A Basic Clipping Example
Quartz has these functions available for clipping:
CGContextClip intersects the current clipping area with the filled area of the current path, using the non zero winding rule.
CGContextEOClip intersects the current clipping area with the filled area of the current path, using the even-odd rule. Often, you’ll find that CGContextEOClip is more convenient to use than the function CGContextClip. For QuickDraw-style intersections, even-odd rules match better.
CGContextClipToMask , available starting in Mac OS X v10.4, intersects the clipping area in a graphics context with a mask. The mask can be an image mask or a grayscale image. For more information, see Masking an Image by Clipping the Context in Quartz 2D Programming Guide.
The Quartz 2D Programming Guide describes how clipping works in more detail and discusses the difference between the winding and even-odd rules for determining the inside of a shape.
Tip: If drawing doesn’t show up as you expect, use the function CGContextGetClipBoundingBox for debugging. By looking at the bounding box returned by this function, you can determine whether the coordinates are wrong or whether your drawing is not near what you clipped out.
This example is a continuation of “Drawing the Union and Symmetric Difference of Two Shapes.” Quartz does not provide functions that compute the difference or intersection of two paths, but this example demonstrates how to use clipping to achieve a similar effect. That is, to draw the intersection and difference of two shapes in a single path (see Figure 2-8).
In Figure 2-10, the intersection of two shapes is drawn by clipping with each shape separately and then filling the shapes. For simplicity, this example uses rectangular paths. Typically you would use this approach with more complex paths. Their difference (shape 1 - shape 2) is drawn by clipping with both shapes using the even-odd rule, and then drawing the first shape.
Listing 2-15 shows how to draw the filled areas in black.
Listing 2-15 Code that uses clipping to draw the intersection and difference of two shapes
// intersection |
CGContextSaveGState (ctx);// 1 |
CGContextAddPath (ctx, shape1);// 2 |
CGContextClip (ctx); |
CGContextAddPath (ctx, shape2); |
CGContextClip (ctx); |
CGContextAddPath (ctx, shapes);// 3 |
CGContextFillPath (ctx); |
CGContextRestoreGState (ctx);// 4 |
CGContextTranslateCTM (ctx, width * 3, 0); |
// difference |
CGContextSaveGState (ctx); |
CGContextAddPath (ctx, shapes);// 5 |
CGContextEOClip (ctx); |
CGContextAddPath (ctx, shape1);// 6 |
CGContextFillPath (ctx); |
CGContextRestoreGState (ctx); |
Here’s what the code does:
Saves the graphics state. This is done because step 2 modifies the clipping area, a part of the graphics state.
Intersects the clipping area with each shape individually. This has the effect of removing the area not common to both shapes from the clipping area. As with drawing operations, clipping consumes the current path.
Fills the shapes using the clip defined in the step 2.
Restores the clipping area to its previous state, saved in step 1.
Intersects the clipping area with both shapes using the even-odd rule. This has the effect of removing the area common to both shapes from the clipping area.
Constructs and fills a path consisting of the first shape, using the clip defined in step 5.
Last updated: 2006-09-05