tfrdraw.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tfrdraw.c (4225B) | |
--- | |
1 #include <u.h> | |
2 #include <libc.h> | |
3 #include <draw.h> | |
4 #include <mouse.h> | |
5 #include <frame.h> | |
6 | |
7 void | |
8 _frdrawtext(Frame *f, Point pt, Image *text, Image *back) | |
9 { | |
10 Frbox *b; | |
11 int nb; | |
12 | |
13 for(nb=0,b=f->box; nb<f->nbox; nb++, b++){ | |
14 _frcklinewrap(f, &pt, b); | |
15 if(!f->noredraw && b->nrune >= 0) | |
16 stringbg(f->b, pt, text, ZP, f->font, (char*)b->… | |
17 pt.x += b->wid; | |
18 } | |
19 } | |
20 | |
21 static int | |
22 nbytes(char *s0, int nr) | |
23 { | |
24 char *s; | |
25 Rune r; | |
26 | |
27 s = s0; | |
28 while(--nr >= 0) | |
29 s += chartorune(&r, s); | |
30 return s-s0; | |
31 } | |
32 | |
33 void | |
34 frdrawsel(Frame *f, Point pt, ulong p0, ulong p1, int issel) | |
35 { | |
36 Image *back, *text; | |
37 | |
38 if(f->ticked) | |
39 frtick(f, frptofchar(f, f->p0), 0); | |
40 | |
41 if(p0 == p1){ | |
42 frtick(f, pt, issel); | |
43 return; | |
44 } | |
45 | |
46 if(issel){ | |
47 back = f->cols[HIGH]; | |
48 text = f->cols[HTEXT]; | |
49 }else{ | |
50 back = f->cols[BACK]; | |
51 text = f->cols[TEXT]; | |
52 } | |
53 | |
54 frdrawsel0(f, pt, p0, p1, back, text); | |
55 } | |
56 | |
57 Point | |
58 frdrawsel0(Frame *f, Point pt, ulong p0, ulong p1, Image *back, Image *t… | |
59 { | |
60 Frbox *b; | |
61 int nb, nr, w, x, trim; | |
62 Point qt; | |
63 uint p; | |
64 char *ptr; | |
65 | |
66 if(p0 > p1) | |
67 sysfatal("libframe: frdrawsel0 p0=%lud > p1=%lud", p0, p… | |
68 | |
69 p = 0; | |
70 b = f->box; | |
71 trim = 0; | |
72 for(nb=0; nb<f->nbox && p<p1; nb++){ | |
73 nr = b->nrune; | |
74 if(nr < 0) | |
75 nr = 1; | |
76 if(p+nr <= p0) | |
77 goto Continue; | |
78 if(p >= p0){ | |
79 qt = pt; | |
80 _frcklinewrap(f, &pt, b); | |
81 /* fill in the end of a wrapped line */ | |
82 if(pt.y > qt.y) | |
83 draw(f->b, Rect(qt.x, qt.y, f->r.max.x, … | |
84 } | |
85 ptr = (char*)b->ptr; | |
86 if(p < p0){ /* beginning of region: advance into … | |
87 ptr += nbytes(ptr, p0-p); | |
88 nr -= (p0-p); | |
89 p = p0; | |
90 } | |
91 trim = 0; | |
92 if(p+nr > p1){ /* end of region: trim box */ | |
93 nr -= (p+nr)-p1; | |
94 trim = 1; | |
95 } | |
96 if(b->nrune<0 || nr==b->nrune) | |
97 w = b->wid; | |
98 else | |
99 w = stringnwidth(f->font, ptr, nr); | |
100 x = pt.x+w; | |
101 if(x > f->r.max.x) | |
102 x = f->r.max.x; | |
103 draw(f->b, Rect(pt.x, pt.y, x, pt.y+f->font->height), ba… | |
104 if(b->nrune >= 0) | |
105 stringnbg(f->b, pt, text, ZP, f->font, ptr, nr, … | |
106 pt.x += w; | |
107 Continue: | |
108 b++; | |
109 p += nr; | |
110 } | |
111 /* if this is end of last plain text box on wrapped line, fill t… | |
112 if(p1>p0 && b>f->box && b<f->box+f->nbox && b[-1].nrune>0 && !t… | |
113 qt = pt; | |
114 _frcklinewrap(f, &pt, b); | |
115 if(pt.y > qt.y) | |
116 draw(f->b, Rect(qt.x, qt.y, f->r.max.x, pt.y), b… | |
117 } | |
118 return pt; | |
119 } | |
120 | |
121 void | |
122 frredraw(Frame *f) | |
123 { | |
124 int ticked; | |
125 Point pt; | |
126 | |
127 if(f->p0 == f->p1){ | |
128 ticked = f->ticked; | |
129 if(ticked) | |
130 frtick(f, frptofchar(f, f->p0), 0); | |
131 frdrawsel0(f, frptofchar(f, 0), 0, f->nchars, f->cols[BA… | |
132 if(ticked) | |
133 frtick(f, frptofchar(f, f->p0), 1); | |
134 return; | |
135 } | |
136 | |
137 pt = frptofchar(f, 0); | |
138 pt = frdrawsel0(f, pt, 0, f->p0, f->cols[BACK], f->cols[TEXT]); | |
139 pt = frdrawsel0(f, pt, f->p0, f->p1, f->cols[HIGH], f->cols[HTEX… | |
140 pt = frdrawsel0(f, pt, f->p1, f->nchars, f->cols[BACK], f->cols[… | |
141 } | |
142 | |
143 static void | |
144 _frtick(Frame *f, Point pt, int ticked) | |
145 { | |
146 Rectangle r; | |
147 | |
148 if(f->ticked==ticked || f->tick==0 || !ptinrect(pt, f->r)) | |
149 return; | |
150 pt.x -= f->tickscale; /* looks best just left of where re… | |
151 r = Rect(pt.x, pt.y, pt.x+FRTICKW*f->tickscale, pt.y+f->font->he… | |
152 /* can go into left border but not right */ | |
153 if(r.max.x > f->r.max.x) | |
154 r.max.x = f->r.max.x; | |
155 if(ticked){ | |
156 draw(f->tickback, f->tickback->r, f->b, nil, pt); | |
157 draw(f->b, r, f->tick, nil, ZP); | |
158 }else | |
159 draw(f->b, r, f->tickback, nil, ZP); | |
160 f->ticked = ticked; | |
161 } | |
162 | |
163 void | |
164 frtick(Frame *f, Point pt, int ticked) | |
165 { | |
166 if(f->tickscale != scalesize(f->display, 1)) { | |
167 if(f->ticked) | |
168 _frtick(f, pt, 0); | |
169 frinittick(f); | |
170 } | |
171 _frtick(f, pt, ticked); | |
172 } | |
173 | |
174 Point | |
175 _frdraw(Frame *f, Point pt) | |
176 { | |
177 Frbox *b; | |
178 int nb, n; | |
179 | |
180 for(b=f->box,nb=0; nb<f->nbox; nb++, b++){ | |
181 _frcklinewrap0(f, &pt, b); | |
182 if(pt.y == f->r.max.y){ | |
183 f->nchars -= _frstrlen(f, nb); | |
184 _frdelbox(f, nb, f->nbox-1); | |
185 break; | |
186 } | |
187 if(b->nrune > 0){ | |
188 n = _frcanfit(f, pt, b); | |
189 if(n == 0) | |
190 break; | |
191 if(n != b->nrune){ | |
192 _frsplitbox(f, nb, n); | |
193 b = &f->box[nb]; | |
194 } | |
195 pt.x += b->wid; | |
196 }else{ | |
197 if(b->bc == '\n'){ | |
198 pt.x = f->r.min.x; | |
199 pt.y+=f->font->height; | |
200 }else | |
201 pt.x += _frnewwid(f, pt, b); | |
202 } | |
203 } | |
204 return pt; | |
205 } | |
206 | |
207 int | |
208 _frstrlen(Frame *f, int nb) | |
209 { | |
210 int n; | |
211 | |
212 for(n=0; nb<f->nbox; nb++) | |
213 n += NRUNE(&f->box[nb]); | |
214 return n; | |
215 } |