added automake.mk files in src/language
[pspp] / src / postscript.c
index 4a2fab0b5848e82f45adec32feb7fb36c5dc8eea..f2bb3400aaed277c80fc1bdb90653ac7dc96475f 100644 (file)
@@ -14,8 +14,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA. */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
 
 #include <config.h>
 
 #include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
+#include <time.h>
 
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 
-#if TIME_WITH_SYS_TIME
-#include <sys/time.h>
-#include <time.h>
-#else
-#if HAVE_SYS_TIME_H
-#include <sys/time.h>
-#else
-#include <time.h>
-#endif
-#endif
-
 #include "alloc.h"
 #include "bitvector.h"
 #include "error.h"
 #include "filename.h"
 #include "font.h"
+#include "getl.h"
 #include "getline.h"
+#include "glob.h"
 #include "hash.h"
 #include "main.h"
 #include "misc.h"
-#include "misc.h"
 #include "output.h"
+#include "som.h"
 #include "version.h"
 
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
 /* FIXMEs:
 
    optimize-text-size not implemented.
@@ -267,6 +262,7 @@ static unsigned hash_font_entry (const void *, void *param);
 static void free_font_entry (void *, void *foo);
 static struct font_entry *load_font (struct outp_driver *, const char *dit);
 static void init_fonts (void);
+static void done_fonts (void);
 
 static void dump_lines (struct outp_driver *this);
 
@@ -297,6 +293,8 @@ ps_open_global (struct outp_class *this UNUSED)
 static int
 ps_close_global (struct outp_class *this UNUSED)
 {
+  groff_done ();
+  done_fonts ();
   return 1;
 }
 
@@ -322,7 +320,7 @@ ps_preopen_driver (struct outp_driver *this)
   assert (this->driver_open == 0);
   msg (VM (1), _("PostScript driver initializing as `%s'..."), this->name);
        
-  this->ext = x = xmalloc (sizeof (struct ps_driver_ext));
+  this->ext = x = xmalloc (sizeof *x);
   this->res = PSUS;
   this->horiz = this->vert = 1;
   this->width = this->length = 0;
@@ -1448,7 +1446,7 @@ postopen (struct file_ext *f)
          char *beg;
          beg = buf2 = fn_interp_vars (buf, ps_get_var);
          len = strlen (buf2);
-         while (isspace (*beg))
+         while (isspace ((unsigned char) *beg))
            beg++, len--;
          if (beg[len - 1] == '\n')
            len--;
@@ -1490,7 +1488,7 @@ quote_ps_name (char *dest, const char *string)
   const char *sp;
 
   for (sp = string; *sp; sp++)
-    switch (*(unsigned char *) sp)
+    switch (*sp)
       {
       case 'a':
       case 'f':
@@ -1565,7 +1563,7 @@ quote_ps_name (char *dest, const char *string)
          *dp++ = '<';
          for (sp = string; *sp && dp < &dest[256]; sp++)
            {
-             sprintf (dp, "%02x", *(unsigned char *) sp);
+             sprintf (dp, "%02x", (unsigned char) *sp);
              dp += 2;
            }
          return stpcpy (dp, ">cvn");
@@ -1590,7 +1588,7 @@ quote_ps_string (char *dest, const char *string)
       dp = stpcpy (dp, "\\(");
     else if (*sp == ')')
       dp = stpcpy (dp, "\\)");
-    else if (*sp < 32 || *((unsigned char *) sp) > 127)
+    else if (*sp < 32 || (unsigned char) *sp > 127)
       dp = spprintf (dp, "\\%3o", *sp);
     else
       *dp++ = *sp;
@@ -1690,6 +1688,8 @@ ps_open_page (struct outp_driver *this)
        draw_headers (this);
     }
 
+  this->cp_y = 0;
+
   return !ferror (x->file.file);
 }
 
@@ -1711,6 +1711,19 @@ ps_close_page (struct outp_driver *this)
   this->page_open = 0;
   return !ferror (x->file.file);
 }
+
+static void
+ps_submit (struct outp_driver *this UNUSED, struct som_entity *s)
+{
+  switch (s->type) 
+    {
+    case SOM_CHART:
+      break;
+    default:
+      assert(0);
+      break;
+    }
+}
 \f
 /* Lines. */
 
@@ -1889,7 +1902,7 @@ line (struct outp_driver *this, int type, int ind, int dep1, int dep2)
   if ((*f)->ndep >= (*f)->mdep)
     {
       (*f)->mdep += 16;
-      *f = xrealloc (*f, (sizeof **f + sizeof (int[2]) * ((*f)->mdep - 1)));
+      *f = xrealloc (*f, sizeof **f + sizeof (int[2]) * ((*f)->mdep - 1));
     }
   (*f)->dep[(*f)->ndep][0] = dep1;
   (*f)->dep[(*f)->ndep][1] = dep2;
@@ -2092,7 +2105,7 @@ draw_headers (struct outp_driver *this)
     int rh_width;
     char buf[128];
 
