HTML5 分页媒体导入
THPDFHTMLImporter.RenderHTML5 将宽容的 HTML5 标记和打印 CSS 转换为分页 PDF 内容,同时保留紧凑的旧版 RenderHTML 路径
CSS 长度和导入器的 Margin、BaseFontSize、ListIndent、BlockSpacing 都以 point 为单位,因此无论 THotPDF.Resolution 设成多少,两个渲染器产出的页面都一致;导入前后你自己绘制的内容仍使用 1/Resolution inch
声明
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;
配置文件契约
HTML5ProfileVersion 返回 1,HTML5ProfileMilestones 报告解析器与级联、分页布局、表格与表单以及有界资源
- 宽容的 DOM 接受常见省略的结束标签、保留文本顺序、跳过非活动文档区域,并强制
MaxDOMNodes - 级联支持类型、类、ID、相等属性、后代和直接子选择器、源顺序、特异性、内联声明、
!important、@media print和@page边距 - 分页布局支持块流、标题、列表、边框、背景、盒间距、显式分页符、表格、图像和自动溢出分页
- 当启用
CreateAcroForms时,文本输入、按钮、复选框、单选按钮、文本区域和选择控件渲染为静态外观或原生 AcroForm 字段
测量段落与书写方向
段落换行使用当前字体测得的步进,包括字体切换、粗体和斜体走向、字距、词距、显式换行和东亚字符边界;对齐与装饰分别作用于得到的每一行
direction: ltr、direction: rtl 和 HTML dir 属性选择段落方向;dir="auto" 采用第一个强字符的 Unicode 方向
在 Windows 上,双向文字走向用 Uniscribe 解析并跨样式边界重排,既有的 PDF 文本引擎负责每个走向内的字形整形;该行的文档方向、查看器偏好和已保存的页面文本状态随后恢复
内联方向覆盖、bdi 和 bdo 目前沿用段落排序并产生 hdkLayoutFallback 诊断;unicode-bidi 不在此配置文件内,文字整形仍遵循文档的整形配置
段落跨页拆分
widows 和 orphans 是可继承的正整数,默认都是 2;分页使用测得的行盒,而不是估算的字符数
导入器会移动段落或调整拆分位置,使分页符前后都保留所请求的最少行数;break-inside: avoid 在段落能放进新的一页时保持段落完整
当一页放不下所请求的约束时,渲染会放宽约束继续推进并记录 hdkPaginationConstraint;每个页面片段都有自己的背景和边框
可选连字符
hyphens: none 抑制自由断行,默认的 hyphens: manual 使用 U+00AD 或 ­;只有选中的断点被使用时才输出可见连字符
hyphens: auto 还会带着单词和继承的 HTML lang 值调用 OnHyphenate;没有回调时保留手动断点并报告布局回退,因为不附带任何语言词典
断点位置从单词起点按 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 列轨道,包括最多 64 列的有界 repeat(n, tracks);单元格按源顺序放置,逐行填充
grid-column: span N 和 grid-column-end: span N 允许子项占据连续的轨道及其间的间隙;放不进当前行的条目移到下一行,跨度超过轨道数会产生布局回退
flex-wrap: wrap 在下一个条目的显式宽度和间隙放不下时另起一行;每行独立应用 flex-grow 和 justify-content,而 row-reverse 和 RTL 只在行内反转位置,不在行间移动条目
gap 接受一个或两个长度,并可用 row-gap 和 column-gap 分别覆盖;平行的行保持在同一页上,并在绘制之前检查
并行子项支持带内联样式的文本块、可递归嵌套的普通块容器(含内边距、边框和背景)、嵌套的 flex 和 grid 容器、图像,以及静态或原生表单控件
图像使用回调提供或 data URI 字节,未指定高度时保持固有纵横比,每个 DOM 节点只解码一次;预检和回退复用同一份缓存图像,不再消耗额外的资源请求
所有子盒在任何并行行绘制之前完成测量,因此不支持或超限的内容会回退到竖向页面流,不会重复绘制已画好的行;嵌套规划以 64 层为界,并消耗既有的布局操作预算
没有显式宽度的可换行子项独占一整行;并行子项内的表格和列表、flex basis 与 shrink、wrap-reverse、固有轨道尺寸、grid 行轨道与行跨度以及显式 grid 放置仍在此配置文件之外,会产生可观察的诊断
不支持的 CSS 诊断
Diagnostics 暴露包含 Kind、Subject、Value 和 MessageText 的记录;OnDiagnostic 在渲染期间接收同样的信息
未知属性、不支持的值、不支持的选择器和不支持的 at 规则会被忽略并产生诊断,包括本就未被使用的样式表规则里的声明;伪选择器会被跳过,而不是当作普通类型选择器
StrictCSS 默认关闭,开启后在出现诊断时抛出 EHPDFHTMLUnsupportedCSS;此前可能已有内容输出,需要全有或全无导入的调用方应使用单独的文档
MaxDiagnostics 默认 256,限制保留的记录数;达到存储上限后 DiagnosticCount 和回调投递仍然可观察,非正的上限会禁用记录存储
有界资源
外部样式表、图像和 @font-face 字体默认禁用,除非 OnResource 提供其字节,因此 HTML 导入绝不会隐式打开文件或网络连接
@font-face 支持一个 url(...) 来源、可选的 format('truetype') 或 format('opentype')、字族别名、normal 或 italic 样式,以及 normal、bold、400 或 700 字重;font-display 接受标准策略,因为离线导入是同步加载资源
字体必须是可嵌入的 TrueType 或 OpenType sfnt 资源,且 ASCII Windows 字族名不超过 31 个字符;WOFF、字体集合、local(...)、可变字体描述符和来源列表会产生诊断
接受的字体在 Windows 上私密注册进进程内存,并一直由文档持有到文档销毁,因此在 EndDoc 之前释放导入器不会使延迟字体嵌入失效
data: 资源和回调结果共享 MaxResources、MaxResourceBytes 和 MaxTotalResourceBytes 限制
MaxDecodedImageBytes 默认 128 MiB,按每像素四字节独立约束解码图像缓存;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;