stew

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

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 }