Skip to content

Commit 46042b3

Browse files
committed
adding conversion of Text to CGPath
1 parent 7434be4 commit 46042b3

File tree

8 files changed

+46
-22
lines changed

8 files changed

+46
-22
lines changed

Samples/shapes.svg

Lines changed: 2 additions & 0 deletions
Loading

SwiftVG.xcodeproj/xcuserdata/swhitty.xcuserdatad/xcschemes/xcschememanagement.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<key>SwiftVG.xcscheme_^#shared#^_</key>
1313
<dict>
1414
<key>orderHint</key>
15-
<integer>0</integer>
15+
<integer>1</integer>
1616
</dict>
1717
</dict>
1818
<key>SuppressBuildableAutocreation</key>

SwiftVG/Extensions/CGPath.swift

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
import CoreGraphics
1010
import CoreText
1111
import Foundation
12+
#if os(macOS)
13+
import AppKit
14+
#endif
1215

1316
extension CGPath {
1417
func applyA(action: @escaping (CGPathElement)->()) {
@@ -52,12 +55,20 @@ extension CGPath {
5255

5356
extension String {
5457

55-
func toPath(font: CTFont) -> CGPath {
56-
let attrs: [String: AnyObject] = [kCTFontAttributeName as String: font]
57-
let attString = CFAttributedStringCreate(nil, self as CFString, attrs as CFDictionary)!
58+
func toPath(font: CTFont) -> CGPath? {
59+
//kCTFontAttributeName
60+
let attributes = [NSFontAttributeName as String: font]
61+
let attString = CFAttributedStringCreate(nil, self as CFString, attributes as CFDictionary)!
5862
let line = CTLineCreateWithAttributedString(attString)
5963
let glyphRuns = CTLineGetGlyphRuns(line)
6064

65+
var ascent = CGFloat(0)
66+
var descent = CGFloat(0)
67+
var leading = CGFloat(0)
68+
CTLineGetTypographicBounds(line, &ascent, &descent, &leading)
69+
let baseline = ascent
70+
71+
6172
let path = CGMutablePath()
6273

6374
for idx in 0..<CFArrayGetCount(glyphRuns) {
@@ -70,12 +81,15 @@ extension String {
7081
var position: CGPoint = .zero
7182
CTRunGetGlyphs(run, glyphRange, &glyph)
7283
CTRunGetPositions(run, glyphRange, &position)
73-
if let glyphPath = CTFontCreatePathForGlyph(font, glyph, nil) {
74-
let t = CGAffineTransform(translationX: position.x, y: position.y)
75-
path.addPath(glyphPath, transform: t)
84+
var t = CGAffineTransform.identity
85+
if let glyphPath = CTFontCreatePathForGlyph(font, glyph, &t) {
86+
let t = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: position.x, ty: baseline)
87+
let t1 = t.translatedBy(x: 0, y: baseline)
88+
path.addPath(glyphPath, transform: t1)
7689
}
7790
}
7891
}
92+
7993
return path
8094
}
8195
}

SwiftVG/SVG/Builder/Builder.Command.swift

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,19 @@ import Foundation
1111

1212
extension Builder {
1313

14-
func createCommands<T: RendererTypeProvider>(for svg: DOM.Svg, with provider: T) -> [RendererCommand<T>] {
14+
func createCommands<T: RendererTypeProvider>(for svg: DOM.Svg, with provider: T, isFlipped: Bool = true) -> [RendererCommand<T>] {
1515

1616
let width = Float(svg.width)
1717
let height = Float(svg.height)
1818

1919
self.defs = svg.defs
2020
var commands = [RendererCommand<T>]()
21-
let flip = Transform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: height)
22-
let t = provider.createTransform(from: flip)
23-
commands.append(.concatenate(transform: t))
21+
22+
if !isFlipped {
23+
let flip = Transform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: height)
24+
let t = provider.createTransform(from: flip)
25+
commands.append(.concatenate(transform: t))
26+
}
2427

2528
if let viewBox = svg.viewBox {
2629

@@ -312,8 +315,12 @@ extension Builder {
312315
return provider.createPath(from: path)
313316
} else if let text = element as? DOM.Text {
314317
let size = provider.createFloat(from: text.fontSize ?? 12.0)
315-
let p = provider.createText(from: text.value, with: text.fontFamily ?? "Helvetica", ofSize: size)
316-
return p
318+
319+
let origin = provider.createPoint(from: Builder.Point(text.x ?? 0, text.y ?? 0))
320+
return provider.createText(from: text.value,
321+
with: text.fontFamily ?? "SystemFont",
322+
at: origin,
323+
ofSize: size)
317324
}
318325

319326
return nil
@@ -331,6 +338,4 @@ extension Builder {
331338

332339
return provider.createPath(from: paths)
333340
}
334-
335-
336341
}

SwiftVG/SVG/Image/UIImage.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import UIKit
1010

1111
extension UIImage {
1212

13-
class func svgNamed(_ name: String,
13+
public class func svgNamed(_ name: String,
1414
in bundle: Bundle = Bundle.main) -> UIImage? {
1515
guard let svg = ImageLoader.svgNamed(name, in: bundle) else { return nil }
1616
return image(from: svg)
@@ -19,7 +19,7 @@ extension UIImage {
1919
class func image(from svg: DOM.Svg) -> UIImage {
2020
let size = CGSize(width: svg.width, height: svg.height)
2121
let f = UIGraphicsImageRendererFormat.default()
22-
f.opaque = true
22+
f.opaque = false
2323
f.prefersExtendedRange = false
2424
let r = UIGraphicsImageRenderer(size: size, format: f)
2525

SwiftVG/SVG/Renderer/CodeRenderer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ struct CodeProvider: RendererTypeProvider {
8080
return .compound(paths: subPaths)
8181
}
8282

83-
func createText(from text: String, with font: String, ofSize: Float) -> Path {
83+
func createText(from text: String, with font: String, at origin: Point, ofSize pt: Float) -> Path? {
8484
return .ellipse(within: Builder.Rect(x: 0, y: 0, width: 0, height: 0))
8585
}
8686

SwiftVG/SVG/Renderer/CoreGraphicsRenderer.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,12 @@ struct CoreGraphicsProvider: RendererTypeProvider {
146146
return cgPath
147147
}
148148

149-
func createText(from text: String, with fontName: String, ofSize pt: Float) -> Path {
150-
let font = CTFontCreateWithName(text as CFString, pt, nil)
151-
return text.toPath(font: font)
149+
func createText(from text: String, with fontName: String, at origin: Point, ofSize pt: Float) -> Path? {
150+
let font = CTFontCreateWithName(fontName as CFString, pt, nil)
151+
guard let path = text.toPath(font: font) else { return nil }
152+
153+
var transform = CGAffineTransform(translationX: origin.x, y: origin.y)
154+
return path.copy(using: &transform)
152155
}
153156

154157
func createImage(from image: Builder.Image) -> CGImage? {

SwiftVG/SVG/Renderer/Renderer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ protocol RendererTypeProvider {
3434
func createLine(from origin: Point, to desination: Point) -> Path
3535
func createLine(between points: [Point]) -> Path
3636
func createPolygon(between points: [Point]) -> Path
37-
func createText(from text: String, with font: String, ofSize: Float) -> Path
37+
func createText(from text: String, with font: String, at origin: Point, ofSize pt: Float) -> Path?
3838

3939
func createRect(from rect: Rect, radii: Builder.Size) -> Path
4040
}

0 commit comments

Comments
 (0)