Pull to refresh

Comments 75

У приборов National Instruments (осциллографы, анализаторы спектра, измерители комплексных сопротивлений) нет дисплеев, потому что это просто модули которые врубаются в блок. А морды всего вышеперечисленного - на обычном компьютерном дисплее.

Да, действительно, много устройств (и не только от NI) имеют описанный Вами интерфейс взаимодействия с пользователем. Но, как Вы понимаете, не во всех случаях есть такая возможность, особенно в портативных устройствах.

Согласен. Пользоваться отдельными приборами или сборкой NI - дела вкуса (и еще бюджета, наверное).

Мне например отдельные больше нравятся, потому что есть ручки

Я сам несколько раз делал коммерческие железки с монохромным графическим интерфейсом и все мне нравилось.

Потом однажды на работе мне заменили ip телефон с таким интерфейсом и я понял что не хочу разбираться в меню. Все это уже морально устарело. В моем старом квадратном ipod'е - идеальный тачевый интерфейс. В новой беззеркалке также экран поддерживает мультитач. Сейчас уже в станках и тракторах андроид.

Короче, ниша конечно осталась - сверхнизкое потребление, малая стоимость (уже спорно) ну или просто лучше одного мигающего светодиода зарядного устройства ничего придумать нельзя - светодиод видно в темноте. Но в остальном подобных интерфейсов лучше избегать. Иначе твое изделие попадает в разряд кустарщины или изделия низкого класса.

Иначе твое изделие попадает в разряд кустарщины или изделия низкого класса.

Как же глубоко вы заблуждаетесь, относительно применимости и распространенности монохромных интерфейсов.

Иначе твое изделие попадает в разряд кустарщины или изделия низкого класса.

Мой только что купленный рекордер категорически с вами не согласен, да и я на его стороне.

Хм, мой Mi band имеет неплохой монохромный интерфейс на oled экране. В новых версиях появились цветные, но и этот вполне неплох. Хотя тут тач скрин и жесты.

Монохромный рефлективный индикатор прекрасно виден и при палящем солнце, и не слепит в темноте. Потребляет жалкие копейки. Графика не перегружена глянцем и т.н. «красивостями».
Цветной экран в новых звонилках — абсолютная победа мракетологов над здравым смыслом…

Хорошее дополнение, но мне кажется нужно уточнить сферу применимости. Если этот девайс предназначен для бытовой электроники с сетевым питанием, то действительно матричные ЖК выглядят как анахронизм. А если это какой-то узкоспецифический девайс предназначенный для профессионалов (типа рекордеров, панелей станков, GPS приемников и т.п.) то там такой дисплей пользователь простит :)

В одном изделии мы выбирали экран и чуть не остановились на новомодном OLED. Бабло победило, а потом оказалось что в этом изделии сверхважен малопотребляющий режим (это редкий и неочевидный кейс, потому что изделие включено всегда). И у ЖК есть уникальное свойство - его видно и без подсветки. То есть у экрана есть два режима - с подсветкой и без. Это уникальное свойство, чего нет ни у какого другого.

Но у айфоноподобного интерфейса есть другое уникальное свойство - "работа без документации". Это не "победа маркетологов", это то что бизнес может оцифровать. Обучение сотрудников стоит денег.

Для цветных экранов с как минимум 256 цветами дополнительно можно добавить сглаживание (4 или 16 бит на пиксель). Я такое делал, надписи получаются гораздо приятнее.
Ну и сам способ организации массива может быть разным Иногда удобнее сплошным массивом, а иногда — когда не нужны все символы из диапазона — удобнее таблица указателей на отдельные массивы для каждого символа.

Спасибо за отзыв и интересные конструктивные идеи. Надо подумать, как их реализовать в приложении. Тут ведь дело в том, что я задумывал приложение именно под простые монохромные шрифты, т.к. рассчитывал на использование в жестко ограниченных по ресурсам системах — 8-битные МК, Arduino и т.п. И чем проще представляются данные, тем проще алгоритм их обработки, и тем быстрее он исполняется. Но, конечно, на 32-битных МК использовать вариант со сглаживанием действительно имеет смысл.

