iText 5.5.11 - 使用PdfCleanUpProcessor后,粗体文本看起来很模糊

时间:2017-06-01 10:11:08

标签: java pdf itext

我需要从iText 5.5.11中使用Jasper Reports创建的现有pdf中删除一些内容,但在运行PdfCleanUpProcessor之后,所有粗体文本都是模糊的。

这是我使用的代码:

public function isAdmin()
 {
   return $this->groups->name =='Admin';
 }

正如已经讨论过的here降级到itext-5.5.4解决了这个问题,但在我的情况下,itext-5.5.11已经因其他原因而被使用,因此降级不是一种选择。

是否有其他解决方案或解决方法?

这是清洁前后的pdf文件:BEFORE - AFTER

1 个答案:

答案 0 :(得分:0)

通过比较之前的之后的,很明显由于某种原因,PdfCleanUpProcessor错误地删除了一般的图形状态操作(至少 w J d )。

之前文档中,特别是 w 操作对于文本非常重要,因为使用了穷人的粗体变体,即不使用实际的粗体字体,而是使用普通字体,文本渲染模式不仅可以填充字形轮廓,还可以沿着它绘制一条线,使其具有醒目的外观。

使用 w 操作将该行的宽度设置为0.23333。由于文档之后缺少该操作,因此使用默认宽度值1。因此,沿着轮廓的线条现在是之前的4倍,导致非常胖的外观。

此问题已在commit d5abd23(2015年5月4日)中引入,其中(除其他外)将此块添加到PdfCleanUpContentOperator.invoke

} else if (lineStyleOperators.contains(operatorStr)) {
    if ("w" == operatorStr) {
        cleanUpStrategy.getContext().setLineWidth(((PdfNumber) operands.get(0)).floatValue());
    } else if ("J" == operatorStr) {
        cleanUpStrategy.getContext().setLineCapStyle(((PdfNumber) operands.get(0)).intValue());
    } else if ("j" == operatorStr) {
        cleanUpStrategy.getContext().setLineJoinStyle(((PdfNumber) operands.get(0)).intValue());
    } else if ("M" == operatorStr) {
        cleanUpStrategy.getContext().setMiterLimit(((PdfNumber) operands.get(0)).floatValue());
    } else if ("d" == operatorStr) {
        cleanUpStrategy.getContext().setLineDashPattern(new LineDashPattern(((PdfArray) operands.get(0)),
                ((PdfNumber) operands.get(1)).floatValue()));
    }

    disableOutput = true;

这会导致删除所有lineStyleOperators,同时尝试将更改的值存储在清除策略上下文中。但是当然在Java中使用==进行String比较通常是一个非常糟糕的主意,所以从这个版本开始,线条样式的运算符在iText中被删除了。

实际上这段代码是从iTextSharp移植的,而在C#==中,string类型的作用完全不同;尽管如此,即使在iTextSharp版本中,如果路径被描边,乍一看似乎也没有考虑这些存储的值,而不是文本渲染包括沿轮廓描边。

稍后在提交9967627中(与上面提交的同一天)内部if..else if..else..已被删除,注释已替换PdfCleanUpGraphicsState来自{GraphicsState 1}}包,将缺少的参数添加到后者中,只剩下itext.pdf.parser。这(也乍一看)似乎已经修复了iText / Java和iTextSharp / .Net之间的差异,但如果文本渲染包括沿轮廓描边,则仍然不考虑线型值。

作为解决方案考虑删除行

disableOutput = true

来自} else if (lineStyleOperators.contains(operatorStr)) { disableOutput = true; 。现在,线条样式运算符不再被删除,并且编辑后的PDF中的文本看起来像以前一样。但是,我没有检查任何副作用,所以在考虑使用生产中的解决方法之前,请先测试一些文件。