backup
This commit is contained in:
parent
0134143c67
commit
71ff8ee586
60
pdf.js
60
pdf.js
@ -3358,18 +3358,48 @@ var Page = (function() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
startRendering: function(canvasCtx, continuation) {
|
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 self = this;
|
||||||
var stats = self.stats;
|
var stats = self.stats;
|
||||||
stats.compile = stats.fonts = stats.render = 0;
|
stats.compile = stats.fonts = stats.render = 0;
|
||||||
|
|
||||||
var gfx = new CanvasGraphics(canvasCtx);
|
|
||||||
var fonts = [];
|
var fonts = [];
|
||||||
var images = new ImagesLoader();
|
var images = new ImagesLoader();
|
||||||
|
|
||||||
this.compile(gfx, fonts, images);
|
var preCompilation = this.preCompile(gfx, fonts, images);
|
||||||
stats.compile = Date.now();
|
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() {
|
var displayContinuation = function() {
|
||||||
|
self.code = gfx.postCompile(preCompilation);
|
||||||
|
|
||||||
// Always defer call to display() to work around bug in
|
// Always defer call to display() to work around bug in
|
||||||
// Firefox error reporting from XHR callbacks.
|
// Firefox error reporting from XHR callbacks.
|
||||||
setTimeout(function() {
|
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() {
|
this.ensureFonts(fonts, function() {
|
||||||
images.notifyOnLoad(function() {
|
images.notifyOnLoad(function() {
|
||||||
stats.images = Date.now();
|
stats.images = Date.now();
|
||||||
@ -3424,12 +3438,8 @@ var Page = (function() {
|
|||||||
content[i] = xref.fetchIfRef(content[i]);
|
content[i] = xref.fetchIfRef(content[i]);
|
||||||
content = new StreamsSequenceStream(content);
|
content = new StreamsSequenceStream(content);
|
||||||
}
|
}
|
||||||
return gfx.preCompile(content, xref, resources, fonts, images);
|
return gfx.preCompile(content, xref, resources, fonts, images,
|
||||||
},
|
this.pageNumber + "_");
|
||||||
|
|
||||||
compile: function(gfx, fonts, images) {
|
|
||||||
var preCompilation = this.preCompile(gfx, fonts, images);
|
|
||||||
this.code = gfx.postCompile(preCompilation);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
ensureFonts: function(fonts, callback) {
|
ensureFonts: function(fonts, callback) {
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
<script type="text/javascript" src="../glyphlist.js"></script>
|
<script type="text/javascript" src="../glyphlist.js"></script>
|
||||||
<script type="text/javascript" src="../metrics.js"></script>
|
<script type="text/javascript" src="../metrics.js"></script>
|
||||||
<script type="text/javascript" src="../worker.js"></script>
|
<script type="text/javascript" src="../worker.js"></script>
|
||||||
|
<script type="text/javascript" src="../worker/message_handler.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
32
worker.js
32
worker.js
@ -25,8 +25,21 @@ var WorkerPage = (function() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
startRendering: function(ctx, callback, errback) {
|
startRendering: function(ctx, callback, errback) {
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.callback = callback;
|
||||||
// TODO: Place the worker magic HERE.
|
// 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() {
|
getLinks: function() {
|
||||||
@ -46,6 +59,19 @@ var WorkerPDFDoc = (function() {
|
|||||||
this.catalog = this.pdf.catalog;
|
this.catalog = this.pdf.catalog;
|
||||||
|
|
||||||
this.pageCache = [];
|
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 = {
|
constructor.prototype = {
|
||||||
@ -53,6 +79,10 @@ var WorkerPDFDoc = (function() {
|
|||||||
return this.pdf.numPages;
|
return this.pdf.numPages;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
startRendering: function(page) {
|
||||||
|
this.handler.send("page", page.page.pageNumber);
|
||||||
|
},
|
||||||
|
|
||||||
getPage: function(n) {
|
getPage: function(n) {
|
||||||
if (this.pageCache[n]) {
|
if (this.pageCache[n]) {
|
||||||
return this.pageCache[n];
|
return this.pageCache[n];
|
||||||
|
63
worker/boot.js
Normal file
63
worker/boot.js
Normal file
@ -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;
|
@ -9,7 +9,7 @@ var console = {
|
|||||||
var args = Array.prototype.slice.call(arguments);
|
var args = Array.prototype.slice.call(arguments);
|
||||||
postMessage({
|
postMessage({
|
||||||
action: 'log',
|
action: 'log',
|
||||||
data: args
|
data: args
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
23
worker/message_handler.js
Normal file
23
worker/message_handler.js
Normal file
@ -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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -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');
|
|
||||||
}
|
|
||||||
};
|
|
Loading…
x
Reference in New Issue
Block a user