Greetings comrades.

You guys forced me to do it. Attached is a preliminary patch to add line
drawing, which is using UTF-8 characters, to the latest tip of st.

There are bugs:
* the implementation is a pure hack (It is a proof of concept. Some
people really seem to need those line drawing characters, so they have
to fix it.)
* alsamixer has problems drawing the different characters inline (I
don't have the time to fix it now.)
* copy and paste does not really work, because this hack does not
affect it (I don't want to fix it, but if someone sends the patch it
will be fixed.)

Please don't report back »works« or »does not work«. This crap is only
implemented because you people are unable to fix any applications or are
too lazy to do so. This is suckless, where you are supposed to go deeper
and fix bugs.

Sincerely,

Christoph Lohmann
diff -r 36f8cd105d65 st.c
--- a/st.c	Tue Sep 25 21:39:25 2012 +0200
+++ b/st.c	Wed Sep 26 08:41:32 2012 +0200
@@ -1177,7 +1177,7 @@
 		switch(attr[i]) {
 		case 0:
 			term.c.attr.mode &= ~(ATTR_REVERSE | ATTR_UNDERLINE | ATTR_BOLD \
-					| ATTR_ITALIC | ATTR_BLINK | ATTR_GFX);
+					| ATTR_ITALIC | ATTR_BLINK);
 			term.c.attr.fg = DefaultFG;
 			term.c.attr.bg = DefaultBG;
 			break;
@@ -1676,12 +1676,18 @@
 				strhandle();
 		} else if(term.esc & ESC_ALTCHARSET) {
 			switch(ascii) {
-			case '0': /* Line drawing crap */
+			case '0': /* Line drawing set */
 				term.c.attr.mode |= ATTR_GFX;
 				break;
-			case 'B': /* Back to regular text */
+			case 'B': /* USASCII */
 				term.c.attr.mode &= ~ATTR_GFX;
 				break;
+			case 'A': /* UK (IGNORED) */
+			case '<': /* multinational charset (IGNORED) */
+			case '5': /* Finnish (IGNORED) */
+			case 'C': /* Finnish (IGNORED) */
+			case 'K': /* German (IGNORED) */
+				break;
 			default:
 				fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii);
 			}
@@ -1700,10 +1706,13 @@
 				strescseq.type = ascii;
 				term.esc |= ESC_STR;
 				break;
-			case ')':
-			case '(':
+			case '(': /* set primary charset G0 */
 				term.esc |= ESC_ALTCHARSET;
 				break;
+			case ')': /* set secondary charset G1 (IGNORED) */
+			case '*': /* set tertiary charset G2 (IGNORED) */
+			case '+': /* set quaternary charset G3 (IGNORED) */
+				break;
 			case 'D': /* IND -- Linefeed */
 				if(term.c.y == term.bot)
 					tscrollup(term.top, 1);
@@ -2068,6 +2077,8 @@
 	Font *font = &dc.font;
 	XGlyphInfo extents;
 	int i;
+	char *as, *asp;
+	int al;
 
 	/* only switch default fg/bg if term is in RV mode */
 	if(IS_SET(MODE_REVERSE)) {
@@ -2093,14 +2104,60 @@
 	XSetBackground(xw.dpy, dc.gc, dc.col[bg]);
 	XSetForeground(xw.dpy, dc.gc, dc.col[fg]);
 
+	/*
+	 * Most of the code proudly stolen from the rxvt codebase.
+	 */
+	as = NULL;
 	if(base.mode & ATTR_GFX) {
-		for(i = 0; i < bytelen; i++) {
-			char c = gfx[(uint)s[i] % 256];
-			if(c)
-				s[i] = c;
-			else if(s[i] > 0x5f)
-				s[i] -= 0x5f;
+		fprintf(stderr, "ATTR_GFX: '%.*s'\n", bytelen, s);
+		al = strlen(s) * 4;
+		asp = as = xmalloc(al+1);
+		memset(as, 0, al+1);
+
+		char *vt100_0[62] = { /* 0x41 - 0x7e */
+			"↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */
+			0, 0, 0, 0, 0, 0, 0, 0, /* H - O */
+			0, 0, 0, 0, 0, 0, 0, 0, /* P - W */
+			0, 0, 0, 0, 0, 0, 0, " ", /* X - _ */
+			"◆", "▒", "␉", "␌", "␍", "␊", "°", "±", /* ` - g */
+			"␤", "␋", "┘", "┐", "┌", "└", "┼", "⎺", /* h - o */
+			"⎻", "─", "⎼", "⎽", "├", "┤", "┴", "┬", /* p - w */
+			"│", "≤", "≥", "π", "≠", "£", "·", /* x - ~ */
+		};
+
+		char *c;
+		int cl = 0, sb = bytelen;
+
+		charlen = 0;
+		bytelen = 0;
+		for(i = 0; i < sb; i++) {
+			if((uint)s[i] < 0x41 || (uint)s[i] > 0x7e
+					|| !vt100_0[(uint)s[i] - 0x41]) {
+				as = strncat(as, &s[1], 1);
+				asp++;
+				charlen++;
+				bytelen++;
+				continue;
+			}
+
+			c = vt100_0[(uint)s[i] - 0x41];
+			cl = strlen(c);
+
+			fprintf(stderr, "'%c' -> '%s'\n", s[i], c);
+
+			if(asp + cl > as + al - 1)
+				break;
+
+			asp = strcat(asp, c);
+			asp += cl;
+			bytelen += cl;
+			charlen++;
 		}
+		fprintf(stderr, "as (%d) (%d) = '%s'\n", charlen, bytelen, as);
+	}
+	if(as != NULL) {
+		s = as;
+		width = charlen * xw.cw;
 	}
 
 	XftTextExtentsUtf8(xw.dpy, font->xft_set, (FcChar8 *)s, bytelen, &extents);
@@ -2110,6 +2167,9 @@
 
 	if(base.mode & ATTR_UNDERLINE)
 		XDrawLine(xw.dpy, xw.buf, dc.gc, winx, winy+1, winx+width-1, winy+1);
+
+	if(as != NULL)
+		free(as);
 }
 
 void

Reply via email to