Adopt use of gnulib for portability.
[pspp-builds.git] / src / postscript.c
index 4a2fab0b5848e82f45adec32feb7fb36c5dc8eea..11473f6488faaa94de282739ecd556232a3d5ec7 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 "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;
 }
 
@@ -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--;
@@ -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. */
 
@@ -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 */