fonttools 4.60.2__cp311-cp311-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.
Files changed (353) hide show
  1. fontTools/__init__.py +8 -0
  2. fontTools/__main__.py +35 -0
  3. fontTools/afmLib.py +439 -0
  4. fontTools/agl.py +5233 -0
  5. fontTools/annotations.py +30 -0
  6. fontTools/cffLib/CFF2ToCFF.py +258 -0
  7. fontTools/cffLib/CFFToCFF2.py +305 -0
  8. fontTools/cffLib/__init__.py +3694 -0
  9. fontTools/cffLib/specializer.py +927 -0
  10. fontTools/cffLib/transforms.py +495 -0
  11. fontTools/cffLib/width.py +210 -0
  12. fontTools/colorLib/__init__.py +0 -0
  13. fontTools/colorLib/builder.py +664 -0
  14. fontTools/colorLib/errors.py +2 -0
  15. fontTools/colorLib/geometry.py +143 -0
  16. fontTools/colorLib/table_builder.py +223 -0
  17. fontTools/colorLib/unbuilder.py +81 -0
  18. fontTools/config/__init__.py +90 -0
  19. fontTools/cu2qu/__init__.py +15 -0
  20. fontTools/cu2qu/__main__.py +6 -0
  21. fontTools/cu2qu/benchmark.py +54 -0
  22. fontTools/cu2qu/cli.py +198 -0
  23. fontTools/cu2qu/cu2qu.c +15817 -0
  24. fontTools/cu2qu/cu2qu.cp311-win32.pyd +0 -0
  25. fontTools/cu2qu/cu2qu.py +563 -0
  26. fontTools/cu2qu/errors.py +77 -0
  27. fontTools/cu2qu/ufo.py +363 -0
  28. fontTools/designspaceLib/__init__.py +3343 -0
  29. fontTools/designspaceLib/__main__.py +6 -0
  30. fontTools/designspaceLib/split.py +475 -0
  31. fontTools/designspaceLib/statNames.py +260 -0
  32. fontTools/designspaceLib/types.py +147 -0
  33. fontTools/encodings/MacRoman.py +258 -0
  34. fontTools/encodings/StandardEncoding.py +258 -0
  35. fontTools/encodings/__init__.py +1 -0
  36. fontTools/encodings/codecs.py +135 -0
  37. fontTools/feaLib/__init__.py +4 -0
  38. fontTools/feaLib/__main__.py +78 -0
  39. fontTools/feaLib/ast.py +2143 -0
  40. fontTools/feaLib/builder.py +1814 -0
  41. fontTools/feaLib/error.py +22 -0
  42. fontTools/feaLib/lexer.c +17029 -0
  43. fontTools/feaLib/lexer.cp311-win32.pyd +0 -0
  44. fontTools/feaLib/lexer.py +287 -0
  45. fontTools/feaLib/location.py +12 -0
  46. fontTools/feaLib/lookupDebugInfo.py +12 -0
  47. fontTools/feaLib/parser.py +2394 -0
  48. fontTools/feaLib/variableScalar.py +118 -0
  49. fontTools/fontBuilder.py +1014 -0
  50. fontTools/help.py +36 -0
  51. fontTools/merge/__init__.py +248 -0
  52. fontTools/merge/__main__.py +6 -0
  53. fontTools/merge/base.py +81 -0
  54. fontTools/merge/cmap.py +173 -0
  55. fontTools/merge/layout.py +526 -0
  56. fontTools/merge/options.py +85 -0
  57. fontTools/merge/tables.py +352 -0
  58. fontTools/merge/unicode.py +78 -0
  59. fontTools/merge/util.py +143 -0
  60. fontTools/misc/__init__.py +1 -0
  61. fontTools/misc/arrayTools.py +424 -0
  62. fontTools/misc/bezierTools.c +39731 -0
  63. fontTools/misc/bezierTools.cp311-win32.pyd +0 -0
  64. fontTools/misc/bezierTools.py +1500 -0
  65. fontTools/misc/classifyTools.py +170 -0
  66. fontTools/misc/cliTools.py +53 -0
  67. fontTools/misc/configTools.py +349 -0
  68. fontTools/misc/cython.py +27 -0
  69. fontTools/misc/dictTools.py +83 -0
  70. fontTools/misc/eexec.py +119 -0
  71. fontTools/misc/encodingTools.py +72 -0
  72. fontTools/misc/enumTools.py +23 -0
  73. fontTools/misc/etree.py +456 -0
  74. fontTools/misc/filenames.py +245 -0
  75. fontTools/misc/filesystem/__init__.py +68 -0
  76. fontTools/misc/filesystem/_base.py +134 -0
  77. fontTools/misc/filesystem/_copy.py +45 -0
  78. fontTools/misc/filesystem/_errors.py +54 -0
  79. fontTools/misc/filesystem/_info.py +75 -0
  80. fontTools/misc/filesystem/_osfs.py +164 -0
  81. fontTools/misc/filesystem/_path.py +67 -0
  82. fontTools/misc/filesystem/_subfs.py +92 -0
  83. fontTools/misc/filesystem/_tempfs.py +34 -0
  84. fontTools/misc/filesystem/_tools.py +34 -0
  85. fontTools/misc/filesystem/_walk.py +55 -0
  86. fontTools/misc/filesystem/_zipfs.py +204 -0
  87. fontTools/misc/fixedTools.py +253 -0
  88. fontTools/misc/intTools.py +25 -0
  89. fontTools/misc/iterTools.py +12 -0
  90. fontTools/misc/lazyTools.py +42 -0
  91. fontTools/misc/loggingTools.py +543 -0
  92. fontTools/misc/macCreatorType.py +56 -0
  93. fontTools/misc/macRes.py +261 -0
  94. fontTools/misc/plistlib/__init__.py +681 -0
  95. fontTools/misc/plistlib/py.typed +0 -0
  96. fontTools/misc/psCharStrings.py +1511 -0
  97. fontTools/misc/psLib.py +398 -0
  98. fontTools/misc/psOperators.py +572 -0
  99. fontTools/misc/py23.py +96 -0
  100. fontTools/misc/roundTools.py +110 -0
  101. fontTools/misc/sstruct.py +227 -0
  102. fontTools/misc/symfont.py +242 -0
  103. fontTools/misc/testTools.py +233 -0
  104. fontTools/misc/textTools.py +156 -0
  105. fontTools/misc/timeTools.py +88 -0
  106. fontTools/misc/transform.py +516 -0
  107. fontTools/misc/treeTools.py +45 -0
  108. fontTools/misc/vector.py +147 -0
  109. fontTools/misc/visitor.py +158 -0
  110. fontTools/misc/xmlReader.py +188 -0
  111. fontTools/misc/xmlWriter.py +231 -0
  112. fontTools/mtiLib/__init__.py +1400 -0
  113. fontTools/mtiLib/__main__.py +5 -0
  114. fontTools/otlLib/__init__.py +1 -0
  115. fontTools/otlLib/builder.py +3465 -0
  116. fontTools/otlLib/error.py +11 -0
  117. fontTools/otlLib/maxContextCalc.py +96 -0
  118. fontTools/otlLib/optimize/__init__.py +53 -0
  119. fontTools/otlLib/optimize/__main__.py +6 -0
  120. fontTools/otlLib/optimize/gpos.py +439 -0
  121. fontTools/pens/__init__.py +1 -0
  122. fontTools/pens/areaPen.py +52 -0
  123. fontTools/pens/basePen.py +475 -0
  124. fontTools/pens/boundsPen.py +98 -0
  125. fontTools/pens/cairoPen.py +26 -0
  126. fontTools/pens/cocoaPen.py +26 -0
  127. fontTools/pens/cu2quPen.py +325 -0
  128. fontTools/pens/explicitClosingLinePen.py +101 -0
  129. fontTools/pens/filterPen.py +433 -0
  130. fontTools/pens/freetypePen.py +462 -0
  131. fontTools/pens/hashPointPen.py +89 -0
  132. fontTools/pens/momentsPen.c +13378 -0
  133. fontTools/pens/momentsPen.cp311-win32.pyd +0 -0
  134. fontTools/pens/momentsPen.py +879 -0
  135. fontTools/pens/perimeterPen.py +69 -0
  136. fontTools/pens/pointInsidePen.py +192 -0
  137. fontTools/pens/pointPen.py +643 -0
  138. fontTools/pens/qtPen.py +29 -0
  139. fontTools/pens/qu2cuPen.py +105 -0
  140. fontTools/pens/quartzPen.py +43 -0
  141. fontTools/pens/recordingPen.py +335 -0
  142. fontTools/pens/reportLabPen.py +79 -0
  143. fontTools/pens/reverseContourPen.py +96 -0
  144. fontTools/pens/roundingPen.py +130 -0
  145. fontTools/pens/statisticsPen.py +312 -0
  146. fontTools/pens/svgPathPen.py +310 -0
  147. fontTools/pens/t2CharStringPen.py +88 -0
  148. fontTools/pens/teePen.py +55 -0
  149. fontTools/pens/transformPen.py +115 -0
  150. fontTools/pens/ttGlyphPen.py +335 -0
  151. fontTools/pens/wxPen.py +29 -0
  152. fontTools/qu2cu/__init__.py +15 -0
  153. fontTools/qu2cu/__main__.py +7 -0
  154. fontTools/qu2cu/benchmark.py +56 -0
  155. fontTools/qu2cu/cli.py +125 -0
  156. fontTools/qu2cu/qu2cu.c +16682 -0
  157. fontTools/qu2cu/qu2cu.cp311-win32.pyd +0 -0
  158. fontTools/qu2cu/qu2cu.py +405 -0
  159. fontTools/subset/__init__.py +4096 -0
  160. fontTools/subset/__main__.py +6 -0
  161. fontTools/subset/cff.py +184 -0
  162. fontTools/subset/svg.py +253 -0
  163. fontTools/subset/util.py +25 -0
  164. fontTools/svgLib/__init__.py +3 -0
  165. fontTools/svgLib/path/__init__.py +65 -0
  166. fontTools/svgLib/path/arc.py +154 -0
  167. fontTools/svgLib/path/parser.py +322 -0
  168. fontTools/svgLib/path/shapes.py +183 -0
  169. fontTools/t1Lib/__init__.py +648 -0
  170. fontTools/tfmLib.py +460 -0
  171. fontTools/ttLib/__init__.py +30 -0
  172. fontTools/ttLib/__main__.py +148 -0
  173. fontTools/ttLib/macUtils.py +54 -0
  174. fontTools/ttLib/removeOverlaps.py +395 -0
  175. fontTools/ttLib/reorderGlyphs.py +285 -0
  176. fontTools/ttLib/scaleUpem.py +436 -0
  177. fontTools/ttLib/sfnt.py +661 -0
  178. fontTools/ttLib/standardGlyphOrder.py +271 -0
  179. fontTools/ttLib/tables/B_A_S_E_.py +14 -0
  180. fontTools/ttLib/tables/BitmapGlyphMetrics.py +64 -0
  181. fontTools/ttLib/tables/C_B_D_T_.py +113 -0
  182. fontTools/ttLib/tables/C_B_L_C_.py +19 -0
  183. fontTools/ttLib/tables/C_F_F_.py +61 -0
  184. fontTools/ttLib/tables/C_F_F__2.py +26 -0
  185. fontTools/ttLib/tables/C_O_L_R_.py +165 -0
  186. fontTools/ttLib/tables/C_P_A_L_.py +305 -0
  187. fontTools/ttLib/tables/D_S_I_G_.py +158 -0
  188. fontTools/ttLib/tables/D__e_b_g.py +35 -0
  189. fontTools/ttLib/tables/DefaultTable.py +49 -0
  190. fontTools/ttLib/tables/E_B_D_T_.py +835 -0
  191. fontTools/ttLib/tables/E_B_L_C_.py +718 -0
  192. fontTools/ttLib/tables/F_F_T_M_.py +52 -0
  193. fontTools/ttLib/tables/F__e_a_t.py +149 -0
  194. fontTools/ttLib/tables/G_D_E_F_.py +13 -0
  195. fontTools/ttLib/tables/G_M_A_P_.py +148 -0
  196. fontTools/ttLib/tables/G_P_K_G_.py +133 -0
  197. fontTools/ttLib/tables/G_P_O_S_.py +14 -0
  198. fontTools/ttLib/tables/G_S_U_B_.py +13 -0
  199. fontTools/ttLib/tables/G_V_A_R_.py +5 -0
  200. fontTools/ttLib/tables/G__l_a_t.py +235 -0
  201. fontTools/ttLib/tables/G__l_o_c.py +85 -0
  202. fontTools/ttLib/tables/H_V_A_R_.py +13 -0
  203. fontTools/ttLib/tables/J_S_T_F_.py +13 -0
  204. fontTools/ttLib/tables/L_T_S_H_.py +58 -0
  205. fontTools/ttLib/tables/M_A_T_H_.py +13 -0
  206. fontTools/ttLib/tables/M_E_T_A_.py +352 -0
  207. fontTools/ttLib/tables/M_V_A_R_.py +13 -0
  208. fontTools/ttLib/tables/O_S_2f_2.py +752 -0
  209. fontTools/ttLib/tables/S_I_N_G_.py +99 -0
  210. fontTools/ttLib/tables/S_T_A_T_.py +15 -0
  211. fontTools/ttLib/tables/S_V_G_.py +223 -0
  212. fontTools/ttLib/tables/S__i_l_f.py +1040 -0
  213. fontTools/ttLib/tables/S__i_l_l.py +92 -0
  214. fontTools/ttLib/tables/T_S_I_B_.py +13 -0
  215. fontTools/ttLib/tables/T_S_I_C_.py +14 -0
  216. fontTools/ttLib/tables/T_S_I_D_.py +13 -0
  217. fontTools/ttLib/tables/T_S_I_J_.py +13 -0
  218. fontTools/ttLib/tables/T_S_I_P_.py +13 -0
  219. fontTools/ttLib/tables/T_S_I_S_.py +13 -0
  220. fontTools/ttLib/tables/T_S_I_V_.py +26 -0
  221. fontTools/ttLib/tables/T_S_I__0.py +70 -0
  222. fontTools/ttLib/tables/T_S_I__1.py +163 -0
  223. fontTools/ttLib/tables/T_S_I__2.py +17 -0
  224. fontTools/ttLib/tables/T_S_I__3.py +22 -0
  225. fontTools/ttLib/tables/T_S_I__5.py +60 -0
  226. fontTools/ttLib/tables/T_T_F_A_.py +14 -0
  227. fontTools/ttLib/tables/TupleVariation.py +884 -0
  228. fontTools/ttLib/tables/V_A_R_C_.py +12 -0
  229. fontTools/ttLib/tables/V_D_M_X_.py +249 -0
  230. fontTools/ttLib/tables/V_O_R_G_.py +165 -0
  231. fontTools/ttLib/tables/V_V_A_R_.py +13 -0
  232. fontTools/ttLib/tables/__init__.py +98 -0
  233. fontTools/ttLib/tables/_a_n_k_r.py +15 -0
  234. fontTools/ttLib/tables/_a_v_a_r.py +193 -0
  235. fontTools/ttLib/tables/_b_s_l_n.py +15 -0
  236. fontTools/ttLib/tables/_c_i_d_g.py +24 -0
  237. fontTools/ttLib/tables/_c_m_a_p.py +1591 -0
  238. fontTools/ttLib/tables/_c_v_a_r.py +94 -0
  239. fontTools/ttLib/tables/_c_v_t.py +56 -0
  240. fontTools/ttLib/tables/_f_e_a_t.py +15 -0
  241. fontTools/ttLib/tables/_f_p_g_m.py +62 -0
  242. fontTools/ttLib/tables/_f_v_a_r.py +261 -0
  243. fontTools/ttLib/tables/_g_a_s_p.py +63 -0
  244. fontTools/ttLib/tables/_g_c_i_d.py +13 -0
  245. fontTools/ttLib/tables/_g_l_y_f.py +2311 -0
  246. fontTools/ttLib/tables/_g_v_a_r.py +340 -0
  247. fontTools/ttLib/tables/_h_d_m_x.py +127 -0
  248. fontTools/ttLib/tables/_h_e_a_d.py +130 -0
  249. fontTools/ttLib/tables/_h_h_e_a.py +147 -0
  250. fontTools/ttLib/tables/_h_m_t_x.py +164 -0
  251. fontTools/ttLib/tables/_k_e_r_n.py +289 -0
  252. fontTools/ttLib/tables/_l_c_a_r.py +13 -0
  253. fontTools/ttLib/tables/_l_o_c_a.py +70 -0
  254. fontTools/ttLib/tables/_l_t_a_g.py +72 -0
  255. fontTools/ttLib/tables/_m_a_x_p.py +147 -0
  256. fontTools/ttLib/tables/_m_e_t_a.py +112 -0
  257. fontTools/ttLib/tables/_m_o_r_t.py +14 -0
  258. fontTools/ttLib/tables/_m_o_r_x.py +15 -0
  259. fontTools/ttLib/tables/_n_a_m_e.py +1242 -0
  260. fontTools/ttLib/tables/_o_p_b_d.py +14 -0
  261. fontTools/ttLib/tables/_p_o_s_t.py +319 -0
  262. fontTools/ttLib/tables/_p_r_e_p.py +16 -0
  263. fontTools/ttLib/tables/_p_r_o_p.py +12 -0
  264. fontTools/ttLib/tables/_s_b_i_x.py +129 -0
  265. fontTools/ttLib/tables/_t_r_a_k.py +332 -0
  266. fontTools/ttLib/tables/_v_h_e_a.py +139 -0
  267. fontTools/ttLib/tables/_v_m_t_x.py +19 -0
  268. fontTools/ttLib/tables/asciiTable.py +20 -0
  269. fontTools/ttLib/tables/grUtils.py +92 -0
  270. fontTools/ttLib/tables/otBase.py +1458 -0
  271. fontTools/ttLib/tables/otConverters.py +2068 -0
  272. fontTools/ttLib/tables/otData.py +6400 -0
  273. fontTools/ttLib/tables/otTables.py +2703 -0
  274. fontTools/ttLib/tables/otTraverse.py +163 -0
  275. fontTools/ttLib/tables/sbixGlyph.py +149 -0
  276. fontTools/ttLib/tables/sbixStrike.py +177 -0
  277. fontTools/ttLib/tables/table_API_readme.txt +91 -0
  278. fontTools/ttLib/tables/ttProgram.py +594 -0
  279. fontTools/ttLib/ttCollection.py +125 -0
  280. fontTools/ttLib/ttFont.py +1148 -0
  281. fontTools/ttLib/ttGlyphSet.py +490 -0
  282. fontTools/ttLib/ttVisitor.py +32 -0
  283. fontTools/ttLib/woff2.py +1680 -0
  284. fontTools/ttx.py +479 -0
  285. fontTools/ufoLib/__init__.py +2575 -0
  286. fontTools/ufoLib/converters.py +407 -0
  287. fontTools/ufoLib/errors.py +30 -0
  288. fontTools/ufoLib/etree.py +6 -0
  289. fontTools/ufoLib/filenames.py +356 -0
  290. fontTools/ufoLib/glifLib.py +2120 -0
  291. fontTools/ufoLib/kerning.py +141 -0
  292. fontTools/ufoLib/plistlib.py +47 -0
  293. fontTools/ufoLib/pointPen.py +6 -0
  294. fontTools/ufoLib/utils.py +107 -0
  295. fontTools/ufoLib/validators.py +1208 -0
  296. fontTools/unicode.py +50 -0
  297. fontTools/unicodedata/Blocks.py +817 -0
  298. fontTools/unicodedata/Mirrored.py +446 -0
  299. fontTools/unicodedata/OTTags.py +50 -0
  300. fontTools/unicodedata/ScriptExtensions.py +832 -0
  301. fontTools/unicodedata/Scripts.py +3639 -0
  302. fontTools/unicodedata/__init__.py +306 -0
  303. fontTools/varLib/__init__.py +1600 -0
  304. fontTools/varLib/__main__.py +6 -0
  305. fontTools/varLib/avar/__init__.py +0 -0
  306. fontTools/varLib/avar/__main__.py +72 -0
  307. fontTools/varLib/avar/build.py +79 -0
  308. fontTools/varLib/avar/map.py +108 -0
  309. fontTools/varLib/avar/plan.py +1004 -0
  310. fontTools/varLib/avar/unbuild.py +271 -0
  311. fontTools/varLib/avarPlanner.py +8 -0
  312. fontTools/varLib/builder.py +215 -0
  313. fontTools/varLib/cff.py +631 -0
  314. fontTools/varLib/errors.py +219 -0
  315. fontTools/varLib/featureVars.py +703 -0
  316. fontTools/varLib/hvar.py +113 -0
  317. fontTools/varLib/instancer/__init__.py +2052 -0
  318. fontTools/varLib/instancer/__main__.py +5 -0
  319. fontTools/varLib/instancer/featureVars.py +190 -0
  320. fontTools/varLib/instancer/names.py +388 -0
  321. fontTools/varLib/instancer/solver.py +309 -0
  322. fontTools/varLib/interpolatable.py +1209 -0
  323. fontTools/varLib/interpolatableHelpers.py +399 -0
  324. fontTools/varLib/interpolatablePlot.py +1269 -0
  325. fontTools/varLib/interpolatableTestContourOrder.py +82 -0
  326. fontTools/varLib/interpolatableTestStartingPoint.py +107 -0
  327. fontTools/varLib/interpolate_layout.py +124 -0
  328. fontTools/varLib/iup.c +19815 -0
  329. fontTools/varLib/iup.cp311-win32.pyd +0 -0
  330. fontTools/varLib/iup.py +490 -0
  331. fontTools/varLib/merger.py +1717 -0
  332. fontTools/varLib/models.py +642 -0
  333. fontTools/varLib/multiVarStore.py +253 -0
  334. fontTools/varLib/mutator.py +529 -0
  335. fontTools/varLib/mvar.py +40 -0
  336. fontTools/varLib/plot.py +238 -0
  337. fontTools/varLib/stat.py +149 -0
  338. fontTools/varLib/varStore.py +739 -0
  339. fontTools/voltLib/__init__.py +5 -0
  340. fontTools/voltLib/__main__.py +206 -0
  341. fontTools/voltLib/ast.py +452 -0
  342. fontTools/voltLib/error.py +12 -0
  343. fontTools/voltLib/lexer.py +99 -0
  344. fontTools/voltLib/parser.py +664 -0
  345. fontTools/voltLib/voltToFea.py +911 -0
  346. fonttools-4.60.2.data/data/share/man/man1/ttx.1 +225 -0
  347. fonttools-4.60.2.dist-info/METADATA +2250 -0
  348. fonttools-4.60.2.dist-info/RECORD +353 -0
  349. fonttools-4.60.2.dist-info/WHEEL +5 -0
  350. fonttools-4.60.2.dist-info/entry_points.txt +5 -0
  351. fonttools-4.60.2.dist-info/licenses/LICENSE +21 -0
  352. fonttools-4.60.2.dist-info/licenses/LICENSE.external +388 -0
  353. fonttools-4.60.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,309 @@
