Skip to content

Instantly share code, notes, and snippets.

@orklann
Created February 17, 2021 09:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save orklann/c1e3a13f21904a15aed12e72598f3f39 to your computer and use it in GitHub Desktop.
Save orklann/c1e3a13f21904a15aed12e72598f3f39 to your computer and use it in GitHub Desktop.
Old method of getting glyph advance
CGFloat getGlyphAdvanceForFont(NSString *ch, NSFont *font) {
// Handle tab character width, because it's not correct to get it with
// CTRunGetAdvances().
if ([ch isEqualToString:@"\t"]) {
// NOTE: (TAB) This clause will never reach because when a \t is entered,
// We convert it into a ' '.
// But I will leave this code her for alternative method to
// get glyph width
CGRect rect;
CGFontRef cgFont = CTFontCopyGraphicsFont((CTFontRef)font, nil);
CGGlyph g = CGFontGetGlyphWithGlyphName(cgFont, (CFStringRef)@"\t");
CGFontGetGlyphBBoxes(cgFont, &g, 1, &rect);
CGFloat hAdvance = rect.size.width / CGFontGetUnitsPerEm(cgFont) * font.pointSize;
NSLog(@"*(TAB) width:%f", hAdvance);
return hAdvance;
}
NSMutableAttributedString *s = [[NSMutableAttributedString alloc] initWithString:ch];
[s addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, 1)];
[s addAttribute:NSForegroundColorAttributeName value:[NSColor blackColor] range:NSMakeRange(0, 1)];
CFAttributedStringRef attrStr = (__bridge CFAttributedStringRef)(s);
CTLineRef line = CTLineCreateWithAttributedString(attrStr);
CFArrayRef runs = CTLineGetGlyphRuns(line);
CTRunRef firstRun = CFArrayGetValueAtIndex(runs, 0);
CGSize size;
CTRunGetAdvances(firstRun, CFRangeMake(0, 1), &size);
CFRelease(line);
return size.width;
}
NSRect getGlyphBoundingBox(NSString *ch, NSFont *font, CGAffineTransform tm) {
CGFloat glyphWidth = getGlyphAdvanceForFont(ch, font);
NSMutableAttributedString *s = [[NSMutableAttributedString alloc]
initWithString:ch];
[s addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, [ch length])];
[s addAttribute:NSForegroundColorAttributeName value:[NSColor blackColor]
range:NSMakeRange(0, [ch length])];
CFAttributedStringRef attrStr = (__bridge CFAttributedStringRef)(s);
CTLineRef line = CTLineCreateWithAttributedString(attrStr);
CGFloat ascent, descent, leading;
CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
CGRect textRect = NSMakeRect(0, 0 - descent, glyphWidth, descent + ascent);
CGRect r = CGRectApplyAffineTransform(textRect, tm);
CFRelease(line);
return r;
}
NSRect getGlyphBoundingBoxGlyphSpace(NSString *ch, NSFont *font) {
CGFloat glyphWidth = getGlyphAdvanceForFont(ch, font);
NSMutableAttributedString *s = [[NSMutableAttributedString alloc]
initWithString:ch];
[s addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, [ch length])];
[s addAttribute:NSForegroundColorAttributeName value:[NSColor blackColor]
range:NSMakeRange(0, [ch length])];
CFAttributedStringRef attrStr = (__bridge CFAttributedStringRef)(s);
CTLineRef line = CTLineCreateWithAttributedString(attrStr);
CGFloat ascent, descent, leading;
CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
CGRect textRect = NSMakeRect(0, 0 - descent, glyphWidth, descent + ascent);
CFRelease(line);
return textRect;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment