From c6316378f2511d53b097fbe49a82e63a13bf37c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B4=AE=E7=94=9F=EF=BC=88=E5=AD=90=E8=99=9A=EF=BC=89?= <2234839456@qq.com> Date: Fri, 24 Jul 2026 20:32:39 +0800 Subject: [PATCH] =?UTF-8?q?perf(cmap):=20presetCmap=20=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=20parse=20=E6=8F=90=E5=89=8D=E8=BF=94=E5=9B=9E=E8=B7=B3?= =?UTF-8?q?=E8=BF=87=20subtable=20=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 承接优化315(readWindowsAllCodes 复用 presetCmap),cmap.parse 在 presetCmap 存在时 直接返回 presetCmap,跳过整个 cmap 解析:子表目录扫描 + readSubTable 建 format4._lazySegs /format12._lazyGroups + readWindowsAllCodes 调用。 presetCmap 模式下 subTables 的 _lazySegs/_lazyGroups 不再被 lookupFormat4/12 使用 (readWindowsAllCodes 已跳过),cmap.write/sizeof 用 ttf.cmap 的 keys 重建不依赖 subTables,故 format4/12 subtable 的 header 解析纯粹是无用功。 收益(Font.create best-of,叠加优化315的总收益):千字文思源 -8.4%、初夏纯标点 -6.2%、 FiraCode -5.0%、思源标点 -5.5%。千字文前段 woff2 基准 avg 4.9→3.7ms。6 字体 woff2 sha 逐字节一致,SSIM 全部不变。 Co-Authored-By: Claude Opus 4.8 (1M context) --- vendor/fonteditor-core/lib/ttf/table/cmap/parse.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vendor/fonteditor-core/lib/ttf/table/cmap/parse.js b/vendor/fonteditor-core/lib/ttf/table/cmap/parse.js index bf6478c..1807b6a 100644 --- a/vendor/fonteditor-core/lib/ttf/table/cmap/parse.js +++ b/vendor/fonteditor-core/lib/ttf/table/cmap/parse.js @@ -257,6 +257,17 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { } function parse(reader, ttf) { + /** + * 优化316: presetCmap 模式下(subset 复用 probeGsubAndCmap 的 codepoint→gid,见 readWindowsAllCodes 优化315), + * 直接返回 presetCmap 跳过整个 cmap 解析(目录扫描 + readSubTable 建 format4._lazySegs/format12._lazyGroups + + * readWindowsAllCodes 二分)。presetCmap 模式下 subTables 的 _lazySegs/_lazyGroups 不再被 lookupFormat4/12 使用 + * (readWindowsAllCodes 已跳过),cmap.write/sizeof 用 ttf.cmap 的 keys 重建不依赖 subTables, + * 故 format4/12 subtable 的 header 解析纯粹是无用功。presetCmap 由 fontSubset 每次新建({}),单次 create 内只读,引用安全。 + */ + if (ttf.readOptions && ttf.readOptions.presetCmap) { + return ttf.readOptions.presetCmap; + } + var tcmap = {}; var cmapOffset = this.offset; reader.seek(cmapOffset);