summaryrefslogtreecommitdiff
path: root/graphics/fig2mf/fig2MF.c
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/fig2mf/fig2MF.c')
-rw-r--r--graphics/fig2mf/fig2MF.c629
1 files changed, 629 insertions, 0 deletions
diff --git a/graphics/fig2mf/fig2MF.c b/graphics/fig2mf/fig2MF.c
new file mode 100644
index 0000000000..dd5a14a5d4
--- /dev/null
+++ b/graphics/fig2mf/fig2MF.c
@@ -0,0 +1,629 @@
+/*
+ * fig2MF -- convert fig to mfpic METAFONT code
+ *
+ * copyright (c) 1993 Anthony Starks (ajs@merck.com)
+ * You may do anything you want with this code except sell it
+ * or claim that you wrote it.
+ *
+ * Version 0.00 -- Incorporate Tobin's small suggestions
+ * Version 0.01 -- Change scaling to inches,
+ * default [x-y]scale is 1/8 inch
+ * slight format changes in cinit()
+ * Version 0.02 -- Fixed pen switching bug
+ * Version 0.03 -- Support new arcthree mode
+ * Version 0.04 -- Token support for text
+ */
+
+#include <stdio.h>
+
+#define put_msg(x) fputs(x, stderr); \
+ fprintf(stderr, \
+ " at line %d of file \"%s\" \n", line, curfile)
+#define dofill() 1.2-((double)area_fill/(double)FILL_BLACK)
+#define dopen(x) ((x-1)*PEN_INCR)+DEF_PEN
+#define VERSION 0.04
+#define BUF_SIZE 1024
+#define O_ELLIPSE 1
+#define O_POLYLINE 2
+#define O_SPLINE 3
+#define O_TEXT 4
+#define O_ARC 5
+#define O_COMP 6
+#define O_ECOMP -6
+#define FILL_BLACK 21
+#define N_CURVE 11
+#define N_POLYLINE 12
+#define N_ELLIPSE 19
+#define N_ARC 20
+#define DEF_PEN 0.5
+#define PEN_INCR 0.10
+#define DEF_BFILE "graphbase.mf"
+char buf[BUF_SIZE];
+
+typedef struct {
+ char *keyword;
+ double *value;
+} Options;
+
+int line;
+double ppi;
+double mag;
+double code;
+double mfpen;
+double xscale;
+double yscale;
+double xl;
+double yl;
+double xu;
+double yu;
+double maxy;
+char *progname;
+char *curfile;
+char basefile[100];
+
+Options opts[] = {
+{"-mag", &mag},
+{"-code", &code},
+{"-pen", &mfpen},
+{"-xscale", &xscale},
+{"-yscale", &yscale},
+{"-xneg", &xl},
+{"-xpos", &xu},
+{"-yneg", &yl},
+{"-ypos", &yu},
+{"-top", &maxy},
+{NULL, NULL}
+};
+
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ FILE *fp;
+ int i;
+ progname = argv[0];
+ curfile = "Standard Input";
+ strcpy(basefile, DEF_BFILE);
+ line=1;
+ mag=1000.0;
+ code=32.0;
+ mfpen=0.5;
+ xscale=0.125;
+ yscale=0.125;
+ xl=0.0;
+ xu=8.0;
+ yl=0.0;
+ yu=8.0;
+ maxy=8.0;
+
+ if (argc < 2)
+ process("-");
+ else
+ {
+ for (i=1; i < argc; i++)
+ {
+ parse(argv[i]);
+ }
+ }
+
+ ffin();
+ exit(0);
+
+}
+
+parse(s)
+char *s;
+{
+ int i, n;
+ char *strchr();
+ double atof();
+
+ for (i=0; opts[i].keyword != NULL; i++)
+ {
+ if (strncmp(s, opts[i].keyword, strlen(opts[i].keyword)) == 0)
+ {
+ *opts[i].value = atof(strchr(s, '=')+1);
+ return;
+ }
+ }
+ process(s);
+}
+
+process(filename)
+char *filename;
+{
+ FILE *fp;
+
+ int coord_sys, object;
+
+ if (filename[0] == '-')
+ {
+ curfile = "Standard Input";
+ fp = stdin;
+ }
+ else
+ {
+ curfile=filename;
+ if ((fp = fopen(filename, "r")) == NULL)
+ {
+ fprintf(stderr,
+ "%s: cannot open the input file \"%s\"\n",
+ progname, filename);
+ return;
+ }
+ }
+
+ line = 1;
+ fgets(buf, sizeof(buf), fp);
+ if (strncmp(buf, "#FIG 2.1", 8) != 0)
+ {
+ put_msg("Not a fig 2.1 file");
+ return;
+ }
+ get_line(fp);
+ if (sscanf(buf, "%lf%d\n", &ppi, &coord_sys) != 2)
+ {
+ put_msg("Incomplete data");
+ return;
+ }
+ cinit();
+ while (get_line(fp) > 0)
+ {
+ if (sscanf(buf, "%d", &object) != 1)
+ {
+ put_msg("Incorrect format");
+ return;
+ }
+ switch(object)
+ {
+ case O_COMP:
+ case O_ECOMP:
+ break;
+ case O_ELLIPSE:
+ ellipse(fp);
+ break;
+ case O_POLYLINE:
+ polyline(fp);
+ break;
+ case O_SPLINE:
+ curve(fp);
+ break;
+ case O_TEXT:
+ text(fp);
+ break;
+ case O_ARC:
+ arc(fp);
+ break;
+ default:
+ fprintf(stderr, "%d is an ", object);
+ put_msg("unknown object");
+ break;
+ }
+ }
+ cfin();
+ if (fp != stdin) fclose(fp);
+
+}
+
+polyline(fp)
+FILE *fp;
+{
+ int c,
+ n,
+ type,
+ subtype,
+ style,
+ radius,
+ thickness,
+ color,
+ depth,
+ pen,
+ area_fill,
+ fa,
+ ba,
+ at,
+ as,
+ eflag;
+
+ double style_val,
+ athick,
+ awidth,
+ aht;
+
+ char epsfile[100];
+
+ c = 0;
+ n = sscanf(buf, "%d%d%d%d%d%d%d%d%lf%d%d%d",
+ &type,
+ &subtype,
+ &style,
+ &thickness,
+ &color,
+ &depth,
+ &pen,
+ &area_fill,
+ &style_val,
+ &radius,
+ &fa,
+ &ba);
+
+ if (n != N_POLYLINE)
+ {
+ put_msg("Malformed polyline");
+ return c;
+ }
+ if (subtype == 5) fscanf(fp, "%d%s", &eflag, epsfile);
+ if (fa) fscanf(fp, "%d%d%lf%lf%lf\n", &at, &as, &athick, &awidth, &aht);
+ if (ba) fscanf(fp, "%d%d%lf%lf%lf\n", &at, &as, &athick, &awidth, &aht);
+ if (thickness > 1)
+ printf(" pickup pencircle scaled %.2lfpt;\n",
+ dopen(thickness));
+ if (area_fill == FILL_BLACK)
+ printf(" cycleshade(0, false,\n");
+ else if (area_fill < FILL_BLACK && area_fill > 0)
+ printf(" cycleshade(%lfpt, false,\n", dofill());
+ else
+ printf(" curve(false, false,\n");
+ c = coords(type, fp);
+ if (thickness > 1)
+ printf(" pickup pencircle scaled %.2lfpt;\n",
+ mfpen);
+
+ return c;
+}
+
+
+curve(fp)
+FILE *fp;
+{
+ int n,
+ c,
+ i,
+ type,
+ style,
+ subtype,
+ thickness,
+ color,
+ depth,
+ pen,
+ area_fill,
+ fa,
+ ba,
+ at,
+ as;
+
+ double style_val,
+ athick,
+ awidth,
+ aht,
+ z;
+
+ c = 0;
+ n = sscanf(buf, "%d%d%d%d%d%d%d%d%lf%d%d",
+ &type,
+ &subtype,
+ &style,
+ &thickness,
+ &color,
+ &depth,
+ &pen,
+ &area_fill,
+ &style_val,
+ &fa,
+ &ba);
+ if (n != N_CURVE)
+ {
+ put_msg("Malformed spline");
+ return c;
+ }
+ if (fa) fscanf(fp, "%d%d%lf%lf%lf\n", &at, &as, &athick, &awidth, &aht);
+ if (ba) fscanf(fp, "%d%d%lf%lf%lf\n", &at, &as, &athick, &awidth, &aht);
+ if (thickness > 1)
+ printf(" pickup pencircle scaled %.2lfpt;\n",
+ dopen(thickness));
+ if (area_fill == FILL_BLACK)
+ printf(" cycleshade(0, true,\n");
+ else if (area_fill < FILL_BLACK && area_fill > 0)
+ printf(" cycleshade(%lfpt, true,\n", dofill());
+ else
+ printf(" curve(true, false,\n");
+ c = coords(type, fp);
+ if (subtype > 1)
+ for (i=0; i < c*4; i++)
+ fscanf(fp, "%lf", &z);
+ if (thickness > 1)
+ printf(" pickup pencircle scaled %.2lfpt;\n", mfpen);
+ return c;
+}
+
+coords(obj, fp)
+int obj;
+FILE *fp;
+{
+ int c, n, x, y;
+
+ c = 0;
+ if ((n = fscanf(fp, "%d%d", &x, &y)) != 2)
+ {
+ put_msg("Incomplete object");
+ return c;
+ }
+ printf(" (%lf, %lf)", x/ppi, maxy-(y/ppi));
+ for (c = 1;;)
+ {
+ if (fscanf(fp, "%d%d", &x, &y) != 2)
+ {
+ put_msg("Incomplete object");
+ fputs(buf, stderr);
+ return c;
+ }
+ if (x == 9999) break;
+ printf(",\n (%lf, %lf)", x/ppi, maxy-(y/ppi));
+ c++;
+ }
+ printf(");\n");
+ return c;
+
+}
+
+ellipse(fp)
+FILE *fp;
+{
+ int n,
+ type,
+ subtype,
+ style,
+ thickness,
+ color,
+ depth,
+ pen,
+ area_fill,
+ dir,
+ cx,
+ cy,
+ rx,
+ ry,
+ sx,
+ sy,
+ ex,
+ ey;
+
+ double style_val,
+ angle;
+
+ n = sscanf(buf, "%d%d%d%d%d%d%d%d%lf%d%lf%d%d%d%d%d%d%d%d",
+ &type,
+ &subtype,
+ &style,
+ &thickness,
+ &color,
+ &depth,
+ &pen,
+ &area_fill,
+ &style_val,
+ &dir,
+ &angle,
+ &cx,
+ &cy,
+ &rx,
+ &ry,
+ &sx,
+ &sy,
+ &ex,
+ &ey);
+ if (n != N_ELLIPSE)
+ {
+ put_msg("Malformed circle or ellipse");
+ return;
+ }
+
+ if (thickness > 1)
+ printf(" pickup pencircle scaled %.2lfpt;\n",
+ dopen(thickness));
+
+ if (subtype == 3 || subtype == 4)
+ {
+ if (area_fill == FILL_BLACK)
+ printf(" circshade(0, ");
+ else if (area_fill < FILL_BLACK && area_fill > 0)
+ printf(" circshade(%lfpt, ", dofill());
+ else
+ printf(" circle(");
+ printf("(%lf,%lf),%lf);\n",
+ cx/ppi, maxy-(cy/ppi), rx/ppi);
+ }
+ else if (subtype == 1 || subtype == 2)
+ {
+ if (area_fill == FILL_BLACK)
+ printf(" ellshade(0, ");
+ else if (area_fill < FILL_BLACK && area_fill > 0)
+ printf(" ellshade(%lfpt, ", dofill());
+ else
+ printf(" ellipse(");
+ printf("(%lf,%lf),%lf,%lf,0);\n",
+ cx/ppi, maxy-(cy/ppi), rx/ppi, ry/ppi);
+ }
+ if (thickness > 1)
+ printf(" pickup pencircle scaled %.2lfpt;\n", mfpen);
+
+}
+
+arc(fp)
+FILE *fp;
+{
+
+ int n,
+ type,
+ subtype,
+ style,
+ thickness,
+ color,
+ depth,
+ pen,
+ fill,
+ dir,
+ fa,
+ ba,
+ x1,
+ y1,
+ x2,
+ y2,
+ x3,
+ y3;
+
+ double style_val,
+ cx,
+ cy;
+
+
+ n = sscanf(buf, "%d%d%d%d%d%d%d%d%lf%d%d%d%lf%lf%d%d%d%d%d%d",
+ &type,
+ &subtype,
+ &style,
+ &thickness,
+ &color,
+ &depth,
+ &pen,
+ &fill,
+ &style_val,
+ &dir,
+ &fa,
+ &ba,
+ &cx,
+ &cy,
+ &x1,
+ &y1,
+ &x2,
+ &y2,
+ &x3,
+ &y3);
+
+ if (fa) get_line(fp);
+ if (ba) get_line(fp);
+
+ if (n != N_ARC)
+ {
+ put_msg("Malformed arc");
+ return n;
+ }
+ if (thickness > 1)
+ printf(" pickup pencircle scaled %.2lfpt;\n",
+ dopen(thickness));
+
+ printf(" arcthree((%lf,%lf), (%lf,%lf), (%lf,%lf));\n",
+ x1/ppi,
+ maxy-(y1/ppi),
+ x2/ppi,
+ maxy-(y2/ppi),
+ x3/ppi,
+ maxy-(y3/ppi));
+
+ if (thickness > 1)
+ printf(" pickup pencircle scaled %.2lfpt;\n",
+ mfpen);
+
+ return n;
+
+}
+
+text(fp)
+FILE *fp;
+{
+
+ int n,
+ x,
+ y;
+
+ int type,
+ font,
+ size,
+ pen,
+ color,
+ depth,
+ filler,
+ angle,
+ flags,
+ ht,
+ len;
+ char text[80],
+ junk[2],
+ *p,
+ *strrchr();
+
+ n = sscanf(buf, "%*d%d%d%d%d%d%d%lf%d%d%d%d%d%[^\1]%[\1]",
+ &type,
+ &font,
+ &size,
+ &pen,
+ &color,
+ &depth,
+ &angle,
+ &flags,
+ &ht,
+ &len,
+ &x,
+ &y,
+ text,
+ junk);
+ if ((n != 13) && (n != 14))
+ {
+ put_msg("Bad Text");
+ return 0;
+ }
+ p = &text[1];
+ printf("%% label((%lf,%lf),%s)\n", x/ppi, maxy-(y/ppi), p);
+ return(strlen(text));
+}
+
+cinit()
+{
+ static int once = 0;
+ static int curchar;
+ if (++once == 1)
+ {
+ curchar = (int)code;
+ printf("%%\n%% %s version %.2lf --- Preamble\n%%\n",
+ progname, VERSION);
+ printf("mag:=%g/1000; input %s; code:=%g;\n",
+ mag, basefile, code);
+ printf("mfpicenv;\ninterim hdwdr:=1; interim hdten:=1;\n");
+ printf("interim penwd:=%.2lfpt;\npickup pencircle scaled penwd;\n", mfpen);
+ }
+ printf("%%\n%% %s (char %d)\n%%\n", curfile, ++curchar);
+ printf("xscale:=%.3lf; yscale:=%.3lf; bounds(%.3lf,%.3lf,%.3lf,%.3lf);\n",
+ xscale, yscale, xl, xu, yl, yu);
+ printf("beginchar(incr code,xscale*(xpos-xneg)*in#,yscale*(ypos-yneg)*in#,0);\n");
+ printf(" setztr;\n");
+ printf(" pickup pencircle scaled %.2lfpt;\n", mfpen);
+}
+
+cfin()
+{
+ printf("endchar;\n");
+}
+
+ffin()
+{
+ if (line > 1) printf("endmfpicenv;\nend.\n");
+}
+
+get_line(fp)
+ FILE *fp;
+{
+ while (1)
+ {
+ if (NULL == fgets(buf, BUF_SIZE, fp))
+ {
+ return (-1);
+ }
+ line++;
+ if (*buf != '\n' && *buf != '#')
+ return (1);
+ /* Skip empty and comment lines */
+ }
+}
+
+
+
+