[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

@ -31,6 +31,8 @@ var removeNullCharacters = sharedUtil.removeNullCharacters;
var warn = sharedUtil.warn;
var deprecated = sharedUtil.deprecated;
var createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;
var stringToBytes = sharedUtil.stringToBytes;
var CMapCompressionType = sharedUtil.CMapCompressionType;
var DEFAULT_LINK_REL = 'noopener noreferrer nofollow';
@ -66,6 +68,57 @@ DOMCanvasFactory.prototype = {
}
};
var DOMCMapReaderFactory = (function DOMCMapReaderFactoryClosure() {
function DOMCMapReaderFactory(params) {
this.baseUrl = params.baseUrl || null;
this.isCompressed = params.isCompressed || false;
}
DOMCMapReaderFactory.prototype = {
fetch: function(params) {
if (!params.name) {
return Promise.reject(new Error('CMap name must be specified.'));
}
return new Promise(function (resolve, reject) {
var url = this.baseUrl + params.name;
var request = new XMLHttpRequest();
if (this.isCompressed) {
url += '.bcmap';
request.responseType = 'arraybuffer';
}
request.onreadystatechange = function () {
if (request.readyState === XMLHttpRequest.DONE &&
(request.status === 200 || request.status === 0)) {
var data;
if (this.isCompressed && request.response) {
data = new Uint8Array(request.response);
} else if (!this.isCompressed && request.responseText) {
data = stringToBytes(request.responseText);
}
if (data) {
resolve({
cMapData: data,
compressionType: this.isCompressed ?
CMapCompressionType.BINARY : CMapCompressionType.NONE,
});
return;
}
reject(new Error('Unable to load ' +
(this.isCompressed ? 'binary' : '') +
' CMap at: ' + url));
}
}.bind(this);
request.open('GET', url, true);
request.send(null);
}.bind(this));
},
};
return DOMCMapReaderFactory;
})();
/**
* Optimised CSS custom property getter/setter.
* @class
@ -284,4 +337,5 @@ exports.hasCanvasTypedArrays = hasCanvasTypedArrays;
exports.getDefaultSetting = getDefaultSetting;
exports.DEFAULT_LINK_REL = DEFAULT_LINK_REL;
exports.DOMCanvasFactory = DOMCanvasFactory;
exports.DOMCMapReaderFactory = DOMCMapReaderFactory;
}));