Add --copy-character-glyphs option

Whether character glyphs are copied is now controlled by the command
line options rather than by `ligatures.py`.
This commit is contained in:
Ben Kelly 2018-01-27 10:27:40 -05:00 committed by Ben Kelly
parent ba71329c48
commit ce11b2e92f
3 changed files with 50 additions and 30 deletions

View File

@ -49,12 +49,12 @@ Use automatic mode to easily convert 1 or more font(s).
### Manual ###
1. Move/copy the font you want to ligaturize into `input-fonts/` (or somewhere else convenient).
2. Edit `ligatures.py` to disable any ligatures you don't want, and/or enable any (non-ligature) characters you want from Fira Code in addition to the ligatures.
2. Edit `ligatures.py` to disable any ligatures you don't want.
3. Run the script: `$ fontforge -lang=py ligaturize.py <INPUT> <OUTPUT>`, e.g. `$ fontforge -lang=py ligaturize.py input-fonts/Cousine-Regular.ttf output-fonts/CousineLigaturized-Regular.ttf`
The font family and weight for the output font (as recorded in the file) will be automatically set based on the name; if the output is `CousineLigaturized-Regular.ttf`, the font family will be `CousineLigaturized` and the font weight will be `Regular`. If no weight is specified, `Regular` is the default.
`ligatures.py` supports some additional command line options to (e.g.) change which font ligatures are copied from; run `fontforge -lang=py ligaturize.py --help` to list them.
`ligatures.py` supports some additional command line options to (e.g.) change which font ligatures are copied from or enable copying of individual character glyphs; run `fontforge -lang=py ligaturize.py --help` to list them.
## Misc. ##
### Credit ###

View File

@ -1,20 +1,28 @@
## This is the master list of ligatures that ligaturize.py will attempt to copy
## from Fira Code to your output font. Ligatures that aren't present in the
## version of Fira Code you're using will be skipped.
## To disable ligatures, simply comment them out in this file.
ligatures = [
## These are all the punctuation characters used in Fira Code ligatures.
## Uncomment this block to enable copying of these characters as well; it
## will make punctuation blend in with the ligatures more cleanly, at the
## cost of blending in with the rest of the font not as well.
## You can also edit the 'chars' list to change exactly which characters
## will be copied.
# {
# 'chars': [
# 'ampersand', 'asciicircum', 'asciitilde', 'asterisk', 'at',
# 'backslash', 'bar', 'braceleft', 'braceright', 'bracketleft', 'bracketright',
# 'colon', 'dollar', 'equal', 'exclam', 'greater', 'hyphen',
# 'less', 'numbersign', 'parenleft', 'percent', 'period', 'plus',
# 'question', 'semicolon', 'slash', 'underscore',
# ],
# 'firacode_ligature_name': None,
# },
{
## These are all the punctuation characters used in Fira Code ligatures.
## Use the `--copy-character-glyphs` option to copy these into the output
## font along with the ligatures themselves.
'chars': [
## These characters generally look good in most fonts and are
## enabled by default if you use `--copy-character-glyphs`.
'ampersand', 'asciicircum', 'asciitilde', 'asterisk',
'backslash', 'bar',
'colon', 'equal', 'exclam', 'greater', 'hyphen',
'less', 'numbersign', 'percent', 'period', 'plus',
'question', 'semicolon', 'slash', 'underscore',
## These characters are also used by the ligatures, but are likely
## to look more out of place when spliced into another font.
# 'at', 'braceleft', 'braceright', 'bracketleft', 'bracketright',
# 'dollar', 'parenleft', 'parenright', 'underscore',
],
'firacode_ligature_name': None,
},
{ # &&
'chars': ['ampersand', 'ampersand'],
'firacode_ligature_name': 'ampersand_ampersand.liga',

View File

@ -66,10 +66,10 @@ def split_camel_case(str):
class LigatureCreator(object):
def __init__(self, font, firacode):
def __init__(self, font, firacode, opts):
self.font = font
self.firacode = firacode
self.opts = opts
self._lig_counter = 0
def copy_ligature_from_source(self, ligature_name):
@ -81,16 +81,24 @@ class LigatureCreator(object):
except ValueError:
return False
def copy_character_glyphs(self, chars):
if not self.opts.copy_character_glyphs:
return
print("Copying %d character glyphs from %s..." % (
len(chars), self.firacode.fullname))
for char in chars:
self.firacode.selection.none()
self.firacode.selection.select(char)
self.firacode.copy()
self.font.selection.none()
self.font.selection.select(char)
self.font.paste()
def add_ligature(self, input_chars, firacode_ligature_name):
if firacode_ligature_name is None:
# No ligature name -- we're just copying a bunch of individual characters.
for char in input_chars:
self.firacode.selection.none()
self.firacode.selection.select(char)
self.firacode.copy()
self.font.selection.none()
self.font.selection.select(char)
self.font.paste()
self.copy_character_glyphs(input_chars)
return
if not self.copy_ligature_from_source(firacode_ligature_name):
@ -98,7 +106,6 @@ class LigatureCreator(object):
return
self._lig_counter += 1
ligature_name = 'lig.{}'.format(self._lig_counter)
self.font.createChar(-1, ligature_name)
@ -106,7 +113,6 @@ class LigatureCreator(object):
self.font.selection.select(ligature_name)
self.font.paste()
self.font.selection.none()
self.font.selection.select('space')
self.font.copy()
@ -191,6 +197,12 @@ def parse_args():
help="The file to copy ligatures from. If unspecified, ligaturize will"
" attempt to pick a suitable one from fira/ based on the input"
" font's weight.")
parser.add_argument("--copy-character-glyphs",
default=False, action='store_true',
help="Copy glyphs for (some) individual characters from the ligature"
" font as well. This will result in punctuation that matches the"
" ligatures more closely, but may not fit in as well with the rest"
" of the font.")
return parser.parse_args()
args = parse_args()
@ -207,7 +219,7 @@ print('Reading ligatures from %s' % ligature_font_path)
firacode = fontforge.open(ligature_font_path)
firacode.em = font.em
creator = LigatureCreator(font, firacode)
creator = LigatureCreator(font, firacode, args)
ligature_length = lambda lig: len(lig['chars'])
for lig_spec in sorted(ligatures, key = ligature_length):
try: