summaryrefslogtreecommitdiff
path: root/cell.c
diff options
context:
space:
mode:
Diffstat (limited to 'cell.c')
-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;
}