会员评分: 4 / 5

点亮的星星点亮的星星点亮的星星点亮的星星灰暗的星星
 

目 录

Joomla! 1.0.x 与 1.5.x 均有内建功能让网站访客产生所阅读文章的 PDF 档案。这项功能对于西方语言没有问题,但对亚洲语言像是中文及日文却无法产生令人满意的 PDF 档案。对于 Joomla! 1.0.x,已经存在了修补方式来让它对亚洲语言作业正常。例如 台湾 Joomla! 释出本地化的正体中文 Joomla! 1.0.x,里面包含了可以正常作业的 PDF 产生子系统。

因为 Joomla! 1.5.x 使用 UTF-8 编码并允许对不同语言指定各自的字体来产生 PDF,它基本上在 PDF 功能支援广泛的语言。只要字体资料、脚本程式与字体本身安装无误,Joomla! 1.5.x 的确可以正确地产生亚洲语言 PDF 档案。然而,它对于亚洲语言的支援仍然有些微问题。

目前 Joomla! (1.5.7) 使用 TCPDF v2.5.000。这个版本的 TCPDF 永远在产生 PDF 档案时将完整的字体嵌入,除非该字体是一个核心字体。这对亚洲字体会有两个问体,而这两个问题都由通常很大的字体档案造成。

第 一个问题是所产生 PDF 档案的大小。因为它包含了整个字体,PDF 的大小会至少是字体的大小。另外一个问题是伺服器需要分配大块的记忆区来使用,因为 TCPDF 在制作 PDF 时把整个字体载入记忆体。一个 15 MB 正体中文字体大约可用到至少 40 MB 记忆体来处理。

在这里我们将提供程序如何对正体中文文章产生不嵌入整个字体的 PDF,使产生的档案大小是在数百 KB 而不是几个 MB。经过些许修改,类似的程序应该也可用于其他亚洲语言。


下载 TCPDF

之前我们提及 Joomla! 1.5.7 提供的 TCPDF v2.5.000 并没有选项不嵌入完整的字体档案。幸运的是新版的 TCPDF 有这个选项。因此我们的计划基本上是将 Joomla! 内的 TCPDF 用最新版来取代。

请前往官方 TCPDF 网站来下载最新版本。将它解压缩到你的电脑硬碟里。你会看到一个目录名称为 tcpdf 被建立,里面含有 TCPDF 的程式码。

建造字体脚本程式

虽然我们不要 TCPDF 把整个字体档案放入 PDF 内,我们仍然必须让它包含一些字体的资讯。你需要执行在 TCPDF 软体包里的两件工具以产生一个含有字体重要资料的 PHP 脚本程式。

为 了要使中文 PDF 能被 Adobe Acrobat 正常显示且不用实际嵌入字体档案,所用的字体必须已经是 Acrobat 安装一部份。如果你检查 Acrobat 安装目录下的 Resource\CIDFont 档案夹,你会发现几个给亚洲语言使用的字体。对于正体中文 Adobe Acrobat 提供了 AdobeMingStd-Light.otf,那是我们要使用的字体。(我们假设你自身使用的机器是一部视窗电脑,因为其中一个你必须使用的指令是 DOS 的程式。)

现在请进入含有 TCPDF 程式码之 tcpdf 档案夹内的 fonts\utils。将字型档 AdobeMingStd-Light.otf 复制到这个档案夹,并将它改名为 adobemingstd-light.otf。开启一个 DOS 指令视窗,执行下面的指令以产生字体资料档案。

D:\tcpdf\fonts\utils> ttf2ufm -a -F adobemingstd-light.otf

这指令会花一点时间来执行。等它完成后,你应该会在同样的目录下看到多出三个档案,它们的延伸档名会分别是 .afm、.t1a 与 .ufm。

接下来你必须执行一个 PHP 脚本程式 makefont.php。(你需要有 PHP 安装在你的视窗机器上,或者你也可以将那三个刚建造的档案复制到你的伺服器上,然后在伺服器上执行下面的指令。)

D:\tcpdf\fonts\utils> php -q makefont.php adobemingstd-light.otf adobemingstd-light.ufm false

