iText7 翻转文本 - 错误?

iText7 flips text - bug?

考虑一个名为 in.pdf 的单页 PDF 文档,如下所示:

我们在C#中执行以下代码:

using (var reader = new PdfReader(@"C:\<path>\in.pdf"))
using (var writer = new PdfWriter(@"C:\<path>\out.pdf"))
using (var pdfDoc = new PdfDocument(reader, writer))
{
    var page = pdfDoc.GetFirstPage();
    var pdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdfDoc);

    using (var canvas = new Canvas(pdfCanvas, new Rectangle(400, 300)))
    {
        canvas.Add(new Paragraph("new text\r\nnew text")
            .SetFontColor(new DeviceRgb(255, 0, 0))
            .SetFontSize(50));
    }

    pdfCanvas.Release();
}

我们得到了原始文本下方出现的新文本,正如预期的那样:

现在我们执行相同的代码,只需做一个更改 - 我们创建 PdfCanvas 如下:

var pdfCanvas = new PdfCanvas(page);

结果仍然如预期 - 新文本在原始文本之上:

最后,我们执行与创建的PdfCanvas相同的代码如下:

var pdfCanvas = new PdfCanvas(page.NewContentStreamAfter(), page.GetResources(), pdfDoc);

新文本如预期的那样位于原始文本之上,但它被翻转了!

这是一个错误吗?获得相同的翻转输出创建 PdfCanvas 像这样:

var pdfCanvas = new PdfCanvas(page.GetFirstContentStream(), page.GetResources(), pdfDoc);
//OR
var pdfCanvas = new PdfCanvas(page.GetLastContentStream(), page.GetResources(), pdfDoc);

使用 nuget 包 itext7 v7.1.15

Is this a bug?

没有。它与您的代码和 PdfCanvas(PdfPage page) 构造函数的功能相匹配。

每个 PDF 内容流都包含一系列更改当前图形状态的指令 and/or 绘制内容。如果相应内容流的原始创建者没有注意清理图形状态,您添加到它或同一页面的后续内容流的指令将受到这些图形状态更改的影响。

在你的例子中,原始页面内容流显然在最后有一个图形状态,当前转换矩阵设置为反射。根据您添加新内容的方式,您添加的内容也会受到反射转换的影响:

  • var pdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdfDoc);
    

    在这里,您在所有现有内容流之前 添加一个新的内容流。因此,您对 pdfCanvas 的添加不会受到任何图形状态变化的影响,并且您会得到直立的文本。

  • var pdfCanvas = new PdfCanvas(page);
    

    您在此处使用的构造函数 PdfCanvas(PdfPage page) 调用另一个构造函数 PdfCanvas(PdfPage page, bool wrapOldContent),它 wrapOldContent == true 将现有内容包装在 save- 的信封中graphics-state / restore-graphics-state 指令对,恢复现有内容后的原始图形状态。 PdfCanvas(PdfPage page) 在特定条件下为 wrapOldContent 使用 true 值,特别是当您正在处理现有 PDF 并且相关页面已经有非空内容流时。

    因此,在您的情况下,原始内容被包裹在这样的信封中,此后图形状态被恢复。因此,您添加的内容不会受到任何图形状态变化的影响,并且您会得到直立的文本。

  • var pdfCanvas = new PdfCanvas(page.NewContentStreamAfter(), page.GetResources(), pdfDoc);
    
    var pdfCanvas = new PdfCanvas(page.GetFirstContentStream(), page.GetResources(), pdfDoc);
    
    var pdfCanvas = new PdfCanvas(page.GetLastContentStream(), page.GetResources(), pdfDoc);
    

    您在此处使用的 PdfCanvas 构造函数不添加任何此类信封。因此,您添加的内容会受到原始内容中图形状态变化的影响,您会得到镜像文本。