/* Move a group of cells. */ void 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; GRID_DEBUG(gd, "dx=%u, px=%u, py=%u, nx=%u", dx, px, py, nx); if (nx == 0 || px == dx) return; if (grid_check_y(gd, py) != 0) return; gl = &gd->linedata[py]; grid_expand_line(gd, py, px + nx); grid_expand_line(gd, py, dx + nx); memmove( &gl->celldata[dx], &gl->celldata[px], nx * sizeof *gl->celldata); if (gl->utf8data != NULL) { grid_expand_line_utf8(gd, py, px + nx); grid_expand_line_utf8(gd, py, dx + nx); memmove(&gl->utf8data[dx], &gl->utf8data[px], nx * sizeof *gl->utf8data); } /* Wipe any cells that have been moved. */ for (xx = px; xx < px + nx; xx++) { if (xx >= dx && xx < dx + nx) continue; grid_put_cell(gd, xx, py, &grid_default_cell); } }
/* Move a group of cells. */ void 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; if (nx == 0 || px == dx) return; if (grid_check_y(gd, py) != 0) return; gl = &gd->linedata[py]; grid_expand_line(gd, py, px + nx); grid_expand_line(gd, py, dx + nx); memmove(&gl->celldata[dx], &gl->celldata[px], nx * sizeof *gl->celldata); /* Wipe any cells that have been moved. */ for (xx = px; xx < px + nx; xx++) { if (xx >= dx && xx < dx + nx) continue; grid_clear_cell(gd, xx, py); } }
/* Set cells at relative position. */ void grid_set_cells(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc, const char *s, size_t slen) { struct grid_line *gl; struct grid_cell_entry *gce; struct grid_cell *gcp; u_int i; if (grid_check_y(gd, __func__, py) != 0) return; grid_expand_line(gd, py, px + slen, 8); gl = &gd->linedata[py]; if (px + slen > gl->cellused) gl->cellused = px + slen; 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]); } else grid_store_cell(gce, gc, s[i]); } }
/* Clear area. */ void grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny, u_int bg) { struct grid_line *gl; u_int xx, yy; if (nx == 0 || ny == 0) return; if (px == 0 && nx == gd->sx) { grid_clear_lines(gd, py, ny, bg); return; } if (grid_check_y(gd, __func__, py) != 0) return; if (grid_check_y(gd, __func__, py + ny - 1) != 0) return; for (yy = py; yy < py + ny; yy++) { gl = &gd->linedata[yy]; if (px + nx >= gd->sx && px < gl->cellused) gl->cellused = px; if (px > gl->cellsize && COLOUR_DEFAULT(bg)) continue; if (px + nx >= gl->cellsize && COLOUR_DEFAULT(bg)) { gl->cellsize = px; continue; } grid_expand_line(gd, yy, px + nx, 8); /* default bg first */ for (xx = px; xx < px + nx; xx++) grid_clear_cell(gd, xx, yy, bg); } }
/* Empty a line and set background colour if needed. */ static void grid_empty_line(struct grid *gd, u_int py, u_int bg) { memset(&gd->linedata[py], 0, sizeof gd->linedata[py]); if (!COLOUR_DEFAULT(bg)) grid_expand_line(gd, py, gd->sx, bg); }
/* Clear area. */ void grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny, u_int bg) { u_int xx, yy; if (nx == 0 || ny == 0) return; if (px == 0 && nx == gd->sx) { grid_clear_lines(gd, py, ny, bg); return; } if (grid_check_y(gd, py) != 0) return; if (grid_check_y(gd, py + ny - 1) != 0) return; for (yy = py; yy < py + ny; yy++) { if (px + nx >= gd->sx && px < gd->linedata[yy].cellused) gd->linedata[yy].cellused = px; if (px > gd->linedata[yy].cellsize && bg == 8) continue; if (px + nx >= gd->linedata[yy].cellsize && bg == 8) { gd->linedata[yy].cellsize = px; continue; } grid_expand_line(gd, yy, px + nx, bg); for (xx = px; xx < px + nx; xx++) grid_clear_cell(gd, xx, yy, bg); } }
/* Get cell at relative position (for writing). */ struct grid_cell * grid_get_cell(struct grid *gd, u_int px, u_int py) { if (grid_check_y(gd, py) != 0) return (NULL); grid_expand_line(gd, py, px + 1); return (&gd->linedata[py].celldata[px]); }
/* Set cell at relative position. */ void grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc) { if (grid_check_y(gd, py) != 0) return; grid_expand_line(gd, py, px + 1); grid_put_cell(gd, px, py, gc); }
/* Set cell at relative position. */ void grid_set_cell(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; int extended; if (grid_check_y(gd, py) != 0) return; grid_expand_line(gd, py, px + 1, 8); gl = &gd->linedata[py]; gce = &gl->celldata[px]; if (px + 1 > gl->cellused) gl->cellused = px + 1; extended = (gce->flags & GRID_FLAG_EXTENDED); if (!extended && (gc->data.size != 1 || gc->data.width != 1)) extended = 1; if (!extended && ((gc->fg & COLOUR_FLAG_RGB) || (gc->bg & COLOUR_FLAG_RGB))) extended = 1; if (extended) { gl->flags |= GRID_LINE_EXTENDED; if (~gce->flags & GRID_FLAG_EXTENDED) { gl->extddata = xreallocarray(gl->extddata, gl->extdsize + 1, sizeof *gl->extddata); gce->offset = gl->extdsize++; gce->flags = gc->flags | GRID_FLAG_EXTENDED; } if (gce->offset >= gl->extdsize) fatalx("offset too big"); gcp = &gl->extddata[gce->offset]; memcpy(gcp, gc, sizeof *gcp); return; } gce->flags = gc->flags; gce->data.attr = gc->attr; gce->data.fg = gc->fg & 0xff; if (gc->fg & COLOUR_FLAG_256) gce->flags |= GRID_FLAG_FG256; gce->data.bg = gc->bg & 0xff; if (gc->bg & COLOUR_FLAG_256) gce->flags |= GRID_FLAG_BG256; gce->data.data = gc->data.data[0]; }
/* Set cell at relative position. */ void grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc) { struct grid_line *gl; struct grid_cell_entry *gce; if (grid_check_y(gd, __func__, py) != 0) return; grid_expand_line(gd, py, px + 1, 8); gl = &gd->linedata[py]; if (px + 1 > gl->cellused) gl->cellused = px + 1; gce = &gl->celldata[px]; if (grid_need_extended_cell(gce, gc)) grid_extended_cell(gl, gce, gc); else grid_store_cell(gce, gc, gc->data.data[0]); }