UPDATE SPRING 2012: The main SVG lib described below (SVGKit) now works a LOT better, and is only a short way from loading all mainstream SVG files.
NB: it also has a new URL (due to GitHub’s internals) – https://github.com/SVGKit/SVGKit/
I’ve got a bunch of SVG files – hand-drawn maps for a computer game – which I wanted to load onto iPad, and port the game. The files are standard, straight out of Inkscape (the most popular free vector-editing / SVG-editing program).
Unfortunately, Apple doesn’t provide any rendering-support for SVG, and the nearest they do provide – PDF rendering – is slow and uses too much memory. PDF isn’t easy to render, and it does a great job on accuracy, but even on OS X, Apple’s API is often too slow for real-world use.
So, a quick look around the open-source alternatives…
SVGQuartzRenderer
This is the library I found via googling. It sort-of works, and it was only designed for a very narrow use-case (so: fair enough) … but it has some pretty major problems, and it’s not really workable for general SVG loading:
- The project is badly organized – it has iOS-only files referenced in the OS X project, and vice versa
- You can’t do a simple “build this and use in another project” – there’s source bugs/typos that have to be fixed by hand first, mostly because of the bad project organization.
- The interface to your Cocoa / iOS app is weak – it’s not designed to integrate cleanly, and it seems to jump you through hoops that most programmers would find makes life hard
SVGKit
While trying to fix SVGQuartzRenderer, I found SVGKit by accident. There are two projects with this name – one is a Javascript library, the other is an Objective-C library. They appear to have nothing in common except the name.
UPDATE SPRING 2012: new URLhttps://github.com/SVGKit/SVGKit/
SVGKit worked pretty well out of the box – you can do a build direct for iPad from their sample project, and it loads up into an “SVG Browser” that lets you try a couple of example SVG’s included in the project.
TL;DR – do NOT download the main version, it’s out of date and buggy, and the original author has disappeared. But there are high-quality forks you can download instead that work very well (instructions below).
UPDATE SPRING 2012: the project now has a team of contributors and admins, and the “main version” should soon be up to production quality
SVGKit installation / getting started
Tragically, the install instructions on the front page of the github project are simply … wrong. There’s no way you can use it in your own projects with those instructions. The sample projects work, so it was a case of doing a line by line compare to work out what special magic settings were needed.
UPDATE SPRING 2012: All the instructions have been re-written (I updated a lot of them myself
) – use the instructions on the https://github.com/SVGKit/SVGKit page
Corrected instructions are:
- Drag/drop (or copy/paste) the “iOS” and “Core” folders into your Xcode project
- edit the Build Phases, and add to the Libraries phase: libxml2 (this gets Xcode4 to add it as a framework/dylib)
- edit “Header Search Paths” and add /usr/share/include/libxml2 (this gets Xcode4 to actually USE it when building)
- edit your Build Settings, and set “GCC_VERSION” to be: “com.apple.compilers.llvm.clang.1_0″
- add “QuartzCore.framework” to your iOS project.
The only one of those that’s particularly unusual is changing the Compiler to LLVM 1. If you don’t … the project won’t compile.
SVGKit: basic SVG files … use Reklis’ fork
Then I started opening Inkscape-generated files in SVGKit. Sadly, most files in Inkscape will – literally – crash SVGKit. There are major bugs in the parser, a combination of mis-reading the SVG spec, and a bit of really sloppy C code (buffer overruns in the parser! Ouch).
Fortunately, the parser has been completely rewritten by reklis, who’s fork seems to be now the “de facto” release of SVGKit. (incidentally, I tried emailing the original author, who I think is the only one that can update the main project, but his website email link is broken
. I’ve tweeted him too, hopefully he can pass-on the project to reklis to maintain).
UPDATE SPRING 2012: … the original author has now made it a shared project, with multiple admins.
…but there were still some major bugs. More than half of the Inkscape files wouldn’t render even vaguely correctly (although all the crashing bugs are fixed).
I delved into this, and it turned out to be two very small remaining bugs in the parser, which I was able to fix quite quickly, and merge back into reklis’ fork – if you grab his fork now, it should work pretty well.
SVGKit: …advanced SVG files
Unfortunately, the really complex / rich SVG files still fail in SVGKit. With my fixes, most of them render approximately correct – e.g. I have a version of the famous Tiger.SVG which gets the main outline exactly correct, but loses all the internal colours and objects.
Others – such as the almost-as-famous Lion.SVG – fail completely, you just get a big blob of colourless trash on screen
.
UPDATE: Lion.SVG now works OK. Colours are slightly wrong, but the complex image is rendering well – you actually get a lion now
However, all the Inkscape-authored files I’ve got are working fine, with all the tools (lines, curves, “freehand”) working as expected. That’s enough for most developer projects.
Guesses at fixing the remaining SVGKit bugs…
Just in case anyone reading this needs a perfect SVG renderer on iOS, and has the time to try and fix it, here’s some thoughts on what to look at next.
My guess is that the vast majority will render the correct *shape* (I’m confident those bugs are all fixed) – but there are some advanced curve shapes that no-one has implemented yet. I suspect that Lion.SVG is using them, hence why it’s such a big mess when it renders.
Separately, I think there’s an issue with z-order layering and/or the implementation of the “fill” command in SVG, that’s causing things like Tiger.SVG to be the right shape, but missing all their internal detail.
Hopefully, someone else can fix those soon. For now, I can say that everything I’ve got / made in Inkscape is working fine, which is good enough for me to get on with my game project.
UPDATE SPRING 2012: There is experimental support for CSS styles (which make the colours correct for every SVG file) – it’s not yet merged to the main fork (still needs testing).
Also, there is partial support for the “transform” attribute – currently only handles translation, not rotation. So, for instance, SVG files that have rotational symmetry (e.g. compass roses) fail badly. But this is coming soon…
Finally, there is partial support for SVG Text.
When all three of those have been tested and merged, SVGKit should be loading almost all SVG files correctly.