summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Bursa <james@netsurf-browser.org>2005-06-05 20:54:37 +0000
committerJames Bursa <james@netsurf-browser.org>2005-06-05 20:54:37 +0000
commit57b68bd9332f4c1636073ab8dd10a3ce50a173cf (patch)
tree8323cb6b6ed9a63b75751c6fa892c6f927c2c833
parent99a483dd7b744ede170eeffde5ec30fd8ed1a0e5 (diff)
downloadnetsurf-57b68bd9332f4c1636073ab8dd10a3ce50a173cf.tar.gz
netsurf-57b68bd9332f4c1636073ab8dd10a3ce50a173cf.tar.bz2
[project @ 2005-06-05 20:54:37 by bursa]
More work on borders / padding / margins on inline elements. Add BOX_INLINE_END to hold the right border / padding / margin (left is in the BOX_INLINE). svn path=/import/netsurf/; revision=1742
-rw-r--r--render/box.c11
-rw-r--r--render/box.h11
-rw-r--r--render/box_construct.c24
-rw-r--r--render/box_normalise.c9
-rw-r--r--render/html_redraw.c38
-rw-r--r--render/layout.c52
6 files changed, 98 insertions, 47 deletions
diff --git a/render/box.c b/render/box.c
index b53ae2b2b..c6e1702d5 100644
--- a/render/box.c
+++ b/render/box.c
@@ -76,7 +76,7 @@ struct box * box_create(struct css_style *style,
box->last = NULL;
box->parent = NULL;
box->fallback = NULL;
- box->end_inline_children = NULL;
+ box->inline_end = NULL;
box->float_children = NULL;
box->next_float = NULL;
box->col = NULL;
@@ -100,6 +100,9 @@ struct box * box_create(struct css_style *style,
void box_add_child(struct box *parent, struct box *child)
{
+ assert(parent);
+ assert(child);
+
if (parent->children != 0) { /* has children already */
parent->last->next = child;
child->prev = parent->last;
@@ -447,6 +450,7 @@ void box_dump(struct box *box, unsigned int depth)
case BOX_BLOCK: fprintf(stderr, "BLOCK "); break;
case BOX_INLINE_CONTAINER: fprintf(stderr, "INLINE_CONTAINER "); break;
case BOX_INLINE: fprintf(stderr, "INLINE "); break;
+ case BOX_INLINE_END: fprintf(stderr, "INLINE_END "); break;
case BOX_INLINE_BLOCK: fprintf(stderr, "INLINE_BLOCK "); break;
case BOX_TABLE: fprintf(stderr, "TABLE [columns %i] ",
box->columns); break;
@@ -476,9 +480,8 @@ void box_dump(struct box *box, unsigned int depth)
fprintf(stderr, " [%s]", box->title);
if (box->id != 0)
fprintf(stderr, " <%s>", box->id);
- if (box->type == BOX_INLINE)
- fprintf(stderr, " end_inline_children %p",
- box->end_inline_children);
+ if (box->type == BOX_INLINE || box->type == BOX_INLINE_END)
+ fprintf(stderr, " inline_end %p", box->inline_end);
if (box->float_children)
fprintf(stderr, " float_children %p", box->float_children);
if (box->next_float)
diff --git a/render/box.h b/render/box.h
index b377cd91a..f8fe0db90 100644
--- a/render/box.h
+++ b/render/box.h
@@ -91,7 +91,8 @@ typedef enum {
BOX_TABLE, BOX_TABLE_ROW, BOX_TABLE_CELL,
BOX_TABLE_ROW_GROUP,
BOX_FLOAT_LEFT, BOX_FLOAT_RIGHT,
- BOX_INLINE_BLOCK, BOX_BR, BOX_TEXT
+ BOX_INLINE_BLOCK, BOX_BR, BOX_TEXT,
+ BOX_INLINE_END
} box_type;
/** Node in box tree. All dimensions are in pixels. */
@@ -166,11 +167,9 @@ struct box {
struct box *last; /**< Last child box, or 0. */
struct box *parent; /**< Parent box, or 0. */
struct box *fallback; /**< Fallback children for object, or 0. */
- /** Sibling box after the last sibling box which was a child of this box
- * in the document tree (the box after is used so that splitting boxes
- * for line wrapping doesn't change it), or 0 if continues to end of
- * inline container (only valid for INLINE boxes). */
- struct box *end_inline_children;
+ /** INLINE_END box corresponding to this INLINE box, or INLINE box
+ * corresponding to this INLINE_END box. */
+ struct box *inline_end;
/** First float child box, or 0. Float boxes are in the tree twice, in
* this list for the block box which defines the area for floats, and
diff --git a/render/box_construct.c b/render/box_construct.c
index c3dc1e7bc..961fc7f17 100644
--- a/render/box_construct.c
+++ b/render/box_construct.c
@@ -263,6 +263,7 @@ bool box_construct_element(xmlNode *n, struct content *content,
char *s;
struct box *box = 0;
struct box *inline_container_c;
+ struct box *inline_end;
struct css_style *style = 0;
struct element_entry *element;
colour border_color;
@@ -336,13 +337,24 @@ bool box_construct_element(xmlNode *n, struct content *content,
if (box->type == BOX_INLINE || box->type == BOX_BR) {
/* inline box: add to tree and recurse */
box_add_child(*inline_container, box);
- for (c = n->children; convert_children && c; c = c->next)
- if (!convert_xml_to_box(c, content, style, parent,
- inline_container, href, title))
+ if (convert_children) {
+ for (c = n->children; c; c = c->next)
+ if (!convert_xml_to_box(c, content, style,
+ parent, inline_container,
+ href, title))
+ return false;
+ inline_end = box_create(style, href, title, id,
+ content);
+ if (!inline_end)
return false;
- /* corrected to next box (which doesn't exist yet) in
- * box_normalise_inline_container() */
- box->end_inline_children = (*inline_container)->last;
+ inline_end->type = BOX_INLINE_END;
+ if (*inline_container)
+ box_add_child(*inline_container, inline_end);
+ else
+ box_add_child(box->parent, inline_end);
+ box->inline_end = inline_end;
+ inline_end->inline_end = box;
+ }
} else if (box->type == BOX_INLINE_BLOCK) {
/* inline block box: add to tree and recurse */
box_add_child(*inline_container, box);
diff --git a/render/box_normalise.c b/render/box_normalise.c
index c67fe285d..22971af8c 100644
--- a/render/box_normalise.c
+++ b/render/box_normalise.c
@@ -110,6 +110,7 @@ bool box_normalise_block(struct box *block, struct content *c)
return false;
break;
case BOX_INLINE:
+ case BOX_INLINE_END:
case BOX_INLINE_BLOCK:
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
@@ -246,6 +247,7 @@ bool box_normalise_table(struct box *table, struct content * c)
}
break;
case BOX_INLINE:
+ case BOX_INLINE_END:
case BOX_INLINE_BLOCK:
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
@@ -409,6 +411,7 @@ bool box_normalise_table_row_group(struct box *row_group,
return false;
break;
case BOX_INLINE:
+ case BOX_INLINE_END:
case BOX_INLINE_BLOCK:
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
@@ -506,6 +509,7 @@ bool box_normalise_table_row(struct box *row,
return false;
break;
case BOX_INLINE:
+ case BOX_INLINE_END:
case BOX_INLINE_BLOCK:
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
@@ -643,10 +647,7 @@ bool box_normalise_inline_container(struct box *cont, struct content * c)
next_child = child->next;
switch (child->type) {
case BOX_INLINE:
- /* correct end_inline_children to the box after the
- * last inline child (see box_construct_element()) */
- child->end_inline_children =
- child->end_inline_children->next;
+ case BOX_INLINE_END:
case BOX_BR:
case BOX_TEXT:
/* ok */
diff --git a/render/html_redraw.c b/render/html_redraw.c
index d6b255de2..cc946f17c 100644
--- a/render/html_redraw.c
+++ b/render/html_redraw.c
@@ -460,17 +460,22 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
if (box->type == BOX_INLINE && !box->object && !box->gadget &&
!box->text) {
- /* draw from next sibling to the sibling which has the same
- * inline parent as this box (which must mean it was the next
- * sibling of this inline in the HTML tree) */
- for (struct box *c = box->next;
- c && c != box->end_inline_children;
- c = c->next) {
+ int padding_height = (box->padding[TOP] + box->height +
+ box->padding[BOTTOM]) * scale;
+ for (struct box *c = box; c; c = c->next) {
int x = (x_parent + c->x) * scale;
- int y = (y_parent + c->y - box->padding[TOP]) * scale;
- int padding_width = c->width * scale;
- int padding_height = (box->padding[TOP] + c->height +
- box->padding[BOTTOM]) * scale;
+ int y = y_parent + c->y;
+ int padding_width = c->width;
+ if (c != box)
+ y -= box->padding[TOP];
+ if (c == box)
+ padding_width += box->padding[LEFT];
+ if (!box->inline_end || c == box->inline_end)
+ padding_width += box->padding[RIGHT];
+ if (scale != 1) {
+ y *= scale;
+ padding_width *= scale;
+ }
int p[20] = {
x, y,
x - left, y - top,
@@ -484,7 +489,7 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
x, y,
x - left, y - top
};
- if (box->border[LEFT] && c == box->next)
+ if (box->border[LEFT] && c == box)
html_redraw_border_plot(LEFT, p,
box->style->border[LEFT].color,
box->style->border[LEFT].style,
@@ -501,12 +506,14 @@ bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
box->style->border[BOTTOM].
style,
box->border[BOTTOM] * scale);
- if (box->border[RIGHT] && (!c->next ||
- c->next == box->end_inline_children))
+ if (box->border[RIGHT] && (!box->inline_end ||
+ c == box->inline_end))
html_redraw_border_plot(RIGHT, p,
box->style->border[RIGHT].color,
box->style->border[RIGHT].style,
box->border[RIGHT] * scale);
+ if (!box->inline_end || c == box->inline_end)
+ break;
}
} else {
int x = (x_parent + box->x) * scale;
@@ -1033,11 +1040,8 @@ bool html_redraw_text_decoration(struct box *box,
bool html_redraw_text_decoration_inline(struct box *box, int x, int y,
float scale, colour colour, float ratio)
{
- /* draw from next sibling to the sibling which has the same inline
- * parent as this box (which must mean it was the next sibling of this
- * inline in the HTML tree) */
for (struct box *c = box->next;
- c && c != box->end_inline_children;
+ c && c != box->inline_end;
c = c->next) {
if (!plot.line((x + c->x) * scale,
(y + c->y + c->height * ratio) * scale,
diff --git a/render/layout.c b/render/layout.c
index 90bdc8c3c..c8633d8f6 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -689,12 +689,13 @@ int line_height(struct css_style *style)
/* take account of minimum font size option */
if ((font_len = css_len2px(&style->font_size.value.length, 0)) <
- ((float)(option_font_min_size * 9.0 / 72.0)))
- font_len = (float)(option_font_min_size * 9.0 / 72.0);
+ option_font_min_size * 9.0 / 72.0)
+ font_len = option_font_min_size * 9.0 / 72.0;
switch (style->line_height.size) {
case CSS_LINE_HEIGHT_LENGTH:
- return (int)css_len2px(&style->line_height.value.length, style);
+ return css_len2px(&style->line_height.value.length,
+ style);
case CSS_LINE_HEIGHT_ABSOLUTE:
return style->line_height.value.absolute * font_len;
@@ -762,7 +763,8 @@ bool layout_line(struct box *first, int width, int *y,
assert(b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK ||
b->type == BOX_FLOAT_LEFT ||
b->type == BOX_FLOAT_RIGHT ||
- b->type == BOX_BR || b->type == BOX_TEXT);
+ b->type == BOX_BR || b->type == BOX_TEXT ||
+ b->type == BOX_INLINE_END);
x += space_after;
@@ -785,7 +787,8 @@ bool layout_line(struct box *first, int width, int *y,
if (b->type == BOX_BR)
break;
- if (b->type != BOX_INLINE && b->type != BOX_TEXT)
+ if (b->type != BOX_INLINE && b->type != BOX_TEXT &&
+ b->type != BOX_INLINE_END)
continue;
if (b->type == BOX_INLINE) {
@@ -795,6 +798,22 @@ bool layout_line(struct box *first, int width, int *y,
for (i = 0; i != 4; i++)
if (b->margin[i] == AUTO)
b->margin[i] = 0;
+ if (b->inline_end) {
+ b->inline_end->margin[RIGHT] = b->margin[RIGHT];
+ b->inline_end->padding[RIGHT] =
+ b->padding[RIGHT];
+ b->inline_end->border[RIGHT] =
+ b->border[RIGHT];
+ }
+ } else if (b->type == BOX_INLINE_END) {
+ b->width = 0;
+ if (b->space) {
+ /** \todo optimize out */
+ nsfont_width(b->style, " ", 1, &space_after);
+ } else {
+ space_after = 0;
+ }
+ continue;
}
if (!b->object && !b->gadget) {
@@ -919,26 +938,35 @@ bool layout_line(struct box *first, int width, int *y,
/* pass 2: place boxes in line: loop body executed at least once */
for (x = x_previous = 0, b = first; x <= x1 - x0 && b; b = b->next) {
if (b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK ||
- b->type == BOX_TEXT) {
+ b->type == BOX_TEXT ||
+ b->type == BOX_INLINE_END) {
assert(b->width != UNKNOWN_WIDTH);
x_previous = x;
x += space_after;
b->x = x;
- if (b->type == BOX_INLINE_BLOCK) {
+ if ((b->type == BOX_INLINE && !b->inline_end) ||
+ b->type == BOX_INLINE_BLOCK) {
b->x += b->margin[LEFT] + b->border[LEFT];
x = b->x + b->padding[LEFT] + b->width +
b->padding[RIGHT] +
b->border[RIGHT] +
b->margin[RIGHT];
- } else
+ } else if (b->type == BOX_INLINE) {
+ b->x += b->margin[LEFT] + b->border[LEFT];
+ x = b->x + b->padding[LEFT] + b->width;
+ } else if (b->type == BOX_INLINE_END) {
+ x += b->padding[RIGHT] + b->border[RIGHT] +
+ b->margin[RIGHT];
+ } else {
x += b->width;
+ }
space_before = space_after;
if (b->object)
space_after = 0;
- else if (b->text) {
+ else if (b->text || b->type == BOX_INLINE_END) {
space_after = 0;
if (b->space)
/** \todo handle errors, optimize */
@@ -1129,7 +1157,8 @@ bool layout_line(struct box *first, int width, int *y,
for (d = first; d != b; d = d->next) {
if (d->type == BOX_INLINE || d->type == BOX_INLINE_BLOCK ||
- d->type == BOX_BR || d->type == BOX_TEXT) {
+ d->type == BOX_BR || d->type == BOX_TEXT ||
+ d->type == BOX_INLINE_END) {
d->x += x0;
d->y = *y - d->padding[TOP];
}
@@ -1827,6 +1856,9 @@ bool calculate_inline_container_widths(struct box *box)
child->width = 0;
break;
+ case BOX_INLINE_END:
+ break;
+
case BOX_INLINE_BLOCK:
if (!calculate_block_widths(child, &min, &max,
&line_max))