Merge branch 'master' into disable-textlayer-opt

This commit is contained in:
Artur Adib 2012-01-05 10:19:15 -05:00
commit 4f65198eaa
6 changed files with 98 additions and 20 deletions

View File

@ -398,17 +398,25 @@ var Page = (function PageClosure() {
}
// Once the IRQueue and fonts are loaded, perform the actual rendering.
this.displayReadyPromise.then(function pageDisplayReadyPromise() {
var gfx = new CanvasGraphics(ctx, this.objs, textLayer);
try {
this.display(gfx, callback);
} catch (e) {
if (self.callback)
self.callback(e);
this.displayReadyPromise.then(
function pageDisplayReadyPromise() {
var gfx = new CanvasGraphics(ctx, this.objs, textLayer);
try {
this.display(gfx, callback);
} catch (e) {
if (callback)
callback(e);
else
throw e;
}
}.bind(this),
function pageDisplayReadPromiseError(reason) {
if (callback)
callback(reason);
else
throw e;
throw reason;
}
}.bind(this));
);
}
};
@ -722,8 +730,8 @@ var PDFDoc = (function PDFDocClosure() {
messageHandler.on('page_error', function pdfDocError(data) {
var page = this.pageCache[data.pageNum];
if (page.callback)
page.callback(data.error);
if (page.displayReadyPromise)
page.displayReadyPromise.reject(data.error);
else
throw data.error;
}, this);

View File

@ -206,6 +206,8 @@ var Promise = (function PromiseClosure() {
*/
function Promise(name, data) {
this.name = name;
this.isRejected = false;
this.error = null;
// If you build a promise and pass in some data it's already resolved.
if (data != null) {
this.isResolved = true;
@ -216,6 +218,7 @@ var Promise = (function PromiseClosure() {
this._data = EMPTY_PROMISE;
}
this.callbacks = [];
this.errbacks = [];
};
/**
* Builds a promise that is resolved when all the passed in promises are
@ -282,6 +285,9 @@ var Promise = (function PromiseClosure() {
if (this.isResolved) {
throw 'A Promise can be resolved only once ' + this.name;
}
if (this.isRejected) {
throw 'The Promise was already rejected ' + this.name;
}
this.isResolved = true;
this.data = data || null;
@ -292,7 +298,24 @@ var Promise = (function PromiseClosure() {
}
},
then: function promiseThen(callback) {
reject: function proimseReject(reason) {
if (this.isRejected) {
throw 'A Promise can be rejected only once ' + this.name;
}
if (this.isResolved) {
throw 'The Promise was already resolved ' + this.name;
}
this.isRejected = true;
this.error = reason || null;
var errbacks = this.errbacks;
for (var i = 0, ii = errbacks.length; i < ii; i++) {
errbacks[i].call(null, reason);
}
},
then: function promiseThen(callback, errback) {
if (!callback) {
throw 'Requiring callback' + this.name;
}
@ -301,8 +324,13 @@ var Promise = (function PromiseClosure() {
if (this.isResolved) {
var data = this.data;
callback.call(null, data);
} else if (this.isRejected && errorback) {
var error = this.error;
errback.call(null, error);
} else {
this.callbacks.push(callback);
if (errback)
this.errbacks.push(errback);
}
}
};

View File

@ -14,7 +14,7 @@
}
function subarray(start, end) {
return this.slice(start, end);
return new TypedArray(this.slice(start, end));
}
function setArrayOffset(array, offset) {

View File

@ -330,7 +330,7 @@ canvas {
color: black;
padding: 3px;
margin: 3px;
white-space: pre;
width: 98%;
}
.clearBoth {

View File

@ -114,7 +114,7 @@
</button>
</div>
<div class="clearBoth"></div>
<div id="errorMoreInfo" hidden='true'></div>
<textarea id="errorMoreInfo" hidden='true' readonly="readonly"></textarea>
</div>
<div id="sidebar">

View File

@ -33,6 +33,9 @@ var RenderingQueue = (function RenderingQueueClosure() {
RenderingQueue.prototype = {
enqueueDraw: function RenderingQueueEnqueueDraw(item) {
if (!item.drawingRequired())
return; // as no redraw required, no need for queueing.
if ('rendering' in item)
return; // is already in the queue
@ -346,13 +349,14 @@ var PDFView = {
};
moreInfoButton.removeAttribute('hidden');
lessInfoButton.setAttribute('hidden', 'true');
errorMoreInfo.innerHTML = 'PDF.JS Build: ' + PDFJS.build + '\n';
errorMoreInfo.value = 'PDF.JS Build: ' + PDFJS.build + '\n';
if (moreInfo) {
errorMoreInfo.innerHTML += 'Message: ' + moreInfo.message;
errorMoreInfo.value += 'Message: ' + moreInfo.message;
if (moreInfo.stack)
errorMoreInfo.innerHTML += '\n' + 'Stack: ' + moreInfo.stack;
errorMoreInfo.value += '\n' + 'Stack: ' + moreInfo.stack;
}
errorMoreInfo.rows = errorMoreInfo.value.split('\n').length - 1;
},
progress: function pdfViewProgress(level) {
@ -366,6 +370,7 @@ var PDFView = {
// when page is painted, using the image as thumbnail base
pageView.onAfterDraw = function pdfViewLoadOnAfterDraw() {
thumbnailView.setImage(pageView.canvas);
preDraw();
};
}
@ -759,8 +764,12 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight,
}, 0);
};
this.drawingRequired = function() {
return !div.hasChildNodes();
};
this.draw = function pageviewDraw(callback) {
if (div.hasChildNodes()) {
if (!this.drawingRequired()) {
this.updateStats();
callback();
return;
@ -1011,16 +1020,49 @@ window.addEventListener('unload', function webViewerUnload(evt) {
window.scrollTo(0, 0);
}, true);
/**
* Render the next not yet visible page already such that it is
* hopefully ready once the user scrolls to it.
*/
function preDraw() {
var pages = PDFView.pages;
var visible = PDFView.getVisiblePages();
var last = visible[visible.length - 1];
// PageView.id is the actual page number, which is + 1 compared
// to the index in `pages`. That means, pages[last.id] is the next
// PageView instance.
if (pages[last.id] && pages[last.id].drawingRequired()) {
renderingQueue.enqueueDraw(pages[last.id]);
return;
}
// If there is nothing to draw on the next page, maybe the user
// is scrolling up, so, let's try to render the next page *before*
// the first visible page
if (pages[visible[0].id - 2]) {
renderingQueue.enqueueDraw(pages[visible[0].id - 2]);
}
}
function updateViewarea() {
var visiblePages = PDFView.getVisiblePages();
var pageToDraw;
for (var i = 0; i < visiblePages.length; i++) {
var page = visiblePages[i];
renderingQueue.enqueueDraw(PDFView.pages[page.id - 1]);
var pageObj = PDFView.pages[page.id - 1];
pageToDraw |= pageObj.drawingRequired();
renderingQueue.enqueueDraw(pageObj);
}
if (!visiblePages.length)
return;
// If there is no need to draw a page that is currenlty visible, preDraw the
// next page the user might scroll to.
if (!pageToDraw) {
preDraw();
}
updateViewarea.inProgress = true; // used in "set page"
var currentId = PDFView.page;
var firstPage = visiblePages[0];