Огромное спасибо. Давно искал похожее решение, всё что находил - было не очень юзабельным. Попробовал вашу утилиту - мега-круто. Даже не вериться что это сделано в Lazarus - настолько смотрится красиво.
Полностью затестить пока нет возможности, но для одного проекта, как доберусь, точно использую.

Спасибо, наконец то нормальная утилита. Все остальное просто шлак

Ваша утилита ориентирована на редактирование и просмотр символов по одному. Но в реальном тексте будут не отдельные символы, а слова из них. И хорошо иметь возможность видеть, как символы сочетаются друг с другом. Причем желательно в реальном времени, чтобы при редактировании сразу же обновлялась картинка.


Например, на картинке в начале поста жутко выглядит слово "муль-т-иметра" — большие промежутки справа и слева от "т". Сравните промежутки в "ьт" и "им". Возможно, букву "т" стоило сделать более узкой.


В шрифтах, которые используются на Хабре, это исправлено с помощью кернинга — в паре "ьт" мягкий знак заезжает под перекладинку буквы "т".


Если бы в программе справа была панелька для просмотра букв в тексте, это было бы легко заметить.

Так это неизбежная проблема моноширинных шрифтов, которые вынуждены быть вписанными в фиксированное знакоместо. Глиф "т" и "ш" располагаются на одинаковой плашке, разве есть возможность их двигать как векторные?

Возможность видеть сочетание символов есть. И кстати, работает именно в реальном времени.

По поводу межсимвольного расстояния. Это же все-таки растровый шрифт, об этом и статья. Но если очень нужен кернинг, то мне видится единственное, возможно корявое, решение: в графической библиотеке при выводе символов анализировать текущий и предыдущий, и выбирать нужное смещение по горизонтали.

И таки да, на картинке в начале символ "т" и правда не удался, его можно было бы сделать не таким широким.

Очень круто! За лазарус отдельный лакойс!

Давным-давно занимался растровыми шрифтами для промышленных принтеров.

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

Вот бы ещё был импорт из си-кода.

Интересная мысль. Возможно, это появится в будущих версиях. Но тут надо учитывать одну вещь: импортируемый код должен содержать данные в таком же формате, какой генерируется самим приложением. Конечно, там есть некоторые настройки, но ведь это только несколько вариантов из бесконечного множества доступных.

Спасибо за ссылку. Глянул на страничку. Из идей этого проекта можно было бы взять поддержку формата Adobe BDF и предустановки генератора кода для разных библиотек.

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

Импорт нового шрифта, при попытке набрать имя шрифта в поле имени выскакивает ошибка :)

При импорте нельзя сразу задать тип "пропорциональный". Ладно, есть кнопка "Оптимизировать размер холста", жму ее, но в появившемся диалоге кнопка "Применить" никак не хочет становиться активной :)

И что самое главное - нет экспорта в битовый поток. Например, если ширина символа 11 пикселей, высота 17, то чтобы сохранялось битовым массивом по 11 бит на строку, дополняя в конце при необходимости до целого байта. В указанном примере это должно быть 11*17=187 бит плюс еще 5 бит для дополнения до целого байта.

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

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

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

Тип шрифта и не требуется задавать при создании или импорте. Это опция генератора кода.

Но мне же надо видеть как этот символ будет отображаться, какие и где будут у него поля :) Или это после оптимизации всех символов становится доступным?
По оптимизации. Вы выбрали в диалоге оптимизацию только правого края холста.

Я перепробовал все варианты полей — и по одному и все сразу, и парами — нифига :) Пробовал на разных символах, в том числе и на восклицательном знаке, у которого уж точно правые 80% ширины поля ничем не заняты :)
По поводу экспорта в битовый поток. Т.к. я никогда не пользовался таким вариантом хранения данных в таблице, то и не реализовал его. Но, похоже, это имеет свое применение

