В приведенном ниже решении предполагается, что для вас будет достаточно младших 16 бит пространства Юникода. Если ваша растровая таблица имеет, скажем, U + 0020 - U + 007E в позициях от 0x00 до 0x5E и U + 00A0 - U + 00FF в позициях от 0x5F до 0xBE и от U + 1200 до U + 1241 от 0xBF до 0xFF, вы можете сделать что-то вроде код ниже (который не проверен, даже не проверен на компиляцию).
растровое изображение содержит серию пар значений. Первое значение в первой паре - это кодовая точка Unicode, которую представляет битовая карта с индексом 0. Предполагается, что таблица растровых изображений содержит ряд непосредственно смежных кодовых точек Unicode. Второе значение говорит о том, как долго эта серия.
Первая часть цикла while перебирает ввод UTF-8 и создает кодовую точку Unicode в ucs2char. Как только полный символ найден, вторая часть ищет этот символ в одном из диапазонов, упомянутых в растровом изображении. Если он находит соответствующий растровый индекс, он добавляет его в индексы. Символы, для которых нет растрового изображения, автоматически отбрасываются.
Функция возвращает количество найденных растровых индексов.
Этот способ работы должен быть эффективным с точки зрения памяти с точки зрения таблицы unicode-> bitmap, достаточно быстрым и достаточно гибким.
// Code below assumes C99, but is about three cut-and-pastes from C89
// Assuming an unsigned short is 16-bit
unsigned short bitmapmap[]={0x0020, 0x005E,
0x00A0, 0x0060,
0x1200, 0x0041,
0x0000};
int utf8_to_bitmap_indexes(unsigned char *utf8, unsigned short *indexes)
{
int bitmapsfound=0;
int utf8numchars;
unsigned char c;
unsigned short ucs2char;
while (*utf8)
{
c=*utf8;
if (c>=0xc0)
{
utf8numchars=0;
while (c&0x80)
{
utf8numchars++;
c<<=1;
}
c>>=utf8numchars;
ucs2char=0;
}
else if (utf8numchars && c<0x80)
{
// This is invalid UTF-8. Do our best.
utf8numchars=0;
}
if (utf8numchars)
{
c&=0x3f;
ucs2char<<=6;
ucs2char+=c;
utf8numchars--;
if (utf8numchars)
continue; // Our work here is done - no char yet
}
else
ucs2char=c;
// At this point, we have a complete UCS-2 char in ucs2char
unsigned short bmpsearch=0;
unsigned short bmpix=0;
while (bitmapmap[bmpsearch])
{
if (ucs2char>=bitmapmap[bmpsearch] && ucs2char<=bitmapmap[bmpsearch]+bitmapmap[bmpsearch+1])
{
*indexes++ = bmpix+(ucs2char-bitmapmap[bmpsearch]);
bitmapsfound++;
break;
}
bmpix+=bitmapmap[bmpsearch+1];
bmpsearch+=2;
}
}
return bitmapsfound;
}
РЕДАКТИРОВАТЬ: Вы упомянули, что вам нужно больше, чем младшие 16 бит. s / unsigned short / unsigned int /; s / ucs2char / codepoint /; в приведенном выше коде, и тогда он может сделать все пространство Unicode.