Blob


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 */
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 */
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 */
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 }
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 }
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 */
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 */
95 void m_finish(void){
96 m_swapbuf();
97 }
98 void m_swapbuf(void){
99 if(offscreen!=screen)
100 draw(screen, offscreen->r, offscreen, nil, offscreen->r.min);
101 flushimage(display, 1);
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;
112 /* Assume colormap entry because
113 * Use cache to avoid repeated allocation.
114 */
115 struct{
116 int v;
117 Image *i;
118 }icache[32];
120 Image*
121 getcolor(int v)
123 Image *i;
124 int j;
126 for(j=0; j<nelem(icache); j++)
127 if(icache[j].v==v && icache[j].i!=nil)
128 return icache[j].i;
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");
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;
142 return i;