Thursday 16 July 2015

bring out the maths.

I wasn't going to bother with supporting the @'math{}'[sic] command in my texinfo backend, but a quick search found jlatexmath so I had a bit of a poke and decided to drop it in.

He's some examples as rendered in my browser:

The first of each row is rendered using jlatex math using Java2D, and the second is rendered by the browser (svg). They both have anti-aliasing via alpha and both render properly if the background colour is changed. Most of the blur differences seems to be down to a different idea of the origin for pixel centres although the browser is probably hinting too (ugh). But the png's are also only 4 bit as well; but they hold up pretty well and actually both formats look pretty decent. Alas the poor baseline alignment, but this is only a quick hack and not a complete typesetting system.

The SVG should at least scale a bit; unfortunately it tends to get out of alignment if you scale too much. Hinting maybe fucking it up?

When I did it I first I hacked up a really small bit of code which directly outputs SVG. It implements enough of a skeleton of a Graphics2D to support the TeXIcon.paintIcon() function. Only a small amount is needed to track the transform and write a string or a rectangle.

As an example, @math{E=mc^2} gets translated into this:

<svg xmlns="http://www.w3.org/2000/svg" width="65" height="18" version="1.1">
<text x="2.00" y="15.82" font-family="jlm_cmmi10" font-size="16.00">E</text>
<text x="18.26" y="15.82" font-family="jlm_cmr10" font-size="16.00">=</text>
<text x="35.14" y="15.82" font-family="jlm_cmmi10" font-size="16.00">m</text>
<text x="49.19" y="15.82" font-family="jlm_cmmi10" font-size="16.00">c</text>
<text x="56.12" y="9.22" font-family="jlm_cmr10" font-size="11.20">2</text>
</svg>

There are some odd limitations with svg used this way, no alt tag or way to copy the image pixels is a pretty big pair of problems. So I also looked into inline PNG and since I was going to that much effort seeing how small I could make it by using a 4-bit image.

After a bit of poking around I worked out how to generate a 4-bit PNG with the correct alpha directly out of javase. I render to a normal 8-bit image and then copy the pixels over to a special 4-bit indexed image using get/setRGB(), and the ImageIO PNG writer writes it correctly. Rendering directly to the image doesn't work (wrong colour selection or something to do with the alpha channel), nor does image.createGraphics().writeImage(8bitimage), although a manual data elements write should and will be the eventual solution.

It makes for a compact image and in base64 the image is about the same size as the svg.

<img alt="e=mc^2" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEE
AAAASBAMAAAD2w64vAAAAMFBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAABaPxwLAAAAD3RSTlMAESIzRFVmd4iZqrvM3e5GKvWZAAAA+0lEQVR42mNgoAg
wBhFSIcqRwMDAhE+F888GAip2MT4AWsXAwLbi1UfVpgvYlHCqQ4TzgEzshgQzQGyxYWD4i1UBy1k
HmAqHf1hVWO0F+oUFqIiXweEAknjlGSGZh7H+TJMvzFaG2MLybTbYVTOBYAqQu65mZeOaLwxa1Wo
wPVwLmByQjGDmCmA5wHCE4RiDEpgPMuMAwwFlhIq/LBeYLzDKMGsz3IM4l4FB8cA/Bt8JDJwTgNz
fOQwM+oe5D7BuUHoP8xADg/0kBrYPDAzf06FCOodZDrBulAUG5S+wrQyak7R96zORHFK4zvQWi+E
WNi7rC/iiRACMiAMA0lo9OMkFb4YAAAAASUVORK5CYII="></img>

FWIW this is how I create the image that I write to the PNG:

static BufferedImage createImage4(int w, int h) {
        int[] cmap = new int[16];
        for (int i = 0; i < 16; i++)
                cmap[i] = (i + (i << 4)) << 24;
        IndexColorModel cm = new IndexColorModel(4, 16, cmap, 0, true, 0, DataBuffer.TYPE_BYTE);

        return new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY, cm);
}

One might notice that the colour palette is actually all black and only the alpha changes - if a browser doesn't support the alpha colourmap then the image will be black. Bummer.

Wikipedia uses 4-bit png's for it's maths equations but I think it only has a transparent colour - and in any event they clearly only work if the background colour of the browser is white. Starting at fully white pages for 10+ hours pre day just burns your eyes out so I force my browser to roughtly amiga-console-grey because that's a colour someone actually thought about before using it. I think we can 'thank' microsoft for the brilliant white background in browsers as before IE they weren't so stupid to choose it as the default. White on black isn't much better either.

But as a result this is the sort of fucked up crap I get out of wikipedia unless I disable my style overrides:

I've started exporting it's pages to PDF so I can actually read them (using a customised mupdf which uses a grey background) but it's formatting leaves a little to be desired and if anything by making it appear like a paper it just emphasises any (of the many) shortcomings in the information content and presentation.

Pretty much any site with maths is pretty shit for that matter; everything from missing or low-quality 2-bit renders to fat javascript libraries that do the layout client-side. Dunno if this approach will be much better but I'm not going to need it very often anyway.

For various reasons from the weather to health to work I've been feeling pretty flat lately and it had me thinking about the past a bit. To think that i've gone from hand-coding raster interrupts and sprite multiplexors to writing information serving software "for fun" is pretty depressing. Computers used to be a much much more fun hobby.

3 comments:

Solerman Kaplon said...

At standard zoom level they both look ok, but the svg works best with greater zoom lvs. I too hate white backgrounds (and most "current" silver-ish-whatever colors themes most "modern" UI use these days), pity I still hit the wrong font/background combo when using dark themes on many linux apps, and java doesn't do much better on that area (eclipse plain sucks and nb been improving with custom color dark theme)

NotZed said...

Well i mean the specific svg that gets created by this code doesn't scale really well inside firefox - the layout starts to fall apart a bit as the scaled+hinted font-metrics starts to drift from the font metrics used by the layout engine in jlatexmath. The individual strokes are obviously cleaner in isolation of course.

The lack of an alt text for svg is a puzzling oversight, as for example if i drag/paste the text from a version with images in it I just get the images replaced by the raw latex - but with an embedded svg image I just get nothing. But there are other ways to embed the image which can probably address this (if i really cared!).

(i might've just missed some detail too, i didn't look into it terribly closely)

I had to customise emacs and netbeans with more subdued colours a couple of years ago. It's a pain as once you set a darkish grey background almost all of the of the default highlighting colours become unreadable. They're either too bright (like yellow/green) or too close to grey (red, pink, anything pastel, and so on). So you have to end up going through changing almost everything. The nimbus look and feel does most of the gui at least for netbeans but some parts like the output pane need to be set somewhere separately from the style editor.

Getting good fonts was also a bit of a pain. I ended up compiling a lucid+x11 emacs by hand so i could get misc-fixed fonts back (not to mention that the performance of the gtk display system is just dreadful). Had to do a lot of style editing in netbeans for that too (DejaVu Sans Mono aka Bitstream Vera all the way there).

DejaVu Serif Condensed is absolute killer for epaper readers too; it's the closest to paperback print in proportion and stroke.

NotZed said...

Oh and xterms too. Actually i gave up on things like ls colours and just disable them.

The two default alternatives of PC colours on white or PC colours on black are both dreadful.