stew

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

commit 4d7f2965857a764fd34cb127600f73a13139f749
parent 2afc12834989375e1f6342f9003467510ba47a8c
Author: Pavel Renev <an2qzavok@gmail.com>
Date:   Sat, 12 Oct 2024 23:10:57 +0000

src/boxes: sync

Diffstat:
Msrc/boxes/boxes.c | 140+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 84 insertions(+), 56 deletions(-)

diff --git a/src/boxes/boxes.c b/src/boxes/boxes.c @@ -10,11 +10,15 @@ enum{ AlignLeft = 1, AlignCenter = 0, AlignRight = -1, - StringSizesSize = 256, + StringSizesSize = 4096, + + BoxType = 0, + TextType = 1, }; typedef struct Box0 Box0; typedef struct Box1 Box1; +typedef struct TextBlock TextBlock; struct Box0{ Rectangle r; @@ -31,6 +35,14 @@ struct Box1{ Box1 *parent; }; +struct TextBlock{ + Image *ink; + Font *font; + Rune *str; + int *width; + long len; +}; + int colors[] ={ 0x000000ff, 0xff0000ff, 0x00ff00ff, 0xffff00ff, 0x0000ffff, 0xff00ffff, 0x00ffffff, 0xffffffff, @@ -39,14 +51,15 @@ int colors[] ={ }; Image *plt[nelem(colors)]; -int spw; -int stringsizes[StringSizesSize]; - -Rune text[] = L"For whatever reason, it's hard to have text displayed \ -on screen in organized manner. Yet text on screen remains the main form of \ +Rune text1[] = L"For whatever reason, it's hard to have text displayed \ +on screen in organized manner."; +Rune text2[] = L"Yet text on screen remains the main form of \ interfacing the operator and the computer."; +Font *nfont; +TextBlock tb1, tb2; + void drawbox0(Image *screen, Box0 box); Rectangle recttopt(Rectangle, Point); @@ -58,64 +71,81 @@ int runestringfit(Font *f, Rune *r, int n, int w); // int stringfit(Font *f, char *s, int n, int w); void -drawboxen(void) -{ - int n, m, i, j; - Rune *str[256]; - int len[256]; - Rectangle rs[256]; - - for(j = 0, i = 0; i < nelem(text); j++){ - n = runestringfit(font, text + i, nelem(text) - i, Dx(screen->r)); - if(n == 0) break; - m = 0; - if(n + i < nelem(text)) for(m = n; m >= 0; m--){ - if(text[i + m] == L' ') break; - if(text[i + m] == L'\0') break; - } - if(m > 0) n = m + 1; - else m = n; - str[j] = text + i; - len[j] = m; - rs[j] = Rect(0, 0, Dx(screen->r), font->height); +calcwidth(TextBlock *tb){ + int i, x; + tb->width = malloc(sizeof(int) * tb->len); + for(x = 0, i = 0; i < tb->len; i++){ + x += runestringnwidth(tb->font, tb->str + i, 1); + tb->width[i] = x; + } +} + +void +initdata(void){ + int i; + nfont = openfont(display, "/lib/font/bit/dejavusans/unicode.18.font"); + if(nfont == nil) sysfatal("%r"); + for(i = 0; i < nelem(colors); i++) + plt[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, colors[i]); - i += n; + tb1.ink = plt[3]; + tb1.font = nfont; + tb1.str = text1; + tb1.len = nelem(text1); + calcwidth(&tb1); + + tb2.ink = plt[5]; + tb2.font = font; + tb2.str = text2; + tb2.len = nelem(text2); + calcwidth(&tb2); +} + +void +redraw(void){ + Point cur; + int sp, n; + Box1 scr = {screen->r, screen->clipr, plt[12], nil, nil, nil, 0, nil}; + drawbox0(screen, (Box0)scr); + cur = screen->r.min; + sp = 0; + while(sp < tb1.len){ + for(n = 0; sp + n + 1 < tb1.len; n++){ + if(tb1.width[sp + n + 1] - tb1.width[sp] > Dx(screen->r)) break; + } + if(n == 0) break; + runestringn(screen, cur, tb1.ink, ZP, tb1.font, tb1.str + sp, n); + sp += n; + cur.y += tb1.font->height; } - rs[j - 1].max.x = stringsizes[n]; - m = arrangerects(rs, Dx(screen->r), rs, j); - - Box1 win = {screen->r, screen->clipr, plt[0], nil, nil, nil, 0, nil}; - drawbox0(screen, (Box0)win); - - for(i = 0; i < m; i++){ - Box1 box = { - rectaddpt(rs[i], screen->r.min), screen->clipr, - plt[9 + i%7], plt[1 + i%7], - font, str[i], len[i], - &win - }; - drawbox0(screen, (Box0)box); + + sp = 0; + while(sp < tb2.len){ + for(n = 0; sp + n + 1 < tb2.len; n++){ + if(tb2.width[sp + n + 1] - tb2.width[sp] > Dx(screen->r)) break; + } + if(n == 0) break; + runestringn(screen, cur, tb2.ink, ZP, tb2.font, tb2.str + sp, n); + sp += n; + cur.y += tb2.font->height; } + flushimage(display, 1); } void -eresized(int ) -{ +eresized(int ){ getwindow(display, Refnone); - drawboxen(); + redraw(); } void main(void){ - int i; Event e; initdraw(0, 0, "boxes"); - for(i = 0; i < nelem(colors); i++) - plt[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, colors[i]); - spw = stringwidth(font, " "); einit(Emouse); - drawboxen(); + initdata(); + redraw(); for(;;) event(&e); } @@ -228,9 +258,7 @@ recttopt(Rectangle r, Point pt){ int runestringfit(Font *f, Rune *r, int n, int w){ int x, i; - for(x = 0, i = 0; i < n; i++){ - if(r[i] == L'\0') break; - if(i < StringSizesSize) stringsizes[i] = x; + for(x = 0, i = 0; i <= n; i++){ x += runestringnwidth(f, r + i, 1); if(x > w) break; } @@ -241,11 +269,11 @@ runestringfit(Font *f, Rune *r, int n, int w){ int stringfit(Font *f, char *s, int n, int w){ - int y, i; - for(y = 0, i = 0; i < n; i++){ + int x, i; + for(x = 0, i = 0; i < n; i++){ if(s[i] == '\0') break; - y += stringnwidth(f, s + i, 1); - if(y > w) break; + x += stringnwidth(f, s + i, 1); + if(x > w) break; } return i; }