output: Use Cairo and Pango to draw charts, instead of libplot.
[pspp-builds.git] / src / output / ascii.c
index f2dff490b8bb23bb92741ad68b280ed740458217..b224b3ebea9e54bdfac5d6859a18793583b046f6 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2007, 2009 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
 
 #include <data/file-name.h>
 #include <data/settings.h>
-#include <libpspp/alloc.h>
 #include <libpspp/assertion.h>
 #include <libpspp/compiler.h>
 #include <libpspp/pool.h>
 #include <libpspp/start-date.h>
 #include <libpspp/version.h>
+#include <output/chart-provider.h>
+#include <output/chart.h>
+#include <output/output.h>
 
-#include "chart.h"
 #include "error.h"
 #include "minmax.h"
-#include "output.h"
+#include "xalloc.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -44,7 +45,7 @@
    output-file="pspp.list"
    append=no|yes                If output-file exists, append to it?
    chart-files="pspp-#.png"     Name used for charts.
-   chart-type=png               Format of charts (use "none" to disable).
+   chart-type=png|none
 
    paginate=on|off              Formfeeds are desired?
    tab-width=8                  Width of a tab; 0 to not use tabs.
@@ -108,7 +109,7 @@ struct ascii_driver_ext
     bool squeeze_blank_lines;   /* Squeeze multiple blank lines into one? */
     enum emphasis_style emphasis; /* How to emphasize text. */
     int tab_width;             /* Width of a tab; 0 not to use tabs. */
-    const char *chart_type;     /* Type of charts to output; NULL for none. */
+    bool enable_charts;         /* Enable charts? */
     const char *chart_file_name; /* Name of files used for charts. */
 
     bool auto_width;            /* Use viewwidth as page width? */
@@ -133,15 +134,17 @@ struct ascii_driver_ext
 static void ascii_flush (struct outp_driver *);
 static int get_default_box_char (size_t idx);
 static bool update_page_size (struct outp_driver *, bool issue_error);
-static bool handle_option (struct outp_driver *this, const char *key,
+static bool handle_option (void *this, const char *key,
                            const struct string *val);
 
 static bool
-ascii_open_driver (struct outp_driver *this, struct substring options)
+ascii_open_driver (const char *name, int types, struct substring options)
 {
+  struct outp_driver *this;
   struct ascii_driver_ext *x;
   int i;
 
+  this = outp_allocate_driver (&ascii_class, name, types);
   this->width = 79;
   this->font_height = 1;
   this->prop_em_width = 1;
@@ -157,7 +160,7 @@ ascii_open_driver (struct outp_driver *this, struct substring options)
   x->emphasis = EMPH_BOLD;
   x->tab_width = 8;
   x->chart_file_name = pool_strdup (x->pool, "pspp-#.png");
-  x->chart_type = pool_strdup (x->pool, "png");
+  x->enable_charts = true;
   x->auto_width = false;
   x->auto_length = false;
   x->page_length = 66;
@@ -172,9 +175,9 @@ ascii_open_driver (struct outp_driver *this, struct substring options)
   x->page_number = 0;
   x->lines = NULL;
   x->line_cap = 0;
-  x->chart_cnt = 0;
+  x->chart_cnt = 1;
 
-  if (!outp_parse_options (options, handle_option, this))
+  if (!outp_parse_options (this->name, options, handle_option, this))
     goto error;
 
   if (!update_page_size (this, true))
@@ -189,10 +192,13 @@ ascii_open_driver (struct outp_driver *this, struct substring options)
         x->box[i] = pool_strdup (x->pool, s);
       }
 
+  outp_register_driver (this);
+
   return true;
 
  error:
   pool_destroy (x->pool);
+  outp_free_driver (this);
   return false;
 }
 
@@ -238,9 +244,9 @@ update_page_size (struct outp_driver *this, bool issue_error)
   int margins = x->top_margin + x->bottom_margin + 1 + (x->headers ? 3 : 0);
 
   if (x->auto_width)
