├── .github └── ISSUE_TEMPLATE │ └── issue.md ├── .gitignore ├── .jazzy.yaml ├── LICENSE ├── Package.swift ├── README.md ├── SwiftSVG.podspec ├── SwiftSVG.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── SwiftSVG.xcscheme │ └── SwiftSVGTests.xcscheme ├── SwiftSVG.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── SwiftSVG ├── CrossPlatform.swift ├── NSBezierPath+CrossPlatform.swift ├── SVG Extensions │ ├── CALayer+SVG.swift │ ├── CAShapeLayer+SVG.swift │ ├── SVGLayer.swift │ ├── SVGView.swift │ ├── UIBezierPath+SVG.swift │ └── UIView+SVG.swift └── SVG │ ├── Attributes │ ├── DelaysApplyingAttributes.swift │ ├── Fillable.swift │ ├── Identifiable.swift │ ├── Strokable.swift │ ├── Stylable.swift │ └── Transformable.swift │ ├── Cache │ └── SVGCache.swift │ ├── Elements │ ├── ParsesAsynchronously.swift │ ├── SVGCircle.swift │ ├── SVGContainerElement.swift │ ├── SVGElement.swift │ ├── SVGEllipse.swift │ ├── SVGGroup.swift │ ├── SVGLine.swift │ ├── SVGPath.swift │ ├── SVGPolygon.swift │ ├── SVGPolyline.swift │ ├── SVGRectangle.swift │ ├── SVGRootElement.swift │ └── SVGShapeElement.swift │ ├── Helpers │ ├── BinaryFloatingPoint+ParseLengthString.swift │ ├── CALayer+Sublayers.swift │ ├── Data+CacheKey.swift │ ├── Dictionary+Add.swift │ ├── Dictionary+JSON.swift │ ├── DispatchQueue+Extensions.swift │ ├── FloatingPoint+DegreesRadians.swift │ ├── Print.swift │ ├── Scalar+FromByteArray.swift │ ├── Stack.swift │ ├── String+Subscript.swift │ ├── String+Trim.swift │ ├── UIColor+Extensions.swift │ ├── Unown.swift │ └── cssColorNames.json │ ├── Iterators │ ├── CoordinateLexer.swift │ ├── PathCommand.swift │ └── PathDLexer.swift │ └── Parser │ ├── NSXMLSVGParser.swift │ ├── SVGParser.swift │ └── SVGParserSupportedElements.swift ├── SwiftSVGExamples ├── SwiftSVGExampleMac │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift ├── SwiftSVGExampleTVOS │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── App Icon & Top Shelf Image.brandassets │ │ │ ├── App Icon - Large.imagestack │ │ │ │ ├── Back.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── Front.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ └── Middle.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ ├── App Icon - Small.imagestack │ │ │ │ ├── Back.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── Front.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ └── Middle.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Top Shelf Image Wide.imageset │ │ │ │ └── Contents.json │ │ │ └── Top Shelf Image.imageset │ │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift ├── SwiftSVGExampleiOS │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── cowboyHat.dataset │ │ │ ├── Contents.json │ │ │ └── cowboyHat.svg │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── GithubCell.swift │ ├── GithubViewController.swift │ ├── Info.plist │ ├── SingleSVGViewController.swift │ ├── StartCell.swift │ ├── StartViewController.swift │ ├── VariousCell.swift │ └── VariousViewController.swift ├── SwiftSVGExamples.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── SwiftSVGExampleiOS.xcscheme └── TestSVGs │ ├── Camel2.svg │ ├── DrawingBoard.svg │ ├── Dulcimer.svg │ ├── Fyodor-Dostoevsky.svg │ ├── George_Kerr_Anderson_Patent_1885_1.svg │ ├── MedievalBanners.svg │ ├── alohaShirt.svg │ ├── baseball.svg │ ├── berlin.svg │ ├── circles.svg │ ├── decorativeblob.svg │ ├── ellipses.svg │ ├── error.svg │ ├── fistBump.svg │ ├── hawaiiFlowers.svg │ ├── johnny-automatic-open-mouth.svg │ ├── openclipart-1290111299.svg │ ├── openclipart-1332611679.svg │ ├── openclipart-1346768588.svg │ ├── openclipart-Anonymous_Architetto_--_Bicicletta.svg │ ├── openclipart-Anonymous_Architetto_--_Camello.svg │ ├── openclipart-Anonymous_Architetto_--_Coccinella_04.svg │ ├── openclipart-angry-coder.svg │ ├── openclipart-motivo_geometrico_archit_01.svg │ ├── openclipart-tux.svg │ ├── openclipart-zanzara_architetto_fran_03r.svg │ ├── pizza.svg │ ├── polygons.svg │ ├── polylines.svg │ ├── rabbitcowboy.svg │ ├── raphaelcruzeiro.svg │ ├── rectangles.svg │ ├── simple-rectangle.svg │ ├── sockPuppet.svg │ ├── tea.svg │ ├── tiger.svg │ └── triangle.svg ├── SwiftSVGFramework ├── Info.plist └── SwiftSVGFramework.h ├── SwiftSVGTests ├── CGPathPoints.swift ├── ClosePathTests.swift ├── CoordinateLexerTests.swift ├── CurveToTests.swift ├── DictionaryAddTests.swift ├── FillableTests.swift ├── FloatingPointDegreesToRadiansTests.swift ├── FloatingPointParseLengthStringTests.swift ├── HorizontalLineToTests.swift ├── IndentifiableTests.swift ├── Info.plist ├── LineToTests.swift ├── MoveToTests.swift ├── PathDLexerTests.swift ├── PerformanceTests.swift ├── SVGCircleTests.swift ├── SVGEllipseTests.swift ├── SVGGroupTests.swift ├── SVGLineTests.swift ├── SVGPathTests.swift ├── SVGPolygonTests.swift ├── SVGPolylineTests.swift ├── SVGRectangleTests.swift ├── SVGRootElementTests.swift ├── ScalarFromByteArrayTests.swift ├── SmoothCurveToTests.swift ├── StackTests.swift ├── StringSubscriptTests.swift ├── TestShapeElement.swift ├── UIColorExtensionsTests.swift └── VerticalLineToTests.swift ├── docs ├── CNAME ├── Classes.html ├── Classes │ ├── NSXMLSVGParser.html │ ├── NSXMLSVGParser │ │ └── SVGParserError.html │ ├── SVGCache.html │ ├── SVGCircle.html │ ├── SVGEllipse.html │ ├── SVGGroup.html │ ├── SVGLayer.html │ ├── SVGLine.html │ ├── SVGPath.html │ ├── SVGRectangle.html │ └── SVGView.html ├── Enums.html ├── Enums │ ├── LineCap.html │ ├── LineJoin.html │ └── PathType.html ├── Extensions.html ├── Extensions │ ├── BinaryFloatingPoint.html │ ├── CALayer.html │ ├── CAShapeLayer.html │ ├── CGFloat.html │ ├── Dictionary.html │ ├── DispatchQueue.html │ ├── Double.html │ ├── Float.html │ ├── FloatingPoint.html │ ├── NSBezierPath.html │ ├── String.html │ ├── UIBezierPath.html │ ├── UIColor.html │ └── UIView.html ├── Global Variables.html ├── Other Classes.html ├── Other Enums.html ├── Other Extensions.html ├── Other Protocols.html ├── Other Structs.html ├── Protocols.html ├── Protocols │ ├── CanManageAsychronousCallbacks.html │ ├── CanManageAsychronousParsing.html │ ├── DelaysApplyingAttributes.html │ ├── Fillable.html │ ├── ParsesAsynchronously.html │ ├── PathCommand.html │ ├── PreviousCommand.html │ ├── SVGContainerElement.html │ ├── SVGElement.html │ ├── SVGLayerType.html │ ├── SVGParser.html │ ├── SVGShapeElement.html │ ├── StackType.html │ ├── Strokable.html │ ├── Stylable.html │ └── Transformable.html ├── SVG Extensions.html ├── Structs.html ├── Structs │ ├── ClosePath.html │ ├── CoordinateLexer.html │ ├── CurveTo.html │ ├── EllipticalArc.html │ ├── HorizontalLineTo.html │ ├── LineTo.html │ ├── MoveTo.html │ ├── NamedColors.html │ ├── PathDConstants.html │ ├── PathDConstants │ │ └── DCharacter.html │ ├── PathDLexer.html │ ├── QuadraticCurveTo.html │ ├── SVGParseOptions.html │ ├── SVGParserSupportedElements.html │ ├── SVGPath.html │ ├── SVGPolygon.html │ ├── SVGPolyline.html │ ├── SVGRootElement.html │ ├── SmoothCurveTo.html │ ├── SmoothQuadraticCurveTo.html │ ├── Stack.html │ ├── Transform.html │ └── VerticalLineTo.html ├── badge.svg ├── css │ ├── highlight.css │ └── jazzy.css ├── docsets │ ├── SwiftSVG.docset │ │ └── Contents │ │ │ ├── Info.plist │ │ │ └── Resources │ │ │ ├── Documents │ │ │ ├── CNAME │ │ │ ├── Classes.html │ │ │ ├── Classes │ │ │ │ ├── NSXMLSVGParser.html │ │ │ │ ├── NSXMLSVGParser │ │ │ │ │ └── SVGParserError.html │ │ │ │ ├── SVGCache.html │ │ │ │ ├── SVGCircle.html │ │ │ │ ├── SVGEllipse.html │ │ │ │ ├── SVGGroup.html │ │ │ │ ├── SVGLayer.html │ │ │ │ ├── SVGLine.html │ │ │ │ ├── SVGPath.html │ │ │ │ ├── SVGRectangle.html │ │ │ │ └── SVGView.html │ │ │ ├── Enums.html │ │ │ ├── Enums │ │ │ │ ├── LineCap.html │ │ │ │ ├── LineJoin.html │ │ │ │ └── PathType.html │ │ │ ├── Extensions.html │ │ │ ├── Extensions │ │ │ │ ├── BinaryFloatingPoint.html │ │ │ │ ├── CALayer.html │ │ │ │ ├── CAShapeLayer.html │ │ │ │ ├── CGFloat.html │ │ │ │ ├── Dictionary.html │ │ │ │ ├── DispatchQueue.html │ │ │ │ ├── Double.html │ │ │ │ ├── Float.html │ │ │ │ ├── FloatingPoint.html │ │ │ │ ├── NSBezierPath.html │ │ │ │ ├── String.html │ │ │ │ ├── UIBezierPath.html │ │ │ │ ├── UIColor.html │ │ │ │ └── UIView.html │ │ │ ├── Global Variables.html │ │ │ ├── Other Classes.html │ │ │ ├── Other Enums.html │ │ │ ├── Other Extensions.html │ │ │ ├── Other Protocols.html │ │ │ ├── Other Structs.html │ │ │ ├── Protocols.html │ │ │ ├── Protocols │ │ │ │ ├── CanManageAsychronousCallbacks.html │ │ │ │ ├── CanManageAsychronousParsing.html │ │ │ │ ├── DelaysApplyingAttributes.html │ │ │ │ ├── Fillable.html │ │ │ │ ├── ParsesAsynchronously.html │ │ │ │ ├── PathCommand.html │ │ │ │ ├── PreviousCommand.html │ │ │ │ ├── SVGContainerElement.html │ │ │ │ ├── SVGElement.html │ │ │ │ ├── SVGLayerType.html │ │ │ │ ├── SVGParser.html │ │ │ │ ├── SVGShapeElement.html │ │ │ │ ├── StackType.html │ │ │ │ ├── Strokable.html │ │ │ │ ├── Stylable.html │ │ │ │ └── Transformable.html │ │ │ ├── SVG Extensions.html │ │ │ ├── Structs.html │ │ │ ├── Structs │ │ │ │ ├── ClosePath.html │ │ │ │ ├── CoordinateLexer.html │ │ │ │ ├── CurveTo.html │ │ │ │ ├── EllipticalArc.html │ │ │ │ ├── HorizontalLineTo.html │ │ │ │ ├── LineTo.html │ │ │ │ ├── MoveTo.html │ │ │ │ ├── NamedColors.html │ │ │ │ ├── PathDConstants.html │ │ │ │ ├── PathDConstants │ │ │ │ │ └── DCharacter.html │ │ │ │ ├── PathDLexer.html │ │ │ │ ├── QuadraticCurveTo.html │ │ │ │ ├── SVGParseOptions.html │ │ │ │ ├── SVGParserSupportedElements.html │ │ │ │ ├── SVGPath.html │ │ │ │ ├── SVGPolygon.html │ │ │ │ ├── SVGPolyline.html │ │ │ │ ├── SVGRootElement.html │ │ │ │ ├── SmoothCurveTo.html │ │ │ │ ├── SmoothQuadraticCurveTo.html │ │ │ │ ├── Stack.html │ │ │ │ ├── Transform.html │ │ │ │ └── VerticalLineTo.html │ │ │ ├── badge.svg │ │ │ ├── css │ │ │ │ ├── highlight.css │ │ │ │ └── jazzy.css │ │ │ ├── images │ │ │ │ ├── SwiftSVG-Logo.png │ │ │ │ ├── fistBump.png │ │ │ │ ├── pizza.png │ │ │ │ ├── sockPuppet.png │ │ │ │ ├── svgViewScreenshot.png │ │ │ │ └── triangle.png │ │ │ ├── img │ │ │ │ ├── carat.png │ │ │ │ ├── dash.png │ │ │ │ ├── gh.png │ │ │ │ └── spinner.gif │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ ├── jazzy.js │ │ │ │ ├── jazzy.search.js │ │ │ │ ├── jquery.min.js │ │ │ │ ├── lunr.min.js │ │ │ │ └── typeahead.jquery.js │ │ │ ├── search.json │ │ │ └── undocumented.json │ │ │ └── docSet.dsidx │ └── SwiftSVG.tgz ├── images │ ├── SwiftSVG-Logo.png │ ├── fistBump.png │ ├── pizza.png │ ├── sockPuppet.png │ ├── svgViewScreenshot.png │ └── triangle.png ├── img │ ├── carat.png │ ├── dash.png │ ├── gh.png │ └── spinner.gif ├── index.html ├── js │ ├── jazzy.js │ ├── jazzy.search.js │ ├── jquery.min.js │ ├── lunr.min.js │ └── typeahead.jquery.js ├── search.json └── undocumented.json ├── images ├── SwiftSVG-Logo.png ├── assetCatalog.png ├── cowboyHat.png ├── fistBump.png ├── hammock.png ├── pizza.png ├── sockPuppet.png ├── svgViewScreenshot.png ├── tea.png └── triangle.png └── svgs └── ukulele.svg /.github/ISSUE_TEMPLATE/issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Issue 3 | about: Help us improve SwiftSVG 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Description of the Issue** 11 | A clear and concise description of what the issue is. 12 | 13 | **Sample SVG** 14 | IMPORTANT - Include the SVG code here or link to a sample file. 15 | 16 | **Screenshots** 17 | If possible, add screenshots to help explain your problem. 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Swift ### 2 | # Xcode 3 | # 4 | build/ 5 | *.pbxuser 6 | !default.pbxuser 7 | *.mode1v3 8 | !default.mode1v3 9 | *.mode2v3 10 | !default.mode2v3 11 | *.perspectivev3 12 | !default.perspectivev3 13 | xcuserdata 14 | *.xccheckout 15 | *.moved-aside 16 | DerivedData 17 | *.hmap 18 | *.ipa 19 | *.xcuserstate 20 | .DS_Store 21 | 22 | # SPM 23 | .swiftpm 24 | 25 | # Carthage 26 | # 27 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 28 | # Carthage/Checkouts 29 | 30 | Carthage/Build 31 | -------------------------------------------------------------------------------- /.jazzy.yaml: -------------------------------------------------------------------------------- 1 | module: SwiftSVG 2 | author: Michael Choe 3 | github_url: https://github.com/mchoe/swiftsvg 4 | copyright: '© 2017 Michael Choe under [MIT](https://github.com/mchoe/SwiftSVG/blob/master/LICENSE).' 5 | theme: fullwidth 6 | min_acl: internal 7 | skip_undocumented: yes 8 | exclude: 9 | - "SwiftSVG/NSBezierPath+CrossPlatform.swift" 10 | - "CrossPlatform.swift" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | SwiftSVG 3 | 4 | Copyright (c) 2015 Michael Choe, Strauss LLC 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "SwiftSVG", 7 | platforms: [.macOS(.v10_14), .iOS(.v8), .tvOS(.v9)], 8 | products: [ 9 | .library( 10 | name: "SwiftSVG", 11 | targets: ["SwiftSVG"] 12 | ), 13 | ], 14 | targets: [ 15 | .target( 16 | name: "SwiftSVG", 17 | dependencies: [], 18 | path: "SwiftSVG" 19 | ), 20 | .testTarget( 21 | name: "SwiftSVGTests", 22 | dependencies: ["SwiftSVG"], 23 | path: "SwiftSVGTests" 24 | ), 25 | ], 26 | swiftLanguageVersions: [.v5] 27 | ) 28 | -------------------------------------------------------------------------------- /SwiftSVG.podspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | Pod::Spec.new do |s| 4 | 5 | s.name = "SwiftSVG" 6 | s.version = "2.3.2" 7 | s.summary = "A simple, performant, single pass SVG parser" 8 | s.description = "A simple, performant, single pass SVG parser. Optimized for extension and developer joy." 9 | s.homepage = "https://github.com/mchoe/SwiftSVG" 10 | s.license = { :type => "MIT", :file => "LICENSE" } 11 | s.author = { "Michael Choe" => "michael@straussmade.com" } 12 | s.social_media_url = "http://twitter.com/_mchoe" 13 | s.osx.deployment_target = "10.11" 14 | s.ios.deployment_target = '8.0' 15 | s.tvos.deployment_target = '9.0' 16 | s.source = { :git => "https://github.com/mchoe/SwiftSVG.git", :tag => "v#{s.version}" } 17 | s.source_files = "SwiftSVG", "SwiftSVG/**/*.{h,swift}" 18 | s.resources = "SwiftSVG/SVG/Helpers/cssColorNames.json" 19 | s.swift_version = "5.0" 20 | end 21 | -------------------------------------------------------------------------------- /SwiftSVG.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftSVG.xcodeproj/xcshareddata/xcschemes/SwiftSVGTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 39 | 40 | 41 | 42 | 48 | 49 | 51 | 52 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /SwiftSVG.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SwiftSVG.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SwiftSVG/CrossPlatform.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CrossPlatform.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import Foundation 32 | 33 | #if os(iOS) || os(tvOS) 34 | import UIKit 35 | #elseif os(OSX) 36 | import AppKit 37 | public typealias UIView = NSView 38 | public typealias UIBezierPath = NSBezierPath 39 | public typealias UIColor = NSColor 40 | #endif 41 | 42 | extension UIView { 43 | var nonOptionalLayer:CALayer { 44 | #if os(iOS) || os(tvOS) 45 | return self.layer 46 | #elseif os(OSX) 47 | if let thisLayer = self.layer { 48 | let transform = CGAffineTransform( 49 | a: 1.0, b: 0.0, 50 | c: 0.0, d: -1.0, 51 | tx: 0.0, ty: self.bounds.size.height 52 | ) 53 | thisLayer.setAffineTransform(transform) 54 | return thisLayer 55 | } else { 56 | self.layer = CALayer() 57 | let transform = CGAffineTransform( 58 | a: 1.0, b: 0.0, 59 | c: 0.0, d: -1.0, 60 | tx: 0.0, ty: self.bounds.size.height 61 | ) 62 | self.layer?.setAffineTransform(transform) 63 | self.wantsLayer = true 64 | return self.layer! 65 | } 66 | #endif 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /SwiftSVG/NSBezierPath+CrossPlatform.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSBezierPath+CrossPlatform.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Created by Michael Choe on 1/5/17. 7 | // Copyright © 2017 Strauss LLC. All rights reserved. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | 28 | 29 | 30 | #if os(OSX) 31 | import AppKit 32 | 33 | public extension NSBezierPath { 34 | 35 | var cgPath: CGPath { 36 | get { 37 | let path = CGMutablePath() 38 | let points = NSPointArray.allocate(capacity: 3) 39 | 40 | for i in 0 ..< self.elementCount { 41 | let type = self.element(at: i, associatedPoints: points) 42 | switch type { 43 | case .moveTo: 44 | path.move(to: points[0]) 45 | case .lineTo: 46 | path.addLine(to: points[0]) 47 | case .curveTo: 48 | path.addCurve(to: points[2], control1: points[0], control2: points[1]) 49 | case .closePath: 50 | path.closeSubpath() 51 | } 52 | } 53 | return path 54 | } 55 | } 56 | 57 | func addLine(to point: NSPoint) { 58 | self.line(to: point) 59 | } 60 | 61 | func addCurve(to point: NSPoint, controlPoint1: NSPoint, controlPoint2: NSPoint) { 62 | self.curve(to: point, controlPoint1: controlPoint1, controlPoint2: controlPoint2) 63 | } 64 | 65 | func addQuadCurve(to point: NSPoint, controlPoint: NSPoint) { 66 | self.curve(to: point, 67 | controlPoint1: NSPoint( 68 | x: (controlPoint.x - self.currentPoint.x) * (2.0 / 3.0) + self.currentPoint.x, 69 | y: (controlPoint.y - self.currentPoint.y) * (2.0 / 3.0) + self.currentPoint.y), 70 | controlPoint2: NSPoint( 71 | x: (controlPoint.x - point.x) * (2.0 / 3.0) + point.x, 72 | y: (controlPoint.y - point.y) * (2.0 / 3.0) + point.y)) 73 | } 74 | 75 | } 76 | #endif 77 | -------------------------------------------------------------------------------- /SwiftSVG/SVG Extensions/CAShapeLayer+SVG.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CAShapeLayer+SVG.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | import UIKit 33 | #elseif os(OSX) 34 | import AppKit 35 | #endif 36 | 37 | 38 | 39 | public extension CAShapeLayer { 40 | 41 | /** 42 | Convenience initalizer that synchronously parses a single path string and returns a `CAShapeLayer` 43 | - Parameter pathString: The path `d` string to parse. 44 | */ 45 | convenience init(pathString: String) { 46 | self.init() 47 | let singlePath = SVGPath(singlePathString: pathString) 48 | self.path = singlePath.svgLayer.path 49 | } 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /SwiftSVG/SVG Extensions/SVGView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGView.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | import UIKit 33 | #elseif os(OSX) 34 | import AppKit 35 | #endif 36 | 37 | 38 | 39 | // TODO: Removing IBDesignable support for now seeing there 40 | // is a bug with using IBDesignables from a framework 41 | // 42 | // References: 43 | // https://openradar.appspot.com/23114017 44 | // https://github.com/Carthage/Carthage/issues/335 45 | // https://stackoverflow.com/questions/29933691/ibdesignable-from-external-framework 46 | 47 | //@IBDesignable 48 | 49 | /** 50 | A `UIView` subclass that can be used in Interface Builder where you can set the @IBInspectable propert `SVGName` in the side panel. Use the UIView extensions if you want to creates SVG views programmatically. 51 | */ 52 | open class SVGView : UIView { 53 | 54 | /** 55 | The name of the SVG file in the main bundle 56 | */ 57 | @IBInspectable 58 | open var svgName: String? { 59 | didSet { 60 | guard let thisName = self.svgName else { 61 | return 62 | } 63 | 64 | #if TARGET_INTERFACE_BUILDER 65 | let bundle = Bundle(for: type(of: self)) 66 | #else 67 | let bundle = Bundle.main 68 | #endif 69 | 70 | if let url = bundle.url(forResource: thisName, withExtension: "svg") { 71 | CALayer(svgURL: url) { [weak self] (svgLayer) in 72 | self?.nonOptionalLayer.addSublayer(svgLayer) 73 | } 74 | } else if #available(iOS 9.0, tvOS 9.0, OSX 10.11, *) { 75 | #if os(iOS) || os(tvOS) 76 | guard let asset = NSDataAsset(name: thisName, bundle: bundle) else { 77 | return 78 | } 79 | #elseif os(OSX) 80 | guard let asset = NSDataAsset(name: NSDataAsset.Name(thisName as NSString), bundle: bundle) else { 81 | return 82 | } 83 | #endif 84 | let data = asset.data 85 | CALayer(svgData: data) { [weak self] (svgLayer) in 86 | self?.nonOptionalLayer.addSublayer(svgLayer) 87 | } 88 | } 89 | 90 | 91 | } 92 | } 93 | 94 | /// :nodoc: 95 | @available(*, deprecated, renamed: "svgName") 96 | open var SVGName: String? 97 | } 98 | 99 | -------------------------------------------------------------------------------- /SwiftSVG/SVG Extensions/UIBezierPath+SVG.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIBezierPath+SVG.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | import UIKit 33 | #elseif os(OSX) 34 | import AppKit 35 | #endif 36 | 37 | /** 38 | Convenience initializer that can parse a single path string and returns a `UIBezierPath` 39 | */ 40 | 41 | public extension UIBezierPath { 42 | 43 | /** 44 | Parses a single path string. Parses synchronously. 45 | - Parameter pathString: The path `d` string to parse. 46 | */ 47 | convenience init(pathString: String) { 48 | let singlePath = SVGPath(singlePathString: pathString) 49 | guard let cgPath = singlePath.svgLayer.path else { 50 | self.init() 51 | return 52 | } 53 | #if os(iOS) || os(tvOS) 54 | self.init(cgPath: cgPath) 55 | #elseif os(OSX) 56 | self.init() 57 | #endif 58 | } 59 | 60 | /// :nodoc: 61 | @available(*, deprecated, message: "This method is deprecated. If you want to parse a single path, instantiate a new instance of SVGPath using the SVGPath(singlePathString:) initializer and pass the path string.") 62 | class func pathWithSVGURL(_ SVGURL: URL) -> UIBezierPath? { 63 | assert(false, "This method is deprecated") 64 | return nil 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Attributes/DelaysApplyingAttributes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DelaysApplyingAttributes.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | import UIKit 33 | #elseif os(OSX) 34 | import AppKit 35 | #endif 36 | 37 | /** 38 | A protocol that describes an instance that will delay processing attributes, usually until in `didProcessElement(in container: SVGContainerElement?)` because either all path information isn't available or when the element needs to apply an attribute to all subelements. 39 | */ 40 | public protocol DelaysApplyingAttributes { 41 | 42 | /** 43 | The attributes to apply to all sublayers after all subelements have been processed. 44 | - parameter Key: The name of an element's attribute such as `d`, `fill`, and `rx`. 45 | - parameter Value: The string value of the attribute passed from the parser, such as `"#ff00ee"` 46 | */ 47 | var delayedAttributes: [String : String] { get set } 48 | } 49 | 50 | /** 51 | An extension that applies any saved and supported attributes 52 | */ 53 | extension DelaysApplyingAttributes where Self : SVGElement { 54 | 55 | /** 56 | Applies any saved and supported attributes 57 | */ 58 | public mutating func applyDelayedAttributes() { 59 | for (attribute, value) in self.delayedAttributes { 60 | guard let closure = self.supportedAttributes[attribute] else { 61 | continue 62 | } 63 | closure(value) 64 | } 65 | 66 | self.supportedAttributes.removeAll() 67 | self.delayedAttributes.removeAll() 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Attributes/Identifiable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Identifiable 3 | // SwiftSVG 4 | // 5 | // 6 | // Thanks to Oliver Jones (@orj) for adding this. 7 | // Copyright (c) 2017 Michael Choe 8 | // http://www.github.com/mchoe 9 | // http://www.straussmade.com/ 10 | // http://www.twitter.com/_mchoe 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in 20 | // all copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | // THE SOFTWARE. 29 | 30 | import Foundation 31 | 32 | public protocol Identifiable { } 33 | 34 | extension Identifiable where Self : SVGShapeElement { 35 | 36 | /** 37 | The curried functions to be used for the `SVGShapeElement`'s default implementation. This dictionary is meant to be used in the `SVGParserSupportedElements` instance 38 | - parameter Key: The SVG string value of the attribute 39 | - parameter Value: A curried function to use to implement the SVG attribute 40 | */ 41 | var identityAttributes: [String : (String) -> ()] { 42 | return [ 43 | "id": self.identify 44 | ] 45 | } 46 | 47 | /** 48 | Sets the identifier of the underlying `SVGLayer`. 49 | - SeeAlso: CALayer's [`name`](https://developer.apple.com/documentation/quartzcore/calayer/1410879-name) property 50 | */ 51 | func identify(identifier: String) { 52 | self.svgLayer.name = identifier 53 | } 54 | } 55 | 56 | extension Identifiable where Self : SVGGroup { 57 | /** 58 | The curried functions to be used for the `SVGShapeElement`'s default implementation. This dictionary is meant to be used in the `SVGParserSupportedElements` instance 59 | - parameter Key: The SVG string value of the attribute 60 | - parameter Value: A curried function to use to implement the SVG attribute 61 | */ 62 | var identityAttributes: [String : (String) -> ()] { 63 | return [ 64 | "id": unown(self, SVGGroup.identify) 65 | ] 66 | } 67 | } 68 | 69 | extension Identifiable where Self : SVGContainerElement { 70 | 71 | /** 72 | The curried functions to be used for the `SVGShapeElement`'s default implementation. This dictionary is meant to be used in the `SVGParserSupportedElements` instance 73 | - parameter Key: The SVG string value of the attribute 74 | - parameter Value: A curried function to use to implement the SVG attribute 75 | */ 76 | var identityAttributes: [String : (String) -> ()] { 77 | return [ 78 | "id": self.identify 79 | ] 80 | } 81 | 82 | /** 83 | Sets the identifier of the underlying `SVGLayer`. 84 | - SeeAlso: CALayer's [`name`](https://developer.apple.com/documentation/quartzcore/calayer/1410879-name) property 85 | */ 86 | func identify(identifier: String) { 87 | self.containerLayer.name = identifier 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Cache/SVGCache.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGCache.swift 3 | // SwiftSVG 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | 29 | 30 | #if os(iOS) || os(tvOS) 31 | import UIKit 32 | #elseif os(OSX) 33 | import AppKit 34 | #endif 35 | 36 | /** 37 | A minimal in-memory cache class for caching `SVGLayer`s. The `default` singleton is the default cache used and you can optionally create your own static singleton through an extension. 38 | */ 39 | open class SVGCache { 40 | 41 | /// A singleton object that is the default store for `SVGlayer`s 42 | public static let `default` = SVGCache() 43 | 44 | /// :nodoc: 45 | public let memoryCache = NSCache() 46 | 47 | /// Subscript to get or set the `SVGLayer` in this cache 48 | public subscript(key: String) -> SVGLayer? { 49 | get { 50 | return self.memoryCache.object(forKey: key as NSString) 51 | } 52 | set { 53 | guard let newValue = newValue else { 54 | return 55 | } 56 | self.memoryCache.setObject(newValue, forKey: key as NSString) 57 | } 58 | } 59 | 60 | /// Removes the value from the cache 61 | public func removeObject(key: String) { 62 | self.memoryCache.removeObject(forKey: key as NSString) 63 | } 64 | } 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Elements/ParsesAsynchronously.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ParsesAsynchronously.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | import UIKit 33 | #elseif os(OSX) 34 | import AppKit 35 | #endif 36 | 37 | 38 | /** 39 | A protocol describing an instance that can manage elements that can parse asynchronously. In the `NSXMLSVGParser` implementation, the parser maintains a simple count of pending asynchronous tasks and decrements the count when an element has finished parsing. When the count has reached zero, a completion block is called 40 | */ 41 | protocol CanManageAsychronousParsing { 42 | /** 43 | The callback called when an `ParsesAsynchronously` element has finished parsing 44 | - Parameter shapeLayer: The completed layer 45 | */ 46 | func finishedProcessing(_ shapeLayer: CAShapeLayer) 47 | } 48 | 49 | /** 50 | A protocol describing an instance that parses asynchronously 51 | */ 52 | protocol ParsesAsynchronously { 53 | /** 54 | The delegate instance that can manage asynchronous parsing 55 | */ 56 | var asyncParseManager: CanManageAsychronousParsing? { get set } 57 | } 58 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Elements/SVGContainerElement.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGContainerElement.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | import UIKit 33 | #elseif os(OSX) 34 | import AppKit 35 | #endif 36 | 37 | 38 | /** 39 | A protocol that describes an instance that can store SVG sublayers and can apply a single attributes to all sublayers. 40 | */ 41 | 42 | public protocol SVGContainerElement: SVGElement, DelaysApplyingAttributes, Fillable, Strokable, Transformable, Stylable, Identifiable { 43 | 44 | /** 45 | The layer that stores all the SVG sublayers 46 | */ 47 | var containerLayer: CALayer { get set } 48 | } 49 | 50 | 51 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Elements/SVGElement.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGElement.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | import UIKit 33 | #elseif os(OSX) 34 | import AppKit 35 | #endif 36 | 37 | // NOTE: For the supported attributes, I wanted to use a little currying 38 | // magic so that it could potentially take any method on any arbitrary 39 | // type. The type signature would look like this `[String : (Self) -> (String) -> ()]` 40 | // 41 | // Unfortunately, I couldn't get this to work because the curried type wouldn't be known 42 | // at runtime. Understandable, and my first inclination was to use type erasure to no avail. 43 | // I think if and when Swift adopts language level type erasure, then 44 | // this will be possible. I'm flagging this here to keep that in mind because 45 | // I think that will yield a cleaner design and implementation. 46 | // 47 | // For now, I'm still using currying, but you have to provide an instance to the partially 48 | // applied function. 49 | // 50 | // -Michael Choe 06.03.17 51 | 52 | 53 | 54 | /** 55 | A protocol describing an instance that can parse a single SVG element such as 56 | `, , `. 57 | */ 58 | 59 | public protocol SVGElement { 60 | 61 | /** 62 | The element name as defined in the SVG specification 63 | - SeeAlso: Official [SVG Element Names](https://www.w3.org/TR/SVG/eltindex.html) 64 | */ 65 | static var elementName: String { get } 66 | 67 | /** 68 | Dictionary of attributes of a given element that are supported by the `SVGParser`. Keys are the name of an element's attribute such as `d`, `fill`, and `rx`. Values are a closure that is used to process the given attribute. 69 | */ 70 | var supportedAttributes: [String : (String) -> ()] { get set } 71 | 72 | 73 | /** 74 | An action to perform once the parser has dispatched all attributes to a given `SVGElement` instance 75 | - Note: If using the default `NSXMLSVGParser` and the element parses asynchronously, there is no guarantee that the instance will be finished processing all the attribites when this is called. 76 | */ 77 | func didProcessElement(in container: SVGContainerElement?) 78 | } 79 | 80 | 81 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Elements/SVGPolygon.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGPolygon.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | import UIKit 33 | #elseif os(OSX) 34 | import AppKit 35 | #endif 36 | 37 | /** 38 | Concrete implementation that creates a `CAShapeLayer` from a `` element and its attributes 39 | */ 40 | 41 | struct SVGPolygon: SVGShapeElement { 42 | 43 | /// :nodoc: 44 | internal static let elementName = "polygon" 45 | 46 | /// :nodoc: 47 | internal var supportedAttributes: [String : (String) -> ()] = [:] 48 | 49 | /// :nodoc: 50 | internal var svgLayer = CAShapeLayer() 51 | 52 | /** 53 | Function that parses a coordinate string and creates a polygon path 54 | */ 55 | internal func points(points: String) { 56 | let polylinePath = UIBezierPath() 57 | for (index, thisPoint) in CoordinateLexer(coordinateString: points).enumerated() { 58 | if index == 0 { 59 | polylinePath.move(to: thisPoint) 60 | } else { 61 | polylinePath.addLine(to: thisPoint) 62 | } 63 | } 64 | polylinePath.close() 65 | self.svgLayer.path = polylinePath.cgPath 66 | } 67 | 68 | /// :nodoc: 69 | internal func didProcessElement(in container: SVGContainerElement?) { 70 | guard let container = container else { 71 | return 72 | } 73 | container.containerLayer.addSublayer(self.svgLayer) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Elements/SVGPolyline.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGPolyline.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | import UIKit 33 | #elseif os(OSX) 34 | import AppKit 35 | #endif 36 | 37 | /** 38 | Concrete implementation that creates a `CAShapeLayer` from a `` element and its attributes 39 | */ 40 | 41 | struct SVGPolyline: SVGShapeElement { 42 | 43 | /// :nodoc: 44 | internal static let elementName = "polyline" 45 | 46 | /// :nodoc: 47 | internal var supportedAttributes: [String : (String) -> ()] = [:] 48 | 49 | /// :nodoc: 50 | internal var svgLayer = CAShapeLayer() 51 | 52 | /** 53 | Parses a coordinate string and creates a new polyline based on them 54 | */ 55 | internal func points(points: String) { 56 | let polylinePath = UIBezierPath() 57 | for (index, thisPoint) in CoordinateLexer(coordinateString: points).enumerated() { 58 | if index == 0 { 59 | polylinePath.move(to: thisPoint) 60 | } else { 61 | polylinePath.addLine(to: thisPoint) 62 | } 63 | } 64 | self.svgLayer.path = polylinePath.cgPath 65 | } 66 | 67 | /// :nodoc: 68 | internal func didProcessElement(in container: SVGContainerElement?) { 69 | guard let container = container else { 70 | return 71 | } 72 | container.containerLayer.addSublayer(self.svgLayer) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Elements/SVGRootElement.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGRootElement.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | import UIKit 33 | #elseif os(OSX) 34 | import AppKit 35 | #endif 36 | 37 | /** 38 | Concrete implementation that creates a container from a `` element and its attributes. This will almost always be the root container element that will container all other `SVGElement` layers 39 | */ 40 | 41 | struct SVGRootElement: SVGContainerElement { 42 | 43 | /// :nodoc: 44 | internal static let elementName = "svg" 45 | 46 | // :nodoc: 47 | internal var delayedAttributes = [String : String]() 48 | 49 | // :nodoc: 50 | internal var containerLayer = CALayer() 51 | 52 | // :nodoc: 53 | internal var supportedAttributes = [String : (String) -> ()]() 54 | 55 | /** 56 | Function that parses a number string and sets the `containerLayer`'s width 57 | */ 58 | internal func parseWidth(lengthString: String) { 59 | if let width = CGFloat(lengthString: lengthString) { 60 | self.containerLayer.frame.size.width = width 61 | } 62 | } 63 | 64 | /** 65 | Function that parses a number string and sets the `containerLayer`'s height 66 | */ 67 | internal func parseHeight(lengthString: String) { 68 | if let height = CGFloat(lengthString: lengthString) { 69 | self.containerLayer.frame.size.height = height 70 | } 71 | } 72 | 73 | /// :nodoc: 74 | internal func didProcessElement(in container: SVGContainerElement?) { 75 | return 76 | } 77 | 78 | /// nodoc: 79 | internal func viewBox(coordinates: String) { 80 | let points = coordinates 81 | .components(separatedBy: CharacterSet(charactersIn: ", ")) 82 | .compactMap { (thisString) -> Double? in 83 | return Double(thisString.trimWhitespace()) 84 | } 85 | guard points.count == 4 else { 86 | return 87 | } 88 | self.containerLayer.frame = CGRect(x: points[0], y: points[1], width: points[2], height: points[3]) 89 | } 90 | } 91 | 92 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Elements/SVGShapeElement.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGShapeElement.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | import UIKit 33 | #elseif os(OSX) 34 | import AppKit 35 | #endif 36 | 37 | 38 | /** 39 | A protocol that describes an instance that stores the path as a `CAShapeLayer` 40 | */ 41 | public protocol SVGShapeElement: SVGElement, Fillable, Strokable, Transformable, Stylable, Identifiable { 42 | 43 | /** 44 | The `CAShapeLayer` that can draw the path data. 45 | */ 46 | var svgLayer: CAShapeLayer { get set } 47 | } 48 | 49 | extension SVGShapeElement { 50 | 51 | /** 52 | The minimum rect that encompasses all of the subpaths 53 | */ 54 | var boundingBox: CGRect? { 55 | return self.svgLayer.path?.boundingBox 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Helpers/BinaryFloatingPoint+ParseLengthString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FloatingPoint+ParseLengthString.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import Foundation 32 | 33 | /** 34 | Extension that takes a length string, e.g. `100px`, `20mm` and parses it into a `BinaryFloatingPoint` (e.g. `Float`, `Double`, `CGFloat`) 35 | */ 36 | extension BinaryFloatingPoint { 37 | 38 | /** 39 | Parses a number string with optional suffix, such as `px`, `mm` 40 | */ 41 | internal init?(lengthString: String) { 42 | 43 | let simpleNumberClosure: (String) -> Double? = { (string) -> Double? in 44 | return Double(string) 45 | } 46 | 47 | if let thisNumber = simpleNumberClosure(lengthString) { 48 | self.init(thisNumber) 49 | return 50 | } 51 | 52 | let numberFromSupportedSuffix: (String, String) -> Double? = { (string, suffix) -> Double? in 53 | if string.hasSuffix(suffix) { 54 | return simpleNumberClosure(string[0..(ofType: T.Type, closure: (T) -> ()) { 47 | _ = self.sublayers(in: self).map(closure) 48 | } 49 | 50 | /** 51 | Helper function that returns an array of all sublayers of a given type 52 | */ 53 | public func sublayers(in layer: T) -> [U] { 54 | 55 | var sublayers = [U]() 56 | 57 | guard let allSublayers = layer.sublayers else { 58 | return sublayers 59 | } 60 | 61 | for thisSublayer in allSublayers { 62 | sublayers += self.sublayers(in: thisSublayer) 63 | if let thisSublayer = thisSublayer as? U { 64 | sublayers.append(thisSublayer) 65 | } 66 | } 67 | return sublayers 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Helpers/Data+CacheKey.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Data+CacheKey.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import Foundation 32 | 33 | extension Data { 34 | var cacheKey: String { 35 | return "\(self.hashValue)-\(self.count)" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Helpers/Dictionary+Add.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Dictionary+Add.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import Foundation 32 | 33 | 34 | /** 35 | An extension that add the elements of one dictionary to another 36 | */ 37 | extension Dictionary { 38 | 39 | /** 40 | An extension that add the elements of one dictionary to another 41 | */ 42 | public mutating func add(_ dictionary: [Key : Value]) { 43 | for (key, value) in dictionary { 44 | self[key] = value 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Helpers/Dictionary+JSON.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Dictionary+JSON.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2019 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | import Foundation 30 | 31 | extension Dictionary where Key: Decodable, Value: Decodable { 32 | 33 | init?(jsonFile name: String?) { 34 | guard let jsonPath = Bundle(for: NSXMLSVGParser.self).url(forResource: name, withExtension: "json") else { 35 | return nil 36 | } 37 | guard let jsonData = try? Data(contentsOf: jsonPath) else { 38 | return nil 39 | } 40 | guard let asDictionary = try? JSONDecoder().decode([Key : Value].self, from: jsonData) else { 41 | return nil 42 | } 43 | self = asDictionary 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Helpers/DispatchQueue+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DispatchQueue+Extensions.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import Foundation 32 | 33 | 34 | extension DispatchQueue { 35 | 36 | /** 37 | An extension that will immediately execute the given block if already on the main thread 38 | */ 39 | internal func safeAsync(_ block: @escaping () -> ()) { 40 | if self === DispatchQueue.main && Thread.isMainThread { 41 | block() 42 | } else { 43 | self.async { 44 | block() 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Helpers/FloatingPoint+DegreesRadians.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FloatingPoint+DegreesRadians.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import Foundation 32 | 33 | /** 34 | Extension that converts a `FloatingPoint` to and from radians and degrees 35 | */ 36 | extension FloatingPoint { 37 | 38 | /** 39 | Converts a `FloatingPoint` type to radians 40 | */ 41 | public var toRadians: Self { 42 | return self * .pi / 180 43 | } 44 | 45 | /** 46 | Converts a `FloatingPoint` type to degrees 47 | */ 48 | public var toDegrees: Self { 49 | return self * 180 / .pi 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Helpers/Print.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Print.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2019 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | import Foundation 30 | 31 | func print(_ item: @autoclosure () -> Any, separator: String = " ", terminator: String = "\n") { 32 | #if DEBUG 33 | Swift.print(item(), separator: separator, terminator: terminator) 34 | #endif 35 | } 36 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Helpers/Scalar+FromByteArray.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Scalar+FromByteArray.swift 3 | // SwiftSVGiOS 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import CoreGraphics 32 | 33 | 34 | 35 | extension CGFloat { 36 | 37 | /** 38 | Initializer that creates a new CGFloat from a String 39 | */ 40 | internal init?(_ string: String) { 41 | guard let asDouble = Double(string) else { 42 | return nil 43 | } 44 | self.init(asDouble) 45 | } 46 | 47 | /** 48 | Initializer that creates a new CGFloat from a Character byte array with the option to set the base. 49 | */ 50 | internal init?(byteArray: [CChar], base: Int32 = 10) { 51 | var nullTerminated = byteArray 52 | nullTerminated.append(0) 53 | self.init(strtol(nullTerminated, nil, base)) 54 | } 55 | 56 | } 57 | 58 | 59 | extension Float { 60 | 61 | /** 62 | Initializer that creates a new Float from a Character byte array 63 | */ 64 | internal init?(byteArray: [CChar]) { 65 | 66 | guard byteArray.count > 0 else { 67 | return nil 68 | } 69 | var nullTerminated = byteArray 70 | nullTerminated.append(0) 71 | var error: UnsafeMutablePointer? = nil 72 | let result = strtof(nullTerminated, &error) 73 | if error != nil && error?.pointee != 0 { 74 | return nil 75 | } 76 | self = result 77 | } 78 | 79 | } 80 | 81 | extension Double { 82 | 83 | /** 84 | Initializer that creates a new Double from a Character byte array 85 | */ 86 | internal init?(byteArray: [CChar]) { 87 | 88 | guard byteArray.count > 0 else { 89 | return nil 90 | } 91 | var nullTerminated = byteArray 92 | nullTerminated.append(0) 93 | var error: UnsafeMutablePointer? = nil 94 | let result = strtod(nullTerminated, &error) 95 | if error != nil && error?.pointee != 0 { 96 | return nil 97 | } 98 | self = result 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Helpers/Stack.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Stack.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | 32 | import Foundation 33 | 34 | /** 35 | A protocol that describes an instance that can act as a stack data structure 36 | */ 37 | protocol StackType { 38 | associatedtype StackItem 39 | var items: [StackItem] { get set } 40 | init() 41 | mutating func pop() -> StackItem? 42 | mutating func push(_ itemToPush: StackItem) 43 | } 44 | 45 | /** 46 | A stack data structure 47 | */ 48 | internal struct Stack: StackType { 49 | var items = [T]() 50 | init() { } 51 | } 52 | 53 | extension StackType { 54 | 55 | /** 56 | Default implementation of popping the last element off the stack 57 | */ 58 | @discardableResult 59 | mutating func pop() -> StackItem? { 60 | guard self.items.count > 0 else { 61 | return nil 62 | } 63 | return self.items.removeLast() 64 | } 65 | 66 | /** 67 | Push a new element on to the stack 68 | */ 69 | mutating func push(_ itemToPush: StackItem) { 70 | self.items.append(itemToPush) 71 | } 72 | 73 | /** 74 | Clear all elements from the stack 75 | */ 76 | mutating func clear() { 77 | self.items.removeAll() 78 | } 79 | 80 | /** 81 | Returns the number of elements on the stack 82 | */ 83 | var count: Int { 84 | get { 85 | return self.items.count 86 | } 87 | } 88 | 89 | /** 90 | Check whether the stack is empty or not 91 | */ 92 | var isEmpty: Bool { 93 | get { 94 | if self.items.count == 0 { 95 | return true 96 | } 97 | return false 98 | } 99 | } 100 | 101 | /** 102 | Return the last element on the stack without popping it off the stack. Equivalent to peek in other stack implementations 103 | */ 104 | var last: StackItem? { 105 | get { 106 | if self.isEmpty == false { 107 | return self.items.last 108 | } 109 | return nil 110 | } 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Helpers/String+Subscript.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String+Subscript.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import Foundation 32 | #if os(iOS) || os(tvOS) 33 | import UIKit 34 | #elseif os(OSX) 35 | import AppKit 36 | #endif 37 | 38 | 39 | public extension String { 40 | 41 | /// Helper function that creates a new String from a given integer range 42 | subscript(integerRange: Range) -> String { 43 | get { 44 | let start = self.index(self.startIndex, offsetBy: integerRange.lowerBound) 45 | let end = self.index(self.startIndex, offsetBy: integerRange.upperBound) 46 | return String(self[start.. String { 42 | return self.trimmingCharacters(in: CharacterSet.whitespaces) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Helpers/Unown.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Unown.swift 3 | // SwiftSVG 4 | // 5 | // Created by Quentin Fasquel on 06/07/2018. 6 | // Copyright © 2018 Strauss LLC. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public func unown(_ owner: T, _ method: @escaping (T) -> ((U) -> V)) -> (U) -> V { 12 | return { [unowned owner] arg in method(owner)(arg) } 13 | } 14 | -------------------------------------------------------------------------------- /SwiftSVG/SVG/Parser/SVGParser.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGParser.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | import UIKit 33 | #elseif os(OSX) 34 | import AppKit 35 | #endif 36 | 37 | 38 | /* 39 | struct SVGParseOptions: OptionSet { 40 | let rawValue: Int 41 | 42 | static let shouldParseAsynchronously = SVGParseOptions(rawValue: 1 << 0) 43 | } 44 | */ 45 | 46 | 47 | 48 | /** 49 | A protocol describing an XML parser capable of parsing SVG data 50 | */ 51 | public protocol SVGParser { 52 | 53 | /** 54 | Initializer to create a new `SVGParser` instance 55 | - parameters: 56 | - SVGData: SVG file as Data 57 | - supportedElements: The elements and corresponding attribiutes the parser can parse 58 | - completion: A closure to execute after the parser has completed parsing and processing the SVG 59 | */ 60 | init(svgData: Data, supportedElements: SVGParserSupportedElements?, completion: ((SVGLayer) -> ())?) 61 | 62 | /// A closure that is executed after all elements have been processed. Should be guaranteed to be executed after all elements have been processed, even if parsing asynchronously. 63 | var completionBlock: ((SVGLayer) -> ())? { get } 64 | 65 | /// A struct listing all the elements and its attributes that should be parsed 66 | var supportedElements: SVGParserSupportedElements? { get } 67 | 68 | /// A `CALayer` that will house the finished sublayers of the SVG doc. 69 | var containerLayer: SVGLayer { get } 70 | 71 | /// Starts parsing the SVG. Allows you to separate initialization from parse start in case you want to set some things up first. 72 | func startParsing() 73 | } 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleMac/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SwiftSVGExampleMac 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | 29 | 30 | import Cocoa 31 | 32 | @NSApplicationMain 33 | class AppDelegate: NSObject, NSApplicationDelegate { 34 | 35 | func applicationDidFinishLaunching(_ aNotification: Notification) { 36 | // Insert code here to initialize your application 37 | } 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleMac/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleMac/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2016 Michael Choe. All rights reserved. 29 | NSMainStoryboardFile 30 | Main 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleMac/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SwiftSVGExampleMac 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | 29 | 30 | import Cocoa 31 | 32 | class ViewController: NSViewController { 33 | 34 | override func viewDidLoad() { 35 | super.viewDidLoad() 36 | 37 | // Do any additional setup after loading the view. 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SwiftSVGExampleTVOS 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | 29 | import UIKit 30 | 31 | @UIApplicationMain 32 | class AppDelegate: UIResponder, UIApplicationDelegate { 33 | 34 | var window: UIWindow? 35 | 36 | 37 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 38 | // Override point for customization after application launch. 39 | return true 40 | } 41 | 42 | func applicationWillResignActive(_ application: UIApplication) { 43 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 44 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 45 | } 46 | 47 | func applicationDidEnterBackground(_ application: UIApplication) { 48 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 49 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 50 | } 51 | 52 | func applicationWillEnterForeground(_ application: UIApplication) { 53 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 54 | } 55 | 56 | func applicationDidBecomeActive(_ application: UIApplication) { 57 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 58 | } 59 | 60 | func applicationWillTerminate(_ application: UIApplication) { 61 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 62 | } 63 | 64 | 65 | } 66 | 67 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "size" : "1280x768", 5 | "idiom" : "tv", 6 | "filename" : "App Icon - Large.imagestack", 7 | "role" : "primary-app-icon" 8 | }, 9 | { 10 | "size" : "400x240", 11 | "idiom" : "tv", 12 | "filename" : "App Icon - Small.imagestack", 13 | "role" : "primary-app-icon" 14 | }, 15 | { 16 | "size" : "2320x720", 17 | "idiom" : "tv", 18 | "filename" : "Top Shelf Image Wide.imageset", 19 | "role" : "top-shelf-image-wide" 20 | }, 21 | { 22 | "size" : "1920x720", 23 | "idiom" : "tv", 24 | "filename" : "Top Shelf Image.imageset", 25 | "role" : "top-shelf-image" 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "landscape", 5 | "idiom" : "tv", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "9.0", 8 | "scale" : "1x" 9 | } 10 | ], 11 | "info" : { 12 | "version" : 1, 13 | "author" : "xcode" 14 | } 15 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIMainStoryboardFile 24 | Main 25 | UIRequiredDeviceCapabilities 26 | 27 | arm64 28 | 29 | UIUserInterfaceStyle 30 | Automatic 31 | 32 | 33 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleTVOS/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SwiftSVGExampleTVOS 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | 29 | import SwiftSVG 30 | import UIKit 31 | 32 | class ViewController: UIViewController { 33 | 34 | @IBOutlet weak var svgView: UIView! 35 | 36 | override func viewDidLoad() { 37 | super.viewDidLoad() 38 | let thisSVGView = UIView(svgNamed: "hawaiiFlowers") { (svgLayer) in 39 | svgLayer.resizeToFit(self.svgView.bounds) 40 | } 41 | self.svgView.addSubview(thisSVGView) 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleiOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SwiftSVGExampleiOS 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | 29 | 30 | import UIKit 31 | 32 | @UIApplicationMain 33 | class AppDelegate: UIResponder, UIApplicationDelegate { 34 | 35 | var window: UIWindow? 36 | 37 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 38 | // Override point for customization after application launch. 39 | return true 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleiOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleiOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleiOS/Assets.xcassets/cowboyHat.dataset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "data" : [ 7 | { 8 | "idiom" : "universal", 9 | "filename" : "cowboyHat.svg", 10 | "universal-type-identifier" : "public.svg-image" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleiOS/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleiOS/GithubCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GithubCell.swift 3 | // SwiftSVGExamples 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | 29 | 30 | import UIKit 31 | 32 | class GithubCell: UICollectionViewCell { 33 | 34 | @IBOutlet weak var svgView: UIView! 35 | } 36 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleiOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleiOS/SingleSVGViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewSVGViewController.swift 3 | // SwiftSVGExamples 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | 29 | 30 | import SwiftSVG 31 | import UIKit 32 | 33 | 34 | class SingleSVGViewController: UIViewController { 35 | 36 | @IBOutlet weak var canvasView: UIView! 37 | 38 | var svgURL = URL(string: "https://openclipart.org/download/181651/manhammock.svg") 39 | 40 | override func viewDidLoad() { 41 | super.viewDidLoad() 42 | 43 | self.automaticallyAdjustsScrollViewInsets = false 44 | 45 | guard let url = self.svgURL else { 46 | return 47 | } 48 | 49 | let svgView = UIView(svgURL: url) { (svgLayer) in 50 | svgLayer.resizeToFit(self.canvasView.bounds) 51 | } 52 | svgView.backgroundColor = UIColor.blue 53 | self.canvasView.addSubview(svgView) 54 | } 55 | 56 | } 57 | 58 | extension SingleSVGViewController: UIScrollViewDelegate { 59 | 60 | func viewForZooming(in scrollView: UIScrollView) -> UIView? { 61 | return self.canvasView 62 | } 63 | 64 | } 65 | 66 | 67 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleiOS/StartCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StartCell.swift 3 | // SwiftSVGExamples 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | 29 | 30 | import UIKit 31 | 32 | class StartCell: UITableViewCell { 33 | @IBOutlet weak var titleLabel: UILabel! 34 | @IBOutlet weak var subtitleLabel: UILabel! 35 | } 36 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExampleiOS/VariousCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VariousCell.swift 3 | // SwiftSVGExamples 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | 29 | 30 | import UIKit 31 | 32 | class VariousCell: UICollectionViewCell { 33 | 34 | @IBOutlet weak var svgView: UIView! 35 | 36 | override func prepareForReuse() { 37 | for thisSublayer in self.svgView.layer.sublayers! { 38 | thisSublayer.removeFromSuperlayer() 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExamples.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftSVGExamples/SwiftSVGExamples.xcodeproj/xcshareddata/xcschemes/SwiftSVGExampleiOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /SwiftSVGExamples/TestSVGs/baseball.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SwiftSVGExamples/TestSVGs/circles.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /SwiftSVGExamples/TestSVGs/ellipses.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /SwiftSVGExamples/TestSVGs/error.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /SwiftSVGExamples/TestSVGs/openclipart-1332611679.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | image/svg+xmlOpenclipartStanding dog silhouette2012-03-24T13:54:39clip art, clipart, dog, realistic, silhouette, simple, standing, http://openclipart.org/detail/169096/standing-dog-silhouette-by-nehtaeh79nehtaeh79clip artclipartdogrealisticsilhouettesimplestanding 7 | -------------------------------------------------------------------------------- /SwiftSVGExamples/TestSVGs/polygons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | polygons 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /SwiftSVGExamples/TestSVGs/polylines.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /SwiftSVGExamples/TestSVGs/raphaelcruzeiro.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | Bike-unselected 6 | 10 | 18 | -------------------------------------------------------------------------------- /SwiftSVGExamples/TestSVGs/rectangles.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /SwiftSVGExamples/TestSVGs/simple-rectangle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /SwiftSVGExamples/TestSVGs/sockPuppet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | fistBump 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /SwiftSVGExamples/TestSVGs/triangle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SwiftSVGFramework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /SwiftSVGFramework/SwiftSVGFramework.h: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftSVGiOSFramework.h 3 | // SwiftSVGiOSFramework 4 | // 5 | // Created by Matthias Schlemm on 25/06/15. 6 | // Copyright (c) 2015 Strauss LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for SwiftSVGiOSFramework. 12 | FOUNDATION_EXPORT double SwiftSVGiOSFrameworkVersionNumber; 13 | 14 | //! Project version string for SwiftSVGiOSFramework. 15 | FOUNDATION_EXPORT const unsigned char SwiftSVGiOSFrameworkVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /SwiftSVGTests/ClosePathTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ClosePathTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class ClosePathTests: XCTestCase { 34 | 35 | func testClosePath() { 36 | let testPath = UIBezierPath() 37 | _ = MoveTo(parameters: [20, -30], pathType: .absolute, path:testPath) 38 | _ = ClosePath(parameters: [], pathType: .absolute, path:testPath) 39 | let lastPointAndType = testPath.cgPath.pointsAndTypes.last! 40 | XCTAssert(lastPointAndType.1 == .closeSubpath, "Expected .closeSubpath, got \(lastPointAndType.1)") 41 | XCTAssert(lastPointAndType.0.x.isNaN == true && lastPointAndType.0.y.isNaN == true, "Expected NaN, NaN, got \(lastPointAndType.0)") 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /SwiftSVGTests/CoordinateLexerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CoordinateLexerTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class IteratorTests: XCTestCase { 34 | 35 | func testWhitespace() { 36 | var testString = " 0,40 40,40 40,80 80,80 80,120 120,120 120,160" 37 | var coordinateArray = [CGPoint]() 38 | var coordinateSequence = CoordinateLexer(coordinateString: testString) 39 | for thisPoint in coordinateSequence { 40 | coordinateArray.append(thisPoint) 41 | } 42 | XCTAssertTrue(coordinateArray[0].equalTo(CGPoint(x: 0, y: 40.0)), "Expected (0, 40), got \(coordinateArray[0])") 43 | XCTAssertTrue(coordinateArray[coordinateArray.count-1].equalTo(CGPoint(x: 120, y: 160.0)), "Expected (120, 160), got \(coordinateArray[coordinateArray.count-1])") 44 | 45 | coordinateArray.removeAll() 46 | testString = "0,40 40,40 40,80 80,80 80,120 120,120 120,160 " 47 | coordinateSequence = CoordinateLexer(coordinateString: testString) 48 | for thisPoint in coordinateSequence { 49 | coordinateArray.append(thisPoint) 50 | } 51 | XCTAssertTrue(coordinateArray[1].equalTo(CGPoint(x: 40, y: 40)), "Expected (40, 40), got \(coordinateArray[1])") 52 | XCTAssertTrue(coordinateArray[coordinateArray.count-2].equalTo(CGPoint(x: 120, y: 120.0)), "Expected (120, 120), got \(coordinateArray[coordinateArray.count-2])") 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /SwiftSVGTests/CurveToTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CurveToTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class CurveToTests: XCTestCase { 34 | 35 | func testAbsoluteCurveTo() { 36 | let testPath = UIBezierPath() 37 | _ = MoveTo(parameters: [10, -20], pathType: .absolute, path: testPath) 38 | _ = CurveTo(parameters: [66, 37, 32, -18, 23, 98], pathType: .absolute, path: testPath) 39 | let points = testPath.cgPath.points 40 | XCTAssert(points[0].x == 10 && points[0].y == -20, "Expected 10, -20, got \(points[0])") 41 | XCTAssert(points[1].x == 66 && points[1].y == 37, "Expected 66, 37, got \(points[1])") 42 | XCTAssert(points[2].x == 32 && points[2].y == -18, "Expected 32, -18, got \(points[2])") 43 | XCTAssert(points[3].x == 23 && points[3].y == 98, "Expected 23, 98, got \(points[3])") 44 | XCTAssert(points[3].x == testPath.currentPoint.x && points[3].y == testPath.currentPoint.y, "Expected {\(testPath.currentPoint)}, got \(points[3])") 45 | } 46 | 47 | func testRelativeCurveTo() { 48 | let testPath = UIBezierPath() 49 | _ = MoveTo(parameters: [10, -20], pathType: .absolute, path: testPath) 50 | _ = CurveTo(parameters: [66, 37, 32, -18, 23, 98], pathType: .relative, path: testPath) 51 | let points = testPath.cgPath.points 52 | XCTAssert(points[0].x == 10 && points[0].y == -20, "Expected 10, -20, got \(points[0])") 53 | XCTAssert(points[1].x == 76 && points[1].y == 17, "Expected 76, 17, got \(points[1])") 54 | XCTAssert(points[2].x == 42 && points[2].y == -38, "Expected 42, -38, got \(points[2])") 55 | XCTAssert(points[3].x == 33 && points[3].y == 78, "Expected 33, 78, got \(points[3])") 56 | XCTAssert(points[3].x == testPath.currentPoint.x && points[3].y == testPath.currentPoint.y, "Expected {\(testPath.currentPoint)}, got \(points[3])") 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /SwiftSVGTests/DictionaryAddTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DictionaryAddTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class DictionaryMergeTests: XCTestCase { 34 | 35 | var one = [ 36 | "one": "one", 37 | "two": "two", 38 | "three": "three", 39 | "four": "four", 40 | "five": "five", 41 | "six": "six", 42 | "seven": "seven", 43 | "eight": "eight", 44 | "nine": "nine", 45 | "ten": "ten" 46 | ] 47 | var two = [ 48 | "eleven": "eleven", 49 | "twelve": "twelve", 50 | "thirteen": "thirteen", 51 | "fourteen": "fourteen", 52 | "fifteen": "fifteen", 53 | "sixteen": "sixteen", 54 | "seventeen": "seventeen", 55 | "eighteen": "eighteen", 56 | "nineteen": "nineteen", 57 | "twenty": "twenty", 58 | ] 59 | 60 | func testForEach() { 61 | self.measure { 62 | self.two.forEach{ 63 | self.one[$0] = $1 64 | } 65 | } 66 | } 67 | 68 | func testForIn() { 69 | self.measure { 70 | for (key, value) in self.two { 71 | self.one[key] = value 72 | } 73 | } 74 | } 75 | 76 | func testMerge() { 77 | self.one.add(self.two) 78 | XCTAssert(self.one.count == 20, "Expected 20, got \(self.one.count)") 79 | XCTAssert(self.one["twenty"] == "twenty", "Expected \"twenty\", got \(self.one["twenty"]!)") 80 | } 81 | 82 | 83 | } 84 | -------------------------------------------------------------------------------- /SwiftSVGTests/FillableTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FillableTests.swift 3 | // SwiftSVG 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | 29 | import XCTest 30 | 31 | class FillableTests: XCTestCase { 32 | 33 | func testFillOpacity() { 34 | let testShapeElement = TestShapeElement() 35 | testShapeElement.fill(fillColor: "#00FF33") 36 | testShapeElement.fillOpacity(opacity: "0.5") 37 | XCTAssert(testShapeElement.svgLayer.opacity == 1.0, "Fill opacity should be set on the CAShapelayer's fill color and not on the layer's overall opacity.") 38 | 39 | guard let fillComponents = testShapeElement.svgLayer.fillColor?.components else { 40 | XCTFail("Fill opacity should set the fill color") 41 | return 42 | } 43 | XCTAssert(fillComponents[3] == 0.5, "Expected 0.5, got \(fillComponents[3])") 44 | } 45 | 46 | func testFillOpacityOrder() { 47 | let testShapeElement = TestShapeElement() 48 | testShapeElement.fillOpacity(opacity: "0.5") 49 | testShapeElement.fill(fillColor: "#00FF00") 50 | 51 | guard let fillComponents = testShapeElement.svgLayer.fillColor?.components else { 52 | XCTFail("Fill should return color components") 53 | return 54 | } 55 | XCTAssert(fillComponents[3] == 0.5, "Fill color should preserve any existing fill opacity. Expected 0.5, got \(fillComponents[3])") 56 | } 57 | 58 | func testFillOpacityColorComponents() { 59 | let testShapeElement = TestShapeElement() 60 | testShapeElement.fill(fillColor: "#33FF66") 61 | testShapeElement.fillOpacity(opacity: "0.5") 62 | guard let fillComponents = testShapeElement.svgLayer.fillColor?.components else { 63 | XCTFail("Fill opacity should set the fill color") 64 | return 65 | } 66 | XCTAssert(testShapeElement.svgLayer.fillColor?.components![0] == 0.2, "Expected 0.0, got \(fillComponents[0])") 67 | XCTAssert(testShapeElement.svgLayer.fillColor?.components![1] == 1.0, "Expected 0.0, got \(testShapeElement.svgLayer.fillColor!.components![1])") 68 | XCTAssert(testShapeElement.svgLayer.fillColor?.components![2] == 0.4, "Expected 0.0, got \(testShapeElement.svgLayer.fillColor!.components![2])") 69 | XCTAssert(testShapeElement.svgLayer.fillColor?.components![3] == 0.5, "Expected 0.0, got \(testShapeElement.svgLayer.fillColor!.components![3])") 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /SwiftSVGTests/FloatingPointDegreesToRadiansTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FloatingPointDegreesToRadiansTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class FloatingPointDegreesToRadiansTests: XCTestCase { 34 | 35 | func testToRadians() { 36 | let degrees: Double = 180.0 37 | XCTAssert(degrees.toRadians == Double.pi, "Expected pi, got \(degrees.toRadians)") 38 | } 39 | 40 | func testToDegrees() { 41 | let radians: Double = Double.pi 42 | XCTAssert(radians.toDegrees == 180, "Expected 180, got \(radians.toDegrees)") 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /SwiftSVGTests/FloatingPointParseLengthStringTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FloatingPointParseLengthStringTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class FloatingPointParseLengthTests: XCTestCase { 34 | 35 | func testStraightInteger() { 36 | let testNumber = Double(lengthString: "78") 37 | XCTAssertTrue(testNumber == 78, "Expected 78, got \(testNumber!)") 38 | } 39 | 40 | func testPixelAnnotation() { 41 | let testNumber = Double(lengthString: "890px") 42 | XCTAssertTrue(testNumber == 890, "Expected 890, got \(testNumber!)") 43 | } 44 | 45 | func testUnsupportedSuffix() { 46 | let testNumber = Float(lengthString: "123em") 47 | XCTAssertNil(testNumber, "Expected nil, got \(testNumber!)") 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /SwiftSVGTests/HorizontalLineToTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HorizontalLineToTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class HorizontalLineToTests: XCTestCase { 34 | 35 | func testAbsoluteHorizontalLineTo() { 36 | let testPath = UIBezierPath() 37 | _ = MoveTo(parameters: [10, -20], pathType: .absolute, path: testPath) 38 | _ = HorizontalLineTo(parameters: [-128], pathType: .absolute, path: testPath) 39 | let points = testPath.cgPath.points 40 | XCTAssert(points[1].x == -128 && points[1].y == -20, "Expected {-128, -20}, got \(points[1])") 41 | } 42 | 43 | func testRelativeHorizontalLineTo() { 44 | let testPath = UIBezierPath() 45 | _ = MoveTo(parameters: [10, -20], pathType: .absolute, path: testPath) 46 | _ = HorizontalLineTo(parameters: [-128], pathType: .relative, path: testPath) 47 | let points = testPath.cgPath.points 48 | XCTAssert(points[1].x == -118 && points[1].y == -20, "Expected {-118, -20}, got \(points[1])") 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /SwiftSVGTests/IndentifiableTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IndentifiableTests.swift 3 | // SwiftSVGTests 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | import XCTest 29 | 30 | class IndentifiableTests: XCTestCase { 31 | 32 | func testShapeElementSetsLayerName() { 33 | let testShapeElement = TestShapeElement() 34 | testShapeElement.identify(identifier: "id-to-check") 35 | XCTAssert(testShapeElement.svgLayer.name == "id-to-check", "Expected \"id-to-check\", got: \(String(describing: testShapeElement.svgLayer.name))") 36 | } 37 | 38 | func testEndToEnd() { 39 | 40 | guard let resourceURL = Bundle(for: type(of: self)).url(forResource: "simple-rectangle", withExtension: "svg") else { 41 | XCTAssert(false, "Couldn't find resource") 42 | return 43 | } 44 | 45 | let asData = try! Data(contentsOf: resourceURL) 46 | let expectation = self.expectation(description: "Identifiable expectation") 47 | _ = UIView(svgData: asData) { (svgLayer) in 48 | guard let rootLayerName = svgLayer.sublayers?[0].name else { 49 | return 50 | } 51 | guard rootLayerName == "root-rectangle-id" else { 52 | return 53 | } 54 | 55 | guard let innerID = svgLayer.sublayers?[0].sublayers?[0].name else { 56 | return 57 | } 58 | guard innerID == "inner-rectangle-id" else { 59 | return 60 | } 61 | expectation.fulfill() 62 | } 63 | 64 | self.waitForExpectations(timeout: 3, handler: nil) 65 | 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /SwiftSVGTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SwiftSVGTests/LineToTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LineToTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class LineToTests: XCTestCase { 34 | 35 | func testAbsoluteLineTo() { 36 | let testPath = UIBezierPath() 37 | _ = MoveTo(parameters: [10, -20], pathType: .absolute, path: testPath) 38 | _ = LineTo(parameters: [66, 37], pathType: .absolute, path: testPath) 39 | let points = testPath.cgPath.points 40 | XCTAssert(points[0].x == 10 && points[0].y == -20, "Expected 10, -20, got \(points[0])") 41 | XCTAssert(points[1].x == 66 && points[1].y == 37, "Expected 66, 37, got \(points[1])") 42 | } 43 | 44 | func testRelativeLineTo() { 45 | let testPath = UIBezierPath() 46 | _ = MoveTo(parameters: [10, -20], pathType: .absolute, path: testPath) 47 | _ = LineTo(parameters: [66, 37], pathType: .relative, path: testPath) 48 | let points = testPath.cgPath.points 49 | XCTAssert(points[0].x == 10 && points[0].y == -20, "Expected 10, -20, got \(points[0])") 50 | XCTAssert(points[1].x == 76 && points[1].y == 17, "Expected 76, 17, got \(points[1])") 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /SwiftSVGTests/PerformanceTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PerformanceTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class PerformanceTests: XCTestCase { 34 | 35 | func testSwiftSVG() { 36 | 37 | self.measureMetrics([XCTPerformanceMetric.wallClockTime], automaticallyStartMeasuring: true) { 38 | 39 | guard let resourceURL = Bundle(for: type(of: self)).url(forResource: "ukulele", withExtension: "svg") else { 40 | XCTAssert(false, "Couldn't find resource") 41 | return 42 | } 43 | 44 | let asData = try! Data(contentsOf: resourceURL) 45 | let expect = self.expectation(description: "SwiftSVG expectation") 46 | _ = UIView(svgData: asData) { (svgLayer) in 47 | SVGCache.default.removeObject(key: asData.cacheKey) 48 | expect.fulfill() 49 | } 50 | 51 | self.waitForExpectations(timeout: 10) { error in 52 | self.stopMeasuring() 53 | } 54 | } 55 | 56 | 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /SwiftSVGTests/SVGCircleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGCircleTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class SVGCircleTests: XCTestCase { 34 | 35 | func testElementName() { 36 | XCTAssert(SVGCircle.elementName == "circle", "Expected \"circle\", got \(SVGCircle.elementName)") 37 | } 38 | 39 | func testSettingValues () { 40 | let testCircle = SVGCircle() 41 | testCircle.xCenter(x: "40.3") 42 | testCircle.yCenter(y: "108.254") 43 | 44 | XCTAssert(testCircle.circleCenter == CGPoint(x: 40.3, y: 108.254), "Expected {40.3, 108.254}, got \(testCircle.circleCenter)") 45 | 46 | testCircle.radius(r: "435.10") 47 | XCTAssert(testCircle.circleRadius == 435.1, "Expected 435.1, got \(testCircle.circleRadius)") 48 | 49 | testCircle.radius(r: "1e3") 50 | XCTAssert(testCircle.circleRadius == 1000, "Expected 1000, got \(testCircle.circleRadius)") 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /SwiftSVGTests/SVGEllipseTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGEllipseTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class SVGEllipseTests: XCTestCase { 34 | 35 | func testElementName() { 36 | XCTAssert(SVGEllipse.elementName == "ellipse", "Expected \"ellipse\", got \(SVGEllipse.elementName)") 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /SwiftSVGTests/SVGGroupTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGGroupTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class SVGGroupTests: XCTestCase { 34 | 35 | func testElementName() { 36 | XCTAssert(SVGGroup.elementName == "g", "Expected \"g\", got \(SVGGroup.elementName)") 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /SwiftSVGTests/SVGLineTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGLineTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class SVGLineTests: XCTestCase { 34 | 35 | func testElementName() { 36 | XCTAssert(SVGLine.elementName == "line", "Expected \"line\", got \(SVGLine.elementName)") 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /SwiftSVGTests/SVGPathTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGPathTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class SVGPathTests: XCTestCase { 34 | 35 | func testElementName() { 36 | XCTAssert(SVGPath.elementName == "path", "Expected \"path\", got \(SVGPath.elementName)") 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /SwiftSVGTests/SVGPolygonTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGPolygonTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class SVGPolygonTests: XCTestCase { 34 | 35 | func testElementName() { 36 | XCTAssert(SVGPolygon.elementName == "polygon", "Expected \"polygon\", got \(SVGPolygon.elementName)") 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /SwiftSVGTests/SVGPolylineTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGPolylineTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class SVGPolylineTests: XCTestCase { 34 | 35 | func testElementName() { 36 | XCTAssert(SVGPolyline.elementName == "polyline", "Expected \"polyline\", got \(SVGPolyline.elementName)") 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /SwiftSVGTests/SVGRectangleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGRectangleTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class SVGRectangleTests: XCTestCase { 34 | 35 | func testElementName() { 36 | XCTAssert(SVGRectangle.elementName == "rect", "Expected \"rect\", got \(SVGRectangle.elementName)") 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /SwiftSVGTests/SVGRootElementTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SVGRootElementTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class SVGRootElementTests: XCTestCase { 34 | 35 | func testWidthParse() { 36 | let testElement = SVGRootElement() 37 | testElement.parseWidth(lengthString: "103px") 38 | XCTAssertTrue(testElement.containerLayer.frame.size.width == 103, "Expected width to be 103, got \(testElement.containerLayer.frame.size.width)") 39 | } 40 | 41 | func testHeightParse() { 42 | let testElement = SVGRootElement() 43 | testElement.parseHeight(lengthString: "271px") 44 | XCTAssertTrue(testElement.containerLayer.frame.size.height == 271, "Expected width to be 271, got \(testElement.containerLayer.frame.size.height)") 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /SwiftSVGTests/ScalarFromByteArrayTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScalarFromByteArrayTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class ScalarFromByteArrayTests: XCTestCase { 34 | 35 | func testByteArray() { 36 | var testArray: [CChar] = [49, 48] 37 | var asDouble = Double(byteArray: testArray)! 38 | XCTAssert(asDouble == 10, "Expected 10, got \(asDouble)") 39 | 40 | testArray = [45, 57, 49, 53] 41 | asDouble = Double(byteArray: testArray)! 42 | XCTAssert(asDouble == -915, "Expected -915, got \(asDouble)") 43 | 44 | testArray = [45, 54, 46, 51, 56] 45 | asDouble = Double(byteArray: testArray)! 46 | XCTAssert(asDouble == -6.38, "Expected -6.38, got \(asDouble)") 47 | } 48 | 49 | func testInvalidByteArray() { 50 | var testArray: [CChar] = [65, 48] // "A0" 51 | var asDouble = Double(byteArray: testArray) 52 | XCTAssertNil(asDouble, "Expected nil, got \(String(describing: asDouble))") 53 | 54 | testArray = [] 55 | asDouble = Double(byteArray: testArray) 56 | XCTAssertNil(asDouble, "Expected nil, got \(String(describing: asDouble))") 57 | } 58 | 59 | func testENumber() { 60 | let testArray: [CChar] = [49, 101, 51] // "1e3 61 | let asDouble = Double(byteArray: testArray) 62 | XCTAssert(asDouble == 1000, "Double: \(asDouble!)") 63 | } 64 | 65 | func testZeroCountArray() { 66 | let testArray = [CChar]() 67 | let asDouble = Double(byteArray: testArray) 68 | XCTAssertNil(asDouble, "Expected nil, got \(String(describing: asDouble))") 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /SwiftSVGTests/SmoothCurveToTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SmoothCurveToTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class SmoothCurveToTests: XCTestCase { 34 | 35 | func testAbsoluteSmoothCurveTo() { 36 | let testPath = UIBezierPath() 37 | _ = MoveTo(parameters: [10, -20], pathType: .absolute, path: testPath) 38 | let curveTo = CurveTo(parameters: [78, -50, 37, 32, -18, 23], pathType: .absolute, path: testPath) 39 | _ = SmoothCurveTo(parameters: [66, 37, 39, -101, -78, 65], pathType: .absolute, path: testPath, previousCommand: curveTo) 40 | let pointsAndTypes = testPath.cgPath.pointsAndTypes 41 | XCTAssert(pointsAndTypes.last!.1 == .addCurveToPoint, "Expected .addCurveToPoint, got \(pointsAndTypes.last!.1)") 42 | 43 | XCTAssert(pointsAndTypes[4].1 == .addCurveToPoint, "Expected .addCurveToPoint, got \(pointsAndTypes[4].1)") 44 | //XCTAssert(pointsAndTypes[4].0.x == 66 && pointsAndTypes[4].0.y == 37, "Expected {66, 37}, got \(pointsAndTypes[4])") 45 | //XCTAssert(pointsAndTypes[6].0.x == 39 && pointsAndTypes[6].0.y == -101, "Expected {39, -101}, got \(pointsAndTypes[6])") 46 | //XCTAssert(pointsAndTypes[7].0.x == -78 && pointsAndTypes[7].0.y == 65, "Expected {-78, 65}, got \(pointsAndTypes[7])") 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /SwiftSVGTests/StackTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StackTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class StackTests: XCTestCase { 34 | 35 | 36 | 37 | func testCount() { 38 | var testStack = Stack() 39 | testStack.push(1) 40 | testStack.push(10) 41 | XCTAssert(testStack.count == 2, "Expected 2, got \(testStack.count)") 42 | } 43 | 44 | func testLast() { 45 | var testStack = Stack() 46 | testStack.push(1.5) 47 | testStack.push(8.2) 48 | testStack.push(40.4) 49 | XCTAssert(testStack.last == 40.4, "Expected 40.4, got \(testStack.last!)") 50 | } 51 | 52 | func testClear() { 53 | var testStack = Stack() 54 | testStack.push("Hello") 55 | testStack.push("There") 56 | testStack.clear() 57 | XCTAssert(testStack.count == 0, "Expected 0, got \(testStack.count)") 58 | } 59 | 60 | func testIsEmpty() { 61 | let testStack = Stack() 62 | XCTAssert(testStack.isEmpty == true, "Expected empty stack, got \(testStack.items)") 63 | } 64 | 65 | func testPush() { 66 | var testStack = Stack() 67 | testStack.push("hello") 68 | XCTAssert(testStack.last == "hello", "Expected \"hello\", got \(testStack.last!)") 69 | } 70 | 71 | func testPop() { 72 | var testStack = Stack() 73 | testStack.push(Character("a")) 74 | testStack.push(Character("b")) 75 | testStack.push(Character("c")) 76 | testStack.push(Character("d")) 77 | let poppedItem = testStack.pop() 78 | XCTAssert(poppedItem == "d", "Expected d, got \(poppedItem!)") 79 | XCTAssert(testStack.count == 3, "Expected count of 3, got \(testStack.count)") 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /SwiftSVGTests/StringSubscriptTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StringSubscriptTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class StringSubscriptTests: XCTestCase { 34 | 35 | func testIntegerRange() { 36 | 37 | let testString = "1234567890" 38 | 39 | XCTAssertTrue(testString[0..<3] == "123", "Expected \"123\", got \(testString[0..<2])") 40 | XCTAssertTrue(testString[3..<7] == "4567", "Expected \"4567\", got \(testString[3..<7])") 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /SwiftSVGTests/TestShapeElement.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TestShapeElement.swift 3 | // SwiftSVGTests 4 | // 5 | // Copyright (c) 2017 Michael Choe 6 | // http://www.github.com/mchoe 7 | // http://www.straussmade.com/ 8 | // http://www.twitter.com/_mchoe 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | import UIKit 29 | 30 | struct TestShapeElement: SVGShapeElement { 31 | static let elementName: String = "test" 32 | var supportedAttributes: [String : (String) -> ()] = [:] 33 | var svgLayer = CAShapeLayer() 34 | 35 | init() { 36 | let rectPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 200, height: 200)) 37 | self.svgLayer.path = rectPath.cgPath 38 | } 39 | 40 | func notReal(string: String) { 41 | return 42 | } 43 | 44 | func didProcessElement(in container: SVGContainerElement?) { 45 | return 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SwiftSVGTests/VerticalLineToTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VerticalLineToTests.swift 3 | // SwiftSVG 4 | // 5 | // 6 | // Copyright (c) 2017 Michael Choe 7 | // http://www.github.com/mchoe 8 | // http://www.straussmade.com/ 9 | // http://www.twitter.com/_mchoe 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | 31 | import XCTest 32 | 33 | class VerticalLineToTests: XCTestCase { 34 | 35 | func testAbsoluteVerticalLineTo() { 36 | let testPath = UIBezierPath() 37 | _ = MoveTo(parameters: [10, -20], pathType: .absolute, path: testPath) 38 | _ = VerticalLineTo(parameters: [-128], pathType: .absolute, path: testPath) 39 | let points = testPath.cgPath.points 40 | XCTAssert(points[1].x == 10 && points[1].y == -128, "Expected {10, -128}, got \(points[1])") 41 | } 42 | 43 | func testRelativeVerticalLineTo() { 44 | let testPath = UIBezierPath() 45 | _ = MoveTo(parameters: [10, -20], pathType: .absolute, path: testPath) 46 | _ = VerticalLineTo(parameters: [-128], pathType: .relative, path: testPath) 47 | let points = testPath.cgPath.points 48 | XCTAssert(points[1].x == 10 && points[1].y == -148, "Expected {10, -148}, got \(points[1])") 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | swiftsvg.com -------------------------------------------------------------------------------- /docs/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | documentation 17 | 18 | 19 | documentation 20 | 21 | 22 | 80% 23 | 24 | 25 | 80% 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | com.jazzy.swiftsvg 7 | CFBundleName 8 | SwiftSVG 9 | DocSetPlatformFamily 10 | swiftsvg 11 | isDashDocset 12 | 13 | dashIndexFilePath 14 | index.html 15 | isJavaScriptEnabled 16 | 17 | DashDocSetFamily 18 | dashtoc 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/CNAME: -------------------------------------------------------------------------------- 1 | swiftsvg.com -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | documentation 17 | 18 | 19 | documentation 20 | 21 | 22 | 79% 23 | 24 | 25 | 79% 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/images/SwiftSVG-Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/images/SwiftSVG-Logo.png -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/images/fistBump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/images/fistBump.png -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/images/pizza.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/images/pizza.png -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/images/sockPuppet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/images/sockPuppet.png -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/images/svgViewScreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/images/svgViewScreenshot.png -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/images/triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/images/triangle.png -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/img/carat.png -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/img/dash.png -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/img/gh.png -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/img/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/img/spinner.gif -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | function toggleItem($link, $content) { 12 | var animationDuration = 300; 13 | $link.toggleClass('token-open'); 14 | $content.slideToggle(animationDuration); 15 | } 16 | 17 | function itemLinkToContent($link) { 18 | return $link.parent().parent().next(); 19 | } 20 | 21 | // On doc load + hash-change, open any targetted item 22 | function openCurrentItemIfClosed() { 23 | if (window.jazzy.docset) { 24 | return; 25 | } 26 | var $link = $(`.token[href="${location.hash}"]`); 27 | $content = itemLinkToContent($link); 28 | if ($content.is(':hidden')) { 29 | toggleItem($link, $content); 30 | } 31 | } 32 | 33 | $(openCurrentItemIfClosed); 34 | $(window).on('hashchange', openCurrentItemIfClosed); 35 | 36 | // On item link ('token') click, toggle its discussion 37 | $('.token').on('click', function(event) { 38 | if (window.jazzy.docset) { 39 | return; 40 | } 41 | var $link = $(this); 42 | toggleItem($link, itemLinkToContent($link)); 43 | 44 | // Keeps the document from jumping to the hash. 45 | var href = $link.attr('href'); 46 | if (history.pushState) { 47 | history.pushState({}, '', href); 48 | } else { 49 | location.hash = href; 50 | } 51 | event.preventDefault(); 52 | }); 53 | 54 | // Clicks on links to the current, closed, item need to open the item 55 | $("a:not('.token')").on('click', function() { 56 | if (location == this.href) { 57 | openCurrentItemIfClosed(); 58 | } 59 | }); 60 | -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/Documents/js/jazzy.search.js: -------------------------------------------------------------------------------- 1 | $(function(){ 2 | var $typeahead = $('[data-typeahead]'); 3 | var $form = $typeahead.parents('form'); 4 | var searchURL = $form.attr('action'); 5 | 6 | function displayTemplate(result) { 7 | return result.name; 8 | } 9 | 10 | function suggestionTemplate(result) { 11 | var t = '
'; 12 | t += '' + result.name + ''; 13 | if (result.parent_name) { 14 | t += '' + result.parent_name + ''; 15 | } 16 | t += '
'; 17 | return t; 18 | } 19 | 20 | $typeahead.one('focus', function() { 21 | $form.addClass('loading'); 22 | 23 | $.getJSON(searchURL).then(function(searchData) { 24 | const searchIndex = lunr(function() { 25 | this.ref('url'); 26 | this.field('name'); 27 | this.field('abstract'); 28 | for (const [url, doc] of Object.entries(searchData)) { 29 | this.add({url: url, name: doc.name, abstract: doc.abstract}); 30 | } 31 | }); 32 | 33 | $typeahead.typeahead( 34 | { 35 | highlight: true, 36 | minLength: 3, 37 | autoselect: true 38 | }, 39 | { 40 | limit: 10, 41 | display: displayTemplate, 42 | templates: { suggestion: suggestionTemplate }, 43 | source: function(query, sync) { 44 | const lcSearch = query.toLowerCase(); 45 | const results = searchIndex.query(function(q) { 46 | q.term(lcSearch, { boost: 100 }); 47 | q.term(lcSearch, { 48 | boost: 10, 49 | wildcard: lunr.Query.wildcard.TRAILING 50 | }); 51 | }).map(function(result) { 52 | var doc = searchData[result.ref]; 53 | doc.url = result.ref; 54 | return doc; 55 | }); 56 | sync(results); 57 | } 58 | } 59 | ); 60 | $form.removeClass('loading'); 61 | $typeahead.trigger('focus'); 62 | }); 63 | }); 64 | 65 | var baseURL = searchURL.slice(0, -"search.json".length); 66 | 67 | $typeahead.on('typeahead:select', function(e, result) { 68 | window.location = baseURL + result.url; 69 | }); 70 | }); 71 | -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.docset/Contents/Resources/docSet.dsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/docsets/SwiftSVG.docset/Contents/Resources/docSet.dsidx -------------------------------------------------------------------------------- /docs/docsets/SwiftSVG.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/docsets/SwiftSVG.tgz -------------------------------------------------------------------------------- /docs/images/SwiftSVG-Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/images/SwiftSVG-Logo.png -------------------------------------------------------------------------------- /docs/images/fistBump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/images/fistBump.png -------------------------------------------------------------------------------- /docs/images/pizza.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/images/pizza.png -------------------------------------------------------------------------------- /docs/images/sockPuppet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/images/sockPuppet.png -------------------------------------------------------------------------------- /docs/images/svgViewScreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/images/svgViewScreenshot.png -------------------------------------------------------------------------------- /docs/images/triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/images/triangle.png -------------------------------------------------------------------------------- /docs/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/img/carat.png -------------------------------------------------------------------------------- /docs/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/img/dash.png -------------------------------------------------------------------------------- /docs/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/img/gh.png -------------------------------------------------------------------------------- /docs/img/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/docs/img/spinner.gif -------------------------------------------------------------------------------- /docs/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | function toggleItem($link, $content) { 12 | var animationDuration = 300; 13 | $link.toggleClass('token-open'); 14 | $content.slideToggle(animationDuration); 15 | } 16 | 17 | function itemLinkToContent($link) { 18 | return $link.parent().parent().next(); 19 | } 20 | 21 | // On doc load + hash-change, open any targetted item 22 | function openCurrentItemIfClosed() { 23 | if (window.jazzy.docset) { 24 | return; 25 | } 26 | var $link = $(`.token[href="${location.hash}"]`); 27 | $content = itemLinkToContent($link); 28 | if ($content.is(':hidden')) { 29 | toggleItem($link, $content); 30 | } 31 | } 32 | 33 | $(openCurrentItemIfClosed); 34 | $(window).on('hashchange', openCurrentItemIfClosed); 35 | 36 | // On item link ('token') click, toggle its discussion 37 | $('.token').on('click', function(event) { 38 | if (window.jazzy.docset) { 39 | return; 40 | } 41 | var $link = $(this); 42 | toggleItem($link, itemLinkToContent($link)); 43 | 44 | // Keeps the document from jumping to the hash. 45 | var href = $link.attr('href'); 46 | if (history.pushState) { 47 | history.pushState({}, '', href); 48 | } else { 49 | location.hash = href; 50 | } 51 | event.preventDefault(); 52 | }); 53 | 54 | // Clicks on links to the current, closed, item need to open the item 55 | $("a:not('.token')").on('click', function() { 56 | if (location == this.href) { 57 | openCurrentItemIfClosed(); 58 | } 59 | }); 60 | -------------------------------------------------------------------------------- /docs/js/jazzy.search.js: -------------------------------------------------------------------------------- 1 | $(function(){ 2 | var $typeahead = $('[data-typeahead]'); 3 | var $form = $typeahead.parents('form'); 4 | var searchURL = $form.attr('action'); 5 | 6 | function displayTemplate(result) { 7 | return result.name; 8 | } 9 | 10 | function suggestionTemplate(result) { 11 | var t = '
'; 12 | t += '' + result.name + ''; 13 | if (result.parent_name) { 14 | t += '' + result.parent_name + ''; 15 | } 16 | t += '
'; 17 | return t; 18 | } 19 | 20 | $typeahead.one('focus', function() { 21 | $form.addClass('loading'); 22 | 23 | $.getJSON(searchURL).then(function(searchData) { 24 | const searchIndex = lunr(function() { 25 | this.ref('url'); 26 | this.field('name'); 27 | this.field('abstract'); 28 | for (const [url, doc] of Object.entries(searchData)) { 29 | this.add({url: url, name: doc.name, abstract: doc.abstract}); 30 | } 31 | }); 32 | 33 | $typeahead.typeahead( 34 | { 35 | highlight: true, 36 | minLength: 3, 37 | autoselect: true 38 | }, 39 | { 40 | limit: 10, 41 | display: displayTemplate, 42 | templates: { suggestion: suggestionTemplate }, 43 | source: function(query, sync) { 44 | const lcSearch = query.toLowerCase(); 45 | const results = searchIndex.query(function(q) { 46 | q.term(lcSearch, { boost: 100 }); 47 | q.term(lcSearch, { 48 | boost: 10, 49 | wildcard: lunr.Query.wildcard.TRAILING 50 | }); 51 | }).map(function(result) { 52 | var doc = searchData[result.ref]; 53 | doc.url = result.ref; 54 | return doc; 55 | }); 56 | sync(results); 57 | } 58 | } 59 | ); 60 | $form.removeClass('loading'); 61 | $typeahead.trigger('focus'); 62 | }); 63 | }); 64 | 65 | var baseURL = searchURL.slice(0, -"search.json".length); 66 | 67 | $typeahead.on('typeahead:select', function(e, result) { 68 | window.location = baseURL + result.url; 69 | }); 70 | }); 71 | -------------------------------------------------------------------------------- /images/SwiftSVG-Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/images/SwiftSVG-Logo.png -------------------------------------------------------------------------------- /images/assetCatalog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/images/assetCatalog.png -------------------------------------------------------------------------------- /images/cowboyHat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/images/cowboyHat.png -------------------------------------------------------------------------------- /images/fistBump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/images/fistBump.png -------------------------------------------------------------------------------- /images/hammock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/images/hammock.png -------------------------------------------------------------------------------- /images/pizza.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/images/pizza.png -------------------------------------------------------------------------------- /images/sockPuppet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/images/sockPuppet.png -------------------------------------------------------------------------------- /images/svgViewScreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/images/svgViewScreenshot.png -------------------------------------------------------------------------------- /images/tea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/images/tea.png -------------------------------------------------------------------------------- /images/triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mchoe/SwiftSVG/88b9ee086b29019e35f6f49c8e30e5552eb8fa9d/images/triangle.png --------------------------------------------------------------------------------