SVG 表单 XObject 导入

THotPDF.ImportSVGFormXObject 解析 SVG 一次并注册一个可复用的 PDF 表单 XObject,而 THPDFPage.DrawSVGFormXObject 以任意大小放置它并可选地创建页面链接批注

声明

function ImportSVGFormXObject(const Input: TBytes): AnsiString; overload;
function ImportSVGFormXObject(
  const Input: TBytes;
  out Statistics: THPDFSVGImportStatistics
): AnsiString; overload;

procedure DrawSVGFormXObject(
  const FormName: AnsiString;
  X, Y, W, H: Single;
  AddLinks: Boolean = True
);

矢量配置文件

文本与绘制边界

文本支持纯色填充、粗体和斜体变体、字号、变换、锚定、不透明度和几何裁剪;渐变文本绘制失败关闭,每个 text 或 tspan 节点仍是独立定位的走向,而不是完整的 SVG 文本流式排版引擎

文档文本导入通过感知样式的字形检查和回退排版保留所选的粗体或斜体字型,保留测得的墨迹边界,并拒绝真正未解析的字形

UTF-8 文本和十六进制或十进制 XML 字符引用在 Delphi 与 FPC 上保留相同的 Unicode 标量,包括由 UTF-16 代理对表示的补充标量

不带文本构建器的独立 HPDFBuildSVGFormData 重载使用测得的 Helvetica、Times 和 Courier Base 14 步进,并拒绝 WinAnsi 之外的字符而不是替换成问号;带 THPDFSVGTextRunBuilder 的重载接受调用方提供的内嵌文本 Form 和度量

渐变保留有界的矢量带近似;透明资源要求 PDF 1.4,PDF/A-1 严格 profile 会拒绝它们

描边样式

stroke-dasharray、stroke-dashoffset 和 stroke-miterlimit 可通过呈现属性、嵌入 CSS、内联样式和继承生效,包括组和仅片段 use 实例

虚线数组接受逗号或空白分隔的数字和受支持的长度;百分比按规范化视口对角线折算,即 sqrt((viewWidth * viewWidth + viewHeight * viewHeight) / 2)

奇数长度数组重复形成偶数长度图案,每个子路径重新开始图案,正负偏移都会环绕完整图案;none 和全零数组产生实线描边

零长度的绘制虚线保留圆头或方头线帽标记;普通实线描边、渐变描边图案、裁剪、蒙版和隔离不透明度组共享所选的描边设置

默认 miter 上限为 4;SVG 2 中 0 到 1 之间的值会被接受,并在 miter 超过上限处改用斜切连接,而渐变和透明资源边界会在所选上限内保留尖角连接

原生渲染使用有界的虚线几何保留偏移、小数长度和超过 GDI 画笔上限的数组,采用自适应曲线打平,并在段边界之间保持连续的绘制连接

用 pathLength 校准虚线仍在此配置文件之外;非实线虚线数组与 pathLength 组合的形状会失败关闭,而不是悄悄使用未校准的长度

描边语义遵循 SVG 2 描边模型,以下述解析器和渲染器预算为界

文本整形配置

内嵌 SVG 文本使用导入文档的 ShapingFeatures、AutoShapeArabic、AutoShapeSyriac、AutoShapeNko、AutoShapeAdlam 和 AutoShapeHanifiRohingya 设置,连同其 GSUB script 与语言选择以及字体回退链

这些设置在测量步进和生成文本外观时同样生效,且不改变调用方的配置;整形仍是可选项,并要求字体提供所请求的字形和 OpenType 表

每个生成的文本外观最多接受 256 个不同的整形字体选择和 64 MiB 累计原始字体数据;不支持的字体数据或超限会让导入原子地失败

对象与组不透明度

opacity 对其节点的完整绘制结果只应用一次,不会被后代继承;fill-opacity 和 stroke-opacity 保留各自独立的继承绘制值

<g opacity="0.5"> 内两个重叠的不透明红色矩形在重叠处保持同样的半透明,而两个各自半透明的矩形在重叠处会更深

