fonttools 4.56.0__cp39-cp39-musllinux_1_2_x86_64.whl → 4.57.0__cp39-cp39-musllinux_1_2_x86_64.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.

Files changed (40) hide show
  1. fontTools/__init__.py +1 -1
  2. fontTools/config/__init__.py +15 -0
  3. fontTools/cu2qu/cu2qu.c +6 -6
  4. fontTools/cu2qu/cu2qu.cpython-39-x86_64-linux-gnu.so +0 -0
  5. fontTools/feaLib/ast.py +8 -3
  6. fontTools/feaLib/builder.py +32 -9
  7. fontTools/feaLib/lexer.c +5 -5
  8. fontTools/feaLib/lexer.cpython-39-x86_64-linux-gnu.so +0 -0
  9. fontTools/feaLib/parser.py +58 -0
  10. fontTools/misc/bezierTools.c +6 -6
  11. fontTools/misc/bezierTools.cpython-39-x86_64-linux-gnu.so +0 -0
  12. fontTools/misc/testTools.py +2 -1
  13. fontTools/otlLib/optimize/gpos.py +7 -1
  14. fontTools/pens/momentsPen.c +5 -5
  15. fontTools/pens/momentsPen.cpython-39-x86_64-linux-gnu.so +0 -0
  16. fontTools/qu2cu/qu2cu.c +6 -6
  17. fontTools/qu2cu/qu2cu.cpython-39-x86_64-linux-gnu.so +0 -0
  18. fontTools/ttLib/__init__.py +4 -0
  19. fontTools/ttLib/__main__.py +47 -8
  20. fontTools/ttLib/tables/D__e_b_g.py +20 -2
  21. fontTools/ttLib/tables/_c_m_a_p.py +19 -6
  22. fontTools/ttLib/tables/_g_l_y_f.py +9 -4
  23. fontTools/ttLib/tables/_g_v_a_r.py +4 -2
  24. fontTools/ttLib/tables/otConverters.py +5 -2
  25. fontTools/ttLib/tables/otTables.py +5 -1
  26. fontTools/ttLib/ttFont.py +3 -5
  27. fontTools/ttLib/ttGlyphSet.py +0 -10
  28. fontTools/ttx.py +13 -1
  29. fontTools/varLib/__init__.py +92 -89
  30. fontTools/varLib/hvar.py +113 -0
  31. fontTools/varLib/iup.c +6 -6
  32. fontTools/varLib/iup.cpython-39-x86_64-linux-gnu.so +0 -0
  33. fontTools/varLib/varStore.py +1 -1
  34. {fonttools-4.56.0.dist-info → fonttools-4.57.0.dist-info}/METADATA +16 -2
  35. {fonttools-4.56.0.dist-info → fonttools-4.57.0.dist-info}/RECORD +270 -269
  36. {fonttools-4.56.0.dist-info → fonttools-4.57.0.dist-info}/WHEEL +1 -1
  37. {fonttools-4.56.0.data → fonttools-4.57.0.data}/data/share/man/man1/ttx.1 +0 -0
  38. {fonttools-4.56.0.dist-info → fonttools-4.57.0.dist-info}/entry_points.txt +0 -0
  39. {fonttools-4.56.0.dist-info → fonttools-4.57.0.dist-info/licenses}/LICENSE +0 -0
  40. {fonttools-4.56.0.dist-info → fonttools-4.57.0.dist-info}/top_level.txt +0 -0
fontTools/__init__.py CHANGED
@@ -3,6 +3,6 @@ from fontTools.misc.loggingTools import configLogger
3
3
 
4
4
  log = logging.getLogger(__name__)
5
5
 
6
- version = __version__ = "4.56.0"
6
+ version = __version__ = "4.57.0"
7
7
 
8
8
  __all__ = ["version", "log", "configLogger"]
@@ -73,3 +73,18 @@ Config.register_option(
73
73
  parse=Option.parse_optional_bool,
74
74
  validate=Option.validate_optional_bool,
75
75
  )
76
+
77
+ Config.register_option(
78
+ name="fontTools.ttLib:OPTIMIZE_FONT_SPEED",
79
+ help=dedent(
80
+ """\
81
+ Enable optimizations that prioritize speed over file size. This
82
+ mainly affects how glyf table and gvar / VARC tables are compiled.
83
+ The produced fonts will be larger, but rendering performance will
84
+ be improved with HarfBuzz and other text layout engines.
85
+ """
86
+ ),
87
+ default=False,
88
+ parse=Option.parse_optional_bool,
89
+ validate=Option.validate_optional_bool,
90
+ )
fontTools/cu2qu/cu2qu.c CHANGED
@@ -1,4 +1,4 @@
1
- /* Generated by Cython 3.0.11 */
1
+ /* Generated by Cython 3.0.12 */
2
2
 
3
3
  /* BEGIN: Cython Metadata
4
4
  {
@@ -42,10 +42,10 @@ END: Cython Metadata */
42
42
  #else
43
43
  #define __PYX_EXTRA_ABI_MODULE_NAME ""
44
44
  #endif
45
- #define CYTHON_ABI "3_0_11" __PYX_EXTRA_ABI_MODULE_NAME
45
+ #define CYTHON_ABI "3_0_12" __PYX_EXTRA_ABI_MODULE_NAME
46
46
  #define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI
47
47
  #define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "."
48
- #define CYTHON_HEX_VERSION 0x03000BF0
48
+ #define CYTHON_HEX_VERSION 0x03000CF0
49
49
  #define CYTHON_FUTURE_DIVISION 1
50
50
  #include <stddef.h>
51
51
  #ifndef offsetof
@@ -1812,7 +1812,7 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
1812
1812
  #if !CYTHON_VECTORCALL
1813
1813
  #if PY_VERSION_HEX >= 0x03080000
1814
1814
  #include "frameobject.h"
1815
- #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API
1815
+ #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION)
1816
1816
  #ifndef Py_BUILD_CORE
1817
1817
  #define Py_BUILD_CORE 1
1818
1818
  #endif
@@ -12113,7 +12113,7 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
12113
12113
  #include "compile.h"
12114
12114
  #include "frameobject.h"
12115
12115
  #include "traceback.h"
12116
- #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API
12116
+ #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION)
12117
12117
  #ifndef Py_BUILD_CORE
12118
12118
  #define Py_BUILD_CORE 1
12119
12119
  #endif
@@ -13389,7 +13389,7 @@ static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name
13389
13389
 
13390
13390
  /* CoroutineBase */
13391
13391
  #include <frameobject.h>
13392
- #if PY_VERSION_HEX >= 0x030b00a6
13392
+ #if PY_VERSION_HEX >= 0x030b00a6 && !defined(PYPY_VERSION)
13393
13393
  #ifndef Py_BUILD_CORE
13394
13394
  #define Py_BUILD_CORE 1
13395
13395
  #endif
fontTools/feaLib/ast.py CHANGED
@@ -1828,15 +1828,16 @@ class BaseAxis(Statement):
1828
1828
  """An axis definition, being either a ``VertAxis.BaseTagList/BaseScriptList``
1829
1829
  pair or a ``HorizAxis.BaseTagList/BaseScriptList`` pair."""
1830
1830
 
1831
- def __init__(self, bases, scripts, vertical, location=None):
1831
+ def __init__(self, bases, scripts, vertical, minmax=None, location=None):
1832
1832
  Statement.__init__(self, location)
1833
1833
  self.bases = bases #: A list of baseline tag names as strings
1834
1834
  self.scripts = scripts #: A list of script record tuplets (script tag, default baseline tag, base coordinate)
1835
1835
  self.vertical = vertical #: Boolean; VertAxis if True, HorizAxis if False
1836
+ self.minmax = [] #: A set of minmax record
1836
1837
 
1837
1838
  def build(self, builder):
1838
1839
  """Calls the builder object's ``set_base_axis`` callback."""
1839
- builder.set_base_axis(self.bases, self.scripts, self.vertical)
1840
+ builder.set_base_axis(self.bases, self.scripts, self.vertical, self.minmax)
1840
1841
 
1841
1842
  def asFea(self, indent=""):
1842
1843
  direction = "Vert" if self.vertical else "Horiz"
