Tehnički članak

Uvoz i izvoz PDF bilješki kao XFDF u Delphiju

HotPDF izvozi i uvozi PDF bilješke kao XFDF putem dviju funkcija koje djeluju na trenutačno učitani dokument, ExportLoadedAnnotationsToXFDF and ImportLoadedAnnotationsFromXFDF. XFDF je XML format za razmjenu bilješki standardiziran kao ISO 19444-1, a ovaj par omogućuje programu u Delphiju ili C++Builderu da preda svoje komentare Acrobatu ili vanjskom alatu za pregled te preuzme označene rezultate natrag, i to bez ponovnog pisanja sadržaja stranice na kojem se bilješke nalaze

Zamislite dva smjera koja ovo rješava. Pregledatelj otvara vaše generirano izvješće u Acrobatu, postavlja crvenu strelicu na loše poravnatu sliku, zaokružuje pogrešan ukupni zbroj i upisuje bilješku na margini, a potom izvozi komentare u malu XFDF datoteku. Ili obrnuto: vaš program sam stvara oznake, a vi ih trebate poslati nekome tko ne koristi HotPDF. U oba slučaja bilješke putuju kao XML koji obje strane razumiju, a PDF stranice ostaju bajt po bajt onakve kakve su i bile

Koja je razlika između FDF-a i XFDF-a?

FDF i XFDF nose iste podatke u dvije različite sintakse, a ta razlika postaje važna onog trenutka kada odlučite koju datoteku predati drugom alatu. FDF je stariji Forms Data Format definiran unutar same PDF specifikacije: koristi sintaksu PDF objekata, pa FDF datoteka izgleda kao ogoljeni PDF i za čitanje zahtijeva raščlanjivač koji prepoznaje PDF. XFDF je XML izraz tih istih podataka, standardiziran neovisno kao ISO 19444-1, što znači da ga bilo koja XML knjižnica na bilo kojoj platformi može otvoriti, usporediti (diff) ili generirati. Oba formata mogu nositi vrijednosti polja obrasca u stablu <fields>, što regulira članak 6.3 standarda ISO 19444-1, i bilješke u stablu <annots>; HotPDF dijeli te odgovornosti, usmjeravajući podatke obrasca kroz ExportLoadedFormToXFDF i rezervirajući ExportLoadedAnnotationsToXFDF za stranu <annots>. Kada razmjenjujete komentare s web servisom, Java poslužiteljem za pregled ili skriptom, XFDF je format koji ne prisiljava drugu stranu da ugrađuje PDF raščlanjivač

Kako izvesti PDF bilješke kao XFDF u Delphiju?

HotPDF izvozi bilješke tako što prolazi kroz svaku stranicu učitanog dokumenta, ispisuje po jedan XFDF element za svaku podržanu bilješku i vraća broj zapisanih bilješki. Najprije učitajte PDF, a zatim pozovite ExportLoadedAnnotationsToXFDF s ciljnom putanjom. Rezultat tipa integer predstavlja broj serijaliziranih bilješki; vrijednost nula ili manja znači da ništa nije izvezeno i da datoteka nije zapisana, što vam je znak da dokument nije sadržavao bilješke podržanog podtipa

var
  Pdf: THotPDF;
  Written: Integer;
begin
  Pdf := THotPDF.Create(nil);
  try
    if Pdf.LoadFromFile('report-reviewed.pdf', '') > 0 then
    begin
      // Write one XFDF element per supported annotation on every page
      Written := Pdf.ExportLoadedAnnotationsToXFDF('comments.xfdf');
      if Written <= 0 then
        ShowMessage('No supported annotations were found');
    end;
  finally
    Pdf.Free;
  end;
end;

XFDF koji izlazi je običan, čitljiv XML. HotPDF zapisuje korijen <xfdf> u ISO 19444-1 prostoru naziva, spremnik <annots> i po jedno dijete za svaku bilješku s njezinim indeksom stranice koji počinje od nule, bojom i geometrijom kao atributima ili podređenim elementima. Linija sa žutim punjenjem i otvorenim vrhom strelice, koja stoji pokraj popunjenog poligona, serijalizira se ovako

<?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 looks off</contents-richtext>
    </line>
    <polygon page="0" color="#0000FF" interior-color="#CCE5FF">
      <vertices>72,120;180,120;180,200;72,200</vertices>
    </polygon>
  </annots>
</xfdf>

Kako se podtipovi bilješki mapiraju na XFDF elemente

Svaki podtip bilješke mapira se na određeni ISO 19444-1 element sa svojom konvencijom geometrije, a HotPDF prati te strukture umjesto da osmišljava vlastite. Linijske bilješke nose atribute start i end koji sadrže koordinatne parove dviju krajnjih točaka, uzete izravno iz polja L bilješke, dok stilovi završetka linije LE postaju atributi head i tail. Bilješke poligona (polygon) i izlomljene linije (polyline) premještaju svoj popis točaka u podređeni element <vertices> kao točke odvojene točka-zarezom x,y, a ne kao atribut, jer će preglednik koji očekuje podređeni element tiho odbaciti točke skrivene bilo gdje drugdje. Bilješke s tintom (ink), koje mogu sadržavati nekoliko zasebnih poteza, ugnježđuju element <inklist> s jednim podređenim elementom <gesture> po potezu, tako da potpis s više poteza preživljava putovanje kao zasebne geste, a ne kao jedna spojena mrlja

