diff options
author | Rich Felker <dalias@aerifal.cx> | 2006-11-02 23:46:08 +0000 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2006-11-02 23:46:08 +0000 |
commit | 191afaf695ae93c1cd3117c373aa1789f862e34f (patch) | |
tree | 837d5e404de7f28d3b5aff9fd4cf046e5d7e16b4 /cell.c | |
parent | 16b8febe8ef3b0ff65215fb64f81427e187524d2 (diff) |
100l: i had omitted korean from combining table since it wasn't
flagged in the u**codedata file. special-casing it like this seems
more logical than adding a huge list of combing chars to the
already-large table but i may reconsider eventually.
Diffstat (limited to 'cell.c')
-rw-r--r-- | cell.c | 16 |
1 files changed, 14 insertions, 2 deletions
@@ -76,17 +76,29 @@ static const unsigned short comb[] = { 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; - for (a=0, n=(sizeof(comb)/sizeof(comb[0])+1)/2; n>1; n=n+1>>1) + 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]<c) a++; return comb[a]==c ? a+1 : 0; } +static wchar_t comb_dec(int c) +{ + if ((unsigned)c > 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 @@ -151,7 +163,7 @@ int uucell_get_wcs(struct uucell *cell, wchar_t *ws, size_t l) *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[c-1]; + if (c) c = comb_dec(c); if (!(*ws++ = c)) l = 1; } |