Это во многих случаях экономит занимаемое шрифтом место, и практически не несет никаких дополнительных накладных расходов при отрисовке :)
У меня шрифт состоит из двух массивов — один (unsigned char) с битовыми потоками символов, второй (unsigned short) с шириной символов. Если в значении ширины установлен старший бит, значит это не ширина, а номер другого символа, на который ссылается этот. То есть можно не кодировать в шрифт, например, русские буквы А, В, Е, К и т.д., а ссылаться на символы латинских букв с таким же начертанием :)

Я не очень понимаю, что за поля Вы имеете в виду. В проекте шрифта размер холста одинаков для всех символов. Т.е. не может быть символ пробела шириной 4 пикселя, а символ А - шириной 10 пикселей. Размеры холста - глобальное свойство проекта шрифта.

Кстати, если при импорте был установлен флажок "Оптимизировать", то естественно, что после импорта с такой опцией оптимизировать уже больше будет нечего. :) Оптимизация - это ведь автоуменьшение размера холста, если таковое возможно, сами изображения символов не передвигаются при этом.

Про битовый поток я понял Вашу мысль. Возможно в будущих выпусках появится такая опция генерации кода. И ссылки на похожие символы тоже.

Т.е. не может быть символ пробела шириной 4 пикселя, а символ А — шириной 10 пикселей.

Но как тогда создавать пропорциональные шрифты? :)

Я уже писал об этом.

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

В моноширинном варианте байта ширины не будет в коде. Вот и вся разница.

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

То есть в процессе редактирования я никак не увижу какая ширина будет установлена для символа при генерации пропорционального шрифта?
Вот, например, апостроф


Какой ширины будет этот символ в результате? 2 пикселя? 4? 18? Где это можно указать?

Ширина рассчитывается автоматически генератором кода. Причем, если слева от символа будут пустые столбцы, они тоже посчитаются. Это число по смыслу можно интерпретировать как координату X правой границы символа. Да, в Вашем случае ширина апострофа будет 2.

Не айс. Я бы хотел сам задавать ширину символам. Ну или хотя бы указать размеры полей с каждой из сторон. И, разумеется, на картинке хотелось бы видеть символ именно так как он будет выведен в итоге.

Иллюстрация к предыдущему комментарию.

Различие
пропорциональный
пропорциональный
моноширинный
моноширинный
А почему у восклицательного знака ширина 1 пиксель? У символов вообще нет пустого поля славе или справа? То есть они будут сливаться друг с другом если выводить их подряд?

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

Ну можно и так, конечно… Но это не слишком удобно. Например, после левой круглой скобки промежуток не нужен, а после двоеточия промежуток желательно сделать чуть больше. Я об этом и пишу изначально — хочется видеть как будет выглядеть окончательно каждый символ. В том виде, в котором он будет сохранен.

Вы перфекционист. :) Ну, а если серьезно, я ведь приложение сделал для создания шрифтов под системы с крайне ограниченными ресурсами - начиная с 8-битных МК. Сомневаюсь, что в устройствах на подобном железе возникнет острая необходимость в полиграфически безукоризненном виде текста на дисплее. Особенно, если учесть что и дисплеи эти вовсе не FullHD. В общем, нет предела совершенству, как говорится.

Но Вы же позиционируете приложение как универсальное :) А получается, что мне приходится жертвовать хорошим видом шрифта в угоду экономии десятка байт. При том, что у меня не стоит остро вопрос в такой экономии :)
Ну то есть я бы с удовольствием использовал Ваше приложение, потому что сейчас я в полуручном режиме делаю шрифты, но не могу :)

Не бывает абсолютно универсальных вещей. Всегда где-то проходит граница возможностей. :)

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

Хороший редактор. Я в свое время для работы со шрифтами и спрайтами пользовался мелкими самописными утилитками. По тому опыту работы есть парочка предложений в функционал программы:

1. Добавить в генерацию кода на С вариант вывода данных в «графическом» виде:
типа такого
________,________,
________,________,
____OO__,________,
___OOO__,________,
_OOOOO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
____OO__,________,
_OOOOOOO,O_______,
________,________,
________,________,

