mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Fix printing double-width char in rightmost column without wrap.
Another bug turned up by writing tests. The code that spots that the
character won't fit, and wraps it to the next line setting
LATTR_WRAPPED2, was not checking that wrap mode was _enabled_ before
doing that. So if you printed a DW character in the rightmost column
while the terminal was in non-auto-wrap mode, you'd get an unwanted
wrap.
Other terminals disagree on what to do here. xterm leaves the cursor
in the same place and doesn't print any character at all.
gnome-terminal, on the other hand, backspaces by a character so that
it _can_ print the requested DW character, in the rightmost _two_
columns.
I think I don't much like either of those, so instead I'm using the
same fallback we use for displaying a DW character when the whole
terminal is only one column wide: if there is physically no room to
print the requested character, turn it into U+FFFD REPLACEMENT
CHARACTER.
(cherry picked from commit ed5bf9b3b8
)
This commit is contained in:
parent
8b8b774fc0
commit
15081bb0ad
@ -3331,34 +3331,43 @@ static void term_display_graphic_char(Terminal *term, unsigned long c)
|
|||||||
linecols -= TRUST_SIGIL_WIDTH;
|
linecols -= TRUST_SIGIL_WIDTH;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Preliminary check: if the terminal is only one character cell
|
* Before we switch on the character width, do a preliminary check for
|
||||||
* wide, then we cannot display any double-width character at all.
|
* cases where we might have no room at all to display a double-width
|
||||||
* Substitute single-width REPLACEMENT CHARACTER instead.
|
* character. Our fallback is to substitute REPLACEMENT CHARACTER,
|
||||||
|
* which is single-width, and it's easiest to do that _before_ having
|
||||||
|
* to 'goto' from one switch case to another.
|
||||||
*/
|
*/
|
||||||
if (width == 2 && linecols < 2) {
|
if (width == 2 && term->curs.x >= linecols-1) {
|
||||||
width = 1;
|
/*
|
||||||
c = 0xFFFD;
|
* If we're in wrapping mode and the terminal is at least 2 cells
|
||||||
|
* wide, it's OK, we have a fallback. But otherwise, substitute.
|
||||||
|
*/
|
||||||
|
if (linecols < 2 || !term->wrap) {
|
||||||
|
width = 1;
|
||||||
|
c = 0xFFFD;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (width) {
|
switch (width) {
|
||||||
case 2:
|
case 2:
|
||||||
/*
|
/*
|
||||||
* If we're about to display a double-width character starting
|
* If we're about to display a double-width character starting in
|
||||||
* in the rightmost column, then we do something special
|
* the rightmost column (and we're in wrapping mode - the other
|
||||||
* instead. We must print a space in the last column of the
|
* case was disposed of above), then we do something special
|
||||||
* screen, then wrap; and we also set LATTR_WRAPPED2 which
|
* instead. We must print a space in the last column of the screen,
|
||||||
* instructs subsequent cut-and-pasting not only to splice
|
* then wrap; and we also set LATTR_WRAPPED2 which instructs
|
||||||
* this line to the one after it, but to ignore the space in
|
* subsequent cut-and-pasting not only to splice this line to the
|
||||||
* the last character position as well. (Because what was
|
* one after it, but to ignore the space in the last character
|
||||||
* actually output to the terminal was presumably just a
|
* position as well. (Because what was actually output to the
|
||||||
* sequence of CJK characters, and we don't want a space to be
|
* terminal was presumably just a sequence of CJK characters, and
|
||||||
* pasted in the middle of those just because they had the
|
* we don't want a space to be pasted in the middle of those just
|
||||||
* misfortune to start in the wrong parity column. xterm
|
* because they had the misfortune to start in the wrong parity
|
||||||
* concurs.)
|
* column. xterm concurs.)
|
||||||
*/
|
*/
|
||||||
check_boundary(term, term->curs.x, term->curs.y);
|
check_boundary(term, term->curs.x, term->curs.y);
|
||||||
check_boundary(term, term->curs.x+2, term->curs.y);
|
check_boundary(term, term->curs.x+2, term->curs.y);
|
||||||
if (term->curs.x >= linecols-1) {
|
if (term->curs.x >= linecols-1) {
|
||||||
|
assert(term->wrap); /* we handled the non-wrapping case above */
|
||||||
copy_termchar(cline, term->curs.x,
|
copy_termchar(cline, term->curs.x,
|
||||||
&term->erase_char);
|
&term->erase_char);
|
||||||
cline->lattr |= LATTR_WRAPPED | LATTR_WRAPPED2;
|
cline->lattr |= LATTR_WRAPPED | LATTR_WRAPPED2;
|
||||||
|
Loading…
Reference in New Issue
Block a user