[api-minor] Refactor fetching of built-in CMaps to utilize a factory on the display side instead, to allow users of the API to provide a custom CMap loading factory (e.g. for use with Node.js)

Currently the built-in CMap files are loaded in `src/core/cmap.js` using `XMLHttpRequest` directly. For some environments that might be a problem, hence this patch refactors that to instead use a factory to load built-in CMaps on the main thread and message the data to the worker thread.

This is inspired by other recent work, e.g. the addition of the `CanvasFactory`, and to a large extent on the IRC discussion starting at http://logs.glob.uno/?c=mozilla%23pdfjs&s=12+Oct+2016&e=12+Oct+2016#c53010.
This commit is contained in:
Jonas Jenwald 2017-02-12 15:54:41 +01:00
parent b509a3f83c
commit 769c1450b7
10 changed files with 211 additions and 111 deletions

View file

@ -62,6 +62,7 @@ var CanvasGraphics = displayCanvas.CanvasGraphics;
var Metadata = displayMetadata.Metadata;
var getDefaultSetting = displayDOMUtils.getDefaultSetting;
var DOMCanvasFactory = displayDOMUtils.DOMCanvasFactory;
var DOMCMapReaderFactory = displayDOMUtils.DOMCMapReaderFactory;
var DEFAULT_RANGE_CHUNK_SIZE = 65536; // 2^16 = 65536
@ -142,6 +143,10 @@ if (typeof PDFJSDev !== 'undefined' &&
* of certain (simple) JPEG images in the browser. This is useful for
* environments without DOM image support, such as e.g. Node.js.
* The default value is `false`.
* @property {Object} CMapReaderFactory - (optional) The factory that will be
* used when reading built-in CMap files. Providing a custom factory is useful
* for environments without `XMLHttpRequest` support, such as e.g. Node.js.
* The default value is {DOMCMapReaderFactory}.
*/
/**
@ -256,6 +261,7 @@ function getDocument(src, pdfDataRangeTransport,
params.rangeChunkSize = params.rangeChunkSize || DEFAULT_RANGE_CHUNK_SIZE;
params.disableNativeImageDecoder = params.disableNativeImageDecoder === true;
var CMapReaderFactory = params.CMapReaderFactory || DOMCMapReaderFactory;
if (!worker) {
// Worker was not provided -- creating and owning our own.
@ -273,7 +279,8 @@ function getDocument(src, pdfDataRangeTransport,
throw new Error('Loading aborted');
}
var messageHandler = new MessageHandler(docId, workerId, worker.port);
var transport = new WorkerTransport(messageHandler, task, rangeTransport);
var transport = new WorkerTransport(messageHandler, task, rangeTransport,
CMapReaderFactory);
task._transport = transport;
messageHandler.send('Ready', null);
});
@ -309,8 +316,6 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
source: source,
disableRange: getDefaultSetting('disableRange'),
maxImageSize: getDefaultSetting('maxImageSize'),
cMapUrl: getDefaultSetting('cMapUrl'),
cMapPacked: getDefaultSetting('cMapPacked'),
disableFontFace: getDefaultSetting('disableFontFace'),
disableCreateObjectURL: getDefaultSetting('disableCreateObjectURL'),
postMessageTransfers: getDefaultSetting('postMessageTransfers') &&
@ -1429,12 +1434,17 @@ var PDFWorker = (function PDFWorkerClosure() {
* @ignore
*/
var WorkerTransport = (function WorkerTransportClosure() {
function WorkerTransport(messageHandler, loadingTask, pdfDataRangeTransport) {
function WorkerTransport(messageHandler, loadingTask, pdfDataRangeTransport,
CMapReaderFactory) {
this.messageHandler = messageHandler;
this.loadingTask = loadingTask;
this.pdfDataRangeTransport = pdfDataRangeTransport;
this.commonObjs = new PDFObjects();
this.fontLoader = new FontLoader(loadingTask.docId);
this.CMapReaderFactory = new CMapReaderFactory({
baseUrl: getDefaultSetting('cMapUrl'),
isCompressed: getDefaultSetting('cMapPacked'),
});
this.destroyed = false;
this.destroyCapability = null;
@ -1794,6 +1804,15 @@ var WorkerTransport = (function WorkerTransportClosure() {
img.src = imageUrl;
});
}, this);
messageHandler.on('FetchBuiltInCMap', function (data) {
if (this.destroyed) {
return Promise.reject(new Error('Worker was destroyed'));
}
return this.CMapReaderFactory.fetch({
name: data.name,
});
}, this);
},
getData: function WorkerTransport_getData() {