weasyprint and glyphicons font on Windows 7: couldn’t load font “Glyphicons Halflings Not-Rotated 21px”

I recently developed tooling using python 2.7. It runs on Windows 7 (using portable python) and Linux, will do something and produce both HTML and PDF output. I used Twitter Bootstrap to format the HTML page and I created a PDF using that HTML page. Should be easy, as weasyprint is pretty mature and actually works on Windows, but pango was emitting couldn't load font messages. Simply installing the font was impossible, as it required administrator access to the operating system

So here’s are the messages pango emitted, for the developers landing here via a query using the search engine of choice:

(python.exe:xxxx): Pango-WARNING **: couldn't load font "Glyphicons Halflings Not-Rotated 21px", falling back to "Sans Not-Rotated 21px", expect ugly output.

(python.exe:xxxx): Pango-WARNING **: couldn't load font "Glyphicons Halflings 21px", falling back to "Sans 21px", expect ugly output.

So this was my first encounter with fonts, pango and whatever else. I can’t say it was easy until I stumbled upon the regfont tool. regtool adds (or removes) fonts to your system using a file and it doesn’t require admin access to do so. The font remains installed until you reboot the machine. My first idea was to use regfont to install the font at startup, but I figured I would probably forget about it when the the operating system would be reinstalled. Plus it didn’t make sense to install it at boot time, as I only needed it when the tooling ran. So I took a look at the code and learned that, much to my surpise, installing a font was real simple and I could probably add it to the tooling.

This is how I installed the font:

import ctypes
font_filename = "glyphicons-halflings-regular.ttf"
# See http://msdn.microsoft.com/en-us/library/windows/desktop/dd183326(v=vs.85).aspx
nfonts = ctypes.windll.gdi32.AddFontResourceW(unicode(font_filename ))
if nfonts > 0:
  print 'Installed %d fonts from %s'%(nfonts, font_filename,)
elif 0 == nfonts:
  # Something went wrong installing the fonts.

Check the filename (including proper backslash escaping) when nfonts == 0. You’ll probably get the idea.

The original source code included a broadcast to update windows open prior to the installation of this font, but I figured I didn’t need it and left it out.

Looking through the code quickly revealed there’s a way to uninstall the font too. Here’s how I implemented it:

import ctypes
font_filename = "glyphicons-halflings-regular.ttf"
# See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162922(v=vs.85).aspx
nfonts = ctypes.windll.gdi32.RemoveFontResourceW(unicode(font_filename ))
if nfonts > 0:
  print 'Uninstalled %d fonts from %s'%(nfonts, font_filename,)
elif 0 == nfonts:
  # Something went wrong uninstalling the fonts.

I used this on Portable Python 2.7, which comes with ctypes included. Here’s a tip: add media_type = 'screen' to the weasyprint.HTML call. Your PDF will look a lot more like the page.

Thanks for reading. Let me know when this was incomplete.

Leave a Reply

Your email address will not be published. Required fields are marked *