vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

Commit: be185571eec96d2c13d18e4fe9c92bf6b74b87b1
Parent: c51eafbc9d8d8e3269704ae15d163d96f63d2055
Author: Randy Palamar
Date:   Thu, 21 Nov 2024 06:19:47 -0700

only support wide cells of width 2

Terminals don't have the concept of wide chars wider than 2 cells.

Diffstat:
Mfont.c | 13++++++-------
Mterminal.c | 29+++++++++++++----------------
Mvtgl.c | 20++++++++++----------
3 files changed, 29 insertions(+), 33 deletions(-)

diff --git a/font.c b/font.c @@ -240,6 +240,7 @@ render_glyph(Arena *a, FontAtlas *fa, u32 cp, u32 font_id, enum face_style style cg->tile_count = ((x1 - 1) / (i32)fa->info.w) + 1; if (x0 < 0 && x1 + x0 <= fa->info.w) cg->tile_count = 1; + CLAMP(cg->tile_count, 1, 2); i32 height = y1 - y0; i32 width = x1 - x0; @@ -258,14 +259,13 @@ render_glyph(Arena *a, FontAtlas *fa, u32 cp, u32 font_id, enum face_style style stbtt_MakeGlyphBitmapSubpixel(*a, &f->font_info, render_buf, width, height, width, scale, scale, 0, 0, glyph_idx); - ASSERT(cg->tile_count >= 1 && cg->tile_count < gc->tiles_in_x); uv2 tile_coord = unpack_gpu_tile_coord(cg->gpu_tile_index); u32 tile_index = tile_coord.y * gc->tiles_in_x + tile_coord.x; if (tile_index != 0 && (tile_coord.x + cg->tile_count < gc->tiles_in_x)) { /* NOTE: try to use the old tile directly */ - for (u32 i = 1; i < cg->tile_count; i++) - if (gc->occupied_tiles[tile_index + i]) - tile_index = 0; + if (gc->occupied_tiles[tile_index] || + (cg->tile_count == 2 && gc->occupied_tiles[tile_index + 1])) + tile_index = 0; } if (!tile_index) { @@ -277,9 +277,8 @@ render_glyph(Arena *a, FontAtlas *fa, u32 cp, u32 font_id, enum face_style style for (x = 0; !tile_index && x < gc->tiles_in_x; x++) { if (!occupied[0]) { tile_index = y * gc->tiles_in_x + x; - for (u32 i = 1; i < cg->tile_count && i < gc->tiles_in_x - x; i++) - if (occupied[i]) - tile_index = 0; + if ((cg->tile_count == 2) && occupied[1]) + tile_index = 0; } occupied++; } diff --git a/terminal.c b/terminal.c @@ -61,14 +61,13 @@ get_char_around_cell(Term *t, iv2 cell) * WIDE cell. then set the range end to the last WDUMMY cell */ Cell *row = t->views[t->view_idx].fb.rows[cell.y]; if (row[cell.x].bg & ATTR_WDUMMY) { - while (!(row[cell.x].bg & ATTR_WIDE) && cell.x > 0) - cell.x--; + ASSERT(cell.x - 1 >= 0); + cell.x--; ASSERT(row[cell.x].bg & ATTR_WIDE); result.start = cell; - } - if (row[cell.x].bg & ATTR_WIDE) { - while ((row[cell.x + 1].bg & ATTR_WDUMMY) && cell.x + 1 < t->size.w) - cell.x++; + } else if (row[cell.x].bg & ATTR_WIDE) { + ASSERT(cell.x + 1 < t->size.w); + cell.x++; ASSERT(row[cell.x].bg & ATTR_WDUMMY); result.end = cell; } @@ -1209,6 +1208,10 @@ push_normal_cp(Term *t, TermView *tv, u32 cp) if (t->mode.term & TM_AUTO_WRAP && t->cursor.state & CURSOR_WRAP_NEXT) push_newline(t, 1); + if (t->cursor.charsets[t->cursor.charset_index] == CS_GRAPHIC0 && + BETWEEN(cp, 0x41, 0x7e) && graphic_0[cp - 0x41]) + cp = graphic_0[cp - 0x41]; + u32 width = 1; if (cp > 0x7F) { /* TODO: this is obviously complete crap but wcwidth from libc doesn't @@ -1218,10 +1221,6 @@ push_normal_cp(Term *t, TermView *tv, u32 cp) width = cg->tile_count; } - if (t->cursor.charsets[t->cursor.charset_index] == CS_GRAPHIC0 && - BETWEEN(cp, 0x41, 0x7e) && graphic_0[cp - 0x41]) - cp = graphic_0[cp - 0x41]; - /* NOTE: make this '>=' for fun in vis */ if (t->cursor.pos.x + width > t->size.w) { /* NOTE: make space for character if mode enabled else @@ -1238,12 +1237,10 @@ push_normal_cp(Term *t, TermView *tv, u32 cp) c->fg = SHADER_PACK_FG(t->cursor.style.fg.rgba, t->cursor.style.attr); c->bg = SHADER_PACK_BG(t->cursor.style.bg.rgba, t->cursor.style.attr); - for (u32 w = width - 1; w; w--) { - c->bg |= ATTR_WIDE; - if (t->cursor.pos.x + w < t->size.w) { - Cell *nc = c + w; - nc->bg |= ATTR_WDUMMY; - } + if (width > 1) { + ASSERT(t->cursor.pos.x + (width - 1) < t->size.w); + c[0].bg |= ATTR_WIDE; + c[1].bg |= ATTR_WDUMMY; } if (t->cursor.pos.x + width < t->size.w) diff --git a/vtgl.c b/vtgl.c @@ -546,18 +546,18 @@ render_framebuffer(Term *t, RenderCell *render_buf) iv2 curs = t->cursor.pos; Cell *c = &tv->fb.rows[curs.y][curs.x]; RenderCell *rc = render_buf + curs.y * t->size.w + curs.x; - ASSERT(!(c->bg & ATTR_WDUMMY)); - - rc->fg ^= SHADER_PACK_ATTR(ATTR_INVERSE); + rc[0].fg ^= SHADER_PACK_ATTR(ATTR_INVERSE); if ((t->mode.term & TM_ALTSCREEN) == 0) - rc->fg |= SHADER_PACK_ATTR(ATTR_BLINK); + rc[0].fg |= SHADER_PACK_ATTR(ATTR_BLINK); if (c->bg & ATTR_WIDE) { - for (u32 j = 1; c[j].bg & ATTR_WDUMMY; j++) { - rc[j].fg ^= SHADER_PACK_ATTR(ATTR_INVERSE); - if ((t->mode.term & TM_ALTSCREEN) == 0) - rc[j].fg |= SHADER_PACK_ATTR(ATTR_BLINK); - } + rc[1].fg ^= SHADER_PACK_ATTR(ATTR_INVERSE); + if ((t->mode.term & TM_ALTSCREEN) == 0) + rc[1].fg |= SHADER_PACK_ATTR(ATTR_BLINK); + } else if (c->bg & ATTR_WDUMMY) { + rc[-1].fg ^= SHADER_PACK_ATTR(ATTR_INVERSE); + if ((t->mode.term & TM_ALTSCREEN) == 0) + rc[-1].fg |= SHADER_PACK_ATTR(ATTR_BLINK); } } @@ -638,7 +638,7 @@ update_selection(Term *t, TerminalInput *input) switch (sel->state) { case SS_WORDS: new = get_word_around_cell(t, new_p); break; case SS_CHAR: new = get_char_around_cell(t, new_p); break; - case SS_NONE: INVALID_CODE_PATH; break; + case SS_NONE: /*TODO: INVALID_CODE_PATH;*/ return; break; } if (sel->anchor.start.y < new.start.y) {