swift – Changing Textual content to CGPath to svg | Downside with SVG Path Conversion from CGPath in iOS: Round Path As an alternative of Textual content

swift – Changing Textual content to CGPath to svg | Downside with SVG Path Conversion from CGPath in iOS: Round Path As an alternative of Textual content


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!

📷 Connect the picture exhibiting incorrect rendering

author avatar
roosho Senior Engineer (Technical Services)
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog. 
rooshohttps://www.roosho.com
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog. 

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here


Latest Articles

author avatar
roosho Senior Engineer (Technical Services)
I am Rakib Raihan RooSho, Jack of all IT Trades. You got it right. Good for nothing. I try a lot of things and fail more than that. That's how I learn. Whenever I succeed, I note that in my cookbook. Eventually, that became my blog.