Compare commits

..

165 Commits

Author SHA1 Message Date
Curtis Hard d0878c9f1b Added convenience method in 2019-12-11 15:47:12 +00:00
Curtis Hard cd135ce271 Refactor and more performant string passing 2019-12-11 13:22:16 +00:00
Curtis Hard b369891e96 Added sequences to float parsing 2019-12-10 22:25:21 +00:00
Curtis Hard cde99fc501 Fixes memory leak 2019-12-06 12:03:44 +00:00
Curtis Hard efc5f139f6 Formatting 2019-12-06 08:26:03 +00:00
Curtis Hard f1c62ed828 Fixes a few things 2019-12-05 21:07:40 +00:00
Curtis Hard d66332ad07 Added is main thread check to transaction 2019-12-05 11:12:45 +00:00
Curtis Hard f2363769bf replaced calls with prefix 2019-12-04 12:58:08 +00:00
Curtis Hard ca1f0d9bf3 Performance increases and memory enhancements 2019-12-04 12:52:58 +00:00
Curtis Hard 8b7fc3171d More goodies 2019-12-04 08:59:55 +00:00
Curtis Hard 38df2094c9 Refactor and moving of groups 2019-12-04 08:59:46 +00:00
Curtis Hard 2355e86ed7 Fixes memory leak 2019-12-03 22:43:25 +00:00
Curtis Hard 192a9259fe Fixes performance here 2019-12-03 22:38:20 +00:00
Curtis Hard 2a9eb3cdc5 Added support for transparent 2019-12-03 14:26:11 +00:00
Curtis Hard 6ed4e3fb8e Export primitive shapes if they were that on import 2019-12-03 14:17:31 +00:00
Curtis Hard f6e1f1494e Initial stuff 2019-12-03 09:22:46 +00:00
Curtis Hard 775e5c15a0 Performance increases and modern syntax things 2019-12-02 22:30:52 +00:00
Curtis Hard abd19c78dd This updates formatting to meet the WebKit standard 2019-12-02 21:05:12 +00:00
Curtis Hard 29090f30f9 Fixes stuff 2019-11-28 21:56:56 +00:00
Curtis Hard e2a2fc615c Fixes warning about commas 2019-11-28 20:33:04 +00:00
Curtis Hard 5466e0f2ec More framework stuff 2019-11-28 13:26:37 +00:00
Curtis Hard c2f0c25913 Updated framework stuff 2019-11-28 13:21:08 +00:00
Curtis Hard cddc9554b4 Start of framework 2019-11-28 12:36:14 +00:00
Curtis Hard ffdbe1ec9c Fixes userSpaceOnUse for masks and clipPaths 2019-11-27 22:08:12 +00:00
Curtis Hard 63586f1181 Reformat 2019-11-18 22:57:55 +00:00
Curtis Hard dc94d9761b Fixes subcommands, this is fairly big bug… 2019-11-18 22:55:44 +00:00
Curtis Hard 8deef07f7f Merge branch 'feature/primitive-colors' of https://github.com/curthard89/IJSVG into feature/primitive-colors 2019-10-24 19:31:54 +01:00
Curtis Hard 2c962db6cc Refactoring of commands 2019-10-24 19:31:51 +01:00
Curtis Hard 9dda7915fa Fixes shorthand 2019-10-22 14:11:12 +01:00
Curtis Hard 1fbb56b443 Fixes shorthand not working correctly 2019-10-22 14:10:23 +01:00
Curtis Hard 4bbf2277bc Fixes exporter 2019-10-20 18:50:34 +01:00
Curtis Hard 7eeeea5167 Adds support for RRGGBBAA 2019-10-20 17:07:07 +01:00
Curtis Hard 8f84aa9070 Modern syntax 2019-08-15 13:16:20 +01:00
Curtis Hard 200fd6893d Fixes memory leak 2019-08-14 23:04:01 +01:00
Curtis Hard 01ad4eaeb2 Fixes clipping issue when drawing into a context 2019-07-21 22:17:58 +01:00
Curtis Hard 6b1c988d89 Added shorthand function for chcking export types 2019-07-17 22:31:13 +01:00
Curtis Hard c91ac95bc2 Swaps over normal attribute setting to a rendering style object instead 2019-07-14 15:35:40 +01:00
Curtis Hard cf14f27560 More color list features 2019-07-07 21:01:38 +01:00
Curtis Hard cef1de35d7 Inital colour sstuff 2019-07-07 20:26:39 +01:00
Curtis Hard c1a98ef5a6 Update all things! 2019-07-07 11:27:20 +01:00
Curtis Hard 690e1c8619 visibleColors now also returns if it has patternFills 2019-07-06 16:55:07 +01:00
Curtis Hard eda2b73eb2 More fixes for gradients 2019-07-06 15:52:41 +01:00
Curtis Hard f00ede11f0 More gradient fixes 2019-07-06 15:31:17 +01:00
Curtis Hard 169da55131 More fixes 2019-07-05 22:34:05 +01:00
Curtis Hard acfec29765 Fixes project for latest master 2019-07-05 15:18:14 +01:00
Curtis Hard a44cc7c098 Fixes objectBoundBox values 2019-07-05 15:16:56 +01:00
Curtis Hard 171e97451b Initial fixes for userSpaceOnUse 2019-07-05 13:27:18 +01:00
Curtis Hard 27e096350e Fixes issue with RGB being parsed incorrectly 2019-07-04 10:04:27 +01:00
Curtis Hard 04646fe4ec Fixes color bug with predefined colours 2019-07-03 21:06:58 +01:00
Curtis Hard a092b612a8 Added translateX and translateY to available transforms
- also fixes more gradient issues
2019-07-03 20:59:47 +01:00
Curtis Hard d176fe6396 This fixes userSpaceOnUse issues with gradients (i think and hope - fingers crossed) 2019-07-03 18:29:12 +01:00
Curtis Hard c94de1d241 Fixes URL parsing and scaling for gradients 2019-07-02 22:27:51 +01:00
Curtis Hard 1294372daa Moved [self class] over to modern syntax 2019-06-22 16:24:32 +01:00
Curtis Hard 60e5c6b68a Slight refactor 2019-06-16 14:00:47 +01:00
Curtis Hard 06c8191732 Added image by maintaining aspect ratio 2019-06-16 12:56:36 +01:00
Curtis Hard 2f0bead7a4 Sets initial stroke width to 1.0, should not be 0.f! 2019-06-10 15:10:52 +01:00
Curtis Hard ee46609165 Merge branch 'master' of https://github.com/IconJar/IJSVG 2019-06-07 10:04:50 +01:00
Curtis Hard 9e58ae6e19 Added string additions 2019-06-07 10:04:47 +01:00
Curtis Hard 199d1a5707 This fixes issue with strokes being set to 0 and not being interpreted correctly 2019-05-22 18:14:29 +01:00
Curtis Hard f72ae8b401 RGB values now support percentage values 2019-05-13 15:58:36 +01:00
Curtis Hard c126f511d6 Merge branch 'features/performance-increases' 2019-03-27 08:25:47 +00:00
Curtis Hard 399e9271b4 Pretty much working 2019-03-19 21:43:09 +00:00
Curtis Hard f9107094a4 Added IJSVGImageRep 2019-03-15 21:41:03 +00:00
Curtis Hard 7a64c122cf #oops 2019-03-15 09:45:18 +00:00
Curtis Hard 8ee96c4a5b Fixes gradient clipping and masking issues 2019-03-15 09:41:24 +00:00
Curtis Hard 7cace854bd Fixes duplicate colors 2019-03-14 21:37:17 +00:00
Curtis Hard 91cf59bd32 Gradient layer now works out if it can be opaque or not 2019-03-14 20:51:19 +00:00
Curtis Hard b5e15445a5 Added renderingQuality property to IJSVG 2019-03-14 20:11:49 +00:00
Curtis Hard e7577a3e76 Various performance increases
- mainly due to gradients having a party off-screen
2019-03-14 16:50:34 +00:00
Curtis Hard 25b38fa128 Various performance increases 2019-03-13 22:19:30 +00:00
Curtis Hard 8ef14224dd Fixes memory crash 2019-03-11 09:44:39 +00:00
Curtis Hard ebfc31cdb1 Ongoing performance increases 2019-03-10 21:24:45 +00:00
Curtis Hard ccfcfbf228 This fixes fillOpacity not inheriting correctly 2019-03-08 15:43:11 +00:00
Curtis Hard 4fe1d594b0 Some reason, this is not needed on 10.14
- removed for perf reasons, still does if needed, does the check for the OS
2019-03-06 21:38:57 +00:00
Curtis Hard 61d5bb99d5 Swappwd strtod over to strtod_l to use POSIX
- reuses memory instead of malloc every string, massive performance increase
2019-03-02 19:49:36 +00:00
Curtis Hard faccec3e01 Swappted atof with strtod - performs alot better 2019-03-02 14:17:28 +00:00
Curtis Hard 66e9c9000e This improves performance by using a prebuild switch of command classes instead of registering from the command class iteself 2019-03-01 21:45:19 +00:00
Curtis Hard 2006e68c2a Updated for 10.14 2018-12-02 21:52:49 +00:00
Curtis Hard 01aea1129d Added tint color 2018-10-09 15:58:59 +01:00
Curtis Hard 388982d37b Added IJSVGExporterOptionRemoveWidthHeightAttributes option to exporter 2018-08-24 21:55:51 +01:00
Curtis Hard 941130d1f2 Removed DOM discard 2018-06-03 21:27:43 +01:00
Curtis Hard b9e964dc50 Style over attribute order 2018-05-20 22:08:30 +01:00
Curtis Hard 8532819b6a Updated generator 2018-05-07 22:03:00 +01:00
Curtis Hard e576803bb7 Fixes opacity issue, defaults to 1.0 unless specified otherwise 2018-04-30 21:48:01 +01:00
Curtis Hard a6a802a36b Fixes crashes for use elements that cannot find their linked object 2018-04-14 18:41:41 +01:00
Curtis Hard b50963292c Fixes crash with restoring context 2018-03-27 19:16:20 +01:00
Curtis Hard c40c63c48d Fixes compiler error -_- 2018-03-04 13:44:38 +00:00
Curtis Hard 6d21b56416 Fixes nested SVG’s origins 2018-03-02 15:45:07 +00:00
Curtis Hard dbdd8a6971 Removed useless defintion 2018-03-02 15:32:52 +00:00
Curtis Hard b7ba91aa82 Moves frame positions over to transforms 2018-03-02 15:31:41 +00:00
Curtis Hard 98efacf93c Fixes Sub SVG rendering 2018-03-02 14:56:30 +00:00
Curtis Hard 1b3cf5a1a0 Updated Example 2018-03-02 14:12:57 +00:00
Curtis Hard 35f8663631 Gradient stroke SVG 2018-03-02 14:09:50 +00:00
Curtis Hard 6d4eb76803 Squashed commit of the following:
commit ffb55b0f31
Author: Curtis Hard <curtishard@me.com>
Date:   Fri Mar 2 13:28:40 2018 +0000

    Fixes viewBox origin translate

commit a4c032afa2
Author: Curtis Hard <curtishard@me.com>
Date:   Wed Feb 28 21:29:11 2018 +0000

    Added clip to viewport

commit abe8f4cba5
Author: Curtis Hard <curtishard@me.com>
Date:   Wed Feb 28 21:00:20 2018 +0000

    Fixes drawInRect not obeying origin

commit a16842271b
Author: Curtis Hard <curtishard@me.com>
Date:   Mon Feb 26 13:46:41 2018 +0000

    Resolves namespaces correctly + added common HTML list to be parsed as groups

commit 58126e06e4
Author: Curtis Hard <curtishard@me.com>
Date:   Sun Feb 25 21:58:49 2018 +0000

    Fixes!

commit 5af5e054ab
Author: Curtis Hard <curtishard@me.com>
Date:   Fri Feb 23 22:37:53 2018 +0000

    Fixed defNode being removed

commit edd3aa1f33
Author: Curtis Hard <curtishard@me.com>
Date:   Fri Feb 23 16:29:54 2018 +0000

    excluded various elements from diff

commit 3366bc4fa5
Author: Curtis Hard <curtishard@me.com>
Date:   Fri Feb 23 14:05:03 2018 +0000

    Better optimaztion

commit 104002183b
Author: Curtis Hard <curtishard@me.com>
Date:   Thu Feb 22 22:17:50 2018 +0000

    Added rudimenatry inline styles -> stylesheet

commit 7010b7ea50
Author: Curtis Hard <curtishard@me.com>
Date:   Thu Feb 22 13:33:32 2018 +0000

    Correct order of cleanup

commit 5266a8c07a
Author: Curtis Hard <curtishard@me.com>
Date:   Thu Feb 22 08:22:17 2018 +0000

    corrent length of string

commit caf55e8bdf
Author: Curtis Hard <curtishard@me.com>
Date:   Wed Feb 21 20:45:17 2018 +0000

    removes useless def if required

commit 8160d05eba
Author: Curtis Hard <curtishard@me.com>
Date:   Tue Feb 20 14:12:02 2018 +0000

    Refactor of a few methods

commit a6d6a06521
Author: Curtis Hard <curtishard@me.com>
Date:   Tue Feb 20 09:40:21 2018 +0000

    Added collpasing of gradients

commit 103a4d71f6
Author: Curtis Hard <curtishard@me.com>
Date:   Mon Feb 19 19:07:30 2018 +0000

    Reduced floats even more

commit 98874b1d2c
Author: Curtis Hard <curtishard@me.com>
Date:   Mon Feb 19 18:53:02 2018 +0000

    More compression goodness

commit e742db31e0
Author: Curtis Hard <curtishard@me.com>
Date:   Mon Feb 19 14:02:15 2018 +0000

    Added intermediateParent

commit 198fd09f07
Author: Curtis Hard <curtishard@me.com>
Date:   Mon Feb 19 11:51:37 2018 +0000

    Fixes! and performance increases

commit 3493194b1b
Author: Curtis Hard <curtishard@me.com>
Date:   Mon Feb 19 08:20:02 2018 +0000

    Scale computation

commit 0016775eaf
Author: Curtis Hard <curtishard@me.com>
Date:   Sun Feb 18 22:33:26 2018 +0000

    More goodness

commit 304a04cc22
Author: Curtis Hard <curtishard@me.com>
Date:   Sun Feb 18 22:32:04 2018 +0000

    Vastly improved the exporter

commit e4fd0af582
Author: Curtis Hard <curtishard@me.com>
Date:   Sun Feb 18 15:20:28 2018 +0000

    This is insanely important!

commit 69a2a0c97e
Author: Curtis Hard <curtishard@me.com>
Date:   Sun Feb 4 22:02:19 2018 +0000

    Refactor

commit 5299bb0479
Author: Curtis Hard <curtishard@me.com>
Date:   Sun Feb 4 21:58:21 2018 +0000

    will continue to use CoreAnimation for the time being

commit 4f1943cad1
Author: Curtis Hard <curtishard@me.com>
Date:   Sun Feb 4 21:57:46 2018 +0000

    Fixes gradient strokes

commit f02d186293
Author: Curtis Hard <curtishard@me.com>
Date:   Sun Feb 4 11:15:04 2018 +0000

    trying to get masks to work

commit 3291718cfb
Author: Curtis Hard <curtishard@me.com>
Date:   Fri Feb 2 22:35:22 2018 +0000

    Beginning of quartz renderer

commit 6fbaaf5884
Author: Curtis Hard <curtishard@me.com>
Date:   Mon Jan 29 22:32:08 2018 +0000

    Removed useless log

commit abc65797ea
Author: Curtis Hard <curtishard@me.com>
Date:   Mon Jan 29 21:37:45 2018 +0000

    I think gradients work :D

commit af5a1c2718
Author: Curtis Hard <curtishard@me.com>
Date:   Sun Jan 28 22:18:02 2018 +0000

    Possible fx and fy things…

commit fb9a5282b9
Author: Curtis Hard <curtishard@me.com>
Date:   Sun Jan 28 19:22:40 2018 +0000

    Even more gradient fixes

commit d83933a103
Author: Curtis Hard <curtishard@me.com>
Date:   Sun Jan 28 14:21:50 2018 +0000

    Various improvements

commit bd7a0d5021
Author: Curtis Hard <curtishard@me.com>
Date:   Sat Jan 27 22:26:33 2018 +0000

    Start to linear

commit a9a038568c
Author: Curtis Hard <curtishard@me.com>
Date:   Sat Jan 27 21:14:25 2018 +0000

    This kind of actually works...

commit 77fbb38b6f
Author: Curtis Hard <curtishard@me.com>
Date:   Sat Jan 27 20:31:36 2018 +0000

    I guess this could be a good start?

    Posssible start of fixes?

commit 12c3191569
Author: Curtis Hard <curtishard@me.com>
Date:   Sat Jan 27 15:32:15 2018 +0000

    Added method for findind absolute position

commit e3e9626ef7
Author: Curtis Hard <curtishard@me.com>
Date:   Sat Jan 27 14:25:03 2018 +0000

    Fixes crash due to parentNode on temp groups being released

commit 1160d89f16
Author: Curtis Hard <curtishard@me.com>
Date:   Fri Jan 26 22:29:22 2018 +0000

    Fixes use statements with transforms

commit 1575cbfde8
Author: Curtis Hard <curtishard@me.com>
Date:   Fri Jan 26 18:16:03 2018 +0000

    Moved color tree over to modern syntax

commit 5c4c2eee91
Author: Curtis Hard <curtishard@me.com>
Date:   Thu Jan 25 18:23:53 2018 +0000

    Added HSL/HSLA support

commit 087b13e58f
Author: Curtis Hard <curtishard@me.com>
Date:   Wed Jan 24 22:24:43 2018 +0000

    Various image loading issues resolved from base64 images

commit 1183e167aa
Author: Curtis Hard <curtishard@me.com>
Date:   Wed Jan 24 21:21:41 2018 +0000

    Rect issue fix

commit 4dbfc59437
Author: Curtis Hard <curtishard@me.com>
Date:   Wed Jan 24 21:19:24 2018 +0000

    Moved transforms over from being concatinated to seperate calls

commit 409bd509fa
Author: Curtis Hard <curtishard@me.com>
Date:   Wed Jan 24 20:30:38 2018 +0000

    Fixes color issue

commit 8ae1d1b4e0
Author: Curtis Hard <curtishard@me.com>
Date:   Wed Jan 24 18:41:08 2018 +0000

    Removed check as its not needed here

commit 7243fbe5ff
Author: Curtis Hard <curtishard@me.com>
Date:   Wed Jan 24 18:35:43 2018 +0000

    Added excludeAttributes list to parseCommonAttributes

    added x and y to that list for rect

commit 51b9a5e85f
Author: Curtis Hard <curtishard@me.com>
Date:   Tue Jan 23 19:53:04 2018 +0000

    Added isSubcommand to IJSVGCommand

    - Fixes move command going awol when preceding move commands are not subcommands (woah)

commit 40098589de
Author: Curtis Hard <curtishard@me.com>
Date:   Mon Jan 22 22:04:48 2018 +0000

    removed reverseObjectEnumerator

    IJSVGTransform already deals with this at parse stage (was a test from earlier), spec states transforms are applied in reverse order (which parser already dealth with :-))

commit 7cb96b21f2
Author: Curtis Hard <curtishard@me.com>
Date:   Mon Jan 22 22:01:56 2018 +0000

    Removed use of origin here as its computed in apply defaults

commit 1bff7c6970
Author: Curtis Hard <curtishard@me.com>
Date:   Mon Jan 22 21:48:07 2018 +0000

    Various fixes… still going…
2018-03-02 13:51:49 +00:00
Curtis Hard 36dae3ad1b Revert "Various fixes… still going…"
This reverts commit 8149293b7b.
2018-01-22 21:48:21 +00:00
Curtis Hard 8149293b7b Various fixes… still going… 2018-01-22 21:48:07 +00:00
Curtis Hard 1993c55cb8 Fixed bounds issue + colors with new line not parsing correctly 2018-01-21 21:25:36 +00:00
Curtis Hard 1f13134ccd Refactored various font things
- added CGPath methods to IJSVGUtils
2018-01-20 12:48:54 +00:00
Curtis Hard 435489f65f Removed multipass 2018-01-19 22:07:29 +00:00
Curtis Hard 4bcbcc374b Check full detail …
- adds convenience method for grabbing an SVG string from an IJSVG object
- Completely swapped IJSVGFontConverter over to use IJSVG and the IJSVGExporter
- Fixed memory leak of Defs element when exporting
2018-01-19 21:55:47 +00:00
Curtis Hard cb544d7a6b Added begin and end vector draw so they are not private 2018-01-16 22:18:25 +00:00
Curtis Hard a4cd0bcc4e Fixes issue with comments being parsed incorrectly in defs 2018-01-16 21:15:24 +00:00
Curtis Hard 02b03d8862 Fixes issue with defined elements causing infinate loop when exported from latest Sketch version 2017-12-06 20:45:24 +00:00
Curtis Hard 94ae7c2757 Added easy method for replacing whole dictionary 2017-11-14 13:29:06 +00:00
Curtis Hard 27371a9d78 Fixes issue with default fill color not being able to be user defined/replaced 2017-11-13 22:00:33 +00:00
Curtis Hard 3c1422a65f Initial color replacement start 2017-11-11 22:50:14 +00:00
Curtis Hard 8ed817aa43 Merge pull request #9 from Deadpikle/master
Fix missing files and macOS SDK setting
2017-11-07 17:55:29 +00:00
Deadpikle ca754ff61c Fix missing files and macOS SDK setting 2017-11-07 12:14:22 -05:00
Curtis Hard 53da0fca4b Refactor of shape layer and default layer 2017-09-13 11:31:58 +01:00
Curtis Hard 1259ce1e63 method name changes 2017-09-12 23:30:58 +01:00
Curtis Hard 70cd111b1c Neatness change 2017-09-12 23:11:31 +01:00
Curtis Hard 15b0805bf9 PDF!!!!!!!!
- This is nuts, so we work out way through the layers working out which are masks, working out the actual path that the mask shape would eventually have amd clip the context when it draws, hell yehs…
2017-09-12 23:00:44 +01:00
Curtis Hard e11e28c54f Here we go.. 2017-09-12 16:23:37 +01:00
Curtis Hard f320bd4684 Added compression options to export SVG 2017-09-11 21:05:51 +01:00
Curtis Hard 2faeda560f More performance 2017-09-10 18:00:06 +01:00
Curtis Hard c56a5ecca1 Faster export 2017-09-07 13:17:48 +01:00
Curtis Hard e85f67358e Initial changes for icon size to export 2017-09-05 16:03:38 +01:00
Curtis Hard 0fb27d4e94 Fixed issue where a color was not specified but a fill opacity was if no overiding color was set. 2017-09-03 20:01:30 +01:00
Curtis Hard 9bce41afff Various memory fixes 2017-07-28 21:55:49 +01:00
Curtis Hard 09b0cc6d96 Added ability to customise strokeWidth, lineCapStyle and lineJoinStyle on the root SVG object
- These will override any given styles/attributes on any element in the SVG
2017-07-04 21:25:41 +01:00
Curtis Hard 58fbb01ff2 Moved command char checker over to C call, believe it or not, this is alot faster then using a characterSet 2017-06-05 21:36:01 +01:00
Curtis Hard 5a5b144ab1 Fixes infinate loop with invalid selector characters 2017-06-05 19:31:22 +01:00
Curtis Hard 359cff7569 Squashed commit of the following:
commit d6b14b9aadc8295512f9a5513d9a3f4169d5965d
Author: Curtis Hard <curtishard@me.com>
Date:   Sun Apr 9 22:37:15 2017 +0100

    Changes to valid chars for a selector
