Mac OS X Reference Library Apple Developer
Search

Troubleshooting

This chapter addresses some problems and questions you may have as you modify your application to take advantage of resolution independence.

Problems

My controls and other window elements are truncated, or show up in odd places.

Misplaced drawing almost certainly results from code that assumes that 1 Quartz point = 1 pixel. In a resolution-independent system, there is no guarantee that this is the case. See “Coordinate Conversion in Cocoa” or “Coordinate Conversion in Carbon.”

Some of my artwork displays with cracks.

Pixel cracking typically occurs at nonintegral scale factors when tiling images to form a continuous background or fill. The cracks are caused when rounding errors cause points to be mapped to nonadjacent pixel boundaries. The image boundaries may overlap or contain anti-aliasing artifacts. Figure 4-1 illustrates the problem.

Figure 4-1  Pixel cracking

Pixel cracking

The solution is to make sure that your drawing aligns on pixel boundaries rather than relying on Quartz points. To adjust the position of an object to fall on exact pixel boundaries, you must do the following:

  1. Convert the object's origin and size values from user space to device space coordinates.

  2. Round each of the values to fall on exact pixel boundaries in device space.

  3. Convert the values back to user space to obtain the coordinates required to achieve the desired pixel boundaries.

Carbon applications can use the function HIWindowGetScaleMode to obtain the scale mode, HIRectConvert to convert coordinates between user and device space, and CGRectIntegral to manipulate the values in an HIRect structure that contains the object’s bounds, as shown in Listing 4-1.

Listing 4-1  Aligning on pixel boundaries in Carbon

// myRect contains the bounds of an object that draws a portion of myView
HIWindowScaleMode scaleMode;
HIWindowGetScaleMode (window, &scaleMode, NULL);
if (scaleMode == kHIWindowScaleModeFrameworkScaled)
{   // window is framework scaled and scale factor is not 1.0
    // convert coordinates to device space units
    HIRectConvert (&myRect, kHICoordSpaceView, myView, kHICoordSpaceScreenPixel, NULL);
    // outset the rectangle to integer boundaries
    myRect = CGRectIntegral(myRect);
    // convert back to user space
    HIRectConvert (&myRect, kHICoordSpaceScreenPixel, NULL, kHICoordSpaceView, myView);
}

Cocoa applications can align a rectangle on pixel boundaries using the convertRect: method in the NSView class, as shown in Listing 4-2.

Listing 4-2  Aligning on pixel boundaries in Cocoa

float scaleFactor = [[myView window] userSpaceScaleFactor];
if (scaleFactor != 1.0)
{
    // convert rect to pixel coordinates
    myRect = [myView convertRect:rect toView:nil];
 
    // round the origin and size up to the nearest pixel boundary
    myRect.origin.x = ceilf(myRect.origin.x);
    myRect.origin.y = ceilf(myRect.origin.y);
    myRect.size.width = ceilf(myRect.size.width);
    myRect.size.height = ceilf(myRect.size.height);
 
    // convert rect back to user space
    myRect = [myView convertRect:myRect fromView:nil];
}

Some of my bitmap images show banding or jaggies.

Jaggies or banding result from poor scaling of bitmap images due to interpolation problems, as shown in Figure 4-2.

Figure 4-2  Interpolation problems

Interpolation problems

You can improve interpolation accuracy by adjusting the interpolation quality using the Quartz 2D function CGContextSetInterpolationQuality or the Cocoa NSGraphicsContext method setImageInterpolation:. Higher quality interpolation can incur a performance overhead.

If your Cocoa application needs to scale any artwork, you should specify NSImageInterpolationHigh when rendering.

If adjusting the interpolation quality does not work, you can supply additional artwork sizes (such as 1.25x and 1.5x) to allow more accurate interpolation.

Questions

What about plug-ins?

If your application supports plug-ins, you may need to ensure that they are resolution independence–savvy. If you pass drawing coordinates between the plug-in and the application, you need to make sure that both sides agree on what type of coordinates they are, and who is responsible for scaling (if necessary).

If the plug-in uses QuickDraw to draw, you should update it to use Quartz, or (if you do not have access to the source), coordinate with the plug-in owner to make sure all drawing is properly scaled.

My application still needs to work on earlier systems. What's the best way to ensure backwards compatibility?

If your application uses Cocoa views or Carbon HIViews and does all of its drawing using Quartz, most scaling should work automatically.

Most standard controls have been available for several OS releases, so they should still work on earlier systems. If the standard control is not available for older systems, draw using the standard control in Mac OS X v10.5 and a custom control in Mac OS X v10.4 and earlier.

The Cocoa class NSImage supports multi-image TIFF and PDF files in Mac OS X v10.3 and later.

Icon Services supports 256 x 256 and 512x 512 images in .icns files back to Mac OS X v10.3, although v10.3 does not use the newer images. Mac OS X v10.2 cannot read the .icns file at all if it contains the larger images, so the only workaround is to install a separate icon file containing only 128 x128 and smaller images.

You should test your application at the following scale factors: 1.0, 1.25, 1.5, 2.0, and 3.0.




Last updated: 2007-05-04

Did this document help you? Yes It's good, but... Not helpful...