momentsPen.py 25 KB

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