@@ -1844,9 +1845,13 @@ class BaseAxis(Statement):
1844
1845
  "{} {} {}".format(a[0], a[1], " ".join(map(str, a[2])))
1845
1846
  for a in self.scripts
1846
1847
  ]
1848
+ minmaxes = [
1849
+ "\n{}Axis.MinMax {} {} {}, {};".format(direction, a[0], a[1], a[2], a[3])
1850
+ for a in self.minmax
1851
+ ]
1847
1852
  return "{}Axis.BaseTagList {};\n{}{}Axis.BaseScriptList {};".format(
1848
1853
  direction, " ".join(self.bases), indent, direction, ", ".join(scripts)
1849
- )
1854
+ ) + "\n".join(minmaxes)
1850
1855
 
1851
1856
 
1852
1857
  class OS2Field(Statement):
@@ -341,6 +341,7 @@ class Builder(object):
341
341
  table = self.font["head"] = newTable("head")
342
342
  table.decompile(b"\0" * 54, self.font)
343
343
  table.tableVersion = 1.0
344
+ table.magicNumber = 0x5F0F3CF5
344
345
  table.created = table.modified = 3406620153 # 2011-12-13 11:22:33
345
346
  table.fontRevision = self.fontRevision_
346
347
 
@@ -727,10 +728,16 @@ class Builder(object):
727
728
  result.table = base
728
729
  return result
729
730
 
731
+ def buildBASECoord(self, c):
732
+ coord = otTables.BaseCoord()
733
+ coord.Format = 1
734
+ coord.Coordinate = c
735
+ return coord
736
+
730
737
  def buildBASEAxis(self, axis):
731
738
  if not axis:
732
739
  return
733
- bases, scripts = axis
740
+ bases, scripts, minmax = axis
734
741
  axis = otTables.Axis()
735
742
  axis.BaseTagList = otTables.BaseTagList()
736
743
  axis.BaseTagList.BaselineTag = bases
@@ -739,19 +746,35 @@ class Builder(object):
739
746
  axis.BaseScriptList.BaseScriptRecord = []
740
747
  axis.BaseScriptList.BaseScriptCount = len(scripts)
741
748
  for script in sorted(scripts):
749
+ minmax_for_script = [
750
+ record[1:] for record in minmax if record[0] == script[0]
751
+ ]
742
752
  record = otTables.BaseScriptRecord()
743
753
  record.BaseScriptTag = script[0]
744
754
  record.BaseScript = otTables.BaseScript()
745
- record.BaseScript.BaseLangSysCount = 0
746
755
  record.BaseScript.BaseValues = otTables.BaseValues()
747
756
  record.BaseScript.BaseValues.DefaultIndex = bases.index(script[1])
748
757
  record.BaseScript.BaseValues.BaseCoord = []
749
758
  record.BaseScript.BaseValues.BaseCoordCount = len(script[2])
759
+ record.BaseScript.BaseLangSysRecord = []
760
+
750
761
  for c in script[2]:
751
- coord = otTables.BaseCoord()
752
- coord.Format = 1
753
- coord.Coordinate = c
754
- record.BaseScript.BaseValues.BaseCoord.append(coord)
762
+ record.BaseScript.BaseValues.BaseCoord.append(self.buildBASECoord(c))
763
+ for language, min_coord, max_coord in minmax_for_script:
764
+ minmax_record = otTables.MinMax()
765
+ minmax_record.MinCoord = self.buildBASECoord(min_coord)
766
+ minmax_record.MaxCoord = self.buildBASECoord(max_coord)
767
+ minmax_record.FeatMinMaxCount = 0
768
+ if language == "dflt":
769
+ record.BaseScript.DefaultMinMax = minmax_record
770
+ else:
771
+ lang_record = otTables.BaseLangSysRecord()
772
+ lang_record.BaseLangSysTag = language
773
+ lang_record.MinMax = minmax_record
774
+ record.BaseScript.BaseLangSysRecord.append(lang_record)
775
+ record.BaseScript.BaseLangSysCount = len(
776
+ record.BaseScript.BaseLangSysRecord
777
+ )
755
778
  axis.BaseScriptList.BaseScriptRecord.append(record)
