diff options
Diffstat (limited to 'graphics/fig2mf/fig2MF.c')
-rw-r--r-- | graphics/fig2mf/fig2MF.c | 629 |
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 */ + } +} + + + + |