Technical Article

PDF/A, PDF/X ir PDF/UA failų kūrimas „Delphi“ aplinkoje: „HotPDF“ vadovas

PDF/A, PDF/X ir PDF/UA yra trys skirtingi standartai, sprendžiantys tris skirtingas problemas: ilgalaikį archyvavimą, spaudos mainus ir prieinamumą (angl. accessibility). Tai nėra trys varnelės vienoje atitikties formoje, o dažniausia klaida yra elgtis su jais taip, tarsi jie būtų suderinami. Failas gali būti nepriekaištingas PDF/A dokumentas, bet visiškai nenaudingas spaustuvei; puikus spaudos maketas gali būti neįskaitomas ekrano skaitytuvui. Dar blogiau – visi trys standartai taiko apribojimus vidinei failo struktūrai, o ne tam, kaip jis atrodo ekrane. Dokumentas, kuris be klaidų atidaromas kiekvienoje jūsų turimoje peržiūros programoje, vis tiek gali neatlaikyti patikros iš pirmo karto, ir dažniausiai neatlaiko.

HotPDF – losLab sukurta VCL PDF biblioteka – atitiktį vertina kaip parametrą, kurį deklaruojate dar prieš sukuriant pirmąjį puslapį. Nustatote atitikties savybę, pridedate standartui reikalingas struktūras, o biblioteka atsisako išsaugoti konfigūracijas, kurios prieštarauja pasirinktam profiliui. Tai yra daug geresnis modelis nei sugeneruoti failą ir tikėtis, kad vėliau jį pavyks pritaikyti papildomai apdorojant, nes daugumos šių standartų reikalaujamų elementų neįmanoma pridėti vėliau.

Trys ISO standartai, trys skirtingi pažadai

PDF/A (ISO 19005) yra skirtas ilgalaikiam saugojimui. Jis garantuoja, kad failas bus atvaizduojamas visiškai taip pat ir po kelių dešimtmečių, todėl reikalaujamų elementų visiško savarankiškumo: visi šriftai turi būti įterpti, kiekviena spalva turi turėti nepriklausomą reikšmę per OutputIntent savybę, turi būti pateikti pilni XMP metaduomenys, o bet kokie elementai, kurių elgsena priklauso nuo aplinkos, yra draudžiami. Šifravimas ir JavaScript čia nenaudojami, nes niekas negali garantuoti, kad dešifravimo įrankis ar scenarijų variklis egzistuos 2050 metais.

PDF/X (ISO 15930) yra orientuotas į spalvų atkūrimą ant popieriaus. Jis sukurtas tam, kad dizaineris galėtų perduoti failo tipą spaustuvei be papildomų derinimų, o tai reiškia apibrėžtas spaudos sąlygas, privalomą /Trapped raktą, nustatytas pjovimo ir paraščių geometrijas, o X-1a atveju – jokio permatomumo elementų naudojimo, kad RIP procesas neturėtų spėlioti. PDF/UA (ISO 14289) yra skirtas dokumento prieinamumui. Pagalbinėms technologijoms reikalingas pilnas žymų medis, logiška skaitymo tvarka, deklaruota dokumento kalba ir tekstiniai atitikmenys visiems ne tekstiniams objektams.

Kadangi šie trys standartai reikalauja skirtingų dalykų, parinkite pagrindinį standartą pagal platinimo kanalą, užuot bandę sukurti vieną failą, kuris atitiktų juos visus. Tik CMYK spalvų spaudos maketas yra visiškai netinkamas ekrano skaitytuvo naudotojui, o archyvavimo profilio draudimas naudoti dinaminę elgseną prieštarauja bet kokiems interaktyviems elementams. Generuokite dokumentą kiekvienam kanalui atskirai iš tų pačių pirminių duomenų ir taip išvengsite šio konflikto.

PDF/A: OutputIntent yra ta dalis, kurią visi pamiršta

Jei PDF/A failo patikra nepavyksta, OutputIntent yra pirmasis dalykas, kurį reikia patikrinti. Tai yra struktūra, kurią kūrėjai praleidžia dažniausiai, nes nuo jos nepriklauso niekas, kas matoma ekrane. ISO 19005 reikalauja šios struktūros: įterpto ICC profilio, kuris tiksliai apibrėžia, ką iš tikrųjų reiškia dokumento spalvos. HotPDF šį profilį reikalauja nurodyti tiesiogiai, o ne kaip papildomą priedą:

