OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 19 Март, 2024 13:01

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 114 ]  На страницу Пред.  1, 2, 3, 4, 5, 6  След.
Автор Сообщение
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Суббота, 14 Декабрь, 2013 13:10 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Да.
Библиотека получает от ОС информацию о глифах, которую затем можно использовать как набор векторов. Соответственно, можно выполнять все операции, которые применимы к векторам.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Среда, 25 Декабрь, 2013 16:34 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Загружены файлы, достаточные для работы простыми (однопиксельными) фигурами.
https://github.com/dmitrys99/BBAGG
Веду работу над механизмом отображения шрифтов/букв.
Проведена работа по исключению избыточного импорта SYSTEM.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Среда, 25 Декабрь, 2013 20:53 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
AggTest не компилируется из-за AggWin32Bmp.
AggWin32Bmp не компилируется из-за отсутствия AggBasics.agg_getbyte.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Четверг, 26 Декабрь, 2013 04:14 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Пётр Кушнир писал(а):
AggTest не компилируется из-за AggWin32Bmp.
AggWin32Bmp не компилируется из-за отсутствия AggBasics.agg_getbyte.

Fixed, commited.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Четверг, 26 Декабрь, 2013 20:37 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
Работает.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Четверг, 26 Декабрь, 2013 21:11 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Скачал, скомпилировал, получил t.bmp


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Воскресенье, 29 Декабрь, 2013 16:31 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Обсуждение Anti-Grain для OpenGL сборки перенесено: viewtopic.php?f=23&t=4906&p=84801#p84801


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Понедельник, 30 Декабрь, 2013 07:58 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
http://oberoncore.ru/projects/bbagg
Добавил карточку проекта.
Пока пусто, по мере работы буду наполнять.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Понедельник, 30 Декабрь, 2013 10:09 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
По мотивам вот этого обсуждения сделал небольшой генератор, который складывает все предварительно инициализированные массивы в один модуль.
См. AggData.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Вторник, 14 Январь, 2014 04:54 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Столкнулся с серьезными различиями в подходах к обработке массивов в AGG, AggPas и ББ.
Работа застопорилась на модулях обработки шрифтовой информации, их придется перепроектировать, чтобы реализовать на ББ; в коде на С++ используются шаблоны, а в коде на Паскале — большое количество нетипизированного копирования в памяти.
Поэтому в качестве временного решения я делаю dll, которая фактически реализует интерфейс Ports.Rider, чтобы подменить HostPorts.

Код библиотеки опубликую чуть позже, а пока такой вопрос, коллеги:
В модуле Ports есть несколько констант, определяющих цвета, например red, grey75 и др. Значения цвета для этих констант состоят из трех (младших) байт четырехбайтного значения. Старший байт может быть использован для прозрачности. Для того, чтобы использовать прозрачность (а она иногда бывает нужна), есть несколько путей:

  • Изменить значения цветов, заданные в Ports и установить старший байт в 0FF.
  • Завести переменную Ports.useOpacity, которая позволит интерпретировать значение прозрачности цвета (это сохранит значения для цветов в неизменном виде).
  • Совсем не использовать понятие прозрачности и не менять интерфейсы ББ, а то, что может потребоваться в графическом движке для реализации прозрачности, оставить в HostPorts.

Собственно вопрос в том, как поступить с графической подсистемой базовой версии?

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Вторник, 14 Январь, 2014 09:38 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
Димыч писал(а):
Для того, чтобы использовать прозрачность (а она иногда бывает нужна), есть несколько путей:

Изменить значения цветов, заданные в Ports и установить старший байт в 0FF.
Завести переменную Ports.useOpacity, которая позволит интерпретировать значение прозрачности цвета (это сохранит значения для цветов в неизменном виде).
Совсем не использовать понятие прозрачности и не менять интерфейсы ББ, а то, что может потребоваться в графическом движке для реализации прозрачности, оставить в HostPorts.
Есть еще один путь, я его рассмотрел в статье http://obertone.ru/doku.php?id=bbextendnohost
Используя подобный способ минимального расширения можно избавиться от необходимости ломать совместимость.
А цвета с нулевым значением прозрачности использовать только в режиме совместимости.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Среда, 22 Январь, 2014 07:24 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Работа продолжается. Поскольку я хочу сохранить интерфейсы по возможности нетронутыми, реализация процедуры Rider.MarkRect вылилась в микрорасследование :)

