Everything you can draw using Cocoa can also be drawn using Quartz. The Cocoa drawing code itself uses Quartz primitives to render content. Cocoa simply adds an object-oriented interface and in some cases does more of the work for you. Cocoa does not provide classes for all Quartz behavior, however. In situations where a feature is not available in Cocoa, you may want to use Quartz directly.
For general information about Quartz features and how to use them, see Quartz 2D Programming Guide.
Using Quartz Features
Graphics Type Conversions
Getting a Quartz Graphics Context
Creating a Cocoa Graphics Context Using Quartz
Modifying the Graphics State
Because Quartz implements some features that Cocoa does not, there may be times when you need to use Quartz function calls from your Cocoa code. Because Cocoa uses Quartz for most drawing operations, mixing the two technologies is not an issue.
Some of the Quartz features that are not supported directly by Cocoa include the following:
Arbitrary patterns (other than images)
In each case, you are free to use Quartz functions to take advantage of these features. Some features can produce data types that you can then incorporate back into a Cocoa object. (For example, you can use an image data source to obtain a Quartz image (CGImageRef), which you can then use to create an NSImage object.) In some cases, however, you may need to perform the entire operation using Quartz functions.
For information on how to use Quartz features, see Quartz 2D Programming Guide.
When going back and forth between Cocoa and Quartz code, some conversion of data types may be necessary. Table 9-1 shows the Cocoa equivalents of some basic Quartz types.
Cocoa type |
Quartz type |
|---|---|
Although in each case the structure layout is the same, you cannot pass the Quartz data type directly to a method expecting the Cocoa type. To convert, you must cast from one type to another, as shown in the following example:
NSRect cocoaRect = *(NSRect*)&myCGRect; |
Table 9-2 lists the Cocoa classes that approximate the behavior of specific Quartz data types. In some cases, the Cocoa class wraps an instance of its Quartz counterpart, but that is not always true. In the case of shadows, Quartz provides no direct data type for managing the shadow parameters; you must set shadows attributes in Quartz using several different functions. In the case of layers, there are no Cocoa equivalents.
Cocoa type |
Quartz type |
|---|---|
|
|
|
|
No equivalent |
Because Cocoa types often wrap equivalent Quartz types, you should look at the Cocoa reference documentation for information about how to get equivalent Quartz objects, if any. In many cases, Cocoa classes do not offer direct access to their Quartz equivalent and you may need to create the Quartz type based on information in the Cocoa object, such as in the following cases:
To create a CGPathRef object from an NSBezierPath object, you must redraw the path using Quartz function calls. Use the elementAtIndex:associatedPoints: method of NSBezierPath to retrieve the path’s point information.
To convert back and forth between CGColorRef and NSColor objects, get the color component values from one object and use those values to create the other object. When creating colors, you may also need to specify the color space for that color. For the most part, Quartz and Cocoa support the same color spaces. If a color uses a custom color space, you can use the available ICC profile data to create the appropriate color space object.
To create an NSImage object from a Quartz image, you need to create the image object indirectly. For information on how to do this, see “Using a Quartz Image to Create an NSImage.”
To create Quartz shadows, you can use the methods of NSShadow to retrieve the color, offset, and blur radius values prior to calling CGContextSetShadow or CGContextSetShadowWithColor.
Before using any Quartz features, you need to obtain a Quartz graphics context (CGContextRef) for drawing. For view-based drawing, you can get the context by sending a graphicsPort message to the current Cocoa graphics context (NSGraphicsContext). This method returns a pointer that you can cast to a CGContextRef data type and use in subsequent Quartz function calls.
In Mac OS X v10.4 and later, if you have an existing Quartz graphics context, you can create a Cocoa graphics context object using the graphicsContextWithGraphicsPort:flipped: class method of NSGraphicsContext. You then use thesetCurrentContext: class method to make that context the current context.
When mixing calls to Quartz and Cocoa, remember that many Cocoa classes maintain a local copy of some graphics attributes normally associated with the Quartz graphics context. When such a class is ready to draw its content, it modifies the graphics state to match its local settings, draws its content, and restores the graphics state to its original settings. If you use Quartz to change an attribute that is maintained locally by a Cocoa class, your changes may not be used.
If you make changes to the graphics state using the NSGraphicsContext class, your changes are immediately conveyed to the Quartz graphics context, and vice versa. If you are not using NSGraphicsContext to set an attribute, you should assume that the attribute is local to the object. For example, the NSBezierPath class prefers local copies of graphics attributes over the default (or global) attributes stored in the current context.
Last updated: 2007-10-31