From b3f32dece4c77a839a5abe9b14c8d87a8aac1971 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Mon, 13 Oct 2008 19:22:16 +0000 Subject: Implement percentage min/max-height. svn path=/trunk/netsurf/; revision=5566 --- render/layout.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 7 deletions(-) (limited to 'render') diff --git a/render/layout.c b/render/layout.c index 7237998e6..b46d554ca 100644 --- a/render/layout.c +++ b/render/layout.c @@ -60,7 +60,7 @@ 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, struct box *box); -static bool layout_apply_minmax_height(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); static int layout_solve_width(int available_width, int width, int max_width, int min_width, int margin[4], int padding[4], int border[4]); @@ -482,7 +482,7 @@ bool layout_block_context(struct box *block, struct content *content) cy += box->height - (y - box->padding[TOP]); - if (layout_apply_minmax_height(box)) { + if (layout_apply_minmax_height(box, NULL)) { /* Height altered */ /* Set current cy */ cy += box->height - @@ -524,7 +524,7 @@ bool layout_block_context(struct box *block, struct content *content) if (block->type == BOX_BLOCK) layout_block_add_scrollbar(block, BOTTOM); } - layout_apply_minmax_height(block); + layout_apply_minmax_height(block, NULL); return true; } @@ -729,13 +729,37 @@ void layout_block_find_dimensions(int available_width, struct box *box) * Manimpulate box height according to CSS min-height and max-height properties * * \param box block to modify with any min-height or max-height + * \param container containing block for absolutely positioned elements, or + * NULL for non absolutely positioned elements. * \return whether the height has been changed */ -bool layout_apply_minmax_height(struct box *box) { +bool layout_apply_minmax_height(struct box *box, struct box *container) +{ int h; + struct box *containing_block = NULL; bool updated = false; + /* Find containing block for percentage heights */ + if (container) { + /* Box is absolutely positioned */ + containing_block = container; + } else if (box->float_container && + (box->style->float_ == CSS_FLOAT_LEFT || + box->style->float_ == CSS_FLOAT_RIGHT)) { + /* Box is a float */ + assert(box->parent && box->parent->parent && + box->parent->parent->parent); + containing_block = box->parent->parent->parent; + } else if (box->parent && box->parent->type != BOX_INLINE_CONTAINER) { + /* Box is a block level element */ + containing_block = box->parent; + } else if (box->parent && box->parent->type == BOX_INLINE_CONTAINER) { + /* Box is an inline block */ + assert(box->parent->parent); + containing_block = box->parent->parent; + } + if (box->style) { /* max-height */ switch (box->style->max_height.max_height) { @@ -748,7 +772,24 @@ bool layout_apply_minmax_height(struct box *box) { } break; case CSS_MAX_HEIGHT_PERCENT: - /* percentage heights not yet implemented */ + if (box->style->position == CSS_POSITION_ABSOLUTE || + (containing_block && + (containing_block->style->height. + height == CSS_HEIGHT_LENGTH || + containing_block->style->height. + height == CSS_HEIGHT_PERCENT) && + containing_block->height != AUTO)) { + /* Box is absolutely positioned or its + * containing block has a valid specified + * height. (CSS 2.1 Section 10.5) */ + h = box->style->max_height.value.percent * + containing_block->height / 100; + if (h < box->height) { + box->height = h; + updated = true; + } + } + break; default: break; } @@ -764,7 +805,24 @@ bool layout_apply_minmax_height(struct box *box) { } break; case CSS_MIN_HEIGHT_PERCENT: - /* percentage heights not yet implemented */ + if (box->style->position == CSS_POSITION_ABSOLUTE || + (containing_block && + (containing_block->style->height. + height == CSS_HEIGHT_LENGTH || + containing_block->style->height. + height == CSS_HEIGHT_PERCENT) && + containing_block->height != AUTO)) { + /* Box is absolutely positioned or its + * containing block has a valid specified + * height. (CSS 2.1 Section 10.5) */ + h = box->style->min_height.value.percent * + containing_block->height / 100; + if (h > box->height) { + box->height = h; + updated = true; + } + } + break; default: break; } @@ -3569,7 +3627,7 @@ bool layout_absolute(struct box *box, struct box *containing_block, /** \todo Inline ancestors */ } box->height = height; - layout_apply_minmax_height(box); + layout_apply_minmax_height(box, containing_block); return true; } -- cgit v1.2.3