• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
2 
3 /* libcroco - Library for parsing and applying CSS
4  * Copyright (C) 2006-2019 Free Software Foundation, Inc.
5  *
6  * This file is not part of the GNU gettext program, but is used with
7  * GNU gettext.
8  *
9  * The original copyright notice is as follows:
10  */
11 
12 /*
13  * This file is part of The Croco Library
14  *
15  * Copyright (C) 2003-2004 Dodji Seketeli.  All Rights Reserved.
16  *
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of version 2.1 of
19  * the GNU Lesser General Public
20  * License as published by the Free Software Foundation.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the
28  * GNU Lesser General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
31  * USA
32  */
33 
34 #include <config.h>
35 #include "cr-fonts.h"
36 #include <string.h>
37 
38 static enum CRStatus
cr_font_family_to_string_real(CRFontFamily const * a_this,gboolean a_walk_list,GString ** a_string)39 cr_font_family_to_string_real (CRFontFamily const * a_this,
40                                gboolean a_walk_list, GString ** a_string)
41 {
42         guchar const *name = NULL;
43         enum CRStatus result = CR_OK;
44 
45         if (!*a_string) {
46                 *a_string = g_string_new (NULL);
47                 g_return_val_if_fail (*a_string,
48                                       CR_INSTANCIATION_FAILED_ERROR);
49         }
50 
51         if (!a_this) {
52                 g_string_append (*a_string, "NULL");
53                 return CR_OK;
54         }
55 
56         switch (a_this->type) {
57         case FONT_FAMILY_SANS_SERIF:
58                 name = (guchar const *) "sans-serif";
59                 break;
60 
61         case FONT_FAMILY_SERIF:
62                 name = (guchar const *) "sans-serif";
63                 break;
64 
65         case FONT_FAMILY_CURSIVE:
66                 name = (guchar const *) "cursive";
67                 break;
68 
69         case FONT_FAMILY_FANTASY:
70                 name = (guchar const *) "fantasy";
71                 break;
72 
73         case FONT_FAMILY_MONOSPACE:
74                 name = (guchar const *) "monospace";
75                 break;
76 
77         case FONT_FAMILY_NON_GENERIC:
78                 name = (guchar const *) a_this->name;
79                 break;
80 
81         default:
82                 name = NULL;
83                 break;
84         }
85 
86         if (name) {
87                 if (a_this->prev) {
88                         g_string_append_printf (*a_string, ", %s", name);
89                 } else {
90                         g_string_append (*a_string, (const gchar *) name);
91                 }
92         }
93         if (a_walk_list == TRUE && a_this->next) {
94                 result = cr_font_family_to_string_real (a_this->next,
95                                                         TRUE, a_string);
96         }
97         return result;
98 }
99 
100 static const gchar *
cr_predefined_absolute_font_size_to_string(enum CRPredefinedAbsoluteFontSize a_code)101 cr_predefined_absolute_font_size_to_string (enum CRPredefinedAbsoluteFontSize
102                                             a_code)
103 {
104         gchar const *str = NULL;
105 
106         switch (a_code) {
107         case FONT_SIZE_XX_SMALL:
108                 str = "xx-small";
109                 break;
110         case FONT_SIZE_X_SMALL:
111                 str = "x-small";
112                 break;
113         case FONT_SIZE_SMALL:
114                 str = "small";
115                 break;
116         case FONT_SIZE_MEDIUM:
117                 str = "medium";
118                 break;
119         case FONT_SIZE_LARGE:
120                 str = "large";
121                 break;
122         case FONT_SIZE_X_LARGE:
123                 str = "x-large";
124                 break;
125         case FONT_SIZE_XX_LARGE:
126                 str = "xx-large";
127                 break;
128         default:
129                 str = "unknown absolute font size value";
130         }
131         return str;
132 }
133 
134 static const gchar *
cr_relative_font_size_to_string(enum CRRelativeFontSize a_code)135 cr_relative_font_size_to_string (enum CRRelativeFontSize a_code)
136 {
137         gchar const *str = NULL;
138 
139         switch (a_code) {
140         case FONT_SIZE_LARGER:
141                 str = "larger";
142                 break;
143         case FONT_SIZE_SMALLER:
144                 str = "smaller";
145                 break;
146         default:
147                 str = "unknown relative font size value";
148                 break;
149         }
150         return str;
151 }
152 
153 /**
154  * cr_font_family_new:
155  * @a_type: the type of font family to create.
156  * @a_name: the name of the font family.
157  *
158  * create a font family.
159  *
160  * Returns the newly built font family.
161  */
162 CRFontFamily *
cr_font_family_new(enum CRFontFamilyType a_type,guchar * a_name)163 cr_font_family_new (enum CRFontFamilyType a_type, guchar * a_name)
164 {
165         CRFontFamily *result = NULL;
166 
167         result = g_try_malloc (sizeof (CRFontFamily));
168 
169         if (!result) {
170                 cr_utils_trace_info ("Out of memory");
171                 return NULL;
172         }
173 
174         memset (result, 0, sizeof (CRFontFamily));
175         result->type = a_type;
176 
177         cr_font_family_set_name (result, a_name);
178 
179         return result;
180 }
181 
182 /**
183  * cr_font_family_to_string:
184  * @a_this: the current instance of #CRFontFamily.
185  * @a_walk_font_family_list: wether the serialize the entire list.
186  *
187  * Returns the seriliazed font family. The caller has to free it using
188  * g_free().
189  */
190 guchar *
cr_font_family_to_string(CRFontFamily const * a_this,gboolean a_walk_font_family_list)191 cr_font_family_to_string (CRFontFamily const * a_this,
192                           gboolean a_walk_font_family_list)
193 {
194         enum CRStatus status = CR_OK;
195         guchar *result = NULL;
196         GString *stringue = NULL;
197 
198         if (!a_this) {
199                 result = (guchar *) g_strdup ("NULL");
200                 g_return_val_if_fail (result, NULL);
201                 return result;
202         }
203         status = cr_font_family_to_string_real (a_this,
204                                                 a_walk_font_family_list,
205                                                 &stringue);
206 
207         if (status == CR_OK && stringue) {
208                 result = (guchar *) stringue->str;
209                 g_string_free (stringue, FALSE);
210                 stringue = NULL;
211 
212         } else {
213                 if (stringue) {
214                         g_string_free (stringue, TRUE);
215                         stringue = NULL;
216                 }
217         }
218 
219         return result;
220 }
221 
222 /**
223  * cr_font_family_set_name:
224  * @a_this: the current instance of #CRFontFamily.
225  * @a_name: the new name
226  *
227  * Returns CR_OK upon sucessful completion, an error code otherwise.
228  */
229 enum CRStatus
cr_font_family_set_name(CRFontFamily * a_this,guchar * a_name)230 cr_font_family_set_name (CRFontFamily * a_this, guchar * a_name)
231 {
232         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
233 
234         /*
235          *only non generic font families can have a name
236          */
237 
238         if (a_this->type != FONT_FAMILY_NON_GENERIC) {
239                 return CR_BAD_PARAM_ERROR;
240         }
241 
242         if (a_this->name) {
243                 g_free (a_this->name);
244                 a_this->name = NULL;
245         }
246 
247         a_this->name = a_name;
248         return CR_OK;
249 }
250 
251 /**
252  * cr_font_family_append:
253  * @a_this: the current instance of #CRFontFamily.
254  * @a_family_to_append: the font family to append to the list
255  *
256  * Returns the new font family list.
257  */
258 CRFontFamily *
cr_font_family_append(CRFontFamily * a_this,CRFontFamily * a_family_to_append)259 cr_font_family_append (CRFontFamily * a_this,
260                        CRFontFamily * a_family_to_append)
261 {
262         CRFontFamily *cur_ff = NULL;
263 
264         g_return_val_if_fail (a_family_to_append, NULL);
265 
266         if (!a_this)
267                 return a_family_to_append;
268 
269         for (cur_ff = a_this; cur_ff && cur_ff->next; cur_ff = cur_ff->next) ;
270 
271         cur_ff->next = a_family_to_append;
272         a_family_to_append->prev = cur_ff;
273 
274         return a_this;
275 
276 }
277 
278 /**
279  * cr_font_family_prepend:
280  * @a_this: the current instance #CRFontFamily.
281  * @a_family_to_prepend: the font family to prepend to the list.
282  *
283  * Returns the font family list.
284  */
285 CRFontFamily *
cr_font_family_prepend(CRFontFamily * a_this,CRFontFamily * a_family_to_prepend)286 cr_font_family_prepend (CRFontFamily * a_this,
287                         CRFontFamily * a_family_to_prepend)
288 {
289         g_return_val_if_fail (a_this && a_family_to_prepend, NULL);
290 
291         if (!a_this)
292                 return a_family_to_prepend;
293 
294         a_family_to_prepend->next = a_this;
295         a_this->prev = a_family_to_prepend;
296 
297         return a_family_to_prepend;
298 }
299 
300 /**
301  * cr_font_family_destroy:
302  * @a_this: the current instance of #CRFontFamily.
303  *
304  * Returns CR_OK upon sucessful completion, an error code otherwise.
305  */
306 enum CRStatus
cr_font_family_destroy(CRFontFamily * a_this)307 cr_font_family_destroy (CRFontFamily * a_this)
308 {
309         CRFontFamily *cur_ff = NULL;
310 
311         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
312 
313         for (cur_ff = a_this; cur_ff && cur_ff->next; cur_ff = cur_ff->next) ;
314 
315         for (; cur_ff; cur_ff = cur_ff->prev) {
316                 if (a_this->name) {
317                         g_free (a_this->name);
318                         a_this->name = NULL;
319                 }
320 
321                 if (cur_ff->next) {
322                         g_free (cur_ff->next);
323 
324                 }
325 
326                 if (cur_ff->prev == NULL) {
327                         g_free (a_this);
328                 }
329         }
330 
331         return CR_OK;
332 }
333 
334 /***************************************************
335  *'font-size' manipulation functions definitions
336  ***************************************************/
337 
338 /**
339  * cr_font_size_new:
340  *
341  * Returns the newly created font size.
342  */
343 CRFontSize *
cr_font_size_new(void)344 cr_font_size_new (void)
345 {
346         CRFontSize *result = NULL;
347 
348         result = g_try_malloc (sizeof (CRFontSize));
349         if (!result) {
350                 cr_utils_trace_info ("Out of memory");
351                 return NULL;
352         }
353         memset (result, 0, sizeof (CRFontSize));
354 
355         return result;
356 }
357 
358 /**
359  * cr_font_size_clear:
360  * @a_this: the current instance of #CRFontSize
361  *
362  * Returns CR_OK upon successful completion, an error code otherwise.
363  */
364 enum CRStatus
cr_font_size_clear(CRFontSize * a_this)365 cr_font_size_clear (CRFontSize * a_this)
366 {
367         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
368 
369         switch (a_this->type) {
370         case PREDEFINED_ABSOLUTE_FONT_SIZE:
371         case RELATIVE_FONT_SIZE:
372         case INHERITED_FONT_SIZE:
373                 memset (a_this, 0, sizeof (CRFontSize));
374                 break;
375 
376         case ABSOLUTE_FONT_SIZE:
377                 memset (a_this, 0, sizeof (CRFontSize));
378                 break;
379 
380         default:
381                 return CR_UNKNOWN_TYPE_ERROR;
382         }
383 
384         return CR_OK;
385 }
386 
387 /**
388  * cr_font_size_copy:
389  * @a_dst: the destination #CRFontSize (where to copy to).
390  * @a_src: the source #CRFontSize (where to copy from).
391  *
392  * Returns CR_OK upon successful completion, an error code otherwise.
393  */
394 enum CRStatus
cr_font_size_copy(CRFontSize * a_dst,CRFontSize const * a_src)395 cr_font_size_copy (CRFontSize * a_dst, CRFontSize const * a_src)
396 {
397         g_return_val_if_fail (a_dst && a_src, CR_BAD_PARAM_ERROR);
398 
399         switch (a_src->type) {
400         case PREDEFINED_ABSOLUTE_FONT_SIZE:
401         case RELATIVE_FONT_SIZE:
402         case INHERITED_FONT_SIZE:
403                 cr_font_size_clear (a_dst);
404                 memcpy (a_dst, a_src, sizeof (CRFontSize));
405                 break;
406 
407         case ABSOLUTE_FONT_SIZE:
408                 cr_font_size_clear (a_dst);
409                 cr_num_copy (&a_dst->value.absolute,
410                              &a_src->value.absolute);
411                 a_dst->type = a_src->type;
412                 break;
413 
414         default:
415                 return CR_UNKNOWN_TYPE_ERROR;
416         }
417         return CR_OK;
418 }
419 
420 /**
421  * cr_font_size_set_predefined_absolute_font_size:
422  * @a_this: the current instance of #CRFontSize.
423  * @a_predefined: what to set.
424  *
425  * Returns CR_OK upon sucessful completion, an error code otherwise.
426  */
427 enum CRStatus
cr_font_size_set_predefined_absolute_font_size(CRFontSize * a_this,enum CRPredefinedAbsoluteFontSize a_predefined)428 cr_font_size_set_predefined_absolute_font_size (CRFontSize *a_this,
429                                                 enum CRPredefinedAbsoluteFontSize a_predefined)
430 {
431         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
432         g_return_val_if_fail (a_predefined >= FONT_SIZE_XX_SMALL
433                               && a_predefined < NB_PREDEFINED_ABSOLUTE_FONT_SIZES,
434                               CR_BAD_PARAM_ERROR) ;
435 
436         a_this->type = PREDEFINED_ABSOLUTE_FONT_SIZE ;
437         a_this->value.predefined = a_predefined ;
438 
439         return CR_OK ;
440 }
441 
442 /**
443  * cr_font_size_set_relative_font_size:
444  * @a_this: the current instance of #CRFontSize
445  * @a_relative: the new relative font size
446  *
447  * Returns CR_OK upon successful completion, an error code otherwise.
448  */
449 enum CRStatus
cr_font_size_set_relative_font_size(CRFontSize * a_this,enum CRRelativeFontSize a_relative)450 cr_font_size_set_relative_font_size (CRFontSize *a_this,
451                                      enum CRRelativeFontSize a_relative)
452 {
453         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
454         g_return_val_if_fail (a_relative >= FONT_SIZE_LARGER
455                               && a_relative < NB_RELATIVE_FONT_SIZE,
456                               CR_BAD_PARAM_ERROR) ;
457 
458         a_this->type = RELATIVE_FONT_SIZE ;
459         a_this->value.relative = a_relative ;
460         return CR_OK ;
461 }
462 
463 /**
464  * cr_font_size_set_absolute_font_size:
465  * @a_this: the current instance of #CRFontSize
466  * @a_num_type: the type of number to set.
467  * @a_value: the actual value to set.
468  *
469  * Returns CR_OK upon succesful completion, an error code otherwise.
470  */
471 enum CRStatus
cr_font_size_set_absolute_font_size(CRFontSize * a_this,enum CRNumType a_num_type,gdouble a_value)472 cr_font_size_set_absolute_font_size (CRFontSize *a_this,
473                                      enum CRNumType a_num_type,
474                                      gdouble a_value)
475 {
476         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
477         g_return_val_if_fail (a_num_type >= NUM_AUTO
478                               && a_num_type < NB_NUM_TYPE,
479                               CR_BAD_PARAM_ERROR) ;
480 
481         a_this->type = ABSOLUTE_FONT_SIZE ;
482         cr_num_set (&a_this->value.absolute,
483                     a_value, a_num_type) ;
484         return CR_OK ;
485 }
486 
487 /**
488  * cr_font_size_set_to_inherit:
489  * @a_this: the current instance of #CRFontSize
490  *
491  * Returns CR_OK upon succesful completion, an error code otherwise.
492  */
493 enum CRStatus
cr_font_size_set_to_inherit(CRFontSize * a_this)494 cr_font_size_set_to_inherit (CRFontSize *a_this)
495 {
496         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
497 
498         cr_font_size_clear (a_this) ;
499         a_this->type = INHERITED_FONT_SIZE ;
500 
501         return CR_OK ;
502 }
503 
504 /**
505  * cr_font_size_is_set_to_inherit:
506  * @a_this: the current instance of #CRFontSize.
507  *
508  * Returns TRUE if the current instance is set to 'inherit'.
509  */
510 gboolean
cr_font_size_is_set_to_inherit(CRFontSize const * a_this)511 cr_font_size_is_set_to_inherit (CRFontSize const *a_this)
512 {
513         g_return_val_if_fail (a_this, FALSE) ;
514 
515         return a_this->type == INHERITED_FONT_SIZE ;
516 }
517 
518 /**
519  * cr_font_size_to_string:
520  * @a_this: the current instance of #CRFontSize
521  *
522  * Returns the serialized form of #CRFontSize. The returned string
523  * has to bee freed using g_free().
524  */
525 gchar *
cr_font_size_to_string(CRFontSize const * a_this)526 cr_font_size_to_string (CRFontSize const * a_this)
527 {
528         gchar *str = NULL;
529 
530         if (!a_this) {
531                 str = g_strdup ("NULL");
532                 g_return_val_if_fail (str, NULL);
533                 return str;
534         }
535         switch (a_this->type) {
536         case PREDEFINED_ABSOLUTE_FONT_SIZE:
537                 str = g_strdup (cr_predefined_absolute_font_size_to_string
538                                 (a_this->value.predefined));
539                 break;
540         case ABSOLUTE_FONT_SIZE:
541                 str = (gchar *) cr_num_to_string (&a_this->value.absolute);
542                 break;
543         case RELATIVE_FONT_SIZE:
544                 str = g_strdup (cr_relative_font_size_to_string
545                                 (a_this->value.relative));
546                 break;
547         case INHERITED_FONT_SIZE:
548                 str = g_strdup ("inherit");
549                 break;
550         default:
551                 break;
552         }
553         return str;
554 }
555 
556 /**
557  * cr_font_size_get_smaller_predefined:
558  * @a_font_size: the font size to consider.
559  * @a_smaller_size: out parameter. The a smaller value than @a_font_size.
560  */
561 void
cr_font_size_get_smaller_predefined_font_size(enum CRPredefinedAbsoluteFontSize a_font_size,enum CRPredefinedAbsoluteFontSize * a_smaller_size)562 cr_font_size_get_smaller_predefined_font_size
563 				(enum CRPredefinedAbsoluteFontSize a_font_size,
564 			         enum CRPredefinedAbsoluteFontSize *a_smaller_size)
565 {
566         enum CRPredefinedAbsoluteFontSize result = FONT_SIZE_MEDIUM ;
567 
568         g_return_if_fail (a_smaller_size) ;
569         g_return_if_fail (a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES
570                           && a_font_size >= FONT_SIZE_XX_SMALL) ;
571 
572         switch (a_font_size) {
573         case FONT_SIZE_XX_SMALL:
574                 result =  FONT_SIZE_XX_SMALL ;
575                 break ;
576         case FONT_SIZE_X_SMALL:
577                 result =  FONT_SIZE_XX_SMALL ;
578                 break ;
579         case FONT_SIZE_SMALL:
580                 result =  FONT_SIZE_X_SMALL;
581                 break ;
582         case FONT_SIZE_MEDIUM:
583                 result =  FONT_SIZE_SMALL;
584                 break ;
585         case FONT_SIZE_LARGE:
586                 result =  FONT_SIZE_MEDIUM;
587                 break ;
588         case FONT_SIZE_X_LARGE:
589                 result =  FONT_SIZE_LARGE;
590                 break ;
591         case FONT_SIZE_XX_LARGE:
592                 result =  FONT_SIZE_XX_LARGE;
593                 break ;
594 	case FONT_SIZE_INHERIT:
595                 cr_utils_trace_info ("can't return a smaller size for FONT_SIZE_INHERIT") ;
596                 result =  FONT_SIZE_MEDIUM ;
597                 break ;
598         default:
599                 cr_utils_trace_info ("Unknown FONT_SIZE") ;
600                 result = FONT_SIZE_MEDIUM ;
601                 break ;
602         }
603         *a_smaller_size = result ;
604 }
605 
606 
607 /**
608  * cr_font_size_get_larger_predefined_font_size:
609  * @a_font_size: the font size to consider.
610  * @a_larger_size: out parameter. the font size considered larger than
611  * @a_font_size.
612  *
613  */
614 void
cr_font_size_get_larger_predefined_font_size(enum CRPredefinedAbsoluteFontSize a_font_size,enum CRPredefinedAbsoluteFontSize * a_larger_size)615 cr_font_size_get_larger_predefined_font_size
616 			(enum CRPredefinedAbsoluteFontSize a_font_size,
617 		         enum CRPredefinedAbsoluteFontSize *a_larger_size)
618 {
619         enum CRPredefinedAbsoluteFontSize result = FONT_SIZE_MEDIUM ;
620 
621         g_return_if_fail (a_larger_size) ;
622         g_return_if_fail (a_font_size >= FONT_SIZE_XX_SMALL
623                           && a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) ;
624 
625         switch (a_font_size) {
626         case FONT_SIZE_XX_SMALL:
627                 result =  FONT_SIZE_X_SMALL ;
628                 break ;
629         case FONT_SIZE_X_SMALL:
630                 result =  FONT_SIZE_SMALL ;
631                 break ;
632         case FONT_SIZE_SMALL:
633                 result =  FONT_SIZE_MEDIUM;
634                 break ;
635         case FONT_SIZE_MEDIUM:
636                 result =  FONT_SIZE_LARGE;
637                 break ;
638         case FONT_SIZE_LARGE:
639                 result =  FONT_SIZE_X_LARGE;
640                 break ;
641         case FONT_SIZE_X_LARGE:
642                 result =  FONT_SIZE_XX_LARGE ;
643                 break ;
644         case FONT_SIZE_XX_LARGE:
645                 result =  FONT_SIZE_XX_LARGE;
646                 break ;
647 	case FONT_SIZE_INHERIT:
648                 cr_utils_trace_info ("can't return a bigger size for FONT_SIZE_INHERIT") ;
649                 result =  FONT_SIZE_MEDIUM ;
650                 break ;
651         default:
652                 cr_utils_trace_info ("Unknown FONT_SIZE") ;
653                 result = FONT_SIZE_MEDIUM ;
654                 break ;
655         }
656         *a_larger_size = result ;
657 }
658 
659 /**
660  * cr_font_size_is_predefined_absolute_font_size:
661  * @a_font_size: the font size to consider.
662  *
663  * Returns TRUE if the instance is an predefined absolute font size, FALSE
664  * otherwise.
665  */
666 gboolean
cr_font_size_is_predefined_absolute_font_size(enum CRPredefinedAbsoluteFontSize a_font_size)667 cr_font_size_is_predefined_absolute_font_size
668 				(enum CRPredefinedAbsoluteFontSize a_font_size)
669 {
670         if (a_font_size >= FONT_SIZE_XX_SMALL
671             && a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) {
672                 return TRUE ;
673         } else {
674                 return FALSE ;
675         }
676 }
677 
678 /**
679  * cr_font_size_adjust_to_string:
680  * @a_this: the instance of #CRFontSizeAdjust.
681  *
682  * Returns the serialized form of #CRFontSizeAdjust
683  */
684 gchar *
cr_font_size_adjust_to_string(CRFontSizeAdjust const * a_this)685 cr_font_size_adjust_to_string (CRFontSizeAdjust const * a_this)
686 {
687         gchar *str = NULL;
688 
689         if (!a_this) {
690                 str = g_strdup ("NULL");
691                 g_return_val_if_fail (str, NULL);
692                 return str;
693         }
694 
695         switch (a_this->type) {
696         case FONT_SIZE_ADJUST_NONE:
697                 str = g_strdup ("none");
698                 break;
699         case FONT_SIZE_ADJUST_NUMBER:
700                 if (a_this->num)
701                         str = (gchar *) cr_num_to_string (a_this->num);
702                 else
703                         str = g_strdup ("unknown font-size-adjust property value"); /* Should raise an error no?*/
704                 break;
705         case FONT_SIZE_ADJUST_INHERIT:
706                 str = g_strdup ("inherit");
707         }
708         return str;
709 }
710 
711 /**
712  * cr_font_style_to_string:
713  * @a_code: the current instance of #CRFontStyle .
714  *
715  * Returns the serialized #CRFontStyle. The caller must free the returned
716  * string using g_free().
717  */
718 const gchar *
cr_font_style_to_string(enum CRFontStyle a_code)719 cr_font_style_to_string (enum CRFontStyle a_code)
720 {
721         gchar *str = NULL;
722 
723         switch (a_code) {
724         case FONT_STYLE_NORMAL:
725                 str = (gchar *) "normal";
726                 break;
727         case FONT_STYLE_ITALIC:
728                 str = (gchar *) "italic";
729                 break;
730         case FONT_STYLE_OBLIQUE:
731                 str = (gchar *) "oblique";
732                 break;
733         case FONT_STYLE_INHERIT:
734                 str = (gchar *) "inherit";
735                 break;
736         default:
737                 str = (gchar *) "unknown font style value";
738                 break;
739         }
740         return str;
741 }
742 
743 /**
744  * cr_font_variant_to_string:
745  * @a_code: the current instance of #CRFontVariant.
746  *
747  * Returns the serialized form of #CRFontVariant. The caller has
748  * to free the returned string using g_free().
749  */
750 const gchar *
cr_font_variant_to_string(enum CRFontVariant a_code)751 cr_font_variant_to_string (enum CRFontVariant a_code)
752 {
753         gchar *str = NULL;
754 
755         switch (a_code) {
756         case FONT_VARIANT_NORMAL:
757                 str = (gchar *) "normal";
758                 break;
759         case FONT_VARIANT_SMALL_CAPS:
760                 str = (gchar *) "small-caps";
761                 break;
762         case FONT_VARIANT_INHERIT:
763                 str = (gchar *) "inherit";
764                 break;
765         }
766         return str;
767 }
768 
769 /**
770  * cr_font_weight_get_bolder:
771  * @a_weight: the #CRFontWeight to consider.
772  *
773  * Returns a font weight bolder than @a_weight
774  */
775 enum CRFontWeight
cr_font_weight_get_bolder(enum CRFontWeight a_weight)776 cr_font_weight_get_bolder (enum CRFontWeight a_weight)
777 {
778         if (a_weight == FONT_WEIGHT_INHERIT) {
779                 cr_utils_trace_info ("can't return a bolder weight for FONT_WEIGHT_INHERIT") ;
780                 return a_weight;
781         } else if (a_weight >= FONT_WEIGHT_900) {
782                 return FONT_WEIGHT_900 ;
783         } else if (a_weight < FONT_WEIGHT_NORMAL) {
784                 return FONT_WEIGHT_NORMAL ;
785         } else if (a_weight == FONT_WEIGHT_BOLDER
786                    || a_weight == FONT_WEIGHT_LIGHTER) {
787                 cr_utils_trace_info ("FONT_WEIGHT_BOLDER or FONT_WEIGHT_LIGHTER should not appear here") ;
788                 return FONT_WEIGHT_NORMAL ;
789         } else {
790                 return a_weight << 1 ;
791         }
792 }
793 
794 /**
795  * cr_font_weight_to_string:
796  * @a_code: the font weight to consider.
797  *
798  * Returns the serialized form of #CRFontWeight.
799  */
800 const gchar *
cr_font_weight_to_string(enum CRFontWeight a_code)801 cr_font_weight_to_string (enum CRFontWeight a_code)
802 {
803         gchar *str = NULL;
804 
805         switch (a_code) {
806         case FONT_WEIGHT_NORMAL:
807                 str = (gchar *) "normal";
808                 break;
809         case FONT_WEIGHT_BOLD:
810                 str = (gchar *) "bold";
811                 break;
812         case FONT_WEIGHT_BOLDER:
813                 str = (gchar *) "bolder";
814                 break;
815         case FONT_WEIGHT_LIGHTER:
816                 str = (gchar *) "lighter";
817                 break;
818         case FONT_WEIGHT_100:
819                 str = (gchar *) "100";
820                 break;
821         case FONT_WEIGHT_200:
822                 str = (gchar *) "200";
823                 break;
824         case FONT_WEIGHT_300:
825                 str = (gchar *) "300";
826                 break;
827         case FONT_WEIGHT_400:
828                 str = (gchar *) "400";
829                 break;
830         case FONT_WEIGHT_500:
831                 str = (gchar *) "500";
832                 break;
833         case FONT_WEIGHT_600:
834                 str = (gchar *) "600";
835                 break;
836         case FONT_WEIGHT_700:
837                 str = (gchar *) "700";
838                 break;
839         case FONT_WEIGHT_800:
840                 str = (gchar *) "800";
841                 break;
842         case FONT_WEIGHT_900:
843                 str = (gchar *) "900";
844                 break;
845         case FONT_WEIGHT_INHERIT:
846                 str = (gchar *) "inherit";
847                 break;
848         default:
849                 str = (gchar *) "unknown font-weight property value";
850                 break;
851         }
852         return str;
853 }
854 
855 /**
856  * cr_font_stretch_to_string:
857  * @a_code: the instance of #CRFontStretch to consider.
858  *
859  * Returns the serialized form of #CRFontStretch.
860  */
861 const gchar *
cr_font_stretch_to_string(enum CRFontStretch a_code)862 cr_font_stretch_to_string (enum CRFontStretch a_code)
863 {
864         gchar *str = NULL;
865 
866         switch (a_code) {
867         case FONT_STRETCH_NORMAL:
868                 str = (gchar *) "normal";
869                 break;
870         case FONT_STRETCH_WIDER:
871                 str = (gchar *) "wider";
872                 break;
873         case FONT_STRETCH_NARROWER:
874                 str = (gchar *) "narrower";
875                 break;
876         case FONT_STRETCH_ULTRA_CONDENSED:
877                 str = (gchar *) "ultra-condensed";
878                 break;
879         case FONT_STRETCH_EXTRA_CONDENSED:
880                 str = (gchar *) "extra-condensed";
881                 break;
882         case FONT_STRETCH_CONDENSED:
883                 str = (gchar *) "condensed";
884                 break;
885         case FONT_STRETCH_SEMI_CONDENSED:
886                 str = (gchar *) "semi-condensed";
887                 break;
888         case FONT_STRETCH_SEMI_EXPANDED:
889                 str = (gchar *) "semi-expanded";
890                 break;
891         case FONT_STRETCH_EXPANDED:
892                 str = (gchar *) "expanded";
893                 break;
894         case FONT_STRETCH_EXTRA_EXPANDED:
895                 str = (gchar *) "extra-expaned";
896                 break;
897         case FONT_STRETCH_ULTRA_EXPANDED:
898                 str = (gchar *) "ultra-expanded";
899                 break;
900         case FONT_STRETCH_INHERIT:
901                 str = (gchar *) "inherit";
902                 break;
903         }
904         return str;
905 }
906 
907 /**
908  * cr_font_size_destroy:
909  * @a_font_size: the font size to destroy
910  *
911  */
912 void
cr_font_size_destroy(CRFontSize * a_font_size)913 cr_font_size_destroy (CRFontSize * a_font_size)
914 {
915         g_return_if_fail (a_font_size);
916 
917         g_free (a_font_size) ;
918 }
919 
920 /*******************************************************
921  *'font-size-adjust' manipulation function definition
922  *******************************************************/
923 
924 /**
925  * cr_font_size_adjust_new:
926  *
927  * Returns a newly built instance of #CRFontSizeAdjust
928  */
929 CRFontSizeAdjust *
cr_font_size_adjust_new(void)930 cr_font_size_adjust_new (void)
931 {
932         CRFontSizeAdjust *result = NULL;
933 
934         result = g_try_malloc (sizeof (CRFontSizeAdjust));
935         if (!result) {
936                 cr_utils_trace_info ("Out of memory");
937                 return NULL;
938         }
939         memset (result, 0, sizeof (CRFontSizeAdjust));
940 
941         return result;
942 }
943 
944 /**
945  * cr_font_size_adjust_destroy:
946  * @a_this: the current instance of #CRFontSizeAdjust.
947  *
948  */
949 void
cr_font_size_adjust_destroy(CRFontSizeAdjust * a_this)950 cr_font_size_adjust_destroy (CRFontSizeAdjust * a_this)
951 {
952         g_return_if_fail (a_this);
953 
954         if (a_this->type == FONT_SIZE_ADJUST_NUMBER && a_this->num) {
955                 cr_num_destroy (a_this->num);
956                 a_this->num = NULL;
957         }
958 }
959