I am trying to pull a few fonts from Google Fonts and I only need the letters that go into each font name to be shown in that font, so I optimize the query with the text=FontName query parameter to get small files back. No problems there.
My challenge is that I would like to merge each @font-face into one css file and base64-encode the font file, but I can't seem to get the base64 encoding right in Python.
I don't know of any good way to troubleshoot base64 encoding, but what I have done is that I have downloaded the font files and uploaded them to FontSquirrel's Webfont Generator and downloaded base64 encoded versions that work as intended. I have then compared them to the corresponding ASCII representation of my encodings and concluded that they are not comparable - so somethings wrong.
Here's my code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import base64, urllib2
font_names = ['Lobster', 'Pacifico', 'Acme']
base_url = 'https://fonts.googleapis.com/css?family='
def get_url(url_string):
return url_string.split('url(')[1].split(')')[0]
def get_format(url_string):
return ' format(' + url_string.split('format(')[1]
font_lines = []
for font in font_names:
font_url = base_url + font + '&text=' + font
# font_face = urllib2.urlopen(font_url).read()
for line in urllib2.urlopen(font_url):
if 'src:' in line:
url = get_url(line)
font_format = get_format(line)
base64_font = base64.b64encode(urllib2.urlopen(url).read())
font_lines.append('src: url(data:font/ttf; base64, ' + base64_font + ')' + font_format)
else:
font_lines.append(line)
with open('fonts.css', 'w') as font_file:
for line in font_lines:
font_file.write(line)
By the way, I got the files for uploading into Fontsquirrel by simply opening the URLs in the src properties in the @font-face expressions I got from the original font request to Google fonts. When opening them in a browser, the file is downloaded.
So, just to illustrate, the start of my base64-encoded version of the Lobster font looks like this:
AAEAAAAQAQAABAAAR1BPU0R0THUAAAEUAAAAHkdTVUJl3GDLAAAE
The same font, base64-encoded, by Fontsquirrel looks like this:
AAEAAAASAQAABAAgRkZUTY3tsD4AAAEsAAAAHEdERUYAJwAgAAABSAAAAB5HUE9TI5w
Strangely enough, they look the same in the beginning and then start to differ. I have done the encoding on a Windows 7 machine.
I found a solution. Instead of:
base64.b64encode(s)
I have to use:
base64.standard_b64encode(s)
It is not particularly clear from the documentation, but apparently the b64encode method does not use the standard Base64 alphabet. It says it uses Base64 and I assumed that was the same as the standard Base64 alphabet. But apparently not. Anyway, the standard_b64encode method uses the standard Base64 alphabet and that seems to do the trick in this case.
It is not clear to me why it is ok to use the b64encode method to encode images when I have to use the standard_b64encode method to get it to work for font files. Anyway, it works now - I'm happy. Hope this might help others as well. Cheers!