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,436 @@
1
+ """Change the units-per-EM of a font.
2
+
3
+ AAT and Graphite tables are not supported. CFF/CFF2 fonts
4
+ are de-subroutinized."""
5
+
6
+ from fontTools.ttLib.ttVisitor import TTVisitor
7
+ import fontTools.ttLib as ttLib
8
+ import fontTools.ttLib.tables.otBase as otBase
9
+ import fontTools.ttLib.tables.otTables as otTables
10
+ from fontTools.cffLib import VarStoreData
11
+ import fontTools.cffLib.specializer as cffSpecializer
12
+ from fontTools.varLib import builder # for VarData.calculateNumShorts
13
+ from fontTools.varLib.multiVarStore import OnlineMultiVarStoreBuilder
14
+ from fontTools.misc.vector import Vector
15
+ from fontTools.misc.fixedTools import otRound
16
+ from fontTools.misc.iterTools import batched
17
+
18
+
19
+ __all__ = ["scale_upem", "ScalerVisitor"]
20
+
21
+
22
+ class ScalerVisitor(TTVisitor):
23
+ def __init__(self, scaleFactor):
24
+ self.scaleFactor = scaleFactor
25
+
26
+ def scale(self, v):
27
+ return otRound(v * self.scaleFactor)
28
+
29
+
30
+ @ScalerVisitor.register_attrs(
31
+ (
32
+ (ttLib.getTableClass("head"), ("unitsPerEm", "xMin", "yMin", "xMax", "yMax")),
33
+ (ttLib.getTableClass("post"), ("underlinePosition", "underlineThickness")),
34
+ (ttLib.getTableClass("VORG"), ("defaultVertOriginY")),
35
+ (
36
+ ttLib.getTableClass("hhea"),
37
+ (
38
+ "ascent",
39
+ "descent",
40
+ "lineGap",
41
+ "advanceWidthMax",
42
+ "minLeftSideBearing",
43
+ "minRightSideBearing",
44
+ "xMaxExtent",
45
+ "caretOffset",
46
+ ),
47
+ ),
48
+ (
49
+ ttLib.getTableClass("vhea"),
50
+ (
51
+ "ascent",
52
+ "descent",
53
+ "lineGap",
54
+ "advanceHeightMax",
55
+ "minTopSideBearing",
56
+ "minBottomSideBearing",
57
+ "yMaxExtent",
58
+ "caretOffset",
59
+ ),
60
+ ),
61
+ (
62
+ ttLib.getTableClass("OS/2"),
63
+ (
64
+ "xAvgCharWidth",
65
+ "ySubscriptXSize",
66
+ "ySubscriptYSize",
67
+ "ySubscriptXOffset",
68
+ "ySubscriptYOffset",
69
+ "ySuperscriptXSize",
70
+ "ySuperscriptYSize",
71
+ "ySuperscriptXOffset",
72
+ "ySuperscriptYOffset",
73
+ "yStrikeoutSize",
74
+ "yStrikeoutPosition",
75
+ "sTypoAscender",
76
+ "sTypoDescender",
77
+ "sTypoLineGap",
78
+ "usWinAscent",
79
+ "usWinDescent",
80
+ "sxHeight",
81
+ "sCapHeight",
82
+ ),
83
+ ),
84
+ (
85
+ otTables.ValueRecord,
86
+ ("XAdvance", "YAdvance", "XPlacement", "YPlacement"),
87
+ ), # GPOS
88
+ (otTables.Anchor, ("XCoordinate", "YCoordinate")), # GPOS
89
+ (otTables.CaretValue, ("Coordinate")), # GDEF
90
+ (otTables.BaseCoord, ("Coordinate")), # BASE
91
+ (otTables.MathValueRecord, ("Value")), # MATH
92
+ (otTables.ClipBox, ("xMin", "yMin", "xMax", "yMax")), # COLR
93
+ )
94
+ )
95
+ def visit(visitor, obj, attr, value):
96
+ setattr(obj, attr, visitor.scale(value))
97
+
98
+
99
+ @ScalerVisitor.register_attr(
100
+ (ttLib.getTableClass("hmtx"), ttLib.getTableClass("vmtx")), "metrics"
101
+ )
102
+ def visit(visitor, obj, attr, metrics):
103
+ for g in metrics:
104
+ advance, lsb = metrics[g]
105
+ metrics[g] = visitor.scale(advance), visitor.scale(lsb)
106
+
107
+
108
+ @ScalerVisitor.register_attr(ttLib.getTableClass("VMTX"), "VOriginRecords")
109
+ def visit(visitor, obj, attr, VOriginRecords):
110
+ for g in VOriginRecords:
111
+ VOriginRecords[g] = visitor.scale(VOriginRecords[g])
112
+
113
+
114
+ @ScalerVisitor.register_attr(ttLib.getTableClass("glyf"), "glyphs")
115
+ def visit(visitor, obj, attr, glyphs):
116
+ for g in glyphs.values():
117
+ for attr in ("xMin", "xMax", "yMin", "yMax"):
118
+ v = getattr(g, attr, None)
119
+ if v is not None:
120
+ setattr(g, attr, visitor.scale(v))
121
+
122
+ if g.isComposite():
123
+ for component in g.components:
124
+ component.x = visitor.scale(component.x)
125
+ component.y = visitor.scale(component.y)
126
+ continue
127
+
128
+ if hasattr(g, "coordinates"):
129
+ coordinates = g.coordinates
130
+ for i, (x, y) in enumerate(coordinates):
131
+ coordinates[i] = visitor.scale(x), visitor.scale(y)
132
+
133
+
134
+ @ScalerVisitor.register_attr(ttLib.getTableClass("gvar"), "variations")
135
+ def visit(visitor, obj, attr, variations):
136
+ glyfTable = visitor.font["glyf"]
137
+
138
+ for glyphName, varlist in variations.items():
139
+ glyph = glyfTable[glyphName]
140
+ for var in varlist:
141
+ coordinates = var.coordinates
142
+ for i, xy in enumerate(coordinates):
143
+ if xy is None:
144
+ continue
145
+ coordinates[i] = visitor.scale(xy[0]), visitor.scale(xy[1])
146
+
147
+
148
+ @ScalerVisitor.register_attr(ttLib.getTableClass("VARC"), "table")
149
+ def visit(visitor, obj, attr, varc):
150
+ # VarComposite variations are a pain
151
+
152
+ fvar = visitor.font["fvar"]
153
+ fvarAxes = [a.axisTag for a in fvar.axes]
154
+
155
+ store = varc.MultiVarStore
156
+ storeBuilder = OnlineMultiVarStoreBuilder(fvarAxes)
157
+
158
+ for g in varc.VarCompositeGlyphs.VarCompositeGlyph:
159
+ for component in g.components:
160
+ t = component.transform
161
+ t.translateX = visitor.scale(t.translateX)
162
+ t.translateY = visitor.scale(t.translateY)
163
+ t.tCenterX = visitor.scale(t.tCenterX)
164
+ t.tCenterY = visitor.scale(t.tCenterY)
165
+
166
+ if component.axisValuesVarIndex != otTables.NO_VARIATION_INDEX:
167
+ varIdx = component.axisValuesVarIndex
168
+ # TODO Move this code duplicated below to MultiVarStore.__getitem__,
169
+ # or a getDeltasAndSupports().
170
+ if varIdx != otTables.NO_VARIATION_INDEX:
171
+ major = varIdx >> 16
172
+ minor = varIdx & 0xFFFF
173
+ varData = store.MultiVarData[major]
174
+ vec = varData.Item[minor]
175
+ storeBuilder.setSupports(store.get_supports(major, fvar.axes))
176
+ if vec:
177
+ m = len(vec) // varData.VarRegionCount
178
+ vec = list(batched(vec, m))
179
+ vec = [Vector(v) for v in vec]
180
+ component.axisValuesVarIndex = storeBuilder.storeDeltas(vec)
181
+ else:
182
+ component.axisValuesVarIndex = otTables.NO_VARIATION_INDEX
183
+
184
+ if component.transformVarIndex != otTables.NO_VARIATION_INDEX:
185
+ varIdx = component.transformVarIndex
186
+ if varIdx != otTables.NO_VARIATION_INDEX:
187
+ major = varIdx >> 16
188
+ minor = varIdx & 0xFFFF
189
+ vec = varData.Item[varIdx & 0xFFFF]
190
+ major = varIdx >> 16
191
+ minor = varIdx & 0xFFFF
192
+ varData = store.MultiVarData[major]
193
+ vec = varData.Item[minor]
194
+ storeBuilder.setSupports(store.get_supports(major, fvar.axes))
195
+ if vec:
196
+ m = len(vec) // varData.VarRegionCount
197
+ flags = component.flags
198
+ vec = list(batched(vec, m))
199
+ newVec = []
200
+ for v in vec:
201
+ v = list(v)
202
+ i = 0
203
+ ## Scale translate & tCenter
204
+ if flags & otTables.VarComponentFlags.HAVE_TRANSLATE_X:
205
+ v[i] = visitor.scale(v[i])
206
+ i += 1
207
+ if flags & otTables.VarComponentFlags.HAVE_TRANSLATE_Y:
208
+ v[i] = visitor.scale(v[i])
209
+ i += 1
210
+ if flags & otTables.VarComponentFlags.HAVE_ROTATION:
211
+ i += 1
212
+ if flags & otTables.VarComponentFlags.HAVE_SCALE_X:
213
+ i += 1
214
+ if flags & otTables.VarComponentFlags.HAVE_SCALE_Y:
215
+ i += 1
216
+ if flags & otTables.VarComponentFlags.HAVE_SKEW_X:
217
+ i += 1
218
+ if flags & otTables.VarComponentFlags.HAVE_SKEW_Y:
219
+ i += 1
220
+ if flags & otTables.VarComponentFlags.HAVE_TCENTER_X:
221
+ v[i] = visitor.scale(v[i])
222
+ i += 1
223
+ if flags & otTables.VarComponentFlags.HAVE_TCENTER_Y:
224
+ v[i] = visitor.scale(v[i])
225
+ i += 1
226
+
227
+ newVec.append(Vector(v))
228
+ vec = newVec
229
+
230
+ component.transformVarIndex = storeBuilder.storeDeltas(vec)
231
+ else:
232
+ component.transformVarIndex = otTables.NO_VARIATION_INDEX
233
+
234
+ varc.MultiVarStore = storeBuilder.finish()
235
+
236
+
237
+ @ScalerVisitor.register_attr(ttLib.getTableClass("kern"), "kernTables")
238
+ def visit(visitor, obj, attr, kernTables):
239
+ for table in kernTables:
240
+ kernTable = table.kernTable
241
+ for k in kernTable.keys():
242
+ kernTable[k] = visitor.scale(kernTable[k])
243
+
244
+
245
+ def _cff_scale(visitor, args):
246
+ for i, arg in enumerate(args):
247
+ if not isinstance(arg, list):
248
+ if not isinstance(arg, bytes):
249
+ args[i] = visitor.scale(arg)
250
+ else:
251
+ num_blends = arg[-1]
252
+ _cff_scale(visitor, arg)
253
+ arg[-1] = num_blends
254
+
255
+
256
+ @ScalerVisitor.register_attr(
257
+ (ttLib.getTableClass("CFF "), ttLib.getTableClass("CFF2")), "cff"
258
+ )
259
+ def visit(visitor, obj, attr, cff):
260
+ cff.desubroutinize()
261
+ topDict = cff.topDictIndex[0]
262
+ varStore = getattr(topDict, "VarStore", None)
263
+ getNumRegions = varStore.getNumRegions if varStore is not None else None
264
+ privates = set()
265
+ for fontname in cff.keys():
266
+ font = cff[fontname]
267
+ cs = font.CharStrings
268
+ for g in font.charset:
269
+ c, _ = cs.getItemAndSelector(g)
270
+ privates.add(c.private)
271
+
272
+ commands = cffSpecializer.programToCommands(
273
+ c.program, getNumRegions=getNumRegions
274
+ )
275
+ for op, args in commands:
276
+ if op == "vsindex":
277
+ continue
278
+ _cff_scale(visitor, args)
279
+ c.program[:] = cffSpecializer.commandsToProgram(commands)
280
+
281
+ # Annoying business of scaling numbers that do not matter whatsoever
282
+
283
+ for attr in (
284
+ "UnderlinePosition",
285
+ "UnderlineThickness",
286
+ "FontBBox",
287
+ "StrokeWidth",
288
+ ):
289
+ value = getattr(topDict, attr, None)
290
+ if value is None:
291
+ continue
292
+ if isinstance(value, list):
293
+ _cff_scale(visitor, value)
294
+ else:
295
+ setattr(topDict, attr, visitor.scale(value))
296
+
297
+ for i in range(6):
298
+ topDict.FontMatrix[i] /= visitor.scaleFactor
299
+
300
+ for private in privates:
301
+ for attr in (
302
+ "BlueValues",
303
+ "OtherBlues",
304
+ "FamilyBlues",
305
+ "FamilyOtherBlues",
306
+ # "BlueScale",
307
+ # "BlueShift",
308
+ # "BlueFuzz",
309
+ "StdHW",
310
+ "StdVW",
311
+ "StemSnapH",
312
+ "StemSnapV",
313
+ "defaultWidthX",
314
+ "nominalWidthX",
315
+ ):
316
+ value = getattr(private, attr, None)
317
+ if value is None:
318
+ continue
319
+ if isinstance(value, list):
320
+ _cff_scale(visitor, value)
321
+ else:
322
+ setattr(private, attr, visitor.scale(value))
323
+
324
+
325
+ # ItemVariationStore
326
+
327
+
328
+ @ScalerVisitor.register(otTables.VarData)
329
+ def visit(visitor, varData):
330
+ for item in varData.Item:
331
+ for i, v in enumerate(item):
332
+ item[i] = visitor.scale(v)
333
+ varData.calculateNumShorts()
334
+
335
+
336
+ # COLRv1
337
+
338
+
339
+ def _setup_scale_paint(paint, scale):
340
+ if -2 <= scale <= 2 - (1 >> 14):
341
+ paint.Format = otTables.PaintFormat.PaintScaleUniform
342
+ paint.scale = scale
343
+ return
344
+
345
+ transform = otTables.Affine2x3()
346
+ transform.populateDefaults()
347
+ transform.xy = transform.yx = transform.dx = transform.dy = 0
348
+ transform.xx = transform.yy = scale
349
+
350
+ paint.Format = otTables.PaintFormat.PaintTransform
351
+ paint.Transform = transform
352
+
353
+
354
+ @ScalerVisitor.register(otTables.BaseGlyphPaintRecord)
355
+ def visit(visitor, record):
356
+ oldPaint = record.Paint
357
+
358
+ scale = otTables.Paint()
359
+ _setup_scale_paint(scale, visitor.scaleFactor)
360
+ scale.Paint = oldPaint
361
+
362
+ record.Paint = scale
363
+
364
+ return True
365
+
366
+
367
+ @ScalerVisitor.register(otTables.Paint)
368
+ def visit(visitor, paint):
369
+ if paint.Format != otTables.PaintFormat.PaintGlyph:
370
+ return True
371
+
372
+ newPaint = otTables.Paint()
373
+ newPaint.Format = paint.Format
374
+ newPaint.Paint = paint.Paint
375
+ newPaint.Glyph = paint.Glyph
376
+ del paint.Paint
377
+ del paint.Glyph
378
+
379
+ _setup_scale_paint(paint, 1 / visitor.scaleFactor)
380
+ paint.Paint = newPaint
381
+
382
+ visitor.visit(newPaint.Paint)
383
+
384
+ return False
385
+
386
+
387
+ def scale_upem(font, new_upem):
388
+ """Change the units-per-EM of font to the new value."""
389
+ upem = font["head"].unitsPerEm
390
+ visitor = ScalerVisitor(new_upem / upem)
391
+ visitor.visit(font)
392
+
393
+
394
+ def main(args=None):
395
+ """Change the units-per-EM of fonts"""
396
+
397
+ if args is None:
398
+ import sys
399
+
400
+ args = sys.argv[1:]
401
+
402
+ from fontTools.ttLib import TTFont
403
+ from fontTools.misc.cliTools import makeOutputFileName
404
+ import argparse
405
+
406
+ parser = argparse.ArgumentParser(
407
+ "fonttools ttLib.scaleUpem", description="Change the units-per-EM of fonts"
408
+ )
409
+ parser.add_argument("font", metavar="font", help="Font file.")
410
+ parser.add_argument(
411
+ "new_upem", metavar="new-upem", help="New units-per-EM integer value."
412
+ )
413
+ parser.add_argument(
414
+ "--output-file", metavar="path", default=None, help="Output file."
415
+ )
416
+
417
+ options = parser.parse_args(args)
418
+
419
+ font = TTFont(options.font)
420
+ new_upem = int(options.new_upem)
421
+ output_file = (
422
+ options.output_file
423
+ if options.output_file is not None
424
+ else makeOutputFileName(options.font, overWrite=True, suffix="-scaled")
425
+ )
426
+
427
+ scale_upem(font, new_upem)
428
+
429
+ print("Writing %s" % output_file)
430
+ font.save(output_file)
431
+
432
+
433
+ if __name__ == "__main__":
434
+ import sys
435
+
436
+ sys.exit(main())