Merge pull request #12060 from Snuffleupagus/evaluator-class

Convert the code in `src/core/evaluator.js` to use standard classes
This commit is contained in:
Tim van der Meij 2020-07-06 23:50:36 +02:00 committed by GitHub
commit cf8daaf78b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -85,58 +85,20 @@ import { MurmurHash3_64 } from "./murmurhash3.js";
import { OperatorList } from "./operator_list.js"; import { OperatorList } from "./operator_list.js";
import { PDFImage } from "./image.js"; import { PDFImage } from "./image.js";
var PartialEvaluator = (function PartialEvaluatorClosure() { const DefaultPartialEvaluatorOptions = Object.freeze({
const DefaultPartialEvaluatorOptions = {
maxImageSize: -1, maxImageSize: -1,
disableFontFace: false, disableFontFace: false,
ignoreErrors: false, ignoreErrors: false,
isEvalSupported: true, isEvalSupported: true,
fontExtraProperties: false, fontExtraProperties: false,
});
const PatternType = {
TILING: 1,
SHADING: 2,
}; };
// eslint-disable-next-line no-shadow const deferred = Promise.resolve();
function PartialEvaluator({
xref,
handler,
pageIndex,
idFactory,
fontCache,
builtInCMapCache,
globalImageCache,
options = null,
}) {
this.xref = xref;
this.handler = handler;
this.pageIndex = pageIndex;
this.idFactory = idFactory;
this.fontCache = fontCache;
this.builtInCMapCache = builtInCMapCache;
this.globalImageCache = globalImageCache;
this.options = options || DefaultPartialEvaluatorOptions;
this.parsingType3Font = false;
this._fetchBuiltInCMapBound = this.fetchBuiltInCMap.bind(this);
}
// Trying to minimize Date.now() usage and check every 100 time
var TIME_SLOT_DURATION_MS = 20;
var CHECK_TIME_EVERY = 100;
function TimeSlotManager() {
this.reset();
}
TimeSlotManager.prototype = {
check: function TimeSlotManager_check() {
if (++this.checked < 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;
},
};
// Convert PDF blend mode names to HTML5 blend mode names. // Convert PDF blend mode names to HTML5 blend mode names.
function normalizeBlendMode(value, parsingArray = false) { function normalizeBlendMode(value, parsingArray = false) {
@ -200,12 +162,58 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
return "source-over"; return "source-over";
} }
var deferred = Promise.resolve(); // Trying to minimize Date.now() usage and check every 100 time.
class TimeSlotManager {
static get TIME_SLOT_DURATION_MS() {
return shadow(this, "TIME_SLOT_DURATION_MS", 20);
}
var TILING_PATTERN = 1, static get CHECK_TIME_EVERY() {
SHADING_PATTERN = 2; return shadow(this, "CHECK_TIME_EVERY", 100);
}
constructor() {
this.reset();
}
check() {
if (++this.checked < TimeSlotManager.CHECK_TIME_EVERY) {
return false;
}
this.checked = 0;
return this.endTime <= Date.now();
}
reset() {
this.endTime = Date.now() + TimeSlotManager.TIME_SLOT_DURATION_MS;
this.checked = 0;
}
}
class PartialEvaluator {
constructor({
xref,
handler,
pageIndex,
idFactory,
fontCache,
builtInCMapCache,
globalImageCache,
options = null,
}) {
this.xref = xref;
this.handler = handler;
this.pageIndex = pageIndex;
this.idFactory = idFactory;
this.fontCache = fontCache;
this.builtInCMapCache = builtInCMapCache;
this.globalImageCache = globalImageCache;
this.options = options || DefaultPartialEvaluatorOptions;
this.parsingType3Font = false;
this._fetchBuiltInCMapBound = this.fetchBuiltInCMap.bind(this);
}
PartialEvaluator.prototype = {
/** /**
* Since Functions are only cached (locally) by reference, we can share one * Since Functions are only cached (locally) by reference, we can share one
* `PDFFunctionFactory` instance within this `PartialEvaluator` instance. * `PDFFunctionFactory` instance within this `PartialEvaluator` instance.
@ -216,15 +224,15 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
isEvalSupported: this.options.isEvalSupported, isEvalSupported: this.options.isEvalSupported,
}); });
return shadow(this, "_pdfFunctionFactory", pdfFunctionFactory); return shadow(this, "_pdfFunctionFactory", pdfFunctionFactory);
}, }
clone(newOptions = DefaultPartialEvaluatorOptions) { clone(newOptions = DefaultPartialEvaluatorOptions) {
var newEvaluator = Object.create(this); var newEvaluator = Object.create(this);
newEvaluator.options = newOptions; newEvaluator.options = newOptions;
return newEvaluator; return newEvaluator;
}, }
hasBlendModes: function PartialEvaluator_hasBlendModes(resources) { hasBlendModes(resources) {
if (!(resources instanceof Dict)) { if (!(resources instanceof Dict)) {
return false; return false;
} }
@ -357,7 +365,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
} }
return false; return false;
}, }
async fetchBuiltInCMap(name) { async fetchBuiltInCMap(name) {
const cachedData = this.builtInCMapCache.get(name); const cachedData = this.builtInCMapCache.get(name);
@ -387,7 +395,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
this.builtInCMapCache.set(name, data); this.builtInCMapCache.set(name, data);
} }
return data; return data;
}, }
async buildFormXObject( async buildFormXObject(
resources, resources,
@ -464,7 +472,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
operatorList.addOp(OPS.endGroup, [groupOptions]); operatorList.addOp(OPS.endGroup, [groupOptions]);
} }
}); });
}, }
_sendImgData(objId, imgData, cacheGlobally = false) { _sendImgData(objId, imgData, cacheGlobally = false) {
const transfers = imgData ? [imgData.data.buffer] : null; const transfers = imgData ? [imgData.data.buffer] : null;
@ -488,7 +496,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
[objId, this.pageIndex, "Image", imgData], [objId, this.pageIndex, "Image", imgData],
transfers transfers
); );
}, }
async buildPaintImageXObject({ async buildPaintImageXObject({
resources, resources,
@ -642,9 +650,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
} }
return undefined; return undefined;
}, }
handleSMask: function PartialEvaluator_handleSmask( handleSMask(
smask, smask,
resources, resources,
operatorList, operatorList,
@ -682,7 +690,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
stateManager.state.clone(), stateManager.state.clone(),
localColorSpaceCache localColorSpaceCache
); );
}, }
handleTilingType( handleTilingType(
fn, fn,
@ -739,16 +747,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
throw reason; throw reason;
} }
); );
}, }
handleSetFont: function PartialEvaluator_handleSetFont( handleSetFont(resources, fontArgs, fontRef, operatorList, task, state) {
resources,
fontArgs,
fontRef,
operatorList,
task,
state
) {
// TODO(mack): Not needed? // TODO(mack): Not needed?
var fontName; var fontName;
if (fontArgs) { if (fontArgs) {
@ -785,7 +786,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
translated.send(this.handler); translated.send(this.handler);
return translated.loadedName; return translated.loadedName;
}); });
}, }
handleText(chars, state) { handleText(chars, state) {
const font = state.font; const font = state.font;
@ -805,7 +806,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
} }
return glyphs; return glyphs;
}, }
ensureStateFont(state) { ensureStateFont(state) {
if (state.font) { if (state.font) {
@ -825,9 +826,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
return; return;
} }
throw reason; throw reason;
}, }
setGState: function PartialEvaluator_setGState( setGState(
resources, resources,
gState, gState,
operatorList, operatorList,
@ -925,9 +926,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
operatorList.addOp(OPS.setGState, [gStateObj]); operatorList.addOp(OPS.setGState, [gStateObj]);
} }
}); });
}, }
loadFont: function PartialEvaluator_loadFont(fontName, font, resources) { loadFont(fontName, font, resources) {
const errorFont = () => { const errorFont = () => {
return Promise.resolve( return Promise.resolve(
new TranslatedFont({ new TranslatedFont({
@ -971,7 +972,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
// Falling back to a default font to avoid completely broken rendering, // Falling back to a default font to avoid completely broken rendering,
// but note that there're no guarantees that things will look "correct". // but note that there're no guarantees that things will look "correct".
fontRef = PartialEvaluator.getFallbackFontDict(); fontRef = PartialEvaluator.fallbackFontDict;
} }
if (this.fontCache.has(fontRef)) { if (this.fontCache.has(fontRef)) {
@ -1008,11 +1009,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
if (fontAliases[hash]) { if (fontAliases[hash]) {
var aliasFontRef = fontAliases[hash].aliasRef; var aliasFontRef = fontAliases[hash].aliasRef;
if ( if (fontRefIsRef && aliasFontRef && this.fontCache.has(aliasFontRef)) {
fontRefIsRef &&
aliasFontRef &&
this.fontCache.has(aliasFontRef)
) {
this.fontCache.putAlias(fontRef, aliasFontRef); this.fontCache.putAlias(fontRef, aliasFontRef);
return this.fontCache.get(fontRef); return this.fontCache.get(fontRef);
} }
@ -1116,7 +1113,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
); );
}); });
return fontCapability.promise; return fontCapability.promise;
}, }
buildPath(operatorList, fn, args, parsingText = false) { buildPath(operatorList, fn, args, parsingText = false) {
var lastIndex = operatorList.length - 1; var lastIndex = operatorList.length - 1;
@ -1149,7 +1146,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
opArgs[0].push(fn); opArgs[0].push(fn);
Array.prototype.push.apply(opArgs[1], args); Array.prototype.push.apply(opArgs[1], args);
} }
}, }
parseColorSpace({ cs, resources, localColorSpaceCache }) { parseColorSpace({ cs, resources, localColorSpaceCache }) {
return ColorSpace.parseAsync({ return ColorSpace.parseAsync({
@ -1173,7 +1170,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
throw reason; throw reason;
}); });
}, }
async handleColorN( async handleColorN(
operatorList, operatorList,
@ -1193,7 +1190,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var dict = isStream(pattern) ? pattern.dict : pattern; var dict = isStream(pattern) ? pattern.dict : pattern;
var typeNum = dict.get("PatternType"); var typeNum = dict.get("PatternType");
if (typeNum === TILING_PATTERN) { if (typeNum === PatternType.TILING) {
var color = cs.base ? cs.base.getRgb(args, 0) : null; var color = cs.base ? cs.base.getRgb(args, 0) : null;
return this.handleTilingType( return this.handleTilingType(
fn, fn,
@ -1204,7 +1201,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
operatorList, operatorList,
task task
); );
} else if (typeNum === SHADING_PATTERN) { } else if (typeNum === PatternType.SHADING) {
var shading = dict.get("Shading"); var shading = dict.get("Shading");
var matrix = dict.getArray("Matrix"); var matrix = dict.getArray("Matrix");
pattern = Pattern.parseShading( pattern = Pattern.parseShading(
@ -1222,7 +1219,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
throw new FormatError(`Unknown PatternType: ${typeNum}`); throw new FormatError(`Unknown PatternType: ${typeNum}`);
} }
throw new FormatError(`Unknown PatternName: ${patternName}`); throw new FormatError(`Unknown PatternName: ${patternName}`);
}, }
getOperatorList({ getOperatorList({
stream, stream,
@ -1303,9 +1300,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
next( next(
new Promise(function (resolveXObject, rejectXObject) { new Promise(function (resolveXObject, rejectXObject) {
if (!name) { if (!name) {
throw new FormatError( throw new FormatError("XObject must be referred to by name.");
"XObject must be referred to by name."
);
} }
let xobj = xobjs.getRaw(name); let xobj = xobjs.getRaw(name);
@ -1748,7 +1743,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
throw reason; throw reason;
}); });
}, }
getTextContent({ getTextContent({
stream, stream,
@ -1870,8 +1865,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
textContentItem.spaceWidth = spaceWidth; textContentItem.spaceWidth = spaceWidth;
textContentItem.fakeSpaceMin = spaceWidth * SPACE_FACTOR; textContentItem.fakeSpaceMin = spaceWidth * SPACE_FACTOR;
textContentItem.fakeMultiSpaceMin = spaceWidth * MULTI_SPACE_FACTOR; textContentItem.fakeMultiSpaceMin = spaceWidth * MULTI_SPACE_FACTOR;
textContentItem.fakeMultiSpaceMax = textContentItem.fakeMultiSpaceMax = spaceWidth * MULTI_SPACE_FACTOR_MAX;
spaceWidth * MULTI_SPACE_FACTOR_MAX;
// It's okay for monospace fonts to fake as much space as needed. // It's okay for monospace fonts to fake as much space as needed.
textContentItem.textRunBreakAllowed = !font.isMonospace; textContentItem.textRunBreakAllowed = !font.isMonospace;
} else { } else {
@ -2141,10 +2135,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
advance.value > 0 && advance.value > 0 &&
advance.value <= textContentItem.fakeMultiSpaceMax advance.value <= textContentItem.fakeMultiSpaceMax
) { ) {
textState.translateTextLineMatrix( textState.translateTextLineMatrix(advance.width, advance.height);
advance.width,
advance.height
);
textContentItem.width += textContentItem.width +=
advance.width - textContentItem.lastAdvanceWidth; advance.width - textContentItem.lastAdvanceWidth;
textContentItem.height += textContentItem.height +=
@ -2280,9 +2271,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
next( next(
new Promise(function (resolveXObject, rejectXObject) { new Promise(function (resolveXObject, rejectXObject) {
if (!name) { if (!name) {
throw new FormatError( throw new FormatError("XObject must be referred to by name.");
"XObject must be referred to by name."
);
} }
let xobj = xobjs.getRaw(name); let xobj = xobjs.getRaw(name);
@ -2430,13 +2419,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
throw reason; throw reason;
}); });
}, }
extractDataStructures: function PartialEvaluator_extractDataStructures( extractDataStructures(dict, baseDict, properties) {
dict,
baseDict,
properties
) {
const xref = this.xref; const xref = this.xref;
let cidToGidBytes; let cidToGidBytes;
// 9.10.2 // 9.10.2
@ -2557,7 +2542,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
return properties; return properties;
}); });
}, }
/** /**
* @returns {ToUnicodeMap} * @returns {ToUnicodeMap}
@ -2658,7 +2643,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
toUnicode[charcode] = String.fromCharCode(glyphsUnicodeMap[glyphName]); toUnicode[charcode] = String.fromCharCode(glyphsUnicodeMap[glyphName]);
} }
return new ToUnicodeMap(toUnicode); return new ToUnicodeMap(toUnicode);
}, }
/** /**
* Builds a char code to unicode map based on section 9.10 of the spec. * Builds a char code to unicode map based on section 9.10 of the spec.
@ -2749,9 +2734,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
return Promise.resolve( return Promise.resolve(
new IdentityToUnicodeMap(properties.firstChar, properties.lastChar) new IdentityToUnicodeMap(properties.firstChar, properties.lastChar)
); );
}, }
readToUnicode: function PartialEvaluator_readToUnicode(toUnicode) { readToUnicode(toUnicode) {
var cmapObj = toUnicode; var cmapObj = toUnicode;
if (isName(cmapObj)) { if (isName(cmapObj)) {
return CMapFactory.create({ return CMapFactory.create({
@ -2813,7 +2798,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
); );
} }
return Promise.resolve(null); return Promise.resolve(null);
}, }
readCidToGidMap(glyphsData, toUnicode) { readCidToGidMap(glyphsData, toUnicode) {
// Extract the encoding from the CIDToGIDMap // Extract the encoding from the CIDToGIDMap
@ -2829,13 +2814,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
result[code] = glyphID; result[code] = glyphID;
} }
return result; return result;
}, }
extractWidths: function PartialEvaluator_extractWidths( extractWidths(dict, descriptor, properties) {
dict,
descriptor,
properties
) {
var xref = this.xref; var xref = this.xref;
var glyphsWidths = []; var glyphsWidths = [];
var defaultWidth = 0; var defaultWidth = 0;
@ -2907,10 +2888,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
if (isName(baseFontName)) { if (isName(baseFontName)) {
var metrics = this.getBaseFontMetrics(baseFontName.name); var metrics = this.getBaseFontMetrics(baseFontName.name);
glyphsWidths = this.buildCharCodeToWidth( glyphsWidths = this.buildCharCodeToWidth(metrics.widths, properties);
metrics.widths,
properties
);
defaultWidth = metrics.defaultWidth; defaultWidth = metrics.defaultWidth;
} }
} }
@ -2941,18 +2919,18 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
properties.widths = glyphsWidths; properties.widths = glyphsWidths;
properties.defaultVMetrics = defaultVMetrics; properties.defaultVMetrics = defaultVMetrics;
properties.vmetrics = glyphsVMetrics; properties.vmetrics = glyphsVMetrics;
}, }
isSerifFont: function PartialEvaluator_isSerifFont(baseFontName) { isSerifFont(baseFontName) {
// Simulating descriptor flags attribute // Simulating descriptor flags attribute
var fontNameWoStyle = baseFontName.split("-")[0]; var fontNameWoStyle = baseFontName.split("-")[0];
return ( return (
fontNameWoStyle in getSerifFonts() || fontNameWoStyle in getSerifFonts() ||
fontNameWoStyle.search(/serif/gi) !== -1 fontNameWoStyle.search(/serif/gi) !== -1
); );
}, }
getBaseFontMetrics: function PartialEvaluator_getBaseFontMetrics(name) { getBaseFontMetrics(name) {
var defaultWidth = 0; var defaultWidth = 0;
var widths = []; var widths = [];
var monospace = false; var monospace = false;
@ -2983,20 +2961,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
monospace, monospace,
widths, widths,
}; };
}, }
buildCharCodeToWidth: function PartialEvaluator_bulildCharCodeToWidth( buildCharCodeToWidth(widthsByGlyphName, properties) {
widthsByGlyphName,
properties
) {
var widths = Object.create(null); var widths = Object.create(null);
var differences = properties.differences; var differences = properties.differences;
var encoding = properties.defaultEncoding; var encoding = properties.defaultEncoding;
for (var charCode = 0; charCode < 256; charCode++) { for (var charCode = 0; charCode < 256; charCode++) {
if ( if (charCode in differences && widthsByGlyphName[differences[charCode]]) {
charCode in differences &&
widthsByGlyphName[differences[charCode]]
) {
widths[charCode] = widthsByGlyphName[differences[charCode]]; widths[charCode] = widthsByGlyphName[differences[charCode]];
continue; continue;
} }
@ -3006,9 +2978,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
} }
return widths; return widths;
}, }
preEvaluateFont: function PartialEvaluator_preEvaluateFont(dict) { preEvaluateFont(dict) {
var baseDict = dict; var baseDict = dict;
var type = dict.get("Subtype"); var type = dict.get("Subtype");
if (!isName(type)) { if (!isName(type)) {
@ -3103,9 +3075,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
type: type.name, type: type.name,
hash: hash ? hash.hexdigest() : "", hash: hash ? hash.hexdigest() : "",
}; };
}, }
translateFont: function PartialEvaluator_translateFont(preEvaluatedFont) { translateFont(preEvaluatedFont) {
var baseDict = preEvaluatedFont.baseDict; var baseDict = preEvaluatedFont.baseDict;
var dict = preEvaluatedFont.dict; var dict = preEvaluatedFont.dict;
var composite = preEvaluatedFont.composite; var composite = preEvaluatedFont.composite;
@ -3202,11 +3174,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
); );
// Workaround for cases where e.g. fontNameStr = 'Arial' and // Workaround for cases where e.g. fontNameStr = 'Arial' and
// baseFontStr = 'Arial,Bold' (needed when no font file is embedded). // baseFontStr = 'Arial,Bold' (needed when no font file is embedded).
if ( if (fontNameStr && baseFontStr && baseFontStr.startsWith(fontNameStr)) {
fontNameStr &&
baseFontStr &&
baseFontStr.startsWith(fontNameStr)
) {
fontName = baseFont; fontName = baseFont;
} }
} }
@ -3284,10 +3252,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
return new Font(fontName.name, fontFile, newProperties); return new Font(fontName.name, fontFile, newProperties);
}); });
}, }
};
PartialEvaluator.buildFontPaths = function (font, glyphs, handler) { static buildFontPaths(font, glyphs, handler) {
function buildPath(fontChar) { function buildPath(fontChar) {
if (font.renderer.hasBuiltPath(fontChar)) { if (font.renderer.hasBuiltPath(fontChar)) {
return; return;
@ -3309,25 +3276,18 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
buildPath(accent.fontChar); 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(); const dict = new Dict();
dict.set("BaseFont", Name.get("PDFJS-FallbackFont")); dict.set("BaseFont", Name.get("PDFJS-FallbackFont"));
dict.set("Type", Name.get("FallbackType")); dict.set("Type", Name.get("FallbackType"));
dict.set("Subtype", Name.get("FallbackType")); dict.set("Subtype", Name.get("FallbackType"));
dict.set("Encoding", Name.get("WinAnsiEncoding")); dict.set("Encoding", Name.get("WinAnsiEncoding"));
return (this._fallbackFontDict = dict); return shadow(this, "fallbackFontDict", dict);
}; }
}
return PartialEvaluator;
})();
class TranslatedFont { class TranslatedFont {
constructor({ loadedName, font, dict, extraProperties = false }) { constructor({ loadedName, font, dict, extraProperties = false }) {
@ -3428,34 +3388,32 @@ class TranslatedFont {
} }
} }
var StateManager = (function StateManagerClosure() { class StateManager {
// eslint-disable-next-line no-shadow constructor(initialState) {
function StateManager(initialState) {
this.state = initialState; this.state = initialState;
this.stateStack = []; this.stateStack = [];
} }
StateManager.prototype = {
save() { save() {
var old = this.state; var old = this.state;
this.stateStack.push(this.state); this.stateStack.push(this.state);
this.state = old.clone(); this.state = old.clone();
}, }
restore() { restore() {
var prev = this.stateStack.pop(); var prev = this.stateStack.pop();
if (prev) { if (prev) {
this.state = prev; this.state = prev;
} }
}, }
transform(args) { transform(args) {
this.state.ctm = Util.transform(this.state.ctm, args); this.state.ctm = Util.transform(this.state.ctm, args);
}, }
}; }
return StateManager;
})();
var TextState = (function TextStateClosure() { class TextState {
// eslint-disable-next-line no-shadow constructor() {
function TextState() {
this.ctm = new Float32Array(IDENTITY_MATRIX); this.ctm = new Float32Array(IDENTITY_MATRIX);
this.fontName = null; this.fontName = null;
this.fontSize = 0; this.fontSize = 0;
@ -3470,8 +3428,7 @@ var TextState = (function TextStateClosure() {
this.textRise = 0; this.textRise = 0;
} }
TextState.prototype = { setTextMatrix(a, b, c, d, e, f) {
setTextMatrix: function TextState_setTextMatrix(a, b, c, d, e, f) {
var m = this.textMatrix; var m = this.textMatrix;
m[0] = a; m[0] = a;
m[1] = b; m[1] = b;
@ -3479,8 +3436,9 @@ var TextState = (function TextStateClosure() {
m[3] = d; m[3] = d;
m[4] = e; m[4] = e;
m[5] = f; m[5] = f;
}, }
setTextLineMatrix: function TextState_setTextMatrix(a, b, c, d, e, f) {
setTextLineMatrix(a, b, c, d, e, f) {
var m = this.textLineMatrix; var m = this.textLineMatrix;
m[0] = a; m[0] = a;
m[1] = b; m[1] = b;
@ -3488,25 +3446,21 @@ var TextState = (function TextStateClosure() {
m[3] = d; m[3] = d;
m[4] = e; m[4] = e;
m[5] = f; m[5] = f;
}, }
translateTextMatrix: function TextState_translateTextMatrix(x, y) {
translateTextMatrix(x, y) {
var m = this.textMatrix; var m = this.textMatrix;
m[4] = m[0] * x + m[2] * y + m[4]; m[4] = m[0] * x + m[2] * y + m[4];
m[5] = m[1] * x + m[3] * y + m[5]; m[5] = m[1] * x + m[3] * y + m[5];
}, }
translateTextLineMatrix: function TextState_translateTextMatrix(x, y) {
translateTextLineMatrix(x, y) {
var m = this.textLineMatrix; var m = this.textLineMatrix;
m[4] = m[0] * x + m[2] * y + m[4]; m[4] = m[0] * x + m[2] * y + m[4];
m[5] = m[1] * x + m[3] * y + m[5]; m[5] = m[1] * x + m[3] * y + m[5];
}, }
calcTextLineMatrixAdvance: function TextState_calcTextLineMatrixAdvance(
a, calcTextLineMatrixAdvance(a, b, c, d, e, f) {
b,
c,
d,
e,
f
) {
var font = this.font; var font = this.font;
if (!font) { if (!font) {
return null; return null;
@ -3531,8 +3485,9 @@ var TextState = (function TextStateClosure() {
ty = (-txDiff * b) / denominator; ty = (-txDiff * b) / denominator;
} }
return { width: tx, height: ty, value: font.vertical ? ty : tx }; return { width: tx, height: ty, value: font.vertical ? ty : tx };
}, }
calcRenderMatrix: function TextState_calcRendeMatrix(ctm) {
calcRenderMatrix(ctm) {
// 9.4.4 Text Space Details // 9.4.4 Text Space Details
var tsm = [ var tsm = [
this.fontSize * this.textHScale, this.fontSize * this.textHScale,
@ -3543,45 +3498,43 @@ var TextState = (function TextStateClosure() {
this.textRise, this.textRise,
]; ];
return Util.transform(ctm, Util.transform(this.textMatrix, tsm)); return Util.transform(ctm, Util.transform(this.textMatrix, tsm));
}, }
carriageReturn: function TextState_carriageReturn() {
carriageReturn() {
this.translateTextLineMatrix(0, -this.leading); this.translateTextLineMatrix(0, -this.leading);
this.textMatrix = this.textLineMatrix.slice(); this.textMatrix = this.textLineMatrix.slice();
}, }
clone: function TextState_clone() {
clone() {
var clone = Object.create(this); var clone = Object.create(this);
clone.textMatrix = this.textMatrix.slice(); clone.textMatrix = this.textMatrix.slice();
clone.textLineMatrix = this.textLineMatrix.slice(); clone.textLineMatrix = this.textLineMatrix.slice();
clone.fontMatrix = this.fontMatrix.slice(); clone.fontMatrix = this.fontMatrix.slice();
return clone; return clone;
}, }
}; }
return TextState;
})();
var EvalState = (function EvalStateClosure() { class EvalState {
// eslint-disable-next-line no-shadow constructor() {
function EvalState() {
this.ctm = new Float32Array(IDENTITY_MATRIX); this.ctm = new Float32Array(IDENTITY_MATRIX);
this.font = null; this.font = null;
this.textRenderingMode = TextRenderingMode.FILL; this.textRenderingMode = TextRenderingMode.FILL;
this.fillColorSpace = ColorSpace.singletons.gray; this.fillColorSpace = ColorSpace.singletons.gray;
this.strokeColorSpace = 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 // Specifies properties for each command
// //
// If variableArgs === true: [0, `numArgs`] expected // If variableArgs === true: [0, `numArgs`] expected
// If variableArgs === false: exactly `numArgs` expected // If variableArgs === false: exactly `numArgs` expected
var getOPMap = getLookupTableFactory(function (t) { const getOPMap = getLookupTableFactory(function (t) {
// Graphic state // Graphic state
t.w = { id: OPS.setLineWidth, numArgs: 1, variableArgs: false }; t.w = { id: OPS.setLineWidth, numArgs: 1, variableArgs: false };
t.J = { id: OPS.setLineCap, numArgs: 1, variableArgs: false }; t.J = { id: OPS.setLineCap, numArgs: 1, variableArgs: false };
@ -3700,15 +3653,18 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
t.null = null; t.null = null;
}); });
const MAX_INVALID_PATH_OPS = 20; return shadow(this, "opMap", getOPMap());
}
// eslint-disable-next-line no-shadow static get MAX_INVALID_PATH_OPS() {
function EvaluatorPreprocessor(stream, xref, stateManager) { return shadow(this, "MAX_INVALID_PATH_OPS", 20);
this.opMap = getOPMap(); }
constructor(stream, xref, stateManager) {
// TODO(mduan): pass array of knownCommands rather than this.opMap // TODO(mduan): pass array of knownCommands rather than this.opMap
// dictionary // dictionary
this.parser = new Parser({ this.parser = new Parser({
lexer: new Lexer(stream, this.opMap), lexer: new Lexer(stream, EvaluatorPreprocessor.opMap),
xref, xref,
}); });
this.stateManager = stateManager; this.stateManager = stateManager;
@ -3716,10 +3672,9 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
this._numInvalidPathOPS = 0; this._numInvalidPathOPS = 0;
} }
EvaluatorPreprocessor.prototype = {
get savedStatesDepth() { get savedStatesDepth() {
return this.stateManager.stateStack.length; return this.stateManager.stateStack.length;
}, }
// |operation| is an object with two fields: // |operation| is an object with two fields:
// //
@ -3742,14 +3697,14 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
// These two modes are present because this function is very hot and so // These two modes are present because this function is very hot and so
// avoiding allocations where possible is worthwhile. // avoiding allocations where possible is worthwhile.
// //
read: function EvaluatorPreprocessor_read(operation) { read(operation) {
var args = operation.args; var args = operation.args;
while (true) { while (true) {
var obj = this.parser.getObj(); var obj = this.parser.getObj();
if (obj instanceof Cmd) { if (obj instanceof Cmd) {
var cmd = obj.cmd; var cmd = obj.cmd;
// Check that the command is valid // Check that the command is valid
var opSpec = this.opMap[cmd]; var opSpec = EvaluatorPreprocessor.opMap[cmd];
if (!opSpec) { if (!opSpec) {
warn(`Unknown command "${cmd}".`); warn(`Unknown command "${cmd}".`);
continue; continue;
@ -3788,7 +3743,8 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
if ( if (
fn >= OPS.moveTo && fn >= OPS.moveTo &&
fn <= OPS.endPath && // Path operator fn <= OPS.endPath && // Path operator
++this._numInvalidPathOPS > MAX_INVALID_PATH_OPS ++this._numInvalidPathOPS >
EvaluatorPreprocessor.MAX_INVALID_PATH_OPS
) { ) {
throw new FormatError(`Invalid ${partialMsg}`); throw new FormatError(`Invalid ${partialMsg}`);
} }
@ -3828,12 +3784,9 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
} }
} }
} }
}, }
preprocessCommand: function EvaluatorPreprocessor_preprocessCommand( preprocessCommand(fn, args) {
fn,
args
) {
switch (fn | 0) { switch (fn | 0) {
case OPS.save: case OPS.save:
this.stateManager.save(); this.stateManager.save();
@ -3845,9 +3798,7 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
this.stateManager.transform(args); this.stateManager.transform(args);
break; break;
} }
}, }
}; }
return EvaluatorPreprocessor;
})();
export { PartialEvaluator }; export { PartialEvaluator };