Техническа статия

Структура на PDF файл: Как всъщност работи форматът

PDF не е формат за документи по начина, по който са Word или RTF. Тези формати съхраняват последователност от съдържание, което рендерерът интерпретира в момента на показване, така че изходът зависи от каквито и шрифтове и двигател за оформление да присъстват. PDF съхранява резултата от този процес: прецизни инструкции за рендиране, програми за шрифтове, компресирани потоци от изображения и граф от обекти, който ги свързва заедно в самостоятелно описание на всяка страница. Файлът носи достатъчно информация, за да възпроизведе всяка страница идентично на всеки съответстващ рендерер, което е едновременно основната му цел на проектиране и източникът на по-голямата част от сложността, която срещате, когато се опитвате да генерирате, анализирате или модифицирате такъв програмно

Обектният модел

Всеки PDF е колекция от номерирани обекти. Обектът може да бъде булева стойност, цяло число, реално число, име, низ, масив, речник, поток или null. Почти всичко интересно е речник, който представлява набор от двойки ключ-стойност, където ключовете са имена, а стойностите са всеки друг тип обект, включително препратки към други обекти по номер и брой поколения. Потокът е речник, последван от последователност от байтове, обикновено компресирана

Речникът на каталога е коренът. Той сочи към дървото на страниците, което организира речниците на страниците в балансирана дървовидна структура, а не в плосък списък, така че навигирането до страница 5000 от документ от 10 000 страници не изисква обхождане на всеки предшестващ дескриптор на страница. Речникът на всяка страница препраща към нейните потоци със съдържание (една или повече последователности от оператори за описание на страница), нейния речник на ресурсите (който на свой ред препраща към дескриптори на шрифтове, цветови пространства и изображения XObjects) и нейния media box (координатното пространство, в което живее страницата). Началото на координатната система е в долния ляв ъгъл, с положително Y насочено нагоре, в единици от 1/72 от инча

В края на файла стои таблицата за кръстосани препратки, която съпоставя всеки номер на обект към неговото байтово отместване във файла. Това е, което позволява произволен достъп: визуализаторът чете таблицата за кръстосани препратки първо, след което търси директно до обектите, от които се нуждае. PDF 1.5 въведе потоци от кръстосани препратки, които компресират таблицата в обект поток и пакетират свързани обекти в потоци от обекти, намалявайки размера на файла забележимо за документи с много малки обекти

Потоци на съдържание и графичният модел

Визуалното съдържание на страницата живее в един или повече потоци от съдържание. Всеки поток е последователност от PDF оператори, разпръснати с техните операнди. Текстовият оператор BT започва текстов обект, Tf избира шрифт и размер от речника на ресурсите, Td позиционира текстовия курсор, Tj или TJ изрисува низ и ET затваря текстовия обект. Векторната графика следва подобен модел: m задава начална точка на пътя, l добавя отсечка, c добавя крива на Безие и f или S запълва или очертава пътя

Графичното състояние управлява всичко, което се случва между операторите: текуща матрица на трансформация, ширина на линията, цветово пространство, цвят на запълване, цвят на контур и път на изрязване. Оператори като q и Q поставят и премахват графичното състояние в стек, което е начинът, по който PDF реализира локални координатни трансформации и временни отмени на състоянието, без да засяга контекста около тях. Формите XObjects обобщават това: самостоятелен поток от съдържание със собствен речник на ресурсите, който може да бъде изрисуван върху страница на произволни позиции и мащаби с един-единствен Do оператор

Вграждане на шрифтове и извличане на текст

PDF може да препраща към шрифтове по име и да разчита на визуализатора да замести нещо, но на практика всеки документ, който възнамерявате да споделите, трябва да вгради данните за шрифта. Шрифт Type 1 или TrueType/OpenType, вграден в PDF, носи речник с дескриптор на шрифт, сочещ към поток от файл на шрифт. За шрифтове TrueType този поток съдържа двоичната програма на шрифта; за Type 1 това са PFB данните. Създаването на подмножества (subsetting), което прави всеки сериозен PDF генератор, премахва глифове, към които не се препраща в документа, поддържайки размерите на файловете управляеми дори за големи Unicode шрифтове

