Skip to content

Commit 4e4e0f2

Browse files
committed
for MONO<1 fonts, just change dlig to calt, and don't remove any other features
1 parent 1e9392d commit 4e4e0f2

2 files changed

Lines changed: 68 additions & 24 deletions

File tree

scripts/dlig2calt.py

Lines changed: 62 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,68 @@
99
from fontTools.pens.ttGlyphPen import TTGlyphPen
1010
from argparse import ArgumentParser
1111
import pathops
12+
import subprocess
13+
import os
1214

15+
def simpleDlig2calt(fontPath, inplace=False):
16+
"""
17+
A simple way to change a "dlig" feature to "calt."
1318
14-
# codeLigs = {} # probably not needed
19+
Assumes the fontPath hasn’t already been converted to a TTX file,
20+
as that would confuse the variables below.
21+
"""
1522

16-
def dlig2calt(fontPath, inplace=False):
23+
# convert font’s GSUB table to a TTX file
24+
subprocess.run(["ttx", "-t", "GSUB", fontPath])
25+
26+
# make the path for a ttx
27+
ttxPath = fontPath.replace(".ttf",".ttx")
28+
29+
# Read in the TTX file
30+
with open(ttxPath, 'r') as file:
31+
ttxData = file.read()
32+
33+
# Replace the target string to update the dlig feature tags to calt feature tags
34+
ttxData = ttxData.replace('"dlig"', '"calt"')
35+
36+
# Write the TTX file out again
37+
with open(ttxPath, 'w') as file:
38+
file.write(ttxData)
39+
40+
# merge TTX back into font:
41+
# ttx -m fontname.ttf fontname.ttx
42+
43+
# save font
44+
if inplace:
45+
subprocess.run(["ttx", "-f", "-m", fontPath, ttxPath])
46+
print("\nCode ligatures are now under the calt feature and on by default.\n")
47+
else:
48+
newFontPath = fontPath.replace('.ttf','.calt_ligs.ttf')
49+
subprocess.run(["ttx", "-o", newFontPath, "-m", fontPath, ttxPath])
50+
print("Saved font with feature 'dlig' changed to 'calt' at ", newFontPath)
51+
52+
# clean up the temporary TTX file
53+
os.remove(ttxPath)
54+
55+
56+
def makeCodeLigsMonospace(fontPath, inplace=False):
57+
"""
58+
Takes code ligatures with different widths, and makes them all exactly one monospace character wide.
59+
60+
The extra width goes over the left bound, and the space is made up for by a newly-created "LIG" glyph.
61+
"""
1762

1863
font = ttLib.TTFont(fontPath)
1964

2065
# set unit width / tabular width ... assumes the "=" symbol will have a tabular width for any code font
2166
# 600 for most monospace fonts w/ UPM=1000
2267
unitWidth = font['hmtx']['equal'][0]
2368

24-
# make "LIG" glyph
69+
# create the "LIG" glyph to fill in gaps for code ligatures made into single-unit-wide glyphs
2570
font['glyf'].__setitem__('LIG', font['glyf']['space'])
26-
2771
font['hmtx'].__setitem__('LIG', font['hmtx']['space'])
2872

2973
# set /LIG glyph width to /equal width, not /space, to allow proportional fonts
30-
31-
# print(font['glyf']._getPhantomPoints('LIG', font['hmtx'].metrics))
32-
33-
# newPhantomPoints = [(0,0), (600,0), (0, 0), (0, 0)]
34-
3574
font['glyf']._setCoordinates('LIG', [(0,0), (600,0), (0, 0), (0, 0)], font['hmtx'].metrics)
3675

3776

@@ -62,29 +101,31 @@ def dlig2calt(fontPath, inplace=False):
62101
newCoords = adjustedCoords+adjustedPhantoms
63102
font['glyf']._setCoordinates(glyphName, newCoords, font['hmtx'].metrics)
64103

65-
66104
# add new feature code, using calt rather than dlig
67105
builder.addOpenTypeFeatures(font,"font-data/features/calt-generated--code_fonts_only.fea")
68106

69-
70107
# save font
71108
if inplace:
72109
font.save(fontPath)
73110
print("\nCode ligatures are now on by default.\n")
74111
else:
75-
newPath = fontPath.replace('.ttf','.calt_ligs.ttf')
76-
font.save(newPath)
77-
print("Saved font with feature 'dlig' changed to 'calt' at ", newPath)
112+
fontPath = fontPath.replace('.ttf','.calt_ligs.ttf')
113+
font.save(fontPath)
114+
print("Saved font with feature 'dlig' changed to 'calt' at ", fontPath)
78115

79116

80117
def main():
81-
description = "Change dlig features to calt features."
82-
parser = ArgumentParser(description=description)
83-
parser.add_argument('font', nargs=1)
84-
parser.add_argument('--inplace', action='store_true')
85-
args = parser.parse_args()
86-
87-
dlig2calt(args.font[0], args.inplace)
118+
description = "Change dlig features to calt features."
119+
parser = ArgumentParser(description=description)
120+
parser.add_argument('font', nargs=1)
121+
parser.add_argument('--inplace', action='store_true')
122+
parser.add_argument('--mono', '-m', action='store_true')
123+
args = parser.parse_args()
124+
125+
if args.mono:
126+
makeCodeLigsMonospace(args.font[0], args.inplace)
127+
else:
128+
simpleDlig2calt(args.font[0], args.inplace)
88129

89130

90131
if __name__ == '__main__':

scripts/instantiate-code-fonts.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from fontTools.varLib import instancer
2121
from fontTools.varLib.instancer import OverlapMode
2222
from opentype_feature_freezer import cli as pyftfeatfreeze
23-
from dlig2calt import dlig2calt
23+
from dlig2calt import (makeCodeLigsMonospace, simpleDlig2calt)
2424
from mergePowerlineFont import mergePowerlineFont
2525
from ttfautohint.options import USER_OPTIONS as ttfautohint_options
2626

@@ -162,9 +162,12 @@ def splitFont(
162162
# if font is proportional, also keep the kern feature for kerning
163163
pyftfeatfreeze.main([f"--features=rvrn,{','.join(fontOptions['Features'])},kern", outputPath, outputPath])
164164

165-
if fontOptions['Code Ligatures']:
165+
if fontOptions['Code Ligatures'] and fontOptions["Fonts"][instance]["MONO"] == 1:
166166
# swap dlig2calt to make code ligatures work in old code editor apps
167-
dlig2calt(outputPath, inplace=True)
167+
makeCodeLigsMonospace(outputPath, inplace=True)
168+
169+
if fontOptions['Code Ligatures'] and fontOptions["Fonts"][instance]["MONO"] < 1:
170+
simpleDlig2calt(outputPath, inplace=True)
168171

169172
# if casual, merge with casual PL; if linear merge w/ Linear PL
170173
if fontOptions["Fonts"][instance]["CASL"] > 0.5:

0 commit comments

Comments
 (0)