Műszaki cikk

PDF fájlszerkezet: Hogyan működik valójában a formátum

A PDF nem olyan dokumentumformátum, mint a Word vagy az RTF. Azok a formátumok olyan tartalomsorozatot tárolnak, amelyet a megjelenítő (renderer) a megjelenítés pillanatában értelmez, így a kimenet attól függ, hogy éppen milyen betűtípusok és elrendezési motor (layout engine) állnak rendelkezésre. A PDF ennek a folyamatnak az eredményét tárolja: precíz megjelenítési utasításokat, betűtípus-programokat, tömörített képfolyamokat és egy objektumgráfot, amely ezeket minden egyes oldal önálló leírásává fűzi össze. A fájl elegendő információt hordoz ahhoz, hogy minden egyes oldalt azonos módon reprodukáljon bármely szabványkövető megjelenítőn; ez egyaránt a fő tervezési célja és a forrása a legtöbb olyan komplexitásnak, amellyel akkor találkozunk, amikor programozottan próbálunk egyet generálni, elemezni vagy módosítani

Az objektummodell

Minden PDF számozott objektumok gyűjteménye. Egy objektum lehet logikai érték, egész szám, valós szám, név, karakterlánc, tömb, szótár (dictionary), adatfolyam (stream) vagy null. Szinte minden, ami érdekes, egy szótár, ami kulcs-érték párok halmaza, ahol a kulcsok nevek, az értékek pedig bármilyen más objektumtípusok lehetnek, beleértve a más objektumokra történő hivatkozásokat szám és generációszám alapján. A stream egy szótár, amelyet egy (jellemzően tömörített) bájtsorozat követ

A katalógusszótár a gyökér. Ez az oldalfára mutat, amely az oldalszótárakat lapos lista helyett egy kiegyensúlyozott faszerkezetbe rendezi, így egy 10 000 oldalas dokumentum 5 000. oldalára való navigáláshoz nem kell bejárni minden megelőző oldalleírót. Minden oldalszótár hivatkozik a saját tartalomfolyamaira (egy vagy több oldalleíró operátorsorozat), az erőforrásszótárára (amely viszont betűtípus-leírókra, színterekre és kép XObjectekre hivatkozik) és a mediaboxára (a koordinátatérre, amelyben az oldal él). A koordináta-rendszer origója a bal alsó sarokban van, a pozitív Y felfelé halad, a mértékegysége pedig 1/72 hüvelyk (inch)

A fájl végén található a kereszthivatkozási tábla (xref), amely minden objektumszámot hozzárendel a fájlon belüli bájtofszethez. Ez az, ami lehetővé teszi a véletlenszerű hozzáférést: egy megjelenítő először a kereszthivatkozási táblát olvassa be, majd közvetlenül azokra az objektumokra ugrik (seek), amelyekre szüksége van. A PDF 1.5 bevezette a kereszthivatkozási adatfolyamokat, amelyek a táblázatot egy adatfolyam-objektumba tömörítik, és a kapcsolódó objektumokat objektum-adatfolyamokba (object streams) csomagolják, ami a sok kis objektumot tartalmazó dokumentumok esetében észrevehetően csökkenti a fájlméretet

Tartalomfolyamok és a grafikai modell

Egy oldal vizuális tartalma egy vagy több tartalomfolyamban él. Minden stream PDF operátorok sorozata, operandusokkal tarkítva. A BT szöveg operátor egy szöveges objektumot kezd meg, a Tf kiválaszt egy betűtípust és méretet az erőforrásszótárból, a Td pozicionálja a szövegkurzort, a Tj vagy TJ kirajzol egy karakterláncot, az ET pedig lezárja a szöveges objektumot. A vektorgrafika hasonló mintát követ: az m beállítja az útvonal (path) kezdőpontját, az l hozzáfűz egy vonalszakaszt, a c hozzáfűz egy Bezier-görbét, az f vagy az S pedig kitölti vagy körvonalazza az útvonalat

