Quartz provides a function—CGPDFPageGetDrawingTransform—that creates an affine transform by mapping a box in a PDF page to a rectangle you specify. The prototype for this function is:
CGAffineTransform CGPDFPageGetDrawingTransform ( |
CGPPageRef page, |
CGPDFBox box, |
CGRect rect, |
int rotate, |
bool preserveAspectRatio |
); |
The function returns an affine transform using that following algorithm:
Intersects the rectangle associated with the type of PDF box you specify in the box parameter (media, crop, bleed, trim, or art) and the /MediaBox entry of the specified PDF page. The intersection results in an effective rectangle.
Rotates the effective rectangle by the amount specified by the /Rotate entry for the PDF page.
Centers the resulting rectangle on rectangle you supply in the rect parameter.
If the value of the rotate parameter you supply is nonzero and a multiple of 90, the function rotates the effective rectangle by the number of degrees you supply. Positive values rotate the rectangle to the right; negative values rotate the rectangle to the left. Note that you pass degrees, not radians. Keep in mind that is the /Rotate entry for the PDF page contains a rotation as well, the rotate parameter you supply is combined with the /Rotate entry.
Scales the effective rectangle, if necessary, so that it coincides with the edges of the rectangle you supply.
If you specify to preserve the aspect ratio by passing true in the preserveAspectRatio parameter, then the final rectangle coincides with the edges of the more restrictive dimension of the rectangle you supply in the rect parameter.
You can use this function, for example, if you are writing a PDF viewing application similar to that shown in Figure 13-3. If you were to provide a Rotate Left/Rotate Right feature, you could call CGPDFPageGetDrawingTransform to compute the appropriate transform for the current window size and rotation setting.
Listing 13-3 shows a function that creates an affine transform for a PDF page, using the parameters passed to the function, applies the transform, and then draws the PDF page. A detailed explanation for each numbered line of code appears following the listing.
Listing 13-3 Creating an affine transform for a PDF page
void MyDrawPDFPageInRect (CGContextRef context, |
CGPDFPageRef page, |
CGPDFBox box, |
CGRect rect, |
int rotation, |
bool preserveAspectRatio) |
{ |
CGAffineTransform m; |
m = CGPDFPageGetDrawingTransform (page, box, rect, rotation,// 1 |
preserveAspectRato); |
CGContextSaveGState (context);// 2 |
CGContextConcatCTM (context, m);// 3 |
CGContextClipToRect (context,CGPDFPageGetBoxRect (page, box));// 4 |
CGContextDrawPDFPage (context, page);// 5 |
CGContextRestoreGState (context);// 6 |
} |
Here’s what the code does:
Creates an affine transform from the parameters supplied to the function.
Saves the graphics state.
Concatenates the CTM with the affine transform.
Clips the graphics context to the rectangle specified by the box parameter. The function CGPDFPageGetBoxRect obtains the page bounding box (media, crop, bleed, trim, and art boxes) associated with the constant you supply—kCGPDFMediaBox, kCGPDFCropBox, kCGPDFBleedBox, kCGPDFTrimBox, or kCGPDFArtBox.
Draws the PDF page to the transformed and clipped context.
Restores the graphics state.
Last updated: 2007-12-11