________,________,
________,________,
___OOOO_,________,
__OO__OO,________,
_OO____O,O_______,
_OO____O,O_______,
_______O,O_______,
_______O,O_______,
______OO,________,
_____OO_,________,
____OO__,________,
___OO___,________,
__OO____,________,
_OO_____,________,
_OO_____,________,
_OOOOOOO,O_______,
________,________,
________,________,

________,________,
________,________,
___OOOO_,________,
__OO__OO,________,
_OO____O,O_______,
_OO____O,O_______,
_______O,O_______,
______OO,________,
___OOOOO,________,
______OO,________,
_______O,O_______,
_______O,O_______,
_OO____O,O_______,
_OO____O,O_______,
__OO__OO,________,
___OOOO_,________,
________,________,
________,________,


Для этого всего лишь требуется определить
небольшую таблицу
#define	________	0
#define	_______O	1
#define	______O_	2
#define	______OO	3
#define	_____O__	4
#define	_____O_O	5
#define	_____OO_	6
#define	_____OOO	7
#define	____O___	8
#define	____O__O	9
#define	____O_O_	10
#define	____O_OO	11
#define	____OO__	12
#define	____OO_O	13
#define	____OOO_	14
#define	____OOOO	15
#define	___O____	16
#define	___O___O	17
#define	___O__O_	18
#define	___O__OO	19
#define	___O_O__	20
#define	___O_O_O	21
#define	___O_OO_	22
#define	___O_OOO	23
#define	___OO___	24
#define	___OO__O	25
#define	___OO_O_	26
#define	___OO_OO	27
#define	___OOO__	28
#define	___OOO_O	29
#define	___OOOO_	30
#define	___OOOOO	31

и т.д. до 255


2. В этой программе кроме шрифтов можно создавать и спрайты, в том числе для анимации (по типу приведенной в статье). Для этих целей максимальный размер «символа» хорошо бы увеличить хотя бы до 320x240.

3. Для шрифтов больших размеров и спрайтов уже может быть актуально применять сжатие для экономии места. Алгоритм LZSS (c измененным кодированием) неплохо подходит для этого.
Например здесь экономия порядка 3-х кратной получалась
//const char spBigMicro_Data[] = {	/* Size:120 */
/*________,________,________,________,	//1
________,________,________,________,	//2
________,________,________,________,	//3
________,________,________,________,	//4
________,________,________,________,	//5
________,________,________,________,	//6
________,________,________,________,	//7
________,________,________,________,	//8
_____OOO,OOO_____,__OOOOOO,________,	//9
_____OOO,OOO_____,__OOOOOO,________,	//10
_____OOO,OOO_____,__OOOOOO,________,	//11
_____OOO,OOO_____,__OOOOOO,________,	//12
_____OOO,OOO_____,__OOOOOO,________,	//13
_____OOO,OOO_____,__OOOOOO,________,	//14
_____OOO,OOO_____,__OOOOOO,________,	//15
_____OOO,OOO_____,__OOOOOO,________,	//16
_____OOO,OOO_____,__OOOOOO,________,	//17
_____OOO,OOO_____,__OOOOOO,________,	//18
_____OOO,OOO_____,__OOOOOO,________,	//19
_____OOO,OOO_____,__OOOOOO,________,	//20
_____OOO,OOO_____,__OOOOOO,________,	//21
_____OOO,OOO_____,__OOOOOO,________,	//22
_____OOO,OOO_____,__OOOOOO,________,	//23
____OOOO,OOO_____,_OOOOOOO,________,	//24
____OOOO,OOOO____,_OOOOOOO,________,	//25
___OOOOO,OOOOO___,OOOOOOOO,________,	//26
_OOOOOOO,OOOOOOOO,OOOOOOOO,________,	//27
OOOOOOO_,OOOOOOOO,OO_OOOOO,________,	//28
OOOOOO__,_OOOOOOO,O__OOOOO,________,	//29
_OOOO___,__OOOOO_,___OOOOO,________ 	//30
};
const struct TSprite spBigMicro = {27,30,COMPRESS_NONE,spBigMicro_Data};
*/
const char spBigMicro_Data[] = {	/* Size:42 (35%) */
0x28,0x00,
0x00,0xF0,0xE0,0x02,0x07,0xE0,0x3F,0xF3,0xF3,0xF3,0x83,0x02,0x0F,0xE0,0x7F,0x13,
0x00,0xF0,0x13,0x05,0x1F,0xF8,0xFF,0x00,0x7F,0xFF,0x13,0x0B,0xFE,0xFF,0xDF,0x00,
0xFC,0x7F,0x9F,0x00,0x78,0x3E,0x1F,0x00};
const struct TSprite spBigMicro = {27,30,COMPRESS_LZSS,spBigMicro_Data};

