perf(cff): Name/String/Global Subr INDEX 改 indexByteRange,删 getIndexBytes

与 Local Subr 同理:Name/String/Global Subr INDEX 仅需字节范围透传 + end
(下一 INDEX 起始),readIndex 全量解析 count+1 个 offset 是浪费。统一改用
indexByteRange,删除仅服务于这三个的 getIndexBytes。

思源场景 offset 数组不大故实测持平(subsetOTF min 0.49ms 不变),但消除潜在
全量解析浪费,与 Local Subr 处理一致;白狐 5字 min 0.052ms。
字节级零回归(cmp 输出逐字节一致);基准测试全字体 SSIM 与优化前完全一致。

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

View File

@ -55,10 +55,6 @@ function readIndex(b: Uint8Array, pos: number): CffIndex {
return { start: pos, count, offSize, offsets, dataStart, end: dataStart + offsets[count] - 1 };
}
/** 取一个已解析 INDEX 的完整字节切片(含头部+偏移量+数据,[start, end) */
function getIndexBytes(b: Uint8Array, idx: CffIndex): Uint8Array {
return b.subarray(idx.start, idx.end);
}
/** INDEX [start, end) offset
* Local/Global Subr INDEX count+1 offset
* Local Subr subrreadIndex subsetCFF
@ -308,9 +304,10 @@ export function subsetCFF(cffBytes: Uint8Array, subsetGids: number[]): Uint8Arra
/** Header: major(1) minor(1) hdrSize(1) offSize(1) */
const hdrSize = b[2];
/** Name INDEX 紧接 Header */
const nameIndex = readIndex(b, hdrSize);
/** Name INDEX 仅需字节范围(透传 headerName+ endTop DICT INDEX 起始),不全量解析 offset */
const nameRange = indexByteRange(b, hdrSize);
/** Top DICT INDEX 紧接 Name INDEX */
const topDictIndex = readIndex(b, nameIndex.end);
const topDictIndex = readIndex(b, nameRange.end);
if (topDictIndex.count < 1) return null;
/** Top DICT 数据 */
@ -321,9 +318,10 @@ export function subsetCFF(cffBytes: Uint8Array, subsetGids: number[]): Uint8Arra
/** 非 CID 字体(无 ROS走 name-keyed 结构,当前不支持 */
if (!topDict.has(OP_ROS)) return null;
/** String INDEX 紧接 Top DICT INDEXGlobal Subr INDEX 紧接其后 */
const stringIndex = readIndex(b, topDictIndex.end);
const globalSubrIndex = readIndex(b, stringIndex.end);
/** String INDEX Top DICT INDEXGlobal Subr INDEX
* + end INDEX offset */
const stringRange = indexByteRange(b, topDictIndex.end);
const globalSubrRange = indexByteRange(b, stringRange.end);
/** Top DICT 中各结构表的绝对偏移(相对 CFF 起始) */
const charStringsOff = topDict.get(OP_charStrings)?.[0];
@ -452,9 +450,9 @@ export function subsetCFF(cffBytes: Uint8Array, subsetGids: number[]): Uint8Arra
/** CFFHeader + Name INDEX + Top DICT INDEX + String INDEX + Global Subr INDEX
* + charset + charStrings + FDArray + FDSelect + Private
* Top DICT offset patch */
const headerNameBytes = combineBytes([b.subarray(0, hdrSize), getIndexBytes(b, nameIndex)]);
const stringSeg = getIndexBytes(b, stringIndex);
const globalSubrSeg = getIndexBytes(b, globalSubrIndex);
const headerNameBytes = combineBytes([b.subarray(0, hdrSize), b.subarray(nameRange.start, nameRange.end)]);
const stringSeg = b.subarray(stringRange.start, stringRange.end);
const globalSubrSeg = b.subarray(globalSubrRange.start, globalSubrRange.end);
/** Top DICT 原始字节(待 patch offset 后替换) */
const topDictBytes = b.subarray(topDictDataStart, topDictDataEnd);