momentsPen.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879
  1. from fontTools.pens.basePen import BasePen, OpenContourError
  2. try:
  3. import cython
  4. except (AttributeError, ImportError):
  5. # if cython not installed, use mock module with no-op decorators and types
  6. from fontTools.misc import cython
  7. COMPILED = cython.compiled
  8. __all__ = ["MomentsPen"]
  9. class MomentsPen(BasePen):
  10. def __init__(self, glyphset=None):
  11. BasePen.__init__(self, glyphset)
  12. self.area = 0
  13. self.momentX = 0
  14. self.momentY = 0
  15. self.momentXX = 0
  16. self.momentXY = 0
  17. self.momentYY = 0
  18. def _moveTo(self, p0):
  19. self._startPoint = p0
  20. def _closePath(self):
  21. p0 = self._getCurrentPoint()
  22. if p0 != self._startPoint:
  23. self._lineTo(self._startPoint)
  24. def _endPath(self):
  25. p0 = self._getCurrentPoint()
  26. if p0 != self._startPoint:
  27. raise OpenContourError("Glyph statistics is not defined on open contours.")
  28. @cython.locals(r0=cython.double)
  29. @cython.locals(r1=cython.double)
  30. @cython.locals(r2=cython.double)
  31. @cython.locals(r3=cython.double)
  32. @cython.locals(r4=cython.double)
  33. @cython.locals(r5=cython.double)
  34. @cython.locals(r6=cython.double)
  35. @cython.locals(r7=cython.double)
  36. @cython.locals(r8=cython.double)
  37. @cython.locals(r9=cython.double)
  38. @cython.locals(r10=cython.double)
  39. @cython.locals(r11=cython.double)
  40. @cython.locals(r12=cython.double)
  41. @cython.locals(x0=cython.double, y0=cython.double)
  42. @cython.locals(x1=cython.double, y1=cython.double)
  43. def _lineTo(self, p1):
  44. x0, y0 = self._getCurrentPoint()
  45. x1, y1 = p1
  46. r0 = x1 * y0
  47. r1 = x1 * y1
  48. r2 = x1**2
  49. r3 = r2 * y1
  50. r4 = y0 - y1
  51. r5 = r4 * x0
  52. r6 = x0**2
  53. r7 = 2 * y0
  54. r8 = y0**2
  55. r9 = y1**2
  56. r10 = x1**3
  57. r11 = y0**3
  58. r12 = y1**3
  59. self.area += -r0 / 2 - r1 / 2 + x0 * (y0 + y1) / 2
  60. self.momentX += -r2 * y0 / 6 - r3 / 3 - r5 * x1 / 6 + r6 * (r7 + y1) / 6
  61. self.momentY += (
  62. -r0 * y1 / 6 - r8 * x1 / 6 - r9 * x1 / 6 + x0 * (r8 + r9 + y0 * y1) / 6
  63. )
  64. self.momentXX += (
  65. -r10 * y0 / 12
  66. - r10 * y1 / 4
  67. - r2 * r5 / 12
  68. - r4 * r6 * x1 / 12
  69. + x0**3 * (3 * y0 + y1) / 12
  70. )
  71. self.momentXY += (
  72. -r2 * r8 / 24
  73. - r2 * r9 / 8
  74. - r3 * r7 / 24
  75. + r6 * (r7 * y1 + 3 * r8 + r9) / 24
  76. - x0 * x1 * (r8 - r9) / 12
  77. )
  78. self.momentYY += (
  79. -r0 * r9 / 12
  80. - r1 * r8 / 12
  81. - r11 * x1 / 12
  82. - r12 * x1 / 12
  83. + x0 * (r11 + r12 + r8 * y1 + r9 * y0) / 12
  84. )
  85. @cython.locals(r0=cython.double)
  86. @cython.locals(r1=cython.double)
  87. @cython.locals(r2=cython.double)
  88. @cython.locals(r3=cython.double)
  89. @cython.locals(r4=cython.double)
  90. @cython.locals(r5=cython.double)
  91. @cython.locals(r6=cython.double)
  92. @cython.locals(r7=cython.double)
  93. @cython.locals(r8=cython.double)
  94. @cython.locals(r9=cython.double)
  95. @cython.locals(r10=cython.double)
  96. @cython.locals(r11=cython.double)
  97. @cython.locals(r12=cython.double)
  98. @cython.locals(r13=cython.double)
  99. @cython.locals(r14=cython.double)
  100. @cython.locals(r15=cython.double)
  101. @cython.locals(r16=cython.double)
  102. @cython.locals(r17=cython.double)
  103. @cython.locals(r18=cython.double)
  104. @cython.locals(r19=cython.double)
  105. @cython.locals(r20=cython.double)
  106. @cython.locals(r21=cython.double)
  107. @cython.locals(r22=cython.double)
  108. @cython.locals(r23=cython.double)
  109. @cython.locals(r24=cython.double)
  110. @cython.locals(r25=cython.double)
  111. @cython.locals(r26=cython.double)
  112. @cython.locals(r27=cython.double)
  113. @cython.locals(r28=cython.double)
  114. @cython.locals(r29=cython.double)
  115. @cython.locals(r30=cython.double)
  116. @cython.locals(r31=cython.double)
  117. @cython.locals(r32=cython.double)
  118. @cython.locals(r33=cython.double)
  119. @cython.locals(r34=cython.double)
  120. @cython.locals(r35=cython.double)
  121. @cython.locals(r36=cython.double)
  122. @cython.locals(r37=cython.double)
  123. @cython.locals(r38=cython.double)
  124. @cython.locals(r39=cython.double)
  125. @cython.locals(r40=cython.double)
  126. @cython.locals(r41=cython.double)
  127. @cython.locals(r42=cython.double)
  128. @cython.locals(r43=cython.double)
  129. @cython.locals(r44=cython.double)
  130. @cython.locals(r45=cython.double)
  131. @cython.locals(r46=cython.double)
  132. @cython.locals(r47=cython.double)
  133. @cython.locals(r48=cython.double)
  134. @cython.locals(r49=cython.double)
  135. @cython.locals(r50=cython.double)
  136. @cython.locals(r51=cython.double)
  137. @cython.locals(r52=cython.double)
  138. @cython.locals(r53=cython.double)
  139. @cython.locals(x0=cython.double, y0=cython.double)
  140. @cython.locals(x1=cython.double, y1=cython.double)
  141. @cython.locals(x2=cython.double, y2=cython.double)
  142. def _qCurveToOne(self, p1, p2):
  143. x0, y0 = self._getCurrentPoint()
  144. x1, y1 = p1
  145. x2, y2 = p2
  146. r0 = 2 * y1
  147. r1 = r0 * x2
  148. r2 = x2 * y2
  149. r3 = 3 * r2
  150. r4 = 2 * x1
  151. r5 = 3 * y0
  152. r6 = x1**2
  153. r7 = x2**2
  154. r8 = 4 * y1
  155. r9 = 10 * y2
  156. r10 = 2 * y2
  157. r11 = r4 * x2
  158. r12 = x0**2
  159. r13 = 10 * y0
  160. r14 = r4 * y2
  161. r15 = x2 * y0
  162. r16 = 4 * x1
  163. r17 = r0 * x1 + r2
  164. r18 = r2 * r8
  165. r19 = y1**2
  166. r20 = 2 * r19
  167. r21 = y2**2
  168. r22 = r21 * x2
  169. r23 = 5 * r22
  170. r24 = y0**2
  171. r25 = y0 * y2
  172. r26 = 5 * r24
  173. r27 = x1**3
  174. r28 = x2**3
  175. r29 = 30 * y1
  176. r30 = 6 * y1
  177. r31 = 10 * r7 * x1
  178. r32 = 5 * y2
  179. r33 = 12 * r6
  180. r34 = 30 * x1
  181. r35 = x1 * y1
  182. r36 = r3 + 20 * r35
  183. r37 = 12 * x1
  184. r38 = 20 * r6
  185. r39 = 8 * r6 * y1
  186. r40 = r32 * r7
  187. r41 = 60 * y1
  188. r42 = 20 * r19
  189. r43 = 4 * r19
  190. r44 = 15 * r21
  191. r45 = 12 * x2
  192. r46 = 12 * y2
  193. r47 = 6 * x1
  194. r48 = 8 * r19 * x1 + r23
  195. r49 = 8 * y1**3
  196. r50 = y2**3
  197. r51 = y0**3
  198. r52 = 10 * y1
  199. r53 = 12 * y1
  200. self.area += (
  201. -r1 / 6
  202. - r3 / 6
  203. + x0 * (r0 + r5 + y2) / 6
  204. + x1 * y2 / 3
  205. - y0 * (r4 + x2) / 6
  206. )
  207. self.momentX += (
  208. -r11 * (-r10 + y1) / 30
  209. + r12 * (r13 + r8 + y2) / 30
  210. + r6 * y2 / 15
  211. - r7 * r8 / 30
  212. - r7 * r9 / 30
  213. + x0 * (r14 - r15 - r16 * y0 + r17) / 30
  214. - y0 * (r11 + 2 * r6 + r7) / 30
  215. )
  216. self.momentY += (
  217. -r18 / 30
  218. - r20 * x2 / 30
  219. - r23 / 30
  220. - r24 * (r16 + x2) / 30
  221. + x0 * (r0 * y2 + r20 + r21 + r25 + r26 + r8 * y0) / 30
  222. + x1 * y2 * (r10 + y1) / 15
  223. - y0 * (r1 + r17) / 30
  224. )
  225. self.momentXX += (
  226. r12 * (r1 - 5 * r15 - r34 * y0 + r36 + r9 * x1) / 420
  227. + 2 * r27 * y2 / 105
  228. - r28 * r29 / 420
  229. - r28 * y2 / 4
  230. - r31 * (r0 - 3 * y2) / 420
  231. - r6 * x2 * (r0 - r32) / 105
  232. + x0**3 * (r30 + 21 * y0 + y2) / 84
  233. - x0
  234. * (
  235. r0 * r7
  236. + r15 * r37
  237. - r2 * r37
  238. - r33 * y2
  239. + r38 * y0
  240. - r39
  241. - r40
  242. + r5 * r7
  243. )
  244. / 420
  245. - y0 * (8 * r27 + 5 * r28 + r31 + r33 * x2) / 420
  246. )
  247. self.momentXY += (
  248. r12 * (r13 * y2 + 3 * r21 + 105 * r24 + r41 * y0 + r42 + r46 * y1) / 840
  249. - r16 * x2 * (r43 - r44) / 840
  250. - r21 * r7 / 8
  251. - r24 * (r38 + r45 * x1 + 3 * r7) / 840
  252. - r41 * r7 * y2 / 840
  253. - r42 * r7 / 840
  254. + r6 * y2 * (r32 + r8) / 210
  255. + x0
  256. * (
  257. -r15 * r8
  258. + r16 * r25
  259. + r18
  260. + r21 * r47
  261. - r24 * r34
  262. - r26 * x2
  263. + r35 * r46
  264. + r48
  265. )
  266. / 420
  267. - y0 * (r16 * r2 + r30 * r7 + r35 * r45 + r39 + r40) / 420
  268. )
  269. self.momentYY += (
  270. -r2 * r42 / 420
  271. - r22 * r29 / 420
  272. - r24 * (r14 + r36 + r52 * x2) / 420
  273. - r49 * x2 / 420
  274. - r50 * x2 / 12
  275. - r51 * (r47 + x2) / 84
  276. + x0
  277. * (
  278. r19 * r46
  279. + r21 * r5
  280. + r21 * r52
  281. + r24 * r29
  282. + r25 * r53
  283. + r26 * y2
  284. + r42 * y0
  285. + r49
  286. + 5 * r50
  287. + 35 * r51
  288. )
  289. / 420
  290. + x1 * y2 * (r43 + r44 + r9 * y1) / 210
  291. - y0 * (r19 * r45 + r2 * r53 - r21 * r4 + r48) / 420
  292. )
  293. @cython.locals(r0=cython.double)
  294. @cython.locals(r1=cython.double)
  295. @cython.locals(r2=cython.double)
  296. @cython.locals(r3=cython.double)
  297. @cython.locals(r4=cython.double)
  298. @cython.locals(r5=cython.double)
  299. @cython.locals(r6=cython.double)
  300. @cython.locals(r7=cython.double)
  301. @cython.locals(r8=cython.double)
  302. @cython.locals(r9=cython.double)
  303. @cython.locals(r10=cython.double)
  304. @cython.locals(r11=cython.double)
  305. @cython.locals(r12=cython.double)
  306. @cython.locals(r13=cython.double)
  307. @cython.locals(r14=cython.double)
  308. @cython.locals(r15=cython.double)
  309. @cython.locals(r16=cython.double)
  310. @cython.locals(r17=cython.double)
  311. @cython.locals(r18=cython.double)
  312. @cython.locals(r19=cython.double)
  313. @cython.locals(r20=cython.double)
  314. @cython.locals(r21=cython.double)
  315. @cython.locals(r22=cython.double)
  316. @cython.locals(r23=cython.double)
  317. @cython.locals(r24=cython.double)
  318. @cython.locals(r25=cython.double)
  319. @cython.locals(r26=cython.double)
  320. @cython.locals(r27=cython.double)
  321. @cython.locals(r28=cython.double)
  322. @cython.locals(r29=cython.double)
  323. @cython.locals(r30=cython.double)
  324. @cython.locals(r31=cython.double)
  325. @cython.locals(r32=cython.double)
  326. @cython.locals(r33=cython.double)
  327. @cython.locals(r34=cython.double)
  328. @cython.locals(r35=cython.double)
  329. @cython.locals(r36=cython.double)
  330. @cython.locals(r37=cython.double)
  331. @cython.locals(r38=cython.double)
  332. @cython.locals(r39=cython.double)
  333. @cython.locals(r40=cython.double)
  334. @cython.locals(r41=cython.double)
  335. @cython.locals(r42=cython.double)
  336. @cython.locals(r43=cython.double)
  337. @cython.locals(r44=cython.double)
  338. @cython.locals(r45=cython.double)
  339. @cython.locals(r46=cython.double)
  340. @cython.locals(r47=cython.double)
  341. @cython.locals(r48=cython.double)
  342. @cython.locals(r49=cython.double)
  343. @cython.locals(r50=cython.double)
  344. @cython.locals(r51=cython.double)
  345. @cython.locals(r52=cython.double)
  346. @cython.locals(r53=cython.double)
  347. @cython.locals(r54=cython.double)
  348. @cython.locals(r55=cython.double)
  349. @cython.locals(r56=cython.double)
  350. @cython.locals(r57=cython.double)
  351. @cython.locals(r58=cython.double)
  352. @cython.locals(r59=cython.double)
  353. @cython.locals(r60=cython.double)
  354. @cython.locals(r61=cython.double)
  355. @cython.locals(r62=cython.double)
  356. @cython.locals(r63=cython.double)
  357. @cython.locals(r64=cython.double)
  358. @cython.locals(r65=cython.double)
  359. @cython.locals(r66=cython.double)
  360. @cython.locals(r67=cython.double)
  361. @cython.locals(r68=cython.double)
  362. @cython.locals(r69=cython.double)
  363. @cython.locals(r70=cython.double)
  364. @cython.locals(r71=cython.double)
  365. @cython.locals(r72=cython.double)
  366. @cython.locals(r73=cython.double)
  367. @cython.locals(r74=cython.double)
  368. @cython.locals(r75=cython.double)
  369. @cython.locals(r76=cython.double)
  370. @cython.locals(r77=cython.double)
  371. @cython.locals(r78=cython.double)
  372. @cython.locals(r79=cython.double)
  373. @cython.locals(r80=cython.double)
  374. @cython.locals(r81=cython.double)
  375. @cython.locals(r82=cython.double)
  376. @cython.locals(r83=cython.double)
  377. @cython.locals(r84=cython.double)
  378. @cython.locals(r85=cython.double)
  379. @cython.locals(r86=cython.double)
  380. @cython.locals(r87=cython.double)
  381. @cython.locals(r88=cython.double)
  382. @cython.locals(r89=cython.double)
  383. @cython.locals(r90=cython.double)
  384. @cython.locals(r91=cython.double)
  385. @cython.locals(r92=cython.double)
  386. @cython.locals(r93=cython.double)
  387. @cython.locals(r94=cython.double)
  388. @cython.locals(r95=cython.double)
  389. @cython.locals(r96=cython.double)
  390. @cython.locals(r97=cython.double)
  391. @cython.locals(r98=cython.double)
  392. @cython.locals(r99=cython.double)
  393. @cython.locals(r100=cython.double)
  394. @cython.locals(r101=cython.double)
  395. @cython.locals(r102=cython.double)
  396. @cython.locals(r103=cython.double)
  397. @cython.locals(r104=cython.double)
  398. @cython.locals(r105=cython.double)
  399. @cython.locals(r106=cython.double)
  400. @cython.locals(r107=cython.double)
  401. @cython.locals(r108=cython.double)
  402. @cython.locals(r109=cython.double)
  403. @cython.locals(r110=cython.double)
  404. @cython.locals(r111=cython.double)
  405. @cython.locals(r112=cython.double)
  406. @cython.locals(r113=cython.double)
  407. @cython.locals(r114=cython.double)
  408. @cython.locals(r115=cython.double)
  409. @cython.locals(r116=cython.double)
  410. @cython.locals(r117=cython.double)
  411. @cython.locals(r118=cython.double)
  412. @cython.locals(r119=cython.double)
  413. @cython.locals(r120=cython.double)
  414. @cython.locals(r121=cython.double)
  415. @cython.locals(r122=cython.double)
  416. @cython.locals(r123=cython.double)
  417. @cython.locals(r124=cython.double)
  418. @cython.locals(r125=cython.double)
  419. @cython.locals(r126=cython.double)
  420. @cython.locals(r127=cython.double)
  421. @cython.locals(r128=cython.double)
  422. @cython.locals(r129=cython.double)
  423. @cython.locals(r130=cython.double)
  424. @cython.locals(r131=cython.double)
  425. @cython.locals(r132=cython.double)
  426. @cython.locals(x0=cython.double, y0=cython.double)
  427. @cython.locals(x1=cython.double, y1=cython.double)
  428. @cython.locals(x2=cython.double, y2=cython.double)
  429. @cython.locals(x3=cython.double, y3=cython.double)
  430. def _curveToOne(self, p1, p2, p3):
  431. x0, y0 = self._getCurrentPoint()
  432. x1, y1 = p1
  433. x2, y2 = p2
  434. x3, y3 = p3
  435. r0 = 6 * y2
  436. r1 = r0 * x3
  437. r2 = 10 * y3
  438. r3 = r2 * x3
  439. r4 = 3 * y1
  440. r5 = 6 * x1
  441. r6 = 3 * x2
  442. r7 = 6 * y1
  443. r8 = 3 * y2
  444. r9 = x2**2
  445. r10 = 45 * r9
  446. r11 = r10 * y3
  447. r12 = x3**2
  448. r13 = r12 * y2
  449. r14 = r12 * y3
  450. r15 = 7 * y3
  451. r16 = 15 * x3
  452. r17 = r16 * x2
  453. r18 = x1**2
  454. r19 = 9 * r18
  455. r20 = x0**2
  456. r21 = 21 * y1
  457. r22 = 9 * r9
  458. r23 = r7 * x3
  459. r24 = 9 * y2
  460. r25 = r24 * x2 + r3
  461. r26 = 9 * x2
  462. r27 = x2 * y3
  463. r28 = -r26 * y1 + 15 * r27
  464. r29 = 3 * x1
  465. r30 = 45 * x1
  466. r31 = 12 * x3
  467. r32 = 45 * r18
  468. r33 = 5 * r12
  469. r34 = r8 * x3
  470. r35 = 105 * y0
  471. r36 = 30 * y0
  472. r37 = r36 * x2
  473. r38 = 5 * x3
  474. r39 = 15 * y3
  475. r40 = 5 * y3
  476. r41 = r40 * x3
  477. r42 = x2 * y2
  478. r43 = 18 * r42
  479. r44 = 45 * y1
  480. r45 = r41 + r43 + r44 * x1
  481. r46 = y2 * y3
  482. r47 = r46 * x3
  483. r48 = y2**2
  484. r49 = 45 * r48
  485. r50 = r49 * x3
  486. r51 = y3**2
  487. r52 = r51 * x3
  488. r53 = y1**2
  489. r54 = 9 * r53
  490. r55 = y0**2
  491. r56 = 21 * x1
  492. r57 = 6 * x2
  493. r58 = r16 * y2
  494. r59 = r39 * y2
  495. r60 = 9 * r48
  496. r61 = r6 * y3
  497. r62 = 3 * y3
  498. r63 = r36 * y2
  499. r64 = y1 * y3
  500. r65 = 45 * r53
  501. r66 = 5 * r51
  502. r67 = x2**3
  503. r68 = x3**3
  504. r69 = 630 * y2
  505. r70 = 126 * x3
  506. r71 = x1**3
  507. r72 = 126 * x2
  508. r73 = 63 * r9
  509. r74 = r73 * x3
  510. r75 = r15 * x3 + 15 * r42
  511. r76 = 630 * x1
  512. r77 = 14 * x3
  513. r78 = 21 * r27
  514. r79 = 42 * x1
  515. r80 = 42 * x2
  516. r81 = x1 * y2
  517. r82 = 63 * r42
  518. r83 = x1 * y1
  519. r84 = r41 + r82 + 378 * r83
  520. r85 = x2 * x3
  521. r86 = r85 * y1
  522. r87 = r27 * x3
  523. r88 = 27 * r9
  524. r89 = r88 * y2
  525. r90 = 42 * r14
  526. r91 = 90 * x1
  527. r92 = 189 * r18
  528. r93 = 378 * r18
  529. r94 = r12 * y1
  530. r95 = 252 * x1 * x2
  531. r96 = r79 * x3
  532. r97 = 30 * r85
  533. r98 = r83 * x3
  534. r99 = 30 * x3
  535. r100 = 42 * x3
  536. r101 = r42 * x1
  537. r102 = r10 * y2 + 14 * r14 + 126 * r18 * y1 + r81 * r99
  538. r103 = 378 * r48
  539. r104 = 18 * y1
  540. r105 = r104 * y2
  541. r106 = y0 * y1
  542. r107 = 252 * y2
  543. r108 = r107 * y0
  544. r109 = y0 * y3
  545. r110 = 42 * r64
  546. r111 = 378 * r53
  547. r112 = 63 * r48
  548. r113 = 27 * x2
  549. r114 = r27 * y2
  550. r115 = r113 * r48 + 42 * r52
  551. r116 = x3 * y3
  552. r117 = 54 * r42
  553. r118 = r51 * x1
  554. r119 = r51 * x2
  555. r120 = r48 * x1
  556. r121 = 21 * x3
  557. r122 = r64 * x1
  558. r123 = r81 * y3
  559. r124 = 30 * r27 * y1 + r49 * x2 + 14 * r52 + 126 * r53 * x1
  560. r125 = y2**3
  561. r126 = y3**3
  562. r127 = y1**3
  563. r128 = y0**3
  564. r129 = r51 * y2
  565. r130 = r112 * y3 + r21 * r51
  566. r131 = 189 * r53
  567. r132 = 90 * y2
  568. self.area += (
  569. -r1 / 20
  570. - r3 / 20
  571. - r4 * (x2 + x3) / 20
  572. + x0 * (r7 + r8 + 10 * y0 + y3) / 20
  573. + 3 * x1 * (y2 + y3) / 20
  574. + 3 * x2 * y3 / 10
  575. - y0 * (r5 + r6 + x3) / 20
  576. )
  577. self.momentX += (
  578. r11 / 840
  579. - r13 / 8
  580. - r14 / 3
  581. - r17 * (-r15 + r8) / 840
  582. + r19 * (r8 + 2 * y3) / 840
  583. + r20 * (r0 + r21 + 56 * y0 + y3) / 168
  584. + r29 * (-r23 + r25 + r28) / 840
  585. - r4 * (10 * r12 + r17 + r22) / 840
  586. + x0
  587. * (
  588. 12 * r27
  589. + r30 * y2
  590. + r34
  591. - r35 * x1
  592. - r37
  593. - r38 * y0
  594. + r39 * x1
  595. - r4 * x3
  596. + r45
  597. )
  598. / 840
  599. - y0 * (r17 + r30 * x2 + r31 * x1 + r32 + r33 + 18 * r9) / 840
  600. )
  601. self.momentY += (
  602. -r4 * (r25 + r58) / 840
  603. - r47 / 8
  604. - r50 / 840
  605. - r52 / 6
  606. - r54 * (r6 + 2 * x3) / 840
  607. - r55 * (r56 + r57 + x3) / 168
  608. + x0
  609. * (
  610. r35 * y1
  611. + r40 * y0
  612. + r44 * y2
  613. + 18 * r48
  614. + 140 * r55
  615. + r59
  616. + r63
  617. + 12 * r64
  618. + r65
  619. + r66
  620. )
  621. / 840
  622. + x1 * (r24 * y1 + 10 * r51 + r59 + r60 + r7 * y3) / 280
  623. + x2 * y3 * (r15 + r8) / 56
  624. - y0 * (r16 * y1 + r31 * y2 + r44 * x2 + r45 + r61 - r62 * x1) / 840
  625. )
  626. self.momentXX += (
  627. -r12 * r72 * (-r40 + r8) / 9240
  628. + 3 * r18 * (r28 + r34 - r38 * y1 + r75) / 3080
  629. + r20
  630. * (
  631. r24 * x3
  632. - r72 * y0
  633. - r76 * y0
  634. - r77 * y0
  635. + r78
  636. + r79 * y3
  637. + r80 * y1
  638. + 210 * r81
  639. + r84
  640. )
  641. / 9240
  642. - r29
  643. * (
  644. r12 * r21
  645. + 14 * r13
  646. + r44 * r9
  647. - r73 * y3
  648. + 54 * r86
  649. - 84 * r87
  650. - r89
  651. - r90
  652. )
  653. / 9240
  654. - r4 * (70 * r12 * x2 + 27 * r67 + 42 * r68 + r74) / 9240
  655. + 3 * r67 * y3 / 220
  656. - r68 * r69 / 9240
  657. - r68 * y3 / 4
  658. - r70 * r9 * (-r62 + y2) / 9240
  659. + 3 * r71 * (r24 + r40) / 3080
  660. + x0**3 * (r24 + r44 + 165 * y0 + y3) / 660
  661. + x0
  662. * (
  663. r100 * r27
  664. + 162 * r101
  665. + r102
  666. + r11
  667. + 63 * r18 * y3
  668. + r27 * r91
  669. - r33 * y0
  670. - r37 * x3
  671. + r43 * x3
  672. - r73 * y0
  673. - r88 * y1
  674. + r92 * y2
  675. - r93 * y0
  676. - 9 * r94
  677. - r95 * y0
  678. - r96 * y0
  679. - r97 * y1
  680. - 18 * r98
  681. + r99 * x1 * y3
  682. )
  683. / 9240
  684. - y0
  685. * (
  686. r12 * r56
  687. + r12 * r80
  688. + r32 * x3
  689. + 45 * r67
  690. + 14 * r68
  691. + 126 * r71
  692. + r74
  693. + r85 * r91
  694. + 135 * r9 * x1
  695. + r92 * x2
  696. )
  697. / 9240
  698. )
  699. self.momentXY += (
  700. -r103 * r12 / 18480
  701. - r12 * r51 / 8
  702. - 3 * r14 * y2 / 44
  703. + 3 * r18 * (r105 + r2 * y1 + 18 * r46 + 15 * r48 + 7 * r51) / 6160
  704. + r20
  705. * (
  706. 1260 * r106
  707. + r107 * y1
  708. + r108
  709. + 28 * r109
  710. + r110
  711. + r111
  712. + r112
  713. + 30 * r46
  714. + 2310 * r55
  715. + r66
  716. )
  717. / 18480
  718. - r54 * (7 * r12 + 18 * r85 + 15 * r9) / 18480
  719. - r55 * (r33 + r73 + r93 + r95 + r96 + r97) / 18480
  720. - r7 * (42 * r13 + r82 * x3 + 28 * r87 + r89 + r90) / 18480
  721. - 3 * r85 * (r48 - r66) / 220
  722. + 3 * r9 * y3 * (r62 + 2 * y2) / 440
  723. + x0
  724. * (
  725. -r1 * y0
  726. - 84 * r106 * x2
  727. + r109 * r56
  728. + 54 * r114
  729. + r117 * y1
  730. + 15 * r118
  731. + 21 * r119
  732. + 81 * r120
  733. + r121 * r46
  734. + 54 * r122
  735. + 60 * r123
  736. + r124
  737. - r21 * x3 * y0
  738. + r23 * y3
  739. - r54 * x3
  740. - r55 * r72
  741. - r55 * r76
  742. - r55 * r77
  743. + r57 * y0 * y3
  744. + r60 * x3
  745. + 84 * r81 * y0
  746. + 189 * r81 * y1
  747. )
  748. / 9240
  749. + x1
  750. * (
  751. r104 * r27
  752. - r105 * x3
  753. - r113 * r53
  754. + 63 * r114
  755. + r115
  756. - r16 * r53
  757. + 28 * r47
  758. + r51 * r80
  759. )
  760. / 3080
  761. - y0
  762. * (
  763. 54 * r101
  764. + r102
  765. + r116 * r5
  766. + r117 * x3
  767. + 21 * r13
  768. - r19 * y3
  769. + r22 * y3
  770. + r78 * x3
  771. + 189 * r83 * x2
  772. + 60 * r86
  773. + 81 * r9 * y1
  774. + 15 * r94
  775. + 54 * r98
  776. )
  777. / 9240
  778. )
  779. self.momentYY += (
  780. -r103 * r116 / 9240
  781. - r125 * r70 / 9240
  782. - r126 * x3 / 12
  783. - 3 * r127 * (r26 + r38) / 3080
  784. - r128 * (r26 + r30 + x3) / 660
  785. - r4 * (r112 * x3 + r115 - 14 * r119 + 84 * r47) / 9240
  786. - r52 * r69 / 9240
  787. - r54 * (r58 + r61 + r75) / 9240
  788. - r55
  789. * (r100 * y1 + r121 * y2 + r26 * y3 + r79 * y2 + r84 + 210 * x2 * y1)
  790. / 9240
  791. + x0
  792. * (
  793. r108 * y1
  794. + r110 * y0
  795. + r111 * y0
  796. + r112 * y0
  797. + 45 * r125
  798. + 14 * r126
  799. + 126 * r127
  800. + 770 * r128
  801. + 42 * r129
  802. + r130
  803. + r131 * y2
  804. + r132 * r64
  805. + 135 * r48 * y1
  806. + 630 * r55 * y1
  807. + 126 * r55 * y2
  808. + 14 * r55 * y3
  809. + r63 * y3
  810. + r65 * y3
  811. + r66 * y0
  812. )
  813. / 9240
  814. + x1
  815. * (
  816. 27 * r125
  817. + 42 * r126
  818. + 70 * r129
  819. + r130
  820. + r39 * r53
  821. + r44 * r48
  822. + 27 * r53 * y2
  823. + 54 * r64 * y2
  824. )
  825. / 3080
  826. + 3 * x2 * y3 * (r48 + r66 + r8 * y3) / 220
  827. - y0
  828. * (
  829. r100 * r46
  830. + 18 * r114
  831. - 9 * r118
  832. - 27 * r120
  833. - 18 * r122
  834. - 30 * r123
  835. + r124
  836. + r131 * x2
  837. + r132 * x3 * y1
  838. + 162 * r42 * y1
  839. + r50
  840. + 63 * r53 * x3
  841. + r64 * r99
  842. )
  843. / 9240
  844. )
  845. if __name__ == "__main__":
  846. from fontTools.misc.symfont import x, y, printGreenPen
  847. printGreenPen(
  848. "MomentsPen",
  849. [
  850. ("area", 1),
  851. ("momentX", x),
  852. ("momentY", y),
  853. ("momentXX", x**2),
  854. ("momentXY", x * y),
  855. ("momentYY", y**2),
  856. ],
  857. )