Merge with master

This commit is contained in:
Julian Viereck 2011-11-01 19:56:34 +01:00
commit 94b8c4656b
23 changed files with 257 additions and 144 deletions

View File

@ -1,4 +1,4 @@
REPO = git@github.com:andreasgal/pdf.js.git REPO = git@github.com:mozilla/pdf.js.git
BUILD_DIR := build BUILD_DIR := build
BUILD_TARGET := $(BUILD_DIR)/pdf.js BUILD_TARGET := $(BUILD_DIR)/pdf.js
DEFAULT_BROWSERS := resources/browser_manifests/browser_manifest.json DEFAULT_BROWSERS := resources/browser_manifests/browser_manifest.json

View File

@ -22,7 +22,7 @@ successful.
For an online demo, visit: 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 This demo provides an interactive interface for displaying and browsing PDFs
using the pdf.js API. using the pdf.js API.
@ -31,7 +31,7 @@ using the pdf.js API.
A Firefox extension is also available: 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. 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: 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 $ cd pdfjs
Next, you need to start a local web server as some browsers don't allow opening 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: 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 This example illustrates the bare minimum ingredients for integrating pdf.js
in a custom project. 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. 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 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. 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 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 If you don't want to hack on the project or have little spare time, __you still
can help!__ Just open PDFs in the 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. any breakage in rendering.
Our Github contributors so far: 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! :) You can add your name to it! :)
@ -143,14 +143,14 @@ against reference images before merging pull requests.
See the bot repo for details: See the bot repo for details:
+ https://github.com/arturadib/pdf.js-bot + https://github.com/mozilla/pdf.js-bot
## Additional resources ## Additional resources
Our demo site is here: 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: You can read more about pdf.js here:

View File

