|
|
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.