#include <lib9.h>#include <draw.h>#include <interp.h>#include <isa.h>#include "../libinterp/runt.h"#include <drawif.h>#include <prefab.h> void icondraw(Prefab_Element*, Image*, Rectangle, int, int);void textdraw(Prefab_Element*, Image*, Rectangle, int, int);void listdraw(Prefab_Element*, Image*, Rectangle, int, int);void outlinehighlight(Prefab_Element*, Image*, Prefab_Compound*, int);void texthighlight(Prefab_Element*, Image*, Prefab_Compound*, int);void simpleclip(Prefab_Element*, Rectangle);void horizontalclip(Prefab_Element*, Rectangle);void verticalclip(Prefab_Element*, Rectangle);void textscroll(Prefab_Element*, Point, int*);void horizontalscroll(Prefab_Element*, Point, int*);void verticalscroll(Prefab_Element*, Point, int*);void iconscroll(Prefab_Element*, Point, int*); struct{ void (*draw)(Prefab_Element*, Image*, Rectangle, int, int); void (*highlight)(Prefab_Element*, Image*, Prefab_Compound*, int); void (*clip)(Prefab_Element*, Rectangle); void (*scroll)(Prefab_Element*, Point, int*);}elemfn[] = { /* EIcon */ { icondraw, outlinehighlight, simpleclip, iconscroll, }, /* EText */ { textdraw, texthighlight, simpleclip, textscroll, }, /* ETitle */ { textdraw, outlinehighlight, simpleclip, textscroll, }, /* EHorizontal */ { listdraw, outlinehighlight, horizontalclip, horizontalscroll, }, /* EVertical */ { listdraw, outlinehighlight, verticalclip, verticalscroll, }, /* ESeparator */ { icondraw, outlinehighlight, simpleclip, iconscroll, },}; Pointiconsize(Image *image){ Point dd; if(image->repl){ dd.x = Dx(image->clipr); dd.y = Dy(image->clipr); }else{ dd.x = Dx(image->r); dd.y = Dy(image->r); } return dd;} voidicondraw(Prefab_Element *elem, Image *i, Rectangle clipr, int clean, int highlight){ Prefab_Style *style; Rectangle r; Point p; PElement *pelem; Image *image, *c; Point size; USED(highlight); pelem = lookupelement(elem); if(pelem == H) return; if(!rectclip(&clipr, i->clipr)) return; R2R(r, elem->r); if(!rectclip(&clipr, r)) return; if(elem->image==H || elem->mask==H || badenviron(elem->environ, 0)) return; style = elem->environ->style; if(!clean){ c = lookupimage(style->elemcolor); if(c != nil) draw(i, clipr, c, nil, clipr.min); } r.min = pelem->drawpt; image = lookupimage(elem->image); if(image == nil) return; size = iconsize(image); r.max.x = r.min.x+size.x; r.max.y = r.min.y+size.y; if(rectclip(&r, clipr)){ p = image->r.min; p.x += r.min.x-pelem->drawpt.x; p.y += r.min.y-pelem->drawpt.y; c = lookupimage(elem->mask); if(c != nil) draw(i, r, image, c, p); }} voidtextdraw(Prefab_Element *elem, Image *i, Rectangle clipr, int clean, int highlight){ Prefab_Style *style; Rectangle r; PElement *pelem; Image *color, *c; Font *font; USED(highlight); pelem = lookupelement(elem); if(pelem == H) return; if(!rectclip(&clipr, i->clipr)) return; R2R(r, elem->r); if(!rectclip(&clipr, r)) return; if(elem->str==H || badenviron(elem->environ, 0)) return; style = elem->environ->style; font = lookupfont(elem->font); if(font == nil) return; if(highlight) color = lookupimage(style->highlightcolor); else color = lookupimage(elem->image); if(!clean){ c = lookupimage(style->elemcolor); if(c != nil) draw(i, clipr, c, nil, clipr.min); } if(color != nil) _string(i, pelem->drawpt, color, pelem->drawpt, font, string2c(elem->str), nil, 1<<24, clipr, nil, pelem->drawpt, SoverD);} voidlistdraw(Prefab_Element *elem, Image *i, Rectangle clipr, int clean, int highlight){ Prefab_Style *style; Prefab_Element *e; List *l; Rectangle r; PElement *pelem; Image *c; pelem = lookupelement(elem); if(pelem == H) return; if(!rectclip(&clipr, i->clipr)) return; R2R(r, elem->r); if(!rectclip(&clipr, r)) return; if(elem->kids==H || badenviron(elem->environ, 0)) return; if(pelem->first != elem->kids) /* error? */ return; style = elem->environ->style; if(!clean){ c = lookupimage(style->elemcolor); if(c != nil) draw(i, clipr, c, nil, clipr.min); } for(l=pelem->vfirst; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; R2R(r, e->r); if(rectXrect(r, clipr)) drawelement(e, i, clipr, elem->environ==e->environ, highlight); if(l == pelem->vlast) break; }} voiddrawelement(Prefab_Element *elem, Image *i, Rectangle clipr, int clean, int highlight){ PElement *pelem; if(elem != H){ pelem = lookupelement(elem); if(pelem == H) return; (*elemfn[elem->kind].draw)(elem, i, clipr, clean, highlight); if(!highlight && pelem->highlight!=H) (*elemfn[elem->kind].highlight)(elem, i, pelem->highlight, 1); }} voidtranslateelement(Prefab_Element *elem, Point delta){ PElement *pelem; List *l; if(elem == H) return; pelem = lookupelement(elem); if(pelem == H) return; elem->r.min.x += delta.x; elem->r.min.y += delta.y; elem->r.max.x += delta.x; elem->r.max.y += delta.y; pelem->drawpt.x += delta.x; pelem->drawpt.y += delta.y; switch(elem->kind){ case EHorizontal: case EVertical: if(pelem->first != elem->kids) return; for(l=elem->kids; l!=H; l=l->tail) translateelement(*(Prefab_Element**)l->data, delta); break; }} intfitrect(Rectangle *r, Rectangle sr){ if(r->max.x > sr.max.x){ r->min.x -= r->max.x-sr.max.x; r->max.x = sr.max.x; } if(r->max.y > sr.max.y){ r->min.y -= r->max.y-sr.max.y; r->max.y = sr.max.y; } if(r->min.x < sr.min.x){ r->max.x += sr.min.x-r->min.x; r->min.x = sr.min.x; } if(r->min.y < sr.min.y){ r->max.y += sr.min.y-r->min.y; r->min.y = sr.min.y; } return rectinrect(*r, sr);} voidadjusthorizontal(Prefab_Element *elem, int spacing, int position){ int edx, dx, i, x; int nlist; /* BUG: should precompute */ List *l; PElement *pelem; Prefab_Element *e; Point p; pelem = lookupelement(elem); if(pelem == H) return; if(pelem->first != elem->kids) return; p.y = 0; switch(spacing){ default: /* shouldn't happen; protected by adjustelement */ case Adjpack: x = elem->r.min.x; for(l=elem->kids; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; p.x = x - e->r.min.x; translateelement(e, p); x += Dx(e->r); } elem->r.max.x = x; return; case Adjequal: dx = 0; nlist = 0; for(l=elem->kids; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; if(dx < Dx(e->r)) dx = Dx(e->r); nlist++; } elem->r.max.x = elem->r.min.x+nlist*dx; break; case Adjfill: nlist = 0; for(l=elem->kids; l!=H; l=l->tail) nlist++; dx = Dx(elem->r)/nlist; break; } i = 0; for(l=elem->kids; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; edx = Dx(e->r); if(position == Adjleft) edx = 0; else if(position == Adjcenter) edx = (dx-edx)/2; else /* right */ edx = dx-edx; p.x = (elem->r.min.x+i*dx + edx) - e->r.min.x; translateelement(e, p); i++; }} voidadjustvertical(Prefab_Element *elem, int spacing, int position){ int edy, dy, i, y; int nlist; /* BUG: should precompute */ List *l; PElement *pelem; Prefab_Element *e; Point p; pelem = lookupelement(elem); if(pelem == H) return; if(pelem->first != elem->kids) return; p.x = 0; switch(spacing){ default: /* shouldn't happen; protected by adjustelement */ case Adjpack: y = elem->r.min.y; for(l=elem->kids; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; p.y = y - e->r.min.y; translateelement(e, p); y += Dy(e->r); } elem->r.max.y = y; return; case Adjequal: dy = 0; nlist = 0; for(l=elem->kids; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; if(dy < Dy(e->r)) dy = Dy(e->r); nlist++; } elem->r.max.y = elem->r.min.y+nlist*dy; break; case Adjfill: nlist = 0; for(l=elem->kids; l!=H; l=l->tail) nlist++; dy = Dy(elem->r)/nlist; break; } i = 0; for(l=elem->kids; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; edy = Dy(e->r); if(position == Adjup) edy = 0; else if(position == Adjcenter) edy = (dy-edy)/2; else /* down */ edy = dy-edy; p.y = (elem->r.min.y+i*dy + edy) - e->r.min.y; translateelement(e, p); i++; }} voidadjustelement(Prefab_Element *elem, int spacing, int position){ if(lookupelement(elem) == H) return; if(spacing<Adjpack || spacing>Adjfill || position<Adjleft || position>Adjdown) return; switch(elem->kind){ case EVertical: adjustvertical(elem, spacing, position); break; case EHorizontal: adjusthorizontal(elem, spacing, position); break; }} voidhighlightelement(Prefab_Element *elem, Image *i, Prefab_Compound *comp, int on){ PElement *pelem; pelem = lookupelement(elem); if(pelem!=H && lookupcompound(comp)!=H){ if(on) pelem->highlight = comp; else pelem->highlight = H; (*elemfn[elem->kind].highlight)(elem, i, comp, on); }} staticintanytextelements(Prefab_Element *e){ Prefab_Element *t; List *l; for(l=e->kids; l!=H; l=l->tail){ t = *(Prefab_Element**)l->data; if(t->kind == EText) return 1; } return 0;} voidtextlisthighlight(Prefab_Element *e, Image *i, Prefab_Compound *c, int on){ Prefab_Element *t; List *l; for(l=e->kids; l!=H; l=l->tail){ t = *(Prefab_Element**)l->data; if(t->kind == EText) texthighlight(t, i, c, on); }} voidoutlinehighlight(Prefab_Element *e, Image *i, Prefab_Compound *c, int on){ List *l; Prefab_Element *t; Image *color; Rectangle r, r1, r2; Point dp; int done; /* see if we can do it by highlighting just a text element */ if((e->kind==EVertical || e->kind==EHorizontal) && e->kids!=H){ /* is any child a text element? */ if(anytextelements(e)){ textlisthighlight(e, i, c, on); return; } /* grandchild? */ done = 0; for(l=e->kids; l!=H; l=l->tail){ t = *(Prefab_Element**)l->data; if(t->kind==EVertical || t->kind==EHorizontal) if(anytextelements(t)){ textlisthighlight(t, i, c, on); done = 1; } } if(done) return; } if(on){ color = lookupimage(e->environ->style->highlightcolor); if(color == nil) return; R2R(r, e->r); /* avoid outlining empty space around images */ dp = ((PElement*)e)->drawpt; if(e->kind==EIcon && e->image->repl==0 && ptinrect(dp, r)){ R2R(r1, e->image->r); R2R(r2, e->image->clipr); if(rectclip(&r1, r2)){ dp.x += Dx(r1); dp.y += Dy(r1); if(ptinrect(dp, r)) r = Rpt(((PElement*)e)->drawpt, dp); } } draw(i, r, color, nil, r.min); drawelement(e, i, insetrect(r, 2), Dirty, 1); }else{ drawelement(e, i, IRECT(e->r), Dirty, 0); edge(c->environ, i, c->r, e->r); }} voidtexthighlight(Prefab_Element *e, Image *i, Prefab_Compound *c, int on){ drawelement(e, i, IRECT(e->r), Clean, on); edge(c->environ, i, c->r, e->r);} voidclipelement(Prefab_Element *elem, Rectangle r){ if(lookupelement(elem) != H) (*elemfn[elem->kind].clip)(elem, r);} voidsimpleclip(Prefab_Element *elem, Rectangle r){ R2R(elem->r, r);} voidLines 1–500 of 723. Load more
#include <lib9.h> #include <draw.h> #include <interp.h> #include <isa.h> #include "../libinterp/runt.h" #include <drawif.h> #include <prefab.h> void icondraw(Prefab_Element*, Image*, Rectangle, int, int); void textdraw(Prefab_Element*, Image*, Rectangle, int, int); void listdraw(Prefab_Element*, Image*, Rectangle, int, int); void outlinehighlight(Prefab_Element*, Image*, Prefab_Compound*, int); void texthighlight(Prefab_Element*, Image*, Prefab_Compound*, int); void simpleclip(Prefab_Element*, Rectangle); void horizontalclip(Prefab_Element*, Rectangle); void verticalclip(Prefab_Element*, Rectangle); void textscroll(Prefab_Element*, Point, int*); void horizontalscroll(Prefab_Element*, Point, int*); void verticalscroll(Prefab_Element*, Point, int*); void iconscroll(Prefab_Element*, Point, int*); struct { void (*draw)(Prefab_Element*, Image*, Rectangle, int, int); void (*highlight)(Prefab_Element*, Image*, Prefab_Compound*, int); void (*clip)(Prefab_Element*, Rectangle); void (*scroll)(Prefab_Element*, Point, int*); }elemfn[] = { /* EIcon */ { icondraw, outlinehighlight, simpleclip, iconscroll, }, /* EText */ { textdraw, texthighlight, simpleclip, textscroll, }, /* ETitle */ { textdraw, outlinehighlight, simpleclip, textscroll, }, /* EHorizontal */ { listdraw, outlinehighlight, horizontalclip, horizontalscroll, }, /* EVertical */ { listdraw, outlinehighlight, verticalclip, verticalscroll, }, /* ESeparator */ { icondraw, outlinehighlight, simpleclip, iconscroll, }, }; Point iconsize(Image *image) { Point dd; if(image->repl){ dd.x = Dx(image->clipr); dd.y = Dy(image->clipr); }else{ dd.x = Dx(image->r); dd.y = Dy(image->r); } return dd; } void icondraw(Prefab_Element *elem, Image *i, Rectangle clipr, int clean, int highlight) { Prefab_Style *style; Rectangle r; Point p; PElement *pelem; Image *image, *c; Point size; USED(highlight); pelem = lookupelement(elem); if(pelem == H) return; if(!rectclip(&clipr, i->clipr)) return; R2R(r, elem->r); if(!rectclip(&clipr, r)) return; if(elem->image==H || elem->mask==H || badenviron(elem->environ, 0)) return; style = elem->environ->style; if(!clean){ c = lookupimage(style->elemcolor); if(c != nil) draw(i, clipr, c, nil, clipr.min); } r.min = pelem->drawpt; image = lookupimage(elem->image); if(image == nil) return; size = iconsize(image); r.max.x = r.min.x+size.x; r.max.y = r.min.y+size.y; if(rectclip(&r, clipr)){ p = image->r.min; p.x += r.min.x-pelem->drawpt.x; p.y += r.min.y-pelem->drawpt.y; c = lookupimage(elem->mask); if(c != nil) draw(i, r, image, c, p); } } void textdraw(Prefab_Element *elem, Image *i, Rectangle clipr, int clean, int highlight) { Prefab_Style *style; Rectangle r; PElement *pelem; Image *color, *c; Font *font; USED(highlight); pelem = lookupelement(elem); if(pelem == H) return; if(!rectclip(&clipr, i->clipr)) return; R2R(r, elem->r); if(!rectclip(&clipr, r)) return; if(elem->str==H || badenviron(elem->environ, 0)) return; style = elem->environ->style; font = lookupfont(elem->font); if(font == nil) return; if(highlight) color = lookupimage(style->highlightcolor); else color = lookupimage(elem->image); if(!clean){ c = lookupimage(style->elemcolor); if(c != nil) draw(i, clipr, c, nil, clipr.min); } if(color != nil) _string(i, pelem->drawpt, color, pelem->drawpt, font, string2c(elem->str), nil, 1<<24, clipr, nil, pelem->drawpt, SoverD); } void listdraw(Prefab_Element *elem, Image *i, Rectangle clipr, int clean, int highlight) { Prefab_Style *style; Prefab_Element *e; List *l; Rectangle r; PElement *pelem; Image *c; pelem = lookupelement(elem); if(pelem == H) return; if(!rectclip(&clipr, i->clipr)) return; R2R(r, elem->r); if(!rectclip(&clipr, r)) return; if(elem->kids==H || badenviron(elem->environ, 0)) return; if(pelem->first != elem->kids) /* error? */ return; style = elem->environ->style; if(!clean){ c = lookupimage(style->elemcolor); if(c != nil) draw(i, clipr, c, nil, clipr.min); } for(l=pelem->vfirst; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; R2R(r, e->r); if(rectXrect(r, clipr)) drawelement(e, i, clipr, elem->environ==e->environ, highlight); if(l == pelem->vlast) break; } } void drawelement(Prefab_Element *elem, Image *i, Rectangle clipr, int clean, int highlight) { PElement *pelem; if(elem != H){ pelem = lookupelement(elem); if(pelem == H) return; (*elemfn[elem->kind].draw)(elem, i, clipr, clean, highlight); if(!highlight && pelem->highlight!=H) (*elemfn[elem->kind].highlight)(elem, i, pelem->highlight, 1); } } void translateelement(Prefab_Element *elem, Point delta) { PElement *pelem; List *l; if(elem == H) return; pelem = lookupelement(elem); if(pelem == H) return; elem->r.min.x += delta.x; elem->r.min.y += delta.y; elem->r.max.x += delta.x; elem->r.max.y += delta.y; pelem->drawpt.x += delta.x; pelem->drawpt.y += delta.y; switch(elem->kind){ case EHorizontal: case EVertical: if(pelem->first != elem->kids) return; for(l=elem->kids; l!=H; l=l->tail) translateelement(*(Prefab_Element**)l->data, delta); break; } } int fitrect(Rectangle *r, Rectangle sr) { if(r->max.x > sr.max.x){ r->min.x -= r->max.x-sr.max.x; r->max.x = sr.max.x; } if(r->max.y > sr.max.y){ r->min.y -= r->max.y-sr.max.y; r->max.y = sr.max.y; } if(r->min.x < sr.min.x){ r->max.x += sr.min.x-r->min.x; r->min.x = sr.min.x; } if(r->min.y < sr.min.y){ r->max.y += sr.min.y-r->min.y; r->min.y = sr.min.y; } return rectinrect(*r, sr); } void adjusthorizontal(Prefab_Element *elem, int spacing, int position) { int edx, dx, i, x; int nlist; /* BUG: should precompute */ List *l; PElement *pelem; Prefab_Element *e; Point p; pelem = lookupelement(elem); if(pelem == H) return; if(pelem->first != elem->kids) return; p.y = 0; switch(spacing){ default: /* shouldn't happen; protected by adjustelement */ case Adjpack: x = elem->r.min.x; for(l=elem->kids; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; p.x = x - e->r.min.x; translateelement(e, p); x += Dx(e->r); } elem->r.max.x = x; return; case Adjequal: dx = 0; nlist = 0; for(l=elem->kids; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; if(dx < Dx(e->r)) dx = Dx(e->r); nlist++; } elem->r.max.x = elem->r.min.x+nlist*dx; break; case Adjfill: nlist = 0; for(l=elem->kids; l!=H; l=l->tail) nlist++; dx = Dx(elem->r)/nlist; break; } i = 0; for(l=elem->kids; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; edx = Dx(e->r); if(position == Adjleft) edx = 0; else if(position == Adjcenter) edx = (dx-edx)/2; else /* right */ edx = dx-edx; p.x = (elem->r.min.x+i*dx + edx) - e->r.min.x; translateelement(e, p); i++; } } void adjustvertical(Prefab_Element *elem, int spacing, int position) { int edy, dy, i, y; int nlist; /* BUG: should precompute */ List *l; PElement *pelem; Prefab_Element *e; Point p; pelem = lookupelement(elem); if(pelem == H) return; if(pelem->first != elem->kids) return; p.x = 0; switch(spacing){ default: /* shouldn't happen; protected by adjustelement */ case Adjpack: y = elem->r.min.y; for(l=elem->kids; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; p.y = y - e->r.min.y; translateelement(e, p); y += Dy(e->r); } elem->r.max.y = y; return; case Adjequal: dy = 0; nlist = 0; for(l=elem->kids; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; if(dy < Dy(e->r)) dy = Dy(e->r); nlist++; } elem->r.max.y = elem->r.min.y+nlist*dy; break; case Adjfill: nlist = 0; for(l=elem->kids; l!=H; l=l->tail) nlist++; dy = Dy(elem->r)/nlist; break; } i = 0; for(l=elem->kids; l!=H; l=l->tail){ e = *(Prefab_Element**)l->data; edy = Dy(e->r); if(position == Adjup) edy = 0; else if(position == Adjcenter) edy = (dy-edy)/2; else /* down */ edy = dy-edy; p.y = (elem->r.min.y+i*dy + edy) - e->r.min.y; translateelement(e, p); i++; } } void adjustelement(Prefab_Element *elem, int spacing, int position) { if(lookupelement(elem) == H) return; if(spacing<Adjpack || spacing>Adjfill || position<Adjleft || position>Adjdown) return; switch(elem->kind){ case EVertical: adjustvertical(elem, spacing, position); break; case EHorizontal: adjusthorizontal(elem, spacing, position); break; } } void highlightelement(Prefab_Element *elem, Image *i, Prefab_Compound *comp, int on) { PElement *pelem; pelem = lookupelement(elem); if(pelem!=H && lookupcompound(comp)!=H){ if(on) pelem->highlight = comp; else pelem->highlight = H; (*elemfn[elem->kind].highlight)(elem, i, comp, on); } } static int anytextelements(Prefab_Element *e) { Prefab_Element *t; List *l; for(l=e->kids; l!=H; l=l->tail){ t = *(Prefab_Element**)l->data; if(t->kind == EText) return 1; } return 0; } void textlisthighlight(Prefab_Element *e, Image *i, Prefab_Compound *c, int on) { Prefab_Element *t; List *l; for(l=e->kids; l!=H; l=l->tail){ t = *(Prefab_Element**)l->data; if(t->kind == EText) texthighlight(t, i, c, on); } } void outlinehighlight(Prefab_Element *e, Image *i, Prefab_Compound *c, int on) { List *l; Prefab_Element *t; Image *color; Rectangle r, r1, r2; Point dp; int done; /* see if we can do it by highlighting just a text element */ if((e->kind==EVertical || e->kind==EHorizontal) && e->kids!=H){ /* is any child a text element? */ if(anytextelements(e)){ textlisthighlight(e, i, c, on); return; } /* grandchild? */ done = 0; for(l=e->kids; l!=H; l=l->tail){ t = *(Prefab_Element**)l->data; if(t->kind==EVertical || t->kind==EHorizontal) if(anytextelements(t)){ textlisthighlight(t, i, c, on); done = 1; } } if(done) return; } if(on){ color = lookupimage(e->environ->style->highlightcolor); if(color == nil) return; R2R(r, e->r); /* avoid outlining empty space around images */ dp = ((PElement*)e)->drawpt; if(e->kind==EIcon && e->image->repl==0 && ptinrect(dp, r)){ R2R(r1, e->image->r); R2R(r2, e->image->clipr); if(rectclip(&r1, r2)){ dp.x += Dx(r1); dp.y += Dy(r1); if(ptinrect(dp, r)) r = Rpt(((PElement*)e)->drawpt, dp); } } draw(i, r, color, nil, r.min); drawelement(e, i, insetrect(r, 2), Dirty, 1); }else{ drawelement(e, i, IRECT(e->r), Dirty, 0); edge(c->environ, i, c->r, e->r); } } void texthighlight(Prefab_Element *e, Image *i, Prefab_Compound *c, int on) { drawelement(e, i, IRECT(e->r), Clean, on); edge(c->environ, i, c->r, e->r); } void clipelement(Prefab_Element *elem, Rectangle r) { if(lookupelement(elem) != H) (*elemfn[elem->kind].clip)(elem, r); } void simpleclip(Prefab_Element *elem, Rectangle r) { R2R(elem->r, r); } void