From b6c8e435cd206b0acac3368098254decfbdb5f74 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Sat, 4 Nov 2006 19:17:11 +0000 Subject: Implement absolute positioned inlines. svn path=/trunk/netsurf/; revision=3026 --- Docs/02-layout | 16 ++++++++++++++++ render/box_construct.c | 13 +++++++++++++ render/layout.c | 41 ++++++++++++++++++++++++++++++++--------- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/Docs/02-layout b/Docs/02-layout index ddc7cfd06..36f856fc0 100644 --- a/Docs/02-layout +++ b/Docs/02-layout @@ -29,3 +29,19 @@ to a new width. Coordinates in the box tree are relative to the position of the parent node. The box tree can then be rendered using each node's coordinates. + +Absolute positioning +-------------------- +Absolutely positioned boxes are constructed in the box tree in the same place as +if they were not absolutely positioned. Inline boxes are created as +INLINE_BLOCK, tables as TABLE, and other boxes as BLOCK (see +box_solve_display()). + +During layout, absolutely positioned boxes in block context (BLOCK or TABLE) are +given a position in layout_block_context(), but treated as having no height. In +inline context (INLINE_BLOCK), they are given a position in layout_line(), but +treated as having no width or height. This is done to determine the static +position. + +An additional pass after main layout positions and layouts all absolutely +positioned boxes (see layout_position_absolute()). diff --git a/render/box_construct.c b/render/box_construct.c index e2f5cc883..69b681760 100644 --- a/render/box_construct.c +++ b/render/box_construct.c @@ -971,6 +971,19 @@ void box_solve_display(struct css_style *style, bool root) else /* 5. */ return; + /* Special case for absolute positioning: make absolute inlines into + * inline block so that the boxes are constructed in an inline container + * as if they were not absolutely positioned. Layout expects and + * handles this. */ + if ((style->position == CSS_POSITION_ABSOLUTE || + style->position == CSS_POSITION_FIXED) && + (style->display == CSS_DISPLAY_INLINE || + style->display == CSS_DISPLAY_INLINE_BLOCK || + style->display == CSS_DISPLAY_INLINE_TABLE)) { + style->display = CSS_DISPLAY_INLINE_BLOCK; + return; + } + /* map specified value to computed value using table given in 9.7 */ if (style->display == CSS_DISPLAY_INLINE_TABLE) style->display = CSS_DISPLAY_TABLE; diff --git a/render/layout.c b/render/layout.c index 906923682..58693e254 100644 --- a/render/layout.c +++ b/render/layout.c @@ -1017,6 +1017,10 @@ bool layout_line(struct box *first, int *width, int *y, if (b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT) continue; + if (b->type == BOX_INLINE_BLOCK && + (b->style->position == CSS_POSITION_ABSOLUTE || + b->style->position == CSS_POSITION_FIXED)) + continue; x += space_after; @@ -1191,7 +1195,13 @@ bool layout_line(struct box *first, int *width, int *y, LOG(("x0 %i, x1 %i, x1 - x0 %i", x0, x1, x1 - x0)); for (x = x_previous = 0, b = first; x <= x1 - x0 && b; b = b->next) { LOG(("pass 2: b %p, x %i", b, x)); - if (b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK || + if (b->type == BOX_INLINE_BLOCK && + (b->style->position == CSS_POSITION_ABSOLUTE || + b->style->position == CSS_POSITION_FIXED)) { + b->x = x + space_after; + + } else if (b->type == BOX_INLINE || + b->type == BOX_INLINE_BLOCK || b->type == BOX_TEXT || b->type == BOX_INLINE_END) { assert(b->width != UNKNOWN_WIDTH); @@ -1442,6 +1452,10 @@ bool layout_line(struct box *first, int *width, int *y, d->x += x0; d->y = *y - d->padding[TOP]; } + if (d->type == BOX_INLINE_BLOCK && + (d->style->position == CSS_POSITION_ABSOLUTE || + d->style->position == CSS_POSITION_FIXED)) + continue; if ((d->type == BOX_INLINE && (d->object || d->gadget)) || d->type == BOX_INLINE_BLOCK) { h = d->border[TOP] + d->padding[TOP] + d->height + @@ -2468,10 +2482,13 @@ void layout_compute_relative_offset(struct box *box, int *x, int *y) /** - * Layout absolutely positioned boxes in a block context. + * Recursively layout and position absolutely positioned boxes. * - * \param block box to layout children of - * \param content memory pool for any new boxes + * \param box tree of boxes to layout + * \param containing_block current containing block + * \param cx position of box relative to containing_block + * \param cy position of box relative to containing_block + * \param content memory pool for any new boxes * \return true on success, false on memory exhaustion */ @@ -2483,7 +2500,8 @@ bool layout_position_absolute(struct box *box, struct box *c; for (c = box->children; c; c = c->next) { - if ((c->type == BOX_BLOCK || c->type == BOX_TABLE) && + if ((c->type == BOX_BLOCK || c->type == BOX_TABLE || + c->type == BOX_INLINE_BLOCK) && (c->style->position == CSS_POSITION_ABSOLUTE || c->style->position == CSS_POSITION_FIXED)) { if (!layout_absolute(c, containing_block, @@ -2509,8 +2527,11 @@ bool layout_position_absolute(struct box *box, /** * Layout and position an absolutely positioned box. * - * \param block box to layout and position - * \param content memory pool for any new boxes + * \param box absolute box to layout and position + * \param containing_block containing block + * \param cx position of box relative to containing_block + * \param cy position of box relative to containing_block + * \param content memory pool for any new boxes * \return true on success, false on memory exhaustion */ @@ -2527,7 +2548,8 @@ bool layout_absolute(struct box *box, struct box *containing_block, int available_width = containing_block->width; int space; - assert(box->type == BOX_BLOCK || box->type == BOX_TABLE); + assert(box->type == BOX_BLOCK || box->type == BOX_TABLE || + box->type == BOX_INLINE_BLOCK); /* The static position is where the box would be if it was not * absolutely positioned. The x and y are filled in by @@ -2689,7 +2711,8 @@ bool layout_absolute(struct box *box, struct box *containing_block, box->width = width; box->height = height; - if (box->type == BOX_BLOCK || box->object) { + if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK || + box->object) { if (!layout_block_context(box, content)) return false; } else if (box->type == BOX_TABLE) { -- cgit v1.2.3