Как проверить кириллические диапазоны OS/2 после экспорта шрифта

После экспорта шрифт может содержать кириллические глифы, но сообщать о поддержке Unicode-диапазонов неверно. Проверяйте два слоя отдельно: таблица cmap связывает кодовые точки со знаками, а поля ulUnicodeRange и ulCodePageRange таблицы OS/2 описывают заявленное покрытие для программ, которые используют эти признаки. Исправление флагов не добавит отсутствующие буквы, а правка карты символов сама по себе не обновит диапазоны.
Две разные проверки: карта символов и флаги покрытия
Когда пользователь вводит «Ж» и получает пустой квадрат, первым делом проверяют соответствие Unicode-кодовой точки и глифа в cmap. Это фактическое отображение: для нужного символа должна существовать запись, ведущая к правильному глифу. Но некоторые утилиты анализа, каталогизаторы и механизмы выбора шрифта также смотрят на диапазоны в OS/2. Это декларация о том, какие символы или кодовые страницы шрифт считает функционально поддерживаемыми.
Для кириллицы особенно полезно помнить, что диапазон основного блока — U+0400–U+04FF — задаётся битом 9 в маске ulUnicodeRange. В тот же бит спецификация включает Cyrillic Supplement, Cyrillic Extended-A и Extended-B, добавленные в последующих редакциях. Это укрупнённая метка диапазона, а не перечень всех кодовых точек, реально покрытых файлом. Поэтому установленный флаг не доказывает, что в cmap есть, например, «Ё», «ґ» или конкретная редкая буква.
И обратная ситуация возможна: карта уже содержит кириллические буквы, но флаг диапазона не выставлен. В такой ситуации непосредственный набор текста может работать, а программа, опирающаяся на декларацию покрытия, способна показать неполные сведения о шрифте или выбрать другой вариант. Microsoft описывает оба поля как независимые признаки покрытия и подчёркивает, что функциональность диапазона определяет разработчик шрифта. Это повод сверить декларацию с реальным назначением гарнитуры, а не включать все битовые маски подряд.
Что именно лежит в таблице OS/2
Таблица OS/2 хранит метрики и параметры, нужные приложениям для выбора и отображения начертания. В контексте покрытия важны два набора полей. Четыре 32-битных значения ulUnicodeRange1–4 образуют 128-битную маску блоков Unicode. Два 32-битных поля ulCodePageRange1–2 образуют 64-битную маску кодовых страниц. Это разные классификации: первая называет диапазоны Unicode, вторая — наборы символов, связанные с кодовыми страницами Windows.
Для русскоязычного проекта часто встречается кодовая страница Windows Cyrillic; в маске ulCodePageRange ей соответствует бит 2. Не смешивайте этот признак с битом 9 ulUnicodeRange: номер относится к другой маске и означает другую вещь. Если ваша гарнитура рассчитана на русский язык, но не предназначена для всех символов целой кодовой страницы, отметку нельзя автоматически считать подтверждением полного набора. Сверьте фактическую карту и намеренно поддерживаемые знаки.
У поля Unicode-диапазона есть исторические нюансы: состав некоторых битов расширялся вместе с версиями спецификации, а часть дополнительных диапазонов была добавлена позднее. Файл с более старой версией OS/2 может встретиться у инструмента, который иначе трактует отдельные расширенные наборы. Для обычной современной кириллицы центральной проверкой остаётся бит 9; при редких символах сверяйтесь с текущей спецификацией и тестируйте целевые приложения.
Как проверить экспортированный файл по шагам
1. Зафиксируйте ожидаемое покрытие
Перед просмотром бинарного файла запишите, для кого сделан шрифт и какие символы обязательны. Для базового русского текста это кириллица, пробел, цифры, распространённая пунктуация и знаки, которые реально встречаются в образце. Если проект включает украинский, белорусский, сербский или расширенную кириллицу, перечислите дополнительные буквы отдельно. Такой список не даст спутать «флаг кириллицы выставлен» с «все нужные знаки присутствуют».
2. Проверьте фактические символы в cmap
Откройте экспортированный TTF или OTF инспектором шрифта, который показывает таблицы cmap, либо запустите ttx -t cmap имя-файла.ttf из FontTools. Найдите тестовые кодовые точки и убедитесь, что каждая ведёт на ожидаемый глиф, а не на .notdef или случайный знак. Для основной проверки используйте небольшой текст с русскими буквами; для расширенного проекта добавьте отдельные тесты «ЁЖ», «ґєії», «ў» и те символы, которые вошли в ваш бриф.
Если файл экспортирован в WOFF2, при необходимости сначала декодируйте его поддерживаемым инструментом или проверьте исходный TTF/OTF той же сборки. Не делайте вывод о покрытии по картинке предпросмотра: рендерер может подставить букву из системного fallback-шрифта. Важны записи внутри самого файла и результат проверки без подмены гарнитуры.
3. Прочитайте маски OS/2
В том же FontTools можно выгрузить таблицу командой ttx -t OS/2 имя-файла.ttf. Проверьте ulUnicodeRange1–4 и ulCodePageRange1–2. Инспекторы обычно показывают названия диапазонов; если программа показывает только шестнадцатеричные числа, сверяйте конкретный бит с официальной таблицей OpenType, а не вычисляйте его «на глаз». Убедитесь, что кириллический диапазон заявлен, если шрифт действительно рассчитан на него, и что кодовая страница указана в соответствии с реальным набором.
Не редактируйте исходник только по тому, что число в выгрузке выглядит необычно. Поле хранится как маска, в которой несколько битов могут быть включены одновременно, а значения могут отображаться в другом порядке. Сначала установите название каждого поля, версию OS/2 и позицию бита. Затем исправьте настройку в редакторе шрифта и соберите файл заново.
4. Сопоставьте два результата
Сделайте простую таблицу: символ, кодовая точка, найденная запись cmap, соответствующий глиф, ожидаемый диапазон. Например, «Ж» — U+0416 — запись есть — глиф Zhe — диапазон Cyrillic заявлен. Для буквы, отсутствующей в шрифте намеренно, отсутствие записи может быть корректным, даже если бит 9 включён: маска сообщает о функциональном диапазоне, а не гарантирует каждую позицию блока.
Затем проверьте экспортированный файл, а не только исходный проект. Некоторые редакторы вычисляют маски автоматически при экспорте; другие сохраняют или ожидают заданные значения. Различие между проектом и итоговым файлом помогает локализовать этап, на котором сведения устарели.
5. Повторите тест после исправления
После изменения масок создайте новую сборку под новым именем и повторите оба чтения: cmap и OS/2. Проверьте образец в целевом приложении, закрыв и вновь открыв его; если приложение кэширует установленные шрифты, обновите кэш или используйте временную копию. Проверяйте семейство по уникальному имени или тестовой среде, чтобы исключить подстановку похожего установленного файла.
Пример: кириллица набирается, но отчёт показывает только Latin
Представим авторский шрифт с буквами А–Я, а также Ё и несколькими знаками пунктуации. В редакторе всё выглядит правильно, но после экспорта проверочный отчёт сообщает, что заявлен только Latin. Проверка показывает: cmap содержит нужные кодовые точки, а ulUnicodeRange не сообщает о кириллическом блоке. Это не повод перерисовывать буквы и не доказательство, что все приложения откажутся от файла. Это несогласованность декларации и содержимого, которую нужно исправить на уровне OS/2.
Другой вариант: маска Cyrillic включена, а в cmap нет U+0401 для «Ё». Тогда объявление диапазона выглядит правдоподобно для шрифта с русской кириллицей, но конкретный обязательный знак отсутствует. Нужно добавить или корректно сопоставить глиф, пересобрать файл и только после этого считать проблему решённой. Для пользователя разница принципиальна: первая ошибка относится к описанию, вторая — к реальному покрытию.
Чек-лист перед передачей шрифта
- Запишите список языков и обязательных знаков проекта.
- Проверьте нужные кодовые точки в
cmapименно итогового файла. - Сверьте
ulUnicodeRangeс заявленными блоками; для кириллицы проверьте бит 9. - Проверьте
ulCodePageRangeотдельно; для Windows Cyrillic сверяйте бит 2 по спецификации. - Не трактуйте установленный флаг как гарантию наличия каждой буквы блока.
- Если используете расширенную кириллицу, проверяйте конкретные символы и версию таблицы.
- Повторите анализ после сборки и протестируйте файл в целевом приложении.
- Сохраните версию экспортированного файла и короткий отчёт для воспроизводимости.
Частые ошибки
Включить все диапазоны ради более полного отчёта. Это создаёт ложную декларацию и может усложнить диагностику. Отмечайте только диапазоны, для которых шрифт действительно функционален.
Считать флаг Cyrillic проверкой полного русского набора. Флаг покрывает блок, а не каждую кодовую точку и не качество конкретного глифа. Проверяйте обязательные буквы по cmap и визуально.
Путать диапазоны Unicode и кодовые страницы. Это отдельные маски и номера битов не взаимозаменяемы. В статье выверены значения для кириллического диапазона и Windows Cyrillic по документации Microsoft.
Проверить проект, но не файл после экспорта. Экспортёр может изменить таблицу или сохранить старые значения. Итоговый бинарный файл является объектом приёмки.
Диагностировать рендер по скриншоту. Fallback может скрыть отсутствие глифа в шрифте, а приложение может кэшировать предыдущую версию. Проверяйте таблицы файла и делайте пробу в контролируемой среде.
Часто задаваемые вопросы
Если кириллица есть в cmap, обязательно ли выставлять диапазон OS/2?
Если шрифт рассчитан на кириллицу, декларация диапазона должна соответствовать его назначению. Таблица cmap определяет сопоставление символов и глифов, а поля OS/2 описывают заявленные функциональные диапазоны и могут учитываться некоторыми программами. Проверяйте оба слоя и настройки конкретного редактора.
Гарантирует ли бит 9 наличие всех русских букв?
Нет. Бит 9 отмечает диапазон Cyrillic в маске Unicode и охватывает несколько связанных блоков, но не служит перечнем глифов. Для каждой обязательной буквы проверяйте конкретную кодовую точку в cmap, а затем осматривайте контур и рендер.
Чем ulUnicodeRange отличается от ulCodePageRange?
ulUnicodeRange описывает блоки Unicode, тогда как ulCodePageRange сообщает о функциональных кодовых страницах. Они относятся к разным полям таблицы OS/2, имеют собственную нумерацию битов и могут использоваться приложениями для разных задач выбора шрифта.
Какой бит относится к Windows Cyrillic?
В ulCodePageRange бит 2 обозначает Windows Cyrillic. Это не бит 2 из ulUnicodeRange: в Unicode-маске кириллический блок обозначается битом 9. Всегда проверяйте имя поля рядом со значением и сверяйтесь с актуальной спецификацией.
Можно ли исправить маску, не пересобирая глифы?
Да, если реальные записи cmap и глифы уже корректны, а ошибочна только декларация OS/2. Но сначала убедитесь, что проблема именно в маске: установка неверного флага не добавит символы и не исправит отсутствующий глиф.
Почему приложения показывают разные сведения о покрытии?
Приложения могут использовать разные источники и правила: одни анализируют карту символов, другие используют дополнительные поля OS/2, кэш или собственный механизм fallback. Сравните таблицы экспортированного файла, затем проверьте результат в конкретных программах, где шрифт будет применяться.
Итог
Проверка кириллического покрытия после экспорта состоит из двух независимых шагов: подтвердить реальные отображения в cmap и сверить заявленные диапазоны Unicode и кодовых страниц в OS/2. Такой порядок помогает отличить отсутствующую букву от неверной декларации и передать не просто устанавливаемый, а предсказуемо описанный файл. Создайте пробный набор символов в Fontgenerator, чтобы заранее определить, какие знаки должны войти в итоговый шрифт.
Источники: спецификация OpenType: таблица OS/2.