varLib CFF fixes (#1653)

* varLib.cff: Apply conv_to_int() to all the values

* varLib: Don't hardcode file extension to 'ttf'

Also remove unused imports

* varLib.cff: Fix merging of sparse PrivateDict items

Fixes #1651
This commit is contained in:
Miguel Sousa 2019-06-24 17:10:36 -07:00 committed by Read Roberts
parent 18f969ab7d
commit e1f0d1ae09
6 changed files with 33 additions and 21 deletions

View File

@ -23,8 +23,7 @@ from __future__ import unicode_literals
from fontTools.misc.py23 import * from fontTools.misc.py23 import *
from fontTools.misc.fixedTools import otRound from fontTools.misc.fixedTools import otRound
from fontTools.misc.arrayTools import Vector from fontTools.misc.arrayTools import Vector
from fontTools.ttLib import TTFont, newTable, TTLibError from fontTools.ttLib import TTFont, newTable
from fontTools.ttLib.tables._n_a_m_e import NameRecord
from fontTools.ttLib.tables._f_v_a_r import Axis, NamedInstance from fontTools.ttLib.tables._f_v_a_r import Axis, NamedInstance
from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates
from fontTools.ttLib.tables.ttProgram import Program from fontTools.ttLib.tables.ttProgram import Program
@ -36,7 +35,7 @@ from fontTools.varLib.merger import VariationMerger
from fontTools.varLib.mvar import MVAR_ENTRIES from fontTools.varLib.mvar import MVAR_ENTRIES
from fontTools.varLib.iup import iup_delta_optimize from fontTools.varLib.iup import iup_delta_optimize
from fontTools.varLib.featureVars import addFeatureVariations from fontTools.varLib.featureVars import addFeatureVariations
from fontTools.designspaceLib import DesignSpaceDocument, AxisDescriptor from fontTools.designspaceLib import DesignSpaceDocument
from collections import OrderedDict, namedtuple from collections import OrderedDict, namedtuple
import os.path import os.path
import logging import logging
@ -1107,9 +1106,6 @@ def main(args=None):
designspace_filename = options.designspace designspace_filename = options.designspace
finder = MasterFinder(options.master_finder) finder = MasterFinder(options.master_finder)
outfile = options.outfile
if outfile is None:
outfile = os.path.splitext(designspace_filename)[0] + '-VF.ttf'
vf, _, _ = build( vf, _, _ = build(
designspace_filename, designspace_filename,
@ -1118,6 +1114,11 @@ def main(args=None):
optimize=options.optimize optimize=options.optimize
) )
outfile = options.outfile
if outfile is None:
ext = "otf" if vf.sfntVersion == "OTTO" else "ttf"
outfile = os.path.splitext(designspace_filename)[0] + '-VF.' + ext
log.info("Saving variation font %s", outfile) log.info("Saving variation font %s", outfile)
vf.save(outfile) vf.save(outfile)

31
Lib/fontTools/varLib/cff.py Executable file → Normal file
View File

@ -131,7 +131,7 @@ class MergeDictError(TypeError):
def conv_to_int(num): def conv_to_int(num):
if num % 1 == 0: if isinstance(num, float) and num.is_integer():
return int(num) return int(num)
return num return num
@ -198,17 +198,17 @@ def merge_PrivateDicts(top_dicts, vsindex_dict, var_model, fd_map):
pds.append(pd) pds.append(pd)
num_masters = len(pds) num_masters = len(pds)
for key, value in private_dict.rawDict.items(): for key, value in private_dict.rawDict.items():
dataList = []
if key not in pd_blend_fields: if key not in pd_blend_fields:
continue continue
if isinstance(value, list): if isinstance(value, list):
try: try:
values = [pd.rawDict[key] for pd in pds] values = [pd.rawDict[key] for pd in pds]
except KeyError: except KeyError:
del private_dict.rawDict[key]
print( print(
b"Warning: {key} in default font Private dict is " "Warning: {key} in default font Private dict is "
b"missing from another font, and was " "missing from another font, and was "
b"discarded.".format(key=key)) "discarded.".format(key=key))
continue continue
try: try:
values = zip(*values) values = zip(*values)
@ -227,7 +227,6 @@ def merge_PrivateDicts(top_dicts, vsindex_dict, var_model, fd_map):
and is converted finally to: and is converted finally to:
OtherBlues = [[-217, 17.0, 46.0], [-205, 0.0, 0.0]] OtherBlues = [[-217, 17.0, 46.0], [-205, 0.0, 0.0]]
""" """
dataList = []
prev_val_list = [0] * num_masters prev_val_list = [0] * num_masters
any_points_differ = False any_points_differ = False
for val_list in values: for val_list in values:
@ -237,8 +236,6 @@ def merge_PrivateDicts(top_dicts, vsindex_dict, var_model, fd_map):
any_points_differ = True any_points_differ = True
prev_val_list = val_list prev_val_list = val_list
deltas = sub_model.getDeltas(rel_list) deltas = sub_model.getDeltas(rel_list)
# Convert numbers with no decimal part to an int.
deltas = [conv_to_int(delta) for delta in deltas]
# For PrivateDict BlueValues, the default font # For PrivateDict BlueValues, the default font
# values are absolute, not relative to the prior value. # values are absolute, not relative to the prior value.
deltas[0] = val_list[0] deltas[0] = val_list[0]
@ -253,6 +250,18 @@ def merge_PrivateDicts(top_dicts, vsindex_dict, var_model, fd_map):
dataList = sub_model.getDeltas(values) dataList = sub_model.getDeltas(values)
else: else:
dataList = values[0] dataList = values[0]
# Convert numbers with no decimal part to an int
if isinstance(dataList, list):
for i, item in enumerate(dataList):
if isinstance(item, list):
for j, jtem in enumerate(item):
dataList[i][j] = conv_to_int(jtem)
else:
dataList[i] = conv_to_int(item)
else:
dataList = conv_to_int(dataList)
private_dict.rawDict[key] = dataList private_dict.rawDict[key] = dataList
@ -270,7 +279,7 @@ def getfd_map(varFont, fonts_list):
num_regions = len(region_fonts) num_regions = len(region_fonts)
topDict = default_font['CFF '].cff.topDictIndex[0] topDict = default_font['CFF '].cff.topDictIndex[0]
if not hasattr(topDict, 'FDSelect'): if not hasattr(topDict, 'FDSelect'):
# All glyphs reference only one FontDict. # All glyphs reference only one FontDict.
# Map the FD index for regions to index 0. # Map the FD index for regions to index 0.
fd_map[0] = {ri:0 for ri in range(num_regions)} fd_map[0] = {ri:0 for ri in range(num_regions)}
return fd_map return fd_map
@ -390,9 +399,9 @@ def merge_charstrings(glyphOrder, num_masters, top_dicts, masterModel):
# as we know it doesn't exist yet. # as we know it doesn't exist yet.
if vsindex != 0: if vsindex != 0:
new_cs.program[:0] = [vsindex, 'vsindex'] new_cs.program[:0] = [vsindex, 'vsindex']
# If there is no variation in any of the charstrings, then vsindex_dict # If there is no variation in any of the charstrings, then vsindex_dict
# never gets built. This 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. # in the PrivatDict, so we will build the default data for vsindex = 0.
if not vsindex_dict: if not vsindex_dict:
key = (True,) * num_masters key = (True,) * num_masters

View File

@ -374,6 +374,7 @@
<FontName value="MasterSet_Kanji-w0.00-Generic"/> <FontName value="MasterSet_Kanji-w0.00-Generic"/>
<Private> <Private>
<BlueValues value="-250 -250 1100 1100"/> <BlueValues value="-250 -250 1100 1100"/>
<FamilyBlues value="-250 -240 1100 1110"/>
<BlueScale value="0.039625"/> <BlueScale value="0.039625"/>
<BlueShift value="7"/> <BlueShift value="7"/>
<BlueFuzz value="0"/> <BlueFuzz value="0"/>

View File

@ -86,10 +86,10 @@
<BlueShift value="7"/> <BlueShift value="7"/>
<BlueFuzz value="0"/> <BlueFuzz value="0"/>
<StdHW> <StdHW>
<blend value="67 -39.0 67.0"/> <blend value="67 -39 67"/>
</StdHW> </StdHW>
<StdVW> <StdVW>
<blend value="85 -51.0 87.0"/> <blend value="85 -51 87"/>
</StdVW> </StdVW>
</Private> </Private>
</FontDict> </FontDict>

View File

@ -31,10 +31,10 @@
<BlueShift value="7"/> <BlueShift value="7"/>
<BlueFuzz value="0"/> <BlueFuzz value="0"/>
<StdHW> <StdHW>
<blend value="28 39.0"/> <blend value="28 39"/>
</StdHW> </StdHW>
<StdVW> <StdVW>
<blend value="34 51.0"/> <blend value="34 51"/>
</StdVW> </StdVW>
</Private> </Private>
</FontDict> </FontDict>

View File

@ -132,6 +132,7 @@
<FontDict index="0"> <FontDict index="0">
<Private> <Private>
<BlueValues value="-250 -250 1100 1100"/> <BlueValues value="-250 -250 1100 1100"/>
<FamilyBlues value="-250 -240 1100 1110"/>
<BlueScale value="0.039625"/> <BlueScale value="0.039625"/>
<BlueShift value="7"/> <BlueShift value="7"/>
<BlueFuzz value="0"/> <BlueFuzz value="0"/>