fonttools 4.59.0__cp310-cp310-win32.whl → 4.59.1__cp310-cp310-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.c +30 -16
- fontTools/cu2qu/cu2qu.cp310-win32.pyd +0 -0
- fontTools/feaLib/builder.py +6 -1
- fontTools/feaLib/lexer.c +30 -16
- fontTools/feaLib/lexer.cp310-win32.pyd +0 -0
- fontTools/misc/bezierTools.c +33 -19
- fontTools/misc/bezierTools.cp310-win32.pyd +0 -0
- fontTools/misc/psCharStrings.py +17 -2
- fontTools/pens/momentsPen.c +20 -14
- fontTools/pens/momentsPen.cp310-win32.pyd +0 -0
- fontTools/qu2cu/qu2cu.c +32 -18
- fontTools/qu2cu/qu2cu.cp310-win32.pyd +0 -0
- fontTools/ttLib/tables/_g_v_a_r.py +6 -3
- fontTools/ttLib/tables/_h_m_t_x.py +7 -3
- fontTools/varLib/featureVars.py +8 -0
- fontTools/varLib/instancer/__init__.py +65 -5
- fontTools/varLib/iup.c +32 -18
- fontTools/varLib/iup.cp310-win32.pyd +0 -0
- fontTools/varLib/mutator.py +11 -0
- {fonttools-4.59.0.dist-info → fonttools-4.59.1.dist-info}/METADATA +24 -10
- {fonttools-4.59.0.dist-info → fonttools-4.59.1.dist-info}/RECORD +30 -30
- {fonttools-4.59.0.data → fonttools-4.59.1.data}/data/share/man/man1/ttx.1 +0 -0
- {fonttools-4.59.0.dist-info → fonttools-4.59.1.dist-info}/WHEEL +0 -0
- {fonttools-4.59.0.dist-info → fonttools-4.59.1.dist-info}/entry_points.txt +0 -0
- {fonttools-4.59.0.dist-info → fonttools-4.59.1.dist-info}/licenses/LICENSE +0 -0
- {fonttools-4.59.0.dist-info → fonttools-4.59.1.dist-info}/licenses/LICENSE.external +0 -0
- {fonttools-4.59.0.dist-info → fonttools-4.59.1.dist-info}/top_level.txt +0 -0
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
|
|
@@ -8294,16 +8297,15 @@ static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) {
|
|
|
8294
8297
|
return -1;
|
|
8295
8298
|
}
|
|
8296
8299
|
/* #### Code section: init_codeobjects ### */
|
|
8297
|
-
|
|
8298
|
-
|
|
8299
|
-
|
|
8300
|
-
|
|
8301
|
-
|
|
8302
|
-
|
|
8303
|
-
|
|
8304
|
-
|
|
8305
|
-
|
|
8306
|
-
} __Pyx_PyCode_New_function_description;
|
|
8300
|
+
typedef struct {
|
|
8301
|
+
unsigned int argcount : 3;
|
|
8302
|
+
unsigned int num_posonly_args : 1;
|
|
8303
|
+
unsigned int num_kwonly_args : 1;
|
|
8304
|
+
unsigned int nlocals : 8;
|
|
8305
|
+
unsigned int flags : 10;
|
|
8306
|
+
unsigned int first_line : 9;
|
|
8307
|
+
unsigned int line_table_length : 17;
|
|
8308
|
+
} __Pyx_PyCode_New_function_description;
|
|
8307
8309
|
/* NewCodeObj.proto */
|
|
8308
8310
|
static PyObject* __Pyx_PyCode_New(
|
|
8309
8311
|
const __Pyx_PyCode_New_function_description descr,
|
|
@@ -10172,6 +10174,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
10172
10174
|
changed = 1;
|
|
10173
10175
|
}
|
|
10174
10176
|
#endif // CYTHON_METH_FASTCALL
|
|
10177
|
+
#if !CYTHON_COMPILING_IN_PYPY
|
|
10175
10178
|
else if (strcmp(memb->name, "__module__") == 0) {
|
|
10176
10179
|
PyObject *descr;
|
|
10177
10180
|
assert(memb->type == T_OBJECT);
|
|
@@ -10186,11 +10189,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
10186
10189
|
}
|
|
10187
10190
|
changed = 1;
|
|
10188
10191
|
}
|
|
10192
|
+
#endif // !CYTHON_COMPILING_IN_PYPY
|
|
10189
10193
|
}
|
|
10190
10194
|
memb++;
|
|
10191
10195
|
}
|
|
10192
10196
|
}
|
|
10193
10197
|
#endif // !CYTHON_COMPILING_IN_LIMITED_API
|
|
10198
|
+
#if !CYTHON_COMPILING_IN_PYPY
|
|
10194
10199
|
slot = spec->slots;
|
|
10195
10200
|
while (slot && slot->slot && slot->slot != Py_tp_getset)
|
|
10196
10201
|
slot++;
|
|
@@ -10222,6 +10227,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
10222
10227
|
++getset;
|
|
10223
10228
|
}
|
|
10224
10229
|
}
|
|
10230
|
+
#endif // !CYTHON_COMPILING_IN_PYPY
|
|
10225
10231
|
if (changed)
|
|
10226
10232
|
PyType_Modified(type);
|
|
10227
10233
|
#endif // PY_VERSION_HEX > 0x030900B1
|
|
@@ -10354,7 +10360,7 @@ bad:
|
|
|
10354
10360
|
}
|
|
10355
10361
|
|
|
10356
10362
|
/* CommonTypesMetaclass */
|
|
10357
|
-
PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
|
|
10363
|
+
static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
|
|
10358
10364
|
return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
|
|
10359
10365
|
}
|
|
10360
10366
|
static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {
|
|
Binary file
|
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)
|
|
@@ -9028,16 +9031,15 @@ static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) {
|
|
|
9028
9031
|
return -1;
|
|
9029
9032
|
}
|
|
9030
9033
|
/* #### Code section: init_codeobjects ### */
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
} __Pyx_PyCode_New_function_description;
|
|
9034
|
+
typedef struct {
|
|
9035
|
+
unsigned int argcount : 3;
|
|
9036
|
+
unsigned int num_posonly_args : 1;
|
|
9037
|
+
unsigned int num_kwonly_args : 1;
|
|
9038
|
+
unsigned int nlocals : 6;
|
|
9039
|
+
unsigned int flags : 10;
|
|
9040
|
+
unsigned int first_line : 9;
|
|
9041
|
+
unsigned int line_table_length : 15;
|
|
9042
|
+
} __Pyx_PyCode_New_function_description;
|
|
9041
9043
|
/* NewCodeObj.proto */
|
|
9042
9044
|
static PyObject* __Pyx_PyCode_New(
|
|
9043
9045
|
const __Pyx_PyCode_New_function_description descr,
|
|
@@ -10557,7 +10559,7 @@ static PyObject *__Pyx_PyLong_AbsNeg(PyObject *n) {
|
|
|
10557
10559
|
PyObject *copy = _PyLong_Copy((PyLongObject*)n);
|
|
10558
10560
|
if (likely(copy)) {
|
|
10559
10561
|
#if PY_VERSION_HEX >= 0x030C00A7
|
|
10560
|
-
((PyLongObject*)copy)->long_value.lv_tag
|
|
10562
|
+
((PyLongObject*)copy)->long_value.lv_tag ^= ((PyLongObject*)copy)->long_value.lv_tag & _PyLong_SIGN_MASK;
|
|
10561
10563
|
#else
|
|
10562
10564
|
__Pyx_SET_SIZE(copy, -Py_SIZE(copy));
|
|
10563
10565
|
#endif
|
|
@@ -11193,6 +11195,13 @@ try_unpack:
|
|
|
11193
11195
|
|
|
11194
11196
|
/* PyObjectCallMethod0 */
|
|
11195
11197
|
static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) {
|
|
11198
|
+
#if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
|
|
11199
|
+
PyObject *args[1] = {obj};
|
|
11200
|
+
(void) __Pyx_PyObject_GetMethod;
|
|
11201
|
+
(void) __Pyx_PyObject_CallOneArg;
|
|
11202
|
+
(void) __Pyx_PyObject_CallNoArg;
|
|
11203
|
+
return PyObject_VectorcallMethod(method_name, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
|
|
11204
|
+
#else
|
|
11196
11205
|
PyObject *method = NULL, *result = NULL;
|
|
11197
11206
|
int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method);
|
|
11198
11207
|
if (likely(is_method)) {
|
|
@@ -11205,6 +11214,7 @@ static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name
|
|
|
11205
11214
|
Py_DECREF(method);
|
|
11206
11215
|
bad:
|
|
11207
11216
|
return result;
|
|
11217
|
+
#endif
|
|
11208
11218
|
}
|
|
11209
11219
|
|
|
11210
11220
|
/* CallUnboundCMethod0 */
|
|
@@ -11742,6 +11752,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
11742
11752
|
changed = 1;
|
|
11743
11753
|
}
|
|
11744
11754
|
#endif // CYTHON_METH_FASTCALL
|
|
11755
|
+
#if !CYTHON_COMPILING_IN_PYPY
|
|
11745
11756
|
else if (strcmp(memb->name, "__module__") == 0) {
|
|
11746
11757
|
PyObject *descr;
|
|
11747
11758
|
assert(memb->type == T_OBJECT);
|
|
@@ -11756,11 +11767,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
11756
11767
|
}
|
|
11757
11768
|
changed = 1;
|
|
11758
11769
|
}
|
|
11770
|
+
#endif // !CYTHON_COMPILING_IN_PYPY
|
|
11759
11771
|
}
|
|
11760
11772
|
memb++;
|
|
11761
11773
|
}
|
|
11762
11774
|
}
|
|
11763
11775
|
#endif // !CYTHON_COMPILING_IN_LIMITED_API
|
|
11776
|
+
#if !CYTHON_COMPILING_IN_PYPY
|
|
11764
11777
|
slot = spec->slots;
|
|
11765
11778
|
while (slot && slot->slot && slot->slot != Py_tp_getset)
|
|
11766
11779
|
slot++;
|
|
@@ -11792,6 +11805,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
11792
11805
|
++getset;
|
|
11793
11806
|
}
|
|
11794
11807
|
}
|
|
11808
|
+
#endif // !CYTHON_COMPILING_IN_PYPY
|
|
11795
11809
|
if (changed)
|
|
11796
11810
|
PyType_Modified(type);
|
|
11797
11811
|
#endif // PY_VERSION_HEX > 0x030900B1
|
|
@@ -12227,7 +12241,7 @@ bad:
|
|
|
12227
12241
|
}
|
|
12228
12242
|
|
|
12229
12243
|
/* CommonTypesMetaclass */
|
|
12230
|
-
PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
|
|
12244
|
+
static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
|
|
12231
12245
|
return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
|
|
12232
12246
|
}
|
|
12233
12247
|
static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {
|
|
@@ -14847,7 +14861,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyOb
|
|
|
14847
14861
|
}
|
|
14848
14862
|
|
|
14849
14863
|
/* PyObjectCallMethod1 */
|
|
14850
|
-
#if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000)
|
|
14864
|
+
#if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)))
|
|
14851
14865
|
static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
|
|
14852
14866
|
PyObject *result = __Pyx_PyObject_CallOneArg(method, arg);
|
|
14853
14867
|
Py_DECREF(method);
|
|
@@ -14855,7 +14869,7 @@ static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
|
|
|
14855
14869
|
}
|
|
14856
14870
|
#endif
|
|
14857
14871
|
static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
|
|
14858
|
-
#if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000
|
|
14872
|
+
#if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
|
|
14859
14873
|
PyObject *args[2] = {obj, arg};
|
|
14860
14874
|
(void) __Pyx_PyObject_GetMethod;
|
|
14861
14875
|
(void) __Pyx_PyObject_CallOneArg;
|
|
Binary file
|
|
@@ -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
|
)
|
|
@@ -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
|
|
fontTools/varLib/featureVars.py
CHANGED
|
@@ -95,6 +95,14 @@ def addFeatureVariations(font, conditionalSubstitutions, featureTag="rvrn"):
|
|
|
95
95
|
|
|
96
96
|
addFeatureVariationsRaw(font, font["GSUB"].table, conditionsAndLookups, featureTags)
|
|
97
97
|
|
|
98
|
+
# Update OS/2.usMaxContext in case the font didn't have features before, but
|
|
99
|
+
# does now, if the OS/2 table exists. The table may be required, but
|
|
100
|
+
# fontTools needs to be able to deal with non-standard fonts. Since feature
|
|
101
|
+
# variations are always 1:1 mappings, we can set the value to at least 1
|
|
102
|
+
# instead of recomputing it with `otlLib.maxContextCalc.maxCtxFont()`.
|
|
103
|
+
if (os2 := font.get("OS/2")) is not None:
|
|
104
|
+
os2.usMaxContext = max(1, os2.usMaxContext)
|
|
105
|
+
|
|
98
106
|
|
|
99
107
|
def _existingVariableFeatures(table):
|
|
100
108
|
existingFeatureVarsTags = set()
|
|
@@ -120,6 +120,7 @@ from fontTools.cffLib.specializer import (
|
|
|
120
120
|
specializeCommands,
|
|
121
121
|
generalizeCommands,
|
|
122
122
|
)
|
|
123
|
+
from fontTools.cffLib.CFF2ToCFF import convertCFF2ToCFF
|
|
123
124
|
from fontTools.varLib import builder
|
|
124
125
|
from fontTools.varLib.mvar import MVAR_ENTRIES
|
|
125
126
|
from fontTools.varLib.merger import MutatorMerger
|
|
@@ -136,6 +137,7 @@ from enum import IntEnum
|
|
|
136
137
|
import logging
|
|
137
138
|
import os
|
|
138
139
|
import re
|
|
140
|
+
import io
|
|
139
141
|
from typing import Dict, Iterable, Mapping, Optional, Sequence, Tuple, Union
|
|
140
142
|
import warnings
|
|
141
143
|
|
|
@@ -643,7 +645,11 @@ def instantiateCFF2(
|
|
|
643
645
|
# the Private dicts.
|
|
644
646
|
#
|
|
645
647
|
# Then prune unused things and possibly drop the VarStore if it's empty.
|
|
646
|
-
#
|
|
648
|
+
#
|
|
649
|
+
# If the downgrade parameter is True, no actual downgrading is done, but
|
|
650
|
+
# the function returns True if the VarStore was empty after instantiation,
|
|
651
|
+
# and hence a downgrade to CFF is possible. In all other cases it returns
|
|
652
|
+
# False.
|
|
647
653
|
|
|
648
654
|
log.info("Instantiating CFF2 table")
|
|
649
655
|
|
|
@@ -882,9 +888,9 @@ def instantiateCFF2(
|
|
|
882
888
|
del private.vstore
|
|
883
889
|
|
|
884
890
|
if downgrade:
|
|
885
|
-
|
|
891
|
+
return True
|
|
886
892
|
|
|
887
|
-
|
|
893
|
+
return False
|
|
888
894
|
|
|
889
895
|
|
|
890
896
|
def _instantiateGvarGlyph(
|
|
@@ -1377,6 +1383,52 @@ def _isValidAvarSegmentMap(axisTag, segmentMap):
|
|
|
1377
1383
|
return True
|
|
1378
1384
|
|
|
1379
1385
|
|
|
1386
|
+
def downgradeCFF2ToCFF(varfont):
|
|
1387
|
+
|
|
1388
|
+
# Save these properties
|
|
1389
|
+
recalcTimestamp = varfont.recalcTimestamp
|
|
1390
|
+
recalcBBoxes = varfont.recalcBBoxes
|
|
1391
|
+
|
|
1392
|
+
# Disable them
|
|
1393
|
+
varfont.recalcTimestamp = False
|
|
1394
|
+
varfont.recalcBBoxes = False
|
|
1395
|
+
|
|
1396
|
+
# Save to memory, reload, downgrade and save again, reload.
|
|
1397
|
+
# We do this dance because the convertCFF2ToCFF changes glyph
|
|
1398
|
+
# names, so following save would fail if any other table was
|
|
1399
|
+
# loaded and referencing glyph names.
|
|
1400
|
+
#
|
|
1401
|
+
# The second save+load is unfortunate but also necessary.
|
|
1402
|
+
|
|
1403
|
+
stream = io.BytesIO()
|
|
1404
|
+
log.info("Saving CFF2 font to memory for downgrade")
|
|
1405
|
+
varfont.save(stream)
|
|
1406
|
+
stream.seek(0)
|
|
1407
|
+
varfont = TTFont(stream, recalcTimestamp=False, recalcBBoxes=False)
|
|
1408
|
+
|
|
1409
|
+
convertCFF2ToCFF(varfont)
|
|
1410
|
+
|
|
1411
|
+
stream = io.BytesIO()
|
|
1412
|
+
log.info("Saving downgraded CFF font to memory")
|
|
1413
|
+
varfont.save(stream)
|
|
1414
|
+
stream.seek(0)
|
|
1415
|
+
varfont = TTFont(stream, recalcTimestamp=False, recalcBBoxes=False)
|
|
1416
|
+
|
|
1417
|
+
# Uncomment, to see test all tables can be loaded. This fails without
|
|
1418
|
+
# the extra save+load above.
|
|
1419
|
+
"""
|
|
1420
|
+
for tag in varfont.keys():
|
|
1421
|
+
print("Loading", tag)
|
|
1422
|
+
varfont[tag]
|
|
1423
|
+
"""
|
|
1424
|
+
|
|
1425
|
+
# Restore them
|
|
1426
|
+
varfont.recalcTimestamp = recalcTimestamp
|
|
1427
|
+
varfont.recalcBBoxes = recalcBBoxes
|
|
1428
|
+
|
|
1429
|
+
return varfont
|
|
1430
|
+
|
|
1431
|
+
|
|
1380
1432
|
def instantiateAvar(varfont, axisLimits):
|
|
1381
1433
|
# 'axisLimits' dict must contain user-space (non-normalized) coordinates.
|
|
1382
1434
|
|
|
@@ -1665,7 +1717,9 @@ def instantiateVariableFont(
|
|
|
1665
1717
|
instantiateVARC(varfont, normalizedLimits)
|
|
1666
1718
|
|
|
1667
1719
|
if "CFF2" in varfont:
|
|
1668
|
-
instantiateCFF2(
|
|
1720
|
+
downgradeCFF2 = instantiateCFF2(
|
|
1721
|
+
varfont, normalizedLimits, downgrade=downgradeCFF2
|
|
1722
|
+
)
|
|
1669
1723
|
|
|
1670
1724
|
if "gvar" in varfont:
|
|
1671
1725
|
instantiateGvar(varfont, normalizedLimits, optimize=optimize)
|
|
@@ -1720,6 +1774,12 @@ def instantiateVariableFont(
|
|
|
1720
1774
|
# name table has been updated.
|
|
1721
1775
|
setRibbiBits(varfont)
|
|
1722
1776
|
|
|
1777
|
+
if downgradeCFF2:
|
|
1778
|
+
origVarfont = varfont
|
|
1779
|
+
varfont = downgradeCFF2ToCFF(varfont)
|
|
1780
|
+
if inplace:
|
|
1781
|
+
origVarfont.__dict__ = varfont.__dict__.copy()
|
|
1782
|
+
|
|
1723
1783
|
return varfont
|
|
1724
1784
|
|
|
1725
1785
|
|
|
@@ -1929,7 +1989,7 @@ def main(args=None):
|
|
|
1929
1989
|
if limit is None or limit[0] == limit[2]
|
|
1930
1990
|
}.issuperset(axis.axisTag for axis in varfont["fvar"].axes)
|
|
1931
1991
|
|
|
1932
|
-
instantiateVariableFont(
|
|
1992
|
+
varfont = instantiateVariableFont(
|
|
1933
1993
|
varfont,
|
|
1934
1994
|
axisLimits,
|
|
1935
1995
|
inplace=True,
|
fontTools/varLib/iup.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
|
|
@@ -2141,7 +2144,7 @@ static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);
|
|
|
2141
2144
|
static PyObject *__Pyx_PyLong_AbsNeg(PyObject *num);
|
|
2142
2145
|
#define __Pyx_PyNumber_Absolute(x)\
|
|
2143
2146
|
((likely(PyLong_CheckExact(x))) ?\
|
|
2144
|
-
(likely(__Pyx_PyLong_IsNonNeg(x)) ? (
|
|
2147
|
+
(likely(__Pyx_PyLong_IsNonNeg(x)) ? __Pyx_NewRef(x) : __Pyx_PyLong_AbsNeg(x)) :\
|
|
2145
2148
|
PyNumber_Absolute(x))
|
|
2146
2149
|
#else
|
|
2147
2150
|
#define __Pyx_PyNumber_Absolute(x) PyNumber_Absolute(x)
|
|
@@ -12093,16 +12096,15 @@ static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) {
|
|
|
12093
12096
|
return -1;
|
|
12094
12097
|
}
|
|
12095
12098
|
/* #### Code section: init_codeobjects ### */
|
|
12096
|
-
|
|
12097
|
-
|
|
12098
|
-
|
|
12099
|
-
|
|
12100
|
-
|
|
12101
|
-
|
|
12102
|
-
|
|
12103
|
-
|
|
12104
|
-
|
|
12105
|
-
} __Pyx_PyCode_New_function_description;
|
|
12099
|
+
typedef struct {
|
|
12100
|
+
unsigned int argcount : 3;
|
|
12101
|
+
unsigned int num_posonly_args : 1;
|
|
12102
|
+
unsigned int num_kwonly_args : 1;
|
|
12103
|
+
unsigned int nlocals : 5;
|
|
12104
|
+
unsigned int flags : 10;
|
|
12105
|
+
unsigned int first_line : 9;
|
|
12106
|
+
unsigned int line_table_length : 14;
|
|
12107
|
+
} __Pyx_PyCode_New_function_description;
|
|
12106
12108
|
/* NewCodeObj.proto */
|
|
12107
12109
|
static PyObject* __Pyx_PyCode_New(
|
|
12108
12110
|
const __Pyx_PyCode_New_function_description descr,
|
|
@@ -14329,7 +14331,7 @@ static PyObject *__Pyx_PyLong_AbsNeg(PyObject *n) {
|
|
|
14329
14331
|
PyObject *copy = _PyLong_Copy((PyLongObject*)n);
|
|
14330
14332
|
if (likely(copy)) {
|
|
14331
14333
|
#if PY_VERSION_HEX >= 0x030C00A7
|
|
14332
|
-
((PyLongObject*)copy)->long_value.lv_tag
|
|
14334
|
+
((PyLongObject*)copy)->long_value.lv_tag ^= ((PyLongObject*)copy)->long_value.lv_tag & _PyLong_SIGN_MASK;
|
|
14333
14335
|
#else
|
|
14334
14336
|
__Pyx_SET_SIZE(copy, -Py_SIZE(copy));
|
|
14335
14337
|
#endif
|
|
@@ -14942,6 +14944,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
14942
14944
|
changed = 1;
|
|
14943
14945
|
}
|
|
14944
14946
|
#endif // CYTHON_METH_FASTCALL
|
|
14947
|
+
#if !CYTHON_COMPILING_IN_PYPY
|
|
14945
14948
|
else if (strcmp(memb->name, "__module__") == 0) {
|
|
14946
14949
|
PyObject *descr;
|
|
14947
14950
|
assert(memb->type == T_OBJECT);
|
|
@@ -14956,11 +14959,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
14956
14959
|
}
|
|
14957
14960
|
changed = 1;
|
|
14958
14961
|
}
|
|
14962
|
+
#endif // !CYTHON_COMPILING_IN_PYPY
|
|
14959
14963
|
}
|
|
14960
14964
|
memb++;
|
|
14961
14965
|
}
|
|
14962
14966
|
}
|
|
14963
14967
|
#endif // !CYTHON_COMPILING_IN_LIMITED_API
|
|
14968
|
+
#if !CYTHON_COMPILING_IN_PYPY
|
|
14964
14969
|
slot = spec->slots;
|
|
14965
14970
|
while (slot && slot->slot && slot->slot != Py_tp_getset)
|
|
14966
14971
|
slot++;
|
|
@@ -14992,6 +14997,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
|
|
|
14992
14997
|
++getset;
|
|
14993
14998
|
}
|
|
14994
14999
|
}
|
|
15000
|
+
#endif // !CYTHON_COMPILING_IN_PYPY
|
|
14995
15001
|
if (changed)
|
|
14996
15002
|
PyType_Modified(type);
|
|
14997
15003
|
#endif // PY_VERSION_HEX > 0x030900B1
|
|
@@ -15090,6 +15096,13 @@ try_unpack:
|
|
|
15090
15096
|
|
|
15091
15097
|
/* PyObjectCallMethod0 */
|
|
15092
15098
|
static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) {
|
|
15099
|
+
#if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
|
|
15100
|
+
PyObject *args[1] = {obj};
|
|
15101
|
+
(void) __Pyx_PyObject_GetMethod;
|
|
15102
|
+
(void) __Pyx_PyObject_CallOneArg;
|
|
15103
|
+
(void) __Pyx_PyObject_CallNoArg;
|
|
15104
|
+
return PyObject_VectorcallMethod(method_name, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
|
|
15105
|
+
#else
|
|
15093
15106
|
PyObject *method = NULL, *result = NULL;
|
|
15094
15107
|
int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method);
|
|
15095
15108
|
if (likely(is_method)) {
|
|
@@ -15102,6 +15115,7 @@ static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name
|
|
|
15102
15115
|
Py_DECREF(method);
|
|
15103
15116
|
bad:
|
|
15104
15117
|
return result;
|
|
15118
|
+
#endif
|
|
15105
15119
|
}
|
|
15106
15120
|
|
|
15107
15121
|
/* ValidateBasesTuple */
|
|
@@ -15489,7 +15503,7 @@ bad:
|
|
|
15489
15503
|
}
|
|
15490
15504
|
|
|
15491
15505
|
/* CommonTypesMetaclass */
|
|
15492
|
-
PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
|
|
15506
|
+
static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
|
|
15493
15507
|
return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
|
|
15494
15508
|
}
|
|
15495
15509
|
static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {
|
|
@@ -17939,7 +17953,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyOb
|
|
|
17939
17953
|
}
|
|
17940
17954
|
|
|
17941
17955
|
/* PyObjectCallMethod1 */
|
|
17942
|
-
#if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000)
|
|
17956
|
+
#if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)))
|
|
17943
17957
|
static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
|
|
17944
17958
|
PyObject *result = __Pyx_PyObject_CallOneArg(method, arg);
|
|
17945
17959
|
Py_DECREF(method);
|
|
@@ -17947,7 +17961,7 @@ static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
|
|
|
17947
17961
|
}
|
|
17948
17962
|
#endif
|
|
17949
17963
|
static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
|
|
17950
|
-
#if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000
|
|
17964
|
+
#if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
|
|
17951
17965
|
PyObject *args[2] = {obj, arg};
|
|
17952
17966
|
(void) __Pyx_PyObject_GetMethod;
|
|
17953
17967
|
(void) __Pyx_PyObject_CallOneArg;
|
|
Binary file
|
fontTools/varLib/mutator.py
CHANGED
|
@@ -4,9 +4,16 @@ Instantiate a variation font. Run, eg:
|
|
|
4
4
|
.. code-block:: sh
|
|
5
5
|
|
|
6
6
|
$ fonttools varLib.mutator ./NotoSansArabic-VF.ttf wght=140 wdth=85
|
|
7
|
+
|
|
8
|
+
.. warning::
|
|
9
|
+
``fontTools.varLib.mutator`` is deprecated in favor of :mod:`fontTools.varLib.instancer`
|
|
10
|
+
which provides equivalent full instancing and also supports partial instancing.
|
|
11
|
+
Please migrate CLI usage to ``fonttools varLib.instancer`` and API usage to
|
|
12
|
+
:func:`fontTools.varLib.instancer.instantiateVariableFont`.
|
|
7
13
|
"""
|
|
8
14
|
|
|
9
15
|
from fontTools.misc.fixedTools import floatToFixedToFloat, floatToFixed
|
|
16
|
+
from fontTools.misc.loggingTools import deprecateFunction
|
|
10
17
|
from fontTools.misc.roundTools import otRound
|
|
11
18
|
from fontTools.pens.boundsPen import BoundsPen
|
|
12
19
|
from fontTools.ttLib import TTFont, newTable
|
|
@@ -159,6 +166,10 @@ def interpolate_cff2_metrics(varfont, topDict, glyphOrder, loc):
|
|
|
159
166
|
hmtx[gname] = tuple(entry)
|
|
160
167
|
|
|
161
168
|
|
|
169
|
+
@deprecateFunction(
|
|
170
|
+
"use fontTools.varLib.instancer.instantiateVariableFont instead "
|
|
171
|
+
"for either full or partial instancing",
|
|
172
|
+
)
|
|
162
173
|
def instantiateVariableFont(varfont, location, inplace=False, overlap=True):
|
|
163
174
|
"""Generate a static instance from a variable TTFont and a dictionary
|
|
164
175
|
defining the desired location along the variable font's axes.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fonttools
|
|
3
|
-
Version: 4.59.
|
|
3
|
+
Version: 4.59.1
|
|
4
4
|
Summary: Tools to manipulate font files
|
|
5
5
|
Home-page: http://github.com/fonttools/fonttools
|
|
6
6
|
Author: Just van Rossum
|
|
@@ -168,15 +168,6 @@ are required to unlock the extra features named "ufo", etc.
|
|
|
168
168
|
|
|
169
169
|
*Extra:* ``lxml``
|
|
170
170
|
|
|
171
|
-
- ``Lib/fontTools/ufoLib``
|
|
172
|
-
|
|
173
|
-
Package for reading and writing UFO source files; it requires:
|
|
174
|
-
|
|
175
|
-
* `fs <https://pypi.org/pypi/fs>`__: (aka ``pyfilesystem2``) filesystem
|
|
176
|
-
abstraction layer.
|
|
177
|
-
|
|
178
|
-
*Extra:* ``ufo``
|
|
179
|
-
|
|
180
171
|
- ``Lib/fontTools/ttLib/woff2.py``
|
|
181
172
|
|
|
182
173
|
Module to compress/decompress WOFF 2.0 web fonts; it requires:
|
|
@@ -269,6 +260,17 @@ are required to unlock the extra features named "ufo", etc.
|
|
|
269
260
|
|
|
270
261
|
*Extra:* ``pathops``
|
|
271
262
|
|
|
263
|
+
- ``Lib/fontTools/ufoLib``
|
|
264
|
+
|
|
265
|
+
Package for reading and writing UFO source files; if available, it will use:
|
|
266
|
+
|
|
267
|
+
* `fs <https://pypi.org/pypi/fs>`__: (aka ``pyfilesystem2``) filesystem abstraction layer
|
|
268
|
+
|
|
269
|
+
for reading and writing UFOs to the local filesystem or zip files (.ufoz), instead of
|
|
270
|
+
the built-in ``fontTools.misc.filesystem`` package.
|
|
271
|
+
The reader and writer classes can in theory also accept any object compatible the
|
|
272
|
+
``fs.base.FS`` interface, although not all have been tested.
|
|
273
|
+
|
|
272
274
|
- ``Lib/fontTools/pens/cocoaPen.py`` and ``Lib/fontTools/pens/quartzPen.py``
|
|
273
275
|
|
|
274
276
|
Pens for drawing glyphs with Cocoa ``NSBezierPath`` or ``CGPath`` require:
|
|
@@ -386,6 +388,18 @@ Have fun!
|
|
|
386
388
|
Changelog
|
|
387
389
|
~~~~~~~~~
|
|
388
390
|
|
|
391
|
+
4.59.1 (released 2025-08-14)
|
|
392
|
+
----------------------------
|
|
393
|
+
|
|
394
|
+
- [featureVars] Update OS/2.usMaxContext if possible after addFeatureVariationsRaw (#3894).
|
|
395
|
+
- [vhmtx] raise TTLibError('not enough data...') when hmtx/vmtx are truncated (#3843, #3901).
|
|
396
|
+
- [feaLib] Combine duplicate features that have the same set of lookups regardless of the order in which those lookups are added to the feature (#3895).
|
|
397
|
+
- [varLib] Deprecate ``varLib.mutator`` in favor of ``varLib.instancer``. The latter
|
|
398
|
+
provides equivalent full (static font) instancing in addition to partial VF instancing.
|
|
399
|
+
CLI users should replace ``fonttools varLib.mutator`` with ``fonttools varLib.instancer``.
|
|
400
|
+
API users should migrate to ``fontTools.varLib.instancer.instantiateVariableFont`` (#2680).
|
|
401
|
+
|
|
402
|
+
|
|
389
403
|
4.59.0 (released 2025-07-16)
|
|
390
404
|
----------------------------
|
|
391
405
|
|