pdf.js/src/core/pdf_manager.js

200 lines
4.7 KiB
JavaScript
Raw Normal View History

2013-02-07 08:19:29 +09:00
/* Copyright 2012 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
createValidAbsoluteUrl, shadow, unreachable, warn
} from '../shared/util';
import { ChunkedStreamManager } from './chunked_stream';
import { MissingDataException } from './core_utils';
import { PDFDocument } from './document';
import { Stream } from './stream';
class BasePdfManager {
constructor() {
if (this.constructor === BasePdfManager) {
unreachable('Cannot initialize BasePdfManager.');
}
2013-02-07 08:19:29 +09:00
}
get docId() {
return this._docId;
}
get password() {
return this._password;
}
get docBaseUrl() {
let docBaseUrl = null;
if (this._docBaseUrl) {
const absoluteUrl = createValidAbsoluteUrl(this._docBaseUrl);
if (absoluteUrl) {
docBaseUrl = absoluteUrl.href;
} else {
warn(`Invalid absolute docBaseUrl: "${this._docBaseUrl}".`);
}
}
return shadow(this, 'docBaseUrl', docBaseUrl);
}
onLoadedStream() {
unreachable('Abstract method `onLoadedStream` called');
}
2013-02-07 08:19:29 +09:00
ensureDoc(prop, args) {
return this.ensure(this.pdfDocument, prop, args);
}
2013-02-07 08:19:29 +09:00
ensureXRef(prop, args) {
return this.ensure(this.pdfDocument.xref, prop, args);
}
2013-02-07 08:19:29 +09:00
ensureCatalog(prop, args) {
return this.ensure(this.pdfDocument.catalog, prop, args);
}
2013-02-07 08:19:29 +09:00
getPage(pageIndex) {
return this.pdfDocument.getPage(pageIndex);
}
2013-02-07 08:19:29 +09:00
Fallback to the built-in font renderer when font loading fails After PR 9340 all glyphs are now re-mapped to a Private Use Area (PUA) which means that if a font fails to load, for whatever reason[1], all glyphs in the font will now render as Unicode glyph outlines. This obviously doesn't look good, to say the least, and might be seen as a "regression" since previously many glyphs were left in their original positions which provided a slightly better fallback[2]. Hence this patch, which implements a *general* fallback to the PDF.js built-in font renderer for fonts that fail to load (i.e. are rejected by the sanitizer). One caveat here is that this only works for the Font Loading API, since it's easy to handle errors in that case[3]. The solution implemented in this patch does *not* in any way delay the loading of valid fonts, which was the problem with my previous attempt at a solution, and will only require a bit of extra work/waiting for those fonts that actually fail to load. *Please note:* This patch doesn't fix any of the underlying PDF.js font conversion bugs that's responsible for creating corrupt font files, however it does *improve* rendering in a number of cases; refer to this possibly incomplete list: [Bug 1524888](https://bugzilla.mozilla.org/show_bug.cgi?id=1524888) Issue 10175 Issue 10232 --- [1] Usually because the PDF.js font conversion code wasn't able to parse the font file correctly. [2] Glyphs fell back to some default font, which while not accurate was more useful than the current state. [3] Furthermore I'm not sure how to implement this generally, assuming that's even possible, and don't really have time/interest to look into it either.
2019-02-11 08:47:56 +09:00
fontFallback(id, handler) {
return this.pdfDocument.fontFallback(id, handler);
}
cleanup() {
return this.pdfDocument.cleanup();
}
async ensure(obj, prop, args) {
unreachable('Abstract method `ensure` called');
}
2013-02-07 08:19:29 +09:00
requestRange(begin, end) {
unreachable('Abstract method `requestRange` called');
}
2013-04-19 02:41:33 +09:00
requestLoadedStream() {
unreachable('Abstract method `requestLoadedStream` called');
}
sendProgressiveData(chunk) {
unreachable('Abstract method `sendProgressiveData` called');
}
updatePassword(password) {
this._password = password;
}
terminate(reason) {
unreachable('Abstract method `terminate` called');
}
}
2013-02-07 08:19:29 +09:00
class LocalPdfManager extends BasePdfManager {
constructor(docId, data, password, evaluatorOptions, docBaseUrl) {
super();
2013-02-07 08:19:29 +09:00
this._docId = docId;
this._password = password;
this._docBaseUrl = docBaseUrl;
this.evaluatorOptions = evaluatorOptions;
const stream = new Stream(data);
this.pdfDocument = new PDFDocument(this, stream);
this._loadedStreamPromise = Promise.resolve(stream);
2013-02-07 08:19:29 +09:00
}
async ensure(obj, prop, args) {
const value = obj[prop];
if (typeof value === 'function') {
return value.apply(obj, args);
}
return value;
}
2013-02-07 08:19:29 +09:00
requestRange(begin, end) {
return Promise.resolve();
}
2013-04-19 02:41:33 +09:00
requestLoadedStream() {}
2013-02-07 08:19:29 +09:00
onLoadedStream() {
return this._loadedStreamPromise;
}
2013-02-07 08:19:29 +09:00
terminate(reason) {}
}
class NetworkPdfManager extends BasePdfManager {
constructor(docId, pdfNetworkStream, args, evaluatorOptions, docBaseUrl) {
super();
2013-02-07 08:19:29 +09:00
this._docId = docId;
this._password = args.password;
this._docBaseUrl = docBaseUrl;
this.msgHandler = args.msgHandler;
this.evaluatorOptions = evaluatorOptions;
2013-02-07 08:19:29 +09:00
this.streamManager = new ChunkedStreamManager(pdfNetworkStream, {
msgHandler: args.msgHandler,
length: args.length,
disableAutoFetch: args.disableAutoFetch,
Fix inconsistent spacing and trailing commas in objects in `src/core/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on *Unfortunately this patch is fairly big, even though it only covers the `src/core` folder, but splitting it even further seemed difficult.* http://eslint.org/docs/rules/comma-dangle http://eslint.org/docs/rules/object-curly-spacing Given that we currently have quite inconsistent object formatting, fixing this in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead. Please note: This patch was created automatically, using the ESLint --fix command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch. ```diff diff --git a/src/core/evaluator.js b/src/core/evaluator.js index abab9027..dcd3594b 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -2785,7 +2785,8 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() { t['Tz'] = { id: OPS.setHScale, numArgs: 1, variableArgs: false, }; t['TL'] = { id: OPS.setLeading, numArgs: 1, variableArgs: false, }; t['Tf'] = { id: OPS.setFont, numArgs: 2, variableArgs: false, }; - t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1, variableArgs: false, }; + t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1, + variableArgs: false, }; t['Ts'] = { id: OPS.setTextRise, numArgs: 1, variableArgs: false, }; t['Td'] = { id: OPS.moveText, numArgs: 2, variableArgs: false, }; t['TD'] = { id: OPS.setLeadingMoveText, numArgs: 2, variableArgs: false, }; diff --git a/src/core/jbig2.js b/src/core/jbig2.js index 5a17d482..71671541 100644 --- a/src/core/jbig2.js +++ b/src/core/jbig2.js @@ -123,19 +123,22 @@ var Jbig2Image = (function Jbig2ImageClosure() { { x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -2, y: 0, }, { x: -1, y: 0, }], [{ x: -3, y: -1, }, { x: -2, y: -1, }, { x: -1, y: -1, }, { x: 0, y: -1, }, - { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, }, { x: -1, y: 0, }] + { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, }, + { x: -1, y: 0, }] ]; var RefinementTemplates = [ { coding: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }], - reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, }, - { x: 1, y: 0, }, { x: -1, y: 1, }, { x: 0, y: 1, }, { x: 1, y: 1, }], + reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }, + { x: 0, y: 0, }, { x: 1, y: 0, }, { x: -1, y: 1, }, + { x: 0, y: 1, }, { x: 1, y: 1, }], }, { - coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }], - reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, }, { x: 1, y: 0, }, - { x: 0, y: 1, }, { x: 1, y: 1, }], + coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, + { x: -1, y: 0, }], + reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, }, + { x: 1, y: 0, }, { x: 0, y: 1, }, { x: 1, y: 1, }], } ]; ```
2017-06-02 18:16:24 +09:00
rangeChunkSize: args.rangeChunkSize,
});
this.pdfDocument = new PDFDocument(this, this.streamManager.getStream());
2013-02-07 08:19:29 +09:00
}
async ensure(obj, prop, args) {
try {
const value = obj[prop];
if (typeof value === 'function') {
return value.apply(obj, args);
}
return value;
} catch (ex) {
if (!(ex instanceof MissingDataException)) {
throw ex;
}
await this.requestRange(ex.begin, ex.end);
return this.ensure(obj, prop, args);
}
}
2013-04-19 02:41:33 +09:00
requestRange(begin, end) {
return this.streamManager.requestRange(begin, end);
}
2013-02-07 08:19:29 +09:00
requestLoadedStream() {
this.streamManager.requestAllChunks();
}
sendProgressiveData(chunk) {
this.streamManager.onReceiveData({ chunk, });
}
2013-02-07 08:19:29 +09:00
onLoadedStream() {
return this.streamManager.onLoadedStream();
}
terminate(reason) {
this.streamManager.abort(reason);
}
}
export {
LocalPdfManager,
NetworkPdfManager,
};