There are five steps you need to perform to paint a stencil pattern:
These are actually the same steps you use to paint a colored pattern. The difference between the two is how you set up color information. Each of the subsequent sections explains how to implement each step. You can see how all the steps fit together in “A Complete Stencil Pattern Painting Function.”
The callback you write for drawing a stencil pattern follows the same form as that described for a colored pattern cell. See “Write a Callback Function That Draws a Colored Pattern Cell.” The only difference is that your drawing callback does not specify any color. The pattern cell shown in Figure 6-10 does not get its color from the drawing callback. The color is set outside the drawing color in the pattern color space.
Take a look at the code in Listing 6-6, which draws the pattern cell shown in Figure 6-10. Notice that the code simply creates a path and fills the path. The code does not set color.
Listing 6-6 A drawing callback that draws a stencil pattern cell
#define PSIZE 16 // size of the pattern cell |
static void MyDrawStencilStar (void *info, CGContextRef myContext) |
{ |
int k; |
double r, theta; |
r = 0.8 * PSIZE / 2; |
theta = 2 * M_PI * (2.0 / 5.0); // 144 degrees |
CGContextTranslateCTM (myContext, PSIZE/2, PSIZE/2); |
CGContextMoveToPoint(myContext, 0, r); |
for (k = 1; k < 5; k++) { |
CGContextAddLineToPoint (myContext, |
r * sin(k * theta), |
r * cos(k * theta)); |
} |
CGContextClosePath(myContext); |
CGContextFillPath(myContext); |
} |
Stencil patterns require that you set up a pattern color space for Quartz to paint with, as shown in Listing 6-7. A detailed explanation for each numbered line of code follows the listing.
Listing 6-7 Code that creates a pattern color space for a stencil pattern
CGPatternRef pattern; |
CGColorSpaceRef baseSpace; |
CGColorSpaceRef patternSpace; |
baseSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);// 1 |
patternSpace = CGColorSpaceCreatePattern (baseSpace);// 2 |
CGContextSetFillColorSpace (myContext, patternSpace);// 3 |
CGColorSpaceRelease(patternSpace);// 4 |
CGColorSpaceRelease(baseSpace);// 5 |
Here’s what the code does:
In Mac OS X v10.4, this function creates a generic RGB space. Generic color spaces leave color matching to the system. For more information, see “Creating Generic Color Spaces.”
Creates a pattern color space. The color space you supply specifies how colors are represented for the pattern. Later, when you set colors for the pattern, you must set them using the pattern color space. For this example, you will need to specify color using RGB values.
Sets the color space to use when filling a pattern. You can set a stroke color space by calling the function CGContextSetStrokeColorSpace.
Releases the base color space object.
Releases the pattern color space object.
You specify information about the anatomy of a pattern the way you would for a colored pattern—by calling the function CGPatternCreate. The only difference is that you pass false for the isColored parameter. See “Set Up the Anatomy of the Colored Pattern” for more information on the parameters you supply to the CGPatternCreate function.
You can use your pattern for filling or stroking by calling the appropriate function, CGContextSetFillPattern or CGContextSetStrokePattern. Quartz uses your pattern for any subsequent filling or stroking.
These functions each take three parameters:
The graphics context
The CGPattern object that you created previously
An array of color components
A stencil pattern does not supply a color in the drawing callback, so you must pass a color to the fill or stroke functions to inform Quartz what color to us. Listing 6-8 shows an example of how to set color for a stencil pattern. The values in the color array will be interpreted by Quartz in the color space you set up earlier. Because this example uses device RGB, the color array contains values for red, green, and blue components. The fourth value specifies the opacity of the color.
Listing 6-8 Code that sets opacity for a colored pattern
static const float color[4] = { 0, 1, 1, 0.5 }; //cyan, 50% transparent |
CGContextSetFillPattern (myContext, myPattern, color); |
After you’ve completed the previous steps, you can call any Quartz 2D function that paints. Your pattern is used as the “paint.” For example, you can call CGContextStrokePath, CGContextFillPath, CGContextFillRect, or any other function that paints.
The code in Listing 6-9 contains a function that paints a stencil pattern. The function incorporates all the steps discussed previously. A detailed explanation for each numbered line of code follows the listing.
Listing 6-9 A function that paints a stencil pattern
#define PSIZE 16 |
void MyStencilPatternPainting (CGContextRef myContext, |
const Rect *windowRect) |
{ |
CGPatternRef pattern; |
CGColorSpaceRef baseSpace; |
CGColorSpaceRef patternSpace; |
static const float color[4] = { 0, 1, 0, 1 };// 1 |
static const CGPatternCallbacks callbacks = {0, &drawStar, NULL};// 2 |
baseSpace = CGColorSpaceCreateDeviceRGB ();// 3 |
patternSpace = CGColorSpaceCreatePattern (baseSpace);// 4 |
CGContextSetFillColorSpace (myContext, patternSpace);// 5 |
CGColorSpaceRelease (patternSpace); |
CGColorSpaceRelease (baseSpace); |
pattern = CGPatternCreate(NULL, CGRectMake(0, 0, PSIZE, PSIZE),// 6 |
CGAffineTransformIdentity, PSIZE, PSIZE, |
kCGPatternTilingConstantSpacing, |
false, &callbacks); |
CGContextSetFillPattern (myContext, pattern, color);// 7 |
CGPatternRelease (pattern);// 8 |
CGContextFillRect (myContext,CGRectMake (0,0,PSIZE*20,PSIZE*20));// 9 |
} |
Here’s what the code does:
Declares an array to hold a color value and sets the value (which will be in RGB color space) to opaque green.
Declares and fills a callbacks structure, passing 0 as the version and a pointer to a drawing callback function. This example does not provide a release info callback, so that field is set to NULL.
Creates an RGB device color space. If the pattern is drawn to a display, you need to supply this type of color space.
Creates a pattern color space object from the RGB device color space.
Sets the fill color space to the pattern color space object you just created.
Creates a pattern object. Note that the second to last parameter—the isColored parameter—is false. Stencil patterns do not supply color, so you must pass false for this parameter. All other parameters are similar to those passed for the colored pattern example. See “A Complete Colored Pattern Painting Function.”
Sets the fill pattern, passing the color array declared previously.
Releases the CGPattern object.
Fills a rectangle. Quartz fills the rectangle using the pattern you just set up.
Last updated: 2007-12-11