version 1.59, 2013/01/15 23:18:55 |
version 1.60, 2013/01/18 02:16:21 |
|
|
|
|
/* Write character. */ |
/* Write character. */ |
void |
void |
screen_write_putc( |
screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch) |
struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch) |
|
{ |
{ |
gc->data = ch; |
grid_cell_one(gc, ch); |
screen_write_cell(ctx, gc, NULL); |
screen_write_cell(ctx, gc); |
} |
} |
|
|
/* Calculate string length, with embedded formatting. */ |
/* Calculate string length, with embedded formatting. */ |
|
|
} |
} |
size += utf8data.width; |
size += utf8data.width; |
|
|
gc->flags |= GRID_FLAG_UTF8; |
grid_cell_set(gc, &utf8data); |
screen_write_cell(ctx, gc, &utf8data); |
screen_write_cell(ctx, gc); |
gc->flags &= ~GRID_FLAG_UTF8; |
|
} else { |
} else { |
if (maxlen > 0 && size + 1 > (size_t) maxlen) |
if (maxlen > 0 && size + 1 > (size_t) maxlen) |
break; |
break; |
|
|
} |
} |
size += utf8data.width; |
size += utf8data.width; |
|
|
lgc.flags |= GRID_FLAG_UTF8; |
grid_cell_set(&lgc, &utf8data); |
screen_write_cell(ctx, &lgc, &utf8data); |
screen_write_cell(ctx, &lgc); |
lgc.flags &= ~GRID_FLAG_UTF8; |
|
} else { |
} else { |
if (maxlen > 0 && size + 1 > (size_t) maxlen) |
if (maxlen > 0 && size + 1 > (size_t) maxlen) |
break; |
break; |
|
|
struct grid *gd = src->grid; |
struct grid *gd = src->grid; |
struct grid_line *gl; |
struct grid_line *gl; |
const struct grid_cell *gc; |
const struct grid_cell *gc; |
const struct grid_utf8 *gu; |
struct utf8_data ud; |
struct utf8_data utf8data; |
|
u_int xx, yy, cx, cy, ax, bx; |
u_int xx, yy, cx, cy, ax, bx; |
|
|
cx = s->cx; |
cx = s->cx; |
|
|
gc = &grid_default_cell; |
gc = &grid_default_cell; |
else |
else |
gc = &gl->celldata[xx]; |
gc = &gl->celldata[xx]; |
if (!(gc->flags & GRID_FLAG_UTF8)) { |
grid_cell_get(gc, &ud); |
screen_write_cell(ctx, gc, NULL); |
screen_write_cell(ctx, gc); |
continue; |
|
} |
|
/* Reinject the UTF-8 sequence. */ |
|
gu = &gl->utf8data[xx]; |
|
utf8data.size = grid_utf8_copy( |
|
gu, utf8data.data, sizeof utf8data.data); |
|
utf8data.width = gu->width; |
|
screen_write_cell(ctx, gc, &utf8data); |
|
} |
} |
if (px + nx == gd->sx && px + nx > gl->cellsize) |
if (px + nx == gd->sx && px + nx > gl->cellsize) |
screen_write_clearendofline(ctx); |
screen_write_clearendofline(ctx); |
|
|
struct screen *s = ctx->s; |
struct screen *s = ctx->s; |
struct grid *gd = s->grid; |
struct grid *gd = s->grid; |
const struct grid_cell *gc; |
const struct grid_cell *gc; |
const struct grid_utf8 *gu; |
|
u_int xx; |
u_int xx; |
|
|
ttyctx->wp = ctx->wp; |
ttyctx->wp = ctx->wp; |
|
|
} |
} |
ttyctx->last_width = xx; |
ttyctx->last_width = xx; |
memcpy(&ttyctx->last_cell, gc, sizeof ttyctx->last_cell); |
memcpy(&ttyctx->last_cell, gc, sizeof ttyctx->last_cell); |
if (gc->flags & GRID_FLAG_UTF8) { |
|
gu = grid_view_peek_utf8(gd, screen_size_x(s) - xx, s->cy); |
|
memcpy(&ttyctx->last_utf8, gu, sizeof ttyctx->last_utf8); |
|
} |
|
} |
} |
|
|
/* Cursor up by ny. */ |
/* Cursor up by ny. */ |
|
|
screen_write_initctx(ctx, &ttyctx, 0); |
screen_write_initctx(ctx, &ttyctx, 0); |
|
|
memcpy(&gc, &grid_default_cell, sizeof gc); |
memcpy(&gc, &grid_default_cell, sizeof gc); |
gc.data = 'E'; |
grid_cell_one(&gc, 'E'); |
|
|
for (yy = 0; yy < screen_size_y(s); yy++) { |
for (yy = 0; yy < screen_size_y(s); yy++) { |
for (xx = 0; xx < screen_size_x(s); xx++) |
for (xx = 0; xx < screen_size_x(s); xx++) |
|
|
|
|
/* Write cell data. */ |
/* Write cell data. */ |
void |
void |
screen_write_cell(struct screen_write_ctx *ctx, |
screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) |
const struct grid_cell *gc, const struct utf8_data *utf8data) |
|
{ |
{ |
struct screen *s = ctx->s; |
struct screen *s = ctx->s; |
struct grid *gd = s->grid; |
struct grid *gd = s->grid; |
struct tty_ctx ttyctx; |
struct tty_ctx ttyctx; |
struct grid_utf8 gu; |
|
u_int width, xx; |
u_int width, xx; |
struct grid_cell tmp_gc, *tmp_gcp; |
struct grid_cell tmp_gc, *tmp_gcp; |
|
struct utf8_data ud; |
int insert = 0; |
int insert = 0; |
|
|
/* Ignore padding. */ |
/* Ignore padding. */ |
if (gc->flags & GRID_FLAG_PADDING) |
if (gc->flags & GRID_FLAG_PADDING) |
return; |
return; |
|
width = grid_cell_width(gc); |
|
|
/* Find character width. */ |
|
if (gc->flags & GRID_FLAG_UTF8) |
|
width = utf8data->width; |
|
else |
|
width = 1; |
|
|
|
/* |
/* |
* If this is a wide character and there is no room on the screen, for |
* If this is a wide character and there is no room on the screen, for |
* the entire character, don't print it. |
* the entire character, don't print it. |
|
|
* there is space. |
* there is space. |
*/ |
*/ |
if (width == 0) { |
if (width == 0) { |
if (screen_write_combine(ctx, utf8data) == 0) { |
grid_cell_get(gc, &ud); |
|
if (screen_write_combine(ctx, &ud) == 0) { |
screen_write_initctx(ctx, &ttyctx, 0); |
screen_write_initctx(ctx, &ttyctx, 0); |
tty_write(tty_cmd_utf8character, &ttyctx); |
tty_write(tty_cmd_utf8character, &ttyctx); |
} |
} |
|
|
|
|
/* Set the cell. */ |
/* Set the cell. */ |
grid_view_set_cell(gd, s->cx, s->cy, gc); |
grid_view_set_cell(gd, s->cx, s->cy, gc); |
if (gc->flags & GRID_FLAG_UTF8) { |
|
/* Construct UTF-8 and write it. */ |
|
grid_utf8_set(&gu, utf8data); |
|
grid_view_set_utf8(gd, s->cx, s->cy, &gu); |
|
} |
|
|
|
/* Move the cursor. */ |
/* Move the cursor. */ |
s->cx += width; |
s->cx += width; |
|
|
ttyctx.num = width; |
ttyctx.num = width; |
tty_write(tty_cmd_insertcharacter, &ttyctx); |
tty_write(tty_cmd_insertcharacter, &ttyctx); |
} |
} |
ttyctx.utf8 = &gu; |
|
if (screen_check_selection(s, s->cx - width, s->cy)) { |
if (screen_check_selection(s, s->cx - width, s->cy)) { |
memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc); |
memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc); |
tmp_gc.data = gc->data; |
grid_cell_get(gc, &ud); |
tmp_gc.flags = gc->flags & |
grid_cell_set(&tmp_gc, &ud); |
~(GRID_FLAG_FG256|GRID_FLAG_BG256); |
tmp_gc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); |
tmp_gc.flags |= s->sel.cell.flags & |
tmp_gc.flags |= s->sel.cell.flags & |
(GRID_FLAG_FG256|GRID_FLAG_BG256); |
(GRID_FLAG_FG256|GRID_FLAG_BG256); |
ttyctx.cell = &tmp_gc; |
ttyctx.cell = &tmp_gc; |
|
|
|
|
/* Combine a UTF-8 zero-width character onto the previous. */ |
/* Combine a UTF-8 zero-width character onto the previous. */ |
int |
int |
screen_write_combine( |
screen_write_combine(struct screen_write_ctx *ctx, const struct utf8_data *ud) |
struct screen_write_ctx *ctx, const struct utf8_data *utf8data) |
|
{ |
{ |
struct screen *s = ctx->s; |
struct screen *s = ctx->s; |
struct grid *gd = s->grid; |
struct grid *gd = s->grid; |
struct grid_cell *gc; |
struct grid_cell *gc; |
struct grid_utf8 *gu, tmp_gu; |
struct utf8_data ud1; |
u_int i; |
|
|
|
/* Can't combine if at 0. */ |
/* Can't combine if at 0. */ |
if (s->cx == 0) |
if (s->cx == 0) |
return (-1); |
return (-1); |
|
|
/* Empty utf8data is out. */ |
/* Empty data is out. */ |
if (utf8data->size == 0) |
if (ud->size == 0) |
fatalx("UTF-8 data empty"); |
fatalx("UTF-8 data empty"); |
|
|
/* Retrieve the previous cell and convert to UTF-8 if not already. */ |
/* Retrieve the previous cell. */ |
gc = grid_view_get_cell(gd, s->cx - 1, s->cy); |
gc = grid_view_get_cell(gd, s->cx - 1, s->cy); |
if (!(gc->flags & GRID_FLAG_UTF8)) { |
grid_cell_get(gc, &ud1); |
tmp_gu.data[0] = gc->data; |
|
tmp_gu.data[1] = 0xff; |
|
tmp_gu.width = 1; |
|
|
|
grid_view_set_utf8(gd, s->cx - 1, s->cy, &tmp_gu); |
/* Check there is enough space. */ |
gc->flags |= GRID_FLAG_UTF8; |
if (ud1.size + ud->size > sizeof ud1.data) |
} |
return (-1); |
|
|
/* Append the current cell. */ |
/* Append the data and set the cell. */ |
gu = grid_view_get_utf8(gd, s->cx - 1, s->cy); |
memcpy(ud1.data + ud1.size, ud->data, ud->size); |
if (grid_utf8_append(gu, utf8data) != 0) { |
ud1.size += ud->size; |
/* Failed: scrap this character and replace with underscores. */ |
grid_cell_set(gc, &ud1); |
if (gu->width == 1) { |
|
gc->data = '_'; |
|
gc->flags &= ~GRID_FLAG_UTF8; |
|
} else { |
|
for (i = 0; i < gu->width && i != sizeof gu->data; i++) |
|
gu->data[i] = '_'; |
|
if (i != sizeof gu->data) |
|
gu->data[i] = 0xff; |
|
gu->width = i; |
|
} |
|
} |
|
|
|
return (0); |
return (0); |
} |
} |