Отображение текста с помощью Юниписи
Приложения могут использовать функции API Юниписи для поддержки типографии и отображения и редактирования международного текста. Юниписец использует абзац в качестве единицы для отображения текста, а функции Юниписи должны использоваться для всего абзаца.
При использовании Юниписи для отображения текста приложение должно пройти процесс форматирования (макета), обычно используя Uniscribe. Приложение делит текстовый абзац на строки символов с тем же стилем, что и "выполняется". Стиль определяется определенной реализацией, но обычно включает такие атрибуты, как шрифт, размер и цвет. При определении запусков приложение также может применять другие сведения, такие как язык и языковые стандарты, поддерживаемые для использования с лексическими инструментами. Например, приложение может рассматриваться как отдельный запуск прохода в основном на английском тексте, отображаемом на французском языке.
После определения запусков для всех абзацев приложение делит каждый абзац на строки с одинаковым скриптом и направлением ("элементы"). Приложение применяет сведения об элементе для создания запусков, которые являются уникальными в скрипте и направлении и полностью находятся в одном элементе ("диапазоны").
Разбивка элемента в диапазоны несколько произвольно, хотя диапазон должен состоять из одного или нескольких последовательных групп символов, которые называются "кластерами". Для европейских языков кластер обычно соответствует одному символу кодовой страницы или кодовой точке Юникода и состоит из одного глифа. Однако на таких языках, как тайский, кластер представляет собой группирование глифов и соответствует нескольким последовательными символами или точками кода. Например, тайский кластер может содержать консонант, гласный и тоновый знак. Таким образом, что он не разбивает кластеры, приложение обычно должно использовать самые длинные диапазоны, которые он может или использовать собственные лексические сведения для разбиения между диапазонами в местах, которые не находятся в середине кластера.
Когда он определил кластеры в каждом диапазоне, приложение должно определить размер каждого кластера. Он использует Uniscribe для суммирования кластеров для определения размера каждого диапазона. Затем приложение суммирует размеры диапазонов, пока они не переполняют строку, то есть достигает поля. Диапазон, который переполнен линией, делится между текущей строкой и следующей строкой. Для каждой строки приложение создает карту из визуальной позиции в логическую позицию для каждого диапазона. Затем приложение формирует точки кода для каждого диапазона в глифы, которые впоследствии могут размещаться и отображаться.
Приложение выполняет разметку текста только один раз. После этого он сохраняет глифы и позиции для отображения или создает их каждый раз при отображении текста с компромиссом скорости и памяти. Обычное приложение реализует процесс макета один раз, а затем создает глифы и позиции при каждом отображении текста.
Приложение, использующее сложные скрипты , имеет следующие проблемы с простым подходом к макету и отображению.
- Ширина сложного символа скрипта зависит от его контекста. Невозможно сохранить ширину в простых таблицах.
- Разрыв между словами в сценариях, таких как тайский, требует поддержки словаря. Например, между тайскими словами не используется символ разделителя.
- Для отображения требуется переупорядочение арабского, иврита, персидского, урду и других двунаправленных текстовых языков.
- Для простого использования сложных скриптов часто требуется некоторая форма сопоставления шрифтов.
Тот факт, что Юнипись использует абзац в качестве единицы отображения, помогает приложению правильно справиться с этими сложными проблемами скрипта.
Примечание.
Юнипись должна использоваться для всего абзаца, даже если разделы абзаца не являются сложными скриптами.
Как показано в следующей таблице, Uniscribe версии 1.6 или более поздней поддерживает несколько функций, которые используют преимущества тегов OpenType. Их можно заменить соответствующими обычными функциями Юниписи. Как правило, приложения должны работать полностью с функциями из одного набора или другого и не должны пытаться смешивать и сопоставлять функции.
Обычная функция Юниписи | Эквивалентная функция OpenType |
---|---|
ScriptItemize | ScriptItemizeOpenType |
ScriptShape | ScriptShapeOpenType |
ScriptPlace | ScriptPlaceOpenType |
Выложить текст с помощью Юниписи
Приложение может использовать следующие действия для размещения текстового абзаца с помощью Юниписи. В этой процедуре предполагается, что приложение уже разделило абзац на выполнение.
Вызов scriptRecordDigitSubstitution только при запуске или получении сообщения WM_SETTINGCHANGE.
(Необязательно) Вызовите ScriptIsComplex , чтобы определить, требуется ли для абзаца сложная обработка.
(Необязательно) При использовании Юниписи для обработки двунаправленного текста и (или) подстановки цифр вызовите ScriptApplyDigitSubstitution, чтобы подготовить SCRIPT_CONTROL и SCRIPT_STATE структуры в качестве входных данных для ScriptItemize. Если пропустить этот шаг, но по-прежнему требуется подстановка цифр, замените национальные цифры Юникод U+0030 по U+0039 (европейские цифры). Сведения о подстановке цифр см. в разделе "Фигуры цифр".
Вызовите ScriptItemize , чтобы разделить абзац на элементы. Если не использовать Юнипись для подстановки цифр и двунаправленный порядок известен, например из-за раскладки клавиатуры, используемой для ввода символа, вызовите ScriptItemize. В вызове укажите указатели NULL для структур SCRIPT_CONTROL и SCRIPT_STATE. Этот метод создает элементы только с помощью обработчика формирования, а элементы можно переупорядочение с помощью сведений о подсистеме.
Примечание.
Как правило, приложения, работающие только с скриптами слева направо и без подстановки цифр, должны передавать указатели NULL для структур SCRIPT_CONTROL и SCRIPT_STATE.
Слияние сведений об элементе с информацией о выполнении для создания диапазонов.
Вызов scriptShape для идентификации кластеров и создания глифов.
Если ScriptShape возвращает код USP_E_SCRIPT_NOT_IN_FONT или S_OK с выходными данными, содержащими отсутствующие глифы, выберите символы из другого шрифта. Замените другой шрифт или отключите формирование, задав элемент eScript структуры SCRIPT_ANALYSIS, переданной в ScriptShape в SCRIPT_UNDEFINED. Дополнительные сведения см. в разделе "Использование резервного шрифта".
Вызов ScriptPlace для создания расширенных ширин и позиций x и y для глифов в каждом последовательном диапазоне. Это первый шаг, для которого размер текста становится вопросом.
Суммируете размеры диапазона до переполнения строки.
Разорвать диапазон на границе слова с помощью элементов fSoftBreak и fWhiteSpace в логических атрибутах. Чтобы разорвать один символьный кластер от выполнения, используйте сведения, возвращаемые вызовом ScriptBreak.
Примечание.
Определите, должна ли первая кодовая точка диапазона быть точкой останова слова, так как для последнего символа предыдущего диапазона требуется. Например, если один диапазон заканчивается запятой, рассмотрите первый символ следующего диапазона, чтобы быть точкой останова слова.
Повторите шаги 6–10 для каждой строки абзаца. Однако при нарушении последнего запуска в строке вызовите ScriptShape , чтобы изменить оставшуюся часть выполнения в качестве первого запуска в следующей строке.
Отображение текста с помощью юниписи
Приложение может использовать следующие действия для отображения текстового абзаца. В этой процедуре предполагается, что приложение уже изложило текст и не сохранило глифы и позиции из процесса макета. Если скорость является проблемой, приложение может сохранить глифы и позиции из процедуры макета и начать с шага 2 в процедуре отображения.
Примечание.
Приложение может опустить шаг 2, если текст не содержит символов из скриптов справа налево, не содержит двунаправленных символов управления и использует уровень внедрения слева направо.
Для каждого запуска выполните следующие действия:
- Если стиль изменился с момента последнего запуска, обновите дескриптор до контекста устройства, отпустив и снова получив его.
- Вызов scriptShape для создания глифов для выполнения.
- Вызов ScriptPlace для создания расширенной ширины и смещения x,y для каждого глифа.
Выполните следующие действия, чтобы установить правильный визуальный порядок для выполнения в строке:
- Извлеките массив двухнаправленных уровней внедрения, по одному на диапазон. Уровень внедрения предоставляется (SCRIPT_ITEM) si. (SCRIPT_ANALYSIS) a. (SCRIPT_STATE) s.uBidiLevel.
- Передайте этот массив в ScriptLayout , чтобы создать карту визуальных позиций логическим позициям.
(Необязательно) Чтобы оправдать текст, вызовите ScriptJustify или используйте специализированные знания о тексте.
Используйте логическую карту для отображения запусков в визуальном порядке. Начиная с левого конца строки вызовите ScriptTextOut , чтобы отобразить выполнение, заданное первой записью на карте. Для каждой последующей записи в карте вызовите ScriptTextOut , чтобы отобразить указанный запуск справа от ранее отображаемого запуска.
Если опущен шаг 2, начните в левом конце строки и вызовите ScriptTextOut , чтобы отобразить первый логический запуск, а затем отобразить каждый логический запуск справа от предыдущего запуска.
Повторите описанные выше действия для всех строк в абзаце.
См. также