stew

a monorepo of some sort
git clone git://git.nsmpr.xyz/stew.git
Log | Files | Refs

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 */