Chapter 1. Getting Started

Macintosh computers have enjoyed a strong association with graphics since they were first introduced to the world in 1984. That association undeniably began with the novelty of the graphical user interface. The platform evolved from its humble beginnings as a consumer computer, and as it grew, it retained its strong association to graphics. The platform attracted professionals in many graphics disciplines. In serving those needs, application developers have firmly established the Macintosh as an invaluable asset in today’s graphics industry.

Apple, for their part, works hard to meet the needs of graphics professionals and application developers alike. They have focused their efforts on creating a system with the power to satisfy the needs of professionals on both sides of the development equation. Macintosh has already taken a leadership role in emerging fields like digital photography and professional digital video production. The future promises to continue or even accelerate this trend.

The classic Macintosh operating systems relied on the QuickDraw graphics library to provide a graphics system for the platform. As the demands of developers evolved, QuickDraw itself evolved, often in unexpected directions. Eventually, the needs of application developers began to outpace the ability of the QuickDraw technology to adapt. Apple took advantage of a rare opportunity when they introduced Mac OS X with a new graphics architecture. Quartz 2D is a portion of that architecture and carries the functionality that is closest to the drawing capabilities of QuickDraw.

Quartz 2D itself is a modern, device independent library for creating 2D graphics. It is a vital component of the operating system and plays a prominent role in many other parts of the system, like the Aqua user interface and the Mac OS X printing system.

This book offers an introduction to Quartz 2D for application developers. The objective is to introduce the Quartz 2D imaging model and explore some drawing techniques for applying that imaging model when creating graphics on Mac OS X.

While Quartz 2D plays the many of the same roles that QuickDraw played on older operating systems, or that GDI plays on Windows, the imaging model it uses is quite different from those other libraries. This makes learning to use Quartz 2D a challenge. Because Apple has deprecated QuickDraw, many developers are now in a position of needing to rework their application’s graphics system to use Quartz 2D. Developers porting applications from Windows or X11 also may find the differences in the imaging models troublesome. Many of the same techniques that a developer might use to optimize graphics with other graphics libraries cannot be applied to Quartz 2D. This book is designed to help programmers understand the differences among Quartz 2D and other graphics libraries and to learn new techniques they can apply through Quartz 2D. At times, this text focuses on QuickDraw because that technology is representative of a pixel-based graphics library and is likely to be familiar to Macintosh developers. However, the discussions should serve those who are bringing their applications to the Macintosh as well.

As an added bonus, a very brief introduction to Core Image is given. Core Image is a high-performance architecture for creating and applying image processing filters to images. It has been included in this book not only because of its novelty, but because it is a very useful tool for creating 2D graphics. Core Image is remarkably easy to use and can generate impressive results quickly. The primary reason for including Core Image, however, is that along with Quartz 2D, Core Image represents the future of graphics on the Macintosh platform.

This first chapter presents some preliminary information. We begin with an overview of the book and a short synopsis of the discussions to follow. Some of the more mundane aspects of accessing the library are covered, such as understanding the naming conventions in the Quartz 2D API. Also presented is a brief description of the Core Image API with some pointers on finding more information about Objective-C.

About This Book

The book begins by placing Quartz 2D and Core Image in the context of the Mac OS X graphics system. As part of that discussion some very important advances in personal computer graphics systems are pointed out—advances that Quartz 2D uses to its advantage. Chapter 2, “From QuickDraw to Quartz 2D,” offers a historical perspective on the origins of the Mac OS X graphics system in general, Quartz 2D in particular. It discusses important trends that are shaping the future of computer graphics on the Macintosh. These discussions also contain valuable insights that will hopefully demonstrate the advantages of adopting Quartz 2D in your own applications.

Chapter 3, “Introduction to Quartz 2D,” begins the main discussion of Quartz 2D itself. This chapter begins by describing some of the distinguishing features that the library provides. Chapter 3 is also an introduction to the Quartz 2D drawing model. The chapter presents a bird’s-eye view of the drawing process and contrasts the Quartz drawing model with the traditional pixel-based model of other graphics systems.

