From 71ff8ee5865a077f0235ec0065d87b3c61f9c7a2 Mon Sep 17 00:00:00 2001 From: Julian Viereck <julian.viereck@gmail.com> Date: Mon, 5 Sep 2011 17:42:58 -0700 Subject: [PATCH] backup --- pdf.js | 60 ++++++++++++++----------- web/viewer.html | 1 + worker.js | 32 ++++++++++++- worker/boot.js | 63 ++++++++++++++++++++++++++ worker/console.js | 2 +- worker/message_handler.js | 23 ++++++++++ worker/pdf.js | 95 --------------------------------------- 7 files changed, 154 insertions(+), 122 deletions(-) create mode 100644 worker/boot.js create mode 100644 worker/message_handler.js delete mode 100644 worker/pdf.js diff --git a/pdf.js b/pdf.js index bc75e8b52..39d36780f 100644 --- a/pdf.js +++ b/pdf.js @@ -3358,18 +3358,48 @@ var Page = (function() { }, startRendering: function(canvasCtx, continuation) { + var gfx = new CanvasGraphics(canvasCtx); + + // If there is already some code to render, then use it directly. + if (this.code) { + this.display(gfx); + return; + } + var self = this; var stats = self.stats; stats.compile = stats.fonts = stats.render = 0; - - var gfx = new CanvasGraphics(canvasCtx); + var fonts = []; var images = new ImagesLoader(); - this.compile(gfx, fonts, images); + var preCompilation = this.preCompile(gfx, fonts, images); stats.compile = Date.now(); + + // Make a copy of the necessary datat to build a font later. The `font` + // object will be sent to the main thread later on. + var fontsBackup = fonts; + fonts = []; + for (var i = 0; i < fontsBackup.length; i++) { + var orgFont = fontsBackup[i]; + + var font = { + name: orgFont.name, + file: orgFont.file, + properties: orgFont.properties + } + fonts.push(font); + } + this.startRenderingFromPreCompilation(gfx, preCompilation, fonts, images, continuation); + }, + + startRenderingFromPreCompilation: function(gfx, preCompilation, fonts, images, continuation) { + var self = this; + var displayContinuation = function() { + self.code = gfx.postCompile(preCompilation); + // Always defer call to display() to work around bug in // Firefox error reporting from XHR callbacks. setTimeout(function() { @@ -3384,22 +3414,6 @@ var Page = (function() { }); }; - // Make a copy of the necessary datat to build a font later. The `font` - // object will be sent to the main thread later on. - var fontsBackup = fonts; - fonts = []; - for (var i = 0; i < fontsBackup.length; i++) { - var orgFont = fontsBackup[i]; - var orgFontObj = orgFont.fontObj; - - var font = { - name: orgFont.name, - file: orgFont.file, - properties: orgFont.properties - } - fonts.push(font); - } - this.ensureFonts(fonts, function() { images.notifyOnLoad(function() { stats.images = Date.now(); @@ -3424,12 +3438,8 @@ var Page = (function() { content[i] = xref.fetchIfRef(content[i]); content = new StreamsSequenceStream(content); } - return gfx.preCompile(content, xref, resources, fonts, images); - }, - - compile: function(gfx, fonts, images) { - var preCompilation = this.preCompile(gfx, fonts, images); - this.code = gfx.postCompile(preCompilation); + return gfx.preCompile(content, xref, resources, fonts, images, + this.pageNumber + "_"); }, ensureFonts: function(fonts, callback) { diff --git a/web/viewer.html b/web/viewer.html index d236f840e..871db8ce6 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -12,6 +12,7 @@ <script type="text/javascript" src="../glyphlist.js"></script> <script type="text/javascript" src="../metrics.js"></script> <script type="text/javascript" src="../worker.js"></script> + <script type="text/javascript" src="../worker/message_handler.js"></script> </head> <body> diff --git a/worker.js b/worker.js index d26735005..61f8c0934 100644 --- a/worker.js +++ b/worker.js @@ -25,8 +25,21 @@ var WorkerPage = (function() { }, startRendering: function(ctx, callback, errback) { + this.ctx = ctx; + this.callback = callback; // TODO: Place the worker magic HERE. - this.page.startRendering(ctx, callback, errback); + // this.page.startRendering(ctx, callback, errback); + + this.workerPDF.startRendering(this) + }, + + startRenderingFromPreCompilation: function(preCompilation, fonts, images) { + var gfx = new CanvasGraphics(this.ctx); + + // TODO: Add proper handling for images loaded by the worker. + var images = new ImagesLoader(); + + this.page.startRenderingFromPreCompilation(gfx, preCompilation, fonts, images, this.callback); }, getLinks: function() { @@ -46,6 +59,19 @@ var WorkerPDFDoc = (function() { this.catalog = this.pdf.catalog; this.pageCache = []; + + this.worker = new Worker("worker/boot.js"); + this.handler = new MessageHandler({ + "page": function(data) { + var pageNum = data.pageNum; + var page = this.pageCache[pageNum]; + + page.startRenderingFromPreCompilation(data.preCompilation, data.fonts, data.images); + } + }, this.worker.postMessage, this); + this.worker.onmessage = this.handler.onMessage; + + this.handler.send("doc", data); } constructor.prototype = { @@ -53,6 +79,10 @@ var WorkerPDFDoc = (function() { return this.pdf.numPages; }, + startRendering: function(page) { + this.handler.send("page", page.page.pageNumber); + }, + getPage: function(n) { if (this.pageCache[n]) { return this.pageCache[n]; diff --git a/worker/boot.js b/worker/boot.js new file mode 100644 index 000000000..4ec65a1de --- /dev/null +++ b/worker/boot.js @@ -0,0 +1,63 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ + +'use strict'; + +// +importScripts('console.js'); +importScripts('event_handler.js'); +importScripts('../pdf.js'); +importScripts('../fonts.js'); +importScripts('../crypto.js'); +importScripts('../glyphlist.js'); + +// Listen for messages from the main thread. +var pdfDoc = null; + +var handler = new MessageHandler({ + "doc": function(data) { + pdfDocument = new PDFDoc(new Stream(data)); + console.log("setup pdfDoc"); + }, + + "page": function(pageNum) { + pageNum = parseInt(pageNum); + console.log("about to process page", pageNum); + + var page = pdfDocument.getPage(pageNum); + + // The following code does quite the same as Page.prototype.startRendering, + // but stops at one point and sends the result back to the main thread. + var gfx = new CanvasGraphics(canvasCtx); + var fonts = []; + // TODO: Figure out how image loading is handled inside the worker. + var images = new ImagesLoader(); + + // Pre compile the pdf page and fetch the fonts/images. + var preCompilation = page.preCompile(gfx, fonts, images); + + // Extract the minimum of font data that is required to build all required + // font stuff on the main thread. + var fontsMin = []; + for (var i = 0; i < fonts.length; i++) { + var font = fonts[i]; + + fontsMin.push({ + name: orgFont.name, + file: orgFont.file, + properties: orgFont.properties + }); + } + + // TODO: Handle images here. + + handler.send("page", { + pageNum: pageNum, + fonts: fontsMin, + images: [], + preCompilation: preCompilation, + }); + } +}, postMessage); + +onmessage = handler.onMessage; diff --git a/worker/console.js b/worker/console.js index fc49583a6..74a2d56a3 100644 --- a/worker/console.js +++ b/worker/console.js @@ -9,7 +9,7 @@ var console = { var args = Array.prototype.slice.call(arguments); postMessage({ action: 'log', - data: args + data: args }); }, diff --git a/worker/message_handler.js b/worker/message_handler.js new file mode 100644 index 000000000..b97558ee6 --- /dev/null +++ b/worker/message_handler.js @@ -0,0 +1,23 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ + +'use strict'; + + +function MessageHandler(actionHandler, postMessage, scope) { + this.onMessage = function(event) { + var data = event.data; + if (data.action in actionHandler) { + actionHandler[data.action].call(scope, data.data); + } else { + throw 'Unkown action from worker: ' + data.action; + } + }; + + this.send = function(actionName, data) { + postMessage({ + action: actionName, + data: data + }); + } +} \ No newline at end of file diff --git a/worker/pdf.js b/worker/pdf.js deleted file mode 100644 index 8cb6342db..000000000 --- a/worker/pdf.js +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -'use strict'; - -var consoleTimer = {}; -var console = { - log: function log() { - var args = Array.prototype.slice.call(arguments); - postMessage({ - action: 'log', - data: args - }); - }, - - time: function(name) { - consoleTimer[name] = Date.now(); - }, - - timeEnd: function(name) { - var time = consoleTimer[name]; - if (time == null) { - throw 'Unkown timer name ' + name; - } - this.log('Timer:', name, Date.now() - time); - } -}; - -// -importScripts('console.js'); -importScripts('canvas.js'); -importScripts('../pdf.js'); -importScripts('../fonts.js'); -importScripts('../crypto.js'); -importScripts('../glyphlist.js'); - -// Use the JpegStreamProxy proxy. -JpegStream = JpegStreamProxy; - -// Create the WebWorkerProxyCanvas. -var canvas = new CanvasProxy(1224, 1584); - -// Listen for messages from the main thread. -var pdfDocument = null; -onmessage = function(event) { - var data = event.data; - // If there is no pdfDocument yet, then the sent data is the PDFDocument. - if (!pdfDocument) { - pdfDocument = new PDFDoc(new Stream(data)); - postMessage({ - action: 'pdf_num_pages', - data: pdfDocument.numPages - }); - return; - } - // User requested to render a certain page. - else { - console.time('compile'); - - // Let's try to render the first page... - var page = pdfDocument.getPage(parseInt(data)); - - var pdfToCssUnitsCoef = 96.0 / 72.0; - var pageWidth = (page.mediaBox[2] - page.mediaBox[0]) * pdfToCssUnitsCoef; - var pageHeight = (page.mediaBox[3] - page.mediaBox[1]) * pdfToCssUnitsCoef; - postMessage({ - action: 'setup_page', - data: pageWidth + ',' + pageHeight - }); - - // Set canvas size. - canvas.width = pageWidth; - canvas.height = pageHeight; - - // page.compile will collect all fonts for us, once we have loaded them - // we can trigger the actual page rendering with page.display - var fonts = []; - var gfx = new CanvasGraphics(canvas.getContext('2d'), CanvasProxy); - page.compile(gfx, fonts); - console.timeEnd('compile'); - - // Send fonts to the main thread. - console.time('fonts'); - postMessage({ - action: 'fonts', - data: fonts - }); - console.timeEnd('fonts'); - - console.time('display'); - page.display(gfx); - canvas.flush(); - console.timeEnd('display'); - } -};