var
  Pdf: THotPDF;
  ICC: TFileStream;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := 'invoice-archival.pdf';
    Pdf.PDFACompliance := 'B';            // level B: visual fidelity
    Pdf.Lang := 'en-US';
    Pdf.StandardFontEmulation := False;   // embed real fonts, no Base-14 emulation
    ICC := TFileStream.Create('sRGB.icc', fmOpenRead);
    try
      Pdf.AddPDFAOutputIntent('sRGB IEC61966-2.1', '', ICC, 3, 'DeviceRGB');
    finally
      ICC.Free;
    end;
    Pdf.BeginDoc;
    Pdf.CurrentPage.SetFont('Arial', [], 11);
    Pdf.CurrentPage.TextOut(50, 760, 0, 'Archival invoice body');
    Pdf.EndDoc;
  finally
    Pdf.Free;
  end;
end;

Keletas detalių čia lemia patikros sėkmę. Savybė StandardFontEmulation turi būti išjungta: emuliuojami Base-14 šriftai nėra įterpiami, o šriftų įterpimas yra privalomas pagal ISO 19005. Šifravimas turi likti išjungtas, todėl niekada nejunkite PDFACompliance su ActivateProtection; šifruotas archyvinis failas yra prieštaravimas, kurį tikrintuvas pastebi iškart. Komponentų skaičius funkcijoje AddPDFAOutputIntent turi atitikti profilį: 3 RGB profiliams (pvz., sRGB IEC61966-2.1) ir 4 CMYK profiliams. HotPDF rašydama failą seka DeviceRGB ir DeviceCMYK naudojimą pagal deklaruotą intenciją, todėl atsitiktinis CMYK užpildymas dokumente su RGB intencija bus užfiksuotas kaip klaida.

Vienas dalykas apie ICC profilį: vertinkite jį kaip programinės įrangos dalį su versijos kontrole, o ne tiesiog kaip failą, kurį kažkas kažkada įkėlė į serverį. Jo baitai įterpiami į kiekvieną generuojamą dokumento tipą, todėl sugadintas ar nepilnas profilis nepastebimai sugadins visą dokumentų partiją, o apie tai sužinosite tik patikros metu. Platinakite jį kartu su diegimo paketu, registruokite jo kontrolinę sumą paleidimo žurnale ir įkelkite naudodami TFileStream, kaip parodyta aukščiau – taip trūkstamas failas sukels klaidą generavimo metu, o ne tyliai praeis archyvavimo etapą.

PDF/X spaudai: Trapped, CMYK ir spaudos profilis

Spaudos maketų atveju situacija su spalvomis yra priešinga. Spaustuvei reikalingas apibrėžtas CMYK, o standartas įpareigoja nurodyti, ar buvo pritaikytas spalvų persidengimas, net jei tikrasis atsakymas yra tas, kad neturite apie tai supratimo. Raktas /Trapped yra privalomas bet kuriuo atveju:

Pdf.PDFXCompliance := 'X-1a';
Pdf.Trapped := 'Unknown';        // mandatory key under ISO 15930
ICC := TFileStream.Create('FOGRA39.icc', fmOpenRead);
try
  Pdf.AddPDFXOutputIntent('FOGRA39 (ISO 12647-2:2004)', '', ICC, 4, 'DeviceCMYK');
finally
  ICC.Free;
end;
Pdf.BeginDoc;
// draw with CMYK-safe colors, no transparency, no encryption
Pdf.EndDoc;

Spaudos CMYK profilio komponentų skaičius dabar yra 4. X-1a taip pat draudžia naudoti skaidrumo elementus, zodžiu, peržiūrėkite piešimo kodą, kuris naudoja permatomus elementus; tai, ką peržiūros programa sujungia ekrane, yra būtent tai, ko RIP atsisakys interpretuoti. Kai spaustuvė atsiunčia kitas specifikacijas, pakeiskite profilio baitus ir identifikavimo eilutę, tačiau pačios struktūros nekeiskite.

PDF/UA: struktūra generuojama iškart, o ne pritaikoma vėliau

Prieinamumas yra standartas, kurį komandos dažniausiai bando pritaikyti pačioje pabaigoje, ir šis požiūris yra baudžiamas labiau nei kitų dviejų standartų atveju. Žymų medis turi atspindėti logišką turinio kūrimo seką, o šios informacijos tiesiog nebelieka, kai failas jau yra sugeneruotas. Savybės PDFUACompliance nustatymas įjungia pažymėtą PDF išvestį, o struktūros API susieja kiekvieną piešimo iškvietimą su jo semantine paskirtimi:

Pdf.PDFUACompliance := True;     // auto-enables tagged PDF
Pdf.Lang := 'en-US';             // set explicitly; empty falls back to 'en'
Pdf.BeginDoc;

