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