Obogaćeni tekst, boja i stil obruba preživljavaju zajedno s geometrijom. Tijelo obogaćenog teksta bilješke zapisuje se kao podređeni element <contents-richtext>; unutarnja ispuna koju PDF pohranjuje u polju IC, boja unutar kruga, kvadrata, poligona ili vrha linije i ispuna okvira za redakciju dolaze kao atribut interior-color u obliku #RRGGBB; a širina obruba, uzorak crtica i efekt valovitog (oblačnog) obruba mapiraju se na atribute width, dashes, style i intensity, tako da oblačić s valovitim obrubom i dalje izgleda valovito na drugom kraju. HotPDF također čuva skočni prozor (popup) povezan s bilješkom označavanja, uvozeći geometriju podređenog skočnog prozora i njegovo otvoreno ili zatvoreno stanje u rječnik Popup bilješke, te prenosi stanja otvorenosti i pregleda tekstualne bilješke, tako da pregledani dokument zadržava ne samo svoje oblike nego i metapodatke tijeka rada na koje se pregledatelji oslanjaju

Uvoz XFDF-a natrag u učitani dokument

HotPDF uvozi XFDF tako što raščlanjuje XML, stvara novu bilješku za svaki element pomoću NewLoadedAnnotation, povezuje je sa stranicom koju element navodi i vraća broj dodanih bilješki. Radni tijek je simetričan s izvozom: učitajte osnovni PDF, pozovite ImportLoadedAnnotationsFromXFDF s pregledateljevom datotekom, a potom spremite učitani dokument kako biste trajno spremili nove oznake. Ako datoteka nedostaje ili se XML ne može raščlaniti, funkcija vraća nulu i učitani dokument ostaje netaknut

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;

Budući da svaki XFDF element navodi vlastiti indeks stranice, bilješke dolaze na stranice na kojima su i stvorene, čak i kada uvozite nekoliko datoteka zaredom, što omogućuje sigurno prikupljanje komentara od više pregledatelja u isti učitani dokument prije jednog spremanja. Primjer u nastavku spaja komentare dvaju pregledatelja u jednu zajedničku kopiju. Za izradu i uređivanje samih objekata bilješki u kodu umjesto njihove razmjene u obliku datoteka, pogledajte kako HotPDF izravno stvara i uređuje objekte PDF bilješki iz Delphija

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;

Što točno prolazi kroz dvosmjerni proces, a što ne

HotPDF provodi dvosmjerni prijenos za podtipove bilješki kojima ISO 19444-1 daje mjesto, a ostale namjerno preskače umjesto ispisivanja nečega što bi čitatelj mogao pogrešno protumačiti. Podržani skup obuhvaća vrste označavanja koje dominiraju stvarnim radom na pregledu: tekstualne bilješke, slobodni tekst, liniju, kvadrat, krug, poligon, izlomljenu liniju, četiri vrste označavanja teksta (isticanje, podcrtavanje, precrtavanje i valovito podcrtavanje), pečat, tintu i caret, uz privitak datoteke, zvuk, redakciju i poveznicu — ukupno osamnaest podtipova. Bilješka čiji podtip ne spada u taj popis se preskače pri izvozu, a budući da se preskače umjesto da bude zapisana prazna, ne uvećava broj koji funkcija vraća

Obogaćeni tekst je stvarna iznimka. HotPDF čuva tijelo <contents-richtext> kako bi oblikovani tekst i obični sadržaj prošli put, ali XFDF prenosi tekst komentara i stilsko označavanje, a ne iscrtani tok izgleda, pa aplikacija primatelj ponovno iscrtava skočni prozor s vlastitim fontovima i rasporedom umjesto repliciranja HotPDF-ovih točnih piksela. Tretirajte ovaj dvosmjerni proces kao vjeran sadržaju i namjeri, a ne iscrtavanju na zaslonu do pojedinog piksela. Ako se vaš oblikovani sadržaj nalazi u XFA podacima obrasca umjesto u tokovima bilješki, pravila se razlikuju, a članak o tome kako HotPDF rukuje XFA exData podacima, obogaćenim tekstom i poveznicama pokriva tu zasebnu putanju

Rukovanje na razini znakova strože je nego što se čini, što je upravo ono što želite. HotPDF primjenjuje pravila izbjegavanja (escaping) iz članka 5.8.2 standarda ISO 19444-1 kada zapisuje tekst, kodirajući znakove važne za XML i kontrolne bajtove, tako da komentar koji sadrži ampersand, šiljastu zagradu ili prijelom retka stvara ispravno oblikovan XML koji svaki standardni raščlanjivač prihvaća, a ista pravila poništava pri uvozu. Zbog toga se bilješka kopirana iz proračunske tablice, sa svim znakovima interpunkcije, vraća netaknuta umjesto da ošteti datoteku

Razmjena bilješki samo je jedan dio onoga što API za učitane dokumente radi i može se kombinirati s ostalima: uvezite pregledateljev XFDF, prilagodite stranice ili uredite metapodatke dokumenta, spljoštite ili promijenite dopuštenja datoteke, a zatim izvezite novi XFDF za sljedeći krug. Sve se to isporučuje u standardnoj komponenti HotPDF Component za Delphi i C++Builder, čija referentna dokumentacija opisuje potpunu pokrivenost podtipova bilješki i popratne funkcije za XFDF podatke obrazaca