Русифицируем LCD экранчик 128х64, точнее библиотеку GLCD

Многие экспериментирующие с *duino сталкиваются с графическими монохромными LCD экранчиками на контроллерах ks0107/ks0108. Благо для их поддержки имеются несколько версий только официальной библиотеки.
Библиотечку можно взять здесь:
code.google.com/p/glcd-arduino/downloads/list
Вопросы подключения экранчика к контроллеру я рассматривать не буду, примеры есть и на этом сайте и на просторах интернета желающий найдет без труда. Кроме того, достаточно подробно расписано в документации к библиотеке.
Засада кроется в том, что без телодвижений, напряжения серого вещества русский текст из скетча ардуино никакими судьбами не выведешь. Ну нет в составе библиотеки русских шрифтов и все! Правда прилагается на страничке скачивания программулина для изобретения своих шрифтов и конвертации виндовых.
Ну во-первых, написана она на JAVA, следовательно запустить ее тоже надо суметь, а во-вторых ну никак она у меня не захотела находить русские буквы в виндовых шрифтах, кракозябры и все!!! :)
Лень, она конечно сильна, слов нет. Поэтому яндексу и гуглу были скормлены пара десятков запросов на различные вариации ключевых слов «русский шрифт GLCD». Ничего вразумительного, а тем более готового файла не нашлось. Может конечно не так искал…
Ну да ладно, делать нечего, пришлось напрягать пресловутое вещество.
Оговорюсь сразу: В данной заметке я рассмотрю создание (а точнее — модификацию) шрифта содержащего символы фиксированной ширины. Если тема кого заинтересует можно будет подобраться и к шрифту с символами переменной ширины.
Итак поехали!
Скачиваем и распаковываем библиотеку. Файлы с описанием шрифтов лежат в папочке «fonts». Открываем самый мелкий SystemFont5x7.h и пытаемся сделать ему трепанацию. Нас интересует какие параметры описывает этот файл, т.е. структура описания шрифта.
/*
 *
 * System5x7
 *
 Ну информация в комментах читаем!
 * 
 * File Name           : System5x7.h  - это понятно!
 * Date                : 28 Oct 2008 - не интересно!!!
 * Font size in bytes  : 470  - поменяется!!
 * Font width          : 5 - вот первое важное - ширина символа
 * Font height         : 7 - его высота
 * Font first char     : 32 - хм.... это у нас код первого символа шрифта
                               (ASCII - пробел)
 * Font last char      : 127 - код последнего символа шрифта
 * Font used chars     : 94 - количество запользованных символов
 *
 * The font data are defined as  - опачки! описание структуры шрифта, разгребаем!!!
 *
 * struct _FONT_ {
 *     uint16_t   font_Size_in_Bytes_over_all_included_Size_it_self; -
ни что иное как размер шрифта в байтах включая все размеры самого себя (вроде тафтология
но выясняется что файл описания может содержать несколько размеров символов 
или я чегой-то не так понял)

 *     uint8_t    font_Width_in_Pixel_for_fixed_drawing; -
ширина шрифта в пикселах для фиксированной отрисовки (не, но вот тут как-то не ясно,
 а как же шрифты с переменным размером?)

 *     uint8_t    font_Height_in_Pixel_for_all_characters; -
высота шрифта для всех символов (я так понимаю наибольшая)

 *     unit8_t    font_First_Char; -
код первого символа

 *     uint8_t    font_Char_Count;
количество символов (где-то это мы уже видели)

 *
 *     uint8_t    font_Char_Widths[font_Last_Char - font_First_Char +1];
 *                  // for each character the separate width in pixels,
 *                  // characters < 128 have an implicit virtual right empty row -
если переводить буквально то диапазон ширины символов ширина_последнего - ширина_первого + 1
добавляем межсимвольный интервал - виртуальный правый пустой столбец.

 *
 *     uint8_t    font_data[];
 *                  // bit field of all characters -
описание символов в виде битовой маски.

 */

#include <inttypes.h>
#include <avr/pgmspace.h>

#ifndef SYSTEM5x7_H
#define SYSTEM5x7_H

#define SYSTEM5x7_WIDTH 5
#define SYSTEM5x7_HEIGHT 7

/*
 * added to allow fontname to match header file name. 
 * as well as keep the old name for backward compability
 */

#define SystemFont5x7 System5x7

