xref: /plan9/sys/src/cmd/grap/misc.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1*3e12c5d1SDavid du Colombier #include <stdio.h>
2*3e12c5d1SDavid du Colombier #include <string.h>
3*3e12c5d1SDavid du Colombier #include <stdlib.h>
4*3e12c5d1SDavid du Colombier #include "grap.h"
5*3e12c5d1SDavid du Colombier #include "y.tab.h"
6*3e12c5d1SDavid du Colombier 
7*3e12c5d1SDavid du Colombier int	nnum	= 0;	/* number of saved numbers */
8*3e12c5d1SDavid du Colombier double	num[MAXNUM];
9*3e12c5d1SDavid du Colombier 
10*3e12c5d1SDavid du Colombier int	just;		/* current justification mode (RJUST, etc.) */
11*3e12c5d1SDavid du Colombier int	sizeop;		/* current optional operator for size change */
12*3e12c5d1SDavid du Colombier double	sizexpr;	/* current size change expression */
13*3e12c5d1SDavid du Colombier 
savenum(int n,double f)14*3e12c5d1SDavid du Colombier void savenum(int n, double f)	/* save f in num[n] */
15*3e12c5d1SDavid du Colombier {
16*3e12c5d1SDavid du Colombier 	num[n] = f;
17*3e12c5d1SDavid du Colombier 	nnum = n+1;
18*3e12c5d1SDavid du Colombier 	if (nnum >= MAXNUM)
19*3e12c5d1SDavid du Colombier 		ERROR "too many numbers" WARNING;
20*3e12c5d1SDavid du Colombier }
21*3e12c5d1SDavid du Colombier 
setjust(int j)22*3e12c5d1SDavid du Colombier void setjust(int j)
23*3e12c5d1SDavid du Colombier {
24*3e12c5d1SDavid du Colombier 	just |= j;
25*3e12c5d1SDavid du Colombier }
26*3e12c5d1SDavid du Colombier 
setsize(int op,double expr)27*3e12c5d1SDavid du Colombier void setsize(int op, double expr)
28*3e12c5d1SDavid du Colombier {
29*3e12c5d1SDavid du Colombier 	sizeop = op;
30*3e12c5d1SDavid du Colombier 	sizexpr = expr;
31*3e12c5d1SDavid du Colombier }
32*3e12c5d1SDavid du Colombier 
tostring(char * s)33*3e12c5d1SDavid du Colombier char *tostring(char *s)
34*3e12c5d1SDavid du Colombier {
35*3e12c5d1SDavid du Colombier 	register char *p;
36*3e12c5d1SDavid du Colombier 
37*3e12c5d1SDavid du Colombier 	p = malloc(strlen(s)+1);
38*3e12c5d1SDavid du Colombier 	if (p == NULL)
39*3e12c5d1SDavid du Colombier 		ERROR "out of space in tostring on %s", s FATAL;
40*3e12c5d1SDavid du Colombier 	strcpy(p, s);
41*3e12c5d1SDavid du Colombier 	return(p);
42*3e12c5d1SDavid du Colombier }
43*3e12c5d1SDavid du Colombier 
range(Point pt)44*3e12c5d1SDavid du Colombier void range(Point pt)	/* update the range for point pt */
45*3e12c5d1SDavid du Colombier {
46*3e12c5d1SDavid du Colombier 	Obj *p = pt.obj;
47*3e12c5d1SDavid du Colombier 
48*3e12c5d1SDavid du Colombier 	if (!(p->coord & XFLAG)) {
49*3e12c5d1SDavid du Colombier 		if (pt.x > p->pt1.x)
50*3e12c5d1SDavid du Colombier 			p->pt1.x = pt.x;
51*3e12c5d1SDavid du Colombier 		if (pt.x < p->pt.x)
52*3e12c5d1SDavid du Colombier 			p->pt.x = pt.x;
53*3e12c5d1SDavid du Colombier 	}
54*3e12c5d1SDavid du Colombier 	if (!(p->coord & YFLAG)) {
55*3e12c5d1SDavid du Colombier 		if (pt.y > p->pt1.y)
56*3e12c5d1SDavid du Colombier 			p->pt1.y = pt.y;
57*3e12c5d1SDavid du Colombier 		if (pt.y < p->pt.y)
58*3e12c5d1SDavid du Colombier 			p->pt.y = pt.y;
59*3e12c5d1SDavid du Colombier 	}
60*3e12c5d1SDavid du Colombier }
61*3e12c5d1SDavid du Colombier 
halfrange(Obj * p,int side,double val)62*3e12c5d1SDavid du Colombier void halfrange(Obj *p, int side, double val)	/* record max and min for one direction */
63*3e12c5d1SDavid du Colombier {
64*3e12c5d1SDavid du Colombier 	if (!(p->coord&XFLAG) && (side == LEFT || side == RIGHT)) {
65*3e12c5d1SDavid du Colombier 		if (val < p->pt.y)
66*3e12c5d1SDavid du Colombier 			p->pt.y = val;
67*3e12c5d1SDavid du Colombier 		if (val > p->pt1.y)
68*3e12c5d1SDavid du Colombier 			p->pt1.y = val;
69*3e12c5d1SDavid du Colombier 	} else if (!(p->coord&YFLAG) && (side == TOP || side == BOT)) {
70*3e12c5d1SDavid du Colombier 		if (val < p->pt.x)
71*3e12c5d1SDavid du Colombier 			p->pt.x = val;
72*3e12c5d1SDavid du Colombier 		if (val > p->pt1.x)
73*3e12c5d1SDavid du Colombier 			p->pt1.x = val;
74*3e12c5d1SDavid du Colombier 	}
75*3e12c5d1SDavid du Colombier }
76*3e12c5d1SDavid du Colombier 
77*3e12c5d1SDavid du Colombier 
lookup(char * s,int inst)78*3e12c5d1SDavid du Colombier Obj *lookup(char *s, int inst)	/* find s in objlist, install if inst */
79*3e12c5d1SDavid du Colombier {
80*3e12c5d1SDavid du Colombier 	Obj *p;
81*3e12c5d1SDavid du Colombier 	int found = 0;
82*3e12c5d1SDavid du Colombier 
83*3e12c5d1SDavid du Colombier 	for (p = objlist; p; p = p->next){
84*3e12c5d1SDavid du Colombier 		if (strcmp(s, p->name) == 0) {
85*3e12c5d1SDavid du Colombier 			found = 1;
86*3e12c5d1SDavid du Colombier 			break;
87*3e12c5d1SDavid du Colombier 		}
88*3e12c5d1SDavid du Colombier 	}
89*3e12c5d1SDavid du Colombier 	if (p == NULL && inst != 0) {
90*3e12c5d1SDavid du Colombier 		p = (Obj *) calloc(1, sizeof(Obj));
91*3e12c5d1SDavid du Colombier 		if (p == NULL)
92*3e12c5d1SDavid du Colombier 			ERROR "out of space in lookup" FATAL;
93*3e12c5d1SDavid du Colombier 		p->name = tostring(s);
94*3e12c5d1SDavid du Colombier 		p->type = NAME;
95*3e12c5d1SDavid du Colombier 		p->pt = ptmax;
96*3e12c5d1SDavid du Colombier 		p->pt1 = ptmin;
97*3e12c5d1SDavid du Colombier 		p->fval = 0.0;
98*3e12c5d1SDavid du Colombier 		p->next = objlist;
99*3e12c5d1SDavid du Colombier 		objlist = p;
100*3e12c5d1SDavid du Colombier 	}
101*3e12c5d1SDavid du Colombier 	dprintf("lookup(%s,%d) = %d\n", s, inst, found);
102*3e12c5d1SDavid du Colombier 	return p;
103*3e12c5d1SDavid du Colombier }
104*3e12c5d1SDavid du Colombier 
getvar(Obj * p)105*3e12c5d1SDavid du Colombier double getvar(Obj *p)	/* return value of variable */
106*3e12c5d1SDavid du Colombier {
107*3e12c5d1SDavid du Colombier 	return p->fval;
108*3e12c5d1SDavid du Colombier }
109*3e12c5d1SDavid du Colombier 
setvar(Obj * p,double f)110*3e12c5d1SDavid du Colombier double setvar(Obj *p, double f)	/* set value of variable to f */
111*3e12c5d1SDavid du Colombier {
112*3e12c5d1SDavid du Colombier 	if (strcmp(p->name, "pointsize") == 0) {	/* kludge */
113*3e12c5d1SDavid du Colombier 		pointsize = f;
114*3e12c5d1SDavid du Colombier 		ps_set = 1;
115*3e12c5d1SDavid du Colombier 	}
116*3e12c5d1SDavid du Colombier 	p->type = VARNAME;
117*3e12c5d1SDavid du Colombier 	return p->fval = f;
118*3e12c5d1SDavid du Colombier }
119*3e12c5d1SDavid du Colombier 
makepoint(Obj * s,double x,double y)120*3e12c5d1SDavid du Colombier Point makepoint(Obj *s, double x, double y)	/* make a Point */
121*3e12c5d1SDavid du Colombier {
122*3e12c5d1SDavid du Colombier 	Point p;
123*3e12c5d1SDavid du Colombier 
124*3e12c5d1SDavid du Colombier 	dprintf("makepoint: %s, %g,%g\n", s->name, x, y);
125*3e12c5d1SDavid du Colombier 	p.obj = s;
126*3e12c5d1SDavid du Colombier 	p.x = x;
127*3e12c5d1SDavid du Colombier 	p.y = y;
128*3e12c5d1SDavid du Colombier 	return p;
129*3e12c5d1SDavid du Colombier }
130*3e12c5d1SDavid du Colombier 
makefattr(int type,double fval)131*3e12c5d1SDavid du Colombier Attr *makefattr(int type, double fval)	/* set double in attribute */
132*3e12c5d1SDavid du Colombier {
133*3e12c5d1SDavid du Colombier 	return makeattr(type, fval, (char *) 0, 0, 0);
134*3e12c5d1SDavid du Colombier }
135*3e12c5d1SDavid du Colombier 
makesattr(char * s)136*3e12c5d1SDavid du Colombier Attr *makesattr(char *s)		/* make an Attr cell containing s */
137*3e12c5d1SDavid du Colombier {
138*3e12c5d1SDavid du Colombier 	Attr *ap = makeattr(STRING, sizexpr, s, just, sizeop);
139*3e12c5d1SDavid du Colombier 	just = sizeop = 0;
140*3e12c5d1SDavid du Colombier 	sizexpr = 0.0;
141*3e12c5d1SDavid du Colombier 	return ap;
142*3e12c5d1SDavid du Colombier }
143*3e12c5d1SDavid du Colombier 
makeattr(int type,double fval,char * sval,int just,int op)144*3e12c5d1SDavid du Colombier Attr *makeattr(int type, double fval, char *sval, int just, int op)
145*3e12c5d1SDavid du Colombier {
146*3e12c5d1SDavid du Colombier 	Attr *a;
147*3e12c5d1SDavid du Colombier 
148*3e12c5d1SDavid du Colombier 	a = (Attr *) malloc(sizeof(Attr));
149*3e12c5d1SDavid du Colombier 	if (a == NULL)
150*3e12c5d1SDavid du Colombier 		ERROR "out of space in makeattr" FATAL;
151*3e12c5d1SDavid du Colombier 	a->type = type;
152*3e12c5d1SDavid du Colombier 	a->fval = fval;
153*3e12c5d1SDavid du Colombier 	a->sval = sval;
154*3e12c5d1SDavid du Colombier 	a->just = just;
155*3e12c5d1SDavid du Colombier 	a->op = op;
156*3e12c5d1SDavid du Colombier 	a->next = NULL;
157*3e12c5d1SDavid du Colombier 	return a;
158*3e12c5d1SDavid du Colombier }
159*3e12c5d1SDavid du Colombier 
addattr(Attr * a1,Attr * ap)160*3e12c5d1SDavid du Colombier Attr *addattr(Attr *a1, Attr *ap)	/* add attr ap to end of list a1 */
161*3e12c5d1SDavid du Colombier {
162*3e12c5d1SDavid du Colombier 	Attr *p;
163*3e12c5d1SDavid du Colombier 
164*3e12c5d1SDavid du Colombier 	if (a1 == 0)
165*3e12c5d1SDavid du Colombier 		return ap;
166*3e12c5d1SDavid du Colombier 	if (ap == 0)
167*3e12c5d1SDavid du Colombier 		return a1;
168*3e12c5d1SDavid du Colombier 	for (p = a1; p->next; p = p->next)
169*3e12c5d1SDavid du Colombier 		;
170*3e12c5d1SDavid du Colombier 	p->next = ap;
171*3e12c5d1SDavid du Colombier 	return a1;
172*3e12c5d1SDavid du Colombier }
173*3e12c5d1SDavid du Colombier 
freeattr(Attr * ap)174*3e12c5d1SDavid du Colombier void freeattr(Attr *ap)	/* free an attribute list */
175*3e12c5d1SDavid du Colombier {
176*3e12c5d1SDavid du Colombier 	Attr *p;
177*3e12c5d1SDavid du Colombier 
178*3e12c5d1SDavid du Colombier 	while (ap) {
179*3e12c5d1SDavid du Colombier 		p = ap->next;	/* save next */
180*3e12c5d1SDavid du Colombier 		if (ap->sval)
181*3e12c5d1SDavid du Colombier 			free(ap->sval);
182*3e12c5d1SDavid du Colombier 		free((char *) ap);
183*3e12c5d1SDavid du Colombier 		ap = p;
184*3e12c5d1SDavid du Colombier 	}
185*3e12c5d1SDavid du Colombier }
186*3e12c5d1SDavid du Colombier 
slprint(Attr * stringlist)187*3e12c5d1SDavid du Colombier char *slprint(Attr *stringlist)	/* print strings from stringlist */
188*3e12c5d1SDavid du Colombier {
189*3e12c5d1SDavid du Colombier 	int ntext, n, last_op, last_just;
190*3e12c5d1SDavid du Colombier 	double last_fval;
191*3e12c5d1SDavid du Colombier 	static char buf[1000];
192*3e12c5d1SDavid du Colombier 	Attr *ap;
193*3e12c5d1SDavid du Colombier 
194*3e12c5d1SDavid du Colombier 	buf[0] = '\0';
195*3e12c5d1SDavid du Colombier 	last_op = last_just = 0;
196*3e12c5d1SDavid du Colombier 	last_fval = 0.0;
197*3e12c5d1SDavid du Colombier 	for (ntext = 0, ap = stringlist; ap != NULL; ap = ap->next)
198*3e12c5d1SDavid du Colombier 		ntext++;
199*3e12c5d1SDavid du Colombier 	sprintf(buf, "box invis wid 0 ht %d*textht", ntext);
200*3e12c5d1SDavid du Colombier 	n = strlen(buf);
201*3e12c5d1SDavid du Colombier 	for (ap = stringlist; ap != NULL; ap = ap->next) {
202*3e12c5d1SDavid du Colombier 		if (ap->op == 0) {	/* propagate last value */
203*3e12c5d1SDavid du Colombier 			ap->op = last_op;
204*3e12c5d1SDavid du Colombier 			ap->fval = last_fval;
205*3e12c5d1SDavid du Colombier 		} else {
206*3e12c5d1SDavid du Colombier 			last_op = ap->op;
207*3e12c5d1SDavid du Colombier 			last_fval = ap->fval;
208*3e12c5d1SDavid du Colombier 		}
209*3e12c5d1SDavid du Colombier 		sprintf(buf+n, " \"%s\"", ps_set || ap->op ? sizeit(ap) : ap->sval);
210*3e12c5d1SDavid du Colombier 		if (ap->just)
211*3e12c5d1SDavid du Colombier 			last_just = ap->just;
212*3e12c5d1SDavid du Colombier 		if (last_just)
213*3e12c5d1SDavid du Colombier 			strcat(buf+n, juststr(last_just));
214*3e12c5d1SDavid du Colombier 		n = strlen(buf);
215*3e12c5d1SDavid du Colombier 	}
216*3e12c5d1SDavid du Colombier 	return buf;	/* watch it:  static */
217*3e12c5d1SDavid du Colombier }
218*3e12c5d1SDavid du Colombier 
juststr(int j)219*3e12c5d1SDavid du Colombier char *juststr(int j)	/* convert RJUST, etc., into string */
220*3e12c5d1SDavid du Colombier {
221*3e12c5d1SDavid du Colombier 	static char buf[50];
222*3e12c5d1SDavid du Colombier 
223*3e12c5d1SDavid du Colombier 	buf[0] = '\0';
224*3e12c5d1SDavid du Colombier 	if (j & RJUST)
225*3e12c5d1SDavid du Colombier 		strcat(buf, " rjust");
226*3e12c5d1SDavid du Colombier 	if (j & LJUST)
227*3e12c5d1SDavid du Colombier 		strcat(buf, " ljust");
228*3e12c5d1SDavid du Colombier 	if (j & ABOVE)
229*3e12c5d1SDavid du Colombier 		strcat(buf, " above");
230*3e12c5d1SDavid du Colombier 	if (j & BELOW)
231*3e12c5d1SDavid du Colombier 		strcat(buf, " below");
232*3e12c5d1SDavid du Colombier 	return buf;	/* watch it:  static */
233*3e12c5d1SDavid du Colombier }
234*3e12c5d1SDavid du Colombier 
sprntf(char * s,Attr * ap)235*3e12c5d1SDavid du Colombier char *sprntf(char *s, Attr *ap)	/* sprintf(s, attrlist ap) */
236*3e12c5d1SDavid du Colombier {
237*3e12c5d1SDavid du Colombier 	char buf[500];
238*3e12c5d1SDavid du Colombier 	int n;
239*3e12c5d1SDavid du Colombier 	Attr *p;
240*3e12c5d1SDavid du Colombier 
241*3e12c5d1SDavid du Colombier 	for (n = 0, p = ap; p; p = p->next)
242*3e12c5d1SDavid du Colombier 		n++;
243*3e12c5d1SDavid du Colombier 	switch (n) {
244*3e12c5d1SDavid du Colombier 	case 0:
245*3e12c5d1SDavid du Colombier 		return s;
246*3e12c5d1SDavid du Colombier 	case 1:
247*3e12c5d1SDavid du Colombier 		sprintf(buf, s, ap->fval);
248*3e12c5d1SDavid du Colombier 		break;
249*3e12c5d1SDavid du Colombier 	case 2:
250*3e12c5d1SDavid du Colombier 		sprintf(buf, s, ap->fval, ap->next->fval);
251*3e12c5d1SDavid du Colombier 		break;
252*3e12c5d1SDavid du Colombier 	case 3:
253*3e12c5d1SDavid du Colombier 		sprintf(buf, s, ap->fval, ap->next->fval, ap->next->next->fval);
254*3e12c5d1SDavid du Colombier 		break;
255*3e12c5d1SDavid du Colombier 	case 5:
256*3e12c5d1SDavid du Colombier 		ERROR "too many expressions in sprintf" WARNING;
257*3e12c5d1SDavid du Colombier 	case 4:
258*3e12c5d1SDavid du Colombier 		sprintf(buf, s, ap->fval, ap->next->fval, ap->next->next->fval, ap->next->next->next->fval);
259*3e12c5d1SDavid du Colombier 		break;
260*3e12c5d1SDavid du Colombier 	}
261*3e12c5d1SDavid du Colombier 	free(s);
262*3e12c5d1SDavid du Colombier 	return tostring(buf);
263*3e12c5d1SDavid du Colombier }
264