In my app I'm trying to render text along a path; this is fine for most characters but not for Japanese (or anything non mac-Roman). I've been advised to use [NSString drawAtPoint] which displays the correct characters in my CATiledLayer; however, they dissapear after approximately 5 seconds. In this time I can zoom the layer and they scale properly, but they don't seem to get committed to the CATiledLayer like the rest of the text usually is.
Before I render, I check the string and decide whether any of them will not be renderable. If I'm going to have issues, I use drawAtpoint instead:
if (!isFullyDisplayable)
{
CGContextShowGlyphsAtPoint(context, pt.x, pt.y, realGlyph, 1);
}
else {
// fall back on less flexible font rendering for difficult characters
NSString *b = [gv text];
NSString *c = [b substringWithRange:NSMakeRange(j,1)];
[c drawAtPoint:pt withFont:[UIFont fontWithName:@"Helvetica-Bold" size:16.0]];
}
Does anyone have any pointers as to why the text disappears?
As soon as the drawAtPoint is used my debug output gets flooded with:
<Error>: CGContextGetShouldSmoothFonts: invalid context
<Error>: CGContextSetFont: invalid context
<Error>: CGContextSetTextMatrix: invalid context
<Error>: CGContextSetFontSize: invalid context
<Error>: CGContextSetTextPosition: invalid context
<Error>: CGContextShowGlyphsWithAdvances: invalid context
So I'm guessing it is something to do with my context management, but I assumed that if this is in the same place as I use CGContextShowGlyphsAtPoint it should have the correct context already?
Answering my own question:
NSString drawAtPoint:withFont: makes use of the context stack, and from where I was calling this method the stack was empty. Wrapping the call with
did the trick.
For completeness, here is the code needed for Cocoa. Also works with
.drawInRect
...This is mostly not needed, as @davbryn says, as normally there is already a "working" context on the stack that is the same (you hope!) as your context, however, as he points out, sometimes there isn't. I discovered this problem particularly with MapKit
MKOverlayRenderer
'sdrawMapRect:
, which simply wouldn't show text without setting the context explicitly.