fonttools 4.58.5__cp311-cp311-macosx_10_9_universal2.whl → 4.59.1__cp311-cp311-macosx_10_9_universal2.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.c +21 -6
- fontTools/cu2qu/cu2qu.cpython-311-darwin.so +0 -0
- fontTools/feaLib/builder.py +6 -1
- fontTools/feaLib/lexer.c +21 -6
- fontTools/feaLib/lexer.cpython-311-darwin.so +0 -0
- fontTools/merge/__init__.py +1 -1
- fontTools/misc/bezierTools.c +24 -9
- fontTools/misc/bezierTools.cpython-311-darwin.so +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.c +11 -4
- fontTools/pens/momentsPen.cpython-311-darwin.so +0 -0
- fontTools/pens/roundingPen.py +2 -2
- fontTools/qu2cu/qu2cu.c +23 -8
- fontTools/qu2cu/qu2cu.cpython-311-darwin.so +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.c +23 -8
- fontTools/varLib/iup.cpython-311-darwin.so +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 +67 -55
- {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
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
from collections import deque
|
|
5
|
+
from collections.abc import Collection, Iterator
|
|
6
|
+
|
|
7
|
+
from ._path import combine
|
|
8
|
+
|
|
9
|
+
if typing.TYPE_CHECKING:
|
|
10
|
+
from typing import Callable
|
|
11
|
+
|
|
12
|
+
from ._base import FS
|
|
13
|
+
from ._info import Info
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BoundWalker:
|
|
17
|
+
def __init__(self, fs: FS):
|
|
18
|
+
self._fs = fs
|
|
19
|
+
|
|
20
|
+
def _iter_walk(
|
|
21
|
+
self, path: str, namespaces: Collection[str] | None = None
|
|
22
|
+
) -> Iterator[tuple[str, Info | None]]:
|
|
23
|
+
"""Walk files using a *breadth first* search."""
|
|
24
|
+
queue = deque([path])
|
|
25
|
+
push = queue.appendleft
|
|
26
|
+
pop = queue.pop
|
|
27
|
+
_scan = self._fs.scandir
|
|
28
|
+
_combine = combine
|
|
29
|
+
|
|
30
|
+
while queue:
|
|
31
|
+
dir_path = pop()
|
|
32
|
+
for info in _scan(dir_path, namespaces=namespaces):
|
|
33
|
+
if info.is_dir:
|
|
34
|
+
yield dir_path, info
|
|
35
|
+
push(_combine(dir_path, info.name))
|
|
36
|
+
else:
|
|
37
|
+
yield dir_path, info
|
|
38
|
+
yield path, None
|
|
39
|
+
|
|
40
|
+
def _filter(
|
|
41
|
+
self,
|
|
42
|
+
include: Callable[[str, Info], bool] = lambda path, info: True,
|
|
43
|
+
path: str = "/",
|
|
44
|
+
namespaces: Collection[str] | None = None,
|
|
45
|
+
) -> Iterator[str]:
|
|
46
|
+
_combine = combine
|
|
47
|
+
for path, info in self._iter_walk(path, namespaces):
|
|
48
|
+
if info is not None and include(path, info):
|
|
49
|
+
yield _combine(path, info.name)
|
|
50
|
+
|
|
51
|
+
def files(self, path: str = "/") -> Iterator[str]:
|
|
52
|
+
yield from self._filter(lambda _, info: info.is_file, path)
|
|
53
|
+
|
|
54
|
+
def dirs(self, path: str = "/") -> Iterator[str]:
|
|
55
|
+
yield from self._filter(lambda _, info: info.is_dir, path)
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import io
|
|
4
|
+
import os
|
|
5
|
+
import shutil
|
|
6
|
+
import stat
|
|
7
|
+
import typing
|
|
8
|
+
import zipfile
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
|
|
11
|
+
from ._base import FS
|
|
12
|
+
from ._errors import FileExpected, ResourceNotFound, ResourceReadOnly
|
|
13
|
+
from ._info import Info
|
|
14
|
+
from ._path import dirname, forcedir, normpath, relpath
|
|
15
|
+
from ._tempfs import TempFS
|
|
16
|
+
|
|
17
|
+
if typing.TYPE_CHECKING:
|
|
18
|
+
from collections.abc import Collection
|
|
19
|
+
from typing import IO, Any
|
|
20
|
+
|
|
21
|
+
from ._subfs import SubFS
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ZipFS(FS):
|
|
25
|
+
"""Read and write zip files."""
|
|
26
|
+
|
|
27
|
+
def __new__(
|
|
28
|
+
cls, file: str | os.PathLike, write: bool = False, encoding: str = "utf-8"
|
|
29
|
+
):
|
|
30
|
+
if write:
|
|
31
|
+
return WriteZipFS(file, encoding)
|
|
32
|
+
else:
|
|
33
|
+
return ReadZipFS(file, encoding)
|
|
34
|
+
|
|
35
|
+
if typing.TYPE_CHECKING:
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self, file: str | os.PathLike, write: bool = False, encoding: str = "utf-8"
|
|
39
|
+
):
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ReadZipFS(FS):
|
|
44
|
+
"""A readable zip file."""
|
|
45
|
+
|
|
46
|
+
def __init__(self, file: str | os.PathLike, encoding: str = "utf-8"):
|
|
47
|
+
super().__init__()
|
|
48
|
+
self._file = os.fspath(file)
|
|
49
|
+
self.encoding = encoding # unused
|
|
50
|
+
self._zip = zipfile.ZipFile(file, "r")
|
|
51
|
+
self._directory_fs = None
|
|
52
|
+
|
|
53
|
+
def __repr__(self) -> str:
|
|
54
|
+
return f"ReadZipFS({self._file!r})"
|
|
55
|
+
|
|
56
|
+
def __str__(self) -> str:
|
|
57
|
+
return f"<zipfs '{self._file}'>"
|
|
58
|
+
|
|
59
|
+
def _path_to_zip_name(self, path: str) -> str:
|
|
60
|
+
"""Convert a path to a zip file name."""
|
|
61
|
+
path = relpath(normpath(path))
|
|
62
|
+
if self._directory.isdir(path):
|
|
63
|
+
path = forcedir(path)
|
|
64
|
+
return path
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def _directory(self) -> TempFS:
|
|
68
|
+
if self._directory_fs is None:
|
|
69
|
+
self._directory_fs = _fs = TempFS()
|
|
70
|
+
for zip_name in self._zip.namelist():
|
|
71
|
+
resource_name = zip_name
|
|
72
|
+
if resource_name.endswith("/"):
|
|
73
|
+
_fs.makedirs(resource_name, recreate=True)
|
|
74
|
+
else:
|
|
75
|
+
_fs.makedirs(dirname(resource_name), recreate=True)
|
|
76
|
+
_fs.create(resource_name)
|
|
77
|
+
return self._directory_fs
|
|
78
|
+
|
|
79
|
+
def close(self):
|
|
80
|
+
super(ReadZipFS, self).close()
|
|
81
|
+
self._zip.close()
|
|
82
|
+
if self._directory_fs is not None:
|
|
83
|
+
self._directory_fs.close()
|
|
84
|
+
|
|
85
|
+
def getinfo(self, path: str, namespaces: Collection[str] | None = None) -> Info:
|
|
86
|
+
namespaces = namespaces or ()
|
|
87
|
+
raw_info = {}
|
|
88
|
+
|
|
89
|
+
if path == "/":
|
|
90
|
+
raw_info["basic"] = {"name": "", "is_dir": True}
|
|
91
|
+
if "details" in namespaces:
|
|
92
|
+
raw_info["details"] = {"type": stat.S_IFDIR}
|
|
93
|
+
else:
|
|
94
|
+
basic_info = self._directory.getinfo(path)
|
|
95
|
+
raw_info["basic"] = {"name": basic_info.name, "is_dir": basic_info.is_dir}
|
|
96
|
+
|
|
97
|
+
if "details" in namespaces:
|
|
98
|
+
zip_name = self._path_to_zip_name(path)
|
|
99
|
+
try:
|
|
100
|
+
zip_info = self._zip.getinfo(zip_name)
|
|
101
|
+
except KeyError:
|
|
102
|
+
pass
|
|
103
|
+
else:
|
|
104
|
+
if "details" in namespaces:
|
|
105
|
+
raw_info["details"] = {
|
|
106
|
+
"size": zip_info.file_size,
|
|
107
|
+
"type": int(
|
|
108
|
+
stat.S_IFDIR if basic_info.is_dir else stat.S_IFREG
|
|
109
|
+
),
|
|
110
|
+
"modified": datetime(*zip_info.date_time).timestamp(),
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return Info(raw_info)
|
|
114
|
+
|
|
115
|
+
def exists(self, path: str) -> bool:
|
|
116
|
+
self.check()
|
|
117
|
+
return self._directory.exists(path)
|
|
118
|
+
|
|
119
|
+
def isdir(self, path: str) -> bool:
|
|
120
|
+
self.check()
|
|
121
|
+
return self._directory.isdir(path)
|
|
122
|
+
|
|
123
|
+
def isfile(self, path: str) -> bool:
|
|
124
|
+
self.check()
|
|
125
|
+
return self._directory.isfile(path)
|
|
126
|
+
|
|
127
|
+
def listdir(self, path: str) -> str:
|
|
128
|
+
self.check()
|
|
129
|
+
return self._directory.listdir(path)
|
|
130
|
+
|
|
131
|
+
def makedir(self, path: str, recreate: bool = False) -> SubFS:
|
|
132
|
+
self.check()
|
|
133
|
+
raise ResourceReadOnly(path)
|
|
134
|
+
|
|
135
|
+
def makedirs(self, path: str, recreate: bool = False) -> SubFS:
|
|
136
|
+
self.check()
|
|
137
|
+
raise ResourceReadOnly(path)
|
|
138
|
+
|
|
139
|
+
def remove(self, path: str):
|
|
140
|
+
self.check()
|
|
141
|
+
raise ResourceReadOnly(path)
|
|
142
|
+
|
|
143
|
+
def removedir(self, path: str):
|
|
144
|
+
self.check()
|
|
145
|
+
raise ResourceReadOnly(path)
|
|
146
|
+
|
|
147
|
+
def removetree(self, path: str):
|
|
148
|
+
self.check()
|
|
149
|
+
raise ResourceReadOnly(path)
|
|
150
|
+
|
|
151
|
+
def movedir(self, src: str, dst: str, create: bool = False):
|
|
152
|
+
self.check()
|
|
153
|
+
raise ResourceReadOnly(src)
|
|
154
|
+
|
|
155
|
+
def readbytes(self, path: str) -> bytes:
|
|
156
|
+
self.check()
|
|
157
|
+
if not self._directory.isfile(path):
|
|
158
|
+
raise ResourceNotFound(path)
|
|
159
|
+
zip_name = self._path_to_zip_name(path)
|
|
160
|
+
zip_bytes = self._zip.read(zip_name)
|
|
161
|
+
return zip_bytes
|
|
162
|
+
|
|
163
|
+
def open(self, path: str, mode: str = "rb", **kwargs) -> IO[Any]:
|
|
164
|
+
self.check()
|
|
165
|
+
if self._directory.isdir(path):
|
|
166
|
+
raise FileExpected(f"{path!r} is a directory")
|
|
167
|
+
|
|
168
|
+
zip_mode = mode[0]
|
|
169
|
+
if zip_mode == "r" and not self._directory.exists(path):
|
|
170
|
+
raise ResourceNotFound(f"No such file or directory: {path!r}")
|
|
171
|
+
|
|
172
|
+
if any(m in mode for m in "wax+"):
|
|
173
|
+
raise ResourceReadOnly(path)
|
|
174
|
+
|
|
175
|
+
zip_name = self._path_to_zip_name(path)
|
|
176
|
+
stream = self._zip.open(zip_name, zip_mode)
|
|
177
|
+
if "b" in mode:
|
|
178
|
+
if kwargs:
|
|
179
|
+
raise ValueError("encoding args invalid for binary operation")
|
|
180
|
+
return stream
|
|
181
|
+
# Text mode
|
|
182
|
+
return io.TextIOWrapper(stream, **kwargs)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class WriteZipFS(TempFS):
|
|
186
|
+
"""A writable zip file."""
|
|
187
|
+
|
|
188
|
+
def __init__(self, file: str | os.PathLike, encoding: str = "utf-8"):
|
|
189
|
+
super().__init__()
|
|
190
|
+
self._file = os.fspath(file)
|
|
191
|
+
self.encoding = encoding # unused
|
|
192
|
+
|
|
193
|
+
def __repr__(self) -> str:
|
|
194
|
+
return f"WriteZipFS({self._file!r})"
|
|
195
|
+
|
|
196
|
+
def __str__(self) -> str:
|
|
197
|
+
return f"<zipfs-write '{self._file}'>"
|
|
198
|
+
|
|
199
|
+
def close(self):
|
|
200
|
+
base_name = os.path.splitext(self._file)[0]
|
|
201
|
+
shutil.make_archive(base_name, format="zip", root_dir=self._temp_dir)
|
|
202
|
+
if self._file != base_name + ".zip":
|
|
203
|
+
shutil.move(base_name + ".zip", self._file)
|
|
204
|
+
super().close()
|
fontTools/misc/psCharStrings.py
CHANGED
|
@@ -338,7 +338,7 @@ class SimpleT2Decompiler(object):
|
|
|
338
338
|
self.numRegions = 0
|
|
339
339
|
self.vsIndex = 0
|
|
340
340
|
|
|
341
|
-
def execute(self, charString):
|
|
341
|
+
def execute(self, charString, *, pushToStack=None):
|
|
342
342
|
self.callingStack.append(charString)
|
|
343
343
|
needsDecompilation = charString.needsDecompilation()
|
|
344
344
|
if needsDecompilation:
|
|
@@ -346,7 +346,8 @@ class SimpleT2Decompiler(object):
|
|
|
346
346
|
pushToProgram = program.append
|
|
347
347
|
else:
|
|
348
348
|
pushToProgram = lambda x: None
|
|
349
|
-
pushToStack
|
|
349
|
+
if pushToStack is None:
|
|
350
|
+
pushToStack = self.operandStack.append
|
|
350
351
|
index = 0
|
|
351
352
|
while True:
|
|
352
353
|
token, isOperator, index = charString.getToken(index)
|
|
@@ -551,6 +552,20 @@ t1Operators = [
|
|
|
551
552
|
]
|
|
552
553
|
|
|
553
554
|
|
|
555
|
+
class T2StackUseExtractor(SimpleT2Decompiler):
|
|
556
|
+
|
|
557
|
+
def execute(self, charString):
|
|
558
|
+
maxStackUse = 0
|
|
559
|
+
|
|
560
|
+
def pushToStack(value):
|
|
561
|
+
nonlocal maxStackUse
|
|
562
|
+
self.operandStack.append(value)
|
|
563
|
+
maxStackUse = max(maxStackUse, len(self.operandStack))
|
|
564
|
+
|
|
565
|
+
super().execute(charString, pushToStack=pushToStack)
|
|
566
|
+
return maxStackUse
|
|
567
|
+
|
|
568
|
+
|
|
554
569
|
class T2WidthExtractor(SimpleT2Decompiler):
|
|
555
570
|
def __init__(
|
|
556
571
|
self,
|
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):
|
fontTools/pens/momentsPen.c
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Generated by Cython 3.1.
|
|
1
|
+
/* Generated by Cython 3.1.3 */
|
|
2
2
|
|
|
3
3
|
/* BEGIN: Cython Metadata
|
|
4
4
|
{
|
|
@@ -26,8 +26,8 @@ END: Cython Metadata */
|
|
|
26
26
|
#elif PY_VERSION_HEX < 0x03080000
|
|
27
27
|
#error Cython requires Python 3.8+.
|
|
28
28
|
#else
|
|
29
|
-
#define __PYX_ABI_VERSION "
|
|
30
|
-
#define CYTHON_HEX_VERSION
|
|
29
|
+
#define __PYX_ABI_VERSION "3_1_3"
|
|
30
|
+
#define CYTHON_HEX_VERSION 0x030103F0
|
|
31
31
|
#define CYTHON_FUTURE_DIVISION 1
|
|
32
32
|
/* CModulePreamble */
|
|
33
33
|
#include <stddef.h>
|
|
@@ -390,6 +390,9 @@ END: Cython Metadata */
|
|
|
390
390
|
enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) };
|
|
391
391
|
#endif
|
|
392
392
|
#endif
|
|
393
|
+
#ifndef CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME
|
|
394
|
+
#define CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME 100
|
|
395
|
+
#endif
|
|
393
396
|
#ifndef __has_attribute
|
|
394
397
|
#define __has_attribute(x) 0
|
|
395
398
|
#endif
|
|
@@ -10172,6 +10175,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
10172
10175
|
changed = 1;
|
|
10173
10176
|
}
|
|
10174
10177
|
#endif // CYTHON_METH_FASTCALL
|
|
10178
|
+
#if !CYTHON_COMPILING_IN_PYPY
|
|
10175
10179
|
else if (strcmp(memb->name, "__module__") == 0) {
|
|
10176
10180
|
PyObject *descr;
|
|
10177
10181
|
assert(memb->type == T_OBJECT);
|
|
@@ -10186,11 +10190,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
10186
10190
|
}
|
|
10187
10191
|
changed = 1;
|
|
10188
10192
|
}
|
|
10193
|
+
#endif // !CYTHON_COMPILING_IN_PYPY
|
|
10189
10194
|
}
|
|
10190
10195
|
memb++;
|
|
10191
10196
|
}
|
|
10192
10197
|
}
|
|
10193
10198
|
#endif // !CYTHON_COMPILING_IN_LIMITED_API
|
|
10199
|
+
#if !CYTHON_COMPILING_IN_PYPY
|
|
10194
10200
|
slot = spec->slots;
|
|
10195
10201
|
while (slot && slot->slot && slot->slot != Py_tp_getset)
|
|
10196
10202
|
slot++;
|
|
@@ -10222,6 +10228,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
10222
10228
|
++getset;
|
|
10223
10229
|
}
|
|
10224
10230
|
}
|
|
10231
|
+
#endif // !CYTHON_COMPILING_IN_PYPY
|
|
10225
10232
|
if (changed)
|
|
10226
10233
|
PyType_Modified(type);
|
|
10227
10234
|
#endif // PY_VERSION_HEX > 0x030900B1
|
|
@@ -10354,7 +10361,7 @@ bad:
|
|
|
10354
10361
|
}
|
|
10355
10362
|
|
|
10356
10363
|
/* CommonTypesMetaclass */
|
|
10357
|
-
PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
|
|
10364
|
+
static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
|
|
10358
10365
|
return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
|
|
10359
10366
|
}
|
|
10360
10367
|
static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {
|
|
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),
|
fontTools/qu2cu/qu2cu.c
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Generated by Cython 3.1.
|
|
1
|
+
/* Generated by Cython 3.1.3 */
|
|
2
2
|
|
|
3
3
|
/* BEGIN: Cython Metadata
|
|
4
4
|
{
|
|
@@ -32,8 +32,8 @@ END: Cython Metadata */
|
|
|
32
32
|
#elif PY_VERSION_HEX < 0x03080000
|
|
33
33
|
#error Cython requires Python 3.8+.
|
|
34
34
|
#else
|
|
35
|
-
#define __PYX_ABI_VERSION "
|
|
36
|
-
#define CYTHON_HEX_VERSION
|
|
35
|
+
#define __PYX_ABI_VERSION "3_1_3"
|
|
36
|
+
#define CYTHON_HEX_VERSION 0x030103F0
|
|
37
37
|
#define CYTHON_FUTURE_DIVISION 1
|
|
38
38
|
/* CModulePreamble */
|
|
39
39
|
#include <stddef.h>
|
|
@@ -396,6 +396,9 @@ END: Cython Metadata */
|
|
|
396
396
|
enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) };
|
|
397
397
|
#endif
|
|
398
398
|
#endif
|
|
399
|
+
#ifndef CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME
|
|
400
|
+
#define CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME 100
|
|
401
|
+
#endif
|
|
399
402
|
#ifndef __has_attribute
|
|
400
403
|
#define __has_attribute(x) 0
|
|
401
404
|
#endif
|
|
@@ -1963,7 +1966,7 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
|
|
|
1963
1966
|
static PyObject *__Pyx_PyLong_AbsNeg(PyObject *num);
|
|
1964
1967
|
#define __Pyx_PyNumber_Absolute(x)\
|
|
1965
1968
|
((likely(PyLong_CheckExact(x))) ?\
|
|
1966
|
-
(likely(__Pyx_PyLong_IsNonNeg(x)) ? (
|
|
1969
|
+
(likely(__Pyx_PyLong_IsNonNeg(x)) ? __Pyx_NewRef(x) : __Pyx_PyLong_AbsNeg(x)) :\
|
|
1967
1970
|
PyNumber_Absolute(x))
|
|
1968
1971
|
#else
|
|
1969
1972
|
#define __Pyx_PyNumber_Absolute(x) PyNumber_Absolute(x)
|
|
@@ -10557,7 +10560,7 @@ static PyObject *__Pyx_PyLong_AbsNeg(PyObject *n) {
|
|
|
10557
10560
|
PyObject *copy = _PyLong_Copy((PyLongObject*)n);
|
|
10558
10561
|
if (likely(copy)) {
|
|
10559
10562
|
#if PY_VERSION_HEX >= 0x030C00A7
|
|
10560
|
-
((PyLongObject*)copy)->long_value.lv_tag
|
|
10563
|
+
((PyLongObject*)copy)->long_value.lv_tag ^= ((PyLongObject*)copy)->long_value.lv_tag & _PyLong_SIGN_MASK;
|
|
10561
10564
|
#else
|
|
10562
10565
|
__Pyx_SET_SIZE(copy, -Py_SIZE(copy));
|
|
10563
10566
|
#endif
|
|
@@ -11193,6 +11196,13 @@ try_unpack:
|
|
|
11193
11196
|
|
|
11194
11197
|
/* PyObjectCallMethod0 */
|
|
11195
11198
|
static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) {
|
|
11199
|
+
#if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
|
|
11200
|
+
PyObject *args[1] = {obj};
|
|
11201
|
+
(void) __Pyx_PyObject_GetMethod;
|
|
11202
|
+
(void) __Pyx_PyObject_CallOneArg;
|
|
11203
|
+
(void) __Pyx_PyObject_CallNoArg;
|
|
11204
|
+
return PyObject_VectorcallMethod(method_name, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
|
|
11205
|
+
#else
|
|
11196
11206
|
PyObject *method = NULL, *result = NULL;
|
|
11197
11207
|
int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method);
|
|
11198
11208
|
if (likely(is_method)) {
|
|
@@ -11205,6 +11215,7 @@ static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name
|
|
|
11205
11215
|
Py_DECREF(method);
|
|
11206
11216
|
bad:
|
|
11207
11217
|
return result;
|
|
11218
|
+
#endif
|
|
11208
11219
|
}
|
|
11209
11220
|
|
|
11210
11221
|
/* CallUnboundCMethod0 */
|
|
@@ -11742,6 +11753,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
11742
11753
|
changed = 1;
|
|
11743
11754
|
}
|
|
11744
11755
|
#endif // CYTHON_METH_FASTCALL
|
|
11756
|
+
#if !CYTHON_COMPILING_IN_PYPY
|
|
11745
11757
|
else if (strcmp(memb->name, "__module__") == 0) {
|
|
11746
11758
|
PyObject *descr;
|
|
11747
11759
|
assert(memb->type == T_OBJECT);
|
|
@@ -11756,11 +11768,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
11756
11768
|
}
|
|
11757
11769
|
changed = 1;
|
|
11758
11770
|
}
|
|
11771
|
+
#endif // !CYTHON_COMPILING_IN_PYPY
|
|
11759
11772
|
}
|
|
11760
11773
|
memb++;
|
|
11761
11774
|
}
|
|
11762
11775
|
}
|
|
11763
11776
|
#endif // !CYTHON_COMPILING_IN_LIMITED_API
|
|
11777
|
+
#if !CYTHON_COMPILING_IN_PYPY
|
|
11764
11778
|
slot = spec->slots;
|
|
11765
11779
|
while (slot && slot->slot && slot->slot != Py_tp_getset)
|
|
11766
11780
|
slot++;
|
|
@@ -11792,6 +11806,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
11792
11806
|
++getset;
|
|
11793
11807
|
}
|
|
11794
11808
|
}
|
|
11809
|
+
#endif // !CYTHON_COMPILING_IN_PYPY
|
|
11795
11810
|
if (changed)
|
|
11796
11811
|
PyType_Modified(type);
|
|
11797
11812
|
#endif // PY_VERSION_HEX > 0x030900B1
|
|
@@ -12227,7 +12242,7 @@ bad:
|
|
|
12227
12242
|
}
|
|
12228
12243
|
|
|
12229
12244
|
/* CommonTypesMetaclass */
|
|
12230
|
-
PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
|
|
12245
|
+
static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
|
|
12231
12246
|
return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
|
|
12232
12247
|
}
|
|
12233
12248
|
static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {
|
|
@@ -14847,7 +14862,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyOb
|
|
|
14847
14862
|
}
|
|
14848
14863
|
|
|
14849
14864
|
/* PyObjectCallMethod1 */
|
|
14850
|
-
#if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000)
|
|
14865
|
+
#if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)))
|
|
14851
14866
|
static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
|
|
14852
14867
|
PyObject *result = __Pyx_PyObject_CallOneArg(method, arg);
|
|
14853
14868
|
Py_DECREF(method);
|
|
@@ -14855,7 +14870,7 @@ static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
|
|
|
14855
14870
|
}
|
|
14856
14871
|
#endif
|
|
14857
14872
|
static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
|
|
14858
|
-
#if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000
|
|
14873
|
+
#if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
|
|
14859
14874
|
PyObject *args[2] = {obj, arg};
|
|
14860
14875
|
(void) __Pyx_PyObject_GetMethod;
|
|
14861
14876
|
(void) __Pyx_PyObject_CallOneArg;
|
|
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")
|