Initial release of Maemo 5 port of gnuplot
[gnuplot] / term / metapost.trm
diff --git a/term/metapost.trm b/term/metapost.trm
new file mode 100644 (file)
index 0000000..08b9412
--- /dev/null
@@ -0,0 +1,1165 @@
+/* Hello, Emacs, this is -*-C-*-
+ * $Id: metapost.trm,v 1.38.2.2 2008/05/31 16:08:26 sfeam Exp $
+ */
+
+/* GNUPLOT - metapost.trm */
+
+/*[
+ * Copyright 1990 - 1993, 1998, 2004
+ *
+ * Permission to use, copy, and distribute this software and its
+ * documentation for any purpose with or without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.
+ *
+ * Permission to modify the software is granted, but not the right to
+ * distribute the complete modified source code.  Modifications are to
+ * be distributed as patches to the released version.  Permission to
+ * distribute binaries produced by compiling modified sources is granted,
+ * provided you
+ *   1. distribute the corresponding source modifications from the
+ *    released version in the form of a patch file along with the binaries,
+ *   2. add special version identification to distinguish your version
+ *    in addition to the base release version number,
+ *   3. provide your name and address as the primary contact for the
+ *    support of your modified version, and
+ *   4. retain our contact information in regard to use of the base
+ *    software.
+ * Permission to distribute the released version of the source code along
+ * with corresponding source modifications in the form of a patch file is
+ * granted with same provisions 2 through 4 for binary distributions.
+ *
+ * This software is provided "as is" without express or implied warranty
+ * to the extent permitted by applicable law.
+]*/
+
+/* 1999/04/22
+ *                     GNUPLOT -- metapost.trm
+ *
+ *                     This terminal driver supports:
+ *                             Metapost Commands
+ *
+ * Based on metafont.trm, written by
+ *             Pl Hedne
+ *             Trondheim, Norway
+ *             Pal.Hedne@termo.unit.no;
+ *             with improvements by Carsten Steger
+ *
+ * and pstricks.trm, written by
+ *             David Kotz and Raymond Toy
+ *
+ * Adapted to metapost by:
+ *             Daniel H. Luecking <luecking@comp.uark.edu> and
+ *             L Srinivasa Mohan <mohan@chemeng.iisc.ernet.in>
+ */
+
+#include "driver.h"
+
+#ifdef TERM_REGISTER
+register_term(mp)
+#endif
+
+#ifdef TERM_PROTO
+TERM_PUBLIC void MP_options __PROTO((void));
+TERM_PUBLIC void MP_init __PROTO((void));
+TERM_PUBLIC void MP_graphics __PROTO((void));
+TERM_PUBLIC void MP_text __PROTO((void));
+TERM_PUBLIC void MP_linetype __PROTO((int linetype));
+TERM_PUBLIC void MP_move __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void MP_point __PROTO((unsigned int x, unsigned int y, int number));
+TERM_PUBLIC void MP_pointsize __PROTO((double size));
+TERM_PUBLIC void MP_linewidth __PROTO((double width));
+TERM_PUBLIC void MP_vector __PROTO((unsigned int ux, unsigned int uy));
+TERM_PUBLIC void MP_arrow __PROTO((unsigned int sx, unsigned int sy,
+                                  unsigned int ex, unsigned int ey,
+                                  int head));
+TERM_PUBLIC void MP_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
+TERM_PUBLIC int MP_justify_text __PROTO((enum JUSTIFY mode));
+TERM_PUBLIC int MP_text_angle __PROTO((int ang));
+TERM_PUBLIC void MP_reset __PROTO((void));
+TERM_PUBLIC int MP_set_font __PROTO((const char *font));
+TERM_PUBLIC void MP_boxfill __PROTO((int style, unsigned int x1,
+                                    unsigned int y1, unsigned int width,
+                                    unsigned int height));
+TERM_PUBLIC int MP_make_palette __PROTO((t_sm_palette *));
+TERM_PUBLIC void MP_previous_palette __PROTO((void));
+TERM_PUBLIC void MP_set_color __PROTO((t_colorspec *));
+TERM_PUBLIC void MP_filled_polygon __PROTO((int, gpiPoint *));
+
+/* 5 inches wide by 3 inches high (default) */
+#define MP_XSIZE 5.0
+#define MP_YSIZE 3.0
+
+/* gnuplot units will be one pixel if printing device has this
+   resolution. Too small resolutions (like 300) can give rough
+   appearence to curves when user tries to smooth a curve by choosing
+   high sampling rate. */
+#define MP_DPI (2400)
+
+#define MP_XMAX (MP_XSIZE*MP_DPI)
+#define MP_YMAX (MP_YSIZE*MP_DPI)
+
+#define MP_HTIC (5*MP_DPI/72)  /* nominally 5pt   */
+#define MP_VTIC (5*MP_DPI/72)  /*    "      5pt   */
+#define MP_HCHAR (MP_DPI*53/10/72)     /*    "      5.3pt */
+#define MP_VCHAR (MP_DPI*11/72)        /*    "      11pt  */
+#endif /* TERM_PROTO */
+
+#ifndef TERM_PROTO_ONLY
+#ifdef TERM_BODY
+
+static double MP_xsize = MP_XSIZE;
+static double MP_ysize = MP_YSIZE;
+/* static double MP_xmax = MP_XMAX;
+   static double MP_ymax = MP_YMAX;
+ * unused, for now
+ */
+static int MP_posx;
+static int MP_posy;
+static char MP_fontname[MAX_ID_LEN + 1];
+static double MP_fontsize;
+static double MP_textmag;
+static enum JUSTIFY MP_justify = LEFT;
+static int MP_ang = 0;
+static int MP_char_code = 0;
+
+/* number of nodes in an output line so far */
+static int MP_linecount = 1;
+
+/* Number of point types */
+#define MP_POINT_TYPES 10
+
+/* Number of line types */
+#define MP_LINE_TYPES 8
+
+/* are we in the middle of a MP path? */
+static TBOOLEAN MP_inline = FALSE;
+/* colored or dashed lines? */
+static TBOOLEAN MP_color = FALSE;
+static TBOOLEAN MP_solid = FALSE;
+
+/* compatability mode*/
+/* static TBOOLEAN MP_notex = FALSE; */
+#define MP_NO_TEX 0
+#define MP_TEX 1
+#define MP_LATEX 2
+static int MP_tex = MP_TEX;
+/* add usepackage instructions for PSNFSS ? */
+#define MP_PSNFSS_NONE 0
+#define MP_PSNFSS_7    1
+#define MP_PSNFSS_8    2
+static int MP_psnfss = MP_PSNFSS_NONE;
+/* should amstex packages be included? */
+static int MP_amstex = 0;
+/* add a4paper option to documentclass */
+static int MP_a4paper = 0;
+/* write a prologues line */
+static int MP_prologues = -1;
+
+/* has color changed? */
+static int MP_color_changed = 0;
+
+/* has a font change taken place? */
+static TBOOLEAN MP_fontchanged = FALSE;
+
+/* The old types */
+static int MP_oldline = -2;
+
+/* The old sizes */
+static double MP_oldptsize = 1.0;
+static double MP_oldpen = 1.0;
+
+/* terminate any path in progress */
+static void MP_endline __PROTO((void));
+
+/* max number of path nodes before a newline */
+#define MP_LINEMAX 5
+
+enum MP_id {
+    MP_OPT_MONOCHROME, MP_OPT_COLOUR,
+    MP_OPT_SOLID, MP_OPT_DASHED,
+    MP_OPT_NOTEX, MP_OPT_TEX, MP_OPT_LATEX,
+    MP_OPT_A4PAPER,
+    MP_OPT_PSNFSS, MP_OPT_PSNFSS_V7, MP_OPT_NOPSNFSS,
+    MP_OPT_AMSTEX,
+    MP_OPT_FONT, MP_OPT_FONTSIZE,
+    MP_OPT_PROLOGUES, MP_OPT_NOPROLOGUES,
+    MP_OPT_MAGNIFICATION, MP_OPT_OTHER
+};
+
+static struct gen_table MP_opts[] = {
+    { "mo$nochrome", MP_OPT_MONOCHROME },
+    { "c$olor", MP_OPT_COLOUR },
+    { "c$olour", MP_OPT_COLOUR },
+    { "s$olid", MP_OPT_SOLID },
+    { "da$shed", MP_OPT_DASHED },
+    { "n$otex", MP_OPT_NOTEX },
+    { "t$ex", MP_OPT_TEX },
+    { "la$tex", MP_OPT_LATEX },
+    { "a4$paper", MP_OPT_A4PAPER },
+    { "am$stex", MP_OPT_AMSTEX },
+    { "ps$nfss", MP_OPT_PSNFSS },
+    { "psnfss-v$ersion7", MP_OPT_PSNFSS_V7 },
+    { "nops$nfss", MP_OPT_NOPSNFSS },
+    { "pro$logues", MP_OPT_PROLOGUES },
+    { "nopro$logues", MP_OPT_NOPROLOGUES },
+    { "ma$gnification", MP_OPT_MAGNIFICATION },
+    { "fo$nt", MP_OPT_FONT },
+    { NULL, MP_OPT_OTHER }
+};
+
+TERM_PUBLIC void
+MP_options()
+{
+    struct value a;
+
+    /* Annoying hack to handle the case of 'set termoption' after */
+    /* we have already initialized the terminal.                  */
+    if (c_token != 2) {
+       MP_color = FALSE;
+       MP_solid = FALSE;
+       MP_tex = MP_TEX;
+       MP_a4paper = 0;
+       MP_amstex  = 0;
+       MP_psnfss = MP_PSNFSS_NONE;
+       MP_fontsize = 10.0;
+       MP_textmag = 1.0;
+       MP_prologues = -1;
+       strcpy(MP_fontname, "cmr10");
+    }
+
+    while (!END_OF_COMMAND) {
+       switch (lookup_table(&MP_opts[0], c_token)) {
+       case MP_OPT_MONOCHROME:
+           MP_color = FALSE;
+           c_token++;
+           break;
+       case MP_OPT_COLOUR:
+           MP_color = TRUE;
+           c_token++;
+           break;
+       case MP_OPT_SOLID:
+           MP_solid = TRUE;
+           c_token++;
+           break;
+       case MP_OPT_DASHED:
+           MP_solid = FALSE;
+           c_token++;
+           break;
+       case MP_OPT_NOTEX:
+           MP_tex = MP_NO_TEX;
+           strcpy(MP_fontname, "pcrr8r");
+           c_token++;
+           break;
+       case MP_OPT_TEX:
+           MP_tex = MP_TEX;
+           c_token++;
+           break;
+       case MP_OPT_LATEX:
+           MP_tex = MP_LATEX;
+           c_token++;
+           break;
+       case MP_OPT_AMSTEX:
+           MP_tex = MP_LATEX; /* only makes sense when using LaTeX */
+           MP_amstex = 1;
+           c_token++;
+           break;
+       case MP_OPT_A4PAPER:
+           MP_tex = MP_LATEX; /* only makes sense when using LaTeX */
+           MP_a4paper = 1;
+           c_token++;
+           break;
+       case MP_OPT_PSNFSS:
+           MP_tex = MP_LATEX;    /* only makes sense when using LaTeX */
+           MP_psnfss = MP_PSNFSS_8;
+           c_token++;
+           break;
+       case MP_OPT_PSNFSS_V7:
+           MP_tex = MP_LATEX; /* only makes sense when using LaTeX */
+           MP_psnfss = MP_PSNFSS_7;
+           c_token++;
+           break;
+       case MP_OPT_NOPSNFSS:
+           MP_psnfss = MP_PSNFSS_NONE;
+           c_token++;
+           break;
+       case MP_OPT_PROLOGUES:
+           c_token++;
+           if (!(END_OF_COMMAND)) {
+               int dummy_for_prologues;
+
+               if (sscanf(gp_input_line + token[c_token].start_index,
+                          "%d", &dummy_for_prologues) == 1) {
+                   MP_prologues = dummy_for_prologues;
+               }
+               c_token++;
+           }
+           break;
+       case MP_OPT_NOPROLOGUES:
+           MP_prologues = -1;
+           c_token++;
+           break;
+       case MP_OPT_MAGNIFICATION:
+           c_token++;
+           if (!END_OF_COMMAND)        /* global text scaling */
+               MP_textmag = (double) real(const_express(&a));
+           /* c_token++; */ /* Needed ??? */
+           break;
+       case MP_OPT_FONT:
+           c_token++;
+           if (isstringvalue(c_token)) {
+               char *s = try_to_get_string();
+               strncpy(MP_fontname, s, sizeof(MP_fontname));
+           }
+           break;
+       case MP_OPT_OTHER:
+       default:
+           if (isstring(c_token)) {    /* font name */
+               quote_str(MP_fontname, c_token, MAX_ID_LEN);
+               c_token++;
+           }
+           if (!END_OF_COMMAND) {      /*font size */
+               MP_fontsize = (double) real(const_express(&a));
+               c_token++;
+           }
+           break;
+       }
+    }
+
+    /* minimal error recovery: */
+    if (MP_fontsize < 5.0)
+       MP_fontsize = 5.0;
+    if (MP_fontsize > 99.99)
+       MP_fontsize = 99.99;
+
+    term->v_char = (unsigned int) (MP_DPI * MP_fontsize * MP_textmag * 11 / 720);
+    if (MP_tex == MP_NO_TEX) { /* Courier is a little wider than cmtt */
+       term->h_char = (unsigned int) (MP_DPI * MP_fontsize * MP_textmag * 6.0 / 720 + 0.5);
+    } else {
+       term->h_char = (unsigned int) (MP_DPI * MP_fontsize * MP_textmag * 5.3 / 720 + 0.5);
+    }
+
+    if (MP_psnfss == MP_PSNFSS_NONE) { /* using the normal font scheme */
+      sprintf(term_options,
+           "%s %s %stex%s%s mag %.3f font \"%s\" %.2f %sprologues(%d)",
+           MP_color ? "color" : "monochrome",
+           MP_solid ? "solid" : "dashed",
+           (MP_tex == MP_NO_TEX) ? "no" : (MP_tex == MP_LATEX) ? "la" : "",
+           MP_a4paper ? " a4paper" : "",
+           MP_amstex ? " amstex" : "",
+           MP_textmag,
+           MP_fontname, MP_fontsize,
+           (MP_prologues > -1) ? "" : "no", MP_prologues );
+    } else { /* using postscript fonts */
+      sprintf(term_options,
+           "%s %s %stex%s%s mag %.3f %s %sprologues(%d)",
+           MP_color ? "color" : "monochrome",
+           MP_solid ? "solid" : "dashed",
+           (MP_tex == MP_NO_TEX) ? "no" : (MP_tex == MP_LATEX) ? "la" : "",
+           MP_a4paper ? " a4paper" : "",
+           MP_amstex ? " amstex" : "",
+           MP_textmag,
+           (MP_psnfss == MP_PSNFSS_7) ? "psnsfss(v7)" : "psnsfss",
+           (MP_prologues > -1) ? "" : "no", MP_prologues );
+    };
+}
+
+TERM_PUBLIC void
+MP_init()
+{
+    time_t now;
+    time(&now);
+    MP_posx = MP_posy = 0;
+    fprintf(gpoutfile, "%%GNUPLOT Metapost output: %s\n", asctime(localtime(&now)));
+    if (MP_prologues > -1) {
+       fprintf(gpoutfile, "prologues:=%d;\n", MP_prologues);
+    }
+    if (MP_tex == MP_LATEX) {
+       fputs("\n\
+%% Add \\documentclass and \\begin{dcoument} for latex\n\
+%% NB you should set the environment variable TEX to the name of your\n\
+%% latex executable (normally latex) inorder for metapost to work\n\
+%% or run\n\
+%% mpost --tex=latex ...\n\
+\n\
+% BEGPRE\n\
+verbatimtex\n", gpoutfile);
+       if (MP_a4paper) {
+           fputs("\\documentclass[a4paper]{article}\n", gpoutfile);
+       } else {
+           fputs("\\documentclass{article}\n", gpoutfile);
+       }
+       switch (MP_psnfss) {
+       case MP_PSNFSS_7:{
+               fputs("\\usepackage[latin1]{inputenc}\n\
+\\usepackage[T1]{fontenc}\n\
+\\usepackage{times,mathptmx}\n\
+\\usepackage{helvet}\n\
+\\usepackage{courier}\n", gpoutfile);
+           }
+           break;
+       case MP_PSNFSS_8:{
+               fputs("\\usepackage[latin1]{inputenc}\n\
+\\usepackage[T1]{fontenc}\n\
+\\usepackage{textcomp}\n\
+\\usepackage{mathptmx}\n\
+\\usepackage[scaled=.92]{helvet}\n\
+\\usepackage{courier}\n\
+\\usepackage{latexsym}\n", gpoutfile);
+           }
+           break;
+       }
+       if (MP_amstex) {
+         fputs("\\usepackage[intlimits]{amsmath}\n\
+\\usepackage{amsfonts}\n", gpoutfile);
+          };
+       fputs("\\begin{document}\n\
+etex\n% ENDPRE\n", gpoutfile);
+    }
+
+    fputs("\n\
+warningcheck:=0;\n\
+defaultmpt:=mpt:=4;\n\
+th:=.6;\n\
+%% Have nice sharp joins on our lines\n\
+linecap:=butt;\n\
+linejoin:=mitered;\n\
+\n\
+def scalepen expr n = pickup pencircle scaled (n*th) enddef;\n\
+def ptsize expr n = mpt:=n*defaultmpt enddef;\n\
+\n", gpoutfile);
+
+    fprintf(gpoutfile, "\ntextmag:=%6.3f;\n", MP_textmag);
+
+    fputs("\
+vardef makepic(expr str) =\n\
+  if picture str : str scaled textmag\n\
+  % otherwise a string\n\
+  else: str infont defaultfont scaled (defaultscale*textmag)\n\
+  fi\n\
+enddef;\n\
+\n\
+def infontsize(expr str, size) =\n\
+  infont str scaled (size / fontsize str)\n\
+enddef;\n", gpoutfile);
+
+    if (MP_tex == MP_NO_TEX) {
+       fprintf(gpoutfile, "\n\
+defaultfont:= \"%s\";\n\
+defaultscale := %6.3f/fontsize defaultfont;\n", MP_fontname, MP_fontsize);
+    } else {
+       if (MP_tex != MP_LATEX) {
+           fputs("\n\
+%font changes\n\
+verbatimtex\n\
+\\def\\setfont#1#2{%.\n\
+  \\font\\gpfont=#1 at #2pt\n\
+\\gpfont}\n", gpoutfile);
+           fprintf(gpoutfile, "\\setfont{%s}{%5.2f}\netex\n",
+                   MP_fontname, MP_fontsize);
+       }
+    }
+    fputs("\n\
+color currentcolor; currentcolor:=black;\n\
+color fillcolor;\n\
+boolean colorlines,dashedlines;\n", gpoutfile);
+    if (MP_color) {
+       fputs("colorlines:=true;\n", gpoutfile);
+    } else {
+       fputs("colorlines:=false;\n", gpoutfile);
+    }
+    if (MP_solid) {
+       fputs("dashedlines:=false;\n", gpoutfile);
+    } else {
+       fputs("dashedlines:=true;\n", gpoutfile);
+    }
+    fputs("\n\
+def _wc = withpen currentpen withcolor currentcolor enddef;\n\
+def _ac = addto currentpicture enddef;\n\
+def _sms = scaled mpt shifted enddef;\n\
+% drawing point-types\n\
+def gpdraw (expr n, x, y) =\n\
+  if n<0: _ac contour fullcircle _sms (x,y)\n\
+  elseif (n=1) or (n=3):\n\
+    _ac doublepath ptpath[n] _sms (x,y) _wc;\n\
+    _ac doublepath ptpath[n] rotated 90 _sms (x,y) _wc\n\
+  elseif n<6: _ac doublepath ptpath[n] _sms (x,y) _wc\n\
+  else: _ac contour ptpath[n] _sms (x,y) _wc\n\
+  fi\n\
+enddef;\n\
+\n\
+% the point shapes\n\
+path ptpath[];\n\
+%diamond\n\
+ptpath0 = ptpath6 = (-1/2,0)--(0,-1/2)--(1/2,0)--(0,1/2)--cycle;\n\
+% plus sign\n\
+ptpath1 = (-1/2,0)--(1/2,0);\n\
+% square\n\
+ptpath2 = ptpath7 = (-1/2,-1/2)--(1/2,-1/2)--(1/2,1/2)--(-1/2,1/2)--cycle;\n\
+% cross\n\
+ptpath3 := (-1/2,-1/2)--(1/2,1/2);\n\
+% circle:\n\
+ptpath4 = ptpath8:= fullcircle;\n\
+% triangle\n\
+ptpath5 = ptpath9 := (0,1/2)--(-1/2,-1/2)--(1/2,-1/2)--cycle;\n\
+\n\
+def linetype expr n =\n\
+  currentcolor:= if colorlines : col[n] else: black fi;\n\
+  if n = -1 :\n\
+      drawoptions(withcolor currentcolor withpen (currentpen scaled .5));\n\
+  elseif n < 1 :\n\
+    drawoptions(_wc);\n\
+  else :\n\
+    drawoptions( if dashedlines: dashed lt[n] fi _wc);\n\
+  fi\n\
+enddef;\n\
+\n\
+% dash patterns\n\
+picture lt[];\n\
+lt1=dashpattern(on 2 off 2); % dashes\n\
+lt2=dashpattern(on 2 off 2 on 0.2 off 2); %dash-dot\n\
+lt3=lt1 scaled 1.414;\n\
+lt4=lt2 scaled 1.414;\n\
+lt5=lt1 scaled 2;\n\
+lt6:=lt2 scaled 2;\n\
+lt7=dashpattern(on 0.2 off 2); %dots\n\
+\n\
+color col[],cyan, magenta, yellow;\n\
+cyan=blue+green; magenta=red+blue;yellow=green+red;\n\
+col[-2]:=col[-1]:=col0:=black;\n\
+col1:=red;\n\
+col2:=(.2,.2,1); %blue\n\
+col3:=(1,.66,0); %orange\n\
+col4:=.85*green;\n\
+col5:=.9*magenta;\n\
+col6:=0.85*cyan;\n\
+col7:=.85*yellow;\n\
+\n\
+%placing text\n\
+picture GPtext;\n\
+def put_text(expr pic, x, y, r, j) =\n\
+  GPtext:=makepic(pic);\n\
+  GPtext:=GPtext shifted\n\
+    if j = 1: (-(ulcorner GPtext + llcorner GPtext)/2)\n\
+    elseif j = 2: (-center GPtext)\n\
+    else: (-(urcorner GPtext + lrcorner GPtext)/2)\n\
+    fi\n\
+    rotated r;\n\
+  draw GPtext shifted (x,y)\n\
+enddef;\n", gpoutfile);
+}
+
+TERM_PUBLIC void
+MP_graphics()
+{
+    /* initialize "remembered" drawing parameters */
+    MP_oldline = -2;
+    MP_oldpen = 1.0;
+    MP_oldptsize = pointsize;
+    fprintf(gpoutfile, "\nbeginfig(%d);\nw:=%.3fin;h:=%.3fin;\n",
+           MP_char_code, MP_xsize, MP_ysize);
+    /* MetaPost can only handle numbers up to 4096. When MP_DPI
+     * is larger than 819, this is exceeded by (term->xmax). So we
+     * scale it and all coordinates down by factor of 10.0. And
+     * compensate by scaling a and b up.
+     */
+    fprintf(gpoutfile, "a:=w/%.1f;b:=h/%.1f;\n",
+           (term->xmax) / 10.0, (term->ymax) / 10.0);
+    fprintf(gpoutfile, "scalepen 1; ptsize %.3f;linetype -2;\n", pointsize);
+    MP_char_code++;
+    /* reset MP_color_changed */
+    MP_color_changed = 0;
+}
+
+TERM_PUBLIC void
+MP_text()
+{
+    if (MP_inline)
+       MP_endline();
+    fputs("endfig;\n", gpoutfile);
+}
+
+TERM_PUBLIC void
+MP_linetype(int lt)
+{
+    int linetype = lt;
+
+    if (linetype >= MP_LINE_TYPES)
+       linetype %= MP_LINE_TYPES;
+    if (MP_inline)
+       MP_endline();
+    /* reset the color in case it has been changed in MP_set_color() */
+    if (MP_color_changed) {
+       MP_oldline = linetype + 1;
+       MP_color_changed = 0;
+    }
+    if (MP_oldline != linetype) {
+       fprintf(gpoutfile, "linetype %d;\n", linetype);
+       MP_oldline = linetype;
+    }
+}
+
+TERM_PUBLIC void
+MP_move(unsigned int x, unsigned int y)
+{
+    if ((x != MP_posx) || (y != MP_posy)) {
+       if (MP_inline)
+           MP_endline();
+       MP_posx = x;
+       MP_posy = y;
+    }                          /* else we seem to be there already */
+}
+
+TERM_PUBLIC void
+MP_point(unsigned int x, unsigned int y, int pt)
+{
+    int pointtype = pt;
+    if (MP_inline)
+       MP_endline();
+
+    /* Print the shape defined by 'number'; number < 0 means
+       to use a dot, otherwise one of the defined points. */
+
+    if (pointtype >= MP_POINT_TYPES)
+       pointtype %= MP_POINT_TYPES;
+/* Change %d to %f, divide x,y by 10 */
+    fprintf(gpoutfile, "gpdraw(%d,%.1fa,%.1fb);\n", pointtype, x / 10.0, y / 10.0);
+}
+
+TERM_PUBLIC void
+MP_pointsize(double ps)
+{
+    if (ps < 0)
+       ps = 1;
+    if (MP_oldptsize != ps) {
+       if (MP_inline)
+           MP_endline();
+       fprintf(gpoutfile, "ptsize %.3f;\n", ps);
+       MP_oldptsize = ps;
+    }
+}
+
+
+TERM_PUBLIC void
+MP_linewidth(double lw)
+{
+    if (MP_oldpen != lw) {
+       if (MP_inline)
+           MP_endline();
+       fprintf(gpoutfile, "scalepen %.3f;\n", lw);
+       MP_oldpen = lw;
+    }
+}
+
+
+TERM_PUBLIC void
+MP_vector(unsigned int ux, unsigned int uy)
+{
+    if ((ux == MP_posx) && (uy == MP_posy))
+       return;                 /* Zero length line */
+
+    if (MP_inline) {
+       if (MP_linecount++ >= MP_LINEMAX) {
+           fputs("\n", gpoutfile);
+           MP_linecount = 1;
+       }
+    } else {
+       MP_inline = TRUE;
+       fprintf(gpoutfile, "draw (%.1fa,%.1fb)", MP_posx / 10.0, MP_posy / 10.0);
+       MP_linecount = 2;
+    }
+    MP_posx = ux;
+    MP_posy = uy;
+    fprintf(gpoutfile, "--(%.1fa,%.1fb)", MP_posx / 10.0, MP_posy / 10.0);
+}
+
+static void
+MP_endline()
+{
+    MP_inline = FALSE;
+    fprintf(gpoutfile, ";\n");
+}
+
+TERM_PUBLIC void
+MP_arrow(unsigned int sx, unsigned int sy, unsigned int ex, unsigned int ey, int head)
+{
+    MP_move(sx, sy);
+    if (head) {
+       fprintf(gpoutfile, "%s (%.1fa,%.1fb)--(%.1fa,%.1fb);\n",
+               head == 1 ? "drawarrow" : "drawdblarrow",
+               sx / 10.0, sy / 10.0, ex / 10.0, ey / 10.0);
+    } else if ((sx != ex) || (sy != ey)) {
+       fprintf(gpoutfile, "draw (%.1fa,%.1fb)--(%.1fa,%.1fb);\n",
+               sx / 10.0, sy / 10.0, ex / 10.0, ey / 10.0);
+    }  /* else: arrow with no length and no head = sound of one hand clapping? */
+    MP_posx = ex;
+    MP_posy = ey;
+
+}
+
+TERM_PUBLIC void
+MP_put_text(unsigned int x, unsigned int y, const char str[])
+{
+    int i, j = 0;
+    char *text;
+
+    /* ignore empty strings */
+    if (!str || !*str)
+       return;
+
+    /* F***. why do drivers need to modify string args? */
+    text = gp_strdup(str);
+
+    if (MP_inline)
+       MP_endline();
+
+
+    switch (MP_justify) {
+    case LEFT:
+       j = 1;
+       break;
+    case CENTRE:
+       j = 2;
+       break;
+    case RIGHT:
+       j = 3;
+       break;
+    }
+    if (MP_tex == MP_NO_TEX) {
+       for (i = 0; i < strlen(text); i++)
+           if (text[i] == '"')
+               text[i] = '\''; /* Replace " with ' */
+       if (MP_fontchanged) {
+           fprintf(gpoutfile, "\
+put_text(\"%s\" infontsize(\"%s\",%5.2f), %.1fa, %.1fb, %d, %d);\n",
+                   text, MP_fontname, MP_fontsize,
+                   x / 10.0, y / 10.0, MP_ang, j);
+       } else {
+           fprintf(gpoutfile, "put_text(\"%s\", %.1fa, %.1fb, %d, %d);\n",
+                   text, x / 10.0, y / 10.0, MP_ang, j);
+       }
+    } else if (MP_fontchanged) {
+       if (MP_tex != MP_LATEX) {
+           fprintf(gpoutfile, "\
+put_text( btex \\setfont{%s}{%5.2f} %s etex, %.1fa, %.1fb, %d, %d);\n",
+                   MP_fontname, MP_fontsize, text,
+                   x / 10.0, y / 10.0, MP_ang, j);
+       } else {
+           fprintf(gpoutfile, "put_text( btex %s etex, %.1fa, %.1fb, %d, %d);\n",
+                   text, x / 10.0, y / 10.0, MP_ang, j);
+       }
+    } else {
+       fprintf(gpoutfile, "put_text( btex %s etex, %.1fa, %.1fb, %d, %d);\n",
+               text, x / 10.0, y / 10.0, MP_ang, j);
+    }
+
+    free(text);
+}
+
+TERM_PUBLIC int
+MP_justify_text(enum JUSTIFY mode)
+{
+    MP_justify = mode;
+    return (TRUE);
+}
+
+TERM_PUBLIC int
+MP_text_angle(int ang)
+{
+    /* Metapost code does the conversion */
+    MP_ang = ang;
+    return (TRUE);
+}
+
+TERM_PUBLIC int
+MP_set_font(const char *font)
+{
+    if (*font) {
+       size_t sep = strcspn(font, ",");
+       strncpy(MP_fontname, font, sep);
+       MP_fontname[sep] = NUL;
+       sscanf(&(font[sep + 1]), "%lf", &MP_fontsize);
+       if (MP_fontsize < 5)
+           MP_fontsize = 5.0;
+       if (MP_fontsize >= 100)
+           MP_fontsize = 99.99;
+       /*  */
+       MP_fontchanged = TRUE;
+    } else {
+       MP_fontchanged = FALSE;
+    }
+    return TRUE;
+}
+
+
+TERM_PUBLIC void
+MP_reset()
+{
+    if (MP_tex == MP_LATEX) {
+       fputs("% BEGPOST\n",gpoutfile);
+       fputs("verbatimtex\n",gpoutfile);
+       fputs(" \\end{document}\n",gpoutfile);
+       fputs("etex\n",gpoutfile);
+       fputs("% ENDPOST\n",gpoutfile);
+    };
+    fputs("end.\n", gpoutfile);
+}
+
+TERM_PUBLIC void
+MP_boxfill(
+    int style,
+    unsigned int x1, unsigned int y1,
+    unsigned int wd, unsigned int ht)
+{
+
+    /* fillpar:
+     * - solid   : 0 - 100% intensity
+     * - pattern : 0 - n    pattern number
+     */
+    int fillpar = style >> 4;
+    style &= 0xf;
+
+    if (MP_inline)
+       MP_endline();
+
+    switch (style) {
+
+       case FS_EMPTY: /* fill with background color */
+           fprintf(gpoutfile, "\
+fill (%.1fa,%.1fb)--(%.1fa,%.1fb)--(%.1fa,%.1fb)--(%.1fa,%.1fb)--cycle withcolor background;\n",
+               x1 / 10.0, y1 / 10.0, (x1 + wd) / 10.0, y1 / 10.0,
+               (x1 + wd) / 10.0, (y1 + ht) / 10.0, x1 / 10.0,
+               (y1 + ht) / 10.0);
+           break;
+
+       case FS_PATTERN: /* pattern fill */
+           /* FIXME: not yet implemented, dummy it up as fill density */
+           fillpar *= 12;
+
+       default:
+       case FS_SOLID: /* solid fill */
+           if (fillpar < 100) {
+               double density = (100-fillpar) * 0.01;
+               fprintf(gpoutfile,"fillcolor:=currentcolor*%.2f+background*%.2f;\n",
+                   1.0-density, density);
+               MP_color_changed = 1;
+           } else
+               fprintf(gpoutfile,"fillcolor:=currentcolor;\n");
+           fprintf(gpoutfile, "\
+fill (%.1fa,%.1fb)--(%.1fa,%.1fb)--(%.1fa,%.1fb)--(%.1fa,%.1fb)--cycle withpen (pencircle scaled 0pt) withcolor fillcolor;\n",
+           x1 / 10.0, y1 / 10.0, (x1 + wd) / 10.0, y1 / 10.0,
+           (x1 + wd) / 10.0, (y1 + ht) / 10.0, x1 / 10.0,
+           (y1 + ht) / 10.0);
+           break;
+
+    }
+
+}
+
+TERM_PUBLIC int
+MP_make_palette(t_sm_palette *palette)
+{
+    /* metapost can do continuous number of colours */
+    return 0;
+}
+
+
+TERM_PUBLIC void
+MP_set_color(t_colorspec *colorspec)
+{
+    double gray = colorspec->value;
+    rgb_color color;
+
+    /* remeber that we changed the color, needed to reset color in MP_linetype()*/
+    MP_color_changed = 1;
+
+    if (MP_inline)
+       MP_endline();
+
+    if (!MP_color) {           /* gray mode */
+       if (gray < 1e-3) gray = 0;
+       fprintf(gpoutfile, "currentcolor:=%.3gwhite;\n", gray);
+    } else {                   /* color mode */
+       if (colorspec->type == TC_LT) {
+           int linecolor = colorspec->lt;
+           if (linecolor >= MP_LINE_TYPES)
+               linecolor %= MP_LINE_TYPES;
+           if (linecolor == -1)
+               fprintf(gpoutfile, "currentcolor:=black;\n");
+           else if (linecolor >= 0)
+               fprintf(gpoutfile, "currentcolor:=col%d;\n",linecolor);
+       }
+       if (colorspec->type == TC_FRAC) {
+           if (sm_palette.colors != 0) /* finite nb of colors explicitly requested */
+               gray = (gray >= ((double)(sm_palette.colors-1)) / sm_palette.colors) ?
+                   1 : floor(gray * sm_palette.colors) / sm_palette.colors;
+           rgb1_from_gray( gray, &color );
+       } else if (colorspec->type == TC_RGB) {
+           color.r = (double)((colorspec->lt >> 16 ) & 255) / 255.;
+           color.g = (double)((colorspec->lt >> 8 ) & 255) / 255.;
+           color.b = (double)(colorspec->lt & 255) / 255.;
+       } else
+           return;
+
+       if (color.r < 1e-4) color.r = 0;
+       if (color.g < 1e-4) color.g = 0;
+       if (color.b < 1e-4) color.b = 0;
+       fprintf(gpoutfile, "currentcolor:=%.4g*red+%.4g*green+%.4g*blue;\n",
+               color.r, color.g, color.b);
+    }
+    return;
+}
+
+TERM_PUBLIC void
+MP_filled_polygon(int points, gpiPoint *corners)
+{
+    int i;
+    int fillpar = corners->style >> 4;
+    int style = corners->style & 0xf;
+
+    if (MP_inline)
+       MP_endline();
+
+    switch (style) {
+       case FS_EMPTY:  /* fill with background color */
+               fprintf(gpoutfile,"fillcolor:=background;\n");
+               break;
+       case FS_PATTERN: /* pattern fill implemented as partial density */
+               fillpar *= 12;
+       case FS_SOLID:  /* solid fill */
+               if (fillpar < 100) {
+                   double density = (100-fillpar) * 0.01;
+                   fprintf(gpoutfile,"fillcolor:=currentcolor*%.2f+background*%.2f;\n",
+                       1.0-density, density);
+               } else {
+                   fprintf(gpoutfile,"fillcolor:=currentcolor;\n");
+               }
+       default:
+               break;
+    }
+
+    fprintf(gpoutfile, "fill ");
+    for (i = 0; i < points; i++)
+       fprintf(gpoutfile, "(%.1fa,%.1fb)%s",
+               corners[i].x / 10.0, corners[i].y / 10.0,
+               (i < points - 1 && (i + 1) % MP_LINEMAX == 0) ? "\n--" : "--");
+    fprintf(gpoutfile, "cycle withcolor fillcolor;\n");
+}
+
+TERM_PUBLIC void
+MP_previous_palette()
+{
+    return;
+}
+
+#endif /* TERM_BODY */
+
+#ifdef TERM_TABLE
+
+TERM_TABLE_START(mp_driver)
+    "mp", "MetaPost plotting standard",
+    MP_XMAX, MP_YMAX, MP_VCHAR, MP_HCHAR,
+    MP_VTIC, MP_HTIC, MP_options, MP_init, MP_reset,
+    MP_text, null_scale, MP_graphics, MP_move, MP_vector,
+    MP_linetype, MP_put_text, MP_text_angle,
+    MP_justify_text, MP_point, MP_arrow, MP_set_font, MP_pointsize,
+    TERM_BINARY|TERM_CAN_CLIP /*flags*/, 
+    0, 0, MP_boxfill, MP_linewidth
+#ifdef USE_MOUSE
+    , 0, 0, 0, 0, 0            /* no mouse support for metapost */
+#endif
+    , MP_make_palette,
+    MP_previous_palette,       /* write grestore */
+    MP_set_color,
+    MP_filled_polygon
+TERM_TABLE_END(mp_driver)
+#undef LAST_TERM
+#define LAST_TERM mp_driver
+
+#endif                         /* TERM_TABLE */
+#endif                         /* TERM_PROTO_ONLY */
+
+#ifdef TERM_HELP
+START_HELP(mp)
+"1 mp",
+"?commands set terminal mpost",
+"?set terminal mp",
+"?set term mp",
+"?terminal mp",
+"?term mp",
+"?mp",
+"?metapost",
+"",
+" The `mp` driver produces output intended to be input to the Metapost program.",
+" Running Metapost on the file creates EPS files containing the plots. By",
+" default, Metapost passes all text through TeX.  This has the advantage of",
+" allowing essentially  any TeX symbols in titles and labels.",
+"",
+" Syntax:",
+"    set term mp {color | colour | monochrome}",
+"                {solid | dashed}",
+"                {notex | tex | latex}",
+"                {magnification <magsize>}",
+"                {psnfss | psnfss-version7 | nopsnfss}",
+"                {prologues <value>}",
+"                {a4paper}",
+"                {amstex}",
+"                {\"<fontname>\"} {<fontsize>}",
+"",
+" The option `color` causes lines to be drawn in color (on a printer or display",
+" that supports it), `monochrome` (or nothing) selects black lines.  The option",
+" `solid` draws solid lines, while `dashed` (or nothing) selects lines with",
+" different patterns of dashes.  If `solid` is selected but `color` is not,",
+" nearly all lines will be identical.  This may occasionally be useful, so it is",
+" allowed.",
+"",
+" The option `notex` bypasses TeX entirely, therefore no TeX code can be used in",
+" labels under this option.  This is intended for use on old plot files or files",
+" that make frequent use of common characters like `$` and `%` that require",
+" special handling in TeX.",
+"",
+" The option `tex` sets the terminal to output its text for TeX to process.",
+"",
+" The option `latex` sets the terminal to output its text for processing by",
+" LaTeX. This allows things like \\frac for fractions which LaTeX knows about",
+" but TeX does not.  Note that you must set the environment variable TEX to the",
+" name of your LaTeX executable (normally latex) if you use this option or use",
+" `mpost --tex=<name of LaTeX executable> ...`. Otherwise metapost will try and",
+" use TeX to process the text and it won't work.",
+"",
+" Changing font sizes in TeX has no effect on the size of mathematics, and there",
+" is no foolproof way to make such a change, except by globally  setting a",
+" magnification factor. This is the purpose of the `magnification` option. It",
+" must be followed by a scaling factor. All text (NOT the graphs) will be scaled",
+" by this factor. Use this if you have math that you want at some size other",
+" than the default 10pt. Unfortunately, all math will be the same size, but see",
+" the discussion below on editing the MP output. `mag` will also work under",
+" `notex` but there seems no point in using it as the font size option (below)",
+" works as well.",
+"",
+" The option `psnfss` uses postscript fonts in combination with LaTeX. Since",
+" this option only makes sense, if LaTeX is being used, the `latex` option is selected",
+" automatically. This option includes the following packages for LaTeX:",
+" inputenc(latin1), fontenc(T1), mathptmx, helvet(scaled=09.2), courier, latexsym ",
+" and textcomp.",
+"",
+" The option `psnfss-version7` uses also postscript fonts in LaTeX (option `latex`",
+" is also automatically selected), but uses the following packages with LaTeX:",
+" inputenc(latin1), fontenc(T1), times, mathptmx, helvet and courier.",
+"",
+" The option `nopsnfss` is the default and uses the standard font (cmr10 if not",
+" otherwise specified).",
+"",
+" The option `prologues` takes a value as an additional argument and adds the line",
+" `prologues:=<value>` to the metapost file. If a value of `2` is specified metapost",
+" uses postscript fonts to generate the eps-file, so that the result can be viewed",
+" using e.g. ghostscript. Normally the output of metapost uses TeX fonts and therefore",
+" has to be included in a (La)TeX file before you can look at it.",
+"",
+" The option `noprologues` is the default. No additional line specifying the prologue",
+" will be added.",
+"",
+" The option `a4paper` adds a `[a4paper]` to the documentclass. Normally letter paper",
+" is used (default). Since this option is only used in case of LaTeX, the `latex` option",
+" is selected automatically.",
+"",
+" The option `amstex` automatically selects the `latex` option and includes the following",
+" LaTeX packages: amsfonts, amsmath(intlimits). By default these packages are not",
+" included.",
+"",
+" A name in quotes selects the font that will be used when no explicit font is",
+" given in a `set label` or `set title`.  A name recognized by TeX (a TFM file",
+" exists) must be used.  The default is \"cmr10\" unless `notex` is selected,",
+" then it is \"pcrr8r\" (Courier).  Even under `notex`, a TFM file is needed by",
+" Metapost. The file `pcrr8r.tfm` is the name given to Courier in LaTeX's psnfss",
+" package.  If you change the font from the `notex` default, choose a font that",
+" matches the ASCII encoding at least in the range 32-126.  `cmtt10` almost",
+" works, but it has a nonblank character in position 32 (space).",
+"",
+" The size can be any number between 5.0 and 99.99.  If it is omitted, 10.0 is",
+" used.  It is advisable to use `magstep` sizes: 10 times an integer or",
+" half-integer power of 1.2, rounded to two decimals, because those are the most",
+" available sizes of fonts in TeX systems.",
+"",
+" All the options are optional.  If font information is given, it must be at the",
+" end, with size (if present) last.  The size is needed to select a size for the",
+" font, even if the font name includes size information.  For example,",
+" `set term mp \"cmtt12\"` selects cmtt12 shrunk to the default size 10.  This",
+" is probably not what you want or you would have used cmtt10.",
+"",
+" The following common ascii characters need special treatment in TeX:",
+"    $, &, #, %, _;  |, <, >;  ^, ~,  \\, {, and }",
+" The five characters $, #, &, _, and % can simply be escaped, e.g., `\\$`.",
+" The three characters <, >, and | can be wrapped in math mode, e.g., `$<$`.",
+" The remainder require some TeX work-arounds.  Any good book on TeX will give",
+" some guidance.",
+"",
+" If you type your labels inside double quotes, backslashes in TeX code need to",
+" be escaped (doubled). Using single quotes will avoid having to do this, but",
+" then you cannot use `\\n` for line breaks.  As of this writing, version 3.7 of",
+" gnuplot processes titles given in a `plot` command differently than in other",
+" places, and backslashes in TeX commands need to be doubled regardless of the",
+" style of quotes.",
+"",
+" Metapost pictures are typically used in TeX documents.  Metapost deals with",
+" fonts pretty much the same way TeX does, which is different from most other",
+" document preparation programs.  If the picture is included in a LaTeX document",
+" using the graphics package, or in a plainTeX document via epsf.tex, and then",
+" converted to PostScript with dvips (or other dvi-to-ps converter), the text in",
+" the plot will usually be handled correctly.  However, the text may not appear",
+" if you send the Metapost output as-is to a PostScript interpreter.",
+"",
+"2 Metapost Instructions",
+"?commands set terminal mp detailed",
+"?set terminal mp detailed",
+"?set term mp detailed",
+"?mp detailed",
+"?metapost detailed",
+"",
+" - Set your terminal to Metapost, e.g.:",
+"    set terminal mp mono \"cmtt12\" 12",
+"",
+" - Select an output-file, e.g.:",
+"    set output \"figure.mp\"",
+"",
+" - Create your pictures.  Each plot (or multiplot group) will generate a",
+" separate Metapost beginfig...endfig group.  Its default size will be 5 by 3",
+" inches.  You can change the size by saying `set size 0.5,0.5` or whatever",
+" fraction of the default size you want to have.",
+"",
+" - Quit gnuplot.",
+"",
+" - Generate EPS files by running Metapost on the output of gnuplot:",
+"    mpost figure.mp  OR  mp figure.mp",
+" The name of the Metapost program depends on the system, typically `mpost` for",
+" a Unix machine and `mp` on many others.  Metapost will generate one EPS file",
+" for each picture.",
+"",
+" - To include your pictures in your document you can use the graphics package",
+" in LaTeX or epsf.tex in plainTeX:",
+"    \\usepackage{graphics} % LaTeX",
+"    \\input epsf.tex       % plainTeX",
+" If you use a driver other than dvips for converting TeX DVI output to PS, you",
+" may need to add the following line in your LaTeX document:",
+"    \\DeclareGraphicsRule{*}{eps}{*}{}",
+" Each picture you made is in a separate file.  The first picture is in, e.g.,",
+" figure.0, the second in figure.1, and so on....  To place the third picture in",
+" your document, for example, all you have to do is:",
+"    \\includegraphics{figure.2} % LaTeX",
+"    \\epsfbox{figure.2}         % plainTeX",
+"",
+" The advantage, if any, of the mp terminal over a postscript terminal is",
+" editable output.  Considerable effort went into making this output as clean as",
+" possible.  For those knowledgeable in the Metapost language, the default line",
+" types and colors can be changed by editing the arrays `lt[]` and `col[]`.",
+" The choice of solid vs dashed lines, and color vs black lines can be change by",
+" changing the values assigned to the booleans `dashedlines` and `colorlines`.",
+" If the default `tex` option was in effect, global changes to the text of",
+" labels can be achieved by editing the `vebatimtex...etex` block.  In",
+" particular, a LaTeX preamble can be added if desired, and then LaTeX's",
+" built-in size changing commands can be used for maximum flexibility. Be sure",
+" to set the appropriate MP configuration variable to force Metapost to run",
+" LaTeX instead of plainTeX."
+END_HELP(mp)
+#endif                         /* TERM_HELP */