Objektinumero (Object number 1 is not page) 1 ei ole sivu (page) 1. Tämä (That single fact trips up more) yksittäinen (single) fakta (fact) kompastuttaa enemmän (trips up more) PDF-käsittelykoodia (processing code than) kuin (than) mikään muu muodon aspekti (aspect of the format, and understanding), ja syyn (why) ymmärtäminen (understanding) edellyttää (requires looking past what a) sen (what a) taakse (past) katsomista, mitä (what a) katseluohjelma (viewer shows you and into the) sinulle näyttää, ja sen (into the) objektikaavion (object graph the) sisälle katsomista (into the), jota katseluohjelma (viewer actually reads) todellisuudessa (actually) lukee (reads)
PDF-tiedosto on (file is a collection of numbered indirect objects) numeroitujen epäsuorien objektien kokoelma (collection of numbered indirect objects). Jokainen objekti (Each object carries an) sisältää (carries an) objektinumeron ja (and a) generaationumeron (generation number, and other), ja (and) muut (other) objektit (objects point to it with a) osoittavat (point to it with a) siihen (it with a) viittauksella (reference written as), joka (written as) kirjoitetaan muodossa N G R: 3 0 R tarkoittaa (means the) objektin (object) 3 nykyistä versiota (current version of). Sivut (Pages are among those) kuuluvat (are among) näihin (those) objekteihin (objects, but their), mutta (but their) niiden näytön (display) sekvenssillä ei ole mitään tekemistä (has nothing to do with where) sen (where) kanssa (where they sit in the file or what numbers they carry), missä ne sijaitsevat (sit in the) tiedostossa (file or what) tai (or what) mitä (what numbers they) numeroita (numbers) ne (they) kantavat (carry). Näyttöjärjestyksen (Display order is determined entirely by the) määrittää täysin (entirely by the) /Pages -puu (tree, a linked structure rooted at the), linkitetty rakenne (linked structure rooted at the), joka juurtuu (rooted at the) asiakirjahakemistoon (document catalog. If you ignore the tree and scan). Jos (If you) ohitat puun (ignore the tree and scan) ja (and) skannaat (scan objects numerically, you will assemble pages in the wrong) objekteja (objects) numeerisesti (numerically, you will assemble pages in the wrong), kokoat (you will assemble pages in the) sivut väärässä järjestyksessä (wrong order for a significant) huomattavalle osalle reaalimaailman tiedostoista (significant fraction of real-world files)
Sivupuu (page tree): se, mikä (what actually sets the) todella (actually sets the) asettaa (sets the) järjestyksen (order)
Jokainen PDF (Every PDF begins with a document) alkaa (begins with a) asiakirjahakemistolla (document catalog) (ISO 32000-2 §7.7.2). Hakemisto sisältää (catalog holds a) /Pages-merkinnän (entry that points to the), joka osoittaa sivupuun juurisolmuun (root node of the page tree). Tuo (That root node is a) juurisolmu (root node is a) on (is a) sanakirja (dictionary with), jossa on /Type /Pages, /Kids-taulukko epäsuorista (indirect references, and a) viittauksista (references, and a), ja (and a) /Count, joka ilmoittaa sen (giving the total) alapuolella olevien (beneath it) lehtisivujen kokonaismäärän (total leaf-page count beneath it). Näyttöjärjestys (Display order is the depth-first) on tuon puun syvyys (depth-first) ensin, vasemmalta oikealle tapahtuva (left-to-right traversal of that) läpikäynti (traversal of that tree, full stop), piste (full stop)
Minimaalinen (A minimal three-page file makes this) kolmisivuinen tiedosto tekee tästä (makes this) konkreettisen (concrete):
%PDF-1.7
1 0 obj
<< /Type /Catalog /Pages 2 0 R >>
endobj
2 0 obj
<< /Type /Pages /Kids [20 0 R 4 0 R 9 0 R] /Count 3 >>
endobj
% Objekti (Object) 4 on tallennettu kolmantena (third in the) tiedostoon (file but is page), mutta on (but is page) näyttöjärjestyksessä (display order) sivu 2 (page 2 in)
4 0 obj
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792]
/Contents 5 0 R /Resources << /Font << /F1 6 0 R >> >> >>
endobj
% Objekti (Object 9 is stored fourth but is page) 9 on (is stored fourth but is page) tallennettu (stored) neljäntenä (fourth but is page), mutta on sivu 3
9 0 obj
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792]
/Contents 10 0 R /Resources << /Font << /F1 6 0 R >> >> >>
endobj
% Objekti (Object 20 is stored last but is page 1; Kids[0] decides, not object number) 20 on tallennettu viimeisenä (last but is page), mutta on sivu 1; Kids[0] päättää (decides, not object number), ei (not) objektinumero (object number)
20 0 obj
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792]
/Contents 21 0 R /Resources << /Font << /F1 6 0 R >> >> >>
endobj
/Kids-taulukko (array reads) lukee (reads) [20 0 R 4 0 R 9 0 R], joten objekti 20 on sivu 1, objekti 4 on sivu 2, ja objekti 9 on sivu 3. Objektien numeroinnilla ei ole merkitystä (Object numbering is irrelevant). Mikä tahansa koodi, joka (Any code that iterates objects in) käy objekteja läpi (iterates objects in) numeerisessa (numeric order and) järjestyksessä ja (order and collects those with) kerää (collects those with) ne (those with), joilla (with) on (with) /Type /Page, tuottaa (will produce the) väärän sekvenssin (wrong sequence on this file) tälle (on this) tiedostolle (file)
Miksi (Why do generators produce) generaattorit (generators produce non-sequential) tuottavat (produce) ei-peräkkäisiä (non-sequential layouts) asetteluita (layouts)? Syitä on useita (Several reasons). Kirjasto (A library that pre-allocates object numbers for all), joka (that pre-allocates object numbers for all pages before) varaa (pre-allocates object) objektinumerot etukäteen (pre-allocates object numbers for all) kaikille sivuille ennen (pages before writing their content will) niiden (their) sisällön kirjoittamista (writing their content will), numeroi (will number them in) ne luontijärjestyksessä (creation order, then) ja kirjoittaa sitten (then write actual) varsinaiset tavut siinä (bytes in whatever) järjestyksessä (order suits the), joka (whatever order suits the) sopii sarjallistajalle (serializer). Yhdistämistyökalu (A merge tool that stitches documents), joka neuloo asiakirjoja yhteen (stitches documents together renumbers objects from), numeroi kunkin lähdeasiakirjan (each source document to avoid) objektit (objects from) uudelleen välttääkseen törmäyksiä (collisions); uudelleennumeroidut sivuobjektit päätyvät (renumbered page objects end up) hajalleen yhdistetyn objektitaulukon (scattered across the combined object table while the) yli (across the), kun taas (while the) uusi juuren (new root) /Kids-taulukko (array holds the) sisältää (holds the) oikean näyttösekvenssin (correct display sequence). Inkrementaaliset päivitykset liittävät uusia objekteja tiedoston loppuun (file with fresh numbers, so a) tuoreilla numeroilla (fresh numbers, so a), joten (so a) versiona lisätty sivu elää (revision lives near the) lähellä (near the end of the) tavuvirran (byte stream even if it) loppua (end of the), vaikka se kuuluisi näyttöjärjestyksen (display order) paikkaan 1 (position 1 of the)
Litteät puut (Flat trees and) ja (and nested subtrees) sisäkkäiset alipuut (nested subtrees)
Määritys (spec permits two shapes for the) sallii (permits two) sivupuulle (page tree) kaksi (two) muotoa (shapes for the). Yksinkertaiset (Simple generators produce a) generaattorit (generators produce a) tuottavat (produce a) litteän rakenteen (flat structure: one root): yhden (one) juuren (root) /Pages-solmun (node whose), jonka (whose) /Kids-taulukko ei sisällä mitään muuta kuin (array contains nothing but) /Page -lehtiobjekteja (leaf objects). Se (That is easy to) on (is easy to traverse: one) helppo (easy to) käydä läpi (traverse: one): yhden (one) tason (level deep, one) syvyinen (deep, one), yksi läpikulku (pass)
Suuret asiakirjat (Large documents routinely use a balanced) käyttävät sen sijaan rutiininomaisesti (routinely use a) tasapainoista (balanced tree instead) puuta (tree instead). Juuren (root) /Pages-solmun /Kids-taulukko (array contains intermediate) sisältää (contains intermediate) väli- (intermediate) /Pages-solmuja (nodes, each of which in), joista kullakin puolestaan (each of which in turn holds a) on oma (of its own) /Kids-taulukkonsa. Kunkin (The) välisolmun (intermediate node reports the) /Count ilmoittaa (reports the) sen alipuussa olevien lehtisivujen (leaf pages in its subtree, so a) kokonaismäärän (total number of), joten katseluohjelma (viewer can skip entire subtrees when) voi (can) ohittaa (skip entire subtrees when) kokonaisia (entire) alipuita hypätessään sivulle indeksin (page by index without) perusteella ilman, että sen (without parsing every object) tarvitsee jäsentää jokaista (every) objektia (object). 1 000-sivuinen (A 1 000-page document structured as a) asiakirja, joka on (document structured as a) strukturoitu (structured as a balanced tree with 10) tasapainoiseksi (balanced) puuksi, jossa (with 10) on 10 sivua lehtisolmua kohden (pages per leaf node can), voi (can locate page) paikantaa sivun 750 binäärihaulla kolmen (binary search through three or) tai neljän (four) sanakirjahaun kautta sen sijaan (dictionary lookups rather than), että se (rather than) skannaisi (scanning 750) 750 /Kids-merkintää (entries)
Seuraus käsittelykoodille (processing code: you cannot assume the): et voi (cannot assume the) olettaa, että (assume the) /Kids-taulukon (Kids contains) ensimmäinen (first level of) taso sisältää (contains) /Page-objekteja (objects). Jokainen (Each child must be checked) lapsi on (child must be) tarkistettava (checked). Jos (If its) sen (its) /Type on (is) /Pages, siirry siihen rekursiivisesti (recurse into it). Jos (If its) sen /Type on /Page, se (it is a) on lehti (leaf). Pysähtyminen (Stopping at the) ensimmäiselle (first level silently drops entire) tasolle pudottaa (silently drops entire) hiljaisesti pois kokonaisia (entire subtrees on any document where the) alipuita mistä tahansa asiakirjasta (document where the), jossa (where the) generaattori (generator chose to) valitsi (chose to) sisäkkäisyyden (nest). Syyt siihen, miksi kirjoittajat ylipäänsä valitsevat syviä puita (Why writers choose deep trees in the first place, what), mistä (what flattening tools give) litistämistyökalut (flattening tools give up, and) luopuvat (give up, and) ja kuinka (how) /Count-korruptio (corruption plays out in) ilmenee käytännössä (plays out in practice is), on käsitelty rinnakkaisessa artikkelissamme (covered in our companion piece on) sivupuun muodosta, haarautumisesta ja /Count-eheydestä
Perityt (Inherited page attributes) sivuattribuutit (page attributes)
Sivupuu sisältää myös (also carries a) resurssienjakomekanismin (resource-sharing mechanism). Tietyt (Certain page) sivuattribuutit (page attributes: /MediaBox, /CropBox, /Resources, and): /MediaBox, /CropBox, /Resources ja (and) /Rotate ovat (are inheritable) perittäviä (inheritable) (ISO 32000-2 §7.7.3.4). Jos (If a) /Page-sanakirja (dictionary omits one of) jättää (omits one of) jonkin (one of them, a reader walks up the) niistä pois (omits one of), lukija kävelee /Parent-ketjua (chain until it finds the attribute or) ylöspäin (up the), kunnes (until it finds the) se löytää attribuutin (attribute or) tai saavuttaa juuren (reaches the root). Jaetun (Placing a shared font dictionary in the) fonttisanakirjan (font dictionary in the) sijoittaminen (Placing a shared) juuren (root) /Pages-solmuun (node rather than copying it into every) sen sijaan, että (rather than copying it into every) se (it into every) kopioitaisiin (copying it into every) jokaiselle (every) lehtisivulle (leaf page can), voi (can reduce file size noticeably for) pienentää tiedostokokoa (file size noticeably for) huomattavasti sellaisissa asiakirjoissa (documents that use the), jotka (that use the) käyttävät samoja kirjasintyyppejä kauttaaltaan (same typefaces throughout)
Perintäsääntö (inheritance rule creates a) luo (creates a) hienovaraisuuden koodille (subtlety for code that), joka lukee (reads page) sivuominaisuuksia (properties). /MediaBox-arvon lukeminen (Reading /MediaBox directly from a) suoraan (directly from a) /Page-objektista ja puuttuvan avaimen käsittely (treating a missing key as an error is) virheenä on (error is wrong; the) väärin (wrong; the); avain saattaa (key may simply be inherited) yksinkertaisesti (simply be) olla peritty (inherited). Koodin (Code that correctly resolves page), joka (that correctly resolves page) ratkaisee oikein sivun (page geometry must follow the parent chain) geometrian (geometry must follow the), on (must follow the) seurattava isäntäketjua (parent chain). Se vaatii myös (It also needs a cycle guard: a) syklisuojan (cycle guard: a): vioittuneessa (corrupted file can have a) tiedostossa (file can have a) voi (can have a) olla /Parent-viittaus (reference that points back to a), joka (that points back to a) osoittaa takaisin (back to a node already) solmuun, jossa on jo käyty (already visited, which would loop), mikä (which would loop forever without a) jäisi ikuiseen silmukkaan (loop forever without a) ilman (without a visited-object check) vierailtujen (visited-object check) objektien (visited-object check) tarkistusta (check)
Xref-taulukko (The xref table and) ja (and cross-reference streams) ristiviittausvirrat (cross-reference streams)
Epäsuoran (Indirect object lookup goes through the) objektin (object lookup goes through the) haku kulkee (goes through the) ristiviittaustaulukon (cross-reference table (or its) (tai (or its) sen (its successor, the) seuraajan (successor, the), PDF 1.5:ssä (PDF 1.5) esitellyn ristiviittausvirran (cross-reference stream introduced in)) kautta (through the). Xref kartoittaa kunkin (maps each object number to a) objektinumeron tiedoston (file) sisäiseen (within the) tavusiirtymään (byte offset within the). Määritysten mukainen lukija (conforming reader uses the) käyttää (uses the) xref:ää hypätäkseen (jump directly to any) suoraan mihin tahansa objektiin (object; it does not scan the); se ei (does not scan the) skannaa tiedostoa (file sequentially) peräkkäin (sequentially). Tuo (That random-access design is) satunnaissaantimalli (random-access design is what makes fast) on (is what makes fast) se, mikä tekee (what makes fast page jumping) nopeasta (fast) sivuilla hyppimisestä mahdollista (possible: the): katseluohjelma (viewer reads the catalog, resolves the) lukee hakemiston (catalog, resolves the), ratkaisee (resolves the) /Pages-viittauksen (reference via the) xref:n (xref, reads the) kautta (via the), lukee juuren /Pages-solmun, ratkaisee /Kids-merkinnän (entry, and so) ja niin edelleen (and so on, touching only the), koskettaen vain tarvitsemiaan (objects it needs) objekteja (objects it needs)
Inkrementaaliset päivitykset lisäävät (add a new xref section at the) uuden (new) xref-osion (section at the) tiedoston loppuun (end of the file with a trailer that) trailerilla varustettuna (with a trailer that chains back to the), joka (that) ketjuttuu takaisin edelliseen (previous one). Versiossa (in a revision gets a) päivitetty objekti saa uuden merkinnän liitetyssä (appended xref section; the) xref-osiossa; alkuperäiset (original bytes stay in) tavut pysyvät paikoillaan, mutta ne korvataan (superseded). Näin (This is how digitally signed PDFs remain verifiable even) digitaalisesti (digitally signed PDFs remain) allekirjoitetut PDF-tiedostot (signed PDFs remain verifiable even) pysyvät (remain) todennettavina jopa sen (even after annotation or form-fill revisions are) jälkeen, kun (after) huomautus- (annotation or) tai (or) lomakkeentäyttöversioita (form-fill revisions are added: the) on lisätty (added: the): allekirjoitettuun tavualueeseen (signed byte range is) ei koskaan (never touched, and the) kosketa (touched, and the), ja (and the) uusi (new) sisältö (content lives in the) elää liitetyssä osiossa. Myös sivupuuta (page tree can be updated) voidaan päivittää (updated too, so), joten version sivujen lisäykset tai poistot (additions or deletions in a) tuottavat (produce a) uuden /Pages-juuren, jolla (with a revised) on (with a revised) tarkistettu (revised) /Kids-taulukko, kun taas (while the old root object still occupies its) vanha (old root object still occupies its) juuriobjekti varaa (occupies its original position in the) edelleen (still occupies its) alkuperäisen (original) paikkansa (position in the) tiedostossa. Linearisoidut (Linearized (web-optimized) files add a) (verkko-optimoidut (web-optimized)) tiedostot (files add a byte-layout twist: the) tuovat (add a) tavujen asetteluun (byte-layout twist: the) pienen (twist: the) käänteen: sivun 1 objektit (objects for page 1 are physically moved to the) siirretään fyysisesti (physically moved to the front of the) tiedoston alkuun, jotta katseluohjelma (viewer can display the) voi (can) näyttää (display the first page while the) ensimmäisen sivun, kun (while the rest is) loppuosa latautuu vielä (still downloading, yet the), silti (yet the) sivupuu on edelleen (remains the) ainoa auktoriteetti (sole authority on) järjestyksestä (order) — vain (only the offsets recorded in the) xref:ään (xref change) tallennetut siirtymät (offsets recorded in the) muuttuvat
Mikä (What goes wrong without tree) menee (goes wrong without) pieleen ilman puun läpikäyntiä (tree traversal)
Objektiskannauslähestymistapojen (object-scan approaches is) epäonnistumistila (failure mode for) on (is) hiljainen (quiet). Tulosteasiakirja (output document looks) näyttää (looks) uskottavalta (plausible: it has the): siinä (it has the right number of) on oikea (right) määrä sivuja (pages and each), ja (and each page contains) jokainen (each) sivu sisältää tunnistettavaa (recognizable) sisältöä (content). Järjestys (order is just) on (is just) vain (just) väärä (wrong, and wrong in a), ja (and wrong in a) väärä tavalla (way that depends on the), joka (that depends on the) riippuu generaattorista, versioiden lukumäärästä (number of revisions, and whether any) ja siitä, yhdistettiinkö (whether any pages were merged from outside) sivuja (pages were merged from) ulkopuolisista (outside) lähteistä (sources). Yhden työkalun tuottama testikorpus tiedostoja voi mennä läpi (pass completely; files) täydellisesti (completely; files); eri työkalusta tai yhdistämistyönkulusta (merge workflow will) peräisin olevat tiedostot (files from a different tool or a) epäonnistuvat (fail). Tuo (That inconsistency is why) epäjohdonmukaisuus (inconsistency is why) on syy siihen (is why heuristic fixes never), miksi (why) heuristiset (heuristic fixes never hold) korjaukset (fixes never hold) eivät (never) koskaan pidä. Jos (For a walkthrough of) haluat nähdä läpikäynnin tismalleen tästä (exactly this failure in a) virheestä (failure in a) todellisessa (real customer document — symptom, misdiagnosis, and the) asiakasasiakirjassa — oire (symptom), väärä (misdiagnosis, and the) diagnoosi (misdiagnosis, and the) ja läpikäyntikorjaus (traversal fix) — katso (see) sivujärjestyksen virheenkorjauksen (debugging case study) tapaustutkimuksemme
Inkrementaalisesti päivitetyt tiedostot ovat erityisen alttiita tälle (are especially prone to this because pages added or rearranged in), koska (because pages added or) myöhemmissä (later revisions carry high) versioissa lisätyt tai uudelleenjärjestellyt sivut kantavat korkeita objektinumeroita, kun (while the display order is) taas (while the) näyttöjärjestystä (display order is controlled by the) ohjaa (controlled by the updated) päivitetty (updated) /Kids-taulukko. Skannaus (scan that processes objects in), joka (that processes objects in numeric order will) käsittelee objektit (objects in) numeerisessa (numeric order will) järjestyksessä (order will), sijoittaa (will place those) nuo (those) myöhään numeroidut (late-numbered) sivut (pages at the) loppuun (end regardless of where the) riippumatta (regardless of where the) siitä, minne puu (tree says they) sanoo (says they belong) niiden (they belong) kuuluvan (belong)
Korjaus ei ole monimutkainen (complicated). Aloita hakemistosta (catalog, resolve the), ratkaise /Pages-viittaus (reference, walk the), käy /Kids-taulukko läpi (walk the) rekursiivisesti, ja (and emit leaves in the) lähetä (emit leaves in the) lehdet (leaves in the) siinä järjestyksessä kuin (order you encounter them) kohtaat ne. Se on määritelmän mukainen näyttöjärjestys, riippumatta (regardless of object numbers, byte offsets, or file) objektinumeroista, tavusiirtymistä (byte offsets, or file structure) tai tiedoston (file structure) rakenteesta. Useimmat (Most mature PDF libraries expose a) kypsät PDF-kirjastot (mature PDF libraries expose a page count and an) paljastavat sivumäärän ja (page count and an indexed page accessor that) indeksoidun sivunkäyttöliittymän (indexed page accessor that already do this), jotka (that already do this correctly; the) tekevät (do this) tämän (this correctly; the) jo (already) oikein; riski piilee koodissa (risk is in code that), joka (that bypasses the) ohittaa (bypasses the library's) kirjaston (library's page model and) sivumallin (page model and touches the) ja koskettaa objektikerrosta (object layer directly) suoraan
Yksi (One structural anomaly worth handling explicitly: the) rakenteellinen anomalia on syytä (worth handling explicitly: the) käsitellä eksplisiittisesti (explicitly: the): /Count-arvo (Count value on an intermediate) välillä olevassa (intermediate) /Pages-solmussa (node can be wrong in) voi (can be wrong in malformed files) olla (be wrong in) väärä (wrong in) viallisissa tiedostoissa. /Count-arvoon (Trusting) luottaminen (Trusting) rajatarkistuksissa (bounds checking and then) ja (and then stopping short of a) sen (then stopping short of a) jälkeen (then) täyden läpikäynnin pysäyttäminen kesken (stopping short of a full traversal will) jättää (will silently omit pages when the) sivuja hiljaisesti pois, kun (when the count is) määrä on ilmoitettu todellista (count is understated) pienemmäksi (understated). Turvallisempi kuvio (safer pattern for) tärkeille asiakirjoille on (is the safer pattern for important documents) käyttää (Using) /Count-arvoa (Count only as a performance hint for) vain (only as a performance hint for) suorituskykyvihjeenä (performance hint for capacity pre-allocation or) kapasiteetin etukäteisvaraukselle tai (or) binäärihaulle, ja (and deriving the) johtaa (deriving the actual count from) todellinen (actual count from) määrä läpikäynnistä (traversal is the safer pattern for)