2017-04-16 20:40:32 +01:00
Curtis Hard 57bfe633e7 Fixes issue with capitals in CSS selectors 2017-04-07 14:17:24 +01:00
Curtis Hard c757fb4b33 Merge remote-tracking branch 'origin/fixes/stroke-gradients' 2017-04-05 09:09:26 +01:00
Curtis Hard 4d1141a889 Added methods for dealing with drawing in views 2017-04-04 14:50:07 +01:00
Curtis Hard 481359ec58 Added IJSVGView - easy way to set SVG image from bundle in IB 2017-04-04 10:08:01 +01:00
Curtis Hard fb14d7be65 Added viewPort to the layer tree 2017-03-30 09:55:22 +01:00
Curtis Hard 0e4a5528f7 Added gradient unit length 2017-03-29 16:17:58 +01:00
Curtis Hard 36216a51ed Fixed dashes offset being wrong attribute key 2017-03-28 12:30:49 +01:00
Curtis Hard 9e1ffd5d46 Fixes parsing issues for DEF’s
- Some defs were not being picked up due to people sticking them at the bottom of the file, IJSVG works top down, so they were ignored, now every group or parent element will be checked for defs, parsed and then will worry about being parsed afterwards :)
2017-03-17 14:46:18 +00:00
Curtis Hard 05d0b6e173 Fixes strokes not being exported of no stroke color is set 2017-03-13 22:23:35 +00:00
Curtis Hard 9cecea923c Comments... 2017-03-13 22:02:42 +00:00
Curtis Hard 8ff1fc860e Various fixes to gradient and pattern strokes 2017-03-13 21:59:50 +00:00
Curtis Hard edef84274d Merge branch 'feature/currentcolorsupport' 2017-03-06 12:50:04 +00:00
Curtis Hard 484675f666 removed miterLimit, added currentColor to being 000 2017-03-01 14:22:50 +00:00
Curtis Hard 2f574e3cbb Fix for end char being wrong when parsing a style 2017-02-22 23:05:52 +00:00
Curtis Hard b64b0f3735 Set theme jekyll-theme-cayman 2017-02-21 13:20:09 +00:00
Curtis Hard c0cdb41ddc Set theme jekyll-theme-minimal 2017-02-21 13:18:43 +00:00
Curtis Hard 258a617564 Added X and Y to pattern node 2017-02-20 11:00:40 +00:00
Curtis Hard bf40002fe0 Adds size option to the exporter 2017-02-19 21:35:42 +00:00
Curtis Hard 2ef0bd88ef Fixes NAN issue on Arc command 2017-02-16 15:41:31 +00:00
Curtis Hard 0aca44ef76 Added offsets to pattern and gradients 2017-02-16 15:26:02 +00:00
Curtis Hard a3e512d7b8 Added fill opacity to pattern layers 2017-02-15 13:44:15 +00:00
Curtis Hard 0ffd20e87c Fixes and better gradient support 2017-02-09 21:18:30 +00:00
Curtis Hard 0f0943816c Provided a color stop if none were provided 2017-02-09 14:37:33 +00:00
Curtis Hard ddb5b2f746 Remove comment 2017-02-08 21:23:01 +00:00
Curtis Hard 80bc3ed1d8 Fixes various drawing and export issues
- Fixes transform being incorrect on export
- Fixes incorrect collapasing of groups with transforms
- Fixes incorrect alpha value in RGBA being used when exporting
- Fixes masking issue on groups (basically never applied them)
- Fixed incorrect parsing of “none” on dash count
2017-02-08 21:22:54 +00:00
Curtis Hard 1a7a7b4d7b Told image layer to need help with rasterizing 2017-02-07 10:04:42 +00:00
Curtis Hard 0876a1e976 Fixes switches that needed parsing
- Basically just parses the things we actually support, nothing more, nothing less
2017-02-07 09:52:05 +00:00
Curtis Hard 6747160504 Fixes issue with Stylesheets that are embedded inside defs not being parsed 2017-02-06 14:01:02 +00:00
Curtis Hard d2059e4d2f Removed switch elements as they are pretty useless in context of what this is used for:
- Also moved styls element and defs element into the default parsing process, which actually speeds up parsing a fair bit (when dealing with loading of 100’s of SVG’s at once)
2017-02-04 23:04:56 +00:00
Curtis Hard 71c47a313e Fixes various export issues
- Fixed issue with exporting SVG where elements that should be hidden were not being given the display:none style.
- Added option for completely removing any elements that are technically hidden (as long as they are not in the defs)
2017-01-27 23:49:08 +00:00
Curtis Hard 70f9c29fe5 This fixes hidden layers from showing
- Basically not obbeying the hidden node properly
- Also fixes CSS parser from beach balling when parsing @ selectors
- Also dramatically improves parsing of key value pairs in CSS, by dramatically, i mean took a file down from 300ms parse to 5ms… woah.
2017-01-27 19:10:01 +00:00
Curtis Hard 5f8f3d8be5 Initial blending mode support 2017-01-24 15:38:17 +00:00
Curtis Hard e26ebe300f Merge branch 'feature/pattern_gradient_strokes' 2017-01-19 15:44:13 +00:00
Curtis Hard c0c46ad2b7 Fixes overriding stroke colour not being applied to gradient or pattern strokes 2017-01-19 15:43:26 +00:00
Curtis Hard abade39e2a Fixes a huge bug with duplication on use elements being parsed and reparsed over and over 2017-01-18 16:32:57 +00:00
Curtis Hard 2f7a6aa213 Fix for gradient units not being applied 2017-01-18 15:31:08 +00:00
Curtis Hard 2598046369 Fixes string issue with linear gradients 2017-01-18 15:20:11 +00:00
Curtis Hard 5424e32a63 Various refactors for stroke pattern and gradient pattern 2017-01-18 14:59:48 +00:00
Curtis Hard a8a7f8d356 Unit computation fixes 2017-01-17 10:46:46 +00:00
Curtis Hard a3bde2f710 Fixed value working out issue 2017-01-17 09:22:19 +00:00
Curtis Hard 0cc22cad44 Update README.md 2017-01-15 21:02:35 +00:00
Curtis Hard 448d46e8ec Update README.md 2017-01-15 12:28:14 +00:00
183 changed files with 37247 additions and 16143 deletions
@@ -0,0 +1,893 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
594CF55F238FF462009B251B /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF55E238FF462009B251B /* AppKit.framework */; };
594CF561238FF46C009B251B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF560238FF46C009B251B /* Foundation.framework */; };
594CF563238FF473009B251B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 594CF562238FF473009B251B /* QuartzCore.framework */; };
599EB4D3238FF570004CB6BC /* libobjc.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 599EB4D2238FF535004CB6BC /* libobjc.tbd */; };
59EB75D623905F7300F5AE63 /* IJSVGLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756523905F6B00F5AE63 /* IJSVGLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75D723905F7300F5AE63 /* IJSVGGradientLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756623905F6B00F5AE63 /* IJSVGGradientLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75D823905F7300F5AE63 /* IJSVGStyleSheetRule.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB756723905F6B00F5AE63 /* IJSVGStyleSheetRule.m */; };
59EB75D923905F7300F5AE63 /* IJSVGCommandLineTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756823905F6B00F5AE63 /* IJSVGCommandLineTo.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75DA23905F7300F5AE63 /* IJSVGDef.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB756923905F6B00F5AE63 /* IJSVGDef.m */; };
59EB75DB23905F7300F5AE63 /* IJSVG.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756A23905F6B00F5AE63 /* IJSVG.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75DC23905F7300F5AE63 /* IJSVGText.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756B23905F6B00F5AE63 /* IJSVGText.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75DD23905F7300F5AE63 /* IJSVGCommandQuadraticCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB756C23905F6B00F5AE63 /* IJSVGCommandQuadraticCurve.m */; };
59EB75DE23905F7300F5AE63 /* IJSVGCommandVerticalLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756D23905F6C00F5AE63 /* IJSVGCommandVerticalLine.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75DF23905F7300F5AE63 /* IJSVGWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756E23905F6C00F5AE63 /* IJSVGWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75E023905F7300F5AE63 /* IJSVGStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB756F23905F6C00F5AE63 /* IJSVGStyleSheet.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75E123905F7300F5AE63 /* IJSVGCommandSmoothCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757023905F6C00F5AE63 /* IJSVGCommandSmoothCurve.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75E223905F7300F5AE63 /* IJSVGColorList.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757123905F6C00F5AE63 /* IJSVGColorList.m */; };
59EB75E323905F7300F5AE63 /* IJSVGRadialGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757223905F6C00F5AE63 /* IJSVGRadialGradient.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75E423905F7300F5AE63 /* IJSVGGradientUnitLength.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757323905F6C00F5AE63 /* IJSVGGradientUnitLength.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75E523905F7300F5AE63 /* IJSVGStrokeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757423905F6C00F5AE63 /* IJSVGStrokeLayer.m */; };
59EB75E623905F7300F5AE63 /* IJSVGStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757523905F6C00F5AE63 /* IJSVGStyle.m */; };
59EB75E723905F7300F5AE63 /* IJSVGImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757623905F6C00F5AE63 /* IJSVGImage.m */; };
59EB75E823905F7300F5AE63 /* IJSVGUnitLength.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757723905F6C00F5AE63 /* IJSVGUnitLength.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75E923905F7300F5AE63 /* IJSVGStringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757823905F6C00F5AE63 /* IJSVGStringAdditions.m */; };
59EB75EA23905F7300F5AE63 /* IJSVGTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757923905F6C00F5AE63 /* IJSVGTransaction.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75EB23905F7300F5AE63 /* IJSVGShapeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757A23905F6C00F5AE63 /* IJSVGShapeLayer.m */; };
59EB75EC23905F7300F5AE63 /* IJSVGLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757B23905F6C00F5AE63 /* IJSVGLayer.m */; };
59EB75ED23905F7300F5AE63 /* IJSVGFontConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757C23905F6C00F5AE63 /* IJSVGFontConverter.m */; };
59EB75EE23905F7300F5AE63 /* IJSVGImageRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB757D23905F6C00F5AE63 /* IJSVGImageRep.m */; };
59EB75EF23905F7300F5AE63 /* IJSVGCommandQuadraticCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757E23905F6C00F5AE63 /* IJSVGCommandQuadraticCurve.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75F023905F7300F5AE63 /* IJSVGStyleSheetSelectorRaw.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB757F23905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75F123905F7300F5AE63 /* IJSVGUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758023905F6C00F5AE63 /* IJSVGUtils.m */; };
59EB75F223905F7300F5AE63 /* IJSVGStyleSheetSelectorRaw.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758123905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.m */; };
59EB75F323905F7300F5AE63 /* IJSVGGroupLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758223905F6C00F5AE63 /* IJSVGGroupLayer.m */; };
59EB75F423905F7300F5AE63 /* IJSVGColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB758323905F6C00F5AE63 /* IJSVGColor.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75F523905F7300F5AE63 /* IJSVGError.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB758423905F6C00F5AE63 /* IJSVGError.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75F623905F7300F5AE63 /* IJSVGColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758523905F6C00F5AE63 /* IJSVGColor.m */; };
59EB75F723905F7300F5AE63 /* IJSVGDef.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB758623905F6C00F5AE63 /* IJSVGDef.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75F823905F7300F5AE63 /* IJSVGCommandHorizontalLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758723905F6C00F5AE63 /* IJSVGCommandHorizontalLine.m */; };
59EB75F923905F7300F5AE63 /* IJSVGFontConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB758823905F6D00F5AE63 /* IJSVGFontConverter.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75FA23905F7300F5AE63 /* IJSVGWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758923905F6D00F5AE63 /* IJSVGWriter.m */; };
59EB75FB23905F7300F5AE63 /* IJSVGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758A23905F6D00F5AE63 /* IJSVGPath.m */; };
59EB75FC23905F7300F5AE63 /* IJSVGGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB758B23905F6D00F5AE63 /* IJSVGGroup.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB75FD23905F7300F5AE63 /* IJSVGPatternLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758C23905F6D00F5AE63 /* IJSVGPatternLayer.m */; };
59EB75FE23905F7300F5AE63 /* IJSVGRenderingStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758D23905F6D00F5AE63 /* IJSVGRenderingStyle.m */; };
59EB75FF23905F7300F5AE63 /* IJSVGBezierPathAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758E23905F6D00F5AE63 /* IJSVGBezierPathAdditions.m */; };
59EB760023905F7300F5AE63 /* IJSVGGradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB758F23905F6D00F5AE63 /* IJSVGGradientLayer.m */; };
59EB760123905F7300F5AE63 /* IJSVGLayerTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB759023905F6D00F5AE63 /* IJSVGLayerTree.m */; };
59EB760223905F7300F5AE63 /* IJSVGCommandVerticalLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB759123905F6D00F5AE63 /* IJSVGCommandVerticalLine.m */; };
59EB760323905F7300F5AE63 /* IJSVGNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759223905F6D00F5AE63 /* IJSVGNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB760423905F7300F5AE63 /* IJSVGCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB759323905F6D00F5AE63 /* IJSVGCache.m */; };
59EB760523905F7300F5AE63 /* IJSVGUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759423905F6D00F5AE63 /* IJSVGUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB760623905F7300F5AE63 /* IJSVGCommandHorizontalLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759523905F6D00F5AE63 /* IJSVGCommandHorizontalLine.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB760723905F7300F5AE63 /* IJSVGNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB759623905F6D00F5AE63 /* IJSVGNode.m */; };
59EB760823905F7300F5AE63 /* IJSVGShapeLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759723905F6D00F5AE63 /* IJSVGShapeLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB760923905F7300F5AE63 /* IJSVGCommandCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB759823905F6E00F5AE63 /* IJSVGCommandCurve.m */; };
59EB760A23905F7300F5AE63 /* IJSVGCommandMove.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB759923905F6E00F5AE63 /* IJSVGCommandMove.m */; };
59EB760B23905F7300F5AE63 /* IJSVGStyleSheetSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759A23905F6E00F5AE63 /* IJSVGStyleSheetSelector.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB760C23905F7300F5AE63 /* IJSVGStyleSheetRule.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759B23905F6E00F5AE63 /* IJSVGStyleSheetRule.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB760D23905F7300F5AE63 /* IJSVGCommandCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759C23905F6E00F5AE63 /* IJSVGCommandCurve.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB760E23905F7300F5AE63 /* IJSVGPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759D23905F6E00F5AE63 /* IJSVGPath.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB760F23905F7300F5AE63 /* IJSVGCommandEllipticalArc.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759E23905F6E00F5AE63 /* IJSVGCommandEllipticalArc.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB761023905F7300F5AE63 /* IJSVGLinearGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB759F23905F6E00F5AE63 /* IJSVGLinearGradient.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB761123905F7300F5AE63 /* IJSVGCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75A023905F6E00F5AE63 /* IJSVGCommand.m */; };
59EB761223905F7300F5AE63 /* IJSVGRenderingStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75A123905F6E00F5AE63 /* IJSVGRenderingStyle.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB761323905F7300F5AE63 /* IJSVG.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75A223905F6E00F5AE63 /* IJSVG.m */; };
59EB761423905F7300F5AE63 /* IJSVGImageRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75A323905F6E00F5AE63 /* IJSVGImageRep.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB761523905F7300F5AE63 /* IJSVGStrokeLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75A423905F6E00F5AE63 /* IJSVGStrokeLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB761623905F7300F5AE63 /* IJSVGParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75A523905F6E00F5AE63 /* IJSVGParser.m */; };
59EB761723905F7300F5AE63 /* IJSVGRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75A623905F6F00F5AE63 /* IJSVGRadialGradient.m */; };
59EB761823905F7300F5AE63 /* IJSVGParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75A723905F6F00F5AE63 /* IJSVGParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB761923905F7300F5AE63 /* IJSVGCommandSmoothCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75A823905F6F00F5AE63 /* IJSVGCommandSmoothCurve.m */; };
59EB761A23905F7300F5AE63 /* IJSVGColorList.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75A923905F6F00F5AE63 /* IJSVGColorList.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB761B23905F7300F5AE63 /* IJSVGPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75AA23905F6F00F5AE63 /* IJSVGPattern.m */; };
59EB761C23905F7300F5AE63 /* IJSVGGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75AB23905F6F00F5AE63 /* IJSVGGradient.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB761D23905F7300F5AE63 /* IJSVGStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75AC23905F6F00F5AE63 /* IJSVGStyle.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB761E23905F7300F5AE63 /* IJSVGGroupLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75AD23905F6F00F5AE63 /* IJSVGGroupLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB761F23905F7300F5AE63 /* IJSVGCommandLineTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75AE23905F6F00F5AE63 /* IJSVGCommandLineTo.m */; };
59EB762023905F7300F5AE63 /* IJSVGCommandMove.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75AF23905F6F00F5AE63 /* IJSVGCommandMove.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB762123905F7300F5AE63 /* IJSVGTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75B023905F6F00F5AE63 /* IJSVGTransform.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB762223905F7300F5AE63 /* IJSVGMath.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75B123905F6F00F5AE63 /* IJSVGMath.m */; };
59EB762323905F7300F5AE63 /* IJSVGExporterPathInstruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75B223905F6F00F5AE63 /* IJSVGExporterPathInstruction.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB762423905F7300F5AE63 /* IJSVGTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75B323905F6F00F5AE63 /* IJSVGTransaction.m */; };
59EB762523905F7300F5AE63 /* IJSVGTransform.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75B423905F6F00F5AE63 /* IJSVGTransform.m */; };
59EB762623905F7300F5AE63 /* IJSVGImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75B523905F7000F5AE63 /* IJSVGImage.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB762723905F7300F5AE63 /* IJSVGMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75B623905F7000F5AE63 /* IJSVGMath.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB762823905F7300F5AE63 /* IJSVGCommandClose.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75B723905F7000F5AE63 /* IJSVGCommandClose.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB762923905F7300F5AE63 /* IJSVGStringAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75B823905F7000F5AE63 /* IJSVGStringAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB762A23905F7300F5AE63 /* IJSVGGradientUnitLength.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75B923905F7000F5AE63 /* IJSVGGradientUnitLength.m */; };
59EB762B23905F7300F5AE63 /* IJSVGUnitLength.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75BA23905F7000F5AE63 /* IJSVGUnitLength.m */; };
59EB762C23905F7300F5AE63 /* IJSVGPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75BB23905F7000F5AE63 /* IJSVGPattern.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB762D23905F7300F5AE63 /* IJSVGLayerTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75BC23905F7000F5AE63 /* IJSVGLayerTree.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB762E23905F7300F5AE63 /* IJSVGExporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75BD23905F7000F5AE63 /* IJSVGExporter.m */; };
59EB762F23905F7300F5AE63 /* IJSVGCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75BE23905F7000F5AE63 /* IJSVGCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB763023905F7300F5AE63 /* IJSVGPatternLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75BF23905F7000F5AE63 /* IJSVGPatternLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB763123905F7300F5AE63 /* IJSVGText.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75C023905F7100F5AE63 /* IJSVGText.m */; };
59EB763223905F7300F5AE63 /* IJSVGView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75C123905F7100F5AE63 /* IJSVGView.m */; };
59EB763323905F7300F5AE63 /* IJSVGLinearGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75C223905F7100F5AE63 /* IJSVGLinearGradient.m */; };
59EB763423905F7300F5AE63 /* IJSVGBezierPathAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75C323905F7100F5AE63 /* IJSVGBezierPathAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB763523905F7300F5AE63 /* IJSVGStyleSheetSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75C423905F7100F5AE63 /* IJSVGStyleSheetSelector.m */; };
59EB763623905F7300F5AE63 /* IJSVGImageLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75C523905F7100F5AE63 /* IJSVGImageLayer.m */; };
59EB763723905F7300F5AE63 /* IJSVGCommandClose.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75C623905F7100F5AE63 /* IJSVGCommandClose.m */; };
59EB763823905F7300F5AE63 /* IJSVGCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75C723905F7100F5AE63 /* IJSVGCommand.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB763923905F7300F5AE63 /* IJSVGCommandSmoothQuadraticCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75C823905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.m */; };
59EB763A23905F7300F5AE63 /* IJSVGForeignObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75C923905F7200F5AE63 /* IJSVGForeignObject.m */; };
59EB763B23905F7300F5AE63 /* IJSVGCommandSmoothQuadraticCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75CA23905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB763C23905F7300F5AE63 /* IJSVGCommandEllipticalArc.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75CB23905F7200F5AE63 /* IJSVGCommandEllipticalArc.m */; };
59EB763D23905F7300F5AE63 /* IJSVGGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75CC23905F7200F5AE63 /* IJSVGGroup.m */; };
59EB763E23905F7300F5AE63 /* IJSVGView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75CD23905F7200F5AE63 /* IJSVGView.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB763F23905F7300F5AE63 /* IJSVGForeignObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75CE23905F7200F5AE63 /* IJSVGForeignObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB764023905F7300F5AE63 /* IJSVGExporterPathInstruction.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75CF23905F7200F5AE63 /* IJSVGExporterPathInstruction.m */; };
59EB764123905F7300F5AE63 /* IJSVGImageLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75D023905F7200F5AE63 /* IJSVGImageLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB764223905F7300F5AE63 /* IJSVGStyleSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75D123905F7300F5AE63 /* IJSVGStyleSheet.m */; };
59EB764323905F7300F5AE63 /* IJSVGGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75D223905F7300F5AE63 /* IJSVGGradient.m */; };
59EB764423905F7300F5AE63 /* IJSVGRendering.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75D323905F7300F5AE63 /* IJSVGRendering.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB764523905F7300F5AE63 /* IJSVGExporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EB75D423905F7300F5AE63 /* IJSVGExporter.h */; settings = {ATTRIBUTES = (Public, ); }; };
59EB764623905F7300F5AE63 /* IJSVGRendering.m in Sources */ = {isa = PBXBuildFile; fileRef = 59EB75D523905F7300F5AE63 /* IJSVGRendering.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
594CF46F238FF38E009B251B /* IJSVG.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = IJSVG.framework; sourceTree = BUILT_PRODUCTS_DIR; };
594CF473238FF38E009B251B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
594CF55E238FF462009B251B /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
594CF560238FF46C009B251B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
594CF562238FF473009B251B /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
599EB4D2238FF535004CB6BC /* libobjc.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libobjc.tbd; path = usr/lib/libobjc.tbd; sourceTree = SDKROOT; };
59EB756523905F6B00F5AE63 /* IJSVGLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGLayer.h; sourceTree = "<group>"; };
59EB756623905F6B00F5AE63 /* IJSVGGradientLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGradientLayer.h; sourceTree = "<group>"; };
59EB756723905F6B00F5AE63 /* IJSVGStyleSheetRule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheetRule.m; sourceTree = "<group>"; };
59EB756823905F6B00F5AE63 /* IJSVGCommandLineTo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandLineTo.h; sourceTree = "<group>"; };
59EB756923905F6B00F5AE63 /* IJSVGDef.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGDef.m; sourceTree = "<group>"; };
59EB756A23905F6B00F5AE63 /* IJSVG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVG.h; path = ../../../../source/IJSVG.h; sourceTree = "<group>"; };
59EB756B23905F6B00F5AE63 /* IJSVGText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGText.h; sourceTree = "<group>"; };
59EB756C23905F6B00F5AE63 /* IJSVGCommandQuadraticCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandQuadraticCurve.m; sourceTree = "<group>"; };
59EB756D23905F6C00F5AE63 /* IJSVGCommandVerticalLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandVerticalLine.h; sourceTree = "<group>"; };
59EB756E23905F6C00F5AE63 /* IJSVGWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGWriter.h; path = ../../../../source/IJSVGWriter.h; sourceTree = "<group>"; };
59EB756F23905F6C00F5AE63 /* IJSVGStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheet.h; sourceTree = "<group>"; };
59EB757023905F6C00F5AE63 /* IJSVGCommandSmoothCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandSmoothCurve.h; sourceTree = "<group>"; };
59EB757123905F6C00F5AE63 /* IJSVGColorList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGColorList.m; sourceTree = "<group>"; };
59EB757223905F6C00F5AE63 /* IJSVGRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGRadialGradient.h; sourceTree = "<group>"; };
59EB757323905F6C00F5AE63 /* IJSVGGradientUnitLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGradientUnitLength.h; sourceTree = "<group>"; };
59EB757423905F6C00F5AE63 /* IJSVGStrokeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStrokeLayer.m; sourceTree = "<group>"; };
59EB757523905F6C00F5AE63 /* IJSVGStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyle.m; sourceTree = "<group>"; };
59EB757623905F6C00F5AE63 /* IJSVGImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGImage.m; sourceTree = "<group>"; };
59EB757723905F6C00F5AE63 /* IJSVGUnitLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGUnitLength.h; sourceTree = "<group>"; };
59EB757823905F6C00F5AE63 /* IJSVGStringAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStringAdditions.m; sourceTree = "<group>"; };
59EB757923905F6C00F5AE63 /* IJSVGTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGTransaction.h; sourceTree = "<group>"; };
59EB757A23905F6C00F5AE63 /* IJSVGShapeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGShapeLayer.m; sourceTree = "<group>"; };
59EB757B23905F6C00F5AE63 /* IJSVGLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGLayer.m; sourceTree = "<group>"; };
59EB757C23905F6C00F5AE63 /* IJSVGFontConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGFontConverter.m; path = ../../../../source/IJSVGFontConverter.m; sourceTree = "<group>"; };
59EB757D23905F6C00F5AE63 /* IJSVGImageRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGImageRep.m; path = ../../../../source/IJSVGImageRep.m; sourceTree = "<group>"; };
59EB757E23905F6C00F5AE63 /* IJSVGCommandQuadraticCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandQuadraticCurve.h; sourceTree = "<group>"; };
59EB757F23905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheetSelectorRaw.h; sourceTree = "<group>"; };
59EB758023905F6C00F5AE63 /* IJSVGUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGUtils.m; sourceTree = "<group>"; };
59EB758123905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheetSelectorRaw.m; sourceTree = "<group>"; };
59EB758223905F6C00F5AE63 /* IJSVGGroupLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGroupLayer.m; sourceTree = "<group>"; };
59EB758323905F6C00F5AE63 /* IJSVGColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGColor.h; sourceTree = "<group>"; };
59EB758423905F6C00F5AE63 /* IJSVGError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGError.h; path = ../../../../source/IJSVGError.h; sourceTree = "<group>"; };
59EB758523905F6C00F5AE63 /* IJSVGColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGColor.m; sourceTree = "<group>"; };
59EB758623905F6C00F5AE63 /* IJSVGDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGDef.h; sourceTree = "<group>"; };
59EB758723905F6C00F5AE63 /* IJSVGCommandHorizontalLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandHorizontalLine.m; sourceTree = "<group>"; };
59EB758823905F6D00F5AE63 /* IJSVGFontConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGFontConverter.h; path = ../../../../source/IJSVGFontConverter.h; sourceTree = "<group>"; };
59EB758923905F6D00F5AE63 /* IJSVGWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGWriter.m; path = ../../../../source/IJSVGWriter.m; sourceTree = "<group>"; };
59EB758A23905F6D00F5AE63 /* IJSVGPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGPath.m; sourceTree = "<group>"; };
59EB758B23905F6D00F5AE63 /* IJSVGGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGroup.h; sourceTree = "<group>"; };
59EB758C23905F6D00F5AE63 /* IJSVGPatternLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGPatternLayer.m; sourceTree = "<group>"; };
59EB758D23905F6D00F5AE63 /* IJSVGRenderingStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGRenderingStyle.m; sourceTree = "<group>"; };
59EB758E23905F6D00F5AE63 /* IJSVGBezierPathAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGBezierPathAdditions.m; sourceTree = "<group>"; };
59EB758F23905F6D00F5AE63 /* IJSVGGradientLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGradientLayer.m; sourceTree = "<group>"; };
59EB759023905F6D00F5AE63 /* IJSVGLayerTree.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGLayerTree.m; sourceTree = "<group>"; };
59EB759123905F6D00F5AE63 /* IJSVGCommandVerticalLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandVerticalLine.m; sourceTree = "<group>"; };
59EB759223905F6D00F5AE63 /* IJSVGNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGNode.h; sourceTree = "<group>"; };
59EB759323905F6D00F5AE63 /* IJSVGCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGCache.m; path = ../../../../source/IJSVGCache.m; sourceTree = "<group>"; };
59EB759423905F6D00F5AE63 /* IJSVGUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGUtils.h; sourceTree = "<group>"; };
59EB759523905F6D00F5AE63 /* IJSVGCommandHorizontalLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandHorizontalLine.h; sourceTree = "<group>"; };
59EB759623905F6D00F5AE63 /* IJSVGNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGNode.m; sourceTree = "<group>"; };
59EB759723905F6D00F5AE63 /* IJSVGShapeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGShapeLayer.h; sourceTree = "<group>"; };
59EB759823905F6E00F5AE63 /* IJSVGCommandCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandCurve.m; sourceTree = "<group>"; };
59EB759923905F6E00F5AE63 /* IJSVGCommandMove.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandMove.m; sourceTree = "<group>"; };
59EB759A23905F6E00F5AE63 /* IJSVGStyleSheetSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheetSelector.h; sourceTree = "<group>"; };
59EB759B23905F6E00F5AE63 /* IJSVGStyleSheetRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyleSheetRule.h; sourceTree = "<group>"; };
59EB759C23905F6E00F5AE63 /* IJSVGCommandCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandCurve.h; sourceTree = "<group>"; };
59EB759D23905F6E00F5AE63 /* IJSVGPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGPath.h; sourceTree = "<group>"; };
59EB759E23905F6E00F5AE63 /* IJSVGCommandEllipticalArc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandEllipticalArc.h; sourceTree = "<group>"; };
59EB759F23905F6E00F5AE63 /* IJSVGLinearGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGLinearGradient.h; sourceTree = "<group>"; };
59EB75A023905F6E00F5AE63 /* IJSVGCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommand.m; sourceTree = "<group>"; };
59EB75A123905F6E00F5AE63 /* IJSVGRenderingStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGRenderingStyle.h; sourceTree = "<group>"; };
59EB75A223905F6E00F5AE63 /* IJSVG.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVG.m; path = ../../../../source/IJSVG.m; sourceTree = "<group>"; };
59EB75A323905F6E00F5AE63 /* IJSVGImageRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGImageRep.h; path = ../../../../source/IJSVGImageRep.h; sourceTree = "<group>"; };
59EB75A423905F6E00F5AE63 /* IJSVGStrokeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStrokeLayer.h; sourceTree = "<group>"; };
59EB75A523905F6E00F5AE63 /* IJSVGParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGParser.m; sourceTree = "<group>"; };
59EB75A623905F6F00F5AE63 /* IJSVGRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGRadialGradient.m; sourceTree = "<group>"; };
59EB75A723905F6F00F5AE63 /* IJSVGParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGParser.h; sourceTree = "<group>"; };
59EB75A823905F6F00F5AE63 /* IJSVGCommandSmoothCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandSmoothCurve.m; sourceTree = "<group>"; };
59EB75A923905F6F00F5AE63 /* IJSVGColorList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGColorList.h; sourceTree = "<group>"; };
59EB75AA23905F6F00F5AE63 /* IJSVGPattern.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGPattern.m; sourceTree = "<group>"; };
59EB75AB23905F6F00F5AE63 /* IJSVGGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGradient.h; sourceTree = "<group>"; };
59EB75AC23905F6F00F5AE63 /* IJSVGStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStyle.h; sourceTree = "<group>"; };
59EB75AD23905F6F00F5AE63 /* IJSVGGroupLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGGroupLayer.h; sourceTree = "<group>"; };
59EB75AE23905F6F00F5AE63 /* IJSVGCommandLineTo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandLineTo.m; sourceTree = "<group>"; };
59EB75AF23905F6F00F5AE63 /* IJSVGCommandMove.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandMove.h; sourceTree = "<group>"; };
59EB75B023905F6F00F5AE63 /* IJSVGTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGTransform.h; sourceTree = "<group>"; };
59EB75B123905F6F00F5AE63 /* IJSVGMath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGMath.m; sourceTree = "<group>"; };
59EB75B223905F6F00F5AE63 /* IJSVGExporterPathInstruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGExporterPathInstruction.h; sourceTree = "<group>"; };
59EB75B323905F6F00F5AE63 /* IJSVGTransaction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGTransaction.m; sourceTree = "<group>"; };
59EB75B423905F6F00F5AE63 /* IJSVGTransform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGTransform.m; sourceTree = "<group>"; };
59EB75B523905F7000F5AE63 /* IJSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGImage.h; sourceTree = "<group>"; };
59EB75B623905F7000F5AE63 /* IJSVGMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGMath.h; sourceTree = "<group>"; };
59EB75B723905F7000F5AE63 /* IJSVGCommandClose.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandClose.h; sourceTree = "<group>"; };
59EB75B823905F7000F5AE63 /* IJSVGStringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGStringAdditions.h; sourceTree = "<group>"; };
59EB75B923905F7000F5AE63 /* IJSVGGradientUnitLength.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGradientUnitLength.m; sourceTree = "<group>"; };
59EB75BA23905F7000F5AE63 /* IJSVGUnitLength.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGUnitLength.m; sourceTree = "<group>"; };
59EB75BB23905F7000F5AE63 /* IJSVGPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGPattern.h; sourceTree = "<group>"; };
59EB75BC23905F7000F5AE63 /* IJSVGLayerTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGLayerTree.h; sourceTree = "<group>"; };
59EB75BD23905F7000F5AE63 /* IJSVGExporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGExporter.m; sourceTree = "<group>"; };
59EB75BE23905F7000F5AE63 /* IJSVGCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGCache.h; path = ../../../../source/IJSVGCache.h; sourceTree = "<group>"; };
59EB75BF23905F7000F5AE63 /* IJSVGPatternLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGPatternLayer.h; sourceTree = "<group>"; };
59EB75C023905F7100F5AE63 /* IJSVGText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGText.m; sourceTree = "<group>"; };
59EB75C123905F7100F5AE63 /* IJSVGView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGView.m; path = ../../../../source/IJSVGView.m; sourceTree = "<group>"; };
59EB75C223905F7100F5AE63 /* IJSVGLinearGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGLinearGradient.m; sourceTree = "<group>"; };
59EB75C323905F7100F5AE63 /* IJSVGBezierPathAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGBezierPathAdditions.h; sourceTree = "<group>"; };
59EB75C423905F7100F5AE63 /* IJSVGStyleSheetSelector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheetSelector.m; sourceTree = "<group>"; };
59EB75C523905F7100F5AE63 /* IJSVGImageLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGImageLayer.m; sourceTree = "<group>"; };
59EB75C623905F7100F5AE63 /* IJSVGCommandClose.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandClose.m; sourceTree = "<group>"; };
59EB75C723905F7100F5AE63 /* IJSVGCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommand.h; sourceTree = "<group>"; };
59EB75C823905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandSmoothQuadraticCurve.m; sourceTree = "<group>"; };
59EB75C923905F7200F5AE63 /* IJSVGForeignObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGForeignObject.m; sourceTree = "<group>"; };
59EB75CA23905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGCommandSmoothQuadraticCurve.h; sourceTree = "<group>"; };
59EB75CB23905F7200F5AE63 /* IJSVGCommandEllipticalArc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGCommandEllipticalArc.m; sourceTree = "<group>"; };
59EB75CC23905F7200F5AE63 /* IJSVGGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGroup.m; sourceTree = "<group>"; };
59EB75CD23905F7200F5AE63 /* IJSVGView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGView.h; path = ../../../../source/IJSVGView.h; sourceTree = "<group>"; };
59EB75CE23905F7200F5AE63 /* IJSVGForeignObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGForeignObject.h; sourceTree = "<group>"; };
59EB75CF23905F7200F5AE63 /* IJSVGExporterPathInstruction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGExporterPathInstruction.m; sourceTree = "<group>"; };
59EB75D023905F7200F5AE63 /* IJSVGImageLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGImageLayer.h; sourceTree = "<group>"; };
59EB75D123905F7300F5AE63 /* IJSVGStyleSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGStyleSheet.m; sourceTree = "<group>"; };
59EB75D223905F7300F5AE63 /* IJSVGGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGGradient.m; sourceTree = "<group>"; };
59EB75D323905F7300F5AE63 /* IJSVGRendering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGRendering.h; sourceTree = "<group>"; };
59EB75D423905F7300F5AE63 /* IJSVGExporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSVGExporter.h; sourceTree = "<group>"; };
59EB75D523905F7300F5AE63 /* IJSVGRendering.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJSVGRendering.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
594CF46C238FF38E009B251B /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
599EB4D3238FF570004CB6BC /* libobjc.tbd in Frameworks */,
594CF55F238FF462009B251B /* AppKit.framework in Frameworks */,
594CF561238FF46C009B251B /* Foundation.framework in Frameworks */,
594CF563238FF473009B251B /* QuartzCore.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
592ABBE223979F9B00F44380 /* Commands */ = {
isa = PBXGroup;
children = (
59EB75C723905F7100F5AE63 /* IJSVGCommand.h */,
59EB75A023905F6E00F5AE63 /* IJSVGCommand.m */,
59EB75B723905F7000F5AE63 /* IJSVGCommandClose.h */,
59EB75C623905F7100F5AE63 /* IJSVGCommandClose.m */,
59EB759C23905F6E00F5AE63 /* IJSVGCommandCurve.h */,
59EB759823905F6E00F5AE63 /* IJSVGCommandCurve.m */,
59EB759E23905F6E00F5AE63 /* IJSVGCommandEllipticalArc.h */,
59EB75CB23905F7200F5AE63 /* IJSVGCommandEllipticalArc.m */,
59EB759523905F6D00F5AE63 /* IJSVGCommandHorizontalLine.h */,
59EB758723905F6C00F5AE63 /* IJSVGCommandHorizontalLine.m */,
59EB756823905F6B00F5AE63 /* IJSVGCommandLineTo.h */,
59EB75AE23905F6F00F5AE63 /* IJSVGCommandLineTo.m */,
59EB75AF23905F6F00F5AE63 /* IJSVGCommandMove.h */,
59EB759923905F6E00F5AE63 /* IJSVGCommandMove.m */,
59EB757E23905F6C00F5AE63 /* IJSVGCommandQuadraticCurve.h */,
59EB756C23905F6B00F5AE63 /* IJSVGCommandQuadraticCurve.m */,
59EB757023905F6C00F5AE63 /* IJSVGCommandSmoothCurve.h */,
59EB75A823905F6F00F5AE63 /* IJSVGCommandSmoothCurve.m */,
59EB75CA23905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.h */,
59EB75C823905F7200F5AE63 /* IJSVGCommandSmoothQuadraticCurve.m */,
59EB756D23905F6C00F5AE63 /* IJSVGCommandVerticalLine.h */,
59EB759123905F6D00F5AE63 /* IJSVGCommandVerticalLine.m */,
);
path = Commands;
sourceTree = "<group>";
};
592ABBE323979FBB00F44380 /* Stylesheets */ = {
isa = PBXGroup;
children = (
59EB75AC23905F6F00F5AE63 /* IJSVGStyle.h */,
59EB757523905F6C00F5AE63 /* IJSVGStyle.m */,
59EB756F23905F6C00F5AE63 /* IJSVGStyleSheet.h */,
59EB75D123905F7300F5AE63 /* IJSVGStyleSheet.m */,
59EB759B23905F6E00F5AE63 /* IJSVGStyleSheetRule.h */,
59EB756723905F6B00F5AE63 /* IJSVGStyleSheetRule.m */,
59EB759A23905F6E00F5AE63 /* IJSVGStyleSheetSelector.h */,
59EB75C423905F7100F5AE63 /* IJSVGStyleSheetSelector.m */,
59EB757F23905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.h */,
59EB758123905F6C00F5AE63 /* IJSVGStyleSheetSelectorRaw.m */,
);
path = Stylesheets;
sourceTree = "<group>";
};
592ABBE423979FD200F44380 /* Colors */ = {
isa = PBXGroup;
children = (
59EB758323905F6C00F5AE63 /* IJSVGColor.h */,
59EB758523905F6C00F5AE63 /* IJSVGColor.m */,
59EB75A923905F6F00F5AE63 /* IJSVGColorList.h */,
59EB757123905F6C00F5AE63 /* IJSVGColorList.m */,
);
path = Colors;
sourceTree = "<group>";
};
592ABBE523979FE100F44380 /* Layers */ = {
isa = PBXGroup;
children = (
59EB756623905F6B00F5AE63 /* IJSVGGradientLayer.h */,
59EB758F23905F6D00F5AE63 /* IJSVGGradientLayer.m */,
59EB75AD23905F6F00F5AE63 /* IJSVGGroupLayer.h */,
59EB758223905F6C00F5AE63 /* IJSVGGroupLayer.m */,
59EB75D023905F7200F5AE63 /* IJSVGImageLayer.h */,
59EB75C523905F7100F5AE63 /* IJSVGImageLayer.m */,
59EB756523905F6B00F5AE63 /* IJSVGLayer.h */,
59EB757B23905F6C00F5AE63 /* IJSVGLayer.m */,
59EB75BF23905F7000F5AE63 /* IJSVGPatternLayer.h */,
59EB758C23905F6D00F5AE63 /* IJSVGPatternLayer.m */,
59EB757223905F6C00F5AE63 /* IJSVGRadialGradient.h */,
59EB75A623905F6F00F5AE63 /* IJSVGRadialGradient.m */,
59EB759723905F6D00F5AE63 /* IJSVGShapeLayer.h */,
59EB757A23905F6C00F5AE63 /* IJSVGShapeLayer.m */,
59EB75A423905F6E00F5AE63 /* IJSVGStrokeLayer.h */,
59EB757423905F6C00F5AE63 /* IJSVGStrokeLayer.m */,
);
path = Layers;
sourceTree = "<group>";
};
592ABBE62397A00C00F44380 /* Parsing */ = {
isa = PBXGroup;
children = (
59EB75A723905F6F00F5AE63 /* IJSVGParser.h */,
59EB75A523905F6E00F5AE63 /* IJSVGParser.m */,
);
path = Parsing;
sourceTree = "<group>";
};
592ABBE72397A02900F44380 /* Nodes */ = {
isa = PBXGroup;
children = (
59EB75CE23905F7200F5AE63 /* IJSVGForeignObject.h */,
59EB75C923905F7200F5AE63 /* IJSVGForeignObject.m */,
59EB758623905F6C00F5AE63 /* IJSVGDef.h */,
59EB756923905F6B00F5AE63 /* IJSVGDef.m */,
59EB759F23905F6E00F5AE63 /* IJSVGLinearGradient.h */,
59EB75C223905F7100F5AE63 /* IJSVGLinearGradient.m */,
59EB75AB23905F6F00F5AE63 /* IJSVGGradient.h */,
59EB75D223905F7300F5AE63 /* IJSVGGradient.m */,
59EB758B23905F6D00F5AE63 /* IJSVGGroup.h */,
59EB75CC23905F7200F5AE63 /* IJSVGGroup.m */,
59EB75B523905F7000F5AE63 /* IJSVGImage.h */,
59EB757623905F6C00F5AE63 /* IJSVGImage.m */,
59EB759223905F6D00F5AE63 /* IJSVGNode.h */,
59EB759623905F6D00F5AE63 /* IJSVGNode.m */,
59EB759D23905F6E00F5AE63 /* IJSVGPath.h */,
59EB758A23905F6D00F5AE63 /* IJSVGPath.m */,
59EB75BB23905F7000F5AE63 /* IJSVGPattern.h */,
59EB75AA23905F6F00F5AE63 /* IJSVGPattern.m */,
59EB756B23905F6B00F5AE63 /* IJSVGText.h */,
59EB75C023905F7100F5AE63 /* IJSVGText.m */,
);
path = Nodes;
sourceTree = "<group>";
};
592ABBE82397A06800F44380 /* Utils */ = {
isa = PBXGroup;
children = (
59EB757323905F6C00F5AE63 /* IJSVGGradientUnitLength.h */,
59EB75B923905F7000F5AE63 /* IJSVGGradientUnitLength.m */,
59EB75B623905F7000F5AE63 /* IJSVGMath.h */,
59EB75B123905F6F00F5AE63 /* IJSVGMath.m */,
59EB757923905F6C00F5AE63 /* IJSVGTransaction.h */,
59EB75B323905F6F00F5AE63 /* IJSVGTransaction.m */,
59EB75B023905F6F00F5AE63 /* IJSVGTransform.h */,
59EB75B423905F6F00F5AE63 /* IJSVGTransform.m */,
59EB757723905F6C00F5AE63 /* IJSVGUnitLength.h */,
59EB75BA23905F7000F5AE63 /* IJSVGUnitLength.m */,
59EB759423905F6D00F5AE63 /* IJSVGUtils.h */,
59EB758023905F6C00F5AE63 /* IJSVGUtils.m */,
);
path = Utils;
sourceTree = "<group>";
};
592ABBE92397A08500F44380 /* Exporter */ = {
isa = PBXGroup;
children = (
59EB75D423905F7300F5AE63 /* IJSVGExporter.h */,
59EB75BD23905F7000F5AE63 /* IJSVGExporter.m */,
59EB75B223905F6F00F5AE63 /* IJSVGExporterPathInstruction.h */,
59EB75CF23905F7200F5AE63 /* IJSVGExporterPathInstruction.m */,
);
path = Exporter;
sourceTree = "<group>";
};
592ABBEA2397A10000F44380 /* Rendering */ = {
isa = PBXGroup;
children = (
59EB75BC23905F7000F5AE63 /* IJSVGLayerTree.h */,
59EB759023905F6D00F5AE63 /* IJSVGLayerTree.m */,
59EB75D323905F7300F5AE63 /* IJSVGRendering.h */,
59EB75D523905F7300F5AE63 /* IJSVGRendering.m */,
59EB75A123905F6E00F5AE63 /* IJSVGRenderingStyle.h */,
59EB758D23905F6D00F5AE63 /* IJSVGRenderingStyle.m */,
);
path = Rendering;
sourceTree = "<group>";
};
592ABBEB2397A11800F44380 /* Additions */ = {
isa = PBXGroup;
children = (
59EB75C323905F7100F5AE63 /* IJSVGBezierPathAdditions.h */,
59EB758E23905F6D00F5AE63 /* IJSVGBezierPathAdditions.m */,
59EB75B823905F7000F5AE63 /* IJSVGStringAdditions.h */,
59EB757823905F6C00F5AE63 /* IJSVGStringAdditions.m */,
);
path = Additions;
sourceTree = "<group>";
};
594CF465238FF38E009B251B = {
isa = PBXGroup;
children = (
594CF471238FF38E009B251B /* IJSVG */,
594CF470238FF38E009B251B /* Products */,
594CF55D238FF461009B251B /* Frameworks */,
);
sourceTree = "<group>";
};
594CF470238FF38E009B251B /* Products */ = {
isa = PBXGroup;
children = (
594CF46F238FF38E009B251B /* IJSVG.framework */,
);
name = Products;
sourceTree = "<group>";
};
594CF471238FF38E009B251B /* IJSVG */ = {
isa = PBXGroup;
children = (
59EB756423905F3100F5AE63 /* Source */,
594CF473238FF38E009B251B /* Info.plist */,
);
path = IJSVG;
sourceTree = "<group>";
};
594CF55D238FF461009B251B /* Frameworks */ = {
isa = PBXGroup;
children = (
599EB4D2238FF535004CB6BC /* libobjc.tbd */,
594CF562238FF473009B251B /* QuartzCore.framework */,
594CF560238FF46C009B251B /* Foundation.framework */,
594CF55E238FF462009B251B /* AppKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
59EB756423905F3100F5AE63 /* Source */ = {
isa = PBXGroup;
children = (
592ABBEB2397A11800F44380 /* Additions */,
592ABBEA2397A10000F44380 /* Rendering */,
592ABBE92397A08500F44380 /* Exporter */,
592ABBE82397A06800F44380 /* Utils */,
592ABBE72397A02900F44380 /* Nodes */,
592ABBE62397A00C00F44380 /* Parsing */,
592ABBE523979FE100F44380 /* Layers */,
592ABBE423979FD200F44380 /* Colors */,
592ABBE323979FBB00F44380 /* Stylesheets */,
592ABBE223979F9B00F44380 /* Commands */,
59EB756A23905F6B00F5AE63 /* IJSVG.h */,
59EB75A223905F6E00F5AE63 /* IJSVG.m */,
59EB75BE23905F7000F5AE63 /* IJSVGCache.h */,
59EB759323905F6D00F5AE63 /* IJSVGCache.m */,
59EB758423905F6C00F5AE63 /* IJSVGError.h */,
59EB758823905F6D00F5AE63 /* IJSVGFontConverter.h */,
59EB757C23905F6C00F5AE63 /* IJSVGFontConverter.m */,
59EB75A323905F6E00F5AE63 /* IJSVGImageRep.h */,
59EB757D23905F6C00F5AE63 /* IJSVGImageRep.m */,
59EB75CD23905F7200F5AE63 /* IJSVGView.h */,
59EB75C123905F7100F5AE63 /* IJSVGView.m */,
59EB756E23905F6C00F5AE63 /* IJSVGWriter.h */,
59EB758923905F6D00F5AE63 /* IJSVGWriter.m */,
);
path = Source;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
594CF46A238FF38E009B251B /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
59EB762623905F7300F5AE63 /* IJSVGImage.h in Headers */,
59EB760823905F7300F5AE63 /* IJSVGShapeLayer.h in Headers */,
59EB75DF23905F7300F5AE63 /* IJSVGWriter.h in Headers */,
59EB760F23905F7300F5AE63 /* IJSVGCommandEllipticalArc.h in Headers */,
59EB75F523905F7300F5AE63 /* IJSVGError.h in Headers */,
59EB763E23905F7300F5AE63 /* IJSVGView.h in Headers */,
59EB75DB23905F7300F5AE63 /* IJSVG.h in Headers */,
59EB764423905F7300F5AE63 /* IJSVGRendering.h in Headers */,
59EB75DC23905F7300F5AE63 /* IJSVGText.h in Headers */,
59EB761C23905F7300F5AE63 /* IJSVGGradient.h in Headers */,
59EB75F923905F7300F5AE63 /* IJSVGFontConverter.h in Headers */,
59EB75EF23905F7300F5AE63 /* IJSVGCommandQuadraticCurve.h in Headers */,
59EB75FC23905F7300F5AE63 /* IJSVGGroup.h in Headers */,
59EB760323905F7300F5AE63 /* IJSVGNode.h in Headers */,
59EB762023905F7300F5AE63 /* IJSVGCommandMove.h in Headers */,
59EB762C23905F7300F5AE63 /* IJSVGPattern.h in Headers */,
59EB762923905F7300F5AE63 /* IJSVGStringAdditions.h in Headers */,
59EB761A23905F7300F5AE63 /* IJSVGColorList.h in Headers */,
59EB762123905F7300F5AE63 /* IJSVGTransform.h in Headers */,
59EB763F23905F7300F5AE63 /* IJSVGForeignObject.h in Headers */,
59EB75F423905F7300F5AE63 /* IJSVGColor.h in Headers */,
59EB760D23905F7300F5AE63 /* IJSVGCommandCurve.h in Headers */,
59EB763823905F7300F5AE63 /* IJSVGCommand.h in Headers */,
59EB760C23905F7300F5AE63 /* IJSVGStyleSheetRule.h in Headers */,
59EB75E323905F7300F5AE63 /* IJSVGRadialGradient.h in Headers */,
59EB760523905F7300F5AE63 /* IJSVGUtils.h in Headers */,
59EB763B23905F7300F5AE63 /* IJSVGCommandSmoothQuadraticCurve.h in Headers */,
59EB75E823905F7300F5AE63 /* IJSVGUnitLength.h in Headers */,
59EB762723905F7300F5AE63 /* IJSVGMath.h in Headers */,
59EB761523905F7300F5AE63 /* IJSVGStrokeLayer.h in Headers */,
59EB762F23905F7300F5AE63 /* IJSVGCache.h in Headers */,
59EB75DE23905F7300F5AE63 /* IJSVGCommandVerticalLine.h in Headers */,
59EB764123905F7300F5AE63 /* IJSVGImageLayer.h in Headers */,
59EB75E023905F7300F5AE63 /* IJSVGStyleSheet.h in Headers */,
59EB761423905F7300F5AE63 /* IJSVGImageRep.h in Headers */,
59EB761223905F7300F5AE63 /* IJSVGRenderingStyle.h in Headers */,
59EB760E23905F7300F5AE63 /* IJSVGPath.h in Headers */,
59EB75EA23905F7300F5AE63 /* IJSVGTransaction.h in Headers */,
59EB75D723905F7300F5AE63 /* IJSVGGradientLayer.h in Headers */,
59EB75F723905F7300F5AE63 /* IJSVGDef.h in Headers */,
59EB760623905F7300F5AE63 /* IJSVGCommandHorizontalLine.h in Headers */,
59EB762323905F7300F5AE63 /* IJSVGExporterPathInstruction.h in Headers */,
59EB761023905F7300F5AE63 /* IJSVGLinearGradient.h in Headers */,
59EB75E123905F7300F5AE63 /* IJSVGCommandSmoothCurve.h in Headers */,
59EB75D923905F7300F5AE63 /* IJSVGCommandLineTo.h in Headers */,
59EB75D623905F7300F5AE63 /* IJSVGLayer.h in Headers */,
59EB763023905F7300F5AE63 /* IJSVGPatternLayer.h in Headers */,
59EB75F023905F7300F5AE63 /* IJSVGStyleSheetSelectorRaw.h in Headers */,
59EB763423905F7300F5AE63 /* IJSVGBezierPathAdditions.h in Headers */,
59EB761823905F7300F5AE63 /* IJSVGParser.h in Headers */,
59EB761E23905F7300F5AE63 /* IJSVGGroupLayer.h in Headers */,
59EB761D23905F7300F5AE63 /* IJSVGStyle.h in Headers */,
59EB764523905F7300F5AE63 /* IJSVGExporter.h in Headers */,
59EB762823905F7300F5AE63 /* IJSVGCommandClose.h in Headers */,
59EB75E423905F7300F5AE63 /* IJSVGGradientUnitLength.h in Headers */,
59EB762D23905F7300F5AE63 /* IJSVGLayerTree.h in Headers */,
59EB760B23905F7300F5AE63 /* IJSVGStyleSheetSelector.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
594CF46E238FF38E009B251B /* IJSVG */ = {
isa = PBXNativeTarget;
buildConfigurationList = 594CF477238FF38E009B251B /* Build configuration list for PBXNativeTarget "IJSVG" */;
buildPhases = (
594CF46A238FF38E009B251B /* Headers */,
594CF46B238FF38E009B251B /* Sources */,
594CF46C238FF38E009B251B /* Frameworks */,
594CF46D238FF38E009B251B /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = IJSVG;
productName = IJSVG;
productReference = 594CF46F238FF38E009B251B /* IJSVG.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
594CF466238FF38E009B251B /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1100;
ORGANIZATIONNAME = "Curtis Hard";
TargetAttributes = {
594CF46E238FF38E009B251B = {
CreatedOnToolsVersion = 11.0;
};
};
};
buildConfigurationList = 594CF469238FF38E009B251B /* Build configuration list for PBXProject "IJSVG" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 594CF465238FF38E009B251B;
productRefGroup = 594CF470238FF38E009B251B /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
594CF46E238FF38E009B251B /* IJSVG */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
594CF46D238FF38E009B251B /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
594CF46B238FF38E009B251B /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
59EB763123905F7300F5AE63 /* IJSVGText.m in Sources */,
59EB760223905F7300F5AE63 /* IJSVGCommandVerticalLine.m in Sources */,
59EB75FD23905F7300F5AE63 /* IJSVGPatternLayer.m in Sources */,
59EB763923905F7300F5AE63 /* IJSVGCommandSmoothQuadraticCurve.m in Sources */,
59EB75D823905F7300F5AE63 /* IJSVGStyleSheetRule.m in Sources */,
59EB75FB23905F7300F5AE63 /* IJSVGPath.m in Sources */,
59EB760123905F7300F5AE63 /* IJSVGLayerTree.m in Sources */,
59EB763A23905F7300F5AE63 /* IJSVGForeignObject.m in Sources */,
59EB761123905F7300F5AE63 /* IJSVGCommand.m in Sources */,
59EB760923905F7300F5AE63 /* IJSVGCommandCurve.m in Sources */,
59EB763323905F7300F5AE63 /* IJSVGLinearGradient.m in Sources */,
59EB761923905F7300F5AE63 /* IJSVGCommandSmoothCurve.m in Sources */,
59EB761323905F7300F5AE63 /* IJSVG.m in Sources */,
59EB763623905F7300F5AE63 /* IJSVGImageLayer.m in Sources */,
59EB75EC23905F7300F5AE63 /* IJSVGLayer.m in Sources */,
59EB75E523905F7300F5AE63 /* IJSVGStrokeLayer.m in Sources */,
59EB763223905F7300F5AE63 /* IJSVGView.m in Sources */,
59EB763523905F7300F5AE63 /* IJSVGStyleSheetSelector.m in Sources */,
59EB760723905F7300F5AE63 /* IJSVGNode.m in Sources */,
59EB75E923905F7300F5AE63 /* IJSVGStringAdditions.m in Sources */,
59EB761723905F7300F5AE63 /* IJSVGRadialGradient.m in Sources */,
59EB760423905F7300F5AE63 /* IJSVGCache.m in Sources */,
59EB75E223905F7300F5AE63 /* IJSVGColorList.m in Sources */,
59EB75ED23905F7300F5AE63 /* IJSVGFontConverter.m in Sources */,
59EB763C23905F7300F5AE63 /* IJSVGCommandEllipticalArc.m in Sources */,
59EB75E723905F7300F5AE63 /* IJSVGImage.m in Sources */,
59EB75FF23905F7300F5AE63 /* IJSVGBezierPathAdditions.m in Sources */,
59EB75E623905F7300F5AE63 /* IJSVGStyle.m in Sources */,
59EB75EB23905F7300F5AE63 /* IJSVGShapeLayer.m in Sources */,
59EB75F623905F7300F5AE63 /* IJSVGColor.m in Sources */,
59EB75F323905F7300F5AE63 /* IJSVGGroupLayer.m in Sources */,
59EB762523905F7300F5AE63 /* IJSVGTransform.m in Sources */,
59EB760023905F7300F5AE63 /* IJSVGGradientLayer.m in Sources */,
59EB762B23905F7300F5AE63 /* IJSVGUnitLength.m in Sources */,
59EB75F823905F7300F5AE63 /* IJSVGCommandHorizontalLine.m in Sources */,
59EB75FA23905F7300F5AE63 /* IJSVGWriter.m in Sources */,
59EB764623905F7300F5AE63 /* IJSVGRendering.m in Sources */,
59EB762E23905F7300F5AE63 /* IJSVGExporter.m in Sources */,
59EB761623905F7300F5AE63 /* IJSVGParser.m in Sources */,
59EB75DD23905F7300F5AE63 /* IJSVGCommandQuadraticCurve.m in Sources */,
59EB762423905F7300F5AE63 /* IJSVGTransaction.m in Sources */,
59EB75DA23905F7300F5AE63 /* IJSVGDef.m in Sources */,
59EB763723905F7300F5AE63 /* IJSVGCommandClose.m in Sources */,
59EB764323905F7300F5AE63 /* IJSVGGradient.m in Sources */,
59EB762A23905F7300F5AE63 /* IJSVGGradientUnitLength.m in Sources */,
59EB764223905F7300F5AE63 /* IJSVGStyleSheet.m in Sources */,
59EB764023905F7300F5AE63 /* IJSVGExporterPathInstruction.m in Sources */,
59EB75FE23905F7300F5AE63 /* IJSVGRenderingStyle.m in Sources */,
59EB75F223905F7300F5AE63 /* IJSVGStyleSheetSelectorRaw.m in Sources */,
59EB75EE23905F7300F5AE63 /* IJSVGImageRep.m in Sources */,
59EB762223905F7300F5AE63 /* IJSVGMath.m in Sources */,
59EB763D23905F7300F5AE63 /* IJSVGGroup.m in Sources */,
59EB761F23905F7300F5AE63 /* IJSVGCommandLineTo.m in Sources */,
59EB75F123905F7300F5AE63 /* IJSVGUtils.m in Sources */,
59EB760A23905F7300F5AE63 /* IJSVGCommandMove.m in Sources */,
59EB761B23905F7300F5AE63 /* IJSVGPattern.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
594CF475238FF38E009B251B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
594CF476238FF38E009B251B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
594CF478238FF38E009B251B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = NO;
CLANG_WARN_COMMA = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = NO;
DEVELOPMENT_TEAM = 9KTR4W9XX6;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = IJSVG/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 2.1;
PRODUCT_BUNDLE_IDENTIFIER = com.iconjar.ijsvg;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
};
name = Debug;
};
594CF479238FF38E009B251B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = NO;
CLANG_WARN_COMMA = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = NO;
DEVELOPMENT_TEAM = 9KTR4W9XX6;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = IJSVG/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 2.1;
PRODUCT_BUNDLE_IDENTIFIER = com.iconjar.ijsvg;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
594CF469238FF38E009B251B /* Build configuration list for PBXProject "IJSVG" */ = {
isa = XCConfigurationList;
buildConfigurations = (
594CF475238FF38E009B251B /* Debug */,
594CF476238FF38E009B251B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
594CF477238FF38E009B251B /* Build configuration list for PBXNativeTarget "IJSVG" */ = {
isa = XCConfigurationList;
buildConfigurations = (
594CF478238FF38E009B251B /* Debug */,
594CF479238FF38E009B251B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 594CF466238FF38E009B251B /* Project object */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:IJSVG.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1120"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "594CF46E238FF38E009B251B"
BuildableName = "IJSVG.framework"
BlueprintName = "IJSVG"
ReferencedContainer = "container:IJSVG.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "594CF46E238FF38E009B251B"
BuildableName = "IJSVG.framework"
BlueprintName = "IJSVG"
ReferencedContainer = "container:IJSVG.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>IJSVG.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>594CF46E238FF38E009B251B</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2019 Curtis Hard. All rights reserved.</string>
</dict>
</plist>
@@ -6,6 +6,7 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
@interface NSBezierPath (IJSVGAdditions)
@@ -15,9 +15,9 @@
{
CGPoint QP0 = [self currentPoint];
CGPoint CP3 = QP2;
CGPoint CP1 = CGPointMake( QP0.x + ((2.0 / 3.0) * (QP1.x - QP0.x)), QP0.y + ((2.0 / 3.0) * (QP1.y - QP0.y)));
CGPoint CP2 = CGPointMake( QP2.x + (2.0 / 3.0) * (QP1.x - QP2.x), QP2.y + (2.0 / 3.0) * (QP1.y - QP2.y) );
CGPoint CP1 = CGPointMake(QP0.x + ((2.0 / 3.0) * (QP1.x - QP0.x)), QP0.y + ((2.0 / 3.0) * (QP1.y - QP0.y)));
CGPoint CP2 = CGPointMake(QP2.x + (2.0 / 3.0) * (QP1.x - QP2.x), QP2.y + (2.0 / 3.0) * (QP1.y - QP2.y));
[self curveToPoint:CP3
controlPoint1:CP1
controlPoint2:CP2];
@@ -0,0 +1,18 @@
//
// IJSVGStringAdditions.h
// IconJar
//
// Created by Curtis Hard on 07/06/2019.
// Copyright © 2019 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSString (IJSVGAdditions)
- (NSArray<NSString *> *)ijsvg_componentsSeparatedByChars:(char *)aChar;
- (BOOL)ijsvg_isNumeric;
- (BOOL)ijsvg_containsAlpha;
- (NSArray*)ijsvg_componentsSplitByWhiteSpace;
@end
@@ -0,0 +1,91 @@
//
// IJSVGStringAdditions.m
// IconJar
//
// Created by Curtis Hard on 07/06/2019.
// Copyright © 2019 Curtis Hard. All rights reserved.
//
#import "IJSVGStringAdditions.h"
@implementation NSString (IJSVGAdditions)
- (NSArray<NSString*>*)ijsvg_componentsSeparatedByChars:(char*)aChar
{
NSMutableArray* comp = [[[NSMutableArray alloc] init] autorelease];
NSInteger length = self.length;
unichar* chars = (unichar*)calloc(sizeof(unichar), self.length);
NSInteger ind = 0;
BOOL startedString = NO;
// block for easy comparison
NSUInteger aLength = strlen(aChar);
BOOL (^charsContainsChar)(char anotherChar) = ^(char anotherChar) {
for (NSInteger i = 0; i < aLength; i++) {
if (aChar[i] == anotherChar) {
return YES;
}
}
return NO;
};
for (NSInteger i = 0; i < length; i++) {
// the char
unichar theChar = [self characterAtIndex:i];
// start the buffer
BOOL isEqualToChar = charsContainsChar(theChar);
if (isEqualToChar == NO) {
startedString = YES;
chars[ind++] = theChar;
}
// has started and char is the search char, or its at end
if ((startedString == YES && isEqualToChar) || (i == (length - 1) && startedString == YES)) {
startedString = NO;
// append the comp
[comp addObject:[NSString stringWithCharacters:chars length:ind]];
free(chars);
// restart and realloc the memory
ind = 0;
chars = (unichar*)calloc(sizeof(unichar), self.length);
}
}
free(chars);
return comp;
}
- (BOOL)ijsvg_containsAlpha
{
const char* buffer = self.UTF8String;
unsigned long length = strlen(buffer);
for (int i = 0; i < length; i++) {
if (isalpha(buffer[i])) {
return YES;
}
}
return NO;
}
- (BOOL)ijsvg_isNumeric
{
const char* buffer = self.UTF8String;
unsigned long length = strlen(buffer);
for (int i = 0; i < length; i++) {
if (!isnumber(buffer[i])) {
return NO;
}
}
return YES;
}
- (NSArray*)ijsvg_componentsSplitByWhiteSpace
{
return [self ijsvg_componentsSeparatedByChars:"\t\n\r "];
}
@end
@@ -6,9 +6,18 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
typedef NS_ENUM( NSInteger, IJSVGPredefinedColor ) {
typedef NS_OPTIONS(NSInteger, IJSVGColorStringOptions) {
IJSVGColorStringOptionNone = 1 << 0,
IJSVGColorStringOptionForceHEX = 1 << 1,
IJSVGColorStringOptionAllowShortHand = 1 << 2,
IJSVGColorStringOptionAllowRRGGBBAA = 1 << 3,
IJSVGColorStringOptionDefault = IJSVGColorStringOptionAllowShortHand
};
typedef NS_ENUM(NSInteger, IJSVGPredefinedColor) {
IJSVGColorAliceblue,
IJSVGColorAntiquewhite,
IJSVGColorAqua,
@@ -160,17 +169,29 @@ typedef NS_ENUM( NSInteger, IJSVGPredefinedColor ) {
@interface IJSVGColor : NSObject
+ (BOOL)isColor:(NSString *)string;
+ (NSString *)colorStringFromColor:(NSColor *)color
forceHex:(BOOL)forceHex;
+ (NSString *)colorStringFromColor:(NSColor *)color;
+ (NSColor *)computeColor:(id)colour;
+ (NSColor *)colorFromString:(NSString *)string;
+ (NSColor *)colorFromHEXString:(NSString *)string
alpha:(CGFloat)alpha;
+ (NSColor *)colorFromPredefinedColorName:(NSString *)name;
+ (NSString *)colorNameFromPredefinedColor:(IJSVGPredefinedColor)color;
+ (NSColor *)changeAlphaOnColor:(NSColor *)color
to:(CGFloat)alphaValue;
CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightness);
+ (NSColor*)computeColorSpace:(NSColor*)color;
+ (NSColorSpace*)defaultColorSpace;
+ (BOOL)isColor:(NSString*)string;
+ (NSString*)colorStringFromColor:(NSColor*)color
options:(IJSVGColorStringOptions)options;
+ (NSString*)colorStringFromColor:(NSColor*)color;
+ (NSColor*)colorFromHEXInteger:(NSInteger)hex;
+ (NSColor*)computeColor:(id)colour;
+ (NSColor*)colorFromString:(NSString*)string;
+ (NSColor*)colorFromHEXString:(NSString*)string;
+ (NSColor*)colorFromHEXString:(NSString*)string
containsAlphaComponent:(BOOL*)containsAlphaComponent;
+ (BOOL)HEXContainsAlphaComponent:(NSUInteger)hex;
+ (unsigned long)lengthOfHEXInteger:(NSUInteger)hex;
+ (NSColor*)colorFromRString:(NSString*)rString
gString:(NSString*)gString
bString:(NSString*)bString
aString:(NSString*)aString;
+ (NSColor*)colorFromPredefinedColorName:(NSString*)name;
+ (NSString*)colorNameFromPredefinedColor:(IJSVGPredefinedColor)color;
+ (NSColor*)changeAlphaOnColor:(NSColor*)color
to:(CGFloat)alphaValue;
@end
@@ -0,0 +1,791 @@
//
// IJSVGColor.m
// IconJar
//
// Created by Curtis Hard on 31/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGColor.h"
#import "IJSVGUtils.h"
@implementation IJSVGColor
static NSDictionary* _colorTree = nil;
CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightness)
{
hue *= (1.f / 360.f);
hue = (hue - floorf(hue));
saturation *= 0.01;
lightness *= 0.01;
lightness *= 2.f;
CGFloat s = saturation * ((lightness < 1.f) ? lightness : (2.f - lightness));
CGFloat brightness = (lightness + s) * .5f;
if (s != 0.f) {
s = (2.f * s) / (lightness + s);
}
CGFloat* floats = (CGFloat*)malloc(3 * sizeof(CGFloat));
floats[0] = hue;
floats[1] = s;
floats[2] = brightness;
return floats;
};
+ (void)load
{
[self.class _generateTree];
}
+ (NSColorSpace*)defaultColorSpace
{
return NSColorSpace.deviceRGBColorSpace;
}
+ (NSColor*)computeColorSpace:(NSColor*)color
{
NSColorSpace* space = [self defaultColorSpace];
if (color.colorSpace != space) {
color = [color colorUsingColorSpace:space];
}
return color;
}
+ (void)_generateTree
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_colorTree = [@{
@"aliceblue" : @(0xf0f8ff),
@"antiquewhite" : @(0xfaebd7),
@"aqua" : @(0x00ffff),
@"aquamarine" : @(0x7fffd4),
@"azure" : @(0xf0ffff),
@"beige" : @(0xf5f5dc),
@"bisque" : @(0xffe4c4),
@"black" : @(0x000000),
@"blanchedalmond" : @(0xffebcd),
@"blue" : @(0x0000ff),
@"blueviolet" : @(0x8a2be2),
@"brown" : @(0xa52a2a),
@"burlywood" : @(0xdeb887),
@"cadetblue" : @(0x5f9ea0),
@"chartreuse" : @(0x7fff00),
@"chocolate" : @(0xd2691e),
@"coral" : @(0xff7f50),
@"cornflowerblue" : @(0x6495ed),
@"cornsilk" : @(0xfff8dc),
@"crimson" : @(0xdc143c),
@"currentcolor" : @(0x000000),
@"cyan" : @(0x00ffff),
@"darkblue" : @(0x00008b),
@"darkcyan" : @(0x008b8b),
@"darkgoldenrod" : @(0xb8860b),
@"darkgray" : @(0xa9a9a9),
@"darkgreen" : @(0x006400),
@"darkgrey" : @(0xa9a9a9),
@"darkkhaki" : @(0xbdb76b),
@"darkmagenta" : @(0x8b008b),
@"darkolivegreen" : @(0x556b2f),
@"darkorange" : @(0xff8c00),
@"darkorchid" : @(0x9932cc),
@"darkred" : @(0x8b0000),
@"darksalmon" : @(0xe9967a),
@"darkseagreen" : @(0x8fbc8f),
@"darkslateblue" : @(0x483d8b),
@"darkslategray" : @(0x2f4f4f),
@"darkturquoise" : @(0x00ced1),
@"darkviolet" : @(0x9400d3),
@"deeppink" : @(0xff1493),
@"deepskyblue" : @(0x00bfff),
@"dimgray" : @(0x696969),
@"dimgrey" : @(0x696969),
@"dodgerblue" : @(0x1e90ff),
@"firebrick" : @(0xb22222),
@"floralwhite" : @(0xfffaf0),
@"forestgreen" : @(0x228b22),
@"fuchsia" : @(0xff00ff),
@"gainsboro" : @(0xdcdcdc),
@"ghostwhite" : @(0xf8f8ff),
@"gold" : @(0xffd700),
@"goldenrod" : @(0xdaa520),
@"gray" : @(0x808080),
@"green" : @(0x008000),
@"greenyellow" : @(0xadff2f),
@"grey" : @(0x808080),
@"honeydew" : @(0xf0fff0),
@"hotpink" : @(0xff69b4),
@"indianred" : @(0xcd5c5c),
@"indigo" : @(0x4b0082),
@"ivory" : @(0xfffff0),
@"khaki" : @(0xf0e68c),
@"lavender" : @(0xe6e6fa),
@"lavenderblush" : @(0xfff0f5),
@"lawngreen" : @(0x7cfc00),
@"lemonchiffon" : @(0xfffacd),
@"lightblue" : @(0xadd8e6),
@"lightcoral" : @(0xf08080),
@"lightcyan" : @(0xe0ffff),
@"lightgoldenrodyellow" : @(0xfafad2),
@"lightgray" : @(0xd3d3d3),
@"lightgreen" : @(0x90ee90),
@"lightgrey" : @(0xd3d3d3),
@"lightpink" : @(0xffb6c1),
@"lightsalmon" : @(0xffa07a),
@"lightseagreen" : @(0x20b2aa),
@"lightskyblue" : @(0x87cefa),
@"lightslategray" : @(0x778899),
@"lightsteelblue" : @(0xb0c4de),
@"lightyellow" : @(0xffffe0),
@"lime" : @(0x00ff00),
@"limegreen" : @(0x32cd32),
@"linen" : @(0xfaf0e6),
@"magenta" : @(0xff00ff),
@"maroon" : @(0x800000),
@"mediumaquamarine" : @(0x66cdaa),
@"mediumblue" : @(0x0000cd),
@"mediumorchid" : @(0xba55d3),
@"mediumpurple" : @(0x9370db),
@"mediumseagreen" : @(0x3cb371),
@"mediumslateblue" : @(0x7b68ee),
@"mediumspringgreen" : @(0x00fa9a),
@"mediumturquoise" : @(0x48d1cc),
@"mediumvioletred" : @(0xc71585),
@"midnightblue" : @(0x191970),
@"mintcream" : @(0xf5fffa),
@"mistyrose" : @(0xffe4e1),
@"moccasin" : @(0xffe4b5),
@"navajowhite" : @(0xffdead),
@"navy" : @(0x000080),
@"oldlace" : @(0xfdf5e6),
@"olive" : @(0x808000),
@"olivedrab" : @(0x6b8e23),
@"orange" : @(0xffa500),
@"orangered" : @(0xff4500),
@"orchid" : @(0xda70d6),
@"palegoldenrod" : @(0xeee8aa),
@"palegreen" : @(0x98fb98),
@"paleturquoise" : @(0xafeeee),
@"palevioletred" : @(0xdb7093),
@"papayawhip" : @(0xffefd5),
@"peachpuff" : @(0xffdab9),
@"peru" : @(0xcd853f),
@"pink" : @(0xffc0cb),
@"plum" : @(0xdda0dd),
@"powderblue" : @(0xb0e0e6),
@"purple" : @(0x800080),
@"red" : @(0xff0000),
@"rosybrown" : @(0xbc8f8f),
@"royalblue" : @(0x4169e1),
@"saddlebrown" : @(0x8b4513),
@"salmon" : @(0xfa8072),
@"sandybrown" : @(0xf4a460),
@"seagreen" : @(0x2e8b57),
@"seashell" : @(0xfff5ee),
@"sienna" : @(0xa0522d),
@"silver" : @(0xc0c0c0),
@"skyblue" : @(0x87ceeb),
@"slateblue" : @(0x6a5acd),
@"slategrey" : @(0x708090),
@"snow" : @(0xfffafa),
@"springgreen" : @(0x00ff7f),
@"steelblue" : @(0x4682b4),
@"tan" : @(0xd2b48c),
@"teal" : @(0x008080),
@"thistle" : @(0xd8bfd8),
@"tomato" : @(0xff6347),
@"turquoise" : @(0x40e0d0),
@"violet" : @(0xee82ee),
@"wheat" : @(0xf5deb3),
@"white" : @(0xffffff),
@"whitesmoke" : @(0xf5f5f5),
@"yellow" : @(0xffff00),
@"yellowgreen" : @(0x9acd32)
} retain];
});
}
+ (NSColor*)computeColor:(id)colour
{
if ([colour isKindOfClass:[NSColor class]])
return colour;
return nil;
}
+ (NSColor*)colorFromRString:(NSString*)rString
gString:(NSString*)gString
bString:(NSString*)bString
aString:(NSString*)aString
{
return [self colorFromRUnit:[IJSVGUnitLength unitWithString:rString]
gUnit:[IJSVGUnitLength unitWithString:gString]
bUnit:[IJSVGUnitLength unitWithString:bString]
aUnit:[IJSVGUnitLength unitWithString:aString]];
}
+ (NSColor*)colorFromRUnit:(IJSVGUnitLength*)rUnit
gUnit:(IJSVGUnitLength*)gUnit
bUnit:(IJSVGUnitLength*)bUnit
aUnit:(IJSVGUnitLength*)aUnit
{
CGFloat r = rUnit.type == IJSVGUnitLengthTypePercentage ? [rUnit computeValue:255.f] : [rUnit computeValue:1.f];
CGFloat g = gUnit.type == IJSVGUnitLengthTypePercentage ? [gUnit computeValue:255.f] : [gUnit computeValue:1.f];
CGFloat b = bUnit.type == IJSVGUnitLengthTypePercentage ? [bUnit computeValue:255.f] : [bUnit computeValue:1.f];
CGFloat a = [aUnit computeValue:100.f];
return [self computeColorSpace:[NSColor colorWithDeviceRed:(r / 255.f)
green:(g / 255.f)
blue:(b / 255.f)
alpha:a]];
}
+ (NSColor*)colorFromString:(NSString*)string
{
NSCharacterSet* set = NSCharacterSet.whitespaceAndNewlineCharacterSet;
string = [string stringByTrimmingCharactersInSet:set];
if ([string length] < 3) {
return nil;
}
NSColor* color = nil;
string = [string lowercaseString];
if ([self.class isHex:string] == NO) {
color = [self.class colorFromPredefinedColorName:string];
if (color != nil) {
return color;
}
}
// is simply a clear color, dont fill
if ([string.lowercaseString isEqualToString:@"none"] ||
[string.lowercaseString isEqualToString:@"transparent"]) {
return [self computeColorSpace:NSColor.clearColor];
}
// is it RGB?
if ([string hasPrefix:@"rgb"] == YES) {
NSRange range = [IJSVGUtils rangeOfParentheses:string];
NSString* rgbString = [string substringWithRange:range];
NSArray* parts = [rgbString ijsvg_componentsSeparatedByChars:","];
NSString* alpha = @"100%";
if (parts.count == 4) {
alpha = parts[3];
}
return [self colorFromRString:parts[0]
gString:parts[1]
bString:parts[2]
aString:alpha];
}
// is it HSL?
if ([string hasPrefix:@"hsl"]) {
NSInteger count = 0;
CGFloat* params = [IJSVGUtils commandParameters:string
count:&count];
CGFloat alpha = 1;
if (count == 4) {
alpha = params[3];
}
// convert HSL to HSB
CGFloat* hsb = IJSVGColorCSSHSLToHSB(params[0], params[1], params[2]);
color = [NSColor colorWithDeviceHue:hsb[0]
saturation:hsb[1]
brightness:hsb[2]
alpha:alpha];
color = [self computeColorSpace:color];
// memory clean!
free(hsb);
free(params);
return color;
}
color = [self.class colorFromHEXString:string];
return color;
}
+ (NSColor*)colorFromPredefinedColorName:(NSString*)name
{
NSNumber* hex = nil;
name = [name.lowercaseString stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
if ((hex = _colorTree[name]) == nil) {
return nil;
}
return [self.class colorFromHEXInteger:hex.integerValue];
}
+ (NSString*)colorStringFromColor:(NSColor*)color
{
IJSVGColorStringOptions options = IJSVGColorStringOptionDefault;
return [self colorStringFromColor:color
options:options];
}
+ (NSString*)colorStringFromColor:(NSColor*)color
options:(IJSVGColorStringOptions)options
{
// convert to RGB
color = [self computeColorSpace:color];
int red = color.redComponent * 0xFF;
int green = color.greenComponent * 0xFF;
int blue = color.blueComponent * 0xFF;
int alpha = (int)(color.alphaComponent * 100);
BOOL forceHex = (options & IJSVGColorStringOptionForceHEX) != 0;
BOOL allowShortHand = (options & IJSVGColorStringOptionAllowShortHand) != 0;
BOOL allowRRGGBBAA = (options & IJSVGColorStringOptionAllowRRGGBBAA) != 0;
// jsut return none
if (alpha == 0 && forceHex == NO) {
return @"none";
}
// always return hex unless criteria is met
if (forceHex == YES || allowRRGGBBAA == YES || alpha == 100 || (red == 0 && green == 0 && blue == 0 && alpha == 0) || (red == 255 && green == 255 && blue == 255 && alpha == 100)) {
// we need to make sure the last 2 chars
// are the same or we cant enable shorthand
if (allowRRGGBBAA == YES) {
NSString* alphaHexString = [NSString stringWithFormat:@"%02X",
(int)(color.alphaComponent * 0xFF)];
if ([alphaHexString characterAtIndex:0] !=
[alphaHexString characterAtIndex:1]) {
allowShortHand = NO;
}
}
if (allowShortHand == YES) {
NSString* r = [NSString stringWithFormat:@"%02X", red];
NSString* g = [NSString stringWithFormat:@"%02X", green];
NSString* b = [NSString stringWithFormat:@"%02X", blue];
if ([r characterAtIndex:0] == [r characterAtIndex:1] &&
[g characterAtIndex:0] == [g characterAtIndex:1] &&
[b characterAtIndex:0] == [b characterAtIndex:1]) {
// allow shorthand alpha
if (allowRRGGBBAA == YES && alpha != 100) {
NSString* a = [NSString stringWithFormat:@"%02X",
(int)(color.alphaComponent * 0xFF)];
return [NSString stringWithFormat:@"#%c%c%c%c",
[r characterAtIndex:0], [g characterAtIndex:0],
[b characterAtIndex:0], [a characterAtIndex:0]];
}
return [NSString stringWithFormat:@"#%c%c%c", [r characterAtIndex:0],
[g characterAtIndex:0], [b characterAtIndex:0]];
}
}
if (allowRRGGBBAA == YES && alpha != 100) {
return [NSString stringWithFormat:@"#%02X%02X%02X%02X", red, green,
blue, (int)(color.alphaComponent * 0xFF)];
}
return [NSString stringWithFormat:@"#%02X%02X%02X", red, green, blue];
}
// note the %g, CSS alpha is 0 to 1, not 0 - 100, my bad!
return [NSString stringWithFormat:@"rgba(%d,%d,%d,%g)", red, green, blue,
((float)alpha / 100.f)];
}
+ (NSString*)colorNameFromPredefinedColor:(IJSVGPredefinedColor)color
{
switch (color) {
case IJSVGColorAliceblue:
return @"aliceblue";
case IJSVGColorAntiquewhite:
return @"antiquewhite";
case IJSVGColorAqua:
return @"aqua";
case IJSVGColorAquamarine:
return @"aquamarine";
case IJSVGColorAzure:
return @"azure";
case IJSVGColorBeige:
return @"beige";
case IJSVGColorBisque:
return @"bisque";
case IJSVGColorBlack:
return @"black";
case IJSVGColorBlanchedalmond:
return @"blanchedalmond";
case IJSVGColorBlue:
return @"blue";
case IJSVGColorBlueviolet:
return @"blueviolet";
case IJSVGColorBrown:
return @"brown";
case IJSVGColorBurlywood:
return @"burlywood";
case IJSVGColorCadetblue:
return @"cadetblue";
case IJSVGColorChartreuse:
return @"chartreuse";
case IJSVGColorChocolate:
return @"chocolate";
case IJSVGColorCoral:
return @"coral";
case IJSVGColorCornflowerblue:
return @"cornflowerblue";
case IJSVGColorCornsilk:
return @"cornsilk";
case IJSVGColorCrimson:
return @"crimson";
case IJSVGColorCyan:
return @"cyan";
case IJSVGColorDarkblue:
return @"darkblue";
case IJSVGColorDarkcyan:
return @"darkcyan";
case IJSVGColorDarkgoldenrod:
return @"darkgoldenrod";
case IJSVGColorDarkgray:
return @"darkgray";
case IJSVGColorDarkgreen:
return @"darkgreen";
case IJSVGColorDarkgrey:
return @"darkgrey";
case IJSVGColorDarkkhaki:
return @"darkkhaki";
case IJSVGColorDarkmagenta:
return @"darkmagenta";
case IJSVGColorDarkolivegreen:
return @"darkolivegreen";
case IJSVGColorDarkorange:
return @"darkorange";
case IJSVGColorDarkorchid:
return @"darkorchid";
case IJSVGColorDarkred:
return @"darkred";
case IJSVGColorDarksalmon:
return @"darksalmon";
case IJSVGColorDarkseagreen:
return @"darkseagreen";
case IJSVGColorDarkslateblue:
return @"darkslateblue";
case IJSVGColorDarkslategray:
return @"darkslategray";
case IJSVGColorDarkslategrey:
return @"darkslategrey";
case IJSVGColorDarkturquoise:
return @"darkturquoise";
case IJSVGColorDarkviolet:
return @"darkviolet";
case IJSVGColorDeeppink:
return @"deeppink";
case IJSVGColorDeepskyblue:
return @"deepskyblue";
case IJSVGColorDimgray:
return @"dimgray";
case IJSVGColorDimgrey:
return @"dimgrey";
case IJSVGColorDodgerblue:
return @"dodgerblue";
case IJSVGColorFirebrick:
return @"firebrick";
case IJSVGColorFloralwhite:
return @"floralwhite";
case IJSVGColorForestgreen:
return @"forestgreen";
case IJSVGColorFuchsia:
return @"fuchsia";
case IJSVGColorGainsboro:
return @"gainsboro";
case IJSVGColorGhostwhite:
return @"ghostwhite";
case IJSVGColorGold:
return @"gold";
case IJSVGColorGoldenrod:
return @"goldenrod";
case IJSVGColorGray:
return @"gray";
case IJSVGColorGreen:
return @"green";
case IJSVGColorGreenyellow:
return @"greenyellow";
case IJSVGColorGrey:
return @"grey";
case IJSVGColorHoneydew:
return @"honeydew";
case IJSVGColorHotpink:
return @"hotpink";
case IJSVGColorIndianred:
return @"indianred";
case IJSVGColorIndigo:
return @"indigo";
case IJSVGColorIvory:
return @"ivory";
case IJSVGColorKhaki:
return @"khaki";
case IJSVGColorLavender:
return @"lavender";
case IJSVGColorLavenderblush:
return @"lavenderblush";
case IJSVGColorLawngreen:
return @"lawngreen";
case IJSVGColorLemonchiffon:
return @"lemonchiffon";
case IJSVGColorLightblue:
return @"lightblue";
case IJSVGColorLightcoral:
return @"lightcoral";
case IJSVGColorLightcyan:
return @"lightcyan";
case IJSVGColorLightgoldenrodyellow:
return @"lightgoldenrodyellow";
case IJSVGColorLightgray:
return @"lightgray";
case IJSVGColorLightgreen:
return @"lightgreen";
case IJSVGColorLightgrey:
return @"lightgrey";
case IJSVGColorLightpink:
return @"lightpink";
case IJSVGColorLightsalmon:
return @"lightsalmon";
case IJSVGColorLightseagreen:
return @"lightseagreen";
case IJSVGColorLightskyblue:
return @"lightskyblue";
case IJSVGColorLightslategray:
return @"lightslategray";
case IJSVGColorLightslategrey:
return @"lightslategrey";
case IJSVGColorLightsteelblue:
return @"lightsteelblue";
case IJSVGColorLightyellow:
return @"lightyellow";
case IJSVGColorLime:
return @"lime";
case IJSVGColorLimegreen:
return @"limegreen";
case IJSVGColorLinen:
return @"linen";
case IJSVGColorMagenta:
return @"magenta";
case IJSVGColorMaroon:
return @"maroon";
case IJSVGColorMediumaquamarine:
return @"mediumaquamarine";
case IJSVGColorMediumblue:
return @"mediumblue";
case IJSVGColorMediumorchid:
return @"mediumorchid";
case IJSVGColorMediumpurple:
return @"mediumpurple";
case IJSVGColorMediumseagreen:
return @"mediumseagreen";
case IJSVGColorMediumslateblue:
return @"mediumslateblue";
case IJSVGColorMediumspringgreen:
return @"mediumspringgreen";
case IJSVGColorMediumturquoise:
return @"mediumturquoise";
case IJSVGColorMediumvioletred:
return @"mediumvioletred";
case IJSVGColorMidnightblue:
return @"midnightblue";
case IJSVGColorMintcream:
return @"mintcream";
case IJSVGColorMistyrose:
return @"mistyrose";
case IJSVGColorMoccasin:
return @"moccasin";
case IJSVGColorNavajowhite:
return @"navajowhite";
case IJSVGColorNavy:
return @"navy";
case IJSVGColorOldlace:
return @"oldlace";
case IJSVGColorOlive:
return @"olive";
case IJSVGColorOlivedrab:
return @"olivedrab";
case IJSVGColorOrange:
return @"orange";
case IJSVGColorOrangered:
return @"orangered";
case IJSVGColorOrchid:
return @"orchid";
case IJSVGColorPalegoldenrod:
return @"palegoldenrod";
case IJSVGColorPalegreen:
return @"palegreen";
case IJSVGColorPaleturquoise:
return @"paleturquoise";
case IJSVGColorPalevioletred:
return @"palevioletred";
case IJSVGColorPapayawhip:
return @"papayawhip";
case IJSVGColorPeachpuff:
return @"peachpuff";
case IJSVGColorPeru:
return @"peru";
case IJSVGColorPink:
return @"pink";
case IJSVGColorPlum:
return @"plum";
case IJSVGColorPowderblue:
return @"powderblue";
case IJSVGColorPurple:
return @"purple";
case IJSVGColorRed:
return @"red";
case IJSVGColorRosybrown:
return @"rosybrown";
case IJSVGColorRoyalblue:
return @"royalblue";
case IJSVGColorSaddlebrown:
return @"saddlebrown";
case IJSVGColorSalmon:
return @"salmon";
case IJSVGColorSandybrown:
return @"sandybrown";
case IJSVGColorSeagreen:
return @"seagreen";
case IJSVGColorSeashell:
return @"seashell";
case IJSVGColorSienna:
return @"sienna";
case IJSVGColorSilver:
return @"silver";
case IJSVGColorSkyblue:
return @"skyblue";
case IJSVGColorSlateblue:
return @"slateblue";
case IJSVGColorSlategray:
return @"slategray";
case IJSVGColorSlategrey:
return @"slategrey";
case IJSVGColorSnow:
return @"snow";
case IJSVGColorSpringgreen:
return @"springgreen";
case IJSVGColorSteelblue:
return @"steelblue";
case IJSVGColorTan:
return @"tan";
case IJSVGColorTeal:
return @"teal";
case IJSVGColorThistle:
return @"thistle";
case IJSVGColorTomato:
return @"tomato";
case IJSVGColorTurquoise:
return @"turquoise";
case IJSVGColorViolet:
return @"violet";
case IJSVGColorWheat:
return @"wheat";
case IJSVGColorWhite:
return @"white";
case IJSVGColorWhitesmoke:
return @"whitesmoke";
case IJSVGColorYellow:
return @"yellow";
case IJSVGColorYellowgreen:
return @"yellowgreen";
}
return nil;
}
+ (NSColor*)changeAlphaOnColor:(NSColor*)color
to:(CGFloat)alphaValue
{
color = [self computeColorSpace:color];
return [self computeColorSpace:[NSColor colorWithDeviceRed:color.redComponent
green:color.greenComponent
blue:color.blueComponent
alpha:alphaValue]];
}
+ (BOOL)isColor:(NSString*)string
{
return [string hasPrefix:@"#"] || [string hasPrefix:@"rgb"];
}
+ (BOOL)isHex:(NSString*)string
{
const char* validList = "0123456789ABCDEFabcdef#";
for (NSInteger i = 0; i < string.length; i++) {
char c = [string characterAtIndex:i];
if (strchr(validList, c) == NULL) {
return NO;
}
}
return YES;
}
+ (unsigned long)lengthOfHEXInteger:(NSUInteger)hex
{
char* buffer;
asprintf(&buffer, "%lX", (long)hex);
unsigned long length = strlen(buffer);
free(buffer);
return length;
}
+ (BOOL)HEXContainsAlphaComponent:(NSUInteger)hex
{
return [self lengthOfHEXInteger:hex] == 8;
}
+ (NSColor*)colorFromHEXInteger:(NSInteger)hex
{
CGFloat alpha = 1.f;
if ([self HEXContainsAlphaComponent:hex] == YES) {
alpha = (hex & 0xFF) / 255.f;
hex = hex >> 8;
}
return [self computeColorSpace:[NSColor colorWithDeviceRed:((hex >> 16) & 0xFF) / 255.f
green:((hex >> 8) & 0xFF) / 255.f
blue:(hex & 0xFF) / 255.f
alpha:alpha]];
}
+ (unsigned long)HEXFromArbitraryHexString:(NSString*)aString
{
const char* hexString = [aString cStringUsingEncoding:NSUTF8StringEncoding];
return strtoul(hexString, NULL, 16);
}
+ (NSColor*)colorFromHEXString:(NSString*)string
{
return [self colorFromHEXString:string
containsAlphaComponent:nil];
}
+ (NSColor*)colorFromHEXString:(NSString*)string
containsAlphaComponent:(BOOL*)containsAlphaComponent
{
// absolutely no string
if (string == nil || string.length == 0 || ![self.class isHex:string]) {
return nil;
}
if ([string hasPrefix:@"#"] == YES) {
string = [string substringFromIndex:1];
}
// whats the length?
NSUInteger length = string.length;
if (length == 3 || length == 4) {
// shorthand...
NSMutableString* str = [[[NSMutableString alloc] init] autorelease];
for (NSInteger i = 0; i < length; i++) {
NSString* sub = [string substringWithRange:NSMakeRange(i, 1)];
[str appendFormat:@"%@%@", sub, sub];
}
string = str;
}
// now convert rest to hex
unsigned long hex = [self HEXFromArbitraryHexString:string];
if (containsAlphaComponent != nil) {
*containsAlphaComponent = [self HEXContainsAlphaComponent:hex];
}
return [self colorFromHEXInteger:hex];
}
@end
@@ -0,0 +1,31 @@
//
// IJSVGColorList.h
// IconJar
//
// Created by Curtis Hard on 07/07/2019.
// Copyright © 2019 Curtis Hard. All rights reserved.
//
#import "IJSVGColor.h"
#import <Foundation/Foundation.h>
@interface IJSVGColorList : NSObject <NSCopying> {
@private
NSMutableDictionary<NSColor*, NSColor*>* _replacementColorTree;
NSMutableSet<NSColor*>* _colors;
}
- (NSColor*)proposedColorForColor:(NSColor*)color;
- (void)removeAllReplacementColors;
- (void)removeReplacementColor:(NSColor*)color;
- (void)setReplacementColor:(NSColor*)newColor
forColor:(NSColor*)color;
- (void)setReplacementColors:(NSDictionary<NSColor*, NSColor*>*)colors
clearExistingColors:(BOOL)clearExistingColors;
- (void)addColorsFromList:(IJSVGColorList*)sheet;
- (NSSet<NSColor*>*)colors;
- (void)addColor:(NSColor*)color;
@end
@@ -0,0 +1,112 @@
//
// IJSVGColorList.m
// IconJar
//
// Created by Curtis Hard on 07/07/2019.
// Copyright © 2019 Curtis Hard. All rights reserved.
//
#import "IJSVGColorList.h"
@implementation IJSVGColorList
- (void)dealloc
{
(void)([_replacementColorTree release]), _replacementColorTree = nil;
(void)([_colors release]), _colors = nil;
[super dealloc];
}
- (instancetype)init
{
if ((self = [super init]) != nil) {
_replacementColorTree = [[NSMutableDictionary alloc] init];
_colors = [[NSMutableSet alloc] init];
}
return self;
}
- (id)copyWithZone:(NSZone*)zone
{
IJSVGColorList* sheet = [[self.class alloc] init];
[sheet setReplacementColors:[_replacementColorTree.copy autorelease]
clearExistingColors:YES];
return sheet;
}
- (NSColor*)proposedColorForColor:(NSColor*)color
{
// nothing found, just return color
if (_replacementColorTree == nil || _replacementColorTree.count == 0) {
return color;
}
// check the mappings
NSColor* found = nil;
color = [IJSVGColor computeColorSpace:color];
if ((found = _replacementColorTree[color]) != nil) {
return found;
}
return color;
}
- (void)_invalidateColorTree
{
(void)([_replacementColorTree release]), _replacementColorTree = nil;
_replacementColorTree = [[NSMutableDictionary alloc] init];
}
- (void)removeAllReplacementColors
{
[self _invalidateColorTree];
}
- (void)removeReplacementColor:(NSColor*)color
{
if (_replacementColorTree == nil) {
return;
}
[_replacementColorTree removeObjectForKey:[IJSVGColor computeColorSpace:color]];
}
- (void)setReplacementColor:(NSColor*)newColor
forColor:(NSColor*)color
{
color = [IJSVGColor computeColorSpace:color];
newColor = [IJSVGColor computeColorSpace:newColor];
_replacementColorTree[color] = newColor;
}
- (void)setReplacementColors:(NSDictionary<NSColor*, NSColor*>*)colors
clearExistingColors:(BOOL)clearExistingColors
{
if (clearExistingColors == YES) {
[self _invalidateColorTree];
}
for (NSColor* oldColor in colors) {
[self setReplacementColor:colors[oldColor]
forColor:oldColor];
}
}
- (NSSet<NSColor*>*)colors
{
return [NSSet setWithSet:_colors];
}
- (void)addColorsFromList:(IJSVGColorList*)sheet
{
[_colors addObjectsFromArray:sheet.colors.allObjects];
}
- (void)addColor:(NSColor*)color
{
[_colors addObject:[IJSVGColor computeColorSpace:color]];
}
- (void)removeColor:(NSColor*)color
{
[_colors removeObject:[IJSVGColor computeColorSpace:color]];
}
@end
@@ -0,0 +1,72 @@
//
// IJSVGCommand.h
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGPath.h"
#import <Foundation/Foundation.h>
static const NSInteger IJSVGCustomVariableParameterCount = NSNotFound;
typedef NS_ENUM(NSInteger, IJSVGCommandType) {
kIJSVGCommandTypeAbsolute,
kIJSVGCommandTypeRelative
};
typedef NS_ENUM(NSUInteger, IJSVGPathDataSequence) {
kIJSVGPathDataSequenceTypeFloat,
kIJSVGPathDataSequenceTypeFlag
};
@interface IJSVGCommand : NSObject {
NSString* commandString;
NSString* command;
CGFloat* parameters;
NSInteger parameterCount;
NSArray<IJSVGCommand*>* subCommands;
NSInteger requiredParameters;
IJSVGCommandType type;
IJSVGCommand* previousCommand;
NSInteger _currentIndex;
BOOL isSubCommand;
}
@property (nonatomic, copy) NSString* commandString;
@property (nonatomic, copy) NSString* command;
@property (nonatomic, assign) CGFloat* parameters;
@property (nonatomic, assign) NSInteger parameterCount;
@property (nonatomic, assign) NSInteger requiredParameters;
@property (nonatomic, assign) IJSVGCommandType type;
@property (nonatomic, retain) NSArray<IJSVGCommand*>* subCommands;
@property (nonatomic, assign) IJSVGCommand* previousCommand;
@property (nonatomic, assign) BOOL isSubCommand;
+ (Class)commandClassForCommandChar:(char)aChar;
+ (NSInteger)requiredParameterCount;
+ (NSPoint)readCoordinatePair:(CGFloat*)pairs
index:(NSInteger)index;
+ (IJSVGPathDataSequence*)pathDataSequence;
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath*)path;
+ (void)parseParams:(CGFloat*)params
paramCount:(NSInteger)paramCount
intoArray:(NSMutableArray<IJSVGCommand*>*)commands
parentCommand:(IJSVGCommand*)parentCommand;
- (id)initWithCommandString:(NSString*)commandString;
- (IJSVGCommand*)subcommandWithParameters:(CGFloat*)subParams
previousCommand:(IJSVGCommand*)command;
- (CGFloat)readFloat;
- (NSPoint)readPoint;
- (BOOL)readBOOL;
- (void)resetRead;
@end
@@ -0,0 +1,212 @@
//
// IJSVGCommand.m
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommand.h"
#import "IJSVGUtils.h"
#import "IJSVGCommandClose.h"
#import "IJSVGCommandCurve.h"
#import "IJSVGCommandEllipticalArc.h"
#import "IJSVGCommandHorizontalLine.h"
#import "IJSVGCommandLineTo.h"
#import "IJSVGCommandMove.h"
#import "IJSVGCommandQuadraticCurve.h"
#import "IJSVGCommandSmoothCurve.h"
#import "IJSVGCommandSmoothQuadraticCurve.h"
#import "IJSVGCommandVerticalLine.h"
@implementation IJSVGCommand
@synthesize commandString;
@synthesize command;
@synthesize parameterCount;
@synthesize parameters;
@synthesize subCommands;
@synthesize requiredParameters;
@synthesize type;
@synthesize previousCommand;
@synthesize isSubCommand;
+ (BOOL)requiresCustomParameterParsing
{
return NO;
}
+ (NSInteger)requiredParameterCount
{
return 1;
}
+ (IJSVGPathDataSequence*)pathDataSequence
{
return NULL;
}
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
}
+ (void)parseParams:(CGFloat*)params
paramCount:(NSInteger)paramCount
intoArray:(NSMutableArray<IJSVGCommand*>*)commands
parentCommand:(IJSVGCommand*)parentCommand
{
}
+ (NSPoint)readCoordinatePair:(CGFloat*)pairs
index:(NSInteger)index
{
return NSMakePoint(pairs[index * 2], pairs[index * 2 + 1]);
}
+ (void)load
{
// register here...
}
+ (Class)commandClassForCommandChar:(char)aChar
{
aChar = tolower(aChar);
switch (aChar) {
case 'a':
return IJSVGCommandEllipticalArc.class;
case 'c':
return IJSVGCommandCurve.class;
case 'h':
return IJSVGCommandHorizontalLine.class;
case 'l':
return IJSVGCommandLineTo.class;
case 'm':
return IJSVGCommandMove.class;
case 'q':
return IJSVGCommandQuadraticCurve.class;
case 's':
return IJSVGCommandSmoothCurve.class;
case 't':
return IJSVGCommandSmoothQuadraticCurve.class;
case 'v':
return IJSVGCommandVerticalLine.class;
case 'z':
return IJSVGCommandClose.class;
}
return nil;
}
- (void)dealloc
{
(void)([commandString release]), commandString = nil;
(void)([command release]), command = nil;
(void)([subCommands release]), subCommands = nil;
if (parameters) {
(void)(free(parameters)), parameters = nil;
}
[super dealloc];
}
- (id)initWithCommandString:(NSString*)str
{
if ((self = [super init]) != nil) {
// work out the basics
_currentIndex = 0;
command = [[str substringToIndex:1] copy];
type = [IJSVGUtils typeForCommandString:self.command];
requiredParameters = [self.class requiredParameterCount];
NSInteger sets = 0;
IJSVGPathDataSequence* sequence = [self.class pathDataSequence];
parameters = IJSVGParsePathDataSequence(str, sequence, requiredParameters, &sets);
if (sets <= 1) {
CGFloat* subParams = [self parametersFromIndexOffset:0];
IJSVGCommand* command = [self subcommandWithParameters:subParams
previousCommand:nil];
subCommands = @[ command ].retain;
} else {
NSMutableArray<IJSVGCommand*>* subCommandArray = nil;
subCommandArray = [[NSMutableArray alloc] initWithCapacity:sets].autorelease;
// interate over the sets
IJSVGCommand* lastCommand = nil;
for (NSInteger i = 0; i < sets; i++) {
// memory for this will be handled by the created subcommand
CGFloat* subParams = [self parametersFromIndexOffset:i];
// generate the subcommand
IJSVGCommand* command = [self subcommandWithParameters:subParams
previousCommand:lastCommand];
// make sure we assign the last command or hell breaks
// lose and the firey demons will run wild, namely, commands will break
// if they are multiples of a set
lastCommand = command;
[subCommandArray addObject:command];
}
// store the retained value
subCommands = subCommandArray.copy;
}
}
return self;
}
- (CGFloat*)parametersFromIndexOffset:(NSInteger)index
{
CGFloat* subParams = 0;
NSInteger req = self.requiredParameters;
if (req != 0) {
subParams = (CGFloat*)malloc(req * sizeof(CGFloat));
memcpy(subParams, &self.parameters[index * req], sizeof(CGFloat) * req);
}
return subParams;
}
- (IJSVGCommand*)subcommandWithParameters:(CGFloat*)subParams
previousCommand:(IJSVGCommand*)aPreviousCommand
{
// create a subcommand per set
IJSVGCommand* c = [[[self.class alloc] init] autorelease];
c.parameterCount = self.requiredParameters;
c.parameters = subParams;
c.type = self.type;
c.command = self.command;
c.previousCommand = aPreviousCommand;
c.isSubCommand = aPreviousCommand != nil;
return c;
}
- (CGFloat)readFloat
{
CGFloat f = parameters[_currentIndex];
_currentIndex++;
return f;
}
- (NSPoint)readPoint
{
CGFloat x = parameters[_currentIndex];
CGFloat y = parameters[_currentIndex + 1];
_currentIndex += 2;
return NSMakePoint(x, y);
}
- (BOOL)readBOOL
{
return [self readFloat] == 1;
}
- (void)resetRead
{
_currentIndex = 0;
}
@end
@@ -6,9 +6,9 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
#import <Foundation/Foundation.h>
@interface IJSVGCommandClose : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandClose : IJSVGCommand
@end
@@ -10,23 +10,17 @@
@implementation IJSVGCommandClose
+ (void)load
{
[IJSVGCommand registerClass:[self class]
forCommand:@"z"];
}
+ (NSInteger)requiredParameterCount
{
return 0;
}
+ (void)runWithParams:(CGFloat *)params
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand *)currentCommand
previousCommand:(IJSVGCommand *)command
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath *)path
path:(IJSVGPath*)path
{
[path close];
}
@@ -6,9 +6,9 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
#import <Foundation/Foundation.h>
@interface IJSVGCommandCurve : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandCurve : IJSVGCommand
@end
@@ -0,0 +1,36 @@
//
// IJSVGCommandCurve.m
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandCurve.h"
@implementation IJSVGCommandCurve
+ (NSInteger)requiredParameterCount
{
return 6;
}
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
if (type == kIJSVGCommandTypeAbsolute) {
[[path currentSubpath] curveToPoint:NSMakePoint(params[4], params[5])
controlPoint1:NSMakePoint(params[0], params[1])
controlPoint2:NSMakePoint(params[2], params[3])];
return;
}
[[path currentSubpath] relativeCurveToPoint:NSMakePoint(params[4], params[5])
controlPoint1:NSMakePoint(params[0], params[1])
controlPoint2:NSMakePoint(params[2], params[3])];
}
@end
@@ -6,9 +6,9 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
#import <Foundation/Foundation.h>
@interface IJSVGCommandArc : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandEllipticalArc : IJSVGCommand
@end
@@ -6,97 +6,119 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandArc.h"
#import "IJSVGCommandEllipticalArc.h"
#import "IJSVGUtils.h"
@implementation IJSVGCommandArc
@implementation IJSVGCommandEllipticalArc
+ (void)load
{
[IJSVGCommand registerClass:[self class]
forCommand:@"a"];
}
static IJSVGPathDataSequence* _sequence;
+ (NSInteger)requiredParameterCount
{
return 7;
}
+ (void)runWithParams:(CGFloat *)params
paramCount:(NSInteger)count
command:(IJSVGCommand *)currentCommand
previousCommand:(IJSVGCommand *)command
type:(IJSVGCommandType)type
path:(IJSVGPath *)path
+ (IJSVGPathDataSequence*)pathDataSequence
{
if(_sequence == NULL) {
_sequence = (IJSVGPathDataSequence*)malloc(sizeof(IJSVGPathDataSequence) * 7);
_sequence[0] = kIJSVGPathDataSequenceTypeFloat;
_sequence[1] = kIJSVGPathDataSequenceTypeFloat;
_sequence[2] = kIJSVGPathDataSequenceTypeFloat;
_sequence[3] = kIJSVGPathDataSequenceTypeFlag;
_sequence[4] = kIJSVGPathDataSequenceTypeFlag;
_sequence[5] = kIJSVGPathDataSequenceTypeFloat;
_sequence[6] = kIJSVGPathDataSequenceTypeFloat;
}
return _sequence;
}
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
// command was taken from: https://github.com/jmenter/JAMSVGImage/blob/89b375c0c3203355a0c693e3b805458415bf4e29/Classes/JAMSVGImage/Path%20and%20Parser/JAMStyledBezierPathFactory.m
// and modified to purpose inside this to be converted into degrees and not radians
CGPoint radii = CGPointZero;
CGPoint arcEndPoint = CGPointZero;
CGPoint arcStartPoint = path.currentPoint;
CGFloat xAxisRotation = 0;
BOOL largeArcFlag = 0;
BOOL sweepFlag = 0;
radii = [currentCommand readPoint];
xAxisRotation = [currentCommand readFloat];
largeArcFlag = [currentCommand readBOOL];
sweepFlag = [currentCommand readBOOL];
arcEndPoint = [currentCommand readPoint];
if ( type == IJSVGCommandTypeRelative ) {
if (type == kIJSVGCommandTypeRelative) {
arcEndPoint.x += path.currentPoint.x;
arcEndPoint.y += path.currentPoint.y;
}
xAxisRotation *= M_PI / 180.f;
CGPoint currentPoint = CGPointMake(cos(xAxisRotation) * (arcStartPoint.x - arcEndPoint.x) / 2.0 + sin(xAxisRotation) * (arcStartPoint.y - arcEndPoint.y) / 2.0, -sin(xAxisRotation) * (arcStartPoint.x - arcEndPoint.x) / 2.0 + cos(xAxisRotation) * (arcStartPoint.y - arcEndPoint.y) / 2.0);
CGFloat radiiAdjustment = pow(currentPoint.x, 2) / pow(radii.x, 2) + pow(currentPoint.y, 2) / pow(radii.y, 2);
radii.x *= (radiiAdjustment > 1) ? sqrt(radiiAdjustment) : 1;
radii.y *= (radiiAdjustment > 1) ? sqrt(radiiAdjustment) : 1;
CGFloat sweep = (largeArcFlag == sweepFlag ? -1 : 1) * sqrt(((pow(radii.x, 2) * pow(radii.y, 2)) - (pow(radii.x, 2) * pow(currentPoint.y, 2)) - (pow(radii.y, 2) * pow(currentPoint.x, 2))) / (pow(radii.x, 2) * pow(currentPoint.y, 2) + pow(radii.y, 2) * pow(currentPoint.x, 2)));
sweep = (sweep != sweep) ? 0 : sweep;
CGPoint preCenterPoint = CGPointMake(sweep * radii.x * currentPoint.y / radii.y, sweep * -radii.y * currentPoint.x / radii.x);
CGPoint centerPoint = CGPointMake((arcStartPoint.x + arcEndPoint.x) / 2.0 + cos(xAxisRotation) * preCenterPoint.x - sin(xAxisRotation) * preCenterPoint.y, (arcStartPoint.y + arcEndPoint.y) / 2.0 + sin(xAxisRotation) * preCenterPoint.x + cos(xAxisRotation) * preCenterPoint.y);
CGFloat startAngle = angle(CGPointMake(1, 0), CGPointMake((currentPoint.x-preCenterPoint.x)/radii.x,
(currentPoint.y-preCenterPoint.y)/radii.y));
CGFloat startAngle = angle(CGPointMake(1, 0), CGPointMake((currentPoint.x - preCenterPoint.x) / radii.x, (currentPoint.y - preCenterPoint.y) / radii.y));
CGPoint deltaU = CGPointMake((currentPoint.x - preCenterPoint.x) / radii.x,
(currentPoint.y - preCenterPoint.y) / radii.y);
(currentPoint.y - preCenterPoint.y) / radii.y);
CGPoint deltaV = CGPointMake((-currentPoint.x - preCenterPoint.x) / radii.x,
(-currentPoint.y - preCenterPoint.y) / radii.y);
(-currentPoint.y - preCenterPoint.y) / radii.y);
CGFloat angleDelta = (deltaU.x * deltaV.y < deltaU.y * deltaV.x ? -1 : 1) * acos(ratio(deltaU, deltaV));
angleDelta = (ratio(deltaU, deltaV) <= -1) ? M_PI : (ratio(deltaU, deltaV) >= 1) ? 0 : angleDelta;
// check for actually numbers, if this is not valid
// kill it, blame WWDC 2017 SVG background for this...
if (isnan(startAngle) || isnan(angleDelta)) {
return;
}
CGFloat radius = MAX(radii.x, radii.y);
CGPoint scale = (radii.x > radii.y) ? CGPointMake(1, radii.y / radii.x) : CGPointMake(radii.x / radii.y, 1);
NSAffineTransform * trans = [NSAffineTransform transform];
NSAffineTransform* trans = NSAffineTransform.transform;
[trans translateXBy:-centerPoint.x yBy:-centerPoint.y];
[trans rotateByRadians:-xAxisRotation];
[trans scaleXBy:(1/scale.x) yBy:(1/scale.y)];
[path.currentSubpath transformUsingAffineTransform:trans];
trans = NSAffineTransform.transform;
[trans rotateByRadians:-xAxisRotation];
[path.currentSubpath transformUsingAffineTransform:trans];
trans = NSAffineTransform.transform;
[trans scaleXBy:(1 / scale.x) yBy:(1 / scale.y)];
[path.currentSubpath transformUsingAffineTransform:trans];
[path.currentSubpath appendBezierPathWithArcWithCenter:NSZeroPoint
radius:radius
startAngle:radians_to_degrees(startAngle)
endAngle:radians_to_degrees(startAngle + angleDelta)
clockwise:!sweepFlag];
trans = [NSAffineTransform transform];
[trans translateXBy:centerPoint.x yBy:centerPoint.y];
[trans rotateByRadians:xAxisRotation];
trans = NSAffineTransform.transform;
[trans scaleXBy:scale.x yBy:scale.y];
[path.currentSubpath transformUsingAffineTransform:trans];
trans = NSAffineTransform.transform;
[trans rotateByRadians:xAxisRotation];
[path.currentSubpath transformUsingAffineTransform:trans];
trans = NSAffineTransform.transform;
[trans translateXBy:centerPoint.x yBy:centerPoint.y];
[path.currentSubpath transformUsingAffineTransform:trans];
}
@end
@@ -6,9 +6,9 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
#import <Foundation/Foundation.h>
@interface IJSVGCommandHorizontalLine : NSObject <IJSVGCommandProtocol>
@interface IJSVGCommandHorizontalLine : IJSVGCommand
@end
@@ -0,0 +1,32 @@
//
// IJSVGCommandHorizontalLine.m
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandHorizontalLine.h"
@implementation IJSVGCommandHorizontalLine
+ (NSInteger)requiredParameterCount
{
return 1;
}
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
if (type == kIJSVGCommandTypeAbsolute) {
[[path currentSubpath] lineToPoint:NSMakePoint(params[0], [path currentSubpath].currentPoint.y)];
return;
}
[[path currentSubpath] relativeLineToPoint:NSMakePoint(params[0], 0.f)];
}
@end
@@ -6,9 +6,9 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
#import <Foundation/Foundation.h>
@interface IJSVGCommandLineTo : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandLineTo : IJSVGCommand
@end
@@ -0,0 +1,34 @@
//
// IJSVGCommandLineTo.m
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandLineTo.h"
@implementation IJSVGCommandLineTo
+ (NSInteger)requiredParameterCount
{
return 2;
}
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
if (type == kIJSVGCommandTypeAbsolute) {
[[path currentSubpath] lineToPoint:NSMakePoint(params[0], params[1])];
return;
}
NSPoint point = NSMakePoint([path currentSubpath].currentPoint.x + params[0],
[path currentSubpath].currentPoint.y + params[1]);
[[path currentSubpath] lineToPoint:point];
}
@end
@@ -6,9 +6,9 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
#import <Foundation/Foundation.h>
@interface IJSVGCommandMove : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandMove : IJSVGCommand
@end
@@ -6,34 +6,26 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandMove.h"
#import "IJSVGCommandLineTo.h"
#import "IJSVGCommandMove.h"
@implementation IJSVGCommandMove
+ (void)load
{
[IJSVGCommand registerClass:[self class]
forCommand:@"m"];
}
+ (NSInteger)requiredParameterCount
{
return 2;
}
+ (void)runWithParams:(CGFloat *)params
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand *)currentCommand
previousCommand:(IJSVGCommand *)command
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath *)path
path:(IJSVGPath*)path
{
// move to's allow more then one move to, but if there are more then one,
// we need to run the line to instead...who knew!
if( command.commandClass == [self class])
{
if (command.class == self.class && currentCommand.isSubCommand == YES) {
[IJSVGCommandLineTo runWithParams:params
paramCount:count
command:currentCommand
@@ -42,18 +34,17 @@
path:path];
return;
}
// actual move to command
if( type == IJSVGCommandTypeAbsolute )
{
[[path currentSubpath] moveToPoint:NSMakePoint( params[0], params[1])];
if (type == kIJSVGCommandTypeAbsolute) {
[[path currentSubpath] moveToPoint:NSMakePoint(params[0], params[1])];
return;
}
@try {
[[path currentSubpath] relativeMoveToPoint:NSMakePoint( params[0], params[1])];
[[path currentSubpath] relativeMoveToPoint:NSMakePoint(params[0], params[1])];
}
@catch (NSException *exception) {
[[path currentSubpath] moveToPoint:NSMakePoint( params[0], params[1])];
@catch (NSException* exception) {
[[path currentSubpath] moveToPoint:NSMakePoint(params[0], params[1])];
}
}
@@ -6,9 +6,9 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
#import <Foundation/Foundation.h>
@interface IJSVGCommandQuadraticCurve : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandQuadraticCurve : IJSVGCommand
@end
@@ -11,28 +11,21 @@
@implementation IJSVGCommandQuadraticCurve
+ (void)load
{
[IJSVGCommand registerClass:[self class]
forCommand:@"q"];
}
+ (NSInteger)requiredParameterCount
{
return 4;
}
+ (void)runWithParams:(CGFloat *)params
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand *)currentCommand
previousCommand:(IJSVGCommand *)command
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath *)path
path:(IJSVGPath*)path
{
if( type == IJSVGCommandTypeAbsolute )
{
[[path currentSubpath] addQuadCurveToPoint:NSMakePoint( params[2], params[3])
controlPoint:NSMakePoint( params[0], params[1])];
if (type == kIJSVGCommandTypeAbsolute) {
[[path currentSubpath] addQuadCurveToPoint:NSMakePoint(params[2], params[3])
controlPoint:NSMakePoint(params[0], params[1])];
return;
}
[[path currentSubpath] addQuadCurveToPoint:NSMakePoint([path currentSubpath].currentPoint.x + params[2], [path currentSubpath].currentPoint.y + params[3])
@@ -6,9 +6,9 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
#import <Foundation/Foundation.h>
@interface IJSVGCommandSmoothCurve : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandSmoothCurve : IJSVGCommand
@end
@@ -0,0 +1,64 @@
//
// IJSVGCommandSmoothCurve.m
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandCurve.h"
#import "IJSVGCommandSmoothCurve.h"
#import "IJSVGUtils.h"
@implementation IJSVGCommandSmoothCurve
+ (NSInteger)requiredParameterCount
{
return 4;
}
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
NSPoint firstControl = NSMakePoint([path currentSubpath].currentPoint.x, [path currentSubpath].currentPoint.y);
if (command != nil) {
if (command.class == [IJSVGCommandCurve class] || command.class == self.class) {
if (command.class == [IJSVGCommandCurve class]) {
if (command.type == kIJSVGCommandTypeAbsolute) {
firstControl = NSMakePoint(-1 * command.parameters[2] + 2 * [path currentSubpath].currentPoint.x,
-1 * command.parameters[3] + 2 * [path currentSubpath].currentPoint.y);
} else {
NSPoint oldPoint = NSMakePoint([path currentSubpath].currentPoint.x - command.parameters[4],
[path currentSubpath].currentPoint.y - command.parameters[5]);
firstControl = NSMakePoint(-1 * (command.parameters[2] + oldPoint.x) + 2 * [path currentSubpath].currentPoint.x,
-1 * (command.parameters[3] + oldPoint.y) + 2 * [path currentSubpath].currentPoint.y);
}
} else {
if (command.type == kIJSVGCommandTypeAbsolute) {
firstControl = NSMakePoint(-1 * command.parameters[0] + 2 * [path currentSubpath].currentPoint.x,
-1 * command.parameters[1] + 2 * [path currentSubpath].currentPoint.y);
} else {
NSPoint oldPoint = NSMakePoint([path currentSubpath].currentPoint.x - command.parameters[2],
[path currentSubpath].currentPoint.y - command.parameters[3]);
firstControl = NSMakePoint(-1 * (command.parameters[0] + oldPoint.x) + 2 * [path currentSubpath].currentPoint.x,
-1 * (command.parameters[1] + oldPoint.y) + 2 * [path currentSubpath].currentPoint.y);
}
}
}
}
if (type == kIJSVGCommandTypeAbsolute) {
[[path currentSubpath] curveToPoint:NSMakePoint(params[2], params[3])
controlPoint1:NSMakePoint(firstControl.x, firstControl.y)
controlPoint2:NSMakePoint(params[0], params[1])];
return;
}
[[path currentSubpath] curveToPoint:NSMakePoint([path currentSubpath].currentPoint.x + params[2], [path currentSubpath].currentPoint.y + params[3])
controlPoint1:NSMakePoint(firstControl.x, firstControl.y)
controlPoint2:NSMakePoint([path currentSubpath].currentPoint.x + params[0], [path currentSubpath].currentPoint.y + params[1])];
}
@end
@@ -6,9 +6,9 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
#import <Foundation/Foundation.h>
@interface IJSVGCommandCommandSmoothQuadraticCurve : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandSmoothQuadraticCurve : IJSVGCommand
@end
@@ -0,0 +1,56 @@
//
// IJSVGCommandCommandQuadraticCurve.m
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandQuadraticCurve.h"
#import "IJSVGCommandSmoothQuadraticCurve.h"
#import "IJSVGUtils.h"
@implementation IJSVGCommandSmoothQuadraticCurve
+ (NSInteger)requiredParameterCount
{
return 2;
}
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
NSPoint commandPoint = NSMakePoint([path currentSubpath].currentPoint.x, [path currentSubpath].currentPoint.y);
if (command != nil) {
if (command.class == IJSVGCommandQuadraticCurve.class) {
// quadratic curve
if (command.type == kIJSVGCommandTypeAbsolute) {
commandPoint = NSMakePoint(-1 * command.parameters[0] + 2 * [path currentSubpath].currentPoint.x,
-1 * command.parameters[1] + 2 * [path currentSubpath].currentPoint.y);
} else {
NSPoint oldPoint = CGPointMake([path currentSubpath].currentPoint.x - command.parameters[2],
[path currentSubpath].currentPoint.y - command.parameters[3]);
commandPoint = CGPointMake(-1 * (command.parameters[0] + oldPoint.x) + 2 * ([path currentSubpath].currentPoint.x),
-1 * (command.parameters[1] + oldPoint.y) + 2 * [path currentSubpath].currentPoint.y);
}
} else if (command.class == self.class) {
// smooth quadratic curve
commandPoint = CGPointMake(-1 * (path.lastControlPoint.x) + 2 * ([path currentSubpath].currentPoint.x),
-1 * (path.lastControlPoint.y) + 2 * [path currentSubpath].currentPoint.y);
}
}
path.lastControlPoint = commandPoint;
if (type == kIJSVGCommandTypeAbsolute) {
[[path currentSubpath] addQuadCurveToPoint:NSMakePoint(params[0], params[1])
controlPoint:commandPoint];
return;
}
[[path currentSubpath] addQuadCurveToPoint:NSMakePoint([path currentSubpath].currentPoint.x + params[0], [path currentSubpath].currentPoint.y + params[1])
controlPoint:commandPoint];
}
@end
@@ -6,9 +6,9 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
#import <Foundation/Foundation.h>
@interface IJSVGCommandVerticalLine : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandVerticalLine : IJSVGCommand
@end
@@ -0,0 +1,32 @@
//
// IJSVGCommandVerticalLine.m
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandVerticalLine.h"
@implementation IJSVGCommandVerticalLine
+ (NSInteger)requiredParameterCount
{
return 1;
}
+ (void)runWithParams:(CGFloat*)params
paramCount:(NSInteger)count
command:(IJSVGCommand*)currentCommand
previousCommand:(IJSVGCommand*)command
type:(IJSVGCommandType)type
path:(IJSVGPath*)path
{
if (type == kIJSVGCommandTypeAbsolute) {
[[path currentSubpath] lineToPoint:NSMakePoint([path currentSubpath].currentPoint.x, params[0])];
return;
}
[[path currentSubpath] relativeLineToPoint:NSMakePoint(0.f, params[0])];
}
@end
@@ -0,0 +1,63 @@
//
// IJSVGExporter.h
// IJSVGExample
//
// Created by Curtis Hard on 06/01/2017.
// Copyright © 2017 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
@class IJSVG;
typedef void (^IJSVGCGPathHandler)(const CGPathElement* pathElement);
typedef void (^IJSVGPathElementEnumerationBlock)(const CGPathElement* pathElement, CGPoint currentPoint);
void IJSVGExporterPathCaller(void* info, const CGPathElement* pathElement);
typedef NS_OPTIONS(NSInteger, IJSVGExporterOptions) {
IJSVGExporterOptionNone = 1 << 0,
IJSVGExporterOptionRemoveUselessGroups = 1 << 1,
IJSVGExporterOptionRemoveUselessDef = 1 << 2,
IJSVGExporterOptionMoveAttributesToGroup = 1 << 3,
IJSVGExporterOptionCreateUseForPaths = 1 << 4,
IJSVGExporterOptionSortAttributes = 1 << 5,
IJSVGExporterOptionCollapseGroups = 1 << 6,
IJSVGExporterOptionCleanupPaths = 1 << 7,
IJSVGExporterOptionRemoveHiddenElements = 1 << 8,
IJSVGExporterOptionScaleToSizeIfNecessary = 1 << 9,
IJSVGExporterOptionCompressOutput = 1 << 10,
IJSVGExporterOptionCollapseGradients = 1 << 11,
IJSVGExporterOptionCreateClasses = 1 << 12,
IJSVGExporterOptionRemoveWidthHeightAttributes = 1 << 13,
IJSVGExporterOptionColorAllowRRGGBBAA = 1 << 14,
IJSVGExporterOptionRemoveComments = 1 << 15,
IJSVGExporterOptionAll = IJSVGExporterOptionRemoveUselessDef | IJSVGExporterOptionRemoveUselessGroups | IJSVGExporterOptionCreateUseForPaths | IJSVGExporterOptionMoveAttributesToGroup | IJSVGExporterOptionSortAttributes | IJSVGExporterOptionCollapseGroups | IJSVGExporterOptionCleanupPaths | IJSVGExporterOptionRemoveHiddenElements | IJSVGExporterOptionScaleToSizeIfNecessary | IJSVGExporterOptionCompressOutput | IJSVGExporterOptionCollapseGradients | IJSVGExporterOptionRemoveWidthHeightAttributes | IJSVGExporterOptionColorAllowRRGGBBAA | IJSVGExporterOptionRemoveComments
};
BOOL IJSVGExporterHasOption(IJSVGExporterOptions options, NSInteger option);
void IJSVGEnumerateCGPathElements(CGPathRef path, IJSVGPathElementEnumerationBlock enumBlock);
@interface IJSVGExporter : NSObject {
@private
IJSVG* _svg;
CGSize _size;
IJSVGExporterOptions _options;
NSXMLDocument* _dom;
NSXMLElement* _defElement;
NSXMLElement* _scaledRootNode;
NSInteger _idCount;
NSInteger _shortIdCount;
}
@property (nonatomic, copy) NSString* title;
@property (nonatomic, copy) NSString* description;
- (id)initWithSVG:(IJSVG*)svg
size:(CGSize)size
options:(IJSVGExporterOptions)options;
- (NSString*)SVGString;
- (NSData*)SVGData;
@end
File diff suppressed because it is too large Load Diff
@@ -9,24 +9,24 @@
#import <Foundation/Foundation.h>
@interface IJSVGExporterPathInstruction : NSObject {
@private
NSInteger _dataCount;
char _instruction;
CGFloat * _data;
CGFloat* _data;
}
+ (NSArray<IJSVGExporterPathInstruction *> *)instructionsFromPath:(CGPathRef)path;
+ (NSArray<IJSVGExporterPathInstruction*>*)instructionsFromPath:(CGPathRef)path;
- (id)initWithInstruction:(char)instruction
dataCount:(NSInteger)floatCount;
- (void)setInstruction:(char)newInstruction;
- (char)instruction;
- (CGFloat *)data;
- (CGFloat*)data;
- (NSInteger)dataLength;
+ (void)convertInstructionsToRelativeCoordinates:(NSArray<IJSVGExporterPathInstruction *> *)instructions;
+ (NSString *)pathStringFromInstructions:(NSArray<IJSVGExporterPathInstruction *> *)instructions;
+ (void)convertInstructionsToRelativeCoordinates:(NSArray<IJSVGExporterPathInstruction*>*)instructions;
+ (NSString*)pathStringFromInstructions:(NSArray<IJSVGExporterPathInstruction*>*)instructions;
@end
@@ -0,0 +1,369 @@
//
// IJSVGExporterPathInstruction.m
// IconJar
//
// Created by Curtis Hard on 08/01/2017.
// Copyright © 2017 Curtis Hard. All rights reserved.
//
#import "IJSVGExporter.h"
#import "IJSVGExporterPathInstruction.h"
@implementation IJSVGExporterPathInstruction
- (void)dealloc
{
if (_data != NULL) {
free(_data);
}
[super dealloc];
}
- (id)initWithInstruction:(char)instruction
dataCount:(NSInteger)floatCount
{
if ((self = [super init]) != nil) {
_instruction = instruction;
// only allocate if not zero
if (floatCount != 0) {
_data = (CGFloat*)calloc(sizeof(CGFloat), floatCount);
}
}
return self;
}
- (NSInteger)dataLength
{
return _dataCount;
}
- (void)setInstruction:(char)newInstruction
{
_instruction = newInstruction;
}
- (char)instruction
{
return _instruction;
}
- (CGFloat*)data
{
return _data;
}
+ (NSString*)pathStringFromInstructions:(NSArray<IJSVGExporterPathInstruction*>*)instructions
{
NSMutableArray* pathData = [[[NSMutableArray alloc] init] autorelease];
for (IJSVGExporterPathInstruction* instruction in instructions) {
CGFloat* data = instruction.data;
NSString* str = nil;
switch (instruction.instruction) {
// move
case 'M':
case 'm': {
char* buffer;
asprintf(&buffer, "%c%g,%g", instruction.instruction, data[0], data[1]);
str = [NSString stringWithCString:buffer
encoding:NSUTF8StringEncoding];
free(buffer);
[pathData addObject:str];
break;
}
// vertical and horizonal line
case 'V':
case 'v':
case 'H':
case 'h': {
char* buffer;
asprintf(&buffer, "%c%g", instruction.instruction, data[0]);
str = [NSString stringWithCString:buffer
encoding:NSUTF8StringEncoding];
free(buffer);
[pathData addObject:str];
break;
}
// line
case 'L':
case 'l': {
char* buffer;
asprintf(&buffer, "%c%g,%g", instruction.instruction, data[0], data[1]);
str = [NSString stringWithCString:buffer
encoding:NSUTF8StringEncoding];
free(buffer);
[pathData addObject:str];
break;
}
// curve
case 'C':
case 'c': {
char* buffer;
asprintf(&buffer, "%c%g,%g %g,%g %g,%g", instruction.instruction,
data[0], data[1], data[2], data[3], data[4], data[5]);
str = [NSString stringWithCString:buffer
encoding:NSUTF8StringEncoding];
free(buffer);
[pathData addObject:str];
break;
}
// quadratic curve
case 'Q':
case 'q': {
char* buffer;
asprintf(&buffer, "%c%g,%g %g,%g", instruction.instruction,
data[0], data[1], data[2], data[3]);
str = [NSString stringWithCString:buffer
encoding:NSUTF8StringEncoding];
free(buffer);
[pathData addObject:str];
break;
}
// close path
case 'Z':
case 'z': {
str = [NSString stringWithFormat:@"%c", instruction.instruction];
[pathData addObject:str];
}
}
}
return [pathData componentsJoinedByString:@""];
}
+ (void)convertInstructionsToRelativeCoordinates:(NSArray<IJSVGExporterPathInstruction*>*)instructions
{
CGFloat point[2] = { 0, 0 };
CGFloat subpathPoint[2] = { 0, 0 };
NSInteger index = 0;
for (IJSVGExporterPathInstruction* anInstruction in instructions) {
char instruction = anInstruction.instruction;
CGFloat* data = anInstruction.data;
NSInteger length = anInstruction.dataLength;
if (data != NULL) {
// already relative
if (instruction == 'm' || instruction == 'c' || instruction == 's' || instruction == 'l' || instruction == 'q' || instruction == 't' || instruction == 'a') {
point[0] += data[length - 2];
point[1] += data[length - 1];
if (instruction == 'm') {
subpathPoint[0] = point[0];
subpathPoint[1] = point[1];
}
} else if (instruction == 'h') {
point[0] += data[0];
} else if (instruction == 'v') {
point[1] += data[0];
}
// convert absolute to relative
if (instruction == 'M') {
if (index > 0) {
instruction = 'm';
}
data[0] -= point[0];
data[1] -= point[1];
subpathPoint[0] = point[0] += data[0];
subpathPoint[1] = point[1] += data[1];
} else if (instruction == 'L' || instruction == 'T') {
instruction = tolower(instruction);
data[0] -= point[0];
data[1] -= point[1];
point[0] += data[0];
point[1] += data[1];
} else if (instruction == 'C') {
instruction = 'c';
data[0] -= point[0];
data[1] -= point[1];
data[2] -= point[0];
data[3] -= point[1];
data[4] -= point[0];
data[5] -= point[1];
point[0] += data[4];
point[1] += data[5];
} else if (instruction == 'S' || instruction == 'Q') {
instruction = tolower(instruction);
data[0] -= point[0];
data[1] -= point[1];
data[2] -= point[0];
data[3] -= point[1];
point[0] += data[2];
point[1] += data[3];
} else if (instruction == 'A') {
instruction = 'a';
data[5] -= point[0];
data[6] -= point[1];
point[0] += data[5];
point[1] += data[6];
} else if (instruction == 'H') {
instruction = 'h';
data[0] -= point[0];
point[0] += data[0];
} else if (instruction == 'V') {
instruction = 'v';
data[0] -= point[1];
point[1] += data[0];
}
// reset the instruction
[anInstruction setInstruction:instruction];
} else if (instruction == 'Z' || instruction == 'z') {
point[0] = subpathPoint[0];
point[1] = subpathPoint[1];
}
// increment index
index++;
}
}
+ (NSArray<IJSVGExporterPathInstruction*>*)instructionsFromPath:(CGPathRef)path
{
// keep track of the current point
__block CGPoint currentPoint = CGPointZero;
NSMutableArray* instructions = [[[NSMutableArray alloc] init] autorelease];
// create the path callback
IJSVGCGPathHandler callback = ^(const CGPathElement* pathElement) {
IJSVGExporterPathInstruction* instruction = nil;
// work out what to do
switch (pathElement->type) {
case kCGPathElementMoveToPoint: {
// move to command
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'M'
dataCount:2] autorelease];
CGPoint point = pathElement->points[0];
instruction.data[0] = point.x;
instruction.data[1] = point.y;
currentPoint = point;
[instructions addObject:instruction];
break;
}
case kCGPathElementAddLineToPoint: {
// line to command
CGPoint point = pathElement->points[0];
if (point.x == currentPoint.x) {
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'V'
dataCount:1] autorelease];
instruction.data[0] = point.y;
} else if (point.y == currentPoint.y) {
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'H'
dataCount:1] autorelease];
instruction.data[0] = point.x;
} else {
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'L'
dataCount:2] autorelease];
instruction.data[0] = point.x;
instruction.data[1] = point.y;
}
currentPoint = point;
[instructions addObject:instruction];
break;
}
case kCGPathElementAddQuadCurveToPoint: {
// quad curve to command
CGPoint controlPoint = pathElement->points[0];
CGPoint point = pathElement->points[1];
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'Q'
dataCount:4] autorelease];
instruction.data[0] = controlPoint.x;
instruction.data[1] = controlPoint.y;
instruction.data[2] = point.x;
instruction.data[3] = point.y;
currentPoint = point;
[instructions addObject:instruction];
break;
}
case kCGPathElementAddCurveToPoint: {
// curve to command
CGPoint controlPoint1 = pathElement->points[0];
CGPoint controlPoint2 = pathElement->points[1];
CGPoint point = pathElement->points[2];
currentPoint = point;
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'C'
dataCount:6] autorelease];
instruction.data[0] = controlPoint1.x;
instruction.data[1] = controlPoint1.y;
instruction.data[2] = controlPoint2.x;
instruction.data[3] = controlPoint2.y;
instruction.data[4] = point.x;
instruction.data[5] = point.y;
[instructions addObject:instruction];
break;
}
case kCGPathElementCloseSubpath: {
// close command
instruction = [[[IJSVGExporterPathInstruction alloc] initWithInstruction:'Z'
dataCount:0] autorelease];
[instructions addObject:instruction];
break;
}
}
};
// apply the
CGPathApply(path, (__bridge void*)callback, IJSVGExporterPathCaller);
// remove last instruction if it was Z -> M
IJSVGExporterPathInstruction* lastInstruction = instructions.lastObject;
if (lastInstruction.instruction == 'M' || lastInstruction.instruction == 'm') {
if (instructions.count >= 2) {
NSInteger index = [instructions indexOfObject:lastInstruction] - 1;
IJSVGExporterPathInstruction* prevInstruction = instructions[index];
if (prevInstruction.instruction == 'z' || prevInstruction.instruction == 'Z') {
[instructions removeLastObject];
}
}
}
return instructions;
}
@end
@@ -6,15 +6,18 @@
// Copyright © 2016 Curtis Hard. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import "IJSVGGradient.h"
#import "IJSVGPath.h"
#import "IJSVGLayer.h"
#import "IJSVGPath.h"
#import <QuartzCore/QuartzCore.h>
@interface IJSVGGradientLayer : IJSVGLayer {
}
@property (nonatomic, retain) IJSVGGradient * gradient;
@property (nonatomic, assign) CGRect viewBox;
@property (nonatomic, retain) IJSVGGradient* gradient;
@property (nonatomic, assign) CGAffineTransform absoluteTransform;
@property (nonatomic, assign) CGRect objectRect;
@end
@@ -0,0 +1,103 @@
//
// IJSVGGradientLayer.m
// IJSVGExample
//
// Created by Curtis Hard on 29/12/2016.
// Copyright © 2016 Curtis Hard. All rights reserved.
//
#import "IJSVGGradientLayer.h"
@implementation IJSVGGradientLayer
@synthesize viewBox;
@synthesize gradient;
@synthesize absoluteTransform;
@synthesize objectRect;
- (void)dealloc
{
(void)([gradient release]), gradient = nil;
[super dealloc];
}
- (id)init
{
if ((self = [super init]) != nil) {
self.requiresBackingScaleHelp = YES;
self.shouldRasterize = YES;
}
return self;
}
- (void)setGradient:(IJSVGGradient*)newGradient
{
if (gradient != nil) {
(void)([gradient release]), gradient = nil;
}
gradient = [newGradient retain];
// lets check its alpha properties on the colors
BOOL hasAlphaChannel = NO;
NSInteger stops = gradient.gradient.numberOfColorStops;
for (NSInteger i = 0; i < stops; i++) {
NSColor* color = nil;
[gradient.gradient getColor:&color
location:NULL
atIndex:i];
if (color.alphaComponent != 1.f) {
hasAlphaChannel = YES;
break;
}
}
self.opaque = hasAlphaChannel == NO;
}
- (void)setOpacity:(float)opacity
{
if (opacity != 1.f) {
self.opaque = NO;
}
[super setOpacity:opacity];
}
- (void)setBackingScaleFactor:(CGFloat)backingScaleFactor
{
switch (self.renderQuality) {
case kIJSVGRenderQualityOptimized: {
backingScaleFactor = (backingScaleFactor * .35f);
break;
}
case kIJSVGRenderQualityLow: {
backingScaleFactor = (backingScaleFactor * .05f);
break;
}
default: {
break;
}
}
[super setBackingScaleFactor:backingScaleFactor];
}
- (void)drawInContext:(CGContextRef)ctx
{
[super drawInContext:ctx];
// nothing to do :(
if (self.gradient == nil) {
return;
}
// draw the gradient
CGAffineTransform trans = CGAffineTransformMakeTranslation(-CGRectGetMinX(objectRect),
-CGRectGetMinY(objectRect));
CGAffineTransform transform = CGAffineTransformConcat(absoluteTransform, trans);
CGContextSaveGState(ctx);
[self.gradient drawInContextRef:ctx
objectRect:objectRect
absoluteTransform:transform
viewPort:self.viewBox];
CGContextRestoreGState(ctx);
}
@end
@@ -6,9 +6,9 @@
// Copyright © 2017 Curtis Hard. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import "IJSVGLayer.h"
#import "IJSVGShapeLayer.h"
#import <QuartzCore/QuartzCore.h>
@interface IJSVGGroupLayer : IJSVGLayer
@@ -6,14 +6,14 @@
// Copyright © 2017 Curtis Hard. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import "IJSVGLayer.h"
#import <AppKit/AppKit.h>
#import <QuartzCore/QuartzCore.h>
@interface IJSVGImageLayer : IJSVGLayer {
}
- (id)initWithImage:(NSImage *)image;
- (id)initWithImage:(NSImage*)image;
- (id)initWithCGImage:(CGImageRef)imageRef;
@end
@@ -10,7 +10,7 @@
@implementation IJSVGImageLayer
- (id)initWithImage:(NSImage *)image
- (id)initWithImage:(NSImage*)image
{
NSRect rect = (NSRect){
.origin = NSZeroPoint,
@@ -24,18 +24,32 @@
- (id)initWithCGImage:(CGImageRef)imageRef
{
if((self = [super init]) != nil) {
if ((self = [super init]) != nil) {
// set the contents
self.contents = (id)imageRef;
// make sure we say we need help
self.requiresBackingScaleHelp = YES;
self.shouldRasterize = YES;
// set the frame, simple stuff
self.frame = (CGRect){
.origin = CGPointZero,
.size = CGSizeMake( CGImageGetWidth(imageRef),
CGImageGetHeight(imageRef))
.size = CGSizeMake(CGImageGetWidth(imageRef),
CGImageGetHeight(imageRef))
};
}
return self;
}
- (void)setNeedsDisplay
{
// swap the content around on call
// because set needs display discards previous
// content - yolo!
id oldContent = self.contents;
[super setNeedsDisplay];
self.contents = oldContent;
}
@end
@@ -0,0 +1,45 @@
//
// IJSVGLayer.h
// IJSVGExample
//
// Created by Curtis Hard on 07/01/2017.
// Copyright © 2017 Curtis Hard. All rights reserved.
//
#import "IJSVGRendering.h"
#import "IJSVGTransaction.h"
#import <QuartzCore/QuartzCore.h>
@class IJSVGShapeLayer;
@class IJSVGGradientLayer;
@class IJSVGPatternLayer;
@class IJSVGStrokeLayer;
@class IJSVGGroupLayer;
@interface IJSVGLayer : CALayer {
@private
IJSVGLayer* _maskingLayer;
}
@property (nonatomic, assign) IJSVGGradientLayer* gradientFillLayer;
@property (nonatomic, assign) IJSVGPatternLayer* patternFillLayer;
@property (nonatomic, assign) IJSVGStrokeLayer* strokeLayer;
@property (nonatomic, assign) IJSVGGradientLayer* gradientStrokeLayer;
@property (nonatomic, assign) IJSVGPatternLayer* patternStrokeLayer;
@property (nonatomic, assign) BOOL requiresBackingScaleHelp;
@property (nonatomic, assign) CGFloat backingScaleFactor;
@property (nonatomic, assign) IJSVGRenderQuality renderQuality;
@property (nonatomic, assign) CGBlendMode blendingMode;
@property (nonatomic, assign) CGPoint absoluteOrigin;
@property (nonatomic, assign) BOOL convertMasksToPaths;
+ (NSArray*)deepestSublayersOfLayer:(CALayer*)layer;
+ (void)recursivelyWalkLayer:(CALayer*)layer
withBlock:(void (^)(CALayer* layer, BOOL isMask))block;
- (void)applySublayerMaskToContext:(CGContextRef)context
forSublayer:(IJSVGLayer*)sublayer
withOffset:(CGPoint)offset;
@end
@@ -0,0 +1,169 @@
//
// IJSVGLayer.m
// IJSVGExample
//
// Created by Curtis Hard on 07/01/2017.
// Copyright © 2017 Curtis Hard. All rights reserved.
//
#import "IJSVG.h"
#import "IJSVGGroupLayer.h"
#import "IJSVGLayer.h"
#import "IJSVGShapeLayer.h"
@implementation IJSVGLayer
@synthesize gradientFillLayer;
@synthesize patternFillLayer;
@synthesize gradientStrokeLayer;
@synthesize patternStrokeLayer;
@synthesize strokeLayer;
@synthesize requiresBackingScaleHelp;
@synthesize backingScaleFactor;
@synthesize blendingMode;
@synthesize convertMasksToPaths;
- (void)dealloc
{
(void)([_maskingLayer release]), _maskingLayer = nil;
[super dealloc];
}
+ (NSArray*)deepestSublayersOfLayer:(CALayer*)layer
{
NSMutableArray* arr = [[[NSMutableArray alloc] init] autorelease];
for (CALayer* subLayer in layer.sublayers) {
if (subLayer.sublayers.count != 0) {
NSArray* moreLayers = [self deepestSublayersOfLayer:(IJSVGLayer*)subLayer];
[arr addObjectsFromArray:moreLayers];
} else {
[arr addObject:subLayer];
}
}
return arr;
}
+ (void)recursivelyWalkLayer:(CALayer*)layer
withBlock:(void (^)(CALayer* layer, BOOL isMask))block
{
// call for layer and mask if there is one
block(layer, NO);
// do the mask too!
if (layer.mask != nil) {
block(layer.mask, YES);
}
// sublayers!!
for (CALayer* aLayer in layer.sublayers) {
[self recursivelyWalkLayer:aLayer
withBlock:block];
}
}
- (void)setBackingScaleFactor:(CGFloat)newFactor
{
if (self.backingScaleFactor == newFactor) {
return;
}
backingScaleFactor = newFactor;
self.contentsScale = newFactor;
self.rasterizationScale = newFactor;
[self setNeedsDisplay];
}
- (void)_customRenderInContext:(CGContextRef)ctx
{
if (self.convertMasksToPaths == YES && _maskingLayer != nil) {
CGContextSaveGState(ctx);
[self applySublayerMaskToContext:ctx
forSublayer:(IJSVGLayer*)self
withOffset:CGPointZero];
[super renderInContext:ctx];
CGContextRestoreGState(ctx);
return;
}
[super renderInContext:ctx];
}
- (void)setConvertMasksToPaths:(BOOL)flag
{
if (convertMasksToPaths == flag) {
return;
}
convertMasksToPaths = flag;
if (flag == YES) {
if (_maskingLayer != nil) {
(void)([_maskingLayer release]), _maskingLayer = nil;
}
_maskingLayer = [(IJSVGLayer*)self.mask retain];
self.mask = nil;
} else {
self.mask = _maskingLayer;
(void)([_maskingLayer release]), _maskingLayer = nil;
}
}
- (void)applySublayerMaskToContext:(CGContextRef)context
forSublayer:(IJSVGLayer*)sublayer
withOffset:(CGPoint)offset
{
// apply any transforms needed
CGPoint layerOffset = offset;
CGAffineTransform sublayerTransform = CATransform3DGetAffineTransform(sublayer.transform);
CGContextConcatCTM(context, CGAffineTransformInvert(sublayerTransform));
// walk up the superlayer chain
CALayer* superlayer = self.superlayer;
if (IJSVGIsSVGLayer(superlayer) == YES) {
[(IJSVGLayer*)superlayer applySublayerMaskToContext:context
forSublayer:(IJSVGLayer*)self
withOffset:layerOffset];
}
// grab the masking layer
IJSVGShapeLayer* maskingLayer = [self maskingLayer];
// if its a group we need to get the lowest level children
// and walk up the chain again
if ([maskingLayer isKindOfClass:[IJSVGGroupLayer class]]) {
NSArray* subs = [IJSVGLayer deepestSublayersOfLayer:maskingLayer];
for (IJSVGLayer* subLayer in subs) {
[subLayer applySublayerMaskToContext:context
forSublayer:(IJSVGLayer*)self
withOffset:layerOffset];
}
} else if ([maskingLayer isKindOfClass:[IJSVGShapeLayer class]]) {
// is a shape, go for it!
CGPathRef maskPath = maskingLayer.path;
CGContextTranslateCTM(context, -layerOffset.x, -layerOffset.y);
CGContextAddPath(context, maskPath);
CGContextClip(context);
CGContextTranslateCTM(context, layerOffset.x, layerOffset.y);
}
CGContextConcatCTM(context, sublayerTransform);
}
- (IJSVGShapeLayer*)maskingLayer
{
return (IJSVGShapeLayer*)_maskingLayer ?: nil;
}
- (void)renderInContext:(CGContextRef)ctx
{
if (self.blendingMode != kCGBlendModeNormal) {
CGContextSaveGState(ctx);
CGContextSetBlendMode(ctx, self.blendingMode);
[self _customRenderInContext:ctx];
CGContextRestoreGState(ctx);
return;
}
[self _customRenderInContext:ctx];
}
- (id<CAAction>)actionForKey:(NSString*)event
{
return nil;
}
@end
@@ -6,13 +6,13 @@
// Copyright © 2017 Curtis Hard. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import "IJSVGLayer.h"
#import "IJSVGPattern.h"
#import <QuartzCore/QuartzCore.h>
@interface IJSVGPatternLayer : IJSVGLayer
@property (nonatomic, retain) IJSVGLayer * pattern;
@property (nonatomic, retain) IJSVGPattern * patternNode;
@property (nonatomic, retain) IJSVGLayer* pattern;
@property (nonatomic, retain) IJSVGPattern* patternNode;
@end
@@ -15,49 +15,51 @@
- (void)dealloc
{
[pattern release], pattern = nil;
[patternNode release], patternNode = nil;
(void)([pattern release]), pattern = nil;
(void)([patternNode release]), patternNode = nil;
[super dealloc];
}
- (id)init
{
if((self = [super init]) != nil) {
if ((self = [super init]) != nil) {
self.requiresBackingScaleHelp = YES;
self.shouldRasterize = YES;
}
return self;
}
void IJSVGPatternDrawingCallBack(void * info, CGContextRef ctx) {
void IJSVGPatternDrawingCallBack(void* info, CGContextRef ctx)
{
// reassign the layer
IJSVGPatternLayer * layer = (IJSVGPatternLayer *)info;
IJSVGPatternLayer* layer = (IJSVGPatternLayer*)info;
[layer.pattern renderInContext:ctx];
};
- (void)drawInContext:(CGContextRef)ctx
{
// holder for callback
static const CGPatternCallbacks callbacks = {0, &IJSVGPatternDrawingCallBack, NULL};
static const CGPatternCallbacks callbacks = { 0, &IJSVGPatternDrawingCallBack, NULL };
// create base pattern space
CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
CGContextSetFillColorSpace(ctx, patternSpace);
CGColorSpaceRelease(patternSpace);
// create the pattern
CGRect rect = self.bounds;
CGPatternRef ref = CGPatternCreate( (void *)self, self.bounds,
CGAffineTransformIdentity,
roundf(rect.size.width*self.patternNode.width.value),
roundf(rect.size.height*self.patternNode.height.value),
kCGPatternTilingConstantSpacing,
true, &callbacks);
CGPatternRef ref = CGPatternCreate((void*)self, self.bounds,
CGAffineTransformIdentity,
roundf(rect.size.width * self.patternNode.width.value),
roundf(rect.size.height * self.patternNode.height.value),
kCGPatternTilingConstantSpacing,
true, &callbacks);
// set the pattern then release it
CGFloat alpha = 1.f;
CGContextSetFillPattern(ctx, ref, &alpha);
CGPatternRelease(ref);
// fill it
CGContextFillRect(ctx, rect);
}
@@ -0,0 +1,23 @@
//
// IJSVGRadialGradient.h
// IJSVGExample
//
// Created by Curtis Hard on 03/09/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGGradient.h"
#import <Foundation/Foundation.h>
@interface IJSVGRadialGradient : IJSVGGradient
@property (nonatomic, retain) IJSVGUnitLength* cx;
@property (nonatomic, retain) IJSVGUnitLength* cy;
@property (nonatomic, retain) IJSVGUnitLength* fx;
@property (nonatomic, retain) IJSVGUnitLength* fy;
@property (nonatomic, retain) IJSVGUnitLength* radius;
+ (NSGradient*)parseGradient:(NSXMLElement*)element
gradient:(IJSVGRadialGradient*)gradient;
@end
@@ -0,0 +1,159 @@
//
// IJSVGRadialGradient.m
// IJSVGExample
//
// Created by Curtis Hard on 03/09/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGRadialGradient.h"
@implementation IJSVGRadialGradient
@synthesize cx;
@synthesize cy;
@synthesize fx;
@synthesize fy;
@synthesize radius;
- (void)dealloc
{
(void)([cx release]), cx = nil;
(void)([cy release]), cy = nil;
(void)([fx release]), fx = nil;
(void)([fy release]), fy = nil;
(void)([radius release]), radius = nil;
[super dealloc];
}
- (id)copyWithZone:(NSZone*)zone
{
IJSVGRadialGradient* grad = [super copyWithZone:zone];
grad.fx = self.fx;
grad.fy = self.fy;
grad.cx = self.cx;
grad.cy = self.cy;
grad.radius = self.radius;
return grad;
}
+ (NSGradient*)parseGradient:(NSXMLElement*)element
gradient:(IJSVGRadialGradient*)gradient
{
// cx defaults to 50% if not specified
NSDictionary* kv = @{ @"cx" : @"cx",
@"cy" : @"cy",
@"r" : @"radius" };
for (NSString* key in kv.allKeys) {
NSString* str = [element attributeForName:key].stringValue;
IJSVGUnitLength* unit = nil;
if (str != nil) {
unit = [IJSVGUnitLength unitWithString:str
fromUnitType:gradient.units];
} else {
// spec says to say 50% for missing property default
unit = [IJSVGUnitLength unitWithPercentageFloat:.5f];
}
[gradient setValue:unit
forKey:kv[key]];
}
// fx and fy are the same unless specified otherwise
gradient.fx = gradient.cx;
gradient.fy = gradient.cy;
// needs fixing
NSString* fx = [element attributeForName:@"fx"].stringValue;
if (fx != nil) {
gradient.fx = [IJSVGUnitLength unitWithString:fx
fromUnitType:gradient.units];
}
NSString* fy = [element attributeForName:@"fy"].stringValue;
if (fx != nil) {
gradient.fy = [IJSVGUnitLength unitWithString:fy
fromUnitType:gradient.units];
}
if (gradient.gradient != nil) {
return nil;
}
NSArray* colors = nil;
CGFloat* colorStops = [self.class computeColorStopsFromString:element colors:&colors];
NSGradient* ret = [[[NSGradient alloc] initWithColors:colors
atLocations:colorStops
colorSpace:IJSVGColor.defaultColorSpace] autorelease];
free(colorStops);
return ret;
}
- (void)drawInContextRef:(CGContextRef)ctx
objectRect:(NSRect)objectRect
absoluteTransform:(CGAffineTransform)absoluteTransform
viewPort:(CGRect)viewBox
{
BOOL inUserSpace = self.units == IJSVGUnitUserSpaceOnUse;
CGFloat radius = 0.f;
CGPoint startPoint = CGPointZero;
CGPoint gradientStartPoint = CGPointZero;
CGPoint gradientEndPoint = CGPointZero;
// transforms
CGAffineTransform selfTransform = IJSVGConcatTransforms(self.transforms);
CGRect boundingBox = inUserSpace ? viewBox : objectRect;
// make sure we apply the absolute position to
// transform us back into the correct space
if (inUserSpace == YES) {
CGContextConcatCTM(ctx, absoluteTransform);
}
// compute size based on percentages
CGFloat x = [self.cx computeValue:CGRectGetWidth(boundingBox)];
CGFloat y = [self.cy computeValue:CGRectGetHeight(boundingBox)];
startPoint = CGPointMake(x, y);
CGFloat val = MIN(CGRectGetWidth(boundingBox),
CGRectGetHeight(boundingBox));
radius = [self.radius computeValue:val];
CGFloat ex = [self.fx computeValue:CGRectGetWidth(boundingBox)];
CGFloat ey = [self.fy computeValue:CGRectGetHeight(boundingBox)];
gradientEndPoint = CGPointMake(ex, ey);
gradientStartPoint = startPoint;
// transform if width or height is not equal - this can only
// be done if we are using objectBoundingBox
if (inUserSpace == NO && CGRectGetWidth(boundingBox) != CGRectGetHeight(boundingBox)) {
CGAffineTransform tr = CGAffineTransformMakeTranslation(gradientStartPoint.x,
gradientStartPoint.y);
if (CGRectGetWidth(boundingBox) > CGRectGetHeight(boundingBox)) {
tr = CGAffineTransformScale(tr, CGRectGetWidth(boundingBox) / CGRectGetHeight(boundingBox), 1);
} else {
tr = CGAffineTransformScale(tr, 1.f, CGRectGetHeight(boundingBox) / CGRectGetWidth(boundingBox));
}
tr = CGAffineTransformTranslate(tr, -gradientStartPoint.x, -gradientStartPoint.y);
selfTransform = CGAffineTransformConcat(tr, selfTransform);
}
// transform the context
CGContextConcatCTM(ctx, selfTransform);
// draw the gradient
CGGradientDrawingOptions options = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
CGContextDrawRadialGradient(ctx, self.CGGradient,
gradientEndPoint, 0,
gradientStartPoint,
radius, options);
#ifdef IJSVG_DEBUG_GRADIENTS
[self _debugStart:gradientStartPoint
end:gradientEndPoint
context:ctx];
#endif
}
@end
@@ -0,0 +1,37 @@
//
// IJSVGShapeLayer.h
// IJSVGExample
//
// Created by Curtis Hard on 07/01/2017.
// Copyright © 2017 Curtis Hard. All rights reserved.
//
#import "IJSVGLayer.h"
#import "IJSVGUtils.h"
#import <QuartzCore/QuartzCore.h>
@interface IJSVGShapeLayer : CAShapeLayer {
@private
IJSVGLayer* _maskingLayer;
}
@property (nonatomic, assign) IJSVGGradientLayer* gradientFillLayer;
@property (nonatomic, assign) IJSVGPatternLayer* patternFillLayer;
@property (nonatomic, assign) IJSVGStrokeLayer* strokeLayer;
@property (nonatomic, assign) IJSVGGradientLayer* gradientStrokeLayer;
@property (nonatomic, assign) IJSVGPatternLayer* patternStrokeLayer;
@property (nonatomic, assign) BOOL requiresBackingScaleHelp;
@property (nonatomic, assign) CGFloat backingScaleFactor;
@property (nonatomic, assign) IJSVGRenderQuality renderQuality;
@property (nonatomic, assign) CGBlendMode blendingMode;
@property (nonatomic, assign) CGPoint absoluteOrigin;
@property (nonatomic, assign) CGPoint originalPathOrigin;
@property (nonatomic, assign) BOOL convertMasksToPaths;
@property (nonatomic, assign) IJSVGPrimitivePathType primitiveType;
- (void)applySublayerMaskToContext:(CGContextRef)context
forSublayer:(IJSVGLayer*)sublayer
withOffset:(CGPoint)offset;
@end
@@ -0,0 +1,150 @@
//
// IJSVGShapeLayer.m
// IJSVGExample
//
// Created by Curtis Hard on 07/01/2017.
// Copyright © 2017 Curtis Hard. All rights reserved.
//
#import "IJSVGGroupLayer.h"
#import "IJSVGShapeLayer.h"
@implementation IJSVGShapeLayer
@synthesize gradientFillLayer;
@synthesize patternFillLayer;
@synthesize gradientStrokeLayer;
@synthesize patternStrokeLayer;
@synthesize strokeLayer;
@synthesize requiresBackingScaleHelp;
@synthesize backingScaleFactor;
@synthesize blendingMode;
@synthesize convertMasksToPaths;
@synthesize originalPathOrigin;
@synthesize renderQuality;
@synthesize primitiveType;
- (void)dealloc
{
(void)([_maskingLayer release]), _maskingLayer = nil;
[super dealloc];
}
- (void)setBackingScaleFactor:(CGFloat)newFactor
{
if (self.backingScaleFactor == newFactor) {
return;
}
backingScaleFactor = newFactor;
self.contentsScale = newFactor;
self.rasterizationScale = newFactor;
[self setNeedsDisplay];
}
- (void)_customRenderInContext:(CGContextRef)ctx
{
if (self.convertMasksToPaths == YES && _maskingLayer != nil) {
CGContextSaveGState(ctx);
[self applySublayerMaskToContext:ctx
forSublayer:(IJSVGLayer*)self
withOffset:CGPointZero];
[super renderInContext:ctx];
CGContextRestoreGState(ctx);
return;
}
[super renderInContext:ctx];
}
- (void)setConvertMasksToPaths:(BOOL)flag
{
if (convertMasksToPaths == flag) {
return;
}
convertMasksToPaths = flag;
if (flag == YES) {
if (_maskingLayer != nil) {
(void)([_maskingLayer release]), _maskingLayer = nil;
}
_maskingLayer = [(IJSVGLayer*)self.mask retain];
self.mask = nil;
} else {
self.mask = _maskingLayer;
(void)([_maskingLayer release]), _maskingLayer = nil;
}
}
- (void)applySublayerMaskToContext:(CGContextRef)context
forSublayer:(IJSVGLayer*)sublayer
withOffset:(CGPoint)offset
{
// apply any transforms needed
CGPoint layerOffset = offset;
CGAffineTransform sublayerTransform = CATransform3DGetAffineTransform(sublayer.transform);
CGContextConcatCTM(context, CGAffineTransformInvert(sublayerTransform));
// walk up the superlayer chain
CALayer* superlayer = self.superlayer;
if (IJSVGIsSVGLayer(superlayer) == YES) {
[(IJSVGLayer*)superlayer applySublayerMaskToContext:context
forSublayer:(IJSVGLayer*)self
withOffset:layerOffset];
}
// grab the masking layer
IJSVGShapeLayer* maskingLayer = [self maskingLayer];
// if its a group we need to get the lowest level children
// and walk up the chain again
if ([maskingLayer isKindOfClass:[IJSVGGroupLayer class]]) {
NSArray* subs = [IJSVGLayer deepestSublayersOfLayer:maskingLayer];
for (IJSVGLayer* subLayer in subs) {
[subLayer applySublayerMaskToContext:context
forSublayer:(IJSVGLayer*)self
withOffset:layerOffset];
}
} else if ([maskingLayer isKindOfClass:[IJSVGShapeLayer class]]) {
// is a shape, go for it!
CGPathRef maskPath = maskingLayer.path;
CGContextTranslateCTM(context, -layerOffset.x, -layerOffset.y);
CGContextAddPath(context, maskPath);
CGContextClip(context);
CGContextTranslateCTM(context, layerOffset.x, layerOffset.y);
}
CGContextConcatCTM(context, sublayerTransform);
}
- (IJSVGShapeLayer*)maskingLayer
{
return (IJSVGShapeLayer*)_maskingLayer ?: nil;
}
- (void)renderInContext:(CGContextRef)ctx
{
if (self.blendingMode != kCGBlendModeNormal) {
CGContextSaveGState(ctx);
CGContextSetBlendMode(ctx, self.blendingMode);
[self _customRenderInContext:ctx];
CGContextRestoreGState(ctx);
return;
}
[self _customRenderInContext:ctx];
}
- (CGPoint)absoluteOrigin
{
CGPoint point = CGPointZero;
CALayer* pLayer = self;
while (pLayer != nil) {
point.x += pLayer.frame.origin.x;
point.y += pLayer.frame.origin.y;
pLayer = pLayer.superlayer;
}
return point;
}
- (id<CAAction>)actionForKey:(NSString*)event
{
return nil;
}
@end
@@ -6,16 +6,15 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGNode.h"
#import <Foundation/Foundation.h>
@interface IJSVGDef : IJSVGNode {
@private
NSMutableDictionary * _dict;
NSMutableDictionary* _dict;
}
- (void)addDef:(IJSVGNode *)aDef;
- (void)addDef:(IJSVGNode*)aDef;
@end
@@ -12,28 +12,28 @@
- (void)dealloc
{
[_dict release], _dict = nil;
(void)([_dict release]), _dict = nil;
[super dealloc];
}
- (id)init
{
if( ( self = [super initWithDef:NO] ) != nil ) {
if ((self = [super initWithDef:NO]) != nil) {
_dict = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)addDef:(IJSVGNode *)aDef
- (void)addDef:(IJSVGNode*)aDef
{
if( aDef.identifier == nil ) {
if (aDef.identifier == nil) {
return;
}
[_dict setObject:aDef
forKey:aDef.identifier];
}
- (IJSVGDef *)defForID:(NSString *)anID
- (IJSVGDef*)defForID:(NSString*)anID
{
return [_dict objectForKey:anID];
}
@@ -10,7 +10,7 @@
#import "IJSVGNode.h"
@interface IJSVGForeignObject : IJSVGNode {
NSString * requiredExtension;
}
@@ -14,7 +14,7 @@
- (void)dealloc
{
[requiredExtension release], requiredExtension = nil;
(void)([requiredExtension release]), requiredExtension = nil;
[super dealloc];
}
@@ -0,0 +1,38 @@
//
// IJSVGGradient.h
// IJSVGExample
//
// Created by Curtis Hard on 03/09/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGColorList.h"
#import "IJSVGDef.h"
#import "IJSVGTransform.h"
#import <Foundation/Foundation.h>
@interface IJSVGGradient : IJSVGNode
@property (nonatomic, retain) NSGradient* gradient;
@property (nonatomic, assign) CGGradientRef CGGradient;
@property (nonatomic, retain) IJSVGUnitLength* x1;
@property (nonatomic, retain) IJSVGUnitLength* x2;
@property (nonatomic, retain) IJSVGUnitLength* y1;
@property (nonatomic, retain) IJSVGUnitLength* y2;
@property (nonatomic, retain) IJSVGColorList* colorList;
+ (CGFloat*)computeColorStopsFromString:(NSXMLElement*)element
colors:(NSArray**)someColors;
- (CGGradientRef)CGGradient;
- (void)drawInContextRef:(CGContextRef)ctx
objectRect:(NSRect)objectRect
absoluteTransform:(CGAffineTransform)absoluteTransform
viewPort:(CGRect)viewBox;
- (void)_debugStart:(CGPoint)startPoint
end:(CGPoint)endPoint
context:(CGContextRef)ctx;
- (IJSVGColorList*)computedColorList;
@end
@@ -0,0 +1,179 @@
//
// IJSVGGradient.m
// IJSVGExample
//
// Created by Curtis Hard on 03/09/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGGradient.h"
@implementation IJSVGGradient
@synthesize gradient, CGGradient;
@synthesize x1, x2, y1, y2;
@synthesize colorList = _colorList;
- (void)dealloc
{
(void)([x1 release]), x1 = nil;
(void)([x2 release]), x2 = nil;
(void)([y1 release]), y1 = nil;
(void)([y2 release]), y2 = nil;
(void)([gradient release]), gradient = nil;
(void)([_colorList release]), _colorList = nil;
if (CGGradient != nil) {
CGGradientRelease(CGGradient);
}
[super dealloc];
}
- (id)copyWithZone:(NSZone*)zone
{
IJSVGGradient* clone = [super copyWithZone:zone];
clone.gradient = [[self.gradient copy] autorelease];
return clone;
}
- (void)setColorList:(IJSVGColorList*)list
{
(void)([_colorList release]), _colorList = nil;
_colorList = list.retain;
if (CGGradient != nil) {
CGGradientRelease(CGGradient);
}
}
+ (CGFloat*)computeColorStopsFromString:(NSXMLElement*)element
colors:(NSArray**)someColors
{
// find each stop element
NSArray* stops = [element children];
NSMutableArray* colors = [[[NSMutableArray alloc] initWithCapacity:stops.count] autorelease];
CGFloat* stopsParams = (CGFloat*)malloc(stops.count * sizeof(CGFloat));
NSInteger i = 0;
for (NSXMLElement* stop in stops) {
// find the offset
CGFloat offset = [stop attributeForName:@"offset"].stringValue.floatValue;
if (offset > 1.f) {
offset /= 100.f;
}
stopsParams[i++] = offset;
// find the stop opacity
CGFloat stopOpacity = 1.f;
NSXMLNode* stopOpacityAttribute = [stop attributeForName:@"stop-opacity"];
if (stopOpacityAttribute != nil) {
stopOpacity = stopOpacityAttribute.stringValue.floatValue;
}
// find the stop color
NSString* scs = [stop attributeForName:@"stop-color"].stringValue;
NSColor* stopColor = [IJSVGColor colorFromString:scs];
if (stopColor != nil && stopOpacity != 1.f) {
stopColor = [IJSVGColor changeAlphaOnColor:stopColor
to:stopOpacity];
}
// compute any style that there was...
NSXMLNode* styleAttribute = [stop attributeForName:@"style"];
if (styleAttribute != nil) {
IJSVGStyle* style = [IJSVGStyle parseStyleString:styleAttribute.stringValue];
NSColor* color = [IJSVGColor colorFromString:[style property:@"stop-color"]];
// we have a color!
if (color != nil) {
// is there a stop opacity?
NSString* numberString = nil;
if ((numberString = [style property:@"stop-opacity"]) != nil) {
color = [IJSVGColor changeAlphaOnColor:color
to:numberString.floatValue];
} else {
color = [IJSVGColor changeAlphaOnColor:color
to:stopOpacity];
}
stopColor = color;
}
}
// default is black
if (stopColor == nil) {
stopColor = [IJSVGColor colorFromString:@"black"];
if (stopOpacity != 1.f) {
stopColor = [IJSVGColor changeAlphaOnColor:stopColor
to:stopOpacity];
}
}
// add the stop color
[(NSMutableArray*)colors addObject:stopColor];
}
*someColors = colors;
return stopsParams;
}
- (IJSVGColorList*)computedColorList
{
IJSVGColorList* sheet = [[[IJSVGColorList alloc] init] autorelease];
NSInteger num = self.gradient.numberOfColorStops;
for (NSInteger i = 0; i < num; i++) {
NSColor* color;
[self.gradient getColor:&color
location:nil
atIndex:i];
[sheet addColor:color];
}
return sheet;
}
- (CGGradientRef)CGGradient
{
// store it in the cache
if (CGGradient != nil) {
return CGGradient;
}
// actually create the gradient
NSInteger num = self.gradient.numberOfColorStops;
CGFloat* locations = malloc(sizeof(CGFloat) * num);
CFMutableArrayRef colors = CFArrayCreateMutable(kCFAllocatorDefault, (CFIndex)num,
&kCFTypeArrayCallBacks);
for (NSInteger i = 0; i < num; i++) {
NSColor* color;
[self.gradient getColor:&color
location:&locations[i]
atIndex:i];
if (_colorList != nil) {
color = [_colorList proposedColorForColor:color];
}
CFArrayAppendValue(colors, color.CGColor);
}
CGGradientRef result = CGGradientCreateWithColors(self.gradient.colorSpace.CGColorSpace,
colors, locations);
CFRelease(colors);
free(locations);
return CGGradient = result;
}
- (void)drawInContextRef:(CGContextRef)ctx
objectRect:(NSRect)objectRect
absoluteTransform:(CGAffineTransform)absoluteTransform
viewPort:(CGRect)viewBox
{
}
- (void)_debugStart:(CGPoint)startPoint
end:(CGPoint)endPoint
context:(CGContextRef)ctx
{
CGContextSaveGState(ctx);
CGContextSetStrokeColorWithColor(ctx, NSColor.blackColor.CGColor);
CGContextSetLineWidth(ctx, 1.f);
CGContextMoveToPoint(ctx, startPoint.x, startPoint.y);
CGContextAddLineToPoint(ctx, endPoint.x, endPoint.y);
CGContextStrokePath(ctx);
}
@end
@@ -6,18 +6,17 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGNode.h"
#import "IJSVGPath.h"
#import <Foundation/Foundation.h>
@interface IJSVGGroup : IJSVGNode {
NSMutableArray * children;
NSMutableArray* children;
}
- (void)addChild:(id)child;
- (NSArray *)children;
- (NSArray*)children;
- (void)purgeChildren;
@end
@@ -12,14 +12,13 @@
- (void)dealloc
{
[children release], children = nil;
(void)([children release]), children = nil;
[super dealloc];
}
- (id)init
{
if( ( self = [super init] ) != nil )
{
if ((self = [super init]) != nil) {
children = [[NSMutableArray alloc] init];
}
return self;
@@ -30,13 +29,12 @@
children = [[NSMutableArray alloc] init];
}
- (id)copyWithZone:(NSZone *)zone
- (id)copyWithZone:(NSZone*)zone
{
IJSVGGroup * node = [super copyWithZone:zone];
IJSVGGroup* node = [super copyWithZone:zone];
[node prepareFromCopy];
for( IJSVGNode * childNode in self.children )
{
for (IJSVGNode* childNode in self.children) {
childNode = [[childNode copy] autorelease];
childNode.parentNode = node;
[node addChild:childNode];
@@ -51,18 +49,18 @@
- (void)addChild:(id)child
{
if( child != nil )
if (child != nil)
[children addObject:child];
}
- (NSArray *)children
- (NSArray*)children
{
return children;
}
- (NSString *)description
- (NSString*)description
{
return [NSString stringWithFormat:@"%@ - %ld",[super description],self.children.count];
return [NSString stringWithFormat:@"%@ - %@", [super description], self.children];
}
@end
@@ -6,22 +6,21 @@
// Copyright © 2016 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGNode.h"
#import <Foundation/Foundation.h>
@class IJSVGPath;
@interface IJSVGImage : IJSVGNode {
NSImage * image;
NSImage* image;
CGImageRef CGImage;
IJSVGPath * imagePath;
IJSVGPath* imagePath;
}
- (CGImageRef)CGImage;
- (void)drawInContextRef:(CGContextRef)context
path:(IJSVGPath *)path;
- (void)loadFromBase64EncodedString:(NSString *)encodedString;
path:(IJSVGPath*)path;
- (void)loadFromBase64EncodedString:(NSString*)encodedString;
@end
@@ -14,30 +14,36 @@
- (void)dealloc
{
CGImageRelease(CGImage), CGImage = nil;
[imagePath release], imagePath = nil;
[image release], image = nil;
(void)(CGImageRelease(CGImage)), CGImage = nil;
(void)([imagePath release]), imagePath = nil;
(void)([image release]), image = nil;
[super dealloc];
}
- (void)loadFromBase64EncodedString:(NSString *)encodedString
- (void)loadFromBase64EncodedString:(NSString*)encodedString
{
NSURL * URL = [NSURL URLWithString:encodedString];
NSData * data = [NSData dataWithContentsOfURL:URL];
// no data, jsut ignore...invalid probably
if(data == nil) {
if ([encodedString hasPrefix:@"data:"]) {
encodedString = [encodedString stringByReplacingOccurrencesOfString:@"\\s+"
withString:@""
options:NSRegularExpressionSearch
range:NSMakeRange(0, encodedString.length)];
}
NSURL* URL = [NSURL URLWithString:encodedString];
NSData* data = [NSData dataWithContentsOfURL:URL];
// no data, just ignore...invalid probably
if (data == nil) {
return;
}
// set the image against the container
NSImage * anImage = [[[NSImage alloc] initWithData:data] autorelease];
NSImage* anImage = [[[NSImage alloc] initWithData:data] autorelease];
[self setImage:anImage];
}
- (IJSVGPath *)path
- (IJSVGPath*)path
{
if(imagePath == nil) {
if (imagePath == nil) {
// lazy load the path as it might not be needed
imagePath = [[IJSVGPath alloc] init];
[imagePath.path appendBezierPathWithRect:NSMakeRect(0.f, 0.f, self.width.value, self.height.value)];
@@ -46,23 +52,23 @@
return imagePath;
}
- (void)setImage:(NSImage *)anImage
- (void)setImage:(NSImage*)anImage
{
if(image != nil) {
[image release], image = nil;
if (image != nil) {
(void)([image release]), image = nil;
}
image = [anImage retain];
if(CGImage != nil) {
if (CGImage != nil) {
CGImageRelease(CGImage);
CGImage = nil;
}
NSRect rect = NSMakeRect( 0.f, 0.f, self.width.value, self.height.value);
NSRect rect = NSMakeRect(0.f, 0.f, self.width.value, self.height.value);
CGImage = [image CGImageForProposedRect:&rect
context:nil
hints:nil];
// be sure to retain (some reason this is required in Xcode 8 beta 5?)
CGImageRetain(CGImage);
}
@@ -73,29 +79,29 @@
}
- (void)drawInContextRef:(CGContextRef)context
path:(IJSVGPath *)path
path:(IJSVGPath*)path
{
// run the transforms
// draw the image
if(self.width.value == 0.f || self.height.value == 0.f) {
if (self.width.value == 0.f || self.height.value == 0.f) {
return;
}
// make sure path is set
if(path == nil) {
if (path == nil) {
path = [self path];
}
CGRect rect = path.path.bounds;
CGRect bounds = CGRectMake( 0.f, 0.f, rect.size.width, rect.size.height);
CGRect bounds = CGRectMake(0.f, 0.f, rect.size.width, rect.size.height);
// save the state of the context
CGContextSaveGState(context);
{
// flip the coordinates
CGContextTranslateCTM(context, rect.origin.x, (rect.origin.y)+rect.size.height);
CGContextTranslateCTM(context, rect.origin.x, (rect.origin.y) + rect.size.height);
CGContextScaleCTM(context, 1.f, -1.f);
CGContextDrawImage( context, bounds, CGImage);
CGContextDrawImage(context, bounds, CGImage);
}
CGContextRestoreGState(context);
}
@@ -6,14 +6,12 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGGradient.h"
#import <Foundation/Foundation.h>
@interface IJSVGLinearGradient : IJSVGGradient
+ (NSGradient *)parseGradient:(NSXMLElement *)element
gradient:(IJSVGLinearGradient *)aGradient
startPoint:(CGPoint *)startPoint
endPoint:(CGPoint *)endPoint;
+ (NSGradient*)parseGradient:(NSXMLElement*)element
gradient:(IJSVGLinearGradient*)aGradient;
@end
@@ -0,0 +1,84 @@
//
// IJSVGGradient.m
// IJSVGExample
//
// Created by Curtis Hard on 03/09/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGLinearGradient.h"
#import "IJSVGUtils.h"
@implementation IJSVGLinearGradient
+ (NSGradient*)parseGradient:(NSXMLElement*)element
gradient:(IJSVGLinearGradient*)aGradient
{
// just ask unit for the value
NSString* x1 = ([element attributeForName:@"x1"].stringValue ?: @"0");
NSString* x2 = ([element attributeForName:@"x2"].stringValue ?: @"100%");
NSString* y1 = ([element attributeForName:@"y1"].stringValue ?: @"0");
NSString* y2 = ([element attributeForName:@"y2"].stringValue ?: @"0");
aGradient.x1 = [IJSVGGradientUnitLength unitWithString:x1 fromUnitType:aGradient.units];
aGradient.x2 = [IJSVGGradientUnitLength unitWithString:x2 fromUnitType:aGradient.units];
aGradient.y1 = [IJSVGGradientUnitLength unitWithString:y1 fromUnitType:aGradient.units];
aGradient.y2 = [IJSVGGradientUnitLength unitWithString:y2 fromUnitType:aGradient.units];
// compute the color stops and colours
NSArray* colors = nil;
CGFloat* stopsParams = [self.class computeColorStopsFromString:element
colors:&colors];
// create the gradient with the colours
NSGradient* grad = [[NSGradient alloc] initWithColors:colors
atLocations:stopsParams
colorSpace:IJSVGColor.defaultColorSpace];
free(stopsParams);
return [grad autorelease];
}
- (void)drawInContextRef:(CGContextRef)ctx
objectRect:(NSRect)objectRect
absoluteTransform:(CGAffineTransform)absoluteTransform
viewPort:(CGRect)viewBox
{
BOOL inUserSpace = self.units == IJSVGUnitUserSpaceOnUse;
CGPoint gradientStartPoint = CGPointZero;
CGPoint gradientEndPoint = CGPointZero;
CGAffineTransform selfTransform = IJSVGConcatTransforms(self.transforms);
CGRect boundingBox = inUserSpace ? viewBox : objectRect;
// make sure we apply the absolute position to
// transform us back into the correct space
if (inUserSpace == YES) {
CGContextConcatCTM(ctx, absoluteTransform);
}
CGFloat width = CGRectGetWidth(boundingBox);
CGFloat height = CGRectGetHeight(boundingBox);
gradientStartPoint = CGPointMake([self.x1 computeValue:width],
[self.y1 computeValue:height]);
gradientEndPoint = CGPointMake([self.x2 computeValue:width],
[self.y2 computeValue:height]);
// transform the context
CGContextConcatCTM(ctx, selfTransform);
// draw the gradient
CGGradientDrawingOptions options = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
CGContextDrawLinearGradient(ctx, self.CGGradient, gradientStartPoint,
gradientEndPoint, options);
#ifdef IJSVG_DEBUG
[self _debugStart:gradientStartPoint
end:gradientEndPoint
context:ctx];
#endif
}
@end
@@ -0,0 +1,147 @@
//
// IJSVGNode.h
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGStyle.h"
#import "IJSVGUnitLength.h"
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
@class IJSVG;
@class IJSVGGroup;
@class IJSVGDef;
@class IJSVGGradient;
@class IJSVGGroup;
@class IJSVGPattern;
@class IJSVGTransform;
typedef NS_ENUM(NSInteger, IJSVGNodeType) {
IJSVGNodeTypeGroup,
IJSVGNodeTypePath,
IJSVGNodeTypeDef,
IJSVGNodeTypePolygon,
IJSVGNodeTypePolyline,
IJSVGNodeTypeRect,
IJSVGNodeTypeLine,
IJSVGNodeTypeCircle,
IJSVGNodeTypeEllipse,
IJSVGNodeTypeUse,
IJSVGNodeTypeLinearGradient,
IJSVGNodeTypeRadialGradient,
IJSVGNodeTypeClipPath,
IJSVGNodeTypeFont,
IJSVGNodeTypeGlyph,
IJSVGNodeTypeMask,
IJSVGNodeTypeImage,
IJSVGNodeTypePattern,
IJSVGNodeTypeSVG,
IJSVGNodeTypeText,
IJSVGNodeTypeTextSpan,
IJSVGNodeTypeStyle,
IJSVGNodeTypeSwitch,
IJSVGNodeTypeNotFound,
};
typedef NS_ENUM(NSInteger, IJSVGWindingRule) {
IJSVGWindingRuleNonZero,
IJSVGWindingRuleEvenOdd,
IJSVGWindingRuleInherit
};
typedef NS_ENUM(NSInteger, IJSVGLineCapStyle) {
IJSVGLineCapStyleNone,
IJSVGLineCapStyleButt,
IJSVGLineCapStyleRound,
IJSVGLineCapStyleSquare,
IJSVGLineCapStyleInherit
};
typedef NS_ENUM(NSInteger, IJSVGLineJoinStyle) {
IJSVGLineJoinStyleNone,
IJSVGLineJoinStyleMiter,
IJSVGLineJoinStyleRound,
IJSVGLineJoinStyleBevel,
IJSVGLineJoinStyleInherit
};
typedef NS_OPTIONS(NSInteger, IJSVGFontTraits) {
IJSVGFontTraitNone = 1 << 0,
IJSVGFontTraitBold = 1 << 1,
IJSVGFontTraitItalic = 1 << 2
};
typedef NS_ENUM(NSInteger, IJSVGBlendMode) {
IJSVGBlendModeNormal = kCGBlendModeNormal,
IJSVGBlendModeMultiply = kCGBlendModeMultiply,
IJSVGBlendModeScreen = kCGBlendModeScreen,
IJSVGBlendModeOverlay = kCGBlendModeOverlay,
IJSVGBlendModeDarken = kCGBlendModeDarken,
IJSVGBlendModeLighten = kCGBlendModeLighten,
IJSVGBlendModeColorDodge = kCGBlendModeColorDodge,
IJSVGBlendModeColorBurn = kCGBlendModeColorBurn,
IJSVGBlendModeHardLight = kCGBlendModeHardLight,
IJSVGBlendModeSoftLight = kCGBlendModeSoftLight,
IJSVGBlendModeDifference = kCGBlendModeDifference,
IJSVGBlendModeExclusion = kCGBlendModeExclusion,
IJSVGBlendModeHue = kCGBlendModeHue,
IJSVGBlendModeSaturation = kCGBlendModeSaturation,
IJSVGBlendModeColor = kCGBlendModeColor,
IJSVGBlendModeLuminosity = kCGBlendModeLuminosity
};
static CGFloat IJSVGInheritedFloatValue = -99.9999991;
@interface IJSVGNode : NSObject <NSCopying>
@property (nonatomic, assign) IJSVGNodeType type;
@property (nonatomic, copy) NSString* name;
@property (nonatomic, copy) NSString* className;
@property (nonatomic, retain) NSArray* classNameList;
@property (nonatomic, copy) NSString* unicode;
@property (nonatomic, assign) BOOL shouldRender;
@property (nonatomic, assign) BOOL usesDefaultFillColor;
@property (nonatomic, retain) IJSVGUnitLength* x;
@property (nonatomic, retain) IJSVGUnitLength* y;
@property (nonatomic, retain) IJSVGUnitLength* width;
@property (nonatomic, retain) IJSVGUnitLength* height;
@property (nonatomic, retain) IJSVGUnitLength* opacity;
@property (nonatomic, retain) IJSVGUnitLength* fillOpacity;
@property (nonatomic, retain) IJSVGUnitLength* strokeOpacity;
@property (nonatomic, retain) IJSVGUnitLength* strokeWidth;
@property (nonatomic, retain) NSColor* fillColor;
@property (nonatomic, retain) NSColor* strokeColor;
@property (nonatomic, copy) NSString* identifier;
@property (nonatomic, assign) IJSVGNode* parentNode;
@property (nonatomic, assign) IJSVGNode* intermediateParentNode;
@property (nonatomic, retain) IJSVGGroup* clipPath;
@property (nonatomic, retain) IJSVGGroup* mask;
@property (nonatomic, assign) IJSVGWindingRule windingRule;
@property (nonatomic, assign) IJSVGLineCapStyle lineCapStyle;
@property (nonatomic, assign) IJSVGLineJoinStyle lineJoinStyle;
@property (nonatomic, retain) NSArray<IJSVGTransform*>* transforms;
@property (nonatomic, retain) IJSVGDef* def;
@property (nonatomic, retain) IJSVGGradient* fillGradient;
@property (nonatomic, retain) IJSVGPattern* fillPattern;
@property (nonatomic, retain) IJSVGGradient* strokeGradient;
@property (nonatomic, retain) IJSVGPattern* strokePattern;
@property (nonatomic, assign) CGFloat* strokeDashArray;
@property (nonatomic, assign) NSInteger strokeDashArrayCount;
@property (nonatomic, retain) IJSVGUnitLength* strokeDashOffset;
@property (nonatomic, retain) IJSVG* svg;
@property (nonatomic, assign) IJSVGUnitType contentUnits;
@property (nonatomic, assign) IJSVGUnitType units;
@property (nonatomic, assign) IJSVGBlendMode blendMode;
+ (IJSVGNodeType)typeForString:(NSString*)string
kind:(NSXMLNodeKind)kind;
- (void)applyPropertiesFromNode:(IJSVGNode*)node;
- (id)initWithDef:(BOOL)flag;
- (void)addDef:(IJSVGNode*)aDef;
- (IJSVGDef*)defForID:(NSString*)anID;
@end
@@ -6,8 +6,9 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGNode.h"
#import "IJSVGDef.h"
#import "IJSVGNode.h"
#import "IJSVGUtils.h"
@implementation IJSVGNode
@@ -29,11 +30,14 @@
@synthesize opacity;
@synthesize identifier;
@synthesize parentNode;
@synthesize intermediateParentNode;
@synthesize transforms;
@synthesize windingRule;
@synthesize def;
@synthesize fillGradient;
@synthesize fillPattern;
@synthesize strokeGradient;
@synthesize strokePattern;
@synthesize clipPath;
@synthesize lineCapStyle;
@synthesize lineJoinStyle;
@@ -45,182 +49,208 @@
@synthesize mask;
@synthesize units;
@synthesize contentUnits;
@synthesize blendMode;
- (void)dealloc
{
free(strokeDashArray);
[x release], x = nil;
[y release], y = nil;
[width release], width = nil;
[height release], height = nil;
[opacity release], opacity = nil;
[fillOpacity release], fillOpacity = nil;
[strokeOpacity release], strokeOpacity = nil;
[strokeWidth release], strokeWidth = nil;
[strokeDashOffset release], strokeDashOffset = nil;
[unicode release], unicode = nil;
[fillGradient release], fillGradient = nil;
[transforms release], transforms = nil;
[fillColor release], fillColor = nil;
[strokeColor release], strokeColor = nil;
[identifier release], identifier = nil;
[def release], def = nil;
[name release], name = nil;
[className release], className = nil;
[classNameList release], classNameList = nil;
[fillPattern release], fillPattern = nil;
[clipPath release], clipPath = nil;
[svg release], svg = nil;
[mask release], mask = nil;
(void)([x release]), x = nil;
(void)([y release]), y = nil;
(void)([width release]), width = nil;
(void)([height release]), height = nil;
(void)([opacity release]), opacity = nil;
(void)([fillOpacity release]), fillOpacity = nil;
(void)([strokeOpacity release]), strokeOpacity = nil;
(void)([strokeWidth release]), strokeWidth = nil;
(void)([strokeDashOffset release]), strokeDashOffset = nil;
(void)([unicode release]), unicode = nil;
(void)([fillGradient release]), fillGradient = nil;
(void)([strokeGradient release]), strokeGradient = nil;
(void)([strokePattern release]), strokePattern = nil;
(void)([transforms release]), transforms = nil;
(void)([fillColor release]), fillColor = nil;
(void)([strokeColor release]), strokeColor = nil;
(void)([identifier release]), identifier = nil;
(void)([def release]), def = nil;
(void)([name release]), name = nil;
(void)([className release]), className = nil;
(void)([classNameList release]), classNameList = nil;
(void)([fillPattern release]), fillPattern = nil;
(void)([clipPath release]), clipPath = nil;
(void)([svg release]), svg = nil;
(void)([mask release]), mask = nil;
[super dealloc];
}
+ (IJSVGNodeType)typeForString:(NSString *)string
+ (IJSVGNodeType)typeForString:(NSString*)string
kind:(NSXMLNodeKind)kind
{
string = [string lowercaseString];
if( [string isEqualToString:@"defs"] )
if ([string isEqualToString:@"style"])
return IJSVGNodeTypeStyle;
if ([string isEqualToString:@"switch"])
return IJSVGNodeTypeSwitch;
if ([string isEqualToString:@"defs"])
return IJSVGNodeTypeDef;
if( [string isEqualToString:@"g"] )
if ([string isEqualToString:@"g"])
return IJSVGNodeTypeGroup;
if( [string isEqualToString:@"path"] )
if ([string isEqualToString:@"path"])
return IJSVGNodeTypePath;
if( [string isEqualToString:@"polygon"] )
if ([string isEqualToString:@"polygon"])
return IJSVGNodeTypePolygon;
if( [string isEqualToString:@"polyline"] )
if ([string isEqualToString:@"polyline"])
return IJSVGNodeTypePolyline;
if( [string isEqualToString:@"rect"] )
if ([string isEqualToString:@"rect"])
return IJSVGNodeTypeRect;
if( [string isEqualToString:@"line"] )
if ([string isEqualToString:@"line"])
return IJSVGNodeTypeLine;
if( [string isEqualToString:@"circle"] )
if ([string isEqualToString:@"circle"])
return IJSVGNodeTypeCircle;
if( [string isEqualToString:@"ellipse"] )
if ([string isEqualToString:@"ellipse"])
return IJSVGNodeTypeEllipse;
if( [string isEqualToString:@"use"] )
if ([string isEqualToString:@"use"])
return IJSVGNodeTypeUse;
if( [string isEqualToString:@"lineargradient"] )
if ([string isEqualToString:@"lineargradient"])
return IJSVGNodeTypeLinearGradient;
if( [string isEqualToString:@"radialgradient"] )
if ([string isEqualToString:@"radialgradient"])
return IJSVGNodeTypeRadialGradient;
if( [string isEqualToString:@"glyph"] )
if ([string isEqualToString:@"glyph"])
return IJSVGNodeTypeGlyph;
if( [string isEqualToString:@"font"] )
if ([string isEqualToString:@"font"])
return IJSVGNodeTypeFont;
if( [string isEqualToString:@"clippath"] )
if ([string isEqualToString:@"clippath"])
return IJSVGNodeTypeClipPath;
if( [string isEqualToString:@"mask"] )
if ([string isEqualToString:@"mask"])
return IJSVGNodeTypeMask;
if( [string isEqualToString:@"image"] )
if ([string isEqualToString:@"image"])
return IJSVGNodeTypeImage;
if([string isEqualToString:@"pattern"])
if ([string isEqualToString:@"pattern"])
return IJSVGNodeTypePattern;
if([string isEqualToString:@"svg"])
if ([string isEqualToString:@"svg"])
return IJSVGNodeTypeSVG;
if([string isEqualToString:@"text"])
if ([string isEqualToString:@"text"])
return IJSVGNodeTypeText;
if([string isEqualToString:@"tspan"] || kind == NSXMLTextKind) {
if ([string isEqualToString:@"tspan"] || kind == NSXMLTextKind) {
return IJSVGNodeTypeTextSpan;
}
// are we commong HTML? - if so just treat as a group
if (IJSVGIsCommonHTMLElementName(string) == YES) {
return IJSVGNodeTypeGroup;
}
return IJSVGNodeTypeNotFound;
}
- (id)init
{
if( ( self = [self initWithDef:YES] ) != nil )
{
if ((self = [self initWithDef:YES]) != nil) {
self.opacity = [IJSVGUnitLength unitWithFloat:1];
}
return self;
}
- (void)applyPropertiesFromNode:(IJSVGNode *)node
- (void)applyPropertiesFromNode:(IJSVGNode*)node
{
self.name = node.name;
self.type = node.type;
self.unicode = node.unicode;
self.className = node.className;
self.classNameList = node.classNameList;
self.x = node.x;
self.y = node.y;
self.width = node.width;
self.height = node.height;
self.fillGradient = node.fillGradient;
self.fillPattern = node.fillPattern;
self.strokeGradient = node.strokeGradient;
self.strokePattern = node.strokePattern;
self.fillColor = node.fillColor;
self.strokeColor = node.strokeColor;
self.clipPath = node.clipPath;
self.units = node.units;
self.contentUnits = node.contentUnits;
self.opacity = node.opacity;
self.strokeWidth = node.strokeWidth;
self.fillOpacity = node.fillOpacity;
self.strokeOpacity = node.strokeOpacity;
self.identifier = node.identifier;
self.usesDefaultFillColor = node.usesDefaultFillColor;
self.transforms = node.transforms;
self.def = node.def;
self.windingRule = node.windingRule;
self.lineCapStyle = node.lineCapStyle;
self.lineJoinStyle = node.lineJoinStyle;
self.parentNode = node.parentNode;
self.shouldRender = node.shouldRender;
self.blendMode = node.blendMode;
// dash array needs physical memory copied
CGFloat * nStrokeDashArray = (CGFloat *)malloc(node.strokeDashArrayCount*sizeof(CGFloat));
memcpy( self.strokeDashArray, nStrokeDashArray, node.strokeDashArrayCount*sizeof(CGFloat));
CGFloat* nStrokeDashArray = (CGFloat*)malloc(node.strokeDashArrayCount * sizeof(CGFloat));
memcpy(self.strokeDashArray, nStrokeDashArray, node.strokeDashArrayCount * sizeof(CGFloat));
self.strokeDashArray = nStrokeDashArray;
self.strokeDashArrayCount = node.strokeDashArrayCount;
self.strokeDashOffset = node.strokeDashOffset;
}
- (id)copyWithZone:(NSZone *)zone
- (id)copyWithZone:(NSZone*)zone
{
IJSVGNode * node = [[self class] allocWithZone:zone];
IJSVGNode* node = [self.class allocWithZone:zone];
[node applyPropertiesFromNode:self];
return node;
}
- (id)initWithDef:(BOOL)flag
{
if( ( self = [super init] ) != nil )
{
if ((self = [super init]) != nil) {
self.opacity = [IJSVGUnitLength unitWithFloat:0.f];
self.fillOpacity = [IJSVGUnitLength unitWithFloat:1.f];
self.strokeOpacity = [IJSVGUnitLength unitWithFloat:1.f];
self.fillOpacity.inherit = YES;
self.strokeDashOffset = [IJSVGUnitLength unitWithFloat:0.f];
self.shouldRender = YES;
self.strokeWidth = [IJSVGUnitLength unitWithFloat:0.f];
self.strokeOpacity = [IJSVGUnitLength unitWithFloat:1.f];
self.strokeOpacity.inherit = YES;
self.strokeWidth = [IJSVGUnitLength unitWithFloat:1.f];
self.strokeWidth.inherit = YES;
self.windingRule = IJSVGWindingRuleInherit;
self.lineCapStyle = IJSVGLineCapStyleInherit;
self.lineJoinStyle = IJSVGLineJoinStyleInherit;
self.units = IJSVGUnitInherit;
if( flag ) {
self.blendMode = IJSVGBlendModeNormal;
if (flag) {
def = [[IJSVGDef alloc] init];
}
}
return self;
}
- (IJSVGDef *)defForID:(NSString *)anID
- (IJSVGDef*)defForID:(NSString*)anID
{
IJSVGDef * aDef = nil;
if( (aDef = [def defForID:anID]) != nil )
IJSVGDef* aDef = nil;
if ((aDef = [def defForID:anID]) != nil) {
return aDef;
if( parentNode != nil )
}
if (parentNode != nil) {
return [parentNode defForID:anID];
}
return nil;
}
- (void)addDef:(IJSVGNode *)aDef
- (void)addDef:(IJSVGNode*)aDef
{
[def addDef:aDef];
}
@@ -228,7 +258,7 @@
// winding rule can inherit..
- (IJSVGWindingRule)windingRule
{
if( windingRule == IJSVGWindingRuleInherit && parentNode != nil ) {
if (windingRule == IJSVGWindingRuleInherit && parentNode != nil) {
return parentNode.windingRule;
}
return windingRule;
@@ -236,29 +266,29 @@
- (IJSVGLineCapStyle)lineCapStyle
{
if( lineCapStyle == IJSVGLineCapStyleInherit )
{
if( parentNode != nil )
if (lineCapStyle == IJSVGLineCapStyleInherit) {
if (parentNode != nil) {
return parentNode.lineCapStyle;
}
}
return lineCapStyle;
}
- (IJSVGLineJoinStyle)lineJoinStyle
{
if( lineJoinStyle == IJSVGLineJoinStyleInherit )
{
if( parentNode != nil )
if (lineJoinStyle == IJSVGLineJoinStyleInherit) {
if (parentNode != nil) {
return parentNode.lineJoinStyle;
}
}
return lineJoinStyle;
}
// these are all recursive, so go up the chain
// if they dont exist on this specific node
- (IJSVGUnitLength *)opacity
- (IJSVGUnitLength*)opacity
{
if(opacity.inherit && parentNode != nil) {
if (opacity.inherit && parentNode != nil) {
return parentNode.opacity;
}
return opacity;
@@ -266,9 +296,9 @@
// these are all recursive, so go up the chain
// if they dont exist on this specific node
- (IJSVGUnitLength *)fillOpacity
- (IJSVGUnitLength*)fillOpacity
{
if(fillOpacity.inherit && parentNode != nil) {
if (fillOpacity.inherit && parentNode != nil) {
return parentNode.fillOpacity;
}
return fillOpacity;
@@ -276,9 +306,9 @@
// these are all recursive, so go up the chain
// if they dont exist on this specific node
- (IJSVGUnitLength *)strokeWidth
- (IJSVGUnitLength*)strokeWidth
{
if(strokeWidth.inherit && parentNode != nil) {
if (strokeWidth.inherit && parentNode != nil) {
return parentNode.strokeWidth;
}
return strokeWidth;
@@ -286,18 +316,18 @@
// these are all recursive, so go up the chain
// if they dont exist on this specific node
- (NSColor *)strokeColor
- (NSColor*)strokeColor
{
if( strokeColor != nil )
if (strokeColor != nil)
return strokeColor;
if( strokeColor == nil && parentNode != nil )
if (strokeColor == nil && parentNode != nil)
return parentNode.strokeColor;
return nil;
}
- (IJSVGUnitLength *)strokeOpacity
- (IJSVGUnitLength*)strokeOpacity
{
if(strokeOpacity.inherit && parentNode != nil) {
if (strokeOpacity.inherit && parentNode != nil) {
return parentNode.strokeOpacity;
}
return strokeOpacity;
@@ -305,18 +335,19 @@
// even though the spec explicity states fill color
// must be on the path, it can also be on the
- (NSColor *)fillColor
- (NSColor*)fillColor
{
if( fillColor == nil && parentNode != nil )
if (fillColor == nil && parentNode != nil) {
return parentNode.fillColor;
}
return fillColor;
}
// these are all recursive, so go up the chain
// if they dont exist on this specific node
- (IJSVGGradient *)fillGradient
- (IJSVGGradient*)fillGradient
{
if(fillGradient == nil && parentNode != nil) {
if (fillGradient == nil && parentNode != nil) {
return parentNode.fillGradient;
}
return fillGradient;
@@ -324,12 +355,32 @@
// these are all recursive, so go up the chain
// if they dont exist on this specific node
- (IJSVGPattern *)fillPattern
- (IJSVGPattern*)fillPattern
{
if(fillPattern == nil && parentNode != nil) {
if (fillPattern == nil && parentNode != nil) {
return parentNode.fillPattern;
}
return fillPattern;
}
// these are all recursive, so go up the chain
// if they dont exist on this specific node
- (IJSVGGradient*)strokeGradient
{
if (strokeGradient == nil && parentNode != nil) {
return parentNode.strokeGradient;
}
return strokeGradient;
}
// these are all recursive, so go up the chain
// if they dont exist on this specific node
- (IJSVGPattern*)strokePattern
{
if (strokePattern == nil && parentNode != nil) {
return parentNode.strokePattern;
}
return strokePattern;
}
@end
@@ -0,0 +1,44 @@
//
// IJSVGPath.h
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGBezierPathAdditions.h"
#import "IJSVGNode.h"
#import <Foundation/Foundation.h>
@class IJSVGGroup;
typedef NS_ENUM(NSInteger, IJSVGPrimitivePathType) {
IJSVGPrimitivePathTypePath,
IJSVGPrimitivePathTypeRect,
IJSVGPrimitivePathTypePolygon,
IJSVGPrimitivePathTypePolyLine,
IJSVGPrimitivePathTypeCircle,
IJSVGPrimitivePathTypeEllipse,
IJSVGPrimitivePathTypeLine
};
@interface IJSVGPath : IJSVGNode {
NSBezierPath* path;
NSBezierPath* subpath;
CGPoint lastControlPoint;
}
@property (nonatomic, assign) IJSVGPrimitivePathType primitiveType;
@property (nonatomic, readonly) NSBezierPath* path;
@property (nonatomic, readonly) NSBezierPath* subpath;
@property (nonatomic, assign) CGPoint lastControlPoint;
@property (nonatomic, readonly) CGPathRef CGPath;
- (NSBezierPath*)currentSubpath;
- (void)close;
- (NSPoint)currentPoint;
- (void)overwritePath:(NSBezierPath*)aPath;
- (CGPathRef)newPathRefByAutoClosingPath:(BOOL)autoClose;
@end
@@ -0,0 +1,140 @@
//
// IJSVGPath.m
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGGroup.h"
#import "IJSVGPath.h"
@implementation IJSVGPath
@synthesize path;
@synthesize subpath;
@synthesize lastControlPoint;
@synthesize CGPath = _CGPath;
@synthesize primitiveType = _primitiveType;
- (void)dealloc
{
if(_CGPath != nil) {
CGPathRelease(_CGPath);
_CGPath = nil;
}
if (subpath != nil) {
(void)([subpath release]), subpath = nil;
}
[super dealloc];
}
- (id)init
{
if ((self = [super init]) != nil) {
_primitiveType = IJSVGPrimitivePathTypePath;
subpath = NSBezierPath.bezierPath.retain;
path = subpath; // for legacy use
}
return self;
}
- (id)copyWithZone:(NSZone*)zone
{
IJSVGPath* node = [super copyWithZone:zone];
[node overwritePath:self.path];
return node;
}
- (NSPoint)currentPoint
{
return [subpath currentPoint];
}
- (NSBezierPath*)currentSubpath
{
return subpath;
}
- (void)close
{
[subpath closePath];
}
- (CGPathRef)CGPath
{
if(_CGPath == nil) {
_CGPath = [self newPathRefByAutoClosingPath:NO];
}
return _CGPath;
}
- (void)overwritePath:(NSBezierPath*)aPath
{
(void)([subpath release]), subpath = nil;
subpath = [aPath retain];
path = subpath;
}
- (CGPathRef)newPathRefByAutoClosingPath:(BOOL)autoClose
{
NSInteger i = 0;
NSInteger numElements = self.path.elementCount;
NSBezierPath* bezPath = self.path;
// nothing to return
if (numElements == 0) {
return NULL;
}
CGMutablePathRef aPath = CGPathCreateMutable();
NSPoint points[3];
BOOL didClosePath = YES;
for (i = 0; i < numElements; i++) {
switch ([bezPath elementAtIndex:i associatedPoints:points]) {
// move
case NSMoveToBezierPathElement: {
CGPathMoveToPoint(aPath, NULL, points[0].x, points[0].y);
break;
}
// line
case NSLineToBezierPathElement: {
CGPathAddLineToPoint(aPath, NULL, points[0].x, points[0].y);
didClosePath = NO;
break;
}
// curve
case NSCurveToBezierPathElement: {
CGPathAddCurveToPoint(aPath, NULL, points[0].x, points[0].y,
points[1].x, points[1].y,
points[2].x, points[2].y);
didClosePath = NO;
break;
}
// close
case NSClosePathBezierPathElement: {
CGPathCloseSubpath(aPath);
didClosePath = YES;
break;
}
}
}
if (!didClosePath && autoClose) {
CGPathCloseSubpath(aPath);
}
// create immutable and release
CGPathRef pathToReturn = CGPathCreateCopy(aPath);
CGPathRelease(aPath);
return pathToReturn;
}
@end
@@ -6,12 +6,11 @@
// Copyright © 2016 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGGroup.h"
#import "IJSVGImage.h"
#import <Foundation/Foundation.h>
@interface IJSVGPattern : IJSVGGroup {
}
@end
@@ -9,11 +9,10 @@
#import "IJSVGGroup.h"
@interface IJSVGText : IJSVGGroup {
NSString * text;
NSString* text;
}
@property (nonatomic, copy) NSString * text;
@property (nonatomic, copy) NSString* text;
@end
@@ -14,13 +14,13 @@
- (void)dealloc
{
[text release], text = nil;
(void)([text release]), text = nil;
[super dealloc];
}
- (IJSVGText *)copyWithZone:(NSZone *)zone
- (IJSVGText*)copyWithZone:(NSZone*)zone
{
IJSVGText * node = [super copyWithZone:zone];
IJSVGText* node = [super copyWithZone:zone];
node.text = self.text;
return node;
}
@@ -0,0 +1,131 @@
//
// IJSVGParser.h
// IconJar
//
// Created by Curtis Hard on 30/08/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGColor.h"
#import "IJSVGCommand.h"
#import "IJSVGDef.h"
#import "IJSVGError.h"
#import "IJSVGForeignObject.h"
#import "IJSVGGroup.h"
#import "IJSVGImage.h"
#import "IJSVGLinearGradient.h"
#import "IJSVGPath.h"
#import "IJSVGPattern.h"
#import "IJSVGRadialGradient.h"
#import "IJSVGStyleSheet.h"
#import "IJSVGText.h"
#import "IJSVGTransform.h"
#import "IJSVGUtils.h"
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
static NSString const* IJSVGAttributeViewBox = @"viewBox";
static NSString const* IJSVGAttributeID = @"id";
static NSString const* IJSVGAttributeClass = @"class";
static NSString const* IJSVGAttributeX = @"x";
static NSString const* IJSVGAttributeY = @"y";
static NSString const* IJSVGAttributeWidth = @"width";
static NSString const* IJSVGAttributeHeight = @"height";
static NSString const* IJSVGAttributeOpacity = @"opacity";
static NSString const* IJSVGAttributeStrokeOpacity = @"stroke-opacity";
static NSString const* IJSVGAttributeStrokeWidth = @"stroke-width";
static NSString const* IJSVGAttributeStrokeDashOffset = @"stroke-dashoffset";
static NSString const* IJSVGAttributeFillOpacity = @"fill-opacity";
static NSString const* IJSVGAttributeClipPath = @"clip-path";
static NSString const* IJSVGAttributeMask = @"mask";
static NSString const* IJSVGAttributeGradientUnits = @"gradientUnits";
static NSString const* IJSVGAttributeMaskUnits = @"maskUnits";
static NSString const* IJSVGAttributeMaskContentUnits = @"maskContentUnits";
static NSString const* IJSVGAttributeTransform = @"transform";
static NSString const* IJSVGAttributeGradientTransform = @"gradientTransform";
static NSString const* IJSVGAttributeUnicode = @"unicode";
static NSString const* IJSVGAttributeStrokeLineCap = @"stroke-linecap";
static NSString const* IJSVGAttributeLineJoin = @"stroke-linejoin";
static NSString const* IJSVGAttributeStroke = @"stroke";
static NSString const* IJSVGAttributeStrokeDashArray = @"stroke-dasharray";
static NSString const* IJSVGAttributeFill = @"fill";
static NSString const* IJSVGAttributeFillRule = @"fill-rule";
static NSString const* IJSVGAttributeBlendMode = @"mix-blend-mode";
static NSString const* IJSVGAttributeDisplay = @"display";
static NSString const* IJSVGAttributeStyle = @"style";
static NSString const* IJSVGAttributeD = @"d";
static NSString const* IJSVGAttributeXLink = @"xlink:href";
static NSString const* IJSVGAttributeX1 = @"x1";
static NSString const* IJSVGAttributeX2 = @"x2";
static NSString const* IJSVGAttributeY1 = @"y1";
static NSString const* IJSVGAttributeY2 = @"y2";
static NSString const* IJSVGAttributeRX = @"rx";
static NSString const* IJSVGAttributeRY = @"ry";
static NSString const* IJSVGAttributeCX = @"cx";
static NSString const* IJSVGAttributeCY = @"cy";
static NSString const* IJSVGAttributeR = @"r";
static NSString const* IJSVGAttributePoints = @"points";
@class IJSVGParser;
@protocol IJSVGParserDelegate <NSObject>
@optional
- (BOOL)svgParser:(IJSVGParser*)svg
shouldHandleForeignObject:(IJSVGForeignObject*)foreignObject;
- (void)svgParser:(IJSVGParser*)svg
handleForeignObject:(IJSVGForeignObject*)foreignObject
document:(NSXMLDocument*)document;
- (void)svgParser:(IJSVGParser*)svg
foundSubSVG:(IJSVG*)subSVG
withSVGString:(NSString*)string;
@end
@interface IJSVGParser : IJSVGGroup {
NSRect viewBox;
NSSize proposedViewSize;
@private
id<IJSVGParserDelegate> _delegate;
NSXMLDocument* _document;
NSMutableArray* _glyphs;
IJSVGStyleSheet* _styleSheet;
NSMutableArray* _parsedNodes;
NSMutableDictionary* _defNodes;
NSMutableDictionary* _baseDefNodes;
NSMutableArray<IJSVG*>* _svgs;
NSMutableArray* _definedGroups;
struct {
unsigned int shouldHandleForeignObject : 1;
unsigned int handleForeignObject : 1;
unsigned int handleSubSVG : 1;
} _respondsTo;
}
@property (nonatomic, readonly) NSRect viewBox;
@property (nonatomic, readonly) NSSize proposedViewSize;
+ (BOOL)isDataSVG:(NSData*)data;
- (id)initWithSVGString:(NSString*)string
error:(NSError**)error
delegate:(id<IJSVGParserDelegate>)delegate;
- (id)initWithFileURL:(NSURL*)aURL
error:(NSError**)error
delegate:(id<IJSVGParserDelegate>)delegate;
+ (IJSVGParser*)groupForFileURL:(NSURL*)aURL;
+ (IJSVGParser*)groupForFileURL:(NSURL*)aURL
delegate:(id<IJSVGParserDelegate>)delegate;
+ (IJSVGParser*)groupForFileURL:(NSURL*)aURL
error:(NSError**)error
delegate:(id<IJSVGParserDelegate>)delegate;
- (NSSize)size;
- (BOOL)isFont;
- (NSArray*)glyphs;
- (NSArray<IJSVG*>*)subSVGs:(BOOL)recursive;
@end
File diff suppressed because it is too large Load Diff
@@ -6,18 +6,18 @@
// Copyright © 2016 Curtis Hard. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import "IJSVGNode.h"
#import "IJSVGRenderingStyle.h"
#import <QuartzCore/QuartzCore.h>
@class IJSVGLayer;
@interface IJSVGLayerTree : NSObject {
}
@property (nonatomic, retain) NSColor * fillColor;
@property (nonatomic, retain) NSColor * strokeColor;
@property (nonatomic, assign) CGRect viewBox;
@property (nonatomic, retain) IJSVGRenderingStyle* style;
- (IJSVGLayer *)layerForNode:(IJSVGNode *)node;
- (IJSVGLayer*)layerForNode:(IJSVGNode*)node;
@end
@@ -0,0 +1,761 @@
//
// IJSVGLayerTree.m
// IJSVGExample
//
// Created by Curtis Hard on 29/12/2016.
// Copyright © 2016 Curtis Hard. All rights reserved.
//
#import "IJSVG.h"
#import "IJSVGGradient.h"
#import "IJSVGGradientLayer.h"
#import "IJSVGGroup.h"
#import "IJSVGGroupLayer.h"
#import "IJSVGImage.h"
#import "IJSVGImageLayer.h"
#import "IJSVGLayer.h"
#import "IJSVGLayerTree.h"
#import "IJSVGPath.h"
#import "IJSVGPattern.h"
#import "IJSVGPatternLayer.h"
#import "IJSVGShapeLayer.h"
#import "IJSVGStrokeLayer.h"
#import "IJSVGText.h"
#import "IJSVGTransform.h"
#import "IJSVGUtils.h"
@implementation IJSVGLayerTree
@synthesize viewBox;
@synthesize style = _style;
- (void)dealloc
{
(void)([_style release]), _style = nil;
[super dealloc];
}
- (id)init
{
if ((self = [super init]) != nil) {
}
return self;
}
- (IJSVGLayer*)layerForNode:(IJSVGNode*)node
{
IJSVGLayer* layer = nil;
// is there a sub SVG?
if ([node isKindOfClass:[IJSVGPath class]]) {
// path
layer = [self layerForPath:(IJSVGPath*)node];
} else if ([node isKindOfClass:[IJSVGGroup class]]) {
// group
layer = [self layerForGroup:(IJSVGGroup*)node];
} else if ([node isKindOfClass:[IJSVGImage class]]) {
// image
layer = [self layerForImage:(IJSVGImage*)node];
}
[self applyDefaultsToLayer:layer fromNode:node];
// create the new layer
layer = [self applyTransforms:node.transforms
toLayer:layer
fromNode:node];
return layer;
}
- (IJSVGLayer*)applyTransforms:(NSArray<IJSVGTransform*>*)transforms
toLayer:(IJSVGLayer*)layer
fromNode:(IJSVGNode*)node
{
// any x and y?
CGFloat x = [node.x computeValue:layer.frame.size.width];
CGFloat y = [node.y computeValue:layer.frame.size.height];
// do some magic transform
if (transforms.count == 0 && x == 0.f && y == 0.f) {
return layer;
}
if (x != 0.f || y != 0.f) {
// we must add translate to the stack
NSMutableArray* trans = nil;
if (transforms != nil) {
trans = [[transforms mutableCopy] autorelease];
} else {
trans = [[[NSMutableArray alloc] initWithCapacity:1] autorelease];
}
[trans addObject:[IJSVGTransform transformByTranslatingX:x y:y]];
transforms = trans;
}
// add any transforms
IJSVGLayer* topLayer = nil;
IJSVGLayer* parentLayer = nil;
for (IJSVGTransform* transform in transforms) {
// make sure we apply the transform to the parent
// so they stack
IJSVGGroupLayer* childLayer = [[[IJSVGGroupLayer alloc] init] autorelease];
childLayer.affineTransform = transform.CGAffineTransform;
// add it to the parent layer
if (parentLayer != nil) {
[parentLayer addSublayer:childLayer];
} else {
// make sure we keep track of the top most layer
topLayer = childLayer;
}
// reset parent layer to the new child
parentLayer = childLayer;
}
// swap the layer around
[parentLayer addSublayer:layer];
layer = topLayer;
return layer;
}
- (void)applyDefaultsToLayer:(IJSVGLayer*)layer
fromNode:(IJSVGNode*)node
{
CGFloat opacity = node.opacity.value;
layer.opacity = opacity;
// setup the blending mode
if (node.blendMode != IJSVGBlendModeNormal) {
layer.blendingMode = (CGBlendMode)node.blendMode;
}
// display?
if (node.shouldRender == NO) {
layer.hidden = YES;
}
}
- (IJSVGLayer*)layerForImage:(IJSVGImage*)image
{
IJSVGImageLayer* layer = [[[IJSVGImageLayer alloc] initWithCGImage:image.CGImage] autorelease];
layer.affineTransform = CGAffineTransformConcat(layer.affineTransform,
CGAffineTransformMakeScale(1.f, -1.f));
// make sure we set the width and height correctly,
// as this may not be exactly the same as the size of the
// given image
CGRect frame = layer.frame;
frame.size.width = image.width.value;
frame.size.height = image.height.value;
layer.frame = frame;
return layer;
}
- (IJSVGLayer*)layerForGroup:(IJSVGGroup*)group
{
// grab the sub layer tree from the SVG
if (group.svg != nil) {
return [self layerForGroup:group.svg.rootNode];
}
IJSVGGroupLayer* groupLayer = [[[IJSVGGroupLayer alloc] init] autorelease];
for (IJSVGNode* node in group.children) {
[groupLayer addSublayer:[self layerForNode:node]];
}
groupLayer.frame = (CGRect){
.origin = CGPointZero,
.size = (CGSize){
.width = group.width.value,
.height = group.height.value }
};
// mask it - forgot groups can have masks too, doh! simple
// enough to apply though, recursion ftw!
[self maskLayer:groupLayer
fromNode:group];
return groupLayer;
}
- (CGRect)correctedBounds:(CGRect)bounds
{
if (bounds.origin.x >= INFINITY) {
bounds.origin.x = 0.f;
}
if (bounds.origin.y >= INFINITY) {
bounds.origin.y = 0.f;
}
if (bounds.size.width >= INFINITY) {
bounds.size.width = 0.f;
}
if (bounds.size.height >= INFINITY) {
bounds.size.height = 0.f;
}
return bounds;
}
- (IJSVGShapeLayer*)basicLayerForPath:(IJSVGPath*)path
originalBoundingBox:(CGRect*)originalBoundingBox
{
// setup path and layer
IJSVGShapeLayer* layer = [[[IJSVGShapeLayer alloc] init] autorelease];
layer.primitiveType = path.primitiveType;
CGPathRef introPath = path.CGPath;
*originalBoundingBox = CGRectIntegral(CGPathGetBoundingBox(introPath));
layer.originalPathOrigin = (*originalBoundingBox).origin;
CGRect bounds = [self correctedBounds:*originalBoundingBox];
// zero back the path
CGAffineTransform trans = CGAffineTransformMakeTranslation(-bounds.origin.x,
-bounds.origin.y);
CGPathRef transformedPath = CGPathCreateCopyByTransformingPath(introPath, &trans);
layer.path = transformedPath;
// clean up path memory
CGPathRelease(transformedPath);
// set the bounds
layer.frame = CGRectIntegral(bounds);
// basic fill color and rule
layer.fillColor = nil;
layer.fillRule = [self fillRule:path.windingRule];
return layer;
}
- (IJSVGShapeLayer*)layerMaskFromLayer:(CAShapeLayer*)layer
fromNode:(IJSVGNode*)node
{
IJSVGShapeLayer* mask = [[[IJSVGShapeLayer alloc] init] autorelease];
mask.fillColor = [NSColor blackColor].CGColor;
mask.path = layer.path;
return mask;
}
- (CGAffineTransform)absoluteTransform:(IJSVGNode*)node
{
CGAffineTransform parentAbsoluteTransform = CGAffineTransformIdentity;
IJSVGNode* intermediateNode = node.intermediateParentNode;
IJSVGNode* parentSVGNode = node;
while ((parentSVGNode = parentSVGNode.parentNode) != nil) {
if (node == intermediateNode) {
continue;
}
parentAbsoluteTransform = [self absoluteTransform:parentSVGNode];
}
return CGAffineTransformConcat(IJSVGConcatTransforms(node.transforms),
parentAbsoluteTransform);
}
- (IJSVGLayer*)layerForPath:(IJSVGPath*)path
{
// grab the basic shape layer
CGRect originalShapeBounds;
IJSVGShapeLayer* layer = [self basicLayerForPath:path
originalBoundingBox:&originalShapeBounds];
BOOL hasStroke = (path.strokeColor != nil || path.strokePattern != nil || path.strokeGradient != nil);
// any gradient?
if (_style.fillColor == nil && path.fillGradient != nil) {
// create the gradient
IJSVGGradientLayer* gradLayer = [self gradientLayerForLayer:layer
gradient:path.fillGradient
fromNode:path
objectRect:originalShapeBounds
shouldMask:YES];
// add the gradient and set it against the layer
[layer addSublayer:gradLayer];
layer.gradientFillLayer = gradLayer;
} else if (_style.fillColor == nil && path.fillPattern != nil) {
// create the pattern, this is actually not as easy as it may seem
IJSVGPatternLayer* patternLayer = [self patternLayerForLayer:layer
pattern:path.fillPattern
fromNode:path];
// add it
[layer addSublayer:patternLayer];
// apply offsets
[self applyOffsetsToLayer:patternLayer
fromNode:path.fillPattern];
layer.patternFillLayer = patternLayer;
} else {
// only use the global if its set and the current colors
// alpha channel is not 0.f, otherwise its a blank clear color,
// aka, not filled in
NSColor* fColor = path.fillColor;
BOOL hasColor = (fColor.alphaComponent == 0.f || fColor == nil) == NO;
BOOL hasFill = path.fillPattern != nil || path.fillGradient != nil;
if (_style.fillColor && (hasFill || hasColor || fColor == nil)) {
fColor = _style.fillColor;
} else if (fColor != nil && path.fillOpacity.value != 1.f) {
fColor = [IJSVGColor changeAlphaOnColor:fColor
to:path.fillOpacity.value];
}
// anything changed by user?
fColor = [_style.colorList proposedColorForColor:fColor];
// just set the color
if (fColor != nil) {
layer.fillColor = fColor.CGColor;
} else {
// use default color
NSColor* defColor = [IJSVGColor computeColorSpace:NSColor.blackColor];
if (path.fillOpacity.value != 1.f) {
defColor = [IJSVGColor changeAlphaOnColor:defColor
to:path.fillOpacity.value];
}
// work out if anything was changed by user
NSColor* proposedColor = [_style.colorList proposedColorForColor:defColor];
layer.fillColor = proposedColor.CGColor;
}
}
// stroke it
if (hasStroke == YES) {
// load the stroke layer
IJSVGStrokeLayer* strokeLayer = [self strokeLayer:layer
fromNode:path];
// reset the node
BOOL moveStrokeLayer = NO;
if (_style.strokeColor == nil && path.strokeGradient != nil) {
// force reset of the mask colour as we need to use the stroke layer
// as the mask for the stroke gradient
strokeLayer.strokeColor = [IJSVGColor computeColorSpace:NSColor.blackColor].CGColor;
// create the gradient
IJSVGGradientLayer* gradLayer = [self gradientStrokeLayerForLayer:layer
gradient:path.strokeGradient
fromNode:path
objectRect:originalShapeBounds];
moveStrokeLayer = YES;
gradLayer.mask = strokeLayer;
gradLayer.opacity = strokeLayer.opacity;
// add it
[layer addSublayer:gradLayer];
layer.strokeLayer = strokeLayer;
layer.gradientStrokeLayer = gradLayer;
} else if (_style.strokeColor == nil && path.strokePattern != nil) {
// force reset of the mask
strokeLayer.strokeColor = [IJSVGColor computeColorSpace:NSColor.blackColor].CGColor;
// create the pattern
IJSVGPatternLayer* patternLayer = [self patternStrokeLayerForLayer:layer
pattern:path.strokePattern
fromNode:path];
// set the mask for it
moveStrokeLayer = YES;
patternLayer.mask = strokeLayer;
patternLayer.opacity = strokeLayer.opacity;
// add it
[layer addSublayer:patternLayer];
layer.strokeLayer = strokeLayer;
layer.patternStrokeLayer = (IJSVGPatternLayer*)patternLayer;
} else {
// just add the coloured layer
[layer addSublayer:strokeLayer];
layer.strokeLayer = strokeLayer;
}
// if we required to move the stroke layer
// then move it in based on half of what the stroke
// width is, as strokes are draw on the center
if (moveStrokeLayer) {
CGFloat layerStrokeWidth = strokeLayer.lineWidth;
CGRect rect = strokeLayer.frame;
rect.origin.x += (layerStrokeWidth * .5f);
rect.origin.y += (layerStrokeWidth * .5f);
strokeLayer.frame = rect;
}
}
// apply masking
[self maskLayer:(IJSVGLayer*)layer
fromNode:path];
return (IJSVGLayer*)layer;
}
- (CGRect)correctBounds:(CGRect)bounds
forStrokedPath:(IJSVGNode*)path
{
// minus half the stroke width from x and y
// plus the stroke width to width and height
CGFloat val = path.strokeWidth.value;
bounds.origin.x -= (val * .5f);
bounds.origin.y -= (val * .5f);
bounds.size.width += val;
bounds.size.height += val;
return bounds;
}
- (IJSVGGradientLayer*)gradientStrokeLayerForLayer:(IJSVGShapeLayer*)layer
gradient:(IJSVGGradient*)gradient
fromNode:(IJSVGNode*)path
objectRect:(CGRect)objectRect
{
// the gradient drawing layer
IJSVGGradientLayer* gradLayer = [self gradientLayerForLayer:layer
gradient:gradient
fromNode:path
objectRect:objectRect
shouldMask:NO];
// set the bounds
CGRect bounds = CGPathGetBoundingBox(layer.path);
bounds = [self correctBounds:bounds forStrokedPath:path];
gradLayer.frame = bounds;
return gradLayer;
}
- (IJSVGGradientLayer*)gradientLayerForLayer:(IJSVGShapeLayer*)layer
gradient:(IJSVGGradient*)gradient
fromNode:(IJSVGNode*)path
objectRect:(CGRect)objectRect
shouldMask:(BOOL)shouldMask
{
// the gradient drawing layer
gradient.colorList = _style.colorList;
IJSVGGradientLayer* gradLayer = [[[IJSVGGradientLayer alloc] init] autorelease];
gradLayer.viewBox = self.viewBox;
gradLayer.frame = layer.bounds;
gradLayer.gradient = gradient;
gradLayer.absoluteTransform = [self absoluteTransform:path];
gradLayer.objectRect = CGRectApplyAffineTransform(objectRect,
gradLayer.absoluteTransform);
if (shouldMask == YES) {
// add the mask
IJSVGShapeLayer* mask = [self layerMaskFromLayer:layer
fromNode:path];
gradLayer.mask = mask;
}
// is there a fill opacity?
if (path.fillOpacity.value != 0.f) {
gradLayer.opacity = path.fillOpacity.value;
}
gradLayer.masksToBounds = YES;
return gradLayer;
}
- (IJSVGPatternLayer*)patternStrokeLayerForLayer:(IJSVGShapeLayer*)layer
pattern:(IJSVGPattern*)pattern
fromNode:(IJSVGNode*)path
{
// create the pattern, this is actually not as easy as it may seem
IJSVGPatternLayer* patternLayer = [[[IJSVGPatternLayer alloc] init] autorelease];
patternLayer.patternNode = pattern;
patternLayer.pattern = [self layerForNode:pattern];
// is there a fill opacity?
if (path.fillOpacity.value != 0.f) {
patternLayer.opacity = path.fillOpacity.value;
}
// set the bounds
CGRect bounds = CGPathGetBoundingBox(layer.path);
bounds = [self correctBounds:bounds forStrokedPath:path];
patternLayer.frame = bounds;
patternLayer.masksToBounds = YES;
// display
[patternLayer setNeedsDisplay];
return patternLayer;
}
- (IJSVGPatternLayer*)patternLayerForLayer:(IJSVGShapeLayer*)layer
pattern:(IJSVGPattern*)pattern
fromNode:(IJSVGNode*)path
{
// create the pattern, this is actually not as easy as it may seem
IJSVGPatternLayer* patternLayer = [[[IJSVGPatternLayer alloc] init] autorelease];
patternLayer.patternNode = pattern;
patternLayer.pattern = [self layerForNode:pattern];
patternLayer.frame = CGPathGetBoundingBox(layer.path);
// is there a fill opacity?
if (path.fillOpacity.value != 0.f) {
patternLayer.opacity = path.fillOpacity.value;
}
// add the mask
patternLayer.mask = [self layerMaskFromLayer:layer
fromNode:path];
// display
[patternLayer setNeedsDisplay];
patternLayer.masksToBounds = YES;
return patternLayer;
}
- (void)applyOffsetsToLayer:(IJSVGLayer*)layer
fromNode:(IJSVGNode*)node
{
// make sure it has a superlayer
if (layer.superlayer == nil) {
return;
}
// grab the x and y
IJSVGUnitLength* x = nil;
IJSVGUnitLength* y = nil;
// sort out the rect
CGRect rect = layer.superlayer.frame;
CGRect frame = layer.frame;
// x
if ((x = node.x) != nil) {
frame.origin.x = [x computeValue:rect.size.width];
}
// y
if ((y = node.y) != nil) {
frame.origin.y = [y computeValue:rect.size.height];
}
// update the frame
if (CGRectEqualToRect(frame, layer.frame) == NO) {
layer.frame = frame;
}
}
- (IJSVGStrokeLayer*)strokeLayer:(IJSVGShapeLayer*)layer
fromNode:(IJSVGPath*)path
{
// same as fill, dont use global if the alpha is 0.f, but do use it
// if there is a pattern or gradient
NSColor* sColor = path.strokeColor;
if (_style.strokeColor != nil && ((sColor != nil && sColor.alphaComponent != 0.f) || path.strokePattern != nil || path.strokeGradient != nil)) {
sColor = _style.strokeColor;
}
sColor = [_style.colorList proposedColorForColor:sColor];
// stroke layer
IJSVGStrokeLayer* strokeLayer = [[[IJSVGStrokeLayer alloc] init] autorelease];
strokeLayer.path = layer.path;
strokeLayer.fillColor = nil;
strokeLayer.strokeColor = sColor.CGColor;
CGFloat lineWidth = 1.f;
if (_style.lineWidth != IJSVGInheritedFloatValue) {
lineWidth = _style.lineWidth;
} else {
lineWidth = path.strokeWidth.value;
}
// work out line styles
IJSVGLineCapStyle lCapStyle;
IJSVGLineJoinStyle lJoinStyle;
// forced cap style
if (_style.lineCapStyle != IJSVGLineCapStyleNone) {
lCapStyle = _style.lineCapStyle;
} else {
lCapStyle = path.lineCapStyle;
}
// forced join style
if (_style.lineJoinStyle != IJSVGLineJoinStyleNone) {
lJoinStyle = _style.lineJoinStyle;
} else {
lJoinStyle = path.lineJoinStyle;
}
// line styles
strokeLayer.lineWidth = lineWidth;
strokeLayer.lineCap = [self lineCap:lCapStyle];
strokeLayer.lineJoin = [self lineJoin:lJoinStyle];
CGFloat strokeOpacity = 1.f;
if (path.strokeOpacity.value != 0.f) {
strokeOpacity = path.strokeOpacity.value;
}
strokeLayer.opacity = strokeOpacity;
// dashing
strokeLayer.lineDashPhase = path.strokeDashOffset.value;
strokeLayer.lineDashPattern = [self lineDashPattern:path];
return strokeLayer;
}
- (void)maskLayer:(IJSVGLayer*)layer
fromNode:(IJSVGNode*)node
{
// any clippath?
if (node.clipPath != nil || node.mask != nil) {
IJSVGGroupLayer* maskLayer = [[[IJSVGGroupLayer alloc] init] autorelease];
// add clip mask
if (node.clipPath != nil) {
IJSVGLayer* clip = [self layerForNode:node.clipPath];
// adjust the frame
if (node.clipPath.units == IJSVGUnitObjectBoundingBox) {
[self adjustLayer:clip
toParentLayerFrame:layer];
} else {
clip.affineTransform = [self absoluteTransform:node];
}
// add the layer
[maskLayer addSublayer:clip];
}
// add the actual mask
if (node.mask != nil) {
IJSVGLayer* mask = [self layerForNode:node.mask];
// only move if bounding box
if (node.mask.units == IJSVGUnitObjectBoundingBox) {
[self adjustLayer:mask
toParentLayerFrame:layer];
} else {
mask.affineTransform = [self absoluteTransform:node];
}
// add the layer
[maskLayer addSublayer:mask];
}
// recursive colourize for each item
[self _recursiveColorLayersFromLayer:maskLayer
withColor:[IJSVGColor computeColorSpace:NSColor.whiteColor].CGColor];
// add the mask
layer.mask = maskLayer;
}
}
- (void)_recursiveColorLayersFromLayer:(IJSVGLayer*)layer
withColor:(CGColorRef)color
{
if ([layer isKindOfClass:[IJSVGShapeLayer class]]) {
// has a proper fill method
for (IJSVGLayer* c in layer.sublayers) {
if ([c isKindOfClass:[IJSVGGradientLayer class]] ||
[c isKindOfClass:[IJSVGPatternLayer class]]) {
return;
}
}
// set the fill
IJSVGShapeLayer* l = (IJSVGShapeLayer*)layer;
l.fillColor = color;
} else if ([layer isKindOfClass:[IJSVGGroupLayer class]]) {
// go through its children, assume its a group
for (IJSVGLayer* child in layer.sublayers) {
[self _recursiveColorLayersFromLayer:child
withColor:color];
}
}
}
- (void)adjustLayer:(IJSVGLayer*)childLayer
toParentLayerFrame:(IJSVGLayer*)parent
{
childLayer.frame = (CGRect){
.size = childLayer.frame.size,
.origin = CGPointMake((childLayer.frame.origin.x - parent.frame.origin.x),
(childLayer.frame.origin.y - parent.frame.origin.y))
};
}
- (NSArray<NSNumber*>*)lineDashPattern:(IJSVGNode*)node
{
NSMutableArray* arr = [[[NSMutableArray alloc] init] autorelease];
for (NSInteger i = 0; i < node.strokeDashArrayCount; i++) {
[arr addObject:@((CGFloat)node.strokeDashArray[i])];
}
return [[arr copy] autorelease];
}
- (NSString*)lineJoin:(IJSVGLineJoinStyle)joinStyle
{
switch (joinStyle) {
default:
case IJSVGLineJoinStyleMiter: {
return kCALineJoinMiter;
}
case IJSVGLineJoinStyleBevel: {
return kCALineJoinBevel;
}
case IJSVGLineJoinStyleRound: {
return kCALineJoinRound;
}
}
}
- (NSString*)lineCap:(IJSVGLineCapStyle)capStyle
{
switch (capStyle) {
default:
case IJSVGLineCapStyleButt: {
return kCALineCapButt;
}
case IJSVGLineCapStyleRound: {
return kCALineCapRound;
}
case IJSVGLineCapStyleSquare: {
return kCALineCapSquare;
}
}
}
- (NSString*)fillRule:(IJSVGWindingRule)rule
{
switch (rule) {
case IJSVGWindingRuleEvenOdd: {
return kCAFillRuleEvenOdd;
}
default: {
return kCAFillRuleNonZero;
}
}
}
+ (void)log:(IJSVGLayer*)layer
depth:(NSInteger)depth
{
NSLog(@"%@%@: %@, Transforms: %@", [@"" stringByPaddingToLength:depth
withString:@"\t"
startingAtIndex:0],
layer,
NSStringFromRect(layer.frame),
[IJSVGTransform affineTransformToSVGTransformAttributeString:layer.affineTransform]);
for (IJSVGLayer* sublayer in layer.sublayers) {
[self log:(IJSVGLayer*)sublayer
depth:depth++];
}
}
@end
@@ -0,0 +1,21 @@
//
// IJSVGRendering.h
// IJSVGExample
//
// Created by Curtis Hard on 14/03/2019.
// Copyright © 2019 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef CGFloat (^IJSVGRenderingBackingScaleFactorHelper)(void);
typedef NS_ENUM(NSInteger, IJSVGRenderQuality) {
kIJSVGRenderQualityFullResolution, // slowest to render
kIJSVGRenderQualityOptimized, // best of both worlds
kIJSVGRenderQualityLow // fast rendering
};
@interface IJSVGRendering : NSObject
@end
@@ -0,0 +1,13 @@
//
// IJSVGRendering.m
// IJSVGExample
//
// Created by Curtis Hard on 14/03/2019.
// Copyright © 2019 Curtis Hard. All rights reserved.
//
#import "IJSVGRendering.h"
@implementation IJSVGRendering
@end
@@ -0,0 +1,26 @@
//
// IJSVGStyleList.h
// IconJar
//
// Created by Curtis Hard on 09/07/2019.
// Copyright © 2019 Curtis Hard. All rights reserved.
//
#import "IJSVGColorList.h"
#import "IJSVGNode.h"
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface IJSVGRenderingStyle : NSObject
@property (nonatomic, assign) IJSVGLineCapStyle lineCapStyle;
@property (nonatomic, assign) IJSVGLineJoinStyle lineJoinStyle;
@property (nonatomic, assign) CGFloat lineWidth;
@property (nonatomic, retain) IJSVGColorList* colorList;
@property (nonatomic, retain) NSColor* fillColor;
@property (nonatomic, retain) NSColor* strokeColor;
+ (NSArray<NSString*>*)observableProperties;
@end
@@ -0,0 +1,50 @@
//
// IJSVGStyleList.m
// IconJar
//
// Created by Curtis Hard on 09/07/2019.
// Copyright © 2019 Curtis Hard. All rights reserved.
//
#import "IJSVGRenderingStyle.h"
@implementation IJSVGRenderingStyle
@synthesize colorList = _colorList;
@synthesize lineCapStyle = _lineCapStyle;
@synthesize lineJoinStyle = _lineJoinStyle;
@synthesize lineWidth = _lineWidth;
@synthesize fillColor = _fillColor;
@synthesize strokeColor = _strokeColor;
- (void)dealloc
{
(void)([_fillColor release]), _fillColor = nil;
(void)([_strokeColor release]), _strokeColor = nil;
(void)([_colorList release]), _colorList = nil;
[super dealloc];
}
- (id)init
{
if ((self = [super init]) != nil) {
_lineCapStyle = IJSVGLineCapStyleNone;
_lineJoinStyle = IJSVGLineJoinStyleNone;
_lineWidth = IJSVGInheritedFloatValue;
_colorList = [[IJSVGColorList alloc] init];
}
return self;
}
+ (NSArray<NSString*>*)observableProperties
{
static NSArray* array = nil;
if (array == nil) {
array = @[ @"lineCapStyle", @"lineJoinStyle", @"lineWidth",
@"colorList", @"fillColor", @"strokeColor" ]
.retain;
}
return array;
}
@end
@@ -6,22 +6,21 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGColor.h"
#import <Foundation/Foundation.h>
@interface IJSVGStyle : NSObject {
@private
NSMutableDictionary * _dict;
NSMutableDictionary* _dict;
}
+ (IJSVGStyle *)parseStyleString:(NSString *)string;
+ (IJSVGStyle*)parseStyleString:(NSString*)string;
- (void)setPropertyValue:(id)value
forProperty:(NSString *)key;
- (id)property:(NSString *)key;
forProperty:(NSString*)key;
- (id)property:(NSString*)key;
- (IJSVGStyle *)mergedStyle:(IJSVGStyle *)style;
- (IJSVGStyle*)mergedStyle:(IJSVGStyle*)style;
@end
@@ -0,0 +1,128 @@
//
// IJSVGStyle.m
// IJSVGExample
//
// Created by Curtis Hard on 03/09/2014.
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGStyle.h"
#import "IJSVGUtils.h"
@implementation IJSVGStyle
- (void)dealloc
{
(void)([_dict release]), _dict = nil;
[super dealloc];
}
- (id)init
{
if ((self = [super init]) != nil) {
_dict = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)setPropertyValue:(id)value
forProperty:(NSString*)key
{
[_dict setObject:value
forKey:key];
}
- (NSDictionary*)properties
{
return _dict;
}
- (id)property:(NSString*)key
{
return [_dict objectForKey:key];
}
+ (IJSVGStyle*)parseStyleString:(NSString*)string
{
IJSVGStyle* style = [[[self.class alloc] init] autorelease];
NSInteger length = string.length;
NSInteger index = 0;
NSString* key = nil;
NSString* value = nil;
// iterate over the string - its actually really simple what we need
// to do
for (NSInteger i = 0; i < length; i++) {
unichar c = [string characterAtIndex:i];
// find the key
if (c == ':') {
key = [string substringWithRange:NSMakeRange(index, (i - index))];
index = i + 1;
}
// find the value
else if (c == ';' || i == (length - 1)) {
NSInteger chomp;
if (i == (length - 1) && c != ';') {
chomp = (i - (index - 1));
} else {
chomp = (i - index);
}
value = [string substringWithRange:NSMakeRange(index, chomp)];
index = i + 1;
}
// set the propery if it actually exists
if (key != nil && value != nil) {
[style setPropertyValue:[self.class trimString:value]
forProperty:[self.class trimString:key]];
key = nil;
value = nil;
}
}
return style;
}
+ (NSString*)trimString:(NSString*)string
{
return [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
+ (NSArray*)allowedColourKeys
{
return @[ @"fill", @"stroke-colour", @"stop-color", @"stroke" ];
}
- (void)setProperties:(NSDictionary*)properties
replaceAll:(BOOL)flag
{
if (flag) {
[_dict removeAllObjects];
}
[_dict addEntriesFromDictionary:properties];
}
- (NSString*)description
{
return [_dict description];
}
- (IJSVGStyle*)mergedStyle:(IJSVGStyle*)style
{
// create the new style
IJSVGStyle* newStyle = [[[IJSVGStyle alloc] init] autorelease];
// grab the current style
NSMutableDictionary* dict = [[[self properties] mutableCopy] autorelease];
// overwride the style with the new styles
[dict addEntriesFromDictionary:[style properties]];
// add the styles to the style
[newStyle setProperties:dict
replaceAll:YES];
return newStyle;
}
@end
@@ -6,20 +6,20 @@
// Copyright © 2016 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGStyleSheetSelector.h"
#import "IJSVGStyleSheetRule.h"
#import "IJSVGStyleSheetSelector.h"
#import <Foundation/Foundation.h>
@class IJSVGNode;
@interface IJSVGStyleSheet : NSObject {
@private
NSMutableDictionary * _selectors;
NSMutableArray * _rules;
NSMutableDictionary* _selectors;
NSMutableArray* _rules;
}
- (void)parseStyleBlock:(NSString *)string;
- (IJSVGStyle *)styleForNode:(IJSVGNode *)node;
- (void)parseStyleBlock:(NSString*)string;
- (IJSVGStyle*)styleForNode:(IJSVGNode*)node;
@end
@@ -6,19 +6,18 @@
// Copyright © 2016 Curtis Hard. All rights reserved.
//
#import "IJSVGStyleSheet.h"
#import "IJSVGStyle.h"
#import "IJSVGNode.h"
#import "IJSVGStyle.h"
#import "IJSVGStyleSheet.h"
@interface IJSVGStyleSheetSelectorListItem : NSObject {
IJSVGStyleSheetSelector * selector;
IJSVGStyleSheetRule * rule;
IJSVGStyleSheetSelector* selector;
IJSVGStyleSheetRule* rule;
}
@property (nonatomic, retain) IJSVGStyleSheetRule * rule;
@property (nonatomic, retain) IJSVGStyleSheetSelector * selector;
@property (nonatomic, retain) IJSVGStyleSheetRule* rule;
@property (nonatomic, retain) IJSVGStyleSheetSelector* selector;
@end
@@ -28,8 +27,8 @@
- (void)dealloc
{
[rule release], rule = nil;
[selector release], selector = nil;
(void)([rule release]), rule = nil;
(void)([selector release]), selector = nil;
[super dealloc];
}
@@ -39,72 +38,73 @@
- (void)dealloc
{
[_selectors release], _selectors = nil;
[_rules release], _rules = nil;
(void)([_selectors release]), _selectors = nil;
(void)([_rules release]), _rules = nil;
[super dealloc];
}
- (id)init
{
if((self = [super init]) != nil)
{
if ((self = [super init]) != nil) {
_selectors = [[NSMutableDictionary alloc] init];
_rules = [[NSMutableArray alloc] init];
}
return self;
}
- (NSArray *)selectorsWithSelectorString:(NSString *)string
- (NSArray*)selectorsWithSelectorString:(NSString*)string
{
NSMutableArray * array = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray* array = [[[NSMutableArray alloc] init] autorelease];
// split the string by the comma, as it could be multiple
NSArray * comp = [string componentsSeparatedByString:@","];
NSCharacterSet * whiteSpaceCharSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSArray* comp = [string componentsSeparatedByString:@","];
NSCharacterSet* whiteSpaceCharSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
// create a selector or reuse one already being used
for( NSString * selectorName in comp )
{
for (NSString* selectorName in comp) {
selectorName = [selectorName stringByTrimmingCharactersInSet:whiteSpaceCharSet];
IJSVGStyleSheetSelector * selector = nil;
IJSVGStyleSheetSelector* selector = nil;
// create a new selector if not found
if((selector = [_selectors objectForKey:selectorName]) == nil) {
if ((selector = [_selectors objectForKey:selectorName]) == nil) {
selector = [[[IJSVGStyleSheetSelector alloc] initWithSelectorString:selectorName] autorelease];
[_selectors setObject:selector
forKey:selectorName];
if (selector != nil) {
[_selectors setObject:selector
forKey:selectorName];
}
}
// add it to our list
[array addObject:selector];
if (selector != nil) {
[array addObject:selector];
}
}
return array;
}
- (void)parseStyleBlock:(NSString *)string
- (void)parseStyleBlock:(NSString*)string
{
NSUInteger depth = 0, marker = 0;
NSUInteger length = [string length];
NSCharacterSet * whitespaceCharSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSString * selector = nil;
for( NSUInteger i = 0; i < length; i++ )
{
NSCharacterSet* whitespaceCharSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSString* selector = nil;
for (NSUInteger i = 0; i < length; i++) {
unichar c = [string characterAtIndex:i];
if( c == '/' ) {
if (c == '/') {
i++;
if( i<length ) {
if (i < length) {
c = [string characterAtIndex:i];
if( c == '*' ) {
if (c == '*') {
// skip comment until closing /
for( ; i < length; i++ ) {
if([string characterAtIndex:i] == '/') {
for (; i < length; i++) {
if ([string characterAtIndex:i] == '/') {
break;
}
}
if( i < length ) {
marker = i+1;
if (i < length) {
marker = i + 1;
continue;
} else {
// end of string
@@ -115,79 +115,77 @@
}
}
}
// opening brace, could be nested or start of a new string
if( c == '{' ) {
if (c == '{') {
// start a new rule
if(depth == 0) {
if (depth == 0) {
// grab selector and trim it
selector = [string substringWithRange:NSMakeRange(marker, i-marker)];
selector = [string substringWithRange:NSMakeRange(marker, i - marker)];
selector = [selector stringByTrimmingCharactersInSet:whitespaceCharSet];
marker = i+1;
marker = i + 1;
}
depth += 1;
}
// ending brace
else if( c == '}' ) {
else if (c == '}') {
// if we finished rule
if(depth == 1) {
NSString * rule = [string substringWithRange:NSMakeRange(marker, i-marker)];
if (depth == 1) {
NSString* rule = [string substringWithRange:NSMakeRange(marker, i - marker)];
rule = [rule stringByTrimmingCharactersInSet:whitespaceCharSet];
// append the rule to the style sheet
[self addStyleRule:rule
withSelectors:[self selectorsWithSelectorString:selector]];
marker = i+1;
marker = i + 1;
}
depth = MAX(depth-1, 0);
depth = MAX(depth - 1, 0);
}
}
}
- (void)addStyleRule:(NSString *)rule
withSelectors:(NSArray *)selectors
- (void)addStyleRule:(NSString*)rule
withSelectors:(NSArray*)selectors
{
// append the rule onto the list within
// this style sheet
IJSVGStyleSheetRule * aRule = [[[IJSVGStyleSheetRule alloc] init] autorelease];
IJSVGStyleSheetRule* aRule = [[[IJSVGStyleSheetRule alloc] init] autorelease];
aRule.style = [IJSVGStyle parseStyleString:rule];
aRule.selectors = selectors;
[_rules addObject:aRule];
}
- (IJSVGStyle *)styleForNode:(IJSVGNode *)node
- (IJSVGStyle*)styleForNode:(IJSVGNode*)node
{
IJSVGStyle * style = [[[IJSVGStyle alloc] init] autorelease];
NSMutableArray * matchedRules = [[[NSMutableArray alloc] init] autorelease];
for(IJSVGStyleSheetRule * rule in _rules)
{
IJSVGStyleSheetSelector * matchedSelector = nil;
if([rule matchesNode:node selector:&matchedSelector]) {
IJSVGStyle* style = [[[IJSVGStyle alloc] init] autorelease];
NSMutableArray* matchedRules = [[[NSMutableArray alloc] init] autorelease];
for (IJSVGStyleSheetRule* rule in _rules) {
IJSVGStyleSheetSelector* matchedSelector = nil;
if ([rule matchesNode:node selector:&matchedSelector]) {
// make a wrapper for the selector with the rule
IJSVGStyleSheetSelectorListItem * listItem = nil;
IJSVGStyleSheetSelectorListItem* listItem = nil;
listItem = [[[IJSVGStyleSheetSelectorListItem alloc] init] autorelease];
listItem.rule = rule;
listItem.selector = matchedSelector;
// add it to the array of matches
[matchedRules addObject:listItem];
}
}
// now we have all the wrappers, we need to sort them
// by specificity
NSSortDescriptor * sort = [NSSortDescriptor sortDescriptorWithKey:@"selector.specificity"
ascending:YES];
[matchedRules sortUsingDescriptors:@[sort]];
NSSortDescriptor* sort = [NSSortDescriptor sortDescriptorWithKey:@"selector.specificity"
ascending:YES];
[matchedRules sortUsingDescriptors:@[ sort ]];
// combine the rule
for(IJSVGStyleSheetSelectorListItem * listItem in matchedRules) {
for (IJSVGStyleSheetSelectorListItem* listItem in matchedRules) {
style = [style mergedStyle:listItem.rule.style];
}
return style;
}
@@ -6,23 +6,22 @@
// Copyright © 2016 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGStyleSheetSelector.h"
#import "IJSVGStyle.h"
#import "IJSVGStyleSheetSelector.h"
#import <Foundation/Foundation.h>
@class IJSVGNode;
@interface IJSVGStyleSheetRule : NSObject {
NSArray * selectors;
IJSVGStyle * style;
NSArray* selectors;
IJSVGStyle* style;
}
@property (nonatomic, retain) NSArray * selectors;
@property (nonatomic, retain) IJSVGStyle * style;
@property (nonatomic, retain) NSArray* selectors;
@property (nonatomic, retain) IJSVGStyle* style;
- (BOOL)matchesNode:(IJSVGNode *)node
selector:(IJSVGStyleSheetSelector **)matchedSelector;
- (BOOL)matchesNode:(IJSVGNode*)node
selector:(IJSVGStyleSheetSelector**)matchedSelector;
@end
@@ -14,18 +14,18 @@
- (void)dealloc
{
[selectors release], selectors = nil;
[style release], style = nil;
(void)([selectors release]), selectors = nil;
(void)([style release]), style = nil;
[super dealloc];
}
- (BOOL)matchesNode:(IJSVGNode *)node
selector:(IJSVGStyleSheetSelector **)matchedSelector
- (BOOL)matchesNode:(IJSVGNode*)node
selector:(IJSVGStyleSheetSelector**)matchedSelector
{
// interate over each select and work out if
// it allows us to be applied
for(IJSVGStyleSheetSelector * selector in selectors) {
if([selector matchesNode:node]) {
for (IJSVGStyleSheetSelector* selector in selectors) {
if ([selector matchesNode:node]) {
*matchedSelector = selector;
return YES;
}
@@ -6,23 +6,22 @@
// Copyright © 2016 Curtis Hard. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "IJSVGStyleSheetSelectorRaw.h"
#import <Foundation/Foundation.h>
@class IJSVGNode;
@interface IJSVGStyleSheetSelector : NSObject {
NSString * selector;
NSString* selector;
NSUInteger specificity;
@private
NSMutableArray * _rawSelectors;
NSMutableArray* _rawSelectors;
}
@property (nonatomic, assign) NSUInteger specificity;
- (id)initWithSelectorString:(NSString *)string;
- (BOOL)matchesNode:(IJSVGNode *)node;
- (id)initWithSelectorString:(NSString*)string;
- (BOOL)matchesNode:(IJSVGNode*)node;
@end
@@ -246,8 +246,8 @@ BOOL IJSVGStyleSheetMatchSelector(IJSVGNode * node, IJSVGStyleSheetSelectorRaw *
- (void)dealloc
{
[_rawSelectors release], _rawSelectors = nil;
[selector release], selector = nil;
(void)([_rawSelectors release]), _rawSelectors = nil;
(void)([selector release]), selector = nil;
[super dealloc];
}
@@ -257,7 +257,12 @@ BOOL IJSVGStyleSheetMatchSelector(IJSVGNode * node, IJSVGStyleSheetSelectorRaw *
{
selector = [string copy];
_rawSelectors = [[NSMutableArray alloc] init];
[self _compile];
// failed to compile
if([self _compile] == NO) {
(void)([self release]), self = nil;
return nil;
}
[self _calculate];
}
return self;
@@ -283,23 +288,55 @@ BOOL IJSVGStyleSheetMatchSelector(IJSVGNode * node, IJSVGStyleSheetSelectorRaw *
}
}
- (void)_compile
- (BOOL)validateSelector:(NSString *)string
{
char * invalidChars = "@:;*()[]";
NSUInteger length = strlen(invalidChars);
NSUInteger sLength = string.length;
for(NSUInteger i = 0; i < length; i++) {
for(NSUInteger s = 0; s < sLength; s++) {
// if found invalid char, just return NO instantly
if(invalidChars[i] == [string characterAtIndex:s]) {
return NO;
}
}
}
return YES;
}
- (BOOL)_compile
{
// completely unsupported
if([self validateSelector:selector] == NO) {
return NO;
}
// keychar lookup
char * keychars = "#+.>~ ";
NSUInteger aLength = strlen(keychars);
BOOL (^isKeyChar)(char anotherChar) = ^(char anotherChar) {
for(NSInteger i = 0; i < aLength; i++) {
if(keychars[i] == anotherChar) {
return YES;
}
}
return NO;
};
NSUInteger length = selector.length;
NSMutableArray * sels = [[[NSMutableArray alloc] init] autorelease];
NSCharacterSet * alphaNumeric = [NSCharacterSet characterSetWithCharactersInString:@"_-abcdefghijklmnopqrstuvwxyz0123456789"];
IJSVGStyleSheetSelectorRaw * rawSelector = [[[IJSVGStyleSheetSelectorRaw alloc] init] autorelease];
for(NSUInteger i = 0; i < length; i++)
{
for(NSUInteger i = 0; i < length; i++) {
unichar c = [selector characterAtIndex:i];
// beginning of class
if( c == '.' ) {
i++;
for(NSUInteger a = i; a < length; a++ ) {
unichar ca = [selector characterAtIndex:a];
if([alphaNumeric characterIsMember:ca] == NO || a == length-1) {
if(isKeyChar(ca) == YES || a == length-1) {
// if at end, add 1 to a so it gets the last character
if( a == length-1 ) {
a++;
@@ -316,7 +353,7 @@ BOOL IJSVGStyleSheetMatchSelector(IJSVGNode * node, IJSVGStyleSheetSelectorRaw *
i++;
for(NSUInteger a = i; a < length; a++ ) {
unichar ca = [selector characterAtIndex:a];
if([alphaNumeric characterIsMember:ca] == NO || a == length-1) {
if(isKeyChar(ca) == YES || a == length-1) {
// if at end, add 1 to a so it gets the last character
if( a == length-1 ) {
a++;
@@ -375,7 +412,7 @@ BOOL IJSVGStyleSheetMatchSelector(IJSVGNode * node, IJSVGStyleSheetSelectorRaw *
else {
for( NSUInteger a = i; a < length; a++ ) {
unichar ca = [selector characterAtIndex:a];
if([alphaNumeric characterIsMember:ca] == NO || a == length-1) {
if(isKeyChar(ca) == YES || a == length-1) {
if( a == length-1 ) {
a++;
}
@@ -397,6 +434,7 @@ BOOL IJSVGStyleSheetMatchSelector(IJSVGNode * node, IJSVGStyleSheetSelectorRaw *
}
// now its compiled, we need to reverse the selectors
[_rawSelectors addObjectsFromArray:[sels reverseObjectEnumerator].allObjects];
return YES;
}
@@ -19,21 +19,20 @@ typedef NS_ENUM(NSUInteger, IJSVGStyleSheetSelectorCombinator) {
@interface IJSVGStyleSheetSelectorRaw : NSObject {
NSString * tag;
NSString * identifier;
NSMutableArray * classes;
NSString* tag;
NSString* identifier;
NSMutableArray* classes;
IJSVGStyleSheetSelectorCombinator combinator;
NSString * combinatorString;
NSString* combinatorString;
}
@property (nonatomic, copy) NSString * tag;
@property (nonatomic, copy) NSString * identifier;
@property (nonatomic, copy) NSString * combinatorString;
@property (nonatomic, retain) NSArray * classes;
@property (nonatomic, copy) NSString* tag;
@property (nonatomic, copy) NSString* identifier;
@property (nonatomic, copy) NSString* combinatorString;
@property (nonatomic, retain) NSArray* classes;
@property (nonatomic, assign) IJSVGStyleSheetSelectorCombinator combinator;
- (void)addClassName:(NSString *)className;
- (void)addClassName:(NSString*)className;
@end
@@ -14,17 +14,16 @@
- (void)dealloc
{
[classes release], classes = nil;
[identifier release], identifier = nil;
[tag release], tag = nil;
[combinatorString release], combinatorString = nil;
(void)([classes release]), classes = nil;
(void)([identifier release]), identifier = nil;
(void)([tag release]), tag = nil;
(void)([combinatorString release]), combinatorString = nil;
[super dealloc];
}
- (id)init
{
if( ( self = [super init] ) != nil )
{
if ((self = [super init]) != nil) {
classes = [[NSMutableArray alloc] init];
combinator = IJSVGStyleSheetSelectorCombinatorDescendant;
combinatorString = @" ";
@@ -32,12 +31,12 @@
return self;
}
- (void)addClassName:(NSString *)className
- (void)addClassName:(NSString*)className
{
[classes addObject:className];
}
- (NSString *)description
- (NSString*)description
{
return [NSString stringWithFormat:@"Combinator: %@, Tag: %@, Classes: %@, Identifier: %@", combinatorString, tag, classes, identifier];
}
@@ -0,0 +1,13 @@
//
// IJSVGGradientUnitLength.h
// IconJar
//
// Created by Curtis Hard on 29/03/2017.
// Copyright © 2017 Curtis Hard. All rights reserved.
//
#import "IJSVGUnitLength.h"
@interface IJSVGGradientUnitLength : IJSVGUnitLength
@end
@@ -0,0 +1,21 @@
//
// IJSVGGradientUnitLength.m
// IconJar
//
// Created by Curtis Hard on 29/03/2017.
// Copyright © 2017 Curtis Hard. All rights reserved.
//
#import "IJSVGGradientUnitLength.h"
@implementation IJSVGGradientUnitLength
- (NSString*)stringValue
{
if (self.type == IJSVGUnitLengthTypePercentage) {
return [NSString stringWithFormat:@"%g", self.value];
}
return [super stringValue];
}
@end
@@ -10,31 +10,38 @@
@implementation IJSVGMath
CGFloat IJSVGMathRad(CGFloat val) {
CGFloat IJSVGMathRad(CGFloat val)
{
return val * M_PI / 180;
};
CGFloat IJSVGMathDeg(CGFloat val) {
CGFloat IJSVGMathDeg(CGFloat val)
{
return val * 180.f / M_PI;
};
CGFloat IJSVGMathAcos(CGFloat val) {
CGFloat IJSVGMathAcos(CGFloat val)
{
return IJSVGMathDeg(acosf(val));
};
CGFloat IJSVGMathSin(CGFloat val) {
CGFloat IJSVGMathSin(CGFloat val)
{
return sinf(IJSVGMathRad(val));
};
CGFloat IJSVGMathAsin(CGFloat val) {
CGFloat IJSVGMathAsin(CGFloat val)
{
return IJSVGMathDeg(asinf(val));
};
CGFloat IJSVGMathTan(CGFloat val) {
CGFloat IJSVGMathTan(CGFloat val)
{
return tanf(IJSVGMathRad(val));
};
CGFloat IJSVGMathAtan(CGFloat val) {
CGFloat IJSVGMathAtan(CGFloat val)
{
return IJSVGMathDeg(atanf(val));
};
@@ -7,7 +7,8 @@
//
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
void IJSVGBeginTransactionLock();
void IJSVGEndTransactionLock();
void IJSVGObtainTransactionLock(dispatch_block_t block, BOOL renderOnMainThread);
BOOL IJSVGIsMainThread(void);
void IJSVGBeginTransactionLock(void);
void IJSVGEndTransactionLock(void);

Some files were not shown because too many files have changed in this diff Show More