fonttools 4.58.5__cp39-cp39-win32.whl → 4.59.1__cp39-cp39-win32.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of fonttools might be problematic. Click here for more details.
- fontTools/__init__.py +1 -1
- fontTools/cffLib/CFF2ToCFF.py +40 -10
- fontTools/cffLib/transforms.py +11 -6
- fontTools/cu2qu/cu2qu.cp39-win32.pyd +0 -0
- fontTools/feaLib/builder.py +6 -1
- fontTools/feaLib/lexer.cp39-win32.pyd +0 -0
- fontTools/merge/__init__.py +1 -1
- fontTools/misc/bezierTools.cp39-win32.pyd +0 -0
- fontTools/misc/filesystem/__init__.py +68 -0
- fontTools/misc/filesystem/_base.py +134 -0
- fontTools/misc/filesystem/_copy.py +45 -0
- fontTools/misc/filesystem/_errors.py +54 -0
- fontTools/misc/filesystem/_info.py +75 -0
- fontTools/misc/filesystem/_osfs.py +164 -0
- fontTools/misc/filesystem/_path.py +67 -0
- fontTools/misc/filesystem/_subfs.py +92 -0
- fontTools/misc/filesystem/_tempfs.py +34 -0
- fontTools/misc/filesystem/_tools.py +34 -0
- fontTools/misc/filesystem/_walk.py +55 -0
- fontTools/misc/filesystem/_zipfs.py +204 -0
- fontTools/misc/psCharStrings.py +17 -2
- fontTools/misc/sstruct.py +2 -6
- fontTools/misc/xmlWriter.py +28 -1
- fontTools/pens/momentsPen.cp39-win32.pyd +0 -0
- fontTools/pens/roundingPen.py +2 -2
- fontTools/qu2cu/qu2cu.cp39-win32.pyd +0 -0
- fontTools/subset/__init__.py +11 -11
- fontTools/ttLib/sfnt.py +2 -3
- fontTools/ttLib/tables/S__i_l_f.py +2 -2
- fontTools/ttLib/tables/T_S_I__1.py +2 -5
- fontTools/ttLib/tables/T_S_I__5.py +2 -2
- fontTools/ttLib/tables/_c_m_a_p.py +1 -1
- fontTools/ttLib/tables/_c_v_t.py +1 -2
- fontTools/ttLib/tables/_g_l_y_f.py +9 -10
- fontTools/ttLib/tables/_g_v_a_r.py +6 -3
- fontTools/ttLib/tables/_h_d_m_x.py +4 -4
- fontTools/ttLib/tables/_h_m_t_x.py +7 -3
- fontTools/ttLib/tables/_l_o_c_a.py +2 -2
- fontTools/ttLib/tables/_p_o_s_t.py +3 -4
- fontTools/ttLib/tables/otBase.py +2 -4
- fontTools/ttLib/tables/otTables.py +7 -12
- fontTools/ttLib/tables/sbixStrike.py +3 -3
- fontTools/ttLib/ttFont.py +7 -16
- fontTools/ttLib/woff2.py +10 -13
- fontTools/ufoLib/__init__.py +20 -25
- fontTools/ufoLib/glifLib.py +12 -17
- fontTools/ufoLib/validators.py +2 -4
- fontTools/unicodedata/__init__.py +2 -0
- fontTools/varLib/featureVars.py +8 -0
- fontTools/varLib/hvar.py +1 -1
- fontTools/varLib/instancer/__init__.py +65 -5
- fontTools/varLib/iup.cp39-win32.pyd +0 -0
- fontTools/varLib/mutator.py +11 -0
- {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/METADATA +42 -12
- {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/RECORD +61 -49
- {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/licenses/LICENSE.external +29 -0
- {fonttools-4.58.5.data → fonttools-4.59.1.data}/data/share/man/man1/ttx.1 +0 -0
- {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/WHEEL +0 -0
- {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/entry_points.txt +0 -0
- {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/licenses/LICENSE +0 -0
- {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/top_level.txt +0 -0
fontTools/misc/sstruct.py
CHANGED
|
@@ -64,10 +64,7 @@ def pack(fmt, obj):
|
|
|
64
64
|
elements = []
|
|
65
65
|
if not isinstance(obj, dict):
|
|
66
66
|
obj = obj.__dict__
|
|
67
|
-
|
|
68
|
-
if formatstring.startswith(">"):
|
|
69
|
-
string_index = formatstring[1:]
|
|
70
|
-
for ix, name in enumerate(names.keys()):
|
|
67
|
+
for name in names.keys():
|
|
71
68
|
value = obj[name]
|
|
72
69
|
if name in fixes:
|
|
73
70
|
# fixed point conversion
|
|
@@ -96,8 +93,7 @@ def unpack(fmt, data, obj=None):
|
|
|
96
93
|
else:
|
|
97
94
|
d = obj.__dict__
|
|
98
95
|
elements = struct.unpack(formatstring, data)
|
|
99
|
-
for i in
|
|
100
|
-
name = list(names.keys())[i]
|
|
96
|
+
for i, name in enumerate(names.keys()):
|
|
101
97
|
value = elements[i]
|
|
102
98
|
if name in fixes:
|
|
103
99
|
# fixed point conversion
|
fontTools/misc/xmlWriter.py
CHANGED
|
@@ -4,8 +4,22 @@ from fontTools.misc.textTools import byteord, strjoin, tobytes, tostr
|
|
|
4
4
|
import sys
|
|
5
5
|
import os
|
|
6
6
|
import string
|
|
7
|
+
import logging
|
|
8
|
+
import itertools
|
|
7
9
|
|
|
8
10
|
INDENT = " "
|
|
11
|
+
TTX_LOG = logging.getLogger("fontTools.ttx")
|
|
12
|
+
REPLACEMENT = "?"
|
|
13
|
+
ILLEGAL_XML_CHARS = dict.fromkeys(
|
|
14
|
+
itertools.chain(
|
|
15
|
+
range(0x00, 0x09),
|
|
16
|
+
(0x0B, 0x0C),
|
|
17
|
+
range(0x0E, 0x20),
|
|
18
|
+
range(0xD800, 0xE000),
|
|
19
|
+
(0xFFFE, 0xFFFF),
|
|
20
|
+
),
|
|
21
|
+
REPLACEMENT,
|
|
22
|
+
)
|
|
9
23
|
|
|
10
24
|
|
|
11
25
|
class XMLWriter(object):
|
|
@@ -168,12 +182,25 @@ class XMLWriter(object):
|
|
|
168
182
|
|
|
169
183
|
|
|
170
184
|
def escape(data):
|
|
185
|
+
"""Escape characters not allowed in `XML 1.0 <https://www.w3.org/TR/xml/#NT-Char>`_."""
|
|
171
186
|
data = tostr(data, "utf_8")
|
|
172
187
|
data = data.replace("&", "&")
|
|
173
188
|
data = data.replace("<", "<")
|
|
174
189
|
data = data.replace(">", ">")
|
|
175
190
|
data = data.replace("\r", " ")
|
|
176
|
-
|
|
191
|
+
|
|
192
|
+
newData = data.translate(ILLEGAL_XML_CHARS)
|
|
193
|
+
if newData != data:
|
|
194
|
+
maxLen = 10
|
|
195
|
+
preview = repr(data)
|
|
196
|
+
if len(data) > maxLen:
|
|
197
|
+
preview = repr(data[:maxLen])[1:-1] + "..."
|
|
198
|
+
TTX_LOG.warning(
|
|
199
|
+
"Illegal XML character(s) found; replacing offending " "string %r with %r",
|
|
200
|
+
preview,
|
|
201
|
+
REPLACEMENT,
|
|
202
|
+
)
|
|
203
|
+
return newData
|
|
177
204
|
|
|
178
205
|
|
|
179
206
|
def escapeattr(data):
|
|
Binary file
|
fontTools/pens/roundingPen.py
CHANGED
|
@@ -116,8 +116,8 @@ class RoundingPointPen(FilterPointPen):
|
|
|
116
116
|
def addComponent(self, baseGlyphName, transformation, identifier=None, **kwargs):
|
|
117
117
|
xx, xy, yx, yy, dx, dy = transformation
|
|
118
118
|
self._outPen.addComponent(
|
|
119
|
-
baseGlyphName
|
|
120
|
-
|
|
119
|
+
baseGlyphName,
|
|
120
|
+
Transform(
|
|
121
121
|
self.transformRoundFunc(xx),
|
|
122
122
|
self.transformRoundFunc(xy),
|
|
123
123
|
self.transformRoundFunc(yx),
|
|
Binary file
|
fontTools/subset/__init__.py
CHANGED
|
@@ -27,16 +27,16 @@ from collections import Counter, defaultdict
|
|
|
27
27
|
from functools import reduce
|
|
28
28
|
from types import MethodType
|
|
29
29
|
|
|
30
|
-
__usage__ = "
|
|
30
|
+
__usage__ = "fonttools subset font-file [glyph...] [--option=value]..."
|
|
31
31
|
|
|
32
32
|
__doc__ = (
|
|
33
33
|
"""\
|
|
34
|
-
|
|
34
|
+
fonttools subset -- OpenType font subsetter and optimizer
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
It accepts any TT- or CFF-flavored OpenType (.otf or .ttf)
|
|
38
|
-
font file. The subsetted glyph set is based on the
|
|
39
|
-
or characters, and specified OpenType layout features.
|
|
36
|
+
fonttools subset is an OpenType font subsetter and optimizer, based on
|
|
37
|
+
fontTools. It accepts any TT- or CFF-flavored OpenType (.otf or .ttf)
|
|
38
|
+
or WOFF (.woff) font file. The subsetted glyph set is based on the
|
|
39
|
+
specified glyphs or characters, and specified OpenType layout features.
|
|
40
40
|
|
|
41
41
|
The tool also performs some size-reducing optimizations, aimed for using
|
|
42
42
|
subset fonts as webfonts. Individual optimizations can be enabled or
|
|
@@ -130,11 +130,11 @@ you might need to escape the question mark, like this: '--glyph-names\\?'.
|
|
|
130
130
|
|
|
131
131
|
Examples::
|
|
132
132
|
|
|
133
|
-
$
|
|
133
|
+
$ fonttools subset --glyph-names?
|
|
134
134
|
Current setting for 'glyph-names' is: False
|
|
135
|
-
$
|
|
135
|
+
$ fonttools subset --name-IDs=?
|
|
136
136
|
Current setting for 'name-IDs' is: [0, 1, 2, 3, 4, 5, 6]
|
|
137
|
-
$
|
|
137
|
+
$ fonttools subset --hinting? --no-hinting --hinting?
|
|
138
138
|
Current setting for 'hinting' is: True
|
|
139
139
|
Current setting for 'hinting' is: False
|
|
140
140
|
|
|
@@ -445,7 +445,7 @@ Example
|
|
|
445
445
|
Produce a subset containing the characters ' !"#$%' without performing
|
|
446
446
|
size-reducing optimizations::
|
|
447
447
|
|
|
448
|
-
$
|
|
448
|
+
$ fonttools subset font.ttf --unicodes="U+0020-0025" \\
|
|
449
449
|
--layout-features=* --glyph-names --symbol-cmap --legacy-cmap \\
|
|
450
450
|
--notdef-glyph --notdef-outline --recommended-glyphs \\
|
|
451
451
|
--name-IDs=* --name-legacy --name-languages=*
|
|
@@ -3768,7 +3768,7 @@ def parse_glyphs(s):
|
|
|
3768
3768
|
|
|
3769
3769
|
def usage():
|
|
3770
3770
|
print("usage:", __usage__, file=sys.stderr)
|
|
3771
|
-
print("Try
|
|
3771
|
+
print("Try fonttools subset --help for more information.\n", file=sys.stderr)
|
|
3772
3772
|
|
|
3773
3773
|
|
|
3774
3774
|
@timer("make one with everything (TOTAL TIME)")
|
fontTools/ttLib/sfnt.py
CHANGED
|
@@ -375,10 +375,9 @@ class SFNTWriter(object):
|
|
|
375
375
|
|
|
376
376
|
def _calcMasterChecksum(self, directory):
|
|
377
377
|
# calculate checkSumAdjustment
|
|
378
|
-
tags = list(self.tables.keys())
|
|
379
378
|
checksums = []
|
|
380
|
-
for
|
|
381
|
-
checksums.append(self.tables[
|
|
379
|
+
for tag in self.tables.keys():
|
|
380
|
+
checksums.append(self.tables[tag].checkSum)
|
|
382
381
|
|
|
383
382
|
if self.DirectoryEntry != SFNTDirectoryEntry:
|
|
384
383
|
# Create a SFNT directory for checksum calculation purposes
|
|
@@ -948,7 +948,7 @@ class Pass(object):
|
|
|
948
948
|
writer.newline()
|
|
949
949
|
writer.begintag("rules")
|
|
950
950
|
writer.newline()
|
|
951
|
-
for i in
|
|
951
|
+
for i, action in enumerate(self.actions):
|
|
952
952
|
writer.begintag(
|
|
953
953
|
"rule",
|
|
954
954
|
index=i,
|
|
@@ -958,7 +958,7 @@ class Pass(object):
|
|
|
958
958
|
writer.newline()
|
|
959
959
|
if len(self.ruleConstraints[i]):
|
|
960
960
|
writecode("constraint", writer, self.ruleConstraints[i])
|
|
961
|
-
writecode("action", writer,
|
|
961
|
+
writecode("action", writer, action)
|
|
962
962
|
writer.endtag("rule")
|
|
963
963
|
writer.newline()
|
|
964
964
|
writer.endtag("rules")
|
|
@@ -91,12 +91,11 @@ class table_T_S_I__1(LogMixin, DefaultTable.DefaultTable):
|
|
|
91
91
|
glyphNames = ttFont.getGlyphOrder()
|
|
92
92
|
|
|
93
93
|
indices = []
|
|
94
|
-
for i in
|
|
94
|
+
for i, name in enumerate(glyphNames):
|
|
95
95
|
if len(data) % 2:
|
|
96
96
|
data = (
|
|
97
97
|
data + b"\015"
|
|
98
98
|
) # align on 2-byte boundaries, fill with return chars. Yum.
|
|
99
|
-
name = glyphNames[i]
|
|
100
99
|
if name in self.glyphPrograms:
|
|
101
100
|
text = tobytes(self.glyphPrograms[name], encoding="utf-8")
|
|
102
101
|
else:
|
|
@@ -108,13 +107,11 @@ class table_T_S_I__1(LogMixin, DefaultTable.DefaultTable):
|
|
|
108
107
|
data = data + text
|
|
109
108
|
|
|
110
109
|
extra_indices = []
|
|
111
|
-
|
|
112
|
-
for i in range(len(codes)):
|
|
110
|
+
for code, name in sorted(self.extras.items()):
|
|
113
111
|
if len(data) % 2:
|
|
114
112
|
data = (
|
|
115
113
|
data + b"\015"
|
|
116
114
|
) # align on 2-byte boundaries, fill with return chars.
|
|
117
|
-
code, name = codes[i]
|
|
118
115
|
if name in self.extraPrograms:
|
|
119
116
|
text = tobytes(self.extraPrograms[name], encoding="utf-8")
|
|
120
117
|
else:
|
|
@@ -38,8 +38,8 @@ class table_T_S_I__5(DefaultTable.DefaultTable):
|
|
|
38
38
|
def compile(self, ttFont):
|
|
39
39
|
glyphNames = ttFont.getGlyphOrder()
|
|
40
40
|
a = array.array("H")
|
|
41
|
-
for
|
|
42
|
-
a.append(self.glyphGrouping.get(
|
|
41
|
+
for glyphName in glyphNames:
|
|
42
|
+
a.append(self.glyphGrouping.get(glyphName, 0))
|
|
43
43
|
if sys.byteorder != "big":
|
|
44
44
|
a.byteswap()
|
|
45
45
|
return a.tobytes()
|
|
@@ -398,7 +398,7 @@ class cmap_format_0(CmapSubtable):
|
|
|
398
398
|
assert 262 == self.length, "Format 0 cmap subtable not 262 bytes"
|
|
399
399
|
gids = array.array("B")
|
|
400
400
|
gids.frombytes(self.data)
|
|
401
|
-
charCodes =
|
|
401
|
+
charCodes = range(len(gids))
|
|
402
402
|
self.cmap = _make_map(self.ttFont, charCodes, gids)
|
|
403
403
|
|
|
404
404
|
def compile(self, ttFont):
|
fontTools/ttLib/tables/_c_v_t.py
CHANGED
|
@@ -29,8 +29,7 @@ class table__c_v_t(DefaultTable.DefaultTable):
|
|
|
29
29
|
return values.tobytes()
|
|
30
30
|
|
|
31
31
|
def toXML(self, writer, ttFont):
|
|
32
|
-
for i in
|
|
33
|
-
value = self.values[i]
|
|
32
|
+
for i, value in enumerate(self.values):
|
|
34
33
|
writer.simpletag("cv", value=value, index=i)
|
|
35
34
|
writer.newline()
|
|
36
35
|
|
|
@@ -974,11 +974,10 @@ class Glyph(object):
|
|
|
974
974
|
lastcomponent = len(self.components) - 1
|
|
975
975
|
more = 1
|
|
976
976
|
haveInstructions = 0
|
|
977
|
-
for i in
|
|
977
|
+
for i, compo in enumerate(self.components):
|
|
978
978
|
if i == lastcomponent:
|
|
979
979
|
haveInstructions = hasattr(self, "program")
|
|
980
980
|
more = 0
|
|
981
|
-
compo = self.components[i]
|
|
982
981
|
data = data + compo.compile(more, haveInstructions, glyfTable)
|
|
983
982
|
if haveInstructions:
|
|
984
983
|
instructions = self.program.getBytecode()
|
|
@@ -2037,8 +2036,8 @@ class GlyphCoordinates(object):
|
|
|
2037
2036
|
if round is noRound:
|
|
2038
2037
|
return
|
|
2039
2038
|
a = self._a
|
|
2040
|
-
for i in
|
|
2041
|
-
a[i] = round(
|
|
2039
|
+
for i, value in enumerate(a):
|
|
2040
|
+
a[i] = round(value)
|
|
2042
2041
|
|
|
2043
2042
|
def calcBounds(self):
|
|
2044
2043
|
a = self._a
|
|
@@ -2168,8 +2167,8 @@ class GlyphCoordinates(object):
|
|
|
2168
2167
|
"""
|
|
2169
2168
|
r = self.copy()
|
|
2170
2169
|
a = r._a
|
|
2171
|
-
for i in
|
|
2172
|
-
a[i] = -
|
|
2170
|
+
for i, value in enumerate(a):
|
|
2171
|
+
a[i] = -value
|
|
2173
2172
|
return r
|
|
2174
2173
|
|
|
2175
2174
|
def __round__(self, *, round=otRound):
|
|
@@ -2214,8 +2213,8 @@ class GlyphCoordinates(object):
|
|
|
2214
2213
|
other = other._a
|
|
2215
2214
|
a = self._a
|
|
2216
2215
|
assert len(a) == len(other)
|
|
2217
|
-
for i in
|
|
2218
|
-
a[i] +=
|
|
2216
|
+
for i, value in enumerate(other):
|
|
2217
|
+
a[i] += value
|
|
2219
2218
|
return self
|
|
2220
2219
|
return NotImplemented
|
|
2221
2220
|
|
|
@@ -2238,8 +2237,8 @@ class GlyphCoordinates(object):
|
|
|
2238
2237
|
other = other._a
|
|
2239
2238
|
a = self._a
|
|
2240
2239
|
assert len(a) == len(other)
|
|
2241
|
-
for i in
|
|
2242
|
-
a[i] -=
|
|
2240
|
+
for i, value in enumerate(other):
|
|
2241
|
+
a[i] -= value
|
|
2243
2242
|
return self
|
|
2244
2243
|
return NotImplemented
|
|
2245
2244
|
|
|
@@ -64,7 +64,6 @@ class table__g_v_a_r(DefaultTable.DefaultTable):
|
|
|
64
64
|
self.variations = {}
|
|
65
65
|
|
|
66
66
|
def compile(self, ttFont):
|
|
67
|
-
|
|
68
67
|
axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
|
|
69
68
|
sharedTuples = tv.compileSharedTuples(
|
|
70
69
|
axisTags, itertools.chain(*self.variations.values())
|
|
@@ -141,8 +140,12 @@ class table__g_v_a_r(DefaultTable.DefaultTable):
|
|
|
141
140
|
self,
|
|
142
141
|
)
|
|
143
142
|
|
|
144
|
-
assert len(glyphs) == self.glyphCount
|
|
145
|
-
assert len(axisTags) == self.axisCount
|
|
143
|
+
assert len(glyphs) == self.glyphCount, (len(glyphs), self.glyphCount)
|
|
144
|
+
assert len(axisTags) == self.axisCount, (
|
|
145
|
+
len(axisTags),
|
|
146
|
+
self.axisCount,
|
|
147
|
+
axisTags,
|
|
148
|
+
)
|
|
146
149
|
sharedCoords = tv.decompileSharedTuples(
|
|
147
150
|
axisTags, self.sharedTupleCount, data, self.offsetToSharedTuples
|
|
148
151
|
)
|
|
@@ -65,8 +65,8 @@ class table__h_d_m_x(DefaultTable.DefaultTable):
|
|
|
65
65
|
items = sorted(self.hdmx.items())
|
|
66
66
|
for ppem, widths in items:
|
|
67
67
|
data = data + bytechr(ppem) + bytechr(max(widths.values()))
|
|
68
|
-
for
|
|
69
|
-
width = widths[
|
|
68
|
+
for glyphName in glyphOrder:
|
|
69
|
+
width = widths[glyphName]
|
|
70
70
|
data = data + bytechr(width)
|
|
71
71
|
data = data + pad
|
|
72
72
|
return data
|
|
@@ -123,5 +123,5 @@ class table__h_d_m_x(DefaultTable.DefaultTable):
|
|
|
123
123
|
glyphName = safeEval('"""' + glyphName + '"""')
|
|
124
124
|
line = list(map(int, line[1:]))
|
|
125
125
|
assert len(line) == len(ppems), "illegal hdmx format"
|
|
126
|
-
for i in
|
|
127
|
-
hdmx[
|
|
126
|
+
for i, ppem in enumerate(ppems):
|
|
127
|
+
hdmx[ppem][glyphName] = line[i]
|
|
@@ -40,15 +40,19 @@ class table__h_m_t_x(DefaultTable.DefaultTable):
|
|
|
40
40
|
% (self.headerTag, self.numberOfMetricsName)
|
|
41
41
|
)
|
|
42
42
|
numberOfMetrics = numGlyphs
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
numberOfSideBearings = numGlyphs - numberOfMetrics
|
|
44
|
+
tableSize = 4 * numberOfMetrics + 2 * numberOfSideBearings
|
|
45
|
+
if len(data) < tableSize:
|
|
46
|
+
raise ttLib.TTLibError(
|
|
47
|
+
f"not enough '{self.tableTag}' table data: "
|
|
48
|
+
f"expected {tableSize} bytes, got {len(data)}"
|
|
49
|
+
)
|
|
45
50
|
# Note: advanceWidth is unsigned, but some font editors might
|
|
46
51
|
# read/write as signed. We can't be sure whether it was a mistake
|
|
47
52
|
# or not, so we read as unsigned but also issue a warning...
|
|
48
53
|
metricsFmt = ">" + self.longMetricFormat * numberOfMetrics
|
|
49
54
|
metrics = struct.unpack(metricsFmt, data[: 4 * numberOfMetrics])
|
|
50
55
|
data = data[4 * numberOfMetrics :]
|
|
51
|
-
numberOfSideBearings = numGlyphs - numberOfMetrics
|
|
52
56
|
sideBearings = array.array("h", data[: 2 * numberOfSideBearings])
|
|
53
57
|
data = data[2 * numberOfSideBearings :]
|
|
54
58
|
|
|
@@ -46,8 +46,8 @@ class table__l_o_c_a(DefaultTable.DefaultTable):
|
|
|
46
46
|
max_location = 0
|
|
47
47
|
if max_location < 0x20000 and all(l % 2 == 0 for l in self.locations):
|
|
48
48
|
locations = array.array("H")
|
|
49
|
-
for
|
|
50
|
-
locations.append(
|
|
49
|
+
for location in self.locations:
|
|
50
|
+
locations.append(location // 2)
|
|
51
51
|
ttFont["head"].indexToLocFormat = 0
|
|
52
52
|
else:
|
|
53
53
|
locations = array.array("I", self.locations)
|
|
@@ -174,10 +174,9 @@ class table__p_o_s_t(DefaultTable.DefaultTable):
|
|
|
174
174
|
extraNames = self.extraNames = [
|
|
175
175
|
n for n in self.extraNames if n not in standardGlyphOrder
|
|
176
176
|
]
|
|
177
|
-
for i in
|
|
178
|
-
extraDict[
|
|
179
|
-
for
|
|
180
|
-
glyphName = glyphOrder[glyphID]
|
|
177
|
+
for i, name in enumerate(extraNames):
|
|
178
|
+
extraDict[name] = i
|
|
179
|
+
for glyphName in glyphOrder:
|
|
181
180
|
if glyphName in self.mapping:
|
|
182
181
|
psName = self.mapping[glyphName]
|
|
183
182
|
else:
|
fontTools/ttLib/tables/otBase.py
CHANGED
|
@@ -500,8 +500,7 @@ class OTTableWriter(object):
|
|
|
500
500
|
internedTables = {}
|
|
501
501
|
|
|
502
502
|
items = self.items
|
|
503
|
-
for i in
|
|
504
|
-
item = items[i]
|
|
503
|
+
for i, item in enumerate(items):
|
|
505
504
|
if hasattr(item, "getCountData"):
|
|
506
505
|
items[i] = item.getCountData()
|
|
507
506
|
elif hasattr(item, "subWriter"):
|
|
@@ -1130,8 +1129,7 @@ class BaseTable(object):
|
|
|
1130
1129
|
for conv in self.getConverters():
|
|
1131
1130
|
if conv.repeat:
|
|
1132
1131
|
value = getattr(self, conv.name, [])
|
|
1133
|
-
for i in
|
|
1134
|
-
item = value[i]
|
|
1132
|
+
for i, item in enumerate(value):
|
|
1135
1133
|
conv.xmlWrite(xmlWriter, font, item, conv.name, [("index", i)])
|
|
1136
1134
|
else:
|
|
1137
1135
|
if conv.aux and not eval(conv.aux, None, vars(self)):
|
|
@@ -990,8 +990,7 @@ class Coverage(FormatSwitchingBaseTable):
|
|
|
990
990
|
if brokenOrder or len(ranges) * 3 < len(glyphs): # 3 words vs. 1 word
|
|
991
991
|
# Format 2 is more compact
|
|
992
992
|
index = 0
|
|
993
|
-
for i in
|
|
994
|
-
start, end = ranges[i]
|
|
993
|
+
for i, (start, end) in enumerate(ranges):
|
|
995
994
|
r = RangeRecord()
|
|
996
995
|
r.StartID = start
|
|
997
996
|
r.Start = font.getGlyphName(start)
|
|
@@ -1404,8 +1403,7 @@ class ClassDef(FormatSwitchingBaseTable):
|
|
|
1404
1403
|
glyphCount = endGlyph - startGlyph + 1
|
|
1405
1404
|
if len(ranges) * 3 < glyphCount + 1:
|
|
1406
1405
|
# Format 2 is more compact
|
|
1407
|
-
for i in
|
|
1408
|
-
cls, start, startName, end, endName = ranges[i]
|
|
1406
|
+
for i, (cls, start, startName, end, endName) in enumerate(ranges):
|
|
1409
1407
|
rec = ClassRangeRecord()
|
|
1410
1408
|
rec.Start = startName
|
|
1411
1409
|
rec.End = endName
|
|
@@ -1463,8 +1461,7 @@ class AlternateSubst(FormatSwitchingBaseTable):
|
|
|
1463
1461
|
if alternates is None:
|
|
1464
1462
|
alternates = self.alternates = {}
|
|
1465
1463
|
items = list(alternates.items())
|
|
1466
|
-
for i in
|
|
1467
|
-
glyphName, set = items[i]
|
|
1464
|
+
for i, (glyphName, set) in enumerate(items):
|
|
1468
1465
|
items[i] = font.getGlyphID(glyphName), glyphName, set
|
|
1469
1466
|
items.sort()
|
|
1470
1467
|
cov = Coverage()
|
|
@@ -1520,8 +1517,8 @@ class LigatureSubst(FormatSwitchingBaseTable):
|
|
|
1520
1517
|
input = _getGlyphsFromCoverageTable(rawTable["Coverage"])
|
|
1521
1518
|
ligSets = rawTable["LigatureSet"]
|
|
1522
1519
|
assert len(input) == len(ligSets)
|
|
1523
|
-
for i in
|
|
1524
|
-
ligatures[
|
|
1520
|
+
for i, inp in enumerate(input):
|
|
1521
|
+
ligatures[inp] = ligSets[i].Ligature
|
|
1525
1522
|
else:
|
|
1526
1523
|
assert 0, "unknown format: %s" % self.Format
|
|
1527
1524
|
self.ligatures = ligatures
|
|
@@ -1577,8 +1574,7 @@ class LigatureSubst(FormatSwitchingBaseTable):
|
|
|
1577
1574
|
ligatures = newLigatures
|
|
1578
1575
|
|
|
1579
1576
|
items = list(ligatures.items())
|
|
1580
|
-
for i in
|
|
1581
|
-
glyphName, set = items[i]
|
|
1577
|
+
for i, (glyphName, set) in enumerate(items):
|
|
1582
1578
|
items[i] = font.getGlyphID(glyphName), glyphName, set
|
|
1583
1579
|
items.sort()
|
|
1584
1580
|
cov = Coverage()
|
|
@@ -2279,8 +2275,7 @@ def fixLookupOverFlows(ttf, overflowRecord):
|
|
|
2279
2275
|
lookup = lookups[lookupIndex]
|
|
2280
2276
|
if lookup.LookupType != extType:
|
|
2281
2277
|
lookup.LookupType = extType
|
|
2282
|
-
for si in
|
|
2283
|
-
subTable = lookup.SubTable[si]
|
|
2278
|
+
for si, subTable in enumerate(lookup.SubTable):
|
|
2284
2279
|
extSubTableClass = lookupTypes[overflowRecord.tableType][extType]
|
|
2285
2280
|
extSubTable = extSubTableClass()
|
|
2286
2281
|
extSubTable.Format = 1
|
|
@@ -128,9 +128,9 @@ class Strike(object):
|
|
|
128
128
|
xmlWriter.simpletag("resolution", value=self.resolution)
|
|
129
129
|
xmlWriter.newline()
|
|
130
130
|
glyphOrder = ttFont.getGlyphOrder()
|
|
131
|
-
for
|
|
132
|
-
if
|
|
133
|
-
self.glyphs[
|
|
131
|
+
for glyphName in glyphOrder:
|
|
132
|
+
if glyphName in self.glyphs:
|
|
133
|
+
self.glyphs[glyphName].toXML(xmlWriter, ttFont)
|
|
134
134
|
# TODO: what if there are more glyph data records than (glyf table) glyphs?
|
|
135
135
|
xmlWriter.endtag("strike")
|
|
136
136
|
xmlWriter.newline()
|
fontTools/ttLib/ttFont.py
CHANGED
|
@@ -259,9 +259,8 @@ class TTFont(object):
|
|
|
259
259
|
"head"
|
|
260
260
|
] # make sure 'head' is loaded so the recalculation is actually done
|
|
261
261
|
|
|
262
|
-
tags =
|
|
263
|
-
|
|
264
|
-
tags.remove("GlyphOrder")
|
|
262
|
+
tags = self.keys()
|
|
263
|
+
tags.pop(0) # skip GlyphOrder tag
|
|
265
264
|
numTables = len(tags)
|
|
266
265
|
# write to a temporary stream to allow saving to unseekable streams
|
|
267
266
|
writer = SFNTWriter(
|
|
@@ -307,14 +306,9 @@ class TTFont(object):
|
|
|
307
306
|
self.disassembleInstructions = disassembleInstructions
|
|
308
307
|
self.bitmapGlyphDataFormat = bitmapGlyphDataFormat
|
|
309
308
|
if not tables:
|
|
310
|
-
tables =
|
|
311
|
-
if "GlyphOrder" not in tables:
|
|
312
|
-
tables = ["GlyphOrder"] + tables
|
|
309
|
+
tables = self.keys()
|
|
313
310
|
if skipTables:
|
|
314
|
-
for tag in skipTables
|
|
315
|
-
if tag in tables:
|
|
316
|
-
tables.remove(tag)
|
|
317
|
-
numTables = len(tables)
|
|
311
|
+
tables = [tag for tag in tables if tag not in skipTables]
|
|
318
312
|
|
|
319
313
|
if writeVersion:
|
|
320
314
|
from fontTools import version
|
|
@@ -337,8 +331,7 @@ class TTFont(object):
|
|
|
337
331
|
else:
|
|
338
332
|
path, ext = os.path.splitext(writer.filename)
|
|
339
333
|
|
|
340
|
-
for
|
|
341
|
-
tag = tables[i]
|
|
334
|
+
for tag in tables:
|
|
342
335
|
if splitTables:
|
|
343
336
|
tablePath = path + "." + tagToIdentifier(tag) + ext
|
|
344
337
|
tableWriter = xmlWriter.XMLWriter(
|
|
@@ -608,8 +601,7 @@ class TTFont(object):
|
|
|
608
601
|
else:
|
|
609
602
|
reversecmap = {}
|
|
610
603
|
useCount = {}
|
|
611
|
-
for i in
|
|
612
|
-
tempName = glyphOrder[i]
|
|
604
|
+
for i, tempName in enumerate(glyphOrder):
|
|
613
605
|
if tempName in reversecmap:
|
|
614
606
|
# If a font maps both U+0041 LATIN CAPITAL LETTER A and
|
|
615
607
|
# U+0391 GREEK CAPITAL LETTER ALPHA to the same glyph,
|
|
@@ -866,8 +858,7 @@ class GlyphOrder(object):
|
|
|
866
858
|
"The 'id' attribute is only for humans; " "it is ignored when parsed."
|
|
867
859
|
)
|
|
868
860
|
writer.newline()
|
|
869
|
-
for i in
|
|
870
|
-
glyphName = glyphOrder[i]
|
|
861
|
+
for i, glyphName in enumerate(glyphOrder):
|
|
871
862
|
writer.simpletag("GlyphID", id=i, name=glyphName)
|
|
872
863
|
writer.newline()
|
|
873
864
|
|
fontTools/ttLib/woff2.py
CHANGED
|
@@ -394,10 +394,9 @@ class WOFF2Writer(SFNTWriter):
|
|
|
394
394
|
|
|
395
395
|
def _calcMasterChecksum(self):
|
|
396
396
|
"""Calculate checkSumAdjustment."""
|
|
397
|
-
tags = list(self.tables.keys())
|
|
398
397
|
checksums = []
|
|
399
|
-
for
|
|
400
|
-
checksums.append(self.tables[
|
|
398
|
+
for tag in self.tables.keys():
|
|
399
|
+
checksums.append(self.tables[tag].checkSum)
|
|
401
400
|
|
|
402
401
|
# Create a SFNT directory for checksum calculation purposes
|
|
403
402
|
self.searchRange, self.entrySelector, self.rangeShift = getSearchRange(
|
|
@@ -642,10 +641,10 @@ woff2OverlapSimpleBitmapFlag = 0x0001
|
|
|
642
641
|
|
|
643
642
|
def getKnownTagIndex(tag):
|
|
644
643
|
"""Return index of 'tag' in woff2KnownTags list. Return 63 if not found."""
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
644
|
+
try:
|
|
645
|
+
return woff2KnownTags.index(tag)
|
|
646
|
+
except ValueError:
|
|
647
|
+
return woff2UnknownTagIndex
|
|
649
648
|
|
|
650
649
|
|
|
651
650
|
class WOFF2DirectoryEntry(DirectoryEntry):
|
|
@@ -747,8 +746,8 @@ class WOFF2LocaTable(getTableClass("loca")):
|
|
|
747
746
|
"indexFormat is 0 but local offsets not multiples of 2"
|
|
748
747
|
)
|
|
749
748
|
locations = array.array("H")
|
|
750
|
-
for
|
|
751
|
-
locations.append(
|
|
749
|
+
for location in self.locations:
|
|
750
|
+
locations.append(location // 2)
|
|
752
751
|
else:
|
|
753
752
|
locations = array.array("I", self.locations)
|
|
754
753
|
if sys.byteorder != "big":
|
|
@@ -1026,11 +1025,10 @@ class WOFF2GlyfTable(getTableClass("glyf")):
|
|
|
1026
1025
|
lastcomponent = len(glyph.components) - 1
|
|
1027
1026
|
more = 1
|
|
1028
1027
|
haveInstructions = 0
|
|
1029
|
-
for i in
|
|
1028
|
+
for i, component in enumerate(glyph.components):
|
|
1030
1029
|
if i == lastcomponent:
|
|
1031
1030
|
haveInstructions = hasattr(glyph, "program")
|
|
1032
1031
|
more = 0
|
|
1033
|
-
component = glyph.components[i]
|
|
1034
1032
|
self.compositeStream += component.compile(more, haveInstructions, self)
|
|
1035
1033
|
if haveInstructions:
|
|
1036
1034
|
self._encodeInstructions(glyph)
|
|
@@ -1078,9 +1076,8 @@ class WOFF2GlyfTable(getTableClass("glyf")):
|
|
|
1078
1076
|
|
|
1079
1077
|
flags = array.array("B")
|
|
1080
1078
|
triplets = array.array("B")
|
|
1081
|
-
for i in
|
|
1079
|
+
for i, (x, y) in enumerate(coordinates):
|
|
1082
1080
|
onCurve = glyph.flags[i] & _g_l_y_f.flagOnCurve
|
|
1083
|
-
x, y = coordinates[i]
|
|
1084
1081
|
absX = abs(x)
|
|
1085
1082
|
absY = abs(y)
|
|
1086
1083
|
onCurveBit = 0 if onCurve else 128
|