Merge remote-tracking branch 'origin/master' into partial-instancer

This commit is contained in:
Cosimo Lupo 2019-07-31 15:22:48 +01:00
commit 5455517689
No known key found for this signature in database
GPG Key ID: 20D4A261E4A0E642
15 changed files with 976 additions and 881 deletions

View File

@ -5,6 +5,6 @@ from fontTools.misc.loggingTools import configLogger
log = logging.getLogger(__name__)
version = __version__ = "3.43.2.dev0"
version = __version__ = "3.43.3.dev0"
__all__ = ["version", "log", "configLogger"]

View File

@ -31,6 +31,7 @@ Here is how to build a minimal TTF:
from fontTools.fontBuilder import FontBuilder
from fontTools.pens.ttGlyphPen import TTGlyphPen
def drawTestGlyph(pen):
pen.moveTo((100, 100))
pen.lineTo((100, 1000))
@ -38,35 +39,39 @@ def drawTestGlyph(pen):
pen.lineTo((500, 100))
pen.closePath()
fb = FontBuilder(1024, isTTF=True)
fb.setupGlyphOrder([".notdef", ".null", "A", "a"])
fb.setupCharacterMap({65: "A", 97: "a"})
advanceWidths = {".notdef": 600, "A": 600, "a": 600, ".null": 600}
fb = FontBuilder(1024, isTTF=True)
fb.setupGlyphOrder([".notdef", ".null", "space", "A", "a"])
fb.setupCharacterMap({32: "space", 65: "A", 97: "a"})
advanceWidths = {".notdef": 600, "space": 500, "A": 600, "a": 600, ".null": 0}
familyName = "HelloTestFont"
styleName = "TotallyNormal"
nameStrings = dict(familyName=dict(en="HelloTestFont", nl="HalloTestFont"),
styleName=dict(en="TotallyNormal", nl="TotaalNormaal"))
nameStrings['psName'] = familyName + "-" + styleName
version = "0.1"
nameStrings = dict(
familyName=dict(en=familyName, nl="HalloTestFont"),
styleName=dict(en=styleName, nl="TotaalNormaal"),
uniqueFontIdentifier="fontBuilder: " + familyName + "." + styleName,
fullName=familyName + "-" + styleName,
psName=familyName + "-" + styleName,
version="Version " + version,
)
pen = TTGlyphPen(None)
drawTestGlyph(pen)
glyph = pen.glyph()
glyphs = {".notdef": glyph, "A": glyph, "a": glyph, ".null": glyph}
glyphs = {".notdef": glyph, "space": glyph, "A": glyph, "a": glyph, ".null": glyph}
fb.setupGlyf(glyphs)
metrics = {}
glyphTable = fb.font["glyf"]
for gn, advanceWidth in advanceWidths.items():
metrics[gn] = (advanceWidth, glyphTable[gn].xMin)
fb.setupHorizontalMetrics(metrics)
fb.setupHorizontalHeader(ascent=824, descent=200)
fb.setupHorizontalHeader(ascent=824, descent=-200)
fb.setupNameTable(nameStrings)
fb.setupOS2()
fb.setupOS2(sTypoAscender=824, usWinAscent=824, usWinDescent=200)
fb.setupPost()
fb.save("test.ttf")
```
@ -76,6 +81,7 @@ And here's how to build a minimal OTF:
from fontTools.fontBuilder import FontBuilder
from fontTools.pens.t2CharStringPen import T2CharStringPen
def drawTestGlyph(pen):
pen.moveTo((100, 100))
pen.lineTo((100, 1000))
@ -83,35 +89,45 @@ def drawTestGlyph(pen):
pen.lineTo((500, 100))
pen.closePath()
fb = FontBuilder(1024, isTTF=False)
fb.setupGlyphOrder([".notdef", ".null", "A", "a"])
fb.setupCharacterMap({65: "A", 97: "a"})
advanceWidths = {".notdef": 600, "A": 600, "a": 600, ".null": 600}
fb = FontBuilder(1024, isTTF=False)
fb.setupGlyphOrder([".notdef", ".null", "space", "A", "a"])
fb.setupCharacterMap({32: "space", 65: "A", 97: "a"})
advanceWidths = {".notdef": 600, "space": 500, "A": 600, "a": 600, ".null": 0}
familyName = "HelloTestFont"
styleName = "TotallyNormal"
nameStrings = dict(familyName=dict(en="HelloTestFont", nl="HalloTestFont"),
styleName=dict(en="TotallyNormal", nl="TotaalNormaal"))
nameStrings['psName'] = familyName + "-" + styleName
version = "0.1"
nameStrings = dict(
familyName=dict(en=familyName, nl="HalloTestFont"),
styleName=dict(en=styleName, nl="TotaalNormaal"),
uniqueFontIdentifier="fontBuilder: " + familyName + "." + styleName,
fullName=familyName + "-" + styleName,
psName=familyName + "-" + styleName,
version="Version " + version,
)
pen = T2CharStringPen(600, None)
drawTestGlyph(pen)
charString = pen.getCharString()
charStrings = {".notdef": charString, "A": charString, "a": charString, ".null": charString}
fb.setupCFF(nameStrings['psName'], {"FullName": nameStrings['psName']}, charStrings, {})
charStrings = {
".notdef": charString,
"space": charString,
"A": charString,
"a": charString,
".null": charString,
}
fb.setupCFF(nameStrings["psName"], {"FullName": nameStrings["psName"]}, charStrings, {})
lsb = {gn: cs.calcBounds(None)[0] for gn, cs in charStrings.items()}
metrics = {}
for gn, advanceWidth in advanceWidths.items():
metrics[gn] = (advanceWidth, lsb[gn])
fb.setupHorizontalMetrics(metrics)
fb.setupHorizontalHeader(ascent=824, descent=200)
fb.setupNameTable(nameStrings)
fb.setupOS2()
fb.setupOS2(sTypoAscender=824, usWinAscent=824, usWinDescent=200)
fb.setupPost()
fb.save("test.otf")
```
"""

View File

@ -1391,7 +1391,7 @@ class UFOWriter(UFOReader):
def _getGlyphSetFormatVersion1(self, validateRead, validateWrite, glyphNameToFileNameFunc=None):
from fontTools.ufoLib.glifLib import GlyphSet
glyphSubFS = self.fs.makedir(DEFAULT_GLYPHS_DIRNAME, recreate=True),
glyphSubFS = self.fs.makedir(DEFAULT_GLYPHS_DIRNAME, recreate=True)
return GlyphSet(
glyphSubFS,
glyphNameToFileNameFunc=glyphNameToFileNameFunc,

View File

@ -23,8 +23,7 @@ from __future__ import unicode_literals
from fontTools.misc.py23 import *
from fontTools.misc.fixedTools import otRound
from fontTools.misc.arrayTools import Vector
from fontTools.ttLib import TTFont, newTable, TTLibError
from fontTools.ttLib.tables._n_a_m_e import NameRecord
from fontTools.ttLib import TTFont, newTable
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.ttProgram import Program
@ -36,7 +35,7 @@ from fontTools.varLib.merger import VariationMerger
from fontTools.varLib.mvar import MVAR_ENTRIES
from fontTools.varLib.iup import iup_delta_optimize
from fontTools.varLib.featureVars import addFeatureVariations
from fontTools.designspaceLib import DesignSpaceDocument, AxisDescriptor
from fontTools.designspaceLib import DesignSpaceDocument
from collections import OrderedDict, namedtuple
import os.path
import logging
@ -1017,9 +1016,6 @@ def main(args=None):
designspace_filename = options.designspace
finder = MasterFinder(options.master_finder)
outfile = options.outfile
if outfile is None:
outfile = os.path.splitext(designspace_filename)[0] + '-VF.ttf'
vf, _, _ = build(
designspace_filename,
@ -1028,6 +1024,11 @@ def main(args=None):
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)
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):
if num % 1 == 0:
if isinstance(num, float) and num.is_integer():
return int(num)
return num
@ -198,17 +198,17 @@ def merge_PrivateDicts(top_dicts, vsindex_dict, var_model, fd_map):
pds.append(pd)
num_masters = len(pds)
for key, value in private_dict.rawDict.items():
dataList = []
if key not in pd_blend_fields:
continue
if isinstance(value, list):
try:
values = [pd.rawDict[key] for pd in pds]
except KeyError:
del private_dict.rawDict[key]
print(
b"Warning: {key} in default font Private dict is "
b"missing from another font, and was "
b"discarded.".format(key=key))
"Warning: {key} in default font Private dict is "
"missing from another font, and was "
"discarded.".format(key=key))
continue
try:
values = zip(*values)
@ -227,7 +227,6 @@ def merge_PrivateDicts(top_dicts, vsindex_dict, var_model, fd_map):
and is converted finally to:
OtherBlues = [[-217, 17.0, 46.0], [-205, 0.0, 0.0]]
"""
dataList = []
prev_val_list = [0] * num_masters
any_points_differ = False
for val_list in values:
@ -237,8 +236,6 @@ def merge_PrivateDicts(top_dicts, vsindex_dict, var_model, fd_map):
any_points_differ = True
prev_val_list = val_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
# values are absolute, not relative to the prior value.
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)
else:
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
@ -270,7 +279,7 @@ def getfd_map(varFont, fonts_list):
num_regions = len(region_fonts)
topDict = default_font['CFF '].cff.topDictIndex[0]
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.
fd_map[0] = {ri:0 for ri in range(num_regions)}
return fd_map
@ -390,9 +399,9 @@ def merge_charstrings(glyphOrder, num_masters, top_dicts, masterModel):
# 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 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

