font-patcher: Add option to allow italic-less fonts with oblique

[why]
Because we do not know if a complete family of fonts has an italic face
we must always assume it does. To get clean RIBBI families in ID1/2 we
create a different family for the oblique slant.
But that is not needed if the font does not have an italic slant, but
just an oblique one (like Bitstream Vera and descendants).

[how]
Add new command line option for font-patcher that specifies if the
family of fonts should be patched under the assumption that there might
be an italic face (default), or if we are sure there is none (and we can
leave oblique in the RIBBI group).

This is then applied to the config.cfg files.

Note that this does not take into account any other of the known_slants.
But they are not encountered in any of our prepatched fonts.

Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
This commit is contained in:
Fini Jastrow 2023-04-24 15:12:37 +02:00
parent f603633536
commit a96006a681
4 changed files with 38 additions and 10 deletions

View file

@ -21,6 +21,7 @@ class FontnameParser:
self.basename = self._basename self.basename = self._basename
self.rest = self._rest self.rest = self._rest
self.add_name_substitution_table(FontnameTools.SIL_TABLE) self.add_name_substitution_table(FontnameTools.SIL_TABLE)
self.rename_oblique = True
self.logger = logger self.logger = logger
def _make_ps_name(self, n, is_family): def _make_ps_name(self, n, is_family):
@ -53,6 +54,21 @@ class FontnameParser:
"""Familyname may contain 'Regular' where it should normally be suppressed""" """Familyname may contain 'Regular' where it should normally be suppressed"""
self.keep_regular_in_family = keep self.keep_regular_in_family = keep
def set_expect_no_italic(self, noitalic):
"""Prevents rewriting Oblique as family name part"""
# To prevent naming clashes usually Oblique is moved out in the family name
# because some fonts have Italic and Oblique, and we want to generate pure
# RIBBI families in ID1/2.
# But some fonts have Oblique instead of Italic, here the prevential movement
# is not needed, or rather contraproductive. This can not be detected on a
# font file level but needs to be specified per family from the outside.
# Returns true if setting was successful.
if 'Italic' in self.style_token:
self.rename_oblique = True
return not noitalic
self.rename_oblique = not noitalic
return True
def set_suppress_preferred(self, suppress): def set_suppress_preferred(self, suppress):
"""Suppress ID16/17 if it is identical to ID1/2 (True is default)""" """Suppress ID16/17 if it is identical to ID1/2 (True is default)"""
self.suppress_preferred_if_identical = suppress self.suppress_preferred_if_identical = suppress
@ -190,22 +206,28 @@ class FontnameParser:
# We use the short form of the styles to save on number of chars # We use the short form of the styles to save on number of chars
(name, rest) = self._shortened_name() (name, rest) = self._shortened_name()
other = self.other_token other = self.other_token
weight = self.weight_token weights = self.weight_token
aggressive = self.use_short_families[2] aggressive = self.use_short_families[2]
if not self.rename_oblique:
(weights, styles) = FontnameTools.make_oblique_style(weights, [])
if self.use_short_families[1]: if self.use_short_families[1]:
[ other, weight ] = FontnameTools.short_styles([ other, weight ], aggressive) [ other, weights ] = FontnameTools.short_styles([ other, weights ], aggressive)
weight = [ w if w != 'Oblique' else 'Obl' for w in weight ] weights = [ w if w != 'Oblique' else 'Obl' for w in weights ]
return FontnameTools.concat(name, rest, other, self.short_family_suff, weight) return FontnameTools.concat(name, rest, other, self.short_family_suff, weights)
def subfamily(self): def subfamily(self):
"""Get the SFNT SubFamily (ID 2)""" """Get the SFNT SubFamily (ID 2)"""
if len(self.style_token) == 0: styles = self.style_token
if 'Oblique' in self.weight_token: weights = self.weight_token
return FontnameTools.concat(self.style_token, 'Italic') if not self.rename_oblique:
(weights, styles) = FontnameTools.make_oblique_style(weights, styles)
if len(styles) == 0:
if 'Oblique' in weights:
return FontnameTools.concat(styles, 'Italic')
return 'Regular' return 'Regular'
if 'Oblique' in self.weight_token and not 'Italic' in self.style_token: if 'Oblique' in weights and not 'Italic' in styles:
return FontnameTools.concat(self.style_token, 'Italic') return FontnameTools.concat(styles, 'Italic')
return FontnameTools.concat(self.style_token) return FontnameTools.concat(styles)
def ps_familyname(self): def ps_familyname(self):
"""Get the PS Familyname""" """Get the PS Familyname"""

View file

@ -573,6 +573,9 @@ class font_patcher:
logger.warning("Have only minimal naming information, check resulting name. Maybe specify --makegroups 0") logger.warning("Have only minimal naming information, check resulting name. Maybe specify --makegroups 0")
n.drop_for_powerline() n.drop_for_powerline()
n.enable_short_families(True, self.args.makegroups in [ 2, 3, 5, 6, ], self.args.makegroups in [ 3, 6, ]) n.enable_short_families(True, self.args.makegroups in [ 2, 3, 5, 6, ], self.args.makegroups in [ 3, 6, ])
if not n.set_expect_no_italic(self.args.noitalic):
logger.critical("Detected 'Italic' slant but --has-no-italic specified")
sys.exit(1)
# All the following stuff is ignored in makegroups-mode # All the following stuff is ignored in makegroups-mode
@ -1804,6 +1807,7 @@ def setup_arguments():
# 6 HugoSansMono NF XCn Lt It [X] [X] [X] # 6 HugoSansMono NF XCn Lt It [X] [X] [X]
parser.add_argument('--variable-width-glyphs', dest='nonmono', default=False, action='store_true', help='Do not adjust advance width (no "overhang")') parser.add_argument('--variable-width-glyphs', dest='nonmono', default=False, action='store_true', help='Do not adjust advance width (no "overhang")')
parser.add_argument('--has-no-italic', dest='noitalic', default=False, action='store_true', help='Font family does not have Italic (but Oblique)')
# progress bar arguments - https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse # progress bar arguments - https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse
progressbars_group_parser = parser.add_mutually_exclusive_group(required=False) progressbars_group_parser = parser.add_mutually_exclusive_group(required=False)

View file

@ -0,0 +1 @@
config_patch_flags="--has-no-italic"

View file

@ -0,0 +1 @@
config_patch_flags="--has-no-italic"