Извличането на текст е мястото, където вграждането на шрифтове отвръща на удара. Визуалното представяне на знак се определя от глиф във вградената програма за шрифт. Unicode стойността на този знак се определя от поток ToUnicode CMap, прикрепен към речника на шрифтовете. Когато ToUnicode CMap липсва или е неправилен, PDF визуализаторът може да рендира текст четливо, но не може да го извлече като смислен Unicode, поради което копирането и поставянето от някои PDF файлове произвежда боклук. Tagged PDF (маркиран PDF, ISO 32000 §14.8) добавя втори слой: логическо дърво на структурата, което съпоставя съдържанието на страницата с роли, семантични за документа, като абзаци, заглавия и клетки на таблица. Екранните четци и двигателите за преформатиране използват дървото на структурата, а не реда на потока от сурово съдържание, което обяснява защо визуално добре оформен PDF все още може да бъде недостъпен, ако маркирането липсва или е грешно

Инкрементални актуализации и цифрови подписи

Когато запишете промени в съществуващ PDF без да го пренаписвате от нулата, новите обекти се добавят след оригиналното тяло на файла заедно с нова секция за кръстосани препратки и нов речник на трейлъра. Актуализираният трейлър сочи към новите данни за кръстосани препратки, а заменените обекти остават във файла, но просто не се споменават от новата верига за кръстосани препратки. Това е инкрементална актуализация и тя има две значителни последици

Първо, файлът расте с всеки цикъл на записване. Документ, редактиран и запазван многократно, натрупва слоеве от остарели обекти. Инструменти като QPDF могат да линеаризират или компресират и пренаписват файл, за да си възвърнат това пространство, но по подразбиране е натрупване. Второ, цифровите подписи зависят от инкременталните актуализации за своя модел на цялост. Подписът по ISO 32000 покрива диапазон от байтове на файла, обикновено всичко с изключение на контейнера за самата стойност на подписа. Всички промени след подписването, които се появяват като допълнителни инкрементални актуализации, са видими за валидиращия четец като модификации, направени след подписването, което е точно одитната пътека, която искате. Това обаче означава също, че определени модификации, като добавяне на подпис за одобрение или попълване на полета във формуляр, са изрично разрешени от стандарта без да обезсилват първоначалния подпис, при условие че промените отговарят на настройките за разрешения на документа (ISO 32000-2 §12.7.6). Модификация, която попада извън тези разрешения, се маркира като неоторизирана. Правилното разбиране на това разграничение има значение, когато генерирате документи, които ще бъдат преподписани надолу по веригата

Нива на съответствие и потеклото на ISO 32000

PDF стартира като проприетарен формат на Adobe през 1993 г., абсорбира модела за изобразяване на PostScript и в продължение на петнадесет версии натрупа функции: криптиране в 1.1, интерактивни формуляри в 1.2, цифрови подписи и логическа структура в 1.3, прозрачност в 1.4, потоци от обекти в 1.5, AES криптиране в 1.6. Adobe представи PDF 1.7 на ISO през 2007 г. и резултатът бе ISO 32000-1:2008. ISO 32000-2:2020 обхваща PDF 2.0, който затегна няколко недостатъчно специфицирани области, ревизира извличането на AES-256 ключ (ревизия 6 заменяща ревизия 5) и добави изрична поддръжка за свързани файлове и богата медия (rich media)

Подстандартите произтичат от същата основа. PDF/A (ISO 19005) заменя функции за архивна стабилност: без криптиране, без зависимости от външно съдържание, всички шрифтове вградени, цветови пространства независими от устройството, изискват се XMP метаданни. PDF/A-1 е базиран на PDF 1.4, PDF/A-2 на PDF 1.7, PDF/A-3 позволява вградени файлове от всякакъв формат. PDF/X (ISO 15930) е подмножеството за печатна продукция: намерения за изход, кутии за наддаване и изрязване, без прозрачност в по-старите нива на съответствие. PDF/UA (ISO 14289) налага маркирана структура, съпоставяне на Unicode и метаданни за език за достъпност. Това не са конкурентни формати; те са набори от допълнителни ограничения върху основния PDF и един файл може да отговаря на повече от едно едновременно, при условие че ограниченията не са в конфликт

За всеки, който пише код, който генерира или обработва PDF, практическата базова линия е ISO 32000-2 с внимателно внимание към разделите, обхващащи модела на кръстосани препратки (§7.5), графичното състояние (§8.4), операторите за състояние на текст (§9.3), дескрипторите на шрифтове и ToUnicode (§9.6 и §9.10), интерактивните формуляри (§12.7) и цифровите подписи (§12.8). Стандартът е дълъг, но по-голямата част от програмната работа с PDF се докосва многократно до тясна част от него. Разбирането на обектния модел и механизма на кръстосани препратки е входната точка; всичко останало оттам нататък е специализация