Implement absolute positioned inlines.
svn path=/trunk/netsurf/; revision=3026
This commit is contained in:
parent
a1f291383f
commit
b6c8e435cd
|
@ -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()).
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue