مقاله فنی

وارد کردن و صادر کردن یادداشت‌های توضیحی PDF به عنوان XFDF در دلفی

ابزار HotPDF یادداشت‌های توضیحی (annotations) فایل PDF را از طریق دو تابع ExportLoadedAnnotationsToXFDF و ImportLoadedAnnotationsFromXFDF که روی سند بارگذاری‌شده فعلی عمل می‌کنند، به عنوان XFDF صادر و وارد می‌کند. XFDF قالب تبادل یادداشت‌های توضیحی مبتنی بر XML است که در استاندارد ISO 19444-1 ثبت شده است، و این جفت متد به یک برنامه دلفی یا سی‌پلاس‌پلاس‌بیلدر اجازه می‌دهد نظرات خود را به آکروبات یا یک ابزار بازبینی شخص ثالث تحویل دهد و نتایج نشانه‌گذاری‌شده را پس بگیرد، بدون اینکه نیازی به بازنویسی محتوای صفحه‌ای باشد که یادداشت‌ها روی آن قرار دارند

دو جهتی را که این ویژگی حل می‌کند تجسم کنید. یک بازبین گزارش تولیدشده شما را در آکروبات باز می‌کند، یک فلش قرمز روی یک شکل نامیزان قرار می‌دهد، دور یک مجموع اشتباه خط می‌کشد و یادداشتی را در حاشیه تایپ می‌کند، سپس نظرات را در یک فایل کوچک XFDF صادر می‌نماید. یا برعکس: برنامه شما خودش نشانه‌گذاری‌ها را تولید می‌کند و باید آن‌ها را برای کسی ارسال کنید که ابزار او HotPDF نیست. در هر دو حالت، یادداشت‌ها به عنوان یک فایل XML منتقل می‌شوند که هر دو طرف آن را می‌فهمند، و صفحات PDF بایت‌به‌بایت همان چیزی که بودند باقی می‌مانند

تفاوت بین FDF و XFDF چیست؟

قالب‌های FDF و XFDF بار داده یکسانی را در دو نحو (syntax) متفاوت حمل می‌کنند، و این تمایز دقیقاً در زمانی که تصمیم می‌گیرید کدام فایل را به ابزار دیگری تحویل دهید اهمیت پیدا می‌کند. FDF قالب قدیمی‌تر داده‌های فرم (Forms Data Format) است که در خود مشخصات PDF تعریف شده است: از نحو شیء PDF استفاده می‌کند، بنابراین یک فایل FDF شبیه یک PDF ساده‌شده به نظر می‌رسد و برای خواندن به یک تجزیه‌کننده آشنا به PDF نیاز دارد. XFDF بیان XML همان داده‌ها است که به طور مستقل به عنوان استاندارد ISO 19444-1 ثبت شده است، به این معنی که هر کتابخانه XML در هر پلتفرمی می‌تواند آن را باز کند، تفاوت‌های آن را مقایسه کند یا آن را تولید نماید. هر دو قالب می‌توانند مقادیر فیلدها را در درخت <fields> (که بند ۶.۳ استاندارد ISO 19444-1 آن را کنترل می‌کند) و یادداشت‌های توضیحی را در درخت <annots> حمل کنند؛ HotPDF این وظایف را تقسیم می‌کند، به طوری که داده‌های فرم را از طریق ExportLoadedFormToXFDF هدایت کرده و متد ExportLoadedAnnotationsToXFDF را برای بخش <annots> رزرو می‌نماید. هنگامی که نظرات را با یک وب‌سرویس، یک سرور بازبینی جاوا یا یک اسکریپت تبادل می‌کنید، XFDF فرمتی است که طرف مقابل را مجبور به تعبیه یک تجزیه‌کننده PDF نمی‌کند

چگونه یادداشت‌های توضیحی PDF را به عنوان XFDF در دلفی صادر کنیم؟

ابزار 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 به جای ابداع ساختار خود، از آن الگوها پیروی می‌کند. یادداشت‌های خطی ویژگی‌های start و end حاوی مختصات دو نقطه پایانی را که مستقیماً از آرایه L یادداشت گرفته شده‌اند حمل می‌کنند، در حالی که استایل‌های انتهای خط LE به ویژگی‌های head و tail تبدیل می‌شوند. یادداشت‌های چندضلعی و چندخطی (polyline) لیست نقاط خود را به یک عنصر فرزند <vertices> به صورت جفت‌های x,y جداشده با سمی‌کالن منتقل می‌کنند و نه یک ویژگی، زیرا خواننده‌ای که انتظار عنصر فرزند را دارد، نقاط پنهان‌شده در هر جای دیگر را نادیده می‌گیرد. یادداشت‌های جوهر (Ink annotations) که می‌توانند چندین خط مجزا را نگه دارند، یک عنصر <inklist> را با یک فرزند <gesture> برای هر خط در خود جای می‌دهند، به طوری که یک امضای چندخطی به صورت خطوط مجزا منتقل می‌شود تا یک شکل ادغام‌شده واحد

متن غنی، رنگ و استایل حاشیه در کنار هندسه حفظ می‌شوند. بدنه متن غنی یک یادداشت به عنوان یک فرزند <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 اشیاء یادداشت PDF را مستقیماً از دلفی ایجاد و ویرایش می‌کند

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 مشخص کرده است منتقل می‌کند و عمداً از بقیه موارد چشم‌پوشی می‌نماید تا چیزی صادر نکند که خواننده آن را اشتباه تفسیر کند. مجموعه پشتیبانی‌شده شامل انواع نشانه‌گذاری است که بخش عمده کارهای بازبینی واقعی را تشکیل می‌دهند: یادداشت‌های متنی، متن آزاد، خط، مربع، دایره، چندضلعی، چندخطی، چهار نوع نشانه‌گذاری متن (هایلایت، زیرخط، خط‌خورده و موج‌دار)، مهر، جوهر و علامت هشتک (caret)، به اضافه فایل پیوست، صدا، لاک‌گیری و لینک، که در مجموع ۱۸ نوع فرعی را شامل می‌شوند. یادداشتی که نوع فرعی آن خارج از آن لیست باشد در هنگام صادر کردن نادیده گرفته می‌شود، و از آنجا که نادیده گرفته می‌شود تا اینکه خالی نوشته شود، تعداد برگشتی تابع را افزایش نمی‌دهد

متن غنی یک هشدار واقعی است. HotPDF بدنه <contents-richtext> را حفظ می‌کند تا متن استایل‌دهی‌شده و محتوای ساده منتقل شوند، اما XFDF متن و استایل نشانه‌گذاری یک نظر را حمل می‌کند، نه یک جریان ظاهری رندرشده، بنابراین برنامه دریافت‌کننده، پاپ‌آپ را با فونت‌ها و چیدمان خود بازطراحی می‌کند به جای اینکه پیکسل‌های دقیق HotPDF را بازتولید کند. با فرآیند رفت و برگشت به عنوان یک انتقال وفادار به محتوا و هدف رفتار کنید، نه رندر روی صفحه تا سطح پیکسل. اگر محتوای استایل‌دهی‌شده شما در داده‌های فرم XFA قرار دارد تا جریان‌های یادداشت، قوانین متفاوت است، و بخش نحوه مدیریت XFA exData، متن غنی و هایپرلینک‌ها توسط HotPDF آن مسیر مجزا را پوشش می‌دهد

مدیریت در سطح کاراکتر سخت‌گیرانه‌تر از آن چیزی است که به نظر می‌رسد، که این دقیقاً همان چیزی است که می‌خواهید. HotPDF قوانین گریزدهی بند ۵.۸.۲ استاندارد ISO 19444-1 را در زمان نوشتن متن اعمال می‌کند و کاراکترهای مهم XML و بایتهای کنترلی را رمزگذاری می‌نماید تا نظری حاوی علامت امپرسند (&)، علامت زاویه یا شکستگی خط، یک XML با ساختار صحیح تولید کند که هر تجزیه‌کننده استانداردی آن را بپذیرد، و همین قوانین را در زمان وارد کردن معکوس می‌کند. به همین دلیل است که یادداشتی که از یک صفحه‌گسترده کپی شده است، با تمام علائم نگارشی‌اش، به صورت دست‌نخورده بازمی‌گردد به جای اینکه فایل را خراب کند

تبادل یادداشت‌های توضیحی تنها بخشی از کارهایی است که API سند بارگذاری‌شده انجام می‌دهد، و با بقیه کارها ترکیب می‌شود: وارد کردن XFDF بازبین، تنظیم صفحات یا ویرایش متادیتای سند، تخت‌سازی یا تنظیم مجدد مجوزهای فایل، و سپس صادر کردن یک XFDF جدید برای مرحله بعدی. همه این ویژگی‌ها در HotPDF Component استاندارد برای دلفی و سی‌پلاس‌پلاس‌بیلدر ارائه می‌شوند که بخش مرجع آن پوشش کامل انواع فرعی یادداشت و توابع همراه XFDF داده‌های فرم را مستند کرده است