My name is Fabio and I'm really glad to meet your community! I faced a problem working fonts with wxPython, PIL and fontconfig. In the beginning I wanted to use PIL to write a text in a tiff image, and I used ImageFont.truetype to load the font in a variable. The truetype method needs the full path to the ttf font, as I know.
I don't like hardcoding, so I used wx.FontDialog class to let the user pick a font, and save the fontpath in a simple binary file. The problem is that the method FontDialog.GetFontData() returns simply the Font Face, and not the font path.
The solution seems to be the fontconfig module: using the fontface, the fontconfig.query method return almost exactly what I need, I mean a list with font full paths. Then another problem raises: I must choose ONE path in the list, so I want to filter the list, selecting the correct fontweight and style.
The properties returned by FontDialog seem to be quite confusing, for example I found that wxnormal can mean "Normal","Regular","Medium","Book","Roman","Condensed","Linemorph","Gothic", wxbold can be used for "Bold","Demi Bold","Demi","Heavy". It's hard to set a good filter, the constants between the two classes are completely different too.
Summing up I want to follow those steps to get my result:
Chioce of the font face via FontDialog,GetFontData() menthod.
Retrieving a list of paths of the font via fontconfig.query() method.
Filtering a path which matches exactly with the font choosen by the user, with size, weight and style.
Returning the font path to the Imagefont.truetype method.
As follows You can read a short example I wrote to explain better what I mean. It solves points 1 and 2 but stops at point 3. Any suggestions will be sincerely appreciated.
Fabio
import wx
import fontconfig
#os.path.join(os.environ['WINDIR'], 'Fonts')
class TF(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "", size=(800, 500), pos=(400, 400))
pan = wx.Panel(self, -1)
self.lbl = wx.TextCtrl(pan, -1, pos=(0,30), size=(750, 210), style=wx.TE_MULTILINE|wx.TE_AUTO_SCROLL)
self.txt = wx.TextCtrl(pan, -1, pos=(0,240), size=(750, 250), style=wx.TE_MULTILINE|wx.TE_AUTO_SCROLL)
self.cmdFontDialog = wx.Button(pan, -1, "A", size=(30,30))
self.Bind(wx.EVT_BUTTON, self.onFontDialog, self.cmdFontDialog)
def propertiesWX(self, fontData):
strLbl = ""
strLbl += "-" * 50 + "\n"
strLbl += fontData.GetChosenFont().GetFaceName() + "\n"
strLbl += fontData.GetChosenFont().GetFamilyString() + "\n"
strLbl += str(fontData.GetChosenFont().GetFamily()) + "\n"
strLbl += fontData.GetChosenFont().GetWeightString() + "\n"
self.lbl.SetValue(strLbl)
def propertiesFC(self, family):
lst = fontconfig.query(family=family)
obj = []
for f in lst:
obj.append(fontconfig.FcFont(f))
strLbl = ""
for font in obj:
strLbl += "*" * 50 + "\n"
strLbl += "FONT FAMILY: " + font.family[0][1] + "\n"
strLbl += "FONT FILE: " + font.file + "\n"
strLbl += "FONT FULLNAME: " + font.fullname[0][1] + "\n"
strLbl += "FONT FORMAT: " + font.fontformat + "\n"
strLbl += "FONT STYLE: " + font.style[0][1] + "\n"
strLbl += "FONT WEIGHT: " + str(font.weight) + "\n"
strLbl += "SLANT: " + str(font.slant) + "\n"
strLbl += "CAPABILITY: " + font.capability + "\n"
strLbl += "WIDTH: " + str(font.width) + "\n"
self.txt.SetValue(strLbl)
def onFontDialog(self, evt):
dlg = wx.FontDialog(None, wx.FontData())
if dlg.ShowModal() == wx.ID_OK:
fontData = dlg.GetFontData()
tf.propertiesWX(fontData)
tf.propertiesFC(fontData.GetChosenFont().GetFaceName())
if __name__ == '__main__':
app = wx.PySimpleApp()
tf = TF()
tf.Show()
app.MainLoop()