[project @ 2005-03-26 01:12:27 by bursa]

Split box.c into box_construct.c, box_normalise.c, and box.c.

svn path=/import/netsurf/; revision=1583
This commit is contained in:
James Bursa 2005-03-26 01:12:27 +00:00
parent 9b8a94cc39
commit 64d8f9d5ed
6 changed files with 3204 additions and 3126 deletions

4
depend
View File

@ -29,7 +29,9 @@ arm-riscos-aof/gif.o arm-ncos-aof/gif.o x86_64-linux-debug/gif.o x86_64-linux-gt
arm-riscos-aof/gifread.o arm-ncos-aof/gifread.o x86_64-linux-debug/gifread.o x86_64-linux-gtk/gifread.o : image/gifread.c image/bitmap.h utils/log.h
arm-riscos-aof/jpeg.o arm-ncos-aof/jpeg.o x86_64-linux-debug/jpeg.o x86_64-linux-gtk/jpeg.o : image/jpeg.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/plotters.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/pool.h utils/utils.h
arm-riscos-aof/mng.o arm-ncos-aof/mng.o x86_64-linux-debug/mng.o x86_64-linux-gtk/mng.o : image/mng.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/options.h desktop/plotters.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/pool.h utils/utils.h
arm-riscos-aof/box.o arm-ncos-aof/box.o x86_64-linux-debug/box.o x86_64-linux-gtk/box.o : render/box.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/font.h render/form.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/pool.h utils/url.h utils/utils.h
arm-riscos-aof/box.o arm-ncos-aof/box.o x86_64-linux-debug/box.o x86_64-linux-gtk/box.o : render/box.c content/content.h content/content_type.h css/css.h css/css_enum.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/pool.h
arm-riscos-aof/box_construct.o arm-ncos-aof/box_construct.o x86_64-linux-debug/box_construct.o x86_64-linux-gtk/box_construct.o : render/box_construct.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/form.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/pool.h utils/url.h utils/utils.h
arm-riscos-aof/box_normalise.o arm-ncos-aof/box_normalise.o x86_64-linux-debug/box_normalise.o x86_64-linux-gtk/box_normalise.o : render/box_normalise.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/html.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/pool.h
arm-riscos-aof/form.o arm-ncos-aof/form.o x86_64-linux-debug/form.o x86_64-linux-gtk/form.o : render/form.c render/box.h render/form.h utils/config.h utils/log.h utils/pool.h utils/utils.h
arm-riscos-aof/html.o arm-ncos-aof/html.o x86_64-linux-debug/html.o x86_64-linux-gtk/html.o : render/html.c content/content.h content/content_type.h content/fetch.h content/fetchcache.h css/css.h css/css_enum.h desktop/browser.h desktop/gui.h desktop/imagemap.h desktop/options.h desktop/tree.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/font.h render/html.h render/layout.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/pool.h utils/url.h utils/utils.h
arm-riscos-aof/html_redraw.o arm-ncos-aof/html_redraw.o x86_64-linux-debug/html_redraw.o x86_64-linux-gtk/html_redraw.o : render/html_redraw.c content/content.h content/content_type.h css/css.h css/css_enum.h desktop/plotters.h image/bitmap.h image/gif.h image/gifread.h image/jpeg.h image/mng.h render/box.h render/font.h render/form.h render/html.h render/layout.h riscos/draw.h riscos/plugin.h riscos/sprite.h utils/config.h utils/log.h utils/messages.h utils/pool.h utils/utils.h

View File

@ -19,8 +19,8 @@
OBJECTS_COMMON = content.o fetch.o fetchcache.o url_store.o # content/
OBJECTS_COMMON += css.o css_enum.o parser.o ruleset.o scanner.o # css/
OBJECTS_COMMON += box.o form.o html.o html_redraw.o layout.o \
list.o textplain.o # render/
OBJECTS_COMMON += box.o box_construct.o box_normalise.o form.o html.o \
html_redraw.o layout.o list.o textplain.o # render/
OBJECTS_COMMON += messages.o pool.o translit.o url.o utils.o # utils/
OBJECTS_COMMON += imagemap.o loginlist.o options.o tree.o # desktop/

File diff suppressed because it is too large Load Diff

View File

