v08i022: xfig -- X Drawing Tool, Part13/21
Brian V. Smith
envbvs at epb2.lbl.gov
Wed Jul 4 04:01:34 AEST 1990
Submitted-by: envbvs at epb2.lbl.gov (Brian V. Smith)
Posting-number: Volume 8, Issue 22
Archive-name: xfig2.8/part13
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 13 (of 21)."
# Contents: f2hp.c movept.c read.c
# Wrapped by envbvs at epb2.lbl.gov on Thu Jun 28 08:52:45 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'f2hp.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'f2hp.c'\"
else
echo shar: Extracting \"'f2hp.c'\" \(18027 characters\)
sed "s/^X//" >'f2hp.c' <<'END_OF_FILE'
X/*
X * f2hp : Fig-to-HPGL translator
X *
X * Original Copyright (c) 1986 by Supoj Sutanthavibul (supoj at sally.UTEXAS.EDU)
X *
X * Created from f2ps by B.V. Smith 5/90
X *
X * %W% %G%
X*/
X#include "fig.h"
X#include "object.h"
X#include "resources.h"
X
X#define PAGE_WIDTH (10.250-0.250) /* 10" X plot area (7475A) */
X#define PAGE_HEIGHT (7.796-0.596) /* 7.2" Y plot area */
X#define POINT_PER_INCH 72 /* text ppi */
X#define MAX_COLORS 6 /* number of pens */
X#define DEFAULT_COLOR 0 /* black */
X#define UP 0
X#define DOWN 1
X
X#define TRANSF_X(x) (x)*scalex
X#define TRANSF_Y(y) (coord_system==2? (ury-(y))*scaley: (y)*scaley)
X
Xchar Usage[] = "Usage: %s [-P][-L][-debug][-e scale] [input [output]]\n";
Xchar *prog;
Xint cur_thickness;
Xint cur_color= -9;
Xint cur_areafill=0;
Xint debug = 0;
Xint landscape = 1;
Xint pen=UP;
Xextern int num_object;
Xchar *from = NULL, *to = NULL;
XFILE *tfp = NULL;
Xchar Err_incomp[] = "Incomplete %s object at line %d.";
Xchar Err_mem[] = "Running out of memory.";
Xdouble scale = 1.0;
Xdouble scalex, scaley;
Xint coord_system;
Xint ppi;
Xint llx, lly, urx, ury;
X
Xint fill_type[NUMFILLPATS] = {4, 3, 4, 3, 4, 3, 4, 3, 4, 3,
X 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 1};
Xint fill_spacing[NUMFILLPATS] = {8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6,
X 4, 4, 4, 4, 4, 4, 2, 2, 0};
Xint fill_angle[NUMFILLPATS] = {0, 0, 45, 45, 90, 90, 0, 0, 45, 45,
X 90, 90, 0, 0, 45, 45, 90, 90, 0, 0, 0};
Xint line_thickness; /* not needed for f2ps, arrow.c needs it for fig */
X
Xget_args(argc, argv)
Xint argc;
Xchar *argv[];
X{
X char *a;
X int first = 1;
X
X prog = *argv;
X while (--argc) {
X a = *++argv;
X if (*a == '-') {
X if (*++a == 'l' || *a == 'L') { /* Landscape */
X landscape = 1;
X }
X else if (*a == 'p' || *a == 'P') { /* Portrait */
X landscape = 0;
X }
X else if (*a == 'd') /* debug printing */
X debug = 1;
X else if (*a == 'e') { /* Enlarging factor followed */
X if (--argc)
X scale = atof(*++argv);
X else
X goto error_exit;
X }
X else
X goto error_exit;
X }
X else if (first) {
X from = a; /* from file */
X first = 0;
X }
X else if (first == 0) {
X to = a; /* to file */
X first = -1;
X }
X else
X goto error_exit;
X }
X return;
X
X error_exit:
X fprintf(stderr, Usage, prog);
X exit(1);
X }
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X F_compound objects;
X int status;
X
X get_args(argc, argv);
X
X if (to == NULL)
X tfp = stdout;
X else if ((tfp = fopen(to, "w")) == NULL) {
X fprintf(stderr, "%s: Couldn't open %s", prog, to);
X fprintf(stderr, Usage, prog);
X exit(1);
X }
X
X if (from)
X status = read_fig(from, &objects);
X else /* read from stdin */
X status = readfp_fig(stdin, &objects);
X
X if (status != 0) {
X if (from) read_fail_message(from, status);
X fprintf(stderr,"\n");
X exit(1);
X }
X genhp_objects(&objects);
X if (tfp != stdout)
X (void)fclose(tfp);
X exit(0);
X }
X
Xprolog(objects)
XF_compound *objects;
X {
X plotter_on();
X fprintf(tfp, "\033.I80;;17:"); /* set x-on/x-off */
X fprintf(tfp, "\033.N;19:");
X /* **** rotate for portrait mode **** */
X if (!landscape) /* must reset clip window and plotter limits with rotaton */
X fprintf(tfp, "RO 90;IW;IP;\n");
X fprintf(tfp, "SC %d %d %d %d;\n", llx, urx, lly, ury);
X }
X
Xepilog()
X {
X penup();
X fprintf(tfp,"PA %d %d; ",urx,ury);
X fprintf(tfp, "SP;\n");
X plotter_off();
X }
X
Xplotter_on()
X {
X fprintf(tfp,"\033.(\n");
X }
X
Xplotter_off()
X {
X fprintf(tfp,"\033.)\n");
X }
X
Xgenhp_objects(objects)
XF_compound *objects;
X{
X F_arc *a;
X F_compound *c;
X F_ellipse *e;
X F_line *l;
X F_spline *s;
X F_text *t;
X int itmp;
X int color;
X
X /* Compute bounding box of objects */
X compound_bound(objects, &llx, &lly, &urx, &ury);
X if (llx > urx) {
X fprintf(stderr, "%s: No object",prog);
X return;
X }
X
X ppi = objects->nwcorner.x; /* ppi */
X coord_system = objects->nwcorner.y; /* 1=y normal, 2=y flipped */
X
X scalex = scaley = scale; /* user enlarging factor */
X
X /*************************************************************************/
X /* we will just set llx lly etc to plotter area */
X /*************************************************************************/
X
X llx = lly = 0; /* lower left */
X urx = PAGE_WIDTH*ppi;
X ury = PAGE_HEIGHT*ppi;
X
X if (!landscape) /* swap x,y */
X {
X itmp = llx; llx = lly; lly = itmp;
X itmp = urx; urx = ury; ury = itmp;
X }
X
X prolog(objects);
X
X /* plot color 0 first then 1, ... */
X for (color=-1; color < MAX_COLORS; color++)
X {
X for (a = objects->arcs; a != NULL; a = a->next)
X genhp_arc(a,color);
X for (c = objects->compounds; c != NULL; c = c->next)
X genhp_compound(c,color);
X for (e = objects->ellipses; e != NULL; e = e->next)
X genhp_ellipse(e,color);
X for (l = objects->lines; l != NULL; l = l->next)
X genhp_line(l,color);
X for (s = objects->splines; s != NULL; s = s->next)
X genhp_spline(s,color);
X for (t = objects->texts; t != NULL; t = t->next)
X genhp_text(t,color);
X }
X epilog();
X }
X
Xset_style(s, v)
Xint s;
Xdouble v;
X{
X if (s == DASH_LINE) {
X if (v > 0.0) fprintf(tfp, "LT 2;\n");
X }
X else if (s == DOTTED_LINE) {
X if (v > 0.0) fprintf(tfp, "LT 1;\n");
X }
X }
X
Xreset_style(s, v)
Xint s;
Xdouble v;
X{
X if (s == DASH_LINE) {
X if (v > 0.0) fprintf(tfp, "LT;\n");
X }
X else if (s == DOTTED_LINE) {
X if (v > 0.0) fprintf(tfp, "LT;\n");
X }
X }
X
Xset_areafill(a)
Xint a;
X {
X if (cur_areafill == a)
X return;
X cur_areafill = a;
X fprintf(tfp, "FT %d %d %d;\n",
X fill_type[a-1],fill_spacing[a-1],fill_angle[a-1]);
X }
X
Xset_linewidth(w)
Xint w;
X {
X cur_thickness = w;
X }
X
Xset_color(c)
Xint c;
X {
X if (c < 0)
X c = DEFAULT_COLOR;
X if (cur_color == c)
X return;
X cur_color = c;
X fprintf(tfp,"SP %d;\n",c+1);
X }
X
Xmoveto(x,y)
Xint x,y;
X {
X penup();
X fprintf(tfp,"PA %.2f %.2f;\n",TRANSF_X(x),TRANSF_Y(y));
X }
X
Xdrawto(x,y)
Xint x,y;
X {
X pendown();
X fprintf(tfp,"PA %.2f %.2f;\n",TRANSF_X(x),TRANSF_Y(y));
X }
X
Xf_moveto(x,y)
Xdouble x,y;
X {
X penup();
X fprintf(tfp,"PA %.2lf %.2lf;\n",TRANSF_X(x),TRANSF_Y(y));
X }
X
Xf_drawto(x,y)
Xdouble x,y;
X {
X pendown();
X fprintf(tfp,"PA %.2lf %.2lf;\n",TRANSF_X(x),TRANSF_Y(y));
X }
X
Xpenup()
X {
X if (pen != UP)
X fprintf(tfp,"PU; ");
X pen = UP;
X }
X
Xpendown()
X {
X if (pen != DOWN)
X fprintf(tfp,"PD; ");
X pen = DOWN;
X }
X
Xgenhp_compound(com,color)
XF_compound *com;
Xint color;
X{
X F_arc *a;
X F_compound *c;
X F_ellipse *e;
X F_line *l;
X F_spline *s;
X F_text *t;
X
X for (a = com->arcs; a != NULL; a = a->next)
X genhp_arc(a,color);
X for (c = com->compounds; c != NULL; c = c->next)
X genhp_compound(c,color);
X for (e = com->ellipses; e != NULL; e = e->next)
X genhp_ellipse(e,color);
X for (l = com->lines; l != NULL; l = l->next)
X genhp_line(l,color);
X for (s = com->splines; s != NULL; s = s->next)
X genhp_spline(s,color);
X for (t = com->texts; t != NULL; t = t->next)
X genhp_text(t,color);
X }
X
X#define FILL_RECT(x,y) fprintf(tfp,"RA %.2f %.2f; ",TRANSF_X((x)),TRANSF_Y((y)))
X#define EDGE_RECT(x,y) fprintf(tfp,"EA %.2f %.2f; ",TRANSF_X((x)),TRANSF_Y((y)))
X#define FILL_WEDGE(r,angle,sweep) fprintf(tfp,"WG %.2f %d %d; ", \
X TRANSF_X(r),(angle),(sweep))
X#define ARC_TO(x,y,angle) fprintf(tfp,"AA %.2f %.2f %d; ", \
X TRANSF_X((x)),TRANSF_Y((y)),(angle))
X#define F_FILL_WEDGE(r,angle,sweep) fprintf(tfp,"WG %.2lf %d %d; ", \
X TRANSF_X(r),(angle),(sweep))
X#define F_ARC_TO(x,y,angle) fprintf(tfp,"AA %.2lf %.2lf %d; ", \
X TRANSF_X((x)),TRANSF_Y((y)),(angle))
X#define CIRCLE(r) fprintf(tfp,"CI %.2f;",TRANSF_X(r))
X
Xgenhp_line(l,color)
XF_line *l;
Xint color;
X {
X F_point *p, *q;
X int radius,tmp;
X int xmin,xmax,ymin,ymax;
X
X if (color != l->color)
X return;
X
X set_linewidth(l->thickness);
X set_color(l->color);
X radius = l->radius; /* radius of rounded-corner boxes */
X p = l->points;
X q = p->next;
X if (q == NULL) { /* A single point line */
X if (l->thickness > 0)
X {
X moveto(p->x,p->y);
X pendown();
X penup();
X }
X return;
X }
X if (l->back_arrow)
X draw_arrow_head((double)q->x, (double)q->y, (double)p->x,
X (double)p->y, l->back_arrow->ht, l->back_arrow->wid);
X set_style(l->style, l->style_val);
X if (l->area_fill)
X set_areafill(l->area_fill);
X xmin = xmax = p->x;
X ymin = ymax = p->y;
X
X while ((l->type == T_BOX || l->type == T_ARC_BOX) &&
X p->next != NULL) /* find lower left and upper right corners */
X {
X p=p->next;
X if (xmin > p->x)
X xmin = p->x;
X else if (xmax < p->x)
X xmax = p->x;
X if (ymin > p->y)
X ymin = p->y;
X else if (ymax < p->y)
X ymax = p->y;
X }
X if (l->type == T_ARC_BOX) /* rounded-corner box */
X {
X if (l->area_fill)
X {
X moveto(xmin+radius,ymin);
X FILL_RECT(xmax-radius,ymin+radius);
X moveto(xmin,ymin+radius);
X FILL_RECT(xmax,ymax-radius);
X moveto(xmin+radius,ymax-radius);
X FILL_RECT(xmax-radius,ymax);
X
X /* now do the corner wedges */
X moveto(xmin+radius,ymin+radius);
X FILL_WEDGE(radius,90,90);
X moveto(xmin+radius,ymax-radius);
X FILL_WEDGE(radius,180,90);
X moveto(xmax-radius,ymax-radius);
X FILL_WEDGE(radius,270,90);
X moveto(xmax-radius,ymin+radius);
X FILL_WEDGE(radius,0,90);
X }
X /* draw the outline of the box */
X moveto(xmin+radius,ymin);
X pendown();
X ARC_TO(xmin+radius,ymin+radius,90);
X drawto(xmin,ymax-radius);
X ARC_TO(xmin+radius,ymax-radius,90);
X drawto(xmax-radius,ymax);
X ARC_TO(xmax-radius,ymax-radius,90);
X drawto(xmax,ymin+radius);
X ARC_TO(xmax-radius,ymin+radius,90);
X drawto(xmin+radius,ymin);
X } /* T_ARC_BOX */
X else if (l->type == T_BOX)
X {
X moveto(xmin,ymin);
X if (l->area_fill)
X FILL_RECT(xmax,ymax);
X EDGE_RECT(xmax,ymax);
X }
X else /* POLYGON or POLYLINE */
X {
X moveto(p->x, p->y);
X while (q->next != NULL)
X {
X p = q;
X q = q->next;
X drawto(p->x, p->y);
X }
X drawto(q->x, q->y);
X }
X penup();
X
X reset_style(l->style, l->style_val);
X if (l->for_arrow && l->thickness > 0)
X draw_arrow_head((double)p->x, (double)p->y, (double)q->x,
X (double)q->y, l->for_arrow->ht, l->for_arrow->wid);
X }
X
Xgenhp_spline(s,color)
XF_spline *s;
Xint color;
X{
X if (color != s->color)
X return;
X
X set_color(s->color);
X#ifndef notdef
X fprintf(stderr,"No spline yet\n");
X#else
X if (int_spline(s))
X genhp_itp_spline(s);
X else
X genhp_ctl_spline(s);
X#endif
X }
X
Xgenhp_itp_spline(s)
XF_spline *s;
X{
X F_point *p, *q;
X F_control *a, *b;
X
X set_linewidth(s->thickness);
X a = s->controls;
X b = a->next;
X p = s->points;
X if (s->back_arrow && s->thickness > 0)
X draw_arrow_head(b->lx, b->ly, (double)p->x,
X (double)p->y, s->back_arrow->ht, s->back_arrow->wid);
X
X set_style(s->style, s->style_val);
X fprintf(tfp, "%% Interpolated spline\n");
X fprintf(tfp, "newpath %d %d moveto\n", p->x, p->y);
X for (q = p->next; q != NULL; p = q, q = q->next) {
X b = a->next;
X fprintf(tfp, "\t%.3f %.3f %.3f %.3f %d %d curveto\n",
X a->rx, a->ry, b->lx, b->ly, q->x, q->y);
X a = b;
X }
X if (closed_spline(s))
X {
X fprintf(tfp, " closepath ");
X if (s->area_fill)
X {
X set_areafill(s->area_fill);
X fprintf(tfp, " gsave fill grestore ");
X set_areafill(NUMFILLPATS); /* back to black for line */
X }
X }
X if (s->thickness > 0)
X fprintf(tfp, " stroke\n");
X reset_style(s->style, s->style_val);
X
X if (s->for_arrow && s->thickness > 0)
X draw_arrow_head(a->lx, a->ly, (double)p->x,
X (double)p->y, s->for_arrow->ht, s->for_arrow->wid);
X }
X
Xgenhp_ctl_spline(s)
XF_spline *s;
X{
X double a, b, c, d, x1, y1, x2, y2, x3, y3;
X F_point *p, *q;
X
X p = s->points;
X x1 = p->x; y1 = p->y;
X p = p->next;
X c = p->x; d = p->y;
X set_linewidth(s->thickness);
X x3 = a = (x1 + c) / 2;
X y3 = b = (y1 + d) / 2;
X if (s->back_arrow && s->thickness > 0) {
X draw_arrow_head(c, d, x1, y1, s->back_arrow->ht, s->back_arrow->wid);
X }
X set_style(s->style, s->style_val);
X if (! closed_spline(s)) {
X fprintf(tfp, "%% Open spline\n");
X fprintf(tfp, "newpath %.3f %.3f moveto %.3f %.3f lineto\n",
X x1, y1, x3, y3);
X }
X else {
X fprintf(tfp, "%% Closed spline\n");
X fprintf(tfp, "newpath %.3f %.3f moveto\n", a, b);
X }
X for (q = p->next; q != NULL; q = q->next) {
X x1 = x3; y1 = y3;
X x2 = c; y2 = d;
X c = q->x; d = q->y;
X x3 = (x2 + c) / 2;
X y3 = (y2 + d) / 2;
X fprintf(tfp, "\t%.3f %.3f %.3f %.3f %.3f %.3f DrawSplineSection\n",
X x1, y1, x2, y2, x3, y3);
X }
X /*
X * At this point, (x2,y2) and (c,d) are the position of the
X * next-to-last and last point respectively, in the point list
X */
X if (closed_spline(s)) {
X fprintf(tfp, "\t%.3f %.3f %.3f %.3f %.3f %.3f DrawSplineSection closepath ",
X x3, y3, c, d, a, b);
X if (s->area_fill)
X {
X set_areafill(s->area_fill);
X fprintf(tfp, " gsave fill grestore\n");
X set_areafill(NUMFILLPATS); /* back to black for line */
X }
X if (s->thickness > 0)
X fprintf(tfp, " stroke\n");
X }
X else {
X if (s->thickness > 0)
X fprintf(tfp, "\t%.3f %.3f lineto stroke\n", c, d);
X else
X fprintf(tfp, "\t%.3f %.3f lineto\n", c, d);
X }
X reset_style(s->style, s->style_val);
X if (s->for_arrow && s->thickness > 0)
X {
X draw_arrow_head(x2, y2, c, d, s->for_arrow->ht,
X s->for_arrow->wid);
X }
X }
X
Xgenhp_ellipse(e,color)
XF_ellipse *e;
Xint color;
X {
X int rx,ry,cx,cy;
X double x,y;
X int npts;
X double theta,inc;
X
X if (color != e->color)
X return;
X
X set_linewidth(e->thickness);
X set_color(e->color);
X set_style(e->style, e->style_val);
X if (e->area_fill)
X set_areafill(e->area_fill);
X rx = e->radiuses.x;
X ry = e->radiuses.y;
X cx = e->center.x;
X cy = e->center.y;
X if (rx == ry)
X { /* CIRCLE */
X moveto(cx, cy);
X if (e->area_fill)
X FILL_WEDGE(rx, 0, 360);
X /* outline the circle */
X CIRCLE(rx);
X }
X else /* ellipse */
X {
X npts = (rx+ry)*2; /* pick some number of points proportional
X to the size of the ellipse to plot */
X inc = 2.0*M_PI/npts;
X moveto(cx+rx,cy);
X for (theta = 0.0; theta <= 2*M_PI; theta += inc)
X {
X x = cx + rx*cos(theta);
X y = cy + ry*sin(theta);
X f_drawto(x,y);
X }
X drawto(cx+rx, cy);
X }
X penup();
X reset_style(e->style, e->style_val);
X }
X
X
X#define IS_ITALICS(f) ((f)&1)
X
Xgenhp_text(t,color)
XF_text *t;
Xint color;
X {
X double height;
X int len;
X
X if (color != t->color)
X return;
X
X set_color(t->color);
X height = (double) t->size/POINT_PER_INCH*2.54; /* height in cm */
X
X height = height*scale;
X height = height/1.5; /* kludge for now */
X fprintf(tfp,"SI %.2lf %.2lf;",height/2.54,height);
X len = strlen(t->cstring);
X if (IS_ITALICS(t->font)) /* slant for Italics font */
X fprintf(tfp,"SL %.2f;",tan((double)30.0*M_PI/180.0)); /* 30 degrees */
X moveto(t->base_x,t->base_y);
X if (t->type == T_RIGHT_JUSTIFIED)
X fprintf(tfp,"CP %d 0; ",-len);
X else if (t->type == T_CENTER_JUSTIFIED)
X fprintf(tfp,"CP %.1f 0; ",-len/2.0);
X fprintf(tfp,"LB%s\003;\n",t->cstring);
X if (IS_ITALICS(t->font))
X fprintf(tfp,"SL;");
X }
X
Xgenhp_arc(a,color)
XF_arc *a;
Xint color;
X{
X double angle1, angle2, dx, dy, radius, x, y;
X double cx, cy, sx, sy, ex, ey;
X int sweep;
X int direction;
X
X if (color != a->color)
X return;
X
X cx = a->center.x; cy = a->center.y;
X sx = a->point[0].x; sy = a->point[0].y;
X ex = a->point[2].x; ey = a->point[2].y;
X
X if (coord_system == 2)
X direction = !a->direction;
X else
X direction = a->direction;
X set_linewidth(a->thickness);
X set_color(a->color);
X if (a->for_arrow && a->thickness > 0) {
X arc_tangent(cx, cy, ex, ey, direction, &x, &y);
X draw_arrow_head(x, y, ex, ey, a->for_arrow->ht, a->for_arrow->wid);
X }
X if (a->back_arrow && a->thickness > 0) {
X arc_tangent(cx, cy, sx, sy, !direction, &x, &y);
X draw_arrow_head(x, y, sx, sy, a->back_arrow->ht, a->back_arrow->wid);
X }
X dx = cx - sx;
X dy = cy - sy;
X radius = sqrt(dx*dx + dy*dy);
X angle1 = atan2(sy-cy, sx-cx) * 180 / M_PI;
X angle2 = atan2(ey-cy, ex-cx) * 180 / M_PI;
X /* make the angles go from 0 to 2PI */
X if (angle1 < 0.0)
X angle1 += 360.0;
X if (angle2 < 0.0)
X angle2 += 360.0;
X /* direction 1 -> Counter-Clockwise */
X if (direction == 1) /* ccw */
X {
X if (angle1 > angle2)
X sweep = 360.0 - angle1 + angle2;
X else
X sweep = angle2 - angle1;
X }
X else /* cw */
X {
X if (angle1 > angle2)
X sweep = - (angle1 - angle2);
X else
X sweep = - (360.0 - angle2 + angle1);
X }
X if (debug)
X fprintf(stderr,"#%d: dir=%s, a1 = %.1f, a2 = %.1f, sweep = %d\n",
X a->thickness,direction==0?"cw ":"ccw",cx,cy,angle1,angle2,sweep);
X set_style(a->style, a->style_val);
X if (a->area_fill)
X {
X set_areafill(a->area_fill);
X f_moveto(cx,cy);
X F_FILL_WEDGE(radius,(int)angle1,sweep);
X }
X f_moveto(ex,ey);
X pendown();
X F_ARC_TO(cx,cy,sweep);
X penup();
X
X reset_style(a->style, a->style_val);
X }
X
Xarc_tangent(x1, y1, x2, y2, direction, x, y)
Xdouble x1, y1, x2, y2, *x, *y;
Xint direction;
X{
X if (direction) { /* counter clockwise */
X *x = x2 + (y2 - y1);
X *y = y2 - (x2 - x1);
X }
X else {
X *x = x2 - (y2 - y1);
X *y = y2 + (x2 - x1);
X }
X }
X
X/* draw arrow heading from (x1, y1) to (x2, y2) */
X
Xdraw_arrow_head(x1, y1, x2, y2, arrowht, arrowwid)
Xdouble x1, y1, x2, y2, arrowht, arrowwid;
X{
X double x, y, xb, yb, dx, dy, l, sina, cosa;
X double xc, yc, xd, yd;
X
X dx = x2 - x1; dy = y1 - y2;
X l = sqrt((double)(dx*dx + dy*dy)); /* length of line */
X sina = dy / l; cosa = dx / l;
X xb = x2*cosa - y2*sina;
X yb = x2*sina + y2*cosa;
X x = xb - arrowht;
X y = yb - arrowwid / 2;
X xc = x*cosa + y*sina; /* one tail of arrow */
X yc = -x*sina + y*cosa;
X y = yb + arrowwid / 2;
X xd = x*cosa + y*sina; /* other tail of arrow */
X yd = -x*sina + y*cosa;
X f_moveto(xc,yc);
X f_drawto(x2,y2);
X f_drawto(xd,yd);
X penup();
X }
X
Xellipse_exist(ob)
XF_compound *ob;
X{
X F_compound *c;
X
X if (NULL != ob->ellipses) return(1);
X
X for (c = ob->compounds; c != NULL; c = c->next) {
X if (ellipse_exist(c)) return(1);
X }
X
X return(0);
X }
X
Xnormal_spline_exist(ob)
XF_compound *ob;
X{
X F_spline *s;
X F_compound *c;
X
X for (s = ob->splines; s != NULL; s = s->next) {
X if (normal_spline(s)) return(1);
X }
X
X for (c = ob->compounds; c != NULL; c = c->next) {
X if (normal_spline_exist(c)) return(1);
X }
X
X return(0);
X }
X
X/*VARARGS1*/
Xput_msg(format, arg1, arg2, arg3, arg4, arg5)
X char *format;
X int arg1, arg2, arg3, arg4, arg5;
X{
X fprintf(stderr, format, arg1, arg2, arg3, arg4, arg5);
X}
END_OF_FILE
if test 18027 -ne `wc -c <'f2hp.c'`; then
echo shar: \"'f2hp.c'\" unpacked with wrong size!
fi
# end of 'f2hp.c'
fi
if test -f 'movept.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'movept.c'\"
else
echo shar: Extracting \"'movept.c'\" \(17045 characters\)
sed "s/^X//" >'movept.c' <<'END_OF_FILE'
X/*
X * FIG : Facility for Interactive Generation of figures
X *
X * Copyright (c) 1985 by Supoj Sutanthavibul (supoj at sally.UTEXAS.EDU)
X * January 1985.
X * 1st revision : Aug 1985.
X *
X * %W% %G%
X*/
X#include "fig.h"
X#include "resources.h"
X#include "func.h"
X#include "object.h"
X#include "paintop.h"
X
X#define TOLERANCE 3
Xextern int latexline_mode, latexarrow_mode;
Xextern int magnet_mode;
X
Xextern (*canvas_kbd_proc)();
Xextern (*canvas_locmove_proc)();
Xextern (*canvas_leftbut_proc)();
Xextern (*canvas_middlebut_proc)();
Xextern (*canvas_rightbut_proc)();
Xextern null_proc();
Xextern set_popupmenu();
XF_line *line_point_search();
XF_spline *spline_point_search();
XF_ellipse *ellipse_point_search();
XF_arc *arc_point_search();
X
Xextern F_compound objects;
X
Xextern F_point *moved_point, *left_point;
Xextern F_pos last_position, new_position;
Xextern int movedpoint_num;
Xextern int last_object;
Xextern int fix_x, fix_y, cur_x, cur_y;
Xextern int pointmarker_shown;
Xextern int foreground_color, background_color;
X
Xextern elastic_box(), move_ebrbox(), move_ebdbox();
Xextern move_cbrbox(), move_cbdbox();
X
Xextern int init_move_point();
Xextern int move_linepoint(), fix_movedlinepoint();
Xextern int move_latexlinepoint(), fix_movedlatexlinepoint();
Xextern int fix_box();
Xextern int fix_movedsplinepoint();
Xextern int move_arcpoint(), fix_movedarcpoint();
Xextern int fix_movedellipsepoint();
X
Xstatic F_line *line;
Xstatic F_spline *spline;
Xstatic F_ellipse *ellipse;
Xstatic F_arc *arc;
X
Xstatic int latex_fix_x, latex_fix_y;
XCURSOR cur_latexcursor;
XBoolean init_ellipsepointmoving();
X
Xmove_point_selected()
X{
X canvas_kbd_proc = null_proc;
X canvas_locmove_proc = null_proc;
X canvas_leftbut_proc = init_move_point;
X canvas_middlebut_proc = null_proc;
X canvas_rightbut_proc = set_popupmenu;
X set_cursor(&pick9_cursor);
X reset_action_on();
X }
X
Xinit_move_point(x, y)
Xint x, y;
X{
X Boolean Ok=True;
X
X if ((line = line_point_search(x, y, TOLERANCE,
X &left_point, &moved_point)) != NULL) {
X init_linepointmoving(line);
X }
X else if ((spline = spline_point_search(x, y,
X TOLERANCE, &left_point, &moved_point)) != NULL){
X init_splinepointmoving(spline);
X }
X else if ((ellipse = ellipse_point_search(x, y, TOLERANCE,
X &movedpoint_num)) != NULL) {
X if (!init_ellipsepointmoving(ellipse)) /* selected center, ignore */
X Ok=False;
X }
X else if ((arc = arc_point_search(x, y, TOLERANCE,
X &movedpoint_num)) != NULL) {
X init_arcpointmoving(arc);
X }
X else {
X return;
X }
X if (Ok) /* movepoint went ok */
X {
X canvas_leftbut_proc = canvas_rightbut_proc = null_proc;
X erase_pointmarker();
X }
X }
X
Xwrapup_movepoint()
X{
X show_pointmarker();
X move_point_selected();
X }
X
X/************************* ellipse *******************************/
X
XF_ellipse *
Xellipse_point_search(x, y, tol, point_num)
Xint x, y, tol, *point_num;
X{
X F_ellipse *e;
X
X for (e = objects.ellipses; e != NULL; e = e->next) {
X if (abs(e->start.x - x) <= tol && abs(e->start.y - y) <= tol) {
X *point_num = 0;
X return(e);
X }
X if (abs(e->end.x - x) <= tol && abs(e->end.y - y) <= tol) {
X *point_num = 1;
X return(e);
X }
X }
X return(NULL);
X }
X
Xstatic F_ellipse *cur_e;
X
XBoolean
Xinit_ellipsepointmoving(ellipse)
XF_ellipse *ellipse;
X{
X if (movedpoint_num == 0) { /* center point is selected - disallow */
X if (ellipse->type == T_ELLIPSE_BY_RAD ||
X ellipse->type == T_CIRCLE_BY_RAD) {
X return False; /* don't erase point_marker etc */
X }
X last_position.x = cur_x = ellipse->start.x;
X last_position.y = cur_y = ellipse->start.y;
X fix_x = ellipse->end.x; fix_y = ellipse->end.y;
X switch (ellipse->type) {
X case T_ELLIPSE_BY_DIA :
X canvas_locmove_proc = move_ebdbox;
X ellipsebydia_box(INV_PAINT);
X break;
X case T_CIRCLE_BY_DIA :
X canvas_locmove_proc = move_cbdbox;
X circlebydia_box(INV_PAINT);
X break;
X }
X }
X else {
X last_position.x = cur_x = ellipse->end.x;
X last_position.y = cur_y = ellipse->end.y;
X fix_x = ellipse->start.x; fix_y = ellipse->start.y;
X switch (ellipse->type) {
X case T_ELLIPSE_BY_RAD :
X canvas_locmove_proc = move_ebrbox;
X ellipsebyrad_box(INV_PAINT);
X break;
X case T_CIRCLE_BY_RAD :
X canvas_locmove_proc = move_cbrbox;
X circlebyrad_box(INV_PAINT);
X break;
X case T_ELLIPSE_BY_DIA :
X canvas_locmove_proc = move_ebdbox;
X ellipsebydia_box(INV_PAINT);
X break;
X case T_CIRCLE_BY_DIA :
X canvas_locmove_proc = move_cbdbox;
X circlebydia_box(INV_PAINT);
X break;
X }
X }
X cur_e = ellipse;
X set_temp_cursor(&crosshair_cursor);
X win_setmouseposition(canvas_win, cur_x, cur_y);
X canvas_middlebut_proc = fix_movedellipsepoint;
X canvas_leftbut_proc = null_proc;
X return True; /* all is Ok */
X }
X
Xfix_movedellipsepoint(x, y)
Xint x, y;
X{
X switch (cur_e->type) {
X case T_ELLIPSE_BY_RAD :
X ellipsebyrad_box(INV_PAINT);
X break;
X case T_CIRCLE_BY_RAD :
X circlebyrad_box(INV_PAINT);
X break;
X case T_ELLIPSE_BY_DIA :
X ellipsebydia_box(INV_PAINT);
X break;
X case T_CIRCLE_BY_DIA :
X circlebydia_box(INV_PAINT);
X break;
X }
X new_position.x = x;
X new_position.y = y;
X clean_up();
X set_action_object(F_MOVE_POINT, O_ELLIPSE);
X set_latestellipse(cur_e);
X relocate_ellipsepoint(cur_e, x, y, movedpoint_num);
X wrapup_movepoint();
X }
X
Xrelocate_ellipsepoint(ellipse, x, y, point_num)
XF_ellipse *ellipse;
Xint x, y, point_num;
X{
X int dx, dy;
X
X set_temp_cursor(&wait_cursor);
X if (pointmarker_shown) toggle_ellipsepointmarker(ellipse);
X draw_ellipse(ellipse, background_color);
X if (point_num == 0) { /* starting point is selected */
X fix_x = ellipse->end.x; fix_y = ellipse->end.y;
X ellipse->start.x = x; ellipse->start.y = y;
X }
X else {
X fix_x = ellipse->start.x; fix_y = ellipse->start.y;
X ellipse->end.x = x; ellipse->end.y = y;
X }
X switch (ellipse->type) {
X case T_ELLIPSE_BY_RAD :
X ellipse->radiuses.x = abs(x - fix_x) + 1;
X ellipse->radiuses.y = abs(y - fix_y) + 1;
X break;
X case T_CIRCLE_BY_RAD :
X dx = fix_x - x; dy = fix_y - y;
X ellipse->radiuses.x = sqrt((double)(dx*dx + dy*dy)) + .5;
X ellipse->radiuses.y = ellipse->radiuses.x;
X break;
X case T_ELLIPSE_BY_DIA :
X ellipse->center.x = (fix_x + x) / 2;
X ellipse->center.y = (fix_y + y) / 2;
X ellipse->radiuses.x = abs(ellipse->center.x - fix_x);
X ellipse->radiuses.y = abs(ellipse->center.y - fix_y);
X break;
X case T_CIRCLE_BY_DIA :
X dx = ellipse->center.x = (fix_x + x) / 2 +.5;
X dy = ellipse->center.y = (fix_y + y) / 2 +.5;
X dx -= x; dy -= y;
X ellipse->radiuses.x = sqrt((double)(dx*dx + dy*dy)) + .5;
X ellipse->radiuses.y = ellipse->radiuses.x;
X break;
X }
X draw_ellipse(ellipse, foreground_color);
X if (pointmarker_shown) toggle_ellipsepointmarker(ellipse);
X reset_cursor();
X set_modifiedflag();
X }
X
X/*************************** arc *********************************/
X
Xstatic F_arc *cur_a;
X
XF_arc *
Xarc_point_search(x, y, tol, point_num)
Xint x, y, tol, *point_num;
X{
X F_arc *a;
X int i;
X
X for(a = objects.arcs; a != NULL; a = a->next) {
X for (i = 0; i < 3; i++) {
X if (abs(a->point[i].x - x) <= tol &&
X abs(a->point[i].y - y) <= tol) {
X *point_num = i;
X return(a);
X }
X }
X }
X return(NULL);
X }
X
Xinit_arcpointmoving(arc)
XF_arc *arc;
X{
X cur_a = arc;
X last_position.x = cur_x = arc->point[movedpoint_num].x;
X last_position.y = cur_y = arc->point[movedpoint_num].y;
X set_temp_cursor(&crosshair_cursor);
X win_setmouseposition(canvas_win, cur_x, cur_y);
X draw_arclink(INV_PAINT);
X canvas_locmove_proc = move_arcpoint;
X canvas_middlebut_proc = fix_movedarcpoint;
X canvas_leftbut_proc = null_proc;
X }
X
Xmove_arcpoint(x, y)
Xint x, y;
X{
X draw_arclink(INV_PAINT);
X cur_x = x; cur_y = y;
X draw_arclink(INV_PAINT);
X }
X
Xdraw_arclink(op)
Xint op;
X{
X switch (movedpoint_num) {
X case 0 :
X pw_vector(canvas_win, cur_x, cur_y,
X arc->point[1].x, arc->point[1].y, op, 1, SOLID_LINE, 0.0);
X break;
X case 1 :
X pw_vector(canvas_win, arc->point[0].x, arc->point[0].y,
X cur_x, cur_y, op, 1, SOLID_LINE, 0.0);
X pw_vector(canvas_win, arc->point[2].x, arc->point[2].y,
X cur_x, cur_y, op, 1, SOLID_LINE, 0.0);
X break;
X default :
X pw_vector(canvas_win, arc->point[2].x, arc->point[2].y,
X cur_x, cur_y, op, 1, SOLID_LINE, 0.0);
X }
X }
X
Xfix_movedarcpoint(x, y)
Xint x, y;
X{
X draw_arclink(INV_PAINT);
X new_position.x = x;
X new_position.y = y;
X clean_up();
X set_action_object(F_MOVE_POINT, O_ARC);
X set_latestarc(cur_a);
X relocate_arcpoint(cur_a, x, y, movedpoint_num);
X wrapup_movepoint();
X }
X
Xrelocate_arcpoint(arc, x, y, movedpoint_num)
XF_arc *arc;
Xint x, y, movedpoint_num;
X{
X float xx, yy;
X F_pos p[3];
X
X p[0] = arc->point[0];
X p[1] = arc->point[1];
X p[2] = arc->point[2];
X p[movedpoint_num].x = x;
X p[movedpoint_num].y = y;
X if (compute_arccenter(p[0], p[1], p[2], &xx, &yy)) {
X set_temp_cursor(&wait_cursor);
X if (pointmarker_shown) toggle_arcpointmarker(arc);
X draw_arc(arc, background_color); /* erase old arc */
X arc->point[movedpoint_num].x = x;
X arc->point[movedpoint_num].y = y;
X arc->center.x = xx;
X arc->center.y = yy;
X arc->direction = compute_direction(p[0], p[1], p[2]);
X draw_arc(arc, foreground_color); /* draw new arc */
X if (pointmarker_shown) toggle_arcpointmarker(arc);
X reset_cursor();
X set_modifiedflag();
X }
X }
X
X/************************** spline *******************************/
X
Xstatic F_spline *cur_s;
X
Xinit_splinepointmoving(s)
XF_spline *s;
X{
X F_point *p;
X
X cur_s = s;
X last_position.x = cur_x = moved_point->x;
X last_position.y = cur_y = moved_point->y;
X set_temp_cursor(&crosshair_cursor);
X win_setmouseposition(canvas_win, cur_x, cur_y);
X if (closed_spline(s) && left_point == NULL) {
X for (left_point = moved_point->next,
X p = left_point->next;
X p->next != NULL;
X left_point = p, p = p->next);
X }
X draw_pointlink(INV_PAINT);
X canvas_locmove_proc = move_linepoint;
X canvas_middlebut_proc = fix_movedsplinepoint;
X canvas_leftbut_proc = null_proc;
X }
X
XF_spline *
Xspline_point_search(x, y, tol, p, q)
Xint x, y, tol;
XF_point **p, **q;
X{
X F_spline *s;
X
X for (s = objects.splines; s != NULL; s= s->next) {
X *p = NULL;
X for (*q = s->points; *q != NULL; *p = *q, *q = (*q)->next) {
X if (abs((*q)->x - x) <= tol && abs((*q)->y - y) <= tol)
X return(s);
X }
X }
X return(NULL);
X }
X
Xfix_movedsplinepoint(x, y)
Xint x, y;
X{
X draw_pointlink(INV_PAINT);
X new_position.x = x;
X new_position.y = y;
X clean_up();
X set_action_object(F_MOVE_POINT, O_SPLINE);
X set_latestspline(cur_s);
X relocate_splinepoint(cur_s, x, y, moved_point);
X wrapup_movepoint();
X }
X
Xrelocate_splinepoint(s, x, y, moved_point)
XF_spline *s;
Xint x, y;
XF_point *moved_point;
X{
X set_temp_cursor(&wait_cursor);
X if (pointmarker_shown) toggle_splinepointmarker(s);
X draw_spline(s, ERASE); /* erase old spline */
X moved_point->x = x;
X moved_point->y = y;
X if (closed_spline(s)) {
X left_point->next->x = x;
X left_point->next->y = y;
X }
X if (int_spline(s)) remake_control_points(s);
X draw_spline(s, PAINT); /* draw spline with moved point */
X if (pointmarker_shown) toggle_splinepointmarker(s);
X reset_cursor();
X set_modifiedflag();
X }
X
X/*************************** line ********************************/
X
Xstatic F_line *cur_l;
X
Xinit_linepointmoving(line)
XF_line *line;
X{
X int box_case;
X int latex_case;
X F_point *p;
X
X cur_l = line;
X box_case = 0;
X latex_case = 0;
X last_position.x = cur_x = moved_point->x;
X last_position.y = cur_y = moved_point->y;
X set_temp_cursor(&crosshair_cursor);
X win_setmouseposition(canvas_win, cur_x, cur_y);
X switch (line->type) {
X case T_POLYGON :
X if (left_point == NULL)
X for (left_point = moved_point->next,
X p = left_point->next;
X p->next != NULL;
X left_point = p, p = p->next);
X break;
X case T_BOX :
X case T_ARC_BOX :
X if (moved_point->next->next == NULL) { /* point 4 */
X fix_x = line->points->next->x;
X fix_y = line->points->next->y;
X }
X else {
X fix_x = moved_point->next->next->x;
X fix_y = moved_point->next->next->y;
X }
X if (line->type == T_ARC_BOX)
X draw_arc_box(line, ERASE);
X else
X draw_line(line, ERASE);
X box_case = 1;
X break;
X case T_POLYLINE :
X if (left_point != NULL) {
X if (left_point == line->points) {
X if (line->back_arrow) /* backward arrow */
X draw_arrow(cur_x, cur_y,
X left_point->x, left_point->y,
X line->back_arrow, ERASE);
X }
X }
X else if (line->back_arrow) /* backward arrow */
X draw_arrow(moved_point->next->x, moved_point->next->y,
X cur_x, cur_y, line->back_arrow, ERASE);
X p = moved_point->next;
X if (p != NULL) {
X if (line->for_arrow && p->next == NULL)
X draw_arrow(cur_x, cur_y, p->x, p->y,
X line->for_arrow, ERASE);
X }
X else if (line->for_arrow)/* f arrow */
X draw_arrow(left_point->x, left_point->y,
X cur_x, cur_y, line->for_arrow, ERASE);
X if (latexline_mode || latexarrow_mode) {
X if (left_point != NULL) {
X latex_fix_x = left_point->x;
X latex_fix_y = left_point->y;
X latex_case = 1;
X }
X else if (p != NULL) {
X latex_fix_x = p->x;
X latex_fix_y = p->y;
X latex_case = 1;
X }
X }
X }
X if (box_case) {
X draw_rectbox(fix_x, fix_y, cur_x, cur_y, INV_PAINT);
X canvas_locmove_proc = elastic_box;
X canvas_middlebut_proc = fix_box;
X }
X else if (latex_case) {
X draw_pointlink(INV_PAINT);
X canvas_locmove_proc = move_latexlinepoint;
X canvas_middlebut_proc = fix_movedlatexlinepoint;
X cur_latexcursor = &crosshair_cursor;
X }
X else {
X draw_pointlink(INV_PAINT);
X canvas_locmove_proc = move_linepoint;
X canvas_middlebut_proc = fix_movedlinepoint;
X }
X canvas_leftbut_proc = null_proc;
X }
X
Xmove_linepoint(x, y)
Xint x, y;
X{
X draw_pointlink(INV_PAINT);
X cur_x = x;
X cur_y = y;
X draw_pointlink(INV_PAINT);
X }
X
Xmove_latexlinepoint(x, y)
Xint x, y;
X{
X CURSOR c;
X
X draw_pointlink(INV_PAINT);
X latex_endpoint(latex_fix_x, latex_fix_y, x, y, &cur_x, &cur_y,
X latexarrow_mode, (magnet_mode)? 5: 1);
X draw_pointlink(INV_PAINT);
X c = (x == cur_x && y == cur_y)? &null_cursor: &crosshair_cursor;
X if (c != cur_latexcursor) {
X set_temp_cursor(c);
X cur_latexcursor = c;
X }
X }
X
Xfix_box(x, y)
Xint x, y;
X{
X draw_rectbox(fix_x, fix_y, cur_x, cur_y, INV_PAINT);
X new_position.x = x;
X new_position.y = y;
X clean_up();
X set_action_object(F_MOVE_POINT, O_POLYLINE);
X set_latestline(line);
X relocate_linepoint(line, x, y, fix_x, fix_y, moved_point,
X left_point);
X wrapup_movepoint();
X }
X
Xassign_newboxpoint(b, x1, y1, x2, y2)
XF_line *b;
Xint x1, y1, x2, y2;
X{
X F_point *p;
X register int tmp;
X
X p = b->points;
X if (x1 > x2) /* sort them so that lower left is first */
X {
X tmp = x1; x1 = x2; x2 = tmp;
X }
X if (y1 > y2)
X {
X tmp = y1; y1 = y2; y2 = tmp;
X }
X p->x = x1; p->y = y1; p = p->next;
X p->x = x1; p->y = y2; p = p->next;
X p->x = x2; p->y = y2; p = p->next;
X p->x = x2; p->y = y1; p = p->next;
X p->x = x1; p->y = y1; p = p->next;
X }
X
Xfix_movedlinepoint(x, y)
Xint x, y;
X{
X draw_pointlink(INV_PAINT);
X new_position.x = x;
X new_position.y = y;
X clean_up();
X set_action_object(F_MOVE_POINT, O_POLYLINE);
X set_latestline(cur_l);
X relocate_linepoint(cur_l, x, y, fix_x, fix_y, moved_point, left_point);
X wrapup_movepoint();
X }
X
Xfix_movedlatexlinepoint(x, y)
Xint x, y;
X{
X draw_pointlink(INV_PAINT);
X latex_endpoint(latex_fix_x, latex_fix_y, x, y, &x, &y,
X latexarrow_mode, (magnet_mode)? 5: 1);
X if (cur_latexcursor != &crosshair_cursor)
X set_temp_cursor(&crosshair_cursor);
X win_setmouseposition(canvas_win, x, y);
X new_position.x = x;
X new_position.y = y;
X clean_up();
X set_action_object(F_MOVE_POINT, O_POLYLINE);
X set_latestline(cur_l);
X relocate_linepoint(cur_l, x, y, fix_x, fix_y, moved_point, left_point);
X wrapup_movepoint();
X }
X
Xrelocate_linepoint(line, x, y, fix_x, fix_y, moved_point, left_point)
XF_line *line;
Xint x, y;
XF_point *moved_point, *left_point;
X{
X if (pointmarker_shown) toggle_linepointmarker(line);
X draw_line(line, ERASE);
X switch (line->type) {
X case T_BOX :
X case T_ARC_BOX:
X assign_newboxpoint(line, fix_x, fix_y, x, y);
X break;
X case T_POLYGON :
X if (line->points == moved_point) {
X left_point->next->x = x;
X left_point->next->y = y;
X }
X default :
X moved_point->x = x;
X moved_point->y = y;
X }
X draw_line(line, PAINT);
X if (pointmarker_shown) toggle_linepointmarker(line);
X set_modifiedflag();
X }
X
Xdraw_pointlink(op)
Xint op;
X{
X F_point *p;
X
X if (left_point != NULL) {
X pw_vector(canvas_win, left_point->x, left_point->y,
X cur_x, cur_y, op, 1, SOLID_LINE, 0.0);
X }
X if ((p = moved_point->next) != NULL) {
X pw_vector(canvas_win, p->x, p->y, cur_x, cur_y, op, 1, SOLID_LINE, 0.0);
X }
X }
X
XF_line *
Xline_point_search(x, y, tol, p, q)
Xint x, y, tol;
XF_point **p, **q;
X{
X F_line *l;
X F_point *a, *b;
X
X for (l = objects.lines; l != NULL; l= l->next) {
X for (a = NULL, b = l->points; b != NULL; a = b, b = b->next) {
X if (abs(b->x - x) <= tol && abs(b->y - y) <= tol) {
X *p = a;
X *q = b;
X return(l);
X }
X }
X }
X return(NULL);
X }
END_OF_FILE
if test 17045 -ne `wc -c <'movept.c'`; then
echo shar: \"'movept.c'\" unpacked with wrong size!
fi
# end of 'movept.c'
fi
if test -f 'read.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'read.c'\"
else
echo shar: Extracting \"'read.c'\" \(16741 characters\)
sed "s/^X//" >'read.c' <<'END_OF_FILE'
X/*
X * FIG : Facility for Interactive Generation of figures
X *
X * Copyright (c) 1985, 1988 by Supoj Sutanthavibul (supoj at sally.UTEXAS.EDU)
X * January 1985.
X * 1st revision : August 1985.
X * 2nd revision : March 1988.
X *
X * %W% %G%
X*/
X#include "fig.h"
X#include "alloc.h"
X#include "object.h"
X#include "psfonts.h"
X
Xextern F_arrow *make_arrow();
Xextern char *calloc();
Xextern int errno;
X
Xstatic F_ellipse *read_ellipseobject();
Xstatic F_line *read_lineobject();
Xstatic F_text *read_textobject();
Xstatic F_spline *read_splineobject();
Xstatic F_arc *read_arcobject();
Xstatic F_compound *read_compoundobject();
X
X#define BUF_SIZE 1024
X
Xchar buf[BUF_SIZE];
Xint line_no;
Xint num_object;
Xint proto; /* file protocol*10 */
X
Xread_fail_message(file, err)
Xchar *file;
Xint err;
X{
X extern char *sys_errlist[];
X
X if (err == 0) /* Successful read */
X return;
X#ifdef ENAMETOOLONG
X else if (err == ENAMETOOLONG)
X put_msg("File name \"%s\" is too long", file);
X#endif
X else if (err == ENOENT)
X put_msg("File \"%s\" does not exist", file);
X else if (err == ENOTDIR)
X put_msg("A name in the path \"%s\" is not a directory", file);
X else if (err == EACCES)
X put_msg("Read access to file \"%s\" is blocked", file);
X else if (err == EISDIR)
X put_msg("File \"%s\" is a directory", file);
X else if (err == -2) {
X put_msg("File \"%s\" is empty", file);
X }
X else if (err == -1) {
X /* Format error; relevant error message is already delivered */
X }
X else
X put_msg("File \"%s\" is not accessable; %s", file, sys_errlist[err]);
X }
X
X/**********************************************************
XRead_fig returns :
X
X 0 : successful read.
X -1 : File is in incorrect format
X -2 : File is empty
Xerr_no : if file can not be read for various reasons
X
XThe resolution (ppi) and the coordinate system (coord_sys) are
Xstored in obj->nwcorner.x and obj->nwcorner.y respectively.
XThe coordinate system is 1 for lower left at 0,0 and
X2 for upper left at 0,0
X>>> xfig only uses 2 for the coordinate system. <<<
X**********************************************************/
X
Xread_fig(file_name, obj)
Xchar *file_name;
XF_compound *obj;
X{
X FILE *fp;
X
X line_no = 0;
X if ((fp = fopen(file_name, "r")) == NULL)
X return(errno);
X else
X return(readfp_fig(fp, obj));
X }
X
Xreadfp_fig(fp, obj)
XFILE *fp;
XF_compound *obj;
X{
X int status;
X float fproto;
X
X num_object = 0;
X bzero((char*)obj, COMOBJ_SIZE);
X if (fgets(buf,BUF_SIZE,fp)==0) /* version */
X return -2;
X if (strncmp(buf,"#FIG",4)==0) /* versions 1.4/later have #FIG in first line */
X {
X if ((sscanf(index(buf,' ')+1,"%f",&fproto))==0) /* assume 1.4 */
X proto=14;
X else
X proto = (fproto+.01)*10; /* protocol version*10 */
X status = read_objects(fp, obj);
X }
X else
X {
X proto = 13;
X status = read_1_3_objects(fp, obj);
X }
X
X fclose(fp);
X return(status);
X }
X
Xint
Xread_objects(fp, obj)
XFILE *fp;
XF_compound *obj;
X{
X F_ellipse *e, *le = NULL;
X F_line *l, *ll = NULL;
X F_text *t, *lt = NULL;
X F_spline *s, *ls = NULL;
X F_arc *a, *la = NULL;
X F_compound *c, *lc = NULL;
X int object, ppi, coord_sys;
X
X line_no++;
X if (get_line(fp) < 0) {
X put_msg("File is truncated");
X return(-1);
X }
X if (2 != sscanf(buf,"%d%d\n", &ppi, &coord_sys)) {
X put_msg("Incomplete data at line %d", line_no);
X return(-1);
X }
X
X obj->nwcorner.x = ppi;
X obj->nwcorner.y = coord_sys;
X while (get_line(fp) > 0) {
X if (1 != sscanf(buf, "%d", &object)) {
X put_msg("Incorrect format at line %d", line_no);
X return(-1);
X }
X switch (object) {
X case O_POLYLINE :
X if ((l = read_lineobject(fp)) == NULL) return(-1);
X if (ll)
X ll = (ll->next = l);
X else
X ll = obj->lines = l;
X num_object++;
X break;
X case O_SPLINE :
X if ((s = read_splineobject(fp)) == NULL) return(-1);
X if (ls)
X ls = (ls->next = s);
X else
X ls = obj->splines = s;
X num_object++;
X break;
X case O_ELLIPSE :
X if ((e = read_ellipseobject()) == NULL) return(-1);
X if (le)
X le = (le->next = e);
X else
X le = obj->ellipses = e;
X num_object++;
X break;
X case O_ARC :
X if ((a = read_arcobject(fp)) == NULL) return(-1);
X if (la)
X la = (la->next = a);
X else
X la = obj->arcs = a;
X num_object++;
X break;
X case O_TEXT :
X if ((t = read_textobject(fp)) == NULL) return(-1);
X if (lt)
X lt = (lt->next = t);
X else
X lt = obj->texts = t;
X num_object++;
X break;
X case O_COMPOUND :
X if ((c = read_compoundobject(fp)) == NULL) return(-1);
X if (lc)
X lc = (lc->next = c);
X else
X lc = obj->compounds = c;
X num_object++;
X break;
X default :
X put_msg("Incorrect object code at line %d", line_no);
X return(-1);
X } /* switch */
X } /* while */
X if (feof(fp))
X return(0);
X else
X return(errno);
X } /* read_objects */
X
Xstatic F_arc *
Xread_arcobject(fp)
XFILE *fp;
X{
X F_arc *a;
X int n, fa, ba;
X int type, style;
X float thickness, wid, ht;
X
X if (NULL == (Arc_malloc(a))) {
X put_msg(Err_mem);
X return(NULL);
X }
X a->next = NULL;
X a->for_arrow = a->back_arrow = NULL; /* added 8/23/89 B.V.Smith */
X n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d%f%f%d%d%d%d%d%d\n",
X &a->type, &a->style, &a->thickness,
X &a->color, &a->depth,
X &a->pen, &a->area_fill,
X &a->style_val, &a->direction, &fa, &ba,
X &a->center.x, &a->center.y,
X &a->point[0].x, &a->point[0].y,
X &a->point[1].x, &a->point[1].y,
X &a->point[2].x, &a->point[2].y);
X if (n != 19) {
X put_msg(Err_incomp, "arc", line_no);
X free((char*)a);
X return(NULL);
X }
X
X skip_comment(fp);
X if (fa) {
X line_no++;
X if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
X fprintf(stderr, Err_incomp, "arc", line_no);
X return(NULL);
X }
X skip_line(fp);
X a->for_arrow = make_arrow(type, style, thickness, wid, ht);
X skip_comment(fp);
X }
X skip_comment(fp);
X if (ba) {
X line_no++;
X if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
X fprintf(stderr, Err_incomp, "arc", line_no);
X return(NULL);
X }
X skip_line(fp);
X a->back_arrow = make_arrow(type, style, thickness, wid, ht);
X }
X return(a);
X }
X
Xstatic F_compound *
Xread_compoundobject(fp)
XFILE *fp;
X{
X F_arc *a, *la = NULL;
X F_ellipse *e, *le = NULL;
X F_line *l, *ll = NULL;
X F_spline *s, *ls = NULL;
X F_text *t, *lt = NULL;
X F_compound *com, *c, *lc = NULL;
X int n, object;
X
X if (NULL == (Compound_malloc(com))) {
X put_msg(Err_mem);
X return(NULL);
X }
X com->arcs = NULL;
X com->ellipses = NULL;
X com->lines = NULL;
X com->splines = NULL;
X com->texts = NULL;
X com->compounds = NULL;
X com->next = NULL;
X n = sscanf(buf, "%*d%d%d%d%d\n", &com->nwcorner.x, &com->nwcorner.y,
X &com->secorner.x, &com->secorner.y);
X if (4 != n) {
X put_msg(Err_incomp, "compound", line_no);
X free((char*)com);
X return(NULL);
X }
X while (get_line(fp) > 0) {
X if (1 != sscanf(buf, "%d", &object)) {
X put_msg(Err_incomp, "compound", line_no);
X free_compound(&com);
X return(NULL);
X }
X switch (object) {
X case O_POLYLINE :
X if ((l = read_lineobject(fp)) == NULL) {
X free_line(&l);
X return(NULL);
X }
X if (ll)
X ll = (ll->next = l);
X else
X ll = com->lines = l;
X break;
X case O_SPLINE :
X if ((s = read_splineobject(fp)) == NULL) {
X free_spline(&s);
X return(NULL);
X }
X if (ls)
X ls = (ls->next = s);
X else
X ls = com->splines = s;
X break;
X case O_ELLIPSE :
X if ((e = read_ellipseobject()) == NULL) {
X free_ellipse(&e);
X return(NULL);
X }
X if (le)
X le = (le->next = e);
X else
X le = com->ellipses = e;
X break;
X case O_ARC :
X if ((a = read_arcobject(fp)) == NULL) {
X free_arc(&a);
X return(NULL);
X }
X if (la)
X la = (la->next = a);
X else
X la = com->arcs = a;
X break;
X case O_TEXT :
X if ((t = read_textobject(fp)) == NULL) {
X free_text(&t);
X return(NULL);
X }
X if (lt)
X lt = (lt->next = t);
X else
X lt = com->texts = t;
X break;
X case O_COMPOUND :
X if ((c = read_compoundobject(fp)) == NULL) {
X free_compound(&c);
X return(NULL);
X }
X if (lc)
X lc = (lc->next = c);
X else
X lc = com->compounds = c;
X break;
X case O_END_COMPOUND :
X return(com);
X default :
X put_msg("Wrong object code at line %d", line_no);
X return(NULL);
X } /* switch */
X }
X if (feof(fp))
X return(com);
X else
X return(NULL);
X }
X
Xstatic F_ellipse *
Xread_ellipseobject()
X{
X F_ellipse *e;
X int n;
X
X if (NULL == (Ellipse_malloc(e))) {
X put_msg(Err_mem);
X return(NULL);
X }
X e->next = NULL;
X n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%f%d%d%d%d%d%d%d%d\n",
X &e->type, &e->style, &e->thickness,
X &e->color, &e->depth, &e->pen, &e->area_fill,
X &e->style_val, &e->direction, &e->angle,
X &e->center.x, &e->center.y,
X &e->radiuses.x, &e->radiuses.y,
X &e->start.x, &e->start.y,
X &e->end.x, &e->end.y);
X if (n != 18) {
X put_msg(Err_incomp, "ellipse", line_no);
X free((char*)e);
X return(NULL);
X }
X return(e);
X }
X
Xstatic F_line *
Xread_lineobject(fp)
XFILE *fp;
X{
X F_line *l;
X F_point *p, *q;
X int n, x, y, fa, ba;
X int type, style;
X float thickness, wid, ht;
X
X if (NULL == (Line_malloc(l))) {
X put_msg(Err_mem);
X return(NULL);
X }
X l->points = NULL;
X l->for_arrow = l->back_arrow = NULL;
X l->next = NULL;
X
X sscanf(buf,"%*d%d",&l->type);
X#ifndef TFX
X /* 2.0 or later; has separate radius parm for arc-box corners */
X if (l->type == T_ARC_BOX && proto >= 20)
X {
X n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d",
X &l->type, &l->style, &l->thickness, &l->color,
X &l->depth, &l->pen, &l->area_fill, &l->style_val, &l->radius,
X &fa, &ba);
X }
X /* old format uses pen for radius of arc-box corners */
X else
X#endif TFX
X {
X n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d",
X &l->type, &l->style, &l->thickness, &l->color,
X &l->depth, &l->pen, &l->area_fill, &l->style_val, &fa, &ba);
X#ifndef TFX
X if (l->type == T_ARC_BOX)
X {
X l->radius = l->pen;
X l->pen = 0;
X }
X else
X#endif TFX
X l->radius = 0;
X }
X
X#ifdef TFX
X if (n != 10)
X#else
X if ((proto==14 && n != 10) ||
X (proto==20 && (l->type == T_ARC_BOX && n != 11) ||
X (l->type != T_ARC_BOX && n != 10))) {
X#endif TFX
X put_msg(Err_incomp, "line", line_no);
X free((char*)l);
X return(NULL);
X }
X skip_comment(fp);
X if (fa) {
X line_no++;
X if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
X fprintf(stderr, Err_incomp, "line", line_no);
X return(NULL);
X }
X skip_line(fp);
X l->for_arrow = make_arrow(type, style, thickness, wid, ht);
X skip_comment(fp);
X }
X if (ba) {
X line_no++;
X if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
X fprintf(stderr, Err_incomp, "line", line_no);
X return(NULL);
X }
X skip_line(fp);
X l->back_arrow = make_arrow(type, style, thickness, wid, ht);
X skip_comment(fp);
X }
X
X if (NULL == (l->points = Point_malloc(p))) {
X put_msg(Err_mem);
X return(NULL);
X }
X p->next = NULL;
X
X /* points start on new line */
X line_no++;
X
X /* read first point */
X if (fscanf(fp, "%d%d", &p->x, &p->y) != 2) {
X put_msg(Err_incomp, "line", line_no);
X free_linestorage(l);
X return(NULL);
X }
X /* read subsequent points */
X for (;;) {
X if (fscanf(fp, "%d%d", &x, &y) != 2) {
X put_msg(Err_incomp, "line", line_no);
X free_linestorage(l);
X return(NULL);
X }
X if (x == 9999) break;
X if (NULL == (Point_malloc(q))) {
X put_msg(Err_mem);
X free_linestorage(l);
X return(NULL);
X }
X q->x = x;
X q->y = y;
X q->next = NULL;
X p->next = q;
X p = q;
X }
X skip_line(fp);
X return(l);
X }
X
Xstatic F_spline *
Xread_splineobject(fp)
XFILE *fp;
X{
X F_spline *s;
X F_point *p, *q;
X F_control *cp, *cq;
X int c, n, x, y, fa, ba;
X int type, style;
X float thickness, wid, ht;
X float lx, ly, rx, ry;
X
X if (NULL == (Spline_malloc(s))) {
X put_msg(Err_mem);
X return(NULL);
X }
X s->points = NULL;
X s->controls = NULL;
X s->for_arrow = s->back_arrow = NULL;
X s->next = NULL;
X
X n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d%d%d%d",
X &s->type, &s->style, &s->thickness, &s->color,
X &s->depth, &s->pen, &s->area_fill, &s->style_val, &fa, &ba);
X if (n != 10) {
X put_msg(Err_incomp, "spline", line_no);
X free((char*)s);
X return(NULL);
X }
X skip_comment(fp);
X if (fa) {
X line_no++;
X if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
X fprintf(stderr, Err_incomp, "spline", line_no);
X return(NULL);
X }
X skip_line(fp);
X s->for_arrow = make_arrow(type, style, thickness, wid, ht);
X skip_comment(fp);
X }
X if (ba) {
X line_no++;
X if (5 != fscanf(fp, "%d%d%f%f%f", &type, &style, &thickness, &wid, &ht)) {
X fprintf(stderr, Err_incomp, "spline", line_no);
X return(NULL);
X }
X skip_line(fp);
X s->back_arrow = make_arrow(type, style, thickness, wid, ht);
X skip_comment(fp);
X }
X
X line_no++;
X
X /* Read points */
X if ((n = fscanf(fp, "%d%d", &x, &y)) != 2) {
X put_msg(Err_incomp, "spline", line_no);
X free_splinestorage(s);
X return(NULL);
X };
X if (NULL == (s->points = Point_malloc(p))) {
X put_msg(Err_mem);
X free_splinestorage(s);
X return(NULL);
X }
X p->x = x; p->y = y;
X for (c = 1;;) {
X if (fscanf(fp, "%d%d", &x, &y) != 2) {
X put_msg(Err_incomp, "spline", line_no);
X p->next = NULL;
X free_splinestorage(s);
X return(NULL);
X };
X if (x == 9999) break;
X if (NULL == (Point_malloc(q))) {
X put_msg(Err_mem);
X free_splinestorage(s);
X return(NULL);
X }
X q->x = x;
X q->y = y;
X p->next = q;
X p = q;
X c++;
X }
X p->next = NULL;
X skip_line(fp);
X
X if (normal_spline(s)) return(s);
X
X line_no++;
X skip_comment(fp);
X /* Read controls */
X if ((n = fscanf(fp, "%f%f%f%f", &lx, &ly, &rx, &ry)) != 4) {
X put_msg(Err_incomp, "spline", line_no);
X free_splinestorage(s);
X return(NULL);
X };
X if (NULL == (s->controls = Control_malloc(cp))) {
X put_msg(Err_mem);
X free_splinestorage(s);
X return(NULL);
X }
X cp->lx = lx; cp->ly = ly;
X cp->rx = rx; cp->ry = ry;
X while (--c) {
X if (fscanf(fp, "%f%f%f%f", &lx, &ly, &rx, &ry) != 4) {
X put_msg(Err_incomp, "spline", line_no);
X cp->next = NULL;
X free_splinestorage(s);
X return(NULL);
X };
X if (NULL == (Control_malloc(cq))) {
X put_msg(Err_mem);
X cp->next = NULL;
X free_splinestorage(s);
X return(NULL);
X }
X cq->lx = lx; cq->ly = ly;
X cq->rx = rx; cq->ry = ry;
X cp->next = cq;
X cp = cq;
X }
X cp->next = NULL;
X
X skip_line(fp);
X return(s);
X }
X
Xstatic F_text *
Xread_textobject(fp)
XFILE *fp;
X{
X F_text *t;
X int n;
X int ignore = 0;
X char s[BUF_SIZE], s_temp[BUF_SIZE], junk[2];
X
X if (NULL == (Text_malloc(t))) {
X put_msg(Err_mem);
X return(NULL);
X }
X t->next = NULL;
X /* The text object is terminated by a CONTROL-A, so we read
X everything up to the CONTROL-A and then read that character.
X If we do not find the CONTROL-A on this line then this must
X be a multi-line text object and we will have to read more. */
X n = sscanf(buf,"%*d%d%d%d%d%d%d%f%d%d%d%d%d %[^\1]%[\1]",
X &t->type, &t->font, &t->size, &t->pen,
X &t->color, &t->depth, &t->angle,
X &t->style, &t->height, &t->length,
X &t->base_x, &t->base_y, s, junk);
X if (n != 13 && n != 14) {
X put_msg(Err_incomp, "text", line_no);
X free((char*)t);
X /* return(NULL); */
X }
X if (n == 13) {
X /* Read in the remainder of the text object. */
X do {
X fgets(buf, BUF_SIZE, fp);
X line_no++; /* As is done in get_line */
X n = sscanf(buf,"%[^\1]%[\1]", s_temp, junk);
X /* Safety check */
X if (strlen(s)+1 + strlen(s_temp)+1 > BUF_SIZE) {
X /* Too many characters. Ignore the rest. */
X ignore = 1;
X }
X if (!ignore)
X strcat(s, s_temp);
X } while (n == 1);
X }
X if (t->type > T_RIGHT_JUSTIFIED)
X {
X put_msg("Invalid text justification at line %d.",line_no);
X return(NULL);
X }
X if (t->font >= NUMFONTS)
X {
X put_msg("Invalid text font (%d) at line %d.",t->font,line_no);
X return(NULL);
X }
X if (strlen(s) == 0)
X (void) strcpy(s," ");
X t->cstring = (char*)calloc((unsigned)(strlen(s)+1), sizeof(char));
X if (NULL == t->cstring) {
X put_msg(Err_mem);
X free((char*)t);
X return(NULL);
X }
X (void) strcpy(t->cstring, s);
X return(t);
X }
X
Xget_line(fp)
XFILE *fp;
X{
X while (1) {
X if (NULL == fgets(buf, BUF_SIZE, fp)) {
X return(-1);
X }
X line_no++;
X if (*buf != '\n' && *buf != '#') /* Skip empty and comment lines */
X return(1);
X }
X }
X
Xskip_comment(fp)
XFILE *fp;
X{
X char c;
X
X while ((c = fgetc(fp)) == '#') skip_line(fp);
X if (c != '#') ungetc(c, fp);
X }
X
Xskip_line(fp)
XFILE *fp;
X{
X while (fgetc(fp) != '\n') {
X if (feof(fp)) return;
X }
X }
END_OF_FILE
if test 16741 -ne `wc -c <'read.c'`; then
echo shar: \"'read.c'\" unpacked with wrong size!
fi
# end of 'read.c'
fi
echo shar: End of archive 13 \(of 21\).
cp /dev/null ark13isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 21 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
dan
----------------------------------------------------
O'Reilly && Associates argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list