From ce7db348639c02023ad507d81d7c102b8878a0f2 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Thu, 2 Jan 2003 13:26:43 +0000 Subject: [project @ 2003-01-02 13:26:43 by bursa] Whitespace and box tree normalisation changes. svn path=/import/netsurf/; revision=81 --- render/box.c | 184 +++++++++++++++++++++++++++++++++++++++++------------------ render/box.h | 3 +- 2 files changed, 132 insertions(+), 55 deletions(-) diff --git a/render/box.c b/render/box.c index 65694810b..32ef6819a 100644 --- a/render/box.c +++ b/render/box.c @@ -1,5 +1,5 @@ /** - * $Id: box.c,v 1.25 2002/12/30 22:56:30 monkeyson Exp $ + * $Id: box.c,v 1.26 2003/01/02 13:26:43 bursa Exp $ */ #include @@ -48,10 +48,13 @@ void box_normalise_inline_container(struct box *cont); void box_add_child(struct box * parent, struct box * child) { - if (parent->children != 0) /* has children already */ + if (parent->children != 0) { /* has children already */ parent->last->next = child; - else /* this is the first child */ + child->prev = parent->last; + } else { /* this is the first child */ parent->children = child; + child->prev = 0; + } parent->last = child; child->parent = parent; @@ -75,6 +78,7 @@ struct box * box_create(xmlNode * node, box_type type, struct css_style * style, box->length = 0; box->columns = 1; box->next = 0; + box->prev = 0; box->children = 0; box->last = 0; box->parent = 0; @@ -208,13 +212,23 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, (n->type == XML_ELEMENT_NODE && (strcmp((const char *) n->name, "img") == 0)) || (n->type == XML_ELEMENT_NODE && (style->float_ == CSS_FLOAT_LEFT || style->float_ == CSS_FLOAT_RIGHT))) { + char * text = 0; + int ignore; + + if (n->type == XML_TEXT_NODE) + text = squash_whitespace(tolat1(n->content)); + ignore = n->type == XML_TEXT_NODE && text[0] == ' ' && text[1] == 0; + /* text nodes are converted to inline boxes, wrapped in an inline container block */ - if (inline_container == 0) { /* this is the first inline node: make a container */ + if (inline_container == 0 && !ignore) { + /* this is the first inline node: make a container */ inline_container = xcalloc(1, sizeof(struct box)); inline_container->type = BOX_INLINE_CONTAINER; box_add_child(parent, inline_container); } - if (n->type == XML_TEXT_NODE) { + if (ignore) { + xfree(text); + } else if (n->type == XML_TEXT_NODE) { LOG2("TEXT NODE"); if (current_textarea != 0) { @@ -233,7 +247,7 @@ struct box * convert_xml_to_box(xmlNode * n, struct css_style * parent_style, { LOG2(("text node")); box = box_create(n, BOX_INLINE, parent_style, href); - box->text = squash_whitespace(tolat1(n->content)); + box->text = text; box->length = strlen(box->text); if (box->text[box->length - 1] == ' ') { box->space = 1; @@ -486,20 +500,32 @@ void box_dump(struct box * box, unsigned int depth) /** * ensure the box tree is correctly nested + * + * parent permitted child nodes + * BLOCK BLOCK, INLINE_CONTAINER, TABLE + * INLINE_CONTAINER INLINE, FLOAT_LEFT, FLOAT_RIGHT + * INLINE none + * TABLE at least 1 TABLE_ROW_GROUP + * TABLE_ROW_GROUP at least 1 TABLE_ROW + * TABLE_ROW at least 1 TABLE_CELL + * TABLE_CELL BLOCK, INLINE_CONTAINER, TABLE (same as BLOCK) + * FLOAT_(LEFT|RIGHT) exactly 1 BLOCK or TABLE */ void box_normalise_block(struct box *block) { struct box *child; - struct box *prev_child = 0; + struct box *next_child; struct box *table; struct css_style *style; - LOG(("block %p", block)); + assert(block != 0); assert(block->type == BOX_BLOCK || block->type == BOX_TABLE_CELL); + LOG(("block %p, block->type", block, block->type)); - for (child = block->children; child != 0; prev_child = child, child = child->next) { - fprintf(stderr, "child->type = %d\n", child->type); + for (child = block->children; child != 0; child = next_child) { + LOG(("child %p, child->type = %d", child, child->type)); + next_child = child->next; /* child may be destroyed */ switch (child->type) { case BOX_BLOCK: /* ok */ @@ -526,42 +552,44 @@ void box_normalise_block(struct box *block) memcpy(style, block->style, sizeof(struct css_style)); css_cascade(style, &css_blank_style); table = box_create(0, BOX_TABLE, style, block->href); - if (prev_child == 0) + if (child->prev == 0) block->children = table; else - prev_child->next = table; + child->prev->next = table; + table->prev = child->prev; while (child != 0 && ( child->type == BOX_TABLE_ROW_GROUP || child->type == BOX_TABLE_ROW || child->type == BOX_TABLE_CELL)) { box_add_child(table, child); - prev_child = child; child = child->next; } - prev_child->next = 0; - table->next = child; + table->last->next = 0; + table->next = next_child = child; table->parent = block; box_normalise_table(table); - child = table; break; default: assert(0); } } + LOG(("block %p done", block)); } void box_normalise_table(struct box *table) { struct box *child; - struct box *prev_child = 0; + struct box *next_child; struct box *row_group; struct css_style *style; - LOG(("table %p", table)); + assert(table != 0); assert(table->type == BOX_TABLE); + LOG(("table %p", table)); - for (child = table->children; child != 0; prev_child = child, child = child->next) { + for (child = table->children; child != 0; child = next_child) { + next_child = child->next; switch (child->type) { case BOX_TABLE_ROW_GROUP: /* ok */ @@ -578,10 +606,11 @@ void box_normalise_table(struct box *table) memcpy(style, table->style, sizeof(struct css_style)); css_cascade(style, &css_blank_style); row_group = box_create(0, BOX_TABLE_ROW_GROUP, style, table->href); - if (prev_child == 0) + if (child->prev == 0) table->children = row_group; else - prev_child->next = row_group; + child->prev->next = row_group; + row_group->prev = child->prev; while (child != 0 && ( child->type == BOX_BLOCK || child->type == BOX_INLINE_CONTAINER || @@ -589,14 +618,12 @@ void box_normalise_table(struct box *table) child->type == BOX_TABLE_ROW || child->type == BOX_TABLE_CELL)) { box_add_child(row_group, child); - prev_child = child; child = child->next; } - prev_child->next = 0; - row_group->next = child; + row_group->last->next = 0; + row_group->next = next_child = child; row_group->parent = table; box_normalise_table_row_group(row_group); - child = row_group; break; case BOX_INLINE: case BOX_FLOAT_LEFT: @@ -610,20 +637,35 @@ void box_normalise_table(struct box *table) assert(0); } } + + if (table->children == 0) { + LOG(("table->children == 0, removing")); + if (table->prev == 0) + table->parent->children = table->next; + else + table->prev->next = table->next; + if (table->next != 0) + table->next->prev = table->prev; + box_free_box(table); + } + + LOG(("table %p done", table)); } void box_normalise_table_row_group(struct box *row_group) { struct box *child; - struct box *prev_child = 0; + struct box *next_child; struct box *row; struct css_style *style; - LOG(("row_group %p", row_group)); + assert(row_group != 0); assert(row_group->type == BOX_TABLE_ROW_GROUP); + LOG(("row_group %p", row_group)); - for (child = row_group->children; child != 0; prev_child = child, child = child->next) { + for (child = row_group->children; child != 0; child = next_child) { + next_child = child->next; switch (child->type) { case BOX_TABLE_ROW: /* ok */ @@ -639,10 +681,11 @@ void box_normalise_table_row_group(struct box *row_group) memcpy(style, row_group->style, sizeof(struct css_style)); css_cascade(style, &css_blank_style); row = box_create(0, BOX_TABLE_ROW, style, row_group->href); - if (prev_child == 0) + if (child->prev == 0) row_group->children = row; else - prev_child->next = row; + child->prev->next = row; + row->prev = child->prev; while (child != 0 && ( child->type == BOX_BLOCK || child->type == BOX_INLINE_CONTAINER || @@ -650,14 +693,12 @@ void box_normalise_table_row_group(struct box *row_group) child->type == BOX_TABLE_ROW_GROUP || child->type == BOX_TABLE_CELL)) { box_add_child(row, child); - prev_child = child; child = child->next; } - prev_child->next = 0; - row->next = child; + row->last->next = 0; + row->next = next_child = child; row->parent = row_group; box_normalise_table_row(row); - child = row; break; case BOX_INLINE: case BOX_FLOAT_LEFT: @@ -670,21 +711,36 @@ void box_normalise_table_row_group(struct box *row_group) assert(0); } } + + if (row_group->children == 0) { + LOG(("row_group->children == 0, removing")); + if (row_group->prev == 0) + row_group->parent->children = row_group->next; + else + row_group->prev->next = row_group->next; + if (row_group->next != 0) + row_group->next->prev = row_group->prev; + box_free_box(row_group); + } + + LOG(("row_group %p done", row_group)); } void box_normalise_table_row(struct box *row) { struct box *child; - struct box *prev_child = 0; + struct box *next_child; struct box *cell; struct css_style *style; unsigned int columns = 0; - LOG(("row %p", row)); + assert(row != 0); assert(row->type == BOX_TABLE_ROW); + LOG(("row %p", row)); - for (child = row->children; child != 0; prev_child = child, child = child->next) { + for (child = row->children; child != 0; child = next_child) { + next_child = child->next; switch (child->type) { case BOX_TABLE_CELL: /* ok */ @@ -701,10 +757,11 @@ void box_normalise_table_row(struct box *row) memcpy(style, row->style, sizeof(struct css_style)); css_cascade(style, &css_blank_style); cell = box_create(0, BOX_TABLE_CELL, style, row->href); - if (prev_child == 0) + if (child->prev == 0) row->children = cell; else - prev_child->next = cell; + child->prev->next = cell; + cell->prev = child->prev; while (child != 0 && ( child->type == BOX_BLOCK || child->type == BOX_INLINE_CONTAINER || @@ -712,14 +769,12 @@ void box_normalise_table_row(struct box *row) child->type == BOX_TABLE_ROW_GROUP || child->type == BOX_TABLE_ROW)) { box_add_child(cell, child); - prev_child = child; child = child->next; } - prev_child->next = 0; - cell->next = child; + cell->last->next = 0; + cell->next = next_child = child; cell->parent = row; box_normalise_block(cell); - child = cell; columns++; break; case BOX_INLINE: @@ -735,18 +790,33 @@ void box_normalise_table_row(struct box *row) } if (row->parent->parent->columns < columns) row->parent->parent->columns = columns; + + if (row->children == 0) { + LOG(("row->children == 0, removing")); + if (row->prev == 0) + row->parent->children = row->next; + else + row->prev->next = row->next; + if (row->next != 0) + row->next->prev = row->prev; + box_free_box(row); + } + + LOG(("row %p done", row)); } void box_normalise_inline_container(struct box *cont) { struct box *child; - struct box *prev_child = 0; + struct box *next_child; - LOG(("cont %p", cont)); + assert(cont != 0); assert(cont->type == BOX_INLINE_CONTAINER); + LOG(("cont %p", cont)); - for (child = cont->children; child != 0; prev_child = child, child = child->next) { + for (child = cont->children; child != 0; child = next_child) { + next_child = child->next; switch (child->type) { case BOX_INLINE: /* ok */ @@ -776,6 +846,7 @@ void box_normalise_inline_container(struct box *cont) assert(0); } } + LOG(("cont %p done", cont)); } @@ -785,7 +856,7 @@ void gadget_free(struct gui_gadget* g) if (g->name != 0) xfree(g->name); - + switch (g->type) { case GADGET_HIDDEN: @@ -843,6 +914,11 @@ void box_free(struct box *box) box_free(box->next); /* last this box */ + box_free_box(box); +} + +void box_free_box(struct box *box) +{ // if (box->style != 0) // free(box->style); if (box->gadget != 0) @@ -855,7 +931,7 @@ void box_free(struct box *box) { free((void*)box->img); } - + if (box->text != 0) free((void*)box->text); /* only free href if we're the top most user */ @@ -887,7 +963,7 @@ struct box* box_image(xmlNode * n, struct css_style* style, char* href) } else box->img->width = 24; - + if ((s = (char *) xmlGetProp(n, (xmlChar *) "height"))) { box->img->height = atoi(s); @@ -935,7 +1011,7 @@ struct box* box_textarea(xmlNode* n, struct css_style* style, struct form* curre } else box->gadget->data.textarea.rows = 16; - + if ((s = (char *) xmlGetProp(n, (xmlChar *) "name"))) { box->gadget->name = s; @@ -1098,7 +1174,7 @@ struct box* box_input(xmlNode * n, struct css_style* style, struct form* current box->gadget->data.radio.selected = -1; free(s); } - + if ((s = (char *) xmlGetProp(n, (xmlChar *) "value"))) { if (type[0] == 'c') box->gadget->data.checkbox.value = s; @@ -1126,7 +1202,7 @@ struct box* box_input(xmlNode * n, struct css_style* style, struct form* current if ((s = (char *) xmlGetProp(n, (xmlChar *) "value"))) { box->gadget->data.actionbutt.label = s; } - else + else { box->gadget->data.actionbutt.label = strdup(type); box->gadget->data.actionbutt.label[0] = toupper(type[0]); @@ -1164,7 +1240,7 @@ struct box* box_input(xmlNode * n, struct css_style* style, struct form* current box->gadget->data.textbox.text = xcalloc(box->gadget->data.textbox.maxlength + 1, sizeof(char)); if ((s = (char *) xmlGetProp(n, (xmlChar *) "value"))) { - strncpy(box->gadget->data.textbox.text, s, + strncpy(box->gadget->data.textbox.text, s, box->gadget->data.textbox.maxlength); free(s); } @@ -1184,7 +1260,7 @@ struct form* box_form(xmlNode* n) char* s; form = xcalloc(1, sizeof(struct form*)); - + if ((s = (char *) xmlGetProp(n, (xmlChar *) "action"))) { form->action = s; } diff --git a/render/box.h b/render/box.h index eb6589118..38e377fc6 100644 --- a/render/box.h +++ b/render/box.h @@ -1,5 +1,5 @@ /** - * $Id: box.h,v 1.15 2002/12/30 22:56:30 monkeyson Exp $ + * $Id: box.h,v 1.16 2003/01/02 13:26:43 bursa Exp $ */ #ifndef _NETSURF_RENDER_BOX_H_ @@ -93,6 +93,7 @@ struct box { unsigned int length; unsigned int columns; struct box * next; + struct box * prev; struct box * children; struct box * last; struct box * parent; -- cgit v1.2.3