Add support for PNG images in .spv files.
[pspp] / utilities / pspp-output.c
index b3b4b57fa0fe42d2f9c88cebd462d8773a8bc85b..56a46f001d876c835936ecc172041730b3006197 100644 (file)
@@ -16,6 +16,9 @@
 
 #include <config.h>
 
+#ifdef HAVE_CAIRO
+#include <cairo.h>
+#endif
 #include <getopt.h>
 #include <limits.h>
 #include <stdlib.h>
@@ -29,6 +32,7 @@
 #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/pivot-table.h"
 #include "output/spv/light-binary-parser.h"
@@ -92,10 +96,14 @@ dump_item (const struct spv_item *item)
     {
       const char *x = item->xml_member;
       const char *b = item->bin_member;
+
+      /* The strings below are not marked for translation because they are only
+         useful to developers. */
       char *s = (x && b
-                 ? xasprintf (_("%s and %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));
+      text_item_submit (text_item_create_nocopy (TEXT_ITEM_TITLE, s,
+                                                 xstrdup ("Member Names")));
     }
 
   switch (spv_item_get_type (item))
@@ -117,7 +125,11 @@ dump_item (const struct spv_item *item)
     case SPV_ITEM_MODEL:
       break;
 
-    case SPV_ITEM_OBJECT:
+    case SPV_ITEM_IMAGE:
+#ifdef HAVE_CAIRO
+      image_item_submit (image_item_create (cairo_surface_reference (
+                                              spv_item_get_image (item))));
+#endif
       break;
 
     case SPV_ITEM_TREE:
@@ -144,9 +156,7 @@ print_item_directory (const struct spv_item *item)
   if (type == SPV_ITEM_TABLE)
     {
       const struct pivot_table *table = spv_item_get_table (item);
-      char *title = pivot_value_to_string (table->title,
-                                           SETTINGS_VALUE_SHOW_DEFAULT,
-                                           SETTINGS_VALUE_SHOW_DEFAULT);
+      char *title = pivot_value_to_string (table->title, table);
       if (!label || strcmp (title, label))
         printf (" title \"%s\"", title);
       free (title);
@@ -162,14 +172,19 @@ print_item_directory (const struct spv_item *item)
 
   if (!spv_item_is_visible (item))
     printf (" (hidden)");
-  if (show_member_names && (item->xml_member || item->bin_member))
+
+  if (show_member_names)
     {
-      if (item->xml_member && item->bin_member)
-        printf (" in %s and %s", item->xml_member, item->bin_member);
-      else if (item->xml_member)
-        printf (" in %s", item->xml_member);
-      else if (item->bin_member)
-        printf (" in %s", item->bin_member);
+      const char *members[] = {
+        item->xml_member,
+        item->bin_member,
+        item->png_member,
+      };
+      size_t n = 0;
+
+      for (size_t i = 0; i < sizeof members / sizeof *members; i++)
+        if (members[i])
+          printf (" %s %s", n++ == 0 ? "in" : "and", members[i]);
     }
   putchar ('\n');
 }
@@ -268,7 +283,8 @@ dump_heading_transition (const struct spv_item *old,
     group_close_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]->command_id,
+                              new_path.nodes[i]->label));
 
   free_path (&old_path);
   free_path (&new_path);
@@ -346,20 +362,30 @@ get_first_table (const struct spv_reader *spv)
 static void
 run_get_table_look (int argc UNUSED, char **argv)
 {
-  struct spv_reader *spv;
-  char *err = spv_open (argv[1], &spv);
-  if (err)
-    error (1, 0, "%s", err);
+  struct pivot_table_look *look;
+  if (strcmp (argv[1], "-"))
+    {
+      struct spv_reader *spv;
+      char *err = spv_open (argv[1], &spv);
+      if (err)
+        error (1, 0, "%s", err);
+
+      const struct pivot_table *table = get_first_table (spv);
+      if (!table)
+        error (1, 0, "%s: no tables found", argv[1]);
 
-  const struct pivot_table *table = get_first_table (spv);
-  if (!table)
-    error (1, 0, "%s: no tables found", argv[1]);
+      look = pivot_table_look_ref (pivot_table_get_look (table));
 
-  err = spv_table_look_write (argv[2], pivot_table_get_look (table));
+      spv_close (spv);
+    }
+  else
+    look = pivot_table_look_ref (pivot_table_look_builtin_default ());
+
+  char *err = spv_table_look_write (argv[2], look);
   if (err)
     error (1, 0, "%s", err);
 
-  spv_close (spv);
+  pivot_table_look_unref (look);
 }
 
 static void
@@ -374,7 +400,7 @@ run_convert_table_look (int argc UNUSED, char **argv)
   if (err)
     error (1, 0, "%s", err);
 
-  pivot_table_look_uninit (look);
+  pivot_table_look_unref (look);
   free (look);
 }
 
@@ -808,11 +834,7 @@ main (int argc, char **argv)
 
   c->run (argc, argv);
 
-  if (table_look)
-    {
-      pivot_table_look_uninit (table_look);
-      free (table_look);
-    }
+  pivot_table_look_unref (table_look);
   i18n_done ();
 
   return n_warnings ? EXIT_FAILURE : EXIT_SUCCESS;
@@ -942,11 +964,7 @@ parse_members (const char *arg)
 static void
 parse_table_look (const char *arg)
 {
-  if (table_look)
-    {
-      pivot_table_look_uninit (table_look);
-      free (table_look);
-    }
+  pivot_table_look_unref (table_look);
 
   char *error_s = spv_table_look_read (arg, &table_look);
   if (error_s)