[project @ 2004-04-18 15:19:53 by bursa]

Implement <br> properly by adding BOX_BR; fix box tree normalisation bugs.

svn path=/import/netsurf/; revision=791
This commit is contained in:
James Bursa 2004-04-18 15:19:53 +00:00
parent dc510627d9
commit dc937fe9ba
4 changed files with 87 additions and 27 deletions

View File

@ -1,4 +1,4 @@
address, blockquote, body, br, center, dd, div,
address, blockquote, body, center, dd, div,
dl, dt, fieldset, form,
h1, h2, h3, h4, h5, h6, html,
ol, p, ul,

View File

@ -63,6 +63,8 @@ static struct result box_a(xmlNode *n, struct status *status,
struct css_style *style);
static struct result box_body(xmlNode *n, struct status *status,
struct css_style *style);
static struct result box_br(xmlNode *n, struct status *status,
struct css_style *style);
static struct result box_image(xmlNode *n, struct status *status,
struct css_style *style);
static struct result box_form(xmlNode *n, struct status *status,
@ -112,6 +114,7 @@ static const struct element_entry element_table[] = {
{"a", box_a},
{"applet", box_applet},
{"body", box_body},
{"br", box_br},
{"button", box_button},
{"embed", box_embed},
{"form", box_form},
@ -337,7 +340,9 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content,
box = box_create(style, status.href, title,
content->data.html.box_pool);
}
box->type = box_map[style->display];
/* set box type from style if it has not been set already */
if (box->type == BOX_INLINE)
box->type = box_map[style->display];
} else if (n->type == XML_TEXT_NODE) {
/* text node: added to inline container below */
@ -449,7 +454,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content,
} else if (box->type == BOX_INLINE ||
box->type == BOX_INLINE_BLOCK ||
style->float_ == CSS_FLOAT_LEFT ||
style->float_ == CSS_FLOAT_RIGHT) {
style->float_ == CSS_FLOAT_RIGHT ||
box->type == BOX_BR) {
/* this is an inline box */
if (inline_container == 0) {
/* this is the first inline node: make a container */
@ -459,7 +465,7 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content,
box_add_child(parent, inline_container);
}
if (box->type == BOX_INLINE) {
if (box->type == BOX_INLINE || box->type == BOX_BR) {
/* inline box: add to tree and recurse */
box_add_child(inline_container, box);
if (convert_children) {
@ -750,6 +756,16 @@ struct result box_body(xmlNode *n, struct status *status,
return (struct result) {box, 1};
}
struct result box_br(xmlNode *n, struct status *status,
struct css_style *style)
{
struct box *box;
box = box_create(style, status->href, status->title,
status->content->data.html.box_pool);
box->type = BOX_BR;
return (struct result) {box, 0};
}
static const content_type image_types[] = {
#ifdef riscos
CONTENT_JPEG, CONTENT_PNG, CONTENT_GIF, CONTENT_SPRITE, CONTENT_DRAW,
@ -853,6 +869,7 @@ struct result box_textarea(xmlNode *n, struct status *status,
box = box_create(style, NULL, 0,
status->content->data.html.box_pool);
box->type = BOX_INLINE_BLOCK;
box->gadget = xcalloc(1, sizeof(struct form_control));
box->gadget->box = box;
box->gadget->type = GADGET_TEXTAREA;
@ -860,7 +877,6 @@ struct result box_textarea(xmlNode *n, struct status *status,
form_add_control(status->current_form, box->gadget);
else
box->gadget->form = 0;
style->display = CSS_DISPLAY_INLINE_BLOCK;
/* split the content at newlines and make an inline container with an
* inline box for each line */
@ -954,9 +970,9 @@ struct result box_select(xmlNode *n, struct status *status,
}
box = box_create(style, NULL, 0, status->content->data.html.box_pool);
box->type = BOX_INLINE_BLOCK;
box->gadget = gadget;
gadget->box = box;
style->display = CSS_DISPLAY_INLINE_BLOCK;
inline_container = box_create(0, 0, 0,
status->content->data.html.box_pool);
@ -1169,7 +1185,7 @@ struct box *box_input_text(xmlNode *n, struct status *status,
struct box *box = box_create(style, 0, 0,
status->content->data.html.box_pool);
struct box *inline_container, *inline_box;
style->display = CSS_DISPLAY_INLINE_BLOCK;
box->type = BOX_INLINE_BLOCK;
box->gadget = xcalloc(1, sizeof(struct form_control));
box->gadget->box = box;
@ -1223,7 +1239,7 @@ struct result box_button(xmlNode *n, struct status *status,
char *type = (char *) xmlGetProp(n, (const xmlChar *) "type");
struct box *box = box_create(style, 0, 0,
status->content->data.html.box_pool);
style->display = CSS_DISPLAY_INLINE_BLOCK;
box->type = BOX_INLINE_BLOCK;
if (!type || strcasecmp(type, "submit") == 0) {
box->gadget = xcalloc(1, sizeof(struct form_control));
@ -1264,6 +1280,7 @@ void box_dump(struct box * box, unsigned int depth)
for (i = 0; i < depth; i++)
fprintf(stderr, " ");
fprintf(stderr, "%p ", box);
fprintf(stderr, "x%i y%i w%i h%i ", box->x, box->y, box->width, box->height);
if ((unsigned long)box->max_width != UNKNOWN_MAX_WIDTH)
fprintf(stderr, "min%i max%i ", box->min_width, box->max_width);
@ -1280,6 +1297,7 @@ void box_dump(struct box * box, unsigned int depth)
case BOX_TABLE_ROW_GROUP: fprintf(stderr, "BOX_TABLE_ROW_GROUP "); break;
case BOX_FLOAT_LEFT: fprintf(stderr, "BOX_FLOAT_LEFT "); break;
case BOX_FLOAT_RIGHT: fprintf(stderr, "BOX_FLOAT_RIGHT "); break;
case BOX_BR: fprintf(stderr, "BOX_BR "); break;
default: fprintf(stderr, "Unknown box type ");
}
if (box->text)
@ -1306,7 +1324,7 @@ void box_dump(struct box * box, unsigned int depth)
*
* parent permitted child nodes
* BLOCK, INLINE_BLOCK BLOCK, INLINE_CONTAINER, TABLE
* INLINE_CONTAINER INLINE, INLINE_BLOCK, FLOAT_LEFT, FLOAT_RIGHT
* INLINE_CONTAINER INLINE, INLINE_BLOCK, FLOAT_LEFT, FLOAT_RIGHT, BR
* INLINE none
* TABLE at least 1 TABLE_ROW_GROUP
* TABLE_ROW_GROUP at least 1 TABLE_ROW
@ -1346,6 +1364,7 @@ void box_normalise_block(struct box *block, pool box_pool)
case BOX_INLINE_BLOCK:
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
case BOX_BR:
/* should have been wrapped in inline
container by convert_xml_to_box() */
assert(0);
@ -1369,10 +1388,14 @@ void box_normalise_block(struct box *block, pool box_pool)
child->type == BOX_TABLE_ROW ||
child->type == BOX_TABLE_CELL)) {
box_add_child(table, child);
child = child->next;
next_child = child->next;
child->next = 0;
child = next_child;
}
table->last->next = 0;
table->next = next_child = child;
if (table->next)
table->next->prev = table;
table->parent = block;
box_normalise_table(table, box_pool);
break;
@ -1430,10 +1453,14 @@ void box_normalise_table(struct box *table, pool box_pool)
child->type == BOX_TABLE_ROW ||
child->type == BOX_TABLE_CELL)) {
box_add_child(row_group, child);
child = child->next;
next_child = child->next;
child->next = 0;
child = next_child;
}
row_group->last->next = 0;
row_group->next = next_child = child;
if (row_group->next)
row_group->next->prev = row_group;
row_group->parent = table;
box_normalise_table_row_group(row_group, &row_span,
&table_columns, box_pool);
@ -1442,6 +1469,7 @@ void box_normalise_table(struct box *table, pool box_pool)
case BOX_INLINE_BLOCK:
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
case BOX_BR:
/* should have been wrapped in inline
container by convert_xml_to_box() */
assert(0);
@ -1515,10 +1543,14 @@ void box_normalise_table_row_group(struct box *row_group,
child->type == BOX_TABLE_ROW_GROUP ||
child->type == BOX_TABLE_CELL)) {
box_add_child(row, child);
child = child->next;
next_child = child->next;
child->next = 0;
child = next_child;
}
row->last->next = 0;
row->next = next_child = child;
if (row->next)
row->next->prev = row;
row->parent = row_group;
box_normalise_table_row(row, row_span,
table_columns, box_pool);
@ -1527,6 +1559,7 @@ void box_normalise_table_row_group(struct box *row_group,
case BOX_INLINE_BLOCK:
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
case BOX_BR:
/* should have been wrapped in inline
container by convert_xml_to_box() */
assert(0);
@ -1596,10 +1629,14 @@ void box_normalise_table_row(struct box *row,
child->type == BOX_TABLE_ROW_GROUP ||
child->type == BOX_TABLE_ROW)) {
box_add_child(cell, child);
child = child->next;
next_child = child->next;
child->next = 0;
child = next_child;
}
cell->last->next = 0;
cell->next = next_child = child;
if (cell->next)
cell->next->prev = cell;
cell->parent = row;
box_normalise_block(cell, box_pool);
break;
@ -1607,6 +1644,7 @@ void box_normalise_table_row(struct box *row,
case BOX_INLINE_BLOCK:
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
case BOX_BR:
/* should have been wrapped in inline
container by convert_xml_to_box() */
assert(0);
@ -1663,6 +1701,7 @@ void box_normalise_inline_container(struct box *cont, pool box_pool)
next_child = child->next;
switch (child->type) {
case BOX_INLINE:
case BOX_BR:
/* ok */
break;
case BOX_INLINE_BLOCK:
@ -2275,7 +2314,6 @@ struct result box_frameset(xmlNode *n, struct status *status,
box = box_create(style, 0, status->title,
status->content->data.html.box_pool);
box->type = BOX_TABLE;
style->display = CSS_DISPLAY_TABLE;
/* count rows and columns */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "rows"))) {

View File

@ -61,7 +61,7 @@
* \code
* parent permitted child nodes
* BLOCK, INLINE_BLOCK BLOCK, INLINE_CONTAINER, TABLE
* INLINE_CONTAINER INLINE, INLINE_BLOCK, FLOAT_LEFT, FLOAT_RIGHT
* INLINE_CONTAINER INLINE, INLINE_BLOCK, FLOAT_LEFT, FLOAT_RIGHT, BR
* INLINE none
* TABLE at least 1 TABLE_ROW_GROUP
* TABLE_ROW_GROUP at least 1 TABLE_ROW
@ -87,7 +87,7 @@ typedef enum {
BOX_TABLE, BOX_TABLE_ROW, BOX_TABLE_CELL,
BOX_TABLE_ROW_GROUP,
BOX_FLOAT_LEFT, BOX_FLOAT_RIGHT,
BOX_INLINE_BLOCK
BOX_INLINE_BLOCK, BOX_BR
} box_type;
struct column {

View File

@ -607,7 +607,7 @@ struct box * layout_line(struct box *first, int width, int *y,
struct box *b;
struct box *split_box = 0;
struct box *d;
int move_y = 0;
bool move_y = false;
int space_before = 0, space_after = 0;
unsigned int inline_count = 0;
@ -628,7 +628,8 @@ struct box * layout_line(struct box *first, int width, int *y,
for (x = 0, b = first; x < x1 - x0 && b != 0; b = b->next) {
assert(b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK ||
b->type == BOX_FLOAT_LEFT ||
b->type == BOX_FLOAT_RIGHT);
b->type == BOX_FLOAT_RIGHT ||
b->type == BOX_BR);
if (b->type == BOX_INLINE_BLOCK) {
if (b->width == UNKNOWN_WIDTH)
@ -644,6 +645,9 @@ struct box * layout_line(struct box *first, int width, int *y,
b->margin[RIGHT];
}
if (b->type == BOX_BR)
break;
if (b->type != BOX_INLINE)
continue;
@ -715,9 +719,17 @@ struct box * layout_line(struct box *first, int width, int *y,
else
space_after = 0;
split_box = b;
move_y = 1;
move_y = true;
inline_count++;
/* fprintf(stderr, "layout_line: '%.*s' %li %li\n", b->length, b->text, xp, x); */
} else if (b->type == BOX_BR) {
b->x = x;
b->width = 0;
b = b->next;
split_box = 0;
move_y = true;
break;
} else {
/* float */
d = b->children;
@ -859,7 +871,7 @@ struct box * layout_line(struct box *first, int width, int *y,
x += space_before + w;
/* fprintf(stderr, "layout_line: overflow, fit\n"); */
}
move_y = 1;
move_y = true;
}
/* set positions */
@ -870,7 +882,8 @@ struct box * 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) {
if (d->type == BOX_INLINE || d->type == BOX_INLINE_BLOCK ||
d->type == BOX_BR) {
d->x += x0;
d->y = *y + d->border[TOP];
h = d->border[TOP] + d->padding[TOP] + d->height +
@ -1287,7 +1300,7 @@ void calculate_widths(struct box *box)
void calculate_inline_container_widths(struct box *box)
{
struct box *child;
int min = 0, max = 0, width;
int min = 0, max = 0, line_max = 0, width;
unsigned int i, j;
for (child = box->children; child != 0; child = child->next) {
@ -1297,7 +1310,7 @@ void calculate_inline_container_widths(struct box *box)
if (child->style->width.width == CSS_WIDTH_LENGTH) {
child->width = len(&child->style->width.value.length,
child->style);
max += child->width;
line_max += child->width;
if (min < child->width)
min = child->width;
}
@ -1306,9 +1319,9 @@ void calculate_inline_container_widths(struct box *box)
/* max = all one line */
child->width = font_width(child->font,
child->text, child->length);
max += child->width;
line_max += child->width;
if (child->next && child->space)
max += child->font->space_width;
line_max += child->font->space_width;
/* min = widest word */
i = 0;
@ -1329,10 +1342,10 @@ void calculate_inline_container_widths(struct box *box)
width = len(&child->style->width.value.length,
child->style);
if (min < width) min = width;
max += width;
line_max += width;
} else {
if (min < child->min_width) min = child->min_width;
max += child->max_width;
line_max += child->max_width;
}
break;
@ -1351,11 +1364,20 @@ void calculate_inline_container_widths(struct box *box)
}
break;
case BOX_BR:
if (max < line_max)
max = line_max;
line_max = 0;
break;
default:
assert(0);
}
}
if (max < line_max)
max = line_max;
if (box->parent && box->parent->style &&
(box->parent->style->white_space == CSS_WHITE_SPACE_PRE ||
box->parent->style->white_space == CSS_WHITE_SPACE_NOWRAP))