Implement absolute positioned inlines.

svn path=/trunk/netsurf/; revision=3026
This commit is contained in:
James Bursa 2006-11-04 19:17:11 +00:00
parent a1f291383f
commit b6c8e435cd
3 changed files with 61 additions and 9 deletions

View File

@ -29,3 +29,19 @@ to a new width. Coordinates in the box tree are relative to the position of the
parent node. parent node.
The box tree can then be rendered using each node's coordinates. 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()).

View File

@ -971,6 +971,19 @@ void box_solve_display(struct css_style *style, bool root)
else /* 5. */ else /* 5. */
return; 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 */ /* map specified value to computed value using table given in 9.7 */
if (style->display == CSS_DISPLAY_INLINE_TABLE) if (style->display == CSS_DISPLAY_INLINE_TABLE)
style->display = CSS_DISPLAY_TABLE; style->display = CSS_DISPLAY_TABLE;

View File

@ -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) if (b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT)
continue; continue;
if (b->type == BOX_INLINE_BLOCK &&
(b->style->position == CSS_POSITION_ABSOLUTE ||
b->style->position == CSS_POSITION_FIXED))
continue;
x += space_after; 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)); 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) { for (x = x_previous = 0, b = first; x <= x1 - x0 && b; b = b->next) {
LOG(("pass 2: b %p, x %i", b, x)); 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_TEXT ||
b->type == BOX_INLINE_END) { b->type == BOX_INLINE_END) {
assert(b->width != UNKNOWN_WIDTH); assert(b->width != UNKNOWN_WIDTH);
@ -1442,6 +1452,10 @@ bool layout_line(struct box *first, int *width, int *y,
d->x += x0; d->x += x0;
d->y = *y - d->padding[TOP]; 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)) || if ((d->type == BOX_INLINE && (d->object || d->gadget)) ||
d->type == BOX_INLINE_BLOCK) { d->type == BOX_INLINE_BLOCK) {
h = d->border[TOP] + d->padding[TOP] + d->height + 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 box tree of boxes to layout
* \param content memory pool for any new boxes * \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 * \return true on success, false on memory exhaustion
*/ */
@ -2483,7 +2500,8 @@ bool layout_position_absolute(struct box *box,
struct box *c; struct box *c;
for (c = box->children; c; c = c->next) { 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_ABSOLUTE ||
c->style->position == CSS_POSITION_FIXED)) { c->style->position == CSS_POSITION_FIXED)) {
if (!layout_absolute(c, containing_block, if (!layout_absolute(c, containing_block,
@ -2509,8 +2527,11 @@ bool layout_position_absolute(struct box *box,
/** /**
* Layout and position an absolutely positioned box. * Layout and position an absolutely positioned box.
* *
* \param block box to layout and position * \param box absolute box to layout and position
* \param content memory pool for any new boxes * \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 * \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 available_width = containing_block->width;
int space; 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 /* The static position is where the box would be if it was not
* absolutely positioned. The x and y are filled in by * 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->width = width;
box->height = height; 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)) if (!layout_block_context(box, content))
return false; return false;
} else if (box->type == BOX_TABLE) { } else if (box->type == BOX_TABLE) {