mirror of
https://github.com/ryanoasis/nerd-fonts.git
synced 2024-12-25 20:18:01 +02:00
font-patcher: Allow to rehint some Cascadia glyphs
[why] Some Caskaydia Cove glyphs that are used in ligatures (to create endless arrows for example) show uneven line thickness on some platforms. The reason is the not-matching hinting of glyphs that are places next to each other and so minuscule differences are quite visible. Note that the 'original' hinting is generated by VTT on the static Cascadia Code instances, which upstream just have ttfautohint hints that are different from the hints in the variable fonts and people complained that the look is different. [how] Add a new field to the config.cfg file that holds regexes of glyph names for glyphs that should be re-hinted by fontforge on patching time. In principle we could also implement that as an additional pre-step that needs to be manually done after running VTT on the static font files. I'm not sure which is better. Note that fontforge generates a lot of debug output because the hinting is not ideal - the global tables are kept and probably less compatible to fontforge's own hinting... But the results are good. Fixes: #1291 Fixes: #1609 Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
This commit is contained in:
parent
88d63ff827
commit
378d97cf1b
38
font-patcher
38
font-patcher
@ -6,7 +6,7 @@
|
|||||||
from __future__ import absolute_import, print_function, unicode_literals
|
from __future__ import absolute_import, print_function, unicode_literals
|
||||||
|
|
||||||
# Change the script version when you edit this script:
|
# Change the script version when you edit this script:
|
||||||
script_version = "4.13.1"
|
script_version = "4.14.0"
|
||||||
|
|
||||||
version = "3.2.1"
|
version = "3.2.1"
|
||||||
projectName = "Nerd Fonts"
|
projectName = "Nerd Fonts"
|
||||||
@ -339,7 +339,9 @@ class font_patcher:
|
|||||||
self.sourceFont = font
|
self.sourceFont = font
|
||||||
self.setup_version()
|
self.setup_version()
|
||||||
self.assert_monospace()
|
self.assert_monospace()
|
||||||
|
self.load_config()
|
||||||
self.remove_ligatures()
|
self.remove_ligatures()
|
||||||
|
self.manipulate_hints()
|
||||||
self.get_essential_references()
|
self.get_essential_references()
|
||||||
self.get_sourcefont_dimensions()
|
self.get_sourcefont_dimensions()
|
||||||
self.setup_patch_set()
|
self.setup_patch_set()
|
||||||
@ -769,11 +771,18 @@ class font_patcher:
|
|||||||
# print("Version now is {}".format(sourceFont.version))
|
# print("Version now is {}".format(sourceFont.version))
|
||||||
|
|
||||||
|
|
||||||
|
def load_config(self):
|
||||||
|
""" Try to read the config file (if specified) """
|
||||||
|
if self.args.configfile:
|
||||||
|
if not self.config.read(self.args.configfile):
|
||||||
|
logger.error("Unable to read configfile")
|
||||||
|
|
||||||
|
|
||||||
def remove_ligatures(self):
|
def remove_ligatures(self):
|
||||||
# let's deal with ligatures (mostly for monospaced fonts)
|
# let's deal with ligatures (mostly for monospaced fonts)
|
||||||
# Usually removes 'fi' ligs that end up being only one cell wide, and 'ldot'
|
# Usually removes 'fi' ligs that end up being only one cell wide, and 'ldot'
|
||||||
if self.args.configfile and self.config.read(self.args.configfile):
|
if self.args.removeligatures:
|
||||||
if self.args.removeligatures:
|
if self.args.configfile:
|
||||||
logger.info("Removing ligatures from configfile `Subtables` section")
|
logger.info("Removing ligatures from configfile `Subtables` section")
|
||||||
ligature_subtables = json.loads(self.config.get("Subtables", "ligatures"))
|
ligature_subtables = json.loads(self.config.get("Subtables", "ligatures"))
|
||||||
for subtable in ligature_subtables:
|
for subtable in ligature_subtables:
|
||||||
@ -783,10 +792,29 @@ class font_patcher:
|
|||||||
logger.debug("Successfully removed subtable: %s", subtable)
|
logger.debug("Successfully removed subtable: %s", subtable)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.error("Failed to remove subtable: %s", subtable)
|
logger.error("Failed to remove subtable: %s", subtable)
|
||||||
elif self.args.removeligatures:
|
else:
|
||||||
logger.error("Unable to read configfile, unable to remove ligatures")
|
logger.error("No configfile, unable to remove ligatures")
|
||||||
|
|
||||||
|
|
||||||
|
def manipulate_hints(self):
|
||||||
|
""" Redo the hinting on some problematic glyphs """
|
||||||
|
if not self.args.configfile:
|
||||||
|
return
|
||||||
|
redo = json.loads(self.config.get("Hinting", "re_hint"))
|
||||||
|
if not len(redo):
|
||||||
|
return
|
||||||
|
logger.debug("Working on {} rehinting rules".format(len(redo)))
|
||||||
|
count = 0
|
||||||
|
for gname in self.sourceFont:
|
||||||
|
for regex in redo:
|
||||||
|
if re.fullmatch(regex, gname):
|
||||||
|
glyph = self.sourceFont[gname]
|
||||||
|
glyph.autoHint()
|
||||||
|
glyph.autoInstr()
|
||||||
|
count += 1
|
||||||
|
break
|
||||||
|
logger.info("Rehinted {} glyphs".format(count))
|
||||||
|
|
||||||
def assert_monospace(self):
|
def assert_monospace(self):
|
||||||
# Check if the sourcefont is monospaced
|
# Check if the sourcefont is monospaced
|
||||||
width_mono, offending_char = is_monospaced(self.sourceFont)
|
width_mono, offending_char = is_monospaced(self.sourceFont)
|
||||||
|
@ -1,2 +1,7 @@
|
|||||||
[Config]
|
[Config]
|
||||||
commandline: --makegroups 4
|
commandline: --makegroups 4
|
||||||
|
[Hinting]
|
||||||
|
re_hint: [
|
||||||
|
".*hyphen.*\\.(liga|seq)",
|
||||||
|
".*equal.*\\.(liga|seq)",
|
||||||
|
".*numbersign.*\\.(liga|seq)" ]
|
||||||
|
@ -1,2 +1,7 @@
|
|||||||
[Config]
|
[Config]
|
||||||
commandline: --makegroups 4
|
commandline: --makegroups 4
|
||||||
|
[Hinting]
|
||||||
|
re_hint: [
|
||||||
|
".*hyphen.*\\.(liga|seq)",
|
||||||
|
".*equal.*\\.(liga|seq)",
|
||||||
|
".*numbersign.*\\.(liga|seq)" ]
|
||||||
|
Loading…
Reference in New Issue
Block a user