2

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:

  1. Chioce of the font face via FontDialog,GetFontData() menthod.

  2. Retrieving a list of paths of the font via fontconfig.query() method.

  3. Filtering a path which matches exactly with the font choosen by the user, with size, weight and style.

  4. 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()

0 Answers0