fonttools 4.59.1__cp314-cp314-macosx_10_13_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 +8 -0
- fontTools/__main__.py +35 -0
- fontTools/afmLib.py +439 -0
- fontTools/agl.py +5233 -0
- fontTools/cffLib/CFF2ToCFF.py +233 -0
- fontTools/cffLib/CFFToCFF2.py +305 -0
- fontTools/cffLib/__init__.py +3694 -0
- fontTools/cffLib/specializer.py +927 -0
- fontTools/cffLib/transforms.py +495 -0
- fontTools/cffLib/width.py +210 -0
- fontTools/colorLib/__init__.py +0 -0
- fontTools/colorLib/builder.py +664 -0
- fontTools/colorLib/errors.py +2 -0
- fontTools/colorLib/geometry.py +143 -0
- fontTools/colorLib/table_builder.py +223 -0
- fontTools/colorLib/unbuilder.py +81 -0
- fontTools/config/__init__.py +90 -0
- fontTools/cu2qu/__init__.py +15 -0
- fontTools/cu2qu/__main__.py +6 -0
- fontTools/cu2qu/benchmark.py +54 -0
- fontTools/cu2qu/cli.py +198 -0
- fontTools/cu2qu/cu2qu.c +15560 -0
- fontTools/cu2qu/cu2qu.cpython-314-darwin.so +0 -0
- fontTools/cu2qu/cu2qu.py +531 -0
- fontTools/cu2qu/errors.py +77 -0
- fontTools/cu2qu/ufo.py +349 -0
- fontTools/designspaceLib/__init__.py +3338 -0
- fontTools/designspaceLib/__main__.py +6 -0
- fontTools/designspaceLib/split.py +475 -0
- fontTools/designspaceLib/statNames.py +260 -0
- fontTools/designspaceLib/types.py +147 -0
- fontTools/encodings/MacRoman.py +258 -0
- fontTools/encodings/StandardEncoding.py +258 -0
- fontTools/encodings/__init__.py +1 -0
- fontTools/encodings/codecs.py +135 -0
- fontTools/feaLib/__init__.py +4 -0
- fontTools/feaLib/__main__.py +78 -0
- fontTools/feaLib/ast.py +2143 -0
- fontTools/feaLib/builder.py +1802 -0
- fontTools/feaLib/error.py +22 -0
- fontTools/feaLib/lexer.c +17351 -0
- fontTools/feaLib/lexer.cpython-314-darwin.so +0 -0
- fontTools/feaLib/lexer.py +287 -0
- fontTools/feaLib/location.py +12 -0
- fontTools/feaLib/lookupDebugInfo.py +12 -0
- fontTools/feaLib/parser.py +2379 -0
- fontTools/feaLib/variableScalar.py +113 -0
- fontTools/fontBuilder.py +1014 -0
- fontTools/help.py +36 -0
- fontTools/merge/__init__.py +248 -0
- fontTools/merge/__main__.py +6 -0
- fontTools/merge/base.py +81 -0
- fontTools/merge/cmap.py +173 -0
- fontTools/merge/layout.py +526 -0
- fontTools/merge/options.py +85 -0
- fontTools/merge/tables.py +352 -0
- fontTools/merge/unicode.py +78 -0
- fontTools/merge/util.py +143 -0
- fontTools/misc/__init__.py +1 -0
- fontTools/misc/arrayTools.py +424 -0
- fontTools/misc/bezierTools.c +40151 -0
- fontTools/misc/bezierTools.cpython-314-darwin.so +0 -0
- fontTools/misc/bezierTools.py +1497 -0
- fontTools/misc/classifyTools.py +170 -0
- fontTools/misc/cliTools.py +53 -0
- fontTools/misc/configTools.py +349 -0
- fontTools/misc/cython.py +27 -0
- fontTools/misc/dictTools.py +83 -0
- fontTools/misc/eexec.py +119 -0
- fontTools/misc/encodingTools.py +72 -0
- fontTools/misc/etree.py +456 -0
- fontTools/misc/filenames.py +245 -0
- fontTools/misc/filesystem/__init__.py +68 -0
- fontTools/misc/filesystem/_base.py +134 -0
- fontTools/misc/filesystem/_copy.py +45 -0
- fontTools/misc/filesystem/_errors.py +54 -0
- fontTools/misc/filesystem/_info.py +75 -0
- fontTools/misc/filesystem/_osfs.py +164 -0
- fontTools/misc/filesystem/_path.py +67 -0
- fontTools/misc/filesystem/_subfs.py +92 -0
- fontTools/misc/filesystem/_tempfs.py +34 -0
- fontTools/misc/filesystem/_tools.py +34 -0
- fontTools/misc/filesystem/_walk.py +55 -0
- fontTools/misc/filesystem/_zipfs.py +204 -0
- fontTools/misc/fixedTools.py +253 -0
- fontTools/misc/intTools.py +25 -0
- fontTools/misc/iterTools.py +12 -0
- fontTools/misc/lazyTools.py +42 -0
- fontTools/misc/loggingTools.py +543 -0
- fontTools/misc/macCreatorType.py +56 -0
- fontTools/misc/macRes.py +261 -0
- fontTools/misc/plistlib/__init__.py +681 -0
- fontTools/misc/plistlib/py.typed +0 -0
- fontTools/misc/psCharStrings.py +1511 -0
- fontTools/misc/psLib.py +398 -0
- fontTools/misc/psOperators.py +572 -0
- fontTools/misc/py23.py +96 -0
- fontTools/misc/roundTools.py +110 -0
- fontTools/misc/sstruct.py +227 -0
- fontTools/misc/symfont.py +242 -0
- fontTools/misc/testTools.py +233 -0
- fontTools/misc/textTools.py +154 -0
- fontTools/misc/timeTools.py +88 -0
- fontTools/misc/transform.py +516 -0
- fontTools/misc/treeTools.py +45 -0
- fontTools/misc/vector.py +147 -0
- fontTools/misc/visitor.py +150 -0
- fontTools/misc/xmlReader.py +188 -0
- fontTools/misc/xmlWriter.py +231 -0
- fontTools/mtiLib/__init__.py +1400 -0
- fontTools/mtiLib/__main__.py +5 -0
- fontTools/otlLib/__init__.py +1 -0
- fontTools/otlLib/builder.py +3465 -0
- fontTools/otlLib/error.py +11 -0
- fontTools/otlLib/maxContextCalc.py +96 -0
- fontTools/otlLib/optimize/__init__.py +53 -0
- fontTools/otlLib/optimize/__main__.py +6 -0
- fontTools/otlLib/optimize/gpos.py +439 -0
- fontTools/pens/__init__.py +1 -0
- fontTools/pens/areaPen.py +52 -0
- fontTools/pens/basePen.py +475 -0
- fontTools/pens/boundsPen.py +98 -0
- fontTools/pens/cairoPen.py +26 -0
- fontTools/pens/cocoaPen.py +26 -0
- fontTools/pens/cu2quPen.py +325 -0
- fontTools/pens/explicitClosingLinePen.py +101 -0
- fontTools/pens/filterPen.py +241 -0
- fontTools/pens/freetypePen.py +462 -0
- fontTools/pens/hashPointPen.py +89 -0
- fontTools/pens/momentsPen.c +13466 -0
- fontTools/pens/momentsPen.cpython-314-darwin.so +0 -0
- fontTools/pens/momentsPen.py +879 -0
- fontTools/pens/perimeterPen.py +69 -0
- fontTools/pens/pointInsidePen.py +192 -0
- fontTools/pens/pointPen.py +609 -0
- fontTools/pens/qtPen.py +29 -0
- fontTools/pens/qu2cuPen.py +105 -0
- fontTools/pens/quartzPen.py +43 -0
- fontTools/pens/recordingPen.py +335 -0
- fontTools/pens/reportLabPen.py +79 -0
- fontTools/pens/reverseContourPen.py +96 -0
- fontTools/pens/roundingPen.py +130 -0
- fontTools/pens/statisticsPen.py +312 -0
- fontTools/pens/svgPathPen.py +310 -0
- fontTools/pens/t2CharStringPen.py +88 -0
- fontTools/pens/teePen.py +55 -0
- fontTools/pens/transformPen.py +115 -0
- fontTools/pens/ttGlyphPen.py +335 -0
- fontTools/pens/wxPen.py +29 -0
- fontTools/qu2cu/__init__.py +15 -0
- fontTools/qu2cu/__main__.py +7 -0
- fontTools/qu2cu/benchmark.py +56 -0
- fontTools/qu2cu/cli.py +125 -0
- fontTools/qu2cu/qu2cu.c +16753 -0
- fontTools/qu2cu/qu2cu.cpython-314-darwin.so +0 -0
- fontTools/qu2cu/qu2cu.py +405 -0
- fontTools/subset/__init__.py +3929 -0
- fontTools/subset/__main__.py +6 -0
- fontTools/subset/cff.py +184 -0
- fontTools/subset/svg.py +253 -0
- fontTools/subset/util.py +25 -0
- fontTools/svgLib/__init__.py +3 -0
- fontTools/svgLib/path/__init__.py +65 -0
- fontTools/svgLib/path/arc.py +154 -0
- fontTools/svgLib/path/parser.py +322 -0
- fontTools/svgLib/path/shapes.py +183 -0
- fontTools/t1Lib/__init__.py +648 -0
- fontTools/tfmLib.py +460 -0
- fontTools/ttLib/__init__.py +30 -0
- fontTools/ttLib/__main__.py +148 -0
- fontTools/ttLib/macUtils.py +54 -0
- fontTools/ttLib/removeOverlaps.py +393 -0
- fontTools/ttLib/reorderGlyphs.py +285 -0
- fontTools/ttLib/scaleUpem.py +436 -0
- fontTools/ttLib/sfnt.py +661 -0
- fontTools/ttLib/standardGlyphOrder.py +271 -0
- fontTools/ttLib/tables/B_A_S_E_.py +14 -0
- fontTools/ttLib/tables/BitmapGlyphMetrics.py +64 -0
- fontTools/ttLib/tables/C_B_D_T_.py +113 -0
- fontTools/ttLib/tables/C_B_L_C_.py +19 -0
- fontTools/ttLib/tables/C_F_F_.py +61 -0
- fontTools/ttLib/tables/C_F_F__2.py +26 -0
- fontTools/ttLib/tables/C_O_L_R_.py +165 -0
- fontTools/ttLib/tables/C_P_A_L_.py +305 -0
- fontTools/ttLib/tables/D_S_I_G_.py +158 -0
- fontTools/ttLib/tables/D__e_b_g.py +35 -0
- fontTools/ttLib/tables/DefaultTable.py +49 -0
- fontTools/ttLib/tables/E_B_D_T_.py +835 -0
- fontTools/ttLib/tables/E_B_L_C_.py +718 -0
- fontTools/ttLib/tables/F_F_T_M_.py +52 -0
- fontTools/ttLib/tables/F__e_a_t.py +149 -0
- fontTools/ttLib/tables/G_D_E_F_.py +13 -0
- fontTools/ttLib/tables/G_M_A_P_.py +148 -0
- fontTools/ttLib/tables/G_P_K_G_.py +133 -0
- fontTools/ttLib/tables/G_P_O_S_.py +14 -0
- fontTools/ttLib/tables/G_S_U_B_.py +13 -0
- fontTools/ttLib/tables/G_V_A_R_.py +5 -0
- fontTools/ttLib/tables/G__l_a_t.py +235 -0
- fontTools/ttLib/tables/G__l_o_c.py +85 -0
- fontTools/ttLib/tables/H_V_A_R_.py +13 -0
- fontTools/ttLib/tables/J_S_T_F_.py +13 -0
- fontTools/ttLib/tables/L_T_S_H_.py +58 -0
- fontTools/ttLib/tables/M_A_T_H_.py +13 -0
- fontTools/ttLib/tables/M_E_T_A_.py +352 -0
- fontTools/ttLib/tables/M_V_A_R_.py +13 -0
- fontTools/ttLib/tables/O_S_2f_2.py +752 -0
- fontTools/ttLib/tables/S_I_N_G_.py +99 -0
- fontTools/ttLib/tables/S_T_A_T_.py +15 -0
- fontTools/ttLib/tables/S_V_G_.py +223 -0
- fontTools/ttLib/tables/S__i_l_f.py +1040 -0
- fontTools/ttLib/tables/S__i_l_l.py +92 -0
- fontTools/ttLib/tables/T_S_I_B_.py +13 -0
- fontTools/ttLib/tables/T_S_I_C_.py +14 -0
- fontTools/ttLib/tables/T_S_I_D_.py +13 -0
- fontTools/ttLib/tables/T_S_I_J_.py +13 -0
- fontTools/ttLib/tables/T_S_I_P_.py +13 -0
- fontTools/ttLib/tables/T_S_I_S_.py +13 -0
- fontTools/ttLib/tables/T_S_I_V_.py +26 -0
- fontTools/ttLib/tables/T_S_I__0.py +70 -0
- fontTools/ttLib/tables/T_S_I__1.py +163 -0
- fontTools/ttLib/tables/T_S_I__2.py +17 -0
- fontTools/ttLib/tables/T_S_I__3.py +22 -0
- fontTools/ttLib/tables/T_S_I__5.py +60 -0
- fontTools/ttLib/tables/T_T_F_A_.py +14 -0
- fontTools/ttLib/tables/TupleVariation.py +884 -0
- fontTools/ttLib/tables/V_A_R_C_.py +12 -0
- fontTools/ttLib/tables/V_D_M_X_.py +249 -0
- fontTools/ttLib/tables/V_O_R_G_.py +165 -0
- fontTools/ttLib/tables/V_V_A_R_.py +13 -0
- fontTools/ttLib/tables/__init__.py +98 -0
- fontTools/ttLib/tables/_a_n_k_r.py +15 -0
- fontTools/ttLib/tables/_a_v_a_r.py +191 -0
- fontTools/ttLib/tables/_b_s_l_n.py +15 -0
- fontTools/ttLib/tables/_c_i_d_g.py +24 -0
- fontTools/ttLib/tables/_c_m_a_p.py +1591 -0
- fontTools/ttLib/tables/_c_v_a_r.py +94 -0
- fontTools/ttLib/tables/_c_v_t.py +56 -0
- fontTools/ttLib/tables/_f_e_a_t.py +15 -0
- fontTools/ttLib/tables/_f_p_g_m.py +62 -0
- fontTools/ttLib/tables/_f_v_a_r.py +261 -0
- fontTools/ttLib/tables/_g_a_s_p.py +63 -0
- fontTools/ttLib/tables/_g_c_i_d.py +13 -0
- fontTools/ttLib/tables/_g_l_y_f.py +2311 -0
- fontTools/ttLib/tables/_g_v_a_r.py +340 -0
- fontTools/ttLib/tables/_h_d_m_x.py +127 -0
- fontTools/ttLib/tables/_h_e_a_d.py +130 -0
- fontTools/ttLib/tables/_h_h_e_a.py +147 -0
- fontTools/ttLib/tables/_h_m_t_x.py +164 -0
- fontTools/ttLib/tables/_k_e_r_n.py +289 -0
- fontTools/ttLib/tables/_l_c_a_r.py +13 -0
- fontTools/ttLib/tables/_l_o_c_a.py +70 -0
- fontTools/ttLib/tables/_l_t_a_g.py +72 -0
- fontTools/ttLib/tables/_m_a_x_p.py +147 -0
- fontTools/ttLib/tables/_m_e_t_a.py +112 -0
- fontTools/ttLib/tables/_m_o_r_t.py +14 -0
- fontTools/ttLib/tables/_m_o_r_x.py +15 -0
- fontTools/ttLib/tables/_n_a_m_e.py +1237 -0
- fontTools/ttLib/tables/_o_p_b_d.py +14 -0
- fontTools/ttLib/tables/_p_o_s_t.py +319 -0
- fontTools/ttLib/tables/_p_r_e_p.py +16 -0
- fontTools/ttLib/tables/_p_r_o_p.py +12 -0
- fontTools/ttLib/tables/_s_b_i_x.py +129 -0
- fontTools/ttLib/tables/_t_r_a_k.py +332 -0
- fontTools/ttLib/tables/_v_h_e_a.py +139 -0
- fontTools/ttLib/tables/_v_m_t_x.py +19 -0
- fontTools/ttLib/tables/asciiTable.py +20 -0
- fontTools/ttLib/tables/grUtils.py +92 -0
- fontTools/ttLib/tables/otBase.py +1464 -0
- fontTools/ttLib/tables/otConverters.py +2068 -0
- fontTools/ttLib/tables/otData.py +6400 -0
- fontTools/ttLib/tables/otTables.py +2703 -0
- fontTools/ttLib/tables/otTraverse.py +163 -0
- fontTools/ttLib/tables/sbixGlyph.py +149 -0
- fontTools/ttLib/tables/sbixStrike.py +177 -0
- fontTools/ttLib/tables/table_API_readme.txt +91 -0
- fontTools/ttLib/tables/ttProgram.py +594 -0
- fontTools/ttLib/ttCollection.py +125 -0
- fontTools/ttLib/ttFont.py +1148 -0
- fontTools/ttLib/ttGlyphSet.py +490 -0
- fontTools/ttLib/ttVisitor.py +32 -0
- fontTools/ttLib/woff2.py +1680 -0
- fontTools/ttx.py +479 -0
- fontTools/ufoLib/__init__.py +2472 -0
- fontTools/ufoLib/converters.py +398 -0
- fontTools/ufoLib/errors.py +30 -0
- fontTools/ufoLib/etree.py +6 -0
- fontTools/ufoLib/filenames.py +346 -0
- fontTools/ufoLib/glifLib.py +2024 -0
- fontTools/ufoLib/kerning.py +121 -0
- fontTools/ufoLib/plistlib.py +47 -0
- fontTools/ufoLib/pointPen.py +6 -0
- fontTools/ufoLib/utils.py +79 -0
- fontTools/ufoLib/validators.py +1184 -0
- fontTools/unicode.py +50 -0
- fontTools/unicodedata/Blocks.py +801 -0
- fontTools/unicodedata/Mirrored.py +446 -0
- fontTools/unicodedata/OTTags.py +50 -0
- fontTools/unicodedata/ScriptExtensions.py +826 -0
- fontTools/unicodedata/Scripts.py +3617 -0
- fontTools/unicodedata/__init__.py +304 -0
- fontTools/varLib/__init__.py +1517 -0
- fontTools/varLib/__main__.py +6 -0
- fontTools/varLib/avar.py +260 -0
- fontTools/varLib/avarPlanner.py +1004 -0
- fontTools/varLib/builder.py +215 -0
- fontTools/varLib/cff.py +631 -0
- fontTools/varLib/errors.py +219 -0
- fontTools/varLib/featureVars.py +703 -0
- fontTools/varLib/hvar.py +113 -0
- fontTools/varLib/instancer/__init__.py +2014 -0
- fontTools/varLib/instancer/__main__.py +5 -0
- fontTools/varLib/instancer/featureVars.py +190 -0
- fontTools/varLib/instancer/names.py +388 -0
- fontTools/varLib/instancer/solver.py +309 -0
- fontTools/varLib/interpolatable.py +1209 -0
- fontTools/varLib/interpolatableHelpers.py +396 -0
- fontTools/varLib/interpolatablePlot.py +1269 -0
- fontTools/varLib/interpolatableTestContourOrder.py +82 -0
- fontTools/varLib/interpolatableTestStartingPoint.py +107 -0
- fontTools/varLib/interpolate_layout.py +124 -0
- fontTools/varLib/iup.c +19845 -0
- fontTools/varLib/iup.cpython-314-darwin.so +0 -0
- fontTools/varLib/iup.py +490 -0
- fontTools/varLib/merger.py +1717 -0
- fontTools/varLib/models.py +642 -0
- fontTools/varLib/multiVarStore.py +253 -0
- fontTools/varLib/mutator.py +529 -0
- fontTools/varLib/mvar.py +40 -0
- fontTools/varLib/plot.py +238 -0
- fontTools/varLib/stat.py +149 -0
- fontTools/varLib/varStore.py +739 -0
- fontTools/voltLib/__init__.py +5 -0
- fontTools/voltLib/__main__.py +206 -0
- fontTools/voltLib/ast.py +452 -0
- fontTools/voltLib/error.py +12 -0
- fontTools/voltLib/lexer.py +99 -0
- fontTools/voltLib/parser.py +664 -0
- fontTools/voltLib/voltToFea.py +911 -0
- fonttools-4.59.1.data/data/share/man/man1/ttx.1 +225 -0
- fonttools-4.59.1.dist-info/METADATA +2175 -0
- fonttools-4.59.1.dist-info/RECORD +346 -0
- fonttools-4.59.1.dist-info/WHEEL +6 -0
- fonttools-4.59.1.dist-info/entry_points.txt +5 -0
- fonttools-4.59.1.dist-info/licenses/LICENSE +21 -0
- fonttools-4.59.1.dist-info/licenses/LICENSE.external +388 -0
- fonttools-4.59.1.dist-info/top_level.txt +1 -0
fontTools/varLib/avar.py
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
from fontTools.varLib import _add_avar, load_designspace
|
|
2
|
+
from fontTools.varLib.models import VariationModel
|
|
3
|
+
from fontTools.varLib.varStore import VarStoreInstancer
|
|
4
|
+
from fontTools.misc.fixedTools import fixedToFloat as fi2fl
|
|
5
|
+
from fontTools.misc.cliTools import makeOutputFileName
|
|
6
|
+
from itertools import product
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
log = logging.getLogger("fontTools.varLib.avar")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _denormalize(v, axis):
|
|
13
|
+
if v >= 0:
|
|
14
|
+
return axis.defaultValue + v * (axis.maxValue - axis.defaultValue)
|
|
15
|
+
else:
|
|
16
|
+
return axis.defaultValue + v * (axis.defaultValue - axis.minValue)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _pruneLocations(locations, poles, axisTags):
|
|
20
|
+
# Now we have all the input locations, find which ones are
|
|
21
|
+
# not needed and remove them.
|
|
22
|
+
|
|
23
|
+
# Note: This algorithm is heavily tied to how VariationModel
|
|
24
|
+
# is implemented. It assumes that input was extracted from
|
|
25
|
+
# VariationModel-generated object, like an ItemVariationStore
|
|
26
|
+
# created by fontmake using varLib.models.VariationModel.
|
|
27
|
+
# Some CoPilot blabbering:
|
|
28
|
+
# I *think* I can prove that this algorithm is correct, but
|
|
29
|
+
# I'm not 100% sure. It's possible that there are edge cases
|
|
30
|
+
# where this algorithm will fail. I'm not sure how to prove
|
|
31
|
+
# that it's correct, but I'm also not sure how to prove that
|
|
32
|
+
# it's incorrect. I'm not sure how to write a test case that
|
|
33
|
+
# would prove that it's incorrect. I'm not sure how to write
|
|
34
|
+
# a test case that would prove that it's correct.
|
|
35
|
+
|
|
36
|
+
model = VariationModel(locations, axisTags)
|
|
37
|
+
modelMapping = model.mapping
|
|
38
|
+
modelSupports = model.supports
|
|
39
|
+
pins = {tuple(k.items()): None for k in poles}
|
|
40
|
+
for location in poles:
|
|
41
|
+
i = locations.index(location)
|
|
42
|
+
i = modelMapping[i]
|
|
43
|
+
support = modelSupports[i]
|
|
44
|
+
supportAxes = set(support.keys())
|
|
45
|
+
for axisTag, (minV, _, maxV) in support.items():
|
|
46
|
+
for v in (minV, maxV):
|
|
47
|
+
if v in (-1, 0, 1):
|
|
48
|
+
continue
|
|
49
|
+
for pin in pins.keys():
|
|
50
|
+
pinLocation = dict(pin)
|
|
51
|
+
pinAxes = set(pinLocation.keys())
|
|
52
|
+
if pinAxes != supportAxes:
|
|
53
|
+
continue
|
|
54
|
+
if axisTag not in pinAxes:
|
|
55
|
+
continue
|
|
56
|
+
if pinLocation[axisTag] == v:
|
|
57
|
+
break
|
|
58
|
+
else:
|
|
59
|
+
# No pin found. Go through the previous masters
|
|
60
|
+
# and find a suitable pin. Going backwards is
|
|
61
|
+
# better because it can find a pin that is close
|
|
62
|
+
# to the pole in more dimensions, and reducing
|
|
63
|
+
# the total number of pins needed.
|
|
64
|
+
for candidateIdx in range(i - 1, -1, -1):
|
|
65
|
+
candidate = modelSupports[candidateIdx]
|
|
66
|
+
candidateAxes = set(candidate.keys())
|
|
67
|
+
if candidateAxes != supportAxes:
|
|
68
|
+
continue
|
|
69
|
+
if axisTag not in candidateAxes:
|
|
70
|
+
continue
|
|
71
|
+
candidate = {
|
|
72
|
+
k: defaultV for k, (_, defaultV, _) in candidate.items()
|
|
73
|
+
}
|
|
74
|
+
if candidate[axisTag] == v:
|
|
75
|
+
pins[tuple(candidate.items())] = None
|
|
76
|
+
break
|
|
77
|
+
else:
|
|
78
|
+
assert False, "No pin found"
|
|
79
|
+
return [dict(t) for t in pins.keys()]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def mappings_from_avar(font, denormalize=True):
|
|
83
|
+
fvarAxes = font["fvar"].axes
|
|
84
|
+
axisMap = {a.axisTag: a for a in fvarAxes}
|
|
85
|
+
axisTags = [a.axisTag for a in fvarAxes]
|
|
86
|
+
axisIndexes = {a.axisTag: i for i, a in enumerate(fvarAxes)}
|
|
87
|
+
if "avar" not in font:
|
|
88
|
+
return {}, {}
|
|
89
|
+
avar = font["avar"]
|
|
90
|
+
axisMaps = {
|
|
91
|
+
tag: seg
|
|
92
|
+
for tag, seg in avar.segments.items()
|
|
93
|
+
if seg and seg != {-1: -1, 0: 0, 1: 1}
|
|
94
|
+
}
|
|
95
|
+
mappings = []
|
|
96
|
+
|
|
97
|
+
if getattr(avar, "majorVersion", 1) == 2:
|
|
98
|
+
varStore = avar.table.VarStore
|
|
99
|
+
regions = varStore.VarRegionList.Region
|
|
100
|
+
|
|
101
|
+
# Find all the input locations; this finds "poles", that are
|
|
102
|
+
# locations of the peaks, and "corners", that are locations
|
|
103
|
+
# of the corners of the regions. These two sets of locations
|
|
104
|
+
# together constitute inputLocations to consider.
|
|
105
|
+
|
|
106
|
+
poles = {(): None} # Just using it as an ordered set
|
|
107
|
+
inputLocations = set({()})
|
|
108
|
+
for varData in varStore.VarData:
|
|
109
|
+
regionIndices = varData.VarRegionIndex
|
|
110
|
+
for regionIndex in regionIndices:
|
|
111
|
+
peakLocation = []
|
|
112
|
+
corners = []
|
|
113
|
+
region = regions[regionIndex]
|
|
114
|
+
for axisIndex, axis in enumerate(region.VarRegionAxis):
|
|
115
|
+
if axis.PeakCoord == 0:
|
|
116
|
+
continue
|
|
117
|
+
axisTag = axisTags[axisIndex]
|
|
118
|
+
peakLocation.append((axisTag, axis.PeakCoord))
|
|
119
|
+
corner = []
|
|
120
|
+
if axis.StartCoord != 0:
|
|
121
|
+
corner.append((axisTag, axis.StartCoord))
|
|
122
|
+
if axis.EndCoord != 0:
|
|
123
|
+
corner.append((axisTag, axis.EndCoord))
|
|
124
|
+
corners.append(corner)
|
|
125
|
+
corners = set(product(*corners))
|
|
126
|
+
peakLocation = tuple(peakLocation)
|
|
127
|
+
poles[peakLocation] = None
|
|
128
|
+
inputLocations.add(peakLocation)
|
|
129
|
+
inputLocations.update(corners)
|
|
130
|
+
|
|
131
|
+
# Sort them by number of axes, then by axis order
|
|
132
|
+
inputLocations = [
|
|
133
|
+
dict(t)
|
|
134
|
+
for t in sorted(
|
|
135
|
+
inputLocations,
|
|
136
|
+
key=lambda t: (len(t), tuple(axisIndexes[tag] for tag, _ in t)),
|
|
137
|
+
)
|
|
138
|
+
]
|
|
139
|
+
poles = [dict(t) for t in poles.keys()]
|
|
140
|
+
inputLocations = _pruneLocations(inputLocations, list(poles), axisTags)
|
|
141
|
+
|
|
142
|
+
# Find the output locations, at input locations
|
|
143
|
+
varIdxMap = avar.table.VarIdxMap
|
|
144
|
+
instancer = VarStoreInstancer(varStore, fvarAxes)
|
|
145
|
+
for location in inputLocations:
|
|
146
|
+
instancer.setLocation(location)
|
|
147
|
+
outputLocation = {}
|
|
148
|
+
for axisIndex, axisTag in enumerate(axisTags):
|
|
149
|
+
varIdx = axisIndex
|
|
150
|
+
if varIdxMap is not None:
|
|
151
|
+
varIdx = varIdxMap[varIdx]
|
|
152
|
+
delta = instancer[varIdx]
|
|
153
|
+
if delta != 0:
|
|
154
|
+
v = location.get(axisTag, 0)
|
|
155
|
+
v = v + fi2fl(delta, 14)
|
|
156
|
+
# See https://github.com/fonttools/fonttools/pull/3598#issuecomment-2266082009
|
|
157
|
+
# v = max(-1, min(1, v))
|
|
158
|
+
outputLocation[axisTag] = v
|
|
159
|
+
mappings.append((location, outputLocation))
|
|
160
|
+
|
|
161
|
+
# Remove base master we added, if it maps to the default location
|
|
162
|
+
assert mappings[0][0] == {}
|
|
163
|
+
if mappings[0][1] == {}:
|
|
164
|
+
mappings.pop(0)
|
|
165
|
+
|
|
166
|
+
if denormalize:
|
|
167
|
+
for tag, seg in axisMaps.items():
|
|
168
|
+
if tag not in axisMap:
|
|
169
|
+
raise ValueError(f"Unknown axis tag {tag}")
|
|
170
|
+
denorm = lambda v: _denormalize(v, axisMap[tag])
|
|
171
|
+
axisMaps[tag] = {denorm(k): denorm(v) for k, v in seg.items()}
|
|
172
|
+
|
|
173
|
+
for i, (inputLoc, outputLoc) in enumerate(mappings):
|
|
174
|
+
inputLoc = {
|
|
175
|
+
tag: _denormalize(val, axisMap[tag]) for tag, val in inputLoc.items()
|
|
176
|
+
}
|
|
177
|
+
outputLoc = {
|
|
178
|
+
tag: _denormalize(val, axisMap[tag]) for tag, val in outputLoc.items()
|
|
179
|
+
}
|
|
180
|
+
mappings[i] = (inputLoc, outputLoc)
|
|
181
|
+
|
|
182
|
+
return axisMaps, mappings
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def main(args=None):
|
|
186
|
+
"""Add `avar` table from designspace file to variable font."""
|
|
187
|
+
|
|
188
|
+
if args is None:
|
|
189
|
+
import sys
|
|
190
|
+
|
|
191
|
+
args = sys.argv[1:]
|
|
192
|
+
|
|
193
|
+
from fontTools import configLogger
|
|
194
|
+
from fontTools.ttLib import TTFont
|
|
195
|
+
from fontTools.designspaceLib import DesignSpaceDocument
|
|
196
|
+
import argparse
|
|
197
|
+
|
|
198
|
+
parser = argparse.ArgumentParser(
|
|
199
|
+
"fonttools varLib.avar",
|
|
200
|
+
description="Add `avar` table from designspace file to variable font.",
|
|
201
|
+
)
|
|
202
|
+
parser.add_argument("font", metavar="varfont.ttf", help="Variable-font file.")
|
|
203
|
+
parser.add_argument(
|
|
204
|
+
"designspace",
|
|
205
|
+
metavar="family.designspace",
|
|
206
|
+
help="Designspace file.",
|
|
207
|
+
nargs="?",
|
|
208
|
+
default=None,
|
|
209
|
+
)
|
|
210
|
+
parser.add_argument(
|
|
211
|
+
"-o",
|
|
212
|
+
"--output-file",
|
|
213
|
+
type=str,
|
|
214
|
+
help="Output font file name.",
|
|
215
|
+
)
|
|
216
|
+
parser.add_argument(
|
|
217
|
+
"-v", "--verbose", action="store_true", help="Run more verbosely."
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
options = parser.parse_args(args)
|
|
221
|
+
|
|
222
|
+
configLogger(level=("INFO" if options.verbose else "WARNING"))
|
|
223
|
+
|
|
224
|
+
font = TTFont(options.font)
|
|
225
|
+
if not "fvar" in font:
|
|
226
|
+
log.error("Not a variable font.")
|
|
227
|
+
return 1
|
|
228
|
+
|
|
229
|
+
if options.designspace is None:
|
|
230
|
+
from pprint import pprint
|
|
231
|
+
|
|
232
|
+
segments, mappings = mappings_from_avar(font)
|
|
233
|
+
pprint(segments)
|
|
234
|
+
pprint(mappings)
|
|
235
|
+
print(len(mappings), "mappings")
|
|
236
|
+
return
|
|
237
|
+
|
|
238
|
+
axisTags = [a.axisTag for a in font["fvar"].axes]
|
|
239
|
+
|
|
240
|
+
ds = load_designspace(options.designspace, require_sources=False)
|
|
241
|
+
|
|
242
|
+
if "avar" in font:
|
|
243
|
+
log.warning("avar table already present, overwriting.")
|
|
244
|
+
del font["avar"]
|
|
245
|
+
|
|
246
|
+
_add_avar(font, ds.axes, ds.axisMappings, axisTags)
|
|
247
|
+
|
|
248
|
+
if options.output_file is None:
|
|
249
|
+
outfile = makeOutputFileName(options.font, overWrite=True, suffix=".avar")
|
|
250
|
+
else:
|
|
251
|
+
outfile = options.output_file
|
|
252
|
+
if outfile:
|
|
253
|
+
log.info("Saving %s", outfile)
|
|
254
|
+
font.save(outfile)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
if __name__ == "__main__":
|
|
258
|
+
import sys
|
|
259
|
+
|
|
260
|
+
sys.exit(main())
|