30.03.2011: Для Колибри собраны и портированы библиотеки FreeType 1.3 и FreeType 2.4.4.
Подробности, файлы и самые свежие новости - на последних страницах темы.
Выкуривание мануалов по SVG, TTF и другим полезным вещам помогло мне понять, как устроены эти самые шрифты.
Между делом были написаны программы для вывода глифов из SVG-шрифтов и конвертер из SVG в VFO (формат векторных шрифтов библиотеки vectors.obj), обе написаны кое-как и на javascript.
Сегодня взялся переносить код из JavaScript на Си (к сожалению, знаниями ассемблера, достаточными для написания библиотеки, не обладаю, но надеюсь, что кто-нибудь, да поможет...когда я отлажу код так, что он будет работать более предсказуемо, чем сейчас). Как оказалось, переносить код с JS на C - одно удовольствие, знай себе function на void заменяй...
Итак, в прикрепленных архивах:
1) Шрифт DejaVu Mono в файле fnt_1.vfo и программа для его просмотра fn.kex (на самом деле эта программа написана IgorA, я просто немножко ее исправил, чтобы она открывала большие файлы шрифтов). Если мне не изменяет память, в файле шрифта все русские и английские буквы, а так же цифры и специальные символы. Если нет, значит, в каком-то другом архиве у меня на диске они есть К сожалению, контуры шрифтов отображаются не всегда правильно, плюс контуры глифов разрываются, и заливать их невозможно
2) Программа на С fonter.kex, которая выводит контур глифа @ (пока что это hardcoded) из набора DejaVu Mono. Глиф отрисовывается в памяти, и лишь затем отрисовывается на экран (хотя сделано это криво). Кривые Безье и линии строятся по правильным формулам, но для них не рассчитывается необходимое количество точек, поэтому при большом масштабе наблюдаются разрывы в линиях. Алгоритм поддерживает и заливку, но я убрал эту функцию потому, что пока что не придумал, как определять точку, к которой применять заливку контура. Для глифа @ она должна находиться внутри части глифа "а", чтобы правильно залить его. Для заливки используется обход в ширину (в алгоритме имеется один момент, который стоит улучшить).
Ах да, шрифты, отрисованные программой fn.kex и залитые простой заливкой, выглядят вот так:
Вот собственно и всё пока что. Как только код будет приведен в состояние "не очень стыдно показывать", так я его сразу выложу.
upd. Так же ковыряюсь в алгоритмах сглаживания. Если немножко подумать, можно реализовать субпиксельное сглаживание. Судя по найденным материалам, это не сложно. Интересная особенность: мне кажется, что глиф гораздо лучше выглядит, если его растеризовать в памяти несколько крупнее, чем нужно, а затем уменьшить с билинейным сглаживанием.
[/hr]
FreeType2 для Колибри (масштабируемые векторные шрифты)
-
Last edited by SoUrcerer on Wed Mar 30, 2011 10:43 pm, edited 2 times in total.
А вот и вариант с заливкой. Когда отрисовывается глиф большого размера, заметно мерцание (в qemu по крайней мере).
Сейчас я работаю с массивом целых чисел для заливки, и вывожу его попиксельно. Если я заменю его на область памяти RGB, и буду выводить изображение через putimage, скорость работы повысится? Или это фантастика?
Сейчас я работаю с массивом целых чисел для заливки, и вывожу его попиксельно. Если я заменю его на область памяти RGB, и буду выводить изображение через putimage, скорость работы повысится? Или это фантастика?
- Attachments
-
-
fonter.kex (3 KiB)Downloaded 419 times
-
Sorcerer
Теоретически должно - ты исключишь кучу переключений из Ring3 в Ring0, к тому же записывать данные большим куском в видеопамять все-же выгодней.
Все зависит от того через какую функцию Колибри реализован putimage.
Теоретически должно - ты исключишь кучу переключений из Ring3 в Ring0, к тому же записывать данные большим куском в видеопамять все-же выгодней.
Все зависит от того через какую функцию Колибри реализован putimage.
Через 7ю...
В Virtualbox мерцание практически исчезло, а в qemu, кажется, стало еще сильнее мерцать при перерисовке.
Попробую загнать весь шрифт в память и посмотреть, что из этого получится. А за одно допилить заливку как положено (а точнее, сделать заново)
В Virtualbox мерцание практически исчезло, а в qemu, кажется, стало еще сильнее мерцать при перерисовке.
Попробую загнать весь шрифт в память и посмотреть, что из этого получится. А за одно допилить заливку как положено (а точнее, сделать заново)
А если через 65ю выводить? Может стать быстрее или нет? Прозрачность не поддерживается, как я понимаю?
65 функция не будет быстрее. Она просто более гибкая в использовании.
Прозрачность придется обеспечить самому. Используй ф.36 и накладывай поверх полученного свой шрифт и выводи ф.7 или ф. 65.
Прозрачность придется обеспечить самому. Используй ф.36 и накладывай поверх полученного свой шрифт и выводи ф.7 или ф. 65.
Sorcerer
Неужели у нас всё-таки будут векторные шрифты?
Неужели у нас всё-таки будут векторные шрифты?
Запустилось (медленно), и отобразился только значок @. Как мне кажется, он довольно-таки неряшливый. Что делать, чтобы отобразилось что-то ещё?
Sorcerer
Есть подозрение, что расчет значений имеет недостаточную точность - маленькие символы сливаются. Производится ли округление значений по математическим правилам или дробная часть координаты отбрасывается?
Есть подозрение, что расчет значений имеет недостаточную точность - маленькие символы сливаются. Производится ли округление значений по математическим правилам или дробная часть координаты отбрасывается?
Пока что программа не выводит больше никаких символов. Все глифы TrueType и SVG-шрифтов выводятся при помощи кривых Безье первого и второго порядка, соответственно, нет никакой разницы, какой из них выводить для проверки работоспособности алгоритма (а это пока что лишь демка). Остальные символы можно посмотреть с помощью программы fn.kex из другого архива (более того, этот шрифт в принципе можно использовать в своих программах, но пока что не стоит).Атауальпа wrote:Запустилось (медленно), и отобразился только значок @. Как мне кажется, он довольно-таки неряшливый. Что делать, чтобы отобразилось что-то ещё?
Маленькие символы сливаются не из-за алгоритма рисования, а из-за алгоритма заливки - в текущем варианте он работает корректно только в том случае, если толщина самой маленькой части глифа (ширина черт в букве, грубо говоря) больше пяти пикселей. Ума не приложу, как реализовали заливку в FreeType, и попробую почитать. Округление производится правильно, проверено в том числе в JS - там глифы отрисовываются точно так же, "заборчиком" (грабельками, да).Mario wrote: Есть подозрение, что расчет значений имеет недостаточную точность - маленькие символы сливаются. Производится ли округление значений по математическим правилам или дробная часть координаты отбрасывается?
Причина некрасивости глифов очень простая. Какие бы шрифты не были хорошие, они даже в начальном варианте моей демо-программы отрисовываются в 1/32 от оригинального глифа. Вот и получаются лесенки и заборчики вместо гладких контуров. Судя по наблюдениям за программой просмотра изображений Gnome, SVG растеризуются в разрешении, заданном в параметрах документа, а затем масштабируются с линейной интерполяцией (если она включена в параметрах). Результат выглядит лучше, чем просто вывод глифа в масштабе. Возможно, там используются еще какие-то методы сглаживания.
Что касается заливки шрифтов небольших размеров (шириной менее 20 пикселей), то в "больших" системах для этого используют хинтинг - нечто вроде отдельных начертаний для маленьких размеров. Замтетить это можно на разнице между Times 8 и 14 кегля, например. Технология патентованная, и поэтому FreeType 2 генерирует начертания небольшого кегля на лету, насколько я знаю. Как во FreeType 1 - не знаю, но мне почему-то кажется (судя по тем демкам, что я видел), что там шрифт растеризуется в большом кегле, а затем масштабируется со сглаживанием. Сейчас я эксперементирую именно с этим направлением.
Почитал документацию к FreeType 1.3 и исходные коды. Много думал. Если документация к FreeType 2 настолько же подробна, но при этом завершена, то веселые выходные мне обеспечены - буду разбираться и проверять, что и как.
Оказывается, все очень просто и удобно. Во-первых, символ сразу отрисовывается с анти-алиасингом с палитрой из 5 оттенков. Так удобнее.
Во-вторых, для того, чтобы отрисовывать небольшие кегли, имеется специальный алгоритм под названием Drop Out (который в руководстве к FT 1.3 не освещен, только вдумчивое чтение кодов).
В-третьих, заливка реализуется одновременно с растеризацией методом "веника". Делается это так (если простым языком): все элементы глифа (линии и кривые Безье) разбиваются на восходящие и нисходящие. Для определенности считаем, что первая встреченная нами линия - восходящая. Все. Теперь остается лишь залить те участки, которые находятся между восходящими и нисходящими линиями. Как там насчет внутренних пустот в контурах - не разбирался, но это дело времени. Всем, кому интересна реализация хороших векторных масштабируемых шрифтов, предлагаю взглянуть на прилагаемый файл.
Почему не портировать сам freetype? Потому что, признаюсь, знаний на это у меня не хватит. Те, у кого знаний хватило бы, заняты другими, более полезными делами. А красивые буковки, чтобы клиентов не отпугивали, хочется наверное всем. Вдобавок написать свою миниатюрную библиотеку - это как минимум интересно.
*ушел учить матчасть и эксперементировать на лисах с надеждой вернуться в ближайшее время с рабочими результатами, и в случае надобности получить помощь сообщества*
Оказывается, все очень просто и удобно. Во-первых, символ сразу отрисовывается с анти-алиасингом с палитрой из 5 оттенков. Так удобнее.
Во-вторых, для того, чтобы отрисовывать небольшие кегли, имеется специальный алгоритм под названием Drop Out (который в руководстве к FT 1.3 не освещен, только вдумчивое чтение кодов).
В-третьих, заливка реализуется одновременно с растеризацией методом "веника". Делается это так (если простым языком): все элементы глифа (линии и кривые Безье) разбиваются на восходящие и нисходящие. Для определенности считаем, что первая встреченная нами линия - восходящая. Все. Теперь остается лишь залить те участки, которые находятся между восходящими и нисходящими линиями. Как там насчет внутренних пустот в контурах - не разбирался, но это дело времени. Всем, кому интересна реализация хороших векторных масштабируемых шрифтов, предлагаю взглянуть на прилагаемый файл.
Почему не портировать сам freetype? Потому что, признаюсь, знаний на это у меня не хватит. Те, у кого знаний хватило бы, заняты другими, более полезными делами. А красивые буковки, чтобы клиентов не отпугивали, хочется наверное всем. Вдобавок написать свою миниатюрную библиотеку - это как минимум интересно.
*ушел учить матчасть и эксперементировать на лисах с надеждой вернуться в ближайшее время с рабочими результатами, и в случае надобности получить помощь сообщества*
- Attachments
-
-
raster.txt (22.46 KiB)Downloaded 453 times
-
Вот так скажет человек не особо раздумывая и все попал в списки цитат навечно.Sorcerer wrote:А красивые буковки, чтобы клиентов не отпугивали
Mario, просто очень уж фраза подходит к ситуации... И ничего не поделать с этим.
Для интересующихся шрифтами добавляю еще пару ссылочек. Никаких алгоритмов, только общие слова, но для тех, кто действительно заинтересован в своей реализации, этого, думаю, более чем достаточно
Drop out control: устранение потерь, которые происходят когда ширина свободного места между элементами обводки становится тоньше 1/2 пиксела
Хинтинг и пиксельная подгонка
Антиалисинг
Для интересующихся шрифтами добавляю еще пару ссылочек. Никаких алгоритмов, только общие слова, но для тех, кто действительно заинтересован в своей реализации, этого, думаю, более чем достаточно
Drop out control: устранение потерь, которые происходят когда ширина свободного места между элементами обводки становится тоньше 1/2 пиксела
Хинтинг и пиксельная подгонка
Антиалисинг
Кажется, начинаю понимать. SVG шрифты, которые я использовал прежде всего, не содержат никакой информации о хинтинге, даже минимальной, позволяющей выравнивать глифы по пикселам. Поэтому отображение кеглей небольшого размера для SVG практически невозможно без "искусственного" сглаживания, которое работает медленно и дает плохой результат.
Значит, для хороших результатов желательно понять формат TrueType или OpenType. Ну или хотя бы реализовать антиалиасинг для SVG.
Разработка алгоритма в процессе.
Значит, для хороших результатов желательно понять формат TrueType или OpenType. Ну или хотя бы реализовать антиалиасинг для SVG.
Разработка алгоритма в процессе.
Нелепая ситуация. Следуя инструкциям install.any из freetype собрал freetype.a, все делалось с мейкфайлами, аналогичными тем, которые собирают libc и другие библиотеки. По именам экспортируемых функций вроде бы все, что должно быть в библиотеке, в ней есть.
А как проверить ее работоспособность - не знаю. Прилагаемые к freetype тесты собираться отказываются (что в принципе понятно - они заточены для dos или x11, на выбор).
В общем, прилагаю то, что получилось. Если кто-то знает, как проверить, все ли собралось как положено - буду благодарен за советы. Пока что просто читаю руководство, довольно много информации, и воспринять ее правильно за несколько часов очень трудно.
upd:
Пишу простую программу для проверки того, слинкуется ли библиотека.
main.c
Makefile
Файл freetype.a лежит в $(MENUETDEV)/lib, make выдает:
Что-то еще нужно, чтобы библиотека находилась?:(
А как проверить ее работоспособность - не знаю. Прилагаемые к freetype тесты собираться отказываются (что в принципе понятно - они заточены для dos или x11, на выбор).
В общем, прилагаю то, что получилось. Если кто-то знает, как проверить, все ли собралось как положено - буду благодарен за советы. Пока что просто читаю руководство, довольно много информации, и воспринять ее правильно за несколько часов очень трудно.
upd:
Пишу простую программу для проверки того, слинкуется ли библиотека.
main.c
Code: Select all
#include <menuet/os.h>
#include <stdio.h>
#include <freetype/freetype.h>
TT_Engine engine;
void main(void){
TT_Init_FreeType(&engine);}
Code: Select all
OUTFILE = demo
OBJS = main.o
LIBS = -lfreetype
include $(MENUETDEV)/makefiles/Makefile_for_program
Code: Select all
mld demo main.o -lfreetype -n -Map demo.map
ld: cannot find -lfreetype
- Attachments
-
-
freetype.a.7z (43.65 KiB)Downloaded 404 times
-
Who is online
Users browsing this forum: No registered users and 12 guests