fonttools 4.55.6__cp311-cp311-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fonttools might be problematic. Click here for more details.

Files changed (329) 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/cffLib/CFF2ToCFF.py +203 -0
  6. fontTools/cffLib/CFFToCFF2.py +305 -0
  7. fontTools/cffLib/__init__.py +3659 -0
  8. fontTools/cffLib/specializer.py +924 -0
  9. fontTools/cffLib/transforms.py +490 -0
  10. fontTools/cffLib/width.py +210 -0
  11. fontTools/colorLib/__init__.py +0 -0
  12. fontTools/colorLib/builder.py +664 -0
  13. fontTools/colorLib/errors.py +2 -0
  14. fontTools/colorLib/geometry.py +143 -0
  15. fontTools/colorLib/table_builder.py +223 -0
  16. fontTools/colorLib/unbuilder.py +81 -0
  17. fontTools/config/__init__.py +75 -0
  18. fontTools/cu2qu/__init__.py +15 -0
  19. fontTools/cu2qu/__main__.py +6 -0
  20. fontTools/cu2qu/benchmark.py +54 -0
  21. fontTools/cu2qu/cli.py +198 -0
  22. fontTools/cu2qu/cu2qu.c +14829 -0
  23. fontTools/cu2qu/cu2qu.cpython-311-x86_64-linux-musl.so +0 -0
  24. fontTools/cu2qu/cu2qu.py +531 -0
  25. fontTools/cu2qu/errors.py +77 -0
  26. fontTools/cu2qu/ufo.py +349 -0
  27. fontTools/designspaceLib/__init__.py +3338 -0
  28. fontTools/designspaceLib/__main__.py +6 -0
  29. fontTools/designspaceLib/split.py +475 -0
  30. fontTools/designspaceLib/statNames.py +253 -0
  31. fontTools/designspaceLib/types.py +147 -0
  32. fontTools/encodings/MacRoman.py +258 -0
  33. fontTools/encodings/StandardEncoding.py +258 -0
  34. fontTools/encodings/__init__.py +1 -0
  35. fontTools/encodings/codecs.py +135 -0
  36. fontTools/feaLib/__init__.py +4 -0
  37. fontTools/feaLib/__main__.py +78 -0
  38. fontTools/feaLib/ast.py +2134 -0
  39. fontTools/feaLib/builder.py +1747 -0
  40. fontTools/feaLib/error.py +22 -0
  41. fontTools/feaLib/lexer.c +17986 -0
  42. fontTools/feaLib/lexer.cpython-311-x86_64-linux-musl.so +0 -0
  43. fontTools/feaLib/lexer.py +287 -0
  44. fontTools/feaLib/location.py +12 -0
  45. fontTools/feaLib/lookupDebugInfo.py +12 -0
  46. fontTools/feaLib/parser.py +2359 -0
  47. fontTools/feaLib/variableScalar.py +113 -0
  48. fontTools/fontBuilder.py +1008 -0
  49. fontTools/help.py +36 -0
  50. fontTools/merge/__init__.py +248 -0
  51. fontTools/merge/__main__.py +6 -0
  52. fontTools/merge/base.py +81 -0
  53. fontTools/merge/cmap.py +141 -0
  54. fontTools/merge/layout.py +526 -0
  55. fontTools/merge/options.py +85 -0
  56. fontTools/merge/tables.py +341 -0
  57. fontTools/merge/unicode.py +78 -0
  58. fontTools/merge/util.py +143 -0
  59. fontTools/misc/__init__.py +1 -0
  60. fontTools/misc/arrayTools.py +424 -0
  61. fontTools/misc/bezierTools.c +41831 -0
  62. fontTools/misc/bezierTools.cpython-311-x86_64-linux-musl.so +0 -0
  63. fontTools/misc/bezierTools.py +1497 -0
  64. fontTools/misc/classifyTools.py +170 -0
  65. fontTools/misc/cliTools.py +53 -0
  66. fontTools/misc/configTools.py +349 -0
  67. fontTools/misc/cython.py +27 -0
  68. fontTools/misc/dictTools.py +83 -0
  69. fontTools/misc/eexec.py +119 -0
  70. fontTools/misc/encodingTools.py +72 -0
  71. fontTools/misc/etree.py +479 -0
  72. fontTools/misc/filenames.py +245 -0
  73. fontTools/misc/fixedTools.py +253 -0
  74. fontTools/misc/intTools.py +25 -0
  75. fontTools/misc/iterTools.py +12 -0
  76. fontTools/misc/lazyTools.py +42 -0
  77. fontTools/misc/loggingTools.py +543 -0
  78. fontTools/misc/macCreatorType.py +56 -0
  79. fontTools/misc/macRes.py +261 -0
  80. fontTools/misc/plistlib/__init__.py +681 -0
  81. fontTools/misc/plistlib/py.typed +0 -0
  82. fontTools/misc/psCharStrings.py +1496 -0
  83. fontTools/misc/psLib.py +398 -0
  84. fontTools/misc/psOperators.py +572 -0
  85. fontTools/misc/py23.py +96 -0
  86. fontTools/misc/roundTools.py +110 -0
  87. fontTools/misc/sstruct.py +231 -0
  88. fontTools/misc/symfont.py +244 -0
  89. fontTools/misc/testTools.py +229 -0
  90. fontTools/misc/textTools.py +154 -0
  91. fontTools/misc/timeTools.py +88 -0
  92. fontTools/misc/transform.py +516 -0
  93. fontTools/misc/treeTools.py +45 -0
  94. fontTools/misc/vector.py +147 -0
  95. fontTools/misc/visitor.py +142 -0
  96. fontTools/misc/xmlReader.py +188 -0
  97. fontTools/misc/xmlWriter.py +204 -0
  98. fontTools/mtiLib/__init__.py +1402 -0
  99. fontTools/mtiLib/__main__.py +5 -0
  100. fontTools/otlLib/__init__.py +1 -0
  101. fontTools/otlLib/builder.py +3221 -0
  102. fontTools/otlLib/error.py +11 -0
  103. fontTools/otlLib/maxContextCalc.py +96 -0
  104. fontTools/otlLib/optimize/__init__.py +53 -0
  105. fontTools/otlLib/optimize/__main__.py +6 -0
  106. fontTools/otlLib/optimize/gpos.py +453 -0
  107. fontTools/pens/__init__.py +1 -0
  108. fontTools/pens/areaPen.py +52 -0
  109. fontTools/pens/basePen.py +475 -0
  110. fontTools/pens/boundsPen.py +98 -0
  111. fontTools/pens/cairoPen.py +26 -0
  112. fontTools/pens/cocoaPen.py +26 -0
  113. fontTools/pens/cu2quPen.py +325 -0
  114. fontTools/pens/explicitClosingLinePen.py +101 -0
  115. fontTools/pens/filterPen.py +241 -0
  116. fontTools/pens/freetypePen.py +462 -0
  117. fontTools/pens/hashPointPen.py +89 -0
  118. fontTools/pens/momentsPen.c +13448 -0
  119. fontTools/pens/momentsPen.cpython-311-x86_64-linux-musl.so +0 -0
  120. fontTools/pens/momentsPen.py +879 -0
  121. fontTools/pens/perimeterPen.py +69 -0
  122. fontTools/pens/pointInsidePen.py +192 -0
  123. fontTools/pens/pointPen.py +600 -0
  124. fontTools/pens/qtPen.py +29 -0
  125. fontTools/pens/qu2cuPen.py +105 -0
  126. fontTools/pens/quartzPen.py +43 -0
  127. fontTools/pens/recordingPen.py +335 -0
  128. fontTools/pens/reportLabPen.py +79 -0
  129. fontTools/pens/reverseContourPen.py +96 -0
  130. fontTools/pens/roundingPen.py +130 -0
  131. fontTools/pens/statisticsPen.py +312 -0
  132. fontTools/pens/svgPathPen.py +310 -0
  133. fontTools/pens/t2CharStringPen.py +68 -0
  134. fontTools/pens/teePen.py +55 -0
  135. fontTools/pens/transformPen.py +115 -0
  136. fontTools/pens/ttGlyphPen.py +335 -0
  137. fontTools/pens/wxPen.py +29 -0
  138. fontTools/qu2cu/__init__.py +15 -0
  139. fontTools/qu2cu/__main__.py +7 -0
  140. fontTools/qu2cu/benchmark.py +56 -0
  141. fontTools/qu2cu/cli.py +125 -0
  142. fontTools/qu2cu/qu2cu.c +16269 -0
  143. fontTools/qu2cu/qu2cu.cpython-311-x86_64-linux-musl.so +0 -0
  144. fontTools/qu2cu/qu2cu.py +405 -0
  145. fontTools/subset/__init__.py +3838 -0
  146. fontTools/subset/__main__.py +6 -0
  147. fontTools/subset/cff.py +184 -0
  148. fontTools/subset/svg.py +253 -0
  149. fontTools/subset/util.py +25 -0
  150. fontTools/svgLib/__init__.py +3 -0
  151. fontTools/svgLib/path/__init__.py +65 -0
  152. fontTools/svgLib/path/arc.py +154 -0
  153. fontTools/svgLib/path/parser.py +322 -0
  154. fontTools/svgLib/path/shapes.py +183 -0
  155. fontTools/t1Lib/__init__.py +648 -0
  156. fontTools/tfmLib.py +460 -0
  157. fontTools/ttLib/__init__.py +26 -0
  158. fontTools/ttLib/__main__.py +109 -0
  159. fontTools/ttLib/macUtils.py +54 -0
  160. fontTools/ttLib/removeOverlaps.py +393 -0
  161. fontTools/ttLib/reorderGlyphs.py +284 -0
  162. fontTools/ttLib/scaleUpem.py +436 -0
  163. fontTools/ttLib/sfnt.py +662 -0
  164. fontTools/ttLib/standardGlyphOrder.py +271 -0
  165. fontTools/ttLib/tables/B_A_S_E_.py +14 -0
  166. fontTools/ttLib/tables/BitmapGlyphMetrics.py +64 -0
  167. fontTools/ttLib/tables/C_B_D_T_.py +113 -0
  168. fontTools/ttLib/tables/C_B_L_C_.py +19 -0
  169. fontTools/ttLib/tables/C_F_F_.py +61 -0
  170. fontTools/ttLib/tables/C_F_F__2.py +26 -0
  171. fontTools/ttLib/tables/C_O_L_R_.py +165 -0
  172. fontTools/ttLib/tables/C_P_A_L_.py +305 -0
  173. fontTools/ttLib/tables/D_S_I_G_.py +158 -0
  174. fontTools/ttLib/tables/D__e_b_g.py +17 -0
  175. fontTools/ttLib/tables/DefaultTable.py +49 -0
  176. fontTools/ttLib/tables/E_B_D_T_.py +835 -0
  177. fontTools/ttLib/tables/E_B_L_C_.py +718 -0
  178. fontTools/ttLib/tables/F_F_T_M_.py +52 -0
  179. fontTools/ttLib/tables/F__e_a_t.py +149 -0
  180. fontTools/ttLib/tables/G_D_E_F_.py +13 -0
  181. fontTools/ttLib/tables/G_M_A_P_.py +148 -0
  182. fontTools/ttLib/tables/G_P_K_G_.py +133 -0
  183. fontTools/ttLib/tables/G_P_O_S_.py +14 -0
  184. fontTools/ttLib/tables/G_S_U_B_.py +13 -0
  185. fontTools/ttLib/tables/G__l_a_t.py +235 -0
  186. fontTools/ttLib/tables/G__l_o_c.py +85 -0
  187. fontTools/ttLib/tables/H_V_A_R_.py +13 -0
  188. fontTools/ttLib/tables/J_S_T_F_.py +13 -0
  189. fontTools/ttLib/tables/L_T_S_H_.py +58 -0
  190. fontTools/ttLib/tables/M_A_T_H_.py +13 -0
  191. fontTools/ttLib/tables/M_E_T_A_.py +352 -0
  192. fontTools/ttLib/tables/M_V_A_R_.py +13 -0
  193. fontTools/ttLib/tables/O_S_2f_2.py +752 -0
  194. fontTools/ttLib/tables/S_I_N_G_.py +99 -0
  195. fontTools/ttLib/tables/S_T_A_T_.py +15 -0
  196. fontTools/ttLib/tables/S_V_G_.py +223 -0
  197. fontTools/ttLib/tables/S__i_l_f.py +1040 -0
  198. fontTools/ttLib/tables/S__i_l_l.py +92 -0
  199. fontTools/ttLib/tables/T_S_I_B_.py +13 -0
  200. fontTools/ttLib/tables/T_S_I_C_.py +14 -0
  201. fontTools/ttLib/tables/T_S_I_D_.py +13 -0
  202. fontTools/ttLib/tables/T_S_I_J_.py +13 -0
  203. fontTools/ttLib/tables/T_S_I_P_.py +13 -0
  204. fontTools/ttLib/tables/T_S_I_S_.py +13 -0
  205. fontTools/ttLib/tables/T_S_I_V_.py +26 -0
  206. fontTools/ttLib/tables/T_S_I__0.py +59 -0
  207. fontTools/ttLib/tables/T_S_I__1.py +166 -0
  208. fontTools/ttLib/tables/T_S_I__2.py +17 -0
  209. fontTools/ttLib/tables/T_S_I__3.py +22 -0
  210. fontTools/ttLib/tables/T_S_I__5.py +49 -0
  211. fontTools/ttLib/tables/T_T_F_A_.py +14 -0
  212. fontTools/ttLib/tables/TupleVariation.py +884 -0
  213. fontTools/ttLib/tables/V_A_R_C_.py +12 -0
  214. fontTools/ttLib/tables/V_D_M_X_.py +249 -0
  215. fontTools/ttLib/tables/V_O_R_G_.py +165 -0
  216. fontTools/ttLib/tables/V_V_A_R_.py +13 -0
  217. fontTools/ttLib/tables/__init__.py +97 -0
  218. fontTools/ttLib/tables/_a_n_k_r.py +15 -0
  219. fontTools/ttLib/tables/_a_v_a_r.py +191 -0
  220. fontTools/ttLib/tables/_b_s_l_n.py +15 -0
  221. fontTools/ttLib/tables/_c_i_d_g.py +24 -0
  222. fontTools/ttLib/tables/_c_m_a_p.py +1578 -0
  223. fontTools/ttLib/tables/_c_v_a_r.py +94 -0
  224. fontTools/ttLib/tables/_c_v_t.py +55 -0
  225. fontTools/ttLib/tables/_f_e_a_t.py +15 -0
  226. fontTools/ttLib/tables/_f_p_g_m.py +60 -0
  227. fontTools/ttLib/tables/_f_v_a_r.py +261 -0
  228. fontTools/ttLib/tables/_g_a_s_p.py +63 -0
  229. fontTools/ttLib/tables/_g_c_i_d.py +13 -0
  230. fontTools/ttLib/tables/_g_l_y_f.py +2311 -0
  231. fontTools/ttLib/tables/_g_v_a_r.py +292 -0
  232. fontTools/ttLib/tables/_h_d_m_x.py +127 -0
  233. fontTools/ttLib/tables/_h_e_a_d.py +130 -0
  234. fontTools/ttLib/tables/_h_h_e_a.py +147 -0
  235. fontTools/ttLib/tables/_h_m_t_x.py +160 -0
  236. fontTools/ttLib/tables/_k_e_r_n.py +289 -0
  237. fontTools/ttLib/tables/_l_c_a_r.py +13 -0
  238. fontTools/ttLib/tables/_l_o_c_a.py +70 -0
  239. fontTools/ttLib/tables/_l_t_a_g.py +72 -0
  240. fontTools/ttLib/tables/_m_a_x_p.py +147 -0
  241. fontTools/ttLib/tables/_m_e_t_a.py +112 -0
  242. fontTools/ttLib/tables/_m_o_r_t.py +14 -0
  243. fontTools/ttLib/tables/_m_o_r_x.py +15 -0
  244. fontTools/ttLib/tables/_n_a_m_e.py +1237 -0
  245. fontTools/ttLib/tables/_o_p_b_d.py +14 -0
  246. fontTools/ttLib/tables/_p_o_s_t.py +317 -0
  247. fontTools/ttLib/tables/_p_r_e_p.py +16 -0
  248. fontTools/ttLib/tables/_p_r_o_p.py +12 -0
  249. fontTools/ttLib/tables/_s_b_i_x.py +129 -0
  250. fontTools/ttLib/tables/_t_r_a_k.py +332 -0
  251. fontTools/ttLib/tables/_v_h_e_a.py +139 -0
  252. fontTools/ttLib/tables/_v_m_t_x.py +19 -0
  253. fontTools/ttLib/tables/asciiTable.py +20 -0
  254. fontTools/ttLib/tables/grUtils.py +92 -0
  255. fontTools/ttLib/tables/otBase.py +1465 -0
  256. fontTools/ttLib/tables/otConverters.py +2065 -0
  257. fontTools/ttLib/tables/otData.py +6400 -0
  258. fontTools/ttLib/tables/otTables.py +2700 -0
  259. fontTools/ttLib/tables/otTraverse.py +162 -0
  260. fontTools/ttLib/tables/sbixGlyph.py +149 -0
  261. fontTools/ttLib/tables/sbixStrike.py +177 -0
  262. fontTools/ttLib/tables/table_API_readme.txt +91 -0
  263. fontTools/ttLib/tables/ttProgram.py +594 -0
  264. fontTools/ttLib/ttCollection.py +125 -0
  265. fontTools/ttLib/ttFont.py +1155 -0
  266. fontTools/ttLib/ttGlyphSet.py +500 -0
  267. fontTools/ttLib/ttVisitor.py +32 -0
  268. fontTools/ttLib/woff2.py +1683 -0
  269. fontTools/ttx.py +467 -0
  270. fontTools/ufoLib/__init__.py +2477 -0
  271. fontTools/ufoLib/converters.py +334 -0
  272. fontTools/ufoLib/errors.py +22 -0
  273. fontTools/ufoLib/etree.py +6 -0
  274. fontTools/ufoLib/filenames.py +291 -0
  275. fontTools/ufoLib/glifLib.py +2022 -0
  276. fontTools/ufoLib/kerning.py +91 -0
  277. fontTools/ufoLib/plistlib.py +47 -0
  278. fontTools/ufoLib/pointPen.py +6 -0
  279. fontTools/ufoLib/utils.py +76 -0
  280. fontTools/ufoLib/validators.py +1186 -0
  281. fontTools/unicode.py +50 -0
  282. fontTools/unicodedata/Blocks.py +802 -0
  283. fontTools/unicodedata/OTTags.py +50 -0
  284. fontTools/unicodedata/ScriptExtensions.py +806 -0
  285. fontTools/unicodedata/Scripts.py +3618 -0
  286. fontTools/unicodedata/__init__.py +298 -0
  287. fontTools/varLib/__init__.py +1511 -0
  288. fontTools/varLib/__main__.py +6 -0
  289. fontTools/varLib/avar.py +260 -0
  290. fontTools/varLib/avarPlanner.py +1004 -0
  291. fontTools/varLib/builder.py +215 -0
  292. fontTools/varLib/cff.py +631 -0
  293. fontTools/varLib/errors.py +219 -0
  294. fontTools/varLib/featureVars.py +689 -0
  295. fontTools/varLib/instancer/__init__.py +1937 -0
  296. fontTools/varLib/instancer/__main__.py +5 -0
  297. fontTools/varLib/instancer/featureVars.py +190 -0
  298. fontTools/varLib/instancer/names.py +388 -0
  299. fontTools/varLib/instancer/solver.py +309 -0
  300. fontTools/varLib/interpolatable.py +1209 -0
  301. fontTools/varLib/interpolatableHelpers.py +396 -0
  302. fontTools/varLib/interpolatablePlot.py +1269 -0
  303. fontTools/varLib/interpolatableTestContourOrder.py +82 -0
  304. fontTools/varLib/interpolatableTestStartingPoint.py +107 -0
  305. fontTools/varLib/interpolate_layout.py +124 -0
  306. fontTools/varLib/iup.c +19154 -0
  307. fontTools/varLib/iup.cpython-311-x86_64-linux-musl.so +0 -0
  308. fontTools/varLib/iup.py +490 -0
  309. fontTools/varLib/merger.py +1717 -0
  310. fontTools/varLib/models.py +642 -0
  311. fontTools/varLib/multiVarStore.py +253 -0
  312. fontTools/varLib/mutator.py +518 -0
  313. fontTools/varLib/mvar.py +40 -0
  314. fontTools/varLib/plot.py +238 -0
  315. fontTools/varLib/stat.py +149 -0
  316. fontTools/varLib/varStore.py +767 -0
  317. fontTools/voltLib/__init__.py +5 -0
  318. fontTools/voltLib/ast.py +448 -0
  319. fontTools/voltLib/error.py +12 -0
  320. fontTools/voltLib/lexer.py +99 -0
  321. fontTools/voltLib/parser.py +656 -0
  322. fontTools/voltLib/voltToFea.py +730 -0
  323. fonttools-4.55.6.data/data/share/man/man1/ttx.1 +225 -0
  324. fonttools-4.55.6.dist-info/LICENSE +21 -0
  325. fonttools-4.55.6.dist-info/METADATA +3413 -0
  326. fonttools-4.55.6.dist-info/RECORD +329 -0
  327. fonttools-4.55.6.dist-info/WHEEL +5 -0
  328. fonttools-4.55.6.dist-info/entry_points.txt +5 -0
  329. fonttools-4.55.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,292 @@
