From df249da923e9dc8e43fcab96c2ebe1fc4fcab429 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Wed, 2 Oct 2013 09:05:46 -0700 Subject: [PATCH 1/2] Use css to initially scale on zoom. --- extensions/b2g/viewer.html | 53 ++++++++++++++++++++-- web/page_view.js | 91 +++++++++++++++++++++++++++++--------- web/viewer.js | 16 +++++-- 3 files changed, 131 insertions(+), 29 deletions(-) diff --git a/extensions/b2g/viewer.html b/extensions/b2g/viewer.html index d39ed5724..f8a24fc97 100644 --- a/extensions/b2g/viewer.html +++ b/extensions/b2g/viewer.html @@ -102,6 +102,47 @@ limitations under the License. + + +
@@ -148,10 +189,14 @@ limitations under the License.
- - - - + + + + diff --git a/web/page_view.js b/web/page_view.js index 4540f4275..91cb81d32 100644 --- a/web/page_view.js +++ b/web/page_view.js @@ -17,7 +17,7 @@ /* globals RenderingStates, PDFView, PDFHistory, PDFFindBar, PDFJS, mozL10n, CustomStyle, PresentationMode, scrollIntoView, SCROLLBAR_PADDING, CSS_UNITS, UNKNOWN_SCALE, DEFAULT_SCALE, getOutputScale, - TextLayerBuilder, cache, Stats */ + TextLayerBuilder, cache, Stats, USE_ONLY_CSS_ZOOM */ 'use strict'; @@ -36,6 +36,8 @@ var PageView = function pageView(container, id, scale, this.textContent = null; this.textLayer = null; + this.zoomLayer = null; + this.annotationLayer = null; var anchor = document.createElement('a'); @@ -53,42 +55,36 @@ var PageView = function pageView(container, id, scale, this.setPdfPage = function pageViewSetPdfPage(pdfPage) { this.pdfPage = pdfPage; this.pdfPageRotate = pdfPage.rotate; - this.viewport = pdfPage.getViewport(this.scale); + this.viewport = pdfPage.getViewport(this.scale * CSS_UNITS); this.stats = pdfPage.stats; - this.update(); + this.reset(); }; this.destroy = function pageViewDestroy() { - this.update(); + this.zoomLayer = null; + this.reset(); if (this.pdfPage) { this.pdfPage.destroy(); } }; - this.update = function pageViewUpdate(scale, rotation) { + this.reset = function pageViewReset() { if (this.renderTask) { this.renderTask.cancel(); } this.resume = null; this.renderingState = RenderingStates.INITIAL; - if (typeof rotation !== 'undefined') { - this.rotation = rotation; - } - - this.scale = scale || this.scale; - - var totalRotation = (this.rotation + this.pdfPageRotate) % 360; - this.viewport = this.viewport.clone({ - scale: this.scale, - rotation: totalRotation - }); - div.style.width = Math.floor(this.viewport.width) + 'px'; div.style.height = Math.floor(this.viewport.height) + 'px'; - while (div.hasChildNodes()) { - div.removeChild(div.lastChild); + var childNodes = div.childNodes; + for (var i = div.childNodes.length - 1; i >= 0; i--) { + var node = childNodes[i]; + if (this.zoomLayer && this.zoomLayer === node) { + continue; + } + div.removeChild(node); } div.removeAttribute('data-loaded'); @@ -101,6 +97,47 @@ var PageView = function pageView(container, id, scale, div.appendChild(this.loadingIconDiv); }; + this.update = function pageViewUpdate(scale, rotation) { + this.scale = scale || this.scale; + + if (typeof rotation !== 'undefined') { + this.rotation = rotation; + } + + var totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = this.viewport.clone({ + scale: this.scale * CSS_UNITS, + rotation: totalRotation + }); + + if (USE_ONLY_CSS_ZOOM && this.canvas) { + this.cssZoom(this.canvas); + return; + } else if (this.canvas && !this.zoomLayer) { + this.zoomLayer = this.canvas.parentNode; + this.zoomLayer.style.position = 'absolute'; + } + if (this.zoomLayer) { + this.cssZoom(this.zoomLayer.firstChild); + } + this.reset(); + }; + + this.cssZoom = function pageViewRescale(canvas) { + // Need to adjust canvas, canvas wrapepr, and page container. + canvas.style.width = canvas.parentNode.style.width = div.style.width = + Math.floor(this.viewport.width) + 'px'; + canvas.style.height = canvas.parentNode.style.height = div.style.height = + Math.floor(this.viewport.height) + 'px'; + if (this.textLayer) { + var scale = (this.viewport.width / canvas.width); + var cssScale = 'scale(' + scale + ', ' + scale + ')'; + var textLayerDiv = this.textLayer.textLayerDiv; + CustomStyle.setProp('transform', textLayerDiv, cssScale); + CustomStyle.setProp('transformOrigin', textLayerDiv, '0% 0%'); + } + }; + Object.defineProperty(this, 'width', { get: function PageView_getWidth() { return this.viewport.width; @@ -360,8 +397,15 @@ var PageView = function pageView(container, id, scale, var ctx = canvas.getContext('2d'); var outputScale = getOutputScale(ctx); - canvas.width = Math.floor(viewport.width) * outputScale.sx; - canvas.height = Math.floor(viewport.height) * outputScale.sy; + if (USE_ONLY_CSS_ZOOM) { + // Use a scale that will give a 100% width canvas. + outputScale.sx *= 1 / (viewport.scale / CSS_UNITS); + outputScale.sy *= 1 / (viewport.scale / CSS_UNITS); + outputScale.scaled = true; + } + + canvas.width = Math.floor(viewport.width * outputScale.sx); + canvas.height = Math.floor(viewport.height * outputScale.sy); canvas.style.width = Math.floor(viewport.width) + 'px'; canvas.style.height = Math.floor(viewport.height) + 'px'; @@ -421,6 +465,11 @@ var PageView = function pageView(container, id, scale, delete self.loadingIconDiv; } + if (self.zoomLayer) { + div.removeChild(self.zoomLayer); + self.zoomLayer = null; + } + //#if (FIREFOX || MOZCENTRAL) // if (checkIfDocumentFontsUsed && PDFView.pdfDocument.embeddedFontsUsed && // PDFJS.disableFontFace) { diff --git a/web/viewer.js b/web/viewer.js index 94b3290d8..3f92507cf 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -35,6 +35,10 @@ var MAX_SCALE = 4.0; var SETTINGS_MEMORY = 20; var SCALE_SELECT_CONTAINER_PADDING = 8; var SCALE_SELECT_PADDING = 22; +var USE_ONLY_CSS_ZOOM = false; +//#if B2G +//USE_ONLY_CSS_ZOOM = true; +//#endif var RenderingStates = { INITIAL: 0, RUNNING: 1, @@ -181,7 +185,7 @@ var PDFView = { var pages = this.pages; for (var i = 0; i < pages.length; i++) - pages[i].update(val * CSS_UNITS); + pages[i].update(val); if (!noScroll && this.currentScale != val) this.pages[this.page - 1].scrollIntoView(); @@ -212,9 +216,9 @@ var PDFView = { } var pageWidthScale = (container.clientWidth - SCROLLBAR_PADDING) / - currentPage.width * currentPage.scale / CSS_UNITS; + currentPage.width * currentPage.scale; var pageHeightScale = (container.clientHeight - VERTICAL_PADDING) / - currentPage.height * currentPage.scale / CSS_UNITS; + currentPage.height * currentPage.scale; switch (value) { case 'page-actual': scale = 1; @@ -803,7 +807,7 @@ var PDFView = { // Fetch a single page so we can get a viewport that will be the default // viewport for all pages firstPagePromise.then(function(pdfPage) { - var viewport = pdfPage.getViewport(scale || 1.0); + var viewport = pdfPage.getViewport((scale || 1.0) * CSS_UNITS); var pagePromises = []; for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { var viewportClone = viewport.clone(); @@ -1500,6 +1504,10 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) { PDFJS.disableHistory = (hashParams['disableHistory'] === 'true'); } + if ('useOnlyCssZoom' in hashParams) { + USE_ONLY_CSS_ZOOM = (hashParams['useOnlyCssZoom'] === 'true'); + } + //#if !(FIREFOX || MOZCENTRAL) var locale = navigator.language; if ('locale' in hashParams) From 52e429550ce43edbedb6f94795f41478f06dca6f Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Tue, 8 Oct 2013 20:31:49 -0700 Subject: [PATCH 2/2] Simplify the output scale for css zoom. --- web/page_view.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/web/page_view.js b/web/page_view.js index 91cb81d32..c53622ede 100644 --- a/web/page_view.js +++ b/web/page_view.js @@ -398,9 +398,11 @@ var PageView = function pageView(container, id, scale, var outputScale = getOutputScale(ctx); if (USE_ONLY_CSS_ZOOM) { - // Use a scale that will give a 100% width canvas. - outputScale.sx *= 1 / (viewport.scale / CSS_UNITS); - outputScale.sy *= 1 / (viewport.scale / CSS_UNITS); + 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; }