Has anyone encountered Xcode failing at UIGraphicsEndPDFContext() after drawing to a context with Japanese text from a NSAttributedString? Luckily the first time I tested my code in Japanese, my iPhone was off-line and it worked. However, much later when I ran the same code in the simulator, it failed and I spent a lot time time trying to debug it. It will also fail when trying to run it from Xcode on an iPhone or iPad when hardwired to the Mac. Seems like trying to run from Xcode in Japanese in this way is the problem. The Mac was set to English.
Following is the method I used for the drawing. It is closely based on the example published by Erica Sadun in her book, "The iOS 5 Developer's Cookbook" which was a good read early on for me. It is placed after a UIGraphicsBeginPDFContextToData() and UIGraphicsBeginPDFPageWithInfo() sequence and before a UIGraphicsEndPDFContext() call which all works fine in English. I don't necessarily need to fix this. I just wanted to alert others so that they might be able to avoid the two days I spent trying to figure this issue out.
- (void)drawText:(NSAttributedString *)textToDraw inFrame:(CGRect)frameRect bkgColor:(UIColor *)backgroundColor {
CFAttributedStringRef currentText = (__bridge CFAttributedStringRef)(textToDraw);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);
// Draw background when a color is set
if (backgroundColor) {
[backgroundColor set];
CGRect backgroundFrame = CGRectMake(frameRect.origin.x, frameRect.origin.y -backgroundOffset, frameRect.size.width, frameRect.size.height -3);
//CGRect backgroundFrame = CGRectMake(frameRect.origin.x, frameRect.origin.y -2, frameRect.size.width, frameRect.size.height -3);
CGContextFillRect( UIGraphicsGetCurrentContext(), backgroundFrame);
[[UIColor whiteColor] set];
}
CGMutablePathRef framePath = CGPathCreateMutable();
CGPathAddRect(framePath, NULL, frameRect);
// Get the frame that will do the rendering.
CFRange currentRange = CFRangeMake(0, 0);
CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
CGPathRelease(framePath);
// Get the graphics context.
CGContextRef currentContext = UIGraphicsGetCurrentContext();
// Put the text matrix into a known state so no old scaling factors are left in place.
CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);
int adjust = frameRect.origin.y * 2 + frameRect.size.height;
// Core Text draws from the bottom-left corner up, so flip
// the current transform prior to drawing.
CGContextTranslateCTM(currentContext, 0, adjust);
CGContextScaleCTM(currentContext, 1.0, -1.0);
// Draw the frame.
CTFrameDraw(frameRef, currentContext);
CGContextScaleCTM(currentContext, 1.0, -1.0);
CGContextTranslateCTM(currentContext, 0, (-1)*adjust);
CFRelease(frameRef);
CFRelease(framesetter);
backgroundColor = nil;
}