diff options
author | noname@inventati.org <noname@inventati.org> | 2015-04-21 23:29:01 +0200 |
---|---|---|
committer | Roberto E. Vargas Caballero <k0ga@shike2.com> | 2015-04-27 09:50:01 +0200 |
commit | 21f765426c36991edd8b14f4989d66187e9ff597 (patch) | |
tree | aef90464411dc59c362fd9278784ef0a2e4bce2b | |
parent | 753fe862b14c7dd4b0449ab2c3bf22ecbb10030e (diff) | |
download | st-patched-21f765426c36991edd8b14f4989d66187e9ff597.tar.bz2 st-patched-21f765426c36991edd8b14f4989d66187e9ff597.tar.xz st-patched-21f765426c36991edd8b14f4989d66187e9ff597.zip |
Change internal character representation.
-rw-r--r-- | st.c | 73 |
1 files changed, 35 insertions, 38 deletions
@@ -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; | |||
180 | typedef XftColor Color; | 181 | typedef XftColor Color; |
181 | 182 | ||
182 | typedef struct { | 183 | typedef 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 | ||
411 | static inline ushort sixd_to_16bit(int); | 412 | static inline ushort sixd_to_16bit(int); |
412 | static void xdraws(char *, Glyph, int, int, int, int); | 413 | static void xdraws(char *, Glyph, int, int, int, int); |
414 | static void xdrawglyph(Glyph, int, int); | ||
413 | static void xhints(void); | 415 | static void xhints(void); |
414 | static void xclear(int, int, int, int); | 416 | static void xclear(int, int, int, int); |
415 | static void xdrawcursor(void); | 417 | static void xdrawcursor(void); |
@@ -461,7 +463,6 @@ static size_t utf8decode(char *, long *, size_t); | |||
461 | static long utf8decodebyte(char, size_t *); | 463 | static long utf8decodebyte(char, size_t *); |
462 | static size_t utf8encode(long, char *); | 464 | static size_t utf8encode(long, char *); |
463 | static char utf8encodebyte(long, size_t); | 465 | static char utf8encodebyte(long, size_t); |
464 | static size_t utf8len(char *); | ||
465 | static size_t utf8validate(long *, size_t); | 466 | static size_t utf8validate(long *, size_t); |
466 | 467 | ||
467 | static ssize_t xwrite(int, const char *, size_t); | 468 | static ssize_t xwrite(int, const char *, size_t); |
@@ -630,11 +631,6 @@ utf8encodebyte(long u, size_t i) { | |||
630 | } | 631 | } |
631 | 632 | ||
632 | size_t | 633 | size_t |
633 | utf8len(char *c) { | ||
634 | return utf8decode(c, &(long){0}, UTF_SIZ); | ||
635 | } | ||
636 | |||
637 | size_t | ||
638 | utf8validate(long *u, size_t i) { | 634 | utf8validate(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) { | |||
936 | char * | 932 | char * |
937 | getsel(void) { | 933 | getsel(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 | ||
1659 | void | 1653 | void |
@@ -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 | ||
2401 | void | 2395 | void |
2402 | tdumpline(int n) { | 2396 | tdumpline(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 | ||
3555 | void | 3550 | void |
3551 | xdrawglyph(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 | |||
3559 | void | ||
3556 | xdrawcursor(void) { | 3560 | xdrawcursor(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 | ||
3669 | void | 3668 | void |
3670 | drawregion(int x1, int y1, int x2, int y2) { | 3669 | drawregion(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) |