From dbcdde1bee8b0a02dda83f51408f44fd629f415b Mon Sep 17 00:00:00 2001 From: ReadRoberts Date: Tue, 30 Apr 2019 09:43:13 -0700 Subject: [PATCH 1/2] Fix bug in subsetting T2 CharStrings from CFF font. The logic seeks to avoid unnecessarily executing subroutines that have already been subroutinized. It is necessary execute all subroutines when counting hints in order to determine the byte length of mask arguments, but we want to quit doing this when we know that counting hints is no longer necessary,. The previous logic stopped when a [vh]stem operator was seen, as this means there will not be need for hintmask mask arguments However, the [vh]stem operators can be used even when there is a cntrmask, so the logic stopped counting hints too early. --- Lib/fontTools/subset/cff.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Lib/fontTools/subset/cff.py b/Lib/fontTools/subset/cff.py index 274071e5a..fc29f182a 100644 --- a/Lib/fontTools/subset/cff.py +++ b/Lib/fontTools/subset/cff.py @@ -366,7 +366,7 @@ class StopHintCountEvent(Exception): class _DesubroutinizingT2Decompiler(psCharStrings.SimpleT2Decompiler): - stop_hintcount_ops = ("op_hstem", "op_vstem", "op_rmoveto", "op_hmoveto", + stop_hintcount_ops = ("op_hintmask", "op_cntrmask", "op_rmoveto", "op_hmoveto", "op_vmoveto") def __init__(self, localSubrs, globalSubrs, private=None): @@ -379,6 +379,10 @@ class _DesubroutinizingT2Decompiler(psCharStrings.SimpleT2Decompiler): setattr(self, op_name, self.stop_hint_count) if hasattr(charString, '_desubroutinized'): + # If a charstring has already been desubroutinized, we will still + # need to execute it if we need to count hints in order to + # compute the byte length for mask arguments, and haven't finished + # counting hints pairs. if self.need_hintcount and self.callingStack: try: psCharStrings.SimpleT2Decompiler.execute(self, charString) From b1999a1a0e7d7fb232e496eff5c6215d8b6aaebd Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Fri, 3 May 2019 01:14:09 +0200 Subject: [PATCH 2/2] Add test for previous commit --- Tests/subset/data/test_cntrmask_CFF.desub.ttx | 70 +++ Tests/subset/data/test_cntrmask_CFF.ttx | 417 ++++++++++++++++++ Tests/subset/subset_test.py | 10 + 3 files changed, 497 insertions(+) create mode 100644 Tests/subset/data/test_cntrmask_CFF.desub.ttx create mode 100644 Tests/subset/data/test_cntrmask_CFF.ttx diff --git a/Tests/subset/data/test_cntrmask_CFF.desub.ttx b/Tests/subset/data/test_cntrmask_CFF.desub.ttx new file mode 100644 index 000000000..ff1c8c594 --- /dev/null +++ b/Tests/subset/data/test_cntrmask_CFF.desub.ttx @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -95 endchar + + + -298 -2 33 583 33 62 96 hstem + 6 96 4 85 4 96 vstem + cntrmask 00011100 + 191 122 rmoveto + 401 vlineto + 0 83 17 5 70 3 6 6 0 21 -6 6 -44 -1 -47.5 -1 -38.5 0 -33.5 0 -48.5 1 -47 1 -6 -6 0 -21 6 -6 70 -3 17 -5 0 -83 rrcurveto + -401 vlineto + 0 -83 -17 -5 -70 -3 -6 -6 0 -21 6 -6 45 1 48.7002 1 36.2998 0 35.59961 0 48.40039 -1 45 -1 6 6 0 21 -6 6 -70 3 -17 5 0 83 rrcurveto + 4 635 rmoveto + -26 22 -22 26 26 22 22 26 26 -22 22 -26 -26 -22 -22 -26 vhcurveto + -189 hmoveto + -26 22 -22 26 26 22 22 26 26 -22 22 -26 -26 -22 -22 -26 vhcurveto + endchar + + + + + + + + + + diff --git a/Tests/subset/data/test_cntrmask_CFF.ttx b/Tests/subset/data/test_cntrmask_CFF.ttx new file mode 100644 index 000000000..5ab6268f6 --- /dev/null +++ b/Tests/subset/data/test_cntrmask_CFF.ttx @@ -0,0 +1,417 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Copyright © 2012-2019 The Libertinus Project Authors. + + + Libertinus Serif + + + Regular + + + 6.8;ALIF;LibertinusSerif-Regular + + + Libertinus Serif Regular + + + Version 6.8 + + + LibertinusSerif-Regular + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -26 22 -22 26 26 22 22 26 26 -22 22 -26 -26 -22 -22 -26 vhcurveto + return + + + 401 vlineto + 0 83 17 5 70 3 6 6 0 21 -6 6 -44 -1 -47.5 -1 -38.5 0 -33.5 0 -48.5 1 -47 1 -6 -6 0 -21 6 -6 70 -3 17 -5 0 -83 rrcurveto + -401 vlineto + 0 -83 -17 -5 -70 -3 -6 -6 0 -21 6 -6 45 1 48.7002 1 36.2998 0 35.59961 0 48.40039 -1 45 -1 6 6 0 21 -6 6 -70 3 -17 5 0 83 rrcurveto + return + + + + + + -95 endchar + + + -298 -2 33 583 33 62 96 hstem + 6 96 4 85 4 96 vstem + cntrmask 00011100 + 191 122 rmoveto + -106 callsubr + 4 635 rmoveto + -107 callsubr + -189 hmoveto + -107 callsubr + endchar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tests/subset/subset_test.py b/Tests/subset/subset_test.py index a269faccb..4a18358e3 100644 --- a/Tests/subset/subset_test.py +++ b/Tests/subset/subset_test.py @@ -426,6 +426,16 @@ class SubsetTest(unittest.TestCase): self.expect_ttx(subsetfont, self.getpath( "test_hinted_subrs_CFF.desub.ttx"), ["CFF "]) + def test_desubroutinize_cntrmask_CFF(self): + ttxpath = self.getpath("test_cntrmask_CFF.ttx") + _, fontpath = self.compile_font(ttxpath, ".otf") + subsetpath = self.temp_path(".otf") + subset.main([fontpath, "--desubroutinize", "--notdef-outline", + "--output-file=%s" % subsetpath, "*"]) + subsetfont = TTFont(subsetpath) + self.expect_ttx(subsetfont, self.getpath( + "test_cntrmask_CFF.desub.ttx"), ["CFF "]) + def test_no_hinting_desubroutinize_CFF(self): ttxpath = self.getpath("test_hinted_subrs_CFF.ttx") _, fontpath = self.compile_font(ttxpath, ".otf")