Как делать шрифты для устройств на микроконтроллерах Печать
Добавил(а) microsin   

В статье рассмотрены методы изготовления простых растровых шрифтов, предназначенных для вывода на графические индикаторы (как, например, WG240128A-FFH-V или экран от NOKIA6610 - Epson S1D15G00).

Если коротко, то основные известные мне методы такие:
    1. Воспользоваться программой BitFontCreator Pro 2.3. Позволяет делать растровые шрифты из шрифтов, встроенных в Windows.
    2. Нарисовать символы в графическом редакторе в виде bmp-картинок и потом конвертнуть их в C-дамп или ASM-дамп (чтобы подсунуть компилятору).

[BitFontCreator Pro 2.3]

Программа интуитивно-понятна, позволяет импортировать TrueType и растровые шрифты Windows, преобразовывать их в ASM- или C-дамп, экспортировать шрифт в набор BMP-картинок. Процесс создания шрифта предполагает 5 стандартных шагов (представлены в меню кнопками) - import font (тут выбираете Windows-шрифт), edit characters table (редактируете таблицу символов и изображения символов - если это нужно), configure data format (изменяете метод, каким графическая информация распределяется по байтам знакогенератора), export bitmap data (получаете текстовый дамп знакогенератора, который можно подсунуть компилятору). Несколько замечаний по использованию программы:

1. Если программа нелицензионная, то Вас ожидают определенные неудобства - половина символов из шрифта представлена пустым дампом. Поэтому чтобы сгенерировать дампы для всех символов в таблице, приходится извращаться - делать дампы символов по частям, удалять из таблицы символов те, чей дамп Вы уже получили. При этом "пустоты" в таблице символов смещаются, и Вы получаете возможность делать дампы остальных символов (которые до этого были испорченные, пустые).

2. Удобнее всего использовать пропорциональные шрифты - у которых постоянная ширина, так как для них проще написать программное обеспечение, выводящее символ на графический индикатор. К пропорциональным шрифтам относятся, например, Courier New и Terminal (к сожалению, шрифт Terminal нерусифицирован, но зато самый маленький из пропорциональных). Недостаток пропорциональных шрифтов - они некрасивые и некомпактные, много драгоценного свободного места на экране будет тратиться впустую. Из шрифтов с переменной шириной стоит присмотреться к MS Serif и Small Fonts - они изначально рассчитаны на маленький размер.

3. Так как экраны у устройств с микроконтроллерами обычно маленькие, для импортируемых шрифтов нужно выбирать самый маленький размер 8 (иногда можно выбрать 6 или даже 5).