嵌套组按顺序合成:两层 0.5 的外层不透明度在不透明后代上的等效值为 0.25,后代显式的 opacity 为 1 不会覆盖其外层组

根 SVG 节点、容器、链接、片段引用、文本、图像和形状走同一条对象不透明度路径;仅片段 use 引用同时保留实例样式和被引用节点的样式

填充和描边 alpha 保持独立,包括在半透明对象内部的重叠处;渐变停靠点 alpha 在对象合成之前先与相关绘制的 alpha 结合

裁剪和蒙版效果属于其节点,不作为后代绘制设置继承;链接几何保持感知放置,隔离 Form 边界保守地保留变换后的描边和线帽

导入器在隔离组内保留矢量操作符、内嵌文本 Form、图像资源、图案和蒙版;不会把整个 SVG 压平成位图

受支持的行为遵循 SVG 对象与组不透明度模型;本页其他有界的文本、渐变和几何限制仍然适用

安全与预算

导入器接受最多 8 MiB 的纯文本或 gzip 压缩 SVG,将展开输入限制为 32 MiB,主、图案、蒙版和组操作符合计限制为 16 MiB,节点限制为 4,096,嵌套限制为 64 层,CSS 规则限制为 256,路径值限制为 100,000

内嵌图像只接受严格的 Base64 data:image/png;base64, 和 data:image/jpeg;base64, 载荷,最多 128 张图像、每维 16,384 像素、所有图像合计 16,777,216 个解码像素;尺寸在原生解码前检查

文本限制为 128 个走向、每个走向 65,536 个 UTF-16 单元;渐变描边图案、蒙版和隔离不透明度组各限制为 128 个资源;递归蒙版引用失败关闭

虚线数组在奇数组展开前最多 64 个源条目;正条目至少 0.000001 用户单位,单个长度和规范化周期不得超过 1,000,000,000,绝对偏移不得超过 1,000,000,000,miter 上限必须落在 0 到 1,000,000 之间

实际的嵌套透明效果限制为 8 层以匹配原生渲染器,与 SVG 树深限制无关;不带透明效果的普通嵌套容器不消耗这个额度

透明效果边界必须是有限值,每个坐标绝对值不得超过 1,000,000,000;超出这个有界坐标配置文件的导入在组或蒙版注册之前失败

导入失败会回滚生成的对象、内嵌文本 Form、注册表条目以及版本和设备颜色状态,调用方因此可以复用同一文档并保留外层图事务

脚本、事件处理程序、DTD、foreignObject、不支持的数据媒体类型、JavaScript URL 以及外部绘制或图像资源 URL 失败关闭

url(#gradient)、url(#clip) 和 href="#symbol" 等片段引用保留在解析的文档内,绝不触发文件或网络访问

统计信息

THPDFSVGImportStatistics 报告节点、CSS 规则、渐变、渐变描边、蒙版、图像、链接、文本走向、经 GroupCount 反映的隔离不透明度组,以及生成的主、图案、蒙版和组操作符合计字节

HPDFBuildSVGFormData 通过 THPDFSVGFormData 和 THPDFSVGLinkInfo 单独公开有界解析器,供需要在注册前获取表单内容、固有尺寸、不透明度资源、图像载荷、图案与蒙版流、文本资源名或链接元数据的调用方使用;Groups 提供隔离组的操作符流和保守的 Form 边界

示例

Document.BeginDoc;
FormName := Document.ImportSVGFormXObject(SVGBytes, Statistics);
if FormName = '' then
  raise Exception.Create('SVG import failed');

Document.CurrentPage.DrawSVGFormXObject(
  FormName,
  36,
  72,
  240,
  120,
  True
);

Document.CurrentPage.DrawSVGFormXObject(
  FormName,
  320,
  72,
  120,
  60,
  False
);

另请参阅: THotPDF.ImportSVGFormXObject, THPDFPage.DrawSVGFormXObject, HTML5 分页媒体导入