|
|
1.1 ! root 1: #include "frame.h" ! 2: ! 3: #define DELTA 25 ! 4: static Frame frame; ! 5: Point ! 6: bxscan(f, sp, ppt) ! 7: Frame *f; ! 8: uchar **sp; ! 9: Point *ppt; ! 10: { ! 11: register w, c, nb; ! 12: register uchar *p; ! 13: register Box *b; ! 14: register uchar *s; ! 15: int n; ! 16: frame.r=f->r; ! 17: frame.b=f->b; ! 18: frame.font=f->font; ! 19: frame.maxcharwid=f->maxcharwid; ! 20: frame.maxtab=f->maxtab; ! 21: frame.left=f->left; ! 22: frame.nbox=0; ! 23: for(n=0, nb=0; (*sp)[n]; nb++,frame.nbox++){ ! 24: if(nb==frame.nalloc) ! 25: growbox(&frame, DELTA); ! 26: s=&(*sp)[n]; ! 27: b=&frame.box[nb]; ! 28: if(*s=='\t' || *s=='\n'){ ! 29: b->bc=*s; ! 30: b->wid=5000; ! 31: b->minwid=(*s=='\n')? 0 : frame.font->info[' '].width; ! 32: b->len=-1; ! 33: n++; ! 34: }else{ ! 35: for(w=0,p=s; (c=*s) && c!='\t' && c!='\n'; s++) ! 36: w+=frame.font->info[c].width; ! 37: *s=0; ! 38: b->ptr=allocstr((int)(s-p+1)); ! 39: copystr(p, b->ptr); ! 40: *s=c; ! 41: b->wid=w; ! 42: n+=b->len=s-p; ! 43: } ! 44: } ! 45: frame.nchars=n; ! 46: b=&frame.box[0]; ! 47: cklinewrap0(f, ppt, b); ! 48: return draw(&frame, *ppt); ! 49: } ! 50: frinsert(f, sp, p0) ! 51: register Frame *f; ! 52: uchar **sp; ! 53: Posn p0; ! 54: { ! 55: Point pt0, pt1, ppt0, ppt1, pt; ! 56: register Box *b; ! 57: register n, n0, nn0; ! 58: Rectangle r; ! 59: int y; ! 60: static struct{ ! 61: Point pt0, pt1; ! 62: }*pts; ! 63: static int nalloc=0; ! 64: int npts; ! 65: if(p0>f->nchars || **sp==0 || f->b==0) ! 66: return; ! 67: nn0=n0=findbox(f, 0, 0, p0); ! 68: ppt0=pt0=ptofcharnb(f, p0, n0); ! 69: ppt1=pt1=bxscan(f, sp, &ppt0); ! 70: if(n0<f->nbox){ ! 71: cklinewrap(f, &pt0, b=&f->box[n0]); /* for selectf() */ ! 72: cklinewrap0(f, &ppt1, b); ! 73: } ! 74: /* ! 75: * ppt0 and ppt1 are start and end of insertion as they will appear when ! 76: * insertion is complete. pt0 is current location of insertion position ! 77: * (p0); pt1 is terminal point (without line wrap) of insertion. ! 78: */ ! 79: if(p0==f->p0 && p0==f->p1) /* quite likely */ ! 80: selectf(f, pt0, pt0, F_XOR); ! 81: else ! 82: selectp(f, F_XOR); ! 83: /* ! 84: * Find point where old and new x's line up ! 85: * Invariants: ! 86: * pt0 is where the next box (b, n0) is now ! 87: * pt1 is where it will be after then insertion ! 88: * If pt1 goes off the rectangle, we can toss everything from there on ! 89: */ ! 90: for(b=&f->box[n0],npts=0; ! 91: pt1.x!=pt0.x && pt1.y!=f->r.corner.y && n0<f->nbox; b++,n0++,npts++){ ! 92: cklinewrap(f, &pt0, b); ! 93: cklinewrap0(f, &pt1, b); ! 94: if(b->len>0){ ! 95: n=canfit(f, pt1, b); ! 96: if(n==0) ! 97: panic("canfit==0"); ! 98: if(n!=b->len){ ! 99: splitbox(f, n0, n); ! 100: b=&f->box[n0]; ! 101: } ! 102: } ! 103: if(npts==nalloc){ ! 104: gcrealloc((char **)&pts, ! 105: npts*sizeof(pts[0]), (npts+DELTA)*sizeof(pts[0])); ! 106: nalloc+=DELTA; ! 107: b=&f->box[n0]; ! 108: } ! 109: pts[npts].pt0=pt0, pts[npts].pt1=pt1; ! 110: /* has a text box overflowed off the frame? */ ! 111: if(pt1.y==f->r.corner.y) ! 112: break; ! 113: advance(f, &pt0, b); ! 114: pt1.x+=newwid(f, pt1, b); ! 115: } ! 116: if(pt1.y>f->r.corner.y) ! 117: panic("frinsert pt1 too far"); ! 118: if(pt1.y==f->r.corner.y && n0<f->nbox){ ! 119: f->nchars-=frstrlen(f, n0); ! 120: delbox(f, n0, f->nbox-1); ! 121: } ! 122: if(n0==f->nbox) ! 123: f->nlines=(pt1.y-f->r.origin.y)/f->font->height+(pt1.x>f->left); ! 124: else if(pt1.y!=pt0.y){ ! 125: int q0, q1; ! 126: y=f->r.corner.y; ! 127: q0=pt0.y+f->font->height, q1=pt1.y+f->font->height; ! 128: f->nlines+=(q1-q0)/f->font->height; ! 129: if(f->nlines>f->maxlines) ! 130: chopframe(f, ppt1, p0, nn0); ! 131: if(pt1.y<y){ ! 132: r=f->r, r.origin.y=q0, r.corner.y=y-(q1-q0); ! 133: if(q1<y) ! 134: bitblt(B, r, B, Pt(f->r.origin.x, q1), F_STORE); ! 135: r.origin=pt0; r.corner.y=q0; ! 136: bitblt(B, r, B, pt1, F_STORE); ! 137: } ! 138: } ! 139: /* ! 140: * Move the old stuff down to make room. The loop will move the stuff ! 141: * between the insertion and the point where the x's lined up. ! 142: * The bitblts above moved everything down after the point they lined up. ! 143: */ ! 144: for((y=pt1.y==f->r.corner.y?pt1.y:0),b=&f->box[n0-1]; --npts>=0; --b){ ! 145: pt=pts[npts].pt1; ! 146: if(b->len>0){ ! 147: r.origin=r.corner=pts[npts].pt0; ! 148: r.corner.x+=b->wid, r.corner.y+=f->font->height; ! 149: bitblt(B, r, B, pt, F_STORE); ! 150: if(pt.y<y){ /* clear bit hanging off right */ ! 151: r.origin=r.corner=pt; ! 152: r.origin.x+=b->wid; ! 153: r.corner.x=f->r.corner.x; ! 154: r.corner.y+=f->font->height; ! 155: rectf(B, r, F_CLR); ! 156: } ! 157: y=pt.y; ! 158: }else{ ! 159: r.origin=r.corner=pt; ! 160: r.corner.x+=b->wid, r.corner.y+=f->font->height; ! 161: if(r.corner.x>=f->r.corner.x) ! 162: r.corner.x=f->r.corner.x; ! 163: rectf(B, r, F_CLR); ! 164: y=pt.x==f->left? pt.y : 0; ! 165: } ! 166: } ! 167: selectf(f, ppt0, ppt1, F_CLR); ! 168: redraw(&frame, ppt0); ! 169: addbox(f, nn0, frame.nbox); ! 170: for(n=0; n<frame.nbox; n++) ! 171: f->box[nn0+n]=frame.box[n]; ! 172: if(nn0>0 && f->box[nn0-1].len>=0 && ppt0.x-f->box[nn0-1].wid>=(int)f->left){ ! 173: --nn0; ! 174: ppt0.x-=f->box[nn0].wid; ! 175: } ! 176: n0+=frame.nbox; ! 177: clean(f, ppt0, nn0, n0<f->nbox-1? n0+1 : n0); ! 178: f->nchars+=frame.nchars; ! 179: if(f->p0>=p0) ! 180: f->p0+=frame.nchars; ! 181: if(f->p0>f->nchars) ! 182: f->p0=f->nchars; ! 183: if(f->p1>=p0) ! 184: f->p1+=frame.nchars; ! 185: if(f->p1>f->nchars) ! 186: f->p1=f->nchars; ! 187: if(pt0.x!=pt1.x) ! 188: f->lastlinefull=pt0.x==f->left; ! 189: selectp(f, F_XOR); ! 190: } ! 191: chopframe(f, pt, p, bn) ! 192: register Frame *f; ! 193: Point pt; ! 194: register Posn p; ! 195: int bn; ! 196: { ! 197: register Box *b; ! 198: for(b=&f->box[bn]; ; b++){ ! 199: if(b>=&f->box[f->nbox]) ! 200: panic("endofframe"); ! 201: cklinewrap(f, &pt, b); ! 202: if(pt.y>=f->r.corner.y) ! 203: break; ! 204: p+=LEN(b); ! 205: advance(f, &pt, b); ! 206: } ! 207: f->nchars=p; ! 208: f->nlines=f->maxlines; ! 209: if(b<&f->box[f->nbox]) /* BUG */ ! 210: delbox(f, (int)(b-f->box), f->nbox-1); ! 211: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.