通过比较文件 之前 和 之后 ,可以清楚地看出,由于某种原因,
PdfCleanUpProcessor错误地放弃了常规图形状态操作(至少
w , J 和 d )。
特别是在您的 之前 文档中, w 操作对于文本非常重要,因为使用了 穷人的粗体
变体,即,使用常规字体代替了实际的粗体字体,并且将文本呈现模式设置为不仅填充字形轮廓并沿其画一条线,使其外观大胆。
使用 w 操作将该行的宽度设置为0.23333 。作为该操作中缺少 后
文件,则使用默认的1宽度值。因此,沿轮廓线的线现在是以前的4倍,导致外观非常胖。
此问题已在提交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丢弃,同时尝试将更改的值存储在清除策略上下文中。但是,当然
==,
String在Java中使用进行比较通常是一个非常糟糕的主意,因此,从该版本开始,线型运算符在iText中已被删除。
实际上,这段代码是从iTextSharp移植过来的,在C#中
==,该
string类型的工作原理完全不同。尽管如此,即使在iTextSharp版本中,乍一看,似乎仅考虑了这些存储的值,如果笔划了路径,如果文本渲染包括沿轮廓笔划,则没有考虑。
稍后在提交9967627中(与上述提交在同一天),内部
if..else if..else..已被删除,并带有注释 替换
为包中的
PdfCleanUpGraphicsState现有内容,并向后者添加了缺少的参数
GraphicsState``itext.pdf.parser,仅
disableOutput= true保留了剩余的参数。这(乍看起来)似乎已经解决了iText / Java和iTextSharp /
.Net之间的差异,但是,如果文本渲染包括沿轮廓笔划,则仍不考虑线型值。
作为解决方法,请考虑删除行
} else if (lineStyleOperators.contains(operatorStr)) { disableOutput = true;来自
PdfCleanUpContentOperator.invoke。现在,不再删除线型运算符,并且编辑后的PDF中的文本看起来像以前一样。不过,我尚未检查任何副作用,因此,即使考虑在生产中使用该替代方法,也请先测试大量文档。



