Measuring glyphs on iOS

Between Resume Designer and Unicode Character Viewer, I’ve done a fair bit of laying out text by hand on iOS.

Part of laying out text is measuring it. And iOS sucks at that.

Here are two examples.

In Resume Designer, I’m using CTFramesetterSuggestFrameSizeWithConstraints to measure paragraphs and then drawing into that frame.  I noticed that occasionally (but not always), the last line of text would go missing.  It just wouldn’t fit into the “suggested” frame.

If you search for CTFramesetterSuggestFrameSizeWithConstraints, the first four results you find are people having the same problem.

The solution is simply to pad the height a bit.  That’s what I ended up doing, and that cleared up my problem.

NewImage

The second example is in Unicode Character Viewer.  The purpose of this app is to make it easy to find beautiful glyphs in the fonts that come with iOS.  I’m sure the market for this sort of thing is very small (maybe just me) but I wanted a way to simply browse glyphs.

Part of this is drawing the glyph, and part of drawing it is I need the extent.  Simple enough, right?  [NSString sizeWithFont:] should tell me how big the glyph is.  Except it doesn’t.

That’s a screenshot of the app showing a particular glyph, that doesn’t fit into the rectangle that [NSString sizeWithFont:] returns. There are lots of these edge cases, particularly in swoopy fonts like SnellRoundhand and Zapfino.

Figuring there must be a way, I used one of my two-per-year Apple support cases to ask Apple what the right way to do this is.  The first answer I got seemed promising.

The suggestion was to drop to using Core Text to measure instead of UIKit, and use CTLineGetBoundsWithOptions, passing kCTLineBoundsUseGlyphPathBounds as an option.  This is new to iOS 6, which seemed promising.

And that did fix the problem for the sample glyph with SnellRoundhand, but when I tried the same glyph with Zapfino, it still extended beyond the measured bounds.

I bounced this off Apple and the response I got?

“We don’t have an API that is perfectly reliable for getting the glyph bounds for all the fonts”

So for all the great text support in iOS (and it really is great), the one thing it can’t do is reliably tell you how big the text is going to be.

In my Unicode app I contemplated measuring the glyphs myself by drawing them into a much bigger rectangle and then cropping to non-whitespace, but in the end I think just adding enough arbitrary padding will suit my purposes.  

Anyway, hopefully if you run across this post because your glyph measuring seems broken, I can save you a few hours of research and just give you a Jim Dalrymple style answer, “Yep”.

 

Leave a Reply