Tekninen artikkeli

PDF-huomautusten tuonti ja vienti XFDF-muodossa Delphissä

HotPDF vie ja tuo PDF-huomautuksia XFDF-muodossa kahdella toiminnolla, jotka vaikuttavat tällä hetkellä ladattuun asiakirjaan: ExportLoadedAnnotationsToXFDF ja ImportLoadedAnnotationsFromXFDF. XFDF on standardoitu XML-huomautusten vaihtomuoto ISO 19444-1, ja tämä pari antaa Delphi- tai C++Builder-ohjelman välittää kommenttinsa Acrobatille tai kolmannen osapuolen tarkistustyökalulle ja ottaa merkityt tulokset takaisin, ilman että sivun sisältöä, jonka päällä huomautukset sijaitsevat, kirjoitetaan uudelleen

Kuvittele kaksi suuntaa, jotka tämä ratkaisee. Tarkistaja avaa luomasi raportin Acrobatissa, pudottaa punaisen nuolen väärin kohdistetun kuvan päälle, ympyröi virheellisen summan ja kirjoittaa huomautuksen marginaaliin ja vie sitten kommentit pieneen XFDF-tiedostoon. Tai päinvastoin: ohjelmasi tuottaa merkinnät itse, ja sinun on lähetettävä ne jollekulle, jonka työkalu ei ole HotPDF. Kummassakin tapauksessa huomautukset kulkevat XML-muodossa, jota molemmat osapuolet ymmärtävät, ja PDF-sivut säilyvät tavu tavulta sellaisina kuin ne olivat

Mitä eroa on FDF:llä ja XFDF:llä?

FDF ja XFDF kuljettavat saman hyötykuorman kahdessa eri syntaksissa, ja ero on merkittävä heti, kun päätät, minkä tiedoston välität toiselle työkalulle. FDF on vanhempi Forms Data Format, joka on määritelty PDF-spesifikaation sisällä: se käyttää PDF-objektisyntaksia, joten FDF-tiedosto näyttää riisutulta PDF-tiedostolta ja vaatii PDF-tietoisen jäsentimen lukemiseen. XFDF on saman tiedon XML-ilmaisu, joka on standardoitu itsenäisesti standardina ISO 19444-1. Tämä tarkoittaa, että mikä tahansa XML-kirjasto millä tahansa alustalla voi avata, vertailla (diff) tai luoda sen. Molemmat muodot voivat kuljettaa lomakekenttien arvoja <fields>-puussa, jota ISO 19444-1 -lauseke 6.3 hallitsee, ja huomautuksia <annots>-puussa. HotPDF jakaa nämä vastuut reitittäen lomaketiedot ExportLoadedFormToXFDF-funktion kautta ja varaten ExportLoadedAnnotationsToXFDF-funktion <annots>-puolelle. Kun vaihdat kommentteja verkkopalvelun, Java-tarkistuspalvelimen tai skriptin kanssa, XFDF on se muoto, joka ei pakota toista osapuolta upottamaan PDF-jäsennintä

Miten PDF-huomautukset viedään XFDF-muodossa Delphissä?

HotPDF vie huomautukset käymällä läpi ladatun asiakirjan jokaisen sivun, tuottaen yhden XFDF-elementin kullekin tuetulle huomautukselle ja palauttaen kirjoitettujen huomautusten määrän. Lataa PDF ensin ja kutsu sitten ExportLoadedAnnotationsToXFDF-funktiota kohdepolun kanssa. Kokonaislukutulos on sarjoitettujen huomautusten määrä. Nolla tai sitä pienempi tulos tarkoittaa, että mitään ei viety eikä tiedostoa kirjoitettu, mikä on signaali siitä, että asiakirja ei sisältänyt tuettujen alityyppien huomautuksia

var
  Pdf: THotPDF;
  Written: Integer;
begin
  Pdf := THotPDF.Create(nil);
  try
    if Pdf.LoadFromFile('report-reviewed.pdf', '') > 0 then
    begin
      // Kirjoita yksi XFDF-elementti tuettua huomautusta kohden jokaisella sivulla
      Written := Pdf.ExportLoadedAnnotationsToXFDF('comments.xfdf');
      if Written <= 0 then
        ShowMessage('No supported annotations were found');
    end;
  finally
    Pdf.Free;
  end;
end;

Ulos tuleva XFDF on selkeää, luettavaa XML-koodia. HotPDF kirjoittaa <xfdf>-juuren ISO 19444-1 -nimiavaruudessa, <annots>-säiliön ja yhden lapsen huomautusta kohden, sen nollaperusteisen sivun indeksin, värin ja geometrian määritteinä (attributes) tai lapsielementteinä. Viiva keltaisella täytöllä ja avoimella nuolenpäällä, täytetyn monikulmion vieressä, sarjoittuu näin