A grafikai állapot (graphics state) szabályoz mindent, ami az operátorok között történik: az aktuális transzformációs mátrixot, a vonalvastagságot, a színteret, a kitöltési színt, a körvonal színét és a vágási görbét (clipping path). A q és Q operátorok a grafikai állapotot egy verembe (stack) helyezik, illetve onnan kiveszik; a PDF így valósítja meg a helyi koordináta-transzformációkat és az ideiglenes állapot-felülírásokat anélkül, hogy az a körülöttük lévő kontextust befolyásolná. A Form XObjectek ezt általánosítják: egy önálló tartalomfolyam saját erőforrásszótárral, amely tetszőleges pozíciókban és méretekben rajzolható egy oldalra egyetlen Do operátorral

Betűtípus-beágyazás és szövegkinyerés

A PDF képes betűtípusokra név alapján hivatkozni, és a megjelenítőre bízni a helyettesítésüket, de a gyakorlatban minden olyan dokumentumnak, amelyet meg akarunk osztani másokkal, be kell ágyaznia a betűtípus adatait. A PDF-be beágyazott Type 1 vagy TrueType/OpenType betűtípus egy betűtípus-leíró szótárat hordoz, amely egy betűtípus-fájl streamre mutat. A TrueType betűtípusok esetében ez a stream tartalmazza a bináris betűtípus-programot; a Type 1 esetében a PFB adatokat. A részhalmazképzés (subsetting) – amit minden komoly PDF generátor elvégez – eltávolítja a dokumentumban nem hivatkozott betűjeleket (glypheket), így a fájlméretek még a nagy Unicode betűtípusok esetén is kezelhetők maradnak

A szövegkinyerés az a pont, ahol a betűtípus-beágyazás visszaüt. Egy karakter vizuális megjelenését a beágyazott betűtípus-program egyik glyph-je határozza meg. Ennek a karakternek a Unicode értékét a betűtípus-szótárhoz csatolt ToUnicode CMap adatfolyam határozza meg. Ha a ToUnicode CMap hiányzik vagy hibás, a PDF-megjelenítő olvashatóan tudja renderelni a szöveget, de nem tudja azt értelmes Unicode-ként kinyerni, és ez az oka annak, hogy egyes PDF-ekből történő másolás és beillesztés csak szemetet eredményez. A Taggelt PDF (ISO 32000 §14.8) hozzáad egy második réteget: egy logikai struktúrafát, amely az oldal tartalmát dokumentumszemantikai szerepekhez – például bekezdésekhez, címsorokhoz és táblázatcellákhoz – rendeli. A képernyőolvasók és a szövegtördelő (reflow) motorok a struktúrafát használják a nyers tartalomfolyam sorrendje helyett, ami megmagyarázza, hogy egy vizuálisan jól elrendezett PDF miért lehet mégis hozzáférhetetlen, ha a címkézés (tagging) hiányzik vagy hibás

Növekményes frissítések és digitális aláírások

Amikor elmenti a meglévő PDF-ben végzett módosításokat anélkül, hogy a nulláról újraírná, az új objektumok az eredeti fájltörzs után kerülnek hozzáfűzésre egy új kereszthivatkozási szakasszal és egy új trailer szótárral együtt. A frissített trailer az új kereszthivatkozási adatokra mutat, és a felváltott objektumok a fájlban maradnak, de egyszerűen nem hivatkozik rájuk az új kereszthivatkozási lánc. Ez a növekményes frissítés, és ennek két jelentős következménye van

