Skip to content

Instantly share code, notes, and snippets.

@typemytype
Created April 6, 2020 12:56
Show Gist options
  • Select an option

  • Save typemytype/df54f2413a2bc45b2408cb4a5e7aba9d to your computer and use it in GitHub Desktop.

Select an option

Save typemytype/df54f2413a2bc45b2408cb4a5e7aba9d to your computer and use it in GitHub Desktop.
import AppKit
import CoreText
x, y, w, h = 100, 100, 300, 500
f = FormattedString()
f.fontSize(12)
f += "hello"
f.fill(1, 0, 0)
f += "qsdfqsdf"
f.font("Helvetica-Oblique")
f += "foo"
f.fontSize(42)
f += "bar"
textBox(f, (x, y, w, h))
###
runData = list()
path = CoreText.CGPathCreateMutable()
CoreText.CGPathAddRect(path, None, CoreText.CGRectMake(x, y, w, h))
attrString = f.getNSObject()
txt = attrString.string()
setter = CoreText.CTFramesetterCreateWithAttributedString(attrString)
frame = CoreText.CTFramesetterCreateFrame(setter, (0, 0), path, None)
ctLines = CoreText.CTFrameGetLines(frame)
origins = CoreText.CTFrameGetLineOrigins(frame, (0, len(ctLines)), None)
for i, (originX, originY) in enumerate(origins):
ctLine = ctLines[i]
ctRuns = CoreText.CTLineGetGlyphRuns(ctLine)
for ctRun in ctRuns:
stringRange = CoreText.CTRunGetStringRange(ctRun)
runPos = CoreText.CTRunGetPositions(ctRun, (0, 1), None)[0]
runW, runH, ascent, _ = CoreText.CTRunGetTypographicBounds(ctRun, (0, 0), None, None, None)
runTxt = txt.substringWithRange_((stringRange.location, stringRange.length))
runData.append(((x+originX + runPos.x, y + originY + runPos.y, runW, runH), runTxt))
fill(random(), random(), random(), .5)
rect(x+originX + runPos.x, y + originY + runPos.y - ascent, runW, runH + ascent)
print(runData)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment