SVGKit (iOS) now supports more SVG’s – including most Wikipedia maps

Finally got the complicated viewBox / transform-matrix code working for SVGKit. Net result: the remaining maps from Wikipedia that used to fail catastrophically now render perfectly, e.g. their European map:

Why so hard?

For the curious…

This European map is specified at “180,000 units wide and 150,000 units high”, but … “Oh, by the way, we suggest you render it at 1800 pixels by 1500 pixels”.

This is a problem unique to scalable vector graphics (and part of what makes vector images so interesting). There is *no* “correct” size for a vector image – it can be rendered at *any* size, by definition.

Unlike a bitmap (i.e. the images used in 99% of situations today), a vector image never goes “blurry” or “pixellated”. If you want to view it at ultra-high res, you’re welcome.

And, because some code in the world still uses low-quality “floats” to store data (which are very inaccurate at high numbers), a lot of the world’s SVG files are specified using large integer numbers, and they assume you will “scale down” to your desired display size. Which is great. Except that (until today) SVGKit didn’t support that scaling, and tried to render everything literally, causing huge memory use and crashes.

NB: all this is currently in an experimental branch of SVGKit – we’re hoping to merge it into the master branch soon, but for now you’ll have to access this directly from https://github.com/adamgit/SVGKit/tree/transforms or not at all – sorry!

Preview: RISK clone boardgame

A couple of preview shots from the boardgame we’re working on. Still a long way to go – most of the art below is just placeholder – but the 3D globe (part of the core interface) is looking rather tasty, especially when you interact with it:

…all shots taken straight off the iPad3 (massively downsized to fit on a webpage – originals are 5MB+ each. iPad3 has a very big screen!)

A very nasty bug in Apple’s compiler?

Just ran into this recently. Took a while to work this out – it seems to be a bug in Apple’s compiler (either that, or I massively misunderstand the scoping rules Apple is using). I didn’t try analysing the assembler output – I didn’t have time, this was for a project that had to ship yesterday!

(this is on the Apple LLVM 3.1 compiler – as shipped with latest/current Xcode)

In this code:

{
NSArray* a = ...get array...

if( something that is true )
{
NSString* p = [a objectAtIndex:0];

// 1. What is "p" at this point?

NSLog( @"%@", [p uppercaseString] );

// 2. What is "p" at this point?

NSLog( @"%@", [p uppercaseString] );

}

UIViewController* p = self.presentingViewController;
}

…it turned out that “p” was simultaneously both variables, with both values (which I thought would be impossible, code-wise: they are defined in non-overlapping scopes). Even more strangely (c.f. below) … Apple seemd to flip-flop between which of the two variables it used at each moment.

Stepping through with the debugger, 2 lines (and one scope!) before the second “p” variable was even declared, it already existed *and already had been defined*.

Maybe this is an obscure piece of Objective-C lore, but it looks to me like a major violation of C rules (hence: I think it’s a pre-emptive performance optimization gone wrong).

NB: the first call to

[s uppercaseString]

worked fine. The second call crashed repeatedly complaining that UIViewController doesn’t conform to selector uppercaseString. It seems that at points “1.” and “2.” the dereferencing of “p” pointed first to the String pointer, and second to the UIVC pointer.

NB: the braces above are exactly as in the source.

Solution

Rename either of the variables and – unsurprisingly – things work as expected. It was a quick “fix” – but worrying that it was needed.

I have almost zero knowledge of the internals of modern C compilers – so if the above behaviour is actually correct, and my understanding is wrong, I’d love it if someone can point to an explanation for this.