diff --git a/pdf.js b/pdf.js index dbd255e6c..e2aece9b7 100644 --- a/pdf.js +++ b/pdf.js @@ -5802,6 +5802,7 @@ var ColorSpace = (function() { return "DeviceCmykCS"; break; case 'Pattern': + console.log("ColorSpace Pattern"); // TODO: IMPLEMENT ME // var baseCS = cs[1]; diff --git a/web/viewer.html b/web/viewer.html index 871db8ce6..00076aa80 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -13,6 +13,7 @@ + diff --git a/worker.js b/worker.js index 1eb65b7b9..cbe62e3d7 100644 --- a/worker.js +++ b/worker.js @@ -60,31 +60,48 @@ var WorkerPDFDoc = (function() { this.pageCache = []; - this.worker = new Worker("../worker/boot.js"); - this.handler = new MessageHandler("main", { - "page": function(data) { - var pageNum = data.pageNum; - var page = this.pageCache[pageNum]; - - // Add necessary shape back to fonts. - var fonts = data.fonts; - for (var i = 0; i < fonts.length; i++) { - var font = fonts[i]; - - var fontFileDict = new Dict(); - fontFileDict.map = font.file.dict.map; - - var fontFile = new Stream(font.file.bytes, font.file.start, - font.file.end - font.file.start, fontFileDict); - font.file = new FlateStream(fontFile); - } - - console.log("startRenderingFromPreCompilation:", "numberOfFonts", fonts.length); - page.startRenderingFromPreCompilation(data.preCompilation, data.fonts, data.images); - } - }, this.worker, this); + var useWorker = false; - this.handler.send("doc", data); + if (useWorker) { + var worker = new Worker("../worker/boot.js"); + } else { + // If we don't use a worker, just post/sendMessage to the main thread. + var worker = { + postMessage: function(obj) { + worker.onmessage({data: obj}); + } + } + } + + var handler = this.handler = new MessageHandler("main", worker); + handler.on("page", function(data) { + var pageNum = data.pageNum; + var page = this.pageCache[pageNum]; + + // Add necessary shape back to fonts. + var fonts = data.fonts; + for (var i = 0; i < fonts.length; i++) { + var font = fonts[i]; + + var fontFileDict = new Dict(); + fontFileDict.map = font.file.dict.map; + + var fontFile = new Stream(font.file.bytes, font.file.start, + font.file.end - font.file.start, fontFileDict); + font.file = new FlateStream(fontFile); + } + + console.log("startRenderingFromPreCompilation:", "numberOfFonts", fonts.length); + page.startRenderingFromPreCompilation(data.preCompilation, data.fonts, data.images); + }, this); + + if (!useWorker) { + // If the main thread is our worker, setup the handling for the messages + // the main thread sends to it self. + WorkerHandler.setup(handler); + } + + handler.send("doc", data); } constructor.prototype = { @@ -93,7 +110,7 @@ var WorkerPDFDoc = (function() { }, startRendering: function(page) { - this.handler.send("page", page.page.pageNumber + 1); + this.handler.send("page_request", page.page.pageNumber + 1); }, getPage: function(n) { diff --git a/worker/boot.js b/worker/boot.js index be8ae40d5..241870c5c 100644 --- a/worker/boot.js +++ b/worker/boot.js @@ -9,82 +9,10 @@ importScripts('../pdf.js'); importScripts('../fonts.js'); importScripts('../crypto.js'); importScripts('../glyphlist.js'); +importScripts('handler.js'); // Listen for messages from the main thread. var pdfDoc = null; -var handler = new MessageHandler("worker", { - "doc": function(data) { - pdfDoc = new PDFDoc(new Stream(data)); - console.log("setup pdfDoc"); - }, - - "page": function(pageNum) { - pageNum = parseInt(pageNum); - console.log("about to process page", pageNum); - - var page = pdfDoc.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(null); - 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: font.name, - file: font.file, - properties: font.properties - }); - } - - // TODO: Handle images here. - - console.log("about to send page", pageNum); - - if (true /* show used commands */) { - var cmdMap = {}; - - var fnArray = preCompilation.fnArray; - for (var i = 0; i < fnArray.length; i++) { - var entry = fnArray[i]; - if (entry == "paintReadyFormXObject") { - //console.log(preCompilation.argsArray[i]); - } - if (cmdMap[entry] == null) { - cmdMap[entry] = 1; - } else { - cmdMap[entry] += 1; - } - } - - // // Make a copy of the fnArray and show all cmds it has. - // var fnArray = preCompilation.fnArray.slice(0).sort(); - // for (var i = 0; i < fnArray.length; true) { - // if (fnArray[i] == fnArray[i + 1]) { - // fnArray.splice(i, 1); - // } else { - // i++; - // } - // } - console.log("cmds", JSON.stringify(cmdMap)); - } - - handler.send("page", { - pageNum: pageNum, - fonts: fontsMin, - images: [], - preCompilation: preCompilation, - }); - } -}, this); +var handler = new MessageHandler("worker", this); +WorkerHandler.setup(handler); diff --git a/worker/handler.js b/worker/handler.js new file mode 100644 index 000000000..ca8413ede --- /dev/null +++ b/worker/handler.js @@ -0,0 +1,84 @@ +/* -*- 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 WorkerHandler = { + setup: function(handler) { + var pdfDoc = null; + + handler.on("doc", function(data) { + pdfDoc = new PDFDoc(new Stream(data)); + console.log("setup pdfDoc"); + }); + + handler.on("page_request", function(pageNum) { + pageNum = parseInt(pageNum); + console.log("about to process page", pageNum); + + var page = pdfDoc.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(null); + 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: font.name, + file: font.file, + properties: font.properties + }); + } + + // TODO: Handle images here. + + console.log("about to send page", pageNum); + + if (true /* show used commands */) { + var cmdMap = {}; + + var fnArray = preCompilation.fnArray; + for (var i = 0; i < fnArray.length; i++) { + var entry = fnArray[i]; + if (entry == "paintReadyFormXObject") { + //console.log(preCompilation.argsArray[i]); + } + if (cmdMap[entry] == null) { + cmdMap[entry] = 1; + } else { + cmdMap[entry] += 1; + } + } + + // // Make a copy of the fnArray and show all cmds it has. + // var fnArray = preCompilation.fnArray.slice(0).sort(); + // for (var i = 0; i < fnArray.length; true) { + // if (fnArray[i] == fnArray[i + 1]) { + // fnArray.splice(i, 1); + // } else { + // i++; + // } + // } + console.log("cmds", JSON.stringify(cmdMap)); + } + + handler.send("page", { + pageNum: pageNum, + fonts: fontsMin, + images: [], + preCompilation: preCompilation, + }); + }, this); + } +} \ No newline at end of file diff --git a/worker/message_handler.js b/worker/message_handler.js index 17c6e4aea..63e8277e2 100644 --- a/worker/message_handler.js +++ b/worker/message_handler.js @@ -4,29 +4,41 @@ 'use strict'; -function MessageHandler(name, actionHandler, comObj, scope) { +function MessageHandler(name, comObj) { this.name = name; + this.comObj = comObj; + var ah = this.actionHandler = {}; - actionHandler["console_log"] = function(data) { + ah["console_log"] = [function(data) { console.log.apply(console, data); - } - actionHandler["console_error"] = function(data) { + }] + ah["console_error"] = [function(data) { console.error.apply(console, data); - } - + }] comObj.onmessage = function(event) { var data = event.data; - if (data.action in actionHandler) { - actionHandler[data.action].call(scope, data.data); + if (data.action in ah) { + var action = ah[data.action]; + action[0].call(action[1], data.data); } else { throw 'Unkown action from worker: ' + data.action; } }; - - this.send = function(actionName, data) { +} + +MessageHandler.prototype = { + on: function(actionName, handler, scope) { + var ah = this.actionHandler; + if (ah[actionName]) { + throw "There is already an actionName called '" + actionName + "'"; + } + ah[actionName] = [handler, scope]; + }, + + send: function(actionName, data) { try { - comObj.postMessage({ + this.comObj.postMessage({ action: actionName, data: data }); @@ -35,4 +47,6 @@ function MessageHandler(name, actionHandler, comObj, scope) { throw e; } } -} \ No newline at end of file + +} +