diff options
author | Rich Felker <dalias@aerifal.cx> | 2006-10-29 08:07:51 +0000 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2006-10-29 08:07:51 +0000 |
commit | 89fd3b76518cf3004053331c580a349afaaf2dab (patch) | |
tree | 61897409524c883266942c744ca58df69eb3970b | |
parent | b97a486c34c343ab18bf16aef507478992af0625 (diff) |
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.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | comb.c | 198 | ||||
-rw-r--r-- | dblbuf.c | 4 | ||||
-rw-r--r-- | refresh.c | 19 | ||||
-rw-r--r-- | term.c | 61 | ||||
-rw-r--r-- | uuterm.h | 28 | ||||
-rw-r--r-- | xlib.c | 4 |
7 files changed, 52 insertions, 264 deletions
@@ -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 @@ -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; -} @@ -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) @@ -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 (; i<sizeof(cell->c) && 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; i<sizeof(ch[0]) && chp[i]; i++) { const void *glyph = lookup_glyph(d->font, i, chp, ch[(x+3)&3], ch[(x+1)&3], width, part); if (glyph) uudisp_draw_glyph(d, row->idx, x, glyph); @@ -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; i<sizeof(cell->c); 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 (; i<sizeof(cell->c); 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; @@ -1,12 +1,12 @@ /* uuterm, Copyright (C) 2006 Rich Felker; licensed under GNU GPL v2 only */ #include <stddef.h> -#include <wchar.h> /* for mbstate_t... */ +#include <stdint.h> +#include <wchar.h> 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 *); @@ -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; |