xref: /plan9-contrib/sys/src/cmd/plot/libplot/machdep.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier #include "mplot.h"
2*7dd7cddfSDavid du Colombier Image *offscreen;
33e12c5d1SDavid du Colombier /*
43e12c5d1SDavid du Colombier  * Clear the window from x0, y0 to x1, y1 (inclusive) to color c
53e12c5d1SDavid du Colombier  */
63e12c5d1SDavid du Colombier void m_clrwin(int x0, int y0, int x1, int y1, int c){
7*7dd7cddfSDavid du Colombier 	draw(offscreen, Rect(x0, y0, x1+1, y1+1), getcolor(c), nil, ZP);
83e12c5d1SDavid du Colombier }
93e12c5d1SDavid du Colombier /*
103e12c5d1SDavid du Colombier  * Draw text between pointers p and q with first character centered at x, y.
113e12c5d1SDavid du Colombier  * Use color c.  Centered if cen is non-zero, right-justified if right is non-zero.
123e12c5d1SDavid du Colombier  * Returns the y coordinate for any following line of text.
133e12c5d1SDavid du Colombier  */
143e12c5d1SDavid du Colombier int m_text(int x, int y, char *p, char *q, int c, int cen, int right){
153e12c5d1SDavid du Colombier 	Point tsize;
163e12c5d1SDavid du Colombier 	USED(c);
17*7dd7cddfSDavid du Colombier 	tsize=stringsize(font, p);
183e12c5d1SDavid du Colombier 	if(cen) x -= tsize.x/2;
193e12c5d1SDavid du Colombier 	else if(right) x -= tsize.x;
20*7dd7cddfSDavid du Colombier 	stringn(offscreen, Pt(x, y-tsize.y/2), getcolor(c), ZP, font, p, q-p);
213e12c5d1SDavid du Colombier 	return y+tsize.y;
223e12c5d1SDavid du Colombier }
233e12c5d1SDavid du Colombier /*
243e12c5d1SDavid du Colombier  * Draw the vector from x0, y0 to x1, y1 in color c.
253e12c5d1SDavid du Colombier  * Clipped by caller
263e12c5d1SDavid du Colombier  */
273e12c5d1SDavid du Colombier void m_vector(int x0, int y0, int x1, int y1, int c){
28*7dd7cddfSDavid du Colombier 	line(offscreen, Pt(x0, y0), Pt(x1, y1), Endsquare, Endsquare, 0, getcolor(c), ZP);
293e12c5d1SDavid du Colombier }
30219b2ee8SDavid du Colombier char *scanint(char *s, int *n){
31219b2ee8SDavid du Colombier 	while(*s<'0' || '9'<*s){
32219b2ee8SDavid du Colombier 		if(*s=='\0'){
33219b2ee8SDavid du Colombier 			fprint(2, "plot: bad -Wxmin,ymin,xmax,ymax\n");
34219b2ee8SDavid du Colombier 			exits("bad arg");
35219b2ee8SDavid du Colombier 		}
36219b2ee8SDavid du Colombier 		s++;
37219b2ee8SDavid du Colombier 	}
38219b2ee8SDavid du Colombier 	*n=0;
39219b2ee8SDavid du Colombier 	while('0'<=*s && *s<='9'){
40219b2ee8SDavid du Colombier 		*n=*n*10+*s-'0';
41219b2ee8SDavid du Colombier 		s++;
42219b2ee8SDavid du Colombier 	}
43219b2ee8SDavid du Colombier 	return s;
44219b2ee8SDavid du Colombier }
45219b2ee8SDavid du Colombier char *rdenv(char *name){
46219b2ee8SDavid du Colombier 	char *v;
47219b2ee8SDavid du Colombier 	int fd, size;
48219b2ee8SDavid du Colombier 	fd=open(name, OREAD);
49219b2ee8SDavid du Colombier 	if(fd<0) return 0;
50219b2ee8SDavid du Colombier 	size=seek(fd, 0, 2);
51219b2ee8SDavid du Colombier 	v=malloc(size+1);
52219b2ee8SDavid du Colombier 	if(v==0){
53219b2ee8SDavid du Colombier 		fprint(2, "Can't malloc: %r\n");
54219b2ee8SDavid du Colombier 		exits("no mem");
55219b2ee8SDavid du Colombier 	}
56219b2ee8SDavid du Colombier 	seek(fd, 0, 0);
57219b2ee8SDavid du Colombier 	read(fd, v, size);
58219b2ee8SDavid du Colombier 	v[size]=0;
59219b2ee8SDavid du Colombier 	close(fd);
60219b2ee8SDavid du Colombier 	return v;
61219b2ee8SDavid du Colombier }
623e12c5d1SDavid du Colombier /*
633e12c5d1SDavid du Colombier  * Startup initialization
643e12c5d1SDavid du Colombier  */
653e12c5d1SDavid du Colombier void m_initialize(char *s){
663e12c5d1SDavid du Colombier 	static int first=1;
673e12c5d1SDavid du Colombier 	int dx, dy;
683e12c5d1SDavid du Colombier 	USED(s);
693e12c5d1SDavid du Colombier 	if(first){
70*7dd7cddfSDavid du Colombier 		initdraw(0,0,"plot");
71*7dd7cddfSDavid du Colombier 		einit(Emouse);
72*7dd7cddfSDavid du Colombier 		clipminx=mapminx=screen->r.min.x+4;
73*7dd7cddfSDavid du Colombier 		clipminy=mapminy=screen->r.min.y+4;
74*7dd7cddfSDavid du Colombier 		clipmaxx=mapmaxx=screen->r.max.x-5;
75*7dd7cddfSDavid du Colombier 		clipmaxy=mapmaxy=screen->r.max.y-5;
763e12c5d1SDavid du Colombier 		dx=clipmaxx-clipminx;
773e12c5d1SDavid du Colombier 		dy=clipmaxy-clipminy;
783e12c5d1SDavid du Colombier 		if(dx>dy){
793e12c5d1SDavid du Colombier 			mapminx+=(dx-dy)/2;
803e12c5d1SDavid du Colombier 			mapmaxx=mapminx+dy;
813e12c5d1SDavid du Colombier 		}
823e12c5d1SDavid du Colombier 		else{
833e12c5d1SDavid du Colombier 			mapminy+=(dy-dx)/2;
843e12c5d1SDavid du Colombier 			mapmaxy=mapminy+dx;
853e12c5d1SDavid du Colombier 		}
863e12c5d1SDavid du Colombier 		first=0;
87*7dd7cddfSDavid du Colombier 		offscreen = screen;
883e12c5d1SDavid du Colombier 	}
893e12c5d1SDavid du Colombier }
903e12c5d1SDavid du Colombier /*
913e12c5d1SDavid du Colombier  * Clean up when finished
923e12c5d1SDavid du Colombier  */
933e12c5d1SDavid du Colombier void m_finish(void){
943e12c5d1SDavid du Colombier 	m_swapbuf();
953e12c5d1SDavid du Colombier }
963e12c5d1SDavid du Colombier void m_swapbuf(void){
97*7dd7cddfSDavid du Colombier 	if(offscreen!=screen)
98*7dd7cddfSDavid du Colombier 		draw(screen, offscreen->r, offscreen, nil, offscreen->r.min);
99*7dd7cddfSDavid du Colombier 	flushimage(display, 1);
1003e12c5d1SDavid du Colombier }
1013e12c5d1SDavid du Colombier void m_dblbuf(void){
102*7dd7cddfSDavid du Colombier 	if(offscreen==screen){
103*7dd7cddfSDavid du Colombier 		offscreen=allocimage(display, insetrect(screen->r, 4), screen->chan, 0, -1);
1043e12c5d1SDavid du Colombier 		if(offscreen==0){
1053e12c5d1SDavid du Colombier 			fprintf(stderr, "Can't double buffer\n");
106*7dd7cddfSDavid du Colombier 			offscreen=screen;
1073e12c5d1SDavid du Colombier 		}
1083e12c5d1SDavid du Colombier 	}
1093e12c5d1SDavid du Colombier }
110*7dd7cddfSDavid du Colombier /* Assume colormap entry because
111*7dd7cddfSDavid du Colombier  * Use cache to avoid repeated allocation.
112*7dd7cddfSDavid du Colombier  */
113*7dd7cddfSDavid du Colombier struct{
114*7dd7cddfSDavid du Colombier 	int		v;
115*7dd7cddfSDavid du Colombier 	Image	*i;
116*7dd7cddfSDavid du Colombier }icache[32];
117*7dd7cddfSDavid du Colombier 
118*7dd7cddfSDavid du Colombier Image*
119*7dd7cddfSDavid du Colombier getcolor(int v)
120*7dd7cddfSDavid du Colombier {
121*7dd7cddfSDavid du Colombier 	Image *i;
122*7dd7cddfSDavid du Colombier 	int j;
123*7dd7cddfSDavid du Colombier 
124*7dd7cddfSDavid du Colombier 	for(j=0; j<nelem(icache); j++)
125*7dd7cddfSDavid du Colombier 		if(icache[j].v==v && icache[j].i!=nil)
126*7dd7cddfSDavid du Colombier 			return icache[j].i;
127*7dd7cddfSDavid du Colombier 
128*7dd7cddfSDavid du Colombier 	i = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, v);
129*7dd7cddfSDavid du Colombier 	if(i == nil){
130*7dd7cddfSDavid du Colombier 		fprint(2, "plot: can't allocate image for color: %r\n");
131*7dd7cddfSDavid du Colombier 		exits("allocimage");
132*7dd7cddfSDavid du Colombier 	}
133*7dd7cddfSDavid du Colombier 	for(j=0; j<nelem(icache); j++)
134*7dd7cddfSDavid du Colombier 		if(icache[j].i == nil){
135*7dd7cddfSDavid du Colombier 			icache[j].v = v;
136*7dd7cddfSDavid du Colombier 			icache[j].i = i;
137*7dd7cddfSDavid du Colombier 			break;
138*7dd7cddfSDavid du Colombier 		}
139*7dd7cddfSDavid du Colombier 
140*7dd7cddfSDavid du Colombier 	return i;
141*7dd7cddfSDavid du Colombier }
142