From 7bd710a71c3233bc44ec66350a9c8d2b7a29c41c Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Sat, 4 Nov 2006 19:53:22 +0000 Subject: Initial work for display: list-item support svn path=/trunk/netsurf/; revision=3028 --- render/box_normalise.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 146 insertions(+), 7 deletions(-) (limited to 'render/box_normalise.c') diff --git a/render/box_normalise.c b/render/box_normalise.c index e241f447f..703622bb9 100644 --- a/render/box_normalise.c +++ b/render/box_normalise.c @@ -57,26 +57,32 @@ static bool calculate_table_row(struct columns *col_info, unsigned int col_span, unsigned int row_span, unsigned int *start_column); static bool box_normalise_inline_container(struct box *cont, struct content *c); +static bool box_normalise_list(struct box *cont, struct content *c); +static bool box_normalise_list_item(struct box *cont, struct content *c); /** * Ensure the box tree is correctly nested by adding and removing nodes. * - * \param block box of type BLOCK, INLINE_BLOCK, or TABLE_CELL + * \param block box of type BLOCK, INLINE_BLOCK, TABLE_CELL or LIST_PRINCIPAL * \param box_pool pool to allocate new boxes in * \return true on success, false on memory exhaustion * * The tree is modified to satisfy the following: * \code * parent permitted child nodes - * BLOCK, INLINE_BLOCK BLOCK, INLINE_CONTAINER, TABLE + * BLOCK, INLINE_BLOCK BLOCK, INLINE_CONTAINER, TABLE, LIST * INLINE_CONTAINER INLINE, INLINE_BLOCK, FLOAT_LEFT, FLOAT_RIGHT, BR, TEXT * INLINE, TEXT 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 \endcode + * FLOAT_(LEFT|RIGHT) exactly 1 BLOCK or TABLE + * LIST at least 1 LIST_ITEM + * LIST_ITEM exactly 1 LIST_MARKER and exactly 1 LIST_PRINCIPAL + * LIST_PRINCIPAL BLOCK, INLINE_CONTAINER, TABLE, LIST (same as BLOCK) + * \endcode */ bool box_normalise_block(struct box *block, struct content *c) @@ -84,12 +90,14 @@ bool box_normalise_block(struct box *block, struct content *c) struct box *child; struct box *next_child; struct box *table; + struct box *list; struct css_style *style; assert(block != 0); LOG(("block %p, block->type %u", block, block->type)); assert(block->type == BOX_BLOCK || block->type == BOX_INLINE_BLOCK || - block->type == BOX_TABLE_CELL); + block->type == BOX_TABLE_CELL || + block->type == BOX_LIST_PRINCIPAL); gui_multitask(); for (child = block->children; child != 0; child = next_child) { @@ -158,6 +166,48 @@ bool box_normalise_block(struct box *block, struct content *c) if (!box_normalise_table(table, c)) return false; break; + case BOX_LIST: + if (!box_normalise_list(child, c)) + return false; + break; + case BOX_LIST_ITEM: + /* Insert implied BOX_LIST */ + style = css_duplicate_style(block->style); + if (!style) + return false; + css_cascade(style, &css_blank_style); + list = box_create(style, 0, 0, 0, 0, c); + if (!list) { + css_free_style(style); + return false; + } + list->type = BOX_LIST; + if (child->prev == 0) + block->children = list; + else + child->prev->next = list; + list->prev = child->prev; + while (child != 0 && child->type == BOX_LIST_ITEM) { + box_add_child(list, child); + next_child = child->next; + child->next = 0; + child = next_child; + } + list->last->next = 0; + list->next = next_child = child; + if (list->next) + list->next->prev = list; + else + block->last = list; + list->parent = block; + if (!box_normalise_list(list, c)) + return false; + break; + case BOX_LIST_MARKER: + case BOX_LIST_PRINCIPAL: + /* Should be wrapped in BOX_LIST_ITEM */ + assert(0); + break; default: assert(0); } @@ -205,6 +255,8 @@ bool box_normalise_table(struct box *table, struct content * c) case BOX_TABLE: case BOX_TABLE_ROW: case BOX_TABLE_CELL: + case BOX_LIST: + case BOX_LIST_ITEM: /* insert implied table row group */ assert(table->style != NULL); style = css_duplicate_style(table->style); @@ -233,12 +285,15 @@ bool box_normalise_table(struct box *table, struct content * c) child->type == BOX_INLINE_CONTAINER || child->type == BOX_TABLE || child->type == BOX_TABLE_ROW || - child->type == BOX_TABLE_CELL)) { + child->type == BOX_TABLE_CELL || + child->type == BOX_LIST || + child->type == BOX_LIST_ITEM)) { box_add_child(row_group, child); next_child = child->next; child->next = 0; child = next_child; } + assert(row_group->last != NULL); row_group->last->next = 0; row_group->next = next_child = child; if (row_group->next) @@ -261,6 +316,11 @@ bool box_normalise_table(struct box *table, struct content * c) container by convert_xml_to_box() */ assert(0); break; + case BOX_LIST_MARKER: + case BOX_LIST_PRINCIPAL: + /* Should have been wrapped in BOX_LIST_ITEM */ + assert(0); + break; default: fprintf(stderr, "%i\n", child->type); assert(0); @@ -381,6 +441,8 @@ bool box_normalise_table_row_group(struct box *row_group, case BOX_TABLE: case BOX_TABLE_ROW_GROUP: case BOX_TABLE_CELL: + case BOX_LIST: + case BOX_LIST_ITEM: /* insert implied table row */ assert(row_group->style != NULL); style = css_duplicate_style(row_group->style); @@ -404,12 +466,15 @@ bool box_normalise_table_row_group(struct box *row_group, child->type == BOX_INLINE_CONTAINER || child->type == BOX_TABLE || child->type == BOX_TABLE_ROW_GROUP || - child->type == BOX_TABLE_CELL)) { + child->type == BOX_TABLE_CELL || + child->type == BOX_LIST || + child->type == BOX_LIST_ITEM)) { box_add_child(row, child); next_child = child->next; child->next = 0; child = next_child; } + assert(row->last != NULL); row->last->next = 0; row->next = next_child = child; if (row->next) @@ -430,6 +495,11 @@ bool box_normalise_table_row_group(struct box *row_group, container by convert_xml_to_box() */ assert(0); break; + case BOX_LIST_MARKER: + case BOX_LIST_PRINCIPAL: + /* should have been wrapped in LIST_ITEM */ + assert(0); + break; default: assert(0); } @@ -480,6 +550,8 @@ bool box_normalise_table_row(struct box *row, case BOX_TABLE: case BOX_TABLE_ROW_GROUP: case BOX_TABLE_ROW: + case BOX_LIST: + case BOX_LIST_ITEM: /* insert implied table cell */ assert(row->style != NULL); style = css_duplicate_style(row->style); @@ -503,12 +575,15 @@ bool box_normalise_table_row(struct box *row, child->type == BOX_INLINE_CONTAINER || child->type == BOX_TABLE || child->type == BOX_TABLE_ROW_GROUP || - child->type == BOX_TABLE_ROW)) { + child->type == BOX_TABLE_ROW || + child->type == BOX_LIST || + child->type == BOX_LIST_ITEM)) { box_add_child(cell, child); next_child = child->next; child->next = 0; child = next_child; } + assert(cell->last != NULL); cell->last->next = 0; cell->next = next_child = child; if (cell->next) @@ -528,6 +603,11 @@ bool box_normalise_table_row(struct box *row, container by convert_xml_to_box() */ assert(0); break; + case BOX_LIST_MARKER: + case BOX_LIST_PRINCIPAL: + /* should have been wrapped in a BOX_LIST_ITEM */ + assert(0); + break; default: assert(0); } @@ -703,6 +783,10 @@ bool box_normalise_inline_container(struct box *cont, struct content * c) case BOX_TABLE_ROW_GROUP: case BOX_TABLE_ROW: case BOX_TABLE_CELL: + case BOX_LIST: + case BOX_LIST_ITEM: + case BOX_LIST_MARKER: + case BOX_LIST_PRINCIPAL: default: assert(0); } @@ -712,3 +796,58 @@ bool box_normalise_inline_container(struct box *cont, struct content * c) return true; } + +bool box_normalise_list(struct box *cont, struct content *c) +{ + struct box *child; + struct box *next_child; + + assert(cont != 0); + assert(cont->type == BOX_LIST); + + for (child = cont->children; child; child = next_child) { + next_child = child->next; + switch (child->type) { + case BOX_LIST_ITEM: + /* ok */ + if (!box_normalise_list_item(child, c)) + return false; + break; + case BOX_LIST_MARKER: + case BOX_LIST_PRINCIPAL: + /** \todo imply LIST_ITEM here? */ + default: + assert(0); + } + } + + return true; +} + + +bool box_normalise_list_item(struct box *cont, struct content *c) +{ + struct box *child; + struct box *next_child; + + assert(cont != 0); + assert(cont->type == BOX_LIST_ITEM); + + for (child = cont->children; child; child = next_child) { + next_child = child->next; + switch (child->type) { + case BOX_LIST_MARKER: + /* ok */ + break; + case BOX_LIST_PRINCIPAL: + /* ok */ + if (!box_normalise_block(child, c)) + return false; + break; + default: + assert(0); + } + } + + return true; +} -- cgit v1.2.3