756
779
  return axis
757
780
 
@@ -1235,11 +1258,11 @@ class Builder(object):
1235
1258
  def add_cv_character(self, character, tag):
1236
1259
  self.cv_characters_[tag].append(character)
1237
1260
 
1238
- def set_base_axis(self, bases, scripts, vertical):
1261
+ def set_base_axis(self, bases, scripts, vertical, minmax=[]):
1239
1262
  if vertical:
1240
- self.base_vert_axis_ = (bases, scripts)
1263
+ self.base_vert_axis_ = (bases, scripts, minmax)
1241
1264
  else:
1242
- self.base_horiz_axis_ = (bases, scripts)
1265
+ self.base_horiz_axis_ = (bases, scripts, minmax)
1243
1266
 
1244
1267
  def set_size_parameters(
1245
1268
  self, location, DesignSize, SubfamilyID, RangeStart, RangeEnd
fontTools/feaLib/lexer.c CHANGED
@@ -1,4 +1,4 @@
1
- /* Generated by Cython 3.0.11 */
1
+ /* Generated by Cython 3.0.12 */
2
2
 
3
3
  /* BEGIN: Cython Metadata
4
4
  {
@@ -36,10 +36,10 @@ END: Cython Metadata */
36
36
  #else
37
37
  #define __PYX_EXTRA_ABI_MODULE_NAME ""
38
38
  #endif
39
- #define CYTHON_ABI "3_0_11" __PYX_EXTRA_ABI_MODULE_NAME
39
+ #define CYTHON_ABI "3_0_12" __PYX_EXTRA_ABI_MODULE_NAME
40
40
  #define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI
41
41
  #define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "."
42
- #define CYTHON_HEX_VERSION 0x03000BF0
42
+ #define CYTHON_HEX_VERSION 0x03000CF0
43
43
  #define CYTHON_FUTURE_DIVISION 1
44
44
  #include <stddef.h>
45
45
  #ifndef offsetof
@@ -1786,7 +1786,7 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
1786
1786
  #if !CYTHON_VECTORCALL
1787
1787
  #if PY_VERSION_HEX >= 0x03080000
1788
1788
  #include "frameobject.h"
1789
- #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API
1789
+ #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION)
1790
1790
  #ifndef Py_BUILD_CORE
1791
1791
  #define Py_BUILD_CORE 1
1792
1792
  #endif
@@ -16796,7 +16796,7 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
16796
16796
  #include "compile.h"
16797
16797
  #include "frameobject.h"
16798
16798
  #include "traceback.h"
16799
- #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API
16799
+ #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION)
16800
16800
  #ifndef Py_BUILD_CORE
16801
16801
  #define Py_BUILD_CORE 1
16802
16802
  #endif
@@ -1286,6 +1286,19 @@ class Parser(object):
1286
1286
  n = match.group(0)[1:]
1287
1287
  return bytechr(int(n, 16)).decode(encoding)
1288
1288
 
1289
+ def find_previous(self, statements, class_):
1290
+ for previous in reversed(statements):
1291
+ if isinstance(previous, self.ast.Comment):
1292
+ continue
1293
+ elif isinstance(previous, class_):
1294
+ return previous
1295
+ else:
1296
+ # If we find something that doesn't match what we're looking
1297
+ # for, and isn't a comment, fail
1298
+ return None
1299
+ # Out of statements to look at
1300
+ return None
1301
+
1289
1302
  def parse_table_BASE_(self, table):
1290
1303
  statements = table.statements
1291
1304
  while self.next_token_ != "}" or self.cur_comments_:
@@ -1306,6 +1319,19 @@ class Parser(object):
1306
1319
  location=self.cur_token_location_,
1307
1320
  )
1308
1321
  )
1322
+ elif self.is_cur_keyword_("HorizAxis.MinMax"):
1323
+ base_script_list = self.find_previous(statements, ast.BaseAxis)
1324
+ if base_script_list is None:
1325
+ raise FeatureLibError(
1326
+ "MinMax must be preceded by BaseScriptList",
1327
+ self.cur_token_location_,
1328
+ )
1329
+ if base_script_list.vertical:
1330
+ raise FeatureLibError(
1331
+ "HorizAxis.MinMax must be preceded by HorizAxis statements",
1332
+ self.cur_token_location_,
1333
+ )
1334
+ base_script_list.minmax.append(self.parse_base_minmax_())
1309
1335
  elif self.is_cur_keyword_("VertAxis.BaseTagList"):
