I’ve been increasingly interested in QR codes as of late, for reasons that Glenn Fleishman articulated far better than I could. I also just find them rather fascinating as a format. There’s a lot of redundancy to account for errors and damage (wonderfully demonstrated here), and a handful of possible masks that overlay all of the data means that the exact same data will have myriad possible representations. I’ve also been curious as to the most efficient ways to store and present the data (GIFs and 1 bit/pixel PNGs done at the pixel-level and then scaled up seem pretty good1), and got to wondering if Unicode Block Elements (2580-259F) would work. As above, they seem to, albeit with the entire block scaled to 60% vertical height and the line-height condensed. Also, Hack (the monospace font I use on this site) seems to render 2588, FULL BLOCK, as a quarter-sized block centered in the space that it should be filling up all of. So I substituted 2593, DARK SHADE, which works. Also, the squareness and contiguousness of the thing seems to be crucial for recognition, far more so than the integrity of the actual data within.
This was a truly pointless exercise, but hey, it’s a thing that can be done.
Humorously, the GIF is less than half the byte size of this UTF-8 rendering, and the PNG only slightly larger than the GIF.
SVGs, via the <use> tag, are capable of symbolic references. If I know I’m going to have ten identical trees in my image, I can simply create one tree with an id="tree" inside of an undrawn <defs> block, and then reference it ten times inside the image along the lines of <use xlink:href="#tree" x="50" y="50"/>.
A billion laughs is a bomb-style attack in which an XML document makes a symbolic reference to an element ten times, then references that symbol ten times in a new symbol, and again, and again, until a billion (109) of these elements are being created. It creates a tremendous amount of resource consumption from a few kilobytes of code. Will symbolic references in an SVG behave similarly?
I briefly searched for SVG bombs, and as expected mostly came up with clipart. I did find one Python script for generating SVG bombs, but it relied on the same XML strategy as the classic billion laughs attack1. The answer is that yes, in about 2.3kB we can make a billion points and one very grumpy web browser:
It works precisely the same way as a billion laughs: it creates one point, a, at 0,0; then it creates a group, b with ten instances of a; then group c with ten instances of b; and so on until we have 109 (+1, I suppose) instances of our point, a. I’m not entirely sure how a renderer handles ‘drawing’ a single point with no stroke, etc. (essentially a nonexistent object), but it is interesting to note that if we wrap the whole thing in a <defs> block (which would define the objects but not draw them), the bomb still works. Browsers respond a few different ways…
Well, this sucks. My host, NFSN, is doing a major overhaul to their pricing scheme simply because the internet has become such a horrible hotbed of malice. To be clear, when I say ‘this sucks’, I don’t mean any negativity toward NFSN. The article link up there goes to their blog post explaining the matter, and it frankly seemed inevitable that fighting DDOS attacks would catch up to their pricing scheme. Previously, if you had a static site with low bandwidth and storage, you could probably get a year out of a quarter (domain registration not included, of course). The new plan allows for basically a $3.65 annual minimum which is still impressive (especially given what NFSN offers). But it’s a bummer that it’s come to this.
I would like to reiterate that this is not a complaint against NFSN. I will continue to use them for hosting, I will continue to recommend them, I will continue to praise them. I believe this is a necessary move. I’m just really, really pissed off that this is where we are with the internet. I don’t know what’s going on behind the scenes as far as law enforcement, but the internet is a global network (really?) and that’s not an easy problem to solve. I just hope something is happening to clean this wasteland up, because the advancements we’ve made in the information age are too important to bury under a sheet of malice.
For someone rooted in graphic design and illustration, I typically hate running across visuals on the internet. Aside from being numbed by ads, the fact of the matter is that a large percentage of the graphical presentation on the web is just bandwidth-stealing window dressing with little impact on the surrounding content. Part of my plan with this blog was to avoid graphics almost entirely, and yet over the past month or so, I have littered this space with a handful of SVGs. I think, for the most part, they have added meaningful visual aids to the surrounding content, but I still don’t want to make too much of a habit of it.
I’m far more comfortable with SVGs (or, vector graphics in general) because I find it easier to have them settle onto the page naturally without becoming jarring. I could obviously restrict the palette of a raster image to the palette of my site, and render a high resolution PNG with manageable file size, but scaling will still come into play, type may be mismatched… aside from being accessibility issues, these things have subtle effects on visual flow. I’m thankful that SVG has been adopted as well as it has, and that it’s relatively simple to write or manipulate by hand. Following is the process I go through to make my graphics as seamless as possible.
Generally speaking, the first step is going to be to get my graphic into Illustrator. Inside Illustrator, I have a palette corresponding to my site’s colors. Making CSS classes for primary, secondary, tertiary colors is in my to-do list, but I need to ensure nothing will break with a class defining both color and fill. Groups and layers (mostly) carry over when Illustrator renders out an SVG, so I make a point of going through the layer tree to organize content. Appearances applied to groups cascade down in the output process, so (as far as SVG output is concerned) there’s no point in, say, applying a fill to a group – each individual item will get that fill in the end anyway. I use Gentium for all of the type, as that is ideally how it will be rendered in the end, though it’s worth quickly checking how it all looks in Times New Roman as well.
Once I get things colored and grouped as I need them, I crop the artboard to the artwork boundaries. This directly affects the SVG viewbox, and unless I need extra whitespace for the sake of visually centering a graphic, I can rely instead on padding or the like for spacing.
Once in the SVG Save dialog, I ensure that ‘Type’ is set to ‘SVG’. I don’t want anything converted to an outline, because I want the type to visually fall back with the rest of my page. I never actually save an SVG file from Illustrator, I just go to ‘SVG Code…’ from the Save dialog, and copypaste it elsewhere for further massaging. This involves:
Setting width="100%" and height="15em"1, or somewhere near that as far as height is concerned. This keeps the images centered and prevents unsightly scaling issues on mobile.
Removing all references to font-family, which ensures that my page’s font cascades down. Generally this means that it’ll render in Gentium as when I was designing it, but if the page falls back for whatever reason, the graphic will too.
Ensuring unique IDs are used. If I didn’t name layers, etc. in Illustrator, I could wind up with several objects on a page with id="Layer1", which would obviously violate HTML spec.
Getting rid of any empty groups. Sometimes Illustrator just throws in a bunch of <g></g> at the end for no discernible reason.
Grouping similar objects, as best as possible, applying shared attributes to the group instead of individual objects
Deleting empty <rect>s, which Illustrator creates around text boxes. Presumably this is because, in Illustrator, text boxes themselves can have appearances applied to them like any other object. It would be nice if it was smart enough to only carry this over if there was some sort of appearance, though.
Adding a <title> if a description is necessary, or aria-hidden="true" to the SVG if the image can be ignored by assistive technology.
Likewise, if the graphic is being ‘read’, adding aria-hidden="true" to (likely) all of the text elements within. In my diagrams, assistive tech users certainly don’t need to hear a bunch of random numbers without context, especially when I’ve provided a <title>.
Illustrator seemingly outputs SVG with the intent being structural accuracy if the file is read back in for editing, which is often counterproductive for web use, which would prioritize small filesize without a sacrifice in selection ordering or visual accuracy. To be fair, I just installed 2018 and haven’t tested its SVG waters yet, so we’ll see how Adobe managed to mess that up handle that.
Finally, it’s worth mentioning SVGO (and the web-based SVGOMG). Very customizable optimization, definitely more useful once one starts dealing with more intricate, complicated SVGs. I’m happy to optimize mine down by hand, and stop there – but I’m keeping them to a handful of kilobytes anyway.
This used to say height="15rem", but apparently, rem is an invalid unit for declaring the height of an SVG. I am going through and replacing all of these height declarations with ems instead. This is weird to me, and Chrome and IE/Edge both take no issue with use of rems, but Firefox renders them full-bore.
Well, I was right about one thing – there was a straightforward solution to this whole Aztec diamond problem. To be fair to myself, my original solution holds up – I neglected to add one somewhere in my equation (we’ll get to that later), an error that was insignificant at the start, and less significant as the Aztec numbers increased. To get to the reveal, it’s worth backing up to our series, OEIS: A046092 again. Somehow, in my haste, I kind of glossed over the fact that these are ‘4 times triangular numbers,’ a fact that became readily apparent to me when I was coming up with the diagrams for the last post. You see…
…our Aztec diamond is made up of four triangles; and it is in fact true that each of our Aztec numbers is 4× the corresponding triangle number. A funny thing about triangle numbers is that if you multiply them by eight and add one, they become perfect squares. This can be demonstrated visually:
So, we know that for our Aztec number, x, x/4 is a triangle number, and for this triangle number, y, 8y+1 is a perfect square. We know that any given side of this square is made up of 2× the length of a side of triangle y plus one, which is ultimately the value that we need to recreate our square from our grid. We can see this rather clearly in the first diagram with the triangle highlighted – the three dots forming the outer side correspond directly to segments of our grid.
Thus, given a triangle number, y, the length of any of its sides is (sqrt(8y+1)-1)/2. Which then leads us to the same thing for our Aztec number, x, (sqrt(2x+1)-1)/2. Now, to solve my problem, I actually need to add one to this. Given that we’re dealing with integers, this can be simplified to ceil(sqrt(2x+1)/2) – precisely what I originally came up with, aside from the +1.
So, my equation was wrong, but it provably works – the off-by-one error is clearly insignificant for a 3×3 square, and, given x, sqrt(x2)-sqrt(x2-1) converges toward zero: