崮生(子虚) ae41a99e95 perf(gsub): serialize type2/3/4 大 coverage 反转遍历 + 修越界 undefined bug
serializeMultipleSubst/serializeAlternateSubst/serializeLigatureSubst 原实现
readCoverageGids 全量展开 coverage 再逐个查 gidLookup,与 serializeSingleSubst
([[gsub-serialize-single-bigcov-reverse]] 早修)同类的 serialize 侧浪费。

probe 实测:白狐千字文 type3 coverage=1000、初夏 type3=329/type4=97、霞鹜 type4=94,
但子集仅命中个位数。CJK 字体(令东/思源 TTF+OTF)type2/3/4 全无调用。

优化:套用 serializeSingleSubst 的反转模式——coverageCount 判大小,coverage 远大于
子集(covGidCount > subsetLen*4 && >16)时遍历 currentSortedSubsetGids 用
coverageIndexOf 二分定位 coverage 下标 idx(即 set 偏移数组下标),替代全量展开。

附带修复原版越界 bug:原版 gidLookup[covGids[i]] 当 covGids[i] 超出 numGlyphs
(损坏 coverage,白狐实测含)返回 undefined,`undefined < 0` 为 false(NaN 比较)漏过,
产生 from=undefined 的非法 AlternateSet entry(emitCoverage 写无效 gid)。
两路径统一改 `!(fromNew >= 0)`(undefined>=0 也是 false → 跳过),与反转路径行为一致。
区别于 reachable 侧 readCoverageRemapped 早有 numGlyphs 越界保护(line 221-261)。

A/B:初夏/霞鹜千字文(type3/4 触发反转)字节与基准线 IDENTICAL;白狐千字文字节变小
(-12B ttf/-16B woff2,即去掉的非法 entry)。
基准测试新增「otf-白狐千字文」用例验证:SSIM=1.0000 ink=19735/19735(渲染像素级一致,
证明去掉的是浏览器本就忽略的无效 gid entry)。

性能 best-of N=2000:白狐千字文 min -5.4%/p10 -6.7%、初夏 -5.1%/-3.9%、霞鹜 -5.6%/-3.5%;
令东千字文(无 type2/3/4)持平。29 用例全 SSIM PASS。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-25 04:58:34 +08:00
..
2026-04-08 22:05:17 +08:00
2024-08-19 18:10:09 +08:00