Other Context Functionality


The graphics context provides some additional functionality that is not directly related to drawing and state management. Many of these settings are device dependent drawing options. Others allow your application to take more control over the drawing process.

Transparency Layers

A transparency layer gives you a convenient tool for collecting a bunch of graphics primitives together into a separate drawing space and then compositing them onto the context all at once. Transparency layers are particularly useful for creating drop shadows and transparent graphics.

You begin a transparency layer by calling the routine CGContextBeginTransparencyLayer. At that point, the computer creates a separate buffer, with a transparent background, for the context. All of the drawing that you send to the context at that point goes to the transparency layer instead of being drawn in the context. The transparency layer honors the clipping area and the graphics state of the context with two exceptions. When you begin a transparency layer, the current context-level alpha is set to be fully opaque (an alpha value of 1), and shadow settings, if any, are turned off.

At this point, your application is free to draw whatever you direct it to, and the graphics will be captured on the transparency layer. When you have finished drawing, call CGContextEndTransparencyLayer and Quartz composites the entire contents of the transparency layer onto the context at once. Before doing so, however, the computer restores the shadow and alpha values in the graphics state. The end result is that the entire contents of the transparency layer are composited on the context with a single alpha value and a single shadow.

Antialiasing and Font Smoothing

Antialiasing and font smoothing are drawing techniques that Quartz uses to improve the appearance of its resolution independent graphics when they are drawn on bitmap displays. When antialiasing, the computer uses the alpha channel to shade pixels along the edges of graphics to reduce their jagged appearance.

When drawing text on a context attached to a color LCD display, Quartz takes advantage of the nature of LCD monitors to improve the legibility of text. This technique is called font smoothing. The pixels of an LCD monitor are made up of red, green, and blue sub-pixels. If you take these sub-pixels into account, the screen appears to have three times the resolution commonly attributed to it, at least in one dimension. Font smoothing takes advantage of this increased resolution to improve the rendering of text. Quartz turns different sub-pixels off and on by changing the color of a pixels along the edge of letter shapes. Because your eye expects to see a hard line at the edge of the glyphs, the computer tricks it into ignoring the color in favor of perceiving a smooth edge. One disadvantage of font smoothing is that it relies on the fixed ordering of the sub-pixels of an LCD display. That makes the technique of limited use on other types of monitors. Font smoothing is also of limited use on offscreen bitmaps.

Antialiasing and font smoothing do not make sense for every graphics context. Nevertheless, the routines that control whether or not Quartz applies antialiasing are part of the generic CGContext API. There are three routines that control antialasing and font smoothing.

The first routine, CGContextSetAllowsAntialiasing is a master switch for the context. This routine turns off antialasing and font smoothing for the context as a whole. The field value controlled by this routine is not part of the graphics state. Use this routine when you want to disable any antialiasing that Quartz might apply to a context.

The next two routines are CGContextSetShouldAntialias and CGContextSetShouldSmoothFonts. These routines manipulate fields that are saved and restored as part of the graphcis state. They change the behavior of the context temporarily. Quartz applies antialiasing when the value in the graphics state and the antialasing master switch are both true. Fonts are smoothed only when antialiasing is enabled and the font smoothing setting in the graphics state is true.

Coordinate Transformations

Because the graphics context contains all the information needed to convert coordinate information between user space and device space, it is uniquely positioned to aid with the reverse transformation as well. The CGContext interface contains routines that transform points, sizes, and rectangles between the two coordinate systems.

CGContextGetUserSpaceToDeviceSpaceTransform returns an CGAffine transformation that converts coordinates between user space and device space. You can use this transform with the techniques described in Chapter 5 to move geometries from user space to the raw coordinate space of the device. Quartz also offers the following methods as convenience routines for transforming common geometries:

CGContextConvertPointToDeviceSpace CGContextConvertPointToUserSpace CGContextConvertSizeToDeviceSpace CGContextConvertSizeToUserSpace CGContextConvertRectToDeviceSpace CGContextConvertRectToUserSpace 


You might use these routines, for example, if you wanted to draw a box that was exactly 32 pixels square into a graphics context attached to a window. To determine how big a rectangle you would have to draw in user space to achieve that effect, you could pass the size 32x32 to CGContextConvertSizeToUserSpace and then draw a rectangle of the resulting size in user space.

Synchronization and Flushing

Mac OS X uses double buffering to draw the contents of its windows. When your application draws to a context attached to a window, the pixels are not actually sent to the screen. Instead, the computer puts your drawing into an offscreen pixel buffer, called the back buffer or backing store, and copies those pixels to the screen at a later time. The act of copying the pixels from the back buffer onto the screen is called flushing the buffer.

Flushing the entire back buffer to the screen with each change is very expensive, particularly for large windows. Additionally, if the computer flushes a lot of little areas, the overhead needed to set up the flushes would be a performance limitation as well. This means that the computer can't flush the entire window each time, nor is it efficient for it to flush each little area of the window as it is drawn. To get the best performance, the computer collects a lot of little changes and copies them to the screen all at once. To do that, the window server keeps track of the dirty areas of each window, those areas where the application has drawn graphics that need to be copied to the screen.

It is up to the application to tell the window server when the program damages an area of the window. Most of the time, this task is handled by the application frameworks, Carbon and Cocoa. On occasion, however, your application may need to forward the dirty areas to the window server explicitly. The Quartz context provides two routines for this task, CGContextSynchronize and CGContextFlush. The proper use of these routines is one of the great mysteries of Quartz programming. Hopefully we can clear up some of that mystery here.

The first thing to realize about CGContextSynchronize and CGContextFlush is that these routines are only useful for CGContexts that are attached to windows. You can call these methods with other graphics contexts, but they don't do anything useful.

The graphics context keeps track of the areas where you draw, and the CGContextSynchronize routine asks the window server to add those areas to the dirty region for the window. Calling CGContextSynchronize is a reasonably fast operation because it doesn't actually cause the window server to flush the back buffer to the screen. It's just a notification that an area of the window is dirty and needs to be updated. The actual flushing will occur at a later time.

If your application creates a CGContext on a window, draws into that context, and then destroys it with CGContextRelease, use CGContextSynchronize before the release to ensure that the dirty areas of the context are sent to the window server.

Compared to CGContextSynchronize, CGContextFlush is a comparatively heavyweight operation. When your application calls CGContextFlush, it forces the computer to take whatever steps are necessary to get the drawing that you've done in the window all the way to the screen. When your application calls CGContextFlush, it will not regain control until the graphics in the context are copied all the way to the computer's display. At first glance this may seem like a good routine to call as often as possible, but this is not the case. If misused, CGContextFlush can be a terrible performance problem.

On systems prior to Tiger, the computer would flush your graphics to the screen almost immediately. Tiger includes a feature that delays the winodw flushes of all applications so that they occur at once. Quartz 2D tries to synchronize its flushes with the refresh rate of the monitor. This refresh usually happens about 60 times a second. If you draw into a graphics context, call CGContextFlush, and then try to draw into that context again. The computer will block your application until the flush occurs. That means that the computer may not return control to your application for as long as one-sixtieth of a second. That is wasted time that your application could probably spend on more valuable computations. When a program calls CGContextFlush and draws into the same context at a rate faster than the computer can complete the flush, the net effect is wasted cycles that could be better spent on other processing. The average person can only perceive screen updates at about 30 frames per second anyway. Calling CGContextFlush more often than that is not useful and can degrade performance.




Quartz 2D Graphics for Mac OS X Developers
Quartz 2D Graphics for Mac OS X Developers
ISBN: 0321336631
EAN: 2147483647
Year: 2006
Pages: 100

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net