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