-    sprintf (buf, _("%s - Page %d"), curdate, ext->page_number);
+    sprintf (buf, _("%s - Page %d"), get_start_date (), ext->page_number);
     rh_width = text_width (this, buf);
 
     out_text_plain (this, buf, this->width - this->prop_em_width - rh_width,
@@ -2453,7 +2466,7 @@ write_text (struct outp_driver *this,
          if (TEST_BIT (literal_chars[ext->data], cp->ch))
            *lp++ = cp->ch;
          else
-           switch (cp->ch)
+           switch ((char) cp->ch)
              {
              case '(':
                lp = stpcpy (lp, "\\(");
@@ -2722,7 +2735,7 @@ text (struct outp_driver *this, struct outp_text *t, int draw)
                }
              else
                {
-                 buf = xrealloc (buf, sizeof *buf * buf_len * 2);
+                 buf = xnrealloc (buf, buf_len * 2, sizeof *buf);
                  buf_loc = buf + buf_len;
                  buf_end = buf + buf_len * 2;
                }
@@ -2815,6 +2828,12 @@ init_fonts (void)
                         NULL, NULL);
 }
 
+static void
+done_fonts (void)
+{
+ hsh_destroy (ps_fonts);
+}
+
 /* Loads the font having Groff name DIT into THIS driver instance.
    Specifically, adds it into the THIS driver's `loaded' hash
    table. */
@@ -2862,6 +2881,86 @@ load_font (struct outp_driver *this, const char *dit)
   return fe;
 }
 
+static void
+ps_chart_initialise (struct outp_driver *this UNUSED, struct chart *ch)
+{
+#ifdef NO_CHARTS
+  ch->lp = NULL;
+#else
+  struct ps_driver_ext *x = this->ext;
+  char page_size[128];
+  int size;
+  int x_origin, y_origin;
+
+  ch->file = tmpfile ();
+  if (ch->file == NULL) 
+    {
+      ch->lp = NULL;
+      return;
+    }
+  
+  size = this->width < this->length ? this->width : this->length;
+  x_origin = x->left_margin + (size - this->width) / 2;
+  y_origin = x->bottom_margin + (size - this->length) / 2;
+
+  snprintf (page_size, sizeof page_size,
+            "a,xsize=%.3f,ysize=%.3f,xorigin=%.3f,yorigin=%.3f",
+            (double) size / PSUS, (double) size / PSUS,
+            (double) x_origin / PSUS, (double) y_origin / PSUS);
+
+  ch->pl_params = pl_newplparams ();
+  pl_setplparam (ch->pl_params, "PAGESIZE", page_size);
+  ch->lp = pl_newpl_r ("ps", NULL, ch->file, stderr, ch->pl_params);
+#endif
+}
+
+static void 
+ps_chart_finalise (struct outp_driver *this UNUSED, struct chart *ch UNUSED)
+{
+#ifndef NO_CHARTS
+  struct ps_driver_ext *x = this->ext;
+  char buf[BUFSIZ];
+  static int doc_num = 0;
+
+  if (this->page_open) 
+    {
+      this->class->close_page (this);
+      this->page_open = 0; 
+    }
+  this->class->open_page (this);
+  fprintf (x->file.file,
+           "/sp save def%s"
+           "%d %d translate 1000 dup scale%s"
+           "userdict begin%s"
+           "/showpage { } def%s"
+           "0 setgray 0 setlinecap 1 setlinewidth%s"
+           "0 setlinejoin 10 setmiterlimit [ ] 0 setdash newpath clear%s"
+           "%%%%BeginDocument: %d%s",
+           x->eol,
+           -x->left_margin, -x->bottom_margin, x->eol,
+           x->eol,
+           x->eol,
+           x->eol,
+           x->eol,
+           doc_num++, x->eol);
+
+  rewind (ch->file);
+  while (fwrite (buf, 1, fread (buf, 1, sizeof buf, ch->file), x->file.file))
+    continue;
+  fclose (ch->file);
+
+  fprintf (x->file.file,
+           "%%%%EndDocument%s"
+           "end%s"
+           "sp restore%s",
+           x->eol,
+           x->eol,
+           x->eol);
+  this->class->close_page (this);
+  this->page_open = 0;
+#endif
+}
+
 /* PostScript driver class. */
 struct outp_class postscript_class =
 {
@@ -2881,7 +2980,7 @@ struct outp_class postscript_class =
   ps_open_page,
   ps_close_page,
 
-  NULL,
+  ps_submit,
 
   ps_line_horz,
   ps_line_vert,
@@ -2901,6 +3000,9 @@ struct outp_class postscript_class =
   ps_text_get_size,
   ps_text_metrics,
   ps_text_draw,
+
+  ps_chart_initialise,
+  ps_chart_finalise
 };
 
 /* EPSF driver class.  FIXME: Probably doesn't work right. */
@@ -2922,7 +3024,7 @@ struct outp_class epsf_class =
   ps_open_page,
   ps_close_page,
 
-  NULL,
+  ps_submit,
 
   ps_line_horz,
   ps_line_vert,
@@ -2942,6 +3044,10 @@ struct outp_class epsf_class =
   ps_text_get_size,
   ps_text_metrics,
   ps_text_draw,
+
+  ps_chart_initialise,
+  ps_chart_finalise
+
 };
 
 #endif /* NO_POSTSCRIPT */