18

Trying to understand why am I getting low quality drawing with CGContextShowTextAtPoint? See attached image: img

The letter "W" is drawn using CGContextShowTextAtPoint on a CALayer and looks very pixelized. The button next to it is a standard button and looks high res as expected. I would like to get the text drawing to be hi-res.

enter image description here

vance
  • 1,071
  • 11
  • 19

4 Answers4

37

By default, your CALayer is not rendering its Quartz content at the higher resolution of the Retina display screen. You can enable this using code like the following:

if ([layer respondsToSelector:@selector(setContentsScale:)])
{
    layer.contentsScale = [[UIScreen mainScreen] scale];
}

This will affect not just text rendering, but all of your Quartz drawing within CALayers, so you'll need to do this for all of your layers with custom Quartz content.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
  • 1
    I don't see contentScaleFactor on CALayer – vance Mar 25 '11 at 04:17
  • 1
    Thanks, it is contentsScale on a CALayer: CGFloat scale = [[UIScreen mainScreen] scale]; self.contentsScale = scale; – vance Mar 25 '11 at 04:33
  • Actually, setting the contentsScale make the image look *very* blurry. See seconds attached image. – vance Mar 25 '11 at 04:38
  • 3
    @vance - You're right. I'd copied that code from the wrong place, referring to a UIView and not a CALayer (it's fixed now). The blurriness is most likely due to either a pixel misalignment of your layer or drawing, or a transform being applied after your text is rendered. Make sure that the contentsScale is set before your layer first displays its content, or use a `-setNeedsDisplay` afterward. Make sure that your layer has its origin on integral pixel coordinates. Remember when drawing within the layer using Quartz that you want to align on half-pixel coordinates, not integral ones. – Brad Larson Mar 25 '11 at 14:55
  • Chiming in 9 years later –– the solution for me was two things: 1) Adjust the scale factor like in this answer. 2) Set `myTextLayer.shouldRasterize = false` – Matt H. Aug 17 '20 at 06:45
6

Does using CGContextScaleCTM deliver any results for you? When working with a graphics context, something like this:

CGFloat scale = [[UIScreen mainScreen] scale];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextScaleCTM(context, scale, scale);
Matt Bishop
  • 1,010
  • 7
  • 18
2

Swift version:

textLayer.contentsScale = UIScreen.mainScreen().scale

enter image description here

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
1

A group of functions controls how Core Graphics renders fonts:

  • CGContextSetAllowsAntialiasing
  • CGContextSetAllowsFontSmoothing
  • CGContextSetAllowsFontSubpixelPositioning
  • CGContextSetAllowsFontSubpixelQuantization
Steve
  • 31,144
  • 19
  • 99
  • 122