if (a->file == NULL && !ascii_open_page (a))
return;
- p = render_pager_create (render_page_create (¶ms, table_item_get_table (
- table_item)));
+ p = render_pager_create (¶ms, table_item);
while (render_pager_has_next (p))
{
int used;
int bb[TABLE_N_AXES][2], int clip[TABLE_N_AXES][2] UNUSED,
int *widthp)
{
- const struct table *table = contents->table;
struct render_params params;
struct render_pager *p;
int r[TABLE_N_AXES][2];
params.line_widths[V][i] = width;
}
- p = render_pager_create (render_page_create (¶ms, table));
+ p = render_pager_create (¶ms, contents->table);
width = render_pager_get_size (p, TABLE_HORZ);
height = render_pager_get_size (p, TABLE_VERT);
else
*caption_heightp = 0;
- return render_pager_create (render_page_create (xr->params,
- table_item_get_table (item)));
+ return render_pager_create (xr->params, item);
}
static void
int bb[TABLE_N_AXES][2],
int clip[TABLE_N_AXES][2], int *widthp, int *brk)
{
- const struct table *table = contents->table;
int single_width, double_width;
struct render_params params;
struct render_pager *p;
}
xr->nest++;
- p = render_pager_create (render_page_create (¶ms, table));
+ p = render_pager_create (¶ms, contents->table);
width = render_pager_get_size (p, H);
height = render_pager_get_size (p, V);
if (bb[V][0] + height >= bb[V][1])
/* PSPP - a program for statistical analysis.
- Copyright (C) 2009, 2010, 2012, 2013 Free Software Foundation, Inc.
+ Copyright (C) 2009, 2010, 2012, 2013, 2014 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
fputs (field, csv->file);
}
+static void PRINTF_FORMAT (2, 3)
+csv_output_field_format (struct csv_driver *csv, const char *format, ...)
+{
+ va_list args;
+ char *s;
+
+ va_start (args, format);
+ s = xvasprintf (format, args);
+ va_end (args);
+
+ csv_output_field (csv, s);
+ free (s);
+}
+
static void
csv_put_field (struct csv_driver *csv, struct string *s, const char *field)
{
static void
csv_output_subtable (struct csv_driver *csv, struct string *s,
- const struct table *t)
+ const struct table_item *item)
{
+ const struct table *t = table_item_get_table (item);
+ const char *caption = table_item_get_caption (item);
int y, x;
+ if (csv->captions && caption != NULL)
+ {
+ csv_output_field_format (csv, "Table: %s", caption);
+ putc ('\n', csv->file);
+ }
+
for (y = 0; y < table_nr (t); y++)
{
if (y > 0)
}
}
-static void
-csv_output_field_format (struct csv_driver *csv, const char *format, ...)
- PRINTF_FORMAT (2, 3);
-
-static void
-csv_output_field_format (struct csv_driver *csv, const char *format, ...)
-{
- va_list args;
- char *s;
-
- va_start (args, format);
- s = xvasprintf (format, args);
- va_end (args);
-
- csv_output_field (csv, s);
- free (s);
-}
-
static void
csv_put_separator (struct csv_driver *csv)
{
static const struct output_driver_class html_driver_class;
-static void html_output_table (struct html_driver *, const struct table *,
- const char *caption);
+static void html_output_table (struct html_driver *, const struct table_item *);
static void escape_string (FILE *file,
const char *text, size_t length,
const char *space, const char *newline);
if (is_table_item (output_item))
{
struct table_item *table_item = to_table_item (output_item);
- html_output_table (html, table_item_get_table (table_item),
- table_item_get_caption (table_item));
+ html_output_table (html, table_item);
}
#ifdef HAVE_CAIRO
else if (is_chart_item (output_item) && html->chart_file_name != NULL)
}
static void
-html_output_table (struct html_driver *html,
- const struct table *t, const char *caption)
+html_output_table (struct html_driver *html, const struct table_item *item)
{
+ const struct table *t = table_item_get_table (item);
+ const char *caption = table_item_get_caption (item);
int x, y;
fputs ("<TABLE><TBODY VALIGN=\"TOP\">\n", html->file);
fputs ("</EM>", html->file);
}
else
- html_output_table (html, c->table, NULL);
+ html_output_table (html, c->table);
}
/* Output </TH> or </TD>. */
static const struct output_driver_class odt_driver_class;
-static void write_table (struct odt_driver *, const struct table *);
-
static struct odt_driver *
odt_driver_cast (struct output_driver *driver)
{
}
static void
-odt_submit_table (struct odt_driver *odt, struct table_item *item)
+write_table (struct odt_driver *odt, const struct table_item *item)
{
+ const struct table *tab = table_item_get_table (item);
const char *caption = table_item_get_caption (item);
+ int r, c;
/* Write a heading for the table */
if (caption != NULL)
xmlTextWriterEndElement (odt->content_wtr);
}
- write_table (odt, table_item_get_table (item));
-}
-
-static void
-write_table (struct odt_driver *odt, const struct table *tab)
-{
- int r, c;
-
/* Start table */
xmlTextWriterStartElement (odt->content_wtr, _xml("table:table"));
xmlTextWriterWriteFormatAttribute (odt->content_wtr, _xml("table:name"),
output_driver_track_current_command (output_item, &odt->command_name);
if (is_table_item (output_item))
- odt_submit_table (odt, to_table_item (output_item));
+ write_table (odt, to_table_item (output_item));
else if (is_text_item (output_item))
{
struct text_item *text_item = to_text_item (output_item);
#include "libpspp/hash-functions.h"
#include "libpspp/hmap.h"
#include "output/render.h"
+#include "output/table-item.h"
#include "output/table.h"
#include "gl/minmax.h"
May represent the layout of an entire table presented to
render_page_create(), or a rectangular subregion of a table broken out using
- render_break_next() to allow a table to be broken across multiple pages. */
+ render_break_next() to allow a table to be broken across multiple pages.
+
+ A page's size is not limited to the size passed in as part of render_params.
+ render_pager breaks a render_page into smaller render_pages that will fit in
+ the available space. */
struct render_page
{
const struct render_params *params; /* Parameters of the target device. */
int *join_crossing[TABLE_N_AXES];
};
+static struct render_page *render_page_create (const struct render_params *,
+ const struct table *);
+
+static void render_page_unref (struct render_page *);
+
/* Returns the offset in struct render_page's cp[axis] array of the rule with
index RULE_IDX. That is, if RULE_IDX is 0, then the offset is that of the
leftmost or topmost rule; if RULE_IDX is 1, then the offset is that of the
The new render_page will be suitable for rendering on a device whose page
size is PARAMS->size, but the caller is responsible for actually breaking it
up to fit on such a device, using the render_break abstraction. */
-struct render_page *
+static struct render_page *
render_page_create (const struct render_params *params,
const struct table *table_)
{
return page;
}
-/* Increases PAGE's reference count. */
-struct render_page *
-render_page_ref (const struct render_page *page_)
-{
- struct render_page *page = CONST_CAST (struct render_page *, page_);
- page->ref_cnt++;
- return page;
-}
-
/* Decreases PAGE's reference count and destroys PAGE if this causes the
reference count to fall to zero. */
-void
+static void
render_page_unref (struct render_page *page)
{
if (page != NULL && --page->ref_cnt == 0)
/* Creates and returns a new render_pager for breaking PAGE into smaller
chunks. Takes ownership of PAGE. */
struct render_pager *
-render_pager_create (struct render_page *page)
+render_pager_create (const struct render_params *params,
+ const struct table_item *table_item)
{
struct render_pager *p = xmalloc (sizeof *p);
- p->width = page->params->size[H];
- p->page = render_page_ref (page);
- render_break_init (&p->x_break, page, H);
+ p->width = params->size[H];
+ p->page = render_page_create (params, table_item_get_table (table_item));
+ render_break_init (&p->x_break, p->page, H);
render_break_init_empty (&p->y_break);
return p;
}
#include <stddef.h>
#include "output/table-provider.h"
-struct table;
+struct table_item;
enum render_line_style
{
int min_break[TABLE_N_AXES];
};
\f
-/* A "page" of content that is ready to be rendered.
-
- A page's size is not limited to the size passed in as part of render_params.
- Use render_pager (see below) to break a render_page into smaller
- render_pages that will fit in the available space. */
-struct render_page *render_page_create (const struct render_params *,
- const struct table *);
-
-struct render_page *render_page_ref (const struct render_page *);
-void render_page_unref (struct render_page *);
\f
/* An iterator for breaking render_pages into smaller chunks. */
-
-struct render_pager *render_pager_create (struct render_page *);
+struct render_pager *render_pager_create (const struct render_params *,
+ const struct table_item *);
void render_pager_destroy (struct render_pager *);
bool render_pager_has_next (const struct render_pager *);
union
{
char *text;
- struct table *subtable;
+ struct table_item *subtable;
}
u;
};
static void
subtable_unref (void *subtable)
{
- table_unref (subtable);
+ table_item_unref (subtable);
}
/* Places SUBTABLE as the content for cells (X1,X2)-(Y1,Y2) inclusive in TABLE
with options OPT. */
void
tab_subtable (struct tab_table *table, int x1, int y1, int x2, int y2,
- unsigned opt, struct table *subtable)
+ unsigned opt, struct table_item *subtable)
{
add_joined_cell (table, x1, y1, x2, y2, opt | TAB_SUBTABLE)->u.subtable
= subtable;
as a nested table but its contents become part of TABLE. */
void
tab_subtable_bare (struct tab_table *table, int x1, int y1, int x2, int y2,
- unsigned opt, struct table *subtable)
+ unsigned opt, struct table_item *subtable)
{
- assert (table_nc (subtable) == 1);
- assert (table_nr (subtable) == 1);
+ const struct table *t UNUSED = table_item_get_table (subtable);
+ assert (table_nc (t) == 1);
+ assert (table_nr (t) == 1);
tab_subtable (table, x1, y1, x2, y2, opt | TAB_BARE, subtable);
}
assert (opt & TAB_SUBTABLE);
/* This overwrites all of the members of CELL. */
- table_get_cell (jc->u.subtable, 0, 0, cell);
+ table_get_cell (table_item_get_table (jc->u.subtable), 0, 0, cell);
}
else
{
PRINTF_FORMAT (7, 8);
void tab_subtable (struct tab_table *, int x1, int y1, int x2, int y2,
- unsigned opt, struct table *subtable);
+ unsigned opt, struct table_item *subtable);
void tab_subtable_bare (struct tab_table *, int x1, int y1, int x2, int y2,
- unsigned opt, struct table *subtable);
+ unsigned opt, struct table_item *subtable);
bool tab_cell_is_empty (const struct tab_table *, int c, int r);
/* Exactly one of these must be nonnull. */
char *text; /* A paragraph of text. */
- struct table *table; /* A table nested within the cell. */
+ struct table_item *table; /* A table nested within the cell. */
};
/* A cell in a table. */
#include "libpspp/cast.h"
#include "libpspp/compiler.h"
+#include "output/table-item.h"
#include "gl/xalloc.h"
struct table_nested
{
struct table table;
- struct table *inner;
+ struct table_item *inner;
};
static const struct table_class table_nested_class;
-/* Creates and returns a table with a single cell that contains INNER. */
+/* Creates and returns a table with a single cell that contains INNER.
+ Takes ownership of INNER. */
struct table *
-table_create_nested (const struct table *inner)
+table_create_nested (struct table *inner)
+{
+ return table_create_nested_item (table_item_create (inner, NULL));
+}
+
+/* Creates and returns a table with a single cell that contains INNER.
+ Takes ownership of INNER. */
+struct table *
+table_create_nested_item (struct table_item *inner)
{
struct table_nested *tn = xmalloc (sizeof *tn);
table_init (&tn->table, &table_nested_class);
tn->table.n[TABLE_HORZ] = tn->table.n[TABLE_VERT] = 1;
- tn->inner = table_ref (inner);
+ tn->inner = table_item_ref (inner);
return &tn->table;
}
table_nested_destroy (struct table *tn_)
{
struct table_nested *tn = table_nested_cast (tn_);
- table_unref (tn->inner);
+ table_item_unref (tn->inner);
free (tn);
}
struct casereader;
struct fmt_spec;
+struct table_item;
struct variable;
/* Properties of a table cell. */
size_t column,
const char *heading,
const struct fmt_spec *);
-struct table *table_create_nested (const struct table *);
+struct table *table_create_nested (struct table *);
+struct table *table_create_nested_item (struct table_item *);
/* Combining tables. */
struct table *table_paste (struct table *, struct table *,
default:
error (1, 0, "unexpected subtable modifier \"%c\"", *text);
}
- tab_subtable (tab, c, r, c + cs - 1, r + rs - 1, opt, table);
+ tab_subtable (tab, c, r, c + cs - 1, r + rs - 1, opt,
+ table_item_create (table, NULL));
}
else
tab_joint_text (tab, c, r, c + cs - 1, r + rs - 1, opt, text);