رفض أرشيف حكومي ذات مرة إيداعًا كاملًا يضم 1,400 فاتورة أنشأها نظام فوترة Delphi لدى أحد العملاء. كل ملف كان يفتح تمامًا في كل عارض جرّبه العميل؛ لكن veraPDF رفضها جميعًا للسبب المنفرد نفسه، وهو غياب OutputIntent. تلخص تلك الحادثة الدرس المركزي في عمل PDF المتوافق مع المعايير: الصحة البصرية لا تثبت شيئًا، لأن PDF/A وPDF/X وPDF/UA قيود على البنية الداخلية للملف، لا على شكله. يبني HotPDF، مكتبة losLab الأصلية بنمط VCL لـ PDF، هذه القيود داخل توليد المستندات بحيث تُهيّأ المطابقة قبل وجود الصفحة الأولى، لا تُرقّع بعد ذلك
ثلاثة معايير ISO وثلاثة وعود مختلفة
يعد PDF/A (ISO 19005) بأن الملف سيظل يُعرض بالطريقة نفسها بعد عقود، ولذلك يفرض الاكتفاء الذاتي الكامل: تضمين كل خط، وجعل كل لون مستقلًا عن الجهاز عبر OutputIntent، وبيانات XMP metadata كاملة، ومنع أي شيء يعتمد سلوكه على البيئة، بما في ذلك التشفير وJavaScript. يعد PDF/X (ISO 15930) بتبادل أعمى بين المصمم والمطبعة، لذلك تدور قواعده حول اللون والهندسة: ظروف طباعة موصّفة، ومفتاح /Trapped إلزامي، وهندسة trim وbleed محددة، وفي نكهة X-1a لا توجد شفافية حية. يعد PDF/UA (ISO 14289) بأن التقنية المساعدة تستطيع قراءة المستند، وهذا يجعله مطلبًا على البنية المنطقية: شجرة وسوم كاملة، وترتيب قراءة صحيح، ولغة مستند معلنة، وبدائل نصية للمحتوى غير النصي
تسحب هذه الوعود في اتجاهات مختلفة. النموذج التفاعلي مقبول في PDF/UA ويستحيل جمعه مع قيود ملف الأرشفة على السلوك الديناميكي؛ أما master طباعة CMYK فقط فهو بالضبط الخيار الخاطئ لمستخدمي قارئات الشاشة الذين لا يرون اللون أصلًا. قرر لكل قناة إخراج أي معيار يحكمها، بدلًا من ملاحقة ملف واحد يرضي كل شيء
PDF/A في HotPDF: OutputIntent هو اللعبة كلها
عاد رفض الأرشيف أعلاه إلى بنية واحدة مفقودة، وهي البنية التي تنساها معظم المولدات لأن لا شيء مرئيًا يعتمد عليها. يتطلب ISO 19005 وجود OutputIntent: ملف ICC مضمّن يعطي ألوان الجهاز معنى غير ملتبس. يجعل HotPDF ملف التعريف مدخلًا صريحًا:
var
Pdf: THotPDF;
ICC: TFileStream;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'invoice-archival.pdf';
Pdf.PDFACompliance := 'B'; // level B: visual fidelity
Pdf.Lang := 'en-US';
Pdf.StandardFontEmulation := False; // embed real fonts, no Base-14 emulation
ICC := TFileStream.Create('sRGB.icc', fmOpenRead);
try
Pdf.AddPDFAOutputIntent('sRGB IEC61966-2.1', '', ICC, 3, 'DeviceRGB');
finally
ICC.Free;
end;
Pdf.BeginDoc;
Pdf.CurrentPage.SetFont('Arial', [], 11);
Pdf.CurrentPage.TextOut(50, 760, 0, 'Archival invoice body');
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
ثلاثة تفاصيل تهيئة تقرر النجاح أو الفشل. يجب إيقاف StandardFontEmulation، لأن خطوط Base-14 المحاكاة ليست مضمّنة بحكم التعريف، والتضمين غير قابل للتفاوض في ISO 19005. ويجب أن يبقى التشفير معطلًا؛ لا تجمع PDFACompliance مع ActivateProtection، لأن ملف أرشفة مشفر تناقض سيكشفه المدقق. كما أن عدد المكونات الممرر إلى AddPDFAOutputIntent يجب أن يطابق ملف التعريف، أي 3 لملف RGB مثل sRGB IEC61966-2.1. يتتبع HotPDF استخدام DeviceRGB وDeviceCMYK أثناء التوليد مقابل القصد المعلن، لذلك يظهر تعبئة CMYK في مستند ذي قصد RGB كمشكلة تحقق بدلًا من تناقض صامت
تعامل مع ملف ICC نفسه كأثر نشر له إصدار، لا كملف نسخه شخص مرة إلى خادم البناء. تُضمّن بايتات ملف التعريف في كل مستند مولد، لذلك يفسد ملف تعريف تالف أو مبتور دفعة كاملة دفعة واحدة، ولا يظهر الفشل إلا في وقت التحقق. اشحن ملف التعريف مع المثبت، وسجل checksum الخاص به في سجل التشغيل، وحمّله عبر نمط TFileStream أعلاه حتى يفشل غياب الملف بوضوح أثناء التوليد لا بهدوء عند بوابة الأرشيف
PDF/X للطباعة: Trapped وCMYK وملف تعريف المطبعة
تقلب masters الطباعة قصة اللون: المطبعة تريد CMYK موصّفًا، والمعيار يصر على أن تذكر هل طُبق trapping أم لا. مفتاح /Trapped إلزامي حتى عندما يكون الجواب الصادق أنك لا تعرف:
Pdf.PDFXCompliance := 'X-1a';
Pdf.Trapped := 'Unknown'; // mandatory key under ISO 15930
ICC := TFileStream.Create('FOGRA39.icc', fmOpenRead);
try
Pdf.AddPDFXOutputIntent('FOGRA39 (ISO 12647-2:2004)', '', ICC, 4, 'DeviceCMYK');
finally
ICC.Free;
end;
Pdf.BeginDoc;
// draw with CMYK-safe colors, no transparency, no encryption
Pdf.EndDoc;
لاحظ أن عدد المكونات تغير إلى 4 لملف تعريف مطبعة CMYK. كما تستبعد X-1a الشفافية الحية، لذلك راجع أي شيفرة رسم تراكب عناصر نصف شفافة؛ فما يركبه العارض على الشاشة هو بالضبط ما يرفض RIP تخمينه. إذا سلمتك المطبعة characterization مختلفًا، فاستبدل ملف التعريف والمعرف مع إبقاء البنية نفسها
PDF/UA: البنية تُولّد ولا تُركّب لاحقًا
إتاحة الوصول هي المعيار الذي تحاول الفرق غالبًا إلصاقه في النهاية، وهو المعيار الذي يفشل فيه الترقيع بأقسى صورة، لأن شجرة الوسوم يجب أن تعكس الترتيب المنطقي الذي أُنشئ به المحتوى. في HotPDF، يفعّل ضبط PDFUACompliance الإخراج الموسوم، وتربط واجهة البنية كل استدعاء رسم بدوره الدلالي:
Pdf.PDFUACompliance := True; // auto-enables tagged PDF
Pdf.Lang := 'en-US'; // set explicitly; empty falls back to 'en'
Pdf.BeginDoc;
Root := Pdf.AddStructureElement(sstDocument, nil);
H1 := Pdf.EmitTaggedHeading(1, Root, 50, 700, 'Quarterly Report');
Para := Pdf.BeginTaggedContent('P', Root);
Pdf.CurrentPage.TextOut(50, 650, 0, 'Revenue grew in all regions.');
Pdf.EndTaggedContent;
Pdf.EndDoc;
نمط الخطأ الذي يجب مراقبته هو محتوى يُرسم خارج أي زوج BeginTaggedContent/EndTaggedContent: يظهر طبيعيًا ولا يراه قارئ الشاشة، وهذا أسوأ أنواع الفشل لأن أي مختبر مبصر لن يلاحظه. إذا كانت قوالبك تستخدم أسماء أدوار بنيوية مخصصة، فاربطها بالمجموعة القياسية باستخدام AddStructRoleMap('MyHead', 'H1') حتى تعرف القارئات المطابقة كيف تفسرها. يتطلب ISO 14289 أيضًا لغة معلنة؛ يستبدل HotPDF 'en' عندما تكون Lang فارغة، وهذا شبكة أمان لا عذرًا لتجاوز ضبط لغة المستند الحقيقية
التحقق: ثق بالمدقق لا بالعارض
لقصة الفاتورة مغزى بسيط: أدخل التحقق في مسار الإصدار بأدوات تفحص البنية لا العرض. بالنسبة إلى PDF/A وPDF/UA، veraPDF هو المدقق المفتوح من درجة مرجعية، ويبلغ عن الإخفاقات حسب بند ISO، مما يجعل خرجه قابلًا للتطبيق مباشرة على التهيئة الموضحة أعلاه. بالنسبة إلى PDF/X، تظل ملفات Preflight في Adobe Acrobat الفحص العملي، لأن ظروف المطبعة تتعلق بقصد اللون بقدر تعلقها بالنحو. داخل المولد، يوفق HotPDF بين أعلام الميزات وإصدار PDF المهيأ وقت الحفظ، فيخفض صامتًا ما لا يستطيع الإصدار التعبير عنه، مثل AES-256 قبل PDF 1.7، بينما ترفع بوابات المطابقة في EndDoc خطأ صريحًا عند التناقضات القاسية مثل جمع PDFACompliance مع التشفير. لا يحل أي فحص منهما محل المدقق الخارجي؛ معًا يمنعان التهيئات المستحيلة من الوصول إليه أصلًا
أصدر تكوين المطابقة كله كحزمة واحدة: إصدار HotPDF، ومراجعة القالب، وchecksum ملف ICC، وإصدار المدقق الذي أجاز المخرج. تنحرف المطابقة عندما يتغير واحد منها تحت الآخرين، وأكثر عمليات التدقيق إيلامًا التي رأيناها كانت تلك التي لم يستطع فيها أحد القول أي تركيبة أنتجت ملف أرشيف عمره خمس سنوات. سجل تهيئة واحد لكل دفعة يغلق هذا السؤال نهائيًا
شغّل المدقق على مخرج إنتاج حقيقي، لا على عينة مصنوعة يدويًا. الإخفاقات المهمة تأتي من البيانات: شعار عميل يصل كـ CMYK عندما يقول القصد RGB، أو مراجعة قالب تُدخل خطًا غير مضمّن، أو مسار شيفرة جديد يرسم نصًا غير موسوم. احتفظ بملف واحد معروف الفشل لكل حادثة سابقة كمدخل regression، وستبقى بوابة المطابقة صادقة. لجانب العرض في هذه الخطوط، راجع مقالنا عن إخراج التقارير والخطوط والصور باستخدام HotPDF، ولربط المدققين بعملية بناء راجع المقالة المرافقة عن أتمتة فحوص PDF preflight
الأسئلة الشائعة
هل يمكن أن يكون ملف PDF واحد متوافقًا مع PDF/A وPDF/X في الوقت نفسه؟
أحيانًا، لكن نادرًا ما يستحق الأمر موازنة القيود: ملف الأرشفة يريد لونًا مستقلًا عن الجهاز وmetadata كاملة، وملف الطباعة يريد CMYK موصّفًا وتصريحات trapping. ولّد لكل قناة من بيانات المصدر نفسها بدلًا من إجبار ملف واحد على خدمة القناتين
لماذا يرفض veraPDF ملفًا يفتح جيدًا في كل عارض؟
العارضات متسامحة عمدًا؛ والمدققون صارمون عمدًا. غياب OutputIntents، والخطوط غير المضمنة، وmetadata XMP المفقودة لا يؤثر أبدًا في العرض، لذلك لا يبلغ عنها إلا مدقق بنيوي
هل يجب أن تستخدم الفواتير PDF/A level A أم level B؟
يضمن Level B إعادة إنتاج بصرية، وهو ما تطلبه معظم الأرشيفات للمستندات التجارية الممسوحة أو المولدة. يضيف Level A متطلبات البنية الموسومة، مستدعيًا عمليًا عبء عمل PDF/UA، وهو الخيار الصحيح عندما تنطبق التزامات إتاحة الوصول على الأرشيف نفسه
قراءات إضافية
خصائص المطابقة، ومقاصد الإخراج، وواجهة الوسوم في هذه المقالة كلها جزء من HotPDF Component لـ Delphi وC++Builder؛ وترتبط صفحة المنتج بالمرجع الكامل لكل استدعاء مستخدم هنا