PDFium Component for Delphi validoi painovalmiit PDF/X-dokumentit metodilla TPdf.ValidatePdfX, joka toteuttaa ISO 15930 -tarkistuksen kahdessa kerroksessa: kahdeksan tavutason sisältötarkistusta (kielletty LZW-pakkaus, JavaScript, lomakekentät, OPI-viittaukset, puuttuva TrimBox, asettamaton Trapped-avain ja muuta) sekä PDFiumin oliomallin läpikäynti, joka varmistaa FPDFFont_GetIsEmbedded-kutsulla fonttien upotuksen jokaisen sivun jokaisessa tekstiobjektissa. Tuloksena on TPdfXValidationResult-tietue, joka nimeää havaitun vaatimustason ja luettelee jokaisen rikkomuksen tyypitettynä luettelotyyppinä, joten Delphi-sovelluksesi voi kertoa asiakkaalle täsmälleen miksi tiedosto kimpoaa takaisin painosta ennen kuin kukaan polttaa levyä
Jos olet joskus lähettänyt työn kuriirilla kirjapainoon ja saanut sen takaisin yhden rivin hylkäyksellä — "ei TrimBoxia", "fontteja ei ole upotettu", "Trapped ei ole asetettu" — tiedät myöhään selviämisen hinnan. PDF/X on PDF/A:n painoteollinen vastine: siinä missä arkistoiva PDF/A takaa, että dokumentti piirtyy identtisesti vuosikymmenten päästä, PDF/X takaa, että dokumentti värierotellaan, kuvitetaan ja leikataan identtisesti jonkun toisen RIPissä huomisaamuna. Kaksi standardia jakavat koneistoa (XMP-tunnistus, OutputIntents, upotetut ICC-profiilit) mutta vastaavat eri kysymyksiin, ja siksi komponentti toimittaa kummallekin oman validaattorinsa — PDF/A-puoli käsitellään artikkelissa PDF/A-preflight-validointi PDFium Componentilla
Mitä ISO 15930 oikeastaan vaatii painovalmiilta PDF:ltä?
ISO 15930 on olemassa tehdäkseen sokean vaihdon mahdolliseksi: suunnittelija ojentaa tiedoston kirjapainolle, jonka kanssa hän ei ole koskaan puhunut, ja paino pystyy tuottamaan oikean lopputuloksen ilman puhelinsoittoa, ilman puuttuvan fontin sähköpostia ja ilman linkitettyä kuvaa, joka jäi suunnittelijan kannettavaan. Standardin jokainen sääntö palvelee tuota tavoitetta. Fontit on upotettava, koska vastaanottavan RIPin ei voi olettaa omistavan niitä. Ulkoiset viittaukset ovat kiellettyjä, koska tiedoston on oltava itsessään täydellinen. Interaktiiviset ominaisuudet ovat kiellettyjä, koska musteella ei ole onclick-käsittelijää
PDFium Component tunnistaa kolme vaatimusperhettä ja raportoi ne validointituloksen TPdfXConformance-luettelotyypin kautta: pxc1a vastaa PDF/X-1a:2001:tä (ISO 15930-1, tiukka CMYK-plus-spottiväri-perustaso PDF 1.3/1.4:n päällä), pxc3 vastaa PDF/X-3:2002:ta (ISO 15930-3, joka sallii RGB:n, Labin ja ICC-hallitun värin) ja pxc4 vastaa PDF/X-4:2010:tä (ISO 15930-7, joka viimein sallii elävän läpinäkyvyyden ja tasot PDF 1.6:n pohjalla). Tiedosto, joka ei kanna lainkaan PDF/X-tunnistusta, palautuu arvona pxcNone, mikä on itsessään hyödyllinen vastaus: dokumentti ei koskaan väittänytkään olevansa painovalmis, ja kaikki muu mitä validaattori raportoi selittää, mitä sinne pääsy vaatisi
Kiellot käyvät järkeen heti kun ajattelee kuten RIP-toimittaja. /LZWDecode on kielletty jokaisessa PDF/X-muunnelmassa, jottei vaatimuksia noudattava kuluttaja koskaan riipu suodattimesta, jolla on yhteensopivuus- ja lisensointihistoria; Flate tekee saman työn ilman painolastia. JavaScript, AcroForm-kentät ja /AA-lisätoimintosanakirjat ovat kiellettyjä, koska painotiedoston on oltava kiinteä kuvaus paperilla olevista merkeistä — mikä tahansa, joka voi muuttaa ulkoasua avaushetkellä, rikkoo takuun siitä että vedostettu on se mikä painuu. OPI-paikanpitäjät (Open Prepress Interface) ovat kiellettyjä, koska ne ovat suunnittelultaan viittauksia korkearesoluutioisiin kuviin, jotka on tallennettu jonnekin muualle, ja "jonnekin muualle" on juuri se, minkä sokea vaihto kieltää
Miksi kirjapainot hylkäävät PDF-tiedostot ilman TrimBoxia?
TrimBox on valmis sivu — se suorakulmio, joka jää jäljelle giljotiinin leikkausten jälkeen. MediaBox, joka on jokaisella PDF-sivulla, on pelkkä arkki: siihen kuuluvat leikkuuvara, leikkuumerkit, kohdistusmerkit ja väripalkit. Arkkiasemointiohjelmisto sijoittaa sivut painoarkille niiden TrimBoxien mukaan; ilman sitä operaattorin on arvattava, mihin käyntikorttisi oikeasti päättyy, ja väärä arvaus leikkaa leikkuuvaran pois tai jättää valkoisen siivun toiseen reunaan. Siksi ISO 15930 vaatii TrimBoxin (tai ArtBoxin) jokaiselle sivulle, ja siksi ValidatePdfX nostaa arvon pvxiMissingTrimBox, kun yhdeltäkään dokumentin sivulta ei löydy /TrimBox-avainta
/Trapped-avain vastaa toiseen tuotannolliseen kysymykseen. Ylitäyttö on painoa edeltävä tekniikka, jossa vierekkäisiä värejä limitetään hieman, jottei painokoneen pienoinen kohdistusvirhe avaa niiden väliin valkoisia rakoja. Painon on tiedettävä, onko tuo työ jo tehty: jo ylitäytetyn tiedoston ylitäyttö kaksinkertaistaa limitykset, ja ylitäyttämättömän tiedoston ohittaminen uhkaa jättää näkyviä rakoja. Siksi PDF/X vaatii, että Info-sanakirja ilmoittaa /Trapped /True tai /Trapped /False nimenomaisesti — puuttuva avain tai /Unknown pakottaa ihmisen tarkastamaan tiedoston, mikä on juuri se keskustelu, jonka sokean vaihdon oli määrä poistaa. Komponentti merkitsee tämän arvolla pvxiTrappedNotSet
Kaksikerroksisen validoinnin ajaminen metodilla TPdf.ValidatePdfX
TPdf.ValidatePdfX ei ota argumentteja ja palauttaa TPdfXValidationResult-tietueen, jossa on kolme jäsentä: Conformance (havaittu PDF/X-muunnelma), Issues (Pascal-joukko TPdfXValidationIssue-arvoja) ja IsCompliant-apufunktio. Sisäisesti se sarjallistaa ladatun dokumentin muistivirtaan, ajaa tavutason tarkastajan sen yli ja kulkee sitten PDFiumin oliomallin läpi fonttikohtaista upotustarkistusta varten. Minimaalinen preflight-portti näyttää tältä:
uses PDFium, FPdfPdfx;
procedure CheckPrintReadiness(const FileName: string);
var
Pdf: TPdf;
Res: TPdfXValidationResult;
begin
Pdf := TPdf.Create(nil);
try
Pdf.FileName := FileName;
Pdf.Active := True;
Res := Pdf.ValidatePdfX;
Writeln('Detected conformance: ',
Ord(Res.Conformance)); // pxc1a, pxc3, pxc4, pxcNone...
if Res.IsCompliant then
Writeln('PDF/X checks passed')
else
begin
if pvxiMissingTrimBox in Res.Issues then
Writeln('REJECT: no /TrimBox on the pages');
if pvxiTrappedNotSet in Res.Issues then
Writeln('REJECT: /Trapped missing or /Unknown');
if pvxiPdfiumFontNotEmbedded in Res.Issues then
Writeln('REJECT: a page uses a non-embedded font');
if pvxiLzwForbidden in Res.Issues then
Writeln('REJECT: LZWDecode filter present');
end;
finally
Pdf.Free;
end;
end;
Koska Issues on tavallinen Pascal-joukko, voit ositella sen juuri niin kuin työnkulkusi vaatii — käsittele rakenteelliset ongelmat kovina hylkäyksinä, käsittele pvxiMissingTitle (standardissa SHOULD eikä MUST) varoituksena ja lokita loput. Sama tietuetyyppi syöttää myös komponentin raporttigeneraattoria, joten jos haluat mieluummin tuottaa ihmisluettavan dokumentin kuin haarautua luettelotyypeillä, artikkelin erä-preflight-raportin CLI:n rakentaminen PDFium Componentilla kuvio pätee PDF/X:ään sellaisenaan
Mitä tavutason kerros nappaa — ja mitä siltä jää huomaamatta
Tavutason kerros on merkkiselaus dokumentin rakenteellisten tavujen yli niin että stream-rungot on tyhjennetty, joten JPEG, joka sattuu sisältämään tavukuvion /JavaScript, ei voi laukaista väärää positiivista. Merkkitarkistusten päälle (XMP pdfxid:GTS_PDFXVersion, OutputIntent upotetulla ICC-profiililla, trailerin /ID, salauskielto) sisältöläpikäynti lisää kahdeksan tarkistusta, kullakin oma luettelotyyppiarvonsa:
pvxiLzwForbidden—/LZWDecode-suodatin esiintyy jossain tiedostossa (kielletty kaikissa PDF/X-muunnelmissa)pvxiJavaScriptForbidden—/JavaScript-toiminto tai nimipuu on läsnäpvxiFormFieldsForbidden—/AcroForm-sanakirja tai/XFA-merkintä on olemassapvxiAdditionalActions—/AA-lisätoimintosanakirja on läsnäpvxiEmbeddedFilesForbidden—/EmbeddedFilestai/FileAttachment-merkintä on läsnäpvxiOpiForbidden—/OPI- tai/Alternates-merkintä viittaa korvattavaan kuvasisältöönpvxiMissingTrimBox— yhdeltäkään sivulta ei löydy/TrimBox-avaintapvxiTrappedNotSet—/Trappedpuuttuu tai on asetettu arvoon/Unknown
Tavuselaus on nopeaa eikä tarvitse piirtomoottoria, mutta siinä on synnynnäinen sokea piste fonttien suhteen: tuolla tasolla tarkastaja voi soveltaa vain karkeaa heuristiikkaa — se merkitsee dokumentin, kun se ei löydä lainkaan upotettua fonttiohjelmaa. Tiedosto, jossa on yhdeksän fonttia upotettuna ja yksi järjestelmäfontti livahtanut mukaan, näyttää tavuselaukselle moitteettomalta. Tuo yksi aukko on syy toisen kerroksen olemassaoloon
Fonttikohtainen upotus PDFiumin oliomallin kautta
PDFium Componentin oliomallikerros vastaa fonttikysymykseen täsmällisesti. Tavutason läpikäynnin jälkeen TPdf.ValidatePdfX käy läpi jokaisen sivun, kysyy objektiluetteloa FPDFPage_CountObjects-kutsulla ja ratkaisee jokaiselle tekstiobjektille fonttikahvan FPDFTextObj_GetFont-kutsulla sekä kyselee FPDFFont_GetIsEmbedded-arvon. Yksi upottamaton fontti missä tahansa dokumentissa lisää arvon pvxiPdfiumFontNotEmbedded ongelmajoukkoon. Läpikäynti oikosulkeutuu kahdella tasolla — se lopettaa sivun objektien selaamisen ja lopettaa lisäsivujen lataamisen heti kun ongelma on vahvistettu — joten rikkovassa 300-sivuisessa luettelossa tuomio saapuu usein ensimmäisen sivun jälkeen
Kaksi rajahuomiota kannattaa tietää. Ensinnäkin tämä kerros tarvitsee ladatun PDFium-kirjaston ja vaatii käännökset, jotka vievät ulos FPDFFont_GetIsEmbedded-funktion; kun vienti puuttuu, tarkistus ohitetaan eikä hylätä, joten vanhempi DLL ei koskaan tuota haamuhylkäyksiä. Toiseksi tarkistus vastaa vain kysymykseen "upotettu vai ei" eikä mihinkään muuhun — se ei erota täyttä upotusta osajoukotuksesta eikä tarkastele merkkien kattavuutta. Kun tiedosto hylkääntyy ja sinun on tiedettävä mikä fontti millä sivulla, artikkelin PDF:n fonttiominaisuuksien analysointi PDFiumilla Delphissä luettelointitekniikat jatkavat täsmälleen siitä mihin validaattorin totuusarvo loppuu
Virtojen validointi ilman dokumentin lataamista — tai DLL:ää
Tavutason tarkastaja on tarjolla myös itsenäisenä funktiona, ValidatePdfXCompliance(Source: TStream) FPdfPdfx-yksikössä, ja se on puhdasta Object Pascalia ilman riippuvuutta PDFium-DLL:ään. Se tekee siitä käyttökelpoisen paikoissa, joihin piirtomoottori ei ole tervetullut: kevyt latausportti verkkopalvelimella, CI-työ joka seuloo tuotettua kuvitusta, tai Lazarus-palvelu alustalla, jolle et mieluusti toimittaisi natiivibinäärejä. Syötä sille mikä tahansa siirrettävä virta:
uses Classes, FPdfPdfx;
function QuickPdfXGate(const FileName: string): Boolean;
var
Fs: TFileStream;
Res: TPdfXValidationResult;
begin
Fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Res := ValidatePdfXCompliance(Fs);
Result := Res.IsCompliant and (Res.Conformance <> pxcNone);
finally
Fs.Free;
end;
end;
Vaihtokauppa on suora: itsenäinen polku ajaa merkkitarkistukset ja kaikki kahdeksan sisältötarkistusta, mutta ei fonttikohtaista PDFium-kerrosta, joten sen fonttituomio putoaa takaisin karkeaan heuristiikkaan. Järkevä arkkitehtuuri käyttää ValidatePdfXCompliance-funktiota halpana ensiporttina ja varaa täyden TPdf.ValidatePdfX-tarkistuksen niille tiedostoille, jotka pääsevät siitä läpi
Mihin tämä validaattori päättyy ja täysi preflight alkaa
Rehellisyydellä on merkitystä preflight-työkaluissa, joten tässä on raja. ValidatePdfX varmistaa tunnistusmerkinnät, rakenteelliset kiellot, sivugeometrian avaimet, Trapped-ilmoituksen ja fonttien upotuksen aina yksittäisiin tekstiobjekteihin asti. Se ei mittaa musteen kokonaispeittoa, ei validoi että jokainen väriavaruus on väitetylle muunnelmalle sallittu (esimerkiksi X-1a:n vain CMYK -sääntö), ei tarkista kuvien resoluutiota rasteritiheyttä vasten eikä arvioi päällepainatuksen ja läpinäkyvyyden litistyksen käyttäytymistä — ne vaativat värihallitun preflight-moottorin, ja yksikön oma dokumentaatio kehottaa parittamaan sen sellaisen kanssa lopullista sertifiointia varten. Kaksikerroksinen tarkistus antaa sinulle sen 80 prosenttia hylkäyksistä, jotka ovat rakenteellisia ja aikaisin havaittavia, napattuna millisekunneissa omassa Delphi-koodissasi eikä huomisessa sähköpostissa painosta
Molemmat validointikerrokset, PDF/X-merkintöjen syöttörajapinnat vaatimustenmukaisen tulosteen tuottamiseen sekä samaa arkkitehtuuria jakavat PDF/A-, PDF/UA-, PDF/E- ja PDF/VT-validaattorit toimitetaan tuotteessa PDFium Component Delphille ja C++Builderille — yksi komponentti, piirrosta painon porttivahtiin