Search code examples
objective-ccocoacore-animationcalayernsview

Bad text rendering with Core Animation


First of all, I know this topic has been brought up several times before but I'm posting this question because none of the "solutions" I've used in the past have worked in this specific case. I'm drawing some text to a CALayer that is hosted by a view inside my NSToolbar. Here's what the text look likes:

Font smoothing on

I tried using a suggestion from this StackOverflow post, which is to call CGContextSetShouldSmoothFonts(ctx, false) to turn off subpixel antialiasing before drawing into the context. This is a solution that has given me acceptable results in the past, but in this case it seems to have made the text look even worse:

Font smoothing off

The other solution mentioned in that post is to fill the rect with an opaque background color before drawing, which simply isn't possible in this case because the toolbar background is a gradient. Is there anything I can do to make this text look as nice as text drawn into a plain NSView?


Solution

  • Unfortunately there's no magic fix. At the end of the day, the text must be drawn on to an opaque background to get SPAA. It sucks, but it makes a lot of sense given how layers work. And honestly, I can't see Apple ever "fixing" this. I think this is the reason they've stuck with the old software compositing model for so long. It's a hard problem and they're hoping to ignore it by going high-DPI.

    But anyways, there are a few ways to get SPAA in your specific case.

    You could try to re-create the gradient and draw it yourself when you draw your text. But obviously that's brittle if the toolbar gradient changes in an OS update, and it could be hard to get the gradient to match exactly right.

    Or you could actually try to grab an image of the toolbar background, either at runtime or ahead of time, and draw that as your background.