استيراد HTML5 ذو الوسائط المُقسَّمة إلى صفحات

تحوّل THPDFHTMLImporter.RenderHTML5 ترميز HTML5 المتساهل وCSS الخاص بالطباعة إلى محتوى PDF مُقسَّم إلى صفحات، مع الحفاظ على مسار RenderHTML القديم المُدمَج

أطوال CSS وقيم Margin وBaseFontSize وListIndent وBlockSpacing الخاصة بالمستورد بالنقطة، فينتج كلا المرمِّزَين الصفحة نفسها أيا كانت قيمة THotPDF.Resolution؛ أما الرسم الذي تجريه بنفسك قبل الاستيراد وبعده فيظل بوحدة 1/Resolution من البوصة

التصريح

function RenderHTML5(
  const HTML: WideString;
  const AuthorStyleSheet: WideString = ''
): Boolean;

function HPDFRenderHTML5Document(
  Doc: THotPDF;
  const HTML: WideString;
  const AuthorStyleSheet: WideString = '';
  MarginPt: Single = 72;
  const FontName: AnsiString = 'Arial';
  FontSize: Single = 12
): Boolean;

عقد ملف التعريف (Profile)

تُعيد HTML5ProfileVersion القيمة 1، وتُبلغ HTML5ProfileMilestones عن المحلِّل والتسلسل الهرمي (cascade)، والتخطيط المُقسَّم إلى صفحات، والجداول والنماذج، والموارد المحدودة

الفقرات المقيسة والاتجاه

تلتف الفقرات (paragraphs) باستخدام تقدّمات مقيسة للخط الحالي، بما فيها تغيّرات الخط، والتشغيلات الغامقة والمائلة، وتباعد الأحرف، وتباعد الكلمات، وفواصل الأسطر الصريحة، وحدود المحارف لشرق آسيا؛ وتُطبَّق المحاذاة والزخرفة على كل سطر ناتج على حدة

تختار direction: ltr وdirection: rtl وسمة HTML‏ dir اتجاهَ الفقرة؛ وتستخدم dir="auto" اتجاه Unicode لأول محرف قوي

على Windows، تُحلّ تشغيلات النصوص ثنائية الاتجاه عبر Uniscribe ويُعاد ترتيبها عبر حدود الأنماط، بينما يتولى محرك نص PDF القائم تشكيل المحارف داخل كل تشغيلة؛ وتُستعاد بعد السطر اتجاهُ المستند وتفضيلات العارض وحالة نص الصفحة المحفوظة

تستخدم تجاوزات الاتجاه المضمَّنة وbdi وbdo حاليًا ترتيب الفقرة وتنتج تشخيص hdkLayoutFallback؛ وunicode-bidi خارج هذا الملف التعريفي، ويظل تشكيل النص البرمجي يتبع إعداد تشكيل المستند

تقطيع الفقرات

تُورَّث widows وorphans كعددين صحيحين موجبين، وكلاهما افتراضه 2؛ ويستخدم ترقيم الصفحات صناديق الأسطر المقيسة بدل تقدير عدد المحارف

ينقل المستورد فقرة أو يعدّل موضع انقسامها لترك العدد الأدنى المطلوب من الأسطر قبل فاصل الصفحة وبعده؛ ويحفظ break-inside: avoid الفقرة متماسكة عندما تتسع في صفحة جديدة

عندما تعجز صفحة عن استيفاء القيد المطلوب، يواصل العرض تقدمه بخفّض القيد وتسجيل hdkPaginationConstraint؛ وتتلقى كل قطعة صفحة خلفيتها وحدودها الخاصة

فصل المقاطع الاختياري (Hyphenation)

يكبت hyphens: none الفواصل الاختيارية، والافتراضي hyphens: manual يستخدم U+00AD أو ­؛ ولا يُصدَر شرطة مرئية إلا عند استخدام الفاصل المختار

يستدعي hyphens: auto إضافةً OnHyphenate مع الكلمة وقيمة HTML‏ lang الموروثة؛ وبدون نداء رجعي يحتفظ بالفواصل اليدوية ويُبلغ عن تراجع في التخطيط، لأنه لا توجد قاموس لغة مضمَّن

