Transakcijska tiskara vraća vam seriju obračuna od 80,000 stranica s odbijenicom od jedne rečenice: "not PDF/VT, RIP cannot cache." Datoteka se normalno otvara u svakom pregledniku na radnom stolu, boje su točne, podaci su se ispravno spojili. Ništa od toga nije ono što je digitalna preša tražila. Brzi ispis varijabilnih podataka živi ili umire o tome može li preša prepoznati da je blok s logotipom kupca na stranici 1 bajt-po-bajt isti objekt kao i onaj na stranici 40,000, jednom ga iscrtati i ponovno upotrijebiti. PDF/VT je standard koji tu tvrdnju čini strojno provjerljivom, a "izgleda ispravno" upravo je zamka, jer je struktura koju RIP čita nevidljiva na ekranu
PDFiumPas tu strukturu izlaže kroz malo sučelje na TPdf: SaveAsPdfVT zapisuje, ValidatePdfVT provjerava. Ovaj članak govori o tome što ta dva metoda doista upisuju na disk i pregledavaju, gdje je ISO 16612-2 stroži nego što na prvi pogled izgleda, i koji su dijelovi poštena strukturna sidra, a ne potpuni preflight koji možete naplatiti klijentu
Što PDF/VT standardizira i zašto prvo dolazi PDF/X
PDF/VT (ISO 16612-2:2010) nije novi format datoteke. To je sloj optimizacijskih metapodataka nadograđen na PDF/X datoteku, i taj je redoslijed presudan. Standard definira tri razine usklađenosti, ali samo dvije od njih imenuju PDF datoteku: PDF/VT-1, a single self-contained document, and PDF/VT-2, a file-set model where pages reference shared external resources. The third token you may see, PDF/VT-2s, nije uopće vrijednost na razini datoteke; ona živi u MIME zaglavlju streama opisanom u Dodatku A. Ako pronađete kôd koji utiskuje GTS_PDFVTVersion = "PDF/VT-2s" u dokumentov XMP, taj je kôd pogrešan
Neupitan pravilnik za jednu datoteku jest PDF/X osnova. ISO 16612-2 §6.2.1 zahtijeva da svaka PDF/VT-1 datoteka također bude valjana PDF/X-4 datoteka. PDF/VT-2 skup datoteka, prema §6.2.2, umjesto toga mora stajati na PDF/X-4p, PDF/X-5g ili PDF/X-5pg. Zato pisac PDF/VT-a ne može samo dodati nekoliko identifikacijskih ključeva: mora ponijeti cijeli set oznaka PDF/X-4, što znači OutputIntent, ugrađeni ICC profil odredišta, odgovarajuće XMP i Info unose dokumenta, trailer /ID, a bez enkripcije. Preskočite bilo što od toga i imate datoteku koja tvrdi da je PDF/VT, a pada u trenutku kada je usklađeni potrošač provjeri prema osnovi. PDFiumPas tretira sloj PDF/X-4 kao dio spremanja PDF/VT-a, pa ne pozivate zaseban SaveAsPdfX prvo; injektor zapisuje oba sloja u jednom prolazu
Pisanje datoteke s SaveAsPdfVT
Minimalni poziv ne treba ništa osim aktivnog dokumenta, jer TPdfVTSaveOptions.Default isporučuje ugrađeni sRGB ICC profil i usklađenost pvc1. Spremanje interno prolazi kroz tri koraka: uklanja svaku zaštitu (ubacivanje čistog teksta u šifrirani object stream bi ga oštetilo), povezuje postojeći Info rječnik dokumenta i trailer /ID u set oznaka tako da se XMP i Info vrijednosti slažu, zatim dodaje PDF/X-4 i PDF/VT objekte kroz inkrementalni update
var
Pdf: TPdf;
begin
Pdf := TPdf.Create(nil);
try
if Pdf.LoadFromFile('statements-merged.pdf') then
begin
// Default options: built-in sRGB OutputIntent, PDF/VT-1, synthesised DPart
if Pdf.SaveAsPdfVT('statements-pdfvt.pdf') then
Writeln('PDF/VT-1 written')
else
Writeln('Save failed (document not active?)');
end;
finally
Pdf.Free;
end;
end;
Za stvarni produkcijski izlaz gotovo uvijek želite nadjačati OutputIntent karakterizacijom svoje preše, a ne generičkim sRGB fallbackom. Dostavite ICC bajtove i identifikatore uvjeta kroz TPdfVTSaveOptions:
var
Pdf: TPdf;
Opt: TPdfVTSaveOptions;
Icc: TBytes;
begin
Pdf := TPdf.Create(nil);
try
Pdf.LoadFromFile('directmail-merged.pdf');
Icc := LoadIccProfile('GRACoL2013_CRPC6.icc'); // your own loader
Opt := TPdfVTSaveOptions.Default;
Opt.Conformance := pvc1; // pvc2 is normalised to pvc1 on write
Opt.IccProfileData := Icc;
Opt.OutputConditionIdentifier := 'CGATS21_CRPC6';
Opt.OutputCondition := 'Commercial print, coated, CRPC6';
Opt.RegistryName := 'http://www.color.org';
Opt.Title := 'Spring 2026 Direct Mail Run';
Opt.Trapped := ptvFalse; // PDF/X Info /Trapped state
Pdf.SaveAsPdfVT('directmail-pdfvt.pdf', Opt);
finally
Pdf.Free;
end;
end;
Jedan detalj u tom isječku namjerno je ograničenje, a ne mana o kojoj možete raspravljati. Postavljanje Opt.Conformance := pvc2 ne proizvodi PDF/VT-2 datoteku. Pisac normalizira svaki zahtjev koji nije pvc1 natrag na pvc1, jer PDF/VT-2 je format skupa datoteka, a pisac za jednu datoteku koji dodaje jedan izlazni dokument fizički ne može sastaviti skup vanjskih resursa koji traži §6.2.2. Vrijednost pvc2 postoji za put čitanja, pa ValidatePdfVT može prepoznati i prijaviti postojeći dokument skupa datoteka; to nije cilj pisanja
DPart stablo: struktura koju RIP doista čita
Srce PDF/VT-a je hijerarhija Document Part (DPart). Ona omogućuje tiskari da dugačak run podijeli u zapise, grupira zapise u primatelje ili poštanske pakete, i priloži Document Part Metadata tako da downstream oprema može usmjeravati i naplaćivati svaki komad. ISO 16612-2 §6.5 opisuje povezivanje: katalog nosi /DPartRoot, korijenski DPart čvor nosi /DPartRootNode i /NodeNameList koji imenuje svaku razinu hijerarhije, leaf DPartovi pokrivaju raspon stranica stabla, a svaka stranica koja pripada dijelu pokazuje natrag na svoj list preko unosa /DPart na razini stranice
Kad izvorni dokument već sadrži upotrebljivu hijerarhiju, SaveAsPdfVT je čuva. Kad ne sadrži, pisac sintetizira minimalnu: jedan DPart na razini dokumenta koji obuhvaća trenutno stablo stranica redom, s /DPart povratnom referencom dodanom svakom živom objektu stranice i jednorazinskim /NodeNameList [/Document]. Budite iskreni prema sebi o tome što je to minimalno stablo. To je strukturno sidro koje zadovoljava zahtjeve oblika iz §6.5; nije poslovni metapodatak. Ono ne može izmišljati primatelje, granice poštanskih jedinica ni proizvodne serije, jer te informacije nikad nisu bile u izvoru. Ako imate podatke po primatelju, očekuje se da sami izgradite dublje DPart stablo i proširite /NodeNameList tako da odgovara razinama koje stvarate
Provjera koja ide dalje od prisutnosti ključeva
ValidatePdfVT vraća TPdfVTValidationResult zapis s tri stvari: otkrivenom Conformance, skupom Issues, i pomoćnikom IsCompliant koji je true samo kada je conformance stvarna razina i skup problema prazan. Enumeracija problema namjerno je specifična, pa neuspjeli rezultat kaže koji ste članak propustili, a ne samo "invalid":
var
Pdf: TPdf;
Res: TPdfVTValidationResult;
begin
Pdf := TPdf.Create(nil);
try
Pdf.LoadFromFile('statements-pdfvt.pdf');
Res := Pdf.ValidatePdfVT;
if Res.IsCompliant then
Writeln('PDF/VT compliant: ', VTLevelName(Res.Conformance))
else
begin
if pvviMissingDPartRoot in Res.Issues then
Writeln('DPart hierarchy missing or unusable');
if pvviMissingPdfXIdentifier in Res.Issues then
Writeln('PDF/X-4 base identifier absent');
if pvviMissingOutputIntent in Res.Issues then
Writeln('OutputIntent / ICC profile missing');
if pvviEncryptionPresent in Res.Issues then
Writeln('Encrypted - PDF/X forbids this');
end;
finally
Pdf.Free;
end;
end;
Dvije provjere koje vrijedi dubinski razumjeti su uparivanje usklađenosti i DPart prolaz, jer su obje prije bile preblage i pooštrene su da odgovaraju specifikaciji. Na strani uparivanja, validator radi točno podudaranje, a ne "bilo koji PDF/X će proći": PDF/VT-1 datoteka prihvaća se samo na PDF/X-4 PDF/X-4 bazu, i PDF/VT-2 datoteka samo na PDF/X-4p, PDF/X-5g, ili PDF/X-5pg. Marker PDF/VT-1 na PDF/X-1a bazi prijavljuje se, ne prolazi dalje
DPart prolaz je mjesto gdje leži većina strogosti. Nije dovoljno da katalog ima /DPartRoot ključ, jer krivotvoreni prazan objekt ili onaj bez veza na stranice i dalje ne može biti potrošen.HasValidDPartHierarchy i rekurzivni ValidateDPartNode prate cijelu strukturu: prate roditeljske veze, odbacuju duple djece i cikluse, nameću da /Start i /DParts budu međusobno isključivi, i zahtijevaju da rasponi stranica lista pokriju stablo stranica u dubinskom redoslijedu, a svaka stranica mora imati svoj /DPart koji pokazuje na list koji je sadrži. Svi ti unutarnji kvarovi slijevaju se u jedan jedini bit problema pvviMissingDPartRoot umjesto da šire javnu enumeraciju, pa taj jedan zastavicu tretirajte kao "DPart hijerarhija je neupotrebljiva", a ne doslovno "root ključ nedostaje"
Tri sintaktičke zamke koje validator sada provjerava
Uzastopni prolazi kroz §6.5 Tablicu 4 otkrili su oblike koje su ranije verzije prihvaćale, a standard ne. To su stvari koje ručno građeno DPart stablo lako pogriješi, pa ih vrijedi izričito navesti:
/DPartsje niz nizova, a ne ravni niz. Svaki element vanjskog niza mora sam biti niz indirektnih referenci. Ravni/DParts [9 0 R]se odbacuje; usklađeni oblik je/DParts [[9 0 R] [10 0 R]]. Time se ne-hijerarhijska struktura sprječava da se prerušava u valjanu razinu/Endsamo označava stvarni višestranični raspon. List DPart može nositi/Endsamo kada također ima/Start, i/Endmora dolaziti kasnije od/Startu redoslijedu stabla stranica. Degenerirani/Start 3 0 R /End 3 0 Rsada čini hijerarhiju neupotrebljivom umjesto da se čita kao jednodijelni dio/NodeNameListnazivi moraju proći PDF name unescaping kao XML NMTOKEN-ovi. Naziv poput/Bad#20Namese proširi u onaj koji sadrži razmak, a to nije valjani token. Implementacija radi laganu ASCII provjeru (slova, znamenke,.,-,_,:, plus non-ASCII bytes) that catches whitespace and delimiter mistakes without rejecting legitimate localized or vendor-specific names
XMP oznake: dva načina za zapis iste osobine
PDF/VT identifikacija živi u XMP-u pod pdfvtid namespaceom, konkretno GTS_PDFVTVersion i GTS_PDFVTModDate, uz standardne xmp:CreateDate i xmp:ModifyDate. Suptilnost koja uzrokuje lažna izvješća o "missing" u naivnim čitačima jest da se bilo koji od njih može serijalizirati na dva načina: kao tekst elementa (<pdfvtid:GTS_PDFVTVersion>PDF/VT-1</pdfvtid:GTS_PDFVTVersion>) ili kao RDF atribut na description elementu. PDFiumPas čita oba oblika, pa datoteka koju je drugi alat zapisao u atributskom stilu nije kažnjena. Također provodi §6.3 pravilo dosljednosti da GTS_PDFVTModDate mora biti jednak xmp:ModifyDate; neusklađenost podiže pvviModDateMismatch
Još jedno pravilo iz istog članka: nepoznata vrijednost GTS_PDFVTVersion čuva se kao pvcUnknown umjesto da se preklopi natrag na pvcNone. Ta razlika operativno je važna. pvcNone znači "nema PDF/VT oznake uopće, običan PDF", dok pvcUnknown znači "nešto je utisnulo verziju koju ovaj validator ne prepoznaje" (među njima i slučaj PDF/VT-2s). Spajanje ta dva sakrilo bi neispravnu datoteku u istu ladicu kao običan dokument
Gdje završava jamstvo
Vrijedi precizno odrediti granicu onoga što ove metode obećavaju, jer usklađenost varijabilnog ispisa nosi stvaran novac. Provjere DPart i pairinga su strukturna provjera na razini bajtova. One potvrđuju da su optimizacijski kostur, osnovni PDF/X-4 markeri, OutputIntent i XMP prisutni i međusobno dosljedni. To nije preflight PDF/X-4 na razini sadržaja: ne provjeravaju je li svaka boja unutar deklariranih izlaznih uvjeta, jesu li svi fontovi ugrađeni ili je li se provukao neki zabranjeni rubni slučaj blending prozirnosti. Za posao koji idete staviti na ugovornu prešu, spojite strukturnu provjeru PDFiumPasa s namjenskim PDF/X preflight engineom i probnim otiskom, isto kao što biste provjerili bilo koju drugu tvrdnju o usklađenosti. Strukturni sloj hvata kvarove koji tiho razbijaju RIP cache; to je jedna polovica potpune provjere, ne cijela
Ako te provjere ugrađujete u širi release gate, isti pristup skeniranja na razini bajtova stoji iza ostalog standardskog rada biblioteke, uključujući provjeravanje object i cross-reference streamova prije nego što datoteka ikad dođe do preflighta, i disciplinu zajedničkih objekata iza ponovno upotrebljivi pečati stranica s Form XObjectima koji čini dokument pogodnim za RIP od samog početka. API-ji za spremanje i provjeru PDF/VT-a i PDF/X-a opisani ovdje dio su PDFium VCL komponente za Delphi i C++Builder, čija stranica proizvoda sadrži potpunu referencu usklađenosti