richterm

"terminal emulator" with support for text fonts and images for plan9
git clone git://nsmpr.xyz/richterm.git
Log | Files | Refs | README

commit 9619d64cf5b0135b83a0f1c7646a65d60926e83d
parent 647009a1d4276cc53b2b5ce59395ae06cece2f9b
Author: glenda <glenda@9front.local>
Date:   Mon, 26 Apr 2021 17:17:35 +0000

implement fonts more or less, start working on newline handling

Diffstat:
Mmkfile | 2+-
Mrichterm.c | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
2 files changed, 83 insertions(+), 18 deletions(-)

diff --git a/mkfile b/mkfile @@ -2,6 +2,6 @@ TARG=richterm OFILES=richterm.$O devfs.$O fs.$O -HFILES=richterm.h +HFILES=richterm.h ui.h </sys/src/cmd/mkone diff --git a/richterm.c b/richterm.c @@ -18,7 +18,18 @@ struct Rich { Page page; }; +typedef struct Fonts Fonts; +struct Fonts { + Font **data; + int size; + int count; +}; + +Fonts fonts; + Page generatepage(Rectangle, Rich *); +Font* getfont(Fonts *, char *); +void addfont(Fonts *, Font *); void usage(void) @@ -48,15 +59,20 @@ threadmain(int argc, char **argv) //if (initview(&view) < 0) sysfatal("initview failed: %r); rich.obj = malloc(sizeof(Object) * 4); rich.count = 4; - rich.obj[0] = (Object){"text", "", "hello ", strlen("hello ")}; + rich.obj[0] = (Object){ + "text", + "font=/lib/font/bit/terminus/unicode.14.font", + "Hello ", + strlen("Hello ") + }; rich.obj[1] = (Object){ "text", - "font=/lib/font/bit/terminusunicode.18.font", - "world", - strlen("world") + "font=/lib/font/bit/terminus/unicode.18.font", + " world", + strlen(" world") }; rich.obj[2] = (Object){"text", "", "!", strlen("!")}; - rich.obj[3] = (Object){"text", "", "\n", strlen("\n")}; + rich.obj[3] = (Object){"text", "", "\t\n", strlen("\t\n")}; rich.page = generatepage(screen->r, &rich); @@ -89,7 +105,11 @@ threadmain(int argc, char **argv) case RESIZE: if (getwindow(display, Refnone) < 0) sysfatal("resize failed: %r"); + rich.page = generatepage(screen->r, &rich); draw(screen, screen->r, display->black, nil, ZP); + for (i = 0; i < 4; i++){ + drawview(screen, &rich.page.view[i]); + } flushimage(display, 1); break; case NONE: @@ -120,36 +140,80 @@ generatepage(Rectangle r, Rich *rich) char *bp, buf[BSIZE], *argc[2]; Object *obj; View view; - int i, argv; + int newline, ymax, i, argv; Point pt; Page page; + page.view = nil; page.count = 0; pt = r.min; - for (i = 0; i < rich->count; i++) { + for (ymax = 0, i = 0; i < rich->count; i++) { + // TODO: set newline=1 when there's \n character + // or when we hit the edge of the window + newline = 0; obj = &rich->obj[i]; - strncpy(buf, obj->opts, BSIZE); - for (bp = buf; (bp != nil) && - (argv = tokenize(bp, argc, 2) > 0); bp = argc[1]){ - if (strstr(argc[0], "font") == argc[0]) { - fprint(2, "we got a font\n"); - } - if (argv == 1) break; - } + page.count++; page.view = realloc(page.view, sizeof(View) * (page.count)); + view.obj = obj; view.page = &page; + view.font = font; view.dp = obj->data; view.length = strlen(view.dp); - view.font = font; + strncpy(buf, obj->opts, BSIZE); + for (bp = buf; (bp != nil) && (argv = tokenize(bp, argc, 2) > 0); bp = argc[1]){ + if (strstr(argc[0], "font") == argc[0]) { + view.font = getfont(&fonts, argc[0] + 5); + } + if (argv == 1) break; + } view.r = (Rectangle){ pt, addpt(pt, Pt(stringnwidth(view.font, view.dp, view.length), view.font->height)) }; + page.view[page.count -1] = view; - pt.y = view.r.max.y; + ymax = (ymax > view.r.max.y) ? ymax : view.r.max.y; + if (newline == 0) pt.x = view.r.max.x; + else { + pt.x = r.min.x; + pt.y += ymax; + ymax = 0; + } } return page; } + +Font * +getfont(struct Fonts *fonts, char *name) +{ + int i; + Font *newfont; + for (i = 0; i < fonts->count; i++){ + if (strcmp(fonts->data[i]->name, name) == 0) return fonts->data[i]; + } + if ((newfont = openfont(display, name)) == nil) { + fprint(2, "can't load font %s\n", name); + newfont = font; + } else { + addfont(fonts, newfont); + } + return newfont; +} + +void +addfont(struct Fonts *fonts, Font *font) +{ + if (fonts->data == nil) { + fonts->data = mallocz(16 * sizeof(Font*), 1); + fonts->size = 16; + } + if (fonts->count >= fonts->size) { + fonts->size = fonts->size * 2; + fonts->data = realloc(fonts->data, fonts->size * sizeof(Font*)); + } + fonts->data[fonts->count] = font; + fonts->count++; +} +\ No newline at end of file