Chapter 4, “The Graphics Context,” begins a more in-depth analysis of the Quartz 2D imaging model. This chapter builds upon the foundation in Chapter 3 and describes a central player in the Quartz 2D imaging model, the Core Graphics Context. The chapter describes the many facets of a graphics context and concludes with a discussion of how to create graphics contexts on a variety of devices.

Chapter 5, “Trasformations,” discusses coordinate transformations in Quartz 2D. The flexibility in the Quartz 2D coordinate system is an important feature that is not found in many other graphics libraries. The transformations in Quartz 2D form the basis of the library’s device independence and are valuable tools that can help applications build their graphics. In describing the transformations in Quartz 2D Chapter 5 offers suggestions about how to use them to simplify the drawing process.

Chapter 6, “Line Art—Building Paths,” and Chapter 7, “Line Art—Drawing,” concern the tools used to draw line art in Quartz 2D. Chapter 6 introduces the fundamental element of line art in the system, the Bezier Path. The chapter discusses the role of the path in the drawing model and describes different ways applications can construct paths. Chapter 7 builds upon the information in Chapter 6 by exploring the basic path drawing operations. While there are only three fundamental drawing operations for paths (stroking, filling, and clipping), the Quartz 2D imaging model includes a large number of options for each operation. Chapter 7 describes these options and their effects.

Chapters 8, “Image Basics,” and Chapter 9, “Importing and Exporting Images,” address the role of images in the Quartz 2D drawing model. Images are the tools that Quartz 2D provides for working with pixel data. Chapter 8 explains what goes into an image, how to incorporate images into your graphics, and how to generate pixel-based images from Quartz drawing code. The ability to create images becomes much more exciting when you can export those images to other applications. Chapter 9 explores two systems capable of importing and exporting graphics, Image I/O and QuickTime. Image I/O is a new, powerful architecture for exporting images from Quartz 2D. Image I/O, however, is a Tiger-only feature. For the benefit of applications that must work with older Mac OS X systems, also included is a description of working with QuickTime importers and exporters.

Chapter 10, “Drawing with Core Image,” continues the theme of working with images by presenting an introduction to Core Image. The chapter provides an quick overview of Core Image features and functionality. It then describes the Core Image drawing process and offers some code demonstrations that show how to use Core Image to apply a simple image filter and to run a transition.

Chapter 11, “Drawing Text with Quartz 2D,” discusses the text capabilities of Quartz 2D. In addition to describing the features of the Quartz 2D text system, the chapter explains how Quartz 2D integrates with more sophisticated text handling systems. To demonstrate the text handling capabilities of Quartz 2D itself, the chapter includes a code sample that demonstrates one technique for using Quartz 2D to generate special text effects.

Chapter 12, “Drawing Offscreen,” describes two mechanisms that Quartz 2D includes for drawing in off-screen environments. Proper use of offscreen graphics can have a profound impact on the performance of your application. This chapter describes drawing in CGLayers and into offscreen bitmaps. It provides some insight directed at helping developers choose the most appropriate mechanism for their own code.

Chapter 13, “Shadings and Patterns,” covers Shadings and Patterns. Shadings and Patterns are two drawing primitives in Quartz 2D that are have not traditionally been available in other graphics libraries but which are found in most contemporary graphics packages. Shadings allow a program to create smoothly blended fields of color and then fill shapes with those colors. Patterns are formed by tiling a particular graphic repeatedly.

Chapter 14, “Working with PDF,” focuses on the role of the PDF format in Quartz 2D. The library has the ability to record a series of drawing commands into a PDF. This means that PDF is the metafile format for Quartz 2D. The system also has the ability to draw PDF files. This chapter explores techniques for both creating PDF files from Quartz 2D drawing commands and incorporating external PDF files into your own graphics.

