boxes.c (5231B)
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 71 void 72 calcwidth(TextBlock *tb){ 73 int i, x; 74 tb->width = malloc(sizeof(int) * tb->len); 75 for(x = 0, i = 0; i < tb->len; i++){ 76 tb->width[i] = x; 77 x += runestringnwidth(tb->font, tb->str + i, 1); 78 } 79 tb->width[i] = x; 80 } 81 82 void 83 initdata(void){ 84 int i; 85 nfont = openfont(display, "/lib/font/bit/dejavusans/unicode.18.font"); 86 if(nfont == nil) sysfatal("%r"); 87 for(i = 0; i < nelem(colors); i++) 88 plt[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, colors[i]); 89 90 tb1.ink = plt[3]; 91 tb1.font = nfont; 92 tb1.str = text1; 93 tb1.len = nelem(text1); 94 calcwidth(&tb1); 95 96 tb2.ink = plt[5]; 97 tb2.font = nfont; 98 tb2.str = text2; 99 tb2.len = nelem(text2); 100 calcwidth(&tb2); 101 } 102 103 void 104 redraw(void){ 105 Point cur; 106 int sp, n; 107 Box1 scr = {screen->r, screen->clipr, plt[12], nil, nil, nil, 0, nil}; 108 drawbox0(screen, (Box0)scr); 109 cur = screen->r.min; 110 sp = 0; 111 while(sp < tb1.len){ 112 for(n = 0; sp + n <= tb1.len; n++){ 113 if(tb1.width[sp + n] - tb1.width[sp] > Dx(screen->r)) break; 114 } 115 if(n == 0) break; 116 117 if (n > 1) n--; 118 119 runestringn(screen, cur, tb1.ink, ZP, tb1.font, tb1.str + sp, n); 120 sp += n; 121 cur.y += tb1.font->height; 122 } 123 124 sp = 0; 125 while(sp < tb2.len){ 126 for(n = 0; sp + n <= tb2.len; n++){ 127 if(tb2.width[sp + n] - tb2.width[sp] > Dx(screen->r)) break; 128 } 129 if(n == 0) break; 130 131 if (n > 1) n--; 132 133 runestringn(screen, cur, tb2.ink, ZP, tb2.font, tb2.str + sp, n); 134 sp += n; 135 cur.y += tb2.font->height; 136 } 137 138 flushimage(display, 1); 139 } 140 141 void 142 eresized(int ){ 143 getwindow(display, Refnone); 144 redraw(); 145 } 146 147 void 148 main(void){ 149 Event e; 150 initdraw(0, 0, "boxes"); 151 einit(Emouse); 152 initdata(); 153 redraw(); 154 for(;;) event(&e); 155 } 156 157 void 158 drawbox0(Image *image, Box0 box){ 159 if(box.paper !=nil) draw(image, box.r, box.paper, nil, ZP); 160 if((box.ink != nil)&&(box.str != nil)&&(box.len != 0)){ 161 _string(image, box.r.min, box.ink, ZP, box.font, nil, 162 box.str, box.len, image->clipr, nil, ZP, SoverD); 163 } 164 } 165 166 int 167 arrangerectsv(Rectangle *buf, int height, Rectangle *src, int n){ 168 int i; 169 Point pt; 170 if(n <= 0) return 0; 171 for(i = 0, pt = ZP; i < n; i++){ 172 if (pt.y > height) break; 173 buf[i] = recttopt(src[i], pt); 174 pt.y += Dy(buf[i]); 175 } 176 return i; 177 } 178 179 int 180 arrangerectsh(Rectangle *buf, int width, Rectangle *src, int n){ 181 int i, j, maxy; 182 Point pt; 183 if(n <= 0) return 0; 184 maxy = src[0].max.y; 185 for(i = 0, pt = ZP; i < n; i++){ 186 buf[i] = recttopt(src[i], pt); 187 if(maxy < buf[i].max.y) maxy = buf[i].max.y; 188 pt.x += Dx(buf[i]); 189 if ((i > 0) && (pt.x > width)) break; 190 } 191 for(j = 0; j < i; j++){ 192 buf[j] = recttopt(buf[j], Pt(buf[j].min.x, maxy - Dy(buf[j]))); 193 } 194 return i; 195 } 196 197 int 198 arrangerects(Rectangle *buf, int width, Rectangle *src, int n){ 199 Point pt; 200 int s, e, maxy; 201 pt = ZP; 202 if(n <= 0) return 0; 203 maxy = src[0].max.y; 204 for(s = 0, e = 0; e < n; e++){ 205 if(pt.x + Dx(src[e]) > width){ 206 pt = Pt(0, maxy); 207 //for(; s < e; s++) buf[s] = rectaddpt(buf[s], Pt(0, maxy - buf[s].min.y)); 208 s = e; 209 } 210 buf[e] = recttopt(src[e], pt); 211 if(maxy < buf[e].max.y) maxy = buf[e].max.y; 212 pt.x += Dx(buf[e]); 213 } 214 return e; 215 } 216 217 int 218 alignrects(Rectangle *buf, Rectangle bnd, Rectangle *src, int n, int t){ 219 int i, x, base; 220 switch(t){ 221 case AlignRight: 222 base = bnd.max.x; 223 for(i = 0; i < n; i++){ 224 x = base; 225 buf[i] = Rect( 226 x - Dx(src[i]), 227 src[i].min.y, 228 x, 229 src[i].max.y); 230 } 231 case AlignCenter: 232 base = bnd.min.x + Dx(bnd) / 2; 233 for(i = 0; i < n; i++){ 234 x = base - Dx(src[i]) / 2; 235 buf[i] = Rect( 236 x, 237 src[i].min.y, 238 x + Dx(src[i]), 239 src[i].max.y); 240 } 241 break; 242 case AlignLeft: 243 base = bnd.min.x; 244 for(i = 0; i < n; i++){ 245 x = base; 246 buf[i] = Rect( 247 x, 248 src[i].min.y, 249 x + Dx(src[i]), 250 src[i].max.y); 251 } 252 default: 253 return -1; 254 }; 255 return i; 256 } 257 258 Rectangle 259 recttopt(Rectangle r, Point pt){ 260 return Rpt(pt, addpt(pt, Pt(Dx(r), Dy(r)))); 261 }