更新日志
版本发布历史
PDFlibPas 库的版本历史。条目按时间倒序排列,每个版本遵循项目发布策略中的语义化版本规范。
语言:English (US)English (UK)Español (España)Español (Latinoamérica)DeutschFrançaisItaliano日本語Português (Brasil)NederlandsSvenskaPolskiTürkçe한국어العربيةРусский简体中文繁體中文
v3.56.42 2026-05-27
- 修复 v3.56.41 引入的基于缓冲区的 AES-256 解密路径,使调用方可以把解密结果重新赋给提供密文缓冲区的同一个
AnsiString,而不会触发访问违规。 - 普通 API 的
LoadFromFile、Encrypt、SaveToFile、重新加载、Decrypt、SaveToFile流程现在可再次在已加载的大型 PDF 上完成,同时保留减少复制的 AES-CBC 解密优化。 - 新增 AES 回归覆盖,验证保存时回滚加密 stream 所用的输入缓冲区/返回结果别名场景,包括此前暴露故障的 504 KB 大 payload。
v3.56.41 2026-05-27
- 新增
TPDFlib.DACopyFile,面向只需要页数和原样文件副本、但不想构建完整普通对象图的 Direct Access 工作流。 - 通过新增基于缓冲区的 AES-CBC 解密路径并在加载后的字符串和 stream 解密中复用它,优化 AES-256 解密,减少大型加密 stream 上的额外密文复制。
- Delphi
HugeFileBenchmarkdemo 新增direct-copy行,并加入--ops与--skip过滤器,便于聚焦运行大文件测试。
v3.56.40 2026-05-26
- Delphi 和 C++Builder 的
HelloWorld例程现在会创建更完整的入门 PDF,包含文档信息、选定标准字体输出、样式化标题区、简单矢量绘图和后续示例指引,同时保持原有的构建并运行流程。 - 所有 Delphi 和 C++Builder 例程说明都已替换为适合浏览器阅读的
Readme.html页面,包括密码、受限文件和签名结果等辅助说明;两个例程索引现在也会引导用户查看 HTML 说明。
v3.56.39 2026-05-26
- 直接文件 API 的保存路径现在以线性方式构建交叉引用查找表,使
DASaveAsFile和相关直接保存路径在对象数量极高或页树密集的 PDF 上明显更快。 - 优化后的 writer 保持相同的自由对象链语义,同时避免完整 xref 生成过程中的重复对象号扫描,在不改变公共 API 或输出契约的情况下改善大型直接保存工作流。
v3.56.38 2026-05-26
- 修复普通 API 的加密输出,使
Encrypt在写入 AES-256 安全数据前创建或保留 trailer/ID,从而让加密后的 PDF 在重新加载时仍可通过EncryptionStatus识别为加密状态。 - 普通 API 的
LoadFromFile、Encrypt、SaveToFile、重新加载、Decrypt、SaveToFile工作流现在会在显式Decrypt前保留加密状态,与直接文件 API 处理大型旧版 PDF 的行为一致。
v3.56.37 2026-05-26
- 新增
TPDFlib.ComparePreflightReports,用于逐行比较纯文本 preflight 报告;它会忽略易变的Generated:时间戳行,并在稳定报告内容一致时返回空字符串。 - Delphi
PreflightReport示例现在支持单文件模式下的--compare <file>,当生成的文本报告与 baseline 不同时,会写出 UTF-8.diff.txt报告并返回退出码 2。
v3.56.36 2026-05-26
- Delphi
PreflightReport示例现在支持使用--input-dir、--output-dir和--recursive进行目录批处理,并为每个 PDF 写出一个<basename>.preflight.<ext>报告。 - 批处理模式会写出 UTF-8
preflight-summary.csv,记录每个源 PDF、通过/失败状态、问题数量和生成的报告路径,同时保留现有退出码约定,便于自动化使用。
v3.56.35 2026-05-26
ReportFormat = 3为TPDFlib.CreatePreflightReportEx和TPDFlib.SavePreflightReportEx增加 CSV 输出,生成 UTF-8 行来表示报告元数据、每个选中的合规检查、单项问题代码与消息,以及最终摘要。- Delphi
PreflightReportdemo 现在支持--format csv和--csv,命令行 preflight 运行结果可直接供电子表格或简单 CI 解析器使用,无需后处理 JSON 或抓取文本。
v3.56.34 2026-05-26
- 新增支持格式选择的
TPDFlib.CreatePreflightReportEx与TPDFlib.SavePreflightReportExAPI,可在保留现有纯文本报告 API 的同时,将 PDF/A 与 PDF/UA-1 preflight 报告生成为纯文本、JSON 或独立 HTML。 - Delphi
PreflightReport例程现在支持--format text|json|html,并提供--json与--html快捷选项,同一套命令行流程既能输出面向人工阅读的报告,也能生成便于 CI 消费的机器可读产物。
v3.56.33 2026-05-26
- 新增
TPDFlib.CreatePreflightReport和TPDFlib.SavePreflightReport,应用程序可以基于内置 PDF/A 与 PDF/UA-1 合规检查生成可复用的纯文本报告,不再需要手动枚举字符串列表句柄。 - Delphi
PreflightReport例程现在直接调用库级报告 API,使示例聚焦于命令行流程、选择检查项、首个问题模式以及便于自动化使用的退出码。
v3.56.32 2026-05-26
- 新增 Delphi 控制台示例
PreflightReport,使用CheckFileCompliance运行 PDF/A 与 PDF/UA-1 检查,通过GetStringListCount和GetStringListItem枚举问题列表,并写出纯文本 preflight 报告。 - 该示例支持
--input、--output、--pdfa、--pdfua、--both和--first-issue选项,并提供便于自动化判断的通过、发现问题和运行错误退出码。
v3.56.31 2026-05-25
GetCustomKeys(2)现在能够一致地隐藏由库管理的 Catalog 系统条目,包括 /OutputIntents、 /Extensions、 /Requirements、 /Collection 和 /NeedsRendering。- 使用
SetPDFAMode创建的 PDF/A 输出意图不再显示为自定义 Catalog 键,从而将应用程序元数据枚举与 PDF 合规性结构分开。
v3.56.25 2026-05-23
- Writer端 GetPDFUADiagnostics 修复了匹配
MULTIPLE-H-CHILDREN:N的问题,与 reader端10044在 v3.56.24 方面保持一致。 ISO 14289-1 §7.4.4 禁止每个标签树节点拥有超过一个直接的H子节点——writer端检查会在内存中的 FStructElems 树包含此类违规时触发。 - 一个新的嵌套 CountMultipleHChildren 辅助函数以深度优先方式遍历树,计算每个级别的H子节点数量。此检查与现有的 LIST-STRUCT / LIST-NO-NUMBERING 遍历并行运行,并共享相同的 FStructElems 遍历模式。
v3.56.24 2026-05-23
- PDF/UA-1 审计增加了 ISO 14289-1 §7.4.4 H标签唯一性检查。
10044报告任何结构节点,如果该节点携带超过一个直接的H子节点,则违反规范(在强结构文档中,此操作是被禁止的),并且相同的约束适用于任何标签树节点,无论整体结构模式如何。 另一个 § 7.4.4 SHALL(文档应要么是强结构,要么是弱结构,而不能两者兼有)需要文档范围的启发式方法,并且有意地未包含在此次审计中。 - 一个新的前序结构树遍历器(UAVisitStructNodeForHUniqueness / ScanStructTreeForHUniqueness)计算每个节点的直接H子节点数量,并以深度优先方式递归。它重用与现有的标题/列表/注释遍历器相同的K形解码器。
v3.56.23 2026-05-23
- PDF/UA-1 审计增加了两个 ISO 14289-1 §7.21.6 字体程序检查,这些检查原本需要 v3.56.10 在一个 TrueType 解析器可用时才能完成。
10034报告非符号 TrueType 程序,这些程序的嵌入式 SFNT cmap 表仅包含符号条目 (platformID=3, encodingID=0)。 — § 7.21.6 段落要求至少有一个非符号 cmap 子表,以便程序可以渲染其 /Encoding. 定义的代码点。10035报告非符号 TrueType 数组,这些数组的字形名称不是 Adobe Glyph List 的成员 (.notdef除外)。 — § 7.21.6 段落要求每个 Differences 条目都位于 AGL 中。 - 新的
Lib/PDFlibPDFUAFontInspect.pas实现了对 SFNT 表目录的容错扫描器和 cmap 子表目录解析器。 在上一个基础设施提交中添加的包含 4281 个名称的 Adobe Glyph List 表现在已通过 Differences 检查连接到系统中。 无法解析为 SFNT (Type 1 PFB / PFA, OpenType 集合,任意垃圾) 的程序将被静默跳过。 在审计层,优先考虑避免误报,而不是漏报。
v3.56.22 2026-05-23
- PDF/UA-1 审计增加了对 ISO 14289-1 §7.18.6 媒体剪辑数据检查。
10042报告缺少必需的/CTcontent-type 条目的媒体剪辑数据字典(由/S /MCD,可选/Type /MediaClip标识)。10043报告相同的字典缺少必需的/Alt数组。 ISO 32000-1 表 274 将这两个键都列为可选,但 ISO 14289-1 §7.18.6 将它们提升为必需,以便屏幕阅读器可以为嵌入式多媒体提供有意义的描述。 - 这是 PDF /UA 深度审计计划的第 6 阶段 (
.superpowers/plans/2026-05-23-pdfua-deep-audit-plan.md)。 它不需要任何字体程序或内容流解析器,因此是 v3.56.0..v3.56.13 系列的第一个后续子类。
v3.56.21 2026-05-23
- 新的
SetSignProcessCommitmentType会发出 CAdEScommitment-type-indication签名属性 (OID 1.2.840.113549.1.9.16.2.16, ETSI EN 319 122-1 v1.2.1 §5.2.3) 到 PAdES-B-B 路径。它接受 1..6 的整数代码,这些代码映射到已知的 ETSI 承诺 OIDsid-cti-ets-proofOfOrigin到id-cti-ets-proofOfCreation;传入 0 以清除。超出范围的代码将被拒绝。 - 新的
SetSignProcessSignaturePolicy会发出 CAdESsignature-policy-identifier签名属性 (OID 1.2.840.113549.1.9.16.2.15, §5.2.9)。它接受点分十进制策略 OID,策略文档的哈希值(以大写十六进制字符串表示),以及摘要算法代码(1=SHA-1,2=SHA-256,3=SHA-384,4=SHA-512,0=自动/SHA-256)。该属性携带SignaturePolicyIdSEQUENCE,其值为sigPolicyId+sigPolicyHash(OtherHashAlgAndValueSEQUENCE)。 - 这两个属性仅在 SubFilter 为
ETSI.CAdES.detached时才生效(即 PAdES-B-B 路径);它们扩展现有的rgAuthAttr数组,并与content-type和signing-certificate-v2协同工作。 PAdES 表 1 的 d) 行禁止将commitment-type-indication与 PDF 签名字典/Reason条目结合使用;调用者负责确保不要同时设置这两个属性。
v3.56.20 2026-05-23
- 新的
AddPAdESDSSVRI为正在构建的 DSS 添加一个签名 VRI 子字典条目,完成了 ETSI EN 319 142-1 v1.2.1 条款 5.4.2.3 验证相关信息结构。该条目以大写十六进制 SHA-1 作为签名 ' 的/Contents字节的键;其Cert/CRL/OCSP子数组通过引用相应的父 DSS 流来填充,这些流的索引以逗号分隔的列表形式提供(例如"0,2,5")。 - 底层
TSmartPDFDocument.AddPAdESDSSWithVRI跟踪为每个证书 / CRL / OCSP 发出的流对象编号,并使用这些编号将 VRI 子数组作为间接引用写入到与父 DSS 数组已经指向的同一流中,以满足规范要求,即 VRI 条目应与父 DSS 字典共享存储。原始AddPAdESDSS入口点继续以不变的方式工作,适用于不需要 VRI 的调用者。 - 每个签名 VRI 子字典都带有可选的
/Type /VRI标记,以便可以根据Type标签遍历目录的工具能够识别该结构,而无需重新解析父路径。
v3.56.19 2026-05-23
- 新的 PAdES-B-T 工作流程,用于将 RFC 3161 / RFC 5816 签名时间戳 (id-aa-signatureTimeStampToken, OID 1.2.840.113549.1.9.16.2.14) 附加到现有的 PAdES-B-B 签名。
NewPAdESSignatureTimeStampProcessFromFile/FromStream/FromString打开一个已签名 PDF,SetPAdESSignatureTimeStampField指定字段名称,GetPAdESSignatureValueHashHex返回签名者的 SHA-256 (或 384 / 512) 哈希值,用于提交到 TSA,GetPAdESSignatureCMSBytes暴露现有的 CMS 负载,SetPAdESSignatureCMSBytes接受调用者通过其首选 CMS 库构建的增强 CMS 字节,以及EndPAdESSignatureTimeStampProcessToFile/ToStream/ToString将新的 CMS 插入到原始/Contents占位符中。 BuildPAdESSignatureTimeStampAttribute是一个无状态的辅助函数,它将 TSA 发出的 TimeStampToken 封装在 CMS 属性 SEQUENCE 中,SignerInfo.unsignedAttrs期望该属性,因此已经拥有 CMS 库的调用者可以跳过 OID + SET 的配置。- 新的
SetSignProcessReserveContentsBytes在初始签名时扩展/Contents占位符,以便在签名后增强的 CMS 可以放入,而不会超出原始预留的空间。 通常,TSA 发出的 TimeStampTokens 会在 SignerInfo 上增加 2-6 字节;此处传递 1024-8192 以保留空间。 如果没有足够的预留空间,增强调用将返回13(输出溢出)。 - 该库不包含 TSA HTTP 客户端;调用者会获取 TimeStampToken (通常是 TSP 请求的 30-50 行 + HTTP POST,例如,针对 FreeTSA 或 DigiCert)。 理论上,Windows ⟦P0010⟧
CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR可以将 CMS 注入到库中,但由于返回CRYPT_E_INVALID_INDEX(0x80091008) 表示分离的 SignedData 形状 PAdES,因此使用调用者提供的 CMS 字节路径。
v3.56.18 2026-05-23
- PAdES 属性现在嵌入了 RFC 5035 (ESSCertIDv2) 定义的可选
IssuerSerial字段。 签名证书的颁发者 Distinguished Name 被封装在一个GeneralName [4] EXPLICIT directoryNameCHOICE 中,位于GeneralNames中,然后是证书序列号,作为 ASN.1 INTEGER。 序列号字节来自 Windows CryptoAPI (CRYPT_INTEGER_BLOB),并且被反转为大端,并在最高位设置为正整数时添加填充字节,这与 OpenSSL 和 BouncyCastle 如何发出相同的字段相同。 - 验证器会交叉检查颁发者名称 + 序列对与它们的路径构建候选集 (特别是 EU DSS 的严格模式),现在会在签名证书 v2 属性中找到这两个标识符;以前的 v3.56.17 输出仅提供
certHash引用。 - 新的 ASN.1 辅助函数
DER_IntegerFromLittleEndian(处理 Win32CRYPT_INTEGER_BLOB字节顺序) 和DER_ContextTagExplicit(将负载封装在构造的上下文特定标记中) 完善了PDFlibASN1微编码器。PDFlibCryptoAPI中的新的CERT_INFO/CRYPT_ALGORITHM_IDENTIFIER/CRYPT_INTEGER_BLOB/PCERT_CONTEXT声明为签名路径提供了访问解析的证书字段。
v3.56.17 2026-05-23
- 内建的
ETSI.CAdES.detached签名路径现在生成结构上符合 PAdES-B-B 的签名。库自己构建 CMS authenticated attributes ——content-type(id-data)和 RFC 5035 / RFC 5816 定义的signing-certificate-v2(携带签名证书的 SHA-256 哈希),再通过rgAuthAttr交给CryptSignMessage。一旦该字段为 non-NULL,Windows CryptoAPI 就会停止自动注入 PAdES(ETSI EN 319 142-1 v1.2.1 Table 1)所禁止的signing-time属性,因此最终的SignerInfo只携带必需的属性。 - 新增
PDFlibASN1单元,提供一个聚焦的 DER (X.690) 微编码器 —— length prefix、OCTET STRING、SEQUENCE、SET、OBJECT IDENTIFIER —— 用于构造SigningCertificateV2属性值。该编码器遵循 base-128 OID 弧的标准规则,并在可选的hashAlgorithm字段只是重复 SHA-256 默认值时省略该字段,与 OpenSSL 和 BouncyCastle 的输出一致。 ApplySignature现在把ETSI.CAdES.detached路由到 raw-byte 路径(与adbe.pkcs7.detached使用的相同路径),不再传入预先计算的 digest。CryptoAPI 现在会基于实际签名内容计算messageDigestauthenticated attribute,这正是验证者所期望的。- 构造 signing-certificate-v2 属性时同样会尊重 SHA-384 和 SHA-512:
hashAlgorithm字段会带上匹配的AlgorithmIdentifier发出,而不再依赖默认值。在此上下文中 SHA-1 会被静默升级为 SHA-256,因为 PAdES-B-B 不允许 SHA-1(clause 6.2.1)。
v3.56.16 2026-05-23
- 新增
SetSignProcessDigestAlgorithm,用于选择签名的 message-digest 算法:1= SHA-1(deprecated),2= SHA-256(现代默认值),3= SHA-384,4= SHA-512,0= auto(除 legacy 的adbe.pkcs7.sha1路径外,所有 SubFilter 均使用 SHA-256;该 legacy 路径继续使用 SHA-1 以保持字节级向后兼容)。ETSI EN 319 142-1 v1.2.1 §6.2.1 禁止 MD5 并将推荐密码套件交由 ETSI TS 119 312 规定,因此 PAdES 签名者应选择 SHA-256 或更强算法。 - 在既有的
SHA1StreamRange旁新增SHA256StreamRange、SHA384StreamRange和SHA512StreamRange哈希辅助函数;签名路径会使用它们按所选算法对 PDF ByteRange 求 digest。PKCS#7 的SignerInfo.digestAlgorithmOID 与实际写入的哈希字节现在保证一致(之前的代码无论协商出哪种算法都始终传入 SHA-1 digest)。 TPDFlibPFXFile.SignData现在接受DigestAlgorithm参数,并为每个 (SubFilter, algorithm) 组合选择正确的 OID:detached 与 custom SubFilter 走2.16.840.1.101.3.4.2.1/.2/.3对应 SHA-256/384/512(RFC 5754),legacy 的adbe.pkcs7.sha1路径走匹配的sha256WithRSAEncryption系列 OID。
v3.56.15 2026-05-23
- 新增
SetSignProcessDocTimeStamp,按 ETSI EN 319 142-1 v1.2.1 §5.4.3 把签名流程切换到 PAdES Document Time-stamp 模式。生成的 Signature Dictionary 携带/Type /DocTimeStamp与/SubFilter /ETSI.RFC3161,省略不允许的/M、/Reason、/Location、/ContactInfo、/Name键,并在/Contents中为外部获取的 RFC 3161 TimeStampToken 预留 8192 字节(或调用方指定大小)的十六进制占位符。 - 选择 DocTimeStamp 模式时自动启用 passthrough,因为 TimeStampToken 来自外部 TSA。切换到 DocTimeStamp 模式后再调用
SetSignProcessInfo会被静默忽略,以保持签名字典符合 spec。 - v3.56.8 新增的 PAdES
/Extensions /ESIC自动注入已经覆盖 DocTimeStamp,因为其 SubFilter 以ETSI.开头,所以 Document Time-stamp PDF 无需额外接线即可声明所需的 catalog extension。
v3.56.14 2026-05-23
- 新增 PAdES Document Security Store (DSS) 增量 API。
NewPAdESDSSProcessFromFile/NewPAdESDSSProcessFromStream/NewPAdESDSSProcessFromString打开已签名的 PDF,AddPAdESDSSCertificate/AddPAdESDSSCRL/AddPAdESDSSOCSP暂存 DER 编码的验证材料,EndPAdESDSSProcessToFile/EndPAdESDSSProcessToStream/EndPAdESDSSProcessToString写入增量更新,包含 ETSI EN 319 142-1 v1.2.1 §5.4.2.2 规定的/DSS << /Type /DSS /Certs [...] /CRLs [...] /OCSPs [...] >>字典。这是把 PAdES-B-B / B-T 签名升级到 PAdES-B-LT 长期验证的基础构件。 - 添加验证材料时,DSS 流程会自动把 catalog
/Extensions /ESIC项升级到至少ExtensionLevel 1,匹配 §5.6 的要求;重复调用时新证书、CRL 和 OCSP 响应会合并进既有的/Certs//CRLs//OCSPs数组,让修订内容累积而非覆盖。 GetPAdESDSSProcessResult/ReleasePAdESDSSProcess完成生命周期管理,镜像既有的SignProcessAPI 接口。
v3.56.8 2026-05-23
- PAdES baseline 一致性:当签名以 PAdES SubFilter(
ETSI.CAdES.detached或ETSI.RFC3161)创建时,文档目录现在会自动收到 ETSI EN 319 142-1 v1.2.1 §5.6 要求的/Extensions /ESIC <</BaseVersion /1.7 /ExtensionLevel 2>>项。该项通过承载签名的同一次增量更新写入,永远不会降级既有的更高/ExtensionLevel,并在源 PDF 已经把/Extensions或/ESIC存为单独对象时跟随其间接引用。 - SetSignProcessCustomSubFilter 为通过
TPDFlib编写的 PDF 写入的 Adobe 等价 extension 标记现在是/ADBE /BaseVersion /1.7 /ExtensionLevel 8(之前是ExtensionLevel 5),与 PAdES baseline 签名可使用的备选声明匹配;级别 5 只覆盖了 ISO 32000-2 forms / 3D / RichMedia 特性,实际并不标识 PAdES extensions。
v3.56.13 2026-05-23
- 当 SetPDFUAMode 激活并保存文档时,任何缺失显式
ListNumbering属性的 L(列表)结构元素现在会自动收到/O = List /ListNumbering = None。ISO 14289-1 §7.6 要求每个 L 标签声明其编号样式;新的ApplyPDFUAListNumbering保存时修复加入既有的ApplyPDFUATabOrder/ApplyPDFUAFormFieldTU/ApplyPDFUAAnnotContents/ApplyPDFUAEmbeddedAFRelationship/ApplyPDFUAStripTrapNet家族。 - 在意特定列表样式的作者仍应在 EndTag 之前调用 SetStructElemListNumbering;自动修复只在保存时检测不到 ListNumbering 属性时触发,因此显式值会被保留。
- writer 端的
LIST-NO-NUMBERING:N诊断消息现在会提示自动修复将在保存时掩盖该问题,让用户既了解缺失的属性也了解自动修复行为。
v3.56.12 2026-05-23
- PDF/UA-1 审计新增三项 ISO 14289-1 检查。
10031报告 URI action 字典携带/IsMap = true的 Link 注解(§7.18.5 禁止此项,除非内容他处提供等效功能;有正当 IsMap 使用场景的作者可自行抑制该诊断)。10032报告缺少/ID项的Note结构元素 — §7.9 要求每个 Note 标签声明唯一 ID。10033报告两个或以上 Note 标签共享同一/ID值时的重复配对数。 - Note ID 冲突检测通过把 ID 收集到排序的 TStringList 并遍历相邻配对完成,因此三个共享同一 ID 的 Note 计为两对重复。
- URI action 检查遍历每页的
/Annots数组,按/Subtype /Link过滤,然后检视/A /S /URI和/IsMap布尔值。间接引用在每一步都会解引用,因此拆分出的 action dict 与内联形式行为一致。
v3.56.11 2026-05-23
- ISO 14289-1 §7.6 要求每个 L(列表)结构元素携带显式
ListNumbering属性。10030(reader 端)与LIST-NO-NUMBERING:N(writer 端)报告省略该属性的 L 标签。reader 端遍历器解码两种/A形式(单一属性字典,或字典与 revision 整数混合的数组),并不区分 owner 寻找/ListNumbering键。writer 端检查在已最终化的结构列表和仍打开的标签栈中检视TPDFStructElem.Attributes中同名条目。 - ISO 32000-1 Table 347 规定的有效
ListNumbering值为None、Disc、Circle、Square、Decimal、UpperRoman、LowerRoman、UpperAlpha、LowerAlpha。审计只检查键的存在,不关心选了哪个值 —— 每个 L 标签都需要其中之一。
v3.56.10 2026-05-23
- PDF/UA-1 审计新增 ISO 14289-1 §7.21.6 TrueType 编码规则。
10028报告/Encoding(或 Encoding 字典内的/BaseEncoding)既不是MacRomanEncoding也不是WinAnsiEncoding的非符号 TrueType 字体。10029报告携带任何/Encoding项的符号 TrueType 字体(§7.21.6 第四段禁止此项)。 - 符号 vs. 非符号通过 FontDescriptor
/Flagsbit 3(mask4)判定,复用子类 4 既有的UAFontDescriptorSymbolichelper。§7.21.6 第一段全文(嵌入的 TrueType 程序必须包含匹配的 cmap 项)需要解析 TrueType 字体程序,仍待实现;以上字典级规则是无需 TrueType 解析器即可验证的实际层面。 - §7.21.6 中的 Differences 数组规则(仅 AGL 字形名、Microsoft Unicode cmap 必须存在)出于同样原因仍不在范围内 —— 它们需要字体程序检视。
v3.56.9 2026-05-23
- PDF/UA-1 审计新增完整的 ISO 14289-1 §7.18.4 检查。
10027报告/StructParent通过结构树的/ParentTree解析但未落到/S = Form结构元素上的 Widget 注解。之前 v3.56.7 的部分检查(10026)只能捕获完全缺少/StructParent的 Widget;新检查通过跟随 number-tree 指针并校验目标标签来完成规则。 - 新增的
NumberTreeLookuphelper 实现 ISO 32000-1 §7.9.7 的 number-tree 结构(扁平/Nums根、被/Limits限定范围的中间/Kids)。未来需要解析/StructParents页项或/PageLabels标签的审计可以复用它。 - Widget 注解 Form-tag 验证采用两层模型:缺少
/StructParent的 Widget 报告为10026;/StructParent存在但未解析为/S = Form的 Widget 报告为更具体的10027。这避免了同一违规在两个代码下被重复计数。
v3.56.7 2026-05-23
- 当 SetPDFUAMode 激活并保存文档时,任何
TrapNet注解项现在会从每页的/Annots数组中自动删除。ISO 14289-1 §7.18.2 禁止TrapNet注解;新的ApplyPDFUAStripTrapNet保存时修复加入既有的ApplyPDFUATabOrder/ApplyPDFUAFormFieldTU/ApplyPDFUAAnnotContents/ApplyPDFUAEmbeddedAFRelationship家族,使 PDF/UA 模式文档不再静默吐出TrapNet残留。 - PDF/UA-1 审计新增部分 §7.18.4 检查。
10026报告缺少/StructParent的 Widget 注解 — 没有/StructParent的 Widget 无法从结构树访问,因此无法嵌套在Form结构标签中。完整的结构性验证(通过ParentTree解析/StructParent并确认父级/S为Form)留到后续 release。 - writer 端 GetPDFUADiagnostics 新增对应的
WIDGET-NO-STRUCTPARENT:Nissue。既有的 TRAPNET-ANNOT 消息现在也会提示 SetPDFUAMode 在保存时自动剥除它们。
v3.56.6 2026-05-23
- PDF/UA-1 审计新增两项 ISO 14289-1 §7.4.2 标题层级检查。
10024报告文档顺序中第一个标题元素不是 H1(或 H)的情况。10025报告下降序列中标题级别跳跃的次数(例如 H1 后直接跟 H3 而没有 H2)。两项检查共享单次结构树先序遍历,解码嵌套的/K形式(单个 StructElem、StructElem / IndRefs / MCRs 数组)。 - writer 端 GetPDFUADiagnostics 新增对应的
FIRST-HEADING-NOT-H1issue,与 reader 端10024平齐。之前存在的 HEADING-LEVEL-SKIP writer 检查现在有了配套,也能捕获“首个标题是 H2”这类问题。
v3.56.5 2026-05-23
- 当 SetPDFUAMode 激活且文档随后被加密时,加密权限键(encrypt 字典中的
/P)现在会自动置位 bit 10(mask$200,“为无障碍提取文本和图形”),即使调用方未在传给 Encrypt 的TPDFExtraPermissions中包含ppCanCopyAccess。ISO 14289-1 §7.16 要求每个加密合规文件都允许无障碍提取,否则该位很容易遗漏。设置该位始终安全 —— 它仅授予辅助技术额外访问权限,不影响其他提取路径。 - writer 端 GetPDFUADiagnostics 新增
ENCRYPT-NO-ACCESSissue,当 PDFUAMode 开启且 encrypt 字典的/Pbit 10 被清除时触发。这能捕捉调用顺序边界情况:用户先调用Encrypt()然后才调用 SetPDFUAMode —— 诊断会提示用户重新调用Encrypt(),以便用修正后的/P重新 emit encrypt 字典。
v3.56.4 2026-05-23
- writer 端 GetPDFUADiagnostics 新增五项 ISO 14289-1 检查,使内存中的文档审计能捕获与 reader 端 CheckFileCompliance ComplianceTest=2 审计相同的违规。
SUSPECTS-TRUE标记 MarkInfo/Suspects=true(§7.1:PDF/UA 合规文件要求 Suspects=false)。ROLEMAP-STANDARD-REMAP:N标记会重映射标准结构标签的 AddRoleMap 调用 —— §7.1 禁止重映射标准标签。DC-TITLE-MISSING标记空的 XMP dc:title(独立于 DOCINFO-TITLE-MISSING,后者检查 /Info /Title)。TRAPNET-ANNOT:N标记 TrapNet 注解(§7.18.2 禁止)。ANNOT-PAGE-NO-TABS-S:N标记携带注解但页字典 /Tabs 不是 /S 的页(§7.18.3 要求这些页采用基于结构树的 tab 顺序)。 - writer 端与 reader 端的 PDF/UA-1 审计现在大致平齐:reader 端审计在保存文件上抛出的每个 issue 也可从内存诊断访问,仅在每个函数的格式约定上有差异(换行分隔文本 vs. NNNNN-code 字符串列表)。
v3.56.3 2026-05-23
- PDF/UA-1 审计新增 §7.21 字体检查。
10020报告任何 FontDescriptor 缺少FontFile/FontFile2/FontFile3的非 Standard-14 字体(§7.21.4.1:每个被渲染的字体必须嵌入其程序)。10021报告缺少/CIDToGIDMap项的 CIDFontType2 后代(§7.21.3.2)。10022指出在未嵌入程序的情况下被引用的 Standard 14 字体(Helvetica、Times、Courier、Symbol、ZapfDingbats 及粗体 / 斜体变体)—— §7.21.4 NOTE 5 明确这些字体不豁免嵌入。10023报告缺少/ToUnicodeCMap 且不匹配 §7.21.7 豁免列表(预定义 MacRoman / MacExpert / WinAnsi encodings、采用 Adobe-GB1 / CNS1 / Japan1 / Korea1 字符集合的 Type 0、非符号 TrueType)的字体。 - Composite Type 0 字体在两个层面检视:Type 0 父字典自身的
/ToUnicode,以及第一个后代 CIDFont 上的嵌入 //CIDToGIDMap。Type 3 字体跳过嵌入检查(其字形为内联 CharProcs),但仍参与/ToUnicode检查。 - 用于类似字体工作的 PDFlibPDFA helper 有意未共享 —— 六七个短例程(subset 前缀剥离、Standard-14 名称表、FontFile 存在性、Symbolic flag)作为
UA*helper 在本地复制,让 PDF/A 审计能继续演进而不破坏 PDF/UA,反之亦然。
v3.56.2 2026-05-23
- PDF/UA-1 审计新增五项 ISO 14289-1 检查,覆盖注解、嵌入文件和可选内容。
10015报告缺少非空/Contents替代描述的 Link 注解(§7.18.5),以便屏幕阅读器宣告链接目标。10016与10017标记缺少必需/F或/UF文件名键的嵌入文件 FileSpec 字典(§7.11)。10018标记省略非空/Name文本字符串的可选内容配置字典(§7.10)。10019标记含有禁用/AS键的可选内容配置字典(§7.10)。 - 已经驱动 TrapNet 和
/Tabs /S检查的逐页注解遍历现在在同一次遍历中收集 Link //Contents数据,保持审计在对象数上的 O(N)。
v3.56.1 2026-05-23
- PDF/UA-1 审计新增五项 ISO 14289-1 检查。
10010校验加密文件上的无障碍提取权限(加密/P键的 bit 10)(§7.16)。10011通过 XFA XDP 包内的<dynamicRender>required</dynamicRender>元素检测动态 XFA 表单(§7.15)。10012标记携带/Ref项的 Form XObject —— reference XObject 被禁用(§7.20)。10013标记TrapNet注解(§7.18.2)。10014遍历每页并报告任何携带注解但页字典未设置/Tabs /S的页(§7.18.3),以便 tab 顺序跟随结构树。 - 全部五个新代码通过上一 release 添加的同一对 CheckFileCompliance + GetStringListItem handle 流动 —— 无新增公开 API 接口。
v3.56.0 2026-05-23
- 新增 reader 端审计
CheckCompliancePDFUA,针对 ISO 14289-1(PDF/UA-1)验证外部 PDF。它通过接受任意输入 PDF(自身输出、扫描仪输出、第三方内容)并按 CheckFileCompliance 已有的 PDF/A 报告方式列出 PDF/UA-1 违规,补充既有的 GetPDFUADiagnostics writer 端检查。 - CheckFileCompliance 现在接受
ComplianceTest = 2来运行新的 PDF/UA-1 审计。ComplianceTest = 1下的 PDF/A 测试保持不变,issue 列表仍通过既有的 GetStringListCount / GetStringListItem handle 对回流。 - 首版覆盖 §5(XMP
pdfuaid:part标识)与 §7.1(Catalog/Metadata流、tagged-PDF 标记、结构树、viewer title 偏好、文档语言、XMPdc:title、/Suspects值,以及禁止重映射标准结构标签)的基础 PDF/UA-1 合规门槛。发出八个诊断代码 ——10001至10009—— 在数字范围上与 PDF/A00xxx代码视觉区分。 - 更深的 PDF/UA-1 条款(安全、注解、XObject、字体子集化)追踪到基于同一审计框架的后续补丁 release。
v3.55.6 2026-05-22
- 每个新生成的 XMP 包现在都携带 xmpMM:InstanceID 属性,格式为 uuid:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX。标识符通过 Win32 CoCreateGuid 生成,按 ISO 19005-1 §6.7.2 (Cor2) 与 PDF/A 最佳实践指南的推荐,为每个生成的文档赋予一个唯一、版本无关的指纹。非 Windows 构建(其 XMP 包保持为空)不受影响。
- xmpMM 命名空间(http://ns.adobe.com/xap/1.0/mm/)现在是 XMP 包 SelectionNamespaces 的一部分;新的 SetXMPMM 与 GenerateInstanceID helper 支撑 InstanceID 发射,并为未来的 xmpMM:History / xmpMM:DerivedFrom 支持奠定基础。
- 本 release 未添加 PDF/A Extension Schema description schema(pdfaExtension / pdfaSchema / pdfaProperty / pdfaType / pdfaField)。编写自定义 extension schema 需要超出当前 SetDublinCore / SetXMPBasic 形状的多步 bag / seq / 结构化属性构造;这项工作追踪到未来 release。需要声明自定义 XMP 属性的文档继续回退到 LoadFromString 路径。
v3.55.5 2026-05-22
- PDF/A 文档的注解 /F 标志现在在保存时被规范化。ISO 19005-1 §6.5.3 要求每个注解的 Print 位为 1 且 Hidden / Invisible / NoView 位为 0;writer 现在在保存时应用该掩码,调用方无需记忆位布局。/Subtype /Popup 情况豁免 —— popup 是其他注解的子项,传统上不打印。
- 当文档处于任何 PDF/A 模式时,AcroForm /NeedAppearances 标志现在在保存时强制设为 false。ISO 19005-1 §6.9 要求该标志缺失或为 false;之前 writer 保留调用方设置的任何值,产生的文档会要求 viewer 在打开时重新生成 appearances,并在调用方将其设为 true 时静默违反 spec。该修复同样作用于之前缺失该标志的文档 —— writer 显式 emit /NeedAppearances false,给验证器留下零歧义。
v3.55.4 2026-05-22
- AddStandardFont 现在在 PDF/A 模式下拒绝调用。ISO 19005-1 §6.3.4 撤销了 PDF reference 中 “Standard 14 可不嵌入” 的豁免:合规文件中的每个字体程序都必须嵌入,且本库不打包 Standard 14 轮廓。门面层静默返回 0;调用方应改用 AddTrueTypeFont 或 AddType1Font 配真实字体文件。
- AddTrueTypeFont 现在在 PDF/A 模式激活时把 Embed=0(不嵌入)静默升级为 Embed=1(嵌入完整字体)。非嵌入引用路径产生的 PDF 依赖 viewer 对系统 Arial / Times / Courier 安装的字体回退,违反 ISO 19005-1 §6.3.4。已请求嵌入(Embed=1 或 2)的既有调用方不受影响。
- 非符号 TrueType /Encoding 合规检查(ISO 19005-1 §6.3.7 Cor2 要求 WinAnsi 或 MacRoman 作为 encoding 名或 BaseEncoding,不带 /Differences)本 release 未添加,因为本库对非符号 TrueType subset 已经 emit /WinAnsiEncoding,而更深的执行需要跟踪 subset 路径上的 symbolic-vs-non-symbolic 派发。CheckCompliancePDFA 00034 / 00035(v3.51.0 添加)会在验证时标记任何不合规的输出。
v3.55.3 2026-05-22
- TrueType 支持的 CIDFontType2 字体字典现在显式携带 /CIDToGIDMap /Identity。ISO 19005-1 §6.3.3.2 (Cor2) 要求每个嵌入的 Type 2 CIDFont 必须存在该项;PDF reference 允许隐式 Identity 默认,但 PDF/A 要求显式值。writer 之前完全省略该键,导致 veraPDF(以及 v3.51.0 添加的 CheckCompliancePDFA 00033)标记文件。/Identity 名称匹配 writer 已经隐式产生的 GID-as-CID 布局,所以既有文档渲染完全一致。
- FontDescriptor /CharSet(用于 Type 1 subset)与 /CIDSet(用于 CIDFont subset)仍为 TODO;writer 需要跟踪哪些字形名 / CID 进入 subset 才能准确填充它们。CheckCompliancePDFA 00031 与 00032(同样在 v3.51.0 添加)会标记其缺失,让用户在验证时看到问题。
v3.55.2 2026-05-22
- AddImageDirectFromString 现在在入口拒绝与 PDF/A 不兼容的 filter。传入 Filter = 'LZWDecode' 在每个 PDF/A 部分都被拒绝(ISO 19005-1 §6.1.10 加上等价的 ISO 19005-2 / -3 规则)。传入 Filter = 'JBIG2Decode' 或 'JPXDecode' 在 PDF/A-1(模式 1 和 2)下被拒绝。PDF/A-2 与 PDF/A-3 在 ISO 19005-2 §6.2.8.3 下允许 JPXDecode,但有子规范约束(颜色通道数、位深一致性、METH/APPROX 要求)writer 端门禁不强制 —— 这些模式下的调用方仍需自行确保 JPEG 2000 流合规。请求禁用 filter 时门面层静默返回 0。
- 通过 AddImageFromFile / AddImageFromStream 加载的 TIFF、PNG、JPEG 和 JPEG 2000 输入不受影响:导入器解压源字节并用 FlateDecode(JPEG 负载用 DCTDecode)重新编码,因此 LZW 输入永远不会传播到输出 Filter 链。v3.50.0 添加的 CheckCompliancePDFA 验证器(00004)和 v3.52.0 添加的(00022、00023)为任何仍把禁用 filter 间接滑入输出的路径提供验证时的第二道防线。
v3.55.1 2026-05-22
- AddLinkToHideField 现在在 PDF/A 模式下拒绝调用。上一 release 留有注释声称该 action 兼容 PDF/A,但 ISO 19005-1 Cor2 已把 /Hide 加入禁用 action 列表(§6.6.1),ISO 19005-2 / -3 继承该限制。门面层在 PDF/A 模式被调用时静默返回 0,与 AddLinkToJavaScript 和 AddLinkToImportData 一致。
- AddSWFAnnotationFromFile 现在在 PDF/A 模式下拒绝调用。SWF / RichMedia 注解封装了 Flash 媒体,被 ISO 19005-1 §6.5.2 禁止(不允许 Movie / Sound 子类型),并被 ISO 19005-2 §6.3.1 加强(不允许 3D / Sound / Screen / Movie)。门面层静默返回 0。
- AddEmbeddedFile 与 AddLinkToEmbeddedFile 现在在 PDF/A-1 与 PDF/A-2 模式下拒绝调用。ISO 19005-1 §6.1.11 禁止 /EF,ISO 19005-2 §6.8 仅允许嵌入 PDF/A 文件;与其递归验证附加负载的 PDF/A 合规性,writer 在这些模式下直接拒绝调用。PDF/A-3(SetPDFAMode 5 或 6)仍被允许 —— 见 v3.55.0 的自动 /AFRelationship 注入。
- SetOpenActionMenu 现在在文档处于 PDF/A 模式时拒绝 {NextPage, PrevPage, FirstPage, LastPage} 白名单外的 MenuItem 值。ISO 19005-1 §6.6.1 把命名 action 限制在该集合,因此之前 API 静默产生 veraPDF 会拒绝的不合规 Find / Print / FullScreen Open-Action 字典。
- NewOptionalContentGroup 现在在 PDF/A-1 模式(SetPDFAMode 1 或 2)下拒绝调用。ISO 19005-1 §6.1.13 禁止 Catalog /OCProperties 键。PDF/A-2(模式 3/4)与 PDF/A-3(模式 5/6)在各自 §6.9 的约束下允许可选内容,因此门禁仅对 PDF/A-1 触发。
v3.55.0 2026-05-22
- PDF/A-3 文档现在自动在每个嵌入文件上接收 /AFRelationship 项。之前用本库创建的 PDF/A-3 文件可能因 ISO 19005-3 Annex E, Table E.1 要求每个嵌入文件规范上必须有 AFRelationship 而验证失败。writer 现在在保存时给任何缺少该项的 FileSpec 字典注入配置的默认值(开箱即 'Unspecified'),镜像之前引入的 PDF/UA AFRelationship 自动注入。仅 PDF/A-3 模式(SetPDFAMode 5 = PDF/A-3b 或 6 = PDF/A-3a)触发自动注入;PDF/A-1 与 PDF/A-2 仍按 ISO 19005-1 §6.1.11 与 ISO 19005-2 §6.8 直接拒绝嵌入文件。
- SetPDFA3DefaultAFRelationship 是新增 API,覆盖 writer 在嵌入文件缺少 /AFRelationship 项时写入的默认值。接受 ISO 19005-3 Table E.1 的值 'Source'(嵌入文件是产生 PDF 内容的源材料)、'Data'(文件是支撑视觉表格或图表的结构化数据)、'Alternative'(替代呈现,例如音频版本)、'Supplement'(补充呈现,例如方程的 MathML 形式)、'Unspecified'(关系无法由上述描述),或任何已注册的二类名。空字符串重置为 'Unspecified'。每文件覆盖仍可通过 SetEmbeddedFileAFRelationship 使用。
- 新 API 在 Delphi 门面上以 TPDFlib.SetPDFA3DefaultAFRelationship 暴露,并通过 DLL 以 DLSetPDFA3DefaultAFRelationship(PWideChar)与 DLSetPDFA3DefaultAFRelationshipA(PAnsiChar)暴露。
v3.54.0 2026-05-22
- LoadOutputIntentProfile 是新增 API,用从磁盘加载的外部 ICC profile 替换打包的 sRGB OutputIntent profile。在 DeviceCMYK 或 DeviceGray 颜色空间下生产 PDF/A 文档时必需,因为本库仅打包 sRGB profile。典型用法是先调用 SetPDFAMode(初始化 OutputIntent 骨架),然后 LoadOutputIntentProfile('C:\\path\\to\\FOGRA39.icc', 'DeviceCMYK') 来替换 profile 字节并把文档标记为新颜色空间。成功返回 1,文件未找到或未知颜色空间返回 0。在 Delphi 门面上以 TPDFlib.LoadOutputIntentProfile 暴露,并通过 DLL 以 DLLoadOutputIntentProfile(PWideChar 形式)与 DLLoadOutputIntentProfileA(PAnsiChar 形式)暴露。ISO 19005-1 §6.2.2 允许 DestOutputProfile 流中使用任何注册的 ICC profile。
- SetFillColorCMYK、SetTextColorCMYK、SetTextHighlightColorCMYK、SetTextUnderlineColorCMYK、AddSeparationColor、SetFillColorSep、SetLineColorSep、SetTextHighlightColorSep 与 SetTextColorSep 现在在文档 OutputIntent profile 为 DeviceCMYK 时在 PDF/A 模式下成功。之前这些 API 在 PDF/A 模式下无论 OutputIntent 如何都拒绝每个调用,导致无法生产合规的 CMYK 文档。门禁现在是 PDFAMode = 0 或 OutputIntentColorSpace = 'DeviceCMYK',匹配 ISO 19005-1 §6.2.3.3 关于 OutputIntent 使用 CMYK profile 时允许 DeviceCMYK 的规则,以及 ISO 19005-1 §6.2.3.4 允许基础颜色空间也合规的 Separation 替代色。
- SetTextShader 现在在 OutputIntent profile 为 DeviceRGB 或 DeviceCMYK 时在 PDF/A 模式下成功。shader 本身并未被 PDF/A 禁止;验证器(reader 端)校验 shader 的内部颜色空间与 OutputIntent 匹配。之前的严格拒绝行为拒绝了合规的 shader 使用。
- CMYK / Separation / Shader 解封依赖 AddOutputIntent 与 LoadOutputIntentProfile(v3.53.0 引入)设置的 OutputIntentColorSpace 标签。调用 SetPDFAMode 而不调用 LoadOutputIntentProfile 保持颜色空间为 DeviceRGB(打包的 sRGB profile),因此 CMYK 调用仍默认拒绝 —— 新行为通过 LoadOutputIntentProfile 主动启用。
v3.53.0 2026-05-22
- OutputIntent 字典现在携带 ISO 19005-1 §6.2.2 与 Adobe Acrobat preflight 推荐的完整 PDF/A 骨架字段:/OutputCondition(人类可读的颜色条件描述)、/Info(长形识别文本)、/RegistryName(注册中心 URL,默认为 http://www.color.org)。这些值对遗留单参数调用点默认为 "sRGB IEC61966-2.1" / "sRGB IEC61966-2.1" / "http://www.color.org";新的 AddOutputIntent 重载直接接受这四个自定义字段,让调用方为自己的颜色条件填充。
- AddOutputIntent 新增五参数重载:AddOutputIntent(ColorSpace, OutputConditionIdentifier, OutputCondition, Info, RegistryName)。遗留单参数形式继续工作不变;现在它委托给新重载并传入 sRGB 默认。ColorSpace 参数也选择写入嵌入 ICC profile 字典的 /N 分量数(DeviceRGB 为 3,DeviceCMYK 为 4,DeviceGray 为 1);嵌入的 profile 本身仍是打包的 sRGB 流,直到即将到来的 LoadOutputIntentProfile API 在 v3.54.0 发布。
- TPDFDocument 暴露 OutputIntentColorSpace 作为读/写属性,跟踪最后一次 AddOutputIntent 调用的颜色空间。这成为 v3.54.0 中 CMYK / Separation / Shader writer 端限制的门禁条件,今天在 PDF/A 模式下拒绝每个调用的颜色 API 将只在颜色空间与 OutputIntent 不匹配时拒绝。
v3.52.0 2026-05-22
- CheckCompliancePDFA 现在审计注解、graphics-state、action 和 form XObject,完成 PDF/A 读端验证器对 ISO 19005-1 第 6.2-6.6 章节与等价 PDF/A-2/-3 差异规则的覆盖。验证器报告 14 个新 issue 类(00050-00067):禁用的注解子类型(00050;ISO 19005-1 §6.5.2 在 PDF/A-1 下禁止 FileAttachment / Sound / Movie,ISO 19005-2 §6.3.1 在 PDF/A-2 与 PDF/A-3 下禁止 3D / Sound / Screen / Movie)、注解 /CA 不等于 1.0(00051;§6.5.3)、注解 /F 缺失或 Print=0 / Hidden=1 / Invisible=1 / NoView=1(00052;§6.5.3,/Subtype /Popup 豁免)、注解 /AA(00054;§6.6.2)、注解 appearance dict 包含 /N 以外的键或不合规的 /N 值(00055;§6.5.3 Cor2)、Widget 注解带 /A(00056;§6.9)、ExtGState /TR(00058;§6.2.8)、ExtGState /TR2 不等于 /Default(00059;§6.2.8),仅 PDF/A-1:ExtGState /SMask 不等于 /None(00061;§6.4)、/BM 不为 Normal 或 Compatible(00062;§6.4)、/CA 或 /ca 不等于 1.0(00063;§6.4)。
- Action-anywhere 审计(00064、00065)以全面扫描替代 v3.50.0 中仅检查 OpenAction 的做法,无论 action 位于何处(注解 /A、widget /A、outline /A、catalog /OpenAction 等),都标记禁用的 /S action 值(Launch、Sound、Movie、ResetForm、ImportData、JavaScript、Hide、SetState、NOP、Trans、GoTo3DView、Rendition、SetOCGState)以及 /N 不在 {NextPage, PrevPage, FirstPage, LastPage} 集合内的命名 action。ISO 19005-1 §6.6.1。
- XObject 审计(00066、00067)报告 PostScript 和 Reference XObject,外加 Form XObject 的禁用键(/OPI、/PS、/Subtype2 = /PS)和 Image XObject 的禁用键(/Alternates、/OPI、/Interpolate true)。ISO 19005-1 §6.2.4 - §6.2.7。
v3.51.0 2026-05-22
- CheckCompliancePDFA 现在除 v3.50.0 添加的结构性检查外,还审计字体与颜色空间一致性。验证器报告九个新 issue 类:至少一个字体程序未嵌入(00030;ISO 19005-1 §6.3.4 要求每个字体程序,包括 Standard 14 替代,必须嵌入)、Type 1 subset 在其 FontDescriptor 中缺少 /CharSet(00031;§6.3.5)、CIDFont subset 缺少 /CIDSet(00032;§6.3.5)、CIDFontType2 缺少 /CIDToGIDMap(00033;§6.3.3.2 Cor2)、非符号 TrueType 带不合规 /Encoding(00034;§6.3.7 Cor2 要求 WinAnsi/MacRoman 直接作为名称或 BaseEncoding,不带 /Differences)、符号 TrueType 仍携带 /Encoding(00035;§6.3.7 Cor2)、PDF/A-Na 或 PDF/A-Nu 文档中至少一个字体缺少 /ToUnicode(00036;应用 §6.3.8 四类豁免)、ICCBased 颜色空间未嵌入其 profile 流(00037;§6.2.3.2)、文件同时使用 DeviceRGB 与 DeviceCMYK(00038;§6.2.3.3 禁止混用)。
- /ToUnicode 检查(00036)仅对一致性级别 A 与 U 生效,因为只有这些级别按 ISO 19005-1 §6.3.8 与 ISO 19005-2 §6.2.11.7 要求 Unicode 映射。Level B 文件(PDF/A-1b、PDF/A-2b、PDF/A-3b)不被标记。四类豁免识别预定义 encoding(MacRomanEncoding、MacExpertEncoding、WinAnsiEncoding)、Standard 14 Type 1 BaseFonts 作为 Adobe Standard Latin / Symbol 字形名字体的代理,以及后代 CIDFont 使用 Adobe-GB1、Adobe-CNS1、Adobe-Japan1 或 Adobe-Korea1 注册中心的 Type 0 字体。
- 字体审计遍历每个 Font 字典,按 Subtype(Type1、MMType1、TrueType、Type3、Type0 及其后代 CIDFontType0 或 CIDFontType2)分类,然后派发相关检查。Type 0 composite 字体把嵌入和 subset 检查委托给其后代 CIDFont,同时把 /ToUnicode 保留在 Type 0 包装层。Subset 检测使用标准的六个大写字母前缀约定。
v3.50.0 2026-05-22
- CheckCompliancePDFA 现在报告验证器之前漏掉的 15 项 PDF/A 不合规问题:缺少 trailer /ID 数组(00013)、缺少 Document Catalog /Metadata 流(00014)、/Filter 应用到 /Metadata 流(00015)、流字典通过 /F、/FFilter 或 /FDecodeParms 引用外部文件(00016)、PDF/A-1 文档中通过任何文件规范字典的 /EF 或通过 Name tree /EmbeddedFiles 项声明的嵌入文件(00017、00018)、/OpenAction 指向禁用 action 类型(00019)、Document Catalog 或任何 Page 中的 /AA additional-action 字典(00020、00021)、PDF/A-1 文档中的 JBIG2Decode 或 JPXDecode filter(00022、00023)、/Name 不为 /Identity 的 Crypt filter(00024)、Document Catalog 中的 /Requirements(00025)、键不为 /UR3 与 /DocMDP 的 /Perms(00026),以及 /AcroForm /NeedAppearances 设为 true(00027)。验证器现在按 ISO 19005-1 §6.6.1 标记禁用的 Catalog /OpenAction action 类型(/Launch、/Sound、/Movie、/ResetForm、/ImportData、/JavaScript、/Hide、/SetState、/NOP、/Trans、/GoTo3DView、/Rendition、/SetOCGState)以及 /N 不在 {NextPage, PrevPage, FirstPage, LastPage} 白名单内的命名 action。
- PDFAID parser 接受 U 一致性后缀(PDF/A-2U、PDF/A-3U)与既有的 A、B 变体并列,因此 CheckCompliancePDFA 在扫描其他工具产生的 PDF/A-2U 或 PDF/A-3U 文件时不再抛出虚假的 "00005 PDFA Mark NOT Found or invalid" 警告。ISO 19005-2:2011 添加的 Unicode 映射一致性级别现在被验证器识别。
- Filter 特定检查(JBIG2Decode、JPXDecode)与嵌入文件检查(/EF、/EmbeddedFiles)仍限定为 PDF/A-1,因为 ISO 19005-2 §6.2.8.3 与 §6.8 明确放宽了 PDF/A-2 与 PDF/A-3 的这些限制。文档结构检查(/Metadata、/AcroForm /NeedAppearances、/OpenAction、/AA、/Requirements、/Perms)适用于每个 PDF/A 部分。
v3.49.0 2026-05-21
- AddLinkToImportData 创建一个 Link 注解,其 action 是 PDF 导入数据动作(/S /ImportData),用户点击链接时从外部 FDF 文件填充文档的 AcroForm 字段(ISO 32000-1 §12.6.4.8, Table 198)。FileName 参数以文件规范字典形式引用,路径规范化规则与 AddLinkToFile / AddLinkToFileEx 一致(按 ISO 32000-1 §7.11.2.1 将反斜杠转换为正斜杠)。Options 位 0 控制是否显示边框,位 1–3 选择链接高亮模式(Invert、Outline、Push),与既有的 AddLinkTo* 约定一致。PDF 1.4 或更高版本。PDF/A 模式下不允许,因为该 action 引用了外部资源;门面层在 PDF/A 模式下被调用时静默返回 0。在 Delphi 库及 DLL 接口中以 DLAddLinkToImportData / DLAddLinkToImportDataA(PWideChar 与 PAnsiChar 两种形式)暴露。
v3.48.0 2026-05-21
- AddLinkToHideField 创建一个 Link 注解,其 action 是 PDF 隐藏动作(/S /Hide),用户点击链接时切换一个或多个 AcroForm 字段的可见性(ISO 32000-1 §12.6.4.10, Table 196)。FieldNames 接受一个或多个完全限定字段名,以逗号、分号或换行分隔;单个名字以文本字符串形式写入 /T,两个及以上以数组形式写入 /T,spec 允许两种形式。HideFlag 选择可见性方向:非零值隐藏列出的字段(/H true),零值显示字段(/H false)。Options 位 0 控制是否显示边框,位 1–3 选择链接高亮模式(Invert、Outline、Push),与 AddLinkToWeb / AddLinkToNamedAction 一致。PDF 1.2 或更高版本。因为不引用外部资源,所以兼容 PDF/A。在 Delphi 库及 DLL 接口中以 DLAddLinkToHideField / DLAddLinkToHideFieldA(PWideChar 与 PAnsiChar 两种形式)暴露。
v3.47.0 2026-05-21
- AddLinkToNamedAction 创建一个 Link 注解,其 action 是 PDF 命名动作(/S /Named),触发 ISO 32000-1 §12.6.4.11, Table 194 定义的四个标准 viewer 导航命令之一:NextPage、PrevPage、FirstPage、LastPage。NamedActionType 参数选择命令(0=NextPage,1=PrevPage,2=FirstPage,3=LastPage);越界值回退到 NextPage,确保 writer 总是写出符合 spec 的 /N 名称。Options 位 0 控制是否显示边框,位 1–3 选择链接高亮模式(Invert、Outline、Push),与既有的 AddLinkToWeb / AddLinkToPage 约定一致。注解需要 PDF 1.1 或更高版本,因为不引用外部资源,所以兼容 PDF/A。在 Delphi 库及 DLL 接口中提供。
v3.46.1 2026-05-21
- AddCaretAnnotation 在给定矩形位置创建一个 caret 标记注解(PDF /Subtype /Caret),用于标记页面上文本或内容被插入、省略或需要审阅者关注的位置。通过 SymbolType(0 / 1)支持两种符号类型(None 和 Paragraph),并可配置颜色、不透明度、标题、内容以及创建/修改时间戳。定义见 ISO 32000-1 §12.5.6.11。PDF 1.5 或更高版本。在 Delphi 库及 DLL 接口中提供。
- 本条目完成了从 v3.44.0 Square+Circle 开始的几何注解补齐工作。PDFlibPas 现已能创建 Text、Stamp、FreeText、TextMarkup(Highlight/Underline/Squiggly/StrikeOut)、Square、Circle、Line、Polygon、PolyLine、Ink 和 Caret 等多种注解,外加已有的 Link、FileAttachment、SVG、U3D 和 SWF 支持。
v3.46.0 2026-05-21
- AddInkAnnotation 创建一个 ink 标记注解(PDF /Subtype /Ink),表示在页面上绘制的手写笔画或自由形状标记。笔画作为单一字符串传入,多笔画间用 '|' 或换行分隔,每个笔画内部的坐标对采用与 AddPolygonAnnotation 相同的空格/逗号/分号/制表符格式。例如 "100 100 110 105 120 110 | 200 200 210 205" 描述两条独立笔画。支持可配置的边框宽度、ink 颜色、不透明度、标题、内容以及时间戳。定义见 ISO 32000-1 §12.5.6.13。PDF 1.3 或更高版本。在 Delphi 库及 DLL 接口中提供。
- 每条笔画必须含偶数个数值(至少四个),否则调用返回 0 且不写入任何注解。/Rect 根据所有笔画的合并范围自动计算,并加上少量内边距以确保笔画始终位于注解包围盒内。
v3.45.0 2026-05-21
- AddPolygonAnnotation 创建一个闭合多边形标记注解(PDF /Subtype /Polygon),顶点以空格、逗号、分号或制表符分隔的坐标对字符串形式传入(例如 "100 100 200 100 200 200 100 200")。支持可配置的边框宽度、边框颜色、可选的内部填充颜色、不透明度、标题、内容以及时间戳。定义见 ISO 32000-1 §12.5.6.9。PDF 1.5 或更高版本。在 Delphi 库及 DLL 接口中提供。
- AddPolyLineAnnotation 创建一个开放折线标记注解(PDF /Subtype /PolyLine),采用相同的顶点字符串格式,并可在两端配置端点样式(None、Square、Circle、Diamond、OpenArrow、ClosedArrow、Butt、ROpenArrow、RClosedArrow、Slash)。定义见 ISO 32000-1 §12.5.6.9。PDF 1.5 或更高版本。在 Delphi 库及 DLL 接口中提供。
- 两种注解都至少需要两个顶点(四个数)且数值总数为偶数;如果顶点字符串无法解析为有效配对列表,调用返回 0。/Rect 根据顶点范围加上与边框宽度成比例的内边距计算,确保端点装饰保持可见。
- 两种注解在文档最低版本被锁定到更低值时,emit 时会将文档版本自动 bump 到 PDF 1.5。
v3.44.1 2026-05-21
- AddLineAnnotation 创建一条 line 标记注解(PDF /Subtype /Line),连接两个端点,可配置边框宽度、线条颜色、可选的内部填充颜色、两端的端点样式(None、Square、Circle、Diamond、OpenArrow、ClosedArrow、Butt、ROpenArrow、RClosedArrow、Slash)、不透明度、标题、内容以及创建/修改时间戳。定义见 ISO 32000-1 §12.5.6.7。PDF 1.3 或更高版本。在 Delphi 库及 DLL 接口中提供。
- 注解的 /Rect 根据两个端点加上与边框宽度成比例的内边距计算,确保端点装饰保持在注解包围盒内。
v3.44.0 2026-05-21
- AddSquareAnnotation 在给定矩形位置创建一个矩形标记注解(PDF /Subtype /Square),可配置边框宽度、边框颜色、可选的内部填充颜色、不透明度、标题、内容以及创建/修改时间戳。定义见 ISO 32000-1 §12.5.6.8。PDF 1.3 或更高版本。在 Delphi 库及 DLL 接口中提供。
- AddCircleAnnotation 创建一个内切于给定矩形的椭圆标记注解(PDF /Subtype /Circle),其可配置的边框、填充、不透明度、标题、内容以及时间戳与 AddSquareAnnotation 一致。定义见 ISO 32000-1 §12.5.6.8。PDF 1.3 或更高版本。在 Delphi 库及 DLL 接口中提供。
- 两种新注解在文档最低版本被锁定到更低值时,emit 时会自动 bump 到 PDF 1.3,并 emit 标准的标记注解字段集(/Type /Subtype /Rect /C /IC /BS /Border /CA /F /M /CreationDate /NM /T /Contents /Subj /P),因此 Acrobat、Foxit 和 Edge 既有的审阅工作流都可以在创建后继续编辑这些注解。
v3.43.0 2026-05-20
- SetStructElemSpaceBefore 与 SetStructElemSpaceAfter 在当前打开的结构元素上设置 /SpaceBefore 与 /SpaceAfter 属性(Layout owner),以点为单位表达块级元素前后的间距。定义见 ISO 32000-1 §14.8.5.4.2 Table 340。在 Delphi 库、ActiveX(Dispid 73008051/73008052)和 DLL 接口中提供。
- SetStructElemStartIndent 与 SetStructElemEndIndent 在当前打开的结构元素上设置 /StartIndent 与 /EndIndent 属性(Layout owner),以点为单位表达从内容矩形写入方向相关的起始与结束边的缩进距离。定义见 ISO 32000-1 §14.8.5.4.2 Table 340。在 Delphi 库、ActiveX(Dispid 73008053/73008054)和 DLL 接口中提供。
- SetStructElemColor 设置 /Color 属性(Layout owner)为一个 RGB 三元组(每个分量 0.0-1.0),描述元素的前景色,用于重排引擎和下游色彩对比度检查器。定义见 ISO 32000-1 §14.8.5.4.2 Table 340。在 Delphi 库、ActiveX(Dispid 73008055)和 DLL 接口中提供。
- 修复了 BuildStructElemDictRef 中的序列化 bug:单 token 数字属性值(如 SpaceBefore、SpaceAfter、StartIndent、EndIndent)原本被写成 PDF 名字而不是 PDF 数字。修复同时适用于单 owner 和多 owner 属性分支。
v3.42.0 2026-05-20
- CheckCompliancePDFA 现已正确校验全部六种 PDF/A 模式(1a、1b、2a、2b、3a、3b)。PDFAID 检查(代码 00005)接受六个有效 XMP 标记中的任意一个,而非仅 '1B'。版本上限检查(00002)对 PDF/A-1 应用 1.4,对 PDF/A-2 与 PDF/A-3 应用 1.7。
- OCProperties 检查(代码 00003)现在按条件应用:仅对 PDF/A-1 文档生效,因 PDF/A-1 禁止可选内容(图层)。PDF/A-2 与 PDF/A-3 允许图层,不再标记。
- 新增三项合规检查:代码 00006 标记加密文档(所有 PDF/A 版本禁止加密);代码 00007 标记目录中缺少 OutputIntents 项的文档(所有 PDF/A 版本要求该项);代码 00011 与 00012 标记一致性级别为 -a(无障碍)时缺少 MarkInfo 或 StructTreeRoot 的文档。
v3.41.0 2026-05-20
- PDF/A 模式现在在 API 层强制阻止禁用操作。当任何 PDF/A 模式(1-6)激活时,调用 SetEncryption、AddSeparationColor、SetFillColorCMYK、SetTextColorCMYK 或任何其他 CMYK/Separation/Shader API 都会返回 0 且无效果,与 PDF/A 要求单一 sRGB 输出意图的规定一致。
- PDF/A-1(模式 1 和 2)禁止透明度:SetTransparency、SetBlendMode 和 SetPageTransparencyGroup 在当前模式为 1 或 2 时返回 0 且为 no-op。PDF/A-2 与 PDF/A-3(模式 3-6)允许有限透明度,不受限制。
- 所有 PDF/A 模式(1-6)都禁止 JavaScript 动作:SetOpenActionJavaScript、PageJavaScriptAction、DocJavaScriptAction、AddGlobalJavaScript 和 AddLinkToJavaScript 在任何 PDF/A 模式激活时都返回 0 且为 no-op。ISO 19005-1 §6.6.1 明确禁止 PDF/A 文档使用 JavaScript。
- 文件附件 API(EmbedFile、AddFileAttachment)在 PDF/A-1 和 PDF/A-2 模式(1-4)下被阻止。在 PDF/A-3(模式 5 和 6)下仍可用,因为 PDF/A-3 明确允许任意嵌入文件。
v3.40.0 2026-05-20
- SetPDFAMode 现已支持 PDF/A-2 与 PDF/A-3 一致性级别。NewMode=3 为 PDF/A-2b,4 为 PDF/A-2a,5 为 PDF/A-3b,6 为 PDF/A-3a。PDF/A-2 目标为 PDF 1.7,允许图层、交互表单、JPEG2000 图像和有限透明度。PDF/A-3 在 PDF/A-2 基础上额外允许任意嵌入文件(任意 MIME 类型)。所有 -a 变体会自动写入 /MarkInfo 与无障碍一致性级别所需的标签化 PDF 结构标记。
- 修复:SetPDFAMode(1)(PDF/A-1a)原本因为 v3.20.0 引入的内部路由 bug 是 no-op,现已正确写入 /MarkInfo 与 /OutputIntents,并设置 XMP pdfaid:part=1/conformance=A。
- GetInformation(201) 返回 '1' 至 '6',对应活动的 PDF/A 模式,与新的模式编号保持一致。
v3.39.0 2026-05-20
- SetStructElemWritingMode 在当前打开的结构元素上设置 /WritingMode 属性(Layout owner)。有效值为 LrTb(从左到右,拉丁文脚本默认)、RlTb(从右到左,阿拉伯文和希伯来文)以及 TbRl(从上到下从右到左,传统中日韩竖排文本)。定义见 ISO 32000-1 §14.8.5.4.2 Table 340。在 Delphi 库、ActiveX(Dispid 73008049)和 DLL 接口中提供。
- SetStructElemListNumbering 在当前打开的结构元素上设置 /ListNumbering 属性(List owner)。支持的值包括 None、Disc、Circle、Square(无序标记)以及 Decimal、UpperRoman、LowerRoman、UpperAlpha、LowerAlpha(有序编号)。属性设置在 L(list)元素上,使辅助技术能够正确朗读列表类型。定义见 ISO 32000-1 §14.8.5.3.2 Table 336。在 Delphi 库、ActiveX(Dispid 73008050)和 DLL 接口中提供。
v3.38.0 2026-05-20
- SetStructElemColSpan 在当前打开的结构元素上设置 /ColSpan 属性(Table owner),指示单元格跨越的列数。定义见 ISO 32000-1 §14.8.5.7.2 Table 337。在 Delphi 库、ActiveX(Dispid 73008047)和 DLL 接口中提供。
- SetStructElemRowSpan 在当前打开的结构元素上设置 /RowSpan 属性(Table owner),指示单元格跨越的行数。定义见 ISO 32000-1 §14.8.5.7.2 Table 337。在 Delphi 库、ActiveX(Dispid 73008048)和 DLL 接口中提供。
- 两个函数都是便捷封装,等效于调用 AddTagAttribute 时传入 Owner='Table' 与对应属性名。它们补充了 SetStructElemScope,用于完整描述复杂或跨越式表头表格中的单元格。
v3.37.2 2026-05-20
- GetPDFUADiagnostics 现在会在 N 个交互表单字段(Widget 注解)缺少 TU(工具提示 / 无障碍名称)项时报告 FORM-NO-TOOLTIP:N。ISO 14289-1 §7.18.4 要求所有交互表单字段都携带 TU 项,以便字段获得焦点时辅助技术能向用户朗读字段用途。/TU 是屏幕阅读器朗读的无障碍名称;它与 /T 不同,后者是用于编程访问与表单提交的部分字段名。
v3.37.1 2026-05-20
- GetPDFUADiagnostics 现在会在 N 个 LI 或 LBody 结构元素出现在所需父元素之外时报告 LIST-STRUCT:N。ISO 32000-1 §14.8.4.4 要求 LI 是 L(列表)的直接子元素,LBody 是 LI(列表项)的直接子元素。列表嵌套畸形会导致辅助技术无法正确遍历与朗读列表内容,并可能在 PDF/UA-1 校验器中触发文档结构校验失败。
v3.37.0 2026-05-20
- BeginTagEx2 是新增 API,在单次调用中打开一个结构元素并设置全部主要元素属性。除 BeginTagEx 的 TagType、AltText、ActualText、Lang 参数外,BeginTagEx2 还接受 Title(/T,用于 Tags 导航面板)、ElemID(/ID,元素唯一标识)和 Expansion(/E,缩写或首字母缩略词的完整形式)。这三个新增参数中任意一个传入空字符串等同于省略对应的 setter。BeginTagEx2 减少了描述良好的元素的样板代码 — 与其分别调用 BeginTagEx 再接 SetStructElemTitle、SetStructElemID 和 SetStructElemExpansion,现在可一次调用设置全部七个属性。该函数在 Delphi 库、ActiveX(Dispid 73008046)和 DLL 接口中提供。
v3.36.1 2026-05-20
- GetPDFUADiagnostics 现在会在 N 个 TH(表头单元格)结构元素缺少 Scope 属性时报告 TABLE-TH-NO-SCOPE:N。ISO 32000-1 §14.8.4.3.4 Table 337 将 Scope(Row、Column 或 Both)定义为描述某个表头单元格作用于哪些数据单元格的属性。缺少该属性时,屏幕阅读器和其他辅助技术无法在复杂或多层表头表格中可靠地把表头单元格与数据单元格关联起来,而这正是 ISO 14289-1 §7.5 所要求的。在标记每个 TH 元素后立即调用 SetStructElemAttr('Table','Scope', 'Column')(或 'Row' / 'Both')。
v3.36.0 2026-05-20
- SetStructElemExpansion 是新增 API,在当前打开的结构元素上设置 /E(展开文本)项(ISO 32000-1 §14.9.5)。展开文本是元素内缩写或首字母缩略词的完整拼写形式 — 例如 Span 文本为 "WWW" 时展开为 "World Wide Web"。屏幕阅读器会朗读展开文本而非尝试逐字符发音,这对技术与科学内容的无障碍性至关重要。PDF/UA-1(ISO 14289-1 §7.2)要求自然语言可被明确识别;/E 是处理缩写和首字母缩略词的标准机制。该函数在 Delphi 库、ActiveX 和 DLL 接口中提供。
v3.35.1 2026-05-20
- GetPDFUADiagnostics 现在会在文档信息字典 /Title 项缺失或为空时报告 DOCINFO-TITLE-MISSING。PDF/UA-1(ISO 14289-1)要求文档具备标题,以便文档打开时屏幕阅读器能朗读。既有的 DISPLAYDOCTITLE-FALSE 检查确认 viewer 标题栏显示该标题;DOCINFO-TITLE-MISSING 是互补检查 — 它确认标题值本身已设置。通过调用 SetDocumentInfo('Title', ...) 提供该值。
v3.35.0 2026-05-20
- SetStructElemTitle 是新增 API,在当前打开的结构元素上设置 /T(标题)项(ISO 32000-1 §14.7.2 Table 324)。该标题是标识具体元素实例的人类可读标签 — 例如 "Chapter 1"、"Summary Table" 或 "Figure 3: Quarterly Sales" — 显示在 PDF viewer 的 Tags 导航面板中,并被无障碍修复工具使用。/T 不同于 /Alt(面向视力障碍用户的替代文本)和 /ActualText(字形级文本校正);它在 Table、Figure、Form、Sect、Div 等非文本容器元素上最为实用。传入空字符串以清空已设置的值。该函数在 Delphi 库、ActiveX 和 DLL 接口中提供。
v3.34.0 2026-05-20
- SetStructElemAltText 是新增 API,在当前打开的结构元素上设置 /Alt 项(ISO 32000-1 §14.9.3)。它等价于在 BeginTag 中传入 AltText,但允许在元素打开后设置或更新替代文本描述 — 当描述与元素类型分开计算时很有用。PDF/UA-1(ISO 14289-1 §7.5)要求 Figure 和 Formula 元素携带 Alt 文本;GetPDFUADiagnostics 已经会针对缺失值报告 FIGURE-NO-ALT:N。该函数在 Delphi 库、ActiveX 和 DLL 接口中提供。
v3.33.1 2026-05-20
- GetPDFUADiagnostics 现在包含 ROLEMAP-UNMAPPED:N 检查,用于检测文档中使用但未在 /RoleMap 字典中映射的自定义结构元素类型名。ISO 14289-1 §7.1 与 ISO 32000-1 §14.7.3 要求每个非标准结构类型必须映射到一个标准 PDF 类型(如 P、Span 或 Figure),以便辅助技术能够判断如何处理该元素。发现 N 个未映射类型时,问题描述包含类型名列表,便于调用方知道需要哪些 AddRoleMap 条目。ISO 32000-1 Table 333(PDF 1.7)定义的全部 49 种标准结构类型都会被识别并从报告中排除。
v3.33.0 2026-05-20
- SetStructElemLang 是新增 API,在当前打开的结构元素上设置 /Lang 项(ISO 32000-1 §14.9.2)。该语言标签覆盖 SetDocumentLanguage 或 SetPDFUAMode 声明的文档级语言,对该元素及其所有后代生效,使混合语言文档能为每段标记其正确的 BCP 47 语言标签(例如 'en-US'、'fr'、'zh-Hant-TW')。屏幕阅读器使用元素级 /Lang 来选择合适的文本到语音引擎或朗读语音。该函数在 Delphi 库、ActiveX 和 DLL 接口中提供。
v3.32.0 2026-05-20
- SetStructElemActualText 是新增 API,在当前打开的结构元素上设置 /ActualText 项(ISO 32000-1 §14.9.4)。当内容流提取会得到错误结果时,用它指定字形序列实际代表的精确 Unicode 文本 — 最常见的情况是 OpenType 连字字形(U+FB00 ff、U+FB01 fi、U+FB02 fl)以及展开形式不明显的缩写。ActualText 补充而非替换渲染内容;它会覆盖该元素对辅助技术与文本提取器的朗读/输出,但不会抑制可视渲染。该函数在 Delphi 库、ActiveX 和 DLL 接口中提供。
v3.31.1 2026-05-20
- GetPDFUADiagnostics 现在在报告缺少 Alt 文本(FIGURE-NO-ALT:N)时除 Figure 元素外也检查 Formula 结构元素。ISO 32000-1 §14.9.3 要求图形 Figure 和数学公式都需提供替代描述;此前只扫描 Figure 元素。
- GetPDFUADiagnostics 现在会在文档 PDF 版本低于 1.7 时报告 PDF-VERSION-LOW。PDF/UA-1(ISO 14289-1)定义在 PDF 1.7(ISO 32000-1:2008)之上;PDF 1.5 或 1.6 文档无法满足基础规范要求。调用 SetPDFUAMode 可自动将版本提升至 1.7。
v3.31.0 2026-05-19
- 现已支持结构元素 ID 与表头单元格关联。SetStructElemID 为当前打开的结构元素赋予一个唯一字符串标识(/ID);保存文档时 ID 会收集到结构树根的 /IDTree 名字树中,使无障碍工具与交叉引用能按 ID 定位元素(ISO 32000-1 §14.7.4)。SetStructElemHeaders 通过一个以逗号分隔的已分配 ID 列表把当前表格单元格(TD 或 TH)与一个或多个表头单元格关联起来,在 Table 属性 owner 字典中写入 /Headers 数组(ISO 32000-1 §14.8.5.7.2)。这两个函数共同支持 PDF/UA-1(ISO 14289-1 §7.10)和 WCAG 2.x SC 1.3.1 所需的复杂表格标记。两个函数都在 Delphi 库、ActiveX 和 DLL 接口中提供。AddTagAttribute 现在也能正确处理 /Headers 属性,将逗号分隔的值写为 PDF 文本字符串数组。
v3.30.1 2026-05-19
- GetPDFUADiagnostics 现在包含 HEADING-LEVEL-SKIP:N 检查,用于检测文档顺序中的标题级别跳跃(例如 H1 后紧跟 H3 而中间没有 H2)。该检查对整棵结构元素树执行前序遍历,并统计下一个标题级别比前一个高出超过一级的每个位置。通用 H 元素按 H1 处理。回到更高级别标题(H3 → H1)不算作跳跃。WCAG 2.x 成功准则 1.3.1 与 ISO 14289-1 §7.1 要求标题嵌套不出现缺口。
v3.30.0 2026-05-19
- 结构元素属性现已支持标签化 PDF 与 PDF/UA 文档。三个新 API 函数允许将属性挂到当前正在 tag 栈上构建的结构元素:AddTagAttribute(通用,任意 owner/name/value)、SetStructElemScope(便捷封装,将 /Scope 属性设置在 Table owner 下,用于 TH 表头单元格 — ISO 32000-1 §14.8.5.7.2)以及 SetStructElemBBox(便捷封装,将 /BBox 属性设置在 Layout owner 下,用于 figure 等视觉定位元素 — ISO 32000-1 §14.8.5.4)。保存文档时,属性被写为每个结构元素中的 /A 属性字典;同一 owner 的多个属性归为同一字典,不同 owner 的属性写为字典数组。三个函数都在 Delphi 库、ActiveX 和 DLL 接口中提供。
v3.29.1 2026-05-19
- GetPDFUADiagnostics 现在包含两项额外检查:是否有 Figure 结构元素缺少 Alt 文本值(报告为 FIGURE-NO-ALT:N,依据 ISO 14289-1 §7.5 和 ISO 32000-1 §14.9.3),以及是否有结构元素因 EndTag 未被调用而仍处于打开状态(报告为 STRUCT-UNCLOSED:N)。figure 检查对结构元素树进行完整递归遍历,覆盖所有嵌套深度的元素。
v3.29.0 2026-05-19
- GetPDFUADiagnostics 是新增的诊断 API,对文档执行 PDF/UA-1(ISO 14289-1)合规性潜在问题检查,返回以换行分隔的发现列表。共执行六项检查:MarkInfo/Marked 是否设置(标签化 PDF)、文档目录是否有 /Lang 项、ViewerPreferences/DisplayDocTitle 是否为 true、XMP 元数据是否含 pdfuaid:part 标识、缺少 Contents 项的非豁免注解数量,以及缺少 AFRelationship 项的嵌入文件数量。每个发现以简短代码(如 LANG-MISSING、ANNOT-NO-CONTENTS:3)加人类可读描述呈现。未发现问题时返回空字符串。在 Delphi 库、ActiveX 和 DLL 接口中提供。
v3.28.5 2026-05-19
- PDF/UA-1 注解无障碍改进:当 FileAttachment 注解没有 Contents 项且没有 /T 字段时,现在使用注解内嵌文件规范(/FS /UF 或 /F)中的文件名作为回退的无障碍描述。这就完整了注解 Contents 回退链:/T → Link URI → Stamp name → FileAttachment filename。屏幕阅读器会读出附件文件名而非静默,满足 ISO 14289-1 §7.18.1 对最常见注解类型的要求。
v3.28.4 2026-05-19
- PDF/UA-1 注解无障碍改进:当 Stamp 注解没有 Contents 项(或为空)且没有 /T 字段时,现在使用注解 /Name 项中的图章类型名作为回退的无障碍描述(例如 "Approved"、"Draft"、"Confidential"、"Final")。这将 v3.28.3 引入的注解 Contents 回退链扩展到图章注解,后者常见于审阅或批准工作流,往往缺少明确的 Contents 值。
v3.28.3 2026-05-19
- PDF/UA-1 注解无障碍改进:当 Link 注解没有 Contents 项(或为空)且没有 /T 字段时,现在使用注解 URI 动作中的 URI 作为回退的无障碍描述。该回退仅在 SetPDFUAMode 处理过程中、且仅针对携带 /URI 动作的 Link 注解生效。屏幕阅读器收到 URL 作为兜底标签,满足 ISO 14289-1 §7.18.1 在作者创建超链接时未提供人类可读描述的常见情景。
v3.28.2 2026-05-19
- SetEmbeddedFileAFRelationship 是新增 API,用于在嵌入文件的文件规范字典上显式设置 AFRelationship 值。ISO 14289-1(PDF/UA-1)§7.11 要求该字段,允许调用方从五个有效值中选择嵌入文件与文档内容的语义关系:Source、Data、Alternative、Supplement 或 Unspecified。当 SetPDFUAMode 激活时,任何缺少 AFRelationship 项的嵌入文件会被自动赋值 Unspecified;用此函数可在保存前覆盖该默认值。在 Delphi 库、ActiveX 和 DLL 接口中提供。
v3.28.1 2026-05-19
- 当 SetPDFUAMode 在 XMP 元数据携带通用库默认标题(而非文档特定标题)的文档上被调用时,标题会自动替换为文档 /Info Title 项的值(若存在)。这确保 pdfuaid:part-1 XMP 包反映实际文档标题而非占位符,满足 PDF/UA-1 校验器的预期。
- XMP 解析器(LoadFromString)现在加载文档时会从既有 XMP 元数据中读取 dc:title 值,所以已含 dc:title 的 PDF 进行回环往返时能正确保留该标题,而不再回退到默认占位符。
v3.28.0 2026-05-19
- BeginArtifactEx(ArtifactType, ArtifactSubtype) 是新增的标签化 PDF API,扩展了 BeginArtifact,在单次调用中同时表达 artifact /Type 和 Pagination /Subtype。当两个参数都非空时,写出的操作符为 /Artifact << /Type /T /Subtype /S >> BMC,按 ISO 32000-1 §14.8.2.2.1 启用完整指定的 Pagination artifact,例如页眉与页脚。如果只有一个参数非空,则使用对应的单键形式。同时导出 DLL 入口点 DLBeginArtifactEx 和 DLBeginArtifactExA。
v3.27.2 2026-05-19
- BeginArtifact 现在能正确区分 artifact 类型与 pagination 子类型。当参数为 Pagination、Layout 或 Page(按 ISO 32000-1 §14.8.2.2.1 Table 330 属于 artifact 类型)时,marked-content 操作符写入 /Type 而不是 /Subtype。Header、Footer、Watermark 等其他值继续写为 /Subtype。这修正了之前调用方意图标记 pagination artifact 却被错误写为 /Subtype /Pagination 的输出。
v3.27.1 2026-05-19
- 当 PDF/UA 模式激活且文档含嵌入文件时,每个缺少 AFRelationship 项的文件规范字典在保存时会自动获得该项。写入的值为 /Unspecified,满足 ISO 14289-1 §7.11 要求每个嵌入文件都携带 AFRelationship 键的规定。该自动补全既适用于通过 EmbedFile 添加的文件,也适用于已加载文档中既有的嵌入文件。
v3.27.0 2026-05-19
- AddRoleMap(CustomType, StandardType) 是新增的标签化 PDF API,用于注册一个从自定义(非标准)结构元素类型名到标准 PDF 结构类型的映射。保存时这些映射写入结构树根的 RoleMap 字典,满足 ISO 14289-1 §7.1 对使用应用特定 tag 名的文档的要求。可注册多个映射;重复键会被最后一次调用覆盖。同时导出 DLL 入口点 DLAddRoleMap 和 DLAddRoleMapA。
v3.26.0 2026-05-19
- BeginTagEx(TagType, AltText, ActualText, Lang) 是新增的标签化 PDF API,扩展 BeginTag,新增一个显式自然语言属性。当 Lang 非空时,它会被写入结构元素的 /Lang 属性,启用 ISO 14289-1 §7.2 多语言文档所需的元素级语言标注。传入空 Lang 字符串等效于 BeginTag。同时导出 DLL 入口点 DLBeginTagEx 和 DLBeginTagExA。
v3.25.1 2026-05-19
- 以默认 Windows 代码页(WinAnsiEncoding)加载的非子集化 TrueType 字体现在会写入 ToUnicode CMap 流,为这些字体启用可靠的 Unicode 文本提取与复制粘贴。此前只在显式覆盖代码页或存在 Differences 数组时才写 ToUnicode 流;常见的默认编码路径缺少该流。
- 同样的修复也适用于以显式非默认代码页加载且不带 Differences 数组的 TrueType 字体,以及通过 packaged-font 格式加载的字体。
v3.25.0 2026-05-19
- 当 PDF/UA 模式激活时,所有缺少非空 Contents 项的非豁免注解(除 Widget、PrinterMark 和 TrapNet 外的全部类型)会在保存时自动获得该项。注解的 /T(标题 / 作者)值作为回退使用,满足 ISO 14289-1 §7.18.1 对携带标题但没有明确无障碍描述的注解的要求。
v3.24.0 2026-05-19
- 当 PDF/UA 模式激活时,所有缺少 TU(工具提示 / 替代描述)项的交互表单字段会在保存时自动获得该项。字段的部分名(/T 项)作为回退值,确保屏幕阅读器能识别每个字段。按 ISO 14289-1 §7.18.4,下压按钮被正确排除在该要求之外。
v3.23.1 2026-05-19
- 当所选文档启用了 PDF/UA-1 模式时,GetInformation(200) 返回 '1',使调用方能在运行时查询一致性模式状态。
- GetInformation(201) 在 PDF/A-1a 时返回 '1',PDF/A-1b 时返回 '2',PDF/A 模式关闭时返回空字符串。
- GetInformation(311) 和 GetInformation(312) 现在能正确返回最近一次版本锁定冲突的版本要求字符串与功能名(先前已在 v3.20.3 公布但尚未实现)。
- GetInformation(313) 返回保存目标当前锁定的 PDF 版本字符串,对于版本自由的文档返回空字符串。
v3.23.0 2026-05-19
- SetMarkInfo(Marked) 现已成为公共 API,允许独立于 SetPDFUAMode 执行的完整 PDF/UA-1 设置之外单独设置 MarkInfo.Marked 标志。当 Marked 为 1 时,按 ISO 14289-1 §7.18.6 要求,MarkInfo.Suspects 也会被设为 false。
- 当 PDF/UA 模式激活时,所有页面在保存时自动获得 /Tabs /S 项,满足 ISO 14289-1 §7.18.4 的基于结构的 tab 顺序要求。
- 为 SetPDFUAMode、SetDocumentLanguage、SetMarkInfo、BeginTag、EndTag、BeginArtifact、EndArtifact 新增 HTML 参考文档,包含完整语法表与使用示例。
v3.22.0 2026-05-19
- BeginTag(TagType, AltText, ActualText) 在当前内容流中打开一个标签化 PDF 结构元素,写出一个 BDC 操作符并自动分配 MCID,同时将该元素注册到文档结构树。TagType 是任意 PDF 标准结构类型(P、H1、Figure、Table 等)。AltText 和 ActualText 是可选的无障碍字符串,编码为 PDF 文本字符串(UTF-16BE)。
- EndTag 关闭最近打开的结构元素,向内容流写出对应的 EMC 操作符。
- BeginArtifact(SubType) 将一段内容标记为 PDF artifact(pagination artifact、背景等),写出 BMC 操作符。SubType 是可选的;提供时写为 /Artifact << /Subtype /SubType >>。
- EndArtifact 用 EMC 操作符关闭 artifact 区域。
- 保存时,当注册了任意标签化结构元素后,库会自动构建完整的 StructTreeRoot、为受影响页面分配 StructParents 键、写入 ParentTree 数字树,满足 ISO 32000-1 §14.7 对标签化 PDF 的要求。
- 标准 Type 1 字体(Helvetica、Times、Courier 家族、Symbol)和采用 WinAnsi 编码的嵌入 Type 1 字体现在会写入 ToUnicode CMap 流,为这些字体类型启用可靠的 Unicode 文本提取与复制粘贴。
v3.21.0 2026-05-19
- SetPDFUAMode(Language) 激活 PDF/UA-1(ISO 14289-1)一致性模式:自动 bump 文档到 PDF 1.7,写入 MarkInfo.Marked 与 MarkInfo.Suspects,在 ViewerPreferences 中启用 DisplayDocTitle,当 Language 非空时设置 Catalog.Lang,并写入 ISO 14289-1 第 6.7.11 节要求的 pdfuaid:part = 1 XMP 命名空间项。
- SetDocumentLanguage(Language) 直接写入 Catalog /Lang 项,允许独立于 PDF/UA 模式声明文档语言。
- 每当 MarkInfo.Marked 被设为 true 时,MarkInfo.Suspects 都会被设为 false,满足 ISO 14289-1 标签化 PDF 结构要求(第 7.18.6 节)。
- Encrypt 现在在文档处于 PDF/UA 模式时强制启用 CanCopyAccess(无障碍内容复制)权限标志,按 ISO 14289-1 第 7.17 节要求。
- Choice(下拉)表单字段不再携带无意义的硬编码 tooltip 值;TU 保持未设置,便于调用方通过表单字段属性 API 赋予有意义的标签。
v3.20.3 2026-05-19
- Encrypt 和 AddSWFAnnotationFromFile 现在在保存版本被锁定到所选加密强度或注解类型所需最低版本以下时,立即返回 0 并设置 LastErrorCode 602,而不再静默继续直到保存时才失败。
- GetInformation(311) 与 GetInformation(312) 现在能在写时反映冲突的版本要求,当锁定版本阻止扩展级功能(如 AES-256 或 RichMedia 注解)时。
v3.20.2 2026-05-19
- AddU3DAnnotationFromFile 现在在向更低版本文档添加 3D 注解时会将文档版本自动 bump 到 PDF 1.6,与其他所有 PDF 1.6+ API 入口点的版本自动 bump 行为保持一致。
v3.20.1 2026-05-17
- PDF 1.2 保存目标现在按严格 PDF 1.2 契约执行。在 PDF 1.2 目标下保存 PDF 1.3+ 对象(如页面 TrimBox 数据)会在输出写入前失败,而不再写出混版文件。
- PDF 1.7 Adobe 扩展级合规性现已纳入保存预检。AESV3、AES-256、RichMedia、Projection、地理空间字典和 ETSI 签名 subfilter 都按所需 ExtensionLevel 进行检查。
- AES-256 加密、RichMedia 注解、地理空间字典和 ETSI 签名 subfilter 现在在 PDFlib 把文档自动 bump 到 PDF 1.7 扩展内容时声明匹配的 Adobe Extensions 项。
- Append 保存现在使用与全量保存相同的版本合规门。
- 为 Win32 和 Win64 刷新了可选 PDFium 运行时 DLL。GDI+ 仍是默认渲染器;PDFium 通过 SetPDFiumFileName 与 SelectRenderer(3) 保持 opt-in。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 207/207,C++Builder Win64x GoogleTest 通过 61 个测试,2 个已存在的样本依赖测试被跳过。
v3.20.0 2026-05-17
- 另外八个 PDFlib writer 入口点现在经过 Phase 3 EnsureMinVersion 路由,使文档版本自动 bump 到所 emit 功能要求的最低版本:SetDocumentMetadata(PDF 1.4 - /Metadata XMP 流)SetPDFAMode(1 或 2)(PDF 1.4 - /MarkInfo + /OutputIntents)PageJavaScriptAction(PDF 1.5 - Page /AA + JavaScript)DocJavaScriptAction(PDF 1.4 - Catalog /AA + JavaScript)SetTabOrderMode(PDF 1.5 - Page /Tabs)NewOptionalContentGroup(PDF 1.5 - /Type /OCG)SetNeedAppearances(PDF 1.5 - AcroForm /NeedAppearances)NewFormField(ftSignature)(PDF 1.5 - AcroForm /SigFlags AppendOnly)
- 结合 v3.15.0 集合(SetTransparency、SetPageUserUnit、Encrypt、SetPageLayout)与 v3.17.0 集合(JavaScript / 嵌入文件 / XFA / SWF 八项),PDFlib 现已在二十一个 writer 入口点上自动 bump FVersion。
- NewOptionalContentGroup 此前直接 bump FVersion;现在改为经过 EnsureMinVersion,使 LockSaveVersion 被尊重,并将 bump 记录到 AutoBumpedFeatures 中。
v3.19.0 2026-05-17
- 保存时与加载时 PDF 版本合规性现在还识别四个此前延迟的功能:Btn /Ff 位 15 NoToggleToOff(仅 radio-button)-> PDF 1.4;DeviceN /Subtype /NChannel(色彩空间细化)-> PDF 1.6;FontFile3 /Subtype /OpenType(字体程序类型)-> PDF 1.6;Sig /SubFilter ETSI.CAdES.detached 或 ETSI.RFC3161 -> PDF 1.7。
- NChannel 规则匹配 DeviceN 色彩空间数组形式 [/DeviceN names alternateSpace tintTransform attributes],当 attributes 字典(索引 4)携带 /Subtype /NChannel 时触发。
- FontFile3 OpenType 规则只在通过名为 'FontFile3' 的父键到达 stream 时触发,因此其他恰好携带 /Subtype /OpenType 的无关 stream 不会被标记。
- PDFFeatureRules 表现在含 103 条规则(99 + 4 条新增)。
v3.18.6 2026-05-17
- 保存时与加载时 PDF 版本合规性现在识别 /AA(附加动作)并具备容器类型感知:Catalog /AA(文档级触发器)-> PDF 1.4;Annot /AA(注解触发器)-> PDF 1.4;Page /AA(页面触发器)-> PDF 1.5。
- 表单字段 /AA(PDF 1.2)仍由既有 PDF 1.3 保存契约覆盖;无需新规则。
- PDFFeatureRules 表现在含 99 条规则(96 + 3 条新增)。
v3.18.5 2026-05-17
- 保存时与加载时 PDF 版本合规性现在将 Page /Tabs 正确归类为 PDF 1.5 功能;此前被误归为 PDF 1.4。PDF 1.4 spec 变更文档(Adobe TN #5409)未列出 /Tabs,PDF 1.5 Table 8.10 引入 "Tabs (Optional; PDF 1.5)"。
- 新规则:AcroForm /NeedAppearances 按 PDF 1.5 Table 218 被识别为 PDF 1.5 功能。
- PDFFeatureRules 表现在含 96 条规则(95 + 1 条新增)。
v3.18.4 2026-05-13
- PDFlibZLib 在常规库构建中始终使用打包的静态 zlib-ng obj 后端,移除了余下的 System.ZLib 回退路径。
- zlib-ng 回归覆盖现在包含边界尺寸 payload、PNG 类扫描线数据、stored 多块流以及已知的 zlib 流,覆盖 Delphi 与 C++Builder 测试 runner。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 194/194,C++Builder Win64x GoogleTest 通过 58 个测试,2 个已存在的样本依赖测试被跳过。
v3.18.3 2026-05-12
- 生成 PDF 或文本输出的 Delphi 与 C++Builder demo 现在在成功保存后自动打开生成的文档。
- Installer 打包现在把构建产物排除在 demo 目录之外,并将 C++Builder 样例以及 DLL、ActiveX/OCX 模块变为 opt-in 组件;只有在选择对应组件时才会安装匹配文件。
v3.18.2 2026-05-12
- Delphi 与 C++Builder 的 EditFormField demo 现在在更新字段值前清除 /NeedAppearances,使每个被编辑过的文本字段在保存的 PDF 中获得刷新过的 normal appearance stream。
- 这能让保存的 /AP 流与存储的 /V 值保持同步,避免不同 viewer 在聚焦字段时显示静态外观流缺失的文本。
v3.18.1 2026-05-10
- 保存时与加载时 PDF 版本合规性现在也识别位级表单字段 /Ff 标志以及 AcroForm /SigFlags AppendOnly 位:/Ff 位 21(FileSelect, mask 1048576)-> PDF 1.4;/Ff 位 22(MultiSelect, mask 2097152)-> PDF 1.4;/Ff 位 23(DoNotSpellCheck, mask 4194304)-> PDF 1.4;/Ff 位 24(DoNotScroll, mask 8388608)-> PDF 1.4;/Ff 位 25(Comb, mask 16777216)-> PDF 1.5;/Ff 位 26(RichText / RadiosInUnison, 33554432)-> PDF 1.5;/Ff 位 27(CommitOnSelChange, mask 67108864)-> PDF 1.5;/SigFlags 位 2(AppendOnly, mask 2)-> PDF 1.5。
- /Parent 继承不被跟踪:只有显式携带 /Ff 或 /SigFlags 的字典才触发规则。
- PDFFeatureRules 表现在含 95 条规则(87 + 8 条新增位级规则)。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 191/191,C++Builder Win64x GoogleTest 通过 57/57。
v3.18.0 2026-05-10
- 保存时与加载时 PDF 版本合规性现在还识别九项更多子键与位级功能:位级注解标志(/F mask):Locked (128) -> PDF 1.4;ToggleNoView (256) -> PDF 1.5;LockedContents (512) -> PDF 1.7;具有区分度的目录与页面子键:/BoxColorInfo(页面)-> PDF 1.4;/Permissions、/Legal、/PresSteps -> PDF 1.5;/VP(页面 geospatial viewport)-> PDF 1.6;/Collection(目录可移植集合)-> PDF 1.7。
- PDFFeatureRules 表现在含 87 条规则(78 章级 + 9 子键 / 位级)。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 189/189,C++Builder Win64x GoogleTest 通过 57/57。
v3.17.0 2026-05-10
- 另外八个 PDFlib writer 入口点现在经过 Phase 3 EnsureMinVersion 路由,使文档版本自动 bump 到所 emit 功能要求的最低版本:AddLinkToJavaScript、SetOpenActionJavaScript、AddGlobalJavaScript、FormFieldJavaScriptAction(PDF 1.3 - JavaScript 动作);AddEmbeddedFile、AddFileAttachment(PDF 1.3 - 文件附件);SetXFAFromString(PDF 1.5 - XFA 表单);AddSWFAnnotationFromFile(PDF 1.7 - RichMedia 注解)。
- 结合 v3.15.0 集合(SetTransparency、SetPageUserUnit、Encrypt、SetPageLayout),PDFlib 现已端到端覆盖十三个高版本 writer 入口点。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 187/187,C++Builder Win64x GoogleTest 通过 57/57。
v3.16.3 2026-05-10
- 新 PDFlib API:LockSaveVersion(Version) 将文档钉在 Version,并阻止 Phase 3 writer 端 EnsureMinVersion 把版本自动 bump 到该值之上。UnlockSaveVersion 清除该锁定。
- 保存时的合规门不变:高于锁定版本的 writer 所 emit 功能在保存时仍会触发 LastErrorCode 602,而不会静默 bump 文件头。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 184/184,C++Builder Win64x GoogleTest 通过 57/57。
v3.16.2 2026-05-10
- 加载的 PDF 现在通过 GetInformation(103)("ContributorFeatures")暴露一个仅显示贡献者特征的视图。列表只包含其最低所需版本严格高于 HeaderVersion(键 100)的功能,因此直接回答 "为什么有效版本高于文件头版本?" 这个问题。
- GetInformation(101)("DetectedFeatures")保持不变,仍列出每一个匹配的功能,无论是否对版本提升做出贡献。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 181/181,C++Builder Win64x GoogleTest 通过 57/57。
v3.16.1 2026-05-10
- 扩展了加载端检测的测试覆盖,新增六个合成 fixture:页面内透明度 ExtGState(不 bump 版本)、Catalog /MarkInfo(PDF 1.3 -> PDF 1.4)、/OCProperties + OCG 内容(PDF 1.4 -> PDF 1.5)、/Type /3DStream(PDF 1.5 -> PDF 1.6)、多功能组合 fixture,以及快照稳定性检查。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 179/179,C++Builder Win64x GoogleTest 通过 57/57。
v3.16.0 2026-05-10
- 加载的 PDF 文档现在会经过内容驱动的版本检测过程:每个间接对象都通过保存时合规门所用的功能-最低版本表进行遍历,当内容实际要求更高版本时,FVersion 会被 bump 到高于字面 %PDF-X.Y 头部值的水平。例如某个 /UserUnit 页面项会把有效版本 bump 到 PDF 1.6,即使文件头说 PDF 1.4。
- 新增 GetInformation 键:100 返回 HeaderVersion(字面 %PDF-X.Y),101 返回 DetectedFeatures(加载时匹配的功能,CRLF 分隔),102 返回 AutoBumpedFeatures(触发 writer 端 EnsureMinVersion 的功能,CRLF 分隔)。
- 保存时合规门不受影响:在加载时被 bump 了有效版本、随后通过 SetInformation(0, ...) 显式降级的文档,保存时仍会触发 LastErrorCode 602。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 173/173,C++Builder Win64x GoogleTest 通过 57/57。
v3.15.0 2026-05-10
- 生成需要特定最低 PDF 版本功能的 writer 入口点现在会自动 bump 文档的 PDF 版本。对一个标记为 PDF 1.3 的文档调用 SetTransparency 现在会把头部提升到 PDF 1.4,而不是用 LastErrorCode 602 让保存失败。
- 同样的自动 bump 已接入 SetPageUserUnit(>=1.6)、Encrypt 配 Strength 1/2/3/4(分别 >=1.4/1.6/1.7/1.7)以及 SetPageLayout 的两页变体(>=1.5)。
- 行为变化对比 3.14.x:此前依赖 v3.12.6 "保存目标拒绝 writer 所 emit 功能" 门的应用程序现在会在 bump 后的版本下成功保存。已包含更高版本功能的已加载 PDF 仍会经过既有保存时合规门,所以加载一份标签化 PDF 后选择 PDF 1.3 仍会以 LastErrorCode 602 失败。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 170/170,C++Builder Win64x GoogleTest 通过 57/57。
v3.14.3 2026-05-10
- 保存时 PDF 版本合规性现在还识别其余 PDF 1.6 3D 字典类型(/Type /3DStream /3DRef /3DBackground /3DRenderMode /3DLightingScheme /3DCrossSection /3DNode)以及 PDF 1.7 的 Redact、RichMedia、Projection 注解子类型加上 /Type /Requirement 与 /ReqHandler 配套字典。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 168/168,C++Builder Win64x GoogleTest 通过 57/57。
v3.14.2 2026-05-10
- 保存时 PDF 版本合规性现在还识别 PDF 1.5 功能:/XFA 表单、/AlternatePresentations、/Renditions 名字树、/Type /Rendition /MediaCriteria /MediaPermissions /MediaPlayers 多媒体字典以及 Screen 注解子类型。
- 以 PDF 1.4 保存现在会用 LastErrorCode 602 拒绝携带这些功能的文档。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 166/166,C++Builder Win64x GoogleTest 通过 57/57。
v3.14.1 2026-05-10
- 保存时 PDF 版本合规性现在还识别 PDF 1.4 功能:标签化 PDF /StructTreeRoot /MarkInfo 与 StructElem 字典、文档 /Lang 与页面 /Tabs 项、/OutputIntents 与 /OutputIntent 字典、/UR3 使用权签名以及 PDF 1.4 的注解子类型 Polygon、PolyLine、Caret、Ink、Popup 和 Watermark。
- 以 PDF 1.3 保存现在会用 LastErrorCode 602 拒绝携带这些功能的文档。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 165/165,C++Builder Win64x GoogleTest 通过 57/57。
v3.14.0 2026-05-10
- 保存时 PDF 版本合规性现在还识别 PDF 1.3 功能,例如平滑着色、function 对象、ICCBased 和 DeviceN 色彩空间、/TrimBox /BleedBox /ArtBox 页面项、/ToUnicode CMaps、文件附件以及 /Sound 和 /Movie 注解、/Type /Filespec 与 /Type /EmbeddedFile 字典、/Group /EF /Alternates /Mask 键,以及 JavaScript 动作。
- PDF 1.2 调用方现在在 PDF 1.3 契约下保存:字面 %PDF-1.2 头部被保留,但门会接受 PDF 1.3 功能。PDF 1.4 及以后的功能仍会以 LastErrorCode 602 被拒绝。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 162/162,C++Builder Win64x GoogleTest 通过 57/57。
v3.13.0 2026-05-10
- 把保存时拒绝高版本功能的 PDF 版本合规门重构到独立模块中,使规则集可以扩展而不会扰动文档核心。
- 对比 v3.12.7,无用户可感知的行为变化:同一批越版本功能仍会被以 LastErrorCode 602 拒绝。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 155/155,C++Builder Win64x GoogleTest 通过 57/57。
v3.12.7 2026-05-09
- 扩展了 Delphi DUnitX 与 C++Builder GoogleTest 套件中 PdfToImage 直接访问渲染工作流的自动化测试覆盖。
- Delphi VCL GUI 测试 runner 现在注册了 Syntax 和 XRef fixture,与控制台 runner 的覆盖一致。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 147/147,C++Builder Win64x GoogleTest 通过 57/57。
v3.12.6 2026-05-09
- 以 PDF 1.3、1.4、1.5、1.6 或 1.7 保存现在会将所选版本作为完整保存输出契约执行。
- 完整保存会移除目录 /Version 覆盖项、移除较低目标不支持的目录扩展与元数据项,并在以 PDF 1.3 保存时抑制 PDF 1.4 XMP 元数据流。
- SaveToFile、SaveToString 和 SaveToStream 现在在所选 PDF 目标版本低于文档中仍存在的功能(如透明度、可选内容、JPX、UserUnit、3D 或 AES 加密过滤器功能)时,以 LastErrorCode 602 失败。
v3.12.5 2026-05-09
- 改进 PDF 1.7 字面字符串解析,使未知转义序列按标准要求忽略反斜杠。
- 字面字符串的八进制转义现在只消费八进制数字,并将紧随其后的非八进制数字保留为普通字符串数据。
- 新增对未知字面字符串转义以及混合八进制/非八进制转义序列的回归测试覆盖。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 141/141。
v3.12.4 2026-05-09
- 改进 PDF 1.7 词法解析,使名字对象正确在右花括号分隔符处停止。
- 修复 SmartAccess 加载 xref 流压缩对象项时,对象流编号大于 PDF 字节长度的情况。
- 新增对右花括号名字分隔符与稀疏压缩对象 xref 流项的回归测试覆盖。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 139/139。
v3.12.3 2026-05-08
- 改进对使用标准安全处理器、含 StrF、StmF、EFF、Identity、None 或 StdCF 风格命名加密过滤器的 PDF 1.7 加密文档的兼容性。
- 元数据流现在在解密、加密以及复制/保存工作流中遵守 EncryptMetadata=false,而不再当成普通流处理。
- 嵌入文件流现在携带 /Type /EmbeddedFile,并在加载或保存加密文档时使用嵌入文件加密过滤器决策路径。
- 外部嵌入文件流现在在 FFilter 升级为 Filter 时同步将 FDecodeParms 升级为 DecodeParms,保留流解码参数。
- 新建的 AES 加密 PDF 现在将加密过滤器 Length 值按位长度写出,与 PDF 1.7 加密过滤器字典契约一致。
- XRef 流的 Prev/XRefStm 值以及较大数值偏移量现在在解析器与 SmartAccess 路径中保持 64 位精度。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 137/137。
v3.12.2 2026-05-08
- 改进 PDF 1.7 流解码兼容性。通用流解码现在把 /DP 视作 DecodeParms 别名、解析间接解码参数数组项,并接受 /AHx 与 /LZW 标准过滤器缩写。
- 大文件 PDF 输出现在通过 64 位格式化路径写入 xref、startxref、linearization 以及数字签名 ByteRange 偏移量,而不再通过 32 位整数 helper 将这些值收窄。
- 已加载文档现在把目录 /Version 项当作有效 PDF 版本(当其比文件头版本更新时)。
- 重写的 xref-stream trailer 在 PDFlibPas 把它们保存为经典 trailer 字典时,不再保留仅流相关的 DecodeParms 键。
- 验证:Delphi Win32 与 Win64 DUnitX 套件各通过 134/134。
v3.12.1 2026-05-06
- 生成的 PDF 打开时第一页会按 viewer 窗口的可用高度调整大小,因此整页能在窗口允许的最大缩放下从上到下完整可见。在文档上配置自定义 OpenAction(SetOpenActionDestination、SetOpenActionMenu、SetOpenActionJavaScript)可覆盖此默认行为。
v3.12.0 2026-05-06
- Windows 静态后端现在包含 libjpeg-turbo 的 Win32 与 Win64 NASM SIMD obj 文件,以及 Win64x zlib-ng 集合的 zlib-ng x86 SIMD 分发 obj 文件。
- 重做 zlib-ng 重建脚本,使 Win64x bcc64x 与诊断 MSVC 构建以每文件特性标志的方式编译通用、SSE2、SSSE3、SSE4.1/SSE4.2、PCLMULQDQ 以及 AVX2 源文件,而不再依赖单一全局编译器开关。
- 为静态 C 库新增 32 字节对齐的 malloc/calloc/realloc/free CRT 桩,并修复 TPDFJPEGImage.Compress,使 jpeg_mem_dest 缓冲区通过分配它们的同一 C free 路径释放。
- 扩展公共验证说明,标明本次发布背后的严格自动化覆盖:库构建、压缩往返、HelloWorld /FlateDecode 输出、JPEG 渲染、图像工作流、字体、表单、安全、签名、打印以及 C++Builder demo 衍生工作流。
v3.11.0 2026-05-05
- 将 Windows Flate 压缩与解压切换到 zlib-compatible 模式下的 zlib-ng。Win32、Delphi Win64 和 C++Builder Win64x 现在链接 Lib\thirdparty\Win32、Lib\thirdparty\Win64 和 Lib\thirdparty\Win64x 中 ABI 匹配的 zlib-ng 静态 obj 集合。
- Win64 路径不再经过 Delphi 的 System.ZLib 单元,因此 PDF 流压缩/解压可以像 32 位构建一样享受 zlib-ng 后端的优化。
- 为 Win64 构建新增一小段 zlib-ng 桥接 obj,让 Pascal 代码保持稳定的 zlib 兼容入口点,而 Delphi 和 C++Builder 各自使用自己的链接器兼容 obj 集合。
- 更新了所有 C++Builder demo 项目以定义 PDFLIB_CPPBUILDER,与 GoogleTest runner 匹配,防止 Win64x demo 链接到 Delphi Win64 的 zlib-ng obj。
v3.10.3 2026-05-01
- 扩展 C++Builder GoogleTest 套件以覆盖 Demo\C++Builder 下的每一个 demo。7 个 fixture 的 phase-1 布局扩展为 15 个 fixture / 52 个 GoogleTest 用例,全部在 Win64x 上通过。新覆盖的 demo:AddFormattedTitle、AddTextImage、AddTrueTypeSubsettedFont、AddWebLink、CanvasText、CaptureToNewSize、CopyPageRanges、CreateWithImage、CreateWithImageToStream、DoInTheStream、DrawWrappedText、EditFormField、EmbeddedFonts、ExtractAnnotAttach、ExtractEmbeddedFonts、ExtractImage、ImageToPdf、ImportEMF、MultiFunction(renderer 切换)、PageOperations、PdfDecrypt、PdfPermission、PrintPDF、TextMeasure、TextPaging。
v3.10.2 2026-05-01
- 在 Tests\C++Builder 下新增 C++Builder GoogleTest runner,通过 C++Builder demo 所用的同一 {$JPHNE} 生成的 HPP 头来运用 Lib\PDFlibrary.pas。第一阶段以 17 个 GoogleTest 用例镜像了七个核心 Delphi 场景(HelloWorld、DrawShapes、CreateTable、PdfEncrypt、ExtractText、PdfSigning、PdfToImage 渲染),全部在 Win64x 上通过。
- 扩展 Delphi DUnitX 套件,增加 Tests.Print 覆盖 PrintPDF 与 ShowPrinterBins demo(默认打印机枚举、自定义打印机设置、打印选项、重定向到文件的打印作业),以及 Tests.Render 中针对 MultiFunction demo 同一源 PDF 的 GDI+ / PDFium / Cairo 引擎选择的渲染器切换测试。
v3.10.1 2026-05-01
- 在 SetPageSize 中新增 57 个命名页面尺寸,使同一组规范页面尺寸名称也可在这里使用:SIZE8X11, QUADA0, DOUBA0, B0PLUS, ENVB4/B5/C6/DL/MONARCH, ENV9/10/11, ANSIA/B/C/D/E, ARCHA/B/C/D/E1/E, SHIROKU, G1K, USBC/EUBC/ASBC, ID1/ID2/ID3, ONEINCH/TWOINCH/L2INCH/USVISA, P2R..P24R / S8R / P4D photo prints, plus the Chinese / Taiwanese octavo and sextodecimo sheet formats LARGE/STANDARD/CROWN/ROC 8K and the matching 16K halves.
v3.10.0 2026-04-30
- 为 Demo 下的每个 Delphi 样例新增 C++Builder 原生版本。PDF 创建、页面操作、字体、图像、安全、签名、渲染与打印 demo 现在都可从 C++Builder 构建并运行,无需任何 Delphi 端封装。
- 每个新 demo 位于 Demo\C++Builder\<Name>\ 下,是一个直接消费 Lib\PDFlibrary.pas 的控制台项目,并附带运行所需的输入文件。
- 为每个 Delphi demo 目录新增简短的英文 Readme.txt,描述该 demo 展示什么、关注哪个 API 以及如何运行;位于 Demo\Delphi\index.html 的 HTML 总览按主题分组链接到所有 demo。
- 为每个 C++Builder demo 镜像同一份 Readme.txt,其 Run 段为控制台工作流重写(用 argv 参数替代 Open/SaveDialogs);位于 Demo\C++Builder\index.html 的对应总览以同样的主题分组列出每个 C++Builder demo。
- 修复 ImportEMF demo 的内存泄漏(TPDFlib 实例被创建但未释放)。
v3.9.14 2026-04-30
- 修复页面范围复制 demo,使其真正复制页面而不是总是报告失败。
- 整理换行文本与 HTML 分页 demo,使每个 demo 专注于自己的 API 并通过单一按钮运行。
- 重命名两个 demo 项目(EmbeddedFonts 与 PdfPermission),使编译出的可执行文件与文件夹名匹配,而不是早期的原型名。
v3.9.13 2026-04-30
- 修复内部缓冲区 reader 的流位置 bug:两字节字读取原本把读取游标推进了四字节而不是两字节。在长度超过两字节的缓冲区中,后续读取会落到错误的偏移并静默返回错误数据。该影响在解析交错字节与字读取的二进制数据结构时最明显。
- 引入自动化 DUnitX 测试套件(控制台与 VCL GUI runner),覆盖工具单元(buffer、AES、ZLib、Unicode、摘要哈希)以及库级工作流,包括文档创建、保存到文件与保存到流、加载回环以及 AES-128/AES-256 加密。
v3.9.12 2026-04-30
- GDI+ 图像渲染现在在把光栅图像缩放到屏幕或导出分辨率时默认使用平滑、高质量的双三次插值。此前默认为最近邻,会在屏幕预览或高 DPI 导出中放大小图像(logo、缩略图)时产生明显的台阶状伪影。偏好更锐利的最近邻模式的调用方可通过 SetGDIPlusOptions 恢复旧行为。
v3.9.11 2026-04-30
- 修复 Cairo 渲染中使用颜色键透明度(图像字典中的 /Mask 颜色范围数组)的 PDF 图像。此前当页面包含该形式透明度的图像时,Cairo 渲染器会完全省略该图像,而不是把它合成到页面背景上。修复后会按声明的颜色键范围派生逐像素 alpha 通道,并以透明图像渲染,输出在视觉上与 GDI+ 渲染器一致。
v3.9.10 2026-04-30
- 修复 Cairo 渲染回归:所有跟在被裁剪图像序列之后的页面内容都被错误地限制在图像的裁剪矩形内。保存 graphics state、应用 clip path、绘制图像、然后恢复 state — 这是带框或带边框图像的常见布局技术 — 这样的 PDF 页面会把后续所有文本、形状和图形都渲染在裁剪区域之内。Cairo 的 state save/restore 现在与 PDF q/Q 操作符正确映射,所以图像绘制完后裁剪区域会被丢弃。
v3.9.9 2026-04-29
- 在 GDI+ 与 PDFium 之外新增基于 Cairo 的 PDF 渲染引擎作为第三种渲染选项。渲染前调用 SelectRenderer(2) 激活;引擎需要打包 DLL\Cairo 目录中的 cairo.dll。Cairo 渲染支持与 GDI+ 相同的输出模式:位图文件与流导出(BMP、JPEG、PNG、GIF、TIFF、G4 TIFF)、设备上下文渲染以及直接打印机输出。
- MultiFunction View/Print demo 现在暴露三向渲染器选择器,使用户能在同一份文档上并排比较 GDI+、PDFium 和 Cairo 输出,无需任何代码修改。
v3.9.8 2026-04-29
- 抑制了 Win32 C 运行时桩中两个伪编译器诊断,这两个诊断在 RAD Studio 13.1 及更新版本出现。一个废弃警告(W1000)因为编译器版本能力守卫没有传播到 Delphi 2009 以后的编译器,导致它们以废弃的内存管理器 API 编译。一个未使用变量提示(H2164)针对一个仅 Delphi 7 构建需要的内部兼容变量;该变量现已限定在那个版本的条件块内。两个问题都仅为诊断性,无运行时影响。
v3.9.7 2026-04-29
- 为 Windows 新增可选的基于 PDFium 的页面渲染,包括 BMP 流渲染、设备上下文渲染、内存渲染以及打印机输出。
- 更新 Delphi MultiFunction View/Print demo,增加渲染器选择器,使用户可在既有 GDI+ 渲染器与 PDFium 之间切换。
v3.9.6 2026-04-29
- 为完整 PDFlibPas 包和试用包提供独立的 Inno Setup 脚本,针对发布场景排除版本控制元数据、构建输出、IDE 缓存、本地 agent 文件以及非发布范围内的打包第三方源码树。
- 试用 installer 现在在生成 setup 可执行文件之前,为 RAD Studio 11.3、12.3 和 13.1 构建并打包试用版二进制库以及试用版 Delphi demo。
v3.9.5 2026-04-29
- 修复在 RAD Studio 9.0 / Delphi XE2 下的 Win32 库构建。构建脚本此前传递的 DCU 输出目录标志只在 Delphi 2010 及以后存在;XE2 的编译器以不同方式解释该标志,产生错乱的输出路径并在处理任何源文件前发生致命错误。脚本现在会根据目标编译器版本自动选择合适的标志。
- 修正了库源码中相关的编译器版本守卫,它原本在 XE2+ 条件下调用一个 XE4 才引入的命名限定运行时函数。针对 XE2 与 XE3 的构建现在会改用正确的兼容导入。
v3.9.4 2026-04-29
- 修复网络与服务器共享打印机的设置:通过打印机 DEVMODE handle(而非打印机设备上下文 handle)来应用纸盒、介质、双面、质量等打印设置。
v3.9.3 2026-04-29
- 在 Win32 与 Win64 上将打包的 AES 后端刷新到 Brian Gladman 2018 年的 AES 源码。可复现的构建脚本现在允许随时从源码重建静态 AES obj。过程中发现并修复了 Pascal 绑定的一个 ABI 缺陷:AES-CBC 加密与解密函数缺少 C 调用约定声明,因此 Win32 构建会静默地以错误的寄存器顺序传递参数,可能产生错误的加密输出。Win64 构建不受影响,因为该平台强制统一调用约定。
- 加固第三方重建脚本,使基于 MSVC 的 zlib、JPEG 和 CRT 桩脚本可以从仓库根和 thirdparty 目录启动;此前需要工作目录设为 thirdparty 目录。
v3.9.2 2026-04-29
- 在 Win32 与 Win64 上把 JPEG 2000 后端从旧版 OpenJPEG 1.5 升级到 OpenJPEG 2.5.4。两个平台现在都使用静态对象链接,因此 JPEG 2000 的编码与解码无需额外运行时 DLL。新版编解码带来当代 JP2/J2K 头部处理、回调驱动的流 API,以及来自上游项目积累的 bug 与安全修复。公共 TJpeg2000Bitmap API 保持不变。
v3.9.1 2026-04-29
- 修复 libjpeg-turbo 升级后的 JPEG 页面渲染与图像导出,恢复 Win32 与 Win64 上的 PdfToImage JPG 转换以及 TPDFJPEGImage.SaveToStream 输出。
- 修正 Win32 libjpeg-turbo ABI 绑定,使回调、结构对齐、布尔字段以及内存支持的 JPEG 目标与 libjpeg-turbo 3.1.90 匹配。
- 修复使用打包 zlib 1.3.2 后端的 Win32 FlateDecode 流解压,恢复 PdfToImage 样例文档等文件的 PDF xref 流加载。
v3.9.0 2026-04-29
- 把打包的 JPEG 2000 后端从旧版 OpenJPEG 1.5 升级到 OpenJPEG 2.5.4。JPEG 2000 加载与保存现在使用当代编解码、回调驱动的流 API 以及当代 JP2/J2K 头部处理,同时保留公共 TJpeg2000Bitmap API。
- JPEG 2000 输出现在为小图像自动选择有效的 OpenJPEG 分辨率数,并且 Win32 静态后端不再依赖缺失的 MSVCRT helper 导出。
v3.8.1 2026-04-29
- 消除了 Win32 与 Win64 上全部 16 条装饰性 linker W1028 "Bad global symbol definition" 警告。源码级重命名移除了多余的 Pascal 端重复(jpeg_std_error 与 jmemnobs allocator 桩现在仅从 obj 层解析);其余三个 bcc32 / vc64 obj 符号(jpeg_natural_order、jpeg_aritab、jpeg_nbits_table)必须保持与 Pascal 端数据的链接解析,它们现在在 thirdparty\build-jpeg-vc64.bat 的 ObjConv 后处理过程中被剥去 COFF 符号名。无公共 API 变更;Delphi Win32 与 Win64 构建的 linker 输出干净无警告。
v3.8.0 2026-04-29
- Win64 JPEG 编解码从 IJG 风格 libjpeg 升级到 libjpeg-turbo 3.1.90,完成了 v3.7.0(Win32)启动的 JPEG 迁移。Win32 与 Win64 路径现在共享同一现代 JPEG 编解码,配同样的 SIMD 优化内部循环以及来自上游累积的 30 多个 CVE / fuzz 修复。公共 PDFlibPas API 保持不变。
v3.7.0 2026-04-28
- Win32 JPEG 编解码从 IJG libjpeg-6b 升级到 libjpeg-turbo 3.1.90。通过 SIMD 优化的内部循环显著提升 JPEG 编码/解码速度,外加 libjpeg-turbo 上游累积的 30 多个 CVE / fuzz 修复。公共 PDFlibPas API(TPDFJPEGImage 类、DumpJPEG 函数)保持不变;既有 PDF/JPEG 代码路径无需源码改动即可获得加速。
v3.6.0 2026-04-28
- Win32 zlib 从 1.2.x 升级到 1.3.2。包含 1.2.8 以来上游累积的标准 25 多个 CVE / fuzz 修复,外加 64 位窗口流所用的新 inflateBack9 / inflateTree9 入口点。公共 PDFlibPas API(DeflateStr / InflateStr / InflateStrParms)保持不变。
- 本次发布 Win64 zlib 路径未变 — 它继续使用 Delphi 打包的 System.ZLib 单元。
- 为 Win32 zlib 路径激活 Win64 链接期 CRT 桩 PDFlibCLibs.pas(v3.5.0 引入),提供新 zlib 1.3.2 obj 文件所引用的 memcpy / memset / malloc / free 符号。
v3.5.0 2026-04-28
- 为打包的 C 图像 / 压缩库引入全新构建基础设施:zlib 1.3.2、libjpeg-turbo 3.1.90、libtiff 4.7.1。Embarcadero bcc32(Win32)与 MSVC cl.exe(Win64)的构建脚本与源码树一起放在 Lib/thirdparty/,因此任何装有 RAD Studio + VS2022 的人都可以从干净源码重建静态 obj 文件。
- 为 OpenJPEG 2.5.4 新增构建基础设施。OpenJPEG 源码树本身由用户独立获取(git clone uclouvain/openjpeg 到 Lib/thirdparty/OpenJPEG/),便于在不触动 PDFlibPas 构建配置的情况下升级。
- 新增 Lib/PDFlibCLibs.pas,这是 Win64 后端使用的 Win64 链接期 CRT shim。它弥合了 MSVC 编译的 C obj 文件与 Delphi Win64 链接器(dcc64 / Win64x ld.lld / BCB ilink64)之间的差异,后者不会自动引入 msvcrt.dll。
v3.4.0 2026-04-28
- 加固加密密钥、AES 初始化向量与 Perms 权限块的生成,使其不受可预测随机数源影响。在墙钟时间接近的系统上生成的加密 PDF 不再可轻易关联;AES-256 文档现在保持完整的密钥强度。
- 加固图像字典解析,使其能抵御声明了不合理 Width、Height、BitsPerComponent 或 DeviceN 分量数的畸形或恶意 PDF。越界值在任何像素缓冲区算术之前被夹紧,防止打开此类文件时崩溃。
- 加固交叉引用与页面树遍历,使其能抵御 /Prev xref 链或 /Parent 页面链接形成循环或过深的文档。reader 现在干净地拒绝畸形结构,而不是递归到栈耗尽。
v3.3.1 2026-04-27
- 精简每个组件的 Windows 构建脚本。DLL/、OCX/ 与 Dylib/ 目录不再带各自的 build12-* / build13-* 变体:每个平台现在只有一个 build-Win32 / build-Win64 脚本,固定到最新的 RAD Studio,并接受一个可选的 "debug" 参数。
- 在已经存在于初始 Git 基线中的 PDFlibRenderer.pas 渲染修复周围添加内联说明性注释。注释记录了 SetPen 为何按活动 canvas 变换缩放笔画宽度,以及 Type 3 字体 CharProc d0/d1 操作符为何必须消费它们的操作数。无运行时行为变化。
v3.3.0 2026-04-26
- 修复 PDFlibRenderer.pas 中变换后笔画的渲染。SetPen 现在在调用 Picasso 前把当前 canvas 变换比例应用到 PDF 线宽,避免在坐标已被变换的路径上出现过粗或过细的笔画。这修复了 Type 3 字形轮廓可能被渲染为粗大不规则块的问题。
- 修复内容流解析器中 Type 3 字体 CharProc d0/d1 处理。d0 现在消费它的两个宽度操作数,d1 在后续绘图命令运行前消费它的六个宽度/包围盒操作数,防止陈旧操作数破坏字形或路径几何。