Formatting Conventions

Throughout the text, the examples strive to use text formatting to enhance the presentation. This section describes some of the formatting used in the text.

The text presents the names of routines, constants, or other code element in a particular font. For example, CGContextRestoreGState is the name of one of the routines in the Quartz 2D drawing API. This same font is also used for any source code listings that appear in the text.

As you progress through the text, you will find sections with special icons in the margins. These sections represent supplemental information related to the topic at hand but may not be essential to your understanding. Table 1.1 describes what kind of supplemental information each icon represents.

Table 1.1. Icons in the Text

Icon

Name

Description

Icons in the Text

Tip

This symbol appears next to descriptions of interesting information related to the topic at hand but which may not be crucial to understanding the main ideas of the text.

Icons in the Text

Caution

This icon calls out warnings related to the topic of discussion. Caution icons can help you avoid pitfalls and errors in your code or in the operating system itself.

Icons in the Text

Performance

The performance icon appears next to information that may help you extract the maximum performance from Quartz 2D or Core Image within your own code.

Icons in the Text

QuickDraw

This icon identifies information that may help developers with legacy applications move those applications from QuickDraw to Quartz 2D.

Apple provides excellent documentation on Quartz 2D and Core Image. You are encouraged to explore that documentation to help deepen your understanding of Quartz 2D. To that end we occasionally provide URLs that hyperlink to relevant Quartz 2D documentation.

Accessing Quartz 2D

Mac OS X includes a remarkable number of different application environments almost all in which Quartz 2D, in one form or another, is available. Clearly Quartz 2D plays an important role in applications with graphical interfaces, like the ones created with the Carbon and Cocoa application APIs. However, Quartz 2D also can be used from command line applications, CGI scripts, and even directly in the HTML of a web page or Dashboard Widget.

While the routines that invoke Quartz 2D will be different in each application environment, the Quartz 2D imaging model should remain familiar. This book is not able to describe each routine of each application interface in detail. For that information, refer to Apple’s reference documentation. Instead the focus is on the general information about the different environments in this chapter and then the drawing model is highlighted throughout the rest of the book.

The Quartz 2D C API

Quartz 2D is one part of a larger graphics environment known as Core Graphics. In addition to Quartz 2D, Core Graphics interacts with the window system and hardware to integrate graphics created by the many different graphics libraries on the system. It is responsible for managing the display environment and working with the window server and Quartz compositor to create the image presented on the screens. While Core Graphics encompasses more than Quartz 2D, it’s not unusual for people to use the two terms interchangeably when discussing Quartz 2D in context.

The Core Graphics API is an object oriented API. To allow developers to use that API in as many environments as possible, however, the system implements it as a set of C routines. The API itself draws upon the object-oriented concepts of encapsulation, inheritance, and polymorphism. Because C doesn’t directly support these concepts, Core Graphics uses opaque data types, in the place of classes, to support encapsulation and inheritance. To provide polymorphism, Core Graphics applies a naming convention to its routines.

Core Graphics draws its design from the Core Foundation API. Developers familiar with Core Foundation can apply much of that knowledge to the Core Graphics APIs as well. In fact, programs can treat Core Graphics objects as Core Foundation objects. For example, Core Graphics objects can be stored in Core Foundation containers.

The Core Graphics APIs manage the life cycle of objects with the Core Foundation ownership model. We present the basics of the naming conventions and the object ownership model here. Apple’s documentation on the Core Foundation Design Concepts present the same information in much greater detail (although in the context of Core Foundation and not Core Graphics). You can find it on the Web at the URL:

http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFDesignConcepts/index.html

Naming Conventions

The first thing you will notice about the API elements in Core Graphics is the fact that they include the prefix CG. For example two Core Graphics routines are CGContextBeginPage and CGImageGetWidth. The simple exception to this rule is constants that also follow an older Macintosh convention. The name of constants begin with a lower case k. The constant kCGImageAlphaNone, for example, is one that describes the way images store alpha channels.