1310
1336
  vert_bases = self.parse_base_tag_list_()
1311
1337
  elif self.is_cur_keyword_("VertAxis.BaseScriptList"):
@@ -1318,6 +1344,19 @@ class Parser(object):
1318
1344
  location=self.cur_token_location_,
1319
1345
  )
1320
1346
  )
1347
+ elif self.is_cur_keyword_("VertAxis.MinMax"):
1348
+ base_script_list = self.find_previous(statements, ast.BaseAxis)
1349
+ if base_script_list is None:
1350
+ raise FeatureLibError(
1351
+ "MinMax must be preceded by BaseScriptList",
1352
+ self.cur_token_location_,
1353
+ )
1354
+ if not base_script_list.vertical:
1355
+ raise FeatureLibError(
1356
+ "VertAxis.MinMax must be preceded by VertAxis statements",
1357
+ self.cur_token_location_,
1358
+ )
1359
+ base_script_list.minmax.append(self.parse_base_minmax_())
1321
1360
  elif self.cur_token_ == ";":
1322
1361
  continue
1323
1362
 
@@ -1587,6 +1626,25 @@ class Parser(object):
1587
1626
  coords = [self.expect_number_() for i in range(count)]
1588
1627
  return script_tag, base_tag, coords
1589
1628
 
1629
+ def parse_base_minmax_(self):
1630
+ script_tag = self.expect_script_tag_()
1631
+ language = self.expect_language_tag_()
1632
+ min_coord = self.expect_number_()
1633
+ self.advance_lexer_()
1634
+ if not (self.cur_token_type_ is Lexer.SYMBOL and self.cur_token_ == ","):
1635
+ raise FeatureLibError(
1636
+ "Expected a comma between min and max coordinates",
1637
+ self.cur_token_location_,
1638
+ )
1639
+ max_coord = self.expect_number_()
1640
+ if self.next_token_ == ",": # feature tag...
1641
+ raise FeatureLibError(
1642
+ "Feature tags are not yet supported in BASE table",
1643
+ self.cur_token_location_,
1644
+ )
1645
+
1646
+ return script_tag, language, min_coord, max_coord
1647
+
1590
1648
  def parse_device_(self):
1591
1649
  result = None
1592
1650
  self.expect_symbol_("<")
@@ -1,4 +1,4 @@
1
- /* Generated by Cython 3.0.11 */
1
+ /* Generated by Cython 3.0.12 */
2
2
 
3
3
  /* BEGIN: Cython Metadata
4
4
  {
@@ -36,10 +36,10 @@ END: Cython Metadata */
36
36
  #else
37
37
  #define __PYX_EXTRA_ABI_MODULE_NAME ""
38
38
  #endif
39
- #define CYTHON_ABI "3_0_11" __PYX_EXTRA_ABI_MODULE_NAME
39
+ #define CYTHON_ABI "3_0_12" __PYX_EXTRA_ABI_MODULE_NAME
40
40
  #define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI
41
41
  #define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "."
42
- #define CYTHON_HEX_VERSION 0x03000BF0
42
+ #define CYTHON_HEX_VERSION 0x03000CF0
43
43
  #define CYTHON_FUTURE_DIVISION 1
44
44
  #include <stddef.h>
45
45
  #ifndef offsetof
@@ -1971,7 +1971,7 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
1971
1971
  #if !CYTHON_VECTORCALL
1972
1972
  #if PY_VERSION_HEX >= 0x03080000
1973
1973
  #include "frameobject.h"
1974
- #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API
1974
+ #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION)
1975
1975
  #ifndef Py_BUILD_CORE
1976
1976
  #define Py_BUILD_CORE 1
1977
1977
  #endif
@@ -36885,7 +36885,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
36885
36885
 
36886
36886
  /* CoroutineBase */
36887
36887
  #include <frameobject.h>
