利用 tcpdf 產生pdf ,
如果一篇文章,繁體中文、泰文、越南文夾雜在一起,
(不是一段一段哦,是一句中夾雜三種)
若用 $pdf->setFont('freeserif', '', 12)
泰文、越南文沒問題,但中文不行,
若用 $pdf->SetFont('cid0ct', '', 12); //
中文沒問題,但泰文、越南文則不行,
有沒有那一種字型可以同時滿足這三種字語文的?
或者說,如何處理這類混雜在一起的文章?
【已解決】
ArialUnicodeMS.ttf 可以同時支援繁體中文、泰文、越南文。
一個字型最多只能容納六萬多個字
所以,要先確定你會用到的字,範圍在哪邊?
如果你用得到的字數低於六萬多個
那麼找一個包含這些字的字型檔案即可
如果超過了,而且函式庫不提供自動切換字型的功能
就得自行手動偵測、切換字型了
(tcpdf 就我所知並不會自動切換不同的字型)
除了六萬多字的限制
還要考慮到罕見字的問題
這邊的罕見字是指 unicode 超過 FFFF 的字
(例如化學符號的「金杜」「金喜」「金波」「金黑」這四個字)
以下是我目前測試幾個函式庫的結果,提供參考
函式庫 | 罕見字測試 | 標楷體測試 |
---|---|---|
dompdf | 錯誤 | 破碎 |
mpdf | 正常 | 正常 |
tcpdf | 錯誤 | 破碎 |
那麼找一個包含這些字的字型檔案即可
我不會用到罕用字,只是,就是不知道那一個字型可以同時容納中、泰、越?
目前我不知道哪個是你需要的
你可以先把會用到的 unicode 範圍列出來
然後下面是一個可以偵測 unicode 是否存在的方式
composer require ren1244/sfnt
在命令列執行的範例
<?php
require('vendor/autoload.php');
use ren1244\sfnt\Sfnt;
use ren1244\sfnt\TypeReader;
use ren1244\sfnt\table\T_cmap;
// 要偵測的字型檔案
$fontFile = __DIR__ . '/SourceHanSansTC-Regular.ttf';
if (!file_exists($fontFile)) {
exit('檔案不存在');
}
// 建立 Sfnt 實體,並確認是 TTF
$reader = new TypeReader(file_get_contents($fontFile));
$font = new Sfnt($reader);
if ($font->sfntVersion !== 0x00010000) {
exit('不是 TTF');
}
// 印出字型內,CMAP 表的資訊,有些套件載入字型可能會用到這些參數
$cmapTable = $font->table('cmap');
$records = $cmapTable->readEncodingRecords();
printf("%-12s %s\n", 'platform', 'encoding');
foreach ($records as $rec) {
$platId = $rec['platformID'];
$encodingId = $rec['encodingID'];
$info = T_cmap::INFO[$platId];
$platStr = $info['platform'];
$encodingStr = $info['encoding'][$encodingId] ?? '無資料';
printf("%-12s %s\n", "$platId ($platStr)", "$encodingId ($encodingStr)");
}
// 取得 unicode => glyf id 的映射表
// 會從 (platformID, encodingID) = {(3, 10), (0, 4), (3, 1), (0, 3)} 去尋找
// 只讀取最先找到的
$utg = $cmapTable->getUnicodeToGid();
// 測試 unicode 1~200 有哪些不在這個字型內
$notExistsArray = [];
for ($unicode = 1; $unicode <= 200; ++$unicode) {
if (!isset($utg[$unicode])) {
$notExistsArray[] = $unicode;
}
}
printf("以下 unicode 不在此字型\n%s", implode(', ', $notExistsArray));
感恩,我再試看看。
目前找到 ArialUnicodeMS.ttf 這個字型檔,可以滿足中、泰、越文的需求,在tcpdf 中使用正常。