Skip to content

Instantly share code, notes, and snippets.

@jwilling
Created January 3, 2014 01:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jwilling/8230765 to your computer and use it in GitHub Desktop.
Save jwilling/8230765 to your computer and use it in GitHub Desktop.
Better string metrics on OS X.
#import <Foundation/Foundation.h>
@interface NSString (IBNMetrics)
- (CGSize)ibn_sizeConstrainedToSize:(CGSize)size font:(NSFont *)font;
- (CGSize)ibn_sizeWithFont:(NSFont *)font;
@end
#import "NSString+IBNMetrics.h"
@implementation NSString (IBNMetrics)
- (CGSize)ibn_sizeWithFont:(NSFont *)font {
return [self ibn_sizeConstrainedToSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX) font:font];
}
- (CGSize)ibn_sizeConstrainedToSize:(CGSize)size font:(NSFont *)font {
CTFontRef coreTextFont = CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize, NULL);
CGFloat leading = font.leading;
CTParagraphStyleSetting paragraphSettings[1] = { kCTParagraphStyleSpecifierLineSpacingAdjustment, sizeof(CGFloat), &leading };
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(paragraphSettings, 1);
CFRange textRange = CFRangeMake(0, self.length);
CFMutableAttributedStringRef mutableString = CFAttributedStringCreateMutable(kCFAllocatorDefault, self.length);
CFAttributedStringReplaceString(mutableString, CFRangeMake(0, 0), (CFStringRef)self);
CFAttributedStringSetAttribute(mutableString, textRange, kCTFontAttributeName, coreTextFont);
CFAttributedStringSetAttribute(mutableString, textRange, kCTParagraphStyleAttributeName, paragraphStyle);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(mutableString);
CFRange fitRange;
CGSize frameSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, textRange, NULL, size, &fitRange);
CFRelease(coreTextFont);
CFRelease(paragraphStyle);
CFRelease(framesetter);
CFRelease(mutableString);
return frameSize;
}
@end
@tonyarnold
Copy link

This seems to chop off descenders:

Image of chopped off descenders

@jwilling
Copy link
Author

@tonyarnold Thanks for that, I think I didn't actually try this out with multi-line text. I'll look into this more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment