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,147 @@
1
+ from fontTools.misc import sstruct
2
+ from fontTools.misc.textTools import safeEval
3
+ from fontTools.misc.fixedTools import (
4
+ ensureVersionIsLong as fi2ve,
5
+ versionToFixed as ve2fi,
6
+ )
7
+ from . import DefaultTable
8
+ import math
9
+
10
+
11
+ hheaFormat = """
12
+ > # big endian
13
+ tableVersion: L
14
+ ascent: h
15
+ descent: h
16
+ lineGap: h
17
+ advanceWidthMax: H
18
+ minLeftSideBearing: h
19
+ minRightSideBearing: h
20
+ xMaxExtent: h
21
+ caretSlopeRise: h
22
+ caretSlopeRun: h
23
+ caretOffset: h
24
+ reserved0: h
25
+ reserved1: h
26
+ reserved2: h
27
+ reserved3: h
28
+ metricDataFormat: h
29
+ numberOfHMetrics: H
30
+ """
31
+
32
+
33
+ class table__h_h_e_a(DefaultTable.DefaultTable):
34
+ """Horizontal Header table
35
+
36
+ The ``hhea`` table contains information needed during horizontal
37
+ text layout.
38
+
39
+ .. note::
40
+ This converter class is kept in sync with the :class:`._v_h_e_a.table__v_h_e_a`
41
+ table constructor.
42
+
43
+ See also https://learn.microsoft.com/en-us/typography/opentype/spec/hhea
44
+ """
45
+
46
+ # Note: Keep in sync with table__v_h_e_a
47
+
48
+ dependencies = ["hmtx", "glyf", "CFF ", "CFF2"]
49
+
50
+ # OpenType spec renamed these, add aliases for compatibility
51
+ @property
52
+ def ascender(self):
53
+ return self.ascent
54
+
55
+ @ascender.setter
56
+ def ascender(self, value):
57
+ self.ascent = value
58
+
59
+ @property
60
+ def descender(self):
61
+ return self.descent
62
+
63
+ @descender.setter
64
+ def descender(self, value):
65
+ self.descent = value
66
+
67
+ def decompile(self, data, ttFont):
68
+ sstruct.unpack(hheaFormat, data, self)
69
+
70
+ def compile(self, ttFont):
71
+ if ttFont.recalcBBoxes and (
72
+ ttFont.isLoaded("glyf")
73
+ or ttFont.isLoaded("CFF ")
74
+ or ttFont.isLoaded("CFF2")
75
+ ):
76
+ self.recalc(ttFont)
77
+ self.tableVersion = fi2ve(self.tableVersion)
78
+ return sstruct.pack(hheaFormat, self)
79
+
80
+ def recalc(self, ttFont):
81
+ if "hmtx" not in ttFont:
82
+ return
83
+
84
+ hmtxTable = ttFont["hmtx"]
85
+ self.advanceWidthMax = max(adv for adv, _ in hmtxTable.metrics.values())
86
+
87
+ boundsWidthDict = {}
88
+ if "glyf" in ttFont:
89
+ glyfTable = ttFont["glyf"]
90
+ for name in ttFont.getGlyphOrder():
91
+ g = glyfTable[name]
92
+ if g.numberOfContours == 0:
93
+ continue
94
+ if g.numberOfContours < 0 and not hasattr(g, "xMax"):
95
+ # Composite glyph without extents set.
96
+ # Calculate those.
97
+ g.recalcBounds(glyfTable)
98
+ boundsWidthDict[name] = g.xMax - g.xMin
99
+ elif "CFF " in ttFont or "CFF2" in ttFont:
100
+ if "CFF " in ttFont:
101
+ topDict = ttFont["CFF "].cff.topDictIndex[0]
102
+ else:
103
+ topDict = ttFont["CFF2"].cff.topDictIndex[0]
104
+ charStrings = topDict.CharStrings
105
+ for name in ttFont.getGlyphOrder():
106
+ cs = charStrings[name]
107
+ bounds = cs.calcBounds(charStrings)
108
+ if bounds is not None:
109
+ boundsWidthDict[name] = int(
110
+ math.ceil(bounds[2]) - math.floor(bounds[0])
111
+ )
112
+
113
+ if boundsWidthDict:
114
+ minLeftSideBearing = float("inf")
115
+ minRightSideBearing = float("inf")
116
+ xMaxExtent = -float("inf")
117
+ for name, boundsWidth in boundsWidthDict.items():
118
+ advanceWidth, lsb = hmtxTable[name]
119
+ rsb = advanceWidth - lsb - boundsWidth
120
+ extent = lsb + boundsWidth
121
+ minLeftSideBearing = min(minLeftSideBearing, lsb)
122
+ minRightSideBearing = min(minRightSideBearing, rsb)
123
+ xMaxExtent = max(xMaxExtent, extent)
124
+ self.minLeftSideBearing = minLeftSideBearing
125
+ self.minRightSideBearing = minRightSideBearing
126
+ self.xMaxExtent = xMaxExtent
127
+
128
+ else: # No glyph has outlines.
129
+ self.minLeftSideBearing = 0
130
+ self.minRightSideBearing = 0
131
+ self.xMaxExtent = 0
132
+
133
+ def toXML(self, writer, ttFont):
134
+ formatstring, names, fixes = sstruct.getformat(hheaFormat)
135
+ for name in names:
136
+ value = getattr(self, name)
137
+ if name == "tableVersion":
138
+ value = fi2ve(value)
139
+ value = "0x%08x" % value
140
+ writer.simpletag(name, value=value)
141
+ writer.newline()
142
+
143
+ def fromXML(self, name, attrs, content, ttFont):
144
+ if name == "tableVersion":
145
+ setattr(self, name, ve2fi(attrs["value"]))
146
+ return
147
+ setattr(self, name, safeEval(attrs["value"]))
@@ -0,0 +1,164 @@
1
+ from fontTools.misc.roundTools import otRound
2
+ from fontTools import ttLib
3
+ from fontTools.misc.textTools import safeEval
4
+ from . import DefaultTable
5
+ import sys
6
+ import struct
7
+ import array
8
+ import logging
9
+
10
+
11
+ log = logging.getLogger(__name__)
12
+
13
+
14
+ class table__h_m_t_x(DefaultTable.DefaultTable):
15
+ """Horizontal Metrics table
16
+
17
+ The ``hmtx`` table contains per-glyph metrics for the glyphs in a
18
+ ``glyf``, ``CFF ``, or ``CFF2`` table, as needed for horizontal text
19
+ layout.
20
+
21
+ See also https://learn.microsoft.com/en-us/typography/opentype/spec/hmtx
22
+ """
23
+
24
+ headerTag = "hhea"
25
+ advanceName = "width"
26
+ sideBearingName = "lsb"
27
+ numberOfMetricsName = "numberOfHMetrics"
28
+ longMetricFormat = "Hh"
29
+
30
+ def decompile(self, data, ttFont):
31
+ numGlyphs = ttFont["maxp"].numGlyphs
32
+ headerTable = ttFont.get(self.headerTag)
33
+ if headerTable is not None:
34
+ numberOfMetrics = int(getattr(headerTable, self.numberOfMetricsName))
35
+ else:
36
+ numberOfMetrics = numGlyphs
37
+ if numberOfMetrics > numGlyphs:
38
+ log.warning(
39
+ "The %s.%s exceeds the maxp.numGlyphs"
40
+ % (self.headerTag, self.numberOfMetricsName)
41
+ )
42
+ numberOfMetrics = numGlyphs
43
+ numberOfSideBearings = numGlyphs - numberOfMetrics
44
+ tableSize = 4 * numberOfMetrics + 2 * numberOfSideBearings
45
+ if len(data) < tableSize:
46
+ raise ttLib.TTLibError(
47
+ f"not enough '{self.tableTag}' table data: "
48
+ f"expected {tableSize} bytes, got {len(data)}"
49
+ )
50
+ # Note: advanceWidth is unsigned, but some font editors might
51
+ # read/write as signed. We can't be sure whether it was a mistake
52
+ # or not, so we read as unsigned but also issue a warning...
53
+ metricsFmt = ">" + self.longMetricFormat * numberOfMetrics
54
+ metrics = struct.unpack(metricsFmt, data[: 4 * numberOfMetrics])
55
+ data = data[4 * numberOfMetrics :]
56
+ sideBearings = array.array("h", data[: 2 * numberOfSideBearings])
57
+ data = data[2 * numberOfSideBearings :]
58
+
59
+ if sys.byteorder != "big":
60
+ sideBearings.byteswap()
61
+ if data:
62
+ log.warning("too much '%s' table data" % self.tableTag)
63
+ self.metrics = {}
64
+ glyphOrder = ttFont.getGlyphOrder()
65
+ for i in range(numberOfMetrics):
66
+ glyphName = glyphOrder[i]
67
+ advanceWidth, lsb = metrics[i * 2 : i * 2 + 2]
68
+ if advanceWidth > 32767:
69
+ log.warning(
70
+ "Glyph %r has a huge advance %s (%d); is it intentional or "
71
+ "an (invalid) negative value?",
72
+ glyphName,
73
+ self.advanceName,
74
+ advanceWidth,
75
+ )
76
+ self.metrics[glyphName] = (advanceWidth, lsb)
77
+ lastAdvance = metrics[-2]
78
+ for i in range(numberOfSideBearings):
79
+ glyphName = glyphOrder[i + numberOfMetrics]
80
+ self.metrics[glyphName] = (lastAdvance, sideBearings[i])
81
+
82
+ def compile(self, ttFont):
83
+ metrics = []
84
+ hasNegativeAdvances = False
85
+ for glyphName in ttFont.getGlyphOrder():
86
+ advanceWidth, sideBearing = self.metrics[glyphName]
87
+ if advanceWidth < 0:
88
+ log.error(
89
+ "Glyph %r has negative advance %s" % (glyphName, self.advanceName)
90
+ )
91
+ hasNegativeAdvances = True
92
+ metrics.append([advanceWidth, sideBearing])
93
+
94
+ headerTable = ttFont.get(self.headerTag)
95
+ if headerTable is not None:
96
+ lastAdvance = metrics[-1][0]
97
+ lastIndex = len(metrics)
98
+ while metrics[lastIndex - 2][0] == lastAdvance:
99
+ lastIndex -= 1
100
+ if lastIndex <= 1:
101
+ # all advances are equal
102
+ lastIndex = 1
103
+ break
104
+ additionalMetrics = metrics[lastIndex:]
105
+ additionalMetrics = [otRound(sb) for _, sb in additionalMetrics]
106
+ metrics = metrics[:lastIndex]
107
+ numberOfMetrics = len(metrics)
108
+ setattr(headerTable, self.numberOfMetricsName, numberOfMetrics)
109
+ else:
110
+ # no hhea/vhea, can't store numberOfMetrics; assume == numGlyphs
111
+ numberOfMetrics = ttFont["maxp"].numGlyphs
112
+ additionalMetrics = []
113
+
114
+ allMetrics = []
115
+ for advance, sb in metrics:
116
+ allMetrics.extend([otRound(advance), otRound(sb)])
117
+ metricsFmt = ">" + self.longMetricFormat * numberOfMetrics
118
+ try:
119
+ data = struct.pack(metricsFmt, *allMetrics)
120
+ except struct.error as e:
121
+ if "out of range" in str(e) and hasNegativeAdvances:
122
+ raise ttLib.TTLibError(
123
+ "'%s' table can't contain negative advance %ss"
124
+ % (self.tableTag, self.advanceName)
125
+ )
126
+ else:
127
+ raise
128
+ additionalMetrics = array.array("h", additionalMetrics)
129
+ if sys.byteorder != "big":
130
+ additionalMetrics.byteswap()
131
+ data = data + additionalMetrics.tobytes()
132
+ return data
133
+
134
+ def toXML(self, writer, ttFont):
135
+ names = sorted(self.metrics.keys())
136
+ for glyphName in names:
137
+ advance, sb = self.metrics[glyphName]
138
+ writer.simpletag(
139
+ "mtx",
140
+ [
141
+ ("name", glyphName),
142
+ (self.advanceName, advance),
143
+ (self.sideBearingName, sb),
144
+ ],
145
+ )
146
+ writer.newline()
147
+
148
+ def fromXML(self, name, attrs, content, ttFont):
149
+ if not hasattr(self, "metrics"):
150
+ self.metrics = {}
151
+ if name == "mtx":
152
+ self.metrics[attrs["name"]] = (
153
+ safeEval(attrs[self.advanceName]),
154
+ safeEval(attrs[self.sideBearingName]),
155
+ )
156
+
157
+ def __delitem__(self, glyphName):
158
+ del self.metrics[glyphName]
159
+
160
+ def __getitem__(self, glyphName):
161
+ return self.metrics[glyphName]
162
+
163
+ def __setitem__(self, glyphName, advance_sb_pair):
164
+ self.metrics[glyphName] = tuple(advance_sb_pair)
@@ -0,0 +1,289 @@
1
+ from fontTools.ttLib import getSearchRange
2
+ from fontTools.misc.textTools import safeEval, readHex
3
+ from fontTools.misc.fixedTools import fixedToFloat as fi2fl, floatToFixed as fl2fi
4
+ from . import DefaultTable
5
+ import struct
6
+ import sys
7
+ import array
8
+ import logging
9
+
10
+
11
+ log = logging.getLogger(__name__)
12
+
13
+
14
+ class table__k_e_r_n(DefaultTable.DefaultTable):
15
+ """Kerning table
16
+
17
+ The ``kern`` table contains values that contextually adjust the inter-glyph
18
+ spacing for the glyphs in a ``glyf`` table.
19
+
20
+ Note that similar contextual spacing adjustments can also be stored
21
+ in the "kern" feature of a ``GPOS`` table.
22
+
23
+ See also https://learn.microsoft.com/en-us/typography/opentype/spec/kern
24
+ """
25
+
26
+ def getkern(self, format):
27
+ for subtable in self.kernTables:
28
+ if subtable.format == format:
29
+ return subtable
30
+ return None # not found
31
+
32
+ def decompile(self, data, ttFont):
33
+ version, nTables = struct.unpack(">HH", data[:4])
34
+ apple = False
35
+ if (len(data) >= 8) and (version == 1):
36
+ # AAT Apple's "new" format. Hm.
37
+ version, nTables = struct.unpack(">LL", data[:8])
38
+ self.version = fi2fl(version, 16)
39
+ data = data[8:]
40
+ apple = True
41
+ else:
42
+ self.version = version
43
+ data = data[4:]
44
+ self.kernTables = []
45
+ for i in range(nTables):
46
+ if self.version == 1.0:
47
+ # Apple
48
+ length, coverage, subtableFormat = struct.unpack(">LBB", data[:6])
49
+ else:
50
+ # in OpenType spec the "version" field refers to the common
51
+ # subtable header; the actual subtable format is stored in
52
+ # the 8-15 mask bits of "coverage" field.
53
+ # This "version" is always 0 so we ignore it here
54
+ _, length, subtableFormat, coverage = struct.unpack(">HHBB", data[:6])
55
+ if nTables == 1 and subtableFormat == 0:
56
+ # The "length" value is ignored since some fonts
57
+ # (like OpenSans and Calibri) have a subtable larger than
58
+ # its value.
59
+ (nPairs,) = struct.unpack(">H", data[6:8])
60
+ calculated_length = (nPairs * 6) + 14
61
+ if length != calculated_length:
62
+ log.warning(
63
+ "'kern' subtable longer than defined: "
64
+ "%d bytes instead of %d bytes" % (calculated_length, length)
65
+ )
66
+ length = calculated_length
67
+ if subtableFormat not in kern_classes:
68
+ subtable = KernTable_format_unkown(subtableFormat)
69
+ else:
70
+ subtable = kern_classes[subtableFormat](apple)
71
+ subtable.decompile(data[:length], ttFont)
72
+ self.kernTables.append(subtable)
73
+ data = data[length:]
74
+
75
+ def compile(self, ttFont):
76
+ if hasattr(self, "kernTables"):
77
+ nTables = len(self.kernTables)
78
+ else:
79
+ nTables = 0
80
+ if self.version == 1.0:
81
+ # AAT Apple's "new" format.
82
+ data = struct.pack(">LL", fl2fi(self.version, 16), nTables)
83
+ else:
84
+ data = struct.pack(">HH", self.version, nTables)
85
+ if hasattr(self, "kernTables"):
86
+ for subtable in self.kernTables:
87
+ data = data + subtable.compile(ttFont)
88
+ return data
89
+
90
+ def toXML(self, writer, ttFont):
91
+ writer.simpletag("version", value=self.version)
92
+ writer.newline()
93
+ for subtable in self.kernTables:
94
+ subtable.toXML(writer, ttFont)
95
+
96
+ def fromXML(self, name, attrs, content, ttFont):
97
+ if name == "version":
98
+ self.version = safeEval(attrs["value"])
99
+ return
100
+ if name != "kernsubtable":
101
+ return
102
+ if not hasattr(self, "kernTables"):
103
+ self.kernTables = []
104
+ format = safeEval(attrs["format"])
105
+ if format not in kern_classes:
106
+ subtable = KernTable_format_unkown(format)
107
+ else:
108
+ apple = self.version == 1.0
109
+ subtable = kern_classes[format](apple)
110
+ self.kernTables.append(subtable)
111
+ subtable.fromXML(name, attrs, content, ttFont)
112
+
113
+
114
+ class KernTable_format_0(object):
115
+ # 'version' is kept for backward compatibility
116
+ version = format = 0
117
+
118
+ def __init__(self, apple=False):
119
+ self.apple = apple
120
+
121
+ def decompile(self, data, ttFont):
122
+ if not self.apple:
123
+ version, length, subtableFormat, coverage = struct.unpack(">HHBB", data[:6])
124
+ if version != 0:
125
+ from fontTools.ttLib import TTLibError
126
+
127
+ raise TTLibError("unsupported kern subtable version: %d" % version)
128
+ tupleIndex = None
129
+ # Should we also assert length == len(data)?
130
+ data = data[6:]
131
+ else:
132
+ length, coverage, subtableFormat, tupleIndex = struct.unpack(
133
+ ">LBBH", data[:8]
134
+ )
135
+ data = data[8:]
136
+ assert self.format == subtableFormat, "unsupported format"
137
+ self.coverage = coverage
138
+ self.tupleIndex = tupleIndex
139
+
140
+ self.kernTable = kernTable = {}
141
+
142
+ nPairs, searchRange, entrySelector, rangeShift = struct.unpack(
143
+ ">HHHH", data[:8]
144
+ )
145
+ data = data[8:]
146
+
147
+ datas = array.array("H", data[: 6 * nPairs])
148
+ if sys.byteorder != "big":
149
+ datas.byteswap()
150
+ it = iter(datas)
151
+ glyphOrder = ttFont.getGlyphOrder()
152
+ for k in range(nPairs):
153
+ left, right, value = next(it), next(it), next(it)
154
+ if value >= 32768:
155
+ value -= 65536
156
+ try:
157
+ kernTable[(glyphOrder[left], glyphOrder[right])] = value
158
+ except IndexError:
159
+ # Slower, but will not throw an IndexError on an invalid
160
+ # glyph id.
161
+ kernTable[(ttFont.getGlyphName(left), ttFont.getGlyphName(right))] = (
162
+ value
163
+ )
164
+ if len(data) > 6 * nPairs + 4: # Ignore up to 4 bytes excess
165
+ log.warning(
166
+ "excess data in 'kern' subtable: %d bytes", len(data) - 6 * nPairs
167
+ )
168
+
169
+ def compile(self, ttFont):
170
+ nPairs = min(len(self.kernTable), 0xFFFF)
171
+ searchRange, entrySelector, rangeShift = getSearchRange(nPairs, 6)
172
+ searchRange &= 0xFFFF
173
+ entrySelector = min(entrySelector, 0xFFFF)
174
+ rangeShift = min(rangeShift, 0xFFFF)
175
+ data = struct.pack(">HHHH", nPairs, searchRange, entrySelector, rangeShift)
176
+
177
+ # yeehee! (I mean, turn names into indices)
178
+ try:
179
+ reverseOrder = ttFont.getReverseGlyphMap()
180
+ kernTable = sorted(
181
+ (reverseOrder[left], reverseOrder[right], value)
182
+ for ((left, right), value) in self.kernTable.items()
183
+ )
184
+ except KeyError:
185
+ # Slower, but will not throw KeyError on invalid glyph id.
186
+ getGlyphID = ttFont.getGlyphID
187
+ kernTable = sorted(
188
+ (getGlyphID(left), getGlyphID(right), value)
189
+ for ((left, right), value) in self.kernTable.items()
190
+ )
191
+
192
+ for left, right, value in kernTable:
193
+ data = data + struct.pack(">HHh", left, right, value)
194
+
195
+ if not self.apple:
196
+ version = 0
197
+ length = len(data) + 6
198
+ if length >= 0x10000:
199
+ log.warning(
200
+ '"kern" subtable overflow, '
201
+ "truncating length value while preserving pairs."
202
+ )
203
+ length &= 0xFFFF
204
+ header = struct.pack(">HHBB", version, length, self.format, self.coverage)
205
+ else:
206
+ if self.tupleIndex is None:
207
+ # sensible default when compiling a TTX from an old fonttools
208
+ # or when inserting a Windows-style format 0 subtable into an
209
+ # Apple version=1.0 kern table
210
+ log.warning("'tupleIndex' is None; default to 0")
211
+ self.tupleIndex = 0
212
+ length = len(data) + 8
213
+ header = struct.pack(
214
+ ">LBBH", length, self.coverage, self.format, self.tupleIndex
215
+ )
216
+ return header + data
217
+
218
+ def toXML(self, writer, ttFont):
219
+ attrs = dict(coverage=self.coverage, format=self.format)
220
+ if self.apple:
221
+ if self.tupleIndex is None:
222
+ log.warning("'tupleIndex' is None; default to 0")
223
+ attrs["tupleIndex"] = 0
224
+ else:
225
+ attrs["tupleIndex"] = self.tupleIndex
226
+ writer.begintag("kernsubtable", **attrs)
227
+ writer.newline()
228
+ items = sorted(self.kernTable.items())
229
+ for (left, right), value in items:
230
+ writer.simpletag("pair", [("l", left), ("r", right), ("v", value)])
231
+ writer.newline()
232
+ writer.endtag("kernsubtable")
233
+ writer.newline()
234
+
235
+ def fromXML(self, name, attrs, content, ttFont):
236
+ self.coverage = safeEval(attrs["coverage"])
237
+ subtableFormat = safeEval(attrs["format"])
238
+ if self.apple:
239
+ if "tupleIndex" in attrs:
240
+ self.tupleIndex = safeEval(attrs["tupleIndex"])
241
+ else:
242
+ # previous fontTools versions didn't export tupleIndex
243
+ log.warning("Apple kern subtable is missing 'tupleIndex' attribute")
244
+ self.tupleIndex = None
245
+ else:
246
+ self.tupleIndex = None
247
+ assert subtableFormat == self.format, "unsupported format"
248
+ if not hasattr(self, "kernTable"):
249
+ self.kernTable = {}
250
+ for element in content:
251
+ if not isinstance(element, tuple):
252
+ continue
253
+ name, attrs, content = element
254
+ self.kernTable[(attrs["l"], attrs["r"])] = safeEval(attrs["v"])
255
+
256
+ def __getitem__(self, pair):
257
+ return self.kernTable[pair]
258
+
259
+ def __setitem__(self, pair, value):
260
+ self.kernTable[pair] = value
261
+
262
+ def __delitem__(self, pair):
263
+ del self.kernTable[pair]
264
+
265
+
266
+ class KernTable_format_unkown(object):
267
+ def __init__(self, format):
268
+ self.format = format
269
+
270
+ def decompile(self, data, ttFont):
271
+ self.data = data
272
+
273
+ def compile(self, ttFont):
274
+ return self.data
275
+
276
+ def toXML(self, writer, ttFont):
277
+ writer.begintag("kernsubtable", format=self.format)
278
+ writer.newline()
279
+ writer.comment("unknown 'kern' subtable format")
280
+ writer.newline()
281
+ writer.dumphex(self.data)
282
+ writer.endtag("kernsubtable")
283
+ writer.newline()
284
+
285
+ def fromXML(self, name, attrs, content, ttFont):
286
+ self.decompile(readHex(content), ttFont)
287
+
288
+
289
+ kern_classes = {0: KernTable_format_0}
@@ -0,0 +1,13 @@
1
+ from .otBase import BaseTTXConverter
2
+
3
+
4
+ class table__l_c_a_r(BaseTTXConverter):
5
+ """Ligature Caret table
6
+
7
+ The AAT ``lcar`` table stores division points within ligatures, which applications
8
+ can use to position carets properly between the logical parts of the ligature.
9
+
10
+ See also https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6lcar.html
11
+ """
12
+
13
+ pass
@@ -0,0 +1,70 @@
1
+ from . import DefaultTable
2
+ import sys
3
+ import array
4
+ import logging
5
+
6
+
7
+ log = logging.getLogger(__name__)
8
+
9
+
10
+ class table__l_o_c_a(DefaultTable.DefaultTable):
11
+ """Index to Location table
12
+
13
+ The ``loca`` table stores the offsets in the ``glyf`` table that correspond
14
+ to the descriptions of each glyph. The glyphs are references by Glyph ID.
15
+
16
+ See also https://learn.microsoft.com/en-us/typography/opentype/spec/loca
17
+ """
18
+
19
+ dependencies = ["glyf"]
20
+
21
+ def decompile(self, data, ttFont):
22
+ longFormat = ttFont["head"].indexToLocFormat
23
+ if longFormat:
24
+ format = "I"
25
+ else:
26
+ format = "H"
27
+ locations = array.array(format)
28
+ locations.frombytes(data)
29
+ if sys.byteorder != "big":
30
+ locations.byteswap()
31
+ if not longFormat:
32
+ locations = array.array("I", (2 * l for l in locations))
33
+ if len(locations) < (ttFont["maxp"].numGlyphs + 1):
34
+ log.warning(
35
+ "corrupt 'loca' table, or wrong numGlyphs in 'maxp': %d %d",
36
+ len(locations) - 1,
37
+ ttFont["maxp"].numGlyphs,
38
+ )
39
+ self.locations = locations
40
+
41
+ def compile(self, ttFont):
42
+ try:
43
+ max_location = max(self.locations)
44
+ except AttributeError:
45
+ self.set([])
46
+ max_location = 0
47
+ if max_location < 0x20000 and all(l % 2 == 0 for l in self.locations):
48
+ locations = array.array("H")
49
+ for location in self.locations:
50
+ locations.append(location // 2)
51
+ ttFont["head"].indexToLocFormat = 0
52
+ else:
53
+ locations = array.array("I", self.locations)
54
+ ttFont["head"].indexToLocFormat = 1
55
+ if sys.byteorder != "big":
56
+ locations.byteswap()
57
+ return locations.tobytes()
58
+
59
+ def set(self, locations):
60
+ self.locations = array.array("I", locations)
61
+
62
+ def toXML(self, writer, ttFont):
63
+ writer.comment("The 'loca' table will be calculated by the compiler")
64
+ writer.newline()
65
+
66
+ def __getitem__(self, index):
67
+ return self.locations[index]
68
+
69
+ def __len__(self):
70
+ return len(self.locations)