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:
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) {