1
votes

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.

1
Have you tried the solution in this question? it seems to point to this cocoa builder articlw which accomplish what you're trying to accomplishPetesh
@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

1 Answers

4
votes

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.