char *pan(void) { Point dd, xy, lastxy, min, max; esetcursor(&blot); waitdown(); xy = mouse.xy; do{ lastxy = mouse.xy; mouse = emouse(); dd = subpt(mouse.xy, lastxy); min = addpt(screen->clipr.min, dd); max = addpt(screen->clipr.max, dd); draw(screen, rectaddpt(screen->r, subpt(mouse.xy, lastxy)), screen, nil, screen->r.min); if(mouse.xy.x < lastxy.x) /* moved left, clear right */ draw(screen, Rect(max.x, screen->r.min.y, screen->r.max.x, screen->r.max.y), display->white, nil, ZP); else /* moved right, clear left*/ draw(screen, Rect(screen->r.min.x, screen->r.min.y, min.x, screen->r.max.y), display->white, nil, ZP); if(mouse.xy.y < lastxy.y) /* moved up, clear down */ draw(screen, Rect(screen->r.min.x, max.y, screen->r.max.x, screen->r.max.y), display->white, nil, ZP); else /* moved down, clear up */ draw(screen, Rect(screen->r.min.x, screen->r.min.y, screen->r.max.x, min.y), display->white, nil, ZP); flushimage(display, 1); }while(mouse.buttons); xyoffset = addpt(xyoffset, subpt(mouse.xy, xy)); esetcursor(0); return "p"; }
/* * make rectangle r in widget tk visible if possible; * if not possible, at least make point p visible. */ void tksee(Tk *tk, Rectangle r, Point p) { Point g; //print("tksee %R, %P in %s\n", r, p, tk->name->name); g = Pt(tk->borderwidth, tk->borderwidth); if(tk->parent != nil) { g = addpt(g, tkmethod[tk->parent->type]->relpos(tk)); tk = tk->parent; } else { g.x += tk->act.x; g.y += tk->act.y; tk = tk->master; } r = rectaddpt(r, g); p = addpt(p, g); while (tk != nil) { if (tkmethod[tk->type]->see != nil){ //print("see r %R, p %P in %s\n", r, p, tk->name->name); tkmethod[tk->type]->see(tk, &r, &p); //print("now r %R, p %P\n", r, p); } g = Pt(tk->borderwidth, tk->borderwidth); if (tk->parent != nil) { g = addpt(g, tkmethod[tk->parent->type]->relpos(tk)); tk = tk->parent; } else { g.x += tk->act.x; g.y += tk->act.y; tk = tk->master; } r = rectaddpt(r, g); p = addpt(p, g); } }
static void ldrawop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave) { struct Draw *d; Point p0, p1; Rectangle oclipr, srcr, r, mr; int ok; d = etc; if(insave && d->dstlayer->save==nil) return; p0 = addpt(screenr.min, d->deltas); p1 = addpt(screenr.min, d->deltam); if(insave){ r = rectsubpt(screenr, d->dstlayer->delta); clipr = rectsubpt(clipr, d->dstlayer->delta); }else r = screenr; /* now in logical coordinates */ /* clipr may have narrowed what we should draw on, so clip if necessary */ if(!rectinrect(r, clipr)){ oclipr = dst->clipr; dst->clipr = clipr; ok = drawclip(dst, &r, d->src, &p0, d->mask, &p1, &srcr, &mr); dst->clipr = oclipr; if(!ok) return; } memdraw(dst, r, d->src, p0, d->mask, p1, d->op); }
void drawnub(Image *m, Image *clipr, Point o, Tnode *t) { clipr = nil; if(t->nkid == 0) return; if(t->nkid == -1 && t->expand == nil) return; o.y += (display->defaultfont->height-Nubheight)/2; draw(m, rectaddpt(Rect(0,0,1,Nubheight), o), display->black, clipr, ZP); draw(m, rectaddpt(Rect(0,0,Nubwidth,1), o), display->black, clipr, o); draw(m, rectaddpt(Rect(Nubwidth-1,0,Nubwidth,Nubheight), o), display->black, clipr, addpt(o, Pt(Nubwidth-1, 0))); draw(m, rectaddpt(Rect(0, Nubheight-1, Nubwidth, Nubheight), o), display->black, clipr, addpt(o, Pt(0, Nubheight-1))); draw(m, rectaddpt(Rect(0, Nubheight/2, Nubwidth, Nubheight/2+1), o), display->black, clipr, addpt(o, Pt(0, Nubheight/2))); if(!t->expanded) draw(m, rectaddpt(Rect(Nubwidth/2, 0, Nubwidth/2+1, Nubheight), o), display->black, clipr, addpt(o, Pt(Nubwidth/2, 0))); }
Rectangle imager(Image *i) { Point p1, p2; p1 = addpt(divpt(subpt(i->r.max, i->r.min), 2), i->r.min); p2 = addpt(divpt(subpt(screen->clipr.max, screen->clipr.min), 2), screen->clipr.min); return rectaddpt(i->r, subpt(p2, p1)); }
Memimage* rot90(Memimage *m) { int line, bpp, x, y, dx, dy; ulong chan; uchar *s, *d; Memimage *w; bpp = (m->depth+7)/8; chan = m->chan; switch(chan){ case GREY1: case GREY2: case GREY4: if((w = allocmemimage(m->r, GREY8)) == nil) sysfatal("allocmemimage: %r"); memimagedraw(w, w->r, m, m->r.min, nil, ZP, S); freememimage(m); m = w; break; } dx = Dx(m->r); dy = Dy(m->r); if((w = allocmemimage(Rect(m->r.min.x, m->r.min.y, m->r.min.x+dy, m->r.min.y+dx), m->chan)) == nil) sysfatal("allocmemimage: %r"); line = w->width*sizeof(ulong); for(y=0; y<dy; y++){ s = byteaddr(m, addpt(m->r.min, Pt(0, y))); d = byteaddr(w, addpt(w->r.min, Pt(dy-y-1, 0))); for(x=0; x<dx; x++){ switch(bpp){ case 4: d[3] = s[3]; case 3: d[2] = s[2]; case 2: d[1] = s[1]; case 1: d[0] = s[0]; } s += bpp; d += line; } } freememimage(m); if(w->chan != chan){ if((m = allocmemimage(w->r, chan)) == nil) sysfatal("allocmemimage: %r"); memimagedraw(m, m->r, w, w->r.min, nil, ZP, S); freememimage(w); w = m; } return w; }
void mousethread(void *v) { Point p; Mouse m; int i, n, prev; char buf[100]; ulong rgb; prev = -1; while(readmouse(mousectl) >= 0){ m = mousectl->m; switch(m.buttons){ case 1: while(m.buttons){ if(screen->depth > 8) n = 256; else n = 1<<screen->depth; for(i=0; i!=n; i++) if(i!=prev && ptinrect(m.xy, crect[i])){ if(ramp) rgb = grey(i); else rgb = cmap2rgb(i); sprint(buf, fmt, i, (rgb>>16)&0xFF, (rgb>>8)&0xFF, rgb&0xFF, (rgb<<8) | 0xFF); p = addpt(screen->r.min, Pt(2,2)); draw(screen, Rpt(p, addpt(p, stringsize(font, buf))), display->white, nil, p); string(screen, p, display->black, ZP, font, buf); prev=i; break; } readmouse(mousectl); m = mousectl->m; } break; case 4: switch(menuhit(3, mousectl, &menu, nil)){ case 0: threadexitsall(0); } } } }
void mousewarp(Point pt) { pt = addpt(pt, screen->r.min); if(fprint(mousefd, "m%d %d", pt.x, pt.y) < 0) fprint(2, "mousefd write: %r\n"); }
void drawface(Face *f, int i) { char *tstr; Rectangle r; Point p; if(f == nil) return; if(i<first || i>=last) return; r = facerect(i-first); draw(screen, r, bgrnd, nil, ZP); draw(screen, r, f->bit, f->mask, ZP); r.min.y += Facesize; center(mediumfont, r.min, f->str[Suser], display->black); r.min.y += mediumfont->height; tstr = facetime(f, &f->recent); center(mediumfont, r.min, tstr, display->black); if(f->unknown){ r.min.y -= mediumfont->height + tinyfont->height + 2; for(p.x=-1; p.x<=1; p.x++) for(p.y=-1; p.y<=1; p.y++) center(tinyfont, addpt(r.min, p), f->str[Sdomain], display->white); center(tinyfont, r.min, f->str[Sdomain], display->black); } }
void rect3d(Image *im, Rectangle r, int i, Image **c, Point sp) { Point p[6]; if(i < 0) { r = insetrect(r, i); sp = addpt(sp, Pt(i,i)); i = -i; } draw(im, Rect(r.min.x+i, r.min.y+i, r.max.x-i, r.max.y-i), c[2], nil, sp); p[0] = r.min; p[1] = Pt(r.min.x, r.max.y); p[2] = Pt(r.min.x+i, r.max.y-i); p[3] = Pt(r.min.x+i, r.min.y+i); p[4] = Pt(r.max.x-i, r.min.y+i); p[5] = Pt(r.max.x, r.min.y); fillpoly(im, p, 6, 0, c[0], sp); p[0] = r.max; p[1] = Pt(r.min.x, r.max.y); p[2] = Pt(r.min.x+i, r.max.y-i); p[3] = Pt(r.max.x-i, r.max.y-i); p[4] = Pt(r.max.x-i, r.min.y+i); p[5] = Pt(r.max.x, r.min.y); fillpoly(im, p, 6, 0, c[1], sp); }
void redraw(Image *screen) { Rectangle r; if(im == nil) return; ulrange.max = screen->r.max; ulrange.min = subpt(screen->r.min, Pt(Dx(im->r), Dy(im->r))); ul = pclip(ul, ulrange); drawop(screen, screen->r, im, nil, subpt(im->r.min, subpt(ul, screen->r.min)), S); if(im->repl) return; /* fill in any outer edges */ /* black border */ r = rectaddpt(im->r, subpt(ul, im->r.min)); border(screen, r, -2, display->black, ZP); r.min = subpt(r.min, Pt(2,2)); r.max = addpt(r.max, Pt(2,2)); /* gray for the rest */ if(gray == nil) { gray = xallocimage(display, Rect(0,0,1,1), RGB24, 1, 0x888888FF); if(gray == nil) { fprint(2, "g out of memory: %r\n"); wexits("mem"); } } border(screen, r, -4000, gray, ZP); // flushimage(display, 0); }
/* * A draw operation that touches only the area contained in bot but not in top. * mp and sp get aligned with bot.min. */ static void gendrawdiff(Image *dst, Rectangle bot, Rectangle top, Image *src, Point sp, Image *mask, Point mp, int op) { Rectangle r; Point origin; Point delta; USED(op); if(Dx(bot)*Dy(bot) == 0) return; /* no points in bot - top */ if(rectinrect(bot, top)) return; /* bot - top ≡ bot */ if(Dx(top)*Dy(top)==0 || rectXrect(bot, top)==0){ gendrawop(dst, bot, src, sp, mask, mp, op); return; } origin = bot.min; /* split bot into rectangles that don't intersect top */ /* left side */ if(bot.min.x < top.min.x){ r = Rect(bot.min.x, bot.min.y, top.min.x, bot.max.y); delta = subpt(r.min, origin); gendrawop(dst, r, src, addpt(sp, delta), mask, addpt(mp, delta), op); bot.min.x = top.min.x; } /* right side */ if(bot.max.x > top.max.x){ r = Rect(top.max.x, bot.min.y, bot.max.x, bot.max.y); delta = subpt(r.min, origin); gendrawop(dst, r, src, addpt(sp, delta), mask, addpt(mp, delta), op); bot.max.x = top.max.x; } /* top */ if(bot.min.y < top.min.y){ r = Rect(bot.min.x, bot.min.y, bot.max.x, top.min.y); delta = subpt(r.min, origin); gendrawop(dst, r, src, addpt(sp, delta), mask, addpt(mp, delta), op); bot.min.y = top.min.y; } /* bottom */ if(bot.max.y > top.max.y){ r = Rect(bot.min.x, top.max.y, bot.max.x, bot.max.y); delta = subpt(r.min, origin); gendrawop(dst, r, src, addpt(sp, delta), mask, addpt(mp, delta), op); bot.max.y = top.max.y; } }
static void setbox(int i, int j) { Point loc; loc = Pt(cen.x + j*PX, cen.y + i*PX); draw(screen, Rpt(loc, addpt(loc, Pt(BX, BX))), box, nil, ZP); }
static void clrbox(int i, int j) { Point loc; loc = Pt(cen.x + j*PX, cen.y + i*PX); draw(screen, Rpt(loc, addpt(loc, Pt(BX, BX))), display->white, nil, ZP); }
Rectangle facerect(int index) /* index is geometric; 0 is always upper left face */ { Rectangle r; int x, y; x = index % nacross; y = index / nacross; r.min = addpt(screen->r.min, facep); r.min.x += x*(Facesize+Facesep); r.min.y += y*(Facesize+Facesep+2*mediumfont->height); r.max = addpt(r.min, Pt(Facesize, Facesize)); r.max.y += 2*mediumfont->height; /* simple fix to avoid drawing off screen, allowing customers to use position */ if(index<0 || index>=nacross*ndown) r.max.x = r.min.x; return r; }
void score(int p) { char buf[128]; points += p; snprint(buf, sizeof(buf), "%.6ld", points); draw(screen, Rpt(pscore, addpt(pscore, scoresz)), display->white, nil, ZP); string(screen, pscore, display->black, ZP, font, buf); }
Rectangle tilerect(Click c) { Point p; Rectangle r; p = Pt(c.x*(Facex/2)-(c.d*TileDxy), c.y*(Facey/2)-(c.d*TileDxy)); r = Rpt(p, addpt(p, Pt(Facex, Facey))); return rectaddpt(r, Pt(Depth*TileDxy, Depth*TileDxy)); }
void drawname(Image *scr, Image *col, char *s, int ra, int dec) { Point p; if(font == nil) return; p = addpt(map(ra, dec), Pt(4, -1)); /* font has huge ascent */ string(scr, p, col, ZP, font, s); }
void drawlevel(void) { Point p; int x, y, rx, ry, d; char *s = nil; if(finished) draw(screen, screen->r, finished==Won?won:lost, nil, ZP); else draw(screen, screen->r, bg, nil, ZP); d = (Dx(screen->r) > Dy(screen->r)) ? Dy(screen->r) -20: Dx(screen->r) -20; rx = (int)ceil((float)(d-2*Border)/(float)SzX)/2; ry = (int)ceil((float)(d-2*Border)/(float)SzY)/2; for(x = 0; x < SzX; x++) { for(y = 0; y < SzY; y++) { p = board2pix(x, y); switch(grid[x][y]){ case 999: fillellipse(screen, addpt(screen->r.min, p), rx, ry, cc, ZP); break; case 1000: p = addpt(screen->r.min, p); fillellipse(screen, p, rx, ry, ec, ZP); p = subpt(p, Pt(24, 24)); draw(screen, Rpt(p, addpt(p, Pt(48, 48))), gl, glm, ZP); break; default: fillellipse(screen, addpt(screen->r.min, p), rx, ry, ec, ZP); USED(s); /* uncomment the following to see game state and field scores */ /*s = smprint("%d", grid[x][y]); string(screen, addpt(screen->r.min, p), display->black, ZP, font, s); free(s); */ break; } } } flushimage(display, 1); }
void drawwin(int i) { draw(screen, win[i].r, lightblue, nil, ZP); _string(screen, addpt(win[i].r.min, Pt(2,0)), display->black, ZP, font, win[i].label, nil, strlen(win[i].label), win[i].r, nil, ZP, SoverD); border(screen, win[i].r, 1, display->black, ZP); win[i].dirty = 0; }
Memimage* upsidedown(Memimage *m) { uchar *s, *d, *t; int w, y, dy; dy = Dy(m->r); w = m->width * sizeof(ulong); if((t = malloc(w)) == nil) sysfatal("malloc: %r"); for(y=0; y<dy/2; y++){ s = byteaddr(m, addpt(m->r.min, Pt(0, y))); d = byteaddr(m, addpt(m->r.min, Pt(0, dy-y-1))); memmove(t, d, w); memmove(d, s, w); memmove(s, t, w); } free(t); return m; }
void drawtree(Tree *t, Image *m, Rectangle r) { Point p; draw(m, r, display->white, nil, ZP); replclipr(t->clipr, 1, r); p = addpt(t->offset, r.min); drawnode(t->root, m, t->clipr, p); }
static void screenwin(void) { Point p; char *greet; Memimage *grey; drawqlock(); back = memwhite; conscol = memblack; memfillcolor(gscreen, 0x444488FF); h = memdefont->height; window.min = addpt(gscreen->r.min, Pt(20,20)); window.max.x = window.min.x + Dx(gscreen->r)*3/4-40; window.max.y = window.min.y + Dy(gscreen->r)*3/4-100; memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP, S); window = insetrect(window, 4); memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S); /* a lot of work to get a grey color */ grey = allocmemimage(Rect(0,0,1,1), CMAP8); grey->flags |= Frepl; grey->clipr = gscreen->r; memfillcolor(grey, 0xAAAAAAFF); memimagedraw(gscreen, Rect(window.min.x, window.min.y, window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP, S); freememimage(grey); window = insetrect(window, 5); greet = " Plan 9 Console "; p = addpt(window.min, Pt(10, 0)); memimagestring(gscreen, p, conscol, ZP, memdefont, greet); window.min.y += h+6; curpos = window.min; window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; flushmemscreen(gscreen->r); drawqunlock(); }
void drawbar(void) { int i, j; int p; char buf[400], bar[200]; static char lastbar[200]; if(n > d || n < 0 || d <= 0) return; i = (Dx(rbar)*n)/d; p = (n*100LL)/d; if(textmode){ if(Dx(rbar) > 150){ rbar.min.x = 0; rbar.max.x = 150; return; } bar[0] = '|'; for(j=0; j<i; j++) bar[j+1] = '#'; for(; j<Dx(rbar); j++) bar[j+1] = '-'; bar[j++] = '|'; bar[j++] = ' '; sprint(bar+j, "%3d%% ", p); for(i=0; bar[i]==lastbar[i] && bar[i]; i++) ; memset(buf, '\b', strlen(lastbar)-i); strcpy(buf+strlen(lastbar)-i, bar+i); if(buf[0]) write(1, buf, strlen(buf)); strcpy(lastbar, bar); return; } if(lastp == p && last == i) return; if(lastp != p){ sprint(buf, "%d%%", p); stringbg(screen, addpt(screen->r.min, Pt(Dx(rbar)-30, 4)), text, ZP, display->defaultfont, buf, light, ZP); lastp = p; } if(last != i){ draw(screen, Rect(rbar.min.x+last, rbar.min.y, rbar.min.x+i, rbar.max.y), dark, nil, ZP); last = i; } flushimage(display, 1); }
void geometry(Rectangle r) { int i; Rectangle fr[9]; rramp.min = addpt(r.min, Pt(4,4)); rramp.max = addpt(rramp.min, Pt(256,256)); rbig.min = Pt(rramp.max.x+6, rramp.min.y); rbig.max = addpt(rbig.min, Pt(Dx(orig->r), Dy(orig->r))); for(i=0; i<9; i++) fr[i] = rectaddpt(Rect(0,0,48,48), Pt(rramp.min.x+48+56*(i%3), rramp.max.y+6+56*(i/3))); rsmall = fr[4]; for(i=0; i<4; i++) rface[i] = fr[i]; for(i=4; i<8; i++) rface[i] = fr[i+1]; }
void drawmap(int i) { if(map[i].current) draw(screen, map[i].r, justblue, nil, ZP); else draw(screen, map[i].r, lightblue, nil, ZP); _string(screen, addpt(map[i].r.min, Pt(2,0)), display->black, ZP, font, map[i].name, nil, strlen(map[i].name), map[i].r, nil, ZP, SoverD); border(screen, map[i].r, 1, display->black, ZP); }
int polyOverlap(Point p, Poly * pp, Point q, Poly * qp) { Point op, cp; Point oq, cq; /* translate bounding boxes */ addpt(&op, p, pp->origin); addpt(&cp, p, pp->corner); addpt(&oq, q, qp->origin); addpt(&cq, q, qp->corner); /* If bounding boxes don't overlap, done */ if (!pintersect(op, cp, oq, cq)) return 0; if (ISBOX(pp) && ISBOX(qp)) return 1; if (ISCIRCLE(pp) && ISCIRCLE(qp)) { double d = (pp->corner.x - pp->origin.x + qp->corner.x - qp->origin.x); double dx = p.x - q.x; double dy = p.y - q.y; if ((dx * dx + dy * dy) > (d * d) / 4.0) return 0; else return 1; } if (tp1 == NULL) { tp1 = N_GNEW(maxcnt, Point); tp2 = N_GNEW(maxcnt, Point); } transCopy(pp->verts, pp->nverts, p, tp1); transCopy(qp->verts, qp->nverts, q, tp2); return (edgesIntersect(tp1, tp2, pp->nverts, qp->nverts) || (inBox(*tp1, oq, cq) && inPoly(tp2, qp->nverts, *tp1)) || (inBox(*tp2, op, cp) && inPoly(tp1, pp->nverts, *tp2))); }
static void _bezsplinepts(Plist *l, Point *pt, int npt) { Point *p, *ep; Point a, b, c, d; int periodic; if(npt<3) return; ep = &pt[npt-3]; periodic = eqpt(pt[0], ep[2]); if(periodic){ a = divpt(addpt(ep[1], pt[0]), 2); b = divpt(addpt(ep[1], mulpt(pt[0], 5)), 6); c = divpt(addpt(mulpt(pt[0], 5), pt[1]), 6); d = divpt(addpt(pt[0], pt[1]), 2); bpts(l, a, b, c, d); } for(p=pt; p<=ep; p++){ if(p==pt && !periodic){ a = p[0]; b = divpt(addpt(p[0], mulpt(p[1], 2)), 3); } else{ a = divpt(addpt(p[0], p[1]), 2); b = divpt(addpt(p[0], mulpt(p[1], 5)), 6); } if(p==ep && !periodic){ c = divpt(addpt(mulpt(p[1], 2), p[2]), 3); d = p[2]; } else{ c = divpt(addpt(mulpt(p[1], 5), p[2]), 6); d = divpt(addpt(p[1], p[2]), 2); } bpts(l, a, b, c, d); } appendpt(l, d); }
void drawbar(int digit, int selected) { Rectangle r = Rect((digit - 1)*Square, 0, digit*Square, Square); if(digit < 1 || digit > 9) return; r = insetrect(r, Border); r.max = addpt(r.max, Pt(2, 2)); draw(screen, rectaddpt(r, screen->r.min), selected ? backselect : background, nil, ZP); draw(screen, rectaddpt(r, screen->r.min), display->black, dig[digit-1], ZP); }
void drawscreen(void) { Point l1, l2; int i; draw(screen, screen->r, brdr, nil, ZP); draw(screen, insetrect(screen->r, Border), background, nil, ZP); for(i = 0; i < Brdsize; i++) { l1 = addpt(screen->r.min, Pt(i*Square, Square)); l2 = addpt(screen->r.min, Pt(i*Square, Maxy)); line(screen, l1, l2, Endsquare, Endsquare, (i%3) == 0 ? Thickline : Line, brdr, ZP); l1 = addpt(screen->r.min, Pt(0, (i+1)*Square)); l2 = addpt(screen->r.min, Pt(Maxx, (i+1)*Square)); line(screen, l1, l2, Endsquare, Endsquare, (i%3) == 0 ? Thickline : Line, brdr, ZP); } for(i = 1; i < 10; i++) { drawbar(i, (selected == i) ? 1 : 0); } drawboard(); flushimage(display, 1); }