Как добавить поддержку UTF-8 и связанную таблицу шрифтов во встроенный проект? - PullRequest
1 голос
/ 19 марта 2009

В настоящее время я разрабатываю движок шрифтов для встроенного дисплея. Основная проблема заключается в следующем:

Мне нужно взять динамически сгенерированную текстовую строку, найти значения из этой строки в таблице UTF-8, а затем использовать таблицу, чтобы указать на сжатый массив растровых изображений всех поддерживаемых символов. После этого я вызываю подпрограмму bitcopy, которая перемещает данные из массива растровых изображений на дисплей.

Я не буду поддерживать полный набор символов UTF-8, так как у меня очень ограниченные системные ресурсы для работы (32K ROM, 8K RAM), но я хочу иметь возможность добавлять необходимые глифы позже для целей локализации , Все разработки ведутся на С и сборке.

Максимальный размер символа составляет 16 бит в ширину и 16 бит в высоту. Возможно, нам потребуется поддержка всей базовой многоязычной плоскости (3 байта), поскольку некоторые из наших крупных клиентов находятся в Азии. Однако мы не будем включать всю таблицу в какую-либо конкретную локализацию.

Мой вопрос такой:
Каков наилучший способ добавить эту поддержку UTF-8 и связанную таблицу?

Ответы [ 2 ]

1 голос
/ 20 марта 2009

В приведенном ниже решении предполагается, что для вас будет достаточно младших 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.

0 голосов
/ 20 марта 2009

Вы не указали размер своих символов или размер набора символов, поэтому сложно оценить требования к размеру.

Я бы сохранял растровые изображения в формате прямого массива, в зависимости от размера символов, он может храниться достаточно эффективно без необходимости упаковывать / распаковывать элементы.

Например, если мы возьмем алфавит из 36 символов с символом 8x6, вам потребуется 216 байт памяти для массива. (6 байт / символ * 36 - каждый байт будет вертикальным срезом символа).

Для анализа это просто вопрос смещения в таблице.
Старые трюки (char - 'A') и (char - '0') работают хорошо.

Другой вопрос - где хранить массив растровых изображений? В ROM это очевидный ответ, но если вам нужно поддерживать другие глифы, возможно, потребуется перепрограммирование, которое не указывается, если это проблема.

Если глифы должны программироваться динамически, то у вас нет выбора, кроме как поместить их в ОЗУ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...