Skip to content

Instantly share code, notes, and snippets.

@citrus-lemon
Created July 10, 2016 15:14
Show Gist options
  • Save citrus-lemon/d4e19e1115c80d28e4ee115e3aaa3a78 to your computer and use it in GitHub Desktop.
Save citrus-lemon/d4e19e1115c80d28e4ee115e3aaa3a78 to your computer and use it in GitHub Desktop.
//:# Playground - TrueType Font Analysis
import Cocoa
import XCPlayground
var char: Character = "书"
var font = CTFontCreateWithName("Weibei SC", 100, nil)
func findGlyph(str: String, font: CTFont) -> CGGlyph {
let cfstr: CFString = str
let length = CFStringGetLength(cfstr)
let us = UnsafeMutablePointer<UniChar>.alloc(length)
CFStringGetCharacters(cfstr, CFRangeMake(0, length), us)
let gly = UnsafeMutablePointer<CGGlyph>.alloc(length)
CTFontGetGlyphsForCharacters(font, us, gly, length)
return gly[0]
}
//:### Font Properites
let glyph = findGlyph(String(char), font: font)
let ascent = CTFontGetAscent(font)
let descent = CTFontGetDescent(font)
let leading = CTFontGetLeading(font)
let unitPerEm = CTFontGetUnitsPerEm(font)
let glyphCount = CTFontGetGlyphCount(font)
let boundingBox = CTFontGetBoundingBox(font)
let underlinePosition = CTFontGetUnderlinePosition(font)
let underlineThickness = CTFontGetUnderlineThickness(font)
let slantAngle = CTFontGetSlantAngle(font)
let CapHeight = CTFontGetCapHeight(font)
let XHeight = CTFontGetXHeight(font)
let PathForGlyph = CTFontCreatePathForGlyph(font, glyph, nil)
let boundingRects = UnsafeMutablePointer<CGRect>.alloc(1)
CTFontGetBoundingRectsForGlyphs(font, CTFontOrientation.Default, [glyph], boundingRects, 1)
let advances = UnsafeMutablePointer<CGSize>.alloc(1)
CTFontGetAdvancesForGlyphs(font, CTFontOrientation.Default, [glyph], advances, 1)
class textView: NSView {
override func drawRect(rect: CGRect) {
let thisContext = NSGraphicsContext.currentContext()?.CGContext
CGContextSetRGBFillColor(thisContext, 0.95, 0.95, 0.95, 1)
CGContextFillRect(thisContext, rect)
let basePoint = CGPointMake(100, 100)
CGContextSetLineWidth(thisContext, 2)
CGContextSetRGBStrokeColor(thisContext, 1, 0, 0, 1)
CGContextAddLines(thisContext, [CGPointMake(0, basePoint.y), CGPointMake(rect.width, basePoint.y)], 2)
CGContextStrokePath(thisContext)
CGContextSetLineWidth(thisContext, 1)
CGContextSetRGBStrokeColor(thisContext, 0, 1, 0, 1)
CGContextAddLines(thisContext, [CGPointMake(0, basePoint.y + CapHeight), CGPointMake(rect.width, basePoint.y + CapHeight)], 2)
CGContextStrokePath(thisContext)
CGContextSetRGBStrokeColor(thisContext, 0, 1, 0, 1)
CGContextAddLines(thisContext, [CGPointMake(0, basePoint.y + XHeight), CGPointMake(rect.width, basePoint.y + XHeight)], 2)
CGContextStrokePath(thisContext)
CGContextSetRGBStrokeColor(thisContext, 0, 1, 0, 1)
CGContextAddLines(thisContext, [CGPointMake(0, basePoint.y + ascent), CGPointMake(rect.width, basePoint.y + ascent)], 2)
CGContextStrokePath(thisContext)
CGContextSetRGBStrokeColor(thisContext, 0, 1, 0, 1)
CGContextAddLines(thisContext, [CGPointMake(0, basePoint.y - descent), CGPointMake(rect.width, basePoint.y - descent)], 2)
CGContextStrokePath(thisContext)
CGContextSetRGBStrokeColor(thisContext, 0, 1, 0, 1)
CGContextAddLines(thisContext, [CGPointMake(0, basePoint.y - descent - leading), CGPointMake(rect.width, basePoint.y - descent - leading)], 2)
CGContextStrokePath(thisContext)
CGContextSetRGBStrokeColor(thisContext, 0, 0, 1, 1)
CGContextStrokeRect(thisContext, CGRectOffset(boundingBox, basePoint.x, basePoint.y))
CGContextStrokeRect(thisContext, CGRectOffset(boundingRects[0], basePoint.x, basePoint.y))
CGContextStrokeRect(thisContext, NSRect(origin: basePoint, size: advances[0]))
let unionrect = CGRectUnion(CGRectOffset(boundingRects[0], basePoint.x, basePoint.y), NSRect(origin: basePoint, size: advances[0]))
CGContextStrokeRect(thisContext, unionrect)
CGContextSetRGBStrokeColor(thisContext, 1, 0, 1, 0.7)
CGContextAddLines(thisContext, [CGPointMake(unionrect.origin.x, ascent + basePoint.y + 20), CGPointMake(unionrect.origin.x, basePoint.y - descent - 25)], 2)
CGContextAddLines(thisContext, [CGPointMake(unionrect.origin.x + unionrect.width, ascent + basePoint.y + 20), CGPointMake(unionrect.origin.x + unionrect.width, basePoint.y - descent - 25)], 2)
CGContextAddLines(thisContext, [CGPointMake(unionrect.origin.x - 20, ascent + basePoint.y), CGPointMake(unionrect.origin.x + unionrect.width + 20, ascent + basePoint.y)], 2)
CGContextAddLines(thisContext, [CGPointMake(unionrect.origin.x - 20, basePoint.y - descent), CGPointMake(unionrect.origin.x + unionrect.width + 20, basePoint.y - descent)], 2)
CGContextStrokePath(thisContext)
CGContextSetRGBFillColor(thisContext, 0, 0, 0, 1)
CGContextSetRGBStrokeColor(thisContext, 0, 0, 0, 1)
CGContextAddPath(thisContext, CGPathCreateCopyByTransformingPath(PathForGlyph, [CGAffineTransformMakeTranslation(basePoint.x, basePoint.y)]))
CGContextFillPath(thisContext)
}
}
textView(frame: NSRect(x: 0, y: 0, width: 600, height: 200))
XCPShowView("textView", view: textView(frame: NSRect(x: 0, y: 0, width: 600, height: 600)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment