High-quality offscreen rendering of text?
High-quality offscreen rendering of text?
- Subject: High-quality offscreen rendering of text?
- From: Jens Alfke <email@hidden>
- Date: Sun, 06 Oct 2013 13:15:17 -0700
My little Mac font-preview app displays swatches of zillions of different fonts, which is expensive. To speed it up, I’m rendering each font’s preview text into an NSImage and caching that, then just blitting the image in the view’s -drawRect: method.
The method I’m using is -[NSImage imageWithSize:flipped:drawingHandler:], which is fairly new (added in 10.8). It’s very easy to use — I just put my font-drawing code in the block — and automatically supports Retina displays. But I’m having a couple of issues.
(1) On a non-retina display, the text quality is poor. It looks like it’s drawn without sub-pixel anti-aliasing (“ClearType”). I do remember hearing that this mode is disabled for offscreen drawing, which makes sense because different LCDs have different sub-pixel layouts and of course CRTs don’t have any. But since the NSImage method I’m using customizes the rendering for each display, I was hoping it’d use ClearType. Is there any way I can get this to work? After all, the whole purpose of this app is to display fonts, so I want the best quality possible.
(2) I get a warning logged when I draw the image: "-[NSImage compositeToPoint:fromRect:operation:] is deprecated in MacOSX 10.8 and later. Please use -[NSImage drawAtPoint:fromRect:operation:fraction:] instead.” But if I change my drawing call to the one suggested, it breaks the image caching — my drawingHandler block gets invoked *every time* the image is drawn, which totally negates the performance improvement and makes scrolling very slow. [At least, this is what happens on my retina display.] So I’ve gone back to the original call and am living with the one-time warning. (Is this an AppKit bug?)
(3) Performance is reasonable, but I’d prefer to render the text in a background thread to avoid jankiness in scrolling. I can’t do that with the NSImage method I’m using, though, because I have no control over when the block is called. So it seems like I’ll need to go back to the old ways: creating an image, calling -lockFocus and then drawing into it. I don’t think I’ve ever done this in a background thread before — is it thread-safe? Or do I need to drop down to raw CG calls?
Thanks!
—Jens
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden