diff --git a/config.yaml b/config.yaml index 4e16c21..31c8fdc 100644 --- a/config.yaml +++ b/config.yaml @@ -68,6 +68,7 @@ Fonts: # Font Features # Freeze in code ligatures? True or False +# Note: must be set to False if you want to both have a proportional font (MONO < 1) and bake in code ligatures under the "calt" feature Code Ligatures: True # Include font features to freeze in stylistic options. Copy them below to use. diff --git a/scripts/dlig2calt.py b/scripts/dlig2calt.py index 9eba945..67e23e2 100644 --- a/scripts/dlig2calt.py +++ b/scripts/dlig2calt.py @@ -17,7 +17,9 @@ def dlig2calt(fontPath, inplace=False): font = ttLib.TTFont(fontPath) - unitWidth = font['hmtx']['space'][0] # 600 for most monospace fonts w/ UPM=1000 + # set unit width / tabular width ... assumes the "=" symbol will have a tabular width for any code font + # 600 for most monospace fonts w/ UPM=1000 + unitWidth = font['hmtx']['equal'][0] # make "LIG" glyph font['glyf'].__setitem__('LIG', font['glyf']['space']) @@ -28,25 +30,28 @@ def dlig2calt(fontPath, inplace=False): for glyphName in font.getGlyphNames(): if font['hmtx'][glyphName][0] > unitWidth: - # set width to space (e.g. 600), then offset left side to be negative - oldWidth = font['hmtx'][glyphName][0] - oldLSB = font['hmtx'][glyphName][1] - widthDiff = oldWidth - unitWidth - newLSB = oldLSB - widthDiff - font['hmtx'].__setitem__(glyphName, (unitWidth, newLSB)) + # only apply this to code ligatures... leave other glyphs as-is, in case they are intentionally proportional (i.e. MONO != 1) + if ".code" in glyphName: - # Adjust coordinates in glyf table - coords = font['glyf']._getCoordinatesAndControls(glyphName, font['hmtx'].metrics)[0] - phantoms = font['glyf']._getPhantomPoints(glyphName, font['hmtx'].metrics) + # set width to equal sign (e.g. 600), then offset left side to be negative + oldWidth = font['hmtx'][glyphName][0] + oldLSB = font['hmtx'][glyphName][1] + widthDiff = oldWidth - unitWidth + newLSB = oldLSB - widthDiff + font['hmtx'].__setitem__(glyphName, (unitWidth, newLSB)) - # take off last four items of coords to allow adjusted phantoms to be handled separately, then combined - coords = coords[:len(coords)-4] + # Adjust coordinates in glyf table + coords = font['glyf']._getCoordinatesAndControls(glyphName, font['hmtx'].metrics)[0] + phantoms = font['glyf']._getPhantomPoints(glyphName, font['hmtx'].metrics) - adjustedCoords = [(x-widthDiff, y) for x, y in coords] - adjustedPhantoms = [(0,0), (600,0), phantoms[-2], phantoms[-1]] + # take off last four items of coords to allow adjusted phantoms to be handled separately, then combined + coords = coords[:len(coords)-4] - newCoords = adjustedCoords+adjustedPhantoms - font['glyf']._setCoordinates(glyphName, newCoords, font['hmtx'].metrics) + adjustedCoords = [(x-widthDiff, y) for x, y in coords] + adjustedPhantoms = [(0,0), (600,0), phantoms[-2], phantoms[-1]] + + newCoords = adjustedCoords+adjustedPhantoms + font['glyf']._setCoordinates(glyphName, newCoords, font['hmtx'].metrics) # add new feature code, using calt rather than dlig diff --git a/scripts/instantiate-code-fonts.py b/scripts/instantiate-code-fonts.py index 71451c9..7c42ab5 100644 --- a/scripts/instantiate-code-fonts.py +++ b/scripts/instantiate-code-fonts.py @@ -155,8 +155,12 @@ def splitFont( # ------------------------------------------------------- # Code font special stuff in post processing - # freeze in rvrn & stylistic set features with pyftfeatfreeze - pyftfeatfreeze.main([f"--features=rvrn,{','.join(fontOptions['Features'])}", outputPath, outputPath]) + if fontOptions["Fonts"][instance]["MONO"] == 1: + # freeze in rvrn & stylistic set features with pyftfeatfreeze + pyftfeatfreeze.main([f"--features=rvrn,{','.join(fontOptions['Features'])}", outputPath, outputPath]) + else: + # if font is proportional, also keep the kern feature for kerning + pyftfeatfreeze.main([f"--features=rvrn,{','.join(fontOptions['Features'])},kern", outputPath, outputPath]) if fontOptions['Code Ligatures']: # swap dlig2calt to make code ligatures work in old code editor apps @@ -181,14 +185,16 @@ def splitFont( except KeyError: print("Font has no STAT table.") - # In the post table, isFixedPitched flag must be set in the code fonts - monoFont['post'].isFixedPitch = 1 + if fontOptions["Fonts"][instance]["MONO"] == 1: + + # In the post table, isFixedPitched flag must be set in the code fonts + monoFont['post'].isFixedPitch = 1 - # In the OS/2 table Panose bProportion must be set to 9 - monoFont["OS/2"].panose.bProportion = 9 + # In the OS/2 table Panose bProportion must be set to 9 + monoFont["OS/2"].panose.bProportion = 9 - # Also in the OS/2 table, xAvgCharWidth should be set to 600 rather than 612 (612 is an average of glyphs in the "Mono" files which include wide ligatures). - monoFont["OS/2"].xAvgCharWidth = 600 + # Also in the OS/2 table, xAvgCharWidth should be set to 600 rather than 612 (612 is an average of glyphs in the "Mono" files which include wide ligatures). + monoFont["OS/2"].xAvgCharWidth = 600 # Code to fix fsSelection adapted from: # https://github.com/googlefonts/gftools/blob/a0b516d71f9e7988dfa45af2d0822ec3b6972be4/Lib/gftools/fix.py#L764