Why does drawing with CoreText look different than UILabel?
Asked Answered
V

3

8

I'm using TTTAttributedLabel (which uses CoreText) instead of a UILabel to be able to bold certain parts. It works great but the text doesn't look the same. It looks like it's using a different font. I've set it to be the same font (Helvetica) but one is a CTFont and one is a UIFont. Why do they look different?

  • Here's the UIFont for the UILabel: [UIFont systemFontOfSize:15]
  • Here's the CTFont for CoreText: CTFontCreateWithName((__bridge CFStringRef)[UIFont systemFontOfSize:15].fontName, 15, NULL)

UILabel Screenshot:

enter image description here

CoreText Screenshot:

enter image description here

The 'p' and the 'o' in "promenade" is the easiest part to see the font doesn't look the same. Letters are more round in the CoreText version.

Veil answered 16/11, 2011 at 20:39 Comment(3)
Show how you set the font. Maybe the bold name is wrong.Camilacamile
@DavidDunham Hi David, I added how I get the fonts. The original label wasn't bolded. The non bold text is what I'm comparing and they definitely look different. I'll add a screen shot.Veil
OK, that rules out some possibilities. (Which means I can’t think of anything to suggest.)Camilacamile
G
9

UILabel uses WebKit style text-rendering that takes shortcuts in accuracy to improve drawing performance. CoreText (originally from OS X) takes the opposite, render exactly and as perfectly as possible at the expense of performance.

For iOS apps, reserve CoreText for only the most visibly critical UI (such as a headline) and where you can potentially cache the rendered output.

Gooseberry answered 8/12, 2011 at 1:30 Comment(2)
thanks jarjar, both this answer and adam's sounded good, but this helped me understand more.Veil
Does it mean I can get the exactly same text rendering in UIWebView as that in UILabel, and I can never get as good performance as UILabel with Core Text?Cloudcapped
A
8

I spent a while trying to solve this problem too, and I think I've got it. From what I've tested so far, your CoreText rendering will look identical to the rendering you see on UILabel, UITextView, etc, by setting kerning to zero:

NSNumber *kern = [NSNumber numberWithFloat:0];
NSRange full = NSMakeRange(0, [attributedText string].length);
[attributedText addAttribute:(id)kCTKernAttributeName value:kern range:full];

This is really strange behavior, and I can't say I know why it's happening, but this is what Apple seems to be doing. (It actually increased spacing in some places, like in between 'Te'.)

Tested on iOS 5.1.

Anatolian answered 20/3, 2012 at 22:44 Comment(1)
Very interesting. Perhaps this explains the width and jarjar's answer explains the subtle letter changes. The height is a little different too, so maybe that just needs to be adjusted as well.Veil
I
3

I'm pretty sure it's because Core Text has more advanced rendering (kerning and spacing improvements, and so forth). I'm sorry I can't dig up any docs to prove this, but it's the general feel I get from it.

The bottom line is, you can't count on getting the same measurements between Core Text and UILabel and the other UIKit APIs. They use different layout and spacing code.

Indeciduous answered 5/12, 2011 at 15:36 Comment(1)
thanks adam, that makes sense. both your answer and jarjar's helped.Veil

© 2022 - 2024 — McMap. All rights reserved.