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,253 @@
1
+ """
2
+ The `OpenType specification <https://docs.microsoft.com/en-us/typography/opentype/spec/otff#data-types>`_
3
+ defines two fixed-point data types:
4
+
5
+ ``Fixed``
6
+ A 32-bit signed fixed-point number with a 16 bit twos-complement
7
+ magnitude component and 16 fractional bits.
8
+ ``F2DOT14``
9
+ A 16-bit signed fixed-point number with a 2 bit twos-complement
10
+ magnitude component and 14 fractional bits.
11
+
12
+ To support reading and writing data with these data types, this module provides
13
+ functions for converting between fixed-point, float and string representations.
14
+
15
+ .. data:: MAX_F2DOT14
16
+
17
+ The maximum value that can still fit in an F2Dot14. (1.99993896484375)
18
+ """
19
+
20
+ from .roundTools import otRound, nearestMultipleShortestRepr
21
+ import logging
22
+
23
+ log = logging.getLogger(__name__)
24
+
25
+ __all__ = [
26
+ "MAX_F2DOT14",
27
+ "fixedToFloat",
28
+ "floatToFixed",
29
+ "floatToFixedToFloat",
30
+ "floatToFixedToStr",
31
+ "fixedToStr",
32
+ "strToFixed",
33
+ "strToFixedToFloat",
34
+ "ensureVersionIsLong",
35
+ "versionToFixed",
36
+ ]
37
+
38
+
39
+ MAX_F2DOT14 = 0x7FFF / (1 << 14)
40
+
41
+
42
+ def fixedToFloat(value, precisionBits):
43
+ """Converts a fixed-point number to a float given the number of
44
+ precision bits.
45
+
46
+ Args:
47
+ value (int): Number in fixed-point format.
48
+ precisionBits (int): Number of precision bits.
49
+
50
+ Returns:
51
+ Floating point value.
52
+
53
+ Examples::
54
+
55
+ >>> import math
56
+ >>> f = fixedToFloat(-10139, precisionBits=14)
57
+ >>> math.isclose(f, -0.61883544921875)
58
+ True
59
+ """
60
+ return value / (1 << precisionBits)
61
+
62
+
63
+ def floatToFixed(value, precisionBits):
64
+ """Converts a float to a fixed-point number given the number of
65
+ precision bits.
66
+
67
+ Args:
68
+ value (float): Floating point value.
69
+ precisionBits (int): Number of precision bits.
70
+
71
+ Returns:
72
+ int: Fixed-point representation.
73
+
74
+ Examples::
75
+
76
+ >>> floatToFixed(-0.61883544921875, precisionBits=14)
77
+ -10139
78
+ >>> floatToFixed(-0.61884, precisionBits=14)
79
+ -10139
80
+ """
81
+ return otRound(value * (1 << precisionBits))
82
+
83
+
84
+ def floatToFixedToFloat(value, precisionBits):
85
+ """Converts a float to a fixed-point number and back again.
86
+
87
+ By converting the float to fixed, rounding it, and converting it back
88
+ to float again, this returns a floating point values which is exactly
89
+ representable in fixed-point format.
90
+
91
+ Note: this **is** equivalent to ``fixedToFloat(floatToFixed(value))``.
92
+
93
+ Args:
94
+ value (float): The input floating point value.
95
+ precisionBits (int): Number of precision bits.
96
+
97
+ Returns:
98
+ float: The transformed and rounded value.
99
+
100
+ Examples::
101
+ >>> import math
102
+ >>> f1 = -0.61884
103
+ >>> f2 = floatToFixedToFloat(-0.61884, precisionBits=14)
104
+ >>> f1 != f2
105
+ True
106
+ >>> math.isclose(f2, -0.61883544921875)
107
+ True
108
+ """
109
+ scale = 1 << precisionBits
110
+ return otRound(value * scale) / scale
111
+
112
+
113
+ def fixedToStr(value, precisionBits):
114
+ """Converts a fixed-point number to a string representing a decimal float.
115
+
116
+ This chooses the float that has the shortest decimal representation (the least
117
+ number of fractional decimal digits).
118
+
119
+ For example, to convert a fixed-point number in a 2.14 format, use
120
+ ``precisionBits=14``::
121
+
122
+ >>> fixedToStr(-10139, precisionBits=14)
123
+ '-0.61884'
124
+
125
+ This is pretty slow compared to the simple division used in ``fixedToFloat``.
126
+ Use sporadically when you need to serialize or print the fixed-point number in
127
+ a human-readable form.
128
+ It uses nearestMultipleShortestRepr under the hood.
129
+
130
+ Args:
131
+ value (int): The fixed-point value to convert.
132
+ precisionBits (int): Number of precision bits, *up to a maximum of 16*.
133
+
134
+ Returns:
135
+ str: A string representation of the value.
136
+ """
137
+ scale = 1 << precisionBits
138
+ return nearestMultipleShortestRepr(value / scale, factor=1.0 / scale)
139
+
140
+
141
+ def strToFixed(string, precisionBits):
142
+ """Converts a string representing a decimal float to a fixed-point number.
143
+
144
+ Args:
145
+ string (str): A string representing a decimal float.
146
+ precisionBits (int): Number of precision bits, *up to a maximum of 16*.
147
+
148
+ Returns:
149
+ int: Fixed-point representation.
150
+
151
+ Examples::
152
+
153
+ >>> ## to convert a float string to a 2.14 fixed-point number:
154
+ >>> strToFixed('-0.61884', precisionBits=14)
155
+ -10139
156
+ """
157
+ value = float(string)
158
+ return otRound(value * (1 << precisionBits))
159
+
160
+
161
+ def strToFixedToFloat(string, precisionBits):
162
+ """Convert a string to a decimal float with fixed-point rounding.
163
+
164
+ This first converts string to a float, then turns it into a fixed-point
165
+ number with ``precisionBits`` fractional binary digits, then back to a
166
+ float again.
167
+
168
+ This is simply a shorthand for fixedToFloat(floatToFixed(float(s))).
169
+
170
+ Args:
171
+ string (str): A string representing a decimal float.
172
+ precisionBits (int): Number of precision bits.
173
+
174
+ Returns:
175
+ float: The transformed and rounded value.
176
+
177
+ Examples::
178
+
179
+ >>> import math
180
+ >>> s = '-0.61884'
181
+ >>> bits = 14
182
+ >>> f = strToFixedToFloat(s, precisionBits=bits)
183
+ >>> math.isclose(f, -0.61883544921875)
184
+ True
185
+ >>> f == fixedToFloat(floatToFixed(float(s), precisionBits=bits), precisionBits=bits)
186
+ True
187
+ """
188
+ value = float(string)
189
+ scale = 1 << precisionBits
190
+ return otRound(value * scale) / scale
191
+
192
+
193
+ def floatToFixedToStr(value, precisionBits):
194
+ """Convert float to string with fixed-point rounding.
195
+
196
+ This uses the shortest decimal representation (ie. the least
197
+ number of fractional decimal digits) to represent the equivalent
198
+ fixed-point number with ``precisionBits`` fractional binary digits.
199
+ It uses nearestMultipleShortestRepr under the hood.
200
+
201
+ >>> floatToFixedToStr(-0.61883544921875, precisionBits=14)
202
+ '-0.61884'
203
+
204
+ Args:
205
+ value (float): The float value to convert.
206
+ precisionBits (int): Number of precision bits, *up to a maximum of 16*.
207
+
208
+ Returns:
209
+ str: A string representation of the value.
210
+
211
+ """
212
+ scale = 1 << precisionBits
213
+ return nearestMultipleShortestRepr(value, factor=1.0 / scale)
214
+
215
+
216
+ def ensureVersionIsLong(value):
217
+ """Ensure a table version is an unsigned long.
218
+
219
+ OpenType table version numbers are expressed as a single unsigned long
220
+ comprising of an unsigned short major version and unsigned short minor
221
+ version. This function detects if the value to be used as a version number
222
+ looks too small (i.e. is less than ``0x10000``), and converts it to
223
+ fixed-point using :func:`floatToFixed` if so.
224
+
225
+ Args:
226
+ value (Number): a candidate table version number.
227
+
228
+ Returns:
229
+ int: A table version number, possibly corrected to fixed-point.
230
+ """
231
+ if value < 0x10000:
232
+ newValue = floatToFixed(value, 16)
233
+ log.warning(
234
+ "Table version value is a float: %.4f; " "fix to use hex instead: 0x%08x",
235
+ value,
236
+ newValue,
237
+ )
238
+ value = newValue
239
+ return value
240
+
241
+
242
+ def versionToFixed(value):
243
+ """Ensure a table version number is fixed-point.
244
+
245
+ Args:
246
+ value (str): a candidate table version number.
247
+
248
+ Returns:
249
+ int: A table version number, possibly corrected to fixed-point.
250
+ """
251
+ value = int(value, 0) if value.startswith("0") else float(value)
252
+ value = ensureVersionIsLong(value)
253
+ return value
@@ -0,0 +1,25 @@
1
+ __all__ = ["popCount", "bit_count", "bit_indices"]
2
+
3
+
4
+ try:
5
+ bit_count = int.bit_count
6
+ except AttributeError:
7
+
8
+ def bit_count(v):
9
+ return bin(v).count("1")
10
+
11
+
12
+ """Return number of 1 bits (population count) of the absolute value of an integer.
13
+
14
+ See https://docs.python.org/3.10/library/stdtypes.html#int.bit_count
15
+ """
16
+ popCount = bit_count # alias
17
+
18
+
19
+ def bit_indices(v):
20
+ """Return list of indices where bits are set, 0 being the index of the least significant bit.
21
+
22
+ >>> bit_indices(0b101)
23
+ [0, 2]
24
+ """
25
+ return [i for i, b in enumerate(bin(v)[::-1]) if b == "1"]
@@ -0,0 +1,12 @@
1
+ from itertools import *
2
+
3
+ # Python 3.12:
4
+ if "batched" not in globals():
5
+ # https://docs.python.org/3/library/itertools.html#itertools.batched
6
+ def batched(iterable, n):
7
+ # batched('ABCDEFG', 3) --> ABC DEF G
8
+ if n < 1:
9
+ raise ValueError("n must be at least one")
10
+ it = iter(iterable)
11
+ while batch := tuple(islice(it, n)):
12
+ yield batch
@@ -0,0 +1,42 @@
1
+ from collections import UserDict, UserList
2
+
3
+ __all__ = ["LazyDict", "LazyList"]
4
+
5
+
6
+ class LazyDict(UserDict):
7
+ def __init__(self, data):
8
+ super().__init__()
9
+ self.data = data
10
+
11
+ def __getitem__(self, k):
12
+ v = self.data[k]
13
+ if callable(v):
14
+ v = v(k)
15
+ self.data[k] = v
16
+ return v
17
+
18
+
19
+ class LazyList(UserList):
20
+ def __getitem__(self, k):
21
+ if isinstance(k, slice):
22
+ indices = range(*k.indices(len(self)))
23
+ return [self[i] for i in indices]
24
+ v = self.data[k]
25
+ if callable(v):
26
+ v = v(k)
27
+ self.data[k] = v
28
+ return v
29
+
30
+ def __add__(self, other):
31
+ if isinstance(other, LazyList):
32
+ other = list(other)
33
+ elif isinstance(other, list):
34
+ pass
35
+ else:
36
+ return NotImplemented
37
+ return list(self) + other
38
+
39
+ def __radd__(self, other):
40
+ if not isinstance(other, list):
41
+ return NotImplemented
42
+ return other + list(self)