Skip to content

Instantly share code, notes, and snippets.

@ZoomTen
Created July 9, 2022 07:34
Show Gist options
  • Save ZoomTen/478de2494e9f7cd88be83422ce047122 to your computer and use it in GitHub Desktop.
Save ZoomTen/478de2494e9f7cd88be83422ce047122 to your computer and use it in GitHub Desktop.
HOWTO: Convert .pcf(.gz) fonts into TTF

Converting PCF fonts to TTF

Let's assume we're converting helvBO24.pcf, a version of Helvetica Bold Oblique for 24px that comes with X11. The output file will be helvBO24_fixed.ttf.

Step 1

Convert the thing to bdf through pcf2bdf

pcf2bdf helvBO24.pcf > helvBO24.bdf

Step 2

Run the bdf through BitsNPicas to convert it to a basic TTF with nonsensical metadata

java -jar BitsNPicas.jar convertbitmap -f ttf -o helvBO24.ttf helvBO24.bdf

Step 3

Run the generated TTF through a Python script with FontForge installed to correct the metadata

python fix-ttf.py helvBO24.ttf Helvetica bold -i 24

Step 4

Install the font file

cp helvBO24_fixed.ttf ~/.local/share/fonts
#!/usr/bin/python
import argparse as ap
import os
import fontforge
AP = ap.ArgumentParser()
AP.add_argument('font_file',
help='TTF file converted from BDF')
AP.add_argument('family_name',
help='original name of the font')
AP.add_argument('weight',
help='weight of the font',
choices=['regular', 'bold'])
AP.add_argument('-i','--italic',
help='treats the font as an italic variant',
action='store_true')
AP.add_argument('size',
help='size in pixels')
AP.add_argument('-o','--output',
help='where to save the fixed TTF')
args = AP.parse_args()
# ------------ font conversion ------------
if isinstance(args.output, str):
OFILE = args.output
else:
OFILE = (
os.path.splitext(args.font_file)[-2]
) + '_fixed.ttf'
FFILE = args.font_file
WEIGHT = args.weight.capitalize()
CLASSIFIER = WEIGHT
FAMILY = '_'.join([args.family_name, args.size])
if args.italic:
CLASSIFIER += ' Italic'
stylemap = {
"Regular": 64,
"Regular Italic": 1,
"Bold": 32,
"Bold Italic": 33
}
hfont = fontforge.open(FFILE)
hfont.reencode('iso10646-1')
frname = 'Italic' if CLASSIFIER == 'Regular Italic' else CLASSIFIER
hfont.sfnt_names = ()
hfont.sfnt_names = hfont.sfnt_names + (('English (US)', 'SubFamily', frname), )
hfont.fontname = f"{FAMILY.replace(' ','')}-{frname.replace(' ','')}"
hfont.familyname = FAMILY
hfont.weight = WEIGHT
hfont.fullname = f'{FAMILY} {CLASSIFIER}'
hfont.os2_stylemap = stylemap[CLASSIFIER]
hfont.generate(OFILE)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment