Skip to content

Commit b5fba45

Browse files
authored
Merge pull request #9 from GoodNotes/paco/parse_height_width_in_svg
[FFA-502] Parse width and height
2 parents 598d2d4 + eef6057 commit b5fba45

File tree

9 files changed

+92
-7
lines changed

9 files changed

+92
-7
lines changed

GenerateReferencesCLI/cli.swift

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import ArgumentParser
66
#if os(macOS)
77
@main
88
struct cli: ParsableCommand {
9-
@Argument(help: "Path to a folder that contains 1.1F2/ and 1.2T/")
9+
@Argument(help: "Path to a folder that contains 1.1F2/, 1.2T/ and Custom/")
1010
var input: String
1111

1212
static let v11Refs: [String] = [
@@ -144,7 +144,12 @@ struct cli: ParsableCommand {
144144
"struct-frag-01-t",
145145
"struct-use-03-t",
146146
]
147-
147+
148+
static let customRefs: [String] = [
149+
"viewport-01",
150+
"viewport-02",
151+
]
152+
148153
mutating func run() throws {
149154
let inputURL = URL(fileURLWithPath: input)
150155

@@ -154,9 +159,10 @@ struct cli: ParsableCommand {
154159

155160
let v11FolderURL = inputURL.appendingPathComponent("1.1F2")
156161
let v12FolderURL = inputURL.appendingPathComponent("1.2T")
157-
158-
guard FileManager.default.fileExists(atPath: v11FolderURL.path) || FileManager.default.fileExists(atPath: v12FolderURL.path) else {
159-
throw ValidationError("1.1F2/ or 1.2T/ folder does not exist in '\(input)'")
162+
let customFolderURL = inputURL.appendingPathComponent("Custom")
163+
164+
guard FileManager.default.fileExists(atPath: v11FolderURL.path) || FileManager.default.fileExists(atPath: v12FolderURL.path) || FileManager.default.fileExists(atPath: customFolderURL.path) else {
165+
throw ValidationError("1.1F2/, 1.2T/ or Custom/ folder does not exist in '\(input)'")
160166
}
161167

162168
for ref in Self.v11Refs {
@@ -172,6 +178,13 @@ struct cli: ParsableCommand {
172178
let refURL = v12FolderURL.appending(path: "refs/\(ref).ref")
173179
try svgContent.write(to: refURL, atomically: true, encoding: .utf8)
174180
}
181+
182+
for ref in Self.customRefs {
183+
let svgURL = customFolderURL.appending(path: "svg/\(ref).svg")
184+
let svgContent = try serialize(inputURL: svgURL)
185+
let refURL = customFolderURL.appending(path: "refs/\(ref).ref")
186+
try svgContent.write(to: refURL, atomically: true, encoding: .utf8)
187+
}
175188
}
176189

177190
private func serialize(inputURL: URL) throws -> String {

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ generate-test-cases: # Generate test cases from w3c reference files
3939
printf "}" >> ../SVGViewTests/$$class.swift; \
4040
}; \
4141
generateTest "1.1F2" "SVG11Tests"; \
42-
generateTest "1.2T" "SVG12Tests"
42+
generateTest "1.2T" "SVG12Tests"; \
43+
generateTest "Custom" "SVGCustomTests"
4344

4445
update-references-snapshots: # Update .ref from .svg files
4546
swift run GenerateReferencesCLI Tests/SVGViewTests/w3c/

Source/Parser/SVG/SVGContext.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ class SVGNodeContext: SVGContext {
115115

116116
private static func replaceRoot(element: XMLElement, context: SVGContext) -> SVGRootContext {
117117
if element.name == "svg" {
118-
if let viewBox = SVGHelper.parseViewBox(element.attributes, context: context) {
118+
let viewPort = SVGHelper.parseViewPort(element.attributes, context: context)
119+
// Each SVG viewport generates a viewport coordinate system and a user coordinate system, initially identical. Providing a ‘viewBox’ on a viewport's element transforms the user coordinate system relative to the viewport coordinate system
120+
if let viewBox = SVGHelper.parseViewBox(element.attributes, context: context) ?? viewPort {
119121
let screen = SVGScreen(ppi: context.screen.ppi, width: viewBox.width, height: viewBox.height)
120122
return SVGRootContext(logger: context.logger, linker: context.linker, screen: screen, index: context.index, defaultFontSize: context.defaultFontSize)
121123
}

Source/Parser/SVG/SVGParserPrimitives.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,16 @@ public class SVGHelper: NSObject {
189189
return scale.concatenating(move)
190190
}
191191

192+
static func parseViewPort(_ attributes: [String: String], context: SVGContext) -> CGRect? {
193+
if let widthAttr = attributes[ignoreCase: "width"],
194+
let heightAttr = attributes[ignoreCase: "height"],
195+
let width = SVGLengthParser.xAxis.double(string: widthAttr, context: context),
196+
let height = SVGLengthParser.yAxis.double(string: heightAttr, context: context) {
197+
return CGRect(x: 0.0, y: 0.0, width: width, height: height)
198+
}
199+
return nil
200+
}
201+
192202
static func parseViewBox(_ attributes: [String: String], context: SVGContext) -> CGRect? {
193203
// TODO: temporary solution, all attributes should be case insensitive
194204
if let string = attributes[ignoreCase: "viewBox"] {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Generated by make generate-test-cases
2+
3+
import XCTest
4+
@testable import SVGView
5+
6+
class SVGCustomTests: BaseTestCase {
7+
8+
override var dir: String {
9+
return "Custom"
10+
}
11+
12+
func testViewport01() {
13+
compareToReference("viewport-01")
14+
}
15+
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
SVGViewport {
2+
width: "780",
3+
height: "950",
4+
scaling: "none",
5+
contents: [
6+
SVGRect { width: 780, height: 950, fill: "#F4F4F4" },
7+
SVGText {
8+
text: "1-to-1 Meeting Template",
9+
font: { size: 24, weight: "bold" },
10+
textAnchor: "middle",
11+
fill: "black",
12+
transform: [1, 0, 0, 1, 390, 50]
13+
}
14+
]
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
SVGViewport {
2+
width: "180%",
3+
scaling: "none",
4+
contents: [
5+
SVGRect { width: 180, height: 100, fill: "#F4F4F4" },
6+
SVGText {
7+
text: "1-to-1 Meeting Template",
8+
font: { size: 24, weight: "bold" },
9+
textAnchor: "middle",
10+
fill: "black",
11+
transform: [1, 0, 0, 1, 390, 50]
12+
}
13+
]
14+
}
Lines changed: 7 additions & 0 deletions
Loading
Lines changed: 7 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)