1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2009, 2010, 2011, 2013, 2014, 2016 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
25 #include "libpspp/assertion.h"
26 #include "libpspp/hash-functions.h"
27 #include "libpspp/hmap.h"
28 #include "libpspp/pool.h"
29 #include "output/pivot-output.h"
30 #include "output/pivot-table.h"
31 #include "output/render.h"
32 #include "output/table.h"
34 #include "gl/minmax.h"
35 #include "gl/xalloc.h"
38 #define _(msgid) gettext (msgid)
40 /* This file uses TABLE_HORZ and TABLE_VERT enough to warrant abbreviating. */
44 /* Maps a contiguous range of cells from a page to the underlying table along
45 the horizontal or vertical dimension. */
48 int p[2]; /* Range of ordinates in the page. */
49 int t[2]; /* Range of ordinates in the table. */
50 int ofs; /* p[0] - t[0]. */
51 int n; /* p[1] - p[0] == t[1] - t[0]. */
54 /* A layout for rendering a specific table on a specific device.
56 May represent the layout of an entire table presented to
57 render_page_create(), or a rectangular subregion of a table broken out using
58 render_break_next() to allow a table to be broken across multiple pages.
60 A page's size is not limited to the size passed in as part of render_params.
61 render_pager breaks a render_page into smaller render_pages that will fit in
62 the available space. */
65 const struct render_params *params; /* Parameters of the target device. */
66 struct table *table; /* Table rendered. */
69 /* Region of 'table' to render.
71 The horizontal cells rendered are the leftmost h[H][0], then
72 r[H][0] through r[H][1], exclusive, then the rightmost h[H][1].
74 The vertical cells rendered are the topmost h[V][0], then r[V][0]
75 through r[V][1], exclusive, then the bottommost h[V][1].
77 n[H] = h[H][0] + (r[H][1] - r[H][0]) + h[H][1]
78 n[V] = h[V][0] + (r[V][1] - r[V][0]) + h[V][1]
81 int h[TABLE_N_AXES][2];
82 int r[TABLE_N_AXES][2];
84 struct map maps[TABLE_N_AXES][3];
88 cp[H] represents x positions within the table.
90 cp[H][1] = the width of the leftmost vertical rule.
91 cp[H][2] = cp[H][1] + the width of the leftmost column.
92 cp[H][3] = cp[H][2] + the width of the second-from-left vertical rule.
94 cp[H][2 * n[H]] = x position of the rightmost vertical rule.
95 cp[H][2 * n[H] + 1] = total table width including all rules.
97 Similarly, cp[V] represents y positions within the table.
99 cp[V][1] = the height of the topmost horizontal rule.
100 cp[V][2] = cp[V][1] + the height of the topmost row.
101 cp[V][3] = cp[V][2] + the height of the second-from-top horizontal rule.
103 cp[V][2 * n[V]] = y position of the bottommost horizontal rule.
104 cp[V][2 * n[V] + 1] = total table height including all rules.
106 Rules and columns can have width or height 0, in which case consecutive
107 values in this array are equal. */
108 int *cp[TABLE_N_AXES];
110 /* render_break_next() can break a table such that some cells are not fully
111 contained within a render_page. This will happen if a cell is too wide
112 or two tall to fit on a single page, or if a cell spans multiple rows or
113 columns and the page only includes some of those rows or columns.
115 This hash table contains "struct render_overflow"s that represents each
116 such cell that doesn't completely fit on this page.
118 Each overflow cell borders at least one header edge of the table and may
119 border more. (A single table cell that is so large that it fills the
120 entire page can overflow on all four sides!) */
121 struct hmap overflows;
123 /* If a single column (or row) is too wide (or tall) to fit on a page
124 reasonably, then render_break_next() will split a single row or column
125 across multiple render_pages. This member indicates when this has
128 is_edge_cutoff[H][0] is true if pixels have been cut off the left side
129 of the leftmost column in this page, and false otherwise.
131 is_edge_cutoff[H][1] is true if pixels have been cut off the right side
132 of the rightmost column in this page, and false otherwise.
134 is_edge_cutoff[V][0] and is_edge_cutoff[V][1] are similar for the top
135 and bottom of the table.
137 The effect of is_edge_cutoff is to prevent rules along the edge in
138 question from being rendered.
140 When is_edge_cutoff is true for a given edge, the 'overflows' hmap will
141 contain a node for each cell along that edge. */
142 bool is_edge_cutoff[TABLE_N_AXES][2];
144 /* If part of a joined cell would be cut off by breaking a table along
145 'axis' at the rule with offset 'z' (where 0 <= z <= n[axis]), then
146 join_crossing[axis][z] is the thickness of the rule that would be cut
149 This is used to know to allocate extra space for breaking at such a
150 position, so that part of the cell's content is not lost.
152 This affects breaking a table only when headers are present. When
153 headers are not present, the rule's thickness is used for cell content,
154 so no part of the cell's content is lost (and in fact it is duplicated
155 across both pages). */
156 int *join_crossing[TABLE_N_AXES];
159 static struct render_page *render_page_create (const struct render_params *,
160 struct table *, int min_width);
162 struct render_page *render_page_ref (const struct render_page *page_);
163 static void render_page_unref (struct render_page *);
165 /* Returns the offset in struct render_page's cp[axis] array of the rule with
166 index RULE_IDX. That is, if RULE_IDX is 0, then the offset is that of the
167 leftmost or topmost rule; if RULE_IDX is 1, then the offset is that of the
168 next rule to the right (or below); and so on. */
170 rule_ofs (int rule_idx)
175 /* Returns the offset in struct render_page's cp[axis] array of the rule with
176 index RULE_IDX_R, which counts from the right side (or bottom) of the page
177 left (or up), according to whether AXIS is H or V, respectively. That is,
178 if RULE_IDX_R is 0, then the offset is that of the rightmost or bottommost
179 rule; if RULE_IDX is 1, then the offset is that of the next rule to the left
180 (or above); and so on. */
182 rule_ofs_r (const struct render_page *page, int axis, int rule_idx_r)
184 return (page->n[axis] - rule_idx_r) * 2;
187 /* Returns the offset in struct render_page's cp[axis] array of the cell with
188 index CELL_IDX. That is, if CELL_IDX is 0, then the offset is that of the
189 leftmost or topmost cell; if CELL_IDX is 1, then the offset is that of the
190 next cell to the right (or below); and so on. */
192 cell_ofs (int cell_idx)
194 return cell_idx * 2 + 1;
197 /* Returns the width of PAGE along AXIS from OFS0 to OFS1, exclusive. */
199 axis_width (const struct render_page *page, int axis, int ofs0, int ofs1)
201 return page->cp[axis][ofs1] - page->cp[axis][ofs0];
204 /* Returns the total width of PAGE along AXIS. */
206 table_width (const struct render_page *page, int axis)
208 return page->cp[axis][2 * page->n[axis] + 1];
211 /* Returns the width of the headers in PAGE along AXIS. */
213 headers_width (const struct render_page *page, int axis)
215 int h0 = page->h[axis][0];
216 int w0 = axis_width (page, axis, rule_ofs (0), cell_ofs (h0));
217 int n = page->n[axis];
218 int h1 = page->h[axis][1];
219 int w1 = axis_width (page, axis, rule_ofs_r (page, axis, h1), cell_ofs (n));
223 /* Returns the width of cell X along AXIS in PAGE. */
225 cell_width (const struct render_page *page, int axis, int x)
227 return axis_width (page, axis, cell_ofs (x), cell_ofs (x) + 1);
230 /* Returns the width of rule X along AXIS in PAGE. */
232 rule_width (const struct render_page *page, int axis, int x)
234 return axis_width (page, axis, rule_ofs (x), rule_ofs (x) + 1);
237 /* Returns the width of rule X along AXIS in PAGE. */
239 rule_width_r (const struct render_page *page, int axis, int x)
241 int ofs = rule_ofs_r (page, axis, x);
242 return axis_width (page, axis, ofs, ofs + 1);
245 /* Returns the width of cells X0 through X1, exclusive, along AXIS in PAGE. */
247 joined_width (const struct render_page *page, int axis, int x0, int x1)
249 return axis_width (page, axis, cell_ofs (x0), cell_ofs (x1) - 1);
252 /* Returns the width of the widest cell, excluding headers, along AXIS in
255 max_cell_width (const struct render_page *page, int axis)
257 int n = page->n[axis];
258 int x0 = page->h[axis][0];
259 int x1 = n - page->h[axis][1];
262 for (int x = x0; x < x1; x++)
264 int w = cell_width (page, axis, x);
271 /* A cell that doesn't completely fit on the render_page. */
272 struct render_overflow
274 struct hmap_node node; /* In render_page's 'overflows' hmap. */
276 /* Occupied region of page.
278 d[H][0] is the leftmost column.
279 d[H][1] is the rightmost column, plus 1.
280 d[V][0] is the top row.
281 d[V][1] is the bottom row, plus 1.
283 The cell in its original table might occupy a larger region. This
284 member reflects the size of the cell in the current render_page, after
285 trimming off any rows or columns due to page-breaking. */
288 /* The space that has been trimmed off the cell:
290 overflow[H][0]: space trimmed off its left side.
291 overflow[H][1]: space trimmed off its right side.
292 overflow[V][0]: space trimmed off its top.
293 overflow[V][1]: space trimmed off its bottom.
295 During rendering, this information is used to position the rendered
296 portion of the cell within the available space.
298 When a cell is rendered, sometimes it is permitted to spill over into
299 space that is ordinarily reserved for rules. Either way, this space is
300 still included in overflow values.
302 Suppose, for example, that a cell that joins 2 columns has a width of 60
303 pixels and content "abcdef", that the 2 columns that it joins have
304 widths of 20 and 30 pixels, respectively, and that therefore the rule
305 between the two joined columns has a width of 10 (20 + 10 + 30 = 60).
306 It might render like this, if each character is 10x10, and showing a few
307 extra table cells for context:
315 If this render_page is broken at the rule that separates "gh" from
316 "ijk", then the page that contains the left side of the "abcdef" cell
317 will have overflow[H][1] of 10 + 30 = 40 for its portion of the cell,
318 and the page that contains the right side of the cell will have
319 overflow[H][0] of 20 + 10 = 30. The two resulting pages would look like
337 int overflow[TABLE_N_AXES][2];
340 /* Returns a hash value for (,Y). */
342 hash_cell (int x, int y)
344 return hash_int (x + (y << 16), 0);
347 /* Searches PAGE's set of render_overflow for one whose top-left cell is
348 (X,Y). Returns it, if there is one, otherwise a null pointer. */
349 static const struct render_overflow *
350 find_overflow (const struct render_page *page, int x, int y)
352 if (!hmap_is_empty (&page->overflows))
354 const struct render_overflow *of;
356 HMAP_FOR_EACH_WITH_HASH (of, struct render_overflow, node,
357 hash_cell (x, y), &page->overflows)
358 if (x == of->d[H] && y == of->d[V])
365 /* Row or column dimensions. Used to figure the size of a table in
366 render_page_create() and discarded after that. */
369 /* Width without considering rows (or columns) that span more than one (or
373 /* Width taking spanned rows (or columns) into consideration. */
377 /* Modifies the 'width' members of the N elements of ROWS so that their sum,
378 when added to rule widths RULES[1] through RULES[N - 1] inclusive, is at
381 distribute_spanned_width (int width,
382 struct render_row *rows, const int *rules, int n)
384 /* Sum up the unspanned widths of the N rows for use as weights. */
385 int total_unspanned = 0;
386 for (int x = 0; x < n; x++)
387 total_unspanned += rows[x].unspanned;
388 for (int x = 0; x < n - 1; x++)
389 total_unspanned += rules[x + 1];
390 if (total_unspanned >= width)
393 /* The algorithm used here is based on the following description from HTML 4:
395 For cells that span multiple columns, a simple approach consists of
396 apportioning the min/max widths evenly to each of the constituent
397 columns. A slightly more complex approach is to use the min/max
398 widths of unspanned cells to weight how spanned widths are
399 apportioned. Experiments suggest that a blend of the two approaches
400 gives good results for a wide range of tables.
402 We blend the two approaches half-and-half, except that we cannot use the
403 unspanned weights when 'total_unspanned' is 0 (because that would cause a
406 The calculation we want to do is this:
409 w1 = width * (column's unspanned width) / (total unspanned width)
410 (column's width) = (w0 + w1) / 2
412 We implement it as a precise calculation in integers by multiplying w0 and
413 w1 by the common denominator of all three calculations (d), dividing that
414 out in the column width calculation, and then keeping the remainder for
417 (We actually compute the unspanned width of a column as twice the
418 unspanned width, plus the width of the rule on the left, plus the width of
419 the rule on the right. That way each rule contributes to both the cell on
420 its left and on its right.)
422 long long int d0 = n;
423 long long int d1 = 2LL * MAX (total_unspanned, 1);
424 long long int d = d0 * d1;
425 if (total_unspanned > 0)
427 long long int w = d / 2;
428 for (int x = 0; x < n; x++)
431 if (total_unspanned > 0)
433 long long int unspanned = rows[x].unspanned * 2LL;
435 unspanned += rules[x + 1];
437 unspanned += rules[x];
438 w += width * unspanned * d0;
441 rows[x].width = MAX (rows[x].width, w / d);
442 w -= rows[x].width * d;
446 /* Initializes PAGE->cp[AXIS] from the row widths in ROWS and the rule widths
449 accumulate_row_widths (const struct render_page *page, enum table_axis axis,
450 const struct render_row *rows, const int *rules)
452 int n = page->n[axis];
453 int *cp = page->cp[axis];
455 for (int z = 0; z < n; z++)
457 cp[1] = cp[0] + rules[z];
458 cp[2] = cp[1] + rows[z].width;
461 cp[1] = cp[0] + rules[n];
464 /* Returns the sum of widths of the N ROWS and N+1 RULES. */
466 calculate_table_width (int n, const struct render_row *rows, int *rules)
469 for (int x = 0; x < n; x++)
470 width += rows[x].width;
471 for (int x = 0; x <= n; x++)
477 /* Rendering utility functions. */
479 /* Returns the width of the rule in TABLE that is at offset Z along axis A, if
480 rendered with PARAMS. */
482 measure_rule (const struct render_params *params, const struct table *table,
483 enum table_axis a, int z)
485 enum table_axis b = !a;
487 /* Determine all types of rules that are present, as a bitmap in 'rules'
488 where rule type 't' is present if bit 2**t is set. */
489 unsigned int rules = 0;
492 for (d[b] = 0; d[b] < table->n[b]; d[b]++)
493 rules |= 1u << table_get_rule (table, a, d[H], d[V]).stroke;
495 /* Turn off TABLE_STROKE_NONE because it has width 0 and we needn't bother.
496 However, if the device doesn't support margins, make sure that there is at
497 least a small gap between cells (but we don't need any at the left or
498 right edge of the table). */
499 if (rules & (1u << TABLE_STROKE_NONE))
501 rules &= ~(1u << TABLE_STROKE_NONE);
502 if (z > 0 && z < table->n[a] && !params->supports_margins && a == H)
503 rules |= 1u << TABLE_STROKE_SOLID;
506 /* Calculate maximum width of the rules that are present. */
508 for (size_t i = 0; i < TABLE_N_STROKES; i++)
509 if (rules & (1u << i))
510 width = MAX (width, params->line_widths[i]);
515 make_map (int p0, int t0, int n)
517 return (struct map) {
525 /* Allocates and returns a new render_page using PARAMS and TABLE. Allocates
526 space for rendering a table with dimensions given in N, headers in H, and
527 content in R. The caller must initialize most of the members itself. */
528 static struct render_page *
529 render_page_allocate__ (const struct render_params *params,
531 const int n[TABLE_N_AXES],
532 const int h[TABLE_N_AXES][2],
533 const int r[TABLE_N_AXES][2])
535 struct render_page *page = xmalloc (sizeof *page);
536 *page = (struct render_page) {
540 .n = { [H] = n[H], [V] = n[V] },
541 .h = { [H] = { h[H][0], h[H][1] }, [V] = { h[V][0], h[V][1] } },
542 .r = { [H] = { r[H][0], r[H][1] }, [V] = { r[V][0], r[V][1] } },
543 .cp = { [H] = xcalloc (2 * n[H] + 2, sizeof *page->cp[H]),
544 [V] = xcalloc (2 * n[V] + 2, sizeof *page->cp[V]) },
546 [H] = xcalloc (n[H] + 1, sizeof *page->join_crossing[H]),
547 [V] = xcalloc (n[V] + 1, sizeof *page->join_crossing[V])
549 .overflows = HMAP_INITIALIZER (page->overflows),
552 for (enum table_axis a = 0; a < TABLE_N_AXES; a++)
554 struct map *m = page->maps[a];
556 *m++ = make_map (0, 0, page->h[a][0]);
557 *m++ = make_map (h[a][0], r[a][0], r[a][1] - r[a][0]);
559 *m++ = make_map (n[a] - h[a][1], table->n[a] - table->h[a][1], h[a][1]);
564 /* Allocates and returns a new render_page using PARAMS and TABLE. Allocates
565 space for all of the members of the new page, but the caller must initialize
566 the 'cp' member itself. */
567 static struct render_page *
568 render_page_allocate (const struct render_params *params, struct table *table)
570 int h[TABLE_N_AXES][2];
571 int r[TABLE_N_AXES][2];
572 for (enum table_axis a = 0; a < TABLE_N_AXES; a++)
574 h[a][0] = table->h[a][0];
575 h[a][1] = table->h[a][1];
576 r[a][0] = table->h[a][0];
577 r[a][1] = table->n[a] - table->h[a][1];
579 return render_page_allocate__ (params, table, table->n, h, r);
582 /* Allocates and returns a new render_page for PARAMS and TABLE, initializing
583 cp[H] in the new page from ROWS and RULES. The caller must still initialize
585 static struct render_page *
586 create_page_with_exact_widths (const struct render_params *params,
588 const struct render_row *rows, int *rules)
590 struct render_page *page = render_page_allocate (params, table);
591 accumulate_row_widths (page, H, rows, rules);
595 /* Allocates and returns a new render_page for PARAMS and TABLE.
597 Initializes cp[H] in the new page by setting the width of each row 'i' to
598 somewhere between the minimum cell width ROW_MIN[i].width and the maximum
599 ROW_MAX[i].width. Sets the width of rules to those in RULES.
601 W_MIN is the sum of ROWS_MIN[].width.
603 W_MAX is the sum of ROWS_MAX[].width.
605 The caller must still initialize cp[V]. */
606 static struct render_page *
607 create_page_with_interpolated_widths (const struct render_params *params,
609 const struct render_row *rows_min,
610 const struct render_row *rows_max,
611 int w_min, int w_max, const int *rules)
613 const int n = table->n[H];
614 const long long int avail = params->size[H] - w_min;
615 const long long int wanted = w_max - w_min;
619 struct render_page *page = render_page_allocate (params, table);
621 int *cph = page->cp[H];
623 long long int w = wanted / 2;
624 for (int x = 0; x < n; x++)
626 w += avail * (rows_max[x].width - rows_min[x].width);
627 int extra = w / wanted;
630 cph[1] = cph[0] + rules[x];
631 cph[2] = cph[1] + rows_min[x].width + extra;
634 cph[1] = cph[0] + rules[n];
636 assert (page->cp[H][n * 2 + 1] == params->size[H]);
641 set_join_crossings (struct render_page *page, enum table_axis axis,
642 const struct table_cell *cell, int *rules)
644 for (int z = cell->d[axis][0] + 1; z <= cell->d[axis][1] - 1; z++)
645 page->join_crossing[axis][z] = rules[z];
648 /* Returns a mapping from page to table ordinates along axis A that includes
649 ordinate Z (in PAGE). */
650 static const struct map *
651 get_map (const struct render_page *page, enum table_axis a, int z)
653 for (size_t i = 0; i < 3; i++)
655 const struct map *m = &page->maps[a][i];
658 assert (z >= m->p[0]);
665 /* Initializes CELL with the contents of the table cell at column X and row Y
666 within PAGE. When CELL is no longer needed, the caller is responsible for
667 freeing it by calling table_cell_free(CELL).
669 The caller must ensure that CELL is destroyed before TABLE is unref'ed.
671 This is equivalent to table_get_cell(), except X and Y are in terms of the
672 page's rows and columns rather than the underlying table's. */
674 render_get_cell (const struct render_page *page, int x, int y,
675 struct table_cell *cell)
677 const struct map *map[TABLE_N_AXES] = {
678 [H] = get_map (page, H, x),
679 [V] = get_map (page, V, y),
682 /* Get CELL, translating X and Y into table coordinates. CELL is also
683 returned in table coordinates. */
684 table_get_cell (page->table, x + map[H]->ofs, y + map[V]->ofs, cell);
686 /* Translate CELL into page coordinates. */
687 for (enum table_axis a = 0; a < TABLE_N_AXES; a++)
689 const struct map *m = map[a];
692 if (a == H && cell->options & TABLE_CELL_FULL_WIDTH)
694 printf ("special case\n");
695 cell->d[a][0] -= m->ofs;
696 cell->d[a][1] -= get_map (page, H, cell->d[a][1] - 1)->ofs;
701 for (int i = 0; i < 2; i++)
702 cell->d[a][i] -= m->ofs;
703 cell->d[a][0] = MAX (cell->d[a][0], m->p[0]);
704 cell->d[a][1] = MIN (cell->d[a][1], m->p[1]);
709 /* Creates and returns a new render_page for rendering TABLE on a device
712 The new render_page will be suitable for rendering on a device whose page
713 size is PARAMS->size, but the caller is responsible for actually breaking it
714 up to fit on such a device, using the render_break abstraction. */
715 static struct render_page *
716 render_page_create (const struct render_params *params, struct table *table,
721 int nc = table->n[H];
722 int nr = table->n[V];
724 /* Figure out rule widths. */
725 int *rules[TABLE_N_AXES];
726 for (enum table_axis axis = 0; axis < TABLE_N_AXES; axis++)
728 int n = table->n[axis] + 1;
730 rules[axis] = xnmalloc (n, sizeof *rules);
731 for (int z = 0; z < n; z++)
732 rules[axis][z] = measure_rule (params, table, axis, z);
735 /* Calculate minimum and maximum widths of cells that do not
736 span multiple columns. */
737 struct render_row *columns[2];
738 for (int i = 0; i < 2; i++)
739 columns[i] = xcalloc (nc, sizeof *columns[i]);
740 for (int y = 0; y < nr; y++)
741 for (int x = 0; x < nc;)
743 struct table_cell cell;
745 table_get_cell (table, x, y, &cell);
746 if (y == cell.d[V][0])
748 if (table_cell_colspan (&cell) == 1)
751 params->ops->measure_cell_width (params->aux, &cell,
753 for (int i = 0; i < 2; i++)
754 if (columns[i][x].unspanned < w[i])
755 columns[i][x].unspanned = w[i];
761 /* Distribute widths of spanned columns. */
762 for (int i = 0; i < 2; i++)
763 for (int x = 0; x < nc; x++)
764 columns[i][x].width = columns[i][x].unspanned;
765 for (int y = 0; y < nr; y++)
766 for (int x = 0; x < nc;)
768 struct table_cell cell;
770 table_get_cell (table, x, y, &cell);
771 if (y == cell.d[V][0] && table_cell_colspan (&cell) > 1)
775 params->ops->measure_cell_width (params->aux, &cell,
777 for (int i = 0; i < 2; i++)
778 distribute_spanned_width (w[i], &columns[i][cell.d[H][0]],
779 rules[H], table_cell_colspan (&cell));
784 for (int i = 0; i < 2; i++)
785 distribute_spanned_width (min_width, &columns[i][0], rules[H], nc);
787 /* In pathological cases, spans can cause the minimum width of a column to
788 exceed the maximum width. This bollixes our interpolation algorithm
789 later, so fix it up. */
790 for (int i = 0; i < nc; i++)
791 if (columns[MIN][i].width > columns[MAX][i].width)
792 columns[MAX][i].width = columns[MIN][i].width;
794 /* Decide final column widths. */
796 for (int i = 0; i < 2; i++)
797 table_widths[i] = calculate_table_width (table->n[H],
798 columns[i], rules[H]);
800 struct render_page *page;
801 if (table_widths[MAX] <= params->size[H])
803 /* Fits even with maximum widths. Use them. */
804 page = create_page_with_exact_widths (params, table, columns[MAX],
806 //page->h[H][0] = page->h[H][1] = 0;
808 else if (table_widths[MIN] <= params->size[H])
810 /* Fits with minimum widths, so distribute the leftover space. */
811 page = create_page_with_interpolated_widths (
812 params, table, columns[MIN], columns[MAX],
813 table_widths[MIN], table_widths[MAX], rules[H]);
814 //page->h[H][0] = page->h[H][1] = 0;
818 /* Doesn't fit even with minimum widths. Assign minimums for now, and
819 later we can break it horizontally into multiple pages. */
820 page = create_page_with_exact_widths (params, table, columns[MIN],
824 /* Calculate heights of cells that do not span multiple rows. */
825 struct render_row *rows = XCALLOC (nr, struct render_row);
826 for (int y = 0; y < nr; y++)
827 for (int x = 0; x < nc;)
829 struct render_row *r = &rows[y];
830 struct table_cell cell;
832 render_get_cell (page, x, y, &cell);
833 if (y == cell.d[V][0])
835 if (table_cell_rowspan (&cell) == 1)
837 int w = joined_width (page, H, cell.d[H][0], cell.d[H][1]);
838 int h = params->ops->measure_cell_height (params->aux,
840 if (h > r->unspanned)
841 r->unspanned = r->width = h;
844 set_join_crossings (page, V, &cell, rules[V]);
846 if (table_cell_colspan (&cell) > 1)
847 set_join_crossings (page, H, &cell, rules[H]);
851 for (int i = 0; i < 2; i++)
854 /* Distribute heights of spanned rows. */
855 for (int y = 0; y < nr; y++)
856 for (int x = 0; x < nc;)
858 struct table_cell cell;
860 render_get_cell (page, x, y, &cell);
861 if (y == cell.d[V][0] && table_cell_rowspan (&cell) > 1)
863 int w = joined_width (page, H, cell.d[H][0], cell.d[H][1]);
864 int h = params->ops->measure_cell_height (params->aux, &cell, w);
865 distribute_spanned_width (h, &rows[cell.d[V][0]], rules[V],
866 table_cell_rowspan (&cell));
871 /* Decide final row heights. */
872 accumulate_row_widths (page, V, rows, rules[V]);
875 /* Measure headers. If they are "too big", get rid of them. */
876 for (enum table_axis axis = 0; axis < TABLE_N_AXES; axis++)
878 int hw = headers_width (page, axis);
879 if (hw * 2 >= page->params->size[axis]
880 || hw + max_cell_width (page, axis) > page->params->size[axis])
882 page->h[axis][0] = page->h[axis][1] = 0;
883 page->r[axis][0] = 0;
884 page->r[axis][1] = page->n[axis];
894 /* Increases PAGE's reference count. */
896 render_page_ref (const struct render_page *page_)
898 struct render_page *page = CONST_CAST (struct render_page *, page_);
903 /* Decreases PAGE's reference count and destroys PAGE if this causes the
904 reference count to fall to zero. */
906 render_page_unref (struct render_page *page)
908 if (page != NULL && --page->ref_cnt == 0)
910 struct render_overflow *overflow, *next;
911 HMAP_FOR_EACH_SAFE (overflow, next, struct render_overflow, node,
914 hmap_destroy (&page->overflows);
916 table_unref (page->table);
918 for (int i = 0; i < TABLE_N_AXES; ++i)
920 free (page->join_crossing[i]);
928 /* Returns the size of PAGE along AXIS. (This might be larger than the page
929 size specified in the parameters passed to render_page_create(). Use a
930 render_break to break up a render_page into page-sized chunks.) */
932 render_page_get_size (const struct render_page *page, enum table_axis axis)
934 return page->cp[axis][page->n[axis] * 2 + 1];
938 render_page_get_best_breakpoint (const struct render_page *page, int height)
940 /* If there's no room for at least the top row and the rules above and below
941 it, don't include any of the table. */
942 if (page->cp[V][3] > height)
945 /* Otherwise include as many rows and rules as we can. */
946 for (int y = 5; y <= 2 * page->n[V] + 1; y += 2)
947 if (page->cp[V][y] > height)
948 return page->cp[V][y - 2];
952 /* Drawing render_pages. */
954 /* This is like table_get_rule() except that D is in terms of the page's rows
955 and column rather than the underlying table's. */
956 static struct table_border_style
957 get_rule (const struct render_page *page, enum table_axis axis,
958 const int d_[TABLE_N_AXES])
960 int d[TABLE_N_AXES] = { d_[0] / 2, d_[1] / 2 };
963 enum table_axis a = axis;
964 if (d[a] < page->h[a][0])
966 else if (d[a] <= page->n[a] - page->h[a][1])
968 if (page->h[a][0] && d[a] == page->h[a][0])
970 else if (page->h[a][1] && d[a] == page->n[a] - page->h[a][1])
971 d2 = page->table->n[a] - page->h[a][1];
972 d[a] += page->r[a][0] - page->h[a][0];
975 d[a] += ((page->table->n[a] - page->table->h[a][1])
976 - (page->n[a] - page->h[a][1]));
978 enum table_axis b = !axis;
979 d[b] += get_map (page, b, d[b])->ofs;
981 struct table_border_style border
982 = table_get_rule (page->table, axis, d[H], d[V]);
986 struct table_border_style border2 = table_get_rule (page->table, axis,
988 border.stroke = table_stroke_combine (border.stroke, border2.stroke);
1000 render_direction_rtl (void)
1002 /* TRANSLATORS: Do not translate this string. If the script of your language
1003 reads from right to left (eg Persian, Arabic, Hebrew etc), then replace
1004 this string with "output-direction-rtl". Otherwise either leave it
1005 untranslated or copy it verbatim. */
1006 const char *dir = _("output-direction-ltr");
1007 if (0 == strcmp ("output-direction-rtl", dir))
1010 if (0 != strcmp ("output-direction-ltr", dir))
1011 fprintf (stderr, "This localisation has been incorrectly translated. "
1012 "Complain to the translator.\n");
1018 render_rule (const struct render_page *page, const int ofs[TABLE_N_AXES],
1019 const int d[TABLE_N_AXES])
1021 const struct table_border_style none = { .stroke = TABLE_STROKE_NONE };
1022 struct table_border_style styles[TABLE_N_AXES][2];
1024 for (enum table_axis a = 0; a < TABLE_N_AXES; a++)
1026 enum table_axis b = !a;
1029 || (page->is_edge_cutoff[a][0] && d[a] == 0)
1030 || (page->is_edge_cutoff[a][1] && d[a] == page->n[a] * 2))
1031 styles[a][0] = styles[a][1] = none;
1032 else if (is_rule (d[b]))
1036 int e[TABLE_N_AXES];
1040 styles[a][0] = get_rule (page, a, e);
1043 styles[a][0] = none;
1045 if (d[b] / 2 < page->n[b])
1046 styles[a][1] = get_rule (page, a, d);
1048 styles[a][1] = none;
1051 styles[a][0] = styles[a][1] = get_rule (page, a, d);
1054 if (styles[H][0].stroke != TABLE_STROKE_NONE
1055 || styles[H][1].stroke != TABLE_STROKE_NONE
1056 || styles[V][0].stroke != TABLE_STROKE_NONE
1057 || styles[V][1].stroke != TABLE_STROKE_NONE)
1059 int bb[TABLE_N_AXES][2];
1061 bb[H][0] = ofs[H] + page->cp[H][d[H]];
1062 bb[H][1] = ofs[H] + page->cp[H][d[H] + 1];
1063 if (page->params->rtl)
1065 int temp = bb[H][0];
1066 bb[H][0] = render_page_get_size (page, H) - bb[H][1];
1067 bb[H][1] = render_page_get_size (page, H) - temp;
1069 bb[V][0] = ofs[V] + page->cp[V][d[V]];
1070 bb[V][1] = ofs[V] + page->cp[V][d[V] + 1];
1071 page->params->ops->draw_line (page->params->aux, bb, styles);
1076 render_cell (const struct render_page *page, const int ofs[TABLE_N_AXES],
1077 const struct table_cell *cell)
1079 int bb[TABLE_N_AXES][2];
1080 int clip[TABLE_N_AXES][2];
1082 bb[H][0] = clip[H][0] = ofs[H] + page->cp[H][cell->d[H][0] * 2 + 1];
1083 bb[H][1] = clip[H][1] = ofs[H] + page->cp[H][cell->d[H][1] * 2];
1084 if (page->params->rtl)
1086 int temp = bb[H][0];
1087 bb[H][0] = clip[H][0] = render_page_get_size (page, H) - bb[H][1];
1088 bb[H][1] = clip[H][1] = render_page_get_size (page, H) - temp;
1090 bb[V][0] = clip[V][0] = ofs[V] + page->cp[V][cell->d[V][0] * 2 + 1];
1091 bb[V][1] = clip[V][1] = ofs[V] + page->cp[V][cell->d[V][1] * 2];
1093 enum table_valign valign = cell->cell_style->valign;
1094 int valign_offset = 0;
1095 if (valign != TABLE_VALIGN_TOP)
1097 int height = page->params->ops->measure_cell_height (
1098 page->params->aux, cell, bb[H][1] - bb[H][0]);
1099 int extra = bb[V][1] - bb[V][0] - height;
1102 if (valign == TABLE_VALIGN_CENTER)
1104 valign_offset += extra;
1108 const struct render_overflow *of = find_overflow (
1109 page, cell->d[H][0], cell->d[V][0]);
1111 for (enum table_axis axis = 0; axis < TABLE_N_AXES; axis++)
1113 if (of->overflow[axis][0])
1115 bb[axis][0] -= of->overflow[axis][0];
1116 if (cell->d[axis][0] == 0 && !page->is_edge_cutoff[axis][0])
1117 clip[axis][0] = ofs[axis] + page->cp[axis][cell->d[axis][0] * 2];
1119 if (of->overflow[axis][1])
1121 bb[axis][1] += of->overflow[axis][1];
1122 if (cell->d[axis][1] == page->n[axis]
1123 && !page->is_edge_cutoff[axis][1])
1124 clip[axis][1] = ofs[axis] + page->cp[axis][cell->d[axis][1] * 2
1129 int spill[TABLE_N_AXES][2];
1130 for (enum table_axis axis = 0; axis < TABLE_N_AXES; axis++)
1132 spill[axis][0] = rule_width (page, axis, cell->d[axis][0]) / 2;
1133 spill[axis][1] = rule_width (page, axis, cell->d[axis][1]) / 2;
1136 int color_idx = (cell->d[V][0] < page->h[V][0]
1137 || page->n[V] - (cell->d[V][0] + 1) < page->h[V][1]
1139 : (cell->d[V][0] - page->h[V][0]) & 1);
1140 page->params->ops->draw_cell (page->params->aux, cell, color_idx,
1141 bb, valign_offset, spill, clip);
1144 /* Draws the cells of PAGE indicated in BB. */
1146 render_page_draw_cells (const struct render_page *page,
1147 int ofs[TABLE_N_AXES], int bb[TABLE_N_AXES][2])
1149 /* OK, the problem is the headers.... the left-side headers shouldn't apply
1150 to the title and caption and so on */
1151 printf ("render page %d,%d - %d,%d\n",
1153 bb[H][1], bb[V][1]);
1154 for (int y = bb[V][0]; y < bb[V][1]; y++)
1156 for (int x = bb[H][0]; x < bb[H][1]; x++)
1159 struct table_cell cell;
1161 render_get_cell (page, x / 2, y / 2, &cell);
1162 char *s = pivot_value_to_string (cell.value, NULL);
1163 printf ("%d,%d - %d,%d: %s\n",
1164 cell.d[H][0], cell.d[V][0],
1165 cell.d[H][1], cell.d[V][1],
1170 for (int y = bb[V][0]; y < bb[V][1]; y++)
1173 for (int x = bb[H][0]; x < bb[H][1];)
1176 struct table_cell cell;
1178 render_get_cell (page, x / 2, y / 2, &cell);
1179 if (y / 2 == bb[V][0] / 2 || y / 2 == cell.d[V][0])
1181 if (cell.d[H][1] - cell.d[H][0] != 1 ||
1182 cell.d[V][1] - cell.d[V][0] != 1)
1184 char *s = pivot_value_to_string (cell.value, NULL);
1185 printf ("rendering %d,%d - %d,%d (%s)\n",
1186 cell.d[H][0], cell.d[V][0],
1187 cell.d[H][1], cell.d[V][1],
1191 render_cell (page, ofs, &cell);
1193 x = rule_ofs (cell.d[H][1]);
1199 for (int y = bb[V][0]; y < bb[V][1]; y++)
1200 for (int x = bb[H][0]; x < bb[H][1]; x++)
1201 if (is_rule (x) || is_rule (y))
1203 int d[TABLE_N_AXES];
1206 render_rule (page, ofs, d);
1210 /* Renders PAGE, by calling the 'draw_line' and 'draw_cell' functions from the
1211 render_params provided to render_page_create(). */
1213 render_page_draw (const struct render_page *page, int ofs[TABLE_N_AXES])
1215 int bb[TABLE_N_AXES][2];
1218 bb[H][1] = page->n[H] * 2 + 1;
1220 bb[V][1] = page->n[V] * 2 + 1;
1222 render_page_draw_cells (page, ofs, bb);
1225 /* Returns the greatest value i, 0 <= i < n, such that cp[i] <= x0. */
1227 get_clip_min_extent (int x0, const int cp[], int n)
1234 int middle = low + (high - low) / 2;
1236 if (cp[middle] <= x0)
1248 /* Returns the least value i, 0 <= i < n, such that cp[i] >= x1. */
1250 get_clip_max_extent (int x1, const int cp[], int n)
1257 int middle = low + (high - low) / 2;
1259 if (cp[middle] >= x1)
1260 best = high = middle;
1265 while (best > 0 && cp[best - 1] == cp[best])
1271 /* Renders the cells of PAGE that intersect (X,Y)-(X+W,Y+H), by calling the
1272 'draw_line' and 'draw_cell' functions from the render_params provided to
1273 render_page_create(). */
1275 render_page_draw_region (const struct render_page *page,
1276 int ofs[TABLE_N_AXES], int clip[TABLE_N_AXES][2])
1278 int bb[TABLE_N_AXES][2];
1280 bb[H][0] = get_clip_min_extent (clip[H][0], page->cp[H], page->n[H] * 2 + 1);
1281 bb[H][1] = get_clip_max_extent (clip[H][1], page->cp[H], page->n[H] * 2 + 1);
1282 bb[V][0] = get_clip_min_extent (clip[V][0], page->cp[V], page->n[V] * 2 + 1);
1283 bb[V][1] = get_clip_max_extent (clip[V][1], page->cp[V], page->n[V] * 2 + 1);
1285 render_page_draw_cells (page, ofs, bb);
1288 /* Breaking up tables to fit on a page. */
1290 /* An iterator for breaking render_pages into smaller chunks. */
1293 struct render_page *page; /* Page being broken up. */
1294 enum table_axis axis; /* Axis along which 'page' is being broken. */
1295 int z; /* Next cell along 'axis'. */
1296 int pixel; /* Pixel offset within cell 'z' (usually 0). */
1297 int hw; /* Width of headers of 'page' along 'axis'. */
1300 static int needed_size (const struct render_break *, int cell);
1301 static bool cell_is_breakable (const struct render_break *, int cell);
1302 static struct render_page *render_page_select (const struct render_page *,
1307 /* Initializes render_break B for breaking PAGE along AXIS.
1308 Takes ownership of PAGE. */
1310 render_break_init (struct render_break *b, struct render_page *page,
1311 enum table_axis axis)
1315 b->z = page->h[axis][0];
1317 b->hw = headers_width (page, axis);
1320 /* Initializes B as a render_break structure for which
1321 render_break_has_next() always returns false. */
1323 render_break_init_empty (struct render_break *b)
1326 b->axis = TABLE_HORZ;
1332 /* Frees B and unrefs the render_page that it owns. */
1334 render_break_destroy (struct render_break *b)
1338 render_page_unref (b->page);
1343 /* Returns true if B still has cells that are yet to be returned,
1344 false if all of B's page has been processed. */
1346 render_break_has_next (const struct render_break *b)
1348 const struct render_page *page = b->page;
1349 enum table_axis axis = b->axis;
1351 return page != NULL && b->z < page->n[axis] - page->h[axis][1];
1354 /* Returns a new render_page that is up to SIZE pixels wide along B's axis.
1355 Returns a null pointer if B has already been completely broken up, or if
1356 SIZE is too small to reasonably render any cells. The latter will never
1357 happen if SIZE is at least as large as the page size passed to
1358 render_page_create() along B's axis. */
1359 static struct render_page *
1360 render_break_next (struct render_break *b, int size)
1362 const struct render_page *page = b->page;
1363 enum table_axis axis = b->axis;
1364 struct render_page *subpage;
1366 if (!render_break_has_next (b))
1371 for (z = b->z; z < page->n[axis] - page->h[axis][1]; z++)
1373 int needed = needed_size (b, z + 1);
1376 if (cell_is_breakable (b, z))
1378 /* If there is no right header and we render a partial cell on
1379 the right side of the body, then we omit the rightmost rule of
1380 the body. Otherwise the rendering is deceptive because it
1381 looks like the whole cell is present instead of a partial
1384 This is similar to code for the left side in needed_size(). */
1385 int rule_allowance = (page->h[axis][1]
1387 : rule_width (page, axis, z));
1389 /* The amount that, if we added cell 'z', the rendering would
1390 overfill the allocated 'size'. */
1391 int overhang = needed - size - rule_allowance;
1393 /* The width of cell 'z'. */
1394 int cell_size = cell_width (page, axis, z);
1396 /* The amount trimmed off the left side of 'z',
1397 and the amount left to render. */
1398 int cell_ofs = z == b->z ? b->pixel : 0;
1399 int cell_left = cell_size - cell_ofs;
1401 /* A small but visible width. */
1402 int em = page->params->font_size[axis];
1404 /* If some of the cell remains to render,
1405 and there would still be some of the cell left afterward,
1406 then partially render that much of the cell. */
1407 pixel = (cell_left && cell_left > overhang
1408 ? cell_left - overhang + cell_ofs
1411 /* If there would be only a tiny amount of the cell left after
1412 rendering it partially, reduce the amount rendered slightly
1413 to make the output look a little better. */
1414 if (pixel + em > cell_size)
1415 pixel = MAX (pixel - em, 0);
1417 /* If we're breaking vertically, then consider whether the cells
1418 being broken have a better internal breakpoint than the exact
1419 number of pixels available, which might look bad e.g. because
1420 it breaks in the middle of a line of text. */
1421 if (axis == TABLE_VERT && page->params->ops->adjust_break)
1422 for (int x = 0; x < page->n[H];)
1424 struct table_cell cell;
1426 render_get_cell (page, x, z, &cell);
1427 int w = joined_width (page, H, cell.d[H][0], cell.d[H][1]);
1428 int better_pixel = page->params->ops->adjust_break (
1429 page->params->aux, &cell, w, pixel);
1432 if (better_pixel < pixel)
1434 if (better_pixel > (z == b->z ? b->pixel : 0))
1436 pixel = better_pixel;
1439 else if (better_pixel == 0 && z != b->z)
1451 if (z == b->z && !pixel)
1454 subpage = render_page_select (page, axis, b->z, b->pixel,
1456 pixel ? cell_width (page, axis, z) - pixel
1463 /* Returns the width that would be required along B's axis to render a page
1464 from B's current position up to but not including CELL. */
1466 needed_size (const struct render_break *b, int cell)
1468 const struct render_page *page = b->page;
1469 enum table_axis axis = b->axis;
1471 /* Width of left header not including its rightmost rule. */
1472 int size = axis_width (page, axis, 0, rule_ofs (page->h[axis][0]));
1474 /* If we have a pixel offset and there is no left header, then we omit the
1475 leftmost rule of the body. Otherwise the rendering is deceptive because
1476 it looks like the whole cell is present instead of a partial cell.
1478 Otherwise (if there are headers) we will be merging two rules: the
1479 rightmost rule in the header and the leftmost rule in the body. We assume
1480 that the width of a merged rule is the larger of the widths of either rule
1482 if (b->pixel == 0 || page->h[axis][0])
1483 size += MAX (rule_width (page, axis, page->h[axis][0]),
1484 rule_width (page, axis, b->z));
1486 /* Width of body, minus any pixel offset in the leftmost cell. */
1487 size += joined_width (page, axis, b->z, cell) - b->pixel;
1489 /* Width of rightmost rule in body merged with leftmost rule in headers. */
1490 size += MAX (rule_width_r (page, axis, page->h[axis][1]),
1491 rule_width (page, axis, cell));
1493 /* Width of right header not including its leftmost rule. */
1494 size += axis_width (page, axis, rule_ofs_r (page, axis, page->h[axis][1]),
1495 rule_ofs_r (page, axis, 0));
1497 /* Join crossing. */
1498 if (page->h[axis][0] && page->h[axis][1])
1499 size += page->join_crossing[axis][b->z];
1504 /* Returns true if CELL along B's axis may be broken across a page boundary.
1506 This is just a heuristic. Breaking cells across page boundaries can save
1507 space, but it looks ugly. */
1509 cell_is_breakable (const struct render_break *b, int cell)
1511 const struct render_page *page = b->page;
1512 enum table_axis axis = b->axis;
1514 return cell_width (page, axis, cell) >= page->params->min_break[axis];
1521 const struct render_params *params;
1524 struct render_page *page;
1526 struct render_break x_break;
1527 struct render_break y_break;
1531 render_pager_start_page (struct render_pager *p)
1533 render_break_init (&p->x_break, render_page_ref (p->page), H);
1534 render_break_init_empty (&p->y_break);
1537 /* Creates and returns a new render_pager for rendering PT on the device
1538 with the given PARAMS. */
1539 struct render_pager *
1540 render_pager_create (const struct render_params *params,
1541 const struct pivot_table *pt,
1542 const size_t *layer_indexes)
1545 layer_indexes = pt->current_layer;
1547 struct table *table = pivot_output_monolithic (pt, layer_indexes,
1550 /* Measure the table width and use it to determine the base scale. */
1551 struct render_page *page = render_page_create (params, table, 0);
1552 int width = table_width (page, H);
1554 if (width > params->size[H])
1556 if (pt->look->shrink_to_fit[H] && params->ops->scale)
1557 scale = params->size[H] / (double) width;
1560 struct render_break b;
1561 render_break_init (&b, render_page_ref (page), H);
1562 struct render_page *subpage
1563 = render_break_next (&b, params->size[H]);
1564 width = subpage ? subpage->cp[H][2 * subpage->n[H] + 1] : 0;
1565 render_page_unref (subpage);
1566 render_break_destroy (&b);
1570 /* Create the pager. */
1571 struct render_pager *p = xmalloc (sizeof *p);
1572 *p = (struct render_pager) { .params = params, .scale = scale, .page = page };
1574 /* If we're shrinking tables to fit the page length, then adjust the scale
1577 XXX This will sometimes shrink more than needed, because adjusting the
1578 scale factor allows for cells to be "wider", which means that sometimes
1579 they won't break across as much vertical space, thus shrinking the table
1580 vertically more than the scale would imply. Shrinking only as much as
1581 necessary would require an iterative search. */
1582 if (pt->look->shrink_to_fit[V] && params->ops->scale)
1584 double height = table_width (p->page, V);
1585 if (height * p->scale >= params->size[V])
1586 p->scale *= params->size[V] / height;
1589 render_pager_start_page (p);
1596 render_pager_destroy (struct render_pager *p)
1600 render_break_destroy (&p->x_break);
1601 render_break_destroy (&p->y_break);
1602 render_page_unref (p->page);
1607 /* Returns true if P has content remaining to render, false if rendering is
1610 render_pager_has_next (const struct render_pager *p_)
1612 struct render_pager *p = CONST_CAST (struct render_pager *, p_);
1614 while (!render_break_has_next (&p->y_break))
1616 render_break_destroy (&p->y_break);
1617 if (!render_break_has_next (&p->x_break))
1619 render_break_destroy (&p->x_break);
1620 render_break_init_empty (&p->x_break);
1621 render_break_init_empty (&p->y_break);
1626 &p->y_break, render_break_next (&p->x_break,
1627 p->params->size[H] / p->scale), V);
1632 /* Draws a chunk of content from P to fit in a space that has vertical size
1633 SPACE and the horizontal size specified in the render_params passed to
1634 render_page_create(). Returns the amount of space actually used by the
1635 rendered chunk, which will be 0 if SPACE is too small to render anything or
1636 if no content remains (use render_pager_has_next() to distinguish these
1639 render_pager_draw_next (struct render_pager *p, int space)
1641 if (p->scale != 1.0)
1643 p->params->ops->scale (p->params->aux, p->scale);
1647 int ofs[TABLE_N_AXES] = { 0, 0 };
1649 if (render_pager_has_next (p))
1651 struct render_page *page
1652 = render_break_next (&p->y_break, space - ofs[V]);
1655 render_page_draw (page, ofs);
1656 ofs[V] += render_page_get_size (page, V);
1657 render_page_unref (page);
1661 if (p->scale != 1.0)
1667 /* Draws all of P's content. */
1669 render_pager_draw (const struct render_pager *p)
1671 render_pager_draw_region (p, 0, 0, INT_MAX, INT_MAX);
1674 /* Draws the region of P's content that lies in the region (X,Y)-(X+W,Y+H).
1675 Some extra content might be drawn; the device should perform clipping as
1678 render_pager_draw_region (const struct render_pager *p,
1679 int x, int y, int w, int h)
1681 int ofs[TABLE_N_AXES] = { 0, 0 };
1682 int clip[TABLE_N_AXES][2];
1686 int size = render_page_get_size (p->page, V);
1688 clip[V][0] = MAX (y, ofs[V]) - ofs[V];
1689 clip[V][1] = MIN (y + h, ofs[V] + size) - ofs[V];
1690 if (clip[V][1] > clip[V][0])
1691 render_page_draw_region (p->page, ofs, clip);
1696 /* Returns the size of P's content along AXIS; i.e. the content's width if AXIS
1697 is TABLE_HORZ and its length if AXIS is TABLE_VERT. */
1699 render_pager_get_size (const struct render_pager *p, enum table_axis axis)
1701 return render_page_get_size (p->page, axis);
1705 render_pager_get_best_breakpoint (const struct render_pager *p, int height)
1707 int size = render_page_get_size (p->page, V);
1708 return (size < height
1710 : render_page_get_best_breakpoint (p->page, height));
1713 /* render_page_select() and helpers. */
1715 struct render_page_selection
1717 const struct render_page *page; /* Page whose slice we are selecting. */
1718 struct render_page *subpage; /* New page under construction. */
1719 enum table_axis a; /* Axis of 'page' along which 'subpage' is a slice. */
1720 enum table_axis b; /* The opposite of 'a'. */
1721 int z0; /* First cell along 'a' being selected. */
1722 int z1; /* Last cell being selected, plus 1. */
1723 int p0; /* Number of pixels to trim off left side of z0. */
1724 int p1; /* Number of pixels to trim off right side of z1-1. */
1727 static void cell_to_subpage (struct render_page_selection *,
1728 const struct table_cell *,
1729 int subcell[TABLE_N_AXES]);
1730 static const struct render_overflow *find_overflow_for_cell (
1731 struct render_page_selection *, const struct table_cell *);
1732 static struct render_overflow *insert_overflow (struct render_page_selection *,
1733 const struct table_cell *);
1735 /* Creates and returns a new render_page whose contents are a subregion of
1736 PAGE's contents. The new render_page includes cells Z0 through Z1
1737 (exclusive) along AXIS, plus any headers on AXIS.
1739 If P0 is nonzero, then it is a number of pixels to exclude from the left or
1740 top (according to AXIS) of cell Z0. Similarly, P1 is a number of pixels to
1741 exclude from the right or bottom of cell Z1 - 1. (P0 and P1 are used to
1742 render cells that are too large to fit on a single page.)
1744 The whole of axis !AXIS is included. (The caller may follow up with another
1745 call to render_page_select() to select on !AXIS to select on that axis as
1748 The caller retains ownership of PAGE, which is not modified. */
1749 static struct render_page *
1750 render_page_select (const struct render_page *page, enum table_axis axis,
1751 int z0, int p0, int z1, int p1)
1753 enum table_axis a = axis;
1754 enum table_axis b = !a;
1756 /* Optimize case where all of PAGE is selected by just incrementing the
1758 if (z0 == page->h[a][0] && p0 == 0
1759 && z1 == page->n[a] - page->h[a][1] && p1 == 0)
1761 struct render_page *page_rw = CONST_CAST (struct render_page *, page);
1766 /* Allocate subpage. */
1767 int trim[2] = { z0 - page->h[a][0], (page->n[a] - page->h[a][1]) - z1 };
1769 int n[TABLE_N_AXES] = { [H] = page->n[H], [V] = page->n[V] };
1770 n[a] -= trim[0] + trim[1];
1772 int r[TABLE_N_AXES][2];
1773 for (enum table_axis k = 0; k < TABLE_N_AXES; k++)
1775 r[k][0] = page->r[k][0];
1776 r[k][1] = page->r[k][1];
1781 struct render_page *subpage = render_page_allocate__ (
1782 page->params, table_ref (page->table), n, page->h, r);
1784 /* An edge is cut off if it was cut off in PAGE or if we're trimming pixels
1785 off that side of the page and there are no headers. */
1786 subpage->is_edge_cutoff[a][0] =
1787 subpage->h[a][0] == 0 && (p0 || (z0 == 0 && page->is_edge_cutoff[a][0]));
1788 subpage->is_edge_cutoff[a][1] =
1789 subpage->h[a][1] == 0 && (p1 || (z1 == page->n[a]
1790 && page->is_edge_cutoff[a][1]));
1791 subpage->is_edge_cutoff[b][0] = page->is_edge_cutoff[b][0];
1792 subpage->is_edge_cutoff[b][1] = page->is_edge_cutoff[b][1];
1794 /* Select join crossings from PAGE into subpage. */
1795 int *jc = subpage->join_crossing[a];
1796 for (int z = 0; z < page->h[a][0]; z++)
1797 *jc++ = page->join_crossing[a][z];
1798 for (int z = z0; z <= z1; z++)
1799 *jc++ = page->join_crossing[a][z];
1800 for (int z = page->n[a] - page->h[a][1]; z < page->n[a]; z++)
1801 *jc++ = page->join_crossing[a][z];
1802 assert (jc == &subpage->join_crossing[a][subpage->n[a] + 1]);
1804 memcpy (subpage->join_crossing[b], page->join_crossing[b],
1805 (subpage->n[b] + 1) * sizeof **subpage->join_crossing);
1807 /* Select widths from PAGE into subpage. */
1808 int *scp = page->cp[a];
1809 int *dcp = subpage->cp[a];
1811 for (int z = 0; z <= rule_ofs (subpage->h[a][0]); z++, dcp++)
1813 int w = !z && subpage->is_edge_cutoff[a][0] ? 0 : scp[z + 1] - scp[z];
1814 dcp[1] = dcp[0] + w;
1816 for (int z = cell_ofs (z0); z <= cell_ofs (z1 - 1); z++, dcp++)
1818 dcp[1] = dcp[0] + (scp[z + 1] - scp[z]);
1819 if (z == cell_ofs (z0))
1822 if (page->h[a][0] && page->h[a][1])
1823 dcp[1] += page->join_crossing[a][z / 2];
1825 if (z == cell_ofs (z1 - 1))
1828 for (int z = rule_ofs_r (page, a, subpage->h[a][1]);
1829 z <= rule_ofs_r (page, a, 0); z++, dcp++)
1831 if (z == rule_ofs_r (page, a, 0) && subpage->is_edge_cutoff[a][1])
1834 dcp[1] = dcp[0] + (scp[z + 1] - scp[z]);
1836 assert (dcp == &subpage->cp[a][2 * subpage->n[a] + 1]);
1838 for (int z = 0; z < page->n[b] * 2 + 2; z++)
1839 subpage->cp[b][z] = page->cp[b][z];
1841 /* Add new overflows. */
1842 struct render_page_selection s = {
1853 if (!page->h[a][0] || z0 > page->h[a][0] || p0)
1854 for (int z = 0; z < page->n[b];)
1856 int d[TABLE_N_AXES];
1860 struct table_cell cell;
1861 render_get_cell (page, d[H], d[V], &cell);
1862 bool overflow0 = p0 || cell.d[a][0] < z0;
1863 bool overflow1 = cell.d[a][1] > z1 || (cell.d[a][1] == z1 && p1);
1864 if (overflow0 || overflow1)
1866 struct render_overflow *ro = insert_overflow (&s, &cell);
1870 ro->overflow[a][0] += p0 + axis_width (
1871 page, a, cell_ofs (cell.d[a][0]), cell_ofs (z0));
1872 if (page->h[a][0] && page->h[a][1])
1873 ro->overflow[a][0] -= page->join_crossing[a][cell.d[a][0]
1879 ro->overflow[a][1] += p1 + axis_width (
1880 page, a, cell_ofs (z1), cell_ofs (cell.d[a][1]));
1881 if (page->h[a][0] && page->h[a][1])
1882 ro->overflow[a][1] -= page->join_crossing[a][cell.d[a][1]];
1888 if (!page->h[a][1] || z1 < page->n[a] - page->h[a][1] || p1)
1889 for (int z = 0; z < page->n[b];)
1891 int d[TABLE_N_AXES];
1895 struct table_cell cell;
1896 render_get_cell (page, d[H], d[V], &cell);
1897 if ((cell.d[a][1] > z1 || (cell.d[a][1] == z1 && p1))
1898 && find_overflow_for_cell (&s, &cell) == NULL)
1900 struct render_overflow *ro = insert_overflow (&s, &cell);
1901 ro->overflow[a][1] += p1 + axis_width (page, a, cell_ofs (z1),
1902 cell_ofs (cell.d[a][1]));
1907 /* Copy overflows from PAGE into subpage. */
1908 struct render_overflow *ro;
1909 HMAP_FOR_EACH (ro, struct render_overflow, node, &page->overflows)
1911 struct table_cell cell;
1913 table_get_cell (page->table, ro->d[H], ro->d[V], &cell);
1914 if (cell.d[a][1] > z0 && cell.d[a][0] < z1
1915 && find_overflow_for_cell (&s, &cell) == NULL)
1916 insert_overflow (&s, &cell);
1922 /* Given CELL, a table_cell within S->page, stores in SUBCELL the (x,y)
1923 coordinates of the top-left cell as it will appear in S->subpage.
1925 CELL must actually intersect the region of S->page that is being selected
1926 by render_page_select() or the results will not make any sense. */
1928 cell_to_subpage (struct render_page_selection *s,
1929 const struct table_cell *cell, int subcell[TABLE_N_AXES])
1931 enum table_axis a = s->a;
1932 enum table_axis b = s->b;
1933 int ha0 = s->subpage->h[a][0];
1935 subcell[a] = MAX (cell->d[a][0] - s->z0 + ha0, ha0);
1936 subcell[b] = cell->d[b][0];
1939 /* Given CELL, a table_cell within S->page, returns the render_overflow for
1940 that cell in S->subpage, if there is one, and a null pointer otherwise.
1942 CELL must actually intersect the region of S->page that is being selected
1943 by render_page_select() or the results will not make any sense. */
1944 static const struct render_overflow *
1945 find_overflow_for_cell (struct render_page_selection *s,
1946 const struct table_cell *cell)
1950 cell_to_subpage (s, cell, subcell);
1951 return find_overflow (s->subpage, subcell[H], subcell[V]);
1954 /* Given CELL, a table_cell within S->page, inserts a render_overflow for that
1955 cell in S->subpage (which must not already exist). Initializes the new
1956 render_overflow's 'overflow' member from the overflow for CELL in S->page,
1959 CELL must actually intersect the region of S->page that is being selected
1960 by render_page_select() or the results will not make any sense. */
1961 static struct render_overflow *
1962 insert_overflow (struct render_page_selection *s,
1963 const struct table_cell *cell)
1965 struct render_overflow *of = XZALLOC (struct render_overflow);
1966 cell_to_subpage (s, cell, of->d);
1967 hmap_insert (&s->subpage->overflows, &of->node,
1968 hash_cell (of->d[H], of->d[V]));
1970 const struct render_overflow *old
1971 = find_overflow (s->page, cell->d[H][0], cell->d[V][0]);
1973 memcpy (of->overflow, old->overflow, sizeof of->overflow);