Переименовать PDF встроенный шрифт - PullRequest
0 голосов
/ 16 сентября 2018

Я использую ghostscript для объединения файлов PDF. Но иногда имена встроенных шрифтов конфликтуют между различными файлами, ghostscript выберет одно подмножество, и некоторые символы из других подмножеств с тем же именем не могут быть отображены после слияния.

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

Решения под Linux предпочтительнее.

P.S. Я использовал другие инструменты для слияния pdf (pdfbox, pdfjam, pdftk, pdfunite, qpdf), но, похоже, ни один из них не идентифицирует одни и те же изображения, и объединенный PDF имеет большой размер. GhostScript сохраняет только один объект для абсолютно одинаковых изображений в нескольких входных файлах, и это соответствует моему сценарию.


Обновление после прочтения ответа от @ KenS

Версия GhostScript: 9.18

Создатель PDF:

  • xelatex: XeTeX 3.14159265-2.6-0.99998 (TeX Live 2017)
  • xdvipdfmx: версия 20170318, разработанная командой проекта DVIPDFMx, изменена для TeX Live.

Вывод 2 PDF с именами шрифтов коллизий:

$ gs -q -dSAFER -dBATCH -dNOPAUSE -dPDFSETTINGS=/prepress -sDEVICE=pdfwrite -sOutputFile=merged.pdf 1.pdf 2.pdf
GPL Ghostscript 9.18: Missing glyph CID=120, glyph=0078 in the font BLTQUA+LMRoman9-Regular . The output PDF may fail with some viewers.
GPL Ghostscript 9.18: Missing glyph CID=117, glyph=0075 in the font BLTQUA+LMRoman9-Regular . The output PDF may fail with some viewers.
GPL Ghostscript 9.18: Missing glyph CID=118, glyph=0076 in the font BLTQUA+LMRoman9-Regular . The output PDF may fail with some viewers.
GPL Ghostscript 9.18: Missing glyph CID=116, glyph=0074 in the font BLTQUA+LMRoman9-Regular . The output PDF may fail with some viewers.

Встроенные шрифты:

$ pdffonts 1.pdf
name                                 type              encoding         emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
ITLHBL+LMRoman10-Regular-Identity-H  CID Type 0C       Identity-H       yes yes yes      7  0
BLTQUA+LMRoman9-Regular-Identity-H   CID Type 0C       Identity-H       yes yes yes      9  0
MHRCBY+LMRoman8-Regular-Identity-H   CID Type 0C       Identity-H       yes yes yes     12  0

$ pdffonts 2.pdf
name                                 type              encoding         emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
ITLHBL+LMRoman10-Regular-Identity-H  CID Type 0C       Identity-H       yes yes yes      7  0
BLTQUA+LMRoman9-Regular-Identity-H   CID Type 0C       Identity-H       yes yes yes      9  0
MHRCBY+LMRoman8-Regular-Identity-H   CID Type 0C       Identity-H       yes yes yes     12  0

Имена шрифтов точно такие же. Поскольку я использую xelatex для программного генерирования PDF-файлов в шаблоне, идентификаторы объектов шрифтов точно такие же. И GhostScript считает BLTQUA+LMRoman9-Regular шрифты из 2 файлов одним и тем же подмножеством и жалуется во время обработки.

Как предложил @KenS, я позволил GhostScript сгенерировать новый файл для каждого PDF.

Ghostscript рассчитает префикс, используя сумму содержимого шрифта MD5.

Затем проверьте шрифты:

$ pdffonts preproc_1.pdf 
name                                 type              encoding         emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
JUVZAM+LMRoman8-Regular              CID Type 0C       Identity-H       yes yes yes     22  0
DCQLFZ+LMRoman9-Regular              CID Type 0C       Identity-H       yes yes yes     17  0
YAKIEH+LMRoman10-Regular             CID Type 0C       Identity-H       yes yes yes     13  0

$ pdffonts preproc_2.pdf 
name                                 type              encoding         emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
JUVZAM+LMRoman8-Regular              CID Type 0C       Identity-H       yes yes yes     22  0
EQFACS+LMRoman9-Regular              CID Type 0C       Identity-H       yes yes yes     17  0
YAKIEH+LMRoman10-Regular             CID Type 0C       Identity-H       yes yes yes     13  0

Теперь очевидно, что LMRoman9-Regular не являются одинаковыми подмножествами (хотя все еще с тем же идентификатором объекта), и это больше не будет путать GhostScript.

1 Ответ

0 голосов
/ 16 сентября 2018

[вставить обычный отказ от ответственности о том, что Ghostscript не объединяет PDF-файлы]

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

Вы не указали, какую версию Ghostscript вы используете. Последние версии Ghostscript используют как имя шрифта, так и номер объекта PDF, чтобы попытаться повысить степень уникальности. Таким образом, шрифты будут конфликтовать только в том случае, если имена объектов и в двух файлах PDF совпадают, что менее вероятно.

Если это все еще проблема, практическим решением является передача каждого из оригинальных файлов PDF через Ghostscript и устройство pdfwrite для создания ряда новых файлов PDF. При создании шрифтов в новых PDF-файлах Ghostscript будет вычислять префикс, используя сумму содержимого шрифта MD5. Хотя это не является абсолютно неразрушимым, шансы двух разных подмножеств с содержимым, которые производят один и тот же хэш MD5, очень низки.

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

Если вы настаиваете на том, чтобы сделать переименование самостоятельно, вам, возможно, удастся просто просмотреть файл PDF с именами для XXXXX + FontName. Вы можете изменить 5-буквенный префикс и переписать файл.

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

...