@ -16,21 +16,31 @@ function log(str) {
function startup(aData, aReason) { function startup(aData, aReason) {
let manifestPath = 'chrome.manifest'; 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 { try {
file.initWithPath(aData.installPath.path); manifest.initWithPath(aData.installPath.path);
file.append(manifestPath); manifest.append(manifestPath);
Cm.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(file); Cm.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(manifest);
Services.prefs.setBoolPref('extensions.pdf.js.active', true);
} catch (e) { } catch (e) {
log(e); log(e);
} }
} }
function shutdown(aData, aReason) { function shutdown(aData, aReason) {
if (Services.prefs.getBoolPref('extensions.pdf.js.active'))
Services.prefs.setBoolPref('extensions.pdf.js.active', false);
} }
function install(aData, aReason) { function install(aData, aReason) {
let url = 'chrome://pdf.js/content/web/viewer.html?file=%s'; let url = 'chrome://pdf.js/content/web/viewer.html?file=%s';
Services.prefs.setCharPref('extensions.pdf.js.url', url); 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');
} }

View File

@ -32,6 +32,9 @@ pdfContentHandler.prototype = {
if (!(aRequest instanceof Ci.nsIChannel)) if (!(aRequest instanceof Ci.nsIChannel))
throw NS_ERROR_WONT_HANDLE_CONTENT; throw NS_ERROR_WONT_HANDLE_CONTENT;
if (!Services.prefs.getBoolPref('extensions.pdf.js.active'))
throw NS_ERROR_WONT_HANDLE_CONTENT;
let window = null; let window = null;
let callbacks = aRequest.notificationCallbacks || let callbacks = aRequest.notificationCallbacks ||
aRequest.loadGroup.notificationCallbacks; aRequest.loadGroup.notificationCallbacks;
@ -53,7 +56,7 @@ pdfContentHandler.prototype = {
throw NS_ERROR_WONT_HANDLE_CONTENT; throw NS_ERROR_WONT_HANDLE_CONTENT;
aRequest.cancel(Cr.NS_BINDING_ABORTED); 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}'), classID: Components.ID('{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}'),

View File

@ -19,6 +19,6 @@
<em:unpack>true</em:unpack> <em:unpack>true</em:unpack>
<em:creator>Vivien Nicolas</em:creator> <em:creator>Vivien Nicolas</em:creator>
<em:description>pdf.js uri loader</em:description> <em:description>pdf.js uri loader</em:description>
<em:homepageURL>https://github.com/andreasgal/pdf.js/</em:homepageURL> <em:homepageURL>https://github.com/mozilla/pdf.js/</em:homepageURL>
</Description> </Description>
</RDF> </RDF>

View File

@ -24,13 +24,18 @@ var CanvasExtraState = (function canvasExtraState() {
this.wordSpacing = 0; this.wordSpacing = 0;
this.textHScale = 1; this.textHScale = 1;
// Color spaces // Color spaces
this.fillColorSpace = new DeviceGrayCS;
this.fillColorSpaceObj = null; this.fillColorSpaceObj = null;
this.strokeColorSpace = new DeviceGrayCS;
this.strokeColorSpaceObj = null; this.strokeColorSpaceObj = null;
this.fillColorObj = null; this.fillColorObj = null;
this.strokeColorObj = null; this.strokeColorObj = null;
// Default fore and background colors // Default fore and background colors
this.fillColor = '#000000'; this.fillColor = '#000000';
this.strokeColor = '#000000'; this.strokeColor = '#000000';
// Note: fill alpha applies to all non-stroking operations
this.fillAlpha = 1;
this.strokeAlpha = 1;
this.old = old; this.old = old;
} }
@ -209,6 +214,13 @@ var CanvasGraphics = (function canvasGraphics() {
case 'Font': case 'Font':
this.setFont(state[1], state[2]); this.setFont(state[1], state[2]);
break; 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) { rectangle: function canvasGraphicsRectangle(x, y, width, height) {
this.ctx.rect(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 ctx = this.ctx;
var strokeColor = this.current.strokeColor; 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') && if (strokeColor && strokeColor.hasOwnProperty('type') &&
strokeColor.type === 'Pattern') { strokeColor.type === 'Pattern') {
// for patterns, we transform to pattern space, calculate // for patterns, we transform to pattern space, calculate
@ -271,14 +287,17 @@ var CanvasGraphics = (function canvasGraphics() {
} else { } else {
ctx.stroke(); ctx.stroke();
} }
if (consumePath)
this.consumePath(); this.consumePath();
// Restore the global alpha to the fill alpha
ctx.globalAlpha = this.current.fillAlpha;
}, },
closeStroke: function canvasGraphicsCloseStroke() { closeStroke: function canvasGraphicsCloseStroke() {
this.closePath(); this.closePath();
this.stroke(); this.stroke();
}, },
fill: function canvasGraphicsFill() { fill: function canvasGraphicsFill(consumePath) {
consumePath = typeof consumePath !== 'undefined' ? consumePath : true;
var ctx = this.ctx; var ctx = this.ctx;
var fillColor = this.current.fillColor; var fillColor = this.current.fillColor;
@ -291,8 +310,8 @@ var CanvasGraphics = (function canvasGraphics() {
} else { } else {
ctx.fill(); ctx.fill();
} }
if (consumePath)
this.consumePath(); this.consumePath();
}, },
eoFill: function canvasGraphicsEoFill() { eoFill: function canvasGraphicsEoFill() {
var savedFillRule = this.setEOFillRule(); var savedFillRule = this.setEOFillRule();
@ -300,29 +319,8 @@ var CanvasGraphics = (function canvasGraphics() {
this.restoreFillRule(savedFillRule); this.restoreFillRule(savedFillRule);
}, },
fillStroke: function canvasGraphicsFillStroke() { fillStroke: function canvasGraphicsFillStroke() {
var ctx = this.ctx; this.fill(false);
this.stroke(false);
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.consumePath(); this.consumePath();
}, },
@ -332,10 +330,12 @@ var CanvasGraphics = (function canvasGraphics() {
this.restoreFillRule(savedFillRule); this.restoreFillRule(savedFillRule);
}, },
closeFillStroke: function canvasGraphicsCloseFillStroke() { closeFillStroke: function canvasGraphicsCloseFillStroke() {
return this.fillStroke(); this.closePath();
this.fillStroke();
}, },
closeEOFillStroke: function canvasGraphicsCloseEOFillStroke() { closeEOFillStroke: function canvasGraphicsCloseEOFillStroke() {
var savedFillRule = this.setEOFillRule(); var savedFillRule = this.setEOFillRule();
this.closePath();
this.fillStroke(); this.fillStroke();
this.restoreFillRule(savedFillRule); this.restoreFillRule(savedFillRule);
}, },
@ -537,8 +537,7 @@ var CanvasGraphics = (function canvasGraphics() {
}, },
// Color // Color
setStrokeColorSpace: setStrokeColorSpace: function canvasGraphicsSetStrokeColorSpace(raw) {
function canvasGraphicsSetStrokeColorSpacefunction(raw) {
this.current.strokeColorSpace = ColorSpace.fromIR(raw); this.current.strokeColorSpace = ColorSpace.fromIR(raw);
}, },
setFillColorSpace: function canvasGraphicsSetFillColorSpace(raw) { setFillColorSpace: function canvasGraphicsSetFillColorSpace(raw) {
@ -549,7 +548,7 @@ var CanvasGraphics = (function canvasGraphics() {
var color = cs.getRgb(arguments); var color = cs.getRgb(arguments);
this.setStrokeRGBColor.apply(this, color); this.setStrokeRGBColor.apply(this, color);
}, },
getColorN_IR_Pattern: function(IR, cs) { getColorN_IR_Pattern: function canvasGraphicsGetColorN_IR_Pattern(IR, cs) {
if (IR[0] == 'TilingPattern') { if (IR[0] == 'TilingPattern') {
var args = IR[1]; var args = IR[1];
var base = cs.base; var base = cs.base;
@ -665,8 +664,8 @@ var CanvasGraphics = (function canvasGraphics() {
error('Should not call beginImageData'); error('Should not call beginImageData');
}, },
paintFormXObjectBegin: paintFormXObjectBegin: function canvasGraphicsPaintFormXObjectBegin(matrix,
function canvasGraphicsPaintFormXObject(matrix, bbox) { bbox) {
this.save(); this.save();
if (matrix && isArray(matrix) && 6 == matrix.length) if (matrix && isArray(matrix) && 6 == matrix.length)
@ -681,11 +680,11 @@ var CanvasGraphics = (function canvasGraphics() {
} }
}, },
paintFormXObjectEnd: function() { paintFormXObjectEnd: function canvasGraphicsPaintFormXObjectEnd() {
this.restore(); this.restore();
}, },
paintJpegXObject: function(objId, w, h) { paintJpegXObject: function canvasGraphicsPaintJpegXObject(objId, w, h) {
var image = this.objs.get(objId); var image = this.objs.get(objId);
if (!image) { if (!image) {
error('Dependent image isn\'t ready yet'); error('Dependent image isn\'t ready yet');
@ -704,7 +703,8 @@ var CanvasGraphics = (function canvasGraphics() {
this.restore(); this.restore();
}, },
paintImageMaskXObject: function(imgArray, inverseDecode, width, height) { paintImageMaskXObject: function canvasGraphicsPaintImageMaskXObject(
imgArray, inverseDecode, width, height) {
function applyStencilMask(buffer, inverseDecode) { function applyStencilMask(buffer, inverseDecode) {
var imgArrayPos = 0; var imgArrayPos = 0;
var i, j, mask, buf; var i, j, mask, buf;
@ -752,7 +752,7 @@ var CanvasGraphics = (function canvasGraphics() {
this.restore(); this.restore();
}, },
paintImageXObject: function(imgData) { paintImageXObject: function canvasGraphicsPaintImageXObject(imgData) {
this.save(); this.save();
var ctx = this.ctx; var ctx = this.ctx;
var w = imgData.width; var w = imgData.width;

View File

@ -12,17 +12,17 @@ var ColorSpace = (function colorSpaceColorSpace() {
constructor.prototype = { constructor.prototype = {
// Input: array of size numComps representing color component values // Input: array of size numComps representing color component values
// Output: array of rgb values, each value ranging from [0.1] // 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); error('Should not call ColorSpace.getRgb: ' + color);
}, },
// Input: Uint8Array of component values, each value scaled to [0,255] // Input: Uint8Array of component values, each value scaled to [0,255]
// Output: Uint8Array of rgb 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); 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); var IR = constructor.parseToIR(cs, xref, res, true);
if (IR instanceof SeparationCS) if (IR instanceof SeparationCS)
return IR; return IR;
@ -30,7 +30,7 @@ var ColorSpace = (function colorSpaceColorSpace() {
return constructor.fromIR(IR); return constructor.fromIR(IR);
}; };
constructor.fromIR = function(IR) { constructor.fromIR = function colorSpaceFromIR(IR) {
var name; var name;
if (isArray(IR)) { if (isArray(IR)) {
name = IR[0]; name = IR[0];
@ -71,7 +71,8 @@ var ColorSpace = (function colorSpaceColorSpace() {
return null; return null;
} }
constructor.parseToIR = function colorspace_parse(cs, xref, res, parseOnly) { constructor.parseToIR = function colorSpaceParseToIR(cs, xref, res,
parseOnly) {
if (isName(cs)) { if (isName(cs)) {
var colorSpaces = xref.fetchIfRef(res.get('ColorSpace')); var colorSpaces = xref.fetchIfRef(res.get('ColorSpace'));
if (isDict(colorSpaces)) { if (isDict(colorSpaces)) {

View File

@ -153,7 +153,7 @@ var Page = (function pagePage() {
return shadow(this, 'rotate', rotate); return shadow(this, 'rotate', rotate);
}, },
startRenderingFromIRQueue: function startRenderingFromIRQueue( startRenderingFromIRQueue: function pageStartRenderingFromIRQueue(
IRQueue, fonts) { IRQueue, fonts) {
var self = this; var self = this;
this.IRQueue = IRQueue; this.IRQueue = IRQueue;
@ -173,12 +173,13 @@ var Page = (function pagePage() {
}); });
}; };
this.ensureFonts(fonts, function() { this.ensureFonts(fonts,
function pageStartRenderingFromIRQueueEnsureFonts() {
displayContinuation(); displayContinuation();
}); });
}, },
getIRQueue: function(handler, dependency) { getIRQueue: function pageGetIRQueue(handler, dependency) {
if (this.IRQueue) { if (this.IRQueue) {
// content was compiled // content was compiled
return this.IRQueue; return this.IRQueue;
@ -202,7 +203,7 @@ var Page = (function pagePage() {
content, resources, IRQueue, dependency); content, resources, IRQueue, dependency);
}, },
ensureFonts: function(fonts, callback) { ensureFonts: function pageEnsureFonts(fonts, callback) {
// Convert the font names to the corresponding font obj. // Convert the font names to the corresponding font obj.
for (var i = 0; i < fonts.length; i++) { for (var i = 0; i < fonts.length; i++) {
fonts[i] = this.objs.objs[fonts[i]].data; fonts[i] = this.objs.objs[fonts[i]].data;
@ -211,7 +212,7 @@ var Page = (function pagePage() {
// Load all the fonts // Load all the fonts
var fontObjs = FontLoader.bind( var fontObjs = FontLoader.bind(
fonts, fonts,
function(fontObjs) { function pageEnsureFontsFontObjs(fontObjs) {
this.stats.fonts = Date.now(); this.stats.fonts = Date.now();
callback.call(this); 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 xref = this.xref;
var resources = xref.fetchIfRef(this.resources); var resources = xref.fetchIfRef(this.resources);
var mediaBox = xref.fetchIfRef(this.mediaBox); var mediaBox = xref.fetchIfRef(this.mediaBox);
@ -305,7 +306,7 @@ var Page = (function pagePage() {
} }
return links; return links;
}, },
startRendering: function(ctx, callback) { startRendering: function pageStartRendering(ctx, callback) {
this.ctx = ctx; this.ctx = ctx;
this.callback = callback; this.callback = callback;
@ -446,7 +447,7 @@ var PDFDocModel = (function pdfDoc() {
return constructor; return constructor;
})(); })();
var PDFDoc = (function() { var PDFDoc = (function pdfDoc() {
function constructor(arg, callback) { function constructor(arg, callback) {
var stream = null; var stream = null;
var data = null; var data = null;
@ -486,10 +487,10 @@ var PDFDoc = (function() {
} else { } else {
// If we don't use a worker, just post/sendMessage to the main thread. // If we don't use a worker, just post/sendMessage to the main thread.
var worker = { var worker = {
postMessage: function(obj) { postMessage: function pdfDocPostMessage(obj) {
worker.onmessage({data: obj}); worker.onmessage({data: obj});
}, },
terminate: function() {} terminate: function pdfDocTerminate() {}
}; };
} }
this.worker = worker; this.worker = worker;
@ -499,7 +500,7 @@ var PDFDoc = (function() {
var processorHandler = this.processorHandler = var processorHandler = this.processorHandler =
new MessageHandler('main', worker); new MessageHandler('main', worker);
processorHandler.on('page', function(data) { processorHandler.on('page', function pdfDocPage(data) {
var pageNum = data.pageNum; var pageNum = data.pageNum;
var page = this.pageCache[pageNum]; var page = this.pageCache[pageNum];
var depFonts = data.depFonts; var depFonts = data.depFonts;
@ -507,7 +508,7 @@ var PDFDoc = (function() {
page.startRenderingFromIRQueue(data.IRQueue, depFonts); page.startRenderingFromIRQueue(data.IRQueue, depFonts);
}, this); }, this);
processorHandler.on('obj', function(data) { processorHandler.on('obj', function pdfDocObj(data) {
var id = data[0]; var id = data[0];
var type = data[1]; var type = data[1];
@ -551,7 +552,7 @@ var PDFDoc = (function() {
} }
}, this); }, this);
processorHandler.on('font_ready', function(data) { processorHandler.on('font_ready', function pdfDocFontReady(data) {
var id = data[0]; var id = data[0];
var font = new FontShape(data[1]); var font = new FontShape(data[1]);
@ -570,7 +571,7 @@ var PDFDoc = (function() {
} }
this.workerReadyPromise = new Promise('workerReady'); this.workerReadyPromise = new Promise('workerReady');
setTimeout(function() { setTimeout(function pdfDocFontReadySetTimeout() {
processorHandler.send('doc', this.data); processorHandler.send('doc', this.data);
this.workerReadyPromise.resolve(true); this.workerReadyPromise.resolve(true);
}.bind(this)); }.bind(this));
@ -581,14 +582,14 @@ var PDFDoc = (function() {
return this.pdf.numPages; return this.pdf.numPages;
}, },
startRendering: function(page) { startRendering: function pdfDocStartRendering(page) {
// The worker might not be ready to receive the page request yet. // 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); this.processorHandler.send('page_request', page.pageNumber + 1);
}.bind(this)); }.bind(this));
}, },
getPage: function(n) { getPage: function pdfDocGetPage(n) {
if (this.pageCache[n]) if (this.pageCache[n])
return this.pageCache[n]; return this.pageCache[n];
@ -600,7 +601,7 @@ var PDFDoc = (function() {
return this.pageCache[n] = page; return this.pageCache[n] = page;
}, },
destroy: function() { destroy: function pdfDocDestroy() {
if (this.worker) if (this.worker)
this.worker.terminate(); this.worker.terminate();

View File

@ -405,6 +405,8 @@ var PartialEvaluator = (function partialEvaluator() {
case 'D': case 'D':
case 'RI': case 'RI':
case 'FL': case 'FL':
case 'CA':
case 'ca':
gsStateObj.push([key, value]); gsStateObj.push([key, value]);
break; break;
case 'Font': case 'Font':
@ -428,8 +430,6 @@ var PartialEvaluator = (function partialEvaluator() {
case 'SA': case 'SA':
case 'BM': case 'BM':
case 'SMask': case 'SMask':
case 'CA':
case 'ca':
case 'AIS': case 'AIS':
case 'TK': case 'TK':
TODO('graphic state operator ' + key); TODO('graphic state operator ' + key);

View File

@ -3,14 +3,15 @@
'use strict'; 'use strict';
var PDFFunction = (function() { var PDFFunction = (function pdfFunction() {
var CONSTRUCT_SAMPLED = 0; var CONSTRUCT_SAMPLED = 0;
var CONSTRUCT_INTERPOLATED = 2; var CONSTRUCT_INTERPOLATED = 2;
var CONSTRUCT_STICHED = 3; var CONSTRUCT_STICHED = 3;
var CONSTRUCT_POSTSCRIPT = 4; var CONSTRUCT_POSTSCRIPT = 4;
return { return {
getSampleArray: function(size, outputSize, bps, str) { getSampleArray: function pdfFunctionGetSampleArray(size, outputSize, bps,
str) {
var length = 1; var length = 1;
for (var i = 0; i < size.length; i++) for (var i = 0; i < size.length; i++)
length *= size[i]; length *= size[i];
@ -35,7 +36,7 @@ var PDFFunction = (function() {
return array; return array;
}, },
getIR: function(xref, fn) { getIR: function pdfFunctionGetIR(xref, fn) {
var dict = fn.dict; var dict = fn.dict;
if (!dict) if (!dict)
dict = fn; dict = fn;
@ -54,7 +55,7 @@ var PDFFunction = (function() {
return typeFn.call(this, fn, dict, xref); return typeFn.call(this, fn, dict, xref);
}, },
fromIR: function(IR) { fromIR: function pdfFunctionFromIR(IR) {
var type = IR[0]; var type = IR[0];
switch (type) { switch (type) {
case CONSTRUCT_SAMPLED: 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); var IR = this.getIR(xref, fn);
return this.fromIR(IR); return this.fromIR(IR);
}, },
constructSampled: function(str, dict) { constructSampled: function pdfFunctionConstructSampled(str, dict) {
var domain = dict.get('Domain'); var domain = dict.get('Domain');
var range = dict.get('Range'); var range = dict.get('Range');
@ -116,7 +117,7 @@ var PDFFunction = (function() {
]; ];
}, },
constructSampledFromIR: function(IR) { constructSampledFromIR: function pdfFunctionConstructSampledFromIR(IR) {
var inputSize = IR[1]; var inputSize = IR[1];
var domain = IR[2]; var domain = IR[2];
var encode = IR[3]; var encode = IR[3];
@ -127,8 +128,8 @@ var PDFFunction = (function() {
var bps = IR[8]; var bps = IR[8];
var range = IR[9]; var range = IR[9];
return function(args) { return function constructSampledFromIRResult(args) {
var clip = function(v, min, max) { var clip = function constructSampledFromIRClip(v, min, max) {
if (v > max) if (v > max)
v = max; v = max;
else if (v < min) else if (v < min)
@ -212,7 +213,7 @@ var PDFFunction = (function() {
var length = diff.length; var length = diff.length;
return function(args) { return function constructInterpolatedFromIRResult(args) {
var x = n == 1 ? args[0] : Math.pow(args[0], n); var x = n == 1 ? args[0] : Math.pow(args[0], n);
var out = []; var out = [];
@ -257,8 +258,8 @@ var PDFFunction = (function() {
fns.push(PDFFunction.fromIR(fnsIR[i])); fns.push(PDFFunction.fromIR(fnsIR[i]));
} }
return function(args) { return function constructStichedFromIRResult(args) {
var clip = function(v, min, max) { var clip = function constructStichedFromIRClip(v, min, max) {
if (v > max) if (v > max)
v = max; v = max;
else if (v < min) else if (v < min)
@ -298,7 +299,7 @@ var PDFFunction = (function() {
constructPostScriptFromIR: function pdfFunctionConstructPostScriptFromIR() { constructPostScriptFromIR: function pdfFunctionConstructPostScriptFromIR() {
TODO('unhandled type of function'); TODO('unhandled type of function');
return function() { return function constructPostScriptFromIRResult() {
return [255, 105, 180]; return [255, 105, 180];
}; };
} }

View File

@ -229,12 +229,12 @@ var PDFImage = (function pdfImage() {
return constructor; return constructor;
})(); })();
var JpegImage = (function() { var JpegImage = (function jpegImage() {
function JpegImage(objId, imageData, objs) { function JpegImage(objId, imageData, objs) {
var src = 'data:image/jpeg;base64,' + window.btoa(imageData); var src = 'data:image/jpeg;base64,' + window.btoa(imageData);
var img = new Image(); var img = new Image();
img.onload = (function() { img.onload = (function jpegImageOnload() {
this.loaded = true; this.loaded = true;
objs.resolve(objId, this); objs.resolve(objId, this);
@ -247,7 +247,7 @@ var JpegImage = (function() {
} }
JpegImage.prototype = { JpegImage.prototype = {
getImage: function() { getImage: function jpegImageGetImage() {
return this.domImage; return this.domImage;
} }
}; };

View File

@ -642,7 +642,7 @@ var XRef = (function xRefXRef() {
* inside of a worker. The `PDFObjects` implements some basic functions to * inside of a worker. The `PDFObjects` implements some basic functions to
* manage these objects. * manage these objects.
*/ */
var PDFObjects = (function() { var PDFObjects = (function pdfObjects() {
function PDFObjects() { function PDFObjects() {
this.objs = {}; this.objs = {};
} }
@ -655,7 +655,7 @@ var PDFObjects = (function() {
* Ensures there is an object defined for `objId`. Stores `data` on the * Ensures there is an object defined for `objId`. Stores `data` on the
* object *if* it is created. * object *if* it is created.
*/ */
ensureObj: function(objId, data) { ensureObj: function pdfObjectsEnsureObj(objId, data) {
if (this.objs[objId]) if (this.objs[objId])
return this.objs[objId]; return this.objs[objId];
return this.objs[objId] = new Promise(objId, data); 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 * function and the object is already resolved, the callback gets called
* right away. * 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 // If there is a callback, then the get can be async and the object is
// not required to be resolved right now // not required to be resolved right now
if (callback) { if (callback) {
@ -695,7 +695,7 @@ var PDFObjects = (function() {
/** /**
* Resolves the object `objId` with optional `data`. * Resolves the object `objId` with optional `data`.
*/ */
resolve: function(objId, data) { resolve: function pdfObjectsResolve(objId, data) {
var objs = this.objs; var objs = this.objs;
// In case there is a promise already on this object, just resolve it. // 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); this.ensureObj(objId).onData(callback);
}, },
isResolved: function(objId) { isResolved: function pdfObjectsIsResolved(objId) {
var objs = this.objs; var objs = this.objs;
if (!objs[objId]) { if (!objs[objId]) {
return false; return false;
@ -719,7 +719,7 @@ var PDFObjects = (function() {
} }
}, },
hasData: function(objId) { hasData: function pdfObjectsHasData(objId) {
var objs = this.objs; var objs = this.objs;
if (!objs[objId]) { if (!objs[objId]) {
return false; return false;
@ -731,7 +731,7 @@ var PDFObjects = (function() {
/** /**
* Sets the data of an object but *doesn't* resolve it. * 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 // Watchout! If you call `this.ensureObj(objId, data)` you're going to
// create a *resolved* promise which shouldn't be the case! // create a *resolved* promise which shouldn't be the case!
this.ensureObj(objId).data = data; this.ensureObj(objId).data = data;

View File

@ -97,7 +97,7 @@ Shadings.RadialAxial = (function radialAxialShading() {
this.colorStops = colorStops; this.colorStops = colorStops;
} }
constructor.fromIR = function(ctx, raw) { constructor.fromIR = function radialAxialShadingGetIR(ctx, raw) {
var type = raw[1]; var type = raw[1];
var colorStops = raw[2]; var colorStops = raw[2];
var p0 = raw[3]; var p0 = raw[3];
@ -129,7 +129,7 @@ Shadings.RadialAxial = (function radialAxialShading() {
} }
constructor.prototype = { constructor.prototype = {
getIR: function RadialAxialShading_getIR() { getIR: function radialAxialShadingGetIR() {
var coordsArr = this.coordsArr; var coordsArr = this.coordsArr;
var type = this.shadingType; var type = this.shadingType;
if (type == 2) { if (type == 2) {
@ -164,12 +164,12 @@ Shadings.Dummy = (function dummyShading() {
this.type = 'Pattern'; this.type = 'Pattern';
} }
constructor.fromIR = function() { constructor.fromIR = function dummyShadingFromIR() {
return 'hotpink'; return 'hotpink';
} }
constructor.prototype = { constructor.prototype = {
getIR: function dummpy_getir() { getIR: function dummyShadingGetIR() {
return ['Dummy']; return ['Dummy'];
} }
}; };

View File

@ -801,7 +801,7 @@ var JpegStream = (function jpegStream() {
} }
constructor.prototype = { constructor.prototype = {
getIR: function() { getIR: function jpegStreamGetIR() {
return this.src; return this.src;
}, },
getChar: function jpegStreamGetChar() { getChar: function jpegStreamGetChar() {

View File

@ -16,16 +16,15 @@ function warn(msg) {
} }
function backtrace() { function backtrace() {
var stackStr;
try { try {
throw new Error(); throw new Error();
} catch (e) { } 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) { function error(msg) {
log('Error: ' + msg);
log(backtrace()); log(backtrace());
throw new Error(msg); 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 * can be set. If any of these happens twice or the data is required before
* it was set, an exception is throw. * it was set, an exception is throw.
*/ */
var Promise = (function() { var Promise = (function promise() {
var EMPTY_PROMISE = {}; var EMPTY_PROMISE = {};
/** /**
@ -222,19 +221,19 @@ var Promise = (function() {
Promise.prototype = { Promise.prototype = {
hasData: false, hasData: false,
set data(data) { set data(value) {
if (data === undefined) { if (value === undefined) {
return; return;
} }
if (this._data !== EMPTY_PROMISE) { if (this._data !== EMPTY_PROMISE) {
throw 'Promise ' + this.name + throw 'Promise ' + this.name +
': Cannot set the data of a promise twice'; ': Cannot set the data of a promise twice';
} }
this._data = data; this._data = value;
this.hasData = true; this.hasData = true;
if (this.onDataCallback) { if (this.onDataCallback) {
this.onDataCallback(data); this.onDataCallback(value);
} }
}, },
@ -245,7 +244,7 @@ var Promise = (function() {
return this._data; return this._data;
}, },
onData: function(callback) { onData: function promiseOnData(callback) {
if (this._data !== EMPTY_PROMISE) { if (this._data !== EMPTY_PROMISE) {
callback(this._data); callback(this._data);
} else { } else {
@ -253,7 +252,7 @@ var Promise = (function() {
} }
}, },
resolve: function(data) { resolve: function promiseResolve(data) {
if (this.isResolved) { if (this.isResolved) {
throw 'A Promise can be resolved only once ' + this.name; 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) { if (!callback) {
throw 'Requiring callback' + this.name; throw 'Requiring callback' + this.name;
} }

View File

@ -8,14 +8,14 @@ function MessageHandler(name, comObj) {
this.comObj = comObj; this.comObj = comObj;
var ah = this.actionHandler = {}; var ah = this.actionHandler = {};
ah['console_log'] = [function(data) { ah['console_log'] = [function ahConsoleLog(data) {
console.log.apply(console, data); console.log.apply(console, data);
}]; }];
ah['console_error'] = [function(data) { ah['console_error'] = [function ahConsoleError(data) {
console.error.apply(console, data); console.error.apply(console, data);
}]; }];
comObj.onmessage = function(event) { comObj.onmessage = function messageHandlerComObjOnMessage(event) {
var data = event.data; var data = event.data;
if (data.action in ah) { if (data.action in ah) {
var action = ah[data.action]; var action = ah[data.action];
@ -27,15 +27,15 @@ function MessageHandler(name, comObj) {
} }
MessageHandler.prototype = { MessageHandler.prototype = {
on: function(actionName, handler, scope) { on: function messageHandlerOn(actionName, handler, scope) {
var ah = this.actionHandler; var ah = this.actionHandler;
if (ah[actionName]) { if (ah[actionName]) {
throw "There is already an actionName called '" + actionName + "'"; throw 'There is already an actionName called "' + actionName + '"';
} }
ah[actionName] = [handler, scope]; ah[actionName] = [handler, scope];
}, },
send: function(actionName, data) { send: function messageHandlerSend(actionName, data) {
this.comObj.postMessage({ this.comObj.postMessage({
action: actionName, action: actionName,
data: data data: data
@ -44,23 +44,23 @@ MessageHandler.prototype = {
}; };
var WorkerProcessorHandler = { var WorkerProcessorHandler = {
setup: function(handler) { setup: function wphSetup(handler) {
var pdfDoc = null; var pdfDoc = null;
handler.on('workerSrc', function(data) { handler.on('workerSrc', function wphSetupWorkerSrc(data) {
// In development, the `workerSrc` message is handled in the // In development, the `workerSrc` message is handled in the
// `worker_loader.js` file. In production the workerProcessHandler is // `worker_loader.js` file. In production the workerProcessHandler is
// called for this. This servers as a dummy to prevent calling an // called for this. This servers as a dummy to prevent calling an
// undefined action `workerSrc`. // 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 // Create only the model of the PDFDoc, which is enough for
// processing the content of the pdf. // processing the content of the pdf.
pdfDoc = new PDFDocModel(new Stream(data)); pdfDoc = new PDFDocModel(new Stream(data));
}); });
handler.on('page_request', function(pageNum) { handler.on('page_request', function wphSetupPageRequest(pageNum) {
pageNum = parseInt(pageNum); pageNum = parseInt(pageNum);
var page = pdfDoc.getPage(pageNum); var page = pdfDoc.getPage(pageNum);
@ -96,7 +96,7 @@ var WorkerProcessorHandler = {
}); });
}, this); }, this);
handler.on('font', function(data) { handler.on('font', function wphSetupFont(data) {
var objId = data[0]; var objId = data[0];
var name = data[1]; var name = data[1];
var file = data[2]; var file = data[2];
@ -166,11 +166,11 @@ var workerConsole = {
}); });
}, },
time: function(name) { time: function time(name) {
consoleTimer[name] = Date.now(); consoleTimer[name] = Date.now();
}, },
timeEnd: function(name) { timeEnd: function timeEnd(name) {
var time = consoleTimer[name]; var time = consoleTimer[name];
if (time == null) { if (time == null) {
throw 'Unkown timer name ' + name; throw 'Unkown timer name ' + name;

View File

@ -12,4 +12,6 @@
!rotation.pdf !rotation.pdf
!simpletype3font.pdf !simpletype3font.pdf
!sizes.pdf !sizes.pdf
!close-path-bug.pdf
!alphatrans.pdf

BIN
test/pdfs/alphatrans.pdf Normal file

Binary file not shown.

View File

@ -0,0 +1,69 @@
%PDF-1.4
1 0 obj
<</Type /Catalog/Outlines 2 0 R/Pages 3 0 R>>
endobj
2 0 obj
<</Type /Outlines/Count 0>>
endobj
3 0 obj
<</Type /Pages/Kids [4 0 R]/Count 1>>
endobj
4 0 obj
<</Type /Page/Parent 3 0 R/MediaBox [0 0 612 792]/Contents 5 0 R/Resources << /ProcSet 6 0 R >>>>
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 1unit 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
<</Size 7/Root 1 0 R>>
startxref
1556
%%EOF

View File

@ -217,5 +217,16 @@
"link": false, "link": false,
"rounds": 1, "rounds": 1,
"type": "eq" "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"
} }
] ]

View File

@ -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 ? // No XMLHttpRequest.response ?
(function checkXMLHttpRequestResponseCompatibility() { (function checkXMLHttpRequestResponseCompatibility() {
var xhrPrototype = XMLHttpRequest.prototype; var xhrPrototype = XMLHttpRequest.prototype;

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset='utf-8'> <meta charset='utf-8'>
<title>andreasgal/pdf.js @ GitHub</title> <title>mozilla/pdf.js @ GitHub</title>
<style type="text/css"> <style type="text/css">
body { body {
@ -31,18 +31,18 @@
</head> </head>
<body> <body>
<a href="http://github.com/andreasgal/pdf.js"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a> <a href="http://github.com/mozilla/pdf.js"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
<div id="container"> <div id="container">
<div class="download"> <div class="download">
<a href="http://github.com/andreasgal/pdf.js/zipball/master"> <a href="http://github.com/mozilla/pdf.js/zipball/master">
<img border="0" width="90" src="http://github.com/images/modules/download/zip.png"></a> <img border="0" width="90" src="http://github.com/images/modules/download/zip.png"></a>
<a href="http://github.com/andreasgal/pdf.js/tarball/master"> <a href="http://github.com/mozilla/pdf.js/tarball/master">
<img border="0" width="90" src="http://github.com/images/modules/download/tar.png"></a> <img border="0" width="90" src="http://github.com/images/modules/download/tar.png"></a>
</div> </div>
<h1><a href="http://github.com/andreasgal/pdf.js">pdf.js</a> <h1><a href="http://github.com/mozilla/pdf.js">pdf.js</a>
<span class="small">by <a href="http://github.com/andreasgal">andreasgal</a></span></h1> <span class="small">by <a href="http://github.com/andreasgal">andreasgal</a></span></h1>
<div class="description"> <div class="description">
@ -69,16 +69,16 @@
<h2>Download</h2> <h2>Download</h2>
<p> <p>
You can download this project in either You can download this project in either
<a href="http://github.com/andreasgal/pdf.js/zipball/master">zip</a> or <a href="http://github.com/mozilla/pdf.js/zipball/master">zip</a> or
<a href="http://github.com/andreasgal/pdf.js/tarball/master">tar</a> formats. <a href="http://github.com/mozilla/pdf.js/tarball/master">tar</a> formats.
</p> </p>
<p>You can also clone the project with <a href="http://git-scm.com">Git</a> <p>You can also clone the project with <a href="http://git-scm.com">Git</a>
by running: by running:
<pre>$ git clone git://github.com/andreasgal/pdf.js</pre> <pre>$ git clone git://github.com/mozilla/pdf.js</pre>
</p> </p>
<div class="footer"> <div class="footer">
get the source code on GitHub : <a href="http://github.com/andreasgal/pdf.js">andreasgal/pdf.js</a> get the source code on GitHub : <a href="http://github.com/mozilla/pdf.js">mozilla/pdf.js</a>
</div> </div>
</div> </div>

View File

@ -4,6 +4,8 @@
<title>Simple pdf.js page viewer</title> <title>Simple pdf.js page viewer</title>
<link rel="stylesheet" href="viewer.css"/> <link rel="stylesheet" href="viewer.css"/>
<script type="text/javascript" src="compatibility.js"></script>
<!-- PDFJSSCRIPT_INCLUDE_BUILD --> <!-- PDFJSSCRIPT_INCLUDE_BUILD -->
<script type="text/javascript" src="../src/core.js"></script> <!-- PDFJSSCRIPT_REMOVE --> <script type="text/javascript" src="../src/core.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="../src/util.js"></script> <!-- PDFJSSCRIPT_REMOVE --> <script type="text/javascript" src="../src/util.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
@ -26,7 +28,6 @@
<script type="text/javascript">PDFJS.workerSrc = '../../src/worker_loader.js';</script> <!-- PDFJSSCRIPT_REMOVE --> <script type="text/javascript">PDFJS.workerSrc = '../../src/worker_loader.js';</script> <!-- PDFJSSCRIPT_REMOVE -->
<script type="text/javascript" src="compatibility.js"></script>
<script type="text/javascript" src="viewer.js"></script> <script type="text/javascript" src="viewer.js"></script>
</head> </head>