diff options
-rw-r--r-- | src/stylesheet.c | 86 | ||||
-rw-r--r-- | src/stylesheet.h | 95 |
2 files changed, 117 insertions, 64 deletions
diff --git a/src/stylesheet.c b/src/stylesheet.c index 7e634a9..ea3f2a6 100644 --- a/src/stylesheet.c +++ b/src/stylesheet.c @@ -595,15 +595,40 @@ css_error css_stylesheet_rule_create(css_stylesheet *sheet, css_rule_type type, css_rule **rule) { css_rule *r; + size_t required = 0; if (sheet == NULL || rule == NULL) return CSS_BADPARM; - r = sheet->alloc(NULL, sizeof(css_rule), sheet->pw); + switch (type) { + case CSS_RULE_UNKNOWN: + required = sizeof(css_rule); + break; + case CSS_RULE_SELECTOR: + required = sizeof(css_rule_selector); + break; + case CSS_RULE_CHARSET: + required = sizeof(css_rule_charset); + break; + case CSS_RULE_IMPORT: + required = sizeof(css_rule_import); + break; + case CSS_RULE_MEDIA: + required = sizeof(css_rule_media); + break; + case CSS_RULE_FONT_FACE: + required = sizeof(css_rule_font_face); + break; + case CSS_RULE_PAGE: + required = sizeof(css_rule_page); + break; + } + + r = sheet->alloc(NULL, required, sheet->pw); if (r == NULL) return CSS_NOMEM; - memset(r, 0, sizeof(css_rule)); + memset(r, 0, required); r->type = type; @@ -641,6 +666,7 @@ css_error css_stylesheet_rule_destroy(css_stylesheet *sheet, css_rule *rule) css_error css_stylesheet_rule_add_selector(css_stylesheet *sheet, css_rule *rule, css_selector *selector) { + css_rule_selector *r = (css_rule_selector *) rule; css_selector **sels; if (sheet == NULL || rule == NULL || selector == NULL) @@ -650,17 +676,16 @@ css_error css_stylesheet_rule_add_selector(css_stylesheet *sheet, if (rule->type != CSS_RULE_SELECTOR) return CSS_INVALID; - sels = sheet->alloc(rule->data.selector.selectors, - (rule->data.selector.selector_count + 1) * - sizeof(css_selector *), + sels = sheet->alloc(r->selectors, + (r->base.items + 1) * sizeof(css_selector *), sheet->pw); if (sels == NULL) return CSS_NOMEM; /* Insert into rule's selector list */ - sels[rule->data.selector.selector_count] = selector; - rule->data.selector.selector_count++; - rule->data.selector.selectors = sels; + sels[r->base.items] = selector; + r->base.items++; + r->selectors = sels; /* Set selector's rule field */ selector->rule = rule; @@ -688,9 +713,9 @@ css_error css_stylesheet_rule_append_style(css_stylesheet *sheet, return CSS_INVALID; if (rule->type == CSS_RULE_SELECTOR) - cur = rule->data.selector.style; + cur = ((css_rule_selector *) rule)->style; else - cur = rule->data.page.style; + cur = ((css_rule_page *) rule)->style; if (cur != NULL) { /* Already have a style, so append to the end of the bytecode */ @@ -718,9 +743,9 @@ css_error css_stylesheet_rule_append_style(css_stylesheet *sheet, } if (rule->type == CSS_RULE_SELECTOR) - rule->data.selector.style = cur; + ((css_rule_selector *) rule)->style = cur; else - rule->data.page.style = cur; + ((css_rule_page *) rule)->style = cur; return CSS_OK; } @@ -739,9 +764,10 @@ css_error css_stylesheet_add_rule(css_stylesheet *sheet, css_rule *rule) if (sheet == NULL || rule == NULL) return CSS_BADPARM; - /* Fill in rule's index and owner fields */ + /* Fill in rule's index and parent fields */ rule->index = sheet->rule_count; - rule->owner = sheet; + rule->ptype = CSS_RULE_PARENT_STYLESHEET; + rule->parent = sheet; /* Add rule to sheet */ sheet->rule_count++; @@ -831,8 +857,6 @@ void css_stylesheet_dump(css_stylesheet *sheet, FILE *target) */ void css_stylesheet_dump_rule(css_rule *rule, FILE *target, size_t *size) { - *size += sizeof(css_rule); - fprintf(target, " Rule %d (type %d):\n", rule->index, rule->type); @@ -840,29 +864,42 @@ void css_stylesheet_dump_rule(css_rule *rule, FILE *target, size_t *size) switch (rule->type) { case CSS_RULE_UNKNOWN: + *size += sizeof(css_rule); break; case CSS_RULE_SELECTOR: - for (uint32_t i = 0; i < rule->data.selector.selector_count; - i++) { + *size += sizeof(css_rule_selector); + for (uint32_t i = 0; i < rule->items; i++) { css_stylesheet_dump_selector_list( - rule->data.selector.selectors[i], target, size); - if (i != rule->data.selector.selector_count - 1) + ((css_rule_selector *) rule)->selectors[i], + target, size); + if (i != (uint32_t) (rule->items - 1)) fprintf(target, ", "); } fprintf(target, " { "); - if (rule->data.selector.style != NULL) { - *size += rule->data.selector.style->length; + if (((css_rule_selector *) rule)->style != NULL) { + *size += ((css_rule_selector *) rule)->style->length; - css_bytecode_dump(rule->data.selector.style->bytecode, - rule->data.selector.style->length, target); + css_bytecode_dump( + ((css_rule_selector *) rule)->style->bytecode, + ((css_rule_selector *) rule)->style->length, + target); } fprintf(target, "}"); break; case CSS_RULE_CHARSET: + *size += sizeof(css_rule_charset); + break; case CSS_RULE_IMPORT: + *size += sizeof(css_rule_import); + break; case CSS_RULE_MEDIA: + *size += sizeof(css_rule_media); + break; case CSS_RULE_FONT_FACE: + *size += sizeof(css_rule_font_face); + break; case CSS_RULE_PAGE: + *size += sizeof(css_rule_page); break; } @@ -935,7 +972,6 @@ void css_stylesheet_dump_selector(css_selector *selector, FILE *target, void css_stylesheet_dump_selector_detail(css_selector_detail *detail, FILE *target, size_t *size) { - *size += sizeof(css_selector_detail); switch (detail->type) { diff --git a/src/stylesheet.h b/src/stylesheet.h index c5c2812..2156b8e 100644 --- a/src/stylesheet.h +++ b/src/stylesheet.h @@ -77,48 +77,65 @@ typedef enum css_rule_type { CSS_RULE_PAGE } css_rule_type; +typedef enum css_rule_parent_type { + CSS_RULE_PARENT_STYLESHEET, + CSS_RULE_PARENT_RULE +} css_rule_parent_type; + struct css_rule { - css_rule_type type; /**< Type of rule */ - - union { - struct { - uint32_t selector_count; - css_selector **selectors; - css_style *style; - } selector; - struct { - uint32_t media; - uint32_t rule_count; - css_rule **rules; /** \todo why this? isn't the - * child list sufficient? */ - } media; - struct { - css_style *style; - } font_face; - struct { - uint32_t selector_count; - css_selector **selectors; - css_style *style; - } page; - struct { - css_stylesheet *sheet; - } import; - struct { - char *encoding; /** \todo use MIB enum? */ - } charset; - } data; /**< Rule data */ - - uint32_t index; /**< Index of rule in sheet */ - - css_stylesheet *owner; /**< Owning sheet */ - - css_rule *parent; /**< Parent rule */ - css_rule *first_child; /**< First in child list */ - css_rule *last_child; /**< Last in child list */ - css_rule *next; /**< Next rule */ - css_rule *prev; /**< Previous rule */ + void *parent; /**< containing rule or owning + * stylesheet (defined by ptype) + */ + css_rule *next; /**< next in list */ + css_rule *prev; /**< previous in list */ + + uint32_t type : 4, /**< css_rule_type */ + index : 16, /**< index in sheet */ + items : 8, /**< # items in rule */ + ptype : 1; /**< css_rule_parent_type */ }; +typedef struct css_rule_selector { + css_rule base; + + css_selector **selectors; + css_style *style; +} css_rule_selector; + +typedef struct css_rule_media { + css_rule base; + + uint32_t media; + + css_rule *first_child; + css_rule *last_child; +} css_rule_media; + +typedef struct css_rule_font_face { + css_rule base; + + css_style *style; +} css_rule_font_face; + +typedef struct css_rule_page { + css_rule base; + + css_selector **selectors; + css_style *style; +} css_rule_page; + +typedef struct css_rule_import { + css_rule base; + + css_stylesheet *sheet; +} css_rule_import; + +typedef struct css_rule_charset { + css_rule base; + + char *encoding; /** \todo use MIB enum? */ +} css_rule_charset; + struct css_stylesheet { #define HASH_SIZE (37) css_selector *selectors[HASH_SIZE]; /**< Hashtable of selectors */ |