Convert the code in src/core/evaluator.js to use standard classes

This removes additional `// eslint-disable-next-line no-shadow` usage, which our old pseudo-classes necessitated.

Most of the re-formatting changes, after the `class` definitions and methods were fixed, were done automatically by Prettier.

*Please note:* I'm purposely not doing any `var` to `let`/`const` conversion here, since it's generally better to (if possible) do that automatically on e.g. a directory basis instead.
This commit is contained in:
Jonas Jenwald 2020-07-05 12:20:10 +02:00
parent 32a0b6fa73
commit c95fbb6e21

View File

@ -163,28 +163,35 @@ function normalizeBlendMode(value, parsingArray = false) {
}
// Trying to minimize Date.now() usage and check every 100 time.
var TIME_SLOT_DURATION_MS = 20;
var CHECK_TIME_EVERY = 100;
function TimeSlotManager() {
class TimeSlotManager {
static get TIME_SLOT_DURATION_MS() {
return shadow(this, "TIME_SLOT_DURATION_MS", 20);
}
static get CHECK_TIME_EVERY() {
return shadow(this, "CHECK_TIME_EVERY", 100);
}
constructor() {
this.reset();
}
TimeSlotManager.prototype = {
check: function TimeSlotManager_check() {
if (++this.checked < CHECK_TIME_EVERY) {
}
check() {
if (++this.checked < TimeSlotManager.CHECK_TIME_EVERY) {
return false;
}
this.checked = 0;
return this.endTime <= Date.now();
},
reset: function TimeSlotManager_reset() {
this.endTime = Date.now() + TIME_SLOT_DURATION_MS;
this.checked = 0;
},
};
}
var PartialEvaluator = (function PartialEvaluatorClosure() {
// eslint-disable-next-line no-shadow
function PartialEvaluator({
reset() {
this.endTime = Date.now() + TimeSlotManager.TIME_SLOT_DURATION_MS;
this.checked = 0;
}
}
class PartialEvaluator {
constructor({
xref,
handler,
pageIndex,
@ -207,7 +214,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
this._fetchBuiltInCMapBound = this.fetchBuiltInCMap.bind(this);
}
PartialEvaluator.prototype = {
/**
* Since Functions are only cached (locally) by reference, we can share one
* `PDFFunctionFactory` instance within this `PartialEvaluator` instance.
@ -218,15 +224,15 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
isEvalSupported: this.options.isEvalSupported,
});
return shadow(this, "_pdfFunctionFactory", pdfFunctionFactory);
},
}
clone(newOptions = DefaultPartialEvaluatorOptions) {
var newEvaluator = Object.create(this);
newEvaluator.options = newOptions;
return newEvaluator;
},
}
hasBlendModes: function PartialEvaluator_hasBlendModes(resources) {
hasBlendModes(resources) {
if (!(resources instanceof Dict)) {
return false;
}
@ -359,7 +365,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
}
return false;
},
}
async fetchBuiltInCMap(name) {
const cachedData = this.builtInCMapCache.get(name);
@ -389,7 +395,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
this.builtInCMapCache.set(name, data);
}
return data;
},
}
async buildFormXObject(
resources,
@ -466,7 +472,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
operatorList.addOp(OPS.endGroup, [groupOptions]);
}
});
},
}
_sendImgData(objId, imgData, cacheGlobally = false) {
const transfers = imgData ? [imgData.data.buffer] : null;
@ -490,7 +496,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
[objId, this.pageIndex, "Image", imgData],
transfers
);
},
}
async buildPaintImageXObject({
resources,
@ -644,9 +650,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
}
return undefined;
},
}
handleSMask: function PartialEvaluator_handleSmask(
handleSMask(
smask,
resources,
operatorList,
@ -684,7 +690,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
stateManager.state.clone(),
localColorSpaceCache
);
},
}
handleTilingType(
fn,
@ -741,16 +747,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
throw reason;
}
);
},
}
handleSetFont: function PartialEvaluator_handleSetFont(
resources,
fontArgs,
fontRef,
operatorList,
task,
state
) {
handleSetFont(resources, fontArgs, fontRef, operatorList, task, state) {
// TODO(mack): Not needed?
var fontName;
if (fontArgs) {
@ -787,7 +786,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
translated.send(this.handler);
return translated.loadedName;
});
},
}
handleText(chars, state) {
const font = state.font;
@ -807,7 +806,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
}
return glyphs;
},
}
ensureStateFont(state) {
if (state.font) {
@ -827,9 +826,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
return;
}
throw reason;
},
}
setGState: function PartialEvaluator_setGState(
setGState(
resources,
gState,
operatorList,
@ -927,9 +926,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
operatorList.addOp(OPS.setGState, [gStateObj]);
}
});
},
}
loadFont: function PartialEvaluator_loadFont(fontName, font, resources) {
loadFont(fontName, font, resources) {
const errorFont = () => {
return Promise.resolve(
new TranslatedFont({
@ -973,7 +972,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
// Falling back to a default font to avoid completely broken rendering,
// but note that there're no guarantees that things will look "correct".
fontRef = PartialEvaluator.getFallbackFontDict();
fontRef = PartialEvaluator.fallbackFontDict;
}
if (this.fontCache.has(fontRef)) {
@ -1010,11 +1009,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
if (fontAliases[hash]) {
var aliasFontRef = fontAliases[hash].aliasRef;
if (
fontRefIsRef &&
aliasFontRef &&
this.fontCache.has(aliasFontRef)
) {
if (fontRefIsRef && aliasFontRef && this.fontCache.has(aliasFontRef)) {
this.fontCache.putAlias(fontRef, aliasFontRef);
return this.fontCache.get(fontRef);
}
@ -1118,7 +1113,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
);
});
return fontCapability.promise;
},
}
buildPath(operatorList, fn, args, parsingText = false) {
var lastIndex = operatorList.length - 1;
@ -1151,7 +1146,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
opArgs[0].push(fn);
Array.prototype.push.apply(opArgs[1], args);
}
},
}
parseColorSpace({ cs, resources, localColorSpaceCache }) {
return ColorSpace.parseAsync({
@ -1175,7 +1170,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
throw reason;
});
},
}
async handleColorN(
operatorList,
@ -1224,7 +1219,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
throw new FormatError(`Unknown PatternType: ${typeNum}`);
}
throw new FormatError(`Unknown PatternName: ${patternName}`);
},
}
getOperatorList({
stream,
@ -1305,9 +1300,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
next(
new Promise(function (resolveXObject, rejectXObject) {
if (!name) {
throw new FormatError(
"XObject must be referred to by name."
);
throw new FormatError("XObject must be referred to by name.");
}
let xobj = xobjs.getRaw(name);
@ -1750,7 +1743,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
throw reason;
});
},
}
getTextContent({
stream,
@ -1872,8 +1865,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
textContentItem.spaceWidth = spaceWidth;
textContentItem.fakeSpaceMin = spaceWidth * SPACE_FACTOR;
textContentItem.fakeMultiSpaceMin = spaceWidth * MULTI_SPACE_FACTOR;
textContentItem.fakeMultiSpaceMax =
spaceWidth * MULTI_SPACE_FACTOR_MAX;
textContentItem.fakeMultiSpaceMax = spaceWidth * MULTI_SPACE_FACTOR_MAX;
// It's okay for monospace fonts to fake as much space as needed.
textContentItem.textRunBreakAllowed = !font.isMonospace;
} else {
@ -2143,10 +2135,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
advance.value > 0 &&
advance.value <= textContentItem.fakeMultiSpaceMax
) {
textState.translateTextLineMatrix(
advance.width,
advance.height
);
textState.translateTextLineMatrix(advance.width, advance.height);
textContentItem.width +=
advance.width - textContentItem.lastAdvanceWidth;
textContentItem.height +=
@ -2282,9 +2271,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
next(
new Promise(function (resolveXObject, rejectXObject) {
if (!name) {
throw new FormatError(
"XObject must be referred to by name."
);
throw new FormatError("XObject must be referred to by name.");
}
let xobj = xobjs.getRaw(name);
@ -2432,13 +2419,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
throw reason;
});
},
}
extractDataStructures: function PartialEvaluator_extractDataStructures(
dict,
baseDict,
properties
) {
extractDataStructures(dict, baseDict, properties) {
const xref = this.xref;
let cidToGidBytes;
// 9.10.2
@ -2559,7 +2542,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
return properties;
});
},
}
/**
* @returns {ToUnicodeMap}
@ -2660,7 +2643,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
toUnicode[charcode] = String.fromCharCode(glyphsUnicodeMap[glyphName]);
}
return new ToUnicodeMap(toUnicode);
},
}
/**
* Builds a char code to unicode map based on section 9.10 of the spec.
@ -2751,9 +2734,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
return Promise.resolve(
new IdentityToUnicodeMap(properties.firstChar, properties.lastChar)
);
},
}
readToUnicode: function PartialEvaluator_readToUnicode(toUnicode) {
readToUnicode(toUnicode) {
var cmapObj = toUnicode;
if (isName(cmapObj)) {
return CMapFactory.create({
@ -2815,7 +2798,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
);
}
return Promise.resolve(null);
},
}
readCidToGidMap(glyphsData, toUnicode) {
// Extract the encoding from the CIDToGIDMap
@ -2831,13 +2814,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
result[code] = glyphID;
}
return result;
},
}
extractWidths: function PartialEvaluator_extractWidths(
dict,
descriptor,
properties
) {
extractWidths(dict, descriptor, properties) {
var xref = this.xref;
var glyphsWidths = [];
var defaultWidth = 0;
@ -2909,10 +2888,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
if (isName(baseFontName)) {
var metrics = this.getBaseFontMetrics(baseFontName.name);
glyphsWidths = this.buildCharCodeToWidth(
metrics.widths,
properties
);
glyphsWidths = this.buildCharCodeToWidth(metrics.widths, properties);
defaultWidth = metrics.defaultWidth;
}
}
@ -2943,18 +2919,18 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
properties.widths = glyphsWidths;
properties.defaultVMetrics = defaultVMetrics;
properties.vmetrics = glyphsVMetrics;
},
}
isSerifFont: function PartialEvaluator_isSerifFont(baseFontName) {
isSerifFont(baseFontName) {
// Simulating descriptor flags attribute
var fontNameWoStyle = baseFontName.split("-")[0];
return (
fontNameWoStyle in getSerifFonts() ||
fontNameWoStyle.search(/serif/gi) !== -1
);
},
}
getBaseFontMetrics: function PartialEvaluator_getBaseFontMetrics(name) {
getBaseFontMetrics(name) {
var defaultWidth = 0;
var widths = [];
var monospace = false;
@ -2985,20 +2961,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
monospace,
widths,
};
},
}
buildCharCodeToWidth: function PartialEvaluator_bulildCharCodeToWidth(
widthsByGlyphName,
properties
) {
buildCharCodeToWidth(widthsByGlyphName, properties) {
var widths = Object.create(null);
var differences = properties.differences;
var encoding = properties.defaultEncoding;
for (var charCode = 0; charCode < 256; charCode++) {
if (
charCode in differences &&
widthsByGlyphName[differences[charCode]]
) {
if (charCode in differences && widthsByGlyphName[differences[charCode]]) {
widths[charCode] = widthsByGlyphName[differences[charCode]];
continue;
}
@ -3008,9 +2978,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
}
return widths;
},
}
preEvaluateFont: function PartialEvaluator_preEvaluateFont(dict) {
preEvaluateFont(dict) {
var baseDict = dict;
var type = dict.get("Subtype");
if (!isName(type)) {
@ -3105,9 +3075,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
type: type.name,
hash: hash ? hash.hexdigest() : "",
};
},
}
translateFont: function PartialEvaluator_translateFont(preEvaluatedFont) {
translateFont(preEvaluatedFont) {
var baseDict = preEvaluatedFont.baseDict;
var dict = preEvaluatedFont.dict;
var composite = preEvaluatedFont.composite;
@ -3204,11 +3174,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
);
// Workaround for cases where e.g. fontNameStr = 'Arial' and
// baseFontStr = 'Arial,Bold' (needed when no font file is embedded).
if (
fontNameStr &&
baseFontStr &&
baseFontStr.startsWith(fontNameStr)
) {
if (fontNameStr && baseFontStr && baseFontStr.startsWith(fontNameStr)) {
fontName = baseFont;
}
}
@ -3286,10 +3252,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
return new Font(fontName.name, fontFile, newProperties);
});
},
};
}
PartialEvaluator.buildFontPaths = function (font, glyphs, handler) {
static buildFontPaths(font, glyphs, handler) {
function buildPath(fontChar) {
if (font.renderer.hasBuiltPath(fontChar)) {
return;
@ -3311,25 +3276,18 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
buildPath(accent.fontChar);
}
}
};
// TODO: Change this to a `static` getter, using shadowing, once
// `PartialEvaluator` is converted to a proper class.
PartialEvaluator.getFallbackFontDict = function () {
if (this._fallbackFontDict) {
return this._fallbackFontDict;
}
static get fallbackFontDict() {
const dict = new Dict();
dict.set("BaseFont", Name.get("PDFJS-FallbackFont"));
dict.set("Type", Name.get("FallbackType"));
dict.set("Subtype", Name.get("FallbackType"));
dict.set("Encoding", Name.get("WinAnsiEncoding"));
return (this._fallbackFontDict = dict);
};
return PartialEvaluator;
})();
return shadow(this, "fallbackFontDict", dict);
}
}
class TranslatedFont {
constructor({ loadedName, font, dict, extraProperties = false }) {
@ -3430,34 +3388,32 @@ class TranslatedFont {
}
}
var StateManager = (function StateManagerClosure() {
// eslint-disable-next-line no-shadow
function StateManager(initialState) {
class StateManager {
constructor(initialState) {
this.state = initialState;
this.stateStack = [];
}
StateManager.prototype = {
save() {
var old = this.state;
this.stateStack.push(this.state);
this.state = old.clone();
},
}
restore() {
var prev = this.stateStack.pop();
if (prev) {
this.state = prev;
}
},
}
transform(args) {
this.state.ctm = Util.transform(this.state.ctm, args);
},
};
return StateManager;
})();
}
}
var TextState = (function TextStateClosure() {
// eslint-disable-next-line no-shadow
function TextState() {
class TextState {
constructor() {
this.ctm = new Float32Array(IDENTITY_MATRIX);
this.fontName = null;
this.fontSize = 0;
@ -3472,8 +3428,7 @@ var TextState = (function TextStateClosure() {
this.textRise = 0;
}
TextState.prototype = {
setTextMatrix: function TextState_setTextMatrix(a, b, c, d, e, f) {
setTextMatrix(a, b, c, d, e, f) {
var m = this.textMatrix;
m[0] = a;
m[1] = b;
@ -3481,8 +3436,9 @@ var TextState = (function TextStateClosure() {
m[3] = d;
m[4] = e;
m[5] = f;
},
setTextLineMatrix: function TextState_setTextMatrix(a, b, c, d, e, f) {
}
setTextLineMatrix(a, b, c, d, e, f) {
var m = this.textLineMatrix;
m[0] = a;
m[1] = b;
@ -3490,25 +3446,21 @@ var TextState = (function TextStateClosure() {
m[3] = d;
m[4] = e;
m[5] = f;
},
translateTextMatrix: function TextState_translateTextMatrix(x, y) {
}
translateTextMatrix(x, y) {
var m = this.textMatrix;
m[4] = m[0] * x + m[2] * y + m[4];
m[5] = m[1] * x + m[3] * y + m[5];
},
translateTextLineMatrix: function TextState_translateTextMatrix(x, y) {
}
translateTextLineMatrix(x, y) {
var m = this.textLineMatrix;
m[4] = m[0] * x + m[2] * y + m[4];
m[5] = m[1] * x + m[3] * y + m[5];
},
calcTextLineMatrixAdvance: function TextState_calcTextLineMatrixAdvance(
a,
b,
c,
d,
e,
f
) {
}
calcTextLineMatrixAdvance(a, b, c, d, e, f) {
var font = this.font;
if (!font) {
return null;
@ -3533,8 +3485,9 @@ var TextState = (function TextStateClosure() {
ty = (-txDiff * b) / denominator;
}
return { width: tx, height: ty, value: font.vertical ? ty : tx };
},
calcRenderMatrix: function TextState_calcRendeMatrix(ctm) {
}
calcRenderMatrix(ctm) {
// 9.4.4 Text Space Details
var tsm = [
this.fontSize * this.textHScale,
@ -3545,45 +3498,43 @@ var TextState = (function TextStateClosure() {
this.textRise,
];
return Util.transform(ctm, Util.transform(this.textMatrix, tsm));
},
carriageReturn: function TextState_carriageReturn() {
}
carriageReturn() {
this.translateTextLineMatrix(0, -this.leading);
this.textMatrix = this.textLineMatrix.slice();
},
clone: function TextState_clone() {
}
clone() {
var clone = Object.create(this);
clone.textMatrix = this.textMatrix.slice();
clone.textLineMatrix = this.textLineMatrix.slice();
clone.fontMatrix = this.fontMatrix.slice();
return clone;
},
};
return TextState;
})();
}
}
var EvalState = (function EvalStateClosure() {
// eslint-disable-next-line no-shadow
function EvalState() {
class EvalState {
constructor() {
this.ctm = new Float32Array(IDENTITY_MATRIX);
this.font = null;
this.textRenderingMode = TextRenderingMode.FILL;
this.fillColorSpace = ColorSpace.singletons.gray;
this.strokeColorSpace = ColorSpace.singletons.gray;
}
EvalState.prototype = {
clone: function CanvasExtraState_clone() {
return Object.create(this);
},
};
return EvalState;
})();
var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
clone() {
return Object.create(this);
}
}
class EvaluatorPreprocessor {
static get opMap() {
// Specifies properties for each command
//
// If variableArgs === true: [0, `numArgs`] expected
// If variableArgs === false: exactly `numArgs` expected
var getOPMap = getLookupTableFactory(function (t) {
const getOPMap = getLookupTableFactory(function (t) {
// Graphic state
t.w = { id: OPS.setLineWidth, numArgs: 1, variableArgs: false };
t.J = { id: OPS.setLineCap, numArgs: 1, variableArgs: false };
@ -3702,15 +3653,18 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
t.null = null;
});
const MAX_INVALID_PATH_OPS = 20;
return shadow(this, "opMap", getOPMap());
}
// eslint-disable-next-line no-shadow
function EvaluatorPreprocessor(stream, xref, stateManager) {
this.opMap = getOPMap();
static get MAX_INVALID_PATH_OPS() {
return shadow(this, "MAX_INVALID_PATH_OPS", 20);
}
constructor(stream, xref, stateManager) {
// TODO(mduan): pass array of knownCommands rather than this.opMap
// dictionary
this.parser = new Parser({
lexer: new Lexer(stream, this.opMap),
lexer: new Lexer(stream, EvaluatorPreprocessor.opMap),
xref,
});
this.stateManager = stateManager;
@ -3718,10 +3672,9 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
this._numInvalidPathOPS = 0;
}
EvaluatorPreprocessor.prototype = {
get savedStatesDepth() {
return this.stateManager.stateStack.length;
},
}
// |operation| is an object with two fields:
//
@ -3744,14 +3697,14 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
// These two modes are present because this function is very hot and so
// avoiding allocations where possible is worthwhile.
//
read: function EvaluatorPreprocessor_read(operation) {
read(operation) {
var args = operation.args;
while (true) {
var obj = this.parser.getObj();
if (obj instanceof Cmd) {
var cmd = obj.cmd;
// Check that the command is valid
var opSpec = this.opMap[cmd];
var opSpec = EvaluatorPreprocessor.opMap[cmd];
if (!opSpec) {
warn(`Unknown command "${cmd}".`);
continue;
@ -3790,7 +3743,8 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
if (
fn >= OPS.moveTo &&
fn <= OPS.endPath && // Path operator
++this._numInvalidPathOPS > MAX_INVALID_PATH_OPS
++this._numInvalidPathOPS >
EvaluatorPreprocessor.MAX_INVALID_PATH_OPS
) {
throw new FormatError(`Invalid ${partialMsg}`);
}
@ -3830,12 +3784,9 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
}
}
}
},
}
preprocessCommand: function EvaluatorPreprocessor_preprocessCommand(
fn,
args
) {
preprocessCommand(fn, args) {
switch (fn | 0) {
case OPS.save:
this.stateManager.save();
@ -3847,9 +3798,7 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
this.stateManager.transform(args);
break;
}
},
};
return EvaluatorPreprocessor;
})();
}
}
export { PartialEvaluator };