Komponent HotPDF pozwala na eksportowanie i importowanie adnotacji PDF w formacie XFDF za pomocą dwóch funkcji działających na aktualnie załadowanym dokumencie: ExportLoadedAnnotationsToXFDF oraz ImportLoadedAnnotationsFromXFDF. XFDF to oparty na formacie XML standard wymiany adnotacji określony normą ISO 19444-1. Ta para metod umożliwia programom napisanym w środowiskach Delphi lub C++Builder przekazywanie komentarzy do programu Acrobat lub innych zewnętrznych narzędzi recenzenckich oraz pobieranie naniesionych uwag z powrotem — a wszystko to bez konieczności modyfikowania samej zawartości strony, na której te adnotacje się znajdują
Wyobraź sobie dwa scenariusze, które rozwiązuje to podejście. W pierwszym recenzent otwiera wygenerowany raport w programie Acrobat, nakłada czerwoną strzałkę na błędnie wyrównany wykres, zakreśla zły wynik i wpisuje notatkę na marginesie, a następnie eksportuje komentarze do małego pliku XFDF. W drugim scenariuszu sytuacja jest odwrotna: to Twój program generuje oznaczenia automatycznie i musisz przesłać je użytkownikowi korzystającemu z innych narzędzi niż HotPDF. W obu przypadkach adnotacje są przesyłane w formacie XML zrozumiałym dla obu stron, a strony PDF pozostają nienaruszone na poziomie bajtowym
Jaka jest różnica między FDF a XFDF?
Formaty FDF i XFDF przenoszą te same dane w dwóch różnych składniach, a różnica ta staje się istotna w momencie wyboru pliku do przekazania do zewnętrznego narzędzia. FDF to starszy format danych formularzy (Forms Data Format) zdefiniowany bezpośrednio w specyfikacji PDF: wykorzystuje on składnię obiektową PDF, co sprawia, że plik FDF wygląda jak okrojony plik PDF i wymaga parsera obsługującego format PDF. XFDF to wersja XML tych samych danych, standaryzowana niezależnie jako norma ISO 19444-1, co pozwala na jej otwieranie, porównywanie lub generowanie za pomocą dowolnej biblioteki XML na dowolnej platformie. Oba formaty mogą przenosić wartości pól formularzy w drzewie <fields>, opisywanym przez klauzulę 6.3 normy ISO 19444-1, oraz adnotacje w strukturze <annots>. Komponent HotPDF rozdziela te zadania, kierując dane formularzy przez ExportLoadedFormToXFDF, a metodę ExportLoadedAnnotationsToXFDF rezerwując dla obszaru <annots>. Gdy wymieniasz komentarze z usługami sieciowymi, serwerami recenzji w Javie czy skryptami, format XFDF eliminuje konieczność osadzania parsera PDF po drugiej stronie
Jak wyeksportować adnotacje PDF jako XFDF w Delphi?
HotPDF eksportuje adnotacje, przechodząc przez każdą stronę załadowanego dokumentu, generując jeden element XFDF dla każdej obsługiwanej adnotacji i zwracając liczbę zapisanych elementów. Najpierw załaduj plik PDF, a następnie wywołaj metodę ExportLoadedAnnotationsToXFDF ze ścieżką docelową. Zwracana liczba całkowita reprezentuje liczbę zserializowanych adnotacji. Wynik równy lub mniejszy od zera oznacza, że nic nie zostało wyeksportowane i plik nie powstał, co sygnalizuje brak adnotacji o obsługiwanych podtypach w dokumencie
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, który powstaje na wyjściu, to zwykły, czytelny kod XML. HotPDF zapisuje główny tag <xfdf> w przestrzeni nazw ISO 19444-1, kontener <annots> oraz jeden element potomny dla każdej adnotacji z jej indeksem strony (liczonym od zera), kolorem i geometrią w postaci atrybutów lub elementów potomnych. Linia z żółtym wypełnieniem i otwartym grotem strzałki, znajdująca się obok wypełnionego wielokąta, jest serializowana w następujący sposób
<?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>
Jak podtypy adnotacji mapują się na elementy XFDF
Każdy podtyp adnotacji mapuje się na konkretny element specyfikacji ISO 19444-1 z własną konwencją geometryczną, a komponent HotPDF ściśle przestrzega tych struktur, zamiast tworzyć własne. Adnotacje liniowe (line) posiadają atrybuty start oraz end przechowujące pary współrzędnych punktów krańcowych pobierane wprost z tablicy L adnotacji, natomiast style zakończeń linii LE stają się atrybutami head i tail. Adnotacje wielokątów (polygon) i linii łamanych (polyline) zapisują listę swoich punktów w elemencie potomnym <vertices> jako pary x,y oddzielone średnikami (a no-go jako atrybut), ponieważ czytniki oczekujące elementu potomnego po cichu pominą punkty zapisane w innym miejscu. Adnotacje rysunków odręcznych (ink), które mogą przechowywać wiele osobnych pociągnięć pędzla, zawierają zagnieżdżony element <inklist> z elementami potomnymi <gesture> dla każdego pociągnięcia. Dzięki temu odręczny podpis składający się z kilku linii pozostaje zestawem osobnych gestów, a nie jednym połączonym obrazem
Formatowanie tekstu, kolory i style obramowania są zachowywane wraz z geometrią. Sformatowana treść notatki jest zapisywana w elemencie potomnym <contents-richtext>. Kolor wnętrza, który PDF przechowuje w tablicy IC (wypełnienie okręgu, kwadratu, wielokąta, grotu strzałki czy pola redagowania), jest przesyłany jako atrybut interior-color w formacie #RRGGBB. Szerokość obramowania, wzorzec linii przerywanej i efekt chmurki (cloudy border) mapują się na atrybuty width, dashes, style oraz intensity, dzięki czemu chmurka pozostaje chmurką po imporcie. HotPDF zachowuje również okno wyskakujące (popup) powiązane z adnotacją, importując geometrię okna i jego stan (otwarte/zamknięte) do słownika Popup adnotacji, a także przenosi stany otwarcia i statusy recenzji adnotacji tekstowych, dzięki czemu zrecenzowany dokument zachowuje nie tylko kształty, ale i metadane pracy recenzentów
Importowanie XFDF z powrotem do załadowanego dokumentu
HotPDF importuje format XFDF poprzez analizę kodu XML, tworząc nową adnotację dla każdego elementu za pomocą metody NewLoadedAnnotation, przypisując ją do strony wskazanej przez dany element i zwracając liczbę dodanych adnotacji. Przepływ pracy jest symetryczny do eksportu: wczytaj plik PDF, wywołaj metodę ImportLoadedAnnotationsFromXFDF wskazując plik recenzenta, a następnie zapisz dokument, aby zachować zmiany. Jeśli pliku brakuje lub kod XML zawiera błędy parsowania, funkcja zwraca zero, a załadowany dokument pozostaje nienaruszony
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;
Ponieważ każdy element XFDF wskazuje własny indeks strony, adnotacje trafiają na właściwe strony, nawet jeśli importujesz kilka plików po kolei. Umożliwia to bezpieczne zbieranie komentarzy od wielu recenzentów do jednego dokumentu przed ostatecznym zapisem. Poniższy przykład łączy komentarze od dwóch recenzentów w jeden dokument. Informacje o tworzeniu i edycji samych obiektów adnotacji w kodzie (zamiast wymiany plików) znajdują się w artykule o tym, jak HotPDF tworzy i edytuje obiekty adnotacji PDF bezpośrednio w 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;
Co daje się czysto przesłać, a co nie
HotPDF przesyła w obie strony te podtypy adnotacji, które są zdefiniowane w normie ISO 19444-1, a pozostałe celowo pomija, aby uniknąć błędnej interpretacji przez czytniki. Obsługiwany zestaw obejmuje typy oznaczania dominujące w pracy recenzenckiej: notatki tekstowe (text), tekst swobodny (free text), linie (line), kwadraty (square), okręgi (circle), wielokąty (polygon), linie łamane (polyline), cztery typy zaznaczania tekstu (wyróżnienie, podkreślenie, przekreślenie, fala), pieczątki (stamp), pociągnięcia odręczne (ink), wskaźniki (caret), a także załączniki plików, dźwięki, pola redagowania (redaction) i odnośniki (link) — łącznie osiemnaście podtypów. Adnotacje spoza tej listy są pomijane przy eksporcie i nie wpływają na wartość liczbową zwracaną przez funkcję
Sformatowany tekst (rich text) to jedyny istotny szczegół. HotPDF zachowuje strukturę <contents-richtext>, dzięki czemu sformatowany tekst i zwykła zawartość są przesyłane poprawnie, jednak format XFDF przenosi tekst i style komentarza, a nie wyrenderowany strumień wyglądu (appearance stream). Oznacza to, że aplikacja docelowa rysuje okno pop-up przy użyciu własnych czcionek i układu, zamiast odtwarzać piksel w piksel wygląd z HotPDF. Traktuj ten mechanizm jako wierny pod kątem treści i intencji autora, a nie odwzorowania wizualnego co do piksela. Jeśli Twoje sformatowane treści znajdują się w danych formularza XFA, a nie w adnotacjach, obowiązują inne reguły, które opisano w artykule o tym, jak HotPDF obsługuje XFA exData, sformatowany tekst i hiperłącza
Obsługa znaków jest bardziej rygorystyczna, niż mogłoby się wydawać, co zapewnia wysokie bezpieczeństwo. HotPDF stosuje reguły ucieczki określone w klauzuli 5.8.2 normy ISO 19444-1 podczas zapisu tekstu, kodując znaki specjalne XML oraz bajty sterujące. Dzięki temu komentarz zawierający ampersand (&), nawiasy ostre czy znaki końca linii tworzy prawidłowy kod XML akceptowany przez każdy zgodny parser, a reguły te są odwracane przy imporcie. W rezultacie notatka skopiowana z arkusza kalkulacyjnego, wraz z całą interpunkcją, powraca w nienaruszonym stanie bez uszkadzania struktury pliku
Wymiana adnotacji to tylko jeden z obszarów możliwości API formularzy i dokumentów, który świetnie komponuje się z pozostałymi funkcjami: możesz zaimportować plik XFDF recenzenta, dostosować strony lub zmodyfikować metadane dokumentu, spłaszczyć formularz lub zmienić uprawnienia, a następnie wyeksportować nowy plik XFDF do kolejnej rundy weryfikacji. Wszystkie te funkcje są dostarczane w standardowym pakiecie HotPDF Component dla Delphi i C++Builder, którego dokumentacja opisuje pełną listę obsługiwanych podtypów adnotacji oraz bliźniacze funkcje wymiany danych XFDF formularzy