commit 4d7f2965857a764fd34cb127600f73a13139f749
parent 2afc12834989375e1f6342f9003467510ba47a8c
Author: Pavel Renev <an2qzavok@gmail.com>
Date: Sat, 12 Oct 2024 23:10:57 +0000
src/boxes: sync
Diffstat:
M | src/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;
}