version 1.22, 2017/04/02 23:02:06 |
version 1.23, 2019/02/24 04:54:36 |
|
|
* in preparation for output to the screen. |
* in preparation for output to the screen. |
*/ |
*/ |
|
|
|
#include <wchar.h> |
|
|
#include "charset.h" |
#include "charset.h" |
#include "less.h" |
#include "less.h" |
|
|
|
|
* attribute sequence to be inserted, so this must be taken into account. |
* attribute sequence to be inserted, so this must be taken into account. |
*/ |
*/ |
static int |
static int |
pwidth(LWCHAR ch, int a, LWCHAR prev_ch) |
pwidth(wchar_t ch, int a, wchar_t prev_ch) |
{ |
{ |
int w; |
int w; |
|
|
if (ch == '\b') |
/* |
/* |
* In case of a backspace, back up by the width of the previous |
* Backspace moves backwards one or two positions. |
* character. If that is non-printable (for example another |
* XXX - Incorrect if several '\b' in a row. |
* backspace) or zero width (for example a combining accent), |
*/ |
* the terminal may actually back up to a character even further |
return ((utf_mode && is_wide_char(prev_ch)) ? -2 : -1); |
* back, but we no longer know how wide that may have been. |
|
* The best guess possible at this point is that it was |
if (!utf_mode || is_ascii_char(ch)) { |
* hopefully width one. |
if (control_char((char)ch)) { |
*/ |
/* |
if (ch == L'\b') { |
* Control characters do unpredictable things, |
w = wcwidth(prev_ch); |
* so we don't even try to guess; say it doesn't move. |
if (w <= 0) |
* This can only happen if the -r flag is in effect. |
w = 1; |
*/ |
return (-w); |
return (0); |
|
} |
|
} else { |
|
if (is_composing_char(ch) || is_combining_char(prev_ch, ch)) { |
|
/* |
|
* Composing and combining chars take up no space. |
|
* |
|
* Some terminals, upon failure to compose a |
|
* composing character with the character(s) that |
|
* precede(s) it will actually take up one column |
|
* for the composing character; there isn't much |
|
* we could do short of testing the (complex) |
|
* composition process ourselves and printing |
|
* a binary representation when it fails. |
|
*/ |
|
return (0); |
|
} |
|
} |
} |
|
|
|
w = wcwidth(ch); |
|
|
/* |
/* |
|
* Non-printable characters can get here if the -r flag is in |
|
* effect, and possibly in some other situations (XXX check that!). |
|
* Treat them as zero width. |
|
* That may not always match their actual behaviour, |
|
* but there is no reasonable way to be more exact. |
|
*/ |
|
if (w == -1) |
|
w = 0; |
|
|
|
/* |
|
* Combining accents take up no space. |
|
* Some terminals, upon failure to compose them with the |
|
* characters that precede them, will actually take up one column |
|
* for the combining accent; there isn't much we could do short |
|
* of testing the (complex) composition process ourselves and |
|
* printing a binary representation when it fails. |
|
*/ |
|
if (w == 0) |
|
return (0); |
|
|
|
/* |
* Other characters take one or two columns, |
* Other characters take one or two columns, |
* plus the width of any attribute enter/exit sequence. |
* plus the width of any attribute enter/exit sequence. |
*/ |
*/ |
w = 1; |
|
if (is_wide_char(ch)) |
|
w++; |
|
if (curr > 0 && !is_at_equiv(attr[curr-1], a)) |
if (curr > 0 && !is_at_equiv(attr[curr-1], a)) |
w += attr_ewidth(attr[curr-1]); |
w += attr_ewidth(attr[curr-1]); |
if ((apply_at_specials(a) != AT_NORMAL) && |
if ((apply_at_specials(a) != AT_NORMAL) && |