HotPDF ส่งออกและนำเข้าคำอธิบายประกอบ (annotations) ของ 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 ใดๆ บนแพลตฟอร์มใดก็ตามสามารถเปิด, ตรวจสอบความแตกต่าง (diff) หรือสร้างขึ้นมาได้ ทั้งสองรูปแบบสามารถเก็บค่าฟิลด์ฟอร์มในโครงสร้างต้นไม้ <fields> ตามที่ข้อกำหนด ISO 19444-1 ข้อ 6.3 ควบคุม และคำอธิบายประกอบในโครงสร้างต้นไม้ <annots> โดย HotPDF จะแบ่งแยกหน้าที่เหล่านี้ โดยส่งข้อมูลฟอร์มผ่าน ExportLoadedFormToXFDF และจอง ExportLoadedAnnotationsToXFDF สำหรับฝั่ง <annots> เมื่อคุณต้องการแลกเปลี่ยนความคิดเห็นกับเว็บเซอร์วิส, เซิร์ฟเวอร์ตรวจทานที่เป็น Java หรือสคริปต์ ตัว XFDF คือรูปแบบไฟล์ที่ไม่บีบบังคับให้อีกฝ่ายต้องติดตั้งตัววิเคราะห์ PDF
จะส่งออกคำอธิบายประกอบ PDF เป็น XFDF ใน Delphi ได้อย่างไร?
HotPDF ส่งออกคำอธิบายประกอบโดยการไล่ดูข้อมูลทุกหน้าของเอกสารที่โหลดเข้ามา เขียนองค์ประกอบ XFDF หนึ่งรายการสำหรับคำอธิบายประกอบแต่ละตัวที่รองรับ และส่งคืนจำนวนคำอธิบายประกอบที่เขียนสำเร็จ เริ่มต้นด้วยการโหลด PDF จากนั้นเรียกใช้ ExportLoadedAnnotationsToXFDF พร้อมกำหนดพาธปลายทาง ผลลัพธ์จำนวนเต็มที่ส่งกลับมาคือจำนวนคำอธิบายประกอบที่ได้รับการแปลง (serialize) โดยผลลัพธ์ที่เป็นศูนย์หรือน้อยกว่าจะหมายถึงไม่มีคำอธิบายประกอบใดถูกส่งออกและไม่มีไฟล์ถูกเขียน ซึ่งเป็นการแจ้งให้ทราบว่าเอกสารไม่มีคำอธิบายประกอบชนิดย่อยที่ระบบรองรับ
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 ที่คั่นด้วยอัฒภาค (semicolon) แทนที่จะเป็นแอตทริบิวต์ เนื่องจากโปรแกรมอ่านที่คาดหวังโหนดลูกจะละทิ้งจุดพิกัดที่ซ่อนอยู่ที่อื่นโดยไม่มีการแจ้งเตือน สำหรับคำอธิบายประกอบประเภทน้ำหมึก (Ink) ซึ่งสามารถเก็บเส้นวาดแยกกันหลายเส้น จะซ้อนองค์ประกอบ <inklist> โดยมีโหนดลูก <gesture> หนึ่งโหนดต่อหนึ่งเส้นวาด ช่วยให้ลายเซ็นที่มีหลายเส้นวาดสามารถส่งผ่านข้อมูลเป็นลายเส้นที่แยกจากกันได้ แทนที่จะรวมกันเป็นภาพเดียว
คุณสมบัติ Rich Text, สี และสไตล์เส้นขอบจะยังคงอยู่ควบคู่ไปกับรูปทรงเรขาคณิต ข้อความ Rich Text ของบันทึกย่อจะถูกเขียนเป็นโหนดลูก <contents-richtext> ส่วนสีถมภายในที่ PDF จัดเก็บในอาร์เรย์ IC (เช่น สีทาภายในวงกลม, สี่เหลี่ยม, รูปหลายเหลี่ยม หรือหัวลูกศร และสีถมของกล่องปกปิดข้อมูล) จะถูกส่งผ่านในรูปแบบแอตทริบิวต์ interior-color ในระบบสี #RRGGBB นอกจากนี้ความกว้างเส้นขอบ, รูปแบบเส้นประ และสไตล์ขอบแบบปุยเมฆจะถูกจับคู่กับแอตทริบิวต์ width, dashes, style และ intensity เพื่อให้กล่องข้อความขอบปุยเมฆยังคงแสดงผลเป็นขอบปุยเมฆในโปรแกรมปลายทาง ตัว HotPDF ยังรักษาหน้าต่างป๊อปอัปที่แนบมากับคำอธิบายประกอบมาร์กอัป โดยนำเข้าพิกัดโหนดลูกของป๊อปอัปและสถานะเปิดหรือปิดลงในพจนานุกรม 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 creates and edits PDF annotation objects directly from 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 notes), ข้อความอิสระ (free text), ลายเส้น (line), สี่เหลี่ยม (square), วงกลม (circle), รูปหลายเหลี่ยม (polygon), เส้นหลายจุด (polyline), มาร์กอัปข้อความทั้งสี่ประเภท (ไฮไลต์, ขีดเส้นใต้, ขีดฆ่า และขีดเส้นหยัก), ตราประทับ (stamp), หมึกวาด (ink) และเครื่องหมายแทรกข้อความ (caret) รวมถึงไฟล์แนบ, เสียง, การปกปิดข้อมูล และลิงก์ รวมเป็น 18 ชนิดย่อย คำอธิบายประกอบที่มีชนิดย่อยอยู่นอกรายการนี้จะถูกข้ามไปในการส่งออก และเนื่องจากเป็นคำสั่งข้ามไม่ใช่การเขียนแบบว่างเปล่า จึงไม่ส่งผลให้ตัวเลขจำนวนที่ฟังก์ชันส่งกลับมาเพิ่มขึ้น
เรื่อง Rich Text เป็นข้อพึงระวังอย่างตรงไปตรงมา HotPDF จะรักษาข้อมูลของโหนด <contents-richtext> ไว้เพื่อให้ข้อความที่มีการจัดสไตล์และข้อความธรรมดายังคงอยู่ครบถ้วน แต่ XFDF จะเก็บข้อมูลมาร์กอัปสไตล์และข้อความของความคิดเห็นเท่านั้น ไม่ได้เก็บสตรีมการแสดงผลที่เรนเดอร์แล้ว ดังนั้นโปรแกรมเปิดอ่านปลายทางจะเป็นผู้วาดหน้าต่างป๊อปอัปขึ้นมาใหม่โดยใช้ฟอนต์และโครงร่างของมันเอง แทนที่จะแสดงพิกเซลแบบเดียวกับของ HotPDF ขอให้พิจารณาว่าการส่งข้อมูลนี้ถูกต้องตรงตามเนื้อหาและเจตนาของผู้ใช้ แต่อาจไม่ตรงตามการเรนเดอร์บนหน้าจอในระดับพิกเซล หากเนื้อหาที่จัดสไตล์ของคุณอยู่ในข้อมูลฟอร์ม XFA แทนที่จะเป็นสตรีมคำอธิบายประกอบ กฎเกณฑ์การทำงานจะมีความแตกต่างกัน ซึ่งหัวข้อ how HotPDF handles XFA exData, rich text and hyperlinks จะอธิบายรายละเอียดของพาธการทำงานนี้แยกต่างหาก
การจัดการข้อมูลในระดับตัวอักษรมีความเข้มงวดเป็นพิเศษเพื่อความปลอดภัยของการทำงาน HotPDF ปฏิบัติตามกฎการหลีกอักขระ (escaping rules) ของมาตรฐาน ISO 19444-1 ข้อ 5.8.2 เมื่อเขียนข้อความ โดยทำการเข้ารหัสอักขระพิเศษสำหรับ XML และควบคุมไบต์ เพื่อให้ความคิดเห็นที่มีเครื่องหมายแอมเพอร์แซนด์ (&), เครื่องหมายวงเล็บมุม หรือการขึ้นบรรทัดใหม่สามารถสร้างไฟล์ XML ที่ถูกต้องตามรูปแบบที่ตัววิเคราะห์ใดๆ ยอมรับได้ และจะทำการแปลงกลับในขั้นตอนนำเข้า นี่คือสาเหตุที่บันทึกย่อที่คัดลอกมาจากตารางสเปรดชีตพร้อมเครื่องหมายวรรคตอนต่างๆ สามารถถูกนำเข้าได้อย่างสมบูรณ์โดยไม่ทำให้ไฟล์เสียหาย
การแลกเปลี่ยนคำอธิบายประกอบเป็นเพียงส่วนหนึ่งของการทำงานของ API เอกสารฟอร์มที่โหลด และสามารถนำมาประกอบร่วมกับส่วนการทำงานอื่นๆ ได้ เช่น นำเข้าไฟล์ XFDF ของผู้ตรวจทาน, ปรับแต่งหน้าเอกสาร หรือ edit the document metadata, แบนชีตฟอร์ม หรือกำหนดสิทธิ์การเข้าถึงไฟล์ใหม่ แล้วจึงส่งออกไฟล์ XFDF ใหม่สำหรับขั้นตอนถัดไป ฟังก์ชันทั้งหมดนี้จัดส่งมาพร้อมกับ HotPDF Component สำหรับ Delphi และ C++Builder ซึ่งมีเอกสารอ้างอิงอธิบายรายละเอียดของการครอบคลุมชนิดย่อยของคำอธิบายประกอบและฟังก์ชัน XFDF สำหรับข้อมูลฟอร์มอย่างครบถ้วน