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