13e12c5d1SDavid du Colombier #include "mplot.h" 2*7dd7cddfSDavid du Colombier Image *offscreen; 33e12c5d1SDavid du Colombier /* 43e12c5d1SDavid du Colombier * Clear the window from x0, y0 to x1, y1 (inclusive) to color c 53e12c5d1SDavid du Colombier */ 63e12c5d1SDavid du Colombier void m_clrwin(int x0, int y0, int x1, int y1, int c){ 7*7dd7cddfSDavid du Colombier draw(offscreen, Rect(x0, y0, x1+1, y1+1), getcolor(c), nil, ZP); 83e12c5d1SDavid du Colombier } 93e12c5d1SDavid du Colombier /* 103e12c5d1SDavid du Colombier * Draw text between pointers p and q with first character centered at x, y. 113e12c5d1SDavid du Colombier * Use color c. Centered if cen is non-zero, right-justified if right is non-zero. 123e12c5d1SDavid du Colombier * Returns the y coordinate for any following line of text. 133e12c5d1SDavid du Colombier */ 143e12c5d1SDavid du Colombier int m_text(int x, int y, char *p, char *q, int c, int cen, int right){ 153e12c5d1SDavid du Colombier Point tsize; 163e12c5d1SDavid du Colombier USED(c); 17*7dd7cddfSDavid du Colombier tsize=stringsize(font, p); 183e12c5d1SDavid du Colombier if(cen) x -= tsize.x/2; 193e12c5d1SDavid du Colombier else if(right) x -= tsize.x; 20*7dd7cddfSDavid du Colombier stringn(offscreen, Pt(x, y-tsize.y/2), getcolor(c), ZP, font, p, q-p); 213e12c5d1SDavid du Colombier return y+tsize.y; 223e12c5d1SDavid du Colombier } 233e12c5d1SDavid du Colombier /* 243e12c5d1SDavid du Colombier * Draw the vector from x0, y0 to x1, y1 in color c. 253e12c5d1SDavid du Colombier * Clipped by caller 263e12c5d1SDavid du Colombier */ 273e12c5d1SDavid du Colombier void m_vector(int x0, int y0, int x1, int y1, int c){ 28*7dd7cddfSDavid du Colombier line(offscreen, Pt(x0, y0), Pt(x1, y1), Endsquare, Endsquare, 0, getcolor(c), ZP); 293e12c5d1SDavid du Colombier } 30219b2ee8SDavid du Colombier char *scanint(char *s, int *n){ 31219b2ee8SDavid du Colombier while(*s<'0' || '9'<*s){ 32219b2ee8SDavid du Colombier if(*s=='\0'){ 33219b2ee8SDavid du Colombier fprint(2, "plot: bad -Wxmin,ymin,xmax,ymax\n"); 34219b2ee8SDavid du Colombier exits("bad arg"); 35219b2ee8SDavid du Colombier } 36219b2ee8SDavid du Colombier s++; 37219b2ee8SDavid du Colombier } 38219b2ee8SDavid du Colombier *n=0; 39219b2ee8SDavid du Colombier while('0'<=*s && *s<='9'){ 40219b2ee8SDavid du Colombier *n=*n*10+*s-'0'; 41219b2ee8SDavid du Colombier s++; 42219b2ee8SDavid du Colombier } 43219b2ee8SDavid du Colombier return s; 44219b2ee8SDavid du Colombier } 45219b2ee8SDavid du Colombier char *rdenv(char *name){ 46219b2ee8SDavid du Colombier char *v; 47219b2ee8SDavid du Colombier int fd, size; 48219b2ee8SDavid du Colombier fd=open(name, OREAD); 49219b2ee8SDavid du Colombier if(fd<0) return 0; 50219b2ee8SDavid du Colombier size=seek(fd, 0, 2); 51219b2ee8SDavid du Colombier v=malloc(size+1); 52219b2ee8SDavid du Colombier if(v==0){ 53219b2ee8SDavid du Colombier fprint(2, "Can't malloc: %r\n"); 54219b2ee8SDavid du Colombier exits("no mem"); 55219b2ee8SDavid du Colombier } 56219b2ee8SDavid du Colombier seek(fd, 0, 0); 57219b2ee8SDavid du Colombier read(fd, v, size); 58219b2ee8SDavid du Colombier v[size]=0; 59219b2ee8SDavid du Colombier close(fd); 60219b2ee8SDavid du Colombier return v; 61219b2ee8SDavid du Colombier } 623e12c5d1SDavid du Colombier /* 633e12c5d1SDavid du Colombier * Startup initialization 643e12c5d1SDavid du Colombier */ 653e12c5d1SDavid du Colombier void m_initialize(char *s){ 663e12c5d1SDavid du Colombier static int first=1; 673e12c5d1SDavid du Colombier int dx, dy; 683e12c5d1SDavid du Colombier USED(s); 693e12c5d1SDavid du Colombier if(first){ 70*7dd7cddfSDavid du Colombier initdraw(0,0,"plot"); 71*7dd7cddfSDavid du Colombier einit(Emouse); 72*7dd7cddfSDavid du Colombier clipminx=mapminx=screen->r.min.x+4; 73*7dd7cddfSDavid du Colombier clipminy=mapminy=screen->r.min.y+4; 74*7dd7cddfSDavid du Colombier clipmaxx=mapmaxx=screen->r.max.x-5; 75*7dd7cddfSDavid du Colombier clipmaxy=mapmaxy=screen->r.max.y-5; 763e12c5d1SDavid du Colombier dx=clipmaxx-clipminx; 773e12c5d1SDavid du Colombier dy=clipmaxy-clipminy; 783e12c5d1SDavid du Colombier if(dx>dy){ 793e12c5d1SDavid du Colombier mapminx+=(dx-dy)/2; 803e12c5d1SDavid du Colombier mapmaxx=mapminx+dy; 813e12c5d1SDavid du Colombier } 823e12c5d1SDavid du Colombier else{ 833e12c5d1SDavid du Colombier mapminy+=(dy-dx)/2; 843e12c5d1SDavid du Colombier mapmaxy=mapminy+dx; 853e12c5d1SDavid du Colombier } 863e12c5d1SDavid du Colombier first=0; 87*7dd7cddfSDavid du Colombier offscreen = screen; 883e12c5d1SDavid du Colombier } 893e12c5d1SDavid du Colombier } 903e12c5d1SDavid du Colombier /* 913e12c5d1SDavid du Colombier * Clean up when finished 923e12c5d1SDavid du Colombier */ 933e12c5d1SDavid du Colombier void m_finish(void){ 943e12c5d1SDavid du Colombier m_swapbuf(); 953e12c5d1SDavid du Colombier } 963e12c5d1SDavid du Colombier void m_swapbuf(void){ 97*7dd7cddfSDavid du Colombier if(offscreen!=screen) 98*7dd7cddfSDavid du Colombier draw(screen, offscreen->r, offscreen, nil, offscreen->r.min); 99*7dd7cddfSDavid du Colombier flushimage(display, 1); 1003e12c5d1SDavid du Colombier } 1013e12c5d1SDavid du Colombier void m_dblbuf(void){ 102*7dd7cddfSDavid du Colombier if(offscreen==screen){ 103*7dd7cddfSDavid du Colombier offscreen=allocimage(display, insetrect(screen->r, 4), screen->chan, 0, -1); 1043e12c5d1SDavid du Colombier if(offscreen==0){ 1053e12c5d1SDavid du Colombier fprintf(stderr, "Can't double buffer\n"); 106*7dd7cddfSDavid du Colombier offscreen=screen; 1073e12c5d1SDavid du Colombier } 1083e12c5d1SDavid du Colombier } 1093e12c5d1SDavid du Colombier } 110*7dd7cddfSDavid du Colombier /* Assume colormap entry because 111*7dd7cddfSDavid du Colombier * Use cache to avoid repeated allocation. 112*7dd7cddfSDavid du Colombier */ 113*7dd7cddfSDavid du Colombier struct{ 114*7dd7cddfSDavid du Colombier int v; 115*7dd7cddfSDavid du Colombier Image *i; 116*7dd7cddfSDavid du Colombier }icache[32]; 117*7dd7cddfSDavid du Colombier 118*7dd7cddfSDavid du Colombier Image* 119*7dd7cddfSDavid du Colombier getcolor(int v) 120*7dd7cddfSDavid du Colombier { 121*7dd7cddfSDavid du Colombier Image *i; 122*7dd7cddfSDavid du Colombier int j; 123*7dd7cddfSDavid du Colombier 124*7dd7cddfSDavid du Colombier for(j=0; j<nelem(icache); j++) 125*7dd7cddfSDavid du Colombier if(icache[j].v==v && icache[j].i!=nil) 126*7dd7cddfSDavid du Colombier return icache[j].i; 127*7dd7cddfSDavid du Colombier 128*7dd7cddfSDavid du Colombier i = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, v); 129*7dd7cddfSDavid du Colombier if(i == nil){ 130*7dd7cddfSDavid du Colombier fprint(2, "plot: can't allocate image for color: %r\n"); 131*7dd7cddfSDavid du Colombier exits("allocimage"); 132*7dd7cddfSDavid du Colombier } 133*7dd7cddfSDavid du Colombier for(j=0; j<nelem(icache); j++) 134*7dd7cddfSDavid du Colombier if(icache[j].i == nil){ 135*7dd7cddfSDavid du Colombier icache[j].v = v; 136*7dd7cddfSDavid du Colombier icache[j].i = i; 137*7dd7cddfSDavid du Colombier break; 138*7dd7cddfSDavid du Colombier } 139*7dd7cddfSDavid du Colombier 140*7dd7cddfSDavid du Colombier return i; 141*7dd7cddfSDavid du Colombier } 142