TCPDF版本:v6.6.2
虽然我还满确定这是 bug 的,也发了 PR,但他们还没有确认。
故以下内容先当作是我个人的看法。
概述
TrueType 字型中 head 表中有个 checksumAdjustment 栏位,这扮演 checksum 的角色。
如果开启 subset 功能,TCPDF 必须重组字型资料。当它在写入这个栏位的时候,位置的计算忘记加上一个额外的 offset,导致这个 checksum 会被写入到字型的其它位置,造成不可预知的结果。
个人觉得这就是有些字型可以正常运作,但有些字型会遇到异常状况的原因。由于原始字型内部 table 的排列顺序不同,被覆盖掉的资料如果是不重要的栏位,可能看起来就很正常。
相关原始码
档案:src/include/tcpdf_fonts.php
1374 ~ 1368 行
$offset = ($numTables * 16);foreach ($table as $tag => $data) {$font .= $tag; // tag$font .= pack('N', $data['checkSum']); // checkSum // 注意下面这行是有加上 $offset 的$font .= pack('N', ($data['offset'] + $offset)); // offset$font .= pack('N', $data['length']); // length}foreach ($table as $data) {$font .= $data['data'];}// set checkSumAdjustment on head table$checkSumAdjustment = 0xB1B0AFBA - self::_getTTFtableChecksum($font, strlen($font));// 下面这行计算偏移量时,忘记把 $offset 加上去$font = substr($font, 0, $table['head']['offset'] + 8).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + 12);
第一个 foreach 迴圈,是在写 TableRecord。其中 offset 的部分它是有加上 $offset
的
$font .= pack('N', ($data['offset'] + $offset)); // offset
但后来在写入 $checkSumAdjustment
时,却忘记加上去了
要修正的话把 $offset
加上去即可
$font = substr($font, 0, $table['head']['offset'] + $offset + 8).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + $offset + 12);