When you use Quartz 2D to draw text, you need to perform these tasks:
Set the font and font size.
Set the text drawing mode.
Set other items as needed—stroke color, fill color, clipping area.
Set up a text matrix if you want to translate, rotate, or scale the text space.
Draw the text.
Quartz 2D provides two ways to set the font and font size. You can call either the function CGContextSelectFont or the functions CGContextSetFont and CGContextSetFontSize. If your requirements are simple, you’ll probably want to use CGContextSelectFont. If your requirements are more complex, you can use the alternative functions, CGContextSetFont and CGContextSetFontSize. But instead of using CGContextSetFont and CGContextSetFontSize, you may instead want to use ATSUI or Cocoa to set the font and perform text drawing. That’s because Quartz has some limitations for drawing text. Here’s a closer look at the two Quartz 2D alternatives.
If setting the font to a MacRoman text encoding is sufficient for your application, use the CGContextSelectFont function. Then, when you are ready to draw the text, you call the function CGContextShowTextAtPoint. The function CGContextSelectFont takes as parameters a graphics context, the PostScript name of the font to set, the size of the font (in user space units), and a text encoding.
To set the font to a text encoding other than MacRoman, you can use the functions CGContextSetFont and CGContextSetFontSize. You must supply a CGFont object to the function CGContextSetFont. You call the function CGFontCreateWithPlatformFont to obtain a CGFont object from an ATS font. When you are ready to draw the text, you use the function CGContextShowGlyphsAtPoint rather than CGContextShowTextAtPoint.
The reason you cannot use CGContextShowTextAtPoint when you use CGContextSetFont is that Quartz needs a text encoding to map the bytes in the text string to glyphs in the font. By default, the text encoding is kCGEncodingFontSpecific, so there's no guarantee of what you'll get when you call CGContextShowTextAtPoint. Since there's no way to set the text encoding other than with a call to CGContextSelectFont you cannot draw text using CGContextShowTextAtPoint if you set the font with CGContextSetFont. If you set the font this way, you must also be prepared to use ATSUI, Cocoa, or your own code to map character strings to glyphs so that you can then call CGContextShowGlyphsAtPoint. It might be easier for you to simply use ATSUI or Cocoa to perform the text drawing, and not use any of the Quartz 2D functions.
Now that you understand some of the limitations of using Quartz to draw text, you can take a look some sample code that draws text when the font and font size are set using the function CGContextSelectFont. This function, although not recommended except for cases in which MacRoman encoding is sufficient, is fairly straightforward to use. Listing 17-1 shows a function—MyDrawText—that draws the text shown in Figure 17-1. A detailed explanation for each numbered line of code appears following the listing.
Listing 17-1 Drawing text
void MyDrawText (CGContextRef myContext, CGRect contextRect) // 1 |
{ |
float w, h; |
w = contextRect.size.width; |
h = contextRect.size.height; |
CGAffineTransform myTextTransform; // 2 |
CGContextSelectFont (myContext, // 3 |
"Times-Bold", |
h/10, |
kCGEncodingMacRoman); |
CGContextSetCharacterSpacing (myContext, 10); // 4 |
CGContextSetTextDrawingMode (myContext, kCGTextFillStroke); // 5 |
CGContextSetRGBFillColor (myContext, 0, 1, 0, .5); // 6 |
CGContextSetRGBStrokeColor (myContext, 0, 0, 1, 1); // 7 |
myTextTransform = CGAffineTransformMakeRotation (MyRadians (45)); // 8 |
CGContextSetTextMatrix (myContext, myTextTransform); // 9 |
CGContextShowTextAtPoint (myContext, 40, 0, "Quartz 2D", 9); // 10 |
} |
Here’s what the code does:
Takes as parameters a graphics context and a rectangle to draw to.
Declares storage for the affine transform.
Sets the font to Times Bold and the font size to the height of the page rectangle divided by 10. The font size is in text space units. In this example, the text is drawn to a resizable window. When the user resizes the window, the text resizes as well. The encoding is set to kCGEncodingMacRoman, but the only other choice is kCGEncodingFontSpecific.
Sets the character spacing to 10 text space units. You call this function only if you want to add the additional space to the advance between the origin of one glyph and the origin of the next glyph.
Sets the text drawing mode to fill and stroke.
Sets the fill color to green with an alpha value of .5 for a partially transparent fill. Note that this is not a text-specific attribute. The fill color applies to the graphics state.
Sets the stroke color to opaque blue. This is another attribute that is not text specific.
Creates an affine transform that performs a 45 degree rotation. The MyRadians routine is an application-defined convenience function for computing degrees from radians. You either need to supply your own routine to convert degrees to radians, or you need to substitute this call with a value that specifies radians. Otherwise, this code example will not compile.
Sets the text matrix to the transform created in the last step.
Draws the text, passing the x- and y-coordinates in text space to start the drawing (40, 0), an array of characters to draw, and a value that specifies the length of the text array. In this case, you pass a C-style string and the value 9 to specify the number of characters.
Last updated: 2007-12-11