使用声明的图形状态剪切路径解析 PDF 文本位置
Parse PDF text position with graphics state clipping path declared
请原谅发帖时间过长,但无论谁回答这个问题,无疑都需要提供的所有信息。
我为我正在从事的项目成功地实施了 PDF 解析。在追查特定 PDF 中文本精确定位的问题时,我发现我的计算是错误的。以下是 PDF 的相关片段(使用 qpdf -qdf
):
相关 PDF 片段
%% Page 1
8 0 obj
<<
/Contents [
10 0 R
12 0 R
]
/MediaBox [ 0 0 612 792 ]
/Type /Page
>>
endobj
=====
9 0 obj
<<
/MediaBox [ 0 0 595 842 ]
/Type /Pages
>>
endobj
======
%% Contents for page 1
10 0 obj
<<
/Length 11 0 R
>>
stream
q
.94062 0 0 .94062 26.16627 0 cm
0 0 m
595 0 l
595 842 l
0 842 l
0 0 l
h
W n
q
16.84 16.84 561.32 808.32 re
W n
q
.24 0 0 .24 90.75993 740.44 cm
BT
133 0 0 133 0 0 Tm /TT1.0 1 Tf .0017 Tc [(The)1( )1(Long )1(Tai)1(l)]TJ
ET
我删除了每个片段的无关部分。
以下详细说明了我计算第 1 页第一个单词中 T 的确切 PDF 矩形。
上面最后一个 PDF 片段流中操作的描述和效果
q : 推送图形状态(GS)。
ctm = identity
cm : 修改ctm
| 0.94062 0 0 |
ctm = | 0 0.94062 0 |
| 26.16627 0 1 |
m : 起始路径在 0, 0
l : 线到 595, 0
l : 线路到 595, 842
l : 线路到 0, 842
l : 线到 0, 0
h : 关闭路径
No op since path already closed
n : 与 GS 剪切路径相交
GS clipping path wasn't set, so GS clipping path is the closed path that
defines rect [0 0 595 842]
q : 推送 GS
re : 创建闭合路径
Path defines rect [16.84 16.84 561.32 808.32]
n : 与 GS 剪切路径相交
The incoming path is totally contained in current GS clipping path,
so the GS clipping path becomes the incoming path, which defines the rect
[16.84 16.84 561.32 808.32]
q : 推送 GS
cm : 修改ctm
| 0.941 0 0 | | 0.24 0 0 | | 0.226 0 0 |
ctm = | 0 0.941 0 | * | 0 0.24 0 | = | 0 0.226 0 |
| 26.167 0 1 | | 90.756 740.44 1 | | 97.04 740.44 1 |
BT : 开始文本对象
Tm : 设置文本和行矩阵
| 133 0 0 |
tm = lm = | 0 133 0 |
| 0 0 1 |
Tf : 设置文字字体和字号
Set font to TT1, which has ascent=750, descent=-250, and glyph width T=667
(I will only need the width of T below). Font size is set to 1.
This has the effect of setting the first component in calculating the text
rendering matrix to
| 1 0 0 |
| 0 1 0 |
| 0 -0.25 1 |
Tc : 设置文本字符间距
TJ : 显示文字
计算 T 的 PDF 矩形
我们的计算目标文本将是显示的第一个文本,字母
T(因此上面提供了唯一的字形宽度)。执行文本显示
运算符 TJ,我们首先按照 PDF 规范 9.4.4 部分中的规定计算 Trm =](PDF 32000-1:2008) :
a = Tfs * Th = 1 * 1 = 1
d = Tfs = 1
ty = Trise = -250/1000 = -0.25
| a 0 0 |
Trm = | 0 d 0 | * Tm * ctm
| 0 ty 1 |
| 1 0 0 | | 133 0 0 | | 0.226 0 0 |
Trm = | 0 1 0 | * | 0 133 0 | * | 0 0.226 0 |
| 0 -0.25 1 | | 0 0 1 | | 97.04 740.44 1 |
| 30.06 0 0 |
= | 0 30.06 0 |
| 97.04 732.93 1 |
还计算了字形宽度(水平位移)和字形高度
根据 9.4.4:
部分
width = width of 'T' / 1000 = 0.667
height = (ascent - descent) / 1000 = (750 + 250) / 1000 = 1
字母 T 的正文是:
textRect for 'T' = [ 0 decent/1000, width, height ]
= [ 0 -0.25, 0.667, 1 ]
T 渲染在由 ctm 转换的文本矩形上。计算 T 的结果 PDF 矩形:
PDF 矩形:97.04 732.93 20.03 30.02
我已经在 Acrobat 和 Preview 中为 T 创建了高亮注释
并使用该信息来确定 PDF 位置的计算
T 在这两个程序中为:
Acrobat : 111.54 718.99 20.03 30.02
预览 : 111.54 718.99 20.03 30.02
与Acrobat和Preview相比,我有dx = -14.5和dy = 13.31, 即我是
T.
的实际位置太左太高
对于未更改媒体框或未声明图形的 PDF
状态剪切路径我所有的计算都是正确的。我知道一定有关系
PDF 对象 8 0 和 9 0 中不同的媒体框声明,或者,
更有可能的是,由 m, l, h, n, 产生的图形状态剪切路径
和 re 运算符,这导致
的矩形剪切路径 rect
[ 16.84 16.84 561.32 808.32 ]
媒体盒是
[ 0 0 595 842 ]
我在 PDF 规范中找不到任何部分表明我的计算因图形状态剪切路径而发生变化(再次假设
是罪魁祸首)。
呃。我错过了什么?
这里有一个错误:
cm : 修改ctm
| 0.941 0 0 | | 0.24 0 0 | | 0.226 0 0 |
ctm = | 0 0.941 0 | * | 0 0.24 0 | = | 0 0.226 0 |
| 26.167 0 1 | | 90.756 740.44 1 | | 97.04 740.44 1 |
你从右边乘以现有变换的变化,但你必须从左边开始。
请原谅发帖时间过长,但无论谁回答这个问题,无疑都需要提供的所有信息。
我为我正在从事的项目成功地实施了 PDF 解析。在追查特定 PDF 中文本精确定位的问题时,我发现我的计算是错误的。以下是 PDF 的相关片段(使用 qpdf -qdf
):
相关 PDF 片段
%% Page 1
8 0 obj
<<
/Contents [
10 0 R
12 0 R
]
/MediaBox [ 0 0 612 792 ]
/Type /Page
>>
endobj
=====
9 0 obj
<<
/MediaBox [ 0 0 595 842 ]
/Type /Pages
>>
endobj
======
%% Contents for page 1
10 0 obj
<<
/Length 11 0 R
>>
stream
q
.94062 0 0 .94062 26.16627 0 cm
0 0 m
595 0 l
595 842 l
0 842 l
0 0 l
h
W n
q
16.84 16.84 561.32 808.32 re
W n
q
.24 0 0 .24 90.75993 740.44 cm
BT
133 0 0 133 0 0 Tm /TT1.0 1 Tf .0017 Tc [(The)1( )1(Long )1(Tai)1(l)]TJ
ET
我删除了每个片段的无关部分。
以下详细说明了我计算第 1 页第一个单词中 T 的确切 PDF 矩形。
上面最后一个 PDF 片段流中操作的描述和效果
q : 推送图形状态(GS)。
ctm = identity
cm : 修改ctm
| 0.94062 0 0 |
ctm = | 0 0.94062 0 |
| 26.16627 0 1 |
m : 起始路径在 0, 0
l : 线到 595, 0
l : 线路到 595, 842
l : 线路到 0, 842
l : 线到 0, 0
h : 关闭路径
No op since path already closed
n : 与 GS 剪切路径相交
GS clipping path wasn't set, so GS clipping path is the closed path that
defines rect [0 0 595 842]
q : 推送 GS
re : 创建闭合路径
Path defines rect [16.84 16.84 561.32 808.32]
n : 与 GS 剪切路径相交
The incoming path is totally contained in current GS clipping path,
so the GS clipping path becomes the incoming path, which defines the rect
[16.84 16.84 561.32 808.32]
q : 推送 GS
cm : 修改ctm
| 0.941 0 0 | | 0.24 0 0 | | 0.226 0 0 |
ctm = | 0 0.941 0 | * | 0 0.24 0 | = | 0 0.226 0 |
| 26.167 0 1 | | 90.756 740.44 1 | | 97.04 740.44 1 |
BT : 开始文本对象
Tm : 设置文本和行矩阵
| 133 0 0 |
tm = lm = | 0 133 0 |
| 0 0 1 |
Tf : 设置文字字体和字号
Set font to TT1, which has ascent=750, descent=-250, and glyph width T=667
(I will only need the width of T below). Font size is set to 1.
This has the effect of setting the first component in calculating the text
rendering matrix to
| 1 0 0 |
| 0 1 0 |
| 0 -0.25 1 |
Tc : 设置文本字符间距
TJ : 显示文字
计算 T 的 PDF 矩形
我们的计算目标文本将是显示的第一个文本,字母 T(因此上面提供了唯一的字形宽度)。执行文本显示 运算符 TJ,我们首先按照 PDF 规范 9.4.4 部分中的规定计算 Trm =](PDF 32000-1:2008) :
a = Tfs * Th = 1 * 1 = 1
d = Tfs = 1
ty = Trise = -250/1000 = -0.25
| a 0 0 |
Trm = | 0 d 0 | * Tm * ctm
| 0 ty 1 |
| 1 0 0 | | 133 0 0 | | 0.226 0 0 |
Trm = | 0 1 0 | * | 0 133 0 | * | 0 0.226 0 |
| 0 -0.25 1 | | 0 0 1 | | 97.04 740.44 1 |
| 30.06 0 0 |
= | 0 30.06 0 |
| 97.04 732.93 1 |
还计算了字形宽度(水平位移)和字形高度 根据 9.4.4:
部分 width = width of 'T' / 1000 = 0.667
height = (ascent - descent) / 1000 = (750 + 250) / 1000 = 1
字母 T 的正文是:
textRect for 'T' = [ 0 decent/1000, width, height ]
= [ 0 -0.25, 0.667, 1 ]
T 渲染在由 ctm 转换的文本矩形上。计算 T 的结果 PDF 矩形:
PDF 矩形:97.04 732.93 20.03 30.02
我已经在 Acrobat 和 Preview 中为 T 创建了高亮注释 并使用该信息来确定 PDF 位置的计算 T 在这两个程序中为:
Acrobat : 111.54 718.99 20.03 30.02
预览 : 111.54 718.99 20.03 30.02
与Acrobat和Preview相比,我有dx = -14.5和dy = 13.31, 即我是 T.
的实际位置太左太高对于未更改媒体框或未声明图形的 PDF 状态剪切路径我所有的计算都是正确的。我知道一定有关系 PDF 对象 8 0 和 9 0 中不同的媒体框声明,或者, 更有可能的是,由 m, l, h, n, 产生的图形状态剪切路径 和 re 运算符,这导致
的矩形剪切路径 rect[ 16.84 16.84 561.32 808.32 ]
媒体盒是
[ 0 0 595 842 ]
我在 PDF 规范中找不到任何部分表明我的计算因图形状态剪切路径而发生变化(再次假设 是罪魁祸首)。
呃。我错过了什么?
这里有一个错误:
cm : 修改ctm
| 0.941 0 0 | | 0.24 0 0 | | 0.226 0 0 |
ctm = | 0 0.941 0 | * | 0 0.24 0 | = | 0 0.226 0 |
| 26.167 0 1 | | 90.756 740.44 1 | | 97.04 740.44 1 |
你从右边乘以现有变换的变化,但你必须从左边开始。