Technical Article

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

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

Моделът на обектите

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

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

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

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

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

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

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

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

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

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

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

Първо, размерът на файла нараства при всеки цикъл на записване. Документ, който се редактира и записва многократно, натрупва слоеве от излишни обекти. Инструменти като 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) и добави изрична поддръжка за свързани файлове и мултимедия.

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

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