Во-первых, в процедуре не используется параметр show. Сначала, видимо, хотели использовать одну технику для создания масок, но потом стали использовать голый WinAPI и отказались от этой затеи. Хозяйке на заметку.

Во-вторых, режимы Ports.invert и Ports.hilite обрабатываются одинаково, т.е. выполняется инвертирование заданного прямоугольника.

Но самое интересное — это реализация заливки прямоугольника с помощью шаблонов Ports.dimXX, где XX это {25, 50, 75}.

Пометка прямоугольника реализована с помощью функции WinApi.PatBlt, которая получает на вход прямоугольник и шаблон, а также номер одной из композитных функций, в случае MarkRect это «xor».

Сама по себе идея композитных функций проста — берется три изображения: исходное, шаблон и их функция, и к ним в разном порядке применяются битовые операции. Тема эта в MSDN хоть и раскрыта, но все же весьма туманна. Сначала я пошел по тому же пути. Попытался разобраться, как происходит применение функций и к чему, с тем, чтобы получить тот же функционал, но уже средствами AGG.

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

Что имеем?
Имеем битовую карту, о построении изображения на которой в общем случае мы ничего не знаем. Делаю эту пометку специально, поскольку если бы мы могли перестроить изображение по требованию, можно было бы не модифицировать битовую карту, а накладывать поверх изображения маску и, когда нужно убрать пометку (т.е. когда MarkRect вызывается повторно с теми же параметрами), просто перерисовывали бы изображение. Можно сохранять изображение в промежутках, но это требует определенных ресурсов. Кроме того, это не избавляет от того, что изображение может быть модифицировано после наложения маски.

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

Это вылилось в такую реализацию.

Инверсия прямоугольника достигается путем инверсии составных частей пикселей исходного изображения, т.е. каждого элемента триады BGR (в Windows используется именно такой порядок следования байт в пикселе).

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

В HostPorts используются 4 маски. Это упомянутые уже dimXX и focusPat, которая представляет собой косую штриховку и используется в модулях HostMechanisms и OleClient.

На стороне ББ из библиотеки AggLib вызываются две функции invert_rect и xor_rect, которые реализуют и реализуют функционал MarkRect. Можно было бы полностью реализовать MarkRect на стороне AggLib, но мне хочется сохранить возможность контролировать цвет(а) масок, поэтому MarkRect переписывается средствами BB.

---

Сейчас все принципиальные вопросы разрешены и я занимаюсь доводкой библиотеки LibAgg до состояния, в котором ее уже можно будет опубликовать. После этого буду делать подмену HostPorts и HostFonts.

В первом модуле от WinAPI осталось, по сути, только вызов копирования битовой карты на HWND, во втором практически ничего, все делается средствами LibAgg.

Перенос LibAgg на другую платформу (ОС) сведется к следующим модификациям:
* изменение порядка следования цветов в пикселе;
* изменение механизма отображения битовой карты на экране (сейчас это делается средствами WinAPI).

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Среда, 22 Январь, 2014 15:17 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
Технически, в OpenGL для MarkRect есть свой stipple с паттернами и расцветкой.
http://www.opengl.org/sdk/docs/man2/xht ... tipple.xml так что если целевая платформа будет OpenGL то можно не нагружать Agg лишним. Но в целом норм опыт.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Понедельник, 27 Январь, 2014 17:05 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Добрый вечер, коллеги!

Публикую библиотеку AGGLib, предназначенную для подмены HostPorts и HostFonts.

Код библиотеки доступен по адресу https://github.com/dmitrys99/agglib

