Pre-compute the length of more intermediate tables in createCmapTable (PR 21103 follow-up)

With the exception of `glyphsIds` the length of the other segments can be trivially determined upfront, which is obvious in hindsight. This way unnecessary allocations can be avoided when building the "cmap" table.
This commit is contained in:
Jonas Jenwald 2026-04-16 09:44:02 +02:00
parent 0a4e8d024d
commit 92a0a91046

View File

@ -702,21 +702,18 @@ function createCmapTable(glyphs, toUnicodeExtraMap, numGlyphs) {
const searchParams = OpenTypeFileBuilder.getSearchParams(segCount, 2); const searchParams = OpenTypeFileBuilder.getSearchParams(segCount, 2);
// Fill up the 4 parallel arrays describing the segments. // Fill up the 4 parallel arrays describing the segments.
const startCount = new TrueTypeTableBuilder({}), const segmentsLength = bmpLength * 2 + trailingRangesCount * 2;
endCount = new TrueTypeTableBuilder({}), const startCount = new TrueTypeTableBuilder({ exactLength: segmentsLength }),
idDeltas = new TrueTypeTableBuilder({}), endCount = new TrueTypeTableBuilder({ exactLength: segmentsLength }),
idRangeOffsets = new TrueTypeTableBuilder({}), idDeltas = new TrueTypeTableBuilder({ exactLength: segmentsLength }),
idRangeOffsets = new TrueTypeTableBuilder({ exactLength: segmentsLength }),
glyphsIds = new TrueTypeTableBuilder({}); glyphsIds = new TrueTypeTableBuilder({});
let bias = 0; let bias = 0;
let range, start, end, codes;
for (i = 0, ii = bmpLength; i < ii; i++) { for (i = 0, ii = bmpLength; i < ii; i++) {
range = ranges[i]; const [start, end, codes] = ranges[i];
start = range[0];
end = range[1];
startCount.setInt16(start); startCount.setInt16(start);
endCount.setInt16(end); endCount.setInt16(end);
codes = range[2];
let contiguous = true; let contiguous = true;
for (j = 1, jj = codes.length; j < jj; ++j) { for (j = 1, jj = codes.length; j < jj; ++j) {
if (codes[j] !== codes[j - 1] + 1) { if (codes[j] !== codes[j - 1] + 1) {
@ -780,14 +777,13 @@ function createCmapTable(glyphs, toUnicodeExtraMap, numGlyphs) {
cmap31012.setInt32(4 + numTables * 8 + 4 + format314.length); // start of the table record cmap31012.setInt32(4 + numTables * 8 + 4 + format314.length); // start of the table record
format31012 = new TrueTypeTableBuilder({}); format31012 = new TrueTypeTableBuilder({});
for (i = 0, ii = ranges.length; i < ii; i++) { for (const range of ranges) {
range = ranges[i]; let start = range[0];
start = range[0]; const codes = range[2];
codes = range[2];
let code = codes[0]; let code = codes[0];
for (j = 1, jj = codes.length; j < jj; ++j) { for (j = 1, jj = codes.length; j < jj; ++j) {
if (codes[j] !== codes[j - 1] + 1) { if (codes[j] !== codes[j - 1] + 1) {
end = range[0] + j - 1; const end = range[0] + j - 1;
format31012.setInt32(start); // startCharCode format31012.setInt32(start); // startCharCode
format31012.setInt32(end); // endCharCode format31012.setInt32(end); // endCharCode
format31012.setInt32(code); // startGlyphID format31012.setInt32(code); // startGlyphID