@ -2,12 +2,12 @@
* This file is part of NetSurf, http://netsurf.sourceforge.net/
* Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license
* Copyright 2004 James Bursa <bursa@users.sourceforge.net>
* Copyright 2005 James Bursa <bursa@users.sourceforge.net>
* Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
*/
/** \file
* Conversion of XML tree to box tree (interface).
* Box tree construction and manipulation (interface).
*
* This stage of rendering converts a tree of xmlNodes (produced by libxml2)
* to a tree of struct box. The box tree represents the structure of the
@ -231,20 +231,21 @@ struct column {
#define UNKNOWN_MAX_WIDTH INT_MAX
bool xml_to_box(xmlNode *n, struct content *c);
void box_dump(struct box *box, unsigned int depth);
struct box * box_create(struct css_style *style,
const char *href, const char *title,
const char *id, pool box_pool);
void box_add_child(struct box * parent, struct box *child);
void box_add_child(struct box *parent, struct box *child);
void box_insert_sibling(struct box *box, struct box *new_box);
void box_free(struct box *box);
void box_free_box(struct box *box);
void box_free_object_params(struct object_params *op);
void box_coords(struct box *box, int *x, int *y);
struct box *box_at_point(struct box *box, int x, int y,
int *box_x, int *box_y,
struct content **content);
struct box *box_object_at_point(struct content *c, int x, int y);
struct box *box_find_by_id(struct box *box, const char *id);
void box_dump(struct box *box, unsigned int depth);
bool box_vscrollbar_present(const struct box *box);
bool box_hscrollbar_present(const struct box *box);
@ -256,4 +257,8 @@ void box_scrollbar_dimensions(const struct box *box,
int *well_width,
int *bar_left, int *bar_width);
bool xml_to_box(xmlNode *n, struct content *c);
bool box_normalise_block(struct box *block, pool box_pool);
#endif

2384
render/box_construct.c Normal file

File diff suppressed because it is too large Load Diff

696
render/box_normalise.c Normal file
View File

@ -0,0 +1,696 @@
/*
* This file is part of NetSurf, http://netsurf.sourceforge.net/
* Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license
* Copyright 2005 James Bursa <bursa@users.sourceforge.net>
* Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
* Copyright 2005 John M Bell <jmb202@ecs.soton.ac.uk>
* Copyright 2004 Kevin Bagust <kevin.bagust@ntlworld.com>
*/
/** \file
* Box tree normalisation (implementation).
*/
#include <assert.h>
#include <stdbool.h>
#include "netsurf/css/css.h"
#include "netsurf/render/box.h"
#ifdef riscos
#include "netsurf/desktop/gui.h"
#endif
#define NDEBUG
#include "netsurf/utils/log.h"
#include "netsurf/utils/pool.h"
struct span_info {
unsigned int row_span;
bool auto_row;
bool auto_column;
};
struct columns {
unsigned int current_column;
bool extra;
/* Number of columns in main part of table 1..max columns */
unsigned int num_columns;
/* Information about columns in main table,
array 0 to num_columns - 1 */
struct span_info *spans;
/* Number of columns that have cells after a colspan 0 */
unsigned int extra_columns;
/* Number of rows in table */
unsigned int num_rows;
};
static bool box_normalise_table(struct box *table, pool box_pool);
static void box_normalise_table_spans(struct box *table);
static bool box_normalise_table_row_group(struct box *row_group,
struct columns *col_info,
pool box_pool);
static bool box_normalise_table_row(struct box *row,
struct columns *col_info,
pool box_pool);
static bool calculate_table_row(struct columns *col_info,
unsigned int col_span, unsigned int row_span,
unsigned int *start_column);
static bool box_normalise_inline_container(struct box *cont, pool box_pool);
/**
* Ensure the box tree is correctly nested by adding and removing nodes.
*
* \param block box of type BLOCK, INLINE_BLOCK, or TABLE_CELL
* \param box_pool pool to allocate new boxes in
* \return true on success, false on memory exhaustion
*
* The tree is modified to satisfy the following:
* \code
* parent permitted child nodes
* BLOCK, INLINE_BLOCK BLOCK, INLINE_CONTAINER, TABLE
* 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
* TABLE_ROW at least 1 TABLE_CELL
* TABLE_CELL BLOCK, INLINE_CONTAINER, TABLE (same as BLOCK)
* FLOAT_(LEFT|RIGHT) exactly 1 BLOCK or TABLE \endcode
*/
bool box_normalise_block(struct box *block, pool box_pool)
{
struct box *child;
struct box *next_child;
struct box *table;
struct css_style *style;
assert(block != 0);
LOG(("block %p, block->type %u", block, block->type));
assert(block->type == BOX_BLOCK || block->type == BOX_INLINE_BLOCK ||
block->type == BOX_TABLE_CELL);
gui_multitask();
for (child = block->children; child != 0; child = next_child) {
LOG(("child %p, child->type = %d", child, child->type));
next_child = child->next; /* child may be destroyed */
switch (child->type) {
case BOX_BLOCK:
/* ok */
if (!box_normalise_block(child, box_pool))
return false;
break;
case BOX_INLINE_CONTAINER:
if (!box_normalise_inline_container(child,
box_pool))
return false;
break;
case BOX_TABLE:
if (!box_normalise_table(child, box_pool))
return false;
break;
case BOX_INLINE:
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);
break;
case BOX_TABLE_ROW_GROUP:
case BOX_TABLE_ROW:
case BOX_TABLE_CELL:
/* insert implied table */
style = css_duplicate_style(block->style);
if (!style)
return false;
css_cascade(style, &css_blank_style);
table = box_create(style, block->href, 0, 0, box_pool);
if (!table) {
css_free_style(style);
return false;
}
table->type = BOX_TABLE;
if (child->prev == 0)
block->children = table;
else
child->prev->next = table;
table->prev = child->prev;
while (child != 0 && (
child->type == BOX_TABLE_ROW_GROUP ||
child->type == BOX_TABLE_ROW ||
child->type == BOX_TABLE_CELL)) {
box_add_child(table, child);
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;
if (!box_normalise_table(table, box_pool))
return false;
break;
default:
assert(0);
}
}
return true;
}
bool box_normalise_table(struct box *table, pool box_pool)
{
struct box *child;
struct box *next_child;
struct box *row_group;
struct css_style *style;
struct columns col_info;
assert(table != 0);
assert(table->type == BOX_TABLE);
LOG(("table %p", table));
col_info.num_columns = 1;
col_info.current_column = 0;
col_info.spans = malloc(2 * sizeof *col_info.spans);
if (!col_info.spans)
return false;
col_info.spans[0].row_span = col_info.spans[1].row_span = 0;
col_info.spans[0].auto_row = col_info.spans[0].auto_column =
col_info.spans[1].auto_row = col_info.spans[1].auto_column = false;
col_info.num_rows = col_info.extra_columns = 0;
col_info.extra = false;
for (child = table->children; child != 0; child = next_child) {
next_child = child->next;
switch (child->type) {
case BOX_TABLE_ROW_GROUP:
/* ok */
if (!box_normalise_table_row_group(child,
&col_info, box_pool)) {
free(col_info.spans);
return false;
}
break;
case BOX_BLOCK:
case BOX_INLINE_CONTAINER:
case BOX_TABLE:
case BOX_TABLE_ROW:
case BOX_TABLE_CELL:
/* insert implied table row group */
assert(table->style != NULL);
style = css_duplicate_style(table->style);
if (!style) {
free(col_info.spans);
return false;
}
css_cascade(style, &css_blank_style);
row_group = box_create(style, table->href, 0,
0, box_pool);
if (!row_group) {
free(col_info.spans);
css_free_style(style);
return false;
}
row_group->type = BOX_TABLE_ROW_GROUP;
if (child->prev == 0)
table->children = row_group;
else
child->prev->next = row_group;
row_group->prev = child->prev;
while (child != 0 && (
child->type == BOX_BLOCK ||
child->type == BOX_INLINE_CONTAINER ||
child->type == BOX_TABLE ||
child->type == BOX_TABLE_ROW ||
child->type == BOX_TABLE_CELL)) {
box_add_child(row_group, child);
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;
if (!box_normalise_table_row_group(row_group,
&col_info, box_pool)) {
free(col_info.spans);
return false;
}
break;
case BOX_INLINE:
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);
break;
default:
fprintf(stderr, "%i\n", child->type);
assert(0);
}
}
table->columns = col_info.num_columns;
table->rows = col_info.num_rows;
free(col_info.spans);
box_normalise_table_spans(table);
if (table->children == 0) {
LOG(("table->children == 0, removing"));
if (table->prev == 0)
table->parent->children = table->next;
else
table->prev->next = table->next;
if (table->next != 0)
table->next->prev = table->prev;
box_free(table);
}
LOG(("table %p done", table));
return true;
}
void box_normalise_table_spans(struct box *table)
{
struct box *table_row_group;
struct box *table_row;
struct box *table_cell;
unsigned int last_column;
unsigned int max_extra = 0;
bool extra;
bool force = false;
unsigned int rows_left = table->rows;
/* Scan table filling in table the width and height of table cells for
cells with colspan = 0 or rowspan = 0. Ignore the colspan and
rowspan of any cells that that follow an colspan = 0 */
for (table_row_group = table->children; table_row_group != NULL;
table_row_group = table_row_group->next) {
for (table_row = table_row_group->children; NULL != table_row;
table_row = table_row->next){
last_column = 0;
extra = false;
for (table_cell = table_row->children; NULL != table_cell;
table_cell = table_cell->next) {
/* We hae reached the end of the row, and have passed
a cell with colspan = 0 so ignore col and row spans */
if (force || extra || (table_cell->start_column + 1 <=
last_column)) {
extra = true;
table_cell->columns = 1;
table_cell->rows = 1;
if (table_cell->start_column <= max_extra) {
max_extra = table_cell->start_column + 1;
}
table_cell->start_column += table->columns;
} else {
/* Fill out the number of columns or the number of rows
if necessary */
if (0 == table_cell->columns) {
table_cell->columns = table->columns -
table_cell->start_column;
if ((0 == table_cell->start_column) &&
(0 == table_cell->rows)) {
force = true;
}
}
assert(0 != table_cell->columns);
if (0 == table_cell->rows) {
table_cell->rows = rows_left;
}
assert(0 != table_cell->rows);
last_column = table_cell->start_column + 1;
}
}
rows_left--;
}
}
table->columns += max_extra;
}
bool box_normalise_table_row_group(struct box *row_group,
struct columns *col_info,
pool box_pool)
{
struct box *child;
struct box *next_child;
struct box *row;
struct css_style *style;
assert(row_group != 0);
assert(row_group->type == BOX_TABLE_ROW_GROUP);
LOG(("row_group %p", row_group));
for (child = row_group->children; child != 0; child = next_child) {
next_child = child->next;
switch (child->type) {
case BOX_TABLE_ROW:
/* ok */
if (!box_normalise_table_row(child, col_info,
box_pool))
return false;
break;
case BOX_BLOCK:
case BOX_INLINE_CONTAINER:
case BOX_TABLE:
case BOX_TABLE_ROW_GROUP:
case BOX_TABLE_CELL:
/* insert implied table row */
assert(row_group->style != NULL);
style = css_duplicate_style(row_group->style);
if (!style)
return false;
css_cascade(style, &css_blank_style);
row = box_create(style, row_group->href, 0,
0, box_pool);
if (!row) {
css_free_style(style);
return false;
}
row->type = BOX_TABLE_ROW;
if (child->prev == 0)
row_group->children = row;
else
child->prev->next = row;
row->prev = child->prev;
while (child != 0 && (
child->type == BOX_BLOCK ||
child->type == BOX_INLINE_CONTAINER ||
child->type == BOX_TABLE ||
child->type == BOX_TABLE_ROW_GROUP ||
child->type == BOX_TABLE_CELL)) {
box_add_child(row, child);
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;
if (!box_normalise_table_row(row, col_info,
box_pool))
return false;
break;
case BOX_INLINE:
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);
break;
default:
assert(0);
}
}
if (row_group->children == 0) {
LOG(("row_group->children == 0, removing"));
if (row_group->prev == 0)
row_group->parent->children = row_group->next;
else
row_group->prev->next = row_group->next;
if (row_group->next != 0)
row_group->next->prev = row_group->prev;
box_free(row_group);
}
LOG(("row_group %p done", row_group));
return true;
}
bool box_normalise_table_row(struct box *row,
struct columns *col_info,
pool box_pool)
{
struct box *child;
struct box *next_child;
struct box *cell;
struct css_style *style;
unsigned int i;
assert(row != 0);
assert(row->type == BOX_TABLE_ROW);
LOG(("row %p", row));
for (child = row->children; child != 0; child = next_child) {
next_child = child->next;
switch (child->type) {
case BOX_TABLE_CELL:
/* ok */
if (!box_normalise_block(child, box_pool))
return false;
cell = child;
break;
case BOX_BLOCK:
case BOX_INLINE_CONTAINER:
case BOX_TABLE:
case BOX_TABLE_ROW_GROUP:
case BOX_TABLE_ROW:
/* insert implied table cell */
assert(row->style != NULL);
style = css_duplicate_style(row->style);
if (!style)
return false;
css_cascade(style, &css_blank_style);
cell = box_create(style, row->href, 0, 0,
box_pool);
if (!cell) {
css_free_style(style);
return false;
}
cell->type = BOX_TABLE_CELL;
if (child->prev == 0)
row->children = cell;
else
child->prev->next = cell;
cell->prev = child->prev;
while (child != 0 && (
child->type == BOX_BLOCK ||
child->type == BOX_INLINE_CONTAINER ||
child->type == BOX_TABLE ||
child->type == BOX_TABLE_ROW_GROUP ||
child->type == BOX_TABLE_ROW)) {
box_add_child(cell, child);
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;
if (!box_normalise_block(cell, box_pool))
return false;
break;
case BOX_INLINE:
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);
break;
default:
assert(0);
}
if (!calculate_table_row(col_info, cell->columns, cell->rows,
&cell->start_column))
return false;
}
for (i = 0; i < col_info->num_columns; i++) {
if ((col_info->spans[i].row_span != 0) && (!col_info->spans[i].auto_row)) {
col_info->spans[i].row_span--;
if ((col_info->spans[i].auto_column) && (0 == col_info->spans[i].row_span)) {
col_info->spans[i].auto_column = false;
}
}
}
col_info->current_column = 0;
col_info->extra = false;
if (row->children == 0) {
LOG(("row->children == 0, removing"));
if (row->prev == 0)
row->parent->children = row->next;
else
row->prev->next = row->next;
if (row->next != 0)
row->next->prev = row->prev;
box_free(row);
} else {
col_info->num_rows++;
}
LOG(("row %p done", row));
return true;
}
/**
* \return true on success, false on memory exhaustion
*/
bool calculate_table_row(struct columns *col_info,
unsigned int col_span, unsigned int row_span,
unsigned int *start_column)
{
unsigned int cell_start_col;
unsigned int cell_end_col;
unsigned int i;
struct span_info *spans;
if (!col_info->extra) {
/* skip columns with cells spanning from above */
while ((col_info->spans[col_info->current_column].row_span != 0) &&
(!col_info->spans[col_info->current_column].auto_column)) {
col_info->current_column++;
}
if (col_info->spans[col_info->current_column].auto_column) {
col_info->extra = true;
col_info->current_column = 0;
}
}
cell_start_col = col_info->current_column;
/* If the current table cell follows a cell with colspan=0,
ignore both colspan and rowspan just assume it is a standard
size cell */
if (col_info->extra) {
col_info->current_column++;
col_info->extra_columns = col_info->current_column;
} else {
/* If span to end of table, assume spaning single column
at the moment */
cell_end_col = cell_start_col + ((0 == col_span) ? 1 : col_span);
if (col_info->num_columns < cell_end_col) {
spans = realloc(col_info->spans,
sizeof *spans * (cell_end_col + 1));
if (!spans)
return false;
col_info->spans = spans;
col_info->num_columns = cell_end_col;
/* Mark new final column as sentinal */
col_info->spans[cell_end_col].row_span = 0;
col_info->spans[cell_end_col].auto_row =
col_info->spans[cell_end_col].auto_column =
false;
}
if (0 == col_span) {
col_info->spans[cell_start_col].auto_column = true;
col_info->spans[cell_start_col].row_span = row_span;
col_info->spans[cell_start_col].auto_row = (0 == row_span);
} else {
for (i = cell_start_col; i < cell_end_col; i++) {
col_info->spans[i].row_span = (0 == row_span) ?
1 : row_span;
col_info->spans[i].auto_row = (0 == row_span);
col_info->spans[i].auto_column = false;
}
}
if (0 == col_span) {
col_info->spans[cell_end_col].auto_column = true;
}
col_info->current_column = cell_end_col;
}
*start_column = cell_start_col;
return true;
}
bool box_normalise_inline_container(struct box *cont, pool box_pool)
{
struct box *child;
struct box *next_child;
assert(cont != 0);
assert(cont->type == BOX_INLINE_CONTAINER);
LOG(("cont %p", cont));
for (child = cont->children; child != 0; child = next_child) {
next_child = child->next;
switch (child->type) {
case BOX_INLINE:
case BOX_BR:
/* ok */
break;
case BOX_INLINE_BLOCK:
/* ok */
if (!box_normalise_block(child, box_pool))
return false;
break;
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
/* ok */
assert(child->children != 0);
switch (child->children->type) {
case BOX_BLOCK:
if (!box_normalise_block(
child->children,
box_pool))
return false;
break;
case BOX_TABLE:
if (!box_normalise_table(
child->children,
box_pool))
return false;
break;
default:
assert(0);
}
if (child->children == 0) {
/* the child has destroyed itself: remove float */
if (child->prev == 0)
child->parent->children = child->next;
else
child->prev->next = child->next;
if (child->next != 0)
child->next->prev = child->prev;
box_free(child);
}
break;
case BOX_BLOCK:
case BOX_INLINE_CONTAINER:
case BOX_TABLE:
case BOX_TABLE_ROW_GROUP:
case BOX_TABLE_ROW:
case BOX_TABLE_CELL:
default:
assert(0);
}
}
LOG(("cont %p done", cont));
return true;
}