0

我提取表单域的字体大小以获取有关其大小的信息(使用 iText)。这适用于大多数文档,但是对于某些文档,我的字体大小为 1,因为在外观上字体大小为 1。但是,如果我在几个不同的查看器中打开 PDF,则此文本字段的大小始终为 8。我想表单域应该根据其外观呈现?那么为什么 PDF 查看器使用默认外观而不是外观流中定义的字体大小呢?

在此处输入图像描述

更新:正如 MKL 提到的,我确实忘记考虑文本矩阵。我确实为字体实现了自己的 RenderListener。有谁知道如何应用缩放?

public class PdfStreamFontExtractor implements RenderListener{

    @Override
    public void usedFont(DocumentFont font, float fontSize) {
        this.font=font;
        this.fontSize=fontSize;
    }

    @Override
    public void renderText(TextRenderInfo renderInfo) {
     //get scaling factor from textToUserSpaceTransformMatrix?
    }
...
}
4

1 回答 1

2

但是即使在外观流中,有效字体大小也是8!

查看整个文本对象:

BT
8 0 0 8 2 5.55 Tm
/TT1 1 Tf
[...] TJ
ET

开始时设置的文本矩阵将所有内容缩放 8 倍。因此,此后绘制的文本的有效字体大小为 8 × 1 = 8。


诚然,虽然您经常可以在常规内容中看到缩放文本矩阵与大小为 1的Tf指令相结合,但我还没有在表单字段的外观中看到这一点。这很不常见,我想。


关于你的更新...

有谁知道如何应用缩放?

@Override
public void renderText(TextRenderInfo renderInfo) {
//get scaling factor from textToUserSpaceTransformMatrix?
}

好吧,这取决于您要如何测量转换后的大小。

一种方法是采用与字体大小一样长的垂直向量(如Tf指令中给出的),将其转换为textToUserSpaceTransformMatrix,并取转换结果的长度:

@Override
public void renderText(TextRenderInfo renderInfo) {
  scaledfontSize=renderInfo.getTransformedFontSize(unScaledfontSize);
}

public class TextRenderInfo {
...
  public float getTransformedFontSize(float fontSize){
    return new Vector(0, fontSize, 0).cross(this.textToUserSpaceTransformMatrix).length();
  }
...

如果转换仅包括反射、旋转和缩放,则结果应该符合预期。如果涉及倾斜效果,您可能希望在获取长度之前将该变换矢量投影到垂直于变换书写方向的平面上。

于 2021-12-21T15:22:57.873 回答