пятница, 25 октября 2013 г.

Русификация библиотеки UTFT - часть 2: BigFont

Ранее мы уже писали о том, как русифицировать библиотеку UTFT и показали, как относительно несложно можно добавить поддержку кириллицы и дополнили шрифт SmallFont недостающими символами.

Сегодня мы дополним и шрифт BigFont кириллическими буквами.

Не будем повторяться, более крупный шрифт построен по тем же правилам, что и маленький. Отличие только в том, что один символ кодируется 32 байтами. 
Размер символа: 16х16 точек.

Первая пара байт - описывает первую строчку в знакоместе, вторая - вторую и т.д.

Снова наш основной инструмент: Microsoft Excel - с его помощью подготовим файл, который позволит в визуальном режиме создавать символы "попиксельно" и сразу выдавать строчку с кодом, который мы будем добавлять в файл DefaultFonts.c

После получения такого удобного инструмента можно просто (правда, долго и кропотливо) создать собственные символы. 

Для удобства использования в BigFont добавлены те же символы и в том же порядке, что и в SmallFont, что позволяет использовать этот шрифт точно так же. 

Т.е. если раньше код:
myGLCD.setFont(SmallFont);
myGLCD.print("\x97""o""\x99""a", x, y);
выводил на экране слово "вода" маленьким ширифтом, то код:
myGLCD.setFont(BigFont);
myGLCD.print("\x97""o""\x99""a", x, y);
выведет то же слово, но большим шрифтом.

Архив со всеми необходимыми файлами (DefaultFonts.c, экселевый файл и тестовый скетч) доступны по ссылке.

2 комментария:

  1. Можно сделать перекодировку "на лету", это будет чуток отжирать время МК, но зато строки пишем на русском и без неудобств(кроме использования strlen, она будет врать). Как-то так(функция заточена на порядок букв как в ваших шрифтах):

    uint8_t utf8_rus_charmap[] PROGMEM= {
    'A', //A 0
    128, //Б 1
    'B', //В 2
    129, //Г 3
    130, //Д 4
    'E', //Е 5
    131, //Ё 6
    132, //Ж 7
    133, //З
    134, //И
    135, //Й 10
    'K', //К
    136, //Л
    'M', //М
    'H', //Н
    'O', // 15
    137, //П
    'P', //
    'C', //
    'T', //
    138, //У 20
    139, //Ф
    'X', //
    140, //Ц
    141, //Ч
    142, //Ш 25
    143, //Щ
    144, //Ъ
    145, //Ы
    146, //Ь
    147, //Э 30
    148, //Ю
    149, //Я 32
    //small letters
    'a', // 33
    150, //б
    151, //в 35
    152, //г
    153, //д
    'e',
    154, //ё
    155, //ж 40
    156, //з
    157, //и
    158, //й
    159, //к
    160, //л 45
    161, //м
    162, //н
    'o', //
    163, //п
    'p', //р 50
    'c', //c 51
    164, //т
    'y',
    165, //ф
    'x', // 55
    166, //ц
    167, //ч
    168, //ш
    169, //щ
    170, //ъ 60
    171, //ы
    172, //ь
    173, //э
    174, //ю
    175 //я 65
    };
    size_t mb_strlen(const char* str)
    {
    size_t length = 0;
    uint8_t*ptr = (uint8_t*)str;
    while (*ptr) {
    if ( !(*ptr == 0xD1 || *ptr == 0xD0) ) {
    ++length;
    }
    ++ptr;
    }
    return length;
    }

    char* utf8_to_utft_encoding(char*st)
    {
    uint8_t utf_high_byte = 0;
    uint8_t ch, ch_pos = 0, stl = mb_strlen(st);

    char*result = (char*)malloc(stl + 1), *pr = result;
    for (int i = 0; i < strlen(st); ++i) {
    ch = st[i];
    if ( ch >= 128) {
    if ( utf_high_byte == 0 && (ch ==0xD0 || ch == 0xD1)) {
    utf_high_byte = ch;
    continue;
    } else {
    if ( utf_high_byte == 0xD0) {
    if (ch == 0x81) { //Ё
    ch = 6;
    } else {
    if(ch <= 0x95) {
    ch -= 0x90;
    } else if( ch < 0xB6){
    ch -= (0x90 - 1);
    } else {
    ch -= (0x90 - 2);
    }
    }
    ch = pgm_read_byte(utf8_rus_charmap + ch);
    } else if (utf_high_byte == 0xD1) {
    if (ch == 0x91) {//ё
    ch = 39;
    } else {
    ch -= 0x80;
    ch += 50;
    }
    ch = pgm_read_byte(utf8_rus_charmap + ch);
    }
    utf_high_byte = 0;
    }
    } else {
    utf_high_byte = 0;
    }
    *pr++ = ch;
    }//for i

    *pr = 0;
    return result;
    }
    использование:
    char*str = "Привет, мир!";
    char*str_encoded = utf8_to_utft_encoding(str);
    tft->print(str_encoded, 20, 20);

    ОтветитьУдалить
  2. а как добавить эту функциию в библиотеку? чтобы сразу писать myGLCD.print("Привет", x, y);

    ОтветитьУдалить