summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2009-05-07 16:22:38 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2009-05-07 16:22:38 +0000
commitc2ecbebd3dff9531e0b46a5d5983f776920935bb (patch)
tree2543dc75ce25d59eb70291b70a912f34f051f775 /render
parent40d27d11523a7bab451e6d21a1e71c6f7304c8d8 (diff)
downloadnetsurf-c2ecbebd3dff9531e0b46a5d5983f776920935bb.tar.gz
netsurf-c2ecbebd3dff9531e0b46a5d5983f776920935bb.tar.bz2
Fix viewport height handling not to obliterate calculation
of root element height from children's dimensions. Improve handling of percentage heights on HTML and BODY. svn path=/trunk/netsurf/; revision=7429
Diffstat (limited to 'render')
-rw-r--r--render/layout.c71
1 files changed, 42 insertions, 29 deletions
diff --git a/render/layout.c b/render/layout.c
index 179b77b28..65ff0c4a2 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -56,11 +56,13 @@
#define AUTO INT_MIN
-static bool layout_block_context(struct box *block, struct content *content);
+static bool layout_block_context(struct box *block, int viewport_height,
+ struct content *content);
static void layout_minmax_block(struct box *block,
const struct font_functions *font_func);
static bool layout_block_object(struct box *block);
-static void layout_block_find_dimensions(int available_width, int lm, int rm,
+static void layout_block_find_dimensions(int available_width,
+ int viewport_height, int lm, int rm,
struct box *box);
static bool layout_apply_minmax_height(struct box *box, struct box *container);
static void layout_block_add_scrollbar(struct box *box, int which);
@@ -69,7 +71,7 @@ static int layout_solve_width(int available_width, int width, int lm, int rm,
int margin[4], int padding[4], int border[4]);
static void layout_float_find_dimensions(int available_width,
struct css_style *style, struct box *box);
-static void layout_find_dimensions(int available_width,
+static void layout_find_dimensions(int available_width, int viewport_height,
struct box *box, struct css_style *style,
int *width, int *height, int *max_width, int *min_width,
int margin[4], int padding[4], int border[4]);
@@ -133,7 +135,7 @@ bool layout_document(struct content *content, int width, int height)
layout_minmax_block(doc, font_func);
- layout_block_find_dimensions(width, 0, 0, doc);
+ layout_block_find_dimensions(width, height, 0, 0, doc);
doc->x = doc->margin[LEFT] + doc->border[LEFT];
doc->y = doc->margin[TOP] + doc->border[TOP];
width -= doc->margin[LEFT] + doc->border[LEFT] + doc->padding[LEFT] +
@@ -142,10 +144,8 @@ bool layout_document(struct content *content, int width, int height)
if (width < 0)
width = 0;
doc->width = width;
- if (doc->height == AUTO)
- doc->height = height;
- ret = layout_block_context(doc, content);
+ ret = layout_block_context(doc, height, content);
/* make <html> and <body> fill available height */
if (doc->y + doc->padding[TOP] + doc->height + doc->padding[BOTTOM] +
@@ -177,15 +177,17 @@ bool layout_document(struct content *content, int width, int height)
/**
* Layout a block formatting context.
*
- * \param block BLOCK, INLINE_BLOCK, or TABLE_CELL to layout
- * \param content memory pool for any new boxes
+ * \param block BLOCK, INLINE_BLOCK, or TABLE_CELL to layout
+ * \param viewport_height Height of viewport in pixels or -ve if unknown
+ * \param content Memory pool for any new boxes
* \return true on success, false on memory exhaustion
*
* This function carries out layout of a block and its children, as described
* in CSS 2.1 9.4.1.
*/
-bool layout_block_context(struct box *block, struct content *content)
+bool layout_block_context(struct box *block, int viewport_height,
+ struct content *content)
{
struct box *box;
int cx, cy; /**< current coordinates */
@@ -317,8 +319,9 @@ bool layout_block_context(struct box *block, struct content *content)
(box->style->position == CSS_POSITION_ABSOLUTE||
box->style->position == CSS_POSITION_FIXED)) {
box->x = box->parent->padding[LEFT];
- layout_find_dimensions(box->parent->width, box,
- box->style, NULL, &(box->height), NULL,
+ layout_find_dimensions(box->parent->width,
+ viewport_height, box, box->style,
+ NULL, &(box->height), NULL,
NULL, NULL, NULL, NULL);
/* absolute positioned; this element will establish
* its own block context when it gets laid out later,
@@ -334,8 +337,9 @@ bool layout_block_context(struct box *block, struct content *content)
/* Get top margin */
if (box->style) {
- layout_find_dimensions(box->parent->width, box,
- box->style, NULL, NULL, NULL, NULL,
+ layout_find_dimensions(box->parent->width,
+ viewport_height, box, box->style,
+ NULL, NULL, NULL, NULL,
box->margin, NULL, NULL);
}
@@ -374,7 +378,7 @@ bool layout_block_context(struct box *block, struct content *content)
x1;
}
layout_block_find_dimensions(box->parent->width,
- lm, rm, box);
+ viewport_height, lm, rm, box);
layout_block_add_scrollbar(box, RIGHT);
layout_block_add_scrollbar(box, BOTTOM);
} else if (box->type == BOX_TABLE) {
@@ -434,7 +438,7 @@ bool layout_block_context(struct box *block, struct content *content)
cy += max_pos_margin - max_neg_margin;
box->y += max_pos_margin - max_neg_margin;
- layout_block_context(box, content);
+ layout_block_context(box, viewport_height, content);
if (box->type == BOX_BLOCK || box->object)
cy += box->padding[TOP];
@@ -760,6 +764,7 @@ bool layout_block_object(struct box *block)
* element.
*
* \param available_width Max width available in pixels
+ * \param viewport_height Height of viewport in pixels or -ve if unknown
* \param lm min left margin required to avoid floats in px.
* zero if not applicable
* \param rm min right margin required to avoid floats in px.
@@ -770,8 +775,8 @@ bool layout_block_object(struct box *block)
* See CSS 2.1 10.3.3, 10.3.4, 10.6.2, and 10.6.3.
*/
-void layout_block_find_dimensions(int available_width, int lm, int rm,
- struct box *box)
+void layout_block_find_dimensions(int available_width, int viewport_height,
+ int lm, int rm, struct box *box)
{
int width, max_width, min_width;
int height;
@@ -780,8 +785,9 @@ void layout_block_find_dimensions(int available_width, int lm, int rm,
int *border = box->border;
struct css_style *style = box->style;
- layout_find_dimensions(available_width, box, style, &width, &height,
- &max_width, &min_width, margin, padding, border);
+ layout_find_dimensions(available_width, viewport_height, box, style,
+ &width, &height, &max_width, &min_width,
+ margin, padding, border);
if (box->object && box->object->type != CONTENT_HTML) {
/* block-level replaced element, see 10.3.4 and 10.6.2 */
@@ -1054,7 +1060,7 @@ void layout_float_find_dimensions(int available_width,
style->overflow == CSS_OVERFLOW_AUTO) ?
SCROLLBAR_WIDTH : 0;
- layout_find_dimensions(available_width, box, style, &width, &height,
+ layout_find_dimensions(available_width, -1, box, style, &width, &height,
&max_width, &min_width, margin, padding, border);
if (margin[LEFT] == AUTO)
@@ -1143,6 +1149,7 @@ void layout_float_find_dimensions(int available_width,
* Calculate width, height, and thickness of margins, paddings, and borders.
*
* \param available_width width of containing block
+ * \param viewport_height height of viewport in pixels or -ve if unknown
* \param box current box
* \param style style giving width, height, margins, paddings,
* and borders
@@ -1155,7 +1162,7 @@ void layout_float_find_dimensions(int available_width,
* \param border[4] filled with border widths, may be NULL
*/
-void layout_find_dimensions(int available_width,
+void layout_find_dimensions(int available_width, int viewport_height,
struct box *box, struct css_style *style,
int *width, int *height, int *max_width, int *min_width,
int margin[4], int padding[4], int border[4])
@@ -1233,6 +1240,12 @@ void layout_find_dimensions(int available_width,
* height. (CSS 2.1 Section 10.5) */
*height = style->height.value.percent *
containing_block->height / 100;
+ } else if ((!box->parent || !box->parent->parent) &&
+ viewport_height >= 0) {
+ /* If root element or it's child
+ * (HTML or BODY) */
+ *height = style->height.value.percent *
+ viewport_height / 100;
} else {
/* precentage height not permissible
* treat height as auto */
@@ -1708,7 +1721,7 @@ bool layout_line(struct box *first, int *width, int *y,
if (b->type == BOX_INLINE) {
/* calculate borders, margins, and padding */
- layout_find_dimensions(*width, b, b->style, 0, 0,
+ layout_find_dimensions(*width, -1, b, b->style, 0, 0,
0, 0, b->margin, b->padding, b->border);
for (i = 0; i != 4; i++)
if (b->margin[i] == AUTO)
@@ -2503,7 +2516,7 @@ bool layout_float(struct box *b, int width, struct content *content)
if (b->margin[BOTTOM] == AUTO)
b->margin[BOTTOM] = 0;
} else
- return layout_block_context(b, content);
+ return layout_block_context(b, -1, content);
return true;
}
@@ -2609,14 +2622,14 @@ bool layout_table(struct box *table, int available_width,
memcpy(col, table->col, sizeof(col[0]) * columns);
/* find margins, paddings, and borders for table and cells */
- layout_find_dimensions(available_width, table, style, 0, 0, 0, 0,
+ layout_find_dimensions(available_width, -1, table, style, 0, 0, 0, 0,
table->margin, table->padding, table->border);
for (row_group = table->children; row_group;
row_group = row_group->next) {
for (row = row_group->children; row; row = row->next) {
for (c = row->children; c; c = c->next) {
assert(c->style);
- layout_find_dimensions(available_width,
+ layout_find_dimensions(available_width, -1,
c, c->style, 0, 0, 0, 0, 0,
c->padding, c->border);
if (c->style->overflow ==
@@ -2861,7 +2874,7 @@ bool layout_table(struct box *table, int available_width,
c->float_children = 0;
c->height = AUTO;
- if (!layout_block_context(c, content)) {
+ if (!layout_block_context(c, -1, content)) {
free(col);
free(excess_y);
free(row_span);
@@ -3559,7 +3572,7 @@ bool layout_absolute(struct box *box, struct box *containing_block,
* containing block box member. This is unused for absolutely positioned
* boxes because a box can't be floated and absolutely positioned. */
box->float_container = containing_block;
- layout_find_dimensions(available_width, box, box->style,
+ layout_find_dimensions(available_width, -1, box, box->style,
&width, &height, &max_width, &min_width,
margin, padding, border);
box->float_container = NULL;
@@ -3739,7 +3752,7 @@ bool layout_absolute(struct box *box, struct box *containing_block,
if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK ||
box->object) {
- if (!layout_block_context(box, content))
+ if (!layout_block_context(box, -1, content))
return false;
} else if (box->type == BOX_TABLE) {
/* \todo layout_table considers margins etc. again */