Teknisk artikel

PDF-filstruktur: Hvordan formatet rent faktisk virker

PDF er ikke et dokumentformat på samme måde som Word eller RTF. Disse formater gemmer en sekvens af indhold, som en renderer fortolker i visningsøjeblikket, så outputtet afhænger af de skrifttyper og den layoutmotor, der tilfældigvis er til stede. PDF gemmer resultatet af den proces: præcise gengivelsesinstruktioner, skrifttypeprogrammer, komprimerede billedstrømme og en objektgraf, der binder dem sammen til en selvstændig beskrivelse af hver side. Filen bærer information nok til at reproducere hver side identisk på enhver kompatibel renderer, hvilket både er dens primære designmål og kilden til det meste af den kompleksitet, du støder på, når du forsøger at generere, parse eller ændre en programmatisk

Objektmodellen

Hver PDF er en samling af nummererede objekter. Et objekt kan være en boolsk værdi, et heltal, et reelt tal, et navn, en streng, et array, en ordbog, en strøm eller null. Næsten alt interessant er en ordbog, som er et sæt nøgle-værdi-par, hvor nøgler er navne, og værdier er enhver anden objekttype, herunder referencer til andre objekter ved nummer og generationstælling. En strøm er en ordbog efterfulgt af en bytesekvens, typisk komprimeret

Katalogordbogen er roden. Den peger på sidetræet, som organiserer sideordbøgerne i en afbalanceret træstruktur snarere end en flad liste, så det at navigere til side 5.000 af et 10.000 siders dokument ikke kræver, at man gennemgår hver forudgående sidebeskrivelse. Hver sideordbog refererer til sine indholdsstrømme (en eller flere sekvenser af sidebeskrivelsesoperatører), sin ressourceordbog (som til gengæld refererer til skrifttypedeskriptorer, farverum og billed-XObjects) og sin medie-boks, som er det koordinatrum, siden lever i. Koordinatens nulpunkt er i det nederste venstre hjørne, med positiv Y, der løber opad, i enheder af 1/72 tomme

I slutningen af filen sidder krydsreferencetabellen, som kortlægger hvert objektnummer til dets byte-offset i filen. Det er dette, der muliggør tilfældig adgang: en fremviser læser krydsreferencetabellen først, og søger derefter direkte til de objekter, den har brug for. PDF 1.5 introducerede krydsreferencestrømme, som komprimerer tabellen til et strømobjekt og pakker relaterede objekter i objektstrømme, hvilket reducerer filstørrelsen mærkbart for dokumenter med mange små objekter

Indholdsstrømme og grafikmodellen

En sides visuelle indhold lever i en eller flere indholdsstrømme. Hver strøm er en sekvens af PDF-operatører afbrudt af deres operander. Tekstoperatøren BT begynder et tekstobjekt, Tf vælger en skrifttype og størrelse fra ressourceordbogen, Td positionerer tekstmarkøren, Tj eller TJ maler en streng, og ET lukker tekstobjektet. Vektorgrafik følger et lignende mønster: m sætter et stis startpunkt, l tilføjer et linjesegment, c tilføjer en Bezier-kurve, og f eller S udfylder eller optegner stien

Grafiktilstanden styrer alt, hvad der sker mellem operatører: aktuel transformationsmatrix, linjebredde, farverum, fyldfarve, stregfarve og afklipningsstien. Operatører som q og Q skubber og popper grafiktilstanden ind og ud af en stak, hvilket er hvordan PDF implementerer lokale koordinattransformationer og midlertidige tilstands-overrides uden at påvirke konteksten omkring dem. Form XObjects generaliserer dette: en selvstændig indholdsstrøm med sin egen ressourceordbog, der kan males på en side ved vilkårlige positioner og skalaer med en enkelt Do operatør

Skrifttypeindlejring og tekstudtrækning

PDF kan referere til skrifttyper ved navn og stole på, at fremviseren erstatter noget, men i praksis skal ethvert dokument, du har tænkt dig at dele, indlejre skrifttypedataene. En Type 1 eller TrueType/OpenType skrifttype indlejret i en PDF bærer en skrifttypedeskriptor-ordbog, der peger på en skrifttypefilstrøm. For TrueType-skrifttyper indeholder den strøm det binære skrifttypeprogram; for Type 1 er det PFB-dataene. Subsetting, som er, hvad enhver seriøs PDF-generator gør, fjerner glyffer, der ikke refereres til af dokumentet, og holder filstørrelserne håndterbare, selv for store Unicode-skrifttyper

