summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2008-11-28 01:36:03 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2008-11-28 01:36:03 +0000
commit5aa8288b483e07769ae363d23c7cb27d9613a9d5 (patch)
tree4b5157ce5e35f68157d4521203640b6b6e3e83eb
parent7adaf92154adc7f3455769ca197f906e3d4cddaa (diff)
downloadlibcss-5aa8288b483e07769ae363d23c7cb27d9613a9d5.tar.gz
libcss-5aa8288b483e07769ae363d23c7cb27d9613a9d5.tar.bz2
Change the way in which css_rules are defined. This is more compact than the previous approach. Space requirements for rule objects alone is now 447,120 bytes as opposed to 819,270 bytes previously. This reduces the space requirements for allzengarden.css to 2,041,712 bytes, which is 45% the size of what we had originally.
svn path=/trunk/libcss/; revision=5810
-rw-r--r--src/stylesheet.c86
-rw-r--r--src/stylesheet.h95
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 */