تُعَدّ مواضع الفصل بوحدات كود UTF-16 من بداية الكلمة؛ وتُتجاهل المواضع غير الصالحة أو الخارجة عن المدى أو قاسمة عبر أزواج بديلة أو قاسمة عبر علامات دمج أساسية

THPDFHTMLHyphenationEvent = procedure(
  Sender: TObject;
  const WordText, Language: WideString;
  var BreakPositions: TArray<Integer>
) of object;

صناديق flex وgrid محدودة

يدعم display: flex القيم row وrow-reverse وcolumn وcolumn-reverse؛ ويستخدم أبناء الصف عروضًا صريحة أو يتقاسمون العرض المتبقي، وتزن قيم flex-grow الموجبة المساحة الإضافية

تدعم الصفوف justify-content بقيم start وend وcenter وspace-between وspace-around وspace-evenly، إضافة إلى محاذاة المحور المتقاطع بقيم start وend وcenter وstretch؛ ويدعم تدفق الأعمدة تخطيطًا عموديًا طبيعيًا ويُصدر تشخيصًا للتوزيع ثابت الارتفاع أو محاذاة المحور المتقاطع غير المدعومة

يدعم display: grid مسارات أعمدة ثابتة الطول موجبة ومسارات fr، بما فيها repeat(n, tracks) المحدودة حتى 64 عمودًا؛ وتوضع الخلايا بترتيب المصدر مع ملء صف واحد في كل مرة

تتيح grid-column: span N وgrid-column-end: span N لابنٍ أن يشغل مسارات متتالية وفجواتها البينية؛ والعنصر الذي لا يتسع في الصف الحالي ينتقل إلى الصف التالي، والامتدادات الأكبر من عدد المسارات تنتج تراجعًا في التخطيط

يبدأ flex-wrap: wrap سطرًا آخر عندما لا يتسع عرض العنصر التالي الصريح وفجوته؛ ويطبق كل سطر flex-grow وjustify-content باستقلال، بينما يعكس row-reverse وRTL الموضعَين داخل كل سطر دون نقل العناصر بين الأسطر

يقبل gap طولًا أو طولين، مع تجاوزات مستقلة عبر row-gap وcolumn-gap؛ وتبقى الصفوف المتوازية في صفحة واحدة وتُفحص قبل الرسم

يدعم الأبناء المتوازون كتل نص بتنسيق مضمَّن، وحاويات كتل عادية متداخلة استنساخيًا مع padding وحدود وخلفيات، وحاويات flex وgrid متداخلة، وصورًا، وعناصر تحكم نماذج ثابتة أو أصلية

تستخدم الصور بايتات يوفرها النداء الرجعي أو بـ data URI، وتحفظ نسبة أبعادها الجوهرية عندما لا يُحدد ارتفاع، وتُفك مرة واحدة لكل عقدة DOM؛ ويعيد الفحص المسبق والتراجع استخدام الصورة المخزَّنة نفسها دون استهلاك طلب مورد إضافي

تُقاس كل صناديق الأبناء قبل رسم أي صف متوازٍ، فيتراجع المحتوى غير المدعوم أو كبير الحجم إلى تدفق الصفحات العمودي دون تكرار الصفوف المرسومة سابقًا؛ ويقتصر التخطيط المتداخل على 64 مستوى ويستهلك ميزانية عمليات التخطيط القائمة

تشغل الأبناء الملتفّة بلا عرض صريح سطرًا كاملًا؛ وتبقى الجداول والقوائم داخل الأبناء المتوازية، وflex basis وshrink، وwrap-reverse، وقياس المسارات الجوهري، ومسارات صفوف grid وامتدادات الصفوف، والتموضع الصريح في grid خارج هذا الملف التعريفي وتنتج تشخيصات قابلة للملاحظة

تشخيصات CSS غير المدعوم

تكشف Diagnostics سجلات تحتوي Kind وSubject وValue وMessageText؛ ويتلقى OnDiagnostic المعلومات نفسها أثناء العرض

تُتجاهل الخصائص المجهولة والقيم غير المدعومة والمحدِّدات غير المدعومة وقواعد at غير المدعومة مع إصدار تشخيص، بما فيها التصريحات في قواعد أنماط غير مستخدمة أصلًا؛ وتُتخطى المحدِّدات الزائفة (pseudo) بدل معاملتها كمحدِّدات نوع عادية

