مقاله فنی

کتابخانه‌های PDF losLab برای Delphi: مقایسه HotPDF، PDFium Component و PDFlibPas

سه کتابخانه. سه کار متمایز. انتخاب اشتباه برای شما هفته‌ها کار برای دور زدن مشکل (workarounds) هزینه دارد، و انتخاب هر سه زمانی که فقط به یکی نیاز دارید، سربار نگهداری (maintenance overhead) برای شما هزینه دارد که بودجه آن را پیش‌بینی نکرده بودید. در اینجا یک گزارش مستقیم از کارهایی که هر کتابخانه PDF losLab در واقع انجام می‌دهد، جایی که در آن قرار می‌گیرد، و جایی که آن را به خواهر و برادران خود تحویل می‌دهد، آورده شده است

HotPDF: نوشتن PDF از ابتدا در Delphi

HotPDF یک کامپوننت VCL بومی برای تولید اسناد PDF است. مدل آن دستوری (imperative) و مبتنی بر صفحه (page-centric) است: شما یک نمونه THotPDF می‌سازید، ویژگی‌های سند را تنظیم می‌کنید، BeginDoc را فراخوانی می‌کنید، در CurrentPage رسم می‌کنید، در صورت نیاز صفحاتی را اضافه می‌کنید، و با EndDoc می‌بندید. ترتیب اهمیت دارد زیرا BeginDoc در لحظه اجرا، فرهنگ لغت رمزنگاری (encryption dictionary) و تنظیمات فشرده‌سازی را متعهد می‌کند؛ هر چیزی که پس از آن نقطه اختصاص داده شود به جای اعمال عطف به ماسبق (retroactively)، بی سر و صدا نادیده گرفته می‌شود

سطح رسم، مجموعه کامل عملگرهای PDF را در سطح Delphi پوشش می‌دهد: TextOut برای متن یونیکد موقعیت‌دار، SetFont با جاسازی TrueType، عناصر اولیه برداری (vector primitives) (خطوط، منحنی‌های Bezier، بیضی‌ها، مستطیل‌ها)، قرار دادن تصویر از فایل یا حافظه، و تولید بارکد. مختصات بر حسب نقطه از گوشه سمت چپ پایین با افزایش Y به سمت بالا هستند، که همه را یک بار غافلگیر می‌کند. وضعیت فونت پس از AddPage باقی نمی‌ماند، بنابراین فراخوانی به SetFont پس از هر شکست صفحه (page break) لازم است

فیلدهای AcroForm شهروندان درجه یک (first-class citizens) هستند. شما می‌توانید فیلدهای متنی، کادرهای انتخاب (checkboxes)، دکمه‌های رادیویی، کادرهای ترکیبی (combo boxes)، کادرهای لیست، و دکمه‌های فشاری را مستقیماً به یک شیء صفحه با یک فراخوانی برای هر کدام اضافه کنید. HotPDF همچنین می‌تواند یک PDF موجود را از طریق LoadFromFile بارگیری کرده و مقادیر فیلد را پر کند یا بخواند، که آن را در دو جریان کاری جداگانه مفید می‌سازد: ساخت فرم‌ها و خودکارسازی پر کردن آن‌ها

رمزنگاری نیز در سطح سند انجام می‌شود. CryptKeyLength طرح را انتخاب می‌کند (40 بیتی RC4 تا AES-256)، ActivateProtection آن را مسلح (arms) می‌کند، و ProtectOptions پرچم‌های مجوز ISO را تنظیم می‌کند. دو حالت تجدید نظر AES-256 (R5 و R6، کنترل شده توسط UseAES256R6) وجود دارند زیرا تجدید نظر 6 یک ضعف شناخته شده در تجدید نظر 5 را برطرف می‌کند اما به یک نمایشگر دارای قابلیت PDF 2.0 نیاز دارد؛ انتخاب بین آن‌ها یک تصمیم سازگاری (compatibility decision) است، نه یک تصمیم راحتی

پشتیبانی از امضای دیجیتال در HotPDF پروفایل‌های پایه (baseline profiles) PAdES را پوشش می‌دهد، بنابراین برای جریان‌های کاری که در آن‌ها امضا باید الزامات ETSI EN 319 142 را برآورده کند، مناسب است. اگر نیاز شما فقط تولید خروجی است، HotPDF کتابخانه‌ای است که در ابتدا باید به سراغ آن بروید

PDFium Component: رندر کردن، مشاهده و خواندن PDF های موجود

PDFium Component موتور PDFium گوگل را به عنوان یک کامپوننت VCL می‌پیچد (wraps)، که نقش اساساً متفاوتی از HotPDF به آن می‌دهد. جایی که HotPDF می‌نویسد، PDFium Component می‌خواند و رندر می‌کند. شیء اصلی TPdf است، یک مدیر سند که با تنظیم FileName و سپس Active := True یک فایل را باز می‌کند. خرابی‌های بارگیری به عنوان استثنا (exceptions) مطرح نمی‌شوند؛ Active به سادگی False باقی می‌ماند، بنابراین بررسی آن پس از تخصیص اختیاری نیست

رندر کردن از طریق TPdfView اجرا می‌شود، یک کامپوننت بصری که روی فرم می‌اندازید و از طریق PdfView.Pdf := Pdf به یک نمونه TPdf پیوند می‌دهید. زوم و حالت تناسب (fit mode) روی نما (view) زنده هستند، نه روی سند. یکی از ظرافت‌هایی که افراد را درگیر می‌کند: Pdf.PageNumber و PdfView.PageNumber ویژگی‌های مستقلی هستند. تنظیم یکی دیگری را به‌روزرسانی نمی‌کند، و API های استخراج مبتنی بر نما (کادرهای کلمه، واحدهای خواندن) از صفحه فعلی نما استفاده می‌کنند، نه صفحه سند

