/* Compare two UTF-8 cells. */ int grid_utf8_compare(const struct grid_utf8 *gu1, const struct grid_utf8 *gu2) { size_t size; size = grid_utf8_size(gu1); if (size != grid_utf8_size(gu2)) return (0); if (memcmp(gu1->data, gu2->data, size) != 0) return (0); return (1); }
void window_copy_copy_line(struct window_pane *wp, char **buf, size_t *off, u_int sy, u_int sx, u_int ex) { struct window_copy_mode_data *data = wp->modedata; struct grid *gd = data->backing->grid; const struct grid_cell *gc; const struct grid_utf8 *gu; struct grid_line *gl; u_int i, xx, wrapped = 0; size_t size; if (sx > ex) return; /* * Work out if the line was wrapped at the screen edge and all of it is * on screen. */ gl = &gd->linedata[sy]; if (gl->flags & GRID_LINE_WRAPPED && gl->cellsize <= gd->sx) wrapped = 1; /* If the line was wrapped, don't strip spaces (use the full length). */ if (wrapped) xx = gl->cellsize; else xx = window_copy_find_length(wp, sy); if (ex > xx) ex = xx; if (sx > xx) sx = xx; if (sx < ex) { for (i = sx; i < ex; i++) { gc = grid_peek_cell(gd, i, sy); if (gc->flags & GRID_FLAG_PADDING) continue; if (!(gc->flags & GRID_FLAG_UTF8)) { *buf = xrealloc(*buf, 1, (*off) + 1); (*buf)[(*off)++] = gc->data; } else { gu = grid_peek_utf8(gd, i, sy); size = grid_utf8_size(gu); *buf = xrealloc(*buf, 1, (*off) + size); *off += grid_utf8_copy(gu, *buf + *off, size); } } } /* Only add a newline if the line wasn't wrapped. */ if (!wrapped || ex != xx) { *buf = xrealloc(*buf, 1, (*off) + 1); (*buf)[(*off)++] = '\n'; } }
/* Copy UTF-8 out into a buffer. */ size_t grid_utf8_copy(const struct grid_utf8 *gu, char *buf, size_t len) { size_t size; size = grid_utf8_size(gu); if (size > len) fatalx("UTF-8 copy overflow"); memcpy(buf, gu->data, size); return (size); }
void tty_pututf8(struct tty *tty, const struct grid_utf8 *gu) { size_t size; size = grid_utf8_size(gu); bufferevent_write(tty->event, gu->data, size); if (tty->log_fd != -1) write(tty->log_fd, gu->data, size); tty->cx += gu->width; }
/* Append UTF-8 character onto the cell data (for combined characters). */ int grid_utf8_append(struct grid_utf8 *gu, const struct utf8_data *utf8data) { size_t old_size; old_size = grid_utf8_size(gu); if (old_size + utf8data->size > sizeof gu->data) return (-1); memcpy(gu->data + old_size, utf8data->data, utf8data->size); if (old_size + utf8data->size != sizeof gu->data) gu->data[old_size + utf8data->size] = 0xff; return (0); }
/* Convert cells into a string. */ char * grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx) { const struct grid_cell *gc; const struct grid_utf8 *gu; char *buf; size_t len, off, size; u_int xx; GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx); len = 128; buf = xmalloc(len); off = 0; for (xx = px; xx < px + nx; xx++) { gc = grid_peek_cell(gd, xx, py); if (gc->flags & GRID_FLAG_PADDING) continue; if (gc->flags & GRID_FLAG_UTF8) { gu = grid_peek_utf8(gd, xx, py); size = grid_utf8_size(gu); while (len < off + size + 1) { buf = xrealloc(buf, 2, len); len *= 2; } off += grid_utf8_copy(gu, buf + off, len - off); } else { while (len < off + 2) { buf = xrealloc(buf, 2, len); len *= 2; } buf[off++] = gc->data; } } while (off > 0 && buf[off - 1] == ' ') off--; buf[off] = '\0'; return (buf); }