一、问题
在项目中使用pdfbox2.0.15版本,将pdf文件转成图片,在windows本地转换正常,发布到linux服务器,转换后图片中的中文出现部分乱码,显示都是方块□□□。
二、分析
1、日志查看
后台日志打印出的日志显示,pdf识别出的字体为STSongStd-Light,服务器没有这个字体库,所以按照默认匹配规则,匹配到了UnDotum-Bold这种字体,经查询,UnDotum-Bold主要为韩语字体,无法匹配所有中文字体,所以出现方块□□□。
2019-12-25 14:50:12.308 [http-nio-9281-exec-9] WARN o.a.p.pdmodel.font.PDCIDFontType0 -Using fallback UnDotum-Bold for CID-keyed font STSongStd-Light
2019-12-25 14:50:12.309 [http-nio-9281-exec-9] WARN o.a.pdfbox.rendering.CIDType0Glyph2D -No glyph for 27748 (CID 0e13) in font STSongStd-Light
2、瞎折腾
根据网上资料显示,因服务器缺少字体库STSongStd-Light,既然是这样,自然是找到对应的字体库放到服务器上(linux添加字体库教程自行google)。经过一番折腾,字体是有了,但是依旧显示乱码,日志还是显示加载的是UnDotum-Bold,此方法不通只能走其他路子了。
3、源码分析
通过断点调试,在FontMapperImpl类中发现有个substitutes 列表,存放的是字体名称的映射关系,即一种字体不存在时,可以根据这个映射关系,优先匹配对应的字体,部分源码如下:
final class FontMapperImpl implements FontMapper
{
private static final FontCache fontCache = new FontCache(); // todo: static cache isn't ideal
private FontProvider fontProvider;
private Map<String, FontInfo> fontInfoByName;
private final TrueTypeFont lastResortFont;
/** Map of PostScript name substitutes, in priority order. */
private final Map<String, List<String>> substitutes = new HashMap<String, List<String>>();
FontMapperImpl()
{
// substitutes for standard 14 fonts
substitutes.put("Courier",
Arrays.asList("CourierNew", "CourierNewPSMT", "LiberationMono", "NimbusMonL-Regu")