Add dependency management for loading images that causes the execution to halt if the dependency isn't satisfied during executing time
This commit is contained in:
parent
e7b636dba4
commit
7e3bbccaae
57
pdf.js
57
pdf.js
@ -861,13 +861,15 @@ var PredictorStream = (function() {
|
|||||||
|
|
||||||
var JpegStreamIR = (function() {
|
var JpegStreamIR = (function() {
|
||||||
function JpegStreamIR(objId, IR) {
|
function JpegStreamIR(objId, IR) {
|
||||||
var src = IR;
|
var src = 'data:image/jpeg;base64,' + window.btoa(IR);
|
||||||
|
|
||||||
// create DOM image
|
// create DOM image
|
||||||
var img = new Image();
|
var img = new Image();
|
||||||
img.onload = (function() {
|
img.onload = (function() {
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
Objects[objId] = this;
|
|
||||||
|
Objects.resolve(objId, this);
|
||||||
|
|
||||||
if (this.onLoad)
|
if (this.onLoad)
|
||||||
this.onLoad();
|
this.onLoad();
|
||||||
}).bind(this);
|
}).bind(this);
|
||||||
@ -925,7 +927,7 @@ var JpegStream = (function() {
|
|||||||
if (isYcckImage(bytes))
|
if (isYcckImage(bytes))
|
||||||
bytes = fixYcckImage(bytes);
|
bytes = fixYcckImage(bytes);
|
||||||
|
|
||||||
this.src = 'data:image/jpeg;base64,' + window.btoa(bytesToString(bytes));
|
this.src = bytesToString(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor.prototype = {
|
constructor.prototype = {
|
||||||
@ -3453,8 +3455,16 @@ var Page = (function() {
|
|||||||
width: this.width,
|
width: this.width,
|
||||||
height: this.height,
|
height: this.height,
|
||||||
rotate: this.rotate });
|
rotate: this.rotate });
|
||||||
gfx.executeIRQueue(this.IRQueue);
|
|
||||||
gfx.endDrawing();
|
var startIdx = 0;
|
||||||
|
var length = this.IRQueue.fnArray.length;
|
||||||
|
var IRQueue = this.IRQueue;
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
console.log("next executeIRQueue", startIdx, length);
|
||||||
|
startIdx = gfx.executeIRQueue(IRQueue, startIdx, next);
|
||||||
|
}
|
||||||
|
next();
|
||||||
},
|
},
|
||||||
rotatePoint: function(x, y) {
|
rotatePoint: function(x, y) {
|
||||||
var rotate = this.rotate;
|
var rotate = this.rotate;
|
||||||
@ -4285,7 +4295,11 @@ var PartialEvaluator = (function() {
|
|||||||
IR: image.getIR()
|
IR: image.getIR()
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Place dependency note in IR queue.
|
// Add the dependency on the image object.
|
||||||
|
fnArray.push("dependency");
|
||||||
|
argsArray.push([ objId ]);
|
||||||
|
|
||||||
|
// The normal fn.
|
||||||
fn = 'paintJpegXObject';
|
fn = 'paintJpegXObject';
|
||||||
args = [ objId, w, h ];
|
args = [ objId, w, h ];
|
||||||
} else {
|
} else {
|
||||||
@ -4864,12 +4878,35 @@ var CanvasGraphics = (function() {
|
|||||||
this.ctx.scale(cw / mediaBox.width, ch / mediaBox.height);
|
this.ctx.scale(cw / mediaBox.width, ch / mediaBox.height);
|
||||||
},
|
},
|
||||||
|
|
||||||
executeIRQueue: function(codeIR) {
|
executeIRQueue: function(codeIR, startIdx, continueCallback) {
|
||||||
var argsArray = codeIR.argsArray;
|
var argsArray = codeIR.argsArray;
|
||||||
var fnArray = codeIR.fnArray;
|
var fnArray = codeIR.fnArray;
|
||||||
for (var i = 0, length = argsArray.length; i < length; i++) {
|
var i = startIdx || 0;
|
||||||
this[fnArray[i]].apply(this, argsArray[i]);
|
var length = argsArray.length;
|
||||||
|
for (i; i < length; i++) {
|
||||||
|
if (fnArray[i] !== "dependency") {
|
||||||
|
this[fnArray[i]].apply(this, argsArray[i]);
|
||||||
|
} else {
|
||||||
|
var deps = argsArray[i];
|
||||||
|
for (var n = 0; n < deps.length; n++) {
|
||||||
|
var depObjId = deps[n];
|
||||||
|
var promise;
|
||||||
|
if (!Objects[depObjId]) {
|
||||||
|
promise = Objects[depObjId] = new Promise();
|
||||||
|
} else {
|
||||||
|
promise = Objects[depObjId];
|
||||||
|
}
|
||||||
|
// If the promise isn't resolved yet, add the continueCallback
|
||||||
|
// to the promise and bail out.
|
||||||
|
if (!promise.isResolved) {
|
||||||
|
console.log("Unresolved object: " + depObjId);
|
||||||
|
promise.then(continueCallback);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return i;
|
||||||
},
|
},
|
||||||
|
|
||||||
endDrawing: function() {
|
endDrawing: function() {
|
||||||
@ -5367,7 +5404,7 @@ var CanvasGraphics = (function() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
paintJpegXObject: function(objId, w, h) {
|
paintJpegXObject: function(objId, w, h) {
|
||||||
var image = Objects[objId];
|
var image = Objects[objId].data;
|
||||||
if (!image) {
|
if (!image) {
|
||||||
error("Dependent image isn't ready yet");
|
error("Dependent image isn't ready yet");
|
||||||
}
|
}
|
||||||
|
54
worker.js
54
worker.js
@ -51,12 +51,27 @@ var WorkerPage = (function() {
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
// This holds a list of objects the IR queue depends on.
|
// This holds a list of objects the IR queue depends on.
|
||||||
var Objects = {};
|
var Objects = {
|
||||||
|
resolve: function(objId, data) {
|
||||||
|
// In case there is a promise already on this object, just resolve it.
|
||||||
|
if (Objects[objId] instanceof Promise) {
|
||||||
|
Objects[objId].resolve(data);
|
||||||
|
} else {
|
||||||
|
Objects[objId] = new Promise(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var Promise = (function() {
|
var Promise = (function() {
|
||||||
function Promise(name) {
|
function Promise(data) {
|
||||||
this.name = name;
|
// If you build a promise and pass in some data it's already resolved.
|
||||||
this.isResolved = false;
|
if (data != null) {
|
||||||
|
this.isResolved = true;
|
||||||
|
this.data = data;
|
||||||
|
} else {
|
||||||
|
this.isResolved = false;
|
||||||
|
}
|
||||||
|
this.callbacks = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
Promise.prototype = {
|
Promise.prototype = {
|
||||||
@ -83,6 +98,7 @@ var Promise = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return Promise;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
var WorkerPDFDoc = (function() {
|
var WorkerPDFDoc = (function() {
|
||||||
@ -95,7 +111,7 @@ var WorkerPDFDoc = (function() {
|
|||||||
|
|
||||||
this.pageCache = [];
|
this.pageCache = [];
|
||||||
|
|
||||||
var useWorker = true;
|
var useWorker = false;
|
||||||
|
|
||||||
if (useWorker) {
|
if (useWorker) {
|
||||||
var worker = new Worker("../worker/boot.js");
|
var worker = new Worker("../worker/boot.js");
|
||||||
@ -125,29 +141,17 @@ var WorkerPDFDoc = (function() {
|
|||||||
font.file.end - font.file.start, fontFileDict);
|
font.file.end - font.file.start, fontFileDict);
|
||||||
font.file = new FlateStream(fontFile);
|
font.file = new FlateStream(fontFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
var imageLoadingDone = function() {
|
|
||||||
var timeStart = new Date();
|
|
||||||
console.log("startRenderingFromPreCompilation:", "numberOfFonts", fonts.length);
|
|
||||||
page.startRenderingFromIRQueue(data.IRQueue, data.fonts, data.images);
|
|
||||||
console.log("RenderingTime", (new Date()) - timeStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
var images = data.images;
|
var images = data.images;
|
||||||
if (images.length != 0) {
|
for (var i = 0; i < images.length; i++) {
|
||||||
// Generate JpegStreams based on IR information and start rendering
|
var image = images[i];
|
||||||
// once the compilation is done.
|
var stream = new JpegStreamIR(image.id, image.IR);
|
||||||
var loader = new ImagesLoader();
|
|
||||||
loader.onLoad = imageLoadingDone;
|
|
||||||
|
|
||||||
for (var i = 0; i < images.length; i++) {
|
|
||||||
var image = images[i];
|
|
||||||
var stream = new JpegStreamIR(image.id, image.IR);
|
|
||||||
loader.bind(stream);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
imageLoadingDone();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var timeStart = new Date();
|
||||||
|
console.log("startRenderingFromPreCompilation:", "numberOfFonts", fonts.length);
|
||||||
|
page.startRenderingFromIRQueue(data.IRQueue, data.fonts, data.images);
|
||||||
|
console.log("RenderingTime", (new Date()) - timeStart);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
if (!useWorker) {
|
if (!useWorker) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user