fix(cff-subset): replaceDictOffsets 补全 op30(BCD) 跳过分支

CFF DICT 的 op30 是 BCD 实数,每字节两 nibble 遇 0xf 结束。replaceDictOffsets 原仅处理
28/29/247-254 整数编码,漏 op30,遇到 BCD 字节会逐字节误扫。当前思源 Top DICT 的
CIDFontVersion(BCD 2.004) 后紧跟非替换目标 operator 且 BCD 字节均 >21,operator 边界
未被破坏故输出恰好正确,但若 BCD 内出现 <=21 字节会致 operator 错乱——潜在 bug。

补 op30 分支完整跳过 nibbles 至 0xf。基准测试全用例 SSIM 无变化(思源 otf 0.9530、白狐 1.0)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
崮生(子虚) 2026-07-24 23:00:51 +08:00
parent bebb8503f4
commit 67439be486

View File

@ -723,6 +723,13 @@ function replaceDictOffsets(dictBytes: Uint8Array, replacements: Map<number, num
p += 2;
} else if (b0 === 29) {
p += 4;
} else if (b0 === 30) {
/** BCD nibble 0xf BCD <=21
* operator operator Top DICT CIDFontVersion BCD */
while (p < len) {
const byte = dictBytes[p++];
if ((byte >> 4) === 0xf || (byte & 0xf) === 0xf) break;
}
} else if (b0 >= 247 && b0 <= 254) {
p += 1;
}