From: Ben Pfaff Date: Mon, 11 Jan 2021 06:19:35 +0000 (-0800) Subject: output-item: Collapse the inheritance hierarchy into a single struct. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29917c4f5908454803e663d2ad78bca4bc35e805;p=pspp output-item: Collapse the inheritance hierarchy into a single struct. When I designed this inheritance hierarchy, what was really needed was a bit of a mystery. Now, it's pretty clear what is really going to be here, and it simplifies and clarifies code a lot to just have a struct with an embedded union. It also removes, net, about 1000 lines of code. --- diff --git a/src/language/command.c b/src/language/command.c index 639bf4a3c0..3c98c3feda 100644 --- a/src/language/command.c +++ b/src/language/command.c @@ -36,7 +36,7 @@ #include "libpspp/i18n.h" #include "libpspp/message.h" #include "libpspp/str.h" -#include "output/group-item.h" +#include "output/output-item.h" #include "xmalloca.h" @@ -198,9 +198,9 @@ do_parse_command (struct lexer *lexer, result = CMD_FAILURE; goto finish; } - group_open_item_submit ( - group_open_item_create_nocopy (utf8_to_title (command->name), - utf8_to_title (command->name))); + output_item_submit (group_open_item_create_nocopy ( + utf8_to_title (command->name), + utf8_to_title (command->name))); opened = true; if (command->function == NULL) @@ -248,7 +248,7 @@ finish: lex_get (lexer); if (opened) - group_close_item_submit (group_close_item_create ()); + output_item_submit (group_close_item_create ()); return result; } diff --git a/src/language/data-io/list.c b/src/language/data-io/list.c index 2fc9baaf43..d84746506b 100644 --- a/src/language/data-io/list.c +++ b/src/language/data-io/list.c @@ -37,7 +37,6 @@ #include "libpspp/message.h" #include "libpspp/misc.h" #include "output/pivot-table.h" -#include "output/table-item.h" #include "gl/intprops.h" #include "gl/minmax.h" diff --git a/src/language/data-io/print-space.c b/src/language/data-io/print-space.c index 60eee4ce81..fafaff81a9 100644 --- a/src/language/data-io/print-space.c +++ b/src/language/data-io/print-space.c @@ -27,7 +27,7 @@ #include "language/expressions/public.h" #include "language/lexer/lexer.h" #include "libpspp/message.h" -#include "output/text-item.h" +#include "output/output-item.h" #include "gl/xalloc.h" @@ -134,7 +134,7 @@ print_space_trns_proc (void *t_, struct ccase **c, while (n--) if (trns->writer == NULL) - text_item_submit (text_item_create (TEXT_ITEM_LOG, "", NULL)); + output_item_submit (text_item_create (TEXT_ITEM_LOG, "", NULL)); else dfm_put_record (trns->writer, " ", 1); /* XXX */ diff --git a/src/language/data-io/print.c b/src/language/data-io/print.c index b021d8eba7..3b5541a3c3 100644 --- a/src/language/data-io/print.c +++ b/src/language/data-io/print.c @@ -42,8 +42,7 @@ #include "libpspp/u8-line.h" #include "output/pivot-table.h" #include "output/table.h" -#include "output/page-break-item.h" -#include "output/text-item.h" +#include "output/output-item.h" #include "gl/xalloc.h" @@ -556,16 +555,16 @@ print_text_flush_records (struct print_trns *trns, struct u8_line *line, { *eject = false; if (trns->writer == NULL) - page_break_item_submit (page_break_item_create ()); + output_item_submit (page_break_item_create ()); else leader = '1'; } *u8_line_reserve (line, 0, 1, 1) = leader; if (trns->writer == NULL) - text_item_submit (text_item_create (TEXT_ITEM_LOG, - ds_cstr (&line->s) + 1, - NULL)); + output_item_submit (text_item_create (TEXT_ITEM_LOG, + ds_cstr (&line->s) + 1, + NULL)); else { size_t len = ds_length (&line->s); diff --git a/src/language/dictionary/sys-file-info.c b/src/language/dictionary/sys-file-info.c index 66ef00bb70..68efb8ee7b 100644 --- a/src/language/dictionary/sys-file-info.c +++ b/src/language/dictionary/sys-file-info.c @@ -43,8 +43,7 @@ #include "libpspp/pool.h" #include "libpspp/string-array.h" #include "output/pivot-table.h" -#include "output/text-item.h" -#include "output/table-item.h" +#include "output/output-item.h" #include "gl/count-one-bits.h" #include "gl/localcharset.h" diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c index ceeb153c3e..34b697efe2 100644 --- a/src/language/lexer/lexer.c +++ b/src/language/lexer/lexer.c @@ -44,7 +44,7 @@ #include "libpspp/str.h" #include "libpspp/u8-istream.h" #include "output/journal.h" -#include "output/text-item.h" +#include "output/output-item.h" #include "gl/c-ctype.h" #include "gl/minmax.h" @@ -1443,9 +1443,9 @@ lex_source_get__ (const struct lex_source *src_) copy_len--; /* Submit the line as syntax. */ - text_item_submit (text_item_create_nocopy (TEXT_ITEM_SYNTAX, - xmemdup0 (line, copy_len), - NULL)); + output_item_submit (text_item_create_nocopy (TEXT_ITEM_SYNTAX, + xmemdup0 (line, copy_len), + NULL)); src->journal_pos += line_len; } diff --git a/src/language/stats/crosstabs.q b/src/language/stats/crosstabs.q index 50ba4a7342..e5f174f007 100644 --- a/src/language/stats/crosstabs.q +++ b/src/language/stats/crosstabs.q @@ -56,7 +56,6 @@ #include "libpspp/pool.h" #include "libpspp/str.h" #include "output/pivot-table.h" -#include "output/chart-item.h" #include "output/charts/barchart.h" #include "gl/minmax.h" @@ -786,9 +785,9 @@ postcalc (struct crosstabs_proc *proc) const struct variable **vars = xcalloc (n_vars, sizeof *vars); for (size_t i = 0; i < n_vars; i++) vars[i] = xt->vars[i].var; - chart_item_submit (barchart_create (vars, n_vars, _("Count"), - false, - xt->entries, xt->n_entries)); + chart_submit (barchart_create (vars, n_vars, _("Count"), + false, + xt->entries, xt->n_entries)); free (vars); } } diff --git a/src/language/stats/examine.c b/src/language/stats/examine.c index 409b9a6dd0..6b2f68a31d 100644 --- a/src/language/stats/examine.c +++ b/src/language/stats/examine.c @@ -373,7 +373,7 @@ show_npplot (const struct examine *cmd, int iact_idx) int grp; for (grp = 0; grp < n_cats; ++grp) { - struct chart_item *npp, *dnpp; + struct chart *npp, *dnpp; struct casereader *reader; struct np *np; @@ -416,13 +416,13 @@ show_npplot (const struct examine *cmd, int iact_idx) if (npp == NULL || dnpp == NULL) { msg (MW, _("Not creating NP plot because data set is empty.")); - chart_item_unref (npp); - chart_item_unref (dnpp); + chart_unref (npp); + chart_unref (dnpp); } else { - chart_item_submit (npp); - chart_item_submit (dnpp); + chart_submit (npp); + chart_submit (dnpp); } casereader_destroy (reader); @@ -446,7 +446,7 @@ show_spreadlevel (const struct examine *cmd, int iact_idx) for (v = 0; v < cmd->n_dep_vars; ++v) { int grp; - struct chart_item *sl; + struct chart *sl; struct string label; ds_init_cstr (&label, @@ -477,7 +477,7 @@ show_spreadlevel (const struct examine *cmd, int iact_idx) if (sl == NULL) msg (MW, _("Not creating spreadlevel chart for %s"), ds_cstr (&label)); else - chart_item_submit (sl); + chart_submit (sl); ds_destroy (&label); } @@ -534,7 +534,7 @@ show_histogram (const struct examine *cmd, int iact_idx) moments_calculate (es[v].mom, &n, &mean, &var, NULL, NULL); - chart_item_submit + chart_submit (histogram_chart_create (es[v].histogram->gsl_hist, ds_cstr (&label), n, mean, sqrt (var), false)); diff --git a/src/language/stats/factor.c b/src/language/stats/factor.c index cf67ecd8d4..f9156b7de0 100644 --- a/src/language/stats/factor.c +++ b/src/language/stats/factor.c @@ -45,7 +45,6 @@ #include "math/correlation.h" #include "math/covariance.h" #include "math/moments.h" -#include "output/chart-item.h" #include "output/charts/scree.h" #include "output/pivot-table.h" diff --git a/src/language/stats/frequencies.c b/src/language/stats/frequencies.c index 0404ceb799..736b6ae555 100644 --- a/src/language/stats/frequencies.c +++ b/src/language/stats/frequencies.c @@ -52,7 +52,6 @@ #include "math/chart-geometry.h" -#include "output/chart-item.h" #include "output/charts/barchart.h" #include "output/charts/piechart.h" #include "output/charts/plot-hist.h" @@ -547,12 +546,12 @@ postcalc (struct frq_proc *frq, const struct dataset *ds) if (histogram) { - chart_item_submit (histogram_chart_create ( - histogram->gsl_hist, var_to_string(vf->var), - vf->tab.valid_cases, - d[FRQ_ST_MEAN], - d[FRQ_ST_STDDEV], - frq->hist->draw_normal)); + chart_submit (histogram_chart_create ( + histogram->gsl_hist, var_to_string(vf->var), + vf->tab.valid_cases, + d[FRQ_ST_MEAN], + d[FRQ_ST_STDDEV], + frq->hist->draw_normal)); statistic_destroy (&histogram->parent); } @@ -1477,7 +1476,7 @@ do_piechart(const struct frq_chart *pie, const struct variable *var, msg (SW, _("Omitting pie chart for %s, which has over 50 unique values."), var_get_name (var)); else - chart_item_submit (piechart_create (var, slices, n_slices)); + chart_submit (piechart_create (var, slices, n_slices)); free (slices); } @@ -1490,10 +1489,10 @@ do_barchart(const struct frq_chart *bar, const struct variable **var, int n_slices; struct freq **slices = pick_cat_counts_ptr (bar, frq_tab, &n_slices); - chart_item_submit (barchart_create (var, 1, - (bar->y_scale == FRQ_FREQ) ? _("Count") : _("Percent"), - (bar->y_scale == FRQ_PERCENT), - slices, n_slices)); + chart_submit (barchart_create (var, 1, + (bar->y_scale == FRQ_FREQ) ? _("Count") : _("Percent"), + (bar->y_scale == FRQ_PERCENT), + slices, n_slices)); free (slices); } diff --git a/src/language/stats/graph.c b/src/language/stats/graph.c index b60ed2fdff..147d654ac4 100644 --- a/src/language/stats/graph.c +++ b/src/language/stats/graph.c @@ -373,7 +373,7 @@ show_histogr (const struct graph *cmd, struct casereader *input) moments_calculate (cmd->es[0].mom, &n, &mean, &var, NULL, NULL); - chart_item_submit + chart_submit (histogram_chart_create (histogram->gsl_hist, ds_cstr (&label), n, mean, sqrt (var), cmd->normal)); @@ -555,9 +555,9 @@ run_barchart (struct graph *cmd, struct casereader *input) ds_put_cstr (&label, ag_func[cmd->agr].description); - chart_item_submit (barchart_create (cmd->by_var, cmd->n_by_vars, - ds_cstr (&label), false, - cells, n_cells)); + chart_submit (barchart_create (cmd->by_var, cmd->n_by_vars, + ds_cstr (&label), false, + cells, n_cells)); ds_destroy (&label); } diff --git a/src/language/stats/quick-cluster.c b/src/language/stats/quick-cluster.c index 04d05d27bf..23f67b00b0 100644 --- a/src/language/stats/quick-cluster.c +++ b/src/language/stats/quick-cluster.c @@ -40,7 +40,7 @@ #include "libpspp/str.h" #include "math/random.h" #include "output/pivot-table.h" -#include "output/text-item.h" +#include "output/output-item.h" #include "gettext.h" #define _(msgid) gettext (msgid) diff --git a/src/language/stats/reliability.c b/src/language/stats/reliability.c index b8dc10b90f..615e108a78 100644 --- a/src/language/stats/reliability.c +++ b/src/language/stats/reliability.c @@ -32,7 +32,7 @@ #include "libpspp/str.h" #include "math/moments.h" #include "output/pivot-table.h" -#include "output/text-item.h" +#include "output/output-item.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@ -522,10 +522,10 @@ do_reliability (struct casereader *input, struct dataset *ds, alpha (s->n_items, s->sum_of_variances, s->variance_of_sums); } - text_item_submit (text_item_create_nocopy ( - TEXT_ITEM_TITLE, - xasprintf (_("Scale: %s"), ds_cstr (&rel->scale_name)), - NULL)); + output_item_submit (text_item_create_nocopy ( + TEXT_ITEM_TITLE, + xasprintf (_("Scale: %s"), ds_cstr (&rel->scale_name)), + NULL)); case_processing_summary (n_valid, n_missing, dataset_dict (ds)); } diff --git a/src/language/stats/roc.c b/src/language/stats/roc.c index 6c3a971bc4..b3f8e91e47 100644 --- a/src/language/stats/roc.c +++ b/src/language/stats/roc.c @@ -33,7 +33,6 @@ #include "language/lexer/variable-parser.h" #include "libpspp/misc.h" #include "math/sort.h" -#include "output/chart-item.h" #include "output/charts/roc-chart.h" #include "output/pivot-table.h" diff --git a/src/language/utilities/echo.c b/src/language/utilities/echo.c index 861fcf88bb..13fa721556 100644 --- a/src/language/utilities/echo.c +++ b/src/language/utilities/echo.c @@ -20,7 +20,8 @@ #include "language/lexer/lexer.h" #include "libpspp/message.h" #include "libpspp/str.h" -#include "output/text-item.h" +#include "output/output-item.h" +#include "output/driver.h" #include "gl/xalloc.h" @@ -34,8 +35,8 @@ cmd_echo (struct lexer *lexer, struct dataset *ds UNUSED) if (!lex_force_string (lexer)) return CMD_FAILURE; - text_item_submit (text_item_create (TEXT_ITEM_LOG, lex_tokcstr (lexer), - _("Echo"))); + output_submit (text_item_create (TEXT_ITEM_LOG, lex_tokcstr (lexer), + _("Echo"))); lex_get (lexer); return CMD_SUCCESS; diff --git a/src/language/utilities/host.c b/src/language/utilities/host.c index 9d19620f7c..e38dc7ab27 100644 --- a/src/language/utilities/host.c +++ b/src/language/utilities/host.c @@ -38,7 +38,7 @@ #include "libpspp/str.h" #include "libpspp/string-array.h" #include "libpspp/temp-file.h" -#include "output/text-item.h" +#include "output/output-item.h" #include "gl/error.h" #include "gl/intprops.h" @@ -261,8 +261,8 @@ run_command (const char *command, struct timespec timeout) if (end > output && end[-1] == '\n') end[-1] = '\0'; - text_item_submit (text_item_create_nocopy (TEXT_ITEM_LOG, output, - xstrdup (_("Host Output")))); + output_item_submit (text_item_create_nocopy (TEXT_ITEM_LOG, output, + xstrdup (_("Host Output")))); } free (locale_output); diff --git a/src/output/ascii.c b/src/output/ascii.c index 0efc523d2a..7b888d06ec 100644 --- a/src/output/ascii.c +++ b/src/output/ascii.c @@ -48,16 +48,13 @@ #include "libpspp/version.h" #include "output/ascii.h" #include "output/cairo-chart.h" -#include "output/chart-item-provider.h" +#include "output/chart-provider.h" #include "output/driver-provider.h" -#include "output/image-item.h" -#include "output/message-item.h" #include "output/options.h" #include "output/pivot-output.h" #include "output/pivot-table.h" #include "output/render.h" -#include "output/table-item.h" -#include "output/text-item.h" +#include "output/output-item.h" #include "gl/minmax.h" #include "gl/xalloc.h" @@ -555,15 +552,15 @@ ascii_output_lines (struct ascii_driver *a, size_t n_lines) static void ascii_output_table_item (struct ascii_driver *a, - const struct table_item *table_item) + const struct output_item *item) { update_page_size (a, false); - a->pt = table_item->pt; + a->pt = item->table; size_t *layer_indexes; - PIVOT_OUTPUT_FOR_EACH_LAYER (layer_indexes, table_item->pt, true) + PIVOT_OUTPUT_FOR_EACH_LAYER (layer_indexes, item->table, true) { - struct render_pager *p = render_pager_create (&a->params, table_item, + struct render_pager *p = render_pager_create (&a->params, item->table, layer_indexes); for (int i = 0; render_pager_has_next (p); i++) { @@ -580,80 +577,85 @@ ascii_output_table_item (struct ascii_driver *a, static void ascii_output_table_item_unref (struct ascii_driver *a, - struct table_item *table_item) + struct output_item *table_item) { ascii_output_table_item (a, table_item); - table_item_unref (table_item); + output_item_unref (table_item); } static void ascii_submit (struct output_driver *driver, - const struct output_item *output_item) + const struct output_item *item) { struct ascii_driver *a = ascii_driver_cast (driver); if (a->error) return; - if (is_table_item (output_item)) - ascii_output_table_item (a, to_table_item (output_item)); - else if (is_image_item (output_item) && a->chart_file_name != NULL) + switch (item->type) { - struct image_item *image_item = to_image_item (output_item); - char *file_name = xr_write_png_image ( - image_item->image, a->chart_file_name, ++a->chart_cnt); - if (file_name != NULL) - { - struct text_item *text_item; - - text_item = text_item_create_nocopy ( - TEXT_ITEM_LOG, - xasprintf (_("See %s for an image."), file_name), - NULL); + case OUTPUT_ITEM_TABLE: + ascii_output_table_item (a, item); + break; - ascii_submit (driver, &text_item->output_item); - text_item_unref (text_item); - free (file_name); - } - } - else if (is_chart_item (output_item) && a->chart_file_name != NULL) - { - struct chart_item *chart_item = to_chart_item (output_item); - char *file_name; - - file_name = xr_draw_png_chart (chart_item, a->chart_file_name, - ++a->chart_cnt, - &a->fg, - &a->bg); - if (file_name != NULL) + case OUTPUT_ITEM_IMAGE: + if (a->chart_file_name != NULL) { - struct text_item *text_item; - - text_item = text_item_create_nocopy ( - TEXT_ITEM_LOG, - xasprintf (_("See %s for a chart."), file_name), - NULL); + char *file_name = xr_write_png_image ( + item->image, a->chart_file_name, ++a->chart_cnt); + if (file_name != NULL) + { + struct output_item *text_item = text_item_create_nocopy ( + TEXT_ITEM_LOG, + xasprintf (_("See %s for an image."), file_name), + NULL); + + ascii_submit (driver, text_item); + output_item_unref (text_item); + free (file_name); + } + } + break; - ascii_submit (driver, &text_item->output_item); - text_item_unref (text_item); - free (file_name); + case OUTPUT_ITEM_CHART: + if (a->chart_file_name != NULL) + { + char *file_name = xr_draw_png_chart (item->chart, a->chart_file_name, + ++a->chart_cnt, &a->fg, + &a->bg); + if (file_name != NULL) + { + struct output_item *text_item = text_item_create_nocopy ( + TEXT_ITEM_LOG, + xasprintf (_("See %s for a chart."), file_name), + NULL); + + ascii_submit (driver, text_item); + output_item_unref (text_item); + free (file_name); + } } - } - else if (is_text_item (output_item)) - { - const struct text_item *text_item = to_text_item (output_item); - enum text_item_type type = text_item_get_type (text_item); + break; - if (type != TEXT_ITEM_PAGE_TITLE) + case OUTPUT_ITEM_TEXT: + if (item->text.subtype != TEXT_ITEM_PAGE_TITLE) ascii_output_table_item_unref ( - a, text_item_to_table_item (text_item_ref (text_item))); + a, text_item_to_table_item (output_item_ref (item))); + break; + + case OUTPUT_ITEM_MESSAGE: + ascii_output_table_item_unref ( + a, text_item_to_table_item ( + message_item_to_text_item ( + output_item_ref (item)))); + break; + + case OUTPUT_ITEM_GROUP_OPEN: + case OUTPUT_ITEM_GROUP_CLOSE: + case OUTPUT_ITEM_PAGE_BREAK: + case OUTPUT_ITEM_PAGE_SETUP: + break; } - else if (is_message_item (output_item)) - ascii_output_table_item_unref ( - a, text_item_to_table_item ( - message_item_to_text_item ( - to_message_item ( - output_item_ref (output_item))))); } const struct output_driver_factory txt_driver_factory = diff --git a/src/output/automake.mk b/src/output/automake.mk index 4ee2da3556..61c812767d 100644 --- a/src/output/automake.mk +++ b/src/output/automake.mk @@ -30,9 +30,9 @@ src_output_liboutput_la_SOURCES = \ src/output/cairo-pager.c \ src/output/cairo-pager.h \ src/output/cairo.c \ - src/output/chart-item-provider.h \ - src/output/chart-item.c \ - src/output/chart-item.h \ + src/output/chart-provider.h \ + src/output/chart.c \ + src/output/chart.h \ src/output/charts/barchart-cairo.c \ src/output/charts/barchart.c \ src/output/charts/barchart.h \ @@ -64,29 +64,20 @@ src_output_liboutput_la_SOURCES = \ src/output/driver-provider.h \ src/output/driver.c \ src/output/driver.h \ - src/output/group-item.c \ - src/output/group-item.h \ src/output/html.c \ - src/output/image-item.c \ - src/output/image-item.h \ src/output/journal.c \ src/output/journal.h \ src/output/measure.c \ src/output/measure.h \ - src/output/message-item.c \ - src/output/message-item.h \ src/output/msglog.c \ src/output/msglog.h \ src/output/odt.c \ src/output/options.c \ src/output/options.h \ - src/output/output-item-provider.h \ src/output/output-item.c \ src/output/output-item.h \ - src/output/page-break-item.c \ - src/output/page-break-item.h \ - src/output/page-setup-item.c \ - src/output/page-setup-item.h \ + src/output/page-setup.c \ + src/output/page-setup.h \ src/output/pivot-output.c \ src/output/pivot-output.h \ src/output/pivot-table.c \ @@ -94,8 +85,6 @@ src_output_liboutput_la_SOURCES = \ src/output/render.c \ src/output/render.h \ src/output/spv-driver.c \ - src/output/table-item.c \ - src/output/table-item.h \ src/output/table-provider.h \ src/output/table.c \ src/output/table.h \ @@ -105,9 +94,7 @@ src_output_liboutput_la_SOURCES = \ src/output/tex-parsing.h \ src/output/tex-rendering.c \ src/output/tex-rendering.h \ - src/output/tex.c \ - src/output/text-item.c \ - src/output/text-item.h + src/output/tex.c nodist_src_output_liboutput_la_SOURCES = EXTRA_DIST += \ diff --git a/src/output/cairo-chart.c b/src/output/cairo-chart.c index 11175292ec..20488bb96e 100644 --- a/src/output/cairo-chart.c +++ b/src/output/cairo-chart.c @@ -34,7 +34,6 @@ #include "libpspp/assertion.h" #include "libpspp/message.h" #include "math/chart-geometry.h" -#include "output/chart-item.h" #include "output/charts/barchart.h" #include "output/charts/boxplot.h" #include "output/charts/np-plot.h" @@ -621,7 +620,7 @@ xrchart_line(cairo_t *cr, const struct xrchart_geometry *geom, } void -xr_draw_chart (const struct chart_item *chart_item, cairo_t *cr, +xr_draw_chart (const struct chart *chart, cairo_t *cr, double width, double height) { struct xrchart_geometry geom; @@ -630,24 +629,24 @@ xr_draw_chart (const struct chart_item *chart_item, cairo_t *cr, cairo_translate (cr, 0, height); cairo_scale (cr, 1.0, -1.0); xrchart_geometry_init (cr, &geom, width, height); - if (is_boxplot (chart_item)) - xrchart_draw_boxplot (chart_item, cr, &geom); - else if (is_histogram_chart (chart_item)) - xrchart_draw_histogram (chart_item, cr, &geom); - else if (is_np_plot_chart (chart_item)) - xrchart_draw_np_plot (chart_item, cr, &geom); - else if (is_piechart (chart_item)) - xrchart_draw_piechart (chart_item, cr, &geom); - else if (is_barchart (chart_item)) - xrchart_draw_barchart (chart_item, cr, &geom); - else if (is_roc_chart (chart_item)) - xrchart_draw_roc (chart_item, cr, &geom); - else if (is_scree (chart_item)) - xrchart_draw_scree (chart_item, cr, &geom); - else if (is_spreadlevel_plot_chart (chart_item)) - xrchart_draw_spreadlevel (chart_item, cr, &geom); - else if (is_scatterplot_chart (chart_item)) - xrchart_draw_scatterplot (chart_item, cr, &geom); + if (is_boxplot (chart)) + xrchart_draw_boxplot (chart, cr, &geom); + else if (is_histogram_chart (chart)) + xrchart_draw_histogram (chart, cr, &geom); + else if (is_np_plot_chart (chart)) + xrchart_draw_np_plot (chart, cr, &geom); + else if (is_piechart (chart)) + xrchart_draw_piechart (chart, cr, &geom); + else if (is_barchart (chart)) + xrchart_draw_barchart (chart, cr, &geom); + else if (is_roc_chart (chart)) + xrchart_draw_roc (chart, cr, &geom); + else if (is_scree (chart)) + xrchart_draw_scree (chart, cr, &geom); + else if (is_spreadlevel_plot_chart (chart)) + xrchart_draw_spreadlevel (chart, cr, &geom); + else if (is_scatterplot_chart (chart)) + xrchart_draw_scatterplot (chart, cr, &geom); else NOT_REACHED (); xrchart_geometry_free (cr, &geom); @@ -656,7 +655,7 @@ xr_draw_chart (const struct chart_item *chart_item, cairo_t *cr, } cairo_surface_t * -xr_draw_image_chart (const struct chart_item *item, +xr_draw_image_chart (const struct chart *chart, const struct cell_color *fg, const struct cell_color *bg) { @@ -671,7 +670,7 @@ xr_draw_image_chart (const struct chart_item *item, cairo_paint (cr); cairo_set_source_rgb (cr, fg->r / 255.0, fg->g / 255.0, fg->b / 255.0); - xr_draw_chart (item, cr, width, length); + xr_draw_chart (chart, cr, width, length); cairo_destroy (cr); @@ -700,19 +699,19 @@ xr_write_png_image (cairo_surface_t *surface, } char * -xr_draw_png_chart (const struct chart_item *item, +xr_draw_png_chart (const struct chart *chart, const char *file_name_template, int number, const struct cell_color *fg, const struct cell_color *bg) { - cairo_surface_t *surface = xr_draw_image_chart (item, fg, bg); + cairo_surface_t *surface = xr_draw_image_chart (chart, fg, bg); char *file_name = xr_write_png_image (surface, file_name_template, number); cairo_surface_destroy (surface); return file_name; } char * -xr_draw_eps_chart (const struct chart_item *item, +xr_draw_eps_chart (const struct chart *chart, const char *file_name_template, int number, const struct cell_color *fg, const struct cell_color *bg) @@ -741,7 +740,7 @@ xr_draw_eps_chart (const struct chart_item *item, cairo_set_source_rgb (cr, fg->r / 255.0, fg->g / 255.0, fg->b / 255.0); - xr_draw_chart (item, cr, width, length); + xr_draw_chart (chart, cr, width, length); cairo_destroy (cr); cairo_surface_destroy (surface); diff --git a/src/output/cairo-chart.h b/src/output/cairo-chart.h index f02fd4efac..18c242efce 100644 --- a/src/output/cairo-chart.h +++ b/src/output/cairo-chart.h @@ -22,8 +22,8 @@ #include #include "libpspp/compiler.h" -struct chart_item; struct cell_color; +struct chart; struct xrchart_colour { @@ -159,40 +159,40 @@ void xrchart_line (cairo_t *, const struct xrchart_geometry *, double limit1, double limit2, enum xrchart_dim lim_dim); /* Drawing various kinds of charts. */ -void xrchart_draw_boxplot (const struct chart_item *, cairo_t *, +void xrchart_draw_boxplot (const struct chart *, cairo_t *, struct xrchart_geometry *); -void xrchart_draw_roc (const struct chart_item *, cairo_t *, +void xrchart_draw_roc (const struct chart *, cairo_t *, struct xrchart_geometry *); -void xrchart_draw_piechart (const struct chart_item *, cairo_t *, +void xrchart_draw_piechart (const struct chart *, cairo_t *, struct xrchart_geometry *); -void xrchart_draw_barchart (const struct chart_item *, cairo_t *, +void xrchart_draw_barchart (const struct chart *, cairo_t *, struct xrchart_geometry *); -void xrchart_draw_histogram (const struct chart_item *, cairo_t *, +void xrchart_draw_histogram (const struct chart *, cairo_t *, struct xrchart_geometry *); -void xrchart_draw_np_plot (const struct chart_item *, cairo_t *, +void xrchart_draw_np_plot (const struct chart *, cairo_t *, struct xrchart_geometry *); -void xrchart_draw_scree (const struct chart_item *, cairo_t *, +void xrchart_draw_scree (const struct chart *, cairo_t *, struct xrchart_geometry *); -void xrchart_draw_spreadlevel (const struct chart_item *, cairo_t *, +void xrchart_draw_spreadlevel (const struct chart *, cairo_t *, struct xrchart_geometry *); -void xrchart_draw_scatterplot (const struct chart_item *, cairo_t *, +void xrchart_draw_scatterplot (const struct chart *, cairo_t *, struct xrchart_geometry *); -void xr_draw_chart (const struct chart_item *, cairo_t *, +void xr_draw_chart (const struct chart *, cairo_t *, double width, double height); -cairo_surface_t *xr_draw_image_chart (const struct chart_item *, +cairo_surface_t *xr_draw_image_chart (const struct chart *, const struct cell_color *fg, const struct cell_color *bg); char *xr_write_png_image (cairo_surface_t *, const char *file_name_template, int number); -char *xr_draw_png_chart (const struct chart_item *, +char *xr_draw_png_chart (const struct chart *, const char *file_name_template, int number, const struct cell_color *fg, const struct cell_color *bg); -char *xr_draw_eps_chart (const struct chart_item *item, +char *xr_draw_eps_chart (const struct chart *, const char *file_name_template, int number, const struct cell_color *fg, const struct cell_color *bg); diff --git a/src/output/cairo-fsm.c b/src/output/cairo-fsm.c index 9b1be30832..183cdb0b7f 100644 --- a/src/output/cairo-fsm.c +++ b/src/output/cairo-fsm.c @@ -26,8 +26,7 @@ #include "libpspp/assertion.h" #include "libpspp/str.h" #include "output/cairo-chart.h" -#include "output/chart-item-provider.h" -#include "output/chart-item.h" +#include "output/chart-provider.h" #include "output/charts/barchart.h" #include "output/charts/boxplot.h" #include "output/charts/np-plot.h" @@ -37,16 +36,10 @@ #include "output/charts/scatterplot.h" #include "output/charts/scree.h" #include "output/charts/spreadlevel-plot.h" -#include "output/group-item.h" -#include "output/image-item.h" -#include "output/message-item.h" -#include "output/page-break-item.h" -#include "output/page-setup-item.h" #include "output/pivot-output.h" #include "output/pivot-table.h" #include "output/render.h" -#include "output/table-item.h" -#include "output/text-item.h" +#include "output/output-item.h" #include "gl/c-ctype.h" #include "gl/c-strcase.h" @@ -639,7 +632,7 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, int bb[TABLE_N_AXES][2], int clip[TABLE_N_AXES][2], int *widthp, int *brk) { - const struct pivot_table *pt = to_table_item (xr->item)->pt; + const struct pivot_table *pt = xr->item->table; const struct font_style *font_style = cell->font_style; const struct cell_style *cell_style = cell->cell_style; unsigned int options = cell->options; @@ -986,45 +979,47 @@ xr_fsm_create (const struct output_item *item_, const struct xr_fsm_style *style, cairo_t *cr, bool print) { - if (is_page_setup_item (item_) - || is_group_open_item (item_) - || is_group_close_item (item_)) - return NULL; - struct output_item *item; - if (is_table_item (item_) - || is_chart_item (item_) - || is_image_item (item_) - || is_page_break_item (item_)) - item = output_item_ref (item_); - else if (is_message_item (item_)) - item = table_item_super ( - text_item_to_table_item ( - message_item_to_text_item ( - to_message_item ( - output_item_ref (item_))))); - else if (is_text_item (item_)) + + switch (item_->type) { - if (to_text_item (item_)->type == TEXT_ITEM_PAGE_TITLE) + case OUTPUT_ITEM_CHART: + case OUTPUT_ITEM_IMAGE: + case OUTPUT_ITEM_PAGE_BREAK: + case OUTPUT_ITEM_TABLE: + item = output_item_ref (item_); + break; + + case OUTPUT_ITEM_GROUP_OPEN: + case OUTPUT_ITEM_GROUP_CLOSE: + case OUTPUT_ITEM_PAGE_SETUP: + return NULL; + + case OUTPUT_ITEM_MESSAGE: + item = text_item_to_table_item (message_item_to_text_item ( + output_item_ref (item_))); + break; + + case OUTPUT_ITEM_TEXT: + if (item_->text.subtype == TEXT_ITEM_PAGE_TITLE) return NULL; - item = table_item_super ( - text_item_to_table_item ( - to_text_item ( - output_item_ref (item_)))); + item = text_item_to_table_item (output_item_ref (item_)); + break; + + default: + NOT_REACHED (); } - else - NOT_REACHED (); - assert (is_table_item (item) - || is_chart_item (item) - || is_image_item (item) - || is_page_break_item (item)); + + assert (item->type == OUTPUT_ITEM_TABLE + || item->type == OUTPUT_ITEM_CHART + || item->type == OUTPUT_ITEM_IMAGE + || item->type == OUTPUT_ITEM_PAGE_BREAK); size_t *layer_indexes = NULL; - if (is_table_item (item)) + if (item->type == OUTPUT_ITEM_TABLE) { - const struct table_item *table_item = to_table_item (item); - layer_indexes = pivot_output_next_layer (table_item->pt, NULL, print); + layer_indexes = pivot_output_next_layer (item->table, NULL, print); if (!layer_indexes) return NULL; } @@ -1087,12 +1082,10 @@ xr_fsm_create (const struct output_item *item_, g_object_unref (G_OBJECT (layout)); - if (is_table_item (item)) + if (item->type == OUTPUT_ITEM_TABLE) { - struct table_item *table_item = to_table_item (item); - fsm->cairo = cr; - fsm->p = render_pager_create (&fsm->rp, table_item, fsm->layer_indexes); + fsm->p = render_pager_create (&fsm->rp, item->table, fsm->layer_indexes); fsm->cairo = NULL; } @@ -1136,26 +1129,34 @@ xr_fsm_measure (struct xr_fsm *fsm, cairo_t *cr, int *wp, int *hp) int w, h; - if (is_table_item (fsm->item)) + switch (fsm->item->type) { + case OUTPUT_ITEM_CHART: + w = CHART_WIDTH; + h = CHART_HEIGHT; + break; + + case OUTPUT_ITEM_IMAGE: + w = cairo_image_surface_get_width (fsm->item->image); + h = cairo_image_surface_get_height (fsm->item->image); + break; + + case OUTPUT_ITEM_TABLE: fsm->cairo = cr; w = render_pager_get_size (fsm->p, H) / XR_POINT; h = render_pager_get_size (fsm->p, V) / XR_POINT; fsm->cairo = NULL; + break; + + case OUTPUT_ITEM_GROUP_OPEN: + case OUTPUT_ITEM_GROUP_CLOSE: + case OUTPUT_ITEM_MESSAGE: + case OUTPUT_ITEM_PAGE_BREAK: + case OUTPUT_ITEM_PAGE_SETUP: + case OUTPUT_ITEM_TEXT: + default: + NOT_REACHED (); } - else if (is_chart_item (fsm->item)) - { - w = CHART_WIDTH; - h = CHART_HEIGHT; - } - else if (is_image_item (fsm->item)) - { - cairo_surface_t *image = to_image_item (fsm->item)->image; - w = cairo_image_surface_get_width (image); - h = cairo_image_surface_get_height (image); - } - else - NOT_REACHED (); if (wp) *wp = w; @@ -1195,23 +1196,31 @@ xr_fsm_draw_region (struct xr_fsm *fsm, cairo_t *cr, int x, int y, int w, int h) { assert (!fsm->print); - if (is_table_item (fsm->item)) + switch (fsm->item->type) { + case OUTPUT_ITEM_CHART: + xr_draw_chart (fsm->item->chart, cr, CHART_WIDTH, CHART_HEIGHT); + break; + + case OUTPUT_ITEM_IMAGE: + draw_image (fsm->item->image, cr); + break; + + case OUTPUT_ITEM_TABLE: fsm->cairo = cr; render_pager_draw_region (fsm->p, mul_XR_POINT (x), mul_XR_POINT (y), mul_XR_POINT (w), mul_XR_POINT (h)); fsm->cairo = NULL; + break; + + case OUTPUT_ITEM_GROUP_OPEN: + case OUTPUT_ITEM_GROUP_CLOSE: + case OUTPUT_ITEM_MESSAGE: + case OUTPUT_ITEM_PAGE_BREAK: + case OUTPUT_ITEM_PAGE_SETUP: + case OUTPUT_ITEM_TEXT: + NOT_REACHED (); } - else if (is_image_item (fsm->item)) - draw_image (to_image_item (fsm->item)->image, cr); - else if (is_chart_item (fsm->item)) - xr_draw_chart (to_chart_item (fsm->item), cr, CHART_WIDTH, CHART_HEIGHT); - else if (is_page_break_item (fsm->item)) - { - /* Nothing to do. */ - } - else - NOT_REACHED (); } /* Printing API. */ @@ -1219,19 +1228,18 @@ xr_fsm_draw_region (struct xr_fsm *fsm, cairo_t *cr, static int xr_fsm_draw_table (struct xr_fsm *fsm, int space) { - struct table_item *table_item = to_table_item (fsm->item); int used = render_pager_draw_next (fsm->p, space); if (!render_pager_has_next (fsm->p)) { render_pager_destroy (fsm->p); - fsm->layer_indexes = pivot_output_next_layer (table_item->pt, + fsm->layer_indexes = pivot_output_next_layer (fsm->item->table, fsm->layer_indexes, true); if (fsm->layer_indexes) { - fsm->p = render_pager_create (&fsm->rp, table_item, + fsm->p = render_pager_create (&fsm->rp, fsm->item->table, fsm->layer_indexes); - if (table_item->pt->look->paginate_layers) + if (fsm->item->table->look->paginate_layers) used = space; else used += fsm->style->object_spacing; @@ -1253,7 +1261,7 @@ xr_fsm_draw_chart (struct xr_fsm *fsm, int space) return 0; fsm->done = true; - xr_draw_chart (to_chart_item (fsm->item), fsm->cairo, + xr_draw_chart (fsm->item->chart, fsm->cairo, xr_to_pt (fsm->rp.size[H]), xr_to_pt (chart_height)); return chart_height; } @@ -1261,7 +1269,7 @@ xr_fsm_draw_chart (struct xr_fsm *fsm, int space) static int xr_fsm_draw_image (struct xr_fsm *fsm, int space) { - cairo_surface_t *image = to_image_item (fsm->item)->image; + cairo_surface_t *image = fsm->item->image; int width = cairo_image_surface_get_width (image) * XR_POINT; int height = cairo_image_surface_get_height (image) * XR_POINT; if (!width || !height) @@ -1319,12 +1327,33 @@ xr_fsm_draw_slice (struct xr_fsm *fsm, cairo_t *cr, int space) cairo_save (cr); fsm->cairo = cr; - int used = (is_table_item (fsm->item) ? xr_fsm_draw_table (fsm, space) - : is_chart_item (fsm->item) ? xr_fsm_draw_chart (fsm, space) - : is_image_item (fsm->item) ? xr_fsm_draw_image (fsm, space) - : is_page_break_item (fsm->item) ? xr_fsm_draw_page_break (fsm, - space) - : (abort (), 0)); + int used; + switch (fsm->item->type) + { + case OUTPUT_ITEM_CHART: + used = xr_fsm_draw_chart (fsm, space); + break; + + case OUTPUT_ITEM_IMAGE: + used = xr_fsm_draw_image (fsm, space); + break; + + case OUTPUT_ITEM_PAGE_BREAK: + used = xr_fsm_draw_page_break (fsm, space); + break; + + case OUTPUT_ITEM_TABLE: + used = xr_fsm_draw_table (fsm, space); + break; + + case OUTPUT_ITEM_GROUP_OPEN: + case OUTPUT_ITEM_GROUP_CLOSE: + case OUTPUT_ITEM_MESSAGE: + case OUTPUT_ITEM_PAGE_SETUP: + case OUTPUT_ITEM_TEXT: + default: + NOT_REACHED (); + } fsm->cairo = NULL; cairo_restore (cr); diff --git a/src/output/cairo-pager.c b/src/output/cairo-pager.c index e1cae64819..06de07b82e 100644 --- a/src/output/cairo-pager.c +++ b/src/output/cairo-pager.c @@ -23,13 +23,8 @@ #include #include -#include "output/chart-item.h" #include "output/driver-provider.h" -#include "output/group-item.h" -#include "output/message-item.h" -#include "output/page-setup-item.h" -#include "output/table-item.h" -#include "output/text-item.h" +#include "output/output-item.h" #include "gl/xalloc.h" @@ -118,7 +113,7 @@ struct xr_pager the outline item can be the first object actually output in it). */ int *group_ids; size_t n_group_ids, allocated_group_ids; - struct group_open_item **group_opens; + struct output_item **group_opens; size_t n_opens, allocated_opens; /* Current output page. */ @@ -255,7 +250,7 @@ xr_pager_destroy (struct xr_pager *p) { free (p->group_ids); for (size_t i = 0; i < p->n_opens; i++) - group_open_item_unref (p->group_opens[i]); + output_item_unref (p->group_opens[i]); free (p->group_opens); xr_page_style_unref (p->page_style); @@ -372,19 +367,18 @@ xr_pager_run (struct xr_pager *p) { if (!p->fsm) { - if (is_group_open_item (p->item)) + if (p->item->type == OUTPUT_ITEM_GROUP_OPEN) { if (p->n_opens >= p->allocated_opens) p->group_opens = x2nrealloc (p->group_opens, &p->allocated_opens, sizeof p->group_opens); - p->group_opens[p->n_opens++] = group_open_item_ref ( - to_group_open_item (p->item)); + p->group_opens[p->n_opens++] = output_item_ref (p->item); } - else if (is_group_close_item (p->item)) + else if (p->item->type == OUTPUT_ITEM_GROUP_CLOSE) { if (p->n_opens) - group_open_item_unref (p->group_opens[--p->n_opens]); + output_item_unref (p->group_opens[--p->n_opens]); else if (p->n_group_ids) p->n_group_ids--; else @@ -436,9 +430,9 @@ xr_pager_run (struct xr_pager *p) { parent_group_id = add_outline ( p->cr, parent_group_id, - output_item_get_label (&p->group_opens[i]->output_item), + output_item_get_label (p->group_opens[i]), attrs, CAIRO_PDF_OUTLINE_FLAG_OPEN); - group_open_item_unref (p->group_opens[i]); + output_item_unref (p->group_opens[i]); if (p->n_group_ids >= p->allocated_group_ids) p->group_ids = x2nrealloc (p->group_ids, diff --git a/src/output/cairo-pager.h b/src/output/cairo-pager.h index d492ba6933..8fa583d7e3 100644 --- a/src/output/cairo-pager.h +++ b/src/output/cairo-pager.h @@ -24,7 +24,7 @@ #include #include #include "output/cairo-fsm.h" -#include "output/page-setup-item.h" +#include "output/page-setup.h" #include "output/table.h" struct xr_page_style diff --git a/src/output/cairo.c b/src/output/cairo.c index 1c043bb93d..e5ac93bcf0 100644 --- a/src/output/cairo.c +++ b/src/output/cairo.c @@ -26,6 +26,7 @@ #include "output/cairo-pager.h" #include "output/driver-provider.h" #include "output/options.h" +#include "output/output-item.h" #include "output/table.h" #include @@ -602,15 +603,14 @@ xr_update_page_setup (struct output_driver *driver, } static void -xr_submit (struct output_driver *driver, const struct output_item *output_item) +xr_submit (struct output_driver *driver, const struct output_item *item) { struct xr_driver *xr = xr_driver_cast (driver); - if (is_page_setup_item (output_item)) + if (item->type == OUTPUT_ITEM_PAGE_SETUP) { if (!xr->pager) - xr_update_page_setup (driver, - to_page_setup_item (output_item)->page_setup); + xr_update_page_setup (driver, item->page_setup); return; } @@ -620,7 +620,7 @@ xr_submit (struct output_driver *driver, const struct output_item *output_item) xr_pager_add_page (xr->pager, cairo_create (xr->drawing_surface)); } - xr_pager_add_item (xr->pager, output_item); + xr_pager_add_item (xr->pager, item); while (xr_pager_needs_new_page (xr->pager)) { xr_finish_page (xr); diff --git a/src/output/chart-item-provider.h b/src/output/chart-item-provider.h deleted file mode 100644 index dd2fa9f12e..0000000000 --- a/src/output/chart-item-provider.h +++ /dev/null @@ -1,31 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2004, 2009, 2011 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef OUTPUT_CHART_ITEM_PROVIDER_H -#define OUTPUT_CHART_ITEM_PROVIDER_H 1 - -#include "output/chart-item.h" -#include "output/output-item.h" - -struct chart_item_class - { - void (*destroy) (struct chart_item *); - }; - -void chart_item_init (struct chart_item *, const struct chart_item_class *, - const char *title); - -#endif /* output/chart-provider.h */ diff --git a/src/output/chart-item.c b/src/output/chart-item.c deleted file mode 100644 index cedfa37a60..0000000000 --- a/src/output/chart-item.c +++ /dev/null @@ -1,102 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2004, 2009, 2011 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include "output/chart-item.h" -#include "output/chart-item-provider.h" - -#include -#include - -#include "libpspp/cast.h" -#include "libpspp/compiler.h" -#include "libpspp/str.h" -#include "output/driver.h" -#include "output/output-item-provider.h" - -#include "gl/xalloc.h" - -#include "gettext.h" -#define _(msgid) gettext (msgid) - -/* Initializes ITEM as a chart item of the specified CLASS. The new chart item - initially has the specified TITLE, which may be NULL if no title is yet - available. The caller retains ownership of TITLE. - - A chart item is an abstract class, that is, a plain chart_item is not useful - on its own. Thus, this function is normally called from the initialization - function of some subclass of chart_item. */ -void -chart_item_init (struct chart_item *item, const struct chart_item_class *class, - const char *title) -{ - *item = (struct chart_item) { - .output_item = OUTPUT_ITEM_INITIALIZER (&chart_item_class), - .class = class, - .title = xstrdup_if_nonnull (title) - }; -} - -/* Returns ITEM's title, which is a null pointer if no title has been set. */ -const char * -chart_item_get_title (const struct chart_item *item) -{ - return item->title; -} - -/* Sets ITEM's title to TITLE, replacing any previous title. Specify NULL for - TITLE to clear any title from ITEM. The caller retains ownership of - TITLE. - - This function may only be used on a chart_item that is unshared. */ -void -chart_item_set_title (struct chart_item *item, const char *title) -{ - assert (!chart_item_is_shared (item)); - free (item->title); - item->title = xstrdup_if_nonnull (title); -} - -/* Submits ITEM to the configured output drivers, and transfers ownership to - the output subsystem. */ -void -chart_item_submit (struct chart_item *item) -{ - output_submit (&item->output_item); -} - -static const char * -chart_item_get_label (const struct output_item *output_item) -{ - const struct chart_item *item = to_chart_item (output_item); - return item->title ? item->title : _("Chart"); -} - -static void -chart_item_destroy (struct output_item *output_item) -{ - struct chart_item *item = to_chart_item (output_item); - char *title = item->title; - item->class->destroy (item); - free (title); -} - -const struct output_item_class chart_item_class = - { - chart_item_get_label, - chart_item_destroy, - }; diff --git a/src/output/chart-item.h b/src/output/chart-item.h deleted file mode 100644 index ac25eb0a77..0000000000 --- a/src/output/chart-item.h +++ /dev/null @@ -1,100 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2009, 2011 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef OUTPUT_CHART_ITEM_H -#define OUTPUT_CHART_ITEM_H 1 - -/* Chart items. - - A chart item is a subclass of an output item (see output/output-item.h). - - A chart item is abstract. Every actual chart is a subclass of - chart_item. */ - -#include -#include "output/output-item.h" - -/* A chart item. - - The members of struct chart_item should not be accessed directly. Use one - of the accessor functions defined below. */ -struct chart_item - { - struct output_item output_item; /* Superclass */ - const struct chart_item_class *class; /* Subclass. */ - char *title; /* May be null if there is no title. */ - }; - -const char *chart_item_get_title (const struct chart_item *); -void chart_item_set_title (struct chart_item *, const char *); - -/* This boilerplate for chart_item, a subclass of output_item, was - autogenerated by mk-class-boilerplate. */ - -#include -#include "libpspp/cast.h" - -extern const struct output_item_class chart_item_class; - -/* Returns true if SUPER is a chart_item, otherwise false. */ -static inline bool -is_chart_item (const struct output_item *super) -{ - return super->class == &chart_item_class; -} - -/* Returns SUPER converted to chart_item. SUPER must be a chart_item, as - reported by is_chart_item. */ -static inline struct chart_item * -to_chart_item (const struct output_item *super) -{ - assert (is_chart_item (super)); - return UP_CAST (super, struct chart_item, output_item); -} - -/* Returns INSTANCE converted to output_item. */ -static inline struct output_item * -chart_item_super (const struct chart_item *instance) -{ - return CONST_CAST (struct output_item *, &instance->output_item); -} - -/* Increments INSTANCE's reference count and returns INSTANCE. */ -static inline struct chart_item * -chart_item_ref (const struct chart_item *instance) -{ - return to_chart_item (output_item_ref (&instance->output_item)); -} - -/* Decrements INSTANCE's reference count, then destroys INSTANCE if - the reference count is now zero. */ -static inline void -chart_item_unref (struct chart_item *instance) -{ - output_item_unref (&instance->output_item); -} - -/* Returns true if INSTANCE's reference count is greater than 1, - false otherwise. */ -static inline bool -chart_item_is_shared (const struct chart_item *instance) -{ - return output_item_is_shared (&instance->output_item); -} - -void chart_item_submit (struct chart_item *); - -#endif /* output/chart-item.h */ diff --git a/src/output/chart-provider.h b/src/output/chart-provider.h new file mode 100644 index 0000000000..82a93809a5 --- /dev/null +++ b/src/output/chart-provider.h @@ -0,0 +1,30 @@ +/* PSPP - a program for statistical analysis. + Copyright (C) 2004, 2009, 2011 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef OUTPUT_CHART_PROVIDER_H +#define OUTPUT_CHART_PROVIDER_H 1 + +#include "output/chart.h" + +struct chart_class + { + void (*destroy) (struct chart *); + }; + +void chart_init (struct chart *, const struct chart_class *, + const char *title); + +#endif /* output/chart-provider.h */ diff --git a/src/output/chart.c b/src/output/chart.c new file mode 100644 index 0000000000..6f1ce034a3 --- /dev/null +++ b/src/output/chart.c @@ -0,0 +1,109 @@ +/* PSPP - a program for statistical analysis. + Copyright (C) 2004, 2009, 2011 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +#include +#include + +#include "libpspp/cast.h" +#include "libpspp/compiler.h" +#include "libpspp/str.h" +#include "output/chart-provider.h" +#include "output/output-item.h" + +#include "gl/xalloc.h" + +#include "gettext.h" +#define _(msgid) gettext (msgid) + +struct chart * +chart_ref (const struct chart *chart_) +{ + struct chart *chart = CONST_CAST (struct chart *, chart_); + assert (chart->ref_cnt > 0); + chart->ref_cnt++; + return chart; +} + +void +chart_unref (struct chart *chart) +{ + if (chart) + { + assert (chart->ref_cnt > 0); + if (!--chart->ref_cnt) + { + char *title = chart->title; + chart->class->destroy (chart); + free (title); + } + } +} + +bool +chart_is_shared (const struct chart *chart) +{ + assert (chart->ref_cnt > 0); + return chart->ref_cnt > 1; +} + +/* Initializes CHART as a chart of the specified CLASS. The new chart + initially has the specified TITLE, which may be NULL if no title is yet + available. The caller retains ownership of TITLE. + + A chart is abstract, that is, a plain chart is not useful on its own. Thus, + this function is normally called from the initialization function of some + subclass of chart. */ +void +chart_init (struct chart *chart, const struct chart_class *class, + const char *title) +{ + *chart = (struct chart) { + .ref_cnt = 1, + .class = class, + .title = xstrdup_if_nonnull (title), + }; +} + +/* Returns CHART's title, which is a null pointer if no title has been set. */ +const char * +chart_get_title (const struct chart *chart) +{ + return chart->title; +} + +/* Sets CHART's title to TITLE, replacing any previous title. Specify NULL for + TITLE to clear any title from CHART. The caller retains ownership of + TITLE. + + This function may only be used on a chart that is unshared. */ +void +chart_set_title (struct chart *chart, const char *title) +{ + assert (!chart_is_shared (chart)); + free (chart->title); + chart->title = xstrdup_if_nonnull (title); +} + +/* Submits CHART to the configured output drivers, and transfers ownership to + the output subsystem. */ +void +chart_submit (struct chart *chart) +{ + if (chart) + output_item_submit (chart_item_create (chart)); +} diff --git a/src/output/charts/barchart-cairo.c b/src/output/charts/barchart-cairo.c index 00b33fc6b0..4663471e56 100644 --- a/src/output/charts/barchart-cairo.c +++ b/src/output/charts/barchart-cairo.c @@ -56,16 +56,16 @@ abscissa_label (const struct barchart *bc, cairo_t *cr, void -xrchart_draw_barchart (const struct chart_item *chart_item, cairo_t *cr, +xrchart_draw_barchart (const struct chart *chart, cairo_t *cr, struct xrchart_geometry *geom) { - struct barchart *bc = to_barchart (chart_item); + struct barchart *bc = to_barchart (chart); int i; xrchart_write_title (cr, geom, _("Bar Chart")); xrchart_write_ylabel (cr, geom, bc->ylabel); - xrchart_write_xlabel (cr, geom, chart_item_get_title (chart_item)); + xrchart_write_xlabel (cr, geom, chart_get_title (chart)); if (! xrchart_write_yscale (cr, geom, 0, bc->percent ? bc->largest * 100.0 / bc->total_count : bc->largest)) diff --git a/src/output/charts/barchart.c b/src/output/charts/barchart.c index eb252d4811..f987794004 100644 --- a/src/output/charts/barchart.c +++ b/src/output/charts/barchart.c @@ -24,7 +24,7 @@ #include "libpspp/cast.h" #include "libpspp/str.h" #include "libpspp/array.h" -#include "output/chart-item-provider.h" +#include "output/chart-provider.h" #include "gl/xalloc.h" #include "data/variable.h" @@ -170,7 +170,7 @@ barchart_dump (const struct barchart *bc, FILE *fp) CATS are the counts of the values of those variables. N_CATS is the number of distinct values. */ -struct chart_item * +struct chart * barchart_create (const struct variable **var, int n_vars, const char *ylabel, bool percent, struct freq *const *cats, int n_cats) @@ -191,7 +191,7 @@ barchart_create (const struct variable **var, int n_vars, bar->var = var; bar->n_vars = n_vars; bar->n_nzcats = n_cats; - chart_item_init (&bar->chart_item, &barchart_class, var_to_string (var[pidx])); + chart_init (&bar->chart, &barchart_class, var_to_string (var[pidx])); bar->largest = -1; bar->ylabel = strdup (ylabel); @@ -341,7 +341,7 @@ barchart_create (const struct variable **var, int n_vars, if (settings_get_testing_mode ()) barchart_dump (bar, stdout); - return &bar->chart_item; + return &bar->chart; } static void @@ -361,9 +361,9 @@ destroy_cat_map (struct hmap *m) } static void -barchart_destroy (struct chart_item *chart_item) +barchart_destroy (struct chart *chart) { - struct barchart *bar = to_barchart (chart_item); + struct barchart *bar = to_barchart (chart); int i; @@ -384,7 +384,7 @@ barchart_destroy (struct chart_item *chart_item) free (bar); } -const struct chart_item_class barchart_class = +const struct chart_class barchart_class = { barchart_destroy }; diff --git a/src/output/charts/barchart.h b/src/output/charts/barchart.h index a9eb5812ac..df27304c56 100644 --- a/src/output/charts/barchart.h +++ b/src/output/charts/barchart.h @@ -20,7 +20,7 @@ #include "libpspp/str.h" #include "libpspp/hmap.h" #include "data/value.h" -#include "output/chart-item.h" +#include "output/chart.h" struct category @@ -35,7 +35,7 @@ struct category struct barchart { - struct chart_item chart_item; + struct chart chart; /* Should the chart be displayed as percentages */ bool percent; @@ -79,21 +79,21 @@ struct barchart struct variable; struct freq; -struct chart_item *barchart_create (const struct variable **, int n_vars, +struct chart *barchart_create (const struct variable **, int n_vars, const char *ylabel, bool percent, struct freq *const *, int n_cats); -/* This boilerplate for barchart, a subclass of chart_item, was +/* This boilerplate for barchart, a subclass of chart, was autogenerated by mk-class-boilerplate. */ #include #include "libpspp/cast.h" -extern const struct chart_item_class barchart_class; +extern const struct chart_class barchart_class; /* Returns true if SUPER is a barchart, otherwise false. */ static inline bool -is_barchart (const struct chart_item *super) +is_barchart (const struct chart *super) { return super->class == &barchart_class; } @@ -101,24 +101,24 @@ is_barchart (const struct chart_item *super) /* Returns SUPER converted to barchart. SUPER must be a barchart, as reported by is_barchart. */ static inline struct barchart * -to_barchart (const struct chart_item *super) +to_barchart (const struct chart *super) { assert (is_barchart (super)); - return UP_CAST (super, struct barchart, chart_item); + return UP_CAST (super, struct barchart, chart); } -/* Returns INSTANCE converted to chart_item. */ -static inline struct chart_item * +/* Returns INSTANCE converted to chart. */ +static inline struct chart * barchart_super (const struct barchart *instance) { - return CONST_CAST (struct chart_item *, &instance->chart_item); + return CONST_CAST (struct chart *, &instance->chart); } /* Increments INSTANCE's reference count and returns INSTANCE. */ static inline struct barchart * barchart_ref (const struct barchart *instance) { - return to_barchart (chart_item_ref (&instance->chart_item)); + return to_barchart (chart_ref (&instance->chart)); } /* Decrements INSTANCE's reference count, then destroys INSTANCE if @@ -126,7 +126,7 @@ barchart_ref (const struct barchart *instance) static inline void barchart_unref (struct barchart *instance) { - chart_item_unref (&instance->chart_item); + chart_unref (&instance->chart); } /* Returns true if INSTANCE's reference count is greater than 1, @@ -134,13 +134,13 @@ barchart_unref (struct barchart *instance) static inline bool barchart_is_shared (const struct barchart *instance) { - return chart_item_is_shared (&instance->chart_item); + return chart_is_shared (&instance->chart); } static inline void barchart_submit (struct barchart *instance) { - chart_item_submit (&instance->chart_item); + chart_submit (&instance->chart); } #endif /* output/charts/barchart.h */ diff --git a/src/output/charts/boxplot-cairo.c b/src/output/charts/boxplot-cairo.c index b79b45f5e8..8448b2d6c4 100644 --- a/src/output/charts/boxplot-cairo.c +++ b/src/output/charts/boxplot-cairo.c @@ -145,17 +145,17 @@ boxplot_draw_box (cairo_t *cr, const struct xrchart_geometry *geom, } void -xrchart_draw_boxplot (const struct chart_item *chart_item, cairo_t *cr, +xrchart_draw_boxplot (const struct chart *chart, cairo_t *cr, struct xrchart_geometry *geom) { - const struct boxplot *boxplot = to_boxplot (chart_item); + const struct boxplot *boxplot = to_boxplot (chart); double box_width; size_t i; if (! xrchart_write_yscale (cr, geom, boxplot->y_min, boxplot->y_max)) return; - xrchart_write_title (cr, geom, "%s", chart_item->title); + xrchart_write_title (cr, geom, "%s", chart->title); box_width = (geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ABSCISSA].data_min) / boxplot->n_boxes / 2.0; for (i = 0; i < boxplot->n_boxes; i++) diff --git a/src/output/charts/boxplot.c b/src/output/charts/boxplot.c index 0abb971f44..3261d02eba 100644 --- a/src/output/charts/boxplot.c +++ b/src/output/charts/boxplot.c @@ -20,7 +20,7 @@ #include "output/charts/boxplot.h" #include "math/box-whisker.h" -#include "output/chart-item-provider.h" +#include "output/chart-provider.h" struct boxplot * boxplot_create (double y_min, double y_max, const char *title) @@ -28,7 +28,7 @@ boxplot_create (double y_min, double y_max, const char *title) if (y_min >= y_max) return NULL; struct boxplot *boxplot = xmalloc (sizeof *boxplot); - chart_item_init (&boxplot->chart_item, &boxplot_class, title); + chart_init (&boxplot->chart, &boxplot_class, title); boxplot->y_min = y_min; boxplot->y_max = y_max; boxplot->boxes = NULL; @@ -57,9 +57,9 @@ boxplot_add_box (struct boxplot *boxplot, } static void -boxplot_chart_destroy (struct chart_item *chart_item) +boxplot_chart_destroy (struct chart *chart) { - struct boxplot *boxplot = to_boxplot (chart_item); + struct boxplot *boxplot = to_boxplot (chart); if (boxplot == NULL) return; @@ -76,7 +76,7 @@ boxplot_chart_destroy (struct chart_item *chart_item) free (boxplot); } -const struct chart_item_class boxplot_class = +const struct chart_class boxplot_class = { boxplot_chart_destroy }; diff --git a/src/output/charts/boxplot.h b/src/output/charts/boxplot.h index e18daa844c..cd6b0961c6 100644 --- a/src/output/charts/boxplot.h +++ b/src/output/charts/boxplot.h @@ -18,12 +18,12 @@ #define OUTPUT_CHARTS_BOXPLOT_H 1 #include -#include "output/chart-item.h" +#include "output/chart.h" /* Box-whiskers plot. */ struct boxplot { - struct chart_item chart_item; + struct chart chart; /* Data. */ struct boxplot_box *boxes; @@ -45,17 +45,17 @@ struct boxplot *boxplot_create (double y_min, double y_max, const char *title); void boxplot_add_box (struct boxplot *, struct box_whisker *, const char *label); -/* This boilerplate for boxplot, a subclass of chart_item, was +/* This boilerplate for boxplot, a subclass of chart, was autogenerated by mk-class-boilerplate. */ #include #include "libpspp/cast.h" -extern const struct chart_item_class boxplot_class; +extern const struct chart_class boxplot_class; /* Returns true if SUPER is a boxplot, otherwise false. */ static inline bool -is_boxplot (const struct chart_item *super) +is_boxplot (const struct chart *super) { return super->class == &boxplot_class; } @@ -63,24 +63,24 @@ is_boxplot (const struct chart_item *super) /* Returns SUPER converted to boxplot. SUPER must be a boxplot, as reported by is_boxplot. */ static inline struct boxplot * -to_boxplot (const struct chart_item *super) +to_boxplot (const struct chart *super) { assert (is_boxplot (super)); - return UP_CAST (super, struct boxplot, chart_item); + return UP_CAST (super, struct boxplot, chart); } -/* Returns INSTANCE converted to chart_item. */ -static inline struct chart_item * +/* Returns INSTANCE converted to chart. */ +static inline struct chart * boxplot_super (const struct boxplot *instance) { - return CONST_CAST (struct chart_item *, &instance->chart_item); + return CONST_CAST (struct chart *, &instance->chart); } /* Increments INSTANCE's reference count and returns INSTANCE. */ static inline struct boxplot * boxplot_ref (const struct boxplot *instance) { - return to_boxplot (chart_item_ref (&instance->chart_item)); + return to_boxplot (chart_ref (&instance->chart)); } /* Decrements INSTANCE's reference count, then destroys INSTANCE if @@ -88,7 +88,7 @@ boxplot_ref (const struct boxplot *instance) static inline void boxplot_unref (struct boxplot *instance) { - chart_item_unref (&instance->chart_item); + chart_unref (&instance->chart); } /* Returns true if INSTANCE's reference count is greater than 1, @@ -96,13 +96,13 @@ boxplot_unref (struct boxplot *instance) static inline bool boxplot_is_shared (const struct boxplot *instance) { - return chart_item_is_shared (&instance->chart_item); + return chart_is_shared (&instance->chart); } static inline void boxplot_submit (struct boxplot *instance) { - chart_item_submit (&instance->chart_item); + chart_submit (&instance->chart); } #endif /* output/charts/boxplot.h */ diff --git a/src/output/charts/np-plot-cairo.c b/src/output/charts/np-plot-cairo.c index aa7d677348..ae866831f6 100644 --- a/src/output/charts/np-plot-cairo.c +++ b/src/output/charts/np-plot-cairo.c @@ -27,14 +27,14 @@ #define _(msgid) gettext (msgid) static void -np_plot_chart_draw (const struct chart_item *chart_item, cairo_t *cr, +np_plot_chart_draw (const struct chart *chart, cairo_t *cr, struct xrchart_geometry *geom) { - const struct np_plot_chart *npp = to_np_plot_chart (chart_item); + const struct np_plot_chart *npp = to_np_plot_chart (chart); struct casereader *data; struct ccase *c; - xrchart_write_title (cr, geom, _("Normal Q-Q Plot of %s"), chart_item->title); + xrchart_write_title (cr, geom, _("Normal Q-Q Plot of %s"), chart->title); xrchart_write_xlabel (cr, geom, _("Observed Value")); xrchart_write_ylabel (cr, geom, _("Expected Normal")); if (! xrchart_write_xscale (cr, geom, @@ -57,14 +57,14 @@ np_plot_chart_draw (const struct chart_item *chart_item, cairo_t *cr, } static void -dnp_plot_chart_draw (const struct chart_item *chart_item, cairo_t *cr, +dnp_plot_chart_draw (const struct chart *chart, cairo_t *cr, struct xrchart_geometry *geom) { - const struct np_plot_chart *dnpp = to_np_plot_chart (chart_item); + const struct np_plot_chart *dnpp = to_np_plot_chart (chart); struct casereader *data; struct ccase *c; - xrchart_write_title (cr, geom, _("Detrended Normal Q-Q Plot of %s"), chart_item->title); + xrchart_write_title (cr, geom, _("Detrended Normal Q-Q Plot of %s"), chart->title); xrchart_write_xlabel (cr, geom, _("Observed Value")); xrchart_write_ylabel (cr, geom, _("Dev from Normal")); if (! xrchart_write_xscale (cr, geom, dnpp->y_min, dnpp->y_max)) @@ -82,13 +82,13 @@ dnp_plot_chart_draw (const struct chart_item *chart_item, cairo_t *cr, } void -xrchart_draw_np_plot (const struct chart_item *chart_item, cairo_t *cr, +xrchart_draw_np_plot (const struct chart *chart, cairo_t *cr, struct xrchart_geometry *geom) { - const struct np_plot_chart *npp = to_np_plot_chart (chart_item); + const struct np_plot_chart *npp = to_np_plot_chart (chart); if (npp->detrended) - dnp_plot_chart_draw (chart_item, cr, geom); + dnp_plot_chart_draw (chart, cr, geom); else - np_plot_chart_draw (chart_item, cr, geom); + np_plot_chart_draw (chart, cr, geom); } diff --git a/src/output/charts/np-plot.c b/src/output/charts/np-plot.c index a140230e06..b0235924f8 100644 --- a/src/output/charts/np-plot.c +++ b/src/output/charts/np-plot.c @@ -23,11 +23,11 @@ #include "data/casereader.h" #include "libpspp/cast.h" #include "math/np.h" -#include "output/chart-item-provider.h" +#include "output/chart-provider.h" #include "gl/minmax.h" -static struct chart_item * +static struct chart * make_np_plot (const struct np *np, const struct casereader *reader, const char *label, bool detrended) { @@ -37,7 +37,7 @@ make_np_plot (const struct np *np, const struct casereader *reader, return NULL; npp = xzalloc (sizeof *npp); - chart_item_init (&npp->chart_item, &np_plot_chart_class, label); + chart_init (&npp->chart, &np_plot_chart_class, label); npp->data = casereader_clone (reader); npp->y_min = np->y_min; npp->y_max = np->y_max; @@ -58,7 +58,7 @@ make_np_plot (const struct np *np, const struct casereader *reader, npp->x_upper = MAX (np->y_max, (npp->y_last - npp->intercept) / npp->slope); npp->slack = (npp->x_upper - npp->x_lower) * 0.05; - return &npp->chart_item; + return &npp->chart; } /* Creates and returns a normal probability plot corresponding to @@ -69,7 +69,7 @@ make_np_plot (const struct np *np, const struct casereader *reader, Returns a null pointer if the data set is empty. The caller retains ownership of NP and READER. */ -struct chart_item * +struct chart * np_plot_create (const struct np *np, const struct casereader *reader, const char *label) { @@ -85,7 +85,7 @@ np_plot_create (const struct np *np, const struct casereader *reader, Returns a null pointer if the data set is empty. The caller retains ownership of NP and READER. */ -struct chart_item * +struct chart * dnp_plot_create (const struct np *np, const struct casereader *reader, const char *label) { @@ -93,14 +93,14 @@ dnp_plot_create (const struct np *np, const struct casereader *reader, } static void -np_plot_chart_destroy (struct chart_item *chart_item) +np_plot_chart_destroy (struct chart *chart) { - struct np_plot_chart *npp = to_np_plot_chart (chart_item); + struct np_plot_chart *npp = to_np_plot_chart (chart); casereader_destroy (npp->data); free (npp); } -const struct chart_item_class np_plot_chart_class = +const struct chart_class np_plot_chart_class = { np_plot_chart_destroy }; diff --git a/src/output/charts/np-plot.h b/src/output/charts/np-plot.h index 15c1cb9f71..b41dd6b374 100644 --- a/src/output/charts/np-plot.h +++ b/src/output/charts/np-plot.h @@ -17,14 +17,14 @@ #ifndef OUTPUT_CHARTS_NP_PLOT_H #define OUTPUT_CHARTS_NP_PLOT_H 1 -#include "output/chart-item.h" +#include "output/chart.h" struct np; /* An NP or DNP plot. */ struct np_plot_chart { - struct chart_item chart_item; + struct chart chart; struct casereader *data; bool detrended; @@ -39,24 +39,24 @@ struct np_plot_chart double slack; }; -struct chart_item *np_plot_create (const struct np *, +struct chart *np_plot_create (const struct np *, const struct casereader *, const char *label); -struct chart_item *dnp_plot_create (const struct np *, +struct chart *dnp_plot_create (const struct np *, const struct casereader *, const char *label); -/* This boilerplate for np_plot_chart, a subclass of chart_item, was +/* This boilerplate for np_plot_chart, a subclass of chart, was autogenerated by mk-class-boilerplate. */ #include #include "libpspp/cast.h" -extern const struct chart_item_class np_plot_chart_class; +extern const struct chart_class np_plot_chart_class; /* Returns true if SUPER is a np_plot_chart, otherwise false. */ static inline bool -is_np_plot_chart (const struct chart_item *super) +is_np_plot_chart (const struct chart *super) { return super->class == &np_plot_chart_class; } @@ -64,24 +64,24 @@ is_np_plot_chart (const struct chart_item *super) /* Returns SUPER converted to np_plot_chart. SUPER must be a np_plot_chart, as reported by is_np_plot_chart. */ static inline struct np_plot_chart * -to_np_plot_chart (const struct chart_item *super) +to_np_plot_chart (const struct chart *super) { assert (is_np_plot_chart (super)); - return UP_CAST (super, struct np_plot_chart, chart_item); + return UP_CAST (super, struct np_plot_chart, chart); } -/* Returns INSTANCE converted to chart_item. */ -static inline struct chart_item * +/* Returns INSTANCE converted to chart. */ +static inline struct chart * np_plot_chart_super (const struct np_plot_chart *instance) { - return CONST_CAST (struct chart_item *, &instance->chart_item); + return CONST_CAST (struct chart *, &instance->chart); } /* Increments INSTANCE's reference count and returns INSTANCE. */ static inline struct np_plot_chart * np_plot_chart_ref (const struct np_plot_chart *instance) { - return to_np_plot_chart (chart_item_ref (&instance->chart_item)); + return to_np_plot_chart (chart_ref (&instance->chart)); } /* Decrements INSTANCE's reference count, then destroys INSTANCE if @@ -89,7 +89,7 @@ np_plot_chart_ref (const struct np_plot_chart *instance) static inline void np_plot_chart_unref (struct np_plot_chart *instance) { - chart_item_unref (&instance->chart_item); + chart_unref (&instance->chart); } /* Returns true if INSTANCE's reference count is greater than 1, @@ -97,13 +97,13 @@ np_plot_chart_unref (struct np_plot_chart *instance) static inline bool np_plot_chart_is_shared (const struct np_plot_chart *instance) { - return chart_item_is_shared (&instance->chart_item); + return chart_is_shared (&instance->chart); } static inline void np_plot_chart_submit (struct np_plot_chart *instance) { - chart_item_submit (&instance->chart_item); + chart_submit (&instance->chart); } #endif /* output/charts/np-plot.h */ diff --git a/src/output/charts/piechart-cairo.c b/src/output/charts/piechart-cairo.c index c63706792e..6c43670806 100644 --- a/src/output/charts/piechart-cairo.c +++ b/src/output/charts/piechart-cairo.c @@ -46,10 +46,10 @@ draw_segment(cairo_t *cr, } void -xrchart_draw_piechart (const struct chart_item *chart_item, cairo_t *cr, +xrchart_draw_piechart (const struct chart *chart, cairo_t *cr, struct xrchart_geometry *geom) { - const struct piechart *pie = to_piechart (chart_item); + const struct piechart *pie = to_piechart (chart); double total_magnitude; double left_label, right_label; double centre_x, centre_y; @@ -66,7 +66,7 @@ xrchart_draw_piechart (const struct chart_item *chart_item, cairo_t *cr, radius = MIN (5.0 / 12.0 * (geom->axis[SCALE_ORDINATE].data_max - geom->axis[SCALE_ORDINATE].data_min), 1.0 / 4.0 * (geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ORDINATE].data_min)); - xrchart_write_title (cr, geom, "%s", chart_item_get_title (chart_item)); + xrchart_write_title (cr, geom, "%s", chart_get_title (chart)); total_magnitude = 0.0; for (i = 0; i < pie->n_slices; i++) diff --git a/src/output/charts/piechart.c b/src/output/charts/piechart.c index d00db1ffd1..678578fcbd 100644 --- a/src/output/charts/piechart.c +++ b/src/output/charts/piechart.c @@ -23,7 +23,7 @@ #include "libpspp/cast.h" #include "libpspp/str.h" #include "data/variable.h" -#include "output/chart-item-provider.h" +#include "output/chart-provider.h" #include "gl/xalloc.h" @@ -34,14 +34,14 @@ /* Creates and returns a chart that will render a piechart with the of VAR and the N_SLICES described in SLICES. */ -struct chart_item * +struct chart * piechart_create (const struct variable *var, const struct freq *slices, int n_slices) { struct piechart *pie; int i; pie = xmalloc (sizeof *pie); - chart_item_init (&pie->chart_item, &piechart_class, var_to_string (var)); + chart_init (&pie->chart, &piechart_class, var_to_string (var)); pie->slices = xnmalloc (n_slices, sizeof *pie->slices); for (i = 0; i < n_slices; i++) { @@ -63,13 +63,13 @@ piechart_create (const struct variable *var, const struct freq *slices, int n_sl dst->magnitude = src->count; } pie->n_slices = n_slices; - return &pie->chart_item; + return &pie->chart; } static void -piechart_destroy (struct chart_item *chart_item) +piechart_destroy (struct chart *chart) { - struct piechart *pie = to_piechart (chart_item); + struct piechart *pie = to_piechart (chart); int i; for (i = 0; i < pie->n_slices; i++) @@ -81,7 +81,7 @@ piechart_destroy (struct chart_item *chart_item) free (pie); } -const struct chart_item_class piechart_class = +const struct chart_class piechart_class = { piechart_destroy }; diff --git a/src/output/charts/piechart.h b/src/output/charts/piechart.h index 1899a511c1..2602c71c32 100644 --- a/src/output/charts/piechart.h +++ b/src/output/charts/piechart.h @@ -18,12 +18,12 @@ #define PIECHART_H #include "libpspp/str.h" -#include "output/chart-item.h" +#include "output/chart.h" #include "language/stats/freq.h" struct piechart { - struct chart_item chart_item; + struct chart chart; struct slice *slices; int n_slices; }; @@ -36,20 +36,20 @@ struct slice struct variable; -struct chart_item *piechart_create (const struct variable *var, +struct chart *piechart_create (const struct variable *var, const struct freq *, int n_slices); -/* This boilerplate for piechart, a subclass of chart_item, was +/* This boilerplate for piechart, a subclass of chart, was autogenerated by mk-class-boilerplate. */ #include #include "libpspp/cast.h" -extern const struct chart_item_class piechart_class; +extern const struct chart_class piechart_class; /* Returns true if SUPER is a piechart, otherwise false. */ static inline bool -is_piechart (const struct chart_item *super) +is_piechart (const struct chart *super) { return super->class == &piechart_class; } @@ -57,24 +57,24 @@ is_piechart (const struct chart_item *super) /* Returns SUPER converted to piechart. SUPER must be a piechart, as reported by is_piechart. */ static inline struct piechart * -to_piechart (const struct chart_item *super) +to_piechart (const struct chart *super) { assert (is_piechart (super)); - return UP_CAST (super, struct piechart, chart_item); + return UP_CAST (super, struct piechart, chart); } -/* Returns INSTANCE converted to chart_item. */ -static inline struct chart_item * +/* Returns INSTANCE converted to chart. */ +static inline struct chart * piechart_super (const struct piechart *instance) { - return CONST_CAST (struct chart_item *, &instance->chart_item); + return CONST_CAST (struct chart *, &instance->chart); } /* Increments INSTANCE's reference count and returns INSTANCE. */ static inline struct piechart * piechart_ref (const struct piechart *instance) { - return to_piechart (chart_item_ref (&instance->chart_item)); + return to_piechart (chart_ref (&instance->chart)); } /* Decrements INSTANCE's reference count, then destroys INSTANCE if @@ -82,7 +82,7 @@ piechart_ref (const struct piechart *instance) static inline void piechart_unref (struct piechart *instance) { - chart_item_unref (&instance->chart_item); + chart_unref (&instance->chart); } /* Returns true if INSTANCE's reference count is greater than 1, @@ -90,13 +90,13 @@ piechart_unref (struct piechart *instance) static inline bool piechart_is_shared (const struct piechart *instance) { - return chart_item_is_shared (&instance->chart_item); + return chart_is_shared (&instance->chart); } static inline void piechart_submit (struct piechart *instance) { - chart_item_submit (&instance->chart_item); + chart_submit (&instance->chart); } #endif /* output/charts/piechart.h */ diff --git a/src/output/charts/plot-hist-cairo.c b/src/output/charts/plot-hist-cairo.c index 620fe68c23..f866342809 100644 --- a/src/output/charts/plot-hist-cairo.c +++ b/src/output/charts/plot-hist-cairo.c @@ -100,17 +100,17 @@ hist_draw_bar (cairo_t *cr, const struct xrchart_geometry *geom, } void -xrchart_draw_histogram (const struct chart_item *chart_item, cairo_t *cr, +xrchart_draw_histogram (const struct chart *chart, cairo_t *cr, struct xrchart_geometry *geom) { - struct histogram_chart *h = to_histogram_chart (chart_item); + struct histogram_chart *h = to_histogram_chart (chart); int i; int bins; xrchart_write_title (cr, geom, _("HISTOGRAM")); xrchart_write_ylabel (cr, geom, _("Frequency")); - xrchart_write_xlabel (cr, geom, chart_item_get_title (chart_item)); + xrchart_write_xlabel (cr, geom, chart_get_title (chart)); if (h->gsl_hist == NULL) { diff --git a/src/output/charts/plot-hist.c b/src/output/charts/plot-hist.c index 3142c49279..aed72e6f48 100644 --- a/src/output/charts/plot-hist.c +++ b/src/output/charts/plot-hist.c @@ -24,7 +24,7 @@ #include "libpspp/cast.h" #include "math/histogram.h" #include "math/moments.h" -#include "output/chart-item-provider.h" +#include "output/chart-provider.h" #include "output/charts/plot-hist.h" #include "gettext.h" @@ -34,7 +34,7 @@ Labels the histogram with each of N, MEAN, and STDDEV that is not SYSMIS. If all three are not SYSMIS and SHOW_NORMAL is true, also draws a normal curve on the histogram. */ -struct chart_item * +struct chart * histogram_chart_create (const gsl_histogram *hist, const char *label, double n, double mean, double stddev, bool show_normal) @@ -42,26 +42,26 @@ histogram_chart_create (const gsl_histogram *hist, const char *label, struct histogram_chart *h; h = xmalloc (sizeof *h); - chart_item_init (&h->chart_item, &histogram_chart_class, label); + chart_init (&h->chart, &histogram_chart_class, label); h->gsl_hist = hist != NULL ? gsl_histogram_clone (hist) : NULL; h->n = n; h->mean = mean; h->stddev = stddev; h->show_normal = show_normal; - return &h->chart_item; + return &h->chart; } static void -histogram_chart_destroy (struct chart_item *chart_item) +histogram_chart_destroy (struct chart *chart) { - struct histogram_chart *h = UP_CAST (chart_item, struct histogram_chart, - chart_item); + struct histogram_chart *h = UP_CAST (chart, struct histogram_chart, + chart); if (h->gsl_hist != NULL) gsl_histogram_free (h->gsl_hist); free (h); } -const struct chart_item_class histogram_chart_class = +const struct chart_class histogram_chart_class = { histogram_chart_destroy }; diff --git a/src/output/charts/plot-hist.h b/src/output/charts/plot-hist.h index bf3674b00e..c1e0cddb0b 100644 --- a/src/output/charts/plot-hist.h +++ b/src/output/charts/plot-hist.h @@ -20,11 +20,11 @@ #include #include -#include "output/chart-item.h" +#include "output/chart.h" struct histogram_chart { - struct chart_item chart_item; + struct chart chart; gsl_histogram *gsl_hist; double n; double mean; @@ -37,22 +37,22 @@ struct histogram_chart with each of N, MEAN, and STDDEV that is not SYSMIS. If all three are not SYSMIS and SHOW_NORMAL is true, also draws a normal curve on the histogram. */ -struct chart_item *histogram_chart_create (const gsl_histogram *, - const char *label, double n, - double mean, double stddev, - bool show_normal); +struct chart *histogram_chart_create (const gsl_histogram *, + const char *label, double n, + double mean, double stddev, + bool show_normal); -/* This boilerplate for histogram_chart, a subclass of chart_item, was +/* This boilerplate for histogram_chart, a subclass of chart, was autogenerated by mk-class-boilerplate. */ #include #include "libpspp/cast.h" -extern const struct chart_item_class histogram_chart_class; +extern const struct chart_class histogram_chart_class; /* Returns true if SUPER is a histogram_chart, otherwise false. */ static inline bool -is_histogram_chart (const struct chart_item *super) +is_histogram_chart (const struct chart *super) { return super->class == &histogram_chart_class; } @@ -60,24 +60,24 @@ is_histogram_chart (const struct chart_item *super) /* Returns SUPER converted to histogram_chart. SUPER must be a histogram_chart, as reported by is_histogram_chart. */ static inline struct histogram_chart * -to_histogram_chart (const struct chart_item *super) +to_histogram_chart (const struct chart *super) { assert (is_histogram_chart (super)); - return UP_CAST (super, struct histogram_chart, chart_item); + return UP_CAST (super, struct histogram_chart, chart); } -/* Returns INSTANCE converted to chart_item. */ -static inline struct chart_item * +/* Returns INSTANCE converted to chart. */ +static inline struct chart * histogram_chart_super (const struct histogram_chart *instance) { - return CONST_CAST (struct chart_item *, &instance->chart_item); + return CONST_CAST (struct chart *, &instance->chart); } /* Increments INSTANCE's reference count and returns INSTANCE. */ static inline struct histogram_chart * histogram_chart_ref (const struct histogram_chart *instance) { - return to_histogram_chart (chart_item_ref (&instance->chart_item)); + return to_histogram_chart (chart_ref (&instance->chart)); } /* Decrements INSTANCE's reference count, then destroys INSTANCE if @@ -85,7 +85,7 @@ histogram_chart_ref (const struct histogram_chart *instance) static inline void histogram_chart_unref (struct histogram_chart *instance) { - chart_item_unref (&instance->chart_item); + chart_unref (&instance->chart); } /* Returns true if INSTANCE's reference count is greater than 1, @@ -93,13 +93,13 @@ histogram_chart_unref (struct histogram_chart *instance) static inline bool histogram_chart_is_shared (const struct histogram_chart *instance) { - return chart_item_is_shared (&instance->chart_item); + return chart_is_shared (&instance->chart); } static inline void histogram_chart_submit (struct histogram_chart *instance) { - chart_item_submit (&instance->chart_item); + chart_submit (&instance->chart); } #endif /* output/plot-hist.h */ diff --git a/src/output/charts/roc-chart-cairo.c b/src/output/charts/roc-chart-cairo.c index ae2db62efb..910d6152f0 100644 --- a/src/output/charts/roc-chart-cairo.c +++ b/src/output/charts/roc-chart-cairo.c @@ -27,10 +27,10 @@ #define _(msgid) gettext (msgid) void -xrchart_draw_roc (const struct chart_item *chart_item, cairo_t *cr, +xrchart_draw_roc (const struct chart *chart, cairo_t *cr, struct xrchart_geometry *geom) { - const struct roc_chart *rc = to_roc_chart (chart_item); + const struct roc_chart *rc = to_roc_chart (chart); size_t i; xrchart_write_title (cr, geom, _("ROC Curve")); diff --git a/src/output/charts/roc-chart.c b/src/output/charts/roc-chart.c index 0285d6f6a1..24fb5cde44 100644 --- a/src/output/charts/roc-chart.c +++ b/src/output/charts/roc-chart.c @@ -20,7 +20,7 @@ #include "data/casereader.h" #include "language/stats/roc.h" -#include "output/chart-item-provider.h" +#include "output/chart-provider.h" #include "gl/xalloc.h" @@ -31,7 +31,7 @@ struct roc_chart * roc_chart_create (bool reference) { struct roc_chart *rc = xmalloc (sizeof *rc); - chart_item_init (&rc->chart_item, &roc_chart_class, NULL); + chart_init (&rc->chart, &roc_chart_class, NULL); rc->reference = reference; rc->vars = NULL; rc->n_vars = 0; @@ -54,9 +54,9 @@ roc_chart_add_var (struct roc_chart *rc, const char *var_name, } static void -roc_chart_destroy (struct chart_item *chart_item) +roc_chart_destroy (struct chart *chart) { - struct roc_chart *rc = UP_CAST (chart_item, struct roc_chart, chart_item); + struct roc_chart *rc = UP_CAST (chart, struct roc_chart, chart); size_t i; for (i = 0; i < rc->n_vars; i++) @@ -69,7 +69,7 @@ roc_chart_destroy (struct chart_item *chart_item) free (rc); } -const struct chart_item_class roc_chart_class = +const struct chart_class roc_chart_class = { roc_chart_destroy }; diff --git a/src/output/charts/roc-chart.h b/src/output/charts/roc-chart.h index 309ac38e98..583bb7cfe9 100644 --- a/src/output/charts/roc-chart.h +++ b/src/output/charts/roc-chart.h @@ -19,11 +19,11 @@ #include #include -#include "output/chart-item.h" +#include "output/chart.h" struct roc_chart { - struct chart_item chart_item; + struct chart chart; bool reference; struct roc_var *vars; size_t n_vars; @@ -40,17 +40,17 @@ struct roc_chart *roc_chart_create (bool reference); void roc_chart_add_var (struct roc_chart *, const char *var_name, const struct casereader *cutpoint_reader); -/* This boilerplate for roc_chart, a subclass of chart_item, was +/* This boilerplate for roc_chart, a subclass of chart, was autogenerated by mk-class-boilerplate. */ #include #include "libpspp/cast.h" -extern const struct chart_item_class roc_chart_class; +extern const struct chart_class roc_chart_class; /* Returns true if SUPER is a roc_chart, otherwise false. */ static inline bool -is_roc_chart (const struct chart_item *super) +is_roc_chart (const struct chart *super) { return super->class == &roc_chart_class; } @@ -58,24 +58,24 @@ is_roc_chart (const struct chart_item *super) /* Returns SUPER converted to roc_chart. SUPER must be a roc_chart, as reported by is_roc_chart. */ static inline struct roc_chart * -to_roc_chart (const struct chart_item *super) +to_roc_chart (const struct chart *super) { assert (is_roc_chart (super)); - return UP_CAST (super, struct roc_chart, chart_item); + return UP_CAST (super, struct roc_chart, chart); } -/* Returns INSTANCE converted to chart_item. */ -static inline struct chart_item * +/* Returns INSTANCE converted to chart. */ +static inline struct chart * roc_chart_super (const struct roc_chart *instance) { - return CONST_CAST (struct chart_item *, &instance->chart_item); + return CONST_CAST (struct chart *, &instance->chart); } /* Increments INSTANCE's reference count and returns INSTANCE. */ static inline struct roc_chart * roc_chart_ref (const struct roc_chart *instance) { - return to_roc_chart (chart_item_ref (&instance->chart_item)); + return to_roc_chart (chart_ref (&instance->chart)); } /* Decrements INSTANCE's reference count, then destroys INSTANCE if @@ -83,7 +83,7 @@ roc_chart_ref (const struct roc_chart *instance) static inline void roc_chart_unref (struct roc_chart *instance) { - chart_item_unref (&instance->chart_item); + chart_unref (&instance->chart); } /* Returns true if INSTANCE's reference count is greater than 1, @@ -91,13 +91,13 @@ roc_chart_unref (struct roc_chart *instance) static inline bool roc_chart_is_shared (const struct roc_chart *instance) { - return chart_item_is_shared (&instance->chart_item); + return chart_is_shared (&instance->chart); } static inline void roc_chart_submit (struct roc_chart *instance) { - chart_item_submit (&instance->chart_item); + chart_submit (&instance->chart); } #endif /* output/charts/roc-chart.h */ diff --git a/src/output/charts/scatterplot-cairo.c b/src/output/charts/scatterplot-cairo.c index cf62539fab..17307497c7 100644 --- a/src/output/charts/scatterplot-cairo.c +++ b/src/output/charts/scatterplot-cairo.c @@ -31,10 +31,10 @@ static const struct xrchart_colour black = {0,0,0}; void -xrchart_draw_scatterplot (const struct chart_item *chart_item, cairo_t *cr, +xrchart_draw_scatterplot (const struct chart *chart, cairo_t *cr, struct xrchart_geometry *geom) { - const struct scatterplot_chart *spc = to_scatterplot_chart (chart_item); + const struct scatterplot_chart *spc = to_scatterplot_chart (chart); struct casereader *data; struct ccase *c; /* While reading the cases, a list with categories of the byvar is build */ @@ -54,7 +54,7 @@ xrchart_draw_scatterplot (const struct chart_item *chart_item, cairo_t *cr, return; if (! xrchart_write_yscale (cr, geom, spc->y_min, spc->y_max)) return; - xrchart_write_title (cr, geom, _("Scatterplot %s"), chart_item->title); + xrchart_write_title (cr, geom, _("Scatterplot %s"), chart->title); xrchart_write_xlabel (cr, geom, spc->xlabel); xrchart_write_ylabel (cr, geom, spc->ylabel); diff --git a/src/output/charts/scatterplot.c b/src/output/charts/scatterplot.c index 69b53b6751..9c9c42a71e 100644 --- a/src/output/charts/scatterplot.c +++ b/src/output/charts/scatterplot.c @@ -23,7 +23,7 @@ #include "data/casereader.h" #include "data/variable.h" #include "libpspp/cast.h" -#include "output/chart-item-provider.h" +#include "output/chart-provider.h" #include "gl/minmax.h" @@ -40,7 +40,7 @@ scatterplot_create (struct casereader *reader, struct scatterplot_chart *spc; spc = xzalloc (sizeof *spc); - chart_item_init (&spc->chart_item, &scatterplot_chart_class, label); + chart_init (&spc->chart, &scatterplot_chart_class, label); spc->data = reader; spc->y_min = ymin; @@ -59,9 +59,9 @@ scatterplot_create (struct casereader *reader, } static void -scatterplot_chart_destroy (struct chart_item *chart_item) +scatterplot_chart_destroy (struct chart *chart) { - struct scatterplot_chart *spc = to_scatterplot_chart (chart_item); + struct scatterplot_chart *spc = to_scatterplot_chart (chart); casereader_destroy (spc->data); free (spc->xlabel); free (spc->ylabel); @@ -70,7 +70,7 @@ scatterplot_chart_destroy (struct chart_item *chart_item) free (spc); } -const struct chart_item_class scatterplot_chart_class = +const struct chart_class scatterplot_chart_class = { scatterplot_chart_destroy }; diff --git a/src/output/charts/scatterplot.h b/src/output/charts/scatterplot.h index a78227dabc..cf549e9c1d 100644 --- a/src/output/charts/scatterplot.h +++ b/src/output/charts/scatterplot.h @@ -17,7 +17,7 @@ #ifndef OUTPUT_CHARTS_SCATTERPLOT_H #define OUTPUT_CHARTS_SCATTERPLOT_H 1 -#include "output/chart-item.h" +#include "output/chart.h" /* Indices for the scatterplot_proto members */ enum @@ -30,7 +30,7 @@ enum /* A scatterplot. */ struct scatterplot_chart { - struct chart_item chart_item; + struct chart chart; struct casereader *data; struct variable *byvar; char *xlabel; @@ -53,17 +53,17 @@ scatterplot_create (struct casereader *, const char *label, double xmin, double xmax, double ymin, double ymax); -/* This boilerplate for scatterplot_chart, a subclass of chart_item, was +/* This boilerplate for scatterplot_chart, a subclass of chart, was autogenerated by mk-class-boilerplate. */ #include #include "libpspp/cast.h" -extern const struct chart_item_class scatterplot_chart_class; +extern const struct chart_class scatterplot_chart_class; /* Returns true if SUPER is a scatterplot_chart, otherwise false. */ static inline bool -is_scatterplot_chart (const struct chart_item *super) +is_scatterplot_chart (const struct chart *super) { return super->class == &scatterplot_chart_class; } @@ -71,24 +71,24 @@ is_scatterplot_chart (const struct chart_item *super) /* Returns SUPER converted to scatterplot_chart. SUPER must be a scatterplot_chart, as reported by is_scatterplot_chart. */ static inline struct scatterplot_chart * -to_scatterplot_chart (const struct chart_item *super) +to_scatterplot_chart (const struct chart *super) { assert (is_scatterplot_chart (super)); - return UP_CAST (super, struct scatterplot_chart, chart_item); + return UP_CAST (super, struct scatterplot_chart, chart); } -/* Returns INSTANCE converted to chart_item. */ -static inline struct chart_item * +/* Returns INSTANCE converted to chart. */ +static inline struct chart * scatterplot_chart_super (const struct scatterplot_chart *instance) { - return CONST_CAST (struct chart_item *, &instance->chart_item); + return CONST_CAST (struct chart *, &instance->chart); } /* Increments INSTANCE's reference count and returns INSTANCE. */ static inline struct scatterplot_chart * scatterplot_chart_ref (const struct scatterplot_chart *instance) { - return to_scatterplot_chart (chart_item_ref (&instance->chart_item)); + return to_scatterplot_chart (chart_ref (&instance->chart)); } /* Decrements INSTANCE's reference count, then destroys INSTANCE if @@ -96,7 +96,7 @@ scatterplot_chart_ref (const struct scatterplot_chart *instance) static inline void scatterplot_chart_unref (struct scatterplot_chart *instance) { - chart_item_unref (&instance->chart_item); + chart_unref (&instance->chart); } /* Returns true if INSTANCE's reference count is greater than 1, @@ -104,13 +104,13 @@ scatterplot_chart_unref (struct scatterplot_chart *instance) static inline bool scatterplot_chart_is_shared (const struct scatterplot_chart *instance) { - return chart_item_is_shared (&instance->chart_item); + return chart_is_shared (&instance->chart); } static inline void scatterplot_chart_submit (struct scatterplot_chart *instance) { - chart_item_submit (&instance->chart_item); + chart_submit (&instance->chart); } #endif /* output/charts/scatterplot.h */ diff --git a/src/output/charts/scree-cairo.c b/src/output/charts/scree-cairo.c index d203b62eff..726e250856 100644 --- a/src/output/charts/scree-cairo.c +++ b/src/output/charts/scree-cairo.c @@ -26,10 +26,10 @@ #define _(msgid) gettext (msgid) void -xrchart_draw_scree (const struct chart_item *chart_item, cairo_t *cr, +xrchart_draw_scree (const struct chart *chart, cairo_t *cr, struct xrchart_geometry *geom) { - const struct scree *rc = to_scree (chart_item); + const struct scree *rc = to_scree (chart); size_t i; double min, max; diff --git a/src/output/charts/scree.c b/src/output/charts/scree.c index 4de1f5e6fc..049087a47c 100644 --- a/src/output/charts/scree.c +++ b/src/output/charts/scree.c @@ -18,7 +18,7 @@ #include "output/charts/scree.h" -#include "output/chart-item-provider.h" +#include "output/chart-provider.h" #include "gl/xalloc.h" @@ -29,7 +29,7 @@ struct scree * scree_create (const gsl_vector *eigenvalues, const char *xlabel) { struct scree *rc = xmalloc (sizeof *rc); - chart_item_init (&rc->chart_item, &scree_class, NULL); + chart_init (&rc->chart, &scree_class, NULL); rc->eval = gsl_vector_alloc (eigenvalues->size); gsl_vector_memcpy (rc->eval, eigenvalues); @@ -40,16 +40,16 @@ scree_create (const gsl_vector *eigenvalues, const char *xlabel) } static void -scree_destroy (struct chart_item *chart_item) +scree_destroy (struct chart *chart) { - struct scree *rc = to_scree (chart_item); + struct scree *rc = to_scree (chart); gsl_vector_free (rc->eval); free (rc->xlabel); free (rc); } -const struct chart_item_class scree_class = +const struct chart_class scree_class = { scree_destroy }; diff --git a/src/output/charts/scree.h b/src/output/charts/scree.h index 5691451d7c..3475ad17ff 100644 --- a/src/output/charts/scree.h +++ b/src/output/charts/scree.h @@ -18,12 +18,12 @@ #define OUTPUT_CHARTS_SCREE_H 1 #include -#include "output/chart-item.h" +#include "output/chart.h" /* A scree plot. */ struct scree { - struct chart_item chart_item; + struct chart chart; gsl_vector *eval; char *xlabel; }; @@ -34,17 +34,17 @@ struct scree *scree_create (const gsl_vector *eigenvalues, const char *label); /* Return the chart underlying SCREE */ struct chart *scree_get_chart (struct scree *scree); -/* This boilerplate for scree, a subclass of chart_item, was +/* This boilerplate for scree, a subclass of chart, was autogenerated by mk-class-boilerplate. */ #include #include "libpspp/cast.h" -extern const struct chart_item_class scree_class; +extern const struct chart_class scree_class; /* Returns true if SUPER is a scree, otherwise false. */ static inline bool -is_scree (const struct chart_item *super) +is_scree (const struct chart *super) { return super->class == &scree_class; } @@ -52,24 +52,24 @@ is_scree (const struct chart_item *super) /* Returns SUPER converted to scree. SUPER must be a scree, as reported by is_scree. */ static inline struct scree * -to_scree (const struct chart_item *super) +to_scree (const struct chart *super) { assert (is_scree (super)); - return UP_CAST (super, struct scree, chart_item); + return UP_CAST (super, struct scree, chart); } -/* Returns INSTANCE converted to chart_item. */ -static inline struct chart_item * +/* Returns INSTANCE converted to chart. */ +static inline struct chart * scree_super (const struct scree *instance) { - return CONST_CAST (struct chart_item *, &instance->chart_item); + return CONST_CAST (struct chart *, &instance->chart); } /* Increments INSTANCE's reference count and returns INSTANCE. */ static inline struct scree * scree_ref (const struct scree *instance) { - return to_scree (chart_item_ref (&instance->chart_item)); + return to_scree (chart_ref (&instance->chart)); } /* Decrements INSTANCE's reference count, then destroys INSTANCE if @@ -77,7 +77,7 @@ scree_ref (const struct scree *instance) static inline void scree_unref (struct scree *instance) { - chart_item_unref (&instance->chart_item); + chart_unref (&instance->chart); } /* Returns true if INSTANCE's reference count is greater than 1, @@ -85,13 +85,13 @@ scree_unref (struct scree *instance) static inline bool scree_is_shared (const struct scree *instance) { - return chart_item_is_shared (&instance->chart_item); + return chart_is_shared (&instance->chart); } static inline void scree_submit (struct scree *instance) { - chart_item_submit (&instance->chart_item); + chart_submit (&instance->chart); } #endif /* output/charts/scree.h */ diff --git a/src/output/charts/spreadlevel-cairo.c b/src/output/charts/spreadlevel-cairo.c index 7167c4c8e6..815cfe5dd3 100644 --- a/src/output/charts/spreadlevel-cairo.c +++ b/src/output/charts/spreadlevel-cairo.c @@ -26,13 +26,13 @@ #define _(msgid) gettext (msgid) void -xrchart_draw_spreadlevel (const struct chart_item *chart_item, cairo_t *cr, - struct xrchart_geometry *geom) +xrchart_draw_spreadlevel (const struct chart *chart, cairo_t *cr, + struct xrchart_geometry *geom) { - const struct spreadlevel_plot_chart *sl = to_spreadlevel_plot_chart (chart_item); + const struct spreadlevel_plot_chart *sl = to_spreadlevel_plot_chart (chart); size_t i; - const char *name = chart_item_get_title (chart_item); + const char *name = chart_get_title (chart); xrchart_write_title (cr, geom, _("Spread vs. Level Plot of %s"), name); xrchart_write_xlabel (cr, geom, _("Level")); diff --git a/src/output/charts/spreadlevel-plot.c b/src/output/charts/spreadlevel-plot.c index e4fed61786..5fd189d6e0 100644 --- a/src/output/charts/spreadlevel-plot.c +++ b/src/output/charts/spreadlevel-plot.c @@ -19,7 +19,7 @@ #include "output/charts/spreadlevel-plot.h" #include "libpspp/cast.h" -#include "output/chart-item-provider.h" +#include "output/chart-provider.h" #include "gl/xalloc.h" #include "gl/minmax.h" @@ -28,11 +28,11 @@ #include #include -struct chart_item * +struct chart * spreadlevel_plot_create (const char *label, double tx_pwr) { struct spreadlevel_plot_chart *sl = xzalloc (sizeof *sl); - chart_item_init (&sl->chart_item, &spreadlevel_plot_chart_class, label); + chart_init (&sl->chart, &spreadlevel_plot_chart_class, label); sl->x_lower = DBL_MAX; sl->x_upper = -DBL_MAX; @@ -45,11 +45,11 @@ spreadlevel_plot_create (const char *label, double tx_pwr) sl->n_data = 0; sl->data = NULL; - return &sl->chart_item; + return &sl->chart; } void -spreadlevel_plot_add (struct chart_item *ci, double spread, double level) +spreadlevel_plot_add (struct chart *ci, double spread, double level) { struct spreadlevel_plot_chart *sl = to_spreadlevel_plot_chart (ci); @@ -79,15 +79,15 @@ spreadlevel_plot_add (struct chart_item *ci, double spread, double level) static void -spreadlevel_plot_chart_destroy (struct chart_item *chart_item) +spreadlevel_plot_chart_destroy (struct chart *chart) { - struct spreadlevel_plot_chart *sl = to_spreadlevel_plot_chart (chart_item); + struct spreadlevel_plot_chart *sl = to_spreadlevel_plot_chart (chart); free (sl->data); free (sl); } -const struct chart_item_class spreadlevel_plot_chart_class = +const struct chart_class spreadlevel_plot_chart_class = { spreadlevel_plot_chart_destroy }; diff --git a/src/output/charts/spreadlevel-plot.h b/src/output/charts/spreadlevel-plot.h index b7c8c354a1..b0029f6a84 100644 --- a/src/output/charts/spreadlevel-plot.h +++ b/src/output/charts/spreadlevel-plot.h @@ -17,7 +17,8 @@ #ifndef OUTPUT_CHARTS_SL_PLOT_H #define OUTPUT_CHARTS_SL_PLOT_H 1 -#include "output/chart-item.h" +#include "output/chart.h" +#include struct datum { @@ -27,7 +28,7 @@ struct datum struct spreadlevel_plot_chart { - struct chart_item chart_item; + struct chart chart; /* Calculated parameters */ double y_lower, y_upper; @@ -39,23 +40,23 @@ struct spreadlevel_plot_chart struct datum *data; }; -struct chart_item *spreadlevel_plot_create (const char *label, double slp); +struct chart *spreadlevel_plot_create (const char *label, double slp); -void spreadlevel_plot_add (struct chart_item *, double spread, double level); +void spreadlevel_plot_add (struct chart *, double spread, double level); -/* This boilerplate for spreadlevel_plot_chart, a subclass of chart_item, was +/* This boilerplate for spreadlevel_plot_chart, a subclass of chart, was autogenerated by mk-class-boilerplate. */ #include #include "libpspp/cast.h" -extern const struct chart_item_class spreadlevel_plot_chart_class; +extern const struct chart_class spreadlevel_plot_chart_class; /* Returns true if SUPER is a spreadlevel_plot_chart, otherwise false. */ static inline bool -is_spreadlevel_plot_chart (const struct chart_item *super) +is_spreadlevel_plot_chart (const struct chart *super) { return super->class == &spreadlevel_plot_chart_class; } @@ -63,24 +64,24 @@ is_spreadlevel_plot_chart (const struct chart_item *super) /* Returns SUPER converted to spreadlevel_plot_chart. SUPER must be a spreadlevel_plot_chart, as reported by is_spreadlevel_plot_chart. */ static inline struct spreadlevel_plot_chart * -to_spreadlevel_plot_chart (const struct chart_item *super) +to_spreadlevel_plot_chart (const struct chart *super) { assert (is_spreadlevel_plot_chart (super)); - return UP_CAST (super, struct spreadlevel_plot_chart, chart_item); + return UP_CAST (super, struct spreadlevel_plot_chart, chart); } -/* Returns INSTANCE converted to chart_item. */ -static inline struct chart_item * +/* Returns INSTANCE converted to chart. */ +static inline struct chart * spreadlevel_plot_chart_super (const struct spreadlevel_plot_chart *instance) { - return CONST_CAST (struct chart_item *, &instance->chart_item); + return CONST_CAST (struct chart *, &instance->chart); } /* Increments INSTANCE's reference count and returns INSTANCE. */ static inline struct spreadlevel_plot_chart * spreadlevel_plot_chart_ref (const struct spreadlevel_plot_chart *instance) { - return to_spreadlevel_plot_chart (chart_item_ref (&instance->chart_item)); + return to_spreadlevel_plot_chart (chart_ref (&instance->chart)); } /* Decrements INSTANCE's reference count, then destroys INSTANCE if @@ -88,7 +89,7 @@ spreadlevel_plot_chart_ref (const struct spreadlevel_plot_chart *instance) static inline void spreadlevel_plot_chart_unref (struct spreadlevel_plot_chart *instance) { - chart_item_unref (&instance->chart_item); + chart_unref (&instance->chart); } /* Returns true if INSTANCE's reference count is greater than 1, @@ -96,13 +97,13 @@ spreadlevel_plot_chart_unref (struct spreadlevel_plot_chart *instance) static inline bool spreadlevel_plot_chart_is_shared (const struct spreadlevel_plot_chart *instance) { - return chart_item_is_shared (&instance->chart_item); + return chart_is_shared (&instance->chart); } static inline void spreadlevel_plot_chart_submit (struct spreadlevel_plot_chart *instance) { - chart_item_submit (&instance->chart_item); + chart_submit (&instance->chart); } #endif diff --git a/src/output/csv.c b/src/output/csv.c index dd8296059d..a34282e012 100644 --- a/src/output/csv.c +++ b/src/output/csv.c @@ -26,14 +26,11 @@ #include "libpspp/message.h" #include "libpspp/str.h" #include "libpspp/string-map.h" -#include "output/text-item.h" #include "output/driver-provider.h" #include "output/options.h" -#include "output/message-item.h" -#include "output/page-break-item.h" +#include "output/output-item.h" #include "output/pivot-output.h" #include "output/pivot-table.h" -#include "output/table-item.h" #include "output/table-provider.h" #include "gl/minmax.h" @@ -239,45 +236,59 @@ csv_output_table_layer (struct csv_driver *csv, const struct pivot_table *pt, static void csv_submit (struct output_driver *driver, - const struct output_item *output_item) + const struct output_item *item) { struct csv_driver *csv = csv_driver_cast (driver); - if (is_table_item (output_item)) + switch (item->type) { - const struct pivot_table *pt = to_table_item (output_item)->pt; + case OUTPUT_ITEM_CHART: + break; - size_t *layer_indexes; - PIVOT_OUTPUT_FOR_EACH_LAYER (layer_indexes, pt, true) - csv_output_table_layer (csv, pt, layer_indexes); - } - else if (is_text_item (output_item)) - { - const struct text_item *text_item = to_text_item (output_item); + case OUTPUT_ITEM_GROUP_OPEN: + break; - enum text_item_type type = text_item_get_type (text_item); - if (type == TEXT_ITEM_SYNTAX || type == TEXT_ITEM_PAGE_TITLE) - return; + case OUTPUT_ITEM_GROUP_CLOSE: + break; - csv_put_separator (csv); + case OUTPUT_ITEM_IMAGE: + break; - char *text = text_item_get_plain_text (text_item); - csv_output_lines (csv, text); - free (text); - } - else if (is_page_break_item (output_item)) - { - csv_put_separator (csv); - csv_output_lines (csv, ""); - } - else if (is_message_item (output_item)) - { - const struct message_item *message_item = to_message_item (output_item); - char *s = msg_to_string (message_item_get_msg (message_item)); + case OUTPUT_ITEM_MESSAGE: csv_put_separator (csv); + char *s = msg_to_string (item->message); csv_output_field (csv, s); free (s); putc ('\n', csv->file); + break; + + case OUTPUT_ITEM_PAGE_BREAK: + csv_put_separator (csv); + csv_output_lines (csv, ""); + break; + + case OUTPUT_ITEM_PAGE_SETUP: + break; + + case OUTPUT_ITEM_TABLE: + { + size_t *layer_indexes; + PIVOT_OUTPUT_FOR_EACH_LAYER (layer_indexes, item->table, true) + csv_output_table_layer (csv, item->table, layer_indexes); + } + break; + + case OUTPUT_ITEM_TEXT: + if (item->text.subtype == TEXT_ITEM_SYNTAX + || item->text.subtype == TEXT_ITEM_PAGE_TITLE) + return; + + csv_put_separator (csv); + + char *text = text_item_get_plain_text (item); + csv_output_lines (csv, text); + free (text); + break; } } diff --git a/src/output/driver.c b/src/output/driver.c index 6c4fd414cb..6f5d4633ce 100644 --- a/src/output/driver.c +++ b/src/output/driver.c @@ -36,10 +36,7 @@ #include "libpspp/string-map.h" #include "libpspp/string-set.h" #include "libpspp/str.h" -#include "output/group-item.h" -#include "output/message-item.h" #include "output/output-item.h" -#include "output/text-item.h" #include "gl/error.h" #include "gl/xalloc.h" @@ -52,7 +49,7 @@ struct output_engine { struct ll ll; /* Node for this engine. */ struct llx_list drivers; /* Contains "struct output_driver"s. */ - struct text_item *deferred_text; /* Output text being accumulated. */ + struct output_item *deferred_text; /* Output text being accumulated. */ char *command_name; /* Name of command being processed. */ char *title, *subtitle; /* Components of page title. */ @@ -120,7 +117,7 @@ output_engine_pop (void) struct output_driver *d = llx_pop_head (&e->drivers, &llx_malloc_mgr); output_driver_destroy (d); } - text_item_unref (e->deferred_text); + output_item_unref (e->deferred_text); free (e->command_name); free (e->title); free (e->subtitle); @@ -148,23 +145,32 @@ output_submit__ (struct output_engine *e, struct output_item *item) for (llx = llx_head (&e->drivers); llx != llx_null (&e->drivers); llx = next) { struct output_driver *d = llx_data (llx); - enum settings_output_type type; next = llx_next (llx); - if (is_message_item (item)) + enum settings_output_type type = SETTINGS_OUTPUT_RESULT; + switch (item->type) { - const struct msg *m = message_item_get_msg (to_message_item (item)); - if (m->severity == MSG_S_NOTE) - type = SETTINGS_OUTPUT_NOTE; - else - type = SETTINGS_OUTPUT_ERROR; + case OUTPUT_ITEM_MESSAGE: + type = (item->message->severity == MSG_S_NOTE + ? SETTINGS_OUTPUT_NOTE + : SETTINGS_OUTPUT_ERROR); + break; + + case OUTPUT_ITEM_TEXT: + if (item->text.subtype == TEXT_ITEM_SYNTAX) + type = SETTINGS_OUTPUT_SYNTAX; + break; + + case OUTPUT_ITEM_CHART: + case OUTPUT_ITEM_GROUP_OPEN: + case OUTPUT_ITEM_GROUP_CLOSE: + case OUTPUT_ITEM_IMAGE: + case OUTPUT_ITEM_PAGE_BREAK: + case OUTPUT_ITEM_PAGE_SETUP: + case OUTPUT_ITEM_TABLE: + break; } - else if (is_text_item (item) - && text_item_get_type (to_text_item (item)) == TEXT_ITEM_SYNTAX) - type = SETTINGS_OUTPUT_SYNTAX; - else - type = SETTINGS_OUTPUT_RESULT; if (settings_get_output_routing (type) & d->device_type) d->class->submit (d, item); @@ -176,29 +182,28 @@ output_submit__ (struct output_engine *e, struct output_item *item) static void flush_deferred_text (struct output_engine *e) { - struct text_item *deferred_text = e->deferred_text; + struct output_item *deferred_text = e->deferred_text; if (deferred_text) { e->deferred_text = NULL; - output_submit__ (e, text_item_super (deferred_text)); + output_submit__ (e, deferred_text); } } static bool -defer_text (struct output_engine *e, struct output_item *output_item) +defer_text (struct output_engine *e, struct output_item *item) { - if (!is_text_item (output_item)) + if (item->type != OUTPUT_ITEM_TEXT) return false; - struct text_item *text = to_text_item (output_item); if (!e->deferred_text) - e->deferred_text = text_item_unshare (text); - else if (text_item_append (e->deferred_text, text)) - text_item_unref (text); + e->deferred_text = output_item_unshare (item); + else if (text_item_append (e->deferred_text, item)) + output_item_unref (item); else { flush_deferred_text (e); - e->deferred_text = text_item_unshare (text); + e->deferred_text = output_item_unshare (item); } return true; } @@ -220,19 +225,17 @@ output_submit (struct output_item *item) return; flush_deferred_text (e); - if (is_group_open_item (item)) + switch (item->type) { - const struct group_open_item *group_open_item - = to_group_open_item (item); + case OUTPUT_ITEM_GROUP_OPEN: if (e->n_groups >= e->allocated_groups) e->groups = x2nrealloc (e->groups, &e->allocated_groups, sizeof *e->groups); - e->groups[e->n_groups] = xstrdup_if_nonnull ( - group_open_item->output_item.command_name); + e->groups[e->n_groups] = xstrdup_if_nonnull (item->command_name); e->n_groups++; - } - else if (is_group_close_item (item)) - { + break; + + case OUTPUT_ITEM_GROUP_CLOSE: assert (e->n_groups > 0); size_t idx = --e->n_groups; @@ -241,17 +244,27 @@ output_submit (struct output_item *item) char *key = xasprintf ("Head%zu", idx); free (string_map_find_and_delete (&e->heading_vars, key)); free (key); - } - else if (is_text_item (item)) - { - const struct text_item *text_item = to_text_item (item); - enum text_item_type type = text_item_get_type (text_item); - char *key = (type == TEXT_ITEM_TITLE ? xasprintf ("Head%zu", e->n_groups) - : type == TEXT_ITEM_PAGE_TITLE ? xstrdup ("PageTitle") - : NULL); - if (key) - string_map_replace_nocopy (&e->heading_vars, key, - text_item_get_plain_text (text_item)); + break; + + case OUTPUT_ITEM_TEXT: + { + enum text_item_subtype st = item->text.subtype; + char *key = (st == TEXT_ITEM_TITLE ? xasprintf ("Head%zu", e->n_groups) + : st == TEXT_ITEM_PAGE_TITLE ? xstrdup ("PageTitle") + : NULL); + if (key) + string_map_replace_nocopy (&e->heading_vars, key, + text_item_get_plain_text (item)); + } + break; + + case OUTPUT_ITEM_CHART: + case OUTPUT_ITEM_IMAGE: + case OUTPUT_ITEM_MESSAGE: + case OUTPUT_ITEM_PAGE_BREAK: + case OUTPUT_ITEM_PAGE_SETUP: + case OUTPUT_ITEM_TABLE: + break; } output_submit__ (e, item); @@ -309,8 +322,8 @@ output_set_title__ (struct output_engine *e, char **dst, const char *src) : e->title ? xstrdup (e->title) : e->subtitle ? xstrdup (e->subtitle) : xzalloc (1)); - text_item_submit (text_item_create_nocopy (TEXT_ITEM_PAGE_TITLE, - page_title, NULL)); + output_item_submit (text_item_create_nocopy (TEXT_ITEM_PAGE_TITLE, + page_title, NULL)); } void diff --git a/src/output/group-item.c b/src/output/group-item.c deleted file mode 100644 index c0aad17d9f..0000000000 --- a/src/output/group-item.c +++ /dev/null @@ -1,122 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2018 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include "output/group-item.h" - -#include - -#include "libpspp/compiler.h" -#include "libpspp/str.h" -#include "output/driver.h" -#include "output/output-item-provider.h" - -#include "gl/xalloc.h" - -#include "gettext.h" -#define _(msgid) gettext (msgid) - -struct group_open_item * -group_open_item_create (const char *command_name, const char *label) -{ - return group_open_item_create_nocopy ( - xstrdup_if_nonnull (command_name), - xstrdup_if_nonnull (label)); -} - -struct group_open_item * -group_open_item_create_nocopy (char *command_name, char *label) -{ - struct group_open_item *item = xmalloc (sizeof *item); - *item = (struct group_open_item) { - .output_item = OUTPUT_ITEM_INITIALIZER (&group_open_item_class), - .output_item.label = label, - .output_item.command_name = command_name, - }; - return item; -} - -/* Submits ITEM to the configured output drivers, and transfers ownership to - the output subsystem. */ -void -group_open_item_submit (struct group_open_item *item) -{ - output_submit (&item->output_item); -} - -static const char * -group_open_item_get_label (const struct output_item *output_item) -{ - struct group_open_item *item = to_group_open_item (output_item); - - return (item->output_item.command_name - ? item->output_item.command_name - : _("Group")); -} - -static void -group_open_item_destroy (struct output_item *output_item) -{ - struct group_open_item *item = to_group_open_item (output_item); - - free (item); -} - -const struct output_item_class group_open_item_class = - { - group_open_item_get_label, - group_open_item_destroy, - }; - -struct group_close_item * -group_close_item_create (void) -{ - struct group_close_item *item = xmalloc (sizeof *item); - *item = (struct group_close_item) { - .output_item = OUTPUT_ITEM_INITIALIZER (&group_close_item_class), - }; - return item; -} - -/* Submits ITEM to the configured output drivers, and transfers ownership to - the output subsystem. */ -void -group_close_item_submit (struct group_close_item *item) -{ - output_submit (&item->output_item); -} - -static const char * -group_close_item_get_label (const struct output_item *output_item UNUSED) -{ - /* Not marked for translation: user should never see it. */ - return "Group Close"; -} - -static void -group_close_item_destroy (struct output_item *output_item) -{ - struct group_close_item *item = to_group_close_item (output_item); - - free (item); -} - -const struct output_item_class group_close_item_class = - { - group_close_item_get_label, - group_close_item_destroy, - }; diff --git a/src/output/group-item.h b/src/output/group-item.h deleted file mode 100644 index b8ac464c3d..0000000000 --- a/src/output/group-item.h +++ /dev/null @@ -1,158 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2018 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef OUTPUT_GROUP_ITEM_H -#define OUTPUT_GROUP_ITEM_H 1 - -/* Grouping items. - - A group-open item marks the beginning of a group of related output items. A - later group-close item ends the group. Groups can nest. */ - -#include -#include "output/output-item.h" - -/* A group_open item. */ -struct group_open_item - { - struct output_item output_item; - }; - -struct group_open_item *group_open_item_create (const char *command_name, - const char *label); -struct group_open_item *group_open_item_create_nocopy (char *command_name, - char *label); - -/* A group_close item. */ -struct group_close_item - { - struct output_item output_item; - }; -struct group_close_item *group_close_item_create (void); - -/* This boilerplate for group_open_item, a subclass of output_item, was - autogenerated by mk-class-boilerplate. */ - -#include -#include "libpspp/cast.h" - -extern const struct output_item_class group_open_item_class; - -/* Returns true if SUPER is a group_open_item, otherwise false. */ -static inline bool -is_group_open_item (const struct output_item *super) -{ - return super->class == &group_open_item_class; -} - -/* Returns SUPER converted to group_open_item. SUPER must be a - group_open_item, as reported by is_group_open_item. */ -static inline struct group_open_item * -to_group_open_item (const struct output_item *super) -{ - assert (is_group_open_item (super)); - return UP_CAST (super, struct group_open_item, output_item); -} - -/* Returns INSTANCE converted to output_item. */ -static inline struct output_item * -group_open_item_super (const struct group_open_item *instance) -{ - return CONST_CAST (struct output_item *, &instance->output_item); -} - -/* Increments INSTANCE's reference count and returns INSTANCE. */ -static inline struct group_open_item * -group_open_item_ref (const struct group_open_item *instance) -{ - return to_group_open_item (output_item_ref (&instance->output_item)); -} - -/* Decrements INSTANCE's reference count, then destroys INSTANCE if - the reference count is now zero. */ -static inline void -group_open_item_unref (struct group_open_item *instance) -{ - output_item_unref (&instance->output_item); -} - -/* Returns true if INSTANCE's reference count is greater than 1, - false otherwise. */ -static inline bool -group_open_item_is_shared (const struct group_open_item *instance) -{ - return output_item_is_shared (&instance->output_item); -} - -void group_open_item_submit (struct group_open_item *); - -/* This boilerplate for group_close_item, a subclass of output_item, was - autogenerated by mk-class-boilerplate. */ - -#include -#include "libpspp/cast.h" - -extern const struct output_item_class group_close_item_class; - -/* Returns true if SUPER is a group_close_item, otherwise false. */ -static inline bool -is_group_close_item (const struct output_item *super) -{ - return super->class == &group_close_item_class; -} - -/* Returns SUPER converted to group_close_item. SUPER must be a - group_close_item, as reported by is_group_close_item. */ -static inline struct group_close_item * -to_group_close_item (const struct output_item *super) -{ - assert (is_group_close_item (super)); - return UP_CAST (super, struct group_close_item, output_item); -} - -/* Returns INSTANCE converted to output_item. */ -static inline struct output_item * -group_close_item_super (const struct group_close_item *instance) -{ - return CONST_CAST (struct output_item *, &instance->output_item); -} - -/* Increments INSTANCE's reference count and returns INSTANCE. */ -static inline struct group_close_item * -group_close_item_ref (const struct group_close_item *instance) -{ - return to_group_close_item (output_item_ref (&instance->output_item)); -} - -/* Decrements INSTANCE's reference count, then destroys INSTANCE if - the reference count is now zero. */ -static inline void -group_close_item_unref (struct group_close_item *instance) -{ - output_item_unref (&instance->output_item); -} - -/* Returns true if INSTANCE's reference count is greater than 1, - false otherwise. */ -static inline bool -group_close_item_is_shared (const struct group_close_item *instance) -{ - return output_item_is_shared (&instance->output_item); -} - -void group_close_item_submit (struct group_close_item *); - -#endif /* output/group-item.h */ diff --git a/src/output/html.c b/src/output/html.c index 0be011d128..dcff0af085 100644 --- a/src/output/html.c +++ b/src/output/html.c @@ -34,17 +34,13 @@ #include "libpspp/message.h" #include "libpspp/version.h" #include "output/cairo-chart.h" -#include "output/chart-item.h" +#include "output/chart.h" #include "output/driver-provider.h" -#include "output/image-item.h" -#include "output/message-item.h" #include "output/options.h" -#include "output/output-item-provider.h" +#include "output/output-item.h" #include "output/pivot-output.h" #include "output/pivot-table.h" #include "output/table-provider.h" -#include "output/table-item.h" -#include "output/text-item.h" #include "gl/minmax.h" #include "gl/xalloc.h" @@ -74,7 +70,8 @@ struct html_driver static const struct output_driver_class html_driver_class; -static void html_output_table (struct html_driver *, const struct table_item *); +static void html_output_table (struct html_driver *, + const struct output_item *); static void escape_string (FILE *file, const char *text, const char *space, const char *newline); static void print_title_tag (FILE *file, const char *name, @@ -250,86 +247,101 @@ html_destroy (struct output_driver *driver) } static void -html_submit (struct output_driver *driver, - const struct output_item *output_item) +html_submit (struct output_driver *driver, const struct output_item *item) { struct html_driver *html = html_driver_cast (driver); - if (is_table_item (output_item)) + switch (item->type) { - struct table_item *table_item = to_table_item (output_item); - html_output_table (html, table_item); - } - else if (is_image_item (output_item) && html->chart_file_name != NULL) - { - struct image_item *image_item = to_image_item (output_item); - char *file_name = xr_write_png_image ( - image_item->image, html->chart_file_name, ++html->chart_cnt); - if (file_name != NULL) - { - fprintf (html->file, "", file_name); - free (file_name); - } - } - else if (is_chart_item (output_item) && html->chart_file_name != NULL) - { - struct chart_item *chart_item = to_chart_item (output_item); - char *file_name; - - file_name = xr_draw_png_chart (chart_item, html->chart_file_name, - html->chart_cnt++, - &html->fg, - &html->bg - ); - if (file_name != NULL) + case OUTPUT_ITEM_CHART: + if (html->chart_file_name) { - const char *title = chart_item_get_title (chart_item); - fprintf (html->file, "\"chart:", - file_name, title ? title : _("No description")); - free (file_name); + char *file_name = xr_draw_png_chart (item->chart, + html->chart_file_name, + html->chart_cnt++, + &html->fg, &html->bg); + if (file_name != NULL) + { + const char *title = chart_get_title (item->chart); + fprintf (html->file, "\"chart:", + file_name, title ? title : _("No description")); + free (file_name); + } } - } - else if (is_text_item (output_item)) - { - struct text_item *text_item = to_text_item (output_item); - char *s = text_item_get_plain_text (text_item); - - switch (text_item_get_type (text_item)) - { - case TEXT_ITEM_PAGE_TITLE: - break; + break; - case TEXT_ITEM_TITLE: - { - int level = MIN (5, output_get_group_level ()) + 1; - char tag[3] = { 'H', level + '1', '\0' }; - print_title_tag (html->file, tag, s); - } - break; + case OUTPUT_ITEM_GROUP_OPEN: + break; - case TEXT_ITEM_SYNTAX: - fprintf (html->file, "
");
-          escape_string (html->file, s, " ", "
"); - fprintf (html->file, "
\n"); - break; + case OUTPUT_ITEM_GROUP_CLOSE: + break; - case TEXT_ITEM_LOG: - fprintf (html->file, "

"); - escape_string (html->file, s, " ", "
"); - fprintf (html->file, "

\n"); - break; + case OUTPUT_ITEM_IMAGE: + if (html->chart_file_name) + { + char *file_name = xr_write_png_image ( + item->image, html->chart_file_name, ++html->chart_cnt); + if (file_name != NULL) + { + fprintf (html->file, "", file_name); + free (file_name); + } } + break; - free (s); - } - else if (is_message_item (output_item)) - { - const struct message_item *message_item = to_message_item (output_item); - char *s = msg_to_string (message_item_get_msg (message_item)); + case OUTPUT_ITEM_MESSAGE: fprintf (html->file, "

"); + + char *s = msg_to_string (item->message); escape_string (html->file, s, " ", "
"); - fprintf (html->file, "

\n"); free (s); + + fprintf (html->file, "

\n"); + break; + + case OUTPUT_ITEM_PAGE_BREAK: + break; + + case OUTPUT_ITEM_PAGE_SETUP: + break; + + case OUTPUT_ITEM_TABLE: + html_output_table (html, item); + break; + + case OUTPUT_ITEM_TEXT: + { + char *s = text_item_get_plain_text (item); + + switch (item->text.subtype) + { + case TEXT_ITEM_PAGE_TITLE: + break; + + case TEXT_ITEM_TITLE: + { + int level = MIN (5, output_get_group_level ()) + 1; + char tag[3] = { 'H', level + '1', '\0' }; + print_title_tag (html->file, tag, s); + } + break; + + case TEXT_ITEM_SYNTAX: + fprintf (html->file, "
");
+            escape_string (html->file, s, " ", "
"); + fprintf (html->file, "
\n"); + break; + + case TEXT_ITEM_LOG: + fprintf (html->file, "

"); + escape_string (html->file, s, " ", "
"); + fprintf (html->file, "

\n"); + break; + } + + free (s); + } + break; } } @@ -716,11 +728,11 @@ html_output_table_layer (struct html_driver *html, const struct pivot_table *pt, } static void -html_output_table (struct html_driver *html, const struct table_item *item) +html_output_table (struct html_driver *html, const struct output_item *item) { size_t *layer_indexes; - PIVOT_OUTPUT_FOR_EACH_LAYER (layer_indexes, item->pt, true) - html_output_table_layer (html, item->pt, layer_indexes); + PIVOT_OUTPUT_FOR_EACH_LAYER (layer_indexes, item->table, true) + html_output_table_layer (html, item->table, layer_indexes); } struct output_driver_factory html_driver_factory = diff --git a/src/output/image-item.c b/src/output/image-item.c deleted file mode 100644 index 371578ba22..0000000000 --- a/src/output/image-item.c +++ /dev/null @@ -1,87 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2020 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include "output/image-item.h" - -#include -#include - -#include "libpspp/cast.h" -#include "libpspp/compiler.h" -#include "output/driver.h" -#include "output/output-item-provider.h" - -#include "gl/xalloc.h" -#include "gl/xvasprintf.h" - -/* Creates and returns a new image item containing IMAGE. Takes ownership of - IMAGE. */ -struct image_item * -image_item_create (cairo_surface_t *image) -{ - struct image_item *item = xmalloc (sizeof *item); - *item = (struct image_item) { - .output_item = OUTPUT_ITEM_INITIALIZER (&image_item_class), - .image = image, - }; - return item; -} - -/* Submits ITEM to the configured output drivers, and transfers ownership to - the output subsystem. */ -void -image_item_submit (struct image_item *item) -{ - output_submit (&item->output_item); -} - -struct image_item * -image_item_unshare (struct image_item *old) -{ - assert (old->output_item.ref_cnt > 0); - if (!image_item_is_shared (old)) - return old; - image_item_unref (old); - - struct image_item *new = xmalloc (sizeof *new); - *new = (struct image_item) { - .output_item = OUTPUT_ITEM_CLONE_INITIALIZER (&old->output_item), - .image = cairo_surface_reference (old->image), - }; - return new; -} - -static const char * -image_item_get_label (const struct output_item *output_item UNUSED) -{ - return "Image"; -} - -static void -image_item_destroy (struct output_item *output_item) -{ - struct image_item *item = to_image_item (output_item); - cairo_surface_destroy (item->image); - free (item); -} - -const struct output_item_class image_item_class = - { - image_item_get_label, - image_item_destroy, - }; diff --git a/src/output/image-item.h b/src/output/image-item.h deleted file mode 100644 index 4cb3614ba4..0000000000 --- a/src/output/image-item.h +++ /dev/null @@ -1,89 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2020 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef OUTPUT_IMAGE_ITEM_H -#define OUTPUT_IMAGE_ITEM_H 1 - -#include -#include -#include "output/output-item.h" - -struct image_item - { - struct output_item output_item; /* Superclass */ - cairo_surface_t *image; - }; - -struct image_item *image_item_create (cairo_surface_t *); -struct image_item *image_item_unshare (struct image_item *); - -/* This boilerplate for image_item, a subclass of output_item, was - autogenerated by mk-class-boilerplate. */ - -#include -#include "libpspp/cast.h" - -extern const struct output_item_class image_item_class; - -/* Returns true if SUPER is a image_item, otherwise false. */ -static inline bool -is_image_item (const struct output_item *super) -{ - return super->class == &image_item_class; -} - -/* Returns SUPER converted to image_item. SUPER must be a image_item, as - reported by is_image_item. */ -static inline struct image_item * -to_image_item (const struct output_item *super) -{ - assert (is_image_item (super)); - return UP_CAST (super, struct image_item, output_item); -} - -/* Returns INSTANCE converted to output_item. */ -static inline struct output_item * -image_item_super (const struct image_item *instance) -{ - return CONST_CAST (struct output_item *, &instance->output_item); -} - -/* Increments INSTANCE's reference count and returns INSTANCE. */ -static inline struct image_item * -image_item_ref (const struct image_item *instance) -{ - return to_image_item (output_item_ref (&instance->output_item)); -} - -/* Decrements INSTANCE's reference count, then destroys INSTANCE if - the reference count is now zero. */ -static inline void -image_item_unref (struct image_item *instance) -{ - output_item_unref (&instance->output_item); -} - -/* Returns true if INSTANCE's reference count is greater than 1, - false otherwise. */ -static inline bool -image_item_is_shared (const struct image_item *instance) -{ - return output_item_is_shared (&instance->output_item); -} - -void image_item_submit (struct image_item *); - -#endif /* output/image-item.h */ diff --git a/src/output/journal.c b/src/output/journal.c index f93ed0bc84..2dd1925843 100644 --- a/src/output/journal.c +++ b/src/output/journal.c @@ -28,8 +28,7 @@ #include "libpspp/message.h" #include "libpspp/str.h" #include "output/driver-provider.h" -#include "output/message-item.h" -#include "output/text-item.h" +#include "output/output-item.h" #include "gl/fwriteerror.h" #include "gl/xalloc.h" @@ -85,17 +84,19 @@ journal_destroy (struct output_driver *driver) } static void -journal_output (struct journal_driver *j, const char *s) +journal_output (struct journal_driver *j, char *s) { - if (j->file == NULL) - return; + if (j->file) + { + fprintf (j->file, "%s\n", s); - fprintf (j->file, "%s\n", s); + /* Flush the journal in case the syntax we're about to write + causes a crash. Having the syntax already written to disk + makes postmortem analysis of the problem possible. */ + fflush (j->file); + } - /* Flush the journal in case the syntax we're about to write - causes a crash. Having the syntax already written to disk - makes postmortem analysis of the problem possible. */ - fflush (j->file); + free (s); } static void @@ -103,24 +104,25 @@ journal_submit (struct output_driver *driver, const struct output_item *item) { struct journal_driver *j = journal_driver_cast (driver); - if (is_text_item (item)) - { - const struct text_item *text_item = to_text_item (item); - enum text_item_type type = text_item_get_type (text_item); - - if (type == TEXT_ITEM_SYNTAX) - { - char *text = text_item_get_plain_text (text_item); - journal_output (j, text); - free (text); - } - } - else if (is_message_item (item)) + switch (item->type) { - const struct message_item *message_item = to_message_item (item); - char *s = msg_to_string (message_item_get_msg (message_item)); - journal_output (j, s); - free (s); + case OUTPUT_ITEM_MESSAGE: + journal_output (j, msg_to_string (item->message)); + break; + + case OUTPUT_ITEM_TEXT: + if (item->text.subtype == TEXT_ITEM_SYNTAX) + journal_output (j, text_item_get_plain_text (item)); + break; + + case OUTPUT_ITEM_CHART: + case OUTPUT_ITEM_GROUP_OPEN: + case OUTPUT_ITEM_GROUP_CLOSE: + case OUTPUT_ITEM_IMAGE: + case OUTPUT_ITEM_PAGE_BREAK: + case OUTPUT_ITEM_PAGE_SETUP: + case OUTPUT_ITEM_TABLE: + break; } } diff --git a/src/output/message-item.c b/src/output/message-item.c deleted file mode 100644 index e834d5a7b2..0000000000 --- a/src/output/message-item.c +++ /dev/null @@ -1,91 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2010 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include "output/message-item.h" - -#include - -#include "libpspp/i18n.h" -#include "libpspp/message.h" -#include "output/driver.h" -#include "output/output-item-provider.h" -#include "output/text-item.h" - -#include "gl/xalloc.h" - -#include "gettext.h" -#define _(msgid) gettext (msgid) - -struct message_item * -message_item_create (const struct msg *msg) -{ - struct message_item *item = xmalloc (sizeof *msg); - *item = (struct message_item) { - .output_item = OUTPUT_ITEM_INITIALIZER (&message_item_class), - .msg = msg_dup (msg) - }; - return item; -} - -const struct msg * -message_item_get_msg (const struct message_item *item) -{ - return item->msg; -} - -struct text_item * -message_item_to_text_item (struct message_item *message_item) -{ - struct text_item *text_item = text_item_create_nocopy ( - TEXT_ITEM_LOG, - msg_to_string (message_item_get_msg (message_item)), - xstrdup (output_item_get_label (message_item_super (message_item)))); - message_item_unref (message_item); - return text_item; -} - -static const char * -message_item_get_label (const struct output_item *output_item) -{ - const struct message_item *item = to_message_item (output_item); - return (item->msg->severity == MSG_S_ERROR ? _("Error") - : item->msg->severity == MSG_S_WARNING ? _("Warning") - : _("Note")); -} - -static void -message_item_destroy (struct output_item *output_item) -{ - struct message_item *item = to_message_item (output_item); - msg_destroy (item->msg); - free (item); -} - -/* Submits ITEM to the configured output drivers, and transfers ownership to - the output subsystem. */ -void -message_item_submit (struct message_item *item) -{ - output_submit (&item->output_item); -} - -const struct output_item_class message_item_class = - { - message_item_get_label, - message_item_destroy, - }; diff --git a/src/output/message-item.h b/src/output/message-item.h deleted file mode 100644 index dca7e7d21a..0000000000 --- a/src/output/message-item.h +++ /dev/null @@ -1,103 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2010, 2011 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef OUTPUT_MESSAGE_ITEM_H -#define OUTPUT_MESSAGE_ITEM_H 1 - -/* Message items. - - A message item is a subclass of an output item (see - output/output-item.h). - - A message item is an error, warning, or note to the user. - - Message items should not be submitted directly to the output subsystem. - Instead, use the msg() function in libpspp/message.h, which will ensure that - the message gets routed properly for the PSPP user interface in use. */ - -#include -#include "output/output-item.h" - -/* A message item. */ -struct message_item - { - struct output_item output_item; - struct msg *msg; - }; - -struct message_item *message_item_create (const struct msg *); - -const struct msg *message_item_get_msg (const struct message_item *); - -struct text_item *message_item_to_text_item (struct message_item *); - -/* This boilerplate for message_item, a subclass of output_item, was - autogenerated by mk-class-boilerplate. */ - -#include -#include "libpspp/cast.h" - -extern const struct output_item_class message_item_class; - -/* Returns true if SUPER is a message_item, otherwise false. */ -static inline bool -is_message_item (const struct output_item *super) -{ - return super->class == &message_item_class; -} - -/* Returns SUPER converted to message_item. SUPER must be a message_item, as - reported by is_message_item. */ -static inline struct message_item * -to_message_item (const struct output_item *super) -{ - assert (is_message_item (super)); - return UP_CAST (super, struct message_item, output_item); -} - -/* Returns INSTANCE converted to output_item. */ -static inline struct output_item * -message_item_super (const struct message_item *instance) -{ - return CONST_CAST (struct output_item *, &instance->output_item); -} - -/* Increments INSTANCE's reference count and returns INSTANCE. */ -static inline struct message_item * -message_item_ref (const struct message_item *instance) -{ - return to_message_item (output_item_ref (&instance->output_item)); -} - -/* Decrements INSTANCE's reference count, then destroys INSTANCE if - the reference count is now zero. */ -static inline void -message_item_unref (struct message_item *instance) -{ - output_item_unref (&instance->output_item); -} - -/* Returns true if INSTANCE's reference count is greater than 1, - false otherwise. */ -static inline bool -message_item_is_shared (const struct message_item *instance) -{ - return output_item_is_shared (&instance->output_item); -} - -void message_item_submit (struct message_item *); - -#endif /* output/message-item.h */ diff --git a/src/output/msglog.c b/src/output/msglog.c index ef2cf6b007..f91c7e6117 100644 --- a/src/output/msglog.c +++ b/src/output/msglog.c @@ -29,7 +29,7 @@ #include "libpspp/cast.h" #include "libpspp/message.h" #include "output/driver-provider.h" -#include "output/message-item.h" +#include "output/output-item.h" #include "gl/fwriteerror.h" #include "gl/xalloc.h" @@ -98,10 +98,9 @@ msglog_submit (struct output_driver *driver, const struct output_item *item) { struct msglog_driver *ml = msglog_driver_cast (driver); - if (is_message_item (item)) + if (item->type == OUTPUT_ITEM_MESSAGE) { - const struct message_item *message_item = to_message_item (item); - char *s = msg_to_string (message_item_get_msg (message_item)); + char *s = msg_to_string (item->message); fprintf (ml->file, "%s\n", s); free (s); } diff --git a/src/output/odt.c b/src/output/odt.c index 82480bb3e3..683d19bcf5 100644 --- a/src/output/odt.c +++ b/src/output/odt.c @@ -38,13 +38,11 @@ #include "libpspp/zip-writer.h" #include "data/file-handle-def.h" #include "output/driver-provider.h" -#include "output/message-item.h" #include "output/options.h" +#include "output/output-item.h" #include "output/pivot-table.h" #include "output/pivot-output.h" -#include "output/table-item.h" #include "output/table-provider.h" -#include "output/text-item.h" #include "gl/xalloc.h" @@ -573,11 +571,11 @@ write_table_layer (struct odt_driver *odt, const struct pivot_table *pt, } static void -write_table (struct odt_driver *odt, const struct table_item *item) +write_table (struct odt_driver *odt, const struct pivot_table *pt) { size_t *layer_indexes; - PIVOT_OUTPUT_FOR_EACH_LAYER (layer_indexes, item->pt, true) - write_table_layer (odt, item->pt, layer_indexes); + PIVOT_OUTPUT_FOR_EACH_LAYER (layer_indexes, pt, true) + write_table_layer (odt, pt, layer_indexes); } static void @@ -590,25 +588,49 @@ odt_output_text (struct odt_driver *odt, const char *text) /* Submit a table to the ODT driver */ static void -odt_submit (struct output_driver *driver, - const struct output_item *output_item) +odt_submit (struct output_driver *driver, const struct output_item *item) { struct odt_driver *odt = odt_driver_cast (driver); - if (is_table_item (output_item)) - write_table (odt, to_table_item (output_item)); - else if (is_text_item (output_item)) + switch (item->type) { - char *text = text_item_get_plain_text (to_text_item (output_item)); - odt_output_text (odt, text); - free (text); - } - else if (is_message_item (output_item)) - { - const struct message_item *message_item = to_message_item (output_item); - char *s = msg_to_string (message_item_get_msg (message_item)); - odt_output_text (odt, s); - free (s); + case OUTPUT_ITEM_CHART: + break; + + case OUTPUT_ITEM_GROUP_OPEN: + break; + + case OUTPUT_ITEM_GROUP_CLOSE: + break; + + case OUTPUT_ITEM_IMAGE: + break; + + case OUTPUT_ITEM_MESSAGE: + { + char *s = msg_to_string (item->message); + odt_output_text (odt, s); + free (s); + } + break; + + case OUTPUT_ITEM_PAGE_BREAK: + break; + + case OUTPUT_ITEM_PAGE_SETUP: + break; + + case OUTPUT_ITEM_TABLE: + write_table (odt, item->table); + break; + + case OUTPUT_ITEM_TEXT: + { + char *text = text_item_get_plain_text (item); + odt_output_text (odt, text); + free (text); + } + break; } } diff --git a/src/output/output-item-provider.h b/src/output/output-item-provider.h deleted file mode 100644 index 62e7561559..0000000000 --- a/src/output/output-item-provider.h +++ /dev/null @@ -1,48 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2009, 2011 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef OUTPUT_ITEM_PROVIDER_H -#define OUTPUT_ITEM_PROVIDER_H 1 - -#include "libpspp/str.h" -#include "output/output-item.h" - -/* Class structure for an output item. - - This structure must be provided by an output_item subclass to initialize an - instance of output_item. */ -struct output_item_class - { - /* Returns the localized label to use for ITEM. This is only called when - ITEM does not have an explicitly set label, that is, when 'item->label' - is NULL. */ - const char *(*get_label) (const struct output_item *item); - - /* Destroys and frees ITEM. Called when output_item_unref() drops ITEM's - reference count to 0. */ - void (*destroy) (struct output_item *item); - }; - -#define OUTPUT_ITEM_INITIALIZER(CLASS) { .class = CLASS, .ref_cnt = 1 } -#define OUTPUT_ITEM_CLONE_INITIALIZER(SRC) \ - { \ - .class = (SRC)->class, \ - .ref_cnt = 1, \ - .label = xstrdup_if_nonnull ((SRC)->label), \ - .command_name = xstrdup_if_nonnull ((SRC)->command_name), \ - } - -#endif /* output/output-item-provider.h */ diff --git a/src/output/output-item.c b/src/output/output-item.c index f80ea19c46..c39e8cd326 100644 --- a/src/output/output-item.c +++ b/src/output/output-item.c @@ -16,19 +16,28 @@ #include -#include "output/output-item-provider.h" +#include "output/output-item.h" #include #include #include "libpspp/assertion.h" #include "libpspp/cast.h" +#include "libpspp/message.h" #include "libpspp/str.h" +#include "output/chart.h" +#include "output/driver.h" +#include "output/page-setup.h" +#include "output/pivot-table.h" #include "gl/xalloc.h" #include "gettext.h" +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid +#define OUTPUT_ITEM_INITIALIZER(TYPE) .type = TYPE, .ref_cnt = 1 + /* Increases ITEM's reference count, indicating that it has an additional owner. An output item that is shared among multiple owners must not be modified. */ @@ -50,11 +59,46 @@ output_item_unref (struct output_item *item) assert (item->ref_cnt > 0); if (--item->ref_cnt == 0) { - char *label = item->label; - char *command_name = item->command_name; - item->class->destroy (item); - free (label); - free (command_name); + switch (item->type) + { + case OUTPUT_ITEM_CHART: + chart_unref (item->chart); + break; + + case OUTPUT_ITEM_GROUP_OPEN: + break; + + case OUTPUT_ITEM_GROUP_CLOSE: + break; + + case OUTPUT_ITEM_IMAGE: + cairo_surface_destroy (item->image); + break; + + case OUTPUT_ITEM_MESSAGE: + msg_destroy (item->message); + break; + + case OUTPUT_ITEM_PAGE_BREAK: + break; + + case OUTPUT_ITEM_PAGE_SETUP: + page_setup_destroy (item->page_setup); + break; + + case OUTPUT_ITEM_TABLE: + pivot_table_unref (item->table); + break; + + case OUTPUT_ITEM_TEXT: + pivot_value_destroy (item->text.content); + break; + } + + free (item->label); + free (item->command_name); + free (item->cached_label); + free (item); } } } @@ -67,11 +111,117 @@ output_item_is_shared (const struct output_item *item) return item->ref_cnt > 1; } +struct output_item * +output_item_unshare (struct output_item *old) +{ + assert (old->ref_cnt > 0); + if (!output_item_is_shared (old)) + return old; + output_item_unref (old); + + struct output_item *new = xmalloc (sizeof *new); + *new = (struct output_item) { + .ref_cnt = 1, + .label = xstrdup_if_nonnull (old->label), + .command_name = xstrdup_if_nonnull (old->command_name), + .type = old->type, + }; + switch (old->type) + { + case OUTPUT_ITEM_CHART: + new->chart = chart_ref (old->chart); + break; + + case OUTPUT_ITEM_GROUP_OPEN: + break; + + case OUTPUT_ITEM_GROUP_CLOSE: + break; + + case OUTPUT_ITEM_IMAGE: + new->image = cairo_surface_reference (old->image); + break; + + case OUTPUT_ITEM_MESSAGE: + new->message = msg_dup (old->message); + break; + + case OUTPUT_ITEM_PAGE_BREAK: + break; + + case OUTPUT_ITEM_PAGE_SETUP: + new->page_setup = page_setup_clone (old->page_setup); + break; + + case OUTPUT_ITEM_TABLE: + new->table = pivot_table_ref (old->table); + break; + + case OUTPUT_ITEM_TEXT: + new->text.subtype = old->text.subtype; + new->text.content = pivot_value_clone (old->text.content); + break; + } + return new; +} + +void +output_item_submit (struct output_item *item) +{ + output_submit (item); +} + /* Returns the label for ITEM, which the caller must not modify or free. */ const char * output_item_get_label (const struct output_item *item) { - return item->label ? item->label : item->class->get_label (item); + if (item->label) + return item->label; + + switch (item->type) + { + case OUTPUT_ITEM_CHART: + return item->chart->title ? item->chart->title : _("Chart"); + + case OUTPUT_ITEM_GROUP_OPEN: + return item->command_name ? item->command_name : _("Group"); + + case OUTPUT_ITEM_GROUP_CLOSE: + /* Not marked for translation: user should never see it. */ + return "Group Close"; + + case OUTPUT_ITEM_IMAGE: + return "Image"; + + case OUTPUT_ITEM_MESSAGE: + return (item->message->severity == MSG_S_ERROR ? _("Error") + : item->message->severity == MSG_S_WARNING ? _("Warning") + : _("Note")); + + case OUTPUT_ITEM_PAGE_BREAK: + return _("Page Break"); + + case OUTPUT_ITEM_PAGE_SETUP: + /* Not marked for translation: user should never see it. */ + return "Page Setup"; + + case OUTPUT_ITEM_TABLE: + if (!item->cached_label) + { + if (!item->table->title) + return _("Table"); + + struct output_item *item_rw = CONST_CAST (struct output_item *, item); + item_rw->cached_label = pivot_value_to_string (item->table->title, + item->table); + } + return item->cached_label; + + case OUTPUT_ITEM_TEXT: + return text_item_subtype_to_string (item->text.subtype); + } + + NOT_REACHED (); } /* Sets the label for ITEM to LABEL. The caller retains ownership of LABEL. @@ -97,3 +247,309 @@ output_item_set_label_nocopy (struct output_item *item, char *label) free (item->label); item->label = label; } + +struct output_item * +chart_item_create (struct chart *chart) +{ + struct output_item *item = xmalloc (sizeof *item); + *item = (struct output_item) { + OUTPUT_ITEM_INITIALIZER (OUTPUT_ITEM_CHART), + .chart = chart, + }; + return item; +} + +struct output_item * +group_open_item_create (const char *command_name, const char *label) +{ + return group_open_item_create_nocopy ( + xstrdup_if_nonnull (command_name), + xstrdup_if_nonnull (label)); +} + +struct output_item * +group_open_item_create_nocopy (char *command_name, char *label) +{ + struct output_item *item = xmalloc (sizeof *item); + *item = (struct output_item) { + OUTPUT_ITEM_INITIALIZER (OUTPUT_ITEM_GROUP_OPEN), + .label = label, + .command_name = command_name, + }; + return item; +} + +struct output_item * +group_close_item_create (void) +{ + struct output_item *item = xmalloc (sizeof *item); + *item = (struct output_item) { + OUTPUT_ITEM_INITIALIZER (OUTPUT_ITEM_GROUP_CLOSE), + }; + return item; +} + +/* Creates and returns a new output item containing IMAGE. Takes ownership of + IMAGE. */ +struct output_item * +image_item_create (cairo_surface_t *image) +{ + struct output_item *item = xmalloc (sizeof *item); + *item = (struct output_item) { + OUTPUT_ITEM_INITIALIZER (OUTPUT_ITEM_IMAGE), + .image = image, + }; + return item; +} + +struct output_item * +message_item_create (const struct msg *msg) +{ + struct output_item *item = xmalloc (sizeof *msg); + *item = (struct output_item) { + OUTPUT_ITEM_INITIALIZER (OUTPUT_ITEM_MESSAGE), + .message = msg_dup (msg), + }; + return item; +} + +const struct msg * +message_item_get_msg (const struct output_item *item) +{ + assert (item->type == OUTPUT_ITEM_MESSAGE); + return item->message; +} + +struct output_item * +message_item_to_text_item (struct output_item *message_item) +{ + assert (message_item->type == OUTPUT_ITEM_MESSAGE); + struct output_item *text_item = text_item_create_nocopy ( + TEXT_ITEM_LOG, + msg_to_string (message_item->message), + xstrdup (output_item_get_label (message_item))); + output_item_unref (message_item); + return text_item; +} + +struct output_item * +page_break_item_create (void) +{ + struct output_item *item = xmalloc (sizeof *item); + *item = (struct output_item) { + OUTPUT_ITEM_INITIALIZER (OUTPUT_ITEM_PAGE_BREAK), + }; + return item; +} + +struct output_item * +page_setup_item_create (const struct page_setup *ps) +{ + struct output_item *item = xmalloc (sizeof *item); + *item = (struct output_item) { + OUTPUT_ITEM_INITIALIZER (OUTPUT_ITEM_PAGE_SETUP), + .page_setup = page_setup_clone (ps), + }; + return item; +} + +/* Returns a new output_item for rendering TABLE. Takes ownership of + TABLE. */ +struct output_item * +table_item_create (struct pivot_table *table) +{ + pivot_table_assign_label_depth (table); + + struct output_item *item = xmalloc (sizeof *item); + *item = (struct output_item) { + OUTPUT_ITEM_INITIALIZER (OUTPUT_ITEM_TABLE), + .command_name = xstrdup_if_nonnull (table->command_c), + .table = table, + }; + return item; +} + +/* Creates and returns a new text item containing TEXT and the specified + SUBTYPE and LABEL. The new text item takes ownership of TEXT and LABEL. If + LABEL is NULL, uses the default label for SUBTYPE. */ +struct output_item * +text_item_create_nocopy (enum text_item_subtype subtype, + char *text, char *label) +{ + return text_item_create_value (subtype, + pivot_value_new_user_text_nocopy (text), + label); +} + +/* Creates and returns a new text item containing a copy of TEXT and the + specified SUBTYPE and LABEL. The caller retains ownership of TEXT and + LABEL. If LABEL is null, uses a default label for SUBTYPE. */ +struct output_item * +text_item_create (enum text_item_subtype subtype, const char *text, + const char *label) +{ + return text_item_create_nocopy (subtype, xstrdup (text), + xstrdup_if_nonnull (label)); +} + +/* Creates and returns a new text item containing VALUE, SUBTYPE, and LABEL. + Takes ownership of VALUE and LABEL. If LABEL is null, uses a default label + for SUBTYPE. */ +struct output_item * +text_item_create_value (enum text_item_subtype subtype, + struct pivot_value *value, char *label) +{ + if (subtype == TEXT_ITEM_SYNTAX || subtype == TEXT_ITEM_LOG) + { + if (!value->font_style) + { + value->font_style = xmalloc (sizeof *value->font_style); + *value->font_style = (struct font_style) FONT_STYLE_INITIALIZER; + } + + free (value->font_style->typeface); + value->font_style->typeface = xstrdup ("Monospaced"); + } + + struct output_item *item = xzalloc (sizeof *item); + *item = (struct output_item) { + OUTPUT_ITEM_INITIALIZER (OUTPUT_ITEM_TEXT), + .command_name = xstrdup_if_nonnull (output_get_command_name ()), + .label = label, + .text = { .subtype = subtype, .content = value }, + }; + return item; +} + +/* Returns ITEM's subtype. */ +enum text_item_subtype +text_item_get_subtype (const struct output_item *item) +{ + assert (item->type == OUTPUT_ITEM_TEXT); + return item->text.subtype; +} + +/* Returns ITEM's text, which the caller must eventually free. */ +char * +text_item_get_plain_text (const struct output_item *item) +{ + assert (item->type == OUTPUT_ITEM_TEXT); + return pivot_value_to_string_defaults (item->text.content); +} + +static bool +nullable_font_style_equal (const struct font_style *a, + const struct font_style *b) +{ + return a && b ? font_style_equal (a, b) : !a && !b; +} + +/* Attempts to append the text in SRC to DST. If successful, returns true, + otherwise false. + + Only TEXT_ITEM_SYNTAX and TEXT_ITEM_LOG items can be combined, and not with + each other. + + DST must not be shared. */ +bool +text_item_append (struct output_item *dst, const struct output_item *src) +{ + assert (dst->type == OUTPUT_ITEM_TEXT); + assert (src->type == OUTPUT_ITEM_TEXT); + assert (!output_item_is_shared (dst)); + + enum text_item_subtype ds = dst->text.subtype; + enum text_item_subtype ss = src->text.subtype; + + struct pivot_value *dc = dst->text.content; + const struct pivot_value *sc = src->text.content; + + if (ds != ss + || (ds != TEXT_ITEM_SYNTAX && ds != TEXT_ITEM_LOG) + || strcmp (output_item_get_label (dst), output_item_get_label (src)) + || !nullable_font_style_equal (dc->font_style, sc->font_style) + || (dc->font_style && dc->font_style->markup) + || sc->type != PIVOT_VALUE_TEXT + || dc->type != PIVOT_VALUE_TEXT) + return false; + else + { + /* Calculate new text. */ + char *new_text = xasprintf ("%s\n%s", dc->text.local, sc->text.local); + + /* Free the old text. */ + free (dc->text.local); + if (dc->text.c != dc->text.local) + free (dc->text.c); + if (dc->text.id != dc->text.local && dc->text.id != dc->text.c) + free (dc->text.id); + + /* Put in new text. */ + dc->text.local = new_text; + dc->text.c = new_text; + dc->text.id = new_text; + + return true; + } +} + +static const struct pivot_table_look * +text_item_table_look (void) +{ + static struct pivot_table_look *look; + if (!look) + { + look = pivot_table_look_new_builtin_default (); + + for (int a = 0; a < PIVOT_N_AREAS; a++) + memset (look->areas[a].cell_style.margin, 0, + sizeof look->areas[a].cell_style.margin); + for (int b = 0; b < PIVOT_N_BORDERS; b++) + look->borders[b].stroke = TABLE_STROKE_NONE; + } + return look; +} + +struct output_item * +text_item_to_table_item (struct output_item *text_item) +{ + assert (text_item->type == OUTPUT_ITEM_TEXT); + + /* Create a new table whose contents come from TEXT_ITEM. */ + struct pivot_table *table = pivot_table_create__ (NULL, "Text"); + pivot_table_set_look (table, text_item_table_look ()); + + struct pivot_dimension *d = pivot_dimension_create ( + table, PIVOT_AXIS_ROW, N_("Text")); + d->hide_all_labels = true; + pivot_category_create_leaf (d->root, pivot_value_new_text ("null")); + + pivot_table_put1 (table, 0, pivot_value_clone (text_item->text.content)); + + /* Free TEXT_ITEM. */ + output_item_unref (text_item); + + /* Return a new output item. */ + return table_item_create (table); +} + +const char * +text_item_subtype_to_string (enum text_item_subtype subtype) +{ + switch (subtype) + { + case TEXT_ITEM_PAGE_TITLE: + return _("Page Title"); + + case TEXT_ITEM_TITLE: + return _("Title"); + + case TEXT_ITEM_SYNTAX: + case TEXT_ITEM_LOG: + return _("Log"); + + default: + return _("Text"); + } +} + diff --git a/src/output/output-item.h b/src/output/output-item.h index 1580d1e1eb..6c0c17592f 100644 --- a/src/output/output-item.h +++ b/src/output/output-item.h @@ -19,18 +19,29 @@ /* Output items. - An output item is a self-contained chunk of output. Several kinds of output - items exist. See *-item.h for details. + An output item is a self-contained chunk of output. */ +#include #include #include "libpspp/cast.h" +enum output_item_type + { + OUTPUT_ITEM_CHART, + OUTPUT_ITEM_GROUP_OPEN, + OUTPUT_ITEM_GROUP_CLOSE, + OUTPUT_ITEM_IMAGE, + OUTPUT_ITEM_MESSAGE, + OUTPUT_ITEM_PAGE_BREAK, + OUTPUT_ITEM_PAGE_SETUP, + OUTPUT_ITEM_TABLE, + OUTPUT_ITEM_TEXT, + }; + /* A single output item. */ struct output_item { - const struct output_item_class *class; - /* Reference count. An output item may be shared between multiple owners, indicated by a reference count greater than 1. When this is the case, the output item must not be modified. */ @@ -47,14 +58,103 @@ struct output_item which may be NULL if unknown or if a command did not produce this output. */ char *command_name; + + enum output_item_type type; + union + { + struct chart *chart; + + cairo_surface_t *image; + + struct msg *message; + + struct page_setup *page_setup; + + struct pivot_table *table; + + struct + { + enum text_item_subtype + { + TEXT_ITEM_PAGE_TITLE, /* TITLE and SUBTITLE commands. */ + TEXT_ITEM_TITLE, /* Title. */ + TEXT_ITEM_SYNTAX, /* Syntax printback logging. */ + TEXT_ITEM_LOG, /* Other logging. */ + } + subtype; + struct pivot_value *content; + } + text; + }; + + char *cached_label; }; struct output_item *output_item_ref (const struct output_item *); void output_item_unref (struct output_item *); bool output_item_is_shared (const struct output_item *); +struct output_item *output_item_unshare (struct output_item *); + +void output_item_submit (struct output_item *); const char *output_item_get_label (const struct output_item *); void output_item_set_label (struct output_item *, const char *); void output_item_set_label_nocopy (struct output_item *, char *); + +/* OUTPUT_ITEM_CHART. */ +struct output_item *chart_item_create (struct chart *); + +/* OUTPUT_ITEM_GROUP_OPEN. */ +struct output_item *group_open_item_create (const char *command_name, + const char *label); +struct output_item *group_open_item_create_nocopy (char *command_name, + char *label); + +/* OUTPUT_ITEM_GROUP_CLOSE. */ + +struct output_item *group_close_item_create (void); + +/* OUTPUT_ITEM_IMAGE. */ + +struct output_item *image_item_create (cairo_surface_t *); + +/* OUTPUT_ITEM_MESSAGE. */ + +struct output_item *message_item_create (const struct msg *); + +const struct msg *message_item_get_msg (const struct output_item *); + +struct output_item *message_item_to_text_item (struct output_item *); + +/* OUTPUT_ITEM_PAGE_BREAK. */ + +struct output_item *page_break_item_create (void); + +/* OUTPUT_ITEM_PAGE_SETUP. */ + +struct output_item *page_setup_item_create (const struct page_setup *); + +/* OUTPUT_ITEM_TABLE. */ + +struct output_item *table_item_create (struct pivot_table *); + +/* OUTPUT_ITEM_TEXT. */ + +struct output_item *text_item_create (enum text_item_subtype, + const char *text, const char *label); +struct output_item *text_item_create_nocopy (enum text_item_subtype, + char *text, char *label); +struct output_item *text_item_create_value (enum text_item_subtype, + struct pivot_value *value, + char *label); + +enum text_item_subtype text_item_get_subtype (const struct output_item *); +char *text_item_get_plain_text (const struct output_item *); + +bool text_item_append (struct output_item *dst, const struct output_item *src); + +struct output_item *text_item_to_table_item (struct output_item *); + +const char *text_item_subtype_to_string (enum text_item_subtype); #endif /* output/output-item.h */ diff --git a/src/output/page-break-item.c b/src/output/page-break-item.c deleted file mode 100644 index 477b640089..0000000000 --- a/src/output/page-break-item.c +++ /dev/null @@ -1,65 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2020 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include "output/page-break-item.h" - -#include - -#include "output/driver-provider.h" -#include "output/output-item-provider.h" - -#include "gl/xalloc.h" - -#include "gettext.h" -#define _(msgid) gettext (msgid) - -struct page_break_item * -page_break_item_create (void) -{ - struct page_break_item *item = xmalloc (sizeof *item); - *item = (struct page_break_item) { - .output_item = OUTPUT_ITEM_INITIALIZER (&page_break_item_class), - }; - return item; -} - -/* Submits ITEM to the configured output drivers, and transfers ownership to - the output subsystem. */ -void -page_break_item_submit (struct page_break_item *item) -{ - output_submit (&item->output_item); -} - -static const char * -page_break_item_get_label (const struct output_item *output_item UNUSED) -{ - return _("Page Break"); -} - -static void -page_break_item_destroy (struct output_item *output_item) -{ - free (to_page_break_item (output_item)); -} - -const struct output_item_class page_break_item_class = - { - page_break_item_get_label, - page_break_item_destroy, - }; diff --git a/src/output/page-break-item.h b/src/output/page-break-item.h deleted file mode 100644 index dea001378b..0000000000 --- a/src/output/page-break-item.h +++ /dev/null @@ -1,91 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2020 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef OUTPUT_PAGE_BREAK_ITEM_H -#define OUTPUT_PAGE_BREAK_ITEM_H 1 - -/* Page break items. - - This ejects the page (for output devices that have pages). */ - -#include -#include "output/output-item.h" - -/* A page break item. */ -struct page_break_item - { - struct output_item output_item; - }; - -struct page_break_item *page_break_item_create (void); - -/* This boilerplate for page_break_item, a subclass of output_item, was - autogenerated by mk-class-boilerplate. */ - -#include -#include "libpspp/cast.h" - -extern const struct output_item_class page_break_item_class; - -/* Returns true if SUPER is a page_break_item, otherwise false. */ -static inline bool -is_page_break_item (const struct output_item *super) -{ - return super->class == &page_break_item_class; -} - -/* Returns SUPER converted to page_break_item. SUPER must be a page_break_item, as - reported by is_page_break_item. */ -static inline struct page_break_item * -to_page_break_item (const struct output_item *super) -{ - assert (is_page_break_item (super)); - return UP_CAST (super, struct page_break_item, output_item); -} - -/* Returns INSTANCE converted to output_item. */ -static inline struct output_item * -page_break_item_super (const struct page_break_item *instance) -{ - return CONST_CAST (struct output_item *, &instance->output_item); -} - -/* Increments INSTANCE's reference count and returns INSTANCE. */ -static inline struct page_break_item * -page_break_item_ref (const struct page_break_item *instance) -{ - return to_page_break_item (output_item_ref (&instance->output_item)); -} - -/* Decrements INSTANCE's reference count, then destroys INSTANCE if - the reference count is now zero. */ -static inline void -page_break_item_unref (struct page_break_item *instance) -{ - output_item_unref (&instance->output_item); -} - -/* Returns true if INSTANCE's reference count is greater than 1, - false otherwise. */ -static inline bool -page_break_item_is_shared (const struct page_break_item *instance) -{ - return output_item_is_shared (&instance->output_item); -} - -void page_break_item_submit (struct page_break_item *); - -#endif /* output/page-break-item.h */ diff --git a/src/output/page-setup-item.c b/src/output/page-setup-item.c deleted file mode 100644 index 7be1c2c43b..0000000000 --- a/src/output/page-setup-item.c +++ /dev/null @@ -1,139 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2018 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include "output/page-setup-item.h" - -#include - -#include "output/driver-provider.h" -#include "output/output-item-provider.h" - -#include "gl/xalloc.h" - -bool -page_paragraph_equals (const struct page_paragraph *a, - const struct page_paragraph *b) -{ - return (!a || !b ? a == b - : !a->markup || !b->markup ? a->markup == b->markup - : !strcmp (a->markup, b->markup) && a->halign == b->halign); -} - -void -page_heading_copy (struct page_heading *dst, const struct page_heading *src) -{ - dst->n = src->n; - dst->paragraphs = xmalloc (dst->n * sizeof *dst->paragraphs); - for (size_t i = 0; i < dst->n; i++) - { - dst->paragraphs[i].markup = xstrdup (src->paragraphs[i].markup); - dst->paragraphs[i].halign = src->paragraphs[i].halign; - } -} - -void -page_heading_uninit (struct page_heading *ph) -{ - if (!ph) - return; - - for (size_t i = 0; i < ph->n; i++) - free (ph->paragraphs[i].markup); - free (ph->paragraphs); -} - -bool -page_heading_equals (const struct page_heading *a, - const struct page_heading *b) -{ - if (!a || !b) - return a == b; - - if (a->n != b->n) - return false; - - for (size_t i = 0; i < a->n; i++) - if (!page_paragraph_equals (&a->paragraphs[i], &b->paragraphs[i])) - return false; - - return true; -} - -struct page_setup * -page_setup_clone (const struct page_setup *old) -{ - struct page_setup *new = xmalloc (sizeof *new); - *new = *old; - for (int i = 0; i < 2; i++) - page_heading_copy (&new->headings[i], &old->headings[i]); - if (new->file_name) - new->file_name = xstrdup (new->file_name); - return new; -} - -void -page_setup_destroy (struct page_setup *ps) -{ - if (ps) - { - for (int i = 0; i < 2; i++) - page_heading_uninit (&ps->headings[i]); - free (ps->file_name); - free (ps); - } -} - -struct page_setup_item * -page_setup_item_create (const struct page_setup *ps) -{ - struct page_setup_item *item = xmalloc (sizeof *item); - *item = (struct page_setup_item) { - .output_item = OUTPUT_ITEM_INITIALIZER (&page_setup_item_class), - .page_setup = page_setup_clone (ps), - }; - return item; -} - -/* Submits ITEM to the configured output drivers, and transfers ownership to - the output subsystem. */ -void -page_setup_item_submit (struct page_setup_item *item) -{ - output_submit (&item->output_item); -} - -static const char * -page_setup_item_get_label (const struct output_item *output_item UNUSED) -{ - /* Not marked for translation: user should never see it. */ - return "Page Setup"; -} - -static void -page_setup_item_destroy (struct output_item *output_item) -{ - struct page_setup_item *item = to_page_setup_item (output_item); - page_setup_destroy (item->page_setup); - free (item); -} - -const struct output_item_class page_setup_item_class = - { - page_setup_item_get_label, - page_setup_item_destroy, - }; diff --git a/src/output/page-setup-item.h b/src/output/page-setup-item.h deleted file mode 100644 index f311ad2d5a..0000000000 --- a/src/output/page-setup-item.h +++ /dev/null @@ -1,153 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2009, 2010, 2011, 2018 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef OUTPUT_PAGE_SETUP_ITEM_H -#define OUTPUT_PAGE_SETUP_ITEM_H 1 - -/* Page setup items. - - A page setup item configures the paper size, margins, header and footer, - and other attributes used for printing. */ - -#include -#include "output/output-item.h" -#include "table.h" - -enum page_orientation - { - PAGE_PORTRAIT, - PAGE_LANDSCAPE - }; - -enum page_chart_size - { - PAGE_CHART_AS_IS, - PAGE_CHART_FULL_HEIGHT, - PAGE_CHART_HALF_HEIGHT, - PAGE_CHART_QUARTER_HEIGHT, - }; - -struct page_paragraph - { - char *markup; - enum table_halign halign; - }; - -bool page_paragraph_equals (const struct page_paragraph *, - const struct page_paragraph *); - -struct page_heading - { - struct page_paragraph *paragraphs; - size_t n; - }; - -void page_heading_copy (struct page_heading *, const struct page_heading *); -void page_heading_uninit (struct page_heading *); -bool page_heading_equals (const struct page_heading *, - const struct page_heading *); - -struct page_setup - { - int initial_page_number; - double paper[TABLE_N_AXES]; /* Paper size in inches. */ - double margins[TABLE_N_AXES][2]; /* In inches. */ - enum page_orientation orientation; - double object_spacing; /* Space between objects, in inches. */ - enum page_chart_size chart_size; - struct page_heading headings[2]; /* Header and footer. */ - char *file_name; - }; - -#define PAGE_SETUP_INITIALIZER \ - { \ - .initial_page_number = 1, \ - .paper = { [TABLE_HORZ] = 8.5, [TABLE_VERT] = 11.0 }, \ - .margins = { { 0.5, 0.5 }, { 0.5, 0.5 } }, \ - .orientation = PAGE_PORTRAIT, \ - .object_spacing = 12.0 / 72.0, \ - .chart_size = PAGE_CHART_AS_IS, \ - } - -struct page_setup *page_setup_clone (const struct page_setup *); -void page_setup_destroy (struct page_setup *); - -/* A page setup item. */ -struct page_setup_item - { - struct output_item output_item; - struct page_setup *page_setup; - }; - -struct page_setup_item *page_setup_item_create (const struct page_setup *); - -/* This boilerplate for page_setup_item, a subclass of output_item, was - autogenerated by mk-class-boilerplate. */ - -#include -#include "libpspp/cast.h" - -extern const struct output_item_class page_setup_item_class; - -/* Returns true if SUPER is a page_setup_item, otherwise false. */ -static inline bool -is_page_setup_item (const struct output_item *super) -{ - return super->class == &page_setup_item_class; -} - -/* Returns SUPER converted to page_setup_item. SUPER must be a page_setup_item, as - reported by is_page_setup_item. */ -static inline struct page_setup_item * -to_page_setup_item (const struct output_item *super) -{ - assert (is_page_setup_item (super)); - return UP_CAST (super, struct page_setup_item, output_item); -} - -/* Returns INSTANCE converted to output_item. */ -static inline struct output_item * -page_setup_item_super (const struct page_setup_item *instance) -{ - return CONST_CAST (struct output_item *, &instance->output_item); -} - -/* Increments INSTANCE's reference count and returns INSTANCE. */ -static inline struct page_setup_item * -page_setup_item_ref (const struct page_setup_item *instance) -{ - return to_page_setup_item (output_item_ref (&instance->output_item)); -} - -/* Decrements INSTANCE's reference count, then destroys INSTANCE if - the reference count is now zero. */ -static inline void -page_setup_item_unref (struct page_setup_item *instance) -{ - output_item_unref (&instance->output_item); -} - -/* Returns true if INSTANCE's reference count is greater than 1, - false otherwise. */ -static inline bool -page_setup_item_is_shared (const struct page_setup_item *instance) -{ - return output_item_is_shared (&instance->output_item); -} - -void page_setup_item_submit (struct page_setup_item *); - -#endif /* output/page-setup-item.h */ diff --git a/src/output/page-setup.c b/src/output/page-setup.c new file mode 100644 index 0000000000..4c9c990464 --- /dev/null +++ b/src/output/page-setup.c @@ -0,0 +1,97 @@ +/* PSPP - a program for statistical analysis. + Copyright (C) 2018 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +#include "output/page-setup.h" + +#include +#include + +#include "gl/xalloc.h" + +bool +page_paragraph_equals (const struct page_paragraph *a, + const struct page_paragraph *b) +{ + return (!a || !b ? a == b + : !a->markup || !b->markup ? a->markup == b->markup + : !strcmp (a->markup, b->markup) && a->halign == b->halign); +} + +void +page_heading_copy (struct page_heading *dst, const struct page_heading *src) +{ + dst->n = src->n; + dst->paragraphs = xmalloc (dst->n * sizeof *dst->paragraphs); + for (size_t i = 0; i < dst->n; i++) + { + dst->paragraphs[i].markup = xstrdup (src->paragraphs[i].markup); + dst->paragraphs[i].halign = src->paragraphs[i].halign; + } +} + +void +page_heading_uninit (struct page_heading *ph) +{ + if (!ph) + return; + + for (size_t i = 0; i < ph->n; i++) + free (ph->paragraphs[i].markup); + free (ph->paragraphs); +} + +bool +page_heading_equals (const struct page_heading *a, + const struct page_heading *b) +{ + if (!a || !b) + return a == b; + + if (a->n != b->n) + return false; + + for (size_t i = 0; i < a->n; i++) + if (!page_paragraph_equals (&a->paragraphs[i], &b->paragraphs[i])) + return false; + + return true; +} + +struct page_setup * +page_setup_clone (const struct page_setup *old) +{ + struct page_setup *new = xmalloc (sizeof *new); + *new = *old; + for (int i = 0; i < 2; i++) + page_heading_copy (&new->headings[i], &old->headings[i]); + if (new->file_name) + new->file_name = xstrdup (new->file_name); + return new; +} + +void +page_setup_destroy (struct page_setup *ps) +{ + if (ps) + { + for (int i = 0; i < 2; i++) + page_heading_uninit (&ps->headings[i]); + free (ps->file_name); + free (ps); + } +} diff --git a/src/output/page-setup.h b/src/output/page-setup.h new file mode 100644 index 0000000000..95405eff27 --- /dev/null +++ b/src/output/page-setup.h @@ -0,0 +1,87 @@ +/* PSPP - a program for statistical analysis. + Copyright (C) 2009, 2010, 2011, 2018 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef OUTPUT_PAGE_SETUP_H +#define OUTPUT_PAGE_SETUP_H 1 + +/* Page setup. + + Configures the paper size, margins, header and footer, and other attributes + used for printing. */ + +#include +#include "table.h" + +enum page_orientation + { + PAGE_PORTRAIT, + PAGE_LANDSCAPE + }; + +enum page_chart_size + { + PAGE_CHART_AS_IS, + PAGE_CHART_FULL_HEIGHT, + PAGE_CHART_HALF_HEIGHT, + PAGE_CHART_QUARTER_HEIGHT, + }; + +struct page_paragraph + { + char *markup; + enum table_halign halign; + }; + +bool page_paragraph_equals (const struct page_paragraph *, + const struct page_paragraph *); + +struct page_heading + { + struct page_paragraph *paragraphs; + size_t n; + }; + +void page_heading_copy (struct page_heading *, const struct page_heading *); +void page_heading_uninit (struct page_heading *); +bool page_heading_equals (const struct page_heading *, + const struct page_heading *); + +struct page_setup + { + int initial_page_number; + double paper[TABLE_N_AXES]; /* Paper size in inches. */ + double margins[TABLE_N_AXES][2]; /* In inches. */ + enum page_orientation orientation; + double object_spacing; /* Space between objects, in inches. */ + enum page_chart_size chart_size; + struct page_heading headings[2]; /* Header and footer. */ + char *file_name; + }; + +#define PAGE_SETUP_INITIALIZER \ + { \ + .initial_page_number = 1, \ + .paper = { [TABLE_HORZ] = 8.5, [TABLE_VERT] = 11.0 }, \ + .margins = { { 0.5, 0.5 }, { 0.5, 0.5 } }, \ + .orientation = PAGE_PORTRAIT, \ + .object_spacing = 12.0 / 72.0, \ + .chart_size = PAGE_CHART_AS_IS, \ + } + +struct page_setup *page_setup_clone (const struct page_setup *); +void page_setup_destroy (struct page_setup *); + +#endif /* output/page-setup.h */ diff --git a/src/output/pivot-output.c b/src/output/pivot-output.c index bea33985eb..2fa664bffa 100644 --- a/src/output/pivot-output.c +++ b/src/output/pivot-output.c @@ -23,11 +23,10 @@ #include "data/settings.h" #include "libpspp/assertion.h" #include "libpspp/pool.h" +#include "output/output-item.h" #include "output/pivot-table.h" -#include "output/table-item.h" #include "output/table-provider.h" #include "output/table.h" -#include "output/text-item.h" #include "gl/minmax.h" #include "gl/xalloc.h" @@ -662,5 +661,5 @@ pivot_output (const struct pivot_table *pt, void pivot_table_submit (struct pivot_table *pt) { - table_item_submit (table_item_create (pt)); + output_item_submit (table_item_create (pt)); } diff --git a/src/output/render.c b/src/output/render.c index b514f09e85..249d77f80b 100644 --- a/src/output/render.c +++ b/src/output/render.c @@ -29,7 +29,6 @@ #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" @@ -1511,14 +1510,13 @@ render_pager_start_page (struct render_pager *p) render_break_init_empty (&p->y_break); } -/* 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 pivot_table *pt = table_item->pt; if (!layer_indexes) layer_indexes = pt->current_layer; @@ -1533,9 +1531,7 @@ render_pager_create (const struct render_params *params, 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 { @@ -1567,9 +1563,7 @@ render_pager_create (const struct render_params *params, 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++) diff --git a/src/output/render.h b/src/output/render.h index bc8db241f8..437c5a0049 100644 --- a/src/output/render.h +++ b/src/output/render.h @@ -152,7 +152,7 @@ struct render_ops /* An iterator for breaking render_pages into smaller chunks. */ struct render_pager *render_pager_create (const struct render_params *, - const struct table_item *, + const struct pivot_table *, const size_t *layer_indexes); void render_pager_destroy (struct render_pager *); diff --git a/src/output/spv-driver.c b/src/output/spv-driver.c index e2bc9b2350..f0c00e5fa8 100644 --- a/src/output/spv-driver.c +++ b/src/output/spv-driver.c @@ -23,12 +23,7 @@ #include "data/file-handle-def.h" #include "libpspp/cast.h" #include "output/cairo-chart.h" -#include "output/chart-item.h" -#include "output/group-item.h" -#include "output/image-item.h" -#include "output/page-setup-item.h" -#include "output/table-item.h" -#include "output/text-item.h" +#include "output/output-item.h" #include "output/spv/spv-writer.h" #include "gl/xalloc.h" diff --git a/src/output/spv/spv-output.c b/src/output/spv/spv-output.c index 49cc195341..8006f85eb2 100644 --- a/src/output/spv/spv-output.c +++ b/src/output/spv/spv-output.c @@ -20,7 +20,7 @@ #include "output/pivot-table.h" #include "output/spv/spv.h" -#include "output/text-item.h" +#include "output/output-item.h" #include "gl/xalloc.h" @@ -28,11 +28,11 @@ void spv_text_submit (const struct spv_item *in) { enum spv_item_class class = spv_item_get_class (in); - struct text_item *item = text_item_create_value ( + struct output_item *item = text_item_create_value ( (class == SPV_CLASS_HEADINGS ? TEXT_ITEM_TITLE : class == SPV_CLASS_PAGETITLE ? TEXT_ITEM_PAGE_TITLE : TEXT_ITEM_LOG), pivot_value_clone (spv_item_get_text (in)), xstrdup_if_nonnull (in->label)); - text_item_submit (item); + output_item_submit (item); } diff --git a/src/output/spv/spv-writer.c b/src/output/spv/spv-writer.c index e3f3b28ffa..270f6beb87 100644 --- a/src/output/spv/spv-writer.c +++ b/src/output/spv/spv-writer.c @@ -34,15 +34,10 @@ #include "libpspp/version.h" #include "libpspp/zip-writer.h" #include "output/cairo-chart.h" -#include "output/chart-item.h" #include "output/driver.h" -#include "output/group-item.h" -#include "output/image-item.h" -#include "output/page-break-item.h" -#include "output/page-setup-item.h" +#include "output/output-item.h" +#include "output/page-setup.h" #include "output/pivot-table.h" -#include "output/table-item.h" -#include "output/text-item.h" #include "gl/xalloc.h" #include "gl/xvasprintf.h" @@ -309,19 +304,20 @@ close_container (struct spv_writer *w) } static void -spv_writer_put_text (struct spv_writer *w, const struct text_item *text) +spv_writer_put_text (struct spv_writer *w, struct output_item *item) { bool initial_depth = w->heading_depth; if (!initial_depth) spv_writer_open_file (w); - open_container (w, &text->output_item, "vtx:text"); - write_attr (w, "type", (text->type == TEXT_ITEM_TITLE ? "title" - : text->type == TEXT_ITEM_PAGE_TITLE ? "page-title" - : "log")); + open_container (w, item, "vtx:text"); + write_attr (w, "type", + (item->text.subtype == TEXT_ITEM_TITLE ? "title" + : item->text.subtype == TEXT_ITEM_PAGE_TITLE ? "page-title" + : "log")); start_elem (w, "html"); - char *s = text_item_get_plain_text (text); + char *s = text_item_get_plain_text (item); write_text (w, s); free (s); end_elem (w); @@ -330,6 +326,8 @@ spv_writer_put_text (struct spv_writer *w, const struct text_item *text) if (!initial_depth) spv_writer_close_file (w, ""); + + output_item_unref (item); } static cairo_status_t @@ -1051,7 +1049,7 @@ put_light_table (struct buf *buf, uint64_t table_id, } static void -spv_writer_put_table (struct spv_writer *w, const struct table_item *item) +spv_writer_put_table (struct spv_writer *w, const struct output_item *item) { int table_id = ++w->n_tables; @@ -1059,12 +1057,12 @@ spv_writer_put_table (struct spv_writer *w, const struct table_item *item) if (!initial_depth) spv_writer_open_file (w); - open_container (w, &item->output_item, "vtb:table"); + open_container (w, item, "vtb:table"); write_attr (w, "type", "table"); /* XXX */ write_attr_format (w, "tableId", "%d", table_id); - char *subtype = (item->pt->subtype - ? pivot_value_to_string (item->pt->subtype, item->pt) + char *subtype = (item->table->subtype + ? pivot_value_to_string (item->table->subtype, item->table) : xstrdup ("unknown")); write_attr (w, "subType", subtype); free (subtype); @@ -1082,7 +1080,7 @@ spv_writer_put_table (struct spv_writer *w, const struct table_item *item) spv_writer_close_file (w, ""); struct buf buf = { NULL, 0, 0 }; - put_light_table (&buf, table_id, item->pt); + put_light_table (&buf, table_id, item->table); zip_writer_add_memory (w->zw, data_path, buf.data, buf.len); free (buf.data); @@ -1092,31 +1090,52 @@ spv_writer_put_table (struct spv_writer *w, const struct table_item *item) void spv_writer_write (struct spv_writer *w, const struct output_item *item) { - if (is_group_open_item (item)) - spv_writer_open_heading (w, item); - else if (is_group_close_item (item)) - spv_writer_close_heading (w); - else if (is_table_item (item)) - spv_writer_put_table (w, to_table_item (item)); - else if (is_chart_item (item)) - { - cairo_surface_t *surface = xr_draw_image_chart ( - to_chart_item (item), - &(struct cell_color) CELL_COLOR_BLACK, - &(struct cell_color) CELL_COLOR_WHITE); - if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS) - spv_writer_put_image (w, item, surface); - cairo_surface_destroy (surface); - } - else if (is_image_item (item)) - spv_writer_put_image (w, item, to_image_item (item)->image); - else if (is_text_item (item)) - spv_writer_put_text (w, to_text_item (item)); - else if (is_page_break_item (item)) - w->need_page_break = true; - else if (is_page_setup_item (item)) + switch (item->type) { + case OUTPUT_ITEM_CHART: + { + cairo_surface_t *surface = xr_draw_image_chart ( + item->chart, + &(struct cell_color) CELL_COLOR_BLACK, + &(struct cell_color) CELL_COLOR_WHITE); + if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS) + spv_writer_put_image (w, item, surface); + cairo_surface_destroy (surface); + } + break; + + case OUTPUT_ITEM_GROUP_OPEN: + spv_writer_open_heading (w, item); + break; + + case OUTPUT_ITEM_GROUP_CLOSE: + spv_writer_close_heading (w); + break; + + case OUTPUT_ITEM_IMAGE: + spv_writer_put_image (w, item, item->image); + break; + + case OUTPUT_ITEM_MESSAGE: + spv_writer_put_text ( + w, message_item_to_text_item (output_item_ref (item))); + break; + + case OUTPUT_ITEM_PAGE_BREAK: + w->need_page_break = true; + break; + + case OUTPUT_ITEM_PAGE_SETUP: page_setup_destroy (w->page_setup); - w->page_setup = page_setup_clone (to_page_setup_item (item)->page_setup); + w->page_setup = page_setup_clone (item->page_setup); + break; + + case OUTPUT_ITEM_TABLE: + spv_writer_put_table (w, item); + break; + + case OUTPUT_ITEM_TEXT: + spv_writer_put_text (w, output_item_ref (item)); + break; } } diff --git a/src/output/spv/spv.c b/src/output/spv/spv.c index c355a625dc..fdafb5aba7 100644 --- a/src/output/spv/spv.c +++ b/src/output/spv/spv.c @@ -31,7 +31,7 @@ #include "libpspp/message.h" #include "libpspp/str.h" #include "libpspp/zip-reader.h" -#include "output/page-setup-item.h" +#include "output/page-setup.h" #include "output/pivot-table.h" #include "output/spv/detail-xml-parser.h" #include "output/spv/light-binary-parser.h" diff --git a/src/output/table-item.c b/src/output/table-item.c deleted file mode 100644 index 5d63be972a..0000000000 --- a/src/output/table-item.c +++ /dev/null @@ -1,88 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2009, 2011, 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include "output/table-provider.h" - -#include - -#include "libpspp/assertion.h" -#include "libpspp/cast.h" -#include "output/driver.h" -#include "output/output-item-provider.h" -#include "output/pivot-table.h" -#include "output/table-item.h" -#include "output/table-provider.h" - -#include "gl/xalloc.h" - -#include "gettext.h" -#define _(msgid) gettext (msgid) - -/* Initializes ITEM as a table item for rendering PT. Takes ownership of - PT. */ -struct table_item * -table_item_create (struct pivot_table *pt) -{ - pivot_table_assign_label_depth (pt); - - struct table_item *item = xmalloc (sizeof *item); - *item = (struct table_item) { - .output_item = OUTPUT_ITEM_INITIALIZER (&table_item_class), - .output_item.command_name = xstrdup_if_nonnull (pt->command_c), - .pt = pt, - }; - return item; -} - -/* Submits TABLE_ITEM to the configured output drivers, and transfers ownership - to the output subsystem. */ -void -table_item_submit (struct table_item *table_item) -{ - output_submit (&table_item->output_item); -} - -static const char * -table_item_get_label (const struct output_item *output_item) -{ - struct table_item *item = to_table_item (output_item); - - if (!item->cached_label) - { - if (!item->pt->title) - return _("Table"); - - item->cached_label = pivot_value_to_string (item->pt->title, item->pt); - } - return item->cached_label; -} - -static void -table_item_destroy (struct output_item *output_item) -{ - struct table_item *item = to_table_item (output_item); - pivot_table_unref (item->pt); - free (item->cached_label); - free (item); -} - -const struct output_item_class table_item_class = - { - table_item_get_label, - table_item_destroy, - }; diff --git a/src/output/table-item.h b/src/output/table-item.h deleted file mode 100644 index be09876596..0000000000 --- a/src/output/table-item.h +++ /dev/null @@ -1,102 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2009, 2011, 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef OUTPUT_TABLE_ITEM_H -#define OUTPUT_TABLE_ITEM_H 1 - -/* Table items. - - A table item is a subclass of an output item (see output-item.h) that - contains a table (see table.h) and some formatting properties. Currently - the formatting properties are an optional title (a brief description - typically displayed above the table) and an optional caption (a more verbose - description typically displayed below the table). */ - -#include "libpspp/compiler.h" -#include "output/output-item.h" -#include "output/table.h" - -/* A table item. - - The members of struct table_item should not be accessed directly. Use one - of the accessor functions defined below. */ -struct table_item - { - struct output_item output_item; /* Superclass. */ - struct pivot_table *pt; /* The table to be rendered. */ - - char *cached_label; - }; - -struct table_item *table_item_create (struct pivot_table *); - -/* This boilerplate for table_item, a subclass of output_item, was - autogenerated by mk-class-boilerplate. */ - -#include -#include "libpspp/cast.h" - -extern const struct output_item_class table_item_class; - -/* Returns true if SUPER is a table_item, otherwise false. */ -static inline bool -is_table_item (const struct output_item *super) -{ - return super->class == &table_item_class; -} - -/* Returns SUPER converted to table_item. SUPER must be a table_item, as - reported by is_table_item. */ -static inline struct table_item * -to_table_item (const struct output_item *super) -{ - assert (is_table_item (super)); - return UP_CAST (super, struct table_item, output_item); -} - -/* Returns INSTANCE converted to output_item. */ -static inline struct output_item * -table_item_super (const struct table_item *instance) -{ - return CONST_CAST (struct output_item *, &instance->output_item); -} - -/* Increments INSTANCE's reference count and returns INSTANCE. */ -static inline struct table_item * -table_item_ref (const struct table_item *instance) -{ - return to_table_item (output_item_ref (&instance->output_item)); -} - -/* Decrements INSTANCE's reference count, then destroys INSTANCE if - the reference count is now zero. */ -static inline void -table_item_unref (struct table_item *instance) -{ - output_item_unref (&instance->output_item); -} - -/* Returns true if INSTANCE's reference count is greater than 1, - false otherwise. */ -static inline bool -table_item_is_shared (const struct table_item *instance) -{ - return output_item_is_shared (&instance->output_item); -} - -void table_item_submit (struct table_item *); - -#endif /* output/table-item.h */ diff --git a/src/output/table.c b/src/output/table.c index eabcc85b89..442b765134 100644 --- a/src/output/table.c +++ b/src/output/table.c @@ -29,10 +29,9 @@ #include "libpspp/compiler.h" #include "libpspp/pool.h" #include "libpspp/str.h" +#include "output/output-item.h" #include "output/pivot-table.h" -#include "output/table-item.h" #include "output/table.h" -#include "output/text-item.h" #include "gl/xalloc.h" diff --git a/src/output/table.h b/src/output/table.h index 51cb1f4242..add7bf94be 100644 --- a/src/output/table.h +++ b/src/output/table.h @@ -26,9 +26,9 @@ broken across more than one page, those rows or columns are repeated on each page. - A table is not itself an output_item, and thus a table cannot by itself be - used for output, but they can be embedded inside struct table_item (see - table-item.h) for that purpose. */ + Some drivers use tables as an implementation detail of rendering pivot + tables. +*/ #include #include diff --git a/src/output/tex.c b/src/output/tex.c index e569a12788..b9a90df2d7 100644 --- a/src/output/tex.c +++ b/src/output/tex.c @@ -37,17 +37,12 @@ #include "libpspp/temp-file.h" #include "libpspp/version.h" #include "output/cairo-chart.h" -#include "output/chart-item.h" #include "output/driver-provider.h" -#include "output/image-item.h" -#include "output/message-item.h" #include "output/options.h" -#include "output/output-item-provider.h" +#include "output/output-item.h" #include "output/pivot-output.h" #include "output/pivot-table.h" #include "output/table-provider.h" -#include "output/table-item.h" -#include "output/text-item.h" #include "output/tex-rendering.h" #include "output/tex-parsing.h" @@ -104,7 +99,7 @@ shipout (struct ll_list *list, const char *str, ...) static const struct output_driver_class tex_driver_class; -static void tex_output_table (struct tex_driver *, const struct table_item *); +static void tex_output_table (struct tex_driver *, const struct pivot_table *); static struct tex_driver * tex_driver_cast (struct output_driver *driver) @@ -308,79 +303,96 @@ tex_escape_string (struct tex_driver *tex, const char *text, } static void -tex_submit (struct output_driver *driver, - const struct output_item *output_item) +tex_submit (struct output_driver *driver, const struct output_item *item) { struct tex_driver *tex = tex_driver_cast (driver); - if (is_table_item (output_item)) + switch (item->type) { - struct table_item *table_item = to_table_item (output_item); - tex_output_table (tex, table_item); - } - else if (is_image_item (output_item) && tex->chart_file_name != NULL) - { - struct image_item *image_item = to_image_item (output_item); - char *file_name = xr_write_png_image ( - image_item->image, tex->chart_file_name, tex->chart_cnt++); - if (file_name != NULL) - { - shipout (&tex->token_list, "\\includegraphics{%s}\n", file_name); - tex->require_graphics = true; - free (file_name); - } - } - else if (is_chart_item (output_item) && tex->chart_file_name != NULL) - { - struct chart_item *chart_item = to_chart_item (output_item); - char *file_name = xr_draw_png_chart (chart_item, tex->chart_file_name, - tex->chart_cnt++, - &tex->fg, - &tex->bg); - if (file_name != NULL) + case OUTPUT_ITEM_CHART: + if (tex->chart_file_name != NULL) { - //const char *title = chart_item_get_title (chart_item); - // printf ("The chart title is %s\n", title); - - shipout (&tex->token_list, "\\includegraphics{%s}\n", file_name); - tex->require_graphics = true; - free (file_name); - } - } - else if (is_text_item (output_item)) - { - struct text_item *text_item = to_text_item (output_item); - char *s = text_item_get_plain_text (text_item); + char *file_name = xr_draw_png_chart (item->chart, + tex->chart_file_name, + tex->chart_cnt++, + &tex->fg, &tex->bg); + if (file_name != NULL) + { + //const char *title = chart_item_get_title (chart_item); + // printf ("The chart title is %s\n", title); - switch (text_item_get_type (text_item)) - { - case TEXT_ITEM_PAGE_TITLE: - shipout (&tex->token_list, "\\headline={\\bf "); - tex_escape_string (tex, s, false); - shipout (&tex->token_list, "\\hfil}\n"); - break; - - case TEXT_ITEM_LOG: - shipout (&tex->token_list, "{\\tt "); - tex_escape_string (tex, s, false); - shipout (&tex->token_list, "}\\par\n\n"); - break; - - case TEXT_ITEM_SYNTAX: - /* So far as I'm aware, this can never happen. */ - default: - printf ("Unhandled type %d\n", text_item_get_type (text_item)); - break; + shipout (&tex->token_list, "\\includegraphics{%s}\n", file_name); + tex->require_graphics = true; + free (file_name); + } } - free (s); - } - else if (is_message_item (output_item)) - { - const struct message_item *message_item = to_message_item (output_item); - char *s = msg_to_string (message_item_get_msg (message_item)); - tex_escape_string (tex, s, false); - shipout (&tex->token_list, "\\par\n"); - free (s); + break; + + case OUTPUT_ITEM_GROUP_OPEN: + break; + + case OUTPUT_ITEM_GROUP_CLOSE: + break; + + case OUTPUT_ITEM_IMAGE: + { + char *file_name = xr_write_png_image ( + item->image, tex->chart_file_name, tex->chart_cnt++); + if (file_name != NULL) + { + shipout (&tex->token_list, "\\includegraphics{%s}\n", file_name); + tex->require_graphics = true; + free (file_name); + } + } + break; + + case OUTPUT_ITEM_MESSAGE: + { + char *s = msg_to_string (item->message); + tex_escape_string (tex, s, false); + shipout (&tex->token_list, "\\par\n"); + free (s); + } + break; + + case OUTPUT_ITEM_PAGE_BREAK: + break; + + case OUTPUT_ITEM_PAGE_SETUP: + break; + + case OUTPUT_ITEM_TABLE: + tex_output_table (tex, item->table); + break; + + case OUTPUT_ITEM_TEXT: + { + char *s = text_item_get_plain_text (item); + + switch (item->text.subtype) + { + case TEXT_ITEM_PAGE_TITLE: + shipout (&tex->token_list, "\\headline={\\bf "); + tex_escape_string (tex, s, false); + shipout (&tex->token_list, "\\hfil}\n"); + break; + + case TEXT_ITEM_LOG: + shipout (&tex->token_list, "{\\tt "); + tex_escape_string (tex, s, false); + shipout (&tex->token_list, "}\\par\n\n"); + break; + + case TEXT_ITEM_SYNTAX: + /* So far as I'm aware, this can never happen. */ + default: + printf ("Unhandled type %d\n", item->text.subtype); + break; + } + free (s); + } + break; } } @@ -590,11 +602,11 @@ tex_output_table_layer (struct tex_driver *tex, const struct pivot_table *pt, } static void -tex_output_table (struct tex_driver *tex, const struct table_item *item) +tex_output_table (struct tex_driver *tex, const struct pivot_table *pt) { size_t *layer_indexes; - PIVOT_OUTPUT_FOR_EACH_LAYER (layer_indexes, item->pt, true) - tex_output_table_layer (tex, item->pt, layer_indexes); + PIVOT_OUTPUT_FOR_EACH_LAYER (layer_indexes, pt, true) + tex_output_table_layer (tex, pt, layer_indexes); } struct output_driver_factory tex_driver_factory = diff --git a/src/output/text-item.c b/src/output/text-item.c deleted file mode 100644 index 6b0d75f374..0000000000 --- a/src/output/text-item.c +++ /dev/null @@ -1,252 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2009, 2010, 2011 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include "output/text-item.h" - -#include -#include - -#include "libpspp/cast.h" -#include "libpspp/pool.h" -#include "output/driver.h" -#include "output/output-item-provider.h" -#include "output/pivot-table.h" -#include "output/table.h" -#include "output/table-item.h" -#include "output/table-provider.h" - -#include "gl/xalloc.h" -#include "gl/xvasprintf.h" - -#include "gettext.h" -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid - -const char * -text_item_type_to_string (enum text_item_type type) -{ - switch (type) - { - case TEXT_ITEM_PAGE_TITLE: - return _("Page Title"); - - case TEXT_ITEM_TITLE: - return _("Title"); - - case TEXT_ITEM_SYNTAX: - case TEXT_ITEM_LOG: - return _("Log"); - - default: - return _("Text"); - } -} - -/* Creates and returns a new text item containing TEXT and the specified TYPE - and LABEL. The new text item takes ownership of TEXT and LABEL. If LABEL - is NULL, uses the default label for TYPE. */ -struct text_item * -text_item_create_nocopy (enum text_item_type type, char *text, char *label) -{ - return text_item_create_value (type, pivot_value_new_user_text_nocopy (text), - label); -} - -/* Creates and returns a new text item containing a copy of TEXT and the - specified TYPE and LABEL. The caller retains ownership of TEXT and LABEL. - If LABEL is null, uses a default label for TYPE. */ -struct text_item * -text_item_create (enum text_item_type type, const char *text, - const char *label) -{ - return text_item_create_nocopy (type, xstrdup (text), - xstrdup_if_nonnull (label)); -} - -/* Creates and returns a new text item containing VALUE, TYPE, and LABEL. - Takes ownership of VALUE and LABEL. If LABEL is null, uses a default label - for TYPE. */ -struct text_item * -text_item_create_value (enum text_item_type type, struct pivot_value *value, - char *label) -{ - if (type == TEXT_ITEM_SYNTAX || type == TEXT_ITEM_LOG) - { - if (!value->font_style) - { - value->font_style = xmalloc (sizeof *value->font_style); - *value->font_style = (struct font_style) FONT_STYLE_INITIALIZER; - } - - free (value->font_style->typeface); - value->font_style->typeface = xstrdup ("Monospaced"); - } - - struct text_item *item = xzalloc (sizeof *item); - *item = (struct text_item) { - .output_item = OUTPUT_ITEM_INITIALIZER (&text_item_class), - .output_item.command_name = xstrdup_if_nonnull (output_get_command_name ()), - .output_item.label = label, - .type = type, - .text = value, - }; - return item; -} - -/* Returns ITEM's type. */ -enum text_item_type -text_item_get_type (const struct text_item *item) -{ - return item->type; -} - -/* Returns ITEM's text, which the caller must eventually free. */ -char * -text_item_get_plain_text (const struct text_item *item) -{ - return pivot_value_to_string_defaults (item->text); -} - -/* Submits ITEM to the configured output drivers, and transfers ownership to - the output subsystem. */ -void -text_item_submit (struct text_item *item) -{ - output_submit (&item->output_item); -} - -struct text_item * -text_item_unshare (struct text_item *old) -{ - assert (old->output_item.ref_cnt > 0); - if (!text_item_is_shared (old)) - return old; - text_item_unref (old); - - struct text_item *new = xmalloc (sizeof *new); - *new = (struct text_item) { - .output_item = OUTPUT_ITEM_CLONE_INITIALIZER (&old->output_item), - .text = pivot_value_clone (old->text), - .type = old->type, - }; - return new; -} - -static bool -nullable_font_style_equal (const struct font_style *a, - const struct font_style *b) -{ - return a && b ? font_style_equal (a, b) : !a && !b; -} - -/* Attempts to append the text in SRC to DST. If successful, returns true, - otherwise false. - - Only TEXT_ITEM_SYNTAX and TEXT_ITEM_LOG items can be combined, and not with - each other. - - DST must not be shared. */ -bool -text_item_append (struct text_item *dst, const struct text_item *src) -{ - assert (!text_item_is_shared (dst)); - if (dst->type != src->type - || (dst->type != TEXT_ITEM_SYNTAX && dst->type != TEXT_ITEM_LOG) - || strcmp (output_item_get_label (&dst->output_item), - output_item_get_label (&src->output_item)) - || !nullable_font_style_equal (dst->text->font_style, - src->text->font_style) - || (dst->text->font_style && dst->text->font_style->markup) - || src->text->type != PIVOT_VALUE_TEXT - || dst->text->type != PIVOT_VALUE_TEXT) - return false; - else - { - char *new_text = xasprintf ("%s\n%s", dst->text->text.local, - src->text->text.local); - - free (dst->text->text.local); - if (dst->text->text.c != dst->text->text.local) - free (dst->text->text.c); - if (dst->text->text.id != dst->text->text.local - && dst->text->text.id != dst->text->text.c) - free (dst->text->text.id); - - dst->text->text.local = new_text; - dst->text->text.c = new_text; - dst->text->text.id = new_text; - - return true; - } -} - -static const struct pivot_table_look * -text_item_table_look (void) -{ - static struct pivot_table_look *look; - if (!look) - { - look = pivot_table_look_new_builtin_default (); - - for (int a = 0; a < PIVOT_N_AREAS; a++) - memset (look->areas[a].cell_style.margin, 0, - sizeof look->areas[a].cell_style.margin); - for (int b = 0; b < PIVOT_N_BORDERS; b++) - look->borders[b].stroke = TABLE_STROKE_NONE; - } - return look; -} - -struct table_item * -text_item_to_table_item (struct text_item *text_item) -{ - struct pivot_table *table = pivot_table_create__ (NULL, "Text"); - pivot_table_set_look (table, text_item_table_look ()); - - struct pivot_dimension *d = pivot_dimension_create ( - table, PIVOT_AXIS_ROW, N_("Text")); - d->hide_all_labels = true; - pivot_category_create_leaf (d->root, pivot_value_new_text ("null")); - - pivot_table_put1 (table, 0, pivot_value_clone (text_item->text)); - - text_item_unref (text_item); - - return table_item_create (table); -} - -static const char * -text_item_get_label (const struct output_item *output_item) -{ - const struct text_item *item = to_text_item (output_item); - return text_item_type_to_string (item->type); -} - -static void -text_item_destroy (struct output_item *output_item) -{ - struct text_item *item = to_text_item (output_item); - pivot_value_destroy (item->text); - free (item); -} - -const struct output_item_class text_item_class = - { - text_item_get_label, - text_item_destroy, - }; diff --git a/src/output/text-item.h b/src/output/text-item.h deleted file mode 100644 index 49b5bbe1eb..0000000000 --- a/src/output/text-item.h +++ /dev/null @@ -1,122 +0,0 @@ -/* PSPP - a program for statistical analysis. - Copyright (C) 2009, 2010, 2011 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef OUTPUT_TEXT_ITEM_H -#define OUTPUT_TEXT_ITEM_H 1 - -/* Text items. - - A text item is a subclass of an output item (see - output/output-item.h). - - A text item is just a text string. */ - -#include -#include "libpspp/compiler.h" -#include "output/output-item.h" -#include "output/table.h" - -enum text_item_type - { - TEXT_ITEM_PAGE_TITLE, /* TITLE and SUBTITLE commands. */ - TEXT_ITEM_TITLE, /* Title. */ - TEXT_ITEM_SYNTAX, /* Syntax printback logging. */ - TEXT_ITEM_LOG, /* Other logging. */ - }; - -const char *text_item_type_to_string (enum text_item_type); - -/* A text item. */ -struct text_item - { - struct output_item output_item; - enum text_item_type type; - struct pivot_value *text; - }; - -struct text_item *text_item_create (enum text_item_type, - const char *text, const char *label); -struct text_item *text_item_create_nocopy (enum text_item_type, - char *text, char *label); -struct text_item *text_item_create_value (enum text_item_type, - struct pivot_value *value, - char *label); - -enum text_item_type text_item_get_type (const struct text_item *); -char *text_item_get_plain_text (const struct text_item *); - -struct text_item *text_item_unshare (struct text_item *); -bool text_item_append (struct text_item *dst, const struct text_item *src); - -struct table_item *text_item_to_table_item (struct text_item *); - -/* This boilerplate for text_item, a subclass of output_item, was - autogenerated by mk-class-boilerplate. */ - -#include -#include "libpspp/cast.h" - -extern const struct output_item_class text_item_class; - -/* Returns true if SUPER is a text_item, otherwise false. */ -static inline bool -is_text_item (const struct output_item *super) -{ - return super->class == &text_item_class; -} - -/* Returns SUPER converted to text_item. SUPER must be a text_item, as - reported by is_text_item. */ -static inline struct text_item * -to_text_item (const struct output_item *super) -{ - assert (is_text_item (super)); - return UP_CAST (super, struct text_item, output_item); -} - -/* Returns INSTANCE converted to output_item. */ -static inline struct output_item * -text_item_super (const struct text_item *instance) -{ - return CONST_CAST (struct output_item *, &instance->output_item); -} - -/* Increments INSTANCE's reference count and returns INSTANCE. */ -static inline struct text_item * -text_item_ref (const struct text_item *instance) -{ - return to_text_item (output_item_ref (&instance->output_item)); -} - -/* Decrements INSTANCE's reference count, then destroys INSTANCE if - the reference count is now zero. */ -static inline void -text_item_unref (struct text_item *instance) -{ - output_item_unref (&instance->output_item); -} - -/* Returns true if INSTANCE's reference count is greater than 1, - false otherwise. */ -static inline bool -text_item_is_shared (const struct text_item *instance) -{ - return output_item_is_shared (&instance->output_item); -} - -void text_item_submit (struct text_item *); - -#endif /* output/text-item.h */ diff --git a/src/ui/gui/psppire-output-view.c b/src/ui/gui/psppire-output-view.c index 746f3b942b..6d704ae1bc 100644 --- a/src/ui/gui/psppire-output-view.c +++ b/src/ui/gui/psppire-output-view.c @@ -28,14 +28,8 @@ #include "output/cairo-pager.h" #include "output/driver-provider.h" #include "output/driver.h" -#include "output/chart-item.h" -#include "output/group-item.h" -#include "output/message-item.h" #include "output/output-item.h" -#include "output/output-item-provider.h" #include "output/pivot-table.h" -#include "output/table-item.h" -#include "output/text-item.h" #include "gl/c-xvasprintf.h" #include "gl/minmax.h" @@ -331,7 +325,7 @@ rerender (struct psppire_output_view *view) if (view->y > 0) view->y += view->object_spacing; - if (is_group_open_item (item->item)) + if (item->item->type == OUTPUT_ITEM_GROUP_OPEN) continue; r = xr_fsm_create_for_scrolling (item->item, view->style, cr); @@ -358,11 +352,9 @@ rerender (struct psppire_output_view *view) gtk_layout_move (view->output, item->drawing_area, xpos, view->y); } - if (is_table_item (item->item)) - { - const struct table_item *ti = to_table_item (item->item); - gtk_widget_set_tooltip_text (item->drawing_area, ti->pt->notes); - } + if (item->item->type == OUTPUT_ITEM_TABLE) + gtk_widget_set_tooltip_text (item->drawing_area, + item->item->table->notes); { gint minw; @@ -404,7 +396,7 @@ psppire_output_view_put (struct psppire_output_view *view, GtkWidget *drawing_area; int tw, th; - if (is_group_close_item (item)) + if (item->type == OUTPUT_ITEM_GROUP_CLOSE) { if (view->cur_group) { @@ -416,10 +408,9 @@ psppire_output_view_put (struct psppire_output_view *view, } return; } - else if (is_text_item (item)) + else if (item->type == OUTPUT_ITEM_TEXT) { - const struct text_item *text_item = to_text_item (item); - char *text = text_item_get_plain_text (text_item); + char *text = text_item_get_plain_text (item); bool text_is_empty = text[0] == '\0'; free (text); if (text_is_empty) @@ -434,7 +425,7 @@ psppire_output_view_put (struct psppire_output_view *view, view_item->drawing_area = NULL; GdkWindow *win = gtk_widget_get_window (GTK_WIDGET (view->output)); - if (is_group_open_item (item)) + if (item->type == OUTPUT_ITEM_GROUP_OPEN) tw = th = 0; else if (win) { @@ -482,7 +473,7 @@ psppire_output_view_put (struct psppire_output_view *view, else gtk_tree_store_append (store, &iter, NULL); - if (is_group_open_item (item)) + if (item->type == OUTPUT_ITEM_GROUP_OPEN) { gtk_tree_path_free (view->cur_group); view->cur_group = gtk_tree_model_get_path (GTK_TREE_MODEL (store), @@ -745,8 +736,7 @@ build_target_list (const struct output_item *item) { GtkTargetList *tl = gtk_target_list_new (targets, G_N_ELEMENTS (targets)); g_return_val_if_fail (tl, NULL); - if (is_table_item (item) || - is_chart_item (item)) + if (item->type == OUTPUT_ITEM_TABLE || item->type == OUTPUT_ITEM_CHART) gtk_target_list_add_image_targets (tl, SELECT_FMT_IMG, TRUE); return tl; } @@ -1106,7 +1096,7 @@ psppire_output_view_submit (struct output_driver *this, { struct psppire_output_view_driver *povd = psppire_output_view_driver_cast (this); - if (is_table_item (item)) + if (item->type == OUTPUT_ITEM_TABLE) psppire_output_view_put (povd->view, item); } diff --git a/src/ui/gui/psppire-output-window.c b/src/ui/gui/psppire-output-window.c index 5d13ecd1ed..b7ed01a191 100644 --- a/src/ui/gui/psppire-output-window.c +++ b/src/ui/gui/psppire-output-window.c @@ -28,12 +28,8 @@ #include "libpspp/cast.h" #include "libpspp/message.h" #include "libpspp/string-map.h" -#include "output/chart-item.h" #include "output/driver-provider.h" -#include "output/message-item.h" #include "output/output-item.h" -#include "output/table-item.h" -#include "output/text-item.h" #include "ui/gui/help-menu.h" #include "ui/gui/builder-wrapper.h" #include "ui/gui/psppire-output-view.h" diff --git a/src/ui/gui/psppire-window.c b/src/ui/gui/psppire-window.c index 7ad2c5a384..4b40f94d1e 100644 --- a/src/ui/gui/psppire-window.c +++ b/src/ui/gui/psppire-window.c @@ -32,8 +32,7 @@ #include "data/file-handle-def.h" #include "data/dataset.h" #include "libpspp/version.h" -#include "output/group-item.h" -#include "output/image-item.h" +#include "output/output-item.h" #include "output/pivot-table.h" #include "output/spv/spv.h" #include "output/spv/spv-output.h" @@ -764,9 +763,9 @@ dump_heading_transition (const struct spv_item *old, break; for (size_t i = common; i < old_path.n; i++) - group_close_item_submit (group_close_item_create ()); + output_item_submit (group_close_item_create ()); for (size_t i = common; i < new_path.n; i++) - group_open_item_submit (group_open_item_create ( + output_item_submit (group_open_item_create ( new_path.nodes[i]->command_id, new_path.nodes[i]->label)); @@ -802,8 +801,8 @@ read_spv_file (const char *filename) else if (items[i]->type == SPV_ITEM_IMAGE) { cairo_surface_t *image = spv_item_get_image (items[i]); - image_item_submit (image_item_create (cairo_surface_reference ( - image))); + output_item_submit (image_item_create (cairo_surface_reference ( + image))); } prev_heading = heading; } diff --git a/src/ui/gui/psppire.c b/src/ui/gui/psppire.c index 240cca178d..e897c599b6 100644 --- a/src/ui/gui/psppire.c +++ b/src/ui/gui/psppire.c @@ -37,7 +37,7 @@ #include "output/driver.h" #include "output/journal.h" -#include "output/message-item.h" +#include "output/output-item.h" #include "output/spv/spv.h" #include "ui/gui/dict-display.h" @@ -162,7 +162,7 @@ handle_msg (const struct msg *m_, void *lexer_) } m.command_name = output_get_uppercase_command_name (); - message_item_submit (message_item_create (&m)); + output_item_submit (message_item_create (&m)); free (m.command_name); } diff --git a/src/ui/terminal/main.c b/src/ui/terminal/main.c index 06677668f4..be1d035f21 100644 --- a/src/ui/terminal/main.c +++ b/src/ui/terminal/main.c @@ -47,7 +47,7 @@ #include "libpspp/version.h" #include "math/random.h" #include "output/driver.h" -#include "output/message-item.h" +#include "output/output-item.h" #include "ui/source-init-opts.h" #include "ui/terminal/terminal-opts.h" #include "ui/terminal/terminal-reader.h" @@ -229,7 +229,7 @@ output_msg (const struct msg *m_, void *lexer_) m.command_name = output_get_uppercase_command_name (); - message_item_submit (message_item_create (&m)); + output_item_submit (message_item_create (&m)); free (m.command_name); } diff --git a/tests/output/ascii-test.c b/tests/output/ascii-test.c index 7c5d8a7cbd..f0adca4d2f 100644 --- a/tests/output/ascii-test.c +++ b/tests/output/ascii-test.c @@ -29,8 +29,8 @@ #include "libpspp/string-map.h" #include "output/ascii.h" #include "output/driver.h" +#include "output/output-item.h" #include "output/table.h" -#include "output/table-item.h" #include "gl/error.h" #include "gl/progname.h" diff --git a/tests/output/pivot-table-test.c b/tests/output/pivot-table-test.c index d7d63fd394..bf275b20d6 100644 --- a/tests/output/pivot-table-test.c +++ b/tests/output/pivot-table-test.c @@ -32,10 +32,9 @@ #include "libpspp/i18n.h" #include "libpspp/string-map.h" #include "output/driver.h" -#include "output/message-item.h" #include "output/options.h" +#include "output/output-item.h" #include "output/pivot-table.h" -#include "output/table-item.h" #include "gl/error.h" #include "gl/progname.h" @@ -1239,7 +1238,7 @@ output_msg (const struct msg *m_, void *lexer_) m.command_name = output_get_uppercase_command_name (); - message_item_submit (message_item_create (&m)); + output_item_submit (message_item_create (&m)); free (m.command_name); } diff --git a/utilities/pspp-output.c b/utilities/pspp-output.c index 5332f2f1a5..971d86b8c9 100644 --- a/utilities/pspp-output.c +++ b/utilities/pspp-output.c @@ -31,9 +31,7 @@ #include "libpspp/string-map.h" #include "libpspp/string-set.h" #include "output/driver.h" -#include "output/group-item.h" -#include "output/image-item.h" -#include "output/page-setup-item.h" +#include "output/output-item.h" #include "output/pivot-table.h" #include "output/spv/light-binary-parser.h" #include "output/spv/spv-legacy-data.h" @@ -42,8 +40,6 @@ #include "output/spv/spv-select.h" #include "output/spv/spv-table-look.h" #include "output/spv/spv.h" -#include "output/table-item.h" -#include "output/text-item.h" #include "gl/c-ctype.h" #include "gl/error.h" @@ -112,8 +108,8 @@ dump_item (const struct spv_item *item) char *s = (x && b ? xasprintf ("%s and %s:", x, b) : xasprintf ("%s:", x ? x : b)); - text_item_submit (text_item_create_nocopy (TEXT_ITEM_TITLE, s, - xstrdup ("Member Names"))); + output_item_submit (text_item_create_nocopy (TEXT_ITEM_TITLE, s, + xstrdup ("Member Names"))); } switch (spv_item_get_type (item)) @@ -136,8 +132,8 @@ dump_item (const struct spv_item *item) break; case SPV_ITEM_IMAGE: - image_item_submit (image_item_create (cairo_surface_reference ( - spv_item_get_image (item)))); + output_item_submit (image_item_create (cairo_surface_reference ( + spv_item_get_image (item)))); break; case SPV_ITEM_TREE: @@ -288,11 +284,11 @@ dump_heading_transition (const struct spv_item *old, break; for (size_t i = common; i < old_path.n; i++) - group_close_item_submit (group_close_item_create ()); + output_item_submit (group_close_item_create ()); for (size_t i = common; i < new_path.n; i++) - group_open_item_submit (group_open_item_create ( - new_path.nodes[i]->command_id, - new_path.nodes[i]->label)); + output_item_submit (group_open_item_create ( + new_path.nodes[i]->command_id, + new_path.nodes[i]->label)); free_path (&old_path); free_path (&new_path); @@ -319,7 +315,7 @@ run_convert (int argc UNUSED, char **argv) const struct page_setup *ps = spv_get_page_setup (spv); if (ps) - page_setup_item_submit (page_setup_item_create (ps)); + output_item_submit (page_setup_item_create (ps)); struct spv_item **items; size_t n_items;