Balance

Check out this code I was using for calculating text widths in my iPhone app’s PDF generator class (the first comment with the asterisks was added by me for this posting):

- (CGFloat)calculateTextWidth:(NSString *)text 
{ 
    // ********** do not use this method, see below for the fix **********
    CGSize fullSize = [UIScreen mainScreen].applicationFrame.size; 
    UIGraphicsBeginImageContext(fullSize);
    CGContextRef context = UIGraphicsGetCurrentContext();
 
    // calculate the text size
    CGContextSelectFont(context, [fontName UTF8String], fontSize, kCGEncodingMacRoman);
    CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0, -1.0));
    CGContextSetTextDrawingMode(context, kCGTextInvisible);
 
    // measure the text
    CGPoint initialTextPosition = CGContextGetTextPosition(context);
    CGContextShowTextAtPoint(context, 0, 0, [text cStringUsingEncoding:NSASCIIStringEncoding], text.length);
    CGPoint finalTextPosition = CGContextGetTextPosition(context);
 
    return finalTextPosition.x - initialTextPosition.x;
}

Pretty awesome, huh? Well, it worked awesome, my right justified text labels were all lining up great. The problem was that I could do one PDF in the app, maybe two, and the app would throw all kinds of memory warnings and then crash.

Well, as it turns out, it is a good idea to use a UIGraphicsEndImageContext() call when you use a UIGraphicsBeginImageContext() call. After I did this, all was right with the world.

Here is the finished product:

- (CGFloat)calculateTextWidth:(NSString *)text 
{ 
    CGSize fullSize = [UIScreen mainScreen].applicationFrame.size; 
    UIGraphicsBeginImageContext(fullSize);
    CGContextRef context = UIGraphicsGetCurrentContext();
 
    // calculate the text size
    CGContextSelectFont(context, [fontName UTF8String], fontSize, kCGEncodingMacRoman);
    CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0, -1.0));
    CGContextSetTextDrawingMode(context, kCGTextInvisible);
 
    // measure the text
    CGPoint initialTextPosition = CGContextGetTextPosition(context);
    CGContextShowTextAtPoint(context, 0, 0, [text cStringUsingEncoding:NSASCIIStringEncoding], text.length);
    CGPoint finalTextPosition = CGContextGetTextPosition(context);
 
    UIGraphicsEndImageContext();  // !!!!!
 
    return finalTextPosition.x - initialTextPosition.x;
}

BTW, Happy Birthday to Zuleikha Robinson. I miss the boys (and Yves, obviously) from The Lone Gunmen, I wish the show could have gone more than the 1/2 season it lasted.

Leave a Reply