4. Кодировку символов лучше выбрать стандартную ANSI Windows 1251 (её удобно использовать потому, что она позволяет использовать строковые константы на русском языке в среде программирования IAR Embedded Workbench). Вот она:

 код  симв.     код  симв.     код  симв.     код  симв.  
    00
    01
    02
    03
    04
    05
    06
    07
    08  'BS'
    09
    0a  'LF'
    0b
    0c
    0d  'CR'
    0e
    0f
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    1a
    1b
    1c
    1d
    1e
    1f
    20  ' '
    21  '!'
    22  '"'
    23  '#'
    24  '$'
    25  '%'
    26  '&'
    27  '''
    28  '('
    29  ')'
    2a  '*'
    2b  '+'
    2c  ','
    2d  '-'
    2e  '.'
    2f  '/'
    30  '0'
    31  '1'
    32  '2'
    33  '3'
    34  '4'
    35  '5'
    36  '6'
    37  '7'
    38  '8'
    39  '9'
    3a  ':'
    3b  ';'
    3c  '<'
    3d  '='
    3e  '>'
    3f  '?'
      40  '@'
    41  'A'
    42  'B'
    43  'C'
    44  'D'
    45  'E'
    46  'F'
    47  'G'
    48  'H'
    49  'I'
    4a  'J'
    4b  'K'
    4c  'L'
    4d  'M'
    4e  'N'
    4f  'O'
    50  'P'
    51  'Q'
    52  'R'
    53  'S'
    54  'T'
    55  'U'
    56  'V'
    57  'W'
    58  'X'
    59  'Y'
    5a  'Z'
    5b  '['
    5c  '\'
    5d  ']'
    5e  '^'
    5f  '_'
    60  '`'
    61  'a'
    62  'b'
    63  'c'
    64  'd'
    65  'e'
    66  'f'
    67  'g'
    68  'h'
    69  'i'
    6a  'j'
    6b  'k'
    6c  'l'
    6d  'm'
    6e  'n'
    6f  'o'
    70  'p'
    71  'q'
    72  'r'
    73  's'
    74  't'
    75  'u'
    76  'v'
    77  'w'
    78  'x'
    79  'y'
    7a  'z'
    7b  '{'
    7c  '|'
    7d  '}'
    7e  '~'
    7f  '' 
      80    'Ђ'
    81    'Ѓ'
    82    '‚'
    83    'ѓ'
    84    '„'
    85    '…'
    86    '†'
    87    '‡'
    88    '€'
    89    '‰'
    8a    'Љ'
    8b    '‹'
    8c    'Њ'
    8d    'Ќ'
    8e    'Ћ'
    8f    'Џ'
    90    'ђ'
    91    '‘'
    92    '’'
    93    '“'
    94    '”'
    95    '•'
    96    '–'
    97    '—'
    98    '�'
    99    '™'
    9a    'љ'
    9b    '›'
    9c    'њ'
    9d    'ќ'
    9e    'ћ'
    9f    'џ'
    a0    ' '
    a1    'Ў'
    a2    'ў'
    a3    'Ј'
    a4    '¤'
    a5    'Ґ'
    a6    '¦'
    a7    '§'
    a8    'Ё'
    a9    '©'
    aa    'Є'
    ab    '«'
    ac    '¬'
    ad    '­'
    ae    '®'
    af    'Ї'
    b0    '°'
    b1    '±'
    b2    'І'
    b3    'і'
    b4    'ґ'
    b5    'µ'
    b6    '¶'
    b7    '·'
    b8    'ё'
    b9    '№'
    ba    'є'
    bb    '»'
    bc    'ј'
    bd    'Ѕ'
    be    'ѕ'
    bf    'ї'
      c0    'А'
    c1    'Б'
    c2    'В'
    c3    'Г'
    c4    'Д'
    c5    'Е'
    c6    'Ж'
    c7    'З'
    c8    'И'
    c9    'Й'
    ca    'К'
    cb    'Л'
    cc    'М'
    cd    'Н'
    ce    'О'
    cf    'П'
    d0    'Р'
    d1    'С'
    d2    'Т'
    d3    'У'
    d4    'Ф'
    d5    'Х'
    d6    'Ц'
    d7    'Ч'
    d8    'Ш'
    d9    'Щ'
    da    'Ъ'
    db    'Ы'
    dc    'Ь'
    dd    'Э'
    de    'Ю'
    df    'Я'
    e0    'а'
    e1    'б'
    e2    'в'
    e3    'г'
    e4    'д'
    e5    'е'
    e6    'ж'
    e7    'з'
    e8    'и'
    e9    'й'
    ea    'к'
    eb    'л'
    ec    'м'
    ed    'н'
    ee    'о'
    ef    'п'
    f0    'р'
    f1    'с'
    f2    'т'
    f3    'у'
    f4    'ф'
    f5    'х'
    f6    'ц'
    f7    'ч'
    f8    'ш'
    f9    'щ'
    fa    'ъ'
    fb    'ы'
    fc    'ь'
    fd    'э'
    fe    'ю'
    ff    'я'
 
 

Такая кодировка (ANSI Windows 1251) лучше всего подходит, поскольку большинство программ используют именно её. Например, такая кодировка позволяет напрямую задавать и выводить русский текст в IAR Embedded Workbench.

5. Есть возможность экспортировать весь набор символов в BMP-картинки (File -> Export -> Bitmap Files of All Chars). Эта возможность хороша тем, что изображения всех символов экспортируются неиспорченные даже для нелицензионной программы (нет таких искусственных ограничений, как на создание текстового дампа символов). Поэтому если у Вас есть конвертор bmp -> текст (например, текст-дамп, понятный для C-компилятора), то создание шрифта сильно упрощается. Если Вы знакомы с программированием на Windows, то написать такой конвертор можно самому, так как формат BMP достаточно прост. Предлагаю готовый конвертор, который я написал самостоятельно (скачать можно по ссылке [1], вместе с примерами использования).

[Генерирование маленького шрифта]

В примере показана генерация миниатюрного цифрового шрифта, который я использовал для вывода напряжения питания прибора рядом с графикой "батарейки" (показывающей степень разряда аккумулятора). 10 символов шрифта (цифры от 0 до 9) подготовлены в удобном для редактирования виде - как единая монохромная картинка 090226small_digits.bmp (легко правится графическим редактором mspaint), и сконвертирована в C-текст с помощью утилиты bmptoc.exe (см. Ссылки).

090226small_digits.GIF

Каждый символ цифры поместился в матрицу 4X6 точек, причем крайний правый столбец используется для пробела между символами (можно было бы и его убрать, но тогда неудобно было бы редактировать символы в картинке). Выводится символ на экран с помощью процедуры void DrawSmallDigit (u8 x, u8 y, char sym), детали вывода точек (процедура put_pixel) не рассматриваются - это зависит от применяемого графического индикатора.

[Другие инструменты и форматы для растровых изображений]

X BitMap, или сокращенно XBM. Это текстовый монохромный графический формат, совместимый с языком C и C++. Пример картинки в формате XBM (из Википедии):

XBM-Sample

#define test_width 16
#define test_height 7
static char test_bits[] = 
{
  0x13, 0x00, 0x15, 0x00, 0x93, 0xcd, 0x55, 0xa5, 0x93, 0xc5, 0x00, 0x80, 0x00, 0x60
};

X PixMap, или сокращенно XPM. Это текстовый графический формат с поддержкой цвета, совместимый с языком C и C++. Пример картинки в формате XPM (из Википедии):

XPM-Sample

/* XPM */
static char *green_simple_crest_xpm[] = {
/* width height num_colors chars_per_pixel */
" 36 36 5 1",
/* colors */
"` c #ffffff",
". c #00ff00",
"# c #ff0000",
"a c #000000",
"b c #0000ff",
/* pixels */
"````````````............############",
"````````````............############",
"````````````............############",
"````````````............############",
"````````````............############",
"````````````............############",
"````````````............############",
"````````````............############",
"````````````............############",
"````````````............############",
"````````````............############",
"````````````............############",
"....................................",
"....................................",
"....................................",
"....................................",
"....................................",
"....................................",
"....................................",
"....................................",
"....................................",
"....................................",
"....................................",
"....................................",
"aaaaaaaaaaaa............bbbbbbbbbbbb",
"aaaaaaaaaaaa............bbbbbbbbbbbb",
"aaaaaaaaaaaa............bbbbbbbbbbbb",
"aaaaaaaaaaaa............bbbbbbbbbbbb",
"aaaaaaaaaaaa............bbbbbbbbbbbb",
"aaaaaaaaaaaa............bbbbbbbbbbbb",
"aaaaaaaaaaaa............bbbbbbbbbbbb",
"aaaaaaaaaaaa............bbbbbbbbbbbb",
"aaaaaaaaaaaa............bbbbbbbbbbbb",
"aaaaaaaaaaaa............bbbbbbbbbbbb",
"aaaaaaaaaaaa............bbbbbbbbbbbb",
"aaaaaaaaaaaa............bbbbbbbbbbbb"
};

Это утилита, которая может конвертировать файлы формата Windows Bitmap в байтовый массив, походящий для дисплеев LCD. Дополнительно для дисплеев она может создавать наборы шрифтов из системных шрифтов Windows. В результате получается код на языке C, который можно использовать в проекте с микроконтроллером.

GLCD-Tools1 GLCD-Tools2

Утилиту можно скачать бесплатно, см. [10].

Как ни странно, но стандартная программа для рисования, входящая в состав Windows 7, очень удобна для редактирования шрифтов. Слайдером в нижней правой части окна можно менять масштаб отображения растра шрифта, масштабирование также можно делать колесиком мыши, если удерживать клавишу Ctrl. Курсором можно удобно отпределить абсолютную коодинату каждой точки.

edit font image with MS Paint

Ниже показан пример такого шрифта, который выполнен в виде растровой картинки (grayscale, 4 бита на точку) и набора координат каждого символа в ней, и подпрограмма для его вывода.

struct TSymData
{
   char code;           //код символа
   //координаты точки X растре:
   u16 offsetStart;     //начало символа
   u16 offsetEnd;       //конец символа
};
 
struct TBmpFont
{
   const u8* rawdata;         //растр шрифта
   u16 heigth;                //высота картинки растра шрифта
   u16 width;                 //ширина картинки растра шрифта
   const TSymData *symdata;   //позиция каждого символа в растре шрифта
};
 
//Растровая картинка всех символов шрифта (переведенная
// в C-дамп картинка BMP):
static const unsigned char Ms_PMincho_36[] = {
/* Ms-PMincho-36-ANSI, 5218x36, 4 bit color */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
...
0x00,0x00,0x00,0x00,0x00,0x04,0xFF,0xFF,
0xFF,0xFF,0xF4,0x00,0x00,0x05,0xEF,0xDC,
0xEF,0xF8,0x00,0x00,0x00,0x00,0x00,0x8F,
...
0x00,0x00,0x00,0x00
};
 
//Данные о координатах каждого символа шрифта:
static TSymData BigANSIData [] =
{
   {16, 0,   17},   //индекс, смещение символа по X, ширина символа по X
   {17, 18,  35},   // ...
   ...
   {'u', 1985, 2003},
   {'v', 2004, 2020},
   {'w', 2021, 2042},
   ...
   {0, 0, 0}
};
 
TBmpFont BigANSI =
{
   Ms_PMincho_36,    //ссылка на массив растра
   36,               //высота растра в точках
   5218,             //ширина растра в точках
   BigANSIData       //данные шрифта
};
 
void placebmpsym (char sym, int xpos, int ypos, TBmpFont *font)
{
   //получение информации о символе в массиве:
   TSymData const *syminfo = font->symdata;
   bool symexist = false;
   while (syminfo->offsetEnd)
   {
      if (sym == syminfo->code)
      {
         symexist = true;
         break;
      }
      syminfo++;
   }
   if (symexist)
   {
      //сколько байт в строке:
      u16 bpl = (font->width%2)?(font->width/2)+1:font->width/2;
      //Выравнивание на 4 байта делать не надо, потому что
      // лишние байты строки вырезает утилита bmptoc.exe:
      //bpl = (bpl + 3) & ~3;
      for (int ycnt=0; ycnt < font->heigth; ycnt++)
      {
         int ydst = ypos + ycnt;
         if ((ydst < 0) || (ydst > (HEIGHT-1)))
            continue;
         int ysrc = (font->heigth-1)-ycnt;
         int symwidth = syminfo->offsetEnd - syminfo->offsetStart + 1;
         for (int xcnt=0;xcnt<symwidth;xcnt++)
         {
            int xdst = xpos + xcnt;
            if ((xdst < 0) || (xdst > (WIDTH-1)))
               continue;
            int xsrc = syminfo->offsetStart + xcnt;
            u8 srcbitmask = (xsrc & 1)?0x0F:0xF0;
            u8 srcdb = *(font->rawdata + ysrc*bpl + (syminfo->offsetStart+xcnt)/2);
            u8 pixelval = (xsrc & 1)?srcdb & srcbitmask:(srcdb & srcbitmask)>>4;
            PLACE_PIXEL(xdst, ydst, pixelval);
         }
      }
   }
}
 
//Пример вывода на экран цифры 2 в позицию экрана X,Y={10,15}:
placebmpsym ('2', 10, 15, &BigANSI);

Это редактор растровых картинок, специально оптимизированный для создания, модификации и преобразования маленьких, среднеразмерных изображений, таких как иконки, кнопки, графика веб-страниц, спрайты и т. д. Очень хорошо подходит для редактирования монохромных изображений. Редактор очень быстрый, простой, и часто более точный и эффективный, чем большинство больших редакторов растровых изображений. В то же самое время он мощнее обычных простых редакторов иконок и лишен их ограничений.

pixelformer main window

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

[Ссылки]

1150113micros-fonts.zip - программы и утилиты, упомянутые в статье, примеры использования.
2Сайт программы BitFontCreator.
3BMP to PIC table for graphic LCD assembly utility.
4TypeFace / Character Set Image Data - работа со шрифтами для микроконтроллеров.
5Charset Extractor from Images.
6Графический интерфейс пользователя с применением микроконтроллеров Microchip.
7. IAR EW ARM: как перенаправить вывод printf и putchar (в статье описан пример подключения индикатора ЖКИ Winstar WG240128B со схемой и исходниками).
8. Утилита bmptoc.exe для конвертирования BMP-картинок и бинарных файлов в C-дамп (вместе с исходниками).
9. Разработка GUI с помощью Excel.
10. GLCD Tools site:sourceforge.net.