36888
- #if PY_VERSION_HEX >= 0x030b00a6
36888
+ #if PY_VERSION_HEX >= 0x030b00a6 && !defined(PYPY_VERSION)
36889
36889
  #ifndef Py_BUILD_CORE
36890
36890
  #define Py_BUILD_CORE 1
36891
36891
  #endif
@@ -40357,7 +40357,7 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
40357
40357
  #include "compile.h"
40358
40358
  #include "frameobject.h"
40359
40359
  #include "traceback.h"
40360
- #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API
40360
+ #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION)
40361
40361
  #ifndef Py_BUILD_CORE
40362
40362
  #define Py_BUILD_CORE 1
40363
40363
  #endif
@@ -46,7 +46,8 @@ def parseXmlInto(font, parseInto, xmlSnippet):
46
46
  parsed_xml = [e for e in parseXML(xmlSnippet.strip()) if not isinstance(e, str)]
47
47
  for name, attrs, content in parsed_xml:
48
48
  parseInto.fromXML(name, attrs, content, font)
49
- parseInto.populateDefaults()
49
+ if hasattr(parseInto, "populateDefaults"):
50
+ parseInto.populateDefaults()
50
51
  return parseInto
51
52
 
52
53
 
@@ -53,12 +53,18 @@ def compact(font: TTFont, level: int) -> TTFont:
53
53
  # are not grouped together first; instead each subtable is treated
54
54
  # independently, so currently this step is:
55
55
  # Split existing subtables into more smaller subtables
56
- gpos = font["GPOS"]
56
+ gpos = font.get("GPOS")
57
+
58
+ # If the font does not contain a GPOS table, there is nothing to do.
59
+ if gpos is None:
60
+ return font
61
+
57
62
  for lookup in gpos.table.LookupList.Lookup:
58
63
  if lookup.LookupType == 2:
59
64
  compact_lookup(font, level, lookup)
60
65
  elif lookup.LookupType == 9 and lookup.SubTable[0].ExtensionLookupType == 2:
61
66
  compact_ext_lookup(font, level, lookup)
67
+
62
68
  return font
63
69
 
64
70
 
@@ -1,4 +1,4 @@
1
- /* Generated by Cython 3.0.11 */
1
+ /* Generated by Cython 3.0.12 */
2
2
 
3
3
  /* BEGIN: Cython Metadata
4
4
  {
@@ -36,10 +36,10 @@ END: Cython Metadata */
36
36
  #else
37
37
  #define __PYX_EXTRA_ABI_MODULE_NAME ""
38
38
  #endif
39
- #define CYTHON_ABI "3_0_11" __PYX_EXTRA_ABI_MODULE_NAME
39
+ #define CYTHON_ABI "3_0_12" __PYX_EXTRA_ABI_MODULE_NAME
40
40
  #define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI
41
41
  #define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "."
42
- #define CYTHON_HEX_VERSION 0x03000BF0
42
+ #define CYTHON_HEX_VERSION 0x03000CF0
43
43
  #define CYTHON_FUTURE_DIVISION 1
44
44
  #include <stddef.h>
45
45
  #ifndef offsetof
@@ -1777,7 +1777,7 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
1777
1777
  #if !CYTHON_VECTORCALL
1778
1778
  #if PY_VERSION_HEX >= 0x03080000
1779
1779
  #include "frameobject.h"
1780
- #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API
1780
+ #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION)
1781
1781
  #ifndef Py_BUILD_CORE
1782
1782
  #define Py_BUILD_CORE 1
1783
1783
  #endif
@@ -12142,7 +12142,7 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
12142
12142
  #include "compile.h"
12143
12143
  #include "frameobject.h"
12144
12144
  #include "traceback.h"
12145
- #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API
12145
+ #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION)
12146
12146
  #ifndef Py_BUILD_CORE
12147
12147
  #define Py_BUILD_CORE 1
12148
12148
  #endif
fontTools/qu2cu/qu2cu.c CHANGED
@@ -1,4 +1,4 @@
1
- /* Generated by Cython 3.0.11 */
1
+ /* Generated by Cython 3.0.12 */
2
2
 
