diff --git a/Makefile b/Makefile index 80003bdf6..3484ab414 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -REPO = git@github.com:andreasgal/pdf.js.git +REPO = git@github.com:mozilla/pdf.js.git BUILD_DIR := build BUILD_TARGET := $(BUILD_DIR)/pdf.js DEFAULT_BROWSERS := resources/browser_manifests/browser_manifest.json diff --git a/README.md b/README.md index 42669da28..8414ad2a9 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ successful. For an online demo, visit: -+ http://andreasgal.github.com/pdf.js/web/viewer.html ++ http://mozilla.github.com/pdf.js/web/viewer.html This demo provides an interactive interface for displaying and browsing PDFs using the pdf.js API. @@ -31,7 +31,7 @@ using the pdf.js API. A Firefox extension is also available: -+ http://andreasgal.github.com/pdf.js/extensions/firefox/pdf.js.xpi ++ http://mozilla.github.com/pdf.js/extensions/firefox/pdf.js.xpi However, note that the extension might not reflect the latest source in our master branch. @@ -39,7 +39,7 @@ However, note that the extension might not reflect the latest source in our mast To get a local copy of the current code, clone it using git: - $ git clone git://github.com/andreasgal/pdf.js.git pdfjs + $ git clone git://github.com/mozilla/pdf.js.git pdfjs $ cd pdfjs Next, you need to start a local web server as some browsers don't allow opening @@ -73,7 +73,7 @@ Additional resources are available in a separate section below. For a "hello world" example, take a look at: -+ [examples/helloworld/hello.js](https://github.com/andreasgal/pdf.js/blob/master/examples/helloworld/hello.js) ++ [examples/helloworld/hello.js](https://github.com/mozilla/pdf.js/blob/master/examples/helloworld/hello.js) This example illustrates the bare minimum ingredients for integrating pdf.js in a custom project. @@ -92,19 +92,19 @@ workings of PDF and pdf.js: pdf.js is a community-driven project, so contributors are always welcome. Simply fork our repo and contribute away. A great place to start is our -[open issues](https://github.com/andreasgal/pdf.js/issues). For better consistency and +[open issues](https://github.com/mozilla/pdf.js/issues). For better consistency and long-term stability, please do look around the code and try to follow our conventions. More information about the contributor process can be found on the -[contributor wiki page](https://github.com/andreasgal/pdf.js/wiki/Contributing). +[contributor wiki page](https://github.com/mozilla/pdf.js/wiki/Contributing). If you don't want to hack on the project or have little spare time, __you still can help!__ Just open PDFs in the -[online demo](http://andreasgal.github.com/pdf.js/web/viewer.html) and report +[online demo](http://mozilla.github.com/pdf.js/web/viewer.html) and report any breakage in rendering. Our Github contributors so far: -+ https://github.com/andreasgal/pdf.js/contributors ++ https://github.com/mozilla/pdf.js/contributors You can add your name to it! :) @@ -143,14 +143,14 @@ against reference images before merging pull requests. See the bot repo for details: -+ https://github.com/arturadib/pdf.js-bot ++ https://github.com/mozilla/pdf.js-bot ## Additional resources Our demo site is here: -+ http://andreasgal.github.com/pdf.js/web/viewer.html ++ http://mozilla.github.com/pdf.js/web/viewer.html You can read more about pdf.js here: diff --git a/extensions/firefox/bootstrap.js b/extensions/firefox/bootstrap.js index 5384a05df..e51df28f8 100644 --- a/extensions/firefox/bootstrap.js +++ b/extensions/firefox/bootstrap.js @@ -16,21 +16,31 @@ function log(str) { function startup(aData, aReason) { let manifestPath = 'chrome.manifest'; - let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile); + let manifest = Cc['@mozilla.org/file/local;1'] + .createInstance(Ci.nsILocalFile); try { - file.initWithPath(aData.installPath.path); - file.append(manifestPath); - Cm.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(file); + manifest.initWithPath(aData.installPath.path); + manifest.append(manifestPath); + Cm.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(manifest); + Services.prefs.setBoolPref('extensions.pdf.js.active', true); } catch (e) { log(e); } } function shutdown(aData, aReason) { + if (Services.prefs.getBoolPref('extensions.pdf.js.active')) + Services.prefs.setBoolPref('extensions.pdf.js.active', false); } function install(aData, aReason) { let url = 'chrome://pdf.js/content/web/viewer.html?file=%s'; Services.prefs.setCharPref('extensions.pdf.js.url', url); + Services.prefs.setBoolPref('extensions.pdf.js.active', false); +} + +function uninstall(aData, aReason) { + Services.prefs.clearUserPref('extensions.pdf.js.url'); + Services.prefs.clearUserPref('extensions.pdf.js.active'); } diff --git a/extensions/firefox/components/pdfContentHandler.js b/extensions/firefox/components/pdfContentHandler.js index 7746e41b6..444db1c1f 100644 --- a/extensions/firefox/components/pdfContentHandler.js +++ b/extensions/firefox/components/pdfContentHandler.js @@ -32,6 +32,9 @@ pdfContentHandler.prototype = { if (!(aRequest instanceof Ci.nsIChannel)) throw NS_ERROR_WONT_HANDLE_CONTENT; + if (!Services.prefs.getBoolPref('extensions.pdf.js.active')) + throw NS_ERROR_WONT_HANDLE_CONTENT; + let window = null; let callbacks = aRequest.notificationCallbacks || aRequest.loadGroup.notificationCallbacks; @@ -53,7 +56,7 @@ pdfContentHandler.prototype = { throw NS_ERROR_WONT_HANDLE_CONTENT; aRequest.cancel(Cr.NS_BINDING_ABORTED); - window.location = url.replace('%s', targetUrl); + window.location = url.replace('%s', encodeURIComponent(targetUrl)); }, classID: Components.ID('{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}'), diff --git a/extensions/firefox/install.rdf b/extensions/firefox/install.rdf index 0dfd6bf57..26b2192b6 100644 --- a/extensions/firefox/install.rdf +++ b/extensions/firefox/install.rdf @@ -19,6 +19,6 @@ true Vivien Nicolas pdf.js uri loader - https://github.com/andreasgal/pdf.js/ + https://github.com/mozilla/pdf.js/ diff --git a/src/canvas.js b/src/canvas.js index b7045dc39..474cc250f 100644 --- a/src/canvas.js +++ b/src/canvas.js @@ -24,13 +24,18 @@ var CanvasExtraState = (function canvasExtraState() { this.wordSpacing = 0; this.textHScale = 1; // Color spaces + this.fillColorSpace = new DeviceGrayCS; this.fillColorSpaceObj = null; + this.strokeColorSpace = new DeviceGrayCS; this.strokeColorSpaceObj = null; this.fillColorObj = null; this.strokeColorObj = null; // Default fore and background colors this.fillColor = '#000000'; this.strokeColor = '#000000'; + // Note: fill alpha applies to all non-stroking operations + this.fillAlpha = 1; + this.strokeAlpha = 1; this.old = old; } @@ -209,6 +214,13 @@ var CanvasGraphics = (function canvasGraphics() { case 'Font': this.setFont(state[1], state[2]); break; + case 'CA': + this.current.strokeAlpha = state[1]; + break; + case 'ca': + this.current.fillAlpha = state[1]; + this.ctx.globalAlpha = state[1]; + break; } } }, @@ -257,9 +269,13 @@ var CanvasGraphics = (function canvasGraphics() { rectangle: function canvasGraphicsRectangle(x, y, width, height) { this.ctx.rect(x, y, width, height); }, - stroke: function canvasGraphicsStroke() { + stroke: function canvasGraphicsStroke(consumePath) { + consumePath = typeof consumePath !== 'undefined' ? consumePath : true; var ctx = this.ctx; var strokeColor = this.current.strokeColor; + // For stroke we want to temporarily change the global alpha to the + // stroking alpha. + ctx.globalAlpha = this.current.strokeAlpha; if (strokeColor && strokeColor.hasOwnProperty('type') && strokeColor.type === 'Pattern') { // for patterns, we transform to pattern space, calculate @@ -271,14 +287,17 @@ var CanvasGraphics = (function canvasGraphics() { } else { ctx.stroke(); } - - this.consumePath(); + if (consumePath) + this.consumePath(); + // Restore the global alpha to the fill alpha + ctx.globalAlpha = this.current.fillAlpha; }, closeStroke: function canvasGraphicsCloseStroke() { this.closePath(); this.stroke(); }, - fill: function canvasGraphicsFill() { + fill: function canvasGraphicsFill(consumePath) { + consumePath = typeof consumePath !== 'undefined' ? consumePath : true; var ctx = this.ctx; var fillColor = this.current.fillColor; @@ -291,8 +310,8 @@ var CanvasGraphics = (function canvasGraphics() { } else { ctx.fill(); } - - this.consumePath(); + if (consumePath) + this.consumePath(); }, eoFill: function canvasGraphicsEoFill() { var savedFillRule = this.setEOFillRule(); @@ -300,29 +319,8 @@ var CanvasGraphics = (function canvasGraphics() { this.restoreFillRule(savedFillRule); }, fillStroke: function canvasGraphicsFillStroke() { - var ctx = this.ctx; - - var fillColor = this.current.fillColor; - if (fillColor && fillColor.hasOwnProperty('type') && - fillColor.type === 'Pattern') { - ctx.save(); - ctx.fillStyle = fillColor.getPattern(ctx); - ctx.fill(); - ctx.restore(); - } else { - ctx.fill(); - } - - var strokeColor = this.current.strokeColor; - if (strokeColor && strokeColor.hasOwnProperty('type') && - strokeColor.type === 'Pattern') { - ctx.save(); - ctx.strokeStyle = strokeColor.getPattern(ctx); - ctx.stroke(); - ctx.restore(); - } else { - ctx.stroke(); - } + this.fill(false); + this.stroke(false); this.consumePath(); }, @@ -332,10 +330,12 @@ var CanvasGraphics = (function canvasGraphics() { this.restoreFillRule(savedFillRule); }, closeFillStroke: function canvasGraphicsCloseFillStroke() { - return this.fillStroke(); + this.closePath(); + this.fillStroke(); }, closeEOFillStroke: function canvasGraphicsCloseEOFillStroke() { var savedFillRule = this.setEOFillRule(); + this.closePath(); this.fillStroke(); this.restoreFillRule(savedFillRule); }, @@ -537,8 +537,7 @@ var CanvasGraphics = (function canvasGraphics() { }, // Color - setStrokeColorSpace: - function canvasGraphicsSetStrokeColorSpacefunction(raw) { + setStrokeColorSpace: function canvasGraphicsSetStrokeColorSpace(raw) { this.current.strokeColorSpace = ColorSpace.fromIR(raw); }, setFillColorSpace: function canvasGraphicsSetFillColorSpace(raw) { @@ -549,7 +548,7 @@ var CanvasGraphics = (function canvasGraphics() { var color = cs.getRgb(arguments); this.setStrokeRGBColor.apply(this, color); }, - getColorN_IR_Pattern: function(IR, cs) { + getColorN_IR_Pattern: function canvasGraphicsGetColorN_IR_Pattern(IR, cs) { if (IR[0] == 'TilingPattern') { var args = IR[1]; var base = cs.base; @@ -665,8 +664,8 @@ var CanvasGraphics = (function canvasGraphics() { error('Should not call beginImageData'); }, - paintFormXObjectBegin: - function canvasGraphicsPaintFormXObject(matrix, bbox) { + paintFormXObjectBegin: function canvasGraphicsPaintFormXObjectBegin(matrix, + bbox) { this.save(); if (matrix && isArray(matrix) && 6 == matrix.length) @@ -681,11 +680,11 @@ var CanvasGraphics = (function canvasGraphics() { } }, - paintFormXObjectEnd: function() { + paintFormXObjectEnd: function canvasGraphicsPaintFormXObjectEnd() { this.restore(); }, - paintJpegXObject: function(objId, w, h) { + paintJpegXObject: function canvasGraphicsPaintJpegXObject(objId, w, h) { var image = this.objs.get(objId); if (!image) { error('Dependent image isn\'t ready yet'); @@ -704,7 +703,8 @@ var CanvasGraphics = (function canvasGraphics() { this.restore(); }, - paintImageMaskXObject: function(imgArray, inverseDecode, width, height) { + paintImageMaskXObject: function canvasGraphicsPaintImageMaskXObject( + imgArray, inverseDecode, width, height) { function applyStencilMask(buffer, inverseDecode) { var imgArrayPos = 0; var i, j, mask, buf; @@ -752,7 +752,7 @@ var CanvasGraphics = (function canvasGraphics() { this.restore(); }, - paintImageXObject: function(imgData) { + paintImageXObject: function canvasGraphicsPaintImageXObject(imgData) { this.save(); var ctx = this.ctx; var w = imgData.width; diff --git a/src/colorspace.js b/src/colorspace.js index 1c5c291f4..6bfad4c39 100644 --- a/src/colorspace.js +++ b/src/colorspace.js @@ -12,17 +12,17 @@ var ColorSpace = (function colorSpaceColorSpace() { constructor.prototype = { // Input: array of size numComps representing color component values // Output: array of rgb values, each value ranging from [0.1] - getRgb: function cs_getRgb(color) { + getRgb: function colorSpaceGetRgb(color) { error('Should not call ColorSpace.getRgb: ' + color); }, // Input: Uint8Array of component values, each value scaled to [0,255] // Output: Uint8Array of rgb values, each value scaled to [0,255] - getRgbBuffer: function cs_getRgbBuffer(input) { + getRgbBuffer: function colorSpaceGetRgbBuffer(input) { error('Should not call ColorSpace.getRgbBuffer: ' + input); } }; - constructor.parse = function colorspace_parse(cs, xref, res) { + constructor.parse = function colorSpaceParse(cs, xref, res) { var IR = constructor.parseToIR(cs, xref, res, true); if (IR instanceof SeparationCS) return IR; @@ -30,7 +30,7 @@ var ColorSpace = (function colorSpaceColorSpace() { return constructor.fromIR(IR); }; - constructor.fromIR = function(IR) { + constructor.fromIR = function colorSpaceFromIR(IR) { var name; if (isArray(IR)) { name = IR[0]; @@ -71,7 +71,8 @@ var ColorSpace = (function colorSpaceColorSpace() { return null; } - constructor.parseToIR = function colorspace_parse(cs, xref, res, parseOnly) { + constructor.parseToIR = function colorSpaceParseToIR(cs, xref, res, + parseOnly) { if (isName(cs)) { var colorSpaces = xref.fetchIfRef(res.get('ColorSpace')); if (isDict(colorSpaces)) { diff --git a/src/core.js b/src/core.js index 48b1d0591..2bc4c50aa 100644 --- a/src/core.js +++ b/src/core.js @@ -153,7 +153,7 @@ var Page = (function pagePage() { return shadow(this, 'rotate', rotate); }, - startRenderingFromIRQueue: function startRenderingFromIRQueue( + startRenderingFromIRQueue: function pageStartRenderingFromIRQueue( IRQueue, fonts) { var self = this; this.IRQueue = IRQueue; @@ -173,12 +173,13 @@ var Page = (function pagePage() { }); }; - this.ensureFonts(fonts, function() { + this.ensureFonts(fonts, + function pageStartRenderingFromIRQueueEnsureFonts() { displayContinuation(); }); }, - getIRQueue: function(handler, dependency) { + getIRQueue: function pageGetIRQueue(handler, dependency) { if (this.IRQueue) { // content was compiled return this.IRQueue; @@ -202,7 +203,7 @@ var Page = (function pagePage() { content, resources, IRQueue, dependency); }, - ensureFonts: function(fonts, callback) { + ensureFonts: function pageEnsureFonts(fonts, callback) { // Convert the font names to the corresponding font obj. for (var i = 0; i < fonts.length; i++) { fonts[i] = this.objs.objs[fonts[i]].data; @@ -211,7 +212,7 @@ var Page = (function pagePage() { // Load all the fonts var fontObjs = FontLoader.bind( fonts, - function(fontObjs) { + function pageEnsureFontsFontObjs(fontObjs) { this.stats.fonts = Date.now(); callback.call(this); @@ -220,7 +221,7 @@ var Page = (function pagePage() { ); }, - display: function(gfx, callback) { + display: function pageDisplay(gfx, callback) { var xref = this.xref; var resources = xref.fetchIfRef(this.resources); var mediaBox = xref.fetchIfRef(this.mediaBox); @@ -305,7 +306,7 @@ var Page = (function pagePage() { } return links; }, - startRendering: function(ctx, callback) { + startRendering: function pageStartRendering(ctx, callback) { this.ctx = ctx; this.callback = callback; @@ -446,7 +447,7 @@ var PDFDocModel = (function pdfDoc() { return constructor; })(); -var PDFDoc = (function() { +var PDFDoc = (function pdfDoc() { function constructor(arg, callback) { var stream = null; var data = null; @@ -486,10 +487,10 @@ var PDFDoc = (function() { } else { // If we don't use a worker, just post/sendMessage to the main thread. var worker = { - postMessage: function(obj) { + postMessage: function pdfDocPostMessage(obj) { worker.onmessage({data: obj}); }, - terminate: function() {} + terminate: function pdfDocTerminate() {} }; } this.worker = worker; @@ -499,7 +500,7 @@ var PDFDoc = (function() { var processorHandler = this.processorHandler = new MessageHandler('main', worker); - processorHandler.on('page', function(data) { + processorHandler.on('page', function pdfDocPage(data) { var pageNum = data.pageNum; var page = this.pageCache[pageNum]; var depFonts = data.depFonts; @@ -507,7 +508,7 @@ var PDFDoc = (function() { page.startRenderingFromIRQueue(data.IRQueue, depFonts); }, this); - processorHandler.on('obj', function(data) { + processorHandler.on('obj', function pdfDocObj(data) { var id = data[0]; var type = data[1]; @@ -551,7 +552,7 @@ var PDFDoc = (function() { } }, this); - processorHandler.on('font_ready', function(data) { + processorHandler.on('font_ready', function pdfDocFontReady(data) { var id = data[0]; var font = new FontShape(data[1]); @@ -570,7 +571,7 @@ var PDFDoc = (function() { } this.workerReadyPromise = new Promise('workerReady'); - setTimeout(function() { + setTimeout(function pdfDocFontReadySetTimeout() { processorHandler.send('doc', this.data); this.workerReadyPromise.resolve(true); }.bind(this)); @@ -581,14 +582,14 @@ var PDFDoc = (function() { return this.pdf.numPages; }, - startRendering: function(page) { + startRendering: function pdfDocStartRendering(page) { // The worker might not be ready to receive the page request yet. - this.workerReadyPromise.then(function() { + this.workerReadyPromise.then(function pdfDocStartRenderingThen() { this.processorHandler.send('page_request', page.pageNumber + 1); }.bind(this)); }, - getPage: function(n) { + getPage: function pdfDocGetPage(n) { if (this.pageCache[n]) return this.pageCache[n]; @@ -600,7 +601,7 @@ var PDFDoc = (function() { return this.pageCache[n] = page; }, - destroy: function() { + destroy: function pdfDocDestroy() { if (this.worker) this.worker.terminate(); diff --git a/src/evaluator.js b/src/evaluator.js index 48e12c83d..b7a5ef583 100644 --- a/src/evaluator.js +++ b/src/evaluator.js @@ -405,6 +405,8 @@ var PartialEvaluator = (function partialEvaluator() { case 'D': case 'RI': case 'FL': + case 'CA': + case 'ca': gsStateObj.push([key, value]); break; case 'Font': @@ -428,8 +430,6 @@ var PartialEvaluator = (function partialEvaluator() { case 'SA': case 'BM': case 'SMask': - case 'CA': - case 'ca': case 'AIS': case 'TK': TODO('graphic state operator ' + key); diff --git a/src/function.js b/src/function.js index e2b191274..a8c797a29 100644 --- a/src/function.js +++ b/src/function.js @@ -3,14 +3,15 @@ 'use strict'; -var PDFFunction = (function() { +var PDFFunction = (function pdfFunction() { var CONSTRUCT_SAMPLED = 0; var CONSTRUCT_INTERPOLATED = 2; var CONSTRUCT_STICHED = 3; var CONSTRUCT_POSTSCRIPT = 4; return { - getSampleArray: function(size, outputSize, bps, str) { + getSampleArray: function pdfFunctionGetSampleArray(size, outputSize, bps, + str) { var length = 1; for (var i = 0; i < size.length; i++) length *= size[i]; @@ -35,7 +36,7 @@ var PDFFunction = (function() { return array; }, - getIR: function(xref, fn) { + getIR: function pdfFunctionGetIR(xref, fn) { var dict = fn.dict; if (!dict) dict = fn; @@ -54,7 +55,7 @@ var PDFFunction = (function() { return typeFn.call(this, fn, dict, xref); }, - fromIR: function(IR) { + fromIR: function pdfFunctionFromIR(IR) { var type = IR[0]; switch (type) { case CONSTRUCT_SAMPLED: @@ -69,12 +70,12 @@ var PDFFunction = (function() { } }, - parse: function(xref, fn) { + parse: function pdfFunctionParse(xref, fn) { var IR = this.getIR(xref, fn); return this.fromIR(IR); }, - constructSampled: function(str, dict) { + constructSampled: function pdfFunctionConstructSampled(str, dict) { var domain = dict.get('Domain'); var range = dict.get('Range'); @@ -116,7 +117,7 @@ var PDFFunction = (function() { ]; }, - constructSampledFromIR: function(IR) { + constructSampledFromIR: function pdfFunctionConstructSampledFromIR(IR) { var inputSize = IR[1]; var domain = IR[2]; var encode = IR[3]; @@ -127,8 +128,8 @@ var PDFFunction = (function() { var bps = IR[8]; var range = IR[9]; - return function(args) { - var clip = function(v, min, max) { + return function constructSampledFromIRResult(args) { + var clip = function constructSampledFromIRClip(v, min, max) { if (v > max) v = max; else if (v < min) @@ -212,7 +213,7 @@ var PDFFunction = (function() { var length = diff.length; - return function(args) { + return function constructInterpolatedFromIRResult(args) { var x = n == 1 ? args[0] : Math.pow(args[0], n); var out = []; @@ -257,8 +258,8 @@ var PDFFunction = (function() { fns.push(PDFFunction.fromIR(fnsIR[i])); } - return function(args) { - var clip = function(v, min, max) { + return function constructStichedFromIRResult(args) { + var clip = function constructStichedFromIRClip(v, min, max) { if (v > max) v = max; else if (v < min) @@ -298,7 +299,7 @@ var PDFFunction = (function() { constructPostScriptFromIR: function pdfFunctionConstructPostScriptFromIR() { TODO('unhandled type of function'); - return function() { + return function constructPostScriptFromIRResult() { return [255, 105, 180]; }; } diff --git a/src/image.js b/src/image.js index b281e21c1..71aa0f113 100644 --- a/src/image.js +++ b/src/image.js @@ -229,12 +229,12 @@ var PDFImage = (function pdfImage() { return constructor; })(); -var JpegImage = (function() { +var JpegImage = (function jpegImage() { function JpegImage(objId, imageData, objs) { var src = 'data:image/jpeg;base64,' + window.btoa(imageData); var img = new Image(); - img.onload = (function() { + img.onload = (function jpegImageOnload() { this.loaded = true; objs.resolve(objId, this); @@ -247,7 +247,7 @@ var JpegImage = (function() { } JpegImage.prototype = { - getImage: function() { + getImage: function jpegImageGetImage() { return this.domImage; } }; diff --git a/src/obj.js b/src/obj.js index 8d5684ec2..fd1579280 100644 --- a/src/obj.js +++ b/src/obj.js @@ -642,7 +642,7 @@ var XRef = (function xRefXRef() { * inside of a worker. The `PDFObjects` implements some basic functions to * manage these objects. */ -var PDFObjects = (function() { +var PDFObjects = (function pdfObjects() { function PDFObjects() { this.objs = {}; } @@ -655,7 +655,7 @@ var PDFObjects = (function() { * Ensures there is an object defined for `objId`. Stores `data` on the * object *if* it is created. */ - ensureObj: function(objId, data) { + ensureObj: function pdfObjectsEnsureObj(objId, data) { if (this.objs[objId]) return this.objs[objId]; return this.objs[objId] = new Promise(objId, data); @@ -670,7 +670,7 @@ var PDFObjects = (function() { * function and the object is already resolved, the callback gets called * right away. */ - get: function(objId, callback) { + get: function pdfObjectsGet(objId, callback) { // If there is a callback, then the get can be async and the object is // not required to be resolved right now if (callback) { @@ -695,7 +695,7 @@ var PDFObjects = (function() { /** * Resolves the object `objId` with optional `data`. */ - resolve: function(objId, data) { + resolve: function pdfObjectsResolve(objId, data) { var objs = this.objs; // In case there is a promise already on this object, just resolve it. @@ -706,11 +706,11 @@ var PDFObjects = (function() { } }, - onData: function(objId, callback) { + onData: function pdfObjectsOnData(objId, callback) { this.ensureObj(objId).onData(callback); }, - isResolved: function(objId) { + isResolved: function pdfObjectsIsResolved(objId) { var objs = this.objs; if (!objs[objId]) { return false; @@ -719,7 +719,7 @@ var PDFObjects = (function() { } }, - hasData: function(objId) { + hasData: function pdfObjectsHasData(objId) { var objs = this.objs; if (!objs[objId]) { return false; @@ -731,7 +731,7 @@ var PDFObjects = (function() { /** * Sets the data of an object but *doesn't* resolve it. */ - setData: function(objId, data) { + setData: function pdfObjectsSetData(objId, data) { // Watchout! If you call `this.ensureObj(objId, data)` you're going to // create a *resolved* promise which shouldn't be the case! this.ensureObj(objId).data = data; diff --git a/src/pattern.js b/src/pattern.js index 8e7760e51..2a31fec4a 100644 --- a/src/pattern.js +++ b/src/pattern.js @@ -97,7 +97,7 @@ Shadings.RadialAxial = (function radialAxialShading() { this.colorStops = colorStops; } - constructor.fromIR = function(ctx, raw) { + constructor.fromIR = function radialAxialShadingGetIR(ctx, raw) { var type = raw[1]; var colorStops = raw[2]; var p0 = raw[3]; @@ -129,7 +129,7 @@ Shadings.RadialAxial = (function radialAxialShading() { } constructor.prototype = { - getIR: function RadialAxialShading_getIR() { + getIR: function radialAxialShadingGetIR() { var coordsArr = this.coordsArr; var type = this.shadingType; if (type == 2) { @@ -164,12 +164,12 @@ Shadings.Dummy = (function dummyShading() { this.type = 'Pattern'; } - constructor.fromIR = function() { + constructor.fromIR = function dummyShadingFromIR() { return 'hotpink'; } constructor.prototype = { - getIR: function dummpy_getir() { + getIR: function dummyShadingGetIR() { return ['Dummy']; } }; diff --git a/src/stream.js b/src/stream.js index 2b10e2fbd..73b096f1e 100644 --- a/src/stream.js +++ b/src/stream.js @@ -801,7 +801,7 @@ var JpegStream = (function jpegStream() { } constructor.prototype = { - getIR: function() { + getIR: function jpegStreamGetIR() { return this.src; }, getChar: function jpegStreamGetChar() { diff --git a/src/util.js b/src/util.js index d8d50337b..41ae4cc96 100644 --- a/src/util.js +++ b/src/util.js @@ -16,16 +16,15 @@ function warn(msg) { } function backtrace() { - var stackStr; try { throw new Error(); } catch (e) { - stackStr = e.stack; + return e.stack ? e.stack.split('\n').slice(2).join('\n') : ''; } - return stackStr.split('\n').slice(1).join('\n'); } function error(msg) { + log('Error: ' + msg); log(backtrace()); throw new Error(msg); } @@ -198,7 +197,7 @@ function isPDFFunction(v) { * can be set. If any of these happens twice or the data is required before * it was set, an exception is throw. */ -var Promise = (function() { +var Promise = (function promise() { var EMPTY_PROMISE = {}; /** @@ -222,19 +221,19 @@ var Promise = (function() { Promise.prototype = { hasData: false, - set data(data) { - if (data === undefined) { + set data(value) { + if (value === undefined) { return; } if (this._data !== EMPTY_PROMISE) { throw 'Promise ' + this.name + ': Cannot set the data of a promise twice'; } - this._data = data; + this._data = value; this.hasData = true; if (this.onDataCallback) { - this.onDataCallback(data); + this.onDataCallback(value); } }, @@ -245,7 +244,7 @@ var Promise = (function() { return this._data; }, - onData: function(callback) { + onData: function promiseOnData(callback) { if (this._data !== EMPTY_PROMISE) { callback(this._data); } else { @@ -253,7 +252,7 @@ var Promise = (function() { } }, - resolve: function(data) { + resolve: function promiseResolve(data) { if (this.isResolved) { throw 'A Promise can be resolved only once ' + this.name; } @@ -267,7 +266,7 @@ var Promise = (function() { } }, - then: function(callback) { + then: function promiseThen(callback) { if (!callback) { throw 'Requiring callback' + this.name; } diff --git a/src/worker.js b/src/worker.js index d46364f60..74a880cae 100644 --- a/src/worker.js +++ b/src/worker.js @@ -8,14 +8,14 @@ function MessageHandler(name, comObj) { this.comObj = comObj; var ah = this.actionHandler = {}; - ah['console_log'] = [function(data) { + ah['console_log'] = [function ahConsoleLog(data) { console.log.apply(console, data); }]; - ah['console_error'] = [function(data) { + ah['console_error'] = [function ahConsoleError(data) { console.error.apply(console, data); }]; - comObj.onmessage = function(event) { + comObj.onmessage = function messageHandlerComObjOnMessage(event) { var data = event.data; if (data.action in ah) { var action = ah[data.action]; @@ -27,15 +27,15 @@ function MessageHandler(name, comObj) { } MessageHandler.prototype = { - on: function(actionName, handler, scope) { + on: function messageHandlerOn(actionName, handler, scope) { var ah = this.actionHandler; if (ah[actionName]) { - throw "There is already an actionName called '" + actionName + "'"; + throw 'There is already an actionName called "' + actionName + '"'; } ah[actionName] = [handler, scope]; }, - send: function(actionName, data) { + send: function messageHandlerSend(actionName, data) { this.comObj.postMessage({ action: actionName, data: data @@ -44,23 +44,23 @@ MessageHandler.prototype = { }; var WorkerProcessorHandler = { - setup: function(handler) { + setup: function wphSetup(handler) { var pdfDoc = null; - handler.on('workerSrc', function(data) { + handler.on('workerSrc', function wphSetupWorkerSrc(data) { // In development, the `workerSrc` message is handled in the // `worker_loader.js` file. In production the workerProcessHandler is // called for this. This servers as a dummy to prevent calling an // undefined action `workerSrc`. }); - handler.on('doc', function(data) { + handler.on('doc', function wphSetupDoc(data) { // Create only the model of the PDFDoc, which is enough for // processing the content of the pdf. pdfDoc = new PDFDocModel(new Stream(data)); }); - handler.on('page_request', function(pageNum) { + handler.on('page_request', function wphSetupPageRequest(pageNum) { pageNum = parseInt(pageNum); var page = pdfDoc.getPage(pageNum); @@ -96,7 +96,7 @@ var WorkerProcessorHandler = { }); }, this); - handler.on('font', function(data) { + handler.on('font', function wphSetupFont(data) { var objId = data[0]; var name = data[1]; var file = data[2]; @@ -166,11 +166,11 @@ var workerConsole = { }); }, - time: function(name) { + time: function time(name) { consoleTimer[name] = Date.now(); }, - timeEnd: function(name) { + timeEnd: function timeEnd(name) { var time = consoleTimer[name]; if (time == null) { throw 'Unkown timer name ' + name; diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index e7eb0da43..443cb155a 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -12,4 +12,6 @@ !rotation.pdf !simpletype3font.pdf !sizes.pdf +!close-path-bug.pdf +!alphatrans.pdf diff --git a/test/pdfs/alphatrans.pdf b/test/pdfs/alphatrans.pdf new file mode 100644 index 000000000..6274ce3ac Binary files /dev/null and b/test/pdfs/alphatrans.pdf differ diff --git a/test/pdfs/close-path-bug.pdf b/test/pdfs/close-path-bug.pdf new file mode 100644 index 000000000..994d4e572 --- /dev/null +++ b/test/pdfs/close-path-bug.pdf @@ -0,0 +1,69 @@ +%PDF-1.4 +1 0 obj + <> +endobj + +2 0 obj + <> +endobj + +3 0 obj + <> +endobj + +4 0 obj + <>>> +endobj + +5 0 obj + << /Length 885 >> +stream + % Draw a black line segment, using the default line width. + 150 250 m + 150 350 l + S + + % Draw a thicker, dashed line segment. + 4 w % Set line width to 4 points + [4 6] 0 d % Set dash pattern to 4 units on, 6 units off + 150 250 m + 400 250 l + S + + [] 0 d % Reset dash pattern to a solid line + 1 w % Reset line width to 1 unit + + % Draw a rectangle with a 1−unit red border, filled with light blue. + 1.0 0.0 0.0 RG % Red for stroke color + 0.5 0.75 1.0 rg % Light blue for fill color + 200 300 50 75 re + B + + % Draw a curve filled with gray and with a colored border. + 0.5 0.1 0.2 RG + 0.7 g + 300 300 m + 300 400 400 400 400 300 c + b +endstream +endobj + +6 0 obj + [/PDF] +endobj + +xref +0 7 +0000000000 65535 f +0000000009 00000 n +0000000074 00000 n +0000000120 00000 n +0000000179 00000 n +0000000300 00000 n +0000001532 00000 n + +trailer + <> +startxref +1556 +%%EOF diff --git a/test/test_manifest.json b/test/test_manifest.json index d7ac34cef..25f609e8d 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -217,5 +217,16 @@ "link": false, "rounds": 1, "type": "eq" + }, + { "id": "close-path-bug", + "file": "pdfs/close-path-bug.pdf", + "rounds": 1, + "type": "eq" + }, + { "id": "alphatrans", + "file": "pdfs/alphatrans.pdf", + "link": false, + "rounds": 1, + "type": "eq" } ] diff --git a/web/compatibility.js b/web/compatibility.js index ad4c8f8a9..7d1d72553 100644 --- a/web/compatibility.js +++ b/web/compatibility.js @@ -83,6 +83,21 @@ }; })(); +// Object.keys() ? +(function checkObjectKeysCompatibility() { + if (typeof Object.keys !== 'undefined') + return; + + Object.keys = function objectKeys(obj) { + var result = []; + for (var i in obj) { + if (obj.hasOwnProperty(i)) + result.push(i); + } + return result; + }; +})(); + // No XMLHttpRequest.response ? (function checkXMLHttpRequestResponseCompatibility() { var xhrPrototype = XMLHttpRequest.prototype; diff --git a/web/index.html.template b/web/index.html.template index 12e606371..44e9a0cbe 100644 --- a/web/index.html.template +++ b/web/index.html.template @@ -3,7 +3,7 @@ - andreasgal/pdf.js @ GitHub + mozilla/pdf.js @ GitHub