//------------------------------------------------------------------

//const char spBigMili_Data[] = {	/* Size:120 */
/*________,________,________,________,	//1
________,________,________,________,	//2
________,________,________,________,	//3
________,________,________,________,	//4
________,________,________,________,	//5
________,________,________,________,	//6
________,________,________,________,	//7
________,OOOOO___,___OOOOO,________,	//8
OOOOO__O,OOOOOOO_,__OOOOOO,OO______,	//9
OOOOO_OO,OOOOOOOO,_OOOOOOO,OOO_____,	//10
OOOOOOOO,OOOOOOOO,OOOOOOOO,OOO_____,	//11
OOOOOOOO,__OOOOOO,OOO__OOO,OOOO____,	//12
OOOOOOO_,___OOOOO,OO____OO,OOOO____,	//13
OOOOOOO_,___OOOOO,OO____OO,OOOO____,	//14
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//15
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//16
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//17
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//18
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//19
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//20
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//21
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//22
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//23
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//24
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//25
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//26
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//27
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//28
OOOOOO__,___OOOOO,O_____OO,OOOO____,	//29
OOOOOO__,___OOOOO,O_____OO,OOOO____ 	//30
};
const struct TSprite spBigMili = {31,30,COMPRESS_NONE,spBigMili_Data};
*/
const char spBigMili_Data[] = {	/* Size:36 (30%) */
0x22,0x00,
0x00,0xF0,0xB0,0x0B,0xF8,0x1F,0x00,0xF9,0xFE,0x3F,0xC0,0xFB,0xFF,0x7F,0xE0,0xFF,
0x10,0x13,0x05,0x3F,0xE7,0xF0,0xFE,0x1F,0xC3,0x43,0x02,0xFC,0x1F,0x83,0xF3,0xF3,
0xF3,0xC3};
const struct TSprite spBigMili = {31,30,COMPRESS_LZSS,spBigMili_Data};

Спасибо за развернутый комментарий и интересные идеи.

  1. Оригинальный вариант визуализации кода символов. Может быть в будущих выпусках добавлю.

  2. Ограничение 100*100 сделал условно. Ничто не мешает перекомпилировать с другими установками лимитов. Но я исходил из следующего: моя реализация редактора оставляет желать лучшего, и нет уверенности, что при таких размерах холста не будут наблюдаться дикие тормоза. Кстати, в продолжение мысли. Кадры анимаций, особенно больших размеров, наверное имеет смысл составлять в других графических редакторах, больше пригодных для этого. А потом импортировать их в генератор кода. Правда, в приложении пока нет опции импорта изображений.

  3. Сжатие - хорошая идея.

 Алгоритм LZSS (c измененным кодированием) неплохо подходит для этого

А можно, пожалуйста, поподробней. Чем жать и каким способом разжимать на МК: динамически выделять память под нужный размер или можно потоково сразу в буфер экрана?

можете поделится ссылкой на примеры с целью повышения самообразованности?

Программы сжатия на PC и разжатия в контроллере были самописные. Кодирование команд так же свое, заточенное под небольшой размер спрайта. От алгоритма LZSS была взята сама идея повторного использования цепочек данных. Описывать ее здесь смысла нет. Можно почитать, например здесь.

Буфер для разжатого изображения нужно иметь по самой сути LZSS. Он берет оттуда повторяющиеся цепочки данных. Динамически я его не выделял, просто фиксированный буфер под самый большой используемый спрайт.

