summaryrefslogtreecommitdiff
path: root/render/box_normalise.c
diff options
context:
space:
mode:
Diffstat (limited to 'render/box_normalise.c')
-rw-r--r--render/box_normalise.c66
1 files changed, 51 insertions, 15 deletions
diff --git a/render/box_normalise.c b/render/box_normalise.c
index 5a4b6256a..0c91fa3fd 100644
--- a/render/box_normalise.c
+++ b/render/box_normalise.c
@@ -42,6 +42,8 @@
struct span_info {
/** Number of rows this cell spans */
unsigned int row_span;
+ /** Row group of cell */
+ struct box *rg;
/** The cell in this column spans all rows until the end of the table */
bool auto_row;
};
@@ -72,7 +74,7 @@ static bool box_normalise_table_row(struct box *row,
html_content *c);
static bool calculate_table_row(struct columns *col_info,
unsigned int col_span, unsigned int row_span,
- unsigned int *start_column);
+ unsigned int *start_column, struct box *cell);
static bool box_normalise_inline_container(struct box *cont, html_content *c);
/**
@@ -419,6 +421,7 @@ bool box_normalise_table_spans(struct box *table, struct span_info *spans,
struct box *table_row;
struct box *table_cell;
unsigned int rows_left = table->rows;
+ unsigned int group_rows_left;
unsigned int col;
nscss_select_ctx ctx;
@@ -427,20 +430,37 @@ bool box_normalise_table_spans(struct box *table, struct span_info *spans,
/* Scan table, filling in width and height of table cells with
* colspan = 0 and rowspan = 0. Also generate empty cells */
- for (table_row_group = table->children; table_row_group != NULL;
- table_row_group = table_row_group->next) {
- for (table_row = table_row_group->children; table_row != NULL;
- table_row = table_row->next){
- for (table_cell = table_row->children;
- table_cell != NULL;
- table_cell = table_cell->next) {
+ for (table_row_group = table->children;
+ table_row_group != NULL;
+ table_row_group = table_row_group->next) {
+
+ group_rows_left = table_row_group->rows;
+
+ for (table_row = table_row_group->children;
+ table_row != NULL;
+ table_row = table_row->next) {
+
+ for (table_cell = table_row->children;
+ table_cell != NULL;
+ table_cell = table_cell->next) {
+
/* colspan = 0 -> colspan = 1 */
- if (table_cell->columns == 0)
+ if (table_cell->columns == 0) {
table_cell->columns = 1;
+ }
+
+ /* if rowspan is 0 it is expanded to
+ * the number of rows left in the row
+ * group
+ */
+ if (table_cell->rows == 0) {
+ table_cell->rows = group_rows_left;
+ }
- /* rowspan = 0 -> rowspan = rows_left */
- if (table_cell->rows == 0)
- table_cell->rows = rows_left;
+ /* limit rowspans within group */
+ if (table_cell->rows > group_rows_left) {
+ table_cell->rows = group_rows_left;
+ }
/* Record span information */
for (col = table_cell->start_column;
@@ -540,6 +560,8 @@ bool box_normalise_table_spans(struct box *table, struct span_info *spans,
rows_left--;
}
+
+ group_rows_left--;
}
return true;
@@ -555,6 +577,7 @@ bool box_normalise_table_row_group(struct box *row_group,
struct box *row;
css_computed_style *style;
nscss_select_ctx ctx;
+ unsigned int group_row_count = 0;
assert(row_group != 0);
assert(row_group->type == BOX_TABLE_ROW_GROUP);
@@ -569,6 +592,7 @@ bool box_normalise_table_row_group(struct box *row_group,
switch (child->type) {
case BOX_TABLE_ROW:
/* ok */
+ group_row_count++;
if (box_normalise_table_row(child, col_info,
c) == false)
return false;
@@ -628,6 +652,7 @@ bool box_normalise_table_row_group(struct box *row_group,
row_group->last = row;
row->parent = row_group;
+ group_row_count++;
if (box_normalise_table_row(row, col_info,
c) == false)
return false;
@@ -676,10 +701,14 @@ bool box_normalise_table_row_group(struct box *row_group,
row->parent = row_group;
row_group->children = row_group->last = row;
+ group_row_count = 1;
+
/* Keep table's row count in sync */
col_info->num_rows++;
}
+ row_group->rows = group_row_count;
+
#ifdef BOX_NORMALISE_DEBUG
LOG(("row_group %p done", row_group));
#endif
@@ -790,7 +819,7 @@ bool box_normalise_table_row(struct box *row,
}
if (calculate_table_row(col_info, cell->columns, cell->rows,
- &cell->start_column) == false)
+ &cell->start_column, cell) == false)
return false;
}
@@ -827,21 +856,27 @@ bool box_normalise_table_row(struct box *row,
* \param col_span Number of columns that current cell spans
* \param row_span Number of rows that current cell spans
* \param start_column Pointer to location to receive column index
+ * \param cell Box for current table cell
* \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 *start_column, struct box *cell)
{
unsigned int cell_start_col = col_info->current_column;
unsigned int cell_end_col;
unsigned int i;
struct span_info *spans;
+ struct box *rg = cell->parent->parent; /* Cell's row group */
/* Skip columns with cells spanning from above */
- while (col_info->spans[cell_start_col].row_span != 0)
+ /* TODO: Need to ignore cells spanning from above that belong to
+ * different row group. We don't have that info here. */
+ while (col_info->spans[cell_start_col].row_span != 0 &&
+ col_info->spans[cell_start_col].rg == rg) {
cell_start_col++;
+ }
/* Update current column with calculated start */
col_info->current_column = cell_start_col;
@@ -876,6 +911,7 @@ bool calculate_table_row(struct columns *col_info,
for (i = cell_start_col; i < cell_end_col; i++) {
col_info->spans[i].row_span = (row_span == 0) ? 1 : row_span;
col_info->spans[i].auto_row = (row_span == 0);
+ col_info->spans[i].rg = rg;
}
/* Update current column with calculated end. */