3
3
  /* BEGIN: Cython Metadata
4
4
  {
@@ -42,10 +42,10 @@ END: Cython Metadata */
42
42
  #else
43
43
  #define __PYX_EXTRA_ABI_MODULE_NAME ""
44
44
  #endif
45
- #define CYTHON_ABI "3_0_11" __PYX_EXTRA_ABI_MODULE_NAME
45
+ #define CYTHON_ABI "3_0_12" __PYX_EXTRA_ABI_MODULE_NAME
46
46
  #define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI
47
47
  #define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "."
48
- #define CYTHON_HEX_VERSION 0x03000BF0
48
+ #define CYTHON_HEX_VERSION 0x03000CF0
49
49
  #define CYTHON_FUTURE_DIVISION 1
50
50
  #include <stddef.h>
51
51
  #ifndef offsetof
@@ -2040,7 +2040,7 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
2040
2040
  #if !CYTHON_VECTORCALL
2041
2041
  #if PY_VERSION_HEX >= 0x03080000
2042
2042
  #include "frameobject.h"
2043
- #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API
2043
+ #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION)
2044
2044
  #ifndef Py_BUILD_CORE
2045
2045
  #define Py_BUILD_CORE 1
2046
2046
  #endif
@@ -13553,7 +13553,7 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
13553
13553
  #include "compile.h"
13554
13554
  #include "frameobject.h"
13555
13555
  #include "traceback.h"
13556
- #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API
13556
+ #if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION)
13557
13557
  #ifndef Py_BUILD_CORE
13558
13558
  #define Py_BUILD_CORE 1
13559
13559
  #endif
@@ -14829,7 +14829,7 @@ static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name
14829
14829
 
14830
14830
  /* CoroutineBase */
14831
14831
  #include <frameobject.h>
14832
- #if PY_VERSION_HEX >= 0x030b00a6
14832
+ #if PY_VERSION_HEX >= 0x030b00a6 && !defined(PYPY_VERSION)
14833
14833
  #ifndef Py_BUILD_CORE
14834
14834
  #define Py_BUILD_CORE 1
14835
14835
  #endif
@@ -1,5 +1,6 @@
1
1
  """fontTools.ttLib -- a package for dealing with TrueType fonts."""
2
2
 
3
+ from fontTools.config import OPTIONS
3
4
  from fontTools.misc.loggingTools import deprecateFunction
4
5
  import logging
5
6
 
@@ -7,6 +8,9 @@ import logging
7
8
  log = logging.getLogger(__name__)
8
9
 
9
10
 
11
+ OPTIMIZE_FONT_SPEED = OPTIONS["fontTools.ttLib:OPTIMIZE_FONT_SPEED"]
12
+
13
+
10
14
  class TTLibError(Exception):
11
15
  pass
12
16
 
@@ -1,5 +1,5 @@
1
1
  import sys
2
- from fontTools.ttLib import TTLibError, TTLibFileIsCollectionError
2
+ from fontTools.ttLib import OPTIMIZE_FONT_SPEED, TTLibError, TTLibFileIsCollectionError
3
3
  from fontTools.ttLib.ttFont import *
4
4
  from fontTools.ttLib.ttCollection import TTCollection
5
5
 
@@ -51,7 +51,7 @@ def main(args=None):
51
51
  )
52
52
  parser.add_argument("font", metavar="font", nargs="*", help="Font file.")
53
53
  parser.add_argument(
54
- "-t", "--table", metavar="table", nargs="*", help="Tables to decompile."
54
+ "-t", "--table", metavar="table", action="append", help="Tables to decompile."
55
55
  )
56
56
  parser.add_argument(
57
57
  "-o", "--output", metavar="FILE", default=None, help="Output file."
@@ -71,27 +71,66 @@ def main(args=None):
71
71
  default=None,
72
72
  help="Flavor of output font. 'woff' or 'woff2'.",
73
73
  )