After the prefix, the name includes an opaque data type that relates to that API element. CGContextBeginPage is a method of a “Context” object. CGImageGetWidth and kCGImageAlphaNone both have something to do with “Image” objects.

The remainder of the name relates to the specific task that element is for. Object methods are usually verb phrases such as BeginPage or GetWidth. Constants simply have descriptive names. Many times the different parts of the name narrow down the use of the constant from general ideas to more specific ones. For example, in kCGImageAlphaNone, the general concept related to the constant is “Alpha” (the alpha channel), and this particular constant represents an image with no alpha channel (alpha channel of none).

Core Graphics Objects

A Core Graphics object is an instance of a particular opaque data type. This is completely analogous to an instance of a class in other object-oriented environments. Routines that create objects return a value known as an object reference. These data objects are easy to recognize because their type name ends with the suffix Ref. For example, one of the routines that create an image in Quartz 2D is CGImageCreate. The data type this routine returns is a CGImageRef.

It’s important to realize that an object reference is not a pointer. Object references might not obey the semantics as pointers. This may have consequences in the way you handle references inside of your application. For example, if your application includes debugging code that validates pointers, you cannot use that code to validate a reference. The Core Graphics API does use NULL to represent an invalid or un-initialized reference. You may compare object references against NULL just as you would a pointer.

Note

Core Graphics objectsObjects

Unfortunately, the naming convention applied to object references does not apply to every API on the system. If you are new to Macintosh programming and you are using the Carbon API, one particular case worth noting is the file reference data type, FSRef. Based on its name, you might conclude that an FSRef variable is an object reference. In this case, the value of the FSRef is an opaque data structure, but it is not a pointer-sized value. You cannot compare an FSRef against NULL, and FSRefs do not implement the Core Foundation ownership model.

Core Graphics uses the Core Foundation reference counting system to manage the life cycle of objects. Each object contains an integer valued reference count. When the object is created, its reference count has the value 1. The API includes routines for incrementing and decrementing the reference count. Incrementing the reference count is called retaining the object. Decrementing the reference count is called releasing the object. When the object’s reference count becomes 0, the system destroys the object and releases any resources it owns.

To retain an object you can use the Core Foundation routine CFRetain or a type-specific routine. To release a CGContext object, for example you could use the type-specific call CGContextRetain. Similarly, to release an object you can use the Core Foundation routine CFRelease or a type-specific routine such as CGContextRelease. The end result of CFRetain and CGContextRetain are the same; the only difference is that CFRetain will generate an error if you pass it NULL. CGContextRetain will not.

The pseudocode in Listing 1.1 presents an example of reference counting in Core Graphics. Listing 1.1 is not valid code—for example some of the parameters to CGImageCreate are not given. The listing represents code that manages the existence of two objects, a CGDataProvider and a CGImage.

Example 1.1. Object Ownership Pseudocode

// Create a new data provider from a URL
CGDataProviderRef myDataProvider = CGDataProviderCreateWithURL(myURL);

// Create an image with the contents of the URL
CGImageRef myImage = CGImageCreate(..., myDataProvider, ...);

// The data provider has served our purposes so release it.
CGDataProviderRelease(myDataProvider);
myDataProvider = NULL;

// Call some code that does something interesting with the image.
DrawMyImage(myImage);

// We're done with the image now so we can release it
CGImageRelease(myImage);
myImage = NULL;

The code begins by creating an instance of the opaque type CGDataProvider. This newly created object begins with a reference count of 1. The CGImageCreate routine builds a CGImage as the second object.

The code uses the CGDataProvider as one of the parameters to the CGImageCreate routine. When the image has been created, the program has no use for the CGDataProvider. Listing 1.1 asks Core Graphics to release a reference to the object by calling the CGDataProviderRelease routine.

