PageRenderTime 77ms CodeModel.GetById 19ms app.highlight 53ms RepoModel.GetById 1ms app.codeStats 1ms

/cssed-0.4.0/libcroco/parser/cr-fonts.c

#
C | 767 lines | 629 code | 106 blank | 32 comment | 70 complexity | f47dbac36271c8b01c2f82cc5c04471f MD5 | raw file
  1/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
  2
  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 */
 25
 26#include "cr-fonts.h"
 27#include <string.h>
 28
 29static enum CRStatus
 30cr_font_family_to_string_real (CRFontFamily * a_this,
 31                               gboolean a_walk_list, GString ** a_string)
 32{
 33        guchar *name = NULL;
 34        enum CRStatus result = CR_OK;
 35
 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        }
 41
 42        if (!a_this) {
 43                g_string_append (*a_string, "NULL");
 44                return CR_OK;
 45        }
 46
 47        switch (a_this->type) {
 48        case FONT_FAMILY_SANS_SERIF:
 49                name = (guchar *) "sans-serif";
 50                break;
 51
 52        case FONT_FAMILY_SERIF:
 53                name = (guchar *) "sans-serif";
 54                break;
 55
 56        case FONT_FAMILY_CURSIVE:
 57                name = (guchar *) "cursive";
 58                break;
 59
 60        case FONT_FAMILY_FANTASY:
 61                name = (guchar *) "fantasy";
 62                break;
 63
 64        case FONT_FAMILY_MONOSPACE:
 65                name = (guchar *) "monospace";
 66                break;
 67
 68        case FONT_FAMILY_NON_GENERIC:
 69                name = (guchar *) a_this->name;
 70                break;
 71
 72        default:
 73                name = (guchar *) NULL;
 74                break;
 75        }
 76
 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}
 90
 91static const gchar *
 92cr_predefined_absolute_font_size_to_string (enum CRPredefinedAbsoluteFontSize
 93                                            a_code)
 94{
 95        gchar *str = NULL;
 96
 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;
123}
124
125static const gchar *
126cr_relative_font_size_to_string (enum CRRelativeFontSize a_code)
127{
128        gchar *str = NULL;
129
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;
142}
143
144CRFontFamily *
145cr_font_family_new (enum CRFontFamilyType a_type, guchar * a_name)
146{
147        CRFontFamily *result = NULL;
148
149        result = g_try_malloc (sizeof (CRFontFamily));
150
151        if (!result) {
152                cr_utils_trace_info ("Out of memory");
153                return NULL;
154        }
155
156        memset (result, 0, sizeof (CRFontFamily));
157        result->type = a_type;
158
159        cr_font_family_set_name (result, a_name);
160
161        return result;
162}
163
164guchar *
165cr_font_family_to_string (CRFontFamily * a_this,
166                          gboolean a_walk_font_family_list)
167{
168        enum CRStatus status = CR_OK;
169        guchar *result = NULL;
170        GString *stringue = NULL;
171
172        if (!a_this) {
173                result = g_strdup ("NULL");
174                g_return_val_if_fail (result, NULL);
175                return result;
176        }
177        status = cr_font_family_to_string_real (a_this,
178                                                a_walk_font_family_list,
179                                                &stringue);
180
181        if (status == CR_OK && stringue) {
182                result = stringue->str;
183                g_string_free (stringue, FALSE);
184                stringue = NULL;
185
186        } else {
187                if (stringue) {
188                        g_string_free (stringue, TRUE);
189                        stringue = NULL;
190                }
191        }
192
193        return result;
194}
195enum CRStatus
196cr_font_family_set_name (CRFontFamily * a_this, guchar * a_name)
197{
198        g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
199
200        /*
201         *only non generic font families can have a name
202         */
203
204        if (a_this->type != FONT_FAMILY_NON_GENERIC) {
205                return CR_BAD_PARAM_ERROR;
206        }
207
208        if (a_this->name) {
209                g_free (a_this->name);
210                a_this->name = NULL;
211        }
212
213        a_this->name = a_name;
214        return CR_OK;
215}
216
217CRFontFamily *
218cr_font_family_append (CRFontFamily * a_this,
219                       CRFontFamily * a_family_to_append)
220{
221        CRFontFamily *cur_ff = NULL;
222
223        g_return_val_if_fail (a_family_to_append, NULL);
224
225        if (!a_this)
226                return a_family_to_append;
227
228        for (cur_ff = a_this; cur_ff && cur_ff->next; cur_ff = cur_ff->next) ;
229
230        cur_ff->next = a_family_to_append;
231        a_family_to_append->prev = cur_ff;
232
233        return a_this;
234
235}
236
237CRFontFamily *
238cr_font_family_prepend (CRFontFamily * a_this,
239                        CRFontFamily * a_family_to_prepend)
240{
241        g_return_val_if_fail (a_this && a_family_to_prepend, NULL);
242
243        if (!a_this)
244                return a_family_to_prepend;
245
246        a_family_to_prepend->next = a_this;
247        a_this->prev = a_family_to_prepend;
248
249        return CR_OK;
250}
251
252enum CRStatus
253cr_font_family_destroy (CRFontFamily * a_this)
254{
255        CRFontFamily *cur_ff = NULL;
256
257        g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
258
259        for (cur_ff = a_this; cur_ff && cur_ff->next; cur_ff = cur_ff->next) ;
260
261        for (; cur_ff; cur_ff = cur_ff->prev) {
262                if (a_this->name) {
263                        g_free (a_this->name);
264                        a_this->name = NULL;
265                }
266
267                if (cur_ff->next) {
268                        g_free (cur_ff->next);
269
270                }
271
272                if (cur_ff->prev == NULL) {
273                        g_free (a_this);
274                }
275        }
276
277        return CR_OK;
278}
279
280/***************************************************
281 *'font-size' manipulation functions definitions
282 ***************************************************/
283
284CRFontSize *
285cr_font_size_new (void)
286{
287        CRFontSize *result = NULL;
288
289        result = g_try_malloc (sizeof (CRFontSize));
290        if (!result) {
291                cr_utils_trace_info ("Out of memory");
292                return NULL;
293        }
294        memset (result, 0, sizeof (CRFontSize));
295
296        return result;
297}
298
299enum CRStatus
300cr_font_size_clear (CRFontSize * a_this)
301{
302        g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
303
304        switch (a_this->type) {
305        case PREDEFINED_ABSOLUTE_FONT_SIZE:
306        case RELATIVE_FONT_SIZE:
307        case INHERITED_FONT_SIZE:
308                memset (a_this, 0, sizeof (CRFontSize));
309                break;
310
311        case ABSOLUTE_FONT_SIZE:
312                memset (a_this, 0, sizeof (CRFontSize));
313                break;
314
315        default:
316                return CR_UNKNOWN_TYPE_ERROR;
317        }
318
319        return CR_OK;
320}
321
322enum CRStatus
323cr_font_size_copy (CRFontSize * a_dst, CRFontSize * a_src)
324{
325        g_return_val_if_fail (a_dst && a_src, CR_BAD_PARAM_ERROR);
326
327        switch (a_src->type) {
328        case PREDEFINED_ABSOLUTE_FONT_SIZE:
329        case RELATIVE_FONT_SIZE:
330        case INHERITED_FONT_SIZE:
331                cr_font_size_clear (a_dst);
332                memcpy (a_dst, a_src, sizeof (CRFontSize));
333                break;
334
335        case ABSOLUTE_FONT_SIZE:
336                cr_font_size_clear (a_dst);
337                cr_num_copy (&a_dst->value.absolute,
338                             &a_src->value.absolute);
339                a_dst->type = a_src->type;
340                break;
341
342        default:
343                return CR_UNKNOWN_TYPE_ERROR;
344        }
345        return CR_OK;
346}
347
348enum CRStatus 
349cr_font_size_set_predefined_absolute_font_size (CRFontSize *a_this, 
350                                                enum CRPredefinedAbsoluteFontSize a_predefined)
351{
352        g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
353        g_return_val_if_fail (a_predefined >= PREDEFINED_ABSOLUTE_FONT_SIZE
354                              && a_predefined < NB_FONT_SIZE_TYPE,
355                              CR_BAD_PARAM_ERROR) ;
356
357        a_this->type = PREDEFINED_ABSOLUTE_FONT_SIZE ;
358        a_this->value.predefined = a_predefined ;
359
360        return CR_OK ;
361}
362
363enum CRStatus 
364cr_font_size_set_relative_font_size (CRFontSize *a_this,
365                                     enum CRRelativeFontSize a_relative)
366{
367        g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
368        g_return_val_if_fail (a_relative >= FONT_SIZE_LARGER
369                              && a_relative < NB_RELATIVE_FONT_SIZE,
370                              CR_BAD_PARAM_ERROR) ;
371        
372        a_this->type = RELATIVE_FONT_SIZE ;
373        a_this->value.relative = a_relative ;
374        return CR_OK ;
375}
376
377enum CRStatus 
378cr_font_size_set_absolute_font_size (CRFontSize *a_this,
379                                     enum CRNumType a_num_type,
380                                     gdouble a_value)
381{
382        g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
383        g_return_val_if_fail (a_num_type >= NUM_AUTO
384                              && a_num_type < NB_NUM_TYPE,
385                              CR_BAD_PARAM_ERROR) ;
386
387        a_this->type = ABSOLUTE_FONT_SIZE ;
388        cr_num_set (&a_this->value.absolute,
389                    a_value, a_num_type) ;        
390        return CR_OK ;
391}
392
393enum CRStatus
394cr_font_size_set_to_inherit (CRFontSize *a_this)
395{
396        g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
397
398        cr_font_size_clear (a_this) ;
399        a_this->type = INHERITED_FONT_SIZE ;
400
401        return CR_OK ;
402}
403
404gboolean
405cr_font_size_is_set_to_inherit (CRFontSize *a_this)
406{
407        g_return_val_if_fail (a_this, FALSE) ;
408
409        return a_this->type == INHERITED_FONT_SIZE ;
410}
411
412gchar *
413cr_font_size_to_string (CRFontSize * a_this)
414{
415        gchar *str = NULL;
416
417        if (!a_this) {
418                str = g_strdup ("NULL");
419                g_return_val_if_fail (str, NULL);
420                return str;
421        }
422        switch (a_this->type) {
423        case PREDEFINED_ABSOLUTE_FONT_SIZE:
424                str = g_strdup (cr_predefined_absolute_font_size_to_string
425                                (a_this->value.predefined));
426                break;
427        case ABSOLUTE_FONT_SIZE:
428                str = cr_num_to_string (&a_this->value.absolute);
429                break;
430        case RELATIVE_FONT_SIZE:
431                str = g_strdup (cr_relative_font_size_to_string
432                                (a_this->value.relative));
433                break;
434        case INHERITED_FONT_SIZE:
435                str = g_strdup ("inherit");
436                break;
437        default:
438                break;
439        }
440        return str;
441}
442
443void 
444cr_font_size_get_smaller_predefined_font_size (enum CRPredefinedAbsoluteFontSize a_font_size,
445                                               enum CRPredefinedAbsoluteFontSize *a_smaller_size)
446{
447        enum CRPredefinedAbsoluteFontSize result = FONT_SIZE_MEDIUM ;
448
449        g_return_if_fail (a_smaller_size) ;
450        g_return_if_fail (a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES
451                          && a_font_size >= FONT_SIZE_XX_SMALL) ;
452
453        switch (a_font_size) {
454        case FONT_SIZE_XX_SMALL:
455                result =  FONT_SIZE_XX_SMALL ;
456                break ;
457        case FONT_SIZE_X_SMALL:
458                result =  FONT_SIZE_XX_SMALL ;
459                break ;
460        case FONT_SIZE_SMALL:
461                result =  FONT_SIZE_X_SMALL;
462                break ;
463        case FONT_SIZE_MEDIUM:
464                result =  FONT_SIZE_SMALL;
465                break ;
466        case FONT_SIZE_LARGE:
467                result =  FONT_SIZE_MEDIUM;
468                break ;
469        case FONT_SIZE_X_LARGE:
470                result =  FONT_SIZE_LARGE;
471                break ;
472        case FONT_SIZE_XX_LARGE:
473                result =  FONT_SIZE_XX_LARGE;
474                break ;
475	case FONT_SIZE_INHERIT:
476                cr_utils_trace_info ("can't return a smaller size for FONT_SIZE_INHERIT") ;                
477                result =  FONT_SIZE_MEDIUM ;
478                break ;
479        default:
480                cr_utils_trace_info ("Unknown FONT_SIZE") ;
481                result = FONT_SIZE_MEDIUM ;
482                break ;
483        }
484        *a_smaller_size = result ;
485}
486
487
488void 
489cr_font_size_get_larger_predefined_font_size (enum CRPredefinedAbsoluteFontSize a_font_size,
490                                              enum CRPredefinedAbsoluteFontSize *a_larger_size)
491{
492        enum CRPredefinedAbsoluteFontSize result = FONT_SIZE_MEDIUM ;
493        
494        g_return_if_fail (a_larger_size) ;
495        g_return_if_fail (a_font_size >= FONT_SIZE_XX_SMALL 
496                          && a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) ;
497
498        switch (a_font_size) {
499        case FONT_SIZE_XX_SMALL:
500                result =  FONT_SIZE_X_SMALL ;
501                break ;
502        case FONT_SIZE_X_SMALL:
503                result =  FONT_SIZE_SMALL ;
504                break ;
505        case FONT_SIZE_SMALL:
506                result =  FONT_SIZE_MEDIUM;
507                break ;
508        case FONT_SIZE_MEDIUM:
509                result =  FONT_SIZE_LARGE;
510                break ;
511        case FONT_SIZE_LARGE:
512                result =  FONT_SIZE_X_LARGE;
513                break ;
514        case FONT_SIZE_X_LARGE:
515                result =  FONT_SIZE_XX_LARGE ;
516                break ;
517        case FONT_SIZE_XX_LARGE:
518                result =  FONT_SIZE_XX_LARGE;
519                break ;
520	case FONT_SIZE_INHERIT:
521                cr_utils_trace_info ("can't return a bigger size for FONT_SIZE_INHERIT") ;                
522                result =  FONT_SIZE_MEDIUM ;
523                break ;
524        default:
525                cr_utils_trace_info ("Unknown FONT_SIZE") ;
526                result = FONT_SIZE_MEDIUM ;
527                break ;
528        }
529        *a_larger_size = result ;
530}
531
532gboolean
533cr_font_size_is_predefined_absolute_font_size (enum CRPredefinedAbsoluteFontSize a_font_size)
534{
535        if (a_font_size >= FONT_SIZE_XX_SMALL
536            && a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) {
537                return TRUE ;
538        } else {
539                return FALSE ;
540        }
541}
542
543gchar *
544cr_font_size_adjust_to_string (CRFontSizeAdjust * a_this)
545{
546        gchar *str = NULL;
547
548        if (!a_this) {
549                str = g_strdup ("NULL");
550                g_return_val_if_fail (str, NULL);
551                return str;
552        }
553
554        switch (a_this->type) {
555        case FONT_SIZE_ADJUST_NONE:
556                str = g_strdup ("none");
557                break;
558        case FONT_SIZE_ADJUST_NUMBER:
559                if (a_this->num)
560                        str = cr_num_to_string (a_this->num);
561                else
562                        str = g_strdup ("unknow font-size-adjust property value"); // Should raise an error no?
563                break;
564        case FONT_SIZE_ADJUST_INHERIT:
565                str = g_strdup ("inherit");
566        }
567        return str;
568}
569
570const gchar *
571cr_font_style_to_string (enum CRFontStyle a_code)
572{
573        gchar *str = NULL;
574
575        switch (a_code) {
576        case FONT_STYLE_NORMAL:
577                str = (gchar *) "normal";
578                break;
579        case FONT_STYLE_ITALIC:
580                str = (gchar *) "italic";
581                break;
582        case FONT_STYLE_OBLIQUE:
583                str = (gchar *) "oblique";
584                break;
585        case FONT_STYLE_INHERIT:
586                str = (gchar *) "inherit";
587                break;
588        default:
589                str = (gchar *) "unknown font style value";
590                break;
591        }
592        return str;
593}
594
595const gchar *
596cr_font_variant_to_string (enum CRFontVariant a_code)
597{
598        gchar *str = NULL;
599
600        switch (a_code) {
601        case FONT_VARIANT_NORMAL:
602                str = (gchar *) "normal";
603                break;
604        case FONT_VARIANT_SMALL_CAPS:
605                str = (gchar *) "small-caps";
606                break;
607        case FONT_VARIANT_INHERIT:
608                str = (gchar *) "inherit";
609                break;
610        }
611        return str;
612}
613
614enum CRFontWeight
615cr_font_weight_get_bolder (enum CRFontWeight a_weight)
616{
617        if (a_weight >= NB_FONT_WEIGHTS) {
618                return FONT_WEIGHT_900 ;
619        } else if (a_weight < FONT_WEIGHT_NORMAL) {
620                return FONT_WEIGHT_NORMAL ;
621        } else if (a_weight == FONT_WEIGHT_BOLDER
622                   || a_weight == FONT_WEIGHT_BOLDER) {
623                cr_utils_trace_info ("FONT_WEIGHT_BOLDER or FONT_WEIGHT_LIGHTER should not appear here") ;
624                return FONT_WEIGHT_NORMAL ;
625        } else {
626                return a_weight << 1 ;
627        }
628}
629
630const gchar *
631cr_font_weight_to_string (enum CRFontWeight a_code)
632{
633        gchar *str = NULL;
634
635        switch (a_code) {
636        case FONT_WEIGHT_NORMAL:
637                str = (gchar *) "normal";
638                break;
639        case FONT_WEIGHT_BOLD:
640                str = (gchar *) "bold";
641                break;
642        case FONT_WEIGHT_BOLDER:
643                str = (gchar *) "bolder";
644                break;
645        case FONT_WEIGHT_LIGHTER:
646                str = (gchar *) "lighter";
647                break;
648        case FONT_WEIGHT_100:
649                str = (gchar *) "100";
650                break;
651        case FONT_WEIGHT_200:
652                str = (gchar *) "200";
653                break;
654        case FONT_WEIGHT_300:
655                str = (gchar *) "300";
656                break;
657        case FONT_WEIGHT_400:
658                str = (gchar *) "400";
659                break;
660        case FONT_WEIGHT_500:
661                str = (gchar *) "500";
662                break;
663        case FONT_WEIGHT_600:
664                str = (gchar *) "600";
665                break;
666        case FONT_WEIGHT_700:
667                str = (gchar *) "700";
668                break;
669        case FONT_WEIGHT_800:
670                str = (gchar *) "800";
671                break;
672        case FONT_WEIGHT_900:
673                str = (gchar *) "900";
674                break;
675        case FONT_WEIGHT_INHERIT:
676                str = (gchar *) "inherit";
677                break;
678        default:
679                str = (gchar *) "unknown font-weight property value";
680                break;
681        }
682        return str;
683}
684
685const gchar *
686cr_font_stretch_to_string (enum CRFontStretch a_code)
687{
688        gchar *str = NULL;
689
690        switch (a_code) {
691        case FONT_STRETCH_NORMAL:
692                str = (gchar *) "normal";
693                break;
694        case FONT_STRETCH_WIDER:
695                str = (gchar *) "wider";
696                break;
697        case FONT_STRETCH_NARROWER:
698                str = (gchar *) "narrower";
699                break;
700        case FONT_STRETCH_ULTRA_CONDENSED:
701                str = (gchar *) "ultra-condensed";
702                break;
703        case FONT_STRETCH_EXTRA_CONDENSED:
704                str = (gchar *) "extra-condensed";
705                break;
706        case FONT_STRETCH_CONDENSED:
707                str = (gchar *) "condensed";
708                break;
709        case FONT_STRETCH_SEMI_CONDENSED:
710                str = (gchar *) "semi-condensed";
711                break;
712        case FONT_STRETCH_SEMI_EXPANDED:
713                str = (gchar *) "semi-expanded";
714                break;
715        case FONT_STRETCH_EXPANDED:
716                str = (gchar *) "expanded";
717                break;
718        case FONT_STRETCH_EXTRA_EXPANDED:
719                str = (gchar *) "extra-expaned";
720                break;
721        case FONT_STRETCH_ULTRA_EXPANDED:
722                str = (gchar *) "ultra-expanded";
723                break;
724        case FONT_STRETCH_INHERIT:
725                str = (gchar *) "inherit";
726                break;
727        }
728        return str;
729}
730
731void
732cr_font_size_destroy (CRFontSize * a_font_size)
733{
734        g_return_if_fail (a_font_size);
735
736        g_free (a_font_size) ;
737}
738
739/*******************************************************
740 *'font-size-adjust' manipulation function definition
741 *******************************************************/
742
743CRFontSizeAdjust *
744cr_font_size_adjust_new (void)
745{
746        CRFontSizeAdjust *result = NULL;
747
748        result = g_try_malloc (sizeof (CRFontSizeAdjust));
749        if (!result) {
750                cr_utils_trace_info ("Out of memory");
751                return NULL;
752        }
753        memset (result, 0, sizeof (CRFontSizeAdjust));
754
755        return result;
756}
757
758void
759cr_font_size_adjust_destroy (CRFontSizeAdjust * a_this)
760{
761        g_return_if_fail (a_this);
762
763        if (a_this->type == FONT_SIZE_ADJUST_NUMBER && a_this->num) {
764                cr_num_destroy (a_this->num);
765                a_this->num = NULL;
766        }
767}