ubuntu pdf 乱码 ,终于明白了原理

来源:互联网 发布:显为人知的外国作家 编辑:程序博客网 时间:2024/05/03 09:50

这里的一篇讲得最清楚:

http://blog.lilinux.net/2010/05/pdf-chinese-font/

 

 

中文PDF在Linux下的显示很容易出问题,最典型的症状是用evince(文档阅读器)打开文件后,凡是应该显示中文的地方都显示是一个个的小方块。

PDF的特点是便携性和跨平台,但为什么会出现这样的问题呢?本文将简单的分析原因,并解决这个问题

1. PDF的组成

关于PDF的详情,可以到wiki(http://en.wikipedia.org/wiki/Portable_Document_Format)或到adobe官方网站查阅。阅读本文时,你只需要知道PDF文件的格式实际上是类似于 标记语言(markup language)的格式即可。比如用来描述网页内容的HTML语言(Hyper Text Markup Language, 超文本标记语言),它的典型形式如下:


<font size=4 color=red>你好,世界</font>
经过浏览器解析后,在浏览器窗口上显示的样式如下:
你好,世界

尖括号内的为标记,一般来说,标记都是成对出现的,在标记对内的文本的样式由标记的属性描述,比如上例中的标记表示将“你好,世界”这几个字以4磅的和红色的字体来显示。浏览器解析标记后,将文本以相应的样式显示出来。

你可以认为PDF文件的组织和HTML类似,只不过方式略有不同罢了。而且PDF显示是通过PDF阅读器而不是浏览器来实现的(当然浏览器一般也有显示PDF文件的扩展功能)。因此,我们假设PDF文件内部是这样的(为了简化问题而作的假设,并不是真的PDF文件内容,具体的PDF文件格式我也没有深入研究过)


/Font /a-font
/Content PDF文件要显示的实际的文本内容
假设Font后面的是指定显示的字体,Content后面的就是文本内容。在PDF文件中,文本内容是一定要有的,字体指定不一定需要

下面就通过这个例子来表示
2. 系统字体设置为英文字体
字体本质上是图形库,比如要显示字母“A”,在计算机内部“A”是以二进制的形式计算和传递,而在屏幕上打印时,就必须把这个编码转换成图形。不同的字体就是不同的图形库,每个字母的编码都与一个图形相对应,于是计算机传递给输出设备的二进制串就转换成了人可以阅读的字符串。

因此,一种英文字体实际上就是显示所有拉丁字母和标点符号的图形。它在建立的时候就不会把汉字的图形包含进去。反过来,汉字字体就必须包含英文字母的图形了(毕竟老外用一辈子计算机也不会打一个中文,中国人有哪天不需要输入字母的)。当Ubuntu安装时,默认是把英文字体作为默认显示字体的。于是在PDF中包含中文时,系统找不到对应编码的“图形”,只能以方框显示!

对PDF而言,只需要修改这个文件,把其中的英文字体改成中文的即可(这在前文“Ubuntu 10.04 简明安装配置”里有提到过)


sudo gedit /etc/fonts/conf.d/49-sansserif.conf # 或者sudo vi /etc/fonts/conf.d/49-sansserif.conf
将文件内容替换成如下
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
If the font still has no generic name, add sans-serif
-->
<match target="pattern">
<test qual="all" name="family" compare="not_eq">
<string>sans-serif</string>
</test>
<test qual="all" name="family" compare="not_eq">
<string>serif</string>
</test>
<test qual="all" name="family" compare="not_eq">
<string>monospace</string>
</test>
<edit name="family" mode="append_last">
<string>WenQuanYi Micro Hei</string>
</edit>
</match>
</fontconfig>

其中的“WenQuanYi Micro Hei”就是中文字体“文泉驿微米黑”,你也可以替换成任意你喜欢的中文字体。

重新打开PDF文件,这时候一般就可以见到中文了。

如果还是方框,那就继续往下看

3. PDF文件中指定了系统不存在的中文字体
PDF文件中可以指定显示的字体(第一节举的例子),这样保证了PDF文件在不同的平台上显示的效果是相同的。但如果PDF指定了字体,而文件又没有包含这个字体库,那就只能希望在其它平台上也恰好有这个字体了。

这就是少数中文PDF文件还是不能正常显示的原因!

有些中文PDF文件在windows上制作的时候,出于美观或者其它考虑,作者将字体指定为“宋体”、“雅黑”等在Linux看来的受限字体,并且作者认为所有的电脑都会有这些字体。而如果你的系统上没有这些字体,那就可能会出现问题了。Foxit Reader在这种情况下会用系统默认字体来显示(就是刚才我们改的那个文件),而evince和Adobe Reader都无法显示。Adobe Reader会提示用户去下载一个语言包安装(这个语言包非常大,而且会安装很多受限字体)

但是我非常喜欢轻便易用的evince。那现在就只有改变PDF文件中指定的字体为系统中已有的字体了。如果用Adobe的产品,不仅需要付费,而且还只有windows平台的版本。如果你仔细看了第一节就知道,我们根本就不需要这么复杂,只需要用纯文本的方式打开文件,改掉相应的字体的不行了!

真的这么简单吗?

确实就是这么简单!(计算机的东西本来就是为了简化人们的生活和工作而存在的)

好,你用vi打开不能正常显示中文的PDF文件后 ,先搜索“Font”看看,是不是看到了诸如“SimSun”(宋体)之类的字体跟在它们的后面

于是,我们只需要做一个简单的全局替换就可以了。在vi中,你只需要
把文件中所有出现的”SimSun”和”TimesNewRoman”都替换成”wqy-zenhei”(文泉驿正黑)

也可用以下命令。做一个简单的全局替换就可以了。在vi中,你只需要输入这样的命令:
:%s/SimSun/wqy-zenhei/g
:%s/TimesNewRoman/wqy-zenhei/g


然后保存退出,再用evince打开,是不是就可以了呢

原创粉丝点击