HotPDF експортира и импортира PDF анотации като XFDF чрез две функции, които действат върху текущо заредения документ: ExportLoadedAnnotationsToXFDF и ImportLoadedAnnotationsFromXFDF. XFDF е XML форматът за обмен на анотации, стандартизиран като ISO 19444-1, и тази двойка методи позволява на програма, написана на Delphi или C++Builder, да прехвърли своите коментари към Acrobat или друг инструмент за преглед и да получи обратно маркираните резултати, без да пренаписва съдържанието на страниците, върху които се намират анотациите
Представете си двете посоки на приложение, които този метод решава. Потребител отваря генерирания от вас отчет в Acrobat, поставя червена стрелка върху неправилно подравнена фигура, огражда грешна обща сума и въвежда бележка в полето, след което експортира коментарите в малък XFDF файл. Или обратното: вашата програма сама създава маркировките и трябва да ги изпратите на някого, чийто инструмент не е HotPDF. И в двата случая анотациите се пренасят като XML, който и двете страни разбират, а PDF страниците остават непроменени байт по байт
Каква е разликата между FDF и XFDF?
FDF и XFDF пренасят еднакви данни в два различни синтаксиса и разликата е важна в момента, в който решите кой файл да предадете на друг инструмент. FDF е по-старият формат за данни на формуляри (Forms Data Format), дефиниран в самата спецификация на PDF: той използва синтаксиса на PDF обекти, така че един FDF файл изглежда като съкратен PDF и се нуждае от четец на PDF, за да бъде разчетен. XFDF е XML изразът на същите тези данни, стандартизиран независимо като ISO 19444-1, което означава, че всяка XML библиотека на всяка платформа може да го отвори, сравни или генерира. И двата формата могат да пренасят стойности на полета от формуляри в дървовидна структура <fields>, управлявана от ISO 19444-1 клауза 6.3, и анотации в дървовидна структура <annots>; HotPDF разделя тези отговорности, като насочва данните от формуляри през ExportLoadedFormToXFDF и запазва ExportLoadedAnnotationsToXFDF за частта <annots>. Когато обменяте коментари с уеб услуга, Java сървър за преглед или скрипт, XFDF е форматът, който не принуждава другата страна да вгражда PDF парсер
Как да експортирате PDF анотации като XFDF в Delphi?
HotPDF експортира анотации, като обхожда всяка страница от заредения документ, генерира по един XFDF елемент за всяка поддържана анотация и връща броя на записаните анотации. Първо заредете PDF файла, след което извикайте ExportLoadedAnnotationsToXFDF с целевия път за запис. Резултатът е бройката на сериализираните анотации; резултат нула или по-нисък означава, че нищо не е експортирано и не е записан файл, което е сигнал, че документът не съдържа анотации от поддържаните типове
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 е обикновен, лесно четим XML файл. HotPDF запива <xfdf> корен в пространството от имена на ISO 19444-1, контейнер <annots> и по един наследник за всяка анотация, съдържащ нейния нулев базиран индекс на страницата, цвят и геометрия като атрибути или под-елементи. Линия с жълт цвят за запълване и отворена стрелка в края, намираща се до запълнен полигон, се сериализира по следния начин:
<?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>
Как подтиповете анотации се съпоставят към XFDF елементи
Всеки подтип анотация се съпоставя към определен елемент по ISO 19444-1 със собствени правила за геометрия, като HotPDF следва тези структури, вместо да създава свои. Анотациите тип линия (line) носят атрибути start и end, съдържащие двете координатни двойки на крайните точки, взети директно от масива L на анотацията, докато стиловете за край на линията LE се превръщат в атрибути head и tail. Анотациите тип полигон (polygon) и полилиния (polyline) преместват списъка си с точки в под-елемент <vertices> като разделени с точка и запетая координатни двойки x,y, а не като атрибут, тъй като четците, които очакват този под-елемент, биха пропуснали скрити точки на други места. Свободните чертежи (ink), които могат да съдържат няколко отделни щриха, съдържат вложен елемент <inklist> с по един под-елемент <gesture> за всеки щрих, така че подпис от няколко части се пренася като отделни жестове, а не като едно слято петно
Форматираният текст, цветът и стилът на границите се запазват заедно с геометрията. Форматираното текстово съдържание (rich-text) се записва като под-елемент <contents-richtext>; вътрешното запълване, което PDF съхранява в масива IC (цвета в кръг, квадрат, полигон или стрелка на линия и запълването на поле за редактиране), се пренася като атрибут interior-color във формат #RRGGBB; ширината на границата, щрихованият стил и ефектът за облачна граница се пренасят като атрибути width, dashes, style и intensity, така че очертана с облак бележка остава очертана по същия начин. HotPDF също така запазва изскачащия прозорец (popup), прикрепен към анотацията, като импортира неговата геометрия и състояние на отворен/затворен в речника Popup, и пренася състоянията на отваряне и преглед на текстовите анотации, така че документът запазва не само формите, но и метаданните от работния процес, на които разчитат проверяващите
Импортиране на XFDF обратно в зареден документ
HotPDF импортира XFDF, като анализира XML структурата, създава нова анотация за всеки елемент чрез NewLoadedAnnotation, прикачва я към страницата, посочена в елемента, и връща броя на добавените анотации. Работният процес е аналогичен на експорта: зареждате базовия PDF, извиквате ImportLoadedAnnotationsFromXFDF с файла на проверяващия и след това записвате заредения документ, за да запазите новите маркировки. Ако файлът липсва или XML структурата съдържа грешка, функцията връща нула и документът остава непроменен
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;
Тъй като всеки XFDF елемент посочва собствения си индекс на страницата, анотациите попадат точно на страниците, на които са били създадени, дори когато импортирате няколко файла последователно. Това прави безопасно събирането на коментари от повече от един проверяващ в един и същ документ преди финалното записване. Примерът по-долу обединява бележките на двама проверяващи в едно общо копие. За създаване и редактиране на самите обекти на анотации в кода, вместо обмен на файлове, вижте как HotPDF създава и редактира обекти на PDF анотации директно от 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;
Какво се пренася коректно в двете посоки и какво не
HotPDF пренася двупосочно подтиповете анотации, дефинирани в ISO 19444-1, и съзнателно пропуска останалите, вместо да генерира данни, които четецът би тълкувал грешно. Поддържаният набор обхваща типовете маркировки, които доминират в реалната работа по преглед на документи: текстови бележки (text), свободен текст (free text), линия (line), квадрат (square), кръг (circle), полигон (polygon), полилиния (polyline), четирите типа за маркиране на текст (highlight, underline, strikeout и squiggly), печат (stamp), рисунка (ink) и каре (caret), плюс прикачен файл, звук, редактиране и връзка – общо осемнадесет подтипа. Анотация, чийто подтип попада извън този списък, се пропуска при експортиране и тъй като се прескача, тя не влияе на броя, който функцията връща
Форматираният текст (rich text) е важно изключение. HotPDF запазва съдържанието на <contents-richtext>, така че стилизираният текст и обикновеното съдържание се пренасят, но XFDF описва текста и маркировката на стила, а не готов поток от визуализация, така че целевото приложение преизчертава изскачащото прозорче със свои собствени шрифтове и оформление, вместо да възпроизвежда точните пиксели на HotPDF. Разглеждайте двупосочния трансфер като точен за съдържанието и намерението, а не за изобразяването на екрана до пиксел. Ако стилизираното съдържание се намира в данни за форми XFA, а не в потоци от анотации, правилата се различават, и статията за начина, по който HotPDF работи с XFA exData, форматиран текст и хипервръзки описва този отделен път
Обработката на символи е по-строга, отколкото изглежда, което е точно това, което искате. HotPDF прилага правилата за екраниране по ISO 19444-1 клауза 5.8.2, когато запива текст, кодирайки XML-значимите символи и контролните байтове, така че коментар, съдържащ амперсанд, ъглова скоба или нов ред, произвежда валиден XML файл, който всеки стандартен парсер приема, и обръща същите тези правила при импортиране. Поради тази причина бележка, копирана от електронна таблица, заедно с всички препинателни знаци, се връща непокътната, вместо да повреди структурата на XML файла
Обменът на анотации е само част от възможностите на приложния програмен интерфейс за заредени документи и се комбинира успешно с останалите функции: импортиране на XFDF на проверяващ, коригиране на страниците или редактиране на метаданните на документа, изравняване или повторно дефиниране на правата на файла, след което експортиране на нов XFDF за следващия етап. Всичко това се предлага в стандартния HotPDF Component за Delphi и C++Builder, чиято документация описва пълното покритие на подтипове анотации и свързаните с тях XFDF функции за данни от формуляри