void memlexpose(Memimage *i, Rectangle screenr) { if(rectclip(&screenr, i->layer->screen->image->r) == 0) return; _memlayerop(lexposeop, i, screenr, screenr, i->layer); }
int getr(Rectangle *rp) { Point p; Rectangle r; *rp = getrect(3, &mouse); if(rp->max.x && rp->max.x-rp->min.x<=5 && rp->max.y-rp->min.y<=5){ p = rp->min; r = cmd.l[cmd.front].entire; *rp = screen.r; if(cmd.nwin==1){ if (p.y <= r.min.y) rp->max.y = r.min.y; else if (p.y >= r.max.y) rp->min.y = r.max.y; if (p.x <= r.min.x) rp->max.x = r.min.x; else if (p.x >= r.max.x) rp->min.x = r.max.x; } } return rectclip(rp, screen.r) && rp->max.x-rp->min.x>100 && rp->max.y-rp->min.y>40; }
static void vesaflush(VGAscr *scr, Rectangle r) { int t, w, wid, off; uint32_t *hp, *sp, *esp; if(hardscreen == nil) return; if(rectclip(&r, scr->gscreen->r) == 0) return; sp = (uint32_t*)(scr->gscreendata->bdata + scr->gscreen->zero); t = (r.max.x * scr->gscreen->depth + 2*BI2WD-1) / BI2WD; w = (r.min.x * scr->gscreen->depth) / BI2WD; w = (t - w) * BY2WD; wid = scr->gscreen->width; off = r.min.y * wid + (r.min.x * scr->gscreen->depth) / BI2WD; hp = hardscreen; hp += off; sp += off; esp = sp + Dy(r) * wid; while(sp < esp){ memmove(hp, sp, w); hp += wid; sp += wid; } }
void memlhide(Memimage *i, Rectangle screenr) { if(i->layer->save == nil) return; if(rectclip(&screenr, i->layer->screen->image->r) == 0) return; _memlayerop(lhideop, i, screenr, screenr, i->layer); }
Win * newwinsel(int t, Mousectl *mc, File *f) { Rectangle u; u = getrect(3, mc); if(Dx(u) < MINSIZ || Dy(u) < MINSIZ) return nil; rectclip(&u, screen->r); return newwin(t, u, f); }
void drawrampbar(Image *color, State *s) { Rectangle liner, r; static Rectangle br; if(Dx(br)) draw(screen, br, ramp, nil, subpt(br.min, rramp.min)); r = rramp; r.max.x = r.min.x + (int)(s->white*255.0); r.min.x += (int)(s->black*255.0); r.min.y += gamma2y(s->gamma); r.max.y = r.min.y+1; rectclip(&r, rramp); draw(screen, r, color, nil, ZP); br = r; r.min.y -= 2; r.max.y += 2; liner = r; r.min.x += Dx(liner)/3; r.max.x -= Dx(liner)/3; rectclip(&r, rramp); draw(screen, r, color, nil, ZP); combinerect(&br, r); r = liner; r.max.x = r.min.x+3; rectclip(&r, rramp); draw(screen, r, color, nil, ZP); combinerect(&br, r); r = liner; r.min.x = r.max.x-3; rectclip(&r, rramp); draw(screen, r, color, nil, ZP); combinerect(&br, r); }
int clipr(Bitmap *d, Rectangle r) { if(rectclip(&r, d->r) == 0) return 0; d->clipr = r; if(r.min.x != d->r.min.x || r.min.y != d->r.min.y || r.max.x != d->r.max.x || r.max.y != d->r.max.y) d->flag |= CLIP; else d->flag &= ~CLIP; return 1; }
void winresize(Win *w, Mousectl *mc) { Rectangle r; if(w == nil) return; r = getrect(3, mc); if(Dx(r) < MINSIZ || Dy(r) < MINSIZ) return; rectclip(&r, screen->r); freeimage(w->im); w->entire = r; w->inner = insetrect(r, BORDSIZ); w->im = allocwindow(scr, r, Refbackup, 0); draw(w->im, w->inner, w->tab->cols[BACK], nil, ZP); setfocus(w); w->tab->draw(w); }
static void llineop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave) { struct Lline *ll; Point p0, p1; USED(screenr.min.x); ll = etc; if(insave && ll->dstlayer->save==nil) return; if(!rectclip(&clipr, screenr)) return; if(insave){ p0 = subpt(ll->p0, ll->delta); p1 = subpt(ll->p1, ll->delta); clipr = rectsubpt(clipr, ll->delta); }else{ p0 = ll->p0; p1 = ll->p1; } _memline(dst, p0, p1, ll->end0, ll->end1, ll->radius, ll->src, ll->sp, clipr, ll->op); }
/* * Translate the image in the window by delta. */ static void translate(Point delta) { Point u; Rectangle r, or; if(im == nil) return; u = pclip(addpt(ul, delta), ulrange); delta = subpt(u, ul); if(delta.x == 0 && delta.y == 0) return; /* * The upper left corner of the image is currently at ul. * We want to move it to u. */ or = rectaddpt(Rpt(ZP, Pt(Dx(im->r), Dy(im->r))), ul); r = rectaddpt(or, delta); drawop(screen, r, screen, nil, ul, S); ul = u; /* fill in gray where image used to be but isn't. */ drawdiff(screen, insetrect(or, -2), insetrect(r, -2), gray, nil, ZP, S); /* fill in black border */ drawdiff(screen, insetrect(r, -2), r, display->black, nil, ZP, S); /* fill in image where it used to be off the screen. */ if(rectclip(&or, screen->r)) drawdiff(screen, r, rectaddpt(or, delta), im, nil, im->r.min, S); else drawop(screen, r, im, nil, im->r.min, S); flushimage(display, 1); }
static char* tkdrawslaves1(Tk *tk, Point orig, Image *dst, int *dirty) { Tk *f; char *e = nil; Point worig; Rectangle r, oclip; worig.x = orig.x + tk->act.x + tk->borderwidth; worig.y = orig.y + tk->act.y + tk->borderwidth; r = rectaddpt(tk->dirty, worig); if (Dx(r) > 0 && rectXrect(r, dst->clipr)) { e = tkmethod[tk->type]->draw(tk, orig); tk->dirty = bbnil; *dirty = 1; } if(e != nil) return e; /* * grids need clipping * XXX BUG: they can't, 'cos text widgets don't clip appropriately. */ if (tk->grid != nil) { r = rectaddpt(tkrect(tk, 0), worig); if (rectclip(&r, dst->clipr) == 0) return nil; oclip = dst->clipr; replclipr(dst, 0, r); } for(f = tk->slave; e == nil && f; f = f->next) e = tkdrawslaves1(f, worig, dst, dirty); if (tk->grid != nil) replclipr(dst, 0, oclip); return e; }
void tkcvswinddraw(Image *img, TkCitem *i, TkEnv *pe) { TkCwind *w; Point rel; Rectangle r; Tk *sub; USED(img); /* See tkimageof */ USED(pe); w = TKobj(TkCwind, i); sub = w->sub; if(sub != nil) { int dirty; r = i->p.bb; rel.x = r.min.x + sub->borderwidth; rel.y = r.min.y + sub->borderwidth; if (rectclip(&r, img->clipr)) { sub->dirty = rectsubpt(r, rel); sub->flag |= Tkrefresh; tkdrawslaves(sub, ZP, &dirty); /* XXX - Tad: propagate err? */ } } }
/* * Place i so i->r.min = log, i->layer->screenr.min == scr. */ int memlorigin(Memimage *i, Point log, Point scr) { Memlayer *l; Memscreen *s; Memimage *t, *shad, *nsave; Rectangle x, newr, oldr; Point delta; int overlap, eqlog, eqscr, wasclear; l = i->layer; s = l->screen; oldr = l->screenr; newr = Rect(scr.x, scr.y, scr.x+Dx(oldr), scr.y+Dy(oldr)); eqscr = eqpt(scr, oldr.min); eqlog = eqpt(log, i->r.min); if(eqscr && eqlog) return 0; nsave = nil; if(eqlog==0 && l->save!=nil){ nsave = allocmemimage(Rect(log.x, log.y, log.x+Dx(oldr), log.y+Dy(oldr)), i->chan); if(nsave == nil) return -1; } /* * Bring it to front and move logical coordinate system. */ memltofront(i); wasclear = l->clear; if(nsave){ if(!wasclear) memimagedraw(nsave, nsave->r, l->save, l->save->r.min, nil, Pt(0,0), S); freememimage(l->save); l->save = nsave; } delta = subpt(log, i->r.min); i->r = rectaddpt(i->r, delta); i->clipr = rectaddpt(i->clipr, delta); l->delta = subpt(l->screenr.min, i->r.min); if(eqscr) return 0; /* * To clean up old position, make a shadow window there, don't paint it, * push it behind this one, and (later) delete it. Because the refresh function * for this fake window is a no-op, this will cause no graphics action except * to restore the background and expose the windows previously hidden. */ shad = memlalloc(s, oldr, memlnorefresh, nil, DNofill); if(shad == nil) return -1; s->frontmost = i; if(s->rearmost == i) s->rearmost = shad; else l->rear->layer->front = shad; shad->layer->front = i; shad->layer->rear = l->rear; l->rear = shad; l->front = nil; shad->layer->clear = 0; /* * Shadow is now holding down the fort at the old position. * Move the window and hide things obscured by new position. */ for(t=l->rear->layer->rear; t!=nil; t=t->layer->rear){ x = newr; overlap = rectclip(&x, t->layer->screenr); if(overlap){ memlhide(t, x); t->layer->clear = 0; } } l->screenr = newr; l->delta = subpt(scr, i->r.min); l->clear = rectinrect(newr, l->screen->image->clipr); /* * Everything's covered. Copy to new position and delete shadow window. */ if(wasclear) memdraw(s->image, newr, s->image, oldr.min, nil, Pt(0,0), S); else memlexpose(i, newr); memldelete(shad); return 1; }
int main (int argc, char **argv) { char **text,**font,*textcolor,*boxcolor; float size,labelCD=0.0,labelCA,labelCW=0.0,labelCH,bigx,bigy,eps,eps2; float *x; int n,j,nsub; size_t nchar; /* Hook up getpars */ initargs(argc,argv); requestdoc(0); /* Get parameters */ if(!getparint("nsub",&nsub))nsub=0; if(!getparfloat("size",&size))size=30; if(!getparstring("tcolor",&textcolor))textcolor="black"; if(!getparstring("bcolor",&boxcolor))boxcolor="white"; checkpars(); eps=0.25*size; eps2=0.1*size; n=countparname("t"); if(n==0) err("must enter at least one PSTEXT text stream as parameter t"); if(n!=countparname("f")) warn("suggest specify same number of values for t and f"); text =(char **)malloc( (n+1)*sizeof(char *) ); font =(char **)malloc( (n+1)*sizeof(char *) ); x = (float *)malloc( (n+1)*sizeof(float) ); for(bigx=eps,bigy=0.,j=0;j<n;j++){ x[j]=bigx; if(!getnparstring(j+1,"t",&text[j]))text[j]="hello"; if(!getnparstring(j+1,"f",&font[j]))font[j]="Times-Bold"; labelCH = fontheight(font[j],size); labelCW = fontwidth(font[j],size); labelCA = fontascender(font[j],size); labelCD = MIN(labelCD,fontdescender(font[j],size)); nchar = strlen(text[j]); bigx+=0.5*(((double) nchar)*labelCW); bigy=MAX(bigy,labelCH+eps+0.0*labelCA); } bigx+=eps; bigx-=0.5*nsub*labelCW; /* open output eps file */ boundingbox(-eps2,-eps2,bigx+eps2,bigy+eps2); begineps(); gsave(); rectclip(0.,0.,bigx,bigy); /* fill background box with background color */ newpath(); moveto(0.,0.); lineto(bigx,0.); lineto(bigx,bigy); lineto(0.,bigy); closepath(); setcolor(boxcolor); fill(); /* write out text strings */ setcolor(textcolor); moveto(eps,eps-labelCD); for(j=0;j<n;j++) { setfont(font[j],size); show(text[j]); } /* close output stream */ grestore(); showpage(); endeps(); return EXIT_SUCCESS; }
int main (int argc, char **argv) { int n1,n2,n3,i1,i2,i3, n1tic,n2tic,n3tic,grid1,grid2,grid3,nz,iz, faces,style=SEISMIC,bbox[4], npar,nc,nplaces,ic; int labelcf, nlabelc, labelcper; float d1,d2,d3,f1,f2,f3,size1,size2,size3,xbox,ybox,angle, x1min,x1max,x2min,x2max,x3min,x3max, x1beg,x1end,x2beg,x2end,x3beg,x3end, d1num,f1num,d2num,f2num,d3num,f3num, p1beg,p1end,p2beg,p2end,p3beg,p3end, labelsize,titlesize, *z,*zfront,*zside,*ztop,*temp,matrix[6], cwidth[NCMAX],cgray[NCMAX],cdash[NCMAX], dc,fc,*x1,*x2,*x3,c[NCMAX],zmin,zmax, x1scale,x2scale,x3scale; float labelcsize,lcsize,*w,*wfront,*wside,*wtop; char *label1="",*label2="",*label3="",*title="", *labelfont="Helvetica",*titlefont="Helvetica-Bold", *labelcfont="Helvetica-Bold",*labelccolor="black", *grid1s="none",*grid2s="none",*grid3s="none", *titlecolor="black",*axescolor="black",*gridcolor="black", *frontf,*sidef,*topf, *scolor="none",*ccolor[NCMAX]; FILE *infp=stdin,*frontfp,*sidefp,*topfp; /* initialize getpar */ initargs(argc,argv); requestdoc(1); /* get parameters describing 1st dimension sampling */ if (!getparint("n1",&n1)) err("must specify n1!\n"); if (!getparfloat("d1",&d1)) d1 = 1.0; if (!getparfloat("f1",&f1)) f1 = 0.0; x1 = ealloc1float(n1); for (i1=0; i1<n1; i1++) x1[i1] = f1+i1*d1; for (i1=1,x1min=x1max=x1[0]; i1<n1; i1++) { x1min = MIN(x1min,x1[i1]); x1max = MAX(x1max,x1[i1]); } /* get parameters describing 2nd dimension sampling */ if (!getparint("n2",&n2)) err("must specify n2!\n"); if (!getparfloat("d2",&d2)) d2 = 1.0; if (!getparfloat("f2",&f2)) f2 = 0.0; x2 = ealloc1float(n2); for (i2=0; i2<n2; i2++) x2[i2] = f2+i2*d2; for (i2=1,x2min=x2max=x2[0]; i2<n2; i2++) { x2min = MIN(x2min,x2[i2]); x2max = MAX(x2max,x2[i2]); } /* get parameters describing 3rd dimension sampling */ if (!getparint("n3",&n3)) err("must specify n3!\n"); if (n3<2)err("must have n3>=2!"); if (!getparfloat("d3",&d3)) d3 = 1.0; if (!getparfloat("f3",&f3)) f3 = 0.0; x3 = ealloc1float(n3); for (i3=0; i3<n3; i3++) x3[i3] = f3+i3*d3; for (i3=1,x3min=x3max=x3[0]; i3<n3; i3++) { x3min = MIN(x3min,x3[i3]); x3max = MAX(x3max,x3[i3]); } /* determine input type */ if (!getparint("faces",&faces)) faces = 0; /* allocate space */ nz = n1*n2+n1*n3+n2*n3; z = ealloc1float(nz); zfront = z; zside = zfront+n1*n2; ztop = zside+n1*n3; /* read data */ if (getparstring("front",&frontf) && getparstring("side",&sidef) && getparstring("top",&topf)) { /* read face files */ if ((frontfp = fopen(frontf,"r")) == NULL) err("error opening front file!\n"); if (fread(zfront,sizeof(float),n1*n2,frontfp)!=n1*n2) err("error reading front file!\n"); if ((sidefp = fopen(sidef,"r")) == NULL) err("error opening side file!\n"); if (fread(zside,sizeof(float),n1*n3,sidefp)!=n1*n3) err("error reading side file!\n"); if ((topfp = fopen(topf,"r")) == NULL) err("error opening top file!\n"); if (fread(ztop,sizeof(float),n2*n3,topfp)!=n2*n3) err("error reading top file!\n"); } else if (getparstring("front",&frontf) || getparstring("side",&sidef) || getparstring("top",&topf)) { err("must specify all or none of face, side, and top!\n"); } else if (faces) { /* read faces from stdin */ if (fread(zfront,sizeof(float),n1*n2,infp)!=n1*n2) err("error reading front from input!\n"); if (fread(zside,sizeof(float),n1*n3, infp)!=n1*n3) err("error reading side from input!\n"); if (fread(ztop,sizeof(float),n2*n3, infp)!=n2*n3) err("error reading top from input!\n"); } else { /* read cube from stdin, pick off faces */ temp = ealloc1float(n1); for (i3=0; i3<n3; i3++) { for (i2=0; i2<n2; i2++) { if (fread(temp,sizeof(float),n1,infp)!=n1) err("error reading cube from input!\n"); if (i3==0) for (i1=0; i1<n1; i1++) zfront[i1+i2*n1] = temp[i1]; if (i2==n2-1) for (i1=0; i1<n1; i1++) zside[i1+i3*n1] = temp[i1]; ztop[i2+i3*n2] = temp[0]; } } free1float(temp); } /* zero w array for contour labeling */ w = ealloc1float(nz); wfront = w; wside = wfront+n1*n2; wtop = wside+n1*n3; for(iz=0; iz<nz; iz++) w[iz] = 0.; /* determine data min and max */ for (iz=0,zmin=zmax=z[0]; iz<nz; iz++){ zmin = MIN(zmin,z[iz]); zmax = MAX(zmax,z[iz]); } /* get contouring parameters */ if ((nc=getparfloat("c",c))==0) { nc = 5; getparint("nc",&nc); dc = (zmax-zmin)/nc; getparfloat("dc",&dc); fc = zmin+dc; getparfloat("fc",&fc); for (ic=0; ic<nc; ic++) c[ic] = fc+ic*dc; } for (ic=0; ic<nc; ic++) { cwidth[ic] = 1.0; cgray[ic] = 0.0; cdash[ic] = 0.0; ccolor[ic] = scolor; } if ((npar=getparfloat("cwidth",cwidth))!=0) for (ic=npar; ic<nc; ic++) cwidth[ic] = cwidth[npar-1]; if ((npar=getparfloat("cgray",cgray))!=0) for (ic=npar; ic<nc; ic++) cgray[ic] = cgray[npar-1]; if ((npar=getparfloat("cdash",cdash))!=0) for (ic=npar; ic<nc; ic++) cdash[ic] = cdash[npar-1]; if (getparstring("ccolor",&scolor)) { int i,j; char *s; for (i=0,s=strtok(scolor,","); s!=NULL; ++i,s=strtok(NULL,",")) ccolor[i] = s; for (j=i-1; i<nc; ++i) ccolor[i] = ccolor[j]; } labelcf = 1; getparint("labelcf",&labelcf); labelcper = 1; getparint("labelcper",&labelcper); nlabelc = nc; getparint("nlabelc",&nlabelc); labelcsize = 6; getparfloat("labelcsize",&labelcsize); getparstring("labelcfont",&labelcfont); getparstring("labelccolor",&labelccolor); if (!getparint("nplaces",&nplaces)) nplaces = 6; /* get axes parameters, convert to points */ if(!getparfloat("size1",&size1)) size1 = 4.0; if(!getparfloat("size2",&size2)) size2 = 4.0; if(!getparfloat("size3",&size3)) size3 = 3.0; if (!getparfloat("xbox",&xbox)) xbox = 1.5; if (!getparfloat("ybox",&ybox)) ybox = 1.5; size1 *= 72; size2 *= 72; size3 *= 72; xbox *= 72; ybox *= 72; /* get projection angle, convert to radians */ if(!getparfloat("angle",&angle)) angle = 45.0; angle = MAX(angle,0.00001); angle = MIN(angle,90.0); angle *= PI/180.0; /* get axis1 parameters */ x1beg = x1min; x1end = x1max; getparfloat("x1end",&x1end); d1num = 0.0; getparfloat("d1num",&d1num); f1num = x1min; getparfloat("f1num",&f1num); n1tic = 1; getparint("n1tic",&n1tic); getparstring("grid1",&grid1s); if (STREQ("dot",grid1s)) grid1 = DOT; else if (STREQ("dash",grid1s)) grid1 = DASH; else if (STREQ("solid",grid1s)) grid1 = SOLID; else grid1 = NONE; getparstring("label1",&label1); /* get axis2 parameters */ x2beg = x2min; getparfloat("x2beg",&x2beg); x2end = x2max; d2num = 0.0; getparfloat("d2num",&d2num); f2num = x2min; getparfloat("f2num",&f2num); n2tic = 1; getparint("n2tic",&n2tic); getparstring("grid2",&grid2s); if (STREQ("dot",grid2s)) grid2 = DOT; else if (STREQ("dash",grid2s)) grid2 = DASH; else if (STREQ("solid",grid2s)) grid2 = SOLID; else grid2 = NONE; getparstring("label2",&label2); /* get axis3 parameters */ x3beg = x3min; x3end = x3max; getparfloat("x3end",&x3end); d3num = 0.0; getparfloat("d3num",&d3num); f3num = x3min; getparfloat("f3num",&f3num); n3tic = 1; getparint("n3tic",&n3tic); getparstring("grid3",&grid3s); if (STREQ("dot",grid3s)) grid3 = DOT; else if (STREQ("dash",grid3s)) grid3 = DASH; else if (STREQ("solid",grid3s)) grid3 = SOLID; else grid3 = NONE; getparstring("label3",&label3); /* get additional font parameters */ getparstring("labelfont",&labelfont); labelsize = 18.0; getparfloat("labelsize",&labelsize); getparstring("title",&title); getparstring("titlefont",&titlefont); titlesize = 24.0; getparfloat("titlesize",&titlesize); getparstring("titlecolor",&titlecolor); getparstring("axescolor",&axescolor); getparstring("gridcolor",&gridcolor); style = SEISMIC; /* determine axes pads */ p1beg = (x1end>x1beg)?-fabs(d1)/2:fabs(d1)/2; p1end = (x1end>x1beg)?fabs(d1)/2:-fabs(d1)/2; p2beg = (x2end>x2beg)?-fabs(d2)/2:fabs(d2)/2; p2end = (x2end>x2beg)?fabs(d2)/2:-fabs(d2)/2; p3beg = (x3end>x3beg)?-fabs(d3)/2:fabs(d3)/2; p3end = (x3end>x3beg)?fabs(d3)/2:-fabs(d3)/2; /* set bounding box */ psAxesBBox(xbox,ybox,size2+cos(angle)*size3,size1+sin(angle)*size3, labelfont,labelsize,titlefont,titlesize,style,bbox); boundingbox(bbox[0],bbox[1],bbox[2],bbox[3]); /* begin PostScript */ begineps(); /* save graphics state */ gsave(); /* translate coordinate system by box offset */ translate(xbox,ybox); /* begin top */ gsave(); /* determine x2 and x3 scale factors */ x2scale = size2/(x2end-x2beg); x3scale = size3*sin(angle)/(x3end-x3beg); /* scale x2 and x3 coordinates */ for (i2=0; i2<n2; i2++) x2[i2] *= x2scale; for (i3=0; i3<n3; i3++) x3[i3] *= x3scale; /* transform and skew coordinates */ matrix[0] = 1; matrix[1] = 0; matrix[2] = 1/tan(angle); matrix[3] = 1; matrix[4] = 0; matrix[5] = 0; translate(-(f2-x2min+x2beg)*x2scale-f3*x3scale/tan(angle),size1-f3*x3scale); concat(matrix); rectclip(x2beg*x2scale,f3*x3scale,size2,size3*sin(angle)); /* draw contours */ for (ic=0; ic<nc; ic++) { setlinewidth(cwidth[ic]); if (strcmp(ccolor[ic],"none")) setcolor(ccolor[ic]); else setgray(cgray[ic]); if (cdash[ic]!=0.0) setdash(&cdash[ic],1,0.0); else setdash(&cdash[ic],0,0.0); lcsize = 0.; if (nlabelc>0) { if((ic-labelcf+1)%labelcper==0 && ic>=labelcf-1 && ic<labelcf-1+labelcper*nlabelc) { setlinewidth(cwidth[ic]); lcsize = labelcsize; } else { lcsize = 0.; setlinewidth(0.25*cwidth[ic]); } } /* no labels -> lcsize=0 to psContour */ psContour(c[ic],n2,x2,n3,x3,ztop,0,labelcfont,labelccolor,wtop,nplaces); } /* unscale x2 and x3 coordinates */ for (i2=0; i2<n2; i2++) x2[i2] /= x2scale; for (i3=0; i3<n3; i3++) x3[i3] /= x3scale; translate((f2-x2min+x2beg)*x2scale+f3*x3scale/tan(angle),-size1+f3*x3scale); /* end top */ grestore(); /* begin front */ gsave(); /* determine x1 and x2 scale factors */ x1scale = size1/(x1end-x1beg); x2scale = size2/(x2end-x2beg); /* scale x1 and x2 coordinates */ for (i1=0; i1<n1; i1++) x1[i1] *= x1scale; for (i2=0; i2<n2; i2++) x2[i2] *= x2scale; rotate(-90); translate(-size1-f1*x1scale,-(f2-x2min+x2beg)*x2scale); rectclip(size1+f1*x1scale,(f2-x2min+x2beg)*x2scale,-size1,size2); /* draw contours */ for (ic=0; ic<nc; ic++) { setlinewidth(cwidth[ic]); if (strcmp(ccolor[ic],"none")) setcolor(ccolor[ic]); else setgray(cgray[ic]); if (cdash[ic]!=0.0) setdash(&cdash[ic],1,0.0); else setdash(&cdash[ic],0,0.0); lcsize = 0.; if (nlabelc>0) { if((ic-labelcf+1)%labelcper==0 && ic>=labelcf-1 && ic<labelcf-1+labelcper*nlabelc) { setlinewidth(cwidth[ic]); lcsize = labelcsize; } else { lcsize = 0.; setlinewidth(0.25*cwidth[ic]); } } psContour(c[ic],n1,x1,n2,x2,z,lcsize,labelcfont,labelccolor,w,nplaces); } /* unscale x1 and x2 coordinates */ for (i1=0; i1<n1; i1++) x1[i1] /= x1scale; for (i2=0; i2<n2; i2++) x2[i2] /= x2scale; translate(size1+f1*x1scale,(f2-x2min+x2beg)*x2scale); rotate(90); /* end front */ grestore(); /* begin side */ gsave(); /* determine x1 and x3 scale factors */ x1scale = size1/(x1end-x1beg); x3scale = size3*cos(angle)/(x3end-x3beg); /* scale x1 and x3 coordinates */ for (i1=0; i1<n1; i1++) x1[i1] *= x1scale; for (i3=0; i3<n3; i3++) x3[i3] *= x3scale; /* transform and skew coordinates */ matrix[0] = 1; matrix[1] = tan(angle); matrix[2] = 0; matrix[3] = 1; matrix[4] = 0; matrix[5] = 0; translate(size2-f3*x3scale,size1+f1*x1scale-f3*x3scale*tan(angle)); concat(matrix); rectclip(f3*x3scale,-x1end*x1scale,size3*cos(angle),size1); rotate(-90); /* draw contours */ for (ic=0; ic<nc; ic++) { setlinewidth(cwidth[ic]); if (strcmp(ccolor[ic],"none")) setcolor(ccolor[ic]); else setgray(cgray[ic]); if (cdash[ic]!=0.0) setdash(&cdash[ic],1,0.0); else setdash(&cdash[ic],0,0.0); lcsize = 0.; if (nlabelc>0) { if((ic-labelcf+1)%labelcper==0 && ic>=labelcf-1 && ic<labelcf-1+labelcper*nlabelc) { setlinewidth(cwidth[ic]); lcsize = labelcsize; } else { lcsize = 0.; setlinewidth(0.25*cwidth[ic]); } } /* no labels -> lcsize=0 to psContour */ psContour(c[ic],n1,x1,n3,x3,zside,0,labelcfont,labelccolor,wside,nplaces); } /* unscale x1 and x3 coordinates */ for (i1=0; i1<n1; i1++) x1[i1] /= x1scale; for (i3=0; i3<n3; i3++) x3[i3] /= x3scale; rotate(90); translate(-size2+f3*x3scale,-size1-f1*x1scale+f3*x3scale*tan(angle)); /* end side */ grestore(); /* restore graphics state */ grestore(); psCubeAxesBox(xbox,ybox,size1,size2,size3,angle, x1beg,x1end,p1beg,p1end, d1num,f1num,n1tic,grid1,label1, x2beg,x2end,p2beg,p2end, d2num,f2num,n2tic,grid2,label2, x3beg,x3end,p3beg,p3end, d3num,f3num,n3tic,grid3,label3, labelfont,labelsize, title,titlefont,titlesize, titlecolor,axescolor,gridcolor); /* end PostScript */ showpage(); endeps(); return 0; }
void screenload(Rectangle r, int depth, uchar *p, Point pt, int step) { int dx, dy, delx; HDC hdc; RECT winr; if(depth != gscreen->depth) panic("screenload: bad ldepth"); /* * Sometimes we do get rectangles that are off the * screen to the negative axes, for example, when * dragging around a window border in a Move operation. */ if(rectclip(&r, gscreen->r) == 0) return; if((step&3) != 0 || ((pt.x*depth)%32) != 0 || ((ulong)p&3) != 0) panic("screenload: bad params %d %d %ux", step, pt.x, p); dx = r.max.x - r.min.x; dy = r.max.y - r.min.y; if(dx <= 0 || dy <= 0) return; if(depth == 24) delx = r.min.x % 4; else delx = r.min.x & (31/depth); p += (r.min.y-pt.y)*step; p += ((r.min.x-delx-pt.x)*depth)>>3; if(GetWindowRect(window, &winr)==0) return; if(rectclip(&r, Rect(0, 0, winr.right-winr.left, winr.bottom-winr.top))==0) return; lock(&gdilock); hdc = GetDC(window); SelectPalette(hdc, palette, 0); RealizePalette(hdc); //FillRect(hdc,(void*)&r, GetStockObject(BLACK_BRUSH)); //GdiFlush(); //Sleep(100); bmi->bmiHeader.biWidth = (step*8)/depth; bmi->bmiHeader.biHeight = -dy; /* - => origin upper left */ StretchDIBits(hdc, r.min.x, r.min.y, dx, dy, delx, 0, dx, dy, p, bmi, screen.dibtype, SRCCOPY); ReleaseDC(window, hdc); GdiFlush(); unlock(&gdilock); }
void viewer(Document *dd) { int i, fd, n, oldpage; int nxt; Menu menu, midmenu; Mouse m; Event e; Point dxy, oxy, xy0; Image *tmp; static char *fwditems[] = { "this page", "next page", "exit", 0 }; static char *miditems[] = { "orig size", "zoom in", "fit window", "rotate 90", "upside down", "", "next", "prev", "zerox", "", "reverse", "discard", "write", "", "quit", 0 }; char *s; enum { Eplumb = 4 }; Plumbmsg *pm; doc = dd; /* save global for menuhit */ ul = screen->r.min; einit(Emouse|Ekeyboard); if(doc->addpage != nil) eplumb(Eplumb, "image"); esetcursor(&reading); /* * im is a global pointer to the current image. * eventually, i think we will have a layer between * the display routines and the ps/pdf/whatever routines * to perhaps cache and handle images of different * sizes, etc. */ im = 0; page = reverse ? doc->npage-1 : 0; if(doc->fwdonly) { menu.item = fwditems; menu.gen = 0; menu.lasthit = 0; } else { menu.item = 0; menu.gen = menugen; menu.lasthit = 0; } midmenu.item = miditems; midmenu.gen = 0; midmenu.lasthit = Next; if(doc->docname != nil) setlabel(doc->docname); showpage(page, &menu); esetcursor(nil); nxt = 0; for(;;) { /* * throughout, if doc->fwdonly is set, we restrict the functionality * a fair amount. we don't care about doc->npage anymore, and * all that can be done is select the next page. */ unlockdisplay(display); i = eread(Emouse|Ekeyboard|Eplumb, &e); lockdisplay(display); switch(i){ case Ekeyboard: if(e.kbdc <= 0xFF && isdigit(e.kbdc)) { nxt = nxt*10+e.kbdc-'0'; break; } else if(e.kbdc != '\n') nxt = 0; switch(e.kbdc) { case 'r': /* reverse page order */ if(doc->fwdonly) break; reverse = !reverse; menu.lasthit = doc->npage-1-menu.lasthit; /* * the theory is that if we are reversing the * document order and are on the first or last * page then we're just starting and really want * to view the other end. maybe the if * should be dropped and this should happen always. */ if(page == 0 || page == doc->npage-1) { page = doc->npage-1-page; showpage(page, &menu); } break; case 'w': /* write bitmap of current screen */ esetcursor(&reading); s = writebitmap(); if(s) string(screen, addpt(screen->r.min, Pt(5,5)), display->black, ZP, display->defaultfont, s); esetcursor(nil); flushimage(display, 1); break; case 'd': /* remove image from working set */ if(doc->rmpage && page < doc->npage) { if(doc->rmpage(doc, page) >= 0) { if(doc->npage < 0) wexits(0); if(page >= doc->npage) page = doc->npage-1; showpage(page, &menu); } } break; case 'q': case 0x04: /* ctrl-d */ wexits(0); case 'u': if(im==nil) break; angle = (angle+180) % 360; showpage(page, &menu); break; case '-': case '\b': case Kleft: if(page > 0 && !doc->fwdonly) { --page; showpage(page, &menu); } break; case '\n': if(nxt) { nxt--; if(nxt >= 0 && nxt < doc->npage && !doc->fwdonly) showpage(page=nxt, &menu); nxt = 0; break; } goto Gotonext; case Kright: case ' ': Gotonext: if(doc->npage && ++page >= doc->npage && !doc->fwdonly) wexits(0); showpage(page, &menu); break; /* * The upper y coordinate of the image is at ul.y in screen->r. * Panning up means moving the upper left corner down. If the * upper left corner is currently visible, we need to go back a page. */ case Kup: if(screen->r.min.y <= ul.y && ul.y < screen->r.max.y){ if(page > 0 && !doc->fwdonly){ --page; showbottom = 1; showpage(page, &menu); } } else { i = Dy(screen->r)/2; if(i > 10) i -= 10; if(i+ul.y > screen->r.min.y) i = screen->r.min.y - ul.y; translate(Pt(0, i)); } break; /* * If the lower y coordinate is on the screen, we go to the next page. * The lower y coordinate is at ul.y + Dy(im->r). */ case Kdown: i = ul.y + Dy(im->r); if(screen->r.min.y <= i && i <= screen->r.max.y){ ul.y = screen->r.min.y; goto Gotonext; } else { i = -Dy(screen->r)/2; if(i < -10) i += 10; if(i+ul.y+Dy(im->r) <= screen->r.max.y) i = screen->r.max.y - Dy(im->r) - ul.y - 1; translate(Pt(0, i)); } break; default: esetcursor(&query); sleep(1000); esetcursor(nil); break; } break; case Emouse: m = e.mouse; switch(m.buttons){ case Left: oxy = m.xy; xy0 = oxy; do { dxy = subpt(m.xy, oxy); oxy = m.xy; translate(dxy); unlockdisplay(display); m = emouse(); lockdisplay(display); } while(m.buttons == Left); if(m.buttons) { dxy = subpt(xy0, oxy); translate(dxy); } break; case Middle: if(doc->npage == 0) break; unlockdisplay(display); n = emenuhit(Middle, &m, &midmenu); lockdisplay(display); if(n == -1) break; switch(n){ case Next: /* next */ if(reverse) page--; else page++; if(page < 0) { if(reverse) return; else page = 0; } if((page >= doc->npage) && !doc->fwdonly) return; showpage(page, &menu); nxt = 0; break; case Prev: /* prev */ if(reverse) page++; else page--; if(page < 0) { if(reverse) return; else page = 0; } if((page >= doc->npage) && !doc->fwdonly && !reverse) return; showpage(page, &menu); nxt = 0; break; case Zerox: /* prev */ zerox(); break; case Zin: /* zoom in */ { double delta; Rectangle r; r = egetrect(Middle, &m); if((rectclip(&r, rectaddpt(im->r, ul)) == 0) || Dx(r) == 0 || Dy(r) == 0) break; /* use the smaller side to expand */ if(Dx(r) < Dy(r)) delta = (double)Dx(im->r)/(double)Dx(r); else delta = (double)Dy(im->r)/(double)Dy(r); esetcursor(&reading); tmp = xallocimage(display, Rect(0, 0, (int)((double)Dx(im->r)*delta), (int)((double)Dy(im->r)*delta)), im->chan, 0, DBlack); if(tmp == nil) { fprint(2, "out of memory during zoom: %r\n"); wexits("memory"); } resample(im, tmp); im = tmp; delayfreeimage(tmp); esetcursor(nil); ul = screen->r.min; redraw(screen); flushimage(display, 1); break; } case Fit: /* fit */ { double delta; Rectangle r; delta = (double)Dx(screen->r)/(double)Dx(im->r); if((double)Dy(im->r)*delta > Dy(screen->r)) delta = (double)Dy(screen->r)/(double)Dy(im->r); r = Rect(0, 0, (int)((double)Dx(im->r)*delta), (int)((double)Dy(im->r)*delta)); esetcursor(&reading); tmp = xallocimage(display, r, im->chan, 0, DBlack); if(tmp == nil) { fprint(2, "out of memory during fit: %r\n"); wexits("memory"); } resample(im, tmp); im = tmp; delayfreeimage(tmp); esetcursor(nil); ul = screen->r.min; redraw(screen); flushimage(display, 1); break; } case Rot: /* rotate 90 */ angle = (angle+90) % 360; showpage(page, &menu); break; case Upside: /* upside-down */ angle = (angle+180) % 360; showpage(page, &menu); break; case Restore: /* restore */ showpage(page, &menu); break; case Reverse: /* reverse */ if(doc->fwdonly) break; reverse = !reverse; menu.lasthit = doc->npage-1-menu.lasthit; if(page == 0 || page == doc->npage-1) { page = doc->npage-1-page; showpage(page, &menu); } break; case Write: /* write */ esetcursor(&reading); s = writebitmap(); if(s) string(screen, addpt(screen->r.min, Pt(5,5)), display->black, ZP, display->defaultfont, s); esetcursor(nil); flushimage(display, 1); break; case Del: /* delete */ if(doc->rmpage && page < doc->npage) { if(doc->rmpage(doc, page) >= 0) { if(doc->npage < 0) wexits(0); if(page >= doc->npage) page = doc->npage-1; showpage(page, &menu); } } break; case Exit: /* exit */ return; case Empty1: case Empty2: case Empty3: break; }; case Right: if(doc->npage == 0) break; oldpage = page; unlockdisplay(display); n = emenuhit(RMenu, &m, &menu); lockdisplay(display); if(n == -1) break; if(doc->fwdonly) { switch(n){ case 0: /* this page */ break; case 1: /* next page */ showpage(++page, &menu); break; case 2: /* exit */ return; } break; } if(n == doc->npage) return; else page = reverse ? doc->npage-1-n : n; if(oldpage != page) showpage(page, &menu); nxt = 0; break; } break; case Eplumb: pm = e.v; if(pm->ndata <= 0){ plumbfree(pm); break; } if(plumbquit(pm)) exits(nil); if(showdata(pm)) { s = estrdup("/tmp/pageplumbXXXXXXX"); fd = opentemp(s); write(fd, pm->data, pm->ndata); /* lose fd reference on purpose; the file is open ORCLOSE */ } else if(pm->data[0] == '/') { s = estrdup(pm->data); } else { s = emalloc(strlen(pm->wdir)+1+pm->ndata+1); sprint(s, "%s/%s", pm->wdir, pm->data); cleanname(s); } if((i = doc->addpage(doc, s)) >= 0) { page = i; unhide(); showpage(page, &menu); } free(s); plumbfree(pm); break; } } }
char* tkdrawcanv(Tk *tk, Point orig) { Image *dst; TkCitem *i; Display *d; TkCanvas *c; Rectangle r, bufr, oclipr; int vis, alpha, buffer; Point rel, p; TkCimeth *imeth; c = TKobj(TkCanvas, tk); d = tk->env->top->display; dst = tkimageof(tk); /* * translation from local to screen coords */ rel.x = orig.x + tk->act.x + tk->borderwidth; rel.y = orig.y + tk->act.y + tk->borderwidth; buffer = c->buffer; if (buffer == TkCbufauto) buffer = TkCbufvisible; /* buffer = (dst == TKobj(TkWin, tk->env->top->root)->image) ? TkCbufvisible : TkCbufnone; */ if (buffer == TkCbufnone) { if(c->image != nil && c->ialloc) freeimage(c->image); c->image = dst; c->ialloc = 0; r = tkrect(tk, 0); bufr = r; rectclip(&bufr, tk->dirty); oclipr = dst->clipr; replclipr(dst, 0, rectaddpt(bufr, rel)); draw(dst, rectaddpt(bufr, rel), tkgc(tk->env, TkCbackgnd), nil, ZP); p = subpt(rel, c->view); p.x = TKI2F(p.x); p.y = TKI2F(p.y); bufr = rectaddpt(bufr, c->view); for(i = c->head; i; i = i->next) { if(rectXrect(i->p.bb, bufr)) { imeth = &tkcimethod[i->type]; imeth->coord(i, nil, p.x, p.y); imeth->draw(dst, i, tk->env); imeth->coord(i, nil, -p.x, -p.y); } } replclipr(dst, 0, oclipr); } else { if (c->buffer == TkCbufall) bufr = c->region; else { bufr.min = c->view; bufr.max.x = c->view.x + tk->act.width; bufr.max.y = c->view.y + tk->act.height; } alpha = (tk->env->colors[TkCbackgnd] & 0xff) != 0xff; if(c->image == nil || eqrect(bufr, c->image->r) == 0) { if(c->image != nil && c->ialloc) freeimage(c->image); c->image = allocimage(d, bufr, alpha?RGBA32:d->image->chan, 0, tk->env->colors[TkCbackgnd]); c->ialloc = 1; c->update = bufr; tkcvssetdirty(tk); /* unnecessary? */ } if(c->image == nil) return nil; r = c->update; if (rectclip(&r, c->image->r)) { if (alpha) drawop(c->image, c->update, nil, nil, ZP, Clear); draw(c->image, c->update, tkgc(tk->env, TkCbackgnd), nil, c->view); replclipr(c->image, 0, r); for(i = c->head; i; i = i->next) { if(rectXrect(i->p.bb, r)) tkcimethod[i->type].draw(c->image, i, tk->env); } replclipr(c->image, 0, c->image->r); } /* * if the visible area of the canvas image doesn't * fit completely within the dirty rectangle, * then we'll need to draw the background behind it */ r = tkrect(tk, 0); bufr = rectsubpt(bufr, c->view); vis = rectclip(&bufr, tkrect(tk, 0)); if (!vis || !rectinrect(tk->dirty, bufr)) draw(dst, rectaddpt(tk->dirty, rel), tkgc(tk->env, TkCbackgnd), nil, c->view); if (vis && rectclip(&bufr, tk->dirty)) draw(dst, rectaddpt(bufr, rel), c->image, nil, addpt(bufr.min, c->view)); } /* * if the border is dirty too, then draw that */ if (!rectinrect(tk->dirty, bufr)) { r.min = addpt(r.min, rel); r.min.x -= tk->borderwidth; r.min.y -= tk->borderwidth; tkdrawrelief(dst, tk, r.min, TkCbackgnd, tk->relief); } c->update = bbnil; return nil; }
static void _memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr, int op) { Rectangle r; struct Lline ll; Point d; int srcclipped; Memlayer *dl; if(radius < 0) return; if(src->layer) /* can't draw line with layered source */ return; srcclipped = 0; Top: dl = dst->layer; if(dl == nil){ _memimageline(dst, p0, p1, end0, end1, radius, src, sp, clipr, op); return; } if(!srcclipped){ d = subpt(sp, p0); if(rectclip(&clipr, rectsubpt(src->clipr, d)) == 0) return; if((src->flags&Frepl)==0 && rectclip(&clipr, rectsubpt(src->r, d))==0) return; srcclipped = 1; } /* dst is known to be a layer */ p0.x += dl->delta.x; p0.y += dl->delta.y; p1.x += dl->delta.x; p1.y += dl->delta.y; clipr.min.x += dl->delta.x; clipr.min.y += dl->delta.y; clipr.max.x += dl->delta.x; clipr.max.y += dl->delta.y; if(dl->clear){ dst = dst->layer->screen->image; goto Top; } /* XXX */ /* this is not the correct set of tests */ // if(log2[dst->depth] != log2[src->depth] || log2[dst->depth]!=3) // return; /* can't use sutherland-cohen clipping because lines are wide */ r = memlinebbox(p0, p1, end0, end1, radius); /* * r is now a bounding box for the line; * use it as a clipping rectangle for subdivision */ if(rectclip(&r, clipr) == 0) return; ll.p0 = p0; ll.p1 = p1; ll.end0 = end0; ll.end1 = end1; ll.sp = sp; ll.dstlayer = dst->layer; ll.src = src; ll.radius = radius; ll.delta = dl->delta; ll.op = op; _memlayerop(llineop, dst, r, r, &ll); }
void addtorlist(Rlist *rlist, Rectangle r) { int i, j; Rectangle ir, cr, rr; Rlist tmp; if(r.min.x >= r.max.x || r.min.y >= r.max.y) return; memset(&tmp, 0, sizeof tmp); rappend(&tmp, r); if(verbose > 5) fprint(2, "region union add %R:\n", r); combinerect(&rlist->bbox, r); // must do this first for(j = 0; j < tmp.nrect; j++){ r = tmp.rect[j]; for(i=0; i < rlist->nrect; i++){ ir = rlist->rect[i]; if(verbose > 5) fprint(2, "checking %R against %R\n", r, ir); if(!rectadjacent(ir, r)) continue; /* r is covered by ir? */ if(rectinrect(r, ir)) break; /* r covers ir? */ if(rectinrect(ir, r)){ rtrim(rlist, i); i--; continue; } /* aligned and overlapping? */ if((ir.min.y == r.min.y && ir.max.y == r.max.y) || (ir.min.x == r.min.x && ir.max.x == r.max.x)){ combinerect(&r, ir); rtrim(rlist, i); i--; continue; } /* not aligned */ if(verbose > 5) fprint(2, "break up rect %R and %R\n", ir, r); /* 2->2 breakup */ cr = ir; if (!rectclip(&cr, r)) /* share only one point */ continue; if(rectubr(&r, cr)) continue; if(rectubr(&rlist->rect[i], cr)) continue; /* 2 -> 3 breakup */ /* stride across */ if(recttridesubr(&r, cr, &rr)){ rappend(&tmp, rr); continue; } /* corner overlap */ if(rectcornersubr(&r, cr, &rr)){ rappend(&tmp, rr); continue; } abort(); } if(i == rlist->nrect) rappend(rlist, r); } freerlist(&tmp); if(verbose > 5) rprint(rlist); }
/* * It would be fair to say that this doesn't work for >8-bit screens. */ void flushmemscreen(Rectangle r) { VGAscr *scr; unsigned char *sp, *disp, *sdisp, *edisp; int y, len, incs, off, page; scr = &vgascreen[0]; if(scr->dev && scr->dev->flush){ scr->dev->flush(scr, r); return; } if(scr->gscreen == nil || scr->useflush == 0) return; if(scr->dev == nil || scr->dev->page == nil) return; if(rectclip(&r, scr->gscreen->r) == 0) return; incs = scr->gscreen->width * BY2WD; switch(scr->gscreen->depth){ default: len = 0; panic("flushmemscreen: depth\n"); break; case 8: len = Dx(r); break; } if(len < 1) return; off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8; page = off/scr->apsize; off %= scr->apsize; disp = scr->vaddr; sdisp = disp+off; edisp = disp+scr->apsize; off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8; sp = scr->gscreendata->bdata + off; scr->dev->page(scr, page); for(y = r.min.y; y < r.max.y; y++) { if(sdisp + incs < edisp) { memmove(sdisp, sp, len); sp += incs; sdisp += incs; } else { off = edisp - sdisp; page++; if(off <= len){ if(off > 0) memmove(sdisp, sp, off); scr->dev->page(scr, page); if(len - off > 0) memmove(disp, sp+off, len - off); } else { memmove(sdisp, sp, len); scr->dev->page(scr, page); } sp += incs; sdisp += incs - scr->apsize; } } }