Обзор шрифтов библиотеки u8glib |
![]() |
Добавил(а) microsin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Одно из больших достоинств библиотеки u8glib помимо всех прочих - большое количество готовых шрифтов. К сожалению, кириллических шрифтов среди них не так много, но все-таки русские шрифты есть, их можно найти. В названии шрифтов (т. е. в именах двоичных массивов, где имеются данные шрифтов) присутствуют суффиксы, которые дают краткую характеристику шрифта (b, n, r и т. п., см. описание суффиксов ниже). Суффикс может быть составной, например br означает жирный урезанный шрифт. r означает reduced, т. е. уменьшенный знакогенератор. Обычно набор символов ограничен сверху, т. е. символы с кодами 128..255 отсутствуют. Хорошо подходит для систем, где не нужно выводить русские буквы или когда есть жесткие ограничения по объему памяти. n означает numberic, т. е. цифровые символы (коды 42 .. 57). Обычно это только символы ^+,-./0123456789:. Знак % отсутствует. b или B означает bold, т. е. "толстые" символы. Если шрифт мелкий, то символы будут угловатые, "квадратные". O означает наклонный шрифт, italic. 67_75, 78_79 наборы графических символов. Некоторые символы сделаны так, что они хорошо масштабируются вверх при отображении (например u8g_font_trixel_square). Это позволяет очень экономить на памяти. Цифры в названии шрифта в формате NNxMM означают размер окружающего символ прямоугольника по X и по Y. Например, имя u8g_font_10x20r говорит нам о том, что максимальный размер символа по горизонтали 10 точек, по вертикали 20, и что шрифт имеет урезанный набор символов (обычно с кодами не более 127).
[Структура шрифта] [U8G_FONT_DATA_STRUCT_SIZE][растровая графика шрифта] Информация о рисуемом символе кэшируется в структуре u8g_t (см. поля glyph_dx, glyph_x, glyph_y, glyph_width, glyph_height). U8G_FONT_DATA_STRUCT_SIZE это специальный блок данных из 17 байт: 0 Байт, в котором закодирован формат шрифта. Формат шрифта может быть 0, 1 или 2. От этого зависит размер структуры определения картинки (Glyph) символа шрифта. Я просмотрел все шрифты в модуле u8g_font_data.cpp, и оказалось что примерно половина шрифтов имеет тип 0 и примерно половина тип 1, других типов нет. В настоящий момент в библиотеке u8glib реально имеется только 2 формата шрифтов 0 и 1. Формат 0 занимает в памяти 6 байт, а формат 1 только 3 байта. Достигается это тем, что в формате 1 данные, описывающие картинку шрифта, запакованы в старшей и младшей тетрадах байта. Если для обоих типов байт 0 формата равен 255, то это означает пустую картинку символа. 1 FONTBOUNDINGBOX width (unsigned). Байт, кодирующий ширину символа. 2 FONTBOUNDINGBOX height (unsigned). Байт, кодирующий высоту символа. 3 FONTBOUNDINGBOX x-offset (signed). 4 FONTBOUNDINGBOX y-offset (signed). 5 Высота заглавной 'A' (unsigned). 6 Начало в кодировке символа 'A'. 8 Начало в кодировке символа 'a'. Функции u8g_font_GetFontStartEncoding, u8g_font_GetFontEndEncoding - извлекают из шрифта начальный и конечный коды символов, которые можно отобразить. 10 Начало кодировки, т. е. код первого символа в знакогенераторе. 11 Конец кодировки, т. е. код последнего символа в знакогенераторе. 12 descent 'g'. Занижение для буквы g, отрицательное значение: ниже базовой линии. 13 max ascent для шрифта, т. е. максимальное завышение символа. 14 min decent для шрифта, т. е. максимальное занижение символа. Отрицательное значение: ниже базовой линии. 15 font xascent. 16 font xdecent. Может быть отрицательным значением. [Как делать русифицированные шрифты для u8glib] По ссылке [1] нашел вот такой рецепт: Шрифт для U8G делается очень просто. Сначала создаете шрифт в формате .bdf (bitmap definition font). Затем с помощью утилиты bdf2u8g.exe конвертируете его в библиотечный формат. Есть очень неплохой редактор шрифтов - Fony, который умеет экспортировать в формат bdf. Кроме этого он умеет импортировать различные шрифтовые форматы. Т.е. с помощью описанной выше связки можно для библиотеки u8g создать практически любой шрифт без особых усилий. Правда шрифт 5x7 я так и не нашел откуда импортнуть, поэтому пришлось поработать. Из командной строки запускаете: bdf2u8g.exe my5x7rus_2.bdf my5x7rus my5x7rus.h где my5x7rus_2.bdf - имя исходного BDF-шрифта my5x7rus - имя шрифта в библиотеке (т.е. это название будете указывать в процедуре u8g.setFont(fontname); т.е. для указанного вторым параметром my5x7rus, выбор шрифта будет осуществляться так: u8g.setFont(my5x7rus); my5x7rus.h - имя выходного файла шрифта, который вы будете подключать в проект Еще рецепт: 1. Ставим Fontforge (если некорректно отображаются строки - удалить русскую локаль - будет английский). 2. Качаем шрифты BDF. 3. Так как русский в юникоде кодируется 2 байтами, а библиотека работает с однобайтовыми строками - юникод отпадает. Подойдет кодировка ISO8859-5, где английские и русские буквы ограничены одним байтом. Конвертим кодировку BDF c помощью fontforge, добавляем свои символы, если надо. 4. используя команды типа "bdf2u8g font/6x10.bdf u8g_font_6x10 utility/u8g_font_6x10.c" конвертим обратно, попутно удаляя дубликаты из "utility/u8g_font_data.c" или добавляем как новый в "utility/u8g.h" и кидаем рядом ".с". 5. записывать строки придется "\xb0\xb1\xb2\xb3" //АБВГ Русские символы А..Я имеют коды 0xB0..0xCF, и символы а..я коды D0..0xEF. Кодировка текста Windows ANSI, которую использует VisualDSP, отличается тем, что А..Я имеют коды 0xC0..0xDF, и символы а..я коды E0..0xFF. Таким образом, чтобы отобразить шрифт VisualDSP по-русски, нужно от кода символа отнять 16. Для вывода русского текста я написал специальную подпрограмму, которая по таблице определяет, какой это шрифт, русский или нет, и если русский, то вычитает из кода символа 16: //Таблица имен массивов шрифтов в кодировке ISO8859-1 Windows-1252.
//Эти шрифты раньше были ISO10646-1, поменял их на ISO8859-5 русский:
static const u8g_fntpgm_uint8_t *ISO8859fonts[] = { u8g_font_10x20, //крупные буквы u8g_font_4x6, //очень мелкие буквы u8g_font_5x8, //мелкие буквы u8g_font_6x10, //минимально разборчивый шрифт u8g_font_6x12, //разборчивый шрифт u8g_font_8x13B, //толстые буквы, шрифт крупнее u8g_font_8x13, //шрифт крупнее u8g_font_8x13O, //шрифт крупнее, наклонный u8g_font_9x15B, //крупный шрифт, толстый u8g_font_9x15, //крупный шрифт u8g_font_9x18B, //самый крупный шрифт, толстый u8g_font_9x18, //самый крупный шрифт NULL }; bool isFontRussian (const u8g_fntpgm_uint8_t *font) { uint8_t fontidx = 0; while(true) { if (NULL == ISO8859fonts[fontidx]) break; else if (font == ISO8859fonts[fontidx]) return true; fontidx++; } return false; } int8_t u8g_draw_glyph(u8 layeridx, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) { const u8g_pgm_uint8_t *data; uint8_t w, h; uint8_t i, j; u8g_uint_t ix, iy; if (isFontRussian(u8gval.font) && (encoding >= (uint8_t)'А')) encoding -= 16; u8g_glyph_t g = u8g_GetGlyph(&u8gval, encoding); if ( g == NULL ) return 0; data = u8g_font_GetGlyphDataStart(u8gval.font, g); w = u8gval.glyph_width; h = u8gval.glyph_height; x += u8gval.glyph_x; y -= u8gval.glyph_y; y--; /* w можно повторно использовать для количества байт на строку */ w += 7; w /= 8; iy = y; iy -= h; iy++; for( j = 0; j < h; j++ ) { ix = x; for( i = 0; i < w; i++ ) { u8g_Draw8Pixel(layeridx, ix, iy, 0, u8g_pgm_read(data)); data++; ix+=8; } iy++; } return u8gval.glyph_dx; } [Ссылки] 1. Как вывести русские буквы на LCD ST7920 site:arduino.ru? |