summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2006-11-02 23:46:08 +0000
committerRich Felker <dalias@aerifal.cx>2006-11-02 23:46:08 +0000
commit191afaf695ae93c1cd3117c373aa1789f862e34f (patch)
tree837d5e404de7f28d3b5aff9fd4cf046e5d7e16b4
parent16b8febe8ef3b0ff65215fb64f81427e187524d2 (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.
-rw-r--r--cell.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/cell.c b/cell.c
index 101dce8..a56b660 100644
--- a/cell.c
+++ b/cell.c
@@ -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;
}