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:
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