render: Render table_items instead of tables.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 7 Sep 2014 18:22:35 +0000 (11:22 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 13 Sep 2014 18:07:03 +0000 (11:07 -0700)
A table_item includes the caption, which future commits will want to have
render_pager render, so the table_item is a more natural target.

13 files changed:
src/output/ascii.c
src/output/cairo.c
src/output/csv.c
src/output/html.c
src/output/odt.c
src/output/render.c
src/output/render.h
src/output/tab.c
src/output/tab.h
src/output/table-provider.h
src/output/table.c
src/output/table.h
tests/output/render-test.c

index 3548844693d09380dbfbe73a5ac696b3595b88d9..a2915ee8f7c6fbedde5a1d88b89d2bd032b2770b 100644 (file)
@@ -461,8 +461,7 @@ ascii_output_table_item (struct ascii_driver *a,
   if (a->file == NULL && !ascii_open_page (a))
     return;
 
-  p = render_pager_create (render_page_create (&params, table_item_get_table (
-                                                 table_item)));
+  p = render_pager_create (&params, table_item);
   while (render_pager_has_next (p))
     {
       int used;
@@ -942,7 +941,6 @@ ascii_layout_subtable (struct ascii_driver *a,
                        int bb[TABLE_N_AXES][2], int clip[TABLE_N_AXES][2] UNUSED,
                        int *widthp)
 {
-  const struct table *table = contents->table;
   struct render_params params;
   struct render_pager *p;
   int r[TABLE_N_AXES][2];
@@ -966,7 +964,7 @@ ascii_layout_subtable (struct ascii_driver *a,
       params.line_widths[V][i] = width;
     }
 
-  p = render_pager_create (render_page_create (&params, table));
+  p = render_pager_create (&params, contents->table);
   width = render_pager_get_size (p, TABLE_HORZ);
   height = render_pager_get_size (p, TABLE_VERT);
 
index 22e060cf936d33bd915a235e5a563be139312f8d..3e8c256f8193f31e4ffc71b513c7e034b4b28556 100644 (file)
@@ -565,8 +565,7 @@ xr_render_table_item (struct xr_driver *xr, const struct table_item *item,
   else
     *caption_heightp = 0;
 
-  return render_pager_create (render_page_create (xr->params,
-                                                  table_item_get_table (item)));
+  return render_pager_create (xr->params, item);
 }
 
 static void
@@ -1045,7 +1044,6 @@ xr_layout_cell_subtable (struct xr_driver *xr,
                          int bb[TABLE_N_AXES][2],
                          int clip[TABLE_N_AXES][2], int *widthp, int *brk)
 {
-  const struct table *table = contents->table;
   int single_width, double_width;
   struct render_params params;
   struct render_pager *p;
@@ -1074,7 +1072,7 @@ xr_layout_cell_subtable (struct xr_driver *xr,
     }
 
   xr->nest++;
-  p = render_pager_create (render_page_create (&params, table));
+  p = render_pager_create (&params, contents->table);
   width = render_pager_get_size (p, H);
   height = render_pager_get_size (p, V);
   if (bb[V][0] + height >= bb[V][1])
index 9be53c8b0f0c92716fc0fe397e23289f7c0a0847..bd61c51a62e63175b66cacd3dc69a6a5e24dd08d 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2009, 2010, 2012, 2013 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010, 2012, 2013, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -147,6 +147,20 @@ csv_output_field (struct csv_driver *csv, const char *field)
     fputs (field, csv->file);
 }
 
+static void PRINTF_FORMAT (2, 3)
+csv_output_field_format (struct csv_driver *csv, const char *format, ...)
+{
+  va_list args;
+  char *s;
+
+  va_start (args, format);
+  s = xvasprintf (format, args);
+  va_end (args);
+
+  csv_output_field (csv, s);
+  free (s);
+}
+
 static void
 csv_put_field (struct csv_driver *csv, struct string *s, const char *field)
 {
@@ -172,10 +186,18 @@ csv_put_field (struct csv_driver *csv, struct string *s, const char *field)
 
 static void
 csv_output_subtable (struct csv_driver *csv, struct string *s,
-                     const struct table *t)
+                     const struct table_item *item)
 {
+  const struct table *t = table_item_get_table (item);
+  const char *caption = table_item_get_caption (item);
   int y, x;
 
+  if (csv->captions && caption != NULL)
+    {
+      csv_output_field_format (csv, "Table: %s", caption);
+      putc ('\n', csv->file);
+    }
+
   for (y = 0; y < table_nr (t); y++)
     {
       if (y > 0)
@@ -219,24 +241,6 @@ csv_output_subtable (struct csv_driver *csv, struct string *s,
     }
 }
 
-static void
-csv_output_field_format (struct csv_driver *csv, const char *format, ...)
-  PRINTF_FORMAT (2, 3);
-
-static void
-csv_output_field_format (struct csv_driver *csv, const char *format, ...)
-{
-  va_list args;
-  char *s;
-
-  va_start (args, format);
-  s = xvasprintf (format, args);
-  va_end (args);
-
-  csv_output_field (csv, s);
-  free (s);
-}
-
 static void
 csv_put_separator (struct csv_driver *csv)
 {
index 3e85b3d968b69c76653775a7239f10c9e08869e3..82478d189bdd8dd44f87e87023287532b2c6e515 100644 (file)
@@ -64,8 +64,7 @@ struct html_driver
 
 static const struct output_driver_class html_driver_class;
 
-static void html_output_table (struct html_driver *, const struct table *,
-                               const char *caption);
+static void html_output_table (struct html_driver *, const struct table_item *);
 static void escape_string (FILE *file,
                            const char *text, size_t length,
                            const char *space, const char *newline);
@@ -236,8 +235,7 @@ html_submit (struct output_driver *driver,
   if (is_table_item (output_item))
     {
       struct table_item *table_item = to_table_item (output_item);
-      html_output_table (html, table_item_get_table (table_item),
-                         table_item_get_caption (table_item));
+      html_output_table (html, table_item);
     }
 #ifdef HAVE_CAIRO
   else if (is_chart_item (output_item) && html->chart_file_name != NULL)
@@ -376,9 +374,10 @@ put_border (FILE *file, int n_borders, int style, const char *border_name)
 }
 
 static void
-html_output_table (struct html_driver *html,
-                   const struct table *t, const char *caption)
+html_output_table (struct html_driver *html, const struct table_item *item)
 {
+  const struct table *t = table_item_get_table (item);
+  const char *caption = table_item_get_caption (item);
   int x, y;
 
   fputs ("<TABLE><TBODY VALIGN=\"TOP\">\n", html->file);
@@ -486,7 +485,7 @@ html_output_table (struct html_driver *html,
                     fputs ("</EM>", html->file);
                 }
               else
-                html_output_table (html, c->table, NULL);
+                html_output_table (html, c->table);
             }
 
           /* Output </TH> or </TD>. */
index 1b637f20b7695d235ed872ee73ae833628efcad4..0d4625c8d4d39ba61046c838aa632fa6d748e811 100644 (file)
@@ -75,8 +75,6 @@ struct odt_driver
 
 static const struct output_driver_class odt_driver_class;
 
-static void write_table (struct odt_driver *, const struct table *);
-
 static struct odt_driver *
 odt_driver_cast (struct output_driver *driver)
 {
@@ -413,9 +411,11 @@ write_xml_with_line_breaks (xmlTextWriterPtr writer, char *line)
 }
 
 static void
-odt_submit_table (struct odt_driver *odt, struct table_item *item)
+write_table (struct odt_driver *odt, const struct table_item *item)
 {
+  const struct table *tab = table_item_get_table (item);
   const char *caption = table_item_get_caption (item);
+  int r, c;
 
   /* Write a heading for the table */
   if (caption != NULL)
@@ -428,14 +428,6 @@ odt_submit_table (struct odt_driver *odt, struct table_item *item)
       xmlTextWriterEndElement (odt->content_wtr);
     }
 
-  write_table (odt, table_item_get_table (item));
-}
-
-static void
-write_table (struct odt_driver *odt, const struct table *tab)
-{
-  int r, c;
-
   /* Start table */
   xmlTextWriterStartElement (odt->content_wtr, _xml("table:table"));
   xmlTextWriterWriteFormatAttribute (odt->content_wtr, _xml("table:name"), 
@@ -553,7 +545,7 @@ odt_submit (struct output_driver *driver,
   output_driver_track_current_command (output_item, &odt->command_name);
 
   if (is_table_item (output_item))
-    odt_submit_table (odt, to_table_item (output_item));
+    write_table (odt, to_table_item (output_item));
   else if (is_text_item (output_item))
     {
       struct text_item *text_item = to_text_item (output_item);
index 35e0a7a94cb6d1382eb59d9237364e9e3f1c1f99..5f2a9d024d89215cbc77c152acc6f14307b4ddc4 100644 (file)
@@ -25,6 +25,7 @@
 #include "libpspp/hash-functions.h"
 #include "libpspp/hmap.h"
 #include "output/render.h"
+#include "output/table-item.h"
 #include "output/table.h"
 
 #include "gl/minmax.h"
 
    May represent the layout of an entire table presented to
    render_page_create(), or a rectangular subregion of a table broken out using
-   render_break_next() to allow a table to be broken across multiple pages. */
+   render_break_next() to allow a table to be broken across multiple pages.
+
+   A page's size is not limited to the size passed in as part of render_params.
+   render_pager breaks a render_page into smaller render_pages that will fit in
+   the available space. */
 struct render_page
   {
     const struct render_params *params; /* Parameters of the target device. */
@@ -120,6 +125,11 @@ struct render_page
     int *join_crossing[TABLE_N_AXES];
   };
 
+static struct render_page *render_page_create (const struct render_params *,
+                                               const struct table *);
+
+static void render_page_unref (struct render_page *);
+
 /* Returns the offset in struct render_page's cp[axis] array of the rule with
    index RULE_IDX.  That is, if RULE_IDX is 0, then the offset is that of the
    leftmost or topmost rule; if RULE_IDX is 1, then the offset is that of the
@@ -607,7 +617,7 @@ set_join_crossings (struct render_page *page, enum table_axis axis,
    The new render_page will be suitable for rendering on a device whose page
    size is PARAMS->size, but the caller is responsible for actually breaking it
    up to fit on such a device, using the render_break abstraction.  */
-struct render_page *
+static struct render_page *
 render_page_create (const struct render_params *params,
                     const struct table *table_)
 {
@@ -783,18 +793,9 @@ render_page_create (const struct render_params *params,
   return page;
 }
 
-/* Increases PAGE's reference count. */
-struct render_page *
-render_page_ref (const struct render_page *page_)
-{
-  struct render_page *page = CONST_CAST (struct render_page *, page_);
-  page->ref_cnt++;
-  return page;
-}
-
 /* Decreases PAGE's reference count and destroys PAGE if this causes the
    reference count to fall to zero. */
-void
+static void
 render_page_unref (struct render_page *page)
 {
   if (page != NULL && --page->ref_cnt == 0)
@@ -1309,12 +1310,13 @@ struct render_pager
 /* Creates and returns a new render_pager for breaking PAGE into smaller
    chunks.  Takes ownership of PAGE. */
 struct render_pager *
-render_pager_create (struct render_page *page)
+render_pager_create (const struct render_params *params,
+                     const struct table_item *table_item)
 {
   struct render_pager *p = xmalloc (sizeof *p);
-  p->width = page->params->size[H];
-  p->page = render_page_ref (page);
-  render_break_init (&p->x_break, page, H);
+  p->width = params->size[H];
+  p->page = render_page_create (params, table_item_get_table (table_item));
+  render_break_init (&p->x_break, p->page, H);
   render_break_init_empty (&p->y_break);
   return p;
 }
index 927009e9cbf0e32dca8c1ddbc154f49133c5e634..dd4b8227795490f41a86b3c58e9b4f17031b1b61 100644 (file)
@@ -21,7 +21,7 @@
 #include <stddef.h>
 #include "output/table-provider.h"
 
-struct table;
+struct table_item;
 
 enum render_line_style
   {
@@ -98,20 +98,10 @@ struct render_params
     int min_break[TABLE_N_AXES];
   };
 \f
-/* A "page" of content that is ready to be rendered.
-
-   A page's size is not limited to the size passed in as part of render_params.
-   Use render_pager (see below) to break a render_page into smaller
-   render_pages that will fit in the available space. */
-struct render_page *render_page_create (const struct render_params *,
-                                        const struct table *);
-
-struct render_page *render_page_ref (const struct render_page *);
-void render_page_unref (struct render_page *);
 \f
 /* An iterator for breaking render_pages into smaller chunks. */
-
-struct render_pager *render_pager_create (struct render_page *);
+struct render_pager *render_pager_create (const struct render_params *,
+                                          const struct table_item *);
 void render_pager_destroy (struct render_pager *);
 
 bool render_pager_has_next (const struct render_pager *);
index 2e788e5a37f9b38faa17f3b17286848bab49747b..bb6b82a2da5e843e47b3ac123eb26d23caead909 100644 (file)
@@ -56,7 +56,7 @@ struct tab_joined_cell
     union
       {
         char *text;
-        struct table *subtable;
+        struct table_item *subtable;
       }
     u;
   };
@@ -600,14 +600,14 @@ tab_joint_text_format (struct tab_table *table, int x1, int y1, int x2, int y2,
 static void
 subtable_unref (void *subtable)
 {
-  table_unref (subtable);
+  table_item_unref (subtable);
 }
 
 /* Places SUBTABLE as the content for cells (X1,X2)-(Y1,Y2) inclusive in TABLE
    with options OPT. */
 void
 tab_subtable (struct tab_table *table, int x1, int y1, int x2, int y2,
-              unsigned opt, struct table *subtable)
+              unsigned opt, struct table_item *subtable)
 {
   add_joined_cell (table, x1, y1, x2, y2, opt | TAB_SUBTABLE)->u.subtable
     = subtable;
@@ -622,10 +622,11 @@ tab_subtable (struct tab_table *table, int x1, int y1, int x2, int y2,
    as a nested table but its contents become part of TABLE. */
 void
 tab_subtable_bare (struct tab_table *table, int x1, int y1, int x2, int y2,
-                   unsigned opt, struct table *subtable)
+                   unsigned opt, struct table_item *subtable)
 {
-  assert (table_nc (subtable) == 1);
-  assert (table_nr (subtable) == 1);
+  const struct table *t UNUSED = table_item_get_table (subtable);
+  assert (table_nc (t) == 1);
+  assert (table_nr (t) == 1);
   tab_subtable (table, x1, y1, x2, y2, opt | TAB_BARE, subtable);
 }
 
@@ -761,7 +762,7 @@ tab_get_cell (const struct table *table, int x, int y, struct table_cell *cell)
           assert (opt & TAB_SUBTABLE);
 
           /* This overwrites all of the members of CELL. */
-          table_get_cell (jc->u.subtable, 0, 0, cell);
+          table_get_cell (table_item_get_table (jc->u.subtable), 0, 0, cell);
         }
       else
         {
index f0cffc17fdde48e1cdca4b9503fe659061749f35..a973b0414bee0368cf15d9a6dcc56c90a976706d 100644 (file)
@@ -144,9 +144,9 @@ void tab_joint_text_format (struct tab_table *, int x1, int y1, int x2, int y2,
      PRINTF_FORMAT (7, 8);
 
 void tab_subtable (struct tab_table *, int x1, int y1, int x2, int y2,
-                   unsigned opt, struct table *subtable);
+                   unsigned opt, struct table_item *subtable);
 void tab_subtable_bare (struct tab_table *, int x1, int y1, int x2, int y2,
-                        unsigned opt, struct table *subtable);
+                        unsigned opt, struct table_item *subtable);
 
 bool tab_cell_is_empty (const struct tab_table *, int c, int r);
 
index 97c264b4f2dc75ee17b789af89fda041c037ff1b..35a4b6cebb7164c27444c8afb786351edf42a2b7 100644 (file)
@@ -26,7 +26,7 @@ struct cell_contents
 
     /* Exactly one of these must be nonnull. */
     char *text;                 /* A paragraph of text. */
-    struct table *table;        /* A table nested within the cell. */
+    struct table_item *table;   /* A table nested within the cell. */
   };
 
 /* A cell in a table. */
index 2a08e14b5558cd50cc95386b6d2339720ce8c7bb..5dc5651fd940c0b86c5d9d6d38d5e5408fb2646f 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "libpspp/cast.h"
 #include "libpspp/compiler.h"
+#include "output/table-item.h"
 
 #include "gl/xalloc.h"
 
@@ -344,19 +345,28 @@ static const struct table_class table_string_class =
 struct table_nested
   {
     struct table table;
-    struct table *inner;
+    struct table_item *inner;
   };
 
 static const struct table_class table_nested_class;
 
-/* Creates and returns a table with a single cell that contains INNER. */
+/* Creates and returns a table with a single cell that contains INNER.
+   Takes ownership of INNER. */
 struct table *
-table_create_nested (const struct table *inner)
+table_create_nested (struct table *inner)
+{
+  return table_create_nested_item (table_item_create (inner, NULL));
+}
+
+/* Creates and returns a table with a single cell that contains INNER.
+   Takes ownership of INNER. */
+struct table *
+table_create_nested_item (struct table_item *inner)
 {
   struct table_nested *tn = xmalloc (sizeof *tn);
   table_init (&tn->table, &table_nested_class);
   tn->table.n[TABLE_HORZ] = tn->table.n[TABLE_VERT] = 1;
-  tn->inner = table_ref (inner);
+  tn->inner = table_item_ref (inner);
   return &tn->table;
 }
 
@@ -371,7 +381,7 @@ static void
 table_nested_destroy (struct table *tn_)
 {
   struct table_nested *tn = table_nested_cast (tn_);
-  table_unref (tn->inner);
+  table_item_unref (tn->inner);
   free (tn);
 }
 
index cf187f10dc325d3e28aabbcb5c2ebc3aae248011..919777db53ff3b90feaecc2c781e04ebae72a5b6 100644 (file)
@@ -40,6 +40,7 @@
 
 struct casereader;
 struct fmt_spec;
+struct table_item;
 struct variable;
 
 /* Properties of a table cell. */
@@ -170,7 +171,8 @@ struct table *table_from_casereader (const struct casereader *,
                                      size_t column,
                                      const char *heading,
                                      const struct fmt_spec *);
-struct table *table_create_nested (const struct table *);
+struct table *table_create_nested (struct table *);
+struct table *table_create_nested_item (struct table_item *);
 
 /* Combining tables. */
 struct table *table_paste (struct table *, struct table *,
index a8c912835fa942adf046222c9e0fcc31643cd4a0..38940baa0c9c6bcf1749ea1d3b492522e539e7ca 100644 (file)
@@ -458,7 +458,8 @@ read_table (FILE *stream, struct table **tables, size_t n_tables)
                   default:
                     error (1, 0, "unexpected subtable modifier \"%c\"", *text);
                   }
-              tab_subtable (tab, c, r, c + cs - 1, r + rs - 1, opt, table);
+              tab_subtable (tab, c, r, c + cs - 1, r + rs - 1, opt,
+                            table_item_create (table, NULL));
             }
           else
             tab_joint_text (tab, c, r, c + cs - 1, r + rs - 1, opt, text);