iT邦幫忙

1

tcpdf 有關繁體中文、泰文、越南文夾雜如何處理?

  • 分享至 

  • xImage

利用 tcpdf 產生pdf ,
如果一篇文章,繁體中文、泰文、越南文夾雜在一起,
(不是一段一段哦,是一句中夾雜三種)
若用 $pdf->setFont('freeserif', '', 12)
泰文、越南文沒問題,但中文不行,
若用 $pdf->SetFont('cid0ct', '', 12); //
中文沒問題,但泰文、越南文則不行,

有沒有那一種字型可以同時滿足這三種字語文的?
或者說,如何處理這類混雜在一起的文章?

【已解決】
ArialUnicodeMS.ttf 可以同時支援繁體中文、泰文、越南文。

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
淺水員
iT邦大師 6 級 ‧ 2023-06-17 02:14:03
最佳解答

一個字型最多只能容納六萬多個字
所以,要先確定你會用到的字,範圍在哪邊?

如果你用得到的字數低於六萬多個
那麼找一個包含這些字的字型檔案即可

如果超過了,而且函式庫不提供自動切換字型的功能
就得自行手動偵測、切換字型了
(tcpdf 就我所知並不會自動切換不同的字型)

除了六萬多字的限制
還要考慮到罕見字的問題
這邊的罕見字是指 unicode 超過 FFFF 的字
(例如化學符號的「金杜」「金喜」「金波」「金黑」這四個字)

以下是我目前測試幾個函式庫的結果,提供參考

函式庫 罕見字測試 標楷體測試
dompdf 錯誤 破碎
mpdf 正常 正常
tcpdf 錯誤 破碎
ckp6250 iT邦好手 1 級 ‧ 2023-06-17 05:04:40 檢舉

那麼找一個包含這些字的字型檔案即可

我不會用到罕用字,只是,就是不知道那一個字型可以同時容納中、泰、越?

淺水員 iT邦大師 6 級 ‧ 2023-06-17 12:30:05 檢舉

目前我不知道哪個是你需要的

你可以先把會用到的 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));
ckp6250 iT邦好手 1 級 ‧ 2023-06-17 16:12:21 檢舉

感恩,我再試看看。
目前找到 ArialUnicodeMS.ttf 這個字型檔,可以滿足中、泰、越文的需求,在tcpdf 中使用正常。

1
rogeryao
iT邦超人 8 級 ‧ 2023-06-16 18:19:33
ckp6250 iT邦好手 1 級 ‧ 2023-06-17 16:14:53 檢舉

感恩,連結中提到了 ArialUnicodeMS.ttf
經測試,可以同時支援繁體中文、泰文、越南文。

rogeryao iT邦超人 8 級 ‧ 2023-06-17 16:20:14 檢舉

有解決了就好

我要發表回答

立即登入回答