aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornoname@inventati.org <noname@inventati.org>2015-04-21 23:29:01 +0200
committerRoberto E. Vargas Caballero <k0ga@shike2.com>2015-04-27 09:50:01 +0200
commit21f765426c36991edd8b14f4989d66187e9ff597 (patch)
treeaef90464411dc59c362fd9278784ef0a2e4bce2b
parent753fe862b14c7dd4b0449ab2c3bf22ecbb10030e (diff)
downloadst-patched-21f765426c36991edd8b14f4989d66187e9ff597.tar.bz2
st-patched-21f765426c36991edd8b14f4989d66187e9ff597.tar.xz
st-patched-21f765426c36991edd8b14f4989d66187e9ff597.zip
Change internal character representation.
-rw-r--r--st.c73
1 files changed, 35 insertions, 38 deletions
diff --git a/st.c b/st.c
index 8ca310c..2788746 100644
--- a/st.c
+++ b/st.c
@@ -72,6 +72,7 @@ char *argv0;
72#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177') 72#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177')
73#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) 73#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
74#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) 74#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
75#define ISDELIM(u) (BETWEEN(u, 0, 127) && strchr(worddelimiters, u) != NULL)
75#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) 76#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
76#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) 77#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg)
77#define IS_SET(flag) ((term.mode & (flag)) != 0) 78#define IS_SET(flag) ((term.mode & (flag)) != 0)
@@ -180,7 +181,7 @@ typedef XftDraw *Draw;
180typedef XftColor Color; 181typedef XftColor Color;
181 182
182typedef struct { 183typedef struct {
183 char c[UTF_SIZ]; /* character code */ 184 long u; /* character code */
184 ushort mode; /* attribute flags */ 185 ushort mode; /* attribute flags */
185 uint32_t fg; /* foreground */ 186 uint32_t fg; /* foreground */
186 uint32_t bg; /* background */ 187 uint32_t bg; /* background */
@@ -410,6 +411,7 @@ static void tstrsequence(uchar);
410 411
411static inline ushort sixd_to_16bit(int); 412static inline ushort sixd_to_16bit(int);
412static void xdraws(char *, Glyph, int, int, int, int); 413static void xdraws(char *, Glyph, int, int, int, int);
414static void xdrawglyph(Glyph, int, int);
413static void xhints(void); 415static void xhints(void);
414static void xclear(int, int, int, int); 416static void xclear(int, int, int, int);
415static void xdrawcursor(void); 417static void xdrawcursor(void);
@@ -461,7 +463,6 @@ static size_t utf8decode(char *, long *, size_t);
461static long utf8decodebyte(char, size_t *); 463static long utf8decodebyte(char, size_t *);
462static size_t utf8encode(long, char *); 464static size_t utf8encode(long, char *);
463static char utf8encodebyte(long, size_t); 465static char utf8encodebyte(long, size_t);
464static size_t utf8len(char *);
465static size_t utf8validate(long *, size_t); 466static size_t utf8validate(long *, size_t);
466 467
467static ssize_t xwrite(int, const char *, size_t); 468static ssize_t xwrite(int, const char *, size_t);
@@ -630,11 +631,6 @@ utf8encodebyte(long u, size_t i) {
630} 631}
631 632
632size_t 633size_t
633utf8len(char *c) {
634 return utf8decode(c, &(long){0}, UTF_SIZ);
635}
636
637size_t
638utf8validate(long *u, size_t i) { 634utf8validate(long *u, size_t i) {
639 if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) 635 if(!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
640 *u = UTF_INVALID; 636 *u = UTF_INVALID;
@@ -679,7 +675,7 @@ tlinelen(int y) {
679 if(term.line[y][i - 1].mode & ATTR_WRAP) 675 if(term.line[y][i - 1].mode & ATTR_WRAP)
680 return i; 676 return i;
681 677
682 while(i > 0 && term.line[y][i - 1].c[0] == ' ') 678 while(i > 0 && term.line[y][i - 1].u == ' ')
683 --i; 679 --i;
684 680
685 return i; 681 return i;
@@ -736,7 +732,7 @@ selsnap(int mode, int *x, int *y, int direction) {
736 * beginning of a line. 732 * beginning of a line.
737 */ 733 */
738 prevgp = &term.line[*y][*x]; 734 prevgp = &term.line[*y][*x];
739 prevdelim = strchr(worddelimiters, prevgp->c[0]) != NULL; 735 prevdelim = ISDELIM(prevgp->u);
740 for(;;) { 736 for(;;) {
741 newx = *x + direction; 737 newx = *x + direction;
742 newy = *y; 738 newy = *y;
@@ -758,9 +754,9 @@ selsnap(int mode, int *x, int *y, int direction) {
758 break; 754 break;
759 755
760 gp = &term.line[newy][newx]; 756 gp = &term.line[newy][newx];
761 delim = strchr(worddelimiters, gp->c[0]) != NULL; 757 delim = ISDELIM(gp->u);
762 if(!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim 758 if(!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim
763 || (delim && gp->c[0] != prevgp->c[0]))) 759 || (delim && gp->u != prevgp->u)))
764 break; 760 break;
765 761
766 *x = newx; 762 *x = newx;
@@ -936,7 +932,7 @@ bpress(XEvent *e) {
936char * 932char *
937getsel(void) { 933getsel(void) {
938 char *str, *ptr; 934 char *str, *ptr;
939 int y, bufsize, size, lastx, linelen; 935 int y, bufsize, lastx, linelen;
940 Glyph *gp, *last; 936 Glyph *gp, *last;
941 937
942 if(sel.ob.x == -1) 938 if(sel.ob.x == -1)
@@ -957,16 +953,14 @@ getsel(void) {
957 lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1; 953 lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1;
958 } 954 }
959 last = &term.line[y][MIN(lastx, linelen-1)]; 955 last = &term.line[y][MIN(lastx, linelen-1)];
960 while(last >= gp && last->c[0] == ' ') 956 while(last >= gp && last->u == ' ')
961 --last; 957 --last;
962 958
963 for( ; gp <= last; ++gp) { 959 for( ; gp <= last; ++gp) {
964 if(gp->mode & ATTR_WDUMMY) 960 if(gp->mode & ATTR_WDUMMY)
965 continue; 961 continue;
966 962
967 size = utf8len(gp->c); 963 ptr += utf8encode(gp->u, ptr);
968 memcpy(ptr, gp->c, size);
969 ptr += size;
970 } 964 }
971 965
972 /* 966 /*
@@ -1643,17 +1637,17 @@ tsetchar(char *c, Glyph *attr, int x, int y) {
1643 1637
1644 if(term.line[y][x].mode & ATTR_WIDE) { 1638 if(term.line[y][x].mode & ATTR_WIDE) {
1645 if(x+1 < term.col) { 1639 if(x+1 < term.col) {
1646 term.line[y][x+1].c[0] = ' '; 1640 term.line[y][x+1].u = ' ';
1647 term.line[y][x+1].mode &= ~ATTR_WDUMMY; 1641 term.line[y][x+1].mode &= ~ATTR_WDUMMY;
1648 } 1642 }
1649 } else if(term.line[y][x].mode & ATTR_WDUMMY) { 1643 } else if(term.line[y][x].mode & ATTR_WDUMMY) {
1650 term.line[y][x-1].c[0] = ' '; 1644 term.line[y][x-1].u = ' ';
1651 term.line[y][x-1].mode &= ~ATTR_WIDE; 1645 term.line[y][x-1].mode &= ~ATTR_WIDE;
1652 } 1646 }
1653 1647
1654 term.dirty[y] = 1; 1648 term.dirty[y] = 1;
1655 term.line[y][x] = *attr; 1649 term.line[y][x] = *attr;
1656 memcpy(term.line[y][x].c, c, UTF_SIZ); 1650 utf8decode(c, &term.line[y][x].u, UTF_SIZ);
1657} 1651}
1658 1652
1659void 1653void
@@ -1680,7 +1674,7 @@ tclearregion(int x1, int y1, int x2, int y2) {
1680 gp->fg = term.c.attr.fg; 1674 gp->fg = term.c.attr.fg;
1681 gp->bg = term.c.attr.bg; 1675 gp->bg = term.c.attr.bg;
1682 gp->mode = 0; 1676 gp->mode = 0;
1683 memcpy(gp->c, " ", 2); 1677 gp->u = ' ';
1684 } 1678 }
1685 } 1679 }
1686} 1680}
@@ -2400,13 +2394,14 @@ tdumpsel(void) {
2400 2394
2401void 2395void
2402tdumpline(int n) { 2396tdumpline(int n) {
2397 char buf[UTF_SIZ];
2403 Glyph *bp, *end; 2398 Glyph *bp, *end;
2404 2399
2405 bp = &term.line[n][0]; 2400 bp = &term.line[n][0];
2406 end = &bp[MIN(tlinelen(n), term.col) - 1]; 2401 end = &bp[MIN(tlinelen(n), term.col) - 1];
2407 if(bp != end || bp->c[0] != ' ') { 2402 if(bp != end || bp->u != ' ') {
2408 for( ;bp <= end; ++bp) 2403 for( ;bp <= end; ++bp)
2409 tprinter(bp->c, utf8len(bp->c)); 2404 tprinter(buf, utf8encode(bp->u, buf));
2410 } 2405 }
2411 tprinter("\n", 1); 2406 tprinter("\n", 1);
2412} 2407}
@@ -2789,7 +2784,7 @@ tputc(char *c, int len) {
2789 if(width == 2) { 2784 if(width == 2) {
2790 gp->mode |= ATTR_WIDE; 2785 gp->mode |= ATTR_WIDE;
2791 if(term.c.x+1 < term.col) { 2786 if(term.c.x+1 < term.col) {
2792 gp[1].c[0] = '\0'; 2787 gp[1].u = '\0';
2793 gp[1].mode = ATTR_WDUMMY; 2788 gp[1].mode = ATTR_WDUMMY;
2794 } 2789 }
2795 } 2790 }
@@ -3553,10 +3548,19 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
3553} 3548}
3554 3549
3555void 3550void
3551xdrawglyph(Glyph g, int x, int y) {
3552 static char buf[UTF_SIZ];
3553 size_t len = utf8encode(g.u, buf);
3554 int width = g.mode & ATTR_WIDE ? 2 : 1;
3555
3556 xdraws(buf, g, x, y, width, len);
3557}
3558
3559void
3556xdrawcursor(void) { 3560xdrawcursor(void) {
3557 static int oldx = 0, oldy = 0; 3561 static int oldx = 0, oldy = 0;
3558 int sl, width, curx; 3562 int curx;
3559 Glyph g = {{' '}, ATTR_NULL, defaultbg, defaultcs}; 3563 Glyph g = {' ', ATTR_NULL, defaultbg, defaultcs};
3560 3564
3561 LIMIT(oldx, 0, term.col-1); 3565 LIMIT(oldx, 0, term.col-1);
3562 LIMIT(oldy, 0, term.row-1); 3566 LIMIT(oldy, 0, term.row-1);
@@ -3569,13 +3573,10 @@ xdrawcursor(void) {
3569 if(term.line[term.c.y][curx].mode & ATTR_WDUMMY) 3573 if(term.line[term.c.y][curx].mode & ATTR_WDUMMY)
3570 curx--; 3574 curx--;
3571 3575
3572 memcpy(g.c, term.line[term.c.y][term.c.x].c, UTF_SIZ); 3576 g.u = term.line[term.c.y][term.c.x].u;
3573 3577
3574 /* remove the old cursor */ 3578 /* remove the old cursor */
3575 sl = utf8len(term.line[oldy][oldx].c); 3579 xdrawglyph(term.line[oldy][oldx], oldx, oldy);
3576 width = (term.line[oldy][oldx].mode & ATTR_WIDE)? 2 : 1;
3577 xdraws(term.line[oldy][oldx].c, term.line[oldy][oldx], oldx,
3578 oldy, width, sl);
3579 3580
3580 if(IS_SET(MODE_HIDE)) 3581 if(IS_SET(MODE_HIDE))
3581 return; 3582 return;
@@ -3592,10 +3593,8 @@ xdrawcursor(void) {
3592 g.bg = defaultfg; 3593 g.bg = defaultfg;
3593 } 3594 }
3594 3595
3595 sl = utf8len(g.c); 3596 g.mode |= term.line[term.c.y][curx].mode & ATTR_WIDE;
3596 width = (term.line[term.c.y][curx].mode & ATTR_WIDE)\ 3597 xdrawglyph(g, term.c.x, term.c.y);
3597 ? 2 : 1;
3598 xdraws(g.c, g, term.c.x, term.c.y, width, sl);
3599 break; 3598 break;
3600 case 3: /* Blinking Underline */ 3599 case 3: /* Blinking Underline */
3601 case 4: /* Steady Underline */ 3600 case 4: /* Steady Underline */
@@ -3668,7 +3667,7 @@ draw(void) {
3668 3667
3669void 3668void
3670drawregion(int x1, int y1, int x2, int y2) { 3669drawregion(int x1, int y1, int x2, int y2) {
3671 int ic, ib, x, y, ox, sl; 3670 int ic, ib, x, y, ox;
3672 Glyph base, new; 3671 Glyph base, new;
3673 char buf[DRAW_BUF_SIZ]; 3672 char buf[DRAW_BUF_SIZ];
3674 bool ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN); 3673 bool ena_sel = sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN);
@@ -3700,9 +3699,7 @@ drawregion(int x1, int y1, int x2, int y2) {
3700 base = new; 3699 base = new;
3701 } 3700 }
3702 3701
3703 sl = utf8len(new.c); 3702 ib += utf8encode(new.u, buf+ib);
3704 memcpy(buf+ib, new.c, sl);
3705 ib += sl;
3706 ic += (new.mode & ATTR_WIDE)? 2 : 1; 3703 ic += (new.mode & ATTR_WIDE)? 2 : 1;
3707 } 3704 }
3708 if(ib > 0) 3705 if(ib > 0)