/* Region of 'table' to render.
- The horizontal cells rendered are the leftmost h[H][0], then
- r[H][0] through r[H][1], exclusive, then the rightmost h[H][1].
+ The horizontal cells rendered are the leftmost h[H], then
+ r[H] through r[H][1].
- The vertical cells rendered are the topmost h[V][0], then r[V][0]
- through r[V][1], exclusive, then the bottommost h[V][1].
+ The vertical cells rendered are the topmost h[V], then r[V][0]
+ through r[V][1].
- n[H] = h[H][0] + (r[H][1] - r[H][0]) + h[H][1]
- n[V] = h[V][0] + (r[V][1] - r[V][0]) + h[V][1]
+ n[H] = h[H] + (r[H][1] - r[H][0])
+ n[V] = h[V] + (r[V][1] - r[V][0])
*/
- int h[TABLE_N_AXES][2];
+ int h[TABLE_N_AXES];
int r[TABLE_N_AXES][2];
int n[TABLE_N_AXES];
When is_edge_cutoff is true for a given edge, the 'overflows' hmap will
contain a node for each cell along that edge. */
bool is_edge_cutoff[TABLE_N_AXES][2];
-
- /* If part of a joined cell would be cut off by breaking a table along
- 'axis' at the rule with offset 'z' (where 0 <= z <= n[axis]), then
- join_crossing[axis][z] is the thickness of the rule that would be cut
- off.
-
- This is used to know to allocate extra space for breaking at such a
- position, so that part of the cell's content is not lost.
-
- This affects breaking a table only when headers are present. When
- headers are not present, the rule's thickness is used for cell content,
- so no part of the cell's content is lost (and in fact it is duplicated
- across both pages). */
- int *join_crossing[TABLE_N_AXES];
};
static struct render_page *render_page_create (const struct render_params *,
static int
headers_width (const struct render_page *page, int axis)
{
- int h0 = page->h[axis][0];
- int w0 = axis_width (page, axis, rule_ofs (0), cell_ofs (h0));
- int n = page->n[axis];
- int h1 = page->h[axis][1];
- int w1 = axis_width (page, axis, rule_ofs_r (page, axis, h1), cell_ofs (n));
- return w0 + w1;
+ return axis_width (page, axis, rule_ofs (0), cell_ofs (page->h[axis]));
}
/* Returns the width of cell X along AXIS in PAGE. */
static int
max_cell_width (const struct render_page *page, int axis)
{
- int n = page->n[axis];
- int x0 = page->h[axis][0];
- int x1 = n - page->h[axis][1];
+ int x0 = page->h[axis];
+ int x1 = page->n[axis];
int max = 0;
for (int x = x0; x < x1; x++)
page->n[V] = n[V];
for (int i = 0; i < TABLE_N_AXES; i++)
- {
- page->cp[i] = xcalloc ((2 * n[i] + 2) , sizeof *page->cp[i]);
- page->join_crossing[i] = xcalloc ((n[i] + 1) , sizeof *page->join_crossing[i]);
- }
+ page->cp[i] = xcalloc ((2 * n[i] + 2) , sizeof *page->cp[i]);
hmap_init (&page->overflows);
memset (page->is_edge_cutoff, 0, sizeof page->is_edge_cutoff);
struct render_page *page = render_page_allocate__ (params, table, table->n);
for (enum table_axis a = 0; a < TABLE_N_AXES; a++)
{
- page->h[a][0] = table->h[a][0];
- page->h[a][1] = table->h[a][1];
- page->r[a][0] = table->h[a][0];
- page->r[a][1] = table->n[a] - table->h[a][1];
+ page->h[a] = table->h[a];
+ page->r[a][0] = table->h[a];
+ page->r[a][1] = table->n[a];
}
return page;
}
return page;
}
\f
-static void
-set_join_crossings (struct render_page *page, enum table_axis axis,
- const struct table_cell *cell, int *rules)
-{
- for (int z = cell->d[axis][0] + 1; z <= cell->d[axis][1] - 1; z++)
- page->join_crossing[axis][z] = rules[z];
-}
-
/* Maps a contiguous range of cells from a page to the underlying table along
the horizontal or vertical dimension. */
struct map
get_map (const struct render_page *page, enum table_axis a, int z,
struct map *m)
{
- if (z < page->h[a][0])
+ if (z < page->h[a])
{
m->p0 = 0;
m->t0 = 0;
- m->n = page->h[a][0];
+ m->n = page->h[a];
}
- else if (z < page->n[a] - page->h[a][1])
+ else
{
- m->p0 = page->h[a][0];
+ assert (z < page->n[a]);
+ m->p0 = page->h[a];
m->t0 = page->r[a][0];
m->n = page->r[a][1] - page->r[a][0];
}
- else
- {
- m->p0 = page->n[a] - page->h[a][1];
- m->t0 = page->table->n[a] - page->table->h[a][1];
- m->n = page->h[a][1];
- }
}
/* Initializes CELL with the contents of the table cell at column X and row Y
struct table_cell cell;
render_get_cell (page, x, y, &cell);
- if (y == cell.d[V][0])
+ if (y == cell.d[V][0] && table_cell_rowspan (&cell) == 1)
{
- if (table_cell_rowspan (&cell) == 1)
- {
- int w = joined_width (page, H, cell.d[H][0], cell.d[H][1]);
- int h = params->ops->measure_cell_height (params->aux,
- &cell, w);
- if (h > r->unspanned)
- r->unspanned = r->width = h;
- }
- else
- set_join_crossings (page, V, &cell, rules[V]);
-
- if (table_cell_colspan (&cell) > 1)
- set_join_crossings (page, H, &cell, rules[H]);
+ int w = joined_width (page, H, cell.d[H][0], cell.d[H][1]);
+ int h = params->ops->measure_cell_height (params->aux,
+ &cell, w);
+ if (h > r->unspanned)
+ r->unspanned = r->width = h;
}
x = cell.d[H][1];
}
if (hw * 2 >= page->params->size[axis]
|| hw + max_cell_width (page, axis) > page->params->size[axis])
{
- page->h[axis][0] = page->h[axis][1] = 0;
+ page->h[axis] = 0;
page->r[axis][0] = 0;
page->r[axis][1] = page->n[axis];
}
table_unref (page->table);
for (int i = 0; i < TABLE_N_AXES; ++i)
- {
- free (page->join_crossing[i]);
- free (page->cp[i]);
- }
+ free (page->cp[i]);
free (page);
}
int d2 = -1;
enum table_axis a = axis;
- if (d[a] < page->h[a][0])
+ if (d[a] < page->h[a])
/* Nothing to do */;
- else if (d[a] <= page->n[a] - page->h[a][1])
+ else if (d[a] <= page->n[a])
{
- if (page->h[a][0] && d[a] == page->h[a][0])
- d2 = page->h[a][0];
- else if (page->h[a][1] && d[a] == page->n[a] - page->h[a][1])
- d2 = page->table->n[a] - page->h[a][1];
- d[a] += page->r[a][0] - page->h[a][0];
+ if (page->h[a] && d[a] == page->h[a])
+ d2 = page->h[a];
+ d[a] += page->r[a][0] - page->h[a];
}
- else
- d[a] += ((page->table->n[a] - page->table->h[a][1])
- - (page->n[a] - page->h[a][1]));
enum table_axis b = !axis;
struct map m;
spill[axis][1] = rule_width (page, axis, cell->d[axis][1]) / 2;
}
- int color_idx = (cell->d[V][0] < page->h[V][0]
- || page->n[V] - (cell->d[V][0] + 1) < page->h[V][1]
+ int color_idx = (cell->d[V][0] < page->h[V]
? 0
- : (cell->d[V][0] - page->h[V][0]) & 1);
+ : (cell->d[V][0] - page->h[V]) & 1);
page->params->ops->draw_cell (page->params->aux, cell, color_idx,
bb, valign_offset, spill, clip);
}
{
b->page = page;
b->axis = axis;
- b->z = page->h[axis][0];
+ b->z = page->h[axis];
b->pixel = 0;
b->hw = headers_width (page, axis);
}
const struct render_page *page = b->page;
enum table_axis axis = b->axis;
- return page != NULL && b->z < page->n[axis] - page->h[axis][1];
+ return page != NULL && b->z < page->n[axis];
}
/* Returns a new render_page that is up to SIZE pixels wide along B's axis.
int pixel = 0;
int z;
- for (z = b->z; z < page->n[axis] - page->h[axis][1]; z++)
+ for (z = b->z; z < page->n[axis]; z++)
{
int needed = needed_size (b, z + 1);
if (needed > size)
cell.
This is similar to code for the left side in needed_size(). */
- int rule_allowance = (page->h[axis][1]
- ? 0
- : rule_width (page, axis, z));
+ int rule_allowance = rule_width (page, axis, z);
/* The amount that, if we added cell 'z', the rendering would
overfill the allocated 'size'. */
enum table_axis axis = b->axis;
/* Width of left header not including its rightmost rule. */
- int size = axis_width (page, axis, 0, rule_ofs (page->h[axis][0]));
+ int size = axis_width (page, axis, 0, rule_ofs (page->h[axis]));
/* If we have a pixel offset and there is no left header, then we omit the
leftmost rule of the body. Otherwise the rendering is deceptive because
rightmost rule in the header and the leftmost rule in the body. We assume
that the width of a merged rule is the larger of the widths of either rule
invidiually. */
- if (b->pixel == 0 || page->h[axis][0])
- size += MAX (rule_width (page, axis, page->h[axis][0]),
+ if (b->pixel == 0 || page->h[axis])
+ size += MAX (rule_width (page, axis, page->h[axis]),
rule_width (page, axis, b->z));
/* Width of body, minus any pixel offset in the leftmost cell. */
size += joined_width (page, axis, b->z, cell) - b->pixel;
/* Width of rightmost rule in body merged with leftmost rule in headers. */
- size += MAX (rule_width_r (page, axis, page->h[axis][1]),
- rule_width (page, axis, cell));
-
- /* Width of right header not including its leftmost rule. */
- size += axis_width (page, axis, rule_ofs_r (page, axis, page->h[axis][1]),
- rule_ofs_r (page, axis, 0));
-
- /* Join crossing. */
- if (page->h[axis][0] && page->h[axis][1])
- size += page->join_crossing[axis][b->z];
+ size += MAX (rule_width_r (page, axis, 0), rule_width (page, axis, cell));
return size;
}
/* Optimize case where all of PAGE is selected by just incrementing the
reference count. */
- if (z0 == page->h[a][0] && p0 == 0
- && z1 == page->n[a] - page->h[a][1] && p1 == 0)
+ if (z0 == page->h[a] && p0 == 0 && z1 == page->n[a] && p1 == 0)
{
struct render_page *page_rw = CONST_CAST (struct render_page *, page);
page_rw->ref_cnt++;
}
/* Allocate subpage. */
- int trim[2] = { z0 - page->h[a][0], (page->n[a] - page->h[a][1]) - z1 };
+ int trim[2] = { z0 - page->h[a], page->n[a] - z1 };
int n[TABLE_N_AXES] = { [H] = page->n[H], [V] = page->n[V] };
n[a] -= trim[0] + trim[1];
struct render_page *subpage = render_page_allocate__ (
page->params, table_ref (page->table), n);
for (enum table_axis k = 0; k < TABLE_N_AXES; k++)
{
- subpage->h[k][0] = page->h[k][0];
- subpage->h[k][1] = page->h[k][1];
+ subpage->h[k] = page->h[k];
subpage->r[k][0] = page->r[k][0];
subpage->r[k][1] = page->r[k][1];
}
/* An edge is cut off if it was cut off in PAGE or if we're trimming pixels
off that side of the page and there are no headers. */
subpage->is_edge_cutoff[a][0] =
- subpage->h[a][0] == 0 && (p0 || (z0 == 0 && page->is_edge_cutoff[a][0]));
+ subpage->h[a] == 0 && (p0 || (z0 == 0 && page->is_edge_cutoff[a][0]));
subpage->is_edge_cutoff[a][1] =
- subpage->h[a][1] == 0 && (p1 || (z1 == page->n[a]
- && page->is_edge_cutoff[a][1]));
+ p1 || (z1 == page->n[a] && page->is_edge_cutoff[a][1]);
subpage->is_edge_cutoff[b][0] = page->is_edge_cutoff[b][0];
subpage->is_edge_cutoff[b][1] = page->is_edge_cutoff[b][1];
- /* Select join crossings from PAGE into subpage. */
- int *jc = subpage->join_crossing[a];
- for (int z = 0; z < page->h[a][0]; z++)
- *jc++ = page->join_crossing[a][z];
- for (int z = z0; z <= z1; z++)
- *jc++ = page->join_crossing[a][z];
- for (int z = page->n[a] - page->h[a][1]; z < page->n[a]; z++)
- *jc++ = page->join_crossing[a][z];
- assert (jc == &subpage->join_crossing[a][subpage->n[a] + 1]);
-
- memcpy (subpage->join_crossing[b], page->join_crossing[b],
- (subpage->n[b] + 1) * sizeof **subpage->join_crossing);
-
/* Select widths from PAGE into subpage. */
int *scp = page->cp[a];
int *dcp = subpage->cp[a];
*dcp = 0;
- for (int z = 0; z <= rule_ofs (subpage->h[a][0]); z++, dcp++)
+ for (int z = 0; z <= rule_ofs (subpage->h[a]); z++, dcp++)
{
int w = !z && subpage->is_edge_cutoff[a][0] ? 0 : scp[z + 1] - scp[z];
dcp[1] = dcp[0] + w;
{
dcp[1] = dcp[0] + (scp[z + 1] - scp[z]);
if (z == cell_ofs (z0))
- {
- dcp[1] -= p0;
- if (page->h[a][0] && page->h[a][1])
- dcp[1] += page->join_crossing[a][z / 2];
- }
+ dcp[1] -= p0;
if (z == cell_ofs (z1 - 1))
dcp[1] -= p1;
}
- for (int z = rule_ofs_r (page, a, subpage->h[a][1]);
+ for (int z = rule_ofs_r (page, a, 0);
z <= rule_ofs_r (page, a, 0); z++, dcp++)
{
if (z == rule_ofs_r (page, a, 0) && subpage->is_edge_cutoff[a][1])
.subpage = subpage,
};
- if (!page->h[a][0] || z0 > page->h[a][0] || p0)
+ if (!page->h[a] || z0 > page->h[a] || p0)
for (int z = 0; z < page->n[b];)
{
int d[TABLE_N_AXES];
struct render_overflow *ro = insert_overflow (&s, &cell);
if (overflow0)
- {
- ro->overflow[a][0] += p0 + axis_width (
- page, a, cell_ofs (cell.d[a][0]), cell_ofs (z0));
- if (page->h[a][0] && page->h[a][1])
- ro->overflow[a][0] -= page->join_crossing[a][cell.d[a][0]
- + 1];
- }
+ ro->overflow[a][0] += p0 + axis_width (
+ page, a, cell_ofs (cell.d[a][0]), cell_ofs (z0));
if (overflow1)
- {
- ro->overflow[a][1] += p1 + axis_width (
- page, a, cell_ofs (z1), cell_ofs (cell.d[a][1]));
- if (page->h[a][0] && page->h[a][1])
- ro->overflow[a][1] -= page->join_crossing[a][cell.d[a][1]];
- }
+ ro->overflow[a][1] += p1 + axis_width (
+ page, a, cell_ofs (z1), cell_ofs (cell.d[a][1]));
}
z = cell.d[b][1];
}
- if (!page->h[a][1] || z1 < page->n[a] - page->h[a][1] || p1)
- for (int z = 0; z < page->n[b];)
- {
- int d[TABLE_N_AXES];
- d[a] = z1 - 1;
- d[b] = z;
+ for (int z = 0; z < page->n[b];)
+ {
+ int d[TABLE_N_AXES];
+ d[a] = z1 - 1;
+ d[b] = z;
- struct table_cell cell;
- render_get_cell (page, d[H], d[V], &cell);
- if ((cell.d[a][1] > z1 || (cell.d[a][1] == z1 && p1))
- && find_overflow_for_cell (&s, &cell) == NULL)
- {
- struct render_overflow *ro = insert_overflow (&s, &cell);
- ro->overflow[a][1] += p1 + axis_width (page, a, cell_ofs (z1),
- cell_ofs (cell.d[a][1]));
- }
- z = cell.d[b][1];
- }
+ struct table_cell cell;
+ render_get_cell (page, d[H], d[V], &cell);
+ if ((cell.d[a][1] > z1 || (cell.d[a][1] == z1 && p1))
+ && find_overflow_for_cell (&s, &cell) == NULL)
+ {
+ struct render_overflow *ro = insert_overflow (&s, &cell);
+ ro->overflow[a][1] += p1 + axis_width (page, a, cell_ofs (z1),
+ cell_ofs (cell.d[a][1]));
+ }
+ z = cell.d[b][1];
+ }
/* Copy overflows from PAGE into subpage. */
struct render_overflow *ro;
{
enum table_axis a = s->a;
enum table_axis b = s->b;
- int ha0 = s->subpage->h[a][0];
+ int ha0 = s->subpage->h[a];
subcell[a] = MAX (cell->d[a][0] - s->z0 + ha0, ha0);
subcell[b] = cell->d[b][0];