Компилированная версия: http://pro.dimina.ru/dl/agglib.zip. Внутри dll и языковая привязка, а также тестовый модуль.

Лицензия BSD.

Использование и тестирование:
DLL кладется рядом с blackbox.exe, запускаются модули AggLib и AggTest3. В AggTest3 имеется единственная экспортированная процедура tst1, которая генерирует *.bmp-файл.

Сейчас библиотека в состоянии уже стабильно работающем, поэтому начинаю подмену модулей.

Обращаю ваше внимание, что почти все процедуры используют координаты с плавающей запятой (кроме Scroll); все координаты в пикселях.

Пока не реализованы процедуры отображения поверхности на HDC и draw_path. Первая будет сделана в процессе подмены подсистемы Host, вторая будет сделана по аналогии с draw_line, пока просто опущена.

За качество C++ кода не ручаюсь, я в нем сильно не разбираюсь.

Очень интересно оказалось реализовывать работу с текстами, про это напишу отдельно, там еще одно «расследование» получилось, пришлось немного модифицировать AGG.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Вторник, 28 Январь, 2014 20:20 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Ну слушайте, универсальные единицы — это что-то :?
Для того, чтобы добраться до размера шрифта в точках нужно через такое продраться!

Всю логику HostFonts придется переписывать из-за этих единиц...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Среда, 29 Январь, 2014 01:21 

Зарегистрирован: Суббота, 16 Февраль, 2008 07:58
Сообщения: 358
Откуда: Россия, Стерлитамак
Может есть возможность хотя бы схематично описывать, как сейчас реализовано, и как планируешь сделать?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Среда, 29 Январь, 2014 06:36 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
adva писал(а):
Может есть возможность хотя бы схематично описывать, как сейчас реализовано, и как планируешь сделать?

В условиях ограничения ресурсов хочется побольше сделать :)

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

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

Началось все с того, что, в ББ, как и в других программах для Windows, ужасная графика. Связано это, в первую очередь, с тем, что таковы реалии WinAPI. Для получения визуально привлекательного результата штатными средствами Windows нужно очень постараться. До появления GDI+ программирование векторной графики Windows было нетривиальным занятием. Связано это, на мой взгляд, с необходимостью для MS реализовывать универсальное решение. Большинство графических пакетов, вроде Aldus (Adobe) PageMaker, так или иначе использовали собственные графические движки.

Тем не менее, для программ, в которых графика не является основным назначением, выбора не было, приходилось пользоваться WinAPI.

Соответственно, для работы с графикой ББ опирается на WinAPI, конкретнее, на систему GDI.
Как она работает?

(знающие люди могут меня покритиковать, объяснение будет очень схематичным)

Каждое окно в системе имеет т.н. контекст устройства, или device context, он же DC. Можно представить DC как структуру данных, содержащих ссылки на:

* битовую карту окна (она может быть не одна);
* перо для рисования линий;
* кисть для заливок;
* регион отсечения (не обязательно прямоугольный);
* режимы отображения и преобразования координат;
* выбранный шрифт;
* и т.д.

Подробности можно посмотреть в MSDN.

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

Можно создавать заэкранные контексты устройств (без привязки к окнам), равно как и заэкранные битовые карты.

Вернемся к ББ.

Для целей работы с графикой подсистема HostPorts реализует операции с битовыми картами. Причем, эти битовые карты могут как быть связаны с окнами, там и могут быть оделены от окна (заэкранные карты).

Каждому порту сопоставляется контекст устройства (при создании или инициализации), затем все операции уже проводятся на этом контексте устройства. Если контекст устройства связан с окном, то манипуляции на контексте сражу отображаются в окне. Но это не обязательно.

В чем состоит суть тех изменений, которые я провожу?

Я написал библиотеку, которая моделирует контекст устройства. Благодаря простоте набора графических операций в ББ, эта работа относительно несложная.

