1 /* Lasem
2 *
3 * Copyright © 2009 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 <pango/pango-attributes.h>
25 #include <lsmmathmltraits.h>
26 #include <math.h>
27 #include <string.h>
28 #include <stdlib.h>
29
30 static gboolean
lsm_mathml_boolean_trait_from_string(LsmTrait * abstract_trait,char * string)31 lsm_mathml_boolean_trait_from_string (LsmTrait *abstract_trait, char *string)
32 {
33 gboolean *value = (gboolean *) abstract_trait;
34
35 if (g_strcmp0 (string, "true") == 0) {
36 *value = TRUE;
37 return TRUE;
38 } else if (g_strcmp0 (string, "false") == 0) {
39 *value = FALSE;
40 return TRUE;
41 }
42
43 *value = FALSE;
44 return FALSE;
45 }
46
47 static char *
lsm_mathml_boolean_trait_to_string(LsmTrait * abstract_trait)48 lsm_mathml_boolean_trait_to_string (LsmTrait *abstract_trait)
49 {
50 gboolean *value = (gboolean *) abstract_trait;
51
52 return g_strdup_printf ("%s", *value ? "true" : "false");
53 }
54
55 const LsmTraitClass lsm_mathml_boolean_trait_class = {
56 .size = sizeof (gboolean),
57 .from_string = lsm_mathml_boolean_trait_from_string,
58 .to_string = lsm_mathml_boolean_trait_to_string
59 };
60
61 static gboolean
lsm_mathml_unsigned_trait_from_string(LsmTrait * abstract_trait,char * string)62 lsm_mathml_unsigned_trait_from_string (LsmTrait *abstract_trait, char *string)
63 {
64 unsigned int *value = (unsigned int *) abstract_trait;
65 char *end_ptr;
66
67 *value = strtol (string, &end_ptr, 10);
68
69 return end_ptr != string;
70 }
71
72 static char *
lsm_mathml_unsigned_trait_to_string(LsmTrait * abstract_trait)73 lsm_mathml_unsigned_trait_to_string (LsmTrait *abstract_trait)
74 {
75 unsigned int *value = (unsigned int *) abstract_trait;
76
77 return g_strdup_printf ("%u", *value);
78 }
79
80 const LsmTraitClass lsm_mathml_unsigned_trait_class = {
81 .size = sizeof (unsigned),
82 .from_string = lsm_mathml_unsigned_trait_from_string,
83 .to_string = lsm_mathml_unsigned_trait_to_string
84 };
85
86 static gboolean
lsm_mathml_display_trait_from_string(LsmTrait * abstract_trait,char * string)87 lsm_mathml_display_trait_from_string (LsmTrait *abstract_trait, char *string)
88 {
89 LsmMathmlDisplay *value = (LsmMathmlDisplay *) abstract_trait;
90
91 *value = lsm_mathml_display_from_string (string);
92
93 return *value >= 0;
94 }
95
96 static char *
lsm_mathml_display_trait_to_string(LsmTrait * abstract_trait)97 lsm_mathml_display_trait_to_string (LsmTrait *abstract_trait)
98 {
99 LsmMathmlDisplay *value = (LsmMathmlDisplay *) abstract_trait;
100
101 return g_strdup (lsm_mathml_display_to_string (*value));
102 }
103
104 const LsmTraitClass lsm_mathml_display_trait_class = {
105 .size = sizeof (int),
106 .from_string = lsm_mathml_display_trait_from_string,
107 .to_string = lsm_mathml_display_trait_to_string
108 };
109
110 static gboolean
lsm_mathml_mode_trait_from_string(LsmTrait * abstract_trait,char * string)111 lsm_mathml_mode_trait_from_string (LsmTrait *abstract_trait, char *string)
112 {
113 LsmMathmlMode *value = (LsmMathmlMode *) abstract_trait;
114
115 *value = lsm_mathml_mode_from_string (string);
116
117 return *value >= 0;
118 }
119
120 static char *
lsm_mathml_mode_trait_to_string(LsmTrait * abstract_trait)121 lsm_mathml_mode_trait_to_string (LsmTrait *abstract_trait)
122 {
123 LsmMathmlMode *value = (LsmMathmlMode *) abstract_trait;
124
125 return g_strdup (lsm_mathml_mode_to_string (*value));
126 }
127
128 const LsmTraitClass lsm_mathml_mode_trait_class = {
129 .size = sizeof (int),
130 .from_string = lsm_mathml_mode_trait_from_string,
131 .to_string = lsm_mathml_mode_trait_to_string
132 };
133
134 static gboolean
lsm_mathml_line_trait_from_string(LsmTrait * abstract_trait,char * string)135 lsm_mathml_line_trait_from_string (LsmTrait *abstract_trait, char *string)
136 {
137 LsmMathmlLine *value = (LsmMathmlLine *) abstract_trait;
138
139 *value = lsm_mathml_line_from_string (string);
140
141 return *value >= 0;
142 }
143
144 static char *
lsm_mathml_line_trait_to_string(LsmTrait * abstract_trait)145 lsm_mathml_line_trait_to_string (LsmTrait *abstract_trait)
146 {
147 LsmMathmlLine *value = (LsmMathmlLine *) abstract_trait;
148
149 return g_strdup (lsm_mathml_line_to_string (*value));
150 }
151
152 const LsmTraitClass lsm_mathml_line_trait_class = {
153 .size = sizeof (int),
154 .from_string = lsm_mathml_line_trait_from_string,
155 .to_string = lsm_mathml_line_trait_to_string
156 };
157
158 static gboolean
lsm_mathml_font_style_trait_from_string(LsmTrait * abstract_trait,char * string)159 lsm_mathml_font_style_trait_from_string (LsmTrait *abstract_trait, char *string)
160 {
161 LsmMathmlFontStyle *value = (LsmMathmlFontStyle *) abstract_trait;
162
163 *value = lsm_mathml_font_style_from_string (string);
164
165 return *value >= 0;
166 }
167
168 static char *
lsm_mathml_font_style_trait_to_string(LsmTrait * abstract_trait)169 lsm_mathml_font_style_trait_to_string (LsmTrait *abstract_trait)
170 {
171 LsmMathmlFontStyle *value = (LsmMathmlFontStyle *) abstract_trait;
172
173 return g_strdup (lsm_mathml_font_style_to_string (*value));
174 }
175
176 const LsmTraitClass lsm_mathml_font_style_trait_class = {
177 .size = sizeof (int),
178 .from_string = lsm_mathml_font_style_trait_from_string,
179 .to_string = lsm_mathml_font_style_trait_to_string
180 };
181
182 static gboolean
lsm_mathml_font_weight_trait_from_string(LsmTrait * abstract_trait,char * string)183 lsm_mathml_font_weight_trait_from_string (LsmTrait *abstract_trait, char *string)
184 {
185 LsmMathmlFontWeight *value = (LsmMathmlFontWeight *) abstract_trait;
186
187 *value = lsm_mathml_font_weight_from_string (string);
188
189 return *value >= 0;
190 }
191
192 static char *
lsm_mathml_font_weight_trait_to_string(LsmTrait * abstract_trait)193 lsm_mathml_font_weight_trait_to_string (LsmTrait *abstract_trait)
194 {
195 LsmMathmlFontWeight *value = (LsmMathmlFontWeight *) abstract_trait;
196
197 return g_strdup (lsm_mathml_font_weight_to_string (*value));
198 }
199
200 const LsmTraitClass lsm_mathml_font_weight_trait_class = {
201 .size = sizeof (int),
202 .from_string = lsm_mathml_font_weight_trait_from_string,
203 .to_string = lsm_mathml_font_weight_trait_to_string
204 };
205
206 static gboolean
lsm_mathml_variant_trait_from_string(LsmTrait * abstract_trait,char * string)207 lsm_mathml_variant_trait_from_string (LsmTrait *abstract_trait, char *string)
208 {
209 LsmMathmlVariant *value = (LsmMathmlVariant *) abstract_trait;
210
211 *value = lsm_mathml_variant_from_string (string);
212
213 return *value >= 0;
214 }
215
216 static char *
lsm_mathml_variant_trait_to_string(LsmTrait * abstract_trait)217 lsm_mathml_variant_trait_to_string (LsmTrait *abstract_trait)
218 {
219 LsmMathmlVariant *value = (LsmMathmlVariant *) abstract_trait;
220
221 return g_strdup (lsm_mathml_variant_to_string (*value));
222 }
223
224 const LsmTraitClass lsm_mathml_variant_trait_class = {
225 .size = sizeof (int),
226 .from_string = lsm_mathml_variant_trait_from_string,
227 .to_string = lsm_mathml_variant_trait_to_string
228 };
229
230 static gboolean
lsm_mathml_form_trait_from_string(LsmTrait * abstract_trait,char * string)231 lsm_mathml_form_trait_from_string (LsmTrait *abstract_trait, char *string)
232 {
233 LsmMathmlForm *value = (LsmMathmlForm *) abstract_trait;
234
235 *value = lsm_mathml_form_from_string (string);
236
237 return *value >= 0;
238 }
239
240 static char *
lsm_mathml_form_trait_to_string(LsmTrait * abstract_trait)241 lsm_mathml_form_trait_to_string (LsmTrait *abstract_trait)
242 {
243 LsmMathmlForm *value = (LsmMathmlForm *) abstract_trait;
244
245 return g_strdup (lsm_mathml_form_to_string (*value));
246 }
247
248 const LsmTraitClass lsm_mathml_form_trait_class = {
249 .size = sizeof (int),
250 .from_string = lsm_mathml_form_trait_from_string,
251 .to_string = lsm_mathml_form_trait_to_string
252 };
253
254 static gboolean
lsm_mathml_notation_trait_from_string(LsmTrait * abstract_trait,char * string)255 lsm_mathml_notation_trait_from_string (LsmTrait *abstract_trait, char *string)
256 {
257 LsmMathmlNotation *value = (LsmMathmlNotation *) abstract_trait;
258
259 *value = lsm_mathml_notation_from_string (string);
260
261 return *value >= 0;
262 }
263
264 static char *
lsm_mathml_notation_trait_to_string(LsmTrait * abstract_trait)265 lsm_mathml_notation_trait_to_string (LsmTrait *abstract_trait)
266 {
267 LsmMathmlNotation *value = (LsmMathmlNotation *) abstract_trait;
268
269 return g_strdup (lsm_mathml_notation_to_string (*value));
270 }
271
272 const LsmTraitClass lsm_mathml_notation_trait_class = {
273 .size = sizeof (int),
274 .from_string = lsm_mathml_notation_trait_from_string,
275 .to_string = lsm_mathml_notation_trait_to_string
276 };
277
278 static gboolean
lsm_mathml_linebreak_trait_from_string(LsmTrait * abstract_trait,char * string)279 lsm_mathml_linebreak_trait_from_string (LsmTrait *abstract_trait, char *string)
280 {
281 LsmMathmlLinebreak *value = (LsmMathmlLinebreak *) abstract_trait;
282
283 *value = lsm_mathml_linebreak_from_string (string);
284
285 return *value >= 0;
286 }
287
288 static char *
lsm_mathml_linebreak_trait_to_string(LsmTrait * abstract_trait)289 lsm_mathml_linebreak_trait_to_string (LsmTrait *abstract_trait)
290 {
291 LsmMathmlLinebreak *value = (LsmMathmlLinebreak *) abstract_trait;
292
293 return g_strdup (lsm_mathml_linebreak_to_string (*value));
294 }
295
296 const LsmTraitClass lsm_mathml_linebreak_trait_class = {
297 .size = sizeof (int),
298 .from_string = lsm_mathml_linebreak_trait_from_string,
299 .to_string = lsm_mathml_linebreak_trait_to_string
300 };
301
302 typedef int (*LsmMathmlEnumFromString) (const char *string);
303 typedef char * (*LsmMathmlEnumToString) (unsigned int value);
304
305 static gboolean
lsm_mathml_enum_list_trait_from_string(LsmMathmlEnumList * enum_list,LsmMathmlEnumFromString from_string,char * string)306 lsm_mathml_enum_list_trait_from_string (LsmMathmlEnumList *enum_list,
307 LsmMathmlEnumFromString from_string,
308 char *string)
309 {
310 char **items;
311 unsigned int i;
312 int enum_value;
313
314 g_free (enum_list->values);
315
316 items = g_strsplit_set (string, " ", -1);
317 enum_list->n_values = g_strv_length (items);
318
319 enum_list->values = g_new (int, enum_list->n_values);
320 for (i = 0; i < enum_list->n_values; i++) {
321 enum_value = from_string (items[i]);
322 if (enum_value < 0) {
323 g_free (enum_list->values);
324 enum_list->values = NULL;
325 enum_list->n_values = 0;
326 g_strfreev (items);
327
328 return FALSE;
329 }
330 enum_list->values[i] = enum_value;
331 }
332
333 g_strfreev (items);
334
335 return TRUE;
336 }
337
338 static char *
lsm_mathml_enum_list_trait_to_string(LsmMathmlEnumList * enum_list,LsmMathmlEnumToString to_string)339 lsm_mathml_enum_list_trait_to_string (LsmMathmlEnumList *enum_list,
340 LsmMathmlEnumToString to_string)
341 {
342 return g_strdup ("FIXME");
343 }
344
345 static void
lsm_mathml_enum_list_trait_init(LsmTrait * abstract_trait,const LsmTrait * abstract_default)346 lsm_mathml_enum_list_trait_init (LsmTrait *abstract_trait,
347 const LsmTrait *abstract_default)
348 {
349 LsmMathmlEnumList *enum_list = (LsmMathmlEnumList *) abstract_trait;
350 LsmMathmlEnumList *enum_list_defaut = (LsmMathmlEnumList *) abstract_default;
351
352 enum_list->n_values = enum_list_defaut->n_values;
353 if (enum_list->n_values == 0)
354 enum_list->values = NULL;
355 else {
356 enum_list->values = g_new (int, enum_list->n_values);
357 memcpy (enum_list->values, enum_list_defaut->values, sizeof (int) * enum_list->n_values);
358 }
359 }
360
361 void
lsm_mathml_enum_list_init(LsmMathmlEnumList * enum_list,const LsmMathmlEnumList * enum_list_default)362 lsm_mathml_enum_list_init (LsmMathmlEnumList *enum_list, const LsmMathmlEnumList *enum_list_default)
363 {
364 g_return_if_fail (enum_list != NULL);
365 g_return_if_fail (enum_list_default != NULL);
366
367 lsm_mathml_enum_list_trait_init (enum_list, enum_list_default);
368 }
369
370 static void
lsm_mathml_enum_list_trait_finalize(LsmTrait * abstract_trait)371 lsm_mathml_enum_list_trait_finalize (LsmTrait *abstract_trait)
372 {
373 LsmMathmlEnumList *enum_list = (LsmMathmlEnumList *) abstract_trait;
374
375 g_free (enum_list->values);
376 enum_list->values = NULL;
377 enum_list->n_values = 0;
378 }
379
380 static gboolean
lsm_mathml_row_align_list_trait_from_string(LsmTrait * abstract_trait,char * string)381 lsm_mathml_row_align_list_trait_from_string (LsmTrait *abstract_trait,
382 char *string)
383 {
384 return lsm_mathml_enum_list_trait_from_string ((LsmMathmlEnumList *) abstract_trait,
385 (LsmMathmlEnumFromString) lsm_mathml_row_align_from_string,
386 string);
387 }
388
389 static char *
lsm_mathml_row_align_list_trait_to_string(LsmTrait * abstract_trait)390 lsm_mathml_row_align_list_trait_to_string (LsmTrait *abstract_trait)
391 {
392 return lsm_mathml_enum_list_trait_to_string ((LsmMathmlEnumList *) abstract_trait,
393 (LsmMathmlEnumToString) lsm_mathml_row_align_to_string);
394 }
395
396 const LsmTraitClass lsm_mathml_row_align_list_trait_class = {
397 .size = sizeof (LsmMathmlEnumList),
398 .from_string = lsm_mathml_row_align_list_trait_from_string,
399 .to_string = lsm_mathml_row_align_list_trait_to_string,
400 .init = lsm_mathml_enum_list_trait_init,
401 .finalize = lsm_mathml_enum_list_trait_finalize
402 };
403
404 static gboolean
lsm_mathml_column_align_list_trait_from_string(LsmTrait * abstract_trait,char * string)405 lsm_mathml_column_align_list_trait_from_string (LsmTrait *abstract_trait,
406 char *string)
407 {
408 return lsm_mathml_enum_list_trait_from_string ((LsmMathmlEnumList *) abstract_trait,
409 (LsmMathmlEnumFromString) lsm_mathml_column_align_from_string,
410 string);
411 }
412
413 static char *
lsm_mathml_column_align_list_trait_to_string(LsmTrait * abstract_trait)414 lsm_mathml_column_align_list_trait_to_string (LsmTrait *abstract_trait)
415 {
416 return lsm_mathml_enum_list_trait_to_string ((LsmMathmlEnumList *) abstract_trait,
417 (LsmMathmlEnumToString) lsm_mathml_column_align_to_string);
418 }
419
420 const LsmTraitClass lsm_mathml_column_align_list_trait_class = {
421 .size = sizeof (LsmMathmlEnumList),
422 .from_string = lsm_mathml_column_align_list_trait_from_string,
423 .to_string = lsm_mathml_column_align_list_trait_to_string,
424 .init = lsm_mathml_enum_list_trait_init,
425 .finalize = lsm_mathml_enum_list_trait_finalize
426 };
427
428 static gboolean
lsm_mathml_line_list_trait_from_string(LsmTrait * abstract_trait,char * string)429 lsm_mathml_line_list_trait_from_string (LsmTrait *abstract_trait,
430 char *string)
431 {
432 return lsm_mathml_enum_list_trait_from_string ((LsmMathmlEnumList *) abstract_trait,
433 (LsmMathmlEnumFromString) lsm_mathml_line_from_string,
434 string);
435 }
436
437 static char *
lsm_mathml_line_list_trait_to_string(LsmTrait * abstract_trait)438 lsm_mathml_line_list_trait_to_string (LsmTrait *abstract_trait)
439 {
440 return lsm_mathml_enum_list_trait_to_string ((LsmMathmlEnumList *) abstract_trait,
441 (LsmMathmlEnumToString) lsm_mathml_line_to_string);
442 }
443
444 const LsmTraitClass lsm_mathml_line_list_trait_class = {
445 .size = sizeof (LsmMathmlEnumList),
446 .from_string = lsm_mathml_line_list_trait_from_string,
447 .to_string = lsm_mathml_line_list_trait_to_string,
448 .init = lsm_mathml_enum_list_trait_init,
449 .finalize = lsm_mathml_enum_list_trait_finalize
450 };
451
452 static gboolean
lsm_mathml_script_level_trait_from_string(LsmTrait * abstract_trait,char * string)453 lsm_mathml_script_level_trait_from_string (LsmTrait *abstract_trait, char *string)
454 {
455 LsmMathmlScriptLevel *value = (LsmMathmlScriptLevel *) abstract_trait;
456 char *end_ptr;
457
458 value->level = strtol (string, &end_ptr, 10);
459
460 if (string[0] == '+')
461 value->sign = LSM_MATHML_SCRIPT_LEVEL_SIGN_PLUS;
462 else if (string[0] == '-')
463 value->sign = LSM_MATHML_SCRIPT_LEVEL_SIGN_MINUS;
464 else
465 value->sign = LSM_MATHML_SCRIPT_LEVEL_SIGN_NONE;
466
467 return end_ptr != string;
468 }
469
470 static char *
lsm_mathml_script_level_trait_to_string(LsmTrait * abstract_trait)471 lsm_mathml_script_level_trait_to_string (LsmTrait *abstract_trait)
472 {
473 LsmMathmlScriptLevel *value = (LsmMathmlScriptLevel *) abstract_trait;
474
475 if (value->sign == LSM_MATHML_SCRIPT_LEVEL_SIGN_PLUS)
476 return g_strdup_printf ("+%d", value->level);
477
478 return g_strdup_printf ("%d", value->level);
479 }
480
481 const LsmTraitClass lsm_mathml_script_level_trait_class = {
482 .size = sizeof (int),
483 .from_string = lsm_mathml_script_level_trait_from_string,
484 .to_string = lsm_mathml_script_level_trait_to_string
485 };
486
487 static gboolean
lsm_mathml_double_trait_from_string(LsmTrait * abstract_trait,char * string)488 lsm_mathml_double_trait_from_string (LsmTrait *abstract_trait, char *string)
489 {
490 double *value = (double *) abstract_trait;
491 char *end_ptr;
492
493 *value = g_ascii_strtod (string, &end_ptr);
494
495 return end_ptr != string;
496 }
497
498 static char *
lsm_mathml_double_trait_to_string(LsmTrait * abstract_trait)499 lsm_mathml_double_trait_to_string (LsmTrait *abstract_trait)
500 {
501 double *value = (double *) abstract_trait;
502
503 return g_strdup_printf ("%g", *value);
504 }
505
506 const LsmTraitClass lsm_mathml_double_trait_class = {
507 .size = sizeof (double),
508 .from_string = lsm_mathml_double_trait_from_string,
509 .to_string = lsm_mathml_double_trait_to_string
510 };
511
512 static LsmMathmlColor *
lsm_mathml_color_copy(LsmMathmlColor * color)513 lsm_mathml_color_copy (LsmMathmlColor *color)
514 {
515 LsmMathmlColor *copy;
516
517 copy = g_new (LsmMathmlColor, 1);
518 memcpy (copy, color, sizeof (LsmMathmlColor));
519
520 return copy;
521 }
522
523 GType
lsm_mathml_color_get_type(void)524 lsm_mathml_color_get_type (void)
525 {
526 static GType our_type = 0;
527 if (our_type == 0)
528 our_type = g_boxed_type_register_static
529 ("LsmMathmlColor",
530 (GBoxedCopyFunc) lsm_mathml_color_copy,
531 (GBoxedFreeFunc) g_free);
532 return our_type;
533 }
534
535 static gboolean
lsm_mathml_color_trait_from_string(LsmTrait * abstract_trait,char * string)536 lsm_mathml_color_trait_from_string (LsmTrait *abstract_trait, char *string)
537 {
538 LsmMathmlColor *color = (LsmMathmlColor *) abstract_trait;
539 PangoColor pango_color;
540 gboolean result;
541
542 if (strcmp (string, "transparent") == 0) {
543 color->red = 0.0;
544 color->green = 0.0;
545 color->blue = 0.0;
546 color->alpha = 0.0;
547
548 return TRUE;
549 }
550
551 result = pango_color_parse (&pango_color, string);
552 color->alpha = 1.0;
553 color->red = pango_color.red / 65535.0;
554 color->green = pango_color.green / 65535.0;
555 color->blue = pango_color.blue / 65535.0;
556
557 return result;
558 }
559
560 static char *
lsm_mathml_color_trait_to_string(LsmTrait * abstract_trait)561 lsm_mathml_color_trait_to_string (LsmTrait *abstract_trait)
562 {
563 LsmMathmlColor *color = (LsmMathmlColor *) abstract_trait;
564 PangoColor pango_color;
565
566 if (color->alpha <= 0.0)
567 return g_strdup ("transparent");
568
569 pango_color.red = ((int) ((double) 0.5 + 65535.0 * color->red));
570 pango_color.blue = ((int) ((double) 0.5 + 65535.0 * color->blue));
571 pango_color.green = ((int) ((double) 0.5 + 65535.0 * color->green));
572
573 return pango_color_to_string (&pango_color);
574 }
575
576 const LsmTraitClass lsm_mathml_color_trait_class = {
577 .size = sizeof (LsmMathmlColor),
578 .from_string = lsm_mathml_color_trait_from_string,
579 .to_string = lsm_mathml_color_trait_to_string
580 };
581
582 static gboolean
lsm_mathml_string_trait_from_string(LsmTrait * abstract_trait,char * string)583 lsm_mathml_string_trait_from_string (LsmTrait *abstract_trait, char *string)
584 {
585 char **value = (char **) abstract_trait;
586
587 g_free (*value);
588 *value = g_strdup (string);
589
590 return TRUE;
591 }
592
593 static char *
lsm_mathml_string_trait_to_string(LsmTrait * abstract_trait)594 lsm_mathml_string_trait_to_string (LsmTrait *abstract_trait)
595 {
596 char **value = (char **) abstract_trait;
597
598 return g_strdup (*value);
599 }
600
601 static void
lsm_mathml_string_trait_init(LsmTrait * abstract_trait,const LsmTrait * abstract_default)602 lsm_mathml_string_trait_init (LsmTrait *abstract_trait,
603 const LsmTrait *abstract_default)
604 {
605 char **value = (char **) abstract_trait;
606 char **default_value = (char **) abstract_default;
607
608 *value = g_strdup (*default_value);
609 }
610
611 static void
lsm_mathml_string_trait_finalize(LsmTrait * abstract_trait)612 lsm_mathml_string_trait_finalize (LsmTrait *abstract_trait)
613 {
614 char **value = (char **) abstract_trait;
615
616 g_free (*value);
617 *value = NULL;
618 }
619
620 const LsmTraitClass lsm_mathml_string_trait_class = {
621 .size = sizeof (char *),
622 .from_string = lsm_mathml_string_trait_from_string,
623 .to_string = lsm_mathml_string_trait_to_string,
624 .init = lsm_mathml_string_trait_init,
625 .finalize = lsm_mathml_string_trait_finalize
626 };
627
628 static LsmMathmlLength *
lsm_mathml_length_copy(LsmMathmlLength * length)629 lsm_mathml_length_copy (LsmMathmlLength *length)
630 {
631 LsmMathmlLength *copy;
632
633 copy = g_new (LsmMathmlLength, 1);
634 memcpy (copy, length, sizeof (LsmMathmlLength));
635
636 return copy;
637 }
638
639 GType
lsm_mathml_length_get_type(void)640 lsm_mathml_length_get_type (void)
641 {
642 static GType our_type = 0;
643
644 if (our_type == 0)
645 our_type = g_boxed_type_register_static
646 ("LsmMathmlLength",
647 (GBoxedCopyFunc) lsm_mathml_length_copy,
648 (GBoxedFreeFunc) g_free);
649 return our_type;
650 }
651
652 static gboolean
lsm_mathml_length_trait_from_string(LsmTrait * abstract_trait,char * string)653 lsm_mathml_length_trait_from_string (LsmTrait *abstract_trait, char *string)
654 {
655 LsmMathmlLength *length = (LsmMathmlLength *) abstract_trait;
656 char *unit_str;
657
658 length->value = g_ascii_strtod (string, &unit_str);
659 length->unit = lsm_mathml_unit_from_string (unit_str);
660
661 /* TODO Handle "big", "small", normal" sizes */
662
663 return unit_str != string && length->unit >= 0;
664 }
665
666 static char *
lsm_mathml_length_trait_to_string(LsmTrait * abstract_trait)667 lsm_mathml_length_trait_to_string (LsmTrait *abstract_trait)
668 {
669 LsmMathmlLength *length = (LsmMathmlLength *) abstract_trait;
670
671 return g_strdup_printf ("%g %s", length->value,
672 lsm_mathml_unit_to_string (length->unit));
673 }
674
675 const LsmTraitClass lsm_mathml_length_trait_class = {
676 .size = sizeof (char *),
677 .from_string = lsm_mathml_length_trait_from_string,
678 .to_string = lsm_mathml_length_trait_to_string
679 };
680
681 double
lsm_mathml_length_normalize(const LsmMathmlLength * length,double base,double font_size)682 lsm_mathml_length_normalize (const LsmMathmlLength *length,
683 double base,
684 double font_size)
685 {
686 double value;
687
688 g_return_val_if_fail (length != NULL, 0.0);
689
690 switch (length->unit) {
691 case LSM_MATHML_UNIT_PX:
692 case LSM_MATHML_UNIT_PT:
693 value = length->value;
694 break;
695 case LSM_MATHML_UNIT_PC:
696 value = length->value * 72.0 / 6.0;
697 break;
698 case LSM_MATHML_UNIT_CM:
699 value = length->value * 72.0 / 2.54;
700 break;
701 case LSM_MATHML_UNIT_MM:
702 value = length->value * 72.0 / 25.4;
703 break;
704 case LSM_MATHML_UNIT_IN:
705 value = length->value * 72.0;
706 break;
707 case LSM_MATHML_UNIT_EM:
708 value = length->value * font_size;
709 break;
710 case LSM_MATHML_UNIT_EX:
711 value = length->value * font_size * 0.5;
712 break;
713 case LSM_MATHML_UNIT_PERCENT:
714 value = length->value * base / 100.0;
715 break;
716 case LSM_MATHML_UNIT_NONE:
717 value = length->value * base;
718 break;
719 default:
720 value = 0;
721 }
722
723 return value;
724 }
725
726 static LsmMathmlSpace *
lsm_mathml_space_copy(LsmMathmlSpace * space)727 lsm_mathml_space_copy (LsmMathmlSpace *space)
728 {
729 LsmMathmlSpace *copy;
730
731 copy = g_new (LsmMathmlSpace, 1);
732 memcpy (copy, space, sizeof (LsmMathmlSpace));
733
734 return copy;
735 }
736
737 GType
lsm_mathml_space_get_type(void)738 lsm_mathml_space_get_type (void)
739 {
740 static GType our_type = 0;
741
742 if (our_type == 0)
743 our_type = g_boxed_type_register_static
744 ("LsmMathmlSpace",
745 (GBoxedCopyFunc) lsm_mathml_space_copy,
746 (GBoxedFreeFunc) g_free);
747 return our_type;
748 }
749
750 static gboolean
lsm_mathml_space_trait_from_string(LsmTrait * abstract_trait,char * string)751 lsm_mathml_space_trait_from_string (LsmTrait *abstract_trait, char *string)
752 {
753 LsmMathmlSpace *space = (LsmMathmlSpace *) abstract_trait;
754 char *unit_str;
755
756 space->name = lsm_mathml_space_name_from_string (string);
757
758 if (space->name < 0) {
759 space->length.value = g_ascii_strtod (string, &unit_str);
760 space->length.unit = lsm_mathml_unit_from_string (unit_str);
761
762 return unit_str != string && space->length.unit >= 0;
763 }
764
765 space->length.value = 0.0;
766 space->length.unit = LSM_MATHML_UNIT_PX;
767
768 return TRUE;
769 }
770
771 static char *
lsm_mathml_space_trait_to_string(LsmTrait * abstract_trait)772 lsm_mathml_space_trait_to_string (LsmTrait *abstract_trait)
773 {
774 LsmMathmlSpace *space = (LsmMathmlSpace *) abstract_trait;
775 const char *string;
776
777 string = lsm_mathml_space_name_to_string (space->name);
778 if (string != NULL)
779 return g_strdup (string);
780
781 return g_strdup_printf ("%g %s", space->length.value,
782 lsm_mathml_unit_to_string (space->length.unit));
783 }
784
785 const LsmTraitClass lsm_mathml_space_trait_class = {
786 .size = sizeof (char *),
787 .from_string = lsm_mathml_space_trait_from_string,
788 .to_string = lsm_mathml_space_trait_to_string
789 };
790
791 static gboolean
lsm_mathml_space_list_trait_from_string(LsmTrait * abstract_trait,char * string)792 lsm_mathml_space_list_trait_from_string (LsmTrait *abstract_trait, char *string)
793 {
794 LsmMathmlSpaceList *space_list = (LsmMathmlSpaceList *) abstract_trait;
795 char **items;
796 unsigned int i;
797
798 g_free (space_list->spaces);
799
800 items = g_strsplit_set (string, " ", -1);
801 space_list->n_spaces = g_strv_length (items);
802
803 space_list->spaces = g_new (LsmMathmlSpace, space_list->n_spaces);
804 for (i = 0; i < space_list->n_spaces; i++) {
805 if (!lsm_mathml_space_trait_from_string (&space_list->spaces[i], items[i])) {
806 g_free (space_list->spaces);
807 space_list->spaces = NULL;
808 space_list->n_spaces = 0;
809 g_strfreev (items);
810
811 return FALSE;
812 }
813 }
814
815 g_strfreev (items);
816
817 return TRUE;
818 }
819
820 static char *
lsm_mathml_space_list_trait_to_string(LsmTrait * abstract_trait)821 lsm_mathml_space_list_trait_to_string (LsmTrait *abstract_trait)
822 {
823 return g_strdup ("FIXME");
824 }
825
826 static void
lsm_mathml_space_list_trait_init(LsmTrait * abstract_trait,const LsmTrait * abstract_default)827 lsm_mathml_space_list_trait_init (LsmTrait *abstract_trait,
828 const LsmTrait *abstract_default)
829 {
830 LsmMathmlSpaceList *space_list = (LsmMathmlSpaceList *) abstract_trait;
831 LsmMathmlSpaceList *space_list_defaut = (LsmMathmlSpaceList *) abstract_default;
832
833 space_list->n_spaces = space_list_defaut->n_spaces;
834 if (space_list->n_spaces == 0)
835 space_list->spaces = NULL;
836 else {
837 space_list->spaces = g_new (LsmMathmlSpace, space_list->n_spaces);
838 memcpy (space_list->spaces, space_list_defaut->spaces, sizeof (LsmMathmlSpace) * space_list->n_spaces);
839 }
840 }
841
842 static void
lsm_mathml_space_list_trait_finalize(LsmTrait * abstract_trait)843 lsm_mathml_space_list_trait_finalize (LsmTrait *abstract_trait)
844 {
845 LsmMathmlSpaceList *space_list = (LsmMathmlSpaceList *) abstract_trait;
846
847 g_free (space_list->spaces);
848 space_list->spaces = NULL;
849 space_list->n_spaces = 0;
850 }
851
852 void
lsm_mathml_space_list_init(LsmMathmlSpaceList * space_list,const LsmMathmlSpaceList * space_list_default)853 lsm_mathml_space_list_init (LsmMathmlSpaceList *space_list, const LsmMathmlSpaceList *space_list_default)
854 {
855 g_return_if_fail (space_list != NULL);
856 g_return_if_fail (space_list_default != NULL);
857
858 lsm_mathml_space_list_trait_init (space_list, space_list_default);
859 }
860
861 const LsmTraitClass lsm_mathml_space_list_trait_class = {
862 .size = sizeof (LsmMathmlSpaceList),
863 .from_string = lsm_mathml_space_list_trait_from_string,
864 .to_string = lsm_mathml_space_list_trait_to_string,
865 .init = lsm_mathml_space_list_trait_init,
866 .finalize = lsm_mathml_space_list_trait_finalize
867 };
868