[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:
parent
dc510627d9
commit
dc937fe9ba
|
@ -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,
|
||||
|
|
64
render/box.c
64
render/box.c
|
@ -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"))) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue