summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2004-07-16 20:26:49 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2004-07-16 20:26:49 +0000
commit51af46fde6b5885d32eab0812189eb8f5e270abf (patch)
tree68d72bf6dfb05988088c3bda1664db5ac1bb4c3b
parent6560a2ae5f68831bec809e9ee847ac0e36ff011d (diff)
downloadnetsurf-51af46fde6b5885d32eab0812189eb8f5e270abf.tar.gz
netsurf-51af46fde6b5885d32eab0812189eb8f5e270abf.tar.bz2
[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
-rw-r--r--render/box.c2
-rw-r--r--render/box.h19
-rw-r--r--render/html.c26
-rw-r--r--render/layout.c49
-rw-r--r--riscos/htmlredraw.c29
5 files changed, 123 insertions, 2 deletions
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;
}
diff --git a/riscos/htmlredraw.c b/riscos/htmlredraw.c
index 2c4da8a28..fb08ae060 100644
--- a/riscos/htmlredraw.c
+++ b/riscos/htmlredraw.c
@@ -258,6 +258,35 @@ void html_redraw_box(struct content *content, struct box * box,
}
}
+ /* handle overflow - horrendously broken atm */
+#if 0
+ if ((box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK ||
+ box->type == BOX_TABLE_CELL || box->object) &&
+ box->style &&
+ box->style->overflow == CSS_OVERFLOW_VISIBLE &&
+ box->descendant_x1 && box->descendant_y1) {
+ LOG(("Box Coords: %d, %d", box->x, box->y));
+ LOG(("Descendants: %d, %d, %d, %d", box->descendant_x0, box->descendant_y0, box->descendant_x1, box->descendant_y1));
+ LOG(("Previous vals: %d, %d, %d, %d", x0, y0, x1, y1));
+ x0 = (box->x + box->descendant_x0) * 2 * scale;
+ y1 = (box->y + box->descendant_y1) * 2 * scale - 1;
+ x1 = (box->x + box->descendant_x1) * 2 * scale - 1;
+ y0 = (box->y + box->descendant_y0) * 2 * scale + 1;
+
+ LOG(("New Coords: %d, %d, %d, %d", x0, y0, x1, y1));
+ LOG(("Clipping: %ld, %ld, %ld, %ld", clip_x0, clip_y0, clip_x1, clip_y1));
+ /* find intersection of clip rectangle and box */
+ if (x0 < clip_x0) x0 = clip_x0;
+ if (y0 < clip_y0) y0 = clip_y0;
+ if (clip_x1 > x1) x1 = clip_x1;
+ if (clip_y1 > y1) y1 = clip_y1;
+
+ LOG(("Overflow clip: %d, %d, %d, %d", x0, y0, x1, y1));
+ /* clip to it */
+ html_redraw_clip(x0, y0, x1, y1);
+ }
+#endif
+
if (box->object) {
content_redraw(box->object, x + padding_left, y - padding_top,
width, height, x0, y0, x1, y1, scale);