استخراج متن جایی است که PDFium Component هیچ رقیب مستقیمی در مجموعه losLab ندارد. ReadablePageContent متن ساختاریافته را با آگاهی از ترتیب خواندن برمی‌گرداند، PageWordBoxes مستطیل‌های مرزی (bounding rectangles) در سطح کلمه را می‌دهد، و DocumentReadingUnits کل سند را می‌پیماید. برای کارهای دسترسی‌پذیری (accessibility)، IsTagged به شما می‌گوید که آیا درخت ساختار وجود دارد یا خیر و ValidatePdfUa بررسی انطباق UA را اجرا می‌کند. این API ها PDFium Component را به انتخاب طبیعی برای هر جریان کاری تبدیل می‌کنند که به جای تولید یک PDF جدید، نیاز به درک آنچه در داخل یک PDF موجود است دارد

پر کردن فرم نیز در سمت PDFium، از طریق همان لایه AcroForm که موتور زیرین در معرض دید قرار می‌دهد، کار می‌کند. این زمانی مناسب است که سند منبع از قبل وجود دارد و شما در حال خودکارسازی تکمیل آن هستید تا اینکه خودتان فیلدهای فرم را بسازید

PDFlibPas: دستکاری، امضای انطباق، و دسترسی مستقیم به فایل

PDFlibPas (نسخه 3.73.0) در انتهای دیگر طیف پیچیدگی قرار دارد. این سه لایه API را در بالای همان مدل سند در معرض دید قرار می‌دهد: یک نمای (facade) مسطح مبتنی بر دستگیره (handle-based) (TPDFlib) سازگار با قرارداد فراخوانی Quick-PDF، یک لایه درخت شیء کامل (TPDFDocument)، و یک تجزیه‌کننده جریانی (streaming parser) (TSmartPDFReader / TSmartPDFWriter) که مستقیماً روی بایت‌های فایل کار می‌کند بدون اینکه نمودار شیء کامل را بارگیری کند

لایه جریانی (streaming layer) چیزی است که PDFlibPas را به انتخاب مناسب برای اسناد بزرگ تبدیل می‌کند. TSmartPDFWriter می‌تواند یک به‌روزرسانی افزایشی (incremental update) را به فایلی در دیسک ضمیمه کند بدون اینکه کل جدول مرجع متقابل (cross-reference table) را بازسازی کند، که مکانیسم اساسی برای هر دو ذخیره مجدد کارآمد و مهرهای اعتبارسنجی طولانی مدت PAdES است. برای جریان‌های کاری امضای درجه انطباق (compliance-grade signing) که در آن‌ها هش امضا شده باید محدوده بایت خاصی را بپوشاند و امضا بدون بازنویسی سند اعمال می‌شود، این لایه تنها مسیر مناسب است

دستکاری سند در سطح TPDFDocument شامل ادغام با Merge، کپی انتخابی صفحه از طریق CopyPagesFromDoc با یک رشته محدوده (range string)، و حاکمیت نسخه از طریق SetMinimumVersion و LockSaveVersion است. قفل نسخه اگر سعی کنید ویژگی را ذخیره کنید که خروجی را به بالای نسخه قفل شده سوق می‌دهد، خطای 602 را ایجاد می‌کند، که زمانی مفید است که نیاز دارید تضمین کنید خروجی برای انطباق آرشیوی در یک تجدید نظر PDF خاص باقی می‌ماند

پشتیبانی از PDF/A (ISO 19005) در میز کار انطباق (conformance workbench) PDFlibPas قرار دارد. توجه داشته باشید که رمزنگاری و PDF/A بر اساس مشخصات (specification) متقابلاً منحصر به فرد (mutually exclusive) هستند: شما نمی‌توانید هر دو را در یک فایل داشته باشید. جریان‌های کاری که به یک کپی توزیع رمزگذاری شده و یک کپی آرشیو PDF/A نیاز دارند، باید دو مصنوع (artifacts) جداگانه تولید کنند

انتخاب بین آن‌ها

درخت تصمیم‌گیری معمولی کوتاه است. اگر در حال تولید یک سند جدید از داده‌ها هستید، از HotPDF استفاده کنید. اگر در حال رندر کردن یا استخراج متن از یک سند موجود در یک برنامه Delphi VCL هستید، از PDFium Component استفاده کنید. اگر در حال دستکاری، ادغام، یا امضای انطباق PDF های موجود در مقیاس یا با معناشناسی ذخیره افزایشی (incremental-save semantics) هستید، از PDFlibPas استفاده کنید. بسیاری از سیستم‌های تولید از دو مورد از این سه استفاده می‌کنند: HotPDF برای تولید خروجی و PDFlibPas برای اعمال مهر اعتبارسنجی طولانی مدت روی آن قبل از آرشیو کردن، برای مثال، یا PDFium Component برای پیش‌نمایش آنچه HotPDF تولید کرده است قبل از ارسال آن به پایین‌دست

هر سه به عنوان منبع پاسکال بومی برای Delphi و C++Builder ارسال می‌شوند، بدون هیچ وابستگی زمان اجرا (runtime dependencies) فراتر از VCL. PDFium Component علاوه بر این DLL PDFium را بسته‌بندی می‌کند، که کار رندر و تجزیه موتور را پوشش می‌دهد. صفحه محصول هر کتابخانه دارای مرجع کامل API و تاریخچه نسخه فعلی آن است

جزئیات مربوط به کتابخانه‌های جداگانه: کامپوننت HotPDF، کامپوننت PDFium Component، و PDFlibPas