addch (' ');
}
+/* See how many bytes to copy from string so its at most maxlen bytes
+ * long and maxwid columns wide */
+int mutt_wstr_trunc (const char *src, size_t maxlen, size_t maxwid, size_t *width)
+{
+ wchar_t wc;
+ int w = 0, l = 0, cl;
+ size_t cw, n;
+ mbstate_t mbstate;
+
+ if (!src)
+ goto out;
+
+ n = mutt_strlen (src);
+
+ memset (&mbstate, 0, sizeof (mbstate));
+ for (w = 0; n && (cl = mbrtowc (&wc, src, n, &mbstate)); src += cl, n -= cl)
+ {
+ if (cl == (size_t)(-1) || cl == (size_t)(-2))
+ cw = cl = 1;
+ else
+ cw = wcwidth (wc);
+ if (cl + l > maxlen || cw + w > maxwid)
+ break;
+ l += cl;
+ w += cw;
+ }
+out:
+ if (width)
+ *width = w;
+ return l;
+}
+
/*
* returns the number of bytes the first (multibyte) character
* of input consumes:
else if (soft && pad < 0)
{
/* set wptr and wlen back just enough bytes to make sure buf
- * fits on screen, col needs no adjustments as we skip more input
- * currently multibyte unaware */
+ * fits on screen, \0-terminate dest so mutt_wstr_trunc()
+ * can correctly compute string's length */
if (pad < -wlen)
pad = -wlen;
- wlen += pad;
- wptr += pad;
+ *wptr = 0;
+ wlen = mutt_wstr_trunc (dest, wlen + pad, col + pad, &col);
+ wptr = dest + wlen;
}
if (len + wlen > destlen)
- len = destlen - wlen;
- /* copy as much of buf as possible: multibyte unaware */
+ len = mutt_wstr_trunc (buf, destlen - wlen, COLS - col, NULL);
memcpy (wptr, buf, len);
wptr += len;
wlen += len;
}
if ((len = mutt_strlen (buf)) + wlen > destlen)
- len = (destlen - wlen > 0) ? (destlen - wlen) : 0;
+ len = mutt_wstr_trunc (buf, destlen - wlen, COLS - col, NULL);
memcpy (wptr, buf, len);
wptr += len;
int mutt_smtp_send (const ADDRESS *, const ADDRESS *, const ADDRESS *,
const ADDRESS *, const char *, int);
#endif
+int mutt_wstr_trunc (const char *, size_t, size_t, size_t *);
int mutt_charlen (const char *s, int *);
int mutt_strwidth (const char *);
int mutt_compose_menu (HEADER *, char *, size_t, HEADER *);