يرفع StrictCSS، المعطَّل افتراضيًا، استثناء EHPDFHTMLUnsupportedCSS عند أي تشخيص؛ وقد يكون المحتوى السابق قد أُصدر بالفعل، فينبغي للمستدعين الذين يشترطون استيرادًا كليًا أو لا شيء استخدام مستند منفصل

افتراضي MaxDiagnostics هو 256 ويحدّ السجلات المحفوظة؛ ويظل DiagnosticCount وتسليم النداءات قابلين للملاحظة بعد بلوغ حد التخزين، والحد غير الموجب يعطّل تخزين السجلات

موارد محدودة

تُعطَّل صفحات الأنماط والصور وخطوط @font-face الخارجية ما لم توفّر OnResource بايتاتها، لذا لا يفتح استيراد HTML أبدًا ملفًا أو اتصال شبكة بشكل ضمني

يدعم @font-face مصدر url(...) واحدًا، وformat('truetype') أو format('opentype') اختياريًا، واسم عائلة بديلًا (alias)، ونمطًا عاديًا أو مائلًا، ووزنًا عاديًا أو غامقًا أو 400 أو 700؛ ويقبل font-display السياسات القياسية لأن الاستيراد دون اتصال يحمّل الموارد بشكل متزامن

يجب أن تكون الخطوط موارد TrueType أو OpenType sfnt قابلة للتضمين باسم عائلة Windows ASCII لا يتجاوز 31 محرفًا؛ وتنتج WOFF ومجموعات الخطوط وlocal(...) وواصفات المتغيرات وقوائم المصادر تشخيصات

تُسجَّل الخطوط المقبولة خصوصًا في ذاكرة العملية على Windows وتبقى مملوكة للمستند حتى يُدمَّر، فلا يُبطل تحريرُ المستورد قبل EndDoc التضمينَ المؤجَّل للخطوط

تشترك موارد data: ونتائج الاستدعاء في حدود MaxResources وMaxResourceBytes وMaxTotalResourceBytes

افتراضي MaxDecodedImageBytes هو 128 ميبيبايت ويحدّ بشكل مستقل ذاكرة الصور المفكوكة بأربعة بايتات لكل بكسل؛ وتُفحص أبعاد BMP وPNG قبل فك الترميز، وتُفحص كل صورة مقبولة قبل الاحتفاظ بها

تحدّ MaxDOMNodes وMaxCSSRules وMaxLayoutOperations بشكل مستقل عملَ التحليل وبناء التسلسل الهرمي والتخطيط

THPDFHTMLResourceEvent = procedure(
  Sender: TObject;
  const URI: WideString;
  ResourceKind: THPDFHTMLResourceKind;
  var Data: TBytes;
  var ContentType: string;
  var Handled: Boolean
) of object;

الإحصاءات

تُبلغ THPDFHTMLImportStatistics عن إصدار الملف الشخصي، والعُقَد المُحلَّلة، وقواعد CSS، وعمليات التخطيط، وفواصل الصفحات، والجداول، وعناصر تحكم النماذج، وطلبات الموارد، والتحميلات المقبولة والمرفوضة، وبايتات الموارد المقبولة، وأسطر النص المقيسة، والأسطر المفصولة بمقاطع، والتشخيصات، وحاويات flex، وحاويات grid

يتلقى OnLineLayout فهرسَي الصفحة وسطر الفقرة (يبدآن من الصفر)، والأصل، والعرض والارتفاع المقيسين، والنص المنطقي، والاتجاه، وعلم فصل المقاطع، بعد إصدار نص PDF الفعلي

يعيد كل استدعاء لـ RenderHTML5 ضبط سجل الإحصاءات، وتثير مخالفات الميزانية استثناء EHPDFHTMLImportBudget

مثال

Importer := THPDFHTMLImporter.Create(Doc);
try
  Importer.CreateAcroForms := True;
  Importer.MaxResources := 16;
  Importer.RenderHTML5(
    '<style>@page { margin: 36pt } ' +
    'table { width: 100% }</style>' +
    '<h1>Invoice</h1>' +
    '<table><tr><td>Total</td><td>42</td></tr></table>' +
    '<input name="approved" type="checkbox">'
  );
finally
  Importer.Free;
end;

انظر أيضًا: THPDFPage.TextOutHTML، Declarative Layout DOM، AcroForm Support