< Previous PageNext Page > Hide TOC

Overview of Quartz 2D

Quartz 2D is a two-dimensional drawing engine accessible from all Mac OS X application environments outside of the kernel. You can use the Quartz 2D application programming interface (API) to gain access to features such as path-based drawing, layer drawing, painting with transparency, shading, drawing shadows, transparency layers, color management, anti-aliased rendering, PDF document generation, and PDF metadata access.

The Mac OS X graphics and imaging architecture is shown in Figure 1-1. Quartz 2D is implemented in the Core Graphics framework, a part of the Application Services umbrella framework. Your program links to ApplicationServices.framework to call Quartz 2D routines directly.

Figure 1-1  Graphics and imaging in Mac OS X

Graphics and imaging in Mac OS X

Quartz 2D can work with all other graphics and imaging technologies–Core Image, Core Video, OpenGL, and QuickTime. It’s possible to create an image in Quartz from a QuickTime graphics importer, using the QuickTime function GraphicsImportCreateCGImage. See QuickTime API Reference for details.

Core Image and Core Video are technologies that are available in Mac OS X v10.4. “Moving Data Between Quartz 2D and Core Image” describes how you can provide images to Core Image, which is a framework that supports image processing.

Notice that QuickDraw is not depicted in Figure 1-1; Quartz 2D replaces QuickDraw. If you still have QuickDraw code in your application, you can read Quartz Programming Guide for QuickDraw Developers for strategies on how to replace your old QuickDraw code in order to take advantage of the sophisticated drawing engine available through Quartz 2D.

Graphics hardware, shown in Figure 1-1 as the foundational layer, is important for high-performance graphics. Whenever possible, Quartz 2D leverages the power of the graphics hardware.

The following sections provide an overview of the key concepts you need to understand about the Quartz 2D drawing environment:

The Page

Quartz 2D uses the painter’s model for its imaging. In the painter’s model, each successive drawing operation applies a layer of “paint” to an output “canvas,” often called a page. The paint on the page can be modified by overlaying more paint through additional drawing operations. An object drawn on the page cannot be modified except by overlaying more paint. This model allows you to construct extremely sophisticated images from a small number of powerful primitives.

Figure 1-2 shows how the painter’s model works. To get the image in the top part of the figure, the shape on the left was drawn first followed by the solid shape. The solid shape overlays the first shape, obscuring all but the perimeter of the first shape. The shapes are drawn in the opposite order in the bottom of the figure, with the solid shape drawn first. As you can see, in the painter’s model the drawing order is important.

Figure 1-2  The painter’s model

The painter’s model

The page may be a real sheet of paper (if the output device is a printer); it may be a virtual sheet of paper (if the output device is a PDF file); it may even be a bitmap image. The exact nature of the page depends on the particular graphics context you use.

Drawing Destinations: The Graphics Context

A graphics context is an opaque data type (CGContextRef) that encapsulates the information Quartz uses to draw images to an output device, such as a PDF file, a bitmap, or a window on a display. The information inside a graphics context includes graphics drawing parameters and a device-specific representation of the paint on the page. All objects in Quartz are drawn to, or contained by, a graphics context.

You can think of a graphics context as a drawing destination, as shown in Figure 1-3. When you draw with Quartz, all device-specific characteristics are contained within the specific type of graphics context you use. In other words, you can draw the same image to a different device simply by providing a different graphics context to the same sequence of Quartz drawing routines. You do not need to perform any device-specific calculations; Quartz does it for you.

Figure 1-3  Quartz drawing destinations

Quartz drawing destinations

These graphics contexts are available to your application:

As of Mac OS X v10.4, Quartz has CGLayer objects, which are drawing layers that are associated with a graphics context. Drawing to a layer destination improves performance for certain types of drawing. For more information, see “CGLayer Drawing.”

Quartz 2D Opaque Data Types

The Quartz 2D API defines a variety of opaque data types in addition to graphics contexts. Because the API is part of the Core Graphics framework, the data types and the routines that operate on them use the CG prefix.

Quartz 2D creates objects from opaque data types that your application operates on to achieve a particular drawing output. Figure 1-4 shows the sorts of results you can achieve when you apply drawing operations to three of the objects provided by Quartz 2D. For example:

Figure 1-4  Opaque data types are the basis of drawing primitives in Quartz 2D

Opaque data types are the basis of drawing primitives in Quartz 2D

The opaque data types available in Quartz 2D include the following:

Graphics States

Quartz modifies the results of drawing operations according to the parameters in the current graphics state. The graphics state contains parameters that would otherwise be taken as arguments to drawing routines. Routines that draw to a graphics context consult the graphics state to determine how to render their results. For example, when you call a function to set the fill color, you are modifying a value stored in the current graphics state. Other commonly used elements of the current graphics state include the line width, the current position, and the text font size.

