From a98f9e2f3a8782e10868ced1f02d020e466cc2b8 Mon Sep 17 00:00:00 2001 From: Alisa Mylnikova Date: Mon, 7 May 2018 11:39:38 +0700 Subject: [PATCH] Replace ViewBoxParams with ContentLayout --- Source/svg/SVGCanvas.swift | 45 ++--------------------------- Source/svg/SVGParser.swift | 14 ++++----- Source/utils/SvgContentLayout.swift | 37 ++++++++++++++++++++---- Source/views/MacawView.swift | 3 +- 4 files changed, 43 insertions(+), 56 deletions(-) diff --git a/Source/svg/SVGCanvas.swift b/Source/svg/SVGCanvas.swift index fb401114..ee46fbc7 100644 --- a/Source/svg/SVGCanvas.swift +++ b/Source/svg/SVGCanvas.swift @@ -5,51 +5,12 @@ // Created by Yuri Strot on 4/11/18. // -enum Dimension { - case percent(Double) - case pixels(Double) - - init(percent: Double) { - self = .percent(percent) - } - - init(pixels: Double) { - self = .pixels(pixels) - } -} - -class Dimensions { - let width: Dimension - let height: Dimension - - public init(width: Dimension, height: Dimension) { - self.width = width - self.height = height - } -} - -class ViewBoxParams { - let svgDimensions: Dimensions? - let viewBox: Rect? - let scalingMode: AspectRatio - let xAligningMode: Align - let yAligningMode: Align - - public init(svgDimensions: Dimensions?, viewBox: Rect?, scalingMode: AspectRatio?, xAligningMode: Align? = .mid, yAligningMode: Align? = .mid) { - self.svgDimensions = svgDimensions - self.viewBox = viewBox - self.scalingMode = scalingMode ?? .meet - self.xAligningMode = xAligningMode ?? .mid - self.yAligningMode = yAligningMode ?? .mid - } -} - class SVGCanvas: Group { - let viewBoxParams: ViewBoxParams + let contentLayout: ContentLayout - public init(viewBoxParams: ViewBoxParams, contents: [Node] = []) { - self.viewBoxParams = viewBoxParams + public init(contentLayout: ContentLayout, contents: [Node] = []) { + self.contentLayout = contentLayout super.init(contents: contents) } diff --git a/Source/svg/SVGParser.swift b/Source/svg/SVGParser.swift index 949a6536..9321b11e 100644 --- a/Source/svg/SVGParser.swift +++ b/Source/svg/SVGParser.swift @@ -69,11 +69,11 @@ open class SVGParser { fileprivate func parse() -> Group { let parsedXml = SWXMLHash.parse(xmlString) - var viewBoxParams: ViewBoxParams? + var contentLayout: ContentLayout? for child in parsedXml.children { if let element = child.element { if element.name == "svg" { - viewBoxParams = parseViewBox(element) + contentLayout = parseViewBox(element) prepareSvg(child.children) break } @@ -81,8 +81,8 @@ open class SVGParser { } parseSvg(parsedXml.children) - if let viewBoxParams = viewBoxParams { - return SVGCanvas(viewBoxParams: viewBoxParams, contents: nodes) + if let contentLayout = contentLayout { + return SVGCanvas(contentLayout: contentLayout, contents: nodes) } return Group(contents: nodes) } @@ -119,7 +119,7 @@ open class SVGParser { } } - fileprivate func parseViewBox(_ element: SWXMLHash.XMLElement) -> ViewBoxParams? { + fileprivate func parseViewBox(_ element: SWXMLHash.XMLElement) -> SvgContentLayout? { var svgDimensions: Dimensions? if let w = getDimensionValue(element, attribute: "width"), let h = getDimensionValue(element, attribute: "height") { svgDimensions = Dimensions(width: w, height: h) @@ -143,7 +143,7 @@ open class SVGParser { let strings = contentModeString.components(separatedBy: CharacterSet(charactersIn: " ")) if strings.count == 1 { // none scalingMode = parseAspectRatio(strings[0]) - return ViewBoxParams(svgDimensions: svgDimensions, viewBox: viewBox, scalingMode: scalingMode) + return SvgContentLayout(svgDimensions: svgDimensions, viewBox: viewBox, scalingMode: scalingMode) } guard strings.count == 2 else { fatalError("Invalid content mode") } @@ -159,7 +159,7 @@ open class SVGParser { scalingMode = parseAspectRatio(strings[1]) } - return ViewBoxParams(svgDimensions: svgDimensions, viewBox: viewBox, scalingMode: scalingMode, xAligningMode: xAligningMode, yAligningMode: yAligningMode) + return SvgContentLayout(svgDimensions: svgDimensions, viewBox: viewBox, scalingMode: scalingMode, xAligningMode: xAligningMode, yAligningMode: yAligningMode) } fileprivate func parseNode(_ node: XMLIndexer, groupStyle: [String: String] = [:]) -> Node? { diff --git a/Source/utils/SvgContentLayout.swift b/Source/utils/SvgContentLayout.swift index ac0febfb..d158b0fe 100644 --- a/Source/utils/SvgContentLayout.swift +++ b/Source/utils/SvgContentLayout.swift @@ -1,4 +1,27 @@ +public enum Dimension { + case percent(Double) + case pixels(Double) + + init(percent: Double) { + self = .percent(percent) + } + + init(pixels: Double) { + self = .pixels(pixels) + } +} + +public class Dimensions { + let width: Dimension + let height: Dimension + + public init(width: Dimension, height: Dimension) { + self.width = width + self.height = height + } +} + public protocol ContentLayout { static var standard: ContentLayout { get } @@ -7,18 +30,22 @@ public protocol ContentLayout { open class SvgContentLayout: ContentLayout { + public let svgDimensions: Dimensions? + public let viewBox: Rect? public let scalingMode: AspectRatio public let xAligningMode: Align public let yAligningMode: Align - public init(scalingMode: AspectRatio, xAligningMode: Align = Align.min, yAligningMode: Align = Align.min) { - self.scalingMode = scalingMode - self.xAligningMode = xAligningMode - self.yAligningMode = yAligningMode + public init(svgDimensions: Dimensions? = .none, viewBox: Rect? = .none, scalingMode: AspectRatio? = .meet, xAligningMode: Align? = .mid, yAligningMode: Align? = .mid) { + self.svgDimensions = svgDimensions + self.viewBox = viewBox + self.scalingMode = scalingMode ?? .meet + self.xAligningMode = xAligningMode ?? .mid + self.yAligningMode = yAligningMode ?? .mid } public static var standard: ContentLayout { - return SvgContentLayout(scalingMode: .none) + return SvgContentLayout() } public func layout(rect: Rect, into rectToFitIn: Rect) -> Transform { diff --git a/Source/views/MacawView.swift b/Source/views/MacawView.swift index 831ebffd..a2c313bc 100644 --- a/Source/views/MacawView.swift +++ b/Source/views/MacawView.swift @@ -18,13 +18,12 @@ open class MacawView: MView, MGestureRecognizerDelegate { } didSet { - if let canvas = node as? SVGCanvas, let dimensions = canvas.viewBoxParams.svgDimensions { + if let canvas = node as? SVGCanvas, let params = canvas.contentLayout as? SvgContentLayout, let dimensions = params.svgDimensions { let width = dimensionToPixels(dimensions.width, framePixels: Double(frame.width)) let height = dimensionToPixels(dimensions.height, framePixels: Double(frame.height)) let svgSize = Size(w: width, h: height) - let params = canvas.viewBoxParams let scalingMode = params.scalingMode if let viewBox = params.viewBox { canvas.clip = viewBox