Last active
January 10, 2023 05:22
-
-
Save warpling/95b18be18a48150569ad9953dd717758 to your computer and use it in GitHub Desktop.
AttributedString to UIBezierPath
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension UIBezierPath { | |
// Source: https://github.com/aderussell/string-to-CGPathRef/blob/0bd9350dc2100029f3ddb8d9667384841549ecd6/ARCGPathFromString/ARCGPathFromString.m | |
convenience init(attributedString: NSAttributedString) { | |
let letters = CGMutablePath() | |
let line = CTLineCreateWithAttributedString(attributedString as CFAttributedString) | |
let runArray = CTLineGetGlyphRuns(line) | |
// for each RUN | |
for runIndex in 0..<CFArrayGetCount(runArray) { | |
// Get FONT for this run | |
let run = unsafeBitCast(CFArrayGetValueAtIndex(runArray, runIndex), to: CTRun.self) | |
let runFontValue = CFDictionaryGetValue(CTRunGetAttributes(run), unsafeBitCast(kCTFontAttributeName, to: UnsafeRawPointer.self)) | |
let runFont = unsafeBitCast(runFontValue, to: CTFont.self) | |
// for each GLYPH in run | |
for runGlyphIndex in 0..<CTRunGetGlyphCount(run) { | |
// get Glyph & Glyph-data | |
let thisGlyphRange = CFRangeMake(runGlyphIndex, 1) | |
var glyph: CGGlyph = CGGlyph() | |
var position: CGPoint = .zero | |
CTRunGetGlyphs(run, thisGlyphRange, &glyph) | |
CTRunGetPositions(run, thisGlyphRange, &position) | |
// Get PATH of outline | |
do { | |
var glyphTransform = CGAffineTransform(translationX: position.x, y: position.y) | |
if let letter = CTFontCreatePathForGlyph(runFont, glyph, &glyphTransform) { | |
// The glyph will initially be upsidedown because CoreText works in an inverted coordinate system. | |
// After flipping we need to move the glyph back down. | |
let t = CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: -letter.boundingBoxOfPath.height) | |
// Because we flipped the text with a transform the drawing direction of the path is unexpectedly reversed | |
// This will reverse it back to make evenOdd binary path operations behave as expected | |
let reverseWindingLetter = UIBezierPath(cgPath: letter).reversing().cgPath | |
letters.addPath(reverseWindingLetter, transform: t) | |
} | |
} | |
} | |
} | |
self.init(cgPath: letters.copy()!) | |
} | |
} |
` let myAttribute = [ NSAttributedString.Key.foregroundColor: UIColor.blue, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 50) ]
let myAttrString = NSAttributedString(string: "A", attributes: myAttribute)
let path = UIBezierPath(attributedString: myAttrString)
print(path)
let pathLayer = CAShapeLayer()
pathLayer.frame = self.viewLayer.bounds
pathLayer.bounds = path.cgPath.boundingBox
pathLayer.backgroundColor = UIColor.red.cgColor
pathLayer.isGeometryFlipped = false
self.viewLayer.layer.addSublayer(pathLayer)`
I used this code
Perhaps you need to set fillColor instead of backgroundColor for it to show up?
Not working By using fill color and stroke color both I used but not showing path
I don't know why I didn't notice it the first time but you aren't assigning the path to the layer's path!! 😆
pathLayer.path = path.cgPath
Thanks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I tried but not created path. Can you please share how to use?