PDF规范 - 获取字体大小(以点为单位)

3

我正在尝试用C#编写PDF解析器,但遇到一个问题:不确定如何解释规范。

除非另有说明,否则PDF文档中的用户空间为1/72英寸(即1pt)。

Tf操作符提供的比例将字体从标准大小(通常为1个用户空间/1pt)缩放到正确的显示大小。

我有以下页面内容:

1 0 0 -1 0 792 cm
q
0 0 612 792 re
W* n
q
.75 0 0 .75 0 0 cm
1 1 1 RG 1 1 1 rg
/G0 gs
0 0 816 1056 re
f
0 0 816 1056 re
f
0 0 816 1056 re
f
Q
Q
q
0 0 612 791.25 re
W* n
q
.75 0 0 .75 0 0 cm
1 1 1 RG 1 1 1 rg
/G0 gs
0 0 816 1055 re
f
0 96 816 960 re
f
0 0 0 RG 0 0 0 rg
BT
/F0 21.33 Tf
1 0 0 -1 0 140 Tm
96 0 Td <0037> Tj
13.0280762 0 Td <004B> Tj
11.8616943 0 Td <004C> Tj
4.7384338 0 Td <0056> Tj
ET
BT
/F1 21.33 Tf
1 0 0 -1 0 140 Tm
136.292267 0 Td <0001> Tj
ET
...

我知道示例中定义的两个文本操作的字体大小为16pt,但Tf操作符使用了21.33的大小。为了将这种字体大小转换回点数,我打算使用cm操作符的比例(y),使点数大小为:

21.33 * 0.75 = 15.9975

然而,我在PDF规范中找不到支持此转换的内容,并且我检查的所有库(PDFBox、iTextSharp和Spire PDF)都将字体大小列为21.33,没有其他的信息。
我应该使用CTM(由cm运算符定义)将字体大小缩放回正确比例,还是这只是纯粹的巧合?
PDF文件在这里:https://github.com/UglyToad/PdfPig/blob/master/src/UglyToad.PdfPig.Tests/Integration/Documents/Single%20Page%20Simple%20-%20from%20google%20drive.pdf

2
cm操作将彼此连接在一起,因此,在处理Tf运算符时,第一个比例操作中的因子0.75仍然是“有效”的。这不是真正的转换;所有图形操作都使用矩阵完成。 - Jongware
有没有一种方法可以将字体大小的缩放表示为矩阵操作,因为它是标量值,所以无法将其乘以矩阵?在问题的示例中,scaleX的值为0.75,scaleY的值为-0.75(负数),因此只有通过X比例乘以才有意义,但我无法弄清楚这样做的理由。 - Underscore
这就是我们最终计算出给定各种转换矩阵的点大小的方式。 https://github.com/UglyToad/PdfPig/blob/master/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs#L245我仍然不确定它在每种情况下是否都是正确的,但对于大多数情况来说似乎“足够接近”。 - Underscore
1个回答

3
首先,你对其他文本提取工具的比较基于一个误解:
引用部分:我检查过的库(PDFBox、iTextSharp、Spire PDF)中,没有一个将字体大小描述为21.33以外的数值。
所有这些库返回的“字体大小”参数只是Tf指令的大小参数,并不代表你在最终文档中观察到的实际字体大小。所以,与其他库的比较毫无意义。
现在,关于你的方法:

In order to convert from this font size back to points I was intending to use the scale (y) of the cm operator making the point size:

21.33 * 0.75 = 15.9975
虽然有些库可能会这样称呼,但把第四个cm参数称为“缩放(y)”是具有误导性的。例如,在将文本旋转90度的情况下,它通常为零,而图形表示通常不会被减少为零高度。
因此,仅使用“缩放(y)”参数是行不通的,您必须考虑到整个变换。
最终,让我们讨论一下您实际想要的内容。
只要组合变换矩阵(当前变换矩阵+文本矩阵+水平缩放)是正交的,并且文本行遵循这种正交性,您对字体大小概念的理解就是相当明显的。
但是,一旦在该组合矩阵中出现剪切,则“字体大小”的含义就不再明显。
您可能意味着一个最初垂直的线段(高度为一单位)被转换成的长度。
您可能意味着该转换线段投影在与转换字体基线成直角的线上的长度。
或者您可能意味着该转换线段投影在观察基线成直角的线上的长度。
前两个数字可以使用简单的线性代数轻松计算。由于必须确定人类在生成的PDF文件中观察到的基线,因此第三个数字可能更难。在使用变换方式方面,这可能是不平凡的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接