Главная особенность LZSS — то что он асимметричный. При сравнительно сложном кодере он имеет простой и очень быстрый декодер.

Основное отличие моей реализации LZSS — кодирование команд в потоке заточенное под конкретное применение. Если интересно — распишу подробнее команды и реализацию.

 Если интересно — распишу подробнее команды и реализацию.

конечно интересно) можно в личку, если объем большой.

Буфер для разжатого изображения нужно иметь по самой сути LZSS. Он берет оттуда повторяющиеся цепочки данных. Динамически я его не выделял, просто фиксированный буфер под самый большой используемый спрайт.

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

прошу сильно не пинать, если вопросы глупые. я с графикой на МК только столкнулся.

а почему цепочку сразу нельзя писать в буфер, ведь по сути мы получаем N раз повторить байт M. вроде логично, сразу писать и можно сэкономить немного памяти.
Это будет алгоритм RLE. Он просто пакует повторяющиеся пиксели одного цвета в команды.
LZSS при разжатии либо копирует данные из входного буфера в выходной, либо копирует ранее распакованную цепочку из выходного буфера опять во входной, т.е. нужен произвольный доступ к выходному буферу. Можно ограничить размер выходного буфера размером используемого окна, т.е. максимальным смещением в команде копирования ранее распакованной цепочки.
Существующий в ЖКИ фреймбуфер использовать для этих целей скорее всего не получится. Программный фреймбуфер использовать можно, но это скорее всего усложнит и замедлит декодер.
либо копирует ранее распакованную цепочку из выходного буфера опять во входной
Извините, описка получилась. Правильно будет:
либо копирует ранее распакованную цепочку из выходного буфера опять в выходной

Это будет алгоритм RLE.

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

LZSS при разжатии либо копирует данные из входного буфера в выходной, либо копирует ранее распакованную цепочку из выходного буфера опять во входной

получается что это работает быстрее, чем RLE за счет того что можно не копировать неизмененные данные. Хотя наверно при небольших размерах разница будет не существенна.

Программный фреймбуфер использовать можно, но это скорее всего усложнит и замедлит декодер.

Как раз вчера сделал декодер RLE в программный фреймбуфер, который потом отсылается в экран. получилось примерно 18 мс на картинку размером 240*240 16битный цвет. причем от самой картинки и степени сжатия не зависит. сделал вывод что основной тормоз это запись в память большого числа данных

получается что это работает быстрее, чем RLE за счет того что можно не копировать неизмененные данные.
Распаковка LZSS и RLE по скорости примерно одинаковы. В обоих случаях в выходной буфер должны попасть все данные, а накладные расходы близки.
Как раз вчера сделал декодер RLE в программный фреймбуфер, который потом отсылается в экран.
RLE последовательно только пишет в выходной буфер и не читает из него, так что можно этот поток без проблем писать как в программный так и в аппаратный фреймбуфер. Для LZSS же нужен промежуточный буфер на размер окна кодирования из которого уже можно гнать поток во фреймбуфер.
получилось примерно 18 мс на картинку размером 240*240 16битный цвет
кстати, при использовании изображения с большим количеством цветов что RLE, что LZSS не смогут нормально сжать. Если фактически использовалась картинка только с несколькими цветами, то выгоднее использовать палитру, т.е. индексы цвета меньшей разрядности. Один раз в исходных данных записать соответствие, а далее, в самой картинке, в качестве цвета уже указывать индекс.

цветов мало задействована, сжалось хорошо ( в среднем в 9.2 раза). Про индексирование цветов думал тоже

 Для LZSS же нужен промежуточный буфер на размер окна кодирования из которого уже можно гнать поток во фреймбуфер.

теперь понял, спасибо.

Все же LZSS несколько тяжелее в распаковке, чем RLE — гораздо больше обращений к памяти. RLE просто пишет в нее непрерывным потоком, а LZSS постоянно прыгает по адресам, копируя отдельные участки.
Да, по обращениям к памяти LZSS конечно тяжелее. Сейчас на быстрых RISC контроллерах это особенно заметно. Раньше на медленных CISC один-два лишних такта на команду не так заметно было.
А в комментарии я имел ввиду что RLE и LZSS (и подобные ему) примерно одинаковы по накладным расходам в сравнении с другими более сложными алгоритмами распаковки.

