1

Text drawn using Cocoa (OS X) in CALayer and CATextLayer comes out all grainy. What method/approach must be used to get the text to come out crisp/clear?

I am happy for the text to be backed by an opaque background - I know that the question would be even more complex if it needed to be transparent.

I can't use an NSView derived instance (like NSTextField) to represent the text in my solution - I am using CALayer because of its more lightweight nature.

EDIT

I am updating with code I have tried based on comments below:

The following is intended to be a custom CATextLayer class where the background color is being pre-set to be opaque prior to the text being composed with it such that sub-pixel anti aliasing can take place:

class TextLayer: CATextLayer {

    override func drawInContext(ctx: CGContext!) {

        CGContextSaveGState(ctx)

        CGContextSetRGBFillColor (ctx, 1, 1, 1, 1)
        CGContextFillRect (ctx, self.bounds)
        CGContextSetShouldSmoothFonts (ctx, true)
        super.drawInContext(ctx)

        CGContextSaveGState(ctx)
    }
}

This custom derived CATextLayer is then used in a custom view as follows:

    override func awakeFromNib() {

    self.wantsLayer = true
    var backingLayer = self.layer
    var textLayer = TextLayer()
    textLayer.string = "ABC"
    textLayer.fontSize = 16
    textLayer.foregroundColor = NSColor.blackColor().CGColor
    textLayer.frame = NSMakeRect(0, 0, 80, 40)

    backingLayer?.addSublayer(textLayer)
    textLayer.setNeedsDisplay()
}

The end result is STILL a grainy picture on my retina macBook Pro.

Muhammad Nabeel Arif
  • 19,140
  • 8
  • 51
  • 70
Sam
  • 2,745
  • 3
  • 20
  • 42
  • 1
    Have you tried the solution in [this question](http://stackoverflow.com/questions/715750/ugly-looking-text-when-drawing-nsattributedstring-in-cgcontext)? it seems to point to this [cocoa builder articlw](http://www.cocoabuilder.com/archive/cocoa/202561-catextlayer-and-subpixel-anti-aliasing.html) which accomplish what you're trying to accomplish – Anya Shenanigans Feb 12 '15 at 17:53
  • @Petesh thanks for the link. As you will see in my edit above, I tried the suggestion but it didn't give the desired result! – Sam Feb 12 '15 at 22:02

1 Answers1

5

Playing around with a few properties on CALayer yielded the solution...

For the code above to render the fonts smoothly and in-line with others on a retina mac it appears that you also need to set:

textLayer.contentsScale = 2.0

in the NSView subclass.

My understanding is that this generates a more detailed bitmap from the underlying image that more closely matches the Retina capable hardware.

Sam
  • 2,745
  • 3
  • 20
  • 42