After you release the object, Quartz 2D may or may not dispose of the CGDataProvider. The code calls CGDataProviderRelease to tell the system that it has finished using the object. However, the CGImageCreate routine may have retained the object for its own uses. From your perspective, however, you no longer have a valid reference to the object, so you would set the reference variable to NULL.

The image also has an initial reference count of 1. The code calls DrawMyImage, which presumably draws the image on a graphics context. This is the only thing the code does with the image. The call to CGImageRelease releases the image and destroys it. If the image has retained the CGDataProvider, it will release that as well.

When you receive an object from a Core Graphics routine, you may or may not be responsible for releasing the object. The key to making the decision is the names of method. If a method’s name includes Create (as in CGBitmapContextCreate) or Copy then the routine will return an object that you must release when you have finished using it. If the name includes the term Get, as in CGImageGetColorSpace, then the object returned by the routine belongs to the caller. If you want to maintain a reference to the object, you should retain it. If you do not retain it, however, do not release it.

Other Object-Oriented Features

Object references can participate in polymorphic methods. The abstract data type in Quartz 2D have inheritance hierarchies. For example, Quartz 2D includes an opaque data type called a CGContext. A CGContext is an abstract interface to a particular graphics device. There are several opaque data types that inherit behaviors from the CGContext type. The CGContext for drawing to a bitmap might be an instance of the CGBitmapContext data type, while the context for drawing to a PDF file would be a CGPDFContext. Both of these context types inherit their context behavior from the CGContext base type.

Inside application code, the polymorphic data type CGContextRef can store an object reference to any type of graphics context. Any routine that accepts a CGContextRef as a parameter should accept a bitmap context or a PDF context as well.

That’s not to say that every polymorphic method applies equally well to all of the opaque types. For example, PDF files have pages while bitmap contexts do not. Quartz 2D has a method called CGContextBeginPage. This routine accepts a CGContextRef as a parameter and tries to create a new page on that context. Starting a new page in a PDF makes sense but creating a new page in a bitmap context does not. Nevertheless, CGContextBeginPage is a polymorphic routine, and you can pass a bitmap context to it. The system simply will won’t do anything in response.

Accessing Quartz 2D from Cocoa

Cocoa and the AppKit include a number of Objective-C classes that are implemented using the Quartz 2D API. For example, NSBezierPath is a class that allows you to draw Quartz 2D line art. An important fact to note about the AppKit’s drawing classes is that they are not a one-to-one reflection of the opaque data types found in the Core Graphics API. The Cocoa classes offer the same graphic quality as the “raw” Core Graphics APIs, but the system presents a more direct embodiment of the graphics model than the C APIs.

Cocoa does not yet provide Objective-C interfaces for every feature in Quartz 2D. However, because Objective-C applications can call C routines, they can make direct calls to Quartz 2D’s C interface. This allows Cocoa applications to take full advantage of the Quartz 2D system, but it may require stepping away from the graphics support that the Cocoa classes provide by default.

Alternative APIs

In addition to the APIs provided by the traditional graphical application frameworks, Quartz 2D also has bindings to other, more unusual environments. In particular, Quartz 2D is available to shell scripts, command line tools, and CGI scripts through a set of Python bindings. HTML developers can use Quartz 2D in Safari and in Dashboard widgets, using the canvas tag. For the sake of completeness, we briefly explore those interfaces here.

The Python Interface

Many developers are surprised to learn that Quartz 2D has bindings for the Python scripting language. A scripting interface opens the power of Quartz 2D to applications that don’t have user interfaces. For example, a server side CGI script, written in Python, could use Quartz 2D to generate an up-to-the-minute weather map.

Working with Quartz 2D through Python is straightforward. Python has its own object model that Apple has integrated with the Quartz 2D object model. The Python runtime environment has a garbage collector. That means that when working with Python, your script does not have to keep track of object references. The Python interface to Quartz 2D takes advantage of this memory scheme. Quartz 2D Python scripts don’t have to retain and release objects explicitly.

