diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 37880c025..ee6123591 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -576,11 +576,11 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var dict = (isStream(pattern) ? pattern.dict : pattern); var typeNum = dict.get('PatternType'); - if (typeNum == TILING_PATTERN) { + if (typeNum === TILING_PATTERN) { var color = cs.base ? cs.base.getRgb(args, 0) : null; return this.handleTilingType(fn, color, resources, pattern, dict, operatorList); - } else if (typeNum == SHADING_PATTERN) { + } else if (typeNum === SHADING_PATTERN) { var shading = dict.get('Shading'); var matrix = dict.get('Matrix'); pattern = Pattern.parseShading(shading, matrix, xref, resources); @@ -954,7 +954,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { } var glyphUnicode = glyph.unicode; - if (glyphUnicode in NormalizedUnicodes) { + if (NormalizedUnicodes[glyphUnicode] !== undefined) { glyphUnicode = NormalizedUnicodes[glyphUnicode]; } glyphUnicode = reverseIfRtl(glyphUnicode); @@ -1486,7 +1486,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var composite = false; var uint8array; - if (type.name == 'Type0') { + if (type.name === 'Type0') { // If font is a composite // - get the descendant font // - set the type according to the descendant font @@ -1552,7 +1552,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var properties; if (!descriptor) { - if (type.name == 'Type3') { + if (type.name === 'Type3') { // FontDescriptor is only required for Type3 fonts when the document // is a tagged pdf. Create a barbebones one to get by. descriptor = new Dict(null); @@ -2081,7 +2081,7 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() { } if (!isCmd(obj)) { // argument - if (obj !== null && obj !== undefined) { + if (obj !== null) { args.push((obj instanceof Dict ? obj.getAll() : obj)); assert(args.length <= 33, 'Too many arguments'); } @@ -2097,37 +2097,32 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() { } var fn = opSpec.id; + var numArgs = opSpec.numArgs; - // Some post script commands can be nested, e.g. /F2 /GS2 gs 5.711 Tf - if (!opSpec.variableArgs && args.length !== opSpec.numArgs) { - while (args.length > opSpec.numArgs) { - this.nonProcessedArgs.push(args.shift()); + if (!opSpec.variableArgs) { + // Some post script commands can be nested, e.g. /F2 /GS2 gs 5.711 Tf + if (args.length !== numArgs) { + var nonProcessedArgs = this.nonProcessedArgs; + while (args.length > numArgs) { + nonProcessedArgs.push(args.shift()); + } + while (args.length < numArgs && nonProcessedArgs.length !== 0) { + args.unshift(nonProcessedArgs.pop()); + } } - while (args.length < opSpec.numArgs && this.nonProcessedArgs.length) { - args.unshift(this.nonProcessedArgs.pop()); - } - } - - // Validate the number of arguments for the command - if (opSpec.variableArgs) { - if (args.length > opSpec.numArgs) { - info('Command ' + fn + ': expected [0,' + opSpec.numArgs + - '] args, but received ' + args.length + ' args'); - } - } else { - if (args.length < opSpec.numArgs) { + if (args.length < numArgs) { // If we receive too few args, it's not possible to possible // to execute the command, so skip the command info('Command ' + fn + ': because expected ' + - opSpec.numArgs + ' args, but received ' + args.length + + numArgs + ' args, but received ' + args.length + ' args; skipping'); args = []; continue; - } else if (args.length > opSpec.numArgs) { - info('Command ' + fn + ': expected ' + opSpec.numArgs + - ' args, but received ' + args.length + ' args'); } + } else if (args.length > numArgs) { + info('Command ' + fn + ': expected [0,' + numArgs + + '] args, but received ' + args.length + ' args'); } // TODO figure out how to type-check vararg functions @@ -2172,9 +2167,9 @@ var QueueOptimizer = (function QueueOptimizerClosure() { // have been found at index. for (var i = 0; i < count; i++) { var arg = argsArray[index + 4 * i + 2]; - var imageMask = arg.length == 1 && arg[0]; - if (imageMask && imageMask.width == 1 && imageMask.height == 1 && - (!imageMask.data.length || (imageMask.data.length == 1 && + var imageMask = arg.length === 1 && arg[0]; + if (imageMask && imageMask.width === 1 && imageMask.height === 1 && + (!imageMask.data.length || (imageMask.data.length === 1 && imageMask.data[0] === 0))) { fnArray[index + 4 * i + 2] = OPS.paintSolidColorImageMask; continue; diff --git a/src/core/parser.js b/src/core/parser.js index 3b3bd2646..e1c196166 100644 --- a/src/core/parser.js +++ b/src/core/parser.js @@ -758,19 +758,19 @@ var Lexer = (function LexerClosure() { // command var str = String.fromCharCode(ch); var knownCommands = this.knownCommands; - var knownCommandFound = knownCommands && (str in knownCommands); + var knownCommandFound = knownCommands && knownCommands[str] !== undefined; while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) { // stop if known command is found and next character does not make // the str a command var possibleCommand = str + String.fromCharCode(ch); - if (knownCommandFound && !(possibleCommand in knownCommands)) { + if (knownCommandFound && knownCommands[possibleCommand] === undefined) { break; } if (str.length === 128) { error('Command token too long: ' + str.length); } str = possibleCommand; - knownCommandFound = knownCommands && (str in knownCommands); + knownCommandFound = knownCommands && knownCommands[str] !== undefined; } if (str === 'true') { return true; diff --git a/src/display/canvas.js b/src/display/canvas.js index 22b027530..a39601142 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -394,6 +394,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { // Defines the time the executeOperatorList is going to be executing // before it stops and shedules a continue of execution. var EXECUTION_TIME = 15; + // Defines the number of steps before checking the execution time + var EXECUTION_STEPS = 10; function CanvasGraphics(canvasCtx, commonObjs, objs, imageLayer) { this.ctx = canvasCtx; @@ -599,49 +601,54 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { } } + function composeSMaskBackdrop(bytes, r0, g0, b0) { + var length = bytes.length; + for (var i = 3; i < length; i += 4) { + var alpha = bytes[i]; + if (alpha === 0) { + bytes[i - 3] = r0; + bytes[i - 2] = g0; + bytes[i - 1] = b0; + } else if (alpha < 255) { + var alpha_ = 255 - alpha; + bytes[i - 3] = (bytes[i - 3] * alpha + r0 * alpha_) >> 8; + bytes[i - 2] = (bytes[i - 2] * alpha + g0 * alpha_) >> 8; + bytes[i - 1] = (bytes[i - 1] * alpha + b0 * alpha_) >> 8; + } + } + } + + function composeSMaskAlpha(maskData, layerData) { + var length = maskData.length; + var scale = 1 / 255; + for (var i = 3; i < length; i += 4) { + var alpha = maskData[i]; + layerData[i] = (layerData[i] * alpha * scale) | 0; + } + } + + function composeSMaskLuminosity(maskData, layerData) { + var length = maskData.length; + for (var i = 3; i < length; i += 4) { + var y = ((maskData[i - 3] * 77) + // * 0.3 / 255 * 0x10000 + (maskData[i - 2] * 152) + // * 0.59 .... + (maskData[i - 1] * 28)) | 0; // * 0.11 .... + layerData[i] = (layerData[i] * y) >> 16; + } + } + function genericComposeSMask(maskCtx, layerCtx, width, height, subtype, backdrop) { - var addBackdropFn; - if (backdrop) { - addBackdropFn = function (r0, g0, b0, bytes) { - var length = bytes.length; - for (var i = 3; i < length; i += 4) { - var alpha = bytes[i] / 255; - if (alpha === 0) { - bytes[i - 3] = r0; - bytes[i - 2] = g0; - bytes[i - 1] = b0; - } else if (alpha < 1) { - var alpha_ = 1 - alpha; - bytes[i - 3] = (bytes[i - 3] * alpha + r0 * alpha_) | 0; - bytes[i - 2] = (bytes[i - 2] * alpha + g0 * alpha_) | 0; - bytes[i - 1] = (bytes[i - 1] * alpha + b0 * alpha_) | 0; - } - } - }.bind(null, backdrop[0], backdrop[1], backdrop[2]); - } else { - addBackdropFn = function () {}; - } + var hasBackdrop = backdrop !== undefined; + var r0 = hasBackdrop ? backdrop[0] : 0; + var g0 = hasBackdrop ? backdrop[1] : 0; + var b0 = hasBackdrop ? backdrop[2] : 0; var composeFn; if (subtype === 'Luminosity') { - composeFn = function (maskDataBytes, layerDataBytes) { - var length = maskDataBytes.length; - for (var i = 3; i < length; i += 4) { - var y = ((maskDataBytes[i - 3] * 77) + // * 0.3 / 255 * 0x10000 - (maskDataBytes[i - 2] * 152) + // * 0.59 .... - (maskDataBytes[i - 1] * 28)) | 0; // * 0.11 .... - layerDataBytes[i] = (layerDataBytes[i] * y) >> 16; - } - }; + composeFn = composeSMaskLuminosity; } else { - composeFn = function (maskDataBytes, layerDataBytes) { - var length = maskDataBytes.length; - for (var i = 3; i < length; i += 4) { - var alpha = maskDataBytes[i]; - layerDataBytes[i] = (layerDataBytes[i] * alpha / 255) | 0; - } - }; + composeFn = composeSMaskAlpha; } // processing image in chunks to save memory @@ -652,7 +659,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var maskData = maskCtx.getImageData(0, row, width, chunkHeight); var layerData = layerCtx.getImageData(0, row, width, chunkHeight); - addBackdropFn(maskData.data); + if (hasBackdrop) { + composeSMaskBackdrop(maskData.data, r0, g0, b0); + } composeFn(maskData.data, layerData.data); maskCtx.putImageData(layerData, 0, row); @@ -726,18 +735,21 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var argsArrayLen = argsArray.length; // Sometimes the OperatorList to execute is empty. - if (argsArrayLen == i) { + if (argsArrayLen === i) { return i; } - var endTime = Date.now() + EXECUTION_TIME; + var chunkOperations = (argsArrayLen - i > EXECUTION_STEPS && + typeof continueCallback === 'function'); + var endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0; + var steps = 0; var commonObjs = this.commonObjs; var objs = this.objs; var fnId; while (true) { - if (stepper && i === stepper.nextBreakPoint) { + if (stepper !== undefined && i === stepper.nextBreakPoint) { stepper.breakIt(i, continueCallback); return i; } @@ -750,16 +762,13 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var deps = argsArray[i]; for (var n = 0, nn = deps.length; n < nn; n++) { var depObjId = deps[n]; - var common = depObjId.substring(0, 2) == 'g_'; + var common = depObjId[0] === 'g' && depObjId[1] === '_'; + var objsPool = common ? commonObjs : objs; // If the promise isn't resolved yet, add the continueCallback // to the promise and bail out. - if (!common && !objs.isResolved(depObjId)) { - objs.get(depObjId, continueCallback); - return i; - } - if (common && !commonObjs.isResolved(depObjId)) { - commonObjs.get(depObjId, continueCallback); + if (!objsPool.isResolved(depObjId)) { + objsPool.get(depObjId, continueCallback); return i; } } @@ -768,15 +777,18 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { i++; // If the entire operatorList was executed, stop as were done. - if (i == argsArrayLen) { + if (i === argsArrayLen) { return i; } // If the execution took longer then a certain amount of time and // `continueCallback` is specified, interrupt the execution. - if (continueCallback && Date.now() > endTime) { - continueCallback(); - return i; + if (chunkOperations && ++steps > EXECUTION_STEPS) { + if (Date.now() > endTime) { + continueCallback(); + return i; + } + steps = 0; } // If the operatorList isn't executed completely yet OR the execution @@ -935,18 +947,15 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var old = this.current; this.stateStack.push(old); this.current = old.clone(); - if (this.current.activeSMask) { - this.current.activeSMask = null; - } + this.current.activeSMask = null; }, restore: function CanvasGraphics_restore() { - var prev = this.stateStack.pop(); - if (prev) { - if (this.current.activeSMask) { + if (this.stateStack.length !== 0) { + if (this.current.activeSMask !== null) { this.endSMaskGroup(); } - this.current = prev; + this.current = this.stateStack.pop(); this.ctx.restore(); } }, @@ -1502,7 +1511,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { // Color getColorN_Pattern: function CanvasGraphics_getColorN_Pattern(IR) { var pattern; - if (IR[0] == 'TilingPattern') { + if (IR[0] === 'TilingPattern') { var color = IR[1]; pattern = new TilingPattern(IR, color, this.ctx, this.objs, this.commonObjs, this.baseTransform); @@ -1578,13 +1587,13 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { this.save(); this.baseTransformStack.push(this.baseTransform); - if (matrix && isArray(matrix) && 6 == matrix.length) { + if (isArray(matrix) && 6 === matrix.length) { this.transform.apply(this, matrix); } this.baseTransform = this.ctx.mozCurrentTransform; - if (bbox && isArray(bbox) && 4 == bbox.length) { + if (isArray(bbox) && 4 === bbox.length) { var width = bbox[2] - bbox[0]; var height = bbox[3] - bbox[1]; this.rectangle(bbox[0], bbox[1], width, height); @@ -1736,7 +1745,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { matrix) { this.save(); - if (rect && isArray(rect) && 4 == rect.length) { + if (isArray(rect) && 4 === rect.length) { var width = rect[2] - rect[0]; var height = rect[3] - rect[1]; this.rectangle(rect[0], rect[1], width, height); @@ -2054,7 +2063,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { consumePath: function CanvasGraphics_consumePath() { var ctx = this.ctx; if (this.pendingClip) { - if (this.pendingClip == EO_CLIP) { + if (this.pendingClip === EO_CLIP) { if (ctx.mozFillRule !== undefined) { ctx.mozFillRule = 'evenodd'; ctx.clip(); diff --git a/src/shared/util.js b/src/shared/util.js index 3aa2164f5..ae4d85d40 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -911,15 +911,15 @@ function isBool(v) { } function isInt(v) { - return typeof v == 'number' && ((v | 0) == v); + return typeof v === 'number' && ((v | 0) === v); } function isNum(v) { - return typeof v == 'number'; + return typeof v === 'number'; } function isString(v) { - return typeof v == 'string'; + return typeof v === 'string'; } function isNull(v) { @@ -931,7 +931,7 @@ function isName(v) { } function isCmd(v, cmd) { - return v instanceof Cmd && (!cmd || v.cmd == cmd); + return v instanceof Cmd && (cmd === undefined || v.cmd === cmd); } function isDict(v, type) { @@ -942,7 +942,7 @@ function isDict(v, type) { return true; } var dictType = v.get('Type'); - return isName(dictType) && dictType.name == type; + return isName(dictType) && dictType.name === type; } function isArray(v) { @@ -950,13 +950,11 @@ function isArray(v) { } function isStream(v) { - return typeof v == 'object' && v !== null && v !== undefined && - ('getBytes' in v); + return typeof v === 'object' && v !== null && v.getBytes !== undefined; } function isArrayBuffer(v) { - return typeof v == 'object' && v !== null && v !== undefined && - ('byteLength' in v); + return typeof v === 'object' && v !== null && v.byteLength !== undefined; } function isRef(v) { @@ -1298,7 +1296,7 @@ PDFJS.createPromiseCapability = createPromiseCapability; HandlerManager.scheduleHandlers(this); return nextPromise; }, - + catch: function Promise_catch(onReject) { return this.then(undefined, onReject); }