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,99 @@
1
+ from fontTools.misc import sstruct
2
+ from fontTools.misc.textTools import bytechr, byteord, tobytes, tostr, safeEval
3
+ from . import DefaultTable
4
+
5
+ SINGFormat = """
6
+ > # big endian
7
+ tableVersionMajor: H
8
+ tableVersionMinor: H
9
+ glyphletVersion: H
10
+ permissions: h
11
+ mainGID: H
12
+ unitsPerEm: H
13
+ vertAdvance: h
14
+ vertOrigin: h
15
+ uniqueName: 28s
16
+ METAMD5: 16s
17
+ nameLength: 1s
18
+ """
19
+ # baseGlyphName is a byte string which follows the record above.
20
+
21
+
22
+ class table_S_I_N_G_(DefaultTable.DefaultTable):
23
+ """Glyphlets SING table
24
+
25
+ The ``SING`` table is used by Adobe's SING Glyphlets.
26
+
27
+ See also https://web.archive.org/web/20080627183635/http://www.adobe.com/devnet/opentype/gdk/topic.html
28
+ """
29
+
30
+ dependencies = []
31
+
32
+ def decompile(self, data, ttFont):
33
+ dummy, rest = sstruct.unpack2(SINGFormat, data, self)
34
+ self.uniqueName = self.decompileUniqueName(self.uniqueName)
35
+ self.nameLength = byteord(self.nameLength)
36
+ assert len(rest) == self.nameLength
37
+ self.baseGlyphName = tostr(rest)
38
+
39
+ rawMETAMD5 = self.METAMD5
40
+ self.METAMD5 = "[" + hex(byteord(self.METAMD5[0]))
41
+ for char in rawMETAMD5[1:]:
42
+ self.METAMD5 = self.METAMD5 + ", " + hex(byteord(char))
43
+ self.METAMD5 = self.METAMD5 + "]"
44
+
45
+ def decompileUniqueName(self, data):
46
+ name = ""
47
+ for char in data:
48
+ val = byteord(char)
49
+ if val == 0:
50
+ break
51
+ if (val > 31) or (val < 128):
52
+ name += chr(val)
53
+ else:
54
+ octString = oct(val)
55
+ if len(octString) > 3:
56
+ octString = octString[1:] # chop off that leading zero.
57
+ elif len(octString) < 3:
58
+ octString.zfill(3)
59
+ name += "\\" + octString
60
+ return name
61
+
62
+ def compile(self, ttFont):
63
+ d = self.__dict__.copy()
64
+ d["nameLength"] = bytechr(len(self.baseGlyphName))
65
+ d["uniqueName"] = self.compilecompileUniqueName(self.uniqueName, 28)
66
+ METAMD5List = eval(self.METAMD5)
67
+ d["METAMD5"] = b""
68
+ for val in METAMD5List:
69
+ d["METAMD5"] += bytechr(val)
70
+ assert len(d["METAMD5"]) == 16, "Failed to pack 16 byte MD5 hash in SING table"
71
+ data = sstruct.pack(SINGFormat, d)
72
+ data = data + tobytes(self.baseGlyphName)
73
+ return data
74
+
75
+ def compilecompileUniqueName(self, name, length):
76
+ nameLen = len(name)
77
+ if length <= nameLen:
78
+ name = name[: length - 1] + "\000"
79
+ else:
80
+ name += (nameLen - length) * "\000"
81
+ return name
82
+
83
+ def toXML(self, writer, ttFont):
84
+ writer.comment("Most of this table will be recalculated by the compiler")
85
+ writer.newline()
86
+ formatstring, names, fixes = sstruct.getformat(SINGFormat)
87
+ for name in names:
88
+ value = getattr(self, name)
89
+ writer.simpletag(name, value=value)
90
+ writer.newline()
91
+ writer.simpletag("baseGlyphName", value=self.baseGlyphName)
92
+ writer.newline()
93
+
94
+ def fromXML(self, name, attrs, content, ttFont):
95
+ value = attrs["value"]
96
+ if name in ["uniqueName", "METAMD5", "baseGlyphName"]:
97
+ setattr(self, name, value)
98
+ else:
99
+ setattr(self, name, safeEval(value))
@@ -0,0 +1,15 @@
1
+ from .otBase import BaseTTXConverter
2
+
3
+
4
+ class table_S_T_A_T_(BaseTTXConverter):
5
+ """Style Attributes table
6
+
7
+ The ``STAT`` table records stylistic or typeface-design attributes that
8
+ differentiate the individual fonts within a font family from one another.
9
+ Those attributes can be used to assist users when navigating the style
10
+ variations of a variable font or a family of static fonts.
11
+
12
+ See also https://learn.microsoft.com/en-us/typography/opentype/spec/stat
13
+ """
14
+
15
+ pass
@@ -0,0 +1,223 @@
1
+ """Compiles/decompiles SVG table.
2
+
3
+ https://docs.microsoft.com/en-us/typography/opentype/spec/svg
4
+
5
+ The XML format is:
6
+
7
+ .. code-block:: xml
8
+
9
+ <SVG>
10
+ <svgDoc endGlyphID="1" startGlyphID="1">
11
+ <![CDATA[ <complete SVG doc> ]]
12
+ </svgDoc>
13
+ ...
14
+ <svgDoc endGlyphID="n" startGlyphID="m">
15
+ <![CDATA[ <complete SVG doc> ]]
16
+ </svgDoc>
17
+ </SVG>
18
+ """
19
+
20
+ from fontTools.misc.textTools import bytesjoin, safeEval, strjoin, tobytes, tostr
21
+ from fontTools.misc import sstruct
22
+ from . import DefaultTable
23
+ from collections.abc import Sequence
24
+ from dataclasses import dataclass, astuple
25
+ from io import BytesIO
26
+ import struct
27
+ import logging
28
+
29
+
30
+ log = logging.getLogger(__name__)
31
+
32
+
33
+ SVG_format_0 = """
34
+ > # big endian
35
+ version: H
36
+ offsetToSVGDocIndex: L
37
+ reserved: L
38
+ """
39
+
40
+ SVG_format_0Size = sstruct.calcsize(SVG_format_0)
41
+
42
+ doc_index_entry_format_0 = """
43
+ > # big endian
44
+ startGlyphID: H
45
+ endGlyphID: H
46
+ svgDocOffset: L
47
+ svgDocLength: L
48
+ """
49
+
50
+ doc_index_entry_format_0Size = sstruct.calcsize(doc_index_entry_format_0)
51
+
52
+
53
+ class table_S_V_G_(DefaultTable.DefaultTable):
54
+ """Scalable Vector Graphics table
55
+
56
+ The ``SVG`` table contains representations for glyphs in the SVG
57
+ image format.
58
+
59
+ See also https://learn.microsoft.com/en-us/typography/opentype/spec/stat
60
+ """
61
+
62
+ def decompile(self, data, ttFont):
63
+ self.docList = []
64
+ # Version 0 is the standardized version of the table; and current.
65
+ # https://www.microsoft.com/typography/otspec/svg.htm
66
+ sstruct.unpack(SVG_format_0, data[:SVG_format_0Size], self)
67
+ if self.version != 0:
68
+ log.warning(
69
+ "Unknown SVG table version '%s'. Decompiling as version 0.",
70
+ self.version,
71
+ )
72
+ # read in SVG Documents Index
73
+ # data starts with the first entry of the entry list.
74
+ pos = subTableStart = self.offsetToSVGDocIndex
75
+ self.numEntries = struct.unpack(">H", data[pos : pos + 2])[0]
76
+ pos += 2
77
+ if self.numEntries > 0:
78
+ data2 = data[pos:]
79
+ entries = []
80
+ for i in range(self.numEntries):
81
+ record_data = data2[
82
+ i
83
+ * doc_index_entry_format_0Size : (i + 1)
84
+ * doc_index_entry_format_0Size
85
+ ]
86
+ docIndexEntry = sstruct.unpack(
87
+ doc_index_entry_format_0, record_data, DocumentIndexEntry()
88
+ )
89
+ entries.append(docIndexEntry)
90
+
91
+ for entry in entries:
92
+ start = entry.svgDocOffset + subTableStart
93
+ end = start + entry.svgDocLength
94
+ doc = data[start:end]
95
+ compressed = False
96
+ if doc.startswith(b"\x1f\x8b"):
97
+ import gzip
98
+
99
+ bytesIO = BytesIO(doc)
100
+ with gzip.GzipFile(None, "r", fileobj=bytesIO) as gunzipper:
101
+ doc = gunzipper.read()
102
+ del bytesIO
103
+ compressed = True
104
+ doc = tostr(doc, "utf_8")
105
+ self.docList.append(
106
+ SVGDocument(doc, entry.startGlyphID, entry.endGlyphID, compressed)
107
+ )
108
+
109
+ def compile(self, ttFont):
110
+ version = 0
111
+ offsetToSVGDocIndex = (
112
+ SVG_format_0Size # I start the SVGDocIndex right after the header.
113
+ )
114
+ # get SGVDoc info.
115
+ docList = []
116
+ entryList = []
117
+ numEntries = len(self.docList)
118
+ datum = struct.pack(">H", numEntries)
119
+ entryList.append(datum)
120
+ curOffset = len(datum) + doc_index_entry_format_0Size * numEntries
121
+ seenDocs = {}
122
+ allCompressed = getattr(self, "compressed", False)
123
+ for i, doc in enumerate(self.docList):
124
+ if isinstance(doc, (list, tuple)):
125
+ doc = SVGDocument(*doc)
126
+ self.docList[i] = doc
127
+ docBytes = tobytes(doc.data, encoding="utf_8")
128
+ if (allCompressed or doc.compressed) and not docBytes.startswith(
129
+ b"\x1f\x8b"
130
+ ):
131
+ import gzip
132
+
133
+ bytesIO = BytesIO()
134
+ # mtime=0 strips the useless timestamp and makes gzip output reproducible;
135
+ # equivalent to `gzip -n`
136
+ with gzip.GzipFile(None, "w", fileobj=bytesIO, mtime=0) as gzipper:
137
+ gzipper.write(docBytes)
138
+ gzipped = bytesIO.getvalue()
139
+ if len(gzipped) < len(docBytes):
140
+ docBytes = gzipped
141
+ del gzipped, bytesIO
142
+ docLength = len(docBytes)
143
+ if docBytes in seenDocs:
144
+ docOffset = seenDocs[docBytes]
145
+ else:
146
+ docOffset = curOffset
147
+ curOffset += docLength
148
+ seenDocs[docBytes] = docOffset
149
+ docList.append(docBytes)
150
+ entry = struct.pack(
151
+ ">HHLL", doc.startGlyphID, doc.endGlyphID, docOffset, docLength
152
+ )
153
+ entryList.append(entry)
154
+ entryList.extend(docList)
155
+ svgDocData = bytesjoin(entryList)
156
+
157
+ reserved = 0
158
+ header = struct.pack(">HLL", version, offsetToSVGDocIndex, reserved)
159
+ data = [header, svgDocData]
160
+ data = bytesjoin(data)
161
+ return data
162
+
163
+ def toXML(self, writer, ttFont):
164
+ for i, doc in enumerate(self.docList):
165
+ if isinstance(doc, (list, tuple)):
166
+ doc = SVGDocument(*doc)
167
+ self.docList[i] = doc
168
+ attrs = {"startGlyphID": doc.startGlyphID, "endGlyphID": doc.endGlyphID}
169
+ if doc.compressed:
170
+ attrs["compressed"] = 1
171
+ writer.begintag("svgDoc", **attrs)
172
+ writer.newline()
173
+ writer.writecdata(doc.data)
174
+ writer.newline()
175
+ writer.endtag("svgDoc")
176
+ writer.newline()
177
+
178
+ def fromXML(self, name, attrs, content, ttFont):
179
+ if name == "svgDoc":
180
+ if not hasattr(self, "docList"):
181
+ self.docList = []
182
+ doc = strjoin(content)
183
+ doc = doc.strip()
184
+ startGID = int(attrs["startGlyphID"])
185
+ endGID = int(attrs["endGlyphID"])
186
+ compressed = bool(safeEval(attrs.get("compressed", "0")))
187
+ self.docList.append(SVGDocument(doc, startGID, endGID, compressed))
188
+ else:
189
+ log.warning("Unknown %s %s", name, content)
190
+
191
+
192
+ class DocumentIndexEntry(object):
193
+ def __init__(self):
194
+ self.startGlyphID = None # USHORT
195
+ self.endGlyphID = None # USHORT
196
+ self.svgDocOffset = None # ULONG
197
+ self.svgDocLength = None # ULONG
198
+
199
+ def __repr__(self):
200
+ return (
201
+ "startGlyphID: %s, endGlyphID: %s, svgDocOffset: %s, svgDocLength: %s"
202
+ % (self.startGlyphID, self.endGlyphID, self.svgDocOffset, self.svgDocLength)
203
+ )
204
+
205
+
206
+ @dataclass
207
+ class SVGDocument(Sequence):
208
+ data: str
209
+ startGlyphID: int
210
+ endGlyphID: int
211
+ compressed: bool = False
212
+
213
+ # Previously, the SVG table's docList attribute contained a lists of 3 items:
214
+ # [doc, startGlyphID, endGlyphID]; later, we added a `compressed` attribute.
215
+ # For backward compatibility with code that depends of them being sequences of
216
+ # fixed length=3, we subclass the Sequence abstract base class and pretend only
217
+ # the first three items are present. 'compressed' is only accessible via named
218
+ # attribute lookup like regular dataclasses: i.e. `doc.compressed`, not `doc[3]`
219
+ def __getitem__(self, index):
220
+ return astuple(self)[:3][index]
221
+
222
+ def __len__(self):
223
+ return 3