问题描述
利用开源代码将pdf转换为ofd后,字符发生变形,显示为一个竖条。
解决过程
- 查看生成的ofd文件,发现每个textobject多了hscale这一属性,在代码中查找hscale,发现了这段代码
if (nextTextRenderingMatrix.getScaleX() != nextTextRenderingMatrix.getScaleY()) {
$textObj.setHScale(
(double) nextTextRenderingMatrix.getScaleX() );
}
简单地把这段代码注释掉,发现生成的ofd文件中文字之间相互有沾粘,同时在wps中打开原doc文件,将文字与正常的相同字体的文字对比,发现文字确实存在横向压缩。因此结论是这段代码设置的HScale不正确,需要修改为正确的计算方式。
再看这段代码,在scaleX和scaleY不相等时才设置横向压缩,猜想:scaleX和scaleY相等说明这个字X和Y方向压缩比相同,因此字形与原字形相同,只是整体字号进行了缩放,不相同时说明存在字形上的压缩,而HScale表示的是横向的压缩,因此应该为 scaleX 与scaleY的比值,修改代码如下:
if (nextTextRenderingMatrix.getScaleX() != nextTextRenderingMatrix.getScaleY()) {
$textObj.setHScale(
(double) nextTextRenderingMatrix.getScaleX() / (double) nextTextRenderingMatrix.getScaleY());
}
经测试,结果字形缩放正确。
延伸
- ofd标准中textobject只有hscale属性,没有vscale,那如何表示纵向压缩
- 猜想: 若hscale大于1则表示纵向压缩
- 验证: 将hscale设置为大于1的值,如2,发现文字字形确实纵向压缩
- 结论:一般而言,通过scaleX和scaleY就能确定这个字的字形,但是ofd标准中应该是使用了scaleY先确定了字形的高(此时字形的宽进行等比压缩),再通过hscale值横向压缩确定字形的宽,其中hscale=scaleX/scaleY
总结
- 第一步仍然是对比,发现问题样本与正常样本的区别
- 然后是找到产生差异的地方,利用相关知识和经验,分析问题
- 再然后是 进行「猜想-验证」循环
- 解决问题后可以进一步思考,以验证解决方案是否考虑全面,是否从根源上得到解决