summaryrefslogtreecommitdiff
path: root/render/layout.c
diff options
context:
space:
mode:
authorJames Bursa <james@netsurf-browser.org>2003-07-06 21:10:12 +0000
committerJames Bursa <james@netsurf-browser.org>2003-07-06 21:10:12 +0000
commitb5606d8f61d3da51302c7acd81ceaa1c236a04b6 (patch)
tree3c73b7713f035c34dd0b4e9413e03774a1541f6c /render/layout.c
parent210a18e39d5858c86b3a7bfc1562b1ad569e5900 (diff)
downloadnetsurf-b5606d8f61d3da51302c7acd81ceaa1c236a04b6.tar.gz
netsurf-b5606d8f61d3da51302c7acd81ceaa1c236a04b6.tar.bz2
[project @ 2003-07-06 21:10:12 by bursa]
Implement rowspan. svn path=/import/netsurf/; revision=207
Diffstat (limited to 'render/layout.c')
-rw-r--r--render/layout.c63
1 files changed, 50 insertions, 13 deletions
diff --git a/render/layout.c b/render/layout.c
index f2bd019c9..4a8bcd386 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -590,9 +590,11 @@ void layout_table(struct box * table, unsigned long width, struct box * cont,
unsigned long table_height = 0;
unsigned long *xs; /* array of column x positions */
unsigned int i;
+ unsigned int *row_span, *excess_y, min;
struct box *c;
struct box *row;
struct box *row_group;
+ struct box **row_span_cell;
assert(table->type == BOX_TABLE);
assert(table->style != 0);
@@ -661,20 +663,26 @@ void layout_table(struct box * table, unsigned long width, struct box * cont,
}
xs = xcalloc(columns + 1, sizeof(*xs));
+ row_span = xcalloc(columns, sizeof(row_span[0]));
+ excess_y = xcalloc(columns, sizeof(excess_y[0]));
+ row_span_cell = xcalloc(columns, sizeof(row_span_cell[0]));
xs[0] = x = 0;
- for (i = 0; i < table->columns; i++) {
+ for (i = 0; i != columns; i++) {
x += table->col[i].width;
xs[i + 1] = x;
+ row_span[i] = 0;
+ excess_y[i] = 0;
+ row_span_cell[i] = 0;
}
-
+
/* position cells */
for (row_group = table->children; row_group != 0; row_group = row_group->next) {
unsigned long row_group_height = 0;
for (row = row_group->children; row != 0; row = row->next) {
unsigned long row_height = 0;
- for (i = 0, c = row->children; c != 0; i += c->columns, c = c->next) {
+ for (c = row->children; c != 0; c = c->next) {
assert(c->style != 0);
- c->width = xs[i + c->columns] - xs[i];
+ c->width = xs[c->start_column + c->columns] - xs[c->start_column];
c->float_children = 0;
c->height = layout_block_children(c, c->width, c, 0, 0);
if (c->style->height.height == CSS_HEIGHT_LENGTH) {
@@ -685,12 +693,37 @@ void layout_table(struct box * table, unsigned long width, struct box * cont,
if (c->height < h)
c->height = h;
}
- c->x = xs[i];
+ c->x = xs[c->start_column];
c->y = 0;
- if (c->height > row_height) row_height = c->height;
+ for (i = 0; i != c->columns; i++) {
+ row_span[c->start_column + i] = c->rows;
+ excess_y[c->start_column + i] = c->height;
+ row_span_cell[c->start_column + i] = 0;
+ }
+ row_span_cell[c->start_column] = c;
+ c->height = 0;
+ }
+ for (i = 0; i != columns; i++)
+ row_span[i]--;
+ /* if all columns have a row span, shrink it to the lowest equivalent */
+ min = row_span[0];
+ for (i = 1; i != columns; i++)
+ if (row_span[i] < min)
+ min = row_span[i];
+ for (i = 0; i != columns; i++)
+ row_span[i] -= min;
+ /* row height is greatest excess of a cell which ends in this row */
+ for (i = 0; i != columns; i++)
+ if (row_span[i] == 0 && row_height < excess_y[i])
+ row_height = excess_y[i];
+ for (i = 0; i != columns; i++) {
+ excess_y[i] -= row_height;
+ if (row_span_cell[i] != 0)
+ row_span_cell[i]->height += row_height;
}
- for (c = row->children; c != 0; c = c->next)
- c->height = row_height;
+
+ /*for (c = row->children; c != 0; c = c->next)
+ c->height = row_height;*/
row->x = 0;
row->y = row_group_height;
row->width = table_width;
@@ -704,7 +737,10 @@ void layout_table(struct box * table, unsigned long width, struct box * cont,
table_height += row_group_height;
}
- free(xs);
+ xfree(row_span_cell);
+ xfree(excess_y);
+ xfree(row_span);
+ xfree(xs);
table->width = table_width;
table->height = table_height;
@@ -848,25 +884,26 @@ void calculate_table_widths(struct box *table)
LOG(("table %p, columns %u", table, table->columns));
assert(table->children != 0 && table->children->children != 0);
- for (pass = 1; pass != 3; pass++) {
+ for (pass = 0; pass != 2; pass++) {
for (row_group = table->children; row_group != 0; row_group = row_group->next) {
assert(row_group->type == BOX_TABLE_ROW_GROUP);
for (row = row_group->children; row != 0; row = row->next) {
assert(row->type == BOX_TABLE_ROW);
- for (i = 0, cell = row->children; cell != 0;
- i += cell->columns, cell = cell->next) {
+ for (cell = row->children; cell != 0; cell = cell->next) {
unsigned int j, flexible_columns = 0;
unsigned long min = 0, max = 0, extra;
/* consider cells with colspan 1 in 1st pass, rest
* in 2nd pass */
- if (pass != cell->columns)
+ if ((pass == 0 && cell->columns != 1) ||
+ (pass == 1 && cell->columns == 1))
continue;
assert(cell->type == BOX_TABLE_CELL);
assert(cell->style != 0);
calculate_widths(cell);
+ i = cell->start_column;
/* find min, max width so far of spanned columns */
for (j = 0; j != cell->columns; j++) {