The methods that you call on Core Graphics objects in Python take their names from the routines in the C API that invoke the same behavior. Because Python has a class hierarchy, the Python methods do not have the CG prefix, and they do not explicitly name the class they work with. Following language guidelines, the initial letter of a method name is not capitalized.

This scheme sounds a bit more complicated than it really is. For example, the Core Graphics method CGContextAddLineToPoint is reflected in the Python interface as the method addLineToPoint called on an instance of the Python CGContext class.

When working with the Quartz 2D API through a C-like language, you have the advantage of being able to call any other API on the system. That means if you need to call QuickTime to import an image, you are free to do so. Unfortunately, Python interfaces do not exist for all that functionality on Mac OS X. The Python interface for Quartz 2D, therefore, includes a number of handy utility routines that help your scripts create graphics. For example, the Python interface includes the routine CGImageImport, which you can use to create a CGImage from a file on disk.

While there is plenty of reference documentation for the Quartz 2D routines themselves, those parts of the Python interface that aren’t found in the C interface are not documented as well as they could be. There are quite a few example programs that Mac OS X includes with the developer tools. These files are found at the path

/Developer/Examples/Quartz/Python

That folder also contains a file called API-SUMMARY that holds a wealth of information about the Python interface to Quartz 2D and different ways you can use it in your own scripts.

The HTML Canvas Tag

Beginning with Mac OS X 10.4 Tiger, developers also can encode Quartz 2D graphics into HTML content that is part of a Dashboard Widget or an HTML page displayed in Safari. To get Quartz 2D graphics directly into HTML content, there are two important steps. The first is to identify some area of your HTML in which you would like to draw Quartz graphics. To do this, the HTML code uses the canvas tag. After the drawing area has been identified, the HTML document can draw into that canvas using JavaScript to talk to it.

The JavaScript routines that put content into an HTML canvas follow naming conventions that are very similar to those found in the Python interface. The code will typically begin by asking the canvas for a context object. It can then call methods on that context to create graphics.

Apple has provided some tutorials about working with the canvas in Safari and in Dashboard widgets. You can reach one such tutorial by following the URL:

http://developer.apple.com/documentation/AppleApplications/Conceptual/SafariJSProgTopics/index.html

The Core Image API

Core Image has an Objective-C interface. To work with Core Image, your code creates Objective-C objects representing concepts like an image or a filter and sends messages to those objects.

As an Objective-C API, Core Image uses the same object ownership model and naming conventions shared by all Objective-C interfaces. The Core Image classes begin with the solidly predictable prefix, CI.

One important note: while the Core Image API is accessed through Objective-C, it is not tied to the Cocoa application frameworks at all. Do not confuse the Objective-C language with Cocoa! The Cocoa application framework uses Objective-C in its interface, but that does not mean that all Objective-C interfaces on the system are Cocoa interfaces. In particular, Carbon applications are free to use Core Image too. They will have to include some Objective-C or Objective-C++ files, but they need not use any Cocoa classes.

Some readers may not be familiar with Objective-C. The language is a straightforward implementation of object-oriented programming, built on top of C but drawing some syntax cues from Smalltalk. Developers familiar with C and object-oriented concepts should have no trouble grasping the basic syntax needed to make effective use of Objective-C in a few hours.

If you are unfamiliar with Objective-C and wish to use Core Image, read Apple’s introduction to Objective-C at

http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/index.html

Additionally, there are several good, third-party books on Cocoa programming that also cover Objective-C. Any of them will provide enough information about Objective-C that you could easily apply that knowledge to the Core Image API.

This concludes the discussion about this book and about some of the more mundane aspects of working with Quartz 2D. Now to begin a discussion of Quartz 2D in earnest. You will hopefully enjoy the presentation and find it valuable!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.66.208