From ec54541e30b68ddd1dae5922fa6ce894fd5814ac Mon Sep 17 00:00:00 2001 From: ReadRoberts Date: Wed, 12 Jun 2019 16:31:29 -0700 Subject: [PATCH 1/5] [varLib.cff] Fix merging bug when there are no blends or marking glyphs. If the CFF2 VF has no blends, or no marking glyphs, the default variation table does not get built; this can be needed later for the PrivateDict. --- Lib/fontTools/varLib/cff.py | 39 ++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/Lib/fontTools/varLib/cff.py b/Lib/fontTools/varLib/cff.py index a8da21456..afa42b7fe 100755 --- a/Lib/fontTools/varLib/cff.py +++ b/Lib/fontTools/varLib/cff.py @@ -161,7 +161,7 @@ def merge_PrivateDicts(top_dicts, vsindex_dict, var_model, fd_map): For each key, step through each relevant source font Private dict, and build a list of values to blend. The 'relevant' source fonts are selected by first getting the right - submodel using model_keys[vsindex]. The indices of the + submodel using vsindex_dict[vsindex]. The indices of the subModel.locations are mapped to source font list indices by assuming the latter order is the same as the order of the var_model.locations. I can then get the index of each subModel @@ -180,7 +180,7 @@ def merge_PrivateDicts(top_dicts, vsindex_dict, var_model, fd_map): # At the moment, no PrivateDict has a vsindex key, but let's support # how it should work. See comment at end of # merge_charstrings() - still need to optimize use of vsindex. - sub_model, model_keys = vsindex_dict[vsindex] + sub_model, _ = vsindex_dict[vsindex] master_indices = [] for loc in sub_model.locations[1:]: i = var_model.locations.index(loc) - 1 @@ -317,6 +317,19 @@ def _get_cs(charstrings, glyphName): return None return charstrings[glyphName] +def _add_new_vsindex(model, key, masterSupports, vsindex_dict, + vsindex_by_key, varDataList): + varTupleIndexes = [] + for support in model.supports[1:]: + if support not in masterSupports: + masterSupports.append(support) + varTupleIndexes.append(masterSupports.index(support)) + var_data = varLib.builder.buildVarData(varTupleIndexes, None, False) + vsindex = len(vsindex_dict) + vsindex_by_key[key] = vsindex + vsindex_dict[vsindex] = (model, [key]) + varDataList.append(var_data) + return vsindex def merge_charstrings(glyphOrder, num_masters, top_dicts, masterModel): @@ -365,24 +378,24 @@ def merge_charstrings(glyphOrder, num_masters, top_dicts, masterModel): # If the charstring required a new model, create # a VarData table to go with, and set vsindex. + key = tuple(v is not None for v in all_cs) try: - key = tuple(v is not None for v in all_cs) vsindex = vsindex_by_key[key] except KeyError: - varTupleIndexes = [] - for support in model.supports[1:]: - if support not in masterSupports: - masterSupports.append(support) - varTupleIndexes.append(masterSupports.index(support)) - var_data = varLib.builder.buildVarData(varTupleIndexes, None, False) - vsindex = len(vsindex_dict) - vsindex_by_key[key] = vsindex - vsindex_dict[vsindex] = (model, [key]) - varDataList.append(var_data) + vsindex = _add_new_vsindex(model, key,masterSupports, vsindex_dict, + vsindex_by_key, varDataList) # We do not need to check for an existing new_cs.private.vsindex, # as we know it doesn't exist yet. if vsindex != 0: new_cs.program[:0] = [vsindex, 'vsindex'] + + # If there is no variation in any of the charstrings, then vsindex_dict + # never gets built. This is could still be needed if there is variation + # in the PrivatDict, so we will build the default data for vsindex = 0. + if not vsindex_dict: + key = (True)*num_masters + _add_new_vsindex(model, key, masterSupports, vsindex_dict, + vsindex_by_key, varDataList) cvData = CVarData(varDataList=varDataList, masterSupports=masterSupports, vsindex_dict=vsindex_dict) # XXX To do: optimize use of vsindex between the PrivateDicts and From dce80efc7ca8dd338c63ec63914a013074c60196 Mon Sep 17 00:00:00 2001 From: ReadRoberts Date: Wed, 12 Jun 2019 16:45:08 -0700 Subject: [PATCH 2/5] [varLib.cff] Add test case for CFF2 variable font with no markiing glyphs. --- .../data/TestNonMarkingCFF2.designspace | 35 +++ .../TestNonMarkingCFF2_ExtraLight.ttx | 233 ++++++++++++++++++ .../TestNonMarkingCFF2_Regular.ttx | 233 ++++++++++++++++++ .../data/test_results/TestNonMarkingCFF2.ttx | 76 ++++++ Tests/varLib/varLib_test.py | 24 +- 5 files changed, 599 insertions(+), 2 deletions(-) create mode 100644 Tests/varLib/data/TestNonMarkingCFF2.designspace create mode 100644 Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_ExtraLight.ttx create mode 100644 Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_Regular.ttx create mode 100644 Tests/varLib/data/test_results/TestNonMarkingCFF2.ttx diff --git a/Tests/varLib/data/TestNonMarkingCFF2.designspace b/Tests/varLib/data/TestNonMarkingCFF2.designspace new file mode 100644 index 000000000..23c7797d1 --- /dev/null +++ b/Tests/varLib/data/TestNonMarkingCFF2.designspace @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_ExtraLight.ttx b/Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_ExtraLight.ttx new file mode 100644 index 000000000..9d3b2679e --- /dev/null +++ b/Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_ExtraLight.ttx @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Source Code Variable + + + Regular + + + 1.010;ADBO;SourceCode_ExtraLight + + + Source Code Variable + + + Version 1.010;hotconv 1.0.109;makeotfexe 2.5.65596 + + + SourceCode_ExtraLight + + + Roman Master 0 + + + Source Code Variable + + + Regular + + + 1.010;ADBO;SourceCode_ExtraLight + + + Source Code Variable + + + Version 1.010;hotconv 1.0.109;makeotfexe 2.5.65596 + + + SourceCode_ExtraLight + + + Roman Master 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + endchar + + + endchar + += + + + + + + + + + + + + + diff --git a/Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_Regular.ttx b/Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_Regular.ttx new file mode 100644 index 000000000..4e6775da8 --- /dev/null +++ b/Tests/varLib/data/master_non_marking_cff2/TestNonMarkingCFF2_Regular.ttx @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Source Code Variable + + + Regular + + + 1.010;ADBO;SourceCodeVariable-Roman + + + Source Code Variable + + + Version 1.010;hotconv 1.0.109;makeotfexe 2.5.65596 + + + SourceCodeVariable-Roman + + + Roman + + + Source Code Variable + + + Regular + + + 1.010;ADBO;SourceCodeVariable-Roman + + + Source Code Variable + + + Version 1.010;hotconv 1.0.109;makeotfexe 2.5.65596 + + + SourceCodeVariable-Roman + + + Roman + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + endchar + + + endchar + + + + + + + + + + + + + + + diff --git a/Tests/varLib/data/test_results/TestNonMarkingCFF2.ttx b/Tests/varLib/data/test_results/TestNonMarkingCFF2.ttx new file mode 100644 index 000000000..5ded5b915 --- /dev/null +++ b/Tests/varLib/data/test_results/TestNonMarkingCFF2.ttx @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tests/varLib/varLib_test.py b/Tests/varLib/varLib_test.py index f3037339e..220873b71 100644 --- a/Tests/varLib/varLib_test.py +++ b/Tests/varLib/varLib_test.py @@ -227,6 +227,28 @@ class BuildTest(unittest.TestCase): expected_ttx_name=test_name ) + def test_varlib_nonmarking_CFF2(self): + ds_path = self.get_test_input('TestNonMarkingCFF2.designspace') + ttx_dir = self.get_test_input("master_non_marking_cff2") + expected_ttx_path = self.get_test_output("TestNonMarkingCFF2.ttx") + + self.temp_dir() + for path in self.get_file_list(ttx_dir, '.ttx', 'TestNonMarkingCFF2_'): + self.compile_font(path, ".otf", self.tempdir) + + ds = DesignSpaceDocument.fromfile(ds_path) + for source in ds.sources: + source.path = os.path.join( + self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf") + ) + ds.updatePaths() + + varfont, _, _ = build(ds) + varfont = reload_font(varfont) + + tables = ["CFF2"] + self.expect_ttx(varfont, expected_ttx_path, tables) + def test_varlib_build_CFF2(self): ds_path = self.get_test_input('TestCFF2.designspace') ttx_dir = self.get_test_input("master_cff2") @@ -249,7 +271,6 @@ class BuildTest(unittest.TestCase): tables = ["fvar", "CFF2"] self.expect_ttx(varfont, expected_ttx_path, tables) - def test_varlib_build_sparse_CFF2(self): ds_path = self.get_test_input('TestSparseCFF2VF.designspace') ttx_dir = self.get_test_input("master_sparse_cff2") @@ -272,7 +293,6 @@ class BuildTest(unittest.TestCase): tables = ["fvar", "CFF2"] self.expect_ttx(varfont, expected_ttx_path, tables) - def test_varlib_main_ttf(self): """Mostly for testing varLib.main() """ From 3ab7dd143d1f18063841b385c29afa5af0a03c35 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Fri, 14 Jun 2019 16:19:29 +0100 Subject: [PATCH 3/5] minor whitespace --- Lib/fontTools/varLib/cff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/fontTools/varLib/cff.py b/Lib/fontTools/varLib/cff.py index afa42b7fe..e5d0d4a16 100755 --- a/Lib/fontTools/varLib/cff.py +++ b/Lib/fontTools/varLib/cff.py @@ -382,7 +382,7 @@ def merge_charstrings(glyphOrder, num_masters, top_dicts, masterModel): try: vsindex = vsindex_by_key[key] except KeyError: - vsindex = _add_new_vsindex(model, key,masterSupports, vsindex_dict, + vsindex = _add_new_vsindex(model, key, masterSupports, vsindex_dict, vsindex_by_key, varDataList) # We do not need to check for an existing new_cs.private.vsindex, # as we know it doesn't exist yet. From c6cf9bbb35cddd127a7c814cf8a9a223d632e123 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Fri, 14 Jun 2019 16:19:54 +0100 Subject: [PATCH 4/5] minor typo fix --- Lib/fontTools/varLib/cff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/fontTools/varLib/cff.py b/Lib/fontTools/varLib/cff.py index e5d0d4a16..be42ae47a 100755 --- a/Lib/fontTools/varLib/cff.py +++ b/Lib/fontTools/varLib/cff.py @@ -390,7 +390,7 @@ def merge_charstrings(glyphOrder, num_masters, top_dicts, masterModel): new_cs.program[:0] = [vsindex, 'vsindex'] # If there is no variation in any of the charstrings, then vsindex_dict - # never gets built. This is could still be needed if there is variation + # never gets built. This could still be needed if there is variation # in the PrivatDict, so we will build the default data for vsindex = 0. if not vsindex_dict: key = (True)*num_masters From fc6ea56568e43e3a33dce6167ebf66cd8ec25410 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Fri, 14 Jun 2019 16:20:48 +0100 Subject: [PATCH 5/5] must add comma to make parentheses into a tuple --- Lib/fontTools/varLib/cff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/fontTools/varLib/cff.py b/Lib/fontTools/varLib/cff.py index be42ae47a..3e17dd4f9 100755 --- a/Lib/fontTools/varLib/cff.py +++ b/Lib/fontTools/varLib/cff.py @@ -393,7 +393,7 @@ def merge_charstrings(glyphOrder, num_masters, top_dicts, masterModel): # never gets built. This could still be needed if there is variation # in the PrivatDict, so we will build the default data for vsindex = 0. if not vsindex_dict: - key = (True)*num_masters + key = (True,) * num_masters _add_new_vsindex(model, key, masterSupports, vsindex_dict, vsindex_by_key, varDataList) cvData = CVarData(varDataList=varDataList, masterSupports=masterSupports,