aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/plot/libplot/machdep.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-04-14 19:54:10 +0000
committerrsc <devnull@localhost>2004-04-14 19:54:10 +0000
commit4314729ddef28cb619ce97d50f0968ca24c93803 (patch)
tree3abd7849a10e842a57b1fd535f8278d22a6bf132 /src/cmd/plot/libplot/machdep.c
parent6e18e03e63942f7b0912bb91d0da02fd493af0af (diff)
downloadplan9port-4314729ddef28cb619ce97d50f0968ca24c93803.tar.gz
plan9port-4314729ddef28cb619ce97d50f0968ca24c93803.tar.bz2
plan9port-4314729ddef28cb619ce97d50f0968ca24c93803.zip
Add graph, plot
Diffstat (limited to 'src/cmd/plot/libplot/machdep.c')
-rw-r--r--src/cmd/plot/libplot/machdep.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/cmd/plot/libplot/machdep.c b/src/cmd/plot/libplot/machdep.c
new file mode 100644
index 00000000..abcb761f
--- /dev/null
+++ b/src/cmd/plot/libplot/machdep.c
@@ -0,0 +1,141 @@
+#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){
+ initdraw(0,0,"plot");
+ 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;
+}