home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume8
/
xfig2.8
/
part07
/
draw.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-02
|
8KB
|
382 lines
/*
* FIG : Facility for Interactive Generation of figures
*
* Copyright (c) 1988 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
* March 1988.
*
* %W% %G%
*/
#include "fig.h"
#include "resources.h"
#include "object.h"
#include "paintop.h"
extern int pointmarker_shown, compoundbox_shown;
extern int background_color, foreground_color;
/* COMMENTED OUT
erase_objects(objects)
F_compound *objects;
{
erase_arcs(objects->arcs);
erase_ellipses(objects->ellipses);
erase_lines(objects->lines);
erase_texts(objects->texts);
erase_splines(objects->splines);
erase_compounds(objects->compounds);
}
*/
erase_splines(splines)
F_spline *splines;
{
F_spline *s;
for (s = splines; s != NULL; s = s->next) {
if (pointmarker_shown) toggle_splinepointmarker(s);
draw_spline(s, ERASE);
};
}
erase_ellipses(ellipses)
F_ellipse *ellipses;
{
F_ellipse *e;
for (e = ellipses; e != NULL; e = e->next) {
if (pointmarker_shown) toggle_ellipsepointmarker(e);
draw_ellipse(e, background_color);
};
}
erase_arcs(arcs)
F_arc *arcs;
{
F_arc *a;
for (a = arcs; a != NULL; a = a->next) {
if (pointmarker_shown) toggle_arcpointmarker(a);
draw_arc(a, background_color);
};
}
erase_compounds(compounds)
F_compound *compounds;
{
F_compound *c;
for (c = compounds; c != NULL; c = c->next) {
if (compoundbox_shown) draw_compoundbox(c, INV_PAINT);
erase_compound(c);
};
}
erase_lines(lines)
F_line *lines;
{
F_line *l;
for (l = lines; l != NULL; l = l->next) {
if (pointmarker_shown) toggle_linepointmarker(l);
draw_line(l, ERASE);
};
}
erase_texts(texts)
F_text *texts;
{
F_text *t;
for (t = texts; t != NULL; t = t->next) {
draw_text(t, INV_PAINT);
};
}
/*
draw_objects(objects)
F_compound *objects;
{
draw_arcs(objects->arcs);
draw_ellipses(objects->ellipses);
draw_lines(objects->lines);
draw_texts(objects->texts);
draw_splines(objects->splines);
draw_compounds(objects->compounds);
}
*/
draw_ellipses(ellipses)
F_ellipse *ellipses;
{
F_ellipse *e;
for (e = ellipses; e != NULL; e = e->next) {
draw_ellipse(e, foreground_color);
if (pointmarker_shown) toggle_ellipsepointmarker(e);
};
}
draw_arcs(arcs)
F_arc *arcs;
{
F_arc *a;
for (a = arcs; a != NULL; a = a->next) {
draw_arc(a, foreground_color);
if (pointmarker_shown) toggle_arcpointmarker(a);
};
}
draw_lines(lines)
F_line *lines;
{
F_line *l;
for (l = lines; l != NULL; l = l->next) {
draw_line(l, PAINT);
if (pointmarker_shown)
toggle_linepointmarker(l);
}
}
draw_splines(splines)
F_spline *splines;
{
F_spline *s;
for (s = splines; s != NULL; s = s->next) {
draw_spline(s, PAINT);
if (pointmarker_shown) toggle_splinepointmarker(s);
};
}
draw_texts(texts)
F_text *texts;
{
F_text *t;
for (t = texts; t != NULL; t = t->next) {
draw_text(t, PAINT);
};
}
draw_compounds(compounds)
F_compound *compounds;
{
F_compound *c;
for (c = compounds; c != NULL; c = c->next) {
draw_compound(c);
if (compoundbox_shown) draw_compoundbox(c, INV_PAINT);
};
}
/* draw arrow heading from (x1, y1) to (x2, y2) */
draw_arrow(x1, y1, x2, y2, arrow, op)
int x1, y1, x2, y2, op;
F_arrow *arrow;
{
float x, y, xb, yb, dx, dy, l, sina, cosa;
int xc, yc, xd, yd;
float wid = arrow->wid, ht = arrow->ht;
dx = x2 - x1; dy = y1 - y2;
l = sqrt((double)(dx*dx + dy*dy));
if(l == 0)
return;
sina = dy / l; cosa = dx / l;
xb = x2*cosa - y2*sina;
yb = x2*sina + y2*cosa;
x = xb - ht;
y = yb - wid / 2;
xc = x*cosa + y*sina + .5;
yc = -x*sina + y*cosa + .5;
y = yb + wid / 2;
xd = x*cosa + y*sina + .5;
yd = -x*sina + y*cosa + .5;
pw_vector(canvas_win, xc, yc, x2, y2, op,
(int) arrow->thickness, arrow->style, 0.0);
pw_vector(canvas_win, xd, yd, x2, y2, op,
(int) arrow->thickness, arrow->style, 0.0);
}
draw_spline(spline, op)
F_spline *spline;
int op;
{
if (int_spline(spline))
draw_intspline(spline, op);
else if (spline->type == T_CLOSED_NORMAL)
draw_closed_spline(spline, op);
else if (spline->type == T_OPEN_NORMAL)
draw_open_spline(spline, op);
}
#define STACK_DEPTH 32
typedef struct stack {
float x1, y1, x2, y2, x3, y3, x4, y4;
}
Stack;
static Stack stack[20];
static Stack *stack_top;
static int stack_count;
clear_stack()
{
stack_top = stack;
stack_count = 0;
}
push(x1, y1, x2, y2, x3, y3, x4, y4)
float x1, y1, x2, y2, x3, y3, x4, y4;
{
stack_top->x1 = x1;
stack_top->y1 = y1;
stack_top->x2 = x2;
stack_top->y2 = y2;
stack_top->x3 = x3;
stack_top->y3 = y3;
stack_top->x4 = x4;
stack_top->y4 = y4;
stack_top++;
stack_count++;
}
int
pop(x1, y1, x2, y2, x3, y3, x4, y4)
float *x1, *y1, *x2, *y2, *x3, *y3, *x4, *y4;
{
if (stack_count == 0) return(0);
stack_top--;
stack_count--;
*x1 = stack_top->x1;
*y1 = stack_top->y1;
*x2 = stack_top->x2;
*y2 = stack_top->y2;
*x3 = stack_top->x3;
*y3 = stack_top->y3;
*x4 = stack_top->x4;
*y4 = stack_top->y4;
return(1);
}
draw_line(line, op)
F_line *line;
int op;
{
F_point *point;
XPoint *points, *pptr;
int npoints;
int xx, yy, x, y;
/* fill the object first then draw outline */
fill_object(line,op);
if (line->type == T_ARC_BOX) /* box with rounded corners */
{
draw_arc_box(line,op);
return;
}
point = line->points;
/* get and save first point */
x = point->x;
y = point->y;
if (line->points->next == NULL) { /* A single point */
XDrawPoint(tool_d, canvas_win, gccache[op], x, y);
return;
}
if (line->back_arrow) /* backward arrow */
draw_arrow(point->next->x, point->next->y, x, y,
line->back_arrow, op);
if (line->style == SOLID_LINE) /* accumulate the points for solid line */
{
npoints = 0;
/* count number of points in this object */
for ( ; point != NULL; point = point->next)
npoints++;
/* accumulate the points in an array */
if ((points = (XPoint *) malloc(npoints*sizeof(XPoint))) == 0)
{
fprintf(stderr,"draw_line(): No memory\n");
return;
}
pptr = points;
}
for (point=line->points; point != NULL; point = point->next) {
if (line->style == SOLID_LINE)
{
pptr->x = point->x;
pptr->y = point->y;
pptr++;
}
else /* draw dashed or dotted line segment by segment
otherwise when moving one segment later there
is an alignment problem with the dashes */
pw_vector(canvas_win, x, y, point->x, point->y, op,
line->thickness, line->style, line->style_val);
xx = x; yy = y;
x = point->x;
y = point->y;
}
if (line->style == SOLID_LINE)
{
pw_lines(canvas_win, points, npoints, op,
line->thickness, line->style, line->style_val, 0);
free(points);
}
if (line->for_arrow)
draw_arrow(xx, yy, x, y, line->for_arrow, op);
}
draw_arc_box(line, op)
F_line *line;
int op;
{
F_point *point;
int xmin,xmax,ymin,ymax;
int thick, style;
float val;
int radius,diam;
GC gc;
thick = line->thickness;
if (thick == 0)
return;
point = line->points;
style = line->style;
val = line->style_val;
radius = line->radius;
xmin = xmax = point->x;
ymin = ymax = point->y;
while (point->next) /* find lower left (upper-left on screen) */
{ /* and upper right (lower right on screen) */
point = point->next;
if (point->x < xmin)
xmin = point->x;
else if (point->x > xmax)
xmax = point->x;
if (point->y < ymin)
ymin = point->y;
else if (point->y > ymax)
ymax = point->y;
}
set_line_stuff(thick,style,val,op);
gc = gccache[op];
diam = 2*radius;
XDrawArc(tool_d, canvas_win, gc, xmin, ymin,
diam, diam, 90*64, 90*64);
XDrawLine(tool_d, canvas_win, gc, xmin, ymin+radius, xmin, ymax-radius+1);
XDrawArc(tool_d, canvas_win, gc, xmin, ymax-diam,
diam, diam, 180*64, 90*64);
XDrawLine(tool_d, canvas_win, gc, xmin+radius, ymax, xmax-radius+1, ymax);
XDrawArc(tool_d, canvas_win, gc, xmax-diam, ymax-diam,
diam, diam, 270*64, 90*64);
XDrawLine(tool_d, canvas_win, gc, xmax, ymax-radius, xmax, ymin+radius-1);
XDrawArc(tool_d, canvas_win, gc, xmax-diam, ymin,
diam, diam, 0*64, 90*64);
XDrawLine(tool_d, canvas_win, gc, xmax-radius, ymin, xmin+radius-1, ymin);
}