-    this->width = get_viewwidth ();
+    this->width = settings_get_viewwidth ();
   if (x->auto_length)
-    x->page_length = get_viewlength ();
+    x->page_length = settings_get_viewlength ();
 
   this->length = x->page_length - margins;
 
@@ -312,9 +318,10 @@ static const struct outp_option option_tab[] =
   };
 
 static bool
-handle_option (struct outp_driver *this, const char *key,
+handle_option (void *this_, const char *key,
                const struct string *val)
 {
+  struct outp_driver *this = this_;
   struct ascii_driver_ext *x = this->ext;
   int subcat;
   const char *value;
@@ -478,10 +485,16 @@ handle_option (struct outp_driver *this, const char *key,
             error (0, 0, _("`chart-files' value must contain `#'"));
           break;
         case 2:
-          if (value[0] != '\0')
-            x->chart_type = pool_strdup (x->pool, value);
+          if (!strcmp (value, "png"))
+            x->enable_charts = true;
+          else if (!strcmp (value, "none"))
+            x->enable_charts = false;
           else
-            x->chart_type = NULL;
+            {
+              error (0, 0,
+                     _("ascii: `png' or `none' expected for `chart-type'"));
+              return false;
+            }
           break;
         case 3:
           x->init = pool_strdup (x->pool, value);
@@ -603,15 +616,6 @@ ascii_line (struct outp_driver *this,
     }
 }
 
-static void
-ascii_submit (struct outp_driver *this UNUSED, struct som_entity *s)
-{
-  extern struct som_table_class tab_table_class;
-
-  assert (s->class == &tab_table_class);
-  assert (s->type == SOM_CHART);
-}
-
 static void
 text_draw (struct outp_driver *this,
            enum outp_font font,
@@ -866,19 +870,15 @@ ascii_flush (struct outp_driver *this)
 }
 
 static void
-ascii_chart_initialise (struct outp_driver *this, struct chart *ch)
+ascii_output_chart (struct outp_driver *this, const struct chart *chart)
 {
   struct ascii_driver_ext *x = this->ext;
   struct outp_text t;
+  char *file_name;
   char *text;
 
-  if (x->chart_type == NULL)
-    return;
-
-  /* Initialize chart. */
-  chart_init_separate (ch, x->chart_type, x->chart_file_name, ++x->chart_cnt);
-  if (ch->file_name == NULL)
-    return;
+  /* Draw chart into separate file */
+  file_name = chart_draw_png (chart, x->chart_file_name, x->chart_cnt++);
 
   /* Mention chart in output.
      First advance current position. */
@@ -895,7 +895,7 @@ ascii_chart_initialise (struct outp_driver *this, struct chart *ch)
     }
 
   /* Then write the text. */
-  text = xasprintf ("See %s for a chart.", ch->file_name);
+  text = xasprintf ("See %s for a chart.", file_name);
   t.font = OUTP_FIXED;
   t.justification = OUTP_LEFT;
   t.string = ss_cstr (text);
@@ -906,17 +906,10 @@ ascii_chart_initialise (struct outp_driver *this, struct chart *ch)
   ascii_text_draw (this, &t);
   this->cp_y++;
 
+  free (file_name);
   free (text);
 }
 
-static void
-ascii_chart_finalise (struct outp_driver *this, struct chart *ch)
-{
-  struct ascii_driver_ext *x = this->ext;
-  if (x->chart_type != NULL)
-    chart_finalise_separate (ch);
-}
-
 const struct outp_class ascii_class =
 {
   "ascii",
@@ -929,12 +922,11 @@ const struct outp_class ascii_class =
   ascii_close_page,
   ascii_flush,
 
-  ascii_submit,
+  ascii_output_chart,
+
+  NULL,                         /* submit */
 
   ascii_line,
   ascii_text_metrics,
   ascii_text_draw,
-
-  ascii_chart_initialise,
-  ascii_chart_finalise
 };