"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Christian Weisgerber <naddy@mips.inka.de>
Subject:
Re: tog: fix display of lines ending in \r\n
To:
gameoftrees@openbsd.org
Date:
Sat, 12 Dec 2020 19:05:19 +0100

Download raw body.

Thread
Stefan Sperling:

> > +			} else if (iswcntrl(wline[i])) {
> > +				if (cols + 2 > wlimit)
> > +					break;
> > +				cols += 2;
> 
> OK. This is a nice and compact solution.

No, it is not.  I retract it.

It assumes that iswcntrl() matches the curses behavior and that
curses will produce a two-character printable representation.  That's
very brittle and if it is ever out of sync with what curses actually
does, you get garbage... That didn't take long: The columns are off
on FreeBSD.

I tried the approach with wunctrl() again, see below.  Unfortunately,
ncurses is inconsistent.  It will actually render (wchar_t)0x9B as
"~[", but wunctrl() says that's a printable character with width 1.
(That diff is fine on FreeBSD, though, but it represents 0x9B with
a space ...)

It's possible OpenBSD's ncurses is misconfigured, I don't know.
I think the last update predates the Latin 1 to UTF-8 policy
change.

The handling of code points 0x0080..0x009F is a sore point.

I don't know what to do.  Go through the line character by character
and handle control char > replacement representation ourselves?


diff 9f6bb280654be7061fc00305743f6ace71f9a1cb /home/naddy/got
blob - 99232045ade1a4d37286e512dd4999368a1b89b5
file + tog/tog.c
--- tog/tog.c
+++ tog/tog.c
@@ -1193,6 +1193,16 @@ format_line(wchar_t **wlinep, int *widthp, const char 
 				if (cols + width > wlimit)
 					break;
 				cols += width;
+			} else {
+				cchar_t cch;
+				wchar_t wch[2] = { wline[i], L'\0' };
+
+				if (setcchar(&cch, wch, 0, 0, NULL) == OK) {
+					width = wcslen(wunctrl(&cch));
+					if (cols + width > wlimit)
+						break;
+					cols += width;
+				}
 			}
 			i++;
 		} else {

-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de