layer2 中的签名外观字体颜色(itext 7)

Signature appearance font color in layer2 (itext 7)

我正在尝试使用 iText7 7.1.0 (java) 中的字体颜色生成具有外观的签名。

使用 iText5,在调用 FontFactory.getFont() 时包含 fontColor,然后:

Font font = FontFactory.getFont(fontName, encoding, embedFont, fontSize, style, bColor); 
appearance.setLayer2Font(font); 

但是,在 iText7 中,Font 似乎丢失了 fontSize 和 fontColor 信息。 fontSize 有一个新的 appearance.setLayer2FontSize() 方法。 但是我找不到指示layer2字体颜色的方法。

我在 Text 或 Paragraph 类中找到了 setFontColor。

但是,在生成signatureApperance时,要调用的方法似乎是PdfSignatureAppearance.setLayer2Text(String),参数只是一个String。

如何在 iText7 中修改 layer2 字体颜色?

非常感谢。

显然,在将 PdfSignatureAppearance 从 iText 5 移植到 iText 7 时,没有考虑在 iText 5 字体对象中传输颜色的选项,至少我没有看到任何官方方式来传输所需的颜色进入外观创建过程。

在这种情况下,显而易见的选择是手动创建第 2 层。这样做,您可以根据需要设计外观的所有选项。您可以复制并粘贴原始代码,包括所需的隐藏辅助方法,以从原始 iText 设计开始您的设计。

如果您不想这样做,即如果您仍然希望 iText 创建外观并只是稍微调整一下,则有一个解决方法:您可以让 iText 创建外观然后操作他们有点。

不幸的是,这现在需要反思,因为生成外观 getAppearance()PdfSignatureAppearance 方法是 protected。 (它在 iText 5 中曾经是 public...)

如果您接受这样的解决方法,您可以像这样给文本着色:

PdfSigner signer = ...;
PdfSignatureAppearance appearance = signer.getSignatureAppearance();

[... customize the appearance using its usual methods ...]

// call appearance.getAppearance() using reflection
// this initializes the layers in the appearance object
Method getAppearanceMethod = PdfSignatureAppearance.class.getDeclaredMethod("getAppearance");
getAppearanceMethod.setAccessible(true);
getAppearanceMethod.invoke(appearance);

// add a fill color setting instruction
// at the start of layer 2
PdfFormXObject layer2 = appearance.getLayer2();
PdfStream layer2Stream = layer2.getPdfObject();
byte[] layer2Bytes = layer2Stream.getBytes();
layer2Stream.setData("1 0 0 rg\n".getBytes());
layer2Stream.setData(layer2Bytes, true);

signer.signDetached(...);

(CreateSpecialSignatureAppearance测试方法testColorizeLayer2Text)

由于最初生成的外观中的填充颜色未明确设置,而是默认为黑色,因此此前置指令将所有文本着色为红色(使用 100% 红色、0% 绿色和 0% 蓝色的 RGB 颜色)。


我真的有点惊讶 iText 7 仍然带有所有这些签名层的东西。至少自 ISO 32000-1 于 2008 年发布以来,除了支持 Adob​​e 查看器特定行为外,没有理由再使用这些层,甚至 Adob​​e 自己在 ISO 32000-1 之前就已宣布弃用。

是否有如此庞大的利益集团游说支持那些已弃用的行为?

你用这种方式创建自定义图层2,然后添加修改。

// Create the signature appearance
            Rectangle rect = new Rectangle(36, 50, 200, 100);
            PdfSignatureAppearance appearance = signer.getSignatureAppearance();
            appearance
            .setLocation(location)

            // Specify if the appearance before field is signed will be used
            // as a background for the signed field. The "false" value is the default value.
            .setReuseAppearance(false)
            .setPageRect(rect)
            .setPageNumber(r.getNumberOfPages());
            signer.setFieldName("sig");
            
            appearance.setLayer2Font(PdfFontFactory.createFont(StandardFonts.TIMES_ITALIC));
            
            // Get the background layer and draw a gray rectangle as a background.
            PdfFormXObject n0 = appearance.getLayer0();
            float x = n0.getBBox().toRectangle().getLeft();
            float y = n0.getBBox().toRectangle().getBottom();
            float width = n0.getBBox().toRectangle().getWidth();
            float height = n0.getBBox().toRectangle().getHeight();
            PdfCanvas canvas = new PdfCanvas(n0, signer.getDocument());
            canvas.setFillColor(ColorConstants.CYAN);
            canvas.rectangle(x, y, width, height);
            canvas.fill();

            // Set the signature information on layer 2
            PdfFormXObject n2 = appearance.getLayer2();
            Paragraph p = new Paragraph("This document was signed by Bruno Specimen.");
            new Canvas(n2, signer.getDocument()).add(p);

            // Creating the signature
            IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, provider);
            IExternalDigest digest = new BouncyCastleDigest();