Mac OS X has a wealth of graphics frameworks. From the PDF-based Quartz to AppKit to the filter-based Core Image, there’s something for everybody. Unfortunately, these frameworks each do things a little differently, which can lead to trouble when getting them to work with each other. There are system-provided ways to convert between some of these different types, but not for others. I put together a few categories with methods to make it easier for these frameworks to all get along.
One of the most common mis-matching issues developers run into is the different geometry types in Quartz and Cocoa. Quartz has
CGSize while Cocoa uses
NSSize. They have all of the same attributes but are still different.
Luckily this situation is much improved in Leopard with a whole host of conversion functions like
NSRectFromCGRect(). Even better, in 64 bit Cocoa all of the
NS* types are
typedef‘ed as their
CG* equivalents! This is a great improvement, and even if you’re not 64 bit only, you can define
NS_BUILD_32_LIKE_64 to still use the 64 bit versions of the
Core Image, though, uses yet another representation of geometric values. The
CIVector class is used for rectangles, points, sizes and even 3D points.
LTConversions includes methods to convert Quartz and Cocoa geometric values to and from their
Color Spaces are used to specify how to interpret the values in a color. Quartz uses
CGColorSpaceRef and Cocoa uses
NSColorSpace is great for converting color spaces-it can convert to and from
CMProfileRef (used by ColorSync) and from ICC profiles (.icc files created with ColorSync Utility). New in Leopard, it can also convert to and from
CGColorSpaceRef. Core Image does not have its own color space object, so in Leopard
NSColorSpace can convert between pretty much any color space format you might need.
For colors, there three very similar flavors.
CIColor are pretty much the same idea, and with
LTConversions you can easily convert between them. Note that it doesn’t handle pattern color conversion since they’re treated a little differently in Quartz and AppKit (and don’t really exist in Core Image).
The situation with paths is a little strange. Quartz’s
CGPathRef actually has (a little) more functionality than AppKit’s
CGPathRef has cubic and quadratic BÃ©zier curves, while
NSBezierPath only has cubic curves. It’s not a major omission, but it seems strange that
NSBezierPath is missing this, making it not quite a perfect mirror of
LTConversions has a method to convert a
NSBezierPath to a
CGPathRef, but not the other way.
There’s also a host of image types.
CIImage don’t share
NSImage‘s concept of representations (which use the
NSImageRep class), but otherwise they are very similar.
LTConversions has methods for converting between these image types, but if you’re doing anything fancy with multiple image representations, you should probably do the conversion yourself.
Leopard is required because of some of the new Color and Image conversions, and everything should work with (or without) Garbage Collection and in 64 bit. Leopard’s Core Animation doesn’t add any of its own new basic types, and generally uses those from Quartz (so using Core Animation together with Cocoa requires a lot of conversions). Of course, on a (purely hypothetical) platform that had Quartz but no AppKit or Core Image, most of these conversions would be unnecessary…