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 te
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
}
}