pdfexplained(翻译)第四章文档结构(代码片段)

ball球 ball球     2022-12-10     118

关键词:

本文是对PDF Explained(by John Whitington)第四章《Document Structure》的摘要式翻译。

本章我们来看PDF的逻辑结构,涉及trailer字典,文档目录(document catalog)和页面树以及PDF中两种常见结构:文本字符串和日期。

一个典型的PDF文档逻辑结构如下图所示:
image

Trailer字典

这份字典位于文件尾部而不是文件的主体中,如果程序想要读取PDF文档,首先要做的就是处理trailer字典。
字典中的重要条目如下表所示,*表示必选条目。

值类型
/Size*整数交叉引用表中的条目总数(通常等于文件中的对象个数加1)
/Root*间接引用字典文档目录
/Info间接引用字典文档信息字典
/ID两个字符串的数组文件在工作流中唯一标识。第一个字串在文件首次创建时确定,第二个字串随工作流系统对文件的修改而修改。

下面是一个trailer字典的例子:

<<
   /Size 421
   /Root 377 0 R
   /Info 375 0 R
   /ID [<75ff22189ceac848dfa2afec93deee03> <057928614d9711db835e000d937095a2>]
>>

处理了trailer字典后,我们就可以继续读取文档信息字典和文档目录。

文档信息字典

文档信息字典包含文件的创建日期和修改日期,以及一些简单的元数据。

文档信息中的条目如下表所示,表中提到的“文本字串”和日期字串将在后文中详述。

值类型
/Title文本字串文档标题。请注意,这与第一页上显示的任何标题无关。
/Subject文本字串文档主题。同样,这只是元数据,没有关于内容的特定规则
/Keywords文本字串文档关键字。
/Author文本字串文档作者
/CreationDate日期字串文档创建日期
/ModDate日期字串文档最后修改日期
/Creator文本字串最初创建此文档的程序的名称。文档起初可能是其它格式,比如Microsoft Word。
/Producer文本字串将此文件转换为PDF的程序的名称。

一个典型的文档信息字典如下例所示:

<<
   /ModDate (D:20060926213913+02'00')
   /CreationDate (D:20060926213913+02'00')
   /Title (catalogueproduit-UK.qxd)
   /Creator (QuarkXPress: pictwpstops filter 1.0)
   /Producer (Acrobat Distiller 6.0 for Macintosh)
   /Author (James Smith)
>>

文档目录(Document Catalog)

文档目录是对象图的根对象(节点),从它出发可以通过间接引用触达所有其他对象。下表列出了文档目录中的条目,*为必选条目。

值类型
/Type*名称必须是/Catalog
/Pages*间接引用字典页面树的父节点
/PageLabels编号树(number tree)一棵编号树,给出了该文档的页面标签。这种机制允许文档中的页面具有比1,2,3更复杂的编号方式…例如,书籍的前言可以编号为i,ii,iii …而主要内容 再次以1,2,3开始…这些页面标签仅用于在PDF查看器中显示,与打印输出无关。
/Names字典名称字典,名称到条目的映射。
/Dests字典该字典将名称映射至目的地。目的地是对超链接跳转位置的描述。
/ViewerPreferences字典查看器首选项字典,用于指定文档在屏幕的显示方式,例如缩放比例等。
/PageLayout名称指定PDF查看器使用的页面布局。值为/SinglePage,/OneColumn,/TwoColumnLeft,/TwoColumnRight,/TwoPageLeft,/TwoPageRight。(默认值:/SinglePage)。详情见ISO 32000-1:2008的表28
/PageMode名称指定PDF查看器使用的页面模式。值为/UseNone,/UseOutlines,/UseThumbs,/FullScreen,/UseOC,/UseAttachments。 (默认值:/UseNone)。详情见ISO 32000-1:2008的表28
/Outlines间接引用字典大纲字典是文档大纲的根,通常称为书签
/Metadata间接引用流文档的XMP元数据

页面和页面树

由页面字典构建的页面树汇集了用于绘制图形和文本内容的指令以及相关的资源(字体,图片,外部数据)。同时还包含页面大小,以及一些裁剪框。

下表列出了页面字典中的条目,*为必选条目。