как человек тоже в свое время написавший утилиты для шрифтов мк сделаю пару замечаний)

размер символов шрифтов не стоит делать больше 255х255 - нет смысла выделять на размер больше 2-х байт, память на мк надо экономить. к сжатию следует подходить разумно в виду низкой производительности процессоров мк и опять же, малого объема памяти. для изображений лучше сделать отдельный формат. хорошим вариантом сжатия изображений является старый добрый PCX - быстро, просто, достаточно эффективно. да и вообще, при работе с мк стоит почаще обращаться к знаниям предков - алгоритмы и форматы 80-х наиболее подходят этому сегменту.

Спасибо за наводку на PCX, будем посмотреть.

память на мк надо экономить

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

к сжатию следует подходить разумно в виду низкой производительности процессоров мк

современные МК достаточно шустрые плюс ускорители есть внутри разные. вон на днях наткнулся на NXP контроллер который аппаратно LZMA декомпрессию умеет.

при работе с мк стоит почаще обращаться к знаниям предков - алгоритмы и форматы 80-х наиболее подходят этому сегменту

ага, как раз и патенты кончили действовать на большую часть алгоритмов. Кстати, получается что младший брат (МК) донашивает за старшим братом (ПК) алгоритмы?

получается что младший брат (МК) донашивает за старшим братом (ПК) алгоритмы?

да, особенно в части выкручиваться с малым объемом озу)

современные МК достаточно шустрые плюс ускорители есть внутри разные

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

LZSS (это модификация LZ77) тоже древний алгоритм. Тот пример сжатия что я приводил (из своих исходников почти 20 летней давности) без проблем работал на 16-битном контроллере на 16 МГц. Сжатие RLE используемое в PCX не так эффективно для мелких черно-белых спрайтов, а остальные возможности PCX для черно-белых изображений и не нужны.

не, безусловно, всё имеет право на жизнь. но всё надо пробовать. хорошее сжатие помимо производительности, так же отнимает и пзу логикой этого сжатия, не везде и не всегда доступна эта роскошь. где-то нужна скорость вывода текста на экран, а где-то можно позволить отрисовываться тексту несколько секунд. при работе с мк надо понимать плюсы и минусы разных форматов. для картинок, думаю, стоит сделать несколько вариантов сжатия - быстрые для распаковки, хорошо жатые, и что-то среднее. тот же PCX можно реализовать с разными вариантами, с горизонтальной и вертикальной последовательностями, например, и пусть каждый сам решает в каком виде хранить конкретную картинку.

ИМХО лучше было бы вместо LZSS кодирования использовать RLE, которое использовалось раньше в формате изображений PCX. И редакторы графики для этого формата наверное ещё можно найти.

Мне тоже недавно захотелось побаловаться с микроконтроллерами. Ардуино и прочая мелочь таки мне скучна в виду слабый возможностей коммуникации, поэтому обратил внимание на ESP32. Поскольку это моё личное время, то трачу его как хочу :) -- написал свою графическую библиотеку с поддержкой разных экранчиков, но откуда брать шрифты, не рисовать же их? Творчески переработал опенсорсную утилиту, которая на основе freetype конвертирует "обычные" шрифты в код на Си. Некоторые идеально прямо вот конвертируются в нужные размеры, но большинство "корявенько", поскольу монохром, а для качества надо бы хотя бы сглаживание. Впрочем, если требуется большой размер символов, то почти любой шрифт подойдёт для конвертации. Вот тут, например, можно видеть результат: https://www.youtube.com/watch?v=9nOHqma-i0U

Хорошая работа и результат неплохой.

Да, насчет "корявости" конвертации, это действительно наблюдается. И именно поэтому, чтобы не делать лишних действий, я добавил в окно импорта своего приложения предпросмотр образца текста. Т.е. наведя мышку на список шрифтов и прокручивая его (или изменяя другие свойства), я тут же вижу как будет выглядеть текст этим шрифтом после импорта.

