From b090cba28981d7a0e40f87211e9b8b065bfdf3e3 Mon Sep 17 00:00:00 2001 From: Akib Azmain Turja Date: Tue, 4 Oct 2022 18:54:58 +0600 Subject: [PATCH 2/2] Merge tty_write_glyphs and tty_write_glyphs_with_face * src/term.c (tty_write_glyphs_1, tty_write_glyphs) (tty_write_glyphs_with_face): Merge tty_write_glyphs and tty_write_glyphs_with_face into tty_write_glyphs_1. Define tty_write_glyphs as a wrapper of tty_write_glyphs_1. --- src/term.c | 243 +++++++++++++++++------------------------------------ 1 file changed, 79 insertions(+), 164 deletions(-) diff --git a/src/term.c b/src/term.c index 283a65c4..db1dd2a4 100644 --- a/src/term.c +++ b/src/term.c @@ -723,7 +723,8 @@ encode_terminal_code (struct glyph *src, int src_len, /* An implementation of write_glyphs for termcap frames. */ static void -tty_write_glyphs (struct frame *f, struct glyph *string, int len) +tty_write_glyphs_1 (struct frame *f, struct glyph *string, int len, + int face_id) { unsigned char *conversion_buffer; struct coding_system *coding; @@ -761,6 +762,13 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) the tail. */ coding->mode &= ~CODING_MODE_LAST_BLOCK; + if (face_id >= 0) + { + /* Turn appearance modes of the face. */ + tty_highlight_if_desired (tty); + turn_on_face (f, face_id); + } + if (len > 0) { cmplus (tty, len); @@ -770,16 +778,27 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) for (stringlen = len; stringlen != 0; stringlen -= n) { - /* Identify a run of glyphs with the same face. */ - int face_id = string->face_id; + int local_face_id; - for (n = 1; n < stringlen; ++n) - if (string[n].face_id != face_id) - break; + if (face_id >= 0) + { + /* This will be a problem when we run the loop another + time, but this is the only iteration. */ + n = stringlen; + } + else + { + /* Identify a run of glyphs with the same face. */ + local_face_id = string->face_id; - /* Turn appearance modes of the face of the run on. */ - tty_highlight_if_desired (tty); - turn_on_face (f, face_id); + for (n = 1; n < stringlen; ++n) + if (string[n].face_id != local_face_id) + break; + + /* Turn appearance modes of the face of the run on. */ + tty_highlight_if_desired (tty); + turn_on_face (f, local_face_id); + } if (n == stringlen && !write_on_last_cell) /* This is the last run. */ @@ -799,24 +818,41 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) } string += n; - /* Turn appearance modes off. */ - turn_off_face (f, face_id); - tty_turn_off_highlight (tty); + if (face_id < 0) + { + /* Turn appearance modes off. */ + turn_off_face (f, local_face_id); + tty_turn_off_highlight (tty); + } } } /* Write on the bottom-right corner. */ if (write_on_last_cell) { - /* Go to the previous position. */ + /* The algorithm here is: we write the whole string except the + last glyph, then move back to the beginning of previous + glyph, write the last glyph, move back again, and insert the + glyph before the last glyph in such a way that last glyph at + cursor' position gets pushed to the corner. */ + + /* Go to the beginning of previous glyph. */ + /* BUG: This assume the previous glyph is a single column width + glyph, so this won't work for multi column width, and the + result is terminal-dependent. */ cmgoto (tty, curY (tty), curX (tty) - 1); cmplus (tty, 1); - int face_id = string->face_id; + int local_face_id; - /* Turn appearance modes of the face. */ - tty_highlight_if_desired (tty); - turn_on_face (f, face_id); + if (face_id < 0) + { + local_face_id = string->face_id; + + /* Turn appearance modes of the face. */ + tty_highlight_if_desired (tty); + turn_on_face (f, local_face_id); + } conversion_buffer = encode_terminal_code (string, 1, coding); if (coding->produced > 0) @@ -831,12 +867,15 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) unblock_input (); } - /* Go to the previous position. */ + /* Go to the beginning of previous glyph. */ + /* BUG: This assume the previous glyph is a single column width + glyph, so this won't work for multi column width, and the + result is terminal-dependent. */ cmgoto (tty, curY (tty), curX (tty) - 1); cmplus (tty, 1); /* Arrange that after writing the next glyph, the glyph on the - current character cell is somehow pushed to the bottom-right + current character cell gets pushed to the bottom-right corner. */ if (tty->TS_ins_char) { @@ -854,17 +893,18 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) tty_turn_on_insert (tty); } - if (face_id != glyph_on_char_cell_before_last.face_id) + if (face_id < 0 + && local_face_id != glyph_on_char_cell_before_last.face_id) { /* Turn appearance modes of the face. */ - turn_off_face (f, face_id); + turn_off_face (f, local_face_id); tty_turn_off_highlight (tty); - face_id = glyph_on_char_cell_before_last.face_id; + local_face_id = glyph_on_char_cell_before_last.face_id; tty_highlight_if_desired (tty); - turn_on_face (f, face_id); + turn_on_face (f, local_face_id); } /* This is the last run. */ @@ -884,157 +924,32 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) unblock_input (); } + if (face_id < 0) + { + /* Turn appearance modes off. */ + turn_off_face (f, local_face_id); + tty_turn_off_highlight (tty); + } + + tty_turn_off_insert (tty); + } + + if (face_id >= 0) + { /* Turn appearance modes off. */ turn_off_face (f, face_id); tty_turn_off_highlight (tty); - - tty_turn_off_insert (tty); } cmcheckmagic (tty); } -#ifndef DOS_NT - static void -tty_write_glyphs_with_face (register struct frame *f, register struct glyph *string, - register int len, register int face_id) +tty_write_glyphs (struct frame *f, struct glyph *string, int len) { - unsigned char *conversion_buffer; - struct coding_system *coding; - int write_on_last_cell; - - struct tty_display_info *tty = FRAME_TTY (f); - - tty_turn_off_insert (tty); - tty_hide_cursor (tty); - - /* Don't dare write in last column of bottom line, if Auto-Wrap, - since that would scroll the whole frame on some terminals. */ - - write_on_last_cell = (AutoWrap (tty) - && curY (tty) + 1 == FRAME_TOTAL_LINES (f) - && (curX (tty) + len) == FRAME_COLS (f)); - if (write_on_last_cell) - len --; - - if (FRAME_COLS (f) == 1 - || !(tty->TS_ins_char || tty->TS_ins_multi_chars - || (tty->TS_insert_mode && tty->TS_end_insert_mode))) - write_on_last_cell = false; - - if (len <= 0 && !write_on_last_cell) - return; - - /* If terminal_coding does any conversion, use it, otherwise use - safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here - because it always return 1 if the member src_multibyte is 1. */ - coding = ((FRAME_TERMINAL_CODING (f)->common_flags - & CODING_REQUIRE_ENCODING_MASK) - ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding); - - /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only - at the tail. */ - coding->mode &= ~CODING_MODE_LAST_BLOCK; - - /* Turn appearance modes of the face. */ - tty_highlight_if_desired (tty); - turn_on_face (f, face_id); - - if (len > 0) - { - cmplus (tty, len); - if (write_on_last_cell) - glyph_on_char_cell_before_last = string[len - 1]; - else - coding->mode |= CODING_MODE_LAST_BLOCK; - - conversion_buffer = encode_terminal_code (string, len, coding); - if (coding->produced > 0) - { - block_input (); - fwrite (conversion_buffer, 1, coding->produced, - tty->output); - clearerr (tty->output); - if (tty->termscript) - fwrite (conversion_buffer, 1, coding->produced, - tty->termscript); - unblock_input (); - } - } - - /* Write on the bottom-right corner. */ - if (write_on_last_cell) - { - /* Go to the previous position. */ - cmgoto (tty, curY (tty), curX (tty) - 1); - cmplus (tty, 1); - - conversion_buffer = encode_terminal_code (string, 1, coding); - if (coding->produced > 0) - { - block_input (); - fwrite (conversion_buffer, 1, coding->produced, - tty->output); - clearerr (tty->output); - if (tty->termscript) - fwrite (conversion_buffer, 1, coding->produced, - tty->termscript); - unblock_input (); - } - - /* Go to the previous position. */ - cmgoto (tty, curY (tty), curX (tty) - 1); - cmplus (tty, 1); - - /* Arrange that after writing the next glyph, the glyph on the - current character cell is somehow pushed to the bottom-right - corner. */ - if (tty->TS_ins_char) - { - OUTPUT1 (tty, tty->TS_ins_char); - } - else if (tty->TS_ins_multi_chars) - { - char *buf = tparam (tty->TS_ins_multi_chars, 0, 0, 1, - 0, 0, 0); - OUTPUT1 (tty, buf); - xfree (buf); - } - else - { - tty_turn_on_insert (tty); - } - - /* This is the last run. */ - coding->mode |= CODING_MODE_LAST_BLOCK; - conversion_buffer - = encode_terminal_code (&glyph_on_char_cell_before_last, 1, - coding); - if (coding->produced > 0) - { - block_input (); - fwrite (conversion_buffer, 1, coding->produced, - tty->output); - clearerr (tty->output); - if (tty->termscript) - fwrite (conversion_buffer, 1, coding->produced, - tty->termscript); - unblock_input (); - } - - tty_turn_off_insert (tty); - } - - /* Turn appearance modes off. */ - turn_off_face (f, face_id); - tty_turn_off_highlight (tty); - - cmcheckmagic (tty); + tty_write_glyphs_1 (f, string, len, -1); } -#endif - /* An implementation of insert_glyphs for termcap frames. */ static void @@ -2615,8 +2530,8 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, cursor_to (f, pos_y, pos_x); if (draw == DRAW_MOUSE_FACE) - tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos, - nglyphs, face_id); + tty_write_glyphs_1 (f, row->glyphs[TEXT_AREA] + start_hpos, + nglyphs, face_id); else if (draw == DRAW_NORMAL_TEXT) write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs); -- 2.37.1