int main(int argc, char const *argv[]) { struct rect r1 = {{1, 1}, {5, 5}}; struct rect r2 = {{2, 3}, {3, 4}}; struct rect r3 = {{2, 3}, {6, 6}}; int ans1 = rectinrect(r2, r1); int ans2 = rectinrect(r3, r1); printf("r2 w r1: %d\n", ans1); printf("r3 w r1: %d\n", ans2); }
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); }
/* * 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; } }
int unloadimage(Image *i, Rectangle r, uchar *data, int ndata) { int bpl, n, chunk, dx, dy; uchar *a, *start; Display *d; if(!rectinrect(r, i->r)) { werrstr("unloadimage: bad rectangle"); return -1; } bpl = bytesperline(r, i->depth); if(ndata < bpl*Dy(r)) { werrstr("unloadimage: buffer too small"); return -1; } start = data; d = i->display; chunk = d->bufsize; flushimage(d, 0); /* make sure subsequent flush is for us only */ while(r.min.y < r.max.y) { dx = Dx(r); dy = chunk/bpl; if(dy <= 0) { dy = 1; dx = ((chunk*dx)/bpl) & ~7; n = bytesperline(Rect(r.min.x, r.min.y, r.min.x+dx, r.min.y+dy), i->depth); if(unloadimage(i, Rect(r.min.x+dx, r.min.y, r.max.x, r.min.y+dy), data+n, bpl-n) < 0) return -1; } else { if(dy > Dy(r)) dy = Dy(r); n = bpl*dy; } a = bufimage(d, 1+4+4*4); if(a == nil) { werrstr("unloadimage: %r"); return -1; } a[0] = 'r'; BPLONG(a+1, i->id); BPLONG(a+5, r.min.x); BPLONG(a+9, r.min.y); BPLONG(a+13, r.min.x+dx); BPLONG(a+17, r.min.y+dy); if(flushimage(d, 0) < 0) return -1; if(read(d->fd, data, n) < 0) return -1; data += bpl*dy; r.min.y += dy; } return data - start; }
int main() { struct rect test1, test2; test1.ll=makepoint(0,0); test1.ur=makepoint(10,10); test2.ll=makepoint(2,2); test2.ur=makepoint(8,8); printf("%d\n",rectinrect(test2,test1)); }
int main(){ struct point a,b,c,d,e,f; a=makepoint(1,3); b=makepoint(3,4); c=makepoint(5,7); d=makepoint(7,9); e=makepoint(9,12); f=makepoint(11,15); struct rect K,L,M; K.ll=b; K.ur=c; L.ll=a; L.ur=d; M.ll=d; M.ur=e; printf("rectinrect(K,L):%d\n",rectinrect(K,L)); printf("rectinrect(K,M):%d\n",rectinrect(K,M)); return 0; }
int loadimage(Image *i, Rectangle r, uchar *data, int ndata) { long dy; int n, bpl; uchar *a; int chunk; chunk = i->display->bufsize - 64; if(!rectinrect(r, i->r)){ werrstr("loadimage: bad rectangle"); return -1; } bpl = bytesperline(r, i->depth); n = bpl*Dy(r); if(n > ndata){ werrstr("loadimage: insufficient data"); return -1; } ndata = 0; while(r.max.y > r.min.y){ dy = r.max.y - r.min.y; if(dy*bpl > chunk) dy = chunk/bpl; if(dy <= 0){ werrstr("loadimage: image too wide for buffer"); return -1; } n = dy*bpl; a = bufimage(i->display, 21+n); if(a == nil){ werrstr("bufimage failed"); return -1; } a[0] = 'y'; BPLONG(a+1, i->id); BPLONG(a+5, r.min.x); BPLONG(a+9, r.min.y); BPLONG(a+13, r.max.x); BPLONG(a+17, r.min.y+dy); memmove(a+21, data, n); ndata += n; data += n; r.min.y += dy; } if(flushimage(i->display, 0) < 0) return -1; return ndata; }
/* * This routine is slow, but safe. It should be improved. */ void b_fill_rect(PixMap pm, Rectangle r, Pixel color) { int x, y; if (!rectinrect(r, pm.r)) return; for (y=r.min.y; y<r.max.y; y++) { Pixel *rp = PIXMAPADDR(pm, r.min.x, y); for (x=r.min.x; x<r.max.x; x++) *rp++ = color; } }
int unloadimage(Image *i, Rectangle r, uchar *data, int ndata) { int bpl, n, ntot, dy; uchar *a; Display *d; if(!rectinrect(r, i->r)){ werrstr("unloadimage: bad rectangle"); return -1; } bpl = bytesperline(r, i->depth); if(ndata < bpl*Dy(r)){ werrstr("unloadimage: buffer too small"); return -1; } d = i->display; flushimage(d, 0); /* make sure subsequent flush is for us only */ ntot = 0; while(r.min.y < r.max.y){ a = bufimage(d, 1+4+4*4); if(a == 0){ werrstr("unloadimage: %r"); return -1; } dy = 8000/bpl; if(dy <= 0){ werrstr("unloadimage: image too wide"); return -1; } if(dy > Dy(r)) dy = Dy(r); a[0] = 'r'; BPLONG(a+1, i->id); BPLONG(a+5, r.min.x); BPLONG(a+9, r.min.y); BPLONG(a+13, r.max.x); BPLONG(a+17, r.min.y+dy); if(flushimage(d, 0) < 0) return -1; n = read(d->fd, data+ntot, ndata-ntot); if(n < 0) return n; ntot += n; r.min.y += dy; } return ntot; }
void _memlsetclear(Memscreen *s) { Memimage *i, *j; Memlayer *l; for(i=s->rearmost; i; i=i->layer->front){ l = i->layer; l->clear = rectinrect(l->screenr, l->screen->image->clipr); if(l->clear) for(j=l->front; j; j=j->layer->front) if(rectXrect(l->screenr, j->layer->screenr)){ l->clear = 0; break; } } }
int cloadimage(Image *i, Rectangle r, uchar *data, int ndata) { int m, nb, miny, maxy, ncblock; uchar *a; if(!rectinrect(r, i->r)){ werrstr("cloadimage: bad rectangle"); return -1; } miny = r.min.y; m = 0; ncblock = _compblocksize(r, i->depth); while(miny != r.max.y){ maxy = atoi((char*)data+0*12); nb = atoi((char*)data+1*12); if(maxy<=miny || r.max.y<maxy){ werrstr("creadimage: bad maxy %d", maxy); return -1; } data += 2*12; ndata -= 2*12; m += 2*12; if(nb<=0 || ncblock<nb || nb>ndata){ werrstr("creadimage: bad count %d", nb); return -1; } a = bufimage(i->display, 21+nb); if(a == nil) return -1; a[0] = 'Y'; BPLONG(a+1, i->id); BPLONG(a+5, r.min.x); BPLONG(a+9, miny); BPLONG(a+13, r.max.x); BPLONG(a+17, maxy); memmove(a+21, data, nb); miny = maxy; data += nb; ndata += nb; m += nb; } return m; }
int unloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) { int y, l; uchar *q; if(!rectinrect(r, i->r)) return -1; l = bytesperline(r, i->depth); if(ndata < l*Dy(r)) return -1; ndata = l*Dy(r); q = byteaddr(i, r.min); for(y=r.min.y; y<r.max.y; y++){ memmove(data, q, l); q += i->width*sizeof(ulong); data += l; } return ndata; }
/* * 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 _cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) { int y, bpl, c, cnt, offs; uchar mem[NMEM], *memp, *omemp, *emem, *linep, *elinep, *u, *eu; if(!rectinrect(r, i->r)) return -1; bpl = bytesperline(r, i->depth); u = data; eu = data+ndata; memp = mem; emem = mem+NMEM; y = r.min.y; linep = byteaddr(i, Pt(r.min.x, y)); elinep = linep+bpl; for(;;){ if(linep == elinep){ if(++y == r.max.y) break; linep = byteaddr(i, Pt(r.min.x, y)); elinep = linep+bpl; } if(u == eu){ /* buffer too small */ return -1; } c = *u++; if(c >= 128){ for(cnt=c-128+1; cnt!=0 ;--cnt){ if(u == eu){ /* buffer too small */ return -1; } if(linep == elinep){ /* phase error */ return -1; } *linep++ = *u; *memp++ = *u++; if(memp == emem) memp = mem; } } else{ if(u == eu) /* short buffer */ return -1; offs = *u++ + ((c&3)<<8)+1; if(memp-mem < offs) omemp = memp+(NMEM-offs); else omemp = memp-offs; for(cnt=(c>>2)+NMATCH; cnt!=0; --cnt){ if(linep == elinep) /* phase error */ return -1; *linep++ = *omemp; *memp++ = *omemp++; if(omemp == emem) omemp = mem; if(memp == emem) memp = mem; } } } return u-data; }
char* tkcvstags(Tk *tk, char *arg, char **val, int af) { TkTop *o; int x, y; TkName *f; TkCtag *t, *tt; char *fmt; TkCpoints p; TkCanvas *c; TkCitem *i, *b; int d, dist, dx, dy; char tag[Tkmaxitem], buf[Tkmaxitem]; char *e; USED(val); c = TKobj(TkCanvas, tk); o = tk->env->top; if(af == TkCadd) { arg = tkword(o, arg, tag, tag+sizeof(tag), nil); if(tag[0] == '\0' || (tag[0] >= '0' && tag[0] <= '9')) return TkBadtg; } fmt = "%d"; arg = tkword(o, arg, buf, buf+sizeof(buf), nil); if(strcmp(buf, "above") == 0) { tkword(o, arg, buf, buf+sizeof(buf), nil); f = tkctaglook(tk, nil, buf); if(f == nil) return TkBadtg; t = tkclasttag(c->head, f->obj); if(t == nil) return TkBadtg; for(i = t->item->next; i; i = i->next) { if(af == TkCadd) { i->tags = tkmkname(tag); if(i->tags == nil) return TkNomem; tkcaddtag(tk, i, 0); } else { e = tkvalue(val, fmt, i->id); if(e != nil) return e; fmt = " %d"; } } return nil; } if(strcmp(buf, "all") == 0) { for(i = c->head; i; i = i->next) { if(af == TkCadd) { i->tags = tkmkname(tag); if(i->tags == nil) return TkNomem; tkcaddtag(tk, i, 0); } else { e = tkvalue(val, fmt, i->id); if(e != nil) return e; fmt = " %d"; } } return nil; } if(strcmp(buf, "below") == 0) { tkword(o, arg, buf, buf+sizeof(buf), nil); f = tkctaglook(tk, nil, buf); if(f == nil) return TkBadtg; tt = f->obj; for(b = c->head; b; b = b->next) { for(t = tt; t; t = t->itemlist) if(t->item == b) goto found; } found: for(i = c->head; i != b; i = i->next) { if(af == TkCadd) { i->tags = tkmkname(tag); if(i->tags == nil) return TkNomem; tkcaddtag(tk, i, 0); } else { e = tkvalue(val, fmt, i->id); if(e != nil) return e; fmt = " %d"; } } return nil; } if(strcmp(buf, "closest") == 0) { e = tkfracword(o, &arg, &x, nil); if (e == nil) e = tkfracword(o, &arg, &y, nil); if (e != nil) return e; if(*arg != '\0') return "!not implemented"; x = TKF2I(x); y = TKF2I(y); i = nil; dist = 0; for(b = c->head; b != nil; b = b->next) { dx = x - (b->p.bb.min.x + Dx(b->p.bb)/2); dy = y - (b->p.bb.min.y + Dy(b->p.bb)/2); d = dx*dx + dy*dy; if(d < dist || dist == 0) { i = b; dist = d; } } if(i == nil) return nil; if(af == TkCadd) { i->tags = tkmkname(tag); if(i->tags == nil) e = TkNomem; else tkcaddtag(tk, i, 0); } else e = tkvalue(val, fmt, i->id); return e; } if(strcmp(buf, "withtag") == 0) { tkword(o, arg, buf, buf+sizeof(buf), nil); f = tkctaglook(tk, nil, buf); if(f == nil) return TkBadtg; for(t = f->obj; t; t = t->taglist) { i = t->item; if(af == TkCadd) { i->tags = tkmkname(tag); if(i->tags == nil) return TkNomem; tkcaddtag(tk, i, 0); } else { e = tkvalue(val, fmt, i->id); if(e != nil) return e; fmt = " %d"; } } return nil; } if(strcmp(buf, "enclosed") == 0) { e = tkparsepts(o, &p, &arg, 0); if(e != nil) goto done; if(p.npoint != 2) { e = TkFewpt; goto done; } for(i = c->head; i; i = i->next) { if(rectinrect(i->p.bb, p.bb)) { if(af == TkCadd) { i->tags = tkmkname(tag); if(i->tags == nil) { e = TkNomem; goto done; } tkcaddtag(tk, i, 0); } else { e = tkvalue(val, fmt, i->id); if(e != nil) goto done; fmt = " %d"; } } } goto done; } if(strcmp(buf, "overlapping") == 0) { e = tkparsepts(o, &p, &arg, 0); if(e != nil) goto done; if(p.npoint != 2) { e = TkFewpt; goto done; } for(i = c->head; i; i = i->next) { if(rectXrect(i->p.bb, p.bb)) { if(af == TkCadd) { i->tags = tkmkname(tag); if(i->tags == nil) { e = TkNomem; goto done; } tkcaddtag(tk, i, 0); } else { e = tkvalue(val, "%d ", i->id); if(e != nil) goto done; } } } goto done; } return TkBadcm; done: /* both no error and error do the same thing */ tkfreepoint(&p); return e; }
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; }
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); }