From 89fd3b76518cf3004053331c580a349afaaf2dab Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sun, 29 Oct 2006 08:07:51 +0000 Subject: major internal changes in representation of character cells. we now use 12 bytes per cell instead of 10. however, this allows us to support 256-color mode (not yet implemented but the framework is in place) and to mix scripts when using combining characters. while the latter sounds ridiculous at first, being able to visibly see a combining letter attached to a [, ", or ' is extremely useful in scripting and regular expressions with some languages. some code is left slightly messy, but overall it's much cleaner now since struct uucell is now properly encapsulated. --- Makefile | 2 +- comb.c | 198 -------------------------------------------------------------- dblbuf.c | 4 +- refresh.c | 19 +++--- term.c | 61 +++++++------------ uuterm.h | 28 +++++---- xlib.c | 4 +- 7 files changed, 52 insertions(+), 264 deletions(-) delete mode 100644 comb.c diff --git a/Makefile b/Makefile index 9dfc429..e3d3bb9 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # uuterm, Copyright (C) 2006 Rich Felker; licensed under GNU GPL v2 only -SRCS = main.c term.c comb.c decomp.c tty.c alloc.c refresh.c ascii.c ucf.c font_load.c +SRCS = main.c term.c cell.c decomp.c tty.c alloc.c refresh.c ascii.c ucf.c font_load.c OBJS_FB = fbcon.o dblbuf.o OBJS_X11 = xlib.o diff --git a/comb.c b/comb.c deleted file mode 100644 index 6bf7f7d..0000000 --- a/comb.c +++ /dev/null @@ -1,198 +0,0 @@ -/* uuterm, Copyright (C) 2006 Rich Felker; licensed under GNU GPL v2 only */ - -#define R(a,b) { (a), (b)-(a) } - -static const unsigned short common[][2] = { - R( 0x300, 0x341 ), - R( 0x346, 0x362 ), - R( 0x200B, 0x200F ), - R( 0x202A, 0x202E ), - R( 0x2060, 0x206F ), - R( 0x20D0, 0x20EA ), - { 0, 0 } -}; - -static const unsigned short latin[][2] = { - R( 0x363, 0x36F ), - { 0, 0 } -}; - -static const unsigned short greek[][2] = { - R( 0x342, 0x345 ), - { 0, 0 } -}; - -static const unsigned short cyrillic[][2] = { - R( 0x483, 0x489 ), - { 0, 0 } -}; - -static const unsigned short hebrew[][2] = { - R( 0x591, 0x5C4 ), - { 0, 0 } -}; - -static const unsigned short arabic[][2] = { - R( 0x600, 0x603 ), - R( 0x610, 0x615 ), - R( 0x64B, 0x658 ), - R( 0x670, 0x670 ), - R( 0x6D6, 0x6ED ), - { 0, 0 } -}; - -static const unsigned short syriac[][2] = { - R( 0x70F, 0x711 ), - R( 0x730, 0x74A ), - { 0, 0 } -}; - -static const unsigned short thaana[][2] = { - R( 0x7A6, 0x7B0 ), - { 0, 0 } -}; - -static const unsigned short devanagari[][2] = { - R( 0x901, 0x902 ), - R( 0x93C, 0x963 ), - { 0, 0 } -}; - -static const unsigned short bengali[][2] = { - R( 0x981, 0x981 ), - R( 0x9BC, 0x9E3 ), - { 0, 0 } -}; - -static const unsigned short gurmukhi[][2] = { - R( 0xA01, 0xA02 ), - R( 0xA3C, 0xA4D ), - R( 0xA70, 0xA71 ), - { 0, 0 } -}; - -static const unsigned short gujarati[][2] = { - R( 0xA81, 0xA82 ), - R( 0xABC, 0xAE3 ), - { 0, 0 } -}; - -static const unsigned short oriya[][2] = { - R( 0xB01, 0xB01 ), - R( 0xB3C, 0xB4D ), - R( 0xB56, 0xB56 ), - { 0, 0 } -}; - -static const unsigned short tamil[][2] = { - R( 0xB82, 0xB82 ), - R( 0xBC0, 0xBCD ), - { 0, 0 } -}; - -static const unsigned short telugu[][2] = { - R( 0xC3E, 0xC56 ), - { 0, 0 } -}; - -static const unsigned short kannada[][2] = { - R( 0xCBC, 0xCCD ), - { 0, 0 } -}; - -static const unsigned short malayalam[][2] = { - R( 0xD41, 0xD4D ), - { 0, 0 } -}; - -static const unsigned short sinhala[][2] = { - R( 0xDCA, 0xDD6 ), - { 0, 0 } -}; - -static const unsigned short thai[][2] = { - R( 0xE31, 0xE3A ), - R( 0xE47, 0xE4E ), - { 0, 0 } -}; - -static const unsigned short lao[][2] = { - R( 0xEB1, 0xECD ), - { 0, 0 } -}; - -static const unsigned short tibetan[][2] = { - R( 0xF18, 0xF19 ), - R( 0xF35, 0xF35 ), - R( 0xF39, 0xF39 ), - R( 0xF71, 0xF84 ), - R( 0xF90, 0xFBC ), - R( 0xFC6, 0xFC6 ), - { 0, 0 } -}; - -static const unsigned short burmese[][2] = { - R( 0x102D, 0x1039 ), - R( 0x1058, 0x1059 ), - { 0, 0 } -}; - -static const unsigned short misc_scripts[][2] = { - R( 0x1732, 0x1734 ), /* hanunoo */ - R( 0x1752, 0x1753 ), /* buhid */ - R( 0x17B4, 0x17BD ), /* khmer */ - R( 0x17C6, 0x17D3 ), - R( 0x17DD, 0x17DD ), - R( 0x18A9, 0x18A9 ), /* mongolian */ - R( 0x1920, 0x193B ), /* limbu (can be broken down more) */ - { 0, 0 } -}; - -#undef R -#define R(a,b,s) { (a), (b)-(a), (s) } - -static const struct { - unsigned a, l; - const unsigned short (*r)[2]; -} scripts[] = { - R( 0x400, 0x52F, cyrillic ), - R( 0x590, 0x5FF, hebrew ), - R( 0x600, 0x6FF, arabic ), - R( 0x700, 0x74F, syriac ), - R( 0x780, 0x7B1, thaana ), - R( 0x900, 0x97F, devanagari ), - R( 0x980, 0x9FF, bengali ), - R( 0xA00, 0xA7F, gurmukhi ), - R( 0xA80, 0xAFF, gujarati ), - R( 0xB00, 0xB7F, oriya ), - R( 0xB80, 0xBFF, tamil ), - R( 0xC00, 0xC7F, telugu ), - R( 0xC80, 0xCFF, kannada ), - R( 0xD00, 0xD7F, malayalam ), - R( 0xD80, 0xDFF, sinhala ), - R( 0xE00, 0xE7F, thai ), - R( 0xE80, 0xEFF, lao ), - R( 0xF00, 0xFFF, tibetan ), - R( 0x1000, 0x108F, burmese ), - R( 0x1720, 0x19FF, misc_scripts ), - R( 0x1D2B, 0x1D2B, cyrillic ), - R( 0x0000, 0x10FFFF, common ), - { } -}; - -#undef R - -int uu_combine_involution(unsigned b, unsigned c) -{ - int i; - unsigned code = 1; - const unsigned short (*r)[2]; - for (i=0; scripts[i].l; i++) - if (b - scripts[i].a <= scripts[i].l) - for (r = scripts[i].r; r[0][0]; code += r++[0][1]+1) - if (c - r[0][0] <= r[0][1]) - return c - r[0][0] + code; - else if (c - code <= r[0][1]) - return c + r[0][0] - code; - return 0; -} diff --git a/dblbuf.c b/dblbuf.c index 32ff996..18e2cd5 100644 --- a/dblbuf.c +++ b/dblbuf.c @@ -117,8 +117,8 @@ void uudisp_predraw_cell(struct uudisp *d, int idx, int x, int color) { struct dblbuf *b = (void *)&d->priv; - b->slices[idx].colors[2*x] = expand_color(d, color&15); - b->slices[idx].colors[2*x+1] = expand_color(d, color>>4) ^ b->slices[idx].colors[2*x]; + b->slices[idx].colors[2*x] = expand_color(d, color&255); + b->slices[idx].colors[2*x+1] = expand_color(d, color>>8) ^ b->slices[idx].colors[2*x]; } void uudisp_draw_glyph(struct uudisp *d, int idx, int x, const void *glyph) diff --git a/refresh.c b/refresh.c index 9e3ab57..06e6f69 100644 --- a/refresh.c +++ b/refresh.c @@ -7,16 +7,17 @@ static void extract_cell(unsigned *ch, size_t max, struct uucell *cell) { - int i, l; - unsigned b; - for (b=i=0; i<3; i++) b |= cell->c[i] << 8*i; - l = uu_decompose_char(b, ch, max); - ch += l; max -= l; - for (; ic) && cell->c[i]; i++) { - l = uu_decompose_char(uu_combine_involution(b, cell->c[i]), ch, max); + int i, j, l; + wchar_t ws[8]; + int attr = uucell_get_attr(cell); + + uucell_get_wcs(cell, ws, 8); + + for (i=j=0; ws[i]; i++) { + l = uu_decompose_char(ws[i], ch, max); ch += l; max -= l; } - if ((cell->a & UU_ATTR_UL) && max) + if ((attr & UU_ATTR_UL) && max) max--, *ch++ = '_'; //0x0332; for (; max; max--) *ch++ = 0; ch[-1] = 0; @@ -54,7 +55,7 @@ void uuterm_refresh_row(struct uudisp *d, struct uurow *row, int x1, int x2) } else { width = 1; part = 0; chp = ch[x&3]; } - uudisp_predraw_cell(d, row->idx, x, row->cells[x].a & 0xff); + uudisp_predraw_cell(d, row->idx, x, uucell_get_color(&row->cells[x])); for (i=0; ifont, i, chp, ch[(x+3)&3], ch[(x+1)&3], width, part); if (glyph) uudisp_draw_glyph(d, row->idx, x, glyph); diff --git a/term.c b/term.c index 83a7c42..1bfc4c7 100644 --- a/term.c +++ b/term.c @@ -61,7 +61,8 @@ static void reset(struct uuterm *t) { /* cheap trick */ memset(&t->reset, 0, sizeof *t - offsetof(struct uuterm, reset)); - t->attr = 7; + t->attr = 0; + t->color = 7; t->sr_y2 = t->h - 1; erase_display(t, 2); } @@ -198,19 +199,30 @@ static void csi(struct uuterm *t, unsigned c) if (t->param[i] == 39) t->param[i] = 37; if (t->param[i] == 49) t->param[i] = 40; if (!t->param[i]) { - t->attr = 7; + t->attr = 0; + t->color = 7; } else if (t->param[i] < 8) { t->attr |= attr[t->param[i]-1]; } else if (t->param[i]-21 < 7) { t->attr &= ~attr[t->param[i]-21]; } else if (t->param[i]-30 < 8) { - t->attr &= ~UU_ATTR_FG; - t->attr |= t->param[i] - 30; + t->color &= ~255; + t->color |= t->param[i] - 30; } else if (t->param[i]-40 < 8) { - t->attr &= ~UU_ATTR_BG; - t->attr |= t->param[i] - 40 << 4; + t->color &= ~(255<<8); + t->color |= t->param[i] - 40 << 8; } } + if ((t->color&255) < 16) + if (t->attr & UU_ATTR_BOLD) + t->color |= 8; + else + t->color &= ~8; + if ((t->color>>8) < 16) + if (t->attr & UU_ATTR_BLINK) + t->color |= 8<<8; + else + t->color &= ~(8<<8); break; case 'n': switch (t->param[0]) { @@ -328,38 +340,6 @@ static void escape(struct uuterm *t, unsigned c) } } -static void setchar(struct uucell *cell, unsigned c, unsigned a) -{ - int i; - if (a & UU_ATTR_REV) - cell->a = (a & ~(0xff)) - | ((a & 0x0f) << 4) - | ((a & 0xf0) >> 4); - else - cell->a = a; - for (i=0; ic); i++, c>>=8) - cell->c[i] = c; -} - -static void addchar(struct uucell *cell, unsigned c) -{ - int i; - unsigned b; - - for (i=b=0; i<3; i++) b |= cell->c[i] << 8*i; - if (b == 0 || b == ' ' || b == 0xa0) { - setchar(cell, c, cell->a); - return; - } - if (!(c = uu_combine_involution(b, c))) return; - for (; ic); i++) { - if (!cell->c[i]) { - cell->c[i] = c; - break; - } - } -} - static void process_char(struct uuterm *t, unsigned c) { int x, y, w; @@ -415,7 +395,7 @@ static void process_char(struct uuterm *t, unsigned c) x = 0; } - addchar(&t->rows[y]->cells[x], c); + uucell_append(&t->rows[y]->cells[x], c); dirty(t, y, x, 1); break; case 1: @@ -424,7 +404,8 @@ static void process_char(struct uuterm *t, unsigned c) while (w--) { if (t->am) newline(t); // kills am flag dirty(t, t->y, t->x, 1); - setchar(&t->rows[t->y]->cells[t->x++], w?UU_FULLWIDTH:c, t->attr); + uucell_set(&t->rows[t->y]->cells[t->x++], + w?UU_FULLWIDTH:c, t->attr, t->color); if (t->x == t->w) { t->x--; t->am=1; diff --git a/uuterm.h b/uuterm.h index 3ce390e..defe16f 100644 --- a/uuterm.h +++ b/uuterm.h @@ -1,12 +1,12 @@ /* uuterm, Copyright (C) 2006 Rich Felker; licensed under GNU GPL v2 only */ #include -#include /* for mbstate_t... */ +#include +#include struct uucell { - unsigned short a; - unsigned char c[8]; + uint32_t x[3]; }; struct uurow @@ -16,15 +16,13 @@ struct uurow struct uucell cells[1]; }; -#define UU_ATTR_DIM 0x0100 -#define UU_ATTR_UL 0x0200 -#define UU_ATTR_REV 0x0400 +/* Cell-preserved attributes must lie in 0xC000FC01, see cell.c */ -#define UU_ATTR_BOLD 0x0008 -#define UU_ATTR_FG 0x0007 - -#define UU_ATTR_BLINK 0x0080 -#define UU_ATTR_BG 0x0070 +#define UU_ATTR_UL 0x00000001 +#define UU_ATTR_BOLD 0x00000002 +#define UU_ATTR_BLINK 0x00000004 +#define UU_ATTR_DIM 0x00000008 +#define UU_ATTR_REV 0x00000010 struct uuterm { @@ -37,6 +35,7 @@ struct uuterm // output state int x, y; int attr; + int color; int sr_y1, sr_y2; int ins :1; int am :1; @@ -84,7 +83,12 @@ void uuterm_stuff_byte(struct uuterm *, unsigned char); void uuterm_refresh_row(struct uudisp *, struct uurow *, int, int); -int uu_combine_involution(unsigned, unsigned); +void uucell_set(struct uucell *, wchar_t, int, int); +void uucell_append(struct uucell *, wchar_t); +int uucell_get_attr(struct uucell *); +int uucell_get_color(struct uucell *); +int uucell_get_wcs(struct uucell *, wchar_t *, size_t); + int uu_decompose_char(unsigned, unsigned *, unsigned); int uudisp_open(struct uudisp *); diff --git a/xlib.c b/xlib.c index 99c7573..4dce890 100644 --- a/xlib.c +++ b/xlib.c @@ -361,8 +361,8 @@ void uudisp_predraw_cell(struct uudisp *d, int idx, int x, int color) commit_cells(d, idx); p->x1 = x; p->color = color; - XSetForeground(p->display, p->gc, p->colors[color&15]); - XSetBackground(p->display, p->gc, p->colors[color>>4]); + XSetForeground(p->display, p->gc, p->colors[color&255]); + XSetBackground(p->display, p->gc, p->colors[color>>8]); } p->x2 = x; -- cgit v1.2.3