[hackers] [st] Wide character support. || Christoph Lohmann

From: <git_AT_suckless.org>
Date: Sat, 07 Sep 2013 12:45:20 +0200

commit 210dda9570095443bac887c2bfcd75f2bcc23780
Author: Christoph Lohmann <20h_AT_r-36.net>
Date: Sat Sep 7 12:41:36 2013 +0200

    Wide character support.
    
    Thanks "Eon S. Jeon" <esjeon_AT_hyunmu.am>!

diff --git a/TODO b/TODO
index 794b71b..0c538e5 100644
--- a/TODO
+++ b/TODO
_AT_@ -1,7 +1,6 @@
 vt emulation
 ------------
 
-* wide-character support in conjunction with fallback xft code
 * double-height support
 
 code & interface
diff --git a/st.c b/st.c
index 0fa0c86..96d45bf 100644
--- a/st.c
+++ b/st.c
_AT_@ -27,6 +27,7 @@
 #include <X11/keysym.h>
 #include <X11/Xft/Xft.h>
 #include <fontconfig/fontconfig.h>
+#include <wchar.h>
 
 #include "arg.h"
 
_AT_@ -96,6 +97,8 @@ enum glyph_attribute {
         ATTR_ITALIC = 16,
         ATTR_BLINK = 32,
         ATTR_WRAP = 64,
+ ATTR_WIDE = 128,
+ ATTR_WDUMMY = 256,
 };
 
 enum cursor_movement {
_AT_@ -165,7 +168,7 @@ typedef unsigned short ushort;
 
 typedef struct {
         char c[UTF_SIZ]; /* character code */
- uchar mode; /* attribute flags */
+ ushort mode; /* attribute flags */
         ulong fg; /* foreground */
         ulong bg; /* background */
 } Glyph;
_AT_@ -719,8 +722,13 @@ selsnap(int mode, int *x, int *y, int direction) {
                                 }
                         }
 
+ if(term.line[*y][*x+direction].mode & ATTR_WDUMMY) {
+ *x += direction;
+ continue;
+ }
+
                         if(strchr(worddelimiters,
- term.line[*y][*x + direction].c[0])) {
+ term.line[*y][*x+direction].c[0])) {
                                 break;
                         }
 
_AT_@ -932,7 +940,7 @@ selcopy(void) {
                                 /* nothing */;
 
                         for(x = 0; gp <= last; x++, ++gp) {
- if(!selected(x, y))
+ if(!selected(x, y) || (gp->mode & ATTR_WDUMMY))
                                         continue;
 
                                 size = utf8size(gp->c);
_AT_@ -1533,6 +1541,16 @@ tsetchar(char *c, Glyph *attr, int x, int y) {
                 }
         }
 
+ if(term.line[y][x].mode & ATTR_WIDE) {
+ if(x+1 < term.col) {
+ term.line[y][x+1].c[0] = ' ';
+ term.line[y][x+1].mode &= ~ATTR_WDUMMY;
+ }
+ } else if(term.line[y][x].mode & ATTR_WDUMMY) {
+ term.line[y][x-1].c[0] = ' ';
+ term.line[y][x-1].mode &= ~ATTR_WIDE;
+ }
+
         term.dirty[y] = 1;
         term.line[y][x] = *attr;
         memcpy(term.line[y][x].c, c, UTF_SIZ);
_AT_@ -2222,6 +2240,15 @@ void
 tputc(char *c, int len) {
         uchar ascii = *c;
         bool control = ascii < '\x20' || ascii == 0177;
+ long u8char;
+ int width;
+
+ if(len == 1) {
+ width = 1;
+ } else {
+ utf8decode(c, &u8char);
+ width = wcwidth(u8char);
+ }
 
         if(iofd != -1) {
                 if(xwrite(iofd, c, len) < 0) {
_AT_@ -2469,9 +2496,20 @@ tputc(char *c, int len) {
                         (term.col - term.c.x - 1) * sizeof(Glyph));
         }
 
+ if(term.c.x+width > term.col)
+ tnewline(1);
+
         tsetchar(c, &term.c.attr, term.c.x, term.c.y);
- if(term.c.x+1 < term.col) {
- tmoveto(term.c.x+1, term.c.y);
+
+ if(width == 2) {
+ term.line[term.c.y][term.c.x].mode |= ATTR_WIDE;
+ if(term.c.x+1 < term.col) {
+ term.line[term.c.y][term.c.x+1].c[0] = '
Received on Sat Sep 07 2013 - 12:45:20 CEST

This archive was generated by hypermail 2.3.0 : Sat Sep 07 2013 - 12:48:21 CEST