OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 28 Март, 2024 16:25

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




Начать новую тему Ответить на тему  [ Сообщений: 3 ] 
Автор Сообщение
 Заголовок сообщения: Кернинговые пары и вывод текста
СообщениеДобавлено: Среда, 24 Март, 2010 20:23 
Аватара пользователя

Зарегистрирован: Среда, 29 Март, 2006 12:09
Сообщения: 495
Info21 писал(а):
Но нетривиально то, что тут нужен выход на таблицы kerning pairs в шрифтах.

Ничего сложного в парах кернинга нет.

Немного теории (для понимания)
Кернинг — подрезка литер при т.н. высокой печати, когда слова составлялись из отдельных букв и была необходимость изменять «полуапроши» для удобства чтения и равномерного набора. Понятие «кернинговая пара» происходит от того, что значение кернинга (как правило, отрицательное), задается для пары символов (или глифов), например A-V, A-W, L-v и т.д. Кернинг задается для разных кеглей (размер шрифта измеряется в пунктах и называется кегль шрифта) отдельно.
Рядом с кернингом стоит упомянуть о существовании лигатур.

При цифровом наборе понятие осталось.
Далее речь пойдет только о Windows.

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

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

Вывод текста в ББ
Примерно так и организован вывод текста в ББ. Создается таблица шрифтов (кэш шрифтов), для каждого шрифта в кэше создается массив, в который записывается ширина каждого используемого символа и затем эта информация используется для подготовки текста к выводу. Подробности в HostPorts.DrawString и HostPorts.DrawSString.
Я понимаю, почему Оминк приняли такое решение. ББ разрабатывался для использования в Windows 3.1, затем в 95/98. Вариантов вывода текста было, по сути, только два — простой или по отдельным символам (глифам). Второй хоть и визуально дает более привлекательный результат, но гораздо более трудоемок.

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

В Windows 2000 появилась функция, которая сразу организует «правильный» вывод текста. Точнее не вывод, а подготовку к выводу. Функция эта — GetCharacterPlacement. Она получает на вход указатель на структуру данных, в которой есть указатели на несколько массивов. В этих массивах после вызова функции содержится следующая информация:
  • выводимая строка в измененном виде (см. ниже);
  • порядок следования глифов;
  • начальные координаты каждого глифа;
  • координаты каретки возле каждого глифа;
  • список глифов.
После вызова функции указанная структура содержит информацию о порядке следования глифов, которые соответствуют символам входной строки. Глифы располагаются с учетом замены символов лигатурами, с учетом метрик шрифта и с учетом информации о кернинге. Кроме того, учитывается еще и хинтовка шрифтов (т.е. используются квадратичные или кубические сплайны). Все это регулируется флагами на входе в функцию GetCharacterPlacement.

Сам вывод осуществляется функцией ExtTextOut с использованием параметра ETO_GLYPH_INDEX.

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

Что очень важно, функция работает быстро.

Изменения в ББ
Чтобы использовать описанный механизм в ББ придется пересмотреть весь вывод текста. При определении позиции вставки в ББ широко используется функция GetCharWidth32W, определяющую ширину символа вместе с метриками. Придется пересмотреть этот механизм и определять ширину символов и потенциальную позицию каретки с помощью предварительно кэшированной информации, возвращенной фукнцией GetCharacterPlacement. Кроме того, придется рассмотреть вопрос о стыковке view и текста, стыковке текста разного начертания и др.
Но, в очередной раз следует отдать должное Оминк, все очень неплохо локализовано и изменения будут в считанных местах. HostPorts я уже назвал.
Да, важное замечание: GetCharacterPlacement ожидает на вход строку в UNICODE, не в UTF-8!

PS. Если интересно, могу выложить проект (на Delphi), в котором я экспериментировал с функциями GetCharacterPlacement и ExtTextOut. Предваряя вопрос, почему не ББ, скажу, что в Delphi заведомо работающие прототипы функций, мне не хотелось еще и их (прототипы) отлаживать.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Март, 2010 20:28 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Димыч писал(а):
Да, важное замечание: GetCharacterPlacement ожидает на вход строку в UNICODE, не в UTF-8!
UNICODE = UCS2?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Март, 2010 21:29 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Евгений Темиргалеев писал(а):
UNICODE = UCS2?
С некоторых пор уже UTF-16.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 3 ] 

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


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

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


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

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