stew

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

commit 1b8ac46d900edb841a3b4f82c049936f81d30dea
parent 588bb1debffd21b4100eb39304344f07d51c05d6
Author: Pavel Renev <an2qzavok@gmail.com>
Date:   Sat, 14 Sep 2024 23:33:55 +0000

src/boxes: workbench for richterm rework

Diffstat:
Asrc/boxes/boxes.c | 243+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/boxes/mkfile | 6++++++
2 files changed, 249 insertions(+), 0 deletions(-)

diff --git a/src/boxes/boxes.c b/src/boxes/boxes.c @@ -0,0 +1,242 @@ +/* test bench for richterm mark 3 rework */ + +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <event.h> +#include <cursor.h> + +enum{ + AlignLeft = 1, + AlignCenter = 0, + AlignRight = -1, +}; + +typedef struct Box0 Box0; +typedef struct Box1 Box1; + +struct Box0{ + Rectangle r; + Rectangle clipr; + Image *paper; + Image *ink; + Font *font; + Rune *str; + long len; +}; + +struct Box1{ + Box0; + Box1 *parent; +}; + +int colors[] ={ + 0x000000ff, 0xff0000ff, 0x00ff00ff, 0xffff00ff, + 0x0000ffff, 0xff00ffff, 0x00ffffff, 0xffffffff, + 0x000000ff, 0x7f0000ff, 0x007f00ff, 0x7f7f00ff, + 0x00007fff, 0x7f007fff, 0x007f7fff, 0x7f7f7fff, +}; + +Image *plt[nelem(colors)]; +int spw; + +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 \ +interfacing the operator and the computer."; + +void drawbox0(Image *screen, Box0 box); +Rectangle recttopt(Rectangle, Point); + +int arrangerectsv(Rectangle *buf, int height, Rectangle *src, int n); +int arrangerectsh(Rectangle *buf, int width, Rectangle *src, int n); +int arrangerects(Rectangle *buf, int width, Rectangle *src, int n); +int alignrects(Rectangle *buf, Rectangle bnd, Rectangle *src, int n, int t); +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; + str[j] = text + i; + len[j] = n; + rs[j] = Rect(0, 0, runestringnwidth(font, str[j], len[j]), font->height); + // rs[j] = Rect(0, 0, Dx(screen->r), font->height); + + i += 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); + } + flushimage(display, 1); +} + +void +eresized(int ) +{ + getwindow(display, Refnone); + drawboxen(); +} + +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(); + for(;;) event(&e); +} + +void +drawbox0(Image *image, Box0 box){ + if(box.paper !=nil) draw(image, box.r, box.paper, nil, ZP); + if((box.ink != nil)&&(box.str != nil)&&(box.len != 0)){ + _string(image, box.r.min, box.ink, ZP, box.font, nil, + box.str, box.len, image->clipr, nil, ZP, SoverD); + } +} + +int +arrangerectsv(Rectangle *buf, int height, Rectangle *src, int n){ + int i; + Point pt; + if(n <= 0) return 0; + for(i = 0, pt = ZP; i < n; i++){ + if (pt.y > height) break; + buf[i] = recttopt(src[i], pt); + pt.y += Dy(buf[i]); + } + return i; +} + +int +arrangerectsh(Rectangle *buf, int width, Rectangle *src, int n){ + int i, j, maxy; + Point pt; + if(n <= 0) return 0; + maxy = src[0].max.y; + for(i = 0, pt = ZP; i < n; i++){ + buf[i] = recttopt(src[i], pt); + if(maxy < buf[i].max.y) maxy = buf[i].max.y; + pt.x += Dx(buf[i]); + if ((i > 0) && (pt.x > width)) break; + } + for(j = 0; j < i; j++){ + buf[j] = recttopt(buf[j], Pt(buf[j].min.x, maxy - Dy(buf[j]))); + } + return i; +} + +int +arrangerects(Rectangle *buf, int width, Rectangle *src, int n){ + Point pt; + int s, e, maxy; + pt = ZP; + if(n <= 0) return 0; + maxy = src[0].max.y; + for(s = 0, e = 0; e < n; e++){ + if(pt.x + Dx(src[e]) > width){ + pt = Pt(0, maxy); + //for(; s < e; s++) buf[s] = rectaddpt(buf[s], Pt(0, maxy - buf[s].min.y)); + s = e; + } + buf[e] = recttopt(src[e], pt); + if(maxy < buf[e].max.y) maxy = buf[e].max.y; + pt.x += Dx(buf[e]); + } + return e; +} + +int +alignrects(Rectangle *buf, Rectangle bnd, Rectangle *src, int n, int t){ + int i, x, base; + switch(t){ + case AlignRight: + base = bnd.max.x; + for(i = 0; i < n; i++){ + x = base; + buf[i] = Rect( + x - Dx(src[i]), + src[i].min.y, + x, + src[i].max.y); + } + case AlignCenter: + base = bnd.min.x + Dx(bnd) / 2; + for(i = 0; i < n; i++){ + x = base - Dx(src[i]) / 2; + buf[i] = Rect( + x, + src[i].min.y, + x + Dx(src[i]), + src[i].max.y); + } + break; + case AlignLeft: + base = bnd.min.x; + for(i = 0; i < n; i++){ + x = base; + buf[i] = Rect( + x, + src[i].min.y, + x + Dx(src[i]), + src[i].max.y); + } + default: + return -1; + }; + return i; +} + +Rectangle +recttopt(Rectangle r, Point pt){ + return Rpt(pt, addpt(pt, Pt(Dx(r), Dy(r)))); +} + +int +runestringfit(Font *f, Rune *r, int n, int w){ + int y, i; + for(y = 0, i = 0; i < n; i++){ + if(r[i] == L'\0') break; + y += runestringnwidth(f, r + i, 1); + if(y > w) break; + } + return i; +} + +/* TODO: should check for unicode specifics + +int +stringfit(Font *f, char *s, int n, int w){ + int y, i; + for(y = 0, i = 0; i < n; i++){ + if(s[i] == '\0') break; + y += stringnwidth(f, s + i, 1); + if(y > w) break; + } + return i; +} +*/ +\ No newline at end of file diff --git a/src/boxes/mkfile b/src/boxes/mkfile @@ -0,0 +1,6 @@ +</$objtype/mkfile +BIN= +TARG=boxes +OFILES=boxes.$O + +</sys/src/cmd/mkone