(5) 文字列にダミーの狭いスペースを挿入する (カーニングが壊れる) か、SVG や HTML/CSS レンダラーのようなはるかに高レベルのものを使用する以外は、確かにトリッキーに見えます。
ただし、手を汚してもかまわない場合は、PIL の freetype レンダラーをハッキングして水平方向のスペースを追加するのは非常に簡単に見えます。_imagingft.cを参照してください。font_getsize と 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;
}
追加:
if (last_index && index) {
x += tracking;
}
最初に追跡用の単純な整数で試してみてください(おそらく「>>6」で判断するとかなり大きい)。コンパイルして、動作するかどうかを確認します。次のステップは、追跡値を Python から C 関数に取得することです。そのためには、font_render の ParseTuple 呼び出しを次のように変更する必要があります。
long tracking;
if (!PyArg_ParseTuple(args, "Ol|il:render", &string, &id, &mask, &tracking))
return NULL;
そしてfont_getsizeで:
long tracking;
if (!PyArg_ParseTuple(args, "O|l:getsize", &string, &tracking))
return NULL;
次に、必要な Python インターフェイスを確認します。これは些細なことですが、インターフェイスの各レベルを介して追加の「追跡」引数を追加する非常に面倒なケースです。たとえば、次のようになります。
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
私はこれをテストしていません!動作する場合は、パッチとして提出する価値があるかもしれません。