(5) it really looks complicated without inserting fictitious narrow spaces into the line (which will cause kerning to break) or using something of a much higher level, such as SVG or HTML / CSS rendering.
However, if you don't mind keeping your hands dirty, it's pretty easy to hack a PIL rendering renderer to add horizontal space. See _imagingft.c ; after the following code in font_getsize and font_render:
if (kerning && last_index && index) { FT_Vector delta; FT_Get_Kerning(self->face, last_index, index, ft_kerning_default, &delta); x += delta.x >> 6; }
Add
if (last_index && index) { x += tracking; }
Try this with a simple integer to track (probably large enough, judging by the fact that “→ 6”); compile and see if it works. The next step would be to get the tracking value in the C function from Python, for which you would have to change the ParseTuple call in font_render to:
long tracking; if (!PyArg_ParseTuple(args, "Ol|il:render", &string, &id, &mask, &tracking)) return NULL;
And in font_getsize:
long tracking; if (!PyArg_ParseTuple(args, "O|l:getsize", &string, &tracking)) return NULL;
Then see which Python interface you want. This is a trivial but rather tedious case of adding an additional tracking argument through each level of the interface, for example:
def truetype(filename, size, index=0, encoding="", tracking= 0): # added optional tracking "Load a truetype font file." try: return FreeTypeFont(filename, size, index, encoding, tracking) # added tracking ... class FreeTypeFont: "FreeType font wrapper (requires _imagingft service)" def __init__(self, file, size, index=0, encoding="", tracking= 0): # added tracking import _imagingft self.font = _imagingft.getfont(file, size, index, encoding) self.tracking= tracking # add this line ... def getmask2(self, text, mode="", fill=Image.core.fill): size, offset = self.font.getsize(text, self.tracking) # use tracking im = fill("L", size, 0) self.font.render(text, im.id, mode=="1", self.tracking) # use tracking return im, offset
I have not tested anything! If this works, it might be worth sending a patch.