Merge pull request #2110 from arturadib/fragments

Use document fragment in text layer
This commit is contained in:
Brendan Dahl 2012-09-19 11:17:26 -07:00
commit 7e648af070

View File

@ -227,9 +227,11 @@ var PDFView = {
isFullscreen: false, isFullscreen: false,
previousScale: null, previousScale: null,
pageRotation: 0, pageRotation: 0,
lastScroll: 0,
// called once when the document is loaded // called once when the document is loaded
initialize: function pdfViewInitialize() { initialize: function pdfViewInitialize() {
var self = this;
var container = this.container = document.getElementById('viewerContainer'); var container = this.container = document.getElementById('viewerContainer');
this.pageViewScroll = {}; this.pageViewScroll = {};
this.watchScroll(container, this.pageViewScroll, updateViewarea); this.watchScroll(container, this.pageViewScroll, updateViewarea);
@ -241,6 +243,9 @@ var PDFView = {
this.renderHighestPriority.bind(this)); this.renderHighestPriority.bind(this));
this.initialized = true; this.initialized = true;
container.addEventListener('scroll', function() {
self.lastScroll = Date.now();
}, false);
}, },
// Helper function to keep track whether a div was scrolled up or down and // Helper function to keep track whether a div was scrolled up or down and
@ -1816,6 +1821,7 @@ var CustomStyle = (function CustomStyleClosure() {
})(); })();
var TextLayerBuilder = function textLayerBuilder(textLayerDiv) { var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
var textLayerFrag = document.createDocumentFragment();
this.textLayerDiv = textLayerDiv; this.textLayerDiv = textLayerDiv;
this.beginLayout = function textLayerBuilderBeginLayout() { this.beginLayout = function textLayerBuilderBeginLayout() {
@ -1823,28 +1829,21 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
this.textLayerQueue = []; this.textLayerQueue = [];
}; };
this.endLayout = function textLayerBuilderEndLayout() { this.renderLayer = function textLayerBuilderRenderLayer() {
var self = this; var self = this;
var textDivs = this.textDivs; var textDivs = this.textDivs;
var textLayerDiv = this.textLayerDiv; var textLayerDiv = this.textLayerDiv;
var renderTimer = null;
var renderingDone = false;
var renderInterval = 0;
var resumeInterval = 500; // in ms
var canvas = document.createElement('canvas'); var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
// Render the text layer, one div at a time // No point in rendering so many divs as it'd make the browser unusable
function renderTextLayer() { // even after the divs are rendered
if (textDivs.length === 0) { if (textDivs.length > 100000)
clearInterval(renderTimer); return;
renderingDone = true;
self.textLayerDiv = textLayerDiv = canvas = ctx = null; while (textDivs.length > 0) {
return;
}
var textDiv = textDivs.shift(); var textDiv = textDivs.shift();
textLayerDiv.appendChild(textDiv); textLayerFrag.appendChild(textDiv);
ctx.font = textDiv.style.fontSize + ' ' + textDiv.style.fontFamily; ctx.font = textDiv.style.fontSize + ' ' + textDiv.style.fontFamily;
var width = ctx.measureText(textDiv.textContent).width; var width = ctx.measureText(textDiv.textContent).width;
@ -1857,28 +1856,26 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
CustomStyle.setProp('transformOrigin' , textDiv, '0% 0%'); CustomStyle.setProp('transformOrigin' , textDiv, '0% 0%');
} }
} }
renderTimer = setInterval(renderTextLayer, renderInterval);
// Stop rendering when user scrolls. Resume after XXX milliseconds textLayerDiv.appendChild(textLayerFrag);
// of no scroll events };
var scrollTimer = null;
function textLayerOnScroll() {
if (renderingDone) {
window.removeEventListener('scroll', textLayerOnScroll, false);
return;
}
// Immediately pause rendering this.endLayout = function textLayerBuilderEndLayout() {
clearInterval(renderTimer); // Schedule renderLayout() if user has been scrolling, otherwise
// run it right away
clearTimeout(scrollTimer); var kRenderDelay = 200; // in ms
scrollTimer = setTimeout(function textLayerScrollTimer() { var self = this;
// Resume rendering if (Date.now() - PDFView.lastScroll > kRenderDelay) {
renderTimer = setInterval(renderTextLayer, renderInterval); // Render right away
}, resumeInterval); this.renderLayer();
} // textLayerOnScroll } else {
// Schedule
window.addEventListener('scroll', textLayerOnScroll, false); if (this.renderTimer)
clearTimeout(this.renderTimer);
this.renderTimer = setTimeout(function() {
self.endLayout();
}, kRenderDelay);
}
}; // endLayout }; // endLayout
this.appendText = function textLayerBuilderAppendText(text, this.appendText = function textLayerBuilderAppendText(text,