mathematical 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (261) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -4
  3. data/.gitmodules +0 -4
  4. data/README.md +108 -28
  5. data/Rakefile +3 -31
  6. data/ext/mathematical/README.itex2MML.md +11 -0
  7. data/ext/mathematical/README.lasem.md +11 -0
  8. data/ext/mathematical/extconf.rb +51 -0
  9. data/ext/mathematical/itex2MML.h +63 -0
  10. data/ext/mathematical/lasemrender.c +257 -0
  11. data/ext/mathematical/lex.yy.c +6548 -0
  12. data/ext/mathematical/lsm.c +30 -0
  13. data/ext/mathematical/lsm.h +36 -0
  14. data/ext/mathematical/lsmattributes.c +279 -0
  15. data/ext/mathematical/lsmattributes.h +75 -0
  16. data/ext/mathematical/lsmcairo.c +598 -0
  17. data/ext/mathematical/lsmcairo.h +51 -0
  18. data/ext/mathematical/lsmdebug.c +179 -0
  19. data/ext/mathematical/lsmdebug.h +76 -0
  20. data/ext/mathematical/lsmdom.h +43 -0
  21. data/ext/mathematical/lsmdomcharacterdata.c +114 -0
  22. data/ext/mathematical/lsmdomcharacterdata.h +59 -0
  23. data/ext/mathematical/lsmdomdocument.c +292 -0
  24. data/ext/mathematical/lsmdomdocument.h +82 -0
  25. data/ext/mathematical/lsmdomdocumentfragment.c +81 -0
  26. data/ext/mathematical/lsmdomdocumentfragment.h +55 -0
  27. data/ext/mathematical/lsmdomelement.c +148 -0
  28. data/ext/mathematical/lsmdomelement.h +62 -0
  29. data/ext/mathematical/lsmdomentities.c +2155 -0
  30. data/ext/mathematical/lsmdomentities.h +35 -0
  31. data/ext/mathematical/lsmdomenumtypes.c +99 -0
  32. data/ext/mathematical/lsmdomenumtypes.c.template +39 -0
  33. data/ext/mathematical/lsmdomenumtypes.h +26 -0
  34. data/ext/mathematical/lsmdomenumtypes.h.template +26 -0
  35. data/ext/mathematical/lsmdomimplementation.c +82 -0
  36. data/ext/mathematical/lsmdomimplementation.h +41 -0
  37. data/ext/mathematical/lsmdomnamednodemap.c +118 -0
  38. data/ext/mathematical/lsmdomnamednodemap.h +64 -0
  39. data/ext/mathematical/lsmdomnode.c +725 -0
  40. data/ext/mathematical/lsmdomnode.h +120 -0
  41. data/ext/mathematical/lsmdomnodelist.c +70 -0
  42. data/ext/mathematical/lsmdomnodelist.h +58 -0
  43. data/ext/mathematical/lsmdomparser.c +461 -0
  44. data/ext/mathematical/lsmdomparser.h +54 -0
  45. data/ext/mathematical/lsmdomtext.c +82 -0
  46. data/ext/mathematical/lsmdomtext.h +55 -0
  47. data/ext/mathematical/lsmdomtypes.h +44 -0
  48. data/ext/mathematical/lsmdomview.c +422 -0
  49. data/ext/mathematical/lsmdomview.h +94 -0
  50. data/ext/mathematical/lsmmathml.h +66 -0
  51. data/ext/mathematical/lsmmathmlactionelement.c +93 -0
  52. data/ext/mathematical/lsmmathmlactionelement.h +57 -0
  53. data/ext/mathematical/lsmmathmlaligngroupelement.c +102 -0
  54. data/ext/mathematical/lsmmathmlaligngroupelement.h +56 -0
  55. data/ext/mathematical/lsmmathmlalignmarkelement.c +102 -0
  56. data/ext/mathematical/lsmmathmlalignmarkelement.h +56 -0
  57. data/ext/mathematical/lsmmathmlattributes.c +197 -0
  58. data/ext/mathematical/lsmmathmlattributes.h +126 -0
  59. data/ext/mathematical/lsmmathmldocument.c +306 -0
  60. data/ext/mathematical/lsmmathmldocument.h +61 -0
  61. data/ext/mathematical/lsmmathmlelement.c +491 -0
  62. data/ext/mathematical/lsmmathmlelement.h +107 -0
  63. data/ext/mathematical/lsmmathmlenums.c +429 -0
  64. data/ext/mathematical/lsmmathmlenums.h +182 -0
  65. data/ext/mathematical/lsmmathmlenumtypes.c +666 -0
  66. data/ext/mathematical/lsmmathmlenumtypes.c.template +39 -0
  67. data/ext/mathematical/lsmmathmlenumtypes.h +90 -0
  68. data/ext/mathematical/lsmmathmlenumtypes.h.template +26 -0
  69. data/ext/mathematical/lsmmathmlerrorelement.c +58 -0
  70. data/ext/mathematical/lsmmathmlerrorelement.h +56 -0
  71. data/ext/mathematical/lsmmathmlfencedelement.c +178 -0
  72. data/ext/mathematical/lsmmathmlfencedelement.h +65 -0
  73. data/ext/mathematical/lsmmathmlfractionelement.c +253 -0
  74. data/ext/mathematical/lsmmathmlfractionelement.h +62 -0
  75. data/ext/mathematical/lsmmathmlglyphtableams.c +597 -0
  76. data/ext/mathematical/lsmmathmlglyphtableams.h +45 -0
  77. data/ext/mathematical/lsmmathmlitexelement.c +187 -0
  78. data/ext/mathematical/lsmmathmlitexelement.h +60 -0
  79. data/ext/mathematical/lsmmathmllayoututils.c +191 -0
  80. data/ext/mathematical/lsmmathmllayoututils.h +58 -0
  81. data/ext/mathematical/lsmmathmlmathelement.c +204 -0
  82. data/ext/mathematical/lsmmathmlmathelement.h +81 -0
  83. data/ext/mathematical/lsmmathmloperatordictionary.c +3332 -0
  84. data/ext/mathematical/lsmmathmloperatordictionary.h +54 -0
  85. data/ext/mathematical/lsmmathmloperatorelement.c +307 -0
  86. data/ext/mathematical/lsmmathmloperatorelement.h +73 -0
  87. data/ext/mathematical/lsmmathmlpaddedelement.c +58 -0
  88. data/ext/mathematical/lsmmathmlpaddedelement.h +56 -0
  89. data/ext/mathematical/lsmmathmlphantomelement.c +71 -0
  90. data/ext/mathematical/lsmmathmlphantomelement.h +56 -0
  91. data/ext/mathematical/lsmmathmlpresentationcontainer.c +43 -0
  92. data/ext/mathematical/lsmmathmlpresentationcontainer.h +54 -0
  93. data/ext/mathematical/lsmmathmlpresentationtoken.c +303 -0
  94. data/ext/mathematical/lsmmathmlpresentationtoken.h +83 -0
  95. data/ext/mathematical/lsmmathmlradicalelement.c +266 -0
  96. data/ext/mathematical/lsmmathmlradicalelement.h +71 -0
  97. data/ext/mathematical/lsmmathmlrowelement.c +58 -0
  98. data/ext/mathematical/lsmmathmlrowelement.h +56 -0
  99. data/ext/mathematical/lsmmathmlscriptelement.c +282 -0
  100. data/ext/mathematical/lsmmathmlscriptelement.h +78 -0
  101. data/ext/mathematical/lsmmathmlsemanticselement.c +82 -0
  102. data/ext/mathematical/lsmmathmlsemanticselement.h +56 -0
  103. data/ext/mathematical/lsmmathmlspaceelement.c +142 -0
  104. data/ext/mathematical/lsmmathmlspaceelement.h +60 -0
  105. data/ext/mathematical/lsmmathmlstringelement.c +123 -0
  106. data/ext/mathematical/lsmmathmlstringelement.h +58 -0
  107. data/ext/mathematical/lsmmathmlstyle.c +130 -0
  108. data/ext/mathematical/lsmmathmlstyle.h +81 -0
  109. data/ext/mathematical/lsmmathmlstyleelement.c +307 -0
  110. data/ext/mathematical/lsmmathmlstyleelement.h +87 -0
  111. data/ext/mathematical/lsmmathmltablecellelement.c +122 -0
  112. data/ext/mathematical/lsmmathmltablecellelement.h +62 -0
  113. data/ext/mathematical/lsmmathmltableelement.c +545 -0
  114. data/ext/mathematical/lsmmathmltableelement.h +78 -0
  115. data/ext/mathematical/lsmmathmltablerowelement.c +120 -0
  116. data/ext/mathematical/lsmmathmltablerowelement.h +64 -0
  117. data/ext/mathematical/lsmmathmltraits.c +819 -0
  118. data/ext/mathematical/lsmmathmltraits.h +119 -0
  119. data/ext/mathematical/lsmmathmltypes.h +66 -0
  120. data/ext/mathematical/lsmmathmlunderoverelement.c +485 -0
  121. data/ext/mathematical/lsmmathmlunderoverelement.h +82 -0
  122. data/ext/mathematical/lsmmathmlutils.c +170 -0
  123. data/ext/mathematical/lsmmathmlutils.h +50 -0
  124. data/ext/mathematical/lsmmathmlview.c +1048 -0
  125. data/ext/mathematical/lsmmathmlview.h +164 -0
  126. data/ext/mathematical/lsmproperties.c +418 -0
  127. data/ext/mathematical/lsmproperties.h +85 -0
  128. data/ext/mathematical/lsmstr.c +231 -0
  129. data/ext/mathematical/lsmstr.h +114 -0
  130. data/ext/mathematical/lsmsvg.h +67 -0
  131. data/ext/mathematical/lsmsvgaelement.c +73 -0
  132. data/ext/mathematical/lsmsvgaelement.h +55 -0
  133. data/ext/mathematical/lsmsvgattributes.h +113 -0
  134. data/ext/mathematical/lsmsvgcircleelement.c +153 -0
  135. data/ext/mathematical/lsmsvgcircleelement.h +59 -0
  136. data/ext/mathematical/lsmsvgclippathelement.c +134 -0
  137. data/ext/mathematical/lsmsvgclippathelement.h +59 -0
  138. data/ext/mathematical/lsmsvgcolors.c +212 -0
  139. data/ext/mathematical/lsmsvgcolors.h +39 -0
  140. data/ext/mathematical/lsmsvgdefselement.c +74 -0
  141. data/ext/mathematical/lsmsvgdefselement.h +55 -0
  142. data/ext/mathematical/lsmsvgdocument.c +230 -0
  143. data/ext/mathematical/lsmsvgdocument.h +58 -0
  144. data/ext/mathematical/lsmsvgelement.c +367 -0
  145. data/ext/mathematical/lsmsvgelement.h +81 -0
  146. data/ext/mathematical/lsmsvgellipseelement.c +158 -0
  147. data/ext/mathematical/lsmsvgellipseelement.h +60 -0
  148. data/ext/mathematical/lsmsvgenums.c +544 -0
  149. data/ext/mathematical/lsmsvgenums.h +357 -0
  150. data/ext/mathematical/lsmsvgenumtypes.c +1083 -0
  151. data/ext/mathematical/lsmsvgenumtypes.c.template +39 -0
  152. data/ext/mathematical/lsmsvgenumtypes.h +111 -0
  153. data/ext/mathematical/lsmsvgenumtypes.h.template +26 -0
  154. data/ext/mathematical/lsmsvgfilterblend.c +105 -0
  155. data/ext/mathematical/lsmsvgfilterblend.h +58 -0
  156. data/ext/mathematical/lsmsvgfiltercomposite.c +109 -0
  157. data/ext/mathematical/lsmsvgfiltercomposite.h +58 -0
  158. data/ext/mathematical/lsmsvgfilterelement.c +266 -0
  159. data/ext/mathematical/lsmsvgfilterelement.h +66 -0
  160. data/ext/mathematical/lsmsvgfilterflood.c +86 -0
  161. data/ext/mathematical/lsmsvgfilterflood.h +55 -0
  162. data/ext/mathematical/lsmsvgfiltergaussianblur.c +114 -0
  163. data/ext/mathematical/lsmsvgfiltergaussianblur.h +57 -0
  164. data/ext/mathematical/lsmsvgfiltermerge.c +98 -0
  165. data/ext/mathematical/lsmsvgfiltermerge.h +55 -0
  166. data/ext/mathematical/lsmsvgfiltermergenode.c +87 -0
  167. data/ext/mathematical/lsmsvgfiltermergenode.h +57 -0
  168. data/ext/mathematical/lsmsvgfilteroffset.c +112 -0
  169. data/ext/mathematical/lsmsvgfilteroffset.h +58 -0
  170. data/ext/mathematical/lsmsvgfilterprimitive.c +168 -0
  171. data/ext/mathematical/lsmsvgfilterprimitive.h +66 -0
  172. data/ext/mathematical/lsmsvgfilterspecularlighting.c +127 -0
  173. data/ext/mathematical/lsmsvgfilterspecularlighting.h +60 -0
  174. data/ext/mathematical/lsmsvgfiltersurface.c +455 -0
  175. data/ext/mathematical/lsmsvgfiltersurface.h +66 -0
  176. data/ext/mathematical/lsmsvgfiltertile.c +102 -0
  177. data/ext/mathematical/lsmsvgfiltertile.h +57 -0
  178. data/ext/mathematical/lsmsvggelement.c +73 -0
  179. data/ext/mathematical/lsmsvggelement.h +55 -0
  180. data/ext/mathematical/lsmsvggradientelement.c +151 -0
  181. data/ext/mathematical/lsmsvggradientelement.h +68 -0
  182. data/ext/mathematical/lsmsvgimageelement.c +261 -0
  183. data/ext/mathematical/lsmsvgimageelement.h +67 -0
  184. data/ext/mathematical/lsmsvglength.c +93 -0
  185. data/ext/mathematical/lsmsvglength.h +59 -0
  186. data/ext/mathematical/lsmsvglineargradientelement.c +271 -0
  187. data/ext/mathematical/lsmsvglineargradientelement.h +60 -0
  188. data/ext/mathematical/lsmsvglineelement.c +153 -0
  189. data/ext/mathematical/lsmsvglineelement.h +60 -0
  190. data/ext/mathematical/lsmsvgmarkerelement.c +266 -0
  191. data/ext/mathematical/lsmsvgmarkerelement.h +74 -0
  192. data/ext/mathematical/lsmsvgmaskelement.c +232 -0
  193. data/ext/mathematical/lsmsvgmaskelement.h +64 -0
  194. data/ext/mathematical/lsmsvgmatrix.c +205 -0
  195. data/ext/mathematical/lsmsvgmatrix.h +59 -0
  196. data/ext/mathematical/lsmsvgpathelement.c +115 -0
  197. data/ext/mathematical/lsmsvgpathelement.h +59 -0
  198. data/ext/mathematical/lsmsvgpatternelement.c +398 -0
  199. data/ext/mathematical/lsmsvgpatternelement.h +69 -0
  200. data/ext/mathematical/lsmsvgpolygonelement.c +106 -0
  201. data/ext/mathematical/lsmsvgpolygonelement.h +57 -0
  202. data/ext/mathematical/lsmsvgpolylineelement.c +106 -0
  203. data/ext/mathematical/lsmsvgpolylineelement.h +57 -0
  204. data/ext/mathematical/lsmsvgradialgradientelement.c +323 -0
  205. data/ext/mathematical/lsmsvgradialgradientelement.h +61 -0
  206. data/ext/mathematical/lsmsvgrectelement.c +184 -0
  207. data/ext/mathematical/lsmsvgrectelement.h +62 -0
  208. data/ext/mathematical/lsmsvgstopelement.c +106 -0
  209. data/ext/mathematical/lsmsvgstopelement.h +57 -0
  210. data/ext/mathematical/lsmsvgstyle.c +558 -0
  211. data/ext/mathematical/lsmsvgstyle.h +217 -0
  212. data/ext/mathematical/lsmsvgsvgelement.c +260 -0
  213. data/ext/mathematical/lsmsvgsvgelement.h +71 -0
  214. data/ext/mathematical/lsmsvgswitchelement.c +103 -0
  215. data/ext/mathematical/lsmsvgswitchelement.h +55 -0
  216. data/ext/mathematical/lsmsvgsymbolelement.c +74 -0
  217. data/ext/mathematical/lsmsvgsymbolelement.h +55 -0
  218. data/ext/mathematical/lsmsvgtextelement.c +170 -0
  219. data/ext/mathematical/lsmsvgtextelement.h +58 -0
  220. data/ext/mathematical/lsmsvgtraits.c +1158 -0
  221. data/ext/mathematical/lsmsvgtraits.h +103 -0
  222. data/ext/mathematical/lsmsvgtransformable.c +106 -0
  223. data/ext/mathematical/lsmsvgtransformable.h +54 -0
  224. data/ext/mathematical/lsmsvgtspanelement.c +143 -0
  225. data/ext/mathematical/lsmsvgtspanelement.h +58 -0
  226. data/ext/mathematical/lsmsvgtypes.h +77 -0
  227. data/ext/mathematical/lsmsvguseelement.c +237 -0
  228. data/ext/mathematical/lsmsvguseelement.h +69 -0
  229. data/ext/mathematical/lsmsvgview.c +2400 -0
  230. data/ext/mathematical/lsmsvgview.h +168 -0
  231. data/ext/mathematical/lsmtraits.c +119 -0
  232. data/ext/mathematical/lsmtraits.h +49 -0
  233. data/ext/mathematical/lsmtypes.h +36 -0
  234. data/ext/mathematical/lsmutils.c +54 -0
  235. data/ext/mathematical/lsmutils.h +56 -0
  236. data/ext/mathematical/mathematical.c +122 -0
  237. data/ext/mathematical/y.tab.c +6179 -0
  238. data/ext/mathematical/y.tab.h +389 -0
  239. data/lib/mathematical.rb +7 -3
  240. data/lib/mathematical/parser.rb +1 -1
  241. data/lib/mathematical/render.rb +51 -77
  242. data/lib/mathematical/version.rb +1 -1
  243. data/mathematical.gemspec +5 -3
  244. data/script/bench +21 -0
  245. data/script/single_test +7 -0
  246. data/test/mathematical/basic_test.rb +30 -1
  247. data/test/mathematical/fixtures/after/brackets_display.html +1 -0
  248. data/test/mathematical/fixtures/after/dollar_sign_inline.html +1 -0
  249. data/test/mathematical/fixtures/after/equation_display.html +1 -0
  250. data/test/mathematical/fixtures/after/multiple_dollar_inline.html +1 -0
  251. data/test/mathematical/fixtures/after/parens_inline.html +1 -0
  252. data/test/mathematical/fixtures/before/brackets_display.text +1 -0
  253. data/test/mathematical/fixtures/before/{basic.text → dollar_sign_inline.text} +0 -0
  254. data/test/mathematical/fixtures/before/equation_display.text +1 -0
  255. data/test/mathematical/fixtures/before/multiple_dollar_inline.text +1 -0
  256. data/test/mathematical/fixtures/before/parens_inline.text +1 -0
  257. data/test/mathematical/fixtures/performance/big_file.text +1767 -0
  258. data/test/mathematical/performance_test.rb +13 -0
  259. data/test/test_helper.rb +1 -0
  260. metadata +303 -18
  261. data/test/mathematical/fixtures/after/basic.html +0 -1
