richterm

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

commit 7c4d69004a4eec1d8407edd43e892b1c80db909e
parent 8375d76ba651551481a377643db178c5da61b136
Author: Pavel Renev <an2qzavok@gmail.com>
Date:   Sat,  7 Aug 2021 17:07:58 +0000

stop trying to reload fonts on every generatepage

font is now stored in Object instead of View
in the process rich->obj was reworked from array into array of pointers.

Diffstat:
Mfs.c | 24++++++++++++++++--------
Mrichterm.c | 108++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mrichterm.h | 27++++++++++++++++++++-------
3 files changed, 105 insertions(+), 54 deletions(-)

diff --git a/fs.c b/fs.c @@ -21,11 +21,12 @@ ctlcmd(char *buf) int i, j; for (i = 0; i < n; i++) { for (j = 0; j < rich.count; j++) { - if (strcmp(rich.obj[j].id, args[i]) == 0) { + if (strcmp(rich.obj[j]->id, args[i]) == 0) { Object *sp, *tp; - rmobjectftree(&rich.obj[j]); - sp = &rich.obj[j]; - tp = &rich.obj[j+1]; + rmobjectftree(rich.obj[j]); + free(rich.obj[j]); + sp = rich.obj[j]; + tp = rich.obj[j+1]; memcpy(sp, tp, (rich.count - j - 1) * sizeof(Object)); rich.count--; break; @@ -33,8 +34,10 @@ ctlcmd(char *buf) } } } else if (strcmp(args[0], "clear") == 0) { - for (rich.count--; rich.count >= 0; rich.count--) - rmobjectftree(rich.obj + rich.count); + for (rich.count--; rich.count == 0; rich.count--) { + rmobjectftree(rich.obj[rich.count]); + free(rich.obj[rich.count]); + } rich.count = 0; rich.obj = realloc(rich.obj, 0); } else return "unknown command"; @@ -105,15 +108,20 @@ fs_write(Req *r) /* TODO: this is not exactly finished */ n = r->ifcall.offset + r->ifcall.count; m = (r->ifcall.offset > aux->data->n) ? aux->data->n : r->ifcall.offset; - buf = mallocz(n, 1); + buf = mallocz(n + 1, 1); memcpy(buf, aux->data->p, m); memcpy(buf + r->ifcall.offset, r->ifcall.data, r->ifcall.count); free(aux->data->p); aux->data->p = buf; aux->data->n = n; r->ofcall.count = r->ifcall.count; - respond(r, nil); + + if (aux->type == FT_FONT) { + aux->obj->font = getfont(&fonts, aux->data->p); + } + qunlock(rich.l); + respond(r, nil); redraw(1); } else respond(r, "fs_write: f->aux is nil"); } diff --git a/richterm.c b/richterm.c @@ -72,7 +72,13 @@ threadmain(int argc, char **argv) mmode = 0; - Iscrollbar = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x888888FF); + Iscrollbar = allocimage( + display, + Rect(0,0,1,1), + screen->chan, + 1, + 0x888888FF); + Ilink = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DBlue); resize(); @@ -110,21 +116,29 @@ threadmain(int argc, char **argv) redraw(1); break; case KBD: - if (kv == 0x7f) shutdown(); + if (kv == 0x7f) shutdown(); /* delete */ if (kv == 0xf00e) { /* d-pad up */ - scroll(Pt(0, rich.page.scroll.y - Dy(screen->r) / 8), &rich); + scroll( + Pt(0, rich.page.scroll.y - Dy(screen->r) / 8), + &rich); break; } if (kv == 0xf800) { /* d-pad down */ - scroll(Pt(0, rich.page.scroll.y + Dy(screen->r) / 8), &rich); + scroll( + Pt(0, rich.page.scroll.y + Dy(screen->r) / 8), + &rich); break; } if (kv == 0xf00f) { /* page up */ - scroll(Pt(0, rich.page.scroll.y - Dy(screen->r) / 4), &rich); + scroll( + Pt(0, rich.page.scroll.y - Dy(screen->r) / 4), + &rich); break; } if (kv == 0xf013) { /* page down */ - scroll(Pt(0, rich.page.scroll.y + Dy(screen->r) / 4), &rich); + scroll( + Pt(0, rich.page.scroll.y + Dy(screen->r) / 4), + &rich); break; } if (rich.obj != nil) { @@ -132,7 +146,7 @@ threadmain(int argc, char **argv) qlock(rich.l); - olast = rich.obj + rich.count - 1; + olast = rich.obj[rich.count - 1]; aux = olast->ftext->aux; aux->data->n+=runelen(kv); aux->data->p = realloc(aux->data->p, aux->data->n + 1); @@ -158,25 +172,40 @@ mouse(Mouse mv, int mmode) { if (mv.buttons == 0) mmode = 0; if (mv.buttons == 8) { - scroll(subpt(rich.page.scroll, Pt(0, mv.xy.y - rich.page.r.min.y)), &rich); + scroll( + subpt(rich.page.scroll, + Pt(0, mv.xy.y - rich.page.r.min.y)), + &rich); return mmode; } if (mv.buttons == 16) { - scroll(addpt(rich.page.scroll, Pt(0, mv.xy.y - rich.page.r.min.y)), &rich); + scroll( + addpt(rich.page.scroll, + Pt(0, mv.xy.y - rich.page.r.min.y)), + &rich); return mmode; } if (ptinrect(mv.xy, rich.page.rs) != 0) { /* scrollbar */ if (mv.buttons == 1) { - scroll(subpt(rich.page.scroll, Pt(0, mv.xy.y - rich.page.r.min.y)), &rich); + scroll( + subpt(rich.page.scroll, + Pt(0, mv.xy.y - rich.page.r.min.y)), + &rich); } else if (mv.buttons == 4) { - scroll(addpt(rich.page.scroll, Pt(0, mv.xy.y - rich.page.r.min.y)), &rich); + scroll( + addpt(rich.page.scroll, + Pt(0, mv.xy.y - rich.page.r.min.y)), + &rich); } else if (mv.buttons == 2) { mmode = 1; } } if (mmode == 1) { int y; - y = (mv.xy.y - rich.page.r.min.y) * ((double)rich.page.max.y / Dy(rich.page.r)); + + y = (mv.xy.y - rich.page.r.min.y) * + ((double)rich.page.max.y / Dy(rich.page.r)); + scroll(Pt(rich.page.scroll.x, y), &rich); } else { /* text area */ if (mv.buttons == 1) { @@ -229,7 +258,7 @@ drawview(Image *dst, View *v) Rectangle r; r = rectsubpt(v->r, v->page->scroll); draw(dst, r, display->white, nil, ZP); - stringn(dst, r.min, v->color, ZP, v->font, v->dp, v->length); + stringn(dst, r.min, v->color, ZP, v->obj->font, v->dp, v->length); } void @@ -238,9 +267,9 @@ generatepage(Rich *rich) #define BSIZE 4096 Rectangle r; - char *sp, *buf; + char *sp; Object *obj; - int newline, tab, ymax; + int newline, tab, ymax, i; Point pt; Page *page; View *v; @@ -263,27 +292,22 @@ generatepage(Rich *rich) return; } - obj = rich->obj; + obj = *rich->obj; aux = obj->ftext->aux; sp = aux->data->p; - while (obj < rich->obj + rich->count) { + i = 0; + while (i < rich->count) { newline = 0; tab = 0; page->count++; page->view = realloc(page->view, sizeof(View) * (page->count)); - v = page->view + page->count - 1; + v = &page->view[page->count - 1]; v->obj = obj; v->color = display->black; if (((Faux *)obj->flink->aux)->data->n > 0) v->color = Ilink; v->page = &rich->page; - buf = mallocz(((Faux *)obj->ffont->aux)->data->n + 1, 1); - memcpy(buf, ((Faux *)obj->ffont->aux)->data->p, ((Faux *)obj->ffont->aux)->data->n); - buf[((Faux *)obj->ffont->aux)->data->n] = '\0'; - v->font = getfont(&fonts, buf); - free(buf); - v->dp = sp; v->length = aux->data->n; @@ -299,14 +323,14 @@ generatepage(Rich *rich) break; } } - while (stringnwidth(v->font, v->dp, v->length) > (r.max.x - pt.x)) { + while (stringnwidth(v->obj->font, v->dp, v->length) > (r.max.x - pt.x)) { newline = 1; v->length--; sp = v->dp + v->length; } - v->r = Rpt(pt, Pt(pt.x + stringnwidth(v->font, v->dp, v->length), - pt.y + v->font->height)); + v->r = Rpt(pt, Pt(pt.x + stringnwidth(v->obj->font, v->dp, v->length), + pt.y + v->obj->font->height)); ymax = (ymax > v->r.max.y) ? ymax : v->r.max.y; pt.x = v->r.max.x; @@ -329,8 +353,9 @@ generatepage(Rich *rich) } if (v->length >= aux->data->n - 1) { - obj++; - if (obj < rich->obj + rich->count) { + i++; + obj = rich->obj[i]; + if (i < rich->count) { aux = obj->ftext->aux; sp = aux->data->p; } @@ -344,7 +369,7 @@ generatepage(Rich *rich) } Font * -getfont(struct Fonts *fonts, char *name) +getfont(Fonts *fonts, char *name) { int i; Font *newfont; @@ -361,7 +386,7 @@ getfont(struct Fonts *fonts, char *name) } void -addfont(struct Fonts *fonts, Font *font) +addfont(Fonts *fonts, Font *font) { if (fonts->data == nil) { fonts->data = mallocz(16 * sizeof(Font*), 1); @@ -389,10 +414,12 @@ scroll(Point p, Rich *r) } Faux * -fauxalloc(char *str) +fauxalloc(Object *obj, char *str, int type) { Faux *aux; aux = mallocz(sizeof(Faux), 1); + aux->obj = obj; + aux->type = type; aux->data = mallocz(sizeof(Data), 1); aux->data->p = str; aux->data->n = strlen(str); @@ -406,9 +433,10 @@ newobject(Rich *rich) qlock(rich->l); rich->count++; rich->idcount++; - rich->obj = realloc(rich->obj, rich->count * sizeof(Object)); - obj = &(rich->obj[rich->count - 1]); - obj->id = smprint("%ld", rich->idcount); + rich->obj = realloc(rich->obj, rich->count * sizeof(Object *)); + obj = mallocz(sizeof(Object), 1); + rich->obj[rich->count - 1] = obj; + obj->id = smprint("%lld", rich->idcount); qunlock(rich->l); return obj; } @@ -422,15 +450,17 @@ mkobjectftree(Object *obj, File *root, char *text) obj->dir = createfile(root, obj->id, "richterm", DMDIR|0555, nil); - auxtext = fauxalloc(text); - auxfont = fauxalloc(strdup(font->name)); - auxlink = fauxalloc(strdup("")); - auximage = fauxalloc(strdup("")); + auxtext = fauxalloc(obj, text, FT_TEXT); + auxfont = fauxalloc(obj, strdup(font->name), FT_FONT); + auxlink = fauxalloc(obj, strdup(""), FT_LINK); + auximage = fauxalloc(obj, strdup(""), FT_IMAGE); obj->ftext = createfile(obj->dir, "text", "richterm", 0666, auxtext); obj->ffont = createfile(obj->dir, "font", "richterm", 0666, auxfont); obj->flink = createfile(obj->dir, "link", "richterm", 0666, auxlink); obj->fimage = createfile(obj->dir, "image", "richterm", 0666, auximage); + + obj->font = font; qunlock(rich.l); return obj; } diff --git a/richterm.h b/richterm.h @@ -17,6 +17,7 @@ struct Object { File *flink; File *fimage; char *id; + Font *font; }; Object * mkobjectftree(Object *, File *, char *); @@ -30,6 +31,8 @@ struct Fonts { int count; }; +extern Fonts fonts; + Font* getfont(Fonts *, char *); void addfont(Fonts *, Font *); @@ -38,13 +41,12 @@ typedef struct View View; typedef struct Page Page; struct View { + Page *page; Object *obj; char *dp; long length; - Font *font; Image *color; Rectangle r; - Page *page; }; struct Page { @@ -64,10 +66,12 @@ typedef struct Rich Rich; struct Rich { QLock *l; - Object *obj; - long count; - long idcount; + Object **obj; + usize count; + usize idcount; Page page; + usize selstart; + usize selend; }; extern Rich rich; @@ -98,7 +102,16 @@ Fsctl * initfs(void); typedef struct Faux Faux; struct Faux { + int type; + Object *obj; Data *data; }; -Faux * fauxalloc(char *); -\ No newline at end of file +enum { + FT_TEXT, + FT_FONT, + FT_LINK, + FT_IMAGE +}; + +Faux * fauxalloc(Object *, char *, int); +\ No newline at end of file