home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume8
/
xfig2.8
/
part13
/
f2hp.c
next >
Wrap
C/C++ Source or Header
|
1990-07-03
|
18KB
|
811 lines
/*
* f2hp : Fig-to-HPGL translator
*
* Original Copyright (c) 1986 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
*
* Created from f2ps by B.V. Smith 5/90
*
* %W% %G%
*/
#include "fig.h"
#include "object.h"
#include "resources.h"
#define PAGE_WIDTH (10.250-0.250) /* 10" X plot area (7475A) */
#define PAGE_HEIGHT (7.796-0.596) /* 7.2" Y plot area */
#define POINT_PER_INCH 72 /* text ppi */
#define MAX_COLORS 6 /* number of pens */
#define DEFAULT_COLOR 0 /* black */
#define UP 0
#define DOWN 1
#define TRANSF_X(x) (x)*scalex
#define TRANSF_Y(y) (coord_system==2? (ury-(y))*scaley: (y)*scaley)
char Usage[] = "Usage: %s [-P][-L][-debug][-e scale] [input [output]]\n";
char *prog;
int cur_thickness;
int cur_color= -9;
int cur_areafill=0;
int debug = 0;
int landscape = 1;
int pen=UP;
extern int num_object;
char *from = NULL, *to = NULL;
FILE *tfp = NULL;
char Err_incomp[] = "Incomplete %s object at line %d.";
char Err_mem[] = "Running out of memory.";
double scale = 1.0;
double scalex, scaley;
int coord_system;
int ppi;
int llx, lly, urx, ury;
int fill_type[NUMFILLPATS] = {4, 3, 4, 3, 4, 3, 4, 3, 4, 3,
4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 1};
int fill_spacing[NUMFILLPATS] = {8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6,
4, 4, 4, 4, 4, 4, 2, 2, 0};
int fill_angle[NUMFILLPATS] = {0, 0, 45, 45, 90, 90, 0, 0, 45, 45,
90, 90, 0, 0, 45, 45, 90, 90, 0, 0, 0};
int line_thickness; /* not needed for f2ps, arrow.c needs it for fig */
get_args(argc, argv)
int argc;
char *argv[];
{
char *a;
int first = 1;
prog = *argv;
while (--argc) {
a = *++argv;
if (*a == '-') {
if (*++a == 'l' || *a == 'L') { /* Landscape */
landscape = 1;
}
else if (*a == 'p' || *a == 'P') { /* Portrait */
landscape = 0;
}
else if (*a == 'd') /* debug printing */
debug = 1;
else if (*a == 'e') { /* Enlarging factor followed */
if (--argc)
scale = atof(*++argv);
else
goto error_exit;
}
else
goto error_exit;
}
else if (first) {
from = a; /* from file */
first = 0;
}
else if (first == 0) {
to = a; /* to file */
first = -1;
}
else
goto error_exit;
}
return;
error_exit:
fprintf(stderr, Usage, prog);
exit(1);
}
main(argc, argv)
int argc;
char *argv[];
{
F_compound objects;
int status;
get_args(argc, argv);
if (to == NULL)
tfp = stdout;
else if ((tfp = fopen(to, "w")) == NULL) {
fprintf(stderr, "%s: Couldn't open %s", prog, to);
fprintf(stderr, Usage, prog);
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);
fprintf(stderr,"\n");
exit(1);
}
genhp_objects(&objects);
if (tfp != stdout)
(void)fclose(tfp);
exit(0);
}
prolog(objects)
F_compound *objects;
{
plotter_on();
fprintf(tfp, "\033.I80;;17:"); /* set x-on/x-off */
fprintf(tfp, "\033.N;19:");
/* **** rotate for portrait mode **** */
if (!landscape) /* must reset clip window and plotter limits with rotaton */
fprintf(tfp, "RO 90;IW;IP;\n");
fprintf(tfp, "SC %d %d %d %d;\n", llx, urx, lly, ury);
}
epilog()
{
penup();
fprintf(tfp,"PA %d %d; ",urx,ury);
fprintf(tfp, "SP;\n");
plotter_off();
}
plotter_on()
{
fprintf(tfp,"\033.(\n");
}
plotter_off()
{
fprintf(tfp,"\033.)\n");
}
genhp_objects(objects)
F_compound *objects;
{
F_arc *a;
F_compound *c;
F_ellipse *e;
F_line *l;
F_spline *s;
F_text *t;
int itmp;
int color;
/* Compute bounding box of objects */
compound_bound(objects, &llx, &lly, &urx, &ury);
if (llx > urx) {
fprintf(stderr, "%s: No object",prog);
return;
}
ppi = objects->nwcorner.x; /* ppi */
coord_system = objects->nwcorner.y; /* 1=y normal, 2=y flipped */
scalex = scaley = scale; /* user enlarging factor */
/*************************************************************************/
/* we will just set llx lly etc to plotter area */
/*************************************************************************/
llx = lly = 0; /* lower left */
urx = PAGE_WIDTH*ppi;
ury = PAGE_HEIGHT*ppi;
if (!landscape) /* swap x,y */
{
itmp = llx; llx = lly; lly = itmp;
itmp = urx; urx = ury; ury = itmp;
}
prolog(objects);
/* plot color 0 first then 1, ... */
for (color=-1; color < MAX_COLORS; color++)
{
for (a = objects->arcs; a != NULL; a = a->next)
genhp_arc(a,color);
for (c = objects->compounds; c != NULL; c = c->next)
genhp_compound(c,color);
for (e = objects->ellipses; e != NULL; e = e->next)
genhp_ellipse(e,color);
for (l = objects->lines; l != NULL; l = l->next)
genhp_line(l,color);
for (s = objects->splines; s != NULL; s = s->next)
genhp_spline(s,color);
for (t = objects->texts; t != NULL; t = t->next)
genhp_text(t,color);
}
epilog();
}
set_style(s, v)
int s;
double v;
{
if (s == DASH_LINE) {
if (v > 0.0) fprintf(tfp, "LT 2;\n");
}
else if (s == DOTTED_LINE) {
if (v > 0.0) fprintf(tfp, "LT 1;\n");
}
}
reset_style(s, v)
int s;
double v;
{
if (s == DASH_LINE) {
if (v > 0.0) fprintf(tfp, "LT;\n");
}
else if (s == DOTTED_LINE) {
if (v > 0.0) fprintf(tfp, "LT;\n");
}
}
set_areafill(a)
int a;
{
if (cur_areafill == a)
return;
cur_areafill = a;
fprintf(tfp, "FT %d %d %d;\n",
fill_type[a-1],fill_spacing[a-1],fill_angle[a-1]);
}
set_linewidth(w)
int w;
{
cur_thickness = w;
}
set_color(c)
int c;
{
if (c < 0)
c = DEFAULT_COLOR;
if (cur_color == c)
return;
cur_color = c;
fprintf(tfp,"SP %d;\n",c+1);
}
moveto(x,y)
int x,y;
{
penup();
fprintf(tfp,"PA %.2f %.2f;\n",TRANSF_X(x),TRANSF_Y(y));
}
drawto(x,y)
int x,y;
{
pendown();
fprintf(tfp,"PA %.2f %.2f;\n",TRANSF_X(x),TRANSF_Y(y));
}
f_moveto(x,y)
double x,y;
{
penup();
fprintf(tfp,"PA %.2lf %.2lf;\n",TRANSF_X(x),TRANSF_Y(y));
}
f_drawto(x,y)
double x,y;
{
pendown();
fprintf(tfp,"PA %.2lf %.2lf;\n",TRANSF_X(x),TRANSF_Y(y));
}
penup()
{
if (pen != UP)
fprintf(tfp,"PU; ");
pen = UP;
}
pendown()
{
if (pen != DOWN)
fprintf(tfp,"PD; ");
pen = DOWN;
}
genhp_compound(com,color)
F_compound *com;
int color;
{
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)
genhp_arc(a,color);
for (c = com->compounds; c != NULL; c = c->next)
genhp_compound(c,color);
for (e = com->ellipses; e != NULL; e = e->next)
genhp_ellipse(e,color);
for (l = com->lines; l != NULL; l = l->next)
genhp_line(l,color);
for (s = com->splines; s != NULL; s = s->next)
genhp_spline(s,color);
for (t = com->texts; t != NULL; t = t->next)
genhp_text(t,color);
}
#define FILL_RECT(x,y) fprintf(tfp,"RA %.2f %.2f; ",TRANSF_X((x)),TRANSF_Y((y)))
#define EDGE_RECT(x,y) fprintf(tfp,"EA %.2f %.2f; ",TRANSF_X((x)),TRANSF_Y((y)))
#define FILL_WEDGE(r,angle,sweep) fprintf(tfp,"WG %.2f %d %d; ", \
TRANSF_X(r),(angle),(sweep))
#define ARC_TO(x,y,angle) fprintf(tfp,"AA %.2f %.2f %d; ", \
TRANSF_X((x)),TRANSF_Y((y)),(angle))
#define F_FILL_WEDGE(r,angle,sweep) fprintf(tfp,"WG %.2lf %d %d; ", \
TRANSF_X(r),(angle),(sweep))
#define F_ARC_TO(x,y,angle) fprintf(tfp,"AA %.2lf %.2lf %d; ", \
TRANSF_X((x)),TRANSF_Y((y)),(angle))
#define CIRCLE(r) fprintf(tfp,"CI %.2f;",TRANSF_X(r))
genhp_line(l,color)
F_line *l;
int color;
{
F_point *p, *q;
int radius,tmp;
int xmin,xmax,ymin,ymax;
if (color != l->color)
return;
set_linewidth(l->thickness);
set_color(l->color);
radius = l->radius; /* radius of rounded-corner boxes */
p = l->points;
q = p->next;
if (q == NULL) { /* A single point line */
if (l->thickness > 0)
{
moveto(p->x,p->y);
pendown();
penup();
}
return;
}
if (l->back_arrow)
draw_arrow_head((double)q->x, (double)q->y, (double)p->x,
(double)p->y, l->back_arrow->ht, l->back_arrow->wid);
set_style(l->style, l->style_val);
if (l->area_fill)
set_areafill(l->area_fill);
xmin = xmax = p->x;
ymin = ymax = p->y;
while ((l->type == T_BOX || l->type == T_ARC_BOX) &&
p->next != NULL) /* find lower left and upper right corners */
{
p=p->next;
if (xmin > p->x)
xmin = p->x;
else if (xmax < p->x)
xmax = p->x;
if (ymin > p->y)
ymin = p->y;
else if (ymax < p->y)
ymax = p->y;
}
if (l->type == T_ARC_BOX) /* rounded-corner box */
{
if (l->area_fill)
{
moveto(xmin+radius,ymin);
FILL_RECT(xmax-radius,ymin+radius);
moveto(xmin,ymin+radius);
FILL_RECT(xmax,ymax-radius);
moveto(xmin+radius,ymax-radius);
FILL_RECT(xmax-radius,ymax);
/* now do the corner wedges */
moveto(xmin+radius,ymin+radius);
FILL_WEDGE(radius,90,90);
moveto(xmin+radius,ymax-radius);
FILL_WEDGE(radius,180,90);
moveto(xmax-radius,ymax-radius);
FILL_WEDGE(radius,270,90);
moveto(xmax-radius,ymin+radius);
FILL_WEDGE(radius,0,90);
}
/* draw the outline of the box */
moveto(xmin+radius,ymin);
pendown();
ARC_TO(xmin+radius,ymin+radius,90);
drawto(xmin,ymax-radius);
ARC_TO(xmin+radius,ymax-radius,90);
drawto(xmax-radius,ymax);
ARC_TO(xmax-radius,ymax-radius,90);
drawto(xmax,ymin+radius);
ARC_TO(xmax-radius,ymin+radius,90);
drawto(xmin+radius,ymin);
} /* T_ARC_BOX */
else if (l->type == T_BOX)
{
moveto(xmin,ymin);
if (l->area_fill)
FILL_RECT(xmax,ymax);
EDGE_RECT(xmax,ymax);
}
else /* POLYGON or POLYLINE */
{
moveto(p->x, p->y);
while (q->next != NULL)
{
p = q;
q = q->next;
drawto(p->x, p->y);
}
drawto(q->x, q->y);
}
penup();
reset_style(l->style, l->style_val);
if (l->for_arrow && l->thickness > 0)
draw_arrow_head((double)p->x, (double)p->y, (double)q->x,
(double)q->y, l->for_arrow->ht, l->for_arrow->wid);
}
genhp_spline(s,color)
F_spline *s;
int color;
{
if (color != s->color)
return;
set_color(s->color);
#ifndef notdef
fprintf(stderr,"No spline yet\n");
#else
if (int_spline(s))
genhp_itp_spline(s);
else
genhp_ctl_spline(s);
#endif
}
genhp_itp_spline(s)
F_spline *s;
{
F_point *p, *q;
F_control *a, *b;
set_linewidth(s->thickness);
a = s->controls;
b = a->next;
p = s->points;
if (s->back_arrow && s->thickness > 0)
draw_arrow_head(b->lx, b->ly, (double)p->x,
(double)p->y, s->back_arrow->ht, s->back_arrow->wid);
set_style(s->style, s->style_val);
fprintf(tfp, "%% Interpolated spline\n");
fprintf(tfp, "newpath %d %d moveto\n", p->x, p->y);
for (q = p->next; q != NULL; p = q, q = q->next) {
b = a->next;
fprintf(tfp, "\t%.3f %.3f %.3f %.3f %d %d curveto\n",
a->rx, a->ry, b->lx, b->ly, q->x, q->y);
a = b;
}
if (closed_spline(s))
{
fprintf(tfp, " closepath ");
if (s->area_fill)
{
set_areafill(s->area_fill);
fprintf(tfp, " gsave fill grestore ");
set_areafill(NUMFILLPATS); /* back to black for line */
}
}
if (s->thickness > 0)
fprintf(tfp, " stroke\n");
reset_style(s->style, s->style_val);
if (s->for_arrow && s->thickness > 0)
draw_arrow_head(a->lx, a->ly, (double)p->x,
(double)p->y, s->for_arrow->ht, s->for_arrow->wid);
}
genhp_ctl_spline(s)
F_spline *s;
{
double a, b, c, d, x1, y1, x2, y2, x3, y3;
F_point *p, *q;
p = s->points;
x1 = p->x; y1 = p->y;
p = p->next;
c = p->x; d = p->y;
set_linewidth(s->thickness);
x3 = a = (x1 + c) / 2;
y3 = b = (y1 + d) / 2;
if (s->back_arrow && s->thickness > 0) {
draw_arrow_head(c, d, x1, y1, s->back_arrow->ht, s->back_arrow->wid);
}
set_style(s->style, s->style_val);
if (! closed_spline(s)) {
fprintf(tfp, "%% Open spline\n");
fprintf(tfp, "newpath %.3f %.3f moveto %.3f %.3f lineto\n",
x1, y1, x3, y3);
}
else {
fprintf(tfp, "%% Closed spline\n");
fprintf(tfp, "newpath %.3f %.3f moveto\n", a, b);
}
for (q = p->next; q != NULL; q = q->next) {
x1 = x3; y1 = y3;
x2 = c; y2 = d;
c = q->x; d = q->y;
x3 = (x2 + c) / 2;
y3 = (y2 + d) / 2;
fprintf(tfp, "\t%.3f %.3f %.3f %.3f %.3f %.3f DrawSplineSection\n",
x1, y1, x2, y2, x3, y3);
}
/*
* At this point, (x2,y2) and (c,d) are the position of the
* next-to-last and last point respectively, in the point list
*/
if (closed_spline(s)) {
fprintf(tfp, "\t%.3f %.3f %.3f %.3f %.3f %.3f DrawSplineSection closepath ",
x3, y3, c, d, a, b);
if (s->area_fill)
{
set_areafill(s->area_fill);
fprintf(tfp, " gsave fill grestore\n");
set_areafill(NUMFILLPATS); /* back to black for line */
}
if (s->thickness > 0)
fprintf(tfp, " stroke\n");
}
else {
if (s->thickness > 0)
fprintf(tfp, "\t%.3f %.3f lineto stroke\n", c, d);
else
fprintf(tfp, "\t%.3f %.3f lineto\n", c, d);
}
reset_style(s->style, s->style_val);
if (s->for_arrow && s->thickness > 0)
{
draw_arrow_head(x2, y2, c, d, s->for_arrow->ht,
s->for_arrow->wid);
}
}
genhp_ellipse(e,color)
F_ellipse *e;
int color;
{
int rx,ry,cx,cy;
double x,y;
int npts;
double theta,inc;
if (color != e->color)
return;
set_linewidth(e->thickness);
set_color(e->color);
set_style(e->style, e->style_val);
if (e->area_fill)
set_areafill(e->area_fill);
rx = e->radiuses.x;
ry = e->radiuses.y;
cx = e->center.x;
cy = e->center.y;
if (rx == ry)
{ /* CIRCLE */
moveto(cx, cy);
if (e->area_fill)
FILL_WEDGE(rx, 0, 360);
/* outline the circle */
CIRCLE(rx);
}
else /* ellipse */
{
npts = (rx+ry)*2; /* pick some number of points proportional
to the size of the ellipse to plot */
inc = 2.0*M_PI/npts;
moveto(cx+rx,cy);
for (theta = 0.0; theta <= 2*M_PI; theta += inc)
{
x = cx + rx*cos(theta);
y = cy + ry*sin(theta);
f_drawto(x,y);
}
drawto(cx+rx, cy);
}
penup();
reset_style(e->style, e->style_val);
}
#define IS_ITALICS(f) ((f)&1)
genhp_text(t,color)
F_text *t;
int color;
{
double height;
int len;
if (color != t->color)
return;
set_color(t->color);
height = (double) t->size/POINT_PER_INCH*2.54; /* height in cm */
height = height*scale;
height = height/1.5; /* kludge for now */
fprintf(tfp,"SI %.2lf %.2lf;",height/2.54,height);
len = strlen(t->cstring);
if (IS_ITALICS(t->font)) /* slant for Italics font */
fprintf(tfp,"SL %.2f;",tan((double)30.0*M_PI/180.0)); /* 30 degrees */
moveto(t->base_x,t->base_y);
if (t->type == T_RIGHT_JUSTIFIED)
fprintf(tfp,"CP %d 0; ",-len);
else if (t->type == T_CENTER_JUSTIFIED)
fprintf(tfp,"CP %.1f 0; ",-len/2.0);
fprintf(tfp,"LB%s\003;\n",t->cstring);
if (IS_ITALICS(t->font))
fprintf(tfp,"SL;");
}
genhp_arc(a,color)
F_arc *a;
int color;
{
double angle1, angle2, dx, dy, radius, x, y;
double cx, cy, sx, sy, ex, ey;
int sweep;
int direction;
if (color != a->color)
return;
cx = a->center.x; cy = a->center.y;
sx = a->point[0].x; sy = a->point[0].y;
ex = a->point[2].x; ey = a->point[2].y;
if (coord_system == 2)
direction = !a->direction;
else
direction = a->direction;
set_linewidth(a->thickness);
set_color(a->color);
if (a->for_arrow && a->thickness > 0) {
arc_tangent(cx, cy, ex, ey, direction, &x, &y);
draw_arrow_head(x, y, ex, ey, a->for_arrow->ht, a->for_arrow->wid);
}
if (a->back_arrow && a->thickness > 0) {
arc_tangent(cx, cy, sx, sy, !direction, &x, &y);
draw_arrow_head(x, y, sx, sy, a->back_arrow->ht, a->back_arrow->wid);
}
dx = cx - sx;
dy = cy - sy;
radius = sqrt(dx*dx + dy*dy);
angle1 = atan2(sy-cy, sx-cx) * 180 / M_PI;
angle2 = atan2(ey-cy, ex-cx) * 180 / M_PI;
/* make the angles go from 0 to 2PI */
if (angle1 < 0.0)
angle1 += 360.0;
if (angle2 < 0.0)
angle2 += 360.0;
/* direction 1 -> Counter-Clockwise */
if (direction == 1) /* ccw */
{
if (angle1 > angle2)
sweep = 360.0 - angle1 + angle2;
else
sweep = angle2 - angle1;
}
else /* cw */
{
if (angle1 > angle2)
sweep = - (angle1 - angle2);
else
sweep = - (360.0 - angle2 + angle1);
}
if (debug)
fprintf(stderr,"#%d: dir=%s, a1 = %.1f, a2 = %.1f, sweep = %d\n",
a->thickness,direction==0?"cw ":"ccw",cx,cy,angle1,angle2,sweep);
set_style(a->style, a->style_val);
if (a->area_fill)
{
set_areafill(a->area_fill);
f_moveto(cx,cy);
F_FILL_WEDGE(radius,(int)angle1,sweep);
}
f_moveto(ex,ey);
pendown();
F_ARC_TO(cx,cy,sweep);
penup();
reset_style(a->style, a->style_val);
}
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((double)(dx*dx + dy*dy)); /* length of line */
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; /* one tail of arrow */
yc = -x*sina + y*cosa;
y = yb + arrowwid / 2;
xd = x*cosa + y*sina; /* other tail of arrow */
yd = -x*sina + y*cosa;
f_moveto(xc,yc);
f_drawto(x2,y2);
f_drawto(xd,yd);
penup();
}
ellipse_exist(ob)
F_compound *ob;
{
F_compound *c;
if (NULL != ob->ellipses) return(1);
for (c = ob->compounds; c != NULL; c = c->next) {
if (ellipse_exist(c)) return(1);
}
return(0);
}
normal_spline_exist(ob)
F_compound *ob;
{
F_spline *s;
F_compound *c;
for (s = ob->splines; s != NULL; s = s->next) {
if (normal_spline(s)) return(1);
}
for (c = ob->compounds; c != NULL; c = c->next) {
if (normal_spline_exist(c)) return(1);
}
return(0);
}
/*VARARGS1*/
put_msg(format, arg1, arg2, arg3, arg4, arg5)
char *format;
int arg1, arg2, arg3, arg4, arg5;
{
fprintf(stderr, format, arg1, arg2, arg3, arg4, arg5);
}