1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-09-21 09:59:10 +03:00

Merge pull request #363 from f3dm76/task/effects

Fix #123: Parse SVG filters to Macaw effects
This commit is contained in:
Yuri Strot 2018-05-16 19:34:10 +07:00 committed by GitHub
commit db66beeae8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 308 additions and 171 deletions

View File

@ -17,7 +17,6 @@
57614AFD1F83D15600875933 /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1381E3B393900D1CB28 /* Group.swift */; };
57614AFE1F83D15600875933 /* TextRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1441E3B393900D1CB28 /* TextRenderer.swift */; };
57614AFF1F83D15600875933 /* CGFloat+Double.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E14D1E3B393900D1CB28 /* CGFloat+Double.swift */; };
57614B011F83D15600875933 /* GaussianBlur.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E11B1E3B393900D1CB28 /* GaussianBlur.swift */; };
57614B021F83D15600875933 /* RoundRect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1341E3B393900D1CB28 /* RoundRect.swift */; };
57614B031F83D15600875933 /* UIImage2Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57900FF81EA0DEBF00809FFB /* UIImage2Image.swift */; };
57614B041F83D15600875933 /* SVGParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1471E3B393900D1CB28 /* SVGParser.swift */; };
@ -34,12 +33,9 @@
57614B0F1F83D15600875933 /* Transform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1361E3B393900D1CB28 /* Transform.swift */; };
57614B101F83D15600875933 /* Graphics_macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A718CD4A1F45C28F00966E06 /* Graphics_macOS.swift */; };
57614B111F83D15600875933 /* ShapeRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1431E3B393900D1CB28 /* ShapeRenderer.swift */; };
57614B121F83D15600875933 /* LinearGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E11D1E3B393900D1CB28 /* LinearGradient.swift */; };
57614B131F83D15600875933 /* MDisplayLink_macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A718CD4B1F45C28F00966E06 /* MDisplayLink_macOS.swift */; };
57614B141F83D15600875933 /* GroupDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1071E3B393900D1CB28 /* GroupDisposable.swift */; };
57614B151F83D15600875933 /* Stroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1221E3B393900D1CB28 /* Stroke.swift */; };
57614B161F83D15600875933 /* TapEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E10E1E3B393900D1CB28 /* TapEvent.swift */; };
57614B171F83D15600875933 /* LineCap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E11E1E3B393900D1CB28 /* LineCap.swift */; };
57614B181F83D15600875933 /* SVGView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E14A1E3B393900D1CB28 /* SVGView.swift */; };
57614B191F83D15600875933 /* Arc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1241E3B393900D1CB28 /* Arc.swift */; };
57614B1A1F83D15600875933 /* MacawView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1501E3B393900D1CB28 /* MacawView.swift */; };
@ -48,7 +44,6 @@
57614B1D1F83D15600875933 /* AnimationImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E0E41E3B393900D1CB28 /* AnimationImpl.swift */; };
57614B1E1F83D15600875933 /* AnimOperators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E0EB1E3B393900D1CB28 /* AnimOperators.swift */; };
57614B1F1F83D15600875933 /* Circle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1251E3B393900D1CB28 /* Circle.swift */; };
57614B201F83D15600875933 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1151E3B393900D1CB28 /* Color.swift */; };
57614B211F83D15600875933 /* PathSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E12E1E3B393900D1CB28 /* PathSegment.swift */; };
57614B221F83D15600875933 /* ImageRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E13F1E3B393900D1CB28 /* ImageRenderer.swift */; };
57614B231F83D15600875933 /* PathFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E0F31E3B393900D1CB28 /* PathFunctions.swift */; };
@ -59,28 +54,20 @@
57614B281F83D15600875933 /* ShapeAnimationGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57A27BD21E44C5570057BD3A /* ShapeAnimationGenerator.swift */; };
57614B291F83D15600875933 /* AnimationUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E0E61E3B393900D1CB28 /* AnimationUtils.swift */; };
57614B2A1F83D15600875933 /* Polygon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1311E3B393900D1CB28 /* Polygon.swift */; };
57614B2B1F83D15600875933 /* Baseline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1141E3B393900D1CB28 /* Baseline.swift */; };
57614B2C1F83D15600875933 /* AspectRatio.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1131E3B393900D1CB28 /* AspectRatio.swift */; };
57614B2D1F83D15600875933 /* TransformAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1041E3B393900D1CB28 /* TransformAnimation.swift */; };
57614B2E1F83D15600875933 /* CombineAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1001E3B393900D1CB28 /* CombineAnimation.swift */; };
57614B2F1F83D15600875933 /* TransformHashable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E0FA1E3B393900D1CB28 /* TransformHashable.swift */; };
57614B301F83D15600875933 /* MoveTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E12B1E3B393900D1CB28 /* MoveTo.swift */; };
57614B311F83D15600875933 /* NodeRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1401E3B393900D1CB28 /* NodeRenderer.swift */; };
57614B321F83D15600875933 /* Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E11A1E3B393900D1CB28 /* Font.swift */; };
57614B331F83D15600875933 /* Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E0E31E3B393900D1CB28 /* Animation.swift */; };
57614B341F83D15600875933 /* SVGParserError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1481E3B393900D1CB28 /* SVGParserError.swift */; };
57614B351F83D15600875933 /* Drawable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1161E3B393900D1CB28 /* Drawable.swift */; };
57614B361F83D15600875933 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1061E3B393900D1CB28 /* Disposable.swift */; };
57614B371F83D15600875933 /* Path.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E12C1E3B393900D1CB28 /* Path.swift */; };
57614B381F83D15600875933 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1291E3B393900D1CB28 /* Line.swift */; };
57614B391F83D15600875933 /* PathBounds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E0F21E3B393900D1CB28 /* PathBounds.swift */; };
57614B3A1F83D15600875933 /* AnimationProducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E0E51E3B393900D1CB28 /* AnimationProducer.swift */; };
57614B3B1F83D15600875933 /* Fill.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1191E3B393900D1CB28 /* Fill.swift */; };
57614B3C1F83D15600875933 /* ShapeInterpolation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57A27BD41E44C5840057BD3A /* ShapeInterpolation.swift */; };
57614B3D1F83D15600875933 /* Graphics_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A718CD451F45C28700966E06 /* Graphics_iOS.swift */; };
57614B3E1F83D15600875933 /* LineJoin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E11F1E3B393900D1CB28 /* LineJoin.swift */; };
57614B3F1F83D15600875933 /* RadialGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1201E3B393900D1CB28 /* RadialGradient.swift */; };
57614B401F83D15600875933 /* Stop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1211E3B393900D1CB28 /* Stop.swift */; };
57614B411F83D15600875933 /* Text.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E13C1E3B393900D1CB28 /* Text.swift */; };
57614B421F83D15600875933 /* MDisplayLink_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57F1087B1F53CA7E00DC365B /* MDisplayLink_iOS.swift */; };
57614B431F83D15600875933 /* RenderContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1411E3B393900D1CB28 /* RenderContext.swift */; };
@ -100,14 +87,11 @@
57614B511F83D15600875933 /* NodeHashable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E0F91E3B393900D1CB28 /* NodeHashable.swift */; };
57614B521F83D15600875933 /* GeomUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1271E3B393900D1CB28 /* GeomUtils.swift */; };
57614B531F83D15600875933 /* CAAnimationClosure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E14C1E3B393900D1CB28 /* CAAnimationClosure.swift */; };
57614B541F83D15600875933 /* DropShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1171E3B393900D1CB28 /* DropShadow.swift */; };
57614B551F83D15600875933 /* Common_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A718CD431F45C28200966E06 /* Common_iOS.swift */; };
57614B561F83D15600875933 /* Common_macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = A718CD491F45C28F00966E06 /* Common_macOS.swift */; };
57614B571F83D15600875933 /* MDisplayLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57F108791F53C92000DC365B /* MDisplayLink.swift */; };
57614B591F83D15600875933 /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E10A1E3B393900D1CB28 /* Event.swift */; };
57614B5A1F83D15600875933 /* Gradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E11C1E3B393900D1CB28 /* Gradient.swift */; };
57614B5B1F83D15600875933 /* Interpolable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E0EE1E3B393900D1CB28 /* Interpolable.swift */; };
57614B5C1F83D15600875933 /* Align.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1121E3B393900D1CB28 /* Align.swift */; };
57614B5D1F83D15600875933 /* Variable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1081E3B393900D1CB28 /* Variable.swift */; };
57614B5E1F83D15600875933 /* OpacityAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1031E3B393900D1CB28 /* OpacityAnimation.swift */; };
57614B5F1F83D15600875933 /* Touchable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57F108731F502A3600DC365B /* Touchable.swift */; };
@ -121,7 +105,6 @@
57614B671F83D15600875933 /* ContentsInterpolation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57A27BCE1E44C4EC0057BD3A /* ContentsInterpolation.swift */; };
57614B681F83D15600875933 /* GroupRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E13E1E3B393900D1CB28 /* GroupRenderer.swift */; };
57614B691F83D15600875933 /* SVGParserRegexHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1491E3B393900D1CB28 /* SVGParserRegexHelper.swift */; };
57614B6A1F83D15600875933 /* Effect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1181E3B393900D1CB28 /* Effect.swift */; };
57614B6B1F83D15600875933 /* NSTimer+Closure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E14E1E3B393900D1CB28 /* NSTimer+Closure.swift */; };
57614B6C1F83D15600875933 /* SWXMLHash+TypeConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 572CEFC51E2CED4B008C7C83 /* SWXMLHash+TypeConversion.swift */; };
57614B6D1F83D15600875933 /* AnimationSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E0FF1E3B393900D1CB28 /* AnimationSequence.swift */; };
@ -187,23 +170,6 @@
57E5E1761E3B393900D1CB28 /* PinchEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E10C1E3B393900D1CB28 /* PinchEvent.swift */; };
57E5E1771E3B393900D1CB28 /* RotateEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E10D1E3B393900D1CB28 /* RotateEvent.swift */; };
57E5E1781E3B393900D1CB28 /* TapEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E10E1E3B393900D1CB28 /* TapEvent.swift */; };
57E5E17A1E3B393900D1CB28 /* Align.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1121E3B393900D1CB28 /* Align.swift */; };
57E5E17B1E3B393900D1CB28 /* AspectRatio.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1131E3B393900D1CB28 /* AspectRatio.swift */; };
57E5E17C1E3B393900D1CB28 /* Baseline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1141E3B393900D1CB28 /* Baseline.swift */; };
57E5E17D1E3B393900D1CB28 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1151E3B393900D1CB28 /* Color.swift */; };
57E5E17E1E3B393900D1CB28 /* Drawable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1161E3B393900D1CB28 /* Drawable.swift */; };
57E5E17F1E3B393900D1CB28 /* DropShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1171E3B393900D1CB28 /* DropShadow.swift */; };
57E5E1801E3B393900D1CB28 /* Effect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1181E3B393900D1CB28 /* Effect.swift */; };
57E5E1811E3B393900D1CB28 /* Fill.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1191E3B393900D1CB28 /* Fill.swift */; };
57E5E1821E3B393900D1CB28 /* Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E11A1E3B393900D1CB28 /* Font.swift */; };
57E5E1831E3B393900D1CB28 /* GaussianBlur.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E11B1E3B393900D1CB28 /* GaussianBlur.swift */; };
57E5E1841E3B393900D1CB28 /* Gradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E11C1E3B393900D1CB28 /* Gradient.swift */; };
57E5E1851E3B393900D1CB28 /* LinearGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E11D1E3B393900D1CB28 /* LinearGradient.swift */; };
57E5E1861E3B393900D1CB28 /* LineCap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E11E1E3B393900D1CB28 /* LineCap.swift */; };
57E5E1871E3B393900D1CB28 /* LineJoin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E11F1E3B393900D1CB28 /* LineJoin.swift */; };
57E5E1881E3B393900D1CB28 /* RadialGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1201E3B393900D1CB28 /* RadialGradient.swift */; };
57E5E1891E3B393900D1CB28 /* Stop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1211E3B393900D1CB28 /* Stop.swift */; };
57E5E18A1E3B393900D1CB28 /* Stroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1221E3B393900D1CB28 /* Stroke.swift */; };
57E5E18B1E3B393900D1CB28 /* Arc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1241E3B393900D1CB28 /* Arc.swift */; };
57E5E18C1E3B393900D1CB28 /* Circle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1251E3B393900D1CB28 /* Circle.swift */; };
57E5E18D1E3B393900D1CB28 /* Ellipse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E5E1261E3B393900D1CB28 /* Ellipse.swift */; };
@ -426,6 +392,42 @@
5B6E188220AAF64E00454E7E /* coords-transformattr-05-f-manual.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5B6E17D820AAF64D00454E7E /* coords-transformattr-05-f-manual.reference */; };
5B6E188320AAF64E00454E7E /* painting-control-03-f-manual.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5B6E17D920AAF64D00454E7E /* painting-control-03-f-manual.svg */; };
5B6E188420AAF64E00454E7E /* coords-trans-07-t-manual.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5B6E17DA20AAF64D00454E7E /* coords-trans-07-t-manual.reference */; };
5B6E192120AC58F900454E7E /* AlphaEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E190F20AC58F700454E7E /* AlphaEffect.swift */; };
5B6E192220AC58F900454E7E /* AlphaEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E190F20AC58F700454E7E /* AlphaEffect.swift */; };
5B6E192320AC58F900454E7E /* OffsetEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191020AC58F700454E7E /* OffsetEffect.swift */; };
5B6E192420AC58F900454E7E /* OffsetEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191020AC58F700454E7E /* OffsetEffect.swift */; };
5B6E192520AC58F900454E7E /* GaussianBlur.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191120AC58F700454E7E /* GaussianBlur.swift */; };
5B6E192620AC58F900454E7E /* GaussianBlur.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191120AC58F700454E7E /* GaussianBlur.swift */; };
5B6E192720AC58F900454E7E /* RadialGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191220AC58F700454E7E /* RadialGradient.swift */; };
5B6E192820AC58F900454E7E /* RadialGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191220AC58F700454E7E /* RadialGradient.swift */; };
5B6E192920AC58F900454E7E /* Align.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191320AC58F700454E7E /* Align.swift */; };
5B6E192A20AC58F900454E7E /* Align.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191320AC58F700454E7E /* Align.swift */; };
5B6E192B20AC58F900454E7E /* AspectRatio.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191420AC58F700454E7E /* AspectRatio.swift */; };
5B6E192C20AC58F900454E7E /* AspectRatio.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191420AC58F700454E7E /* AspectRatio.swift */; };
5B6E192D20AC58F900454E7E /* Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191520AC58F700454E7E /* Font.swift */; };
5B6E192E20AC58F900454E7E /* Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191520AC58F700454E7E /* Font.swift */; };
5B6E192F20AC58F900454E7E /* LinearGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191620AC58F800454E7E /* LinearGradient.swift */; };
5B6E193020AC58F900454E7E /* LinearGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191620AC58F800454E7E /* LinearGradient.swift */; };
5B6E193120AC58F900454E7E /* LineJoin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191720AC58F800454E7E /* LineJoin.swift */; };
5B6E193220AC58F900454E7E /* LineJoin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191720AC58F800454E7E /* LineJoin.swift */; };
5B6E193320AC58F900454E7E /* Baseline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191820AC58F800454E7E /* Baseline.swift */; };
5B6E193420AC58F900454E7E /* Baseline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191820AC58F800454E7E /* Baseline.swift */; };
5B6E193520AC58F900454E7E /* Stop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191920AC58F800454E7E /* Stop.swift */; };
5B6E193620AC58F900454E7E /* Stop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191920AC58F800454E7E /* Stop.swift */; };
5B6E193720AC58F900454E7E /* LineCap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191A20AC58F800454E7E /* LineCap.swift */; };
5B6E193820AC58F900454E7E /* LineCap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191A20AC58F800454E7E /* LineCap.swift */; };
5B6E193920AC58F900454E7E /* Drawable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191B20AC58F800454E7E /* Drawable.swift */; };
5B6E193A20AC58F900454E7E /* Drawable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191B20AC58F800454E7E /* Drawable.swift */; };
5B6E193B20AC58F900454E7E /* Effect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191C20AC58F800454E7E /* Effect.swift */; };
5B6E193C20AC58F900454E7E /* Effect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191C20AC58F800454E7E /* Effect.swift */; };
5B6E193D20AC58F900454E7E /* Fill.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191D20AC58F900454E7E /* Fill.swift */; };
5B6E193E20AC58F900454E7E /* Fill.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191D20AC58F900454E7E /* Fill.swift */; };
5B6E193F20AC58F900454E7E /* Stroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191E20AC58F900454E7E /* Stroke.swift */; };
5B6E194020AC58F900454E7E /* Stroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191E20AC58F900454E7E /* Stroke.swift */; };
5B6E194120AC58F900454E7E /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191F20AC58F900454E7E /* Color.swift */; };
5B6E194220AC58F900454E7E /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E191F20AC58F900454E7E /* Color.swift */; };
5B6E194320AC58F900454E7E /* Gradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E192020AC58F900454E7E /* Gradient.swift */; };
5B6E194420AC58F900454E7E /* Gradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6E192020AC58F900454E7E /* Gradient.swift */; };
5BAA56A8207C73FF0055BC5B /* SVGContentLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BAA56A7207C73FF0055BC5B /* SVGContentLayout.swift */; };
5BAE201F208E1211006BF277 /* SVGCanvas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BAE201E208E1211006BF277 /* SVGCanvas.swift */; };
5BAE2038208E163D006BF277 /* polyline.reference in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE2022208E1637006BF277 /* polyline.reference */; };
@ -569,23 +571,6 @@
57E5E10D1E3B393900D1CB28 /* RotateEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RotateEvent.swift; sourceTree = "<group>"; };
57E5E10E1E3B393900D1CB28 /* TapEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TapEvent.swift; sourceTree = "<group>"; };
57E5E10F1E3B393900D1CB28 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
57E5E1121E3B393900D1CB28 /* Align.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Align.swift; sourceTree = "<group>"; };
57E5E1131E3B393900D1CB28 /* AspectRatio.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AspectRatio.swift; sourceTree = "<group>"; };
57E5E1141E3B393900D1CB28 /* Baseline.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Baseline.swift; sourceTree = "<group>"; };
57E5E1151E3B393900D1CB28 /* Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
57E5E1161E3B393900D1CB28 /* Drawable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Drawable.swift; sourceTree = "<group>"; };
57E5E1171E3B393900D1CB28 /* DropShadow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropShadow.swift; sourceTree = "<group>"; };
57E5E1181E3B393900D1CB28 /* Effect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Effect.swift; sourceTree = "<group>"; };
57E5E1191E3B393900D1CB28 /* Fill.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fill.swift; sourceTree = "<group>"; };
57E5E11A1E3B393900D1CB28 /* Font.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Font.swift; sourceTree = "<group>"; };
57E5E11B1E3B393900D1CB28 /* GaussianBlur.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GaussianBlur.swift; sourceTree = "<group>"; };
57E5E11C1E3B393900D1CB28 /* Gradient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Gradient.swift; sourceTree = "<group>"; };
57E5E11D1E3B393900D1CB28 /* LinearGradient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinearGradient.swift; sourceTree = "<group>"; };
57E5E11E1E3B393900D1CB28 /* LineCap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineCap.swift; sourceTree = "<group>"; };
57E5E11F1E3B393900D1CB28 /* LineJoin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineJoin.swift; sourceTree = "<group>"; };
57E5E1201E3B393900D1CB28 /* RadialGradient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadialGradient.swift; sourceTree = "<group>"; };
57E5E1211E3B393900D1CB28 /* Stop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Stop.swift; sourceTree = "<group>"; };
57E5E1221E3B393900D1CB28 /* Stroke.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Stroke.swift; sourceTree = "<group>"; };
57E5E1241E3B393900D1CB28 /* Arc.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Arc.swift; sourceTree = "<group>"; };
57E5E1251E3B393900D1CB28 /* Circle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Circle.swift; sourceTree = "<group>"; };
57E5E1261E3B393900D1CB28 /* Ellipse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Ellipse.swift; sourceTree = "<group>"; };
@ -807,6 +792,24 @@
5B6E17D820AAF64D00454E7E /* coords-transformattr-05-f-manual.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "coords-transformattr-05-f-manual.reference"; sourceTree = "<group>"; };
5B6E17D920AAF64D00454E7E /* painting-control-03-f-manual.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "painting-control-03-f-manual.svg"; sourceTree = "<group>"; };
5B6E17DA20AAF64D00454E7E /* coords-trans-07-t-manual.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "coords-trans-07-t-manual.reference"; sourceTree = "<group>"; };
5B6E190F20AC58F700454E7E /* AlphaEffect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlphaEffect.swift; sourceTree = "<group>"; };
5B6E191020AC58F700454E7E /* OffsetEffect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OffsetEffect.swift; sourceTree = "<group>"; };
5B6E191120AC58F700454E7E /* GaussianBlur.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GaussianBlur.swift; sourceTree = "<group>"; };
5B6E191220AC58F700454E7E /* RadialGradient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadialGradient.swift; sourceTree = "<group>"; };
5B6E191320AC58F700454E7E /* Align.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Align.swift; sourceTree = "<group>"; };
5B6E191420AC58F700454E7E /* AspectRatio.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AspectRatio.swift; sourceTree = "<group>"; };
5B6E191520AC58F700454E7E /* Font.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Font.swift; sourceTree = "<group>"; };
5B6E191620AC58F800454E7E /* LinearGradient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinearGradient.swift; sourceTree = "<group>"; };
5B6E191720AC58F800454E7E /* LineJoin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineJoin.swift; sourceTree = "<group>"; };
5B6E191820AC58F800454E7E /* Baseline.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Baseline.swift; sourceTree = "<group>"; };
5B6E191920AC58F800454E7E /* Stop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Stop.swift; sourceTree = "<group>"; };
5B6E191A20AC58F800454E7E /* LineCap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineCap.swift; sourceTree = "<group>"; };
5B6E191B20AC58F800454E7E /* Drawable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Drawable.swift; sourceTree = "<group>"; };
5B6E191C20AC58F800454E7E /* Effect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Effect.swift; sourceTree = "<group>"; };
5B6E191D20AC58F900454E7E /* Fill.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fill.swift; sourceTree = "<group>"; };
5B6E191E20AC58F900454E7E /* Stroke.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Stroke.swift; sourceTree = "<group>"; };
5B6E191F20AC58F900454E7E /* Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
5B6E192020AC58F900454E7E /* Gradient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Gradient.swift; sourceTree = "<group>"; };
5BAA56A7207C73FF0055BC5B /* SVGContentLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SVGContentLayout.swift; sourceTree = "<group>"; };
5BAE201E208E1211006BF277 /* SVGCanvas.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SVGCanvas.swift; sourceTree = "<group>"; };
5BAE2022208E1637006BF277 /* polyline.reference */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = polyline.reference; sourceTree = "<group>"; };
@ -1093,23 +1096,24 @@
57E5E1111E3B393900D1CB28 /* draw */ = {
isa = PBXGroup;
children = (
57E5E1121E3B393900D1CB28 /* Align.swift */,
57E5E1131E3B393900D1CB28 /* AspectRatio.swift */,
57E5E1141E3B393900D1CB28 /* Baseline.swift */,
57E5E1151E3B393900D1CB28 /* Color.swift */,
57E5E1161E3B393900D1CB28 /* Drawable.swift */,
57E5E1171E3B393900D1CB28 /* DropShadow.swift */,
57E5E1181E3B393900D1CB28 /* Effect.swift */,
57E5E1191E3B393900D1CB28 /* Fill.swift */,
57E5E11A1E3B393900D1CB28 /* Font.swift */,
57E5E11B1E3B393900D1CB28 /* GaussianBlur.swift */,
57E5E11C1E3B393900D1CB28 /* Gradient.swift */,
57E5E11D1E3B393900D1CB28 /* LinearGradient.swift */,
57E5E11E1E3B393900D1CB28 /* LineCap.swift */,
57E5E11F1E3B393900D1CB28 /* LineJoin.swift */,
57E5E1201E3B393900D1CB28 /* RadialGradient.swift */,
57E5E1211E3B393900D1CB28 /* Stop.swift */,
57E5E1221E3B393900D1CB28 /* Stroke.swift */,
5B6E191320AC58F700454E7E /* Align.swift */,
5B6E190F20AC58F700454E7E /* AlphaEffect.swift */,
5B6E191420AC58F700454E7E /* AspectRatio.swift */,
5B6E191820AC58F800454E7E /* Baseline.swift */,
5B6E191F20AC58F900454E7E /* Color.swift */,
5B6E191B20AC58F800454E7E /* Drawable.swift */,
5B6E191C20AC58F800454E7E /* Effect.swift */,
5B6E191D20AC58F900454E7E /* Fill.swift */,
5B6E191520AC58F700454E7E /* Font.swift */,
5B6E191120AC58F700454E7E /* GaussianBlur.swift */,
5B6E192020AC58F900454E7E /* Gradient.swift */,
5B6E191620AC58F800454E7E /* LinearGradient.swift */,
5B6E191A20AC58F800454E7E /* LineCap.swift */,
5B6E191720AC58F800454E7E /* LineJoin.swift */,
5B6E191020AC58F700454E7E /* OffsetEffect.swift */,
5B6E191220AC58F700454E7E /* RadialGradient.swift */,
5B6E191920AC58F800454E7E /* Stop.swift */,
5B6E191E20AC58F900454E7E /* Stroke.swift */,
);
path = draw;
sourceTree = "<group>";
@ -1871,9 +1875,9 @@
57D9DAE11FC9AA4C0002555D /* Locus+ToPath.swift in Sources */,
57614AFE1F83D15600875933 /* TextRenderer.swift in Sources */,
57614AFF1F83D15600875933 /* CGFloat+Double.swift in Sources */,
57614B011F83D15600875933 /* GaussianBlur.swift in Sources */,
57614B021F83D15600875933 /* RoundRect.swift in Sources */,
57614B031F83D15600875933 /* UIImage2Image.swift in Sources */,
5B6E194020AC58F900454E7E /* Stroke.swift in Sources */,
57614B041F83D15600875933 /* SVGParser.swift in Sources */,
57614B051F83D15600875933 /* SWXMLHash.swift in Sources */,
57614B061F83D15600875933 /* NodesMap.swift in Sources */,
@ -1883,72 +1887,71 @@
57614B0A1F83D15600875933 /* DoubleInterpolation.swift in Sources */,
57614B0B1F83D15600875933 /* PathSegmentType.swift in Sources */,
57614B0C1F83D15600875933 /* AnimatableVariable.swift in Sources */,
5B6E193C20AC58F900454E7E /* Effect.swift in Sources */,
57614B0D1F83D15600875933 /* TimingFunction.swift in Sources */,
57614B0E1F83D15600875933 /* AnimationCache.swift in Sources */,
57614B0F1F83D15600875933 /* Transform.swift in Sources */,
57614B101F83D15600875933 /* Graphics_macOS.swift in Sources */,
5B6E192220AC58F900454E7E /* AlphaEffect.swift in Sources */,
57614B111F83D15600875933 /* ShapeRenderer.swift in Sources */,
57614B121F83D15600875933 /* LinearGradient.swift in Sources */,
57614B131F83D15600875933 /* MDisplayLink_macOS.swift in Sources */,
57614B141F83D15600875933 /* GroupDisposable.swift in Sources */,
57614B151F83D15600875933 /* Stroke.swift in Sources */,
57614B161F83D15600875933 /* TapEvent.swift in Sources */,
57614B171F83D15600875933 /* LineCap.swift in Sources */,
57614B181F83D15600875933 /* SVGView.swift in Sources */,
57614B191F83D15600875933 /* Arc.swift in Sources */,
57614B1A1F83D15600875933 /* MacawView.swift in Sources */,
5B6E193420AC58F900454E7E /* Baseline.swift in Sources */,
57614B1B1F83D15600875933 /* Image.swift in Sources */,
57614B1C1F83D15600875933 /* TransformGenerator.swift in Sources */,
57614B1D1F83D15600875933 /* AnimationImpl.swift in Sources */,
57614B1E1F83D15600875933 /* AnimOperators.swift in Sources */,
57614B1F1F83D15600875933 /* Circle.swift in Sources */,
57614B201F83D15600875933 /* Color.swift in Sources */,
5BAE204C208E1EF4006BF277 /* SVGCanvas.swift in Sources */,
57614B211F83D15600875933 /* PathSegment.swift in Sources */,
5B6E193E20AC58F900454E7E /* Fill.swift in Sources */,
57614B221F83D15600875933 /* ImageRenderer.swift in Sources */,
57614B231F83D15600875933 /* PathFunctions.swift in Sources */,
57614B241F83D15600875933 /* SVGSerializer.swift in Sources */,
57614B251F83D15600875933 /* MorphingAnimation.swift in Sources */,
5B6E192420AC58F900454E7E /* OffsetEffect.swift in Sources */,
5B6E193020AC58F900454E7E /* LinearGradient.swift in Sources */,
57614B261F83D15600875933 /* ShapeAnimation.swift in Sources */,
57614B271F83D15600875933 /* TransformInterpolation.swift in Sources */,
57614B281F83D15600875933 /* ShapeAnimationGenerator.swift in Sources */,
57614B291F83D15600875933 /* AnimationUtils.swift in Sources */,
57614B2A1F83D15600875933 /* Polygon.swift in Sources */,
57614B2B1F83D15600875933 /* Baseline.swift in Sources */,
57614B2C1F83D15600875933 /* AspectRatio.swift in Sources */,
57614B2D1F83D15600875933 /* TransformAnimation.swift in Sources */,
57614B2E1F83D15600875933 /* CombineAnimation.swift in Sources */,
57614B2F1F83D15600875933 /* TransformHashable.swift in Sources */,
57614B301F83D15600875933 /* MoveTo.swift in Sources */,
5B6E193A20AC58F900454E7E /* Drawable.swift in Sources */,
57614B311F83D15600875933 /* NodeRenderer.swift in Sources */,
57614B321F83D15600875933 /* Font.swift in Sources */,
57614B331F83D15600875933 /* Animation.swift in Sources */,
57614B341F83D15600875933 /* SVGParserError.swift in Sources */,
57614B351F83D15600875933 /* Drawable.swift in Sources */,
57614B361F83D15600875933 /* Disposable.swift in Sources */,
5B6E192C20AC58F900454E7E /* AspectRatio.swift in Sources */,
57614B371F83D15600875933 /* Path.swift in Sources */,
57614B381F83D15600875933 /* Line.swift in Sources */,
57614B391F83D15600875933 /* PathBounds.swift in Sources */,
57614B3A1F83D15600875933 /* AnimationProducer.swift in Sources */,
57614B3B1F83D15600875933 /* Fill.swift in Sources */,
57614B3C1F83D15600875933 /* ShapeInterpolation.swift in Sources */,
57614B3D1F83D15600875933 /* Graphics_iOS.swift in Sources */,
57614B3E1F83D15600875933 /* LineJoin.swift in Sources */,
57614B3F1F83D15600875933 /* RadialGradient.swift in Sources */,
57614BDB1F8739EE00875933 /* MacawView+PDF.swift in Sources */,
57614B401F83D15600875933 /* Stop.swift in Sources */,
57614B411F83D15600875933 /* Text.swift in Sources */,
57614B421F83D15600875933 /* MDisplayLink_iOS.swift in Sources */,
57614B431F83D15600875933 /* RenderContext.swift in Sources */,
57614B441F83D15600875933 /* Size.swift in Sources */,
5B6E193220AC58F900454E7E /* LineJoin.swift in Sources */,
5835969C20A9CA150090400C /* CGMappings.swift in Sources */,
57614B451F83D15600875933 /* Polyline.swift in Sources */,
57614B461F83D15600875933 /* ContentsAnimation.swift in Sources */,
57614B471F83D15600875933 /* TouchEvent.swift in Sources */,
57614B481F83D15600875933 /* MBezierPath+Extension_macOS.swift in Sources */,
57614B491F83D15600875933 /* MView_macOS.swift in Sources */,
5B6E192E20AC58F900454E7E /* Font.swift in Sources */,
57614B4A1F83D15600875933 /* Easing.swift in Sources */,
57614B4B1F83D15600875933 /* Point.swift in Sources */,
5B6E192620AC58F900454E7E /* GaussianBlur.swift in Sources */,
57614B4C1F83D15600875933 /* OpacityGenerator.swift in Sources */,
57614B4D1F83D15600875933 /* Shape.swift in Sources */,
57614B4E1F83D15600875933 /* Ellipse.swift in Sources */,
@ -1956,16 +1959,16 @@
57614B501F83D15600875933 /* SceneUtils.swift in Sources */,
57614B511F83D15600875933 /* NodeHashable.swift in Sources */,
57614B521F83D15600875933 /* GeomUtils.swift in Sources */,
5B6E194420AC58F900454E7E /* Gradient.swift in Sources */,
57614B531F83D15600875933 /* CAAnimationClosure.swift in Sources */,
57614B541F83D15600875933 /* DropShadow.swift in Sources */,
5B6E194220AC58F900454E7E /* Color.swift in Sources */,
57614B551F83D15600875933 /* Common_iOS.swift in Sources */,
57614B561F83D15600875933 /* Common_macOS.swift in Sources */,
57614B571F83D15600875933 /* MDisplayLink.swift in Sources */,
57614B591F83D15600875933 /* Event.swift in Sources */,
57614B5A1F83D15600875933 /* Gradient.swift in Sources */,
57614B5B1F83D15600875933 /* Interpolable.swift in Sources */,
57614B5C1F83D15600875933 /* Align.swift in Sources */,
57614B5D1F83D15600875933 /* Variable.swift in Sources */,
5B6E193820AC58F900454E7E /* LineCap.swift in Sources */,
57614B5E1F83D15600875933 /* OpacityAnimation.swift in Sources */,
57614B5F1F83D15600875933 /* Touchable.swift in Sources */,
57614B601F83D15600875933 /* Node.swift in Sources */,
@ -1977,9 +1980,11 @@
57614B661F83D15600875933 /* PinchEvent.swift in Sources */,
57614B671F83D15600875933 /* ContentsInterpolation.swift in Sources */,
57614B681F83D15600875933 /* GroupRenderer.swift in Sources */,
5B6E192820AC58F900454E7E /* RadialGradient.swift in Sources */,
57614B691F83D15600875933 /* SVGParserRegexHelper.swift in Sources */,
57614B6A1F83D15600875933 /* Effect.swift in Sources */,
5B6E192A20AC58F900454E7E /* Align.swift in Sources */,
57614B6B1F83D15600875933 /* NSTimer+Closure.swift in Sources */,
5B6E193620AC58F900454E7E /* Stop.swift in Sources */,
57614B6C1F83D15600875933 /* SWXMLHash+TypeConversion.swift in Sources */,
57614B6D1F83D15600875933 /* AnimationSequence.swift in Sources */,
5B1A8C7720A15F7300E5FFAE /* SVGNodeLayout.swift in Sources */,
@ -1998,10 +2003,10 @@
C43B06511F9866E400787A35 /* Locus+ToPath.swift in Sources */,
57E5E1A91E3B393900D1CB28 /* TextRenderer.swift in Sources */,
57E5E1B01E3B393900D1CB28 /* CGFloat+Double.swift in Sources */,
57E5E1831E3B393900D1CB28 /* GaussianBlur.swift in Sources */,
57E5E19B1E3B393900D1CB28 /* RoundRect.swift in Sources */,
57900FF91EA0DEBF00809FFB /* UIImage2Image.swift in Sources */,
57E5E1AB1E3B393900D1CB28 /* SVGParser.swift in Sources */,
5B6E193F20AC58F900454E7E /* Stroke.swift in Sources */,
572CEFC81E2CED4B008C7C83 /* SWXMLHash.swift in Sources */,
57E5E1B31E3B393900D1CB28 /* NodesMap.swift in Sources */,
57E5E1A71E3B393900D1CB28 /* RenderUtils.swift in Sources */,
@ -2011,72 +2016,71 @@
57E5E1961E3B393900D1CB28 /* PathSegmentType.swift in Sources */,
57E5E1531E3B393900D1CB28 /* AnimatableVariable.swift in Sources */,
57E5E1691E3B393900D1CB28 /* TimingFunction.swift in Sources */,
5B6E193B20AC58F900454E7E /* Effect.swift in Sources */,
57E5E1631E3B393900D1CB28 /* AnimationCache.swift in Sources */,
57E5E19D1E3B393900D1CB28 /* Transform.swift in Sources */,
A718CD4E1F45C28F00966E06 /* Graphics_macOS.swift in Sources */,
57E5E1A81E3B393900D1CB28 /* ShapeRenderer.swift in Sources */,
57E5E1851E3B393900D1CB28 /* LinearGradient.swift in Sources */,
5B6E192120AC58F900454E7E /* AlphaEffect.swift in Sources */,
A718CD4F1F45C28F00966E06 /* MDisplayLink_macOS.swift in Sources */,
57E5E1721E3B393900D1CB28 /* GroupDisposable.swift in Sources */,
57E5E18A1E3B393900D1CB28 /* Stroke.swift in Sources */,
57E5E1781E3B393900D1CB28 /* TapEvent.swift in Sources */,
57E5E1861E3B393900D1CB28 /* LineCap.swift in Sources */,
57E5E1AE1E3B393900D1CB28 /* SVGView.swift in Sources */,
57E5E18B1E3B393900D1CB28 /* Arc.swift in Sources */,
57E5E1B21E3B393900D1CB28 /* MacawView.swift in Sources */,
57E5E19F1E3B393900D1CB28 /* Image.swift in Sources */,
5B6E193320AC58F900454E7E /* Baseline.swift in Sources */,
57E5E16A1E3B393900D1CB28 /* TransformGenerator.swift in Sources */,
57E5E1551E3B393900D1CB28 /* AnimationImpl.swift in Sources */,
57E5E15A1E3B393900D1CB28 /* AnimOperators.swift in Sources */,
57E5E18C1E3B393900D1CB28 /* Circle.swift in Sources */,
57E5E17D1E3B393900D1CB28 /* Color.swift in Sources */,
57E5E1951E3B393900D1CB28 /* PathSegment.swift in Sources */,
5BAE201F208E1211006BF277 /* SVGCanvas.swift in Sources */,
57E5E1A41E3B393900D1CB28 /* ImageRenderer.swift in Sources */,
5B6E193D20AC58F900454E7E /* Fill.swift in Sources */,
57E5E1621E3B393900D1CB28 /* PathFunctions.swift in Sources */,
C4820B181F458D0E008CE0FF /* SVGSerializer.swift in Sources */,
57E5E16E1E3B393900D1CB28 /* MorphingAnimation.swift in Sources */,
57A27BD11E44C5460057BD3A /* ShapeAnimation.swift in Sources */,
5B6E192320AC58F900454E7E /* OffsetEffect.swift in Sources */,
5B6E192F20AC58F900454E7E /* LinearGradient.swift in Sources */,
57E5E15F1E3B393900D1CB28 /* TransformInterpolation.swift in Sources */,
57A27BD31E44C5570057BD3A /* ShapeAnimationGenerator.swift in Sources */,
57E5E1571E3B393900D1CB28 /* AnimationUtils.swift in Sources */,
57E5E1981E3B393900D1CB28 /* Polygon.swift in Sources */,
57E5E17C1E3B393900D1CB28 /* Baseline.swift in Sources */,
57E5E17B1E3B393900D1CB28 /* AspectRatio.swift in Sources */,
57E5E1701E3B393900D1CB28 /* TransformAnimation.swift in Sources */,
57E5E16C1E3B393900D1CB28 /* CombineAnimation.swift in Sources */,
57E5E1661E3B393900D1CB28 /* TransformHashable.swift in Sources */,
57E5E1921E3B393900D1CB28 /* MoveTo.swift in Sources */,
57E5E1A51E3B393900D1CB28 /* NodeRenderer.swift in Sources */,
57E5E1821E3B393900D1CB28 /* Font.swift in Sources */,
5B6E193920AC58F900454E7E /* Drawable.swift in Sources */,
57E5E1541E3B393900D1CB28 /* Animation.swift in Sources */,
57E5E1AC1E3B393900D1CB28 /* SVGParserError.swift in Sources */,
57E5E17E1E3B393900D1CB28 /* Drawable.swift in Sources */,
57E5E1711E3B393900D1CB28 /* Disposable.swift in Sources */,
57E5E1931E3B393900D1CB28 /* Path.swift in Sources */,
5B6E192B20AC58F900454E7E /* AspectRatio.swift in Sources */,
57E5E1901E3B393900D1CB28 /* Line.swift in Sources */,
57E5E1611E3B393900D1CB28 /* PathBounds.swift in Sources */,
57E5E1561E3B393900D1CB28 /* AnimationProducer.swift in Sources */,
57E5E1811E3B393900D1CB28 /* Fill.swift in Sources */,
57A27BD51E44C5840057BD3A /* ShapeInterpolation.swift in Sources */,
A718CD471F45C28700966E06 /* Graphics_iOS.swift in Sources */,
57E5E1871E3B393900D1CB28 /* LineJoin.swift in Sources */,
57E5E1881E3B393900D1CB28 /* RadialGradient.swift in Sources */,
57614BDA1F8739EE00875933 /* MacawView+PDF.swift in Sources */,
57E5E1891E3B393900D1CB28 /* Stop.swift in Sources */,
57E5E1A21E3B393900D1CB28 /* Text.swift in Sources */,
57F1087C1F53CA7E00DC365B /* MDisplayLink_iOS.swift in Sources */,
57E5E1A61E3B393900D1CB28 /* RenderContext.swift in Sources */,
57E5E19C1E3B393900D1CB28 /* Size.swift in Sources */,
57E5E1991E3B393900D1CB28 /* Polyline.swift in Sources */,
5B6E193120AC58F900454E7E /* LineJoin.swift in Sources */,
5835969B20A9CA150090400C /* CGMappings.swift in Sources */,
57E5E16D1E3B393900D1CB28 /* ContentsAnimation.swift in Sources */,
5713C4E21E51EC8F00BBA4D9 /* TouchEvent.swift in Sources */,
A718CD521F45C2A400966E06 /* MBezierPath+Extension_macOS.swift in Sources */,
A718CD501F45C28F00966E06 /* MView_macOS.swift in Sources */,
57E5E1581E3B393900D1CB28 /* Easing.swift in Sources */,
5B6E192D20AC58F900454E7E /* Font.swift in Sources */,
57E5E1971E3B393900D1CB28 /* Point.swift in Sources */,
57E5E1681E3B393900D1CB28 /* OpacityGenerator.swift in Sources */,
5B6E192520AC58F900454E7E /* GaussianBlur.swift in Sources */,
57E5E1A11E3B393900D1CB28 /* Shape.swift in Sources */,
57E5E18D1E3B393900D1CB28 /* Ellipse.swift in Sources */,
57E5E1911E3B393900D1CB28 /* Locus.swift in Sources */,
@ -2084,16 +2088,16 @@
57E5E1651E3B393900D1CB28 /* NodeHashable.swift in Sources */,
57E5E18E1E3B393900D1CB28 /* GeomUtils.swift in Sources */,
57E5E1AF1E3B393900D1CB28 /* CAAnimationClosure.swift in Sources */,
57E5E17F1E3B393900D1CB28 /* DropShadow.swift in Sources */,
5B6E194320AC58F900454E7E /* Gradient.swift in Sources */,
A718CD441F45C28200966E06 /* Common_iOS.swift in Sources */,
5B6E194120AC58F900454E7E /* Color.swift in Sources */,
A718CD4D1F45C28F00966E06 /* Common_macOS.swift in Sources */,
57F1087A1F53C92000DC365B /* MDisplayLink.swift in Sources */,
57E5E1741E3B393900D1CB28 /* Event.swift in Sources */,
57E5E1841E3B393900D1CB28 /* Gradient.swift in Sources */,
57E5E15D1E3B393900D1CB28 /* Interpolable.swift in Sources */,
57E5E17A1E3B393900D1CB28 /* Align.swift in Sources */,
57E5E1731E3B393900D1CB28 /* Variable.swift in Sources */,
57E5E16F1E3B393900D1CB28 /* OpacityAnimation.swift in Sources */,
5B6E193720AC58F900454E7E /* LineCap.swift in Sources */,
57F108741F502A3600DC365B /* Touchable.swift in Sources */,
57E5E1A01E3B393900D1CB28 /* Node.swift in Sources */,
57E5E1751E3B393900D1CB28 /* PanEvent.swift in Sources */,
@ -2105,9 +2109,11 @@
57E5E1761E3B393900D1CB28 /* PinchEvent.swift in Sources */,
57A27BCF1E44C4EC0057BD3A /* ContentsInterpolation.swift in Sources */,
57E5E1A31E3B393900D1CB28 /* GroupRenderer.swift in Sources */,
5B6E192720AC58F900454E7E /* RadialGradient.swift in Sources */,
57E5E1AD1E3B393900D1CB28 /* SVGParserRegexHelper.swift in Sources */,
57E5E1801E3B393900D1CB28 /* Effect.swift in Sources */,
5B6E192920AC58F900454E7E /* Align.swift in Sources */,
57E5E1B11E3B393900D1CB28 /* NSTimer+Closure.swift in Sources */,
5B6E193520AC58F900454E7E /* Stop.swift in Sources */,
572CEFC71E2CED4B008C7C83 /* SWXMLHash+TypeConversion.swift in Sources */,
57E5E16B1E3B393900D1CB28 /* AnimationSequence.swift in Sources */,
5B1A8C7620A15F7300E5FFAE /* SVGNodeLayout.swift in Sources */,

View File

@ -0,0 +1,2 @@
open class AlphaEffect: Effect {
}

View File

@ -1,16 +0,0 @@
import Foundation
open class DropShadow: Effect {
open let radius: Double
open let offset: Point
open let color: Color
open let input: Effect?
public init(radius: Double = 0, offset: Point = Point.origin, color: Color = Color.black, input: Effect? = nil) {
self.radius = radius
self.offset = offset
self.color = color
self.input = input
}
}

View File

@ -1,8 +1,9 @@
import Foundation
open class Effect {
open let input: Effect?
public init() {
public init(input: Effect?) {
self.input = input
}
}

View File

@ -3,10 +3,9 @@ import Foundation
open class GaussianBlur: Effect {
open let radius: Double
open let input: Effect?
public init(radius: Double = 0, input: Effect? = nil) {
public init(radius: Double = 0, input: Effect?) {
self.radius = radius
self.input = input
super.init(input: input)
}
}

View File

@ -0,0 +1,11 @@
open class OffsetEffect: Effect {
open let dx: Double
open let dy: Double
public init(dx: Double = 0, dy: Double = 0, input: Effect?) {
self.dx = dx
self.dy = dy
super.init(input: input)
}
}

View File

@ -31,20 +31,102 @@ class ShapeRenderer: NodeRenderer {
observe(shape.strokeVar)
}
fileprivate func drawShape(in context: CGContext, opacity: Double) {
guard let shape = shape else { return }
setGeometry(shape.form, ctx: context)
var fillRule = FillRule.nonzero
if let path = shape.form as? Path {
fillRule = path.fillRule
}
drawPath(shape.fill, stroke: shape.stroke, ctx: context, opacity: opacity, fillRule: fillRule)
}
override func doRender(_ force: Bool, opacity: Double) {
guard let shape = shape else {
guard let shape = shape, let context = ctx.cgContext else { return }
if shape.fill == nil && shape.stroke == nil { return }
// no effects, just draw as usual
guard let effect = shape.effect else {
drawShape(in: context, opacity: opacity)
return
}
if shape.fill != nil || shape.stroke != nil {
setGeometry(shape.form, ctx: ctx.cgContext!)
var fillRule = FillRule.nonzero
if let path = shape.form as? Path {
fillRule = path.fillRule
}
drawPath(shape.fill, stroke: shape.stroke, ctx: ctx.cgContext!, opacity: opacity, fillRule: fillRule)
var effects = [Effect]()
var next: Effect? = effect
while next != nil {
effects.append(next!)
next = next?.input
}
let offset = effects.filter { $0 is OffsetEffect }.first
let otherEffects = effects.filter { !($0 is OffsetEffect) }
if let offset = offset as? OffsetEffect {
let move = Transform(m11: 1, m12: 0, m21: 0, m22: 1, dx: offset.dx, dy: offset.dy)
context.concatenate(move.toCG())
if otherEffects.count == 0 {
// draw offset shape
drawShape(in: context, opacity: opacity)
} else {
// apply other effects to offset shape
applyEffects(otherEffects, opacity: opacity)
}
// move back and draw the shape itself
context.concatenate(move.invert()!.toCG())
drawShape(in: context, opacity: opacity)
} else {
// draw the shape
drawShape(in: context, opacity: opacity)
// apply other effects to shape
applyEffects(otherEffects, opacity: opacity)
}
}
fileprivate func applyEffects(_ effects: [Effect], opacity: Double) {
guard let shape = shape, let context = ctx.cgContext else { return }
for effect in effects {
if let blur = effect as? GaussianBlur {
let shadowInset = min(blur.radius * 6 + 1, 150)
guard let shapeImage = saveToImage(shape: shape, shadowInset: shadowInset, opacity: opacity)?.cgImage else { return }
guard let filteredImage = applyBlur(shapeImage, blur: blur) else { return }
guard let bounds = shape.bounds() else { return }
context.draw(filteredImage, in: CGRect(x: bounds.x - shadowInset / 2, y: bounds.y - shadowInset / 2, width: bounds.w + shadowInset, height: bounds.h + shadowInset))
}
}
}
fileprivate func applyBlur(_ image: CGImage, blur: GaussianBlur) -> CGImage? {
let image = CIImage(cgImage: image)
guard let filter = CIFilter(name: "CIGaussianBlur") else { return .none }
filter.setDefaults()
filter.setValue(Int(blur.radius), forKey: kCIInputRadiusKey)
filter.setValue(image, forKey: kCIInputImageKey)
let context = CIContext(options: nil)
let imageRef = context.createCGImage(filter.outputImage!, from: image.extent)
return imageRef
}
fileprivate func saveToImage(shape: Shape, shadowInset: Double, opacity: Double) -> MImage? {
guard let size = shape.bounds() else { return .none }
MGraphicsBeginImageContextWithOptions(CGSize(width: size.w + shadowInset, height: size.h + shadowInset), false, 1)
guard let tempContext = MGraphicsGetCurrentContext() else { return .none }
if (shape.fill != nil || shape.stroke != nil) {
// flip y-axis and leave space for the blur
tempContext.translateBy(x: CGFloat(shadowInset / 2 - size.x), y: CGFloat(size.h + shadowInset / 2 + size.y))
tempContext.scaleBy(x: 1, y: -1)
drawShape(in: tempContext, opacity: opacity)
}
let img = MGraphicsGetImageFromCurrentImageContext()
MGraphicsEndImageContext()
return img
}
override func doFindNodeAt(location: CGPoint, ctx: CGContext) -> Node? {

View File

@ -47,6 +47,7 @@ open class SVGParser {
fileprivate var defFills = [String: Fill]()
fileprivate var defMasks = [String: Shape]()
fileprivate var defClip = [String: Locus]()
fileprivate var defEffects = [String: Effect]()
fileprivate enum PathCommandType {
case moveTo
@ -171,8 +172,6 @@ open class SVGParser {
if let id = element.allAttributes["id"]?.text, let clip = parseClip(node) {
self.defClip[id] = clip
}
case "linearGradient", "radialGradient":
parseDefinition(node)
case "style", "defs":
// do nothing - it was parsed on first iteration
return .none
@ -211,40 +210,49 @@ open class SVGParser {
}
private func parseDefinition(_ child: XMLIndexer) {
guard let id = child.element?.allAttributes["id"]?.text else {
guard let id = child.element?.allAttributes["id"]?.text, let element = child.element else {
return
}
if let fill = parseFill(child) {
if element.name == "fill", let fill = parseFill(child) {
defFills[id] = fill
}
else if let _ = parseNode(child) {
} else if element.name == "mask", let mask = parseMask(child) {
defMasks[id] = mask
} else if element.name == "filter", let effect = parseEffect(child) {
defEffects[id] = effect
} else if element.name == "clip", let clip = parseClip(child) {
defClip[id] = clip
} else if let _ = parseNode(child) {
// TODO we don't really need to parse node
defNodes[id] = child
}
else if let mask = parseMask(child) {
defMasks[id] = mask
}
else if let clip = parseClip(child) {
defClip[id] = clip
}
}
fileprivate func parseElement(_ node: XMLIndexer, groupStyle: [String: String] = [:]) -> Node? {
guard let element = node.element else { return .none }
let styleAttributes = getStyleAttributes(groupStyle, element: element)
if styleAttributes["display"] == "none" {
let nodeStyle = getStyleAttributes(groupStyle, element: element)
if nodeStyle["display"] == "none" {
return .none
}
if styleAttributes["visibility"] == "hidden" {
if nodeStyle["visibility"] == "hidden" {
return .none
}
guard let parsedNode = parseElementInternal(node, groupStyle: nodeStyle) else { return .none }
if let filterString = element.allAttributes["filter"]?.text ?? nodeStyle["filter"], let filterId = parseIdFromUrl(filterString), let effect = defEffects[filterId] {
parsedNode.effect = effect
}
return parsedNode
}
fileprivate func parseElementInternal(_ node: XMLIndexer, groupStyle: [String: String] = [:]) -> Node? {
guard let element = node.element else { return .none }
let id = node.element?.allAttributes["id"]?.text
let styleAttributes = groupStyle
let position = getPosition(element)
switch element.name {
case "path":
@ -285,6 +293,14 @@ open class SVGParser {
stroke: getStroke(styleAttributes, groupStyle: styleAttributes), opacity: getOpacity(styleAttributes), fontName: getFontName(styleAttributes), fontSize: getFontSize(styleAttributes), fontWeight: getFontWeight(styleAttributes), pos: position)
case "use":
return parseUse(node, groupStyle: styleAttributes, place: position)
case "linearGradient", "radialGradient", "fill":
if let fill = parseFill(node), let id = id {
defFills[id] = fill
}
case "filter":
if let effect = parseEffect(node), let id = id {
defEffects[id] = effect
}
case "mask":
break
default:
@ -558,13 +574,8 @@ open class SVGParser {
if fillColor.hasPrefix("rgb") {
let color = parseRGBNotation(colorString: fillColor)
return hasFillOpacity ? color.with(a: opacity) : color
} else if fillColor.hasPrefix("url") {
let index = fillColor.index(fillColor.startIndex, offsetBy: 4)
let id = String(fillColor.suffix(from: index))
.replacingOccurrences(of: "(", with: "")
.replacingOccurrences(of: ")", with: "")
.replacingOccurrences(of: "#", with: "")
return defFills[id]
} else if let colorId = parseIdFromUrl(fillColor) {
return defFills[colorId]
} else {
return createColor(fillColor.replacingOccurrences(of: " ", with: ""), opacity: opacity)
}
@ -591,13 +602,8 @@ open class SVGParser {
fill = color.with(a: opacity)
} else if strokeColor.hasPrefix("rgb") {
fill = parseRGBNotation(colorString: strokeColor)
} else if strokeColor.hasPrefix("url") {
let index = strokeColor.index(strokeColor.startIndex, offsetBy: 4)
let id = String(strokeColor.suffix(from: index))
.replacingOccurrences(of: "(", with: "")
.replacingOccurrences(of: ")", with: "")
.replacingOccurrences(of: "#", with: "")
fill = defFills[id]
} else if let colorId = parseIdFromUrl(strokeColor) {
fill = defFills[colorId]
} else {
fill = createColor(strokeColor.replacingOccurrences(of: " ", with: ""), opacity: opacity)
}
@ -1000,6 +1006,42 @@ open class SVGParser {
return path
}
fileprivate func parseEffect(_ filterNode: XMLIndexer) -> Effect? {
let defaultSource = "SourceGraphic"
var effects = [String: Effect]()
for child in filterNode.children.reversed() {
guard let element = child.element else { continue }
let filterIn = element.allAttributes["in"]?.text ?? defaultSource
let filterOut = element.allAttributes["result"]?.text ?? ""
let currentEffect = effects[filterOut]
effects.removeValue(forKey: filterOut)
switch element.name {
case "feOffset":
if let dx = getDoubleValue(element, attribute: "dx"), let dy = getDoubleValue(element, attribute: "dy") {
effects[filterIn] = OffsetEffect(dx: dx, dy: dy, input: currentEffect)
}
case "feGaussianBlur":
if let radius = getDoubleValue(element, attribute: "stdDeviation") {
effects[filterIn] = GaussianBlur(radius: radius, input: currentEffect)
}
case "feBlend":
if let filterIn2 = element.allAttributes["in2"]?.text {
if filterIn2 == defaultSource {
effects[filterIn] = nil
} else if filterIn == defaultSource {
effects[filterIn2] = nil
}
}
default:
print("SVG parsing error. Filter \(element.name) not supported")
continue
}
}
return effects.first?.value
}
fileprivate func parseMask(_ mask: XMLIndexer) -> Shape? {
guard let element = mask.element else {
return .none
@ -1195,6 +1237,13 @@ open class SVGParser {
return .none
}
fileprivate func parseIdFromUrl(_ urlString: String) -> String? {
if urlString.hasPrefix("url") {
return urlString.substringWithOffset(fromStart: 5, fromEnd: 1)
}
return .none
}
fileprivate func getDoubleValue(_ element: SWXMLHash.XMLElement, attribute: String) -> Double? {
guard let attributeValue = element.allAttributes[attribute]?.text else {
return .none
@ -1307,12 +1356,7 @@ open class SVGParser {
}
fileprivate func getClipPath(_ attributes: [String: String]) -> Locus? {
if let clipPath = attributes["clip-path"] {
let index = clipPath.index(clipPath.startIndex, offsetBy: 4)
let id = String(clipPath.suffix(from: index))
.replacingOccurrences(of: "(", with: "")
.replacingOccurrences(of: ")", with: "")
.replacingOccurrences(of: "#", with: "")
if let clipPath = attributes["clip-path"], let id = parseIdFromUrl(clipPath) {
if let locus = defClip[id] {
return locus
}
@ -1555,3 +1599,11 @@ private class PathDataReader {
}
}
fileprivate extension String {
func substringWithOffset(fromStart: Int, fromEnd: Int) -> String {
let start = index(startIndex, offsetBy: fromStart)
let end = index(endIndex, offsetBy: -fromEnd)
return String(self[start..<end])
}
}