Skip to content

Instantly share code, notes, and snippets.

@petrblahos
Created October 21, 2023 10:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petrblahos/a1be2f125b8ae541a2b78e7f772996a1 to your computer and use it in GitHub Desktop.
Save petrblahos/a1be2f125b8ae541a2b78e7f772996a1 to your computer and use it in GitHub Desktop.
Drawing text with a font, using kerning info.
from collections import defaultdict
import wx
from fontTools.pens.wxPen import WxPen
from fontTools.ttLib import TTFont
class MyFrame(wx.Frame):
def __init__(self, ttfont: TTFont):
wx.Frame.__init__(self, None, -1, "Font painter")
self.font = ttfont
self.prepare_kerning()
self.Bind(wx.EVT_PAINT, self.on_paint)
def prepare_kerning(self):
self.kerning_pairs = defaultdict(int)
if not "kern" in self.font:
return
for kern_table in self.font['kern'].kernTables:
assert kern_table.version == 0, "kern table version other than 0 not supported"
self.kerning_pairs.update(kern_table.kernTable)
def on_paint(self, evt):
evt.Skip()
t = "VAVA7FAT"
dc = wx.PaintDC(self)
gc = wx.GraphicsContext.Create(dc)
height = self.GetSize()[1]
units_per_em = self.font['head'].unitsPerEm
scale = height / 4 / units_per_em
m = gc.CreateMatrix()
m.Translate(0, height // 2)
m.Scale(scale, -scale)
cmap = self.font['cmap'].getBestCmap()
for unicode in t:
glyph_name = cmap.get(ord(unicode))
if not glyph_name:
glyph_name = ".notdef"
glyph = self.draw_glyph(gc, glyph_name, m, wx.RED_BRUSH)
m.Translate(glyph.width, 0)
m = gc.CreateMatrix()
m.Translate(0, height // 2)
m.Scale(scale, -scale)
last = None
cmap = self.font['cmap'].getBestCmap()
for unicode in t:
glyph_name = cmap.get(ord(unicode))
if not glyph_name:
glyph_name = ".notdef"
m.Translate(self.kerning_pairs[last, glyph_name], 0)
glyph = self.draw_glyph(gc, glyph_name, m, wx.BLACK_BRUSH)
m.Translate(glyph.width, 0)
last = glyph_name
def draw_glyph(self, gc, glyph_name, m, brush):
glyph = self.font.getGlyphSet()[glyph_name]
pen = WxPen(self.font.getGlyphSet())
glyph.draw(pen)
pen.path.Transform(m)
gc.SetBrush(brush)
gc.FillPath(pen.path)
return glyph
def show_ui(font):
app = wx.App()
frame = MyFrame(font)
frame.Show()
frame.Maximize(True)
app.MainLoop()
if "__main__" == __name__:
show_ui(TTFont("/usr/share/fonts/truetype/liberation2/LiberationSans-Regular.ttf"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment