Technický článok

Import a export anotácií PDF ako XFDF v Delphi

HotPDF exportuje a importuje anotácie PDF ako XFDF prostredníctvom dovoch funkcií, ktoré pracujú s aktuálne načítaným dokumentom: ExportLoadedAnnotationsToXFDF a ImportLoadedAnnotationsFromXFDF. XFDF je XML formát na výmenu anotácií štandardizovaný ako ISO 19444-1 a táto dvojica umožňuje programu v Delphi alebo C++Builder odovzdať komentáre do Acrobatu alebo iného recenzného nástroja tretej strany a prijať späť výsledky s poznámkami, a to všetko bez prepisovania obsahu stránky, na ktorom sú anotácie umiestnené

Predstavte si dva smery, ktoré to rieši. Recenzent otvorí vašu vygenerovanú správu v Acrobate, pridá červenú šípku k nesprávne zarovnanému číslu, zakrúžkuje nesprávny súčet, napíše poznámku na okraji a potom exportuje komentáre do malého súboru XFDF. Alebo naopak: váš program sám vytvára poznámky a potrebujete ich poslať niekomu, kto nepoužíva HotPDF. V oboch prípadoch anotácie putujú ako XML, ktorému rozumejú obe strany, a PDF stránky zostávajú bajt po bajte rovnaké

Aký je rozdiel medzi FDF a XFDF?

FDF a XFDF prenášajú rovnaké dáta v dvoch rôznych syntaxiach a tento rozdiel je dôležitý v momente, keď sa rozhodujete, ktorý súbor odovzdáte inému nástroju. FDF je starší formát Forms Data Format definovaný priamo v špecifikácii PDF: používa syntax objektov PDF, takže súbor FDF vyzerá ako zjednodušené PDF a na čítanie vyžaduje parser pracujúci s PDF. XFDF je XML vyjadrenie rovnakých dát, nezávisle štandardizované ako ISO 19444-1, čo znamená, že akákoľvek XML knižnica na akejkoľvek platforme ho môže otvoriť, porovnať (diff) alebo generovať. Oba formáty môžu niesť hodnoty polí formulára v strome <fields>, ktorý upravuje článok 6.3 normy ISO 19444-1, a anotácie v strome <annots>. HotPDF tieto zodpovednosti rozdeľuje, pričom formulárové dáta smeruje cez ExportLoadedFormToXFDF a ExportLoadedAnnotationsToXFDF vyhradzuje pre stranu <annots>. Keď si vymieňate komentáre s webovou službou, recenzným serverom Java alebo skriptom, XFDF je formát, ktorý nenúti druhú stranu implementovať parser PDF

Ako exportovať anotácie PDF ako XFDF v Delphi?

HotPDF exportuje anotácie tak, že prechádza každú stránku načítaného dokumentu, vysiela jeden XML element XFDF pre každú podporovanú anotáciu a vracia počet zapísaných anotácií. Najprv načítajte PDF a potom zavolajte ExportLoadedAnnotationsToXFDF s cieľovou cestou. Výsledkom typu integer je počet serializovaných anotácií; výsledok nula alebo menej znamená, že sa nič neexportovalo a nezapísal sa žiadny súbor, čo je pre vás signál, že dokument neobsahoval žiadne anotácie podporovaného podtypu

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;

Výsledné XFDF je čisté a čitateľné XML. HotPDF zapisuje koreňový element <xfdf> v mennom priestore ISO 19444-1, kontajner <annots> a jedného potomka pre každú anotáciu s jej indexom stránky od nuly, farbou a geometriou vo forme atribútov alebo dcérskych elementov. Čiara so žltou výplňou a otvoreným hrotom šípky, ktorá sa nachádza vedľa vyplneného polygónu, sa serializuje nasledovne:

<?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>

Ako sa podtypy anotácií mapujú na elementy XFDF

Každý podtyp anotácie sa mapuje na špecifický element normy ISO 19444-1 s vlastnou konvenciou geometrie a HotPDF tieto štruktúry dodržiava namiesto toho, aby si vymýšľal vlastné. Líniové anotácie (čiary) nesú atribút start a end, ktoré obsahujú dvojice súradníc koncových bodov prevzaté priamo z poľa L anotácie, zatiaľ čo štýly koncov čiar LE sa stávajú atribútmi head (hrot) a tail (koniec). Anotácie polygónov a lomených čiar (polyline) presúvajú svoj zoznam bodov do dcérskeho elementu <vertices> ako dvojice x,y oddelené bodkočiarkou, a nie do atribútu, pretože čítačka, ktorá očakáva dcérsky element, ticho zahodí body skryté kdekoľvek inde. Anotácie typu Ink (atrament), ktoré môžu obsahovať niekoľko samostatných ťahov, vnorujú element <inklist> s jedným dcérskym elementom <gesture> na ťah, takže podpis s viacerými ťahmi prežije prenos ako samostatné gestá a nie ako jedna zlúčená škvrna

Formátovaný text, farba a štýl orámovania prežívajú popri geometrii. Telo formátovaného textu poznámky sa zapisuje ako potomok <contents-richtext>; vnútorná výplň, ktorú PDF ukladá v poli IC (farba vo vnútri kruhu, štvorca, polygónu alebo hrotu šípky a výplň redakčného boxu), prechádza ako atribút interior-color vo formáte #RRGGBB; a šírka okraja, vzor prerušenia (dashes) a efekt obláčikového okraja sa mapujú na atribúty width, dashes, style a intensity, takže popiska s obláčikovým obrysom sa na druhom konci stále zobrazuje s obláčikmi. HotPDF tiež zachováva vyskakovacie (popup) okno pripojené k poznámke, pričom importuje geometriu popupu a jeho stav (otvorený/zatvorený) do slovníka Popup anotácie, a prenáša stavy otvorenia a recenzie textovej anotácie, takže recenzovaný dokument si zachováva nielen svoje tvary, ale aj metadáta pracovného postupu (workflow), na ktoré sa recenzenti spoliehajú

Import XFDF späť do načítaného dokumentu

HotPDF importuje XFDF tak, že analyzuje (parsuje) XML, vytvorí novú anotáciu pre každý element prostredníctvom NewLoadedAnnotation, pripojí ju k stránke, ktorú element uvádza, a vráti počet pridaných anotácií. Pracovný postup je symetrický s exportom: načítate základné PDF, zavoláte ImportLoadedAnnotationsFromXFDF so súborom recenzenta a potom uložíte načítaný dokument, čím pretrvajú nové poznámky. Ak súbor chýba alebo sa XML nedá spracovať, funkcia vráti nulu a načítaný dokument zostane nedotknutý

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;

Keďže každý element XFDF uvádza svoj vlastný index stránky, anotácie pristanú na stránkach, pre ktoré boli vytvorené, aj keď importujete niekoľko súborov za sebou, čo umožňuje bezpečne zhromaždiť komentáre od viacerých recenzentov do jedného načítaného dokumentu pred jedným uložením. Nižšie uvedený príklad spája dvoch recenzentov do jednej zlúčenej kópie. Informácie o vytváraní a úprave samotných objektov anotácií v kóde (namiesto ich výmeny vo forme súborov) nájdete v sprievodcovi, ako HotPDF vytvára a upravuje objekty anotácií PDF priamo z Delphi

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;

Čo sa prenáša čisto a čo nie

HotPDF prenáša obojsmerne tie podtypy anotácií, ktoré zastrešuje norma ISO 19444-1, a zvyšok zámerne preskakuje namiesto toho, aby vytvoril niečo, čo by si čítačka mohla nesprávne vysvetliť. Podporovaná sada zahŕňa typy poznámok, ktoré dominujú skutočnej recenznej práci: textové poznámky, voľný text, čiaru, štvorec, kruh, polygón, lomenú čiaru, štyri typy označenia textu (zvýraznenie, podčiarknutie, prečiarknutie a vlnovka), pečiatku, atrament (ink) a striešku (caret), plus prílohu súboru, zvuk, redakciu a odkaz — celkovo osemnásť podtypov. Anotácia, ktorej podtyp nespadá do tohto zoznamu, sa pri exporte vynechá a keďže sa preskočí namiesto zápisu prázdneho elementu, nezvyšuje počet, ktorý funkcia vracia

Formátovaný text (rich text) je úprimným varovaním. HotPDF zachováva telo <contents-richtext>, takže formátovaný text aj čistý obsah sa prenesú, avšak XFDF prenáša text a značky štýlu komentára a nie vykreslený tok vzhľadu, takže prijímajúca aplikácia prekreslí popup okno s vlastnými písmami a rozložením namiesto toho, aby reprodukovala presné pixely z HotPDF. Považujte tento prenos za verný obsahu a zámeru, a nie vykresľovaniu na obrazovke do posledného pixelu. Ak vaše štylizované dáta žijú v formulárových dátach XFA a nie v tokoch anotácií, pravidlá sa líšia a táto samostatná cesta je opísaná v časti ako HotPDF narába s XFA exData, formátovaným textom a odkazmi

Narábanie so znakmi je prísnejšie, než sa zdá, čo je presne to, čo chcete. HotPDF pri zápise textu uplatňuje pravidlá escapovania podľa článku 5.8.2 normy ISO 19444-1, pričom kóduje riadiace bajty a znaky významné pre XML, takže komentár obsahujúci ampersand, lomenú zátvorku alebo zalomenie riadku vytvorí správne formátované XML, ktoré akceptuje akýkoľvek kompatibilný parser, a pri importe tieto pravidlá znova invertuje. To je dôvod, prečo sa poznámka vložená z tabuľkového procesora vráti neporušená, vrátane interpunkcie, namiesto poškodenia súboru

Výmena anotácií je jednou časťou toho, čo robí API pre načítané dokumenty, a dá sa kombinovať so zvyškom: importujte XFDF recenzenta, upravte stránky alebo upravte metadáta dokumentu, zlučte alebo zmeňte oprávnenia súboru a potom exportujte čerstvé XFDF pre ďalšie kolo. Všetko sa dodáva v štandardnom komponente HotPDF Component pre Delphi a C++Builder, ktorého referenčná príručka dokumentuje kompletné pokrytie podtypov anotácií a sprievodné funkcie XFDF pre formulárové dáta