Először is, a fájl minden mentési ciklussal növekszik. Egy ismételten szerkesztett és mentett dokumentum felhalmozza az elavult objektumok rétegeit. Az olyan eszközök, mint a QPDF, képesek linearizálni vagy tömöríteni-és-újraírni a fájlt, hogy visszanyerjék ezt a helyet, de az alapértelmezett a felhalmozódás. Másodszor, a digitális aláírások integritási modellje a növekményes frissítéseken alapul. Egy ISO 32000 aláírás a fájl egy bájttartományára terjed ki, jellemzően mindenre, kivéve magának az aláírási értéknek a helyőrzőjét (placeholder). Bármely aláírás utáni változtatás, amely további növekményes frissítésként jelenik meg, az érvényesítést végző olvasó számára úgy látszik, mint aláírás után elvégzett módosítás, és pontosan ez az az ellenőrzési nyomvonal (audit trail), amire szükségünk van. Ez azonban azt is jelenti, hogy bizonyos módosításokat – mint például egy jóváhagyó aláírás hozzáadása vagy az űrlapmezők kitöltése – a szabvány kifejezetten megenged anélkül, hogy érvénytelenítené az eredeti aláírást, feltéve, hogy a módosítások megfelelnek a dokumentum jogosultsági beállításainak (ISO 32000-2 §12.7.6). Az olyan módosítás, amely kívül esik ezeken a jogosultságokon, jogosulatlanként (unauthorized) lesz megjelölve. Ennek a különbségnek a helyes értelmezése fontos, amikor olyan dokumentumokat generál, amelyeket a későbbiekben ellenjegyezni fognak

Megfelelőségi szintek és az ISO 32000 leszármazás

A PDF 1993-ban egy szabadalmaztatott Adobe formátumként indult, átvette a PostScript képalkotási modelljét, és tizenöt verzión keresztül halmozta fel a funkcióit: titkosítás az 1.1-ben, interaktív űrlapok az 1.2-ben, digitális aláírások és logikai struktúra az 1.3-ban, átlátszóság az 1.4-ben, objektum adatfolyamok (object streams) az 1.5-ben, AES titkosítás az 1.6-ban. Az Adobe 2007-ben benyújtotta a PDF 1.7-et az ISO-hoz, aminek az eredménye az ISO 32000-1:2008 lett. Az ISO 32000-2:2020 a PDF 2.0-t fedi le, amely több aluldefiniált területet szigorított, felülvizsgálta az AES-256 kulcs-származtatást (a 6. revízió felváltotta az 5. revíziót), és kifejezett támogatást adott a társított fájlokhoz (associated files) és a rich media tartalmakhoz

Az alszabványok ugyanebből az alapból származnak. A PDF/A (ISO 19005) a funkciókat archiválási stabilitásra cseréli: nincs titkosítás, nincsenek külső tartalomfüggőségek, minden betűtípus beágyazott, a színterek eszközfüggetlenek, XMP metaadatok szükségesek. A PDF/A-1 a PDF 1.4-re, a PDF/A-2 a PDF 1.7-re épül, a PDF/A-3 pedig bármilyen formátumú beágyazott fájlt megenged. A PDF/X (ISO 15930) a nyomdai előállítás (print production) részhalmaza: kimeneti szándékok (output intents), kifutó és vágó dobozok (bleed and trim boxes), nincs átlátszóság a régebbi megfelelőségi szinteken. A PDF/UA (ISO 14289) taggelt struktúrát, Unicode leképezéseket és nyelvi metaadatokat ír elő a hozzáférhetőség érdekében. Ezek nem egymással versengő formátumok; a mag-PDF tetején lévő további megszorítások halmazai, és egyetlen fájl egyszerre többnek is megfelelhet, feltéve, hogy a megszorítások nem ütköznek egymással

Bárki számára, aki olyan kódot ír, amely PDF-et generál vagy dolgoz fel, a gyakorlati kiindulópont az ISO 32000-2, fokozott figyelmet fordítva a kereszthivatkozási modellt (§7.5), a grafikai állapotot (§8.4), a szövegállapot operátorokat (§9.3), a betűtípus-leírókat és a ToUnicode-ot (§9.6 és §9.10), az interaktív űrlapokat (§12.7), valamint a digitális aláírásokat (§12.8) tárgyaló szakaszokra. A szabvány hosszú, de a legtöbb programozott PDF-munka annak egy szűk szeletét érinti ismételten. Az objektummodell és a kereszthivatkozási mechanizmus megértése a belépési pont; onnantól kezdve minden más már csak specializáció