这 会制作出一个有 .z 延伸档名的压缩档及一个 PHP 脚本程式叫做 adobemingstd-light.php,这是 TCPDF 产生 PDF 时需要用到的档案。但在这个 PHP 脚本程式能被使用之前,还需经过一些修改。请用你惯用的文字编辑器开启 adobemingstd-light.php,做以下的改变:

  • 改变字体型式成为:$type='cidfont0';
  • 增加这行以设定预设的字型宽度:$dw=1000;
  • 移除 $enc、$file 和 $ctg 变数的定义
  • 于档案的最后加入下面这段文字:
    // Chinese Traditional
    $enc='UniCNS-UTF16-H';
    $cidinfo=array('Registry'=>'Adobe', 'Ordering'=>'CNS1','Supplement'=>0);
    include(dirname(__FILE__).'/uni2cid_ac15.php');

要知道如何针对其他亚洲语言做修改,请参考TCPDF 官方网站上的文件


复制档案到 Joomla! 的安装内

全 部档案准备好之后,我们现在可以把它们复制到伺服器上的适当位置里。请使用 FTP 或 SFTP 将你的 tcpdf 档案夹内的所有档案以及 cache、config 与 images 三个目录复制到你的 Joomla! 安装内的 libraries/tcpdf 目录里面。(为了安全你最好把原来的 libraries/tcpdf 目录改名,再建立一个新的 libraries/tcpdf 目录。)

然 后请把之前制作的 adobemingstd-light.php 复制到你的 Joomla! 安装下的 language/pdf_fonts。同样地将你电脑 tcpdf/fonts 档案夹里的 helvetica.php 和 uni2cid_ac15.php 复制过去。

编辑语言叙述 XML 档

产生 PDF 时使用的字体是在个别语言目录里的语言叙述 XML 档内指定。对正体中文来说,那个档案是 language/zh-TW/zh-TW.xml。我们需在 标签之间加入下面这行:

<pdffontname>adobemingstd-light</pdffontname>

修改 Joomla! PDF 脚本程式

在 Joomla! PDF 脚本程式里似乎有个臭虫。它并没有正确地为文章内容设定字体。请用你爱用的文字编辑器开启档案 libraries/joomla/document/pdf/pdf.php。搜寻 function render( $cache = false, $params = array())。将下面这行插入到 $pdf->WriteHTML($this->getBuffer(), true); 之前。

$pdf->setFont($font, '', 10);

额外步骤

如果你能容忍 PDF 档案中文章内容丑陋的编排,这其实是选择性的步骤。这里的问题是 TCPDF 使用空白字元来排版,但中文字通常是连在一起,并没有空白字元夹在中间。

要 修正这个问题,你必须修改 TCPDF 核心程式。在你的伺服器上用你爱用的编辑器开启档案 libraries/tcpdf/tcpdf.php,找到 public function Write($h, $txt, $link='', $fill=0, $align='', $ln=false, $stretch=0, $firstline=false) 函式的定义。在该函式内,搜寻以下这行:

if (preg_match("/[\s]/u", $this->unichr($c))) {

以这行文字取代

if (preg_match("/[\s\p{Lo}]/u", $this->unichr($c))) {

现在从你的 Joomla! 网站前台,试着产生一个中文 PDF 档案,看看编排是否有改进。如果没有改进,表示你的伺服器上之 PCRE 函式库没有把 Unicode 性能支援编译进去。你可以在伺服器上用这个指令来检查:

$ pcretest -C

你会看见类似下面的输出

PCRE version 6.6 06-Feb-2006
Compiled with
  UTF-8 support
  Unicode properties support
  Newline character is LF
  Internal link size = 2
  POSIX malloc threshold = 10
  Default match limit = 10000000
  Default recursion depth limit = 10000000
  Match recursion uses stack

如果它显示 Unicode 性能支援没有启动,这步骤里的修改便无效。在这状况下,你可以下载 PCRE 函式库的程式码,自行编译以启用 Unicode 性能支援。一旦新编译的 PCRE 函式库安装好了,所产生之中文 PDF 的排版应该变得能被接受。

如果觉得懒惰.....

要是看到这些步骤让你觉得气馁,这里告诉你一个捷径。我把所有的档案(除了额外步骤提及的档案外,因为需要特别的 PCRE 函式库)打包成一个套件,放在 Joomla! Taiwan。你可以将它下载,放进你的伺服器上。

FaLang translation system by Faboba