home *** CD-ROM | disk | FTP | other *** search
- /*
- * F2p : Fig-to-pic translator
- *
- * Copyright (c) 1985, 1988 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
- * January 1985.
- * 1st revision : October 1985.
- * 2nd revision : March 1988 - read fig 1.4
- * Support for fonts and point sizes added by daved@physiol.su.oz.au
- * March 1990
- *
- * %W% %G%
- */
- #include "fig.h"
- #include "object.h"
- #include "troff_fonts.h"
- #include "psfonts.h"
-
- char Usage[] = "Usage: f2p [ -f font_file ] [ input_file [ output_file ] ]\n";
- char *from = NULL,
- *to = NULL;
- FILE *tfp = NULL;
- char Err_incomp[] = "Incomplete %s object at line %d.";
- char Err_mem[] = "Running out of memory.";
-
- int line_thickness; /* not for f2ps - arrow.c needs it for fig */
- extern struct _fstruct fontnames[]; /* printer font names */
- int dotps, /* most recent size passed to .ps */
- dotft; /* one more than num of font passed to .ft */
-
- /*VARARGS1*/
- put_msg(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
- char *format, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6, *arg7, *arg8;
- {
- fprintf(stderr, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
- fputc('\n',stderr);
- }
-
- get_args(argc, argv)
- int argc;
- char *argv[];
- {
- char *a;
- int first = 1;
-
- while (--argc)
- {
- a = *++argv;
- if (*a == '-')
- {
- if (*++a == 'f')
- {
- if (--argc)
- font_file = *++argv;
- else
- {
- fprintf(stderr, Usage);
- exit(1);
- }
- }
- else
- {
- fprintf(stderr, Usage);
- exit(1);
- }
- }
- else if (first)
- {
- from = a; /* from file */
- first = 0;
- }
- else if (first == 0)
- {
- to = a; /* to file */
- first = -1;
- }
- else
- {
- fprintf(stderr, Usage);
- exit(1);
- }
- }
- }
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- F_compound objects;
- int status;
-
- get_args(argc, argv);
- troff_init();
- if (to == NULL)
- tfp = stdout;
- else if ((tfp = fopen(to, "w")) == NULL)
- {
- fprintf(stderr, "Couldn't open %s\n", to);
- fprintf(stderr, Usage);
- exit(1);
- }
-
- if (from)
- status = read_fig(from, &objects);
- else /* read from stdin */
- status = readfp_fig(stdin, &objects);
-
- if (status != 0)
- {
- if (from) read_fail_message(from, status);
- exit(1);
- }
- genpic_objects(&objects);
- if (tfp != stdout) fclose(tfp);
- exit(0);
- }
-
- #define TOP 10.5 /* top of page is 10.5 inch */
- static double ppi;
- static int CONV = 0;
-
- double
- convy(a)
- double a;
- {
- return((double)(CONV ? TOP-a : a));
- }
-
- genpic_objects(objects)
- F_compound *objects;
- {
- int coord_system;
- F_arc *a;
- F_compound *c;
- F_ellipse *e;
- F_line *l;
- F_spline *s;
- F_text *t;
-
- if (0 == (ppi = (double)objects->nwcorner.x))
- {
- fprintf(stderr, "Resolution is zero!! default to 80 ppi\n");
- ppi = 80.0;
- }
- coord_system = objects->nwcorner.y;
- if (coord_system != 1 && coord_system != 2)
- {
- fprintf(stderr, "Wrong coordinate system; cannot continue\n");
- return;
- }
- if (coord_system == 2) CONV = 1;
-
- fprintf(tfp, ".PS\n"); /* start of pic macro */
-
- for (a = objects->arcs; a != NULL; a = a->next) genpic_arc(a);
- for (c = objects->compounds; c != NULL; c = c->next) genpic_compound(c);
- for (e = objects->ellipses; e != NULL; e = e->next) genpic_ellipse(e);
- for (l = objects->lines; l != NULL; l = l->next) genpic_line(l);
- for (s = objects->splines; s != NULL; s = s->next) genpic_spline(s);
- for (t = objects->texts; t != NULL; t = t->next) genpic_text(t);
- if(dotps)
- fprintf(tfp, ".ps\n"); /* back to initial point size */
- if(dotft)
- fprintf(tfp, ".ft\n"); /* back to initial font */
- fprintf(tfp, ".PE\n");
- }
-
- /*
- ** linewidth can be controlled with pointsize, but this means we have
- ** to be rigorous about using a .ps (null) every time, so a real point size
- ** request can revert to previous size
- */
- set_linewidth(w)
- int w;
- {
- if (w == 0 || w*10 == dotps) return;
- fprintf(tfp,".ps\n.ps %d\n",dotps = 10*w);
- }
-
- set_style(s, v)
- int s;
- float v;
- {
- static float style_val = -1;
-
- if (s == DASH_LINE || s == DOTTED_LINE)
- {
- if (v == style_val) return;
- if (v == 0.0) return;
- style_val = v;
- fprintf(tfp, "dashwid = %.3fi\n", style_val/ppi);
- }
- }
-
- genpic_compound(com)
- F_compound *com;
- {
- F_arc *a;
- F_compound *c;
- F_ellipse *e;
- F_line *l;
- F_spline *s;
- F_text *t;
-
- for (a = com->arcs; a != NULL; a = a->next) genpic_arc(a);
- for (c = com->compounds; c != NULL; c = c->next) genpic_compound(c);
- for (e = com->ellipses; e != NULL; e = e->next) genpic_ellipse(e);
- for (l = com->lines; l != NULL; l = l->next) genpic_line(l);
- for (s = com->splines; s != NULL; s = s->next) genpic_spline(s);
- for (t = com->texts; t != NULL; t = t->next) genpic_text(t);
- }
-
- genpic_line(l)
- F_line *l;
- {
- F_point *p, *q;
-
- set_linewidth(l->thickness);
- set_style(l->style, l->style_val);
- p = l->points;
- q = p->next;
- if (q == NULL)
- { /* A single point line */
- fprintf(tfp, "line from %.3f,%.3f to %.3f,%.3f\n",
- p->x/ppi, convy(p->y/ppi), p->x/ppi, convy(p->y/ppi));
- return;
- }
- if (l->back_arrow)
- draw_arrow_head(q->x/ppi, convy(q->y/ppi), p->x/ppi,
- convy(p->y/ppi), l->back_arrow->ht/ppi, l->back_arrow->wid/ppi);
- if (l->style == DASH_LINE && l->style_val > 0.0)
- fprintf(tfp, "line dashed from");
- else if (l->style == DOTTED_LINE && l->style_val > 0.0)
- fprintf(tfp, "line dotted from");
- else
- fprintf(tfp, "line from");
- fprintf(tfp, " %.3f,%.3f to", p->x/ppi, convy(p->y/ppi));
- while (q->next != NULL)
- {
- p = q;
- q = q->next;
- fprintf(tfp, " %.3f,%.3f to", p->x/ppi, convy(p->y/ppi));
- }
- fprintf(tfp, " %.3f,%.3f\n", q->x/ppi, convy(q->y/ppi));
- if (l->for_arrow)
- draw_arrow_head(p->x/ppi, convy(p->y/ppi), q->x/ppi,
- convy(q->y/ppi), l->for_arrow->ht/ppi, l->for_arrow->wid/ppi);
- }
-
- genpic_spline(s)
- F_spline *s;
- {
- set_linewidth(s->thickness);
- if (int_spline(s))
- genpic_itp_spline(s);
- else
- genpic_ctl_spline(s);
- }
-
- genpic_ctl_spline(s)
- F_spline *s;
- {
- if (closed_spline(s))
- genpic_closed_spline(s);
- else
- genpic_open_spline(s);
- }
-
- genpic_open_spline(s)
- F_spline *s;
- {
- double x1, y1, x2, y2;
- F_point *p, *q;
-
- p = s->points;
- x1 = p->x/ppi;
- y1 = convy(p->y/ppi);
- p = p->next;
- x2 = p->x/ppi;
- y2 = convy(p->y/ppi);
-
- if (s->back_arrow)
- draw_arrow_head(x2, y2, x1, y1,
- s->back_arrow->ht/ppi, s->back_arrow->wid/ppi);
-
- /* Pic's spline supports only solid line style */
-
- if (p->next == NULL)
- {
- fprintf(tfp, "line from %.3f,%.3f to %.3f,%.3f\n", x1, y1, x2, y2);
- if (s->for_arrow)
- draw_arrow_head(x1, y1, x2, y2, s->for_arrow->ht/ppi,
- s->for_arrow->wid/ppi);
- return;
- }
-
- fprintf(tfp, "spline from %.3f,%.3f to %.3f,%.3f", x1, y1, x2, y2);
-
- for (q = p->next; q->next != NULL; p = q, q = q->next)
- fprintf(tfp, " to %.3f,%.3f", q->x/ppi, convy(q->y/ppi));
- fprintf(tfp, " to %.3f,%.3f\n", (x2=q->x/ppi), (y2=convy(q->y/ppi)));
-
- if (s->for_arrow)
- draw_arrow_head(p->x/ppi, convy(p->y/ppi), x2, y2,
- s->for_arrow->ht/ppi, s->for_arrow->wid/ppi);
- }
-
- genpic_ellipse(e)
- F_ellipse *e;
- {
- set_linewidth(e->thickness);
- fprintf(tfp, "ellipse at %.3f,%.3f wid %.3f ht %.3f\n",
- e->center.x/ppi, convy(e->center.y/ppi),
- 2 * e->radiuses.x/ppi, 2 * e->radiuses.y/ppi);
- }
-
- /*
- Text is display on the screen with the base line starting at
- (base_x, base_y); some characters extend below this line.
- Pic displays the center of the height of text at the given
- coordinate. HT_OFFSET is use to compensate all the above factors
- so text position in fig 1.4 should be at the same position on
- the screen as on the hard copy.
- */
- #define HT_OFFSET (0.2 / 72.0)
-
- genpic_text(t)
- F_text *t;
- {
- float y;
- static char fontcode[NUMFONTS][3];
- int i;
-
- if(fontcode[t->font][0] == '\0')
- for(i=0; *troff_fonts[i].lwname != '\0'; i++)
- {
- if(strcmp(troff_fonts[i].lwname,fontnames[t->font].psfont)==0)
- {
- strncpy(&fontcode[t->font][0],troff_fonts[i].trname,2);
- break;
- }
- }
- if(fontcode[t->font][0] == '\0')
- fontcode[t->font][0] = 'R'; /* default */
-
- if(t->size != dotps)
- fprintf(tfp, ".ps\n.ps %d\n", dotps = t->size);
- if(t->font != dotft - 1)
- {
- fprintf(tfp, ".ft\n.ft %s\n", &fontcode[t->font][0]);
- dotft = t->font + 1;
- }
-
- y = convy(t->base_y/ppi) + t->size * HT_OFFSET;
- fprintf(tfp, "\"%s\" at %.3f,%.3f",
- t->cstring, t->base_x/ppi, y);
-
- switch(t->type)
- {
- case T_RIGHT_JUSTIFIED:
- fprintf(tfp, " rjust\n");
- break;
- case T_LEFT_JUSTIFIED:
- fprintf(tfp, " ljust\n");
- break;
- default:
- putc('\n',tfp);
- }
- }
-
- genpic_arc(a)
- F_arc *a;
- {
- double x, y;
- double cx, cy, sx, sy, ex, ey;
-
- cx = a->center.x/ppi;
- cy = convy(a->center.y/ppi);
- sx = a->point[0].x/ppi;
- sy = convy(a->point[0].y/ppi);
- ex = a->point[2].x/ppi;
- ey = convy(a->point[2].y/ppi);
-
- set_linewidth(a->thickness);
-
- if (a->for_arrow)
- {
- arc_tangent(cx, cy, ex, ey, a->direction, &x, &y);
- draw_arrow_head(x, y, ex, ey,
- a->for_arrow->ht/ppi, a->for_arrow->wid/ppi);
- }
- if (a->back_arrow)
- {
- arc_tangent(cx, cy, sx, sy, !a->direction, &x, &y);
- draw_arrow_head(x, y, sx, sy,
- a->back_arrow->ht/ppi, a->back_arrow->wid/ppi);
- }
-
- if (a->direction)
- fprintf(tfp, "arc at %.3f,%.3f from %.3f,%.3f to %.3f,%.3f\n",
- cx, cy, sx, sy, ex, ey);
- else
- fprintf(tfp, "arc at %.3f,%.3f from %.3f,%.3f to %.3f,%.3f cw\n",
- cx, cy, sx, sy, ex, ey);
-
- }
-
- arc_tangent(x1, y1, x2, y2, direction, x, y)
- double x1, y1, x2, y2, *x, *y;
- int direction;
- {
- if (direction)
- { /* counter clockwise */
- *x = x2 + (y2 - y1);
- *y = y2 - (x2 - x1);
- }
- else
- {
- *x = x2 - (y2 - y1);
- *y = y2 + (x2 - x1);
- }
- }
-
- /* draw arrow heading from (x1, y1) to (x2, y2) */
-
- draw_arrow_head(x1, y1, x2, y2, arrowht, arrowwid)
- double x1, y1, x2, y2, arrowht, arrowwid;
- {
- double x, y, xb, yb, dx, dy, l, sina, cosa;
- double xc, yc, xd, yd;
-
- dx = x2 - x1;
- dy = y1 - y2;
- l = sqrt((dx*dx + dy*dy));
- sina = dy / l;
- cosa = dx / l;
- xb = x2*cosa - y2*sina;
- yb = x2*sina + y2*cosa;
- x = xb - arrowht;
- y = yb - arrowwid / 2;
- xc = x*cosa + y*sina;
- yc = -x*sina + y*cosa;
- y = yb + arrowwid / 2;
- xd = x*cosa + y*sina;
- yd = -x*sina + y*cosa;
- fprintf(tfp, "line from %.3f,%.3f to %.3f,%.3f to %.3f,%.3f\n",
- xc, yc, x2, y2, xd, yd);
- }
-
- #define THRESHOLD .05 /* inch */
-
- quadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4)
- double a1, b1, a2, b2, a3, b3, a4, b4;
- {
- double x1, y1, x4, y4;
- double xmid, ymid;
-
- x1 = a1;
- y1 = b1;
- x4 = a4;
- y4 = b4;
-
- xmid = (a2 + a3) / 2;
- ymid = (b2 + b3) / 2;
- if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD)
- {
- fprintf(tfp, "\tto %.3f,%.3f\\\n", xmid, ymid);
- }
- else
- {
- quadratic_spline(x1, y1, ((x1+a2)/2), ((y1+b2)/2),
- ((3*a2+a3)/4), ((3*b2+b3)/4), xmid, ymid);
- }
-
- if (fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD)
- {
- fprintf(tfp, "\tto %.3f,%.3f\\\n", x4, y4);
- }
- else
- {
- quadratic_spline(xmid, ymid, ((a2+3*a3)/4), ((b2+3*b3)/4),
- ((a3+x4)/2), ((b3+y4)/2), x4, y4);
- }
- }
-
- genpic_closed_spline(s)
- F_spline *s;
- {
- F_point *p;
- double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
- double x1, y1, x2, y2;
-
- set_linewidth(s->thickness);
- p = s->points;
- x1 = p->x/ppi;
- y1 = convy(p->y/ppi);
- p = p->next;
- x2 = p->x/ppi;
- y2 = convy(p->y/ppi);
- cx1 = (x1 + x2) / 2;
- cy1 = (y1 + y2) / 2;
- cx2 = (x1 + 3 * x2) / 4;
- cy2 = (y1 + 3 * y2) / 4;
-
- for (p = p->next; p != NULL; p = p->next)
- {
- fprintf(tfp, "line from %.3f,%.3f ", cx1, cy1);
- x1 = x2;
- y1 = y2;
- x2 = p->x/ppi;
- y2 = convy(p->y/ppi);
- cx3 = (3 * x1 + x2) / 4;
- cy3 = (3 * y1 + y2) / 4;
- cx4 = (x1 + x2) / 2;
- cy4 = (y1 + y2) / 2;
- quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
- fprintf(tfp, "\n");
- cx1 = cx4;
- cy1 = cy4;
- cx2 = (x1 + 3 * x2) / 4;
- cy2 = (y1 + 3 * y2) / 4;
- }
- x1 = x2;
- y1 = y2;
- p = s->points->next;
- x2 = p->x/ppi;
- y2 = convy(p->y/ppi);
- cx3 = (3 * x1 + x2) / 4;
- cy3 = (3 * y1 + y2) / 4;
- cx4 = (x1 + x2) / 2;
- cy4 = (y1 + y2) / 2;
- fprintf(tfp, "line from %.3f,%.3f ", cx1, cy1);
- quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
- fprintf(tfp, "\n");
- }
-
- genpic_itp_spline(s)
- F_spline *s;
- {
- F_point *p1, *p2;
- F_control *cp1, *cp2;
- double x1, x2, y1, y2;
-
- p1 = s->points;
- cp1 = s->controls;
- cp2 = cp1->next;
- x2 = p1->x/ppi;
- y2 = convy(p1->y/ppi);
-
- if (s->back_arrow)
- draw_arrow_head(cp2->lx/ppi, convy(cp2->ly/ppi), x2, y2,
- s->back_arrow->ht/ppi, s->back_arrow->wid/ppi);
-
- for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
- cp1 = cp2, p2 = p2->next, cp2 = cp2->next)
- {
- fprintf(tfp, "line from %.3f,%.3f ", x2, y2);
- x1 = x2;
- y1 = y2;
- x2 = p2->x/ppi;
- y2 = convy(p2->y/ppi);
- bezier_spline(x1, y1, (double)cp1->rx/ppi, convy(cp1->ry/ppi),
- (double)cp2->lx/ppi, convy(cp2->ly/ppi), x2, y2);
- fprintf(tfp, "\n");
- }
-
- if (s->for_arrow)
- draw_arrow_head((double)cp1->lx/ppi, convy(cp1->ly/ppi), x1, y1,
- (double)s->for_arrow->ht/ppi, (double)s->for_arrow->wid/ppi);
- }
-
- bezier_spline(a0, b0, a1, b1, a2, b2, a3, b3)
- double a0, b0, a1, b1, a2, b2, a3, b3;
- {
- double x0, y0, x3, y3;
- double sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid;
-
- x0 = a0;
- y0 = b0;
- x3 = a3;
- y3 = b3;
- if (fabs(x0 - x3) < THRESHOLD && fabs(y0 - y3) < THRESHOLD)
- {
- fprintf(tfp, "\tto %.3f,%.3f\\\n", x3, y3);
- }
- else
- {
- tx = (a1 + a2) / 2;
- ty = (b1 + b2) / 2;
- sx1 = (x0 + a1) / 2;
- sy1 = (y0 + b1) / 2;
- sx2 = (sx1 + tx) / 2;
- sy2 = (sy1 + ty) / 2;
- tx2 = (a2 + x3) / 2;
- ty2 = (b2 + y3) / 2;
- tx1 = (tx2 + tx) / 2;
- ty1 = (ty2 + ty) / 2;
- xmid = (sx2 + tx1) / 2;
- ymid = (sy2 + ty1) / 2;
-
- bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid);
- bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3);
- }
- }
-
-