<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/">
  <annots>
    <line page="0" start="72,700" end="220,700"
          color="#FF0000" interior-color="#FFFF00"
          head="OpenArrow" tail="None">
      <contents-richtext>Baseline näyttää olevan vinossa</contents-richtext>
    </line>
    <polygon page="0" color="#0000FF" interior-color="#CCE5FF">
      <vertices>72,120;180,120;180,200;72,200</vertices>
    </polygon>
  </annots>
</xfdf>

Miten huomautusten alityypit mäppäytyvät XFDF-elementeiksi

Jokainen huomautuksen alityyppi mäppäytyy tiettyyn ISO 19444-1 -elementtiin omalla geometriakonventiollaan, ja HotPDF noudattaa näitä rakenteita sen sijaan, että keksisi omiaan. Viivahuomautukset (line annotations) sisältävät start- ja end-määritteet, jotka pitävät sisällään kaksi päätepisteiden koordinaattiparia otettuna suoraan huomautuksen L-taulukosta, kun taas LE-viivanpäätetyyleistä (line-ending styles) tulee head- ja tail-määritteitä. Monikulmio (polygon)- ja murtoviiva (polyline) -huomautukset siirtävät pisteluettelonsa <vertices>-lapsielementtiin puolipistein erotettuina x,y-pareina, eivät määritteenä, koska lukija, joka odottaa lapsielementtiä, ohittaa hiljaisesti muualle piilotetut pisteet. Ink (muste) -huomautukset, jotka voivat sisältää useita erillisiä vetoja, pesittävät <inklist>-elementin, jossa on yksi <gesture>-lapsi vetoa kohden, joten monivaiheinen allekirjoitus säilyy erillisinä eleinä (gestures) yhden yhdistetyn möykyn sijaan

Rikas teksti (rich text), väri- ja reunatyylit säilyvät geometrian rinnalla. Huomautuksen rikas tekstisisältö kirjoitetaan <contents-richtext>-lapsena. Sisäinen täyttö, jonka PDF tallentaa IC-taulukkoon (kuten maali ympyrän, neliön, monikulmion tai viivan nuolenpään sisällä ja sensurointilaatikon täyttö), tulee interior-color-määritteenä #RRGGBB-muodossa. Reunan leveys, katkoviivamalli ja pilvimäinen reunavaikutus mäppäytyvät määritteisiin width, dashes, style ja intensity, joten pilvireunainen kuvateksti (callout) luetaan yhä pilvimäisenä toisessa päässä. HotPDF säilyttää myös huomautukseen liitetyn ponnahdusikkunan (popup window), tuoden ponnahdusikkunan lapsigeometrian ja sen auki- tai kiinni-tilan huomautuksen Popup-sanakirjaan, ja se kuljettaa tekstihuomautuksen aukiolo- ja tarkistustilat (review states). Siten tarkistettu asiakirja säilyttää muotojensa lisäksi myös työnkulun metatiedot, joihin tarkistajat tukeutuvat

XFDF:n tuominen takaisin ladattuun asiakirjaan

HotPDF tuo XFDF:n jäsentämällä XML-koodin, luomalla uuden huomautuksen jokaiselle elementille NewLoadedAnnotation-kutsulla, liittämällä sen sivulle, jonka elementti nimeää, ja palauttamalla lisättyjen huomautusten määrän. Työnkulku on symmetrinen viennin kanssa: lataa perus-PDF, kutsu ImportLoadedAnnotationsFromXFDF-funktiota tarkistajan tiedoston kanssa ja tallenna ladattu asiakirja uusien merkintöjen tallentamiseksi. Jos tiedosto puuttuu tai XML ei jäsenny, funktio palauttaa nollan ja ladattu asiakirja jätetään ennalleen

var
  Pdf: THotPDF;
  Added: Integer;
begin
  Pdf := THotPDF.Create(nil);
  try
    if Pdf.LoadFromFile('report.pdf', '') > 0 then
    begin
      Added := Pdf.ImportLoadedAnnotationsFromXFDF('comments.xfdf');
      if Added > 0 then
        Pdf.SaveLoadedDocument('report-annotated.pdf');
    end;
  finally
    Pdf.Free;
  end;
end;

