From 1dc4713a0baa73c2d395713fc955ac7a053dc2a3 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 5 Apr 2022 16:01:01 +0200 Subject: [PATCH 1/2] Re-factor the `isLittleEndian`/`isEvalSupported` caching This functionality is very old, hence we should be able to improve the caching a little bit with modern JavaScript features. --- src/core/function.js | 4 ++-- src/display/canvas.js | 4 ++-- src/display/font_loader.js | 4 ++-- src/shared/util.js | 23 +++++++++++------------ 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/core/function.js b/src/core/function.js index 37710610f..3d1285f41 100644 --- a/src/core/function.js +++ b/src/core/function.js @@ -15,9 +15,9 @@ import { Dict, Ref } from "./primitives.js"; import { + FeatureTest, FormatError, info, - IsEvalSupportedCached, shadow, unreachable, } from "../shared/util.js"; @@ -438,7 +438,7 @@ class PDFFunction { const parser = new PostScriptParser(lexer); const code = parser.parse(); - if (isEvalSupported && IsEvalSupportedCached.value) { + if (isEvalSupported && FeatureTest.isEvalSupported) { const compiled = new PostScriptCompiler().compile(code, domain, range); if (compiled) { // Compiled function consists of simple expressions such as addition, diff --git a/src/display/canvas.js b/src/display/canvas.js index 6ca01a1c7..3dc0ad1de 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -14,11 +14,11 @@ */ import { + FeatureTest, FONT_IDENTITY_MATRIX, IDENTITY_MATRIX, ImageKind, info, - IsLittleEndianCached, OPS, shadow, TextRenderingMode, @@ -702,7 +702,7 @@ function putBinaryImageData(ctx, imgData, transferMaps = null) { const dest32DataLength = dest32.length; const fullSrcDiff = (width + 7) >> 3; let white = 0xffffffff; - let black = IsLittleEndianCached.value ? 0xff000000 : 0x000000ff; + let black = FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; if (transferMapGray) { if (transferMapGray[0] === 0xff && transferMapGray[0xff] === 0) { diff --git a/src/display/font_loader.js b/src/display/font_loader.js index 0b6aedc45..a80a7de6e 100644 --- a/src/display/font_loader.js +++ b/src/display/font_loader.js @@ -16,7 +16,7 @@ import { assert, bytesToString, - IsEvalSupportedCached, + FeatureTest, shadow, string32, unreachable, @@ -455,7 +455,7 @@ class FontFaceObject { } // If we can, compile cmds into JS for MAXIMUM SPEED... - if (this.isEvalSupported && IsEvalSupportedCached.value) { + if (this.isEvalSupported && FeatureTest.isEvalSupported) { const jsBuf = []; for (const current of cmds) { const args = current.args !== undefined ? current.args.join(",") : ""; diff --git a/src/shared/util.js b/src/shared/util.js index e51f61735..ee0a7eceb 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -682,11 +682,6 @@ function isLittleEndian() { const view32 = new Uint32Array(buffer8.buffer, 0, 1); return view32[0] === 1; } -const IsLittleEndianCached = { - get value() { - return shadow(this, "value", isLittleEndian()); - }, -}; // Checks if it's possible to eval JS expressions. function isEvalSupported() { @@ -697,11 +692,16 @@ function isEvalSupported() { return false; } } -const IsEvalSupportedCached = { - get value() { - return shadow(this, "value", isEvalSupported()); - }, -}; + +class FeatureTest { + static get isLittleEndian() { + return shadow(this, "isLittleEndian", isLittleEndian()); + } + + static get isEvalSupported() { + return shadow(this, "isEvalSupported", isEvalSupported()); + } +} const hexNumbers = [...Array(256).keys()].map(n => n.toString(16).padStart(2, "0") @@ -1103,6 +1103,7 @@ export { createValidAbsoluteUrl, DocumentActionEventType, escapeString, + FeatureTest, FONT_IDENTITY_MATRIX, FontType, FormatError, @@ -1115,8 +1116,6 @@ export { isArrayBuffer, isArrayEqual, isAscii, - IsEvalSupportedCached, - IsLittleEndianCached, MissingPDFException, objectFromMap, objectSize, From a919959d8388602d0789a1b56e093a67678cd1fd Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 5 Apr 2022 16:04:09 +0200 Subject: [PATCH 2/2] Slightly simplify the `Catalog._readMarkInfo` method We don't need to first check if the Dictionary contains the key, since trying to get a non-existent key simply returns `undefined` and we're already ensuring that the value is a boolean. Furthermore, we shouldn't need to worry about the `Object.prototype` containing enumerable properties since the checks (in `src/core/worker.js`) done for `Array.prototype` *indirectly* also cover `Object`s. (Keep in mind that an `Array` is just a special kind of `Object` in JavaScript.) --- src/core/catalog.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/core/catalog.js b/src/core/catalog.js index 13f54f75d..dcc509c91 100644 --- a/src/core/catalog.js +++ b/src/core/catalog.js @@ -209,20 +209,16 @@ class Catalog { return null; } - const markInfo = Object.assign(Object.create(null), { + const markInfo = { Marked: false, UserProperties: false, Suspects: false, - }); + }; for (const key in markInfo) { - if (!obj.has(key)) { - continue; - } const value = obj.get(key); - if (typeof value !== "boolean") { - continue; + if (typeof value === "boolean") { + markInfo[key] = value; } - markInfo[key] = value; } return markInfo;