1 /* $OpenBSD: utf8.c,v 1.1 2018/07/29 11:27:15 schwarze Exp $ */ 2 /* 3 * Copyright (c) 2018 Ingo Schwarze <schwarze@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <stdlib.h> 19 #include <wchar.h> 20 21 /* 22 * Measure the display width of the multibyte string. 23 * Treat invalid bytes and non-printable characters as width 1. 24 * Truncate the string to a display width of maxwidth. 25 * Return the total width, possibly after truncation. 26 */ 27 int 28 mbswidth_truncate(char *mbs, int maxwidth) 29 { 30 wchar_t wc; 31 int len, width, sum; 32 33 sum = 0; 34 while (*mbs != '\0') { 35 if ((len = mbtowc(&wc, mbs, MB_CUR_MAX)) == -1) 36 len = width = 1; 37 else if ((width = wcwidth(wc)) < 0) 38 width = 1; 39 if (sum + width > maxwidth) { 40 *mbs = '\0'; 41 break; 42 } 43 sum += width; 44 mbs += len; 45 } 46 return sum; 47 } 48