Koska jokainen XFDF-elementti nimeää oman sivuindeksinsä, huomautukset päätyvät niille sivuille, joille ne on luotu, vaikka tuot useita tiedostoja peräkkäin. Tämä tekee turvalliseksi kerätä kommentteja useammalta kuin yhdeltä tarkistajalta samaan ladattuun asiakirjaan ennen yhtä tallennusta. Alla oleva esimerkki yhdistää kahden tarkistajan kommentit yhdeksi versioksi. Jos haluat rakentaa ja muokata huomautusobjekteja itse koodissa tiedostojen vaihtamisen sijaan, katso miten HotPDF luo ja muokkaa PDF-huomautusobjekteja suoraan Delphistä

var
  Pdf: THotPDF;
  Total, I: Integer;
  Files: array[0..1] of string;
begin
  Files[0] := 'alice-comments.xfdf';
  Files[1] := 'bob-comments.xfdf';
  Pdf := THotPDF.Create(nil);
  try
    if Pdf.LoadFromFile('master.pdf', '') > 0 then
    begin
      Total := 0;
      for I := Low(Files) to High(Files) do
        Inc(Total, Pdf.ImportLoadedAnnotationsFromXFDF(Files[I]));
      if Total > 0 then
        Pdf.SaveLoadedDocument('master-merged.pdf');
    end;
  finally
    Pdf.Free;
  end;
end;

Mikä siirtyy edestakaisin puhtaasti, ja mikä ei

HotPDF siirtää edestakaisin ne huomautusten alityypit, joille ISO 19444-1 antaa kodin, ja se ohittaa tarkoituksella loput sen sijaan, että se tuottaisi jotain, mitä lukija tulkitsisi väärin. Tuettu joukko kattaa merkintätyypit (markup types), jotka hallitsevat todellista tarkistustyötä: tekstihuomautukset (text notes), vapaa teksti (free text), viiva (line), neliö (square), ympyrä (circle), monikulmio (polygon), murtoviiva (polyline), neljä tekstimerkintätyyppiä (korostus, alleviivaus, yliviivaus ja aaltoviiva), leima (stamp), muste (ink) ja kohdistinmerkki (caret), sekä tiedostoliite, ääni, sensurointi ja linkki, eli yhteensä kahdeksantoista alityyppiä. Huomautus, jonka alityyppi jää tämän luettelon ulkopuolelle, sivuutetaan vietäessä, ja koska se ohitetaan sen sijaan, että se kirjoitettaisiin tyhjänä, se ei kasvata funktion palauttamaa määrää

Rikas teksti on rehellinen varoitus. HotPDF säilyttää <contents-richtext>-rungon, joten muotoiltu teksti ja pelkkä sisältö tekevät matkan, mutta XFDF kuljettaa kommentin tekstin ja tyylimerkinnät, ei valmista ulkoasuvirtaa. Siksi vastaanottava sovellus piirtää ponnahdusikkunan uudelleen omilla fonteillaan ja asettelullaan sen sijaan, että se toistaisi HotPDF:n tarkat pikselit. Käsittele edestakaista matkaa uskollisena sisällölle ja tarkoitukselle, älä näytön renderöinnille pikselitasolla. Jos tyylitelty sisältösi elää XFA-lomaketiedoissa eikä huomautusvirroissa, säännöt eroavat, ja artikkeli miten HotPDF käsittelee XFA exDataa, rikasta tekstiä ja hyperlinkkejä kattaa tuon erillisen polun

Merkkitason käsittely on tiukempaa kuin miltä se näyttää, mikä on juuri sitä mitä haluat. HotPDF soveltaa standardin ISO 19444-1 lausekkeen 5.8.2 mukaisia suojaussääntöjä (escaping rules) kirjoittaessaan tekstiä, koodaten XML-merkittävät merkit ja ohjaustavut, jotta ampersandin, kulmasulkeen tai rivinvaihdon sisältävä kommentti tuottaa hyvin muotoiltua XML-koodia, jonka mikä tahansa yhteensopiva jäsennin hyväksyy. Se kumoaa samat säännöt tuotaessa. Siksi taulukkolaskentaohjelmasta kopioitu huomautus välimerkkeineen kaikkineen palaa ehjänä sen sijaan, että se korruptoisi tiedoston

Huomautusten vaihto on vain yksi osa sitä, mitä ladatun asiakirjan API tekee, ja se yhdistyy muuhun: tuo tarkistajan XFDF, säädä sivuja tai muokkaa asiakirjan metatietoja, litistä tai määritä tiedoston oikeudet uudelleen ja vie sitten uusi XFDF seuraavaa kierrosta varten. Kaikki tämä toimitetaan standardin Delphille ja C++Builderille tarkoitetun HotPDF-komponentin mukana, jonka viiteopas dokumentoi täydellisen huomautusten alityyppikattavuuden ja siihen liittyvät lomaketietojen XFDF-funktiot