summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-08-13 07:19:28 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-08-13 07:19:28 -0700
commit4b308561021d4dedd7e83e5df30534d1fdde2216 (patch)
tree5dfe9d9f3463b3d819387618e1dc6005d831aec9
parent1684fc0bedfa9fa9a5a7a22d6fb44e660a203a1c (diff)
downloadtxr-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.c42
-rw-r--r--txr.126
2 files changed, 59 insertions, 9 deletions
diff --git a/stream.c b/stream.c
index 1ecf5400..bf50220f 100644
--- a/stream.c
+++ b/stream.c
@@ -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);
diff --git a/txr.1 b/txr.1
index d788c6bb..fe7a8536 100644
--- a/txr.1
+++ b/txr.1
@@ -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:"