The graphics context contains a stack of graphics states. When Quartz creates a graphics context, the stack is empty. When you save the graphics state, Quartz pushes a copy of the current graphics state onto the stack. When you restore the graphics state, Quartz pops the graphics state off the top of the stack. The popped state becomes the current graphics state.

The graphics context maintains a stack of graphics states. To save the current graphics state, use the function CGContextSaveGState to push a copy of the current graphics state onto the stack. To restore a previously saved graphics state, use the function CGContextRestoreGState to replace the current graphics state with the graphics state that’s on top of the stack.

Note that not all aspects of the current drawing environment are elements of the graphics state. For example, the current path is not considered part of the graphics state and is therefore not saved when you call the function CGContextSaveGState. The graphics state parameters that are saved when you call this function are listed in Table 1-1.

Table 1-1  Parameters that are associated with the graphics state


Discussed in this chapter

Current transformation matrix (CTM)


Clipping area


Line: width, join, cap, dash, miter limit


Accuracy of curve estimation (flatness)


Anti-aliasing setting

“Graphics Contexts”

Color: fill and stroke settings

“Color and Color Spaces”

Alpha value (transparency)

“Color and Color Spaces”

Rendering intent

“Color and Color Spaces”

Color space: fill and stroke settings

“Color and Color Spaces”

Text: font, font size, character spacing, text drawing mode


Blend mode

“Paths” and “Bitmap Images and Image Masks”

Quartz 2D Coordinates

A coordinate system defines the range of locations used to express the location and sizes of objects to be drawn on the page. You specify the location and size of graphics in the user-space coordinate system, or, more simply, the user space. Coordinates are defined as floating-point values.

Figure 1-5  The Quartz coordinate system

The Quartz coordinate system

Because different devices have different underlying imaging capabilities, the locations and sizes of graphics must be defined in a device-independent manner. For example, a screen display device might be capable of displaying no more than 96 pixels per inch, while a printer might be capable of displaying 300 pixels per inch. If you define the coordinate system at the device level (in this example, either 96 pixels or 300 pixels), objects drawn in that space cannot be reproduced on other devices without visible distortion. They will appear too large or too small.

Quartz accomplishes device independence with a separate coordinate system—user space—mapping it to the coordinate system of the output device—device space—using the current transformation matrix, or CTM. A matrix is a mathematical construct used to efficiently describe a set of related equations. The current transformation matrix is a particular type of matrix called an affine transform, which maps points from one coordinate space to another by applying translation, rotation, and scaling operations (calculations that move, rotate, and resize a coordinate system).

The current transformation matrix has a secondary purpose: It allows you to transform how objects are drawn. For example, to draw a box rotated by 45 degrees, you rotate the coordinate system of the page (the CTM) before you draw the box. Quartz draws to the output device using the rotated coordinate system.

A point in user space is represented by a coordinate pair (x, y), where x represents the location along the horizontal axis (left and right) and y represents the vertical axis (up and down). The origin of the user coordinate space is the point (0,0). By default, the origin is located at the lower-left corner of the page. The x-axis increases as it moves from the left toward the right of the page. The y-axis increases in value as it moves from the bottom toward the top of the page.

Memory Management: Object Ownership

Quartz uses the Core Foundation memory management model, in which objects are reference counted. When created, Core Foundation objects start out with a reference count of 1. You can increment the reference count by calling a function to retain the object, and decrement the reference count by calling a function to release the object. When the reference count is decremented to 0, the object is freed. This allows objects to safely share references to other objects.

There are a few simple rules to keep in mind:

Quartz Performance: A Look Under the Hood

When your application draws to a window using Quartz 2D function calls, the drawing travels from your application to the window’s backing store. From there, Quartz composites all window backing stores, including those generated by OpenGL and video playback, and sends the composite to a frame buffer.

The Quartz Compositor acts like a video mixer in which every pixel onscreen can be shared among windows in real time. Sharing is a big break from traditional windowing systems, which use a switch model. In a switch model, every pixel onscreen belongs entirely to one window or the desktop. The switch model results in a less elegant interface, with abrupt switching between windows. The video mixer model, combined with the ability to make windows translucent, allows for smooth transitions between the states of a graphical user interface and gives Mac OS X its unique and elegant look.

Quartz Extreme, introduced in Mac OS X v10.2, harnesses the power of the graphics processing unit (GPU) to composite the window backing store to the frame buffer. For computers that do not have the minimum graphics hardware needed for Quartz Extreme, Quartz uses the CPU, just as it did prior to Mac OS X v10.2.

< Previous PageNext Page > Hide TOC

© 2001, 2007 Apple Inc. All Rights Reserved. (Last updated: 2007-12-11)

Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.