version 1.9, 2009/07/21 18:40:30 |
version 1.10, 2009/08/08 13:29:27 |
|
|
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); |
|
|
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); |
} |
} |
|
|
|
|
void |
void |
grid_destroy(struct grid *gd) |
grid_destroy(struct grid *gd) |
{ |
{ |
u_int yy; |
struct grid_line *gl; |
|
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); |
} |
} |
|
|
|
|
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; |
|
|
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); |
} |
} |
|
|
|
|
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++; |
} |
} |
|
|
|
|
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) |
{ |
{ |
u_int xx; |
struct grid_line *gl; |
|
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. */ |
|
|
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). */ |
|
|
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. */ |
|
|
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). */ |
|
|
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. */ |
|
|
|
|
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); |
} |
} |
|
|
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) |
{ |
{ |
u_int yy; |
struct grid_line *gl; |
|
u_int yy; |
|
|
GRID_DEBUG(gd, "py=%u, ny=%u", py, ny); |
GRID_DEBUG(gd, "py=%u, ny=%u", py, 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; |
|
} |
|
} |
} |
} |
} |
|
|
|
|
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; |
|
} |
} |
} |
} |
|
|
|
|
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) |
{ |
{ |
u_int xx; |
struct grid_line *gl; |
|
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); |
|
|
|
|
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. */ |
|
|
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) |
{ |
{ |
u_int yy; |
struct grid_line *dstl, *srcl; |
|
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); |
|
|
|
|
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 { |
|
dst->data[dy] = xcalloc( |
|
src->size[sy], sizeof **dst->data); |
|
memcpy(dst->data[dy], src->data[sy], |
|
src->size[sy] * (sizeof **dst->data)); |
|
} |
|
|
|
dst->usize[dy] = src->usize[sy]; |
memcpy(dstl, srcl, sizeof *dstl); |
if (src->usize[sy] == 0) |
if (srcl->cellsize != 0) { |
dst->udata[dy] = NULL; |
dstl->celldata = xcalloc( |
else { |
srcl->cellsize, sizeof *dstl->celldata); |
dst->udata[dy] = xcalloc( |
memcpy(dstl->celldata, srcl->celldata, |
src->usize[sy], sizeof **dst->udata); |
srcl->cellsize * sizeof *dstl->celldata); |
memcpy(dst->udata[dy], src->udata[sy], |
|
src->usize[sy] * (sizeof **dst->udata)); |
|
} |
} |
|
if (srcl->utf8size != 0) { |
|
dstl->utf8data = xcalloc( |
|
srcl->utf8size, sizeof *dstl->utf8data); |
|
memcpy(dstl->utf8data, srcl->utf8data, |
|
srcl->utf8size * sizeof *dstl->utf8data); |
|
} |
|
|
sy++; dy++; |
sy++; |
|
dy++; |
} |
} |
} |
} |