diff --git a/CHANGELOG.md b/CHANGELOG.md index a7f27bc1..c711b664 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -109,6 +109,8 @@ * A multi-column character that does not fit on the current line is now printed on the next line, instead of only printing half the character. +* Font size can no longer be reduced to negative values + (https://codeberg.org/dnkl/foot/issues/38). ### Security diff --git a/csi.c b/csi.c index fc6db974..fe102ada 100644 --- a/csi.c +++ b/csi.c @@ -338,8 +338,10 @@ csi_dispatch(struct terminal *term, uint8_t final) LOG_DBG("REP: '%C' %d times", term->vt.last_printed, count); const int width = wcwidth(term->vt.last_printed); - for (int i = 0; i < count; i++) - term_print(term, term->vt.last_printed, width); + if (width > 0) { + for (int i = 0; i < count; i++) + term_print(term, term->vt.last_printed, width); + } } break; diff --git a/sixel.c b/sixel.c index 7d4b3d38..7dab1fcc 100644 --- a/sixel.c +++ b/sixel.c @@ -113,13 +113,33 @@ verify_sixel_list_order(const struct terminal *term) { #if defined(_DEBUG) int prev_row = INT_MAX; + int prev_col = -1; + int prev_col_count = 0; tll_foreach(term->grid->sixel_images, it) { int row = rebase_row(term, it->item.pos.row + it->item.rows - 1); - assert(row < prev_row); - if (row >= prev_row) + int col = it->item.pos.col; + int col_count = it->item.cols; + + assert(row <= prev_row); + if (row > prev_row) return false; + + if (row == prev_row) { + /* Allowed to be on the same row only if their columns + * don't overlap */ + + assert(col + col_count <= prev_col || + prev_col + prev_col_count <= col); + + if (!(col + col_count <= prev_col || + prev_col + prev_col_count <= col)) + return false; + } + prev_row = row; + prev_col = col; + prev_col_count = col_count; } #endif return true; diff --git a/terminal.c b/terminal.c index c720aea4..86672f06 100644 --- a/terminal.c +++ b/terminal.c @@ -1432,7 +1432,7 @@ term_font_size_adjust(struct terminal *term, double amount) old_pt_size = term->font_sizes[i].px_size * 72. / dpi; } - term->font_sizes[i].pt_size = old_pt_size + amount; + term->font_sizes[i].pt_size = fmax(old_pt_size + amount, 0); term->font_sizes[i].px_size = -1; } @@ -2307,12 +2307,15 @@ print_linewrap(struct terminal *term) } term->grid->cursor.lcf = false; - if (term->grid->cursor.point.row == term->scroll_region.end - 1) + + const int row = term->grid->cursor.point.row; + + if (row == term->scroll_region.end - 1) term_scroll(term, 1); else { - assert(term->grid->cursor.point.row < term->scroll_region.end - 1); - term->grid->cursor.point.row++; - term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row); + const int new_row = min(row + 1, term->rows - 1); + term->grid->cursor.point.row = new_row; + term->grid->cur_row = grid_row(term->grid, new_row); } term->grid->cursor.point.col = 0; @@ -2353,8 +2356,7 @@ print_spacer(struct terminal *term, int col) void term_print(struct terminal *term, wchar_t wc, int width) { - if (unlikely(width <= 0)) - return; + assert(width > 0); print_linewrap(term); print_insert(term, width); diff --git a/vt.c b/vt.c index 618611c6..f25f26be 100644 --- a/vt.c +++ b/vt.c @@ -223,6 +223,8 @@ action_print(struct terminal *term, uint8_t c) L'│', L'≤', L'≥', L'π', L'≠', L'£', L'·', /* x - ~ */ }; + assert(wcwidth(c) == 1); + if (unlikely(term->charsets.set[term->charsets.selected] == CHARSET_GRAPHIC) && c >= 0x60 && c <= 0x7e) { @@ -540,15 +542,12 @@ action_utf8_print(struct terminal *term, wchar_t wc) if (!term->grid->cursor.lcf) base_col--; + while (row->cells[base_col].wc == CELL_MULT_COL_SPACER && base_col > 0) + base_col--; + assert(base_col >= 0 && base_col < term->cols); wchar_t base = row->cells[base_col].wc; - /* Handle double-column glyphs */ - if (base == 0 && base_col > 0) { - base_col--; - base = row->cells[base_col].wc; - } - const struct composed *composed = (base >= CELL_COMB_CHARS_LO && base < (CELL_COMB_CHARS_LO + term->composed_count)) @@ -664,7 +663,8 @@ action_utf8_print(struct terminal *term, wchar_t wc) } } - term_print(term, wc, width); + if (width > 0) + term_print(term, wc, width); } static void @@ -742,7 +742,8 @@ state_ground_switch(struct terminal *term, uint8_t data) case 0x19: case 0x1c ... 0x1f: action_execute(term, data); return STATE_GROUND; - case 0x20 ... 0x7f: action_print(term, data); return STATE_GROUND; + /* modified from 0x20..0x7f to 0x20..0x7e, since 0x7f is DEL, which is a zero-width character */ + case 0x20 ... 0x7e: action_print(term, data); return STATE_GROUND; case 0xc2 ... 0xdf: action_utf8_21(term, data); return STATE_UTF8_21; case 0xe0 ... 0xef: action_utf8_31(term, data); return STATE_UTF8_31;