值类型
/Type*名称必须为/Page
/Parent*间接引用字典当前节点的父节点
/Resources字典页面资源(字体、图片等)。如果省略这项,所需资源将从页面树中的父节点继承。如果的确无需任何资源,请保留些项,使用空字典。
/Contents对数组,流等的间接引用页面的图形内容。如果缺少此条目,则页面为空。
/Rotate整数页面旋转角度,单位:度。值必须是90的倍数。默认值:0。这适用于查看和打印。如果缺少此条目,则其值将从父节点继承。
/MediaBox*长方形页面的媒体框。大多数情况指页面大小。如果缺少此条目,将从父节点继承。
/CropBox长方形页面的裁剪框。定义了在显示或打印页面时默认的可见区域。如果不存在,则取媒体框的值。

用于媒体框和其它框的矩形数据结构是包含四个数字的数组。它们定义了矩形的对角–数组的前两个元素是一个角的x和y坐标,后两个元素是另一个角的x和y坐标。 通常给出的是左下角和右上角。例如:

/MediaBox [0 0 500 800]
/CropBox [100 100 400 700]

定义一个500 x 800点的页面,裁剪框在页面的每一侧保留100个点。

页面通过页面树链接在一起。设计良好的PDF应用程序会构建一棵平衡树(具有最小高度的树)。这可确保任何页面均可被快速定位。没有子节点的节点(页节点)就是页面。 下图显示了由七个页构成的页面树。

image

该页面树对应的对象如下:

1 0 obj Root node
<< /Type /Pages /Kids [2 0 R 3 0 R 4 0 R] /Count 7 >>
endobj
2 0 obj Intermediate node
<< /Type /Pages /Kids [5 0 R 6 0 R 7 0 R] /Parent 1 0 R /Count 3 >>
endobj
3 0 obj Intermediate node
<< /Type /Pages /Kids [8 0 R 9 0 R 10 0 R] /Parent 1 0 R /Count 3 >>
endobj
4 0 obj Page 7
<< /Type /Page /Parent 1 0 R /MediaBox [0 0 500 500] /Resources << >> >>
endobj
5 0 obj Page 1
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 500 500] /Resources << >> >>
endobj
6 0 obj Page 2
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 500 500] /Resources << >> >>
endobj
7 0 obj Page 3
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 500 500] /Resources << >> >>
endobj
8 0 obj Page 4
<< /Type /Page /Parent 3 0 R /MediaBox [0 0 500 500] /Resources << >> >>
endobj
9 0 obj Page 5
<< /Type /Page /Parent 3 0 R /MediaBox [0 0 500 500] /Resources << >> >>
endobj
10 0 obj Page 6
<< /Type /Page /Parent 3 0 R /MediaBox [0 0 500 500] /Resources << >> >>
endobj

中间节点及根节点使用的条目如下(*为必选)

值类型
/Type*名称必须是/Pages
/Kids*间接引用数组该节点的直接子页面树节点。
/Count*整数该节点的子节点数量
/Parent页面树节点的间接引用指向该节点的父节点。除根节点外,所有节点必须有此条目。

文本字符串

页面实际文本内容之外的字符串(例如,书签名称,文档信息等)被称为文本字符串。 它们使用PDFDocEn编码或Unicode编码(使用更广)。

编码为Unicode的文本字符串通过查看前两个字节来区分:这些字符将是254后跟255.这是Unicode字节顺序标记U + FEFF,表示UTF16BE编码。 这意味着PDFDocEncoding字符串不能以þ(254)后跟ÿ(255)开头,但这在任何合理的情况下都不太可能发生。

日期

日期字符串的格式为: (D:YYYYMMDDHHmmSSOHH’mm’)

其中括号表示字符串。其他部分的含义如下表所示。

含义
YYYY四位年份,例如2008年
MM月份,从01到12的两位数
DD日期,从01到31的两位数
HH小时,从00到23的两位数
mm分钟,从00到59两位数
SS秒,从00到59两位数
O本地时间与世界时的关系,取值为:+,- 或Z。分别表示晚于, 早于,等于世界时间。
HH’世界时间的小时偏差,从00到23的两位数
mm’世界时间的侰偏差,从00到23的两位数

年份之后的部分都是可选的。例如,(D:1999)就是全法有效的。DD和MM的默认值为01,对于所有其他部分,默认值为零。例如:(D:20060926213913+02’00’)
代表2006年9月26日下午9:39:13,比世界时间早两个小时的时区。

整合

下面这是一个手动创建的文本,它是一个三页的文档。

