1 #include "mplot.h"
2 int mapminx, mapminy, mapmaxx, mapmaxy;
3 Image *offscreen;
4 /*
5  * Clear the window from x0, y0 to x1, y1 (inclusive) to color c
6  */
m_clrwin(int x0,int y0,int x1,int y1,int c)7 void m_clrwin(int x0, int y0, int x1, int y1, int c){
8 	draw(offscreen, Rect(x0, y0, x1+1, y1+1), getcolor(c), nil, ZP);
9 }
10 /*
11  * Draw text between pointers p and q with first character centered at x, y.
12  * Use color c.  Centered if cen is non-zero, right-justified if right is non-zero.
13  * Returns the y coordinate for any following line of text.
14  */
m_text(int x,int y,char * p,char * q,int c,int cen,int right)15 int m_text(int x, int y, char *p, char *q, int c, int cen, int right){
16 	Point tsize;
17 	USED(c);
18 	tsize=stringsize(font, p);
19 	if(cen) x -= tsize.x/2;
20 	else if(right) x -= tsize.x;
21 	stringn(offscreen, Pt(x, y-tsize.y/2), getcolor(c), ZP, font, p, q-p);
22 	return y+tsize.y;
23 }
24 /*
25  * Draw the vector from x0, y0 to x1, y1 in color c.
26  * Clipped by caller
27  */
m_vector(int x0,int y0,int x1,int y1,int c)28 void m_vector(int x0, int y0, int x1, int y1, int c){
29 	line(offscreen, Pt(x0, y0), Pt(x1, y1), Endsquare, Endsquare, 0, getcolor(c), ZP);
30 }
scanint(char * s,int * n)31 char *scanint(char *s, int *n){
32 	while(*s<'0' || '9'<*s){
33 		if(*s=='\0'){
34 			fprint(2, "plot: bad -Wxmin,ymin,xmax,ymax\n");
35 			exits("bad arg");
36 		}
37 		s++;
38 	}
39 	*n=0;
40 	while('0'<=*s && *s<='9'){
41 		*n=*n*10+*s-'0';
42 		s++;
43 	}
44 	return s;
45 }
rdenv(char * name)46 char *rdenv(char *name){
47 	char *v;
48 	int fd, size;
49 	fd=open(name, OREAD);
50 	if(fd<0) return 0;
51 	size=seek(fd, 0, 2);
52 	v=malloc(size+1);
53 	if(v==0){
54 		fprint(2, "Can't malloc: %r\n");
55 		exits("no mem");
56 	}
57 	seek(fd, 0, 0);
58 	read(fd, v, size);
59 	v[size]=0;
60 	close(fd);
61 	return v;
62 }
63 /*
64  * Startup initialization
65  */
m_initialize(char * s)66 void m_initialize(char *s){
67 	static int first=1;
68 	int dx, dy;
69 	USED(s);
70 	if(first){
71 		if(initdraw(0,0,"plot") < 0)
72 			sysfatal("plot: can't open display: %r");
73 		einit(Emouse);
74 		clipminx=mapminx=screen->r.min.x+4;
75 		clipminy=mapminy=screen->r.min.y+4;
76 		clipmaxx=mapmaxx=screen->r.max.x-5;
77 		clipmaxy=mapmaxy=screen->r.max.y-5;
78 		dx=clipmaxx-clipminx;
79 		dy=clipmaxy-clipminy;
80 		if(dx>dy){
81 			mapminx+=(dx-dy)/2;
82 			mapmaxx=mapminx+dy;
83 		}
84 		else{
85 			mapminy+=(dy-dx)/2;
86 			mapmaxy=mapminy+dx;
87 		}
88 		first=0;
89 		offscreen = screen;
90 	}
91 }
92 /*
93  * Clean up when finished
94  */
m_finish(void)95 void m_finish(void){
96 	m_swapbuf();
97 }
m_swapbuf(void)98 void m_swapbuf(void){
99 	if(offscreen!=screen)
100 		draw(screen, offscreen->r, offscreen, nil, offscreen->r.min);
101 	flushimage(display, 1);
102 }
m_dblbuf(void)103 void m_dblbuf(void){
104 	if(offscreen==screen){
105 		offscreen=allocimage(display, insetrect(screen->r, 4), screen->chan, 0, -1);
106 		if(offscreen==0){
107 			fprintf(stderr, "Can't double buffer\n");
108 			offscreen=screen;
109 		}
110 	}
111 }
112 /* Assume colormap entry because
113  * Use cache to avoid repeated allocation.
114  */
115 struct{
116 	int		v;
117 	Image	*i;
118 }icache[32];
119 
120 Image*
getcolor(int v)121 getcolor(int v)
122 {
123 	Image *i;
124 	int j;
125 
126 	for(j=0; j<nelem(icache); j++)
127 		if(icache[j].v==v && icache[j].i!=nil)
128 			return icache[j].i;
129 
130 	i = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, v);
131 	if(i == nil){
132 		fprint(2, "plot: can't allocate image for color: %r\n");
133 		exits("allocimage");
134 	}
135 	for(j=0; j<nelem(icache); j++)
136 		if(icache[j].i == nil){
137 			icache[j].v = v;
138 			icache[j].i = i;
139 			break;
140 		}
141 
142 	return i;
143 }
144