/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "mplot.h"Image *offscreen;/* * Clear the window from x0, y0 to x1, y1 (inclusive) to color c */void m_clrwin(int x0, int y0, int x1, int y1, int c){ draw(offscreen, Rect(x0, y0, x1+1, y1+1), getcolor(c), nil, ZP);}/* * Draw text between pointers p and q with first character centered at x, y. * Use color c. Centered if cen is non-zero, right-justified if right is non-zero. * Returns the y coordinate for any following line of text. */int m_text(int x, int y, char *p, char *q, int c, int cen, int right){ Point tsize; USED(c); tsize=stringsize(font, p); if(cen) x -= tsize.x/2; else if(right) x -= tsize.x; stringn(offscreen, Pt(x, y-tsize.y/2), getcolor(c), ZP, font, p, q-p); return y+tsize.y;}/* * Draw the vector from x0, y0 to x1, y1 in color c. * Clipped by caller */void m_vector(int x0, int y0, int x1, int y1, int c){ line(offscreen, Pt(x0, y0), Pt(x1, y1), Endsquare, Endsquare, 0, getcolor(c), ZP);}char *scanint(char *s, int *n){ while(*s<'0' || '9'<*s){ if(*s=='\0'){ fprint(2, "plot: bad -Wxmin,ymin,xmax,ymax\n"); exits("bad arg"); } s++; } *n=0; while('0'<=*s && *s<='9'){ *n=*n*10+*s-'0'; s++; } return s;}char *rdenv(char *name){ char *v; int fd, size; fd=open(name, OREAD); if(fd<0) return 0; size=seek(fd, 0, 2); v=malloc(size+1); if(v==0){ fprint(2, "Can't malloc: %r\n"); exits("no mem"); } seek(fd, 0, 0); read(fd, v, size); v[size]=0; close(fd); return v;}/* * Startup initialization */void m_initialize(char *s){ static int first=1; int dx, dy; USED(s); if(first){ if(initdraw(0,0,"plot") < 0) sysfatal("initdraw: %r"); einit(Emouse); clipminx=mapminx=screen->r.min.x+4; clipminy=mapminy=screen->r.min.y+4; clipmaxx=mapmaxx=screen->r.max.x-5; clipmaxy=mapmaxy=screen->r.max.y-5; dx=clipmaxx-clipminx; dy=clipmaxy-clipminy; if(dx>dy){ mapminx+=(dx-dy)/2; mapmaxx=mapminx+dy; } else{ mapminy+=(dy-dx)/2; mapmaxy=mapminy+dx; } first=0; offscreen = screen; }}/* * Clean up when finished */void m_finish(void){ m_swapbuf();}void m_swapbuf(void){ if(offscreen!=screen) draw(screen, offscreen->r, offscreen, nil, offscreen->r.min); flushimage(display, 1);}void m_dblbuf(void){ if(offscreen==screen){ offscreen=allocimage(display, insetrect(screen->r, 4), screen->chan, 0, -1); if(offscreen==0){ fprintf(stderr, "Can't double buffer\n"); offscreen=screen; } }}/* Assume colormap entry because * Use cache to avoid repeated allocation. */struct{ int v; Image *i;}icache[32]; Image*getcolor(int v){ Image *i; int j; for(j=0; j<nelem(icache); j++) if(icache[j].v==v && icache[j].i!=nil) return icache[j].i; i = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, v); if(i == nil){ fprint(2, "plot: can't allocate image for color: %r\n"); exits("allocimage"); } for(j=0; j<nelem(icache); j++) if(icache[j].i == nil){ icache[j].v = v; icache[j].i = i; break; } return i;}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#include "mplot.h"
Image *offscreen;
/*
* Clear the window from x0, y0 to x1, y1 (inclusive) to color c
*/
void m_clrwin(int x0, int y0, int x1, int y1, int c){
draw(offscreen, Rect(x0, y0, x1+1, y1+1), getcolor(c), nil, ZP);
}
/*
* Draw text between pointers p and q with first character centered at x, y.
* Use color c. Centered if cen is non-zero, right-justified if right is non-zero.
* Returns the y coordinate for any following line of text.
*/
int m_text(int x, int y, char *p, char *q, int c, int cen, int right){
Point tsize;
USED(c);
tsize=stringsize(font, p);
if(cen) x -= tsize.x/2;
else if(right) x -= tsize.x;
stringn(offscreen, Pt(x, y-tsize.y/2), getcolor(c), ZP, font, p, q-p);
return y+tsize.y;
}
/*
* Draw the vector from x0, y0 to x1, y1 in color c.
* Clipped by caller
*/
void m_vector(int x0, int y0, int x1, int y1, int c){
line(offscreen, Pt(x0, y0), Pt(x1, y1), Endsquare, Endsquare, 0, getcolor(c), ZP);
}
char *scanint(char *s, int *n){
while(*s<'0' || '9'<*s){
if(*s=='\0'){
fprint(2, "plot: bad -Wxmin,ymin,xmax,ymax\n");
exits("bad arg");
}
s++;
}
*n=0;
while('0'<=*s && *s<='9'){
*n=*n*10+*s-'0';
s++;
}
return s;
}
char *rdenv(char *name){
char *v;
int fd, size;
fd=open(name, OREAD);
if(fd<0) return 0;
size=seek(fd, 0, 2);
v=malloc(size+1);
if(v==0){
fprint(2, "Can't malloc: %r\n");
exits("no mem");
}
seek(fd, 0, 0);
read(fd, v, size);
v[size]=0;
close(fd);
return v;
}
/*
* Startup initialization
*/
void m_initialize(char *s){
static int first=1;
int dx, dy;
USED(s);
if(first){
if(initdraw(0,0,"plot") < 0)
sysfatal("initdraw: %r");
einit(Emouse);
clipminx=mapminx=screen->r.min.x+4;
clipminy=mapminy=screen->r.min.y+4;
clipmaxx=mapmaxx=screen->r.max.x-5;
clipmaxy=mapmaxy=screen->r.max.y-5;
dx=clipmaxx-clipminx;
dy=clipmaxy-clipminy;
if(dx>dy){
mapminx+=(dx-dy)/2;
mapmaxx=mapminx+dy;
}
else{
mapminy+=(dy-dx)/2;
mapmaxy=mapminy+dx;
}
first=0;
offscreen = screen;
}
}
/*
* Clean up when finished
*/
void m_finish(void){
m_swapbuf();
}
void m_swapbuf(void){
if(offscreen!=screen)
draw(screen, offscreen->r, offscreen, nil, offscreen->r.min);
flushimage(display, 1);
}
void m_dblbuf(void){
if(offscreen==screen){
offscreen=allocimage(display, insetrect(screen->r, 4), screen->chan, 0, -1);
if(offscreen==0){
fprintf(stderr, "Can't double buffer\n");
offscreen=screen;
}
}
}
/* Assume colormap entry because
* Use cache to avoid repeated allocation.
*/
struct{
int v;
Image *i;
}icache[32];
Image*
getcolor(int v)
{
Image *i;
int j;
for(j=0; j<nelem(icache); j++)
if(icache[j].v==v && icache[j].i!=nil)
return icache[j].i;
i = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, v);
if(i == nil){
fprint(2, "plot: can't allocate image for color: %r\n");
exits("allocimage");
}
for(j=0; j<nelem(icache); j++)
if(icache[j].i == nil){
icache[j].v = v;
icache[j].i = i;
break;
}
return i;
}