%PDF-1.1 //Header
1 0 obj //Top-level of page tree: has two children—page one and an intermediate page tree node
<< /Kids [2 0 R 3 0 R] /Type /Pages /Count 3 >>
endobj 
4 0 obj //Contents stream for page one
<< >>
stream
1. 0.000000 0.000000 1. 50. 770. cm BT /F0 36. Tf (Page One) Tj ET 
endstream 
endobj 
2 0 obj //Page one
<<
  /Rotate 0
  /Parent 1 0 R
  /Resources 
    << /Font << /F0 << /BaseFont /Times-Italic /Subtype /Type1 /Type /Font >> >> >>
  /MediaBox [0.000000 0.000000 595.275590551 841.88976378]
  /Type /Page
  /Contents [4 0 R]
>>
endobj 
5 0 obj //Document catalog
<< /PageLayout /TwoColumnLeft /Pages 1 0 R /Type /Catalog >>
endobj 
6 0 obj //Page three 
<<
  /Rotate 0
  /Parent 3 0 R
  /Resources 
    << /Font << /F0 << /BaseFont /Times-Italic /Subtype /Type1 /Type /Font >> >> >>
  /MediaBox [0.000000 0.000000 595.275590551 841.88976378]
  /Type /Page
  /Contents [7 0 R]
>>
endobj 
3 0 obj //Intermediate page tree node, linking to pages two and three
<< /Parent 1 0 R /Kids [8 0 R 6 0 R] /Count 2 /Type /Pages >>
endobj 
8 0 obj //Page two 
<<
  /Rotate 270
  /Parent 3 0 R
  /Resources 
    << /Font << /F0 << /BaseFont /Times-Italic /Subtype /Type1 /Type /Font >> >> >>
  /MediaBox [0.000000 0.000000 595.275590551 841.88976378]
  /Type /Page
  /Contents [9 0 R]
>>
endobj 
9 0 obj //Content stream for page two
<< >>
stream
q 1. 0.000000 0.000000 1. 50. 770. cm BT /F0 36. Tf (Page Two) Tj ET Q
1. 0.000000 0.000000 1. 50. 750 cm BT /F0 16 Tf ((Rotated by 270 degrees)) Tj ET
endstream 
endobj 
7 0 obj Content stream for page three
<< >>
stream
1. 0.000000 0.000000 1. 50. 770. cm BT /F0 36. Tf (Page Three) Tj ET 
endstream 
endobj 
10 0 obj //Document information dictionary 
<<
  /Title (PDF Explained Example)
  /Author (John Whitington)
  /Producer (Manually Created)
  /ModDate (D:20110313002346Z)
  /CreationDate (D:2011)
>>
endobj xref
0 11
trailer //Trailer dictionary
<<
  /Info 10 0 R
  /Root 5 0 R
  /Size 11
  /ID [<75ff22189ceac848dfa2afec93deee03> <75ff22189ceac848dfa2afec93deee03>]
>>
startxref
0
%%EOF

上述代码通过pdftk处理后即可在Acrobat Reader中展现。
image

对象图如下:
image

pdfexplained(翻译)第三章文件结构(代码片段)

本文是对PDFExplained(byJohnWhitington)第三章《FileStructure》的摘要式翻译。文件布局一个简单合法的PDF文件按顺序可分为如下四部分:header,给出了PDF版本号body,包含了页面,图形内容,和许多辅助信息,它们... 查看详情

文档结构(代码片段)

本文是对PDFExplained(byJohnWhitington)第四章《DocumentStructure》的摘要式翻译。本章我们来看PDF的逻辑结构,涉及trailer字典,文档目录(documentcatalog)和页面树以及PDF中两种常见结构:文本字符串和日期。一个典型的PDF文档逻... 查看详情

文档结构(代码片段)

本文是对PDFExplained(byJohnWhitington)第四章《DocumentStructure》的摘要式翻译。本章我们来看PDF的逻辑结构,涉及trailer字典,文档目录(documentcatalog)和页面树以及PDF中两种常见结构:文本字符串和日期。一个典型的PDF文档逻... 查看详情

pdfexplained(翻译)第六章文本和字体(代码片段)

本文是对PDFExplained(byJohnWhitington)第六章《TextAndFonts》的摘要式翻译,并加入了一些自己的理解。文本状态文本状态相关的操作符和参数如下表所示:操作符操作数(参数)描述默认值例TccharSpaceTc将字符间距设为charSpace0TwwordS... 查看详情

pdfexplained(翻译)第二章构建一个简单的pdf(代码片段)

本文是对PDFExplained(byJohnWhitington)第二章《BuildingaSimplePDF》的摘要式翻译。本章我们将使用文本编辑器手动构建PDF内容。然后我们将使用pdftk将其转换为有效的PDF文件,并在PDF查看器中进行查看。关于PDFTK(THEPDFTOOLKIT)p... 查看详情

