// 采集驾驶舱的「实际用字清单」——中文字体子集化的输入(规格 11:中文字体必须子集化)。 // // 为什么是源码而不是运行时:运行时文本来自后端(设备名/点位名/事件文本),无法穷举, // 这正是规格 11 要求「子集字体必须保留系统回退链」的原因——子集外汉字落到系统字体。 // 本脚本只收「源码里能看到的静态用字」+ 设计稿可见文案,动态值不假装能覆盖。 // // 用法:node .scratch/lanhu-cockpit-asset-replacement/tools/collect-charset.mjs import { readFileSync, writeFileSync, readdirSync, statSync } from 'node:fs' import { join, dirname } from 'node:path' import { fileURLToPath } from 'node:url' const here = dirname(fileURLToPath(import.meta.url)) const ROOT = join(here, '..', '..', '..') function walk(dir, exts, out = []) { for (const name of readdirSync(dir)) { if (name === 'node_modules') continue const p = join(dir, name) if (statSync(p).isDirectory()) walk(p, exts, out) else if (exts.some((e) => name.endsWith(e))) out.push(p) } return out } const sourceFiles = walk(join(ROOT, 'src', 'modules', 'cockpit'), ['.vue', '.js', '.css']) const staticChars = new Set() for (const f of sourceFiles) { for (const ch of readFileSync(f, 'utf8')) if (ch.codePointAt(0) > 0x7f) staticChars.add(ch) } // 设计稿可见文案(raw-v2 的 Figma JSON):补上「源码没有但设计稿有」的字 const designChars = new Set() const rawV2 = join(here, '..', 'research', 'raw-v2') for (const f of readdirSync(rawV2)) { for (const ch of readFileSync(join(rawV2, f), 'utf8')) { const cp = ch.codePointAt(0) if (cp > 0x2e80) designChars.add(ch) } } // 子集文本 = 静态用字 ∪ 设计稿文案 ∪ 可打印 ASCII const ascii = Array.from({ length: 0x7f - 0x20 }, (_, i) => String.fromCodePoint(0x20 + i)).join('') const subsetChars = new Set([...staticChars, ...designChars, ...ascii]) const result = { note: '驾驶舱静态用字清单;运行时动态文本不在内,故子集字体必须保留系统回退链(规格 11)。', sources: { sourceFiles: sourceFiles.length, staticChars: staticChars.size, designChars: designChars.size, }, subsetText: [...subsetChars].sort().join(''), } writeFileSync(join(here, 'charset.json'), JSON.stringify(result, null, 2), 'utf8') console.log('source files:', sourceFiles.length) console.log('static non-ASCII chars:', staticChars.size, '| design-only chars:', designChars.size) console.log('subset text chars:', subsetChars.size) console.log('wrote tools/charset.json')