| tChange internal character representation. - st - [fork] customized build of st… | |
| git clone git://src.adamsgaard.dk/st | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| commit 21f765426c36991edd8b14f4989d66187e9ff597 | |
| parent 753fe862b14c7dd4b0449ab2c3bf22ecbb10030e | |
| Author: [email protected] <[email protected]> | |
| Date: Tue, 21 Apr 2015 23:29:01 +0200 | |
| Change internal character representation. | |
| Diffstat: | |
| M st.c | 73 +++++++++++++++--------------… | |
| 1 file changed, 35 insertions(+), 38 deletions(-) | |
| --- | |
| diff --git a/st.c b/st.c | |
| t@@ -72,6 +72,7 @@ char *argv0; | |
| #define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177') | |
| #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) | |
| #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) | |
| +#define ISDELIM(u) (BETWEEN(u, 0, 127) && strchr(worddelimiters, u) != NULL) | |
| #define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) | |
| #define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (… | |
| #define IS_SET(flag) ((term.mode & (flag)) != 0) | |
| t@@ -180,7 +181,7 @@ typedef XftDraw *Draw; | |
| typedef XftColor Color; | |
| typedef struct { | |
| - char c[UTF_SIZ]; /* character code */ | |
| + long u; /* character code */ | |
| ushort mode; /* attribute flags */ | |
| uint32_t fg; /* foreground */ | |
| uint32_t bg; /* background */ | |
| t@@ -410,6 +411,7 @@ static void tstrsequence(uchar); | |
| static inline ushort sixd_to_16bit(int); | |
| static void xdraws(char *, Glyph, int, int, int, int); | |
| +static void xdrawglyph(Glyph, int, int); | |
| static void xhints(void); | |
| static void xclear(int, int, int, int); | |
| static void xdrawcursor(void); | |
| t@@ -461,7 +463,6 @@ static size_t utf8decode(char *, long *, size_t); | |
| static long utf8decodebyte(char, size_t *); | |
| static size_t utf8encode(long, char *); | |
| static char utf8encodebyte(long, size_t); | |
| -static size_t utf8len(char *); | |
| static size_t utf8validate(long *, size_t); | |
| static ssize_t xwrite(int, const char *, size_t); | |
| t@@ -630,11 +631,6 @@ utf8encodebyte(long u, size_t i) { | |
| } | |
| size_t | |
| -utf8len(char *c) { | |
| - return utf8decode(c, &(long){0}, UTF_SIZ); | |
| -} | |
| - | |
| -size_t | |
| utf8validate(long *u, size_t i) { | |
| if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) | |
| *u = UTF_INVALID; | |
| t@@ -679,7 +675,7 @@ tlinelen(int y) { | |
| if(term.line[y][i - 1].mode & ATTR_WRAP) | |
| return i; | |
| - while(i > 0 && term.line[y][i - 1].c[0] == ' ') | |
| + while(i > 0 && term.line[y][i - 1].u == ' ') | |
| --i; | |
| return i; | |
| t@@ -736,7 +732,7 @@ selsnap(int mode, int *x, int *y, int direction) { | |
| * beginning of a line. | |
| */ | |
| prevgp = &term.line[*y][*x]; | |
| - prevdelim = strchr(worddelimiters, prevgp->c[0]) != NULL; | |
| + prevdelim = ISDELIM(prevgp->u); | |
| for(;;) { | |
| newx = *x + direction; | |
| newy = *y; | |
| t@@ -758,9 +754,9 @@ selsnap(int mode, int *x, int *y, int direction) { | |
| break; | |
| gp = &term.line[newy][newx]; | |
| - delim = strchr(worddelimiters, gp->c[0]) != NULL; | |
| + delim = ISDELIM(gp->u); | |
| if(!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim | |
| - || (delim && gp->c[0] != prevgp->c[0])… | |
| + || (delim && gp->u != prevgp->u))) | |
| break; | |
| *x = newx; | |
| t@@ -936,7 +932,7 @@ bpress(XEvent *e) { | |
| char * | |
| getsel(void) { | |
| char *str, *ptr; | |
| - int y, bufsize, size, lastx, linelen; | |
| + int y, bufsize, lastx, linelen; | |
| Glyph *gp, *last; | |
| if(sel.ob.x == -1) | |
| t@@ -957,16 +953,14 @@ getsel(void) { | |
| lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1; | |
| } | |
| last = &term.line[y][MIN(lastx, linelen-1)]; | |
| - while(last >= gp && last->c[0] == ' ') | |
| + while(last >= gp && last->u == ' ') | |
| --last; | |
| for( ; gp <= last; ++gp) { | |
| if(gp->mode & ATTR_WDUMMY) | |
| continue; | |
| - size = utf8len(gp->c); | |
| - memcpy(ptr, gp->c, size); | |
| - ptr += size; | |
| + ptr += utf8encode(gp->u, ptr); | |
| } | |
| /* | |
| t@@ -1643,17 +1637,17 @@ 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].u = ' '; | |
| 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].u = ' '; | |
| 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); | |
| + utf8decode(c, &term.line[y][x].u, UTF_SIZ); | |
| } | |
| void | |
| t@@ -1680,7 +1674,7 @@ tclearregion(int x1, int y1, int x2, int y2) { | |
| gp->fg = term.c.attr.fg; | |
| gp->bg = term.c.attr.bg; | |
| gp->mode = 0; | |
| - memcpy(gp->c, " ", 2); | |
| + gp->u = ' '; | |
| } | |
| } | |
| } | |
| t@@ -2400,13 +2394,14 @@ tdumpsel(void) { | |
| void | |
| tdumpline(int n) { | |
| + char buf[UTF_SIZ]; | |
| Glyph *bp, *end; | |
| bp = &term.line[n][0]; | |
| end = &bp[MIN(tlinelen(n), term.col) - 1]; | |
| - if(bp != end || bp->c[0] != ' ') { | |
| + if(bp != end || bp->u != ' ') { | |
| for( ;bp <= end; ++bp) | |
| - tprinter(bp->c, utf8len(bp->c)); | |
| + tprinter(buf, utf8encode(bp->u, buf)); | |
| } | |
| tprinter("\n", 1); | |
| } | |
| t@@ -2789,7 +2784,7 @@ tputc(char *c, int len) { | |
| if(width == 2) { | |
| gp->mode |= ATTR_WIDE; | |
| if(term.c.x+1 < term.col) { | |
| - gp[1].c[0] = '\0'; | |
| + gp[1].u = '\0'; | |
| gp[1].mode = ATTR_WDUMMY; | |
| } | |
| } | |
| t@@ -3553,10 +3548,19 @@ xdraws(char *s, Glyph base, int x, int y, int charlen,… | |
| } | |
| void | |
| +xdrawglyph(Glyph g, int x, int y) { | |
| + static char buf[UTF_SIZ]; | |
| + size_t len = utf8encode(g.u, buf); | |
| + int width = g.mode & ATTR_WIDE ? 2 : 1; | |
| + | |
| + xdraws(buf, g, x, y, width, len); | |
| +} | |
| + | |
| +void | |
| xdrawcursor(void) { | |
| static int oldx = 0, oldy = 0; | |
| - int sl, width, curx; | |
| - Glyph g = {{' '}, ATTR_NULL, defaultbg, defaultcs}; | |
| + int curx; | |
| + Glyph g = {' ', ATTR_NULL, defaultbg, defaultcs}; | |
| LIMIT(oldx, 0, term.col-1); | |
| LIMIT(oldy, 0, term.row-1); | |
| t@@ -3569,13 +3573,10 @@ xdrawcursor(void) { | |
| if(term.line[term.c.y][curx].mode & ATTR_WDUMMY) | |
| curx--; | |
| - memcpy(g.c, term.line[term.c.y][term.c.x].c, UTF_SIZ); | |
| + g.u = term.line[term.c.y][term.c.x].u; | |
| /* remove the old cursor */ | |
| - sl = utf8len(term.line[oldy][oldx].c); | |
| - width = (term.line[oldy][oldx].mode & ATTR_WIDE)? 2 : 1; | |
| - xdraws(term.line[oldy][oldx].c, term.line[oldy][oldx], oldx, | |
| - oldy, width, sl); | |
| + xdrawglyph(term.line[oldy][oldx], oldx, oldy); | |
| if(IS_SET(MODE_HIDE)) | |
| return; | |
| t@@ -3592,10 +3593,8 @@ xdrawcursor(void) { | |
| g.bg = defaultfg; | |
| } | |
| - sl = utf8len(g.c); | |
| - width = (term.line[term.c.y][curx].mode & ATTR… | |
| - ? 2 : 1; | |
| - xdraws(g.c, g, term.c.x, term.c.y, width, sl); | |
| + g.mode |= term.line[term.c.y][curx].mode & ATT… | |
| + xdrawglyph(g, term.c.x, term.c.y); | |
| break; | |
| case 3: /* Blinking Underline */ | |
| case 4: /* Steady Underline */ | |
| t@@ -3668,7 +3667,7 @@ draw(void) { | |
| void | |
| drawregion(int x1, int y1, int x2, int y2) { | |
| - int ic, ib, x, y, ox, sl; | |
| + int ic, ib, x, y, ox; | |
| Glyph base, new; | |
| char buf[DRAW_BUF_SIZ]; | |
| bool ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN); | |
| t@@ -3700,9 +3699,7 @@ drawregion(int x1, int y1, int x2, int y2) { | |
| base = new; | |
| } | |
| - sl = utf8len(new.c); | |
| - memcpy(buf+ib, new.c, sl); | |
| - ib += sl; | |
| + ib += utf8encode(new.u, buf+ib); | |
| ic += (new.mode & ATTR_WIDE)? 2 : 1; | |
| } | |
| if(ib > 0) |