PageRenderTime 92ms CodeModel.GetById 5ms app.highlight 76ms RepoModel.GetById 1ms app.codeStats 1ms

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

#
C | 2851 lines | 2260 code | 387 blank | 204 comment | 487 complexity | 06c6bad09f7687ac494c1b3febb81d02 MD5 | raw file

Large files files are truncated, but you can click here to view the full 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 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of version 2.1 of 
   8 * the GNU Lesser General Public
   9 * License as published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the 
  17 * GNU Lesser General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  20 * USA
  21 *
  22 * Author: Dodji Seketeli.
  23 * see COPYRIGTHS file for copyright information
  24 */
  25
  26#include <string.h>
  27#include "cr-style.h"
  28
  29/**
  30 *@file
  31 *The definition of the #CRStyle class.
  32 */
  33
  34/**
  35 *A property ID.
  36 *Each supported css property has an ID which is
  37 *an entry into a property "population" jump table.
  38 *each entry of the property population jump table
  39 *contains code to tranform the literal form of
  40 *a property value into a strongly typed value.
  41 */
  42enum CRPropertyID {
  43        PROP_ID_NOT_KNOWN = 0,
  44        PROP_ID_PADDING_TOP,
  45        PROP_ID_PADDING_RIGHT,
  46        PROP_ID_PADDING_BOTTOM,
  47        PROP_ID_PADDING_LEFT,
  48        PROP_ID_PADDING,
  49        PROP_ID_BORDER_TOP_WIDTH,
  50        PROP_ID_BORDER_RIGHT_WIDTH,
  51        PROP_ID_BORDER_BOTTOM_WIDTH,
  52        PROP_ID_BORDER_LEFT_WIDTH,
  53        PROP_ID_BORDER_WIDTH,
  54        PROP_ID_BORDER_TOP_STYLE,
  55        PROP_ID_BORDER_RIGHT_STYLE,
  56        PROP_ID_BORDER_BOTTOM_STYLE,
  57        PROP_ID_BORDER_LEFT_STYLE,
  58        PROP_ID_BORDER_STYLE,
  59        PROP_ID_BORDER_TOP_COLOR,
  60        PROP_ID_BORDER_RIGHT_COLOR,
  61        PROP_ID_BORDER_BOTTOM_COLOR,
  62        PROP_ID_BORDER_LEFT_COLOR,
  63        PROP_ID_BORDER_TOP,
  64        PROP_ID_BORDER_RIGHT,
  65        PROP_ID_BORDER_BOTTOM,
  66        PROP_ID_BORDER_LEFT,
  67        PROP_ID_BORDER,
  68        PROP_ID_MARGIN_TOP,
  69        PROP_ID_MARGIN_RIGHT,
  70        PROP_ID_MARGIN_BOTTOM,
  71        PROP_ID_MARGIN_LEFT,
  72        PROP_ID_MARGIN,
  73        PROP_ID_DISPLAY,
  74        PROP_ID_POSITION,
  75        PROP_ID_TOP,
  76        PROP_ID_RIGHT,
  77        PROP_ID_BOTTOM,
  78        PROP_ID_LEFT,
  79        PROP_ID_FLOAT,
  80        PROP_ID_WIDTH,
  81        PROP_ID_COLOR,
  82        PROP_ID_BACKGROUND_COLOR,
  83        PROP_ID_FONT_FAMILY,
  84        PROP_ID_FONT_SIZE,
  85        PROP_ID_FONT_STYLE,
  86        PROP_ID_FONT_WEIGHT,
  87	PROP_ID_WHITE_SPACE,
  88        /*should be the last one. */
  89        NB_PROP_IDS
  90};
  91
  92typedef struct _CRPropertyDesc CRPropertyDesc;
  93
  94struct _CRPropertyDesc {
  95        const guchar *name;
  96        enum CRPropertyID prop_id;
  97};
  98
  99static CRPropertyDesc gv_prop_table[] = {
 100        {"padding-top", PROP_ID_PADDING_TOP},
 101        {"padding-right", PROP_ID_PADDING_RIGHT},
 102        {"padding-bottom", PROP_ID_PADDING_BOTTOM},
 103        {"padding-left", PROP_ID_PADDING_LEFT},
 104        {"padding", PROP_ID_PADDING},
 105        {"border-top-width", PROP_ID_BORDER_TOP_WIDTH},
 106        {"border-right-width", PROP_ID_BORDER_RIGHT_WIDTH},
 107        {"border-bottom-width", PROP_ID_BORDER_BOTTOM_WIDTH},
 108        {"border-left-width", PROP_ID_BORDER_LEFT_WIDTH},
 109        {"border-width", PROP_ID_BORDER_WIDTH},
 110        {"border-top-style", PROP_ID_BORDER_TOP_STYLE},
 111        {"border-right-style", PROP_ID_BORDER_RIGHT_STYLE},
 112        {"border-bottom-style", PROP_ID_BORDER_BOTTOM_STYLE},
 113        {"border-left-style", PROP_ID_BORDER_LEFT_STYLE},
 114        {"border-style", PROP_ID_BORDER_STYLE},
 115        {"border-top", PROP_ID_BORDER_TOP},
 116        {"border-right", PROP_ID_BORDER_RIGHT},
 117        {"border-bottom", PROP_ID_BORDER_BOTTOM},
 118        {"border-left", PROP_ID_BORDER_LEFT},
 119        {"border", PROP_ID_BORDER},
 120        {"margin-top", PROP_ID_MARGIN_TOP},
 121        {"margin-right", PROP_ID_MARGIN_RIGHT},
 122        {"margin-bottom", PROP_ID_MARGIN_BOTTOM},
 123        {"margin-left", PROP_ID_MARGIN_LEFT},
 124        {"margin", PROP_ID_MARGIN},
 125        {"display", PROP_ID_DISPLAY},
 126        {"position", PROP_ID_POSITION},
 127        {"top", PROP_ID_TOP},
 128        {"right", PROP_ID_RIGHT},
 129        {"bottom", PROP_ID_BOTTOM},
 130        {"left", PROP_ID_LEFT},
 131        {"float", PROP_ID_FLOAT},
 132        {"width", PROP_ID_WIDTH},
 133        {"color", PROP_ID_COLOR},
 134        {"border-top-color", PROP_ID_BORDER_TOP_COLOR},
 135        {"border-right-color", PROP_ID_BORDER_RIGHT_COLOR},
 136        {"border-bottom-color", PROP_ID_BORDER_BOTTOM_COLOR},
 137        {"border-left-color", PROP_ID_BORDER_LEFT_COLOR},
 138        {"background-color", PROP_ID_BACKGROUND_COLOR},
 139        {"font-family", PROP_ID_FONT_FAMILY},
 140        {"font-size", PROP_ID_FONT_SIZE},
 141        {"font-style", PROP_ID_FONT_STYLE},
 142        {"font-weight", PROP_ID_FONT_WEIGHT},
 143	{"white-space", PROP_ID_WHITE_SPACE},
 144        /*must be the last one */
 145        {NULL, 0}
 146};
 147
 148/**
 149 *A the key/value pair of this hash table
 150 *are:
 151 *key => name of the the css propertie found in gv_prop_table
 152 *value => matching property id found in gv_prop_table.
 153 *So this hash table is here just to retrieval of a property id
 154 *from a property name.
 155 */
 156static GHashTable *gv_prop_hash = NULL;
 157
 158/**
 159 *incremented by each new instance of #CRStyle
 160 *and decremented at the it destroy time.
 161 *When this reaches zero, gv_prop_hash is destroyed.
 162 */
 163static gulong gv_prop_hash_ref_count = 0;
 164
 165struct CRNumPropEnumDumpInfo {
 166        enum CRNumProp code;
 167        const gchar *str;
 168};
 169
 170static struct CRNumPropEnumDumpInfo gv_num_props_dump_infos[] = {
 171        {NUM_PROP_TOP, "top"},
 172        {NUM_PROP_RIGHT, "right"},
 173        {NUM_PROP_BOTTOM, "bottom"},
 174        {NUM_PROP_LEFT, "left"},
 175        {NUM_PROP_PADDING_TOP, "padding-top"},
 176        {NUM_PROP_PADDING_RIGHT, "padding-right"},
 177        {NUM_PROP_PADDING_BOTTOM, "padding-bottom"},
 178        {NUM_PROP_PADDING_LEFT, "padding-left"},
 179        {NUM_PROP_BORDER_TOP, "border-top"},
 180        {NUM_PROP_BORDER_RIGHT, "border-right"},
 181        {NUM_PROP_BORDER_BOTTOM, "border-bottom"},
 182        {NUM_PROP_BORDER_LEFT, "border-left"},
 183        {NUM_PROP_MARGIN_TOP, "margin-top"},
 184        {NUM_PROP_MARGIN_RIGHT, "margin-right"},
 185        {NUM_PROP_MARGIN_BOTTOM, "margin-bottom"},
 186        {NUM_PROP_MARGIN_LEFT, "margin-left"},
 187        {NUM_PROP_WIDTH, "width"},
 188        {0, NULL}
 189};
 190
 191struct CRRgbPropEnumDumpInfo {
 192        enum CRRgbProp code;
 193        const gchar *str;
 194};
 195
 196static struct CRRgbPropEnumDumpInfo gv_rgb_props_dump_infos[] = {
 197        {RGB_PROP_BORDER_TOP_COLOR, "border-top-color"},
 198        {RGB_PROP_BORDER_RIGHT_COLOR, "border-right-color"},
 199        {RGB_PROP_BORDER_BOTTOM_COLOR, "bottom-color"},
 200        {RGB_PROP_BORDER_LEFT_COLOR, "left-color"},
 201        {RGB_PROP_COLOR, "color"},
 202        {RGB_PROP_BACKGROUND_COLOR, "background-color"},
 203        {0, NULL}
 204};
 205
 206struct CRBorderStylePropEnumDumpInfo {
 207        enum CRBorderStyleProp code;
 208        const gchar *str;
 209
 210};
 211
 212static struct CRBorderStylePropEnumDumpInfo gv_border_style_props_dump_infos[]
 213        = {
 214        {BORDER_STYLE_PROP_TOP, "border-style-top"},
 215        {BORDER_STYLE_PROP_RIGHT, "border-style-right"},
 216        {BORDER_STYLE_PROP_BOTTOM, "boder-style-bottom"},
 217        {BORDER_STYLE_PROP_LEFT, "border-style-left"},
 218        {0, NULL}
 219};
 220
 221static enum CRStatus
 222  cr_style_init_properties (void);
 223
 224enum CRDirection {
 225        DIR_TOP = 0,
 226        DIR_RIGHT,
 227        DIR_BOTTOM,
 228        DIR_LEFT,
 229
 230        /*must be the last one */
 231        NB_DIRS
 232};
 233
 234static const gchar *num_prop_code_to_string (enum CRNumProp a_code);
 235
 236static const gchar *rgb_prop_code_to_string (enum CRRgbProp a_code);
 237
 238static const gchar *border_style_prop_code_to_string (enum CRBorderStyleProp
 239                                                      a_code);
 240
 241static enum CRStatus
 242set_prop_padding_x_from_value (CRStyle * a_style,
 243                                 CRTerm * a_value, enum CRDirection a_dir);
 244
 245static enum CRStatus
 246set_prop_border_x_width_from_value (CRStyle * a_style,
 247                                    CRTerm * a_value,
 248                                    enum CRDirection a_dir);
 249static enum CRStatus
 250set_prop_border_width_from_value (CRStyle *a_style,
 251                                  CRTerm *a_value) ;
 252
 253static enum CRStatus
 254set_prop_border_x_style_from_value (CRStyle * a_style,
 255                                    CRTerm * a_value,
 256                                    enum CRDirection a_dir);
 257static enum CRStatus
 258set_prop_border_style_from_value (CRStyle *a_style,
 259                                  CRTerm *a_value) ;
 260
 261static enum CRStatus
 262set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
 263                                enum CRDirection a_dir);
 264
 265static enum CRStatus
 266set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value);
 267
 268static enum CRStatus
 269set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value);
 270
 271static enum CRStatus
 272set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
 273                         enum CRDirection a_dir);
 274
 275static enum CRStatus
 276set_prop_float (CRStyle * a_style, CRTerm * a_value);
 277
 278static enum CRStatus
 279set_prop_width (CRStyle * a_style, CRTerm * a_value);
 280
 281static enum CRStatus
 282set_prop_color (CRStyle * a_style, CRTerm * a_value);
 283
 284static enum CRStatus
 285set_prop_background_color (CRStyle * a_style, CRTerm * a_value);
 286
 287static enum CRStatus
 288set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
 289                                      enum CRDirection a_dir);
 290
 291static enum CRStatus
 292set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
 293                                enum CRDirection a_dir);
 294
 295static enum CRStatus
 296set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value);
 297
 298static enum CRStatus
 299set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value);
 300
 301static enum CRStatus
 302set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value);
 303
 304static enum CRStatus
 305set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value);
 306
 307static enum CRStatus
 308init_style_font_size_field (CRStyle * a_style);
 309
 310static enum CRStatus
 311set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value);
 312
 313static enum CRStatus
 314set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value);
 315
 316static enum CRStatus
 317set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value);
 318
 319static const gchar *
 320num_prop_code_to_string (enum CRNumProp a_code)
 321{
 322        gint len = sizeof (gv_num_props_dump_infos) /
 323                sizeof (struct CRNumPropEnumDumpInfo);
 324        if (a_code >= len) {
 325                cr_utils_trace_info ("A field has been added "
 326                                     "to 'enum CRNumProp' and no matching"
 327                                     " entry has been "
 328                                     "added to gv_num_prop_dump_infos table.\n"
 329                                     "Please add the missing matching entry");
 330                return NULL;
 331        }
 332        if (gv_num_props_dump_infos[a_code].code != a_code) {
 333                cr_utils_trace_info ("mismatch between the order of fields in"
 334                                     " 'enum CRNumProp' and "
 335                                     "the order of entries in "
 336                                     "the gv_num_prop_dump_infos table");
 337                return NULL;
 338        }
 339        return gv_num_props_dump_infos[a_code].str;
 340}
 341
 342static const gchar *
 343rgb_prop_code_to_string (enum CRRgbProp a_code)
 344{
 345        gint len = sizeof (gv_rgb_props_dump_infos) /
 346                sizeof (struct CRRgbPropEnumDumpInfo);
 347
 348        if (a_code >= len) {
 349                cr_utils_trace_info ("A field has been added "
 350                                     "to 'enum CRRgbProp' and no matching"
 351                                     " entry has been "
 352                                     "added to gv_rgb_prop_dump_infos table.\n"
 353                                     "Please add the missing matching entry");
 354                return NULL;
 355        }
 356        if (gv_rgb_props_dump_infos[a_code].code != a_code) {
 357                cr_utils_trace_info ("mismatch between the order of fields in"
 358                                     " 'enum CRRgbProp' and "
 359                                     "the order of entries in "
 360                                     "the gv_rgb_props_dump_infos table");
 361                return NULL;
 362        }
 363        return gv_rgb_props_dump_infos[a_code].str;
 364}
 365
 366static const gchar *
 367border_style_prop_code_to_string (enum CRBorderStyleProp a_code)
 368{
 369        gint len = sizeof (gv_border_style_props_dump_infos) /
 370                sizeof (struct CRBorderStylePropEnumDumpInfo);
 371
 372        if (a_code >= len) {
 373                cr_utils_trace_info ("A field has been added "
 374                                     "to 'enum CRBorderStyleProp' and no matching"
 375                                     " entry has been "
 376                                     "added to gv_border_style_prop_dump_infos table.\n"
 377                                     "Please add the missing matching entry");
 378                return NULL;
 379        }
 380        if (gv_border_style_props_dump_infos[a_code].code != a_code) {
 381                cr_utils_trace_info ("mismatch between the order of fields in"
 382                                     " 'enum CRBorderStyleProp' and "
 383                                     "the order of entries in "
 384                                     "the gv_border_style_props_dump_infos table");
 385                return NULL;
 386        }
 387        return gv_border_style_props_dump_infos[a_code].str;
 388}
 389
 390static enum CRStatus
 391cr_style_init_properties (void)
 392{
 393
 394        if (!gv_prop_hash) {
 395                gulong i = 0;
 396
 397                gv_prop_hash = g_hash_table_new (g_str_hash, g_str_equal);
 398                if (!gv_prop_hash) {
 399                        cr_utils_trace_info ("Out of memory");
 400                        return CR_ERROR;
 401                }
 402
 403                /*load gv_prop_hash from gv_prop_table */
 404                for (i = 0; gv_prop_table[i].name; i++) {
 405                        g_hash_table_insert
 406                                (gv_prop_hash,
 407                                 (gpointer) gv_prop_table[i].name,
 408                                 GINT_TO_POINTER (gv_prop_table[i].prop_id));
 409                }
 410        }
 411
 412        return CR_OK;
 413}
 414
 415static enum CRPropertyID
 416cr_style_get_prop_id (const guchar * a_prop)
 417{
 418        gpointer *raw_id = NULL;
 419
 420        if (!gv_prop_hash) {
 421                cr_style_init_properties ();
 422        }
 423
 424        raw_id = g_hash_table_lookup (gv_prop_hash, a_prop);
 425        if (!raw_id) {
 426                return PROP_ID_NOT_KNOWN;
 427        }
 428        return GPOINTER_TO_INT (raw_id);
 429}
 430
 431static enum CRStatus
 432set_prop_padding_x_from_value (CRStyle * a_style,
 433                               CRTerm * a_value, enum CRDirection a_dir)
 434{
 435        enum CRStatus status = CR_OK;
 436        CRNum *num_val = NULL;
 437
 438        g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
 439
 440        if (a_value->type != TERM_NUMBER && a_value->type != TERM_IDENT)
 441                return CR_BAD_PARAM_ERROR;
 442
 443        switch (a_dir) {
 444        case DIR_TOP:
 445                num_val = &a_style->num_props[NUM_PROP_PADDING_TOP].sv;
 446                break;
 447
 448        case DIR_RIGHT:
 449                num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv;
 450                break;
 451
 452        case DIR_BOTTOM:
 453                num_val = &a_style->num_props[NUM_PROP_PADDING_BOTTOM].sv;
 454                break;
 455
 456        case DIR_LEFT:
 457                num_val = &a_style->num_props[NUM_PROP_PADDING_LEFT].sv;
 458                break;
 459
 460        default:
 461                return CR_BAD_PARAM_ERROR;
 462        }
 463
 464        if (a_value->type == TERM_IDENT) {
 465                if (a_value->content.str
 466                    && a_value->content.str->stryng
 467		    && a_value->content.str->stryng->str
 468                    && !strncmp ((guchar *) "inherit",
 469                                 a_value->content.str->stryng->str,
 470                                 sizeof ("inherit")-1)) {
 471			status = cr_num_set (num_val, 0.0, NUM_INHERIT);
 472                        return CR_OK;
 473                } else
 474                        return CR_UNKNOWN_TYPE_ERROR;
 475        }
 476
 477        g_return_val_if_fail (a_value->type == TERM_NUMBER
 478                              && a_value->content.num, CR_UNKNOWN_TYPE_ERROR);
 479
 480        switch (a_value->content.num->type) {
 481        case NUM_LENGTH_EM:
 482        case NUM_LENGTH_EX:
 483        case NUM_LENGTH_PX:
 484        case NUM_LENGTH_IN:
 485        case NUM_LENGTH_CM:
 486        case NUM_LENGTH_MM:
 487        case NUM_LENGTH_PT:
 488        case NUM_LENGTH_PC:
 489        case NUM_PERCENTAGE:
 490                status = cr_num_copy (num_val, a_value->content.num);
 491                break;
 492        default:
 493                status = CR_UNKNOWN_TYPE_ERROR;
 494                break;
 495        }
 496
 497        return status;
 498}
 499
 500static enum CRStatus
 501set_prop_border_x_width_from_value (CRStyle * a_style,
 502                                    CRTerm * a_value, 
 503                                    enum CRDirection a_dir)
 504{
 505        enum CRStatus status = CR_OK;
 506        CRNum *num_val = NULL;
 507
 508        g_return_val_if_fail (a_value && a_style, CR_BAD_PARAM_ERROR);
 509
 510        switch (a_dir) {
 511        case DIR_TOP:
 512                num_val = &a_style->num_props[NUM_PROP_BORDER_TOP].sv;
 513                break;
 514
 515        case DIR_RIGHT:
 516                num_val = &a_style->num_props[NUM_PROP_BORDER_RIGHT].sv;
 517                break;
 518
 519        case DIR_BOTTOM:
 520                num_val = &a_style->num_props[NUM_PROP_BORDER_BOTTOM].sv;
 521                break;
 522
 523        case DIR_LEFT:
 524                num_val = &a_style->num_props[NUM_PROP_BORDER_LEFT].sv;
 525                break;
 526
 527        default:
 528                return CR_BAD_PARAM_ERROR;
 529                break;
 530        }
 531
 532        if (a_value->type == TERM_IDENT) {
 533                if (a_value->content.str 
 534                    && a_value->content.str->stryng
 535                    && a_value->content.str->stryng->str) {
 536                        if (!strncmp ("thin",
 537                                      a_value->content.str->stryng->str,
 538                                      sizeof ("thin")-1)) {
 539                                cr_num_set (num_val, BORDER_THIN,
 540                                            NUM_LENGTH_PX);
 541                        } else if (!strncmp 
 542                                   ("medium",
 543                                    a_value->content.str->stryng->str,
 544                                             sizeof ("medium")-1)) {
 545                                cr_num_set (num_val, BORDER_MEDIUM,
 546                                            NUM_LENGTH_PX);
 547                        } else if (!strncmp ("thick",
 548                                             a_value->content.str->stryng->str,
 549                                             sizeof ("thick")-1)) {
 550                                cr_num_set (num_val, BORDER_THICK,
 551                                            NUM_LENGTH_PX);
 552                        } else {
 553                                return CR_UNKNOWN_TYPE_ERROR;
 554                        }
 555                }
 556        } else if (a_value->type == TERM_NUMBER) {
 557                if (a_value->content.num) {
 558                        cr_num_copy (num_val, a_value->content.num);
 559                }
 560        } else if (a_value->type != TERM_NUMBER
 561                   || a_value->content.num == NULL) {
 562                return CR_UNKNOWN_TYPE_ERROR;
 563        }
 564
 565        return status;
 566}
 567
 568static enum CRStatus
 569set_prop_border_width_from_value (CRStyle *a_style,
 570                                  CRTerm *a_value)
 571{
 572        CRTerm *cur_term = NULL ;
 573        enum CRDirection direction = DIR_TOP ;
 574
 575        g_return_val_if_fail (a_style && a_value,
 576                              CR_BAD_PARAM_ERROR) ;
 577        cur_term = a_value ;
 578
 579        if (!cur_term)
 580                return CR_ERROR ;
 581
 582        for (direction = DIR_TOP ; 
 583             direction < NB_DIRS ; direction ++) {
 584                set_prop_border_x_width_from_value (a_style, 
 585                                                    cur_term,
 586                                                    direction) ;
 587        }
 588
 589        cur_term = cur_term->next ;
 590        if (!cur_term)
 591                return CR_OK ;
 592        set_prop_border_x_width_from_value (a_style, cur_term,
 593                                            DIR_RIGHT) ;
 594        set_prop_border_x_width_from_value (a_style, cur_term,
 595                                            DIR_LEFT) ;
 596
 597        cur_term = cur_term->next ;
 598        if (!cur_term)
 599                return CR_OK ;
 600        set_prop_border_x_width_from_value (a_style, cur_term,
 601                                            DIR_BOTTOM) ;
 602
 603        cur_term = cur_term->next ;
 604        if (!cur_term)
 605                return CR_OK ;
 606        set_prop_border_x_width_from_value (a_style, cur_term,
 607                                            DIR_LEFT) ;
 608
 609        return CR_OK ;
 610}
 611
 612static enum CRStatus
 613set_prop_border_x_style_from_value (CRStyle * a_style,
 614                                    CRTerm * a_value, enum CRDirection a_dir)
 615{
 616        enum CRStatus status = CR_OK;
 617        enum CRBorderStyle *border_style_ptr = NULL;
 618
 619        g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
 620
 621        switch (a_dir) {
 622        case DIR_TOP:
 623                border_style_ptr = &a_style->
 624                        border_style_props[BORDER_STYLE_PROP_TOP];
 625                break;
 626
 627        case DIR_RIGHT:
 628                border_style_ptr =
 629                        &a_style->border_style_props[BORDER_STYLE_PROP_RIGHT];
 630                break;
 631
 632        case DIR_BOTTOM:
 633                border_style_ptr = &a_style->
 634                        border_style_props[BORDER_STYLE_PROP_BOTTOM];
 635                break;
 636
 637        case DIR_LEFT:
 638                border_style_ptr = &a_style->
 639                        border_style_props[BORDER_STYLE_PROP_LEFT];
 640                break;
 641
 642        default:
 643                break;
 644        }
 645
 646        if (a_value->type != TERM_IDENT || !a_value->content.str) {
 647                return CR_UNKNOWN_TYPE_ERROR;
 648        }
 649
 650        if (!strncmp ("none", 
 651                      a_value->content.str->stryng->str, 
 652                      sizeof ("none")-1)) {
 653                *border_style_ptr = BORDER_STYLE_NONE;
 654        } else if (!strncmp ("hidden",
 655                             a_value->content.str->stryng->str, 
 656                             sizeof ("hidden")-1)) {
 657                *border_style_ptr = BORDER_STYLE_HIDDEN;
 658        } else if (!strncmp ("dotted",
 659                             a_value->content.str->stryng->str, 
 660                             sizeof ("dotted")-1)) {
 661                *border_style_ptr = BORDER_STYLE_DOTTED;
 662        } else if (!strncmp ("dashed",
 663                             a_value->content.str->stryng->str, sizeof ("dashed")-1)) {
 664                *border_style_ptr = BORDER_STYLE_DASHED;
 665        } else if (!strncmp ("solid",
 666                             a_value->content.str->stryng->str, sizeof ("solid")-1)) {
 667                *border_style_ptr = BORDER_STYLE_SOLID;
 668        } else if (!strncmp ("double",
 669                             a_value->content.str->stryng->str, sizeof ("double")-1)) {
 670                *border_style_ptr = BORDER_STYLE_DOUBLE;
 671        } else if (!strncmp ("groove",
 672                             a_value->content.str->stryng->str, sizeof ("groove")-1)) {
 673                *border_style_ptr = BORDER_STYLE_GROOVE;
 674        } else if (!strncmp ("ridge",
 675                             a_value->content.str->stryng->str, 
 676                             sizeof ("ridge")-1)) {
 677                *border_style_ptr = BORDER_STYLE_RIDGE;
 678        } else if (!strncmp ("inset",
 679                             a_value->content.str->stryng->str, 
 680                             sizeof ("inset")-1)) {
 681                *border_style_ptr = BORDER_STYLE_INSET;
 682        } else if (!strncmp ("outset",
 683                             a_value->content.str->stryng->str, 
 684                             sizeof ("outset")-1)) {
 685                *border_style_ptr = BORDER_STYLE_OUTSET;
 686        } else if (!strncmp ("inherit",
 687                             a_value->content.str->stryng->str, 
 688                             sizeof ("inherit")-1)) {
 689		*border_style_ptr = BORDER_STYLE_INHERIT;
 690        } else {
 691                status = CR_UNKNOWN_TYPE_ERROR;
 692        }
 693
 694        return status;
 695}
 696
 697static enum CRStatus
 698set_prop_border_style_from_value (CRStyle *a_style,
 699                                  CRTerm *a_value)
 700{
 701        CRTerm *cur_term = NULL ;
 702        enum CRDirection direction = DIR_TOP ;
 703
 704        g_return_val_if_fail (a_style && a_value, 
 705                              CR_BAD_PARAM_ERROR) ;
 706
 707        cur_term = a_value ;
 708        if (!cur_term || cur_term->type != TERM_IDENT) {
 709                return CR_ERROR ;
 710        }
 711        
 712        for (direction = DIR_TOP ; 
 713             direction < NB_DIRS ;
 714             direction ++) {
 715                set_prop_border_x_style_from_value (a_style, 
 716                                                    cur_term,
 717                                                    direction) ;
 718        }
 719        
 720        cur_term = cur_term->next ;
 721        if (!cur_term || cur_term->type != TERM_IDENT) {
 722                return CR_OK ;
 723        }
 724        
 725        set_prop_border_x_style_from_value (a_style, cur_term, 
 726                                            DIR_RIGHT) ;
 727        set_prop_border_x_style_from_value (a_style, cur_term, 
 728                                            DIR_LEFT) ;
 729
 730        cur_term = cur_term->next ;
 731        if (!cur_term || cur_term->type != TERM_IDENT) {
 732                return CR_OK ;
 733        }        
 734        set_prop_border_x_style_from_value (a_style, cur_term,
 735                                           DIR_BOTTOM) ;
 736        
 737        cur_term = cur_term->next ;
 738        if (!cur_term || cur_term->type != TERM_IDENT) {
 739                return CR_OK ;
 740        }
 741        set_prop_border_x_style_from_value (a_style, cur_term,
 742                                            DIR_LEFT) ;
 743        return CR_OK ;
 744}
 745
 746static enum CRStatus
 747set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
 748                              enum CRDirection a_dir)
 749{
 750        enum CRStatus status = CR_OK;
 751        CRNum *num_val = NULL;
 752
 753        g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
 754
 755        switch (a_dir) {
 756        case DIR_TOP:
 757                num_val = &a_style->num_props[NUM_PROP_MARGIN_TOP].sv;
 758                break;
 759
 760        case DIR_RIGHT:
 761                num_val = &a_style->num_props[NUM_PROP_MARGIN_RIGHT].sv;
 762                break;
 763
 764        case DIR_BOTTOM:
 765                num_val = &a_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv;
 766                break;
 767
 768        case DIR_LEFT:
 769                num_val = &a_style->num_props[NUM_PROP_MARGIN_LEFT].sv;
 770                break;
 771
 772        default:
 773                break;
 774        }
 775
 776        switch (a_value->type) {
 777        case TERM_IDENT:
 778                if (a_value->content.str
 779                    && a_value->content.str->stryng
 780                    && a_value->content.str->stryng->str
 781                    && !strcmp (a_value->content.str->stryng->str,
 782                                 "inherit")) {
 783			status = cr_num_set (num_val, 0.0, NUM_INHERIT);
 784                } else if (a_value->content.str
 785                           && a_value->content.str->stryng
 786                           && !strcmp (a_value->content.str->stryng->str,
 787                                        "auto")) {
 788                        status = cr_num_set (num_val, 0.0, NUM_AUTO);
 789                } else {
 790                        status = CR_UNKNOWN_TYPE_ERROR;
 791                }
 792                break ;
 793
 794        case TERM_NUMBER:
 795                status = cr_num_copy (num_val, a_value->content.num);
 796                break;
 797
 798        default:
 799                status = CR_UNKNOWN_TYPE_ERROR;
 800                break;
 801        }
 802
 803        return status;
 804}
 805
 806struct CRPropDisplayValPair {
 807        const guchar *prop_name;
 808        enum CRDisplayType type;
 809};
 810
 811static enum CRStatus
 812set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value)
 813{
 814        static const struct CRPropDisplayValPair disp_vals_map[] = {
 815                {"none", DISPLAY_NONE},
 816                {"inline", DISPLAY_INLINE},
 817                {"block", DISPLAY_BLOCK},
 818                {"run-in", DISPLAY_RUN_IN},
 819                {"compact", DISPLAY_COMPACT},
 820                {"marker", DISPLAY_MARKER},
 821                {"table", DISPLAY_TABLE},
 822                {"inline-table", DISPLAY_INLINE_TABLE},
 823                {"table-row-group", DISPLAY_TABLE_ROW_GROUP},
 824                {"table-header-group", DISPLAY_TABLE_HEADER_GROUP},
 825                {"table-footer-group", DISPLAY_TABLE_FOOTER_GROUP},
 826                {"table-row", DISPLAY_TABLE_ROW},
 827                {"table-column-group", DISPLAY_TABLE_COLUMN_GROUP},
 828                {"table-column", DISPLAY_TABLE_COLUMN},
 829                {"table-cell", DISPLAY_TABLE_CELL},
 830                {"table-caption", DISPLAY_TABLE_CAPTION},
 831                {"inherit", DISPLAY_INHERIT},
 832                {NULL, DISPLAY_NONE}
 833        };
 834
 835        g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
 836
 837        switch (a_value->type) {
 838        case TERM_IDENT:
 839                {
 840                        int i = 0;
 841
 842                        if (!a_value->content.str
 843                            || !a_value->content.str->stryng
 844                            || !a_value->content.str->stryng->str)
 845                                break;
 846
 847                        for (i = 0; disp_vals_map[i].prop_name; i++) {
 848                                if (!strncmp 
 849                                    (disp_vals_map[i].prop_name,
 850                                     a_value->content.str->stryng->str,
 851                                     strlen (disp_vals_map[i].prop_name))) {
 852                                        a_style->display =
 853                                                disp_vals_map[i].type;
 854                                        break;
 855                                }
 856                        }
 857                }
 858                break;
 859
 860        default:
 861                break;
 862        }
 863
 864        return CR_OK;
 865}
 866
 867struct CRPropPositionValPair {
 868        const guchar *name;
 869        enum CRPositionType type;
 870};
 871
 872static enum CRStatus
 873set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value)
 874{
 875        enum CRStatus status = CR_UNKNOWN_PROP_VAL_ERROR;
 876        static const struct CRPropPositionValPair position_vals_map[] = {
 877                {"static", POSITION_STATIC},
 878                {"relative", POSITION_RELATIVE},
 879                {"absolute", POSITION_ABSOLUTE},
 880                {"fixed", POSITION_FIXED},
 881                {"inherit", POSITION_INHERIT},
 882                {NULL, POSITION_STATIC}
 883                /*must alwas be the last one */
 884        };
 885
 886        g_return_val_if_fail (a_value, CR_BAD_PARAM_ERROR);
 887
 888        switch (a_value->type) {
 889        case TERM_IDENT:
 890                {
 891                        int i = 0;
 892
 893                        if (!a_value->content.str
 894                            || !a_value->content.str->stryng
 895                            || !a_value->content.str->stryng->str)
 896                                break;
 897
 898                        for (i = 0; position_vals_map[i].name; i++) {
 899                                if (!strncmp (position_vals_map[i].name,
 900                                              a_value->content.str->stryng->str,
 901                                              strlen (position_vals_map[i].
 902                                                      name))) {
 903                                        a_style->position =
 904                                                position_vals_map[i].type;
 905                                        status = CR_OK;
 906                                        break;
 907                                }
 908                        }
 909                }
 910                break;
 911
 912        default:
 913                break;
 914        }
 915
 916        return CR_OK;
 917}
 918
 919static enum CRStatus
 920set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
 921                       enum CRDirection a_dir)
 922{
 923        CRNum *box_offset = NULL;
 924
 925        g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
 926
 927        if (!(a_value->type == TERM_NUMBER)
 928            && !(a_value->type == TERM_IDENT)) {
 929                return CR_UNKNOWN_PROP_VAL_ERROR;
 930        }
 931
 932        switch (a_dir) {
 933        case DIR_TOP:
 934                box_offset = &a_style->num_props[NUM_PROP_TOP].sv;
 935                break;
 936
 937        case DIR_RIGHT:
 938                box_offset = &a_style->num_props[NUM_PROP_RIGHT].sv;
 939                break;
 940
 941        case DIR_BOTTOM:
 942                box_offset = &a_style->num_props[NUM_PROP_BOTTOM].sv;
 943                break;
 944        case DIR_LEFT:
 945                box_offset = &a_style->num_props[NUM_PROP_LEFT].sv;
 946                break;
 947
 948        default:
 949                break;
 950        }
 951
 952        box_offset->type = NUM_AUTO;
 953
 954        if (a_value->type == TERM_NUMBER && a_value->content.num) {
 955                cr_num_copy (box_offset, a_value->content.num);
 956        } else if (a_value->type == TERM_IDENT
 957                   && a_value->content.str
 958                   && a_value->content.str->stryng
 959                   && a_value->content.str->stryng->str) {
 960                if (!strncmp ("inherit",
 961                              a_value->content.str->stryng->str,
 962                              sizeof ("inherit")-1)) {
 963                        cr_num_set (box_offset, 0.0, NUM_INHERIT);
 964                } else if (!strncmp ("auto",
 965                                     a_value->content.str->stryng->str,
 966                                     sizeof ("auto")-1)) {
 967                        box_offset->type = NUM_AUTO;
 968                }
 969        }
 970
 971        return CR_OK;
 972}
 973
 974static enum CRStatus
 975set_prop_float (CRStyle * a_style, CRTerm * a_value)
 976{
 977        g_return_val_if_fail (a_style && a_value, 
 978                              CR_BAD_PARAM_ERROR);
 979
 980        /*the default float type as specified by the css2 spec */
 981        a_style->float_type = FLOAT_NONE;
 982
 983        if (a_value->type != TERM_IDENT 
 984            || !a_value->content.str
 985            || !a_value->content.str->stryng
 986            || !a_value->content.str->stryng->str) { 
 987                /*unknow type, the float type is set to it's default value */
 988                return CR_OK;
 989        }
 990
 991        if (!strncmp ("none", 
 992                      a_value->content.str->stryng->str, 
 993                      sizeof ("none")-1)) {
 994                a_style->float_type = FLOAT_NONE;
 995        } else if (!strncmp ("left",
 996                             a_value->content.str->stryng->str, 
 997                             sizeof ("left")-1)) {
 998                a_style->float_type = FLOAT_LEFT;
 999        } else if (!strncmp ("right",
1000                             a_value->content.str->stryng->str, 
1001                             sizeof ("right")-1)) {
1002                a_style->float_type = FLOAT_RIGHT;
1003        } else if (!strncmp ("inherit",
1004                             a_value->content.str->stryng->str, 
1005                             sizeof ("inherit")-1)) {
1006		a_style->float_type = FLOAT_INHERIT;
1007        }
1008        return CR_OK;
1009}
1010
1011static enum CRStatus
1012set_prop_width (CRStyle * a_style, CRTerm * a_value)
1013{
1014	CRNum *width = NULL;
1015        g_return_val_if_fail (a_style 
1016                              && a_value, 
1017                              CR_BAD_PARAM_ERROR);
1018
1019	width = &a_style->num_props[NUM_PROP_WIDTH].sv;
1020	cr_num_set (width, 0.0, NUM_AUTO);
1021
1022        if (a_value->type == TERM_IDENT) {
1023                if (a_value->content.str 
1024                    && a_value->content.str->stryng
1025                    && a_value->content.str->stryng->str) {
1026                        if (!strncmp ("auto",
1027                                      a_value->content.str->stryng->str,
1028                                      sizeof ("auto")-1)) {
1029				cr_num_set (width, 0.0, NUM_AUTO);
1030                        } else if (!strncmp ("inherit",
1031                                             a_value->content.str->stryng->str,
1032                                             sizeof ("inherit")-1)) {
1033				cr_num_set (width, 0.0, NUM_INHERIT);
1034                        }
1035                }
1036        } else if (a_value->type == TERM_NUMBER) {
1037                if (a_value->content.num) {
1038                        cr_num_copy (&a_style->num_props[NUM_PROP_WIDTH].sv,
1039                                     a_value->content.num);
1040                }
1041        }
1042        return CR_OK;
1043}
1044
1045static enum CRStatus 
1046set_prop_color (CRStyle * a_style, CRTerm * a_value)
1047{
1048	enum CRStatus status = CR_OK;
1049	CRRgb *a_rgb = &a_style->rgb_props[RGB_PROP_COLOR].sv;
1050
1051	g_return_val_if_fail (a_style 
1052                              && a_value, CR_BAD_PARAM_ERROR);
1053
1054	status = cr_rgb_set_from_term (a_rgb, a_value);
1055
1056	return status;
1057}
1058
1059static enum CRStatus
1060set_prop_background_color (CRStyle * a_style, CRTerm * a_value)
1061{
1062	enum CRStatus status = CR_OK;
1063	CRRgb *rgb = &a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv;
1064
1065	g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1066
1067	status = cr_rgb_set_from_term (rgb, a_value);
1068	return status;
1069}
1070
1071/**
1072 *Sets border-top-color, border-right-color,
1073 *border-bottom-color or border-left-color properties
1074 *in the style structure. The value is taken from a
1075 *css2 term of type IDENT or RGB.
1076 *@param a_style the style structure to set.
1077 *@param a_value the css2 term to take the color information from.
1078 *@param a_dir the direction (TOP, LEFT, RIGHT, or BOTTOM).
1079 *@return CR_OK upon successfull completion, an error code otherwise.
1080 */
1081static enum CRStatus
1082set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
1083                                    enum CRDirection a_dir)
1084{
1085        CRRgb *rgb_color = NULL;
1086        enum CRStatus status = CR_OK;
1087
1088        g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1089
1090        switch (a_dir) {
1091        case DIR_TOP:
1092                rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_TOP_COLOR].sv;
1093                break;
1094
1095        case DIR_RIGHT:
1096                rgb_color =
1097                        &a_style->rgb_props[RGB_PROP_BORDER_RIGHT_COLOR].sv;
1098                break;
1099
1100        case DIR_BOTTOM:
1101                rgb_color =
1102                        &a_style->rgb_props[RGB_PROP_BORDER_BOTTOM_COLOR].sv;
1103                break;
1104
1105        case DIR_LEFT:
1106                rgb_color =
1107                        &a_style->rgb_props[RGB_PROP_BORDER_LEFT_COLOR].sv;
1108                break;
1109
1110        default:
1111                cr_utils_trace_info ("unknown DIR type");
1112                return CR_BAD_PARAM_ERROR;
1113        }
1114
1115        status = CR_UNKNOWN_PROP_VAL_ERROR;
1116
1117        if (a_value->type == TERM_IDENT) {
1118                if (a_value->content.str 
1119                    && a_value->content.str->stryng
1120                    && a_value->content.str->stryng->str) {
1121                        status = cr_rgb_set_from_name
1122                                (rgb_color, 
1123                                 a_value->content.str->stryng->str);
1124
1125                }
1126                if (status != CR_OK) {
1127                        cr_rgb_set_from_name (rgb_color, "black");
1128                }
1129        } else if (a_value->type == TERM_RGB) {
1130                if (a_value->content.rgb) {
1131                        status = cr_rgb_set_from_rgb
1132                                (rgb_color, a_value->content.rgb);
1133                }
1134        }
1135        return status;
1136}
1137
1138static enum CRStatus
1139set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
1140                              enum CRDirection a_dir)
1141{
1142        CRTerm *cur_term = NULL;
1143
1144        enum CRStatus status = CR_OK;
1145
1146        g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1147
1148        for (cur_term = a_value; 
1149             cur_term; 
1150             cur_term = cur_term->next) {
1151                status = set_prop_border_x_width_from_value (a_style,
1152                                                             cur_term, a_dir);
1153
1154                if (status != CR_OK) {
1155                        status = set_prop_border_x_style_from_value
1156                                (a_style, cur_term, a_dir);
1157                }
1158                if (status != CR_OK) {
1159                        status = set_prop_border_x_color_from_value
1160                                (a_style, cur_term, a_dir);
1161                }
1162        }
1163        return CR_OK;
1164}
1165
1166static enum CRStatus
1167set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value)
1168{
1169        enum CRDirection direction = 0;
1170
1171        g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1172
1173        for (direction = 0; direction < NB_DIRS; direction++) {
1174                set_prop_border_x_from_value (a_style, 
1175                                              a_value, 
1176                                              direction);
1177        }
1178
1179        return CR_OK;
1180}
1181
1182static enum CRStatus
1183set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value)
1184{
1185        CRTerm *cur_term = NULL;
1186        enum CRDirection direction = 0;
1187        enum CRStatus status = CR_OK;
1188        
1189        g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1190
1191        cur_term = a_value;
1192
1193        /*filter the eventual non NUMBER terms some user can have written here*/
1194        while (cur_term && cur_term->type != TERM_NUMBER) {
1195                cur_term = cur_term->next;
1196        }
1197        if (!cur_term)
1198                return CR_ERROR ;
1199
1200        for (direction = 0; direction < NB_DIRS; direction++) {
1201                set_prop_padding_x_from_value (a_style, cur_term, direction);
1202        }
1203        cur_term = cur_term->next;
1204
1205        /*filter non NUMBER terms that some users can have written here...*/
1206        while (cur_term && cur_term->type != TERM_NUMBER) {
1207                cur_term = cur_term->next;
1208        }
1209        /*the user can have just written padding: 1px*/
1210        if (!cur_term)
1211                return CR_OK;
1212
1213        set_prop_padding_x_from_value (a_style, cur_term, DIR_RIGHT);
1214        set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
1215
1216        while (cur_term && cur_term->type != TERM_NUMBER) {
1217                cur_term = cur_term->next;
1218        }
1219        if (!cur_term)
1220                return CR_OK;
1221
1222        set_prop_padding_x_from_value (a_style, cur_term, DIR_BOTTOM);
1223
1224        while (cur_term && cur_term->type != TERM_NUMBER) {
1225                cur_term = cur_term->next;
1226        }
1227        if (!cur_term)
1228                return CR_OK;
1229        status = set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
1230        return status;
1231}
1232
1233static enum CRStatus
1234set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value)
1235{
1236        CRTerm *cur_term = NULL;
1237        enum CRDirection direction = 0;
1238        enum CRStatus status = CR_OK;
1239
1240        g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1241
1242        cur_term = a_value;
1243
1244        while (cur_term && cur_term->type != TERM_NUMBER) {
1245                cur_term = cur_term->next;
1246        }
1247
1248        if (!cur_term)
1249                return CR_OK;
1250
1251        for (direction = 0; direction < NB_DIRS; direction++) {
1252                set_prop_margin_x_from_value (a_style, cur_term, direction);
1253        }
1254        cur_term = cur_term->next;
1255
1256        while (cur_term && cur_term->type != TERM_NUMBER) {
1257                cur_term = cur_term->next;
1258        }
1259        if (!cur_term)
1260                return CR_OK;
1261
1262        set_prop_margin_x_from_value (a_style, cur_term, DIR_RIGHT);
1263        set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
1264
1265        while (cur_term && cur_term->type != TERM_NUMBER) {
1266                cur_term = cur_term->next;
1267        }
1268        if (!cur_term)
1269                return CR_OK;
1270
1271        set_prop_margin_x_from_value (a_style, cur_term, DIR_BOTTOM);
1272
1273        while (cur_term && cur_term->type != TERM_NUMBER) {
1274                cur_term = cur_term->next;
1275        }
1276        if (!cur_term)
1277                return CR_OK;
1278
1279        status = set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);        
1280
1281        return status;
1282}
1283
1284static enum CRStatus
1285set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value)
1286{
1287        CRTerm *cur_term = NULL;
1288        CRFontFamily *font_family = NULL,
1289                *cur_ff = NULL,
1290                *cur_ff2 = NULL;
1291
1292        g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1293
1294	if (a_value->type == TERM_IDENT &&
1295	    a_value->content.str &&
1296	    a_value->content.str->stryng &&
1297	    a_value->content.str->stryng->str &&
1298	    !strcmp ("inherit", a_value->content.str->stryng->str))
1299	{
1300		font_family = cr_font_family_new (FONT_FAMILY_INHERIT, NULL);
1301		goto out;
1302	}
1303
1304        for (cur_term = a_value; cur_term; cur_term = cur_term->next) {
1305                switch (cur_term->type) {
1306                case TERM_IDENT:
1307                        {
1308                                enum CRFontFamilyType font_type;
1309
1310                                if (cur_term->content.str
1311                                    && cur_term->content.str->stryng
1312                                    && cur_term->content.str->stryng->str
1313                                    && !strcmp 
1314                                    (cur_term->content.str->stryng->str,
1315                                     "sans-serif")) {
1316                                        font_type = FONT_FAMILY_SANS_SERIF;
1317                                } else if (cur_term->content.str
1318                                           && cur_term->content.str->stryng
1319                                           && cur_term->content.str->stryng->str
1320                                           && !strcmp 
1321                                           (cur_term->content.str->stryng->str, 
1322                                            "serif")) {
1323                                        font_type = FONT_FAMILY_SERIF;
1324                                } else if (cur_term->content.str
1325                                           && cur_term->content.str->stryng
1326                                           && cur_term->content.str->stryng->str
1327                                           && !strcmp (cur_term->content.str->stryng->str, 
1328                                                       "cursive")) {
1329                                        font_type = FONT_FAMILY_CURSIVE;
1330                                } else if (cur_term->content.str
1331                                           && cur_term->content.str->stryng
1332                                           && cur_term->content.str->stryng->str
1333                                           && !strcmp (cur_term->content.str->stryng->str,
1334                                                       "fantasy")) {
1335                                        font_type = FONT_FAMILY_FANTASY;
1336                                } else if (cur_term->content.str
1337                                           && cur_term->content.str->stryng
1338                                           && cur_term->content.str->stryng->str
1339                                           && !strcmp (cur_term->content.str->stryng->str, 
1340                                                       "monospace")) {
1341                                        font_type = FONT_FAMILY_MONOSPACE;
1342                                } else {
1343                                        /*
1344                                         *unknown property value.
1345                                         *ignore it.
1346                                         */
1347                                        continue;
1348                                }
1349
1350                                cur_ff = cr_font_family_new (font_type, NULL);
1351                        }
1352                        break;
1353
1354                case TERM_STRING:
1355                        {
1356                                if (cur_term->content.str
1357                                    && cur_term->content.str->stryng
1358                                    && cur_term->content.str->stryng->str) {
1359                                        cur_ff = cr_font_family_new
1360                                                (FONT_FAMILY_NON_GENERIC,
1361                                                 cur_term->content.str->stryng->str);
1362                                }
1363                        }
1364                        break;
1365
1366                default:
1367                        break;
1368                }
1369
1370                cur_ff2 = cr_font_family_append (font_family, cur_ff);
1371                if (cur_ff2) {
1372                        font_family = cur_ff2;
1373                }
1374        }
1375
1376 out:
1377        if (font_family) {
1378                if (a_style->font_family) {
1379                        cr_font_family_destroy (a_style->font_family);
1380                        a_style->font_family = NULL ;
1381                }
1382                a_style->font_family = font_family;
1383                font_family = NULL ;
1384        }
1385
1386        return CR_OK;
1387}
1388
1389static enum CRStatus
1390init_style_font_size_field (CRStyle * a_style)
1391{
1392        g_return_val_if_fail (a_style, CR_BAD_PARAM_ERROR);
1393
1394        memset (&a_style->font_size, 0, 
1395               sizeof (CRFontSizeVal)) ;
1396        /*
1397        if (!a_style->font_size) {
1398                a_style->font_size = cr_font_size_new ();
1399                if (!a_style->font_size) {
1400                        return CR_INSTANCIATION_FAILED_ERROR;
1401                }
1402        } else {
1403                cr_font_size_clear (a_style->font_size);
1404        }
1405        */
1406        return CR_OK;
1407}
1408
1409static enum CRStatus
1410set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value)
1411{
1412        enum CRStatus status = CR_OK;
1413
1414        g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1415
1416        switch (a_value->type) {
1417        case TERM_IDENT:
1418                if (a_value->content.str
1419                    && a_value->content.str->stryng
1420                    && a_value->content.str->stryng->str
1421                    && !strcmp (a_value->content.str->

Large files files are truncated, but you can click here to view the full file