Introduction
Introduction Statistics Contact Development Disclaimer Help
frinsert.c - sam - An updated version of the sam text editor.
git clone git://vernunftzentrum.de/sam.git
Log
Files
Refs
LICENSE
---
frinsert.c (7163B)
---
1 /* Copyright (c) 1998 Lucent Technologies - All rights reserved. */
2 #include <u.h>
3 #include <libg.h>
4 #include <frame.h>
5
6 #define DELTA 25
7 #define TMPSIZE 256
8 static Frame frame;
9
10 static
11 Point
12 bxscan(Frame *f, wchar_t *sp, wchar_t *ep, Point *ppt)
13 {
14 int w, c, nb, delta, nl, nr, rw;
15 Frbox *b;
16 char *s, tmp[TMPSIZE+3]; /* +3 for rune overflow */
17 uint8_t *p;
18
19 frame.r = f->r;
20 frame.b = f->b;
21 frame.font = f->font;
22 frame.fheight = f->font->ascent + f->font->descent;
23 frame.maxtab = f->maxtab;
24 frame.left = f->left;
25 frame.nbox = 0;
26 frame.nchars = 0;
27 delta = DELTA;
28 nl = 0;
29 for(nb=0; sp<ep && nl<=f->maxlines; nb++,frame.nbox++){
30 if(nb == frame.nalloc){
31 _frgrowbox(&frame, delta);
32 if(delta < 10000)
33 delta *= 2;
34 }
35 b = &frame.box[nb];
36 c = *sp;
37 if(c=='\t' || c=='\n'){
38 b->a.b.bc = c;
39 b->wid = 5000;
40 b->a.b.minwid = (c=='\n')? 0 : charwidth(frame.font, ' ');
41 b->nrune = -1;
42 if(c=='\n')
43 nl++;
44 frame.nchars++;
45 sp++;
46 }else{
47 s = tmp;
48 nr = 0;
49 w = 0;
50 while(sp < ep){
51 c = *sp;
52 if(c=='\t' || c=='\n')
53 break;
54 rw = runetochar(s, *sp);
55 if(s+rw >= tmp+TMPSIZE)
56 break;
57 w += charwidth(frame.font, c);
58 sp++;
59 s += rw;
60 nr++;
61 }
62 *s++ = 0;
63 p = _frallocstr(s-tmp);
64 b = &frame.box[nb];
65 b->a.ptr = p;
66 memmove(p, tmp, s-tmp);
67 b->wid = w;
68 b->nrune = nr;
69 frame.nchars += nr;
70 }
71 }
72 _frcklinewrap0(f, ppt, &frame.box[0]);
73 return _frdraw(&frame, *ppt);
74 }
75
76 static
77 void
78 chopframe(Frame *f, Point pt, uint64_t p, int bn)
79 {
80 Frbox *b;
81
82 for(b = &f->box[bn]; ; b++){
83 if(b >= &f->box[f->nbox])
84 berror("endofframe");
85 _frcklinewrap(f, &pt, b);
86 if(pt.y >= f->r.max.y)
87 break;
88 p += NRUNE(b);
89 _fradvance(f, &pt, b);
90 }
91 f->nchars = p;
92 f->nlines = f->maxlines;
93 if(b<&f->box[f->nbox]) /* BUG */
94 _frdelbox(f, (int)(b-f->box), f->nbox-1);
95 }
96
97 void
98 frinsert(Frame *f, wchar_t *sp, wchar_t *ep, uint64_t p0)
99 {
100 Point pt0, pt1, ppt0, ppt1, pt;
101 Frbox *b;
102 int n, n0, nn0, y;
103 Rectangle r;
104 static struct{
105 Point pt0, pt1;
106 }*pts;
107 static int nalloc=0;
108 int npts;
109
110 if(p0>f->nchars || sp==ep || f->b==0)
111 return;
112 n0 = _frfindbox(f, 0, 0, p0);
113 nn0 = n0;
114 pt0 = _frptofcharnb(f, p0, n0);
115 ppt0 = pt0;
116 pt1 = bxscan(f, sp, ep, &ppt0);
117 ppt1 = pt1;
118 if(n0 < f->nbox){
119 _frcklinewrap(f, &pt0, b = &f->box[n0]); /* for frselectf() */
120 _frcklinewrap0(f, &ppt1, b);
121 }
122 f->modified = true;
123 /*
124 * ppt0 and ppt1 are start and end of insertion as they will appear …
125 * insertion is complete. pt0 is current location of insertion posit…
126 * (p0); pt1 is terminal point (without line wrap) of insertion.
127 */
128 if(p0==f->p0 && p0==f->p1) /* quite likely */
129 frselectf(f, pt0, pt0, F&~D);
130 else
131 frselectp(f, F&~D);
132 /*
133 * Find point where old and new x's line up
134 * Invariants:
135 * pt0 is where the next box (b, n0) is now
136 * pt1 is where it will be after then insertion
137 * If pt1 goes off the rectangle, we can toss everything from there …
138 */
139 for(b = &f->box[n0],npts=0;
140 pt1.x!=pt0.x && pt1.y!=f->r.max.y && n0<f->nbox; b++,n0++,npts+…
141 _frcklinewrap(f, &pt0, b);
142 _frcklinewrap0(f, &pt1, b);
143 if(b->nrune > 0){
144 n = _frcanfit(f, pt1, b);
145 if(n == 0)
146 berror("_frcanfit==0");
147 if(n != b->nrune){
148 _frsplitbox(f, n0, n);
149 b = &f->box[n0];
150 }
151 }
152 if(npts == nalloc){
153 pts = realloc(pts, (npts+DELTA)*sizeof(pts[0]));
154 nalloc += DELTA;
155 b = &f->box[n0];
156 }
157 pts[npts].pt0 = pt0;
158 pts[npts].pt1 = pt1;
159 /* has a text box overflowed off the frame? */
160 if(pt1.y == f->r.max.y)
161 break;
162 _fradvance(f, &pt0, b);
163 pt1.x += _frnewwid(f, pt1, b);
164 }
165 if(pt1.y > f->r.max.y)
166 berror("frinsert pt1 too far");
167 if(pt1.y==f->r.max.y && n0<f->nbox){
168 f->nchars -= _frstrlen(f, n0);
169 _frdelbox(f, n0, f->nbox-1);
170 }
171 if(n0 == f->nbox)
172 f->nlines = (pt1.y-f->r.min.y)/f->fheight+(pt1.x>f->left);
173 else if(pt1.y!=pt0.y){
174 int q0, q1;
175
176 y = f->r.max.y;
177 q0 = pt0.y+f->fheight;
178 q1 = pt1.y+f->fheight;
179 f->nlines += (q1-q0)/f->fheight;
180 if(f->nlines > f->maxlines)
181 chopframe(f, ppt1, p0, nn0);
182 if(pt1.y < y){
183 r = f->r;
184 r.min.y = q0;
185 r.max.y = y-(q1-q0);
186 if(q1 < y)
187 bitblt2(f->b, Pt(f->r.min.x, q1), f->b, r, S, 0, f->bg);
188 r.min = pt0;
189 r.max.y = q0;
190 bitblt2(f->b, pt1, f->b, r, S, 0, f->bg);
191 }
192 }
193 /*
194 * Move the old stuff down to make room. The loop will move the stu…
195 * between the insertion and the point where the x's lined up.
196 * The bitblt2 above moved everything down after the point they line…
197 */
198 for((y=pt1.y==f->r.max.y?pt1.y:0),b = &f->box[n0-1]; --npts>=0; --b){
199 pt = pts[npts].pt1;
200 if(b->nrune > 0){
201 r.min = pts[npts].pt0;
202 r.max = r.min;
203 r.max.x += b->wid;
204 r.max.y += f->fheight;
205 bitblt2(f->b, pt, f->b, r, S, 0, f->bg);
206 if(pt.y < y){ /* clear bit hanging off right */
207 r.min = pt;
208 r.max = pt;
209 r.min.x += b->wid;
210 r.max.x = f->r.max.x;
211 r.max.y += f->fheight;
212 bitblt2(f->b, r.min, f->b, r, 0, 0, f->bg);
213 }
214 y = pt.y;
215 }else{
216 r.min = pt;
217 r.max = pt;
218 r.max.x += b->wid;
219 r.max.y += f->fheight;
220 if(r.max.x >= f->r.max.x)
221 r.max.x = f->r.max.x;
222 bitblt2(f->b, r.min, f->b, r, 0, 0, f->bg);
223 y = (pt.x == f->left)? pt.y : 0;
224 }
225 }
226 frselectf(f, ppt0, ppt1, 0);
227 _frredraw(&frame, ppt0);
228 _fraddbox(f, nn0, frame.nbox);
229 for(n=0; n<frame.nbox; n++)
230 f->box[nn0+n] = frame.box[n];
231 if(nn0>0 && f->box[nn0-1].nrune>=0 && ppt0.x-f->box[nn0-1].wid>=(int…
232 --nn0;
233 ppt0.x -= f->box[nn0].wid;
234 }
235 n0 += frame.nbox;
236 _frclean(f, ppt0, nn0, n0<f->nbox-1? n0+1 : n0);
237 f->nchars += frame.nchars;
238 if(f->p0 >= p0)
239 f->p0 += frame.nchars;
240 if(f->p0 > f->nchars)
241 f->p0 = f->nchars;
242 if(f->p1 >= p0)
243 f->p1 += frame.nchars;
244 if(f->p1 > f->nchars)
245 f->p1 = f->nchars;
246 frselectp(f, F&~D);
247 }
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.