【问题标题】:iText7 flips text - bug?iText7 翻转文本 - 错误?
【发布时间】:2021-05-15 10:34:28
【问题描述】:

考虑一个名为 in.pdf 的 1 页 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

【问题讨论】:

    标签: itext7


    【解决方案1】:

    这是一个错误吗?

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

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

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

    • 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) 在某些条件下使用true 值作为wrapOldContent,尤其是当您正在处理现有 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 构造函数不会添加任何此类信封。因此,您的添加会受到原始内容中图形状态变化的影响,并且您会得到镜像文本。

    【讨论】:

    • mkl 非常感谢您的详细回复。我在MS Word 中创建了原始文档,然后使用Microsoft Print to PDF 打印机打印为PDF。我现在尝试使用Adobe PDF 打印机将相同的文档打印到 PDF,并且不再获得翻转输出。看起来 MS 打印机本身的清理工作并没有那么好。
    • 好吧,严格来说不需要清理,只是风格好......;)
    猜你喜欢
    • 2021-10-09
    • 2012-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    相关资源
    最近更新 更多