From 8c1d1a58f7b8dacfea5fc77a50183b1a7868c0ff Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sun, 2 May 2021 11:54:05 +0200 Subject: [PATCH] Convert `src/core/opentype_file_builder.js` to use standard classes --- src/core/opentype_file_builder.js | 219 ++++++++++++++---------------- 1 file changed, 105 insertions(+), 114 deletions(-) diff --git a/src/core/opentype_file_builder.js b/src/core/opentype_file_builder.js index 1cf0ac811..9405ed40d 100644 --- a/src/core/opentype_file_builder.js +++ b/src/core/opentype_file_builder.js @@ -16,45 +16,43 @@ import { readUint32 } from "./core_utils.js"; import { string32 } from "../shared/util.js"; -const OpenTypeFileBuilder = (function OpenTypeFileBuilderClosure() { - function writeInt16(dest, offset, num) { - dest[offset] = (num >> 8) & 0xff; - dest[offset + 1] = num & 0xff; - } +function writeInt16(dest, offset, num) { + dest[offset] = (num >> 8) & 0xff; + dest[offset + 1] = num & 0xff; +} - function writeInt32(dest, offset, num) { - dest[offset] = (num >> 24) & 0xff; - dest[offset + 1] = (num >> 16) & 0xff; - dest[offset + 2] = (num >> 8) & 0xff; - dest[offset + 3] = num & 0xff; - } +function writeInt32(dest, offset, num) { + dest[offset] = (num >> 24) & 0xff; + dest[offset + 1] = (num >> 16) & 0xff; + dest[offset + 2] = (num >> 8) & 0xff; + dest[offset + 3] = num & 0xff; +} - function writeData(dest, offset, data) { - let i, ii; - if (data instanceof Uint8Array) { - dest.set(data, offset); - } else if (typeof data === "string") { - for (i = 0, ii = data.length; i < ii; i++) { - dest[offset++] = data.charCodeAt(i) & 0xff; - } - } else { - // treating everything else as array - for (i = 0, ii = data.length; i < ii; i++) { - dest[offset++] = data[i] & 0xff; - } +function writeData(dest, offset, data) { + if (data instanceof Uint8Array) { + dest.set(data, offset); + } else if (typeof data === "string") { + for (let i = 0, ii = data.length; i < ii; i++) { + dest[offset++] = data.charCodeAt(i) & 0xff; + } + } else { + // treating everything else as array + for (let i = 0, ii = data.length; i < ii; i++) { + dest[offset++] = data[i] & 0xff; } } +} - // eslint-disable-next-line no-shadow - function OpenTypeFileBuilder(sfnt) { +const OTF_HEADER_SIZE = 12; +const OTF_TABLE_ENTRY_SIZE = 16; + +class OpenTypeFileBuilder { + constructor(sfnt) { this.sfnt = sfnt; this.tables = Object.create(null); } - OpenTypeFileBuilder.getSearchParams = function OpenTypeFileBuilder_getSearchParams( - entriesCount, - entrySize - ) { + static getSearchParams(entriesCount, entrySize) { let maxPower2 = 1, log2 = 0; while ((maxPower2 ^ entriesCount) > maxPower2) { @@ -67,97 +65,90 @@ const OpenTypeFileBuilder = (function OpenTypeFileBuilderClosure() { entry: log2, rangeShift: entrySize * entriesCount - searchRange, }; - }; + } - const OTF_HEADER_SIZE = 12; - const OTF_TABLE_ENTRY_SIZE = 16; + toArray() { + let sfnt = this.sfnt; - OpenTypeFileBuilder.prototype = { - toArray: function OpenTypeFileBuilder_toArray() { - let sfnt = this.sfnt; + // Tables needs to be written by ascendant alphabetic order + const tables = this.tables; + const tablesNames = Object.keys(tables); + tablesNames.sort(); + const numTables = tablesNames.length; - // Tables needs to be written by ascendant alphabetic order - const tables = this.tables; - const tablesNames = Object.keys(tables); - tablesNames.sort(); - const numTables = tablesNames.length; + let i, j, jj, table, tableName; + // layout the tables data + let offset = OTF_HEADER_SIZE + numTables * OTF_TABLE_ENTRY_SIZE; + const tableOffsets = [offset]; + for (i = 0; i < numTables; i++) { + table = tables[tablesNames[i]]; + const paddedLength = ((table.length + 3) & ~3) >>> 0; + offset += paddedLength; + tableOffsets.push(offset); + } - let i, j, jj, table, tableName; - // layout the tables data - let offset = OTF_HEADER_SIZE + numTables * OTF_TABLE_ENTRY_SIZE; - const tableOffsets = [offset]; - for (i = 0; i < numTables; i++) { - table = tables[tablesNames[i]]; - const paddedLength = ((table.length + 3) & ~3) >>> 0; - offset += paddedLength; - tableOffsets.push(offset); + const file = new Uint8Array(offset); + // write the table data first (mostly for checksum) + for (i = 0; i < numTables; i++) { + table = tables[tablesNames[i]]; + writeData(file, tableOffsets[i], table); + } + + // sfnt version (4 bytes) + if (sfnt === "true") { + // Windows hates the Mac TrueType sfnt version number + sfnt = string32(0x00010000); + } + file[0] = sfnt.charCodeAt(0) & 0xff; + file[1] = sfnt.charCodeAt(1) & 0xff; + file[2] = sfnt.charCodeAt(2) & 0xff; + file[3] = sfnt.charCodeAt(3) & 0xff; + + // numTables (2 bytes) + writeInt16(file, 4, numTables); + + const searchParams = OpenTypeFileBuilder.getSearchParams(numTables, 16); + + // searchRange (2 bytes) + writeInt16(file, 6, searchParams.range); + // entrySelector (2 bytes) + writeInt16(file, 8, searchParams.entry); + // rangeShift (2 bytes) + writeInt16(file, 10, searchParams.rangeShift); + + offset = OTF_HEADER_SIZE; + // writing table entries + for (i = 0; i < numTables; i++) { + tableName = tablesNames[i]; + file[offset] = tableName.charCodeAt(0) & 0xff; + file[offset + 1] = tableName.charCodeAt(1) & 0xff; + file[offset + 2] = tableName.charCodeAt(2) & 0xff; + file[offset + 3] = tableName.charCodeAt(3) & 0xff; + + // checksum + let checksum = 0; + for (j = tableOffsets[i], jj = tableOffsets[i + 1]; j < jj; j += 4) { + const quad = readUint32(file, j); + checksum = (checksum + quad) >>> 0; } + writeInt32(file, offset + 4, checksum); - const file = new Uint8Array(offset); - // write the table data first (mostly for checksum) - for (i = 0; i < numTables; i++) { - table = tables[tablesNames[i]]; - writeData(file, tableOffsets[i], table); - } + // offset + writeInt32(file, offset + 8, tableOffsets[i]); + // length + writeInt32(file, offset + 12, tables[tableName].length); - // sfnt version (4 bytes) - if (sfnt === "true") { - // Windows hates the Mac TrueType sfnt version number - sfnt = string32(0x00010000); - } - file[0] = sfnt.charCodeAt(0) & 0xff; - file[1] = sfnt.charCodeAt(1) & 0xff; - file[2] = sfnt.charCodeAt(2) & 0xff; - file[3] = sfnt.charCodeAt(3) & 0xff; + offset += OTF_TABLE_ENTRY_SIZE; + } + return file; + } - // numTables (2 bytes) - writeInt16(file, 4, numTables); - - const searchParams = OpenTypeFileBuilder.getSearchParams(numTables, 16); - - // searchRange (2 bytes) - writeInt16(file, 6, searchParams.range); - // entrySelector (2 bytes) - writeInt16(file, 8, searchParams.entry); - // rangeShift (2 bytes) - writeInt16(file, 10, searchParams.rangeShift); - - offset = OTF_HEADER_SIZE; - // writing table entries - for (i = 0; i < numTables; i++) { - tableName = tablesNames[i]; - file[offset] = tableName.charCodeAt(0) & 0xff; - file[offset + 1] = tableName.charCodeAt(1) & 0xff; - file[offset + 2] = tableName.charCodeAt(2) & 0xff; - file[offset + 3] = tableName.charCodeAt(3) & 0xff; - - // checksum - let checksum = 0; - for (j = tableOffsets[i], jj = tableOffsets[i + 1]; j < jj; j += 4) { - const quad = readUint32(file, j); - checksum = (checksum + quad) >>> 0; - } - writeInt32(file, offset + 4, checksum); - - // offset - writeInt32(file, offset + 8, tableOffsets[i]); - // length - writeInt32(file, offset + 12, tables[tableName].length); - - offset += OTF_TABLE_ENTRY_SIZE; - } - return file; - }, - - addTable: function OpenTypeFileBuilder_addTable(tag, data) { - if (tag in this.tables) { - throw new Error("Table " + tag + " already exists"); - } - this.tables[tag] = data; - }, - }; - - return OpenTypeFileBuilder; -})(); + addTable(tag, data) { + if (tag in this.tables) { + throw new Error("Table " + tag + " already exists"); + } + this.tables[tag] = data; + } +} export { OpenTypeFileBuilder };