Итак, с помощью библиотеки AGG я сделал библиотеку, которая реализует операции, за которыми HostPorts обращается к WinAPI, это, например, draw_line или invert_rect. Эти операции производят манипуляции на битовой карте, не связанной с DC. И если в случае с WinAPI все манипуляции с контекстом сразу могут быть отображены на контексте, то в моем случае все сводится копированию битовой карты из памяти на контекст.

Конечно, от WinAPI совсем отказаться не получится, мы же в Windows всё-таки работаем, да это и не нужно. Но фактически все операции сводятся к инициализации собственной битовой карты и последующему копированию ее на DC. В теории все просто :)

Поэтому текущая работа по подмене HostPorts состоит в том, чтобы заменить процедуры, обращающиеся к WinAPI (и вспомогательные) на собственные и изменить цепочку вызовов, обрабатывающих обновление окна так, чтобы использовалась битовая карта не из контекста устройства.

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

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Среда, 29 Январь, 2014 10:16 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
А битмап у вас представлен в платформонезависимом виде или тоже в виде дескриптора (со скрытой структурой)?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Среда, 29 Январь, 2014 16:31 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Графика со сглаживанием

То, о чем пойдет речь дальше, хорошо иллюстрирует эта картинка:
Вложение:
Комментарий к файлу: С сайта antigrain.com
agg1_01.jpg
agg1_01.jpg [ 36.86 КБ | Просмотров: 12177 ]


В GDI линии рисуются без сглаживания. Рисование происходит с помощью алгоритма Брезенхема или его модификаций. Т.е. рассчитывается теоретический путь линии из точки (x0, y0) в точку (x1, y1) и, перо, пробегая по этому пути, закрашивает пиксели, в которых путь проходит больше некоей величины (в разных реализациях этого алгоритма используются разные метрики — угол прохождения, длина отрезка и т.д.)

В результате получается ступенчатая линия (aliased line или grained line). Интересно, что слово aliased в техническом словаре переводится как «с побочными эффектами», т.е. речь идет о зернистой линии (grained) или линии с изъянами.

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

Но качество экранов еще не скоро дорастет до качества принтеров. Впрочем, в этом направлении сделаны большие сдвиги (привет Retina).

Вернемся к линиям. Для исправления этой ситуации придумано множество разных техник.

Одна из техник сглаживания при рисовании линий — алгоритм Ву. Как и для Брезенхема, рассчитывается теоретическая линия и для пикселей меняется яркость в зависимости от того, на каком расстоянии находится пиксель от линии. Получается, что «зубцы» никуда не исчезают, но их хуже видно. Линия более сглаженная.

Развитием этой техники стало субпиксельное сглаживание.
Дело в том, что на изменение цвета и на изменение яркости наше зрение реагирует по разному. Поэтому если просто изменить значение яркости пикселя, то получится, что он изменит и цвет. Это приводит с тому, что линии могут снова стать зубчатыми, но «зубчатость» проявляется в цвете граней и линии становятся неряшливыми. Для этого стали менять не только яркость пикселей, но и учитывать то, как глаза реагируют на цвета. При увеличении становится заметно, что линия, сглаженная субпиксельным сглаживанием (а это все шрифты в Windows, см. ClearType, в OS X, см. Quartz, в *nix, см. FreeType), по краям разноцветная.

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

Есть еще полноэкранное сглаживание (в противовес сглаживанию примитивов), но это выходит за рамки настоящей работы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Anti-Grain для Ports
СообщениеДобавлено: Среда, 29 Январь, 2014 16:37 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Пётр Кушнир писал(а):
А битмап у вас представлен в платформонезависимом виде или тоже в виде дескриптора (со скрытой структурой)?
Из библиотеки возвращаю указатель на структуру. Его можно воспринимать как дескриптор.
Внутри же битмап находится в платформонезависимом виде, в виде массива трехбайтных пикселей (BGR).
В принципе, если сильно надо будет, массив можно будет вытащить наружу. Но пока я не видел необходимости.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 114 ]  На страницу Пред.  1, 2, 3, 4, 5, 6  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB