Code

Node tool: fix handle retraction with non-cusp nodes
[inkscape.git] / src / libcroco / cr-fonts.c
1 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
3 /*
4  * This file is part of The Croco Library
5  *
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of version 2.1 of 
9  * the GNU Lesser General Public
10  * License as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the 
18  * GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21  * USA
22  *
23  *See COPYRIGHTS file for copyright information
24  */
26 #include "cr-fonts.h"
27 #include <string.h>
29 static enum CRStatus
30 cr_font_family_to_string_real (CRFontFamily * a_this,
31                                gboolean a_walk_list, GString ** a_string)
32 {
33         gchar *name = NULL;
34         enum CRStatus result = CR_OK;
36         if (!*a_string) {
37                 *a_string = g_string_new (NULL);
38                 g_return_val_if_fail (*a_string,
39                                       CR_INSTANCIATION_FAILED_ERROR);
40         }
42         if (!a_this) {
43                 g_string_append (*a_string, "NULL");
44                 return CR_OK;
45         }
47         switch (a_this->type) {
48         case FONT_FAMILY_SANS_SERIF:
49                 name = (gchar *) "sans-serif";
50                 break;
52         case FONT_FAMILY_SERIF:
53                 name = (gchar *) "sans-serif";
54                 break;
56         case FONT_FAMILY_CURSIVE:
57                 name = (gchar *) "cursive";
58                 break;
60         case FONT_FAMILY_FANTASY:
61                 name = (gchar *) "fantasy";
62                 break;
64         case FONT_FAMILY_MONOSPACE:
65                 name = (gchar *) "monospace";
66                 break;
68         case FONT_FAMILY_NON_GENERIC:
69                 name = (gchar *) a_this->name;
70                 break;
72         default:
73                 name = (gchar *) NULL;
74                 break;
75         }
77         if (name) {
78                 if (a_this->prev) {
79                         g_string_append_printf (*a_string, ", %s", name);
80                 } else {
81                         g_string_append (*a_string, name);
82                 }
83         }
84         if (a_walk_list == TRUE && a_this->next) {
85                 result = cr_font_family_to_string_real (a_this->next,
86                                                         TRUE, a_string);
87         }
88         return result;
89 }
91 static const gchar *
92 cr_predefined_absolute_font_size_to_string (enum CRPredefinedAbsoluteFontSize
93                                             a_code)
94 {
95         gchar *str = NULL;
97         switch (a_code) {
98         case FONT_SIZE_XX_SMALL:
99                 str = (gchar *) "xx-small";
100                 break;
101         case FONT_SIZE_X_SMALL:
102                 str = (gchar *) "x-small";
103                 break;
104         case FONT_SIZE_SMALL:
105                 str = (gchar *) "small";
106                 break;
107         case FONT_SIZE_MEDIUM:
108                 str = (gchar *) "medium";
109                 break;
110         case FONT_SIZE_LARGE:
111                 str = (gchar *) "large";
112                 break;
113         case FONT_SIZE_X_LARGE:
114                 str = (gchar *) "x-large";
115                 break;
116         case FONT_SIZE_XX_LARGE:
117                 str = (gchar *) "xx-large";
118                 break;
119         default:
120                 str = (gchar *) "unknown absolute font size value";
121         }
122         return str;
125 static const gchar *
126 cr_relative_font_size_to_string (enum CRRelativeFontSize a_code)
128         gchar *str = NULL;
130         switch (a_code) {
131         case FONT_SIZE_LARGER:
132                 str = (gchar *) "larger";
133                 break;
134         case FONT_SIZE_SMALLER:
135                 str = (gchar *) "smaller";
136                 break;
137         default:
138                 str = (gchar *) "unknown relative font size value";
139                 break;
140         }
141         return str;
144 CRFontFamily *
145 cr_font_family_new (enum CRFontFamilyType a_type, guchar * a_name)
147         CRFontFamily *result = (CRFontFamily *)g_try_malloc (sizeof (CRFontFamily));
149         if (!result) {
150                 cr_utils_trace_info ("Out of memory");
151                 return NULL;
152         }
154         memset (result, 0, sizeof (CRFontFamily));
155         result->type = a_type;
157         cr_font_family_set_name (result, a_name);
159         return result;
162 guchar *
163 cr_font_family_to_string (CRFontFamily * a_this,
164                           gboolean a_walk_font_family_list)
166         enum CRStatus status = CR_OK;
167         gchar *result = NULL;
168         GString *stringue = NULL;
170         if (!a_this) {
171                 result = g_strdup ("NULL");
172                 g_return_val_if_fail (result, NULL);
173                 return (guchar *)result;
174         }
175         status = cr_font_family_to_string_real (a_this,
176                                                 a_walk_font_family_list,
177                                                 &stringue);
179         if (status == CR_OK && stringue) {
180                 result = stringue->str;
181                 g_string_free (stringue, FALSE);
182                 stringue = NULL;
184         } else {
185                 if (stringue) {
186                         g_string_free (stringue, TRUE);
187                         stringue = NULL;
188                 }
189         }
191         return (guchar *)result;
193 enum CRStatus
194 cr_font_family_set_name (CRFontFamily * a_this, guchar * a_name)
196         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
198         /*
199          *only non generic font families can have a name
200          */
202         if (a_this->type != FONT_FAMILY_NON_GENERIC) {
203                 return CR_BAD_PARAM_ERROR;
204         }
206         if (a_this->name) {
207                 g_free (a_this->name);
208                 a_this->name = NULL;
209         }
211         a_this->name = a_name;
212         return CR_OK;
215 CRFontFamily *
216 cr_font_family_append (CRFontFamily * a_this,
217                        CRFontFamily * a_family_to_append)
219         CRFontFamily *cur_ff = NULL;
221         g_return_val_if_fail (a_family_to_append, NULL);
223         if (!a_this)
224                 return a_family_to_append;
226         for (cur_ff = a_this; cur_ff && cur_ff->next; cur_ff = cur_ff->next) ;
228         cur_ff->next = a_family_to_append;
229         a_family_to_append->prev = cur_ff;
231         return a_this;
235 CRFontFamily *
236 cr_font_family_prepend (CRFontFamily * a_this,
237                         CRFontFamily * a_family_to_prepend)
239         g_return_val_if_fail (a_this && a_family_to_prepend, NULL);
241         if (!a_this)
242                 return a_family_to_prepend;
244         a_family_to_prepend->next = a_this;
245         a_this->prev = a_family_to_prepend;
247         return a_family_to_prepend;
250 enum CRStatus
251 cr_font_family_destroy (CRFontFamily * a_this)
253         CRFontFamily *cur_ff = NULL;
255         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
257         for (cur_ff = a_this; cur_ff && cur_ff->next; cur_ff = cur_ff->next) ;
259         for (; cur_ff; cur_ff = cur_ff->prev) {
260                 if (a_this->name) {
261                         g_free (a_this->name);
262                         a_this->name = NULL;
263                 }
265                 if (cur_ff->next) {
266                         g_free (cur_ff->next);
268                 }
270                 if (cur_ff->prev == NULL) {
271                         g_free (a_this);
272                 }
273         }
275         return CR_OK;
278 /***************************************************
279  *'font-size' manipulation functions definitions
280  ***************************************************/
282 CRFontSize *
283 cr_font_size_new (void)
285         CRFontSize *result = (CRFontSize *)g_try_malloc (sizeof (CRFontSize));
286         if (!result) {
287                 cr_utils_trace_info ("Out of memory");
288                 return NULL;
289         }
290         memset (result, 0, sizeof (CRFontSize));
292         return result;
295 enum CRStatus
296 cr_font_size_clear (CRFontSize * a_this)
298         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
300         switch (a_this->type) {
301         case PREDEFINED_ABSOLUTE_FONT_SIZE:
302         case RELATIVE_FONT_SIZE:
303         case INHERITED_FONT_SIZE:
304                 memset (a_this, 0, sizeof (CRFontSize));
305                 break;
307         case ABSOLUTE_FONT_SIZE:
308                 memset (a_this, 0, sizeof (CRFontSize));
309                 break;
311         default:
312                 return CR_UNKNOWN_TYPE_ERROR;
313         }
315         return CR_OK;
318 enum CRStatus
319 cr_font_size_copy (CRFontSize * a_dst, CRFontSize * a_src)
321         g_return_val_if_fail (a_dst && a_src, CR_BAD_PARAM_ERROR);
323         switch (a_src->type) {
324         case PREDEFINED_ABSOLUTE_FONT_SIZE:
325         case RELATIVE_FONT_SIZE:
326         case INHERITED_FONT_SIZE:
327                 cr_font_size_clear (a_dst);
328                 memcpy (a_dst, a_src, sizeof (CRFontSize));
329                 break;
331         case ABSOLUTE_FONT_SIZE:
332                 cr_font_size_clear (a_dst);
333                 cr_num_copy (&a_dst->value.absolute,
334                              &a_src->value.absolute);
335                 a_dst->type = a_src->type;
336                 break;
338         default:
339                 return CR_UNKNOWN_TYPE_ERROR;
340         }
341         return CR_OK;
344 enum CRStatus 
345 cr_font_size_set_predefined_absolute_font_size (CRFontSize *a_this, 
346                                                 enum CRPredefinedAbsoluteFontSize a_predefined)
348         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
349         g_return_val_if_fail ((unsigned)a_predefined < NB_FONT_SIZE_TYPE,
350                               CR_BAD_PARAM_ERROR) ;
352         a_this->type = PREDEFINED_ABSOLUTE_FONT_SIZE ;
353         a_this->value.predefined = a_predefined ;
355         return CR_OK ;
358 enum CRStatus 
359 cr_font_size_set_relative_font_size (CRFontSize *a_this,
360                                      enum CRRelativeFontSize a_relative)
362         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
363         g_return_val_if_fail ((unsigned)a_relative < NB_RELATIVE_FONT_SIZE,
364                               CR_BAD_PARAM_ERROR) ;
365         
366         a_this->type = RELATIVE_FONT_SIZE ;
367         a_this->value.relative = a_relative ;
368         return CR_OK ;
371 enum CRStatus 
372 cr_font_size_set_absolute_font_size (CRFontSize *a_this,
373                                      enum CRNumType a_num_type,
374                                      gdouble a_value)
376         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
377         g_return_val_if_fail ((unsigned)a_num_type < NB_NUM_TYPE,
378                               CR_BAD_PARAM_ERROR) ;
380         a_this->type = ABSOLUTE_FONT_SIZE ;
381         cr_num_set (&a_this->value.absolute,
382                     a_value, a_num_type) ;        
383         return CR_OK ;
386 enum CRStatus
387 cr_font_size_set_to_inherit (CRFontSize *a_this)
389         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
391         cr_font_size_clear (a_this) ;
392         a_this->type = INHERITED_FONT_SIZE ;
394         return CR_OK ;
397 gboolean
398 cr_font_size_is_set_to_inherit (CRFontSize *a_this)
400         g_return_val_if_fail (a_this, FALSE) ;
402         return a_this->type == INHERITED_FONT_SIZE ;
405 gchar *
406 cr_font_size_to_string (CRFontSize * a_this)
408         gchar *str = NULL;
410         if (!a_this) {
411                 str = g_strdup ("NULL");
412                 g_return_val_if_fail (str, NULL);
413                 return str;
414         }
415         switch (a_this->type) {
416         case PREDEFINED_ABSOLUTE_FONT_SIZE:
417                 str = g_strdup (cr_predefined_absolute_font_size_to_string
418                                 (a_this->value.predefined));
419                 break;
420         case ABSOLUTE_FONT_SIZE:
421                 str = (gchar *)cr_num_to_string (&a_this->value.absolute);
422                 break;
423         case RELATIVE_FONT_SIZE:
424                 str = g_strdup (cr_relative_font_size_to_string
425                                 (a_this->value.relative));
426                 break;
427         case INHERITED_FONT_SIZE:
428                 str = g_strdup ("inherit");
429                 break;
430         default:
431                 break;
432         }
433         return str;
436 void 
437 cr_font_size_get_smaller_predefined_font_size (enum CRPredefinedAbsoluteFontSize a_font_size,
438                                                enum CRPredefinedAbsoluteFontSize *a_smaller_size)
440         enum CRPredefinedAbsoluteFontSize result = FONT_SIZE_MEDIUM ;
442         g_return_if_fail (a_smaller_size) ;
443         g_return_if_fail ((unsigned)a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) ;
445         switch (a_font_size) {
446         case FONT_SIZE_XX_SMALL:
447                 result =  FONT_SIZE_XX_SMALL ;
448                 break ;
449         case FONT_SIZE_X_SMALL:
450                 result =  FONT_SIZE_XX_SMALL ;
451                 break ;
452         case FONT_SIZE_SMALL:
453                 result =  FONT_SIZE_X_SMALL;
454                 break ;
455         case FONT_SIZE_MEDIUM:
456                 result =  FONT_SIZE_SMALL;
457                 break ;
458         case FONT_SIZE_LARGE:
459                 result =  FONT_SIZE_MEDIUM;
460                 break ;
461         case FONT_SIZE_X_LARGE:
462                 result =  FONT_SIZE_LARGE;
463                 break ;
464         case FONT_SIZE_XX_LARGE:
465                 result =  FONT_SIZE_XX_LARGE;
466                 break ;
467         case FONT_SIZE_INHERIT:
468                 cr_utils_trace_info ("can't return a smaller size for FONT_SIZE_INHERIT") ;                
469                 result =  FONT_SIZE_MEDIUM ;
470                 break ;
471         default:
472                 cr_utils_trace_info ("Unknown FONT_SIZE") ;
473                 result = FONT_SIZE_MEDIUM ;
474                 break ;
475         }
476         *a_smaller_size = result ;
480 void 
481 cr_font_size_get_larger_predefined_font_size (enum CRPredefinedAbsoluteFontSize a_font_size,
482                                               enum CRPredefinedAbsoluteFontSize *a_larger_size)
484         enum CRPredefinedAbsoluteFontSize result = FONT_SIZE_MEDIUM ;
485         
486         g_return_if_fail (a_larger_size) ;
487         g_return_if_fail ((unsigned)a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) ;
489         switch (a_font_size) {
490         case FONT_SIZE_XX_SMALL:
491                 result =  FONT_SIZE_X_SMALL ;
492                 break ;
493         case FONT_SIZE_X_SMALL:
494                 result =  FONT_SIZE_SMALL ;
495                 break ;
496         case FONT_SIZE_SMALL:
497                 result =  FONT_SIZE_MEDIUM;
498                 break ;
499         case FONT_SIZE_MEDIUM:
500                 result =  FONT_SIZE_LARGE;
501                 break ;
502         case FONT_SIZE_LARGE:
503                 result =  FONT_SIZE_X_LARGE;
504                 break ;
505         case FONT_SIZE_X_LARGE:
506                 result =  FONT_SIZE_XX_LARGE ;
507                 break ;
508         case FONT_SIZE_XX_LARGE:
509                 result =  FONT_SIZE_XX_LARGE;
510                 break ;
511         case FONT_SIZE_INHERIT:
512                 cr_utils_trace_info ("can't return a bigger size for FONT_SIZE_INHERIT") ;                
513                 result =  FONT_SIZE_MEDIUM ;
514                 break ;
515         default:
516                 cr_utils_trace_info ("Unknown FONT_SIZE") ;
517                 result = FONT_SIZE_MEDIUM ;
518                 break ;
519         }
520         *a_larger_size = result ;
523 gboolean
524 cr_font_size_is_predefined_absolute_font_size (enum CRPredefinedAbsoluteFontSize a_font_size)
526         if ((unsigned)a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) {
527                 return TRUE ;
528         } else {
529                 return FALSE ;
530         }
533 gchar *
534 cr_font_size_adjust_to_string (CRFontSizeAdjust * a_this)
536         gchar *str = NULL;
538         if (!a_this) {
539                 str = g_strdup ("NULL");
540                 g_return_val_if_fail (str, NULL);
541                 return str;
542         }
544         switch (a_this->type) {
545         case FONT_SIZE_ADJUST_NONE:
546                 str = g_strdup ("none");
547                 break;
548         case FONT_SIZE_ADJUST_NUMBER:
549                 if (a_this->num)
550                         str = (gchar *)cr_num_to_string (a_this->num);
551                 else
552                         str = g_strdup ("unknow font-size-adjust property value"); // Should raise an error no?
553                 break;
554         case FONT_SIZE_ADJUST_INHERIT:
555                 str = g_strdup ("inherit");
556         }
557         return str;
560 const gchar *
561 cr_font_style_to_string (enum CRFontStyle a_code)
563         gchar *str = NULL;
565         switch (a_code) {
566         case FONT_STYLE_NORMAL:
567                 str = (gchar *) "normal";
568                 break;
569         case FONT_STYLE_ITALIC:
570                 str = (gchar *) "italic";
571                 break;
572         case FONT_STYLE_OBLIQUE:
573                 str = (gchar *) "oblique";
574                 break;
575         case FONT_STYLE_INHERIT:
576                 str = (gchar *) "inherit";
577                 break;
578         default:
579                 str = (gchar *) "unknown font style value";
580                 break;
581         }
582         return str;
585 const gchar *
586 cr_font_variant_to_string (enum CRFontVariant a_code)
588         gchar *str = NULL;
590         switch (a_code) {
591         case FONT_VARIANT_NORMAL:
592                 str = (gchar *) "normal";
593                 break;
594         case FONT_VARIANT_SMALL_CAPS:
595                 str = (gchar *) "small-caps";
596                 break;
597         case FONT_VARIANT_INHERIT:
598                 str = (gchar *) "inherit";
599                 break;
600         }
601         return str;
604 enum CRFontWeight
605 cr_font_weight_get_bolder (enum CRFontWeight a_weight)
607         if (a_weight >= NB_FONT_WEIGHTS) {
608                 return FONT_WEIGHT_900 ;
609         } else if (a_weight < FONT_WEIGHT_NORMAL) {
610                 return FONT_WEIGHT_NORMAL ;
611         } else if (a_weight == FONT_WEIGHT_BOLDER
612                    || a_weight == FONT_WEIGHT_BOLDER) {
613                 cr_utils_trace_info ("FONT_WEIGHT_BOLDER or FONT_WEIGHT_LIGHTER should not appear here") ;
614                 return FONT_WEIGHT_NORMAL ;
615         } else {
616                 return (enum CRFontWeight)(a_weight << 1) ;
617         }
620 const gchar *
621 cr_font_weight_to_string (enum CRFontWeight a_code)
623         gchar *str = NULL;
625         switch (a_code) {
626         case FONT_WEIGHT_NORMAL:
627                 str = (gchar *) "normal";
628                 break;
629         case FONT_WEIGHT_BOLD:
630                 str = (gchar *) "bold";
631                 break;
632         case FONT_WEIGHT_BOLDER:
633                 str = (gchar *) "bolder";
634                 break;
635         case FONT_WEIGHT_LIGHTER:
636                 str = (gchar *) "lighter";
637                 break;
638         case FONT_WEIGHT_100:
639                 str = (gchar *) "100";
640                 break;
641         case FONT_WEIGHT_200:
642                 str = (gchar *) "200";
643                 break;
644         case FONT_WEIGHT_300:
645                 str = (gchar *) "300";
646                 break;
647         case FONT_WEIGHT_400:
648                 str = (gchar *) "400";
649                 break;
650         case FONT_WEIGHT_500:
651                 str = (gchar *) "500";
652                 break;
653         case FONT_WEIGHT_600:
654                 str = (gchar *) "600";
655                 break;
656         case FONT_WEIGHT_700:
657                 str = (gchar *) "700";
658                 break;
659         case FONT_WEIGHT_800:
660                 str = (gchar *) "800";
661                 break;
662         case FONT_WEIGHT_900:
663                 str = (gchar *) "900";
664                 break;
665         case FONT_WEIGHT_INHERIT:
666                 str = (gchar *) "inherit";
667                 break;
668         default:
669                 str = (gchar *) "unknown font-weight property value";
670                 break;
671         }
672         return str;
675 const gchar *
676 cr_font_stretch_to_string (enum CRFontStretch a_code)
678         gchar *str = NULL;
680         switch (a_code) {
681         case FONT_STRETCH_NORMAL:
682                 str = (gchar *) "normal";
683                 break;
684         case FONT_STRETCH_WIDER:
685                 str = (gchar *) "wider";
686                 break;
687         case FONT_STRETCH_NARROWER:
688                 str = (gchar *) "narrower";
689                 break;
690         case FONT_STRETCH_ULTRA_CONDENSED:
691                 str = (gchar *) "ultra-condensed";
692                 break;
693         case FONT_STRETCH_EXTRA_CONDENSED:
694                 str = (gchar *) "extra-condensed";
695                 break;
696         case FONT_STRETCH_CONDENSED:
697                 str = (gchar *) "condensed";
698                 break;
699         case FONT_STRETCH_SEMI_CONDENSED:
700                 str = (gchar *) "semi-condensed";
701                 break;
702         case FONT_STRETCH_SEMI_EXPANDED:
703                 str = (gchar *) "semi-expanded";
704                 break;
705         case FONT_STRETCH_EXPANDED:
706                 str = (gchar *) "expanded";
707                 break;
708         case FONT_STRETCH_EXTRA_EXPANDED:
709                 str = (gchar *) "extra-expaned";
710                 break;
711         case FONT_STRETCH_ULTRA_EXPANDED:
712                 str = (gchar *) "ultra-expanded";
713                 break;
714         case FONT_STRETCH_INHERIT:
715                 str = (gchar *) "inherit";
716                 break;
717         }
718         return str;
721 void
722 cr_font_size_destroy (CRFontSize * a_font_size)
724         g_return_if_fail (a_font_size);
726         g_free (a_font_size) ;
729 /*******************************************************
730  *'font-size-adjust' manipulation function definition
731  *******************************************************/
733 CRFontSizeAdjust *
734 cr_font_size_adjust_new (void)
736         CRFontSizeAdjust *result =
737                      (CRFontSizeAdjust *)g_try_malloc (sizeof (CRFontSizeAdjust));
738         if (!result) {
739                 cr_utils_trace_info ("Out of memory");
740                 return NULL;
741         }
742         memset (result, 0, sizeof (CRFontSizeAdjust));
744         return result;
747 void
748 cr_font_size_adjust_destroy (CRFontSizeAdjust * a_this)
750         g_return_if_fail (a_this);
752         if (a_this->type == FONT_SIZE_ADJUST_NUMBER && a_this->num) {
753                 cr_num_destroy (a_this->num);
754                 a_this->num = NULL;
755         }