perf(gsub): readCoverageRemapped format2 range 改子集 gid 二分

与 readClassDefMap format2 同思路:原实现逐 gid 遍历 [start..e] 全部
查 gidLookup(FiraCode coverage format2 首次展开共 2317 gid,子集占极小
部分)。改为在升序子集 gid 数组上二分定位 [start,end] 内的 gid,仅 push
命中的 newGid。range 非空即 origNonEmpty=true(无论是否命中子集),与原
逐 gid 遍历语义一致。

subsetGSUB 再 -8.7%(0.314→0.287ms),FiraCode woff2 min 1.8→1.6ms
GSUB 输出 sha256 三字体全一致,SSIM 不变

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
崮生(子虚) 2026-07-24 16:30:00 +08:00
parent 06c8fcf18c
commit a1fe4da1ce

View File

@ -237,25 +237,50 @@ function readCoverageRemapped(
* FiraCode 11 format2 miss 439 end >= numGlyphs range gid
* ~320 gidLookup readCoverageRemapped */
const numGlyphs = gidLookup.length;
/**
* range readClassDefMap format2 [[gsub-classdef-format2-bsearch]]
* gid [start..e] gidLookupFiraCode coverage format2 2317 gid
* gid [start,end] gid push newGid
* range + range gid newGids gid */
const subsetGids = currentSortedSubsetGids;
const subsetLen = subsetGids.length;
let p = off + 4;
for (let i = 0; i < rangeCount; i++) {
if (p + 6 > len) break;
const start = dv.getUint16(p, false);
const end = dv.getUint16(p + 2, false);
/** COVERAGE_MAX_EXPAND range
* O(log) range */
if (end >= start && end - start < COVERAGE_MAX_EXPAND && newGids.length + (end - start + 1) <= COVERAGE_MAX_EXPAND) {
if (start >= numGlyphs) {
/** range gid push origNonEmpty=true
* newGids origNonEmpty=true outOfSubset null */
origNonEmpty = true;
} else {
/** clamp end gid start..numGlyphs-1 gid
* numGlyphs..end clamp */
} else if (subsetLen > 0) {
/** clamp end gid clamp gid [start..e]
* gid gid */
const e = end < numGlyphs ? end : numGlyphs - 1;
for (let g = start; g <= e; g++) {
origNonEmpty = true;
const m = gidLookup[g];
if (m >= 0) newGids.push(m);
/** range gidstart<=e origNonEmpty=true
* gid [start..e] origNonEmpty=true 使 */
origNonEmpty = true;
if (!(e < subsetGids[0] || start > subsetGids[subsetLen - 1])) {
/** 二分定位第一个 >= start 的子集 gid顺序扫描到 > e 为止 */
let lo = 0;
let hi = subsetLen;
while (lo < hi) {
const mid = (lo + hi) >>> 1;
if (subsetGids[mid] < start) lo = mid + 1;
else hi = mid;
}
for (let j = lo; j < subsetLen; j++) {
const g = subsetGids[j];
if (g > e) break;
newGids.push(gidLookup[g]);
}
}
} else {
/** 子集为空理论不会subsetGSUB 必有 .notdef保持 origNonEmpty 语义 */
origNonEmpty = true;
}
}
p += 6;