diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-08-13 07:19:28 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-08-13 07:19:28 -0700 |
commit | 4b308561021d4dedd7e83e5df30534d1fdde2216 (patch) | |
tree | 5dfe9d9f3463b3d819387618e1dc6005d831aec9 | |
parent | 1684fc0bedfa9fa9a5a7a22d6fb44e660a203a1c (diff) | |
download | txr-4b308561021d4dedd7e83e5df30534d1fdde2216.tar.gz txr-4b308561021d4dedd7e83e5df30534d1fdde2216.tar.bz2 txr-4b308561021d4dedd7e83e5df30534d1fdde2216.zip |
Observe display width in format.
Take into account string display width in field trimming and padding
calculations, including situations where only half a character fits.
* stream.c (calc_fitlen): New function.
(vformat_str): Revised to use calc_fitlen. If calc_fitlen indicates
that there is no trimming or padding, then use put_string rather than
put_char.
* txr.1: Update description of format with regard to use of
dispaly width in field calculations.
-rw-r--r-- | stream.c | 42 | ||||
-rw-r--r-- | txr.1 | 26 |
2 files changed, 59 insertions, 9 deletions
@@ -2081,21 +2081,51 @@ static void vformat_num(val stream, const char *str, vformat_align_post(stream, align, slack); } +static cnum calc_fitlen(const wchar_t *cstr, int precision, int width) +{ + cnum i, fitlen; + wchar_t ch; + + if (width == 0 && precision == 0) + return INT_PTR_MAX; + + for (i = 0, fitlen = 0; (ch = cstr[i]) != 0; i++) { + int chw = iswcntrl(ch) ? 0 : 1 + wide_display_char_p(ch); + + if (precision && fitlen + chw > precision) + break; + + if (width && fitlen + chw > width) + return INT_PTR_MAX; + + fitlen += chw; + } + + return fitlen; +} + static void vformat_str(val stream, val str, int width, enum align align, int precision) { const wchar_t *cstr = c_str(str); - int len = c_num(length_str(str)); - int truelen = (precision && precision < len) ? precision : len; - int slack = (truelen < width) ? width - truelen : 0; - int i; + cnum fitlen = calc_fitlen(cstr, precision, width); + cnum slack = (fitlen < width) ? width - fitlen : 0; + cnum i, w; + wchar_t wc; prot1(&str); vformat_align_pre(stream, align, slack); - for (i = 0; i < truelen; i++) - put_char(chr(cstr[i]), stream); + if (fitlen == INT_PTR_MAX) { + put_string(str, stream); + } else for (i = 0, w = 0; (wc = cstr[i]) != 0; i++) { + int cw = iswcntrl(wc) ? 0 : 1 + wide_display_char_p(wc); + if (w + cw > fitlen) + break; + put_char(chr(wc), stream); + w += cw; + } vformat_align_post(stream, align, slack); @@ -26945,6 +26945,20 @@ or prefix character is present in the width specifier, then the field is adjusted according to that character. +The padding calculations for alignment and centering take into account +character display width, as defined by the +.code display-width +function. For instance, a character string containing four Chinese +characters (kanji) has a display width of 8, not 4. + +The width specification does not restrict the printed portion of a datum. +Rather, for some kinds of conversions, it is the precision specification that +performs such truncation. A datum's display width (or that of its printed +portion, after such truncation is applied) can equal or exceed the specified +field width. In this situation it overflows the field: the printed portion is +rendered in its entirety without any padding applied on either side for +alignment or centering. + .meIP < precision The precision specifier is introduced by a leading comma. If this comma appears immediately after the directive's @@ -27007,9 +27021,15 @@ numbers are unconditionally prefixed with a .code - sign. -For all other objects, the precision specifies the maximum number of characters -to print. The object's printed representation is crudely truncated at that -number of characters. +For all other objects, the precision specifies the maximum number of +print positions to occupy, taking into account the display width of each +character of the printed representation of the object, as according +to the +.code display-width +function. The object's printed representation is truncated, if necessary, to +the maximum number of characters which will not exceed the specified number of +print positions. + .RE .TP* "Format directives:" |