fonttools 4.56.0__cp39-cp39-macosx_10_9_universal2.whl → 4.58.0__cp39-cp39-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/__init__.py +61 -26
- fontTools/config/__init__.py +15 -0
- fontTools/cu2qu/cu2qu.c +4563 -4047
- fontTools/cu2qu/cu2qu.cpython-39-darwin.so +0 -0
- fontTools/designspaceLib/statNames.py +14 -7
- fontTools/feaLib/ast.py +92 -13
- fontTools/feaLib/builder.py +52 -13
- fontTools/feaLib/lexer.c +6268 -7111
- fontTools/feaLib/lexer.cpython-39-darwin.so +0 -0
- fontTools/feaLib/parser.py +59 -39
- fontTools/fontBuilder.py +6 -0
- fontTools/misc/bezierTools.c +13479 -15374
- fontTools/misc/bezierTools.cpython-39-darwin.so +0 -0
- fontTools/misc/etree.py +4 -27
- fontTools/misc/testTools.py +2 -1
- fontTools/mtiLib/__init__.py +0 -2
- fontTools/otlLib/builder.py +195 -145
- fontTools/otlLib/optimize/gpos.py +49 -63
- fontTools/pens/momentsPen.c +4492 -4674
- fontTools/pens/momentsPen.cpython-39-darwin.so +0 -0
- fontTools/pens/pointPen.py +21 -12
- fontTools/qu2cu/qu2cu.c +5727 -5458
- fontTools/qu2cu/qu2cu.cpython-39-darwin.so +0 -0
- fontTools/subset/__init__.py +11 -0
- fontTools/ttLib/__init__.py +4 -0
- fontTools/ttLib/__main__.py +47 -8
- fontTools/ttLib/tables/D__e_b_g.py +20 -2
- fontTools/ttLib/tables/G_V_A_R_.py +5 -0
- fontTools/ttLib/tables/T_S_I__0.py +14 -3
- fontTools/ttLib/tables/T_S_I__5.py +16 -5
- fontTools/ttLib/tables/__init__.py +1 -0
- fontTools/ttLib/tables/_c_m_a_p.py +19 -6
- fontTools/ttLib/tables/_c_v_t.py +2 -0
- fontTools/ttLib/tables/_f_p_g_m.py +3 -1
- fontTools/ttLib/tables/_g_l_y_f.py +11 -10
- fontTools/ttLib/tables/_g_v_a_r.py +62 -17
- fontTools/ttLib/tables/_p_o_s_t.py +5 -2
- fontTools/ttLib/tables/otBase.py +1 -0
- fontTools/ttLib/tables/otConverters.py +5 -2
- fontTools/ttLib/tables/otTables.py +5 -1
- fontTools/ttLib/ttFont.py +3 -5
- fontTools/ttLib/ttGlyphSet.py +0 -10
- fontTools/ttx.py +13 -1
- fontTools/ufoLib/__init__.py +2 -2
- fontTools/ufoLib/converters.py +89 -25
- fontTools/ufoLib/errors.py +8 -0
- fontTools/ufoLib/etree.py +1 -1
- fontTools/ufoLib/filenames.py +155 -100
- fontTools/ufoLib/glifLib.py +9 -2
- fontTools/ufoLib/kerning.py +66 -36
- fontTools/ufoLib/utils.py +5 -2
- fontTools/unicodedata/Mirrored.py +446 -0
- fontTools/unicodedata/__init__.py +6 -2
- fontTools/varLib/__init__.py +94 -89
- fontTools/varLib/hvar.py +113 -0
- fontTools/varLib/iup.c +6700 -6224
- fontTools/varLib/iup.cpython-39-darwin.so +0 -0
- fontTools/varLib/varStore.py +1 -1
- fontTools/voltLib/__main__.py +206 -0
- fontTools/voltLib/ast.py +4 -0
- fontTools/voltLib/parser.py +16 -8
- fontTools/voltLib/voltToFea.py +347 -166
- {fonttools-4.56.0.dist-info → fonttools-4.58.0.dist-info}/METADATA +60 -12
- {fonttools-4.56.0.dist-info → fonttools-4.58.0.dist-info}/RECORD +71 -66
- {fonttools-4.56.0.dist-info → fonttools-4.58.0.dist-info}/WHEEL +2 -1
- fonttools-4.58.0.dist-info/licenses/LICENSE.external +359 -0
- {fonttools-4.56.0.data → fonttools-4.58.0.data}/data/share/man/man1/ttx.1 +0 -0
- {fonttools-4.56.0.dist-info → fonttools-4.58.0.dist-info}/entry_points.txt +0 -0
- {fonttools-4.56.0.dist-info → fonttools-4.58.0.dist-info/licenses}/LICENSE +0 -0
- {fonttools-4.56.0.dist-info → fonttools-4.58.0.dist-info}/top_level.txt +0 -0
|
Binary file
|
|
@@ -12,14 +12,13 @@ instance:
|
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
14
|
from dataclasses import dataclass
|
|
15
|
-
from typing import Dict, Optional, Tuple, Union
|
|
15
|
+
from typing import Dict, Literal, Optional, Tuple, Union
|
|
16
16
|
import logging
|
|
17
17
|
|
|
18
18
|
from fontTools.designspaceLib import (
|
|
19
19
|
AxisDescriptor,
|
|
20
20
|
AxisLabelDescriptor,
|
|
21
21
|
DesignSpaceDocument,
|
|
22
|
-
DesignSpaceDocumentError,
|
|
23
22
|
DiscreteAxisDescriptor,
|
|
24
23
|
SimpleLocationDict,
|
|
25
24
|
SourceDescriptor,
|
|
@@ -27,9 +26,13 @@ from fontTools.designspaceLib import (
|
|
|
27
26
|
|
|
28
27
|
LOGGER = logging.getLogger(__name__)
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
RibbiStyleName = Union[
|
|
30
|
+
Literal["regular"],
|
|
31
|
+
Literal["bold"],
|
|
32
|
+
Literal["italic"],
|
|
33
|
+
Literal["bold italic"],
|
|
34
|
+
]
|
|
35
|
+
|
|
33
36
|
BOLD_ITALIC_TO_RIBBI_STYLE = {
|
|
34
37
|
(False, False): "regular",
|
|
35
38
|
(False, True): "italic",
|
|
@@ -46,7 +49,7 @@ class StatNames:
|
|
|
46
49
|
styleNames: Dict[str, str]
|
|
47
50
|
postScriptFontName: Optional[str]
|
|
48
51
|
styleMapFamilyNames: Dict[str, str]
|
|
49
|
-
styleMapStyleName: Optional[
|
|
52
|
+
styleMapStyleName: Optional[RibbiStyleName]
|
|
50
53
|
|
|
51
54
|
|
|
52
55
|
def getStatNames(
|
|
@@ -61,6 +64,10 @@ def getStatNames(
|
|
|
61
64
|
localized names will be empty (family and style names), or the name will be
|
|
62
65
|
None (PostScript name).
|
|
63
66
|
|
|
67
|
+
Note: this method does not consider info attached to the instance, like
|
|
68
|
+
family name. The user needs to override all names on an instance that STAT
|
|
69
|
+
information would compute differently than desired.
|
|
70
|
+
|
|
64
71
|
.. versionadded:: 5.0
|
|
65
72
|
"""
|
|
66
73
|
familyNames: Dict[str, str] = {}
|
|
@@ -201,7 +208,7 @@ def _getAxisLabelsForUserLocation(
|
|
|
201
208
|
|
|
202
209
|
def _getRibbiStyle(
|
|
203
210
|
self: DesignSpaceDocument, userLocation: SimpleLocationDict
|
|
204
|
-
) -> Tuple[
|
|
211
|
+
) -> Tuple[RibbiStyleName, SimpleLocationDict]:
|
|
205
212
|
"""Compute the RIBBI style name of the given user location,
|
|
206
213
|
return the location of the matching Regular in the RIBBI group.
|
|
207
214
|
|
fontTools/feaLib/ast.py
CHANGED
|
@@ -337,6 +337,76 @@ class AnonymousBlock(Statement):
|
|
|
337
337
|
return res
|
|
338
338
|
|
|
339
339
|
|
|
340
|
+
def _upgrade_mixed_subst_statements(statements):
|
|
341
|
+
# https://github.com/fonttools/fonttools/issues/612
|
|
342
|
+
# A multiple substitution may have a single destination, in which case
|
|
343
|
+
# it will look just like a single substitution. So if there are both
|
|
344
|
+
# multiple and single substitutions, upgrade all the single ones to
|
|
345
|
+
# multiple substitutions. Similarly, a ligature substitution may have a
|
|
346
|
+
# single source glyph, so if there are both ligature and single
|
|
347
|
+
# substitutions, upgrade all the single ones to ligature substitutions.
|
|
348
|
+
|
|
349
|
+
has_single = False
|
|
350
|
+
has_multiple = False
|
|
351
|
+
has_ligature = False
|
|
352
|
+
for s in statements:
|
|
353
|
+
if isinstance(s, SingleSubstStatement):
|
|
354
|
+
has_single = not any([s.prefix, s.suffix, s.forceChain])
|
|
355
|
+
elif isinstance(s, MultipleSubstStatement):
|
|
356
|
+
has_multiple = not any([s.prefix, s.suffix, s.forceChain])
|
|
357
|
+
elif isinstance(s, LigatureSubstStatement):
|
|
358
|
+
has_ligature = not any([s.prefix, s.suffix, s.forceChain])
|
|
359
|
+
|
|
360
|
+
to_multiple = False
|
|
361
|
+
to_ligature = False
|
|
362
|
+
|
|
363
|
+
# If we have mixed single and multiple substitutions,
|
|
364
|
+
# upgrade all single substitutions to multiple substitutions.
|
|
365
|
+
if has_single and has_multiple and not has_ligature:
|
|
366
|
+
to_multiple = True
|
|
367
|
+
|
|
368
|
+
# If we have mixed single and ligature substitutions,
|
|
369
|
+
# upgrade all single substitutions to ligature substitutions.
|
|
370
|
+
elif has_single and has_ligature and not has_multiple:
|
|
371
|
+
to_ligature = True
|
|
372
|
+
|
|
373
|
+
if to_multiple or to_ligature:
|
|
374
|
+
ret = []
|
|
375
|
+
for s in statements:
|
|
376
|
+
if isinstance(s, SingleSubstStatement):
|
|
377
|
+
glyphs = s.glyphs[0].glyphSet()
|
|
378
|
+
replacements = s.replacements[0].glyphSet()
|
|
379
|
+
if len(replacements) == 1:
|
|
380
|
+
replacements *= len(glyphs)
|
|
381
|
+
for glyph, replacement in zip(glyphs, replacements):
|
|
382
|
+
if to_multiple:
|
|
383
|
+
ret.append(
|
|
384
|
+
MultipleSubstStatement(
|
|
385
|
+
s.prefix,
|
|
386
|
+
glyph,
|
|
387
|
+
s.suffix,
|
|
388
|
+
[replacement],
|
|
389
|
+
s.forceChain,
|
|
390
|
+
location=s.location,
|
|
391
|
+
)
|
|
392
|
+
)
|
|
393
|
+
elif to_ligature:
|
|
394
|
+
ret.append(
|
|
395
|
+
LigatureSubstStatement(
|
|
396
|
+
s.prefix,
|
|
397
|
+
[GlyphName(glyph)],
|
|
398
|
+
s.suffix,
|
|
399
|
+
replacement,
|
|
400
|
+
s.forceChain,
|
|
401
|
+
location=s.location,
|
|
402
|
+
)
|
|
403
|
+
)
|
|
404
|
+
else:
|
|
405
|
+
ret.append(s)
|
|
406
|
+
return ret
|
|
407
|
+
return statements
|
|
408
|
+
|
|
409
|
+
|
|
340
410
|
class Block(Statement):
|
|
341
411
|
"""A block of statements: feature, lookup, etc."""
|
|
342
412
|
|
|
@@ -348,7 +418,8 @@ class Block(Statement):
|
|
|
348
418
|
"""When handed a 'builder' object of comparable interface to
|
|
349
419
|
:class:`fontTools.feaLib.builder`, walks the statements in this
|
|
350
420
|
block, calling the builder callbacks."""
|
|
351
|
-
|
|
421
|
+
statements = _upgrade_mixed_subst_statements(self.statements)
|
|
422
|
+
for s in statements:
|
|
352
423
|
s.build(builder)
|
|
353
424
|
|
|
354
425
|
def asFea(self, indent=""):
|
|
@@ -382,8 +453,7 @@ class FeatureBlock(Block):
|
|
|
382
453
|
def build(self, builder):
|
|
383
454
|
"""Call the ``start_feature`` callback on the builder object, visit
|
|
384
455
|
all the statements in this feature, and then call ``end_feature``."""
|
|
385
|
-
|
|
386
|
-
builder.start_feature(self.location, self.name)
|
|
456
|
+
builder.start_feature(self.location, self.name, self.use_extension)
|
|
387
457
|
# language exclude_dflt statements modify builder.features_
|
|
388
458
|
# limit them to this block with temporary builder.features_
|
|
389
459
|
features = builder.features_
|
|
@@ -433,8 +503,7 @@ class LookupBlock(Block):
|
|
|
433
503
|
self.name, self.use_extension = name, use_extension
|
|
434
504
|
|
|
435
505
|
def build(self, builder):
|
|
436
|
-
|
|
437
|
-
builder.start_lookup_block(self.location, self.name)
|
|
506
|
+
builder.start_lookup_block(self.location, self.name, self.use_extension)
|
|
438
507
|
Block.build(self, builder)
|
|
439
508
|
builder.end_lookup_block()
|
|
440
509
|
|
|
@@ -753,7 +822,7 @@ class ChainContextPosStatement(Statement):
|
|
|
753
822
|
if len(self.suffix):
|
|
754
823
|
res += " " + " ".join(map(asFea, self.suffix))
|
|
755
824
|
else:
|
|
756
|
-
res += " ".join(map(asFea, self.
|
|
825
|
+
res += " ".join(map(asFea, self.glyphs))
|
|
757
826
|
res += ";"
|
|
758
827
|
return res
|
|
759
828
|
|
|
@@ -811,7 +880,7 @@ class ChainContextSubstStatement(Statement):
|
|
|
811
880
|
if len(self.suffix):
|
|
812
881
|
res += " " + " ".join(map(asFea, self.suffix))
|
|
813
882
|
else:
|
|
814
|
-
res += " ".join(map(asFea, self.
|
|
883
|
+
res += " ".join(map(asFea, self.glyphs))
|
|
815
884
|
res += ";"
|
|
816
885
|
return res
|
|
817
886
|
|
|
@@ -1512,7 +1581,9 @@ class SinglePosStatement(Statement):
|
|
|
1512
1581
|
res += " ".join(map(asFea, self.prefix)) + " "
|
|
1513
1582
|
res += " ".join(
|
|
1514
1583
|
[
|
|
1515
|
-
asFea(x[0])
|
|
1584
|
+
asFea(x[0])
|
|
1585
|
+
+ "'"
|
|
1586
|
+
+ ((" " + x[1].asFea()) if x[1] is not None else "")
|
|
1516
1587
|
for x in self.pos
|
|
1517
1588
|
]
|
|
1518
1589
|
)
|
|
@@ -1520,7 +1591,10 @@ class SinglePosStatement(Statement):
|
|
|
1520
1591
|
res += " " + " ".join(map(asFea, self.suffix))
|
|
1521
1592
|
else:
|
|
1522
1593
|
res += " ".join(
|
|
1523
|
-
[
|
|
1594
|
+
[
|
|
1595
|
+
asFea(x[0]) + " " + (x[1].asFea() if x[1] is not None else "")
|
|
1596
|
+
for x in self.pos
|
|
1597
|
+
]
|
|
1524
1598
|
)
|
|
1525
1599
|
res += ";"
|
|
1526
1600
|
return res
|
|
@@ -1828,15 +1902,16 @@ class BaseAxis(Statement):
|
|
|
1828
1902
|
"""An axis definition, being either a ``VertAxis.BaseTagList/BaseScriptList``
|
|
1829
1903
|
pair or a ``HorizAxis.BaseTagList/BaseScriptList`` pair."""
|
|
1830
1904
|
|
|
1831
|
-
def __init__(self, bases, scripts, vertical, location=None):
|
|
1905
|
+
def __init__(self, bases, scripts, vertical, minmax=None, location=None):
|
|
1832
1906
|
Statement.__init__(self, location)
|
|
1833
1907
|
self.bases = bases #: A list of baseline tag names as strings
|
|
1834
1908
|
self.scripts = scripts #: A list of script record tuplets (script tag, default baseline tag, base coordinate)
|
|
1835
1909
|
self.vertical = vertical #: Boolean; VertAxis if True, HorizAxis if False
|
|
1910
|
+
self.minmax = [] #: A set of minmax record
|
|
1836
1911
|
|
|
1837
1912
|
def build(self, builder):
|
|
1838
1913
|
"""Calls the builder object's ``set_base_axis`` callback."""
|
|
1839
|
-
builder.set_base_axis(self.bases, self.scripts, self.vertical)
|
|
1914
|
+
builder.set_base_axis(self.bases, self.scripts, self.vertical, self.minmax)
|
|
1840
1915
|
|
|
1841
1916
|
def asFea(self, indent=""):
|
|
1842
1917
|
direction = "Vert" if self.vertical else "Horiz"
|
|
@@ -1844,9 +1919,13 @@ class BaseAxis(Statement):
|
|
|
1844
1919
|
"{} {} {}".format(a[0], a[1], " ".join(map(str, a[2])))
|
|
1845
1920
|
for a in self.scripts
|
|
1846
1921
|
]
|
|
1922
|
+
minmaxes = [
|
|
1923
|
+
"\n{}Axis.MinMax {} {} {}, {};".format(direction, a[0], a[1], a[2], a[3])
|
|
1924
|
+
for a in self.minmax
|
|
1925
|
+
]
|
|
1847
1926
|
return "{}Axis.BaseTagList {};\n{}{}Axis.BaseScriptList {};".format(
|
|
1848
1927
|
direction, " ".join(self.bases), indent, direction, ", ".join(scripts)
|
|
1849
|
-
)
|
|
1928
|
+
) + "\n".join(minmaxes)
|
|
1850
1929
|
|
|
1851
1930
|
|
|
1852
1931
|
class OS2Field(Statement):
|
|
@@ -2098,7 +2177,7 @@ class VariationBlock(Block):
|
|
|
2098
2177
|
def build(self, builder):
|
|
2099
2178
|
"""Call the ``start_feature`` callback on the builder object, visit
|
|
2100
2179
|
all the statements in this feature, and then call ``end_feature``."""
|
|
2101
|
-
builder.start_feature(self.location, self.name)
|
|
2180
|
+
builder.start_feature(self.location, self.name, self.use_extension)
|
|
2102
2181
|
if (
|
|
2103
2182
|
self.conditionset != "NULL"
|
|
2104
2183
|
and self.conditionset not in builder.conditionsets_
|
fontTools/feaLib/builder.py
CHANGED
|
@@ -126,6 +126,7 @@ class Builder(object):
|
|
|
126
126
|
self.script_ = None
|
|
127
127
|
self.lookupflag_ = 0
|
|
128
128
|
self.lookupflag_markFilterSet_ = None
|
|
129
|
+
self.use_extension_ = False
|
|
129
130
|
self.language_systems = set()
|
|
130
131
|
self.seen_non_DFLT_script_ = False
|
|
131
132
|
self.named_lookups_ = {}
|
|
@@ -141,6 +142,7 @@ class Builder(object):
|
|
|
141
142
|
self.aalt_features_ = [] # [(location, featureName)*], for 'aalt'
|
|
142
143
|
self.aalt_location_ = None
|
|
143
144
|
self.aalt_alternates_ = {}
|
|
145
|
+
self.aalt_use_extension_ = False
|
|
144
146
|
# for 'featureNames'
|
|
145
147
|
self.featureNames_ = set()
|
|
146
148
|
self.featureNames_ids_ = {}
|
|
@@ -247,6 +249,7 @@ class Builder(object):
|
|
|
247
249
|
result = builder_class(self.font, location)
|
|
248
250
|
result.lookupflag = self.lookupflag_
|
|
249
251
|
result.markFilterSet = self.lookupflag_markFilterSet_
|
|
252
|
+
result.extension = self.use_extension_
|
|
250
253
|
self.lookups_.append(result)
|
|
251
254
|
return result
|
|
252
255
|
|
|
@@ -272,6 +275,7 @@ class Builder(object):
|
|
|
272
275
|
self.cur_lookup_ = builder_class(self.font, location)
|
|
273
276
|
self.cur_lookup_.lookupflag = self.lookupflag_
|
|
274
277
|
self.cur_lookup_.markFilterSet = self.lookupflag_markFilterSet_
|
|
278
|
+
self.cur_lookup_.extension = self.use_extension_
|
|
275
279
|
self.lookups_.append(self.cur_lookup_)
|
|
276
280
|
if self.cur_lookup_name_:
|
|
277
281
|
# We are starting a lookup rule inside a named lookup block.
|
|
@@ -323,7 +327,7 @@ class Builder(object):
|
|
|
323
327
|
}
|
|
324
328
|
old_lookups = self.lookups_
|
|
325
329
|
self.lookups_ = []
|
|
326
|
-
self.start_feature(self.aalt_location_, "aalt")
|
|
330
|
+
self.start_feature(self.aalt_location_, "aalt", self.aalt_use_extension_)
|
|
327
331
|
if single:
|
|
328
332
|
single_lookup = self.get_lookup_(location, SingleSubstBuilder)
|
|
329
333
|
single_lookup.mapping = single
|
|
@@ -341,6 +345,7 @@ class Builder(object):
|
|
|
341
345
|
table = self.font["head"] = newTable("head")
|
|
342
346
|
table.decompile(b"\0" * 54, self.font)
|
|
343
347
|
table.tableVersion = 1.0
|
|
348
|
+
table.magicNumber = 0x5F0F3CF5
|
|
344
349
|
table.created = table.modified = 3406620153 # 2011-12-13 11:22:33
|
|
345
350
|
table.fontRevision = self.fontRevision_
|
|
346
351
|
|
|
@@ -727,10 +732,16 @@ class Builder(object):
|
|
|
727
732
|
result.table = base
|
|
728
733
|
return result
|
|
729
734
|
|
|
735
|
+
def buildBASECoord(self, c):
|
|
736
|
+
coord = otTables.BaseCoord()
|
|
737
|
+
coord.Format = 1
|
|
738
|
+
coord.Coordinate = c
|
|
739
|
+
return coord
|
|
740
|
+
|
|
730
741
|
def buildBASEAxis(self, axis):
|
|
731
742
|
if not axis:
|
|
732
743
|
return
|
|
733
|
-
bases, scripts = axis
|
|
744
|
+
bases, scripts, minmax = axis
|
|
734
745
|
axis = otTables.Axis()
|
|
735
746
|
axis.BaseTagList = otTables.BaseTagList()
|
|
736
747
|
axis.BaseTagList.BaselineTag = bases
|
|
@@ -739,19 +750,35 @@ class Builder(object):
|
|
|
739
750
|
axis.BaseScriptList.BaseScriptRecord = []
|
|
740
751
|
axis.BaseScriptList.BaseScriptCount = len(scripts)
|
|
741
752
|
for script in sorted(scripts):
|
|
753
|
+
minmax_for_script = [
|
|
754
|
+
record[1:] for record in minmax if record[0] == script[0]
|
|
755
|
+
]
|
|
742
756
|
record = otTables.BaseScriptRecord()
|
|
743
757
|
record.BaseScriptTag = script[0]
|
|
744
758
|
record.BaseScript = otTables.BaseScript()
|
|
745
|
-
record.BaseScript.BaseLangSysCount = 0
|
|
746
759
|
record.BaseScript.BaseValues = otTables.BaseValues()
|
|
747
760
|
record.BaseScript.BaseValues.DefaultIndex = bases.index(script[1])
|
|
748
761
|
record.BaseScript.BaseValues.BaseCoord = []
|
|
749
762
|
record.BaseScript.BaseValues.BaseCoordCount = len(script[2])
|
|
763
|
+
record.BaseScript.BaseLangSysRecord = []
|
|
764
|
+
|
|
750
765
|
for c in script[2]:
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
766
|
+
record.BaseScript.BaseValues.BaseCoord.append(self.buildBASECoord(c))
|
|
767
|
+
for language, min_coord, max_coord in minmax_for_script:
|
|
768
|
+
minmax_record = otTables.MinMax()
|
|
769
|
+
minmax_record.MinCoord = self.buildBASECoord(min_coord)
|
|
770
|
+
minmax_record.MaxCoord = self.buildBASECoord(max_coord)
|
|
771
|
+
minmax_record.FeatMinMaxCount = 0
|
|
772
|
+
if language == "dflt":
|
|
773
|
+
record.BaseScript.DefaultMinMax = minmax_record
|
|
774
|
+
else:
|
|
775
|
+
lang_record = otTables.BaseLangSysRecord()
|
|
776
|
+
lang_record.BaseLangSysTag = language
|
|
777
|
+
lang_record.MinMax = minmax_record
|
|
778
|
+
record.BaseScript.BaseLangSysRecord.append(lang_record)
|
|
779
|
+
record.BaseScript.BaseLangSysCount = len(
|
|
780
|
+
record.BaseScript.BaseLangSysRecord
|
|
781
|
+
)
|
|
755
782
|
axis.BaseScriptList.BaseScriptRecord.append(record)
|
|
756
783
|
return axis
|
|
757
784
|
|
|
@@ -1031,15 +1058,22 @@ class Builder(object):
|
|
|
1031
1058
|
else:
|
|
1032
1059
|
return frozenset({("DFLT", "dflt")})
|
|
1033
1060
|
|
|
1034
|
-
def start_feature(self, location, name):
|
|
1061
|
+
def start_feature(self, location, name, use_extension=False):
|
|
1062
|
+
if use_extension and name != "aalt":
|
|
1063
|
+
raise FeatureLibError(
|
|
1064
|
+
"'useExtension' keyword for feature blocks is allowed only for 'aalt' feature",
|
|
1065
|
+
location,
|
|
1066
|
+
)
|
|
1035
1067
|
self.language_systems = self.get_default_language_systems_()
|
|
1036
1068
|
self.script_ = "DFLT"
|
|
1037
1069
|
self.cur_lookup_ = None
|
|
1038
1070
|
self.cur_feature_name_ = name
|
|
1039
1071
|
self.lookupflag_ = 0
|
|
1040
1072
|
self.lookupflag_markFilterSet_ = None
|
|
1073
|
+
self.use_extension_ = use_extension
|
|
1041
1074
|
if name == "aalt":
|
|
1042
1075
|
self.aalt_location_ = location
|
|
1076
|
+
self.aalt_use_extension_ = use_extension
|
|
1043
1077
|
|
|
1044
1078
|
def end_feature(self):
|
|
1045
1079
|
assert self.cur_feature_name_ is not None
|
|
@@ -1048,8 +1082,9 @@ class Builder(object):
|
|
|
1048
1082
|
self.cur_lookup_ = None
|
|
1049
1083
|
self.lookupflag_ = 0
|
|
1050
1084
|
self.lookupflag_markFilterSet_ = None
|
|
1085
|
+
self.use_extension_ = False
|
|
1051
1086
|
|
|
1052
|
-
def start_lookup_block(self, location, name):
|
|
1087
|
+
def start_lookup_block(self, location, name, use_extension=False):
|
|
1053
1088
|
if name in self.named_lookups_:
|
|
1054
1089
|
raise FeatureLibError(
|
|
1055
1090
|
'Lookup "%s" has already been defined' % name, location
|
|
@@ -1063,6 +1098,7 @@ class Builder(object):
|
|
|
1063
1098
|
self.cur_lookup_name_ = name
|
|
1064
1099
|
self.named_lookups_[name] = None
|
|
1065
1100
|
self.cur_lookup_ = None
|
|
1101
|
+
self.use_extension_ = use_extension
|
|
1066
1102
|
if self.cur_feature_name_ is None:
|
|
1067
1103
|
self.lookupflag_ = 0
|
|
1068
1104
|
self.lookupflag_markFilterSet_ = None
|
|
@@ -1071,6 +1107,7 @@ class Builder(object):
|
|
|
1071
1107
|
assert self.cur_lookup_name_ is not None
|
|
1072
1108
|
self.cur_lookup_name_ = None
|
|
1073
1109
|
self.cur_lookup_ = None
|
|
1110
|
+
self.use_extension_ = False
|
|
1074
1111
|
if self.cur_feature_name_ is None:
|
|
1075
1112
|
self.lookupflag_ = 0
|
|
1076
1113
|
self.lookupflag_markFilterSet_ = None
|
|
@@ -1235,11 +1272,11 @@ class Builder(object):
|
|
|
1235
1272
|
def add_cv_character(self, character, tag):
|
|
1236
1273
|
self.cv_characters_[tag].append(character)
|
|
1237
1274
|
|
|
1238
|
-
def set_base_axis(self, bases, scripts, vertical):
|
|
1275
|
+
def set_base_axis(self, bases, scripts, vertical, minmax=[]):
|
|
1239
1276
|
if vertical:
|
|
1240
|
-
self.base_vert_axis_ = (bases, scripts)
|
|
1277
|
+
self.base_vert_axis_ = (bases, scripts, minmax)
|
|
1241
1278
|
else:
|
|
1242
|
-
self.base_horiz_axis_ = (bases, scripts)
|
|
1279
|
+
self.base_horiz_axis_ = (bases, scripts, minmax)
|
|
1243
1280
|
|
|
1244
1281
|
def set_size_parameters(
|
|
1245
1282
|
self, location, DesignSize, SubfamilyID, RangeStart, RangeEnd
|
|
@@ -1448,7 +1485,9 @@ class Builder(object):
|
|
|
1448
1485
|
lookup = self.get_lookup_(location, PairPosBuilder)
|
|
1449
1486
|
v1 = self.makeOpenTypeValueRecord(location, value1, pairPosContext=True)
|
|
1450
1487
|
v2 = self.makeOpenTypeValueRecord(location, value2, pairPosContext=True)
|
|
1451
|
-
|
|
1488
|
+
cls1 = tuple(sorted(set(glyphclass1)))
|
|
1489
|
+
cls2 = tuple(sorted(set(glyphclass2)))
|
|
1490
|
+
lookup.addClassPair(location, cls1, v1, cls2, v2)
|
|
1452
1491
|
|
|
1453
1492
|
def add_specific_pair_pos(self, location, glyph1, value1, glyph2, value2):
|
|
1454
1493
|
if not glyph1 or not glyph2:
|