ref: 655c657d070ebf46a869a90b1bc79a3601692247
parent: 37d24eaeea5017212d9fcad84619089603f6b64f
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Sat Feb 15 13:03:03 EST 2020
plan9: redraw only parts of the field that were changed, helps with huge fields
--- a/plan9.c
+++ b/plan9.c
@@ -52,6 +52,9 @@
Dblow,
Dbinv,
Numcolors,
+
+ /* this might become a bad idea in the future */
+ Mark_flag_selected = 1<<7,
};
struct Key {
@@ -68,11 +71,11 @@
static int selw = 1, selh = 1;
static int charw, charh;
static Field field;
-static Mbuf_reusable mbuf;
+static Mbuf_reusable mbuf, mscr;
static Oevent_list events;
static char filename[256];
static Channel *cchan;
-static Field copyfield;
+static Field copyfield, selfield;
static int altdown;
static int mode = Minsert;
static long framedev; /* frame deviation >= 1ms */
@@ -312,7 +315,7 @@
Rectangle r;
Point p, top, bot;
int x, y, rx, ry, i;
- int oldbg, oldfg, bg, fg, attr, selected;
+ int oldbg, oldfg, bg, fg, attr, selected, off;
char s[32];
Rune c;
@@ -336,20 +339,38 @@
bg = -1;
fg = -1;
for (y = 0; y < field.height && p.y < bot.y-charh; y++) {
+ p.x = top.x;
for (x = i = 0; x < field.width && x < screen->r.max.x-Txtoff; x++) {
oldbg = bg;
oldfg = fg;
+ off = field.width*y + x;
- c = field.buffer[field.width*y + x];
- attr = mbuf.buffer[field.width*y + x];
+ c = field.buffer[off];
+ attr = mbuf.buffer[off];
+ selected = x >= curx && y >= cury && x < curx+selw && y < cury+selh;
+ if (selected)
+ attr |= Mark_flag_selected;
+ else
+ attr &= ~Mark_flag_selected;
- if (c == '.')
- c = dot[dotstyle];
+ if (!complete && c == copyfield.buffer[off] && attr == mscr.buffer[off]) {
+ if (i > 0) {
+ p = runestringnbg(screen, p, color[oldfg], ZP, font, linebuf, i, color[oldbg], ZP);
+ i = 0;
+ }
+ p.x += charw;
+ continue;
+ }
- selected = x >= curx && y >= cury && x < curx+selw && y < cury+selh;
+ copyfield.buffer[off] = c;
+ mscr.buffer[off] = attr;
+
bg = selected ? Dbinv : Dback;
fg = selected ? Dfinv : Dfhigh;
+ if (c == '.')
+ c = dot[dotstyle];
+
if (c == dot[dotstyle] && attr == 0) {
if ((x % gridw) == 0 && (y % gridh) == 0) {
rx = !!x + (x + 1) / field.width;
@@ -391,7 +412,6 @@
}
runestringnbg(screen, p, color[fg], ZP, font, linebuf, i, color[bg], ZP);
p.y += charh;
- p.x = top.x;
}
r = screen->r;
@@ -510,31 +530,28 @@
static void
selmove(int x, int y)
{
- int i;
+ int i, n;
if (curx+x < 0 || cury+y < 0)
return;
- field_resize_raw(©field, selh, selw);
+ field_resize_raw(&selfield, selh, selw);
gbuffer_copy_subrect(
- field.buffer,
- copyfield.buffer,
- field.height, field.width,
- copyfield.height, copyfield.width,
- cury, curx, 0, 0,
- selh, selw
+ field.buffer, selfield.buffer,
+ field.height, field.width, selh, selw,
+ cury, curx, 0, 0, selh, selw
);
- for (i = cury; i < cury+selh && i < field.height; i++)
- memset(&field.buffer[curx + field.width*i], '.', MIN(selw, field.width-curx));
+ n = MIN(selw, field.width-curx);
+ for (i = cury; i < cury+selh && i < field.height; i++) {
+ memset(&field.buffer[curx + field.width*i], '.', n);
+ memset(&mbuf.buffer[curx + field.width*i], 0, n);
+ }
gbuffer_copy_subrect(
- copyfield.buffer,
- field.buffer,
- copyfield.height, copyfield.width,
- field.height, field.width,
- 0, 0, cury+y, curx+x,
- selh, selw
+ selfield.buffer, field.buffer,
+ selh, selw, field.height, field.width,
+ 0, 0, cury+y, curx+x, selh, selw
);
}
@@ -688,12 +705,19 @@
screensize(&w, &h);
field_init_fill(&field, h, w, '.');
- field_init(©field);
+ field_init_fill(©field, h, w, '.');
+ field_init(&selfield);
linebuf = malloc(sizeof(Rune)*MAX(w+1, 64));
memset(noteoff, 0, sizeof(noteoff));
+
mbuf_reusable_init(&mbuf);
mbuf_reusable_ensure_size(&mbuf, h, w);
+ memset(mbuf.buffer, 0, w*h);
+ mbuf_reusable_init(&mscr);
+ mbuf_reusable_ensure_size(&mscr, h, w);
+ memset(mscr.buffer, 0, w*h);
+
oevent_list_init(&events);
proccreate(orcathread, a[Credraw].c, mainstacksize);
@@ -721,10 +745,8 @@
w = field.width;
h = field.height;
strncpy(filename, tmp, sizeof(filename));
- complete = 1;
} else if (n == Menu3save && fieldsave(tmp) == 0) {
strncpy(filename, tmp, sizeof(filename));
- complete = 1;
}
}
} else if (n == Menu3dotstyle) {
@@ -734,6 +756,7 @@
} else if (n == Menu3exit) {
goto end;
}
+ complete = 1;
}
break;
@@ -904,34 +927,40 @@
// fprint(2, "unhandled key %04x\n", key.rune);
break;
}
-
- if (w != oldw || h != oldh) {
- field_copy(&field, ©field);
- field_resize_raw(&field, h, w);
- memset(field.buffer, '.', w*h);
- gbuffer_copy_subrect(
- copyfield.buffer,
- field.buffer,
- copyfield.height, copyfield.width,
- field.height, field.width,
- 0, 0, 0, 0,
- MIN(field.height, copyfield.height), MIN(field.width, copyfield.width)
- );
- }
}
if (w != oldw || h != oldh) {
+ mbuf_reusable_ensure_size(&mscr, h, w);
+ memset(mscr.buffer, 0, w*h);
+ for (n = 0; n < oldh; n++)
+ memmove(&mscr.buffer[n*w], &mbuf.buffer[n*oldw], oldw);
mbuf_reusable_ensure_size(&mbuf, h, w);
+ memmove(mbuf.buffer, mscr.buffer, w*h);
linebuf = realloc(linebuf, sizeof(Rune)*MAX(w+1, 64));
+
+ field_resize_raw(©field, h, w);
+ field_copy(&field, ©field);
+ field_resize_raw(&field, h, w);
+ memset(field.buffer, '.', w*h);
+ gbuffer_copy_subrect(
+ copyfield.buffer, field.buffer,
+ copyfield.height, copyfield.width, h, w,
+ 0, 0, 0, 0, MIN(h, copyfield.height), MIN(w, copyfield.width)
+ );
+ field_resize_raw(©field, h, w);
+
complete = 1;
}
}
end:
+ mbuf_reusable_deinit(&mscr);
mbuf_reusable_deinit(&mbuf);
oevent_list_deinit(&events);
field_deinit(&field);
field_deinit(©field);
+ field_deinit(&selfield);
+ free(linebuf);
threadexitsall(nil);
}