Professional Documents
Culture Documents
www.pdflib.com
PDFlib、 PDI 和
PPS 教程
®
PDF 动态生成库
版本 7.0.1
综合版本:
Cobol、 C、 C++、 Java、 Perl、 PHP、 Python、 RPG、
Ruby 和 Tcl
版权所有 © 1997–2007 PDFlib GmbH 和 Thomas Merz。保留所有权利。
在此授予 PDFlib 用户许可,可以内部使用为目的复制本手册的印刷或数字副本。
PDFlib GmbH
Tal 40, 80331 München, Germany
www.pdflib.com
电话 +49 • 89 • 29 16 46 87
传真 +49 • 89 • 29 16 46 86
许可联系人: sales@pdflib.com
商业 PDFlib 许可证持有人支持: support@pdflib.com (请提供您的许可证号)
Adobe、 Acrobat、 PostScript 和 XMP 是 Adobe Systems Inc. 的商标。 AIX、 IBM、 OS/390、 WebSphere、
iSeries 和 zSeries 是 International Business Machines Corporation 的商标。ActiveX、Microsoft、OpenType
和 Windows 是 Microsoft Corporation 的商标。Apple、Macintosh 和 TrueType 是 Apple Computer, Inc. 的
商标。Unicode 及 Unicode 徽标是 Unicode, Inc. 的商标。Unix 是 The Open Group 的商标。Java 和 Solaris
是 Sun Microsystems, Inc. 的商标。HKS 是 HKS 品牌联名的注册商标:Hostmann-Steinberg、K+E Printing
Inks、 Schmincke。 其他公司的产品和服务名称可能是其他公司的商标或服务标志。
PDFlib 包含下列经过修改的第三方软件组件:
ICClib,版权所有 © 1997-2002 Graeme W. Gill
GIF 图像解码器,版权所有 © 1990-1994 David Koblas
PNG 图像参考库 (libpng),版权所有 © 1998-2004 Glenn Randers-Pehrson
Zlib 压缩库,版权所有 © 1995-2002 Jean-loup Gailly and Mark Adler
TIFFlib 图像库,版权所有 © 1988-1997 Sam Leffler,版权所有 © 1991-1997 Silicon Graphics, Inc.
Eric Young 编写的密码软件,版权所有 © 1995-1998 (eay@cryptsoft.com)
Independent JPEG Group 的 JPEG 软件,版权所有 © 1991-1998, Thomas G. Lane
密码软件,版权所有 © 1998-2002 The OpenSSL Project (www.openssl.org)
Expat XML 分析器,版权所有 © 1998, 1999, 2000 Thai Open Source Software Center Ltd
1 前言 13
1.1 文档与示例指南 13
1.2 PDFlib 编程 14
1.3 PDFlib 7 中的新增功能 16
1.4 PDFlib/PDFlib+PDI/PPS 7 中的功能 19
1.5 产品的功能对照 21
2 PDFlib 语言绑定 23
2.1 Cobol 绑定 23
2.2 COM 绑定 24
2.3 C 绑定 25
2.4 C++ 绑定 27
2.5 Java 绑定 28
2.6 .NET 绑定 30
2.7 Perl 绑定 31
2.8 PHP 绑定 33
2.9 Python 绑定 35
2.10 REALbasic 绑定 36
2.11 RPG 绑定 37
2.12 Ruby 绑定 40
2.13 Tcl 绑定 41
3 PDFlib 编程 43
3.1 常规编程 43
3.1.1 异常处理 43
3.1.2 PDFlib 虚拟文件系统 (PVF) 45
3.1.3 资源配置和文件搜索 46
3.1.4 在内存中生成 PDF 文档 49
3.1.5 在基于 EBCDIC 的平台上使用 PDFlib 50
3.1.6 大型文件支持 50
3.2 页面说明 51
3.2.1 坐标系统 51
3.2.2 页面大小 53
3.2.3 路径 54
3.2.4 模板 54
目录 3
3.3 使用颜色 56
3.3.1 图案和平滑着色 56
3.3.2 专色 57
3.3.3 色彩管理和 ICC 色彩特征描述文件 59
3.4 交互元素 63
3.4.1 创建交互元素的示例 63
3.4.2 文本域的格式化选项 67
4 Unicode 与旧有编码 69
4.1 概述 69
4.2 几个重要的 Unicode 概念 70
4.3 PDFlib 中的字符串 72
4.3.1 PDFlib 中的字符串类型 72
4.3.2 识别 Unicode 的语言中的字符串 72
4.3.3 不识别 Unicode 的语言绑定中的字符串 73
4.4 8 位编码 76
4.5 中文、日文和韩文文本编码 80
4.6 字符和字形寻址 83
4.6.1 转义序列 83
4.6.2 字符引用和字形名称引用 84
4.6.3 字形检查和替代 86
4.6.4 检查字形可用性 87
5 字体处理 89
5.1 字体和编码概述 89
5.1.1 支持的字体格式 89
5.1.2 字体编码 90
5.2 字体格式详细信息 92
5.2.1 PostScript Type 1 字体 92
5.2.2 TrueType 和 OpenType 字体 93
5.2.3 用户定义的 (Type 3) 字体 94
5.3 搜索、嵌入和子集化字体 95
5.3.1 搜索字体 95
5.3.2 Windows 和 Mac 上的宿主字体 98
5.3.3 字体嵌入 99
5.3.4 字体子集化 101
5.4 其他主题 103
5.4.1 符号字体和特定于字体的编码 103
5.4.2 TrueType 和 OpenType 字体的字形 ID 寻址 104
5.4.3 欧元符号字形 104
5.4.4 Unicode 兼容的字体 105
5.5 字体规格和文本变体 106
5.5.1 字体和字形规格 106
5.5.2 字距调整 107
5.5.3 文本变体 108
4 目录
5.6 中文、日文和韩文字体 110
5.6.1 标准 CJK 字体 110
5.6.2 自定义 CJK 字体 111
7 格式化功能 127
7.1 放置并调整单行文本 127
7.1.1 简单的文本放置 127
7.1.2 在框中放置文本 128
7.1.3 框中填充文本 129
7.1.4 沿字符对齐文本 131
7.1.5 放置图章 131
7.1.6 使用前导字符 132
7.2 多行 textflow 133
7.2.1 在限定框中放置 textflow 134
7.2.2 段落格式设置选项 136
7.2.3 内嵌选项列表和宏 137
7.2.4 制表位 139
7.2.5 编号列表和段落间距 140
7.2.6 控制字符、字符映射和符号字体 141
7.2.7 断字 144
7.2.8 控制换行算法 145
7.2.9 环绕文本 147
7.3 放置图像和导入的 PDF 页 150
7.3.1 简单的对象放置 150
7.3.2 在框中定位对象 150
7.3.3 使对象适合框 151
7.3.4 对象的定向 152
7.3.5 旋转对象 153
7.3.6 调整页面尺寸 155
目录 5
7.4 表格式化 156
7.4.1 放置简单表 157
7.4.2 表单元格的内容 158
7.4.3 表和列宽度 160
7.4.4 大表示例 161
7.4.5 表实例 165
7.5 匹配框 168
7.5.1 装饰文本行 168
7.5.2 在 Textflow 中使用匹配框 169
7.5.3 匹配框和图像 170
8 pCOS 接口 173
8.1 pCOS 的简单示例 173
8.2 处理基本 PDF 数据类型 174
8.3 复合数据结构和 ID 176
8.4 路径语法 177
8.5 伪对象 179
8.6 加密的 PDF 文档 183
6 目录
10 数据变量和块 211
10.1 安装 PDFlib 块增效工具 211
10.2 PDFlib 块概念的概述 213
10.2.1 文档设计和程序代码的完整分离 213
10.2.2 块属性 214
10.2.3 链接多个 Textflow 块 215
10.2.4 为什么不使用 PDF 表单域? 216
10.3 建立 PDFlib 块 217
10.3.1 利用 PDFlib 块增效工具交互式建立块 217
10.3.2 编辑块属性 220
10.3.3 页和文件之间的块拷贝 221
10.3.4 将 PDF 表单域转换为 PDFlib 块 222
10.4 用于自动化处理的标准属性 224
10.4.1 常规属性 224
10.4.2 Text 属性 226
10.4.3 Image 属性 230
10.4.4 PDF 属性 230
10.4.5 自定义属性 230
10.5 使用 pCOS 询问块名及其属性 231
10.6 PDFlib 块规格 233
10.6.1 PDFlib 块的 PDF 对象结构 233
10.6.2 利用 pdfmarks 生成 PDFlib 块 236
A 修订历史记录 237
索引 239
目录 7
0 应用 PDFlib 许可证密钥
无论您是否持有 PDFlib 的商业许可证,由 PDFlib GmbH 提供的所有二进制版本的 PDFlib、
PDFlib+PDI 和 PPS 都可以作为功能完整的评估版本使用。然而,未经许可的版本将在所有
生成的页上显示 www.pdflib.com 演示图章。那些真正对 PDFlib 许可证感兴趣并希望消除评
估期间或原型演示的演示图章的公司,可以将带有简要说明的有关公司和项目的详细信息
提交到 sales@pdflib.com,以便申请临时许可证密钥 (我们保留拒绝评估密钥的权利,例如
匿名请求)。
在您购买许可证密钥之后,必须应用该密钥才能消除演示图章。您可以在运行时使用一
个 PDFlib 调用、通过准备许可证文件或(在 Windows 上)使用注册表项应用许可证密钥。
如果您使用 Windows 安装程序,您可以在安装本产品时输入许可证密钥。
在运行时应用许可证密钥 在脚本或程序中添加一行代码以便在运行时设置许可证密钥。
在实例化 PDFlib 对象之后(即,在 PDF_new( ) 或等同的调用之后),紧接着必须设置 license
参数。具体语法取决于您所用的编程语言:
> 在 C 和 Python 中:
PDF_set_parameter(p, "license", "... 您的许可证密钥 ...")
> 在 RPG 中:
c callp RPDF_set_parameter(p:%ucs2('license'):
c %ucs2('...your license key...'))
> 在 Tcl 中:
PDF_set_parameter $p, "license", "... 您的许可证密钥 ..."
9
使用许可证文件 除通过运行时调用提供许可证密钥外,您还可以根据以下格式在文本文件
中输入许可证密钥(您可以使用所有 PDFlib 发布中均包含的许可证文件模板 licensekeys.txt)
:
PDFlib license file 1.0
# Licensing information for PDFlib GmbH products
PDFlib 7.0.1 ... 您的许可证密钥 ...
> 在 Tcl 中:
PDF_set_parameter $p, "licensefile", "/path/to/licensekeys.txt"
10 第 0 章: 应用 PDFlib 许可证密钥
更新和升级 若您已购买一个更新 (从产品的旧版本换到同一产品的新版本)或升级 (从
PDFlib 换到 PDFlib+PDI 或 PPS,或从 PDFlib+PDI 换到 PPS ),则必须应用您所接收的用于
更新或升级的新的许可证密钥。不得再使用先前产品的旧的许可证密钥。请注意许可证密钥
对特定产品版本的所有维护版均有效;就许可而言,所有版本的 7.0.x 的处理方式均相同。
评估未经许可的功能 当未应用任何许可证密钥时,您可以完全评估软件的所有功能。一
旦您应用了特定产品的有效许可证密钥,将不再可使用更高类别的功能。例如,若您已安装
有效的 PDFlib 许可证密钥,则 PDI 功能将不再可用于测试。同样,在安装 PDFlib+PDI 许可
证密钥后, PPS 功能 (块函数)将不再可用。
若您已安装某个产品的许可证密钥,则可以用伪许可证字符串 “0”(零)替换该密钥来
启用更高的产品类别的功能以进行评估。这将启用先前已禁用的功能,并重新激活所有页的
演示图章。
11
12 第 0 章: 应用 PDFlib 许可证密钥
1 前言
1.1 文档与示例指南
我们提供以下材料帮助您成功使用 PDFlib 产品:
> 所有软件包及其所有语言绑定均提供微型示例(Hello、图像、 Pdfclock 等)。它们为文
本输出、图像和矢量图形提供了最基本的示例代码。这些微型示例主要供您测试 PDFlib
安装时使用,并且还有助于您快速概略了解如何编写 PDFlib 应用程序。
> 在所有软件包中均含有针对各种语言绑定的入门示例。这为想了解重要主题的用户提供了
有用的起点。示例内容覆盖简单文本和图像输出、文本流和表格式化、PDF/A 和 PDF/X 创
建以及其他主题。入门示例演示了一些使用 PDFlib 产品实现特定目标的基本技巧。强烈建
议您查看这些入门示例。
1.1 文档与示例指南 13
1.2 PDFlib 编程
什么是 PDFlib? PDFlib 是一个帮助您生成符合 Adobe 的可移植文档格式 (PDF) 文件的中
间件。 PDFlib 充当用户自己程序的后端。当应用程序员负责抽取要处理的数据时, PDFlib
承担生成 PDF 输出 (图解数据)的任务。 PDFlib 让您无需再关注 PDF 的内部细节问题,并
提供了各种方法来帮助您设置输出的格式。发布软件包在同一个二进制文件中包含了不同
的产品:
> PDFlib 包含创建 PDF 输出(包括文本、矢量图形和图像以及超文本元素)所必需的所有
函数。 PDFlib 为放置单行或多行文本、图像和创建表提供了强大的格式化功能。
> PDFlib+PDI 包括所有 PDFlib 函数,以及用于在输出的文件中嵌入现有的 PDF 文档页的
PDF 输入库 (PDI),及用于查询导入文档中任意 PDF 对象(例如列出页面上的所有字体、
查询元数据等等)的 pCOS 接口。
> PDFlib Personalization Server (PPS) 包括 PDFlib+PDI 以及用于自动填充 PDFlib 块的附
加函数。块是页上的占位矩形,可以用文本、图像或 PDF 页进行填充。可以使用适用于
Adobe Acrobat (Mac 或 Windows)的 PDFlib 块插件交互式创建块,并使用 PPS 自动
进行填充。该插件包含在 PPS 中。
14 第 1 章: 前言
使用 PDFlib 可以做些什么? PDFlib 的主要目标是在您自己的软件内部或在 Web 服务器
上动态创建 PDF。类似于在 Web 服务器上动态创建 HTML 页,您可以使用 PDFlib 程序动态
创建 PDF 以反映用户输入或其他一些动态数据 (例如从 Web 服务器的数据库中检索的数
据)。 PDFlib 方法具有下面几个优点:
> PDFlib 可被直接集成到生成数据的应用程序中。
> 这一直接简单的方法意味着, PDFlib 是生成 PDF 的最快方法,完全适用于 Web。
> PDFlib 的多线程安全及其可靠内存和错误处理可支持实现高性能的服务器应用程序。
> PDFlib 可用于多种操作系统和开发环境。
1.2 PDFlib 编程 15
1.3 PDFlib 7 中的新增功能
下面的列表讨论 PDFlib 7 中最重要的新增功能或改进功能。
文本流功能增强 用于格式化文本的文本流引擎已得到改进:
> 链接和其他交互元素均可在文本流中从文本片段自动创建。
> 文本可以围绕图像。
> 文本流格式器支持前导字符,例如目录条目与对应的页码之间的重复圆点。
> 文本目录和格式化选项可以任意步骤单独提供给文本流引擎。这样便无需创建包含完整
文本及内嵌格式化选项的缓冲区。
> 现在可以重定义用于作格式化决定的字符类,例如可指定在格式化决定中是否将“/”字
符作为字母或标点处理。
> 可以编程方式查询格式化结果。
其他格式化功能
> 单行文本 (除多行文本流之外)中支持小数制表符和前导字符
> 新的图章功能可计算矩形内文本图章的最优化大小和位置。
> 改进了文本几何特征的查询功能。
16 第 1 章: 前言
改进了中文、日文和韩文文本的处理 PDFlib 7 消除了在早期版本中出现的如下一些与
CJK 文本处理有关的限制:
> PDFlib 完全支持所有标准 CMap 的字形规格;例如可以使用文本流格式化 Shift-JIS 文本。
> 现在所有 TrueType 和 OpenType 字体均支持垂直书写模式。
> 现在所有平台 (以前仅 Windows)均支持中文、日文和韩文代码页 (例如 Shift-JIS 的
代码页 932)。
> CJK CMap 现在也支持交互功能,例如书签 (以前仅支持页内容)。
> Acrobat 的预定义 CJK 字体现在可用于 Unicode 编码。
> 对于编码为预定义 CMap 的 OpenType CID 字体不再强制进行字体嵌入,因而减小了文
件大小。
错误处理 在所有语言绑定中更简洁有效地处理异常和其他错误。
18 第 1 章: 前言
1.4 PDFlib/PDFlib+PDI/PPS 7 中的功能
表 1.1 列出了用于生成和导入 PDF 的主要 PDFlib 功能。PDFlib 7 中新功能或改进功能已被标
记出来。
20 第 1 章: 前言
1.5 产品的功能对照
表 1.2 罗列了开放原码版本 PDFlib Lite 和不同的商业产品的功能。
表 1.2 不同产品中的功能的可用性
(开放原码)
PDFlib+PDI
PDFlib Lite
PDFlib
PPS
功能 API 函数、参数和选项
基本 PDF 生成 (除以下列出项之外的全部) X X X X
支持 EBCDIC 系统 所有函数 – X X X
字形 ID 寻址 带有 encoding=glyphid 的 PDF_load_font( ) – X X X
查询字体详细信息 PDF_info_font( ) – X X X
专色 PDF_makespotcolor( ) – X X X
1.5 产品的功能对照 21
表 1.2 不同产品中的功能的可用性 (续)
(开放原码)
PDFlib+PDI
PDFlib Lite
PDFlib
PPS
功能 API 函数、参数和选项
分色 带有 separationinfo 选项的 – X X X
PDF_begin_page_ext( )
表域 PDF_create_field( )、 PDF_create_fieldgroup( ) – X X X
图层 带有 type=SetOCGState 的 PDF_define_layer( )、 – X X X
PDF_begin_layer( )、 PDF_end_layer( )、 PDF_set_
layer_dependency( )、 PDF_create_action( )
22 第 1 章: 前言
2 PDFlib 语言绑定
注: 强烈建议您查看包含在所有 PDFlib 软件包中的入门示例。这些示例为您自己的应用程序开
发提供了一个方便的起点,并涵盖了 PDFlib 编程的许多重要方面。
2.1 Cobol 绑定
虽然用于 Cobol 的 PDFlib API 函数不可以按照标准 C 中的名称使用,但可以使用缩写的函
数名称。虽然在此处没有说明相应的缩写函数名称,但可以在单独的交叉引用列表 (xref.txt)
中找到它们。例如,必须使用缩写形式 PDLODFNT 来代替 PDF_load_font( )。
将用 Cobol 编写的 PDFlib 客户端静态地链接到 PDFLBCOB 对象。此对象然后动态地加
载 PDLBDLCB 加载模块 (DLL),该模块又将在首次调用 PDNEW (对应于 PDF_new( ))时动
态加载 PDFlib 加载模块 (DLL)。新近分配的 PDFlib 内部结构的实例句柄存储在 P 参数中,随
后的每个调用都必须提供该参数。
PDLBDLCB 加载模块提供 8 字符 Cobol 函数与核心 PDFlib 例程之间的接口。PDLBDLCB
加载模块还提供 PDFlib 的异步异常处理与 Cobol 预期的整体式 (检查每个函数的返回代
码)方法之间的映射。
2.1 Cobol 绑定 23
2.2 COM 绑定
(只有 COM/.NET/REAL 基本版的 PDFlib 教程中包括此小节。)
24 第 2 章: PDFlib 语言绑定
2.3 C 绑定
PDFlib 自身是用 ANSI C 语言编写的。为了使用 PDFlib C 绑定,您可以使用静态或共享库
(Windows 和 MVS 上的 DLL) ,并且您需要在 PDFlib 客户端源模块中包含带有 pdflib.h 的
PDFlib 核心文件。另外,可以使用 pdflibdl.h 在运行时动态加载 PDFlib DLL(有关详细信息,
请参见下一节)。
PDF_delete(p);
注: PDF_TRY/PDF_CATCH 是用复杂的预处理器宏实现的。若不小心忽略了其中一个,将导致一些
可能让人难以理解的编译器错误消息。确保完全按照如上所示的形式使用这些宏,在 TRY 子
句和 CATCH 子句 (PDF_CATCH( ) 除外)之间不要添加任何代码。
2.3 C 绑定 25
如果您想在 try 子句结束之前离开该子句,则必须先使用 PDF_EXIT_TRY( ) 宏通知异常机
制。在此宏与 try 块的结尾之间可以不调用任何其他 PDFlib 函数。
catch 子句的一个重要任务是通过使用 PDF_delete( ) 和指向 PDFlib 对象的指针清理
PDFlib 内部变量。必要时 PDF_delete( ) 也将关闭输出文件。发生严重异常后,PDF 文档将不
能使用,并将保留为未完成和不一致状态。很显然,不同的应用程序对异常的正确处理会各
不相同。
对于未捕捉异常的 C 和 C++ 客户端,针对异常的默认操作是在标准错误通道上发出适当
的消息,并在发生严重错误时退出。PDF 输出文件将保留为未完成状态!由于默认操作可能
无法满足对库的例行要求,因此对于重大的 PDFlib 项目,强烈建议利用 PDFlib 的异常处理
功能。例如,用户定义的 catch 子句可能在 GUI 对话框中显示错误消息,并获取其他度量值
而不是中止项目。
26 第 2 章: PDFlib 语言绑定
2.4 C++ 绑定
除了提供 pdflib.h C 头文件之外,我们还为 PDFlib 客户提供 C++ 的面向对象的包装。这就需
要 pdflib.hpp 头文件(它又包含 pdflib.h)。相应的 pdflib.cpp 模块应针对应用程序进行链接,
而该应用程序又应针对通用 PDFlib C 库进行链接。
通过使用 C++ 对象包装,可用一个更加面向对象的方法替代所有 PDFlib 函数名称中的
PDF_ 前缀。
C++ 的错误处理 出错时, PDFlib API 函数将引发 C++ 异常。必须使用 C++ try/catch 子句
在客户端代码中捕获这些异常。为了提供扩展的错误信息, PDFlib 类提供了一个公共
PDFlib::Exception 类,该类公开了用来检索详细的错误信息、异常号和引发异常的 PDFlib
API 函数的名称的方法。
由 PDFlib 例程引发 的本地 C++ 异常将 按预期 的方式运 行。以下代 码片段 将捕获由
PDFlib 引发的异常:
try {
...some PDFlib instructions...
catch (PDFlib::Exception &ex) {
cerr << "PDFlib exception occurred in hello sample:" << endl;
cerr << "[" << ex.get_errnum() << "] " << ex.get_apiname()
<< ": " << ex.get_errmsg() << endl;
return 2;
}
若要修复此问题,请提供带有长度参数的字符串构造函数:
p.show(string("\x00\x41\x96\x7B\x8C\xEA", 6)); // Correct
2.4 C++ 绑定 27
2.5 Java 绑定
Java 支持可移植机制以便将本地语言代码附加到 Java 程序,即 Java 本地接口 (JNI)。 JNI 提
供编程约定以便从 Java 代码内部调用本地 C 或 C++ 例程或进行相反的调用。每个 C 例程都
需要用适当的代码进行包装以便可用于 Java VM,并且需要共享或动态对象生成库,以便将
其加载到 Java VM 中。
PDFlib 提供 JNI 包装代码以便从 Java 中使用库。此技术使我们可以通过从 Java VM 加载
共享库将 PDFlib 附加到 Java。实际上,库的加载是通过 pdflib Java 类中的静态成员函数来
完成的。因此, Java 客户端不需要为共享库处理的细节费心。
考虑到 PDFlib 的稳定性和成熟性,将本地 PDFlib 库附加到 Java VM 不但不会对您的
Java 应用程序带来任何稳定性或安全性限制,反而提供本地实现的性能优势。关于可移植
性,请记住, PDFlib 适用于所有安装了 Java VM 的平台!
安装 PDFlib Java 版本 为了使 PDFlib 绑定起作用, Java VM 必须有对 PDFlib Java 包装和
PDFlib Java 包的访问权。将 PDFlib 组织成以下包名称的 Java 包:
com.pdflib.pdflib
您可以按照如下方式检查此属性的值:
System.out.println(System.getProperty("java.library.path"));
另外,必须执行下面的与平台相关的步骤:
> Unix:必须将 libpdf_java.so 库 (在 Mac OS X 上:libpdf_java.jnilib)置于某一默认存放
共享库的目录,或某一合适的配置目录中。
> Windows:必须将 pdf_java.dll 库置于 Windows 系统目录中,或置于 PATH 环境变量列
出的某一目录中。
28 第 2 章: PDFlib 语言绑定
Java 的错误处理 Java 绑定安装一个特殊的错误处理程序,该程序会将 PDFlib 错误转换成
本机 Java 异常。发生异常时, PDFlib 将引发本地 Java 异常通过以下类:
PDFlibException
} catch (PDFlibException e) {
System.err.print("PDFlib exception occurred in hello sample:\n");
System.err.print("[" + e.get_errnum() + "] " + e.get_apiname() +
": " + e.get_errmsg() + "\n");
} catch (Exception e) {
System.err.println(e.getMessage());
} finally {
if (p != null) {
p.delete(); /* delete the PDFlib object */
}
}
2.5 Java 绑定 29
2.6 .NET 绑定
(只有 COM/.NET/REAL 基本版的 PDFlib 教程中包括此小节。)
30 第 2 章: PDFlib 语言绑定
2.7 Perl 绑定
Perl1 支持通过本地 C 库扩展语言解释程序的机制。Perl 的 PDFlib 包装由一个 C 包装文件和
一个 Perl 包模块组成。在一些包文件的帮助下, C 模块用于构建 Perl 解释程序在运行时加
载的共享库。 Perl 脚本通过 use 语句引用共享库模块。
以上命令的典型输出如下所示:
C:\Program Files\Perl5.8\site\lib
1. 请参见 www.perl.com
2. 请参见 www.activestate.com
2.7 Perl 绑定 31
多种字符串处理方式 根据应用程序要求的不同,您可以使用 UTF-8、 UTF-16 或旧编码。
下面的代码片段演示了所有这三种变体。所有示例均创建相同的日文输出,但以不同的格式
接受字符串输入。
第一个示例使用 Unicode UTF-8,并使用 Unicode::String 模块,该模块属于最新的 Perl 发
布的一部分,并在 CPAN 上可用)。由于 Perl 在内部使用 UTF-8,所以无需进行显式 UTF-8
转换:
use Unicode::String qw(utf8 utf16 uhex);
...
PDF_set_parameter($p, "textformat", "utf8");
$font = PDF_load_font($p, "Arial Unicode MS", "unicode", "");
PDF_setfont($p, $font, 24.0);
PDF_set_text_pos($p, 50, 700);
PDF_show($p, uhex("U+65E5 U+672C U+8A9E"));
Encode 模块支持许多种编码,并具备在这些编码之间进行转换的接口:
use Encode 'decode';
$data = decode("iso-8859-3", $data); # convert from legacy to UTF-8
32 第 2 章: PDFlib 语言绑定
2.8 PHP 绑定
安装 PDFlib PHP 版本 有关将 PDFlib 用于 PHP 的1 的各种风格和选项的详细信息,包括有
关是否使用 PHP 的可加载 PDFlib 模块的问题,都可以在 PDFlib-in-PHP-HowTo.pdf 文档中找
到。此文档包含在分发包中,也可以在 PDFlib 网站上找到。
必须对 PHP 进行配置,以便让其了解外部的 PDFlib 库。您有两种选择:
> 在 php.ini 中添加以下行之一:
extension=libpdf_php.so ; for Unix
extension=libpdf_php.dll ; for Windows
1. 请参见 www.php.net
2.8 PHP 绑定 33
PHP 4 的错误处理 当出现一个 PDFlib 异常时,将引发一个 PHP 异常。由于 PHP 4 不支持
结构化异常处理,所以无法捕获异常和进行适当的操作。使用 PDFlib 时,不要禁用 PHP 警
告,否则将会遇到真正的麻烦。
PDFlib 警告 (非严重错误)将被映射到 PHP 警告,这些警告可以在 php.ini 中禁用。另
外,如同在任何其他语言绑定中一样,在运行时可以使用一个 PDFlib 函数调用禁止警告:
PDF_set_parameter($p, "warning", "false");
34 第 2 章: PDFlib 语言绑定
2.9 Python 绑定
安装 PDFlib Python 版本 Python1 扩展机制通过在运行时加载共享库的方式工作。为了使
PDFlib 绑定运作, Python 解释程序必须能够访问 PDFlib Python 包装:
> Unix:将在 PYTHONPATH 环境变量列出的目录中搜索库 pdflib_py.so (在 Mac OS X
上:pdflib_py.dylib)。
> Windows:将在 PYTHONPATH 环境变量列出的目录中搜索库 pdflib_py.dll 。
1. 请参见 www.python.org
2.9 Python 绑定 35
2.10 REALbasic 绑定1
(只有 COM/.NET/REAL 基本版的 PDFlib 教程中包括此小节。)
1. 请参见 www.realbasic.com
36 第 2 章: PDFlib 语言绑定
2.11 RPG 绑定
PDFlib 提供一个 /copy 模块,其中定义了所有原型和使用嵌入的 PDFlib 函数编译 ILE-RPG
程序时必需的一些有用的常量。
因为所有字符串都是作为可变长度字符串传递的,所以您不能传递引用相同函数的字符串
参数的 length 参数。可变长度域的长度存储在所分配内存的前两个字节中。
若 PDFlib 源文件库未在库列表的顶部,则您还必须指定库:
d/copy PDFsrclib/QRPGLESRC,PDFLIB
2.11 RPG 绑定 37
RPG 的错误处理 用 ILE-RPG 编写的 PDFlib 客户端可以在 PDFlib 中安装一个错误处理程
序,该程序将在发生异常时被激活。由于 ILE-RPG 将所有程序名称都转换成大写形式,因此
应将错误处理程序的名称以大写形式指定。下面的主干代码演示了此技术:
*****************************************************************************************
d/copy QRPGLESRC,PDFLIB
*****************************************************************************************
d p S *
d font s 10i 0
*
d error s 50
*
d errhdl s * procptr
*
* Prototype for exception handling procedure
*
d errhandler PR
d p * value
d type 10i 0 value
d shortmsg 2048
*****************************************************************************************
c clear error
*
* Set the procedure pointer to the ERRHANDLER procedure.
*
c eval errhdl=%paddr('ERRHANDLER')
*
c eval p=pdf_new2(errhdl:*null:*null:*null:*null)
...PDFlib instructions...
c callp PDF_delete(p)
*
c exsr exit
*****************************************************************************************
c exit begsr
c if error<>*blanks
c error dsply
c endif
c seton lr
c return
c endsr
*****************************************************************************************
* If any of the PDFlib functions will cause an exception, first the error handler
* will be called and after that we will get a regular RPG exception.
c *pssr begsr
c exsr exit
c endsr
*****************************************************************************************
* Exception Handler Procedure
* This procedure will be linked to PDFlib by passing the procedure pointer to
* PDF_new2. This procedure will be called when a PDFlib exception occurs.
*
*****************************************************************************************
p errhandler B
d errhandler PI
d p * value
d type 10i 0 value
38 第 2 章: PDFlib 语言绑定
d c_message 2048
*
d length s 10i 0
*
* Chop off the trailing x'00' (we are called by a C program)
* and set the error (global) string
c clear error
c x'00' scan c_message length 50
c sub 1 length
c if *in50 and length>0
c if length>%size(error)
c eval error=c_message
c else
c eval error=%subst(c_message:1:length)
c endif
c endif
*
* Always call PDF_delete to clean up PDFlib
c callp PDF_delete(p)
*
c return
*
p errhandler E
2.11 RPG 绑定 39
2.12 Ruby 绑定
安装 PDFlib Ruby 版本 通过在运行时加载共享库实现 Ruby1 扩展机制。为了使 PDFlib 绑
定运作, Ruby 解释程序必须能够访问用于 Ruby 的 PDFlib 扩展 :此库 (在 Windows/
Linux/Unix 上为:PDFlib.so ;在 Mac OS X 上为:PDFlib.bundle)通常安装在本地 ruby 安
装目录的 site_ruby 子目录下,即在一个类似以下名称的目录下:
/usr/local/lib/ruby/site_ruby/<rubyversion>/
1. 请参见 www.ruby-lang.org/en
2. 请参见 www.rubyonrails.org
40 第 2 章: PDFlib 语言绑定
2.13 Tcl 绑定
安装 PDFlib Tcl 版本 通过在运行时加载共享库实现 Tcl 1 扩展机制。为了使 PDFlib 绑定起
作用,Tcl 外壳程序必须能访问 PDFlib Tcl 包装共享库和软件包索引文件 pkgIndex.tcl 。您可
以在脚本中使用以下命令,以便可以从某个目录中使用库 (如果您想在您没有安装 PDFlib
的根权限的计算机上部署 PDFlib,这将会很有用):
lappend auto_path /path/to/pdflib
1. 请参见 www.tcl.tk
2.13 Tcl 绑定 41
42 第 2 章: PDFlib 语言绑定
3 PDFlib 编程
3.1 常规编程
3.1.1 异常处理
有一类型的错误在许多语言中有很好的理由被称作异常―它们仅仅是异常,并且在程序的
生存期间不会经常发生。一般策略是对可能时常出错的函数调用使用常规的错误报告机制
(即特殊错误返回代码,例如 -1),而对那些极少出现的且在一定条件下会弄乱代码的情况
使用特殊异常机制。这正是 PDFlib 遵循的处理方法:可预期一些操作将相当频繁地出错,
例如:
> 试图打开对其没有相应权限的输出文件
> 试图用错误的文件名打开输入 PDF 文件
> 试图打开损坏的图像文件
当 PDFlib 检测到这种情形时,将引发一个异常而不是将一个特殊的错误返回值传递给调
用方。必须懂得一点,即在发生异常后无法完成 PDF 文档的生成。发生异常后,只可以安
全调用以下方法之一 :PDF_delete( )、PDF_get_apiname( )、PDF_get_errnum( ) 和 PDF_get_
errmsg( )。发生异常后,调用任何其他 PDFlib 方法可能导致意外结果。异常中将包括以下
信息:
> 唯一的错误号;
> 引发异常的 PDFlib API 函数的名称;
> 包含问题的详细信息的描述性文本。
3.1 常规编程 43
错误处理策略 当 PDFlib 检测到错误条件时,它将根据任一可以使用 errorpolicy 参数进行
配置的错误处理策略做出反应。所有能够返回错误代码的函数也支持 errorpolicy 选项。支持
以下错误处理策略:
> errorpolicy=legacy: 此设置确保错误处理行为与 PDFlib 早期的版本兼容,在这些版本
中,异常和错误返回值是通过例如 fontwarning、 imagewarning 等参数和选项控制的。
只有要求源代码与 PDFlib 6 兼容的应用程序,才建议使用此设置。对于新的应用程序,
不应使用此设置。 legacy 设置是默认的错误处理策略。
> errorpolicy=return: 当检测到错误条件时,相应的函数将返回 -1 (在 PHP 中: 0) 与警
告参数或选项无关的错误值。应用程序开发人员必须检查返回值以鉴别问题,且必须以
适合于应用程序的方式对问题作出反应。此方法统一了对错误的处理方式,建议采用。
> errorpolicy=exception: 检 测 到错误条件时将引发异常。但异常之后,输出文档将不可
用。这可以用于无任何错误条件的简化编程,但将以牺牲输出文档为代价,特别是一些
可以由应用程序修正的问题。
以下代码片段演示了有关异常处理的不同策略。示例试图加载某一字体,但该字体不一定
可用。
若 errorpolicy=return,必须检查返回值以判断是否存在错误。若返回值指示失败,则查
询失败的原因以便对这种情况进行正确地处理:
font = p.load_font("MyFontName", "unicode", "errorpolicy=return");
if (font == -1)
{
/* font handle is invalid; find out what happened. */
errmsg = p.get_errmsg());
/* Try a different font or give up */
...
}
/* font handle is valid; continue */
若 errorpolicy=exception,产生错误时必须放弃文档:
font = p.load_font("MyFontName", "unicode", "errorpolicy=exception");
/* Unless an exception was thrown the font handle is valid;
* if an exception occurred, the PDF output cannot be continued
*/
警告 PDFlib 内部能够检测一些问题,但不会为此引发异常而中断程序流程。在早期版本
的 PDFlib 支持非致命异常 (可禁用)的概念, PDFlib 7 则从不为非致命情况引发异常。而
是会记录情况的描述 (如果启用了日志)。可以按以下方式启用日志:
p.set_parameter("logging", "filename=private.log");
关于警告,建议采用以下方法:
> 在开发阶段启用警告日志,并仔细研究日志文件中的任何警告消息。这些消息可能会指
向代码或数据中的潜在问题,您应尝试理解或消除产生这些警告的原因。
> 在生产阶段禁用警告日志,只有在出现问题时才重新启用。
44 第 3 章: PDFlib 编程
3.1.2 PDFlib 虚拟文件系统 (PVF)
除磁盘文件以外,一种名为“PDFlib 虚拟文件系统”(PDFlib Virtual File System, PVF) 的工具
允许客户端直接在内存中提供数据而不需要任何磁盘文件参与。这种方式带来了性能上的
优势,可用于从数据库捕获的数据 (这些数据甚至不存在于单独的磁盘文件上)以及其他
一些客户端在内存中已具有所需的数据 (作为处理的结果)的情况。
PVF 基于命名的虚拟只读文件的概念,这类文件与常规文件名称一样,可以与任何 API
函数一起使用。 PVF 甚至可以在 UPR 配置文件中使用。客户端可以使用任意方法生成虚拟
文件名称。显然,必须选择虚拟文件名称以避免与常规磁盘文件发生名称冲突。为此,建议
遵循以下的虚拟文件名称的分层命名约定 (filename 是指客户端选择的在相应类别中唯一
的名称)。还建议保留标准文件名称后缀:
> 光栅图像文件:/pvf/image/filename
> 字型和规格文件 (建议将实际字体名称用作文件名称的基础部分):/pvf/font/filename
> ICC 色彩特征描述文件:/pvf/iccprofile/filename
> 编码和代码页:/pvf/codepage/filename
> PDF 文档:/pvf/pdf/filename
当搜索一个命名的文件时,PDFlib 将首先检查提供的文件名称是否引用已知的虚拟文件,然
后试图打开磁盘上相应的命名文件。
虚拟文件的生存时间 一些函数将立即使用虚拟文件中提供的数据,而其他函数将仅读取
文件的部分内容,并在稍后使用其他数据片段。为此,必须密切关注虚拟文件的生存时间。
PDFlib 将在每个虚拟文件上放置一个内部锁,并仅在不再需要相应内容时移除该锁。除非客
户端请求 PDFlib 立即复制数据 (使用 PDF_create_pvf( ) 中的 copy 选项) ,否则,只有当
PDFlib 不再锁定虚拟文件内容时,客户端才能对虚拟文件内容进行修改、删除或释放。
PDFlib 将使用 PDF_delete( ) 自动删除所有虚拟文件。不过,必须总是由客户端释放实际文件
内容 (包含虚拟文件的数据)。
3.1 常规编程 45
3.1.3 资源配置和文件搜索
在大多数高级应用程序中, PDFlib 需要访问字体文件、编码定义、 ICC 颜色配置文件等资
源。为了使 PDFlib 的资源处理功能与平台无关并实现自定义,可以提供一个配置文件用于
描述可用资源以及相应的磁盘文件的名称。除了静态配置文件之外,可以利用 PDF_set_
parameter( ) 在运行时添加资源从而实现动态配置。对于配置文件,我们挖掘出在 Display
PostScript 时代问世并仍被几个系统使用的简单文本格式 (Unix PostScript Resource, UPR)。
不过,我们已经根据自己的需要扩展了原始的 UPR 格式。下面将描述 PDFlib 使用的 UPR 文
件格式。有一种名为 makepsres (经常作为 X Window 系统的一部分进行分发)的实用工
具,此工具可用于从 PostScript 字库外形和量度文件自动生成 UPR 文件。
46 第 3 章: PDFlib 编程
UPR 文件由以下各部分组成:
> 用于标识文件的特殊行。它具备以下形式:
PS-Resources-1.0
> 列出文件中描述的所有资源类别的可选节。每行描述一种资源类别。该列表由带有单个
句点字符的行终止。稍后将描述可用的资源类别。
> 在文件的开头列出的针对每一个资源类别的节。每一节由显示资源类别的行开始,后跟
任意数量的描述可用资源的行。该列表由带有单个句点字符的行终止。每个资源数据行
都包含资源的名称 (必须用引号将等号引起来)。若资源需要一个文件名称,则必须在
等号后面添加此名称。当 PDFlib 搜索资源项中列出的文件时,将应用 SearchPath (请参
见以下内容)。
3.1 常规编程 47
示例 UPR 文件 以下列表提供了一个 UPR 配置文件示例:
PS-Resources-1.0
SearchPath
/usr/local/lib/fonts
C:/psfonts/pfm
C:/psfonts
/users/kurt/my_images
.
FontAFM
Code-128=Code_128.afm
.
FontPFM
Corporate-Bold=corpb___.pfm
Mistral=c:/psfonts/pfm/mist____.pfm
.
FontOutline
Code-128=Code_128.pfa
ArialMT=Arial.ttf
.
HostFont
Wingdings=Wingdings
.
Encoding
myencoding=myencoding.enc
.
ICCProfile
highspeedprinter=cmykhighspeed.icc
.
即使无法读取此文件,也不会引发异常。
> 在 Windows 上, PDFlib 将额外尝试读取注册表项
HKLM\SOFTWARE\PDFlib\PDFlib\7.0.1\resourcefile
可以时常任意重复此调用;资源项将进行累积。
48 第 3 章: PDFlib 编程
在运行时配置资源 除了使用 UPR 文件进行配置以外,还能够通过 PDF_set_parameter( ) 函
数在源代码内直接配置各个资源。此函数采用一个类别名称和相应的资源项作为参数,这正
如同它出现在 UPR 资源文件中此类别的相关节中一样,例如:
p.set_parameter("FontAFM", "Foobar-Bold=foobb___.afm");
p.set_parameter("FontOutline", "Foobar-Bold=foobb___.pfa");
buf = p.get_buffer();
... use the PDF data contained in the buffer ...
p.delete();
以上程序是由客户端决定何时获取缓冲区内容,故被认为是 “主动”模式。此模式可用于
所有受支持的语言绑定。
注: C 和 C++ 客户端不得释放返回的缓冲区。
3.1 常规编程 49
3.1.5 在基于 EBCDIC 的平台上使用 PDFlib
PDF 文件格式中的运算符和结构元素都基于 ASCII,这样就使得在基于 EBCDIC 的平台 (例
如 IBM eServer iSeries 400 和 zSeries S/390)上难以混合文本输出和 PDF 运算符。不过,
我们已精心制作了一个特殊的 PDFlib 大型机版本,以便使基于 ASCII 的 PDF 运算符和
EBCDIC (或其他)文本输出能够混合。 EBCDIC 安全版本的 PDFlib 可用于多种操作系统和
计算机架构。
为了在基于 EBCDIC 的平台上利用 PDFlib 的功能,应使用 EBCDIC 文本格式提供以下项
(更具体而言,对于 iSeries 是在代码页 037 中,而对于 zSeries 是在代码页 1047 中):
> PFA 字体文件、 UPR 配置文件、 AFM 字库量度文件
> 编码和代码页文件
> 用于 PDFlib 函数的字符串参数
> 输入和输出文件名称
> 环境变量 (如果受运行库环境支持)
> PDFlib 错误消息 (除 Java 之外)也将用 EBCDIC 格式生成。
3.1.6 大型文件支持
在本节中,术语 “大型文件”是指大小超过 2 GB 的文件。虽然对于普通用户来说似乎不需
要如此大的文件,但是实际上有些企业应用程序需要创建或处理如包含大量发票或结算单
的单个大型文件。在这类情况下,文件大小可能会超过 2 GB。
PDFlib 支持输出大型文件,也就是说,它可以创建大于 2 GB 的 PDF 输出。PDI 也支持处
理大型输入文件。不过,对大型文件的支持仅适用于操作系统其本身支持大型文件。显然,
所使用的文件系统也必须支持大型文件。请注意, Acrobat 6 及更早的版本不能处理大型文
件。不过, Acrobat 7 完全可以处理大型文件。
50 第 3 章: PDFlib 编程
3.2 页面说明
3.2.1 坐标系统
在 PDFlib 中使用 PDF 的默认坐标系统。默认坐标系统 (或默认用户空间)的原点位于页面
的左下角,并使用 DTP 点作为单位:
1 pt = 1/72 inch = 25.4/72 mm = 0.3528 mm
第一个坐标向右增加,第二个坐标向上增加。PDFlib 客户端程序可以通过旋转、缩放、平移
或斜移更改默认用户空间,从而产生新的用户坐标。这些转换对应的函数分别为 PDF_
rotate( )、 PDF_scale( )、 PDF_translate( ) 和 PDF_skew( )。若已转换坐标系统,则必须根据新
的坐标系统提供图形和文本函数中的所有坐标。在每一页的开头,坐标系统都会重置为默认
坐标系统。
由于 PDF 仅支持其边缘平行于页边缘的链接和域矩形,当坐标系统通过缩放、旋转、平移
或斜移完成转换后,必须修改所提供的矩形。在这种情况下,PDFlib 将计算其边缘平行于页
边缘的最小包容矩形,将其转换到默认坐标,并使用得到的值替换提供的坐标。
总而言之,当 usercoordinates 参数被设置为 true 时,您可以对页面内容和交互元素使用
同一坐标系统。
3.2 页面说明 51
不要被看起来好像页面尺寸存在错误的 PDF 打印输出误导。由于以下一些常见原因,这
些打印输出可能是错误的:
> Acrobat 的打印对话框中的页面缩放:选项具有不同于 None 的设置,这将导致缩放打印
输出。
> 非 PostScript 打印机驱动程序并不总是能够保留所打印对象的精确大小。
52 第 3 章: PDFlib 编程
以下的相对坐标值将在内部修改以匹配自上而下系统:
> 文本 (字体大小为正数)将面向页面顶端;
> 当手册中谈论到矩形、方框等的左下角时,这将被解释为您在页面上实际看到的图形的
左下角;
> 当指定一个旋转角度时,旋转中心仍是用户坐标系统的原点 (0, 0)。顺时针方向旋转的可
视化结果将仍是顺时针方向的。
3.2.2 页面大小
标准页格式 绝 对值 和页 面大 小的 格式 名可 以被 用于 PDF_begin/end_page_ext( ) 中的
width 和 height 选项。后者称作 <format>.width 和 <format>.height,此处的 <format> 是标
准页格式之一 (用小写字母表示,例如 a4.width)。
PDFlib 除了在输出文件中记录这些值以外,将不会使用其中的任何值。默认情况下,PDFlib
根据指定的页面宽度和高度生成 MediaBox,而不会生成任何其他项。以下代码片段将启动
一个新页,并设置裁剪框的四个值:
/* start a new page with custom CropBox */
p.begin_page_ext(595, 842, "cropbox={10 10 500 800}");
3.2 页面说明 53
3.2.3 路径
路径是由任意数目的直线、矩形或曲线构成的一种形状。路径可以包含一些断开的部分(称
作子路径)。以下操作可用于路径处理:
> 描边就是使用客户端提供的绘制参数 (例如颜色、线宽)沿着路径绘制线条。
> 填充就是使用客户端提供的填充参数对路径包围的整个区域涂色。
> 剪切就是以当前剪切区域 (默认情况下为页面大小)与路径包围区域的相交区域替换当
前剪切区域,从而减少用于后续绘制操作的成像区域。
> 断然终止路径将导致不可见的路径,不过该路径仍存在于 PDF 文件中。这种需求极少。
大多数图形函数都利用了当前点的概念,当前点可看作是用于绘图的笔的位置。
3.2.4 模板
PDF 中的模板 PDFlib 支持一种在技术上称为 “form XObjects”的 PDF 功能。不过,由于
此术语与交互式表格存在冲突,因此我们将此功能称为 “模板”。可以将 PDFlib 模板看作
一个离页缓冲区,文本、矢量和图像操作将被重定向到此离页缓冲区中 (而不在常规页上
操作)。模板完成后,就可以像光栅图像一样使用,并可以在任意页上放置任意次数。与图
像一样,模板也可以被几何转换 (例如缩放或斜移) 。当在多个页面上 (或在同一页面上
多次)使用同一模板时,用于构造模板的实际 PDF 运算符只需在 PDF 文件中包含一次,因
此可减小 PDF 输出文件的大小。模板适用于在一些页面上反复出现的元素,例如保持不变
的背景、公司徽标或由 CAD 和地理绘图软件绘制的图形元素。使用模板的其他典型示例包
括裁剪和注册标志或自定义亚洲字形。
54 第 3 章: PDFlib 编程
可以在模板上使用所有文本、图形和颜色函数。不过,构造模板时下列函数禁止使用:
> PDF_load_image( ):由于图像可以在模板定义之外打开,并可以在模板 (但是未打开)
内自由使用,故这并不是一个很大的限制。
> 所有交互函数,因为这些函数必须总是在所出现的文档页上进行定义,而不能作为模板
的一部分生成。
3.2 页面说明 55
3.3 使用颜色
注: PDFlib 参考包含支持的色彩空间的详细列表并附有说明。
3.3.1 图案和平滑着色
作为对纯色的补充,图案和着色是可以用于填充或描边任意对象的特殊种类的颜色。
图案 图案是任意数目的绘图操作组合成的单一实体。这组对象可以被任意的复制 (或平
铺)直至整个区域被填充或描边。使用图案涉及以下步骤:
> 首先,必须在 PDF_begin_pattern( ) 和 PDF_end_pattern( ) 之间定义图案。大多数图形运
算符都可以用于定义图案。
> 由 PDF_begin_pattern( ) 返回的图案句柄可以通过使用 PDF_setcolor( ) 将图案设置为当前
颜色。
图案定义可能会也可能不会包含其自身的颜色规范,这取决于 PDF_begin_pattern( ) 的
painttype 参数。若 painttype 为 1,则图案定义包含其自身的颜色规范并且外观总是保持相
同;若 painttype 为 2,则图案定义禁止包含任何颜色规范。反之,用当前填充或描边颜色
进行填充和描边。
注: 也可以基于平滑着色定义图案 (请参见以下内容)。
着色是两种颜色之间的过渡。总是将第一种颜色作为当前填充颜色;第二种颜色在 PDF_
shading( ) 的 c1、 c2、 c3 和 c4 参数中提供。这些数值将根据第一种颜色的色彩空间 PDF_
setcolor( ) 的描边做解释。
调用 PDF_shading( ) 将返回处理某个着色对象的句柄,可以按以下两种方式使用该句柄:
> 使用 PDF_shfill( ) 填充一个区域。当要填充的对象的几何形状与着色的几何形状相同时,
可以使用此方法。与其名称相反,此函数不仅将填充对象内部,而且还会影响外部。使
用 PDF_clip( ) 可以修改此行为。
> 定义一个可用于填充更多复杂对象的着色图案。这就需要调用 PDF_shading_pattern( ) 以
创建基于着色的图案,并用该图案填充或描边任意对象。
56 第 3 章: PDFlib 编程
3.3.2 专色
PDFlib 支持专色 (技术上称为 PDF 中的分色色彩空间,尽管 “分色”这个术语通常也与印
刷色一起使用),专色可以用于印刷超出印刷混合色范围之外的自定义颜色。专色是根据名
称指定的,在 PDF 中,总是附有一种与专色接近但不完全类似的替代颜色。Acrobat 将使用
此替代颜色进行屏幕显示和输出到不支持专色的设备(例如办公用的普通打印机)。在印刷
时,除了文档中可能使用的任何印刷色之外,还将应用要求的专色。这就需要通过一种称作
“分色”的过程对 PDF 文件进行后处理。
PDFlib 支持各种内置专色库,也支持自定义 (用户定义的)专色。当使用 PDF_
makespotcolor( ) 请求一个专色名称时, PDFlib 首先将检查在其内置库中是否可以找到请求
的专色。如果能够找到, PDFlib 将对替代颜色使用内置值。否则,将假定该专色为用户定
义的颜色,客户端必须提供适当的替代颜色值 (通过当前颜色)。专色可以减淡,即可以
与 0 和 1 之间的百分比一起使用。
默认情况下,不能使用自定义替代值重新定义内置专色。不过,可以使用 spotcolorlookup
参数更改此行为。这对实现与早期应用程序 (可能使用了不同的颜色定义)的兼容性,以
及对于无法处理 PANTONE 颜色的 PDFlib 的 Lab 替代值的工作流来说,会很有用。
当选定 PDF/X 或 PDF/A 规范等级后,PDFlib 将为内置专色自动生成适合的替代颜色(请
参见第 191 页上的第 9.4 节 “用于印刷生产的 PDF/X”)。对于自定义专色,用户需要负责
提供与选定的 PDF/X 或 PDF/A 规范等级兼容的替代颜色。
3.3 使用颜色 57
表 3.3 PDFlib 中内置的 PANTONE 专色库
颜色库名称 采样色名称 备注
PANTONE solid coated PANTONE 185 C
PANTONE 色彩桥 CMYK EURO PANTONE 185 EC 替代 PANTONE solid to process coated EURO
58 第 3 章: PDFlib 编程
PDFlib 商业用户可以向我们索取一个列出了全部 HKS 专色名称的文本文件。
专色名称区分大小写;如示例中所示,使用大写字母。如示例中所示,必须总是在色板
名称中提供 HKS 前缀。通常,必须根据以下方案构造 HKS 专色名称:
HKS <id> <paperstock>
3.3 使用颜色 59
ICC 色彩特征描述文件 International Color Consortium (ICC)1 定义了一种用来指定输入
和输出设备的颜色特征的文件格式。这些 ICC 色彩特征描述文件已被作为产业标准,受到所
有主要的色彩管理系统和应用程序厂商的支持。在以下一些领域,PDFlib 支持带 ICC 色彩特
征描述文件的颜色管理:
> 为页面上文本和矢量图形定义基于 ICC 的色彩空间。
> 处理嵌入到导入的图像文件中的 ICC 色彩特征描述文件。
> 将一 ICC 色彩特征描述文件用于导入的图像 (可能会覆盖已嵌入图像中的 ICC 色彩特征
描述文件)。
> 定义默认色彩空间以便将灰度、 RGB 或 CMYK 数据映射到基于 ICC 的色彩空间。
> 通过外部 ICC 色彩特征描述文件定义 PDF/X 或 PDF/A 定义输出方法。
1. 请参见 www.color.org
60 第 3 章: PDFlib 编程
可接受的 ICC 色彩特征描述文件 可接受的 ICC 色彩特征描述文件的类型取决于提供给
PDF_load_iccprofile( ) 的 usage 参数:
> 若 usage=outputintent,则在 PDF/X 模式下仅接受输出设备 (打印机)描述文件,在
PDF/A 模式下可接受任何描述文件。
> 若 usage=iccbased,则接受输入设备、显示设备和输出设备(扫描仪、显示器和打印机)
描述文件以及色彩空间转换描述文件。可以在灰色、 RGB、 CMYK 或 Lab 色彩空间中指
定这些配置文件。
3.3 使用颜色 61
将设备颜色映射到基于 ICC 的默认色彩空间 PDF 提供了一个功能,可以将页面说明中的
设备相关的灰色、RGB 或 CMYK 颜色映射到与设备无关的颜色。即对与设备相关的颜色附加
精确的比色规范。这一颜色值映射可通过提供 DefaultGray、 DefaultRGB 或 DefaultCMYK
色彩空间定义来实现。在 PDFlib 中,可以通过设置 defaultgray、 defaultrgb 或 defaultcmyk
参数并提供 ICC 色彩特征描述文件句柄作为相应的值,完成此操作。以下示例将 sRGB 色彩
空间设置为文本、图像和矢量图形的默认 RGB 色彩空间:
/* sRGB is guaranteed to be always available */
icchandle = p.load_iccprofile("sRGB", 0, "usage=iccbased");
p.set_value("defaultrgb", icchandle);
62 第 3 章: PDFlib 编程
3.4 交互元素
3.4.1 创建交互元素的示例
本节解释如何创建交互元素 (如书签、表单域和注释)。图 3.1 显示了包含我们将在本节中
创建的所有交互元素的结果文档。该文档包含以下交互元素:
> 在页面的右上角,文本 www.kraxi.com 处有一个不可见的 Web 链接 www.kraxi.com 。单
击此区域将打开一个相关网页。
> Web 链接之下有一个文本类型的灰色表单域。通过使用 JavaScript 代码,将自动使用当
前日期填充该表单域。
> 红色图钉包含带有一个附件的注释。单击此图钉将打开附加的文件。
> 在页面的左下角,有一个带有打印机符号的按钮类型的表单域。单击此按钮将执行
Acrobat 的菜单项 “文件” -> “打印”。
> 该导航页包含书签“Our Paper Planes Catalog”。单击此书签将打开另一页 PDF 文档。
图 3.1
包含交互元素的文档
3.4 交互元素 63
normalfont = p.load_font("Helvetica", "unicode", "");
p.begin_page_ext(pagewidth, pageheight, "topdown");
p.end_page_ext("");
单击书签将显示目标文档中的页面的指定部分。
64 第 3 章: PDFlib 编程
带有文件附件的注释 在 下 一 个 示 例 中,我 们 创 建 一 个 文 件 附 件。我 们 先 创 建 一 个
FileAttachment 类型的注释。filename 选项指定附件的名称,选项 mimetype image/gif 指定
附件的类型 (MIME 是一种用于给文件内容分类的常用约定) 。注释将显示为一个红色
(annotcolor {rgb 1 0 0}) 的图钉 (iconname pushpin),并带有一个工具提示 (contents {Get the
Kraxi Paper Plane!})。注释不进行打印 (display noprint):
String optlist =
"filename=kraxi_logo.gif mimetype=image/gif iconname=pushpin " +
"annotcolor={rgb 1 0 0} contents={Get the Kraxi Paper Plane!} display=noprint";
用于打印的按钮表单域 下一个示例创建可用于打印文档的按钮表单域。在第一个版本
中,我们将对按钮添加一个标题;在以后的版本中,我们将使用打印机符号,而不用标题。
我们先创建一个 Named 类型的操作 (在 Acrobat 中:执行菜单项)。同样,我们必须指定
标题的字体:
print_action = p.create_action("Named", "menuname=Print");
button_font = p.load_font("Helvetica-Bold", "unicode", "");
3.4 交互元素 65
现在我们通过用一个小的打印机图标替换文本 Print 的方式扩展第一个版本的按钮。为了完
成此操作,在创建页之前,我们加载相应的图像文件 print_icon.jpg 作为模板。使用 icon 选
项,我们可以对按钮域指定模板句柄 print_icon,并创建类似于以上代码的表单域:
print_icon = p.load_image("auto", "print_icon.jpg", "template");
if (print_icon == -1)
{
/* Error handling */
return;
}
p.begin_page_ext(pagewidth, pageheight, "");
...
String optlist = "action={up " + print_action + "} icon=" + print_icon +
" tooltip={Print the document} font=" + button_font;
简单文本域 现在我们在页面的右上角附近创建一个文本域。用户将能够在此域中输入当
前日期。我们获取一个字体句柄,并创建一个名为 date 且带有灰色背景的 textfield 类型的
表单域:
textfield_font = p.load_font("Helvetica-Bold", "unicode", "");
String optlist = "backgroundcolor={gray 0.8} font=" + textfield_font;
p.create_field(left_x, left_y, right_x, right_y, "date", "textfield", optlist);
默认情况下,字体大小是 auto,这意味着初始的域高度将用作为字体大小。当输入文本达
到域的末尾时,将减少字体大小以便使文本总是适合域大小。
最后,我们按照上面的操作创建文本域。只要页面处于打开状态,就将用当前日期自动填充
该页面:
textfield_font = p.load_font("Helvetica-Bold", "unicode", "");
String optlist = "backgroundcolor={gray 0.8} font=" + textfield_font;
p.create_field(left_x, left_y, right_x, right_y, "date", "textfield", optlist);
66 第 3 章: PDFlib 编程
3.4.2 文本域的格式化选项
在 Acrobat 中,可以指定用于格式化文本域内容 (例如货币金额、日期或百分比)的各种
选项。此操作可以通过由 Acrobat 使用的自定义 JavaScript 代码完成。PDFlib 不直接支持这
些格式化功能,因为在 PDF 参考中未指定这些功能。不过,为了 PDFlib 用户的利益,我们
在下面提供了一些信息,让您能够通过使用 PDF_create_field( ) 的 action 选项提供简单
JavaSscript 代码片段实现文本域的格式化选项。
为了对文本域应用格式化设置, JavaScript 片段将被附加到文本域作为 keystroke 和
format 操作。JavaScript 代码调用一些内部 Acrobat 函数,这些函数的参数可控制格式化设
置的细节。
以下示例创建两个 keystroke 和 format 操作,并将它们附加到一个表单域,以便用两个
小数位数和 EUR 货币标识符设置域内容的格式:
keystroke_action = p.create_action("JavaScript",
"script={AFNumber_Keystroke(2, 0, 3, 0, \"EUR \", true); }");
format_action = p.create_action("JavaScript",
"script=AFNumber_Format(2, 0, 0, 0, \"EUR \", true); }");
日期 AFDate_KeystrokeEx(cFormat), AFDate_FormatEx(cFormat)
时间 AFTime_Keystroke(tFormat), AFTime_FormatEx(cFormat)
特殊 AFSpecial_Keystroke(psf), AFSpecial_Format(psf)
negStyle 突出负数的方式:
0 正常
1 使用红色文本
2 显示括号
3 显示括号并使用红色文本
3.4 交互元素 67
表 3.5 JavaScript 格式化函数的参数 (续)
parameters 说明和可能的值
strCurrency 要使用的货币字符串,例如表示欧元符号的 “\u20AC”
bCurrency- false 不预置货币符号
Prepend true 预置货币符号
cFormat 日期格式字符串。它可能包含以下格式占位符或下面为 tFormat 列出的时间格式:
d 日
dd 带有前导零的日
ddd 缩写的星期
m 用数字表示的月份
mm 用数字表示的带有前导零的月份
mmm 缩写的月份名称
mmmm 完整的月份名称
yyyy 用四位数字表示的年份
yy 年份的后两位数字
tFormat 时间格式字符串。它可能包含以下格式占位符:
h 小时 (0-12)
hh 带有前导零的小时 (0-12)
H 小时 (0-24)
HH 带有前导零的小时 (0-24)
M 分钟
MM 带有前导零的分钟
s 秒
ss 带有前导零的秒
t 'a' 或 'p'
tt 'am' 或 'pm'
psf 描述几种附加格式:
0 邮政编码
1 邮政编码 + 4
2 电话号码
3 身份证号码
68 第 3 章: PDFlib 编程
4 Unicode 与旧有编码
4.1 概述
PDFlib 中的 Unicode 支持 PDFlib 的文 本处 理基 于 Unicode 标 准1,该标 准几 乎与 ISO
10646 相同。由于最新的开发环境支持 Unicode 标准,因此我们的目标是在创建 PDF 输出
时尽可能轻松的使用 Unicode 字符串。但是不使用 Unicode 的开发人员不必将其应用程序
转换到 Unicode,因为也可以使用旧有的编码。尤其是, PDFlib 支持传统的 8 位编码 (例
如 Windows ANSI、 Latin-1)和多字节 CJK 编码 (例如 Shift-JIS、 Big 5)。
尽管大多数文本将在 PDF 页上创建,但 PDFlib 的字符串处理概念同样可应用于其他区
域,例如用于交互功能的文本 (如书签)。
许多印刷和联机出版物涵盖了 Unicode 标准;在第 70 页上的第 4.2 节 “几个重要的
Unicode 概念”中总结了一些重要概念。
1. 请参见 www.unicode.org
4.1 概述 69
4.2 几个重要的 Unicode 概念
字符和字形 处理文本时,必须清晰地区分以下概念:
> 字符是在一种语言中传递信息的最小单位。 常见示例有拉丁字母表中的字母、中文象形
文字和日文音节。字符具有意义:它们是语义实体。
> 字形是一些不同的图形变体,表示一个或多个特定的字符。 字形具有外观: 它们是表示
实体。
在字符与字形之间没有一对一关系。例如,连字是一种简单的字形,它由两个或多个单独字
符表示。另一方面,根据上下文的不同,一个特定的字形可以被用来表示不同的字符 (有
些字符外形相同,请参见图 4.1)。
Characters Glyphs
图 4.1
U+2167 ROMAN NUMERAL EIGHT or 字形与字符的关系
U+0056 V U+0049 I U+0049 I U+0049 I
70 第 4 章: Unicode 与旧有编码
Unicode 编码方案和字节顺序标记 (BOM) 各种计算机架构的字节顺序不同,字节顺序即
是构成较大值 (16 或 32 位)的字节先存储在最高字节 (big-endian)还是最低字节先存
(little-endian) 。big-endian 架构的一个常见示例就是 PowerPC,而 x86 架构是 little-
endian。由于 UTF-8 和 UTF-16 是基于大于单字节的值,就关系到字节顺序的问题。编码方
案(请注意与上面的编码形式的差异)指定编码形式及字节顺序。例如,UTF-16BE 代表 big-
endian 字节顺序的 UTF-16。如果事先未知字节顺序,可以借助码位 U+FEFF 来指定,它称
作字节顺序标记 (BOM)。尽管在 UTF-8 中不要求 BOM,它还是可以存在,并且还可以用于
将字节流标识为 UTF-8。表 4.1 列出了各种编码形式下 BOM 的表示形式。
UTF-16 big-endian FE FF þÿ
UTF-16 little-endian FF FE ÿþ
UTF-32 little-endian FF FE 00 00 ÿþ ? ?1
1. 对于空字节,没有标准图形表示形式。
72 第 4 章: Unicode 与旧有编码
Unicode 转换函数 若您必须处理 Unicode 之外的其他编码的字符串,则在将其传递到
PDFlib 之前必须将它们转换成 Unicode。第 23 页上的第 2 章 “PDFlib 语言绑定”中有关特
定语言的各节提供了关于常见语言环境下可用的 Unicode 字符串转换方法的详细信息。
名称字符串 这些字符串的解释与页面说明字符串的解释稍微不同。默认情况下,使用宿
主编码解释名称字符串。不过,若它是以 UTF-8 BOM 开始的,则将其解释为 UTF-8 (或
者,若它是以 EBCDIC UTF-8 BOM 开始,则将其解释为 EBCDIC UTF-8)。若
usehypertextencoding 参数为 true,则 hypertextencoding 中指定的编码将同样适用于名称
字符串。例如,此功能可以用于指定 Shift-JIS 中的字体或文件名。
在 C 中,对于 UTF-8 字符串, length 参数必须为 0。若此参数不等于 0,则字符串将被
解释为 UTF-16。在不识别 Unicode 的所有语言绑定中,在 API 函数中没有 length 参数,且
必须始终以 UTF-8 格式提供名称字符串。为了创建 Unicode 名称字符串,可以使用 PDF_
utf16_to_utf8( ) 实用工具函数以创建 UTF-8 (请参见以下内容)。
表 4.3 编码和文本格式的关系
[hypertext]encoding textformat=bytes textformat = utf8, utf16, utf16be, or utf16le
所有字符串类型:
auto 请参见第 76 页上的 “自动编码”一节
U+XXXX 8 位代码将添加到偏移量 XXXX 处 根据选定的 Unicode 偏移量将 Unicode 值转换为 8 位代码
以对 Unicode 值寻址
仅内容字符串:
74 第 4 章: Unicode 与旧有编码
选项列表中的字符串 选项列表内的字符串需要特别注意,因为在不识别 Unicode 的语言
绑定中这些字符串不能表示为 UTF-16 格式的 Unicode 字符串,而只能表示为字节字符串。
为此, UTF-8 用于 Unicode 选项。 PDFlib 通过在选项开始处寻找 BOM 来决定解释方式。
BOM 将用于确定字符串的格式,而字符串的类型 (前面定义的内容字符串、超文本字符串
或名称字符串)将用于确定适当的编码。更加确切地说,将按如下所示解释字符串选项:
> 若选项以 UTF-8 BOM 开头 (0xEF 0xBB 0xBF),它将被解释为 UTF-8。在基于 EBCDIC 的
系 统上:若 选项 以 EBCDIC UTF-8 BOM 开头 (0x57 0x8B 0xAB) 它 将被 解释 为 EBCDIC
UTF-8。若找不到 BOM,将根据字符串的类型解释字符串:
> 内容字符串将根据适用的编码选项或对应字体的编码 (只要存在任何一个)进行解释。
> 超文本字符串将根据 hypertextencoding 参数或选项进行解释。
> 若 usehypertextencoding=true,则名称字符串将根据 hypertext 设置进行解释,否则将按
宿主编码。
请注意在选项列表中,字符串内的字符 { 和 } 需要特殊处理,并且若在字符串选项中使用这
些字符,必须在前面加一个 \ 符。这一要求同样适用于旧有编码,例如 Shift-JIS:每次出现
字节值 0x7B 和 0x7D 时,必须在前面加上 0x5C。为此,建议对选项使用 UTF-8 (而不要使
用 Shift-JIS 和其他旧有编码)。
76 第 4 章: Unicode 与旧有编码
表 4.4 用于预定义编码的字形在一些类别的字体中的可用性:一些语言无法用 Acrobat 的核心字体表示
Acrobat 6/7/8 2
PS Level 1/2,
Acrobat 4/51
“大字体”5
PostScript 3
OpenType
Pro 字体4
核心字体
TrueType
字体3
代码页 受支持的语言
4.4 8 位编码 77
分支系统代码页 可以指示 PDFlib 从系统中获取代码页定义并将其适当转换以供内部使
用。由于这种方法将使您不必亲自需要实现代码页定义,因而使用上很方便。这种方法不必
再向 PDF_load_font( ) 提供内建编码或用户定义的编码的名称,只需使用系统已知的编码名
称即可。此功能仅在选定的平台上可用,并且编码字符串的语法是特定于平台的:
> 在 Windows 上,编码名称是 cp<number>,此处 <number> 是指系统上安装的任何单字节
代码页的数目 (有关多字节 Windows 代码页的更多信息,请参见第 111 页上的第 5.6.2 节
“自定义 CJK 字体”):
font = p.load_font("Helvetica", "cp1250", "");
> 在带有 USS 或 MVS 的 IBM eServer zSeries 上,可以使用任何 Coded Character Set
Identifier (CCSID)。必须提供 CCSID 作为字符串,并且 PDFlib 将提供的代码页名称完全
传递给系统 (对名称不作任何更改):
font = p.load_font("Helvetica", "IBM-273", "");
编码文件只是逐行列出字形名称和编号。以下节选显示了编码定义的开头部分:
% Encoding definition for PDFlib, based on glyph names
% name code Unicode (optional)
space 32 0x0020
exclam 33 0x0021
...
78 第 4 章: Unicode 与旧有编码
更合乎规范的做法是按照以下规则管理编码或代码页文件的内容:
> 注释由百分比 “%”字符引入,并在行的末尾终止。
> 每一行的第一项是 PostScript 字形名称,或是一个由 0x 前缀和四位数的十六进制数字
(大写或小写)组成的十六进制 Unicode 值。其后紧跟空白和一个十六进制 (0xoo-0xFF)
或十进制 (0-255) 字符代码。有时,基于名称的编码文件可能包含带有相应 Unicode 值的
第三列。
> 编码文件中未提及的字符代码假定为未定义的代码。或者,可以将 Unicode 值 0x0000
或字符名称 .notdef 提供给未使用的插槽。
4.4 8 位编码 79
4.5 中文、日文和韩文文本编码
在历史上,不同的标准化团体和公司已开发出大量 CJK 编码方案。幸运地是,默认情况下,
Acrobat 和 PDF 支持所有现行编码。由于编码的概念对于 CJK 文本相对于拉丁文本来说复杂
很多,所以仅使用简单的 8 位编码已不够。 PostScript 和 PDF 使用字符集合和字符映射
(CMap) 的概念来组织字体中的字符。
80 第 4 章: Unicode 与旧有编码
表 4.5 用于日文、中文和韩文文本的预定义 CMap (摘自 PDF Reference)
区域 CMap 名称 字符集和文本格式
简体中文 UniGB-UCS2-H 用于 Adobe-GB1 字符集合的 Unicode (UCS-2) 编码
UniGB-UCS2-V
UniGB-UTF16-H 用于 Adobe-GB1 字符集合的 Unicode (UTF-16BE) 编码。包含对 GB18030-2000 字
UniGB-UTF16-V 符集中所有字符的映射。
GB-EUC-H Microsoft 代码页 936 (字符集 134), GB 2312-80 字符集, EUC-CN 编码
GB-EUC-V
GBpc-EUC-H Macintosh, GB 2312-80 字符集, EUC-CN 编码, Script Manager 代码 2
GBpc-EUC-V
GBK-EUC-H, -V Microsoft 代码页 936 (字符集 134), GBK 字符集, GBK 编码
GBKp-EUC-H 与 GBK-EUC-H 一样,但将半宽拉丁字符替换为比例字符,并将代码 0x24 映射
GBKp-EUC-V 为美元符号 ($) 而非人民币元符号 (¥)。
GBK2K-H, -V GB 18030-2000 字符集,混合的 1 字节、 2 字节 和 4 字节编码
繁体中文 UniCNS-UCS2-H 用于 Adobe-CNS1 字符集合的 Unicode (UCS-2) 编码
UniCNS-UCS2-V
UniCNS-UTF16-H 用于 Adobe-CNS1 字符集合的 Unicode (UTF-16BE) 编码。包含对 HKSCS-2001 的
UniCNS-UTF16-V 所有字符 (2 字节和 4 字节字符代码)的映射
B5pc-H, -V Macintosh, Big 5 字符集, Big 5 编码, Script Manager 代码 2
HKscs-B5-H 香港 SCS (增补字符集),对 Big 5 字符集和编码的扩充
HKscs-B5-V
ETen-B5-H, -V Microsoft 代码页 950 (字符集 136),带 ETen 扩展名的 Big 5
ETenms-B5-H 与 ETen-B5-H 一样,但将半宽拉丁字符替换为比例字符
ETenms-B5-V
CNS-EUC-H, -V CNS 11643-1992 字符集, EUC-TW 编码
日文 UniJIS-UCS2-H, -V 用于 Adobe-Japan1 字符集合的 Unicode (UCS-2) 编码
UniJIS-UCS2-HW-H 与 UniJIS-UCS2-H 一样,但是用半宽窗体替换成比例的拉丁字符
UniJIS-UCS2-HW-V
UniJIS-UTF16-H 用于 Adobe-Japan1 字符集合的 Unicode (UTF-16BE) 编码。在 JIS X 0213:1000 字
UniJIS-UTF16-V 符集中包含所有字符的映射。
83pv-RKSJ-H Mac,带 KanjiTalk6 扩展名的 JIS X 0208, Shift-JIS,脚本管理器代码 1
90ms-RKSJ-H Microsoft 代码页 932 (字符集 128),带 NEC 和 IBM 扩展名的 JIS X 0208 字符集
90ms-RKSJ-V
90msp-RKSJ-H 与 90ms-RKSJ-H 一样,但是用成比例的窗体替换半宽拉丁字符
90msp-RKSJ-V
90pv-RKSJ-H Mac,带 KanjiTalk7 扩展名的 JIS X 0208, Shift-JIS,脚本管理器代码 1
Add-RKSJ-H, -V 带 Fujitsu FMR 扩展名、 Shift-JIS 编码的 JIS X 0208 字符集
EUC-H, -V JIS X 0208 字符集, EUC-JP 编码
Ext-RKSJ-H, -V 带 NEC 扩展名、 Shift-JIS 编码的 JIS C 6226 (JIS78) 字符集
H, V JIS X 0208 字符集, ISO-2022-JP 编码
韩文 UniKS-UCS2-H, -V 用于 Adobe-Korea1 字符集合的 Unicode (UCS-2) 编码
UniKS-UTF16-H, -V 用于 Adobe-Korea1 字符集合的 Unicode (UTF-16BE) 编码
KSC-EUC-H, -V KS X 1001:1992 字符集, EUC-KR 编码
KSCms-UHC-H Microsoft 代码页 949 (字符集 129), KS X 1001:1992 字符集加上 8822 附加
KSCms-UHC-V hangul,统一 Hangul 代码 (UHC) 编码
KSCms-UHC-HW-H 与 KSCms-UHC-H 一样,但是用半宽窗体替换成比例的拉丁字符
KSCms-UHC-HW-V
KSCpc-EUC-H Mac,具有 Mac OS KH 扩展的 KS X 1001:1992, Script Manager 代码 3
4.5 中文、日文和韩文文本编码 81
自定义 CJK 字体的代码页 在 Windows 上,PDFlib 支持系统上安装的任何 CJK 代码页。在
其他平台上,可使用表 4.6 中列出的代码页。这些代码页将通过内部映射到相应的 CMap
(例如将 cp932 映射到 90ms-RKSJ-H/V)。由于这一映射的原因,必须配置适当的 Cmap(请
参见上述内容)。textformat 参数必须设置为 auto,并且必须使用与选定的代码页兼容的格
式提供文本。
82 第 4 章: Unicode 与旧有编码
4.6 字符和字形寻址
一些环境要求程序员使用 8 位编码编写源代码 (例如 winansi、 macroman 或 ebcdic)。若
不将文本中的所有字符更改为多字节编码,则很难在 8 位编码的文本中包含独立的 Unicode
字符。在这种情况下,为了方便开发人员, PDFlib 支持若干表示文本的辅助方法。
4.6.1 转义序列
PDFlib 支持通过转义序列 (在许多编程语言中支持类似的序列)在文本字符串内轻松嵌入
任意值的方法。例如,可以使用文本块的默认文本中的 \t 序列来包含通过键盘无法直接输
入的制表符。类似地,转义序列对于在符号字体中表示代码很有用。
转义序列是创建某些字节值的一种快捷方式。从转义序列创建的值将始终被解释为选定
的编码 (与始终解释为的 Unicode 字符引用不同)。表 4.7 中列出了转义序列解析后对应的
字节值;有些结果在 ASCII 和 EBCDIC 平台上各不相同。使用转义序列只能表示 0-255 范围
内的字节值。
表 4.7 字节值的转义序列
Mac、 Windows、 EBCDIC 平台
序列 Linux、 Unix (zSeries/iSeries) 常见解释
\f 0C 0C 换页符
\n 0A 15/25 换行符
\r 0D 0D 回车符
\t 09 05 水平制表符
\v 0B 0B 垂直制表符
\\ 5C E0 反斜线
\xNN 指定字节值的两个十六进制数字
\NNN 指定一个字节值的三个八进制数字 (最高 \377)
默认情况下,将不会转换转义序列;若想使用所有内容字符串中的转义序列,则必须将
escapesequence 参数或选项明确设置为 true:
p.set_parameter("escapesequence", "true");
在 BOM 检测之后、转换成目标格式之前,将评估所有内容字符串、超文本字符串和名称字
符串中的转义序列。若 textformat= utf16le 或 utf16be,则根据所选格式必须将转义序列表
示为双字节值。若 textformat=utf8,结果代码将无法转换为 UTF-8。
若无法解析某个转义序列 (例如后跟无效十六进制数字的 \x),将引发异常。对于内容
字符串,此行为由 glyphcheck 和 errorpolicy 设置控制。
4.6 字符和字形寻址 83
4.6.2 字符引用和字形名称引用
HTML 样式字符引用 PDFlib 支持 HTML 4.01 中定义的所有数字字符引用和字符实体引
用。可以用十进制或十六进制表示法提供数字字符引用;它们将始终被解释为 Unicode 值。
默认情况下,将不会转换字符引用;若想使用所有内容字符串中的字符引用,则必须将
charref 参数或选项明确设置为 true:
p.set_parameter("charref", "true");
以下是有效的字符引用以及对得到的字符的说明的示例:
­ soft hyphen
­ soft hyphen
­ soft hyphen
å letter a with small circle above (decimal)
å letter a with small circle above (hexadecimal, lowercase x)
å letter a with small circle above (hexadecimal, uppercase X)
€ Euro glyph (hexadecimal)
€ Euro glyph (decimal)
€ Euro glyph (entity name)
< less than sign
> greater than sign
& ampersand sign
Α Greek Alpha
字形名称引用 字 体 可 能 会 包 含 不 能 直 接 访 问 的 字 形,原 因 是 不 能 预 先 知 道 相 应 的
Unicode 值 (例如 PUA 分配)或者是因为字体中甚至没有 Unicode 值。虽然字体中的所有
字形均可通过 glyphid 编码寻址,不过这样做会很麻烦,不适合 Unicode 工作流程。于是可
以使用一种有用的工具:字形名称引用。它与字符引用类似,但使用略微不同的语法,通过
名称来引用字形 (请注意,在示例中,第一个句点字符属于语法的一部分,而第二个属于
字形名称的一部分):
&.T.swash;
&.orn.15;
默认情况下,将不会转换字形名称引用;若想使用所有内容字符串中的字形名称引用,则必
须将 charref 参数或选项明确设置为 true:
p.set_parameter("charref", "true");
1. 请参见 www.w3.org/TR/REC-html40/charset.html#h-5.3
84 第 4 章: Unicode 与旧有编码
表 4.8 Textflow 中的控制字符及其含意
Unicode 字符 实体名称 相当于 在使用 Unicode 兼容字体的 Textflow 中的含意
Textflow
选项
U+0020 SP, space space 对齐单词并分行
U+00A0 NBSP, nbsp (none) (非分行空格)将不分行的空格字符
U+0009 HT, hortab (none) 水平制表位:将根据 ruler、 tabalignchar 和 tabalignment 选
项进行处理
U+002D HY, hyphen (none) 用于断词的分隔符字符
U+00AD SHY, shy (none) (自动连字符)提供断词的机会,仅在分行符处可见
U+000B VT, verttab nextline (新行)强制一个新行
U+2028 LS, linesep
U+000A LF, linefeed next- (新段落)与 nextline 效果相同;另外 parindent 选项将影响
U+000D CR, return paragraph 新行。
U+000D and CRLF
U+000A
U+0085 NEL, newline
U+2029 PS, parasep
U+000C FF, formfeed return PDF_fit_textflow( ) 将停止,然后返回字符串 _nextpage。
若无法找到在字形名称引用中指定的名称所对应的字形,将引发异常。对于内容字符串,此
行为由 glyphcheck 和 errorpolicy 设置控制。字形名称引用无法用于 glyphid 或 builtin 编码。
使用字符和字形名称引用 字符和字形名称引用可以在所有的内容字符串、超文本字符串
和名称字符串中使用,例如在使用 show 或 Textflow 函数放置在页上的文本中使用,以及在
提供给超文本函数的文本中使用。在 builtin 编码的文本中不处理字符引用。不过,您可以
通过使用 unicode 编码来使用符号字体的字形名称引用。在这种情况下,所有的字形都必须
通过名称寻址;不能混淆数值代码和字形名称。
通过将 charref 选项提供给 PDF_add/create_textflow( ) (直接提供或作为内嵌选项提供) 、
PDF_fit_textline( ) 或 PDF_fill_textblock( ),也可以为 Textflow 处理启用字符和字形名称引用。
当启用字符和字形名称引用时,可以在 8 位编码的文本中提供数字引用、实体引用和字
形名称引用:
p.set_parameter("charref", "true");
font = p.load_font("Helvetica", "winansi", "");
if (font == -1) { ...}
p.setfont(font, 24);
p.show_xy("Price:500€", 50, 500);
4.6 字符和字形寻址 85
在选项列表中将不会替换字符引用,但是将在选项中使用 Unichar 数据类型 (不含 “&”和
“;”修饰)识别字符引用。此识别将始终启用;它不由 charref 参数或选项控制。
当在未引入数字引用、字符引用或字形名称引用的文本中找到 & 字符时,若
glyphcheck=error,将引发异常。换言之,通过设置 glyphcheck=none,可以在同一文本中
使用字符或字形名称引用和独立的 & 字符。
4.6.3 字形检查和替代
内容字符串将用特定的字体显现在页面上。不过,不存在包含所有最新 Unicode 标准中包
含的字符的单一字体。尽管获取合适的字体显然是 PDFlib 用户的任务,但是,如果原始字
形在字体中不可用,则 PDFlib 会尝试通过使用可见的相似字形替换某些字符来解决一些常
见问题。这一处理的细节可由 glyphcheck 和 errorpolicy 参数和选项,以及 PDF_load_font( )
的 replacementchar 选项进行控制。
glyphcheck 参数和选项为所选字体不包含用于文本输出的内容字符串中所含某一代码的
任何字形的情况提供了控制:
> glyphcheck=none:快速,但不安全;文本输出可能包含缺失的字形符号(通常是一个中
空或画叉的矩形);
> glyphcheck=replace:无提示方法;可创建最适当的文本输出 (请参见以下内容);
> glyphcheck=error:最安全的方法;将引发异常以提请用户注意出现了问题。 但因为异
常,输出文档将不再可用。
表 4.9 各种编码的字形检查详细信息
Unicode 其他
glyphcheck 8 位编码 内建 字形 unicode CMap CMap
字形替换 若 glyphcheck=replace,将递归替换不可用字形,如下所示:
> 根据 Unicode 值从 PDFlib 的内部替换表选择类似字形。以下列表 (不完整)包含一些
字形映射。若列表中的第一个字符在字体中不可用,则使用第二个字符自动替换它:
U+00A0 (非分行空格) U+0020 (空格)
U+00AD (自动连字符) U+002D (减号连字符)
U+2010 (连字符) U+002D (减号连字符)
U+03BC (希腊小写字母 MU) U+00C5 (微符号)
U+212B (埃符号) U+00B5 (上部带有一个圆圈的拉丁大写字母 A Ý)
U+220F (元积 ) U+03A0 (希腊大写字母 PI)
U+2126 (欧姆符号) U+03A9 (希腊大写字母 OMEGA)
86 第 4 章: Unicode 与旧有编码
除了内部表之外,若全宽变体在字体中不可用,则使用相应的 ISO 8859-1 字符 (即
U+0021 到 U+007E)替换从 U+FF01 到 U+FF5E 区间的全宽字符。
> 将 Unicode 花饰字符分解为其组成字形 (例如,用 U+0066 U+0066 替换 U+FB00)
> 根据字形名称使用相同的 Unicode 语义选择字形 (例如用 A 替换 A.swash,用 f, f, i 序列
替换 f_f_i)
4.6.4 检查字形可用性
使用 PDF_info_font( ),您可以检查某一特定字体是否包含应用程序所需的字形。以下代码示
例将检查在字体中是否包含 Euro 字形 (假定先前已经使用 PDF_load_font( ) 成功加载了该
字体)。请注意,unicode 选项要求提供一个 Unichar,可以为 Unichar 使用字形名称引用,
无需 & 和 ; 修饰。这比检查字形名称安全,字形名称可能是 euro、 Euro 或其他:
if (p.info_font(font, "code", "unicode=euro") == -1)
{
/* no glyph for Euro sign available in the font */
}
4.6 字符和字形寻址 87
88 第 4 章: Unicode 与旧有编码
5 字体处理
5.1 字体和编码概述
字体处理是文档格式的一个最复杂的方面。在本节中,我们将总结 PDFlib 的有关字体和编
码处理的主要特征。
5.1.1 支持的字体格式
PDFlib 支持多种字体类型。本节总结 PDFlib 支持的字体类型,并对这些格式中的一些最重
要的方面加以说明。
5.1 字体和编码概述 89
5.1.2 字体编码
页面上文本的所有字体必须与适当的编码一起使用。编码定义 PDFlib 和 Acrobat 将如何解
释字符串中的实际字节,以及如何将这些字节转换成页面上的文本。 PDFlib 支持多种编码
方法。
所有受支持的编码都可以在一个文档中任意混合。您甚至可以对单个字体使用不同的编
码,尽管这种情况很少出现。
注: 并非所有编码都可以用于某一给定的字体。用户需要负责确保该字体包含某一特定编码所
需的所有字符。这甚至对 Acrobat 的核心字体都是一个问题 (请参见表 4.4)。
90 第 5 章: 字体处理
宽字符寻址 除了 8 位编码之外,也支持其他各种功能更为强大且不需遵从 256 个字符限
制的寻址方案。
> 通过 unicode 编码关键字可以完全基于 Unicode 的寻址。在这种情况下,客户端直接为
PDFlib 提供 Unicode 字符串。可以根据一些标准方法(例如 UTF-16,UTF-8)和字节顺
序 (little-endian 或 big-endian)格式化 Unicode 字符串。
> 各种中文、日文和韩文标准的基于 CMap 的寻址。 PDFlib 支持所有 Acrobat 支持的
CMap (请参见第 110 页上的第 5.6 节 “中文、日文和韩文字体”)。
> 通过 glyphid 编码关键字的 TrueType 和 OpenType 字体的字形 ID 寻址。这对高级文本
处理应用程序非常有用,因为这类应用程序需要不通过参考任何特殊编码方案即可访问
字体的各个字形,或必须对没有任何 Unicode 映射的字形进行寻址。可以使用 PDF_info_
font( ) 中的 maxcode 关键字查询字体中的有效字形 ID 的数目。
> 直接 CID 寻址:这主要用于创建 CJK 字符集表。
5.1 字体和编码概述 91
5.2 字体格式详细信息
5.2.1 PostScript Type 1 字体
PostScript 字体文件格式 PostScript Type 1 字体总是分为两个部分:实际字型数据和规格
信息。PDFlib 在所有平台上都支持以下用于 PostScript Type 1 字型和规格数据的文件格式:
> 用于规格信息的独立于平台的 AFM(Adobe 字体规格)和特定于 Windows 的 PFM(打
印机字体规格)格式。虽然基于 AFM 的字体规格可以对字体支持的任何编码重新安排,
但是 Western 字体 (代码页 1252)的常见 PFM 规格文件仅可以与以下编码一起使用:
auto、 winansi、 iso8859-1、 unicode、 ebcdic。符号字体的 PFM 文件可以与 builtin 编码
一起使用。其他代码页的 PFM 文件可以用于与 PFM (或其任何子集)中的代码页匹配
的编码、或者用于 builtin 编码以选择 PFM 的内部代码页、或者用于 unicode。例如,用
于古斯拉夫语字体的 PFM 可以与编码 cp1250、builtin 和 Unicode 一起使用。编码 auto 将
自动选择适当的编码。
> 用于 PostScript Type 1 格式 (有时也称作 »ATM 字体 «)的字型信息的、独立于平台的
PFA (打印机字体 ASCII)和特定于 Windows 的 PFB (打印机字体二进制)格式。
> 在 Mac 上,也支持基于资源的 PostScript Type 1 字体,即 LWFN (LaserWriter 字体)
字型字体。这些字体附有一个字体包 (FOND 资源或 FFIL),其中包含了规格数据 (以
及 PDFlib 将忽略的屏幕字体) 。 PostScript 宿主字体可以与以下一些编码一起使用:
auto、macroman、macroman_apple、unicode 和 builtin。不过,对于一些需要字形补充
的字体,可能不可以接受 macroman 和 macroman_apple。
当使用 PostScript 宿主字体时, LWFN 文件必须放置在与字体包相同的目录中,并且必
须按照 5+3+3 的规则进行命名。请注意,在 PDFlib 的无 CarbonLib 支持的 OS 9 版本中不
支持 PostScript 宿主字体。
> 使用 PostScript 字型 (*.otf) 的 OpenType 字体。
92 第 5 章: 字体处理
PostScript 字形名称 为了编写自定义编码文件或查找可以与某一提供的编码一同使用的
字体,将必须查找有关编码定义的字符集的准确定义,以及字体文件中使用的字形名称。还
必须确保选择的字体提供了用于编码的所有必需的字符。若您正巧有 FontLab1 字体编辑器
(顺便说一下,此编辑器是用于处理所有种类的字体和编码问题的有效工具),则可以使用
此编辑器查找有关某一给定字体所支持的编码的信息 (在 FontLab 文档中查找 “代码
页”)。2
为了方便 PDFlib 用户,分发文件集中的 PostScript 程序 print_glyphs.ps 可以用于查找
PostScript 字体中包含的所有字符的名称。为了使用该程序,可在 PostScript 文件的末尾输
入字体的名称并将其 (连同字体一起)发送到 PostScript 打印机,或使用 Acrobat Distiller
转换为 PDF 文件。该程序将打印字体中的所有字形,并按照字形名称的字母顺序排序。
为了在字体中按字形名称引用字形,您可以使用 PDFlib 的字形名称语法(请参见第 84 页
上的第 4.6.2 节 “字符引用和字形名称引用”)。
1. 请参见 www.fontlab.com
2. 有关 PostScript 字体中使用的字形名称的信息可以在 partners.adobe.com/asn/tech/type/unicodegn.jsp 网页上找到
(并不要求字体供应商遵从这些字形命名建议)。
5.2 字体格式详细信息 93
5.2.3 用户定义的 (Type 3) 字体
PDF 中的 Type 3 字体 (与 PostScript Type 3 字体相对)实际上不是一种文件格式。 Type 3
字体中的字形必须在运行时使用标准 PDFlib 图形函数进行定义。由于矢量图形、光栅图像
甚至文本输出的所有 PDFlib 功能都可以在 Type 3 字体定义中使用,所以对于使用 Type 3
字体的字符内容没有任何限制。通过与 PDF 导入库 PDI 配合使用,甚至可以导入复杂的绘
图作为 PDF 页,并使用这些绘图定义 Type 3 字体的字符。
p.end_font();
94 第 5 章: 字体处理
5.3 搜索、嵌入和子集化字体
5.3.1 搜索字体
字体数据源 PDFlib 使 用函 数 PDF_load_font( ) 或 PDF_fit_textline( ) 和 PDF_add/create_
textflow( ) 函数的相应字体选项。您可以用字体的本地名称,或使用将用于定位字体数据的
任意自定义字体名称。在一个文档内,自定义字体名称应该是唯一的。在 PDF_info_font( )
中,可以使用 apiname 关键字查询此字体名称。
多次调用 PDF_load_font( ) 时,若所有选项均与第一次调用此函数时提供的选项相同,将
返回相同的字体句柄;否则,将为相同的字体名称创建新的字体句柄。PDFlib 支持以下字体
数据资源:
> 基于磁盘的字体文件
> 源自 Windows 或 Mac 操作系统的字体 (宿主字体)
> PDF 标准字体:这些字体源自一小部分具有已知名称的 Latin 和 CJK 字体集
> 已使用 PDF_begin_font( ) 和相关函数定义的 Type 3 字体
> 客户端通过 PDFlib 虚拟文件 (PVF) 直接在内存中传递的字体数据。对于已在内存中加载
字体数据并希望避免不必要的 PDFlib 磁盘访问 (有关虚拟文件的详细信息,请参见第
45 页上的第 3.1.2 节 “PDFlib 虚拟文件系统 (PVF)”)的高级应用程序,这一点很有用。
5.3 搜索、嵌入和子集化字体 95
对于 PostScript 字体,在对应的资源配置中必须将字体规格和字型数据 (只有在请求嵌入
时才涉及后者,请参见第 99 页上的第 5.3.3 节 “字体嵌入”)与对应的磁盘文件相关联:
p.set_parameter("FontOutline", "f1=LuciduxSans.pfa");
p.set_parameter("FontPFM", "f1=LuciduxSans.pfm");
font = font = p.load_font("f1", "unicode", "embedding");
以下代码片段请求一种核心字体,而无需任何配置:
font = p.load_font("Times-Roman", "unicode", "");
96 第 5 章: 字体处理
宿主字体 若字体名称与 Windows 或 Mac 上系统字体 (也称作宿主字体)的名称匹配,
将选择该字体。有关宿主字体的详细信息,请参见第 98 页上的第 5.3.2 节“Windows 和 Mac
上的宿主字体”。示例:
font = p.load_font("Verdana", "unicode", "");
在 Windows 上可以将可选字体样式添加到逗号之后的字体名称:
font = p.load_font("Verdana,Bold", "unicode", "");
这意味着,只要相应的字体文件中包含字体名称和对应于字体类型的标准文件名后缀,并
且该文件位于任一个 SearchPath 目录中,则不需要任何手动配置, PDFlib 就将查找相应的
字体。
下面的各组语句在查找字型文件方面效果一致:
p.set_parameter("FontOutline", "Arial=/usr/fonts/Arial.ttf");
font = p.load_font("Arial", "unicode", "");
和
p.set_parameter("SearchPath", "/usr/fonts");
font = p.load_font("Arial", "unicode", "");
5.3 搜索、嵌入和子集化字体 97
5.3.2 Windows 和 Mac 上的宿主字体
在 Mac 和 Windows 系统 上, PDFlib 可以 访问 已经 安装 在操 作系 统上 的 TrueType、
OpenType 和 PostScript 字体。我们将这样的字体称为 “宿主字体”。只需在系统中安装字
体(通常是将字体放入适当的目录中),而不用手动配置字体文件,PDFlib 就可使用相应的
字体了。
当使用宿主字体时,使用准确的 (区分大小写)字体名称很重要。由于字体名称非常重
要,以下我们会提及一些用于不同平台的确定字体名称的特有方法。有关字体名称的更多信
息可 以在 第 92 页上 的第 5.2.1 节 “PostScript Type 1 字体”和 第 93 页上 的第 5.2.2 节
“TrueType 和 OpenType 字体”中找到。
1. 请参见 www.microsoft.com/typography/TrueTypeProperty21.mspx
98 第 5 章: 字体处理
Windows 上有关宿主字体访问的潜在问题 我们提请用户注意一个与在 Windows 上安装
字体有关的潜在问题。若您通过 “文件” -> “安装新字体”菜单项 (另一种对应的方法是
将字体拖动到 Fonts 目录中)安装字体,将出现一个复选框 “复制字体到 Fonts 文件夹” 。
若未选中此框, Windows 将在字体文件夹中仅放置一个指向原始字体文件的快捷方式 (链
接)。在这种情况下,原始字体文件必须位于一个应用程序可使用 PDFlib 访问的目录中。具
体而言,位于 Windows 的 Fonts 目录之外的字体文件对于使用默认安全设置的 IIS 可能是不
可访问的。解决方案:将字体文件复制到 Fonts 目录下,或将原始字体文件放置到 IIS 对其
具有 read 权限的目录中。
在使用 Adobe Type Manager (ATM) 时,如果在安装字体时选中了“添加时不复制字体”
选项,则会出现类似的问题。
5.3.3 字体嵌入
PDFlib 能够将字型嵌入到生成的 PDF 输出中。通过 PDF_load_font( ) 的 embedding 选项可
以控制字体嵌入 (尽管在某些情况下, PDFlib 将强制实施字体嵌入):
font = p.load_font("WarnockPro", "winansi", "embedding");
另外,也可以嵌入仅包含字符规格和有关字体的常规信息(不带实际字型)的字体说明符。
若某种字体未嵌入到 PDF 文档中,Acrobat 将从目标系统获取相应的字体(如果存在),或
者根据字体说明符构造替代字体。表 5.1 列出有关字体用法的不同情况,每种用法都对
PDFlib 必需的字体和规格文件提出了不同的要求。除了在表 5.1 中列出的要求以外,为使用
带任何标准的 (标准或自定义) CJK 字体,必须提供对应的 CMap 文件 (以及在某些情况
下各字符集合的 Unicode 映射 CMap,例如 Adobe-Japan1-UCS2)。
当字体带有局限于该字体的编码(符号字体)或包含 Adobe 的标准拉丁字符集之外的字
形的字体时,但在 PDF 输出中没有嵌入这种字体,则只有当该字体已经安装在目标系统上
产生的 PDF 才将可用 (因为 Acrobat 只能模拟拉丁文字体)。这类 PDF 文件天生就不可移
植,不过可以在受控环境下使用 (例如,公司内部文档交换)。
1. 请参见 developer.apple.com/textfonts/download
5.3 搜索、嵌入和子集化字体 99
表 5.1 不同的字体用法情况以及要求的文件
字体用法 必须提供字体规格文件吗? 必须提供字型文件吗?
14 种核心字体之一 否 仅在要求嵌入的情况下需要
TrueType 字体 不适用 是
100 第 5 章: 字体处理
5.3.4 字体子集化
为了减少 PDF 输出的大小,PDFlib 可以仅嵌入字体中的那些在文档中实际使用的字符。这
个过程称作“字体子集化”。此过程将创建一个新的字体,其中包含的字形比原始字体包含
的字 形要 少一 些,并将 省略 PDF 查看 不需 要的 字体 信息。不 过,请注 意, Acrobat 的
TouchUp 工具将拒绝处理使用子集字体的文本。字体子集化对于 CJK 字体特别重要。
PDFlib 支持以下类型的字体的子集化:
> TrueType 字体
> 具有 PostScript 或 TrueType 字型的 OpenType 字体
> Type 3 字体 (要求特殊处理,请参见以下内容)
当已请求子集化的字体在文档中使用时,PDFlib 将记录实际用于文本输出的字符。对于子集
化行为有一些控制方式:
> 默认的子集化行为由 autosubsetting 参数控制。若该参数为 true,则将对所有可能发生
子集化的字体启用子集化 (要求特殊处理的 Type 3 字体除外,请参见以下内容)。默认
值为 true。
> 若 autosubsetting=true:subsetlimit 参数包含一个百分比值。若文档使用的值大于字体
中的此字形百分比值,则将对此特殊字体禁用子集化,而改为嵌入完整字体。这将节省
一些处理时间,不过输出文件会较大:
p.set_value("subsetlimit", 75); /* set subset limit to 75% */
p.end_font();
p.end_font();
p.end_document("");
102 第 5 章: 字体处理
5.4 其他主题
5.4.1 符号字体和特定于字体的编码
由于符号或徽标字体 (也称作 Pi 字体)通常未包含标准字符,因此它们必须使用与文本字
体不同的编码方案。
可以对文本字体重新编码 (调整到某个代码页或字符集),但不可以对符号字体重新编码,
而必须改用 builtin 编码。
注: 不幸的是,过去许多印刷商和字体供应商没有完全理解特定于字体的编码的概念 (这可能
是由于一些不甚完美的生产工具导致的) 。为此,产生了许多标记为 FontSpecific 编码的拉
丁文本字体以及许多错误地标记为文本字体的符号字体。
5.4.3 欧元符号字形
此符号表示欧洲货币,当需要正确显示和打印符号时,欧元符号会引发许多问题。在本节
中,我们将提供一些提示以便您可以成功处理欧元字符。首先,您将必须选择包含欧元字符
的编码并检查欧元字符的位置。以下是一些示例:
> 在 unicode 编码中使用字符 U+20AC。您还可使用对应的字符引用 € (通过名称)
或 € (通过数值)寻址欧元字符。
> 在 winansi 编码中,位置是 0x80 (十六进制)或 128 (十进制)。
> 普通 iso8859-1 编码不包含欧元字符。不过,iso8859-15 编码是 iso8859-1 的扩展,其中在
0xA4 (十六进制)或 164 (十进制)处添加了欧元字符。
> 原始的 macroman 编码不包含欧元字符。不过,Apple 修改了此编码并用位于 0xDB(十
六进制)或 219 (十进制)处的欧元字形替换旧的货币字形。为了使用此已修改的 Mac
编码,请使用 macroman_apple,而不使用 macroman。
下一步,您必须选择包含欧元字形的字体。许多现代字体包含欧元字形,但是并不是所有字
体都包含。同样,请看一些示例:
> PostScript Level 1 和 Level 2 设备中的内建字体不包含欧元字符,而 PostScript 3 设备中
的内建字体通常包含欧元字符。
> 若字体未包含欧元字符,则可以使用 Symbol 核心字体的欧元符号,此欧元符号位于
0xA0(十六进制)或 160(十进制)。在 Acrobat 4.0 及更高版本的软件附带的 Symbol
字体的版本中带有该字符,并构建到 PostScript 3 设备内部。
104 第 5 章: 字体处理
5.4.4 Unicode 兼容的字体
精确的 Unicode 语义对于 PDFlib 的内部处理很重要,而且对从 PDF 文档中正确提取文本或
以其他方式重用文档(例如将内容转换成其他格式)至关紧要。这在创建标签 PDF 时尤为重
要,因为标签 PDF 对于 Unicode 规范具有严格的要求 (请参见第 203 页上的第 9.6.1 节 “用
PDFlib 生成标签 PDF”)。除了标签 PDF 之外, Unicode 兼容性还与 Textflow 功能有关。
图 5.1 字体和字符规格
ascender
capheight
font size
baseline
descender
106 第 5 章: 字体处理
CPI 计算 虽然多数字体都具有变化的字符宽度,但是所谓的等宽字体对所有字符都使用相
同的宽度。为了将 PDF 字体规格与高速度打印环境下经常使用的每英寸字符数 (CPI) 测量单
位联系起来,等宽的 Courier 字体的一些计算示例可能会有帮助。在 Courier 中,所有字符
的宽度均为 600 个单位,与此对应的是,整个字符单元为每点 1000 个单位 (可以从相应
的 AFM 规格文件检索此值)。例如,对于 12 点的文本,所有字符的绝对宽度应为
12 点 * 600/1000 = 7.2 点
5.5.2 字距调整
一些字符组合会导致难看的外观。例如,紧邻的两个 V 看起来就像一个 W,而 T 和 e 之间的
距离必须减少以避免不协调的空白。这种调整通常称为“字距调整”。许多字体都包含有全
面的字距调整表,提供了用于某些关键字母对的间距调整值。PDFlib 提供了两种控制字距调
整行为的方式:
> 默认情况下,加载字体时不会读取字体中的字距调整信息。若要求进行字距调整,则在
对 PDF_load_font( ) 的相应的调用中必须设置 kerning 选项。这将指示 PDFlib 读取字体的
字距调整数据 (如果可用)。
> 当已读取了字距调整数据的字体与任何文本输出函数一起使用时,将应用字距调整数据
提供的位置修正。不过,也可以通过将 kerning 参数设置为 false 禁用字距调整:
p.set_parameter("kerning", "false"); /* disable kerning */
有时可能需要临时禁用字距调整,例如,由于经过字距调整的数字在表中无法对齐,因
此对于在字距调整表中具有对应的数字对的表中数字,应临时禁用字距调整。
除了可能激活的任何字符间距、单词间距和水平缩放之外,还应用字距调整。PDFlib 对字体
中的字距调整对的数目没有任何限制。
图 5.2 字距调整
No kerning
Kerning applied
虽然 PDFlib 将检查最初三个条件,但是用户需要负责确保最后一个条件。
通过 对 PDF_load_font( ) 的 fontstyle 选 项使 用 normal (对基 字体 不做 任何 更改) 、
bold,italic 或 bolditalic 关键字,可以请求伪字体样式:
font = p.load_font("HeiseiKakuGo-W5", "UniJIS-UCS2-H", "fontstyle bold");
108 第 5 章: 字体处理
下划线、上划线和删除线文本 可以指示 PDFlib 将文本的下方、上方或中间放置直线。横
线的粗细以及它与基线的距离将基于字体的规格信息进行计算。另外,当计算横线的宽度
时,需要考虑水平缩放因子和文本字模的当前值。 PDF_set_parameter( ) 的各参数名称可以
用 于 开 启 或 关 闭 下 划 线、上 划 线 和 删 除 线 功 能,以 及 文 本 输 出 函 数 中 的 对 应 选 项。
underlineposition 和 underlinewidth 参数和选项可以用于微调。
使用当前的笔触颜色绘制横线。不过,将忽略当前的 linecap 和 dash 参数。审美学上的
提示:在大多数字体中,下划线将接触到下行字母,而上划线将接触到上行字母顶部的发音
标记。
110 第 5 章: 字体处理
水平书写和垂直书写模式 PDFlib 支持水平书写和垂直书写模式。对于标准 CJK 字体和
CMap,通过选择适当的 CMap 名称,可连同编码一起选定书写模式。其名称结尾为 -H 的
CMap 选择水平书写模式,而 -V 后缀选择垂直书写模式。除之外的其他编码的字体可以通
过将 vertical 选项提供给 PDF_load_font( ) 而用于垂直书写模式。
p.setfont(font, 24);
p.set_text_pos(50, 500);
p.show("\u4e00\u500b\u4eba");
请注意,msgothic(不带任何后缀)将不能用作字体名,因为它不能唯一地识别字体。字体
名称别名 (请参见第 95 页上的 “字体数据源”)可以与 TTC 索引结合使用。若找不到带指
定索引的字体,函数调用将失败。
TTC 字体文件仅需要配置一次; TTC 文件中所有编入索引的字体都将自动找到。以下代
码足以配置 msgothic.ttc 中的所有编入索引的字体 (请参见第 95 页上的第 5.3.1 节 “搜索字
体”):
p.set_parameter("FontOutline", "msgothic=msgothic.ttc");
112 第 5 章: 字体处理
终端用户定义的字符 (EUDC) PDFlib 不支持将终端用户定义的字符链接到字体中,但是可
以使用 Windows 中可用的 EUDC 编辑器创建自定义字符,以便与 PDFlib 一起使用。按如下
所示操作:
> 使用 eudcedit.exe 在所需的 Unicode 位置创建一个或多个自定义字符。
> 在目录 \Windows\fonts 中查找 EUDC.TTE 文件,并将该文件复制到另外的目录。由于此
文件在 Windows 资源管理器中不可见,因此需要在 DOS 对话框中使用 dir 和 copy 命令
来查找这个文件。现在使用第 95 页上的第 5.3.1 节 “搜索字体”中讨论的方法之一配置
字体以便用于 PDFlib:
p.set_parameter("FontOutline", "EUDC=EUDC.TTE");
p.set_parameter("SearchPath", "...directory name...");
或在当前目录下放置 EUDC.TTE。
> 作为前一步骤的替代方式,可以使用以下函数调用以从 Windows 目录直接配置字体文
件。这样能总是访问在 Windows 中使用的当前 EUDC 字体:
p.set_parameter("FontOutline", "EUDC=C:\Windows\fonts\EUDC.TTE");
> 使用以下调用来加载字体:
font = p.load_font("EUDC", "unicode", "");
6.1 导入光栅图像
6.1.1 基本图像处理
在 PDFlib 中嵌入光栅图像可以轻松实现。首先,必须用一个 PDFlib 函数打开图像文件,对
图像参数进行简短的分析。 PDF_load_image( ) 函数返回一个句柄用作图像说明。此句柄可
以随同 positioning 和 scaling 参数,在对 PDF_fit_image( ) 的调用中使用:
image = p.load_image("auto", "image.jpg", "");
if (image == -1)
throw new Exception("Error: " + p.get_errmsg());
PDF_fit_image( ) 函数的最后的参数是一个选项列表,它支持用于定位、缩放和旋转图像的
各种选项。有关这些选项的详细信息将在第 150 页上的第 7.3 节 “放置图像和导入的 PDF
页”中讨论。
6.1.2 受支持的图像文件格式
PDFlib 处理以下描述的图像文件格式。默认情况下,如果可能的话, PDFlib 将压缩的图像
数据无改变地传递给 PDF 输出,因为 PDF 内部支持在常见图像文件格式中使用的大多数压
缩方案。此技术 (在以下的描述中称作 pass-through 模式)导致快速图像导入,因为此技
术不再需要对图像数据进行解压缩以及随后的再压缩。不过,在这种模式下,PDFlib 无法检
查已压缩图像数据的完整性。当在 Acrobat 中使用 PDF 文档时,不完整的图像数据或损坏
的图像数据可能导致错误或警告消息 (例如读取比预期少的图像数据) 。可以使用 PDF_
load_image( ) 的 passthrough 选项控制 Pass-through 模式。
若无法成功导入图像文件, PDF_load_image( ) 将返回一个错误代码。若想知道有关图像
失败的更多详细信息,请调用 PDF_get_errmsg( ) 以检索详细的错误消息。
PNG 图像 PDFlib 支持所 有风格 的 PNG 图 像 (ISO 15948)。多 数情况 下,都是 在 pass-
through 模式中处理 PNG 图像。用了隔行扫描或包含一个 alpha 通道(此通道总会丢失,
请参见以下内容)的 PNG 图像必须是未压缩的,这样将比 pass-through 模式花多很多时
间。若 PNG 图像包含透明度信息,则在生成的 PDF 中保留透明度 (请参见第 119 页上的
第 6.1.4 节 “图像蒙版和透明度”)。不过, alpha 通道不受 PDFlib 支持。
注: 根据 ISO 15444-6 (通常为 *.jpm) ,不带 JPX 包装的原始 JPEG2000 代码流 (通常为 *.j2k)
和 JPM 复合图像文件将不被支持。
1. 请参见 www.libtiff.org
2. 请参见 www.imagemagick.org
6.1.3 剪贴路径
PDFlib 支持 Adobe Photoshop 创建的 TIFF 和 JPEG 图像中的剪贴路径。一个图像文件中可
能包含多个命名路径。使用 PDF_load_image( ) 的 clippingpathname 选项,可以选择其中一
个命名路径,并将其用作剪贴路径:仅在剪贴路径内的图像部分可见,其他部分保持不可
见。这对于分离背景和前景、消除图像中不需要的部分等很有用。
图像文件还可以指定默认的剪贴路径。若 PDFlib 在图像文件中找到默认的剪贴路径,会
自动将其应用于图像 (请参见图 6.1) 。为了防止使用默认的剪贴路径,可将 PDF_load_
image( ) 中的 honorclippingpath 选项设置为 false。若您有相同图像的多个实例,而只有其
中某些实例要应用剪贴路径,您可以在 PDF_fit_image( ) 中提供 ignoreclippingpath 选项,以
便禁用剪贴路径。当应用剪贴路径时,将使用被剪贴图像的边框作为所有与放置或填充图像
相关的计算的基础。
PDFlib 支持图像中的三种透明度信息:隐式透明度、显式透明度和图像蒙版。
注: 蒙版必须与底层的图像具有相同的方向,否则将会被拒绝。因为方向取决于图像文件格式和
其他因素,所以难以检测。为此,建议对蒙版和图像使用相同的文件格式和创建软件。
隐式透明度 在隐式情况下,将使用外部图像文件中的透明度信息,前提是图像文件格式支
持透明度或 alpha 通道(并非所有图像文件格式都是如此)。在以下的图像文件格式中检测
透明度信息:
> GIF 图像文件可能包含一个 PDFlib 遵从的透明度颜色值。
> PNG 图像文件可能包含一些风格的透明度信息或整个 alpha 通道。 PDFlib 将保留单个
透明度颜色值;若给定带附加 alpha 值的多个颜色值,则仅使用第一个带有 50% 以下的
alpha 值的颜色值。忽略整个 alpha 通道。
图 6.1
使用剪贴路径分离前景和背景
蒙版中的为 0(零)像素值将导致所蒙版图像的相应部分被绘制,而高像素值导致背景透射
出来。若像素具有大于 1 位 / 像素,中间值将针对背景混合前景图像,提供透明效果。在第
二步中,蒙版应用于其他通过以下图像函数之一获得的图像:
mask = p.load_image("png", maskfilename, "mask");
if (mask == -1)
throw new Exception("Error: " + p.get_errmsg());
p.fit_image(image, x, y, "");
使用 mask 选项打开图像蒙版,在完成对所需填充色的设置后,将该蒙版放置在页面上:
mask = p.load_image("tiff", maskfilename, "mask");
p.setcolor("fill", "rgb", 1.0, 0.0, 0.0, 0.0);
if (mask != -1)
{
p.fit_image(mask, x, y, "");
}
忽略透明度 有时,需要忽略在图像文件中可能包含的任何透明度信息。例如,Acrobat 的
消除锯齿功能 (也称作 » 平滑 «)不能用于仅包含黑色和透明的 1 位图像。为此,当透明度
信息保留在生成的 PDF 中时,细节丰富的导入图像 (例如,光栅化文本)可能看起来很不
舒服。为了处理这种情况,当打开文件时,可以用 ignoremask 选项禁用 PDFlib 的自动透明
度支持:
image = p.load_image("gif", filename, "ignoremask");
6.1.5 图像着色
与图像蒙版 (对图像的非透明部分应用颜色)类似, PDFlib 支持用专色给图像着色。此功
能可用于以下格式的黑白或灰度图像:
> BMP
> PNG
> JPEG
> TIFF
> GIF
page 选项指示要使用多图像文件。最后一个参数指定要使用的图像的编号。第一个图像的
编号为 1。此选项可以增加直到 PDF_load_image( ) 返回 -1,发出信号表示文件中再没有图像
可用。
类似以下的代码片段可以用于将多图像 TIFF 文件中的所有图像转换为多页 PDF 文件:
for (frame = 1; /* */ ; frame++)
{
String optlist = "page=" + frame;
image = p.load_image("tiff", filename, optlist);
if (image == -1)
break;
p.begin_page_ext(width, height, "");
p.fit_image(image, 0.0, 0.0, "");
p.close_image(image);
p.end_page_ext("");
}
6.1.7 OPI 支持
当加载图像时,根据 OPI (开放印前作业界面)版本 1.3 或 2.0,在对 PDF_load_image( ) 的
调用中将提供附加信息。 PDFlib 接受所有标准 OPI 1.3 或 2.0 PostScript 注释作为选项 (不
是相应的 PDF 关键字!),并将提供的 OPI 信息传递到生成的 PDF 输出(不做任何修改)。
以下示例将 OPI 信息附加到图像:
String optlist13 =
"OPI-1.3 { ALDImageFilename bigfile.tif " +
"ALDImageDimensions {400 561} " +
"ALDImageCropRect {10 10 390 550} " +
"ALDImagePosition {10 10 10 540 390 540 390 10} }";
PDF_fit_pdi_page( ) 的最后一个参数是一个选项列表,此列表支持用于定位、缩放和旋转导
入的页的各种选项。有关这些选项的详细信息将在第 150 页上的第 7.3 节 “放置图像和导入
的 PDF 页”中讨论。
7.1.1 简单的文本放置
将文本定位在参考点 缺省情况下,文本的左下角将置于参考点上。不过,在此例中需要将
文本的底边中心置于参考点上。以下代码片段将文本框的底边中心与参考点 (30, 20) 对齐。
p.fit_textline(text, 30, 20, "position={center bottom}");
图 7.2 说明了带方向的简单文本放置。
图 7.1 图 7.2
Kraxi
居中文本 朝西的简单文本
y Kraxi y
x x
30 20
图 7.3 在框中定位文本
7.1.2 在框中放置文本
为了定位文本,可以使用带预定义宽度和高度的附加框,并且可以相对此框定位文本。
图 7.3 说明了一般行为。
在框中定位文本 我们定义一个矩形框,并在该框内右上角放置文本。下面的代码片段定义
一个位于参考点 (30, 20) 的框 , 宽度为 50 单位、高度为 22 单位。在图 7.4a 中,将文本放置
在框的右上角。
类似地,我们可以将文本放置在底边中心。图 7.4b 中说明了这种情况。
为了在文本与框之间保持一定距离,我们可以添加 margin 选项 (请参见图 7.4c)。
请注意,在图中用于可视化框大小而绘制的蓝色框或线不属于实际输出。
图 7.4 在框中放置文本受各种定位选项的约束
生成的输出 PDF_fit_textline( ) 的选项列表
a)
Kraxi boxsize={50 22} position={right top}
128 第 7 章: 格式化功能
7.1.3 框中填充文本
在本节中我们将使用各种填充方法将文本填入框。假定当前字体和字体大小在全部示例中
均相同,这样,我们可以查看不同的填充方法如何隐式更改字体大小和其他属性。
让我们从默认情况开始:使用 no fit 填充方法,这样,不会发生剪裁或缩放。文本将被
居中放置在宽度为 100 单位、高度为 35 单位的框中 (请参见图 7.5a)。
将框宽度从 100 单位减少到 50 单位不会对输出有任何影响。文本将保持其原始字体大
小,并将超出框 (请参见图 7.5b)。
按比例调整文本以使其适合小框 现在我们将文本完全填入框,同时保持其比例。这可以
通过 fitmethod=auto 选项实现。在图 7.5c 中,该框足以在其原始大小内容纳文本,这样,
文本将不加更改地填入框。
当将文本框的宽度从 100 缩小至 58 时,文本会变得过长而无法完全填入框。auto 填充方
法将尝试水平紧缩文本,这将受 shrinklimit 选项的约束 (默认值:0.75)。图 7.5d 显示文本
被缩减至其原始长度的 75%。
当将框的宽度进一步缩小至 30 单位时,即使对文本应用挤压,也不能完全填入框。然后
将应用 meet 方法。meet 方法将缩小字体大小,直至文本完全填入框。图 7.5e 中显示了这种
情况。
使用增大的字体大小将文本填入框 您可能会需要这样填入文本:使其覆盖框的整个宽度
(或高度),同时保持其比例。对一个大于文本的框使用 fitmethod=meet,将增大文本直至
其宽度与框宽度匹配。图 7.5f 中说明了这种情况。
完全调整文本以使其适合框 我们可以进一步调整文本,以使其完全填入框。在这种情况
下,可以使用 fitmethod=entire。不过,此组合将很少使用,因为文本很可能会扭曲 (请参
见图 7.5g)。
使用剪裁将文本填入框 在另一极少出现的情况下,您可能需要以其原始大小填入文本,
若文本超出框,则剪裁文本。在这种情况下,可以使用 fitmethod=clip。在图 7.5h 中,将文
本放置在框的左下角,而框的宽度不足。将从右侧剪裁文本。
图 7.5 在页面上将文本填入框受各种选项的约束
生成的输出 PDF_fit_textline( ) 的选项列表
g)
Kraxi Systems boxsize={100 35} position=center fontsize=12
fitmethod=entire
图 7.6 根据不同的框高度按比例调整文本以使其适合框
生成的输出 PDF_fit_textline( ) 的选项列表
130 第 7 章: 格式化功能
生成的输出 PDF_fit_textline( ) 的选项列表
boxsize={80 20} position=center fitmethod=auto
f) Kraxi Systems matchbox={boxheight={fontsize none}
fillcolor={rgb 1 0.8 0.8}}
7.1.4 沿字符对齐文本
沿字符对齐文本 您可能需要沿特定字符对齐文本,例如沿数字中的小数点。在以下代码片
段中,将文本与限定框 (fitbox) 的中心对齐。使用 alignchar=. 选项,数字沿圆点字符对齐
(请参见图 7.7a)。
/* align floating point numbers at the dot character */
String optlist =
"font=" + normalfont + " fontsize=8 boxsize={70 8} " +
"position={center bottom} alignchar=.";
图 7.7 将文本行与圆点字符对齐
生成的输出 PDF_fit_textline( ) 的选项列表
127.123
12.01 boxsize={70 8} position={center bottom} alignchar=.
a)
123.0
4025.20
127.123
12.01 boxsize={70 8} position={left bottom} alignchar=.
b)
123.0
4025.20
7.1.5 放置图章
除旋转文本外,图章功能还为在框中沿对角线放置文本提供了一个方便的方法。图章功能将
自动执行一些复杂的计算,以确定合适的字体大小和旋转方式,以便文本能够覆盖框。例
如,为了在页面背景中放置对角线图章,下面的代码片段将沿限定框的左下角至右上角
(ll2ur) 填充文本。当 showborder=true 图章的限定框和边框将显示 (请参见图 7.8)。
/* fit the text line and add a stamp from the lower left to the upper right */
String optlist = "font=" + normalfont + " fontsize=8 boxsize={160 50} " +
"showborder=true stamp=ll2ur";
ng
Giant Wi
fontsize=8 boxsize={160 50} showborder=true stamp=ll2ur
7.1.6 使用前导字符
可以使用前导字符填充限定框边框与文本之间的空间。例如,常常使用圆点前导字符作为目
录条目与对应的页码之间的可视化辅助工具。
滚动新闻中的前导字符 在另一用例中,您可能需要创建滚动新闻的效果。在这种情况下,
可以使用加号 “+”和空格字符作为前导符。文本居中放置,并在文本前后打印前导字符
(alignment={left right})。左前导字符与左边框对齐,右前导字符与右边框对齐,但与文本的
距离可能不同。(请参见图 7.9b)。
/* fit the text line and add a Ticker-like leader */
String optlist =
"font=" + normalfont + " fontsize=8 boxsize={200 10} " +
"position={center bottom} leader={alignment={left right} text={+ }}";
图 7.9 使用前导字符填充文本行
生成的输出 PDF_fit_textline( ) 的选项列表
132 第 7 章: 格式化功能
7.2 多行 textflow
除了在页上放置单行文本之外, PDFlib 支持一种称作 “Textflow”的功能,可用于放置任
意长度的文本部分。文本可能会延伸到任意数量的行、列或页,文本的外观可以使用多个选
项进行控制。字符属性 (例如字体、大小和颜色)可以适用于文本的任何部分。可以指定
textflow 属性 (例如分散对齐的文本或锯齿形的文本、段落缩排和制表位等);将考虑文
本中由自动连字符指定的换行机会。图 7.10 和图 7.11 演示如何使用 Textflow 功能在页面上
放置发票的不同的部分。在以下的部分,我们将更加详细地讨论用于控制输出的选项。
多行 textflow 可以放置在一个或多个页上的一个或多个矩形 (所谓的 “限定框”)中。
以下步骤是在页上放置 Textflow 所必需的步骤:
图 7.10
格式化
Textflow
Kraxi Systems, Inc.
Paper Planes
17, Aviation Road
Paperfield
Phone 7079-4301
Fax 7079-4302
info@kraxi.com
Kraxi Systems, Inc. 17, Aviation Road Paperfield www.kraxi.com
John Q. Doe
255 Customer Lane
Suite B
12345 User Town
Everland
INVOICE 14.03.2004
hortabmethod ruler
tabalignment right left right right right
ruler 30 45 275 375 475
ITEM DESCRIPTION QUANTITY PRICE AMOUNT
1 Super Kite 2 20,00 40,00
2 Turbo Flyer 5 40,00 200,00
3 Giga Trash 1 180,00 180,00
4 Bare Bone Kit 3 50,00 150,00
5 Nitty Gritty 10 20,00 200,00
6 Pretty Dark Flyer 1 75,00 75,00
7 Free Gift 1 0,00 0,00
845,00
leftindent Terms of payment: 30 days net. 30 days warranty starting at the day of sale. This
warranty covers defects in workmanship only. Kraxi Systems, Inc., at its option, repairs or alignment
= 55 replaces the product under warranty. This warranty is not transferable. Returns or = left
exchanges are not possible for wet products.
3. C one H e a d R oc ke t
This paper arrow can be thrown with big swing. We launched it from
the roof of a hotel. It stayed in the air a long time and covered a
considerable distance.
4. Super Dart
The super dart can fly giant loops with a radius of 4 or 5 meters and
cover very long distances. Its heavy cone point is slightly bowed
upwards to get the lift required for loops.
5. German Bi-Plane
Brand-new and ready for take-off. If you have lessons in the history of 图 7.11
aviation you can show your interest by letting it land on your teacher's 格式化
desk. Textflow
134 第 7 章: 格式化功能
if (tf == -1)
throw new Exception("Error: " + p.get_errmsg());
p.delete_textflow(tf);
p.end_page_ext("");
放置 textflow
Ut enim ad minim veniam, quis nostrud laboris nisi ut aliquip ex ea commodo con- 27 Lorem ipsum dolor sit amet, consectetur
exercitation ullamco laboris nisi ut aliquip ex id est laborum. 14 Lorem ipsum dolor sit sequat. Duis aute irure dolor in reprehenderit adipisicing elit, sed do eiusmod tempor
ea commodo consequat. Duis aute irure amet, consectetur adipisicing elit, sed do in voluptate velit esse cillum dolore eu fugiat incididunt ut labore et dolore magna aliqua.
7.2.2 段落格式设置选项
在上一示例中,我们使用段落的默认设置。例如,默认对齐方式是左对齐,行距是 100%
(与字体大小相同)。
为了调整段落的格式设置,我们可以对 PDF_add_textflow( ) 提供更多选项。例如,我们
可以将文本从左边距缩排 15 个单位,从右边距缩排 10 个单位。每个段落的第一行应另外缩
排 20 个单位。文本应对照左右边距对齐,并将行距增加到 140%。最终,我们将字体大小减
少到 8 点。为达到此目的,扩展 PDF_add_textflow( ) 的选项列表,如下所示(请参见图 7.13)
:
String optlist =
"leftindent=15 rightindent=10 parindent=20 alignment=justify " +
"leading=140% fontname=Helvetica fontsize=8 encoding=unicode";
136 第 7 章: 格式化功能
H1 Have a look at our new paper plane models!
Body Our paper planes are the ideal way of passing the time. We offer
revolutionary new developments of the traditional common paper
planes.
Body_indented If your lesson, conference, or lecture turn out to be deadly boring,
you can have a wonderful time with our planes. All our models are
folded from one paper sheet.
They are exclusively folded without using any adhesive. Several
models are equipped with a folded landing gear enabling a safe landing
on the intended location provided that you have aimed well. Other
models are able to fly loops or cover long distances. Let them start
图 7.14
from a vista point in the mountains and see where they touch the
将内嵌选项与宏组合
ground. 使用
7.2.3 内嵌选项列表和宏
图 7.13 中的文本还不完美。标题 »Have a look at our new paper plane models!« 应独自占
用一行,并应使用较大的字体居中显示。有一些方法可以用来达到此目的。
注: 在所有后续示例中将对内嵌选项列表进行着色;并使用箭头对段末字符进行可视化。
<leftindent=15 rightindent=10 alignment=center fontname=Helvetica fontsize=12
encoding=winansi>Have a look at our new paper plane models!
<alignment=justify fontname=Helvetica leading=140% fontsize=8 encoding=winansi>
Our paper planes are the ideal way of passing the time. We offer
revolutionary new developments of the traditional common paper planes.
<parindent=20>If your lesson, conference, or lecture
turn out to be deadly boring, you can have a wonderful time
with our planes.All our models are folded from one paper sheet.
They are exclusively folded without using any adhesive.Several
models are equipped with a folded landing gear enabling a safe
landing on the intended location provided that you have aimed well.
Other models are able to fly loops or cover long distances.Let them
start from a vista point in the mountains and see
where they touch the ground.Let them
start from a vista point in the mountains and see
where they touch the ground.
明确设置选项 请注意,所有未在宏中设置的选项将保留其先前的值。为了避免由选项的不
必要 » 继承 « 产生的副作用,应明确指定特殊的宏所需的所有设置。这样,不管宏的顺序或
与其他选项列表的组合如何,都可以确保宏将始终如一地工作。
另一方面,可以利用这种方式有意保留上下文的某些设置,而不用明确提供它们。例如,
宏可能会指定字体名称,而不提供 fontsize 选项。结果,字体大小将总是匹配先前文本中的
字体大小。
138 第 7 章: 格式化功能
hortabmethod ruler
tabalignment left right right right
ruler 30 150 250 350
7.2.4 制表位
在下一个示例中,我们将使用制表符制作一个带有左对齐列和右对齐列的表。此表包含以下
文本行,其中的各个项用制表符分隔 (用箭头指示):
ITEM DESCRIPTION QUANTITY PRICE AMOUNT
1 Super Kite 2 20.00 40.00
2 Turbo Flyer 5 40.00 200.00
3 Giga Trash 1 180.00 180.00
TOTAL 420.00
p.delete_textflow(textflow);
7.2.5 编号列表和段落间距
以下示例演示如何使用内嵌选项 leftindent 设置编号列表的格式 (请参见图 7.16):
1.<leftindent 10>Long Distance Glider: With this paper rocket you can send all
your messages even when sitting in a hall or in the cinema pretty near the back.
<leftindent 0>2.<leftindent 10>Giant Wing: An unbelievable sailplane! It is amazingly
robust and can even do aerobatics. But it is best suited to gliding.
<leftindent 0>3.<leftindent 10>Cone Head Rocket: This paper arrow can be thrown with big
swing. We launched it from the roof of a hotel. It stayed in the air a long time and
covered a considerable distance.
设置和重新设置缩排值比较麻烦,特别是每个段落都需要进行此操作。更加完美的解决方案是
定义一个名为 list 的宏。为了方便起见,其中定义一个宏 indent 用作常量。宏定义如下所示:
<macro {
indent {25}
leftindent = &indent
parindent = – &indent 1. Long Distance Glider: With this paper rocket you can send all your
messages even when sitting in a hall or in the cinema pretty near
the back.
2. Giant Wing: An unbelievable sailplane! It is amazingly robust and
can even do aerobatics. But it is best suited to gliding.
3. Cone Head Rocket: This paper arrow can be thrown with big swing.
图 7.17
We launched it from the roof of a hotel. It stayed in the air a long
使用宏的编号
列表
time and covered a considerable distance.
140 第 7 章: 格式化功能
设置段落间距 在许多情况下,相邻段落之间的距离需要大于段落内各行之间的距离。这可
以通过插入额外的空行 (可以使用 nextline 选项创建) ,并为空行指定合适的前导值来实
现。此值是前一段落最后一行的基线与空行的基线之间的距离。下面的示例将在两个段落之
间创建 80% 的附加空间 (其中 100% 等同于最近一次设置的字体大小值):
1. Long Distance Glider: With this paper rocket you can send all your messages
even when sitting in a hall or in the cinema pretty near the back.
<nextline leading=80%><nextparagraph>2. Giant Wing: An unbelievable sailplane! It is
amazingly robust and can even do
aerobatics. But it is best suited to gliding.
7.2.6 控制字符、字符映射和符号字体
textflow 中的控制字符 可对 textflow 中的不同字符进行特殊的处理。PDFlib 支持符号字
符名称,此类名称可以用于替换 charmapping 选项 (在处理文本之前替换其中的字符,请
参见以下内容)中对应的字符代码。PDFlib 参考列出了 textflow 函数使用的所有控制字符以
及相应的符号名称,并解释各自的含意。虽然一个选项列表只能使用一个选项,但是可以接
连提供多个选项列表。例如,以下序列将创建一个空行:
<nextline><nextline>
以下命令移除所有自动连字符:
charmapping={shy {shy 0}}
每个制表符都将被替换为四个空格字符:
charmapping={hortab {space 4}}
每个任意长度的换行符序列都将减少为单个换行符:
charmapping={linefeed {linefeed -1}}
每个 CRLF 组合序列都将被替换为单个空格:
charmapping={CRLF {space -1}}
我们将更进一步地讨论最后一个示例。让我们假定,您接收的文本中的行已由一些其他软件
通过固定的换行符分离,因此无法正确地设置这些行的格式。您需要用空格符替换这些换行
符以便在限定框内实现正确的格式设置。若要达到此目的,我们用单个空格符替换任意长度
的换行符序列。最初的文本如下所示:
To fold the famous rocket looper proceed as follows:
Take a sheet of paper. Fold it
lengthwise in the middle.
Then, fold down the upper corners. Fold the
long sides inwards
that the points A and B meet on the central fold.
以下代码片段演示如何替换多余的换行符以及如何对替换后的文本设置格式:
/* assemble option list */
String optlist =
"fontname=Helvetica fontsize=9 encoding=winansi alignment=justify " +
"charmapping {CRLF {space -1}}"
p.delete_textflow(textflow);
142 第 7 章: 格式化功能
Textflows 中的符号字体与 textlen 选项 在 textflow 中使用符号字体(更准确地说,应是
用了第 105 页上的第 5.4.4 节 “Unicode 兼容的字体”表中列出的字体之外的非 Unicode 兼
容的字体的文本)时,应特别注意:
> 控制字符将不会进行特殊处理,也就是说这些控制字符没有特殊含意。
> 一些 textflow 选项会因为对符号字体没有任何意义而被忽略,例如 tabalignchar。
> 因为内嵌选项列表不能在带有符号字体的文本部分中使用 (由于符号没有内在含意,因
此不可能定位和解释选项列表),必须使用 textlen 选项显式指定由符号字符组成的文本
片段的长度。
> 在 textlen 字符的后面,必须在文本中放置一个新的内嵌选项列表。通常下一个选项列表
将转换为其他字体 / 编码组合,但这不是必须的。
图 7.19 图 7.20
带有自动连字符的分散对齐的文本, 不带自动连字符的分散对齐的文本,
使用默认设置和宽限定框 使用默认设置和宽限定框。
7.2.7 断字
PDFlib 不会自动对文本进行断字,但是可以在出现由自动连字符明确标记的断字机会时实
现断字。自动连字符在 Unicode 中的位置是 U+00AD,但是也可以使用其他一些方法在非
Unicode 环境中指定自动连字符:
> 在所有 cp1250 – cp1258 (包括 winansi)和 iso8859-1 – iso8859-16 编码中,自动连字符对
应于十进制 173、八进制 255 或十六进制 0xAD。
> 在 ebcdic 编码中,自动连字符对应于十进制 202、八进制 312 或十六进制 0xCA。
> 若编码未包含自动连字符,则可以使用字符实体引用,例如 macroman:­
U+002D 将被用作断字符。除了自动连字符指定的中断机会以外,在极端情况下,当其他调
整方法 (例如更改字间距或挤压文本)不可用时,可以强行断字。
带有或不带自动连字符的分散对齐的文本 在以下的示例中,我们将使用分散对齐的方式
打印下面的文本。文本中包含自动连字符 (在此处以短线显示):
Our paper planes are the ideal way of pas sing the time. We offer revolu tionary
brand new dev elop ments of the tradi tional common paper planes. If your lesson,
confe rence, or lecture turn out to be deadly boring, you can have a wonder ful time
with our planes. All our models are folded from one paper sheet. They are exclu sively
folded without using any adhe sive. Several models are equip ped with a folded
landing gear enab ling a safe landing on the intended loca tion provided that you
have aimed well.Other models are able to fly loops or cover long dist ances. Let them
start from a vista point in the mount ains and see where they touch the ground.
图 7.19 显示了使用默认设置生成的分散对齐的文本输出。由于各项条件都很好,因此文本输
出很美观:限定框足够宽,并且自动连字符指定了一些明显的中断机会。从图 7.20 中可以看
到,即使没有明确的自动连字符,输出效果看上去也不错。两种情况下的选项列表如下所示:
fontname=Helvetica fontsize=9 encoding=winansi alignment=justify
144 第 7 章: 格式化功能
7.2.8 控制换行算法
PDFlib 执行一种复杂的换行算法。1 表 7.1 列出了可用来控制换行算法的 textflow 选项。
换行规则 当某个单词或由空格字符环绕的其他文本序列无法放入到行中时,必须将它移
动到下一行。在这种情况下,换行算法决定可能在哪个字符后换行。
例如,决不会断开像 -12+235/8*45 这样的公式,而字符串 PDF-345+LIBRARY 可能会在减号
字符处断开换到下一行。若文本包含自动连字符,则也可以在该字符后断开。
表 7.1 用于控制换行算法的选项
选项 说明
adjust- (关键字)如果在压缩或扩展单词之间的距离后文本部分无法在某个行中放下,此时用来调整行的方
method 法需要考虑到由 minspacing 和 maxspacing 选项指定的限制。默认值:auto
auto 按顺序使用以下方法:shrink、 spread、 nofit、 split。
clip 与 nofit 相同 (请参见以下内容),但将剪切位于限定框右边缘的长文本部分 (将考虑
rightindent 选项)。
nofit 末尾单词将移动到下一行,以使剩余 (短)行将不会少于 nofitlimit 选项中指定的百分
比。在这种情况下,甚至分散对齐的段落看上去也会有点错乱。
shrink 若一个单词在行中放不下,则会根据 shrinklimit 选项压缩文本直到可以将该单词完整放
入。若仍不能满足要求,则将使用 nofit 方法。
split 末尾单词将不会移动到下一行,但是将强制对其添加连字符。为文本字体,而非为符号字
体插入连字符。
spread 最后的字将移动到下一行,并服从 spreadlimit 选项,通过增加字中的字符之间的距离对
齐剩余的行。若仍无法实现对齐,则将使用 nofit 方法。
avoidbreak (布尔值)若为 true,则避免任何换行直到 avoidbreak 重置为 false。默认值:false
charclass (成对列表,其中,每对的第一元素是一个关键字,第二个元素是一个 unichar 或一组 unichar 的列
表)指定的 unichar 将按指定的关键字分类,以确定这些字符的换行行为:
letter 行为如同一个字母 (例如 B)
punct 行为如同一个标点符号 (例如 + / ; : )
open 行为如同一个左括号 (例如 [)
close 行为如同一个右括号 (例如 ])
default 将所有字符类重置为 PDFlib 的内置默认值
示例:charclass={ close » open « letter {/ : =} punct & }
hyphenchar (Unichar 或关键字)用于在换行处替换自动连字符的字符的 Unicode 值。值 0 和关键字 none 将完全
禁用连字符。默认值:若在字体中可用,则为 U+00AD (自动连字符),否则为 U+002D (减号连
字符)
maxspacing (浮点型或百分比)指定单词之间的最大距离或最小距离 (通过用户坐标表示,或作为空格字符宽
minspacing 度的百分比)。计算的字间距受提供的值的限制 (但是仍将添加 wordspacing 选项)。默认值:
minspacing=50%, maxspacing=500%
nofitlimit (浮点型或百分比)对于 nofit 方式,所需文本行长度的下限 (以在用户坐标中或定界框的宽度的百
分比为单位)。默认值:75%.
shrinklimit (百分比)对于 shrink 方式,可缩减文本的下限;计算的收缩因素受限于提供的值,但是将乘以
horizscaling 选项提供的值。默认值:85%
spreadlimit (浮点型或百分比)对于 spread 方式,可调整字间距的上限; (以用户坐标中或字体大小的百分比
为单位);计算的字符距离将被添加到 charspacing 选项的值。默认值:0
对于圆括号和引号,它取决于我们是否有一个开始或结束字符:开始圆括号和开始引号
不会提供任何断开机会。为了查找引号是否开始或结束一个序列,需要检查引号对。
通常内嵌选项列表不会创建换行机会以允许字内的选项更改。不过,当选项列表由空格
字 符 环 绕 时,在 选 项 列 表 的 开 始 处 有 换 行 机 会。若 换 行 出 现 在 选 项 列 表 处 且
alignment=justify,则将忽略选项列表前面的空格。选项列表后面的空格将保留,并将出现
在下一行的开始处。
在 Textflow 中不支持直排书写模式。
146 第 7 章: 格式化功能
用于分散对齐文本的选项 spreadlimit 扩展文本是用来控制换行的另外一种方法,它由
spread 方法实现并由 spreadlimit 选项控制。不过,这种方法的效果并不令人满意,很少使
用。图 7.22b 使用 spreadlimit=5 演示了最大字符间距为 5 个单位的文本。
图 7.22 窄限定框中用于分散对齐文本的选项
生成的输出 PDF_fit_textflow( ) 的选项列表
7.2.9 环绕文本
可以使用环绕功能将图形放置到 Textflow 内并使文本围绕图形,或用文本填充任意多边
形。可以使用匹配框、矩形或多边形为 Textflow 指定环绕区域。或者,可以将 Textflow 放
入指定区域内,不用为 Textflow 指定环绕区域。这意味着可以将 Textflow 放入任意形状
内,而不仅仅只是矩形。
图 7.23 图 7.24
使用匹配框使文本环绕图像 使用匹配框使文本环绕图像
Have a look at our new paper plane models! Our Our paper planes are50% 80%
the ideal way of passing the time.
paper planes are the ideal way of passing the time. We offer a lot of revolutionary brand-new developments
We offer revolutionary new of the traditional common paper planes. If your
developme- nts of the traditi- lesson, conference, or lecture turn out to be
deadly boring, you can have a wonderful
onal com- mon paper planes. time with our planes. All our models are
If your les- son, conference, folded from one paper sheet. They
or lecture turn out to be are exclusively folded without
deadly bor- ing, you can using
20% 30% any 80% 30%
adhesive.
have a wonderful time with our planes. All our Several models are equipped with a folded landing gear.
enabling a safe landing on the intended location provided
models are folded from one paper sheet. They are that you have aimed well. Other models are able to fly
exclusively folded without using any adhesive. loops or cover long distances.
首先,加载图像,并将其放入框内目标位置。为了稍后引用图像,请使用 在 PDF_fit_
image( ) 中的选项列表 matchbox={name=img margin=-5} 使用 matchbox={name=img
margin=-5} 定义一个名为 img 边距为 5 个单位的匹配框。接着,使用 wrap 选项选项将图像
的匹配框 img 作为环绕区域添加和放置 Textflow:wrap={usematchboxes={{img all}}}。
在放置文本之前,可以使用相同的匹配框名称填入其他图像。在这种情况下,文本将环绕
所有图像,因为关键字 all 指的是包含指定匹配框的所有矩形。
将文本环绕非矩形图形 除将文本环绕匹配框指定的矩形以外,还可以将任意多边形定义
为环绕形状。例如,下面的选项列表使文本环绕一个三角形 (请参见图 7.24 ):
wrap={ polygons={ {50% 80% 20% 30% 80% 30% 50% 80%} } }
除百分比 (限定框内的相对坐标)以外,还可以使用页面上的绝对坐标。
注: 将形状用于非水平和垂直朝向的片段时,建议设置 fixedleading=true 。
148 第 7 章: 格式化功能
图 7.26
50% 100%
填充重叠形状
图 7.25
使用文本 Our
paper
填充菱形 planes are
the ideal way Our paper planes are
of passing the the ideal way of pas-
time. We offer a lot sing the time. We offer
of revolutionary brand- revolutionary new develop-
new developments of the ments of the tradi-
90% 50% tional co- mmon pa-
10% 50% traditional common paper
per planes. If your les-
planes. If your lesson, con-
ference, or lecture turn son, conf- erence, or
out to be deadly bor- lecture turn out to be
ing, you can have deadly boring,
a wonderful you can have a wonderful
time with time with our planes. All
our pla- our models are folded
nes. from one paper sheet.
50% 0%
填充重叠形状 在下一示例中,我们将填充包含两个重叠多边形的形状,即内含矩形的六边
形。使用 addfitbox 选项,不会填充限定框本身,而是填充下面列表中除重叠部分以外的多
边形 (请参见图 7.26):
wrap={ addfitbox polygons=
{ {20% 10% 80% 10% 100% 50% 80% 90% 20% 90% 0% 50% 20% 10%}
{35% 35% 65% 35% 65% 65% 35% 65% 35% 35%} } }
7.3.1 简单的对象放置
将图像定位在参考点 缺省情况下,将按其原始大小放置对象,并使对象的左下角置于参
考点上。在此例中我们将图像的底边中心置于参考点上。以下代码片段将图像的底边中心与
参考点 (0, 0) 对齐。
p.fit_image(image, 0, 0, "position={center bottom}");
带缩放的图像放置 以下变体将在放置图像的同时修改其大小:
p.fit_image(image, 0, 0, "scale=0.5");
7.3.2 在框中定位对象
为了定位对象,可以使用带预定义宽度和高度的附加框。图 7.27 显示了下述示例的输出。请
注意,蓝色的框或线用于可视化显示框的大小,不属于实际输出。
图 7.27 在框中放置图像受各种定位选项的约束
生成的输出 PDF_fit_image 的选项列表
150 第 7 章: 格式化功能
7.3.3 使对象适合框
在本节中我们将使用各种填充方法将对象填入框。让我们从默认情况开始,在默认情况下使
用 no fit 填充方法,并且不应用剪切或缩放。图像将被居中放置在宽度为 70 单位、高度为
45 单位的框中。将框放置在参考点 (0, 0) 上。图 7.28a 说明了这种简单情况。
将框宽度从 70 单位减少到 35 单位不会对输出有任何影响。图像将保持其原始字体大
小,并将超出框 (请参见图 7.28b)。
在框中居中填充图像 为了使图像在预定义的矩形中居中放置,您不需要作任何计算,而
只需使用合适的选项就可以实现。通过 position=center,图像将被居中放置在宽度为 70 单
位、高度为 45 单位的框 (boxsize={70 45}) 中。使用 fitmethod=meet,按比例调整图像大小,
直至图像高度完全填入框。(请参见图 7.28c)。
将框的宽度从 70 缩小至 35,将缩小图像直至其宽度完全填入框 (请参见图 7.28d)。
将图像完全填入框 我们可以进一步调整图像,以使其完全填入框。这将通过
fitmethod=entire 完成。不过,此组合将很少使用,因为图像很可能会扭曲 (请参见
图 7.28e)。
图 7.28 在框中填充图像受各种填充方法的约束
生成的输出 PDF_fit_image( ) 的选项列表
按照页面大小调整对象 通过选择页面作为用来放置对象的目标框,可以轻松将对象调整
到给定页面的尺寸。以下语句使用尺寸为 595 x 842 的 A4 大小的页:
p.fit_image(image, 0, 0, "boxsize={595 842} position={left bottom} fitmethod=slice");
在此代码片段中,在页面的左下角放置一个框。该框的尺寸等于 A4 页的尺寸。将对象放置
在该框的左下角,并按比例缩放此对象直到它完全覆盖框以及页面。若对象超过该框,则此
对象将被剪切。请注意, fitmethod=slice 导致对象被缩放 (与此相反, fitmethod=clip 不缩
放对象)。当然,此示例中的 position 和 fitmethod 选项也可以变化。
7.3.4 对象的定向
按方向放置图像 在下一个示例中,我们将一个图像朝向西 (orientate=west)。这意味着将
图像逆时针旋转 90 度,然后将旋转对象的左下角平移至参考点 (0, 0)。该对象将自我旋转
(请参见图 7.31a)。由于我们未指定任何填充方法,图像将按其原始大小输出,并将超出文
本框。
将图像按比例和方向填入框 我们的下一个目标是以预定义大小将图像朝西放置。我们定
义一个所需大小的框并将图像填入框中,并保持图像的比例不变 (fitmethod=meet)。方向指
定为 orientate=west。默认情况下,将图像放置在框的左下角 (请参见图 7.31b) 。图 7.31c
显示图像朝东,图 7.31d 显示图像朝南。
orientate 选项支持方向关键字 north、 east、 west 和 south,如图 7.30 中所示。
请注意, orientate 选项不影响整个坐标系统,只影响被放置的对象。
152 第 7 章: 格式化功能
使用剪裁将定向图像填入框 我们使图像朝东 (orientate=east) 并将其居中定位在框的底边
上 (position={center bottom})。另外,放置图像时,图像将保持其原始大小,若超出框,则
进行剪裁 (fitmethod=clip) (请参见图 7.31e)。
图 7.31 图像定向
生成的输出 PDF_fit_image( ) 的选项列表
7.3.5 旋转对象
旋转对象的方式与定向类似。不过,旋转对象不仅影响放置的对象,而且还会影响整个坐标
系统。
图 7.32 图像定向
生成的输出 PDF_fit_image( ) 的选项列表
(x, y)
(x, y)
(x, y)
(x, y)
154 第 7 章: 格式化功能
图 7.33
调整页面尺寸。
从左向右:完全相
同、扩大、缩小
7.3.6 调整页面尺寸
在下一个示例中,我们将页面的尺寸自动调整到对象的尺寸。例如,这对存档 PDF 格式的图
像很有用。参考点 (x, y) 可以用于指定页面的尺寸是正好等于对象的尺寸,还是比对象的尺
寸大一点或小一点。放大页面大小时 (请参见图 7.33),有些边框将保持在图像周围。若页
面大小小于图像,将剪裁图像的某些部分。让我们从页面尺寸与对象的尺寸完全匹配开始:
p.fit_image(image, 0, 0, "adjustpage");
1 Giant Wing
注: 表处理与当前图形状态无关。可以在文档范围内定义表单元格,而实际的表放置必须在页范
围内执行。
156 第 7 章: 格式化功能
7.4.1 放置简单表
在更详细地描述表的概念之前,我们将演示一个用于创建表的简单示例。表中包含六个格,
排列成三行两列。其中四个单元格包含文本行,一个单元格包含多行 Textflow。所有单元
格内容沿水平向左对齐,在垂直方向上居中对齐,边距为 2 points。
为了创建表,我们首先通过定义所需选项 font 和 fontsize 及 fittextline 子选项中的 位置
{left center} 为文本行单元格准备选项列表。另外,我们将单元格边距定义为 2 points。然后
在相应的列和行中逐一添加文本行单元格,并在调用中直接将实际文本提供给 PDF_add_
table_cell( )。
在下一步中,我们将创建一个 Textflow,使用 Textflow 句柄合成 Textflow 表单元格的
选项列表,并将该单元格添加至表。
最后,我们使用 PDF_fit_table( ) 放置表,同时使用黑线可视化显示表和单元格边框。由
于我们不提供任何列宽,将从所提供的文本行及边距自动计算列宽。
以下代码片段显示如何创建简单表。图 7.35 中显示了结果。
/* Text for filling a table cell with multi-line Textflow */
String tf_text = "It is amazingly robust and can even do aerobatics. " +
"But it is best suited to gliding.";
/* Define the lower left and upper right corners of the table instance (fitbox) */
int llx=1, lly=1, urx=199, ury=99;
/* Add a Textflow */
optlist = "font=" + tfont + " fontsize=8 leading=110%";
tflow = p.add_textflow(-1, tf_text, optlist);
/* Define the option list for the Textflow cell using the handle retrieved above */
optlist = "textflow=" + tflow + " margin=2";
/* Define the option list for fitting the table with outside and cell ruling */
optlist = "stroke={{line=frame linewidth=0.3} {line=other linewidth=0.3}}";
7.4.2 表单元格的内容
当使用 PDF_add_table_cell( ) 将单元格添加到表时,您可以指定各种类型的单元格内容。例
如,表纸飞机的单元格包含了图 7.36 中说明的元素。
Text line
Text line
158 第 7 章: 格式化功能
单行文本 文本在 PDF_add_table_cell( ) 的 text 参数中提供。在 fittextline 选项中,可以指
定 PDF_fit_textline( ) 的所有格式化选项。默认的填充方法是 fitmethod=nofit。若文本不能
完全填入单元格,将放大单元格。为了避免这种情况,可以使用 fitmethod=auto 缩小文本,
此方法受 shrinklimit 选项的约束。若未指定行高,将通过将字体大小乘以 1.5 倍计算行高。
这同样适用于旋转文本的行宽。
单元格中的多个内容类型 表单元格可以同时包含一个或多个上述内容类型。还提供附加
的划线和阴影以及匹配框以用于交互功能,例如链接或表单域。
另外,单元格内容可能会受在内容特定的填充选项中提供的其他选项的约束,在第 161 页上
的第 7.4.4 节 “大表示例”中描述了这种情况。
colwidth=50
1 3
colspan=1 2 3
colspan=1 rowspan=3
colwidth=50 colwidth=100 colwidth=90
1 4 2 4
colspan=1 colspan=1
colwidth=50 colwidth=100
50 100 90
total table width of 240
另外,您可以在适当时以百分比形式指定列宽度。在这种情况下,百分比将参考表的限定框
宽度。列宽度必须要么都不以百分比形式提供,要么全部以百分比形式提供。
若使用 PDF_add_table_cell( ) 的 colscalegroup 选项将某些列合并成一个列缩放组,将根
据该组中最宽的列调整这些列的宽度 (请参见图 7.40)。
第一行中的最后四个单元格在同一
Weight
个列缩放组中。它们将具有相同的
Range
Speed
宽度。
若使用绝对坐标(而非百分比),并且存在一些保留未定义列宽度的单元格,将按以下方式
计算缺失的宽度:首先,将根据列宽或文本宽度 (或者在旋转文本的情况下,根据文本高
度)计算每个包含文本行的单元格的实际宽度。然后,将剩余的表宽度平均分配到仍然缺失
的列宽度。
160 第 7 章: 格式化功能
7.4.4 大表示例
在以下各节中,我们将分步创建图 7.41 中所示的示例表。作为先决条件,我们需要加载两种
字体,定义表大小并以 DIN A4 格式启动一个新页:
int tablewidth = 240, tableheight = 150;
步骤 1:添加第一个单元格 我们先创建表的第一个单元格。将单元格放置在第一行的第一
列,并跨三列。第一列的宽度为 50 points。将文本行垂直或水平居中对齐,距离所有边框的
边距为 2 points。下面的代码片段显示如何添加第一个单元格。
String optlist =
"fittextline={font=" + boldfont + " fontsize=12 position=center} " +
"margin=2 colspan=3 colwidth=50";
图 7.41 分步为表单元格添加不同属性
生成的表 生成步骤
String optlist =
"fittextline={font=" + boldfont + " fontsize=8} image=" + giant_wing_image +
" colwidth=90 rowspan=3 margin=4;
162 第 7 章: 格式化功能
我们还可以将图像导入为一个 PDF 页。确保必须在调用 PDF_fit_table( ) 之后才能关闭 PDI 页。
int doc = p.open_pdi("giant_wing.pdf", "", 0);
if (tbl == -1)
throw new Exception("Error: " + p.get_errmsg());
String optlist =
"fittextline={font=" + boldfont + " fontsize=8} pdipage=" + page +
" colwidth=90 rowspan=3 margin=4";
微调单元格内容的垂直对齐 当我们将表单元格中各种类型的内容垂直居中对齐时,它们
将距边框不等的距离。在图 7.42a 中,使用了以下选项列表放置四个文本行单元格:
optlist = "fittextline={position={left center} font=" + normalfont +
" fontsize=8} colwidth=80 margin=2";
164 第 7 章: 格式化功能
7.4.5 表实例
放置在一个限定框中的各表行构成一个表实例。表示一个完整的表可能需要一个或多个表
实例。每次调用 PDF_fit_table( ) 时将在限定框内放置一个表实例。可以将限定框放置在同一
页 (例如使用多栏布局)或几页上。
图 7.43 中的表分布在三页上。将每个表实例放置在一页上的一个限定框内。对于对 PDF_
fit_table( ) 的每一次调用,会将第一行定义为页眉,将最后一行定义为页脚。
图 7.43
表被分成若干个表实
Our Paper Plane Models 例,分别放置在一个
3 Cone Head Rocket 限定框中。
Material Kent paper 200g/sqm
With big swing!
BenefitOur Paper Plane
This paper Models
arrow can be
thrown with big swing. It
2 Long Distance Glider
stays in the air a long time.
Material Drawing paper 180g/sqm
header Benefit Our PaperWith this Plane Models
paper rocket you
can send all your messages
row join
table instance
1 Giant Wing
even when sitting in the
group Material Offset print paper pretty
cinema 220g/sqm
near the back.
Amazingly robust!
Benefit It is amazingly robust and
can even do aerobatics. But Page 3
it is best suited to gliding.
footer
Page 2
table’s fitbox
Page 1
以下代码片段显示填充表实例直至完全放置表的一般循环。只要需要放置更多表实例,就会
创建新页。
do {
/* Create a new page */
p.begin_page_ext(0, 0, "width=a4.width height=a4.height");
/* Use the first row as header and draw lines for all table cells */
optlist = "header=1 stroke={{line=other}}";
p.end_page_ext("");
} while (result.equals("_boxfull"));
限定框过低 若限定框过低,无法容纳所需页眉和页脚行及至少一个正文行或行连接组,将
均匀减小行高,直至将表填入限定框。不过,若所需收缩因子小于 vertshrinklimit 中所设置
的极限,不会执行收缩,而是 PDF_fit_table( ) 将返回字符串 _error 或相应的错误消息。为了
避免任何收缩,可以使用 vertshrinklimit=100%。
拆分单元格 若不能将一个单元格的最后数行填入单元格的限定框,将拆分该单元格。在图
像、 PDI 页或文本行单元格的情况下,单元格内容将在下一个表实例中重复出现。在
Textflow 单元格的情况下,单元格内容将在单元格的剩余行中继续。
图 7.44 显示当 Textflow 在下一行中继续时,如何拆分 Textflow 单元格。在图 7.45 中,
显示一个将在下一个表实例的第一行重复的图像单元格。
166 第 7 章: 格式化功能
拆分单元格 若最后的正文不能完全填入表的限定框,通常不会拆分。此行为由 PDF_fit_
table( ) 的 minrowheight 选项控制,默认值为 100%。在这种默认情况下,将不拆分行,而
是将行完全放置在下一个表实例中。
您可以减小 minrowheight 值在第一个实例中以给定的百分比拆分最后的正文行,并将该
行的剩余部分放置在下一个实例中。
图 7.45 说明了如何拆分 Textflow It's amazingly robust... ,以及该 Textflow 如何在下一
个表实例的第一个正文体行中继续。跨多行的图像单元格将被拆分,并重复其中的图像。
Benefit 文本行也将重复。
图 7.45
1 Giant Wing
拆分行
table Material Offset print paper 220g/sqm
instance 1
It is amazingly robust and
Benefit
can even do aerobatics. But
table
Benefit it is best suited to gliding.
instance 2
7.5.1 装饰文本行
让我们从讨论文本行中的匹配框开始。在 PDF_fit_textline( ) 中,匹配框是所提供文本的文本
框。默认情况下,文本框的宽度是文本的宽度,高度是给定字体大小的 capheight。为了说
明匹配框的大小,以下代码片段将使用蓝色背景色填充匹配框 (请参见图 7.46a)。
String optlist =
"font=" + normalfont + " fontsize=8 position={left top} " +
"matchbox={fillcolor={rgb 0.8 0.8 0.87} boxheight={capheight none}}";
图 7.46 使用带各种子选项的匹配框装饰文本行
生成的输出 PDF_fit_textline( ) 的匹配框选项的子选项
168 第 7 章: 格式化功能
7.5.2 在 Textflow 中使用匹配框
装饰部分 Textflow 在本节中,我们将装饰 Textflow 内的某些文本:将使用类似标记笔的
方式强调字 very dangerous。为达到此目的,将这些字包括在 matchbox 和 matchbox=end
内嵌选项中 (请参见图 7.47)。
String tftext =
"It is <matchbox={boxheight={ascender descender} fillcolor={rgb 1 0 0}}>" +
"very dangerous<matchbox=end> to fly the Giant Wing in a thunderstorm";
7.5.3 匹配框和图像
围绕图像绘制框架 在此示例中,我们使用 fitmethod=meet 将图像完全填入框内,同时保
持保持其比例。我们使用带 borderwidth 子选项的 matchbox 选项围绕图像绘制一个厚的矩
形。 strokecolor 子选项确定边框的颜色, linecap 和 linejoin 子选项用于圆角。
始终先绘制匹配框再绘制图像,这表示匹配框可能会被图像隐藏起来。为了避免这样,
我们使用带 50% 边框宽度的 offset 子选项放大框架以超出图像所覆盖的区域 (请参见
图 7.49)。
image = p.load_image("auto", "kraxi.jpg", "");
if (image == -1)
throw new Exception("Error: " + p.get_errmsg());
String optlist =
"boxsize={60 60} position={center} fitmethod=meet " +
" "matchbox={name=kraxi borderwidth=4 offsetleft=-2 offsetright=2 " +
"offsetbottom=-2 offsettop=2 linecap=round linejoin=round " +
"strokecolor {rgb 0.0 0.3 0.3}}";
p.fit_image(image, 6, 5, optlist);
p.close_image(image);
图 7.49 使用匹配框功能绘制图像的框架
生成的输出 PDF_fit_image( ) 的选项列表
170 第 7 章: 格式化功能
基于匹配框坐标绘制框架 在下一个示例中,图像朝西放置,并选择填充方法 meet 将图像
按比例填入所提供的框中。然后我们将使用 PDF_info_matchbox( ) 检索限定框的实际坐标,
并使垂直文本行相对限定框的右下角 (x1, y1) 对齐。框的边框以蓝色描边,而图像的实际限定
框的边框以黑色显示。从匹配框信息中检索限定框的坐标 (x1, y1) (请参见图 7.50)。
/* load and fit the image */
String optlist =
"boxsize={130 130} position={center} orientate=west " +
"fitmethod=meet matchbox={name=giantwing borderwidth=1 " +
"offsetleft=-0.5 offsetright=0.5 offsetbottom=-0.5 offsettop=0.5}";
图 7.50 使用匹配框功能检索坐标以填充文本行
生成的输出 生成步骤
步骤 1:使用匹配框填充图像
Foto: Kraxi
(x1, y1)
172 第 7 章: 格式化功能
8 pCOS 接口
pCOS (PDFlib Comprehensive Object Syntax) 接口提供一个简单而美观的实用工具,用于检索
PDF 文档非描述页面内容的任意信息 (如页面尺寸、元数据,交互元素等)。 pCOS 用户需
了解 PDF 内部结构和字典关键字的一些基本知识,但不必处理 PDF 语法和解析详细信息。
我们强烈建议 pCOS 用户拥有 PDF Reference,获取方法如下所示:
Adobe Systems Incorporated:PDF Reference, Fifth Edition: Version 1.6。可从
partners.adobe.com/public/developer/pdf/index_reference.html 下载 PDF 版本。
页数 文档的总页数可按如下方式查询:
pagecount = p.pcos_get_number(doc, "length:pages");
文档信息域 文档信息域可通过下列代码序列检索:
objtype = p.pcos_get_string(doc, "type:/Info/Title");
if (objtype.equals("string"))
{
/* Document info key found */
title = p.pcos_get_string(doc, "/Info/Title");
}
列出文档中的所有字体 下列序列创建文档中所有字体的列表及其嵌入状态:
fontcount = p.pcos_get_number(doc, "length:fonts");
174 第 8 章: pCOS 接口
布尔型 boolean 类型的对象可通过 PDF_pcos_get_number( ) 查询,并将返回 1 (true) 或 0
(false)。 PDF_pcos_get_string( ) 也可用于查询布尔型对象;在这种情况下,将返回 true 和
false 这两个字符串中的某个字符串。
数组 数组是任意数量对象的一维集合,其中每个对象都可能具有任意类型。
可以通过查询数组包含的元素数量 N (在数组的路径开头处使用 length 前缀,请参见
表 8.2),然后重复索引 0 至 N-1 的所有元素来列举数组的内容。
字典 字典 (也称作相关数组)包含任意数量的对象对。每个对象对中的第一个对象都具
有 name 类型,并称作关键字。第二个对象称作值,并可能具有除 null 以外的任意类型。
可以通过查询字典包含的元素数量 N (在字典的路径开头处使用 length 前缀,请参见
表 8.2),然后重复索引 0 至 N-1 的所有元素来列举字典的内容。在字典的路径结尾处使用
.key 后缀,列举字典将按其在 PDF 中的存储顺序提供所有字典关键字。同样,可以使用 .val
后缀列举相应的值。列举字典关键字时将不显示继承的值 (请参见以下内容)和伪对象,
并且不包含在 length 计数中。
PDF 中某些与页面相关的字典项可以通过树状数据结构继承,这使检索字典项变得困
难。例如,页面的 MediaBox 不能保证包含在页字典中,但可以从任意复杂的页面树继承。
pCOS 通过以透明的方式将所有继承的关键字和值插入到最新版的字典中来解决此问题。换
言之,pCOS 用户可以假定所有可继承项都可以直接在字典中找到,并且不必搜索树中的所
有相关父项。只有通过 pages[ ] 伪对象访问页面树时才会使用合并的继承项;访问 /Pages
树、 objects[ ] 伪对象,或通过 pages[ ][ ] 列举关键字将返回相应字典中存在的实际项,不会
应用任何继承项。
176 第 8 章: pCOS 接口
8.4 路径语法
pCOS 接口的最大特征是用于寻址和检索 PDF 文档中包含的任意对象的简单路径语法。除对
象数据本身以外, pCOS 还可以检索有关对象的信息 (例如,对象的类型或长度)。根据对
象的类型 ( 其本身可以查询),可以使用 PDF_pcos_get_number( )、 PDF_pcos_get_string( )
和 PDF_pcos_get_stream( ) 中的任一函数获取对象的值。 pCOS 路径的一般语法如下所示:
[<prefix>:][pseudoname[<index>]]/<name>[<index>]/<name>[<index>] ... [.key|.val]
各个路径组件的含义如下所示:
> 可选的 prefix 可以获取表 8.2 中列出的值。
> 可选的 pseudo object name 可能包含第 179 页上的第 8.5 节 “伪对象”中描述的值之一。
> name 组件是在文档中找到的字典关键字。多个名称可用 / 字符分隔。空路径(即单个 /)
表示文档的 Trailer 字典。每个名称都必须是前一字典中出现的字典关键字。完整路径描
述了从初始字典 (可能是 Trailer 或伪对象)到目标对象的字典关键字链。
> 指定数组或字典的路径或路径组件可以包含数字索引,该索引必须以括号括起来的十进
位格式指定。嵌套数组或字典可以通过多个索引项寻址。数组或字典中第一个项的索引
为 0。
> 指定字典的路径或路径组件可以包含索引限定符和 .key 或 .val 后缀。这可用于分别检索
特定字典关键字或索引字典项的相应值。如果字典的路径包含索引限定符,则它后面必
须跟有这些后缀之一。
长度 (数字)对象的长度,它取决于对象的类型:
array 数组中的元素数量
dict 字典中关键字 / 值对的数量
stream 流字典中关键字 / 值对的数量(不是流长度;使用 Length 关键字确定流数据的长度,以字
节为单位)
fstream 与流相同
other 0
类型 (字符串或数字)数字或字符串形式的对象类型:
0, null 空对象或对象不存在 (用于检查是否存在对象)
1, boolean 布尔型对象
2, number 整数或实数
3, name 名称对象
4, string 字符串对象
5, array 数组对象
6, dict 字典对象 (但不是流)
7, stream 仅使用受支持的筛选器的流对象
8, fstream 使用一个或多个受支持筛选器的流对象
178 第 8 章: pCOS 接口
8.5 伪对象
伪对象扩展 pCOS 路径集的方法是引入某些有用元素,这些元素可用作 PDF 中存在的信息
的缩写,但不能通过读取单个值轻松访问。下面各部分列出了所有受支持的伪对象。无法列
举 dict 类型的伪对象。
通用伪对象 无论是否设置了加密和口令,通用伪对象始终可用。这种情况假定存在有效的
文档句柄,可能会要求在打开文档时适当设置 requiredmode 选项。表 8.3 列出了所有通用伪
对象。
表 8.3 通用伪对象
对象名称 说明
encrypt (字典)带有说明文档加密状态密钥的字典:
length (数字)加密密钥长度,以位为单位
algorithm (数字)
description(字符串)加密算法数字或描述:
-1 未知加密
0 未加密
1 40 位 RC4 (Acrobat 2-4)
2 128 位 RC4 (Acrobat 5)
3 128 位 RC4 (Acrobat 6)
4 128 位 AES (Acrobat 7)
5 位于 128 位 RC4 顶部的公钥 (Acrobat 5) (不支持)
6 位于 128 位 AES 顶部的公钥 (Acrobat 7) (不支持)
7 Adobe Policy Server (Acrobat 7) (不支持)
master (布尔型)如果 PDF 要求输入许可口令以更改安全性设置 (权限,打开或许可口令),则
为 True ,否则为 false
user (布尔型)如果 PDF 要求文档打开口令,则为 True,否则为 false
noaccessible, noannots, noassemble, nocopy, noforms, nohiresprint, nomodify, noprint
(布尔型)如果设置了相应的访问保护,则为 True,否则为 false
plainmetadata
(布尔型)如果 PDF 包含未加密的元数据,则为 True,否则为 false
filename (字符串)PDF 文件的名称
filesize (数字) PDF 文件的大小 (以字节为单位)
linearized (布尔型)如果是线性 PDF 文档,则为 True,否则为 false
major (数字)分别表示库的主要、次要或修订版本号。
minor
revision
简化资源处理的伪对象 资源是用于管理完整描述页面内容所需的各种数据的关键概念。
PDF 中的资源概念功能非常强大且高效,但各种技术概念又使访问变得非常复杂,例如,递
归和资源继承。pCOS 极大地简化了资源检索并提供了几组可用于直接查询资源的伪对象。
其中某些伪资源字典还包含标准 PDF 关键字以外的项,以便进一步简化资源信息检索。
pCOS 支持两组用于资源检索的伪对象。全局资源数组包含 PDF 文档中的所有资源,而
页面资源仅包含特定页面使用的资源。全局资源数组和基于页面的资源数组中的资源项都
是从用户的角度反映资源。这些资源项与本机 PDF 资源的区别如下:
> 可以添加某些项(如内嵌图像、简单色彩空间)或删除某些项(如多带区图像的组件)。
> 除原始 PDF 字典关键字以外,资源字典还可能包含某些提供辅助信息的用户友好关键字
(如字体的嵌入状态,色彩空间的组件数量)。
patterns (字典数组)包含页面上或文档中所有图案字典的数组
properties (字典数组)包含页面上或文档中所有属性字典的数组
shadings (字典数组)包含页面上或文档中所有着色字典的数组。除着色字典中的标准 PDF 关键字以外,还支
持下列伪关键字:
colorspaceid
(整型) colorspaces[] 伪对象中底层色彩空间的索引。
templates (字典数组)包含页面上或文档中所有模板 (Form XObjects) 字典的数组
182 第 8 章: pCOS 接口
8.6 加密的 PDF 文档
pCOS 支持加密和未加密的 PDF 文档作为输入。但是,加密文档的完整对象检索要求在打开
文档时提供相应的许可口令。根据文档打开或许可口令的可用性,可以按下面描述的任一
pCOS 模式处理加密文档。
某些动作选项 PDF_create_action( )
某些注释选项 PDF_create_annotation( )
某些注释选项 PDF_create_annotation( )
标签 PDF 某些 PDF_begin_item( ) 选项
PDF_begin/end_page_ext( ) 选项:taborder 选项
用于 PDF 1.6 或更高版本的 PDFlib 输出功能 在 PDF 1.5 以下的 PDF 兼容模式下,无法使用
用于 PDF 1.6 的 PDFlib 功能。在版本较低的 PDF 模式下尝试使用这些功能会导致异常。
1. 参见 www.callassoftware.com
如果文件具有文档打开口令、许可口令或任何权限限制设置,则表明文件是加密的。
提供的口令将用于此后生成的所有文档。
表 9.4 列出了所有支持的访问限制关键字。如表中的详细信息所述,有些关键字要求兼容
PDF 1.4 或更高版本。如果 PDF 输出版本过低,它们将被拒绝。
ISO 15930-3 中规定的 PDF/X-3:2002 此标准基于 PDF 1.3 ;除灰度、 CMYK 和专色之外,
它还支持基于设备无关颜色的现代工作流程。此标准在欧洲国家 / 地区尤为盛行。输出设备
可以采用单色、 RGB 或 CMYK。
PDF 版本 / 兼容性 PDF/X-1a:2001 和 PDF/X-3:2002 都基于 PDF 1.3。必须避免使用要求 PDF 1.4 或更高版本的操作,
例如透明度或软蒙版。
PDF/X-1a:2003、 PDF/X-2:2003 和 PDF/X-3:2003 都基于 PDF 1.4。必须避免使用要求 PDF 1.5 的
操作,例如图层。
PDF/X-1a:2001 允许
PDF/X-1a:2003 允许 允许
PDF/X-2:2003 允许 允许 允许 允许 允许
PDF/X-3:2002 允许 允许
PDF/X-3:2003 允许 允许 允许 允许
标签 PDF 必须满足标签 PDF 的所有要求 (请参见第 203 页上的第 9.6 节 “标签 PDF”)。
强烈建议遵守以下限制:
> 应在 PDF_begin_item( ) 中正确地为所有与默认文档语言不同的内容项指定 Lang 选项。
> 应使用 PDF_begin_item( ) 的 Alt 选项为非文本内容项 (例如图像)提供替代文本描述。
> 应针对括号内的内容项目使用 PDF_begin_item( ) 的 ActualText 选项为非 Unicode 文本
(例如徽标和符号)指定相应的替换文本。
> 应针对括号内的内容项目在 PDF_begin_item( ) 的 E 选项中为缩略语指定相应的扩展文本。
批注 PDF_create_annotation( ):必须为 contents 选项提供非空字符串
PDF/A-1a:2005 – 允许
PDF/A-1b:2005 – 允许
1. 参见 www.callassoftware.com
none 是 – – –
1
灰度 ICC 色彩特征描述文件 是 是 – –
– 1 –
RGB ICC 色彩特征描述文件 是 是
1. 导入文档的输出描述和生成文档的输出描述必须相同
none 是 是 – – –
灰度 ICC 色彩特征描述文件 是 是 是 – –
除表 9.15 中列出的色彩空间外,可以使用专色,但具有对应的替代色彩空间的约束。由于
PDFlib 将 CIELab 用作内置 HKS 和 PANTONE 专色的替代色彩空间,因而这些颜色始终可以
用于 PDF/A。对于自定义专色,必须选择替代色彩空间,以便与 PDF/A 输出描述兼容。
页面内容顺序 定义页面内容的文本、图形和页面运算符的顺序称为内容流顺序;由逻辑
结构树定义的内容顺序称为逻辑顺序。生成标签 PDF 要求客户端遵守某些内容顺序方面的
规则。
推荐的、也是很自然的方法是,依次生成结构元素的所有构成部分,然后移至下一个元
素。从技术角度讲,应以深度优先遍历创建结构树。
以下方法应避免:输出第一个元素的一部分、切换到下一元素的一部分,然后在返回第
一个元素,等等。如果采用这种方法,结构树是在多次遍历中建立的,且每次遍历只生成元
素的一部分。
伪像 不属于作者原始内容的一部分的图形或文本对象称为伪像。伪像应使用 Artifact 伪标
签等加以标识,可分为以下几个类别:
> 分页:自动标题和页码等功能
> 版面:标尺和表格阴影等排版或设计元素
> 页面:裁切标记和颜色条等印刷辅助功能
尽管没有严格规定,但我们强烈建议标识伪像,以帮助实现文本重排和辅助功能。
表 9.17 常规项目和内嵌项目
常规项目 内嵌项目
文档结构树的一部分 是 否
可跨越页面边界 是 否
可被其他项目中断 是 否
可暂停和启动 是 否
可以任意深度嵌套 是 只能与其他内嵌项目一起
使用
不兼容 Unicode 的 必须避免使用不兼容 Unicode 的字体,具体参见第 105 页上的第 5.4.4 节 “Unicode 兼容的
字体 字体”。
/* open the first structure element as a child of the document structure root (=0) */
id = p.begin_item("P", "Title={Simple Paragraph}");
p.setfont(font, 24);
p.show_xy("Hello, Tagged PDF!", 50, 700);
p.continue_text("This PDF has a very simple");
p.continue_text("document structure.");
p.end_page_ext("");
p.end_item(id);
p.end_document("");
9.6.3 启动复杂布局的项目
为了帮助创建具有复杂的非线性页面布局的结构信息, PDFlib 支持一种称为项目启动的功
能。在开发人员必须跟踪多个结构分支,且每个分支都可能跨一个或多个页面的情况下,可
使用这种功能启动以前创建的结构元素。这种技术通常可用于以下情况:
> 一个页面上的多个栏
> 小结或插入等中断主文本的插入操作
> 放置在两栏之间的表格和插图
通过启动功能,可在两个逻辑分支之间切换以及其他情况下使用经过改进的页面内容生成
方法。这种方法比依次完成每个分支更加高效。我们以图 9.1 中显示的页面布局为例,说明
启动功能的优点。该布局包含两个主文本栏,文本栏被黑色背景显示的框中的一个表格和插
入注释以及页眉和页脚中断。
按逻辑顺序生成页面内容 从逻辑结构的角度讲,应按照以下顺序创建页面内容:左栏、右
栏 (页面右下角部分)、表格、插入、页眉和页脚。以下伪代码便采用了这一顺序:
/* create page layout in logical structure order */
采用这种结构元素的顺序时,主文本 (跨一个半栏)会被表格和插入内容中断两次。因此,
必须使用 PDF_activate_item( ) 启动两次。
如果内容跨多个页面,可以采用相同的技术。例如,可以首先创建页眉或其他插入内容,
然后再次启动主页面内容元素。
212 第 10 章: 数据变量和块
10.2 PDFlib 块概念的概述
10.2.1 文档设计和程序代码的完整分离
使用 PDFlib 数据块,可以很方便地在导入页上放置可变文本、图像或图形。相对于普通的
PDF 页,内部包含数据块的页携带了稍后在服务器端将要处理的信息。PDFlib 块概念将下列
的任务非常清晰的分开:
> 设计师可以创建页布局,并指定可变文本和图像元素的位置和一些相关的属性如字体大
小、颜色或图像的比例等。将布局创建为 PDF 文档后,设计器使用 Acrobat 的 PDFlib 块
增效工具以指定可变数据块及其相关属性。
> 程序员编写代码以连接包含在 PDFlib 块中的信息,该 PDFlib 块位于带有动态信息 (例
如,数据库域)的导入 PDF 页上。程序员不需要知道有关块的任何详细信息 (它是否包
含名称或 ZIP 代码、页上的准确位置、它的格式等等),因此该块独立于任何布局更改。
PDFlib 将维护基于文件中找到的块属性的与所有块相关的详细信息。
控制导入页和块的显示顺序 使用任何块填充函数之前,导入页面必须已经放置在输出页
面中。这表示原始页通常将被放置在块内容下面。不过,在某些情况下,可能需要将原始页
面放置在填充块的顶部。这可以通过 PDF_fit_pdi_page( ) 的 blind 选项实现:
/* Place the page in blind mode to prepare the blocks, without the page being visible */
p.fit_pdi_page(page, 0.0, 0.0, "blind");
p.fill_textblock(page, "firstname", "Serge", "encoding=winansi");
/* ... fill more blocks ... */
不同的类型块会带有不同的标准属性。例如,文本块可能指定文本的字体和尺寸,图像块或
PDF 块可能指定缩放因子或旋转。对于每种块类型,PDFlib API 提供用于处理该块的专用函
数。这些函数按照块的名称搜索该块的导入的 PDF 页,分析页的属性并根据相应的块属性
将一些客户端提供的数据 (文本、光栅图像或 PDF 页)放置在新页上。
自定义块属性 标准块属性可以快速执行可变数据处理应用程序,但是限于属性集,此属
性集在内部为 PDFlib 所知并可以自动被处理。为了提供更多的灵活性,设计器也可以对块
指定自定义属性。这些属性可以用于扩展块概念以符合大多数请求的可变数据处理程序的
要求。
不存在自定义属性的规则,因为 PDFlib 除了使自定义属性对客户端可用之外,将不会以
任何方式处理自定义属性。客户端代码可以检查自定义属性并用它认为是合适的任何方法
使用该自定义属性。基于块的一些自定义属性,代码可以作出布局相关的或数据收集的决
定。例如,科学应用程序的自定义属性可以指定用于数字输出的数字的数量,或者数据域名
称可以定义为自定义块属性以便检索此块相应的数据。
块属性重写 在特定的情况下,程序员只需要使用块定义中提供的部分属性,而使用自定义
值重写其他属性。在各种情况下,这一点很有用:
> 图像或 PDF 页的缩放因子将被计算,而不是从块定义中得到。
> 例如,当用可变数量的数据项生成发票时,通过编程方式更改块坐标。
> 应提供单独的专色名称以满足打印机应用程序中的各个用户的要求。
214 第 10 章: 数据变量和块
坐标系统 块坐标是以 PDF 的缺省坐标系统为依据。当带有块的页放置在输出页上时,几
个与位置和比例相关的选项将提供给 PDF_fit_pdi_page( )。处理块的时候,这些参数将被用
到。这使得将同一模版在同一页重复出现多次成为可能。例如,一个名片模版可以在同一张
纸上重复四次,这样一版可印 4 张名片。块函数会处理坐标系统的变换,并将块内容填到正
确的位置。用户需做的是先将输入模版所有块填写后生成页。然后再将该页重复几次写入输
出页不同的位置,并接着做一系列的块处理,依次类推。
if (tf == -1)
break;
更改文本内的字体或其他文本属性 – 是
用户可以编辑合并的字段内容 是 否
可扩展的属性集 – 是 (自定义块属性)
填充时,可以重写图形和文本属性 – 是
可以链接文本块 – 是
216 第 10 章: 数据变量和块
10.3 建立 PDFlib 块
10.3.1 利用 PDFlib 块增效工具交互式建立块
激活 PDFlib 块工具 用于建立 PDFlib 块的 PDFlib 块增效工具类似于 Acrobat 中的表单工
具。当块工具被激活,所以在页上的块将被显示出来。当其他 Acrobat 工具被选择后,块依
旧存在但会被隐藏。用户可以用以下几种方式激活块工具:
> 在 Acrobat 的 “高级编辑”工具条中点击块图标 (在 Acrobat 5 中:“编辑”工具
栏);
> 通过菜单项 “PDFlib 块” -> “PDFlib 块工具”;
> 使用快捷键 P ;但在使用之前要确信在“编辑”->“首选项”->“[ 常规 ...]”->“常规”
窗口中选择了 “使用加速键访问工具”,默认值是不选 (Acrobat 5 不需此步)
建立和修改块 当您激活了块工具后,就可以移动十字光标以在页面上要求的位置建立所
需尺寸的块。所有块都是矩形的,它们的四边总是与页边缘平行。当用户建立了新块后,将
出现块属性对话框,您可以在对话框中编辑各种块属性 (见第 220 页上的第 10.3.2 节 “编
辑块属性”)。块工具会自动建立一个块名称,该块名称可以在属性对话框中更改。页块名
称在同一页中必须是唯一的。您可以将顶部区域中的块类型更改为某一文本、图像或 PDF。
常规和自定义标签将总是可用,而根据选择的块类型不同,一次只能激活一个文本、图像和
PDF 标签。Textflow 标签仅在 textflow 属性为 true 的情况下,用作类型文本块。另一个标记
为 Tabs (跳格键位置)的标签仅在 Textflow 标签中的 hortabmethod 属性设置为 ruler 的情
况下可用。
选择块 块拷贝,块移动等几个块操作,都需在选择块后方可进行。用户可以通过块工具去
选择一个或多个块,如下所示:
> 若选择一个块,只需用鼠标单击相应块。
> 在按下 Shift 键的同时单击其他块以扩大选择。
> 若选择当前页的所与块,按 Ctrl-A (在 Windows 平台上)或 Cmd-A (在 Mac 平台上)
或 “编辑” -> “全部选定”。
上下文菜单 若已选定一个或多个块,则您可以打开上下文菜单以快速访问块相关的函数
(在 PDFlib 块菜单中同样可用)如要打开上下文菜单,在 Windows 上,在选定的块上单击
鼠标右键,或者在 Mac 上,按住 Ctrl 键并单击块。
例如,想删除一个块,用块工具选择此块,然后按 Delete 键,或在上下文菜单中选择
“编辑” -> “删除”。
微调块大小和位置 使用块工具,您可以将一个或多个选定的块移动到不同的位置。在移
动块时按住 Shift 键,可以保持块将沿着水平和垂直方向的移动。这对于块准确对齐很有帮
助。当指针位于块的转角处时将变为箭头,并且您可以重新调整块的大小。要调整多个块的
位置和大小,可以在选择两个或两个以上的块后,使用“PDFlib 块”菜单或上下文菜单中的
“对齐”、“居中”“分布”或“大小”命令进行调整。单个或多个块的位置也可以用箭头键
进行调整。
另外,您可以在属性对话框中输入用数字表示的块坐标。坐标系统的原点位于页的左上
角。当前在 Acrobat 中选定的坐标将按照单位显示。 . 更改显示单位的过程,如下所示:
> 在 Acrobat 6/7 中,转到 “编辑” ->“首选项”-> “[ 常规 ...]”->“单位和网线” [ 或在
Acrobat 7 标准版本中,“单位” ->“页面单位” ],并选择点、英寸、毫米、派卡、厘米
中的某一项。您还可以跳至 “视图” -> “导航标签” -> “信息”,并从 “选项”菜单中
选择一个单位。
> 在 Acrobat 5 中,跳至 “编辑” -> “首选项” -> “常规” -> “显示” -> “页面单位”,
并选择点、英寸、毫米中的某一项。您还可以跳至 “窗口” -> “信息”,并从 “信息”
菜单选择一个单位。
218 第 10 章: 数据变量和块
通过选择图像或图形建立块 作为手动拖动块矩形的一个替换,您可以使用现有页内容定
义块大小。首先,确保已启用菜单项 “PDFlib 块” -> “单击对象以定义块”。现在您可以
使用块工具单击页上的图像以建立图像大小的块。您也可以单击其他图形对象,块工具将试
图选择周围的图形(例如徽标)。单击对象功能是作为定义块的一个辅助功能。若您想重写
调整块的位置和大小,以后您可以不受任何限制的这样做。块将不会对作为定位和调整大小
的辅助工具使用的图像或图形对象锁定。
单击对象功能将试图识别形成页上的逻辑元素的矢量图形和图像。当单击一些页面内容
时,将选定此页面内容的边框(周围的矩形),除非此对象是空白或太大。在下一个步骤中,
其他部分包含在检测的矩形框中的对象将被添加导选定的区域,等等。最终区域将用作生成
的块矩形的基础。最终的结果是单击对象功能将试图选择完整图形,而不是选择单个行。
单击对象功能并不完善:根据页面内容的性质的不同,它不会总是选择用户所需内容。
请记住该功能仅可作为用于快速建立块矩形的定位辅助工具。
因为在背景应被忽略时,对字体属性进行自动检测会引起不希望发生的行为,使用 “PDFlib
块” -> “检测基本字体和颜色”可以启用或停用此自动检测。默认情况下,此功能被关闭。
锁定块 块可以被锁定,从而可以保护它们不会被意外的移动、改变大小或删除。当块工具
活动时,选择块并从块的上下文菜单中选择锁定。当块被锁定后,此块不能被移动、改变大
小或删除;也不可以显示块属性对话框。
交叠块 交叠块很难进行选择,因为用鼠标点击一个区域将总是选定最上层的块。在这种情
况下,可以使用上下文菜单中的 “选择块”项以按照块名称选择块。当块被选择后,随后
所有对于该区域的操作 (如双击)都针对被选择块,其他在此区域的块不会受影响。这样,
即使被局部或完全覆盖的块属性也可以很方便地编辑。
使用和恢复属性默认值 为了保存一些数量的键入和单击,块工具会记住在上一个块的属
性对话框中输入的属性值。当您建立一个新的块时,将再次使用这些值。当然,您可以随时
通过不同的值重写这些值。
按下属性对话框中的 “全部重置”按钮将大多数块属性重置为其相应的默认值。不过,
以下项将保持不变:
> Name、 Type、 Rect 和 Description 属性
> 所有自定义属性。
220 第 10 章: 数据变量和块
10.3.3 页和文件之间的块拷贝
块增效工具提供了几种在当前页,当前文档或不同文件间移动和拷贝块的方法:
> 拖动鼠标进行块移动或拷贝,或粘贴到别的页或打开的文件
> 在同一文件中,复制相同的块到一或多页里
> 导出块到新文件 (空白页面)或已存在文件 (对现有页使用块)
> 从其他文档导入块
为了在保留块定义的同时更新页面内容,您可以在保留块的同时替换以下页。使用 “文档”
-> “替换页面”(Acrobat 5 和 7)或 “文档” -> “页面” -> “替换”(Acrobat 6)。
复制块到其他页 您可以同时创建当前文档中的任意数目页上的一个或多个块的副本:
> 启用块工具,并选择您想要复制的块。
> 从 “PDFlib 块”菜单或上下文菜单选择 “导入和导出” -> “复制”。
> 选择要复制的块 (选定的块或页上的所有块)以及您想要用来复制块的目标页的范围。
在导出时,将块复制到其他文档 当导出块时,您可以立即对其他文档中的页使用这些
块,从而使这些块从一个文档传播到另一个文档。为此,选择一个现有文档,以将块导出到
此文档。若您启用复选框 “删除已存块”,则在将新的块复制到文档中之前,将删除目标文
档中可能存在的所有块。
所有域
位置 常规, Rect
Name 常规,名称
工具提示 常规,描述
外观,文本,文本颜色 文本,strokecolor,文本,fillcolor
文本域
单选按钮和复选框
列表框和组合框
按钮
222 第 10 章: 数据变量和块
具有相同名称的多个表单域 允许同一页面上的多个表单域具有相同的名称,而页上的块
名称必须是唯一的。当见表单域转换为块时,将为生成的块的名称添加一个用数字表示的后
缀以创建唯一的块名称 (另请参见第 223 页上的 “将表单域与对应块关联”)。
请注意,由于 Acrobat 中的某个问题,导致无法准确报告具有相同名称的表单域的域属
性。若多个域的名称相同而属性不同,则将不会在生成的块中反映这些差异。在这种情况
下,转换过程将发出警告并提供受影响的表单域的名称。在这种情况下,您应仔细检查生成
的块中的属性。
表 10.3 用于标识与块对应的原始表单域的自定义属性
自定义属性 含义
PDFlib: 域 : 名称 表单域的完全限定名称
10.4.1 常规属性
常规属性适用于所有块类型 (Text,Image,PDF)。对于块管理、自身描述块矩形的外观和管理
在块内部放置内容的方式,常规属性都是必需的。 PDFlib 块增效工具将自动生成必需的属
性。表 10.4 列出了常规属性。
表 10.4 常规块属性
keyword 可能的值和说明
块管理
Name (字符串;必需的)块名。在一页里,块名必须是唯一的,但同一块名可出现在同一文档的不同页
中。块名中不允许出现 [ ] / 这三个字符。块名最不能超过 125 个字符。
Description (字符串)块的函数的可供人读的说明,采用 PDFDocEncoding 或 Unicode 编码 (在后者情况下,以
BOM 开头)。此属性仅用于用户信息,在进行块处理时该属性将被忽略。
Locked (布尔值;可共享的)若值为 true,块增效工具将不能编辑该块及其属性。当进行块处理时该属性将
被忽略。默认值:false。
Rect (矩形;必需的)块坐标。坐标系统的原点位于页的左下角。不过,块增效工具将按照 Acrobat 的表
示法显示坐标,也就是说,原点在页的左上角。坐标将用在 Acrobat 中当前选定的单位进行显示,但
在 PDF 文档里将以点为单位进行存储。
Status (关键字)描述块将如何被处理。默认值:active。
active 该块将按照其属性设置被完全处理。
ignore 该块将被忽略。
static 不将放置任何可变内容;而将使用块的默认文本、图像或 PDF 内容 (如果可用)。
224 第 10 章: 数据变量和块
表 10.4 常规块属性
keyword 可能的值和说明
Subtype (关键字;必需的)取决于块类型,其值可为 Text、 Image 或 PDF
Type (关键字;必需的)始终为 Block
块外观
backgroundc (色彩;可共享的)若此属性存在并具有非 None 的色彩空间关键字,则将绘制一个矩形并用提供的
olor 颜色填充该矩形。这对覆盖当前页已有内容很有效。默认值:None
bordercolor (色彩;可共享的)若此属性存在并具有非 None 的色彩空间关键字,则将绘制一个矩形并用提供的
颜色为该矩形描边。默认值:None
linewidth (浮点型;可共享的;必须大于 0)用于绘制块边框的线宽度;只有在 bordercolor 被设置时才有效。
默认值:1
内容排版
fitmethod (关键字;可共享的)当提供的内容不能完全排入块矩形框时的策略。其可选值为 auto、 nofit、
clip、 meet1、 slice1 和 entire1。对于简单的文本块、图像和 PDF 块,将根据标准解释说明此属
性。默认值:auto。对于 Textflow 块 (此处的块对于文本太小),说明如下所示:
auto fontsize 和 leading 将被减小直至文本可完全排入矩形框
nofit 文本将超出块矩形框底线。
clip 文本将在块矩形框处剪切。
orientate (关键字;可共享的)当内容被放置时,指定内容的必需方向。其可选值为 north、 east、 south、
west。默认值:north
position1 (浮点型;可共享的)用于指定内容内的参考点的位置的一个或两个值。位置被指定为块中的百分
比。默认值:{0 0}, i.e. the lower left corner
rotate (浮点型;可共享的)在处理开始之前,块将反时针方向旋转的旋转角 (以度为单位)。参考点为旋
转的中心。默认值:0
226 第 10 章: 数据变量和块
表 10.5 Text 块属性
keyword 可能的值和说明
strokecolor (颜色)文本描边色。默认值:gray 0 (=black)
textflow (布尔值)控制单行或多行文本处理 (默认值:false£©£½
false 文本可以跨单行并将使用 PDF_fit_textline( ) 处理此文本。
true 文本将跨多行并将使用 PDF_fit_textflow( ) 处理此文本。将忽略常规属性位置。除了标准
文本属性之外,还可以指定所有 Textflow 相关的属性 (请参见表 10.6)。
textrendering (整型)文本渲染模式。默认值:0
textrise (浮点型或百分比)文本提升参数。其值为字体大小的百分比。默认值:0
underline (布尔值)下划线模式。默认值:false
underline- (浮点型、百分比或关键字)用于相对于基线的加下划线的文本的描边线的位置。其值为字体大小的
position 百分比。默认值:auto
underline- (浮点型、百分比或关键字)下划线文本的线宽。其值为字体大小的百分比。默认值:auto
width
wordspacing (浮点型或百分比)字间距。其值为字体大小的百分比。默认值:0
文本语义属性
tabalignchar (整型)小数部分以之对齐的字符 Unicode 值。默认值: ’ .’ 字符 (U+002E)
控制文本排版的属性
alignment (关键字)指定文本行在段落中的对齐方式。默认值:left。
left 起于 leftindent,向左对齐
center 以 leftindent 和 rightindent 之间的中心对齐
right 向右对齐,止于 rightindent
justify 左右两边对齐
firstlinedist (浮点型、百分比或关键字)定界框顶部与第一行文本的基线之间的距离,以用户坐标或相关字体大
小的百分比为单位 (用该行的第一个字体大小为单位,如果 fixedleading=true 并且该字体大小是
该行中最大的),或者用关键字。默认值:leading。
leading 第一行的行距值;常用可触及定界框顶部的典型字符如 À 为基准。
ascender 第一行的字体上伸部分;常用可触及定界框顶部的带较大的上伸部分的典型字符如 d 和 h
为基准。
capheight 为首行确定的大写高度值;常用可触及定界框顶部的典型的大写字母字符如 H 为基准。
xheight 第一行的行距值;常用可触及定界框顶部的典型字符如 À 为基准。
若 fixedleading=false 第一行里 leading、 ascender, xheight 或 capheight 中的最大值将被使用。
fixedleading (布尔值)如果值为 true,每行的第一个行距将作为该行的 leading 值。否则,每行的最大行距将作
为该行的 leading 值。默认值:false
228 第 10 章: 数据变量和块
表 10.6 textflow 块属性 (续)
keyword 可能的值和说明
控制分行算法的属性
adjust- (关键字)当使用大于等于 minspacing 并小于等于 maxspacing 的单词距离选项进行增加或缩减单词
method 间距离的调整后,仍有部分文本不能排入同一文本行时,所采用的方法。默认值:auto。
auto 按顺序使用以下方法:shrink、 spread、 nofit、 split。
clip 类似于 nofit,除了将剪切定界框 (考虑 rightindent 选项)右边缘的长的部分以外。
nofit 末尾单词将移动到下一行,以使剩余 (短)行将不会少于 nofitlimit 选项中指定的百分
比。即使对齐的段落也可能看起来有点不规则。
shrink 若单词不能完全排入当前行,将缩减文本直至 shrinklimit。若仍不能满足要求,则将使
用 nofit 方法。
split 末尾单词将不会移动到下一行,但是将强制对其添加连字符。为文本字体,而非为符号字
体插入连字符。
spread 末尾字将移动到下一行,并将根据 spreadlimit 通过增加词中字符之间的距离对齐剩余
(短)行。若仍无法实现对齐,则将使用 nofit 方法。
linespread- (浮点型或百分比;只有当 verticalalign=justify 时有效)垂直排版行距调整最大值,以用户坐标
limit 或相关行距的百分比为单位。默认值:200%
maxlines (整型或关键字)该属性值可以是整数代表定界框可容纳文本行的最大值;亦可是关键字 auto,代
表定界框所含文本行数没有限制。若已放置最大行数,则 PDF_fit_textflow( ) 将返回 _boxfull。
maxspacing (整型或百分比)单词间最大或最小的距离 (以用户坐标或间隔字符的宽度的百分比为单位)。计算
minspacing 的字间距受提供的值的限制 (但是仍将添加 wordspacing 选项)。默认值:minspacing=50%,
maxspacing=500%
nofitlimit (浮点型或百分比)对于 nofit 方式,所需文本行长度的下限 (以在用户坐标中或定界框的宽度的百
分比为单位)。默认值:75%.
shrinklimit (百分比)对于 shrink 方式,可缩减文本的下限;计算的收缩因素受限于提供的值,但是将乘以
horizscaling 选项提供的值。默认值:85%
spreadlimit (浮点型或百分比)对于 spread 方式,可调整字间距的上限; (以用户坐标中或字体大小的百分比
为单位);计算的字符距离将被添加到 charspacing 选项的值。默认值:0
1. 在用户坐标中,或作为定界框的宽度的百分比
2. 可以在 » 块属性 « 对话框中的 » 制表位 « 区域编辑标尺。
10.4.4 PDF 属性
PDF 相关的属性适用于 PDF 类型块 (除常规属性之外)。所有 PDF 相关的属性都可以被共
享。表 10.8 列出了 PDF 相关的属性。
10.4.5 自定义属性
自定义属性适用于各种块类型(除常规属性和特定块类型的属性之外)。自定义属性是可选
的,并不能共享。表 10.9 列出了自定义属性的命名规则。
表 10.9 自定义块属性
keyword 可能的值和说明
任何名称都不包含 (字符串、名称、浮点型或浮点型列表)与自定义属性对应的值的说明完全适用于客
[、 ]、 / 这三个字符。 户端应用程序。
230 第 10 章: 数据变量和块
10.5 使用 pCOS 询问块名及其属性
除了使用 PPS 进行自动块处理外,集成的 pCOS 实用工具可用于列举块名并询问标准属性或
自定义属性的功能。
寻找块的数目和名称。 客户可能甚至不知道导入的页上的块的名称和数量,因为这些也
可以查询。以下语句返回第 pagenum 页的块数:
blockcount = (int) p.pcos_get_number(doc,
"length:pages[" + pagenum + "]/PieceInfo/PDFlib/Private/Blocks");
请注意,在默认的用户坐标系统 (该系统的原点位于左下角,也许被页的裁剪框修改)中
提供这些坐标,而块增效工具根据 Acrobat 的用户界面坐标系统 (该系统的原点位于页的
左上角)显示坐标。因为用于重写块坐标的 Rect 选项不会考虑裁剪框项使用的任何修改,所
以若裁剪框存在,则从原始块查询的坐标不能直接作为新坐标使用。作为工作区,您可以使
用 refpoint 和 boxsize 选项。
还请注意,当查询块坐标时,不会考虑 topdown 参数。
若您不知道在块中实际存在的是哪一个自定义属性,可以在运行时确定名称。为了找到块中
名为 b1 的第一个自定义属性的名称,可以使用以下语句:
propname = p.pcos_get_string(doc,
"pages[" + pagenum + "]/PieceInfo/PDFlib/Private/Blocks/b1/Custom[0].key");
232 第 10 章: 数据变量和块
10.6 PDFlib 块规格
PDFlib 块语法完全符合 PDF 引用,该引用指定一个扩展机制,此机制允许应用程序存储附
加到包含一个 PDF 页的数据结构的私人数据。下面提供 PDFlib 块语法的具体描述,以方便
一些用户想通过 PDFlib 块增效工具之外的方式建立 PDFlib 块。对于使用 PDFlib 增效工具
的用户,可跳过此章节。
表 10.11 块列表字典中的项
关键字 值
Version (数字;必需的)文件要遵从的块规格的版本号。此文档说明块规格的版本 7。
Blocks (字典;必需的)每个项都是一个包含块的名称的名称对象;相应的值是用于此块的块字典 (请参见
表 10.13)。块字典中的 /Name 项必须与此字典中的块的名称一致。
PluginVersion (字符串;必需的,除非 pdfmark 项存在1)包含 PDFlib 块增效工具的版本识别的字符串,该增效工
具已用于创建块。
pdfmark (布尔值;必需的,除非 PluginVersion 项存在 1)若块列表是用 pdfmarks 生成的,则此值必须为
true。
表 10.12 用于块属性的数据类型
块类型 PDF 类型和备注
boolean (布尔值)
string (字符串)
keyword (名称)提供特殊属性支持的关键字的列表之外的关键字是错误的。
float, integer (数字)选项列表支持点和逗号作为十进制分隔符,而 PDF 数字仅支持小数点。
percentage (两个元素的数组)数组中的第一个元素是数字,第二个元素是含有百分比符号的字符串。
color (两个或三个元素的数组)数组中的第一个元素指定一个色彩空间,第二个元素指定一个色彩值,
如下所示。数组中的第一个元素支持以下项:
/DeviceGray
第二个元素是单个灰度值。
/DeviceRGB
第二个元素是含有三个元素 (RGB 值)的数组。
/DeviceCMYK
第二个元素是含有四个元素 (CMYK 值)的数组。
[/Separation/spotname]
第一个元素是一个包含关键字 /Separation 和一个专色名称的数组。第二个元素是一个
色调值。
数组中的第三个元素为该专色指定一个替代颜色,替代颜色本身是 /DeviceGray、
/DeviceRGB、 /DeviceCMYK 或 /Lab 色彩空间中的一个颜色数组。若替代色缺失,则专色
名称必须指向一个 PDFlib 内部已知的颜色,或者是应用程序已在运行时定义的颜色。
[/Lab] 第一个元素是包含关键字 /Lab 的数组。第二个元素是一个含有三个元素 (Lab 值)的
数组。
若要指定不使用某种颜色,必须省略相应的属性。
表 10.13 块字典中的项
关键字 值
234 第 10 章: 数据变量和块
示例 以下片段显示用于两个块的 PDF 代码,这两个块分别为称作 job_title 的文本块和称
作 logo 的图像块。文本块包含称作 format 的自定义属性:
<<
/Contents 12 0 R
/Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 842 ]
/PieceInfo << /PDFlib 13 0 R >>
>>
13 0 obj
<<
/Private <<
/Blocks <<
/job_title 14 0 R
/logo 15 0 R
>>
/Version 7
/PluginVersion (3.0)
>>
/LastModified (D:20060813200730)
>>
endobj
14 0 obj
<<
/Type /Block
/Rect [ 70 740 200 800 ]
/Name /job_title
/Subtype /Text
/fitmethod /auto
/fontname (Helvetica)
/fontsize 12
/Custom << /format 5 >>
>>
endobj
15 0 obj
<<
/Type /Block
/Rect [ 250 700 400 800 ]
/Name /logo
/Subtype /Image
/fitmethod /auto
>>
[{ThisPage} <<
/PieceInfo <<
/PDFlib <<
/LastModified (D:20060813200730)
/Private <<
/Version 7
/pdfmark true
/Blocks {B1}
>>
>>
>>
>> /PUT pdfmark
236 第 10 章: 数据变量和块
A 修订历史记录
日期 更改
A 修订历史记录 237
索引
A 超文本字符串 72
在不支持 Unicode 的语言中 73
Adobe 字体规格 (AFM) 92 出血框 53
AES (高级加密标准) 187 垂直书写模式 110, 111
AFM (Adobe 字体规格) 92 错误处理 43
alpha 通道 119
AS/400 50
ascender 106 D
asciifile 参数 50 defaultgray/rgb/cmyk 参数 62
auto descender 106
请参见 hypertextformat dpi 计算 116
autocidfont 参数 101 打印机字体 ASCII (PFA) 92
autosubsetting 参数 101 打印机字体二进制 (PFB) 92
安全性 187 打印机字体规格 (PFM) 92
代码页 Microsoft Windows 1250-1258 77
B 单位 51
当前点 54
Big 5 82 等宽字体 107
BMP 118 多页图像文件 122
builtin 编码 103
bytes
请参见 hypertextformat
E
byteserving 190 EBCDIC 50
绑定 23 ebcdic 编码 77
表单域 ebcdicutf8
转换为块 222 请参见 hypertextformat
标准输出条件 EJB (Enterprise Java Bean) 28
用于 PDF/A 199 encoding
CJK 80
custom 78
C 从系统获取 78
C 绑定 25 errorpolicy 参数 125
C++ 绑定 27 eServer zSeries and iSeries 50
capheight 106 EUDC (终端用户定义的字符) 93, 113
CCITT 118
CCSID 78
CFF (Compact Font Format) 89
F
CIE L*a*b* 色彩空间 59 fontmaxcode 参数 104
CJK (中文、日文、韩文) FontSpecific 编码 103
标准字体 80 form XObjects 54
配置 80
Windows 代码页 82 G
自定义字体 111
clip 54 gaiji 字符 89
CMap 80, 81
GBK 82
GIF 117
Cobol 绑定 23
grid.pdf 51
COM (组件对象模型)绑定 24
公制坐标 51
copyoutputintent 选项 195, 200
规格 106
CPI (字符 / 英寸) 107
currentx 和 currenty 参数 106
裁剪框 53
裁切框 53
索引 239
H mask 120
masked 120
HKS 专色 58 masterpassword 188
HTML 字符引用 83 MediaBox 53
hypertextformat 参数 74 “每次一页”下载 190
韩文 81, 82, 110 蒙版图像 119
毫米 51 描边 54
核心字体 96 名称字符串 72
环境变量 PDFLIBRESOURCE 48 在不支持 Unicode 的语言中 73
模板 54
I 默认坐标系统 51
IBM eServer 50
ignoremask 121 N
image:iccprofile 参数 61 .NET 绑定 30
iSeries 50 内嵌图像 115
ISO 10646 69 内容字符串 72
ISO 15930 191
ISO 19005 196
ISO 8859-2 到 ISO 8859-15 77
O
OpenType 字体 89
overline 参数 109
J 欧元字符 104
Java 绑定 28
EJB 28
javadoc 28
P
servlet 28 PANTONE 专色 57
pCOS 173
Java 应用程序服务器 28
JFIF 116 加密 183
Johab 82 路径语法 177
JPEG 116 数据类型 174
JPEG2000 117 伪对象 179
基线压缩 116 PDF 导入库 (PDI) 123
PDF/A 196
加密 187
PDF/X 191
加密的 PDF 文档 183
PDF/X 的标准输出条件 194
渐变 56
PDF/X 的输出描述 192, 197
PDF_get_buffer() 49
K PDFlib 的功能 19
kerning 107 PDFlib 功能 19
可移植文档格式 (PDF) 参考手册 173 PDFlib Personalization Server 211
口令 187 pdflib.upr 48
好和坏 188 PDFLIBRESOURCE 环境变量 48
块 211 PDI 123
属性 214 pdiusebox 124
增效工具 211 Perl 绑定 31
permissions 187, 189
PFA (打印机字体 ASCII) 92
L PFB (打印机字体二进制) 92
leading 106 PFM (打印机字体规格) 92
LWFN (LaserWriter 字体) 92 PHP 绑定 33
利用块进行数据变量处理 211 PNG 116, 120
临时磁盘空间要求 190 PostScript 字体 89, 92
路径 54 PPS (PDFlib Personalization Server) 211
print_glyphs.ps 93
M Python 绑定 35
平滑混合 56
macroman 编码 76, 77
macroman_apple 编码 104
makepsres 实用工具 46
240 索引
Q U
嵌入字体 99 UHC 82
underline 参数 109
R UPR (Unix PostScript 资源) 46
文件格式 46
REALbasic 绑定 36 文件搜索 48
renderingintent 选项 59 usehypertextencoding 参数 74
resourcefile 参数 48 usercoordinates 参数 51
RPG 绑定 37 userpassword 188
Ruby 绑定 40 UTF 格式 70
日语 81, 82, 110 utf16
软蒙版 119 请参见 hypertextformat
utf16be
S 请参见 hypertextformat
utf16le
S/390 50
SearchPath 参数 47 请参见 hypertextformat
servlet 28 utf8
请参见 hypertextformat
setcolor:iccprofilegray/rgb/cmyk 参数 61
Shift-JIS 82
SPIFF 116 W
sRGB 色彩空间 61 winansi 编码 77
strikeout 参数 109 Windows 的样式名称 98
subsetminsize 参数 101 Windows 的字体样式名称 98
Symbol 字体 103 网页优化 PDF 190
上标 106 伪字体样式 108
商业许可证 9 文本变体 106
生成的 PDF 文件输出到内存 49 文本规格 106
书写模式 110, 111 文本位置 106
水平书写模式 110, 111
宿主编码 76
宿主字体 98
X
缩放图像 116 xheight 106
XObjects 54
T 系统编码支持 78
下标 106
Tcl 绑定 41 显式透明度 120
Textflow 中符号字体的 textlen 143 线性化 PDF 190
textformat 参数 74 像素取样 116
textrendering 参数 109 行间距 106
textx 和 texty 参数 106 渲染方法 59
TIFF 117
选项列表中的字符串 75
TrueType 字体 89 旋转对象 52
TTC (TrueType 集合) 93, 111, 112
TTF (TrueType 字体) 89
Type 1 字体 92
Y
Type 3 (用户定义的)字体 94 页大小
填充 54 Acrobat 中的限制 53
透明度 119 页格式 53
图案 56 页面 122
图层和 PDI 124 页面大小 174
图像蒙版 119, 120 页面说明 51
图像数据,重用 115 异常 43
图像缩放 116 隐式透明度 119
图像文件格式 116 英寸 51
用户定义的 (Type 3) 字体 94
索引 241
用户空间 51 字体规格 106
用于建立块的 Acrobat 增效工具 211 字体样式 108
用于建立块的增效工具 211 字形 70
优化的 PDF 190 字形 ID 寻址 104
语言绑定 字形可用性 87
请参见绑定 字形名称引用 84
原始图像数据 118 字形替换 86
资源的类别 46
Z 资源类别 46
坐标系统 51
ZapfDingbats 字体 103 公制 51
zSeries 50
自上而下 52
在不支持 Unicode 的语言中的内容字符串 73 作品框 53
在内存中生成 PDF 文档 49
着色 56
中文 81, 82, 110
专色 (分色色彩空间) 57
转义序列 83
自定义编码 78
字符 / 英寸 107
字符规格 106
字符和字形 70
字符名称 93
字符引用 83, 84
子集化 101
字节顺序标记 (BOM) 71, 74
子路径 54
自上而下的坐标 52
字体
AFM 文件 92
等宽 107
embedding 99
OpenType 89
PDF 核心集 96
PFA 文件 92
PFB 文件 92
PFM 文件 92
PostScript 89, 92
TrueType 89
Type 1 92
Type 3 94
Type 3 (用户定义的)字体 94
用户定义的 (Type 3) 94
有关嵌入的法律事宜 100
子集化 101
字形名称 93
资源配置 46
242 索引