frbox.c - sam - An updated version of the sam text editor. | |
git clone git://vernunftzentrum.de/sam.git | |
Log | |
Files | |
Refs | |
LICENSE | |
--- | |
frbox.c (3196B) | |
--- | |
1 /* Copyright (c) 1998 Lucent Technologies - All rights reserved. */ | |
2 #include <u.h> | |
3 #include <libg.h> | |
4 #include <frame.h> | |
5 | |
6 #define SLOP 25 | |
7 | |
8 void | |
9 _fraddbox(Frame *f, int bn, int n) /* add n boxes after bn, shift the r… | |
10 * box[bn+n]==box[bn] */ | |
11 { | |
12 int i; | |
13 | |
14 if(bn > f->nbox) | |
15 berror("_fraddbox"); | |
16 if(f->nbox+n > f->nalloc) | |
17 _frgrowbox(f, n+SLOP); | |
18 for(i=f->nbox; --i>=bn; ) | |
19 f->box[i+n] = f->box[i]; | |
20 f->nbox+=n; | |
21 } | |
22 | |
23 void | |
24 _frclosebox(Frame *f, int n0, int n1) /* inclusive */ | |
25 { | |
26 int i; | |
27 | |
28 if(n0>=f->nbox || n1>=f->nbox || n1<n0) | |
29 berror("_frclosebox"); | |
30 n1++; | |
31 for(i=n1; i<f->nbox; i++) | |
32 f->box[i-(n1-n0)] = f->box[i]; | |
33 f->nbox -= n1-n0; | |
34 } | |
35 | |
36 void | |
37 _frdelbox(Frame *f, int n0, int n1) /* inclusive */ | |
38 { | |
39 if(n0>=f->nbox || n1>=f->nbox || n1<n0) | |
40 berror("_frdelbox"); | |
41 _frfreebox(f, n0, n1); | |
42 _frclosebox(f, n0, n1); | |
43 } | |
44 | |
45 void | |
46 _frfreebox(Frame *f, int n0, int n1) /* inclusive */ | |
47 { | |
48 int i; | |
49 | |
50 if(n1<n0) | |
51 return; | |
52 if(n0>=f->nbox || n1>=f->nbox) | |
53 berror("_frfreebox"); | |
54 n1++; | |
55 for(i=n0; i<n1; i++) | |
56 if(f->box[i].nrune >= 0) | |
57 free(f->box[i].a.ptr); | |
58 } | |
59 | |
60 void | |
61 _frgrowbox(Frame *f, int delta) | |
62 { | |
63 f->nalloc += delta; | |
64 f->box = realloc(f->box, f->nalloc*sizeof(Frbox)); | |
65 if(f->box == 0) | |
66 berror("_frgrowbox"); | |
67 } | |
68 | |
69 static | |
70 void | |
71 dupbox(Frame *f, int bn) | |
72 { | |
73 uint8_t *p; | |
74 | |
75 if(f->box[bn].nrune < 0) | |
76 berror("dupbox"); | |
77 _fraddbox(f, bn, 1); | |
78 if(f->box[bn].nrune >= 0){ | |
79 p = _frallocstr(NBYTE(&f->box[bn])+1); | |
80 strcpy((char*)p, (char*)f->box[bn].a.ptr); | |
81 f->box[bn+1].a.ptr = p; | |
82 } | |
83 } | |
84 | |
85 static | |
86 uint8_t* | |
87 runeindex(uint8_t *p, int n) | |
88 { | |
89 int i, w; | |
90 wchar_t rune; | |
91 | |
92 for(i=0; i<n; i++,p+=w) | |
93 w = chartorune(&rune, (char*)p); | |
94 return p; | |
95 } | |
96 | |
97 static | |
98 void | |
99 truncatebox(Frame *f, Frbox *b, int n) /* drop last n chars; no allocat… | |
100 { | |
101 if(b->nrune<0 || b->nrune<n) | |
102 berror("truncatebox"); | |
103 b->nrune -= n; | |
104 runeindex(b->a.ptr, b->nrune)[0] = 0; | |
105 b->wid = strwidth(f->font, (char *)b->a.ptr); | |
106 } | |
107 | |
108 static | |
109 void | |
110 chopbox(Frame *f, Frbox *b, int n) /* drop first n chars; no allocation… | |
111 { | |
112 if(b->nrune<0 || b->nrune<n) | |
113 berror("chopbox"); | |
114 | |
115 uint8_t *ri = runeindex(b->a.ptr, n); | |
116 memmove(b->a.ptr, ri, strlen((char *)ri) + 1); | |
117 b->nrune -= n; | |
118 b->wid = strwidth(f->font, (char *)b->a.ptr); | |
119 } | |
120 | |
121 void | |
122 _frsplitbox(Frame *f, int bn, int n) | |
123 { | |
124 dupbox(f, bn); | |
125 truncatebox(f, &f->box[bn], f->box[bn].nrune-n); | |
126 chopbox(f, &f->box[bn+1], n); | |
127 } | |
128 | |
129 void | |
130 _frmergebox(Frame *f, int bn) /* merge bn and bn+1 */ | |
131 { | |
132 Frbox *b; | |
133 | |
134 b = &f->box[bn]; | |
135 _frinsure(f, bn, NBYTE(&b[0])+NBYTE(&b[1])+1); | |
136 strcpy((char*)runeindex(b[0].a.ptr, b[0].nrune), (char*)b[1].a.ptr); | |
137 b[0].wid += b[1].wid; | |
138 b[0].nrune += b[1].nrune; | |
139 _frdelbox(f, bn+1, bn+1); | |
140 } | |
141 | |
142 int | |
143 _frfindbox(Frame *f, int bn, uint64_t p, uint64_t q) /* find box contai… | |
144 { | |
145 Frbox *b; | |
146 | |
147 for(b = &f->box[bn]; bn<f->nbox && p+NRUNE(b)<=q; bn++, b++) | |
148 p += NRUNE(b); | |
149 if(p != q) | |
150 _frsplitbox(f, bn++, (int)(q-p)); | |
151 return bn; | |
152 } |