Root := Pdf.AddStructureElement(sstDocument, nil);
H1 := Pdf.EmitTaggedHeading(1, Root, 50, 700, 'Quarterly Report');
Para := Pdf.BeginTaggedContent('P', Root);
Pdf.CurrentPage.TextOut(50, 650, 0, 'Revenue grew in all regions.');
Pdf.EndTaggedContent;

Pdf.EndDoc;

Klaida, kurios reikia labiausiai saugotis – teksto piešimas už bet kokios BeginTaggedContent ir EndTaggedContent poros ribų. Ekrane toks tekstas matomas puikiai, tačiau ekrano skaitytuvui jis išlieka nematomas, todėl joks matantis testuotojas to nepastebės; ši klaida pasirodys tik tada, kai tikrasis pagalbinės technologijos naudotojas susidurs su šia spraga. Kai jūsų šablonai naudoja pasirinktinius struktūros vaidmenų pavadinimus, susiekite juos su standartiniu rinkiniu naudodami AddStructRoleMap('ManoAntraste', 'H1'), kad skaitytuvai suprastų jų reikšmę. ISO 14289 taip pat reikalauja nurodyti dokumento kalbą. HotPDF naudoja 'en', kai Lang yra tuščias, tačiau tai tėra apsauginis tinklas, o ne priežastis palikti tikrąją dokumento kalbą nenustatytą.

Patikra: pasitikėkite tikrinimo įrankiu, o ne peržiūros programa

Peržiūros programa, atidaranti jūsų failą, neįrodo atitikties standartams, todėl patikra turi būti atliekama programos platinimo etape naudojant įrankius, kurie tikrina struktūrą, o ne vaizdinį pateikimą. PDF/A ir PDF/UA atveju veraPDF yra rekomenduojamas atvirasis patikros įrankis; jis pateikia klaidas pagal ISO punktus, kurie tiesiogiai nurodo aukščiau aprašytą konfigūraciją. PDF/X atveju praktiniu tikrinimo standartu išlieka „Adobe Acrobat“ Preflight profiliai, nes spaudos atitiktis yra susijusi ne tik su sintakse, bet ir su spalvų intencija.

Biblioteka pati atlieka dalį šio darbo. Išsaugojimo metu HotPDF suderina funkcijų vėliavėles su nustatyta PDF versija, automatiškai pakeisdama tai, ko versija negali išreikšti (pavyzdžiui, AES-256 sumažinama iki AES-128 senesnėse nei PDF 1.7 versijose). Atitikties tikrinimas funkcijoje EndDoc eina dar toliau ir sukelia klaidą esant akivaizdiems prieštaravimams, pavyzdžiui, bandant naudoti PDFACompliance kartu su šifravimu. Nei vienas iš šių žingsnių nepakeičia išorinio tikrinimo įrankio. Jie tiesiog neleidžia tokioms nesuderinamoms konfigūracijoms jo pasiekti.

Vienas įprotis atsiperka nuolat: valdykite visą atitikties konfigūraciją kaip vientisą vienetą: „HotPDF“ versiją, šablono versiją, ICC profilio kontrolinę sumą ir patikrą atlikusio įrankio versiją. Atitiktis gali pakisti pasikeitus bent vienam iš šių elementų, o sudėtingiausi auditai būna tie, kai niekas negali atkurti, kokia kombinacija sukūrė penkerių metų senumo archyvo failą. Vieno konfigūracijos įrašo naudojimas kiekvienai partijai išsprendžia šią problemą visam laikui.

Galiausiai, vykdykite tikrinimą su realiais gamybiniais failais, o ne su idealiais pavyzdžiais. Klaidos dažniausiai kyla dėl duomenų, kurių niekas nenumatė: kliento logotipas CMYK formatu dokumente su RGB intencija, šablono pakeitimas, kuris naudoja neįterptą šriftą, arba nauja kodo atšaka, kuri piešia tekstą už žymų medžio ribų. Saugokite po vieną žinomą klaidingą failą iš kiekvieno praeities incidento regresiniam testavimui ir atitikties tikrinimas išliks patikimas. Dėl šių procesų vizualinio pateikimo skaitykite mūsų straipsnį apie ataskaitų išvestį, šriftus ir vaizdus su HotPDF; apie tikrinimo įrankių integravimą į kūrimo procesą skaitykite papildomame straipsnyje apie PDF preflight patikrų automatizavimą.

Šiuose pavyzdžiuose naudojamos atitikties savybės, išvesties intencijos ir žymėjimo API yra pateikiami kartu su HotPDF komponentu, skirtu „Delphi“ ir „C++Builder“; produkto puslapyje pateikiama nuoroda į pilną visų čia parodytų funkcijų aprašymą.