From 05de20071a43f7dac9903835f479d57e863521f7 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 27 Feb 2021 14:20:43 +0100 Subject: [PATCH] Modernize some of the code in `src/core/cmap.js` by using classes and async/await This converts a couple of our old "classes" to proper ECMAScript classes, and replaces a lot of manual Promise-wrapping with async/await instead. --- src/core/cmap.js | 174 +++++++++++++++++++++-------------------------- 1 file changed, 79 insertions(+), 95 deletions(-) diff --git a/src/core/cmap.js b/src/core/cmap.js index a6abeaab5..dbf083bf9 100644 --- a/src/core/cmap.js +++ b/src/core/cmap.js @@ -479,20 +479,21 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() { var MAX_NUM_SIZE = 16; var MAX_ENCODED_NUM_SIZE = 19; // ceil(MAX_NUM_SIZE * 7 / 8) - function BinaryCMapStream(data) { - this.buffer = data; - this.pos = 0; - this.end = data.length; - this.tmpBuf = new Uint8Array(MAX_ENCODED_NUM_SIZE); - } + class BinaryCMapStream { + constructor(data) { + this.buffer = data; + this.pos = 0; + this.end = data.length; + this.tmpBuf = new Uint8Array(MAX_ENCODED_NUM_SIZE); + } - BinaryCMapStream.prototype = { readByte() { if (this.pos >= this.end) { return -1; } return this.buffer[this.pos++]; - }, + } + readNumber() { var n = 0; var last; @@ -505,15 +506,18 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() { n = (n << 7) | (b & 0x7f); } while (!last); return n; - }, + } + readSigned() { var n = this.readNumber(); return n & 1 ? ~(n >>> 1) : n >>> 1; - }, + } + readHex(num, size) { num.set(this.buffer.subarray(this.pos, this.pos + size + 1)); this.pos += size + 1; - }, + } + readHexNumber(num, size) { var last; var stack = this.tmpBuf, @@ -539,7 +543,8 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() { buffer >>= 8; bufferSize -= 8; } - }, + } + readHexSigned(num, size) { this.readHexNumber(num, size); var sign = num[size] & 1 ? 255 : 0; @@ -548,7 +553,8 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() { c = ((c & 1) << 8) | num[i]; num[i] = (c >> 1) ^ sign; } - }, + } + readString() { var len = this.readNumber(); var s = ""; @@ -556,11 +562,12 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() { s += String.fromCharCode(this.readNumber()); } return s; - }, - }; + } + } - function processBinaryCMap(data, cMap, extend) { - return new Promise(function (resolve, reject) { + // eslint-disable-next-line no-shadow + class BinaryCMapReader { + async process(data, cMap, extend) { var stream = new BinaryCMapStream(data); var header = stream.readByte(); cMap.vertical = !!(header & 1); @@ -592,7 +599,7 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() { var dataSize = b & 15; if (dataSize + 1 > MAX_NUM_SIZE) { - throw new Error("processBinaryCMap: Invalid dataSize."); + throw new Error("BinaryCMapReader.process: Invalid dataSize."); } var ucs2DataSize = 1; @@ -730,26 +737,17 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() { } break; default: - reject(new Error("processBinaryCMap: Unknown type: " + type)); - return; + throw new Error(`BinaryCMapReader.process - unknown type: ${type}`); } } if (useCMap) { - resolve(extend(useCMap)); - return; + return extend(useCMap); } - resolve(cMap); - }); + return cMap; + } } - // eslint-disable-next-line no-shadow - function BinaryCMapReader() {} - - BinaryCMapReader.prototype = { - process: processBinaryCMap, - }; - return BinaryCMapReader; })(); @@ -902,7 +900,7 @@ var CMapFactory = (function CMapFactoryClosure() { } } - function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) { + async function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) { var previous; var embeddedUseCMap; objLoop: while (true) { @@ -960,74 +958,59 @@ var CMapFactory = (function CMapFactoryClosure() { if (useCMap) { return extendCMap(cMap, fetchBuiltInCMap, useCMap); } - return Promise.resolve(cMap); + return cMap; } - function extendCMap(cMap, fetchBuiltInCMap, useCMap) { - return createBuiltInCMap(useCMap, fetchBuiltInCMap).then(function ( - newCMap - ) { - cMap.useCMap = newCMap; - // If there aren't any code space ranges defined clone all the parent ones - // into this cMap. - if (cMap.numCodespaceRanges === 0) { - var useCodespaceRanges = cMap.useCMap.codespaceRanges; - for (var i = 0; i < useCodespaceRanges.length; i++) { - cMap.codespaceRanges[i] = useCodespaceRanges[i].slice(); - } - cMap.numCodespaceRanges = cMap.useCMap.numCodespaceRanges; + async function extendCMap(cMap, fetchBuiltInCMap, useCMap) { + cMap.useCMap = await createBuiltInCMap(useCMap, fetchBuiltInCMap); + // If there aren't any code space ranges defined clone all the parent ones + // into this cMap. + if (cMap.numCodespaceRanges === 0) { + var useCodespaceRanges = cMap.useCMap.codespaceRanges; + for (var i = 0; i < useCodespaceRanges.length; i++) { + cMap.codespaceRanges[i] = useCodespaceRanges[i].slice(); + } + cMap.numCodespaceRanges = cMap.useCMap.numCodespaceRanges; + } + // Merge the map into the current one, making sure not to override + // any previously defined entries. + cMap.useCMap.forEach(function (key, value) { + if (!cMap.contains(key)) { + cMap.mapOne(key, cMap.useCMap.lookup(key)); } - // Merge the map into the current one, making sure not to override - // any previously defined entries. - cMap.useCMap.forEach(function (key, value) { - if (!cMap.contains(key)) { - cMap.mapOne(key, cMap.useCMap.lookup(key)); - } - }); - - return cMap; }); + + return cMap; } - function createBuiltInCMap(name, fetchBuiltInCMap) { + async function createBuiltInCMap(name, fetchBuiltInCMap) { if (name === "Identity-H") { - return Promise.resolve(new IdentityCMap(false, 2)); + return new IdentityCMap(false, 2); } else if (name === "Identity-V") { - return Promise.resolve(new IdentityCMap(true, 2)); + return new IdentityCMap(true, 2); } if (!BUILT_IN_CMAPS.includes(name)) { - return Promise.reject(new Error("Unknown CMap name: " + name)); + throw new Error("Unknown CMap name: " + name); } if (!fetchBuiltInCMap) { - return Promise.reject( - new Error("Built-in CMap parameters are not provided.") - ); + throw new Error("Built-in CMap parameters are not provided."); } - return fetchBuiltInCMap(name).then(function (data) { - var cMapData = data.cMapData, - compressionType = data.compressionType; - var cMap = new CMap(true); + const { cMapData, compressionType } = await fetchBuiltInCMap(name); + var cMap = new CMap(true); - if (compressionType === CMapCompressionType.BINARY) { - return new BinaryCMapReader().process( - cMapData, - cMap, - function (useCMap) { - return extendCMap(cMap, fetchBuiltInCMap, useCMap); - } - ); - } - if (compressionType === CMapCompressionType.NONE) { - var lexer = new Lexer(new Stream(cMapData)); - return parseCMap(cMap, lexer, fetchBuiltInCMap, null); - } - return Promise.reject( - new Error( - "TODO: Only BINARY/NONE CMap compression is currently supported." - ) - ); - }); + if (compressionType === CMapCompressionType.BINARY) { + return new BinaryCMapReader().process(cMapData, cMap, useCMap => { + return extendCMap(cMap, fetchBuiltInCMap, useCMap); + }); + } + if (compressionType === CMapCompressionType.NONE) { + var lexer = new Lexer(new Stream(cMapData)); + return parseCMap(cMap, lexer, fetchBuiltInCMap, null); + } + throw new Error( + "TODO: Only BINARY/NONE CMap compression is currently supported." + ); } return { @@ -1039,16 +1022,17 @@ var CMapFactory = (function CMapFactoryClosure() { if (isName(encoding)) { return createBuiltInCMap(encoding.name, fetchBuiltInCMap); } else if (isStream(encoding)) { - var cMap = new CMap(); - var lexer = new Lexer(encoding); - return parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap).then(function ( - parsedCMap - ) { - if (parsedCMap.isIdentityCMap) { - return createBuiltInCMap(parsedCMap.name, fetchBuiltInCMap); - } - return parsedCMap; - }); + const parsedCMap = await parseCMap( + /* cMap = */ new CMap(), + /* lexer = */ new Lexer(encoding), + fetchBuiltInCMap, + useCMap + ); + + if (parsedCMap.isIdentityCMap) { + return createBuiltInCMap(parsedCMap.name, fetchBuiltInCMap); + } + return parsedCMap; } throw new Error("Encoding required."); },