machdep.c (3045B)
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); 102 } 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* 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 }