summaryrefslogtreecommitdiffstats
path: root/usr.bin/tmux/grid.c
diff options
context:
space:
mode:
authornicm <nicm@openbsd.org>2020-05-25 09:32:10 +0000
committernicm <nicm@openbsd.org>2020-05-25 09:32:10 +0000
commit5832c8de7fc8451dd2a84667a1d4f5b8a30b99a7 (patch)
tree4f8182cf8330c793812bed5426bff1aed14e9e15 /usr.bin/tmux/grid.c
parentFor regular users sndioctl(1) can be restricted to pledge(2) "stdio", but since (diff)
downloadwireguard-openbsd-5832c8de7fc8451dd2a84667a1d4f5b8a30b99a7.tar.xz
wireguard-openbsd-5832c8de7fc8451dd2a84667a1d4f5b8a30b99a7.zip
Instead of storing all UTF-8 characters in the extended cell which means
that 14 bytes are wasted for each character in the BMP, only store characters of three bytes or less in the cell itself and store others (outside the BMP or with combining characters) in a separate global tree. Can reduce grid memory use for heavy Unicode users by around 30%.
Diffstat (limited to 'usr.bin/tmux/grid.c')
-rw-r--r--usr.bin/tmux/grid.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/usr.bin/tmux/grid.c b/usr.bin/tmux/grid.c
index 3c36d359603..d2cc6a2efc3 100644
--- a/usr.bin/tmux/grid.c
+++ b/usr.bin/tmux/grid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: grid.c,v 1.109 2020/05/16 16:22:01 nicm Exp $ */
+/* $OpenBSD: grid.c,v 1.110 2020/05/25 09:32:10 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -100,11 +100,11 @@ grid_get_extended_cell(struct grid_line *gl, struct grid_cell_entry *gce,
}
/* Set cell as extended. */
-static struct grid_cell *
+static struct grid_extd_entry *
grid_extended_cell(struct grid_line *gl, struct grid_cell_entry *gce,
const struct grid_cell *gc)
{
- struct grid_cell *gcp;
+ struct grid_extd_entry *gee;
int flags = (gc->flags & ~GRID_FLAG_CLEARED);
if (~gce->flags & GRID_FLAG_EXTENDED)
@@ -113,10 +113,14 @@ grid_extended_cell(struct grid_line *gl, struct grid_cell_entry *gce,
fatalx("offset too big");
gl->flags |= GRID_LINE_EXTENDED;
- gcp = &gl->extddata[gce->offset];
- memcpy(gcp, gc, sizeof *gcp);
- gcp->flags = flags;
- return (gcp);
+ gee = &gl->extddata[gce->offset];
+ gee->data = utf8_map_big(&gc->data);
+ gee->attr = gc->attr;
+ gee->flags = flags;
+ gee->fg = gc->fg;
+ gee->bg = gc->bg;
+ gee->us = gc->us;
+ return (gee);
}
/* Free up unused extended cells. */
@@ -124,9 +128,9 @@ static void
grid_compact_line(struct grid_line *gl)
{
int new_extdsize = 0;
- struct grid_cell *new_extddata;
+ struct grid_extd_entry *new_extddata;
struct grid_cell_entry *gce;
- struct grid_cell *gc;
+ struct grid_extd_entry *gee;
u_int px, idx;
if (gl->extdsize == 0)
@@ -150,8 +154,8 @@ grid_compact_line(struct grid_line *gl)
for (px = 0; px < gl->cellsize; px++) {
gce = &gl->celldata[px];
if (gce->flags & GRID_FLAG_EXTENDED) {
- gc = &gl->extddata[gce->offset];
- memcpy(&new_extddata[idx], gc, sizeof *gc);
+ gee = &gl->extddata[gce->offset];
+ memcpy(&new_extddata[idx], gee, sizeof *gee);
gce->offset = idx++;
}
}
@@ -181,17 +185,14 @@ grid_clear_cell(struct grid *gd, u_int px, u_int py, u_int bg)
{
struct grid_line *gl = &gd->linedata[py];
struct grid_cell_entry *gce = &gl->celldata[px];
- struct grid_cell *gc;
+ struct grid_extd_entry *gee;
memcpy(gce, &grid_cleared_entry, sizeof *gce);
if (bg != 8) {
if (bg & COLOUR_FLAG_RGB) {
grid_get_extended_cell(gl, gce, gce->flags);
- gl->flags |= GRID_LINE_EXTENDED;
-
- gc = &gl->extddata[gce->offset];
- memcpy(gc, &grid_cleared_cell, sizeof *gc);
- gc->bg = bg;
+ gee = grid_extended_cell(gl, gce, &grid_cleared_cell);
+ gee->bg = bg;
} else {
if (bg & COLOUR_FLAG_256)
gce->flags |= GRID_FLAG_BG256;
@@ -483,12 +484,20 @@ static void
grid_get_cell1(struct grid_line *gl, u_int px, struct grid_cell *gc)
{
struct grid_cell_entry *gce = &gl->celldata[px];
+ struct grid_extd_entry *gee;
if (gce->flags & GRID_FLAG_EXTENDED) {
if (gce->offset >= gl->extdsize)
memcpy(gc, &grid_default_cell, sizeof *gc);
- else
- memcpy(gc, &gl->extddata[gce->offset], sizeof *gc);
+ else {
+ gee = &gl->extddata[gce->offset];
+ gc->flags = gee->flags;
+ gc->attr = gee->attr;
+ gc->fg = gee->fg;
+ gc->bg = gee->bg;
+ gc->us = gee->us;
+ utf8_get_big(gee->data, &gc->data);
+ }
return;
}
@@ -545,7 +554,7 @@ grid_set_cells(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc,
{
struct grid_line *gl;
struct grid_cell_entry *gce;
- struct grid_cell *gcp;
+ struct grid_extd_entry *gee;
u_int i;
if (grid_check_y(gd, __func__, py) != 0)
@@ -560,8 +569,8 @@ grid_set_cells(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc,
for (i = 0; i < slen; i++) {
gce = &gl->celldata[px + i];
if (grid_need_extended_cell(gce, gc)) {
- gcp = grid_extended_cell(gl, gce, gc);
- utf8_set(&gcp->data, s[i]);
+ gee = grid_extended_cell(gl, gce, gc);
+ gee->data = utf8_set_big(s[i], 1);
} else
grid_store_cell(gce, gc, s[i]);
}