PDF nu este un format de document în felul în care sunt Word sau RTF. Acele formate stochează o secvență de conținut pe care un motor de randare o interpretează în momentul afișării, așa că rezultatul depinde de fonturile și de motorul de aranjare care se întâmplă să fie prezente. PDF stochează rezultatul acelui proces: instrucțiuni de randare precise, programe de font, fluxuri de imagine comprimate și un graf de obiecte care le leagă într-o descriere autonomă a fiecărei pagini. Fișierul poartă suficientă informație pentru a reproduce fiecare pagină identic pe orice motor de randare conform, ceea ce este atât obiectivul principal de proiectare, cât și sursa majorității complexității pe care o întâlniți când încercați să generați, să parsați sau să modificați unul programatic
Modelul de obiecte
Orice PDF este o colecție de obiecte numerotate. Un obiect poate fi un boolean, un întreg, un număr real, un nume, un șir, un tablou, un dicționar, un flux sau null. Aproape tot ce este interesant este un dicționar, adică un set de perechi cheie-valoare în care cheile sunt nume, iar valorile sunt orice alt tip de obiect, inclusiv referințe la alte obiecte după număr și generație. Un flux este un dicționar urmat de o secvență de octeți, de obicei comprimată
Dicționarul catalog este rădăcina. El indică arborele de pagini, care organizează dicționarele de pagină într-o structură de arbore echilibrat în loc de o listă plată, așa că navigarea la pagina 5.000 dintr-un document de 10.000 de pagini nu cere parcurgerea fiecărui descriptor de pagină anterior. Fiecare dicționar de pagină face referire la fluxurile lui de conținut (una sau mai multe secvențe de operatori de descriere a paginii), la dicționarul lui de resurse (care la rândul lui face referire la descriptori de font, spații de culoare și imagini XObject) și la caseta lui de mediu (spațiul de coordonate în care trăiește pagina). Originea coordonatelor se află în colțul din stânga-jos, cu Y pozitiv crescând în sus, în unități de 1/72 dintr-un țol
La finalul fișierului stă tabelul de referințe încrucișate, care asociază fiecare număr de obiect cu offsetul lui în octeți din fișier. El este cel care permite accesul aleatoriu: un vizualizator citește mai întâi tabelul de referințe încrucișate, apoi se poziționează direct pe obiectele de care are nevoie. PDF 1.5 a introdus fluxurile de referințe încrucișate, care comprimă tabelul într-un obiect flux și împachetează obiectele înrudite în fluxuri de obiecte, reducând simțitor dimensiunea fișierului pentru documentele cu multe obiecte mici
Fluxurile de conținut și modelul grafic
Conținutul vizual al unei pagini trăiește în unul sau mai multe fluxuri de conținut. Fiecare flux este o secvență de operatori PDF intercalați cu operanzii lor. Operatorul de text BT începe un obiect de text, Tf selectează un font și un corp din dicționarul de resurse, Td poziționează cursorul de text, Tj sau TJ pictează un șir, iar ET închide obiectul de text. Grafica vectorială urmează un tipar asemănător: m stabilește punctul de start al unui traseu, l adaugă un segment de dreaptă, c adaugă o curbă Bezier, iar f sau S umple sau trasează conturul traseului
Starea grafică guvernează tot ce se întâmplă între operatori: matricea de transformare curentă, grosimea liniei, spațiul de culoare, culoarea de umplere, culoarea de contur și traseul de decupare. Operatori precum q și Q pun și scot starea grafică de pe o stivă, iar așa implementează PDF transformările locale de coordonate și suprascrierile temporare de stare fără să afecteze contextul din jurul lor. XObject-urile de tip formular generalizează acest lucru: un flux de conținut autonom, cu propriul dicționar de resurse, care poate fi pictat pe o pagină în poziții și la scări arbitrare cu un singur operator Do
Încorporarea fonturilor și extragerea textului
PDF poate face referire la fonturi după nume și se poate baza pe vizualizator să substituie ceva, dar în practică orice document pe care intenționați să îl distribuiți trebuie să încorporeze datele fontului. Un font Type 1 sau TrueType/OpenType încorporat într-un PDF poartă un dicționar de descriptor de font care indică un flux cu fișierul fontului. La fonturile TrueType, acel flux conține programul binar al fontului; la Type 1, sunt datele PFB. Subsetarea, adică ceea ce face orice generator PDF serios, elimină glifele la care documentul nu face referire, menținând dimensiunile fișierelor gestionabile chiar și pentru fonturi Unicode mari
Extragerea textului este locul unde încorporarea fonturilor își arată colții. Reprezentarea vizuală a unui caracter este determinată de o glifă din programul de font încorporat. Valoarea Unicode a acelui caracter este determinată de un flux ToUnicode CMap atașat dicționarului de font. Când CMap-ul ToUnicode lipsește sau este incorect, un vizualizator PDF poate randa textul lizibil, dar nu îl poate extrage ca Unicode cu sens, motiv pentru care copierea din unele PDF-uri produce mizerie. PDF-ul etichetat (ISO 32000 §14.8) adaugă un al doilea strat: un arbore de structură logică ce asociază conținutul paginii cu roluri semantice de document, precum paragrafe, titluri și celule de tabel. Cititoarele de ecran și motoarele de reformatare folosesc arborele de structură, nu ordinea brută a fluxului de conținut, ceea ce explică de ce un PDF bine aranjat vizual poate rămâne inaccesibil dacă etichetarea lipsește sau este greșită
Actualizările incrementale și semnăturile digitale
Când salvați modificări într-un PDF existent fără să îl rescrieți de la zero, obiectele noi sunt adăugate după corpul original al fișierului, împreună cu o nouă secțiune de referințe încrucișate și un nou dicționar de trailer. Trailerul actualizat indică noile date de referințe încrucișate, iar obiectele înlocuite rămân în fișier, dar pur și simplu nu mai sunt referite de noul lanț de referințe încrucișate. Aceasta este actualizarea incrementală și are două consecințe importante
Întâi, fișierul crește cu fiecare ciclu de salvare. Un document editat și salvat în mod repetat acumulează straturi de obiecte învechite. Instrumente precum QPDF pot lineariza sau comprima-și-rescrie un fișier pentru a recupera acel spațiu, dar comportamentul implicit este acumularea. Apoi, semnăturile digitale depind de actualizările incrementale pentru modelul lor de integritate. O semnătură ISO 32000 acoperă un interval de octeți din fișier, de obicei tot în afară de spațiul rezervat valorii semnăturii înseși. Orice modificare de după semnare care apare ca actualizare incrementală suplimentară este vizibilă pentru un cititor care validează drept modificare făcută după semnare, adică exact traseul de audit pe care îl doriți. Totuși, asta înseamnă și că anumite modificări, precum adăugarea unei semnături de aprobare sau completarea câmpurilor de formular, sunt permise explicit de standard fără invalidarea semnăturii originale, cu condiția ca schimbările să respecte setările de permisiuni ale documentului (ISO 32000-2 §12.7.6). O modificare aflată în afara acelor permisiuni este marcată ca neautorizată. Distincția aceasta contează atunci când generați documente care vor fi contrasemnate mai departe
Nivelurile de conformitate și descendența ISO 32000
PDF a pornit ca format proprietar Adobe în 1993, a absorbit modelul de imagine al PostScript și, de-a lungul a cincisprezece versiuni, a acumulat funcții: criptare în 1.1, formulare interactive în 1.2, semnături digitale și structură logică în 1.3, transparență în 1.4, fluxuri de obiecte în 1.5, criptare AES în 1.6. Adobe a depus PDF 1.7 la ISO în 2007, iar rezultatul a fost ISO 32000-1:2008. ISO 32000-2:2020 acoperă PDF 2.0, care a strâns șuruburile în câteva zone subspecificate, a revizuit derivarea cheii AES-256 (revizia 6 înlocuind revizia 5) și a adăugat suport explicit pentru fișiere asociate și conținut media bogat
Substandardele derivă din aceeași bază. PDF/A (ISO 19005) schimbă funcții pe stabilitate arhivistică: fără criptare, fără dependențe de conținut extern, toate fonturile încorporate, spații de culoare independente de dispozitiv, metadate XMP obligatorii. PDF/A-1 se bazează pe PDF 1.4, PDF/A-2 pe PDF 1.7, iar PDF/A-3 permite fișiere încorporate de orice format. PDF/X (ISO 15930) este subsetul pentru producția tipografică: intenții de ieșire, casete de bleed și de tăiere, fără transparență în nivelurile de conformitate mai vechi. PDF/UA (ISO 14289) impune structură etichetată, corespondențe Unicode și metadate de limbă pentru accesibilitate. Acestea nu sunt formate concurente; sunt seturi de constrângeri suplimentare peste PDF-ul de bază, iar un singur fișier poate fi conform cu mai multe simultan, cu condiția ca restricțiile să nu intre în conflict
Pentru oricine scrie cod care generează sau prelucrează PDF, reperul practic este ISO 32000-2, cu atenție deosebită la secțiunile care acoperă modelul de referințe încrucișate (§7.5), starea grafică (§8.4), operatorii de stare a textului (§9.3), descriptorii de font și ToUnicode (§9.6 și §9.10), formularele interactive (§12.7) și semnăturile digitale (§12.8). Standardul este lung, dar cea mai mare parte a muncii programatice cu PDF atinge în mod repetat o felie îngustă din el. Înțelegerea modelului de obiecte și a mecanismului de referințe încrucișate este punctul de intrare; tot restul înseamnă specializare de acolo încolo