fonttools 4.59.2__cp39-cp39-musllinux_1_2_aarch64.whl → 4.60.1__cp39-cp39-musllinux_1_2_aarch64.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/annotations.py +30 -0
- fontTools/cu2qu/cu2qu.c +1057 -937
- fontTools/cu2qu/cu2qu.cpython-39-aarch64-linux-gnu.so +0 -0
- fontTools/cu2qu/cu2qu.py +19 -2
- fontTools/feaLib/lexer.c +8 -3
- fontTools/feaLib/lexer.cpython-39-aarch64-linux-gnu.so +0 -0
- fontTools/misc/bezierTools.c +8 -3
- fontTools/misc/bezierTools.cpython-39-aarch64-linux-gnu.so +0 -0
- fontTools/misc/enumTools.py +23 -0
- fontTools/misc/visitor.py +24 -16
- fontTools/pens/filterPen.py +218 -26
- fontTools/pens/momentsPen.c +8 -3
- fontTools/pens/momentsPen.cpython-39-aarch64-linux-gnu.so +0 -0
- fontTools/pens/pointPen.py +40 -6
- fontTools/qu2cu/qu2cu.c +20 -7
- fontTools/qu2cu/qu2cu.cpython-39-aarch64-linux-gnu.so +0 -0
- fontTools/subset/__init__.py +178 -12
- fontTools/ttLib/tables/_p_o_s_t.py +5 -5
- fontTools/ufoLib/__init__.py +278 -175
- fontTools/ufoLib/converters.py +14 -5
- fontTools/ufoLib/filenames.py +16 -6
- fontTools/ufoLib/glifLib.py +286 -190
- fontTools/ufoLib/kerning.py +32 -12
- fontTools/ufoLib/utils.py +41 -13
- fontTools/ufoLib/validators.py +121 -97
- fontTools/varLib/avar/__init__.py +0 -0
- fontTools/varLib/avar/__main__.py +72 -0
- fontTools/varLib/avar/build.py +79 -0
- fontTools/varLib/avar/map.py +108 -0
- fontTools/varLib/avar/plan.py +1004 -0
- fontTools/varLib/{avar.py → avar/unbuild.py} +70 -59
- fontTools/varLib/avarPlanner.py +3 -999
- fontTools/varLib/interpolatableHelpers.py +3 -0
- fontTools/varLib/iup.c +14 -5
- fontTools/varLib/iup.cpython-39-aarch64-linux-gnu.so +0 -0
- {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/METADATA +41 -2
- {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/RECORD +44 -37
- {fonttools-4.59.2.data → fonttools-4.60.1.data}/data/share/man/man1/ttx.1 +0 -0
- {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/WHEEL +0 -0
- {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/entry_points.txt +0 -0
- {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/licenses/LICENSE +0 -0
- {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/licenses/LICENSE.external +0 -0
- {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/top_level.txt +0 -0
fontTools/qu2cu/qu2cu.c
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Generated by Cython 3.1.
|
|
1
|
+
/* Generated by Cython 3.1.4 */
|
|
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_4"
|
|
36
|
+
#define CYTHON_HEX_VERSION 0x030104F0
|
|
37
37
|
#define CYTHON_FUTURE_DIVISION 1
|
|
38
38
|
/* CModulePreamble */
|
|
39
39
|
#include <stddef.h>
|
|
@@ -3887,8 +3887,12 @@ static PyObject *__pyx_f_9fontTools_5qu2cu_5qu2cu_merge_curves(PyObject *__pyx_v
|
|
|
3887
3887
|
__pyx_t_14 = __Pyx_c_diff_double(__pyx_v_p1, __pyx_v_p0);
|
|
3888
3888
|
__pyx_t_7 = __pyx_PyComplex_FromComplex(__pyx_t_14); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 146, __pyx_L1_error)
|
|
3889
3889
|
__Pyx_GOTREF(__pyx_t_7);
|
|
3890
|
-
|
|
3891
|
-
|
|
3890
|
+
{
|
|
3891
|
+
Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_v_ts);
|
|
3892
|
+
if (unlikely(((!CYTHON_ASSUME_SAFE_SIZE) && __pyx_temp < 0))) __PYX_ERR(0, 146, __pyx_L1_error)
|
|
3893
|
+
__pyx_t_9 = (__pyx_temp != 0);
|
|
3894
|
+
}
|
|
3895
|
+
|
|
3892
3896
|
if (__pyx_t_9) {
|
|
3893
3897
|
__pyx_t_1 = __Pyx_GetItemInt_List(__pyx_v_ts, 0, long, 1, __Pyx_PyLong_From_long, 1, 0, 1, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 146, __pyx_L1_error)
|
|
3894
3898
|
__Pyx_GOTREF(__pyx_t_1);
|
|
@@ -3922,8 +3926,12 @@ static PyObject *__pyx_f_9fontTools_5qu2cu_5qu2cu_merge_curves(PyObject *__pyx_v
|
|
|
3922
3926
|
__pyx_t_14 = __Pyx_c_diff_double(__pyx_v_p2, __pyx_v_p3);
|
|
3923
3927
|
__pyx_t_1 = __pyx_PyComplex_FromComplex(__pyx_t_14); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 147, __pyx_L1_error)
|
|
3924
3928
|
__Pyx_GOTREF(__pyx_t_1);
|
|
3925
|
-
|
|
3926
|
-
|
|
3929
|
+
{
|
|
3930
|
+
Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_v_ts);
|
|
3931
|
+
if (unlikely(((!CYTHON_ASSUME_SAFE_SIZE) && __pyx_temp < 0))) __PYX_ERR(0, 147, __pyx_L1_error)
|
|
3932
|
+
__pyx_t_9 = (__pyx_temp != 0);
|
|
3933
|
+
}
|
|
3934
|
+
|
|
3927
3935
|
if (__pyx_t_9) {
|
|
3928
3936
|
__pyx_t_7 = __Pyx_GetItemInt_List(__pyx_v_ts, -1L, long, 1, __Pyx_PyLong_From_long, 1, 1, 1, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 147, __pyx_L1_error)
|
|
3929
3937
|
__Pyx_GOTREF(__pyx_t_7);
|
|
@@ -12271,6 +12279,7 @@ static int __pyx_CommonTypesMetaclass_init(PyObject *module) {
|
|
|
12271
12279
|
return -1;
|
|
12272
12280
|
}
|
|
12273
12281
|
mstate->__pyx_CommonTypesMetaclassType = __Pyx_FetchCommonTypeFromSpec(NULL, module, &__pyx_CommonTypesMetaclass_spec, bases);
|
|
12282
|
+
Py_DECREF(bases);
|
|
12274
12283
|
if (unlikely(mstate->__pyx_CommonTypesMetaclassType == NULL)) {
|
|
12275
12284
|
return -1;
|
|
12276
12285
|
}
|
|
@@ -16098,6 +16107,10 @@ static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt
|
|
|
16098
16107
|
PyCode_NewWithPosOnlyArgs
|
|
16099
16108
|
#endif
|
|
16100
16109
|
(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, __pyx_mstate_global->__pyx_empty_bytes);
|
|
16110
|
+
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030c00A1
|
|
16111
|
+
if (likely(result))
|
|
16112
|
+
result->_co_firsttraceable = 0;
|
|
16113
|
+
#endif
|
|
16101
16114
|
return result;
|
|
16102
16115
|
}
|
|
16103
16116
|
#elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY
|
|
Binary file
|
fontTools/subset/__init__.py
CHANGED
|
@@ -272,7 +272,7 @@ Font table options
|
|
|
272
272
|
Specify (=), add to (+=) or exclude from (-=) the comma-separated
|
|
273
273
|
set of tables that will be be dropped.
|
|
274
274
|
By default, the following tables are dropped:
|
|
275
|
-
'
|
|
275
|
+
'JSTF', 'DSIG', 'EBDT', 'EBLC', 'EBSC', 'PCLT', 'LTSH'
|
|
276
276
|
and Graphite tables: 'Feat', 'Glat', 'Gloc', 'Silf', 'Sill'.
|
|
277
277
|
The tool will attempt to subset the remaining tables.
|
|
278
278
|
|
|
@@ -827,13 +827,26 @@ def subset_glyphs(self, s):
|
|
|
827
827
|
self.MarkArray.MarkRecord, mark_indices
|
|
828
828
|
)
|
|
829
829
|
self.MarkArray.MarkCount = len(self.MarkArray.MarkRecord)
|
|
830
|
-
|
|
830
|
+
class_indices = _uniq_sort(v.Class for v in self.MarkArray.MarkRecord)
|
|
831
|
+
|
|
832
|
+
intersect_base_indices = self.BaseCoverage.intersect(s.glyphs)
|
|
833
|
+
base_records = self.BaseArray.BaseRecord
|
|
834
|
+
num_base_records = len(base_records)
|
|
835
|
+
base_indices = [
|
|
836
|
+
i
|
|
837
|
+
for i in intersect_base_indices
|
|
838
|
+
if i < num_base_records
|
|
839
|
+
and any(base_records[i].BaseAnchor[j] is not None for j in class_indices)
|
|
840
|
+
]
|
|
841
|
+
if not base_indices:
|
|
842
|
+
return False
|
|
843
|
+
|
|
844
|
+
self.BaseCoverage.remap(base_indices)
|
|
831
845
|
self.BaseArray.BaseRecord = _list_subset(
|
|
832
846
|
self.BaseArray.BaseRecord, base_indices
|
|
833
847
|
)
|
|
834
848
|
self.BaseArray.BaseCount = len(self.BaseArray.BaseRecord)
|
|
835
849
|
# Prune empty classes
|
|
836
|
-
class_indices = _uniq_sort(v.Class for v in self.MarkArray.MarkRecord)
|
|
837
850
|
self.ClassCount = len(class_indices)
|
|
838
851
|
for m in self.MarkArray.MarkRecord:
|
|
839
852
|
m.Class = class_indices.index(m.Class)
|
|
@@ -867,13 +880,31 @@ def subset_glyphs(self, s):
|
|
|
867
880
|
self.MarkArray.MarkRecord, mark_indices
|
|
868
881
|
)
|
|
869
882
|
self.MarkArray.MarkCount = len(self.MarkArray.MarkRecord)
|
|
870
|
-
|
|
883
|
+
class_indices = _uniq_sort(v.Class for v in self.MarkArray.MarkRecord)
|
|
884
|
+
|
|
885
|
+
intersect_ligature_indices = self.LigatureCoverage.intersect(s.glyphs)
|
|
886
|
+
ligature_array = self.LigatureArray.LigatureAttach
|
|
887
|
+
num_ligatures = self.LigatureArray.LigatureCount
|
|
888
|
+
|
|
889
|
+
ligature_indices = [
|
|
890
|
+
i
|
|
891
|
+
for i in intersect_ligature_indices
|
|
892
|
+
if i < num_ligatures
|
|
893
|
+
and any(
|
|
894
|
+
any(component.LigatureAnchor[j] is not None for j in class_indices)
|
|
895
|
+
for component in ligature_array[i].ComponentRecord
|
|
896
|
+
)
|
|
897
|
+
]
|
|
898
|
+
|
|
899
|
+
if not ligature_indices:
|
|
900
|
+
return False
|
|
901
|
+
|
|
902
|
+
self.LigatureCoverage.remap(ligature_indices)
|
|
871
903
|
self.LigatureArray.LigatureAttach = _list_subset(
|
|
872
904
|
self.LigatureArray.LigatureAttach, ligature_indices
|
|
873
905
|
)
|
|
874
906
|
self.LigatureArray.LigatureCount = len(self.LigatureArray.LigatureAttach)
|
|
875
907
|
# Prune empty classes
|
|
876
|
-
class_indices = _uniq_sort(v.Class for v in self.MarkArray.MarkRecord)
|
|
877
908
|
self.ClassCount = len(class_indices)
|
|
878
909
|
for m in self.MarkArray.MarkRecord:
|
|
879
910
|
m.Class = class_indices.index(m.Class)
|
|
@@ -915,13 +946,26 @@ def subset_glyphs(self, s):
|
|
|
915
946
|
self.Mark1Array.MarkRecord, mark1_indices
|
|
916
947
|
)
|
|
917
948
|
self.Mark1Array.MarkCount = len(self.Mark1Array.MarkRecord)
|
|
918
|
-
|
|
949
|
+
class_indices = _uniq_sort(v.Class for v in self.Mark1Array.MarkRecord)
|
|
950
|
+
|
|
951
|
+
intersect_mark2_indices = self.Mark2Coverage.intersect(s.glyphs)
|
|
952
|
+
mark2_records = self.Mark2Array.Mark2Record
|
|
953
|
+
num_mark2_records = len(mark2_records)
|
|
954
|
+
mark2_indices = [
|
|
955
|
+
i
|
|
956
|
+
for i in intersect_mark2_indices
|
|
957
|
+
if i < num_mark2_records
|
|
958
|
+
and any(mark2_records[i].Mark2Anchor[j] is not None for j in class_indices)
|
|
959
|
+
]
|
|
960
|
+
if not mark2_indices:
|
|
961
|
+
return False
|
|
962
|
+
|
|
963
|
+
self.Mark2Coverage.remap(mark2_indices)
|
|
919
964
|
self.Mark2Array.Mark2Record = _list_subset(
|
|
920
965
|
self.Mark2Array.Mark2Record, mark2_indices
|
|
921
966
|
)
|
|
922
967
|
self.Mark2Array.MarkCount = len(self.Mark2Array.Mark2Record)
|
|
923
968
|
# Prune empty classes
|
|
924
|
-
class_indices = _uniq_sort(v.Class for v in self.Mark1Array.MarkRecord)
|
|
925
969
|
self.ClassCount = len(class_indices)
|
|
926
970
|
for m in self.Mark1Array.MarkRecord:
|
|
927
971
|
m.Class = class_indices.index(m.Class)
|
|
@@ -1717,6 +1761,19 @@ def subset_features(self, feature_indices):
|
|
|
1717
1761
|
return bool(self.SubstitutionCount)
|
|
1718
1762
|
|
|
1719
1763
|
|
|
1764
|
+
@_add_method(otTables.FeatureTableSubstitution)
|
|
1765
|
+
def prune_features(self, feature_index_map):
|
|
1766
|
+
self.ensureDecompiled()
|
|
1767
|
+
self.SubstitutionRecord = [
|
|
1768
|
+
r for r in self.SubstitutionRecord if r.FeatureIndex in feature_index_map.keys()
|
|
1769
|
+
]
|
|
1770
|
+
# remap feature indices
|
|
1771
|
+
for r in self.SubstitutionRecord:
|
|
1772
|
+
r.FeatureIndex = feature_index_map[r.FeatureIndex]
|
|
1773
|
+
self.SubstitutionCount = len(self.SubstitutionRecord)
|
|
1774
|
+
return bool(self.SubstitutionCount)
|
|
1775
|
+
|
|
1776
|
+
|
|
1720
1777
|
@_add_method(otTables.FeatureVariations)
|
|
1721
1778
|
def subset_features(self, feature_indices):
|
|
1722
1779
|
self.ensureDecompiled()
|
|
@@ -1735,6 +1792,24 @@ def subset_features(self, feature_indices):
|
|
|
1735
1792
|
return bool(self.FeatureVariationCount)
|
|
1736
1793
|
|
|
1737
1794
|
|
|
1795
|
+
@_add_method(otTables.FeatureVariations)
|
|
1796
|
+
def prune_features(self, feature_index_map):
|
|
1797
|
+
self.ensureDecompiled()
|
|
1798
|
+
for r in self.FeatureVariationRecord:
|
|
1799
|
+
r.FeatureTableSubstitution.prune_features(feature_index_map)
|
|
1800
|
+
# Prune empty records at the end only
|
|
1801
|
+
# https://github.com/fonttools/fonttools/issues/1881
|
|
1802
|
+
while (
|
|
1803
|
+
self.FeatureVariationRecord
|
|
1804
|
+
and not self.FeatureVariationRecord[
|
|
1805
|
+
-1
|
|
1806
|
+
].FeatureTableSubstitution.SubstitutionCount
|
|
1807
|
+
):
|
|
1808
|
+
self.FeatureVariationRecord.pop()
|
|
1809
|
+
self.FeatureVariationCount = len(self.FeatureVariationRecord)
|
|
1810
|
+
return bool(self.FeatureVariationCount)
|
|
1811
|
+
|
|
1812
|
+
|
|
1738
1813
|
@_add_method(otTables.DefaultLangSys, otTables.LangSys)
|
|
1739
1814
|
def subset_features(self, feature_indices):
|
|
1740
1815
|
if self.ReqFeatureIndex in feature_indices:
|
|
@@ -1750,6 +1825,16 @@ def subset_features(self, feature_indices):
|
|
|
1750
1825
|
return bool(self.FeatureCount or self.ReqFeatureIndex != 65535)
|
|
1751
1826
|
|
|
1752
1827
|
|
|
1828
|
+
@_add_method(otTables.DefaultLangSys, otTables.LangSys)
|
|
1829
|
+
def prune_features(self, feature_index_map):
|
|
1830
|
+
self.ReqFeatureIndex = feature_index_map.get(self.ReqFeatureIndex, 65535)
|
|
1831
|
+
self.FeatureIndex = [
|
|
1832
|
+
feature_index_map[f] for f in self.FeatureIndex if f in feature_index_map.keys()
|
|
1833
|
+
]
|
|
1834
|
+
self.FeatureCount = len(self.FeatureIndex)
|
|
1835
|
+
return bool(self.FeatureCount or self.ReqFeatureIndex != 65535)
|
|
1836
|
+
|
|
1837
|
+
|
|
1753
1838
|
@_add_method(otTables.DefaultLangSys, otTables.LangSys)
|
|
1754
1839
|
def collect_features(self):
|
|
1755
1840
|
feature_indices = self.FeatureIndex[:]
|
|
@@ -1773,6 +1858,21 @@ def subset_features(self, feature_indices, keepEmptyDefaultLangSys=False):
|
|
|
1773
1858
|
return bool(self.LangSysCount or self.DefaultLangSys)
|
|
1774
1859
|
|
|
1775
1860
|
|
|
1861
|
+
@_add_method(otTables.Script)
|
|
1862
|
+
def prune_features(self, feature_index_map, keepEmptyDefaultLangSys=False):
|
|
1863
|
+
if (
|
|
1864
|
+
self.DefaultLangSys
|
|
1865
|
+
and not self.DefaultLangSys.prune_features(feature_index_map)
|
|
1866
|
+
and not keepEmptyDefaultLangSys
|
|
1867
|
+
):
|
|
1868
|
+
self.DefaultLangSys = None
|
|
1869
|
+
self.LangSysRecord = [
|
|
1870
|
+
l for l in self.LangSysRecord if l.LangSys.prune_features(feature_index_map)
|
|
1871
|
+
]
|
|
1872
|
+
self.LangSysCount = len(self.LangSysRecord)
|
|
1873
|
+
return bool(self.LangSysCount or self.DefaultLangSys)
|
|
1874
|
+
|
|
1875
|
+
|
|
1776
1876
|
@_add_method(otTables.Script)
|
|
1777
1877
|
def collect_features(self):
|
|
1778
1878
|
feature_indices = [l.LangSys.collect_features() for l in self.LangSysRecord]
|
|
@@ -1794,6 +1894,19 @@ def subset_features(self, feature_indices, retain_empty):
|
|
|
1794
1894
|
return bool(self.ScriptCount)
|
|
1795
1895
|
|
|
1796
1896
|
|
|
1897
|
+
@_add_method(otTables.ScriptList)
|
|
1898
|
+
def prune_features(self, feature_index_map, retain_empty):
|
|
1899
|
+
# https://bugzilla.mozilla.org/show_bug.cgi?id=1331737#c32
|
|
1900
|
+
self.ScriptRecord = [
|
|
1901
|
+
s
|
|
1902
|
+
for s in self.ScriptRecord
|
|
1903
|
+
if s.Script.prune_features(feature_index_map, s.ScriptTag == "DFLT")
|
|
1904
|
+
or retain_empty
|
|
1905
|
+
]
|
|
1906
|
+
self.ScriptCount = len(self.ScriptRecord)
|
|
1907
|
+
return bool(self.ScriptCount)
|
|
1908
|
+
|
|
1909
|
+
|
|
1797
1910
|
@_add_method(otTables.ScriptList)
|
|
1798
1911
|
def collect_features(self):
|
|
1799
1912
|
return _uniq_sort(sum((s.Script.collect_features() for s in self.ScriptRecord), []))
|
|
@@ -1981,21 +2094,74 @@ def subset_script_tags(self, tags):
|
|
|
1981
2094
|
|
|
1982
2095
|
@_add_method(ttLib.getTableClass("GSUB"), ttLib.getTableClass("GPOS"))
|
|
1983
2096
|
def prune_features(self):
|
|
1984
|
-
"""Remove unreferenced features
|
|
2097
|
+
"""Remove unreferenced and duplicate features in FeatureList
|
|
2098
|
+
Remove unreferenced features and remap duplicate feature indices in ScriptList and FeatureVariations
|
|
2099
|
+
"""
|
|
1985
2100
|
if self.table.ScriptList:
|
|
1986
2101
|
feature_indices = self.table.ScriptList.collect_features()
|
|
1987
2102
|
else:
|
|
1988
2103
|
feature_indices = []
|
|
2104
|
+
(feature_indices, feature_index_map) = self.remap_duplicate_features(
|
|
2105
|
+
feature_indices
|
|
2106
|
+
)
|
|
2107
|
+
|
|
1989
2108
|
if self.table.FeatureList:
|
|
1990
2109
|
self.table.FeatureList.subset_features(feature_indices)
|
|
1991
2110
|
if getattr(self.table, "FeatureVariations", None):
|
|
1992
|
-
self.table.FeatureVariations.
|
|
2111
|
+
self.table.FeatureVariations.prune_features(feature_index_map)
|
|
1993
2112
|
if self.table.ScriptList:
|
|
1994
|
-
self.table.ScriptList.
|
|
1995
|
-
|
|
2113
|
+
self.table.ScriptList.prune_features(
|
|
2114
|
+
feature_index_map, self.retain_empty_scripts()
|
|
1996
2115
|
)
|
|
1997
2116
|
|
|
1998
2117
|
|
|
2118
|
+
@_add_method(ttLib.getTableClass("GSUB"), ttLib.getTableClass("GPOS"))
|
|
2119
|
+
def remap_duplicate_features(self, feature_indices):
|
|
2120
|
+
"""Return retained feature indices(without duplicates) and remapped feature indices"""
|
|
2121
|
+
features = self.table.FeatureList.FeatureRecord
|
|
2122
|
+
|
|
2123
|
+
unique_features = {}
|
|
2124
|
+
duplicate_features = {}
|
|
2125
|
+
for i in feature_indices:
|
|
2126
|
+
f = features[i]
|
|
2127
|
+
tag = f.FeatureTag
|
|
2128
|
+
|
|
2129
|
+
same_tag_features = unique_features.get(tag)
|
|
2130
|
+
if same_tag_features is None:
|
|
2131
|
+
unique_features[tag] = set([i])
|
|
2132
|
+
duplicate_features[i] = i
|
|
2133
|
+
continue
|
|
2134
|
+
|
|
2135
|
+
found = False
|
|
2136
|
+
for other_i in same_tag_features:
|
|
2137
|
+
if features[other_i] == f:
|
|
2138
|
+
found = True
|
|
2139
|
+
duplicate_features[i] = other_i
|
|
2140
|
+
break
|
|
2141
|
+
|
|
2142
|
+
if not found:
|
|
2143
|
+
same_tag_features.add(i)
|
|
2144
|
+
duplicate_features[i] = i
|
|
2145
|
+
|
|
2146
|
+
## remap retained feature indices
|
|
2147
|
+
feature_map = {}
|
|
2148
|
+
new_idx = 0
|
|
2149
|
+
|
|
2150
|
+
for i in feature_indices:
|
|
2151
|
+
unique_i = duplicate_features.get(i, i)
|
|
2152
|
+
v = feature_map.get(unique_i)
|
|
2153
|
+
if v is None:
|
|
2154
|
+
feature_map[i] = new_idx
|
|
2155
|
+
new_idx += 1
|
|
2156
|
+
else:
|
|
2157
|
+
feature_map[i] = v
|
|
2158
|
+
|
|
2159
|
+
retained_feature_indices = _uniq_sort(
|
|
2160
|
+
sum((list(s) for s in unique_features.values()), [])
|
|
2161
|
+
)
|
|
2162
|
+
return (retained_feature_indices, feature_map)
|
|
2163
|
+
|
|
2164
|
+
|
|
1999
2165
|
@_add_method(ttLib.getTableClass("GSUB"), ttLib.getTableClass("GPOS"))
|
|
2000
2166
|
def prune_pre_subset(self, font, options):
|
|
2001
2167
|
# Drop undesired features
|
|
@@ -3145,7 +3311,6 @@ class Options(object):
|
|
|
3145
3311
|
|
|
3146
3312
|
# spaces in tag names (e.g. "SVG ", "cvt ") are stripped by the argument parser
|
|
3147
3313
|
_drop_tables_default = [
|
|
3148
|
-
"BASE",
|
|
3149
3314
|
"JSTF",
|
|
3150
3315
|
"DSIG",
|
|
3151
3316
|
"EBDT",
|
|
@@ -3157,6 +3322,7 @@ class Options(object):
|
|
|
3157
3322
|
_drop_tables_default += ["Feat", "Glat", "Gloc", "Silf", "Sill"] # Graphite
|
|
3158
3323
|
_no_subset_tables_default = [
|
|
3159
3324
|
"avar",
|
|
3325
|
+
"BASE",
|
|
3160
3326
|
"fvar",
|
|
3161
3327
|
"gasp",
|
|
3162
3328
|
"head",
|
|
@@ -118,6 +118,7 @@ class table__p_o_s_t(DefaultTable.DefaultTable):
|
|
|
118
118
|
def build_psNameMapping(self, ttFont):
|
|
119
119
|
mapping = {}
|
|
120
120
|
allNames = {}
|
|
121
|
+
glyphOrderNames = set(self.glyphOrder)
|
|
121
122
|
for i in range(ttFont["maxp"].numGlyphs):
|
|
122
123
|
glyphName = psName = self.glyphOrder[i]
|
|
123
124
|
if glyphName == "":
|
|
@@ -126,16 +127,15 @@ class table__p_o_s_t(DefaultTable.DefaultTable):
|
|
|
126
127
|
if glyphName in allNames:
|
|
127
128
|
# make up a new glyphName that's unique
|
|
128
129
|
n = allNames[glyphName]
|
|
129
|
-
# check if the exists in
|
|
130
|
-
|
|
131
|
-
while (glyphName + "." + str(n)) in names:
|
|
130
|
+
# check if the glyph name exists in the glyph order
|
|
131
|
+
while f"{glyphName}.{n}" in glyphOrderNames:
|
|
132
132
|
n += 1
|
|
133
133
|
allNames[glyphName] = n + 1
|
|
134
|
-
glyphName = glyphName
|
|
134
|
+
glyphName = f"{glyphName}.{n}"
|
|
135
135
|
|
|
136
|
-
self.glyphOrder[i] = glyphName
|
|
137
136
|
allNames[glyphName] = 1
|
|
138
137
|
if glyphName != psName:
|
|
138
|
+
self.glyphOrder[i] = glyphName
|
|
139
139
|
mapping[glyphName] = psName
|
|
140
140
|
|
|
141
141
|
self.mapping = mapping
|