-static void
-xr_init_caption_cell (const char *caption, struct table_cell *cell)
-{
- cell->contents = caption;
- cell->options = TAB_LEFT;
- cell->destructor = NULL;
-}
-
-static struct render_page *
-xr_render_table_item (struct xr_driver *xr, const struct table_item *item,
- int *caption_heightp)
-{
- const char *caption = table_item_get_caption (item);
-
- if (caption != NULL)
- {
- /* XXX doesn't do well with very large captions */
- struct table_cell cell;
- xr_init_caption_cell (caption, &cell);
- *caption_heightp = xr_measure_cell_height (xr, &cell, xr->width);
- }
- else
- *caption_heightp = 0;
-
- return render_page_create (xr->params, table_item_get_table (item));
-}
-
-static void
-xr_submit (struct output_driver *driver, const struct output_item *output_item)
-{
- struct xr_driver *xr = xr_driver_cast (driver);
-
- xr_driver_output_item (xr, output_item);
- while (xr_driver_need_new_page (xr))
- {
- cairo_restore (xr->cairo);
- cairo_show_page (xr->cairo);
- cairo_save (xr->cairo);
- xr_driver_next_page (xr, xr->cairo);
- }
-}
-\f
-/* Functions for rendering a series of output items to a series of Cairo
- contexts, with pagination, possibly including headers.
-
- Used by PSPPIRE for printing, and by the basic Cairo output driver above as
- its underlying implementation.
-
- See the big comment in cairo.h for intended usage. */
-
-/* Gives new page CAIRO to XR for output. CAIRO may be null to skip actually
- rendering the page (which might be useful to find out how many pages an
- output document has without actually rendering it). */
-void
-xr_driver_next_page (struct xr_driver *xr, cairo_t *cairo)
-{
- if (cairo != NULL)
- cairo_translate (cairo,
- xr_to_pt (xr->left_margin),
- xr_to_pt (xr->top_margin));
-
- xr->page_number++;
- xr->cairo = cairo;
- xr->y = 0;
- draw_headers (xr);
- xr_driver_run_fsm (xr);
-}
-
-/* Start rendering OUTPUT_ITEM to XR. Only valid if XR is not in the middle of
- rendering a previous output item, that is, only if xr_driver_need_new_page()
- returns false. */
-void
-xr_driver_output_item (struct xr_driver *xr,
- const struct output_item *output_item)
-{
- assert (xr->fsm == NULL);
- xr->fsm = xr_render_output_item (xr, output_item);
- xr_driver_run_fsm (xr);
-}
-
-/* Returns true if XR is in the middle of rendering an output item and needs a
- new page to be appended using xr_driver_next_page() to make progress,
- otherwise false. */
-bool
-xr_driver_need_new_page (const struct xr_driver *xr)
-{
- return xr->fsm != NULL;
-}
-
-/* Returns true if the current page doesn't have any content yet (besides
- headers, if enabled). */
-bool
-xr_driver_is_page_blank (const struct xr_driver *xr)
-{
- return xr->y == 0;
-}
-
-static void
-xr_driver_destroy_fsm (struct xr_driver *xr)
-{
- if (xr->fsm != NULL)
- {
- xr->fsm->destroy (xr->fsm);
- xr->fsm = NULL;
- }
-}
-
-static void
-xr_driver_run_fsm (struct xr_driver *xr)
-{
- if (xr->fsm != NULL && !xr->fsm->render (xr->fsm, xr))
- xr_driver_destroy_fsm (xr);
-}
-\f
-static void
-xr_layout_cell (struct xr_driver *, const struct table_cell *,
- int bb[TABLE_N_AXES][2], int clip[TABLE_N_AXES][2],
- PangoWrapMode, int *width, int *height);
-
-static void
-dump_line (struct xr_driver *xr, int x0, int y0, int x1, int y1)
-{
- cairo_new_path (xr->cairo);
- cairo_move_to (xr->cairo, xr_to_pt (x0), xr_to_pt (y0 + xr->y));
- cairo_line_to (xr->cairo, xr_to_pt (x1), xr_to_pt (y1 + xr->y));
- cairo_stroke (xr->cairo);
-}
-
-/* Draws a horizontal line X0...X2 at Y if LEFT says so,
- shortening it to X0...X1 if SHORTEN is true.
- Draws a horizontal line X1...X3 at Y if RIGHT says so,
- shortening it to X2...X3 if SHORTEN is true. */
-static void
-horz_line (struct xr_driver *xr, int x0, int x1, int x2, int x3, int y,
- enum render_line_style left, enum render_line_style right,
- bool shorten)