static uint8_t System5x7[] PROGMEM = {
    0x0, 0x0, // size of zero indicates fixed width font, actual length is width * height -
нули здесь говорят о том что мы имеем шрифт фиксированного размера!!

    0x05, // width  -5 на
    0x07, // height -7 пикселей
    0x20, // first char    -HEX-код первого символа
    0x60, // char count    -количество буков в HEX!
    
    // Fixed width; char width table not used !!!!
АГА!!!! здесь должна располагаться таблица ширин символов отличающихся от базового размера
у нас в данном случае таких нет!
    
    // font data
    0x00, 0x00, 0x00, 0x00, 0x00,// (space) - пошло описалово в HEX-формате.

Ну вроде все достаточно ясно для практического использования:

размер символов строго 5х7 точек, межсимвольный интервал добавляется автоматом, последний использованный код 0x20+0x60 — 1 = 0x7F. Начиня с 0x80 можно куролесить свои битовые маски.

Конечно, желающие могут взять тетрадку в клеточку, карандашик, разметить знакоместа 5 на 7 клеточек, закрасить соответствующие и перевести в начале в бинарный код а потом в HEX. Круто!!!
:) Только для начала надо интерпретировать по клеточкам коды символа 0х41, чтобы разобраться как библиотека отрисовывает символ по вертикали или по горизонтали.
Я воспользовался для этой цели найденной на просторе интернета программой, могущей пригодиться не только при изобретении шрифтов но и для других работ с нашим экранчиком. (можно взять здесь: ikarab.narod.ru/KS0108.html ) В ней есть преобразование «код — картинка» можно проверить символ 0х41 и получить «A». Соответственно, закрашивая попиксельно знакоместа — получаем строчку HEX-кодов символов.
Ну что ж, рисуем:

        0x7e, 0x11, 0x11, 0x11, 0x7e,//A	0x80	
	0x7f, 0x49, 0x49, 0x49, 0x33,//Б	0x81	
	0x7f, 0x49, 0x49, 0x49, 0x36,//В	0x82	
	0x7f, 0x01, 0x01, 0x01, 0x03,//Г	0x83	
	0xe0, 0x51, 0x4f, 0x41, 0xff,//Д	0x84	
	0x7f, 0x49, 0x49, 0x49, 0x41,//E	0x85	
	0x77, 0x08, 0x7f, 0x08, 0x77,//Ж	0x86	
	0x41, 0x49, 0x49, 0x49, 0x36,//З	0x87	
	0x7f, 0x10, 0x08, 0x04, 0x7f,//И	0x88	
	0x7c, 0x21, 0x12, 0x09, 0x7c,//Й	0x89	
	0x7f, 0x08, 0x14, 0x22, 0x41,//K	0x8A	
	0x20, 0x41, 0x3f, 0x01, 0x7f,//Л	0x8B	
	0x7f, 0x02, 0x0c, 0x02, 0x7f,//M	0x8C	
	0x7f, 0x08, 0x08, 0x08, 0x7f,//H	0x8D	
	0x3e, 0x41, 0x41, 0x41, 0x3e,//O	0x8E	
	0x7f, 0x01, 0x01, 0x01, 0x7f,//П	0x8F	
	0x7f, 0x09, 0x09, 0x09, 0x06,//P	0x90	
	0x3e, 0x41, 0x41, 0x41, 0x22,//C	0x91
	0x01, 0x01, 0x7f, 0x01, 0x01,//T	0x92
	0x47, 0x28, 0x10, 0x08, 0x07,//У	0x93
	0x1c, 0x22, 0x7f, 0x22, 0x1c,//Ф	0x94
	0x63, 0x14, 0x08, 0x14, 0x63,//X	0x95
	0x7f, 0x40, 0x40, 0x40, 0xff,//Ц	0x96
	0x07, 0x08, 0x08, 0x08, 0x7f,//Ч	0x97
	0x7f, 0x40, 0x7f, 0x40, 0x7f,//Ш	0x98
	0x7f, 0x40, 0x7f, 0x40, 0xff,//Щ	0x99
	0x01, 0x7f, 0x48, 0x48, 0x30,//Ъ	0x9A
	0x7f, 0x48, 0x30, 0x00, 0x7f,//Ы	0x9B
	0x00, 0x7f, 0x48, 0x48, 0x30,//Э	0x9C
	0x22, 0x41, 0x49, 0x49, 0x3e,//Ь	0x9D
	0x7f, 0x08, 0x3e, 0x41, 0x3e,//Ю	0x9E
	0x46, 0x29, 0x19, 0x09, 0x7f,//Я	0x9F