На счёт визуализации шрифта в исходнике. Вот тут можно видеть что получается: https://github.com/jef-sure/dgx_clock/blob/main/components/dgx/src/fonts/TerminusTTFMedium12.c

На счёт сжатия шрифта. Я пробовал модификацию RLE. Экономия размера до 30%, но разжатие каждого символа довольно дорого получается и требует выделения памяти хотя бы один раз в двойном размере. Поскольку у меня ESP32 и там нет такой уж явной нехватки памяти, то экономия пары килобайт на шрифт не имеет критической важности, а алгоритм упрощается заметно и скорость тоже вырастает.

Мне вот интересно стало, насколько вообще востребовано иметь визуализацию символа шрифта в виде закомментированной ASCII-графики? Просто во время разработки приложения, да и с своих проектах такой необходимости не видел. Пишите или плюсуйте, если это нужная опция. Может быть в будущем она и появится :)

Согласен. Правда, когда я использовал нестандартные символы, то объявлял define с понятным именем для каждого спецсимвола, например

#define FONT_CHAR_H2O ((char)136)

Название символа -- это полезно, конечно, но визуальный контроль в комментариях исходника вреда не несёт, так почему бы и нет? Не настаиваю, я сейчас на другим вопросом думаю -- как бы такой вот алфавит сделать в визуальном редакторе, а не подгонкой координат руками, как я это для десяти цифр сделал: https://www.youtube.com/watch?v=GvBGo-hvBrQ

Сам я больше бэкендер по работе, фронтендом только по случаю занимаюсь, в основном веб, редко приложения для десктопа... Мне нужен (мне нужно сделать) визуальный редактор символов, рисуемых из кубических кривых Безье на поле 100х160 (мой размер из демки) с возможностью добавления полей в разные стороны. Ну это так, лирическое отступление на тему шрифтов и их редакторов. Свой первый редактор матричных шрифтов я делал ещё на MSX-Basic году так в 1990м...

По визуализации - не исключаю, что добавлю такое в генератор кода.

Обновил Lazarus на своей Ubuntu, скачал исходники, компильнул, запустил, работает)) Правда пришлось в юнитах повыпиливать модуль Windows (вроде нигде не используется, а добавлен лазарем по дефолту, т.к. на этот модуль не ругался), ShellAPI и целиком закомментировал функцию FileRemove в u_utilities. Если будет время, может портирую её для убунты, потому как на первый взляд удобная програмка. Писал сто лет назад редактор фонтов на спектруме на смеси ассемблера и бэйсика.

Вот, честно говоря, никак не ожидал, что уже на следующий день после представления приложения найдется человек, настолько увлеченный. Приятно удивлен. Если портируете на Ubuntu, то кроме меня Вам будут благодарны и многие другие люди. Кстати, уже объявлялся человек с похожим предложением. Наверное, надо создавать отдельный репозиторий, чтобы народ видел, кто уже начал что-то делать.

А может кто знает хороший архив шрифтов?

Кстати поделюсь и своим велосипедом https://github.com/lexview/pybmf позволял в свое время обычный ASCII преобразовать в бинарный формат и вставить в код.

Находил коллекции на сайтах посвящённых спектруму. Zx-pk.ru vtrd.in в основном 8*8, 4*8, 6*8

Можно делать векторные шрифты достаточно компактными. Преимущества: лучшая масштабируемость и больше символов в том же объеме (а со сжатием еще больше). Недостаток: сложнее код вывода на экран. Пример реализации (не мой) — библиотека rawdraw на гитхабе. Или старый добрый CHR формат от Борланд С/Паскаля.

Согласен с Вами. Добавить только хочу, что свое приложение делал с упором по максимальную простоту кода, предполагая использование на самых слабых МК. Таких, где только графическая библиотека может "съесть" треть, а то и половину ПЗУ, а ОЗУ в пару килобайт - за счастье (почти все 8-битные МК).

Мой проект начинался с похожего прототипа. :)

Sign up to leave a comment.

Articles