Merge remote-tracking branch 'origin/master' into partial-instancer
This commit is contained in:
commit
5455517689
@ -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"]
|
||||
|
@ -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")
|
||||
```
|
||||
"""
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
||||
|
25
Lib/fontTools/varLib/cff.py
Executable file → Normal file
25
Lib/fontTools/varLib/cff.py
Executable file → Normal 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
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
6
NEWS.rst
6
NEWS.rst
@ -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
@ -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"/>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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"/>
|
||||
|
@ -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'
|
||||
|
@ -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}
|
||||
|
Loading…
x
Reference in New Issue
Block a user