From 05e8696fc444ffd4d39e9b1138e5a99a56a4680e Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sun, 20 Apr 2008 15:49:25 +0000 Subject: Improve handling of absolutely positioned table cells. Corrects positioning of "Weather" box contents on BBC homepage. svn path=/trunk/netsurf/; revision=4100 --- render/box.c | 5 ++++- render/box.h | 2 ++ render/box_normalise.c | 6 ++++++ render/layout.c | 30 ++++++++++++++++++++---------- render/table.c | 6 ++++++ 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/render/box.c b/render/box.c index 9aadcda86..cddcb022b 100644 --- a/render/box.c +++ b/render/box.c @@ -594,10 +594,13 @@ void box_dump(FILE *stream, struct box *box, unsigned int depth) if (box->col) { fprintf(stream, " (columns"); for (i = 0; i != box->columns; i++) - fprintf(stream, " (%s %i %i %i)", + fprintf(stream, " (%s %s %i %i %i)", ((const char *[]) {"UNKNOWN", "FIXED", "AUTO", "PERCENT", "RELATIVE"}) [box->col[i].type], + ((const char *[]) {"normal", + "positioned"}) + [box->col[i].positioned], box->col[i].width, box->col[i].min, box->col[i].max); fprintf(stream, ")"); diff --git a/render/box.h b/render/box.h index 22a40d13d..ad02ccc55 100644 --- a/render/box.h +++ b/render/box.h @@ -239,6 +239,8 @@ struct column { int min; /** Maximum width of content. */ int max; + /** Whether all of column's cells are css positioned. */ + bool positioned; }; /** Parameters for and similar elements. */ diff --git a/render/box_normalise.c b/render/box_normalise.c index 2df859025..757ba4bb6 100644 --- a/render/box_normalise.c +++ b/render/box_normalise.c @@ -542,6 +542,12 @@ bool box_normalise_table_row(struct box *row, if (!style) 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) { diff --git a/render/layout.c b/render/layout.c index 8a6b856c8..aa11aa47d 100644 --- a/render/layout.c +++ b/render/layout.c @@ -197,12 +197,12 @@ bool layout_block_context(struct box *block, struct content *content) * for the purposes of this discussion. * * layout_document is only ever called from html_reformat, which itself - * is only ever called from content_reformat. content_reformat locks + * is only ever called from content_reformat. content_reformat locks * the content structure while reformatting is taking place. * * If we call gui_multitask here, then any pending UI events will get * processed. This includes window expose/redraw events. Upon receipt - * of these events, the UI code will call content_redraw for the + * of these events, the UI code will call content_redraw for the * window's content. content_redraw will return immediately if the * content is currently locked (which it will be if we're still doing * layout). @@ -212,8 +212,8 @@ bool layout_block_context(struct box *block, struct content *content) * in that case. This effectively means that the window contents * aren't updated, so whatever's already in the window will remain * on-screen. On GTK, however, redraw is not direct-to-screen, but - * to a pixmap which is then blitted to screen. If we perform no - * redraw, then the pixmap will be flat white. When this is + * to a pixmap which is then blitted to screen. If we perform no + * redraw, then the pixmap will be flat white. When this is * subsequently blitted, the user gets greeted with an unsightly * flicker to white (and then back to the document when the content * is redrawn when unlocked). @@ -408,8 +408,8 @@ bool layout_block_context(struct box *block, struct content *content) box->padding[BOTTOM] + box->border[BOTTOM]; advance_to_next_box: if (!box->next) { - /* No more siblings: up to first ancestor with a - sibling. */ + /* No more siblings: + * up to first ancestor with a sibling. */ do { box = box->parent; if (box == block) @@ -2040,6 +2040,7 @@ bool layout_table(struct box *table, int available_width, int relative_sum = 0; int border_spacing_h = 0, border_spacing_v = 0; int spare_height; + int positioned_columns = 0; struct box *c; struct box *row; struct box *row_group; @@ -2132,7 +2133,10 @@ bool layout_table(struct box *table, int available_width, ((const char *[]) {"UNKNOWN", "FIXED", "AUTO", "PERCENT", "RELATIVE"})[col[i].type], col[i].width, col[i].min, col[i].max)); - if (col[i].type == COLUMN_WIDTH_FIXED) { + if (col[i].positioned) { + positioned_columns++; + continue; + } else if (col[i].type == COLUMN_WIDTH_FIXED) { if (col[i].width < col[i].min) col[i].width = col[i].max = col[i].min; else @@ -2146,7 +2150,8 @@ bool layout_table(struct box *table, int available_width, required_width += col[i].min; LOG(("required_width %i", required_width)); } - required_width += (columns + 1) * border_spacing_h; + required_width += (columns + 1 - positioned_columns) * + border_spacing_h; LOG(("width %i, min %i, max %i, auto %i, required %i", table_width, table->min_width, table->max_width, @@ -2271,7 +2276,8 @@ bool layout_table(struct box *table, int available_width, xs[0] = x = border_spacing_h; for (i = 0; i != columns; i++) { - x += col[i].width + border_spacing_h; + if (!col[i].positioned) + x += col[i].width + border_spacing_h; xs[i + 1] = x; row_span[i] = 0; excess_y[i] = 0; @@ -2488,6 +2494,9 @@ void layout_minmax_table(struct box *table) layout_minmax_block(cell); i = cell->start_column; + if (col[i].positioned) + continue; + /* update column min, max widths using cell widths */ if (col[i].min < cell->min_width) col[i].min = cell->min_width; @@ -2680,7 +2689,8 @@ void layout_lists(struct box *box) marker->width = 0; marker->height = 0; } - marker->x -= 4; // Gap between marker and content + /* Gap between marker and content */ + marker->x -= 4; } layout_lists(child); } diff --git a/render/table.c b/render/table.c index b2fa4cd53..baa052e87 100644 --- a/render/table.c +++ b/render/table.c @@ -67,6 +67,7 @@ bool table_calculate_column_types(struct box *table) for (i = 0; i != table->columns; i++) { col[i].type = COLUMN_WIDTH_UNKNOWN; col[i].width = 0; + col[i].positioned = true; } /* 1st pass: cells with colspan 1 only */ @@ -80,6 +81,11 @@ bool table_calculate_column_types(struct box *table) continue; i = cell->start_column; + if (cell->style->position != CSS_POSITION_ABSOLUTE && + cell->style->position != CSS_POSITION_FIXED) { + col[i].positioned = false; + } + /* fixed width takes priority over any other width type */ if (col[i].type != COLUMN_WIDTH_FIXED && cell->style->width.width == CSS_WIDTH_LENGTH) { -- cgit v1.2.3