1
+ from fontTools.varLib.models import supportScalar
2
+ from fontTools.misc.fixedTools import MAX_F2DOT14
3
+ from functools import lru_cache
4
+
5
+ __all__ = ["rebaseTent"]
6
+
7
+ EPSILON = 1 / (1 << 14)
8
+
9
+
10
+ def _reverse_negate(v):
11
+ return (-v[2], -v[1], -v[0])
12
+
13
+
14
+ def _solve(tent, axisLimit, negative=False):
15
+ axisMin, axisDef, axisMax, _distanceNegative, _distancePositive = axisLimit
16
+ lower, peak, upper = tent
17
+
18
+ # Mirror the problem such that axisDef <= peak
19
+ if axisDef > peak:
20
+ return [
21
+ (scalar, _reverse_negate(t) if t is not None else None)
22
+ for scalar, t in _solve(
23
+ _reverse_negate(tent),
24
+ axisLimit.reverse_negate(),
25
+ not negative,
26
+ )
27
+ ]
28
+ # axisDef <= peak
29
+
30
+ # case 1: The whole deltaset falls outside the new limit; we can drop it
31
+ #
32
+ # peak
33
+ # 1.........................................o..........
34
+ # / \
35
+ # / \
36
+ # / \
37
+ # / \
38
+ # 0---|-----------|----------|-------- o o----1
39
+ # axisMin axisDef axisMax lower upper
40
+ #
41
+ if axisMax <= lower and axisMax < peak:
42
+ return [] # No overlap
43
+
44
+ # case 2: Only the peak and outermost bound fall outside the new limit;
45
+ # we keep the deltaset, update peak and outermost bound and and scale deltas
46
+ # by the scalar value for the restricted axis at the new limit, and solve
47
+ # recursively.
48
+ #
49
+ # |peak
50
+ # 1...............................|.o..........
51
+ # |/ \
52
+ # / \
53
+ # /| \
54
+ # / | \
55
+ # 0--------------------------- o | o----1
56
+ # lower | upper
57
+ # |
58
+ # axisMax
59
+ #
60
+ # Convert to:
61
+ #
62
+ # 1............................................
63
+ # |
64
+ # o peak
65
+ # /|
66
+ # /x|
67
+ # 0--------------------------- o o upper ----1
68
+ # lower |
69
+ # |
70
+ # axisMax
71
+ if axisMax < peak:
72
+ mult = supportScalar({"tag": axisMax}, {"tag": tent})
73
+ tent = (lower, axisMax, axisMax)
74
+ return [(scalar * mult, t) for scalar, t in _solve(tent, axisLimit)]
75
+
76
+ # lower <= axisDef <= peak <= axisMax
77
+
78
+ gain = supportScalar({"tag": axisDef}, {"tag": tent})
79
+ out = [(gain, None)]
80
+
81
+ # First, the positive side
82
+
83
+ # outGain is the scalar of axisMax at the tent.
84
+ outGain = supportScalar({"tag": axisMax}, {"tag": tent})
85
+
86
+ # Case 3a: Gain is more than outGain. The tent down-slope crosses
87
+ # the axis into negative. We have to split it into multiples.
88
+ #
89
+ # | peak |
90
+ # 1...................|.o.....|..............
91
+ # |/x\_ |
92
+ # gain................+....+_.|..............
93
+ # /| |y\|
94
+ # ................../.|....|..+_......outGain
95
+ # / | | | \
96
+ # 0---|-----------o | | | o----------1
97
+ # axisMin lower | | | upper
98
+ # | | |
99
+ # axisDef | axisMax
100
+ # |
101
+ # crossing
102
+ if gain >= outGain:
103
+ # Note that this is the branch taken if both gain and outGain are 0.
104
+
105
+ # Crossing point on the axis.
106
+ crossing = peak + (1 - gain) * (upper - peak)
107
+
108
+ loc = (max(lower, axisDef), peak, crossing)
109
+ scalar = 1
110
+
111
+ # The part before the crossing point.
112
+ out.append((scalar - gain, loc))
113
+
114
+ # The part after the crossing point may use one or two tents,
115
+ # depending on whether upper is before axisMax or not, in one
116
+ # case we need to keep it down to eternity.
117
+
118
+ # Case 3a1, similar to case 1neg; just one tent needed, as in
119
+ # the drawing above.
120
+ if upper >= axisMax:
121
+ loc = (crossing, axisMax, axisMax)
122
+ scalar = outGain
123
+
124
+ out.append((scalar - gain, loc))
125
+
126
+ # Case 3a2: Similar to case 2neg; two tents needed, to keep
127
+ # down to eternity.
128
+ #
129
+ # | peak |
130
+ # 1...................|.o................|...
131
+ # |/ \_ |
132
+ # gain................+....+_............|...
133
+ # /| | \xxxxxxxxxxy|
134
+ # / | | \_xxxxxyyyy|
135
+ # / | | \xxyyyyyy|
136
+ # 0---|-----------o | | o-------|--1
137
+ # axisMin lower | | upper |
138
+ # | | |
139
+ # axisDef | axisMax
140
+ # |
141
+ # crossing
142
+ else:
143
+ # A tent's peak cannot fall on axis default. Nudge it.
144
+ if upper == axisDef:
145
+ upper += EPSILON
146
+
147
+ # Downslope.
148
+ loc1 = (crossing, upper, axisMax)
149
+ scalar1 = 0
150
+
151
+ # Eternity justify.
152
+ loc2 = (upper, axisMax, axisMax)
153
+ scalar2 = 0
154
+
155
+ out.append((scalar1 - gain, loc1))
156
+ out.append((scalar2 - gain, loc2))
157
+
158
+ else:
159
+ # Special-case if peak is at axisMax.
160
+ if axisMax == peak:
161
+ upper = peak
162
+
163
+ # Case 3:
164
+ # We keep delta as is and only scale the axis upper to achieve
165
+ # the desired new tent if feasible.
166
+ #
167
+ # peak
168
+ # 1.....................o....................
169
+ # / \_|
170
+ # ..................../....+_.........outGain
171
+ # / | \
172
+ # gain..............+......|..+_.............
173
+ # /| | | \
174
+ # 0---|-----------o | | | o----------1
175
+ # axisMin lower| | | upper
176
+ # | | newUpper
177
+ # axisDef axisMax
178
+ #
179
+ newUpper = peak + (1 - gain) * (upper - peak)
180
+ assert axisMax <= newUpper # Because outGain > gain
181
+ # Disabled because ots doesn't like us:
182
+ # https://github.com/fonttools/fonttools/issues/3350
183
+ if False and newUpper <= axisDef + (axisMax - axisDef) * 2:
184
+ upper = newUpper
185
+ if not negative and axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper:
186
+ # we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience
187
+ upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14
188
+ assert peak < upper
189
+
190
+ loc = (max(axisDef, lower), peak, upper)
191
+ scalar = 1
192
+
193
+ out.append((scalar - gain, loc))
194
+
195
+ # Case 4: New limit doesn't fit; we need to chop into two tents,
196
+ # because the shape of a triangle with part of one side cut off
197
+ # cannot be represented as a triangle itself.
198
+ #
199
+ # | peak |
200
+ # 1.........|......o.|....................
201
+ # ..........|...../x\|.............outGain
202
+ # | |xxy|\_
203
+ # | /xxxy| \_
204
+ # | |xxxxy| \_
205
+ # | /xxxxy| \_
206
+ # 0---|-----|-oxxxxxx| o----------1
207
+ # axisMin | lower | upper
208
+ # | |
209
+ # axisDef axisMax
210
+ #
211
+ else:
212
+ loc1 = (max(axisDef, lower), peak, axisMax)
213
+ scalar1 = 1
214
+
215
+ loc2 = (peak, axisMax, axisMax)
216
+ scalar2 = outGain
217
+
218
+ out.append((scalar1 - gain, loc1))
219
+ # Don't add a dirac delta!
220
+ if peak < axisMax:
221
+ out.append((scalar2 - gain, loc2))
222
+
223
+ # Now, the negative side
224
+
225
+ # Case 1neg: Lower extends beyond axisMin: we chop. Simple.
226
+ #
227
+ # | |peak
228
+ # 1..................|...|.o.................
229
+ # | |/ \
230
+ # gain...............|...+...\...............
231
+ # |x_/| \
232
+ # |/ | \
233
+ # _/| | \
234
+ # 0---------------o | | o----------1
235
+ # lower | | upper
236
+ # | |
237
+ # axisMin axisDef
238
+ #
239
+ if lower <= axisMin:
240
+ loc = (axisMin, axisMin, axisDef)
241
+ scalar = supportScalar({"tag": axisMin}, {"tag": tent})
242
+
243
+ out.append((scalar - gain, loc))
244
+
245
+ # Case 2neg: Lower is betwen axisMin and axisDef: we add two
246
+ # tents to keep it down all the way to eternity.
247
+ #
248
+ # | |peak
249
+ # 1...|...............|.o.................
250
+ # | |/ \
251
+ # gain|...............+...\...............
252
+ # |yxxxxxxxxxxxxx/| \
253
+ # |yyyyyyxxxxxxx/ | \
254
+ # |yyyyyyyyyyyx/ | \
255
+ # 0---|-----------o | o----------1
256
+ # axisMin lower | upper
257
+ # |
258
+ # axisDef
259
+ #
260
+ else:
261
+ # A tent's peak cannot fall on axis default. Nudge it.
262
+ if lower == axisDef:
263
+ lower -= EPSILON
264
+
265
+ # Downslope.
266
+ loc1 = (axisMin, lower, axisDef)
267
+ scalar1 = 0
268
+
269
+ # Eternity justify.
270
+ loc2 = (axisMin, axisMin, lower)
271
+ scalar2 = 0
272
+
273
+ out.append((scalar1 - gain, loc1))
274
+ out.append((scalar2 - gain, loc2))
275
+
276
+ return out
277
+
278
+
279
+ @lru_cache(128)
280
+ def rebaseTent(tent, axisLimit):
281
+ """Given a tuple (lower,peak,upper) "tent" and new axis limits
282
+ (axisMin,axisDefault,axisMax), solves how to represent the tent
283
+ under the new axis configuration. All values are in normalized
284
+ -1,0,+1 coordinate system. Tent values can be outside this range.
285
+
286
+ Return value is a list of tuples. Each tuple is of the form
287
+ (scalar,tent), where scalar is a multipler to multiply any
288
+ delta-sets by, and tent is a new tent for that output delta-set.
289
+ If tent value is None, that is a special deltaset that should
290
+ be always-enabled (called "gain")."""
291
+
292
+ axisMin, axisDef, axisMax, _distanceNegative, _distancePositive = axisLimit
293
+ assert -1 <= axisMin <= axisDef <= axisMax <= +1
294
+
295
+ lower, peak, upper = tent
296
+ assert -2 <= lower <= peak <= upper <= +2
297
+
298
+ assert peak != 0
299
+
300
+ sols = _solve(tent, axisLimit)
301
+
302
+ n = lambda v: axisLimit.renormalizeValue(v)
303
+ sols = [
304
+ (scalar, (n(v[0]), n(v[1]), n(v[2])) if v is not None else None)
305
+ for scalar, v in sols
306
+ if scalar
307
+ ]
308
+
309
+ return sols