Merge font and processor working into one worker and fix some bugs in font-loading-data-ready code
This commit is contained in:
parent
e9b6ffbaf6
commit
d7521f758a
11
fonts.js
11
fonts.js
@ -211,6 +211,17 @@ var FontLoader = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
bind: function fontLoaderBind(fonts, callback, objects) {
|
bind: function fontLoaderBind(fonts, callback, objects) {
|
||||||
|
var fontsToLoad = {};
|
||||||
|
// check if there are twice the same font.
|
||||||
|
for (var i = 0; i < fonts.length; i++) {
|
||||||
|
var fontName = fonts[i].loadedName;
|
||||||
|
if (fontsToLoad[fontName]) {
|
||||||
|
throw "Got twice the same font!";
|
||||||
|
} else {
|
||||||
|
fontsToLoad[fontName] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function checkFontsLoaded() {
|
function checkFontsLoaded() {
|
||||||
for (var i = 0; i < objs.length; i++) {
|
for (var i = 0; i < objs.length; i++) {
|
||||||
var fontObj = objs[i];
|
var fontObj = objs[i];
|
||||||
|
2
pdf.js
2
pdf.js
@ -3387,7 +3387,7 @@ var Page = (function() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
ensureFonts: function(fonts, callback) {
|
ensureFonts: function(fonts, callback) {
|
||||||
console.log('--ensureFonts--');
|
console.log('--ensureFonts--', '' + fonts);
|
||||||
// Convert the font names to the corresponding font obj.
|
// Convert the font names to the corresponding font obj.
|
||||||
for (var i = 0; i < fonts.length; i++) {
|
for (var i = 0; i < fonts.length; i++) {
|
||||||
// HACK FOR NOW. Access the data directly. This isn't allowed as the
|
// HACK FOR NOW. Access the data directly. This isn't allowed as the
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
<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>
|
<script type="text/javascript" src="../worker/message_handler.js"></script>
|
||||||
<script type="text/javascript" src="../worker/processor_handler.js"></script>
|
<script type="text/javascript" src="../worker/processor_handler.js"></script>
|
||||||
<script type="text/javascript" src="../worker/font_handler.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
42
worker.js
42
worker.js
@ -264,8 +264,7 @@ var WorkerPDFDoc = (function() {
|
|||||||
this.pageCache = [];
|
this.pageCache = [];
|
||||||
|
|
||||||
if (useWorker) {
|
if (useWorker) {
|
||||||
var worker = this.worker = new Worker("../worker/processor_boot.js");
|
var worker = this.worker = new Worker("../worker/pdf_worker_loader.js");
|
||||||
var fontWorker = this.fontWorker = new Worker('../worker/font_boot.js');
|
|
||||||
} else {
|
} else {
|
||||||
// If we don't use a worker, just post/sendMessage to the main thread.
|
// If we don't use a worker, just post/sendMessage to the main thread.
|
||||||
var worker = {
|
var worker = {
|
||||||
@ -273,13 +272,10 @@ var WorkerPDFDoc = (function() {
|
|||||||
worker.onmessage({data: obj});
|
worker.onmessage({data: obj});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var fontWorker = {
|
|
||||||
postMessage: function(obj) {
|
|
||||||
fontWorker.onmessage({data: obj});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.fontsLoading = {};
|
||||||
|
|
||||||
var processorHandler = this.processorHandler = new MessageHandler("main", worker);
|
var processorHandler = this.processorHandler = new MessageHandler("main", worker);
|
||||||
processorHandler.on("page", function(data) {
|
processorHandler.on("page", function(data) {
|
||||||
var pageNum = data.pageNum;
|
var pageNum = data.pageNum;
|
||||||
@ -289,24 +285,44 @@ var WorkerPDFDoc = (function() {
|
|||||||
// are all the fonts that are required to render the page AND that
|
// are all the fonts that are required to render the page AND that
|
||||||
// aren't loaded on the page yet.
|
// aren't loaded on the page yet.
|
||||||
var depFonts = data.depFonts;
|
var depFonts = data.depFonts;
|
||||||
var fontsToLoad = [];
|
|
||||||
var objs = this.objs;
|
var objs = this.objs;
|
||||||
|
var fontsToLoad = [];
|
||||||
|
var fontsLoading = this.fontsLoading;
|
||||||
|
// The `i` for the checkFontData is stored here to keep the state in
|
||||||
|
// the closure.
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
|
||||||
function checkFontData() {
|
function checkFontData() {
|
||||||
// Check if all fontObjs have been processed. If not, shedule a
|
// Check if all fontObjs have been processed. If not, shedule a
|
||||||
// callback that is called once the data arrives and that checks
|
// callback that is called once the data arrives and that checks
|
||||||
// the next fonts.
|
// the next fonts.
|
||||||
for (var i = 0; i < depFonts.length; i++) {
|
for (i; i < depFonts.length; i++) {
|
||||||
var fontName = depFonts[i];
|
var fontName = depFonts[i];
|
||||||
if (!objs.hasData(fontName)) {
|
if (!objs.hasData(fontName)) {
|
||||||
console.log('need to wait for fontData', fontName);
|
console.log('need to wait for fontData', fontName);
|
||||||
objs.onData(fontObj, checkFontData);
|
objs.onData(fontName, checkFontData);
|
||||||
return;
|
return;
|
||||||
} else if (!objs.isResolved(fontName)) {
|
} else if (!objs.isResolved(fontName)) {
|
||||||
fontsToLoad.push(fontName);
|
fontsToLoad.push(fontName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There can be edge cases where two pages wait for one font and then
|
||||||
|
// call startRenderingFromIRQueue twice with the same font. That makes
|
||||||
|
// the font getting loaded twice and throw an error later as the font
|
||||||
|
// promise gets resolved twice.
|
||||||
|
// This prevents thats fonts are loaded really only once.
|
||||||
|
for (var j = 0; j < fontsToLoad.length; j++) {
|
||||||
|
var fontName = fontsToLoad[j];
|
||||||
|
if (fontsLoading[fontName]) {
|
||||||
|
fontsToLoad.splice(j, 1);
|
||||||
|
j--;
|
||||||
|
} else {
|
||||||
|
fontsLoading[fontName] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// At this point, all font data ia loaded. Start the actuall rendering.
|
// At this point, all font data ia loaded. Start the actuall rendering.
|
||||||
page.startRenderingFromIRQueue(data.IRQueue, fontsToLoad);
|
page.startRenderingFromIRQueue(data.IRQueue, fontsToLoad);
|
||||||
}
|
}
|
||||||
@ -329,15 +345,14 @@ var WorkerPDFDoc = (function() {
|
|||||||
var file = data[3];
|
var file = data[3];
|
||||||
var properties = data[4];
|
var properties = data[4];
|
||||||
|
|
||||||
fontHandler.send("font", [objId, name, file, properties]);
|
processorHandler.send("font", [objId, name, file, properties]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw "Got unkown object type " + objType;
|
throw "Got unkown object type " + objType;
|
||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
var fontHandler = this.fontHandler = new MessageHandler('font', fontWorker);
|
processorHandler.on('font_ready', function(data) {
|
||||||
fontHandler.on('font_ready', function(data) {
|
|
||||||
var objId = data[0];
|
var objId = data[0];
|
||||||
var fontObj = new FontShape(data[1]);
|
var fontObj = new FontShape(data[1]);
|
||||||
|
|
||||||
@ -355,7 +370,6 @@ var WorkerPDFDoc = (function() {
|
|||||||
// If the main thread is our worker, setup the handling for the messages
|
// If the main thread is our worker, setup the handling for the messages
|
||||||
// the main thread sends to it self.
|
// the main thread sends to it self.
|
||||||
WorkerProcessorHandler.setup(processorHandler);
|
WorkerProcessorHandler.setup(processorHandler);
|
||||||
WorkerFontHandler.setup(fontHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
processorHandler.send("doc", data);
|
processorHandler.send("doc", data);
|
||||||
|
@ -1,16 +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';
|
|
||||||
|
|
||||||
importScripts('console.js');
|
|
||||||
importScripts('message_handler.js');
|
|
||||||
importScripts('../pdf.js');
|
|
||||||
importScripts('../fonts.js');
|
|
||||||
importScripts('../crypto.js');
|
|
||||||
importScripts('../glyphlist.js');
|
|
||||||
importScripts('font_handler.js');
|
|
||||||
|
|
||||||
|
|
||||||
var handler = new MessageHandler("worker_font", this);
|
|
||||||
WorkerFontHandler.setup(handler);
|
|
@ -1,52 +0,0 @@
|
|||||||
var WorkerFontHandler = {
|
|
||||||
setup: function(handler) {
|
|
||||||
handler.on("font", function(data) {
|
|
||||||
var objId = data[0];
|
|
||||||
var name = data[1];
|
|
||||||
var file = data[2];
|
|
||||||
var properties = data[3];
|
|
||||||
|
|
||||||
var font = {
|
|
||||||
name: name,
|
|
||||||
file: file,
|
|
||||||
properties: properties
|
|
||||||
};
|
|
||||||
|
|
||||||
// Some fonts don't have a file, e.g. the build in ones like Arial.
|
|
||||||
if (file) {
|
|
||||||
var fontFileDict = new Dict();
|
|
||||||
fontFileDict.map = file.dict.map;
|
|
||||||
|
|
||||||
var fontFile = new Stream(file.bytes, file.start,
|
|
||||||
file.end - file.start, fontFileDict);
|
|
||||||
|
|
||||||
// Check if this is a FlateStream. Otherwise just use the created
|
|
||||||
// Stream one. This makes complex_ttf_font.pdf work.
|
|
||||||
var cmf = file.bytes[0];
|
|
||||||
if ((cmf & 0x0f) == 0x08) {
|
|
||||||
font.file = new FlateStream(fontFile);
|
|
||||||
} else {
|
|
||||||
font.file = fontFile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var obj = new Font(font.name, font.file, font.properties);
|
|
||||||
|
|
||||||
var str = '';
|
|
||||||
var data = obj.data;
|
|
||||||
if (data) {
|
|
||||||
var length = data.length;
|
|
||||||
for (var j = 0; j < length; j++)
|
|
||||||
str += String.fromCharCode(data[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.str = str;
|
|
||||||
|
|
||||||
// Remove the data array form the font object, as it's not needed
|
|
||||||
// anymore as we sent over the ready str.
|
|
||||||
delete obj.data;
|
|
||||||
|
|
||||||
handler.send("font_ready", [objId, obj]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -63,5 +63,54 @@ var WorkerProcessorHandler = {
|
|||||||
depFonts: Object.keys(fonts)
|
depFonts: Object.keys(fonts)
|
||||||
});
|
});
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
handler.on("font", function(data) {
|
||||||
|
var objId = data[0];
|
||||||
|
var name = data[1];
|
||||||
|
var file = data[2];
|
||||||
|
var properties = data[3];
|
||||||
|
|
||||||
|
var font = {
|
||||||
|
name: name,
|
||||||
|
file: file,
|
||||||
|
properties: properties
|
||||||
|
};
|
||||||
|
|
||||||
|
// Some fonts don't have a file, e.g. the build in ones like Arial.
|
||||||
|
if (file) {
|
||||||
|
var fontFileDict = new Dict();
|
||||||
|
fontFileDict.map = file.dict.map;
|
||||||
|
|
||||||
|
var fontFile = new Stream(file.bytes, file.start,
|
||||||
|
file.end - file.start, fontFileDict);
|
||||||
|
|
||||||
|
// Check if this is a FlateStream. Otherwise just use the created
|
||||||
|
// Stream one. This makes complex_ttf_font.pdf work.
|
||||||
|
var cmf = file.bytes[0];
|
||||||
|
if ((cmf & 0x0f) == 0x08) {
|
||||||
|
font.file = new FlateStream(fontFile);
|
||||||
|
} else {
|
||||||
|
font.file = fontFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var obj = new Font(font.name, font.file, font.properties);
|
||||||
|
|
||||||
|
var str = '';
|
||||||
|
var data = obj.data;
|
||||||
|
if (data) {
|
||||||
|
var length = data.length;
|
||||||
|
for (var j = 0; j < length; j++)
|
||||||
|
str += String.fromCharCode(data[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.str = str;
|
||||||
|
|
||||||
|
// Remove the data array form the font object, as it's not needed
|
||||||
|
// anymore as we sent over the ready str.
|
||||||
|
delete obj.data;
|
||||||
|
|
||||||
|
handler.send("font_ready", [objId, obj]);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user