/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ /* Copyright 2012 Mozilla Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 'use strict'; var CLEANUP_TIMEOUT = 30000; var RenderingStates = { INITIAL: 0, RUNNING: 1, PAUSED: 2, FINISHED: 3 }; /** * Controls rendering of the views for pages and thumbnails. * @class */ var PDFRenderingQueue = (function PDFRenderingQueueClosure() { /** * @constructs */ function PDFRenderingQueue() { this.pdfViewer = null; this.pdfThumbnailViewer = null; this.onIdle = null; this.highestPriorityPage = null; this.idleTimeout = null; this.printing = false; this.isThumbnailViewEnabled = false; } PDFRenderingQueue.prototype = /** @lends PDFRenderingQueue.prototype */ { /** * @param {PDFViewer} pdfViewer */ setViewer: function PDFRenderingQueue_setViewer(pdfViewer) { this.pdfViewer = pdfViewer; }, /** * @param {PDFThumbnailViewer} pdfThumbnailViewer */ setThumbnailViewer: function PDFRenderingQueue_setThumbnailViewer(pdfThumbnailViewer) { this.pdfThumbnailViewer = pdfThumbnailViewer; }, /** * @param {IRenderableView} view * @returns {boolean} */ isHighestPriority: function PDFRenderingQueue_isHighestPriority(view) { return this.highestPriorityPage === view.renderingId; }, renderHighestPriority: function PDFRenderingQueue_renderHighestPriority(currentlyVisiblePages) { if (this.idleTimeout) { clearTimeout(this.idleTimeout); this.idleTimeout = null; } // Pages have a higher priority than thumbnails, so check them first. if (this.pdfViewer.forceRendering(currentlyVisiblePages)) { return; } // No pages needed rendering so check thumbnails. if (this.pdfThumbnailViewer && this.isThumbnailViewEnabled) { if (this.pdfThumbnailViewer.forceRendering()) { return; } } if (this.printing) { // If printing is currently ongoing do not reschedule cleanup. return; } if (this.onIdle) { this.idleTimeout = setTimeout(this.onIdle.bind(this), CLEANUP_TIMEOUT); } }, getHighestPriority: function PDFRenderingQueue_getHighestPriority(visible, views, scrolledDown) { // The state has changed figure out which page has the highest priority to // render next (if any). // Priority: // 1 visible pages // 2 if last scrolled down page after the visible pages // 2 if last scrolled up page before the visible pages var visibleViews = visible.views; var numVisible = visibleViews.length; if (numVisible === 0) { return false; } for (var i = 0; i < numVisible; ++i) { var view = visibleViews[i].view; if (!this.isViewFinished(view)) { return view; } } // All the visible views have rendered, try to render next/previous pages. if (scrolledDown) { var nextPageIndex = visible.last.id; // ID's start at 1 so no need to add 1. if (views[nextPageIndex] && !this.isViewFinished(views[nextPageIndex])) { return views[nextPageIndex]; } } else { var previousPageIndex = visible.first.id - 2; if (views[previousPageIndex] && !this.isViewFinished(views[previousPageIndex])) { return views[previousPageIndex]; } } // Everything that needs to be rendered has been. return null; }, /** * @param {IRenderableView} view * @returns {boolean} */ isViewFinished: function PDFRenderingQueue_isViewFinished(view) { return view.renderingState === RenderingStates.FINISHED; }, /** * Render a page or thumbnail view. This calls the appropriate function * based on the views state. If the view is already rendered it will return * false. * @param {IRenderableView} view */ renderView: function PDFRenderingQueue_renderView(view) { var state = view.renderingState; switch (state) { case RenderingStates.FINISHED: return false; case RenderingStates.PAUSED: this.highestPriorityPage = view.renderingId; view.resume(); break; case RenderingStates.RUNNING: this.highestPriorityPage = view.renderingId; break; case RenderingStates.INITIAL: this.highestPriorityPage = view.renderingId; var continueRendering = function () { this.renderHighestPriority(); }.bind(this); view.draw().then(continueRendering, continueRendering); break; } return true; }, }; return PDFRenderingQueue; })();