View File

@ -71,7 +71,7 @@ def overlayFeatureVariations(conditionalSubstitutions):
and rules with the same Box merged. The more specific rules appear earlier
in the resulting list. Moreover, instead of just a dictionary of substitutions,
a list of dictionaries is returned for substitutions corresponding to each
uniq space, with each dictionary being identical to one of the input
unique space, with each dictionary being identical to one of the input
substitution dictionaries. These dictionaries are not merged to allow data
sharing when they are converted into font tables.
@ -79,6 +79,7 @@ def overlayFeatureVariations(conditionalSubstitutions):
>>> condSubst = [
... # A list of (Region, Substitution) tuples.
... ([{"wght": (0.5, 1.0)}], {"dollar": "dollar.rvrn"}),
... ([{"wght": (0.5, 1.0)}], {"dollar": "dollar.rvrn"}),
... ([{"wdth": (0.5, 1.0)}], {"cent": "cent.rvrn"}),
... ]
>>> from pprint import pprint
@ -107,7 +108,8 @@ def overlayFeatureVariations(conditionalSubstitutions):
# rules for the same region.
merged = OrderedDict()
for key,value in reversed(conditionalSubstitutions):
key = tuple(sorted(hashdict(cleanupBox(k)) for k in key))
key = tuple(sorted((hashdict(cleanupBox(k)) for k in key),
key=lambda d: tuple(sorted(d.items()))))
if key in merged:
merged[key].update(value)
else:

View File

@ -1,3 +1,9 @@
3.43.2 (released 2019-07-10)
----------------------------
- [featureVars] Fixed region-merging code on python3 (#1659).
- [varLib.cff] Fixed merging of sparse PrivateDict items (#1653).
3.43.1 (released 2019-06-19)
----------------------------

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -9,3 +9,7 @@ munkres==1.0.12; platform_python_implementation == "PyPy" and python_version < '
munkres==1.1.2; platform_python_implementation == "PyPy" and python_version >= '3.5'
zopfli==0.1.6
fs==2.4.8
# lxml 4.4.0 breaks OrderedDict attributes in python < 3.6 so we pin to previous version
# https://bugs.launchpad.net/lxml/+bug/1838252
lxml==4.3.5; python_version < '3.6' # pyup: ignore
lxml==4.4.0; python_version >= '3.6'

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 3.43.2.dev0
current_version = 3.43.3.dev0
commit = True
tag = False
tag_name = {new_version}

View File

@ -352,7 +352,7 @@ def find_data_files(manpath="share/man"):
setup(
name="fonttools",
version="3.43.2.dev0",
version="3.43.3.dev0",
description="Tools to manipulate font files",
author="Just van Rossum",
author_email="just@letterror.com",