1
+ from collections import deque
2
+ from functools import partial
3
+ from fontTools.misc import sstruct
4
+ from fontTools.misc.textTools import safeEval
5
+ from fontTools.misc.lazyTools import LazyDict
6
+ from fontTools.ttLib.tables.TupleVariation import TupleVariation
7
+ from . import DefaultTable
8
+ import array
9
+ import itertools
10
+ import logging
11
+ import struct
12
+ import sys
13
+ import fontTools.ttLib.tables.TupleVariation as tv
14
+
15
+ log = logging.getLogger(__name__)
16
+
17
+ # https://www.microsoft.com/typography/otspec/gvar.htm
18
+ # https://www.microsoft.com/typography/otspec/otvarcommonformats.htm
19
+ #
20
+ # Apple's documentation of 'gvar':
21
+ # https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6gvar.html
22
+ #
23
+ # FreeType2 source code for parsing 'gvar':
24
+ # http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/truetype/ttgxvar.c
25
+
26
+ GVAR_HEADER_FORMAT = """
27
+ > # big endian
28
+ version: H
29
+ reserved: H
30
+ axisCount: H
31
+ sharedTupleCount: H
32
+ offsetToSharedTuples: I
33
+ glyphCount: H
34
+ flags: H
35
+ offsetToGlyphVariationData: I
36
+ """
37
+
38
+ GVAR_HEADER_SIZE = sstruct.calcsize(GVAR_HEADER_FORMAT)
39
+
40
+
41
+ class table__g_v_a_r(DefaultTable.DefaultTable):
42
+ """Glyph Variations table
43
+
44
+ The ``gvar`` table provides the per-glyph variation data that
45
+ describe how glyph outlines in the ``glyf`` table change across
46
+ the variation space that is defined for the font in the ``fvar``
47
+ table.
48
+
49
+ See also https://learn.microsoft.com/en-us/typography/opentype/spec/gvar
50
+ """
51
+
52
+ dependencies = ["fvar", "glyf"]
53
+
54
+ def __init__(self, tag=None):
55
+ DefaultTable.DefaultTable.__init__(self, tag)
56
+ self.version, self.reserved = 1, 0
57
+ self.variations = {}
58
+
59
+ def compile(self, ttFont):
60
+ axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
61
+ sharedTuples = tv.compileSharedTuples(
62
+ axisTags, itertools.chain(*self.variations.values())
63
+ )
64
+ sharedTupleIndices = {coord: i for i, coord in enumerate(sharedTuples)}
65
+ sharedTupleSize = sum([len(c) for c in sharedTuples])
66
+ compiledGlyphs = self.compileGlyphs_(ttFont, axisTags, sharedTupleIndices)
67
+ offset = 0
68
+ offsets = []
69
+ for glyph in compiledGlyphs:
70
+ offsets.append(offset)
71
+ offset += len(glyph)
72
+ offsets.append(offset)
73
+ compiledOffsets, tableFormat = self.compileOffsets_(offsets)
74
+
75
+ header = {}
76
+ header["version"] = self.version
77
+ header["reserved"] = self.reserved
78
+ header["axisCount"] = len(axisTags)
79
+ header["sharedTupleCount"] = len(sharedTuples)
80
+ header["offsetToSharedTuples"] = GVAR_HEADER_SIZE + len(compiledOffsets)
81
+ header["glyphCount"] = len(compiledGlyphs)
82
+ header["flags"] = tableFormat
83
+ header["offsetToGlyphVariationData"] = (
84
+ header["offsetToSharedTuples"] + sharedTupleSize
85
+ )
86
+ compiledHeader = sstruct.pack(GVAR_HEADER_FORMAT, header)
87
+
88
+ result = [compiledHeader, compiledOffsets]
89
+ result.extend(sharedTuples)
90
+ result.extend(compiledGlyphs)
91
+ return b"".join(result)
92
+
93
+ def compileGlyphs_(self, ttFont, axisTags, sharedCoordIndices):
94
+ result = []
95
+ glyf = ttFont["glyf"]
96
+ optimizeSize = getattr(self, "optimizeSize", True)
97
+ for glyphName in ttFont.getGlyphOrder():
98
+ variations = self.variations.get(glyphName, [])
99
+ if not variations:
100
+ result.append(b"")
101
+ continue
102
+ pointCountUnused = 0 # pointCount is actually unused by compileGlyph
103
+ result.append(
104
+ compileGlyph_(
105
+ variations,
106
+ pointCountUnused,
107
+ axisTags,
108
+ sharedCoordIndices,
109
+ optimizeSize=optimizeSize,
110
+ )
111
+ )
112
+ return result
113
+
114
+ def decompile(self, data, ttFont):
115
+ axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
116
+ glyphs = ttFont.getGlyphOrder()
117
+ sstruct.unpack(GVAR_HEADER_FORMAT, data[0:GVAR_HEADER_SIZE], self)
118
+ assert len(glyphs) == self.glyphCount
119
+ assert len(axisTags) == self.axisCount
120
+ sharedCoords = tv.decompileSharedTuples(
121
+ axisTags, self.sharedTupleCount, data, self.offsetToSharedTuples
122
+ )
123
+ variations = {}
124
+ offsetToData = self.offsetToGlyphVariationData
125
+ glyf = ttFont["glyf"]
126
+
127
+ def get_read_item():
128
+ reverseGlyphMap = ttFont.getReverseGlyphMap()
129
+ tableFormat = self.flags & 1
130
+
131
+ def read_item(glyphName):
132
+ gid = reverseGlyphMap[glyphName]
133
+ offsetSize = 2 if tableFormat == 0 else 4
134
+ startOffset = GVAR_HEADER_SIZE + offsetSize * gid
135
+ endOffset = startOffset + offsetSize * 2
136
+ offsets = table__g_v_a_r.decompileOffsets_(
137
+ data[startOffset:endOffset],
138
+ tableFormat=tableFormat,
139
+ glyphCount=1,
140
+ )
141
+ gvarData = data[offsetToData + offsets[0] : offsetToData + offsets[1]]
142
+ if not gvarData:
143
+ return []
144
+ glyph = glyf[glyphName]
145
+ numPointsInGlyph = self.getNumPoints_(glyph)
146
+ return decompileGlyph_(
147
+ numPointsInGlyph, sharedCoords, axisTags, gvarData
148
+ )
149
+
150
+ return read_item
151
+
152
+ read_item = get_read_item()
153
+ l = LazyDict({glyphs[gid]: read_item for gid in range(self.glyphCount)})
154
+
155
+ self.variations = l
156
+
157
+ if ttFont.lazy is False: # Be lazy for None and True
158
+ self.ensureDecompiled()
159
+
160
+ def ensureDecompiled(self, recurse=False):
161
+ # The recurse argument is unused, but part of the signature of
162
+ # ensureDecompiled across the library.
163
+ # Use a zero-length deque to consume the lazy dict
164
+ deque(self.variations.values(), maxlen=0)
165
+
166
+ @staticmethod
167
+ def decompileOffsets_(data, tableFormat, glyphCount):
168
+ if tableFormat == 0:
169
+ # Short format: array of UInt16
170
+ offsets = array.array("H")
171
+ offsetsSize = (glyphCount + 1) * 2
172
+ else:
173
+ # Long format: array of UInt32
174
+ offsets = array.array("I")
175
+ offsetsSize = (glyphCount + 1) * 4
176
+ offsets.frombytes(data[0:offsetsSize])
177
+ if sys.byteorder != "big":
178
+ offsets.byteswap()
179
+
180
+ # In the short format, offsets need to be multiplied by 2.
181
+ # This is not documented in Apple's TrueType specification,
182
+ # but can be inferred from the FreeType implementation, and
183
+ # we could verify it with two sample GX fonts.
184
+ if tableFormat == 0:
185
+ offsets = [off * 2 for off in offsets]
186
+
187
+ return offsets
188
+
189
+ @staticmethod
190
+ def compileOffsets_(offsets):
191
+ """Packs a list of offsets into a 'gvar' offset table.
192
+
193
+ Returns a pair (bytestring, tableFormat). Bytestring is the
194
+ packed offset table. Format indicates whether the table
195
+ uses short (tableFormat=0) or long (tableFormat=1) integers.
196
+ The returned tableFormat should get packed into the flags field
197
+ of the 'gvar' header.
198
+ """
199
+ assert len(offsets) >= 2
200
+ for i in range(1, len(offsets)):
201
+ assert offsets[i - 1] <= offsets[i]
202
+ if max(offsets) <= 0xFFFF * 2:
203
+ packed = array.array("H", [n >> 1 for n in offsets])
204
+ tableFormat = 0
205
+ else:
206
+ packed = array.array("I", offsets)
207
+ tableFormat = 1
208
+ if sys.byteorder != "big":
209
+ packed.byteswap()
210
+ return (packed.tobytes(), tableFormat)
211
+
212
+ def toXML(self, writer, ttFont):
213
+ writer.simpletag("version", value=self.version)
214
+ writer.newline()
215
+ writer.simpletag("reserved", value=self.reserved)
216
+ writer.newline()
217
+ axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
218
+ for glyphName in ttFont.getGlyphNames():
219
+ variations = self.variations.get(glyphName)
220
+ if not variations:
221
+ continue
222
+ writer.begintag("glyphVariations", glyph=glyphName)
223
+ writer.newline()
224
+ for gvar in variations:
225
+ gvar.toXML(writer, axisTags)
226
+ writer.endtag("glyphVariations")
227
+ writer.newline()
228
+
229
+ def fromXML(self, name, attrs, content, ttFont):
230
+ if name == "version":
231
+ self.version = safeEval(attrs["value"])
232
+ elif name == "reserved":
233
+ self.reserved = safeEval(attrs["value"])
234
+ elif name == "glyphVariations":
235
+ if not hasattr(self, "variations"):
236
+ self.variations = {}
237
+ glyphName = attrs["glyph"]
238
+ glyph = ttFont["glyf"][glyphName]
239
+ numPointsInGlyph = self.getNumPoints_(glyph)
240
+ glyphVariations = []
241
+ for element in content:
242
+ if isinstance(element, tuple):
243
+ name, attrs, content = element
244
+ if name == "tuple":
245
+ gvar = TupleVariation({}, [None] * numPointsInGlyph)
246
+ glyphVariations.append(gvar)
247
+ for tupleElement in content:
248
+ if isinstance(tupleElement, tuple):
249
+ tupleName, tupleAttrs, tupleContent = tupleElement
250
+ gvar.fromXML(tupleName, tupleAttrs, tupleContent)
251
+ self.variations[glyphName] = glyphVariations
252
+
253
+ @staticmethod
254
+ def getNumPoints_(glyph):
255
+ NUM_PHANTOM_POINTS = 4
256
+
257
+ if glyph.isComposite():
258
+ return len(glyph.components) + NUM_PHANTOM_POINTS
259
+ else:
260
+ # Empty glyphs (eg. space, nonmarkingreturn) have no "coordinates" attribute.
261
+ return len(getattr(glyph, "coordinates", [])) + NUM_PHANTOM_POINTS
262
+
263
+
264
+ def compileGlyph_(
265
+ variations, pointCount, axisTags, sharedCoordIndices, *, optimizeSize=True
266
+ ):
267
+ tupleVariationCount, tuples, data = tv.compileTupleVariationStore(
268
+ variations, pointCount, axisTags, sharedCoordIndices, optimizeSize=optimizeSize
269
+ )
270
+ if tupleVariationCount == 0:
271
+ return b""
272
+ result = [struct.pack(">HH", tupleVariationCount, 4 + len(tuples)), tuples, data]
273
+ if (len(tuples) + len(data)) % 2 != 0:
274
+ result.append(b"\0") # padding
275
+ return b"".join(result)
276
+
277
+
278
+ def decompileGlyph_(pointCount, sharedTuples, axisTags, data):
279
+ if len(data) < 4:
280
+ return []
281
+ tupleVariationCount, offsetToData = struct.unpack(">HH", data[:4])
282
+ dataPos = offsetToData
283
+ return tv.decompileTupleVariationStore(
284
+ "gvar",
285
+ axisTags,
286
+ tupleVariationCount,
287
+ pointCount,
288
+ sharedTuples,
289
+ data,
290
+ 4,
291
+ offsetToData,
292
+ )
@@ -0,0 +1,127 @@
1
+ from fontTools.misc import sstruct
2
+ from fontTools.misc.textTools import bytechr, byteord, strjoin
3
+ from . import DefaultTable
4
+ import array
5
+ from collections.abc import Mapping
6
+
7
+ hdmxHeaderFormat = """
8
+ > # big endian!
9
+ version: H
10
+ numRecords: H
11
+ recordSize: l
12
+ """
13
+
14
+
15
+ class _GlyphnamedList(Mapping):
16
+ def __init__(self, reverseGlyphOrder, data):
17
+ self._array = data
18
+ self._map = dict(reverseGlyphOrder)
19
+
20
+ def __getitem__(self, k):
21
+ return self._array[self._map[k]]
22
+
23
+ def __len__(self):
24
+ return len(self._map)
25
+
26
+ def __iter__(self):
27
+ return iter(self._map)
28
+
29
+ def keys(self):
30
+ return self._map.keys()
31
+
32
+
33
+ class table__h_d_m_x(DefaultTable.DefaultTable):
34
+ """Horizontal Device Metrics table
35
+
36
+ The ``hdmx`` table is an optional table that stores advance widths for
37
+ glyph outlines at specified pixel sizes.
38
+
39
+ See also https://learn.microsoft.com/en-us/typography/opentype/spec/hdmx
40
+ """
41
+
42
+ def decompile(self, data, ttFont):
43
+ numGlyphs = ttFont["maxp"].numGlyphs
44
+ glyphOrder = ttFont.getGlyphOrder()
45
+ dummy, data = sstruct.unpack2(hdmxHeaderFormat, data, self)
46
+ self.hdmx = {}
47
+ for i in range(self.numRecords):
48
+ ppem = byteord(data[0])
49
+ maxSize = byteord(data[1])
50
+ widths = _GlyphnamedList(
51
+ ttFont.getReverseGlyphMap(), array.array("B", data[2 : 2 + numGlyphs])
52
+ )
53
+ self.hdmx[ppem] = widths
54
+ data = data[self.recordSize :]
55
+ assert len(data) == 0, "too much hdmx data"
56
+
57
+ def compile(self, ttFont):
58
+ self.version = 0
59
+ numGlyphs = ttFont["maxp"].numGlyphs
60
+ glyphOrder = ttFont.getGlyphOrder()
61
+ self.recordSize = 4 * ((2 + numGlyphs + 3) // 4)
62
+ pad = (self.recordSize - 2 - numGlyphs) * b"\0"
63
+ self.numRecords = len(self.hdmx)
64
+ data = sstruct.pack(hdmxHeaderFormat, self)
65
+ items = sorted(self.hdmx.items())
66
+ for ppem, widths in items:
67
+ data = data + bytechr(ppem) + bytechr(max(widths.values()))
68
+ for glyphID in range(len(glyphOrder)):
69
+ width = widths[glyphOrder[glyphID]]
70
+ data = data + bytechr(width)
71
+ data = data + pad
72
+ return data
73
+
74
+ def toXML(self, writer, ttFont):
75
+ writer.begintag("hdmxData")
76
+ writer.newline()
77
+ ppems = sorted(self.hdmx.keys())
78
+ records = []
79
+ format = ""
80
+ for ppem in ppems:
81
+ widths = self.hdmx[ppem]
82
+ records.append(widths)
83
+ format = format + "%4d"
84
+ glyphNames = ttFont.getGlyphOrder()[:]
85
+ glyphNames.sort()
86
+ maxNameLen = max(map(len, glyphNames))
87
+ format = "%" + repr(maxNameLen) + "s:" + format + " ;"
88
+ writer.write(format % (("ppem",) + tuple(ppems)))
89
+ writer.newline()
90
+ writer.newline()
91
+ for glyphName in glyphNames:
92
+ row = []
93
+ for ppem in ppems:
94
+ widths = self.hdmx[ppem]
95
+ row.append(widths[glyphName])
96
+ if ";" in glyphName:
97
+ glyphName = "\\x3b".join(glyphName.split(";"))
98
+ writer.write(format % ((glyphName,) + tuple(row)))
99
+ writer.newline()
100
+ writer.endtag("hdmxData")
101
+ writer.newline()
102
+
103
+ def fromXML(self, name, attrs, content, ttFont):
104
+ if name != "hdmxData":
105
+ return
106
+ content = strjoin(content)
107
+ lines = content.split(";")
108
+ topRow = lines[0].split()
109
+ assert topRow[0] == "ppem:", "illegal hdmx format"
110
+ ppems = list(map(int, topRow[1:]))
111
+ self.hdmx = hdmx = {}
112
+ for ppem in ppems:
113
+ hdmx[ppem] = {}
114
+ lines = (line.split() for line in lines[1:])
115
+ for line in lines:
116
+ if not line:
117
+ continue
118
+ assert line[0][-1] == ":", "illegal hdmx format"
119
+ glyphName = line[0][:-1]
120
+ if "\\" in glyphName:
121
+ from fontTools.misc.textTools import safeEval
122
+
123
+ glyphName = safeEval('"""' + glyphName + '"""')
124
+ line = list(map(int, line[1:]))
125
+ assert len(line) == len(ppems), "illegal hdmx format"
126
+ for i in range(len(ppems)):
127
+ hdmx[ppems[i]][glyphName] = line[i]
@@ -0,0 +1,130 @@
1
+ from fontTools.misc import sstruct
2
+ from fontTools.misc.fixedTools import floatToFixedToStr, strToFixedToFloat
3
+ from fontTools.misc.textTools import safeEval, num2binary, binary2num
4
+ from fontTools.misc.timeTools import (
5
+ timestampFromString,
6
+ timestampToString,
7
+ timestampNow,
8
+ )
9
+ from fontTools.misc.timeTools import epoch_diff as mac_epoch_diff # For backward compat
10
+ from fontTools.misc.arrayTools import intRect, unionRect
11
+ from . import DefaultTable
12
+ import logging
13
+
14
+
15
+ log = logging.getLogger(__name__)
16
+
17
+ headFormat = """
18
+ > # big endian
19
+ tableVersion: 16.16F
20
+ fontRevision: 16.16F
21
+ checkSumAdjustment: I
22
+ magicNumber: I
23
+ flags: H
24
+ unitsPerEm: H
25
+ created: Q
26
+ modified: Q
27
+ xMin: h
28
+ yMin: h
29
+ xMax: h
30
+ yMax: h
31
+ macStyle: H
32
+ lowestRecPPEM: H
33
+ fontDirectionHint: h
34
+ indexToLocFormat: h
35
+ glyphDataFormat: h
36
+ """
37
+
38
+
39
+ class table__h_e_a_d(DefaultTable.DefaultTable):
40
+ """Font Header table
41
+
42
+ The ``head`` table contains a variety of font-wide information.
43
+
44
+ See also https://learn.microsoft.com/en-us/typography/opentype/spec/head
45
+ """
46
+
47
+ dependencies = ["maxp", "loca", "CFF ", "CFF2"]
48
+
49
+ def decompile(self, data, ttFont):
50
+ dummy, rest = sstruct.unpack2(headFormat, data, self)
51
+ if rest:
52
+ # this is quite illegal, but there seem to be fonts out there that do this
53
+ log.warning("extra bytes at the end of 'head' table")
54
+ assert rest == b"\0\0"
55
+
56
+ # For timestamp fields, ignore the top four bytes. Some fonts have
57
+ # bogus values there. Since till 2038 those bytes only can be zero,
58
+ # ignore them.
59
+ #
60
+ # https://github.com/fonttools/fonttools/issues/99#issuecomment-66776810
61
+ for stamp in "created", "modified":
62
+ value = getattr(self, stamp)
63
+ if value > 0xFFFFFFFF:
64
+ log.warning("'%s' timestamp out of range; ignoring top bytes", stamp)
65
+ value &= 0xFFFFFFFF
66
+ setattr(self, stamp, value)
67
+ if value < 0x7C259DC0: # January 1, 1970 00:00:00
68
+ log.warning(
69
+ "'%s' timestamp seems very low; regarding as unix timestamp", stamp
70
+ )
71
+ value += 0x7C259DC0
72
+ setattr(self, stamp, value)
73
+
74
+ def compile(self, ttFont):
75
+ if ttFont.recalcBBoxes:
76
+ # For TT-flavored fonts, xMin, yMin, xMax and yMax are set in table__m_a_x_p.recalc().
77
+ if "CFF " in ttFont:
78
+ topDict = ttFont["CFF "].cff.topDictIndex[0]
79
+ self.xMin, self.yMin, self.xMax, self.yMax = intRect(topDict.FontBBox)
80
+ elif "CFF2" in ttFont:
81
+ topDict = ttFont["CFF2"].cff.topDictIndex[0]
82
+ charStrings = topDict.CharStrings
83
+ fontBBox = None
84
+ for charString in charStrings.values():
85
+ bounds = charString.calcBounds(charStrings)
86
+ if bounds is not None:
87
+ if fontBBox is not None:
88
+ fontBBox = unionRect(fontBBox, bounds)
89
+ else:
90
+ fontBBox = bounds
91
+ if fontBBox is not None:
92
+ self.xMin, self.yMin, self.xMax, self.yMax = intRect(fontBBox)
93
+ if ttFont.recalcTimestamp:
94
+ self.modified = timestampNow()
95
+ data = sstruct.pack(headFormat, self)
96
+ return data
97
+
98
+ def toXML(self, writer, ttFont):
99
+ writer.comment("Most of this table will be recalculated by the compiler")
100
+ writer.newline()
101
+ _, names, fixes = sstruct.getformat(headFormat)
102
+ for name in names:
103
+ value = getattr(self, name)
104
+ if name in fixes:
105
+ value = floatToFixedToStr(value, precisionBits=fixes[name])
106
+ elif name in ("created", "modified"):
107
+ value = timestampToString(value)
108
+ elif name in ("magicNumber", "checkSumAdjustment"):
109
+ if value < 0:
110
+ value = value + 0x100000000
111
+ value = hex(value)
112
+ if value[-1:] == "L":
113
+ value = value[:-1]
114
+ elif name in ("macStyle", "flags"):
115
+ value = num2binary(value, 16)
116
+ writer.simpletag(name, value=value)
117
+ writer.newline()
118
+
119
+ def fromXML(self, name, attrs, content, ttFont):
120
+ value = attrs["value"]
121
+ fixes = sstruct.getformat(headFormat)[2]
122
+ if name in fixes:
123
+ value = strToFixedToFloat(value, precisionBits=fixes[name])
124
+ elif name in ("created", "modified"):
125
+ value = timestampFromString(value)
126
+ elif name in ("macStyle", "flags"):
127
+ value = binary2num(value)
128
+ else:
129
+ value = safeEval(value)
130
+ setattr(self, name, value)
@@ -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"]))