Merge pull request #2382 from fonttools/ignore-overlap-errors-option

instancer: add --ignore-overlap-errors option
This commit is contained in:
Cosimo Lupo 2021-08-02 10:34:18 +01:00 committed by GitHub
commit 5cb288f345
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 9 deletions

View File

@ -115,7 +115,8 @@ def _simplify(path: pathops.Path, debugGlyphName: str) -> pathops.Path:
)
return path
except pathops.PathOpsError as e:
path.dump()
if log.isEnabledFor(logging.DEBUG):
path.dump()
raise RemoveOverlapsError(
f"Failed to remove overlaps from glyph {debugGlyphName!r}"
) from e
@ -162,6 +163,7 @@ def removeOverlaps(
font: ttFont.TTFont,
glyphNames: Optional[Iterable[str]] = None,
removeHinting: bool = True,
ignoreErrors=False,
) -> None:
"""Simplify glyphs in TTFont by merging overlapping contours.
@ -179,6 +181,8 @@ def removeOverlaps(
glyphNames: optional iterable of glyph names (str) to remove overlaps from.
By default, all glyphs in the font are processed.
removeHinting (bool): set to False to keep hinting for unmodified glyphs.
ignoreErrors (bool): set to True to ignore errors while removing overlaps,
thus keeping the tricky glyphs unchanged (fonttools/fonttools#2363).
"""
try:
glyfTable = font["glyf"]
@ -206,10 +210,15 @@ def removeOverlaps(
)
modified = set()
for glyphName in glyphNames:
if removeTTGlyphOverlaps(
glyphName, glyphSet, glyfTable, hmtxTable, removeHinting
):
modified.add(glyphName)
try:
if removeTTGlyphOverlaps(
glyphName, glyphSet, glyfTable, hmtxTable, removeHinting
):
modified.add(glyphName)
except RemoveOverlapsError:
if not ignoreErrors:
raise
log.error("Failed to remove overlaps for '%s'", glyphName)
log.debug("Removed overlaps for %s glyphs:\n%s", len(modified), " ".join(modified))

View File

@ -127,6 +127,7 @@ class OverlapMode(IntEnum):
KEEP_AND_DONT_SET_FLAGS = 0
KEEP_AND_SET_FLAGS = 1
REMOVE = 2
REMOVE_AND_IGNORE_ERRORS = 3
def instantiateTupleVariationStore(
@ -1185,7 +1186,8 @@ def instantiateVariableFont(
on all glyphs to maximise cross-compatibility of the generated instance.
You can disable this by passing OverlapMode.KEEP_AND_DONT_SET_FLAGS.
If you want to remove the overlaps altogether and merge overlapping
contours and components, you can pass OverlapMode.REMOVE. Note that this
contours and components, you can pass OverlapMode.REMOVE (or
REMOVE_AND_IGNORE_ERRORS to not hard-fail on tricky glyphs). Note that this
requires the skia-pathops package (available to pip install).
The overlap parameter only has effect when generating full static instances.
updateFontNames (bool): if True, update the instantiated font's name table using
@ -1244,11 +1246,14 @@ def instantiateVariableFont(
if "glyf" in varfont:
if overlap == OverlapMode.KEEP_AND_SET_FLAGS:
setMacOverlapFlags(varfont["glyf"])
elif overlap == OverlapMode.REMOVE:
elif overlap in (OverlapMode.REMOVE, OverlapMode.REMOVE_AND_IGNORE_ERRORS):
from fontTools.ttLib.removeOverlaps import removeOverlaps
log.info("Removing overlaps from glyf table")
removeOverlaps(varfont)
removeOverlaps(
varfont,
ignoreErrors=(overlap == OverlapMode.REMOVE_AND_IGNORE_ERRORS),
)
varLib.set_default_weight_width_slant(
varfont,
@ -1355,6 +1360,12 @@ def parseArgs(args):
help="Merge overlapping contours and components (only applicable "
"when generating a full instance). Requires skia-pathops",
)
parser.add_argument(
"--ignore-overlap-errors",
dest="ignore_overlap_errors",
action="store_true",
help="Don't crash if the remove-overlaps operation fails for some glyphs.",
)
parser.add_argument(
"--update-name-table",
action="store_true",
@ -1371,7 +1382,10 @@ def parseArgs(args):
options = parser.parse_args(args)
if options.remove_overlaps:
options.overlap = OverlapMode.REMOVE
if options.ignore_overlap_errors:
options.overlap = OverlapMode.REMOVE_AND_IGNORE_ERRORS
else:
options.overlap = OverlapMode.REMOVE
else:
options.overlap = OverlapMode(int(options.overlap))