CID-шрифт и CMap: как устроен набор и почему текст в PDF может извлекаться неверно

CID-keyed шрифт — это способ хранить большие наборы глифов, обращаясь к ним по числовым идентификаторам, а CMap связывает коды в тексте с этими идентификаторами. Архитектура помогла PostScript и PDF работать с многоязычными наборами, в том числе китайским, японским и корейским. Понимание этой цепочки помогает диагностировать файл, который выглядит правильно, но плохо ищется, копируется или читается программами.
Почему для большого набора букв понадобилась другая адресация
В простом шрифте глифы часто описывают через имена вроде A или comma. Для европейского набора этого обычно достаточно: количество основных букв и знаков сравнительно невелико, а кодирование можно уложить в небольшую таблицу. Но для китайского, японского и корейского письма типичный шрифт содержит гораздо больше вариантов знаков. Именовать каждый глиф и помещать его в одну маленькую таблицу неудобно.
CID расшифровывается как character identifier — идентификатор символа. Вместо поиска по имени программа использует целое число: CID указывает на запись с описанием глифа. Сам номер не сообщает, какой именно знак увидит человек. Его значение зависит от набора символов, называемого character collection, и от карты, которая переводит входной код в CID. Это важно: CID не равен Unicode-коду и не является универсальным номером знака.
Архитектура разделяет две задачи. CIDFont хранит описания глифов и метрики. CMap преобразует коды, которые приходят из строки, в CID. В описании Adobe эти два ресурса работают вместе: карта задаёт соответствие кодов и селекторов глифов, а CIDFont использует идентификатор для доступа к контуру. Спецификация Adobe CMap/CIDFont фиксирует именно такое разделение.
Такой подход относится к истории цифрового набора, но он не исчез из готовых материалов. В PDF могут встречаться составные шрифты, основанные на CID, а старый PostScript-файл может ссылаться на ресурсы, собранные по этой схеме. Поэтому проблема с копированием текста из PDF иногда скрывается глубже, чем внешний вид шрифта.
Как код текста проходит путь до контура
Удобно представить путь как цепочку из четырёх звеньев:
- Программа передаёт код символа в текстовой строке.
- CMap интерпретирует этот код согласно выбранной кодировке и находит CID.
- CIDFont по CID выбирает описание глифа и метрики.
- Растеризатор строит изображение, которое появляется на странице.
Для одной и той же видимой буквы или иероглифа эти звенья могут быть настроены по-разному. Если визуальный глиф совпал с ожиданием, это ещё не доказывает, что исходный Unicode-код сохранён верно. Контур может отрисоваться правильно, а обратное соответствие для поиска и копирования отсутствовать или ошибаться.
В PDF эту конструкцию часто представляют как Type 0 font: верхний объект связывает CMap и потомка CIDFont. Входные коды могут занимать несколько байтов, что позволяет адресовать гораздо больше символов, чем простая однобайтная кодировка. PDF Reference описывает, что CMap задаёт связь кодов с CID, а таблица символов CIDFont содержит сами глифы. Там же объясняется, почему это полезно для больших наборов, например для CJK-письма (раздел 5.6 PDF Reference).
Не нужно смешивать CMap со всей системой кодирования текста. CMap относится к конкретному способу интерпретировать коды, поданные в PDF-поток. Unicode — универсальная система кодовых точек, используемая приложениями для представления текста. Между Unicode и CID можно построить соответствие, но это отдельное отношение, которое должно быть явно задано или выведено из доступных данных.
Почему страница выглядит правильно, а поиск ломается
PDF хранит операции рисования и текстовые коды. В некоторых файлах из них нельзя однозначно восстановить текст без дополнительной карты. Для зрителя достаточно показать нужный контур в нужной позиции; для копирования, поиска, экранного чтения и экспорта нужен ответ на другой вопрос: какой Unicode-текст представляет этот фрагмент?
В PDF для этого может использоваться отдельная ToUnicode CMap. Она связывает внутренние коды, применённые в потоке страницы, с Unicode-последовательностями. Это не то же самое, что CMap кодирования для выбора CID: одна карта ведёт к глифу, другая помогает восстановить семантический текст. Adobe описывает ToUnicode как средство явно передать соответствие символов Unicode и отдельно отмечает, что без пригодного пути сопоставления нельзя надёжно определить, что означает код PDF (PDF Reference, раздел 5.9 и раздел 9.7).
Отсюда возникают знакомые симптомы:
- текст на экране читается, но при копировании появляется мусор или пробелы;
- поиск не находит слово, которое явно напечатано на странице;
- экранный диктор произносит бессвязные знаки;
- при экспорте в редактор часть знаков превращается в квадраты или теряет порядок;
- один PDF-просмотрщик копирует фрагмент верно, а другой — иначе.
Эти признаки не доказывают, что виноват CID-шрифт. Причиной могут быть некорректная ToUnicode CMap, неверно выбранная кодировка, подстановка шрифта, ошибка экспорта, а для сложных письменностей — также порядок визуального размещения и логического чтения. CID-архитектура помогает задать вопрос точнее: «какая карта выбрала этот глиф и какая карта возвращает текст?», вместо расплывчатого «почему шрифт сломался?».
Практическая проверка PDF перед передачей
Проверяйте не только внешний вид страницы. Сделайте короткий тестовый файл из той же программы и с теми же настройками экспорта, что будут в финальной поставке. Возьмите несколько строк, где есть обычные знаки, редкие символы, повторяющиеся знаки, пунктуация и имена собственные. Для CJK добавьте символы из разных участков набора и вертикальный текст, если он используется.
Шаг 1. Зафиксируйте исходный текст
Сохраните контрольную строку в отдельном обычном текстовом файле или документе. Для каждого проблемного знака запишите кодовую точку Unicode, если она известна. Не полагайтесь на изображение страницы как на эталон: два символа могут выглядеть похоже, но иметь разные коды и смысл.
Шаг 2. Откройте PDF в целевом просмотрщике
Сравните отображение с исходником на том же масштабе. Отметьте квадраты, пропуски, внезапную смену толщины и ширины, подстановку похожего глифа. Если проблема есть уже визуально, сначала проверяйте наличие нужного глифа в шрифте и корректность его выбора. Если изображение правильное, переходите к текстовому слою.
Шаг 3. Проверьте поиск и копирование
Найдите контрольное слово через встроенный поиск. Скопируйте ту же строку в простой текстовый редактор, где не включены автоматическая замена и форматирование. Сверьте знаки, пробелы и порядок с исходником. Для сложной письменности проверяйте не только отдельный знак, но и последовательность: в некоторых системах один визуальный элемент может соответствовать нескольким Unicode-кодам.
Шаг 4. Сравните результат в независимом инструменте
Если исходная программа экспортировала PDF, откройте копию другим проверенным просмотрщиком или инструментом извлечения текста. Не считайте один способ чтения абсолютным арбитром: сравните, где именно расходятся результаты. Например, если один просмотрщик показывает верно, а экспорт в текст даёт ошибки, проблема может быть в таблице соответствий или обработке потока, а не в рисунке глифа.
Шаг 5. Проверьте встраивание и повторите экспорт
В свойствах документа или отчёте проверки шрифтов посмотрите, встроен ли шрифт и нет ли предупреждений о замене. Встраивание помогает сохранить нужные контуры для отображения, но само по себе не исправляет ошибочную карту текста. После смены параметров экспорта повторите весь контроль: изображение, поиск, копирование и извлечение.
Если вы не разрабатываете CJK-шрифт и не создаёте CMap вручную, не редактируйте внутренние номера CID. Работайте через исходную программу, корректное Unicode-представление, актуальную гарнитуру и её документированные настройки экспорта. Для технического расследования передайте разработчику шрифта контрольный PDF, исходную строку, название просмотрщика и точное описание: «видно, но не копируется» или «поиск находит не тот символ».
Что изменилось в поздних форматах
CID-адресация не означает, что пользователь работает с голым CIDFont. На настольных компьютерах старые CID-файлы сменялись оболочками, а затем OpenType/CFF стал более привычным контейнером для многих сценариев. Разработчик Adobe Ken Lunde описывает ранние настольные варианты CID и переход к OpenType/CFF как часть эволюции поддержки больших CJK-наборов (историческая заметка Adobe). Сам принцип остаётся полезным: внутренний номер глифа, код текста и видимая форма — связанные, но не тождественные вещи.
В современном шрифтовом файле обычно есть таблица cmap, которая связывает Unicode-коды с номерами глифов, а таблицы OpenType layout могут менять выбор формы в контексте. CID и CMap поэтому особенно важны при чтении старых PDF/PostScript материалов и при разборе устройства больших коллекций, но не являются обязательным шагом обычного создания кириллического авторского шрифта. Если в вашем шрифте важны кириллические буквы и знаки, начните с реальных слов и проверьте экспортируемый файл в целевой программе; создать свой набор и увидеть его в строке можно в Fontgenerator.
Частые ошибки диагностики
- **Считать CID кодом Unicode.** CID — внутренний идентификатор в конкретной коллекции, а не универсальный знак. Проверяйте входной код и таблицу соответствия отдельно.
- **Путать карту для выбора глифа с картой для извлечения.** CMap кодирования и ToUnicode решают разные задачи; правильный контур не гарантирует корректное копирование.
- **Исправлять форму глифа, когда сломана текстовая связь.** Если знак визуально верен, но поиск ошибается, сначала изучите экспорт и кодовые соответствия.
- **Проверять только один PDF-просмотрщик.** Разные инструменты могут по-разному восстанавливать отсутствующие данные. Сравните не менее двух способов вывода или извлечения.
- **Считать встраивание полной гарантией.** Встроенный шрифт сохраняет ресурс для отрисовки, но не обязательно даёт правильный семантический текст.
- **Объявлять формат причиной без контрольного файла.** Сохраните входную строку, версию приложения, параметры экспорта и наблюдаемый результат.
Чек-лист перед выпуском многоязычного PDF
- Сохранён контрольный исходный текст с редкими и характерными знаками.
- PDF показывает нужные контуры и метрики без нежелательной подстановки.
- Поиск находит контрольные слова.
- Копирование в простой текст сохраняет знаки, пробелы и порядок.
- Второй просмотрщик или средство извлечения подтверждает результат.
- Сведения о шрифтах не показывают неожиданную замену; встраивание соответствует требованиям поставки.
- Если проверяется старый файл, сохранены его копия и сведения об источнике, а новый экспорт сравнивается с исходником.
Вопросы и ответы
CID — это номер Unicode?
Нет. CID — идентификатор глифа в упорядоченной коллекции, а Unicode задаёт кодовую точку абстрактного символа. CMap или другая таблица связывает один вид номера с другим в рамках конкретного шрифта и сценария.
CMap и ToUnicode CMap — одно и то же?
Нет. Карта кодирования в составном PDF-шрифте помогает преобразовать входной код в селектор, например CID, чтобы выбрать глиф. ToUnicode CMap связывает коды из текстового потока PDF с Unicode-текстом для поиска, копирования и других операций.
Почему китайские, японские и корейские шрифты часто используют CID?
CID-архитектура удобна для больших коллекций глифов и многобайтовых кодов. Она отделяет кодировку текста от числовой адресации глифов, поэтому одну коллекцию можно использовать в сочетании с разными картами кодирования.
Если символ правильно виден, означает ли это, что PDF исправен?
Не обязательно. Для отображения достаточно выбрать контур и поставить его на страницу. Поиск и копирование требуют отдельного корректного соответствия между кодом в PDF и Unicode, поэтому проверьте текстовые операции отдельно.
Можно ли исправить плохое копирование заменой шрифта?
Иногда повторный экспорт с другой гарнитурой помогает, но причина может быть в настройках PDF-экспорта или ToUnicode-карте. Сначала сравните встроенное изображение, поиск и копирование, а затем повторите экспорт с одинаковым контрольным текстом.
Нужно ли вручную назначать CID для шрифта на кириллице?
Обычно нет. Для стандартного рабочего процесса авторского кириллического шрифта используйте редактор шрифтов или инструмент сборки, который создаёт таблицу Unicode-сопоставлений. Ручная работа с CID относится к специализированным форматам и не заменяет проверку кодовых точек.
Что передать разработчику, если текст не извлекается?
Передайте PDF, точную исходную строку, скриншот отображения, скопированный ошибочный результат, название программы и просмотрщика, а также сведения о встраивании шрифта. Это позволяет отделить проблему глифа от ошибки карты кодов или обработки PDF.
Вывод
CID-keyed шрифт показывает, как цифровой набор отделил код текста от числового адреса глифа, чтобы управлять большими коллекциями знаков. В повседневной работе главное следствие практическое: проверяйте одновременно внешний вид и текстовый слой PDF. Если знаки видны, но не ищутся или не копируются, исследуйте соответствие кодов и экспорт — а не только рисунок букв.