10

I am trying to create an app that scales up nicely on the iPhone 4. Currently most of it scales up perfectly, except for one crucial piece: the text that I draw inside a CALayer, inside its drawInContext: method. Here is my code:

- (void)drawInContext:(CGContextRef)context {
    UIGraphicsPushContext(context);

    CGContextSetGrayFillColor(context, 1.0f, 1.0f);
    CGContextFillRect(context, self.bounds);

    CGContextSetAllowsAntialiasing(context, true);
    CGContextSetShouldAntialias(context, true);

    CGContextSetAllowsFontSmoothing(context, true);
    CGContextSetShouldSmoothFonts(context, true);

    CGContextSetAllowsFontSubpixelQuantization(context, true);
    CGContextSetShouldSubpixelQuantizeFonts(context, true);

    CGContextTranslateCTM(context, 0.0f, self.frame.size.height);
    CGContextScaleCTM(context, 1.0f, -1.0f);

    CGContextSetFillColorWithColor(context, [[UIColor blackColor] CGColor]);
    CGContextSelectFont(context, "CardKit", 30.0f, kCGEncodingMacRoman);
    CGContextSetTextDrawingMode(context, kCGTextFill);
    CGContextShowText(context, "A", sizeof("A"));

    UIGraphicsPopContext();
}

This short produce crisp text on both devices, but unfortunately, it produces blurry text on both. Here is how it appears:

ugly text http://files.droplr.com.s3.amazonaws.com/files/16285043/1gBp61.Screen%20shot%202010-06-26%20at%2021:25:09.png

That image is taken at 100% zoom on the iPhone 4. What in the world? Any ideas how I can fix this?

Carter Allen
  • 1,984
  • 15
  • 22
  • this is just a guess to look into, I haven't tried to see what it does. You are currently using 30pt font, you could test the size of the string with 60pt font via (CGSize)sizeWithFont:(UIFont *)font and if the width is within your size target rect then draw using 60pt and if not then draw using 30pt. the iphone4 screen is a direct 2x of the iphone screen, so I'm just guessing that rendering text at twice the point size might work. – scottbates22 Jul 06 '10 at 17:04
  • That just makes the letter get cut off. See: http://zcr.me/01g Still blurry. Just bigger. – Carter Allen Jul 11 '10 at 22:48

3 Answers3

28

You should set the layer's contentsScale to be the same as the scale of your screen:

layer.contentsScale = [UIScreen mainScreen].scale;

This will scale it correctly on all iOS devices, Retina Display and non-Retina Display. You shouldn't hard-code it to 2.0 (or anything else for that matter) unless you have a good reason to do so.

Nick Forge
  • 21,344
  • 7
  • 55
  • 78
2

Since you're dealing with CALayers, you need to set the contentsScale property of your layer to 2.0.

See this section in the iPhone Application programming guide for iOS 4.

Ben Lings
  • 28,823
  • 13
  • 72
  • 81
Jason Foreman
  • 2,146
  • 18
  • 15
  • what happens for non retina display ? Will the text be 50% smaller ? – thierryb Aug 21 '10 at 18:27
  • 1
    Yes, it will appear at the wrong scale (which makes this answer incorrect). To render images that will display correctly on either a Retina or non-Retina display, you should use the `-[UIScreen scale]` property to determine the correct value of `contentsScale`. See my answer to this question… – Nick Forge Feb 13 '11 at 03:33
2

The link of the previous answer is broken now. New link is this one.

Jean-Pierre Matsumoto
  • 1,917
  • 1
  • 18
  • 26