I am trying to transform textual content to a path utilizing CGPath in iOS after which convert that path to an SVG string, however after I save the SVG and cargo it once more, the trail is round slightly than forming the right textual content form.
Right here’s my implementation:
textToPath perform:
func textToPath(textual content: String, font: UIFont) -> CGPath? {
let attributedString = NSAttributedString(string: textual content, attributes: [.font: font])
let line = CTLineCreateWithAttributedString(attributedString)
let runArray = CTLineGetGlyphRuns(line) as NSArray
let path = CGMutablePath()
for run in runArray {
let run = run as! CTRun
let rely = CTRunGetGlyphCount(run)
for index in 0..<rely {
let vary = CFRangeMake(index, 1)
var glyph: CGGlyph = 0
var place: CGPoint = .zero
CTRunGetGlyphs(run, vary, &glyph)
CTRunGetPositions(run, vary, &place)
if let glyphPath = CTFontCreatePathForGlyph(font, glyph, nil) {
var rework = CGAffineTransform(translationX: place.x, y: place.y)
rework = rework.scaledBy(x: 1, y: -1) // Invert Y-axis to match SVG coordinate system
// Add the glyph path to the primary path
path.addPath(glyphPath, rework: rework)
}
}
}
DispatchQueue.most important.asyncAfter(deadline: .now() + 0.5, execute: {
cgPath = path
})
return path
}
pathToSVG perform:
func pathToSVG(path: CGPath, shade: UIColor) -> String {
let boundingBox = path.boundingBox
let svgWidth = boundingBox.width
let svgHeight = boundingBox.top
var svgString = "<svg width="(svgWidth)" top="(svgHeight)" xmlns="http://www.w3.org/2000/svg">n"
svgString += "<path d=""
path.applyWithBlock { elementPointer in
let ingredient = elementPointer.pointee
let factors = ingredient.factors
swap ingredient.sort {
case .moveToPoint:
svgString += "M (factors.pointee.x) (factors.pointee.y) "
case .addLineToPoint:
svgString += "L (factors.pointee.x) (factors.pointee.y) "
case .addQuadCurveToPoint:
svgString += "Q (factors.pointee.x) (factors.pointee.y) (factors.pointee.x) (factors.pointee.y) "
case .addCurveToPoint:
svgString += "C (factors.pointee.x) (factors.pointee.y) (factors.pointee.x) (factors.pointee.y) (factors.pointee.x) (factors.pointee.y) "
case .closeSubpath:
svgString += "Z "
@unknown default:
break
}
}
svgString += "" fill="(shade.hexString)" />n"
svgString += "</svg>"
return svgString
}
The issue:
Once I load the saved SVG file, it creates a round path as an alternative of the right textual content form. I consider the trail conversion just isn’t capturing the right coordinates or curves, because it would not render correctly in an SVG viewer.
Further particulars:
The textToPath perform generates a CGPath primarily based on the textual content and its font.
The pathToSVG perform is meant to transform the CGPath to an SVG path string.
The saved SVG file shows a round path slightly than the supposed textual content.
What I’ve tried:
I’ve checked the transformation utilized to the trail, and it appears appropriate for inverting the Y-axis.
I attempted utilizing each M and L for path instructions, however the SVG nonetheless doesn’t render the textual content as anticipated.
Any assist could be vastly appreciated. Thanks upfront!