#include "libpspp/hash-functions.h"
#include "libpspp/hmap.h"
#include "libpspp/pool.h"
+#include "output/pivot-output.h"
#include "output/pivot-table.h"
#include "output/render.h"
-#include "output/table-item.h"
#include "output/table.h"
#include "gl/minmax.h"
for (int i = 0; i < TABLE_N_AXES; i++)
{
- page->cp[i] = xmalloc ((2 * n[i] + 2) * sizeof *page->cp[i]);
- page->join_crossing[i] = xzalloc ((n[i] + 1)
- * sizeof *page->join_crossing[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]);
}
hmap_init (&page->overflows);
span multiple columns. */
struct render_row *columns[2];
for (int i = 0; i < 2; i++)
- columns[i] = xzalloc (nc * sizeof *columns[i]);
+ columns[i] = xcalloc (nc , sizeof *columns[i]);
for (int y = 0; y < nr; y++)
for (int x = 0; x < nc;)
{
}
/* Calculate heights of cells that do not span multiple rows. */
- struct render_row *rows = xzalloc (nr * sizeof *rows);
+ struct render_row *rows = XCALLOC (nr, struct render_row);
for (int y = 0; y < nr; y++)
for (int x = 0; x < nc;)
{
bb[V][0] = clip[V][0] = ofs[V] + page->cp[V][cell->d[V][0] * 2 + 1];
bb[V][1] = clip[V][1] = ofs[V] + page->cp[V][cell->d[V][1] * 2];
- enum table_valign valign = cell->style->cell_style.valign;
+ enum table_valign valign = cell->cell_style->valign;
int valign_offset = 0;
if (valign != TABLE_VALIGN_TOP)
{
struct render_break y_break;
};
-static const struct render_page *
+static void
render_pager_add_table (struct render_pager *p, struct table *table,
int min_width)
{
- struct render_page *page = render_page_create (p->params, table, min_width);
- p->pages[p->n_pages++] = page;
- return page;
+ if (table)
+ p->pages[p->n_pages++] = render_page_create (p->params, table, min_width);
}
static void
render_break_init_empty (&p->y_break);
}
-static void
-add_footnote_page (struct render_pager *p, const struct table_item *item)
-{
- struct footnote **f;
- size_t n_footnotes = table_collect_footnotes (item, &f);
- if (!n_footnotes)
- return;
-
- struct table *t = table_create (1, n_footnotes, 0, 0, 0, 0);
-
- for (size_t i = 0; i < n_footnotes; i++)
- {
- table_text_format (t, 0, i, 0, "%s. %s", f[i]->marker, f[i]->content);
- table_add_style (t, 0, i, f[i]->style);
- }
- render_pager_add_table (p, t, 0);
-
- free (f);
-}
-
-static void
-add_table_cell_page (struct render_pager *p, const struct table_cell *cell,
- int min_width)
-{
- if (!cell)
- return;
-
- struct table *tab = table_create (1, 1, 0, 0, 0, 0);
- table_text (tab, 0, 0, 0, cell->text);
- for (size_t i = 0; i < cell->n_footnotes; i++)
- table_add_footnote (tab, 0, 0, cell->footnotes[i]);
- if (cell->style)
- tab->styles[0] = table_area_style_clone (tab->container, cell->style);
- render_pager_add_table (p, tab, min_width);
-}
-
-static void
-add_layers_page (struct render_pager *p,
- const struct table_item_layers *layers, int min_width)
-{
- if (!layers)
- return;
-
- struct table *tab = table_create (1, layers->n_layers, 0, 0, 0, 0);
- for (size_t i = 0; i < layers->n_layers; i++)
- {
- const struct table_item_layer *layer = &layers->layers[i];
- table_text (tab, 0, i, 0, layer->content);
- for (size_t j = 0; j < layer->n_footnotes; j++)
- table_add_footnote (tab, 0, i, layer->footnotes[j]);
- }
- if (layers->style)
- tab->styles[0] = table_area_style_clone (tab->container, layers->style);
- render_pager_add_table (p, tab, min_width);
-}
-
-/* Creates and returns a new render_pager for rendering TABLE_ITEM on the
- device with the given PARAMS. */
+/* Creates and returns a new render_pager for rendering PT on the device
+ with the given PARAMS. */
struct render_pager *
render_pager_create (const struct render_params *params,
- const struct table_item *table_item)
+ const struct pivot_table *pt,
+ const size_t *layer_indexes)
{
- const struct table *table = table_item_get_table (table_item);
+ if (!layer_indexes)
+ layer_indexes = pt->current_layer;
+
+ struct table *title, *layers, *body, *caption, *footnotes;
+ pivot_output (pt, layer_indexes, params->printing,
+ &title, &layers, &body, &caption, &footnotes, NULL, NULL);
/* Figure out the width of the body of the table. Use this to determine the
base scale. */
- struct render_page *page = render_page_create (params, table_ref (table), 0);
- int body_width = table_width (page, H);
+ struct render_page *body_page = render_page_create (params, body, 0);
+ int body_width = table_width (body_page, H);
double scale = 1.0;
if (body_width > params->size[H])
{
- if (table_item->pt
- && table_item->pt->look->shrink_to_fit[H]
- && params->ops->scale)
+ if (pt->look->shrink_to_fit[H] && params->ops->scale)
scale = params->size[H] / (double) body_width;
else
{
struct render_break b;
- render_break_init (&b, page, H);
+ render_break_init (&b, render_page_ref (body_page), H);
struct render_page *subpage
= render_break_next (&b, params->size[H]);
body_width = subpage ? subpage->cp[H][2 * subpage->n[H] + 1] : 0;
/* Create the pager. */
struct render_pager *p = xmalloc (sizeof *p);
*p = (struct render_pager) { .params = params, .scale = scale };
- add_table_cell_page (p, table_item_get_title (table_item), body_width);
- add_layers_page (p, table_item_get_layers (table_item), body_width);
- render_pager_add_table (p, table_ref (table_item_get_table (table_item)), 0);
- add_table_cell_page (p, table_item_get_caption (table_item), 0);
- add_footnote_page (p, table_item);
+ render_pager_add_table (p, title, body_width);
+ render_pager_add_table (p, layers, body_width);
+ p->pages[p->n_pages++] = body_page;
+ render_pager_add_table (p, caption, 0);
+ render_pager_add_table (p, footnotes, 0);
+ assert (p->n_pages <= sizeof p->pages / sizeof *p->pages);
/* If we're shrinking tables to fit the page length, then adjust the scale
factor.
they won't break across as much vertical space, thus shrinking the table
vertically more than the scale would imply. Shrinking only as much as
necessary would require an iterative search. */
- if (table_item->pt
- && table_item->pt->look->shrink_to_fit[V]
- && params->ops->scale)
+ if (pt->look->shrink_to_fit[V] && params->ops->scale)
{
int total_height = 0;
for (size_t i = 0; i < p->n_pages; i++)
insert_overflow (struct render_page_selection *s,
const struct table_cell *cell)
{
- struct render_overflow *of = xzalloc (sizeof *of);
+ struct render_overflow *of = XZALLOC (struct render_overflow);
cell_to_subpage (s, cell, of->d);
hmap_insert (&s->subpage->overflows, &of->node,
hash_cell (of->d[H], of->d[V]));