boxes.c (5689B)
1 /* test bench for richterm mark 3 rework */ 2 3 #include <u.h> 4 #include <libc.h> 5 #include <draw.h> 6 #include <event.h> 7 #include <cursor.h> 8 9 enum{ 10 AlignLeft = 1, 11 AlignCenter = 0, 12 AlignRight = -1, 13 StringSizesSize = 4096, 14 15 BoxType = 0, 16 TextType = 1, 17 }; 18 19 typedef struct Box0 Box0; 20 typedef struct Box1 Box1; 21 typedef struct TextBlock TextBlock; 22 23 struct Box0{ 24 Rectangle r; 25 Rectangle clipr; 26 Image *paper; 27 Image *ink; 28 Font *font; 29 Rune *str; 30 long len; 31 }; 32 33 struct Box1{ 34 Box0; 35 Box1 *parent; 36 }; 37 38 struct TextBlock{ 39 Image *ink; 40 Font *font; 41 Rune *str; 42 int *width; 43 long len; 44 }; 45 46 int colors[] ={ 47 0x000000ff, 0xff0000ff, 0x00ff00ff, 0xffff00ff, 48 0x0000ffff, 0xff00ffff, 0x00ffffff, 0xffffffff, 49 0x000000ff, 0x7f0000ff, 0x007f00ff, 0x7f7f00ff, 50 0x00007fff, 0x7f007fff, 0x007f7fff, 0x7f7f7fff, 51 }; 52 53 Image *plt[nelem(colors)]; 54 55 Rune text1[] = L"For whatever reason, it's hard to have text displayed \ 56 on screen in organized manner."; 57 Rune text2[] = L"Yet text on screen remains the main form of \ 58 interfacing the operator and the computer."; 59 60 Font *nfont; 61 TextBlock tb1, tb2; 62 63 void drawbox0(Image *screen, Box0 box); 64 Rectangle recttopt(Rectangle, Point); 65 66 int arrangerectsv(Rectangle *buf, int height, Rectangle *src, int n); 67 int arrangerectsh(Rectangle *buf, int width, Rectangle *src, int n); 68 int arrangerects(Rectangle *buf, int width, Rectangle *src, int n); 69 int alignrects(Rectangle *buf, Rectangle bnd, Rectangle *src, int n, int t); 70 int runestringfit(Font *f, Rune *r, int n, int w); 71 // int stringfit(Font *f, char *s, int n, int w); 72 73 void 74 calcwidth(TextBlock *tb){ 75 int i, x; 76 tb->width = malloc(sizeof(int) * tb->len); 77 for(x = 0, i = 0; i < tb->len; i++){ 78 x += runestringnwidth(tb->font, tb->str + i, 1); 79 tb->width[i] = x; 80 } 81 } 82 83 void 84 initdata(void){ 85 int i; 86 nfont = openfont(display, "/lib/font/bit/dejavusans/unicode.18.font"); 87 if(nfont == nil) sysfatal("%r"); 88 for(i = 0; i < nelem(colors); i++) 89 plt[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, colors[i]); 90 91 tb1.ink = plt[3]; 92 tb1.font = nfont; 93 tb1.str = text1; 94 tb1.len = nelem(text1); 95 calcwidth(&tb1); 96 97 tb2.ink = plt[5]; 98 tb2.font = font; 99 tb2.str = text2; 100 tb2.len = nelem(text2); 101 calcwidth(&tb2); 102 } 103 104 void 105 redraw(void){ 106 Point cur; 107 int sp, n; 108 Box1 scr = {screen->r, screen->clipr, plt[12], nil, nil, nil, 0, nil}; 109 drawbox0(screen, (Box0)scr); 110 cur = screen->r.min; 111 sp = 0; 112 while(sp < tb1.len){ 113 for(n = 0; sp + n + 1 < tb1.len; n++){ 114 if(tb1.width[sp + n + 1] - tb1.width[sp] > Dx(screen->r)) break; 115 } 116 if(n == 0) break; 117 runestringn(screen, cur, tb1.ink, ZP, tb1.font, tb1.str + sp, n); 118 sp += n; 119 cur.y += tb1.font->height; 120 } 121 122 sp = 0; 123 while(sp < tb2.len){ 124 for(n = 0; sp + n + 1 < tb2.len; n++){ 125 if(tb2.width[sp + n + 1] - tb2.width[sp] > Dx(screen->r)) break; 126 } 127 if(n == 0) break; 128 runestringn(screen, cur, tb2.ink, ZP, tb2.font, tb2.str + sp, n); 129 sp += n; 130 cur.y += tb2.font->height; 131 } 132 133 flushimage(display, 1); 134 } 135 136 void 137 eresized(int ){ 138 getwindow(display, Refnone); 139 redraw(); 140 } 141 142 void 143 main(void){ 144 Event e; 145 initdraw(0, 0, "boxes"); 146 einit(Emouse); 147 initdata(); 148 redraw(); 149 for(;;) event(&e); 150 } 151 152 void 153 drawbox0(Image *image, Box0 box){ 154 if(box.paper !=nil) draw(image, box.r, box.paper, nil, ZP); 155 if((box.ink != nil)&&(box.str != nil)&&(box.len != 0)){ 156 _string(image, box.r.min, box.ink, ZP, box.font, nil, 157 box.str, box.len, image->clipr, nil, ZP, SoverD); 158 } 159 } 160 161 int 162 arrangerectsv(Rectangle *buf, int height, Rectangle *src, int n){ 163 int i; 164 Point pt; 165 if(n <= 0) return 0; 166 for(i = 0, pt = ZP; i < n; i++){ 167 if (pt.y > height) break; 168 buf[i] = recttopt(src[i], pt); 169 pt.y += Dy(buf[i]); 170 } 171 return i; 172 } 173 174 int 175 arrangerectsh(Rectangle *buf, int width, Rectangle *src, int n){ 176 int i, j, maxy; 177 Point pt; 178 if(n <= 0) return 0; 179 maxy = src[0].max.y; 180 for(i = 0, pt = ZP; i < n; i++){ 181 buf[i] = recttopt(src[i], pt); 182 if(maxy < buf[i].max.y) maxy = buf[i].max.y; 183 pt.x += Dx(buf[i]); 184 if ((i > 0) && (pt.x > width)) break; 185 } 186 for(j = 0; j < i; j++){ 187 buf[j] = recttopt(buf[j], Pt(buf[j].min.x, maxy - Dy(buf[j]))); 188 } 189 return i; 190 } 191 192 int 193 arrangerects(Rectangle *buf, int width, Rectangle *src, int n){ 194 Point pt; 195 int s, e, maxy; 196 pt = ZP; 197 if(n <= 0) return 0; 198 maxy = src[0].max.y; 199 for(s = 0, e = 0; e < n; e++){ 200 if(pt.x + Dx(src[e]) > width){ 201 pt = Pt(0, maxy); 202 //for(; s < e; s++) buf[s] = rectaddpt(buf[s], Pt(0, maxy - buf[s].min.y)); 203 s = e; 204 } 205 buf[e] = recttopt(src[e], pt); 206 if(maxy < buf[e].max.y) maxy = buf[e].max.y; 207 pt.x += Dx(buf[e]); 208 } 209 return e; 210 } 211 212 int 213 alignrects(Rectangle *buf, Rectangle bnd, Rectangle *src, int n, int t){ 214 int i, x, base; 215 switch(t){ 216 case AlignRight: 217 base = bnd.max.x; 218 for(i = 0; i < n; i++){ 219 x = base; 220 buf[i] = Rect( 221 x - Dx(src[i]), 222 src[i].min.y, 223 x, 224 src[i].max.y); 225 } 226 case AlignCenter: 227 base = bnd.min.x + Dx(bnd) / 2; 228 for(i = 0; i < n; i++){ 229 x = base - Dx(src[i]) / 2; 230 buf[i] = Rect( 231 x, 232 src[i].min.y, 233 x + Dx(src[i]), 234 src[i].max.y); 235 } 236 break; 237 case AlignLeft: 238 base = bnd.min.x; 239 for(i = 0; i < n; i++){ 240 x = base; 241 buf[i] = Rect( 242 x, 243 src[i].min.y, 244 x + Dx(src[i]), 245 src[i].max.y); 246 } 247 default: 248 return -1; 249 }; 250 return i; 251 } 252 253 Rectangle 254 recttopt(Rectangle r, Point pt){ 255 return Rpt(pt, addpt(pt, Pt(Dx(r), Dy(r)))); 256 } 257 258 int 259 runestringfit(Font *f, Rune *r, int n, int w){ 260 int x, i; 261 for(x = 0, i = 0; i <= n; i++){ 262 x += runestringnwidth(f, r + i, 1); 263 if(x > w) break; 264 } 265 return i; 266 } 267 268 /* TODO: should check for unicode specifics 269 270 int 271 stringfit(Font *f, char *s, int n, int w){ 272 int x, i; 273 for(x = 0, i = 0; i < n; i++){ 274 if(s[i] == '\0') break; 275 x += stringnwidth(f, s + i, 1); 276 if(x > w) break; 277 } 278 return i; 279 } 280 */