Please how can we get path of particular arabic of french letter ? I've just found out that CTFontCreatePathForGlyph will give CGPathRef like, but its will be the outline of text .
I need this real text path for showing a text drawing animation..
any help please
You dont require ur path to be converted into NSString at all.
You can create the path for text as follows:
CTFontRef font = CTFontCreateWithName(CFSTR("Helvetica-Bold"), 72.0f, NULL);
NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:
(id)font, kCTFontAttributeName,
nil];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"Hello World!"
attributes:attrs];
CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attrString);
CFArrayRef runArray = CTLineGetGlyphRuns(line);
// for each RUN
for (CFIndex runIndex = 0; runIndex < CFArrayGetCount(runArray); runIndex++)
{
// Get FONT for this run
CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runArray, runIndex);
CTFontRef runFont = CFDictionaryGetValue(CTRunGetAttributes(run), kCTFontAttributeName);
// for each GLYPH in run
for (CFIndex runGlyphIndex = 0; runGlyphIndex < CTRunGetGlyphCount(run); runGlyphIndex++)
{
// get Glyph & Glyph-data
CFRange thisGlyphRange = CFRangeMake(runGlyphIndex, 1);
CGGlyph glyph;
CGPoint position;
CTRunGetGlyphs(run, thisGlyphRange, &glyph);
CTRunGetPositions(run, thisGlyphRange, &position);
// Get PATH of outline
{
CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyph, NULL);
CGAffineTransform t = CGAffineTransformMakeTranslation(position.x, position.y);
CGPathAddPath(letters, &t, letter);
CGPathRelease(letter);
}
}
}
CFRelease(line);
This is how you create a path, for sample code please refer this link. This code is a part of this sample project. Hope this helps you
I needed this in Swift but it was painful to work out. I hope this is useful to someone else! I've written it as extensions to String and NSAttributedString to be more versatile.
You might see the letters as upside-down depending on how you're drawing your path. You can fix this by adding a vertical flip transform to the call to CTFontCreatePathForGlyph() (a vertical flip is just a CGAffineTransform with a scaleY of -1).
public extension String {
func path(withFont font: UIFont) -> CGPath {
let attributedString = NSAttributedString(string: self, attributes: [.font: font])
let path = attributedString.path()
return path
}
}
public extension NSAttributedString {
func path() -> CGPath {
let path = CGMutablePath()
// Use CoreText to lay the string out as a line
let line = CTLineCreateWithAttributedString(self as CFAttributedString)
// Iterate the runs on the line
let runArray = CTLineGetGlyphRuns(line)
let numRuns = CFArrayGetCount(runArray)
for runIndex in 0..<numRuns {
// Get the font for this run
let run = unsafeBitCast(CFArrayGetValueAtIndex(runArray, runIndex), to: CTRun.self)
let runAttributes = CTRunGetAttributes(run) as Dictionary
let runFont = runAttributes[kCTFontAttributeName] as! CTFont
// Iterate the glyphs in this run
let numGlyphs = CTRunGetGlyphCount(run)
for glyphIndex in 0..<numGlyphs {
let glyphRange = CFRangeMake(glyphIndex, 1)
// Get the glyph
var glyph : CGGlyph = 0
withUnsafeMutablePointer(to: &glyph) { glyphPtr in
CTRunGetGlyphs(run, glyphRange, glyphPtr)
}
// Get the position
var position : CGPoint = .zero
withUnsafeMutablePointer(to: &position) {positionPtr in
CTRunGetPositions(run, glyphRange, positionPtr)
}
// Get a path for the glyph
guard let glyphPath = CTFontCreatePathForGlyph(runFont, glyph, nil) else {
continue
}
// Transform the glyph as it is added to the final path
let t = CGAffineTransform(translationX: position.x, y: position.y)
path.addPath(glyphPath, transform: t)
}
}
return path
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With