/* uuterm, Copyright (C) 2006 Rich Felker; licensed under GNU GPL v2 only */ #include #include "uuterm.h" static const unsigned short comb[] = { 0x300,0x301,0x302,0x303,0x304,0x305,0x306,0x307, 0x308,0x309,0x30A,0x30B,0x30C,0x30D,0x30E,0x30F, 0x310,0x311,0x312,0x313,0x314,0x315,0x316,0x317, 0x318,0x319,0x31A,0x31B,0x31C,0x31D,0x31E,0x31F, 0x320,0x321,0x322,0x323,0x324,0x325,0x326,0x327, 0x328,0x329,0x32A,0x32B,0x32C,0x32D,0x32E,0x32F, 0x330,0x331,0x332,0x333,0x334,0x335,0x336,0x337, 0x338,0x339,0x33A,0x33B,0x33C,0x33D,0x33E,0x33F, 0x340,0x341,0x342,0x343,0x344,0x345,0x346,0x347, 0x348,0x349,0x34A,0x34B,0x34C,0x34D,0x34E,0x34F, 0x350,0x351,0x352,0x353,0x354,0x355,0x356,0x357, 0x358,0x359,0x35A,0x35B,0x35C, 0x35D,0x35E,0x35F,0x360,0x361,0x362,0x363,0x364, 0x365,0x366,0x367,0x368,0x369,0x36A,0x36B,0x36C, 0x36D,0x36E,0x36F,0x483,0x484,0x485,0x486,0x488, 0x489,0x591,0x592,0x593,0x594,0x595,0x596,0x597, 0x598,0x599,0x59A,0x59B,0x59C,0x59D,0x59E,0x59F, 0x5A0,0x5A1,0x5A2,0x5A3,0x5A4,0x5A5,0x5A6,0x5A7,0x5A8, 0x5A9,0x5AA,0x5AB,0x5AC,0x5AD,0x5AE,0x5AF,0x5B0, 0x5B1,0x5B2,0x5B3,0x5B4,0x5B5,0x5B6,0x5B7,0x5B8, 0x5B9,0x5BA,0x5BB,0x5BC,0x5BD,0x5BF,0x5C1,0x5C2,0x5C4,0x5C5,0x5C7, 0x600,0x601,0x602,0x603,0x610,0x611,0x612,0x613, 0x614,0x615,0x64B,0x64C,0x64D,0x64E,0x64F,0x650, 0x651,0x652,0x653,0x654,0x655,0x656,0x657,0x658, 0x659,0x65A,0x65B,0x65C,0x65E, 0x670,0x6D6,0x6D7,0x6D8,0x6D9,0x6DA,0x6DB,0x6DC, 0x6DD,0x6DE,0x6DF,0x6E0,0x6E1,0x6E2,0x6E3,0x6E4, 0x6E7,0x6E8,0x6EA,0x6EB,0x6EC,0x6ED,0x70F,0x711, 0x730,0x731,0x732,0x733,0x734,0x735,0x736,0x737, 0x738,0x739,0x73A,0x73B,0x73C,0x73D,0x73E,0x73F, 0x740,0x741,0x742,0x743,0x744,0x745,0x746,0x747, 0x748,0x749,0x74A,0x7A6,0x7A7,0x7A8,0x7A9,0x7AA, 0x7AB,0x7AC,0x7AD,0x7AE,0x7AF,0x7B0,0x7EB,0x7EC, 0x7ED,0x7EE,0x7EF,0x7F0,0x7F1,0x7F2,0x7F3,0x901,0x902, 0x93C,0x941,0x942,0x943,0x944,0x945,0x946,0x947, 0x948,0x94D,0x951,0x952,0x953,0x954,0x962,0x963, 0x981,0x9BC,0x9C1,0x9C2,0x9C3,0x9C4,0x9CD,0x9E2, 0x9E3,0xA01,0xA02,0xA3C,0xA41,0xA42,0xA47,0xA48, 0xA4B,0xA4C,0xA4D,0xA70,0xA71,0xA81,0xA82,0xABC, 0xAC1,0xAC2,0xAC3,0xAC4,0xAC5,0xAC7,0xAC8,0xACD, 0xAE2,0xAE3,0xB01,0xB3C,0xB3F,0xB41,0xB42,0xB43, 0xB4D,0xB56,0xB82,0xBC0,0xBCD,0xBF8,0xC3E,0xC3F, 0xC40,0xC46,0xC47,0xC48,0xC4A,0xC4B,0xC4C,0xC4D, 0xC55,0xC56,0xCBC,0xCBF,0xCC6,0xCCC,0xCCD,0xCE2,0xCE3,0xD41, 0xD42,0xD43,0xD4D,0xDCA,0xDD2,0xDD3,0xDD4,0xDD6, 0xE31,0xE34,0xE35,0xE36,0xE37,0xE38,0xE39,0xE3A, 0xE47,0xE48,0xE49,0xE4A,0xE4B,0xE4C,0xE4D,0xE4E, 0xEB1,0xEB4,0xEB5,0xEB6,0xEB7,0xEB8,0xEB9,0xEBB, 0xEBC,0xEC8,0xEC9,0xECA,0xECB,0xECC,0xECD,0xF18, 0xF19,0xF35,0xF37,0xF39,0xF71,0xF72,0xF73,0xF74, 0xF75,0xF76,0xF77,0xF78,0xF79,0xF7A,0xF7B,0xF7C, 0xF7D,0xF7E,0xF80,0xF81,0xF82,0xF83,0xF84,0xF86, 0xF87,0xF90,0xF91,0xF92,0xF93,0xF94,0xF95,0xF96, 0xF97,0xF99,0xF9A,0xF9B,0xF9C,0xF9D,0xF9E,0xF9F, 0xFA0,0xFA1,0xFA2,0xFA3,0xFA4,0xFA5,0xFA6,0xFA7, 0xFA8,0xFA9,0xFAA,0xFAB,0xFAC,0xFAD,0xFAE,0xFAF, 0xFB0,0xFB1,0xFB2,0xFB3,0xFB4,0xFB5,0xFB6,0xFB7, 0xFB8,0xFB9,0xFBA,0xFBB,0xFBC,0xFC6,0x102D,0x102E, 0x102F,0x1030,0x1032,0x1036,0x1037,0x1039,0x1058,0x1059, 0x135F, 0x1712,0x1713,0x1714,0x1732,0x1733,0x1734,0x1752,0x1753, 0x1772,0x1773,0x17B4,0x17B5,0x17B7,0x17B8,0x17B9,0x17BA, 0x17BB,0x17BC,0x17BD,0x17C6,0x17C9,0x17CA,0x17CB,0x17CC, 0x17CD,0x17CE,0x17CF,0x17D0,0x17D1,0x17D2,0x17D3,0x17DD, 0x180B,0x180C,0x180D,0x18A9,0x1920,0x1921,0x1922,0x1927, 0x1928,0x1932,0x1939,0x193A,0x193B,0x1A17,0x1A18,0x1B00, 0x1B01,0x1B02,0x1B03,0x1B34,0x1B36,0x1B37,0x1B38,0x1B39, 0x1B3A,0x1B3C,0x1B42,0x1B6B,0x1B6C,0x1B6D,0x1B6E,0x1B6F, 0x1B70,0x1B71,0x1B72,0x1B73,0x1DC0,0x1DC1,0x1DC2,0x1DC3, 0x1DC4,0x1DC5,0x1DC6,0x1DC7,0x1DC8,0x1DC9,0x1DCA,0x1DFE,0x1DFF, 0x200B,0x200C,0x200D, 0x200E,0x200F,0x202A,0x202B,0x202C,0x202D,0x202E,0x2060, 0x2061,0x2062,0x2063,0x206A,0x206B,0x206C,0x206D,0x206E, 0x206F,0x20D0,0x20D1,0x20D2,0x20D3,0x20D4,0x20D5,0x20D6, 0x20D7,0x20D8,0x20D9,0x20DA,0x20DB,0x20DC,0x20DD,0x20DE, 0x20DF,0x20E0,0x20E1,0x20E2,0x20E3,0x20E4,0x20E5,0x20E6, 0x20E7,0x20E8,0x20E9,0x20EA,0x20EB,0x20EC,0x20ED,0x20EE, 0x20EF,0x302A,0x302B,0x302C,0x302D,0x302E,0x302F,0x3099, 0x309A,0xA805,0xA80B,0xA825,0xA826,0xFB1E,0xFE20,0xFE21, 0xFE22,0xFE23,0xFEFF, }; #define COMB_CNT (sizeof(comb)/sizeof(comb[0])) static int comb_enc(wchar_t c) { int a, n; if (c > 0xffff) return 0; if ((unsigned)c - 0x1160 < 0xa0) return COMB_CNT + 1 + c - 0x1160; for (a=0, n=(COMB_CNT+1)/2; n>1; n=n+1>>1) a += n & ((signed)(comb[a+n]-c-1) >> 21); if (comb[a] COMB_CNT) return c - COMB_CNT - 1 + 0x1160; else if (c) return comb[c-1]; else return 0; } #define BASE_BIT 11 #define COLOR_BIT 16 #define COMB_MASK 0x3ff #define MAX_COMB 5 static const int comb_idx[] = { 0, 1, 1, 1, 2 }; static const int comb_bit[] = { 1, 0, 10, 20, 0 }; /* ** Bit layout (B=base char, #=combining chars, C=color, A=attr ** 0: BBBBBBBBBBBBBBBBBBBBB0000000000A ** 1: AA333333333322222222221111111111 ** 2: CCCCCCCCCCCCCCCCAAAAAA4444444444 ** Attribute bits have been placed not to overlap. The attribute ** bits defined in uuterm.h must come from available positions. */ #define ATTR_MASK0 0x00000001 #define ATTR_MASK1 0 /* 0xC0000000 */ #define ATTR_MASK2 0 /* 0x0000FC00 */ void uucell_set(struct uucell *cell, wchar_t wc, int attr, int color) { if (attr & UU_ATTR_REV) { int tmp = color & 255; color >>= 8; color |= tmp << 8; } cell->x[0] = (attr & ATTR_MASK0) | (wc << BASE_BIT); cell->x[1] = (attr & ATTR_MASK1); cell->x[2] = (attr & ATTR_MASK2) | (color << COLOR_BIT); } void uucell_append(struct uucell *cell, wchar_t wc) { int i; for (i=0; ix[comb_idx[i]]>>comb_bit[i]) & COMB_MASK)) { cell->x[comb_idx[i]] |= comb_enc(wc)<x[0] & ATTR_MASK0) | (cell->x[1] & ATTR_MASK1) | (cell->x[2] & ATTR_MASK2); } int uucell_get_color(struct uucell *cell) { return cell->x[2] >> COLOR_BIT; } int uucell_get_wcs(struct uucell *cell, wchar_t *ws, size_t l) { int i, c; if (!l--) return 0; *ws++ = cell->x[0] >> BASE_BIT; for (i=0; l; i++,l--) { c = (cell->x[comb_idx[i]]>>comb_bit[i]) & COMB_MASK; if (c) c = comb_dec(c); if (!(*ws++ = c)) l = 1; } ws[-1] = 0; return i; }