From 1e592489b152d305a44c3049ab7e263f2be9f6f7 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Sun, 16 Jan 2005 00:03:45 +0000 Subject: [PATCH] [project @ 2005-01-16 00:03:45 by jmb] Create interface for duplication and destruction of css_style structs. svn path=/import/netsurf/; revision=1450 --- css/css.c | 67 +++++++++++++++++++++++++++++++++++++++ css/css.h | 4 ++- css/ruleset.c | 3 +- render/box.c | 86 ++++++++++++++++++++++++++++----------------------- render/html.c | 2 +- 5 files changed, 119 insertions(+), 43 deletions(-) diff --git a/css/css.c b/css/css.c index 1083c9f69..d9cd777b6 100644 --- a/css/css.c +++ b/css/css.c @@ -467,6 +467,73 @@ void css_destroy(struct content *c) free(c->data.css.import_content); } +/** + * Duplicate a CSS style struct + * + * \param style The style to duplicate + * \return The duplicate style, or NULL if out of memory. + */ +struct css_style *css_duplicate_style(const struct css_style * const style) +{ + struct css_style *dup; + + assert(style); + + /* create duplicated style */ + dup = calloc(1, sizeof(struct css_style)); + if (!dup) + return NULL; + + /* copy all style information into duplicate style */ + memcpy(dup, style, sizeof(struct css_style)); + + /* duplicate strings, if in use */ + + /* background_image */ + if (dup->background_image.type == CSS_BACKGROUND_IMAGE_URI) { + dup->background_image.uri = NULL; + dup->background_image.uri = + strdup(style->background_image.uri); + if (!dup->background_image.uri) { + free(dup); + return NULL; + } + } + + /* list_style_image */ + if (dup->list_style_image.type == CSS_LIST_STYLE_IMAGE_URI) { + dup->list_style_image.uri = NULL; + dup->list_style_image.uri = + strdup(style->list_style_image.uri); + if (!dup->list_style_image.uri) { + if (dup->background_image.type == + CSS_BACKGROUND_IMAGE_URI) + free(dup->background_image.uri); + free(dup); + return NULL; + } + } + + return dup; +} + +/** + * Free a CSS style + * + * \param style The style to free + */ +void css_free_style(struct css_style *style) +{ + assert(style); + + if (style->background_image.type == CSS_BACKGROUND_IMAGE_URI) + free(style->background_image.uri); + + if (style->list_style_image.type == CSS_LIST_STYLE_IMAGE_URI) + free(style->list_style_image.uri); + + free(style); +} /** * Create a new struct css_node. diff --git a/css/css.h b/css/css.h index cc5e9bbd6..9c02cf26e 100644 --- a/css/css.h +++ b/css/css.h @@ -112,7 +112,7 @@ typedef enum { CSS_VERTICAL_ALIGN_PERCENT, CSS_VERTICAL_ALIGN_NOT_SET } css_vertical_align_type; - + struct css_counter { const char *name; css_list_style_type style; @@ -560,6 +560,8 @@ const char *css_parser_TokenName(int tokenType); #endif void css_get_style(struct content *c, xmlNode *n, struct css_style * style); +struct css_style *css_duplicate_style(const struct css_style * const style); +void css_free_style(struct css_style *style); void css_cascade(struct css_style * const style, const struct css_style * const apply); void css_merge(struct css_style * const style, diff --git a/css/ruleset.c b/css/ruleset.c index c2ea45618..50ed75743 100644 --- a/css/ruleset.c +++ b/css/ruleset.c @@ -483,13 +483,12 @@ void css_add_ruleset(struct content *c, if (!found) { /* not present: construct a new struct css_style */ LOG(("constructing new style")); - style = malloc(sizeof *style); + style = css_duplicate_style(&css_empty_style); if (!style) { /** \todo report to user */ css_free_selector(sel); return; } - memcpy(style, &css_empty_style, sizeof(*style)); sel->style = style; sel->next = n; if (prev) diff --git a/render/box.c b/render/box.c index 4d57c9f8c..061c022b2 100644 --- a/render/box.c +++ b/render/box.c @@ -344,15 +344,15 @@ bool xml_to_box(xmlNode *n, struct content *c) root.float_children = NULL; root.next_float = NULL; - c->data.html.style = malloc(sizeof (struct css_style)); + c->data.html.style = css_duplicate_style(&css_base_style); if (!c->data.html.style) return false; - memcpy(c->data.html.style, &css_base_style, sizeof(struct css_style)); + c->data.html.style->font_size.value.length.value = option_font_size * 0.1; c->data.html.fonts = nsfont_new_set(); if (!c->data.html.fonts) { - free(c->data.html.style); + css_free_style(c->data.html.style); return false; } @@ -433,8 +433,10 @@ bool convert_xml_to_box(xmlNode *n, struct content *content, gui_multitask(); style = box_get_style(content, parent_style, n); + if (!style) + goto no_memory; if (style->display == CSS_DISPLAY_NONE) { - free(style); + css_free_style(style); goto end; } /* floats are treated as blocks */ @@ -474,7 +476,7 @@ bool convert_xml_to_box(xmlNode *n, struct content *content, if (!box) { /* no box for this element */ assert(!convert_children); - free(style); + css_free_style(style); goto end; } } else { @@ -745,7 +747,7 @@ no_memory: if (!href_in) xmlFree(status.href); if (style && !box) - free(style); + css_free_style(style); return false; } @@ -774,23 +776,30 @@ struct css_style * box_get_style(struct content *c, unsigned int stylesheet_count = c->data.html.stylesheet_count; struct content **stylesheet = c->data.html.stylesheet_content; struct css_style *style; - struct css_style style_new; + struct css_style *style_new; char *url; url_func_result res; - style = malloc(sizeof (struct css_style)); + style = css_duplicate_style(parent_style); if (!style) return 0; - memcpy(style, parent_style, sizeof(struct css_style)); - memcpy(&style_new, &css_blank_style, sizeof(struct css_style)); + style_new = css_duplicate_style(&css_blank_style); + if (!style_new) { + css_free_style(style); + return 0; + } + for (i = 0; i != stylesheet_count; i++) { if (stylesheet[i]) { assert(stylesheet[i]->type == CONTENT_CSS); - css_get_style(stylesheet[i], n, &style_new); + css_get_style(stylesheet[i], n, style_new); } } - css_cascade(style, &style_new); + css_cascade(style, style_new); + + /* style_new isn't needed past this point */ + css_free_style(style_new); /* This property only applies to the body element, if you believe * the spec. Many browsers seem to allow it on other elements too, @@ -798,7 +807,7 @@ struct css_style * box_get_style(struct content *c, if ((s = (char *) xmlGetProp(n, (const xmlChar *) "background"))) { res = url_join(s, c->data.html.base_url, &url); if (res == URL_FUNC_NOMEM) { - free(style); + css_free_style(style); return 0; } else if (res == URL_FUNC_OK) { /* if url is equivalent to the parent's url, @@ -935,10 +944,16 @@ struct css_style * box_get_style(struct content *c, } if ((s = (char *) xmlGetProp(n, (const xmlChar *) "style")) != NULL) { - struct css_style astyle; - memcpy(&astyle, &css_empty_style, sizeof(struct css_style)); - css_parse_property_list(c, &astyle, s); - css_cascade(style, &astyle); + struct css_style *astyle; + astyle = css_duplicate_style(&css_empty_style); + if (!astyle) { + xmlFree(s); + css_free_style(style); + return 0; + } + css_parse_property_list(c, astyle, s); + css_cascade(style, astyle); + css_free_style(astyle); xmlFree(s); } @@ -1843,14 +1858,13 @@ bool box_normalise_block(struct box *block, pool box_pool) case BOX_TABLE_ROW: case BOX_TABLE_CELL: /* insert implied table */ - style = malloc(sizeof *style); + style = css_duplicate_style(block->style); if (!style) return false; - memcpy(style, block->style, sizeof *style); css_cascade(style, &css_blank_style); table = box_create(style, block->href, 0, 0, box_pool); if (!table) { - free(style); + css_free_style(style); return false; } table->type = BOX_TABLE; @@ -1982,19 +1996,18 @@ bool box_normalise_table(struct box *table, pool box_pool) case BOX_TABLE_ROW: case BOX_TABLE_CELL: /* insert implied table row group */ - style = malloc(sizeof *style); + assert(table->style != NULL); + style = css_duplicate_style(table->style); if (!style) { free(col_info.spans); return false; } - assert(table->style != NULL); - memcpy(style, table->style, sizeof *style); css_cascade(style, &css_blank_style); row_group = box_create(style, table->href, 0, 0, box_pool); if (!row_group) { free(col_info.spans); - free(style); + css_free_style(style); return false; } row_group->type = BOX_TABLE_ROW_GROUP; @@ -2091,16 +2104,15 @@ bool box_normalise_table_row_group(struct box *row_group, case BOX_TABLE_ROW_GROUP: case BOX_TABLE_CELL: /* insert implied table row */ - style = malloc(sizeof *style); + assert(row_group->style != NULL); + style = css_duplicate_style(row_group->style); if (!style) return false; - assert(row_group->style != NULL); - memcpy(style, row_group->style, sizeof *style); css_cascade(style, &css_blank_style); row = box_create(style, row_group->href, 0, 0, box_pool); if (!row) { - free(style); + css_free_style(style); return false; } row->type = BOX_TABLE_ROW; @@ -2263,16 +2275,15 @@ bool box_normalise_table_row(struct box *row, case BOX_TABLE_ROW_GROUP: case BOX_TABLE_ROW: /* insert implied table cell */ - style = malloc(sizeof *style); + assert(row->style != NULL); + style = css_duplicate_style(row->style); if (!style) return false; - assert(row->style != NULL); - memcpy(style, row->style, sizeof *style); css_cascade(style, &css_blank_style); cell = box_create(style, row->href, 0, 0, box_pool); if (!cell) { - free(style); + css_free_style(style); return false; } cell->type = BOX_TABLE_CELL; @@ -2448,7 +2459,7 @@ void box_free_box(struct box *box) free(box->title); free(box->col); if (!box->style_clone) - free(box->style); + css_free_style(box->style); } free(box->usemap); @@ -3035,14 +3046,13 @@ struct box_result box_frameset(xmlNode *n, struct box_status *status, /* create the frameset table */ c = n->children; for (row = 0; c && row != rows; row++) { - row_style = malloc(sizeof (struct css_style)); + row_style = css_duplicate_style(style); if (!row_style) { box_free(box); free(row_height); free(col_width); return (struct box_result) {0, false, true}; } - memcpy(row_style, style, sizeof (struct css_style)); object_height = 1000; /** \todo get available height */ /* if (row_height) { row_style->height.height = CSS_HEIGHT_LENGTH; @@ -3080,14 +3090,13 @@ struct box_result box_frameset(xmlNode *n, struct box_status *status, if (col_width && col_width[col].type == LENGTH_PX) object_width = col_width[col].value; - cell_style = malloc(sizeof (struct css_style)); + cell_style = css_duplicate_style(style); if (!cell_style) { box_free(box); free(row_height); free(col_width); return (struct box_result) {0, false, true}; } - memcpy(cell_style, style, sizeof (struct css_style)); css_cascade(cell_style, &css_blank_style); cell_style->overflow = CSS_OVERFLOW_AUTO; @@ -3115,14 +3124,13 @@ struct box_result box_frameset(xmlNode *n, struct box_status *status, continue; } - object_style = malloc(sizeof (struct css_style)); + object_style = css_duplicate_style(style); if (!object_style) { box_free(box); free(row_height); free(col_width); return (struct box_result) {0, false, true}; } - memcpy(object_style, style, sizeof (struct css_style)); if (col_width && col_width[col].type == LENGTH_PX) { object_style->width.width = CSS_WIDTH_LENGTH; object_style->width.value.length.unit = diff --git a/render/html.c b/render/html.c index 068260d3d..36555e259 100644 --- a/render/html.c +++ b/render/html.c @@ -1035,7 +1035,7 @@ void html_destroy(struct content *c) } } free(c->data.html.stylesheet_content); - free(c->data.html.style); + css_free_style(c->data.html.style); if (c->data.html.fonts) nsfont_free_set(c->data.html.fonts);