Tekstudtrækning er, hvor skrifttypeindlejring bider igen. Den visuelle repræsentation af et tegn bestemmes af en glyf i det indlejrede skrifttypeprogram. Unicode-værdien af det tegn bestemmes af en ToUnicode CMap-strøm knyttet til skrifttypeordbogen. Når ToUnicode CMap mangler eller er forkert, kan en PDF-fremviser gengive tekst læseligt, men kan ikke udtrække den som meningsfuld Unicode, hvilket er grunden til, at kopier-sæt-ind fra nogle PDF'er producerer skrald. Mærket PDF (ISO 32000 §14.8) tilføjer et andet lag: et logisk strukturtræ, der knytter sideindhold til dokuments-semantiske roller som afsnit, overskrifter og tabelceller. Skærmlæsere og ombrydningsmotorer bruger strukturtræet snarere end den rå indholdsstrøm-rækkefølge, hvilket forklarer, hvorfor en visuelt veloplagt PDF stadig kan være utilgængelig, hvis tagging er fraværende eller forkert

Trinvise opdateringer og digitale signaturer

Når du gemmer ændringer i en eksisterende PDF uden at omskrive den fra bunden, tilføjes de nye objekter efter den oprindelige filkrop sammen med en ny krydsreferencesektion og en ny trailerordbog. Den opdaterede trailer peger på de nye krydsreferencedata, og erstattede objekter forbliver i filen, men de refereres simpelthen ikke af den nye krydsreferencekæde. Dette er trinvis opdatering, og det har to væsentlige konsekvenser

For det første vokser filen med hver gemme-cyklus. Et dokument, der redigeres og gemmes gentagne gange, akkumulerer lag af forældede objekter. Værktøjer som QPDF kan linearisere eller komprimere-og-omskrive en fil for at genvinde den plads, men standarden er akkumulering. For det andet afhænger digitale signaturer af trinvise opdateringer for deres integritetsmodel. En ISO 32000 signatur dækker et byte-interval af filen, typisk alt undtagen pladsholderen til selve signaturværdien. Enhver ændring efter signering, der optræder som yderligere trinvise opdateringer, er synlig for en validerende læser som modifikationer foretaget efter signering, hvilket er præcis det revisionsspor, du ønsker. Men det betyder også, at visse modifikationer, såsom at tilføje en godkendelsessignatur eller udfylde formularfelter, udtrykkeligt er tilladt af standarden uden at ugyldiggøre den oprindelige signatur, forudsat at ændringerne er i overensstemmelse med dokumentets tilladelsesindstillinger (ISO 32000-2 §12.7.6). En modifikation, der falder uden for disse tilladelser, markeres som uautoriseret. At få denne sondring rigtig betyder noget, når du genererer dokumenter, der skal medunderskrives downstream

Overensstemmelsesniveauer og ISO 32000-slægten

PDF startede som et proprietært Adobe-format i 1993, absorberede PostScripts billedmodel og akkumulerede i løbet af femten versioner funktioner: kryptering i 1.1, interaktive formularer i 1.2, digitale signaturer og logisk struktur i 1.3, gennemsigtighed i 1.4, objektstrømme i 1.5, AES-kryptering i 1.6. Adobe indsendte PDF 1.7 til ISO i 2007, og ISO 32000-1:2008 var resultatet. ISO 32000-2:2020 dækker PDF 2.0, som strammede op på flere underspecificerede områder, reviderede AES-256 nøgleafledningen (revision 6 erstattede revision 5) og tilføjede eksplicit support for tilknyttede filer og rich media

Substandarderne stammer fra den samme base. PDF/A (ISO 19005) bytter funktioner for arkivstabilitet: ingen kryptering, ingen eksterne indholdsafhængigheder, alle skrifttyper indlejret, farverum enhedsuafhængige, XMP-metadata påkrævet. PDF/A-1 er baseret på PDF 1.4, PDF/A-2 på PDF 1.7, PDF/A-3 tillader indlejrede filer af ethvert format. PDF/X (ISO 15930) er undergruppen til printproduktion: output-hensigter, beskærings- og trim-bokse, ingen gennemsigtighed i ældre overensstemmelsesniveauer. PDF/UA (ISO 14289) kræver tagged struktur, Unicode-kortlægninger og sprogmetadata for tilgængelighed. Disse er ikke konkurrerende formater; de er sæt af yderligere begrænsninger oven på kerne-PDF, og en enkelt fil kan overholde mere end én samtidigt, forudsat at begrænsningerne ikke er i konflikt med hinanden

For enhver, der skriver kode, der genererer eller behandler PDF, er den praktiske basislinje ISO 32000-2 med omhyggelig opmærksomhed på de sektioner, der dækker krydsreferencemodellen (§7.5), grafiktilstanden (§8.4), teksttilstandsoperatører (§9.3), skrifttypedeskriptorer og ToUnicode (§9.6 og §9.10), interaktive formularer (§12.7) og digitale signaturer (§12.8). Standarden er lang, men det meste programmatiske PDF-arbejde berører et snævert udsnit af det gentagne gange. At forstå objektmodellen og krydsreferencemekanismen er indgangspunktet; alt andet er specialisering derfra