Thursday 18 June 2009

Rendering and Backends

As well as familiarising myself with the existing Mathtex code I have also been considering how to actually go about rendering parsed expressions. Matplotlib currently has a very rich collection of backends which all provide significantly more functionality than required by Mathtex — which only needs glyph setting and line drawing.

One of the outstanding issues, however, is that of FreeType. Although there are bindings for virtually every other programming language there are currently none for Python. (There are, however, two failed attempts.) As a result of this Matplotlib includes its own wrapper FT2Font which is C++ based.

In the current implementation of Mathtex all backends use this FreeType wrapper to get glyph metrics (width, height, advance, etc). Some backends then go on to use FreeType for the rendering, while others (such as PDF and SVG) do not. As glyph metrics are, for the most part, invariant I have been considering putting them in a table as opposed to reading them from the font file each time. This is similar to how TeX operates.

The immediate consequence of this would be that FreeType would not be a hard dependency — if one wishes to only produce PDF/SVG files (or use backends which use FreeType indirectly). However, it might lead to reduced rendering quality for bitmapped backends. (I am still investigating this; the reason being that FreeType provides hinted metrics, while a table would not.)

Assuming that there is no perceivable difference then it is likely that for most of the default fonts a look-up table will be produced. This will allow for separation of the parsing/rendering stages: one piece of code can parse the expression and produce a list of glyphs (at specific sizes, styles and locations) and another independent piece of code can then go onto render it. Furthermore this would make it easy for people to make use of Mathtex in their own applications, but just asking for a stream of glyphs/drawing ops and then rendering it themselves.

For the bitmapped backend (arguably the most common) it is likely to be written in C and abstracting away all of the FreeType/compositing operations — which are more natural in C than Python — and then using Cython to create a Python wrapper for it.

If both of these prove viable then they will serve the purpose of sidestepping the FreeType + Python issue entirely. Of course, I think most agree that a well maintained FreeType wrapper for Python is the way to go (and is something I will consider if I have time at the end of my project).

Otherwise my current plan is to use FT2Font from Matplotlib as a wrapper around FreeType. Expect an answer in the next couple of days :)

3 comments:

  1. I've never done enough investigation to know if it's viable -- but there is a ctypes-based FreeType wrapper included in pyglet. It should probably at least be looked at to determine if it's suitable.

    ReplyDelete
  2. Just looking over the documentation for pyglet it seems as if it is quite a high level wrapper and does not provide the low-level access to glyph info we require.

    ReplyDelete
  3. One GSOC project is implementing freetype wrappers for pygame:
    http://www.bellverde.org/gsoc


    maybe the current pygame font module would be useful too... it allows you to get some glyph metrics - using freetype.

    http://www.pygame.org/docs/ref/font.html#Font.metrics

    cheers,

    ReplyDelete