74
+ parser.add_argument(
75
+ "--no-recalc-timestamp",
76
+ dest="recalcTimestamp",
77
+ action="store_false",
78
+ help="Keep the original font 'modified' timestamp.",
79
+ )
80
+ parser.add_argument(
81
+ "-b",
82
+ dest="recalcBBoxes",
83
+ action="store_false",
84
+ help="Don't recalc glyph bounding boxes: use the values in the original font.",
85
+ )
86
+ parser.add_argument(
87
+ "--optimize-font-speed",
88
+ action="store_true",
89
+ help=(
90
+ "Enable optimizations that prioritize speed over file size. This "
91
+ "mainly affects how glyf table and gvar / VARC tables are compiled."
92
+ ),
93
+ )
74
94
  options = parser.parse_args(args)
75
95
 
76
96
  fontNumber = int(options.y) if options.y is not None else None
77
97
  outFile = options.output
78
98
  lazy = options.lazy
79
99
  flavor = options.flavor
80
- tables = options.table if options.table is not None else ["*"]
100
+ tables = options.table
101
+ recalcBBoxes = options.recalcBBoxes
102
+ recalcTimestamp = options.recalcTimestamp
103
+ optimizeFontSpeed = options.optimize_font_speed
81
104
 
82
105
  fonts = []
83
106
  for f in options.font:
84
107
  try:
85
- font = TTFont(f, fontNumber=fontNumber, lazy=lazy)
108
+ font = TTFont(
109
+ f,
110
+ recalcBBoxes=recalcBBoxes,
111
+ recalcTimestamp=recalcTimestamp,
112
+ fontNumber=fontNumber,
113
+ lazy=lazy,
114
+ )
115
+ if optimizeFontSpeed:
116
+ font.cfg[OPTIMIZE_FONT_SPEED] = optimizeFontSpeed
86
117
  fonts.append(font)
87
118
  except TTLibFileIsCollectionError:
88
119
  collection = TTCollection(f, lazy=lazy)
89
120
  fonts.extend(collection.fonts)
90
121
 
91
- if lazy is False:
92
- for font in fonts:
93
- for table in tables if "*" not in tables else font.keys():
94
- font[table] # Decompiles
122
+ if tables is None:
123
+ if lazy is False:
124
+ tables = ["*"]
125
+ elif optimizeFontSpeed:
126
+ tables = {"glyf", "gvar", "VARC"}.intersection(font.keys())
127
+ else:
128
+ tables = []
129
+ for font in fonts:
130
+ if "GlyphOrder" in tables:
131
+ font.getGlyphOrder()
132
+ for table in tables if "*" not in tables else font.keys():
133
+ font[table] # Decompiles
95
134
 
96
135
  if outFile is not None:
97
136
  if len(fonts) == 1:
@@ -1,9 +1,15 @@
1
1
  import json
2
+ from textwrap import indent
2
3
 
3
4
  from . import DefaultTable
5
+ from fontTools.misc.textTools import tostr
4
6
 
5
7
 
6
8
  class table_D__e_b_g(DefaultTable.DefaultTable):
9
+ def __init__(self, tag=None):
10
+ DefaultTable.DefaultTable.__init__(self, tag)
11
+ self.data = {}
12
+
7
13
  def decompile(self, data, ttFont):
8
14
  self.data = json.loads(data)
9
15
 
@@ -11,7 +17,19 @@ class table_D__e_b_g(DefaultTable.DefaultTable):
11
17
  return json.dumps(self.data).encode("utf-8")
12
18
 
13
19
  def toXML(self, writer, ttFont):
14
- writer.writecdata(json.dumps(self.data, indent=2))
20
+ # make sure json indentation inside CDATA block matches XMLWriter's
21
+ data = json.dumps(self.data, indent=len(writer.indentwhite))
22
+ prefix = tostr(writer.indentwhite) * (writer.indentlevel + 1)
23
+ # but don't indent the first json line so it's adjacent to `<![CDATA[{`
24
+ cdata = indent(data, prefix, lambda ln: ln != "{\n")
25
+
26
+ writer.begintag("json")
27
+ writer.newline()
28
+ writer.writecdata(cdata)
29
+ writer.newline()
30
+ writer.endtag("json")
31
+ writer.newline()
15
32
 
16
33
  def fromXML(self, name, attrs, content, ttFont):
17
- self.data = json.loads(content)
34
+ if name == "json":
35
+ self.data = json.loads("".join(content))