From 51af46fde6b5885d32eab0812189eb8f5e270abf Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Fri, 16 Jul 2004 20:26:49 +0000 Subject: [project @ 2004-07-16 20:26:49 by jmb] Preliminary overflow support. This also goes some way to making the horizontal scrollbar work. svn path=/import/netsurf/; revision=1088 --- render/box.c | 2 ++ render/box.h | 19 +++++++++++++++++++ render/html.c | 26 ++++++++++++++++++++++++-- render/layout.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 2 deletions(-) (limited to 'render') diff --git a/render/box.c b/render/box.c index bb2ac8a44..29d2bfdb6 100644 --- a/render/box.c +++ b/render/box.c @@ -225,6 +225,8 @@ struct box * box_create(struct css_style * style, box->height = 0; for (i = 0; i != 4; i++) box->margin[i] = box->padding[i] = box->border[i] = 0; + box->descendant_x0 = box->descendant_y0 = 0; + box->descendant_x1 = box->descendant_y1 = 0; return box; } diff --git a/render/box.h b/render/box.h index 142a74c6a..815a5fcf8 100644 --- a/render/box.h +++ b/render/box.h @@ -140,6 +140,25 @@ struct box { int width; /**< Width of content box (excluding padding etc.). */ int height; /**< Height of content box (excluding padding etc.). */ + /* These four variables determine the maximum extent of a box's + * descendants. They are relative to the x,y coordinates of the box. + * + * Their use depends on the overflow CSS property: + * + * Overflow: Usage: + * visible The content of the box is displayed within these + * dimensions. + * hidden These are ignored. Content is plotted within the box + * dimensions. + * scroll These are used to determine the extent of the + * scrollable area. + * auto As "scroll". + */ + int descendant_x0; /**< left edge of descendants */ + int descendant_y0; /**< top edge of descendants */ + int descendant_x1; /**< right edge of descendants */ + int descendant_y1; /**< bottom edge of descendants */ + int margin[4]; /**< Margin: TOP, RIGHT, BOTTOM, LEFT. */ int padding[4]; /**< Padding: TOP, RIGHT, BOTTOM, LEFT. */ int border[4]; /**< Border width: TOP, RIGHT, BOTTOM, LEFT. */ diff --git a/render/html.c b/render/html.c index 422528ad0..5fce63c26 100644 --- a/render/html.c +++ b/render/html.c @@ -181,6 +181,7 @@ bool html_convert(struct content *c, int width, int height) xmlDoc *document; xmlNode *html, *head; union content_msg_data msg_data; + int descendant_width; /* finish parsing */ htmlParseChunk(c->data.html.parser, "", 0, 1); @@ -251,7 +252,16 @@ bool html_convert(struct content *c, int width, int height) c->data.html.box_pool); /*box_dump(c->data.html.layout->children, 0);*/ - c->width = c->data.html.layout->children->width; + descendant_width = c->data.html.layout->children->descendant_x1 - + c->data.html.layout->children->descendant_x0; + + LOG(("Available width: %d, Returned Width: %d, Required width: %d", width, c->data.html.layout->children->width, descendant_width)); + + if (descendant_width > c->data.html.layout->children->width) + c->width = descendant_width; + else + c->width = c->data.html.layout->children->width; + c->height = c->data.html.layout->children->height; if (c->active == 0) { @@ -828,9 +838,21 @@ void html_stop(struct content *c) void html_reformat(struct content *c, int width, int height) { + int descendant_width; + layout_document(c->data.html.layout->children, width, c->data.html.box_pool); - c->width = c->data.html.layout->children->width; + + descendant_width = c->data.html.layout->children->descendant_x1 - + c->data.html.layout->children->descendant_x0; + + LOG(("Available width: %d, Returned Width: %d, Required width: %d", width, c->data.html.layout->children->width, descendant_width)); + + if (descendant_width > c->data.html.layout->children->width) + c->width = descendant_width; + else + c->width = c->data.html.layout->children->width; + c->height = c->data.html.layout->children->height; } diff --git a/render/layout.c b/render/layout.c index caf76abe9..26b266547 100644 --- a/render/layout.c +++ b/render/layout.c @@ -70,6 +70,18 @@ static void calculate_inline_replaced_widths(struct box *box, int *min, static void calculate_inline_widths(struct box *box, int *min, int *line_max); static bool calculate_table_widths(struct box *table); +/**\todo Do we want to split this into a separate function? */ +#define set_descendant_extent(parent, child) do { \ + if (child->x+child->descendant_x0 < parent->descendant_x0) \ + parent->descendant_x0 = child->x+child->descendant_x0; \ + if (child->x+child->descendant_x1 > parent->descendant_x1) \ + parent->descendant_x1 = child->x+child->descendant_x1; \ + if (child->y+child->descendant_y0 < parent->descendant_y0) \ + parent->descendant_y0 = child->y+child->descendant_y0; \ + if (child->y+child->descendant_y1 > parent->descendant_y1) \ + parent->descendant_y1 = child->y+child->descendant_y1; \ +} while (0); + /** * Calculate positions of boxes in a document. @@ -230,6 +242,9 @@ bool layout_block_context(struct box *block, pool box_pool) max_pos_margin = max_neg_margin = 0; margin_box = box; } + + set_descendant_extent(block, box); + continue; } if (box->type == BOX_BLOCK && box->height == AUTO) @@ -246,6 +261,7 @@ bool layout_block_context(struct box *block, pool box_pool) y = box->y + box->padding[TOP] + box->height + box->padding[BOTTOM] + box->border[BOTTOM]; + set_descendant_extent(box->parent, box); box = box->parent; if (box != block && box->height == AUTO) box->height = y - box->padding[TOP]; @@ -255,6 +271,7 @@ bool layout_block_context(struct box *block, pool box_pool) max_pos_margin = box->margin[BOTTOM]; else if (max_neg_margin < -box->margin[BOTTOM]) max_neg_margin = -box->margin[BOTTOM]; + set_descendant_extent(box->parent, box); } while (box != block && !box->next); if (box == block) break; @@ -265,6 +282,8 @@ bool layout_block_context(struct box *block, pool box_pool) box = box->next; box->y = y; margin_box = box; + + set_descendant_extent(block, box); } /* Increase height to contain any floats inside (CSS 2.1 10.6.7). */ @@ -278,6 +297,8 @@ bool layout_block_context(struct box *block, pool box_pool) if (block->height == AUTO) block->height = cy - block->padding[TOP]; + LOG(("Block Content: At: (%d, %d), %d, %d Descendants: %d, %d, %d, %d", block->x, block->y, block->width, block->height, block->descendant_x0, block->descendant_y0, block->descendant_x1, block->descendant_y1)); + return true; } @@ -619,6 +640,8 @@ bool layout_inline_container(struct box *box, int width, box->width = width; box->height = y; + LOG(("Inline container: At: (%d, %d) %d, %d Descendants: %d, %d, %d, %d", box->x, box->y, box->width, box->height, box->descendant_x0, box->descendant_y0, box->descendant_x1, box->descendant_y1)); + return true; } @@ -1033,6 +1056,15 @@ bool layout_line(struct box *first, int width, int *y, } for (d = first; d != b; d = d->next) { + /* BOXes_INLINE contain either text, an object or a form + * field. Therefore the extent of these is known so fill + * in the descendant_* fields. */ + if (d->type == BOX_INLINE) { + d->descendant_x0 = 0; + d->descendant_y0 = 0; + d->descendant_x1 = d->width; + d->descendant_y1 = d->height; + } if (d->type == BOX_INLINE || d->type == BOX_INLINE_BLOCK || d->type == BOX_BR) { d->x += x0; @@ -1042,6 +1074,13 @@ bool layout_line(struct box *first, int width, int *y, if (used_height < h) used_height = h; } + + /* fill in the parent's descendant_* fields. */ + if (first->parent) { + set_descendant_extent(first->parent, d); + } + + LOG(("Inline block: '%s' At: (%d, %d), %d, %d Descendants: %d, %d, %d, %d", d->text?d->text:d->object?d->object->url:d->gadget?"(gadget)":"", d->x, d->y, d->width, d->height, d->descendant_x0, d->descendant_y0, d->descendant_x1, d->descendant_y1)); } assert(b != first || (move_y && 0 < used_height && (left || right))); @@ -1376,6 +1415,8 @@ bool layout_table(struct box *table, int available_width, } row_span_cell[c->start_column] = c; c->height = 0; + + set_descendant_extent(row, c); } for (i = 0; i != columns; i++) if (row_span[i] != 0) @@ -1407,12 +1448,18 @@ bool layout_table(struct box *table, int available_width, row->width = table_width; row->height = row_height; row_group_height += row_height; + + set_descendant_extent(row_group, row); + LOG(("Table row: At: (%d, %d), %d, %d Descendants: %d, %d, %d, %d", row->x, row->y, row->width, row->height, row->descendant_x0, row->descendant_y0, row->descendant_x1, row->descendant_y1)); } row_group->x = 0; row_group->y = table_height; row_group->width = table_width; row_group->height = row_group_height; table_height += row_group_height; + + set_descendant_extent(table, row_group); + LOG(("Table row group: At: (%d, %d), %d, %d Descendants: %d, %d, %d, %d", row_group->x, row_group->y, row_group->width, row_group->height, row_group->descendant_x0, row_group->descendant_y0, row_group->descendant_x1, row_group->descendant_y1)); } free(col); @@ -1424,6 +1471,8 @@ bool layout_table(struct box *table, int available_width, table->width = table_width; table->height = table_height; + LOG(("Table: At: (%d, %d), %d, %d Descendants: %d, %d, %d, %d", table->x, table->y, table->width, table->height, table->descendant_x0, table->descendant_y0, table->descendant_x1, table->descendant_y1)); + return true; } -- cgit v1.2.3