diff --git a/GenerateReferencesCLI/cli.swift b/GenerateReferencesCLI/cli.swift index c89f5c4..5294b4e 100644 --- a/GenerateReferencesCLI/cli.swift +++ b/GenerateReferencesCLI/cli.swift @@ -6,7 +6,7 @@ import ArgumentParser #if os(macOS) @main struct cli: ParsableCommand { - @Argument(help: "Path to a folder that contains 1.1F2/ and 1.2T/") + @Argument(help: "Path to a folder that contains 1.1F2/, 1.2T/ and Custom/") var input: String static let v11Refs: [String] = [ @@ -144,7 +144,12 @@ struct cli: ParsableCommand { "struct-frag-01-t", "struct-use-03-t", ] - + + static let customRefs: [String] = [ + "viewport-01", + "viewport-02", + ] + mutating func run() throws { let inputURL = URL(fileURLWithPath: input) @@ -154,9 +159,10 @@ struct cli: ParsableCommand { let v11FolderURL = inputURL.appendingPathComponent("1.1F2") let v12FolderURL = inputURL.appendingPathComponent("1.2T") - - guard FileManager.default.fileExists(atPath: v11FolderURL.path) || FileManager.default.fileExists(atPath: v12FolderURL.path) else { - throw ValidationError("1.1F2/ or 1.2T/ folder does not exist in '\(input)'") + let customFolderURL = inputURL.appendingPathComponent("Custom") + + guard FileManager.default.fileExists(atPath: v11FolderURL.path) || FileManager.default.fileExists(atPath: v12FolderURL.path) || FileManager.default.fileExists(atPath: customFolderURL.path) else { + throw ValidationError("1.1F2/, 1.2T/ or Custom/ folder does not exist in '\(input)'") } for ref in Self.v11Refs { @@ -172,6 +178,13 @@ struct cli: ParsableCommand { let refURL = v12FolderURL.appending(path: "refs/\(ref).ref") try svgContent.write(to: refURL, atomically: true, encoding: .utf8) } + + for ref in Self.customRefs { + let svgURL = customFolderURL.appending(path: "svg/\(ref).svg") + let svgContent = try serialize(inputURL: svgURL) + let refURL = customFolderURL.appending(path: "refs/\(ref).ref") + try svgContent.write(to: refURL, atomically: true, encoding: .utf8) + } } private func serialize(inputURL: URL) throws -> String { diff --git a/Makefile b/Makefile index 4ba3a72..8c6b3ff 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,8 @@ generate-test-cases: # Generate test cases from w3c reference files printf "}" >> ../SVGViewTests/$$class.swift; \ }; \ generateTest "1.1F2" "SVG11Tests"; \ - generateTest "1.2T" "SVG12Tests" + generateTest "1.2T" "SVG12Tests"; \ + generateTest "Custom" "SVGCustomTests" update-references-snapshots: # Update .ref from .svg files swift run GenerateReferencesCLI Tests/SVGViewTests/w3c/ diff --git a/Source/Parser/SVG/SVGContext.swift b/Source/Parser/SVG/SVGContext.swift index 5506fcc..6438e7f 100644 --- a/Source/Parser/SVG/SVGContext.swift +++ b/Source/Parser/SVG/SVGContext.swift @@ -115,7 +115,9 @@ class SVGNodeContext: SVGContext { private static func replaceRoot(element: XMLElement, context: SVGContext) -> SVGRootContext { if element.name == "svg" { - if let viewBox = SVGHelper.parseViewBox(element.attributes, context: context) { + let viewPort = SVGHelper.parseViewPort(element.attributes, context: context) + // 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 + if let viewBox = SVGHelper.parseViewBox(element.attributes, context: context) ?? viewPort { let screen = SVGScreen(ppi: context.screen.ppi, width: viewBox.width, height: viewBox.height) return SVGRootContext(logger: context.logger, linker: context.linker, screen: screen, index: context.index, defaultFontSize: context.defaultFontSize) } diff --git a/Source/Parser/SVG/SVGParserPrimitives.swift b/Source/Parser/SVG/SVGParserPrimitives.swift index 7570527..e1376b5 100644 --- a/Source/Parser/SVG/SVGParserPrimitives.swift +++ b/Source/Parser/SVG/SVGParserPrimitives.swift @@ -189,6 +189,16 @@ public class SVGHelper: NSObject { return scale.concatenating(move) } + static func parseViewPort(_ attributes: [String: String], context: SVGContext) -> CGRect? { + if let widthAttr = attributes[ignoreCase: "width"], + let heightAttr = attributes[ignoreCase: "height"], + let width = SVGLengthParser.xAxis.double(string: widthAttr, context: context), + let height = SVGLengthParser.yAxis.double(string: heightAttr, context: context) { + return CGRect(x: 0.0, y: 0.0, width: width, height: height) + } + return nil + } + static func parseViewBox(_ attributes: [String: String], context: SVGContext) -> CGRect? { // TODO: temporary solution, all attributes should be case insensitive if let string = attributes[ignoreCase: "viewBox"] { diff --git a/Tests/SVGViewTests/SVGCustomTests.swift b/Tests/SVGViewTests/SVGCustomTests.swift new file mode 100644 index 0000000..eaf9b70 --- /dev/null +++ b/Tests/SVGViewTests/SVGCustomTests.swift @@ -0,0 +1,16 @@ +// Generated by make generate-test-cases + +import XCTest +@testable import SVGView + +class SVGCustomTests: BaseTestCase { + + override var dir: String { + return "Custom" + } + + func testViewport01() { + compareToReference("viewport-01") + } + +} \ No newline at end of file diff --git a/Tests/SVGViewTests/w3c/Custom/refs/viewport-01.ref b/Tests/SVGViewTests/w3c/Custom/refs/viewport-01.ref new file mode 100644 index 0000000..62c6760 --- /dev/null +++ b/Tests/SVGViewTests/w3c/Custom/refs/viewport-01.ref @@ -0,0 +1,15 @@ +SVGViewport { + width: "780", + height: "950", + scaling: "none", + contents: [ + SVGRect { width: 780, height: 950, fill: "#F4F4F4" }, + SVGText { + text: "1-to-1 Meeting Template", + font: { size: 24, weight: "bold" }, + textAnchor: "middle", + fill: "black", + transform: [1, 0, 0, 1, 390, 50] + } + ] +} diff --git a/Tests/SVGViewTests/w3c/Custom/refs/viewport-02.ref b/Tests/SVGViewTests/w3c/Custom/refs/viewport-02.ref new file mode 100644 index 0000000..0c426d6 --- /dev/null +++ b/Tests/SVGViewTests/w3c/Custom/refs/viewport-02.ref @@ -0,0 +1,14 @@ +SVGViewport { + width: "180%", + scaling: "none", + contents: [ + SVGRect { width: 180, height: 100, fill: "#F4F4F4" }, + SVGText { + text: "1-to-1 Meeting Template", + font: { size: 24, weight: "bold" }, + textAnchor: "middle", + fill: "black", + transform: [1, 0, 0, 1, 390, 50] + } + ] +} diff --git a/Tests/SVGViewTests/w3c/Custom/svg/viewport-01.svg b/Tests/SVGViewTests/w3c/Custom/svg/viewport-01.svg new file mode 100644 index 0000000..075fbf1 --- /dev/null +++ b/Tests/SVGViewTests/w3c/Custom/svg/viewport-01.svg @@ -0,0 +1,7 @@ + + + + + + 1-to-1 Meeting Template + diff --git a/Tests/SVGViewTests/w3c/Custom/svg/viewport-02.svg b/Tests/SVGViewTests/w3c/Custom/svg/viewport-02.svg new file mode 100644 index 0000000..edce9b7 --- /dev/null +++ b/Tests/SVGViewTests/w3c/Custom/svg/viewport-02.svg @@ -0,0 +1,7 @@ + + + + + + 1-to-1 Meeting Template +