// маленькие буквы
 	0x20, 0x54, 0x54, 0x54, 0x78,//a	0xA0
	0x3c, 0x4a, 0x4a, 0x49, 0x31,//б	0xA1
	0x7c, 0x54, 0x54, 0x28, 0x00,//в	0xA2
	0x7c, 0x04, 0x04, 0x04, 0x0c,//г	0xA3
	0xe0, 0x54, 0x4c, 0x44, 0xfc,//д	0xA4
	0x38, 0x54, 0x54, 0x54, 0x18,//e	0xA5
	0x6c, 0x10, 0x7c, 0x10, 0x6c,//ж	0xA6
	0x44, 0x44, 0x54, 0x54, 0x28,//з	0xA7
	0x7c, 0x20, 0x10, 0x08, 0x7c,//и	0xA8
	0x7c, 0x41, 0x22, 0x11, 0x7c,//й	0xA9
	0x7c, 0x10, 0x28, 0x44, 0x00,//к	0xAA
	0x20, 0x44, 0x3c, 0x04, 0x7c,//л	0xAB
	0x7c, 0x08, 0x10, 0x08, 0x7c,//м	0xAC
	0x7c, 0x10, 0x10, 0x10, 0x7c,//н	0xAD
	0x38, 0x44, 0x44, 0x44, 0x38,//o	0xAE
	0x7c, 0x04, 0x04, 0x04, 0x7c,//п	0xAF
	0x7C, 0x14, 0x14, 0x14, 0x08,//p 	0xB0
	0x38, 0x44, 0x44, 0x44, 0x20,//c	0xB1
	0x04, 0x04, 0x7c, 0x04, 0x04,//т	0xB2
	0x0C, 0x50, 0x50, 0x50, 0x3C,//у	0xB3
	0x30, 0x48, 0xfc, 0x48, 0x30,//ф	0xB4
	0x44, 0x28, 0x10, 0x28, 0x44,//x	0xB5
	0x7c, 0x40, 0x40, 0x40, 0xfc,//ц	0xB6
	0x0c, 0x10, 0x10, 0x10, 0x7c,//ч	0xB7
	0x7c, 0x40, 0x7c, 0x40, 0x7c,//ш	0xB8
	0x7c, 0x40, 0x7c, 0x40, 0xfc,//щ	0xB9
	0x04, 0x7c, 0x50, 0x50, 0x20,//ъ	0xBA
	0x7c, 0x50, 0x50, 0x20, 0x7c,//ы	0xBB
	0x7c, 0x50, 0x50, 0x20, 0x00,//ь	0xBC
	0x28, 0x44, 0x54, 0x54, 0x38,//э	0xBD
	0x7c, 0x10, 0x38, 0x44, 0x38,//ю	0xBE
	0x08, 0x54, 0x34, 0x14, 0x7c //я	0xBF


Ну вот, самая трудоемкая часть работы позади… Не притомились?
Идем дальше…

Казалось бы, добавляем наш двоичный массив в хвост шрифта, корректируем заголовок и вот оно — счастье! Не тут-то было!
Меня осенила здравая идея — проверить в какой кодировке работает Arduino IDE. Для этого был спешно набросан кусочек кода:

#include <glcd.h>
#include "fonts/SystemFont5x7.h"

char myString[] = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя";

void setup ()
{
  GLCD.Init();
  GLCD.SelectFont(System5x7,BLACK);
}



void loop()
{
  byte i=0;
  while (i<120)
   {
     GLCD.print(myString[i]);
     GLCD.print(" == ");
     GLCD.print(myString[i],HEX);
     GLCD.println();
     delay(100);
     i++;
   }
  GLCD.println();
  GLCD.println(myString);
 delay(5000);
}

Выяснилось — работаем в UTF-8. Берем таблицу кодировки и получается что:
диапазону 0x80 — 0x8F соответствуют маленькие буквы от «р» до «я»
с 0x90 и до 0xAF идут заглавные по порядку «А» — «Я» исключая «Ё»
и в хвосте с 0xB0 до 0xBF маленькие от «а» до «п». Корректируем наш сотворенный битовый массив согласно кодировке и добавляем в хвост h-файла. Не забываем поправить служебные поля в начале.
Вуаля!

Ну и бонусом для тех кто дочитал до сего места ссылка на готовый файл шрифта:
Брать здесь: narod.ru/disk/47094865001.37fe25fb0ce3344acb820deb206144db/SystemRus5x7.h.html
  • +3
  • 24 апреля 2012, 10:50
  • SkyFort

Комментарии (1)

RSS свернуть / развернуть
+
0
Вот только шрифт на проверку оказался 5x7, что всплывает при попытке использования букв с «хвостами» типа «Д».
avatar

Artyoum

  • 2 сентября 2014, 08:52

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.