coreanimation文档翻译(第四篇)

CoreAnimation文档翻译(第四篇)让Layer的content动画起来核心动画的基础接口以及为拥有Layer的View做的动画扩展接口,使得为Layer制作复杂动画变得简单化。例如改变Layer的frame的size、改变Layer在屏幕上的position、应用旋转transform、或... 查看详情

文档元数据和导航(代码片段)

本文是对PDFExplained(byJohnWhitington)第七章《DocumentMetadataandNavigation》的摘要式翻译,并加入了一些自己的理解。本章我们讨论四个辅助数据,这些数据并不影响PDF的显示。定位(Destinations):定义文件中位置的数... 查看详情

第四章hotspotjvm中的垃圾回收机制

有很多有名的Jvm,但我们最常用到的就是Oracle收购sun公司的HotSpot。HotSpot中内存被分为3个代:年轻代(younggeneration),年老代(oldgeneration),持久代(permanentgeneration)。对象最初在年轻代,年老代代理存放着是经过几次年轻代... 查看详情

简介

本文是对PDFExplained(byJohnWhitington)的摘要式翻译。一.一点历史PDF的发展PDF起初是Adobe的一个内部项目,其目标是创建一种平台无关的文档交换方式。当时PostScript已经在印刷界非常流行,但在当时的电脑屏幕显示上还不是很... 查看详情

fabric2.4文档翻译12体系结构参考-03fabric网关(代码片段)

FabricGateway官方文档:https://hyperledger-fabric.readthedocs.io/en/latest/gateway.html参考翻译:https://blog.csdn.net/zhanglingge/article/details/122926437FabricGatewayisaservice,introducedinHype 查看详情

coreanimation文档翻译(第五篇)

?构建Layer层次结构在APP中大多数情况下,将Layer和View对象结合使用是Layer最好的使用方式。然而,很多时候我们可能需要通过添加单独的Layer对象,以便增加视图继承层次;当为了提高性能,或为了实现View很难实现的特性,此时... 查看详情

blender文档翻译:rna

 这是关于DataAPI实现的文档,有一些示例代码,帮助得到所有的Blender数据包装!查看任务列表。 --Brecht 22:35,31October2008(UTC)实现在Blender2.5分支中的实现,位于makesrna模块。了解系统的重要文件是: RNA_types.h:重要的RN... 查看详情

fabric2.4文档翻译12体系结构参考-03fabric网关(代码片段)

...ff1a;https://hyperledger-fabric.readthedocs.io/en/latest/gateway.html参考翻译:https://blog.csdn.net/zhanglingge/article/details/122926437FabricGatewayisaservice,introducedinHyperledgerFabricv2.4peers,thatprovidesasimplified,minimalAPIforsubmittingtransactionstoaFabricnetwork.Requirementsp... 查看详情

sysfs.txt文档翻译(代码片段)

sysfs-用于导出内核对象的文件系统。1.sysfs是一个基于ram的文件系统,最初基于ramfs。它提供了一种方法,可以将内核数据结构,它们的属性以及它们之间的链接导出到用户空间。sysfs本质上与kobject基础结构相关联。有关kobject接... 查看详情

选择器—文档结构

1、结构文档中有2种关系,父子关系或祖先-后代关系;父子关系是一种特殊的祖先-后代关系。2、语法结构如下:  祖先  后代{属性名:属性值}  祖先  后代之间间隔一代的父子关系,也可以是间隔很多代的... 查看详情

httpclient教程

...译文档:第一章基础第二章连接管理第三章HTTP状态管理第四章HTTP认证第五章HTTP客户端服务第六章高级主题封装HttpClient 轻松把玩HttpClient之封装HttpClient工具 查看详情

pymongo官方文档翻译——vnpy(代码片段)

PyMongo是MongoDB数据库的python模块VNPY默认的数据库,没有采用SQL类型的数据库,而是采用No-Sql类型的MongoDB数据库,对于想了解VNPY内部结构的童鞋,多多少少会遇到PyMongo的调用问题,虽然我个人不喜欢用数据库的方式存储证券行情... 查看详情

.mo翻译文件结构解析(代码片段)

.Mo翻译文件结构解析.mo文件是.po文件经msgfmt编译后生成的翻译文件,便于程序阅读.我这段时间折腾了下i18n,根据Gettext的文档研究了一下Mo文件的结构,在C#上实现了mo文件的解析和浏览,现把.mo的结构和基于Winform实现的Mo查看器分享... 查看详情