From ddeadd1c02880367ad786b113d352a519f45ec73 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Thu, 23 Jul 2009 23:05:34 +0000 Subject: Merge LibCSS port to trunk. svn path=/trunk/netsurf/; revision=8752 --- render/box_normalise.c | 637 ++++++++++++++++++++++++++++++------------------- 1 file changed, 386 insertions(+), 251 deletions(-) (limited to 'render/box_normalise.c') diff --git a/render/box_normalise.c b/render/box_normalise.c index 865433e26..fc563e743 100644 --- a/render/box_normalise.c +++ b/render/box_normalise.c @@ -26,6 +26,7 @@ #include #include #include "css/css.h" +#include "css/select.h" #include "render/box.h" #include "render/table.h" #include "desktop/gui.h" @@ -35,29 +36,34 @@ #include "utils/talloc.h" +/** + * Row spanning information for a cell + */ struct span_info { + /** Number of rows this cell spans */ unsigned int row_span; + /** The cell in this column spans all rows until the end of the table */ bool auto_row; - bool auto_column; }; +/** + * Column record for a table + */ struct columns { + /** Current column index */ unsigned int current_column; - bool extra; - /* Number of columns in main part of table 1..max columns */ + /** Number of columns in main part of table 1..max columns */ unsigned int num_columns; - /* Information about columns in main table, - array 0 to num_columns - 1 */ + /** Information about columns in main table, array [0, num_columns) */ struct span_info *spans; - /* Number of columns that have cells after a colspan 0 */ - unsigned int extra_columns; - /* Number of rows in table */ + /** Number of rows in table */ unsigned int num_rows; }; static bool box_normalise_table(struct box *table, struct content *c); -static void box_normalise_table_spans(struct box *table); +static bool box_normalise_table_spans(struct box *table, + struct span_info *spans, struct content *c); static bool box_normalise_table_row_group(struct box *row_group, struct columns *col_info, struct content *c); @@ -69,6 +75,18 @@ static bool calculate_table_row(struct columns *col_info, unsigned int *start_column); static bool box_normalise_inline_container(struct box *cont, struct content *c); +/** + * Allocator + * + * \param ptr Pointer to reallocate, or NULL for new allocation + * \param size Number of bytes requires + * \param pw Allocation context + * \return Pointer to allocated block, or NULL on failure + */ +static void *myrealloc(void *ptr, size_t len, void *pw) +{ + return talloc_realloc_size(pw, ptr, len); +} /** * Ensure the box tree is correctly nested by adding and removing nodes. @@ -96,30 +114,34 @@ bool box_normalise_block(struct box *block, struct content *c) struct box *child; struct box *next_child; struct box *table; - struct css_style *style; + css_computed_style *style; + + assert(block != NULL); - 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); + gui_multitask(); - for (child = block->children; child != 0; child = next_child) { + for (child = block->children; child != NULL; 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 */ - if (!box_normalise_block(child, c)) + if (box_normalise_block(child, c) == false) return false; break; case BOX_INLINE_CONTAINER: - if (!box_normalise_inline_container(child, - c)) + if (box_normalise_inline_container(child, c) == false) return false; break; case BOX_TABLE: - if (!box_normalise_table(child, c)) + if (box_normalise_table(child, c) == false) return false; break; case BOX_INLINE: @@ -137,37 +159,48 @@ bool box_normalise_block(struct box *block, struct content *c) case BOX_TABLE_ROW: case BOX_TABLE_CELL: /* insert implied table */ - style = talloc_memdup(c, block->style, sizeof *style); - if (!style) + assert(block->style != NULL); + + style = nscss_get_blank_style(c, block->style, + myrealloc, c); + if (style == NULL) return false; - css_cascade(style, &css_blank_style, NULL); + table = box_create(style, block->href, block->target, - 0, 0, c); - if (!table) { - talloc_free(style); + NULL, NULL, c); + if (table == NULL) { + css_computed_style_destroy(style); return false; } table->type = BOX_TABLE; - if (child->prev == 0) + + if (child->prev == NULL) block->children = table; else child->prev->next = table; + table->prev = child->prev; - while (child != 0 && ( + + while (child != NULL && ( child->type == BOX_TABLE_ROW_GROUP || child->type == BOX_TABLE_ROW || child->type == BOX_TABLE_CELL)) { box_add_child(table, child); + next_child = child->next; - child->next = 0; + child->next = NULL; child = next_child; } - table->last->next = 0; + + table->last->next = NULL; table->next = next_child = child; - if (table->next) + if (table->next != NULL) table->next->prev = table; + else + block->last = table; table->parent = block; - if (!box_normalise_table(table, c)) + + if (box_normalise_table(table, c) == false) return false; break; default: @@ -184,30 +217,32 @@ bool box_normalise_table(struct box *table, struct content * c) struct box *child; struct box *next_child; struct box *row_group; - struct css_style *style; + css_computed_style *style; struct columns col_info; - assert(table != 0); + assert(table != NULL); assert(table->type == BOX_TABLE); + LOG(("table %p", table)); + col_info.num_columns = 1; col_info.current_column = 0; col_info.spans = malloc(2 * sizeof *col_info.spans); - if (!col_info.spans) + if (col_info.spans == NULL) return false; + col_info.spans[0].row_span = col_info.spans[1].row_span = 0; - col_info.spans[0].auto_row = col_info.spans[0].auto_column = - col_info.spans[1].auto_row = col_info.spans[1].auto_column = false; - col_info.num_rows = col_info.extra_columns = 0; - col_info.extra = false; + col_info.spans[0].auto_row = false; + col_info.spans[1].auto_row = false; + col_info.num_rows = 0; - for (child = table->children; child != 0; child = next_child) { + for (child = table->children; child != NULL; child = next_child) { next_child = child->next; switch (child->type) { case BOX_TABLE_ROW_GROUP: /* ok */ - if (!box_normalise_table_row_group(child, - &col_info, c)) { + if (box_normalise_table_row_group(child, + &col_info, c) == false) { free(col_info.spans); return false; } @@ -219,46 +254,56 @@ bool box_normalise_table(struct box *table, struct content * c) case BOX_TABLE_CELL: /* insert implied table row group */ assert(table->style != NULL); - style = talloc_memdup(c, table->style, sizeof *style); - if (!style) { + + style = nscss_get_blank_style(c, table->style, + myrealloc, c); + if (style == NULL) { free(col_info.spans); return false; } - css_cascade(style, &css_blank_style, NULL); + row_group = box_create(style, table->href, - table->target, 0, 0, c); - if (!row_group) { + table->target, NULL, NULL, c); + if (row_group == NULL) { + css_computed_style_destroy(style); free(col_info.spans); - talloc_free(style); return false; } + row_group->type = BOX_TABLE_ROW_GROUP; - if (child->prev == 0) + + if (child->prev == NULL) table->children = row_group; else child->prev->next = row_group; + row_group->prev = child->prev; - while (child != 0 && ( + + while (child != NULL && ( child->type == BOX_BLOCK || child->type == BOX_INLINE_CONTAINER || child->type == BOX_TABLE || child->type == BOX_TABLE_ROW || child->type == BOX_TABLE_CELL)) { box_add_child(row_group, child); + next_child = child->next; - child->next = 0; + child->next = NULL; child = next_child; } + assert(row_group->last != NULL); - row_group->last->next = 0; + + row_group->last->next = NULL; row_group->next = next_child = child; - if (row_group->next) + if (row_group->next != NULL) row_group->next->prev = row_group; else table->last = row_group; row_group->parent = table; - if (!box_normalise_table_row_group(row_group, - &col_info, c)) { + + if (box_normalise_table_row_group(row_group, + &col_info, c) == false) { free(col_info.spans); return false; } @@ -282,38 +327,43 @@ bool box_normalise_table(struct box *table, struct content * c) table->columns = col_info.num_columns; table->rows = col_info.num_rows; - free(col_info.spans); - if (table->children == 0) { + if (table->children == NULL) { struct box *row; LOG(("table->children == 0, creating implied row")); assert(table->style != NULL); - style = talloc_memdup(c, table->style, sizeof *style); - if (!style) { + + style = nscss_get_blank_style(c, table->style, myrealloc, c); + if (style == NULL) { + free(col_info.spans); return false; } - css_cascade(style, &css_blank_style, NULL); + row_group = box_create(style, table->href, - table->target, 0, 0, c); - if (!row_group) { - talloc_free(style); + table->target, NULL, NULL, c); + if (row_group == NULL) { + css_computed_style_destroy(style); + free(col_info.spans); return false; } row_group->type = BOX_TABLE_ROW_GROUP; - style = talloc_memdup(c, row_group->style, sizeof *style); - if (!style) { + style = nscss_get_blank_style(c, row_group->style, + myrealloc, c); + if (style == NULL) { box_free(row_group); + free(col_info.spans); return false; } - css_cascade(style, &css_blank_style, NULL); + row = box_create(style, row_group->href, - row_group->target, 0, 0, c); - if (!row) { - talloc_free(style); + row_group->target, NULL, NULL, c); + if (row == NULL) { + css_computed_style_destroy(style); box_free(row_group); + free(col_info.spans); return false; } row->type = BOX_TABLE_ROW; @@ -327,11 +377,15 @@ bool box_normalise_table(struct box *table, struct content * c) table->rows = 1; } - box_normalise_table_spans(table); - if (!table_calculate_column_types(table)) + if (box_normalise_table_spans(table, col_info.spans, c) == false) { + free(col_info.spans); + return false; + } + + free(col_info.spans); + + if (table_calculate_column_types(table) == false) return false; - if (table->style->border_collapse == CSS_BORDER_COLLAPSE_COLLAPSE) - table_collapse_borders(table); LOG(("table %p done", table)); @@ -339,62 +393,141 @@ bool box_normalise_table(struct box *table, struct content * c) } -void box_normalise_table_spans(struct box *table) +/** + * Normalise table cell column/row counts for colspan/rowspan = 0. + * Additionally, generate empty cells. + * + * \param table Table to process + * \param spans Array of length table->columns for use in empty cell detection + * \param c Content containing table + * \return True on success, false on memory exhaustion. + */ + +bool box_normalise_table_spans(struct box *table, struct span_info *spans, + struct content *c) { struct box *table_row_group; struct box *table_row; struct box *table_cell; - unsigned int last_column; - unsigned int max_extra = 0; - bool extra; - bool force = false; unsigned int rows_left = table->rows; + unsigned int col; + + /* Clear span data */ + memset(spans, 0, table->columns * sizeof(struct span_info)); - /* Scan table filling in table the width and height of table cells for - cells with colspan = 0 or rowspan = 0. Ignore the colspan and - rowspan of any cells that that follow an colspan = 0 */ + /* Scan table, filling in width and height of table cells with + * colspan = 0 and rowspan = 0. Also generate empty cells */ for (table_row_group = table->children; table_row_group != NULL; - table_row_group = table_row_group->next) { - for (table_row = table_row_group->children; NULL != table_row; + table_row_group = table_row_group->next) { + for (table_row = table_row_group->children; table_row != NULL; table_row = table_row->next){ - last_column = 0; - extra = false; - for (table_cell = table_row->children; NULL != table_cell; + for (table_cell = table_row->children; + table_cell != NULL; table_cell = table_cell->next) { - /* We hae reached the end of the row, and have passed - a cell with colspan = 0 so ignore col and row spans */ - if (force || extra || (table_cell->start_column + 1 <= - last_column)) { - extra = true; + /* colspan = 0 -> colspan = 1 */ + if (table_cell->columns == 0) table_cell->columns = 1; - table_cell->rows = 1; - if (table_cell->start_column <= max_extra) { - max_extra = table_cell->start_column + 1; + + /* rowspan = 0 -> rowspan = rows_left */ + if (table_cell->rows == 0) + table_cell->rows = rows_left; + + /* Record span information */ + for (col = table_cell->start_column; + col < table_cell->start_column + + table_cell->columns; col++) { + spans[col].row_span = table_cell->rows; + } + } + + /* Reduce span count of each column */ + for (col = 0; col < table->columns; col++) { + if (spans[col].row_span == 0) { + unsigned int start = col; + css_computed_style *style; + struct box *cell, *prev; + + /* If it's already zero, then we need + * to generate an empty cell for the + * gap in the row that spans as many + * columns as remain blank. + */ + assert(table_row->style != NULL); + + /* Find width of gap */ + while (col < table->columns && + spans[col].row_span == + 0) { + col++; } - table_cell->start_column += table->columns; - } else { - /* Fill out the number of columns or the number of rows - if necessary */ - if (0 == table_cell->columns) { - table_cell->columns = table->columns - - table_cell->start_column; - if ((0 == table_cell->start_column) && - (0 == table_cell->rows)) { - force = true; - } + + style = nscss_get_blank_style(c, + table_row->style, + myrealloc, c); + if (style == NULL) + return false; + + cell = box_create(style, + table_row->href, + table_row->target, + NULL, NULL, c); + if (cell == NULL) { + css_computed_style_destroy( + style); + return false; } - assert(0 != table_cell->columns); - if (0 == table_cell->rows) { - table_cell->rows = rows_left; + cell->type = BOX_TABLE_CELL; + + cell->rows = 1; + cell->columns = col - start; + cell->start_column = start; + + /* Find place to insert cell */ + for (prev = table_row->children; + prev != NULL; + prev = prev->next) { + if (prev->start_column + + prev->columns == + start) + break; + if (prev->next == NULL) + break; } - assert(0 != table_cell->rows); - last_column = table_cell->start_column + 1; + + /* Insert it */ + if (prev == NULL) { + if (table_row->children != NULL) + table_row->children-> + prev = cell; + else + table_row->last = cell; + + cell->next = + table_row->children; + table_row->children = cell; + } else { + if (prev->next != NULL) + prev->next->prev = cell; + else + table_row->last = cell; + + cell->next = prev->next; + prev->next = cell; + cell->prev = prev; + } + cell->parent = table_row; + } else { + spans[col].row_span--; } } + + assert(rows_left > 0); + rows_left--; } } - table->columns += max_extra; + + return true; } @@ -405,19 +538,21 @@ bool box_normalise_table_row_group(struct box *row_group, struct box *child; struct box *next_child; struct box *row; - struct css_style *style; + css_computed_style *style; 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; child = next_child) { + for (child = row_group->children; child != NULL; child = next_child) { next_child = child->next; + switch (child->type) { case BOX_TABLE_ROW: /* ok */ - if (!box_normalise_table_row(child, col_info, - c)) + if (box_normalise_table_row(child, col_info, + c) == false) return false; break; case BOX_BLOCK: @@ -427,44 +562,52 @@ bool box_normalise_table_row_group(struct box *row_group, case BOX_TABLE_CELL: /* insert implied table row */ assert(row_group->style != NULL); - style = talloc_memdup(c, row_group->style, - sizeof *style); - if (!style) + + style = nscss_get_blank_style(c, row_group->style, + myrealloc, c); + if (style == NULL) return false; - css_cascade(style, &css_blank_style, NULL); + row = box_create(style, row_group->href, - row_group->target, 0, 0, c); - if (!row) { - talloc_free(style); + row_group->target, NULL, NULL, c); + if (row == NULL) { + css_computed_style_destroy(style); return false; } row->type = BOX_TABLE_ROW; - if (child->prev == 0) + + if (child->prev == NULL) row_group->children = row; else child->prev->next = row; + row->prev = child->prev; - while (child != 0 && ( + + while (child != NULL && ( child->type == BOX_BLOCK || child->type == BOX_INLINE_CONTAINER || child->type == BOX_TABLE || child->type == BOX_TABLE_ROW_GROUP || child->type == BOX_TABLE_CELL)) { box_add_child(row, child); + next_child = child->next; - child->next = 0; + child->next = NULL; child = next_child; } + assert(row->last != NULL); - row->last->next = 0; + + row->last->next = NULL; row->next = next_child = child; - if (row->next) + if (row->next != NULL) row->next->prev = row; else row_group->last = row; row->parent = row_group; - if (!box_normalise_table_row(row, col_info, - c)) + + if (box_normalise_table_row(row, col_info, + c) == false) return false; break; case BOX_INLINE: @@ -483,24 +626,30 @@ bool box_normalise_table_row_group(struct box *row_group, } } - if (row_group->children == 0) { + if (row_group->children == NULL) { LOG(("row_group->children == 0, inserting implied row")); + assert(row_group->style != NULL); - style = talloc_memdup(c, row_group->style, sizeof *style); - if (!style) { + + style = nscss_get_blank_style(c, row_group->style, + myrealloc, c); + if (style == NULL) { return false; } - css_cascade(style, &css_blank_style, NULL); + row = box_create(style, row_group->href, - row_group->target, 0, 0, c); - if (!row) { - talloc_free(style); + row_group->target, NULL, NULL, c); + if (row == NULL) { + css_computed_style_destroy(style); return false; } row->type = BOX_TABLE_ROW; row->parent = row_group; row_group->children = row_group->last = row; + + /* Keep table's row count in sync */ + col_info->num_rows++; } LOG(("row_group %p done", row_group)); @@ -516,19 +665,20 @@ bool box_normalise_table_row(struct box *row, struct box *child; struct box *next_child; struct box *cell = NULL; - struct css_style *style; + css_computed_style *style; unsigned int i; - assert(row != 0); + assert(row != NULL); assert(row->type == BOX_TABLE_ROW); LOG(("row %p", row)); - for (child = row->children; child != 0; child = next_child) { + for (child = row->children; child != NULL; child = next_child) { next_child = child->next; + switch (child->type) { case BOX_TABLE_CELL: /* ok */ - if (!box_normalise_block(child, c)) + if (box_normalise_block(child, c) == false) return false; cell = child; break; @@ -539,46 +689,51 @@ bool box_normalise_table_row(struct box *row, case BOX_TABLE_ROW: /* insert implied table cell */ assert(row->style != NULL); - style = talloc_memdup(c, row->style, sizeof *style); - if (!style) + + style = nscss_get_blank_style(c, row->style, + myrealloc, c); + if (style == NULL) return false; - css_cascade(style, &css_blank_style, NULL); - if (child->style && (child->style->position == - CSS_POSITION_ABSOLUTE || - child->style->position == - CSS_POSITION_FIXED)) { - style->position = child->style->position; - } - cell = box_create(style, row->href, row->target, 0, 0, - c); - if (!cell) { - talloc_free(style); + + cell = box_create(style, row->href, row->target, + NULL, NULL, c); + if (cell == NULL) { + css_computed_style_destroy(style); return false; } cell->type = BOX_TABLE_CELL; - if (child->prev == 0) + + if (child->prev == NULL) row->children = cell; else child->prev->next = cell; + cell->prev = child->prev; - while (child != 0 && ( + + while (child != NULL && ( child->type == BOX_BLOCK || child->type == BOX_INLINE_CONTAINER || child->type == BOX_TABLE || child->type == BOX_TABLE_ROW_GROUP || child->type == BOX_TABLE_ROW)) { box_add_child(cell, child); + next_child = child->next; - child->next = 0; + child->next = NULL; child = next_child; } + assert(cell->last != NULL); - cell->last->next = 0; + + cell->last->next = NULL; cell->next = next_child = child; - if (cell->next) + if (cell->next != NULL) cell->next->prev = cell; + else + row->last = cell; cell->parent = row; - if (!box_normalise_block(cell, c)) + + if (box_normalise_block(cell, c) == false) return false; break; case BOX_INLINE: @@ -596,42 +751,27 @@ bool box_normalise_table_row(struct box *row, assert(0); } - if (!calculate_table_row(col_info, cell->columns, cell->rows, - &cell->start_column)) + if (calculate_table_row(col_info, cell->columns, cell->rows, + &cell->start_column) == false) return false; } + + /* Update row spanning details for all columns */ for (i = 0; i < col_info->num_columns; i++) { - if ((col_info->spans[i].row_span != 0) && (!col_info->spans[i].auto_row)) { + if (col_info->spans[i].row_span != 0 && + col_info->spans[i].auto_row == false) { + /* This cell spans rows, and is not an auto row. + * Reduce number of rows left to span */ col_info->spans[i].row_span--; - if ((col_info->spans[i].auto_column) && (0 == col_info->spans[i].row_span)) { - col_info->spans[i].auto_column = false; - } } } + + /* Reset current column for next row */ col_info->current_column = 0; - col_info->extra = false; - - /* Removing empty rows causes ill effects for HTML such as: - * - * 12 - * - * as it breaks the colspan value. Additionally, both MSIE and FF - * render in the same manner as NetSurf does with the empty row - * culling commented out. - */ -// 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(row); -// } else { - col_info->num_rows++; -// } + + /* Increment row counter */ + col_info->num_rows++; LOG(("row %p done", row)); @@ -640,6 +780,13 @@ bool box_normalise_table_row(struct box *row, /** + * Compute the column index at which the current cell begins. + * Additionally, update the column record to reflect row spanning. + * + * \param col_info Column record + * \param col_span Number of columns that current cell spans + * \param row_span Number of rows that current cell spans + * \param start_column Pointer to location to receive column index * \return true on success, false on memory exhaustion */ @@ -647,70 +794,55 @@ bool calculate_table_row(struct columns *col_info, unsigned int col_span, unsigned int row_span, unsigned int *start_column) { - unsigned int cell_start_col; + unsigned int cell_start_col = col_info->current_column; unsigned int cell_end_col; unsigned int i; struct span_info *spans; - if (!col_info->extra) { - /* skip columns with cells spanning from above */ - while ((col_info->spans[col_info->current_column].row_span != 0) && - (!col_info->spans[col_info->current_column].auto_column)) { - col_info->current_column++; - } - if (col_info->spans[col_info->current_column].auto_column) { - col_info->extra = true; - col_info->current_column = 0; - } - } + /* Skip columns with cells spanning from above */ + while (col_info->spans[cell_start_col].row_span != 0) + cell_start_col++; + + /* Update current column with calculated start */ + col_info->current_column = cell_start_col; + + /* If this cell has a colspan of 0, then assume 1. + * No other browser supports colspan=0, anyway. */ + if (col_span == 0) + col_span = 1; + + cell_end_col = cell_start_col + col_span; + + if (col_info->num_columns < cell_end_col) { + /* It appears that this row has more columns than + * the maximum recorded for the table so far. + * Allocate more span records. */ + spans = realloc(col_info->spans, + sizeof *spans * (cell_end_col + 1)); + if (spans == NULL) + return false; - cell_start_col = col_info->current_column; - - /* If the current table cell follows a cell with colspan=0, - ignore both colspan and rowspan just assume it is a standard - size cell */ - if (col_info->extra) { - col_info->current_column++; - col_info->extra_columns = col_info->current_column; - } else { - /* If span to end of table, assume spaning single column - at the moment */ - cell_end_col = cell_start_col + ((0 == col_span) ? 1 : col_span); - - if (col_info->num_columns < cell_end_col) { - spans = realloc(col_info->spans, - sizeof *spans * (cell_end_col + 1)); - if (!spans) - return false; - col_info->spans = spans; - col_info->num_columns = cell_end_col; - - /* Mark new final column as sentinal */ - col_info->spans[cell_end_col].row_span = 0; - col_info->spans[cell_end_col].auto_row = - col_info->spans[cell_end_col].auto_column = - false; - } + col_info->spans = spans; + col_info->num_columns = cell_end_col; - if (0 == col_span) { - col_info->spans[cell_start_col].auto_column = true; - col_info->spans[cell_start_col].row_span = row_span; - col_info->spans[cell_start_col].auto_row = (0 == row_span); - } else { - for (i = cell_start_col; i < cell_end_col; i++) { - col_info->spans[i].row_span = (0 == row_span) ? - 1 : row_span; - col_info->spans[i].auto_row = (0 == row_span); - col_info->spans[i].auto_column = false; - } - } - if (0 == col_span) { - col_info->spans[cell_end_col].auto_column = true; - } - col_info->current_column = cell_end_col; + /* Mark new final column as sentinel */ + col_info->spans[cell_end_col].row_span = 0; + col_info->spans[cell_end_col].auto_row = false; + } + + /* This cell may span multiple columns. If it also wants to span + * multiple rows, temporarily assume it spans 1 row only. This will + * be fixed up in box_normalise_table_spans() */ + for (i = cell_start_col; i < cell_end_col; i++) { + col_info->spans[i].row_span = (row_span == 0) ? 1 : row_span; + col_info->spans[i].auto_row = (row_span == 0); } + /* Update current column with calculated end. */ + col_info->current_column = cell_end_col; + *start_column = cell_start_col; + return true; } @@ -720,11 +852,11 @@ bool box_normalise_inline_container(struct box *cont, struct content * c) struct box *child; struct box *next_child; - assert(cont != 0); + assert(cont != NULL); assert(cont->type == BOX_INLINE_CONTAINER); LOG(("cont %p", cont)); - for (child = cont->children; child != 0; child = next_child) { + for (child = cont->children; child != NULL; child = next_child) { next_child = child->next; switch (child->type) { case BOX_INLINE: @@ -735,37 +867,40 @@ bool box_normalise_inline_container(struct box *cont, struct content * c) break; case BOX_INLINE_BLOCK: /* ok */ - if (!box_normalise_block(child, c)) + if (box_normalise_block(child, c) == false) return false; break; case BOX_FLOAT_LEFT: case BOX_FLOAT_RIGHT: /* ok */ - assert(child->children != 0); + assert(child->children != NULL); + switch (child->children->type) { case BOX_BLOCK: - if (!box_normalise_block( - child->children, - c)) + if (box_normalise_block(child->children, + c) == false) return false; break; case BOX_TABLE: - if (!box_normalise_table( - child->children, - c)) + if (box_normalise_table(child->children, + c) == false) return false; break; default: assert(0); } - if (child->children == 0) { + + if (child->children == NULL) { /* the child has destroyed itself: remove float */ - if (child->prev == 0) + if (child->prev == NULL) child->parent->children = child->next; else child->prev->next = child->next; - if (child->next != 0) + if (child->next != NULL) child->next->prev = child->prev; + else + child->parent->last = child->prev; + box_free(child); } break; -- cgit v1.2.3