@@ -0,0 +1,82 @@
1
+ /* Lasem
2
+ *
3
+ * Copyright © 2007-2008 Emmanuel Pacaud
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General
16
+ * Public License along with this library; if not, write to the
17
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
+ * Boston, MA 02111-1307, USA.
19
+ *
20
+ * Author:
21
+ * Emmanuel Pacaud <emmanuel@gnome.org>
22
+ */
23
+
24
+ #ifndef LSM_MATHML_UNDER_OVER_ELEMENT_H
25
+ #define LSM_MATHML_UNDER_OVER_ELEMENT_H
26
+
27
+ #include <lsmmathmltypes.h>
28
+ #include <lsmmathmlelement.h>
29
+
30
+ G_BEGIN_DECLS
31
+
32
+ typedef enum {
33
+ LSM_MATHML_UNDER_OVER_ELEMENT_TYPE_UNDER,
34
+ LSM_MATHML_UNDER_OVER_ELEMENT_TYPE_OVER,
35
+ LSM_MATHML_UNDER_OVER_ELEMENT_TYPE_UNDER_OVER
36
+ } LsmMathmlUnderOverElementType;
37
+
38
+ #define LSM_TYPE_MATHML_UNDER_OVER_ELEMENT (lsm_mathml_under_over_element_get_type ())
39
+ #define LSM_MATHML_UNDER_OVER_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_MATHML_UNDER_OVER_ELEMENT, LsmMathmlUnderOverElement))
40
+ #define LSM_MATHML_UNDER_OVER_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_MATHML_UNDER_OVER_ELEMENT, LsmMathmlUnderOverElementClass))
41
+ #define LSM_IS_MATHML_UNDER_OVER_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_MATHML_UNDER_OVER_ELEMENT))
42
+ #define LSM_IS_MATHML_UNDER_OVER_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_MATHML_UNDER_OVER_ELEMENT))
43
+ #define LSM_MATHML_UNDER_OVER_ELEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_MATHML_UNDER_OVER_ELEMENT, LsmMathmlUnderOverElementClass))
44
+
45
+ typedef struct _LsmMathmlUnderOverElementClass LsmMathmlUnderOverElementClass;
46
+
47
+ struct _LsmMathmlUnderOverElement {
48
+ LsmMathmlElement element;
49
+
50
+ LsmMathmlBooleanAttribute accent;
51
+ LsmMathmlBooleanAttribute accent_under;
52
+
53
+ LsmMathmlUnderOverElementType type;
54
+
55
+ LsmMathmlElement *base;
56
+ LsmMathmlElement *underscript;
57
+ LsmMathmlElement *overscript;
58
+
59
+ LsmMathmlDisplay display;
60
+
61
+ double under_space;
62
+ double over_space;
63
+
64
+ gboolean as_script;
65
+ double underscript_offset;
66
+ double overscript_offset;
67
+ };
68
+
69
+ struct _LsmMathmlUnderOverElementClass {
70
+ LsmMathmlElementClass parent_class;
71
+ };
72
+
73
+ GType lsm_mathml_under_over_element_get_type (void);
74
+
75
+ LsmDomNode * lsm_mathml_under_element_new (void);
76
+ LsmDomNode * lsm_mathml_over_element_new (void);
77
+ LsmDomNode * lsm_mathml_under_over_element_new (void);
78
+
79
+ G_END_DECLS
80
+
81
+ #endif
82
+
@@ -0,0 +1,170 @@
1
+ /* Lasem
2
+ *
3
+ * Copyright © 2007-2008 Emmanuel Pacaud
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General
16
+ * Public License along with this library; if not, write to the
17
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
+ * Boston, MA 02111-1307, USA.
19
+ *
20
+ * Author:
21
+ * Emmanuel Pacaud <emmanuel@gnome.org>
22
+ */
23
+
24
+ #include <lsmmathmlutils.h>
25
+
26
+ const LsmMathmlBbox lsm_mathml_bbox_null = {0.0, 0.0, 0.0, FALSE};
27
+
28
+ void
29
+ lsm_mathml_bbox_add_horizontally (LsmMathmlBbox *self, const LsmMathmlBbox *bbox)
30
+ {
31
+ g_return_if_fail (self != NULL);
32
+ g_return_if_fail (bbox != NULL);
33
+
34
+ if (!bbox->is_defined)
35
+ return;
36
+
37
+ if (!self->is_defined) {
38
+ *self = *bbox;
39
+ return;
40
+ }
41
+
42
+ self->width += bbox->width;
43
+ if (bbox->height > self->height)
44
+ self->height = bbox->height;
45
+ if (bbox->depth > self->depth)
46
+ self->depth = bbox->depth;
47
+ }
48
+
49
+ void
50
+ lsm_mathml_bbox_add_over (LsmMathmlBbox *self, const LsmMathmlBbox *bbox)
51
+ {
52
+ g_return_if_fail (self != NULL);
53
+ g_return_if_fail (bbox != NULL);
54
+
55
+ if (!bbox->is_defined)
56
+ return;
57
+
58
+ if (!self->is_defined) {
59
+ *self = *bbox;
60
+ return;
61
+ }
62
+
63
+ self->height += bbox->height + bbox->depth;
64
+ self->width = MAX (self->width, bbox->width);
65
+ }
66
+
67
+ void
68
+ lsm_mathml_bbox_add_under (LsmMathmlBbox *self, const LsmMathmlBbox *bbox)
69
+ {
70
+ g_return_if_fail (self != NULL);
71
+ g_return_if_fail (bbox != NULL);
72
+
73
+ if (!bbox->is_defined)
74
+ return;
75
+
76
+ if (!self->is_defined) {
77
+ *self = *bbox;
78
+ return;
79
+ }
80
+
81
+ self->depth += bbox->height + bbox->depth;
82
+ self->width = MAX (self->width, bbox->width);
83
+ }
84
+
85
+ void
86
+ lsm_mathml_bbox_merge_vertically (LsmMathmlBbox *self, const LsmMathmlBbox *bbox, double offset)
87
+ {
88
+ g_return_if_fail (self != NULL);
89
+ g_return_if_fail (bbox != NULL);
90
+
91
+ if (!bbox->is_defined)
92
+ return;
93
+
94
+ if (!self->is_defined) {
95
+ *self = *bbox;
96
+ self->height += offset;
97
+ self->depth -= offset;
98
+ return;
99
+ }
100
+
101
+ if (bbox->height + offset > self->height)
102
+ self->height = bbox->height + offset;
103
+ if (bbox->depth - offset > self->depth)
104
+ self->depth = bbox->depth - offset;
105
+ self->width = MAX (self->width, bbox->width);
106
+ }
107
+
108
+ void
109
+ lsm_mathml_bbox_stretch (LsmMathmlBbox *self, const LsmMathmlBbox *bbox)
110
+ {
111
+ g_return_if_fail (self != NULL);
112
+ g_return_if_fail (bbox != NULL);
113
+
114
+ if (!bbox->is_defined)
115
+ return;
116
+
117
+ if (!self->is_defined) {
118
+ *self = *bbox;
119
+ return;
120
+ }
121
+
122
+ if (bbox->height > self->height)
123
+ self->height = bbox->height;
124
+ if (bbox->depth > self->depth)
125
+ self->depth = bbox->depth;
126
+ if (bbox->width > self->width)
127
+ self->width = bbox->width;
128
+ }
129
+
130
+ void
131
+ lsm_mathml_bbox_stretch_vertically (LsmMathmlBbox *self, const LsmMathmlBbox *bbox)
132
+ {
133
+ g_return_if_fail (self != NULL);
134
+ g_return_if_fail (bbox != NULL);
135
+
136
+ if (!bbox->is_defined)
137
+ return;
138
+
139
+ if (!self->is_defined) {
140
+ *self = *bbox;
141
+ self->width = -1.0;
142
+ return;
143
+ }
144
+
145
+ if (bbox->height > self->height)
146
+ self->height = bbox->height;
147
+ if (bbox->depth > self->depth)
148
+ self->depth = bbox->depth;
149
+ }
150
+
151
+ void
152
+ lsm_mathml_bbox_stretch_horizontally (LsmMathmlBbox *self, const LsmMathmlBbox *bbox)
153
+ {
154
+ g_return_if_fail (self != NULL);
155
+ g_return_if_fail (bbox != NULL);
156
+
157
+ if (!bbox->is_defined)
158
+ return;
159
+
160
+ if (!self->is_defined) {
161
+ self->width = bbox->width;
162
+ self->height = -1.0;
163
+ self->depth = -1.0;
164
+ self->is_defined = TRUE;
165
+ return;
166
+ }
167
+
168
+ if (bbox->width > self->width)
169
+ self->width = bbox->width;
170
+ }
@@ -0,0 +1,50 @@
1
+ /* Lasem
2
+ *
3
+ * Copyright © 2007-2008 Emmanuel Pacaud
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General
16
+ * Public License along with this library; if not, write to the
17
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
+ * Boston, MA 02111-1307, USA.
19
+ *
20
+ * Author:
21
+ * Emmanuel Pacaud <emmanuel@gnome.org>
22
+ */
23
+
24
+ #ifndef LSM_MATHML_UTILS_H
25
+ #define LSM_MATHML_UTILS_H
26
+
27
+ #include <lsmmathmltypes.h>
28
+
29
+ G_BEGIN_DECLS
30
+
31
+ typedef struct {
32
+ double width;
33
+ double height;
34
+ double depth;
35
+ gboolean is_defined;
36
+ } LsmMathmlBbox;
37
+
38
+ extern const LsmMathmlBbox lsm_mathml_bbox_null;
39
+
40
+ void lsm_mathml_bbox_add_horizontally (LsmMathmlBbox *bbox, const LsmMathmlBbox *new_bbox);
41
+ void lsm_mathml_bbox_add_over (LsmMathmlBbox *self, const LsmMathmlBbox *bbox);
42
+ void lsm_mathml_bbox_add_under (LsmMathmlBbox *self, const LsmMathmlBbox *bbox);
43
+ void lsm_mathml_bbox_merge_vertically (LsmMathmlBbox *self, const LsmMathmlBbox *bbox, double offset);
44
+ void lsm_mathml_bbox_stretch (LsmMathmlBbox *self, const LsmMathmlBbox *bbox);
45
+ void lsm_mathml_bbox_stretch_vertically (LsmMathmlBbox *self, const LsmMathmlBbox *bbox);
46
+ void lsm_mathml_bbox_stretch_horizontally (LsmMathmlBbox *self, const LsmMathmlBbox *bbox);
47
+
48
+ G_END_DECLS
49
+
50
+ #endif
@@ -0,0 +1,1048 @@
1
+ /* Lasem
2
+ *
3
+ * Copyright © 2007-2012 Emmanuel Pacaud
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General
16
+ * Public License along with this library; if not, write to the
17
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
+ * Boston, MA 02111-1307, USA.
19
+ *
20
+ * Author:
21
+ * Emmanuel Pacaud <emmanuel@gnome.org>
22
+ */
23
+
24
+ #include <lsmdebug.h>
25
+ #include <lsmmathmlview.h>
26
+ #include <lsmmathmldocument.h>
27
+ #include <lsmmathmlelement.h>
28
+ #include <lsmmathmlmathelement.h>
29
+ #include <lsmmathmlstyleelement.h>
30
+ #include <lsmmathmlglyphtableams.h>
31
+ #include <glib/gprintf.h>
32
+
33
+ #include <math.h>
34
+ #include <string.h>
35
+
36
+ #define LSM_MATHML_LARGE_OP_SCALE 1.6
37
+
38
+ static const char *lsm_mathml_font_names[] = {
39
+ "",
40
+ "Sans",
41
+ "cmr10",
42
+ "cmmi10",
43
+ "cmex10",
44
+ "cmsy10",
45
+ "symbol"
46
+ };
47
+
48
+ static const struct {
49
+ const char *font;
50
+ PangoStyle style;
51
+ PangoWeight weight;
52
+ } lsm_mathml_pango_options[LSM_MATHML_VARIANT_MONOSPACE + 1] = {
53
+ {NULL, PANGO_STYLE_NORMAL, PANGO_WEIGHT_NORMAL},
54
+ {NULL, PANGO_STYLE_NORMAL, PANGO_WEIGHT_BOLD},
55
+ {NULL, PANGO_STYLE_ITALIC, PANGO_WEIGHT_NORMAL},
56
+ {NULL, PANGO_STYLE_ITALIC, PANGO_WEIGHT_BOLD},
57
+ {LSM_MATHML_FONT_DOUBLE_STRUCK, PANGO_STYLE_NORMAL, PANGO_WEIGHT_NORMAL},
58
+ {NULL, PANGO_STYLE_NORMAL, PANGO_WEIGHT_NORMAL},
59
+ {LSM_MATHML_FONT_SCRIPT, PANGO_STYLE_NORMAL, PANGO_WEIGHT_NORMAL},
60
+ {LSM_MATHML_FONT_SCRIPT, PANGO_STYLE_NORMAL, PANGO_WEIGHT_BOLD},
61
+ {NULL, PANGO_STYLE_NORMAL, PANGO_WEIGHT_NORMAL},
62
+ {LSM_MATHML_FONT_SANS, PANGO_STYLE_NORMAL, PANGO_WEIGHT_NORMAL},
63
+ {LSM_MATHML_FONT_SANS, PANGO_STYLE_NORMAL, PANGO_WEIGHT_BOLD},
64
+ {LSM_MATHML_FONT_SANS, PANGO_STYLE_ITALIC, PANGO_WEIGHT_NORMAL},
65
+ {LSM_MATHML_FONT_SANS, PANGO_STYLE_ITALIC, PANGO_WEIGHT_BOLD},
66
+ {LSM_MATHML_FONT_MONOSPACE, PANGO_STYLE_NORMAL, PANGO_WEIGHT_NORMAL}
67
+ };
68
+
69
+ static GObjectClass *parent_class;
70
+
71
+ static void
72
+ lsm_mathml_view_apply_style_to_font_description (PangoFontDescription *font_description,
73
+ const LsmMathmlElementStyle *style,
74
+ gboolean set_family)
75
+ {
76
+ g_return_if_fail (font_description != NULL);
77
+ g_return_if_fail (style != NULL);
78
+
79
+ if (style->math_variant < G_N_ELEMENTS (lsm_mathml_pango_options)) {
80
+ if (set_family) {
81
+ if (lsm_mathml_pango_options[style->math_variant].font == NULL)
82
+ pango_font_description_set_family (font_description, style->math_family);
83
+ else
84
+ pango_font_description_set_family (font_description,
85
+ lsm_mathml_pango_options[style->math_variant].font);
86
+ }
87
+ pango_font_description_set_style (font_description,
88
+ lsm_mathml_pango_options[style->math_variant].style);
89
+ pango_font_description_set_weight (font_description,
90
+ lsm_mathml_pango_options[style->math_variant].weight);
91
+ return;
92
+ }
93
+
94
+ if (set_family)
95
+ pango_font_description_set_family (font_description, style->math_family);
96
+ pango_font_description_set_style (font_description, PANGO_STYLE_NORMAL);
97
+ pango_font_description_set_weight (font_description, PANGO_WEIGHT_NORMAL);
98
+ }
99
+
100
+ static void
101
+ lsm_mathml_view_update_layout_for_text (LsmMathmlView *view,
102
+ const LsmMathmlElementStyle *style,
103
+ const char *text,
104
+ PangoLayout *pango_layout,
105
+ PangoRectangle *ink_rect,
106
+ PangoRectangle *rect,
107
+ int *baseline)
108
+ {
109
+ PangoFontDescription *font_description;
110
+
111
+ font_description = view->dom_view.font_description;
112
+
113
+ pango_font_description_set_size (font_description, style->math_size * PANGO_SCALE);
114
+
115
+ /* Kludge for a nicer latex like rendering */
116
+ if (strcmp (style->math_family, "cmr10") == 0 &&
117
+ (style->math_variant == LSM_MATHML_VARIANT_ITALIC ||
118
+ style->math_variant == LSM_MATHML_VARIANT_BOLD_ITALIC)) {
119
+ pango_font_description_set_family (font_description, "cmmi10");
120
+ pango_font_description_set_style (font_description, PANGO_STYLE_NORMAL);
121
+ if (style->math_variant == LSM_MATHML_VARIANT_BOLD_ITALIC)
122
+ pango_font_description_set_weight (font_description, PANGO_WEIGHT_BOLD);
123
+ else
124
+ pango_font_description_set_weight (font_description, PANGO_WEIGHT_NORMAL);
125
+ } else {
126
+ lsm_mathml_view_apply_style_to_font_description (font_description, style, TRUE);
127
+ }
128
+ pango_layout_set_text (pango_layout, text, -1);
129
+ pango_layout_set_font_description (pango_layout, font_description);
130
+ pango_layout_get_extents (pango_layout, ink_rect, rect);
131
+
132
+ if (baseline != NULL) {
133
+ PangoLayoutIter *iter;
134
+
135
+ iter = pango_layout_get_iter (pango_layout);
136
+ *baseline = pango_layout_iter_get_baseline (iter);
137
+ pango_layout_iter_free (iter);
138
+ }
139
+ }
140
+
141
+ static void
142
+ lsm_mathml_view_show_layout (LsmMathmlView *view,
143
+ double x, double y,
144
+ int baseline,
145
+ const PangoRectangle *ink_rect,
146
+ const PangoRectangle * rect)
147
+ {
148
+ if (lsm_debug_check (&lsm_debug_category_render, LSM_DEBUG_LEVEL_DEBUG)) {
149
+ cairo_t *cairo;
150
+
151
+ cairo = view->dom_view.cairo;
152
+
153
+ cairo_set_line_width (cairo, 0.1);
154
+ cairo_set_source_rgb (cairo, 1,0,0);
155
+ cairo_rectangle (cairo,
156
+ x + pango_units_to_double (rect->x)
157
+ - pango_units_to_double (ink_rect->x),
158
+ y + pango_units_to_double (rect->y) -
159
+ pango_units_to_double (baseline),
160
+ pango_units_to_double (rect->width),
161
+ pango_units_to_double (rect->height));
162
+ cairo_stroke (cairo);
163
+ cairo_set_source_rgb (cairo, 0,1,0);
164
+ cairo_rectangle (cairo,
165
+ x,
166
+ y + pango_units_to_double (ink_rect->y) -
167
+ pango_units_to_double (baseline),
168
+ pango_units_to_double (ink_rect->width),
169
+ pango_units_to_double (ink_rect->height));
170
+ cairo_stroke (cairo);
171
+ }
172
+
173
+ }
174
+
175
+ double
176
+ lsm_mathml_view_measure_axis_offset (LsmMathmlView *view,
177
+ double math_size)
178
+ {
179
+ PangoLayout *pango_layout;
180
+ PangoRectangle ink_rect;
181
+ PangoLayoutIter *iter;
182
+ PangoFontDescription *font_description;
183
+ double axis_offset;
184
+ int baseline;
185
+
186
+ g_return_val_if_fail (LSM_IS_MATHML_VIEW (view), 0.0);
187
+
188
+ font_description = view->dom_view.font_description;
189
+ pango_layout = view->dom_view.measure_pango_layout;
190
+
191
+ pango_font_description_set_family (font_description, LSM_MATHML_FONT_SERIF);
192
+ pango_font_description_set_size (font_description, math_size * PANGO_SCALE);
193
+ pango_font_description_set_style (font_description, PANGO_STYLE_NORMAL);
194
+ pango_font_description_set_weight (font_description, PANGO_WEIGHT_NORMAL);
195
+ pango_layout_set_text (pango_layout, "\xe2\x88\x92", -1);
196
+ pango_layout_set_font_description (pango_layout, font_description);
197
+ pango_layout_get_extents (pango_layout, &ink_rect, NULL);
198
+
199
+ iter = pango_layout_get_iter (pango_layout);
200
+ baseline = pango_layout_iter_get_baseline (iter);
201
+ pango_layout_iter_free (iter);
202
+
203
+ axis_offset = pango_units_to_double (- 0.5 * ink_rect.height - ink_rect.y + baseline);
204
+
205
+ lsm_debug_measure ("[LsmMathmlView::measure_axis_offset] offset = %g (%g %%)",
206
+ axis_offset, axis_offset / math_size);
207
+
208
+ return axis_offset;
209
+ }
210
+
211
+ void
212
+ lsm_mathml_view_get_font_metrics (LsmMathmlView *view,
213
+ const LsmMathmlElementStyle *style,
214
+ double *ascent,
215
+ double *descent)
216
+ {
217
+ LsmMathmlBbox bbox;
218
+
219
+ lsm_mathml_view_measure_text (view, style, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", &bbox);
220
+
221
+ if (ascent != NULL)
222
+ *ascent = bbox.height;
223
+ if (descent != NULL)
224
+ *descent = bbox.depth;
225
+ }
226
+
227
+ void
228
+ lsm_mathml_view_measure_text (LsmMathmlView *view,
229
+ const LsmMathmlElementStyle *style,
230
+ char const *text,
231
+ LsmMathmlBbox *bbox)
232
+ {
233
+ PangoRectangle ink_rect;
234
+ int baseline;
235
+
236
+ g_return_if_fail (LSM_IS_MATHML_VIEW (view));
237
+ g_return_if_fail (style != NULL);
238
+ g_return_if_fail (bbox != NULL);
239
+
240
+ if (text == NULL) {
241
+ *bbox = lsm_mathml_bbox_null;
242
+ return;
243
+ }
244
+
245
+ lsm_mathml_view_update_layout_for_text (view, style, text,
246
+ view->dom_view.measure_pango_layout, &ink_rect, NULL, &baseline);
247
+
248
+ bbox->width = pango_units_to_double (ink_rect.width);
249
+ bbox->height = pango_units_to_double (baseline - ink_rect.y);
250
+ bbox->depth = pango_units_to_double (ink_rect.height + ink_rect.y - baseline);
251
+ bbox->is_defined = TRUE;
252
+ }
253
+
254
+ void
255
+ lsm_mathml_view_show_text (LsmMathmlView *view,
256
+ const LsmMathmlElementStyle *style,
257
+ double x, double y, char const *text)
258
+ {
259
+ PangoLayout *pango_layout;
260
+ PangoRectangle rect, ink_rect;
261
+ cairo_t *cairo;
262
+ int baseline;
263
+
264
+ g_return_if_fail (LSM_IS_MATHML_VIEW (view));
265
+ g_return_if_fail (style != NULL);
266
+
267
+ if (text == NULL || strlen (text) < 1)
268
+ return;
269
+
270
+ lsm_debug_render ("[LsmMathmlView::show_text] '%s' at %g, %g (size = %g) %s",
271
+ text, x, y, style->math_size,
272
+ lsm_mathml_variant_to_string (style->math_variant));
273
+
274
+ lsm_mathml_view_update_layout_for_text (view, style, text,
275
+ view->dom_view.pango_layout, &ink_rect, &rect, &baseline);
276
+ lsm_mathml_view_show_layout (view, x, y, baseline, &ink_rect, &rect);
277
+
278
+ if (ink_rect.width <= 0 || ink_rect.height <= 0)
279
+ return;
280
+
281
+ cairo = view->dom_view.cairo;
282
+ pango_layout = view->dom_view.pango_layout;
283
+
284
+ cairo_save (cairo);
285
+
286
+ if (lsm_debug_check (&lsm_debug_category_dom, LSM_DEBUG_LEVEL_DEBUG)) {
287
+ cairo_set_source_rgba (cairo, 1.0, 0.0, 0.0, 0.2);
288
+ cairo_arc (cairo, x, y, 1.0, 0.0, 2.0 * M_PI);
289
+ cairo_fill (cairo);
290
+ }
291
+
292
+ cairo_set_source_rgba (cairo,
293
+ style->math_color.red,
294
+ style->math_color.green,
295
+ style->math_color.blue,
296
+ style->math_color.alpha);
297
+
298
+ cairo_move_to (cairo, x - pango_units_to_double (ink_rect.x), y - pango_units_to_double (baseline));
299
+ pango_cairo_show_layout (cairo, pango_layout);
300
+
301
+ cairo_restore (cairo);
302
+ }
303
+
304
+ static void
305
+ lsm_mathml_view_update_layout_for_operator (LsmMathmlView *view,
306
+ const LsmMathmlElementStyle *style,
307
+ const char *text,
308
+ gboolean large,
309
+ PangoLayout *pango_layout,
310
+ PangoRectangle *ink_rect,
311
+ PangoRectangle *rect,
312
+ int *baseline)
313
+ {
314
+ PangoFontDescription *font_description;
315
+
316
+ font_description = view->dom_view.font_description;
317
+
318
+ pango_font_description_set_size (font_description,
319
+ style->math_size * PANGO_SCALE * (large ? LSM_MATHML_LARGE_OP_SCALE : 1.0));
320
+ pango_font_description_set_family (font_description, LSM_MATHML_FONT_SERIF);
321
+ lsm_mathml_view_apply_style_to_font_description (font_description, style, FALSE);
322
+ pango_layout_set_text (pango_layout, text, -1);
323
+ pango_layout_set_font_description (pango_layout, font_description);
324
+ pango_layout_get_extents (pango_layout, ink_rect, rect);
325
+
326
+ if (baseline != NULL) {
327
+ PangoLayoutIter *iter;
328
+
329
+ iter = pango_layout_get_iter (pango_layout);
330
+ *baseline = pango_layout_iter_get_baseline (iter);
331
+ pango_layout_iter_free (iter);
332
+ }
333
+ }
334
+
335
+ void
336
+ lsm_mathml_view_measure_operator (LsmMathmlView *view,
337
+ const LsmMathmlElementStyle *style,
338
+ char const *text,
339
+ gboolean large,
340
+ gboolean symmetric,
341
+ double axis_offset,
342
+ LsmMathmlBbox const *stretch_bbox, LsmMathmlBbox *bbox)
343
+ {
344
+ PangoFontDescription *font_description;
345
+ PangoLayout *pango_layout;
346
+ PangoRectangle ink_rect;
347
+ LsmMathmlGlyphFlags flags;
348
+ const LsmMathmlOperatorGlyph *glyph;
349
+ const char *font_name;
350
+ int baseline;
351
+ gboolean is_stretch_bbox_defined;
352
+
353
+ g_return_if_fail (LSM_IS_MATHML_VIEW (view));
354
+ g_return_if_fail (style != NULL);
355
+ g_return_if_fail (bbox != NULL);
356
+ g_return_if_fail (stretch_bbox != NULL);
357
+
358
+ if (text == NULL) {
359
+ *bbox = lsm_mathml_bbox_null;
360
+ return;
361
+ }
362
+
363
+ is_stretch_bbox_defined = stretch_bbox->is_defined;
364
+
365
+ font_description = view->dom_view.font_description;
366
+ pango_layout = view->dom_view.measure_pango_layout;
367
+
368
+ if (is_stretch_bbox_defined)
369
+ lsm_debug_render ("[LsmMathmlView::measure_operator] Stretch bbox w = %g, h = %g, d = %g",
370
+ stretch_bbox->width, stretch_bbox->height, stretch_bbox->depth);
371
+
372
+ glyph = lsm_mathml_glyph_table_find_operator_glyph (text);
373
+ if (glyph == NULL) {
374
+ lsm_mathml_view_update_layout_for_operator (view, style, text, large,
375
+ pango_layout, &ink_rect, NULL, &baseline);
376
+ flags = 0;
377
+
378
+ lsm_debug_render ("[LsmMathmlView::measure_operator] operator = %s", text);
379
+
380
+ } else {
381
+ PangoLayoutIter *iter;
382
+ unsigned int i;
383
+ double width, height;
384
+ gboolean found = FALSE;
385
+
386
+ if (large && (glyph->flags & LSM_MATHML_GLYPH_FLAG_HAS_LARGE_VERSION) &&
387
+ !is_stretch_bbox_defined) {
388
+ pango_font_description_set_size (font_description,
389
+ style->math_size * PANGO_SCALE);
390
+ i = 1;
391
+ } else {
392
+ pango_font_description_set_size (font_description,
393
+ style->math_size * PANGO_SCALE *
394
+ (large ? LSM_MATHML_LARGE_OP_SCALE : 1.0));
395
+ i = 0;
396
+ }
397
+
398
+ for (; i < glyph->n_sized_glyphs; i++) {
399
+ font_name = lsm_mathml_font_names [glyph->sized_glyphs[i].font];
400
+ pango_font_description_set_family (font_description, font_name);
401
+ lsm_mathml_view_apply_style_to_font_description (font_description, style, FALSE);
402
+ pango_layout_set_text (pango_layout, glyph->sized_glyphs[i].utf8, -1);
403
+ pango_layout_set_font_description (pango_layout, font_description);
404
+ pango_layout_get_extents (pango_layout, &ink_rect, NULL);
405
+
406
+ height = pango_units_to_double (ink_rect.height);
407
+ width = pango_units_to_double (ink_rect.width);
408
+
409
+ lsm_debug_render ( "[LsmMathmlView::measure_operator] Glyph #%i -> width = %g, height = %g",
410
+ i, width, height);
411
+
412
+ if (!is_stretch_bbox_defined) {
413
+ found = TRUE;
414
+ break;
415
+ }
416
+
417
+ if (glyph->flags & LSM_MATHML_GLYPH_FLAG_STRETCH_VERTICAL) {
418
+ if (height > (stretch_bbox->height + stretch_bbox->depth))
419
+ found = TRUE;
420
+ }
421
+
422
+ if (glyph->flags & LSM_MATHML_GLYPH_FLAG_STRETCH_HORIZONTAL) {
423
+ if (width > stretch_bbox->width)
424
+ found = TRUE;
425
+ }
426
+
427
+ if (found)
428
+ break;
429
+ }
430
+
431
+ if (found)
432
+ lsm_debug_render ("[LsmMathmlView::measure_operator] Found sized glyph #%i", i);
433
+
434
+ iter = pango_layout_get_iter (pango_layout);
435
+ baseline = pango_layout_iter_get_baseline (iter);
436
+ pango_layout_iter_free (iter);
437
+
438
+ flags = glyph->flags;
439
+ }
440
+
441
+ if (is_stretch_bbox_defined && (flags & LSM_MATHML_GLYPH_FLAG_STRETCH_VERTICAL) &&
442
+ (stretch_bbox->height + stretch_bbox->depth) >= 0) {
443
+ bbox->height = stretch_bbox->height;
444
+ bbox->depth = stretch_bbox->depth;
445
+ } else {
446
+ bbox->height = pango_units_to_double (baseline - ink_rect.y);
447
+ bbox->depth = pango_units_to_double (ink_rect.height + ink_rect.y - baseline);
448
+ }
449
+
450
+ if (is_stretch_bbox_defined && (flags & LSM_MATHML_GLYPH_FLAG_STRETCH_HORIZONTAL) &&
451
+ stretch_bbox->width >= 0.0)
452
+ bbox->width = stretch_bbox->width;
453
+ else
454
+ bbox->width = pango_units_to_double (ink_rect.width);
455
+
456
+ if (!is_stretch_bbox_defined &&
457
+ (flags & LSM_MATHML_GLYPH_FLAG_ALIGN_AXIS)) {
458
+ double length = bbox->depth + bbox->height;
459
+
460
+ bbox->height = 0.5 * length + axis_offset;
461
+ bbox->depth = 0.5 * length - axis_offset;
462
+ }
463
+
464
+ if (is_stretch_bbox_defined && symmetric &&
465
+ (flags & LSM_MATHML_GLYPH_FLAG_STRETCH_VERTICAL)) {
466
+ double length = MAX (axis_offset + bbox->depth, bbox->height - axis_offset);
467
+
468
+ bbox->height = length + axis_offset;
469
+ bbox->depth = length - axis_offset;
470
+ }
471
+
472
+ bbox->is_defined = TRUE;
473
+ }
474
+
475
+ void
476
+ lsm_mathml_view_show_operator (LsmMathmlView *view,
477
+ const LsmMathmlElementStyle *style,
478
+ double x, double y, char const *text,
479
+ gboolean large,
480
+ LsmMathmlBbox const *stretch_bbox)
481
+ {
482
+ PangoFontDescription *font_description;
483
+ PangoLayout *pango_layout;
484
+ PangoRectangle rect, ink_rect;
485
+ cairo_t *cairo;
486
+ const LsmMathmlOperatorGlyph *glyph;
487
+ const char *font_name;
488
+ double scale_x, scale_y;
489
+ int baseline;
490
+
491
+ g_return_if_fail (LSM_IS_MATHML_VIEW (view));
492
+ g_return_if_fail (style != NULL);
493
+ g_return_if_fail (stretch_bbox != NULL);
494
+
495
+ if (text == NULL || !stretch_bbox->is_defined)
496
+ return;
497
+
498
+ font_description = view->dom_view.font_description;
499
+ pango_layout = view->dom_view.measure_pango_layout;
500
+
501
+ if (stretch_bbox->is_defined)
502
+ lsm_debug_render ("[LsmMathmlView::show_operator] Stretch bbox w = %g, h = %g, d = %g",
503
+ stretch_bbox->width, stretch_bbox->height, stretch_bbox->depth);
504
+
505
+ glyph = lsm_mathml_glyph_table_find_operator_glyph (text);
506
+ if (glyph == NULL) {
507
+ lsm_mathml_view_update_layout_for_operator (view, style, text, large,
508
+ pango_layout, &ink_rect, &rect, &baseline);
509
+ } else {
510
+ PangoLayoutIter *iter;
511
+ unsigned int i;
512
+ gboolean found = FALSE;
513
+
514
+ if (large && (glyph->flags & LSM_MATHML_GLYPH_FLAG_HAS_LARGE_VERSION)) {
515
+ pango_font_description_set_size (font_description,
516
+ style->math_size * PANGO_SCALE);
517
+ i = 1;
518
+ } else {
519
+ pango_font_description_set_size (font_description,
520
+ style->math_size * PANGO_SCALE *
521
+ (large ? LSM_MATHML_LARGE_OP_SCALE : 1.0));
522
+ i = 0;
523
+ }
524
+
525
+ for (; i < glyph->n_sized_glyphs; i++) {
526
+ font_name = lsm_mathml_font_names [glyph->sized_glyphs[i].font];
527
+ pango_font_description_set_family (font_description, font_name);
528
+ lsm_mathml_view_apply_style_to_font_description (font_description, style, FALSE);
529
+ pango_layout_set_text (pango_layout, glyph->sized_glyphs[i].utf8, -1);
530
+ pango_layout_set_font_description (pango_layout, font_description);
531
+ pango_layout_get_extents (pango_layout, &ink_rect, NULL);
532
+
533
+ lsm_debug_render ("[LsmMathmlView::show_operator] Glyph #%i -> width = %g, height = %g", i,
534
+ pango_units_to_double (ink_rect.width),
535
+ pango_units_to_double (ink_rect.height));
536
+
537
+ if (!stretch_bbox->is_defined) {
538
+ found = TRUE;
539
+ break;
540
+ }
541
+
542
+ if (glyph->flags & LSM_MATHML_GLYPH_FLAG_STRETCH_VERTICAL) {
543
+ if (pango_units_to_double (ink_rect.height) >
544
+ (stretch_bbox->height + stretch_bbox->depth))
545
+ found = TRUE;
546
+ }
547
+
548
+ if (glyph->flags & LSM_MATHML_GLYPH_FLAG_STRETCH_HORIZONTAL) {
549
+ if (pango_units_to_double (ink_rect.width) >
550
+ stretch_bbox->width)
551
+ found = TRUE;
552
+ }
553
+
554
+ if (found)
555
+ break;
556
+ }
557
+
558
+ if (found)
559
+ lsm_debug_render ("[LsmMathmlView::show_operator] Found sized glyph #%i", i);
560
+
561
+ iter = pango_layout_get_iter (pango_layout);
562
+ baseline = pango_layout_iter_get_baseline (iter);
563
+ pango_layout_iter_free (iter);
564
+ }
565
+
566
+ lsm_debug_render ("[LsmMathmlView::show_operator] '%s' at %g, %g (size = %g) %s - %s",
567
+ text, x, y, style->math_size,
568
+ style->math_family,
569
+ lsm_mathml_variant_to_string (style->math_variant));
570
+
571
+ if (ink_rect.width == 0 || ink_rect.height == 0)
572
+ return;
573
+
574
+ scale_x = stretch_bbox->width / pango_units_to_double (ink_rect.width);
575
+ scale_y = (stretch_bbox->height + stretch_bbox->depth) / pango_units_to_double (ink_rect.height);
576
+
577
+ cairo = view->dom_view.cairo;
578
+
579
+ cairo_save (cairo);
580
+
581
+ if (lsm_debug_check (&lsm_debug_category_render, LSM_DEBUG_LEVEL_DEBUG)) {
582
+ cairo_set_source_rgba (cairo, 1.0, 0.0, 0.0, 0.1);
583
+ cairo_arc (cairo, x, y, 1.0, 0.0, 2.0 * M_PI);
584
+ cairo_fill (cairo);
585
+ }
586
+
587
+ cairo_move_to (cairo, x , y - stretch_bbox->height);
588
+ cairo_scale (cairo, scale_x, scale_y);
589
+ cairo_rel_move_to (cairo,
590
+ - pango_units_to_double (ink_rect.x),
591
+ - pango_units_to_double (ink_rect.y));
592
+
593
+ cairo_set_source_rgba (cairo,
594
+ style->math_color.red,
595
+ style->math_color.green,
596
+ style->math_color.blue,
597
+ style->math_color.alpha);
598
+
599
+ pango_cairo_show_layout (cairo, pango_layout);
600
+ cairo_restore (cairo);
601
+ }
602
+
603
+ double
604
+ lsm_mathml_view_get_operator_slant (LsmMathmlView *view,
605
+ const LsmMathmlElementStyle *style,
606
+ const char *text)
607
+ {
608
+ return lsm_mathml_glyph_table_get_operator_slant (text);
609
+ }
610
+
611
+ void
612
+ lsm_mathml_view_measure_radical (LsmMathmlView *view,
613
+ const LsmMathmlElementStyle *style,
614
+ const LsmMathmlBbox *stretch_bbox,
615
+ LsmMathmlBbox *bbox, double *x_offset, double *y_offset)
616
+ {
617
+ LsmMathmlBbox radical_stretch_bbox;
618
+ double thickness;
619
+
620
+ g_return_if_fail (LSM_IS_MATHML_VIEW (view));
621
+ g_return_if_fail (style != NULL);
622
+ g_return_if_fail (bbox != NULL);
623
+ g_return_if_fail (stretch_bbox != NULL);
624
+
625
+ radical_stretch_bbox = *stretch_bbox;
626
+
627
+ thickness = style->math_size * LSM_MATHML_RADICAL_TOP_LINE_WIDTH;
628
+
629
+ radical_stretch_bbox.height += LSM_MATHML_SPACE_EM_THICK * style->math_size + thickness;
630
+
631
+ radical_stretch_bbox.depth += LSM_MATHML_SPACE_EM_THICK * style->math_size;
632
+
633
+ lsm_mathml_view_measure_operator (view, style, LSM_MATHML_RADICAL_UTF8,
634
+ FALSE, FALSE, 0.0, &radical_stretch_bbox, bbox);
635
+
636
+ if (x_offset != NULL) {
637
+ *x_offset = bbox->width * LSM_MATHML_RADICAL_ORDER_X_OFFSET;
638
+ }
639
+
640
+ if (y_offset != NULL) {
641
+ *y_offset = (bbox->height + bbox->depth) * LSM_MATHML_RADICAL_ORDER_Y_OFFSET -
642
+ LSM_MATHML_SPACE_EM_MEDIUM * style->math_size;
643
+ }
644
+ }
645
+
646
+ void
647
+ lsm_mathml_view_show_radical (LsmMathmlView *view,
648
+ const LsmMathmlElementStyle *style,
649
+ double x, double y, double width,
650
+ LsmMathmlBbox const *stretch_bbox)
651
+ {
652
+ cairo_t *cairo;
653
+ double thickness;
654
+ double y_line;
655
+ double dummy = 0.0;
656
+ double alpha;
657
+
658
+ g_return_if_fail (LSM_IS_MATHML_VIEW (view));
659
+ g_return_if_fail (style != NULL);
660
+ g_return_if_fail (stretch_bbox != NULL);
661
+
662
+ cairo = view->dom_view.cairo;
663
+
664
+ lsm_mathml_view_show_operator (view, style, x, y, LSM_MATHML_RADICAL_UTF8, FALSE, stretch_bbox);
665
+
666
+ thickness = style->math_size * LSM_MATHML_RADICAL_TOP_LINE_WIDTH;
667
+
668
+ alpha = style->math_color.alpha;
669
+
670
+ if (!view->dom_view.is_vector) {
671
+ cairo_user_to_device_distance (cairo, &dummy, &thickness);
672
+
673
+ if (thickness < 1.0) {
674
+ alpha *= thickness;
675
+ thickness = 1.0;
676
+ }
677
+
678
+ thickness = floor (thickness + 0.5);
679
+ cairo_device_to_user_distance (cairo, &dummy, &thickness);
680
+ }
681
+
682
+ cairo_save (cairo);
683
+ cairo_set_line_cap (cairo, CAIRO_LINE_CAP_ROUND);
684
+ cairo_set_line_width (cairo, thickness);
685
+
686
+ cairo_set_source_rgba (cairo,
687
+ style->math_color.red,
688
+ style->math_color.green,
689
+ style->math_color.blue,
690
+ alpha);
691
+
692
+ x += stretch_bbox->width;
693
+
694
+ y_line = y - stretch_bbox->height;
695
+
696
+ if (!view->dom_view.is_vector) {
697
+ cairo_user_to_device (cairo, &dummy, &y_line);
698
+
699
+ y_line = floor (y_line);
700
+
701
+ cairo_device_to_user (cairo, &dummy, &y_line);
702
+ }
703
+
704
+ y_line += 0.5 * thickness;
705
+
706
+ cairo_move_to (cairo,
707
+ x - 0.5 * style->math_size * LSM_MATHML_RADICAL_TOP_LINE_WIDTH,
708
+ y_line);
709
+ cairo_line_to (cairo,
710
+ x - thickness * 0.5 + width,
711
+ y_line);
712
+
713
+ cairo_stroke (cairo);
714
+
715
+ cairo_restore (cairo);
716
+ }
717
+
718
+ typedef enum {
719
+ _GMATHML_STROKE_WIDTH_EVEN,
720
+ _GMATHML_STROKE_WIDTH_ODD,
721
+ _GMATHML_STROKE_WIDTH_NULL,
722
+ _GMATHML_STROKE_WIDTH_VECTOR
723
+ } _LsmMathmlStrokeWidth;
724
+
725
+ static void
726
+ _round_rectangle_coordinates (cairo_t *cairo,
727
+ _LsmMathmlStrokeWidth stroke_width,
728
+ double *x0, double *y0,
729
+ double *x1, double *y1)
730
+ {
731
+ if (stroke_width != _GMATHML_STROKE_WIDTH_VECTOR) {
732
+ cairo_user_to_device (cairo, x0, y0);
733
+ cairo_user_to_device (cairo, x1, y1);
734
+
735
+ if (stroke_width == _GMATHML_STROKE_WIDTH_EVEN) {
736
+ *x0 = floor (*x0 + 0.5);
737
+ *y0 = floor (*y0 + 0.5);
738
+ *x1 = floor (*x1 + 0.5);
739
+ *y1 = floor (*y1 + 0.5);
740
+ } else {
741
+ *x0 = 0.5 + floor (*x0);
742
+ *y0 = 0.5 + floor (*y0);
743
+ *x1 = 0.5 + floor (*x1);
744
+ *y1 = 0.5 + floor (*y1);
745
+ }
746
+
747
+ cairo_device_to_user (cairo, x0, y0);
748
+ cairo_device_to_user (cairo, x1, y1);
749
+ }
750
+ }
751
+
752
+ static _LsmMathmlStrokeWidth
753
+ _emit_stroke_attributes (LsmMathmlView *view, LsmMathmlLine line, double line_width,
754
+ const LsmMathmlColor *color)
755
+ {
756
+ _LsmMathmlStrokeWidth stroke_width;
757
+ cairo_t *cairo;
758
+ double dashes[2] = {3.0, 2.0};
759
+ double rounded_width = line_width;
760
+ double dummy = 0;
761
+ double alpha = color->alpha;
762
+
763
+ cairo = view->dom_view.cairo;
764
+
765
+ switch (line) {
766
+ case LSM_MATHML_LINE_DASHED:
767
+ cairo_set_dash (cairo, dashes, 2, 0.0);
768
+ break;
769
+ case LSM_MATHML_LINE_SOLID:
770
+ cairo_set_dash (cairo, NULL, 0, 0.0);
771
+ break;
772
+ default:
773
+ return _GMATHML_STROKE_WIDTH_NULL;
774
+ }
775
+
776
+ if (view->dom_view.is_vector) {
777
+ cairo_set_line_width (cairo, line_width);
778
+ cairo_set_source_rgba (cairo,
779
+ color->red,
780
+ color->green,
781
+ color->blue,
782
+ color->alpha);
783
+ return _GMATHML_STROKE_WIDTH_VECTOR;
784
+ }
785
+
786
+ cairo_user_to_device_distance (cairo, &dummy, &rounded_width);
787
+
788
+ if (rounded_width < 1.0) {
789
+ alpha *= rounded_width;
790
+ rounded_width = 1.0;
791
+ }
792
+
793
+ rounded_width = floor (rounded_width + 0.5);
794
+
795
+ if (((int) rounded_width) % 2 == 0)
796
+ stroke_width = _GMATHML_STROKE_WIDTH_EVEN;
797
+ else
798
+ stroke_width = _GMATHML_STROKE_WIDTH_ODD;
799
+
800
+ cairo_device_to_user_distance (cairo, &dummy, &rounded_width);
801
+
802
+ cairo_set_line_width (cairo, rounded_width);
803
+ cairo_set_source_rgba (cairo,
804
+ color->red,
805
+ color->green,
806
+ color->blue,
807
+ alpha);
808
+
809
+ return stroke_width;
810
+ }
811
+
812
+ void
813
+ lsm_mathml_view_show_background (LsmMathmlView *view,
814
+ const LsmMathmlElementStyle *style,
815
+ double x, double y,
816
+ const LsmMathmlBbox *bbox)
817
+ {
818
+ cairo_t *cairo;
819
+ double x0, y0, x1, y1;
820
+
821
+ g_return_if_fail (LSM_IS_MATHML_VIEW (view));
822
+ g_return_if_fail (style != NULL);
823
+
824
+ cairo = view->dom_view.cairo;
825
+
826
+ x0 = x;
827
+ y0 = y - bbox->height;
828
+ x1 = x + bbox->width;
829
+ y1 = y + bbox->depth;
830
+
831
+ if (!view->dom_view.is_vector)
832
+ _round_rectangle_coordinates (cairo, _GMATHML_STROKE_WIDTH_EVEN, &x0, &y0, &x1, &y1);
833
+
834
+ cairo_set_source_rgba (cairo,
835
+ style->math_background.red,
836
+ style->math_background.green,
837
+ style->math_background.blue,
838
+ style->math_background.alpha);
839
+ cairo_rectangle (cairo, x0, y0, x1 - x0, y1 - y0);
840
+ cairo_fill (cairo);
841
+ }
842
+
843
+ void
844
+ lsm_mathml_view_show_bbox (LsmMathmlView *view, double x, double y, const LsmMathmlBbox *bbox)
845
+ {
846
+ cairo_t *cairo;
847
+
848
+ g_return_if_fail (LSM_IS_MATHML_VIEW (view));
849
+
850
+ cairo = view->dom_view.cairo;
851
+
852
+ if (lsm_debug_check (&lsm_debug_category_render, LSM_DEBUG_LEVEL_DEBUG)) {
853
+ cairo_move_to (cairo, x, y);
854
+ cairo_set_source_rgba (cairo, 0,0,1,0.1);
855
+ cairo_rectangle (cairo, x, y, bbox->width, -bbox->height);
856
+ cairo_rectangle (cairo, x, y, bbox->width, bbox->depth);
857
+ cairo_fill (cairo);
858
+ }
859
+ }
860
+
861
+ void
862
+ lsm_mathml_view_show_rectangle (LsmMathmlView *view,
863
+ const LsmMathmlElementStyle *style,
864
+ double x0, double y0, double width, double height,
865
+ LsmMathmlLine line, double line_width)
866
+ {
867
+ _LsmMathmlStrokeWidth stroke_width;
868
+ cairo_t *cairo;
869
+ double x1, y1;
870
+
871
+ g_return_if_fail (LSM_IS_MATHML_VIEW (view));
872
+ g_return_if_fail (style != NULL);
873
+
874
+ stroke_width = _emit_stroke_attributes (view, line, line_width, &style->math_color);
875
+
876
+ if (stroke_width == _GMATHML_STROKE_WIDTH_NULL)
877
+ return;
878
+
879
+ x1 = x0 + width;
880
+ y1 = y0 + height;
881
+
882
+ cairo = view->dom_view.cairo;
883
+
884
+ _round_rectangle_coordinates (cairo, stroke_width, &x0, &y0, &x1, &y1);
885
+
886
+ cairo_rectangle (cairo, x0, y0, x1 - x0, y1 - y0);
887
+ cairo_stroke (cairo);
888
+ }
889
+
890
+ void
891
+ lsm_mathml_view_show_line (LsmMathmlView *view,
892
+ const LsmMathmlElementStyle *style,
893
+ double x0, double y0, double x1, double y1,
894
+ LsmMathmlLine line, double line_width)
895
+ {
896
+ _LsmMathmlStrokeWidth stroke_width;
897
+ cairo_t *cairo;
898
+
899
+ g_return_if_fail (LSM_IS_MATHML_VIEW (view));
900
+ g_return_if_fail (style != NULL);
901
+
902
+ stroke_width = _emit_stroke_attributes (view, line, line_width, &style->math_color);
903
+
904
+ if (stroke_width == _GMATHML_STROKE_WIDTH_NULL)
905
+ return;
906
+
907
+ cairo = view->dom_view.cairo;
908
+
909
+ _round_rectangle_coordinates (cairo, stroke_width, &x0, &y0, &x1, &y1);
910
+
911
+ cairo_move_to (cairo, x0, y0);
912
+ cairo_line_to (cairo, x1, y1);
913
+ cairo_stroke (cairo);
914
+ }
915
+
916
+ void
917
+ lsm_mathml_view_show_fraction_line (LsmMathmlView *view,
918
+ const LsmMathmlElementStyle *style,
919
+ double x, double y,
920
+ double width, double thickness)
921
+ {
922
+ _LsmMathmlStrokeWidth stroke_width;
923
+ cairo_t *cairo;
924
+ double x0, y0, x1, y1;
925
+
926
+ g_return_if_fail (LSM_IS_MATHML_VIEW (view));
927
+ g_return_if_fail (style != NULL);
928
+
929
+ stroke_width = _emit_stroke_attributes (view, LSM_MATHML_LINE_SOLID, thickness, &style->math_color);
930
+
931
+ if (stroke_width == _GMATHML_STROKE_WIDTH_NULL)
932
+ return;
933
+
934
+ x0 = x;
935
+ y0 = y;
936
+ x1 = x + width;
937
+ y1 = y;
938
+
939
+ cairo = view->dom_view.cairo;
940
+
941
+ _round_rectangle_coordinates (cairo, stroke_width, &x0, &y0, &x1, &y1);
942
+
943
+ cairo_move_to (cairo, x0, y0);
944
+ cairo_line_to (cairo, x1, y1);
945
+ cairo_stroke (cairo);
946
+ }
947
+
948
+ static const LsmMathmlBbox *
949
+ _view_measure (LsmMathmlView *view, double *width, double *height, double *baseline)
950
+ {
951
+ LsmMathmlMathElement *math_element;
952
+ const LsmMathmlBbox *bbox;
953
+
954
+ math_element = lsm_mathml_document_get_root_element (LSM_MATHML_DOCUMENT (view->dom_view.document));
955
+ if (math_element == NULL)
956
+ return NULL;
957
+
958
+ lsm_mathml_math_element_update (math_element);
959
+
960
+ bbox = lsm_mathml_math_element_measure (math_element, view);
961
+
962
+ if (bbox != NULL) {
963
+ if (width != NULL)
964
+ *width = bbox->width;
965
+ if (height != NULL)
966
+ *height = bbox->height + bbox->depth;
967
+ if (baseline != NULL)
968
+ *baseline = bbox->height;
969
+ }
970
+
971
+ return bbox;
972
+ }
973
+
974
+ static void
975
+ lsm_mathml_view_measure (LsmDomView *dom_view, double *width, double *height, double *baseline)
976
+ {
977
+ _view_measure (LSM_MATHML_VIEW (dom_view), width, height, baseline);
978
+ }
979
+
980
+ static void
981
+ lsm_mathml_view_render (LsmDomView *dom_view)
982
+ {
983
+ LsmMathmlView *view = LSM_MATHML_VIEW (dom_view);
984
+ LsmMathmlMathElement *math_element;
985
+ cairo_t *cairo;
986
+ const LsmMathmlBbox *bbox;
987
+ double resolution_ppi;
988
+
989
+ math_element = lsm_mathml_document_get_root_element (LSM_MATHML_DOCUMENT (view->dom_view.document));
990
+ if (math_element == NULL)
991
+ return;
992
+
993
+ resolution_ppi = lsm_dom_view_get_resolution (dom_view);
994
+
995
+ bbox = _view_measure (view, NULL, NULL, NULL);
996
+
997
+ lsm_mathml_math_element_layout (math_element, view, bbox);
998
+
999
+ cairo = view->dom_view.cairo;
1000
+
1001
+ cairo_scale (cairo, resolution_ppi / 72.0, resolution_ppi / 72.0);
1002
+
1003
+ cairo_translate (cairo, 0, bbox->height);
1004
+
1005
+ lsm_mathml_math_element_render (math_element, view);
1006
+
1007
+ lsm_debug_render ("[LsmMathmlView::render] cairo status = %s",
1008
+ cairo_status_to_string (cairo_status (cairo)));
1009
+ }
1010
+
1011
+ LsmMathmlView *
1012
+ lsm_mathml_view_new (LsmMathmlDocument *document)
1013
+ {
1014
+ LsmMathmlView *view;
1015
+
1016
+ view = g_object_new (LSM_TYPE_MATHML_VIEW, NULL);
1017
+
1018
+ lsm_dom_view_set_document (LSM_DOM_VIEW (view), LSM_DOM_DOCUMENT (document));
1019
+
1020
+ return view;
1021
+ }
1022
+
1023
+ static void
1024
+ lsm_mathml_view_init (LsmMathmlView *view)
1025
+ {
1026
+ }
1027
+
1028
+ static void
1029
+ lsm_mathml_view_finalize (GObject *object)
1030
+ {
1031
+ parent_class->finalize (object);
1032
+ }
1033
+
1034
+ static void
1035
+ lsm_mathml_view_class_init (LsmMathmlViewClass *view_class)
1036
+ {
1037
+ GObjectClass *object_class = G_OBJECT_CLASS (view_class);
1038
+ LsmDomViewClass *d_view_class = LSM_DOM_VIEW_CLASS (view_class);
1039
+
1040
+ parent_class = g_type_class_peek_parent (view_class);
1041
+
1042
+ object_class->finalize = lsm_mathml_view_finalize;
1043
+
1044
+ d_view_class->measure = lsm_mathml_view_measure;
1045
+ d_view_class->render = lsm_mathml_view_render;
1046
+ }
1047
+
1048
+ G_DEFINE_TYPE (LsmMathmlView, lsm_mathml_view, LSM_TYPE_DOM_VIEW)