Sync OpenBSD patchset 226:

Change the way the grid is stored, previously it was:

- a two-dimensional array of cells;
- a two-dimensional array of utf8 data;
- an array of line lengths.

Now it is a single array of a new struct grid_line each of which represents a
line and contains the length and an array of cells and an array of utf8 data.

This will make it easier to add additional per-line members, such as flags.
This commit is contained in:
Tiago Cunha 2009-08-09 17:28:24 +00:00
parent 5b56ea1816
commit 37b0bcd7c1
7 changed files with 118 additions and 130 deletions

View File

@ -1,4 +1,4 @@
/* $Id: cmd-list-windows.c,v 1.39 2009-08-08 16:03:09 nicm Exp $ */ /* $Id: cmd-list-windows.c,v 1.40 2009-08-09 17:28:23 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -48,6 +48,7 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window *w; struct window *w;
struct window_pane *wp; struct window_pane *wp;
struct grid *gd; struct grid *gd;
struct grid_line *gl;
u_int i; u_int i;
unsigned long long size; unsigned long long size;
const char *name; const char *name;
@ -65,11 +66,11 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
size = 0; size = 0;
for (i = 0; i < gd->hsize; i++) { for (i = 0; i < gd->hsize; i++) {
size += gd->size[i] * sizeof **gd->data; gl = &gd->linedata[i];
size += gd->usize[i] * sizeof **gd->udata; size += gl->cellsize * sizeof *gl->celldata;
size += gl->utf8size * sizeof *gl->utf8data;
} }
size += gd->hsize * (sizeof *gd->data); size += gd->hsize * sizeof *gd->linedata;
size += gd->hsize * (sizeof *gd->size);
name = NULL; name = NULL;
if (wp->fd != -1) if (wp->fd != -1)

View File

@ -1,4 +1,4 @@
/* $Id: cmd-server-info.c,v 1.23 2009-07-28 23:04:29 tcunha Exp $ */ /* $Id: cmd-server-info.c,v 1.24 2009-08-09 17:28:23 tcunha Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -56,6 +56,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
struct tty_term_code_entry *ent; struct tty_term_code_entry *ent;
struct utsname un; struct utsname un;
struct grid *gd; struct grid *gd;
struct grid_line *gl;
u_int i, j, k; u_int i, j, k;
char out[80]; char out[80];
char *tim; char *tim;
@ -120,15 +121,16 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
lines = ulines = size = usize = 0; lines = ulines = size = usize = 0;
gd = wp->base.grid; gd = wp->base.grid;
for (k = 0; k < gd->hsize + gd->sy; k++) { for (k = 0; k < gd->hsize + gd->sy; k++) {
if (gd->data[k] != NULL) { gl = &gd->linedata[k];
if (gl->celldata != NULL) {
lines++; lines++;
size += gd->size[k] * size += gl->cellsize *
sizeof (**gd->data); sizeof *gl->celldata;
} }
if (gd->udata[k] != NULL) { if (gl->utf8data != NULL) {
ulines++; ulines++;
usize += gd->usize[k] * usize += gl->utf8size *
sizeof (**gd->udata); sizeof *gl->utf8data;
} }
} }
ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu " ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu "

168
grid.c
View File

@ -1,4 +1,4 @@
/* $Id: grid.c,v 1.28 2009-07-22 17:31:20 tcunha Exp $ */ /* $Id: grid.c,v 1.29 2009-08-09 17:28:23 tcunha Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -38,10 +38,12 @@
const struct grid_cell grid_default_cell = { 0, 0, 8, 8, ' ' }; const struct grid_cell grid_default_cell = { 0, 0, 8, 8, ' ' };
#define grid_put_cell(gd, px, py, gc) do { \ #define grid_put_cell(gd, px, py, gc) do { \
memcpy(&gd->data[py][px], gc, sizeof gd->data[py][px]); \ memcpy(&gd->linedata[py].celldata[px], \
gc, sizeof gd->linedata[py].celldata[px]); \
} while (0) } while (0)
#define grid_put_utf8(gd, px, py, gc) do { \ #define grid_put_utf8(gd, px, py, gc) do { \
memcpy(&gd->udata[py][px], gc, sizeof gd->udata[py][px]); \ memcpy(&gd->linedata[py].utf8data[px], \
gc, sizeof gd->linedata[py].utf8data[px]); \
} while (0) } while (0)
int grid_check_x(struct grid *, u_int); int grid_check_x(struct grid *, u_int);
@ -100,11 +102,7 @@ grid_create(u_int sx, u_int sy, u_int hlimit)
gd->hsize = 0; gd->hsize = 0;
gd->hlimit = hlimit; gd->hlimit = hlimit;
gd->size = xcalloc(gd->sy, sizeof *gd->size); gd->linedata = xcalloc(gd->sy, sizeof *gd->linedata);
gd->data = xcalloc(gd->sy, sizeof *gd->data);
gd->usize = xcalloc(gd->sy, sizeof *gd->usize);
gd->udata = xcalloc(gd->sy, sizeof *gd->udata);
return (gd); return (gd);
} }
@ -113,24 +111,18 @@ grid_create(u_int sx, u_int sy, u_int hlimit)
void void
grid_destroy(struct grid *gd) grid_destroy(struct grid *gd)
{ {
struct grid_line *gl;
u_int yy; u_int yy;
for (yy = 0; yy < gd->hsize + gd->sy; yy++) { for (yy = 0; yy < gd->hsize + gd->sy; yy++) {
if (gd->udata[yy] != NULL) gl = &gd->linedata[yy];
xfree(gd->udata[yy]); if (gl->celldata != NULL)
if (gd->data[yy] != NULL) xfree(gl->celldata);
xfree(gd->data[yy]); if (gl->utf8data != NULL)
xfree(gl->utf8data);
} }
if (gd->udata != NULL) xfree(gd->linedata);
xfree(gd->udata);
if (gd->usize != NULL)
xfree(gd->usize);
if (gd->data != NULL)
xfree(gd->data);
if (gd->size != NULL)
xfree(gd->size);
xfree(gd); xfree(gd);
} }
@ -139,6 +131,7 @@ grid_destroy(struct grid *gd)
int int
grid_compare(struct grid *ga, struct grid *gb) grid_compare(struct grid *ga, struct grid *gb)
{ {
struct grid_line *gla, *glb;
struct grid_cell *gca, *gcb; struct grid_cell *gca, *gcb;
struct grid_utf8 *gua, *gub; struct grid_utf8 *gua, *gub;
u_int xx, yy; u_int xx, yy;
@ -147,17 +140,19 @@ grid_compare(struct grid *ga, struct grid *gb)
return (1); return (1);
for (yy = 0; yy < ga->sy; yy++) { for (yy = 0; yy < ga->sy; yy++) {
if (ga->size[yy] != gb->size[yy]) gla = &ga->linedata[yy];
glb = &gb->linedata[yy];
if (gla->cellsize != glb->cellsize)
return (1); return (1);
for (xx = 0; xx < ga->sx; xx++) { for (xx = 0; xx < ga->sx; xx++) {
gca = &ga->data[yy][xx]; gca = &gla->celldata[xx];
gcb = &gb->data[yy][xx]; gcb = &glb->celldata[xx];
if (memcmp(gca, gcb, sizeof (struct grid_cell)) != 0) if (memcmp(gca, gcb, sizeof (struct grid_cell)) != 0)
return (1); return (1);
if (!(gca->flags & GRID_FLAG_UTF8)) if (!(gca->flags & GRID_FLAG_UTF8))
continue; continue;
gua = &ga->udata[yy][xx]; gua = &gla->utf8data[xx];
gub = &gb->udata[yy][xx]; gub = &glb->utf8data[xx];
if (memcmp(gua, gub, sizeof (struct grid_utf8)) != 0) if (memcmp(gua, gub, sizeof (struct grid_utf8)) != 0)
return (1); return (1);
} }
@ -186,15 +181,8 @@ grid_scroll_line(struct grid *gd)
yy = gd->hsize + gd->sy; yy = gd->hsize + gd->sy;
gd->size = xrealloc(gd->size, yy + 1, sizeof *gd->size); gd->linedata = xrealloc(gd->linedata, yy + 1, sizeof *gd->linedata);
gd->size[yy] = 0; memset(&gd->linedata[yy], 0, sizeof gd->linedata[yy]);
gd->data = xrealloc(gd->data, yy + 1, sizeof *gd->data);
gd->data[yy] = NULL;
gd->usize = xrealloc(gd->usize, yy + 1, sizeof *gd->usize);
gd->usize[yy] = 0;
gd->udata = xrealloc(gd->udata, yy + 1, sizeof *gd->udata);
gd->udata[yy] = NULL;
gd->hsize++; gd->hsize++;
} }
@ -203,26 +191,31 @@ grid_scroll_line(struct grid *gd)
void void
grid_expand_line(struct grid *gd, u_int py, u_int sx) grid_expand_line(struct grid *gd, u_int py, u_int sx)
{ {
struct grid_line *gl;
u_int xx; u_int xx;
if (sx <= gd->size[py]) gl = &gd->linedata[py];
if (sx <= gl->cellsize)
return; return;
gd->data[py] = xrealloc(gd->data[py], sx, sizeof **gd->data); gl->celldata = xrealloc(gl->celldata, sx, sizeof *gl->celldata);
for (xx = gd->size[py]; xx < sx; xx++) for (xx = gl->cellsize; xx < sx; xx++)
grid_put_cell(gd, xx, py, &grid_default_cell); grid_put_cell(gd, xx, py, &grid_default_cell);
gd->size[py] = sx; gl->cellsize = sx;
} }
/* Expand line to fit to cell for UTF-8. */ /* Expand line to fit to cell for UTF-8. */
void void
grid_expand_line_utf8(struct grid *gd, u_int py, u_int sx) grid_expand_line_utf8(struct grid *gd, u_int py, u_int sx)
{ {
if (sx <= gd->usize[py]) struct grid_line *gl;
gl = &gd->linedata[py];
if (sx <= gl->utf8size)
return; return;
gd->udata[py] = xrealloc(gd->udata[py], sx, sizeof **gd->udata); gl->utf8data = xrealloc(gl->utf8data, sx, sizeof *gl->utf8data);
gd->usize[py] = sx; gl->utf8size = sx;
} }
/* Get cell for reading. */ /* Get cell for reading. */
@ -234,9 +227,9 @@ grid_peek_cell(struct grid *gd, u_int px, u_int py)
if (grid_check_y(gd, py) != 0) if (grid_check_y(gd, py) != 0)
return (&grid_default_cell); return (&grid_default_cell);
if (px >= gd->size[py]) if (px >= gd->linedata[py].cellsize)
return (&grid_default_cell); return (&grid_default_cell);
return (&gd->data[py][px]); return (&gd->linedata[py].celldata[px]);
} }
/* Get cell at relative position (for writing). */ /* Get cell at relative position (for writing). */
@ -249,7 +242,7 @@ grid_get_cell(struct grid *gd, u_int px, u_int py)
return (NULL); return (NULL);
grid_expand_line(gd, py, px + 1); grid_expand_line(gd, py, px + 1);
return (&gd->data[py][px]); return (&gd->linedata[py].celldata[px]);
} }
/* Set cell at relative position. */ /* Set cell at relative position. */
@ -275,9 +268,9 @@ grid_peek_utf8(struct grid *gd, u_int px, u_int py)
if (grid_check_y(gd, py) != 0) if (grid_check_y(gd, py) != 0)
return (NULL); return (NULL);
if (px >= gd->usize[py]) if (px >= gd->linedata[py].utf8size)
return (NULL); return (NULL);
return (&gd->udata[py][px]); return (&gd->linedata[py].utf8data[px]);
} }
/* Get utf8 at relative position (for writing). */ /* Get utf8 at relative position (for writing). */
@ -290,7 +283,7 @@ grid_get_utf8(struct grid *gd, u_int px, u_int py)
return (NULL); return (NULL);
grid_expand_line_utf8(gd, py, px + 1); grid_expand_line_utf8(gd, py, px + 1);
return (&gd->udata[py][px]); return (&gd->linedata[py].utf8data[px]);
} }
/* Set utf8 at relative position. */ /* Set utf8 at relative position. */
@ -337,7 +330,7 @@ grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny)
for (yy = py; yy < py + ny; yy++) { for (yy = py; yy < py + ny; yy++) {
for (xx = px; xx < px + nx; xx++) { for (xx = px; xx < px + nx; xx++) {
if (xx >= gd->size[yy]) if (xx >= gd->linedata[yy].cellsize)
break; break;
grid_put_cell(gd, xx, yy, &grid_default_cell); grid_put_cell(gd, xx, yy, &grid_default_cell);
} }
@ -348,6 +341,7 @@ grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny)
void void
grid_clear_lines(struct grid *gd, u_int py, u_int ny) grid_clear_lines(struct grid *gd, u_int py, u_int ny)
{ {
struct grid_line *gl;
u_int yy; u_int yy;
GRID_DEBUG(gd, "py=%u, ny=%u", py, ny); GRID_DEBUG(gd, "py=%u, ny=%u", py, ny);
@ -361,16 +355,12 @@ grid_clear_lines(struct grid *gd, u_int py, u_int ny)
return; return;
for (yy = py; yy < py + ny; yy++) { for (yy = py; yy < py + ny; yy++) {
if (gd->data[yy] != NULL) { gl = &gd->linedata[yy];
xfree(gd->data[yy]); if (gl->celldata != NULL)
gd->data[yy] = NULL; xfree(gl->celldata);
gd->size[yy] = 0; if (gl->utf8data != NULL)
} xfree(gl->utf8data);
if (gd->udata[yy] != NULL) { memset(gl, 0, sizeof *gl);
xfree(gd->udata[yy]);
gd->udata[yy] = NULL;
gd->usize[yy] = 0;
}
} }
} }
@ -401,20 +391,14 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny)
grid_clear_lines(gd, yy, 1); grid_clear_lines(gd, yy, 1);
} }
memmove(&gd->data[dy], &gd->data[py], ny * (sizeof *gd->data)); memmove(
memmove(&gd->size[dy], &gd->size[py], ny * (sizeof *gd->size)); &gd->linedata[dy], &gd->linedata[py], ny * (sizeof *gd->linedata));
memmove(&gd->udata[dy], &gd->udata[py], ny * (sizeof *gd->udata));
memmove(&gd->usize[dy], &gd->usize[py], ny * (sizeof *gd->usize));
/* Wipe any lines that have been moved (without freeing them). */ /* Wipe any lines that have been moved (without freeing them). */
for (yy = py; yy < py + ny; yy++) { for (yy = py; yy < py + ny; yy++) {
if (yy >= dy && yy < dy + ny) if (yy >= dy && yy < dy + ny)
continue; continue;
gd->data[yy] = NULL; memset(&gd->linedata[yy], 0, sizeof gd->linedata[yy]);
gd->size[yy] = 0;
gd->udata[yy] = NULL;
gd->usize[yy] = 0;
} }
} }
@ -422,6 +406,7 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny)
void void
grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx) grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
{ {
struct grid_line *gl;
u_int xx; u_int xx;
GRID_DEBUG(gd, "dx=%u, px=%u, py=%u, nx=%u", dx, px, py, nx); GRID_DEBUG(gd, "dx=%u, px=%u, py=%u, nx=%u", dx, px, py, nx);
@ -437,16 +422,18 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
return; return;
if (grid_check_y(gd, py) != 0) if (grid_check_y(gd, py) != 0)
return; return;
gl = &gd->linedata[py];
grid_expand_line(gd, py, px + nx); grid_expand_line(gd, py, px + nx);
grid_expand_line(gd, py, dx + nx); grid_expand_line(gd, py, dx + nx);
memmove(&gd->data[py][dx], &gd->data[py][px], nx * (sizeof **gd->data)); memmove(
&gl->celldata[dx], &gl->celldata[px], nx * sizeof *gl->celldata);
if (gd->udata[py] != NULL) { if (gl->utf8data != NULL) {
grid_expand_line_utf8(gd, py, px + nx); grid_expand_line_utf8(gd, py, px + nx);
grid_expand_line_utf8(gd, py, dx + nx); grid_expand_line_utf8(gd, py, dx + nx);
memmove(&gd->udata[py][dx], memmove(&gl->utf8data[dx],
&gd->udata[py][px], nx * (sizeof **gd->udata)); &gl->utf8data[px], nx * sizeof *gl->utf8data);
} }
/* Wipe any cells that have been moved. */ /* Wipe any cells that have been moved. */
@ -515,6 +502,7 @@ void
grid_duplicate_lines( grid_duplicate_lines(
struct grid *dst, u_int dy, struct grid *src, u_int sy, u_int ny) struct grid *dst, u_int dy, struct grid *src, u_int sy, u_int ny)
{ {
struct grid_line *dstl, *srcl;
u_int yy; u_int yy;
GRID_DEBUG(src, "dy=%u, sy=%u, ny=%u", dy, sy, ny); GRID_DEBUG(src, "dy=%u, sy=%u, ny=%u", dy, sy, ny);
@ -526,26 +514,24 @@ grid_duplicate_lines(
grid_clear_lines(dst, dy, ny); grid_clear_lines(dst, dy, ny);
for (yy = 0; yy < ny; yy++) { for (yy = 0; yy < ny; yy++) {
dst->size[dy] = src->size[sy]; srcl = &src->linedata[yy];
if (src->size[sy] == 0) dstl = &dst->linedata[yy];
dst->data[dy] = NULL;
else { memcpy(dstl, srcl, sizeof *dstl);
dst->data[dy] = xcalloc( if (srcl->cellsize != 0) {
src->size[sy], sizeof **dst->data); dstl->celldata = xcalloc(
memcpy(dst->data[dy], src->data[sy], srcl->cellsize, sizeof *dstl->celldata);
src->size[sy] * (sizeof **dst->data)); memcpy(dstl->celldata, srcl->celldata,
srcl->cellsize * sizeof *dstl->celldata);
}
if (srcl->utf8size != 0) {
dstl->utf8data = xcalloc(
srcl->utf8size, sizeof *dstl->utf8data);
memcpy(dstl->utf8data, srcl->utf8data,
srcl->utf8size * sizeof *dstl->utf8data);
} }
dst->usize[dy] = src->usize[sy]; sy++;
if (src->usize[sy] == 0) dy++;
dst->udata[dy] = NULL;
else {
dst->udata[dy] = xcalloc(
src->usize[sy], sizeof **dst->udata);
memcpy(dst->udata[dy], src->udata[sy],
src->usize[sy] * (sizeof **dst->udata));
}
sy++; dy++;
} }
} }

View File

@ -1,4 +1,4 @@
/* $Id: screen.c,v 1.95 2009-07-30 21:14:04 tcunha Exp $ */ /* $Id: screen.c,v 1.96 2009-08-09 17:28:23 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -193,10 +193,8 @@ screen_resize_y(struct screen *s, u_int sy)
} }
/* Resize line arrays. */ /* Resize line arrays. */
gd->size = xrealloc(gd->size, gd->hsize + sy, sizeof *gd->size); gd->linedata = xrealloc(
gd->data = xrealloc(gd->data, gd->hsize + sy, sizeof *gd->data); gd->linedata, gd->hsize + sy, sizeof *gd->linedata);
gd->usize = xrealloc(gd->usize, gd->hsize + sy, sizeof *gd->usize);
gd->udata = xrealloc(gd->udata, gd->hsize + sy, sizeof *gd->udata);
/* Size increasing. */ /* Size increasing. */
if (sy > oldy) { if (sy > oldy) {
@ -217,12 +215,8 @@ screen_resize_y(struct screen *s, u_int sy)
needed -= available; needed -= available;
/* Then fill the rest in with blanks. */ /* Then fill the rest in with blanks. */
for (i = gd->hsize + sy - needed; i < gd->hsize + sy; i++) { for (i = gd->hsize + sy - needed; i < gd->hsize + sy; i++)
gd->size[i] = 0; memset(&gd->linedata[i], 0, sizeof gd->linedata[i]);
gd->data[i] = NULL;
gd->usize[i] = 0;
gd->udata[i] = NULL;
}
} }
/* Set the new size, and reset the scroll region. */ /* Set the new size, and reset the scroll region. */

17
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.405 2009-08-09 17:19:18 tcunha Exp $ */ /* $Id: tmux.h,v 1.406 2009-08-09 17:28:23 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -499,6 +499,15 @@ struct grid_utf8 {
u_char data[UTF8_SIZE]; u_char data[UTF8_SIZE];
} __packed; } __packed;
/* Grid line. */
struct grid_line {
u_int cellsize;
struct grid_cell *celldata;
u_int utf8size;
struct grid_utf8 *utf8data;
} __packed;
/* Entire grid of cells. */ /* Entire grid of cells. */
struct grid { struct grid {
int flags; int flags;
@ -510,11 +519,7 @@ struct grid {
u_int hsize; u_int hsize;
u_int hlimit; u_int hlimit;
u_int *size; struct grid_line *linedata;
struct grid_cell **data;
u_int *usize;
struct grid_utf8 **udata;
}; };
/* Option data structures. */ /* Option data structures. */

6
tty.c
View File

@ -1,4 +1,4 @@
/* $Id: tty.c,v 1.121 2009-08-09 16:50:57 tcunha Exp $ */ /* $Id: tty.c,v 1.122 2009-08-09 17:28:24 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -496,8 +496,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
u_int i, sx; u_int i, sx;
sx = screen_size_x(s); sx = screen_size_x(s);
if (sx > s->grid->size[s->grid->hsize + py]) if (sx > s->grid->linedata[s->grid->hsize + py].cellsize)
sx = s->grid->size[s->grid->hsize + py]; sx = s->grid->linedata[s->grid->hsize + py].cellsize;
if (sx > tty->sx) if (sx > tty->sx)
sx = tty->sx; sx = tty->sx;

View File

@ -1,4 +1,4 @@
/* $Id: window-copy.c,v 1.73 2009-08-09 16:50:57 tcunha Exp $ */ /* $Id: window-copy.c,v 1.74 2009-08-09 17:28:24 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -537,7 +537,7 @@ window_copy_find_length(struct window_pane *wp, u_int py)
* width of the grid, and screen_write_copy treats them as spaces, so * width of the grid, and screen_write_copy treats them as spaces, so
* ignore them here too. * ignore them here too.
*/ */
px = wp->base.grid->size[py]; px = wp->base.grid->linedata[py].cellsize;
if (px > screen_size_x(&wp->base)) if (px > screen_size_x(&wp->base))
px = screen_size_x(&wp->base); px = screen_size_x(&wp->base);
while (px > 0) { while (px > 0) {