|
|
|
@ -93,9 +93,11 @@ var PDFPageView = (function PDFPageViewClosure() {
@@ -93,9 +93,11 @@ var PDFPageView = (function PDFPageViewClosure() {
|
|
|
|
|
this.textLayerFactory = textLayerFactory; |
|
|
|
|
this.annotationLayerFactory = annotationLayerFactory; |
|
|
|
|
|
|
|
|
|
this.renderTask = null; |
|
|
|
|
this.paintTask = null; |
|
|
|
|
this.paintedViewport = null; |
|
|
|
|
this.renderingState = RenderingStates.INITIAL; |
|
|
|
|
this.resume = null; |
|
|
|
|
this.error = null; |
|
|
|
|
|
|
|
|
|
this.onBeforeDraw = null; |
|
|
|
|
this.onAfterDraw = null; |
|
|
|
@ -171,6 +173,9 @@ var PDFPageView = (function PDFPageViewClosure() {
@@ -171,6 +173,9 @@ var PDFPageView = (function PDFPageViewClosure() {
|
|
|
|
|
this.canvas.height = 0; |
|
|
|
|
delete this.canvas; |
|
|
|
|
} |
|
|
|
|
if (!currentZoomLayerNode) { |
|
|
|
|
this.paintedViewport = null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.loadingIconDiv = document.createElement('div'); |
|
|
|
|
this.loadingIconDiv.className = 'loadingIcon'; |
|
|
|
@ -224,9 +229,9 @@ var PDFPageView = (function PDFPageViewClosure() {
@@ -224,9 +229,9 @@ var PDFPageView = (function PDFPageViewClosure() {
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
cancelRendering: function PDFPageView_cancelRendering() { |
|
|
|
|
if (this.renderTask) { |
|
|
|
|
this.renderTask.cancel(); |
|
|
|
|
this.renderTask = null; |
|
|
|
|
if (this.paintTask) { |
|
|
|
|
this.paintTask.cancel(); |
|
|
|
|
this.paintTask = null; |
|
|
|
|
} |
|
|
|
|
this.renderingState = RenderingStates.INITIAL; |
|
|
|
|
this.resume = null; |
|
|
|
@ -258,7 +263,8 @@ var PDFPageView = (function PDFPageViewClosure() {
@@ -258,7 +263,8 @@ var PDFPageView = (function PDFPageViewClosure() {
|
|
|
|
|
canvas.style.height = canvas.parentNode.style.height = div.style.height = |
|
|
|
|
Math.floor(height) + 'px'; |
|
|
|
|
// The canvas may have been originally rotated, rotate relative to that.
|
|
|
|
|
var relativeRotation = this.viewport.rotation - canvas._viewport.rotation; |
|
|
|
|
var relativeRotation = this.viewport.rotation - |
|
|
|
|
this.paintedViewport.rotation; |
|
|
|
|
var absRotation = Math.abs(relativeRotation); |
|
|
|
|
var scaleX = 1, scaleY = 1; |
|
|
|
|
if (absRotation === 90 || absRotation === 270) { |
|
|
|
@ -337,6 +343,7 @@ var PDFPageView = (function PDFPageViewClosure() {
@@ -337,6 +343,7 @@ var PDFPageView = (function PDFPageViewClosure() {
|
|
|
|
|
|
|
|
|
|
this.renderingState = RenderingStates.RUNNING; |
|
|
|
|
|
|
|
|
|
var self = this; |
|
|
|
|
var pdfPage = this.pdfPage; |
|
|
|
|
var viewport = this.viewport; |
|
|
|
|
var div = this.div; |
|
|
|
@ -347,62 +354,12 @@ var PDFPageView = (function PDFPageViewClosure() {
@@ -347,62 +354,12 @@ var PDFPageView = (function PDFPageViewClosure() {
|
|
|
|
|
canvasWrapper.style.height = div.style.height; |
|
|
|
|
canvasWrapper.classList.add('canvasWrapper'); |
|
|
|
|
|
|
|
|
|
var canvas = document.createElement('canvas'); |
|
|
|
|
canvas.id = 'page' + this.id; |
|
|
|
|
// Keep the canvas hidden until the first draw callback, or until drawing
|
|
|
|
|
// is complete when `!this.renderingQueue`, to prevent black flickering.
|
|
|
|
|
canvas.setAttribute('hidden', 'hidden'); |
|
|
|
|
var isCanvasHidden = true; |
|
|
|
|
|
|
|
|
|
canvasWrapper.appendChild(canvas); |
|
|
|
|
if (this.annotationLayer && this.annotationLayer.div) { |
|
|
|
|
// annotationLayer needs to stay on top
|
|
|
|
|
div.insertBefore(canvasWrapper, this.annotationLayer.div); |
|
|
|
|
} else { |
|
|
|
|
div.appendChild(canvasWrapper); |
|
|
|
|
} |
|
|
|
|
this.canvas = canvas; |
|
|
|
|
|
|
|
|
|
if (typeof PDFJSDev === 'undefined' || |
|
|
|
|
PDFJSDev.test('MOZCENTRAL || FIREFOX || GENERIC')) { |
|
|
|
|
canvas.mozOpaque = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var ctx = canvas.getContext('2d', {alpha: false}); |
|
|
|
|
var outputScale = getOutputScale(ctx); |
|
|
|
|
this.outputScale = outputScale; |
|
|
|
|
|
|
|
|
|
if (pdfjsLib.PDFJS.useOnlyCssZoom) { |
|
|
|
|
var actualSizeViewport = viewport.clone({scale: CSS_UNITS}); |
|
|
|
|
// Use a scale that will make the canvas be the original intended size
|
|
|
|
|
// of the page.
|
|
|
|
|
outputScale.sx *= actualSizeViewport.width / viewport.width; |
|
|
|
|
outputScale.sy *= actualSizeViewport.height / viewport.height; |
|
|
|
|
outputScale.scaled = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pdfjsLib.PDFJS.maxCanvasPixels > 0) { |
|
|
|
|
var pixelsInViewport = viewport.width * viewport.height; |
|
|
|
|
var maxScale = |
|
|
|
|
Math.sqrt(pdfjsLib.PDFJS.maxCanvasPixels / pixelsInViewport); |
|
|
|
|
if (outputScale.sx > maxScale || outputScale.sy > maxScale) { |
|
|
|
|
outputScale.sx = maxScale; |
|
|
|
|
outputScale.sy = maxScale; |
|
|
|
|
outputScale.scaled = true; |
|
|
|
|
this.hasRestrictedScaling = true; |
|
|
|
|
} else { |
|
|
|
|
this.hasRestrictedScaling = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var sfx = approximateFraction(outputScale.sx); |
|
|
|
|
var sfy = approximateFraction(outputScale.sy); |
|
|
|
|
canvas.width = roundToDivide(viewport.width * outputScale.sx, sfx[0]); |
|
|
|
|
canvas.height = roundToDivide(viewport.height * outputScale.sy, sfy[0]); |
|
|
|
|
canvas.style.width = roundToDivide(viewport.width, sfx[1]) + 'px'; |
|
|
|
|
canvas.style.height = roundToDivide(viewport.height, sfy[1]) + 'px'; |
|
|
|
|
// Add the viewport so it's known what it was originally drawn with.
|
|
|
|
|
canvas._viewport = viewport; |
|
|
|
|
|
|
|
|
|
var textLayerDiv = null; |
|
|
|
|
var textLayer = null; |
|
|
|
@ -424,35 +381,36 @@ var PDFPageView = (function PDFPageViewClosure() {
@@ -424,35 +381,36 @@ var PDFPageView = (function PDFPageViewClosure() {
|
|
|
|
|
} |
|
|
|
|
this.textLayer = textLayer; |
|
|
|
|
|
|
|
|
|
var resolveRenderPromise, rejectRenderPromise; |
|
|
|
|
var promise = new Promise(function (resolve, reject) { |
|
|
|
|
resolveRenderPromise = resolve; |
|
|
|
|
rejectRenderPromise = reject; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// Rendering area
|
|
|
|
|
var renderContinueCallback = null; |
|
|
|
|
if (this.renderingQueue) { |
|
|
|
|
renderContinueCallback = function renderContinueCallback(cont) { |
|
|
|
|
if (!self.renderingQueue.isHighestPriority(self)) { |
|
|
|
|
self.renderingState = RenderingStates.PAUSED; |
|
|
|
|
self.resume = function resumeCallback() { |
|
|
|
|
self.renderingState = RenderingStates.RUNNING; |
|
|
|
|
cont(); |
|
|
|
|
}; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
cont(); |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var self = this; |
|
|
|
|
function pageViewDrawCallback(error) { |
|
|
|
|
// The renderTask may have been replaced by a new one, so only remove
|
|
|
|
|
// the reference to the renderTask if it matches the one that is
|
|
|
|
|
var finishPaintTask = function finishPaintTask(error) { |
|
|
|
|
// The paintTask may have been replaced by a new one, so only remove
|
|
|
|
|
// the reference to the paintTask if it matches the one that is
|
|
|
|
|
// triggering this callback.
|
|
|
|
|
if (renderTask === self.renderTask) { |
|
|
|
|
self.renderTask = null; |
|
|
|
|
if (paintTask === self.paintTask) { |
|
|
|
|
self.paintTask = null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (error === 'cancelled') { |
|
|
|
|
rejectRenderPromise(error); |
|
|
|
|
self.error = null; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self.renderingState = RenderingStates.FINISHED; |
|
|
|
|
|
|
|
|
|
if (isCanvasHidden) { |
|
|
|
|
self.canvas.removeAttribute('hidden'); |
|
|
|
|
isCanvasHidden = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (self.loadingIconDiv) { |
|
|
|
|
div.removeChild(self.loadingIconDiv); |
|
|
|
|
delete self.loadingIconDiv; |
|
|
|
@ -484,33 +442,121 @@ var PDFPageView = (function PDFPageViewClosure() {
@@ -484,33 +442,121 @@ var PDFPageView = (function PDFPageViewClosure() {
|
|
|
|
|
pageNumber: self.id, |
|
|
|
|
cssTransform: false, |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
if (!error) { |
|
|
|
|
resolveRenderPromise(undefined); |
|
|
|
|
} else { |
|
|
|
|
rejectRenderPromise(error); |
|
|
|
|
var paintTask = this.paintOnCanvas(canvasWrapper); |
|
|
|
|
paintTask.onRenderContinue = renderContinueCallback; |
|
|
|
|
this.paintTask = paintTask; |
|
|
|
|
|
|
|
|
|
var resultPromise = paintTask.promise.then(function () { |
|
|
|
|
finishPaintTask(null); |
|
|
|
|
if (textLayer) { |
|
|
|
|
pdfPage.getTextContent({ |
|
|
|
|
normalizeWhitespace: true, |
|
|
|
|
}).then(function textContentResolved(textContent) { |
|
|
|
|
textLayer.setTextContent(textContent); |
|
|
|
|
textLayer.render(TEXT_LAYER_RENDER_DELAY); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}, function (reason) { |
|
|
|
|
finishPaintTask(reason); |
|
|
|
|
throw reason; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
if (this.annotationLayerFactory) { |
|
|
|
|
if (!this.annotationLayer) { |
|
|
|
|
this.annotationLayer = this.annotationLayerFactory. |
|
|
|
|
createAnnotationLayerBuilder(div, pdfPage, |
|
|
|
|
this.renderInteractiveForms); |
|
|
|
|
} |
|
|
|
|
this.annotationLayer.render(this.viewport, 'display'); |
|
|
|
|
} |
|
|
|
|
div.setAttribute('data-loaded', true); |
|
|
|
|
|
|
|
|
|
var renderContinueCallback = null; |
|
|
|
|
if (this.renderingQueue) { |
|
|
|
|
renderContinueCallback = function renderContinueCallback(cont) { |
|
|
|
|
if (!self.renderingQueue.isHighestPriority(self)) { |
|
|
|
|
self.renderingState = RenderingStates.PAUSED; |
|
|
|
|
self.resume = function resumeCallback() { |
|
|
|
|
self.renderingState = RenderingStates.RUNNING; |
|
|
|
|
if (this.onBeforeDraw) { |
|
|
|
|
this.onBeforeDraw(); |
|
|
|
|
} |
|
|
|
|
return resultPromise; |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
paintOnCanvas: function (canvasWrapper) { |
|
|
|
|
var resolveRenderPromise, rejectRenderPromise; |
|
|
|
|
var promise = new Promise(function (resolve, reject) { |
|
|
|
|
resolveRenderPromise = resolve; |
|
|
|
|
rejectRenderPromise = reject; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
var result = { |
|
|
|
|
promise: promise, |
|
|
|
|
onRenderContinue: function (cont) { |
|
|
|
|
cont(); |
|
|
|
|
}; |
|
|
|
|
return; |
|
|
|
|
}, |
|
|
|
|
cancel: function () { |
|
|
|
|
renderTask.cancel(); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var self = this; |
|
|
|
|
var pdfPage = this.pdfPage; |
|
|
|
|
var viewport = this.viewport; |
|
|
|
|
var canvas = document.createElement('canvas'); |
|
|
|
|
canvas.id = 'page' + this.id; |
|
|
|
|
// Keep the canvas hidden until the first draw callback, or until drawing
|
|
|
|
|
// is complete when `!this.renderingQueue`, to prevent black flickering.
|
|
|
|
|
canvas.setAttribute('hidden', 'hidden'); |
|
|
|
|
var isCanvasHidden = true; |
|
|
|
|
var showCanvas = function () { |
|
|
|
|
if (isCanvasHidden) { |
|
|
|
|
self.canvas.removeAttribute('hidden'); |
|
|
|
|
canvas.removeAttribute('hidden'); |
|
|
|
|
isCanvasHidden = false; |
|
|
|
|
} |
|
|
|
|
cont(); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
canvasWrapper.appendChild(canvas); |
|
|
|
|
this.canvas = canvas; |
|
|
|
|
|
|
|
|
|
if (typeof PDFJSDev === 'undefined' || |
|
|
|
|
PDFJSDev.test('MOZCENTRAL || FIREFOX || GENERIC')) { |
|
|
|
|
canvas.mozOpaque = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var ctx = canvas.getContext('2d', {alpha: false}); |
|
|
|
|
var outputScale = getOutputScale(ctx); |
|
|
|
|
this.outputScale = outputScale; |
|
|
|
|
|
|
|
|
|
if (pdfjsLib.PDFJS.useOnlyCssZoom) { |
|
|
|
|
var actualSizeViewport = viewport.clone({scale: CSS_UNITS}); |
|
|
|
|
// Use a scale that will make the canvas be the original intended size
|
|
|
|
|
// of the page.
|
|
|
|
|
outputScale.sx *= actualSizeViewport.width / viewport.width; |
|
|
|
|
outputScale.sy *= actualSizeViewport.height / viewport.height; |
|
|
|
|
outputScale.scaled = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pdfjsLib.PDFJS.maxCanvasPixels > 0) { |
|
|
|
|
var pixelsInViewport = viewport.width * viewport.height; |
|
|
|
|
var maxScale = |
|
|
|
|
Math.sqrt(pdfjsLib.PDFJS.maxCanvasPixels / pixelsInViewport); |
|
|
|
|
if (outputScale.sx > maxScale || outputScale.sy > maxScale) { |
|
|
|
|
outputScale.sx = maxScale; |
|
|
|
|
outputScale.sy = maxScale; |
|
|
|
|
outputScale.scaled = true; |
|
|
|
|
this.hasRestrictedScaling = true; |
|
|
|
|
} else { |
|
|
|
|
this.hasRestrictedScaling = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var sfx = approximateFraction(outputScale.sx); |
|
|
|
|
var sfy = approximateFraction(outputScale.sy); |
|
|
|
|
canvas.width = roundToDivide(viewport.width * outputScale.sx, sfx[0]); |
|
|
|
|
canvas.height = roundToDivide(viewport.height * outputScale.sy, sfy[0]); |
|
|
|
|
canvas.style.width = roundToDivide(viewport.width, sfx[1]) + 'px'; |
|
|
|
|
canvas.style.height = roundToDivide(viewport.height, sfy[1]) + 'px'; |
|
|
|
|
// Add the viewport so it's known what it was originally drawn with.
|
|
|
|
|
this.paintedViewport = viewport; |
|
|
|
|
|
|
|
|
|
// Rendering area
|
|
|
|
|
var transform = !outputScale.scaled ? null : |
|
|
|
|
[outputScale.sx, 0, 0, outputScale.sy, 0, 0]; |
|
|
|
|
var renderContext = { |
|
|
|
@ -520,40 +566,28 @@ var PDFPageView = (function PDFPageViewClosure() {
@@ -520,40 +566,28 @@ var PDFPageView = (function PDFPageViewClosure() {
|
|
|
|
|
renderInteractiveForms: this.renderInteractiveForms, |
|
|
|
|
// intent: 'default', // === 'display'
|
|
|
|
|
}; |
|
|
|
|
var renderTask = this.renderTask = this.pdfPage.render(renderContext); |
|
|
|
|
renderTask.onContinue = renderContinueCallback; |
|
|
|
|
var renderTask = this.pdfPage.render(renderContext); |
|
|
|
|
renderTask.onContinue = function (cont) { |
|
|
|
|
showCanvas(); |
|
|
|
|
if (result.onRenderContinue) { |
|
|
|
|
result.onRenderContinue(cont); |
|
|
|
|
} else { |
|
|
|
|
cont(); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
this.renderTask.promise.then( |
|
|
|
|
renderTask.promise.then( |
|
|
|
|
function pdfPageRenderCallback() { |
|
|
|
|
pageViewDrawCallback(null); |
|
|
|
|
if (textLayer) { |
|
|
|
|
self.pdfPage.getTextContent({ |
|
|
|
|
normalizeWhitespace: true, |
|
|
|
|
}).then(function textContentResolved(textContent) { |
|
|
|
|
textLayer.setTextContent(textContent); |
|
|
|
|
textLayer.render(TEXT_LAYER_RENDER_DELAY); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
showCanvas(); |
|
|
|
|
resolveRenderPromise(undefined); |
|
|
|
|
}, |
|
|
|
|
function pdfPageRenderError(error) { |
|
|
|
|
pageViewDrawCallback(error); |
|
|
|
|
showCanvas(); |
|
|
|
|
rejectRenderPromise(error); |
|
|
|
|
} |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
if (this.annotationLayerFactory) { |
|
|
|
|
if (!this.annotationLayer) { |
|
|
|
|
this.annotationLayer = this.annotationLayerFactory. |
|
|
|
|
createAnnotationLayerBuilder(div, this.pdfPage, |
|
|
|
|
this.renderInteractiveForms); |
|
|
|
|
} |
|
|
|
|
this.annotationLayer.render(this.viewport, 'display'); |
|
|
|
|
} |
|
|
|
|
div.setAttribute('data-loaded', true); |
|
|
|
|
|
|
|
|
|
if (self.onBeforeDraw) { |
|
|
|
|
self.onBeforeDraw(); |
|
|
|
|
} |
|
|
|
|
return promise; |
|
|
|
|
return result; |
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|