mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-22 16:18:08 +02:00
Enable auto-formatting of the entire code-base using Prettier (issue 11444)
Note that Prettier, purposely, has only limited [configuration options](https://prettier.io/docs/en/options.html). The configuration file is based on [the one in `mozilla central`](https://searchfox.org/mozilla-central/source/.prettierrc) with just a few additions (to avoid future breakage if the defaults ever changes). Prettier is being used for a couple of reasons: - To be consistent with `mozilla-central`, where Prettier is already in use across the tree. - To ensure a *consistent* coding style everywhere, which is automatically enforced during linting (since Prettier is used as an ESLint plugin). This thus ends "all" formatting disussions once and for all, removing the need for review comments on most stylistic matters. Many ESLint options are now redundant, and I've tried my best to remove all the now unnecessary options (but I may have missed some). Note also that since Prettier considers the `printWidth` option as a guide, rather than a hard rule, this patch resorts to a small hack in the ESLint config to ensure that *comments* won't become too long. *Please note:* This patch is generated automatically, by appending the `--fix` argument to the ESLint call used in the `gulp lint` task. It will thus require some additional clean-up, which will be done in a *separate* commit. (On a more personal note, I'll readily admit that some of the changes Prettier makes are *extremely* ugly. However, in the name of consistency we'll probably have to live with that.)
This commit is contained in:
parent
8ec1dfde49
commit
de36b2aaba
205 changed files with 40024 additions and 31859 deletions
|
@ -15,16 +15,25 @@
|
|||
/* eslint no-var: error */
|
||||
|
||||
import {
|
||||
AnnotationBorderStyleType, AnnotationFieldFlag, AnnotationFlag,
|
||||
AnnotationReplyType, AnnotationType, assert, isString, OPS, stringToBytes,
|
||||
stringToPDFString, Util, warn
|
||||
} from '../shared/util';
|
||||
import { Catalog, FileSpec, ObjectLoader } from './obj';
|
||||
import { Dict, isDict, isName, isRef, isStream } from './primitives';
|
||||
import { ColorSpace } from './colorspace';
|
||||
import { getInheritableProperty } from './core_utils';
|
||||
import { OperatorList } from './operator_list';
|
||||
import { Stream } from './stream';
|
||||
AnnotationBorderStyleType,
|
||||
AnnotationFieldFlag,
|
||||
AnnotationFlag,
|
||||
AnnotationReplyType,
|
||||
AnnotationType,
|
||||
assert,
|
||||
isString,
|
||||
OPS,
|
||||
stringToBytes,
|
||||
stringToPDFString,
|
||||
Util,
|
||||
warn,
|
||||
} from "../shared/util";
|
||||
import { Catalog, FileSpec, ObjectLoader } from "./obj";
|
||||
import { Dict, isDict, isName, isRef, isStream } from "./primitives";
|
||||
import { ColorSpace } from "./colorspace";
|
||||
import { getInheritableProperty } from "./core_utils";
|
||||
import { OperatorList } from "./operator_list";
|
||||
import { Stream } from "./stream";
|
||||
|
||||
class AnnotationFactory {
|
||||
/**
|
||||
|
@ -40,8 +49,12 @@ class AnnotationFactory {
|
|||
* instance.
|
||||
*/
|
||||
static create(xref, ref, pdfManager, idFactory) {
|
||||
return pdfManager.ensure(this, '_create',
|
||||
[xref, ref, pdfManager, idFactory]);
|
||||
return pdfManager.ensure(this, "_create", [
|
||||
xref,
|
||||
ref,
|
||||
pdfManager,
|
||||
idFactory,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,7 +68,7 @@ class AnnotationFactory {
|
|||
const id = isRef(ref) ? ref.toString() : `annot_${idFactory.createObjId()}`;
|
||||
|
||||
// Determine the annotation's subtype.
|
||||
let subtype = dict.get('Subtype');
|
||||
let subtype = dict.get("Subtype");
|
||||
subtype = isName(subtype) ? subtype.name : null;
|
||||
|
||||
// Return the right annotation object based on the subtype and field type.
|
||||
|
@ -68,79 +81,87 @@ class AnnotationFactory {
|
|||
};
|
||||
|
||||
switch (subtype) {
|
||||
case 'Link':
|
||||
case "Link":
|
||||
return new LinkAnnotation(parameters);
|
||||
|
||||
case 'Text':
|
||||
case "Text":
|
||||
return new TextAnnotation(parameters);
|
||||
|
||||
case 'Widget':
|
||||
let fieldType = getInheritableProperty({ dict, key: 'FT', });
|
||||
case "Widget":
|
||||
let fieldType = getInheritableProperty({ dict, key: "FT" });
|
||||
fieldType = isName(fieldType) ? fieldType.name : null;
|
||||
|
||||
switch (fieldType) {
|
||||
case 'Tx':
|
||||
case "Tx":
|
||||
return new TextWidgetAnnotation(parameters);
|
||||
case 'Btn':
|
||||
case "Btn":
|
||||
return new ButtonWidgetAnnotation(parameters);
|
||||
case 'Ch':
|
||||
case "Ch":
|
||||
return new ChoiceWidgetAnnotation(parameters);
|
||||
}
|
||||
warn('Unimplemented widget field type "' + fieldType + '", ' +
|
||||
'falling back to base field type.');
|
||||
warn(
|
||||
'Unimplemented widget field type "' +
|
||||
fieldType +
|
||||
'", ' +
|
||||
"falling back to base field type."
|
||||
);
|
||||
return new WidgetAnnotation(parameters);
|
||||
|
||||
case 'Popup':
|
||||
case "Popup":
|
||||
return new PopupAnnotation(parameters);
|
||||
|
||||
case 'FreeText':
|
||||
case "FreeText":
|
||||
return new FreeTextAnnotation(parameters);
|
||||
|
||||
case 'Line':
|
||||
case "Line":
|
||||
return new LineAnnotation(parameters);
|
||||
|
||||
case 'Square':
|
||||
case "Square":
|
||||
return new SquareAnnotation(parameters);
|
||||
|
||||
case 'Circle':
|
||||
case "Circle":
|
||||
return new CircleAnnotation(parameters);
|
||||
|
||||
case 'PolyLine':
|
||||
case "PolyLine":
|
||||
return new PolylineAnnotation(parameters);
|
||||
|
||||
case 'Polygon':
|
||||
case "Polygon":
|
||||
return new PolygonAnnotation(parameters);
|
||||
|
||||
case 'Caret':
|
||||
case "Caret":
|
||||
return new CaretAnnotation(parameters);
|
||||
|
||||
case 'Ink':
|
||||
case "Ink":
|
||||
return new InkAnnotation(parameters);
|
||||
|
||||
case 'Highlight':
|
||||
case "Highlight":
|
||||
return new HighlightAnnotation(parameters);
|
||||
|
||||
case 'Underline':
|
||||
case "Underline":
|
||||
return new UnderlineAnnotation(parameters);
|
||||
|
||||
case 'Squiggly':
|
||||
case "Squiggly":
|
||||
return new SquigglyAnnotation(parameters);
|
||||
|
||||
case 'StrikeOut':
|
||||
case "StrikeOut":
|
||||
return new StrikeOutAnnotation(parameters);
|
||||
|
||||
case 'Stamp':
|
||||
case "Stamp":
|
||||
return new StampAnnotation(parameters);
|
||||
|
||||
case 'FileAttachment':
|
||||
case "FileAttachment":
|
||||
return new FileAttachmentAnnotation(parameters);
|
||||
|
||||
default:
|
||||
if (!subtype) {
|
||||
warn('Annotation is missing the required /Subtype.');
|
||||
warn("Annotation is missing the required /Subtype.");
|
||||
} else {
|
||||
warn('Unimplemented annotation type "' + subtype + '", ' +
|
||||
'falling back to base annotation.');
|
||||
warn(
|
||||
'Unimplemented annotation type "' +
|
||||
subtype +
|
||||
'", ' +
|
||||
"falling back to base annotation."
|
||||
);
|
||||
}
|
||||
return new Annotation(parameters);
|
||||
}
|
||||
|
@ -148,13 +169,13 @@ class AnnotationFactory {
|
|||
}
|
||||
|
||||
function getQuadPoints(dict, rect) {
|
||||
if (!dict.has('QuadPoints')) {
|
||||
if (!dict.has("QuadPoints")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// The region is described as a number of quadrilaterals.
|
||||
// Each quadrilateral must consist of eight coordinates.
|
||||
const quadPoints = dict.getArray('QuadPoints');
|
||||
const quadPoints = dict.getArray("QuadPoints");
|
||||
if (!Array.isArray(quadPoints) || quadPoints.length % 8 > 0) {
|
||||
return null;
|
||||
}
|
||||
|
@ -165,7 +186,7 @@ function getQuadPoints(dict, rect) {
|
|||
// quadrilateral in the order [x1, y1, x2, y2, x3, y3, x4, y4].
|
||||
// Convert this to an array of objects with x and y coordinates.
|
||||
quadPointsLists.push([]);
|
||||
for (let j = i * 8, jj = (i * 8) + 8; j < jj; j += 2) {
|
||||
for (let j = i * 8, jj = i * 8 + 8; j < jj; j += 2) {
|
||||
const x = quadPoints[j];
|
||||
const y = quadPoints[j + 1];
|
||||
|
||||
|
@ -174,7 +195,7 @@ function getQuadPoints(dict, rect) {
|
|||
if (x < rect[0] || x > rect[2] || y < rect[1] || y > rect[3]) {
|
||||
return null;
|
||||
}
|
||||
quadPointsLists[i].push({ x, y, });
|
||||
quadPointsLists[i].push({ x, y });
|
||||
}
|
||||
}
|
||||
return quadPointsLists;
|
||||
|
@ -182,8 +203,10 @@ function getQuadPoints(dict, rect) {
|
|||
|
||||
function getTransformMatrix(rect, bbox, matrix) {
|
||||
// 12.5.5: Algorithm: Appearance streams
|
||||
const [minX, minY, maxX, maxY] =
|
||||
Util.getAxialAlignedBoundingBox(bbox, matrix);
|
||||
const [minX, minY, maxX, maxY] = Util.getAxialAlignedBoundingBox(
|
||||
bbox,
|
||||
matrix
|
||||
);
|
||||
if (minX === maxX || minY === maxY) {
|
||||
// From real-life file, bbox was [0, 0, 0, 0]. In this case,
|
||||
// just apply the transform for rect
|
||||
|
@ -198,7 +221,7 @@ function getTransformMatrix(rect, bbox, matrix) {
|
|||
0,
|
||||
yRatio,
|
||||
rect[0] - minX * xRatio,
|
||||
rect[1] - minY * yRatio
|
||||
rect[1] - minY * yRatio,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -206,11 +229,11 @@ class Annotation {
|
|||
constructor(params) {
|
||||
const dict = params.dict;
|
||||
|
||||
this.setContents(dict.get('Contents'));
|
||||
this.setModificationDate(dict.get('M'));
|
||||
this.setFlags(dict.get('F'));
|
||||
this.setRectangle(dict.getArray('Rect'));
|
||||
this.setColor(dict.getArray('C'));
|
||||
this.setContents(dict.get("Contents"));
|
||||
this.setModificationDate(dict.get("M"));
|
||||
this.setFlags(dict.get("F"));
|
||||
this.setRectangle(dict.getArray("Rect"));
|
||||
this.setColor(dict.getArray("C"));
|
||||
this.setBorderStyle(dict);
|
||||
this.setAppearance(dict);
|
||||
|
||||
|
@ -239,18 +262,22 @@ class Annotation {
|
|||
* @private
|
||||
*/
|
||||
_isViewable(flags) {
|
||||
return !this._hasFlag(flags, AnnotationFlag.INVISIBLE) &&
|
||||
!this._hasFlag(flags, AnnotationFlag.HIDDEN) &&
|
||||
!this._hasFlag(flags, AnnotationFlag.NOVIEW);
|
||||
return (
|
||||
!this._hasFlag(flags, AnnotationFlag.INVISIBLE) &&
|
||||
!this._hasFlag(flags, AnnotationFlag.HIDDEN) &&
|
||||
!this._hasFlag(flags, AnnotationFlag.NOVIEW)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_isPrintable(flags) {
|
||||
return this._hasFlag(flags, AnnotationFlag.PRINT) &&
|
||||
!this._hasFlag(flags, AnnotationFlag.INVISIBLE) &&
|
||||
!this._hasFlag(flags, AnnotationFlag.HIDDEN);
|
||||
return (
|
||||
this._hasFlag(flags, AnnotationFlag.PRINT) &&
|
||||
!this._hasFlag(flags, AnnotationFlag.INVISIBLE) &&
|
||||
!this._hasFlag(flags, AnnotationFlag.HIDDEN)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -283,7 +310,7 @@ class Annotation {
|
|||
* description of the annotation's contents
|
||||
*/
|
||||
setContents(contents) {
|
||||
this.contents = stringToPDFString(contents || '');
|
||||
this.contents = stringToPDFString(contents || "");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -295,8 +322,9 @@ class Annotation {
|
|||
* annotation was last modified
|
||||
*/
|
||||
setModificationDate(modificationDate) {
|
||||
this.modificationDate = isString(modificationDate) ?
|
||||
modificationDate : null;
|
||||
this.modificationDate = isString(modificationDate)
|
||||
? modificationDate
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -309,7 +337,7 @@ class Annotation {
|
|||
* @see {@link shared/util.js}
|
||||
*/
|
||||
setFlags(flags) {
|
||||
this.flags = (Number.isInteger(flags) && flags > 0) ? flags : 0;
|
||||
this.flags = Number.isInteger(flags) && flags > 0 ? flags : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -392,32 +420,35 @@ class Annotation {
|
|||
* @param {Dict} borderStyle - The border style dictionary
|
||||
*/
|
||||
setBorderStyle(borderStyle) {
|
||||
if (typeof PDFJSDev === 'undefined' ||
|
||||
PDFJSDev.test('!PRODUCTION || TESTING')) {
|
||||
assert(this.rectangle, 'setRectangle must have been called previously.');
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(this.rectangle, "setRectangle must have been called previously.");
|
||||
}
|
||||
|
||||
this.borderStyle = new AnnotationBorderStyle();
|
||||
if (!isDict(borderStyle)) {
|
||||
return;
|
||||
}
|
||||
if (borderStyle.has('BS')) {
|
||||
const dict = borderStyle.get('BS');
|
||||
const dictType = dict.get('Type');
|
||||
if (borderStyle.has("BS")) {
|
||||
const dict = borderStyle.get("BS");
|
||||
const dictType = dict.get("Type");
|
||||
|
||||
if (!dictType || isName(dictType, 'Border')) {
|
||||
this.borderStyle.setWidth(dict.get('W'), this.rectangle);
|
||||
this.borderStyle.setStyle(dict.get('S'));
|
||||
this.borderStyle.setDashArray(dict.getArray('D'));
|
||||
if (!dictType || isName(dictType, "Border")) {
|
||||
this.borderStyle.setWidth(dict.get("W"), this.rectangle);
|
||||
this.borderStyle.setStyle(dict.get("S"));
|
||||
this.borderStyle.setDashArray(dict.getArray("D"));
|
||||
}
|
||||
} else if (borderStyle.has('Border')) {
|
||||
const array = borderStyle.getArray('Border');
|
||||
} else if (borderStyle.has("Border")) {
|
||||
const array = borderStyle.getArray("Border");
|
||||
if (Array.isArray(array) && array.length >= 3) {
|
||||
this.borderStyle.setHorizontalCornerRadius(array[0]);
|
||||
this.borderStyle.setVerticalCornerRadius(array[1]);
|
||||
this.borderStyle.setWidth(array[2], this.rectangle);
|
||||
|
||||
if (array.length === 4) { // Dash array available
|
||||
if (array.length === 4) {
|
||||
// Dash array available
|
||||
this.borderStyle.setDashArray(array[3]);
|
||||
}
|
||||
}
|
||||
|
@ -441,13 +472,13 @@ class Annotation {
|
|||
setAppearance(dict) {
|
||||
this.appearance = null;
|
||||
|
||||
const appearanceStates = dict.get('AP');
|
||||
const appearanceStates = dict.get("AP");
|
||||
if (!isDict(appearanceStates)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// In case the normal appearance is a stream, then it is used directly.
|
||||
const normalAppearanceState = appearanceStates.get('N');
|
||||
const normalAppearanceState = appearanceStates.get("N");
|
||||
if (isStream(normalAppearanceState)) {
|
||||
this.appearance = normalAppearanceState;
|
||||
return;
|
||||
|
@ -458,7 +489,7 @@ class Annotation {
|
|||
|
||||
// In case the normal appearance is a dictionary, the `AS` entry provides
|
||||
// the key of the stream in this dictionary.
|
||||
const as = dict.get('AS');
|
||||
const as = dict.get("AS");
|
||||
if (!isName(as) || !normalAppearanceState.has(as.name)) {
|
||||
return;
|
||||
}
|
||||
|
@ -466,7 +497,7 @@ class Annotation {
|
|||
}
|
||||
|
||||
loadResources(keys) {
|
||||
return this.appearance.dict.getAsync('Resources').then((resources) => {
|
||||
return this.appearance.dict.getAsync("Resources").then(resources => {
|
||||
if (!resources) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -486,30 +517,32 @@ class Annotation {
|
|||
const data = this.data;
|
||||
const appearanceDict = this.appearance.dict;
|
||||
const resourcesPromise = this.loadResources([
|
||||
'ExtGState',
|
||||
'ColorSpace',
|
||||
'Pattern',
|
||||
'Shading',
|
||||
'XObject',
|
||||
'Font',
|
||||
"ExtGState",
|
||||
"ColorSpace",
|
||||
"Pattern",
|
||||
"Shading",
|
||||
"XObject",
|
||||
"Font",
|
||||
]);
|
||||
const bbox = appearanceDict.getArray('BBox') || [0, 0, 1, 1];
|
||||
const matrix = appearanceDict.getArray('Matrix') || [1, 0, 0, 1, 0, 0];
|
||||
const bbox = appearanceDict.getArray("BBox") || [0, 0, 1, 1];
|
||||
const matrix = appearanceDict.getArray("Matrix") || [1, 0, 0, 1, 0, 0];
|
||||
const transform = getTransformMatrix(data.rect, bbox, matrix);
|
||||
|
||||
return resourcesPromise.then((resources) => {
|
||||
return resourcesPromise.then(resources => {
|
||||
const opList = new OperatorList();
|
||||
opList.addOp(OPS.beginAnnotation, [data.rect, transform, matrix]);
|
||||
return evaluator.getOperatorList({
|
||||
stream: this.appearance,
|
||||
task,
|
||||
resources,
|
||||
operatorList: opList,
|
||||
}).then(() => {
|
||||
opList.addOp(OPS.endAnnotation, []);
|
||||
this.appearance.reset();
|
||||
return opList;
|
||||
});
|
||||
return evaluator
|
||||
.getOperatorList({
|
||||
stream: this.appearance,
|
||||
task,
|
||||
resources,
|
||||
operatorList: opList,
|
||||
})
|
||||
.then(() => {
|
||||
opList.addOp(OPS.endAnnotation, []);
|
||||
this.appearance.reset();
|
||||
return opList;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -535,10 +568,14 @@ class AnnotationBorderStyle {
|
|||
* @param {Array} rect - The annotation `Rect` entry.
|
||||
*/
|
||||
setWidth(width, rect = [0, 0, 0, 0]) {
|
||||
if (typeof PDFJSDev === 'undefined' ||
|
||||
PDFJSDev.test('!PRODUCTION || TESTING')) {
|
||||
assert(Array.isArray(rect) && rect.length === 4,
|
||||
'A valid `rect` parameter must be provided.');
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(
|
||||
Array.isArray(rect) && rect.length === 4,
|
||||
"A valid `rect` parameter must be provided."
|
||||
);
|
||||
}
|
||||
|
||||
// Some corrupt PDF generators may provide the width as a `Name`,
|
||||
|
@ -555,8 +592,11 @@ class AnnotationBorderStyle {
|
|||
// Ignore large `width`s, since they lead to the Annotation overflowing
|
||||
// the size set by the `Rect` entry thus causing the `annotationLayer`
|
||||
// to render it over the surrounding document (fixes bug1552113.pdf).
|
||||
if ((maxWidth > 0 && maxHeight > 0) &&
|
||||
(width > maxWidth || width > maxHeight)) {
|
||||
if (
|
||||
maxWidth > 0 &&
|
||||
maxHeight > 0 &&
|
||||
(width > maxWidth || width > maxHeight)
|
||||
) {
|
||||
warn(`AnnotationBorderStyle.setWidth - ignoring width: ${width}`);
|
||||
width = 1;
|
||||
}
|
||||
|
@ -578,23 +618,23 @@ class AnnotationBorderStyle {
|
|||
return;
|
||||
}
|
||||
switch (style.name) {
|
||||
case 'S':
|
||||
case "S":
|
||||
this.style = AnnotationBorderStyleType.SOLID;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
case "D":
|
||||
this.style = AnnotationBorderStyleType.DASHED;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
case "B":
|
||||
this.style = AnnotationBorderStyleType.BEVELED;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
case "I":
|
||||
this.style = AnnotationBorderStyleType.INSET;
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
case "U":
|
||||
this.style = AnnotationBorderStyleType.UNDERLINE;
|
||||
break;
|
||||
|
||||
|
@ -620,7 +660,7 @@ class AnnotationBorderStyle {
|
|||
let isValid = true;
|
||||
let allZeros = true;
|
||||
for (const element of dashArray) {
|
||||
const validNumber = (+element >= 0);
|
||||
const validNumber = +element >= 0;
|
||||
if (!validNumber) {
|
||||
isValid = false;
|
||||
break;
|
||||
|
@ -671,56 +711,56 @@ class MarkupAnnotation extends Annotation {
|
|||
|
||||
const dict = parameters.dict;
|
||||
|
||||
if (dict.has('IRT')) {
|
||||
const rawIRT = dict.getRaw('IRT');
|
||||
if (dict.has("IRT")) {
|
||||
const rawIRT = dict.getRaw("IRT");
|
||||
this.data.inReplyTo = isRef(rawIRT) ? rawIRT.toString() : null;
|
||||
|
||||
const rt = dict.get('RT');
|
||||
const rt = dict.get("RT");
|
||||
this.data.replyType = isName(rt) ? rt.name : AnnotationReplyType.REPLY;
|
||||
}
|
||||
|
||||
if (this.data.replyType === AnnotationReplyType.GROUP) {
|
||||
// Subordinate annotations in a group should inherit
|
||||
// the group attributes from the primary annotation.
|
||||
const parent = dict.get('IRT');
|
||||
const parent = dict.get("IRT");
|
||||
|
||||
this.data.title = stringToPDFString(parent.get('T') || '');
|
||||
this.data.title = stringToPDFString(parent.get("T") || "");
|
||||
|
||||
this.setContents(parent.get('Contents'));
|
||||
this.setContents(parent.get("Contents"));
|
||||
this.data.contents = this.contents;
|
||||
|
||||
if (!parent.has('CreationDate')) {
|
||||
if (!parent.has("CreationDate")) {
|
||||
this.data.creationDate = null;
|
||||
} else {
|
||||
this.setCreationDate(parent.get('CreationDate'));
|
||||
this.setCreationDate(parent.get("CreationDate"));
|
||||
this.data.creationDate = this.creationDate;
|
||||
}
|
||||
|
||||
if (!parent.has('M')) {
|
||||
if (!parent.has("M")) {
|
||||
this.data.modificationDate = null;
|
||||
} else {
|
||||
this.setModificationDate(parent.get('M'));
|
||||
this.setModificationDate(parent.get("M"));
|
||||
this.data.modificationDate = this.modificationDate;
|
||||
}
|
||||
|
||||
this.data.hasPopup = parent.has('Popup');
|
||||
this.data.hasPopup = parent.has("Popup");
|
||||
|
||||
if (!parent.has('C')) {
|
||||
if (!parent.has("C")) {
|
||||
// Fall back to the default background color.
|
||||
this.data.color = null;
|
||||
} else {
|
||||
this.setColor(parent.getArray('C'));
|
||||
this.setColor(parent.getArray("C"));
|
||||
this.data.color = this.color;
|
||||
}
|
||||
} else {
|
||||
this.data.title = stringToPDFString(dict.get('T') || '');
|
||||
this.data.title = stringToPDFString(dict.get("T") || "");
|
||||
|
||||
this.setCreationDate(dict.get('CreationDate'));
|
||||
this.setCreationDate(dict.get("CreationDate"));
|
||||
this.data.creationDate = this.creationDate;
|
||||
|
||||
this.data.hasPopup = dict.has('Popup');
|
||||
this.data.hasPopup = dict.has("Popup");
|
||||
|
||||
if (!dict.has('C')) {
|
||||
if (!dict.has("C")) {
|
||||
// Fall back to the default background color.
|
||||
this.data.color = null;
|
||||
}
|
||||
|
@ -749,16 +789,19 @@ class WidgetAnnotation extends Annotation {
|
|||
|
||||
data.annotationType = AnnotationType.WIDGET;
|
||||
data.fieldName = this._constructFieldName(dict);
|
||||
data.fieldValue = getInheritableProperty({ dict, key: 'V',
|
||||
getArray: true, });
|
||||
data.alternativeText = stringToPDFString(dict.get('TU') || '');
|
||||
data.defaultAppearance = getInheritableProperty({ dict, key: 'DA', }) || '';
|
||||
const fieldType = getInheritableProperty({ dict, key: 'FT', });
|
||||
data.fieldValue = getInheritableProperty({
|
||||
dict,
|
||||
key: "V",
|
||||
getArray: true,
|
||||
});
|
||||
data.alternativeText = stringToPDFString(dict.get("TU") || "");
|
||||
data.defaultAppearance = getInheritableProperty({ dict, key: "DA" }) || "";
|
||||
const fieldType = getInheritableProperty({ dict, key: "FT" });
|
||||
data.fieldType = isName(fieldType) ? fieldType.name : null;
|
||||
this.fieldResources = getInheritableProperty({ dict, key: 'DR', }) ||
|
||||
Dict.empty;
|
||||
this.fieldResources =
|
||||
getInheritableProperty({ dict, key: "DR" }) || Dict.empty;
|
||||
|
||||
data.fieldFlags = getInheritableProperty({ dict, key: 'Ff', });
|
||||
data.fieldFlags = getInheritableProperty({ dict, key: "Ff" });
|
||||
if (!Number.isInteger(data.fieldFlags) || data.fieldFlags < 0) {
|
||||
data.fieldFlags = 0;
|
||||
}
|
||||
|
@ -768,7 +811,7 @@ class WidgetAnnotation extends Annotation {
|
|||
// Hide signatures because we cannot validate them, and unset the fieldValue
|
||||
// since it's (most likely) a `Dict` which is non-serializable and will thus
|
||||
// cause errors when sending annotations to the main-thread (issue 10347).
|
||||
if (data.fieldType === 'Sig') {
|
||||
if (data.fieldType === "Sig") {
|
||||
data.fieldValue = null;
|
||||
this.setFlags(AnnotationFlag.HIDDEN);
|
||||
}
|
||||
|
@ -786,26 +829,26 @@ class WidgetAnnotation extends Annotation {
|
|||
_constructFieldName(dict) {
|
||||
// Both the `Parent` and `T` fields are optional. While at least one of
|
||||
// them should be provided, bad PDF generators may fail to do so.
|
||||
if (!dict.has('T') && !dict.has('Parent')) {
|
||||
warn('Unknown field name, falling back to empty field name.');
|
||||
return '';
|
||||
if (!dict.has("T") && !dict.has("Parent")) {
|
||||
warn("Unknown field name, falling back to empty field name.");
|
||||
return "";
|
||||
}
|
||||
|
||||
// If no parent exists, the partial and fully qualified names are equal.
|
||||
if (!dict.has('Parent')) {
|
||||
return stringToPDFString(dict.get('T'));
|
||||
if (!dict.has("Parent")) {
|
||||
return stringToPDFString(dict.get("T"));
|
||||
}
|
||||
|
||||
// Form the fully qualified field name by appending the partial name to
|
||||
// the parent's fully qualified name, separated by a period.
|
||||
const fieldName = [];
|
||||
if (dict.has('T')) {
|
||||
fieldName.unshift(stringToPDFString(dict.get('T')));
|
||||
if (dict.has("T")) {
|
||||
fieldName.unshift(stringToPDFString(dict.get("T")));
|
||||
}
|
||||
|
||||
let loopDict = dict;
|
||||
while (loopDict.has('Parent')) {
|
||||
loopDict = loopDict.get('Parent');
|
||||
while (loopDict.has("Parent")) {
|
||||
loopDict = loopDict.get("Parent");
|
||||
if (!isDict(loopDict)) {
|
||||
// Even though it is not allowed according to the PDF specification,
|
||||
// bad PDF generators may provide a `Parent` entry that is not a
|
||||
|
@ -813,11 +856,11 @@ class WidgetAnnotation extends Annotation {
|
|||
break;
|
||||
}
|
||||
|
||||
if (loopDict.has('T')) {
|
||||
fieldName.unshift(stringToPDFString(loopDict.get('T')));
|
||||
if (loopDict.has("T")) {
|
||||
fieldName.unshift(stringToPDFString(loopDict.get("T")));
|
||||
}
|
||||
}
|
||||
return fieldName.join('.');
|
||||
return fieldName.join(".");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -851,17 +894,17 @@ class TextWidgetAnnotation extends WidgetAnnotation {
|
|||
const dict = params.dict;
|
||||
|
||||
// The field value is always a string.
|
||||
this.data.fieldValue = stringToPDFString(this.data.fieldValue || '');
|
||||
this.data.fieldValue = stringToPDFString(this.data.fieldValue || "");
|
||||
|
||||
// Determine the alignment of text in the field.
|
||||
let alignment = getInheritableProperty({ dict, key: 'Q', });
|
||||
let alignment = getInheritableProperty({ dict, key: "Q" });
|
||||
if (!Number.isInteger(alignment) || alignment < 0 || alignment > 2) {
|
||||
alignment = null;
|
||||
}
|
||||
this.data.textAlignment = alignment;
|
||||
|
||||
// Determine the maximum length of text in the field.
|
||||
let maximumLength = getInheritableProperty({ dict, key: 'MaxLen', });
|
||||
let maximumLength = getInheritableProperty({ dict, key: "MaxLen" });
|
||||
if (!Number.isInteger(maximumLength) || maximumLength < 0) {
|
||||
maximumLength = null;
|
||||
}
|
||||
|
@ -869,11 +912,12 @@ class TextWidgetAnnotation extends WidgetAnnotation {
|
|||
|
||||
// Process field flags for the display layer.
|
||||
this.data.multiLine = this.hasFieldFlag(AnnotationFieldFlag.MULTILINE);
|
||||
this.data.comb = this.hasFieldFlag(AnnotationFieldFlag.COMB) &&
|
||||
!this.hasFieldFlag(AnnotationFieldFlag.MULTILINE) &&
|
||||
!this.hasFieldFlag(AnnotationFieldFlag.PASSWORD) &&
|
||||
!this.hasFieldFlag(AnnotationFieldFlag.FILESELECT) &&
|
||||
this.data.maxLen !== null;
|
||||
this.data.comb =
|
||||
this.hasFieldFlag(AnnotationFieldFlag.COMB) &&
|
||||
!this.hasFieldFlag(AnnotationFieldFlag.MULTILINE) &&
|
||||
!this.hasFieldFlag(AnnotationFieldFlag.PASSWORD) &&
|
||||
!this.hasFieldFlag(AnnotationFieldFlag.FILESELECT) &&
|
||||
this.data.maxLen !== null;
|
||||
}
|
||||
|
||||
getOperatorList(evaluator, task, renderForms) {
|
||||
|
@ -890,14 +934,16 @@ class TextWidgetAnnotation extends WidgetAnnotation {
|
|||
}
|
||||
|
||||
const stream = new Stream(stringToBytes(this.data.defaultAppearance));
|
||||
return evaluator.getOperatorList({
|
||||
stream,
|
||||
task,
|
||||
resources: this.fieldResources,
|
||||
operatorList,
|
||||
}).then(function () {
|
||||
return operatorList;
|
||||
});
|
||||
return evaluator
|
||||
.getOperatorList({
|
||||
stream,
|
||||
task,
|
||||
resources: this.fieldResources,
|
||||
operatorList,
|
||||
})
|
||||
.then(function() {
|
||||
return operatorList;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -905,10 +951,12 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
|
|||
constructor(params) {
|
||||
super(params);
|
||||
|
||||
this.data.checkBox = !this.hasFieldFlag(AnnotationFieldFlag.RADIO) &&
|
||||
!this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
|
||||
this.data.radioButton = this.hasFieldFlag(AnnotationFieldFlag.RADIO) &&
|
||||
!this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
|
||||
this.data.checkBox =
|
||||
!this.hasFieldFlag(AnnotationFieldFlag.RADIO) &&
|
||||
!this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
|
||||
this.data.radioButton =
|
||||
this.hasFieldFlag(AnnotationFieldFlag.RADIO) &&
|
||||
!this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
|
||||
this.data.pushButton = this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
|
||||
|
||||
if (this.data.checkBox) {
|
||||
|
@ -918,7 +966,7 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
|
|||
} else if (this.data.pushButton) {
|
||||
this._processPushButton(params);
|
||||
} else {
|
||||
warn('Invalid field flags for button widget annotation');
|
||||
warn("Invalid field flags for button widget annotation");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -927,12 +975,12 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
|
|||
this.data.fieldValue = this.data.fieldValue.name;
|
||||
}
|
||||
|
||||
const customAppearance = params.dict.get('AP');
|
||||
const customAppearance = params.dict.get("AP");
|
||||
if (!isDict(customAppearance)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const exportValueOptionsDict = customAppearance.get('D');
|
||||
const exportValueOptionsDict = customAppearance.get("D");
|
||||
if (!isDict(exportValueOptionsDict)) {
|
||||
return;
|
||||
}
|
||||
|
@ -943,8 +991,8 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
|
|||
return;
|
||||
}
|
||||
|
||||
this.data.exportValue = exportValues[0] === 'Off' ?
|
||||
exportValues[1] : exportValues[0];
|
||||
this.data.exportValue =
|
||||
exportValues[0] === "Off" ? exportValues[1] : exportValues[0];
|
||||
}
|
||||
|
||||
_processRadioButton(params) {
|
||||
|
@ -952,25 +1000,25 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
|
|||
|
||||
// The parent field's `V` entry holds a `Name` object with the appearance
|
||||
// state of whichever child field is currently in the "on" state.
|
||||
const fieldParent = params.dict.get('Parent');
|
||||
if (isDict(fieldParent) && fieldParent.has('V')) {
|
||||
const fieldParentValue = fieldParent.get('V');
|
||||
const fieldParent = params.dict.get("Parent");
|
||||
if (isDict(fieldParent) && fieldParent.has("V")) {
|
||||
const fieldParentValue = fieldParent.get("V");
|
||||
if (isName(fieldParentValue)) {
|
||||
this.data.fieldValue = fieldParentValue.name;
|
||||
}
|
||||
}
|
||||
|
||||
// The button's value corresponds to its appearance state.
|
||||
const appearanceStates = params.dict.get('AP');
|
||||
const appearanceStates = params.dict.get("AP");
|
||||
if (!isDict(appearanceStates)) {
|
||||
return;
|
||||
}
|
||||
const normalAppearanceState = appearanceStates.get('N');
|
||||
const normalAppearanceState = appearanceStates.get("N");
|
||||
if (!isDict(normalAppearanceState)) {
|
||||
return;
|
||||
}
|
||||
for (const key of normalAppearanceState.getKeys()) {
|
||||
if (key !== 'Off') {
|
||||
if (key !== "Off") {
|
||||
this.data.buttonValue = key;
|
||||
break;
|
||||
}
|
||||
|
@ -978,8 +1026,8 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
|
|||
}
|
||||
|
||||
_processPushButton(params) {
|
||||
if (!params.dict.has('A')) {
|
||||
warn('Push buttons without action dictionaries are not supported');
|
||||
if (!params.dict.has("A")) {
|
||||
warn("Push buttons without action dictionaries are not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1006,7 +1054,7 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation {
|
|||
// inherit the options from a parent annotation (issue 8094).
|
||||
this.data.options = [];
|
||||
|
||||
const options = getInheritableProperty({ dict: params.dict, key: 'Opt', });
|
||||
const options = getInheritableProperty({ dict: params.dict, key: "Opt" });
|
||||
if (Array.isArray(options)) {
|
||||
const xref = params.xref;
|
||||
for (let i = 0, ii = options.length; i < ii; i++) {
|
||||
|
@ -1015,8 +1063,9 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation {
|
|||
|
||||
this.data.options[i] = {
|
||||
exportValue: isOptionArray ? xref.fetchIfRef(option[0]) : option,
|
||||
displayValue: stringToPDFString(isOptionArray ?
|
||||
xref.fetchIfRef(option[1]) : option),
|
||||
displayValue: stringToPDFString(
|
||||
isOptionArray ? xref.fetchIfRef(option[1]) : option
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1044,17 +1093,16 @@ class TextAnnotation extends MarkupAnnotation {
|
|||
this.data.annotationType = AnnotationType.TEXT;
|
||||
|
||||
if (this.data.hasAppearance) {
|
||||
this.data.name = 'NoIcon';
|
||||
this.data.name = "NoIcon";
|
||||
} else {
|
||||
this.data.rect[1] = this.data.rect[3] - DEFAULT_ICON_SIZE;
|
||||
this.data.rect[2] = this.data.rect[0] + DEFAULT_ICON_SIZE;
|
||||
this.data.name = dict.has('Name') ?
|
||||
dict.get('Name').name : 'Note';
|
||||
this.data.name = dict.has("Name") ? dict.get("Name").name : "Note";
|
||||
}
|
||||
|
||||
if (dict.has('State')) {
|
||||
this.data.state = dict.get('State') || null;
|
||||
this.data.stateModel = dict.get('StateModel') || null;
|
||||
if (dict.has("State")) {
|
||||
this.data.state = dict.get("State") || null;
|
||||
this.data.stateModel = dict.get("StateModel") || null;
|
||||
} else {
|
||||
this.data.state = null;
|
||||
this.data.stateModel = null;
|
||||
|
@ -1087,36 +1135,36 @@ class PopupAnnotation extends Annotation {
|
|||
|
||||
this.data.annotationType = AnnotationType.POPUP;
|
||||
|
||||
let parentItem = parameters.dict.get('Parent');
|
||||
let parentItem = parameters.dict.get("Parent");
|
||||
if (!parentItem) {
|
||||
warn('Popup annotation has a missing or invalid parent annotation.');
|
||||
warn("Popup annotation has a missing or invalid parent annotation.");
|
||||
return;
|
||||
}
|
||||
|
||||
const parentSubtype = parentItem.get('Subtype');
|
||||
const parentSubtype = parentItem.get("Subtype");
|
||||
this.data.parentType = isName(parentSubtype) ? parentSubtype.name : null;
|
||||
const rawParent = parameters.dict.getRaw('Parent');
|
||||
const rawParent = parameters.dict.getRaw("Parent");
|
||||
this.data.parentId = isRef(rawParent) ? rawParent.toString() : null;
|
||||
|
||||
const rt = parentItem.get('RT');
|
||||
const rt = parentItem.get("RT");
|
||||
if (isName(rt, AnnotationReplyType.GROUP)) {
|
||||
// Subordinate annotations in a group should inherit
|
||||
// the group attributes from the primary annotation.
|
||||
parentItem = parentItem.get('IRT');
|
||||
parentItem = parentItem.get("IRT");
|
||||
}
|
||||
|
||||
if (!parentItem.has('M')) {
|
||||
if (!parentItem.has("M")) {
|
||||
this.data.modificationDate = null;
|
||||
} else {
|
||||
this.setModificationDate(parentItem.get('M'));
|
||||
this.setModificationDate(parentItem.get("M"));
|
||||
this.data.modificationDate = this.modificationDate;
|
||||
}
|
||||
|
||||
if (!parentItem.has('C')) {
|
||||
if (!parentItem.has("C")) {
|
||||
// Fall back to the default background color.
|
||||
this.data.color = null;
|
||||
} else {
|
||||
this.setColor(parentItem.getArray('C'));
|
||||
this.setColor(parentItem.getArray("C"));
|
||||
this.data.color = this.color;
|
||||
}
|
||||
|
||||
|
@ -1124,14 +1172,14 @@ class PopupAnnotation extends Annotation {
|
|||
// that is most likely a bug. Fallback to inherit the flags from the parent
|
||||
// annotation (this is consistent with the behaviour in Adobe Reader).
|
||||
if (!this.viewable) {
|
||||
const parentFlags = parentItem.get('F');
|
||||
const parentFlags = parentItem.get("F");
|
||||
if (this._isViewable(parentFlags)) {
|
||||
this.setFlags(parentFlags);
|
||||
}
|
||||
}
|
||||
|
||||
this.data.title = stringToPDFString(parentItem.get('T') || '');
|
||||
this.data.contents = stringToPDFString(parentItem.get('Contents') || '');
|
||||
this.data.title = stringToPDFString(parentItem.get("T") || "");
|
||||
this.data.contents = stringToPDFString(parentItem.get("Contents") || "");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1149,8 +1197,9 @@ class LineAnnotation extends MarkupAnnotation {
|
|||
|
||||
this.data.annotationType = AnnotationType.LINE;
|
||||
|
||||
this.data.lineCoordinates =
|
||||
Util.normalizeRect(parameters.dict.getArray('L'));
|
||||
this.data.lineCoordinates = Util.normalizeRect(
|
||||
parameters.dict.getArray("L")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1179,7 +1228,7 @@ class PolylineAnnotation extends MarkupAnnotation {
|
|||
// The vertices array is an array of numbers representing the alternating
|
||||
// horizontal and vertical coordinates, respectively, of each vertex.
|
||||
// Convert this to an array of objects with x and y coordinates.
|
||||
const rawVertices = parameters.dict.getArray('Vertices');
|
||||
const rawVertices = parameters.dict.getArray("Vertices");
|
||||
this.data.vertices = [];
|
||||
for (let i = 0, ii = rawVertices.length; i < ii; i += 2) {
|
||||
this.data.vertices.push({
|
||||
|
@ -1214,7 +1263,7 @@ class InkAnnotation extends MarkupAnnotation {
|
|||
this.data.annotationType = AnnotationType.INK;
|
||||
|
||||
const xref = parameters.xref;
|
||||
const originalInkLists = parameters.dict.getArray('InkList');
|
||||
const originalInkLists = parameters.dict.getArray("InkList");
|
||||
this.data.inkLists = [];
|
||||
for (let i = 0, ii = originalInkLists.length; i < ii; ++i) {
|
||||
// The raw ink lists array contains arrays of numbers representing
|
||||
|
@ -1296,7 +1345,7 @@ class FileAttachmentAnnotation extends MarkupAnnotation {
|
|||
constructor(parameters) {
|
||||
super(parameters);
|
||||
|
||||
const file = new FileSpec(parameters.dict.get('FS'), parameters.xref);
|
||||
const file = new FileSpec(parameters.dict.get("FS"), parameters.xref);
|
||||
|
||||
this.data.annotationType = AnnotationType.FILEATTACHMENT;
|
||||
this.data.file = file.serializable;
|
||||
|
|
|
@ -16,53 +16,53 @@
|
|||
|
||||
// Table C-2
|
||||
const QeTable = [
|
||||
{ qe: 0x5601, nmps: 1, nlps: 1, switchFlag: 1, },
|
||||
{ qe: 0x3401, nmps: 2, nlps: 6, switchFlag: 0, },
|
||||
{ qe: 0x1801, nmps: 3, nlps: 9, switchFlag: 0, },
|
||||
{ qe: 0x0AC1, nmps: 4, nlps: 12, switchFlag: 0, },
|
||||
{ qe: 0x0521, nmps: 5, nlps: 29, switchFlag: 0, },
|
||||
{ qe: 0x0221, nmps: 38, nlps: 33, switchFlag: 0, },
|
||||
{ qe: 0x5601, nmps: 7, nlps: 6, switchFlag: 1, },
|
||||
{ qe: 0x5401, nmps: 8, nlps: 14, switchFlag: 0, },
|
||||
{ qe: 0x4801, nmps: 9, nlps: 14, switchFlag: 0, },
|
||||
{ qe: 0x3801, nmps: 10, nlps: 14, switchFlag: 0, },
|
||||
{ qe: 0x3001, nmps: 11, nlps: 17, switchFlag: 0, },
|
||||
{ qe: 0x2401, nmps: 12, nlps: 18, switchFlag: 0, },
|
||||
{ qe: 0x1C01, nmps: 13, nlps: 20, switchFlag: 0, },
|
||||
{ qe: 0x1601, nmps: 29, nlps: 21, switchFlag: 0, },
|
||||
{ qe: 0x5601, nmps: 15, nlps: 14, switchFlag: 1, },
|
||||
{ qe: 0x5401, nmps: 16, nlps: 14, switchFlag: 0, },
|
||||
{ qe: 0x5101, nmps: 17, nlps: 15, switchFlag: 0, },
|
||||
{ qe: 0x4801, nmps: 18, nlps: 16, switchFlag: 0, },
|
||||
{ qe: 0x3801, nmps: 19, nlps: 17, switchFlag: 0, },
|
||||
{ qe: 0x3401, nmps: 20, nlps: 18, switchFlag: 0, },
|
||||
{ qe: 0x3001, nmps: 21, nlps: 19, switchFlag: 0, },
|
||||
{ qe: 0x2801, nmps: 22, nlps: 19, switchFlag: 0, },
|
||||
{ qe: 0x2401, nmps: 23, nlps: 20, switchFlag: 0, },
|
||||
{ qe: 0x2201, nmps: 24, nlps: 21, switchFlag: 0, },
|
||||
{ qe: 0x1C01, nmps: 25, nlps: 22, switchFlag: 0, },
|
||||
{ qe: 0x1801, nmps: 26, nlps: 23, switchFlag: 0, },
|
||||
{ qe: 0x1601, nmps: 27, nlps: 24, switchFlag: 0, },
|
||||
{ qe: 0x1401, nmps: 28, nlps: 25, switchFlag: 0, },
|
||||
{ qe: 0x1201, nmps: 29, nlps: 26, switchFlag: 0, },
|
||||
{ qe: 0x1101, nmps: 30, nlps: 27, switchFlag: 0, },
|
||||
{ qe: 0x0AC1, nmps: 31, nlps: 28, switchFlag: 0, },
|
||||
{ qe: 0x09C1, nmps: 32, nlps: 29, switchFlag: 0, },
|
||||
{ qe: 0x08A1, nmps: 33, nlps: 30, switchFlag: 0, },
|
||||
{ qe: 0x0521, nmps: 34, nlps: 31, switchFlag: 0, },
|
||||
{ qe: 0x0441, nmps: 35, nlps: 32, switchFlag: 0, },
|
||||
{ qe: 0x02A1, nmps: 36, nlps: 33, switchFlag: 0, },
|
||||
{ qe: 0x0221, nmps: 37, nlps: 34, switchFlag: 0, },
|
||||
{ qe: 0x0141, nmps: 38, nlps: 35, switchFlag: 0, },
|
||||
{ qe: 0x0111, nmps: 39, nlps: 36, switchFlag: 0, },
|
||||
{ qe: 0x0085, nmps: 40, nlps: 37, switchFlag: 0, },
|
||||
{ qe: 0x0049, nmps: 41, nlps: 38, switchFlag: 0, },
|
||||
{ qe: 0x0025, nmps: 42, nlps: 39, switchFlag: 0, },
|
||||
{ qe: 0x0015, nmps: 43, nlps: 40, switchFlag: 0, },
|
||||
{ qe: 0x0009, nmps: 44, nlps: 41, switchFlag: 0, },
|
||||
{ qe: 0x0005, nmps: 45, nlps: 42, switchFlag: 0, },
|
||||
{ qe: 0x0001, nmps: 45, nlps: 43, switchFlag: 0, },
|
||||
{ qe: 0x5601, nmps: 46, nlps: 46, switchFlag: 0, },
|
||||
{ qe: 0x5601, nmps: 1, nlps: 1, switchFlag: 1 },
|
||||
{ qe: 0x3401, nmps: 2, nlps: 6, switchFlag: 0 },
|
||||
{ qe: 0x1801, nmps: 3, nlps: 9, switchFlag: 0 },
|
||||
{ qe: 0x0ac1, nmps: 4, nlps: 12, switchFlag: 0 },
|
||||
{ qe: 0x0521, nmps: 5, nlps: 29, switchFlag: 0 },
|
||||
{ qe: 0x0221, nmps: 38, nlps: 33, switchFlag: 0 },
|
||||
{ qe: 0x5601, nmps: 7, nlps: 6, switchFlag: 1 },
|
||||
{ qe: 0x5401, nmps: 8, nlps: 14, switchFlag: 0 },
|
||||
{ qe: 0x4801, nmps: 9, nlps: 14, switchFlag: 0 },
|
||||
{ qe: 0x3801, nmps: 10, nlps: 14, switchFlag: 0 },
|
||||
{ qe: 0x3001, nmps: 11, nlps: 17, switchFlag: 0 },
|
||||
{ qe: 0x2401, nmps: 12, nlps: 18, switchFlag: 0 },
|
||||
{ qe: 0x1c01, nmps: 13, nlps: 20, switchFlag: 0 },
|
||||
{ qe: 0x1601, nmps: 29, nlps: 21, switchFlag: 0 },
|
||||
{ qe: 0x5601, nmps: 15, nlps: 14, switchFlag: 1 },
|
||||
{ qe: 0x5401, nmps: 16, nlps: 14, switchFlag: 0 },
|
||||
{ qe: 0x5101, nmps: 17, nlps: 15, switchFlag: 0 },
|
||||
{ qe: 0x4801, nmps: 18, nlps: 16, switchFlag: 0 },
|
||||
{ qe: 0x3801, nmps: 19, nlps: 17, switchFlag: 0 },
|
||||
{ qe: 0x3401, nmps: 20, nlps: 18, switchFlag: 0 },
|
||||
{ qe: 0x3001, nmps: 21, nlps: 19, switchFlag: 0 },
|
||||
{ qe: 0x2801, nmps: 22, nlps: 19, switchFlag: 0 },
|
||||
{ qe: 0x2401, nmps: 23, nlps: 20, switchFlag: 0 },
|
||||
{ qe: 0x2201, nmps: 24, nlps: 21, switchFlag: 0 },
|
||||
{ qe: 0x1c01, nmps: 25, nlps: 22, switchFlag: 0 },
|
||||
{ qe: 0x1801, nmps: 26, nlps: 23, switchFlag: 0 },
|
||||
{ qe: 0x1601, nmps: 27, nlps: 24, switchFlag: 0 },
|
||||
{ qe: 0x1401, nmps: 28, nlps: 25, switchFlag: 0 },
|
||||
{ qe: 0x1201, nmps: 29, nlps: 26, switchFlag: 0 },
|
||||
{ qe: 0x1101, nmps: 30, nlps: 27, switchFlag: 0 },
|
||||
{ qe: 0x0ac1, nmps: 31, nlps: 28, switchFlag: 0 },
|
||||
{ qe: 0x09c1, nmps: 32, nlps: 29, switchFlag: 0 },
|
||||
{ qe: 0x08a1, nmps: 33, nlps: 30, switchFlag: 0 },
|
||||
{ qe: 0x0521, nmps: 34, nlps: 31, switchFlag: 0 },
|
||||
{ qe: 0x0441, nmps: 35, nlps: 32, switchFlag: 0 },
|
||||
{ qe: 0x02a1, nmps: 36, nlps: 33, switchFlag: 0 },
|
||||
{ qe: 0x0221, nmps: 37, nlps: 34, switchFlag: 0 },
|
||||
{ qe: 0x0141, nmps: 38, nlps: 35, switchFlag: 0 },
|
||||
{ qe: 0x0111, nmps: 39, nlps: 36, switchFlag: 0 },
|
||||
{ qe: 0x0085, nmps: 40, nlps: 37, switchFlag: 0 },
|
||||
{ qe: 0x0049, nmps: 41, nlps: 38, switchFlag: 0 },
|
||||
{ qe: 0x0025, nmps: 42, nlps: 39, switchFlag: 0 },
|
||||
{ qe: 0x0015, nmps: 43, nlps: 40, switchFlag: 0 },
|
||||
{ qe: 0x0009, nmps: 44, nlps: 41, switchFlag: 0 },
|
||||
{ qe: 0x0005, nmps: 45, nlps: 42, switchFlag: 0 },
|
||||
{ qe: 0x0001, nmps: 45, nlps: 43, switchFlag: 0 },
|
||||
{ qe: 0x5601, nmps: 46, nlps: 46, switchFlag: 0 },
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -86,8 +86,8 @@ class ArithmeticDecoder {
|
|||
|
||||
this.byteIn();
|
||||
|
||||
this.chigh = ((this.chigh << 7) & 0xFFFF) | ((this.clow >> 9) & 0x7F);
|
||||
this.clow = (this.clow << 7) & 0xFFFF;
|
||||
this.chigh = ((this.chigh << 7) & 0xffff) | ((this.clow >> 9) & 0x7f);
|
||||
this.clow = (this.clow << 7) & 0xffff;
|
||||
this.ct -= 7;
|
||||
this.a = 0x8000;
|
||||
}
|
||||
|
@ -97,25 +97,25 @@ class ArithmeticDecoder {
|
|||
const data = this.data;
|
||||
let bp = this.bp;
|
||||
|
||||
if (data[bp] === 0xFF) {
|
||||
if (data[bp + 1] > 0x8F) {
|
||||
this.clow += 0xFF00;
|
||||
if (data[bp] === 0xff) {
|
||||
if (data[bp + 1] > 0x8f) {
|
||||
this.clow += 0xff00;
|
||||
this.ct = 8;
|
||||
} else {
|
||||
bp++;
|
||||
this.clow += (data[bp] << 9);
|
||||
this.clow += data[bp] << 9;
|
||||
this.ct = 7;
|
||||
this.bp = bp;
|
||||
}
|
||||
} else {
|
||||
bp++;
|
||||
this.clow += bp < this.dataEnd ? (data[bp] << 8) : 0xFF00;
|
||||
this.clow += bp < this.dataEnd ? data[bp] << 8 : 0xff00;
|
||||
this.ct = 8;
|
||||
this.bp = bp;
|
||||
}
|
||||
if (this.clow > 0xFFFF) {
|
||||
this.chigh += (this.clow >> 16);
|
||||
this.clow &= 0xFFFF;
|
||||
if (this.clow > 0xffff) {
|
||||
this.chigh += this.clow >> 16;
|
||||
this.clow &= 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,8 @@ class ArithmeticDecoder {
|
|||
readBit(contexts, pos) {
|
||||
// Contexts are packed into 1 byte:
|
||||
// highest 7 bits carry cx.index, lowest bit carries cx.mps
|
||||
let cx_index = contexts[pos] >> 1, cx_mps = contexts[pos] & 1;
|
||||
let cx_index = contexts[pos] >> 1,
|
||||
cx_mps = contexts[pos] & 1;
|
||||
const qeTableIcx = QeTable[cx_index];
|
||||
const qeIcx = qeTableIcx.qe;
|
||||
let d;
|
||||
|
@ -168,17 +169,15 @@ class ArithmeticDecoder {
|
|||
}
|
||||
|
||||
a <<= 1;
|
||||
this.chigh = ((this.chigh << 1) & 0xFFFF) | ((this.clow >> 15) & 1);
|
||||
this.clow = (this.clow << 1) & 0xFFFF;
|
||||
this.chigh = ((this.chigh << 1) & 0xffff) | ((this.clow >> 15) & 1);
|
||||
this.clow = (this.clow << 1) & 0xffff;
|
||||
this.ct--;
|
||||
} while ((a & 0x8000) === 0);
|
||||
this.a = a;
|
||||
|
||||
contexts[pos] = cx_index << 1 | cx_mps;
|
||||
contexts[pos] = (cx_index << 1) | cx_mps;
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
ArithmeticDecoder,
|
||||
};
|
||||
export { ArithmeticDecoder };
|
||||
|
|
181
src/core/bidi.js
181
src/core/bidi.js
|
@ -13,32 +13,32 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { warn } from '../shared/util';
|
||||
import { warn } from "../shared/util";
|
||||
|
||||
// Character types for symbols from 0000 to 00FF.
|
||||
// Source: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
|
||||
// prettier-ignore
|
||||
var baseTypes = [
|
||||
'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'S', 'B', 'S',
|
||||
'WS', 'B', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',
|
||||
'BN', 'BN', 'BN', 'BN', 'B', 'B', 'B', 'S', 'WS', 'ON', 'ON', 'ET',
|
||||
'ET', 'ET', 'ON', 'ON', 'ON', 'ON', 'ON', 'ES', 'CS', 'ES', 'CS', 'CS',
|
||||
'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'CS', 'ON',
|
||||
'ON', 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'L', 'ON', 'ON', 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'ON', 'ON', 'ON', 'ON',
|
||||
'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'B', 'BN', 'BN', 'BN', 'BN', 'BN',
|
||||
'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',
|
||||
'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'CS', 'ON', 'ET',
|
||||
'ET', 'ET', 'ET', 'ON', 'ON', 'ON', 'ON', 'L', 'ON', 'ON', 'BN', 'ON',
|
||||
'ON', 'ET', 'ET', 'EN', 'EN', 'ON', 'L', 'ON', 'ON', 'ON', 'EN', 'L',
|
||||
'ON', 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
|
||||
'L', 'L', 'L', 'L', 'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L'
|
||||
"BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "S", "B", "S",
|
||||
"WS", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN",
|
||||
"BN", "BN", "BN", "BN", "B", "B", "B", "S", "WS", "ON", "ON", "ET",
|
||||
"ET", "ET", "ON", "ON", "ON", "ON", "ON", "ES", "CS", "ES", "CS", "CS",
|
||||
"EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "CS", "ON",
|
||||
"ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L",
|
||||
"L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L",
|
||||
"L", "L", "L", "L", "ON", "ON", "ON", "ON", "ON", "ON", "L", "L", "L",
|
||||
"L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L",
|
||||
"L", "L", "L", "L", "L", "L", "L", "L", "L", "ON", "ON", "ON", "ON",
|
||||
"BN", "BN", "BN", "BN", "BN", "BN", "B", "BN", "BN", "BN", "BN", "BN",
|
||||
"BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN",
|
||||
"BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "CS", "ON", "ET",
|
||||
"ET", "ET", "ET", "ON", "ON", "ON", "ON", "L", "ON", "ON", "BN", "ON",
|
||||
"ON", "ET", "ET", "EN", "EN", "ON", "L", "ON", "ON", "ON", "EN", "L",
|
||||
"ON", "ON", "ON", "ON", "ON", "L", "L", "L", "L", "L", "L", "L", "L",
|
||||
"L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L",
|
||||
"L", "ON", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L",
|
||||
"L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L",
|
||||
"L", "L", "L", "L", "L", "ON", "L", "L", "L", "L", "L", "L", "L", "L"
|
||||
];
|
||||
|
||||
// Character types for symbols from 0600 to 06FF.
|
||||
|
@ -49,28 +49,28 @@ var baseTypes = [
|
|||
// empty string is required to properly index the items after it.
|
||||
// prettier-ignore
|
||||
var arabicTypes = [
|
||||
'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'ON', 'ON', 'AL', 'ET', 'ET', 'AL',
|
||||
'CS', 'AL', 'ON', 'ON', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM',
|
||||
'NSM', 'NSM', 'NSM', 'NSM', 'AL', 'AL', '', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM',
|
||||
'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM',
|
||||
'NSM', 'NSM', 'NSM', 'NSM', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN',
|
||||
'AN', 'AN', 'AN', 'ET', 'AN', 'AN', 'AL', 'AL', 'AL', 'NSM', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
|
||||
'AL', 'AL', 'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AN',
|
||||
'ON', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL', 'AL', 'NSM', 'NSM',
|
||||
'ON', 'NSM', 'NSM', 'NSM', 'NSM', 'AL', 'AL', 'EN', 'EN', 'EN', 'EN',
|
||||
'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL'
|
||||
"AN", "AN", "AN", "AN", "AN", "AN", "ON", "ON", "AL", "ET", "ET", "AL",
|
||||
"CS", "AL", "ON", "ON", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM",
|
||||
"NSM", "NSM", "NSM", "NSM", "AL", "AL", "", "AL", "AL", "AL", "AL", "AL",
|
||||
"AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL",
|
||||
"AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL",
|
||||
"AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL",
|
||||
"AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM",
|
||||
"NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM",
|
||||
"NSM", "NSM", "NSM", "NSM", "AN", "AN", "AN", "AN", "AN", "AN", "AN",
|
||||
"AN", "AN", "AN", "ET", "AN", "AN", "AL", "AL", "AL", "NSM", "AL", "AL",
|
||||
"AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL",
|
||||
"AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL",
|
||||
"AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL",
|
||||
"AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL",
|
||||
"AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL",
|
||||
"AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL",
|
||||
"AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL",
|
||||
"AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL",
|
||||
"AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN",
|
||||
"ON", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "NSM", "NSM",
|
||||
"ON", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "EN", "EN", "EN", "EN",
|
||||
"EN", "EN", "EN", "EN", "EN", "EN", "AL", "AL", "AL", "AL", "AL", "AL"
|
||||
];
|
||||
|
||||
function isOdd(i) {
|
||||
|
@ -107,7 +107,7 @@ function reverseValues(arr, start, end) {
|
|||
function createBidiText(str, isLTR, vertical) {
|
||||
return {
|
||||
str,
|
||||
dir: (vertical ? 'ttb' : (isLTR ? 'ltr' : 'rtl')),
|
||||
dir: vertical ? "ttb" : isLTR ? "ltr" : "rtl",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -133,20 +133,20 @@ function bidi(str, startLevel, vertical) {
|
|||
chars[i] = str.charAt(i);
|
||||
|
||||
var charCode = str.charCodeAt(i);
|
||||
var charType = 'L';
|
||||
var charType = "L";
|
||||
if (charCode <= 0x00ff) {
|
||||
charType = baseTypes[charCode];
|
||||
} else if (0x0590 <= charCode && charCode <= 0x05f4) {
|
||||
charType = 'R';
|
||||
charType = "R";
|
||||
} else if (0x0600 <= charCode && charCode <= 0x06ff) {
|
||||
charType = arabicTypes[charCode & 0xff];
|
||||
if (!charType) {
|
||||
warn('Bidi: invalid Unicode character ' + charCode.toString(16));
|
||||
warn("Bidi: invalid Unicode character " + charCode.toString(16));
|
||||
}
|
||||
} else if (0x0700 <= charCode && charCode <= 0x08AC) {
|
||||
charType = 'AL';
|
||||
} else if (0x0700 <= charCode && charCode <= 0x08ac) {
|
||||
charType = "AL";
|
||||
}
|
||||
if (charType === 'R' || charType === 'AL' || charType === 'AN') {
|
||||
if (charType === "R" || charType === "AL" || charType === "AN") {
|
||||
numBidi++;
|
||||
}
|
||||
types[i] = charType;
|
||||
|
@ -162,7 +162,7 @@ function bidi(str, startLevel, vertical) {
|
|||
}
|
||||
|
||||
if (startLevel === -1) {
|
||||
if ((numBidi / strLength) < 0.3) {
|
||||
if (numBidi / strLength < 0.3) {
|
||||
isLTR = true;
|
||||
startLevel = 0;
|
||||
} else {
|
||||
|
@ -179,7 +179,7 @@ function bidi(str, startLevel, vertical) {
|
|||
/*
|
||||
X1-X10: skip most of this, since we are NOT doing the embeddings.
|
||||
*/
|
||||
var e = (isOdd(startLevel) ? 'R' : 'L');
|
||||
var e = isOdd(startLevel) ? "R" : "L";
|
||||
var sor = e;
|
||||
var eor = sor;
|
||||
|
||||
|
@ -190,7 +190,7 @@ function bidi(str, startLevel, vertical) {
|
|||
*/
|
||||
var lastType = sor;
|
||||
for (i = 0; i < strLength; ++i) {
|
||||
if (types[i] === 'NSM') {
|
||||
if (types[i] === "NSM") {
|
||||
types[i] = lastType;
|
||||
} else {
|
||||
lastType = types[i];
|
||||
|
@ -206,9 +206,9 @@ function bidi(str, startLevel, vertical) {
|
|||
var t;
|
||||
for (i = 0; i < strLength; ++i) {
|
||||
t = types[i];
|
||||
if (t === 'EN') {
|
||||
types[i] = (lastType === 'AL') ? 'AN' : 'EN';
|
||||
} else if (t === 'R' || t === 'L' || t === 'AL') {
|
||||
if (t === "EN") {
|
||||
types[i] = lastType === "AL" ? "AN" : "EN";
|
||||
} else if (t === "R" || t === "L" || t === "AL") {
|
||||
lastType = t;
|
||||
}
|
||||
}
|
||||
|
@ -218,8 +218,8 @@ function bidi(str, startLevel, vertical) {
|
|||
*/
|
||||
for (i = 0; i < strLength; ++i) {
|
||||
t = types[i];
|
||||
if (t === 'AL') {
|
||||
types[i] = 'R';
|
||||
if (t === "AL") {
|
||||
types[i] = "R";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,12 +229,14 @@ function bidi(str, startLevel, vertical) {
|
|||
type changes to that type:
|
||||
*/
|
||||
for (i = 1; i < strLength - 1; ++i) {
|
||||
if (types[i] === 'ES' && types[i - 1] === 'EN' && types[i + 1] === 'EN') {
|
||||
types[i] = 'EN';
|
||||
if (types[i] === "ES" && types[i - 1] === "EN" && types[i + 1] === "EN") {
|
||||
types[i] = "EN";
|
||||
}
|
||||
if (types[i] === 'CS' &&
|
||||
(types[i - 1] === 'EN' || types[i - 1] === 'AN') &&
|
||||
types[i + 1] === types[i - 1]) {
|
||||
if (
|
||||
types[i] === "CS" &&
|
||||
(types[i - 1] === "EN" || types[i - 1] === "AN") &&
|
||||
types[i + 1] === types[i - 1]
|
||||
) {
|
||||
types[i] = types[i - 1];
|
||||
}
|
||||
}
|
||||
|
@ -244,21 +246,21 @@ function bidi(str, startLevel, vertical) {
|
|||
to all European numbers:
|
||||
*/
|
||||
for (i = 0; i < strLength; ++i) {
|
||||
if (types[i] === 'EN') {
|
||||
if (types[i] === "EN") {
|
||||
// do before
|
||||
var j;
|
||||
for (j = i - 1; j >= 0; --j) {
|
||||
if (types[j] !== 'ET') {
|
||||
if (types[j] !== "ET") {
|
||||
break;
|
||||
}
|
||||
types[j] = 'EN';
|
||||
types[j] = "EN";
|
||||
}
|
||||
// do after
|
||||
for (j = i + 1; j < strLength; ++j) {
|
||||
if (types[j] !== 'ET') {
|
||||
if (types[j] !== "ET") {
|
||||
break;
|
||||
}
|
||||
types[j] = 'EN';
|
||||
types[j] = "EN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -268,8 +270,8 @@ function bidi(str, startLevel, vertical) {
|
|||
*/
|
||||
for (i = 0; i < strLength; ++i) {
|
||||
t = types[i];
|
||||
if (t === 'WS' || t === 'ES' || t === 'ET' || t === 'CS') {
|
||||
types[i] = 'ON';
|
||||
if (t === "WS" || t === "ES" || t === "ET" || t === "CS") {
|
||||
types[i] = "ON";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,9 +283,9 @@ function bidi(str, startLevel, vertical) {
|
|||
lastType = sor;
|
||||
for (i = 0; i < strLength; ++i) {
|
||||
t = types[i];
|
||||
if (t === 'EN') {
|
||||
types[i] = ((lastType === 'L') ? 'L' : 'EN');
|
||||
} else if (t === 'R' || t === 'L') {
|
||||
if (t === "EN") {
|
||||
types[i] = lastType === "L" ? "L" : "EN";
|
||||
} else if (t === "R" || t === "L") {
|
||||
lastType = t;
|
||||
}
|
||||
}
|
||||
|
@ -295,8 +297,8 @@ function bidi(str, startLevel, vertical) {
|
|||
end-of-level-run (eor) are used at level run boundaries.
|
||||
*/
|
||||
for (i = 0; i < strLength; ++i) {
|
||||
if (types[i] === 'ON') {
|
||||
var end = findUnequal(types, i + 1, 'ON');
|
||||
if (types[i] === "ON") {
|
||||
var end = findUnequal(types, i + 1, "ON");
|
||||
var before = sor;
|
||||
if (i > 0) {
|
||||
before = types[i - 1];
|
||||
|
@ -306,11 +308,11 @@ function bidi(str, startLevel, vertical) {
|
|||
if (end + 1 < strLength) {
|
||||
after = types[end + 1];
|
||||
}
|
||||
if (before !== 'L') {
|
||||
before = 'R';
|
||||
if (before !== "L") {
|
||||
before = "R";
|
||||
}
|
||||
if (after !== 'L') {
|
||||
after = 'R';
|
||||
if (after !== "L") {
|
||||
after = "R";
|
||||
}
|
||||
if (before === after) {
|
||||
setValues(types, i, end, before);
|
||||
|
@ -323,7 +325,7 @@ function bidi(str, startLevel, vertical) {
|
|||
N2. Any remaining neutrals take the embedding direction.
|
||||
*/
|
||||
for (i = 0; i < strLength; ++i) {
|
||||
if (types[i] === 'ON') {
|
||||
if (types[i] === "ON") {
|
||||
types[i] = e;
|
||||
}
|
||||
}
|
||||
|
@ -338,13 +340,14 @@ function bidi(str, startLevel, vertical) {
|
|||
for (i = 0; i < strLength; ++i) {
|
||||
t = types[i];
|
||||
if (isEven(levels[i])) {
|
||||
if (t === 'R') {
|
||||
if (t === "R") {
|
||||
levels[i] += 1;
|
||||
} else if (t === 'AN' || t === 'EN') {
|
||||
} else if (t === "AN" || t === "EN") {
|
||||
levels[i] += 2;
|
||||
}
|
||||
} else { // isOdd
|
||||
if (t === 'L' || t === 'AN' || t === 'EN') {
|
||||
} else {
|
||||
// isOdd
|
||||
if (t === "L" || t === "AN" || t === "EN") {
|
||||
levels[i] += 1;
|
||||
}
|
||||
}
|
||||
|
@ -422,13 +425,11 @@ function bidi(str, startLevel, vertical) {
|
|||
// Finally, return string
|
||||
for (i = 0, ii = chars.length; i < ii; ++i) {
|
||||
var ch = chars[i];
|
||||
if (ch === '<' || ch === '>') {
|
||||
chars[i] = '';
|
||||
if (ch === "<" || ch === ">") {
|
||||
chars[i] = "";
|
||||
}
|
||||
}
|
||||
return createBidiText(chars.join(''), isLTR);
|
||||
return createBidiText(chars.join(""), isLTR);
|
||||
}
|
||||
|
||||
export {
|
||||
bidi,
|
||||
};
|
||||
export { bidi };
|
||||
|
|
|
@ -25,10 +25,9 @@
|
|||
* or -1 when EOF is reached.
|
||||
*/
|
||||
|
||||
import { info } from '../shared/util';
|
||||
import { info } from "../shared/util";
|
||||
|
||||
let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
||||
|
||||
const ccittEOL = -2;
|
||||
const ccittEOF = -1;
|
||||
const twoDimPass = 0;
|
||||
|
@ -467,23 +466,23 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
* @param {Object} [options] - Decoding options.
|
||||
*/
|
||||
function CCITTFaxDecoder(source, options = {}) {
|
||||
if (!source || typeof source.next !== 'function') {
|
||||
if (!source || typeof source.next !== "function") {
|
||||
throw new Error('CCITTFaxDecoder - invalid "source" parameter.');
|
||||
}
|
||||
this.source = source;
|
||||
this.eof = false;
|
||||
|
||||
this.encoding = options['K'] || 0;
|
||||
this.eoline = options['EndOfLine'] || false;
|
||||
this.byteAlign = options['EncodedByteAlign'] || false;
|
||||
this.columns = options['Columns'] || 1728;
|
||||
this.rows = options['Rows'] || 0;
|
||||
let eoblock = options['EndOfBlock'];
|
||||
this.encoding = options["K"] || 0;
|
||||
this.eoline = options["EndOfLine"] || false;
|
||||
this.byteAlign = options["EncodedByteAlign"] || false;
|
||||
this.columns = options["Columns"] || 1728;
|
||||
this.rows = options["Rows"] || 0;
|
||||
let eoblock = options["EndOfBlock"];
|
||||
if (eoblock === null || eoblock === undefined) {
|
||||
eoblock = true;
|
||||
}
|
||||
this.eoblock = eoblock;
|
||||
this.black = options['BlackIs1'] || false;
|
||||
this.black = options["BlackIs1"] || false;
|
||||
|
||||
this.codingLine = new Uint32Array(this.columns + 1);
|
||||
this.refLine = new Uint32Array(this.columns + 2);
|
||||
|
@ -556,27 +555,33 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
code1 = code2 = 0;
|
||||
if (blackPixels) {
|
||||
do {
|
||||
code1 += (code3 = this._getBlackCode());
|
||||
code1 += code3 = this._getBlackCode();
|
||||
} while (code3 >= 64);
|
||||
do {
|
||||
code2 += (code3 = this._getWhiteCode());
|
||||
code2 += code3 = this._getWhiteCode();
|
||||
} while (code3 >= 64);
|
||||
} else {
|
||||
do {
|
||||
code1 += (code3 = this._getWhiteCode());
|
||||
code1 += code3 = this._getWhiteCode();
|
||||
} while (code3 >= 64);
|
||||
do {
|
||||
code2 += (code3 = this._getBlackCode());
|
||||
code2 += code3 = this._getBlackCode();
|
||||
} while (code3 >= 64);
|
||||
}
|
||||
this._addPixels(codingLine[this.codingPos] +
|
||||
code1, blackPixels);
|
||||
this._addPixels(
|
||||
codingLine[this.codingPos] + code1,
|
||||
blackPixels
|
||||
);
|
||||
if (codingLine[this.codingPos] < columns) {
|
||||
this._addPixels(codingLine[this.codingPos] + code2,
|
||||
blackPixels ^ 1);
|
||||
this._addPixels(
|
||||
codingLine[this.codingPos] + code2,
|
||||
blackPixels ^ 1
|
||||
);
|
||||
}
|
||||
while (refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns) {
|
||||
while (
|
||||
refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns
|
||||
) {
|
||||
refPos += 2;
|
||||
}
|
||||
break;
|
||||
|
@ -585,8 +590,10 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
blackPixels ^= 1;
|
||||
if (codingLine[this.codingPos] < columns) {
|
||||
++refPos;
|
||||
while (refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns) {
|
||||
while (
|
||||
refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns
|
||||
) {
|
||||
refPos += 2;
|
||||
}
|
||||
}
|
||||
|
@ -596,8 +603,10 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
blackPixels ^= 1;
|
||||
if (codingLine[this.codingPos] < columns) {
|
||||
++refPos;
|
||||
while (refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns) {
|
||||
while (
|
||||
refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns
|
||||
) {
|
||||
refPos += 2;
|
||||
}
|
||||
}
|
||||
|
@ -607,8 +616,10 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
blackPixels ^= 1;
|
||||
if (codingLine[this.codingPos] < columns) {
|
||||
++refPos;
|
||||
while (refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns) {
|
||||
while (
|
||||
refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns
|
||||
) {
|
||||
refPos += 2;
|
||||
}
|
||||
}
|
||||
|
@ -618,8 +629,10 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
blackPixels ^= 1;
|
||||
if (codingLine[this.codingPos] < columns) {
|
||||
++refPos;
|
||||
while (refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns) {
|
||||
while (
|
||||
refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns
|
||||
) {
|
||||
refPos += 2;
|
||||
}
|
||||
}
|
||||
|
@ -633,8 +646,10 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
} else {
|
||||
++refPos;
|
||||
}
|
||||
while (refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns) {
|
||||
while (
|
||||
refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns
|
||||
) {
|
||||
refPos += 2;
|
||||
}
|
||||
}
|
||||
|
@ -648,8 +663,10 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
} else {
|
||||
++refPos;
|
||||
}
|
||||
while (refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns) {
|
||||
while (
|
||||
refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns
|
||||
) {
|
||||
refPos += 2;
|
||||
}
|
||||
}
|
||||
|
@ -663,8 +680,10 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
} else {
|
||||
++refPos;
|
||||
}
|
||||
while (refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns) {
|
||||
while (
|
||||
refLine[refPos] <= codingLine[this.codingPos] &&
|
||||
refLine[refPos] < columns
|
||||
) {
|
||||
refPos += 2;
|
||||
}
|
||||
}
|
||||
|
@ -674,7 +693,7 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
this.eof = true;
|
||||
break;
|
||||
default:
|
||||
info('bad 2d code');
|
||||
info("bad 2d code");
|
||||
this._addPixels(columns, 0);
|
||||
this.err = true;
|
||||
}
|
||||
|
@ -687,11 +706,11 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
code1 = 0;
|
||||
if (blackPixels) {
|
||||
do {
|
||||
code1 += (code3 = this._getBlackCode());
|
||||
code1 += code3 = this._getBlackCode();
|
||||
} while (code3 >= 64);
|
||||
} else {
|
||||
do {
|
||||
code1 += (code3 = this._getWhiteCode());
|
||||
code1 += code3 = this._getWhiteCode();
|
||||
} while (code3 >= 64);
|
||||
}
|
||||
this._addPixels(codingLine[this.codingPos] + code1, blackPixels);
|
||||
|
@ -745,7 +764,7 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
for (i = 0; i < 4; ++i) {
|
||||
code1 = this._lookBits(12);
|
||||
if (code1 !== 1) {
|
||||
info('bad rtc code: ' + code1);
|
||||
info("bad rtc code: " + code1);
|
||||
}
|
||||
this._eatBits(12);
|
||||
if (this.encoding > 0) {
|
||||
|
@ -763,7 +782,7 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
this.eof = true;
|
||||
return -1;
|
||||
}
|
||||
if ((code1 >> 1) === 1) {
|
||||
if (code1 >> 1 === 1) {
|
||||
break;
|
||||
}
|
||||
this._eatBits(1);
|
||||
|
@ -776,21 +795,21 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
}
|
||||
|
||||
if (codingLine[0] > 0) {
|
||||
this.outputBits = codingLine[this.codingPos = 0];
|
||||
this.outputBits = codingLine[(this.codingPos = 0)];
|
||||
} else {
|
||||
this.outputBits = codingLine[this.codingPos = 1];
|
||||
this.outputBits = codingLine[(this.codingPos = 1)];
|
||||
}
|
||||
this.row++;
|
||||
}
|
||||
|
||||
let c;
|
||||
if (this.outputBits >= 8) {
|
||||
c = (this.codingPos & 1) ? 0 : 0xFF;
|
||||
c = this.codingPos & 1 ? 0 : 0xff;
|
||||
this.outputBits -= 8;
|
||||
if (this.outputBits === 0 && codingLine[this.codingPos] < columns) {
|
||||
this.codingPos++;
|
||||
this.outputBits = (codingLine[this.codingPos] -
|
||||
codingLine[this.codingPos - 1]);
|
||||
this.outputBits =
|
||||
codingLine[this.codingPos] - codingLine[this.codingPos - 1];
|
||||
}
|
||||
} else {
|
||||
bits = 8;
|
||||
|
@ -799,21 +818,21 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
if (this.outputBits > bits) {
|
||||
c <<= bits;
|
||||
if (!(this.codingPos & 1)) {
|
||||
c |= 0xFF >> (8 - bits);
|
||||
c |= 0xff >> (8 - bits);
|
||||
}
|
||||
this.outputBits -= bits;
|
||||
bits = 0;
|
||||
} else {
|
||||
c <<= this.outputBits;
|
||||
if (!(this.codingPos & 1)) {
|
||||
c |= 0xFF >> (8 - this.outputBits);
|
||||
c |= 0xff >> (8 - this.outputBits);
|
||||
}
|
||||
bits -= this.outputBits;
|
||||
this.outputBits = 0;
|
||||
if (codingLine[this.codingPos] < columns) {
|
||||
this.codingPos++;
|
||||
this.outputBits = (codingLine[this.codingPos] -
|
||||
codingLine[this.codingPos - 1]);
|
||||
this.outputBits =
|
||||
codingLine[this.codingPos] - codingLine[this.codingPos - 1];
|
||||
} else if (bits > 0) {
|
||||
c <<= bits;
|
||||
bits = 0;
|
||||
|
@ -822,7 +841,7 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
} while (bits);
|
||||
}
|
||||
if (this.black) {
|
||||
c ^= 0xFF;
|
||||
c ^= 0xff;
|
||||
}
|
||||
return c;
|
||||
},
|
||||
|
@ -836,7 +855,7 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
|
||||
if (a1 > codingLine[codingPos]) {
|
||||
if (a1 > this.columns) {
|
||||
info('row is wrong length');
|
||||
info("row is wrong length");
|
||||
this.err = true;
|
||||
a1 = this.columns;
|
||||
}
|
||||
|
@ -858,7 +877,7 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
|
||||
if (a1 > codingLine[codingPos]) {
|
||||
if (a1 > this.columns) {
|
||||
info('row is wrong length');
|
||||
info("row is wrong length");
|
||||
this.err = true;
|
||||
a1 = this.columns;
|
||||
}
|
||||
|
@ -869,7 +888,7 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
codingLine[codingPos] = a1;
|
||||
} else if (a1 < codingLine[codingPos]) {
|
||||
if (a1 < 0) {
|
||||
info('invalid code');
|
||||
info("invalid code");
|
||||
this.err = true;
|
||||
a1 = 0;
|
||||
}
|
||||
|
@ -931,7 +950,7 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
return result[1];
|
||||
}
|
||||
}
|
||||
info('Bad two dim code');
|
||||
info("Bad two dim code");
|
||||
return ccittEOF;
|
||||
},
|
||||
|
||||
|
@ -947,7 +966,7 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
return 1;
|
||||
}
|
||||
|
||||
if ((code >> 5) === 0) {
|
||||
if (code >> 5 === 0) {
|
||||
p = whiteTable1[code];
|
||||
} else {
|
||||
p = whiteTable2[code >> 3];
|
||||
|
@ -968,7 +987,7 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
return result[1];
|
||||
}
|
||||
}
|
||||
info('bad white code');
|
||||
info("bad white code");
|
||||
this._eatBits(1);
|
||||
return 1;
|
||||
},
|
||||
|
@ -983,9 +1002,9 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
if (code === ccittEOF) {
|
||||
return 1;
|
||||
}
|
||||
if ((code >> 7) === 0) {
|
||||
if (code >> 7 === 0) {
|
||||
p = blackTable1[code];
|
||||
} else if ((code >> 9) === 0 && (code >> 7) !== 0) {
|
||||
} else if (code >> 9 === 0 && code >> 7 !== 0) {
|
||||
p = blackTable2[(code >> 1) - 64];
|
||||
} else {
|
||||
p = blackTable3[code >> 7];
|
||||
|
@ -1011,7 +1030,7 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
return result[1];
|
||||
}
|
||||
}
|
||||
info('bad black code');
|
||||
info("bad black code");
|
||||
this._eatBits(1);
|
||||
return 1;
|
||||
},
|
||||
|
@ -1026,13 +1045,12 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
if (this.inputBits === 0) {
|
||||
return ccittEOF;
|
||||
}
|
||||
return ((this.inputBuf << (n - this.inputBits)) &
|
||||
(0xFFFF >> (16 - n)));
|
||||
return (this.inputBuf << (n - this.inputBits)) & (0xffff >> (16 - n));
|
||||
}
|
||||
this.inputBuf = (this.inputBuf << 8) | c;
|
||||
this.inputBits += 8;
|
||||
}
|
||||
return (this.inputBuf >> (this.inputBits - n)) & (0xFFFF >> (16 - n));
|
||||
return (this.inputBuf >> (this.inputBits - n)) & (0xffff >> (16 - n));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1048,6 +1066,4 @@ let CCITTFaxDecoder = (function CCITTFaxDecoder() {
|
|||
return CCITTFaxDecoder;
|
||||
})();
|
||||
|
||||
export {
|
||||
CCITTFaxDecoder,
|
||||
};
|
||||
export { CCITTFaxDecoder };
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Dict, isDict } from './primitives';
|
||||
import { CCITTFaxDecoder } from './ccitt';
|
||||
import { DecodeStream } from './stream';
|
||||
import { Dict, isDict } from "./primitives";
|
||||
import { CCITTFaxDecoder } from "./ccitt";
|
||||
import { DecodeStream } from "./stream";
|
||||
|
||||
var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
||||
function CCITTFaxStream(str, maybeLength, params) {
|
||||
|
@ -32,13 +32,13 @@ var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
|||
},
|
||||
};
|
||||
this.ccittFaxDecoder = new CCITTFaxDecoder(source, {
|
||||
K: params.get('K'),
|
||||
EndOfLine: params.get('EndOfLine'),
|
||||
EncodedByteAlign: params.get('EncodedByteAlign'),
|
||||
Columns: params.get('Columns'),
|
||||
Rows: params.get('Rows'),
|
||||
EndOfBlock: params.get('EndOfBlock'),
|
||||
BlackIs1: params.get('BlackIs1'),
|
||||
K: params.get("K"),
|
||||
EndOfLine: params.get("EndOfLine"),
|
||||
EncodedByteAlign: params.get("EncodedByteAlign"),
|
||||
Columns: params.get("Columns"),
|
||||
Rows: params.get("Rows"),
|
||||
EndOfBlock: params.get("EndOfBlock"),
|
||||
BlackIs1: params.get("BlackIs1"),
|
||||
});
|
||||
|
||||
DecodeStream.call(this, maybeLength);
|
||||
|
@ -61,6 +61,4 @@ var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
|||
return CCITTFaxStream;
|
||||
})();
|
||||
|
||||
export {
|
||||
CCITTFaxStream,
|
||||
};
|
||||
export { CCITTFaxStream };
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,109 +16,105 @@
|
|||
|
||||
// prettier-ignore
|
||||
const ISOAdobeCharset = [
|
||||
'.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar',
|
||||
'percent', 'ampersand', 'quoteright', 'parenleft', 'parenright',
|
||||
'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero',
|
||||
'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight',
|
||||
'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question',
|
||||
'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore',
|
||||
'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
|
||||
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'braceleft', 'bar', 'braceright', 'asciitilde', 'exclamdown', 'cent',
|
||||
'sterling', 'fraction', 'yen', 'florin', 'section', 'currency',
|
||||
'quotesingle', 'quotedblleft', 'guillemotleft', 'guilsinglleft',
|
||||
'guilsinglright', 'fi', 'fl', 'endash', 'dagger', 'daggerdbl',
|
||||
'periodcentered', 'paragraph', 'bullet', 'quotesinglbase',
|
||||
'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis',
|
||||
'perthousand', 'questiondown', 'grave', 'acute', 'circumflex', 'tilde',
|
||||
'macron', 'breve', 'dotaccent', 'dieresis', 'ring', 'cedilla',
|
||||
'hungarumlaut', 'ogonek', 'caron', 'emdash', 'AE', 'ordfeminine',
|
||||
'Lslash', 'Oslash', 'OE', 'ordmasculine', 'ae', 'dotlessi', 'lslash',
|
||||
'oslash', 'oe', 'germandbls', 'onesuperior', 'logicalnot', 'mu',
|
||||
'trademark', 'Eth', 'onehalf', 'plusminus', 'Thorn', 'onequarter',
|
||||
'divide', 'brokenbar', 'degree', 'thorn', 'threequarters', 'twosuperior',
|
||||
'registered', 'minus', 'eth', 'multiply', 'threesuperior', 'copyright',
|
||||
'Aacute', 'Acircumflex', 'Adieresis', 'Agrave', 'Aring', 'Atilde',
|
||||
'Ccedilla', 'Eacute', 'Ecircumflex', 'Edieresis', 'Egrave', 'Iacute',
|
||||
'Icircumflex', 'Idieresis', 'Igrave', 'Ntilde', 'Oacute', 'Ocircumflex',
|
||||
'Odieresis', 'Ograve', 'Otilde', 'Scaron', 'Uacute', 'Ucircumflex',
|
||||
'Udieresis', 'Ugrave', 'Yacute', 'Ydieresis', 'Zcaron', 'aacute',
|
||||
'acircumflex', 'adieresis', 'agrave', 'aring', 'atilde', 'ccedilla',
|
||||
'eacute', 'ecircumflex', 'edieresis', 'egrave', 'iacute', 'icircumflex',
|
||||
'idieresis', 'igrave', 'ntilde', 'oacute', 'ocircumflex', 'odieresis',
|
||||
'ograve', 'otilde', 'scaron', 'uacute', 'ucircumflex', 'udieresis',
|
||||
'ugrave', 'yacute', 'ydieresis', 'zcaron'
|
||||
".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar",
|
||||
"percent", "ampersand", "quoteright", "parenleft", "parenright",
|
||||
"asterisk", "plus", "comma", "hyphen", "period", "slash", "zero",
|
||||
"one", "two", "three", "four", "five", "six", "seven", "eight",
|
||||
"nine", "colon", "semicolon", "less", "equal", "greater", "question",
|
||||
"at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
|
||||
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
|
||||
"bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
|
||||
"quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
|
||||
"m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
|
||||
"braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent",
|
||||
"sterling", "fraction", "yen", "florin", "section", "currency",
|
||||
"quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft",
|
||||
"guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl",
|
||||
"periodcentered", "paragraph", "bullet", "quotesinglbase",
|
||||
"quotedblbase", "quotedblright", "guillemotright", "ellipsis",
|
||||
"perthousand", "questiondown", "grave", "acute", "circumflex", "tilde",
|
||||
"macron", "breve", "dotaccent", "dieresis", "ring", "cedilla",
|
||||
"hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine",
|
||||
"Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash",
|
||||
"oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu",
|
||||
"trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter",
|
||||
"divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior",
|
||||
"registered", "minus", "eth", "multiply", "threesuperior", "copyright",
|
||||
"Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde",
|
||||
"Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute",
|
||||
"Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex",
|
||||
"Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex",
|
||||
"Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute",
|
||||
"acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla",
|
||||
"eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex",
|
||||
"idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis",
|
||||
"ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis",
|
||||
"ugrave", "yacute", "ydieresis", "zcaron"
|
||||
];
|
||||
|
||||
// prettier-ignore
|
||||
const ExpertCharset = [
|
||||
'.notdef', 'space', 'exclamsmall', 'Hungarumlautsmall', 'dollaroldstyle',
|
||||
'dollarsuperior', 'ampersandsmall', 'Acutesmall', 'parenleftsuperior',
|
||||
'parenrightsuperior', 'twodotenleader', 'onedotenleader', 'comma',
|
||||
'hyphen', 'period', 'fraction', 'zerooldstyle', 'oneoldstyle',
|
||||
'twooldstyle', 'threeoldstyle', 'fouroldstyle', 'fiveoldstyle',
|
||||
'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle',
|
||||
'colon', 'semicolon', 'commasuperior', 'threequartersemdash',
|
||||
'periodsuperior', 'questionsmall', 'asuperior', 'bsuperior',
|
||||
'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior',
|
||||
'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior',
|
||||
'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior',
|
||||
'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall',
|
||||
'Asmall', 'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall',
|
||||
'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall',
|
||||
'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall',
|
||||
'Vsmall', 'Wsmall', 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary',
|
||||
'onefitted', 'rupiah', 'Tildesmall', 'exclamdownsmall', 'centoldstyle',
|
||||
'Lslashsmall', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall',
|
||||
'Brevesmall', 'Caronsmall', 'Dotaccentsmall', 'Macronsmall',
|
||||
'figuredash', 'hypheninferior', 'Ogoneksmall', 'Ringsmall',
|
||||
'Cedillasmall', 'onequarter', 'onehalf', 'threequarters',
|
||||
'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths',
|
||||
'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior',
|
||||
'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior',
|
||||
'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior',
|
||||
'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior',
|
||||
'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior',
|
||||
'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior',
|
||||
'periodinferior', 'commainferior', 'Agravesmall', 'Aacutesmall',
|
||||
'Acircumflexsmall', 'Atildesmall', 'Adieresissmall', 'Aringsmall',
|
||||
'AEsmall', 'Ccedillasmall', 'Egravesmall', 'Eacutesmall',
|
||||
'Ecircumflexsmall', 'Edieresissmall', 'Igravesmall', 'Iacutesmall',
|
||||
'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall',
|
||||
'Ogravesmall', 'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall',
|
||||
'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', 'Uacutesmall',
|
||||
'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall',
|
||||
'Ydieresissmall'
|
||||
".notdef", "space", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle",
|
||||
"dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior",
|
||||
"parenrightsuperior", "twodotenleader", "onedotenleader", "comma",
|
||||
"hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle",
|
||||
"twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle",
|
||||
"sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle",
|
||||
"colon", "semicolon", "commasuperior", "threequartersemdash",
|
||||
"periodsuperior", "questionsmall", "asuperior", "bsuperior",
|
||||
"centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior",
|
||||
"msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
|
||||
"tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior",
|
||||
"parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
|
||||
"Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall",
|
||||
"Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall",
|
||||
"Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
|
||||
"Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary",
|
||||
"onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle",
|
||||
"Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall",
|
||||
"Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall",
|
||||
"figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall",
|
||||
"Cedillasmall", "onequarter", "onehalf", "threequarters",
|
||||
"questiondownsmall", "oneeighth", "threeeighths", "fiveeighths",
|
||||
"seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior",
|
||||
"twosuperior", "threesuperior", "foursuperior", "fivesuperior",
|
||||
"sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior",
|
||||
"zeroinferior", "oneinferior", "twoinferior", "threeinferior",
|
||||
"fourinferior", "fiveinferior", "sixinferior", "seveninferior",
|
||||
"eightinferior", "nineinferior", "centinferior", "dollarinferior",
|
||||
"periodinferior", "commainferior", "Agravesmall", "Aacutesmall",
|
||||
"Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall",
|
||||
"AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall",
|
||||
"Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall",
|
||||
"Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall",
|
||||
"Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
|
||||
"Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall",
|
||||
"Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall",
|
||||
"Ydieresissmall"
|
||||
];
|
||||
|
||||
// prettier-ignore
|
||||
const ExpertSubsetCharset = [
|
||||
'.notdef', 'space', 'dollaroldstyle', 'dollarsuperior',
|
||||
'parenleftsuperior', 'parenrightsuperior', 'twodotenleader',
|
||||
'onedotenleader', 'comma', 'hyphen', 'period', 'fraction',
|
||||
'zerooldstyle', 'oneoldstyle', 'twooldstyle', 'threeoldstyle',
|
||||
'fouroldstyle', 'fiveoldstyle', 'sixoldstyle', 'sevenoldstyle',
|
||||
'eightoldstyle', 'nineoldstyle', 'colon', 'semicolon', 'commasuperior',
|
||||
'threequartersemdash', 'periodsuperior', 'asuperior', 'bsuperior',
|
||||
'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior',
|
||||
'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior',
|
||||
'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior',
|
||||
'parenrightinferior', 'hyphensuperior', 'colonmonetary', 'onefitted',
|
||||
'rupiah', 'centoldstyle', 'figuredash', 'hypheninferior', 'onequarter',
|
||||
'onehalf', 'threequarters', 'oneeighth', 'threeeighths', 'fiveeighths',
|
||||
'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior',
|
||||
'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior',
|
||||
'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior',
|
||||
'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior',
|
||||
'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior',
|
||||
'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior',
|
||||
'periodinferior', 'commainferior'
|
||||
".notdef", "space", "dollaroldstyle", "dollarsuperior",
|
||||
"parenleftsuperior", "parenrightsuperior", "twodotenleader",
|
||||
"onedotenleader", "comma", "hyphen", "period", "fraction",
|
||||
"zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle",
|
||||
"fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle",
|
||||
"eightoldstyle", "nineoldstyle", "colon", "semicolon", "commasuperior",
|
||||
"threequartersemdash", "periodsuperior", "asuperior", "bsuperior",
|
||||
"centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior",
|
||||
"msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
|
||||
"tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior",
|
||||
"parenrightinferior", "hyphensuperior", "colonmonetary", "onefitted",
|
||||
"rupiah", "centoldstyle", "figuredash", "hypheninferior", "onequarter",
|
||||
"onehalf", "threequarters", "oneeighth", "threeeighths", "fiveeighths",
|
||||
"seveneighths", "onethird", "twothirds", "zerosuperior", "onesuperior",
|
||||
"twosuperior", "threesuperior", "foursuperior", "fivesuperior",
|
||||
"sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior",
|
||||
"zeroinferior", "oneinferior", "twoinferior", "threeinferior",
|
||||
"fourinferior", "fiveinferior", "sixinferior", "seveninferior",
|
||||
"eightinferior", "nineinferior", "centinferior", "dollarinferior",
|
||||
"periodinferior", "commainferior"
|
||||
];
|
||||
|
||||
export {
|
||||
ISOAdobeCharset,
|
||||
ExpertCharset,
|
||||
ExpertSubsetCharset,
|
||||
};
|
||||
export { ISOAdobeCharset, ExpertCharset, ExpertSubsetCharset };
|
||||
|
|
|
@ -15,9 +15,12 @@
|
|||
/* eslint no-var: error */
|
||||
|
||||
import {
|
||||
arrayByteLength, arraysToBytes, createPromiseCapability, isEmptyObj
|
||||
} from '../shared/util';
|
||||
import { MissingDataException } from './core_utils';
|
||||
arrayByteLength,
|
||||
arraysToBytes,
|
||||
createPromiseCapability,
|
||||
isEmptyObj,
|
||||
} from "../shared/util";
|
||||
import { MissingDataException } from "./core_utils";
|
||||
|
||||
class ChunkedStream {
|
||||
constructor(length, chunkSize, manager) {
|
||||
|
@ -86,8 +89,10 @@ class ChunkedStream {
|
|||
this.bytes.set(new Uint8Array(data), position);
|
||||
position += data.byteLength;
|
||||
this.progressiveDataLength = position;
|
||||
const endChunk = position >= this.end ? this.numChunks :
|
||||
Math.floor(position / this.chunkSize);
|
||||
const endChunk =
|
||||
position >= this.end
|
||||
? this.numChunks
|
||||
: Math.floor(position / this.chunkSize);
|
||||
|
||||
for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) {
|
||||
if (!this.loadedChunks[curChunk]) {
|
||||
|
@ -194,7 +199,7 @@ class ChunkedStream {
|
|||
}
|
||||
const subarray = bytes.subarray(pos, strEnd);
|
||||
// `this.bytes` is always a `Uint8Array` here.
|
||||
return (forceClamped ? new Uint8ClampedArray(subarray) : subarray);
|
||||
return forceClamped ? new Uint8ClampedArray(subarray) : subarray;
|
||||
}
|
||||
|
||||
let end = pos + length;
|
||||
|
@ -208,7 +213,7 @@ class ChunkedStream {
|
|||
this.pos = end;
|
||||
const subarray = bytes.subarray(pos, end);
|
||||
// `this.bytes` is always a `Uint8Array` here.
|
||||
return (forceClamped ? new Uint8ClampedArray(subarray) : subarray);
|
||||
return forceClamped ? new Uint8ClampedArray(subarray) : subarray;
|
||||
}
|
||||
|
||||
peekByte() {
|
||||
|
@ -332,16 +337,17 @@ class ChunkedStreamManager {
|
|||
rangeReader.onProgress = this.onProgress.bind(this);
|
||||
}
|
||||
|
||||
let chunks = [], loaded = 0;
|
||||
let chunks = [],
|
||||
loaded = 0;
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
const readChunk = (chunk) => {
|
||||
const readChunk = chunk => {
|
||||
try {
|
||||
if (!chunk.done) {
|
||||
const data = chunk.value;
|
||||
chunks.push(data);
|
||||
loaded += arrayByteLength(data);
|
||||
if (rangeReader.isStreamingSupported) {
|
||||
this.onProgress({ loaded, });
|
||||
this.onProgress({ loaded });
|
||||
}
|
||||
rangeReader.read().then(readChunk, reject);
|
||||
return;
|
||||
|
@ -355,11 +361,11 @@ class ChunkedStreamManager {
|
|||
};
|
||||
rangeReader.read().then(readChunk, reject);
|
||||
});
|
||||
promise.then((data) => {
|
||||
promise.then(data => {
|
||||
if (this.aborted) {
|
||||
return; // Ignoring any data after abort.
|
||||
}
|
||||
this.onReceiveData({ chunk: data, begin, });
|
||||
this.onReceiveData({ chunk: data, begin });
|
||||
});
|
||||
// TODO check errors
|
||||
}
|
||||
|
@ -470,13 +476,11 @@ class ChunkedStreamManager {
|
|||
}
|
||||
|
||||
if (prevChunk >= 0 && prevChunk + 1 !== chunk) {
|
||||
groupedChunks.push({ beginChunk,
|
||||
endChunk: prevChunk + 1, });
|
||||
groupedChunks.push({ beginChunk, endChunk: prevChunk + 1 });
|
||||
beginChunk = chunk;
|
||||
}
|
||||
if (i + 1 === chunks.length) {
|
||||
groupedChunks.push({ beginChunk,
|
||||
endChunk: chunk + 1, });
|
||||
groupedChunks.push({ beginChunk, endChunk: chunk + 1 });
|
||||
}
|
||||
|
||||
prevChunk = chunk;
|
||||
|
@ -485,7 +489,7 @@ class ChunkedStreamManager {
|
|||
}
|
||||
|
||||
onProgress(args) {
|
||||
this.msgHandler.send('DocProgress', {
|
||||
this.msgHandler.send("DocProgress", {
|
||||
loaded: this.stream.numChunksLoaded * this.chunkSize + args.loaded,
|
||||
total: this.length,
|
||||
});
|
||||
|
@ -498,8 +502,10 @@ class ChunkedStreamManager {
|
|||
const end = begin + chunk.byteLength;
|
||||
|
||||
const beginChunk = Math.floor(begin / this.chunkSize);
|
||||
const endChunk = end < this.length ? Math.floor(end / this.chunkSize) :
|
||||
Math.ceil(end / this.chunkSize);
|
||||
const endChunk =
|
||||
end < this.length
|
||||
? Math.floor(end / this.chunkSize)
|
||||
: Math.ceil(end / this.chunkSize);
|
||||
|
||||
if (isProgressive) {
|
||||
this.stream.onReceiveProgressiveData(chunk);
|
||||
|
@ -557,7 +563,7 @@ class ChunkedStreamManager {
|
|||
capability.resolve();
|
||||
}
|
||||
|
||||
this.msgHandler.send('DocProgress', {
|
||||
this.msgHandler.send("DocProgress", {
|
||||
loaded: this.stream.numChunksLoaded * this.chunkSize,
|
||||
total: this.length,
|
||||
});
|
||||
|
@ -586,7 +592,4 @@ class ChunkedStreamManager {
|
|||
}
|
||||
}
|
||||
|
||||
export {
|
||||
ChunkedStream,
|
||||
ChunkedStreamManager,
|
||||
};
|
||||
export { ChunkedStream, ChunkedStreamManager };
|
||||
|
|
562
src/core/cmap.js
562
src/core/cmap.js
|
@ -14,184 +14,189 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
CMapCompressionType, FormatError, isString, unreachable, warn
|
||||
} from '../shared/util';
|
||||
import { isCmd, isEOF, isName, isStream } from './primitives';
|
||||
import { Lexer } from './parser';
|
||||
import { MissingDataException } from './core_utils';
|
||||
import { Stream } from './stream';
|
||||
CMapCompressionType,
|
||||
FormatError,
|
||||
isString,
|
||||
unreachable,
|
||||
warn,
|
||||
} from "../shared/util";
|
||||
import { isCmd, isEOF, isName, isStream } from "./primitives";
|
||||
import { Lexer } from "./parser";
|
||||
import { MissingDataException } from "./core_utils";
|
||||
import { Stream } from "./stream";
|
||||
|
||||
var BUILT_IN_CMAPS = [
|
||||
// << Start unicode maps.
|
||||
'Adobe-GB1-UCS2',
|
||||
'Adobe-CNS1-UCS2',
|
||||
'Adobe-Japan1-UCS2',
|
||||
'Adobe-Korea1-UCS2',
|
||||
// >> End unicode maps.
|
||||
'78-EUC-H',
|
||||
'78-EUC-V',
|
||||
'78-H',
|
||||
'78-RKSJ-H',
|
||||
'78-RKSJ-V',
|
||||
'78-V',
|
||||
'78ms-RKSJ-H',
|
||||
'78ms-RKSJ-V',
|
||||
'83pv-RKSJ-H',
|
||||
'90ms-RKSJ-H',
|
||||
'90ms-RKSJ-V',
|
||||
'90msp-RKSJ-H',
|
||||
'90msp-RKSJ-V',
|
||||
'90pv-RKSJ-H',
|
||||
'90pv-RKSJ-V',
|
||||
'Add-H',
|
||||
'Add-RKSJ-H',
|
||||
'Add-RKSJ-V',
|
||||
'Add-V',
|
||||
'Adobe-CNS1-0',
|
||||
'Adobe-CNS1-1',
|
||||
'Adobe-CNS1-2',
|
||||
'Adobe-CNS1-3',
|
||||
'Adobe-CNS1-4',
|
||||
'Adobe-CNS1-5',
|
||||
'Adobe-CNS1-6',
|
||||
'Adobe-GB1-0',
|
||||
'Adobe-GB1-1',
|
||||
'Adobe-GB1-2',
|
||||
'Adobe-GB1-3',
|
||||
'Adobe-GB1-4',
|
||||
'Adobe-GB1-5',
|
||||
'Adobe-Japan1-0',
|
||||
'Adobe-Japan1-1',
|
||||
'Adobe-Japan1-2',
|
||||
'Adobe-Japan1-3',
|
||||
'Adobe-Japan1-4',
|
||||
'Adobe-Japan1-5',
|
||||
'Adobe-Japan1-6',
|
||||
'Adobe-Korea1-0',
|
||||
'Adobe-Korea1-1',
|
||||
'Adobe-Korea1-2',
|
||||
'B5-H',
|
||||
'B5-V',
|
||||
'B5pc-H',
|
||||
'B5pc-V',
|
||||
'CNS-EUC-H',
|
||||
'CNS-EUC-V',
|
||||
'CNS1-H',
|
||||
'CNS1-V',
|
||||
'CNS2-H',
|
||||
'CNS2-V',
|
||||
'ETHK-B5-H',
|
||||
'ETHK-B5-V',
|
||||
'ETen-B5-H',
|
||||
'ETen-B5-V',
|
||||
'ETenms-B5-H',
|
||||
'ETenms-B5-V',
|
||||
'EUC-H',
|
||||
'EUC-V',
|
||||
'Ext-H',
|
||||
'Ext-RKSJ-H',
|
||||
'Ext-RKSJ-V',
|
||||
'Ext-V',
|
||||
'GB-EUC-H',
|
||||
'GB-EUC-V',
|
||||
'GB-H',
|
||||
'GB-V',
|
||||
'GBK-EUC-H',
|
||||
'GBK-EUC-V',
|
||||
'GBK2K-H',
|
||||
'GBK2K-V',
|
||||
'GBKp-EUC-H',
|
||||
'GBKp-EUC-V',
|
||||
'GBT-EUC-H',
|
||||
'GBT-EUC-V',
|
||||
'GBT-H',
|
||||
'GBT-V',
|
||||
'GBTpc-EUC-H',
|
||||
'GBTpc-EUC-V',
|
||||
'GBpc-EUC-H',
|
||||
'GBpc-EUC-V',
|
||||
'H',
|
||||
'HKdla-B5-H',
|
||||
'HKdla-B5-V',
|
||||
'HKdlb-B5-H',
|
||||
'HKdlb-B5-V',
|
||||
'HKgccs-B5-H',
|
||||
'HKgccs-B5-V',
|
||||
'HKm314-B5-H',
|
||||
'HKm314-B5-V',
|
||||
'HKm471-B5-H',
|
||||
'HKm471-B5-V',
|
||||
'HKscs-B5-H',
|
||||
'HKscs-B5-V',
|
||||
'Hankaku',
|
||||
'Hiragana',
|
||||
'KSC-EUC-H',
|
||||
'KSC-EUC-V',
|
||||
'KSC-H',
|
||||
'KSC-Johab-H',
|
||||
'KSC-Johab-V',
|
||||
'KSC-V',
|
||||
'KSCms-UHC-H',
|
||||
'KSCms-UHC-HW-H',
|
||||
'KSCms-UHC-HW-V',
|
||||
'KSCms-UHC-V',
|
||||
'KSCpc-EUC-H',
|
||||
'KSCpc-EUC-V',
|
||||
'Katakana',
|
||||
'NWP-H',
|
||||
'NWP-V',
|
||||
'RKSJ-H',
|
||||
'RKSJ-V',
|
||||
'Roman',
|
||||
'UniCNS-UCS2-H',
|
||||
'UniCNS-UCS2-V',
|
||||
'UniCNS-UTF16-H',
|
||||
'UniCNS-UTF16-V',
|
||||
'UniCNS-UTF32-H',
|
||||
'UniCNS-UTF32-V',
|
||||
'UniCNS-UTF8-H',
|
||||
'UniCNS-UTF8-V',
|
||||
'UniGB-UCS2-H',
|
||||
'UniGB-UCS2-V',
|
||||
'UniGB-UTF16-H',
|
||||
'UniGB-UTF16-V',
|
||||
'UniGB-UTF32-H',
|
||||
'UniGB-UTF32-V',
|
||||
'UniGB-UTF8-H',
|
||||
'UniGB-UTF8-V',
|
||||
'UniJIS-UCS2-H',
|
||||
'UniJIS-UCS2-HW-H',
|
||||
'UniJIS-UCS2-HW-V',
|
||||
'UniJIS-UCS2-V',
|
||||
'UniJIS-UTF16-H',
|
||||
'UniJIS-UTF16-V',
|
||||
'UniJIS-UTF32-H',
|
||||
'UniJIS-UTF32-V',
|
||||
'UniJIS-UTF8-H',
|
||||
'UniJIS-UTF8-V',
|
||||
'UniJIS2004-UTF16-H',
|
||||
'UniJIS2004-UTF16-V',
|
||||
'UniJIS2004-UTF32-H',
|
||||
'UniJIS2004-UTF32-V',
|
||||
'UniJIS2004-UTF8-H',
|
||||
'UniJIS2004-UTF8-V',
|
||||
'UniJISPro-UCS2-HW-V',
|
||||
'UniJISPro-UCS2-V',
|
||||
'UniJISPro-UTF8-V',
|
||||
'UniJISX0213-UTF32-H',
|
||||
'UniJISX0213-UTF32-V',
|
||||
'UniJISX02132004-UTF32-H',
|
||||
'UniJISX02132004-UTF32-V',
|
||||
'UniKS-UCS2-H',
|
||||
'UniKS-UCS2-V',
|
||||
'UniKS-UTF16-H',
|
||||
'UniKS-UTF16-V',
|
||||
'UniKS-UTF32-H',
|
||||
'UniKS-UTF32-V',
|
||||
'UniKS-UTF8-H',
|
||||
'UniKS-UTF8-V',
|
||||
'V',
|
||||
'WP-Symbol'];
|
||||
// << Start unicode maps.
|
||||
"Adobe-GB1-UCS2",
|
||||
"Adobe-CNS1-UCS2",
|
||||
"Adobe-Japan1-UCS2",
|
||||
"Adobe-Korea1-UCS2",
|
||||
// >> End unicode maps.
|
||||
"78-EUC-H",
|
||||
"78-EUC-V",
|
||||
"78-H",
|
||||
"78-RKSJ-H",
|
||||
"78-RKSJ-V",
|
||||
"78-V",
|
||||
"78ms-RKSJ-H",
|
||||
"78ms-RKSJ-V",
|
||||
"83pv-RKSJ-H",
|
||||
"90ms-RKSJ-H",
|
||||
"90ms-RKSJ-V",
|
||||
"90msp-RKSJ-H",
|
||||
"90msp-RKSJ-V",
|
||||
"90pv-RKSJ-H",
|
||||
"90pv-RKSJ-V",
|
||||
"Add-H",
|
||||
"Add-RKSJ-H",
|
||||
"Add-RKSJ-V",
|
||||
"Add-V",
|
||||
"Adobe-CNS1-0",
|
||||
"Adobe-CNS1-1",
|
||||
"Adobe-CNS1-2",
|
||||
"Adobe-CNS1-3",
|
||||
"Adobe-CNS1-4",
|
||||
"Adobe-CNS1-5",
|
||||
"Adobe-CNS1-6",
|
||||
"Adobe-GB1-0",
|
||||
"Adobe-GB1-1",
|
||||
"Adobe-GB1-2",
|
||||
"Adobe-GB1-3",
|
||||
"Adobe-GB1-4",
|
||||
"Adobe-GB1-5",
|
||||
"Adobe-Japan1-0",
|
||||
"Adobe-Japan1-1",
|
||||
"Adobe-Japan1-2",
|
||||
"Adobe-Japan1-3",
|
||||
"Adobe-Japan1-4",
|
||||
"Adobe-Japan1-5",
|
||||
"Adobe-Japan1-6",
|
||||
"Adobe-Korea1-0",
|
||||
"Adobe-Korea1-1",
|
||||
"Adobe-Korea1-2",
|
||||
"B5-H",
|
||||
"B5-V",
|
||||
"B5pc-H",
|
||||
"B5pc-V",
|
||||
"CNS-EUC-H",
|
||||
"CNS-EUC-V",
|
||||
"CNS1-H",
|
||||
"CNS1-V",
|
||||
"CNS2-H",
|
||||
"CNS2-V",
|
||||
"ETHK-B5-H",
|
||||
"ETHK-B5-V",
|
||||
"ETen-B5-H",
|
||||
"ETen-B5-V",
|
||||
"ETenms-B5-H",
|
||||
"ETenms-B5-V",
|
||||
"EUC-H",
|
||||
"EUC-V",
|
||||
"Ext-H",
|
||||
"Ext-RKSJ-H",
|
||||
"Ext-RKSJ-V",
|
||||
"Ext-V",
|
||||
"GB-EUC-H",
|
||||
"GB-EUC-V",
|
||||
"GB-H",
|
||||
"GB-V",
|
||||
"GBK-EUC-H",
|
||||
"GBK-EUC-V",
|
||||
"GBK2K-H",
|
||||
"GBK2K-V",
|
||||
"GBKp-EUC-H",
|
||||
"GBKp-EUC-V",
|
||||
"GBT-EUC-H",
|
||||
"GBT-EUC-V",
|
||||
"GBT-H",
|
||||
"GBT-V",
|
||||
"GBTpc-EUC-H",
|
||||
"GBTpc-EUC-V",
|
||||
"GBpc-EUC-H",
|
||||
"GBpc-EUC-V",
|
||||
"H",
|
||||
"HKdla-B5-H",
|
||||
"HKdla-B5-V",
|
||||
"HKdlb-B5-H",
|
||||
"HKdlb-B5-V",
|
||||
"HKgccs-B5-H",
|
||||
"HKgccs-B5-V",
|
||||
"HKm314-B5-H",
|
||||
"HKm314-B5-V",
|
||||
"HKm471-B5-H",
|
||||
"HKm471-B5-V",
|
||||
"HKscs-B5-H",
|
||||
"HKscs-B5-V",
|
||||
"Hankaku",
|
||||
"Hiragana",
|
||||
"KSC-EUC-H",
|
||||
"KSC-EUC-V",
|
||||
"KSC-H",
|
||||
"KSC-Johab-H",
|
||||
"KSC-Johab-V",
|
||||
"KSC-V",
|
||||
"KSCms-UHC-H",
|
||||
"KSCms-UHC-HW-H",
|
||||
"KSCms-UHC-HW-V",
|
||||
"KSCms-UHC-V",
|
||||
"KSCpc-EUC-H",
|
||||
"KSCpc-EUC-V",
|
||||
"Katakana",
|
||||
"NWP-H",
|
||||
"NWP-V",
|
||||
"RKSJ-H",
|
||||
"RKSJ-V",
|
||||
"Roman",
|
||||
"UniCNS-UCS2-H",
|
||||
"UniCNS-UCS2-V",
|
||||
"UniCNS-UTF16-H",
|
||||
"UniCNS-UTF16-V",
|
||||
"UniCNS-UTF32-H",
|
||||
"UniCNS-UTF32-V",
|
||||
"UniCNS-UTF8-H",
|
||||
"UniCNS-UTF8-V",
|
||||
"UniGB-UCS2-H",
|
||||
"UniGB-UCS2-V",
|
||||
"UniGB-UTF16-H",
|
||||
"UniGB-UTF16-V",
|
||||
"UniGB-UTF32-H",
|
||||
"UniGB-UTF32-V",
|
||||
"UniGB-UTF8-H",
|
||||
"UniGB-UTF8-V",
|
||||
"UniJIS-UCS2-H",
|
||||
"UniJIS-UCS2-HW-H",
|
||||
"UniJIS-UCS2-HW-V",
|
||||
"UniJIS-UCS2-V",
|
||||
"UniJIS-UTF16-H",
|
||||
"UniJIS-UTF16-V",
|
||||
"UniJIS-UTF32-H",
|
||||
"UniJIS-UTF32-V",
|
||||
"UniJIS-UTF8-H",
|
||||
"UniJIS-UTF8-V",
|
||||
"UniJIS2004-UTF16-H",
|
||||
"UniJIS2004-UTF16-V",
|
||||
"UniJIS2004-UTF32-H",
|
||||
"UniJIS2004-UTF32-V",
|
||||
"UniJIS2004-UTF8-H",
|
||||
"UniJIS2004-UTF8-V",
|
||||
"UniJISPro-UCS2-HW-V",
|
||||
"UniJISPro-UCS2-V",
|
||||
"UniJISPro-UTF8-V",
|
||||
"UniJISX0213-UTF32-H",
|
||||
"UniJISX0213-UTF32-V",
|
||||
"UniJISX02132004-UTF32-H",
|
||||
"UniJISX02132004-UTF32-V",
|
||||
"UniKS-UCS2-H",
|
||||
"UniKS-UCS2-V",
|
||||
"UniKS-UTF16-H",
|
||||
"UniKS-UTF16-V",
|
||||
"UniKS-UTF32-H",
|
||||
"UniKS-UTF32-V",
|
||||
"UniKS-UTF8-H",
|
||||
"UniKS-UTF8-V",
|
||||
"V",
|
||||
"WP-Symbol",
|
||||
];
|
||||
|
||||
// CMap, not to be confused with TrueType's cmap.
|
||||
class CMap {
|
||||
|
@ -206,7 +211,7 @@ class CMap {
|
|||
// - bf chars are variable-length byte sequences, stored as strings, with
|
||||
// one byte per character.
|
||||
this._map = [];
|
||||
this.name = '';
|
||||
this.name = "";
|
||||
this.vertical = false;
|
||||
this.useCMap = null;
|
||||
this.builtInCMap = builtInCMap;
|
||||
|
@ -228,13 +233,15 @@ class CMap {
|
|||
while (low <= high) {
|
||||
this._map[low++] = dstLow;
|
||||
// Only the last byte has to be incremented.
|
||||
dstLow = dstLow.substring(0, lastByte) +
|
||||
String.fromCharCode(dstLow.charCodeAt(lastByte) + 1);
|
||||
dstLow =
|
||||
dstLow.substring(0, lastByte) +
|
||||
String.fromCharCode(dstLow.charCodeAt(lastByte) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
mapBfRangeToArray(low, high, array) {
|
||||
let i = 0, ii = array.length;
|
||||
let i = 0,
|
||||
ii = array.length;
|
||||
while (low <= high && i < ii) {
|
||||
this._map[low] = array[i++];
|
||||
++low;
|
||||
|
@ -284,7 +291,7 @@ class CMap {
|
|||
}
|
||||
for (let charCode in map) {
|
||||
if (map[charCode] === value) {
|
||||
return (charCode | 0);
|
||||
return charCode | 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
@ -303,7 +310,7 @@ class CMap {
|
|||
c = ((c << 8) | str.charCodeAt(offset + n)) >>> 0;
|
||||
// Check each codespace range to see if it falls within.
|
||||
const codespaceRange = codespaceRanges[n];
|
||||
for (let k = 0, kk = codespaceRange.length; k < kk;) {
|
||||
for (let k = 0, kk = codespaceRange.length; k < kk; ) {
|
||||
const low = codespaceRange[k++];
|
||||
const high = codespaceRange[k++];
|
||||
if (c >= low && c <= high) {
|
||||
|
@ -322,7 +329,7 @@ class CMap {
|
|||
}
|
||||
|
||||
get isIdentityCMap() {
|
||||
if (!(this.name === 'Identity-H' || this.name === 'Identity-V')) {
|
||||
if (!(this.name === "Identity-H" || this.name === "Identity-V")) {
|
||||
return false;
|
||||
}
|
||||
if (this._map.length !== 0x10000) {
|
||||
|
@ -348,23 +355,23 @@ class IdentityCMap extends CMap {
|
|||
}
|
||||
|
||||
mapCidRange(low, high, dstLow) {
|
||||
unreachable('should not call mapCidRange');
|
||||
unreachable("should not call mapCidRange");
|
||||
}
|
||||
|
||||
mapBfRange(low, high, dstLow) {
|
||||
unreachable('should not call mapBfRange');
|
||||
unreachable("should not call mapBfRange");
|
||||
}
|
||||
|
||||
mapBfRangeToArray(low, high, array) {
|
||||
unreachable('should not call mapBfRangeToArray');
|
||||
unreachable("should not call mapBfRangeToArray");
|
||||
}
|
||||
|
||||
mapOne(src, dst) {
|
||||
unreachable('should not call mapCidOne');
|
||||
unreachable("should not call mapCidOne");
|
||||
}
|
||||
|
||||
lookup(code) {
|
||||
return (Number.isInteger(code) && code <= 0xffff) ? code : undefined;
|
||||
return Number.isInteger(code) && code <= 0xffff ? code : undefined;
|
||||
}
|
||||
|
||||
contains(code) {
|
||||
|
@ -378,7 +385,7 @@ class IdentityCMap extends CMap {
|
|||
}
|
||||
|
||||
charCodeOf(value) {
|
||||
return (Number.isInteger(value) && value <= 0xffff) ? value : -1;
|
||||
return Number.isInteger(value) && value <= 0xffff ? value : -1;
|
||||
}
|
||||
|
||||
getMap() {
|
||||
|
@ -394,8 +401,9 @@ class IdentityCMap extends CMap {
|
|||
return 0x10000;
|
||||
}
|
||||
|
||||
get isIdentityCMap() { // eslint-disable-line getter-return
|
||||
unreachable('should not access .isIdentityCMap');
|
||||
get isIdentityCMap() {
|
||||
// eslint-disable-line getter-return
|
||||
unreachable("should not access .isIdentityCMap");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,34 +469,36 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() {
|
|||
do {
|
||||
var b = this.readByte();
|
||||
if (b < 0) {
|
||||
throw new FormatError('unexpected EOF in bcmap');
|
||||
throw new FormatError("unexpected EOF in bcmap");
|
||||
}
|
||||
last = !(b & 0x80);
|
||||
n = (n << 7) | (b & 0x7F);
|
||||
n = (n << 7) | (b & 0x7f);
|
||||
} while (!last);
|
||||
return n;
|
||||
},
|
||||
readSigned() {
|
||||
var n = this.readNumber();
|
||||
return (n & 1) ? ~(n >>> 1) : n >>> 1;
|
||||
return n & 1 ? ~(n >>> 1) : n >>> 1;
|
||||
},
|
||||
readHex(num, size) {
|
||||
num.set(this.buffer.subarray(this.pos,
|
||||
this.pos + size + 1));
|
||||
num.set(this.buffer.subarray(this.pos, this.pos + size + 1));
|
||||
this.pos += size + 1;
|
||||
},
|
||||
readHexNumber(num, size) {
|
||||
var last;
|
||||
var stack = this.tmpBuf, sp = 0;
|
||||
var stack = this.tmpBuf,
|
||||
sp = 0;
|
||||
do {
|
||||
var b = this.readByte();
|
||||
if (b < 0) {
|
||||
throw new FormatError('unexpected EOF in bcmap');
|
||||
throw new FormatError("unexpected EOF in bcmap");
|
||||
}
|
||||
last = !(b & 0x80);
|
||||
stack[sp++] = b & 0x7F;
|
||||
stack[sp++] = b & 0x7f;
|
||||
} while (!last);
|
||||
var i = size, buffer = 0, bufferSize = 0;
|
||||
var i = size,
|
||||
buffer = 0,
|
||||
bufferSize = 0;
|
||||
while (i >= 0) {
|
||||
while (bufferSize < 8 && stack.length > 0) {
|
||||
buffer = (stack[--sp] << bufferSize) | buffer;
|
||||
|
@ -511,7 +521,7 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() {
|
|||
},
|
||||
readString() {
|
||||
var len = this.readNumber();
|
||||
var s = '';
|
||||
var s = "";
|
||||
for (var i = 0; i < len; i++) {
|
||||
s += String.fromCharCode(this.readNumber());
|
||||
}
|
||||
|
@ -520,7 +530,7 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() {
|
|||
};
|
||||
|
||||
function processBinaryCMap(data, cMap, extend) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var stream = new BinaryCMapStream(data);
|
||||
var header = stream.readByte();
|
||||
cMap.vertical = !!(header & 1);
|
||||
|
@ -536,8 +546,9 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() {
|
|||
var b;
|
||||
while ((b = stream.readByte()) >= 0) {
|
||||
var type = b >> 5;
|
||||
if (type === 7) { // metadata, e.g. comment or usecmap
|
||||
switch (b & 0x1F) {
|
||||
if (type === 7) {
|
||||
// metadata, e.g. comment or usecmap
|
||||
switch (b & 0x1f) {
|
||||
case 0:
|
||||
stream.readString(); // skipping comment
|
||||
break;
|
||||
|
@ -551,7 +562,7 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() {
|
|||
var dataSize = b & 15;
|
||||
|
||||
if (dataSize + 1 > MAX_NUM_SIZE) {
|
||||
throw new Error('processBinaryCMap: Invalid dataSize.');
|
||||
throw new Error("processBinaryCMap: Invalid dataSize.");
|
||||
}
|
||||
|
||||
var ucs2DataSize = 1;
|
||||
|
@ -562,16 +573,22 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() {
|
|||
stream.readHex(start, dataSize);
|
||||
stream.readHexNumber(end, dataSize);
|
||||
addHex(end, start, dataSize);
|
||||
cMap.addCodespaceRange(dataSize + 1, hexToInt(start, dataSize),
|
||||
hexToInt(end, dataSize));
|
||||
cMap.addCodespaceRange(
|
||||
dataSize + 1,
|
||||
hexToInt(start, dataSize),
|
||||
hexToInt(end, dataSize)
|
||||
);
|
||||
for (i = 1; i < subitemsCount; i++) {
|
||||
incHex(end, dataSize);
|
||||
stream.readHexNumber(start, dataSize);
|
||||
addHex(start, end, dataSize);
|
||||
stream.readHexNumber(end, dataSize);
|
||||
addHex(end, start, dataSize);
|
||||
cMap.addCodespaceRange(dataSize + 1, hexToInt(start, dataSize),
|
||||
hexToInt(end, dataSize));
|
||||
cMap.addCodespaceRange(
|
||||
dataSize + 1,
|
||||
hexToInt(start, dataSize),
|
||||
hexToInt(end, dataSize)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 1: // notdefrange
|
||||
|
@ -609,8 +626,11 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() {
|
|||
stream.readHexNumber(end, dataSize);
|
||||
addHex(end, start, dataSize);
|
||||
code = stream.readNumber();
|
||||
cMap.mapCidRange(hexToInt(start, dataSize), hexToInt(end, dataSize),
|
||||
code);
|
||||
cMap.mapCidRange(
|
||||
hexToInt(start, dataSize),
|
||||
hexToInt(end, dataSize),
|
||||
code
|
||||
);
|
||||
for (i = 1; i < subitemsCount; i++) {
|
||||
incHex(end, dataSize);
|
||||
if (!sequence) {
|
||||
|
@ -622,15 +642,20 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() {
|
|||
stream.readHexNumber(end, dataSize);
|
||||
addHex(end, start, dataSize);
|
||||
code = stream.readNumber();
|
||||
cMap.mapCidRange(hexToInt(start, dataSize),
|
||||
hexToInt(end, dataSize), code);
|
||||
cMap.mapCidRange(
|
||||
hexToInt(start, dataSize),
|
||||
hexToInt(end, dataSize),
|
||||
code
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 4: // bfchar
|
||||
stream.readHex(char, ucs2DataSize);
|
||||
stream.readHex(charCode, dataSize);
|
||||
cMap.mapOne(hexToInt(char, ucs2DataSize),
|
||||
hexToStr(charCode, dataSize));
|
||||
cMap.mapOne(
|
||||
hexToInt(char, ucs2DataSize),
|
||||
hexToStr(charCode, dataSize)
|
||||
);
|
||||
for (i = 1; i < subitemsCount; i++) {
|
||||
incHex(char, ucs2DataSize);
|
||||
if (!sequence) {
|
||||
|
@ -640,8 +665,10 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() {
|
|||
incHex(charCode, dataSize);
|
||||
stream.readHexSigned(tmp, dataSize);
|
||||
addHex(charCode, tmp, dataSize);
|
||||
cMap.mapOne(hexToInt(char, ucs2DataSize),
|
||||
hexToStr(charCode, dataSize));
|
||||
cMap.mapOne(
|
||||
hexToInt(char, ucs2DataSize),
|
||||
hexToStr(charCode, dataSize)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 5: // bfrange
|
||||
|
@ -649,9 +676,11 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() {
|
|||
stream.readHexNumber(end, ucs2DataSize);
|
||||
addHex(end, start, ucs2DataSize);
|
||||
stream.readHex(charCode, dataSize);
|
||||
cMap.mapBfRange(hexToInt(start, ucs2DataSize),
|
||||
hexToInt(end, ucs2DataSize),
|
||||
hexToStr(charCode, dataSize));
|
||||
cMap.mapBfRange(
|
||||
hexToInt(start, ucs2DataSize),
|
||||
hexToInt(end, ucs2DataSize),
|
||||
hexToStr(charCode, dataSize)
|
||||
);
|
||||
for (i = 1; i < subitemsCount; i++) {
|
||||
incHex(end, ucs2DataSize);
|
||||
if (!sequence) {
|
||||
|
@ -663,13 +692,15 @@ var BinaryCMapReader = (function BinaryCMapReaderClosure() {
|
|||
stream.readHexNumber(end, ucs2DataSize);
|
||||
addHex(end, start, ucs2DataSize);
|
||||
stream.readHex(charCode, dataSize);
|
||||
cMap.mapBfRange(hexToInt(start, ucs2DataSize),
|
||||
hexToInt(end, ucs2DataSize),
|
||||
hexToStr(charCode, dataSize));
|
||||
cMap.mapBfRange(
|
||||
hexToInt(start, ucs2DataSize),
|
||||
hexToInt(end, ucs2DataSize),
|
||||
hexToStr(charCode, dataSize)
|
||||
);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
reject(new Error('processBinaryCMap: Unknown type: ' + type));
|
||||
reject(new Error("processBinaryCMap: Unknown type: " + type));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -702,13 +733,13 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
|
||||
function expectString(obj) {
|
||||
if (!isString(obj)) {
|
||||
throw new FormatError('Malformed CMap: expected string.');
|
||||
throw new FormatError("Malformed CMap: expected string.");
|
||||
}
|
||||
}
|
||||
|
||||
function expectInt(obj) {
|
||||
if (!Number.isInteger(obj)) {
|
||||
throw new FormatError('Malformed CMap: expected int.');
|
||||
throw new FormatError("Malformed CMap: expected int.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -718,7 +749,7 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
if (isEOF(obj)) {
|
||||
break;
|
||||
}
|
||||
if (isCmd(obj, 'endbfchar')) {
|
||||
if (isCmd(obj, "endbfchar")) {
|
||||
return;
|
||||
}
|
||||
expectString(obj);
|
||||
|
@ -737,7 +768,7 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
if (isEOF(obj)) {
|
||||
break;
|
||||
}
|
||||
if (isCmd(obj, 'endbfrange')) {
|
||||
if (isCmd(obj, "endbfrange")) {
|
||||
return;
|
||||
}
|
||||
expectString(obj);
|
||||
|
@ -749,10 +780,10 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
if (Number.isInteger(obj) || isString(obj)) {
|
||||
var dstLow = Number.isInteger(obj) ? String.fromCharCode(obj) : obj;
|
||||
cMap.mapBfRange(low, high, dstLow);
|
||||
} else if (isCmd(obj, '[')) {
|
||||
} else if (isCmd(obj, "[")) {
|
||||
obj = lexer.getObj();
|
||||
var array = [];
|
||||
while (!isCmd(obj, ']') && !isEOF(obj)) {
|
||||
while (!isCmd(obj, "]") && !isEOF(obj)) {
|
||||
array.push(obj);
|
||||
obj = lexer.getObj();
|
||||
}
|
||||
|
@ -761,7 +792,7 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
throw new FormatError('Invalid bf range.');
|
||||
throw new FormatError("Invalid bf range.");
|
||||
}
|
||||
|
||||
function parseCidChar(cMap, lexer) {
|
||||
|
@ -770,7 +801,7 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
if (isEOF(obj)) {
|
||||
break;
|
||||
}
|
||||
if (isCmd(obj, 'endcidchar')) {
|
||||
if (isCmd(obj, "endcidchar")) {
|
||||
return;
|
||||
}
|
||||
expectString(obj);
|
||||
|
@ -788,7 +819,7 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
if (isEOF(obj)) {
|
||||
break;
|
||||
}
|
||||
if (isCmd(obj, 'endcidrange')) {
|
||||
if (isCmd(obj, "endcidrange")) {
|
||||
return;
|
||||
}
|
||||
expectString(obj);
|
||||
|
@ -809,7 +840,7 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
if (isEOF(obj)) {
|
||||
break;
|
||||
}
|
||||
if (isCmd(obj, 'endcodespacerange')) {
|
||||
if (isCmd(obj, "endcodespacerange")) {
|
||||
return;
|
||||
}
|
||||
if (!isString(obj)) {
|
||||
|
@ -823,7 +854,7 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
var high = strToInt(obj);
|
||||
cMap.addCodespaceRange(obj.length, low, high);
|
||||
}
|
||||
throw new FormatError('Invalid codespace range.');
|
||||
throw new FormatError("Invalid codespace range.");
|
||||
}
|
||||
|
||||
function parseWMode(cMap, lexer) {
|
||||
|
@ -849,34 +880,34 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
if (isEOF(obj)) {
|
||||
break;
|
||||
} else if (isName(obj)) {
|
||||
if (obj.name === 'WMode') {
|
||||
if (obj.name === "WMode") {
|
||||
parseWMode(cMap, lexer);
|
||||
} else if (obj.name === 'CMapName') {
|
||||
} else if (obj.name === "CMapName") {
|
||||
parseCMapName(cMap, lexer);
|
||||
}
|
||||
previous = obj;
|
||||
} else if (isCmd(obj)) {
|
||||
switch (obj.cmd) {
|
||||
case 'endcmap':
|
||||
case "endcmap":
|
||||
break objLoop;
|
||||
case 'usecmap':
|
||||
case "usecmap":
|
||||
if (isName(previous)) {
|
||||
embeddedUseCMap = previous.name;
|
||||
}
|
||||
break;
|
||||
case 'begincodespacerange':
|
||||
case "begincodespacerange":
|
||||
parseCodespaceRange(cMap, lexer);
|
||||
break;
|
||||
case 'beginbfchar':
|
||||
case "beginbfchar":
|
||||
parseBfChar(cMap, lexer);
|
||||
break;
|
||||
case 'begincidchar':
|
||||
case "begincidchar":
|
||||
parseCidChar(cMap, lexer);
|
||||
break;
|
||||
case 'beginbfrange':
|
||||
case "beginbfrange":
|
||||
parseBfRange(cMap, lexer);
|
||||
break;
|
||||
case 'begincidrange':
|
||||
case "begincidrange":
|
||||
parseCidRange(cMap, lexer);
|
||||
break;
|
||||
}
|
||||
|
@ -885,7 +916,7 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
if (ex instanceof MissingDataException) {
|
||||
throw ex;
|
||||
}
|
||||
warn('Invalid cMap data: ' + ex);
|
||||
warn("Invalid cMap data: " + ex);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -926,26 +957,29 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
}
|
||||
|
||||
function createBuiltInCMap(name, fetchBuiltInCMap) {
|
||||
if (name === 'Identity-H') {
|
||||
if (name === "Identity-H") {
|
||||
return Promise.resolve(new IdentityCMap(false, 2));
|
||||
} else if (name === 'Identity-V') {
|
||||
} else if (name === "Identity-V") {
|
||||
return Promise.resolve(new IdentityCMap(true, 2));
|
||||
}
|
||||
if (!BUILT_IN_CMAPS.includes(name)) {
|
||||
return Promise.reject(new Error('Unknown CMap name: ' + name));
|
||||
return Promise.reject(new Error("Unknown CMap name: " + name));
|
||||
}
|
||||
if (!fetchBuiltInCMap) {
|
||||
return Promise.reject(new Error(
|
||||
'Built-in CMap parameters are not provided.'));
|
||||
return Promise.reject(
|
||||
new Error("Built-in CMap parameters are not provided.")
|
||||
);
|
||||
}
|
||||
|
||||
return fetchBuiltInCMap(name).then(function (data) {
|
||||
var cMapData = data.cMapData, compressionType = data.compressionType;
|
||||
return fetchBuiltInCMap(name).then(function(data) {
|
||||
var cMapData = data.cMapData,
|
||||
compressionType = data.compressionType;
|
||||
var cMap = new CMap(true);
|
||||
|
||||
if (compressionType === CMapCompressionType.BINARY) {
|
||||
return new BinaryCMapReader().process(cMapData, cMap,
|
||||
function (useCMap) {
|
||||
return new BinaryCMapReader().process(cMapData, cMap, function(
|
||||
useCMap
|
||||
) {
|
||||
return extendCMap(cMap, fetchBuiltInCMap, useCMap);
|
||||
});
|
||||
}
|
||||
|
@ -953,8 +987,11 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
var lexer = new Lexer(new Stream(cMapData));
|
||||
return parseCMap(cMap, lexer, fetchBuiltInCMap, null);
|
||||
}
|
||||
return Promise.reject(new Error(
|
||||
'TODO: Only BINARY/NONE CMap compression is currently supported.'));
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
"TODO: Only BINARY/NONE CMap compression is currently supported."
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -969,21 +1006,18 @@ var CMapFactory = (function CMapFactoryClosure() {
|
|||
} else if (isStream(encoding)) {
|
||||
var cMap = new CMap();
|
||||
var lexer = new Lexer(encoding);
|
||||
return parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap).then(
|
||||
function (parsedCMap) {
|
||||
return parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap).then(function(
|
||||
parsedCMap
|
||||
) {
|
||||
if (parsedCMap.isIdentityCMap) {
|
||||
return createBuiltInCMap(parsedCMap.name, fetchBuiltInCMap);
|
||||
}
|
||||
return parsedCMap;
|
||||
});
|
||||
}
|
||||
return Promise.reject(new Error('Encoding required.'));
|
||||
return Promise.reject(new Error("Encoding required."));
|
||||
},
|
||||
};
|
||||
})();
|
||||
|
||||
export {
|
||||
CMap,
|
||||
IdentityCMap,
|
||||
CMapFactory,
|
||||
};
|
||||
export { CMap, IdentityCMap, CMapFactory };
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
/* eslint no-var: error */
|
||||
|
||||
import { assert, BaseException, warn } from '../shared/util';
|
||||
import { assert, BaseException, warn } from "../shared/util";
|
||||
|
||||
function getLookupTableFactory(initializer) {
|
||||
let lookup;
|
||||
|
@ -36,9 +36,9 @@ class MissingDataException extends BaseException {
|
|||
}
|
||||
}
|
||||
|
||||
class XRefEntryException extends BaseException { }
|
||||
class XRefEntryException extends BaseException {}
|
||||
|
||||
class XRefParseException extends BaseException { }
|
||||
class XRefParseException extends BaseException {}
|
||||
|
||||
/**
|
||||
* Get the value of an inheritable property.
|
||||
|
@ -61,8 +61,12 @@ class XRefParseException extends BaseException { }
|
|||
* chain, for example to be able to find `\Resources` placed on multiple
|
||||
* levels of the tree. The default value is `true`.
|
||||
*/
|
||||
function getInheritableProperty({ dict, key, getArray = false,
|
||||
stopWhenFound = true, }) {
|
||||
function getInheritableProperty({
|
||||
dict,
|
||||
key,
|
||||
getArray = false,
|
||||
stopWhenFound = true,
|
||||
}) {
|
||||
const LOOP_LIMIT = 100;
|
||||
let loopCount = 0;
|
||||
let values;
|
||||
|
@ -82,16 +86,16 @@ function getInheritableProperty({ dict, key, getArray = false,
|
|||
warn(`getInheritableProperty: maximum loop count exceeded for "${key}"`);
|
||||
break;
|
||||
}
|
||||
dict = dict.get('Parent');
|
||||
dict = dict.get("Parent");
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
const ROMAN_NUMBER_MAP = [
|
||||
'', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM',
|
||||
'', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC',
|
||||
'', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'
|
||||
"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM",
|
||||
"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC",
|
||||
"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -102,13 +106,16 @@ const ROMAN_NUMBER_MAP = [
|
|||
* @returns {string} The resulting Roman number.
|
||||
*/
|
||||
function toRomanNumerals(number, lowerCase = false) {
|
||||
assert(Number.isInteger(number) && number > 0,
|
||||
'The number should be a positive integer.');
|
||||
let pos, romanBuf = [];
|
||||
assert(
|
||||
Number.isInteger(number) && number > 0,
|
||||
"The number should be a positive integer."
|
||||
);
|
||||
let pos,
|
||||
romanBuf = [];
|
||||
// Thousands
|
||||
while (number >= 1000) {
|
||||
number -= 1000;
|
||||
romanBuf.push('M');
|
||||
romanBuf.push("M");
|
||||
}
|
||||
// Hundreds
|
||||
pos = (number / 100) | 0;
|
||||
|
@ -121,8 +128,8 @@ function toRomanNumerals(number, lowerCase = false) {
|
|||
// Ones
|
||||
romanBuf.push(ROMAN_NUMBER_MAP[20 + number]);
|
||||
|
||||
const romanStr = romanBuf.join('');
|
||||
return (lowerCase ? romanStr.toLowerCase() : romanStr);
|
||||
const romanStr = romanBuf.join("");
|
||||
return lowerCase ? romanStr.toLowerCase() : romanStr;
|
||||
}
|
||||
|
||||
export {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,35 +15,60 @@
|
|||
/* eslint no-var: error */
|
||||
|
||||
import {
|
||||
assert, FormatError, info, InvalidPDFException, isArrayBuffer, isArrayEqual,
|
||||
isBool, isNum, isSpace, isString, OPS, shadow, stringToBytes,
|
||||
stringToPDFString, Util, warn
|
||||
} from '../shared/util';
|
||||
import { Catalog, ObjectLoader, XRef } from './obj';
|
||||
import { Dict, isDict, isName, isStream, Ref } from './primitives';
|
||||
assert,
|
||||
FormatError,
|
||||
info,
|
||||
InvalidPDFException,
|
||||
isArrayBuffer,
|
||||
isArrayEqual,
|
||||
isBool,
|
||||
isNum,
|
||||
isSpace,
|
||||
isString,
|
||||
OPS,
|
||||
shadow,
|
||||
stringToBytes,
|
||||
stringToPDFString,
|
||||
Util,
|
||||
warn,
|
||||
} from "../shared/util";
|
||||
import { Catalog, ObjectLoader, XRef } from "./obj";
|
||||
import { Dict, isDict, isName, isStream, Ref } from "./primitives";
|
||||
import {
|
||||
getInheritableProperty, MissingDataException, XRefEntryException,
|
||||
XRefParseException
|
||||
} from './core_utils';
|
||||
import { NullStream, Stream, StreamsSequenceStream } from './stream';
|
||||
import { AnnotationFactory } from './annotation';
|
||||
import { calculateMD5 } from './crypto';
|
||||
import { Linearization } from './parser';
|
||||
import { OperatorList } from './operator_list';
|
||||
import { PartialEvaluator } from './evaluator';
|
||||
import { PDFFunctionFactory } from './function';
|
||||
getInheritableProperty,
|
||||
MissingDataException,
|
||||
XRefEntryException,
|
||||
XRefParseException,
|
||||
} from "./core_utils";
|
||||
import { NullStream, Stream, StreamsSequenceStream } from "./stream";
|
||||
import { AnnotationFactory } from "./annotation";
|
||||
import { calculateMD5 } from "./crypto";
|
||||
import { Linearization } from "./parser";
|
||||
import { OperatorList } from "./operator_list";
|
||||
import { PartialEvaluator } from "./evaluator";
|
||||
import { PDFFunctionFactory } from "./function";
|
||||
|
||||
const DEFAULT_USER_UNIT = 1.0;
|
||||
const LETTER_SIZE_MEDIABOX = [0, 0, 612, 792];
|
||||
|
||||
function isAnnotationRenderable(annotation, intent) {
|
||||
return (intent === 'display' && annotation.viewable) ||
|
||||
(intent === 'print' && annotation.printable);
|
||||
return (
|
||||
(intent === "display" && annotation.viewable) ||
|
||||
(intent === "print" && annotation.printable)
|
||||
);
|
||||
}
|
||||
|
||||
class Page {
|
||||
constructor({ pdfManager, xref, pageIndex, pageDict, ref, fontCache,
|
||||
builtInCMapCache, pdfFunctionFactory, }) {
|
||||
constructor({
|
||||
pdfManager,
|
||||
xref,
|
||||
pageIndex,
|
||||
pageDict,
|
||||
ref,
|
||||
fontCache,
|
||||
builtInCMapCache,
|
||||
pdfFunctionFactory,
|
||||
}) {
|
||||
this.pdfManager = pdfManager;
|
||||
this.pageIndex = pageIndex;
|
||||
this.pageDict = pageDict;
|
||||
|
@ -72,8 +97,12 @@ class Page {
|
|||
* @private
|
||||
*/
|
||||
_getInheritableProperty(key, getArray = false) {
|
||||
const value = getInheritableProperty({ dict: this.pageDict, key, getArray,
|
||||
stopWhenFound: false, });
|
||||
const value = getInheritableProperty({
|
||||
dict: this.pageDict,
|
||||
key,
|
||||
getArray,
|
||||
stopWhenFound: false,
|
||||
});
|
||||
if (!Array.isArray(value)) {
|
||||
return value;
|
||||
}
|
||||
|
@ -84,22 +113,25 @@ class Page {
|
|||
}
|
||||
|
||||
get content() {
|
||||
return this.pageDict.get('Contents');
|
||||
return this.pageDict.get("Contents");
|
||||
}
|
||||
|
||||
get resources() {
|
||||
// For robustness: The spec states that a \Resources entry has to be
|
||||
// present, but can be empty. Some documents still omit it; in this case
|
||||
// we return an empty dictionary.
|
||||
return shadow(this, 'resources',
|
||||
this._getInheritableProperty('Resources') || Dict.empty);
|
||||
return shadow(
|
||||
this,
|
||||
"resources",
|
||||
this._getInheritableProperty("Resources") || Dict.empty
|
||||
);
|
||||
}
|
||||
|
||||
_getBoundingBox(name) {
|
||||
const box = this._getInheritableProperty(name, /* getArray = */ true);
|
||||
|
||||
if (Array.isArray(box) && box.length === 4) {
|
||||
if ((box[2] - box[0]) !== 0 && (box[3] - box[1]) !== 0) {
|
||||
if (box[2] - box[0] !== 0 && box[3] - box[1] !== 0) {
|
||||
return box;
|
||||
}
|
||||
warn(`Empty /${name} entry.`);
|
||||
|
@ -109,22 +141,28 @@ class Page {
|
|||
|
||||
get mediaBox() {
|
||||
// Reset invalid media box to letter size.
|
||||
return shadow(this, 'mediaBox',
|
||||
this._getBoundingBox('MediaBox') || LETTER_SIZE_MEDIABOX);
|
||||
return shadow(
|
||||
this,
|
||||
"mediaBox",
|
||||
this._getBoundingBox("MediaBox") || LETTER_SIZE_MEDIABOX
|
||||
);
|
||||
}
|
||||
|
||||
get cropBox() {
|
||||
// Reset invalid crop box to media box.
|
||||
return shadow(this, 'cropBox',
|
||||
this._getBoundingBox('CropBox') || this.mediaBox);
|
||||
return shadow(
|
||||
this,
|
||||
"cropBox",
|
||||
this._getBoundingBox("CropBox") || this.mediaBox
|
||||
);
|
||||
}
|
||||
|
||||
get userUnit() {
|
||||
let obj = this.pageDict.get('UserUnit');
|
||||
let obj = this.pageDict.get("UserUnit");
|
||||
if (!isNum(obj) || obj <= 0) {
|
||||
obj = DEFAULT_USER_UNIT;
|
||||
}
|
||||
return shadow(this, 'userUnit', obj);
|
||||
return shadow(this, "userUnit", obj);
|
||||
}
|
||||
|
||||
get view() {
|
||||
|
@ -132,23 +170,23 @@ class Page {
|
|||
// "The crop, bleed, trim, and art boxes should not ordinarily
|
||||
// extend beyond the boundaries of the media box. If they do, they are
|
||||
// effectively reduced to their intersection with the media box."
|
||||
const { cropBox, mediaBox, } = this;
|
||||
const { cropBox, mediaBox } = this;
|
||||
let view;
|
||||
if (cropBox === mediaBox || isArrayEqual(cropBox, mediaBox)) {
|
||||
view = mediaBox;
|
||||
} else {
|
||||
const box = Util.intersect(cropBox, mediaBox);
|
||||
if (box && ((box[2] - box[0]) !== 0 && (box[3] - box[1]) !== 0)) {
|
||||
if (box && box[2] - box[0] !== 0 && box[3] - box[1] !== 0) {
|
||||
view = box;
|
||||
} else {
|
||||
warn('Empty /CropBox and /MediaBox intersection.');
|
||||
warn("Empty /CropBox and /MediaBox intersection.");
|
||||
}
|
||||
}
|
||||
return shadow(this, 'view', view || mediaBox);
|
||||
return shadow(this, "view", view || mediaBox);
|
||||
}
|
||||
|
||||
get rotate() {
|
||||
let rotate = this._getInheritableProperty('Rotate') || 0;
|
||||
let rotate = this._getInheritableProperty("Rotate") || 0;
|
||||
|
||||
// Normalize rotation so it's a multiple of 90 and between 0 and 270.
|
||||
if (rotate % 90 !== 0) {
|
||||
|
@ -160,7 +198,7 @@ class Page {
|
|||
// rotation. The following is the other implementation of modulo.
|
||||
rotate = ((rotate % 360) + 360) % 360;
|
||||
}
|
||||
return shadow(this, 'rotate', rotate);
|
||||
return shadow(this, "rotate", rotate);
|
||||
}
|
||||
|
||||
getContentStream() {
|
||||
|
@ -187,7 +225,7 @@ class Page {
|
|||
loadResources(keys) {
|
||||
if (!this.resourcesPromise) {
|
||||
// TODO: add async `_getInheritableProperty` and remove this.
|
||||
this.resourcesPromise = this.pdfManager.ensure(this, 'resources');
|
||||
this.resourcesPromise = this.pdfManager.ensure(this, "resources");
|
||||
}
|
||||
return this.resourcesPromise.then(() => {
|
||||
const objectLoader = new ObjectLoader(this.resources, keys, this.xref);
|
||||
|
@ -195,16 +233,18 @@ class Page {
|
|||
});
|
||||
}
|
||||
|
||||
getOperatorList({ handler, sink, task, intent, renderInteractiveForms, }) {
|
||||
const contentStreamPromise = this.pdfManager.ensure(this,
|
||||
'getContentStream');
|
||||
getOperatorList({ handler, sink, task, intent, renderInteractiveForms }) {
|
||||
const contentStreamPromise = this.pdfManager.ensure(
|
||||
this,
|
||||
"getContentStream"
|
||||
);
|
||||
const resourcesPromise = this.loadResources([
|
||||
'ExtGState',
|
||||
'ColorSpace',
|
||||
'Pattern',
|
||||
'Shading',
|
||||
'XObject',
|
||||
'Font',
|
||||
"ExtGState",
|
||||
"ColorSpace",
|
||||
"Pattern",
|
||||
"Shading",
|
||||
"XObject",
|
||||
"Font",
|
||||
]);
|
||||
|
||||
const partialEvaluator = new PartialEvaluator({
|
||||
|
@ -222,61 +262,76 @@ class Page {
|
|||
const pageListPromise = dataPromises.then(([contentStream]) => {
|
||||
const opList = new OperatorList(intent, sink, this.pageIndex);
|
||||
|
||||
handler.send('StartRenderPage', {
|
||||
handler.send("StartRenderPage", {
|
||||
transparency: partialEvaluator.hasBlendModes(this.resources),
|
||||
pageIndex: this.pageIndex,
|
||||
intent,
|
||||
});
|
||||
|
||||
return partialEvaluator.getOperatorList({
|
||||
stream: contentStream,
|
||||
task,
|
||||
resources: this.resources,
|
||||
operatorList: opList,
|
||||
}).then(function() {
|
||||
return opList;
|
||||
});
|
||||
return partialEvaluator
|
||||
.getOperatorList({
|
||||
stream: contentStream,
|
||||
task,
|
||||
resources: this.resources,
|
||||
operatorList: opList,
|
||||
})
|
||||
.then(function() {
|
||||
return opList;
|
||||
});
|
||||
});
|
||||
|
||||
// Fetch the page's annotations and add their operator lists to the
|
||||
// page's operator list to render them.
|
||||
return Promise.all([pageListPromise, this._parsedAnnotations]).then(
|
||||
function([pageOpList, annotations]) {
|
||||
if (annotations.length === 0) {
|
||||
pageOpList.flush(true);
|
||||
return { length: pageOpList.totalLength, };
|
||||
}
|
||||
|
||||
// Collect the operator list promises for the annotations. Each promise
|
||||
// is resolved with the complete operator list for a single annotation.
|
||||
const opListPromises = [];
|
||||
for (const annotation of annotations) {
|
||||
if (isAnnotationRenderable(annotation, intent)) {
|
||||
opListPromises.push(annotation.getOperatorList(
|
||||
partialEvaluator, task, renderInteractiveForms));
|
||||
function([pageOpList, annotations]) {
|
||||
if (annotations.length === 0) {
|
||||
pageOpList.flush(true);
|
||||
return { length: pageOpList.totalLength };
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.all(opListPromises).then(function(opLists) {
|
||||
pageOpList.addOp(OPS.beginAnnotations, []);
|
||||
for (const opList of opLists) {
|
||||
pageOpList.addOpList(opList);
|
||||
// Collect the operator list promises for the annotations. Each promise
|
||||
// is resolved with the complete operator list for a single annotation.
|
||||
const opListPromises = [];
|
||||
for (const annotation of annotations) {
|
||||
if (isAnnotationRenderable(annotation, intent)) {
|
||||
opListPromises.push(
|
||||
annotation.getOperatorList(
|
||||
partialEvaluator,
|
||||
task,
|
||||
renderInteractiveForms
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
pageOpList.addOp(OPS.endAnnotations, []);
|
||||
pageOpList.flush(true);
|
||||
return { length: pageOpList.totalLength, };
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(opListPromises).then(function(opLists) {
|
||||
pageOpList.addOp(OPS.beginAnnotations, []);
|
||||
for (const opList of opLists) {
|
||||
pageOpList.addOpList(opList);
|
||||
}
|
||||
pageOpList.addOp(OPS.endAnnotations, []);
|
||||
pageOpList.flush(true);
|
||||
return { length: pageOpList.totalLength };
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
extractTextContent({ handler, task, normalizeWhitespace, sink,
|
||||
combineTextItems, }) {
|
||||
const contentStreamPromise = this.pdfManager.ensure(this,
|
||||
'getContentStream');
|
||||
extractTextContent({
|
||||
handler,
|
||||
task,
|
||||
normalizeWhitespace,
|
||||
sink,
|
||||
combineTextItems,
|
||||
}) {
|
||||
const contentStreamPromise = this.pdfManager.ensure(
|
||||
this,
|
||||
"getContentStream"
|
||||
);
|
||||
const resourcesPromise = this.loadResources([
|
||||
'ExtGState',
|
||||
'XObject',
|
||||
'Font',
|
||||
"ExtGState",
|
||||
"XObject",
|
||||
"Font",
|
||||
]);
|
||||
|
||||
const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]);
|
||||
|
@ -316,47 +371,62 @@ class Page {
|
|||
}
|
||||
|
||||
get annotations() {
|
||||
return shadow(this, 'annotations',
|
||||
this._getInheritableProperty('Annots') || []);
|
||||
return shadow(
|
||||
this,
|
||||
"annotations",
|
||||
this._getInheritableProperty("Annots") || []
|
||||
);
|
||||
}
|
||||
|
||||
get _parsedAnnotations() {
|
||||
const parsedAnnotations =
|
||||
this.pdfManager.ensure(this, 'annotations').then(() => {
|
||||
const parsedAnnotations = this.pdfManager
|
||||
.ensure(this, "annotations")
|
||||
.then(() => {
|
||||
const annotationRefs = this.annotations;
|
||||
const annotationPromises = [];
|
||||
for (let i = 0, ii = annotationRefs.length; i < ii; i++) {
|
||||
annotationPromises.push(AnnotationFactory.create(
|
||||
this.xref, annotationRefs[i], this.pdfManager, this.idFactory));
|
||||
annotationPromises.push(
|
||||
AnnotationFactory.create(
|
||||
this.xref,
|
||||
annotationRefs[i],
|
||||
this.pdfManager,
|
||||
this.idFactory
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return Promise.all(annotationPromises).then(function(annotations) {
|
||||
return annotations.filter(function isDefined(annotation) {
|
||||
return !!annotation;
|
||||
});
|
||||
}, function(reason) {
|
||||
warn(`_parsedAnnotations: "${reason}".`);
|
||||
return [];
|
||||
});
|
||||
return Promise.all(annotationPromises).then(
|
||||
function(annotations) {
|
||||
return annotations.filter(function isDefined(annotation) {
|
||||
return !!annotation;
|
||||
});
|
||||
},
|
||||
function(reason) {
|
||||
warn(`_parsedAnnotations: "${reason}".`);
|
||||
return [];
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return shadow(this, '_parsedAnnotations', parsedAnnotations);
|
||||
return shadow(this, "_parsedAnnotations", parsedAnnotations);
|
||||
}
|
||||
}
|
||||
|
||||
const PDF_HEADER_SIGNATURE = new Uint8Array([0x25, 0x50, 0x44, 0x46, 0x2D]);
|
||||
const PDF_HEADER_SIGNATURE = new Uint8Array([0x25, 0x50, 0x44, 0x46, 0x2d]);
|
||||
// prettier-ignore
|
||||
const STARTXREF_SIGNATURE = new Uint8Array([
|
||||
0x73, 0x74, 0x61, 0x72, 0x74, 0x78, 0x72, 0x65, 0x66]);
|
||||
const ENDOBJ_SIGNATURE = new Uint8Array([0x65, 0x6E, 0x64, 0x6F, 0x62, 0x6A]);
|
||||
const ENDOBJ_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64, 0x6f, 0x62, 0x6a]);
|
||||
|
||||
const FINGERPRINT_FIRST_BYTES = 1024;
|
||||
const EMPTY_FINGERPRINT =
|
||||
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00';
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||
|
||||
function find(stream, signature, limit = 1024, backwards = false) {
|
||||
if (typeof PDFJSDev === 'undefined' ||
|
||||
PDFJSDev.test('!PRODUCTION || TESTING')) {
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(limit > 0, 'The "limit" must be a positive integer.');
|
||||
}
|
||||
const signatureLength = signature.length;
|
||||
|
@ -373,24 +443,29 @@ function find(stream, signature, limit = 1024, backwards = false) {
|
|||
let pos = scanBytes.length - 1;
|
||||
while (pos >= signatureEnd) {
|
||||
let j = 0;
|
||||
while (j < signatureLength &&
|
||||
scanBytes[pos - j] === signature[signatureEnd - j]) {
|
||||
while (
|
||||
j < signatureLength &&
|
||||
scanBytes[pos - j] === signature[signatureEnd - j]
|
||||
) {
|
||||
j++;
|
||||
}
|
||||
if (j >= signatureLength) { // `signature` found.
|
||||
stream.pos += (pos - signatureEnd);
|
||||
if (j >= signatureLength) {
|
||||
// `signature` found.
|
||||
stream.pos += pos - signatureEnd;
|
||||
return true;
|
||||
}
|
||||
pos--;
|
||||
}
|
||||
} else { // forwards
|
||||
} else {
|
||||
// forwards
|
||||
let pos = 0;
|
||||
while (pos <= scanLength) {
|
||||
let j = 0;
|
||||
while (j < signatureLength && scanBytes[pos + j] === signature[j]) {
|
||||
j++;
|
||||
}
|
||||
if (j >= signatureLength) { // `signature` found.
|
||||
if (j >= signatureLength) {
|
||||
// `signature` found.
|
||||
stream.pos += pos;
|
||||
return true;
|
||||
}
|
||||
|
@ -411,11 +486,12 @@ class PDFDocument {
|
|||
} else if (isArrayBuffer(arg)) {
|
||||
stream = new Stream(arg);
|
||||
} else {
|
||||
throw new Error('PDFDocument: Unknown argument type');
|
||||
throw new Error("PDFDocument: Unknown argument type");
|
||||
}
|
||||
if (stream.length <= 0) {
|
||||
throw new InvalidPDFException(
|
||||
'The PDF file is empty, i.e. its size is zero bytes.');
|
||||
"The PDF file is empty, i.e. its size is zero bytes."
|
||||
);
|
||||
}
|
||||
|
||||
this.pdfManager = pdfManager;
|
||||
|
@ -432,17 +508,17 @@ class PDFDocument {
|
|||
parse(recoveryMode) {
|
||||
this.setup(recoveryMode);
|
||||
|
||||
const version = this.catalog.catDict.get('Version');
|
||||
const version = this.catalog.catDict.get("Version");
|
||||
if (isName(version)) {
|
||||
this.pdfFormatVersion = version.name;
|
||||
}
|
||||
|
||||
// Check if AcroForms are present in the document.
|
||||
try {
|
||||
this.acroForm = this.catalog.catDict.get('AcroForm');
|
||||
this.acroForm = this.catalog.catDict.get("AcroForm");
|
||||
if (this.acroForm) {
|
||||
this.xfa = this.acroForm.get('XFA');
|
||||
const fields = this.acroForm.get('Fields');
|
||||
this.xfa = this.acroForm.get("XFA");
|
||||
const fields = this.acroForm.get("Fields");
|
||||
if ((!Array.isArray(fields) || fields.length === 0) && !this.xfa) {
|
||||
this.acroForm = null; // No fields and no XFA, so it's not a form.
|
||||
}
|
||||
|
@ -451,13 +527,13 @@ class PDFDocument {
|
|||
if (ex instanceof MissingDataException) {
|
||||
throw ex;
|
||||
}
|
||||
info('Cannot fetch AcroForm entry; assuming no AcroForms are present');
|
||||
info("Cannot fetch AcroForm entry; assuming no AcroForms are present");
|
||||
this.acroForm = null;
|
||||
}
|
||||
|
||||
// Check if a Collection dictionary is present in the document.
|
||||
try {
|
||||
const collection = this.catalog.catDict.get('Collection');
|
||||
const collection = this.catalog.catDict.get("Collection");
|
||||
if (isDict(collection) && collection.getKeys().length > 0) {
|
||||
this.collection = collection;
|
||||
}
|
||||
|
@ -465,7 +541,7 @@ class PDFDocument {
|
|||
if (ex instanceof MissingDataException) {
|
||||
throw ex;
|
||||
}
|
||||
info('Cannot fetch Collection dictionary.');
|
||||
info("Cannot fetch Collection dictionary.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -479,7 +555,7 @@ class PDFDocument {
|
|||
}
|
||||
info(err);
|
||||
}
|
||||
return shadow(this, 'linearization', linearization);
|
||||
return shadow(this, "linearization", linearization);
|
||||
}
|
||||
|
||||
get startXRef() {
|
||||
|
@ -490,13 +566,14 @@ class PDFDocument {
|
|||
// Find the end of the first object.
|
||||
stream.reset();
|
||||
if (find(stream, ENDOBJ_SIGNATURE)) {
|
||||
startXRef = (stream.pos + 6) - stream.start;
|
||||
startXRef = stream.pos + 6 - stream.start;
|
||||
}
|
||||
} else {
|
||||
// Find `startxref` by checking backwards from the end of the file.
|
||||
const step = 1024;
|
||||
const startXRefLength = STARTXREF_SIGNATURE.length;
|
||||
let found = false, pos = stream.end;
|
||||
let found = false,
|
||||
pos = stream.end;
|
||||
|
||||
while (!found && pos > 0) {
|
||||
pos -= step - startXRefLength;
|
||||
|
@ -513,8 +590,9 @@ class PDFDocument {
|
|||
do {
|
||||
ch = stream.getByte();
|
||||
} while (isSpace(ch));
|
||||
let str = '';
|
||||
while (ch >= 0x20 && ch <= 0x39) { // < '9'
|
||||
let str = "";
|
||||
while (ch >= 0x20 && ch <= 0x39) {
|
||||
// < '9'
|
||||
str += String.fromCharCode(ch);
|
||||
ch = stream.getByte();
|
||||
}
|
||||
|
@ -524,7 +602,7 @@ class PDFDocument {
|
|||
}
|
||||
}
|
||||
}
|
||||
return shadow(this, 'startXRef', startXRef);
|
||||
return shadow(this, "startXRef", startXRef);
|
||||
}
|
||||
|
||||
// Find the header, get the PDF format version and setup the
|
||||
|
@ -542,8 +620,10 @@ class PDFDocument {
|
|||
|
||||
// Read the PDF format version.
|
||||
const MAX_PDF_VERSION_LENGTH = 12;
|
||||
let version = '', ch;
|
||||
while ((ch = stream.getByte()) > 0x20) { // Space
|
||||
let version = "",
|
||||
ch;
|
||||
while ((ch = stream.getByte()) > 0x20) {
|
||||
// Space
|
||||
if (version.length >= MAX_PDF_VERSION_LENGTH) {
|
||||
break;
|
||||
}
|
||||
|
@ -567,7 +647,7 @@ class PDFDocument {
|
|||
get numPages() {
|
||||
const linearization = this.linearization;
|
||||
const num = linearization ? linearization.numPages : this.catalog.numPages;
|
||||
return shadow(this, 'numPages', num);
|
||||
return shadow(this, "numPages", num);
|
||||
}
|
||||
|
||||
get documentInfo() {
|
||||
|
@ -593,12 +673,12 @@ class PDFDocument {
|
|||
|
||||
let infoDict;
|
||||
try {
|
||||
infoDict = this.xref.trailer.get('Info');
|
||||
infoDict = this.xref.trailer.get("Info");
|
||||
} catch (err) {
|
||||
if (err instanceof MissingDataException) {
|
||||
throw err;
|
||||
}
|
||||
info('The document information dictionary is invalid.');
|
||||
info("The document information dictionary is invalid.");
|
||||
}
|
||||
|
||||
if (isDict(infoDict)) {
|
||||
|
@ -610,12 +690,12 @@ class PDFDocument {
|
|||
if (DocumentInfoValidators[key]) {
|
||||
// Make sure the (standard) value conforms to the specification.
|
||||
if (DocumentInfoValidators[key](value)) {
|
||||
docInfo[key] = (typeof value !== 'string' ?
|
||||
value : stringToPDFString(value));
|
||||
docInfo[key] =
|
||||
typeof value !== "string" ? value : stringToPDFString(value);
|
||||
} else {
|
||||
info(`Bad value in document info for "${key}".`);
|
||||
}
|
||||
} else if (typeof key === 'string') {
|
||||
} else if (typeof key === "string") {
|
||||
// For custom values, only accept white-listed types to prevent
|
||||
// errors that would occur when trying to send non-serializable
|
||||
// objects to the main-thread (for example `Dict` or `Stream`).
|
||||
|
@ -629,67 +709,83 @@ class PDFDocument {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!docInfo['Custom']) {
|
||||
docInfo['Custom'] = Object.create(null);
|
||||
if (!docInfo["Custom"]) {
|
||||
docInfo["Custom"] = Object.create(null);
|
||||
}
|
||||
docInfo['Custom'][key] = customValue;
|
||||
docInfo["Custom"][key] = customValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return shadow(this, 'documentInfo', docInfo);
|
||||
return shadow(this, "documentInfo", docInfo);
|
||||
}
|
||||
|
||||
get fingerprint() {
|
||||
let hash;
|
||||
const idArray = this.xref.trailer.get('ID');
|
||||
if (Array.isArray(idArray) && idArray[0] && isString(idArray[0]) &&
|
||||
idArray[0] !== EMPTY_FINGERPRINT) {
|
||||
const idArray = this.xref.trailer.get("ID");
|
||||
if (
|
||||
Array.isArray(idArray) &&
|
||||
idArray[0] &&
|
||||
isString(idArray[0]) &&
|
||||
idArray[0] !== EMPTY_FINGERPRINT
|
||||
) {
|
||||
hash = stringToBytes(idArray[0]);
|
||||
} else {
|
||||
hash = calculateMD5(this.stream.getByteRange(0, FINGERPRINT_FIRST_BYTES),
|
||||
0, FINGERPRINT_FIRST_BYTES);
|
||||
hash = calculateMD5(
|
||||
this.stream.getByteRange(0, FINGERPRINT_FIRST_BYTES),
|
||||
0,
|
||||
FINGERPRINT_FIRST_BYTES
|
||||
);
|
||||
}
|
||||
|
||||
const fingerprintBuf = [];
|
||||
for (let i = 0, ii = hash.length; i < ii; i++) {
|
||||
const hex = hash[i].toString(16);
|
||||
fingerprintBuf.push(hex.padStart(2, '0'));
|
||||
fingerprintBuf.push(hex.padStart(2, "0"));
|
||||
}
|
||||
return shadow(this, 'fingerprint', fingerprintBuf.join(''));
|
||||
return shadow(this, "fingerprint", fingerprintBuf.join(""));
|
||||
}
|
||||
|
||||
_getLinearizationPage(pageIndex) {
|
||||
const { catalog, linearization, } = this;
|
||||
const { catalog, linearization } = this;
|
||||
assert(linearization && linearization.pageFirst === pageIndex);
|
||||
|
||||
const ref = Ref.get(linearization.objectNumberFirst, 0);
|
||||
return this.xref.fetchAsync(ref).then((obj) => {
|
||||
// Ensure that the object that was found is actually a Page dictionary.
|
||||
if (isDict(obj, 'Page') ||
|
||||
(isDict(obj) && !obj.has('Type') && obj.has('Contents'))) {
|
||||
if (ref && !catalog.pageKidsCountCache.has(ref)) {
|
||||
catalog.pageKidsCountCache.put(ref, 1); // Cache the Page reference.
|
||||
return this.xref
|
||||
.fetchAsync(ref)
|
||||
.then(obj => {
|
||||
// Ensure that the object that was found is actually a Page dictionary.
|
||||
if (
|
||||
isDict(obj, "Page") ||
|
||||
(isDict(obj) && !obj.has("Type") && obj.has("Contents"))
|
||||
) {
|
||||
if (ref && !catalog.pageKidsCountCache.has(ref)) {
|
||||
catalog.pageKidsCountCache.put(ref, 1); // Cache the Page reference.
|
||||
}
|
||||
return [obj, ref];
|
||||
}
|
||||
return [obj, ref];
|
||||
}
|
||||
throw new FormatError('The Linearization dictionary doesn\'t point ' +
|
||||
'to a valid Page dictionary.');
|
||||
}).catch((reason) => {
|
||||
info(reason);
|
||||
return catalog.getPageDict(pageIndex);
|
||||
});
|
||||
throw new FormatError(
|
||||
"The Linearization dictionary doesn't point " +
|
||||
"to a valid Page dictionary."
|
||||
);
|
||||
})
|
||||
.catch(reason => {
|
||||
info(reason);
|
||||
return catalog.getPageDict(pageIndex);
|
||||
});
|
||||
}
|
||||
|
||||
getPage(pageIndex) {
|
||||
if (this._pagePromises[pageIndex] !== undefined) {
|
||||
return this._pagePromises[pageIndex];
|
||||
}
|
||||
const { catalog, linearization, } = this;
|
||||
const { catalog, linearization } = this;
|
||||
|
||||
const promise = (linearization && linearization.pageFirst === pageIndex) ?
|
||||
this._getLinearizationPage(pageIndex) : catalog.getPageDict(pageIndex);
|
||||
const promise =
|
||||
linearization && linearization.pageFirst === pageIndex
|
||||
? this._getLinearizationPage(pageIndex)
|
||||
: catalog.getPageDict(pageIndex);
|
||||
|
||||
return this._pagePromises[pageIndex] = promise.then(([pageDict, ref]) => {
|
||||
return (this._pagePromises[pageIndex] = promise.then(([pageDict, ref]) => {
|
||||
return new Page({
|
||||
pdfManager: this.pdfManager,
|
||||
xref: this.xref,
|
||||
|
@ -700,11 +796,11 @@ class PDFDocument {
|
|||
builtInCMapCache: catalog.builtInCMapCache,
|
||||
pdfFunctionFactory: this.pdfFunctionFactory,
|
||||
});
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
checkFirstPage() {
|
||||
return this.getPage(0).catch(async (reason) => {
|
||||
return this.getPage(0).catch(async reason => {
|
||||
if (reason instanceof XRefEntryException) {
|
||||
// Clear out the various caches to ensure that we haven't stored any
|
||||
// inconsistent and/or incorrect state, since that could easily break
|
||||
|
@ -726,7 +822,4 @@ class PDFDocument {
|
|||
}
|
||||
}
|
||||
|
||||
export {
|
||||
Page,
|
||||
PDFDocument,
|
||||
};
|
||||
export { Page, PDFDocument };
|
||||
|
|
|
@ -15,275 +15,275 @@
|
|||
|
||||
// prettier-ignore
|
||||
const ExpertEncoding = [
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'space', 'exclamsmall', 'Hungarumlautsmall', '', 'dollaroldstyle',
|
||||
'dollarsuperior', 'ampersandsmall', 'Acutesmall', 'parenleftsuperior',
|
||||
'parenrightsuperior', 'twodotenleader', 'onedotenleader', 'comma',
|
||||
'hyphen', 'period', 'fraction', 'zerooldstyle', 'oneoldstyle',
|
||||
'twooldstyle', 'threeoldstyle', 'fouroldstyle', 'fiveoldstyle',
|
||||
'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', 'colon',
|
||||
'semicolon', 'commasuperior', 'threequartersemdash', 'periodsuperior',
|
||||
'questionsmall', '', 'asuperior', 'bsuperior', 'centsuperior', 'dsuperior',
|
||||
'esuperior', '', '', '', 'isuperior', '', '', 'lsuperior', 'msuperior',
|
||||
'nsuperior', 'osuperior', '', '', 'rsuperior', 'ssuperior', 'tsuperior',
|
||||
'', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', '',
|
||||
'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall',
|
||||
'Asmall', 'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall',
|
||||
'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall',
|
||||
'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall',
|
||||
'Vsmall', 'Wsmall', 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary',
|
||||
'onefitted', 'rupiah', 'Tildesmall', '', '', '', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', 'exclamdownsmall', 'centoldstyle', 'Lslashsmall',
|
||||
'', '', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', 'Brevesmall',
|
||||
'Caronsmall', '', 'Dotaccentsmall', '', '', 'Macronsmall', '', '',
|
||||
'figuredash', 'hypheninferior', '', '', 'Ogoneksmall', 'Ringsmall',
|
||||
'Cedillasmall', '', '', '', 'onequarter', 'onehalf', 'threequarters',
|
||||
'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths',
|
||||
'seveneighths', 'onethird', 'twothirds', '', '', 'zerosuperior',
|
||||
'onesuperior', 'twosuperior', 'threesuperior', 'foursuperior',
|
||||
'fivesuperior', 'sixsuperior', 'sevensuperior', 'eightsuperior',
|
||||
'ninesuperior', 'zeroinferior', 'oneinferior', 'twoinferior',
|
||||
'threeinferior', 'fourinferior', 'fiveinferior', 'sixinferior',
|
||||
'seveninferior', 'eightinferior', 'nineinferior', 'centinferior',
|
||||
'dollarinferior', 'periodinferior', 'commainferior', 'Agravesmall',
|
||||
'Aacutesmall', 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall',
|
||||
'Aringsmall', 'AEsmall', 'Ccedillasmall', 'Egravesmall', 'Eacutesmall',
|
||||
'Ecircumflexsmall', 'Edieresissmall', 'Igravesmall', 'Iacutesmall',
|
||||
'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall',
|
||||
'Ogravesmall', 'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall',
|
||||
'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', 'Uacutesmall',
|
||||
'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall',
|
||||
'Ydieresissmall'];
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"space", "exclamsmall", "Hungarumlautsmall", "", "dollaroldstyle",
|
||||
"dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior",
|
||||
"parenrightsuperior", "twodotenleader", "onedotenleader", "comma",
|
||||
"hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle",
|
||||
"twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle",
|
||||
"sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon",
|
||||
"semicolon", "commasuperior", "threequartersemdash", "periodsuperior",
|
||||
"questionsmall", "", "asuperior", "bsuperior", "centsuperior", "dsuperior",
|
||||
"esuperior", "", "", "", "isuperior", "", "", "lsuperior", "msuperior",
|
||||
"nsuperior", "osuperior", "", "", "rsuperior", "ssuperior", "tsuperior",
|
||||
"", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", "",
|
||||
"parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
|
||||
"Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall",
|
||||
"Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall",
|
||||
"Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
|
||||
"Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary",
|
||||
"onefitted", "rupiah", "Tildesmall", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "exclamdownsmall", "centoldstyle", "Lslashsmall",
|
||||
"", "", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall",
|
||||
"Caronsmall", "", "Dotaccentsmall", "", "", "Macronsmall", "", "",
|
||||
"figuredash", "hypheninferior", "", "", "Ogoneksmall", "Ringsmall",
|
||||
"Cedillasmall", "", "", "", "onequarter", "onehalf", "threequarters",
|
||||
"questiondownsmall", "oneeighth", "threeeighths", "fiveeighths",
|
||||
"seveneighths", "onethird", "twothirds", "", "", "zerosuperior",
|
||||
"onesuperior", "twosuperior", "threesuperior", "foursuperior",
|
||||
"fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior",
|
||||
"ninesuperior", "zeroinferior", "oneinferior", "twoinferior",
|
||||
"threeinferior", "fourinferior", "fiveinferior", "sixinferior",
|
||||
"seveninferior", "eightinferior", "nineinferior", "centinferior",
|
||||
"dollarinferior", "periodinferior", "commainferior", "Agravesmall",
|
||||
"Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall",
|
||||
"Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall",
|
||||
"Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall",
|
||||
"Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall",
|
||||
"Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
|
||||
"Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall",
|
||||
"Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall",
|
||||
"Ydieresissmall"];
|
||||
|
||||
// prettier-ignore
|
||||
const MacExpertEncoding = [
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'space', 'exclamsmall', 'Hungarumlautsmall', 'centoldstyle',
|
||||
'dollaroldstyle', 'dollarsuperior', 'ampersandsmall', 'Acutesmall',
|
||||
'parenleftsuperior', 'parenrightsuperior', 'twodotenleader',
|
||||
'onedotenleader', 'comma', 'hyphen', 'period', 'fraction', 'zerooldstyle',
|
||||
'oneoldstyle', 'twooldstyle', 'threeoldstyle', 'fouroldstyle',
|
||||
'fiveoldstyle', 'sixoldstyle', 'sevenoldstyle', 'eightoldstyle',
|
||||
'nineoldstyle', 'colon', 'semicolon', '', 'threequartersemdash', '',
|
||||
'questionsmall', '', '', '', '', 'Ethsmall', '', '', 'onequarter',
|
||||
'onehalf', 'threequarters', 'oneeighth', 'threeeighths', 'fiveeighths',
|
||||
'seveneighths', 'onethird', 'twothirds', '', '', '', '', '', '', 'ff',
|
||||
'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', '', 'parenrightinferior',
|
||||
'Circumflexsmall', 'hypheninferior', 'Gravesmall', 'Asmall', 'Bsmall',
|
||||
'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', 'Hsmall', 'Ismall',
|
||||
'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall', 'Osmall', 'Psmall',
|
||||
'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', 'Vsmall', 'Wsmall',
|
||||
'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', 'onefitted', 'rupiah',
|
||||
'Tildesmall', '', '', 'asuperior', 'centsuperior', '', '', '', '',
|
||||
'Aacutesmall', 'Agravesmall', 'Acircumflexsmall', 'Adieresissmall',
|
||||
'Atildesmall', 'Aringsmall', 'Ccedillasmall', 'Eacutesmall', 'Egravesmall',
|
||||
'Ecircumflexsmall', 'Edieresissmall', 'Iacutesmall', 'Igravesmall',
|
||||
'Icircumflexsmall', 'Idieresissmall', 'Ntildesmall', 'Oacutesmall',
|
||||
'Ogravesmall', 'Ocircumflexsmall', 'Odieresissmall', 'Otildesmall',
|
||||
'Uacutesmall', 'Ugravesmall', 'Ucircumflexsmall', 'Udieresissmall', '',
|
||||
'eightsuperior', 'fourinferior', 'threeinferior', 'sixinferior',
|
||||
'eightinferior', 'seveninferior', 'Scaronsmall', '', 'centinferior',
|
||||
'twoinferior', '', 'Dieresissmall', '', 'Caronsmall', 'osuperior',
|
||||
'fiveinferior', '', 'commainferior', 'periodinferior', 'Yacutesmall', '',
|
||||
'dollarinferior', '', '', 'Thornsmall', '', 'nineinferior', 'zeroinferior',
|
||||
'Zcaronsmall', 'AEsmall', 'Oslashsmall', 'questiondownsmall',
|
||||
'oneinferior', 'Lslashsmall', '', '', '', '', '', '', 'Cedillasmall', '',
|
||||
'', '', '', '', 'OEsmall', 'figuredash', 'hyphensuperior', '', '', '', '',
|
||||
'exclamdownsmall', '', 'Ydieresissmall', '', 'onesuperior', 'twosuperior',
|
||||
'threesuperior', 'foursuperior', 'fivesuperior', 'sixsuperior',
|
||||
'sevensuperior', 'ninesuperior', 'zerosuperior', '', 'esuperior',
|
||||
'rsuperior', 'tsuperior', '', '', 'isuperior', 'ssuperior', 'dsuperior',
|
||||
'', '', '', '', '', 'lsuperior', 'Ogoneksmall', 'Brevesmall',
|
||||
'Macronsmall', 'bsuperior', 'nsuperior', 'msuperior', 'commasuperior',
|
||||
'periodsuperior', 'Dotaccentsmall', 'Ringsmall', '', '', '', ''];
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"space", "exclamsmall", "Hungarumlautsmall", "centoldstyle",
|
||||
"dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall",
|
||||
"parenleftsuperior", "parenrightsuperior", "twodotenleader",
|
||||
"onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle",
|
||||
"oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle",
|
||||
"fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle",
|
||||
"nineoldstyle", "colon", "semicolon", "", "threequartersemdash", "",
|
||||
"questionsmall", "", "", "", "", "Ethsmall", "", "", "onequarter",
|
||||
"onehalf", "threequarters", "oneeighth", "threeeighths", "fiveeighths",
|
||||
"seveneighths", "onethird", "twothirds", "", "", "", "", "", "", "ff",
|
||||
"fi", "fl", "ffi", "ffl", "parenleftinferior", "", "parenrightinferior",
|
||||
"Circumflexsmall", "hypheninferior", "Gravesmall", "Asmall", "Bsmall",
|
||||
"Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall",
|
||||
"Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
|
||||
"Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall",
|
||||
"Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah",
|
||||
"Tildesmall", "", "", "asuperior", "centsuperior", "", "", "", "",
|
||||
"Aacutesmall", "Agravesmall", "Acircumflexsmall", "Adieresissmall",
|
||||
"Atildesmall", "Aringsmall", "Ccedillasmall", "Eacutesmall", "Egravesmall",
|
||||
"Ecircumflexsmall", "Edieresissmall", "Iacutesmall", "Igravesmall",
|
||||
"Icircumflexsmall", "Idieresissmall", "Ntildesmall", "Oacutesmall",
|
||||
"Ogravesmall", "Ocircumflexsmall", "Odieresissmall", "Otildesmall",
|
||||
"Uacutesmall", "Ugravesmall", "Ucircumflexsmall", "Udieresissmall", "",
|
||||
"eightsuperior", "fourinferior", "threeinferior", "sixinferior",
|
||||
"eightinferior", "seveninferior", "Scaronsmall", "", "centinferior",
|
||||
"twoinferior", "", "Dieresissmall", "", "Caronsmall", "osuperior",
|
||||
"fiveinferior", "", "commainferior", "periodinferior", "Yacutesmall", "",
|
||||
"dollarinferior", "", "", "Thornsmall", "", "nineinferior", "zeroinferior",
|
||||
"Zcaronsmall", "AEsmall", "Oslashsmall", "questiondownsmall",
|
||||
"oneinferior", "Lslashsmall", "", "", "", "", "", "", "Cedillasmall", "",
|
||||
"", "", "", "", "OEsmall", "figuredash", "hyphensuperior", "", "", "", "",
|
||||
"exclamdownsmall", "", "Ydieresissmall", "", "onesuperior", "twosuperior",
|
||||
"threesuperior", "foursuperior", "fivesuperior", "sixsuperior",
|
||||
"sevensuperior", "ninesuperior", "zerosuperior", "", "esuperior",
|
||||
"rsuperior", "tsuperior", "", "", "isuperior", "ssuperior", "dsuperior",
|
||||
"", "", "", "", "", "lsuperior", "Ogoneksmall", "Brevesmall",
|
||||
"Macronsmall", "bsuperior", "nsuperior", "msuperior", "commasuperior",
|
||||
"periodsuperior", "Dotaccentsmall", "Ringsmall", "", "", "", ""];
|
||||
|
||||
// prettier-ignore
|
||||
const MacRomanEncoding = [
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent',
|
||||
'ampersand', 'quotesingle', 'parenleft', 'parenright', 'asterisk', 'plus',
|
||||
'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three',
|
||||
'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon',
|
||||
'less', 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F',
|
||||
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
|
||||
'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright',
|
||||
'asciicircum', 'underscore', 'grave', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde', '',
|
||||
'Adieresis', 'Aring', 'Ccedilla', 'Eacute', 'Ntilde', 'Odieresis',
|
||||
'Udieresis', 'aacute', 'agrave', 'acircumflex', 'adieresis', 'atilde',
|
||||
'aring', 'ccedilla', 'eacute', 'egrave', 'ecircumflex', 'edieresis',
|
||||
'iacute', 'igrave', 'icircumflex', 'idieresis', 'ntilde', 'oacute',
|
||||
'ograve', 'ocircumflex', 'odieresis', 'otilde', 'uacute', 'ugrave',
|
||||
'ucircumflex', 'udieresis', 'dagger', 'degree', 'cent', 'sterling',
|
||||
'section', 'bullet', 'paragraph', 'germandbls', 'registered', 'copyright',
|
||||
'trademark', 'acute', 'dieresis', 'notequal', 'AE', 'Oslash', 'infinity',
|
||||
'plusminus', 'lessequal', 'greaterequal', 'yen', 'mu', 'partialdiff',
|
||||
'summation', 'product', 'pi', 'integral', 'ordfeminine', 'ordmasculine',
|
||||
'Omega', 'ae', 'oslash', 'questiondown', 'exclamdown', 'logicalnot',
|
||||
'radical', 'florin', 'approxequal', 'Delta', 'guillemotleft',
|
||||
'guillemotright', 'ellipsis', 'space', 'Agrave', 'Atilde', 'Otilde', 'OE',
|
||||
'oe', 'endash', 'emdash', 'quotedblleft', 'quotedblright', 'quoteleft',
|
||||
'quoteright', 'divide', 'lozenge', 'ydieresis', 'Ydieresis', 'fraction',
|
||||
'currency', 'guilsinglleft', 'guilsinglright', 'fi', 'fl', 'daggerdbl',
|
||||
'periodcentered', 'quotesinglbase', 'quotedblbase', 'perthousand',
|
||||
'Acircumflex', 'Ecircumflex', 'Aacute', 'Edieresis', 'Egrave', 'Iacute',
|
||||
'Icircumflex', 'Idieresis', 'Igrave', 'Oacute', 'Ocircumflex', 'apple',
|
||||
'Ograve', 'Uacute', 'Ucircumflex', 'Ugrave', 'dotlessi', 'circumflex',
|
||||
'tilde', 'macron', 'breve', 'dotaccent', 'ring', 'cedilla', 'hungarumlaut',
|
||||
'ogonek', 'caron'];
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"space", "exclam", "quotedbl", "numbersign", "dollar", "percent",
|
||||
"ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus",
|
||||
"comma", "hyphen", "period", "slash", "zero", "one", "two", "three",
|
||||
"four", "five", "six", "seven", "eight", "nine", "colon", "semicolon",
|
||||
"less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F",
|
||||
"G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
|
||||
"V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright",
|
||||
"asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g",
|
||||
"h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
|
||||
"w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "",
|
||||
"Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis",
|
||||
"Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde",
|
||||
"aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis",
|
||||
"iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute",
|
||||
"ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave",
|
||||
"ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling",
|
||||
"section", "bullet", "paragraph", "germandbls", "registered", "copyright",
|
||||
"trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity",
|
||||
"plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff",
|
||||
"summation", "product", "pi", "integral", "ordfeminine", "ordmasculine",
|
||||
"Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot",
|
||||
"radical", "florin", "approxequal", "Delta", "guillemotleft",
|
||||
"guillemotright", "ellipsis", "space", "Agrave", "Atilde", "Otilde", "OE",
|
||||
"oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft",
|
||||
"quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction",
|
||||
"currency", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl",
|
||||
"periodcentered", "quotesinglbase", "quotedblbase", "perthousand",
|
||||
"Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute",
|
||||
"Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "apple",
|
||||
"Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "circumflex",
|
||||
"tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut",
|
||||
"ogonek", "caron"];
|
||||
|
||||
// prettier-ignore
|
||||
const StandardEncoding = [
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent',
|
||||
'ampersand', 'quoteright', 'parenleft', 'parenright', 'asterisk', 'plus',
|
||||
'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three',
|
||||
'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon',
|
||||
'less', 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F',
|
||||
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
|
||||
'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright',
|
||||
'asciicircum', 'underscore', 'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
|
||||
'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde',
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'exclamdown',
|
||||
'cent', 'sterling', 'fraction', 'yen', 'florin', 'section', 'currency',
|
||||
'quotesingle', 'quotedblleft', 'guillemotleft', 'guilsinglleft',
|
||||
'guilsinglright', 'fi', 'fl', '', 'endash', 'dagger', 'daggerdbl',
|
||||
'periodcentered', '', 'paragraph', 'bullet', 'quotesinglbase',
|
||||
'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis',
|
||||
'perthousand', '', 'questiondown', '', 'grave', 'acute', 'circumflex',
|
||||
'tilde', 'macron', 'breve', 'dotaccent', 'dieresis', '', 'ring', 'cedilla',
|
||||
'', 'hungarumlaut', 'ogonek', 'caron', 'emdash', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', '', '', '', 'AE', '', 'ordfeminine', '', '',
|
||||
'', '', 'Lslash', 'Oslash', 'OE', 'ordmasculine', '', '', '', '', '', 'ae',
|
||||
'', '', '', 'dotlessi', '', '', 'lslash', 'oslash', 'oe', 'germandbls', '',
|
||||
'', '', ''];
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"space", "exclam", "quotedbl", "numbersign", "dollar", "percent",
|
||||
"ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus",
|
||||
"comma", "hyphen", "period", "slash", "zero", "one", "two", "three",
|
||||
"four", "five", "six", "seven", "eight", "nine", "colon", "semicolon",
|
||||
"less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F",
|
||||
"G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
|
||||
"V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright",
|
||||
"asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f",
|
||||
"g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
|
||||
"v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "exclamdown",
|
||||
"cent", "sterling", "fraction", "yen", "florin", "section", "currency",
|
||||
"quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft",
|
||||
"guilsinglright", "fi", "fl", "", "endash", "dagger", "daggerdbl",
|
||||
"periodcentered", "", "paragraph", "bullet", "quotesinglbase",
|
||||
"quotedblbase", "quotedblright", "guillemotright", "ellipsis",
|
||||
"perthousand", "", "questiondown", "", "grave", "acute", "circumflex",
|
||||
"tilde", "macron", "breve", "dotaccent", "dieresis", "", "ring", "cedilla",
|
||||
"", "hungarumlaut", "ogonek", "caron", "emdash", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "AE", "", "ordfeminine", "", "",
|
||||
"", "", "Lslash", "Oslash", "OE", "ordmasculine", "", "", "", "", "", "ae",
|
||||
"", "", "", "dotlessi", "", "", "lslash", "oslash", "oe", "germandbls", "",
|
||||
"", "", ""];
|
||||
|
||||
// prettier-ignore
|
||||
const WinAnsiEncoding = [
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent',
|
||||
'ampersand', 'quotesingle', 'parenleft', 'parenright', 'asterisk', 'plus',
|
||||
'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three',
|
||||
'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon',
|
||||
'less', 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F',
|
||||
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
|
||||
'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright',
|
||||
'asciicircum', 'underscore', 'grave', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde',
|
||||
'bullet', 'Euro', 'bullet', 'quotesinglbase', 'florin', 'quotedblbase',
|
||||
'ellipsis', 'dagger', 'daggerdbl', 'circumflex', 'perthousand', 'Scaron',
|
||||
'guilsinglleft', 'OE', 'bullet', 'Zcaron', 'bullet', 'bullet', 'quoteleft',
|
||||
'quoteright', 'quotedblleft', 'quotedblright', 'bullet', 'endash',
|
||||
'emdash', 'tilde', 'trademark', 'scaron', 'guilsinglright', 'oe', 'bullet',
|
||||
'zcaron', 'Ydieresis', 'space', 'exclamdown', 'cent', 'sterling',
|
||||
'currency', 'yen', 'brokenbar', 'section', 'dieresis', 'copyright',
|
||||
'ordfeminine', 'guillemotleft', 'logicalnot', 'hyphen', 'registered',
|
||||
'macron', 'degree', 'plusminus', 'twosuperior', 'threesuperior', 'acute',
|
||||
'mu', 'paragraph', 'periodcentered', 'cedilla', 'onesuperior',
|
||||
'ordmasculine', 'guillemotright', 'onequarter', 'onehalf', 'threequarters',
|
||||
'questiondown', 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', 'Adieresis',
|
||||
'Aring', 'AE', 'Ccedilla', 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis',
|
||||
'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', 'Eth', 'Ntilde', 'Ograve',
|
||||
'Oacute', 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', 'Oslash',
|
||||
'Ugrave', 'Uacute', 'Ucircumflex', 'Udieresis', 'Yacute', 'Thorn',
|
||||
'germandbls', 'agrave', 'aacute', 'acircumflex', 'atilde', 'adieresis',
|
||||
'aring', 'ae', 'ccedilla', 'egrave', 'eacute', 'ecircumflex', 'edieresis',
|
||||
'igrave', 'iacute', 'icircumflex', 'idieresis', 'eth', 'ntilde', 'ograve',
|
||||
'oacute', 'ocircumflex', 'otilde', 'odieresis', 'divide', 'oslash',
|
||||
'ugrave', 'uacute', 'ucircumflex', 'udieresis', 'yacute', 'thorn',
|
||||
'ydieresis'];
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"space", "exclam", "quotedbl", "numbersign", "dollar", "percent",
|
||||
"ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus",
|
||||
"comma", "hyphen", "period", "slash", "zero", "one", "two", "three",
|
||||
"four", "five", "six", "seven", "eight", "nine", "colon", "semicolon",
|
||||
"less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F",
|
||||
"G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
|
||||
"V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright",
|
||||
"asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g",
|
||||
"h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
|
||||
"w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde",
|
||||
"bullet", "Euro", "bullet", "quotesinglbase", "florin", "quotedblbase",
|
||||
"ellipsis", "dagger", "daggerdbl", "circumflex", "perthousand", "Scaron",
|
||||
"guilsinglleft", "OE", "bullet", "Zcaron", "bullet", "bullet", "quoteleft",
|
||||
"quoteright", "quotedblleft", "quotedblright", "bullet", "endash",
|
||||
"emdash", "tilde", "trademark", "scaron", "guilsinglright", "oe", "bullet",
|
||||
"zcaron", "Ydieresis", "space", "exclamdown", "cent", "sterling",
|
||||
"currency", "yen", "brokenbar", "section", "dieresis", "copyright",
|
||||
"ordfeminine", "guillemotleft", "logicalnot", "hyphen", "registered",
|
||||
"macron", "degree", "plusminus", "twosuperior", "threesuperior", "acute",
|
||||
"mu", "paragraph", "periodcentered", "cedilla", "onesuperior",
|
||||
"ordmasculine", "guillemotright", "onequarter", "onehalf", "threequarters",
|
||||
"questiondown", "Agrave", "Aacute", "Acircumflex", "Atilde", "Adieresis",
|
||||
"Aring", "AE", "Ccedilla", "Egrave", "Eacute", "Ecircumflex", "Edieresis",
|
||||
"Igrave", "Iacute", "Icircumflex", "Idieresis", "Eth", "Ntilde", "Ograve",
|
||||
"Oacute", "Ocircumflex", "Otilde", "Odieresis", "multiply", "Oslash",
|
||||
"Ugrave", "Uacute", "Ucircumflex", "Udieresis", "Yacute", "Thorn",
|
||||
"germandbls", "agrave", "aacute", "acircumflex", "atilde", "adieresis",
|
||||
"aring", "ae", "ccedilla", "egrave", "eacute", "ecircumflex", "edieresis",
|
||||
"igrave", "iacute", "icircumflex", "idieresis", "eth", "ntilde", "ograve",
|
||||
"oacute", "ocircumflex", "otilde", "odieresis", "divide", "oslash",
|
||||
"ugrave", "uacute", "ucircumflex", "udieresis", "yacute", "thorn",
|
||||
"ydieresis"];
|
||||
|
||||
// prettier-ignore
|
||||
const SymbolSetEncoding = [
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'space', 'exclam', 'universal', 'numbersign', 'existential', 'percent',
|
||||
'ampersand', 'suchthat', 'parenleft', 'parenright', 'asteriskmath', 'plus',
|
||||
'comma', 'minus', 'period', 'slash', 'zero', 'one', 'two', 'three', 'four',
|
||||
'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less',
|
||||
'equal', 'greater', 'question', 'congruent', 'Alpha', 'Beta', 'Chi',
|
||||
'Delta', 'Epsilon', 'Phi', 'Gamma', 'Eta', 'Iota', 'theta1', 'Kappa',
|
||||
'Lambda', 'Mu', 'Nu', 'Omicron', 'Pi', 'Theta', 'Rho', 'Sigma', 'Tau',
|
||||
'Upsilon', 'sigma1', 'Omega', 'Xi', 'Psi', 'Zeta', 'bracketleft',
|
||||
'therefore', 'bracketright', 'perpendicular', 'underscore', 'radicalex',
|
||||
'alpha', 'beta', 'chi', 'delta', 'epsilon', 'phi', 'gamma', 'eta', 'iota',
|
||||
'phi1', 'kappa', 'lambda', 'mu', 'nu', 'omicron', 'pi', 'theta', 'rho',
|
||||
'sigma', 'tau', 'upsilon', 'omega1', 'omega', 'xi', 'psi', 'zeta',
|
||||
'braceleft', 'bar', 'braceright', 'similar', '', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', 'Euro', 'Upsilon1', 'minute', 'lessequal',
|
||||
'fraction', 'infinity', 'florin', 'club', 'diamond', 'heart', 'spade',
|
||||
'arrowboth', 'arrowleft', 'arrowup', 'arrowright', 'arrowdown', 'degree',
|
||||
'plusminus', 'second', 'greaterequal', 'multiply', 'proportional',
|
||||
'partialdiff', 'bullet', 'divide', 'notequal', 'equivalence',
|
||||
'approxequal', 'ellipsis', 'arrowvertex', 'arrowhorizex', 'carriagereturn',
|
||||
'aleph', 'Ifraktur', 'Rfraktur', 'weierstrass', 'circlemultiply',
|
||||
'circleplus', 'emptyset', 'intersection', 'union', 'propersuperset',
|
||||
'reflexsuperset', 'notsubset', 'propersubset', 'reflexsubset', 'element',
|
||||
'notelement', 'angle', 'gradient', 'registerserif', 'copyrightserif',
|
||||
'trademarkserif', 'product', 'radical', 'dotmath', 'logicalnot',
|
||||
'logicaland', 'logicalor', 'arrowdblboth', 'arrowdblleft', 'arrowdblup',
|
||||
'arrowdblright', 'arrowdbldown', 'lozenge', 'angleleft', 'registersans',
|
||||
'copyrightsans', 'trademarksans', 'summation', 'parenlefttp',
|
||||
'parenleftex', 'parenleftbt', 'bracketlefttp', 'bracketleftex',
|
||||
'bracketleftbt', 'bracelefttp', 'braceleftmid', 'braceleftbt', 'braceex',
|
||||
'', 'angleright', 'integral', 'integraltp', 'integralex', 'integralbt',
|
||||
'parenrighttp', 'parenrightex', 'parenrightbt', 'bracketrighttp',
|
||||
'bracketrightex', 'bracketrightbt', 'bracerighttp', 'bracerightmid',
|
||||
'bracerightbt', ''];
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"space", "exclam", "universal", "numbersign", "existential", "percent",
|
||||
"ampersand", "suchthat", "parenleft", "parenright", "asteriskmath", "plus",
|
||||
"comma", "minus", "period", "slash", "zero", "one", "two", "three", "four",
|
||||
"five", "six", "seven", "eight", "nine", "colon", "semicolon", "less",
|
||||
"equal", "greater", "question", "congruent", "Alpha", "Beta", "Chi",
|
||||
"Delta", "Epsilon", "Phi", "Gamma", "Eta", "Iota", "theta1", "Kappa",
|
||||
"Lambda", "Mu", "Nu", "Omicron", "Pi", "Theta", "Rho", "Sigma", "Tau",
|
||||
"Upsilon", "sigma1", "Omega", "Xi", "Psi", "Zeta", "bracketleft",
|
||||
"therefore", "bracketright", "perpendicular", "underscore", "radicalex",
|
||||
"alpha", "beta", "chi", "delta", "epsilon", "phi", "gamma", "eta", "iota",
|
||||
"phi1", "kappa", "lambda", "mu", "nu", "omicron", "pi", "theta", "rho",
|
||||
"sigma", "tau", "upsilon", "omega1", "omega", "xi", "psi", "zeta",
|
||||
"braceleft", "bar", "braceright", "similar", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "Euro", "Upsilon1", "minute", "lessequal",
|
||||
"fraction", "infinity", "florin", "club", "diamond", "heart", "spade",
|
||||
"arrowboth", "arrowleft", "arrowup", "arrowright", "arrowdown", "degree",
|
||||
"plusminus", "second", "greaterequal", "multiply", "proportional",
|
||||
"partialdiff", "bullet", "divide", "notequal", "equivalence",
|
||||
"approxequal", "ellipsis", "arrowvertex", "arrowhorizex", "carriagereturn",
|
||||
"aleph", "Ifraktur", "Rfraktur", "weierstrass", "circlemultiply",
|
||||
"circleplus", "emptyset", "intersection", "union", "propersuperset",
|
||||
"reflexsuperset", "notsubset", "propersubset", "reflexsubset", "element",
|
||||
"notelement", "angle", "gradient", "registerserif", "copyrightserif",
|
||||
"trademarkserif", "product", "radical", "dotmath", "logicalnot",
|
||||
"logicaland", "logicalor", "arrowdblboth", "arrowdblleft", "arrowdblup",
|
||||
"arrowdblright", "arrowdbldown", "lozenge", "angleleft", "registersans",
|
||||
"copyrightsans", "trademarksans", "summation", "parenlefttp",
|
||||
"parenleftex", "parenleftbt", "bracketlefttp", "bracketleftex",
|
||||
"bracketleftbt", "bracelefttp", "braceleftmid", "braceleftbt", "braceex",
|
||||
"", "angleright", "integral", "integraltp", "integralex", "integralbt",
|
||||
"parenrighttp", "parenrightex", "parenrightbt", "bracketrighttp",
|
||||
"bracketrightex", "bracketrightbt", "bracerighttp", "bracerightmid",
|
||||
"bracerightbt", ""];
|
||||
|
||||
// prettier-ignore
|
||||
const ZapfDingbatsEncoding = [
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
|
||||
'space', 'a1', 'a2', 'a202', 'a3', 'a4', 'a5', 'a119', 'a118', 'a117',
|
||||
'a11', 'a12', 'a13', 'a14', 'a15', 'a16', 'a105', 'a17', 'a18', 'a19',
|
||||
'a20', 'a21', 'a22', 'a23', 'a24', 'a25', 'a26', 'a27', 'a28', 'a6', 'a7',
|
||||
'a8', 'a9', 'a10', 'a29', 'a30', 'a31', 'a32', 'a33', 'a34', 'a35', 'a36',
|
||||
'a37', 'a38', 'a39', 'a40', 'a41', 'a42', 'a43', 'a44', 'a45', 'a46',
|
||||
'a47', 'a48', 'a49', 'a50', 'a51', 'a52', 'a53', 'a54', 'a55', 'a56',
|
||||
'a57', 'a58', 'a59', 'a60', 'a61', 'a62', 'a63', 'a64', 'a65', 'a66',
|
||||
'a67', 'a68', 'a69', 'a70', 'a71', 'a72', 'a73', 'a74', 'a203', 'a75',
|
||||
'a204', 'a76', 'a77', 'a78', 'a79', 'a81', 'a82', 'a83', 'a84', 'a97',
|
||||
'a98', 'a99', 'a100', '', 'a89', 'a90', 'a93', 'a94', 'a91', 'a92', 'a205',
|
||||
'a85', 'a206', 'a86', 'a87', 'a88', 'a95', 'a96', '', '', '', '', '', '',
|
||||
'', '', '', '', '', '', '', '', '', '', '', '', '', 'a101', 'a102', 'a103',
|
||||
'a104', 'a106', 'a107', 'a108', 'a112', 'a111', 'a110', 'a109', 'a120',
|
||||
'a121', 'a122', 'a123', 'a124', 'a125', 'a126', 'a127', 'a128', 'a129',
|
||||
'a130', 'a131', 'a132', 'a133', 'a134', 'a135', 'a136', 'a137', 'a138',
|
||||
'a139', 'a140', 'a141', 'a142', 'a143', 'a144', 'a145', 'a146', 'a147',
|
||||
'a148', 'a149', 'a150', 'a151', 'a152', 'a153', 'a154', 'a155', 'a156',
|
||||
'a157', 'a158', 'a159', 'a160', 'a161', 'a163', 'a164', 'a196', 'a165',
|
||||
'a192', 'a166', 'a167', 'a168', 'a169', 'a170', 'a171', 'a172', 'a173',
|
||||
'a162', 'a174', 'a175', 'a176', 'a177', 'a178', 'a179', 'a193', 'a180',
|
||||
'a199', 'a181', 'a200', 'a182', '', 'a201', 'a183', 'a184', 'a197', 'a185',
|
||||
'a194', 'a198', 'a186', 'a195', 'a187', 'a188', 'a189', 'a190', 'a191', ''];
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"space", "a1", "a2", "a202", "a3", "a4", "a5", "a119", "a118", "a117",
|
||||
"a11", "a12", "a13", "a14", "a15", "a16", "a105", "a17", "a18", "a19",
|
||||
"a20", "a21", "a22", "a23", "a24", "a25", "a26", "a27", "a28", "a6", "a7",
|
||||
"a8", "a9", "a10", "a29", "a30", "a31", "a32", "a33", "a34", "a35", "a36",
|
||||
"a37", "a38", "a39", "a40", "a41", "a42", "a43", "a44", "a45", "a46",
|
||||
"a47", "a48", "a49", "a50", "a51", "a52", "a53", "a54", "a55", "a56",
|
||||
"a57", "a58", "a59", "a60", "a61", "a62", "a63", "a64", "a65", "a66",
|
||||
"a67", "a68", "a69", "a70", "a71", "a72", "a73", "a74", "a203", "a75",
|
||||
"a204", "a76", "a77", "a78", "a79", "a81", "a82", "a83", "a84", "a97",
|
||||
"a98", "a99", "a100", "", "a89", "a90", "a93", "a94", "a91", "a92", "a205",
|
||||
"a85", "a206", "a86", "a87", "a88", "a95", "a96", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "a101", "a102", "a103",
|
||||
"a104", "a106", "a107", "a108", "a112", "a111", "a110", "a109", "a120",
|
||||
"a121", "a122", "a123", "a124", "a125", "a126", "a127", "a128", "a129",
|
||||
"a130", "a131", "a132", "a133", "a134", "a135", "a136", "a137", "a138",
|
||||
"a139", "a140", "a141", "a142", "a143", "a144", "a145", "a146", "a147",
|
||||
"a148", "a149", "a150", "a151", "a152", "a153", "a154", "a155", "a156",
|
||||
"a157", "a158", "a159", "a160", "a161", "a163", "a164", "a196", "a165",
|
||||
"a192", "a166", "a167", "a168", "a169", "a170", "a171", "a172", "a173",
|
||||
"a162", "a174", "a175", "a176", "a177", "a178", "a179", "a193", "a180",
|
||||
"a199", "a181", "a200", "a182", "", "a201", "a183", "a184", "a197", "a185",
|
||||
"a194", "a198", "a186", "a195", "a187", "a188", "a189", "a190", "a191", ""];
|
||||
|
||||
function getEncoding(encodingName) {
|
||||
switch (encodingName) {
|
||||
case 'WinAnsiEncoding':
|
||||
case "WinAnsiEncoding":
|
||||
return WinAnsiEncoding;
|
||||
case 'StandardEncoding':
|
||||
case "StandardEncoding":
|
||||
return StandardEncoding;
|
||||
case 'MacRomanEncoding':
|
||||
case "MacRomanEncoding":
|
||||
return MacRomanEncoding;
|
||||
case 'SymbolSetEncoding':
|
||||
case "SymbolSetEncoding":
|
||||
return SymbolSetEncoding;
|
||||
case 'ZapfDingbatsEncoding':
|
||||
case "ZapfDingbatsEncoding":
|
||||
return ZapfDingbatsEncoding;
|
||||
case 'ExpertEncoding':
|
||||
case "ExpertEncoding":
|
||||
return ExpertEncoding;
|
||||
case 'MacExpertEncoding':
|
||||
case "MacExpertEncoding":
|
||||
return MacExpertEncoding;
|
||||
default:
|
||||
return null;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,17 +14,25 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
bytesToString, FONT_IDENTITY_MATRIX, FormatError, unreachable, warn
|
||||
} from '../shared/util';
|
||||
import { CFFParser } from './cff_parser';
|
||||
import { getGlyphsUnicode } from './glyphlist';
|
||||
import { StandardEncoding } from './encodings';
|
||||
import { Stream } from './stream';
|
||||
bytesToString,
|
||||
FONT_IDENTITY_MATRIX,
|
||||
FormatError,
|
||||
unreachable,
|
||||
warn,
|
||||
} from "../shared/util";
|
||||
import { CFFParser } from "./cff_parser";
|
||||
import { getGlyphsUnicode } from "./glyphlist";
|
||||
import { StandardEncoding } from "./encodings";
|
||||
import { Stream } from "./stream";
|
||||
|
||||
var FontRendererFactory = (function FontRendererFactoryClosure() {
|
||||
function getLong(data, offset) {
|
||||
return (data[offset] << 24) | (data[offset + 1] << 16) |
|
||||
(data[offset + 2] << 8) | data[offset + 3];
|
||||
return (
|
||||
(data[offset] << 24) |
|
||||
(data[offset + 1] << 16) |
|
||||
(data[offset + 2] << 8) |
|
||||
data[offset + 3]
|
||||
);
|
||||
}
|
||||
|
||||
function getUshort(data, offset) {
|
||||
|
@ -32,8 +40,10 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
}
|
||||
|
||||
function parseCmap(data, start, end) {
|
||||
var offset = (getUshort(data, start + 2) === 1 ?
|
||||
getLong(data, start + 8) : getLong(data, start + 16));
|
||||
var offset =
|
||||
getUshort(data, start + 2) === 1
|
||||
? getLong(data, start + 8)
|
||||
: getLong(data, start + 16);
|
||||
var format = getUshort(data, start + offset);
|
||||
var ranges, p, i;
|
||||
if (format === 4) {
|
||||
|
@ -42,7 +52,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
p = start + offset + 14;
|
||||
ranges = [];
|
||||
for (i = 0; i < segCount; i++, p += 2) {
|
||||
ranges[i] = { end: getUshort(data, p), };
|
||||
ranges[i] = { end: getUshort(data, p) };
|
||||
}
|
||||
p += 2;
|
||||
for (i = 0; i < segCount; i++, p += 2) {
|
||||
|
@ -83,13 +93,18 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
|
||||
function parseCff(data, start, end, seacAnalysisEnabled) {
|
||||
var properties = {};
|
||||
var parser = new CFFParser(new Stream(data, start, end - start),
|
||||
properties, seacAnalysisEnabled);
|
||||
var parser = new CFFParser(
|
||||
new Stream(data, start, end - start),
|
||||
properties,
|
||||
seacAnalysisEnabled
|
||||
);
|
||||
var cff = parser.parse();
|
||||
return {
|
||||
glyphs: cff.charStrings.objects,
|
||||
subrs: (cff.topDict.privateDict && cff.topDict.privateDict.subrsIndex &&
|
||||
cff.topDict.privateDict.subrsIndex.objects),
|
||||
subrs:
|
||||
cff.topDict.privateDict &&
|
||||
cff.topDict.privateDict.subrsIndex &&
|
||||
cff.topDict.privateDict.subrsIndex.objects,
|
||||
gsubrs: cff.globalSubrIndex && cff.globalSubrIndex.objects,
|
||||
isCFFCIDFont: cff.isCIDFont,
|
||||
fdSelect: cff.fdSelect,
|
||||
|
@ -102,8 +117,12 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
if (isGlyphLocationsLong) {
|
||||
itemSize = 4;
|
||||
itemDecode = function fontItemDecodeLong(data, offset) {
|
||||
return (data[offset] << 24) | (data[offset + 1] << 16) |
|
||||
(data[offset + 2] << 8) | data[offset + 3];
|
||||
return (
|
||||
(data[offset] << 24) |
|
||||
(data[offset + 1] << 16) |
|
||||
(data[offset + 2] << 8) |
|
||||
data[offset + 3]
|
||||
);
|
||||
};
|
||||
} else {
|
||||
itemSize = 2;
|
||||
|
@ -122,8 +141,10 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
}
|
||||
|
||||
function lookupCmap(ranges, unicode) {
|
||||
var code = unicode.codePointAt(0), gid = 0;
|
||||
var l = 0, r = ranges.length - 1;
|
||||
var code = unicode.codePointAt(0),
|
||||
gid = 0;
|
||||
var l = 0,
|
||||
r = ranges.length - 1;
|
||||
while (l < r) {
|
||||
var c = (l + r + 1) >> 1;
|
||||
if (code < ranges[c].start) {
|
||||
|
@ -133,8 +154,10 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
}
|
||||
}
|
||||
if (ranges[l].start <= code && code <= ranges[l].end) {
|
||||
gid = (ranges[l].idDelta + (ranges[l].ids ?
|
||||
ranges[l].ids[code - ranges[l].start] : code)) & 0xFFFF;
|
||||
gid =
|
||||
(ranges[l].idDelta +
|
||||
(ranges[l].ids ? ranges[l].ids[code - ranges[l].start] : code)) &
|
||||
0xffff;
|
||||
}
|
||||
return {
|
||||
charCode: code,
|
||||
|
@ -144,19 +167,20 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
|
||||
function compileGlyf(code, cmds, font) {
|
||||
function moveTo(x, y) {
|
||||
cmds.push({ cmd: 'moveTo', args: [x, y], });
|
||||
cmds.push({ cmd: "moveTo", args: [x, y] });
|
||||
}
|
||||
function lineTo(x, y) {
|
||||
cmds.push({ cmd: 'lineTo', args: [x, y], });
|
||||
cmds.push({ cmd: "lineTo", args: [x, y] });
|
||||
}
|
||||
function quadraticCurveTo(xa, ya, x, y) {
|
||||
cmds.push({ cmd: 'quadraticCurveTo', args: [xa, ya, x, y], });
|
||||
cmds.push({ cmd: "quadraticCurveTo", args: [xa, ya, x, y] });
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
var numberOfContours = ((code[i] << 24) | (code[i + 1] << 16)) >> 16;
|
||||
var flags;
|
||||
var x = 0, y = 0;
|
||||
var x = 0,
|
||||
y = 0;
|
||||
i += 10;
|
||||
if (numberOfContours < 0) {
|
||||
// composite glyph
|
||||
|
@ -165,29 +189,34 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
var glyphIndex = (code[i + 2] << 8) | code[i + 3];
|
||||
i += 4;
|
||||
var arg1, arg2;
|
||||
if ((flags & 0x01)) {
|
||||
if (flags & 0x01) {
|
||||
arg1 = ((code[i] << 24) | (code[i + 1] << 16)) >> 16;
|
||||
arg2 = ((code[i + 2] << 24) | (code[i + 3] << 16)) >> 16;
|
||||
i += 4;
|
||||
} else {
|
||||
arg1 = code[i++]; arg2 = code[i++];
|
||||
arg1 = code[i++];
|
||||
arg2 = code[i++];
|
||||
}
|
||||
if ((flags & 0x02)) {
|
||||
x = arg1;
|
||||
y = arg2;
|
||||
if (flags & 0x02) {
|
||||
x = arg1;
|
||||
y = arg2;
|
||||
} else {
|
||||
x = 0; y = 0; // TODO "they are points" ?
|
||||
x = 0;
|
||||
y = 0; // TODO "they are points" ?
|
||||
}
|
||||
var scaleX = 1, scaleY = 1, scale01 = 0, scale10 = 0;
|
||||
if ((flags & 0x08)) {
|
||||
scaleX =
|
||||
scaleY = ((code[i] << 24) | (code[i + 1] << 16)) / 1073741824;
|
||||
var scaleX = 1,
|
||||
scaleY = 1,
|
||||
scale01 = 0,
|
||||
scale10 = 0;
|
||||
if (flags & 0x08) {
|
||||
scaleX = scaleY =
|
||||
((code[i] << 24) | (code[i + 1] << 16)) / 1073741824;
|
||||
i += 2;
|
||||
} else if ((flags & 0x40)) {
|
||||
} else if (flags & 0x40) {
|
||||
scaleX = ((code[i] << 24) | (code[i + 1] << 16)) / 1073741824;
|
||||
scaleY = ((code[i + 2] << 24) | (code[i + 3] << 16)) / 1073741824;
|
||||
i += 4;
|
||||
} else if ((flags & 0x80)) {
|
||||
} else if (flags & 0x80) {
|
||||
scaleX = ((code[i] << 24) | (code[i + 1] << 16)) / 1073741824;
|
||||
scale01 = ((code[i + 2] << 24) | (code[i + 3] << 16)) / 1073741824;
|
||||
scale10 = ((code[i + 4] << 24) | (code[i + 5] << 16)) / 1073741824;
|
||||
|
@ -196,13 +225,15 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
}
|
||||
var subglyph = font.glyphs[glyphIndex];
|
||||
if (subglyph) {
|
||||
cmds.push({ cmd: 'save', });
|
||||
cmds.push({ cmd: 'transform',
|
||||
args: [scaleX, scale01, scale10, scaleY, x, y], });
|
||||
cmds.push({ cmd: "save" });
|
||||
cmds.push({
|
||||
cmd: "transform",
|
||||
args: [scaleX, scale01, scale10, scaleY, x, y],
|
||||
});
|
||||
compileGlyf(subglyph, cmds, font);
|
||||
cmds.push({ cmd: 'restore', });
|
||||
cmds.push({ cmd: "restore" });
|
||||
}
|
||||
} while ((flags & 0x20));
|
||||
} while (flags & 0x20);
|
||||
} else {
|
||||
// simple glyph
|
||||
var endPtsOfContours = [];
|
||||
|
@ -218,11 +249,11 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
while (points.length < numberOfPoints) {
|
||||
flags = code[i++];
|
||||
var repeat = 1;
|
||||
if ((flags & 0x08)) {
|
||||
if (flags & 0x08) {
|
||||
repeat += code[i++];
|
||||
}
|
||||
while (repeat-- > 0) {
|
||||
points.push({ flags, });
|
||||
points.push({ flags });
|
||||
}
|
||||
}
|
||||
for (j = 0; j < numberOfPoints; j++) {
|
||||
|
@ -262,9 +293,9 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
// contours might have implicit points, which is located in the middle
|
||||
// between two neighboring off-curve points
|
||||
var contour = points.slice(startPoint, endPoint + 1);
|
||||
if ((contour[0].flags & 1)) {
|
||||
if (contour[0].flags & 1) {
|
||||
contour.push(contour[0]); // using start point at the contour end
|
||||
} else if ((contour[contour.length - 1].flags & 1)) {
|
||||
} else if (contour[contour.length - 1].flags & 1) {
|
||||
// first is off-curve point, trying to use one from the end
|
||||
contour.unshift(contour[contour.length - 1]);
|
||||
} else {
|
||||
|
@ -279,16 +310,23 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
}
|
||||
moveTo(contour[0].x, contour[0].y);
|
||||
for (j = 1, jj = contour.length; j < jj; j++) {
|
||||
if ((contour[j].flags & 1)) {
|
||||
if (contour[j].flags & 1) {
|
||||
lineTo(contour[j].x, contour[j].y);
|
||||
} else if ((contour[j + 1].flags & 1)) {
|
||||
quadraticCurveTo(contour[j].x, contour[j].y,
|
||||
contour[j + 1].x, contour[j + 1].y);
|
||||
} else if (contour[j + 1].flags & 1) {
|
||||
quadraticCurveTo(
|
||||
contour[j].x,
|
||||
contour[j].y,
|
||||
contour[j + 1].x,
|
||||
contour[j + 1].y
|
||||
);
|
||||
j++;
|
||||
} else {
|
||||
quadraticCurveTo(contour[j].x, contour[j].y,
|
||||
quadraticCurveTo(
|
||||
contour[j].x,
|
||||
contour[j].y,
|
||||
(contour[j].x + contour[j + 1].x) / 2,
|
||||
(contour[j].y + contour[j + 1].y) / 2);
|
||||
(contour[j].y + contour[j + 1].y) / 2
|
||||
);
|
||||
}
|
||||
}
|
||||
startPoint = endPoint + 1;
|
||||
|
@ -298,17 +336,18 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
|
||||
function compileCharString(code, cmds, font, glyphId) {
|
||||
var stack = [];
|
||||
var x = 0, y = 0;
|
||||
var x = 0,
|
||||
y = 0;
|
||||
var stems = 0;
|
||||
|
||||
function moveTo(x, y) {
|
||||
cmds.push({ cmd: 'moveTo', args: [x, y], });
|
||||
cmds.push({ cmd: "moveTo", args: [x, y] });
|
||||
}
|
||||
function lineTo(x, y) {
|
||||
cmds.push({ cmd: 'lineTo', args: [x, y], });
|
||||
cmds.push({ cmd: "lineTo", args: [x, y] });
|
||||
}
|
||||
function bezierCurveTo(x1, y1, x2, y2, x, y) {
|
||||
cmds.push({ cmd: 'bezierCurveTo', args: [x1, y1, x2, y2, x, y], });
|
||||
cmds.push({ cmd: "bezierCurveTo", args: [x1, y1, x2, y2, x, y] });
|
||||
}
|
||||
|
||||
function parse(code) {
|
||||
|
@ -362,9 +401,12 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
break;
|
||||
case 8: // rrcurveto
|
||||
while (stack.length > 0) {
|
||||
xa = x + stack.shift(); ya = y + stack.shift();
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
x = xb + stack.shift(); y = yb + stack.shift();
|
||||
xa = x + stack.shift();
|
||||
ya = y + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
x = xb + stack.shift();
|
||||
y = yb + stack.shift();
|
||||
bezierCurveTo(xa, ya, xb, yb, x, y);
|
||||
}
|
||||
break;
|
||||
|
@ -374,19 +416,19 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
if (font.isCFFCIDFont) {
|
||||
let fdIndex = font.fdSelect.getFDIndex(glyphId);
|
||||
if (fdIndex >= 0 && fdIndex < font.fdArray.length) {
|
||||
let fontDict = font.fdArray[fdIndex], subrs;
|
||||
let fontDict = font.fdArray[fdIndex],
|
||||
subrs;
|
||||
if (fontDict.privateDict && fontDict.privateDict.subrsIndex) {
|
||||
subrs = fontDict.privateDict.subrsIndex.objects;
|
||||
}
|
||||
if (subrs) {
|
||||
let numSubrs = subrs.length;
|
||||
// Add subroutine bias.
|
||||
n += numSubrs < 1240 ? 107 :
|
||||
(numSubrs < 33900 ? 1131 : 32768);
|
||||
n += numSubrs < 1240 ? 107 : numSubrs < 33900 ? 1131 : 32768;
|
||||
subrCode = subrs[n];
|
||||
}
|
||||
} else {
|
||||
warn('Invalid fd index for glyph index.');
|
||||
warn("Invalid fd index for glyph index.");
|
||||
}
|
||||
} else {
|
||||
subrCode = font.subrs[n + font.subrsBias];
|
||||
|
@ -402,7 +444,8 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
switch (v) {
|
||||
case 34: // flex
|
||||
xa = x + stack.shift();
|
||||
xb = xa + stack.shift(); y1 = y + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
y1 = y + stack.shift();
|
||||
x = xb + stack.shift();
|
||||
bezierCurveTo(xa, y, xb, y1, x, y1);
|
||||
xa = x + stack.shift();
|
||||
|
@ -411,35 +454,51 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
bezierCurveTo(xa, y1, xb, y, x, y);
|
||||
break;
|
||||
case 35: // flex
|
||||
xa = x + stack.shift(); ya = y + stack.shift();
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
x = xb + stack.shift(); y = yb + stack.shift();
|
||||
xa = x + stack.shift();
|
||||
ya = y + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
x = xb + stack.shift();
|
||||
y = yb + stack.shift();
|
||||
bezierCurveTo(xa, ya, xb, yb, x, y);
|
||||
xa = x + stack.shift(); ya = y + stack.shift();
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
x = xb + stack.shift(); y = yb + stack.shift();
|
||||
xa = x + stack.shift();
|
||||
ya = y + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
x = xb + stack.shift();
|
||||
y = yb + stack.shift();
|
||||
bezierCurveTo(xa, ya, xb, yb, x, y);
|
||||
stack.pop(); // fd
|
||||
break;
|
||||
case 36: // hflex1
|
||||
xa = x + stack.shift(); y1 = y + stack.shift();
|
||||
xb = xa + stack.shift(); y2 = y1 + stack.shift();
|
||||
xa = x + stack.shift();
|
||||
y1 = y + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
y2 = y1 + stack.shift();
|
||||
x = xb + stack.shift();
|
||||
bezierCurveTo(xa, y1, xb, y2, x, y2);
|
||||
xa = x + stack.shift();
|
||||
xb = xa + stack.shift(); y3 = y2 + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
y3 = y2 + stack.shift();
|
||||
x = xb + stack.shift();
|
||||
bezierCurveTo(xa, y2, xb, y3, x, y);
|
||||
break;
|
||||
case 37: // flex1
|
||||
var x0 = x, y0 = y;
|
||||
xa = x + stack.shift(); ya = y + stack.shift();
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
x = xb + stack.shift(); y = yb + stack.shift();
|
||||
var x0 = x,
|
||||
y0 = y;
|
||||
xa = x + stack.shift();
|
||||
ya = y + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
x = xb + stack.shift();
|
||||
y = yb + stack.shift();
|
||||
bezierCurveTo(xa, ya, xb, yb, x, y);
|
||||
xa = x + stack.shift(); ya = y + stack.shift();
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
x = xb; y = yb;
|
||||
xa = x + stack.shift();
|
||||
ya = y + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
x = xb;
|
||||
y = yb;
|
||||
if (Math.abs(x - x0) > Math.abs(y - y0)) {
|
||||
x += stack.shift();
|
||||
} else {
|
||||
|
@ -457,18 +516,30 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
var bchar = stack.pop();
|
||||
y = stack.pop();
|
||||
x = stack.pop();
|
||||
cmds.push({ cmd: 'save', });
|
||||
cmds.push({ cmd: 'translate', args: [x, y], });
|
||||
var cmap = lookupCmap(font.cmap, String.fromCharCode(
|
||||
font.glyphNameMap[StandardEncoding[achar]]));
|
||||
compileCharString(font.glyphs[cmap.glyphId], cmds, font,
|
||||
cmap.glyphId);
|
||||
cmds.push({ cmd: 'restore', });
|
||||
cmds.push({ cmd: "save" });
|
||||
cmds.push({ cmd: "translate", args: [x, y] });
|
||||
var cmap = lookupCmap(
|
||||
font.cmap,
|
||||
String.fromCharCode(font.glyphNameMap[StandardEncoding[achar]])
|
||||
);
|
||||
compileCharString(
|
||||
font.glyphs[cmap.glyphId],
|
||||
cmds,
|
||||
font,
|
||||
cmap.glyphId
|
||||
);
|
||||
cmds.push({ cmd: "restore" });
|
||||
|
||||
cmap = lookupCmap(font.cmap, String.fromCharCode(
|
||||
font.glyphNameMap[StandardEncoding[bchar]]));
|
||||
compileCharString(font.glyphs[cmap.glyphId], cmds, font,
|
||||
cmap.glyphId);
|
||||
cmap = lookupCmap(
|
||||
font.cmap,
|
||||
String.fromCharCode(font.glyphNameMap[StandardEncoding[bchar]])
|
||||
);
|
||||
compileCharString(
|
||||
font.glyphs[cmap.glyphId],
|
||||
cmds,
|
||||
font,
|
||||
cmap.glyphId
|
||||
);
|
||||
}
|
||||
return;
|
||||
case 18: // hstemhm
|
||||
|
@ -502,9 +573,12 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
break;
|
||||
case 24: // rcurveline
|
||||
while (stack.length > 2) {
|
||||
xa = x + stack.shift(); ya = y + stack.shift();
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
x = xb + stack.shift(); y = yb + stack.shift();
|
||||
xa = x + stack.shift();
|
||||
ya = y + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
x = xb + stack.shift();
|
||||
y = yb + stack.shift();
|
||||
bezierCurveTo(xa, ya, xb, yb, x, y);
|
||||
}
|
||||
x += stack.shift();
|
||||
|
@ -517,9 +591,12 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
y += stack.shift();
|
||||
lineTo(x, y);
|
||||
}
|
||||
xa = x + stack.shift(); ya = y + stack.shift();
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
x = xb + stack.shift(); y = yb + stack.shift();
|
||||
xa = x + stack.shift();
|
||||
ya = y + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
x = xb + stack.shift();
|
||||
y = yb + stack.shift();
|
||||
bezierCurveTo(xa, ya, xb, yb, x, y);
|
||||
break;
|
||||
case 26: // vvcurveto
|
||||
|
@ -527,9 +604,12 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
x += stack.shift();
|
||||
}
|
||||
while (stack.length > 0) {
|
||||
xa = x; ya = y + stack.shift();
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
x = xb; y = yb + stack.shift();
|
||||
xa = x;
|
||||
ya = y + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
x = xb;
|
||||
y = yb + stack.shift();
|
||||
bezierCurveTo(xa, ya, xb, yb, x, y);
|
||||
}
|
||||
break;
|
||||
|
@ -538,9 +618,12 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
y += stack.shift();
|
||||
}
|
||||
while (stack.length > 0) {
|
||||
xa = x + stack.shift(); ya = y;
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
x = xb + stack.shift(); y = yb;
|
||||
xa = x + stack.shift();
|
||||
ya = y;
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
x = xb + stack.shift();
|
||||
y = yb;
|
||||
bezierCurveTo(xa, ya, xb, yb, x, y);
|
||||
}
|
||||
break;
|
||||
|
@ -557,8 +640,10 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
break;
|
||||
case 30: // vhcurveto
|
||||
while (stack.length > 0) {
|
||||
xa = x; ya = y + stack.shift();
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
xa = x;
|
||||
ya = y + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
x = xb + stack.shift();
|
||||
y = yb + (stack.length === 1 ? stack.shift() : 0);
|
||||
bezierCurveTo(xa, ya, xb, yb, x, y);
|
||||
|
@ -566,8 +651,10 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
break;
|
||||
}
|
||||
|
||||
xa = x + stack.shift(); ya = y;
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
xa = x + stack.shift();
|
||||
ya = y;
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
y = yb + stack.shift();
|
||||
x = xb + (stack.length === 1 ? stack.shift() : 0);
|
||||
bezierCurveTo(xa, ya, xb, yb, x, y);
|
||||
|
@ -575,8 +662,10 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
break;
|
||||
case 31: // hvcurveto
|
||||
while (stack.length > 0) {
|
||||
xa = x + stack.shift(); ya = y;
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
xa = x + stack.shift();
|
||||
ya = y;
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
y = yb + stack.shift();
|
||||
x = xb + (stack.length === 1 ? stack.shift() : 0);
|
||||
bezierCurveTo(xa, ya, xb, yb, x, y);
|
||||
|
@ -584,8 +673,10 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
break;
|
||||
}
|
||||
|
||||
xa = x; ya = y + stack.shift();
|
||||
xb = xa + stack.shift(); yb = ya + stack.shift();
|
||||
xa = x;
|
||||
ya = y + stack.shift();
|
||||
xb = xa + stack.shift();
|
||||
yb = ya + stack.shift();
|
||||
x = xb + stack.shift();
|
||||
y = yb + (stack.length === 1 ? stack.shift() : 0);
|
||||
bezierCurveTo(xa, ya, xb, yb, x, y);
|
||||
|
@ -602,8 +693,13 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
} else if (v < 255) {
|
||||
stack.push(-(v - 251) * 256 - code[i++] - 108);
|
||||
} else {
|
||||
stack.push(((code[i] << 24) | (code[i + 1] << 16) |
|
||||
(code[i + 2] << 8) | code[i + 3]) / 65536);
|
||||
stack.push(
|
||||
((code[i] << 24) |
|
||||
(code[i + 1] << 16) |
|
||||
(code[i + 2] << 8) |
|
||||
code[i + 3]) /
|
||||
65536
|
||||
);
|
||||
i += 4;
|
||||
}
|
||||
break;
|
||||
|
@ -621,7 +717,7 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
class CompiledFont {
|
||||
constructor(fontMatrix) {
|
||||
if (this.constructor === CompiledFont) {
|
||||
unreachable('Cannot initialize CompiledFont.');
|
||||
unreachable("Cannot initialize CompiledFont.");
|
||||
}
|
||||
this.fontMatrix = fontMatrix;
|
||||
|
||||
|
@ -654,32 +750,34 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
let fdIndex = this.fdSelect.getFDIndex(glyphId);
|
||||
if (fdIndex >= 0 && fdIndex < this.fdArray.length) {
|
||||
let fontDict = this.fdArray[fdIndex];
|
||||
fontMatrix = fontDict.getByName('FontMatrix') || FONT_IDENTITY_MATRIX;
|
||||
fontMatrix = fontDict.getByName("FontMatrix") || FONT_IDENTITY_MATRIX;
|
||||
} else {
|
||||
warn('Invalid fd index for glyph index.');
|
||||
warn("Invalid fd index for glyph index.");
|
||||
}
|
||||
}
|
||||
|
||||
const cmds = [];
|
||||
cmds.push({ cmd: 'save', });
|
||||
cmds.push({ cmd: 'transform', args: fontMatrix.slice(), });
|
||||
cmds.push({ cmd: 'scale', args: ['size', '-size'], });
|
||||
cmds.push({ cmd: "save" });
|
||||
cmds.push({ cmd: "transform", args: fontMatrix.slice() });
|
||||
cmds.push({ cmd: "scale", args: ["size", "-size"] });
|
||||
|
||||
this.compileGlyphImpl(code, cmds, glyphId);
|
||||
|
||||
cmds.push({ cmd: 'restore', });
|
||||
cmds.push({ cmd: "restore" });
|
||||
|
||||
return cmds;
|
||||
}
|
||||
|
||||
compileGlyphImpl() {
|
||||
unreachable('Children classes should implement this.');
|
||||
unreachable("Children classes should implement this.");
|
||||
}
|
||||
|
||||
hasBuiltPath(unicode) {
|
||||
const cmap = lookupCmap(this.cmap, unicode);
|
||||
return (this.compiledGlyphs[cmap.glyphId] !== undefined &&
|
||||
this.compiledCharCodeToGlyphId[cmap.charCode] !== undefined);
|
||||
return (
|
||||
this.compiledGlyphs[cmap.glyphId] !== undefined &&
|
||||
this.compiledCharCodeToGlyphId[cmap.charCode] !== undefined
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -706,10 +804,18 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
this.cmap = cmap;
|
||||
this.glyphNameMap = glyphNameMap || getGlyphsUnicode();
|
||||
|
||||
this.gsubrsBias = (this.gsubrs.length < 1240 ?
|
||||
107 : (this.gsubrs.length < 33900 ? 1131 : 32768));
|
||||
this.subrsBias = (this.subrs.length < 1240 ?
|
||||
107 : (this.subrs.length < 33900 ? 1131 : 32768));
|
||||
this.gsubrsBias =
|
||||
this.gsubrs.length < 1240
|
||||
? 107
|
||||
: this.gsubrs.length < 33900
|
||||
? 1131
|
||||
: 32768;
|
||||
this.subrsBias =
|
||||
this.subrs.length < 1240
|
||||
? 107
|
||||
: this.subrs.length < 33900
|
||||
? 1131
|
||||
: 32768;
|
||||
|
||||
this.isCFFCIDFont = cffInfo.isCFFCIDFont;
|
||||
this.fdSelect = cffInfo.fdSelect;
|
||||
|
@ -731,36 +837,38 @@ var FontRendererFactory = (function FontRendererFactoryClosure() {
|
|||
var offset = getLong(data, p + 8);
|
||||
var length = getLong(data, p + 12);
|
||||
switch (tag) {
|
||||
case 'cmap':
|
||||
case "cmap":
|
||||
cmap = parseCmap(data, offset, offset + length);
|
||||
break;
|
||||
case 'glyf':
|
||||
case "glyf":
|
||||
glyf = data.subarray(offset, offset + length);
|
||||
break;
|
||||
case 'loca':
|
||||
case "loca":
|
||||
loca = data.subarray(offset, offset + length);
|
||||
break;
|
||||
case 'head':
|
||||
case "head":
|
||||
unitsPerEm = getUshort(data, offset + 18);
|
||||
indexToLocFormat = getUshort(data, offset + 50);
|
||||
break;
|
||||
case 'CFF ':
|
||||
case "CFF ":
|
||||
cff = parseCff(data, offset, offset + length, seacAnalysisEnabled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (glyf) {
|
||||
var fontMatrix = (!unitsPerEm ? font.fontMatrix :
|
||||
[1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0]);
|
||||
var fontMatrix = !unitsPerEm
|
||||
? font.fontMatrix
|
||||
: [1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0];
|
||||
return new TrueTypeCompiled(
|
||||
parseGlyfTable(glyf, loca, indexToLocFormat), cmap, fontMatrix);
|
||||
parseGlyfTable(glyf, loca, indexToLocFormat),
|
||||
cmap,
|
||||
fontMatrix
|
||||
);
|
||||
}
|
||||
return new Type2Compiled(cff, cmap, font.fontMatrix, font.glyphNameMap);
|
||||
},
|
||||
};
|
||||
})();
|
||||
|
||||
export {
|
||||
FontRendererFactory,
|
||||
};
|
||||
export { FontRendererFactory };
|
||||
|
|
1895
src/core/fonts.js
1895
src/core/fonts.js
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -13,12 +13,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { assert, FormatError, ImageKind, info, warn } from '../shared/util';
|
||||
import { isName, isStream, Name } from './primitives';
|
||||
import { ColorSpace } from './colorspace';
|
||||
import { DecodeStream } from './stream';
|
||||
import { JpegStream } from './jpeg_stream';
|
||||
import { JpxImage } from './jpx';
|
||||
import { assert, FormatError, ImageKind, info, warn } from "../shared/util";
|
||||
import { isName, isStream, Name } from "./primitives";
|
||||
import { ColorSpace } from "./colorspace";
|
||||
import { DecodeStream } from "./stream";
|
||||
import { JpegStream } from "./jpeg_stream";
|
||||
import { JpxImage } from "./jpx";
|
||||
|
||||
var PDFImage = (function PDFImageClosure() {
|
||||
/**
|
||||
|
@ -27,9 +27,11 @@ var PDFImage = (function PDFImageClosure() {
|
|||
*/
|
||||
function handleImageData(image, nativeDecoder) {
|
||||
if (nativeDecoder && nativeDecoder.canDecode(image)) {
|
||||
return nativeDecoder.decode(image).catch((reason) => {
|
||||
warn('Native image decoding failed -- trying to recover: ' +
|
||||
(reason && reason.message));
|
||||
return nativeDecoder.decode(image).catch(reason => {
|
||||
warn(
|
||||
"Native image decoding failed -- trying to recover: " +
|
||||
(reason && reason.message)
|
||||
);
|
||||
return image;
|
||||
});
|
||||
}
|
||||
|
@ -43,7 +45,7 @@ var PDFImage = (function PDFImageClosure() {
|
|||
function decodeAndClamp(value, addend, coefficient, max) {
|
||||
value = addend + value * coefficient;
|
||||
// Clamp the value to the range
|
||||
return (value < 0 ? 0 : (value > max ? max : value));
|
||||
return value < 0 ? 0 : value > max ? max : value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,11 +60,19 @@ var PDFImage = (function PDFImageClosure() {
|
|||
*/
|
||||
function resizeImageMask(src, bpc, w1, h1, w2, h2) {
|
||||
var length = w2 * h2;
|
||||
var dest = (bpc <= 8 ? new Uint8Array(length) :
|
||||
(bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length)));
|
||||
var dest =
|
||||
bpc <= 8
|
||||
? new Uint8Array(length)
|
||||
: bpc <= 16
|
||||
? new Uint16Array(length)
|
||||
: new Uint32Array(length);
|
||||
var xRatio = w1 / w2;
|
||||
var yRatio = h1 / h2;
|
||||
var i, j, py, newIndex = 0, oldIndex;
|
||||
var i,
|
||||
j,
|
||||
py,
|
||||
newIndex = 0,
|
||||
oldIndex;
|
||||
var xScaled = new Uint16Array(w2);
|
||||
var w1Scanline = w1;
|
||||
|
||||
|
@ -79,15 +89,23 @@ var PDFImage = (function PDFImageClosure() {
|
|||
return dest;
|
||||
}
|
||||
|
||||
function PDFImage({ xref, res, image, isInline = false, smask = null,
|
||||
mask = null, isMask = false, pdfFunctionFactory, }) {
|
||||
function PDFImage({
|
||||
xref,
|
||||
res,
|
||||
image,
|
||||
isInline = false,
|
||||
smask = null,
|
||||
mask = null,
|
||||
isMask = false,
|
||||
pdfFunctionFactory,
|
||||
}) {
|
||||
this.image = image;
|
||||
var dict = image.dict;
|
||||
|
||||
const filter = dict.get('Filter');
|
||||
const filter = dict.get("Filter");
|
||||
if (isName(filter)) {
|
||||
switch (filter.name) {
|
||||
case 'JPXDecode':
|
||||
case "JPXDecode":
|
||||
var jpxImage = new JpxImage();
|
||||
jpxImage.parseImageProperties(image.stream);
|
||||
image.stream.reset();
|
||||
|
@ -97,7 +115,7 @@ var PDFImage = (function PDFImageClosure() {
|
|||
image.bitsPerComponent = jpxImage.bitsPerComponent;
|
||||
image.numComps = jpxImage.componentsCount;
|
||||
break;
|
||||
case 'JBIG2Decode':
|
||||
case "JBIG2Decode":
|
||||
image.bitsPerComponent = 1;
|
||||
image.numComps = 1;
|
||||
break;
|
||||
|
@ -105,86 +123,103 @@ var PDFImage = (function PDFImageClosure() {
|
|||
}
|
||||
// TODO cache rendered images?
|
||||
|
||||
let width = dict.get('Width', 'W');
|
||||
let height = dict.get('Height', 'H');
|
||||
let width = dict.get("Width", "W");
|
||||
let height = dict.get("Height", "H");
|
||||
|
||||
if ((Number.isInteger(image.width) && image.width > 0) &&
|
||||
(Number.isInteger(image.height) && image.height > 0) &&
|
||||
(image.width !== width || image.height !== height)) {
|
||||
warn('PDFImage - using the Width/Height of the image data, ' +
|
||||
'rather than the image dictionary.');
|
||||
if (
|
||||
Number.isInteger(image.width) &&
|
||||
image.width > 0 &&
|
||||
Number.isInteger(image.height) &&
|
||||
image.height > 0 &&
|
||||
(image.width !== width || image.height !== height)
|
||||
) {
|
||||
warn(
|
||||
"PDFImage - using the Width/Height of the image data, " +
|
||||
"rather than the image dictionary."
|
||||
);
|
||||
width = image.width;
|
||||
height = image.height;
|
||||
}
|
||||
if (width < 1 || height < 1) {
|
||||
throw new FormatError(`Invalid image width: ${width} or ` +
|
||||
`height: ${height}`);
|
||||
throw new FormatError(
|
||||
`Invalid image width: ${width} or ` + `height: ${height}`
|
||||
);
|
||||
}
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.interpolate = dict.get('Interpolate', 'I') || false;
|
||||
this.imageMask = dict.get('ImageMask', 'IM') || false;
|
||||
this.matte = dict.get('Matte') || false;
|
||||
this.interpolate = dict.get("Interpolate", "I") || false;
|
||||
this.imageMask = dict.get("ImageMask", "IM") || false;
|
||||
this.matte = dict.get("Matte") || false;
|
||||
|
||||
var bitsPerComponent = image.bitsPerComponent;
|
||||
if (!bitsPerComponent) {
|
||||
bitsPerComponent = dict.get('BitsPerComponent', 'BPC');
|
||||
bitsPerComponent = dict.get("BitsPerComponent", "BPC");
|
||||
if (!bitsPerComponent) {
|
||||
if (this.imageMask) {
|
||||
bitsPerComponent = 1;
|
||||
} else {
|
||||
throw new FormatError(
|
||||
`Bits per component missing in image: ${this.imageMask}`);
|
||||
`Bits per component missing in image: ${this.imageMask}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.bpc = bitsPerComponent;
|
||||
|
||||
if (!this.imageMask) {
|
||||
var colorSpace = dict.get('ColorSpace', 'CS');
|
||||
var colorSpace = dict.get("ColorSpace", "CS");
|
||||
if (!colorSpace) {
|
||||
info('JPX images (which do not require color spaces)');
|
||||
info("JPX images (which do not require color spaces)");
|
||||
switch (image.numComps) {
|
||||
case 1:
|
||||
colorSpace = Name.get('DeviceGray');
|
||||
colorSpace = Name.get("DeviceGray");
|
||||
break;
|
||||
case 3:
|
||||
colorSpace = Name.get('DeviceRGB');
|
||||
colorSpace = Name.get("DeviceRGB");
|
||||
break;
|
||||
case 4:
|
||||
colorSpace = Name.get('DeviceCMYK');
|
||||
colorSpace = Name.get("DeviceCMYK");
|
||||
break;
|
||||
default:
|
||||
throw new Error(`JPX images with ${image.numComps} ` +
|
||||
'color components not supported.');
|
||||
throw new Error(
|
||||
`JPX images with ${image.numComps} ` +
|
||||
"color components not supported."
|
||||
);
|
||||
}
|
||||
}
|
||||
let resources = isInline ? res : null;
|
||||
this.colorSpace = ColorSpace.parse(colorSpace, xref, resources,
|
||||
pdfFunctionFactory);
|
||||
this.colorSpace = ColorSpace.parse(
|
||||
colorSpace,
|
||||
xref,
|
||||
resources,
|
||||
pdfFunctionFactory
|
||||
);
|
||||
this.numComps = this.colorSpace.numComps;
|
||||
}
|
||||
|
||||
this.decode = dict.getArray('Decode', 'D');
|
||||
this.decode = dict.getArray("Decode", "D");
|
||||
this.needsDecode = false;
|
||||
if (this.decode &&
|
||||
((this.colorSpace &&
|
||||
!this.colorSpace.isDefaultDecode(this.decode, bitsPerComponent)) ||
|
||||
(isMask &&
|
||||
!ColorSpace.isDefaultDecode(this.decode, /* numComps = */ 1)))) {
|
||||
if (
|
||||
this.decode &&
|
||||
((this.colorSpace &&
|
||||
!this.colorSpace.isDefaultDecode(this.decode, bitsPerComponent)) ||
|
||||
(isMask &&
|
||||
!ColorSpace.isDefaultDecode(this.decode, /* numComps = */ 1)))
|
||||
) {
|
||||
this.needsDecode = true;
|
||||
// Do some preprocessing to avoid more math.
|
||||
var max = (1 << bitsPerComponent) - 1;
|
||||
this.decodeCoefficients = [];
|
||||
this.decodeAddends = [];
|
||||
const isIndexed = this.colorSpace && this.colorSpace.name === 'Indexed';
|
||||
const isIndexed = this.colorSpace && this.colorSpace.name === "Indexed";
|
||||
for (var i = 0, j = 0; i < this.decode.length; i += 2, ++j) {
|
||||
var dmin = this.decode[i];
|
||||
var dmax = this.decode[i + 1];
|
||||
this.decodeCoefficients[j] = isIndexed ? ((dmax - dmin) / max) :
|
||||
(dmax - dmin);
|
||||
this.decodeAddends[j] = isIndexed ? dmin : (max * dmin);
|
||||
this.decodeCoefficients[j] = isIndexed
|
||||
? (dmax - dmin) / max
|
||||
: dmax - dmin;
|
||||
this.decodeAddends[j] = isIndexed ? dmin : max * dmin;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,9 +233,10 @@ var PDFImage = (function PDFImageClosure() {
|
|||
});
|
||||
} else if (mask) {
|
||||
if (isStream(mask)) {
|
||||
var maskDict = mask.dict, imageMask = maskDict.get('ImageMask', 'IM');
|
||||
var maskDict = mask.dict,
|
||||
imageMask = maskDict.get("ImageMask", "IM");
|
||||
if (!imageMask) {
|
||||
warn('Ignoring /Mask in image without /ImageMask.');
|
||||
warn("Ignoring /Mask in image without /ImageMask.");
|
||||
} else {
|
||||
this.mask = new PDFImage({
|
||||
xref,
|
||||
|
@ -221,15 +257,21 @@ var PDFImage = (function PDFImageClosure() {
|
|||
* Handles processing of image data and returns the Promise that is resolved
|
||||
* with a PDFImage when the image is ready to be used.
|
||||
*/
|
||||
PDFImage.buildImage = function({ handler, xref, res, image, isInline = false,
|
||||
nativeDecoder = null,
|
||||
pdfFunctionFactory, }) {
|
||||
PDFImage.buildImage = function({
|
||||
handler,
|
||||
xref,
|
||||
res,
|
||||
image,
|
||||
isInline = false,
|
||||
nativeDecoder = null,
|
||||
pdfFunctionFactory,
|
||||
}) {
|
||||
var imagePromise = handleImageData(image, nativeDecoder);
|
||||
var smaskPromise;
|
||||
var maskPromise;
|
||||
|
||||
var smask = image.dict.get('SMask');
|
||||
var mask = image.dict.get('Mask');
|
||||
var smask = image.dict.get("SMask");
|
||||
var mask = image.dict.get("Mask");
|
||||
|
||||
if (smask) {
|
||||
smaskPromise = handleImageData(smask, nativeDecoder);
|
||||
|
@ -242,7 +284,7 @@ var PDFImage = (function PDFImageClosure() {
|
|||
} else if (Array.isArray(mask)) {
|
||||
maskPromise = Promise.resolve(mask);
|
||||
} else {
|
||||
warn('Unsupported mask format.');
|
||||
warn("Unsupported mask format.");
|
||||
maskPromise = Promise.resolve(null);
|
||||
}
|
||||
} else {
|
||||
|
@ -260,15 +302,25 @@ var PDFImage = (function PDFImageClosure() {
|
|||
mask: maskData,
|
||||
pdfFunctionFactory,
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
PDFImage.createMask = function({ imgArray, width, height,
|
||||
imageIsFromDecodeStream, inverseDecode, }) {
|
||||
if (typeof PDFJSDev === 'undefined' ||
|
||||
PDFJSDev.test('!PRODUCTION || TESTING')) {
|
||||
assert(imgArray instanceof Uint8ClampedArray,
|
||||
'PDFImage.createMask: Unsupported "imgArray" type.');
|
||||
PDFImage.createMask = function({
|
||||
imgArray,
|
||||
width,
|
||||
height,
|
||||
imageIsFromDecodeStream,
|
||||
inverseDecode,
|
||||
}) {
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(
|
||||
imgArray instanceof Uint8ClampedArray,
|
||||
'PDFImage.createMask: Unsupported "imgArray" type.'
|
||||
);
|
||||
}
|
||||
// |imgArray| might not contain full data for every pixel of the mask, so
|
||||
// we need to distinguish between |computedLength| and |actualLength|.
|
||||
|
@ -301,24 +353,28 @@ var PDFImage = (function PDFImageClosure() {
|
|||
// in this thread can be relying on its contents.
|
||||
if (inverseDecode) {
|
||||
for (i = 0; i < actualLength; i++) {
|
||||
data[i] ^= 0xFF;
|
||||
data[i] ^= 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
return { data, width, height, };
|
||||
return { data, width, height };
|
||||
};
|
||||
|
||||
PDFImage.prototype = {
|
||||
get drawWidth() {
|
||||
return Math.max(this.width,
|
||||
this.smask && this.smask.width || 0,
|
||||
this.mask && this.mask.width || 0);
|
||||
return Math.max(
|
||||
this.width,
|
||||
(this.smask && this.smask.width) || 0,
|
||||
(this.mask && this.mask.width) || 0
|
||||
);
|
||||
},
|
||||
|
||||
get drawHeight() {
|
||||
return Math.max(this.height,
|
||||
this.smask && this.smask.height || 0,
|
||||
this.mask && this.mask.height || 0);
|
||||
return Math.max(
|
||||
this.height,
|
||||
(this.smask && this.smask.height) || 0,
|
||||
(this.mask && this.mask.height) || 0
|
||||
);
|
||||
},
|
||||
|
||||
decodeBuffer(buffer) {
|
||||
|
@ -333,15 +389,19 @@ var PDFImage = (function PDFImageClosure() {
|
|||
if (bpc === 1) {
|
||||
// If the buffer needed decode that means it just needs to be inverted.
|
||||
for (i = 0, ii = buffer.length; i < ii; i++) {
|
||||
buffer[i] = +!(buffer[i]);
|
||||
buffer[i] = +!buffer[i];
|
||||
}
|
||||
return;
|
||||
}
|
||||
var index = 0;
|
||||
for (i = 0, ii = this.width * this.height; i < ii; i++) {
|
||||
for (var j = 0; j < numComps; j++) {
|
||||
buffer[index] = decodeAndClamp(buffer[index], decodeAddends[j],
|
||||
decodeCoefficients[j], max);
|
||||
buffer[index] = decodeAndClamp(
|
||||
buffer[index],
|
||||
decodeAddends[j],
|
||||
decodeCoefficients[j],
|
||||
max
|
||||
);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
@ -361,12 +421,18 @@ var PDFImage = (function PDFImageClosure() {
|
|||
|
||||
var length = width * height * numComps;
|
||||
var bufferPos = 0;
|
||||
var output = (bpc <= 8 ? new Uint8Array(length) :
|
||||
(bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length)));
|
||||
var output =
|
||||
bpc <= 8
|
||||
? new Uint8Array(length)
|
||||
: bpc <= 16
|
||||
? new Uint16Array(length)
|
||||
: new Uint32Array(length);
|
||||
var rowComps = width * numComps;
|
||||
|
||||
var max = (1 << bpc) - 1;
|
||||
var i = 0, ii, buf;
|
||||
var i = 0,
|
||||
ii,
|
||||
buf;
|
||||
|
||||
if (bpc === 1) {
|
||||
// Optimization for reading 1 bpc images.
|
||||
|
@ -416,7 +482,7 @@ var PDFImage = (function PDFImageClosure() {
|
|||
|
||||
var remainingBits = bits - bpc;
|
||||
var value = buf >> remainingBits;
|
||||
output[i] = (value < 0 ? 0 : (value > max ? max : value));
|
||||
output[i] = value < 0 ? 0 : value > max ? max : value;
|
||||
buf = buf & ((1 << remainingBits) - 1);
|
||||
bits = remainingBits;
|
||||
}
|
||||
|
@ -425,10 +491,14 @@ var PDFImage = (function PDFImageClosure() {
|
|||
},
|
||||
|
||||
fillOpacity(rgbaBuf, width, height, actualHeight, image) {
|
||||
if (typeof PDFJSDev === 'undefined' ||
|
||||
PDFJSDev.test('!PRODUCTION || TESTING')) {
|
||||
assert(rgbaBuf instanceof Uint8ClampedArray,
|
||||
'PDFImage.fillOpacity: Unsupported "rgbaBuf" type.');
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(
|
||||
rgbaBuf instanceof Uint8ClampedArray,
|
||||
'PDFImage.fillOpacity: Unsupported "rgbaBuf" type.'
|
||||
);
|
||||
}
|
||||
var smask = this.smask;
|
||||
var mask = this.mask;
|
||||
|
@ -440,8 +510,14 @@ var PDFImage = (function PDFImageClosure() {
|
|||
alphaBuf = new Uint8ClampedArray(sw * sh);
|
||||
smask.fillGrayBuffer(alphaBuf);
|
||||
if (sw !== width || sh !== height) {
|
||||
alphaBuf = resizeImageMask(alphaBuf, smask.bpc, sw, sh,
|
||||
width, height);
|
||||
alphaBuf = resizeImageMask(
|
||||
alphaBuf,
|
||||
smask.bpc,
|
||||
sw,
|
||||
sh,
|
||||
width,
|
||||
height
|
||||
);
|
||||
}
|
||||
} else if (mask) {
|
||||
if (mask instanceof PDFImage) {
|
||||
|
@ -457,8 +533,14 @@ var PDFImage = (function PDFImageClosure() {
|
|||
}
|
||||
|
||||
if (sw !== width || sh !== height) {
|
||||
alphaBuf = resizeImageMask(alphaBuf, mask.bpc, sw, sh,
|
||||
width, height);
|
||||
alphaBuf = resizeImageMask(
|
||||
alphaBuf,
|
||||
mask.bpc,
|
||||
sw,
|
||||
sh,
|
||||
width,
|
||||
height
|
||||
);
|
||||
}
|
||||
} else if (Array.isArray(mask)) {
|
||||
// Color key mask: if any of the components are outside the range
|
||||
|
@ -479,7 +561,7 @@ var PDFImage = (function PDFImageClosure() {
|
|||
alphaBuf[i] = opacity;
|
||||
}
|
||||
} else {
|
||||
throw new FormatError('Unknown mask format.');
|
||||
throw new FormatError("Unknown mask format.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -496,10 +578,14 @@ var PDFImage = (function PDFImageClosure() {
|
|||
},
|
||||
|
||||
undoPreblend(buffer, width, height) {
|
||||
if (typeof PDFJSDev === 'undefined' ||
|
||||
PDFJSDev.test('!PRODUCTION || TESTING')) {
|
||||
assert(buffer instanceof Uint8ClampedArray,
|
||||
'PDFImage.undoPreblend: Unsupported "buffer" type.');
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(
|
||||
buffer instanceof Uint8ClampedArray,
|
||||
'PDFImage.undoPreblend: Unsupported "buffer" type.'
|
||||
);
|
||||
}
|
||||
var matte = this.smask && this.smask.matte;
|
||||
if (!matte) {
|
||||
|
@ -530,7 +616,8 @@ var PDFImage = (function PDFImageClosure() {
|
|||
createImageData(forceRGBA = false) {
|
||||
var drawWidth = this.drawWidth;
|
||||
var drawHeight = this.drawHeight;
|
||||
var imgData = { // other fields are filled in below
|
||||
var imgData = {
|
||||
// other fields are filled in below
|
||||
width: drawWidth,
|
||||
height: drawHeight,
|
||||
kind: 0,
|
||||
|
@ -555,14 +642,22 @@ var PDFImage = (function PDFImageClosure() {
|
|||
// Similarly, if it is a 24-bit-per pixel RGB image without any
|
||||
// complications, we avoid expanding by 1.333x to RGBA form.
|
||||
var kind;
|
||||
if (this.colorSpace.name === 'DeviceGray' && bpc === 1) {
|
||||
if (this.colorSpace.name === "DeviceGray" && bpc === 1) {
|
||||
kind = ImageKind.GRAYSCALE_1BPP;
|
||||
} else if (this.colorSpace.name === 'DeviceRGB' && bpc === 8 &&
|
||||
!this.needsDecode) {
|
||||
} else if (
|
||||
this.colorSpace.name === "DeviceRGB" &&
|
||||
bpc === 8 &&
|
||||
!this.needsDecode
|
||||
) {
|
||||
kind = ImageKind.RGB_24BPP;
|
||||
}
|
||||
if (kind && !this.smask && !this.mask &&
|
||||
drawWidth === originalWidth && drawHeight === originalHeight) {
|
||||
if (
|
||||
kind &&
|
||||
!this.smask &&
|
||||
!this.mask &&
|
||||
drawWidth === originalWidth &&
|
||||
drawHeight === originalHeight
|
||||
) {
|
||||
imgData.kind = kind;
|
||||
|
||||
imgArray = this.getImageBytes(originalHeight * rowBytes);
|
||||
|
@ -580,8 +675,10 @@ var PDFImage = (function PDFImageClosure() {
|
|||
}
|
||||
if (this.needsDecode) {
|
||||
// Invert the buffer (which must be grayscale if we reached here).
|
||||
assert(kind === ImageKind.GRAYSCALE_1BPP,
|
||||
'PDFImage.createImageData: The image must be grayscale.');
|
||||
assert(
|
||||
kind === ImageKind.GRAYSCALE_1BPP,
|
||||
"PDFImage.createImageData: The image must be grayscale."
|
||||
);
|
||||
var buffer = imgData.data;
|
||||
for (var i = 0, ii = buffer.length; i < ii; i++) {
|
||||
buffer[i] ^= 0xff;
|
||||
|
@ -592,16 +689,20 @@ var PDFImage = (function PDFImageClosure() {
|
|||
if (this.image instanceof JpegStream && !this.smask && !this.mask) {
|
||||
let imageLength = originalHeight * rowBytes;
|
||||
switch (this.colorSpace.name) {
|
||||
case 'DeviceGray':
|
||||
case "DeviceGray":
|
||||
// Avoid truncating the image, since `JpegImage.getData`
|
||||
// will expand the image data when `forceRGB === true`.
|
||||
imageLength *= 3;
|
||||
/* falls through */
|
||||
case 'DeviceRGB':
|
||||
case 'DeviceCMYK':
|
||||
/* falls through */
|
||||
case "DeviceRGB":
|
||||
case "DeviceCMYK":
|
||||
imgData.kind = ImageKind.RGB_24BPP;
|
||||
imgData.data = this.getImageBytes(imageLength,
|
||||
drawWidth, drawHeight, /* forceRGB = */ true);
|
||||
imgData.data = this.getImageBytes(
|
||||
imageLength,
|
||||
drawWidth,
|
||||
drawHeight,
|
||||
/* forceRGB = */ true
|
||||
);
|
||||
return imgData;
|
||||
}
|
||||
}
|
||||
|
@ -609,8 +710,8 @@ var PDFImage = (function PDFImageClosure() {
|
|||
|
||||
imgArray = this.getImageBytes(originalHeight * rowBytes);
|
||||
// imgArray can be incomplete (e.g. after CCITT fax encoding).
|
||||
var actualHeight = 0 | (imgArray.length / rowBytes *
|
||||
drawHeight / originalHeight);
|
||||
var actualHeight =
|
||||
0 | (((imgArray.length / rowBytes) * drawHeight) / originalHeight);
|
||||
|
||||
var comps = this.getComponents(imgArray);
|
||||
|
||||
|
@ -629,16 +730,29 @@ var PDFImage = (function PDFImageClosure() {
|
|||
maybeUndoPreblend = true;
|
||||
|
||||
// Color key masking (opacity) must be performed before decoding.
|
||||
this.fillOpacity(imgData.data, drawWidth, drawHeight, actualHeight,
|
||||
comps);
|
||||
this.fillOpacity(
|
||||
imgData.data,
|
||||
drawWidth,
|
||||
drawHeight,
|
||||
actualHeight,
|
||||
comps
|
||||
);
|
||||
}
|
||||
|
||||
if (this.needsDecode) {
|
||||
this.decodeBuffer(comps);
|
||||
}
|
||||
this.colorSpace.fillRgb(imgData.data, originalWidth, originalHeight,
|
||||
drawWidth, drawHeight, actualHeight, bpc, comps,
|
||||
alpha01);
|
||||
this.colorSpace.fillRgb(
|
||||
imgData.data,
|
||||
originalWidth,
|
||||
originalHeight,
|
||||
drawWidth,
|
||||
drawHeight,
|
||||
actualHeight,
|
||||
bpc,
|
||||
comps,
|
||||
alpha01
|
||||
);
|
||||
if (maybeUndoPreblend) {
|
||||
this.undoPreblend(imgData.data, drawWidth, actualHeight);
|
||||
}
|
||||
|
@ -647,15 +761,20 @@ var PDFImage = (function PDFImageClosure() {
|
|||
},
|
||||
|
||||
fillGrayBuffer(buffer) {
|
||||
if (typeof PDFJSDev === 'undefined' ||
|
||||
PDFJSDev.test('!PRODUCTION || TESTING')) {
|
||||
assert(buffer instanceof Uint8ClampedArray,
|
||||
'PDFImage.fillGrayBuffer: Unsupported "buffer" type.');
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(
|
||||
buffer instanceof Uint8ClampedArray,
|
||||
'PDFImage.fillGrayBuffer: Unsupported "buffer" type.'
|
||||
);
|
||||
}
|
||||
var numComps = this.numComps;
|
||||
if (numComps !== 1) {
|
||||
throw new FormatError(
|
||||
`Reading gray scale from a color image: ${numComps}`);
|
||||
`Reading gray scale from a color image: ${numComps}`
|
||||
);
|
||||
}
|
||||
|
||||
var width = this.width;
|
||||
|
@ -680,7 +799,7 @@ var PDFImage = (function PDFImageClosure() {
|
|||
} else {
|
||||
// scale to {0, 255}
|
||||
for (i = 0; i < length; ++i) {
|
||||
buffer[i] = (-comps[i]) & 255;
|
||||
buffer[i] = -comps[i] & 255;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -708,6 +827,4 @@ var PDFImage = (function PDFImageClosure() {
|
|||
return PDFImage;
|
||||
})();
|
||||
|
||||
export {
|
||||
PDFImage,
|
||||
};
|
||||
export { PDFImage };
|
||||
|
|
|
@ -14,13 +14,18 @@
|
|||
*/
|
||||
/* eslint no-var: error */
|
||||
|
||||
import { ColorSpace } from './colorspace';
|
||||
import { JpegStream } from './jpeg_stream';
|
||||
import { Stream } from './stream';
|
||||
import { ColorSpace } from "./colorspace";
|
||||
import { JpegStream } from "./jpeg_stream";
|
||||
import { Stream } from "./stream";
|
||||
|
||||
class NativeImageDecoder {
|
||||
constructor({ xref, resources, handler, forceDataSchema = false,
|
||||
pdfFunctionFactory, }) {
|
||||
constructor({
|
||||
xref,
|
||||
resources,
|
||||
handler,
|
||||
forceDataSchema = false,
|
||||
pdfFunctionFactory,
|
||||
}) {
|
||||
this.xref = xref;
|
||||
this.resources = resources;
|
||||
this.handler = handler;
|
||||
|
@ -29,23 +34,36 @@ class NativeImageDecoder {
|
|||
}
|
||||
|
||||
canDecode(image) {
|
||||
return image instanceof JpegStream &&
|
||||
NativeImageDecoder.isDecodable(image, this.xref, this.resources,
|
||||
this.pdfFunctionFactory);
|
||||
return (
|
||||
image instanceof JpegStream &&
|
||||
NativeImageDecoder.isDecodable(
|
||||
image,
|
||||
this.xref,
|
||||
this.resources,
|
||||
this.pdfFunctionFactory
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
decode(image) {
|
||||
// For natively supported JPEGs send them to the main thread for decoding.
|
||||
const dict = image.dict;
|
||||
let colorSpace = dict.get('ColorSpace', 'CS');
|
||||
colorSpace = ColorSpace.parse(colorSpace, this.xref, this.resources,
|
||||
this.pdfFunctionFactory);
|
||||
let colorSpace = dict.get("ColorSpace", "CS");
|
||||
colorSpace = ColorSpace.parse(
|
||||
colorSpace,
|
||||
this.xref,
|
||||
this.resources,
|
||||
this.pdfFunctionFactory
|
||||
);
|
||||
|
||||
return this.handler.sendWithPromise('JpegDecode', [
|
||||
image.getIR(this.forceDataSchema), colorSpace.numComps
|
||||
]).then(function({ data, width, height, }) {
|
||||
return new Stream(data, 0, data.length, dict);
|
||||
});
|
||||
return this.handler
|
||||
.sendWithPromise("JpegDecode", [
|
||||
image.getIR(this.forceDataSchema),
|
||||
colorSpace.numComps,
|
||||
])
|
||||
.then(function({ data, width, height }) {
|
||||
return new Stream(data, 0, data.length, dict);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,14 +72,20 @@ class NativeImageDecoder {
|
|||
*/
|
||||
static isSupported(image, xref, res, pdfFunctionFactory) {
|
||||
const dict = image.dict;
|
||||
if (dict.has('DecodeParms') || dict.has('DP')) {
|
||||
if (dict.has("DecodeParms") || dict.has("DP")) {
|
||||
return false;
|
||||
}
|
||||
const cs = ColorSpace.parse(dict.get('ColorSpace', 'CS'), xref, res,
|
||||
pdfFunctionFactory);
|
||||
const cs = ColorSpace.parse(
|
||||
dict.get("ColorSpace", "CS"),
|
||||
xref,
|
||||
res,
|
||||
pdfFunctionFactory
|
||||
);
|
||||
// isDefaultDecode() of DeviceGray and DeviceRGB needs no `bpc` argument.
|
||||
return (cs.name === 'DeviceGray' || cs.name === 'DeviceRGB') &&
|
||||
cs.isDefaultDecode(dict.getArray('Decode', 'D'));
|
||||
return (
|
||||
(cs.name === "DeviceGray" || cs.name === "DeviceRGB") &&
|
||||
cs.isDefaultDecode(dict.getArray("Decode", "D"))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,17 +93,21 @@ class NativeImageDecoder {
|
|||
*/
|
||||
static isDecodable(image, xref, res, pdfFunctionFactory) {
|
||||
const dict = image.dict;
|
||||
if (dict.has('DecodeParms') || dict.has('DP')) {
|
||||
if (dict.has("DecodeParms") || dict.has("DP")) {
|
||||
return false;
|
||||
}
|
||||
const cs = ColorSpace.parse(dict.get('ColorSpace', 'CS'), xref, res,
|
||||
pdfFunctionFactory);
|
||||
const bpc = dict.get('BitsPerComponent', 'BPC') || 1;
|
||||
return (cs.numComps === 1 || cs.numComps === 3) &&
|
||||
cs.isDefaultDecode(dict.getArray('Decode', 'D'), bpc);
|
||||
const cs = ColorSpace.parse(
|
||||
dict.get("ColorSpace", "CS"),
|
||||
xref,
|
||||
res,
|
||||
pdfFunctionFactory
|
||||
);
|
||||
const bpc = dict.get("BitsPerComponent", "BPC") || 1;
|
||||
return (
|
||||
(cs.numComps === 1 || cs.numComps === 3) &&
|
||||
cs.isDefaultDecode(dict.getArray("Decode", "D"), bpc)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
NativeImageDecoder,
|
||||
};
|
||||
export { NativeImageDecoder };
|
||||
|
|
1382
src/core/jbig2.js
1382
src/core/jbig2.js
File diff suppressed because it is too large
Load diff
|
@ -13,10 +13,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { isDict, isStream } from './primitives';
|
||||
import { DecodeStream } from './stream';
|
||||
import { Jbig2Image } from './jbig2';
|
||||
import { shadow } from '../shared/util';
|
||||
import { isDict, isStream } from "./primitives";
|
||||
import { DecodeStream } from "./stream";
|
||||
import { Jbig2Image } from "./jbig2";
|
||||
import { shadow } from "../shared/util";
|
||||
|
||||
/**
|
||||
* For JBIG2's we use a library to decode these images and
|
||||
|
@ -34,10 +34,10 @@ let Jbig2Stream = (function Jbig2StreamClosure() {
|
|||
|
||||
Jbig2Stream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
Object.defineProperty(Jbig2Stream.prototype, 'bytes', {
|
||||
Object.defineProperty(Jbig2Stream.prototype, "bytes", {
|
||||
get() {
|
||||
// If `this.maybeLength` is null, we'll get the entire stream.
|
||||
return shadow(this, 'bytes', this.stream.getBytes(this.maybeLength));
|
||||
return shadow(this, "bytes", this.stream.getBytes(this.maybeLength));
|
||||
},
|
||||
configurable: true,
|
||||
});
|
||||
|
@ -55,19 +55,19 @@ let Jbig2Stream = (function Jbig2StreamClosure() {
|
|||
|
||||
let chunks = [];
|
||||
if (isDict(this.params)) {
|
||||
let globalsStream = this.params.get('JBIG2Globals');
|
||||
let globalsStream = this.params.get("JBIG2Globals");
|
||||
if (isStream(globalsStream)) {
|
||||
let globals = globalsStream.getBytes();
|
||||
chunks.push({ data: globals, start: 0, end: globals.length, });
|
||||
chunks.push({ data: globals, start: 0, end: globals.length });
|
||||
}
|
||||
}
|
||||
chunks.push({ data: this.bytes, start: 0, end: this.bytes.length, });
|
||||
chunks.push({ data: this.bytes, start: 0, end: this.bytes.length });
|
||||
let data = jbig2Image.parseChunks(chunks);
|
||||
let dataLength = data.length;
|
||||
|
||||
// JBIG2 had black as 1 and white as 0, inverting the colors
|
||||
for (let i = 0; i < dataLength; i++) {
|
||||
data[i] ^= 0xFF;
|
||||
data[i] ^= 0xff;
|
||||
}
|
||||
this.buffer = data;
|
||||
this.bufferLength = dataLength;
|
||||
|
@ -77,6 +77,4 @@ let Jbig2Stream = (function Jbig2StreamClosure() {
|
|||
return Jbig2Stream;
|
||||
})();
|
||||
|
||||
export {
|
||||
Jbig2Stream,
|
||||
};
|
||||
export { Jbig2Stream };
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createObjectURL, shadow } from '../shared/util';
|
||||
import { DecodeStream } from './stream';
|
||||
import { isDict } from './primitives';
|
||||
import { JpegImage } from './jpg';
|
||||
import { createObjectURL, shadow } from "../shared/util";
|
||||
import { DecodeStream } from "./stream";
|
||||
import { isDict } from "./primitives";
|
||||
import { JpegImage } from "./jpg";
|
||||
|
||||
/**
|
||||
* Depending on the type of JPEG a JpegStream is handled in different ways. For
|
||||
|
@ -31,7 +31,8 @@ let JpegStream = (function JpegStreamClosure() {
|
|||
// Note: this seems to mainly affect inline images.
|
||||
let ch;
|
||||
while ((ch = stream.getByte()) !== -1) {
|
||||
if (ch === 0xFF) { // Find the first byte of the SOI marker (0xFFD8).
|
||||
if (ch === 0xff) {
|
||||
// Find the first byte of the SOI marker (0xFFD8).
|
||||
stream.skip(-1); // Reset the stream position to the SOI.
|
||||
break;
|
||||
}
|
||||
|
@ -46,10 +47,10 @@ let JpegStream = (function JpegStreamClosure() {
|
|||
|
||||
JpegStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
Object.defineProperty(JpegStream.prototype, 'bytes', {
|
||||
Object.defineProperty(JpegStream.prototype, "bytes", {
|
||||
get: function JpegStream_bytes() {
|
||||
// If `this.maybeLength` is null, we'll get the entire stream.
|
||||
return shadow(this, 'bytes', this.stream.getBytes(this.maybeLength));
|
||||
return shadow(this, "bytes", this.stream.getBytes(this.maybeLength));
|
||||
},
|
||||
configurable: true,
|
||||
});
|
||||
|
@ -69,9 +70,9 @@ let JpegStream = (function JpegStreamClosure() {
|
|||
};
|
||||
|
||||
// Checking if values need to be transformed before conversion.
|
||||
let decodeArr = this.dict.getArray('Decode', 'D');
|
||||
let decodeArr = this.dict.getArray("Decode", "D");
|
||||
if (this.forceRGB && Array.isArray(decodeArr)) {
|
||||
let bitsPerComponent = this.dict.get('BitsPerComponent') || 8;
|
||||
let bitsPerComponent = this.dict.get("BitsPerComponent") || 8;
|
||||
let decodeArrLength = decodeArr.length;
|
||||
let transform = new Int32Array(decodeArrLength);
|
||||
let transformNeeded = false;
|
||||
|
@ -89,7 +90,7 @@ let JpegStream = (function JpegStreamClosure() {
|
|||
}
|
||||
// Fetching the 'ColorTransform' entry, if it exists.
|
||||
if (isDict(this.params)) {
|
||||
let colorTransform = this.params.get('ColorTransform');
|
||||
let colorTransform = this.params.get("ColorTransform");
|
||||
if (Number.isInteger(colorTransform)) {
|
||||
jpegOptions.colorTransform = colorTransform;
|
||||
}
|
||||
|
@ -109,12 +110,10 @@ let JpegStream = (function JpegStreamClosure() {
|
|||
};
|
||||
|
||||
JpegStream.prototype.getIR = function(forceDataSchema = false) {
|
||||
return createObjectURL(this.bytes, 'image/jpeg', forceDataSchema);
|
||||
return createObjectURL(this.bytes, "image/jpeg", forceDataSchema);
|
||||
};
|
||||
|
||||
return JpegStream;
|
||||
})();
|
||||
|
||||
export {
|
||||
JpegStream,
|
||||
};
|
||||
export { JpegStream };
|
||||
|
|
546
src/core/jpg.js
546
src/core/jpg.js
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
/* eslint-disable no-multi-spaces */
|
||||
|
||||
import { assert, BaseException, warn } from '../shared/util';
|
||||
import { assert, BaseException, warn } from "../shared/util";
|
||||
|
||||
class JpegError extends BaseException {
|
||||
constructor(msg) {
|
||||
|
@ -29,7 +29,7 @@ class DNLMarkerError extends BaseException {
|
|||
}
|
||||
}
|
||||
|
||||
class EOIMarkerError extends BaseException { }
|
||||
class EOIMarkerError extends BaseException {}
|
||||
|
||||
/**
|
||||
* This code was forked from https://github.com/notmasteryet/jpgjs.
|
||||
|
@ -64,27 +64,32 @@ var JpegImage = (function JpegImageClosure() {
|
|||
63
|
||||
]);
|
||||
|
||||
var dctCos1 = 4017; // cos(pi/16)
|
||||
var dctSin1 = 799; // sin(pi/16)
|
||||
var dctCos3 = 3406; // cos(3*pi/16)
|
||||
var dctSin3 = 2276; // sin(3*pi/16)
|
||||
var dctCos6 = 1567; // cos(6*pi/16)
|
||||
var dctSin6 = 3784; // sin(6*pi/16)
|
||||
var dctSqrt2 = 5793; // sqrt(2)
|
||||
var dctSqrt1d2 = 2896; // sqrt(2) / 2
|
||||
var dctCos1 = 4017; // cos(pi/16)
|
||||
var dctSin1 = 799; // sin(pi/16)
|
||||
var dctCos3 = 3406; // cos(3*pi/16)
|
||||
var dctSin3 = 2276; // sin(3*pi/16)
|
||||
var dctCos6 = 1567; // cos(6*pi/16)
|
||||
var dctSin6 = 3784; // sin(6*pi/16)
|
||||
var dctSqrt2 = 5793; // sqrt(2)
|
||||
var dctSqrt1d2 = 2896; // sqrt(2) / 2
|
||||
|
||||
function JpegImage({ decodeTransform = null, colorTransform = -1, } = {}) {
|
||||
function JpegImage({ decodeTransform = null, colorTransform = -1 } = {}) {
|
||||
this._decodeTransform = decodeTransform;
|
||||
this._colorTransform = colorTransform;
|
||||
}
|
||||
|
||||
function buildHuffmanTable(codeLengths, values) {
|
||||
var k = 0, code = [], i, j, length = 16;
|
||||
var k = 0,
|
||||
code = [],
|
||||
i,
|
||||
j,
|
||||
length = 16;
|
||||
while (length > 0 && !codeLengths[length - 1]) {
|
||||
length--;
|
||||
}
|
||||
code.push({ children: [], index: 0, });
|
||||
var p = code[0], q;
|
||||
code.push({ children: [], index: 0 });
|
||||
var p = code[0],
|
||||
q;
|
||||
for (i = 0; i < length; i++) {
|
||||
for (j = 0; j < codeLengths[i]; j++) {
|
||||
p = code.pop();
|
||||
|
@ -95,7 +100,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||
p.index++;
|
||||
code.push(p);
|
||||
while (code.length <= i) {
|
||||
code.push(q = { children: [], index: 0, });
|
||||
code.push((q = { children: [], index: 0 }));
|
||||
p.children[p.index] = q.children;
|
||||
p = q;
|
||||
}
|
||||
|
@ -103,7 +108,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||
}
|
||||
if (i + 1 < length) {
|
||||
// p here points to last code
|
||||
code.push(q = { children: [], index: 0, });
|
||||
code.push((q = { children: [], index: 0 }));
|
||||
p.children[p.index] = q.children;
|
||||
p = q;
|
||||
}
|
||||
|
@ -115,13 +120,24 @@ var JpegImage = (function JpegImageClosure() {
|
|||
return 64 * ((component.blocksPerLine + 1) * row + col);
|
||||
}
|
||||
|
||||
function decodeScan(data, offset, frame, components, resetInterval,
|
||||
spectralStart, spectralEnd, successivePrev, successive,
|
||||
parseDNLMarker = false) {
|
||||
function decodeScan(
|
||||
data,
|
||||
offset,
|
||||
frame,
|
||||
components,
|
||||
resetInterval,
|
||||
spectralStart,
|
||||
spectralEnd,
|
||||
successivePrev,
|
||||
successive,
|
||||
parseDNLMarker = false
|
||||
) {
|
||||
var mcusPerLine = frame.mcusPerLine;
|
||||
var progressive = frame.progressive;
|
||||
|
||||
var startOffset = offset, bitsData = 0, bitsCount = 0;
|
||||
var startOffset = offset,
|
||||
bitsData = 0,
|
||||
bitsCount = 0;
|
||||
|
||||
function readBit() {
|
||||
if (bitsCount > 0) {
|
||||
|
@ -129,22 +145,28 @@ var JpegImage = (function JpegImageClosure() {
|
|||
return (bitsData >> bitsCount) & 1;
|
||||
}
|
||||
bitsData = data[offset++];
|
||||
if (bitsData === 0xFF) {
|
||||
if (bitsData === 0xff) {
|
||||
var nextByte = data[offset++];
|
||||
if (nextByte) {
|
||||
if (nextByte === 0xDC && parseDNLMarker) { // DNL == 0xFFDC
|
||||
if (nextByte === 0xdc && parseDNLMarker) {
|
||||
// DNL == 0xFFDC
|
||||
offset += 2; // Skip data length.
|
||||
const scanLines = (data[offset++] << 8) | data[offset++];
|
||||
if (scanLines > 0 && scanLines !== frame.scanLines) {
|
||||
throw new DNLMarkerError(
|
||||
'Found DNL marker (0xFFDC) while parsing scan data', scanLines);
|
||||
"Found DNL marker (0xFFDC) while parsing scan data",
|
||||
scanLines
|
||||
);
|
||||
}
|
||||
} else if (nextByte === 0xD9) { // EOI == 0xFFD9
|
||||
} else if (nextByte === 0xd9) {
|
||||
// EOI == 0xFFD9
|
||||
throw new EOIMarkerError(
|
||||
'Found EOI marker (0xFFD9) while parsing scan data');
|
||||
"Found EOI marker (0xFFD9) while parsing scan data"
|
||||
);
|
||||
}
|
||||
throw new JpegError(
|
||||
`unexpected marker ${((bitsData << 8) | nextByte).toString(16)}`);
|
||||
`unexpected marker ${((bitsData << 8) | nextByte).toString(16)}`
|
||||
);
|
||||
}
|
||||
// unstuff 0
|
||||
}
|
||||
|
@ -156,11 +178,11 @@ var JpegImage = (function JpegImageClosure() {
|
|||
var node = tree;
|
||||
while (true) {
|
||||
node = node[readBit()];
|
||||
if (typeof node === 'number') {
|
||||
if (typeof node === "number") {
|
||||
return node;
|
||||
}
|
||||
if (typeof node !== 'object') {
|
||||
throw new JpegError('invalid huffman sequence');
|
||||
if (typeof node !== "object") {
|
||||
throw new JpegError("invalid huffman sequence");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -188,11 +210,12 @@ var JpegImage = (function JpegImageClosure() {
|
|||
function decodeBaseline(component, offset) {
|
||||
var t = decodeHuffman(component.huffmanTableDC);
|
||||
var diff = t === 0 ? 0 : receiveAndExtend(t);
|
||||
component.blockData[offset] = (component.pred += diff);
|
||||
component.blockData[offset] = component.pred += diff;
|
||||
var k = 1;
|
||||
while (k < 64) {
|
||||
var rs = decodeHuffman(component.huffmanTableAC);
|
||||
var s = rs & 15, r = rs >> 4;
|
||||
var s = rs & 15,
|
||||
r = rs >> 4;
|
||||
if (s === 0) {
|
||||
if (r < 15) {
|
||||
break;
|
||||
|
@ -209,8 +232,8 @@ var JpegImage = (function JpegImageClosure() {
|
|||
|
||||
function decodeDCFirst(component, offset) {
|
||||
var t = decodeHuffman(component.huffmanTableDC);
|
||||
var diff = t === 0 ? 0 : (receiveAndExtend(t) << successive);
|
||||
component.blockData[offset] = (component.pred += diff);
|
||||
var diff = t === 0 ? 0 : receiveAndExtend(t) << successive;
|
||||
component.blockData[offset] = component.pred += diff;
|
||||
}
|
||||
|
||||
function decodeDCSuccessive(component, offset) {
|
||||
|
@ -223,10 +246,12 @@ var JpegImage = (function JpegImageClosure() {
|
|||
eobrun--;
|
||||
return;
|
||||
}
|
||||
var k = spectralStart, e = spectralEnd;
|
||||
var k = spectralStart,
|
||||
e = spectralEnd;
|
||||
while (k <= e) {
|
||||
var rs = decodeHuffman(component.huffmanTableAC);
|
||||
var s = rs & 15, r = rs >> 4;
|
||||
var s = rs & 15,
|
||||
r = rs >> 4;
|
||||
if (s === 0) {
|
||||
if (r < 15) {
|
||||
eobrun = receive(r) + (1 << r) - 1;
|
||||
|
@ -243,7 +268,8 @@ var JpegImage = (function JpegImageClosure() {
|
|||
}
|
||||
}
|
||||
|
||||
var successiveACState = 0, successiveACNextValue;
|
||||
var successiveACState = 0,
|
||||
successiveACNextValue;
|
||||
function decodeACSuccessive(component, offset) {
|
||||
var k = spectralStart;
|
||||
var e = spectralEnd;
|
||||
|
@ -268,7 +294,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||
}
|
||||
} else {
|
||||
if (s !== 1) {
|
||||
throw new JpegError('invalid ACn encoding');
|
||||
throw new JpegError("invalid ACn encoding");
|
||||
}
|
||||
successiveACNextValue = receiveAndExtend(s);
|
||||
successiveACState = r ? 2 : 3;
|
||||
|
@ -339,7 +365,8 @@ var JpegImage = (function JpegImageClosure() {
|
|||
decodeFn = decodeBaseline;
|
||||
}
|
||||
|
||||
var mcu = 0, fileMarker;
|
||||
var mcu = 0,
|
||||
fileMarker;
|
||||
var mcuExpected;
|
||||
if (componentsLength === 1) {
|
||||
mcuExpected = components[0].blocksPerLine * components[0].blocksPerColumn;
|
||||
|
@ -350,8 +377,9 @@ var JpegImage = (function JpegImageClosure() {
|
|||
var h, v;
|
||||
while (mcu < mcuExpected) {
|
||||
// reset interval stuff
|
||||
var mcuToRead = resetInterval ?
|
||||
Math.min(mcuExpected - mcu, resetInterval) : mcuExpected;
|
||||
var mcuToRead = resetInterval
|
||||
? Math.min(mcuExpected - mcu, resetInterval)
|
||||
: mcuExpected;
|
||||
for (i = 0; i < componentsLength; i++) {
|
||||
components[i].pred = 0;
|
||||
}
|
||||
|
@ -388,16 +416,19 @@ var JpegImage = (function JpegImageClosure() {
|
|||
} else if (fileMarker.invalid) {
|
||||
// Some bad images seem to pad Scan blocks with e.g. zero bytes, skip
|
||||
// past those to attempt to find a valid marker (fixes issue4090.pdf).
|
||||
warn('decodeScan - unexpected MCU data, current marker is: ' +
|
||||
fileMarker.invalid);
|
||||
warn(
|
||||
"decodeScan - unexpected MCU data, current marker is: " +
|
||||
fileMarker.invalid
|
||||
);
|
||||
offset = fileMarker.offset;
|
||||
}
|
||||
var marker = fileMarker && fileMarker.marker;
|
||||
if (!marker || marker <= 0xFF00) {
|
||||
throw new JpegError('decodeScan - a valid marker was not found.');
|
||||
if (!marker || marker <= 0xff00) {
|
||||
throw new JpegError("decodeScan - a valid marker was not found.");
|
||||
}
|
||||
|
||||
if (marker >= 0xFFD0 && marker <= 0xFFD7) { // RSTx
|
||||
if (marker >= 0xffd0 && marker <= 0xffd7) {
|
||||
// RSTx
|
||||
offset += 2;
|
||||
} else {
|
||||
break;
|
||||
|
@ -408,8 +439,10 @@ var JpegImage = (function JpegImageClosure() {
|
|||
// Some images include more Scan blocks than expected, skip past those and
|
||||
// attempt to find the next valid marker (fixes issue8182.pdf).
|
||||
if (fileMarker && fileMarker.invalid) {
|
||||
warn('decodeScan - unexpected Scan data, current marker is: ' +
|
||||
fileMarker.invalid);
|
||||
warn(
|
||||
"decodeScan - unexpected Scan data, current marker is: " +
|
||||
fileMarker.invalid
|
||||
);
|
||||
offset = fileMarker.offset;
|
||||
}
|
||||
|
||||
|
@ -422,13 +455,14 @@ var JpegImage = (function JpegImageClosure() {
|
|||
// IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
|
||||
// 988-991.
|
||||
function quantizeAndInverse(component, blockBufferOffset, p) {
|
||||
var qt = component.quantizationTable, blockData = component.blockData;
|
||||
var qt = component.quantizationTable,
|
||||
blockData = component.blockData;
|
||||
var v0, v1, v2, v3, v4, v5, v6, v7;
|
||||
var p0, p1, p2, p3, p4, p5, p6, p7;
|
||||
var t;
|
||||
|
||||
if (!qt) {
|
||||
throw new JpegError('missing required Quantization Table.');
|
||||
throw new JpegError("missing required Quantization Table.");
|
||||
}
|
||||
|
||||
// inverse DCT on rows
|
||||
|
@ -481,7 +515,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||
// stage 3
|
||||
v0 = (v0 + v1 + 1) >> 1;
|
||||
v1 = v0 - v1;
|
||||
t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
|
||||
t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
|
||||
v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
|
||||
v3 = t;
|
||||
v4 = (v4 + v6 + 1) >> 1;
|
||||
|
@ -494,10 +528,10 @@ var JpegImage = (function JpegImageClosure() {
|
|||
v3 = v0 - v3;
|
||||
v1 = (v1 + v2 + 1) >> 1;
|
||||
v2 = v1 - v2;
|
||||
t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
|
||||
t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
|
||||
v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
|
||||
v7 = t;
|
||||
t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
|
||||
t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
|
||||
v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
|
||||
v6 = t;
|
||||
|
||||
|
@ -515,7 +549,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||
// inverse DCT on columns
|
||||
for (var col = 0; col < 8; ++col) {
|
||||
p0 = p[col];
|
||||
p1 = p[col + 8];
|
||||
p1 = p[col + 8];
|
||||
p2 = p[col + 16];
|
||||
p3 = p[col + 24];
|
||||
p4 = p[col + 32];
|
||||
|
@ -527,9 +561,9 @@ var JpegImage = (function JpegImageClosure() {
|
|||
if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) {
|
||||
t = (dctSqrt2 * p0 + 8192) >> 14;
|
||||
// convert to 8 bit
|
||||
t = (t < -2040) ? 0 : (t >= 2024) ? 255 : (t + 2056) >> 4;
|
||||
t = t < -2040 ? 0 : t >= 2024 ? 255 : (t + 2056) >> 4;
|
||||
blockData[blockBufferOffset + col] = t;
|
||||
blockData[blockBufferOffset + col + 8] = t;
|
||||
blockData[blockBufferOffset + col + 8] = t;
|
||||
blockData[blockBufferOffset + col + 16] = t;
|
||||
blockData[blockBufferOffset + col + 24] = t;
|
||||
blockData[blockBufferOffset + col + 32] = t;
|
||||
|
@ -554,7 +588,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||
// converting to UInt8 range later.
|
||||
v0 = ((v0 + v1 + 1) >> 1) + 4112;
|
||||
v1 = v0 - v1;
|
||||
t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
|
||||
t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
|
||||
v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
|
||||
v3 = t;
|
||||
v4 = (v4 + v6 + 1) >> 1;
|
||||
|
@ -567,10 +601,10 @@ var JpegImage = (function JpegImageClosure() {
|
|||
v3 = v0 - v3;
|
||||
v1 = (v1 + v2 + 1) >> 1;
|
||||
v2 = v1 - v2;
|
||||
t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
|
||||
t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
|
||||
v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
|
||||
v7 = t;
|
||||
t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
|
||||
t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
|
||||
v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
|
||||
v6 = t;
|
||||
|
||||
|
@ -585,18 +619,18 @@ var JpegImage = (function JpegImageClosure() {
|
|||
p4 = v3 - v4;
|
||||
|
||||
// convert to 8-bit integers
|
||||
p0 = (p0 < 16) ? 0 : (p0 >= 4080) ? 255 : p0 >> 4;
|
||||
p1 = (p1 < 16) ? 0 : (p1 >= 4080) ? 255 : p1 >> 4;
|
||||
p2 = (p2 < 16) ? 0 : (p2 >= 4080) ? 255 : p2 >> 4;
|
||||
p3 = (p3 < 16) ? 0 : (p3 >= 4080) ? 255 : p3 >> 4;
|
||||
p4 = (p4 < 16) ? 0 : (p4 >= 4080) ? 255 : p4 >> 4;
|
||||
p5 = (p5 < 16) ? 0 : (p5 >= 4080) ? 255 : p5 >> 4;
|
||||
p6 = (p6 < 16) ? 0 : (p6 >= 4080) ? 255 : p6 >> 4;
|
||||
p7 = (p7 < 16) ? 0 : (p7 >= 4080) ? 255 : p7 >> 4;
|
||||
p0 = p0 < 16 ? 0 : p0 >= 4080 ? 255 : p0 >> 4;
|
||||
p1 = p1 < 16 ? 0 : p1 >= 4080 ? 255 : p1 >> 4;
|
||||
p2 = p2 < 16 ? 0 : p2 >= 4080 ? 255 : p2 >> 4;
|
||||
p3 = p3 < 16 ? 0 : p3 >= 4080 ? 255 : p3 >> 4;
|
||||
p4 = p4 < 16 ? 0 : p4 >= 4080 ? 255 : p4 >> 4;
|
||||
p5 = p5 < 16 ? 0 : p5 >= 4080 ? 255 : p5 >> 4;
|
||||
p6 = p6 < 16 ? 0 : p6 >= 4080 ? 255 : p6 >> 4;
|
||||
p7 = p7 < 16 ? 0 : p7 >= 4080 ? 255 : p7 >> 4;
|
||||
|
||||
// store block data
|
||||
blockData[blockBufferOffset + col] = p0;
|
||||
blockData[blockBufferOffset + col + 8] = p1;
|
||||
blockData[blockBufferOffset + col + 8] = p1;
|
||||
blockData[blockBufferOffset + col + 16] = p2;
|
||||
blockData[blockBufferOffset + col + 24] = p3;
|
||||
blockData[blockBufferOffset + col + 32] = p4;
|
||||
|
@ -632,7 +666,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||
return null; // Don't attempt to read non-existent data and just return.
|
||||
}
|
||||
var currentMarker = peekUint16(currentPos);
|
||||
if (currentMarker >= 0xFFC0 && currentMarker <= 0xFFFE) {
|
||||
if (currentMarker >= 0xffc0 && currentMarker <= 0xfffe) {
|
||||
return {
|
||||
invalid: null,
|
||||
marker: currentMarker,
|
||||
|
@ -640,7 +674,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||
};
|
||||
}
|
||||
var newMarker = peekUint16(newPos);
|
||||
while (!(newMarker >= 0xFFC0 && newMarker <= 0xFFFE)) {
|
||||
while (!(newMarker >= 0xffc0 && newMarker <= 0xfffe)) {
|
||||
if (++newPos >= maxPos) {
|
||||
return null; // Don't attempt to read non-existent data and just return.
|
||||
}
|
||||
|
@ -654,8 +688,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||
}
|
||||
|
||||
JpegImage.prototype = {
|
||||
parse(data, { dnlScanLines = null, } = {}) {
|
||||
|
||||
parse(data, { dnlScanLines = null } = {}) {
|
||||
function readUint16() {
|
||||
var value = (data[offset] << 8) | data[offset + 1];
|
||||
offset += 2;
|
||||
|
@ -668,8 +701,10 @@ var JpegImage = (function JpegImageClosure() {
|
|||
|
||||
var fileMarker = findNextFileMarker(data, endOffset, offset);
|
||||
if (fileMarker && fileMarker.invalid) {
|
||||
warn('readDataBlock - incorrect length, current marker is: ' +
|
||||
fileMarker.invalid);
|
||||
warn(
|
||||
"readDataBlock - incorrect length, current marker is: " +
|
||||
fileMarker.invalid
|
||||
);
|
||||
endOffset = fileMarker.offset;
|
||||
}
|
||||
|
||||
|
@ -683,15 +718,17 @@ var JpegImage = (function JpegImageClosure() {
|
|||
var mcusPerColumn = Math.ceil(frame.scanLines / 8 / frame.maxV);
|
||||
for (var i = 0; i < frame.components.length; i++) {
|
||||
component = frame.components[i];
|
||||
var blocksPerLine = Math.ceil(Math.ceil(frame.samplesPerLine / 8) *
|
||||
component.h / frame.maxH);
|
||||
var blocksPerColumn = Math.ceil(Math.ceil(frame.scanLines / 8) *
|
||||
component.v / frame.maxV);
|
||||
var blocksPerLine = Math.ceil(
|
||||
(Math.ceil(frame.samplesPerLine / 8) * component.h) / frame.maxH
|
||||
);
|
||||
var blocksPerColumn = Math.ceil(
|
||||
(Math.ceil(frame.scanLines / 8) * component.v) / frame.maxV
|
||||
);
|
||||
var blocksPerLineForMcu = mcusPerLine * component.h;
|
||||
var blocksPerColumnForMcu = mcusPerColumn * component.v;
|
||||
|
||||
var blocksBufferSize = 64 * blocksPerColumnForMcu *
|
||||
(blocksPerLineForMcu + 1);
|
||||
var blocksBufferSize =
|
||||
64 * blocksPerColumnForMcu * (blocksPerLineForMcu + 1);
|
||||
component.blockData = new Int16Array(blocksBufferSize);
|
||||
component.blocksPerLine = blocksPerLine;
|
||||
component.blocksPerColumn = blocksPerColumn;
|
||||
|
@ -706,56 +743,71 @@ var JpegImage = (function JpegImageClosure() {
|
|||
var frame, resetInterval;
|
||||
let numSOSMarkers = 0;
|
||||
var quantizationTables = [];
|
||||
var huffmanTablesAC = [], huffmanTablesDC = [];
|
||||
var huffmanTablesAC = [],
|
||||
huffmanTablesDC = [];
|
||||
var fileMarker = readUint16();
|
||||
if (fileMarker !== 0xFFD8) { // SOI (Start of Image)
|
||||
throw new JpegError('SOI not found');
|
||||
if (fileMarker !== 0xffd8) {
|
||||
// SOI (Start of Image)
|
||||
throw new JpegError("SOI not found");
|
||||
}
|
||||
|
||||
fileMarker = readUint16();
|
||||
markerLoop: while (fileMarker !== 0xFFD9) { // EOI (End of image)
|
||||
markerLoop: while (fileMarker !== 0xffd9) {
|
||||
// EOI (End of image)
|
||||
var i, j, l;
|
||||
switch (fileMarker) {
|
||||
case 0xFFE0: // APP0 (Application Specific)
|
||||
case 0xFFE1: // APP1
|
||||
case 0xFFE2: // APP2
|
||||
case 0xFFE3: // APP3
|
||||
case 0xFFE4: // APP4
|
||||
case 0xFFE5: // APP5
|
||||
case 0xFFE6: // APP6
|
||||
case 0xFFE7: // APP7
|
||||
case 0xFFE8: // APP8
|
||||
case 0xFFE9: // APP9
|
||||
case 0xFFEA: // APP10
|
||||
case 0xFFEB: // APP11
|
||||
case 0xFFEC: // APP12
|
||||
case 0xFFED: // APP13
|
||||
case 0xFFEE: // APP14
|
||||
case 0xFFEF: // APP15
|
||||
case 0xFFFE: // COM (Comment)
|
||||
case 0xffe0: // APP0 (Application Specific)
|
||||
case 0xffe1: // APP1
|
||||
case 0xffe2: // APP2
|
||||
case 0xffe3: // APP3
|
||||
case 0xffe4: // APP4
|
||||
case 0xffe5: // APP5
|
||||
case 0xffe6: // APP6
|
||||
case 0xffe7: // APP7
|
||||
case 0xffe8: // APP8
|
||||
case 0xffe9: // APP9
|
||||
case 0xffea: // APP10
|
||||
case 0xffeb: // APP11
|
||||
case 0xffec: // APP12
|
||||
case 0xffed: // APP13
|
||||
case 0xffee: // APP14
|
||||
case 0xffef: // APP15
|
||||
case 0xfffe: // COM (Comment)
|
||||
var appData = readDataBlock();
|
||||
|
||||
if (fileMarker === 0xFFE0) {
|
||||
if (appData[0] === 0x4A && appData[1] === 0x46 &&
|
||||
appData[2] === 0x49 && appData[3] === 0x46 &&
|
||||
appData[4] === 0) { // 'JFIF\x00'
|
||||
if (fileMarker === 0xffe0) {
|
||||
if (
|
||||
appData[0] === 0x4a &&
|
||||
appData[1] === 0x46 &&
|
||||
appData[2] === 0x49 &&
|
||||
appData[3] === 0x46 &&
|
||||
appData[4] === 0
|
||||
) {
|
||||
// 'JFIF\x00'
|
||||
jfif = {
|
||||
version: { major: appData[5], minor: appData[6], },
|
||||
version: { major: appData[5], minor: appData[6] },
|
||||
densityUnits: appData[7],
|
||||
xDensity: (appData[8] << 8) | appData[9],
|
||||
yDensity: (appData[10] << 8) | appData[11],
|
||||
thumbWidth: appData[12],
|
||||
thumbHeight: appData[13],
|
||||
thumbData: appData.subarray(14, 14 +
|
||||
3 * appData[12] * appData[13]),
|
||||
thumbData: appData.subarray(
|
||||
14,
|
||||
14 + 3 * appData[12] * appData[13]
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
// TODO APP1 - Exif
|
||||
if (fileMarker === 0xFFEE) {
|
||||
if (appData[0] === 0x41 && appData[1] === 0x64 &&
|
||||
appData[2] === 0x6F && appData[3] === 0x62 &&
|
||||
appData[4] === 0x65) { // 'Adobe'
|
||||
if (fileMarker === 0xffee) {
|
||||
if (
|
||||
appData[0] === 0x41 &&
|
||||
appData[1] === 0x64 &&
|
||||
appData[2] === 0x6f &&
|
||||
appData[3] === 0x62 &&
|
||||
appData[4] === 0x65
|
||||
) {
|
||||
// 'Adobe'
|
||||
adobe = {
|
||||
version: (appData[5] << 8) | appData[6],
|
||||
flags0: (appData[7] << 8) | appData[8],
|
||||
|
@ -766,48 +818,52 @@ var JpegImage = (function JpegImageClosure() {
|
|||
}
|
||||
break;
|
||||
|
||||
case 0xFFDB: // DQT (Define Quantization Tables)
|
||||
case 0xffdb: // DQT (Define Quantization Tables)
|
||||
var quantizationTablesLength = readUint16();
|
||||
var quantizationTablesEnd = quantizationTablesLength + offset - 2;
|
||||
var z;
|
||||
while (offset < quantizationTablesEnd) {
|
||||
var quantizationTableSpec = data[offset++];
|
||||
var tableData = new Uint16Array(64);
|
||||
if ((quantizationTableSpec >> 4) === 0) { // 8 bit values
|
||||
if (quantizationTableSpec >> 4 === 0) {
|
||||
// 8 bit values
|
||||
for (j = 0; j < 64; j++) {
|
||||
z = dctZigZag[j];
|
||||
tableData[z] = data[offset++];
|
||||
}
|
||||
} else if ((quantizationTableSpec >> 4) === 1) { // 16 bit values
|
||||
} else if (quantizationTableSpec >> 4 === 1) {
|
||||
// 16 bit values
|
||||
for (j = 0; j < 64; j++) {
|
||||
z = dctZigZag[j];
|
||||
tableData[z] = readUint16();
|
||||
}
|
||||
} else {
|
||||
throw new JpegError('DQT - invalid table spec');
|
||||
throw new JpegError("DQT - invalid table spec");
|
||||
}
|
||||
quantizationTables[quantizationTableSpec & 15] = tableData;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xFFC0: // SOF0 (Start of Frame, Baseline DCT)
|
||||
case 0xFFC1: // SOF1 (Start of Frame, Extended DCT)
|
||||
case 0xFFC2: // SOF2 (Start of Frame, Progressive DCT)
|
||||
case 0xffc0: // SOF0 (Start of Frame, Baseline DCT)
|
||||
case 0xffc1: // SOF1 (Start of Frame, Extended DCT)
|
||||
case 0xffc2: // SOF2 (Start of Frame, Progressive DCT)
|
||||
if (frame) {
|
||||
throw new JpegError('Only single frame JPEGs supported');
|
||||
throw new JpegError("Only single frame JPEGs supported");
|
||||
}
|
||||
readUint16(); // skip data length
|
||||
frame = {};
|
||||
frame.extended = (fileMarker === 0xFFC1);
|
||||
frame.progressive = (fileMarker === 0xFFC2);
|
||||
frame.extended = fileMarker === 0xffc1;
|
||||
frame.progressive = fileMarker === 0xffc2;
|
||||
frame.precision = data[offset++];
|
||||
const sofScanLines = readUint16();
|
||||
frame.scanLines = dnlScanLines || sofScanLines;
|
||||
frame.samplesPerLine = readUint16();
|
||||
frame.components = [];
|
||||
frame.componentIds = {};
|
||||
var componentsCount = data[offset++], componentId;
|
||||
var maxH = 0, maxV = 0;
|
||||
var componentsCount = data[offset++],
|
||||
componentId;
|
||||
var maxH = 0,
|
||||
maxV = 0;
|
||||
for (i = 0; i < componentsCount; i++) {
|
||||
componentId = data[offset];
|
||||
var h = data[offset + 1] >> 4;
|
||||
|
@ -833,14 +889,14 @@ var JpegImage = (function JpegImageClosure() {
|
|||
prepareComponents(frame);
|
||||
break;
|
||||
|
||||
case 0xFFC4: // DHT (Define Huffman Tables)
|
||||
case 0xffc4: // DHT (Define Huffman Tables)
|
||||
var huffmanLength = readUint16();
|
||||
for (i = 2; i < huffmanLength;) {
|
||||
for (i = 2; i < huffmanLength; ) {
|
||||
var huffmanTableSpec = data[offset++];
|
||||
var codeLengths = new Uint8Array(16);
|
||||
var codeLengthSum = 0;
|
||||
for (j = 0; j < 16; j++, offset++) {
|
||||
codeLengthSum += (codeLengths[j] = data[offset]);
|
||||
codeLengthSum += codeLengths[j] = data[offset];
|
||||
}
|
||||
var huffmanValues = new Uint8Array(codeLengthSum);
|
||||
for (j = 0; j < codeLengthSum; j++, offset++) {
|
||||
|
@ -848,27 +904,28 @@ var JpegImage = (function JpegImageClosure() {
|
|||
}
|
||||
i += 17 + codeLengthSum;
|
||||
|
||||
((huffmanTableSpec >> 4) === 0 ?
|
||||
huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] =
|
||||
buildHuffmanTable(codeLengths, huffmanValues);
|
||||
(huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[
|
||||
huffmanTableSpec & 15
|
||||
] = buildHuffmanTable(codeLengths, huffmanValues);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xFFDD: // DRI (Define Restart Interval)
|
||||
case 0xffdd: // DRI (Define Restart Interval)
|
||||
readUint16(); // skip data length
|
||||
resetInterval = readUint16();
|
||||
break;
|
||||
|
||||
case 0xFFDA: // SOS (Start of Scan)
|
||||
case 0xffda: // SOS (Start of Scan)
|
||||
// A DNL marker (0xFFDC), if it exists, is only allowed at the end
|
||||
// of the first scan segment and may only occur once in an image.
|
||||
// Furthermore, to prevent an infinite loop, do *not* attempt to
|
||||
// parse DNL markers during re-parsing of the JPEG scan data.
|
||||
const parseDNLMarker = (++numSOSMarkers) === 1 && !dnlScanLines;
|
||||
const parseDNLMarker = ++numSOSMarkers === 1 && !dnlScanLines;
|
||||
|
||||
readUint16(); // scanLength
|
||||
var selectorsCount = data[offset++];
|
||||
var components = [], component;
|
||||
var components = [],
|
||||
component;
|
||||
for (i = 0; i < selectorsCount; i++) {
|
||||
var componentIndex = frame.componentIds[data[offset++]];
|
||||
component = frame.components[componentIndex];
|
||||
|
@ -881,16 +938,23 @@ var JpegImage = (function JpegImageClosure() {
|
|||
var spectralEnd = data[offset++];
|
||||
var successiveApproximation = data[offset++];
|
||||
try {
|
||||
var processed = decodeScan(data, offset,
|
||||
frame, components, resetInterval,
|
||||
spectralStart, spectralEnd,
|
||||
successiveApproximation >> 4, successiveApproximation & 15,
|
||||
parseDNLMarker);
|
||||
var processed = decodeScan(
|
||||
data,
|
||||
offset,
|
||||
frame,
|
||||
components,
|
||||
resetInterval,
|
||||
spectralStart,
|
||||
spectralEnd,
|
||||
successiveApproximation >> 4,
|
||||
successiveApproximation & 15,
|
||||
parseDNLMarker
|
||||
);
|
||||
offset += processed;
|
||||
} catch (ex) {
|
||||
if (ex instanceof DNLMarkerError) {
|
||||
warn(`${ex.message} -- attempting to re-parse the JPEG image.`);
|
||||
return this.parse(data, { dnlScanLines: ex.scanLines, });
|
||||
return this.parse(data, { dnlScanLines: ex.scanLines });
|
||||
} else if (ex instanceof EOIMarkerError) {
|
||||
warn(`${ex.message} -- ignoring the rest of the image data.`);
|
||||
break markerLoop;
|
||||
|
@ -899,20 +963,24 @@ var JpegImage = (function JpegImageClosure() {
|
|||
}
|
||||
break;
|
||||
|
||||
case 0xFFDC: // DNL (Define Number of Lines)
|
||||
case 0xffdc: // DNL (Define Number of Lines)
|
||||
// Ignore the marker, since it's being handled in `decodeScan`.
|
||||
offset += 4;
|
||||
break;
|
||||
|
||||
case 0xFFFF: // Fill bytes
|
||||
if (data[offset] !== 0xFF) { // Avoid skipping a valid marker.
|
||||
case 0xffff: // Fill bytes
|
||||
if (data[offset] !== 0xff) {
|
||||
// Avoid skipping a valid marker.
|
||||
offset--;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (data[offset - 3] === 0xFF &&
|
||||
data[offset - 2] >= 0xC0 && data[offset - 2] <= 0xFE) {
|
||||
if (
|
||||
data[offset - 3] === 0xff &&
|
||||
data[offset - 2] >= 0xc0 &&
|
||||
data[offset - 2] <= 0xfe
|
||||
) {
|
||||
// could be incorrect encoding -- last 0xFF byte of the previous
|
||||
// block was eaten by the encoder
|
||||
offset -= 3;
|
||||
|
@ -920,18 +988,23 @@ var JpegImage = (function JpegImageClosure() {
|
|||
}
|
||||
let nextFileMarker = findNextFileMarker(data, offset - 2);
|
||||
if (nextFileMarker && nextFileMarker.invalid) {
|
||||
warn('JpegImage.parse - unexpected data, current marker is: ' +
|
||||
nextFileMarker.invalid);
|
||||
warn(
|
||||
"JpegImage.parse - unexpected data, current marker is: " +
|
||||
nextFileMarker.invalid
|
||||
);
|
||||
offset = nextFileMarker.offset;
|
||||
break;
|
||||
}
|
||||
if (offset > (data.length - 2)) {
|
||||
warn('JpegImage.parse - reached the end of the image data ' +
|
||||
'without finding an EOI marker (0xFFD9).');
|
||||
if (offset > data.length - 2) {
|
||||
warn(
|
||||
"JpegImage.parse - reached the end of the image data " +
|
||||
"without finding an EOI marker (0xFFD9)."
|
||||
);
|
||||
break markerLoop;
|
||||
}
|
||||
throw new JpegError('JpegImage.parse - unknown marker: ' +
|
||||
fileMarker.toString(16));
|
||||
throw new JpegError(
|
||||
"JpegImage.parse - unknown marker: " + fileMarker.toString(16)
|
||||
);
|
||||
}
|
||||
fileMarker = readUint16();
|
||||
}
|
||||
|
@ -965,7 +1038,8 @@ var JpegImage = (function JpegImageClosure() {
|
|||
},
|
||||
|
||||
_getLinearizedBlockData(width, height, isSourcePDF = false) {
|
||||
var scaleX = this.width / width, scaleY = this.height / height;
|
||||
var scaleX = this.width / width,
|
||||
scaleY = this.height / height;
|
||||
|
||||
var component, componentScaleX, componentScaleY, blocksPerScanline;
|
||||
var x, y, i, j, k;
|
||||
|
@ -993,7 +1067,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||
// linearize the blocks of the component
|
||||
for (y = 0; y < height; y++) {
|
||||
j = 0 | (y * componentScaleY);
|
||||
index = blocksPerScanline * (j & mask3LSB) | ((j & 7) << 3);
|
||||
index = (blocksPerScanline * (j & mask3LSB)) | ((j & 7) << 3);
|
||||
for (x = 0; x < width; x++) {
|
||||
data[offset] = output[index + xScaleBlockOffset[x]];
|
||||
offset += numComponents;
|
||||
|
@ -1022,7 +1096,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||
}
|
||||
|
||||
if (transform) {
|
||||
for (i = 0; i < dataLength;) {
|
||||
for (i = 0; i < dataLength; ) {
|
||||
for (j = 0, k = 0; j < numComponents; j++, i++, k += 2) {
|
||||
data[i] = ((data[i] * transform[k]) >> 8) + transform[k + 1];
|
||||
}
|
||||
|
@ -1077,34 +1151,61 @@ var JpegImage = (function JpegImageClosure() {
|
|||
Cr = data[i + 2];
|
||||
k = data[i + 3];
|
||||
|
||||
data[offset++] = -122.67195406894 +
|
||||
Cb * (-6.60635669420364e-5 * Cb + 0.000437130475926232 * Cr -
|
||||
5.4080610064599e-5 * Y + 0.00048449797120281 * k -
|
||||
0.154362151871126) +
|
||||
Cr * (-0.000957964378445773 * Cr + 0.000817076911346625 * Y -
|
||||
0.00477271405408747 * k + 1.53380253221734) +
|
||||
Y * (0.000961250184130688 * Y - 0.00266257332283933 * k +
|
||||
0.48357088451265) +
|
||||
data[offset++] =
|
||||
-122.67195406894 +
|
||||
Cb *
|
||||
(-6.60635669420364e-5 * Cb +
|
||||
0.000437130475926232 * Cr -
|
||||
5.4080610064599e-5 * Y +
|
||||
0.00048449797120281 * k -
|
||||
0.154362151871126) +
|
||||
Cr *
|
||||
(-0.000957964378445773 * Cr +
|
||||
0.000817076911346625 * Y -
|
||||
0.00477271405408747 * k +
|
||||
1.53380253221734) +
|
||||
Y *
|
||||
(0.000961250184130688 * Y -
|
||||
0.00266257332283933 * k +
|
||||
0.48357088451265) +
|
||||
k * (-0.000336197177618394 * k + 0.484791561490776);
|
||||
|
||||
data[offset++] = 107.268039397724 +
|
||||
Cb * (2.19927104525741e-5 * Cb - 0.000640992018297945 * Cr +
|
||||
0.000659397001245577 * Y + 0.000426105652938837 * k -
|
||||
0.176491792462875) +
|
||||
Cr * (-0.000778269941513683 * Cr + 0.00130872261408275 * Y +
|
||||
0.000770482631801132 * k - 0.151051492775562) +
|
||||
Y * (0.00126935368114843 * Y - 0.00265090189010898 * k +
|
||||
0.25802910206845) +
|
||||
data[offset++] =
|
||||
107.268039397724 +
|
||||
Cb *
|
||||
(2.19927104525741e-5 * Cb -
|
||||
0.000640992018297945 * Cr +
|
||||
0.000659397001245577 * Y +
|
||||
0.000426105652938837 * k -
|
||||
0.176491792462875) +
|
||||
Cr *
|
||||
(-0.000778269941513683 * Cr +
|
||||
0.00130872261408275 * Y +
|
||||
0.000770482631801132 * k -
|
||||
0.151051492775562) +
|
||||
Y *
|
||||
(0.00126935368114843 * Y -
|
||||
0.00265090189010898 * k +
|
||||
0.25802910206845) +
|
||||
k * (-0.000318913117588328 * k - 0.213742400323665);
|
||||
|
||||
data[offset++] = -20.810012546947 +
|
||||
Cb * (-0.000570115196973677 * Cb - 2.63409051004589e-5 * Cr +
|
||||
0.0020741088115012 * Y - 0.00288260236853442 * k +
|
||||
0.814272968359295) +
|
||||
Cr * (-1.53496057440975e-5 * Cr - 0.000132689043961446 * Y +
|
||||
0.000560833691242812 * k - 0.195152027534049) +
|
||||
Y * (0.00174418132927582 * Y - 0.00255243321439347 * k +
|
||||
0.116935020465145) +
|
||||
data[offset++] =
|
||||
-20.810012546947 +
|
||||
Cb *
|
||||
(-0.000570115196973677 * Cb -
|
||||
2.63409051004589e-5 * Cr +
|
||||
0.0020741088115012 * Y -
|
||||
0.00288260236853442 * k +
|
||||
0.814272968359295) +
|
||||
Cr *
|
||||
(-1.53496057440975e-5 * Cr -
|
||||
0.000132689043961446 * Y +
|
||||
0.000560833691242812 * k -
|
||||
0.195152027534049) +
|
||||
Y *
|
||||
(0.00174418132927582 * Y -
|
||||
0.00255243321439347 * k +
|
||||
0.116935020465145) +
|
||||
k * (-0.000343531996510555 * k + 0.24165260232407);
|
||||
}
|
||||
// Ensure that only the converted RGB data is returned.
|
||||
|
@ -1135,47 +1236,74 @@ var JpegImage = (function JpegImageClosure() {
|
|||
y = data[i + 2] * scale;
|
||||
k = data[i + 3] * scale;
|
||||
|
||||
data[offset++] = 255 +
|
||||
c * (-4.387332384609988 * c + 54.48615194189176 * m +
|
||||
18.82290502165302 * y + 212.25662451639585 * k -
|
||||
285.2331026137004) +
|
||||
m * (1.7149763477362134 * m - 5.6096736904047315 * y -
|
||||
17.873870861415444 * k - 5.497006427196366) +
|
||||
y * (-2.5217340131683033 * y - 21.248923337353073 * k +
|
||||
17.5119270841813) -
|
||||
data[offset++] =
|
||||
255 +
|
||||
c *
|
||||
(-4.387332384609988 * c +
|
||||
54.48615194189176 * m +
|
||||
18.82290502165302 * y +
|
||||
212.25662451639585 * k -
|
||||
285.2331026137004) +
|
||||
m *
|
||||
(1.7149763477362134 * m -
|
||||
5.6096736904047315 * y -
|
||||
17.873870861415444 * k -
|
||||
5.497006427196366) +
|
||||
y *
|
||||
(-2.5217340131683033 * y -
|
||||
21.248923337353073 * k +
|
||||
17.5119270841813) -
|
||||
k * (21.86122147463605 * k + 189.48180835922747);
|
||||
|
||||
data[offset++] = 255 +
|
||||
c * (8.841041422036149 * c + 60.118027045597366 * m +
|
||||
6.871425592049007 * y + 31.159100130055922 * k -
|
||||
79.2970844816548) +
|
||||
m * (-15.310361306967817 * m + 17.575251261109482 * y +
|
||||
131.35250912493976 * k - 190.9453302588951) +
|
||||
y * (4.444339102852739 * y + 9.8632861493405 * k -
|
||||
24.86741582555878) -
|
||||
data[offset++] =
|
||||
255 +
|
||||
c *
|
||||
(8.841041422036149 * c +
|
||||
60.118027045597366 * m +
|
||||
6.871425592049007 * y +
|
||||
31.159100130055922 * k -
|
||||
79.2970844816548) +
|
||||
m *
|
||||
(-15.310361306967817 * m +
|
||||
17.575251261109482 * y +
|
||||
131.35250912493976 * k -
|
||||
190.9453302588951) +
|
||||
y *
|
||||
(4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878) -
|
||||
k * (20.737325471181034 * k + 187.80453709719578);
|
||||
|
||||
data[offset++] = 255 +
|
||||
c * (0.8842522430003296 * c + 8.078677503112928 * m +
|
||||
30.89978309703729 * y - 0.23883238689178934 * k -
|
||||
14.183576799673286) +
|
||||
m * (10.49593273432072 * m + 63.02378494754052 * y +
|
||||
50.606957656360734 * k - 112.23884253719248) +
|
||||
y * (0.03296041114873217 * y + 115.60384449646641 * k -
|
||||
193.58209356861505) -
|
||||
data[offset++] =
|
||||
255 +
|
||||
c *
|
||||
(0.8842522430003296 * c +
|
||||
8.078677503112928 * m +
|
||||
30.89978309703729 * y -
|
||||
0.23883238689178934 * k -
|
||||
14.183576799673286) +
|
||||
m *
|
||||
(10.49593273432072 * m +
|
||||
63.02378494754052 * y +
|
||||
50.606957656360734 * k -
|
||||
112.23884253719248) +
|
||||
y *
|
||||
(0.03296041114873217 * y +
|
||||
115.60384449646641 * k -
|
||||
193.58209356861505) -
|
||||
k * (22.33816807309886 * k + 180.12613974708367);
|
||||
}
|
||||
// Ensure that only the converted RGB data is returned.
|
||||
return data.subarray(0, offset);
|
||||
},
|
||||
|
||||
getData({ width, height, forceRGB = false, isSourcePDF = false, }) {
|
||||
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('TESTING && !LIB')) {
|
||||
assert(isSourcePDF === true,
|
||||
'JpegImage.getData: Unexpected "isSourcePDF" value for PDF files.');
|
||||
getData({ width, height, forceRGB = false, isSourcePDF = false }) {
|
||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING && !LIB")) {
|
||||
assert(
|
||||
isSourcePDF === true,
|
||||
'JpegImage.getData: Unexpected "isSourcePDF" value for PDF files.'
|
||||
);
|
||||
}
|
||||
if (this.numComponents > 4) {
|
||||
throw new JpegError('Unsupported color mode');
|
||||
throw new JpegError("Unsupported color mode");
|
||||
}
|
||||
// Type of data: Uint8ClampedArray(width * height * numComponents)
|
||||
var data = this._getLinearizedBlockData(width, height, isSourcePDF);
|
||||
|
@ -1210,6 +1338,4 @@ var JpegImage = (function JpegImageClosure() {
|
|||
return JpegImage;
|
||||
})();
|
||||
|
||||
export {
|
||||
JpegImage,
|
||||
};
|
||||
export { JpegImage };
|
||||
|
|
631
src/core/jpx.js
631
src/core/jpx.js
File diff suppressed because it is too large
Load diff
|
@ -13,9 +13,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DecodeStream } from './stream';
|
||||
import { JpxImage } from './jpx';
|
||||
import { shadow } from '../shared/util';
|
||||
import { DecodeStream } from "./stream";
|
||||
import { JpxImage } from "./jpx";
|
||||
import { shadow } from "../shared/util";
|
||||
|
||||
/**
|
||||
* For JPEG 2000's we use a library to decode these images and
|
||||
|
@ -33,10 +33,10 @@ let JpxStream = (function JpxStreamClosure() {
|
|||
|
||||
JpxStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
Object.defineProperty(JpxStream.prototype, 'bytes', {
|
||||
Object.defineProperty(JpxStream.prototype, "bytes", {
|
||||
get: function JpxStream_bytes() {
|
||||
// If `this.maybeLength` is null, we'll get the entire stream.
|
||||
return shadow(this, 'bytes', this.stream.getBytes(this.maybeLength));
|
||||
return shadow(this, "bytes", this.stream.getBytes(this.maybeLength));
|
||||
},
|
||||
configurable: true,
|
||||
});
|
||||
|
@ -91,6 +91,4 @@ let JpxStream = (function JpxStreamClosure() {
|
|||
return JpxStream;
|
||||
})();
|
||||
|
||||
export {
|
||||
JpxStream,
|
||||
};
|
||||
export { JpxStream };
|
||||
|
|
5860
src/core/metrics.js
5860
src/core/metrics.js
File diff suppressed because it is too large
Load diff
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
/* eslint no-var: error */
|
||||
|
||||
import { isArrayBuffer, isString } from '../shared/util';
|
||||
import { isArrayBuffer, isString } from "../shared/util";
|
||||
|
||||
const SEED = 0xc3d2e1f0;
|
||||
// Workaround for missing math precision in JS.
|
||||
|
@ -49,35 +49,41 @@ class MurmurHash3_64 {
|
|||
data = input;
|
||||
length = data.byteLength;
|
||||
} else {
|
||||
throw new Error('Wrong data format in MurmurHash3_64_update. ' +
|
||||
'Input must be a string or array.');
|
||||
throw new Error(
|
||||
"Wrong data format in MurmurHash3_64_update. " +
|
||||
"Input must be a string or array."
|
||||
);
|
||||
}
|
||||
|
||||
const blockCounts = length >> 2;
|
||||
const tailLength = length - blockCounts * 4;
|
||||
// We don't care about endianness here.
|
||||
const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts);
|
||||
let k1 = 0, k2 = 0;
|
||||
let h1 = this.h1, h2 = this.h2;
|
||||
const C1 = 0xcc9e2d51, C2 = 0x1b873593;
|
||||
const C1_LOW = C1 & MASK_LOW, C2_LOW = C2 & MASK_LOW;
|
||||
let k1 = 0,
|
||||
k2 = 0;
|
||||
let h1 = this.h1,
|
||||
h2 = this.h2;
|
||||
const C1 = 0xcc9e2d51,
|
||||
C2 = 0x1b873593;
|
||||
const C1_LOW = C1 & MASK_LOW,
|
||||
C2_LOW = C2 & MASK_LOW;
|
||||
|
||||
for (let i = 0; i < blockCounts; i++) {
|
||||
if (i & 1) {
|
||||
k1 = dataUint32[i];
|
||||
k1 = (k1 * C1 & MASK_HIGH) | (k1 * C1_LOW & MASK_LOW);
|
||||
k1 = k1 << 15 | k1 >>> 17;
|
||||
k1 = (k1 * C2 & MASK_HIGH) | (k1 * C2_LOW & MASK_LOW);
|
||||
k1 = ((k1 * C1) & MASK_HIGH) | ((k1 * C1_LOW) & MASK_LOW);
|
||||
k1 = (k1 << 15) | (k1 >>> 17);
|
||||
k1 = ((k1 * C2) & MASK_HIGH) | ((k1 * C2_LOW) & MASK_LOW);
|
||||
h1 ^= k1;
|
||||
h1 = h1 << 13 | h1 >>> 19;
|
||||
h1 = (h1 << 13) | (h1 >>> 19);
|
||||
h1 = h1 * 5 + 0xe6546b64;
|
||||
} else {
|
||||
k2 = dataUint32[i];
|
||||
k2 = (k2 * C1 & MASK_HIGH) | (k2 * C1_LOW & MASK_LOW);
|
||||
k2 = k2 << 15 | k2 >>> 17;
|
||||
k2 = (k2 * C2 & MASK_HIGH) | (k2 * C2_LOW & MASK_LOW);
|
||||
k2 = ((k2 * C1) & MASK_HIGH) | ((k2 * C1_LOW) & MASK_LOW);
|
||||
k2 = (k2 << 15) | (k2 >>> 17);
|
||||
k2 = ((k2 * C2) & MASK_HIGH) | ((k2 * C2_LOW) & MASK_LOW);
|
||||
h2 ^= k2;
|
||||
h2 = h2 << 13 | h2 >>> 19;
|
||||
h2 = (h2 << 13) | (h2 >>> 19);
|
||||
h2 = h2 * 5 + 0xe6546b64;
|
||||
}
|
||||
}
|
||||
|
@ -87,17 +93,17 @@ class MurmurHash3_64 {
|
|||
switch (tailLength) {
|
||||
case 3:
|
||||
k1 ^= data[blockCounts * 4 + 2] << 16;
|
||||
/* falls through */
|
||||
/* falls through */
|
||||
case 2:
|
||||
k1 ^= data[blockCounts * 4 + 1] << 8;
|
||||
/* falls through */
|
||||
/* falls through */
|
||||
case 1:
|
||||
k1 ^= data[blockCounts * 4];
|
||||
/* falls through */
|
||||
|
||||
k1 = (k1 * C1 & MASK_HIGH) | (k1 * C1_LOW & MASK_LOW);
|
||||
k1 = k1 << 15 | k1 >>> 17;
|
||||
k1 = (k1 * C2 & MASK_HIGH) | (k1 * C2_LOW & MASK_LOW);
|
||||
k1 = ((k1 * C1) & MASK_HIGH) | ((k1 * C1_LOW) & MASK_LOW);
|
||||
k1 = (k1 << 15) | (k1 >>> 17);
|
||||
k1 = ((k1 * C2) & MASK_HIGH) | ((k1 * C2_LOW) & MASK_LOW);
|
||||
if (blockCounts & 1) {
|
||||
h1 ^= k1;
|
||||
} else {
|
||||
|
@ -110,23 +116,25 @@ class MurmurHash3_64 {
|
|||
}
|
||||
|
||||
hexdigest() {
|
||||
let h1 = this.h1, h2 = this.h2;
|
||||
let h1 = this.h1,
|
||||
h2 = this.h2;
|
||||
|
||||
h1 ^= h2 >>> 1;
|
||||
h1 = (h1 * 0xed558ccd & MASK_HIGH) | (h1 * 0x8ccd & MASK_LOW);
|
||||
h2 = (h2 * 0xff51afd7 & MASK_HIGH) |
|
||||
(((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16);
|
||||
h1 = ((h1 * 0xed558ccd) & MASK_HIGH) | ((h1 * 0x8ccd) & MASK_LOW);
|
||||
h2 =
|
||||
((h2 * 0xff51afd7) & MASK_HIGH) |
|
||||
(((((h2 << 16) | (h1 >>> 16)) * 0xafd7ed55) & MASK_HIGH) >>> 16);
|
||||
h1 ^= h2 >>> 1;
|
||||
h1 = (h1 * 0x1a85ec53 & MASK_HIGH) | (h1 * 0xec53 & MASK_LOW);
|
||||
h2 = (h2 * 0xc4ceb9fe & MASK_HIGH) |
|
||||
(((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16);
|
||||
h1 = ((h1 * 0x1a85ec53) & MASK_HIGH) | ((h1 * 0xec53) & MASK_LOW);
|
||||
h2 =
|
||||
((h2 * 0xc4ceb9fe) & MASK_HIGH) |
|
||||
(((((h2 << 16) | (h1 >>> 16)) * 0xb9fe1a85) & MASK_HIGH) >>> 16);
|
||||
h1 ^= h2 >>> 1;
|
||||
|
||||
const hex1 = (h1 >>> 0).toString(16), hex2 = (h2 >>> 0).toString(16);
|
||||
return hex1.padStart(8, '0') + hex2.padStart(8, '0');
|
||||
const hex1 = (h1 >>> 0).toString(16),
|
||||
hex2 = (h2 >>> 0).toString(16);
|
||||
return hex1.padStart(8, "0") + hex2.padStart(8, "0");
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
MurmurHash3_64,
|
||||
};
|
||||
export { MurmurHash3_64 };
|
||||
|
|
990
src/core/obj.js
990
src/core/obj.js
File diff suppressed because it is too large
Load diff
|
@ -14,14 +14,14 @@
|
|||
*/
|
||||
/* eslint-disable no-unsanitized/method */
|
||||
|
||||
import { assert, ImageKind, OPS } from '../shared/util';
|
||||
import { assert, ImageKind, OPS } from "../shared/util";
|
||||
|
||||
var QueueOptimizer = (function QueueOptimizerClosure() {
|
||||
function addState(parentState, pattern, checkFn, iterateFn, processFn) {
|
||||
var state = parentState;
|
||||
for (var i = 0, ii = pattern.length - 1; i < ii; i++) {
|
||||
var item = pattern[i];
|
||||
state = (state[item] || (state[item] = []));
|
||||
state = state[item] || (state[item] = []);
|
||||
}
|
||||
state[pattern[pattern.length - 1]] = {
|
||||
checkFn,
|
||||
|
@ -30,8 +30,12 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
};
|
||||
}
|
||||
|
||||
function handlePaintSolidColorImageMask(iFirstSave, count, fnArray,
|
||||
argsArray) {
|
||||
function handlePaintSolidColorImageMask(
|
||||
iFirstSave,
|
||||
count,
|
||||
fnArray,
|
||||
argsArray
|
||||
) {
|
||||
// Handles special case of mainly LaTeX documents which use image masks to
|
||||
// draw lines with the current fill style.
|
||||
// 'count' groups of (save, transform, paintImageMaskXObject, restore)+
|
||||
|
@ -40,9 +44,13 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
for (var i = 0; i < count; i++) {
|
||||
var arg = argsArray[iFirstPIMXO + 4 * i];
|
||||
var imageMask = arg.length === 1 && arg[0];
|
||||
if (imageMask && imageMask.width === 1 && imageMask.height === 1 &&
|
||||
(!imageMask.data.length ||
|
||||
(imageMask.data.length === 1 && imageMask.data[0] === 0))) {
|
||||
if (
|
||||
imageMask &&
|
||||
imageMask.width === 1 &&
|
||||
imageMask.height === 1 &&
|
||||
(!imageMask.data.length ||
|
||||
(imageMask.data.length === 1 && imageMask.data[0] === 0))
|
||||
) {
|
||||
fnArray[iFirstPIMXO + 4 * i] = OPS.paintSolidColorImageMask;
|
||||
continue;
|
||||
}
|
||||
|
@ -55,7 +63,8 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
|
||||
// This replaces (save, transform, paintInlineImageXObject, restore)+
|
||||
// sequences with one |paintInlineImageXObjectGroup| operation.
|
||||
addState(InitialState,
|
||||
addState(
|
||||
InitialState,
|
||||
[OPS.save, OPS.transform, OPS.paintInlineImageXObject, OPS.restore],
|
||||
null,
|
||||
function iterateInlineImageGroup(context, i) {
|
||||
|
@ -80,23 +89,28 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
var MAX_WIDTH = 1000;
|
||||
var IMAGE_PADDING = 1;
|
||||
|
||||
var fnArray = context.fnArray, argsArray = context.argsArray;
|
||||
var fnArray = context.fnArray,
|
||||
argsArray = context.argsArray;
|
||||
var curr = context.iCurr;
|
||||
var iFirstSave = curr - 3;
|
||||
var iFirstTransform = curr - 2;
|
||||
var iFirstPIIXO = curr - 1;
|
||||
|
||||
var count = Math.min(Math.floor((i - iFirstSave) / 4),
|
||||
MAX_IMAGES_IN_INLINE_IMAGES_BLOCK);
|
||||
var count = Math.min(
|
||||
Math.floor((i - iFirstSave) / 4),
|
||||
MAX_IMAGES_IN_INLINE_IMAGES_BLOCK
|
||||
);
|
||||
if (count < MIN_IMAGES_IN_INLINE_IMAGES_BLOCK) {
|
||||
return i - (i - iFirstSave) % 4;
|
||||
return i - ((i - iFirstSave) % 4);
|
||||
}
|
||||
|
||||
// assuming that heights of those image is too small (~1 pixel)
|
||||
// packing as much as possible by lines
|
||||
var maxX = 0;
|
||||
var map = [], maxLineHeight = 0;
|
||||
var currentX = IMAGE_PADDING, currentY = IMAGE_PADDING;
|
||||
var map = [],
|
||||
maxLineHeight = 0;
|
||||
var currentX = IMAGE_PADDING,
|
||||
currentY = IMAGE_PADDING;
|
||||
var q;
|
||||
for (q = 0; q < count; q++) {
|
||||
var transform = argsArray[iFirstTransform + (q << 2)];
|
||||
|
@ -110,8 +124,10 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
}
|
||||
map.push({
|
||||
transform,
|
||||
x: currentX, y: currentY,
|
||||
w: img.width, h: img.height,
|
||||
x: currentX,
|
||||
y: currentY,
|
||||
w: img.width,
|
||||
h: img.height,
|
||||
});
|
||||
currentX += img.width + 2 * IMAGE_PADDING;
|
||||
maxLineHeight = Math.max(maxLineHeight, img.height);
|
||||
|
@ -148,17 +164,25 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
|
||||
// Replace queue items.
|
||||
fnArray.splice(iFirstSave, count * 4, OPS.paintInlineImageXObjectGroup);
|
||||
argsArray.splice(iFirstSave, count * 4,
|
||||
[{ width: imgWidth, height: imgHeight, kind: ImageKind.RGBA_32BPP,
|
||||
data: imgData, }, map]);
|
||||
argsArray.splice(iFirstSave, count * 4, [
|
||||
{
|
||||
width: imgWidth,
|
||||
height: imgHeight,
|
||||
kind: ImageKind.RGBA_32BPP,
|
||||
data: imgData,
|
||||
},
|
||||
map,
|
||||
]);
|
||||
|
||||
return iFirstSave + 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// This replaces (save, transform, paintImageMaskXObject, restore)+
|
||||
// sequences with one |paintImageMaskXObjectGroup| or one
|
||||
// |paintImageMaskXObjectRepeat| operation.
|
||||
addState(InitialState,
|
||||
addState(
|
||||
InitialState,
|
||||
[OPS.save, OPS.transform, OPS.paintImageMaskXObject, OPS.restore],
|
||||
null,
|
||||
function iterateImageMaskGroup(context, i) {
|
||||
|
@ -182,7 +206,8 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
var MAX_IMAGES_IN_MASKS_BLOCK = 100;
|
||||
var MAX_SAME_IMAGES_IN_MASKS_BLOCK = 1000;
|
||||
|
||||
var fnArray = context.fnArray, argsArray = context.argsArray;
|
||||
var fnArray = context.fnArray,
|
||||
argsArray = context.argsArray;
|
||||
var curr = context.iCurr;
|
||||
var iFirstSave = curr - 3;
|
||||
var iFirstTransform = curr - 2;
|
||||
|
@ -191,18 +216,24 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
// At this point, i is the index of the first op past the last valid
|
||||
// quartet.
|
||||
var count = Math.floor((i - iFirstSave) / 4);
|
||||
count = handlePaintSolidColorImageMask(iFirstSave, count, fnArray,
|
||||
argsArray);
|
||||
count = handlePaintSolidColorImageMask(
|
||||
iFirstSave,
|
||||
count,
|
||||
fnArray,
|
||||
argsArray
|
||||
);
|
||||
if (count < MIN_IMAGES_IN_MASKS_BLOCK) {
|
||||
return i - (i - iFirstSave) % 4;
|
||||
return i - ((i - iFirstSave) % 4);
|
||||
}
|
||||
|
||||
var q;
|
||||
var isSameImage = false;
|
||||
var iTransform, transformArgs;
|
||||
var firstPIMXOArg0 = argsArray[iFirstPIMXO][0];
|
||||
if (argsArray[iFirstTransform][1] === 0 &&
|
||||
argsArray[iFirstTransform][2] === 0) {
|
||||
if (
|
||||
argsArray[iFirstTransform][1] === 0 &&
|
||||
argsArray[iFirstTransform][2] === 0
|
||||
) {
|
||||
isSameImage = true;
|
||||
var firstTransformArg0 = argsArray[iFirstTransform][0];
|
||||
var firstTransformArg3 = argsArray[iFirstTransform][3];
|
||||
|
@ -210,11 +241,13 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
var iPIMXO = iFirstPIMXO + 4;
|
||||
for (q = 1; q < count; q++, iTransform += 4, iPIMXO += 4) {
|
||||
transformArgs = argsArray[iTransform];
|
||||
if (argsArray[iPIMXO][0] !== firstPIMXOArg0 ||
|
||||
transformArgs[0] !== firstTransformArg0 ||
|
||||
transformArgs[1] !== 0 ||
|
||||
transformArgs[2] !== 0 ||
|
||||
transformArgs[3] !== firstTransformArg3) {
|
||||
if (
|
||||
argsArray[iPIMXO][0] !== firstPIMXOArg0 ||
|
||||
transformArgs[0] !== firstTransformArg0 ||
|
||||
transformArgs[1] !== 0 ||
|
||||
transformArgs[2] !== 0 ||
|
||||
transformArgs[3] !== firstTransformArg3
|
||||
) {
|
||||
if (q < MIN_IMAGES_IN_MASKS_BLOCK) {
|
||||
isSameImage = false;
|
||||
} else {
|
||||
|
@ -231,23 +264,30 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
iTransform = iFirstTransform;
|
||||
for (q = 0; q < count; q++, iTransform += 4) {
|
||||
transformArgs = argsArray[iTransform];
|
||||
positions[(q << 1)] = transformArgs[4];
|
||||
positions[q << 1] = transformArgs[4];
|
||||
positions[(q << 1) + 1] = transformArgs[5];
|
||||
}
|
||||
|
||||
// Replace queue items.
|
||||
fnArray.splice(iFirstSave, count * 4, OPS.paintImageMaskXObjectRepeat);
|
||||
argsArray.splice(iFirstSave, count * 4,
|
||||
[firstPIMXOArg0, firstTransformArg0, firstTransformArg3, positions]);
|
||||
argsArray.splice(iFirstSave, count * 4, [
|
||||
firstPIMXOArg0,
|
||||
firstTransformArg0,
|
||||
firstTransformArg3,
|
||||
positions,
|
||||
]);
|
||||
} else {
|
||||
count = Math.min(count, MAX_IMAGES_IN_MASKS_BLOCK);
|
||||
var images = [];
|
||||
for (q = 0; q < count; q++) {
|
||||
transformArgs = argsArray[iFirstTransform + (q << 2)];
|
||||
var maskParams = argsArray[iFirstPIMXO + (q << 2)][0];
|
||||
images.push({ data: maskParams.data, width: maskParams.width,
|
||||
height: maskParams.height,
|
||||
transform: transformArgs, });
|
||||
images.push({
|
||||
data: maskParams.data,
|
||||
width: maskParams.width,
|
||||
height: maskParams.height,
|
||||
transform: transformArgs,
|
||||
});
|
||||
}
|
||||
|
||||
// Replace queue items.
|
||||
|
@ -256,21 +296,26 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
}
|
||||
|
||||
return iFirstSave + 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// This replaces (save, transform, paintImageXObject, restore)+ sequences
|
||||
// with one paintImageXObjectRepeat operation, if the |transform| and
|
||||
// |paintImageXObjectRepeat| ops are appropriate.
|
||||
addState(InitialState,
|
||||
addState(
|
||||
InitialState,
|
||||
[OPS.save, OPS.transform, OPS.paintImageXObject, OPS.restore],
|
||||
function (context) {
|
||||
function(context) {
|
||||
var argsArray = context.argsArray;
|
||||
var iFirstTransform = context.iCurr - 2;
|
||||
return argsArray[iFirstTransform][1] === 0 &&
|
||||
argsArray[iFirstTransform][2] === 0;
|
||||
return (
|
||||
argsArray[iFirstTransform][1] === 0 &&
|
||||
argsArray[iFirstTransform][2] === 0
|
||||
);
|
||||
},
|
||||
function iterateImageGroup(context, i) {
|
||||
var fnArray = context.fnArray, argsArray = context.argsArray;
|
||||
var fnArray = context.fnArray,
|
||||
argsArray = context.argsArray;
|
||||
var iFirstSave = context.iCurr - 3;
|
||||
var pos = (i - iFirstSave) % 4;
|
||||
switch (pos) {
|
||||
|
@ -283,10 +328,12 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
var iFirstTransform = context.iCurr - 2;
|
||||
var firstTransformArg0 = argsArray[iFirstTransform][0];
|
||||
var firstTransformArg3 = argsArray[iFirstTransform][3];
|
||||
if (argsArray[i][0] !== firstTransformArg0 ||
|
||||
argsArray[i][1] !== 0 ||
|
||||
argsArray[i][2] !== 0 ||
|
||||
argsArray[i][3] !== firstTransformArg3) {
|
||||
if (
|
||||
argsArray[i][0] !== firstTransformArg0 ||
|
||||
argsArray[i][1] !== 0 ||
|
||||
argsArray[i][2] !== 0 ||
|
||||
argsArray[i][3] !== firstTransformArg3
|
||||
) {
|
||||
return false; // transforms don't match
|
||||
}
|
||||
return true;
|
||||
|
@ -305,11 +352,12 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
}
|
||||
throw new Error(`iterateImageGroup - invalid pos: ${pos}`);
|
||||
},
|
||||
function (context, i) {
|
||||
function(context, i) {
|
||||
var MIN_IMAGES_IN_BLOCK = 3;
|
||||
var MAX_IMAGES_IN_BLOCK = 1000;
|
||||
|
||||
var fnArray = context.fnArray, argsArray = context.argsArray;
|
||||
var fnArray = context.fnArray,
|
||||
argsArray = context.argsArray;
|
||||
var curr = context.iCurr;
|
||||
var iFirstSave = curr - 3;
|
||||
var iFirstTransform = curr - 2;
|
||||
|
@ -320,10 +368,12 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
|
||||
// At this point, i is the index of the first op past the last valid
|
||||
// quartet.
|
||||
var count = Math.min(Math.floor((i - iFirstSave) / 4),
|
||||
MAX_IMAGES_IN_BLOCK);
|
||||
var count = Math.min(
|
||||
Math.floor((i - iFirstSave) / 4),
|
||||
MAX_IMAGES_IN_BLOCK
|
||||
);
|
||||
if (count < MIN_IMAGES_IN_BLOCK) {
|
||||
return i - (i - iFirstSave) % 4;
|
||||
return i - ((i - iFirstSave) % 4);
|
||||
}
|
||||
|
||||
// Extract the (x,y) positions from all of the matching transforms.
|
||||
|
@ -331,27 +381,34 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
var iTransform = iFirstTransform;
|
||||
for (var q = 0; q < count; q++, iTransform += 4) {
|
||||
var transformArgs = argsArray[iTransform];
|
||||
positions[(q << 1)] = transformArgs[4];
|
||||
positions[q << 1] = transformArgs[4];
|
||||
positions[(q << 1) + 1] = transformArgs[5];
|
||||
}
|
||||
|
||||
// Replace queue items.
|
||||
var args = [firstPIXOArg0, firstTransformArg0, firstTransformArg3,
|
||||
positions];
|
||||
var args = [
|
||||
firstPIXOArg0,
|
||||
firstTransformArg0,
|
||||
firstTransformArg3,
|
||||
positions,
|
||||
];
|
||||
fnArray.splice(iFirstSave, count * 4, OPS.paintImageXObjectRepeat);
|
||||
argsArray.splice(iFirstSave, count * 4, args);
|
||||
|
||||
return iFirstSave + 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// This replaces (beginText, setFont, setTextMatrix, showText, endText)+
|
||||
// sequences with (beginText, setFont, (setTextMatrix, showText)+, endText)+
|
||||
// sequences, if the font for each one is the same.
|
||||
addState(InitialState,
|
||||
addState(
|
||||
InitialState,
|
||||
[OPS.beginText, OPS.setFont, OPS.setTextMatrix, OPS.showText, OPS.endText],
|
||||
null,
|
||||
function iterateShowTextGroup(context, i) {
|
||||
var fnArray = context.fnArray, argsArray = context.argsArray;
|
||||
var fnArray = context.fnArray,
|
||||
argsArray = context.argsArray;
|
||||
var iFirstSave = context.iCurr - 4;
|
||||
var pos = (i - iFirstSave) % 5;
|
||||
switch (pos) {
|
||||
|
@ -368,8 +425,10 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
var iFirstSetFont = context.iCurr - 3;
|
||||
var firstSetFontArg0 = argsArray[iFirstSetFont][0];
|
||||
var firstSetFontArg1 = argsArray[iFirstSetFont][1];
|
||||
if (argsArray[i][0] !== firstSetFontArg0 ||
|
||||
argsArray[i][1] !== firstSetFontArg1) {
|
||||
if (
|
||||
argsArray[i][0] !== firstSetFontArg0 ||
|
||||
argsArray[i][1] !== firstSetFontArg1
|
||||
) {
|
||||
return false; // fonts don't match
|
||||
}
|
||||
return true;
|
||||
|
@ -378,11 +437,12 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
}
|
||||
throw new Error(`iterateShowTextGroup - invalid pos: ${pos}`);
|
||||
},
|
||||
function (context, i) {
|
||||
function(context, i) {
|
||||
var MIN_CHARS_IN_BLOCK = 3;
|
||||
var MAX_CHARS_IN_BLOCK = 1000;
|
||||
|
||||
var fnArray = context.fnArray, argsArray = context.argsArray;
|
||||
var fnArray = context.fnArray,
|
||||
argsArray = context.argsArray;
|
||||
var curr = context.iCurr;
|
||||
var iFirstBeginText = curr - 4;
|
||||
var iFirstSetFont = curr - 3;
|
||||
|
@ -394,23 +454,27 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
|
||||
// At this point, i is the index of the first op past the last valid
|
||||
// quintet.
|
||||
var count = Math.min(Math.floor((i - iFirstBeginText) / 5),
|
||||
MAX_CHARS_IN_BLOCK);
|
||||
var count = Math.min(
|
||||
Math.floor((i - iFirstBeginText) / 5),
|
||||
MAX_CHARS_IN_BLOCK
|
||||
);
|
||||
if (count < MIN_CHARS_IN_BLOCK) {
|
||||
return i - (i - iFirstBeginText) % 5;
|
||||
return i - ((i - iFirstBeginText) % 5);
|
||||
}
|
||||
|
||||
// If the preceding quintet is (<something>, setFont, setTextMatrix,
|
||||
// showText, endText), include that as well. (E.g. <something> might be
|
||||
// |dependency|.)
|
||||
var iFirst = iFirstBeginText;
|
||||
if (iFirstBeginText >= 4 &&
|
||||
fnArray[iFirstBeginText - 4] === fnArray[iFirstSetFont] &&
|
||||
fnArray[iFirstBeginText - 3] === fnArray[iFirstSetTextMatrix] &&
|
||||
fnArray[iFirstBeginText - 2] === fnArray[iFirstShowText] &&
|
||||
fnArray[iFirstBeginText - 1] === fnArray[iFirstEndText] &&
|
||||
argsArray[iFirstBeginText - 4][0] === firstSetFontArg0 &&
|
||||
argsArray[iFirstBeginText - 4][1] === firstSetFontArg1) {
|
||||
if (
|
||||
iFirstBeginText >= 4 &&
|
||||
fnArray[iFirstBeginText - 4] === fnArray[iFirstSetFont] &&
|
||||
fnArray[iFirstBeginText - 3] === fnArray[iFirstSetTextMatrix] &&
|
||||
fnArray[iFirstBeginText - 2] === fnArray[iFirstShowText] &&
|
||||
fnArray[iFirstBeginText - 1] === fnArray[iFirstEndText] &&
|
||||
argsArray[iFirstBeginText - 4][0] === firstSetFontArg0 &&
|
||||
argsArray[iFirstBeginText - 4][1] === firstSetFontArg1
|
||||
) {
|
||||
count++;
|
||||
iFirst -= 5;
|
||||
}
|
||||
|
@ -424,7 +488,8 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
}
|
||||
|
||||
return iEndText + 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
function QueueOptimizer(queue) {
|
||||
this.queue = queue;
|
||||
|
@ -442,10 +507,11 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
|
|||
_optimize() {
|
||||
// Process new fnArray item(s) chunk.
|
||||
const fnArray = this.queue.fnArray;
|
||||
let i = this.lastProcessed, ii = fnArray.length;
|
||||
let i = this.lastProcessed,
|
||||
ii = fnArray.length;
|
||||
let state = this.state;
|
||||
let match = this.match;
|
||||
if (!state && !match && (i + 1 === ii) && !InitialState[fnArray[i]]) {
|
||||
if (!state && !match && i + 1 === ii && !InitialState[fnArray[i]]) {
|
||||
// Micro-optimization for the common case: last item is not
|
||||
// optimizable, just skipping it.
|
||||
this.lastProcessed = ii;
|
||||
|
@ -529,9 +595,9 @@ var NullOptimizer = (function NullOptimizerClosure() {
|
|||
this.queue.argsArray.push(args);
|
||||
},
|
||||
|
||||
flush() { },
|
||||
flush() {},
|
||||
|
||||
reset() { },
|
||||
reset() {},
|
||||
};
|
||||
|
||||
return NullOptimizer;
|
||||
|
@ -545,7 +611,7 @@ var OperatorList = (function OperatorListClosure() {
|
|||
this._streamSink = streamSink;
|
||||
this.fnArray = [];
|
||||
this.argsArray = [];
|
||||
if (streamSink && intent !== 'oplist') {
|
||||
if (streamSink && intent !== "oplist") {
|
||||
this.optimizer = new QueueOptimizer(this);
|
||||
} else {
|
||||
this.optimizer = new NullOptimizer(this);
|
||||
|
@ -572,7 +638,7 @@ var OperatorList = (function OperatorListClosure() {
|
|||
* `this.length === 0` after flushing.
|
||||
*/
|
||||
get totalLength() {
|
||||
return (this._totalLength + this.length);
|
||||
return this._totalLength + this.length;
|
||||
},
|
||||
|
||||
addOp(fn, args) {
|
||||
|
@ -581,8 +647,10 @@ var OperatorList = (function OperatorListClosure() {
|
|||
if (this._streamSink) {
|
||||
if (this.weight >= CHUNK_SIZE) {
|
||||
this.flush();
|
||||
} else if (this.weight >= CHUNK_SIZE_ABOUT &&
|
||||
(fn === OPS.restore || fn === OPS.endText)) {
|
||||
} else if (
|
||||
this.weight >= CHUNK_SIZE_ABOUT &&
|
||||
(fn === OPS.restore || fn === OPS.endText)
|
||||
) {
|
||||
// heuristic to flush on boundary of restore or endText
|
||||
this.flush();
|
||||
}
|
||||
|
@ -620,7 +688,7 @@ var OperatorList = (function OperatorListClosure() {
|
|||
|
||||
get _transfers() {
|
||||
const transfers = [];
|
||||
const { fnArray, argsArray, length, } = this;
|
||||
const { fnArray, argsArray, length } = this;
|
||||
for (let i = 0; i < length; i++) {
|
||||
switch (fnArray[i]) {
|
||||
case OPS.paintInlineImageXObject:
|
||||
|
@ -628,10 +696,14 @@ var OperatorList = (function OperatorListClosure() {
|
|||
case OPS.paintImageMaskXObject:
|
||||
const arg = argsArray[i][0]; // first param in imgData
|
||||
|
||||
if (typeof PDFJSDev === 'undefined' ||
|
||||
PDFJSDev.test('!PRODUCTION || TESTING')) {
|
||||
assert(arg.data instanceof Uint8ClampedArray,
|
||||
'OperatorList._transfers: Unsupported "arg.data" type.');
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(
|
||||
arg.data instanceof Uint8ClampedArray,
|
||||
'OperatorList._transfers: Unsupported "arg.data" type.'
|
||||
);
|
||||
}
|
||||
if (!arg.cached) {
|
||||
transfers.push(arg.data.buffer);
|
||||
|
@ -647,12 +719,16 @@ var OperatorList = (function OperatorListClosure() {
|
|||
const length = this.length;
|
||||
this._totalLength += length;
|
||||
|
||||
this._streamSink.enqueue({
|
||||
fnArray: this.fnArray,
|
||||
argsArray: this.argsArray,
|
||||
lastChunk,
|
||||
length,
|
||||
}, 1, this._transfers);
|
||||
this._streamSink.enqueue(
|
||||
{
|
||||
fnArray: this.fnArray,
|
||||
argsArray: this.argsArray,
|
||||
lastChunk,
|
||||
length,
|
||||
},
|
||||
1,
|
||||
this._transfers
|
||||
);
|
||||
|
||||
this.dependencies = Object.create(null);
|
||||
this.fnArray.length = 0;
|
||||
|
@ -665,6 +741,4 @@ var OperatorList = (function OperatorListClosure() {
|
|||
return OperatorList;
|
||||
})();
|
||||
|
||||
export {
|
||||
OperatorList,
|
||||
};
|
||||
export { OperatorList };
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,11 +15,17 @@
|
|||
/* eslint-disable no-multi-spaces */
|
||||
|
||||
import {
|
||||
assert, FormatError, info, unreachable, UNSUPPORTED_FEATURES, Util, warn
|
||||
} from '../shared/util';
|
||||
import { ColorSpace } from './colorspace';
|
||||
import { isStream } from './primitives';
|
||||
import { MissingDataException } from './core_utils';
|
||||
assert,
|
||||
FormatError,
|
||||
info,
|
||||
unreachable,
|
||||
UNSUPPORTED_FEATURES,
|
||||
Util,
|
||||
warn,
|
||||
} from "../shared/util";
|
||||
import { ColorSpace } from "./colorspace";
|
||||
import { isStream } from "./primitives";
|
||||
import { MissingDataException } from "./core_utils";
|
||||
|
||||
var ShadingType = {
|
||||
FUNCTION_BASED: 1,
|
||||
|
@ -34,7 +40,7 @@ var ShadingType = {
|
|||
var Pattern = (function PatternClosure() {
|
||||
// Constructor should define this.getPattern
|
||||
function Pattern() {
|
||||
unreachable('should not call Pattern constructor');
|
||||
unreachable("should not call Pattern constructor");
|
||||
}
|
||||
|
||||
Pattern.prototype = {
|
||||
|
@ -45,33 +51,50 @@ var Pattern = (function PatternClosure() {
|
|||
},
|
||||
};
|
||||
|
||||
Pattern.parseShading = function(shading, matrix, xref, res, handler,
|
||||
pdfFunctionFactory) {
|
||||
Pattern.parseShading = function(
|
||||
shading,
|
||||
matrix,
|
||||
xref,
|
||||
res,
|
||||
handler,
|
||||
pdfFunctionFactory
|
||||
) {
|
||||
var dict = isStream(shading) ? shading.dict : shading;
|
||||
var type = dict.get('ShadingType');
|
||||
var type = dict.get("ShadingType");
|
||||
|
||||
try {
|
||||
switch (type) {
|
||||
case ShadingType.AXIAL:
|
||||
case ShadingType.RADIAL:
|
||||
// Both radial and axial shadings are handled by RadialAxial shading.
|
||||
return new Shadings.RadialAxial(dict, matrix, xref, res,
|
||||
pdfFunctionFactory);
|
||||
return new Shadings.RadialAxial(
|
||||
dict,
|
||||
matrix,
|
||||
xref,
|
||||
res,
|
||||
pdfFunctionFactory
|
||||
);
|
||||
case ShadingType.FREE_FORM_MESH:
|
||||
case ShadingType.LATTICE_FORM_MESH:
|
||||
case ShadingType.COONS_PATCH_MESH:
|
||||
case ShadingType.TENSOR_PATCH_MESH:
|
||||
return new Shadings.Mesh(shading, matrix, xref, res,
|
||||
pdfFunctionFactory);
|
||||
return new Shadings.Mesh(
|
||||
shading,
|
||||
matrix,
|
||||
xref,
|
||||
res,
|
||||
pdfFunctionFactory
|
||||
);
|
||||
default:
|
||||
throw new FormatError('Unsupported ShadingType: ' + type);
|
||||
throw new FormatError("Unsupported ShadingType: " + type);
|
||||
}
|
||||
} catch (ex) {
|
||||
if (ex instanceof MissingDataException) {
|
||||
throw ex;
|
||||
}
|
||||
handler.send('UnsupportedFeature',
|
||||
{ featureId: UNSUPPORTED_FEATURES.shadingPattern, });
|
||||
handler.send("UnsupportedFeature", {
|
||||
featureId: UNSUPPORTED_FEATURES.shadingPattern,
|
||||
});
|
||||
warn(ex);
|
||||
return new Shadings.Dummy();
|
||||
}
|
||||
|
@ -90,35 +113,39 @@ Shadings.SMALL_NUMBER = 1e-6;
|
|||
Shadings.RadialAxial = (function RadialAxialClosure() {
|
||||
function RadialAxial(dict, matrix, xref, res, pdfFunctionFactory) {
|
||||
this.matrix = matrix;
|
||||
this.coordsArr = dict.getArray('Coords');
|
||||
this.shadingType = dict.get('ShadingType');
|
||||
this.type = 'Pattern';
|
||||
var cs = dict.get('ColorSpace', 'CS');
|
||||
this.coordsArr = dict.getArray("Coords");
|
||||
this.shadingType = dict.get("ShadingType");
|
||||
this.type = "Pattern";
|
||||
var cs = dict.get("ColorSpace", "CS");
|
||||
cs = ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
|
||||
this.cs = cs;
|
||||
const bbox = dict.getArray('BBox');
|
||||
const bbox = dict.getArray("BBox");
|
||||
if (Array.isArray(bbox) && bbox.length === 4) {
|
||||
this.bbox = Util.normalizeRect(bbox);
|
||||
} else {
|
||||
this.bbox = null;
|
||||
}
|
||||
|
||||
var t0 = 0.0, t1 = 1.0;
|
||||
if (dict.has('Domain')) {
|
||||
var domainArr = dict.getArray('Domain');
|
||||
var t0 = 0.0,
|
||||
t1 = 1.0;
|
||||
if (dict.has("Domain")) {
|
||||
var domainArr = dict.getArray("Domain");
|
||||
t0 = domainArr[0];
|
||||
t1 = domainArr[1];
|
||||
}
|
||||
|
||||
var extendStart = false, extendEnd = false;
|
||||
if (dict.has('Extend')) {
|
||||
var extendArr = dict.getArray('Extend');
|
||||
var extendStart = false,
|
||||
extendEnd = false;
|
||||
if (dict.has("Extend")) {
|
||||
var extendArr = dict.getArray("Extend");
|
||||
extendStart = extendArr[0];
|
||||
extendEnd = extendArr[1];
|
||||
}
|
||||
|
||||
if (this.shadingType === ShadingType.RADIAL &&
|
||||
(!extendStart || !extendEnd)) {
|
||||
if (
|
||||
this.shadingType === ShadingType.RADIAL &&
|
||||
(!extendStart || !extendEnd)
|
||||
) {
|
||||
// Radial gradient only currently works if either circle is fully within
|
||||
// the other circle.
|
||||
var x1 = this.coordsArr[0];
|
||||
|
@ -128,16 +155,15 @@ Shadings.RadialAxial = (function RadialAxialClosure() {
|
|||
var y2 = this.coordsArr[4];
|
||||
var r2 = this.coordsArr[5];
|
||||
var distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
|
||||
if (r1 <= r2 + distance &&
|
||||
r2 <= r1 + distance) {
|
||||
warn('Unsupported radial gradient.');
|
||||
if (r1 <= r2 + distance && r2 <= r1 + distance) {
|
||||
warn("Unsupported radial gradient.");
|
||||
}
|
||||
}
|
||||
|
||||
this.extendStart = extendStart;
|
||||
this.extendEnd = extendEnd;
|
||||
|
||||
var fnObj = dict.get('Function');
|
||||
var fnObj = dict.get("Function");
|
||||
var fn = pdfFunctionFactory.createFromArray(fnObj);
|
||||
|
||||
// 10 samples seems good enough for now, but probably won't work
|
||||
|
@ -146,17 +172,18 @@ Shadings.RadialAxial = (function RadialAxialClosure() {
|
|||
const NUMBER_OF_SAMPLES = 10;
|
||||
const step = (t1 - t0) / NUMBER_OF_SAMPLES;
|
||||
|
||||
var colorStops = this.colorStops = [];
|
||||
var colorStops = (this.colorStops = []);
|
||||
|
||||
// Protect against bad domains.
|
||||
if (t0 >= t1 || step <= 0) {
|
||||
// Acrobat doesn't seem to handle these cases so we'll ignore for
|
||||
// now.
|
||||
info('Bad shading domain.');
|
||||
info("Bad shading domain.");
|
||||
return;
|
||||
}
|
||||
|
||||
var color = new Float32Array(cs.numComps), ratio = new Float32Array(1);
|
||||
var color = new Float32Array(cs.numComps),
|
||||
ratio = new Float32Array(1);
|
||||
var rgbColor;
|
||||
for (let i = 0; i <= NUMBER_OF_SAMPLES; i++) {
|
||||
ratio[0] = t0 + i * step;
|
||||
|
@ -166,9 +193,9 @@ Shadings.RadialAxial = (function RadialAxialClosure() {
|
|||
colorStops.push([i / NUMBER_OF_SAMPLES, cssColor]);
|
||||
}
|
||||
|
||||
var background = 'transparent';
|
||||
if (dict.has('Background')) {
|
||||
rgbColor = cs.getRgb(dict.get('Background'), 0);
|
||||
var background = "transparent";
|
||||
if (dict.has("Background")) {
|
||||
rgbColor = cs.getRgb(dict.get("Background"), 0);
|
||||
background = Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]);
|
||||
}
|
||||
|
||||
|
@ -197,13 +224,13 @@ Shadings.RadialAxial = (function RadialAxialClosure() {
|
|||
p1 = [coordsArr[2], coordsArr[3]];
|
||||
r0 = null;
|
||||
r1 = null;
|
||||
type = 'axial';
|
||||
type = "axial";
|
||||
} else if (shadingType === ShadingType.RADIAL) {
|
||||
p0 = [coordsArr[0], coordsArr[1]];
|
||||
p1 = [coordsArr[3], coordsArr[4]];
|
||||
r0 = coordsArr[2];
|
||||
r1 = coordsArr[5];
|
||||
type = 'radial';
|
||||
type = "radial";
|
||||
} else {
|
||||
unreachable(`getPattern type unknown: ${shadingType}`);
|
||||
}
|
||||
|
@ -219,7 +246,7 @@ Shadings.RadialAxial = (function RadialAxialClosure() {
|
|||
}
|
||||
}
|
||||
|
||||
return ['RadialAxial', type, this.bbox, this.colorStops, p0, p1, r0, r1];
|
||||
return ["RadialAxial", type, this.bbox, this.colorStops, p0, p1, r0, r1];
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -238,8 +265,9 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
var numComps = context.numComps;
|
||||
this.tmpCompsBuf = new Float32Array(numComps);
|
||||
var csNumComps = context.colorSpace.numComps;
|
||||
this.tmpCsCompsBuf = context.colorFn ? new Float32Array(csNumComps) :
|
||||
this.tmpCompsBuf;
|
||||
this.tmpCsCompsBuf = context.colorFn
|
||||
? new Float32Array(csNumComps)
|
||||
: this.tmpCompsBuf;
|
||||
}
|
||||
MeshStreamReader.prototype = {
|
||||
get hasData() {
|
||||
|
@ -262,16 +290,26 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
var bufferLength = this.bufferLength;
|
||||
if (n === 32) {
|
||||
if (bufferLength === 0) {
|
||||
return ((this.stream.getByte() << 24) |
|
||||
(this.stream.getByte() << 16) | (this.stream.getByte() << 8) |
|
||||
this.stream.getByte()) >>> 0;
|
||||
return (
|
||||
((this.stream.getByte() << 24) |
|
||||
(this.stream.getByte() << 16) |
|
||||
(this.stream.getByte() << 8) |
|
||||
this.stream.getByte()) >>>
|
||||
0
|
||||
);
|
||||
}
|
||||
buffer = (buffer << 24) | (this.stream.getByte() << 16) |
|
||||
(this.stream.getByte() << 8) | this.stream.getByte();
|
||||
buffer =
|
||||
(buffer << 24) |
|
||||
(this.stream.getByte() << 16) |
|
||||
(this.stream.getByte() << 8) |
|
||||
this.stream.getByte();
|
||||
var nextByte = this.stream.getByte();
|
||||
this.buffer = nextByte & ((1 << bufferLength) - 1);
|
||||
return ((buffer << (8 - bufferLength)) |
|
||||
((nextByte & 0xFF) >> bufferLength)) >>> 0;
|
||||
return (
|
||||
((buffer << (8 - bufferLength)) |
|
||||
((nextByte & 0xff) >> bufferLength)) >>>
|
||||
0
|
||||
);
|
||||
}
|
||||
if (n === 8 && bufferLength === 0) {
|
||||
return this.stream.getByte();
|
||||
|
@ -297,18 +335,22 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
var xi = this.readBits(bitsPerCoordinate);
|
||||
var yi = this.readBits(bitsPerCoordinate);
|
||||
var decode = this.context.decode;
|
||||
var scale = bitsPerCoordinate < 32 ? 1 / ((1 << bitsPerCoordinate) - 1) :
|
||||
2.3283064365386963e-10; // 2 ^ -32
|
||||
var scale =
|
||||
bitsPerCoordinate < 32
|
||||
? 1 / ((1 << bitsPerCoordinate) - 1)
|
||||
: 2.3283064365386963e-10; // 2 ^ -32
|
||||
return [
|
||||
xi * scale * (decode[1] - decode[0]) + decode[0],
|
||||
yi * scale * (decode[3] - decode[2]) + decode[2]
|
||||
yi * scale * (decode[3] - decode[2]) + decode[2],
|
||||
];
|
||||
},
|
||||
readComponents: function MeshStreamReader_readComponents() {
|
||||
var numComps = this.context.numComps;
|
||||
var bitsPerComponent = this.context.bitsPerComponent;
|
||||
var scale = bitsPerComponent < 32 ? 1 / ((1 << bitsPerComponent) - 1) :
|
||||
2.3283064365386963e-10; // 2 ^ -32
|
||||
var scale =
|
||||
bitsPerComponent < 32
|
||||
? 1 / ((1 << bitsPerComponent) - 1)
|
||||
: 2.3283064365386963e-10; // 2 ^ -32
|
||||
var decode = this.context.decode;
|
||||
var components = this.tmpCompsBuf;
|
||||
for (var i = 0, j = 4; i < numComps; i++, j += 2) {
|
||||
|
@ -333,9 +375,10 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
var f = reader.readFlag();
|
||||
var coord = reader.readCoordinate();
|
||||
var color = reader.readComponents();
|
||||
if (verticesLeft === 0) { // ignoring flags if we started a triangle
|
||||
if (verticesLeft === 0) {
|
||||
// ignoring flags if we started a triangle
|
||||
if (!(0 <= f && f <= 2)) {
|
||||
throw new FormatError('Unknown type4 flag');
|
||||
throw new FormatError("Unknown type4 flag");
|
||||
}
|
||||
switch (f) {
|
||||
case 0:
|
||||
|
@ -360,7 +403,7 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
reader.align();
|
||||
}
|
||||
mesh.figures.push({
|
||||
type: 'triangles',
|
||||
type: "triangles",
|
||||
coords: new Int32Array(ps),
|
||||
colors: new Int32Array(ps),
|
||||
});
|
||||
|
@ -378,7 +421,7 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
colors.push(color);
|
||||
}
|
||||
mesh.figures.push({
|
||||
type: 'lattice',
|
||||
type: "lattice",
|
||||
coords: new Int32Array(ps),
|
||||
colors: new Int32Array(ps),
|
||||
verticesPerRow,
|
||||
|
@ -394,9 +437,16 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
function buildB(count) {
|
||||
var lut = [];
|
||||
for (var i = 0; i <= count; i++) {
|
||||
var t = i / count, t_ = 1 - t;
|
||||
lut.push(new Float32Array([t_ * t_ * t_, 3 * t * t_ * t_,
|
||||
3 * t * t * t_, t * t * t]));
|
||||
var t = i / count,
|
||||
t_ = 1 - t;
|
||||
lut.push(
|
||||
new Float32Array([
|
||||
t_ * t_ * t_,
|
||||
3 * t * t_ * t_,
|
||||
3 * t * t * t_,
|
||||
t * t * t,
|
||||
])
|
||||
);
|
||||
}
|
||||
return lut;
|
||||
}
|
||||
|
@ -411,37 +461,66 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
|
||||
function buildFigureFromPatch(mesh, index) {
|
||||
var figure = mesh.figures[index];
|
||||
assert(figure.type === 'patch', 'Unexpected patch mesh figure');
|
||||
assert(figure.type === "patch", "Unexpected patch mesh figure");
|
||||
|
||||
var coords = mesh.coords, colors = mesh.colors;
|
||||
var coords = mesh.coords,
|
||||
colors = mesh.colors;
|
||||
var pi = figure.coords;
|
||||
var ci = figure.colors;
|
||||
|
||||
var figureMinX = Math.min(coords[pi[0]][0], coords[pi[3]][0],
|
||||
coords[pi[12]][0], coords[pi[15]][0]);
|
||||
var figureMinY = Math.min(coords[pi[0]][1], coords[pi[3]][1],
|
||||
coords[pi[12]][1], coords[pi[15]][1]);
|
||||
var figureMaxX = Math.max(coords[pi[0]][0], coords[pi[3]][0],
|
||||
coords[pi[12]][0], coords[pi[15]][0]);
|
||||
var figureMaxY = Math.max(coords[pi[0]][1], coords[pi[3]][1],
|
||||
coords[pi[12]][1], coords[pi[15]][1]);
|
||||
var splitXBy = Math.ceil((figureMaxX - figureMinX) * TRIANGLE_DENSITY /
|
||||
(mesh.bounds[2] - mesh.bounds[0]));
|
||||
splitXBy = Math.max(MIN_SPLIT_PATCH_CHUNKS_AMOUNT,
|
||||
Math.min(MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitXBy));
|
||||
var splitYBy = Math.ceil((figureMaxY - figureMinY) * TRIANGLE_DENSITY /
|
||||
(mesh.bounds[3] - mesh.bounds[1]));
|
||||
splitYBy = Math.max(MIN_SPLIT_PATCH_CHUNKS_AMOUNT,
|
||||
Math.min(MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitYBy));
|
||||
var figureMinX = Math.min(
|
||||
coords[pi[0]][0],
|
||||
coords[pi[3]][0],
|
||||
coords[pi[12]][0],
|
||||
coords[pi[15]][0]
|
||||
);
|
||||
var figureMinY = Math.min(
|
||||
coords[pi[0]][1],
|
||||
coords[pi[3]][1],
|
||||
coords[pi[12]][1],
|
||||
coords[pi[15]][1]
|
||||
);
|
||||
var figureMaxX = Math.max(
|
||||
coords[pi[0]][0],
|
||||
coords[pi[3]][0],
|
||||
coords[pi[12]][0],
|
||||
coords[pi[15]][0]
|
||||
);
|
||||
var figureMaxY = Math.max(
|
||||
coords[pi[0]][1],
|
||||
coords[pi[3]][1],
|
||||
coords[pi[12]][1],
|
||||
coords[pi[15]][1]
|
||||
);
|
||||
var splitXBy = Math.ceil(
|
||||
((figureMaxX - figureMinX) * TRIANGLE_DENSITY) /
|
||||
(mesh.bounds[2] - mesh.bounds[0])
|
||||
);
|
||||
splitXBy = Math.max(
|
||||
MIN_SPLIT_PATCH_CHUNKS_AMOUNT,
|
||||
Math.min(MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitXBy)
|
||||
);
|
||||
var splitYBy = Math.ceil(
|
||||
((figureMaxY - figureMinY) * TRIANGLE_DENSITY) /
|
||||
(mesh.bounds[3] - mesh.bounds[1])
|
||||
);
|
||||
splitYBy = Math.max(
|
||||
MIN_SPLIT_PATCH_CHUNKS_AMOUNT,
|
||||
Math.min(MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitYBy)
|
||||
);
|
||||
|
||||
var verticesPerRow = splitXBy + 1;
|
||||
var figureCoords = new Int32Array((splitYBy + 1) * verticesPerRow);
|
||||
var figureColors = new Int32Array((splitYBy + 1) * verticesPerRow);
|
||||
var k = 0;
|
||||
var cl = new Uint8Array(3), cr = new Uint8Array(3);
|
||||
var c0 = colors[ci[0]], c1 = colors[ci[1]],
|
||||
c2 = colors[ci[2]], c3 = colors[ci[3]];
|
||||
var bRow = getB(splitYBy), bCol = getB(splitXBy);
|
||||
var cl = new Uint8Array(3),
|
||||
cr = new Uint8Array(3);
|
||||
var c0 = colors[ci[0]],
|
||||
c1 = colors[ci[1]],
|
||||
c2 = colors[ci[2]],
|
||||
c3 = colors[ci[3]];
|
||||
var bRow = getB(splitYBy),
|
||||
bCol = getB(splitXBy);
|
||||
for (var row = 0; row <= splitYBy; row++) {
|
||||
cl[0] = ((c0[0] * (splitYBy - row) + c2[0] * row) / splitYBy) | 0;
|
||||
cl[1] = ((c0[1] * (splitYBy - row) + c2[1] * row) / splitYBy) | 0;
|
||||
|
@ -452,11 +531,14 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
cr[2] = ((c1[2] * (splitYBy - row) + c3[2] * row) / splitYBy) | 0;
|
||||
|
||||
for (var col = 0; col <= splitXBy; col++, k++) {
|
||||
if ((row === 0 || row === splitYBy) &&
|
||||
(col === 0 || col === splitXBy)) {
|
||||
if (
|
||||
(row === 0 || row === splitYBy) &&
|
||||
(col === 0 || col === splitXBy)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
var x = 0, y = 0;
|
||||
var x = 0,
|
||||
y = 0;
|
||||
var q = 0;
|
||||
for (var i = 0; i <= 3; i++) {
|
||||
for (var j = 0; j <= 3; j++, q++) {
|
||||
|
@ -485,7 +567,7 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
figureColors[verticesPerRow * splitYBy + splitXBy] = ci[3];
|
||||
|
||||
mesh.figures[index] = {
|
||||
type: 'lattice',
|
||||
type: "lattice",
|
||||
coords: figureCoords,
|
||||
colors: figureColors,
|
||||
verticesPerRow,
|
||||
|
@ -501,15 +583,15 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
while (reader.hasData) {
|
||||
var f = reader.readFlag();
|
||||
if (!(0 <= f && f <= 3)) {
|
||||
throw new FormatError('Unknown type6 flag');
|
||||
throw new FormatError("Unknown type6 flag");
|
||||
}
|
||||
var i, ii;
|
||||
var pi = coords.length;
|
||||
for (i = 0, ii = (f !== 0 ? 8 : 12); i < ii; i++) {
|
||||
for (i = 0, ii = f !== 0 ? 8 : 12; i < ii; i++) {
|
||||
coords.push(reader.readCoordinate());
|
||||
}
|
||||
var ci = colors.length;
|
||||
for (i = 0, ii = (f !== 0 ? 2 : 4); i < ii; i++) {
|
||||
for (i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {
|
||||
colors.push(reader.readComponents());
|
||||
}
|
||||
var tmp1, tmp2, tmp3, tmp4;
|
||||
|
@ -559,50 +641,66 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
// set p11, p12, p21, p22
|
||||
ps[5] = coords.length;
|
||||
coords.push([
|
||||
(-4 * coords[ps[0]][0] - coords[ps[15]][0] +
|
||||
(-4 * coords[ps[0]][0] -
|
||||
coords[ps[15]][0] +
|
||||
6 * (coords[ps[4]][0] + coords[ps[1]][0]) -
|
||||
2 * (coords[ps[12]][0] + coords[ps[3]][0]) +
|
||||
3 * (coords[ps[13]][0] + coords[ps[7]][0])) / 9,
|
||||
(-4 * coords[ps[0]][1] - coords[ps[15]][1] +
|
||||
3 * (coords[ps[13]][0] + coords[ps[7]][0])) /
|
||||
9,
|
||||
(-4 * coords[ps[0]][1] -
|
||||
coords[ps[15]][1] +
|
||||
6 * (coords[ps[4]][1] + coords[ps[1]][1]) -
|
||||
2 * (coords[ps[12]][1] + coords[ps[3]][1]) +
|
||||
3 * (coords[ps[13]][1] + coords[ps[7]][1])) / 9
|
||||
3 * (coords[ps[13]][1] + coords[ps[7]][1])) /
|
||||
9,
|
||||
]);
|
||||
ps[6] = coords.length;
|
||||
coords.push([
|
||||
(-4 * coords[ps[3]][0] - coords[ps[12]][0] +
|
||||
(-4 * coords[ps[3]][0] -
|
||||
coords[ps[12]][0] +
|
||||
6 * (coords[ps[2]][0] + coords[ps[7]][0]) -
|
||||
2 * (coords[ps[0]][0] + coords[ps[15]][0]) +
|
||||
3 * (coords[ps[4]][0] + coords[ps[14]][0])) / 9,
|
||||
(-4 * coords[ps[3]][1] - coords[ps[12]][1] +
|
||||
3 * (coords[ps[4]][0] + coords[ps[14]][0])) /
|
||||
9,
|
||||
(-4 * coords[ps[3]][1] -
|
||||
coords[ps[12]][1] +
|
||||
6 * (coords[ps[2]][1] + coords[ps[7]][1]) -
|
||||
2 * (coords[ps[0]][1] + coords[ps[15]][1]) +
|
||||
3 * (coords[ps[4]][1] + coords[ps[14]][1])) / 9
|
||||
3 * (coords[ps[4]][1] + coords[ps[14]][1])) /
|
||||
9,
|
||||
]);
|
||||
ps[9] = coords.length;
|
||||
coords.push([
|
||||
(-4 * coords[ps[12]][0] - coords[ps[3]][0] +
|
||||
(-4 * coords[ps[12]][0] -
|
||||
coords[ps[3]][0] +
|
||||
6 * (coords[ps[8]][0] + coords[ps[13]][0]) -
|
||||
2 * (coords[ps[0]][0] + coords[ps[15]][0]) +
|
||||
3 * (coords[ps[11]][0] + coords[ps[1]][0])) / 9,
|
||||
(-4 * coords[ps[12]][1] - coords[ps[3]][1] +
|
||||
3 * (coords[ps[11]][0] + coords[ps[1]][0])) /
|
||||
9,
|
||||
(-4 * coords[ps[12]][1] -
|
||||
coords[ps[3]][1] +
|
||||
6 * (coords[ps[8]][1] + coords[ps[13]][1]) -
|
||||
2 * (coords[ps[0]][1] + coords[ps[15]][1]) +
|
||||
3 * (coords[ps[11]][1] + coords[ps[1]][1])) / 9
|
||||
3 * (coords[ps[11]][1] + coords[ps[1]][1])) /
|
||||
9,
|
||||
]);
|
||||
ps[10] = coords.length;
|
||||
coords.push([
|
||||
(-4 * coords[ps[15]][0] - coords[ps[0]][0] +
|
||||
(-4 * coords[ps[15]][0] -
|
||||
coords[ps[0]][0] +
|
||||
6 * (coords[ps[11]][0] + coords[ps[14]][0]) -
|
||||
2 * (coords[ps[12]][0] + coords[ps[3]][0]) +
|
||||
3 * (coords[ps[2]][0] + coords[ps[8]][0])) / 9,
|
||||
(-4 * coords[ps[15]][1] - coords[ps[0]][1] +
|
||||
3 * (coords[ps[2]][0] + coords[ps[8]][0])) /
|
||||
9,
|
||||
(-4 * coords[ps[15]][1] -
|
||||
coords[ps[0]][1] +
|
||||
6 * (coords[ps[11]][1] + coords[ps[14]][1]) -
|
||||
2 * (coords[ps[12]][1] + coords[ps[3]][1]) +
|
||||
3 * (coords[ps[2]][1] + coords[ps[8]][1])) / 9
|
||||
3 * (coords[ps[2]][1] + coords[ps[8]][1])) /
|
||||
9,
|
||||
]);
|
||||
mesh.figures.push({
|
||||
type: 'patch',
|
||||
type: "patch",
|
||||
coords: new Int32Array(ps), // making copies of ps and cs
|
||||
colors: new Int32Array(cs),
|
||||
});
|
||||
|
@ -617,15 +715,15 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
while (reader.hasData) {
|
||||
var f = reader.readFlag();
|
||||
if (!(0 <= f && f <= 3)) {
|
||||
throw new FormatError('Unknown type7 flag');
|
||||
throw new FormatError("Unknown type7 flag");
|
||||
}
|
||||
var i, ii;
|
||||
var pi = coords.length;
|
||||
for (i = 0, ii = (f !== 0 ? 12 : 16); i < ii; i++) {
|
||||
for (i = 0, ii = f !== 0 ? 12 : 16; i < ii; i++) {
|
||||
coords.push(reader.readCoordinate());
|
||||
}
|
||||
var ci = colors.length;
|
||||
for (i = 0, ii = (f !== 0 ? 2 : 4); i < ii; i++) {
|
||||
for (i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {
|
||||
colors.push(reader.readComponents());
|
||||
}
|
||||
var tmp1, tmp2, tmp3, tmp4;
|
||||
|
@ -673,7 +771,7 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
break;
|
||||
}
|
||||
mesh.figures.push({
|
||||
type: 'patch',
|
||||
type: "patch",
|
||||
coords: new Int32Array(ps), // making copies of ps and cs
|
||||
colors: new Int32Array(cs),
|
||||
});
|
||||
|
@ -681,10 +779,13 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
}
|
||||
|
||||
function updateBounds(mesh) {
|
||||
var minX = mesh.coords[0][0], minY = mesh.coords[0][1],
|
||||
maxX = minX, maxY = minY;
|
||||
var minX = mesh.coords[0][0],
|
||||
minY = mesh.coords[0][1],
|
||||
maxX = minX,
|
||||
maxY = minY;
|
||||
for (var i = 1, ii = mesh.coords.length; i < ii; i++) {
|
||||
var x = mesh.coords[i][0], y = mesh.coords[i][1];
|
||||
var x = mesh.coords[i][0],
|
||||
y = mesh.coords[i][1];
|
||||
minX = minX > x ? x : minX;
|
||||
minY = minY > y ? y : minY;
|
||||
maxX = maxX < x ? x : maxX;
|
||||
|
@ -717,7 +818,9 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
|
||||
var figures = mesh.figures;
|
||||
for (i = 0, ii = figures.length; i < ii; i++) {
|
||||
var figure = figures[i], ps = figure.coords, cs = figure.colors;
|
||||
var figure = figures[i],
|
||||
ps = figure.coords,
|
||||
cs = figure.colors;
|
||||
for (j = 0, jj = ps.length; j < jj; j++) {
|
||||
ps[j] *= 2;
|
||||
cs[j] *= 3;
|
||||
|
@ -727,25 +830,26 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
|
||||
function Mesh(stream, matrix, xref, res, pdfFunctionFactory) {
|
||||
if (!isStream(stream)) {
|
||||
throw new FormatError('Mesh data is not a stream');
|
||||
throw new FormatError("Mesh data is not a stream");
|
||||
}
|
||||
var dict = stream.dict;
|
||||
this.matrix = matrix;
|
||||
this.shadingType = dict.get('ShadingType');
|
||||
this.type = 'Pattern';
|
||||
const bbox = dict.getArray('BBox');
|
||||
this.shadingType = dict.get("ShadingType");
|
||||
this.type = "Pattern";
|
||||
const bbox = dict.getArray("BBox");
|
||||
if (Array.isArray(bbox) && bbox.length === 4) {
|
||||
this.bbox = Util.normalizeRect(bbox);
|
||||
} else {
|
||||
this.bbox = null;
|
||||
}
|
||||
var cs = dict.get('ColorSpace', 'CS');
|
||||
var cs = dict.get("ColorSpace", "CS");
|
||||
cs = ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
|
||||
this.cs = cs;
|
||||
this.background = dict.has('Background') ?
|
||||
cs.getRgb(dict.get('Background'), 0) : null;
|
||||
this.background = dict.has("Background")
|
||||
? cs.getRgb(dict.get("Background"), 0)
|
||||
: null;
|
||||
|
||||
var fnObj = dict.get('Function');
|
||||
var fnObj = dict.get("Function");
|
||||
var fn = fnObj ? pdfFunctionFactory.createFromArray(fnObj) : null;
|
||||
|
||||
this.coords = [];
|
||||
|
@ -753,10 +857,10 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
this.figures = [];
|
||||
|
||||
var decodeContext = {
|
||||
bitsPerCoordinate: dict.get('BitsPerCoordinate'),
|
||||
bitsPerComponent: dict.get('BitsPerComponent'),
|
||||
bitsPerFlag: dict.get('BitsPerFlag'),
|
||||
decode: dict.getArray('Decode'),
|
||||
bitsPerCoordinate: dict.get("BitsPerCoordinate"),
|
||||
bitsPerComponent: dict.get("BitsPerComponent"),
|
||||
bitsPerFlag: dict.get("BitsPerFlag"),
|
||||
decode: dict.getArray("Decode"),
|
||||
colorFn: fn,
|
||||
colorSpace: cs,
|
||||
numComps: fn ? 1 : cs.numComps,
|
||||
|
@ -769,9 +873,9 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
decodeType4Shading(this, reader);
|
||||
break;
|
||||
case ShadingType.LATTICE_FORM_MESH:
|
||||
var verticesPerRow = dict.get('VerticesPerRow') | 0;
|
||||
var verticesPerRow = dict.get("VerticesPerRow") | 0;
|
||||
if (verticesPerRow < 2) {
|
||||
throw new FormatError('Invalid VerticesPerRow');
|
||||
throw new FormatError("Invalid VerticesPerRow");
|
||||
}
|
||||
decodeType5Shading(this, reader, verticesPerRow);
|
||||
break;
|
||||
|
@ -784,7 +888,7 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
patchMesh = true;
|
||||
break;
|
||||
default:
|
||||
unreachable('Unsupported mesh type.');
|
||||
unreachable("Unsupported mesh type.");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -803,8 +907,17 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
|
||||
Mesh.prototype = {
|
||||
getIR: function Mesh_getIR() {
|
||||
return ['Mesh', this.shadingType, this.coords, this.colors, this.figures,
|
||||
this.bounds, this.matrix, this.bbox, this.background];
|
||||
return [
|
||||
"Mesh",
|
||||
this.shadingType,
|
||||
this.coords,
|
||||
this.colors,
|
||||
this.figures,
|
||||
this.bounds,
|
||||
this.matrix,
|
||||
this.bbox,
|
||||
this.background,
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -813,38 +926,42 @@ Shadings.Mesh = (function MeshClosure() {
|
|||
|
||||
Shadings.Dummy = (function DummyClosure() {
|
||||
function Dummy() {
|
||||
this.type = 'Pattern';
|
||||
this.type = "Pattern";
|
||||
}
|
||||
|
||||
Dummy.prototype = {
|
||||
getIR: function Dummy_getIR() {
|
||||
return ['Dummy'];
|
||||
return ["Dummy"];
|
||||
},
|
||||
};
|
||||
return Dummy;
|
||||
})();
|
||||
|
||||
function getTilingPatternIR(operatorList, dict, args) {
|
||||
let matrix = dict.getArray('Matrix');
|
||||
let bbox = Util.normalizeRect(dict.getArray('BBox'));
|
||||
let xstep = dict.get('XStep');
|
||||
let ystep = dict.get('YStep');
|
||||
let paintType = dict.get('PaintType');
|
||||
let tilingType = dict.get('TilingType');
|
||||
let matrix = dict.getArray("Matrix");
|
||||
let bbox = Util.normalizeRect(dict.getArray("BBox"));
|
||||
let xstep = dict.get("XStep");
|
||||
let ystep = dict.get("YStep");
|
||||
let paintType = dict.get("PaintType");
|
||||
let tilingType = dict.get("TilingType");
|
||||
|
||||
// Ensure that the pattern has a non-zero width and height, to prevent errors
|
||||
// in `pattern_helper.js` (fixes issue8330.pdf).
|
||||
if ((bbox[2] - bbox[0]) === 0 || (bbox[3] - bbox[1]) === 0) {
|
||||
if (bbox[2] - bbox[0] === 0 || bbox[3] - bbox[1] === 0) {
|
||||
throw new FormatError(`Invalid getTilingPatternIR /BBox array: [${bbox}].`);
|
||||
}
|
||||
|
||||
return [
|
||||
'TilingPattern', args, operatorList, matrix, bbox, xstep, ystep,
|
||||
paintType, tilingType
|
||||
"TilingPattern",
|
||||
args,
|
||||
operatorList,
|
||||
matrix,
|
||||
bbox,
|
||||
xstep,
|
||||
ystep,
|
||||
paintType,
|
||||
tilingType,
|
||||
];
|
||||
}
|
||||
|
||||
export {
|
||||
Pattern,
|
||||
getTilingPatternIR,
|
||||
};
|
||||
export { Pattern, getTilingPatternIR };
|
||||
|
|
|
@ -14,17 +14,20 @@
|
|||
*/
|
||||
|
||||
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';
|
||||
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.');
|
||||
unreachable("Cannot initialize BasePdfManager.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,11 +49,11 @@ class BasePdfManager {
|
|||
warn(`Invalid absolute docBaseUrl: "${this._docBaseUrl}".`);
|
||||
}
|
||||
}
|
||||
return shadow(this, 'docBaseUrl', docBaseUrl);
|
||||
return shadow(this, "docBaseUrl", docBaseUrl);
|
||||
}
|
||||
|
||||
onLoadedStream() {
|
||||
unreachable('Abstract method `onLoadedStream` called');
|
||||
unreachable("Abstract method `onLoadedStream` called");
|
||||
}
|
||||
|
||||
ensureDoc(prop, args) {
|
||||
|
@ -78,19 +81,19 @@ class BasePdfManager {
|
|||
}
|
||||
|
||||
async ensure(obj, prop, args) {
|
||||
unreachable('Abstract method `ensure` called');
|
||||
unreachable("Abstract method `ensure` called");
|
||||
}
|
||||
|
||||
requestRange(begin, end) {
|
||||
unreachable('Abstract method `requestRange` called');
|
||||
unreachable("Abstract method `requestRange` called");
|
||||
}
|
||||
|
||||
requestLoadedStream() {
|
||||
unreachable('Abstract method `requestLoadedStream` called');
|
||||
unreachable("Abstract method `requestLoadedStream` called");
|
||||
}
|
||||
|
||||
sendProgressiveData(chunk) {
|
||||
unreachable('Abstract method `sendProgressiveData` called');
|
||||
unreachable("Abstract method `sendProgressiveData` called");
|
||||
}
|
||||
|
||||
updatePassword(password) {
|
||||
|
@ -98,7 +101,7 @@ class BasePdfManager {
|
|||
}
|
||||
|
||||
terminate(reason) {
|
||||
unreachable('Abstract method `terminate` called');
|
||||
unreachable("Abstract method `terminate` called");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,7 +121,7 @@ class LocalPdfManager extends BasePdfManager {
|
|||
|
||||
async ensure(obj, prop, args) {
|
||||
const value = obj[prop];
|
||||
if (typeof value === 'function') {
|
||||
if (typeof value === "function") {
|
||||
return value.apply(obj, args);
|
||||
}
|
||||
return value;
|
||||
|
@ -159,7 +162,7 @@ class NetworkPdfManager extends BasePdfManager {
|
|||
async ensure(obj, prop, args) {
|
||||
try {
|
||||
const value = obj[prop];
|
||||
if (typeof value === 'function') {
|
||||
if (typeof value === "function") {
|
||||
return value.apply(obj, args);
|
||||
}
|
||||
return value;
|
||||
|
@ -181,7 +184,7 @@ class NetworkPdfManager extends BasePdfManager {
|
|||
}
|
||||
|
||||
sendProgressiveData(chunk) {
|
||||
this.streamManager.onReceiveData({ chunk, });
|
||||
this.streamManager.onReceiveData({ chunk });
|
||||
}
|
||||
|
||||
onLoadedStream() {
|
||||
|
@ -193,7 +196,4 @@ class NetworkPdfManager extends BasePdfManager {
|
|||
}
|
||||
}
|
||||
|
||||
export {
|
||||
LocalPdfManager,
|
||||
NetworkPdfManager,
|
||||
};
|
||||
export { LocalPdfManager, NetworkPdfManager };
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
/* uses XRef */
|
||||
|
||||
import { assert } from '../shared/util';
|
||||
import { assert } from "../shared/util";
|
||||
|
||||
var EOF = {};
|
||||
|
||||
|
@ -29,7 +29,7 @@ var Name = (function NameClosure() {
|
|||
|
||||
Name.get = function Name_get(name) {
|
||||
var nameValue = nameCache[name];
|
||||
return (nameValue ? nameValue : (nameCache[name] = new Name(name)));
|
||||
return nameValue ? nameValue : (nameCache[name] = new Name(name));
|
||||
};
|
||||
|
||||
Name._clearCache = function() {
|
||||
|
@ -50,7 +50,7 @@ var Cmd = (function CmdClosure() {
|
|||
|
||||
Cmd.get = function Cmd_get(cmd) {
|
||||
var cmdValue = cmdCache[cmd];
|
||||
return (cmdValue ? cmdValue : (cmdCache[cmd] = new Cmd(cmd)));
|
||||
return cmdValue ? cmdValue : (cmdCache[cmd] = new Cmd(cmd));
|
||||
};
|
||||
|
||||
Cmd._clearCache = function() {
|
||||
|
@ -193,9 +193,9 @@ var Ref = (function RefClosure() {
|
|||
};
|
||||
|
||||
Ref.get = function(num, gen) {
|
||||
const key = (gen === 0 ? `${num}R` : `${num}R${gen}`);
|
||||
const key = gen === 0 ? `${num}R` : `${num}R${gen}`;
|
||||
const refValue = refCache[key];
|
||||
return (refValue ? refValue : (refCache[key] = new Ref(num, gen)));
|
||||
return refValue ? refValue : (refCache[key] = new Ref(num, gen));
|
||||
};
|
||||
|
||||
Ref._clearCache = function() {
|
||||
|
@ -266,7 +266,7 @@ var RefSetCache = (function RefSetCacheClosure() {
|
|||
})();
|
||||
|
||||
function isEOF(v) {
|
||||
return (v === EOF);
|
||||
return v === EOF;
|
||||
}
|
||||
|
||||
function isName(v, name) {
|
||||
|
@ -278,8 +278,9 @@ function isCmd(v, cmd) {
|
|||
}
|
||||
|
||||
function isDict(v, type) {
|
||||
return v instanceof Dict &&
|
||||
(type === undefined || isName(v.get('Type'), type));
|
||||
return (
|
||||
v instanceof Dict && (type === undefined || isName(v.get("Type"), type))
|
||||
);
|
||||
}
|
||||
|
||||
function isRef(v) {
|
||||
|
@ -287,16 +288,20 @@ function isRef(v) {
|
|||
}
|
||||
|
||||
function isRefsEqual(v1, v2) {
|
||||
if (typeof PDFJSDev === 'undefined' ||
|
||||
PDFJSDev.test('!PRODUCTION || TESTING')) {
|
||||
assert(v1 instanceof Ref && v2 instanceof Ref,
|
||||
'isRefsEqual: Both parameters should be `Ref`s.');
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(
|
||||
v1 instanceof Ref && v2 instanceof Ref,
|
||||
"isRefsEqual: Both parameters should be `Ref`s."
|
||||
);
|
||||
}
|
||||
return v1.num === v2.num && v1.gen === v2.gen;
|
||||
}
|
||||
|
||||
function isStream(v) {
|
||||
return typeof v === 'object' && v !== null && v.getBytes !== undefined;
|
||||
return typeof v === "object" && v !== null && v.getBytes !== undefined;
|
||||
}
|
||||
|
||||
function clearPrimitiveCaches() {
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
*/
|
||||
/* eslint no-var: error */
|
||||
|
||||
import { FormatError, isSpace, shadow } from '../shared/util';
|
||||
import { EOF } from './primitives';
|
||||
import { FormatError, isSpace, shadow } from "../shared/util";
|
||||
import { EOF } from "./primitives";
|
||||
|
||||
class PostScriptParser {
|
||||
constructor(lexer) {
|
||||
|
@ -43,7 +43,8 @@ class PostScriptParser {
|
|||
return true;
|
||||
}
|
||||
throw new FormatError(
|
||||
`Unexpected symbol: found ${this.token.type} expected ${type}.`);
|
||||
`Unexpected symbol: found ${this.token.type} expected ${type}.`
|
||||
);
|
||||
}
|
||||
|
||||
parse() {
|
||||
|
@ -79,7 +80,7 @@ class PostScriptParser {
|
|||
// The true block is right after the 'if' so it just falls through on true
|
||||
// else it jumps and skips the true block.
|
||||
this.operators[conditionLocation] = this.operators.length;
|
||||
this.operators[conditionLocation + 1] = 'jz';
|
||||
this.operators[conditionLocation + 1] = "jz";
|
||||
} else if (this.accept(PostScriptTokenTypes.LBRACE)) {
|
||||
const jumpLocation = this.operators.length;
|
||||
this.operators.push(null, null);
|
||||
|
@ -89,12 +90,12 @@ class PostScriptParser {
|
|||
this.expect(PostScriptTokenTypes.IFELSE);
|
||||
// The jump is added at the end of the true block to skip the false block.
|
||||
this.operators[jumpLocation] = this.operators.length;
|
||||
this.operators[jumpLocation + 1] = 'j';
|
||||
this.operators[jumpLocation + 1] = "j";
|
||||
|
||||
this.operators[conditionLocation] = endOfTrue;
|
||||
this.operators[conditionLocation + 1] = 'jz';
|
||||
this.operators[conditionLocation + 1] = "jz";
|
||||
} else {
|
||||
throw new FormatError('PS Function: error parsing conditional.');
|
||||
throw new FormatError("PS Function: error parsing conditional.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,28 +123,42 @@ const PostScriptToken = (function PostScriptTokenClosure() {
|
|||
if (opValue) {
|
||||
return opValue;
|
||||
}
|
||||
return opCache[op] = new PostScriptToken(PostScriptTokenTypes.OPERATOR,
|
||||
op);
|
||||
return (opCache[op] = new PostScriptToken(
|
||||
PostScriptTokenTypes.OPERATOR,
|
||||
op
|
||||
));
|
||||
}
|
||||
|
||||
static get LBRACE() {
|
||||
return shadow(this, 'LBRACE',
|
||||
new PostScriptToken(PostScriptTokenTypes.LBRACE, '{'));
|
||||
return shadow(
|
||||
this,
|
||||
"LBRACE",
|
||||
new PostScriptToken(PostScriptTokenTypes.LBRACE, "{")
|
||||
);
|
||||
}
|
||||
|
||||
static get RBRACE() {
|
||||
return shadow(this, 'RBRACE',
|
||||
new PostScriptToken(PostScriptTokenTypes.RBRACE, '}'));
|
||||
return shadow(
|
||||
this,
|
||||
"RBRACE",
|
||||
new PostScriptToken(PostScriptTokenTypes.RBRACE, "}")
|
||||
);
|
||||
}
|
||||
|
||||
static get IF() {
|
||||
return shadow(this, 'IF',
|
||||
new PostScriptToken(PostScriptTokenTypes.IF, 'IF'));
|
||||
return shadow(
|
||||
this,
|
||||
"IF",
|
||||
new PostScriptToken(PostScriptTokenTypes.IF, "IF")
|
||||
);
|
||||
}
|
||||
|
||||
static get IFELSE() {
|
||||
return shadow(this, 'IFELSE',
|
||||
new PostScriptToken(PostScriptTokenTypes.IFELSE, 'IFELSE'));
|
||||
return shadow(
|
||||
this,
|
||||
"IFELSE",
|
||||
new PostScriptToken(PostScriptTokenTypes.IFELSE, "IFELSE")
|
||||
);
|
||||
}
|
||||
}
|
||||
return PostScriptToken;
|
||||
|
@ -172,10 +187,11 @@ class PostScriptLexer {
|
|||
}
|
||||
|
||||
if (comment) {
|
||||
if (ch === 0x0A || ch === 0x0D) {
|
||||
if (ch === 0x0a || ch === 0x0d) {
|
||||
comment = false;
|
||||
}
|
||||
} else if (ch === 0x25) { // '%'
|
||||
} else if (ch === 0x25) {
|
||||
// '%'
|
||||
comment = true;
|
||||
} else if (!isSpace(ch)) {
|
||||
break;
|
||||
|
@ -183,15 +199,27 @@ class PostScriptLexer {
|
|||
ch = this.nextChar();
|
||||
}
|
||||
switch (ch | 0) {
|
||||
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: // '0'-'4'
|
||||
case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: // '5'-'9'
|
||||
case 0x2B: case 0x2D: case 0x2E: // '+', '-', '.'
|
||||
return new PostScriptToken(PostScriptTokenTypes.NUMBER,
|
||||
this.getNumber());
|
||||
case 0x7B: // '{'
|
||||
case 0x30:
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
case 0x34: // '0'-'4'
|
||||
case 0x35:
|
||||
case 0x36:
|
||||
case 0x37:
|
||||
case 0x38:
|
||||
case 0x39: // '5'-'9'
|
||||
case 0x2b:
|
||||
case 0x2d:
|
||||
case 0x2e: // '+', '-', '.'
|
||||
return new PostScriptToken(
|
||||
PostScriptTokenTypes.NUMBER,
|
||||
this.getNumber()
|
||||
);
|
||||
case 0x7b: // '{'
|
||||
this.nextChar();
|
||||
return PostScriptToken.LBRACE;
|
||||
case 0x7D: // '}'
|
||||
case 0x7d: // '}'
|
||||
this.nextChar();
|
||||
return PostScriptToken.RBRACE;
|
||||
}
|
||||
|
@ -200,15 +228,17 @@ class PostScriptLexer {
|
|||
strBuf.length = 0;
|
||||
strBuf[0] = String.fromCharCode(ch);
|
||||
|
||||
while ((ch = this.nextChar()) >= 0 && // and 'A'-'Z', 'a'-'z'
|
||||
((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A))) {
|
||||
while (
|
||||
(ch = this.nextChar()) >= 0 && // and 'A'-'Z', 'a'-'z'
|
||||
((ch >= 0x41 && ch <= 0x5a) || (ch >= 0x61 && ch <= 0x7a))
|
||||
) {
|
||||
strBuf.push(String.fromCharCode(ch));
|
||||
}
|
||||
const str = strBuf.join('');
|
||||
const str = strBuf.join("");
|
||||
switch (str.toLowerCase()) {
|
||||
case 'if':
|
||||
case "if":
|
||||
return PostScriptToken.IF;
|
||||
case 'ifelse':
|
||||
case "ifelse":
|
||||
return PostScriptToken.IFELSE;
|
||||
default:
|
||||
return PostScriptToken.getOperator(str);
|
||||
|
@ -222,14 +252,18 @@ class PostScriptLexer {
|
|||
strBuf[0] = String.fromCharCode(ch);
|
||||
|
||||
while ((ch = this.nextChar()) >= 0) {
|
||||
if ((ch >= 0x30 && ch <= 0x39) || // '0'-'9'
|
||||
ch === 0x2D || ch === 0x2E) { // '-', '.'
|
||||
if (
|
||||
(ch >= 0x30 && ch <= 0x39) || // '0'-'9'
|
||||
ch === 0x2d ||
|
||||
ch === 0x2e
|
||||
) {
|
||||
// '-', '.'
|
||||
strBuf.push(String.fromCharCode(ch));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const value = parseFloat(strBuf.join(''));
|
||||
const value = parseFloat(strBuf.join(""));
|
||||
if (isNaN(value)) {
|
||||
throw new FormatError(`Invalid floating point number: ${value}`);
|
||||
}
|
||||
|
@ -237,7 +271,4 @@ class PostScriptLexer {
|
|||
}
|
||||
}
|
||||
|
||||
export {
|
||||
PostScriptLexer,
|
||||
PostScriptParser,
|
||||
};
|
||||
export { PostScriptLexer, PostScriptParser };
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -20,17 +20,22 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
FormatError, isSpace, stringToBytes, unreachable
|
||||
} from '../shared/util';
|
||||
import { isDict } from './primitives';
|
||||
FormatError,
|
||||
isSpace,
|
||||
stringToBytes,
|
||||
unreachable,
|
||||
} from "../shared/util";
|
||||
import { isDict } from "./primitives";
|
||||
|
||||
var Stream = (function StreamClosure() {
|
||||
function Stream(arrayBuffer, start, length, dict) {
|
||||
this.bytes = (arrayBuffer instanceof Uint8Array ?
|
||||
arrayBuffer : new Uint8Array(arrayBuffer));
|
||||
this.bytes =
|
||||
arrayBuffer instanceof Uint8Array
|
||||
? arrayBuffer
|
||||
: new Uint8Array(arrayBuffer);
|
||||
this.start = start || 0;
|
||||
this.pos = this.start;
|
||||
this.end = (start + length) || this.bytes.length;
|
||||
this.end = start + length || this.bytes.length;
|
||||
this.dict = dict;
|
||||
}
|
||||
|
||||
|
@ -73,7 +78,7 @@ var Stream = (function StreamClosure() {
|
|||
if (!length) {
|
||||
let subarray = bytes.subarray(pos, strEnd);
|
||||
// `this.bytes` is always a `Uint8Array` here.
|
||||
return (forceClamped ? new Uint8ClampedArray(subarray) : subarray);
|
||||
return forceClamped ? new Uint8ClampedArray(subarray) : subarray;
|
||||
}
|
||||
var end = pos + length;
|
||||
if (end > strEnd) {
|
||||
|
@ -82,7 +87,7 @@ var Stream = (function StreamClosure() {
|
|||
this.pos = end;
|
||||
let subarray = bytes.subarray(pos, end);
|
||||
// `this.bytes` is always a `Uint8Array` here.
|
||||
return (forceClamped ? new Uint8ClampedArray(subarray) : subarray);
|
||||
return forceClamped ? new Uint8ClampedArray(subarray) : subarray;
|
||||
},
|
||||
peekByte: function Stream_peekByte() {
|
||||
var peekedByte = this.getByte();
|
||||
|
@ -208,7 +213,8 @@ var DecodeStream = (function DecodeStreamClosure() {
|
|||
return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;
|
||||
},
|
||||
getBytes(length, forceClamped = false) {
|
||||
var end, pos = this.pos;
|
||||
var end,
|
||||
pos = this.pos;
|
||||
|
||||
if (length) {
|
||||
this.ensureBuffer(pos + length);
|
||||
|
@ -231,8 +237,9 @@ var DecodeStream = (function DecodeStreamClosure() {
|
|||
this.pos = end;
|
||||
let subarray = this.buffer.subarray(pos, end);
|
||||
// `this.buffer` is either a `Uint8Array` or `Uint8ClampedArray` here.
|
||||
return (forceClamped && !(subarray instanceof Uint8ClampedArray) ?
|
||||
new Uint8ClampedArray(subarray) : subarray);
|
||||
return forceClamped && !(subarray instanceof Uint8ClampedArray)
|
||||
? new Uint8ClampedArray(subarray)
|
||||
: subarray;
|
||||
},
|
||||
peekByte: function DecodeStream_peekByte() {
|
||||
var peekedByte = this.getByte();
|
||||
|
@ -255,7 +262,7 @@ var DecodeStream = (function DecodeStreamClosure() {
|
|||
},
|
||||
|
||||
getByteRange(begin, end) {
|
||||
unreachable('Should not call DecodeStream.getByteRange');
|
||||
unreachable("Should not call DecodeStream.getByteRange");
|
||||
},
|
||||
|
||||
skip: function DecodeStream_skip(n) {
|
||||
|
@ -296,9 +303,7 @@ var StreamsSequenceStream = (function StreamsSequenceStreamClosure() {
|
|||
|
||||
StreamsSequenceStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
StreamsSequenceStream.prototype.readBlock =
|
||||
function streamSequenceStreamReadBlock() {
|
||||
|
||||
StreamsSequenceStream.prototype.readBlock = function streamSequenceStreamReadBlock() {
|
||||
var streams = this.streams;
|
||||
if (streams.length === 0) {
|
||||
this.eof = true;
|
||||
|
@ -313,9 +318,7 @@ var StreamsSequenceStream = (function StreamsSequenceStreamClosure() {
|
|||
this.bufferLength = newLength;
|
||||
};
|
||||
|
||||
StreamsSequenceStream.prototype.getBaseStreams =
|
||||
function StreamsSequenceStream_getBaseStreams() {
|
||||
|
||||
StreamsSequenceStream.prototype.getBaseStreams = function StreamsSequenceStream_getBaseStreams() {
|
||||
var baseStreams = [];
|
||||
for (var i = 0, ii = this.streams.length; i < ii; i++) {
|
||||
var stream = this.streams[i];
|
||||
|
@ -434,19 +437,18 @@ var FlateStream = (function FlateStreamClosure() {
|
|||
var cmf = str.getByte();
|
||||
var flg = str.getByte();
|
||||
if (cmf === -1 || flg === -1) {
|
||||
throw new FormatError(
|
||||
`Invalid header in flate stream: ${cmf}, ${flg}`);
|
||||
throw new FormatError(`Invalid header in flate stream: ${cmf}, ${flg}`);
|
||||
}
|
||||
if ((cmf & 0x0f) !== 0x08) {
|
||||
throw new FormatError(
|
||||
`Unknown compression method in flate stream: ${cmf}, ${flg}`);
|
||||
`Unknown compression method in flate stream: ${cmf}, ${flg}`
|
||||
);
|
||||
}
|
||||
if ((((cmf << 8) + flg) % 31) !== 0) {
|
||||
if (((cmf << 8) + flg) % 31 !== 0) {
|
||||
throw new FormatError(`Bad FCHECK in flate stream: ${cmf}, ${flg}`);
|
||||
}
|
||||
if (flg & 0x20) {
|
||||
throw new FormatError(
|
||||
`FDICT bit set in flate stream: ${cmf}, ${flg}`);
|
||||
throw new FormatError(`FDICT bit set in flate stream: ${cmf}, ${flg}`);
|
||||
}
|
||||
|
||||
this.codeSize = 0;
|
||||
|
@ -465,7 +467,7 @@ var FlateStream = (function FlateStreamClosure() {
|
|||
var b;
|
||||
while (codeSize < bits) {
|
||||
if ((b = str.getByte()) === -1) {
|
||||
throw new FormatError('Bad encoding in flate stream');
|
||||
throw new FormatError("Bad encoding in flate stream");
|
||||
}
|
||||
codeBuf |= b << codeSize;
|
||||
codeSize += 8;
|
||||
|
@ -491,22 +493,23 @@ var FlateStream = (function FlateStreamClosure() {
|
|||
// codeSize < codeLen check below guards against incomplete codeVal.
|
||||
break;
|
||||
}
|
||||
codeBuf |= (b << codeSize);
|
||||
codeBuf |= b << codeSize;
|
||||
codeSize += 8;
|
||||
}
|
||||
var code = codes[codeBuf & ((1 << maxLen) - 1)];
|
||||
var codeLen = code >> 16;
|
||||
var codeVal = code & 0xffff;
|
||||
if (codeLen < 1 || codeSize < codeLen) {
|
||||
throw new FormatError('Bad encoding in flate stream');
|
||||
throw new FormatError("Bad encoding in flate stream");
|
||||
}
|
||||
this.codeBuf = (codeBuf >> codeLen);
|
||||
this.codeSize = (codeSize - codeLen);
|
||||
this.codeBuf = codeBuf >> codeLen;
|
||||
this.codeSize = codeSize - codeLen;
|
||||
return codeVal;
|
||||
};
|
||||
|
||||
FlateStream.prototype.generateHuffmanTable =
|
||||
function flateStreamGenerateHuffmanTable(lengths) {
|
||||
FlateStream.prototype.generateHuffmanTable = function flateStreamGenerateHuffmanTable(
|
||||
lengths
|
||||
) {
|
||||
var n = lengths.length;
|
||||
|
||||
// find max code length
|
||||
|
@ -521,9 +524,11 @@ var FlateStream = (function FlateStreamClosure() {
|
|||
// build the table
|
||||
var size = 1 << maxLen;
|
||||
var codes = new Int32Array(size);
|
||||
for (var len = 1, code = 0, skip = 2;
|
||||
len <= maxLen;
|
||||
++len, code <<= 1, skip <<= 1) {
|
||||
for (
|
||||
var len = 1, code = 0, skip = 2;
|
||||
len <= maxLen;
|
||||
++len, code <<= 1, skip <<= 1
|
||||
) {
|
||||
for (var val = 0; val < n; ++val) {
|
||||
if (lengths[val] === len) {
|
||||
// bit-reverse the code
|
||||
|
@ -556,36 +561,36 @@ var FlateStream = (function FlateStreamClosure() {
|
|||
}
|
||||
hdr >>= 1;
|
||||
|
||||
if (hdr === 0) { // uncompressed block
|
||||
if (hdr === 0) {
|
||||
// uncompressed block
|
||||
var b;
|
||||
|
||||
if ((b = str.getByte()) === -1) {
|
||||
throw new FormatError('Bad block header in flate stream');
|
||||
throw new FormatError("Bad block header in flate stream");
|
||||
}
|
||||
var blockLen = b;
|
||||
if ((b = str.getByte()) === -1) {
|
||||
throw new FormatError('Bad block header in flate stream');
|
||||
throw new FormatError("Bad block header in flate stream");
|
||||
}
|
||||
blockLen |= (b << 8);
|
||||
blockLen |= b << 8;
|
||||
if ((b = str.getByte()) === -1) {
|
||||
throw new FormatError('Bad block header in flate stream');
|
||||
throw new FormatError("Bad block header in flate stream");
|
||||
}
|
||||
var check = b;
|
||||
if ((b = str.getByte()) === -1) {
|
||||
throw new FormatError('Bad block header in flate stream');
|
||||
throw new FormatError("Bad block header in flate stream");
|
||||
}
|
||||
check |= (b << 8);
|
||||
if (check !== (~blockLen & 0xffff) &&
|
||||
(blockLen !== 0 || check !== 0)) {
|
||||
check |= b << 8;
|
||||
if (check !== (~blockLen & 0xffff) && (blockLen !== 0 || check !== 0)) {
|
||||
// Ignoring error for bad "empty" block (see issue 1277)
|
||||
throw new FormatError(
|
||||
'Bad uncompressed block length in flate stream');
|
||||
throw new FormatError("Bad uncompressed block length in flate stream");
|
||||
}
|
||||
|
||||
this.codeBuf = 0;
|
||||
this.codeSize = 0;
|
||||
|
||||
const bufferLength = this.bufferLength, end = bufferLength + blockLen;
|
||||
const bufferLength = this.bufferLength,
|
||||
end = bufferLength + blockLen;
|
||||
buffer = this.ensureBuffer(end);
|
||||
this.bufferLength = end;
|
||||
|
||||
|
@ -605,10 +610,12 @@ var FlateStream = (function FlateStreamClosure() {
|
|||
|
||||
var litCodeTable;
|
||||
var distCodeTable;
|
||||
if (hdr === 1) { // compressed block, fixed codes
|
||||
if (hdr === 1) {
|
||||
// compressed block, fixed codes
|
||||
litCodeTable = fixedLitCodeTab;
|
||||
distCodeTable = fixedDistCodeTab;
|
||||
} else if (hdr === 2) { // compressed block, dynamic codes
|
||||
} else if (hdr === 2) {
|
||||
// compressed block, dynamic codes
|
||||
var numLitCodes = this.getBits(5) + 257;
|
||||
var numDistCodes = this.getBits(5) + 1;
|
||||
var numCodeLenCodes = this.getBits(4) + 4;
|
||||
|
@ -631,11 +638,17 @@ var FlateStream = (function FlateStreamClosure() {
|
|||
while (i < codes) {
|
||||
var code = this.getCode(codeLenCodeTab);
|
||||
if (code === 16) {
|
||||
bitsLength = 2; bitsOffset = 3; what = len;
|
||||
bitsLength = 2;
|
||||
bitsOffset = 3;
|
||||
what = len;
|
||||
} else if (code === 17) {
|
||||
bitsLength = 3; bitsOffset = 3; what = (len = 0);
|
||||
bitsLength = 3;
|
||||
bitsOffset = 3;
|
||||
what = len = 0;
|
||||
} else if (code === 18) {
|
||||
bitsLength = 7; bitsOffset = 11; what = (len = 0);
|
||||
bitsLength = 7;
|
||||
bitsOffset = 11;
|
||||
what = len = 0;
|
||||
} else {
|
||||
codeLengths[i++] = len = code;
|
||||
continue;
|
||||
|
@ -647,12 +660,14 @@ var FlateStream = (function FlateStreamClosure() {
|
|||
}
|
||||
}
|
||||
|
||||
litCodeTable =
|
||||
this.generateHuffmanTable(codeLengths.subarray(0, numLitCodes));
|
||||
distCodeTable =
|
||||
this.generateHuffmanTable(codeLengths.subarray(numLitCodes, codes));
|
||||
litCodeTable = this.generateHuffmanTable(
|
||||
codeLengths.subarray(0, numLitCodes)
|
||||
);
|
||||
distCodeTable = this.generateHuffmanTable(
|
||||
codeLengths.subarray(numLitCodes, codes)
|
||||
);
|
||||
} else {
|
||||
throw new FormatError('Unknown block type in flate stream');
|
||||
throw new FormatError("Unknown block type in flate stream");
|
||||
}
|
||||
|
||||
buffer = this.buffer;
|
||||
|
@ -704,7 +719,7 @@ var PredictorStream = (function PredictorStreamClosure() {
|
|||
if (!isDict(params)) {
|
||||
return str; // no prediction
|
||||
}
|
||||
var predictor = this.predictor = params.get('Predictor') || 1;
|
||||
var predictor = (this.predictor = params.get("Predictor") || 1);
|
||||
|
||||
if (predictor <= 1) {
|
||||
return str; // no prediction
|
||||
|
@ -722,9 +737,9 @@ var PredictorStream = (function PredictorStreamClosure() {
|
|||
this.str = str;
|
||||
this.dict = str.dict;
|
||||
|
||||
var colors = this.colors = params.get('Colors') || 1;
|
||||
var bits = this.bits = params.get('BitsPerComponent') || 8;
|
||||
var columns = this.columns = params.get('Columns') || 1;
|
||||
var colors = (this.colors = params.get("Colors") || 1);
|
||||
var bits = (this.bits = params.get("BitsPerComponent") || 8);
|
||||
var columns = (this.columns = params.get("Columns") || 1);
|
||||
|
||||
this.pixBytes = (colors * bits + 7) >> 3;
|
||||
this.rowBytes = (columns * colors * bits + 7) >> 3;
|
||||
|
@ -735,8 +750,7 @@ var PredictorStream = (function PredictorStreamClosure() {
|
|||
|
||||
PredictorStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
PredictorStream.prototype.readBlockTiff =
|
||||
function predictorStreamReadBlockTiff() {
|
||||
PredictorStream.prototype.readBlockTiff = function predictorStreamReadBlockTiff() {
|
||||
var rowBytes = this.rowBytes;
|
||||
|
||||
var bufferLength = this.bufferLength;
|
||||
|
@ -751,8 +765,10 @@ var PredictorStream = (function PredictorStreamClosure() {
|
|||
return;
|
||||
}
|
||||
|
||||
var inbuf = 0, outbuf = 0;
|
||||
var inbits = 0, outbits = 0;
|
||||
var inbuf = 0,
|
||||
outbuf = 0;
|
||||
var inbits = 0,
|
||||
outbits = 0;
|
||||
var pos = bufferLength;
|
||||
var i;
|
||||
|
||||
|
@ -781,46 +797,46 @@ var PredictorStream = (function PredictorStreamClosure() {
|
|||
buffer[pos++] = rawBytes[i];
|
||||
}
|
||||
for (; i < rowBytes; i += 2) {
|
||||
var sum = ((rawBytes[i] & 0xFF) << 8) +
|
||||
(rawBytes[i + 1] & 0xFF) +
|
||||
((buffer[pos - bytesPerPixel] & 0xFF) << 8) +
|
||||
(buffer[pos - bytesPerPixel + 1] & 0xFF);
|
||||
buffer[pos++] = ((sum >> 8) & 0xFF);
|
||||
buffer[pos++] = (sum & 0xFF);
|
||||
var sum =
|
||||
((rawBytes[i] & 0xff) << 8) +
|
||||
(rawBytes[i + 1] & 0xff) +
|
||||
((buffer[pos - bytesPerPixel] & 0xff) << 8) +
|
||||
(buffer[pos - bytesPerPixel + 1] & 0xff);
|
||||
buffer[pos++] = (sum >> 8) & 0xff;
|
||||
buffer[pos++] = sum & 0xff;
|
||||
}
|
||||
} else {
|
||||
var compArray = new Uint8Array(colors + 1);
|
||||
var bitMask = (1 << bits) - 1;
|
||||
var j = 0, k = bufferLength;
|
||||
var j = 0,
|
||||
k = bufferLength;
|
||||
var columns = this.columns;
|
||||
for (i = 0; i < columns; ++i) {
|
||||
for (var kk = 0; kk < colors; ++kk) {
|
||||
if (inbits < bits) {
|
||||
inbuf = (inbuf << 8) | (rawBytes[j++] & 0xFF);
|
||||
inbuf = (inbuf << 8) | (rawBytes[j++] & 0xff);
|
||||
inbits += 8;
|
||||
}
|
||||
compArray[kk] = (compArray[kk] +
|
||||
(inbuf >> (inbits - bits))) & bitMask;
|
||||
compArray[kk] =
|
||||
(compArray[kk] + (inbuf >> (inbits - bits))) & bitMask;
|
||||
inbits -= bits;
|
||||
outbuf = (outbuf << bits) | compArray[kk];
|
||||
outbits += bits;
|
||||
if (outbits >= 8) {
|
||||
buffer[k++] = (outbuf >> (outbits - 8)) & 0xFF;
|
||||
buffer[k++] = (outbuf >> (outbits - 8)) & 0xff;
|
||||
outbits -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (outbits > 0) {
|
||||
buffer[k++] = (outbuf << (8 - outbits)) +
|
||||
(inbuf & ((1 << (8 - outbits)) - 1));
|
||||
buffer[k++] =
|
||||
(outbuf << (8 - outbits)) + (inbuf & ((1 << (8 - outbits)) - 1));
|
||||
}
|
||||
}
|
||||
this.bufferLength += rowBytes;
|
||||
};
|
||||
|
||||
PredictorStream.prototype.readBlockPng =
|
||||
function predictorStreamReadBlockPng() {
|
||||
|
||||
PredictorStream.prototype.readBlockPng = function predictorStreamReadBlockPng() {
|
||||
var rowBytes = this.rowBytes;
|
||||
var pixBytes = this.pixBytes;
|
||||
|
||||
|
@ -839,7 +855,10 @@ var PredictorStream = (function PredictorStreamClosure() {
|
|||
prevRow = new Uint8Array(rowBytes);
|
||||
}
|
||||
|
||||
var i, j = bufferLength, up, c;
|
||||
var i,
|
||||
j = bufferLength,
|
||||
up,
|
||||
c;
|
||||
switch (predictor) {
|
||||
case 0:
|
||||
for (i = 0; i < rowBytes; ++i) {
|
||||
|
@ -851,13 +870,13 @@ var PredictorStream = (function PredictorStreamClosure() {
|
|||
buffer[j++] = rawBytes[i];
|
||||
}
|
||||
for (; i < rowBytes; ++i) {
|
||||
buffer[j] = (buffer[j - pixBytes] + rawBytes[i]) & 0xFF;
|
||||
buffer[j] = (buffer[j - pixBytes] + rawBytes[i]) & 0xff;
|
||||
j++;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (i = 0; i < rowBytes; ++i) {
|
||||
buffer[j++] = (prevRow[i] + rawBytes[i]) & 0xFF;
|
||||
buffer[j++] = (prevRow[i] + rawBytes[i]) & 0xff;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
|
@ -865,8 +884,8 @@ var PredictorStream = (function PredictorStreamClosure() {
|
|||
buffer[j++] = (prevRow[i] >> 1) + rawBytes[i];
|
||||
}
|
||||
for (; i < rowBytes; ++i) {
|
||||
buffer[j] = (((prevRow[i] + buffer[j - pixBytes]) >> 1) +
|
||||
rawBytes[i]) & 0xFF;
|
||||
buffer[j] =
|
||||
(((prevRow[i] + buffer[j - pixBytes]) >> 1) + rawBytes[i]) & 0xff;
|
||||
j++;
|
||||
}
|
||||
break;
|
||||
|
@ -950,7 +969,8 @@ var DecryptStream = (function DecryptStreamClosure() {
|
|||
chunk = decrypt(chunk, !hasMoreData);
|
||||
|
||||
var bufferLength = this.bufferLength;
|
||||
var i, n = chunk.length;
|
||||
var i,
|
||||
n = chunk.length;
|
||||
var buffer = this.ensureBuffer(bufferLength + n);
|
||||
for (i = 0; i < n; i++) {
|
||||
buffer[bufferLength++] = chunk[i];
|
||||
|
@ -978,8 +998,8 @@ var Ascii85Stream = (function Ascii85StreamClosure() {
|
|||
Ascii85Stream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
Ascii85Stream.prototype.readBlock = function Ascii85Stream_readBlock() {
|
||||
var TILDA_CHAR = 0x7E; // '~'
|
||||
var Z_LOWER_CHAR = 0x7A; // 'z'
|
||||
var TILDA_CHAR = 0x7e; // '~'
|
||||
var Z_LOWER_CHAR = 0x7a; // 'z'
|
||||
var EOF = -1;
|
||||
|
||||
var str = this.str;
|
||||
|
@ -994,7 +1014,8 @@ var Ascii85Stream = (function Ascii85StreamClosure() {
|
|||
return;
|
||||
}
|
||||
|
||||
var bufferLength = this.bufferLength, buffer;
|
||||
var bufferLength = this.bufferLength,
|
||||
buffer;
|
||||
var i;
|
||||
|
||||
// special code for z
|
||||
|
@ -1035,7 +1056,7 @@ var Ascii85Stream = (function Ascii85StreamClosure() {
|
|||
}
|
||||
|
||||
for (i = 3; i >= 0; --i) {
|
||||
buffer[bufferLength + i] = t & 0xFF;
|
||||
buffer[bufferLength + i] = t & 0xff;
|
||||
t >>= 8;
|
||||
}
|
||||
}
|
||||
|
@ -1075,16 +1096,20 @@ var AsciiHexStream = (function AsciiHexStreamClosure() {
|
|||
|
||||
var firstDigit = this.firstDigit;
|
||||
for (var i = 0, ii = bytes.length; i < ii; i++) {
|
||||
var ch = bytes[i], digit;
|
||||
if (ch >= 0x30 && ch <= 0x39) { // '0'-'9'
|
||||
digit = ch & 0x0F;
|
||||
var ch = bytes[i],
|
||||
digit;
|
||||
if (ch >= 0x30 && ch <= 0x39) {
|
||||
// '0'-'9'
|
||||
digit = ch & 0x0f;
|
||||
} else if ((ch >= 0x41 && ch <= 0x46) || (ch >= 0x61 && ch <= 0x66)) {
|
||||
// 'A'-'Z', 'a'-'z'
|
||||
digit = (ch & 0x0F) + 9;
|
||||
} else if (ch === 0x3E) { // '>'
|
||||
digit = (ch & 0x0f) + 9;
|
||||
} else if (ch === 0x3e) {
|
||||
// '>'
|
||||
this.eof = true;
|
||||
break;
|
||||
} else { // probably whitespace
|
||||
} else {
|
||||
// probably whitespace
|
||||
continue; // ignoring
|
||||
}
|
||||
if (firstDigit < 0) {
|
||||
|
@ -1096,7 +1121,7 @@ var AsciiHexStream = (function AsciiHexStreamClosure() {
|
|||
}
|
||||
if (firstDigit >= 0 && this.eof) {
|
||||
// incomplete byte
|
||||
buffer[bufferLength++] = (firstDigit << 4);
|
||||
buffer[bufferLength++] = firstDigit << 4;
|
||||
firstDigit = -1;
|
||||
}
|
||||
this.firstDigit = firstDigit;
|
||||
|
@ -1194,7 +1219,7 @@ var LZWStream = (function LZWStreamClosure() {
|
|||
cachedData = (cachedData << 8) | c;
|
||||
bitsCached += 8;
|
||||
}
|
||||
this.bitsCached = (bitsCached -= n);
|
||||
this.bitsCached = bitsCached -= n;
|
||||
this.cachedData = cachedData;
|
||||
this.lastCode = null;
|
||||
return (cachedData >>> bitsCached) & ((1 << n) - 1);
|
||||
|
@ -1202,7 +1227,8 @@ var LZWStream = (function LZWStreamClosure() {
|
|||
|
||||
LZWStream.prototype.readBlock = function LZWStream_readBlock() {
|
||||
var blockSize = 512;
|
||||
var estimatedDecodedSize = blockSize * 2, decodedSizeDelta = blockSize;
|
||||
var estimatedDecodedSize = blockSize * 2,
|
||||
decodedSizeDelta = blockSize;
|
||||
var i, j, q;
|
||||
|
||||
var lzwState = this.lzwState;
|
||||
|
@ -1256,9 +1282,13 @@ var LZWStream = (function LZWStreamClosure() {
|
|||
dictionaryLengths[nextCode] = dictionaryLengths[prevCode] + 1;
|
||||
dictionaryValues[nextCode] = currentSequence[0];
|
||||
nextCode++;
|
||||
codeLength = (nextCode + earlyChange) & (nextCode + earlyChange - 1) ?
|
||||
codeLength : Math.min(Math.log(nextCode + earlyChange) /
|
||||
0.6931471805599453 + 1, 12) | 0;
|
||||
codeLength =
|
||||
(nextCode + earlyChange) & (nextCode + earlyChange - 1)
|
||||
? codeLength
|
||||
: Math.min(
|
||||
Math.log(nextCode + earlyChange) / 0.6931471805599453 + 1,
|
||||
12
|
||||
) | 0;
|
||||
}
|
||||
prevCode = code;
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { isSpace, warn } from '../shared/util';
|
||||
import { getEncoding } from './encodings';
|
||||
import { Stream } from './stream';
|
||||
import { isSpace, warn } from "../shared/util";
|
||||
import { getEncoding } from "./encodings";
|
||||
import { Stream } from "./stream";
|
||||
|
||||
// Hinting is currently disabled due to unknown problems on windows
|
||||
// in tracemonkey and various other pdfs with type1 fonts.
|
||||
|
@ -61,21 +61,21 @@ var HINTING_ENABLED = false;
|
|||
*/
|
||||
var Type1CharString = (function Type1CharStringClosure() {
|
||||
var COMMAND_MAP = {
|
||||
'hstem': [1],
|
||||
'vstem': [3],
|
||||
'vmoveto': [4],
|
||||
'rlineto': [5],
|
||||
'hlineto': [6],
|
||||
'vlineto': [7],
|
||||
'rrcurveto': [8],
|
||||
'callsubr': [10],
|
||||
'flex': [12, 35],
|
||||
'drop': [12, 18],
|
||||
'endchar': [14],
|
||||
'rmoveto': [21],
|
||||
'hmoveto': [22],
|
||||
'vhcurveto': [30],
|
||||
'hvcurveto': [31],
|
||||
hstem: [1],
|
||||
vstem: [3],
|
||||
vmoveto: [4],
|
||||
rlineto: [5],
|
||||
hlineto: [6],
|
||||
vlineto: [7],
|
||||
rrcurveto: [8],
|
||||
callsubr: [10],
|
||||
flex: [12, 35],
|
||||
drop: [12, 18],
|
||||
endchar: [14],
|
||||
rmoveto: [21],
|
||||
hmoveto: [22],
|
||||
vhcurveto: [30],
|
||||
hvcurveto: [31],
|
||||
};
|
||||
|
||||
function Type1CharString() {
|
||||
|
@ -87,8 +87,11 @@ var Type1CharString = (function Type1CharStringClosure() {
|
|||
}
|
||||
|
||||
Type1CharString.prototype = {
|
||||
convert: function Type1CharString_convert(encoded, subrs,
|
||||
seacAnalysisEnabled) {
|
||||
convert: function Type1CharString_convert(
|
||||
encoded,
|
||||
subrs,
|
||||
seacAnalysisEnabled
|
||||
) {
|
||||
var count = encoded.length;
|
||||
var error = false;
|
||||
var wx, sbx, subrNumber;
|
||||
|
@ -154,8 +157,11 @@ var Type1CharString = (function Type1CharStringClosure() {
|
|||
error = true;
|
||||
break;
|
||||
}
|
||||
error = this.convert(subrs[subrNumber], subrs,
|
||||
seacAnalysisEnabled);
|
||||
error = this.convert(
|
||||
subrs[subrNumber],
|
||||
subrs,
|
||||
seacAnalysisEnabled
|
||||
);
|
||||
break;
|
||||
case 11: // return
|
||||
return error;
|
||||
|
@ -214,7 +220,7 @@ var Type1CharString = (function Type1CharStringClosure() {
|
|||
break;
|
||||
case (12 << 8) + 2: // hstem3
|
||||
if (!HINTING_ENABLED) {
|
||||
this.stack = [];
|
||||
this.stack = [];
|
||||
break;
|
||||
}
|
||||
// See vstem3.
|
||||
|
@ -308,12 +314,15 @@ var Type1CharString = (function Type1CharStringClosure() {
|
|||
} else if (value <= 246) {
|
||||
value = value - 139;
|
||||
} else if (value <= 250) {
|
||||
value = ((value - 247) * 256) + encoded[++i] + 108;
|
||||
value = (value - 247) * 256 + encoded[++i] + 108;
|
||||
} else if (value <= 254) {
|
||||
value = -((value - 251) * 256) - encoded[++i] - 108;
|
||||
} else {
|
||||
value = (encoded[++i] & 0xff) << 24 | (encoded[++i] & 0xff) << 16 |
|
||||
(encoded[++i] & 0xff) << 8 | (encoded[++i] & 0xff) << 0;
|
||||
value =
|
||||
((encoded[++i] & 0xff) << 24) |
|
||||
((encoded[++i] & 0xff) << 16) |
|
||||
((encoded[++i] & 0xff) << 8) |
|
||||
((encoded[++i] & 0xff) << 0);
|
||||
}
|
||||
this.stack.push(value);
|
||||
}
|
||||
|
@ -330,13 +339,16 @@ var Type1CharString = (function Type1CharStringClosure() {
|
|||
var value = this.stack[i];
|
||||
if (Number.isInteger(value)) {
|
||||
this.output.push(28, (value >> 8) & 0xff, value & 0xff);
|
||||
} else { // fixed point
|
||||
} else {
|
||||
// fixed point
|
||||
value = (65536 * value) | 0;
|
||||
this.output.push(255,
|
||||
(value >> 24) & 0xFF,
|
||||
(value >> 16) & 0xFF,
|
||||
(value >> 8) & 0xFF,
|
||||
value & 0xFF);
|
||||
this.output.push(
|
||||
255,
|
||||
(value >> 24) & 0xff,
|
||||
(value >> 16) & 0xff,
|
||||
(value >> 8) & 0xff,
|
||||
value & 0xff
|
||||
);
|
||||
}
|
||||
}
|
||||
this.output.push.apply(this.output, command);
|
||||
|
@ -370,16 +382,22 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
var CHAR_STRS_ENCRYPT_KEY = 4330;
|
||||
|
||||
function isHexDigit(code) {
|
||||
return code >= 48 && code <= 57 || // '0'-'9'
|
||||
code >= 65 && code <= 70 || // 'A'-'F'
|
||||
code >= 97 && code <= 102; // 'a'-'f'
|
||||
return (
|
||||
(code >= 48 && code <= 57) || // '0'-'9'
|
||||
(code >= 65 && code <= 70) || // 'A'-'F'
|
||||
(code >= 97 && code <= 102)
|
||||
); // 'a'-'f'
|
||||
}
|
||||
|
||||
function decrypt(data, key, discardNumber) {
|
||||
if (discardNumber >= data.length) {
|
||||
return new Uint8Array(0);
|
||||
}
|
||||
var r = key | 0, c1 = 52845, c2 = 22719, i, j;
|
||||
var r = key | 0,
|
||||
c1 = 52845,
|
||||
c2 = 22719,
|
||||
i,
|
||||
j;
|
||||
for (i = 0; i < discardNumber; i++) {
|
||||
r = ((data[i] + r) * c1 + c2) & ((1 << 16) - 1);
|
||||
}
|
||||
|
@ -394,8 +412,11 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
}
|
||||
|
||||
function decryptAscii(data, key, discardNumber) {
|
||||
var r = key | 0, c1 = 52845, c2 = 22719;
|
||||
var count = data.length, maybeLength = count >>> 1;
|
||||
var r = key | 0,
|
||||
c1 = 52845,
|
||||
c2 = 22719;
|
||||
var count = data.length,
|
||||
maybeLength = count >>> 1;
|
||||
var decrypted = new Uint8Array(maybeLength);
|
||||
var i, j;
|
||||
for (i = 0, j = 0; i < count; i++) {
|
||||
|
@ -405,7 +426,7 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
}
|
||||
i++;
|
||||
var digit2;
|
||||
while (i < count && !isHexDigit(digit2 = data[i])) {
|
||||
while (i < count && !isHexDigit((digit2 = data[i]))) {
|
||||
i++;
|
||||
}
|
||||
if (i < count) {
|
||||
|
@ -418,19 +439,31 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
}
|
||||
|
||||
function isSpecial(c) {
|
||||
return c === 0x2F || // '/'
|
||||
c === 0x5B || c === 0x5D || // '[', ']'
|
||||
c === 0x7B || c === 0x7D || // '{', '}'
|
||||
c === 0x28 || c === 0x29; // '(', ')'
|
||||
return (
|
||||
c === 0x2f || // '/'
|
||||
c === 0x5b ||
|
||||
c === 0x5d || // '[', ']'
|
||||
c === 0x7b ||
|
||||
c === 0x7d || // '{', '}'
|
||||
c === 0x28 ||
|
||||
c === 0x29
|
||||
); // '(', ')'
|
||||
}
|
||||
|
||||
function Type1Parser(stream, encrypted, seacAnalysisEnabled) {
|
||||
if (encrypted) {
|
||||
var data = stream.getBytes();
|
||||
var isBinary = !(isHexDigit(data[0]) && isHexDigit(data[1]) &&
|
||||
isHexDigit(data[2]) && isHexDigit(data[3]));
|
||||
stream = new Stream(isBinary ? decrypt(data, EEXEC_ENCRYPT_KEY, 4) :
|
||||
decryptAscii(data, EEXEC_ENCRYPT_KEY, 4));
|
||||
var isBinary = !(
|
||||
isHexDigit(data[0]) &&
|
||||
isHexDigit(data[1]) &&
|
||||
isHexDigit(data[2]) &&
|
||||
isHexDigit(data[3])
|
||||
);
|
||||
stream = new Stream(
|
||||
isBinary
|
||||
? decrypt(data, EEXEC_ENCRYPT_KEY, 4)
|
||||
: decryptAscii(data, EEXEC_ENCRYPT_KEY, 4)
|
||||
);
|
||||
}
|
||||
this.seacAnalysisEnabled = !!seacAnalysisEnabled;
|
||||
|
||||
|
@ -444,7 +477,7 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
var array = [];
|
||||
while (true) {
|
||||
var token = this.getToken();
|
||||
if (token === null || token === ']' || token === '}') {
|
||||
if (token === null || token === "]" || token === "}") {
|
||||
break;
|
||||
}
|
||||
array.push(parseFloat(token || 0));
|
||||
|
@ -468,7 +501,7 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
var token = this.getToken();
|
||||
|
||||
// Use 1 and 0 since that's what type2 charstrings use.
|
||||
return token === 'true' ? 1 : 0;
|
||||
return token === "true" ? 1 : 0;
|
||||
},
|
||||
|
||||
nextChar: function Type1_nextChar() {
|
||||
|
@ -485,10 +518,11 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
}
|
||||
|
||||
if (comment) {
|
||||
if (ch === 0x0A || ch === 0x0D) {
|
||||
if (ch === 0x0a || ch === 0x0d) {
|
||||
comment = false;
|
||||
}
|
||||
} else if (ch === 0x25) { // '%'
|
||||
} else if (ch === 0x25) {
|
||||
// '%'
|
||||
comment = true;
|
||||
} else if (!isSpace(ch)) {
|
||||
break;
|
||||
|
@ -499,7 +533,7 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
this.nextChar();
|
||||
return String.fromCharCode(ch);
|
||||
}
|
||||
var token = '';
|
||||
var token = "";
|
||||
do {
|
||||
token += String.fromCharCode(ch);
|
||||
ch = this.nextChar();
|
||||
|
@ -523,24 +557,25 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
extractFontProgram: function Type1Parser_extractFontProgram(properties) {
|
||||
var stream = this.stream;
|
||||
|
||||
var subrs = [], charstrings = [];
|
||||
var subrs = [],
|
||||
charstrings = [];
|
||||
var privateData = Object.create(null);
|
||||
privateData['lenIV'] = 4;
|
||||
privateData["lenIV"] = 4;
|
||||
var program = {
|
||||
subrs: [],
|
||||
charstrings: [],
|
||||
properties: {
|
||||
'privateData': privateData,
|
||||
privateData,
|
||||
},
|
||||
};
|
||||
var token, length, data, lenIV, encoded;
|
||||
while ((token = this.getToken()) !== null) {
|
||||
if (token !== '/') {
|
||||
if (token !== "/") {
|
||||
continue;
|
||||
}
|
||||
token = this.getToken();
|
||||
switch (token) {
|
||||
case 'CharStrings':
|
||||
case "CharStrings":
|
||||
// The number immediately following CharStrings must be greater or
|
||||
// equal to the number of CharStrings.
|
||||
this.getToken();
|
||||
|
@ -549,22 +584,22 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
this.getToken(); // read in 'begin'
|
||||
while (true) {
|
||||
token = this.getToken();
|
||||
if (token === null || token === 'end') {
|
||||
if (token === null || token === "end") {
|
||||
break;
|
||||
}
|
||||
|
||||
if (token !== '/') {
|
||||
if (token !== "/") {
|
||||
continue;
|
||||
}
|
||||
var glyph = this.getToken();
|
||||
length = this.readInt();
|
||||
this.getToken(); // read in 'RD' or '-|'
|
||||
data = (length > 0 ? stream.getBytes(length) : new Uint8Array(0));
|
||||
lenIV = program.properties.privateData['lenIV'];
|
||||
data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
|
||||
lenIV = program.properties.privateData["lenIV"];
|
||||
encoded = this.readCharStrings(data, lenIV);
|
||||
this.nextChar();
|
||||
token = this.getToken(); // read in 'ND' or '|-'
|
||||
if (token === 'noaccess') {
|
||||
if (token === "noaccess") {
|
||||
this.getToken(); // read in 'def'
|
||||
}
|
||||
charstrings.push({
|
||||
|
@ -573,54 +608,56 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
});
|
||||
}
|
||||
break;
|
||||
case 'Subrs':
|
||||
case "Subrs":
|
||||
this.readInt(); // num
|
||||
this.getToken(); // read in 'array'
|
||||
while (this.getToken() === 'dup') {
|
||||
while (this.getToken() === "dup") {
|
||||
var index = this.readInt();
|
||||
length = this.readInt();
|
||||
this.getToken(); // read in 'RD' or '-|'
|
||||
data = (length > 0 ? stream.getBytes(length) : new Uint8Array(0));
|
||||
lenIV = program.properties.privateData['lenIV'];
|
||||
data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
|
||||
lenIV = program.properties.privateData["lenIV"];
|
||||
encoded = this.readCharStrings(data, lenIV);
|
||||
this.nextChar();
|
||||
token = this.getToken(); // read in 'NP' or '|'
|
||||
if (token === 'noaccess') {
|
||||
if (token === "noaccess") {
|
||||
this.getToken(); // read in 'put'
|
||||
}
|
||||
subrs[index] = encoded;
|
||||
}
|
||||
break;
|
||||
case 'BlueValues':
|
||||
case 'OtherBlues':
|
||||
case 'FamilyBlues':
|
||||
case 'FamilyOtherBlues':
|
||||
case "BlueValues":
|
||||
case "OtherBlues":
|
||||
case "FamilyBlues":
|
||||
case "FamilyOtherBlues":
|
||||
var blueArray = this.readNumberArray();
|
||||
// *Blue* values may contain invalid data: disables reading of
|
||||
// those values when hinting is disabled.
|
||||
if (blueArray.length > 0 && (blueArray.length % 2) === 0 &&
|
||||
HINTING_ENABLED) {
|
||||
if (
|
||||
blueArray.length > 0 &&
|
||||
blueArray.length % 2 === 0 &&
|
||||
HINTING_ENABLED
|
||||
) {
|
||||
program.properties.privateData[token] = blueArray;
|
||||
}
|
||||
break;
|
||||
case 'StemSnapH':
|
||||
case 'StemSnapV':
|
||||
case "StemSnapH":
|
||||
case "StemSnapV":
|
||||
program.properties.privateData[token] = this.readNumberArray();
|
||||
break;
|
||||
case 'StdHW':
|
||||
case 'StdVW':
|
||||
program.properties.privateData[token] =
|
||||
this.readNumberArray()[0];
|
||||
case "StdHW":
|
||||
case "StdVW":
|
||||
program.properties.privateData[token] = this.readNumberArray()[0];
|
||||
break;
|
||||
case 'BlueShift':
|
||||
case 'lenIV':
|
||||
case 'BlueFuzz':
|
||||
case 'BlueScale':
|
||||
case 'LanguageGroup':
|
||||
case 'ExpansionFactor':
|
||||
case "BlueShift":
|
||||
case "lenIV":
|
||||
case "BlueFuzz":
|
||||
case "BlueScale":
|
||||
case "LanguageGroup":
|
||||
case "ExpansionFactor":
|
||||
program.properties.privateData[token] = this.readNumber();
|
||||
break;
|
||||
case 'ForceBold':
|
||||
case "ForceBold":
|
||||
program.properties.privateData[token] = this.readBoolean();
|
||||
break;
|
||||
}
|
||||
|
@ -630,8 +667,11 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
glyph = charstrings[i].glyph;
|
||||
encoded = charstrings[i].encoded;
|
||||
var charString = new Type1CharString();
|
||||
var error = charString.convert(encoded, subrs,
|
||||
this.seacAnalysisEnabled);
|
||||
var error = charString.convert(
|
||||
encoded,
|
||||
subrs,
|
||||
this.seacAnalysisEnabled
|
||||
);
|
||||
var output = charString.output;
|
||||
if (error) {
|
||||
// It seems when FreeType encounters an error while evaluating a glyph
|
||||
|
@ -651,8 +691,12 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
// entry, with ones from the font data (fixes issue11150_reduced.pdf).
|
||||
if (properties.builtInEncoding) {
|
||||
const index = properties.builtInEncoding.indexOf(glyph);
|
||||
if (index > -1 && properties.widths[index] === undefined &&
|
||||
index >= properties.firstChar && index <= properties.lastChar) {
|
||||
if (
|
||||
index > -1 &&
|
||||
properties.widths[index] === undefined &&
|
||||
index >= properties.firstChar &&
|
||||
index <= properties.lastChar
|
||||
) {
|
||||
properties.widths[index] = charString.width;
|
||||
}
|
||||
}
|
||||
|
@ -664,16 +708,16 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
extractFontHeader: function Type1Parser_extractFontHeader(properties) {
|
||||
var token;
|
||||
while ((token = this.getToken()) !== null) {
|
||||
if (token !== '/') {
|
||||
if (token !== "/") {
|
||||
continue;
|
||||
}
|
||||
token = this.getToken();
|
||||
switch (token) {
|
||||
case 'FontMatrix':
|
||||
case "FontMatrix":
|
||||
var matrix = this.readNumberArray();
|
||||
properties.fontMatrix = matrix;
|
||||
break;
|
||||
case 'Encoding':
|
||||
case "Encoding":
|
||||
var encodingArg = this.getToken();
|
||||
var encoding;
|
||||
if (!/^\d+$/.test(encodingArg)) {
|
||||
|
@ -687,13 +731,13 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
for (var j = 0; j < size; j++) {
|
||||
token = this.getToken();
|
||||
// skipping till first dup or def (e.g. ignoring for statement)
|
||||
while (token !== 'dup' && token !== 'def') {
|
||||
while (token !== "dup" && token !== "def") {
|
||||
token = this.getToken();
|
||||
if (token === null) {
|
||||
return; // invalid header
|
||||
}
|
||||
}
|
||||
if (token === 'def') {
|
||||
if (token === "def") {
|
||||
break; // read all array data
|
||||
}
|
||||
var index = this.readInt();
|
||||
|
@ -705,7 +749,7 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
}
|
||||
properties.builtInEncoding = encoding;
|
||||
break;
|
||||
case 'FontBBox':
|
||||
case "FontBBox":
|
||||
var fontBBox = this.readNumberArray();
|
||||
// adjusting ascent/descent
|
||||
properties.ascent = Math.max(fontBBox[3], fontBBox[1]);
|
||||
|
@ -720,6 +764,4 @@ var Type1Parser = (function Type1ParserClosure() {
|
|||
return Type1Parser;
|
||||
})();
|
||||
|
||||
export {
|
||||
Type1Parser,
|
||||
};
|
||||
export { Type1Parser };
|
||||
|
|
3075
src/core/unicode.js
3075
src/core/unicode.js
File diff suppressed because it is too large
Load diff
|
@ -14,17 +14,28 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
AbortException, arrayByteLength, arraysToBytes, createPromiseCapability,
|
||||
getVerbosityLevel, info, InvalidPDFException, MissingPDFException,
|
||||
PasswordException, setVerbosityLevel, UnexpectedResponseException,
|
||||
UnknownErrorException, UNSUPPORTED_FEATURES, VerbosityLevel, warn
|
||||
} from '../shared/util';
|
||||
import { clearPrimitiveCaches, Ref } from './primitives';
|
||||
import { LocalPdfManager, NetworkPdfManager } from './pdf_manager';
|
||||
import { isNodeJS } from '../shared/is_node';
|
||||
import { MessageHandler } from '../shared/message_handler';
|
||||
import { PDFWorkerStream } from './worker_stream';
|
||||
import { XRefParseException } from './core_utils';
|
||||
AbortException,
|
||||
arrayByteLength,
|
||||
arraysToBytes,
|
||||
createPromiseCapability,
|
||||
getVerbosityLevel,
|
||||
info,
|
||||
InvalidPDFException,
|
||||
MissingPDFException,
|
||||
PasswordException,
|
||||
setVerbosityLevel,
|
||||
UnexpectedResponseException,
|
||||
UnknownErrorException,
|
||||
UNSUPPORTED_FEATURES,
|
||||
VerbosityLevel,
|
||||
warn,
|
||||
} from "../shared/util";
|
||||
import { clearPrimitiveCaches, Ref } from "./primitives";
|
||||
import { LocalPdfManager, NetworkPdfManager } from "./pdf_manager";
|
||||
import { isNodeJS } from "../shared/is_node";
|
||||
import { MessageHandler } from "../shared/message_handler";
|
||||
import { PDFWorkerStream } from "./worker_stream";
|
||||
import { XRefParseException } from "./core_utils";
|
||||
|
||||
var WorkerTask = (function WorkerTaskClosure() {
|
||||
function WorkerTask(name) {
|
||||
|
@ -48,7 +59,7 @@ var WorkerTask = (function WorkerTaskClosure() {
|
|||
|
||||
ensureNotTerminated() {
|
||||
if (this.terminated) {
|
||||
throw new Error('Worker task was terminated');
|
||||
throw new Error("Worker task was terminated");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -59,7 +70,7 @@ var WorkerTask = (function WorkerTaskClosure() {
|
|||
var WorkerMessageHandler = {
|
||||
setup(handler, port) {
|
||||
var testMessageProcessed = false;
|
||||
handler.on('test', function wphSetupTest(data) {
|
||||
handler.on("test", function wphSetupTest(data) {
|
||||
if (testMessageProcessed) {
|
||||
return; // we already processed 'test' message once
|
||||
}
|
||||
|
@ -67,21 +78,21 @@ var WorkerMessageHandler = {
|
|||
|
||||
// check if Uint8Array can be sent to worker
|
||||
if (!(data instanceof Uint8Array)) {
|
||||
handler.send('test', null);
|
||||
handler.send("test", null);
|
||||
return;
|
||||
}
|
||||
// making sure postMessage transfers are working
|
||||
const supportTransfers = data[0] === 255;
|
||||
handler.postMessageTransfers = supportTransfers;
|
||||
|
||||
handler.send('test', { supportTransfers, });
|
||||
handler.send("test", { supportTransfers });
|
||||
});
|
||||
|
||||
handler.on('configure', function wphConfigure(data) {
|
||||
handler.on("configure", function wphConfigure(data) {
|
||||
setVerbosityLevel(data.verbosity);
|
||||
});
|
||||
|
||||
handler.on('GetDocRequest', function wphSetupDoc(data) {
|
||||
handler.on("GetDocRequest", function wphSetupDoc(data) {
|
||||
return WorkerMessageHandler.createDocumentHandler(data, port);
|
||||
});
|
||||
},
|
||||
|
@ -96,16 +107,19 @@ var WorkerMessageHandler = {
|
|||
|
||||
const apiVersion = docParams.apiVersion;
|
||||
const workerVersion =
|
||||
typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('TESTING') ?
|
||||
PDFJSDev.eval('BUNDLE_VERSION') : null;
|
||||
typeof PDFJSDev !== "undefined" && !PDFJSDev.test("TESTING")
|
||||
? PDFJSDev.eval("BUNDLE_VERSION")
|
||||
: null;
|
||||
if (apiVersion !== workerVersion) {
|
||||
throw new Error(`The API version "${apiVersion}" does not match ` +
|
||||
`the Worker version "${workerVersion}".`);
|
||||
throw new Error(
|
||||
`The API version "${apiVersion}" does not match ` +
|
||||
`the Worker version "${workerVersion}".`
|
||||
);
|
||||
}
|
||||
|
||||
var docId = docParams.docId;
|
||||
var docBaseUrl = docParams.docBaseUrl;
|
||||
var workerHandlerName = docParams.docId + '_worker';
|
||||
var workerHandlerName = docParams.docId + "_worker";
|
||||
var handler = new MessageHandler(workerHandlerName, docId, port);
|
||||
|
||||
// Ensure that postMessage transfers are always correctly enabled/disabled,
|
||||
|
@ -114,7 +128,7 @@ var WorkerMessageHandler = {
|
|||
|
||||
function ensureNotTerminated() {
|
||||
if (terminated) {
|
||||
throw new Error('Worker was terminated');
|
||||
throw new Error("Worker was terminated");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,21 +143,21 @@ var WorkerMessageHandler = {
|
|||
}
|
||||
|
||||
async function loadDocument(recoveryMode) {
|
||||
await pdfManager.ensureDoc('checkHeader');
|
||||
await pdfManager.ensureDoc('parseStartXRef');
|
||||
await pdfManager.ensureDoc('parse', [recoveryMode]);
|
||||
await pdfManager.ensureDoc("checkHeader");
|
||||
await pdfManager.ensureDoc("parseStartXRef");
|
||||
await pdfManager.ensureDoc("parse", [recoveryMode]);
|
||||
|
||||
if (!recoveryMode) {
|
||||
// Check that at least the first page can be successfully loaded,
|
||||
// since otherwise the XRef table is definitely not valid.
|
||||
await pdfManager.ensureDoc('checkFirstPage');
|
||||
await pdfManager.ensureDoc("checkFirstPage");
|
||||
}
|
||||
|
||||
const [numPages, fingerprint] = await Promise.all([
|
||||
pdfManager.ensureDoc('numPages'),
|
||||
pdfManager.ensureDoc('fingerprint'),
|
||||
pdfManager.ensureDoc("numPages"),
|
||||
pdfManager.ensureDoc("fingerprint"),
|
||||
]);
|
||||
return { numPages, fingerprint, };
|
||||
return { numPages, fingerprint };
|
||||
}
|
||||
|
||||
function getPdfManager(data, evaluatorOptions) {
|
||||
|
@ -153,8 +167,13 @@ var WorkerMessageHandler = {
|
|||
var source = data.source;
|
||||
if (source.data) {
|
||||
try {
|
||||
pdfManager = new LocalPdfManager(docId, source.data, source.password,
|
||||
evaluatorOptions, docBaseUrl);
|
||||
pdfManager = new LocalPdfManager(
|
||||
docId,
|
||||
source.data,
|
||||
source.password,
|
||||
evaluatorOptions,
|
||||
docBaseUrl
|
||||
);
|
||||
pdfManagerCapability.resolve(pdfManager);
|
||||
} catch (ex) {
|
||||
pdfManagerCapability.reject(ex);
|
||||
|
@ -162,7 +181,8 @@ var WorkerMessageHandler = {
|
|||
return pdfManagerCapability.promise;
|
||||
}
|
||||
|
||||
var pdfStream, cachedChunks = [];
|
||||
var pdfStream,
|
||||
cachedChunks = [];
|
||||
try {
|
||||
pdfStream = new PDFWorkerStream(handler);
|
||||
} catch (ex) {
|
||||
|
@ -171,55 +191,68 @@ var WorkerMessageHandler = {
|
|||
}
|
||||
|
||||
var fullRequest = pdfStream.getFullReader();
|
||||
fullRequest.headersReady.then(function () {
|
||||
if (!fullRequest.isRangeSupported) {
|
||||
return;
|
||||
}
|
||||
fullRequest.headersReady
|
||||
.then(function() {
|
||||
if (!fullRequest.isRangeSupported) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't need auto-fetch when streaming is enabled.
|
||||
var disableAutoFetch = source.disableAutoFetch ||
|
||||
fullRequest.isStreamingSupported;
|
||||
pdfManager = new NetworkPdfManager(docId, pdfStream, {
|
||||
msgHandler: handler,
|
||||
password: source.password,
|
||||
length: fullRequest.contentLength,
|
||||
disableAutoFetch,
|
||||
rangeChunkSize: source.rangeChunkSize,
|
||||
}, evaluatorOptions, docBaseUrl);
|
||||
// There may be a chance that `pdfManager` is not initialized
|
||||
// for first few runs of `readchunk` block of code. Be sure
|
||||
// to send all cached chunks, if any, to chunked_stream via
|
||||
// pdf_manager.
|
||||
for (let i = 0; i < cachedChunks.length; i++) {
|
||||
pdfManager.sendProgressiveData(cachedChunks[i]);
|
||||
}
|
||||
// We don't need auto-fetch when streaming is enabled.
|
||||
var disableAutoFetch =
|
||||
source.disableAutoFetch || fullRequest.isStreamingSupported;
|
||||
pdfManager = new NetworkPdfManager(
|
||||
docId,
|
||||
pdfStream,
|
||||
{
|
||||
msgHandler: handler,
|
||||
password: source.password,
|
||||
length: fullRequest.contentLength,
|
||||
disableAutoFetch,
|
||||
rangeChunkSize: source.rangeChunkSize,
|
||||
},
|
||||
evaluatorOptions,
|
||||
docBaseUrl
|
||||
);
|
||||
// There may be a chance that `pdfManager` is not initialized
|
||||
// for first few runs of `readchunk` block of code. Be sure
|
||||
// to send all cached chunks, if any, to chunked_stream via
|
||||
// pdf_manager.
|
||||
for (let i = 0; i < cachedChunks.length; i++) {
|
||||
pdfManager.sendProgressiveData(cachedChunks[i]);
|
||||
}
|
||||
|
||||
cachedChunks = [];
|
||||
pdfManagerCapability.resolve(pdfManager);
|
||||
cancelXHRs = null;
|
||||
}).catch(function (reason) {
|
||||
pdfManagerCapability.reject(reason);
|
||||
cancelXHRs = null;
|
||||
});
|
||||
cachedChunks = [];
|
||||
pdfManagerCapability.resolve(pdfManager);
|
||||
cancelXHRs = null;
|
||||
})
|
||||
.catch(function(reason) {
|
||||
pdfManagerCapability.reject(reason);
|
||||
cancelXHRs = null;
|
||||
});
|
||||
|
||||
var loaded = 0;
|
||||
var flushChunks = function () {
|
||||
var flushChunks = function() {
|
||||
var pdfFile = arraysToBytes(cachedChunks);
|
||||
if (source.length && pdfFile.length !== source.length) {
|
||||
warn('reported HTTP length is different from actual');
|
||||
warn("reported HTTP length is different from actual");
|
||||
}
|
||||
// the data is array, instantiating directly from it
|
||||
try {
|
||||
pdfManager = new LocalPdfManager(docId, pdfFile, source.password,
|
||||
evaluatorOptions, docBaseUrl);
|
||||
pdfManager = new LocalPdfManager(
|
||||
docId,
|
||||
pdfFile,
|
||||
source.password,
|
||||
evaluatorOptions,
|
||||
docBaseUrl
|
||||
);
|
||||
pdfManagerCapability.resolve(pdfManager);
|
||||
} catch (ex) {
|
||||
pdfManagerCapability.reject(ex);
|
||||
}
|
||||
cachedChunks = [];
|
||||
};
|
||||
var readPromise = new Promise(function (resolve, reject) {
|
||||
var readChunk = function (chunk) {
|
||||
var readPromise = new Promise(function(resolve, reject) {
|
||||
var readChunk = function(chunk) {
|
||||
try {
|
||||
ensureNotTerminated();
|
||||
if (chunk.done) {
|
||||
|
@ -233,7 +266,7 @@ var WorkerMessageHandler = {
|
|||
var data = chunk.value;
|
||||
loaded += arrayByteLength(data);
|
||||
if (!fullRequest.isStreamingSupported) {
|
||||
handler.send('DocProgress', {
|
||||
handler.send("DocProgress", {
|
||||
loaded,
|
||||
total: Math.max(loaded, fullRequest.contentLength || 0),
|
||||
});
|
||||
|
@ -252,7 +285,7 @@ var WorkerMessageHandler = {
|
|||
};
|
||||
fullRequest.read().then(readChunk, reject);
|
||||
});
|
||||
readPromise.catch(function (e) {
|
||||
readPromise.catch(function(e) {
|
||||
pdfManagerCapability.reject(e);
|
||||
cancelXHRs = null;
|
||||
});
|
||||
|
@ -267,7 +300,7 @@ var WorkerMessageHandler = {
|
|||
function setupDoc(data) {
|
||||
function onSuccess(doc) {
|
||||
ensureNotTerminated();
|
||||
handler.send('GetDoc', { pdfInfo: doc, });
|
||||
handler.send("GetDoc", { pdfInfo: doc });
|
||||
}
|
||||
|
||||
function onFailure(ex) {
|
||||
|
@ -277,43 +310,54 @@ var WorkerMessageHandler = {
|
|||
var task = new WorkerTask(`PasswordException: response ${ex.code}`);
|
||||
startWorkerTask(task);
|
||||
|
||||
handler.sendWithPromise('PasswordRequest', ex).then(function(data) {
|
||||
finishWorkerTask(task);
|
||||
pdfManager.updatePassword(data.password);
|
||||
pdfManagerReady();
|
||||
}).catch(function() {
|
||||
finishWorkerTask(task);
|
||||
handler.send('DocException', ex);
|
||||
});
|
||||
} else if (ex instanceof InvalidPDFException ||
|
||||
ex instanceof MissingPDFException ||
|
||||
ex instanceof UnexpectedResponseException ||
|
||||
ex instanceof UnknownErrorException) {
|
||||
handler.send('DocException', ex);
|
||||
handler
|
||||
.sendWithPromise("PasswordRequest", ex)
|
||||
.then(function(data) {
|
||||
finishWorkerTask(task);
|
||||
pdfManager.updatePassword(data.password);
|
||||
pdfManagerReady();
|
||||
})
|
||||
.catch(function() {
|
||||
finishWorkerTask(task);
|
||||
handler.send("DocException", ex);
|
||||
});
|
||||
} else if (
|
||||
ex instanceof InvalidPDFException ||
|
||||
ex instanceof MissingPDFException ||
|
||||
ex instanceof UnexpectedResponseException ||
|
||||
ex instanceof UnknownErrorException
|
||||
) {
|
||||
handler.send("DocException", ex);
|
||||
} else {
|
||||
handler.send('DocException',
|
||||
new UnknownErrorException(ex.message, ex.toString()));
|
||||
handler.send(
|
||||
"DocException",
|
||||
new UnknownErrorException(ex.message, ex.toString())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function pdfManagerReady() {
|
||||
ensureNotTerminated();
|
||||
|
||||
loadDocument(false).then(onSuccess, function loadFailure(ex) {
|
||||
ensureNotTerminated();
|
||||
|
||||
// Try again with recoveryMode == true
|
||||
if (!(ex instanceof XRefParseException)) {
|
||||
onFailure(ex);
|
||||
return;
|
||||
}
|
||||
pdfManager.requestLoadedStream();
|
||||
pdfManager.onLoadedStream().then(function() {
|
||||
loadDocument(false).then(
|
||||
onSuccess,
|
||||
function loadFailure(ex) {
|
||||
ensureNotTerminated();
|
||||
|
||||
loadDocument(true).then(onSuccess, onFailure);
|
||||
});
|
||||
}, onFailure);
|
||||
// Try again with recoveryMode == true
|
||||
if (!(ex instanceof XRefParseException)) {
|
||||
onFailure(ex);
|
||||
return;
|
||||
}
|
||||
pdfManager.requestLoadedStream();
|
||||
pdfManager.onLoadedStream().then(function() {
|
||||
ensureNotTerminated();
|
||||
|
||||
loadDocument(true).then(onSuccess, onFailure);
|
||||
});
|
||||
},
|
||||
onFailure
|
||||
);
|
||||
}
|
||||
|
||||
ensureNotTerminated();
|
||||
|
@ -327,28 +371,32 @@ var WorkerMessageHandler = {
|
|||
isEvalSupported: data.isEvalSupported,
|
||||
};
|
||||
|
||||
getPdfManager(data, evaluatorOptions).then(function (newPdfManager) {
|
||||
if (terminated) {
|
||||
// We were in a process of setting up the manager, but it got
|
||||
// terminated in the middle.
|
||||
newPdfManager.terminate(new AbortException('Worker was terminated.'));
|
||||
throw new Error('Worker was terminated');
|
||||
}
|
||||
pdfManager = newPdfManager;
|
||||
getPdfManager(data, evaluatorOptions)
|
||||
.then(function(newPdfManager) {
|
||||
if (terminated) {
|
||||
// We were in a process of setting up the manager, but it got
|
||||
// terminated in the middle.
|
||||
newPdfManager.terminate(
|
||||
new AbortException("Worker was terminated.")
|
||||
);
|
||||
throw new Error("Worker was terminated");
|
||||
}
|
||||
pdfManager = newPdfManager;
|
||||
|
||||
pdfManager.onLoadedStream().then(function(stream) {
|
||||
handler.send('DataLoaded', { length: stream.bytes.byteLength, });
|
||||
});
|
||||
}).then(pdfManagerReady, onFailure);
|
||||
pdfManager.onLoadedStream().then(function(stream) {
|
||||
handler.send("DataLoaded", { length: stream.bytes.byteLength });
|
||||
});
|
||||
})
|
||||
.then(pdfManagerReady, onFailure);
|
||||
}
|
||||
|
||||
handler.on('GetPage', function wphSetupGetPage(data) {
|
||||
handler.on("GetPage", function wphSetupGetPage(data) {
|
||||
return pdfManager.getPage(data.pageIndex).then(function(page) {
|
||||
return Promise.all([
|
||||
pdfManager.ensure(page, 'rotate'),
|
||||
pdfManager.ensure(page, 'ref'),
|
||||
pdfManager.ensure(page, 'userUnit'),
|
||||
pdfManager.ensure(page, 'view'),
|
||||
pdfManager.ensure(page, "rotate"),
|
||||
pdfManager.ensure(page, "ref"),
|
||||
pdfManager.ensure(page, "userUnit"),
|
||||
pdfManager.ensure(page, "view"),
|
||||
]).then(function([rotate, ref, userUnit, view]) {
|
||||
return {
|
||||
rotate,
|
||||
|
@ -360,201 +408,206 @@ var WorkerMessageHandler = {
|
|||
});
|
||||
});
|
||||
|
||||
handler.on('GetPageIndex', function wphSetupGetPageIndex(data) {
|
||||
handler.on("GetPageIndex", function wphSetupGetPageIndex(data) {
|
||||
var ref = Ref.get(data.ref.num, data.ref.gen);
|
||||
var catalog = pdfManager.pdfDocument.catalog;
|
||||
return catalog.getPageIndex(ref);
|
||||
});
|
||||
|
||||
handler.on('GetDestinations',
|
||||
function wphSetupGetDestinations(data) {
|
||||
return pdfManager.ensureCatalog('destinations');
|
||||
}
|
||||
);
|
||||
|
||||
handler.on('GetDestination',
|
||||
function wphSetupGetDestination(data) {
|
||||
return pdfManager.ensureCatalog('getDestination', [data.id]);
|
||||
}
|
||||
);
|
||||
|
||||
handler.on('GetPageLabels',
|
||||
function wphSetupGetPageLabels(data) {
|
||||
return pdfManager.ensureCatalog('pageLabels');
|
||||
}
|
||||
);
|
||||
|
||||
handler.on('GetPageLayout', function wphSetupGetPageLayout(data) {
|
||||
return pdfManager.ensureCatalog('pageLayout');
|
||||
handler.on("GetDestinations", function wphSetupGetDestinations(data) {
|
||||
return pdfManager.ensureCatalog("destinations");
|
||||
});
|
||||
|
||||
handler.on('GetPageMode', function wphSetupGetPageMode(data) {
|
||||
return pdfManager.ensureCatalog('pageMode');
|
||||
handler.on("GetDestination", function wphSetupGetDestination(data) {
|
||||
return pdfManager.ensureCatalog("getDestination", [data.id]);
|
||||
});
|
||||
|
||||
handler.on('GetViewerPreferences', function(data) {
|
||||
return pdfManager.ensureCatalog('viewerPreferences');
|
||||
handler.on("GetPageLabels", function wphSetupGetPageLabels(data) {
|
||||
return pdfManager.ensureCatalog("pageLabels");
|
||||
});
|
||||
|
||||
handler.on('GetOpenActionDestination', function(data) {
|
||||
return pdfManager.ensureCatalog('openActionDestination');
|
||||
handler.on("GetPageLayout", function wphSetupGetPageLayout(data) {
|
||||
return pdfManager.ensureCatalog("pageLayout");
|
||||
});
|
||||
|
||||
handler.on('GetAttachments',
|
||||
function wphSetupGetAttachments(data) {
|
||||
return pdfManager.ensureCatalog('attachments');
|
||||
}
|
||||
);
|
||||
|
||||
handler.on('GetJavaScript',
|
||||
function wphSetupGetJavaScript(data) {
|
||||
return pdfManager.ensureCatalog('javaScript');
|
||||
}
|
||||
);
|
||||
|
||||
handler.on('GetOutline',
|
||||
function wphSetupGetOutline(data) {
|
||||
return pdfManager.ensureCatalog('documentOutline');
|
||||
}
|
||||
);
|
||||
|
||||
handler.on('GetPermissions', function(data) {
|
||||
return pdfManager.ensureCatalog('permissions');
|
||||
handler.on("GetPageMode", function wphSetupGetPageMode(data) {
|
||||
return pdfManager.ensureCatalog("pageMode");
|
||||
});
|
||||
|
||||
handler.on('GetMetadata',
|
||||
function wphSetupGetMetadata(data) {
|
||||
return Promise.all([pdfManager.ensureDoc('documentInfo'),
|
||||
pdfManager.ensureCatalog('metadata')]);
|
||||
}
|
||||
);
|
||||
handler.on("GetViewerPreferences", function(data) {
|
||||
return pdfManager.ensureCatalog("viewerPreferences");
|
||||
});
|
||||
|
||||
handler.on('GetData', function wphSetupGetData(data) {
|
||||
handler.on("GetOpenActionDestination", function(data) {
|
||||
return pdfManager.ensureCatalog("openActionDestination");
|
||||
});
|
||||
|
||||
handler.on("GetAttachments", function wphSetupGetAttachments(data) {
|
||||
return pdfManager.ensureCatalog("attachments");
|
||||
});
|
||||
|
||||
handler.on("GetJavaScript", function wphSetupGetJavaScript(data) {
|
||||
return pdfManager.ensureCatalog("javaScript");
|
||||
});
|
||||
|
||||
handler.on("GetOutline", function wphSetupGetOutline(data) {
|
||||
return pdfManager.ensureCatalog("documentOutline");
|
||||
});
|
||||
|
||||
handler.on("GetPermissions", function(data) {
|
||||
return pdfManager.ensureCatalog("permissions");
|
||||
});
|
||||
|
||||
handler.on("GetMetadata", function wphSetupGetMetadata(data) {
|
||||
return Promise.all([
|
||||
pdfManager.ensureDoc("documentInfo"),
|
||||
pdfManager.ensureCatalog("metadata"),
|
||||
]);
|
||||
});
|
||||
|
||||
handler.on("GetData", function wphSetupGetData(data) {
|
||||
pdfManager.requestLoadedStream();
|
||||
return pdfManager.onLoadedStream().then(function(stream) {
|
||||
return stream.bytes;
|
||||
});
|
||||
});
|
||||
|
||||
handler.on('GetStats',
|
||||
function wphSetupGetStats(data) {
|
||||
return pdfManager.pdfDocument.xref.stats;
|
||||
}
|
||||
);
|
||||
handler.on("GetStats", function wphSetupGetStats(data) {
|
||||
return pdfManager.pdfDocument.xref.stats;
|
||||
});
|
||||
|
||||
handler.on('GetAnnotations', function({ pageIndex, intent, }) {
|
||||
handler.on("GetAnnotations", function({ pageIndex, intent }) {
|
||||
return pdfManager.getPage(pageIndex).then(function(page) {
|
||||
return page.getAnnotationsData(intent);
|
||||
});
|
||||
});
|
||||
|
||||
handler.on('GetOperatorList', function wphSetupRenderPage(data, sink) {
|
||||
handler.on(
|
||||
"GetOperatorList",
|
||||
function wphSetupRenderPage(data, sink) {
|
||||
var pageIndex = data.pageIndex;
|
||||
pdfManager.getPage(pageIndex).then(function(page) {
|
||||
var task = new WorkerTask(`GetOperatorList: page ${pageIndex}`);
|
||||
startWorkerTask(task);
|
||||
|
||||
// NOTE: Keep this condition in sync with the `info` helper function.
|
||||
const start = verbosity >= VerbosityLevel.INFOS ? Date.now() : 0;
|
||||
|
||||
// Pre compile the pdf page and fetch the fonts/images.
|
||||
page
|
||||
.getOperatorList({
|
||||
handler,
|
||||
sink,
|
||||
task,
|
||||
intent: data.intent,
|
||||
renderInteractiveForms: data.renderInteractiveForms,
|
||||
})
|
||||
.then(
|
||||
function(operatorListInfo) {
|
||||
finishWorkerTask(task);
|
||||
|
||||
if (start) {
|
||||
info(
|
||||
`page=${pageIndex + 1} - getOperatorList: time=` +
|
||||
`${Date.now() - start}ms, len=${operatorListInfo.length}`
|
||||
);
|
||||
}
|
||||
sink.close();
|
||||
},
|
||||
function(reason) {
|
||||
finishWorkerTask(task);
|
||||
if (task.terminated) {
|
||||
return; // ignoring errors from the terminated thread
|
||||
}
|
||||
// For compatibility with older behavior, generating unknown
|
||||
// unsupported feature notification on errors.
|
||||
handler.send("UnsupportedFeature", {
|
||||
featureId: UNSUPPORTED_FEATURES.unknown,
|
||||
});
|
||||
|
||||
sink.error(reason);
|
||||
|
||||
// TODO: Should `reason` be re-thrown here (currently that casues
|
||||
// "Uncaught exception: ..." messages in the console)?
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
this
|
||||
);
|
||||
|
||||
handler.on("GetTextContent", function wphExtractText(data, sink) {
|
||||
var pageIndex = data.pageIndex;
|
||||
sink.onPull = function(desiredSize) {};
|
||||
sink.onCancel = function(reason) {};
|
||||
|
||||
pdfManager.getPage(pageIndex).then(function(page) {
|
||||
var task = new WorkerTask(`GetOperatorList: page ${pageIndex}`);
|
||||
var task = new WorkerTask("GetTextContent: page " + pageIndex);
|
||||
startWorkerTask(task);
|
||||
|
||||
// NOTE: Keep this condition in sync with the `info` helper function.
|
||||
const start = (verbosity >= VerbosityLevel.INFOS ? Date.now() : 0);
|
||||
const start = verbosity >= VerbosityLevel.INFOS ? Date.now() : 0;
|
||||
|
||||
// Pre compile the pdf page and fetch the fonts/images.
|
||||
page.getOperatorList({
|
||||
handler,
|
||||
sink,
|
||||
task,
|
||||
intent: data.intent,
|
||||
renderInteractiveForms: data.renderInteractiveForms,
|
||||
}).then(function(operatorListInfo) {
|
||||
finishWorkerTask(task);
|
||||
page
|
||||
.extractTextContent({
|
||||
handler,
|
||||
task,
|
||||
sink,
|
||||
normalizeWhitespace: data.normalizeWhitespace,
|
||||
combineTextItems: data.combineTextItems,
|
||||
})
|
||||
.then(
|
||||
function() {
|
||||
finishWorkerTask(task);
|
||||
|
||||
if (start) {
|
||||
info(`page=${pageIndex + 1} - getOperatorList: time=` +
|
||||
`${Date.now() - start}ms, len=${operatorListInfo.length}`);
|
||||
}
|
||||
sink.close();
|
||||
}, function(reason) {
|
||||
finishWorkerTask(task);
|
||||
if (task.terminated) {
|
||||
return; // ignoring errors from the terminated thread
|
||||
}
|
||||
// For compatibility with older behavior, generating unknown
|
||||
// unsupported feature notification on errors.
|
||||
handler.send('UnsupportedFeature',
|
||||
{ featureId: UNSUPPORTED_FEATURES.unknown, });
|
||||
if (start) {
|
||||
info(
|
||||
`page=${pageIndex + 1} - getTextContent: time=` +
|
||||
`${Date.now() - start}ms`
|
||||
);
|
||||
}
|
||||
sink.close();
|
||||
},
|
||||
function(reason) {
|
||||
finishWorkerTask(task);
|
||||
if (task.terminated) {
|
||||
return; // ignoring errors from the terminated thread
|
||||
}
|
||||
sink.error(reason);
|
||||
|
||||
sink.error(reason);
|
||||
|
||||
// TODO: Should `reason` be re-thrown here (currently that casues
|
||||
// "Uncaught exception: ..." messages in the console)?
|
||||
});
|
||||
});
|
||||
}, this);
|
||||
|
||||
handler.on('GetTextContent', function wphExtractText(data, sink) {
|
||||
var pageIndex = data.pageIndex;
|
||||
sink.onPull = function (desiredSize) { };
|
||||
sink.onCancel = function (reason) { };
|
||||
|
||||
pdfManager.getPage(pageIndex).then(function(page) {
|
||||
var task = new WorkerTask('GetTextContent: page ' + pageIndex);
|
||||
startWorkerTask(task);
|
||||
|
||||
// NOTE: Keep this condition in sync with the `info` helper function.
|
||||
const start = (verbosity >= VerbosityLevel.INFOS ? Date.now() : 0);
|
||||
|
||||
page.extractTextContent({
|
||||
handler,
|
||||
task,
|
||||
sink,
|
||||
normalizeWhitespace: data.normalizeWhitespace,
|
||||
combineTextItems: data.combineTextItems,
|
||||
}).then(function() {
|
||||
finishWorkerTask(task);
|
||||
|
||||
if (start) {
|
||||
info(`page=${pageIndex + 1} - getTextContent: time=` +
|
||||
`${Date.now() - start}ms`);
|
||||
}
|
||||
sink.close();
|
||||
}, function (reason) {
|
||||
finishWorkerTask(task);
|
||||
if (task.terminated) {
|
||||
return; // ignoring errors from the terminated thread
|
||||
}
|
||||
sink.error(reason);
|
||||
|
||||
// TODO: Should `reason` be re-thrown here (currently that casues
|
||||
// "Uncaught exception: ..." messages in the console)?
|
||||
});
|
||||
// TODO: Should `reason` be re-thrown here (currently that casues
|
||||
// "Uncaught exception: ..." messages in the console)?
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
handler.on('FontFallback', function(data) {
|
||||
handler.on("FontFallback", function(data) {
|
||||
return pdfManager.fontFallback(data.id, handler);
|
||||
});
|
||||
|
||||
handler.on('Cleanup', function wphCleanup(data) {
|
||||
handler.on("Cleanup", function wphCleanup(data) {
|
||||
return pdfManager.cleanup();
|
||||
});
|
||||
|
||||
handler.on('Terminate', function wphTerminate(data) {
|
||||
handler.on("Terminate", function wphTerminate(data) {
|
||||
terminated = true;
|
||||
if (pdfManager) {
|
||||
pdfManager.terminate(new AbortException('Worker was terminated.'));
|
||||
pdfManager.terminate(new AbortException("Worker was terminated."));
|
||||
pdfManager = null;
|
||||
}
|
||||
if (cancelXHRs) {
|
||||
cancelXHRs(new AbortException('Worker was terminated.'));
|
||||
cancelXHRs(new AbortException("Worker was terminated."));
|
||||
}
|
||||
clearPrimitiveCaches();
|
||||
|
||||
var waitOn = [];
|
||||
WorkerTasks.forEach(function (task) {
|
||||
WorkerTasks.forEach(function(task) {
|
||||
waitOn.push(task.finished);
|
||||
task.terminate();
|
||||
});
|
||||
|
||||
return Promise.all(waitOn).then(function () {
|
||||
return Promise.all(waitOn).then(function() {
|
||||
// Notice that even if we destroying handler, resolved response promise
|
||||
// must be sent back.
|
||||
handler.destroy();
|
||||
|
@ -562,31 +615,33 @@ var WorkerMessageHandler = {
|
|||
});
|
||||
});
|
||||
|
||||
handler.on('Ready', function wphReady(data) {
|
||||
handler.on("Ready", function wphReady(data) {
|
||||
setupDoc(docParams);
|
||||
docParams = null; // we don't need docParams anymore -- saving memory.
|
||||
});
|
||||
return workerHandlerName;
|
||||
},
|
||||
initializeFromPort(port) {
|
||||
var handler = new MessageHandler('worker', 'main', port);
|
||||
var handler = new MessageHandler("worker", "main", port);
|
||||
WorkerMessageHandler.setup(handler, port);
|
||||
handler.send('ready', null);
|
||||
handler.send("ready", null);
|
||||
},
|
||||
};
|
||||
|
||||
function isMessagePort(maybePort) {
|
||||
return typeof maybePort.postMessage === 'function' &&
|
||||
('onmessage' in maybePort);
|
||||
return (
|
||||
typeof maybePort.postMessage === "function" && "onmessage" in maybePort
|
||||
);
|
||||
}
|
||||
|
||||
// Worker thread (and not node.js)?
|
||||
if (typeof window === 'undefined' && !isNodeJS &&
|
||||
typeof self !== 'undefined' && isMessagePort(self)) {
|
||||
if (
|
||||
typeof window === "undefined" &&
|
||||
!isNodeJS &&
|
||||
typeof self !== "undefined" &&
|
||||
isMessagePort(self)
|
||||
) {
|
||||
WorkerMessageHandler.initializeFromPort(self);
|
||||
}
|
||||
|
||||
export {
|
||||
WorkerTask,
|
||||
WorkerMessageHandler,
|
||||
};
|
||||
export { WorkerTask, WorkerMessageHandler };
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
/* eslint no-var: error */
|
||||
|
||||
import { assert } from '../shared/util';
|
||||
import { assert } from "../shared/util";
|
||||
|
||||
/** @implements {IPDFStream} */
|
||||
class PDFWorkerStream {
|
||||
|
@ -58,15 +58,16 @@ class PDFWorkerStreamReader {
|
|||
this._isRangeSupported = false;
|
||||
this._isStreamingSupported = false;
|
||||
|
||||
const readableStream = this._msgHandler.sendWithStream('GetReader');
|
||||
const readableStream = this._msgHandler.sendWithStream("GetReader");
|
||||
this._reader = readableStream.getReader();
|
||||
|
||||
this._headersReady = this._msgHandler.sendWithPromise('ReaderHeadersReady').
|
||||
then((data) => {
|
||||
this._isStreamingSupported = data.isStreamingSupported;
|
||||
this._isRangeSupported = data.isRangeSupported;
|
||||
this._contentLength = data.contentLength;
|
||||
});
|
||||
this._headersReady = this._msgHandler
|
||||
.sendWithPromise("ReaderHeadersReady")
|
||||
.then(data => {
|
||||
this._isStreamingSupported = data.isStreamingSupported;
|
||||
this._isRangeSupported = data.isRangeSupported;
|
||||
this._contentLength = data.contentLength;
|
||||
});
|
||||
}
|
||||
|
||||
get headersReady() {
|
||||
|
@ -86,13 +87,13 @@ class PDFWorkerStreamReader {
|
|||
}
|
||||
|
||||
async read() {
|
||||
const { value, done, } = await this._reader.read();
|
||||
const { value, done } = await this._reader.read();
|
||||
if (done) {
|
||||
return { value: undefined, done: true, };
|
||||
return { value: undefined, done: true };
|
||||
}
|
||||
// `value` is wrapped into Uint8Array, we need to
|
||||
// unwrap it to ArrayBuffer for further processing.
|
||||
return { value: value.buffer, done: false, };
|
||||
return { value: value.buffer, done: false };
|
||||
}
|
||||
|
||||
cancel(reason) {
|
||||
|
@ -106,8 +107,10 @@ class PDFWorkerStreamRangeReader {
|
|||
this._msgHandler = msgHandler;
|
||||
this.onProgress = null;
|
||||
|
||||
const readableStream = this._msgHandler.sendWithStream('GetRangeReader',
|
||||
{ begin, end, });
|
||||
const readableStream = this._msgHandler.sendWithStream("GetRangeReader", {
|
||||
begin,
|
||||
end,
|
||||
});
|
||||
this._reader = readableStream.getReader();
|
||||
}
|
||||
|
||||
|
@ -116,11 +119,11 @@ class PDFWorkerStreamRangeReader {
|
|||
}
|
||||
|
||||
async read() {
|
||||
const { value, done, } = await this._reader.read();
|
||||
const { value, done } = await this._reader.read();
|
||||
if (done) {
|
||||
return { value: undefined, done: true, };
|
||||
return { value: undefined, done: true };
|
||||
}
|
||||
return { value: value.buffer, done: false, };
|
||||
return { value: value.buffer, done: false };
|
||||
}
|
||||
|
||||
cancel(reason) {
|
||||
|
@ -128,6 +131,4 @@ class PDFWorkerStreamRangeReader {
|
|||
}
|
||||
}
|
||||
|
||||
export {
|
||||
PDFWorkerStream,
|
||||
};
|
||||
export { PDFWorkerStream };
|
||||
|
|
|
@ -15,13 +15,20 @@
|
|||
/* eslint no-var: error */
|
||||
|
||||
import {
|
||||
addLinkAttributes, DOMSVGFactory, getFilenameFromUrl, LinkTarget,
|
||||
PDFDateString
|
||||
} from './display_utils';
|
||||
addLinkAttributes,
|
||||
DOMSVGFactory,
|
||||
getFilenameFromUrl,
|
||||
LinkTarget,
|
||||
PDFDateString,
|
||||
} from "./display_utils";
|
||||
import {
|
||||
AnnotationBorderStyleType, AnnotationType, stringToPDFString, unreachable,
|
||||
Util, warn
|
||||
} from '../shared/util';
|
||||
AnnotationBorderStyleType,
|
||||
AnnotationType,
|
||||
stringToPDFString,
|
||||
unreachable,
|
||||
Util,
|
||||
warn,
|
||||
} from "../shared/util";
|
||||
|
||||
/**
|
||||
* @typedef {Object} AnnotationElementParameters
|
||||
|
@ -56,16 +63,16 @@ class AnnotationElementFactory {
|
|||
const fieldType = parameters.data.fieldType;
|
||||
|
||||
switch (fieldType) {
|
||||
case 'Tx':
|
||||
case "Tx":
|
||||
return new TextWidgetAnnotationElement(parameters);
|
||||
case 'Btn':
|
||||
case "Btn":
|
||||
if (parameters.data.radioButton) {
|
||||
return new RadioButtonWidgetAnnotationElement(parameters);
|
||||
} else if (parameters.data.checkBox) {
|
||||
return new CheckboxWidgetAnnotationElement(parameters);
|
||||
}
|
||||
return new PushButtonWidgetAnnotationElement(parameters);
|
||||
case 'Ch':
|
||||
case "Ch":
|
||||
return new ChoiceWidgetAnnotationElement(parameters);
|
||||
}
|
||||
return new WidgetAnnotationElement(parameters);
|
||||
|
@ -148,12 +155,14 @@ class AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
_createContainer(ignoreBorder = false) {
|
||||
const data = this.data, page = this.page, viewport = this.viewport;
|
||||
const container = document.createElement('section');
|
||||
const data = this.data,
|
||||
page = this.page,
|
||||
viewport = this.viewport;
|
||||
const container = document.createElement("section");
|
||||
let width = data.rect[2] - data.rect[0];
|
||||
let height = data.rect[3] - data.rect[1];
|
||||
|
||||
container.setAttribute('data-annotation-id', data.id);
|
||||
container.setAttribute("data-annotation-id", data.id);
|
||||
|
||||
// Do *not* modify `data.rect`, since that will corrupt the annotation
|
||||
// position on subsequent calls to `_createContainer` (see issue 6804).
|
||||
|
@ -161,10 +170,10 @@ class AnnotationElement {
|
|||
data.rect[0],
|
||||
page.view[3] - data.rect[1] + page.view[1],
|
||||
data.rect[2],
|
||||
page.view[3] - data.rect[3] + page.view[1]
|
||||
page.view[3] - data.rect[3] + page.view[1],
|
||||
]);
|
||||
|
||||
container.style.transform = `matrix(${viewport.transform.join(',')})`;
|
||||
container.style.transform = `matrix(${viewport.transform.join(",")})`;
|
||||
container.style.transformOrigin = `-${rect[0]}px -${rect[1]}px`;
|
||||
|
||||
if (!ignoreBorder && data.borderStyle.width > 0) {
|
||||
|
@ -186,23 +195,23 @@ class AnnotationElement {
|
|||
|
||||
switch (data.borderStyle.style) {
|
||||
case AnnotationBorderStyleType.SOLID:
|
||||
container.style.borderStyle = 'solid';
|
||||
container.style.borderStyle = "solid";
|
||||
break;
|
||||
|
||||
case AnnotationBorderStyleType.DASHED:
|
||||
container.style.borderStyle = 'dashed';
|
||||
container.style.borderStyle = "dashed";
|
||||
break;
|
||||
|
||||
case AnnotationBorderStyleType.BEVELED:
|
||||
warn('Unimplemented border style: beveled');
|
||||
warn("Unimplemented border style: beveled");
|
||||
break;
|
||||
|
||||
case AnnotationBorderStyleType.INSET:
|
||||
warn('Unimplemented border style: inset');
|
||||
warn("Unimplemented border style: inset");
|
||||
break;
|
||||
|
||||
case AnnotationBorderStyleType.UNDERLINE:
|
||||
container.style.borderBottomStyle = 'solid';
|
||||
container.style.borderBottomStyle = "solid";
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -210,9 +219,11 @@ class AnnotationElement {
|
|||
}
|
||||
|
||||
if (data.color) {
|
||||
container.style.borderColor = Util.makeCssRgb(data.color[0] | 0,
|
||||
data.color[1] | 0,
|
||||
data.color[2] | 0);
|
||||
container.style.borderColor = Util.makeCssRgb(
|
||||
data.color[0] | 0,
|
||||
data.color[1] | 0,
|
||||
data.color[2] | 0
|
||||
);
|
||||
} else {
|
||||
// Transparent (invisible) border, so do not draw it at all.
|
||||
container.style.borderWidth = 0;
|
||||
|
@ -240,7 +251,7 @@ class AnnotationElement {
|
|||
_createPopup(container, trigger, data) {
|
||||
// If no trigger element is specified, create it.
|
||||
if (!trigger) {
|
||||
trigger = document.createElement('div');
|
||||
trigger = document.createElement("div");
|
||||
trigger.style.height = container.style.height;
|
||||
trigger.style.width = container.style.width;
|
||||
container.appendChild(trigger);
|
||||
|
@ -270,14 +281,17 @@ class AnnotationElement {
|
|||
* @memberof AnnotationElement
|
||||
*/
|
||||
render() {
|
||||
unreachable('Abstract method `AnnotationElement.render` called');
|
||||
unreachable("Abstract method `AnnotationElement.render` called");
|
||||
}
|
||||
}
|
||||
|
||||
class LinkAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.url || parameters.data.dest ||
|
||||
parameters.data.action);
|
||||
const isRenderable = !!(
|
||||
parameters.data.url ||
|
||||
parameters.data.dest ||
|
||||
parameters.data.action
|
||||
);
|
||||
super(parameters, isRenderable);
|
||||
}
|
||||
|
||||
|
@ -289,16 +303,17 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'linkAnnotation';
|
||||
this.container.className = "linkAnnotation";
|
||||
|
||||
const { data, linkService, } = this;
|
||||
const link = document.createElement('a');
|
||||
const { data, linkService } = this;
|
||||
const link = document.createElement("a");
|
||||
|
||||
if (data.url) {
|
||||
addLinkAttributes(link, {
|
||||
url: data.url,
|
||||
target: (data.newWindow ?
|
||||
LinkTarget.BLANK : linkService.externalLinkTarget),
|
||||
target: data.newWindow
|
||||
? LinkTarget.BLANK
|
||||
: linkService.externalLinkTarget,
|
||||
rel: linkService.externalLinkRel,
|
||||
enabled: linkService.externalLinkEnabled,
|
||||
});
|
||||
|
@ -329,7 +344,7 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||
return false;
|
||||
};
|
||||
if (destination) {
|
||||
link.className = 'internalLink';
|
||||
link.className = "internalLink";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,19 +357,22 @@ class LinkAnnotationElement extends AnnotationElement {
|
|||
* @memberof LinkAnnotationElement
|
||||
*/
|
||||
_bindNamedAction(link, action) {
|
||||
link.href = this.linkService.getAnchorUrl('');
|
||||
link.href = this.linkService.getAnchorUrl("");
|
||||
link.onclick = () => {
|
||||
this.linkService.executeNamedAction(action);
|
||||
return false;
|
||||
};
|
||||
link.className = 'internalLink';
|
||||
link.className = "internalLink";
|
||||
}
|
||||
}
|
||||
|
||||
class TextAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable);
|
||||
}
|
||||
|
||||
|
@ -366,16 +384,19 @@ class TextAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'textAnnotation';
|
||||
this.container.className = "textAnnotation";
|
||||
|
||||
const image = document.createElement('img');
|
||||
const image = document.createElement("img");
|
||||
image.style.height = this.container.style.height;
|
||||
image.style.width = this.container.style.width;
|
||||
image.src = this.imageResourcesPath + 'annotation-' +
|
||||
this.data.name.toLowerCase() + '.svg';
|
||||
image.alt = '[{{type}} Annotation]';
|
||||
image.dataset.l10nId = 'text_annotation_type';
|
||||
image.dataset.l10nArgs = JSON.stringify({ type: this.data.name, });
|
||||
image.src =
|
||||
this.imageResourcesPath +
|
||||
"annotation-" +
|
||||
this.data.name.toLowerCase() +
|
||||
".svg";
|
||||
image.alt = "[{{type}} Annotation]";
|
||||
image.dataset.l10nId = "text_annotation_type";
|
||||
image.dataset.l10nArgs = JSON.stringify({ type: this.data.name });
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
this._createPopup(this.container, image, this.data);
|
||||
|
@ -402,7 +423,8 @@ class WidgetAnnotationElement extends AnnotationElement {
|
|||
|
||||
class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = parameters.renderInteractiveForms ||
|
||||
const isRenderable =
|
||||
parameters.renderInteractiveForms ||
|
||||
(!parameters.data.hasAppearance && !!parameters.data.fieldValue);
|
||||
super(parameters, isRenderable);
|
||||
}
|
||||
|
@ -415,9 +437,9 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
const TEXT_ALIGNMENT = ['left', 'center', 'right'];
|
||||
const TEXT_ALIGNMENT = ["left", "center", "right"];
|
||||
|
||||
this.container.className = 'textWidgetAnnotation';
|
||||
this.container.className = "textWidgetAnnotation";
|
||||
|
||||
let element = null;
|
||||
if (this.renderInteractiveForms) {
|
||||
|
@ -425,12 +447,12 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
// prevents the AnnotationLayer rasterizer in `test/driver.js`
|
||||
// from parsing the elements correctly for the reference tests.
|
||||
if (this.data.multiLine) {
|
||||
element = document.createElement('textarea');
|
||||
element = document.createElement("textarea");
|
||||
element.textContent = this.data.fieldValue;
|
||||
} else {
|
||||
element = document.createElement('input');
|
||||
element.type = 'text';
|
||||
element.setAttribute('value', this.data.fieldValue);
|
||||
element = document.createElement("input");
|
||||
element.type = "text";
|
||||
element.setAttribute("value", this.data.fieldValue);
|
||||
}
|
||||
|
||||
element.disabled = this.data.readOnly;
|
||||
|
@ -443,18 +465,20 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
const fieldWidth = this.data.rect[2] - this.data.rect[0];
|
||||
const combWidth = fieldWidth / this.data.maxLen;
|
||||
|
||||
element.classList.add('comb');
|
||||
element.classList.add("comb");
|
||||
element.style.letterSpacing = `calc(${combWidth}px - 1ch)`;
|
||||
}
|
||||
} else {
|
||||
element = document.createElement('div');
|
||||
element = document.createElement("div");
|
||||
element.textContent = this.data.fieldValue;
|
||||
element.style.verticalAlign = 'middle';
|
||||
element.style.display = 'table-cell';
|
||||
element.style.verticalAlign = "middle";
|
||||
element.style.display = "table-cell";
|
||||
|
||||
let font = null;
|
||||
if (this.data.fontRefName &&
|
||||
this.page.commonObjs.has(this.data.fontRefName)) {
|
||||
if (
|
||||
this.data.fontRefName &&
|
||||
this.page.commonObjs.has(this.data.fontRefName)
|
||||
) {
|
||||
font = this.page.commonObjs.get(this.data.fontRefName);
|
||||
}
|
||||
this._setTextStyle(element, font);
|
||||
|
@ -480,20 +504,24 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
// TODO: This duplicates some of the logic in CanvasGraphics.setFont().
|
||||
const style = element.style;
|
||||
style.fontSize = `${this.data.fontSize}px`;
|
||||
style.direction = (this.data.fontDirection < 0 ? 'rtl' : 'ltr');
|
||||
style.direction = this.data.fontDirection < 0 ? "rtl" : "ltr";
|
||||
|
||||
if (!font) {
|
||||
return;
|
||||
}
|
||||
|
||||
style.fontWeight = (font.black ?
|
||||
(font.bold ? '900' : 'bold') :
|
||||
(font.bold ? 'bold' : 'normal'));
|
||||
style.fontStyle = (font.italic ? 'italic' : 'normal');
|
||||
style.fontWeight = font.black
|
||||
? font.bold
|
||||
? "900"
|
||||
: "bold"
|
||||
: font.bold
|
||||
? "bold"
|
||||
: "normal";
|
||||
style.fontStyle = font.italic ? "italic" : "normal";
|
||||
|
||||
// Use a reasonable default font if the font doesn't specify a fallback.
|
||||
const fontFamily = font.loadedName ? `"${font.loadedName}", ` : '';
|
||||
const fallbackName = font.fallbackName || 'Helvetica, sans-serif';
|
||||
const fontFamily = font.loadedName ? `"${font.loadedName}", ` : "";
|
||||
const fallbackName = font.fallbackName || "Helvetica, sans-serif";
|
||||
style.fontFamily = fontFamily + fallbackName;
|
||||
}
|
||||
}
|
||||
|
@ -512,13 +540,13 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'buttonWidgetAnnotation checkBox';
|
||||
this.container.className = "buttonWidgetAnnotation checkBox";
|
||||
|
||||
const element = document.createElement('input');
|
||||
const element = document.createElement("input");
|
||||
element.disabled = this.data.readOnly;
|
||||
element.type = 'checkbox';
|
||||
if (this.data.fieldValue && this.data.fieldValue !== 'Off') {
|
||||
element.setAttribute('checked', true);
|
||||
element.type = "checkbox";
|
||||
if (this.data.fieldValue && this.data.fieldValue !== "Off") {
|
||||
element.setAttribute("checked", true);
|
||||
}
|
||||
|
||||
this.container.appendChild(element);
|
||||
|
@ -540,14 +568,14 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'buttonWidgetAnnotation radioButton';
|
||||
this.container.className = "buttonWidgetAnnotation radioButton";
|
||||
|
||||
const element = document.createElement('input');
|
||||
const element = document.createElement("input");
|
||||
element.disabled = this.data.readOnly;
|
||||
element.type = 'radio';
|
||||
element.type = "radio";
|
||||
element.name = this.data.fieldName;
|
||||
if (this.data.fieldValue === this.data.buttonValue) {
|
||||
element.setAttribute('checked', true);
|
||||
element.setAttribute("checked", true);
|
||||
}
|
||||
|
||||
this.container.appendChild(element);
|
||||
|
@ -569,7 +597,7 @@ class PushButtonWidgetAnnotationElement extends LinkAnnotationElement {
|
|||
// equal to that of a link annotation, but may have more functionality, such
|
||||
// as performing actions on form fields (resetting, submitting, et cetera).
|
||||
const container = super.render();
|
||||
container.className = 'buttonWidgetAnnotation pushButton';
|
||||
container.className = "buttonWidgetAnnotation pushButton";
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
@ -588,9 +616,9 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'choiceWidgetAnnotation';
|
||||
this.container.className = "choiceWidgetAnnotation";
|
||||
|
||||
const selectElement = document.createElement('select');
|
||||
const selectElement = document.createElement("select");
|
||||
selectElement.disabled = this.data.readOnly;
|
||||
|
||||
if (!this.data.combo) {
|
||||
|
@ -603,11 +631,11 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
|
||||
// Insert the options into the choice field.
|
||||
for (const option of this.data.options) {
|
||||
const optionElement = document.createElement('option');
|
||||
const optionElement = document.createElement("option");
|
||||
optionElement.textContent = option.displayValue;
|
||||
optionElement.value = option.exportValue;
|
||||
if (this.data.fieldValue.includes(option.displayValue)) {
|
||||
optionElement.setAttribute('selected', true);
|
||||
optionElement.setAttribute("selected", true);
|
||||
}
|
||||
selectElement.appendChild(optionElement);
|
||||
}
|
||||
|
@ -634,15 +662,15 @@ class PopupAnnotationElement extends AnnotationElement {
|
|||
// Do not render popup annotations for parent elements with these types as
|
||||
// they create the popups themselves (because of custom trigger divs).
|
||||
const IGNORE_TYPES = [
|
||||
'Line',
|
||||
'Square',
|
||||
'Circle',
|
||||
'PolyLine',
|
||||
'Polygon',
|
||||
'Ink',
|
||||
"Line",
|
||||
"Square",
|
||||
"Circle",
|
||||
"PolyLine",
|
||||
"Polygon",
|
||||
"Ink",
|
||||
];
|
||||
|
||||
this.container.className = 'popupAnnotation';
|
||||
this.container.className = "popupAnnotation";
|
||||
|
||||
if (IGNORE_TYPES.includes(this.data.parentType)) {
|
||||
return this.container;
|
||||
|
@ -667,8 +695,9 @@ class PopupAnnotationElement extends AnnotationElement {
|
|||
// PDF viewers ignore a popup annotation's rectangle.
|
||||
const parentLeft = parseFloat(parentElement.style.left);
|
||||
const parentWidth = parseFloat(parentElement.style.width);
|
||||
this.container.style.transformOrigin =
|
||||
`-${parentLeft + parentWidth}px -${parentElement.style.top}`;
|
||||
this.container.style.transformOrigin = `-${parentLeft + parentWidth}px -${
|
||||
parentElement.style.top
|
||||
}`;
|
||||
this.container.style.left = `${parentLeft + parentWidth}px`;
|
||||
|
||||
this.container.appendChild(popup.render());
|
||||
|
@ -699,18 +728,18 @@ class PopupElement {
|
|||
render() {
|
||||
const BACKGROUND_ENLIGHT = 0.7;
|
||||
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'popupWrapper';
|
||||
const wrapper = document.createElement("div");
|
||||
wrapper.className = "popupWrapper";
|
||||
|
||||
// For Popup annotations we hide the entire section because it contains
|
||||
// only the popup. However, for Text annotations without a separate Popup
|
||||
// annotation, we cannot hide the entire container as the image would
|
||||
// disappear too. In that special case, hiding the wrapper suffices.
|
||||
this.hideElement = (this.hideWrapper ? wrapper : this.container);
|
||||
this.hideElement.setAttribute('hidden', true);
|
||||
this.hideElement = this.hideWrapper ? wrapper : this.container;
|
||||
this.hideElement.setAttribute("hidden", true);
|
||||
|
||||
const popup = document.createElement('div');
|
||||
popup.className = 'popup';
|
||||
const popup = document.createElement("div");
|
||||
popup.className = "popup";
|
||||
|
||||
const color = this.color;
|
||||
if (color) {
|
||||
|
@ -721,7 +750,7 @@ class PopupElement {
|
|||
popup.style.backgroundColor = Util.makeCssRgb(r | 0, g | 0, b | 0);
|
||||
}
|
||||
|
||||
const title = document.createElement('h1');
|
||||
const title = document.createElement("h1");
|
||||
title.textContent = this.title;
|
||||
popup.appendChild(title);
|
||||
|
||||
|
@ -730,9 +759,9 @@ class PopupElement {
|
|||
// consistent with other viewers such as Adobe Acrobat.
|
||||
const dateObject = PDFDateString.toDateObject(this.modificationDate);
|
||||
if (dateObject) {
|
||||
const modificationDate = document.createElement('span');
|
||||
modificationDate.textContent = '{{date}}, {{time}}';
|
||||
modificationDate.dataset.l10nId = 'annotation_date_string';
|
||||
const modificationDate = document.createElement("span");
|
||||
modificationDate.textContent = "{{date}}, {{time}}";
|
||||
modificationDate.dataset.l10nId = "annotation_date_string";
|
||||
modificationDate.dataset.l10nArgs = JSON.stringify({
|
||||
date: dateObject.toLocaleDateString(),
|
||||
time: dateObject.toLocaleTimeString(),
|
||||
|
@ -744,10 +773,10 @@ class PopupElement {
|
|||
popup.appendChild(contents);
|
||||
|
||||
// Attach the event listeners to the trigger element.
|
||||
this.trigger.addEventListener('click', this._toggle.bind(this));
|
||||
this.trigger.addEventListener('mouseover', this._show.bind(this, false));
|
||||
this.trigger.addEventListener('mouseout', this._hide.bind(this, false));
|
||||
popup.addEventListener('click', this._hide.bind(this, true));
|
||||
this.trigger.addEventListener("click", this._toggle.bind(this));
|
||||
this.trigger.addEventListener("mouseover", this._show.bind(this, false));
|
||||
this.trigger.addEventListener("mouseout", this._hide.bind(this, false));
|
||||
popup.addEventListener("click", this._hide.bind(this, true));
|
||||
|
||||
wrapper.appendChild(popup);
|
||||
return wrapper;
|
||||
|
@ -762,13 +791,13 @@ class PopupElement {
|
|||
* @returns {HTMLParagraphElement}
|
||||
*/
|
||||
_formatContents(contents) {
|
||||
const p = document.createElement('p');
|
||||
const p = document.createElement("p");
|
||||
const lines = contents.split(/(?:\r\n?|\n)/);
|
||||
for (let i = 0, ii = lines.length; i < ii; ++i) {
|
||||
const line = lines[i];
|
||||
p.appendChild(document.createTextNode(line));
|
||||
if (i < (ii - 1)) {
|
||||
p.appendChild(document.createElement('br'));
|
||||
if (i < ii - 1) {
|
||||
p.appendChild(document.createElement("br"));
|
||||
}
|
||||
}
|
||||
return p;
|
||||
|
@ -799,8 +828,8 @@ class PopupElement {
|
|||
if (pin) {
|
||||
this.pinned = true;
|
||||
}
|
||||
if (this.hideElement.hasAttribute('hidden')) {
|
||||
this.hideElement.removeAttribute('hidden');
|
||||
if (this.hideElement.hasAttribute("hidden")) {
|
||||
this.hideElement.removeAttribute("hidden");
|
||||
this.container.style.zIndex += 1;
|
||||
}
|
||||
}
|
||||
|
@ -816,8 +845,8 @@ class PopupElement {
|
|||
if (unpin) {
|
||||
this.pinned = false;
|
||||
}
|
||||
if (!this.hideElement.hasAttribute('hidden') && !this.pinned) {
|
||||
this.hideElement.setAttribute('hidden', true);
|
||||
if (!this.hideElement.hasAttribute("hidden") && !this.pinned) {
|
||||
this.hideElement.setAttribute("hidden", true);
|
||||
this.container.style.zIndex -= 1;
|
||||
}
|
||||
}
|
||||
|
@ -825,8 +854,11 @@ class PopupElement {
|
|||
|
||||
class FreeTextAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||
}
|
||||
|
||||
|
@ -838,7 +870,7 @@ class FreeTextAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'freeTextAnnotation';
|
||||
this.container.className = "freeTextAnnotation";
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
this._createPopup(this.container, null, this.data);
|
||||
|
@ -849,8 +881,11 @@ class FreeTextAnnotationElement extends AnnotationElement {
|
|||
|
||||
class LineAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||
}
|
||||
|
||||
|
@ -862,7 +897,7 @@ class LineAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'lineAnnotation';
|
||||
this.container.className = "lineAnnotation";
|
||||
|
||||
// Create an invisible line with the same starting and ending coordinates
|
||||
// that acts as the trigger for the popup. Only the line itself should
|
||||
|
@ -874,15 +909,15 @@ class LineAnnotationElement extends AnnotationElement {
|
|||
|
||||
// PDF coordinates are calculated from a bottom left origin, so transform
|
||||
// the line coordinates to a top left origin for the SVG element.
|
||||
const line = this.svgFactory.createElement('svg:line');
|
||||
line.setAttribute('x1', data.rect[2] - data.lineCoordinates[0]);
|
||||
line.setAttribute('y1', data.rect[3] - data.lineCoordinates[1]);
|
||||
line.setAttribute('x2', data.rect[2] - data.lineCoordinates[2]);
|
||||
line.setAttribute('y2', data.rect[3] - data.lineCoordinates[3]);
|
||||
const line = this.svgFactory.createElement("svg:line");
|
||||
line.setAttribute("x1", data.rect[2] - data.lineCoordinates[0]);
|
||||
line.setAttribute("y1", data.rect[3] - data.lineCoordinates[1]);
|
||||
line.setAttribute("x2", data.rect[2] - data.lineCoordinates[2]);
|
||||
line.setAttribute("y2", data.rect[3] - data.lineCoordinates[3]);
|
||||
// Ensure that the 'stroke-width' is always non-zero, since otherwise it
|
||||
// won't be possible to open/close the popup (note e.g. issue 11122).
|
||||
line.setAttribute('stroke-width', data.borderStyle.width || 1);
|
||||
line.setAttribute('stroke', 'transparent');
|
||||
line.setAttribute("stroke-width", data.borderStyle.width || 1);
|
||||
line.setAttribute("stroke", "transparent");
|
||||
|
||||
svg.appendChild(line);
|
||||
this.container.append(svg);
|
||||
|
@ -897,8 +932,11 @@ class LineAnnotationElement extends AnnotationElement {
|
|||
|
||||
class SquareAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||
}
|
||||
|
||||
|
@ -910,7 +948,7 @@ class SquareAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'squareAnnotation';
|
||||
this.container.className = "squareAnnotation";
|
||||
|
||||
// Create an invisible square with the same rectangle that acts as the
|
||||
// trigger for the popup. Only the square itself should trigger the
|
||||
|
@ -924,16 +962,16 @@ class SquareAnnotationElement extends AnnotationElement {
|
|||
// the borders outside the square by default. This behavior cannot be
|
||||
// changed programmatically, so correct for that here.
|
||||
const borderWidth = data.borderStyle.width;
|
||||
const square = this.svgFactory.createElement('svg:rect');
|
||||
square.setAttribute('x', borderWidth / 2);
|
||||
square.setAttribute('y', borderWidth / 2);
|
||||
square.setAttribute('width', width - borderWidth);
|
||||
square.setAttribute('height', height - borderWidth);
|
||||
const square = this.svgFactory.createElement("svg:rect");
|
||||
square.setAttribute("x", borderWidth / 2);
|
||||
square.setAttribute("y", borderWidth / 2);
|
||||
square.setAttribute("width", width - borderWidth);
|
||||
square.setAttribute("height", height - borderWidth);
|
||||
// Ensure that the 'stroke-width' is always non-zero, since otherwise it
|
||||
// won't be possible to open/close the popup (note e.g. issue 11122).
|
||||
square.setAttribute('stroke-width', borderWidth || 1);
|
||||
square.setAttribute('stroke', 'transparent');
|
||||
square.setAttribute('fill', 'none');
|
||||
square.setAttribute("stroke-width", borderWidth || 1);
|
||||
square.setAttribute("stroke", "transparent");
|
||||
square.setAttribute("fill", "none");
|
||||
|
||||
svg.appendChild(square);
|
||||
this.container.append(svg);
|
||||
|
@ -948,8 +986,11 @@ class SquareAnnotationElement extends AnnotationElement {
|
|||
|
||||
class CircleAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||
}
|
||||
|
||||
|
@ -961,7 +1002,7 @@ class CircleAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'circleAnnotation';
|
||||
this.container.className = "circleAnnotation";
|
||||
|
||||
// Create an invisible circle with the same ellipse that acts as the
|
||||
// trigger for the popup. Only the circle itself should trigger the
|
||||
|
@ -975,16 +1016,16 @@ class CircleAnnotationElement extends AnnotationElement {
|
|||
// the borders outside the circle by default. This behavior cannot be
|
||||
// changed programmatically, so correct for that here.
|
||||
const borderWidth = data.borderStyle.width;
|
||||
const circle = this.svgFactory.createElement('svg:ellipse');
|
||||
circle.setAttribute('cx', width / 2);
|
||||
circle.setAttribute('cy', height / 2);
|
||||
circle.setAttribute('rx', (width / 2) - (borderWidth / 2));
|
||||
circle.setAttribute('ry', (height / 2) - (borderWidth / 2));
|
||||
const circle = this.svgFactory.createElement("svg:ellipse");
|
||||
circle.setAttribute("cx", width / 2);
|
||||
circle.setAttribute("cy", height / 2);
|
||||
circle.setAttribute("rx", width / 2 - borderWidth / 2);
|
||||
circle.setAttribute("ry", height / 2 - borderWidth / 2);
|
||||
// Ensure that the 'stroke-width' is always non-zero, since otherwise it
|
||||
// won't be possible to open/close the popup (note e.g. issue 11122).
|
||||
circle.setAttribute('stroke-width', borderWidth || 1);
|
||||
circle.setAttribute('stroke', 'transparent');
|
||||
circle.setAttribute('fill', 'none');
|
||||
circle.setAttribute("stroke-width", borderWidth || 1);
|
||||
circle.setAttribute("stroke", "transparent");
|
||||
circle.setAttribute("fill", "none");
|
||||
|
||||
svg.appendChild(circle);
|
||||
this.container.append(svg);
|
||||
|
@ -999,12 +1040,15 @@ class CircleAnnotationElement extends AnnotationElement {
|
|||
|
||||
class PolylineAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||
|
||||
this.containerClassName = 'polylineAnnotation';
|
||||
this.svgElementName = 'svg:polyline';
|
||||
this.containerClassName = "polylineAnnotation";
|
||||
this.svgElementName = "svg:polyline";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1033,17 +1077,17 @@ class PolylineAnnotationElement extends AnnotationElement {
|
|||
for (const coordinate of data.vertices) {
|
||||
const x = coordinate.x - data.rect[0];
|
||||
const y = data.rect[3] - coordinate.y;
|
||||
points.push(x + ',' + y);
|
||||
points.push(x + "," + y);
|
||||
}
|
||||
points = points.join(' ');
|
||||
points = points.join(" ");
|
||||
|
||||
const polyline = this.svgFactory.createElement(this.svgElementName);
|
||||
polyline.setAttribute('points', points);
|
||||
polyline.setAttribute("points", points);
|
||||
// Ensure that the 'stroke-width' is always non-zero, since otherwise it
|
||||
// won't be possible to open/close the popup (note e.g. issue 11122).
|
||||
polyline.setAttribute('stroke-width', data.borderStyle.width || 1);
|
||||
polyline.setAttribute('stroke', 'transparent');
|
||||
polyline.setAttribute('fill', 'none');
|
||||
polyline.setAttribute("stroke-width", data.borderStyle.width || 1);
|
||||
polyline.setAttribute("stroke", "transparent");
|
||||
polyline.setAttribute("fill", "none");
|
||||
|
||||
svg.appendChild(polyline);
|
||||
this.container.append(svg);
|
||||
|
@ -1061,15 +1105,18 @@ class PolygonAnnotationElement extends PolylineAnnotationElement {
|
|||
// Polygons are specific forms of polylines, so reuse their logic.
|
||||
super(parameters);
|
||||
|
||||
this.containerClassName = 'polygonAnnotation';
|
||||
this.svgElementName = 'svg:polygon';
|
||||
this.containerClassName = "polygonAnnotation";
|
||||
this.svgElementName = "svg:polygon";
|
||||
}
|
||||
}
|
||||
|
||||
class CaretAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||
}
|
||||
|
||||
|
@ -1081,7 +1128,7 @@ class CaretAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'caretAnnotation';
|
||||
this.container.className = "caretAnnotation";
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
this._createPopup(this.container, null, this.data);
|
||||
|
@ -1092,15 +1139,18 @@ class CaretAnnotationElement extends AnnotationElement {
|
|||
|
||||
class InkAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||
|
||||
this.containerClassName = 'inkAnnotation';
|
||||
this.containerClassName = "inkAnnotation";
|
||||
|
||||
// Use the polyline SVG element since it allows us to use coordinates
|
||||
// directly and to draw both straight lines and curves.
|
||||
this.svgElementName = 'svg:polyline';
|
||||
this.svgElementName = "svg:polyline";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1131,15 +1181,15 @@ class InkAnnotationElement extends AnnotationElement {
|
|||
const y = data.rect[3] - coordinate.y;
|
||||
points.push(`${x},${y}`);
|
||||
}
|
||||
points = points.join(' ');
|
||||
points = points.join(" ");
|
||||
|
||||
const polyline = this.svgFactory.createElement(this.svgElementName);
|
||||
polyline.setAttribute('points', points);
|
||||
polyline.setAttribute("points", points);
|
||||
// Ensure that the 'stroke-width' is always non-zero, since otherwise it
|
||||
// won't be possible to open/close the popup (note e.g. issue 11122).
|
||||
polyline.setAttribute('stroke-width', data.borderStyle.width || 1);
|
||||
polyline.setAttribute('stroke', 'transparent');
|
||||
polyline.setAttribute('fill', 'none');
|
||||
polyline.setAttribute("stroke-width", data.borderStyle.width || 1);
|
||||
polyline.setAttribute("stroke", "transparent");
|
||||
polyline.setAttribute("fill", "none");
|
||||
|
||||
// Create the popup ourselves so that we can bind it to the polyline
|
||||
// instead of to the entire container (which is the default).
|
||||
|
@ -1155,8 +1205,11 @@ class InkAnnotationElement extends AnnotationElement {
|
|||
|
||||
class HighlightAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||
}
|
||||
|
||||
|
@ -1168,7 +1221,7 @@ class HighlightAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'highlightAnnotation';
|
||||
this.container.className = "highlightAnnotation";
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
this._createPopup(this.container, null, this.data);
|
||||
|
@ -1179,8 +1232,11 @@ class HighlightAnnotationElement extends AnnotationElement {
|
|||
|
||||
class UnderlineAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||
}
|
||||
|
||||
|
@ -1192,7 +1248,7 @@ class UnderlineAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'underlineAnnotation';
|
||||
this.container.className = "underlineAnnotation";
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
this._createPopup(this.container, null, this.data);
|
||||
|
@ -1203,8 +1259,11 @@ class UnderlineAnnotationElement extends AnnotationElement {
|
|||
|
||||
class SquigglyAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||
}
|
||||
|
||||
|
@ -1216,7 +1275,7 @@ class SquigglyAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'squigglyAnnotation';
|
||||
this.container.className = "squigglyAnnotation";
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
this._createPopup(this.container, null, this.data);
|
||||
|
@ -1227,8 +1286,11 @@ class SquigglyAnnotationElement extends AnnotationElement {
|
|||
|
||||
class StrikeOutAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||
}
|
||||
|
||||
|
@ -1240,7 +1302,7 @@ class StrikeOutAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'strikeoutAnnotation';
|
||||
this.container.className = "strikeoutAnnotation";
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
this._createPopup(this.container, null, this.data);
|
||||
|
@ -1251,8 +1313,11 @@ class StrikeOutAnnotationElement extends AnnotationElement {
|
|||
|
||||
class StampAnnotationElement extends AnnotationElement {
|
||||
constructor(parameters) {
|
||||
const isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
const isRenderable = !!(
|
||||
parameters.data.hasPopup ||
|
||||
parameters.data.title ||
|
||||
parameters.data.contents
|
||||
);
|
||||
super(parameters, isRenderable, /* ignoreBorder = */ true);
|
||||
}
|
||||
|
||||
|
@ -1264,7 +1329,7 @@ class StampAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'stampAnnotation';
|
||||
this.container.className = "stampAnnotation";
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
this._createPopup(this.container, null, this.data);
|
||||
|
@ -1277,12 +1342,12 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
|
|||
constructor(parameters) {
|
||||
super(parameters, /* isRenderable = */ true);
|
||||
|
||||
const { filename, content, } = this.data.file;
|
||||
const { filename, content } = this.data.file;
|
||||
this.filename = getFilenameFromUrl(filename);
|
||||
this.content = content;
|
||||
|
||||
if (this.linkService.eventBus) {
|
||||
this.linkService.eventBus.dispatch('fileattachmentannotation', {
|
||||
this.linkService.eventBus.dispatch("fileattachmentannotation", {
|
||||
source: this,
|
||||
id: stringToPDFString(filename),
|
||||
filename,
|
||||
|
@ -1300,12 +1365,12 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
|
|||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render() {
|
||||
this.container.className = 'fileAttachmentAnnotation';
|
||||
this.container.className = "fileAttachmentAnnotation";
|
||||
|
||||
const trigger = document.createElement('div');
|
||||
const trigger = document.createElement("div");
|
||||
trigger.style.height = this.container.style.height;
|
||||
trigger.style.width = this.container.style.width;
|
||||
trigger.addEventListener('dblclick', this._download.bind(this));
|
||||
trigger.addEventListener("dblclick", this._download.bind(this));
|
||||
|
||||
if (!this.data.hasPopup && (this.data.title || this.data.contents)) {
|
||||
this._createPopup(this.container, trigger, this.data);
|
||||
|
@ -1323,10 +1388,10 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
|
|||
*/
|
||||
_download() {
|
||||
if (!this.downloadManager) {
|
||||
warn('Download cannot be started due to unavailable download manager');
|
||||
warn("Download cannot be started due to unavailable download manager");
|
||||
return;
|
||||
}
|
||||
this.downloadManager.downloadData(this.content, this.filename, '');
|
||||
this.downloadManager.downloadData(this.content, this.filename, "");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1363,7 +1428,7 @@ class AnnotationLayer {
|
|||
viewport: parameters.viewport,
|
||||
linkService: parameters.linkService,
|
||||
downloadManager: parameters.downloadManager,
|
||||
imageResourcesPath: parameters.imageResourcesPath || '',
|
||||
imageResourcesPath: parameters.imageResourcesPath || "",
|
||||
renderInteractiveForms: parameters.renderInteractiveForms || false,
|
||||
svgFactory: new DOMSVGFactory(),
|
||||
});
|
||||
|
@ -1383,16 +1448,16 @@ class AnnotationLayer {
|
|||
static update(parameters) {
|
||||
for (const data of parameters.annotations) {
|
||||
const element = parameters.div.querySelector(
|
||||
`[data-annotation-id="${data.id}"]`);
|
||||
`[data-annotation-id="${data.id}"]`
|
||||
);
|
||||
if (element) {
|
||||
element.style.transform =
|
||||
`matrix(${parameters.viewport.transform.join(',')})`;
|
||||
element.style.transform = `matrix(${parameters.viewport.transform.join(
|
||||
","
|
||||
)})`;
|
||||
}
|
||||
}
|
||||
parameters.div.removeAttribute('hidden');
|
||||
parameters.div.removeAttribute("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
AnnotationLayer,
|
||||
};
|
||||
export { AnnotationLayer };
|
||||
|
|
1140
src/display/api.js
1140
src/display/api.js
File diff suppressed because it is too large
Load diff
|
@ -14,11 +14,11 @@
|
|||
*/
|
||||
|
||||
let compatibilityParams = Object.create(null);
|
||||
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
||||
const { isNodeJS, } = require('../shared/is_node');
|
||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
const { isNodeJS } = require("../shared/is_node");
|
||||
|
||||
const userAgent =
|
||||
(typeof navigator !== 'undefined' && navigator.userAgent) || '';
|
||||
(typeof navigator !== "undefined" && navigator.userAgent) || "";
|
||||
const isIE = /Trident/.test(userAgent);
|
||||
const isIOSChrome = /CriOS/.test(userAgent);
|
||||
|
||||
|
@ -37,7 +37,7 @@ if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
|||
// Node.js is missing native support for `@font-face` and `Image`.
|
||||
if (isNodeJS) {
|
||||
compatibilityParams.disableFontFace = true;
|
||||
compatibilityParams.nativeImageDecoderSupport = 'none';
|
||||
compatibilityParams.nativeImageDecoderSupport = "none";
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -31,7 +31,7 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
let needsEncodingFixup = true;
|
||||
|
||||
// filename*=ext-value ("ext-value" from RFC 5987, referenced by RFC 6266).
|
||||
let tmp = toParamRegExp('filename\\*', 'i').exec(contentDisposition);
|
||||
let tmp = toParamRegExp("filename\\*", "i").exec(contentDisposition);
|
||||
if (tmp) {
|
||||
tmp = tmp[1];
|
||||
let filename = rfc2616unquote(tmp);
|
||||
|
@ -52,7 +52,7 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
}
|
||||
|
||||
// filename=value (RFC 5987, section 4.1).
|
||||
tmp = toParamRegExp('filename', 'i').exec(contentDisposition);
|
||||
tmp = toParamRegExp("filename", "i").exec(contentDisposition);
|
||||
if (tmp) {
|
||||
tmp = tmp[1];
|
||||
let filename = rfc2616unquote(tmp);
|
||||
|
@ -65,14 +65,18 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
// declarations...
|
||||
function toParamRegExp(attributePattern, flags) {
|
||||
return new RegExp(
|
||||
'(?:^|;)\\s*' + attributePattern + '\\s*=\\s*' +
|
||||
// Captures: value = token | quoted-string
|
||||
// (RFC 2616, section 3.6 and referenced by RFC 6266 4.1)
|
||||
'(' +
|
||||
"(?:^|;)\\s*" +
|
||||
attributePattern +
|
||||
"\\s*=\\s*" +
|
||||
// Captures: value = token | quoted-string
|
||||
// (RFC 2616, section 3.6 and referenced by RFC 6266 4.1)
|
||||
"(" +
|
||||
'[^";\\s][^;\\s]*' +
|
||||
'|' +
|
||||
"|" +
|
||||
'"(?:[^"\\\\]|\\\\"?)+"?' +
|
||||
')', flags);
|
||||
")",
|
||||
flags
|
||||
);
|
||||
}
|
||||
function textdecode(encoding, value) {
|
||||
if (encoding) {
|
||||
|
@ -80,9 +84,9 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
return value;
|
||||
}
|
||||
try {
|
||||
let decoder = new TextDecoder(encoding, { fatal: true, });
|
||||
let decoder = new TextDecoder(encoding, { fatal: true });
|
||||
let bytes = Array.from(value, function(ch) {
|
||||
return ch.charCodeAt(0) & 0xFF;
|
||||
return ch.charCodeAt(0) & 0xff;
|
||||
});
|
||||
value = decoder.decode(new Uint8Array(bytes));
|
||||
needsEncodingFixup = false;
|
||||
|
@ -94,8 +98,7 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
try {
|
||||
value = decodeURIComponent(escape(value));
|
||||
needsEncodingFixup = false;
|
||||
} catch (err) {
|
||||
}
|
||||
} catch (err) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,19 +107,20 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
function fixupEncoding(value) {
|
||||
if (needsEncodingFixup && /[\x80-\xff]/.test(value)) {
|
||||
// Maybe multi-byte UTF-8.
|
||||
value = textdecode('utf-8', value);
|
||||
value = textdecode("utf-8", value);
|
||||
if (needsEncodingFixup) {
|
||||
// Try iso-8859-1 encoding.
|
||||
value = textdecode('iso-8859-1', value);
|
||||
value = textdecode("iso-8859-1", value);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function rfc2231getparam(contentDisposition) {
|
||||
let matches = [], match;
|
||||
let matches = [],
|
||||
match;
|
||||
// Iterate over all filename*n= and filename*n*= with n being an integer
|
||||
// of at least zero. Any non-zero number must not start with '0'.
|
||||
let iter = toParamRegExp('filename\\*((?!0\\d)\\d+)(\\*?)', 'ig');
|
||||
let iter = toParamRegExp("filename\\*((?!0\\d)\\d+)(\\*?)", "ig");
|
||||
while ((match = iter.exec(contentDisposition)) !== null) {
|
||||
let [, n, quot, part] = match;
|
||||
n = parseInt(n, 10);
|
||||
|
@ -145,7 +149,7 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
}
|
||||
parts.push(part);
|
||||
}
|
||||
return parts.join('');
|
||||
return parts.join("");
|
||||
}
|
||||
function rfc2616unquote(value) {
|
||||
if (value.startsWith('"')) {
|
||||
|
@ -157,7 +161,7 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
parts[i] = parts[i].slice(0, quotindex);
|
||||
parts.length = i + 1; // Truncates and stop the iteration.
|
||||
}
|
||||
parts[i] = parts[i].replace(/\\(.)/g, '$1');
|
||||
parts[i] = parts[i].replace(/\\(.)/g, "$1");
|
||||
}
|
||||
value = parts.join('"');
|
||||
}
|
||||
|
@ -165,7 +169,7 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
}
|
||||
function rfc5987decode(extvalue) {
|
||||
// Decodes "ext-value" from RFC 5987.
|
||||
let encodingend = extvalue.indexOf('\'');
|
||||
let encodingend = extvalue.indexOf("'");
|
||||
if (encodingend === -1) {
|
||||
// Some servers send "filename*=" without encoding 'language' prefix,
|
||||
// e.g. in https://github.com/Rob--W/open-in-browser/issues/26
|
||||
|
@ -175,7 +179,7 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
let encoding = extvalue.slice(0, encodingend);
|
||||
let langvalue = extvalue.slice(encodingend + 1);
|
||||
// Ignore language (RFC 5987 section 3.2.1, and RFC 6266 section 4.1 ).
|
||||
let value = langvalue.replace(/^[^']*'/, '');
|
||||
let value = langvalue.replace(/^[^']*'/, "");
|
||||
return textdecode(encoding, value);
|
||||
}
|
||||
function rfc2047decode(value) {
|
||||
|
@ -189,7 +193,7 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
|
||||
// Firefox also decodes words even where RFC 2047 section 5 states:
|
||||
// "An 'encoded-word' MUST NOT appear within a 'quoted-string'."
|
||||
if (!value.startsWith('=?') || /[\x00-\x19\x80-\xff]/.test(value)) {
|
||||
if (!value.startsWith("=?") || /[\x00-\x19\x80-\xff]/.test(value)) {
|
||||
return value;
|
||||
}
|
||||
// RFC 2047, section 2.4
|
||||
|
@ -199,11 +203,12 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
// encoding = q or b
|
||||
// encoded-text = any printable ASCII character other than ? or space.
|
||||
// ... but Firefox permits ? and space.
|
||||
return value.replace(/=\?([\w-]*)\?([QqBb])\?((?:[^?]|\?(?!=))*)\?=/g,
|
||||
return value.replace(
|
||||
/=\?([\w-]*)\?([QqBb])\?((?:[^?]|\?(?!=))*)\?=/g,
|
||||
function(_, charset, encoding, text) {
|
||||
if (encoding === 'q' || encoding === 'Q') {
|
||||
if (encoding === "q" || encoding === "Q") {
|
||||
// RFC 2047 section 4.2.
|
||||
text = text.replace(/_/g, ' ');
|
||||
text = text.replace(/_/g, " ");
|
||||
text = text.replace(/=([0-9a-fA-F]{2})/g, function(_, hex) {
|
||||
return String.fromCharCode(parseInt(hex, 16));
|
||||
});
|
||||
|
@ -211,15 +216,13 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
|
|||
} // else encoding is b or B - base64 (RFC 2047 section 4.1)
|
||||
try {
|
||||
text = atob(text);
|
||||
} catch (e) {
|
||||
}
|
||||
} catch (e) {}
|
||||
return textdecode(charset, text);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
return "";
|
||||
}
|
||||
|
||||
export {
|
||||
getFilenameFromContentDispositionHeader,
|
||||
};
|
||||
export { getFilenameFromContentDispositionHeader };
|
||||
|
|
|
@ -15,20 +15,26 @@
|
|||
/* eslint no-var: error */
|
||||
|
||||
import {
|
||||
assert, BaseException, CMapCompressionType, isString, removeNullCharacters,
|
||||
stringToBytes, Util, warn
|
||||
} from '../shared/util';
|
||||
assert,
|
||||
BaseException,
|
||||
CMapCompressionType,
|
||||
isString,
|
||||
removeNullCharacters,
|
||||
stringToBytes,
|
||||
Util,
|
||||
warn,
|
||||
} from "../shared/util";
|
||||
|
||||
const DEFAULT_LINK_REL = 'noopener noreferrer nofollow';
|
||||
const SVG_NS = 'http://www.w3.org/2000/svg';
|
||||
const DEFAULT_LINK_REL = "noopener noreferrer nofollow";
|
||||
const SVG_NS = "http://www.w3.org/2000/svg";
|
||||
|
||||
class DOMCanvasFactory {
|
||||
create(width, height) {
|
||||
if (width <= 0 || height <= 0) {
|
||||
throw new Error('Invalid canvas size');
|
||||
throw new Error("Invalid canvas size");
|
||||
}
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
const canvas = document.createElement("canvas");
|
||||
const context = canvas.getContext("2d");
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
return {
|
||||
|
@ -39,10 +45,10 @@ class DOMCanvasFactory {
|
|||
|
||||
reset(canvasAndContext, width, height) {
|
||||
if (!canvasAndContext.canvas) {
|
||||
throw new Error('Canvas is not specified');
|
||||
throw new Error("Canvas is not specified");
|
||||
}
|
||||
if (width <= 0 || height <= 0) {
|
||||
throw new Error('Invalid canvas size');
|
||||
throw new Error("Invalid canvas size");
|
||||
}
|
||||
canvasAndContext.canvas.width = width;
|
||||
canvasAndContext.canvas.height = height;
|
||||
|
@ -50,7 +56,7 @@ class DOMCanvasFactory {
|
|||
|
||||
destroy(canvasAndContext) {
|
||||
if (!canvasAndContext.canvas) {
|
||||
throw new Error('Canvas is not specified');
|
||||
throw new Error("Canvas is not specified");
|
||||
}
|
||||
// Zeroing the width and height cause Firefox to release graphics
|
||||
// resources immediately, which can greatly reduce memory consumption.
|
||||
|
@ -62,50 +68,58 @@ class DOMCanvasFactory {
|
|||
}
|
||||
|
||||
class DOMCMapReaderFactory {
|
||||
constructor({ baseUrl = null, isCompressed = false, }) {
|
||||
constructor({ baseUrl = null, isCompressed = false }) {
|
||||
this.baseUrl = baseUrl;
|
||||
this.isCompressed = isCompressed;
|
||||
}
|
||||
|
||||
async fetch({ name, }) {
|
||||
async fetch({ name }) {
|
||||
if (!this.baseUrl) {
|
||||
throw new Error(
|
||||
'The CMap "baseUrl" parameter must be specified, ensure that ' +
|
||||
'the "cMapUrl" and "cMapPacked" API parameters are provided.');
|
||||
'the "cMapUrl" and "cMapPacked" API parameters are provided.'
|
||||
);
|
||||
}
|
||||
if (!name) {
|
||||
throw new Error('CMap name must be specified.');
|
||||
throw new Error("CMap name must be specified.");
|
||||
}
|
||||
const url = this.baseUrl + name + (this.isCompressed ? '.bcmap' : '');
|
||||
const compressionType = (this.isCompressed ? CMapCompressionType.BINARY :
|
||||
CMapCompressionType.NONE);
|
||||
const url = this.baseUrl + name + (this.isCompressed ? ".bcmap" : "");
|
||||
const compressionType = this.isCompressed
|
||||
? CMapCompressionType.BINARY
|
||||
: CMapCompressionType.NONE;
|
||||
|
||||
if ((typeof PDFJSDev !== 'undefined' && PDFJSDev.test('MOZCENTRAL')) ||
|
||||
(isFetchSupported() && isValidFetchUrl(url, document.baseURI))) {
|
||||
return fetch(url).then(async (response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
let cMapData;
|
||||
if (this.isCompressed) {
|
||||
cMapData = new Uint8Array(await response.arrayBuffer());
|
||||
} else {
|
||||
cMapData = stringToBytes(await response.text());
|
||||
}
|
||||
return { cMapData, compressionType, };
|
||||
}).catch((reason) => {
|
||||
throw new Error(`Unable to load ${this.isCompressed ? 'binary ' : ''}` +
|
||||
`CMap at: ${url}`);
|
||||
});
|
||||
if (
|
||||
(typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) ||
|
||||
(isFetchSupported() && isValidFetchUrl(url, document.baseURI))
|
||||
) {
|
||||
return fetch(url)
|
||||
.then(async response => {
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
let cMapData;
|
||||
if (this.isCompressed) {
|
||||
cMapData = new Uint8Array(await response.arrayBuffer());
|
||||
} else {
|
||||
cMapData = stringToBytes(await response.text());
|
||||
}
|
||||
return { cMapData, compressionType };
|
||||
})
|
||||
.catch(reason => {
|
||||
throw new Error(
|
||||
`Unable to load ${this.isCompressed ? "binary " : ""}` +
|
||||
`CMap at: ${url}`
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// The Fetch API is not supported.
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', url, true);
|
||||
request.open("GET", url, true);
|
||||
|
||||
if (this.isCompressed) {
|
||||
request.responseType = 'arraybuffer';
|
||||
request.responseType = "arraybuffer";
|
||||
}
|
||||
request.onreadystatechange = () => {
|
||||
if (request.readyState !== XMLHttpRequest.DONE) {
|
||||
|
@ -119,7 +133,7 @@ class DOMCMapReaderFactory {
|
|||
cMapData = stringToBytes(request.responseText);
|
||||
}
|
||||
if (cMapData) {
|
||||
resolve({ cMapData, compressionType, });
|
||||
resolve({ cMapData, compressionType });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -127,29 +141,31 @@ class DOMCMapReaderFactory {
|
|||
};
|
||||
|
||||
request.send(null);
|
||||
}).catch((reason) => {
|
||||
throw new Error(`Unable to load ${this.isCompressed ? 'binary ' : ''}` +
|
||||
`CMap at: ${url}`);
|
||||
}).catch(reason => {
|
||||
throw new Error(
|
||||
`Unable to load ${this.isCompressed ? "binary " : ""}` +
|
||||
`CMap at: ${url}`
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class DOMSVGFactory {
|
||||
create(width, height) {
|
||||
assert(width > 0 && height > 0, 'Invalid SVG dimensions');
|
||||
assert(width > 0 && height > 0, "Invalid SVG dimensions");
|
||||
|
||||
const svg = document.createElementNS(SVG_NS, 'svg:svg');
|
||||
svg.setAttribute('version', '1.1');
|
||||
svg.setAttribute('width', width + 'px');
|
||||
svg.setAttribute('height', height + 'px');
|
||||
svg.setAttribute('preserveAspectRatio', 'none');
|
||||
svg.setAttribute('viewBox', '0 0 ' + width + ' ' + height);
|
||||
const svg = document.createElementNS(SVG_NS, "svg:svg");
|
||||
svg.setAttribute("version", "1.1");
|
||||
svg.setAttribute("width", width + "px");
|
||||
svg.setAttribute("height", height + "px");
|
||||
svg.setAttribute("preserveAspectRatio", "none");
|
||||
svg.setAttribute("viewBox", "0 0 " + width + " " + height);
|
||||
|
||||
return svg;
|
||||
}
|
||||
|
||||
createElement(type) {
|
||||
assert(typeof type === 'string', 'Invalid SVG element type');
|
||||
assert(typeof type === "string", "Invalid SVG element type");
|
||||
|
||||
return document.createElementNS(SVG_NS, type);
|
||||
}
|
||||
|
@ -189,8 +205,14 @@ class PageViewport {
|
|||
/**
|
||||
* @param {PageViewportParameters}
|
||||
*/
|
||||
constructor({ viewBox, scale, rotation, offsetX = 0, offsetY = 0,
|
||||
dontFlip = false, }) {
|
||||
constructor({
|
||||
viewBox,
|
||||
scale,
|
||||
rotation,
|
||||
offsetX = 0,
|
||||
offsetY = 0,
|
||||
dontFlip = false,
|
||||
}) {
|
||||
this.viewBox = viewBox;
|
||||
this.scale = scale;
|
||||
this.rotation = rotation;
|
||||
|
@ -206,22 +228,35 @@ class PageViewport {
|
|||
rotation = rotation < 0 ? rotation + 360 : rotation;
|
||||
switch (rotation) {
|
||||
case 180:
|
||||
rotateA = -1; rotateB = 0; rotateC = 0; rotateD = 1;
|
||||
rotateA = -1;
|
||||
rotateB = 0;
|
||||
rotateC = 0;
|
||||
rotateD = 1;
|
||||
break;
|
||||
case 90:
|
||||
rotateA = 0; rotateB = 1; rotateC = 1; rotateD = 0;
|
||||
rotateA = 0;
|
||||
rotateB = 1;
|
||||
rotateC = 1;
|
||||
rotateD = 0;
|
||||
break;
|
||||
case 270:
|
||||
rotateA = 0; rotateB = -1; rotateC = -1; rotateD = 0;
|
||||
rotateA = 0;
|
||||
rotateB = -1;
|
||||
rotateC = -1;
|
||||
rotateD = 0;
|
||||
break;
|
||||
// case 0:
|
||||
default:
|
||||
rotateA = 1; rotateB = 0; rotateC = 0; rotateD = -1;
|
||||
rotateA = 1;
|
||||
rotateB = 0;
|
||||
rotateC = 0;
|
||||
rotateD = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dontFlip) {
|
||||
rotateC = -rotateC; rotateD = -rotateD;
|
||||
rotateC = -rotateC;
|
||||
rotateD = -rotateD;
|
||||
}
|
||||
|
||||
let offsetCanvasX, offsetCanvasY;
|
||||
|
@ -246,7 +281,7 @@ class PageViewport {
|
|||
rotateC * scale,
|
||||
rotateD * scale,
|
||||
offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY,
|
||||
offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY
|
||||
offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY,
|
||||
];
|
||||
|
||||
this.width = width;
|
||||
|
@ -258,8 +293,13 @@ class PageViewport {
|
|||
* @param {PageViewportCloneParameters} [params]
|
||||
* @returns {PageViewport} Cloned viewport.
|
||||
*/
|
||||
clone({ scale = this.scale, rotation = this.rotation, offsetX = this.offsetX,
|
||||
offsetY = this.offsetY, dontFlip = false, } = {}) {
|
||||
clone({
|
||||
scale = this.scale,
|
||||
rotation = this.rotation,
|
||||
offsetX = this.offsetX,
|
||||
offsetY = this.offsetY,
|
||||
dontFlip = false,
|
||||
} = {}) {
|
||||
return new PageViewport({
|
||||
viewBox: this.viewBox.slice(),
|
||||
scale,
|
||||
|
@ -343,50 +383,54 @@ const LinkTarget = {
|
|||
* @param {HTMLLinkElement} link - The link element.
|
||||
* @param {ExternalLinkParameters} params
|
||||
*/
|
||||
function addLinkAttributes(link, { url, target, rel, enabled = true, } = {}) {
|
||||
assert(url && typeof url === 'string',
|
||||
'addLinkAttributes: A valid "url" parameter must provided.');
|
||||
function addLinkAttributes(link, { url, target, rel, enabled = true } = {}) {
|
||||
assert(
|
||||
url && typeof url === "string",
|
||||
'addLinkAttributes: A valid "url" parameter must provided.'
|
||||
);
|
||||
|
||||
const urlNullRemoved = removeNullCharacters(url);
|
||||
if (enabled) {
|
||||
link.href = link.title = urlNullRemoved;
|
||||
} else {
|
||||
link.href = '';
|
||||
link.href = "";
|
||||
link.title = `Disabled: ${urlNullRemoved}`;
|
||||
link.onclick = () => {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
let targetStr = ''; // LinkTarget.NONE
|
||||
let targetStr = ""; // LinkTarget.NONE
|
||||
switch (target) {
|
||||
case LinkTarget.NONE:
|
||||
break;
|
||||
case LinkTarget.SELF:
|
||||
targetStr = '_self';
|
||||
targetStr = "_self";
|
||||
break;
|
||||
case LinkTarget.BLANK:
|
||||
targetStr = '_blank';
|
||||
targetStr = "_blank";
|
||||
break;
|
||||
case LinkTarget.PARENT:
|
||||
targetStr = '_parent';
|
||||
targetStr = "_parent";
|
||||
break;
|
||||
case LinkTarget.TOP:
|
||||
targetStr = '_top';
|
||||
targetStr = "_top";
|
||||
break;
|
||||
}
|
||||
link.target = targetStr;
|
||||
|
||||
link.rel = (typeof rel === 'string' ? rel : DEFAULT_LINK_REL);
|
||||
link.rel = typeof rel === "string" ? rel : DEFAULT_LINK_REL;
|
||||
}
|
||||
|
||||
// Gets the file name from a given URL.
|
||||
function getFilenameFromUrl(url) {
|
||||
const anchor = url.indexOf('#');
|
||||
const query = url.indexOf('?');
|
||||
const end = Math.min(anchor > 0 ? anchor : url.length,
|
||||
query > 0 ? query : url.length);
|
||||
return url.substring(url.lastIndexOf('/', end) + 1, end);
|
||||
const anchor = url.indexOf("#");
|
||||
const query = url.indexOf("?");
|
||||
const end = Math.min(
|
||||
anchor > 0 ? anchor : url.length,
|
||||
query > 0 ? query : url.length
|
||||
);
|
||||
return url.substring(url.lastIndexOf("/", end) + 1, end);
|
||||
}
|
||||
|
||||
class StatTimer {
|
||||
|
@ -407,9 +451,9 @@ class StatTimer {
|
|||
warn(`Timer has not been started for ${name}`);
|
||||
}
|
||||
this.times.push({
|
||||
'name': name,
|
||||
'start': this.started[name],
|
||||
'end': Date.now(),
|
||||
name,
|
||||
start: this.started[name],
|
||||
end: Date.now(),
|
||||
});
|
||||
// Remove timer from started so it can be called again.
|
||||
delete this.started[name];
|
||||
|
@ -417,7 +461,8 @@ class StatTimer {
|
|||
|
||||
toString() {
|
||||
// Find the longest name for padding purposes.
|
||||
let outBuf = [], longest = 0;
|
||||
let outBuf = [],
|
||||
longest = 0;
|
||||
for (const time of this.times) {
|
||||
const name = time.name;
|
||||
if (name.length > longest) {
|
||||
|
@ -428,21 +473,24 @@ class StatTimer {
|
|||
const duration = time.end - time.start;
|
||||
outBuf.push(`${time.name.padEnd(longest)} ${duration}ms\n`);
|
||||
}
|
||||
return outBuf.join('');
|
||||
return outBuf.join("");
|
||||
}
|
||||
}
|
||||
|
||||
function isFetchSupported() {
|
||||
return (typeof fetch !== 'undefined' &&
|
||||
typeof Response !== 'undefined' && 'body' in Response.prototype &&
|
||||
typeof ReadableStream !== 'undefined');
|
||||
return (
|
||||
typeof fetch !== "undefined" &&
|
||||
typeof Response !== "undefined" &&
|
||||
"body" in Response.prototype &&
|
||||
typeof ReadableStream !== "undefined"
|
||||
);
|
||||
}
|
||||
|
||||
function isValidFetchUrl(url, baseUrl) {
|
||||
try {
|
||||
const { protocol, } = baseUrl ? new URL(url, baseUrl) : new URL(url);
|
||||
const { protocol } = baseUrl ? new URL(url, baseUrl) : new URL(url);
|
||||
// The Fetch API only supports the http/https protocols, and not file/ftp.
|
||||
return (protocol === 'http:' || protocol === 'https:');
|
||||
return protocol === "http:" || protocol === "https:";
|
||||
} catch (ex) {
|
||||
return false; // `new URL()` will throw on incorrect data.
|
||||
}
|
||||
|
@ -450,7 +498,7 @@ function isValidFetchUrl(url, baseUrl) {
|
|||
|
||||
function loadScript(src) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script');
|
||||
const script = document.createElement("script");
|
||||
script.src = src;
|
||||
|
||||
script.onload = resolve;
|
||||
|
@ -463,39 +511,42 @@ function loadScript(src) {
|
|||
|
||||
// Deprecated API function -- display regardless of the `verbosity` setting.
|
||||
function deprecated(details) {
|
||||
console.log('Deprecated API usage: ' + details);
|
||||
console.log("Deprecated API usage: " + details);
|
||||
}
|
||||
|
||||
function releaseImageResources(img) {
|
||||
assert(img instanceof Image, 'Invalid `img` parameter.');
|
||||
assert(img instanceof Image, "Invalid `img` parameter.");
|
||||
|
||||
const url = img.src;
|
||||
if (typeof url === 'string' && url.startsWith('blob:') &&
|
||||
URL.revokeObjectURL) {
|
||||
if (
|
||||
typeof url === "string" &&
|
||||
url.startsWith("blob:") &&
|
||||
URL.revokeObjectURL
|
||||
) {
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
img.removeAttribute('src');
|
||||
img.removeAttribute("src");
|
||||
}
|
||||
|
||||
let pdfDateStringRegex;
|
||||
|
||||
class PDFDateString {
|
||||
/**
|
||||
* Convert a PDF date string to a JavaScript `Date` object.
|
||||
*
|
||||
* The PDF date string format is described in section 7.9.4 of the official
|
||||
* PDF 32000-1:2008 specification. However, in the PDF 1.7 reference (sixth
|
||||
* edition) Adobe describes the same format including a trailing apostrophe.
|
||||
* This syntax in incorrect, but Adobe Acrobat creates PDF files that contain
|
||||
* them. We ignore all apostrophes as they are not necessary for date parsing.
|
||||
*
|
||||
* Moreover, Adobe Acrobat doesn't handle changing the date to universal time
|
||||
* and doesn't use the user's time zone (effectively ignoring the HH' and mm'
|
||||
* parts of the date string).
|
||||
*
|
||||
* @param {string} input
|
||||
* @returns {Date|null}
|
||||
*/
|
||||
/**
|
||||
* Convert a PDF date string to a JavaScript `Date` object.
|
||||
*
|
||||
* The PDF date string format is described in section 7.9.4 of the official
|
||||
* PDF 32000-1:2008 specification. However, in the PDF 1.7 reference (sixth
|
||||
* edition) Adobe describes the same format including a trailing apostrophe.
|
||||
* This syntax in incorrect, but Adobe Acrobat creates PDF files that contain
|
||||
* them. We ignore all apostrophes as they are not necessary for date parsing.
|
||||
*
|
||||
* Moreover, Adobe Acrobat doesn't handle changing the date to universal time
|
||||
* and doesn't use the user's time zone (effectively ignoring the HH' and mm'
|
||||
* parts of the date string).
|
||||
*
|
||||
* @param {string} input
|
||||
* @returns {Date|null}
|
||||
*/
|
||||
static toDateObject(input) {
|
||||
if (!input || !isString(input)) {
|
||||
return null;
|
||||
|
@ -504,18 +555,18 @@ class PDFDateString {
|
|||
// Lazily initialize the regular expression.
|
||||
if (!pdfDateStringRegex) {
|
||||
pdfDateStringRegex = new RegExp(
|
||||
'^D:' + // Prefix (required)
|
||||
'(\\d{4})' + // Year (required)
|
||||
'(\\d{2})?' + // Month (optional)
|
||||
'(\\d{2})?' + // Day (optional)
|
||||
'(\\d{2})?' + // Hour (optional)
|
||||
'(\\d{2})?' + // Minute (optional)
|
||||
'(\\d{2})?' + // Second (optional)
|
||||
'([Z|+|-])?' + // Universal time relation (optional)
|
||||
'(\\d{2})?' + // Offset hour (optional)
|
||||
'\'?' + // Splitting apostrophe (optional)
|
||||
'(\\d{2})?' + // Offset minute (optional)
|
||||
'\'?' // Trailing apostrophe (optional)
|
||||
"^D:" + // Prefix (required)
|
||||
"(\\d{4})" + // Year (required)
|
||||
"(\\d{2})?" + // Month (optional)
|
||||
"(\\d{2})?" + // Day (optional)
|
||||
"(\\d{2})?" + // Hour (optional)
|
||||
"(\\d{2})?" + // Minute (optional)
|
||||
"(\\d{2})?" + // Second (optional)
|
||||
"([Z|+|-])?" + // Universal time relation (optional)
|
||||
"(\\d{2})?" + // Offset hour (optional)
|
||||
"'?" + // Splitting apostrophe (optional)
|
||||
"(\\d{2})?" + // Offset minute (optional)
|
||||
"'?" // Trailing apostrophe (optional)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -531,29 +582,29 @@ class PDFDateString {
|
|||
// instead of 1 and 12, so we have to correct for that.
|
||||
const year = parseInt(matches[1], 10);
|
||||
let month = parseInt(matches[2], 10);
|
||||
month = (month >= 1 && month <= 12) ? month - 1 : 0;
|
||||
month = month >= 1 && month <= 12 ? month - 1 : 0;
|
||||
let day = parseInt(matches[3], 10);
|
||||
day = (day >= 1 && day <= 31) ? day : 1;
|
||||
day = day >= 1 && day <= 31 ? day : 1;
|
||||
let hour = parseInt(matches[4], 10);
|
||||
hour = (hour >= 0 && hour <= 23) ? hour : 0;
|
||||
hour = hour >= 0 && hour <= 23 ? hour : 0;
|
||||
let minute = parseInt(matches[5], 10);
|
||||
minute = (minute >= 0 && minute <= 59) ? minute : 0;
|
||||
minute = minute >= 0 && minute <= 59 ? minute : 0;
|
||||
let second = parseInt(matches[6], 10);
|
||||
second = (second >= 0 && second <= 59) ? second : 0;
|
||||
const universalTimeRelation = matches[7] || 'Z';
|
||||
second = second >= 0 && second <= 59 ? second : 0;
|
||||
const universalTimeRelation = matches[7] || "Z";
|
||||
let offsetHour = parseInt(matches[8], 10);
|
||||
offsetHour = (offsetHour >= 0 && offsetHour <= 23) ? offsetHour : 0;
|
||||
offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0;
|
||||
let offsetMinute = parseInt(matches[9], 10) || 0;
|
||||
offsetMinute = (offsetMinute >= 0 && offsetMinute <= 59) ? offsetMinute : 0;
|
||||
offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0;
|
||||
|
||||
// Universal time relation 'Z' means that the local time is equal to the
|
||||
// universal time, whereas the relations '+'/'-' indicate that the local
|
||||
// time is later respectively earlier than the universal time. Every date
|
||||
// is normalized to universal time.
|
||||
if (universalTimeRelation === '-') {
|
||||
if (universalTimeRelation === "-") {
|
||||
hour += offsetHour;
|
||||
minute += offsetMinute;
|
||||
} else if (universalTimeRelation === '+') {
|
||||
} else if (universalTimeRelation === "+") {
|
||||
hour -= offsetHour;
|
||||
minute -= offsetMinute;
|
||||
}
|
||||
|
|
|
@ -15,21 +15,25 @@
|
|||
/* eslint no-var: error */
|
||||
|
||||
import {
|
||||
AbortException, assert, createPromiseCapability
|
||||
} from '../shared/util';
|
||||
AbortException,
|
||||
assert,
|
||||
createPromiseCapability,
|
||||
} from "../shared/util";
|
||||
import {
|
||||
createResponseStatusError, extractFilenameFromHeader,
|
||||
validateRangeRequestCapabilities, validateResponseStatus
|
||||
} from './network_utils';
|
||||
createResponseStatusError,
|
||||
extractFilenameFromHeader,
|
||||
validateRangeRequestCapabilities,
|
||||
validateResponseStatus,
|
||||
} from "./network_utils";
|
||||
|
||||
function createFetchOptions(headers, withCredentials, abortController) {
|
||||
return {
|
||||
method: 'GET',
|
||||
method: "GET",
|
||||
headers,
|
||||
signal: abortController && abortController.signal,
|
||||
mode: 'cors',
|
||||
credentials: withCredentials ? 'include' : 'same-origin',
|
||||
redirect: 'follow',
|
||||
mode: "cors",
|
||||
credentials: withCredentials ? "include" : "same-origin",
|
||||
redirect: "follow",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -37,7 +41,7 @@ function createHeaders(httpHeaders) {
|
|||
const headers = new Headers();
|
||||
for (const property in httpHeaders) {
|
||||
const value = httpHeaders[property];
|
||||
if (typeof value === 'undefined') {
|
||||
if (typeof value === "undefined") {
|
||||
continue;
|
||||
}
|
||||
headers.append(property, value);
|
||||
|
@ -57,7 +61,7 @@ class PDFFetchStream {
|
|||
}
|
||||
|
||||
get _progressiveDataLength() {
|
||||
return (this._fullRequestReader ? this._fullRequestReader._loaded : 0);
|
||||
return this._fullRequestReader ? this._fullRequestReader._loaded : 0;
|
||||
}
|
||||
|
||||
getFullReader() {
|
||||
|
@ -103,7 +107,7 @@ class PDFFetchStreamReader {
|
|||
this._disableRange = true;
|
||||
}
|
||||
|
||||
if (typeof AbortController !== 'undefined') {
|
||||
if (typeof AbortController !== "undefined") {
|
||||
this._abortController = new AbortController();
|
||||
}
|
||||
this._isStreamingSupported = !source.disableStream;
|
||||
|
@ -112,37 +116,47 @@ class PDFFetchStreamReader {
|
|||
this._headers = createHeaders(this._stream.httpHeaders);
|
||||
|
||||
const url = source.url;
|
||||
fetch(url, createFetchOptions(this._headers, this._withCredentials,
|
||||
this._abortController)).then((response) => {
|
||||
if (!validateResponseStatus(response.status)) {
|
||||
throw createResponseStatusError(response.status, url);
|
||||
}
|
||||
this._reader = response.body.getReader();
|
||||
this._headersCapability.resolve();
|
||||
fetch(
|
||||
url,
|
||||
createFetchOptions(
|
||||
this._headers,
|
||||
this._withCredentials,
|
||||
this._abortController
|
||||
)
|
||||
)
|
||||
.then(response => {
|
||||
if (!validateResponseStatus(response.status)) {
|
||||
throw createResponseStatusError(response.status, url);
|
||||
}
|
||||
this._reader = response.body.getReader();
|
||||
this._headersCapability.resolve();
|
||||
|
||||
const getResponseHeader = (name) => {
|
||||
return response.headers.get(name);
|
||||
};
|
||||
const { allowRangeRequests, suggestedLength, } =
|
||||
validateRangeRequestCapabilities({
|
||||
const getResponseHeader = name => {
|
||||
return response.headers.get(name);
|
||||
};
|
||||
const {
|
||||
allowRangeRequests,
|
||||
suggestedLength,
|
||||
} = validateRangeRequestCapabilities({
|
||||
getResponseHeader,
|
||||
isHttp: this._stream.isHttp,
|
||||
rangeChunkSize: this._rangeChunkSize,
|
||||
disableRange: this._disableRange,
|
||||
});
|
||||
|
||||
this._isRangeSupported = allowRangeRequests;
|
||||
// Setting right content length.
|
||||
this._contentLength = suggestedLength || this._contentLength;
|
||||
this._isRangeSupported = allowRangeRequests;
|
||||
// Setting right content length.
|
||||
this._contentLength = suggestedLength || this._contentLength;
|
||||
|
||||
this._filename = extractFilenameFromHeader(getResponseHeader);
|
||||
this._filename = extractFilenameFromHeader(getResponseHeader);
|
||||
|
||||
// We need to stop reading when range is supported and streaming is
|
||||
// disabled.
|
||||
if (!this._isStreamingSupported && this._isRangeSupported) {
|
||||
this.cancel(new AbortException('Streaming is disabled.'));
|
||||
}
|
||||
}).catch(this._headersCapability.reject);
|
||||
// We need to stop reading when range is supported and streaming is
|
||||
// disabled.
|
||||
if (!this._isStreamingSupported && this._isRangeSupported) {
|
||||
this.cancel(new AbortException("Streaming is disabled."));
|
||||
}
|
||||
})
|
||||
.catch(this._headersCapability.reject);
|
||||
|
||||
this.onProgress = null;
|
||||
}
|
||||
|
@ -169,9 +183,9 @@ class PDFFetchStreamReader {
|
|||
|
||||
async read() {
|
||||
await this._headersCapability.promise;
|
||||
const { value, done, } = await this._reader.read();
|
||||
const { value, done } = await this._reader.read();
|
||||
if (done) {
|
||||
return { value, done, };
|
||||
return { value, done };
|
||||
}
|
||||
this._loaded += value.byteLength;
|
||||
if (this.onProgress) {
|
||||
|
@ -181,7 +195,7 @@ class PDFFetchStreamReader {
|
|||
});
|
||||
}
|
||||
const buffer = new Uint8Array(value).buffer;
|
||||
return { value: buffer, done: false, };
|
||||
return { value: buffer, done: false };
|
||||
}
|
||||
|
||||
cancel(reason) {
|
||||
|
@ -205,16 +219,22 @@ class PDFFetchStreamRangeReader {
|
|||
this._readCapability = createPromiseCapability();
|
||||
this._isStreamingSupported = !source.disableStream;
|
||||
|
||||
if (typeof AbortController !== 'undefined') {
|
||||
if (typeof AbortController !== "undefined") {
|
||||
this._abortController = new AbortController();
|
||||
}
|
||||
|
||||
this._headers = createHeaders(this._stream.httpHeaders);
|
||||
this._headers.append('Range', `bytes=${begin}-${end - 1}`);
|
||||
this._headers.append("Range", `bytes=${begin}-${end - 1}`);
|
||||
|
||||
const url = source.url;
|
||||
fetch(url, createFetchOptions(this._headers, this._withCredentials,
|
||||
this._abortController)).then((response) => {
|
||||
fetch(
|
||||
url,
|
||||
createFetchOptions(
|
||||
this._headers,
|
||||
this._withCredentials,
|
||||
this._abortController
|
||||
)
|
||||
).then(response => {
|
||||
if (!validateResponseStatus(response.status)) {
|
||||
throw createResponseStatusError(response.status, url);
|
||||
}
|
||||
|
@ -231,16 +251,16 @@ class PDFFetchStreamRangeReader {
|
|||
|
||||
async read() {
|
||||
await this._readCapability.promise;
|
||||
const { value, done, } = await this._reader.read();
|
||||
const { value, done } = await this._reader.read();
|
||||
if (done) {
|
||||
return { value, done, };
|
||||
return { value, done };
|
||||
}
|
||||
this._loaded += value.byteLength;
|
||||
if (this.onProgress) {
|
||||
this.onProgress({ loaded: this._loaded, });
|
||||
this.onProgress({ loaded: this._loaded });
|
||||
}
|
||||
const buffer = new Uint8Array(value).buffer;
|
||||
return { value: buffer, done: false, };
|
||||
return { value: buffer, done: false };
|
||||
}
|
||||
|
||||
cancel(reason) {
|
||||
|
@ -253,6 +273,4 @@ class PDFFetchStreamRangeReader {
|
|||
}
|
||||
}
|
||||
|
||||
export {
|
||||
PDFFetchStream,
|
||||
};
|
||||
export { PDFFetchStream };
|
||||
|
|
|
@ -14,14 +14,20 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
assert, bytesToString, isEvalSupported, shadow, string32, unreachable,
|
||||
UNSUPPORTED_FEATURES, warn
|
||||
} from '../shared/util';
|
||||
assert,
|
||||
bytesToString,
|
||||
isEvalSupported,
|
||||
shadow,
|
||||
string32,
|
||||
unreachable,
|
||||
UNSUPPORTED_FEATURES,
|
||||
warn,
|
||||
} from "../shared/util";
|
||||
|
||||
class BaseFontLoader {
|
||||
constructor({ docId, onUnsupportedFeature, }) {
|
||||
constructor({ docId, onUnsupportedFeature }) {
|
||||
if (this.constructor === BaseFontLoader) {
|
||||
unreachable('Cannot initialize BaseFontLoader.');
|
||||
unreachable("Cannot initialize BaseFontLoader.");
|
||||
}
|
||||
this.docId = docId;
|
||||
this._onUnsupportedFeature = onUnsupportedFeature;
|
||||
|
@ -38,10 +44,11 @@ class BaseFontLoader {
|
|||
insertRule(rule) {
|
||||
let styleElement = this.styleElement;
|
||||
if (!styleElement) {
|
||||
styleElement = this.styleElement = document.createElement('style');
|
||||
styleElement = this.styleElement = document.createElement("style");
|
||||
styleElement.id = `PDFJS_FONT_STYLE_TAG_${this.docId}`;
|
||||
document.documentElement.getElementsByTagName('head')[0].appendChild(
|
||||
styleElement);
|
||||
document.documentElement
|
||||
.getElementsByTagName("head")[0]
|
||||
.appendChild(styleElement);
|
||||
}
|
||||
|
||||
const styleSheet = styleElement.sheet;
|
||||
|
@ -75,7 +82,7 @@ class BaseFontLoader {
|
|||
try {
|
||||
await nativeFontFace.loaded;
|
||||
} catch (ex) {
|
||||
this._onUnsupportedFeature({ featureId: UNSUPPORTED_FEATURES.font, });
|
||||
this._onUnsupportedFeature({ featureId: UNSUPPORTED_FEATURES.font });
|
||||
warn(`Failed to load font '${nativeFontFace.family}': '${ex}'.`);
|
||||
|
||||
// When font loading failed, fall back to the built-in font renderer.
|
||||
|
@ -94,7 +101,7 @@ class BaseFontLoader {
|
|||
if (this.isSyncFontLoadingSupported) {
|
||||
return undefined; // The font was, synchronously, loaded.
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
return new Promise(resolve => {
|
||||
const request = this._queueLoadingCallback(resolve);
|
||||
this._prepareFontLoadEvent([rule], [font], request);
|
||||
});
|
||||
|
@ -103,251 +110,277 @@ class BaseFontLoader {
|
|||
}
|
||||
|
||||
_queueLoadingCallback(callback) {
|
||||
unreachable('Abstract method `_queueLoadingCallback`.');
|
||||
unreachable("Abstract method `_queueLoadingCallback`.");
|
||||
}
|
||||
|
||||
get isFontLoadingAPISupported() { // eslint-disable-line getter-return
|
||||
unreachable('Abstract method `isFontLoadingAPISupported`.');
|
||||
get isFontLoadingAPISupported() {
|
||||
// eslint-disable-line getter-return
|
||||
unreachable("Abstract method `isFontLoadingAPISupported`.");
|
||||
}
|
||||
|
||||
get isSyncFontLoadingSupported() { // eslint-disable-line getter-return
|
||||
unreachable('Abstract method `isSyncFontLoadingSupported`.');
|
||||
get isSyncFontLoadingSupported() {
|
||||
// eslint-disable-line getter-return
|
||||
unreachable("Abstract method `isSyncFontLoadingSupported`.");
|
||||
}
|
||||
|
||||
get _loadTestFont() { // eslint-disable-line getter-return
|
||||
unreachable('Abstract method `_loadTestFont`.');
|
||||
get _loadTestFont() {
|
||||
// eslint-disable-line getter-return
|
||||
unreachable("Abstract method `_loadTestFont`.");
|
||||
}
|
||||
|
||||
_prepareFontLoadEvent(rules, fontsToLoad, request) {
|
||||
unreachable('Abstract method `_prepareFontLoadEvent`.');
|
||||
unreachable("Abstract method `_prepareFontLoadEvent`.");
|
||||
}
|
||||
}
|
||||
|
||||
let FontLoader;
|
||||
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('MOZCENTRAL')) {
|
||||
|
||||
FontLoader = class MozcentralFontLoader extends BaseFontLoader {
|
||||
get isFontLoadingAPISupported() {
|
||||
return shadow(this, 'isFontLoadingAPISupported',
|
||||
typeof document !== 'undefined' && !!document.fonts);
|
||||
}
|
||||
|
||||
get isSyncFontLoadingSupported() {
|
||||
return shadow(this, 'isSyncFontLoadingSupported', true);
|
||||
}
|
||||
};
|
||||
|
||||
} else { // PDFJSDev.test('CHROME || GENERIC')
|
||||
|
||||
FontLoader = class GenericFontLoader extends BaseFontLoader {
|
||||
constructor(docId) {
|
||||
super(docId);
|
||||
this.loadingContext = {
|
||||
requests: [],
|
||||
nextRequestId: 0,
|
||||
};
|
||||
this.loadTestFontId = 0;
|
||||
}
|
||||
|
||||
get isFontLoadingAPISupported() {
|
||||
let supported = (typeof document !== 'undefined' && !!document.fonts);
|
||||
|
||||
if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) &&
|
||||
(supported && typeof navigator !== 'undefined')) {
|
||||
// The Firefox Font Loading API does not work with `mozPrintCallback`
|
||||
// prior to version 63; see https://bugzilla.mozilla.org/show_bug.cgi?id=1473742
|
||||
const m = /Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(navigator.userAgent);
|
||||
if (m && m[1] < 63) {
|
||||
supported = false;
|
||||
}
|
||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
|
||||
FontLoader = class MozcentralFontLoader extends BaseFontLoader {
|
||||
get isFontLoadingAPISupported() {
|
||||
return shadow(
|
||||
this,
|
||||
"isFontLoadingAPISupported",
|
||||
typeof document !== "undefined" && !!document.fonts
|
||||
);
|
||||
}
|
||||
return shadow(this, 'isFontLoadingAPISupported', supported);
|
||||
}
|
||||
|
||||
get isSyncFontLoadingSupported() {
|
||||
let supported = false;
|
||||
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) {
|
||||
if (typeof navigator === 'undefined') {
|
||||
// Node.js - we can pretend that sync font loading is supported.
|
||||
supported = true;
|
||||
} else {
|
||||
// User agent string sniffing is bad, but there is no reliable way to
|
||||
// tell if the font is fully loaded and ready to be used with canvas.
|
||||
get isSyncFontLoadingSupported() {
|
||||
return shadow(this, "isSyncFontLoadingSupported", true);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
// PDFJSDev.test('CHROME || GENERIC')
|
||||
|
||||
FontLoader = class GenericFontLoader extends BaseFontLoader {
|
||||
constructor(docId) {
|
||||
super(docId);
|
||||
this.loadingContext = {
|
||||
requests: [],
|
||||
nextRequestId: 0,
|
||||
};
|
||||
this.loadTestFontId = 0;
|
||||
}
|
||||
|
||||
get isFontLoadingAPISupported() {
|
||||
let supported = typeof document !== "undefined" && !!document.fonts;
|
||||
|
||||
if (
|
||||
(typeof PDFJSDev === "undefined" || !PDFJSDev.test("CHROME")) &&
|
||||
supported &&
|
||||
typeof navigator !== "undefined"
|
||||
) {
|
||||
// The Firefox Font Loading API does not work with `mozPrintCallback`
|
||||
// prior to version 63; see https://bugzilla.mozilla.org/show_bug.cgi?id=1473742
|
||||
const m = /Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(navigator.userAgent);
|
||||
if (m && m[1] >= 14) {
|
||||
supported = true;
|
||||
if (m && m[1] < 63) {
|
||||
supported = false;
|
||||
}
|
||||
// TODO - other browsers...
|
||||
}
|
||||
return shadow(this, "isFontLoadingAPISupported", supported);
|
||||
}
|
||||
return shadow(this, 'isSyncFontLoadingSupported', supported);
|
||||
}
|
||||
|
||||
_queueLoadingCallback(callback) {
|
||||
function completeRequest() {
|
||||
assert(!request.done, 'completeRequest() cannot be called twice.');
|
||||
request.done = true;
|
||||
|
||||
// Sending all completed requests in order of how they were queued.
|
||||
while (context.requests.length > 0 && context.requests[0].done) {
|
||||
const otherRequest = context.requests.shift();
|
||||
setTimeout(otherRequest.callback, 0);
|
||||
get isSyncFontLoadingSupported() {
|
||||
let supported = false;
|
||||
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("CHROME")) {
|
||||
if (typeof navigator === "undefined") {
|
||||
// Node.js - we can pretend that sync font loading is supported.
|
||||
supported = true;
|
||||
} else {
|
||||
// User agent string sniffing is bad, but there is no reliable way to
|
||||
// tell if the font is fully loaded and ready to be used with canvas.
|
||||
const m = /Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(
|
||||
navigator.userAgent
|
||||
);
|
||||
if (m && m[1] >= 14) {
|
||||
supported = true;
|
||||
}
|
||||
// TODO - other browsers...
|
||||
}
|
||||
}
|
||||
return shadow(this, "isSyncFontLoadingSupported", supported);
|
||||
}
|
||||
|
||||
const context = this.loadingContext;
|
||||
const request = {
|
||||
id: `pdfjs-font-loading-${context.nextRequestId++}`,
|
||||
done: false,
|
||||
complete: completeRequest,
|
||||
callback,
|
||||
};
|
||||
context.requests.push(request);
|
||||
return request;
|
||||
}
|
||||
_queueLoadingCallback(callback) {
|
||||
function completeRequest() {
|
||||
assert(!request.done, "completeRequest() cannot be called twice.");
|
||||
request.done = true;
|
||||
|
||||
get _loadTestFont() {
|
||||
const getLoadTestFont = function() {
|
||||
// This is a CFF font with 1 glyph for '.' that fills its entire width and
|
||||
// height.
|
||||
return atob(
|
||||
'T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQA' +
|
||||
'FQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAA' +
|
||||
'ALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgA' +
|
||||
'AAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1' +
|
||||
'AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD' +
|
||||
'6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACM' +
|
||||
'AooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4D' +
|
||||
'IP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAA' +
|
||||
'AAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUA' +
|
||||
'AQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgAB' +
|
||||
'AAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABY' +
|
||||
'AAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAA' +
|
||||
'AC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
|
||||
'AAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
|
||||
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
|
||||
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
|
||||
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' +
|
||||
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAA' +
|
||||
'AAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQAC' +
|
||||
'AQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3' +
|
||||
'Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTj' +
|
||||
'FQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA==');
|
||||
};
|
||||
return shadow(this, '_loadTestFont', getLoadTestFont());
|
||||
}
|
||||
|
||||
_prepareFontLoadEvent(rules, fonts, request) {
|
||||
/** Hack begin */
|
||||
// There's currently no event when a font has finished downloading so the
|
||||
// following code is a dirty hack to 'guess' when a font is ready.
|
||||
// It's assumed fonts are loaded in order, so add a known test font after
|
||||
// the desired fonts and then test for the loading of that test font.
|
||||
|
||||
function int32(data, offset) {
|
||||
return (data.charCodeAt(offset) << 24) |
|
||||
(data.charCodeAt(offset + 1) << 16) |
|
||||
(data.charCodeAt(offset + 2) << 8) |
|
||||
(data.charCodeAt(offset + 3) & 0xff);
|
||||
}
|
||||
function spliceString(s, offset, remove, insert) {
|
||||
let chunk1 = s.substring(0, offset);
|
||||
let chunk2 = s.substring(offset + remove);
|
||||
return chunk1 + insert + chunk2;
|
||||
}
|
||||
let i, ii;
|
||||
|
||||
// The temporary canvas is used to determine if fonts are loaded.
|
||||
let canvas = document.createElement('canvas');
|
||||
canvas.width = 1;
|
||||
canvas.height = 1;
|
||||
let ctx = canvas.getContext('2d');
|
||||
|
||||
let called = 0;
|
||||
function isFontReady(name, callback) {
|
||||
called++;
|
||||
// With setTimeout clamping this gives the font ~100ms to load.
|
||||
if (called > 30) {
|
||||
warn('Load test font never loaded.');
|
||||
callback();
|
||||
return;
|
||||
// Sending all completed requests in order of how they were queued.
|
||||
while (context.requests.length > 0 && context.requests[0].done) {
|
||||
const otherRequest = context.requests.shift();
|
||||
setTimeout(otherRequest.callback, 0);
|
||||
}
|
||||
}
|
||||
ctx.font = '30px ' + name;
|
||||
ctx.fillText('.', 0, 20);
|
||||
let imageData = ctx.getImageData(0, 0, 1, 1);
|
||||
if (imageData.data[3] > 0) {
|
||||
callback();
|
||||
return;
|
||||
|
||||
const context = this.loadingContext;
|
||||
const request = {
|
||||
id: `pdfjs-font-loading-${context.nextRequestId++}`,
|
||||
done: false,
|
||||
complete: completeRequest,
|
||||
callback,
|
||||
};
|
||||
context.requests.push(request);
|
||||
return request;
|
||||
}
|
||||
|
||||
get _loadTestFont() {
|
||||
const getLoadTestFont = function() {
|
||||
// This is a CFF font with 1 glyph for '.' that fills its entire width and
|
||||
// height.
|
||||
return atob(
|
||||
"T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQA" +
|
||||
"FQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAA" +
|
||||
"ALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgA" +
|
||||
"AAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1" +
|
||||
"AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD" +
|
||||
"6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACM" +
|
||||
"AooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4D" +
|
||||
"IP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAA" +
|
||||
"AAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUA" +
|
||||
"AQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgAB" +
|
||||
"AAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABY" +
|
||||
"AAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAA" +
|
||||
"AC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAA" +
|
||||
"AAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQAC" +
|
||||
"AQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3" +
|
||||
"Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTj" +
|
||||
"FQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA=="
|
||||
);
|
||||
};
|
||||
return shadow(this, "_loadTestFont", getLoadTestFont());
|
||||
}
|
||||
|
||||
_prepareFontLoadEvent(rules, fonts, request) {
|
||||
/** Hack begin */
|
||||
// There's currently no event when a font has finished downloading so the
|
||||
// following code is a dirty hack to 'guess' when a font is ready.
|
||||
// It's assumed fonts are loaded in order, so add a known test font after
|
||||
// the desired fonts and then test for the loading of that test font.
|
||||
|
||||
function int32(data, offset) {
|
||||
return (
|
||||
(data.charCodeAt(offset) << 24) |
|
||||
(data.charCodeAt(offset + 1) << 16) |
|
||||
(data.charCodeAt(offset + 2) << 8) |
|
||||
(data.charCodeAt(offset + 3) & 0xff)
|
||||
);
|
||||
}
|
||||
setTimeout(isFontReady.bind(null, name, callback));
|
||||
function spliceString(s, offset, remove, insert) {
|
||||
let chunk1 = s.substring(0, offset);
|
||||
let chunk2 = s.substring(offset + remove);
|
||||
return chunk1 + insert + chunk2;
|
||||
}
|
||||
let i, ii;
|
||||
|
||||
// The temporary canvas is used to determine if fonts are loaded.
|
||||
let canvas = document.createElement("canvas");
|
||||
canvas.width = 1;
|
||||
canvas.height = 1;
|
||||
let ctx = canvas.getContext("2d");
|
||||
|
||||
let called = 0;
|
||||
function isFontReady(name, callback) {
|
||||
called++;
|
||||
// With setTimeout clamping this gives the font ~100ms to load.
|
||||
if (called > 30) {
|
||||
warn("Load test font never loaded.");
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
ctx.font = "30px " + name;
|
||||
ctx.fillText(".", 0, 20);
|
||||
let imageData = ctx.getImageData(0, 0, 1, 1);
|
||||
if (imageData.data[3] > 0) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
setTimeout(isFontReady.bind(null, name, callback));
|
||||
}
|
||||
|
||||
const loadTestFontId = `lt${Date.now()}${this.loadTestFontId++}`;
|
||||
// Chromium seems to cache fonts based on a hash of the actual font data,
|
||||
// so the font must be modified for each load test else it will appear to
|
||||
// be loaded already.
|
||||
// TODO: This could maybe be made faster by avoiding the btoa of the full
|
||||
// font by splitting it in chunks before hand and padding the font id.
|
||||
let data = this._loadTestFont;
|
||||
let COMMENT_OFFSET = 976; // has to be on 4 byte boundary (for checksum)
|
||||
data = spliceString(
|
||||
data,
|
||||
COMMENT_OFFSET,
|
||||
loadTestFontId.length,
|
||||
loadTestFontId
|
||||
);
|
||||
// CFF checksum is important for IE, adjusting it
|
||||
let CFF_CHECKSUM_OFFSET = 16;
|
||||
let XXXX_VALUE = 0x58585858; // the "comment" filled with 'X'
|
||||
let checksum = int32(data, CFF_CHECKSUM_OFFSET);
|
||||
for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) {
|
||||
checksum = (checksum - XXXX_VALUE + int32(loadTestFontId, i)) | 0;
|
||||
}
|
||||
if (i < loadTestFontId.length) {
|
||||
// align to 4 bytes boundary
|
||||
checksum =
|
||||
(checksum - XXXX_VALUE + int32(loadTestFontId + "XXX", i)) | 0;
|
||||
}
|
||||
data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, string32(checksum));
|
||||
|
||||
const url = `url(data:font/opentype;base64,${btoa(data)});`;
|
||||
const rule = `@font-face {font-family:"${loadTestFontId}";src:${url}}`;
|
||||
this.insertRule(rule);
|
||||
|
||||
let names = [];
|
||||
for (i = 0, ii = fonts.length; i < ii; i++) {
|
||||
names.push(fonts[i].loadedName);
|
||||
}
|
||||
names.push(loadTestFontId);
|
||||
|
||||
let div = document.createElement("div");
|
||||
div.setAttribute(
|
||||
"style",
|
||||
"visibility: hidden;" +
|
||||
"width: 10px; height: 10px;" +
|
||||
"position: absolute; top: 0px; left: 0px;"
|
||||
);
|
||||
for (i = 0, ii = names.length; i < ii; ++i) {
|
||||
let span = document.createElement("span");
|
||||
span.textContent = "Hi";
|
||||
span.style.fontFamily = names[i];
|
||||
div.appendChild(span);
|
||||
}
|
||||
document.body.appendChild(div);
|
||||
|
||||
isFontReady(loadTestFontId, function() {
|
||||
document.body.removeChild(div);
|
||||
request.complete();
|
||||
});
|
||||
/** Hack end */
|
||||
}
|
||||
|
||||
const loadTestFontId = `lt${Date.now()}${this.loadTestFontId++}`;
|
||||
// Chromium seems to cache fonts based on a hash of the actual font data,
|
||||
// so the font must be modified for each load test else it will appear to
|
||||
// be loaded already.
|
||||
// TODO: This could maybe be made faster by avoiding the btoa of the full
|
||||
// font by splitting it in chunks before hand and padding the font id.
|
||||
let data = this._loadTestFont;
|
||||
let COMMENT_OFFSET = 976; // has to be on 4 byte boundary (for checksum)
|
||||
data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length,
|
||||
loadTestFontId);
|
||||
// CFF checksum is important for IE, adjusting it
|
||||
let CFF_CHECKSUM_OFFSET = 16;
|
||||
let XXXX_VALUE = 0x58585858; // the "comment" filled with 'X'
|
||||
let checksum = int32(data, CFF_CHECKSUM_OFFSET);
|
||||
for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) {
|
||||
checksum = (checksum - XXXX_VALUE + int32(loadTestFontId, i)) | 0;
|
||||
}
|
||||
if (i < loadTestFontId.length) { // align to 4 bytes boundary
|
||||
checksum = (checksum - XXXX_VALUE + int32(loadTestFontId + 'XXX', i)) | 0;
|
||||
}
|
||||
data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, string32(checksum));
|
||||
|
||||
const url = `url(data:font/opentype;base64,${btoa(data)});`;
|
||||
const rule = `@font-face {font-family:"${loadTestFontId}";src:${url}}`;
|
||||
this.insertRule(rule);
|
||||
|
||||
let names = [];
|
||||
for (i = 0, ii = fonts.length; i < ii; i++) {
|
||||
names.push(fonts[i].loadedName);
|
||||
}
|
||||
names.push(loadTestFontId);
|
||||
|
||||
let div = document.createElement('div');
|
||||
div.setAttribute('style', 'visibility: hidden;' +
|
||||
'width: 10px; height: 10px;' +
|
||||
'position: absolute; top: 0px; left: 0px;');
|
||||
for (i = 0, ii = names.length; i < ii; ++i) {
|
||||
let span = document.createElement('span');
|
||||
span.textContent = 'Hi';
|
||||
span.style.fontFamily = names[i];
|
||||
div.appendChild(span);
|
||||
}
|
||||
document.body.appendChild(div);
|
||||
|
||||
isFontReady(loadTestFontId, function() {
|
||||
document.body.removeChild(div);
|
||||
request.complete();
|
||||
});
|
||||
/** Hack end */
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
} // End of PDFJSDev.test('CHROME || GENERIC')
|
||||
|
||||
const IsEvalSupportedCached = {
|
||||
get value() {
|
||||
return shadow(this, 'value', isEvalSupported());
|
||||
return shadow(this, "value", isEvalSupported());
|
||||
},
|
||||
};
|
||||
|
||||
class FontFaceObject {
|
||||
constructor(translatedData, { isEvalSupported = true,
|
||||
disableFontFace = false,
|
||||
ignoreErrors = false,
|
||||
onUnsupportedFeature = null,
|
||||
fontRegistry = null, }) {
|
||||
constructor(
|
||||
translatedData,
|
||||
{
|
||||
isEvalSupported = true,
|
||||
disableFontFace = false,
|
||||
ignoreErrors = false,
|
||||
onUnsupportedFeature = null,
|
||||
fontRegistry = null,
|
||||
}
|
||||
) {
|
||||
this.compiledGlyphs = Object.create(null);
|
||||
// importing translated data
|
||||
for (let i in translatedData) {
|
||||
|
@ -394,53 +427,51 @@ class FontFaceObject {
|
|||
|
||||
let cmds, current;
|
||||
try {
|
||||
cmds = objs.get(this.loadedName + '_path_' + character);
|
||||
cmds = objs.get(this.loadedName + "_path_" + character);
|
||||
} catch (ex) {
|
||||
if (!this.ignoreErrors) {
|
||||
throw ex;
|
||||
}
|
||||
if (this._onUnsupportedFeature) {
|
||||
this._onUnsupportedFeature({ featureId: UNSUPPORTED_FEATURES.font, });
|
||||
this._onUnsupportedFeature({ featureId: UNSUPPORTED_FEATURES.font });
|
||||
}
|
||||
warn(`getPathGenerator - ignoring character: "${ex}".`);
|
||||
|
||||
return this.compiledGlyphs[character] = function(c, size) {
|
||||
return (this.compiledGlyphs[character] = function(c, size) {
|
||||
// No-op function, to allow rendering to continue.
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// If we can, compile cmds into JS for MAXIMUM SPEED...
|
||||
if (this.isEvalSupported && IsEvalSupportedCached.value) {
|
||||
let args, js = '';
|
||||
let args,
|
||||
js = "";
|
||||
for (let i = 0, ii = cmds.length; i < ii; i++) {
|
||||
current = cmds[i];
|
||||
|
||||
if (current.args !== undefined) {
|
||||
args = current.args.join(',');
|
||||
args = current.args.join(",");
|
||||
} else {
|
||||
args = '';
|
||||
args = "";
|
||||
}
|
||||
js += 'c.' + current.cmd + '(' + args + ');\n';
|
||||
js += "c." + current.cmd + "(" + args + ");\n";
|
||||
}
|
||||
// eslint-disable-next-line no-new-func
|
||||
return this.compiledGlyphs[character] = new Function('c', 'size', js);
|
||||
return (this.compiledGlyphs[character] = new Function("c", "size", js));
|
||||
}
|
||||
// ... but fall back on using Function.prototype.apply() if we're
|
||||
// blocked from using eval() for whatever reason (like CSP policies).
|
||||
return this.compiledGlyphs[character] = function(c, size) {
|
||||
return (this.compiledGlyphs[character] = function(c, size) {
|
||||
for (let i = 0, ii = cmds.length; i < ii; i++) {
|
||||
current = cmds[i];
|
||||
|
||||
if (current.cmd === 'scale') {
|
||||
if (current.cmd === "scale") {
|
||||
current.args = [size, -size];
|
||||
}
|
||||
c[current.cmd].apply(c, current.args);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
FontFaceObject,
|
||||
FontLoader,
|
||||
};
|
||||
export { FontFaceObject, FontLoader };
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { assert } from '../shared/util';
|
||||
import { SimpleXMLParser } from './xml_parser';
|
||||
import { assert } from "../shared/util";
|
||||
import { SimpleXMLParser } from "./xml_parser";
|
||||
|
||||
class Metadata {
|
||||
constructor(data) {
|
||||
assert(typeof data === 'string', 'Metadata: input is not a string');
|
||||
assert(typeof data === "string", "Metadata: input is not a string");
|
||||
|
||||
// Ghostscript may produce invalid metadata, so try to repair that first.
|
||||
data = this._repair(data);
|
||||
|
@ -36,66 +36,74 @@ class Metadata {
|
|||
|
||||
_repair(data) {
|
||||
// Start by removing any "junk" before the first tag (see issue 10395).
|
||||
return data.replace(/^([^<]+)/, '').replace(/>\\376\\377([^<]+)/g,
|
||||
function(all, codes) {
|
||||
let bytes = codes.replace(/\\([0-3])([0-7])([0-7])/g,
|
||||
function(code, d1, d2, d3) {
|
||||
return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1);
|
||||
}).replace(/&(amp|apos|gt|lt|quot);/g, function(str, name) {
|
||||
switch (name) {
|
||||
case 'amp':
|
||||
return '&';
|
||||
case 'apos':
|
||||
return '\'';
|
||||
case 'gt':
|
||||
return '>';
|
||||
case 'lt':
|
||||
return '<';
|
||||
case 'quot':
|
||||
return '\"';
|
||||
return data
|
||||
.replace(/^([^<]+)/, "")
|
||||
.replace(/>\\376\\377([^<]+)/g, function(all, codes) {
|
||||
let bytes = codes
|
||||
.replace(/\\([0-3])([0-7])([0-7])/g, function(code, d1, d2, d3) {
|
||||
return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1);
|
||||
})
|
||||
.replace(/&(amp|apos|gt|lt|quot);/g, function(str, name) {
|
||||
switch (name) {
|
||||
case "amp":
|
||||
return "&";
|
||||
case "apos":
|
||||
return "'";
|
||||
case "gt":
|
||||
return ">";
|
||||
case "lt":
|
||||
return "<";
|
||||
case "quot":
|
||||
return '"';
|
||||
}
|
||||
throw new Error(`_repair: ${name} isn't defined.`);
|
||||
});
|
||||
|
||||
let chars = "";
|
||||
for (let i = 0, ii = bytes.length; i < ii; i += 2) {
|
||||
let code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1);
|
||||
if (
|
||||
code >= 32 &&
|
||||
code < 127 &&
|
||||
code !== 60 &&
|
||||
code !== 62 &&
|
||||
code !== 38
|
||||
) {
|
||||
chars += String.fromCharCode(code);
|
||||
} else {
|
||||
chars += "&#x" + (0x10000 + code).toString(16).substring(1) + ";";
|
||||
}
|
||||
}
|
||||
throw new Error(`_repair: ${name} isn't defined.`);
|
||||
|
||||
return ">" + chars;
|
||||
});
|
||||
|
||||
let chars = '';
|
||||
for (let i = 0, ii = bytes.length; i < ii; i += 2) {
|
||||
let code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1);
|
||||
if (code >= 32 && code < 127 && code !== 60 && code !== 62 &&
|
||||
code !== 38) {
|
||||
chars += String.fromCharCode(code);
|
||||
} else {
|
||||
chars += '&#x' + (0x10000 + code).toString(16).substring(1) + ';';
|
||||
}
|
||||
}
|
||||
|
||||
return '>' + chars;
|
||||
});
|
||||
}
|
||||
|
||||
_parse(xmlDocument) {
|
||||
let rdf = xmlDocument.documentElement;
|
||||
|
||||
if (rdf.nodeName.toLowerCase() !== 'rdf:rdf') { // Wrapped in <xmpmeta>
|
||||
if (rdf.nodeName.toLowerCase() !== "rdf:rdf") {
|
||||
// Wrapped in <xmpmeta>
|
||||
rdf = rdf.firstChild;
|
||||
while (rdf && rdf.nodeName.toLowerCase() !== 'rdf:rdf') {
|
||||
while (rdf && rdf.nodeName.toLowerCase() !== "rdf:rdf") {
|
||||
rdf = rdf.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
let nodeName = rdf ? rdf.nodeName.toLowerCase() : null;
|
||||
if (!rdf || nodeName !== 'rdf:rdf' || !rdf.hasChildNodes()) {
|
||||
if (!rdf || nodeName !== "rdf:rdf" || !rdf.hasChildNodes()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let children = rdf.childNodes;
|
||||
for (let i = 0, ii = children.length; i < ii; i++) {
|
||||
let desc = children[i];
|
||||
if (desc.nodeName.toLowerCase() !== 'rdf:description') {
|
||||
if (desc.nodeName.toLowerCase() !== "rdf:description") {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let j = 0, jj = desc.childNodes.length; j < jj; j++) {
|
||||
if (desc.childNodes[j].nodeName.toLowerCase() !== '#text') {
|
||||
if (desc.childNodes[j].nodeName.toLowerCase() !== "#text") {
|
||||
let entry = desc.childNodes[j];
|
||||
let name = entry.nodeName.toLowerCase();
|
||||
|
||||
|
@ -107,7 +115,7 @@ class Metadata {
|
|||
|
||||
get(name) {
|
||||
const data = this._metadata[name];
|
||||
return (typeof data !== 'undefined' ? data : null);
|
||||
return typeof data !== "undefined" ? data : null;
|
||||
}
|
||||
|
||||
getAll() {
|
||||
|
@ -115,10 +123,8 @@ class Metadata {
|
|||
}
|
||||
|
||||
has(name) {
|
||||
return typeof this._metadata[name] !== 'undefined';
|
||||
return typeof this._metadata[name] !== "undefined";
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
Metadata,
|
||||
};
|
||||
export { Metadata };
|
||||
|
|
|
@ -14,15 +14,18 @@
|
|||
*/
|
||||
/* eslint no-var: error */
|
||||
|
||||
import { assert, createPromiseCapability, stringToBytes } from '../shared/util';
|
||||
import { assert, createPromiseCapability, stringToBytes } from "../shared/util";
|
||||
import {
|
||||
createResponseStatusError, extractFilenameFromHeader,
|
||||
validateRangeRequestCapabilities
|
||||
} from './network_utils';
|
||||
createResponseStatusError,
|
||||
extractFilenameFromHeader,
|
||||
validateRangeRequestCapabilities,
|
||||
} from "./network_utils";
|
||||
|
||||
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
|
||||
throw new Error('Module "./network" shall not ' +
|
||||
'be used with FIREFOX or MOZCENTRAL build.');
|
||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("FIREFOX || MOZCENTRAL")) {
|
||||
throw new Error(
|
||||
'Module "./network" shall not ' +
|
||||
"be used with FIREFOX or MOZCENTRAL build."
|
||||
);
|
||||
}
|
||||
|
||||
const OK_RESPONSE = 200;
|
||||
|
@ -30,7 +33,7 @@ const PARTIAL_CONTENT_RESPONSE = 206;
|
|||
|
||||
function getArrayBuffer(xhr) {
|
||||
const data = xhr.response;
|
||||
if (typeof data !== 'string') {
|
||||
if (typeof data !== "string") {
|
||||
return data;
|
||||
}
|
||||
const array = stringToBytes(data);
|
||||
|
@ -44,7 +47,8 @@ class NetworkManager {
|
|||
this.isHttp = /^https?:/i.test(url);
|
||||
this.httpHeaders = (this.isHttp && args.httpHeaders) || {};
|
||||
this.withCredentials = args.withCredentials || false;
|
||||
this.getXhr = args.getXhr ||
|
||||
this.getXhr =
|
||||
args.getXhr ||
|
||||
function NetworkManager_getXhr() {
|
||||
return new XMLHttpRequest();
|
||||
};
|
||||
|
@ -71,26 +75,26 @@ class NetworkManager {
|
|||
request(args) {
|
||||
const xhr = this.getXhr();
|
||||
const xhrId = this.currXhrId++;
|
||||
const pendingRequest = this.pendingRequests[xhrId] = {
|
||||
const pendingRequest = (this.pendingRequests[xhrId] = {
|
||||
xhr,
|
||||
};
|
||||
});
|
||||
|
||||
xhr.open('GET', this.url);
|
||||
xhr.open("GET", this.url);
|
||||
xhr.withCredentials = this.withCredentials;
|
||||
for (const property in this.httpHeaders) {
|
||||
const value = this.httpHeaders[property];
|
||||
if (typeof value === 'undefined') {
|
||||
if (typeof value === "undefined") {
|
||||
continue;
|
||||
}
|
||||
xhr.setRequestHeader(property, value);
|
||||
}
|
||||
if (this.isHttp && 'begin' in args && 'end' in args) {
|
||||
xhr.setRequestHeader('Range', `bytes=${args.begin}-${args.end - 1}`);
|
||||
if (this.isHttp && "begin" in args && "end" in args) {
|
||||
xhr.setRequestHeader("Range", `bytes=${args.begin}-${args.end - 1}`);
|
||||
pendingRequest.expectedStatus = PARTIAL_CONTENT_RESPONSE;
|
||||
} else {
|
||||
pendingRequest.expectedStatus = OK_RESPONSE;
|
||||
}
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.responseType = "arraybuffer";
|
||||
|
||||
if (args.onError) {
|
||||
xhr.onerror = function(evt) {
|
||||
|
@ -163,8 +167,10 @@ class NetworkManager {
|
|||
xhrStatus === OK_RESPONSE &&
|
||||
pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE;
|
||||
|
||||
if (!ok_response_on_range_request &&
|
||||
xhrStatus !== pendingRequest.expectedStatus) {
|
||||
if (
|
||||
!ok_response_on_range_request &&
|
||||
xhrStatus !== pendingRequest.expectedStatus
|
||||
) {
|
||||
if (pendingRequest.onError) {
|
||||
pendingRequest.onError(xhr.status);
|
||||
}
|
||||
|
@ -173,7 +179,7 @@ class NetworkManager {
|
|||
|
||||
const chunk = getArrayBuffer(xhr);
|
||||
if (xhrStatus === PARTIAL_CONTENT_RESPONSE) {
|
||||
const rangeHeader = xhr.getResponseHeader('Content-Range');
|
||||
const rangeHeader = xhr.getResponseHeader("Content-Range");
|
||||
const matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader);
|
||||
pendingRequest.onDone({
|
||||
begin: parseInt(matches[1], 10),
|
||||
|
@ -239,14 +245,19 @@ class PDFNetworkStream {
|
|||
|
||||
getFullReader() {
|
||||
assert(!this._fullRequestReader);
|
||||
this._fullRequestReader =
|
||||
new PDFNetworkStreamFullRequestReader(this._manager, this._source);
|
||||
this._fullRequestReader = new PDFNetworkStreamFullRequestReader(
|
||||
this._manager,
|
||||
this._source
|
||||
);
|
||||
return this._fullRequestReader;
|
||||
}
|
||||
|
||||
getRangeReader(begin, end) {
|
||||
const reader = new PDFNetworkStreamRangeRequestReader(this._manager,
|
||||
begin, end);
|
||||
const reader = new PDFNetworkStreamRangeRequestReader(
|
||||
this._manager,
|
||||
begin,
|
||||
end
|
||||
);
|
||||
reader.onClosed = this._onRangeRequestReaderClosed.bind(this);
|
||||
this._rangeRequestReaders.push(reader);
|
||||
return reader;
|
||||
|
@ -300,16 +311,18 @@ class PDFNetworkStreamFullRequestReader {
|
|||
const fullRequestXhrId = this._fullRequestId;
|
||||
const fullRequestXhr = this._manager.getRequestXhr(fullRequestXhrId);
|
||||
|
||||
const getResponseHeader = (name) => {
|
||||
const getResponseHeader = name => {
|
||||
return fullRequestXhr.getResponseHeader(name);
|
||||
};
|
||||
const { allowRangeRequests, suggestedLength, } =
|
||||
validateRangeRequestCapabilities({
|
||||
getResponseHeader,
|
||||
isHttp: this._manager.isHttp,
|
||||
rangeChunkSize: this._rangeChunkSize,
|
||||
disableRange: this._disableRange,
|
||||
});
|
||||
const {
|
||||
allowRangeRequests,
|
||||
suggestedLength,
|
||||
} = validateRangeRequestCapabilities({
|
||||
getResponseHeader,
|
||||
isHttp: this._manager.isHttp,
|
||||
rangeChunkSize: this._rangeChunkSize,
|
||||
disableRange: this._disableRange,
|
||||
});
|
||||
|
||||
if (allowRangeRequests) {
|
||||
this._isRangeSupported = true;
|
||||
|
@ -334,7 +347,7 @@ class PDFNetworkStreamFullRequestReader {
|
|||
if (args) {
|
||||
if (this._requests.length > 0) {
|
||||
const requestCapability = this._requests.shift();
|
||||
requestCapability.resolve({ value: args.chunk, done: false, });
|
||||
requestCapability.resolve({ value: args.chunk, done: false });
|
||||
} else {
|
||||
this._cachedChunks.push(args.chunk);
|
||||
}
|
||||
|
@ -344,7 +357,7 @@ class PDFNetworkStreamFullRequestReader {
|
|||
return;
|
||||
}
|
||||
this._requests.forEach(function(requestCapability) {
|
||||
requestCapability.resolve({ value: undefined, done: true, });
|
||||
requestCapability.resolve({ value: undefined, done: true });
|
||||
});
|
||||
this._requests = [];
|
||||
}
|
||||
|
@ -396,10 +409,10 @@ class PDFNetworkStreamFullRequestReader {
|
|||
}
|
||||
if (this._cachedChunks.length > 0) {
|
||||
const chunk = this._cachedChunks.shift();
|
||||
return { value: chunk, done: false, };
|
||||
return { value: chunk, done: false };
|
||||
}
|
||||
if (this._done) {
|
||||
return { value: undefined, done: true, };
|
||||
return { value: undefined, done: true };
|
||||
}
|
||||
const requestCapability = createPromiseCapability();
|
||||
this._requests.push(requestCapability);
|
||||
|
@ -409,8 +422,8 @@ class PDFNetworkStreamFullRequestReader {
|
|||
cancel(reason) {
|
||||
this._done = true;
|
||||
this._headersReceivedCapability.reject(reason);
|
||||
this._requests.forEach(function (requestCapability) {
|
||||
requestCapability.resolve({ value: undefined, done: true, });
|
||||
this._requests.forEach(function(requestCapability) {
|
||||
requestCapability.resolve({ value: undefined, done: true });
|
||||
});
|
||||
this._requests = [];
|
||||
if (this._manager.isPendingRequest(this._fullRequestId)) {
|
||||
|
@ -447,13 +460,13 @@ class PDFNetworkStreamRangeRequestReader {
|
|||
const chunk = data.chunk;
|
||||
if (this._requests.length > 0) {
|
||||
const requestCapability = this._requests.shift();
|
||||
requestCapability.resolve({ value: chunk, done: false, });
|
||||
requestCapability.resolve({ value: chunk, done: false });
|
||||
} else {
|
||||
this._queuedChunk = chunk;
|
||||
}
|
||||
this._done = true;
|
||||
this._requests.forEach(function(requestCapability) {
|
||||
requestCapability.resolve({ value: undefined, done: true, });
|
||||
requestCapability.resolve({ value: undefined, done: true });
|
||||
});
|
||||
this._requests = [];
|
||||
this._close();
|
||||
|
@ -475,10 +488,10 @@ class PDFNetworkStreamRangeRequestReader {
|
|||
if (this._queuedChunk !== null) {
|
||||
const chunk = this._queuedChunk;
|
||||
this._queuedChunk = null;
|
||||
return { value: chunk, done: false, };
|
||||
return { value: chunk, done: false };
|
||||
}
|
||||
if (this._done) {
|
||||
return { value: undefined, done: true, };
|
||||
return { value: undefined, done: true };
|
||||
}
|
||||
const requestCapability = createPromiseCapability();
|
||||
this._requests.push(requestCapability);
|
||||
|
@ -487,8 +500,8 @@ class PDFNetworkStreamRangeRequestReader {
|
|||
|
||||
cancel(reason) {
|
||||
this._done = true;
|
||||
this._requests.forEach(function (requestCapability) {
|
||||
requestCapability.resolve({ value: undefined, done: true, });
|
||||
this._requests.forEach(function(requestCapability) {
|
||||
requestCapability.resolve({ value: undefined, done: true });
|
||||
});
|
||||
this._requests = [];
|
||||
if (this._manager.isPendingRequest(this._requestId)) {
|
||||
|
@ -498,6 +511,4 @@ class PDFNetworkStreamRangeRequestReader {
|
|||
}
|
||||
}
|
||||
|
||||
export {
|
||||
PDFNetworkStream,
|
||||
};
|
||||
export { PDFNetworkStream };
|
||||
|
|
|
@ -14,21 +14,25 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
assert, MissingPDFException, UnexpectedResponseException
|
||||
} from '../shared/util';
|
||||
import {
|
||||
getFilenameFromContentDispositionHeader
|
||||
} from './content_disposition';
|
||||
assert,
|
||||
MissingPDFException,
|
||||
UnexpectedResponseException,
|
||||
} from "../shared/util";
|
||||
import { getFilenameFromContentDispositionHeader } from "./content_disposition";
|
||||
|
||||
function validateRangeRequestCapabilities({ getResponseHeader, isHttp,
|
||||
rangeChunkSize, disableRange, }) {
|
||||
assert(rangeChunkSize > 0, 'Range chunk size must be larger than zero');
|
||||
function validateRangeRequestCapabilities({
|
||||
getResponseHeader,
|
||||
isHttp,
|
||||
rangeChunkSize,
|
||||
disableRange,
|
||||
}) {
|
||||
assert(rangeChunkSize > 0, "Range chunk size must be larger than zero");
|
||||
let returnValues = {
|
||||
allowRangeRequests: false,
|
||||
suggestedLength: undefined,
|
||||
};
|
||||
|
||||
let length = parseInt(getResponseHeader('Content-Length'), 10);
|
||||
let length = parseInt(getResponseHeader("Content-Length"), 10);
|
||||
if (!Number.isInteger(length)) {
|
||||
return returnValues;
|
||||
}
|
||||
|
@ -44,12 +48,12 @@ function validateRangeRequestCapabilities({ getResponseHeader, isHttp,
|
|||
if (disableRange || !isHttp) {
|
||||
return returnValues;
|
||||
}
|
||||
if (getResponseHeader('Accept-Ranges') !== 'bytes') {
|
||||
if (getResponseHeader("Accept-Ranges") !== "bytes") {
|
||||
return returnValues;
|
||||
}
|
||||
|
||||
let contentEncoding = getResponseHeader('Content-Encoding') || 'identity';
|
||||
if (contentEncoding !== 'identity') {
|
||||
let contentEncoding = getResponseHeader("Content-Encoding") || "identity";
|
||||
if (contentEncoding !== "identity") {
|
||||
return returnValues;
|
||||
}
|
||||
|
||||
|
@ -58,10 +62,10 @@ function validateRangeRequestCapabilities({ getResponseHeader, isHttp,
|
|||
}
|
||||
|
||||
function extractFilenameFromHeader(getResponseHeader) {
|
||||
const contentDisposition = getResponseHeader('Content-Disposition');
|
||||
const contentDisposition = getResponseHeader("Content-Disposition");
|
||||
if (contentDisposition) {
|
||||
let filename = getFilenameFromContentDispositionHeader(contentDisposition);
|
||||
if (filename.includes('%')) {
|
||||
if (filename.includes("%")) {
|
||||
try {
|
||||
filename = decodeURIComponent(filename);
|
||||
} catch (ex) {}
|
||||
|
@ -74,12 +78,17 @@ function extractFilenameFromHeader(getResponseHeader) {
|
|||
}
|
||||
|
||||
function createResponseStatusError(status, url) {
|
||||
if (status === 404 || status === 0 && /^file:/.test(url)) {
|
||||
if (status === 404 || (status === 0 && /^file:/.test(url))) {
|
||||
return new MissingPDFException('Missing PDF "' + url + '".');
|
||||
}
|
||||
return new UnexpectedResponseException(
|
||||
'Unexpected server response (' + status +
|
||||
') while retrieving PDF "' + url + '".', status);
|
||||
"Unexpected server response (" +
|
||||
status +
|
||||
') while retrieving PDF "' +
|
||||
url +
|
||||
'".',
|
||||
status
|
||||
);
|
||||
}
|
||||
|
||||
function validateResponseStatus(status) {
|
||||
|
|
|
@ -14,23 +14,27 @@
|
|||
*/
|
||||
/* globals __non_webpack_require__ */
|
||||
|
||||
let fs = __non_webpack_require__('fs');
|
||||
let http = __non_webpack_require__('http');
|
||||
let https = __non_webpack_require__('https');
|
||||
let url = __non_webpack_require__('url');
|
||||
let fs = __non_webpack_require__("fs");
|
||||
let http = __non_webpack_require__("http");
|
||||
let https = __non_webpack_require__("https");
|
||||
let url = __non_webpack_require__("url");
|
||||
|
||||
import {
|
||||
AbortException, assert, createPromiseCapability, MissingPDFException
|
||||
} from '../shared/util';
|
||||
AbortException,
|
||||
assert,
|
||||
createPromiseCapability,
|
||||
MissingPDFException,
|
||||
} from "../shared/util";
|
||||
import {
|
||||
extractFilenameFromHeader, validateRangeRequestCapabilities
|
||||
} from './network_utils';
|
||||
extractFilenameFromHeader,
|
||||
validateRangeRequestCapabilities,
|
||||
} from "./network_utils";
|
||||
|
||||
const fileUriRegex = /^file:\/\/\/[a-zA-Z]:\//;
|
||||
|
||||
function parseUrl(sourceUrl) {
|
||||
let parsedUrl = url.parse(sourceUrl);
|
||||
if (parsedUrl.protocol === 'file:' || parsedUrl.host) {
|
||||
if (parsedUrl.protocol === "file:" || parsedUrl.host) {
|
||||
return parsedUrl;
|
||||
}
|
||||
// Prepending 'file:///' to Windows absolute path.
|
||||
|
@ -39,7 +43,7 @@ function parseUrl(sourceUrl) {
|
|||
}
|
||||
// Changes protocol to 'file:' if url refers to filesystem.
|
||||
if (!parsedUrl.host) {
|
||||
parsedUrl.protocol = 'file:';
|
||||
parsedUrl.protocol = "file:";
|
||||
}
|
||||
return parsedUrl;
|
||||
}
|
||||
|
@ -48,10 +52,10 @@ class PDFNodeStream {
|
|||
constructor(source) {
|
||||
this.source = source;
|
||||
this.url = parseUrl(source.url);
|
||||
this.isHttp = this.url.protocol === 'http:' ||
|
||||
this.url.protocol === 'https:';
|
||||
this.isHttp =
|
||||
this.url.protocol === "http:" || this.url.protocol === "https:";
|
||||
// Check if url refers to filesystem.
|
||||
this.isFsUrl = this.url.protocol === 'file:';
|
||||
this.isFsUrl = this.url.protocol === "file:";
|
||||
this.httpHeaders = (this.isHttp && source.httpHeaders) || {};
|
||||
|
||||
this._fullRequestReader = null;
|
||||
|
@ -59,14 +63,14 @@ class PDFNodeStream {
|
|||
}
|
||||
|
||||
get _progressiveDataLength() {
|
||||
return (this._fullRequestReader ? this._fullRequestReader._loaded : 0);
|
||||
return this._fullRequestReader ? this._fullRequestReader._loaded : 0;
|
||||
}
|
||||
|
||||
getFullReader() {
|
||||
assert(!this._fullRequestReader);
|
||||
this._fullRequestReader = this.isFsUrl ?
|
||||
new PDFNodeStreamFsFullReader(this) :
|
||||
new PDFNodeStreamFullReader(this);
|
||||
this._fullRequestReader = this.isFsUrl
|
||||
? new PDFNodeStreamFsFullReader(this)
|
||||
: new PDFNodeStreamFullReader(this);
|
||||
return this._fullRequestReader;
|
||||
}
|
||||
|
||||
|
@ -74,9 +78,9 @@ class PDFNodeStream {
|
|||
if (end <= this._progressiveDataLength) {
|
||||
return null;
|
||||
}
|
||||
let rangeReader = this.isFsUrl ?
|
||||
new PDFNodeStreamFsRangeReader(this, start, end) :
|
||||
new PDFNodeStreamRangeReader(this, start, end);
|
||||
let rangeReader = this.isFsUrl
|
||||
? new PDFNodeStreamFsRangeReader(this, start, end)
|
||||
: new PDFNodeStreamRangeReader(this, start, end);
|
||||
this._rangeRequestReaders.push(rangeReader);
|
||||
return rangeReader;
|
||||
}
|
||||
|
@ -141,7 +145,7 @@ class BaseFullReader {
|
|||
async read() {
|
||||
await this._readCapability.promise;
|
||||
if (this._done) {
|
||||
return { value: undefined, done: true, };
|
||||
return { value: undefined, done: true };
|
||||
}
|
||||
if (this._storedError) {
|
||||
throw this._storedError;
|
||||
|
@ -161,7 +165,7 @@ class BaseFullReader {
|
|||
}
|
||||
// Ensure that `read()` method returns ArrayBuffer.
|
||||
let buffer = new Uint8Array(chunk).buffer;
|
||||
return { value: buffer, done: false, };
|
||||
return { value: buffer, done: false };
|
||||
}
|
||||
|
||||
cancel(reason) {
|
||||
|
@ -181,25 +185,25 @@ class BaseFullReader {
|
|||
|
||||
_setReadableStream(readableStream) {
|
||||
this._readableStream = readableStream;
|
||||
readableStream.on('readable', () => {
|
||||
readableStream.on("readable", () => {
|
||||
this._readCapability.resolve();
|
||||
});
|
||||
|
||||
readableStream.on('end', () => {
|
||||
readableStream.on("end", () => {
|
||||
// Destroy readable to minimize resource usage.
|
||||
readableStream.destroy();
|
||||
this._done = true;
|
||||
this._readCapability.resolve();
|
||||
});
|
||||
|
||||
readableStream.on('error', (reason) => {
|
||||
readableStream.on("error", reason => {
|
||||
this._error(reason);
|
||||
});
|
||||
|
||||
// We need to stop reading when range is supported and streaming is
|
||||
// disabled.
|
||||
if (!this._isStreamingSupported && this._isRangeSupported) {
|
||||
this._error(new AbortException('streaming is disabled'));
|
||||
this._error(new AbortException("streaming is disabled"));
|
||||
}
|
||||
|
||||
// Destroy ReadableStream if already in errored state.
|
||||
|
@ -229,7 +233,7 @@ class BaseRangeReader {
|
|||
async read() {
|
||||
await this._readCapability.promise;
|
||||
if (this._done) {
|
||||
return { value: undefined, done: true, };
|
||||
return { value: undefined, done: true };
|
||||
}
|
||||
if (this._storedError) {
|
||||
throw this._storedError;
|
||||
|
@ -242,11 +246,11 @@ class BaseRangeReader {
|
|||
}
|
||||
this._loaded += chunk.length;
|
||||
if (this.onProgress) {
|
||||
this.onProgress({ loaded: this._loaded, });
|
||||
this.onProgress({ loaded: this._loaded });
|
||||
}
|
||||
// Ensure that `read()` method returns ArrayBuffer.
|
||||
let buffer = new Uint8Array(chunk).buffer;
|
||||
return { value: buffer, done: false, };
|
||||
return { value: buffer, done: false };
|
||||
}
|
||||
|
||||
cancel(reason) {
|
||||
|
@ -266,18 +270,18 @@ class BaseRangeReader {
|
|||
|
||||
_setReadableStream(readableStream) {
|
||||
this._readableStream = readableStream;
|
||||
readableStream.on('readable', () => {
|
||||
readableStream.on("readable", () => {
|
||||
this._readCapability.resolve();
|
||||
});
|
||||
|
||||
readableStream.on('end', () => {
|
||||
readableStream.on("end", () => {
|
||||
// Destroy readableStream to minimize resource usage.
|
||||
readableStream.destroy();
|
||||
this._done = true;
|
||||
this._readCapability.resolve();
|
||||
});
|
||||
|
||||
readableStream.on('error', (reason) => {
|
||||
readableStream.on("error", reason => {
|
||||
this._error(reason);
|
||||
});
|
||||
|
||||
|
@ -295,7 +299,7 @@ function createRequestOptions(url, headers) {
|
|||
host: url.hostname,
|
||||
port: url.port,
|
||||
path: url.path,
|
||||
method: 'GET',
|
||||
method: "GET",
|
||||
headers,
|
||||
};
|
||||
}
|
||||
|
@ -304,7 +308,7 @@ class PDFNodeStreamFullReader extends BaseFullReader {
|
|||
constructor(stream) {
|
||||
super(stream);
|
||||
|
||||
let handleResponse = (response) => {
|
||||
let handleResponse = response => {
|
||||
if (response.statusCode === 404) {
|
||||
const error = new MissingPDFException(`Missing PDF "${this._url}".`);
|
||||
this._storedError = error;
|
||||
|
@ -314,18 +318,20 @@ class PDFNodeStreamFullReader extends BaseFullReader {
|
|||
this._headersCapability.resolve();
|
||||
this._setReadableStream(response);
|
||||
|
||||
const getResponseHeader = (name) => {
|
||||
const getResponseHeader = name => {
|
||||
// Make sure that headers name are in lower case, as mentioned
|
||||
// here: https://nodejs.org/api/http.html#http_message_headers.
|
||||
return this._readableStream.headers[name.toLowerCase()];
|
||||
};
|
||||
let { allowRangeRequests, suggestedLength, } =
|
||||
validateRangeRequestCapabilities({
|
||||
getResponseHeader,
|
||||
isHttp: stream.isHttp,
|
||||
rangeChunkSize: this._rangeChunkSize,
|
||||
disableRange: this._disableRange,
|
||||
});
|
||||
let {
|
||||
allowRangeRequests,
|
||||
suggestedLength,
|
||||
} = validateRangeRequestCapabilities({
|
||||
getResponseHeader,
|
||||
isHttp: stream.isHttp,
|
||||
rangeChunkSize: this._rangeChunkSize,
|
||||
disableRange: this._disableRange,
|
||||
});
|
||||
|
||||
this._isRangeSupported = allowRangeRequests;
|
||||
// Setting right content length.
|
||||
|
@ -335,17 +341,19 @@ class PDFNodeStreamFullReader extends BaseFullReader {
|
|||
};
|
||||
|
||||
this._request = null;
|
||||
if (this._url.protocol === 'http:') {
|
||||
if (this._url.protocol === "http:") {
|
||||
this._request = http.request(
|
||||
createRequestOptions(this._url, stream.httpHeaders),
|
||||
handleResponse);
|
||||
handleResponse
|
||||
);
|
||||
} else {
|
||||
this._request = https.request(
|
||||
createRequestOptions(this._url, stream.httpHeaders),
|
||||
handleResponse);
|
||||
handleResponse
|
||||
);
|
||||
}
|
||||
|
||||
this._request.on('error', (reason) => {
|
||||
this._request.on("error", reason => {
|
||||
this._storedError = reason;
|
||||
this._headersCapability.reject(reason);
|
||||
});
|
||||
|
@ -363,14 +371,14 @@ class PDFNodeStreamRangeReader extends BaseRangeReader {
|
|||
this._httpHeaders = {};
|
||||
for (let property in stream.httpHeaders) {
|
||||
let value = stream.httpHeaders[property];
|
||||
if (typeof value === 'undefined') {
|
||||
if (typeof value === "undefined") {
|
||||
continue;
|
||||
}
|
||||
this._httpHeaders[property] = value;
|
||||
}
|
||||
this._httpHeaders['Range'] = `bytes=${start}-${end - 1}`;
|
||||
this._httpHeaders["Range"] = `bytes=${start}-${end - 1}`;
|
||||
|
||||
let handleResponse = (response) => {
|
||||
let handleResponse = response => {
|
||||
if (response.statusCode === 404) {
|
||||
const error = new MissingPDFException(`Missing PDF "${this._url}".`);
|
||||
this._storedError = error;
|
||||
|
@ -380,17 +388,19 @@ class PDFNodeStreamRangeReader extends BaseRangeReader {
|
|||
};
|
||||
|
||||
this._request = null;
|
||||
if (this._url.protocol === 'http:') {
|
||||
if (this._url.protocol === "http:") {
|
||||
this._request = http.request(
|
||||
createRequestOptions(this._url, this._httpHeaders),
|
||||
handleResponse);
|
||||
handleResponse
|
||||
);
|
||||
} else {
|
||||
this._request = https.request(
|
||||
createRequestOptions(this._url, this._httpHeaders),
|
||||
handleResponse);
|
||||
handleResponse
|
||||
);
|
||||
}
|
||||
|
||||
this._request.on('error', (reason) => {
|
||||
this._request.on("error", reason => {
|
||||
this._storedError = reason;
|
||||
});
|
||||
this._request.end();
|
||||
|
@ -405,12 +415,12 @@ class PDFNodeStreamFsFullReader extends BaseFullReader {
|
|||
|
||||
// Remove the extra slash to get right path from url like `file:///C:/`
|
||||
if (fileUriRegex.test(this._url.href)) {
|
||||
path = path.replace(/^\//, '');
|
||||
path = path.replace(/^\//, "");
|
||||
}
|
||||
|
||||
fs.lstat(path, (error, stat) => {
|
||||
if (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
if (error.code === "ENOENT") {
|
||||
error = new MissingPDFException(`Missing PDF "${path}".`);
|
||||
}
|
||||
this._storedError = error;
|
||||
|
@ -434,14 +444,11 @@ class PDFNodeStreamFsRangeReader extends BaseRangeReader {
|
|||
|
||||
// Remove the extra slash to get right path from url like `file:///C:/`
|
||||
if (fileUriRegex.test(this._url.href)) {
|
||||
path = path.replace(/^\//, '');
|
||||
path = path.replace(/^\//, "");
|
||||
}
|
||||
|
||||
this._setReadableStream(
|
||||
fs.createReadStream(path, { start, end: end - 1, }));
|
||||
this._setReadableStream(fs.createReadStream(path, { start, end: end - 1 }));
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
PDFNodeStream,
|
||||
};
|
||||
export { PDFNodeStream };
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FormatError, info, Util } from '../shared/util';
|
||||
import { FormatError, info, Util } from "../shared/util";
|
||||
|
||||
var ShadingIRs = {};
|
||||
|
||||
function applyBoundingBox(ctx, bbox) {
|
||||
if (!bbox || typeof Path2D === 'undefined') {
|
||||
if (!bbox || typeof Path2D === "undefined") {
|
||||
return;
|
||||
}
|
||||
const width = bbox[2] - bbox[0];
|
||||
|
@ -38,13 +38,13 @@ ShadingIRs.RadialAxial = {
|
|||
var r0 = raw[6];
|
||||
var r1 = raw[7];
|
||||
return {
|
||||
type: 'Pattern',
|
||||
type: "Pattern",
|
||||
getPattern: function RadialAxial_getPattern(ctx) {
|
||||
applyBoundingBox(ctx, bbox);
|
||||
var grad;
|
||||
if (type === 'axial') {
|
||||
if (type === "axial") {
|
||||
grad = ctx.createLinearGradient(p0[0], p0[1], p1[0], p1[1]);
|
||||
} else if (type === 'radial') {
|
||||
} else if (type === "radial") {
|
||||
grad = ctx.createRadialGradient(p0[0], p0[1], r0, p1[0], p1[1], r1);
|
||||
}
|
||||
|
||||
|
@ -61,17 +61,34 @@ ShadingIRs.RadialAxial = {
|
|||
var createMeshCanvas = (function createMeshCanvasClosure() {
|
||||
function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) {
|
||||
// Very basic Gouraud-shaded triangle rasterization algorithm.
|
||||
var coords = context.coords, colors = context.colors;
|
||||
var bytes = data.data, rowSize = data.width * 4;
|
||||
var coords = context.coords,
|
||||
colors = context.colors;
|
||||
var bytes = data.data,
|
||||
rowSize = data.width * 4;
|
||||
var tmp;
|
||||
if (coords[p1 + 1] > coords[p2 + 1]) {
|
||||
tmp = p1; p1 = p2; p2 = tmp; tmp = c1; c1 = c2; c2 = tmp;
|
||||
tmp = p1;
|
||||
p1 = p2;
|
||||
p2 = tmp;
|
||||
tmp = c1;
|
||||
c1 = c2;
|
||||
c2 = tmp;
|
||||
}
|
||||
if (coords[p2 + 1] > coords[p3 + 1]) {
|
||||
tmp = p2; p2 = p3; p3 = tmp; tmp = c2; c2 = c3; c3 = tmp;
|
||||
tmp = p2;
|
||||
p2 = p3;
|
||||
p3 = tmp;
|
||||
tmp = c2;
|
||||
c2 = c3;
|
||||
c3 = tmp;
|
||||
}
|
||||
if (coords[p1 + 1] > coords[p2 + 1]) {
|
||||
tmp = p1; p1 = p2; p2 = tmp; tmp = c1; c1 = c2; c2 = tmp;
|
||||
tmp = p1;
|
||||
p1 = p2;
|
||||
p2 = tmp;
|
||||
tmp = c1;
|
||||
c1 = c2;
|
||||
c2 = tmp;
|
||||
}
|
||||
var x1 = (coords[p1] + context.offsetX) * context.scaleX;
|
||||
var y1 = (coords[p1 + 1] + context.offsetY) * context.scaleY;
|
||||
|
@ -82,11 +99,18 @@ var createMeshCanvas = (function createMeshCanvasClosure() {
|
|||
if (y1 >= y3) {
|
||||
return;
|
||||
}
|
||||
var c1r = colors[c1], c1g = colors[c1 + 1], c1b = colors[c1 + 2];
|
||||
var c2r = colors[c2], c2g = colors[c2 + 1], c2b = colors[c2 + 2];
|
||||
var c3r = colors[c3], c3g = colors[c3 + 1], c3b = colors[c3 + 2];
|
||||
var c1r = colors[c1],
|
||||
c1g = colors[c1 + 1],
|
||||
c1b = colors[c1 + 2];
|
||||
var c2r = colors[c2],
|
||||
c2g = colors[c2 + 1],
|
||||
c2b = colors[c2 + 2];
|
||||
var c3r = colors[c3],
|
||||
c3g = colors[c3 + 1],
|
||||
c3b = colors[c3 + 2];
|
||||
|
||||
var minY = Math.round(y1), maxY = Math.round(y3);
|
||||
var minY = Math.round(y1),
|
||||
maxY = Math.round(y3);
|
||||
var xa, car, cag, cab;
|
||||
var xb, cbr, cbg, cbb;
|
||||
var k;
|
||||
|
@ -128,36 +152,65 @@ var createMeshCanvas = (function createMeshCanvasClosure() {
|
|||
var cs = figure.colors;
|
||||
var i, ii;
|
||||
switch (figure.type) {
|
||||
case 'lattice':
|
||||
case "lattice":
|
||||
var verticesPerRow = figure.verticesPerRow;
|
||||
var rows = Math.floor(ps.length / verticesPerRow) - 1;
|
||||
var cols = verticesPerRow - 1;
|
||||
for (i = 0; i < rows; i++) {
|
||||
var q = i * verticesPerRow;
|
||||
for (var j = 0; j < cols; j++, q++) {
|
||||
drawTriangle(data, context,
|
||||
ps[q], ps[q + 1], ps[q + verticesPerRow],
|
||||
cs[q], cs[q + 1], cs[q + verticesPerRow]);
|
||||
drawTriangle(data, context,
|
||||
ps[q + verticesPerRow + 1], ps[q + 1], ps[q + verticesPerRow],
|
||||
cs[q + verticesPerRow + 1], cs[q + 1], cs[q + verticesPerRow]);
|
||||
drawTriangle(
|
||||
data,
|
||||
context,
|
||||
ps[q],
|
||||
ps[q + 1],
|
||||
ps[q + verticesPerRow],
|
||||
cs[q],
|
||||
cs[q + 1],
|
||||
cs[q + verticesPerRow]
|
||||
);
|
||||
drawTriangle(
|
||||
data,
|
||||
context,
|
||||
ps[q + verticesPerRow + 1],
|
||||
ps[q + 1],
|
||||
ps[q + verticesPerRow],
|
||||
cs[q + verticesPerRow + 1],
|
||||
cs[q + 1],
|
||||
cs[q + verticesPerRow]
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'triangles':
|
||||
case "triangles":
|
||||
for (i = 0, ii = ps.length; i < ii; i += 3) {
|
||||
drawTriangle(data, context,
|
||||
ps[i], ps[i + 1], ps[i + 2],
|
||||
cs[i], cs[i + 1], cs[i + 2]);
|
||||
drawTriangle(
|
||||
data,
|
||||
context,
|
||||
ps[i],
|
||||
ps[i + 1],
|
||||
ps[i + 2],
|
||||
cs[i],
|
||||
cs[i + 1],
|
||||
cs[i + 2]
|
||||
);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error('illegal figure');
|
||||
throw new Error("illegal figure");
|
||||
}
|
||||
}
|
||||
|
||||
function createMeshCanvas(bounds, combinesScale, coords, colors, figures,
|
||||
backgroundColor, cachedCanvases, webGLContext) {
|
||||
function createMeshCanvas(
|
||||
bounds,
|
||||
combinesScale,
|
||||
coords,
|
||||
colors,
|
||||
figures,
|
||||
backgroundColor,
|
||||
cachedCanvases,
|
||||
webGLContext
|
||||
) {
|
||||
// we will increase scale on some weird factor to let antialiasing take
|
||||
// care of "rough" edges
|
||||
var EXPECTED_SCALE = 1.1;
|
||||
|
@ -172,10 +225,14 @@ var createMeshCanvas = (function createMeshCanvasClosure() {
|
|||
var boundsWidth = Math.ceil(bounds[2]) - offsetX;
|
||||
var boundsHeight = Math.ceil(bounds[3]) - offsetY;
|
||||
|
||||
var width = Math.min(Math.ceil(Math.abs(boundsWidth * combinesScale[0] *
|
||||
EXPECTED_SCALE)), MAX_PATTERN_SIZE);
|
||||
var height = Math.min(Math.ceil(Math.abs(boundsHeight * combinesScale[1] *
|
||||
EXPECTED_SCALE)), MAX_PATTERN_SIZE);
|
||||
var width = Math.min(
|
||||
Math.ceil(Math.abs(boundsWidth * combinesScale[0] * EXPECTED_SCALE)),
|
||||
MAX_PATTERN_SIZE
|
||||
);
|
||||
var height = Math.min(
|
||||
Math.ceil(Math.abs(boundsHeight * combinesScale[1] * EXPECTED_SCALE)),
|
||||
MAX_PATTERN_SIZE
|
||||
);
|
||||
var scaleX = boundsWidth / width;
|
||||
var scaleY = boundsHeight / height;
|
||||
|
||||
|
@ -201,13 +258,21 @@ var createMeshCanvas = (function createMeshCanvasClosure() {
|
|||
context,
|
||||
});
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=972126
|
||||
tmpCanvas = cachedCanvases.getCanvas('mesh', paddedWidth, paddedHeight,
|
||||
false);
|
||||
tmpCanvas = cachedCanvases.getCanvas(
|
||||
"mesh",
|
||||
paddedWidth,
|
||||
paddedHeight,
|
||||
false
|
||||
);
|
||||
tmpCanvas.context.drawImage(canvas, BORDER_SIZE, BORDER_SIZE);
|
||||
canvas = tmpCanvas.canvas;
|
||||
} else {
|
||||
tmpCanvas = cachedCanvases.getCanvas('mesh', paddedWidth, paddedHeight,
|
||||
false);
|
||||
tmpCanvas = cachedCanvases.getCanvas(
|
||||
"mesh",
|
||||
paddedWidth,
|
||||
paddedHeight,
|
||||
false
|
||||
);
|
||||
var tmpCtx = tmpCanvas.context;
|
||||
|
||||
var data = tmpCtx.createImageData(width, height);
|
||||
|
@ -249,7 +314,7 @@ ShadingIRs.Mesh = {
|
|||
var bbox = raw[7];
|
||||
var background = raw[8];
|
||||
return {
|
||||
type: 'Pattern',
|
||||
type: "Pattern",
|
||||
getPattern: function Mesh_getPattern(ctx, owner, shadingFill) {
|
||||
applyBoundingBox(ctx, bbox);
|
||||
var scale;
|
||||
|
@ -260,16 +325,22 @@ ShadingIRs.Mesh = {
|
|||
scale = Util.singularValueDecompose2dScale(owner.baseTransform);
|
||||
if (matrix) {
|
||||
var matrixScale = Util.singularValueDecompose2dScale(matrix);
|
||||
scale = [scale[0] * matrixScale[0],
|
||||
scale[1] * matrixScale[1]];
|
||||
scale = [scale[0] * matrixScale[0], scale[1] * matrixScale[1]];
|
||||
}
|
||||
}
|
||||
|
||||
// Rasterizing on the main thread since sending/queue large canvases
|
||||
// might cause OOM.
|
||||
var temporaryPatternCanvas = createMeshCanvas(bounds, scale, coords,
|
||||
colors, figures, shadingFill ? null : background,
|
||||
owner.cachedCanvases, owner.webGLContext);
|
||||
var temporaryPatternCanvas = createMeshCanvas(
|
||||
bounds,
|
||||
scale,
|
||||
coords,
|
||||
colors,
|
||||
figures,
|
||||
shadingFill ? null : background,
|
||||
owner.cachedCanvases,
|
||||
owner.webGLContext
|
||||
);
|
||||
|
||||
if (!shadingFill) {
|
||||
ctx.setTransform.apply(ctx, owner.baseTransform);
|
||||
|
@ -278,12 +349,13 @@ ShadingIRs.Mesh = {
|
|||
}
|
||||
}
|
||||
|
||||
ctx.translate(temporaryPatternCanvas.offsetX,
|
||||
temporaryPatternCanvas.offsetY);
|
||||
ctx.scale(temporaryPatternCanvas.scaleX,
|
||||
temporaryPatternCanvas.scaleY);
|
||||
ctx.translate(
|
||||
temporaryPatternCanvas.offsetX,
|
||||
temporaryPatternCanvas.offsetY
|
||||
);
|
||||
ctx.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY);
|
||||
|
||||
return ctx.createPattern(temporaryPatternCanvas.canvas, 'no-repeat');
|
||||
return ctx.createPattern(temporaryPatternCanvas.canvas, "no-repeat");
|
||||
},
|
||||
};
|
||||
},
|
||||
|
@ -292,9 +364,9 @@ ShadingIRs.Mesh = {
|
|||
ShadingIRs.Dummy = {
|
||||
fromIR: function Dummy_fromIR() {
|
||||
return {
|
||||
type: 'Pattern',
|
||||
type: "Pattern",
|
||||
getPattern: function Dummy_fromIR_getPattern() {
|
||||
return 'hotpink';
|
||||
return "hotpink";
|
||||
},
|
||||
};
|
||||
},
|
||||
|
@ -327,7 +399,7 @@ var TilingPattern = (function TilingPatternClosure() {
|
|||
this.color = color;
|
||||
this.canvasGraphicsFactory = canvasGraphicsFactory;
|
||||
this.baseTransform = baseTransform;
|
||||
this.type = 'Pattern';
|
||||
this.type = "Pattern";
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
|
@ -342,7 +414,7 @@ var TilingPattern = (function TilingPatternClosure() {
|
|||
var color = this.color;
|
||||
var canvasGraphicsFactory = this.canvasGraphicsFactory;
|
||||
|
||||
info('TilingType: ' + tilingType);
|
||||
info("TilingType: " + tilingType);
|
||||
|
||||
// A tiling pattern as defined by PDF spec 8.7.2 is a cell whose size is
|
||||
// described by bbox, and may repeat regularly by shifting the cell by
|
||||
|
@ -364,25 +436,41 @@ var TilingPattern = (function TilingPatternClosure() {
|
|||
// TODO: Fix the implementation, to allow this scenario to be painted
|
||||
// correctly.
|
||||
|
||||
var x0 = bbox[0], y0 = bbox[1], x1 = bbox[2], y1 = bbox[3];
|
||||
var x0 = bbox[0],
|
||||
y0 = bbox[1],
|
||||
x1 = bbox[2],
|
||||
y1 = bbox[3];
|
||||
|
||||
// Obtain scale from matrix and current transformation matrix.
|
||||
var matrixScale = Util.singularValueDecompose2dScale(this.matrix);
|
||||
var curMatrixScale = Util.singularValueDecompose2dScale(
|
||||
this.baseTransform);
|
||||
var combinedScale = [matrixScale[0] * curMatrixScale[0],
|
||||
matrixScale[1] * curMatrixScale[1]];
|
||||
this.baseTransform
|
||||
);
|
||||
var combinedScale = [
|
||||
matrixScale[0] * curMatrixScale[0],
|
||||
matrixScale[1] * curMatrixScale[1],
|
||||
];
|
||||
|
||||
// Use width and height values that are as close as possible to the end
|
||||
// result when the pattern is used. Too low value makes the pattern look
|
||||
// blurry. Too large value makes it look too crispy.
|
||||
var dimx = this.getSizeAndScale(xstep, this.ctx.canvas.width,
|
||||
combinedScale[0]);
|
||||
var dimy = this.getSizeAndScale(ystep, this.ctx.canvas.height,
|
||||
combinedScale[1]);
|
||||
var dimx = this.getSizeAndScale(
|
||||
xstep,
|
||||
this.ctx.canvas.width,
|
||||
combinedScale[0]
|
||||
);
|
||||
var dimy = this.getSizeAndScale(
|
||||
ystep,
|
||||
this.ctx.canvas.height,
|
||||
combinedScale[1]
|
||||
);
|
||||
|
||||
var tmpCanvas = owner.cachedCanvases.getCanvas('pattern',
|
||||
dimx.size, dimy.size, true);
|
||||
var tmpCanvas = owner.cachedCanvases.getCanvas(
|
||||
"pattern",
|
||||
dimx.size,
|
||||
dimy.size,
|
||||
true
|
||||
);
|
||||
var tmpCtx = tmpCanvas.context;
|
||||
var graphics = canvasGraphicsFactory.createCanvasGraphics(tmpCtx);
|
||||
graphics.groupLevel = owner.groupLevel;
|
||||
|
@ -406,8 +494,11 @@ var TilingPattern = (function TilingPatternClosure() {
|
|||
return tmpCanvas.canvas;
|
||||
},
|
||||
|
||||
getSizeAndScale:
|
||||
function TilingPattern_getSizeAndScale(step, realOutputSize, scale) {
|
||||
getSizeAndScale: function TilingPattern_getSizeAndScale(
|
||||
step,
|
||||
realOutputSize,
|
||||
scale
|
||||
) {
|
||||
// xstep / ystep may be negative -- normalize.
|
||||
step = Math.abs(step);
|
||||
// MAX_PATTERN_SIZE is used to avoid OOM situation.
|
||||
|
@ -421,7 +512,7 @@ var TilingPattern = (function TilingPatternClosure() {
|
|||
} else {
|
||||
scale = size / step;
|
||||
}
|
||||
return { scale, size, };
|
||||
return { scale, size };
|
||||
},
|
||||
|
||||
clipBbox: function clipBbox(graphics, bbox, x0, y0, x1, y1) {
|
||||
|
@ -434,29 +525,33 @@ var TilingPattern = (function TilingPatternClosure() {
|
|||
}
|
||||
},
|
||||
|
||||
setFillAndStrokeStyleToContext:
|
||||
function setFillAndStrokeStyleToContext(graphics, paintType, color) {
|
||||
let context = graphics.ctx, current = graphics.current;
|
||||
switch (paintType) {
|
||||
case PaintType.COLORED:
|
||||
var ctx = this.ctx;
|
||||
context.fillStyle = ctx.fillStyle;
|
||||
context.strokeStyle = ctx.strokeStyle;
|
||||
current.fillColor = ctx.fillStyle;
|
||||
current.strokeColor = ctx.strokeStyle;
|
||||
break;
|
||||
case PaintType.UNCOLORED:
|
||||
var cssColor = Util.makeCssRgb(color[0], color[1], color[2]);
|
||||
context.fillStyle = cssColor;
|
||||
context.strokeStyle = cssColor;
|
||||
// Set color needed by image masks (fixes issues 3226 and 8741).
|
||||
current.fillColor = cssColor;
|
||||
current.strokeColor = cssColor;
|
||||
break;
|
||||
default:
|
||||
throw new FormatError(`Unsupported paint type: ${paintType}`);
|
||||
}
|
||||
},
|
||||
setFillAndStrokeStyleToContext: function setFillAndStrokeStyleToContext(
|
||||
graphics,
|
||||
paintType,
|
||||
color
|
||||
) {
|
||||
let context = graphics.ctx,
|
||||
current = graphics.current;
|
||||
switch (paintType) {
|
||||
case PaintType.COLORED:
|
||||
var ctx = this.ctx;
|
||||
context.fillStyle = ctx.fillStyle;
|
||||
context.strokeStyle = ctx.strokeStyle;
|
||||
current.fillColor = ctx.fillStyle;
|
||||
current.strokeColor = ctx.strokeStyle;
|
||||
break;
|
||||
case PaintType.UNCOLORED:
|
||||
var cssColor = Util.makeCssRgb(color[0], color[1], color[2]);
|
||||
context.fillStyle = cssColor;
|
||||
context.strokeStyle = cssColor;
|
||||
// Set color needed by image masks (fixes issues 3226 and 8741).
|
||||
current.fillColor = cssColor;
|
||||
current.strokeColor = cssColor;
|
||||
break;
|
||||
default:
|
||||
throw new FormatError(`Unsupported paint type: ${paintType}`);
|
||||
}
|
||||
},
|
||||
|
||||
getPattern: function TilingPattern_getPattern(ctx, owner) {
|
||||
ctx = this.ctx;
|
||||
|
@ -466,14 +561,11 @@ var TilingPattern = (function TilingPatternClosure() {
|
|||
|
||||
var temporaryPatternCanvas = this.createPatternCanvas(owner);
|
||||
|
||||
return ctx.createPattern(temporaryPatternCanvas, 'repeat');
|
||||
return ctx.createPattern(temporaryPatternCanvas, "repeat");
|
||||
},
|
||||
};
|
||||
|
||||
return TilingPattern;
|
||||
})();
|
||||
|
||||
export {
|
||||
getShadingPatternFromIR,
|
||||
TilingPattern,
|
||||
};
|
||||
export { getShadingPatternFromIR, TilingPattern };
|
||||
|
|
2978
src/display/svg.js
2978
src/display/svg.js
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AbortException, createPromiseCapability, Util } from '../shared/util';
|
||||
import { AbortException, createPromiseCapability, Util } from "../shared/util";
|
||||
|
||||
/**
|
||||
* Text layer render parameters.
|
||||
|
@ -48,7 +48,7 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
|
||||
function appendText(task, geom, styles) {
|
||||
// Initialize all used properties to keep the caches monomorphic.
|
||||
var textDiv = document.createElement('span');
|
||||
var textDiv = document.createElement("span");
|
||||
var textDivProperties = {
|
||||
angle: 0,
|
||||
canvasWidth: 0,
|
||||
|
@ -74,7 +74,7 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
if (style.vertical) {
|
||||
angle += Math.PI / 2;
|
||||
}
|
||||
var fontHeight = Math.sqrt((tx[2] * tx[2]) + (tx[3] * tx[3]));
|
||||
var fontHeight = Math.sqrt(tx[2] * tx[2] + tx[3] * tx[3]);
|
||||
var fontAscent = fontHeight;
|
||||
if (style.ascent) {
|
||||
fontAscent = style.ascent * fontAscent;
|
||||
|
@ -87,8 +87,8 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
left = tx[4];
|
||||
top = tx[5] - fontAscent;
|
||||
} else {
|
||||
left = tx[4] + (fontAscent * Math.sin(angle));
|
||||
top = tx[5] - (fontAscent * Math.cos(angle));
|
||||
left = tx[4] + fontAscent * Math.sin(angle);
|
||||
top = tx[5] - fontAscent * Math.cos(angle);
|
||||
}
|
||||
// Setting the style properties individually, rather than all at once,
|
||||
// should be OK since the `textDiv` isn't appended to the document yet.
|
||||
|
@ -122,13 +122,14 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
}
|
||||
|
||||
if (task._enhanceTextSelection) {
|
||||
var angleCos = 1, angleSin = 0;
|
||||
var angleCos = 1,
|
||||
angleSin = 0;
|
||||
if (angle !== 0) {
|
||||
angleCos = Math.cos(angle);
|
||||
angleSin = Math.sin(angle);
|
||||
}
|
||||
var divWidth = (style.vertical ? geom.height : geom.width) *
|
||||
task._viewport.scale;
|
||||
var divWidth =
|
||||
(style.vertical ? geom.height : geom.width) * task._viewport.scale;
|
||||
var divHeight = fontHeight;
|
||||
|
||||
var m, b;
|
||||
|
@ -195,12 +196,15 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
}
|
||||
// Box is rotated -- trying to find padding so rotated div will not
|
||||
// exceed its expanded bounds.
|
||||
var e = expanded[i], b = bounds[i];
|
||||
var m = b.m, c = m[0], s = m[1];
|
||||
var e = expanded[i],
|
||||
b = bounds[i];
|
||||
var m = b.m,
|
||||
c = m[0],
|
||||
s = m[1];
|
||||
// Finding intersections with expanded box.
|
||||
var points = [[0, 0], [0, b.size[1]], [b.size[0], 0], b.size];
|
||||
var ts = new Float64Array(64);
|
||||
points.forEach(function (p, i) {
|
||||
points.forEach(function(p, i) {
|
||||
var t = Util.applyTransform(p, m);
|
||||
ts[i + 0] = c && (e.left - t[0]) / c;
|
||||
ts[i + 4] = s && (e.top - t[1]) / s;
|
||||
|
@ -222,7 +226,7 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
ts[i + 56] = s && (e.right - t[0]) / s;
|
||||
ts[i + 60] = c && (e.bottom - t[1]) / -c;
|
||||
});
|
||||
var findPositiveMin = function (ts, offset, count) {
|
||||
var findPositiveMin = function(ts, offset, count) {
|
||||
var result = 0;
|
||||
for (var i = 0; i < count; i++) {
|
||||
var t = ts[offset++];
|
||||
|
@ -244,7 +248,7 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
}
|
||||
|
||||
function expandBounds(width, height, boxes) {
|
||||
var bounds = boxes.map(function (box, i) {
|
||||
var bounds = boxes.map(function(box, i) {
|
||||
return {
|
||||
x1: box.left,
|
||||
y1: box.top,
|
||||
|
@ -257,7 +261,7 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
});
|
||||
expandBoundsLTR(width, bounds);
|
||||
var expanded = new Array(boxes.length);
|
||||
bounds.forEach(function (b) {
|
||||
bounds.forEach(function(b) {
|
||||
var i = b.index;
|
||||
expanded[i] = {
|
||||
left: b.x1New,
|
||||
|
@ -269,8 +273,9 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
|
||||
// Rotating on 90 degrees and extending extended boxes. Reusing the bounds
|
||||
// array and objects.
|
||||
boxes.map(function (box, i) {
|
||||
var e = expanded[i], b = bounds[i];
|
||||
boxes.map(function(box, i) {
|
||||
var e = expanded[i],
|
||||
b = bounds[i];
|
||||
b.x1 = box.top;
|
||||
b.y1 = width - e.right;
|
||||
b.x2 = box.bottom;
|
||||
|
@ -281,7 +286,7 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
});
|
||||
expandBoundsLTR(height, bounds);
|
||||
|
||||
bounds.forEach(function (b) {
|
||||
bounds.forEach(function(b) {
|
||||
var i = b.index;
|
||||
expanded[i].top = b.x1New;
|
||||
expanded[i].bottom = b.x2New;
|
||||
|
@ -291,7 +296,7 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
|
||||
function expandBoundsLTR(width, bounds) {
|
||||
// Sorting by x1 coordinate and walk by the bounds in the same order.
|
||||
bounds.sort(function (a, b) {
|
||||
bounds.sort(function(a, b) {
|
||||
return a.x1 - b.x1 || a.index - b.index;
|
||||
});
|
||||
|
||||
|
@ -305,13 +310,15 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
x1New: 0,
|
||||
x2New: 0,
|
||||
};
|
||||
var horizon = [{
|
||||
start: -Infinity,
|
||||
end: Infinity,
|
||||
boundary: fakeBoundary,
|
||||
}];
|
||||
var horizon = [
|
||||
{
|
||||
start: -Infinity,
|
||||
end: Infinity,
|
||||
boundary: fakeBoundary,
|
||||
},
|
||||
];
|
||||
|
||||
bounds.forEach(function (boundary) {
|
||||
bounds.forEach(function(boundary) {
|
||||
// Searching for the affected part of horizon.
|
||||
// TODO red-black tree or simple binary search
|
||||
var i = 0;
|
||||
|
@ -324,7 +331,9 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
}
|
||||
|
||||
var horizonPart, affectedBoundary;
|
||||
var q, k, maxXNew = -Infinity;
|
||||
var q,
|
||||
k,
|
||||
maxXNew = -Infinity;
|
||||
for (q = i; q <= j; q++) {
|
||||
horizonPart = horizon[q];
|
||||
affectedBoundary = horizonPart.boundary;
|
||||
|
@ -333,8 +342,10 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
// In the middle of the previous element, new x shall be at the
|
||||
// boundary start. Extending if further if the affected boundary
|
||||
// placed on top of the current one.
|
||||
xNew = affectedBoundary.index > boundary.index ?
|
||||
affectedBoundary.x1New : boundary.x1;
|
||||
xNew =
|
||||
affectedBoundary.index > boundary.index
|
||||
? affectedBoundary.x1New
|
||||
: boundary.x1;
|
||||
} else if (affectedBoundary.x2New === undefined) {
|
||||
// We have some space in between, new x in middle will be a fair
|
||||
// choice.
|
||||
|
@ -373,13 +384,14 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
}
|
||||
|
||||
// Fixing the horizon.
|
||||
var changedHorizon = [], lastBoundary = null;
|
||||
var changedHorizon = [],
|
||||
lastBoundary = null;
|
||||
for (q = i; q <= j; q++) {
|
||||
horizonPart = horizon[q];
|
||||
affectedBoundary = horizonPart.boundary;
|
||||
// Checking which boundary will be visible.
|
||||
var useBoundary = affectedBoundary.x2 > boundary.x2 ?
|
||||
affectedBoundary : boundary;
|
||||
var useBoundary =
|
||||
affectedBoundary.x2 > boundary.x2 ? affectedBoundary : boundary;
|
||||
if (lastBoundary === useBoundary) {
|
||||
// Merging with previous.
|
||||
changedHorizon[changedHorizon.length - 1].end = horizonPart.end;
|
||||
|
@ -419,12 +431,18 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
continue;
|
||||
}
|
||||
var used = false;
|
||||
for (k = i - 1; !used && k >= 0 &&
|
||||
horizon[k].start >= affectedBoundary.y1; k--) {
|
||||
for (
|
||||
k = i - 1;
|
||||
!used && k >= 0 && horizon[k].start >= affectedBoundary.y1;
|
||||
k--
|
||||
) {
|
||||
used = horizon[k].boundary === affectedBoundary;
|
||||
}
|
||||
for (k = j + 1; !used && k < horizon.length &&
|
||||
horizon[k].end <= affectedBoundary.y2; k++) {
|
||||
for (
|
||||
k = j + 1;
|
||||
!used && k < horizon.length && horizon[k].end <= affectedBoundary.y2;
|
||||
k++
|
||||
) {
|
||||
used = horizon[k].boundary === affectedBoundary;
|
||||
}
|
||||
for (k = 0; !used && k < changedHorizon.length; k++) {
|
||||
|
@ -435,12 +453,14 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
}
|
||||
}
|
||||
|
||||
Array.prototype.splice.apply(horizon,
|
||||
[i, j - i + 1].concat(changedHorizon));
|
||||
Array.prototype.splice.apply(
|
||||
horizon,
|
||||
[i, j - i + 1].concat(changedHorizon)
|
||||
);
|
||||
});
|
||||
|
||||
// Set new x2 for all unset boundaries.
|
||||
horizon.forEach(function (horizonPart) {
|
||||
horizon.forEach(function(horizonPart) {
|
||||
var affectedBoundary = horizonPart.boundary;
|
||||
if (affectedBoundary.x2New === undefined) {
|
||||
affectedBoundary.x2New = Math.max(width, affectedBoundary.x2);
|
||||
|
@ -458,9 +478,15 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
* @param {boolean} enhanceTextSelection
|
||||
* @private
|
||||
*/
|
||||
function TextLayerRenderTask({ textContent, textContentStream, container,
|
||||
viewport, textDivs, textContentItemsStr,
|
||||
enhanceTextSelection, }) {
|
||||
function TextLayerRenderTask({
|
||||
textContent,
|
||||
textContentStream,
|
||||
container,
|
||||
viewport,
|
||||
textDivs,
|
||||
textContentItemsStr,
|
||||
enhanceTextSelection,
|
||||
}) {
|
||||
this._textContent = textContent;
|
||||
this._textContentStream = textContentStream;
|
||||
this._container = container;
|
||||
|
@ -468,8 +494,9 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
this._textDivs = textDivs || [];
|
||||
this._textContentItemsStr = textContentItemsStr || [];
|
||||
this._enhanceTextSelection = !!enhanceTextSelection;
|
||||
this._fontInspectorEnabled = !!(globalThis.FontInspector &&
|
||||
globalThis.FontInspector.enabled);
|
||||
this._fontInspectorEnabled = !!(
|
||||
globalThis.FontInspector && globalThis.FontInspector.enabled
|
||||
);
|
||||
|
||||
this._reader = null;
|
||||
this._layoutTextLastFontSize = null;
|
||||
|
@ -483,15 +510,19 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
this._bounds = [];
|
||||
|
||||
// Always clean-up the temporary canvas once rendering is no longer pending.
|
||||
this._capability.promise.finally(() => {
|
||||
if (this._layoutTextCtx) {
|
||||
// Zeroing the width and height cause Firefox to release graphics
|
||||
// resources immediately, which can greatly reduce memory consumption.
|
||||
this._layoutTextCtx.canvas.width = 0;
|
||||
this._layoutTextCtx.canvas.height = 0;
|
||||
this._layoutTextCtx = null;
|
||||
}
|
||||
}).catch(() => { /* Avoid "Uncaught promise" messages in the console. */ });
|
||||
this._capability.promise
|
||||
.finally(() => {
|
||||
if (this._layoutTextCtx) {
|
||||
// Zeroing the width and height cause Firefox to release graphics
|
||||
// resources immediately, which can greatly reduce memory consumption.
|
||||
this._layoutTextCtx.canvas.width = 0;
|
||||
this._layoutTextCtx.canvas.height = 0;
|
||||
this._layoutTextCtx = null;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
/* Avoid "Uncaught promise" messages in the console. */
|
||||
});
|
||||
}
|
||||
TextLayerRenderTask.prototype = {
|
||||
get promise() {
|
||||
|
@ -501,14 +532,14 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
cancel: function TextLayer_cancel() {
|
||||
this._canceled = true;
|
||||
if (this._reader) {
|
||||
this._reader.cancel(new AbortException('TextLayer task cancelled.'));
|
||||
this._reader.cancel(new AbortException("TextLayer task cancelled."));
|
||||
this._reader = null;
|
||||
}
|
||||
if (this._renderTimer !== null) {
|
||||
clearTimeout(this._renderTimer);
|
||||
this._renderTimer = null;
|
||||
}
|
||||
this._capability.reject(new Error('TextLayer task cancelled.'));
|
||||
this._capability.reject(new Error("TextLayer task cancelled."));
|
||||
},
|
||||
|
||||
_processItems(items, styleCache) {
|
||||
|
@ -524,19 +555,21 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
return;
|
||||
}
|
||||
|
||||
let transform = '';
|
||||
let transform = "";
|
||||
if (textDivProperties.canvasWidth !== 0) {
|
||||
const { fontSize, fontFamily, } = textDiv.style;
|
||||
const { fontSize, fontFamily } = textDiv.style;
|
||||
|
||||
// Only build font string and set to context if different from last.
|
||||
if (fontSize !== this._layoutTextLastFontSize ||
|
||||
fontFamily !== this._layoutTextLastFontFamily) {
|
||||
if (
|
||||
fontSize !== this._layoutTextLastFontSize ||
|
||||
fontFamily !== this._layoutTextLastFontFamily
|
||||
) {
|
||||
this._layoutTextCtx.font = `${fontSize} ${fontFamily}`;
|
||||
this._layoutTextLastFontSize = fontSize;
|
||||
this._layoutTextLastFontFamily = fontFamily;
|
||||
}
|
||||
// Only measure the width for multi-char text divs, see `appendText`.
|
||||
const { width, } = this._layoutTextCtx.measureText(textDiv.textContent);
|
||||
const { width } = this._layoutTextCtx.measureText(textDiv.textContent);
|
||||
|
||||
if (width > 0) {
|
||||
textDivProperties.scale = textDivProperties.canvasWidth / width;
|
||||
|
@ -561,12 +594,14 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
let styleCache = Object.create(null);
|
||||
|
||||
// The temporary canvas is used to measure text length in the DOM.
|
||||
let canvas = document.createElement('canvas');
|
||||
if (typeof PDFJSDev === 'undefined' ||
|
||||
PDFJSDev.test('FIREFOX || MOZCENTRAL || GENERIC')) {
|
||||
canvas.mozOpaque = true;
|
||||
let canvas = document.createElement("canvas");
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("FIREFOX || MOZCENTRAL || GENERIC")
|
||||
) {
|
||||
canvas.mozOpaque = true;
|
||||
}
|
||||
this._layoutTextCtx = canvas.getContext('2d', { alpha: false, });
|
||||
this._layoutTextCtx = canvas.getContext("2d", { alpha: false });
|
||||
|
||||
if (this._textContent) {
|
||||
let textItems = this._textContent.items;
|
||||
|
@ -575,7 +610,7 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
capability.resolve();
|
||||
} else if (this._textContentStream) {
|
||||
let pump = () => {
|
||||
this._reader.read().then(({ value, done, }) => {
|
||||
this._reader.read().then(({ value, done }) => {
|
||||
if (done) {
|
||||
capability.resolve();
|
||||
return;
|
||||
|
@ -590,15 +625,19 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
this._reader = this._textContentStream.getReader();
|
||||
pump();
|
||||
} else {
|
||||
throw new Error('Neither "textContent" nor "textContentStream"' +
|
||||
' parameters specified.');
|
||||
throw new Error(
|
||||
'Neither "textContent" nor "textContentStream"' +
|
||||
" parameters specified."
|
||||
);
|
||||
}
|
||||
|
||||
capability.promise.then(() => {
|
||||
styleCache = null;
|
||||
if (!timeout) { // Render right away
|
||||
if (!timeout) {
|
||||
// Render right away
|
||||
render(this);
|
||||
} else { // Schedule
|
||||
} else {
|
||||
// Schedule
|
||||
this._renderTimer = setTimeout(() => {
|
||||
render(this);
|
||||
this._renderTimer = null;
|
||||
|
@ -615,8 +654,9 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
expand(this);
|
||||
this._bounds = null;
|
||||
}
|
||||
const NO_PADDING = '0 0 0 0';
|
||||
const transformBuf = [], paddingBuf = [];
|
||||
const NO_PADDING = "0 0 0 0";
|
||||
const transformBuf = [],
|
||||
paddingBuf = [];
|
||||
|
||||
for (var i = 0, ii = this._textDivs.length; i < ii; i++) {
|
||||
const div = this._textDivs[i];
|
||||
|
@ -651,17 +691,18 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
if (divProps.paddingLeft > 0) {
|
||||
paddingBuf.push(`${divProps.paddingLeft / divProps.scale}px`);
|
||||
transformBuf.push(
|
||||
`translateX(${-divProps.paddingLeft / divProps.scale}px)`);
|
||||
`translateX(${-divProps.paddingLeft / divProps.scale}px)`
|
||||
);
|
||||
} else {
|
||||
paddingBuf.push(0);
|
||||
}
|
||||
|
||||
const padding = paddingBuf.join(' ');
|
||||
const padding = paddingBuf.join(" ");
|
||||
if (padding !== NO_PADDING) {
|
||||
div.style.padding = padding;
|
||||
}
|
||||
if (transformBuf.length) {
|
||||
div.style.transform = transformBuf.join(' ');
|
||||
div.style.transform = transformBuf.join(" ");
|
||||
}
|
||||
} else {
|
||||
div.style.padding = null;
|
||||
|
@ -694,6 +735,4 @@ var renderTextLayer = (function renderTextLayerClosure() {
|
|||
return renderTextLayer;
|
||||
})();
|
||||
|
||||
export {
|
||||
renderTextLayer,
|
||||
};
|
||||
export { renderTextLayer };
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
/* eslint no-var: error */
|
||||
|
||||
import { assert, createPromiseCapability } from '../shared/util';
|
||||
import { assert, createPromiseCapability } from "../shared/util";
|
||||
|
||||
/** @implements {IPDFStream} */
|
||||
class PDFDataTransportStream {
|
||||
|
@ -39,15 +39,15 @@ class PDFDataTransportStream {
|
|||
this._rangeReaders = [];
|
||||
|
||||
this._pdfDataRangeTransport.addRangeListener((begin, chunk) => {
|
||||
this._onReceiveData({ begin, chunk, });
|
||||
this._onReceiveData({ begin, chunk });
|
||||
});
|
||||
|
||||
this._pdfDataRangeTransport.addProgressListener((loaded, total) => {
|
||||
this._onProgress({ loaded, total, });
|
||||
this._onProgress({ loaded, total });
|
||||
});
|
||||
|
||||
this._pdfDataRangeTransport.addProgressiveReadListener((chunk) => {
|
||||
this._onReceiveData({ chunk, });
|
||||
this._pdfDataRangeTransport.addProgressiveReadListener(chunk => {
|
||||
this._onReceiveData({ chunk });
|
||||
});
|
||||
|
||||
this._pdfDataRangeTransport.addProgressiveDoneListener(() => {
|
||||
|
@ -78,7 +78,7 @@ class PDFDataTransportStream {
|
|||
}
|
||||
|
||||
get _progressiveDataLength() {
|
||||
return (this._fullRequestReader ? this._fullRequestReader._loaded : 0);
|
||||
return this._fullRequestReader ? this._fullRequestReader._loaded : 0;
|
||||
}
|
||||
|
||||
_onProgress(evt) {
|
||||
|
@ -86,12 +86,12 @@ class PDFDataTransportStream {
|
|||
// Reporting to first range reader, if it exists.
|
||||
const firstReader = this._rangeReaders[0];
|
||||
if (firstReader && firstReader.onProgress) {
|
||||
firstReader.onProgress({ loaded: evt.loaded, });
|
||||
firstReader.onProgress({ loaded: evt.loaded });
|
||||
}
|
||||
} else {
|
||||
const fullReader = this._fullRequestReader;
|
||||
if (fullReader && fullReader.onProgress) {
|
||||
fullReader.onProgress({ loaded: evt.loaded, total: evt.total, });
|
||||
fullReader.onProgress({ loaded: evt.loaded, total: evt.total });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,8 +114,11 @@ class PDFDataTransportStream {
|
|||
assert(!this._fullRequestReader);
|
||||
const queuedChunks = this._queuedChunks;
|
||||
this._queuedChunks = null;
|
||||
return new PDFDataTransportStreamReader(this, queuedChunks,
|
||||
this._progressiveDone);
|
||||
return new PDFDataTransportStreamReader(
|
||||
this,
|
||||
queuedChunks,
|
||||
this._progressiveDone
|
||||
);
|
||||
}
|
||||
|
||||
getRangeReader(begin, end) {
|
||||
|
@ -164,7 +167,7 @@ class PDFDataTransportStreamReader {
|
|||
}
|
||||
if (this._requests.length > 0) {
|
||||
const requestCapability = this._requests.shift();
|
||||
requestCapability.resolve({ value: chunk, done: false, });
|
||||
requestCapability.resolve({ value: chunk, done: false });
|
||||
} else {
|
||||
this._queuedChunks.push(chunk);
|
||||
}
|
||||
|
@ -194,10 +197,10 @@ class PDFDataTransportStreamReader {
|
|||
async read() {
|
||||
if (this._queuedChunks.length > 0) {
|
||||
const chunk = this._queuedChunks.shift();
|
||||
return { value: chunk, done: false, };
|
||||
return { value: chunk, done: false };
|
||||
}
|
||||
if (this._done) {
|
||||
return { value: undefined, done: true, };
|
||||
return { value: undefined, done: true };
|
||||
}
|
||||
const requestCapability = createPromiseCapability();
|
||||
this._requests.push(requestCapability);
|
||||
|
@ -207,7 +210,7 @@ class PDFDataTransportStreamReader {
|
|||
cancel(reason) {
|
||||
this._done = true;
|
||||
this._requests.forEach(function(requestCapability) {
|
||||
requestCapability.resolve({ value: undefined, done: true, });
|
||||
requestCapability.resolve({ value: undefined, done: true });
|
||||
});
|
||||
this._requests = [];
|
||||
}
|
||||
|
@ -241,9 +244,9 @@ class PDFDataTransportStreamRangeReader {
|
|||
this._queuedChunk = chunk;
|
||||
} else {
|
||||
const requestsCapability = this._requests.shift();
|
||||
requestsCapability.resolve({ value: chunk, done: false, });
|
||||
requestsCapability.resolve({ value: chunk, done: false });
|
||||
this._requests.forEach(function(requestCapability) {
|
||||
requestCapability.resolve({ value: undefined, done: true, });
|
||||
requestCapability.resolve({ value: undefined, done: true });
|
||||
});
|
||||
this._requests = [];
|
||||
}
|
||||
|
@ -259,10 +262,10 @@ class PDFDataTransportStreamRangeReader {
|
|||
if (this._queuedChunk) {
|
||||
const chunk = this._queuedChunk;
|
||||
this._queuedChunk = null;
|
||||
return { value: chunk, done: false, };
|
||||
return { value: chunk, done: false };
|
||||
}
|
||||
if (this._done) {
|
||||
return { value: undefined, done: true, };
|
||||
return { value: undefined, done: true };
|
||||
}
|
||||
const requestCapability = createPromiseCapability();
|
||||
this._requests.push(requestCapability);
|
||||
|
@ -272,13 +275,11 @@ class PDFDataTransportStreamRangeReader {
|
|||
cancel(reason) {
|
||||
this._done = true;
|
||||
this._requests.forEach(function(requestCapability) {
|
||||
requestCapability.resolve({ value: undefined, done: true, });
|
||||
requestCapability.resolve({ value: undefined, done: true });
|
||||
});
|
||||
this._requests = [];
|
||||
this._stream._removeRangeReader(this);
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
PDFDataTransportStream,
|
||||
};
|
||||
export { PDFDataTransportStream };
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
*/
|
||||
/* eslint-disable no-multi-str */
|
||||
|
||||
import { shadow } from '../shared/util';
|
||||
import { shadow } from "../shared/util";
|
||||
|
||||
class WebGLContext {
|
||||
constructor({ enable = false, }) {
|
||||
constructor({ enable = false }) {
|
||||
this._enabled = enable === true;
|
||||
}
|
||||
|
||||
|
@ -26,16 +26,21 @@ class WebGLContext {
|
|||
if (enabled) {
|
||||
enabled = WebGLUtils.tryInitGL();
|
||||
}
|
||||
return shadow(this, 'isEnabled', enabled);
|
||||
return shadow(this, "isEnabled", enabled);
|
||||
}
|
||||
|
||||
composeSMask({ layer, mask, properties, }) {
|
||||
composeSMask({ layer, mask, properties }) {
|
||||
return WebGLUtils.composeSMask(layer, mask, properties);
|
||||
}
|
||||
|
||||
drawFigures({ width, height, backgroundColor, figures, context, }) {
|
||||
return WebGLUtils.drawFigures(width, height, backgroundColor, figures,
|
||||
context);
|
||||
drawFigures({ width, height, backgroundColor, figures, context }) {
|
||||
return WebGLUtils.drawFigures(
|
||||
width,
|
||||
height,
|
||||
backgroundColor,
|
||||
figures,
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
clear() {
|
||||
|
@ -51,7 +56,7 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
|
||||
if (!compiled) {
|
||||
var errorMsg = gl.getShaderInfoLog(shader);
|
||||
throw new Error('Error during shader compilation: ' + errorMsg);
|
||||
throw new Error("Error during shader compilation: " + errorMsg);
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
@ -70,7 +75,7 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
|
||||
if (!linked) {
|
||||
var errorMsg = gl.getProgramInfoLog(program);
|
||||
throw new Error('Error during program linking: ' + errorMsg);
|
||||
throw new Error("Error during program linking: " + errorMsg);
|
||||
}
|
||||
return program;
|
||||
}
|
||||
|
@ -97,12 +102,14 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
}
|
||||
|
||||
// The temporary canvas is used in the WebGL context.
|
||||
currentCanvas = document.createElement('canvas');
|
||||
currentGL = currentCanvas.getContext('webgl',
|
||||
{ premultipliedalpha: false, });
|
||||
currentCanvas = document.createElement("canvas");
|
||||
currentGL = currentCanvas.getContext("webgl", {
|
||||
premultipliedalpha: false,
|
||||
});
|
||||
}
|
||||
|
||||
var smaskVertexShaderCode = '\
|
||||
var smaskVertexShaderCode =
|
||||
"\
|
||||
attribute vec2 a_position; \
|
||||
attribute vec2 a_texCoord; \
|
||||
\
|
||||
|
@ -115,9 +122,10 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1); \
|
||||
\
|
||||
v_texCoord = a_texCoord; \
|
||||
} ';
|
||||
} ";
|
||||
|
||||
var smaskFragmentShaderCode = '\
|
||||
var smaskFragmentShaderCode =
|
||||
"\
|
||||
precision mediump float; \
|
||||
\
|
||||
uniform vec4 u_backdrop; \
|
||||
|
@ -144,7 +152,7 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
imageColor.a *= lum; \
|
||||
imageColor.rgb *= imageColor.a; \
|
||||
gl_FragColor = imageColor; \
|
||||
} ';
|
||||
} ";
|
||||
|
||||
var smaskCache = null;
|
||||
|
||||
|
@ -166,14 +174,14 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
var cache = {};
|
||||
cache.gl = gl;
|
||||
cache.canvas = canvas;
|
||||
cache.resolutionLocation = gl.getUniformLocation(program, 'u_resolution');
|
||||
cache.positionLocation = gl.getAttribLocation(program, 'a_position');
|
||||
cache.backdropLocation = gl.getUniformLocation(program, 'u_backdrop');
|
||||
cache.subtypeLocation = gl.getUniformLocation(program, 'u_subtype');
|
||||
cache.resolutionLocation = gl.getUniformLocation(program, "u_resolution");
|
||||
cache.positionLocation = gl.getAttribLocation(program, "a_position");
|
||||
cache.backdropLocation = gl.getUniformLocation(program, "u_backdrop");
|
||||
cache.subtypeLocation = gl.getUniformLocation(program, "u_subtype");
|
||||
|
||||
var texCoordLocation = gl.getAttribLocation(program, 'a_texCoord');
|
||||
var texLayerLocation = gl.getUniformLocation(program, 'u_image');
|
||||
var texMaskLocation = gl.getUniformLocation(program, 'u_mask');
|
||||
var texCoordLocation = gl.getAttribLocation(program, "a_texCoord");
|
||||
var texLayerLocation = gl.getUniformLocation(program, "u_image");
|
||||
var texMaskLocation = gl.getUniformLocation(program, "u_mask");
|
||||
|
||||
// provide texture coordinates for the rectangle.
|
||||
var texCoordBuffer = gl.createBuffer();
|
||||
|
@ -196,25 +204,35 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
}
|
||||
|
||||
function composeSMask(layer, mask, properties) {
|
||||
var width = layer.width, height = layer.height;
|
||||
var width = layer.width,
|
||||
height = layer.height;
|
||||
|
||||
if (!smaskCache) {
|
||||
initSmaskGL();
|
||||
}
|
||||
var cache = smaskCache, canvas = cache.canvas, gl = cache.gl;
|
||||
var cache = smaskCache,
|
||||
canvas = cache.canvas,
|
||||
gl = cache.gl;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
||||
gl.uniform2f(cache.resolutionLocation, width, height);
|
||||
|
||||
if (properties.backdrop) {
|
||||
gl.uniform4f(cache.resolutionLocation, properties.backdrop[0],
|
||||
properties.backdrop[1], properties.backdrop[2], 1);
|
||||
gl.uniform4f(
|
||||
cache.resolutionLocation,
|
||||
properties.backdrop[0],
|
||||
properties.backdrop[1],
|
||||
properties.backdrop[2],
|
||||
1
|
||||
);
|
||||
} else {
|
||||
gl.uniform4f(cache.resolutionLocation, 0, 0, 0, 0);
|
||||
}
|
||||
gl.uniform1i(cache.subtypeLocation,
|
||||
properties.subtype === 'Luminosity' ? 1 : 0);
|
||||
gl.uniform1i(
|
||||
cache.subtypeLocation,
|
||||
properties.subtype === "Luminosity" ? 1 : 0
|
||||
);
|
||||
|
||||
// Create a textures
|
||||
var texture = createTexture(gl, layer, gl.TEXTURE0);
|
||||
|
@ -252,7 +270,8 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
return canvas;
|
||||
}
|
||||
|
||||
var figuresVertexShaderCode = '\
|
||||
var figuresVertexShaderCode =
|
||||
"\
|
||||
attribute vec2 a_position; \
|
||||
attribute vec3 a_color; \
|
||||
\
|
||||
|
@ -268,16 +287,17 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1); \
|
||||
\
|
||||
v_color = vec4(a_color / 255.0, 1.0); \
|
||||
} ';
|
||||
} ";
|
||||
|
||||
var figuresFragmentShaderCode = '\
|
||||
var figuresFragmentShaderCode =
|
||||
"\
|
||||
precision mediump float; \
|
||||
\
|
||||
varying vec4 v_color; \
|
||||
\
|
||||
void main() { \
|
||||
gl_FragColor = v_color; \
|
||||
} ';
|
||||
} ";
|
||||
|
||||
var figuresCache = null;
|
||||
|
||||
|
@ -299,11 +319,11 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
var cache = {};
|
||||
cache.gl = gl;
|
||||
cache.canvas = canvas;
|
||||
cache.resolutionLocation = gl.getUniformLocation(program, 'u_resolution');
|
||||
cache.scaleLocation = gl.getUniformLocation(program, 'u_scale');
|
||||
cache.offsetLocation = gl.getUniformLocation(program, 'u_offset');
|
||||
cache.positionLocation = gl.getAttribLocation(program, 'a_position');
|
||||
cache.colorLocation = gl.getAttribLocation(program, 'a_color');
|
||||
cache.resolutionLocation = gl.getUniformLocation(program, "u_resolution");
|
||||
cache.scaleLocation = gl.getUniformLocation(program, "u_scale");
|
||||
cache.offsetLocation = gl.getUniformLocation(program, "u_offset");
|
||||
cache.positionLocation = gl.getAttribLocation(program, "a_position");
|
||||
cache.colorLocation = gl.getAttribLocation(program, "a_color");
|
||||
|
||||
figuresCache = cache;
|
||||
}
|
||||
|
@ -312,7 +332,9 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
if (!figuresCache) {
|
||||
initFiguresGL();
|
||||
}
|
||||
var cache = figuresCache, canvas = cache.canvas, gl = cache.gl;
|
||||
var cache = figuresCache,
|
||||
canvas = cache.canvas,
|
||||
gl = cache.gl;
|
||||
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
@ -324,11 +346,11 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
var i, ii, rows;
|
||||
for (i = 0, ii = figures.length; i < ii; i++) {
|
||||
switch (figures[i].type) {
|
||||
case 'lattice':
|
||||
case "lattice":
|
||||
rows = (figures[i].coords.length / figures[i].verticesPerRow) | 0;
|
||||
count += (rows - 1) * (figures[i].verticesPerRow - 1) * 6;
|
||||
break;
|
||||
case 'triangles':
|
||||
case "triangles":
|
||||
count += figures[i].coords.length;
|
||||
break;
|
||||
}
|
||||
|
@ -336,12 +358,16 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
// transfer data
|
||||
var coords = new Float32Array(count * 2);
|
||||
var colors = new Uint8Array(count * 3);
|
||||
var coordsMap = context.coords, colorsMap = context.colors;
|
||||
var pIndex = 0, cIndex = 0;
|
||||
var coordsMap = context.coords,
|
||||
colorsMap = context.colors;
|
||||
var pIndex = 0,
|
||||
cIndex = 0;
|
||||
for (i = 0, ii = figures.length; i < ii; i++) {
|
||||
var figure = figures[i], ps = figure.coords, cs = figure.colors;
|
||||
var figure = figures[i],
|
||||
ps = figure.coords,
|
||||
cs = figure.colors;
|
||||
switch (figure.type) {
|
||||
case 'lattice':
|
||||
case "lattice":
|
||||
var cols = figure.verticesPerRow;
|
||||
rows = (ps.length / cols) | 0;
|
||||
for (var row = 1; row < rows; row++) {
|
||||
|
@ -383,7 +409,7 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 'triangles':
|
||||
case "triangles":
|
||||
for (var j = 0, jj = ps.length; j < jj; j++) {
|
||||
coords[pIndex] = coordsMap[ps[j]];
|
||||
coords[pIndex + 1] = coordsMap[ps[j] + 1];
|
||||
|
@ -399,8 +425,12 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
|
||||
// draw
|
||||
if (backgroundColor) {
|
||||
gl.clearColor(backgroundColor[0] / 255, backgroundColor[1] / 255,
|
||||
backgroundColor[2] / 255, 1.0);
|
||||
gl.clearColor(
|
||||
backgroundColor[0] / 255,
|
||||
backgroundColor[1] / 255,
|
||||
backgroundColor[2] / 255,
|
||||
1.0
|
||||
);
|
||||
} else {
|
||||
gl.clearColor(0, 0, 0, 0);
|
||||
}
|
||||
|
@ -416,8 +446,14 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
gl.bindBuffer(gl.ARRAY_BUFFER, colorsBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(cache.colorLocation);
|
||||
gl.vertexAttribPointer(cache.colorLocation, 3, gl.UNSIGNED_BYTE, false,
|
||||
0, 0);
|
||||
gl.vertexAttribPointer(
|
||||
cache.colorLocation,
|
||||
3,
|
||||
gl.UNSIGNED_BYTE,
|
||||
false,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
gl.uniform2f(cache.scaleLocation, context.scaleX, context.scaleY);
|
||||
gl.uniform2f(cache.offsetLocation, context.offsetX, context.offsetY);
|
||||
|
@ -437,7 +473,7 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
try {
|
||||
generateGL();
|
||||
return !!currentGL;
|
||||
} catch (ex) { }
|
||||
} catch (ex) {}
|
||||
return false;
|
||||
},
|
||||
|
||||
|
@ -460,6 +496,4 @@ var WebGLUtils = (function WebGLUtilsClosure() {
|
|||
};
|
||||
})();
|
||||
|
||||
export {
|
||||
WebGLContext,
|
||||
};
|
||||
export { WebGLContext };
|
||||
|
|
|
@ -19,8 +19,10 @@ const GlobalWorkerOptions = Object.create(null);
|
|||
* Defines global port for worker process. Overrides the `workerSrc` option.
|
||||
* @var {Object}
|
||||
*/
|
||||
GlobalWorkerOptions.workerPort = (GlobalWorkerOptions.workerPort === undefined ?
|
||||
null : GlobalWorkerOptions.workerPort);
|
||||
GlobalWorkerOptions.workerPort =
|
||||
GlobalWorkerOptions.workerPort === undefined
|
||||
? null
|
||||
: GlobalWorkerOptions.workerPort;
|
||||
|
||||
/**
|
||||
* Path and filename of the worker file. Required when workers are enabled in
|
||||
|
@ -31,9 +33,9 @@ GlobalWorkerOptions.workerPort = (GlobalWorkerOptions.workerPort === undefined ?
|
|||
* to prevent issues caused by third-party frameworks and libraries.
|
||||
* @var {string}
|
||||
*/
|
||||
GlobalWorkerOptions.workerSrc = (GlobalWorkerOptions.workerSrc === undefined ?
|
||||
'' : GlobalWorkerOptions.workerSrc);
|
||||
GlobalWorkerOptions.workerSrc =
|
||||
GlobalWorkerOptions.workerSrc === undefined
|
||||
? ""
|
||||
: GlobalWorkerOptions.workerSrc;
|
||||
|
||||
export {
|
||||
GlobalWorkerOptions,
|
||||
};
|
||||
export { GlobalWorkerOptions };
|
||||
|
|
|
@ -32,7 +32,7 @@ const XMLParserErrorCode = {
|
|||
|
||||
function isWhitespace(s, index) {
|
||||
const ch = s[index];
|
||||
return ch === ' ' || ch === '\n' || ch === '\r' || ch === '\t';
|
||||
return ch === " " || ch === "\n" || ch === "\r" || ch === "\t";
|
||||
}
|
||||
|
||||
function isWhitespaceString(s) {
|
||||
|
@ -47,27 +47,29 @@ function isWhitespaceString(s) {
|
|||
class XMLParserBase {
|
||||
_resolveEntities(s) {
|
||||
return s.replace(/&([^;]+);/g, (all, entity) => {
|
||||
if (entity.substring(0, 2) === '#x') {
|
||||
if (entity.substring(0, 2) === "#x") {
|
||||
return String.fromCharCode(parseInt(entity.substring(2), 16));
|
||||
} else if (entity.substring(0, 1) === '#') {
|
||||
} else if (entity.substring(0, 1) === "#") {
|
||||
return String.fromCharCode(parseInt(entity.substring(1), 10));
|
||||
}
|
||||
switch (entity) {
|
||||
case 'lt':
|
||||
return '<';
|
||||
case 'gt':
|
||||
return '>';
|
||||
case 'amp':
|
||||
return '&';
|
||||
case 'quot':
|
||||
return '\"';
|
||||
case "lt":
|
||||
return "<";
|
||||
case "gt":
|
||||
return ">";
|
||||
case "amp":
|
||||
return "&";
|
||||
case "quot":
|
||||
return '"';
|
||||
}
|
||||
return this.onResolveEntity(entity);
|
||||
});
|
||||
}
|
||||
|
||||
_parseContent(s, start) {
|
||||
let pos = start, name, attributes = [];
|
||||
let pos = start,
|
||||
name,
|
||||
attributes = [];
|
||||
|
||||
function skipWs() {
|
||||
while (pos < s.length && isWhitespace(s, pos)) {
|
||||
|
@ -75,28 +77,37 @@ class XMLParserBase {
|
|||
}
|
||||
}
|
||||
|
||||
while (pos < s.length && !isWhitespace(s, pos) &&
|
||||
s[pos] !== '>' && s[pos] !== '/') {
|
||||
while (
|
||||
pos < s.length &&
|
||||
!isWhitespace(s, pos) &&
|
||||
s[pos] !== ">" &&
|
||||
s[pos] !== "/"
|
||||
) {
|
||||
++pos;
|
||||
}
|
||||
name = s.substring(start, pos);
|
||||
skipWs();
|
||||
while (pos < s.length && s[pos] !== '>' &&
|
||||
s[pos] !== '/' && s[pos] !== '?') {
|
||||
while (
|
||||
pos < s.length &&
|
||||
s[pos] !== ">" &&
|
||||
s[pos] !== "/" &&
|
||||
s[pos] !== "?"
|
||||
) {
|
||||
skipWs();
|
||||
let attrName = '', attrValue = '';
|
||||
while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== '=') {
|
||||
let attrName = "",
|
||||
attrValue = "";
|
||||
while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== "=") {
|
||||
attrName += s[pos];
|
||||
++pos;
|
||||
}
|
||||
skipWs();
|
||||
if (s[pos] !== '=') {
|
||||
if (s[pos] !== "=") {
|
||||
return null;
|
||||
}
|
||||
++pos;
|
||||
skipWs();
|
||||
const attrEndChar = s[pos];
|
||||
if (attrEndChar !== '\"' && attrEndChar !== '\'') {
|
||||
if (attrEndChar !== '"' && attrEndChar !== "'") {
|
||||
return null;
|
||||
}
|
||||
const attrEndIndex = s.indexOf(attrEndChar, ++pos);
|
||||
|
@ -119,7 +130,9 @@ class XMLParserBase {
|
|||
}
|
||||
|
||||
_parseProcessingInstruction(s, start) {
|
||||
let pos = start, name, value;
|
||||
let pos = start,
|
||||
name,
|
||||
value;
|
||||
|
||||
function skipWs() {
|
||||
while (pos < s.length && isWhitespace(s, pos)) {
|
||||
|
@ -127,14 +140,18 @@ class XMLParserBase {
|
|||
}
|
||||
}
|
||||
|
||||
while (pos < s.length && !isWhitespace(s, pos) &&
|
||||
s[pos] !== '>' && s[pos] !== '/') {
|
||||
while (
|
||||
pos < s.length &&
|
||||
!isWhitespace(s, pos) &&
|
||||
s[pos] !== ">" &&
|
||||
s[pos] !== "/"
|
||||
) {
|
||||
++pos;
|
||||
}
|
||||
name = s.substring(start, pos);
|
||||
skipWs();
|
||||
const attrStart = pos;
|
||||
while (pos < s.length && (s[pos] !== '?' || s[pos + 1] !== '>')) {
|
||||
while (pos < s.length && (s[pos] !== "?" || s[pos + 1] !== ">")) {
|
||||
++pos;
|
||||
}
|
||||
value = s.substring(attrStart, pos);
|
||||
|
@ -150,14 +167,14 @@ class XMLParserBase {
|
|||
while (i < s.length) {
|
||||
const ch = s[i];
|
||||
let j = i;
|
||||
if (ch === '<') {
|
||||
if (ch === "<") {
|
||||
++j;
|
||||
const ch2 = s[j];
|
||||
let q;
|
||||
switch (ch2) {
|
||||
case '/':
|
||||
case "/":
|
||||
++j;
|
||||
q = s.indexOf('>', j);
|
||||
q = s.indexOf(">", j);
|
||||
if (q < 0) {
|
||||
this.onError(XMLParserErrorCode.UnterminatedElement);
|
||||
return;
|
||||
|
@ -165,52 +182,55 @@ class XMLParserBase {
|
|||
this.onEndElement(s.substring(j, q));
|
||||
j = q + 1;
|
||||
break;
|
||||
case '?':
|
||||
case "?":
|
||||
++j;
|
||||
const pi = this._parseProcessingInstruction(s, j);
|
||||
if (s.substring(j + pi.parsed, j + pi.parsed + 2) !== '?>') {
|
||||
if (s.substring(j + pi.parsed, j + pi.parsed + 2) !== "?>") {
|
||||
this.onError(XMLParserErrorCode.UnterminatedXmlDeclaration);
|
||||
return;
|
||||
}
|
||||
this.onPi(pi.name, pi.value);
|
||||
j += pi.parsed + 2;
|
||||
break;
|
||||
case '!':
|
||||
if (s.substring(j + 1, j + 3) === '--') {
|
||||
q = s.indexOf('-->', j + 3);
|
||||
case "!":
|
||||
if (s.substring(j + 1, j + 3) === "--") {
|
||||
q = s.indexOf("-->", j + 3);
|
||||
if (q < 0) {
|
||||
this.onError(XMLParserErrorCode.UnterminatedComment);
|
||||
return;
|
||||
}
|
||||
this.onComment(s.substring(j + 3, q));
|
||||
j = q + 3;
|
||||
} else if (s.substring(j + 1, j + 8) === '[CDATA[') {
|
||||
q = s.indexOf(']]>', j + 8);
|
||||
} else if (s.substring(j + 1, j + 8) === "[CDATA[") {
|
||||
q = s.indexOf("]]>", j + 8);
|
||||
if (q < 0) {
|
||||
this.onError(XMLParserErrorCode.UnterminatedCdat);
|
||||
return;
|
||||
}
|
||||
this.onCdata(s.substring(j + 8, q));
|
||||
j = q + 3;
|
||||
} else if (s.substring(j + 1, j + 8) === 'DOCTYPE') {
|
||||
const q2 = s.indexOf('[', j + 8);
|
||||
} else if (s.substring(j + 1, j + 8) === "DOCTYPE") {
|
||||
const q2 = s.indexOf("[", j + 8);
|
||||
let complexDoctype = false;
|
||||
q = s.indexOf('>', j + 8);
|
||||
q = s.indexOf(">", j + 8);
|
||||
if (q < 0) {
|
||||
this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration);
|
||||
return;
|
||||
}
|
||||
if (q2 > 0 && q > q2) {
|
||||
q = s.indexOf(']>', j + 8);
|
||||
q = s.indexOf("]>", j + 8);
|
||||
if (q < 0) {
|
||||
this.onError(
|
||||
XMLParserErrorCode.UnterminatedDoctypeDeclaration);
|
||||
XMLParserErrorCode.UnterminatedDoctypeDeclaration
|
||||
);
|
||||
return;
|
||||
}
|
||||
complexDoctype = true;
|
||||
}
|
||||
const doctypeContent =
|
||||
s.substring(j + 8, q + (complexDoctype ? 1 : 0));
|
||||
const doctypeContent = s.substring(
|
||||
j + 8,
|
||||
q + (complexDoctype ? 1 : 0)
|
||||
);
|
||||
this.onDoctype(doctypeContent);
|
||||
j = q + (complexDoctype ? 2 : 1);
|
||||
} else {
|
||||
|
@ -225,11 +245,13 @@ class XMLParserBase {
|
|||
return;
|
||||
}
|
||||
let isClosed = false;
|
||||
if (s.substring(j + content.parsed,
|
||||
j + content.parsed + 2) === '/>') {
|
||||
if (
|
||||
s.substring(j + content.parsed, j + content.parsed + 2) === "/>"
|
||||
) {
|
||||
isClosed = true;
|
||||
} else if (s.substring(j + content.parsed,
|
||||
j + content.parsed + 1) !== '>') {
|
||||
} else if (
|
||||
s.substring(j + content.parsed, j + content.parsed + 1) !== ">"
|
||||
) {
|
||||
this.onError(XMLParserErrorCode.UnterminatedElement);
|
||||
return;
|
||||
}
|
||||
|
@ -238,7 +260,7 @@ class XMLParserBase {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
while (j < s.length && s[j] !== '<') {
|
||||
while (j < s.length && s[j] !== "<") {
|
||||
j++;
|
||||
}
|
||||
const text = s.substring(i, j);
|
||||
|
@ -252,21 +274,21 @@ class XMLParserBase {
|
|||
return `&${name};`;
|
||||
}
|
||||
|
||||
onPi(name, value) { }
|
||||
onPi(name, value) {}
|
||||
|
||||
onComment(text) { }
|
||||
onComment(text) {}
|
||||
|
||||
onCdata(text) { }
|
||||
onCdata(text) {}
|
||||
|
||||
onDoctype(doctypeContent) { }
|
||||
onDoctype(doctypeContent) {}
|
||||
|
||||
onText(text) { }
|
||||
onText(text) {}
|
||||
|
||||
onBeginElement(name, attributes, isEmpty) { }
|
||||
onBeginElement(name, attributes, isEmpty) {}
|
||||
|
||||
onEndElement(name) { }
|
||||
onEndElement(name) {}
|
||||
|
||||
onError(code) { }
|
||||
onError(code) {}
|
||||
}
|
||||
|
||||
class SimpleDOMNode {
|
||||
|
@ -274,7 +296,7 @@ class SimpleDOMNode {
|
|||
this.nodeName = nodeName;
|
||||
this.nodeValue = nodeValue;
|
||||
|
||||
Object.defineProperty(this, 'parentNode', { value: null, writable: true, });
|
||||
Object.defineProperty(this, "parentNode", { value: null, writable: true });
|
||||
}
|
||||
|
||||
get firstChild() {
|
||||
|
@ -295,11 +317,13 @@ class SimpleDOMNode {
|
|||
|
||||
get textContent() {
|
||||
if (!this.childNodes) {
|
||||
return this.nodeValue || '';
|
||||
return this.nodeValue || "";
|
||||
}
|
||||
return this.childNodes.map(function(child) {
|
||||
return child.textContent;
|
||||
}).join('');
|
||||
return this.childNodes
|
||||
.map(function(child) {
|
||||
return child.textContent;
|
||||
})
|
||||
.join("");
|
||||
}
|
||||
|
||||
hasChildNodes() {
|
||||
|
@ -331,13 +355,13 @@ class SimpleXMLParser extends XMLParserBase {
|
|||
if (!documentElement) {
|
||||
return undefined; // Return undefined if no root was found.
|
||||
}
|
||||
return { documentElement, };
|
||||
return { documentElement };
|
||||
}
|
||||
|
||||
onResolveEntity(name) {
|
||||
switch (name) {
|
||||
case 'apos':
|
||||
return '\'';
|
||||
case "apos":
|
||||
return "'";
|
||||
}
|
||||
return super.onResolveEntity(name);
|
||||
}
|
||||
|
@ -346,12 +370,12 @@ class SimpleXMLParser extends XMLParserBase {
|
|||
if (isWhitespaceString(text)) {
|
||||
return;
|
||||
}
|
||||
const node = new SimpleDOMNode('#text', text);
|
||||
const node = new SimpleDOMNode("#text", text);
|
||||
this._currentFragment.push(node);
|
||||
}
|
||||
|
||||
onCdata(text) {
|
||||
const node = new SimpleDOMNode('#text', text);
|
||||
const node = new SimpleDOMNode("#text", text);
|
||||
this._currentFragment.push(node);
|
||||
}
|
||||
|
||||
|
@ -382,6 +406,4 @@ class SimpleXMLParser extends XMLParserBase {
|
|||
}
|
||||
}
|
||||
|
||||
export {
|
||||
SimpleXMLParser,
|
||||
};
|
||||
export { SimpleXMLParser };
|
||||
|
|
|
@ -166,8 +166,4 @@ class IPDFStreamRangeReader {
|
|||
cancel(reason) {}
|
||||
}
|
||||
|
||||
export {
|
||||
IPDFStream,
|
||||
IPDFStreamReader,
|
||||
IPDFStreamRangeReader,
|
||||
};
|
||||
export { IPDFStream, IPDFStreamReader, IPDFStreamRangeReader };
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
*/
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
import { getVerbosityLevel, setVerbosityLevel } from './shared/util';
|
||||
import { Jbig2mage } from './core/jbig2';
|
||||
import { JpegImage } from './core/jpg';
|
||||
import { JpxImage } from './core/jpx';
|
||||
import { getVerbosityLevel, setVerbosityLevel } from "./shared/util";
|
||||
import { Jbig2mage } from "./core/jbig2";
|
||||
import { JpegImage } from "./core/jpg";
|
||||
import { JpxImage } from "./core/jpx";
|
||||
|
||||
// To ensure that the standalone PDF.js image decoders have the same
|
||||
// browser/environment compatibility as the regular PDF.js library,
|
||||
|
@ -33,13 +33,7 @@ import { JpxImage } from './core/jpx';
|
|||
// - Promise
|
||||
// - URL
|
||||
|
||||
const pdfjsVersion = PDFJSDev.eval('BUNDLE_VERSION');
|
||||
const pdfjsBuild = PDFJSDev.eval('BUNDLE_BUILD');
|
||||
const pdfjsVersion = PDFJSDev.eval("BUNDLE_VERSION");
|
||||
const pdfjsBuild = PDFJSDev.eval("BUNDLE_BUILD");
|
||||
|
||||
export {
|
||||
Jbig2mage,
|
||||
JpegImage,
|
||||
JpxImage,
|
||||
getVerbosityLevel,
|
||||
setVerbosityLevel,
|
||||
};
|
||||
export { Jbig2mage, JpegImage, JpxImage, getVerbosityLevel, setVerbosityLevel };
|
||||
|
|
62
src/pdf.js
62
src/pdf.js
|
@ -14,45 +14,47 @@
|
|||
*/
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
var pdfjsVersion =
|
||||
typeof PDFJSDev !== 'undefined' ? PDFJSDev.eval('BUNDLE_VERSION') : void 0;
|
||||
typeof PDFJSDev !== "undefined" ? PDFJSDev.eval("BUNDLE_VERSION") : void 0;
|
||||
var pdfjsBuild =
|
||||
typeof PDFJSDev !== 'undefined' ? PDFJSDev.eval('BUNDLE_BUILD') : void 0;
|
||||
typeof PDFJSDev !== "undefined" ? PDFJSDev.eval("BUNDLE_BUILD") : void 0;
|
||||
|
||||
var pdfjsSharedUtil = require('./shared/util.js');
|
||||
var pdfjsDisplayAPI = require('./display/api.js');
|
||||
var pdfjsDisplayTextLayer = require('./display/text_layer.js');
|
||||
var pdfjsDisplayAnnotationLayer = require('./display/annotation_layer.js');
|
||||
var pdfjsDisplayDisplayUtils = require('./display/display_utils.js');
|
||||
var pdfjsDisplaySVG = require('./display/svg.js');
|
||||
let pdfjsDisplayWorkerOptions = require('./display/worker_options.js');
|
||||
let pdfjsDisplayAPICompatibility = require('./display/api_compatibility.js');
|
||||
var pdfjsSharedUtil = require("./shared/util.js");
|
||||
var pdfjsDisplayAPI = require("./display/api.js");
|
||||
var pdfjsDisplayTextLayer = require("./display/text_layer.js");
|
||||
var pdfjsDisplayAnnotationLayer = require("./display/annotation_layer.js");
|
||||
var pdfjsDisplayDisplayUtils = require("./display/display_utils.js");
|
||||
var pdfjsDisplaySVG = require("./display/svg.js");
|
||||
let pdfjsDisplayWorkerOptions = require("./display/worker_options.js");
|
||||
let pdfjsDisplayAPICompatibility = require("./display/api_compatibility.js");
|
||||
|
||||
if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
||||
const { isNodeJS, } = require('./shared/is_node.js');
|
||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
const { isNodeJS } = require("./shared/is_node.js");
|
||||
if (isNodeJS) {
|
||||
let PDFNodeStream = require('./display/node_stream.js').PDFNodeStream;
|
||||
pdfjsDisplayAPI.setPDFNetworkStreamFactory((params) => {
|
||||
let PDFNodeStream = require("./display/node_stream.js").PDFNodeStream;
|
||||
pdfjsDisplayAPI.setPDFNetworkStreamFactory(params => {
|
||||
return new PDFNodeStream(params);
|
||||
});
|
||||
} else {
|
||||
let PDFNetworkStream = require('./display/network.js').PDFNetworkStream;
|
||||
let PDFNetworkStream = require("./display/network.js").PDFNetworkStream;
|
||||
let PDFFetchStream;
|
||||
if (pdfjsDisplayDisplayUtils.isFetchSupported()) {
|
||||
PDFFetchStream = require('./display/fetch_stream.js').PDFFetchStream;
|
||||
PDFFetchStream = require("./display/fetch_stream.js").PDFFetchStream;
|
||||
}
|
||||
pdfjsDisplayAPI.setPDFNetworkStreamFactory((params) => {
|
||||
if (PDFFetchStream &&
|
||||
pdfjsDisplayDisplayUtils.isValidFetchUrl(params.url)) {
|
||||
pdfjsDisplayAPI.setPDFNetworkStreamFactory(params => {
|
||||
if (
|
||||
PDFFetchStream &&
|
||||
pdfjsDisplayDisplayUtils.isValidFetchUrl(params.url)
|
||||
) {
|
||||
return new PDFFetchStream(params);
|
||||
}
|
||||
return new PDFNetworkStream(params);
|
||||
});
|
||||
}
|
||||
} else if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME')) {
|
||||
let PDFNetworkStream = require('./display/network.js').PDFNetworkStream;
|
||||
} else if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("CHROME")) {
|
||||
let PDFNetworkStream = require("./display/network.js").PDFNetworkStream;
|
||||
let PDFFetchStream;
|
||||
let isChromeWithFetchCredentials = function() {
|
||||
// fetch does not include credentials until Chrome 61.0.3138.0 and later.
|
||||
|
@ -67,13 +69,17 @@ if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
|
|||
return true;
|
||||
}
|
||||
};
|
||||
if (pdfjsDisplayDisplayUtils.isFetchSupported() &&
|
||||
isChromeWithFetchCredentials()) {
|
||||
PDFFetchStream = require('./display/fetch_stream.js').PDFFetchStream;
|
||||
if (
|
||||
pdfjsDisplayDisplayUtils.isFetchSupported() &&
|
||||
isChromeWithFetchCredentials()
|
||||
) {
|
||||
PDFFetchStream = require("./display/fetch_stream.js").PDFFetchStream;
|
||||
}
|
||||
pdfjsDisplayAPI.setPDFNetworkStreamFactory((params) => {
|
||||
if (PDFFetchStream &&
|
||||
pdfjsDisplayDisplayUtils.isValidFetchUrl(params.url)) {
|
||||
pdfjsDisplayAPI.setPDFNetworkStreamFactory(params => {
|
||||
if (
|
||||
PDFFetchStream &&
|
||||
pdfjsDisplayDisplayUtils.isValidFetchUrl(params.url)
|
||||
) {
|
||||
return new PDFFetchStream(params);
|
||||
}
|
||||
return new PDFNetworkStream(params);
|
||||
|
|
|
@ -13,5 +13,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
(typeof window !== 'undefined' ? window : {}).pdfjsWorker =
|
||||
require('./pdf.worker.js');
|
||||
(typeof window !== "undefined"
|
||||
? window
|
||||
: {}
|
||||
).pdfjsWorker = require("./pdf.worker.js");
|
||||
|
|
8
src/pdf.worker.js
vendored
8
src/pdf.worker.js
vendored
|
@ -14,11 +14,11 @@
|
|||
*/
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
const pdfjsVersion = PDFJSDev.eval('BUNDLE_VERSION');
|
||||
const pdfjsBuild = PDFJSDev.eval('BUNDLE_BUILD');
|
||||
const pdfjsVersion = PDFJSDev.eval("BUNDLE_VERSION");
|
||||
const pdfjsBuild = PDFJSDev.eval("BUNDLE_BUILD");
|
||||
|
||||
const pdfjsCoreWorker = require('./core/worker.js');
|
||||
const pdfjsCoreWorker = require("./core/worker.js");
|
||||
|
||||
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
|
||||
|
|
|
@ -15,337 +15,340 @@
|
|||
/* eslint no-var: error */
|
||||
|
||||
// Skip compatibility checks for modern builds and if we already ran the module.
|
||||
if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('SKIP_BABEL')) &&
|
||||
(typeof globalThis === 'undefined' ||
|
||||
!globalThis._pdfjsCompatibilityChecked)) {
|
||||
|
||||
// Provides support for globalThis in legacy browsers.
|
||||
// Support: IE11/Edge, Opera
|
||||
if (typeof globalThis === 'undefined' || globalThis.Math !== Math) {
|
||||
// eslint-disable-next-line no-global-assign
|
||||
globalThis = require('core-js/es/global-this');
|
||||
}
|
||||
globalThis._pdfjsCompatibilityChecked = true;
|
||||
|
||||
const { isNodeJS, } = require('./is_node');
|
||||
|
||||
const hasDOM = typeof window === 'object' && typeof document === 'object';
|
||||
const userAgent =
|
||||
(typeof navigator !== 'undefined' && navigator.userAgent) || '';
|
||||
const isIE = /Trident/.test(userAgent);
|
||||
|
||||
// Support: Node.js
|
||||
(function checkNodeBtoa() {
|
||||
if (globalThis.btoa || !isNodeJS) {
|
||||
return;
|
||||
}
|
||||
globalThis.btoa = function(chars) {
|
||||
// eslint-disable-next-line no-undef
|
||||
return Buffer.from(chars, 'binary').toString('base64');
|
||||
};
|
||||
})();
|
||||
|
||||
// Support: Node.js
|
||||
(function checkNodeAtob() {
|
||||
if (globalThis.atob || !isNodeJS) {
|
||||
return;
|
||||
}
|
||||
globalThis.atob = function(input) {
|
||||
// eslint-disable-next-line no-undef
|
||||
return Buffer.from(input, 'base64').toString('binary');
|
||||
};
|
||||
})();
|
||||
|
||||
// Provides support for ChildNode.remove in legacy browsers.
|
||||
// Support: IE.
|
||||
(function checkChildNodeRemove() {
|
||||
if (!hasDOM) {
|
||||
return;
|
||||
}
|
||||
if (typeof Element.prototype.remove !== 'undefined') {
|
||||
return;
|
||||
}
|
||||
Element.prototype.remove = function () {
|
||||
if (this.parentNode) {
|
||||
// eslint-disable-next-line mozilla/avoid-removeChild
|
||||
this.parentNode.removeChild(this);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
// Provides support for DOMTokenList.prototype.{add, remove}, with more than
|
||||
// one parameter, in legacy browsers.
|
||||
// Support: IE
|
||||
(function checkDOMTokenListAddRemove() {
|
||||
if (!hasDOM || isNodeJS) {
|
||||
return;
|
||||
}
|
||||
const div = document.createElement('div');
|
||||
div.classList.add('testOne', 'testTwo');
|
||||
|
||||
if (div.classList.contains('testOne') === true &&
|
||||
div.classList.contains('testTwo') === true) {
|
||||
return;
|
||||
}
|
||||
const OriginalDOMTokenListAdd = DOMTokenList.prototype.add;
|
||||
const OriginalDOMTokenListRemove = DOMTokenList.prototype.remove;
|
||||
|
||||
DOMTokenList.prototype.add = function(...tokens) {
|
||||
for (let token of tokens) {
|
||||
OriginalDOMTokenListAdd.call(this, token);
|
||||
}
|
||||
};
|
||||
DOMTokenList.prototype.remove = function(...tokens) {
|
||||
for (let token of tokens) {
|
||||
OriginalDOMTokenListRemove.call(this, token);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
// Provides support for DOMTokenList.prototype.toggle, with the optional
|
||||
// "force" parameter, in legacy browsers.
|
||||
// Support: IE
|
||||
(function checkDOMTokenListToggle() {
|
||||
if (!hasDOM || isNodeJS) {
|
||||
return;
|
||||
}
|
||||
const div = document.createElement('div');
|
||||
if (div.classList.toggle('test', 0) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
DOMTokenList.prototype.toggle = function(token) {
|
||||
let force = (arguments.length > 1 ? !!arguments[1] : !this.contains(token));
|
||||
return (this[force ? 'add' : 'remove'](token), force);
|
||||
};
|
||||
})();
|
||||
|
||||
// Provides support for window.history.{pushState, replaceState}, with the
|
||||
// `url` parameter set to `undefined`, without breaking the document URL.
|
||||
// Support: IE
|
||||
(function checkWindowHistoryPushStateReplaceState() {
|
||||
if (!hasDOM || !isIE) {
|
||||
return;
|
||||
}
|
||||
const OriginalPushState = window.history.pushState;
|
||||
const OriginalReplaceState = window.history.replaceState;
|
||||
|
||||
window.history.pushState = function(state, title, url) {
|
||||
const args = (url === undefined ? [state, title] : [state, title, url]);
|
||||
OriginalPushState.apply(this, args);
|
||||
};
|
||||
window.history.replaceState = function(state, title, url) {
|
||||
const args = (url === undefined ? [state, title] : [state, title, url]);
|
||||
OriginalReplaceState.apply(this, args);
|
||||
};
|
||||
})();
|
||||
|
||||
// Provides support for String.prototype.startsWith in legacy browsers.
|
||||
// Support: IE, Chrome<41
|
||||
(function checkStringStartsWith() {
|
||||
if (String.prototype.startsWith) {
|
||||
return;
|
||||
}
|
||||
require('core-js/es/string/starts-with');
|
||||
})();
|
||||
|
||||
// Provides support for String.prototype.endsWith in legacy browsers.
|
||||
// Support: IE, Chrome<41
|
||||
(function checkStringEndsWith() {
|
||||
if (String.prototype.endsWith) {
|
||||
return;
|
||||
}
|
||||
require('core-js/es/string/ends-with');
|
||||
})();
|
||||
|
||||
// Provides support for String.prototype.includes in legacy browsers.
|
||||
// Support: IE, Chrome<41
|
||||
(function checkStringIncludes() {
|
||||
if (String.prototype.includes) {
|
||||
return;
|
||||
}
|
||||
require('core-js/es/string/includes');
|
||||
})();
|
||||
|
||||
// Provides support for Array.prototype.includes in legacy browsers.
|
||||
// Support: IE, Chrome<47
|
||||
(function checkArrayIncludes() {
|
||||
if (Array.prototype.includes) {
|
||||
return;
|
||||
}
|
||||
require('core-js/es/array/includes');
|
||||
})();
|
||||
|
||||
// Provides support for Array.from in legacy browsers.
|
||||
// Support: IE
|
||||
(function checkArrayFrom() {
|
||||
if (Array.from) {
|
||||
return;
|
||||
}
|
||||
require('core-js/es/array/from');
|
||||
})();
|
||||
|
||||
// Provides support for Object.assign in legacy browsers.
|
||||
// Support: IE
|
||||
(function checkObjectAssign() {
|
||||
if (Object.assign) {
|
||||
return;
|
||||
}
|
||||
require('core-js/es/object/assign');
|
||||
})();
|
||||
|
||||
// Provides support for Math.log2 in legacy browsers.
|
||||
// Support: IE, Chrome<38
|
||||
(function checkMathLog2() {
|
||||
if (Math.log2) {
|
||||
return;
|
||||
}
|
||||
Math.log2 = require('core-js/es/math/log2');
|
||||
})();
|
||||
|
||||
// Provides support for Number.isNaN in legacy browsers.
|
||||
// Support: IE.
|
||||
(function checkNumberIsNaN() {
|
||||
if (Number.isNaN) {
|
||||
return;
|
||||
}
|
||||
Number.isNaN = require('core-js/es/number/is-nan');
|
||||
})();
|
||||
|
||||
// Provides support for Number.isInteger in legacy browsers.
|
||||
// Support: IE, Chrome<34
|
||||
(function checkNumberIsInteger() {
|
||||
if (Number.isInteger) {
|
||||
return;
|
||||
}
|
||||
Number.isInteger = require('core-js/es/number/is-integer');
|
||||
})();
|
||||
|
||||
// Support: IE, Safari<11, Chrome<63
|
||||
(function checkPromise() {
|
||||
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('IMAGE_DECODERS')) {
|
||||
// The current image decoders are synchronous, hence `Promise` shouldn't
|
||||
// need to be polyfilled for the IMAGE_DECODERS build target.
|
||||
return;
|
||||
}
|
||||
if (globalThis.Promise && (globalThis.Promise.prototype &&
|
||||
globalThis.Promise.prototype.finally)) {
|
||||
return;
|
||||
}
|
||||
globalThis.Promise = require('core-js/es/promise/index');
|
||||
})();
|
||||
|
||||
// Support: IE
|
||||
(function checkURL() {
|
||||
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('IMAGE_DECODERS')) {
|
||||
// The current image decoders don't use the `URL` constructor, so it
|
||||
// doesn't need to be polyfilled for the IMAGE_DECODERS build target.
|
||||
return;
|
||||
}
|
||||
if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('GENERIC')) {
|
||||
// The `URL` constructor is assumed to be available in the extension builds.
|
||||
return;
|
||||
}
|
||||
globalThis.URL = require('core-js/web/url');
|
||||
})();
|
||||
|
||||
// Support: IE, Node.js
|
||||
(function checkReadableStream() {
|
||||
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('IMAGE_DECODERS')) {
|
||||
// The current image decoders are synchronous, hence `ReadableStream`
|
||||
// shouldn't need to be polyfilled for the IMAGE_DECODERS build target.
|
||||
return;
|
||||
}
|
||||
let isReadableStreamSupported = false;
|
||||
|
||||
if (typeof ReadableStream !== 'undefined') {
|
||||
// MS Edge may say it has ReadableStream but they are not up to spec yet.
|
||||
try {
|
||||
// eslint-disable-next-line no-new
|
||||
new ReadableStream({
|
||||
start(controller) {
|
||||
controller.close();
|
||||
},
|
||||
});
|
||||
isReadableStreamSupported = true;
|
||||
} catch (e) {
|
||||
// The ReadableStream constructor cannot be used.
|
||||
}
|
||||
}
|
||||
if (isReadableStreamSupported) {
|
||||
return;
|
||||
}
|
||||
globalThis.ReadableStream =
|
||||
require('web-streams-polyfill/dist/ponyfill').ReadableStream;
|
||||
})();
|
||||
|
||||
// Support: IE<11, Safari<8, Chrome<36
|
||||
(function checkWeakMap() {
|
||||
if (globalThis.WeakMap) {
|
||||
return;
|
||||
}
|
||||
globalThis.WeakMap = require('core-js/es/weak-map/index');
|
||||
})();
|
||||
|
||||
// Support: IE11
|
||||
(function checkWeakSet() {
|
||||
if (globalThis.WeakSet) {
|
||||
return;
|
||||
}
|
||||
globalThis.WeakSet = require('core-js/es/weak-set/index');
|
||||
})();
|
||||
|
||||
// Provides support for String.codePointAt in legacy browsers.
|
||||
// Support: IE11.
|
||||
(function checkStringCodePointAt() {
|
||||
if (String.prototype.codePointAt) {
|
||||
return;
|
||||
}
|
||||
require('core-js/es/string/code-point-at');
|
||||
})();
|
||||
|
||||
// Provides support for String.fromCodePoint in legacy browsers.
|
||||
// Support: IE11.
|
||||
(function checkStringFromCodePoint() {
|
||||
if (String.fromCodePoint) {
|
||||
return;
|
||||
}
|
||||
String.fromCodePoint = require('core-js/es/string/from-code-point');
|
||||
})();
|
||||
|
||||
// Support: IE
|
||||
(function checkSymbol() {
|
||||
if (globalThis.Symbol) {
|
||||
return;
|
||||
}
|
||||
require('core-js/es/symbol/index');
|
||||
})();
|
||||
|
||||
// Provides support for String.prototype.padStart in legacy browsers.
|
||||
// Support: IE, Chrome<57
|
||||
(function checkStringPadStart() {
|
||||
if (String.prototype.padStart) {
|
||||
return;
|
||||
}
|
||||
require('core-js/es/string/pad-start');
|
||||
})();
|
||||
|
||||
// Provides support for String.prototype.padEnd in legacy browsers.
|
||||
// Support: IE, Chrome<57
|
||||
(function checkStringPadEnd() {
|
||||
if (String.prototype.padEnd) {
|
||||
return;
|
||||
}
|
||||
require('core-js/es/string/pad-end');
|
||||
})();
|
||||
|
||||
// Provides support for Object.values in legacy browsers.
|
||||
// Support: IE, Chrome<54
|
||||
(function checkObjectValues() {
|
||||
if (Object.values) {
|
||||
return;
|
||||
}
|
||||
Object.values = require('core-js/es/object/values');
|
||||
})();
|
||||
if (
|
||||
(typeof PDFJSDev === "undefined" || !PDFJSDev.test("SKIP_BABEL")) &&
|
||||
(typeof globalThis === "undefined" || !globalThis._pdfjsCompatibilityChecked)
|
||||
) {
|
||||
// Provides support for globalThis in legacy browsers.
|
||||
// Support: IE11/Edge, Opera
|
||||
if (typeof globalThis === "undefined" || globalThis.Math !== Math) {
|
||||
// eslint-disable-next-line no-global-assign
|
||||
globalThis = require("core-js/es/global-this");
|
||||
}
|
||||
globalThis._pdfjsCompatibilityChecked = true;
|
||||
|
||||
const { isNodeJS } = require("./is_node");
|
||||
|
||||
const hasDOM = typeof window === "object" && typeof document === "object";
|
||||
const userAgent =
|
||||
(typeof navigator !== "undefined" && navigator.userAgent) || "";
|
||||
const isIE = /Trident/.test(userAgent);
|
||||
|
||||
// Support: Node.js
|
||||
(function checkNodeBtoa() {
|
||||
if (globalThis.btoa || !isNodeJS) {
|
||||
return;
|
||||
}
|
||||
globalThis.btoa = function(chars) {
|
||||
// eslint-disable-next-line no-undef
|
||||
return Buffer.from(chars, "binary").toString("base64");
|
||||
};
|
||||
})();
|
||||
|
||||
// Support: Node.js
|
||||
(function checkNodeAtob() {
|
||||
if (globalThis.atob || !isNodeJS) {
|
||||
return;
|
||||
}
|
||||
globalThis.atob = function(input) {
|
||||
// eslint-disable-next-line no-undef
|
||||
return Buffer.from(input, "base64").toString("binary");
|
||||
};
|
||||
})();
|
||||
|
||||
// Provides support for ChildNode.remove in legacy browsers.
|
||||
// Support: IE.
|
||||
(function checkChildNodeRemove() {
|
||||
if (!hasDOM) {
|
||||
return;
|
||||
}
|
||||
if (typeof Element.prototype.remove !== "undefined") {
|
||||
return;
|
||||
}
|
||||
Element.prototype.remove = function() {
|
||||
if (this.parentNode) {
|
||||
// eslint-disable-next-line mozilla/avoid-removeChild
|
||||
this.parentNode.removeChild(this);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
// Provides support for DOMTokenList.prototype.{add, remove}, with more than
|
||||
// one parameter, in legacy browsers.
|
||||
// Support: IE
|
||||
(function checkDOMTokenListAddRemove() {
|
||||
if (!hasDOM || isNodeJS) {
|
||||
return;
|
||||
}
|
||||
const div = document.createElement("div");
|
||||
div.classList.add("testOne", "testTwo");
|
||||
|
||||
if (
|
||||
div.classList.contains("testOne") === true &&
|
||||
div.classList.contains("testTwo") === true
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const OriginalDOMTokenListAdd = DOMTokenList.prototype.add;
|
||||
const OriginalDOMTokenListRemove = DOMTokenList.prototype.remove;
|
||||
|
||||
DOMTokenList.prototype.add = function(...tokens) {
|
||||
for (let token of tokens) {
|
||||
OriginalDOMTokenListAdd.call(this, token);
|
||||
}
|
||||
};
|
||||
DOMTokenList.prototype.remove = function(...tokens) {
|
||||
for (let token of tokens) {
|
||||
OriginalDOMTokenListRemove.call(this, token);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
// Provides support for DOMTokenList.prototype.toggle, with the optional
|
||||
// "force" parameter, in legacy browsers.
|
||||
// Support: IE
|
||||
(function checkDOMTokenListToggle() {
|
||||
if (!hasDOM || isNodeJS) {
|
||||
return;
|
||||
}
|
||||
const div = document.createElement("div");
|
||||
if (div.classList.toggle("test", 0) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
DOMTokenList.prototype.toggle = function(token) {
|
||||
let force = arguments.length > 1 ? !!arguments[1] : !this.contains(token);
|
||||
return this[force ? "add" : "remove"](token), force;
|
||||
};
|
||||
})();
|
||||
|
||||
// Provides support for window.history.{pushState, replaceState}, with the
|
||||
// `url` parameter set to `undefined`, without breaking the document URL.
|
||||
// Support: IE
|
||||
(function checkWindowHistoryPushStateReplaceState() {
|
||||
if (!hasDOM || !isIE) {
|
||||
return;
|
||||
}
|
||||
const OriginalPushState = window.history.pushState;
|
||||
const OriginalReplaceState = window.history.replaceState;
|
||||
|
||||
window.history.pushState = function(state, title, url) {
|
||||
const args = url === undefined ? [state, title] : [state, title, url];
|
||||
OriginalPushState.apply(this, args);
|
||||
};
|
||||
window.history.replaceState = function(state, title, url) {
|
||||
const args = url === undefined ? [state, title] : [state, title, url];
|
||||
OriginalReplaceState.apply(this, args);
|
||||
};
|
||||
})();
|
||||
|
||||
// Provides support for String.prototype.startsWith in legacy browsers.
|
||||
// Support: IE, Chrome<41
|
||||
(function checkStringStartsWith() {
|
||||
if (String.prototype.startsWith) {
|
||||
return;
|
||||
}
|
||||
require("core-js/es/string/starts-with");
|
||||
})();
|
||||
|
||||
// Provides support for String.prototype.endsWith in legacy browsers.
|
||||
// Support: IE, Chrome<41
|
||||
(function checkStringEndsWith() {
|
||||
if (String.prototype.endsWith) {
|
||||
return;
|
||||
}
|
||||
require("core-js/es/string/ends-with");
|
||||
})();
|
||||
|
||||
// Provides support for String.prototype.includes in legacy browsers.
|
||||
// Support: IE, Chrome<41
|
||||
(function checkStringIncludes() {
|
||||
if (String.prototype.includes) {
|
||||
return;
|
||||
}
|
||||
require("core-js/es/string/includes");
|
||||
})();
|
||||
|
||||
// Provides support for Array.prototype.includes in legacy browsers.
|
||||
// Support: IE, Chrome<47
|
||||
(function checkArrayIncludes() {
|
||||
if (Array.prototype.includes) {
|
||||
return;
|
||||
}
|
||||
require("core-js/es/array/includes");
|
||||
})();
|
||||
|
||||
// Provides support for Array.from in legacy browsers.
|
||||
// Support: IE
|
||||
(function checkArrayFrom() {
|
||||
if (Array.from) {
|
||||
return;
|
||||
}
|
||||
require("core-js/es/array/from");
|
||||
})();
|
||||
|
||||
// Provides support for Object.assign in legacy browsers.
|
||||
// Support: IE
|
||||
(function checkObjectAssign() {
|
||||
if (Object.assign) {
|
||||
return;
|
||||
}
|
||||
require("core-js/es/object/assign");
|
||||
})();
|
||||
|
||||
// Provides support for Math.log2 in legacy browsers.
|
||||
// Support: IE, Chrome<38
|
||||
(function checkMathLog2() {
|
||||
if (Math.log2) {
|
||||
return;
|
||||
}
|
||||
Math.log2 = require("core-js/es/math/log2");
|
||||
})();
|
||||
|
||||
// Provides support for Number.isNaN in legacy browsers.
|
||||
// Support: IE.
|
||||
(function checkNumberIsNaN() {
|
||||
if (Number.isNaN) {
|
||||
return;
|
||||
}
|
||||
Number.isNaN = require("core-js/es/number/is-nan");
|
||||
})();
|
||||
|
||||
// Provides support for Number.isInteger in legacy browsers.
|
||||
// Support: IE, Chrome<34
|
||||
(function checkNumberIsInteger() {
|
||||
if (Number.isInteger) {
|
||||
return;
|
||||
}
|
||||
Number.isInteger = require("core-js/es/number/is-integer");
|
||||
})();
|
||||
|
||||
// Support: IE, Safari<11, Chrome<63
|
||||
(function checkPromise() {
|
||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("IMAGE_DECODERS")) {
|
||||
// The current image decoders are synchronous, hence `Promise` shouldn't
|
||||
// need to be polyfilled for the IMAGE_DECODERS build target.
|
||||
return;
|
||||
}
|
||||
if (
|
||||
globalThis.Promise &&
|
||||
globalThis.Promise.prototype &&
|
||||
globalThis.Promise.prototype.finally
|
||||
) {
|
||||
return;
|
||||
}
|
||||
globalThis.Promise = require("core-js/es/promise/index");
|
||||
})();
|
||||
|
||||
// Support: IE
|
||||
(function checkURL() {
|
||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("IMAGE_DECODERS")) {
|
||||
// The current image decoders don't use the `URL` constructor, so it
|
||||
// doesn't need to be polyfilled for the IMAGE_DECODERS build target.
|
||||
return;
|
||||
}
|
||||
if (typeof PDFJSDev !== "undefined" && !PDFJSDev.test("GENERIC")) {
|
||||
// The `URL` constructor is assumed to be available in the extension builds.
|
||||
return;
|
||||
}
|
||||
globalThis.URL = require("core-js/web/url");
|
||||
})();
|
||||
|
||||
// Support: IE, Node.js
|
||||
(function checkReadableStream() {
|
||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("IMAGE_DECODERS")) {
|
||||
// The current image decoders are synchronous, hence `ReadableStream`
|
||||
// shouldn't need to be polyfilled for the IMAGE_DECODERS build target.
|
||||
return;
|
||||
}
|
||||
let isReadableStreamSupported = false;
|
||||
|
||||
if (typeof ReadableStream !== "undefined") {
|
||||
// MS Edge may say it has ReadableStream but they are not up to spec yet.
|
||||
try {
|
||||
// eslint-disable-next-line no-new
|
||||
new ReadableStream({
|
||||
start(controller) {
|
||||
controller.close();
|
||||
},
|
||||
});
|
||||
isReadableStreamSupported = true;
|
||||
} catch (e) {
|
||||
// The ReadableStream constructor cannot be used.
|
||||
}
|
||||
}
|
||||
if (isReadableStreamSupported) {
|
||||
return;
|
||||
}
|
||||
globalThis.ReadableStream = require("web-streams-polyfill/dist/ponyfill").ReadableStream;
|
||||
})();
|
||||
|
||||
// Support: IE<11, Safari<8, Chrome<36
|
||||
(function checkWeakMap() {
|
||||
if (globalThis.WeakMap) {
|
||||
return;
|
||||
}
|
||||
globalThis.WeakMap = require("core-js/es/weak-map/index");
|
||||
})();
|
||||
|
||||
// Support: IE11
|
||||
(function checkWeakSet() {
|
||||
if (globalThis.WeakSet) {
|
||||
return;
|
||||
}
|
||||
globalThis.WeakSet = require("core-js/es/weak-set/index");
|
||||
})();
|
||||
|
||||
// Provides support for String.codePointAt in legacy browsers.
|
||||
// Support: IE11.
|
||||
(function checkStringCodePointAt() {
|
||||
if (String.prototype.codePointAt) {
|
||||
return;
|
||||
}
|
||||
require("core-js/es/string/code-point-at");
|
||||
})();
|
||||
|
||||
// Provides support for String.fromCodePoint in legacy browsers.
|
||||
// Support: IE11.
|
||||
(function checkStringFromCodePoint() {
|
||||
if (String.fromCodePoint) {
|
||||
return;
|
||||
}
|
||||
String.fromCodePoint = require("core-js/es/string/from-code-point");
|
||||
})();
|
||||
|
||||
// Support: IE
|
||||
(function checkSymbol() {
|
||||
if (globalThis.Symbol) {
|
||||
return;
|
||||
}
|
||||
require("core-js/es/symbol/index");
|
||||
})();
|
||||
|
||||
// Provides support for String.prototype.padStart in legacy browsers.
|
||||
// Support: IE, Chrome<57
|
||||
(function checkStringPadStart() {
|
||||
if (String.prototype.padStart) {
|
||||
return;
|
||||
}
|
||||
require("core-js/es/string/pad-start");
|
||||
})();
|
||||
|
||||
// Provides support for String.prototype.padEnd in legacy browsers.
|
||||
// Support: IE, Chrome<57
|
||||
(function checkStringPadEnd() {
|
||||
if (String.prototype.padEnd) {
|
||||
return;
|
||||
}
|
||||
require("core-js/es/string/pad-end");
|
||||
})();
|
||||
|
||||
// Provides support for Object.values in legacy browsers.
|
||||
// Support: IE, Chrome<54
|
||||
(function checkObjectValues() {
|
||||
if (Object.values) {
|
||||
return;
|
||||
}
|
||||
Object.values = require("core-js/es/object/values");
|
||||
})();
|
||||
}
|
||||
|
|
|
@ -18,10 +18,9 @@
|
|||
// http://docs.nwjs.io/en/latest/For%20Users/Advanced/JavaScript%20Contexts%20in%20NW.js/#access-nodejs-and-nwjs-api-in-browser-context
|
||||
// https://electronjs.org/docs/api/process#processversionselectron
|
||||
const isNodeJS =
|
||||
typeof process === 'object' &&
|
||||
process + '' === '[object process]' &&
|
||||
!process.versions['nw'] && !process.versions['electron'];
|
||||
typeof process === "object" &&
|
||||
process + "" === "[object process]" &&
|
||||
!process.versions["nw"] &&
|
||||
!process.versions["electron"];
|
||||
|
||||
export {
|
||||
isNodeJS,
|
||||
};
|
||||
export { isNodeJS };
|
||||
|
|
|
@ -15,9 +15,13 @@
|
|||
/* eslint no-var: error, prefer-const: error */
|
||||
|
||||
import {
|
||||
AbortException, assert, createPromiseCapability, MissingPDFException,
|
||||
UnexpectedResponseException, UnknownErrorException
|
||||
} from './util';
|
||||
AbortException,
|
||||
assert,
|
||||
createPromiseCapability,
|
||||
MissingPDFException,
|
||||
UnexpectedResponseException,
|
||||
UnknownErrorException,
|
||||
} from "./util";
|
||||
|
||||
const CallbackKind = {
|
||||
UNKNOWN: 0,
|
||||
|
@ -38,23 +42,27 @@ const StreamKind = {
|
|||
};
|
||||
|
||||
function wrapReason(reason) {
|
||||
if (typeof PDFJSDev === 'undefined' ||
|
||||
PDFJSDev.test('!PRODUCTION || TESTING')) {
|
||||
assert(reason instanceof Error ||
|
||||
(typeof reason === 'object' && reason !== null),
|
||||
'wrapReason: Expected "reason" to be a (possibly cloned) Error.');
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(
|
||||
reason instanceof Error ||
|
||||
(typeof reason === "object" && reason !== null),
|
||||
'wrapReason: Expected "reason" to be a (possibly cloned) Error.'
|
||||
);
|
||||
}
|
||||
if (typeof reason !== 'object' || reason === null) {
|
||||
if (typeof reason !== "object" || reason === null) {
|
||||
return reason;
|
||||
}
|
||||
switch (reason.name) {
|
||||
case 'AbortException':
|
||||
case "AbortException":
|
||||
return new AbortException(reason.message);
|
||||
case 'MissingPDFException':
|
||||
case "MissingPDFException":
|
||||
return new MissingPDFException(reason.message);
|
||||
case 'UnexpectedResponseException':
|
||||
case "UnexpectedResponseException":
|
||||
return new UnexpectedResponseException(reason.message, reason.status);
|
||||
case 'UnknownErrorException':
|
||||
case "UnknownErrorException":
|
||||
return new UnknownErrorException(reason.message, reason.details);
|
||||
default:
|
||||
return new UnknownErrorException(reason.message, reason.toString());
|
||||
|
@ -74,7 +82,7 @@ class MessageHandler {
|
|||
this.callbackCapabilities = Object.create(null);
|
||||
this.actionHandler = Object.create(null);
|
||||
|
||||
this._onComObjOnMessage = (event) => {
|
||||
this._onComObjOnMessage = event => {
|
||||
const data = event.data;
|
||||
if (data.targetName !== this.sourceName) {
|
||||
return;
|
||||
|
@ -96,7 +104,7 @@ class MessageHandler {
|
|||
} else if (data.callback === CallbackKind.ERROR) {
|
||||
capability.reject(wrapReason(data.reason));
|
||||
} else {
|
||||
throw new Error('Unexpected callback case');
|
||||
throw new Error("Unexpected callback case");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -109,23 +117,26 @@ class MessageHandler {
|
|||
const targetName = data.sourceName;
|
||||
new Promise(function(resolve) {
|
||||
resolve(action(data.data));
|
||||
}).then(function(result) {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
callback: CallbackKind.DATA,
|
||||
callbackId: data.callbackId,
|
||||
data: result,
|
||||
});
|
||||
}, function(reason) {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
callback: CallbackKind.ERROR,
|
||||
callbackId: data.callbackId,
|
||||
reason: wrapReason(reason),
|
||||
});
|
||||
});
|
||||
}).then(
|
||||
function(result) {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
callback: CallbackKind.DATA,
|
||||
callbackId: data.callbackId,
|
||||
data: result,
|
||||
});
|
||||
},
|
||||
function(reason) {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
callback: CallbackKind.ERROR,
|
||||
callbackId: data.callbackId,
|
||||
reason: wrapReason(reason),
|
||||
});
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (data.streamId) {
|
||||
|
@ -134,14 +145,18 @@ class MessageHandler {
|
|||
}
|
||||
action(data.data);
|
||||
};
|
||||
comObj.addEventListener('message', this._onComObjOnMessage);
|
||||
comObj.addEventListener("message", this._onComObjOnMessage);
|
||||
}
|
||||
|
||||
on(actionName, handler) {
|
||||
if (typeof PDFJSDev === 'undefined' ||
|
||||
PDFJSDev.test('!PRODUCTION || TESTING')) {
|
||||
assert(typeof handler === 'function',
|
||||
'MessageHandler.on: Expected "handler" to be a function.');
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(
|
||||
typeof handler === "function",
|
||||
'MessageHandler.on: Expected "handler" to be a function.'
|
||||
);
|
||||
}
|
||||
const ah = this.actionHandler;
|
||||
if (ah[actionName]) {
|
||||
|
@ -157,12 +172,15 @@ class MessageHandler {
|
|||
* @param {Array} [transfers] - List of transfers/ArrayBuffers.
|
||||
*/
|
||||
send(actionName, data, transfers) {
|
||||
this._postMessage({
|
||||
sourceName: this.sourceName,
|
||||
targetName: this.targetName,
|
||||
action: actionName,
|
||||
data,
|
||||
}, transfers);
|
||||
this._postMessage(
|
||||
{
|
||||
sourceName: this.sourceName,
|
||||
targetName: this.targetName,
|
||||
action: actionName,
|
||||
data,
|
||||
},
|
||||
transfers
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -178,13 +196,16 @@ class MessageHandler {
|
|||
const capability = createPromiseCapability();
|
||||
this.callbackCapabilities[callbackId] = capability;
|
||||
try {
|
||||
this._postMessage({
|
||||
sourceName: this.sourceName,
|
||||
targetName: this.targetName,
|
||||
action: actionName,
|
||||
callbackId,
|
||||
data,
|
||||
}, transfers);
|
||||
this._postMessage(
|
||||
{
|
||||
sourceName: this.sourceName,
|
||||
targetName: this.targetName,
|
||||
action: actionName,
|
||||
callbackId,
|
||||
data,
|
||||
},
|
||||
transfers
|
||||
);
|
||||
} catch (ex) {
|
||||
capability.reject(ex);
|
||||
}
|
||||
|
@ -207,59 +228,65 @@ class MessageHandler {
|
|||
const targetName = this.targetName;
|
||||
const comObj = this.comObj;
|
||||
|
||||
return new ReadableStream({
|
||||
start: (controller) => {
|
||||
const startCapability = createPromiseCapability();
|
||||
this.streamControllers[streamId] = {
|
||||
controller,
|
||||
startCall: startCapability,
|
||||
pullCall: null,
|
||||
cancelCall: null,
|
||||
isClosed: false,
|
||||
};
|
||||
this._postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
action: actionName,
|
||||
streamId,
|
||||
data,
|
||||
desiredSize: controller.desiredSize,
|
||||
}, transfers);
|
||||
// Return Promise for Async process, to signal success/failure.
|
||||
return startCapability.promise;
|
||||
},
|
||||
return new ReadableStream(
|
||||
{
|
||||
start: controller => {
|
||||
const startCapability = createPromiseCapability();
|
||||
this.streamControllers[streamId] = {
|
||||
controller,
|
||||
startCall: startCapability,
|
||||
pullCall: null,
|
||||
cancelCall: null,
|
||||
isClosed: false,
|
||||
};
|
||||
this._postMessage(
|
||||
{
|
||||
sourceName,
|
||||
targetName,
|
||||
action: actionName,
|
||||
streamId,
|
||||
data,
|
||||
desiredSize: controller.desiredSize,
|
||||
},
|
||||
transfers
|
||||
);
|
||||
// Return Promise for Async process, to signal success/failure.
|
||||
return startCapability.promise;
|
||||
},
|
||||
|
||||
pull: (controller) => {
|
||||
const pullCapability = createPromiseCapability();
|
||||
this.streamControllers[streamId].pullCall = pullCapability;
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.PULL,
|
||||
streamId,
|
||||
desiredSize: controller.desiredSize,
|
||||
});
|
||||
// Returning Promise will not call "pull"
|
||||
// again until current pull is resolved.
|
||||
return pullCapability.promise;
|
||||
},
|
||||
pull: controller => {
|
||||
const pullCapability = createPromiseCapability();
|
||||
this.streamControllers[streamId].pullCall = pullCapability;
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.PULL,
|
||||
streamId,
|
||||
desiredSize: controller.desiredSize,
|
||||
});
|
||||
// Returning Promise will not call "pull"
|
||||
// again until current pull is resolved.
|
||||
return pullCapability.promise;
|
||||
},
|
||||
|
||||
cancel: (reason) => {
|
||||
assert(reason instanceof Error, 'cancel must have a valid reason');
|
||||
const cancelCapability = createPromiseCapability();
|
||||
this.streamControllers[streamId].cancelCall = cancelCapability;
|
||||
this.streamControllers[streamId].isClosed = true;
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.CANCEL,
|
||||
streamId,
|
||||
reason: wrapReason(reason),
|
||||
});
|
||||
// Return Promise to signal success or failure.
|
||||
return cancelCapability.promise;
|
||||
cancel: reason => {
|
||||
assert(reason instanceof Error, "cancel must have a valid reason");
|
||||
const cancelCapability = createPromiseCapability();
|
||||
this.streamControllers[streamId].cancelCall = cancelCapability;
|
||||
this.streamControllers[streamId].isClosed = true;
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.CANCEL,
|
||||
streamId,
|
||||
reason: wrapReason(reason),
|
||||
});
|
||||
// Return Promise to signal success or failure.
|
||||
return cancelCapability.promise;
|
||||
},
|
||||
},
|
||||
}, queueingStrategy);
|
||||
queueingStrategy
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -287,13 +314,16 @@ class MessageHandler {
|
|||
this.sinkCapability = createPromiseCapability();
|
||||
this.ready = this.sinkCapability.promise;
|
||||
}
|
||||
self._postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.ENQUEUE,
|
||||
streamId,
|
||||
chunk,
|
||||
}, transfers);
|
||||
self._postMessage(
|
||||
{
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.ENQUEUE,
|
||||
streamId,
|
||||
chunk,
|
||||
},
|
||||
transfers
|
||||
);
|
||||
},
|
||||
|
||||
close() {
|
||||
|
@ -311,7 +341,7 @@ class MessageHandler {
|
|||
},
|
||||
|
||||
error(reason) {
|
||||
assert(reason instanceof Error, 'error must have a valid reason');
|
||||
assert(reason instanceof Error, "error must have a valid reason");
|
||||
if (this.isCancelled) {
|
||||
return;
|
||||
}
|
||||
|
@ -338,23 +368,26 @@ class MessageHandler {
|
|||
this.streamSinks[streamId] = streamSink;
|
||||
new Promise(function(resolve) {
|
||||
resolve(action(data.data, streamSink));
|
||||
}).then(function() {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.START_COMPLETE,
|
||||
streamId,
|
||||
success: true,
|
||||
});
|
||||
}, function(reason) {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.START_COMPLETE,
|
||||
streamId,
|
||||
reason: wrapReason(reason),
|
||||
});
|
||||
});
|
||||
}).then(
|
||||
function() {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.START_COMPLETE,
|
||||
streamId,
|
||||
success: true,
|
||||
});
|
||||
},
|
||||
function(reason) {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.START_COMPLETE,
|
||||
streamId,
|
||||
reason: wrapReason(reason),
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -372,7 +405,8 @@ class MessageHandler {
|
|||
this.streamControllers[streamId].startCall.resolve();
|
||||
} else {
|
||||
this.streamControllers[streamId].startCall.reject(
|
||||
wrapReason(data.reason));
|
||||
wrapReason(data.reason)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case StreamKind.PULL_COMPLETE:
|
||||
|
@ -380,7 +414,8 @@ class MessageHandler {
|
|||
this.streamControllers[streamId].pullCall.resolve();
|
||||
} else {
|
||||
this.streamControllers[streamId].pullCall.reject(
|
||||
wrapReason(data.reason));
|
||||
wrapReason(data.reason)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case StreamKind.PULL:
|
||||
|
@ -398,44 +433,53 @@ class MessageHandler {
|
|||
// Pull increases the desiredSize property of sink,
|
||||
// so when it changes from negative to positive,
|
||||
// set ready property as resolved promise.
|
||||
if (this.streamSinks[streamId].desiredSize <= 0 &&
|
||||
data.desiredSize > 0) {
|
||||
if (
|
||||
this.streamSinks[streamId].desiredSize <= 0 &&
|
||||
data.desiredSize > 0
|
||||
) {
|
||||
this.streamSinks[streamId].sinkCapability.resolve();
|
||||
}
|
||||
// Reset desiredSize property of sink on every pull.
|
||||
this.streamSinks[streamId].desiredSize = data.desiredSize;
|
||||
const { onPull, } = this.streamSinks[data.streamId];
|
||||
const { onPull } = this.streamSinks[data.streamId];
|
||||
new Promise(function(resolve) {
|
||||
resolve(onPull && onPull());
|
||||
}).then(function() {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.PULL_COMPLETE,
|
||||
streamId,
|
||||
success: true,
|
||||
});
|
||||
}, function(reason) {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.PULL_COMPLETE,
|
||||
streamId,
|
||||
reason: wrapReason(reason),
|
||||
});
|
||||
});
|
||||
}).then(
|
||||
function() {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.PULL_COMPLETE,
|
||||
streamId,
|
||||
success: true,
|
||||
});
|
||||
},
|
||||
function(reason) {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.PULL_COMPLETE,
|
||||
streamId,
|
||||
reason: wrapReason(reason),
|
||||
});
|
||||
}
|
||||
);
|
||||
break;
|
||||
case StreamKind.ENQUEUE:
|
||||
assert(this.streamControllers[streamId],
|
||||
'enqueue should have stream controller');
|
||||
assert(
|
||||
this.streamControllers[streamId],
|
||||
"enqueue should have stream controller"
|
||||
);
|
||||
if (this.streamControllers[streamId].isClosed) {
|
||||
break;
|
||||
}
|
||||
this.streamControllers[streamId].controller.enqueue(data.chunk);
|
||||
break;
|
||||
case StreamKind.CLOSE:
|
||||
assert(this.streamControllers[streamId],
|
||||
'close should have stream controller');
|
||||
assert(
|
||||
this.streamControllers[streamId],
|
||||
"close should have stream controller"
|
||||
);
|
||||
if (this.streamControllers[streamId].isClosed) {
|
||||
break;
|
||||
}
|
||||
|
@ -444,10 +488,13 @@ class MessageHandler {
|
|||
this._deleteStreamController(streamId);
|
||||
break;
|
||||
case StreamKind.ERROR:
|
||||
assert(this.streamControllers[streamId],
|
||||
'error should have stream controller');
|
||||
assert(
|
||||
this.streamControllers[streamId],
|
||||
"error should have stream controller"
|
||||
);
|
||||
this.streamControllers[streamId].controller.error(
|
||||
wrapReason(data.reason));
|
||||
wrapReason(data.reason)
|
||||
);
|
||||
this._deleteStreamController(streamId);
|
||||
break;
|
||||
case StreamKind.CANCEL_COMPLETE:
|
||||
|
@ -455,7 +502,8 @@ class MessageHandler {
|
|||
this.streamControllers[streamId].cancelCall.resolve();
|
||||
} else {
|
||||
this.streamControllers[streamId].cancelCall.reject(
|
||||
wrapReason(data.reason));
|
||||
wrapReason(data.reason)
|
||||
);
|
||||
}
|
||||
this._deleteStreamController(streamId);
|
||||
break;
|
||||
|
@ -463,33 +511,37 @@ class MessageHandler {
|
|||
if (!this.streamSinks[streamId]) {
|
||||
break;
|
||||
}
|
||||
const { onCancel, } = this.streamSinks[data.streamId];
|
||||
const { onCancel } = this.streamSinks[data.streamId];
|
||||
new Promise(function(resolve) {
|
||||
resolve(onCancel && onCancel(wrapReason(data.reason)));
|
||||
}).then(function() {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.CANCEL_COMPLETE,
|
||||
streamId,
|
||||
success: true,
|
||||
});
|
||||
}, function(reason) {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.CANCEL_COMPLETE,
|
||||
streamId,
|
||||
reason: wrapReason(reason),
|
||||
});
|
||||
});
|
||||
}).then(
|
||||
function() {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.CANCEL_COMPLETE,
|
||||
streamId,
|
||||
success: true,
|
||||
});
|
||||
},
|
||||
function(reason) {
|
||||
comObj.postMessage({
|
||||
sourceName,
|
||||
targetName,
|
||||
stream: StreamKind.CANCEL_COMPLETE,
|
||||
streamId,
|
||||
reason: wrapReason(reason),
|
||||
});
|
||||
}
|
||||
);
|
||||
this.streamSinks[streamId].sinkCapability.reject(
|
||||
wrapReason(data.reason));
|
||||
wrapReason(data.reason)
|
||||
);
|
||||
this.streamSinks[streamId].isCancelled = true;
|
||||
delete this.streamSinks[streamId];
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unexpected stream case');
|
||||
throw new Error("Unexpected stream case");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -499,13 +551,15 @@ class MessageHandler {
|
|||
async _deleteStreamController(streamId) {
|
||||
// Delete the `streamController` only when the start, pull, and cancel
|
||||
// capabilities have settled, to prevent `TypeError`s.
|
||||
await Promise.all([
|
||||
this.streamControllers[streamId].startCall,
|
||||
this.streamControllers[streamId].pullCall,
|
||||
this.streamControllers[streamId].cancelCall
|
||||
].map(function(capability) {
|
||||
return capability && capability.promise.catch(function() { });
|
||||
}));
|
||||
await Promise.all(
|
||||
[
|
||||
this.streamControllers[streamId].startCall,
|
||||
this.streamControllers[streamId].pullCall,
|
||||
this.streamControllers[streamId].cancelCall,
|
||||
].map(function(capability) {
|
||||
return capability && capability.promise.catch(function() {});
|
||||
})
|
||||
);
|
||||
delete this.streamControllers[streamId];
|
||||
}
|
||||
|
||||
|
@ -524,10 +578,8 @@ class MessageHandler {
|
|||
}
|
||||
|
||||
destroy() {
|
||||
this.comObj.removeEventListener('message', this._onComObjOnMessage);
|
||||
this.comObj.removeEventListener("message", this._onComObjOnMessage);
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
MessageHandler,
|
||||
};
|
||||
export { MessageHandler };
|
||||
|
|
|
@ -14,15 +14,15 @@
|
|||
*/
|
||||
/* eslint no-var: error */
|
||||
|
||||
import './compatibility';
|
||||
import "./compatibility";
|
||||
|
||||
const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
|
||||
const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
|
||||
|
||||
const NativeImageDecoding = {
|
||||
NONE: 'none',
|
||||
DECODE: 'decode',
|
||||
DISPLAY: 'display',
|
||||
NONE: "none",
|
||||
DECODE: "decode",
|
||||
DISPLAY: "display",
|
||||
};
|
||||
|
||||
// Permission flags from Table 22, Section 7.6.3.2 of the PDF specification.
|
||||
|
@ -86,26 +86,26 @@ const AnnotationType = {
|
|||
};
|
||||
|
||||
const AnnotationStateModelType = {
|
||||
MARKED: 'Marked',
|
||||
REVIEW: 'Review',
|
||||
MARKED: "Marked",
|
||||
REVIEW: "Review",
|
||||
};
|
||||
|
||||
const AnnotationMarkedState = {
|
||||
MARKED: 'Marked',
|
||||
UNMARKED: 'Unmarked',
|
||||
MARKED: "Marked",
|
||||
UNMARKED: "Unmarked",
|
||||
};
|
||||
|
||||
const AnnotationReviewState = {
|
||||
ACCEPTED: 'Accepted',
|
||||
REJECTED: 'Rejected',
|
||||
CANCELLED: 'Cancelled',
|
||||
COMPLETED: 'Completed',
|
||||
NONE: 'None',
|
||||
ACCEPTED: "Accepted",
|
||||
REJECTED: "Rejected",
|
||||
CANCELLED: "Cancelled",
|
||||
COMPLETED: "Completed",
|
||||
NONE: "None",
|
||||
};
|
||||
|
||||
const AnnotationReplyType = {
|
||||
GROUP: 'Group',
|
||||
REPLY: 'R',
|
||||
GROUP: "Group",
|
||||
REPLY: "R",
|
||||
};
|
||||
|
||||
const AnnotationFlag = {
|
||||
|
@ -152,30 +152,30 @@ const AnnotationBorderStyleType = {
|
|||
};
|
||||
|
||||
const StreamType = {
|
||||
UNKNOWN: 'UNKNOWN',
|
||||
FLATE: 'FLATE',
|
||||
LZW: 'LZW',
|
||||
DCT: 'DCT',
|
||||
JPX: 'JPX',
|
||||
JBIG: 'JBIG',
|
||||
A85: 'A85',
|
||||
AHX: 'AHX',
|
||||
CCF: 'CCF',
|
||||
RLX: 'RLX', // PDF short name is 'RL', but telemetry requires three chars.
|
||||
UNKNOWN: "UNKNOWN",
|
||||
FLATE: "FLATE",
|
||||
LZW: "LZW",
|
||||
DCT: "DCT",
|
||||
JPX: "JPX",
|
||||
JBIG: "JBIG",
|
||||
A85: "A85",
|
||||
AHX: "AHX",
|
||||
CCF: "CCF",
|
||||
RLX: "RLX", // PDF short name is 'RL', but telemetry requires three chars.
|
||||
};
|
||||
|
||||
const FontType = {
|
||||
UNKNOWN: 'UNKNOWN',
|
||||
TYPE1: 'TYPE1',
|
||||
TYPE1C: 'TYPE1C',
|
||||
CIDFONTTYPE0: 'CIDFONTTYPE0',
|
||||
CIDFONTTYPE0C: 'CIDFONTTYPE0C',
|
||||
TRUETYPE: 'TRUETYPE',
|
||||
CIDFONTTYPE2: 'CIDFONTTYPE2',
|
||||
TYPE3: 'TYPE3',
|
||||
OPENTYPE: 'OPENTYPE',
|
||||
TYPE0: 'TYPE0',
|
||||
MMTYPE1: 'MMTYPE1',
|
||||
UNKNOWN: "UNKNOWN",
|
||||
TYPE1: "TYPE1",
|
||||
TYPE1C: "TYPE1C",
|
||||
CIDFONTTYPE0: "CIDFONTTYPE0",
|
||||
CIDFONTTYPE0C: "CIDFONTTYPE0C",
|
||||
TRUETYPE: "TRUETYPE",
|
||||
CIDFONTTYPE2: "CIDFONTTYPE2",
|
||||
TYPE3: "TYPE3",
|
||||
OPENTYPE: "OPENTYPE",
|
||||
TYPE0: "TYPE0",
|
||||
MMTYPE1: "MMTYPE1",
|
||||
};
|
||||
|
||||
const VerbosityLevel = {
|
||||
|
@ -288,12 +288,12 @@ const OPS = {
|
|||
};
|
||||
|
||||
const UNSUPPORTED_FEATURES = {
|
||||
unknown: 'unknown',
|
||||
forms: 'forms',
|
||||
javaScript: 'javaScript',
|
||||
smask: 'smask',
|
||||
shadingPattern: 'shadingPattern',
|
||||
font: 'font',
|
||||
unknown: "unknown",
|
||||
forms: "forms",
|
||||
javaScript: "javaScript",
|
||||
smask: "smask",
|
||||
shadingPattern: "shadingPattern",
|
||||
font: "font",
|
||||
};
|
||||
|
||||
const PasswordResponses = {
|
||||
|
@ -344,7 +344,7 @@ function isSameOrigin(baseUrl, otherUrl) {
|
|||
let base;
|
||||
try {
|
||||
base = new URL(baseUrl);
|
||||
if (!base.origin || base.origin === 'null') {
|
||||
if (!base.origin || base.origin === "null") {
|
||||
return false; // non-HTTP url
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -361,11 +361,11 @@ function _isValidProtocol(url) {
|
|||
return false;
|
||||
}
|
||||
switch (url.protocol) {
|
||||
case 'http:':
|
||||
case 'https:':
|
||||
case 'ftp:':
|
||||
case 'mailto:':
|
||||
case 'tel:':
|
||||
case "http:":
|
||||
case "https:":
|
||||
case "ftp:":
|
||||
case "mailto:":
|
||||
case "tel:":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -388,22 +388,26 @@ function createValidAbsoluteUrl(url, baseUrl) {
|
|||
if (_isValidProtocol(absoluteUrl)) {
|
||||
return absoluteUrl;
|
||||
}
|
||||
} catch (ex) { /* `new URL()` will throw on incorrect data. */ }
|
||||
} catch (ex) {
|
||||
/* `new URL()` will throw on incorrect data. */
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function shadow(obj, prop, value) {
|
||||
Object.defineProperty(obj, prop, { value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: false, });
|
||||
Object.defineProperty(obj, prop, {
|
||||
value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: false,
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
const BaseException = (function BaseExceptionClosure() {
|
||||
function BaseException(message) {
|
||||
if (this.constructor === BaseException) {
|
||||
unreachable('Cannot initialize BaseException.');
|
||||
unreachable("Cannot initialize BaseException.");
|
||||
}
|
||||
this.message = message;
|
||||
this.name = this.constructor.name;
|
||||
|
@ -428,9 +432,9 @@ class UnknownErrorException extends BaseException {
|
|||
}
|
||||
}
|
||||
|
||||
class InvalidPDFException extends BaseException { }
|
||||
class InvalidPDFException extends BaseException {}
|
||||
|
||||
class MissingPDFException extends BaseException { }
|
||||
class MissingPDFException extends BaseException {}
|
||||
|
||||
class UnexpectedResponseException extends BaseException {
|
||||
constructor(msg, status) {
|
||||
|
@ -442,26 +446,28 @@ class UnexpectedResponseException extends BaseException {
|
|||
/**
|
||||
* Error caused during parsing PDF data.
|
||||
*/
|
||||
class FormatError extends BaseException { }
|
||||
class FormatError extends BaseException {}
|
||||
|
||||
/**
|
||||
* Error used to indicate task cancellation.
|
||||
*/
|
||||
class AbortException extends BaseException { }
|
||||
class AbortException extends BaseException {}
|
||||
|
||||
const NullCharactersRegExp = /\x00/g;
|
||||
|
||||
function removeNullCharacters(str) {
|
||||
if (typeof str !== 'string') {
|
||||
warn('The argument for removeNullCharacters must be a string.');
|
||||
if (typeof str !== "string") {
|
||||
warn("The argument for removeNullCharacters must be a string.");
|
||||
return str;
|
||||
}
|
||||
return str.replace(NullCharactersRegExp, '');
|
||||
return str.replace(NullCharactersRegExp, "");
|
||||
}
|
||||
|
||||
function bytesToString(bytes) {
|
||||
assert(bytes !== null && typeof bytes === 'object' &&
|
||||
bytes.length !== undefined, 'Invalid argument for bytesToString');
|
||||
assert(
|
||||
bytes !== null && typeof bytes === "object" && bytes.length !== undefined,
|
||||
"Invalid argument for bytesToString"
|
||||
);
|
||||
const length = bytes.length;
|
||||
const MAX_ARGUMENT_COUNT = 8192;
|
||||
if (length < MAX_ARGUMENT_COUNT) {
|
||||
|
@ -473,15 +479,15 @@ function bytesToString(bytes) {
|
|||
const chunk = bytes.subarray(i, chunkEnd);
|
||||
strBuf.push(String.fromCharCode.apply(null, chunk));
|
||||
}
|
||||
return strBuf.join('');
|
||||
return strBuf.join("");
|
||||
}
|
||||
|
||||
function stringToBytes(str) {
|
||||
assert(typeof str === 'string', 'Invalid argument for stringToBytes');
|
||||
assert(typeof str === "string", "Invalid argument for stringToBytes");
|
||||
const length = str.length;
|
||||
const bytes = new Uint8Array(length);
|
||||
for (let i = 0; i < length; ++i) {
|
||||
bytes[i] = str.charCodeAt(i) & 0xFF;
|
||||
bytes[i] = str.charCodeAt(i) & 0xff;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
@ -507,7 +513,7 @@ function arrayByteLength(arr) {
|
|||
function arraysToBytes(arr) {
|
||||
const length = arr.length;
|
||||
// Shortcut: if first and only item is Uint8Array, return it.
|
||||
if (length === 1 && (arr[0] instanceof Uint8Array)) {
|
||||
if (length === 1 && arr[0] instanceof Uint8Array) {
|
||||
return arr[0];
|
||||
}
|
||||
let resultLength = 0;
|
||||
|
@ -519,7 +525,7 @@ function arraysToBytes(arr) {
|
|||
for (let i = 0; i < length; i++) {
|
||||
let item = arr[i];
|
||||
if (!(item instanceof Uint8Array)) {
|
||||
if (typeof item === 'string') {
|
||||
if (typeof item === "string") {
|
||||
item = stringToBytes(item);
|
||||
} else {
|
||||
item = new Uint8Array(item);
|
||||
|
@ -533,8 +539,12 @@ function arraysToBytes(arr) {
|
|||
}
|
||||
|
||||
function string32(value) {
|
||||
return String.fromCharCode((value >> 24) & 0xff, (value >> 16) & 0xff,
|
||||
(value >> 8) & 0xff, value & 0xff);
|
||||
return String.fromCharCode(
|
||||
(value >> 24) & 0xff,
|
||||
(value >> 16) & 0xff,
|
||||
(value >> 8) & 0xff,
|
||||
value & 0xff
|
||||
);
|
||||
}
|
||||
|
||||
// Calculate the base 2 logarithm of the number `x`. This differs from the
|
||||
|
@ -556,8 +566,13 @@ function readUint16(data, offset) {
|
|||
}
|
||||
|
||||
function readUint32(data, offset) {
|
||||
return ((data[offset] << 24) | (data[offset + 1] << 16) |
|
||||
(data[offset + 2] << 8) | data[offset + 3]) >>> 0;
|
||||
return (
|
||||
((data[offset] << 24) |
|
||||
(data[offset + 1] << 16) |
|
||||
(data[offset + 2] << 8) |
|
||||
data[offset + 3]) >>>
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
// Lazy test the endianness of the platform
|
||||
|
@ -566,20 +581,20 @@ function isLittleEndian() {
|
|||
const buffer8 = new Uint8Array(4);
|
||||
buffer8[0] = 1;
|
||||
const view32 = new Uint32Array(buffer8.buffer, 0, 1);
|
||||
return (view32[0] === 1);
|
||||
return view32[0] === 1;
|
||||
}
|
||||
|
||||
// Checks if it's possible to eval JS expressions.
|
||||
function isEvalSupported() {
|
||||
try {
|
||||
new Function(''); // eslint-disable-line no-new, no-new-func
|
||||
new Function(""); // eslint-disable-line no-new, no-new-func
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const rgbBuf = ['rgb(', 0, ',', 0, ',', 0, ')'];
|
||||
const rgbBuf = ["rgb(", 0, ",", 0, ",", 0, ")"];
|
||||
|
||||
class Util {
|
||||
// makeCssRgb() can be called thousands of times. Using ´rgbBuf` avoids
|
||||
|
@ -588,7 +603,7 @@ class Util {
|
|||
rgbBuf[1] = r;
|
||||
rgbBuf[3] = g;
|
||||
rgbBuf[5] = b;
|
||||
return rgbBuf.join('');
|
||||
return rgbBuf.join("");
|
||||
}
|
||||
|
||||
// Concatenates two transformation matrices together and returns the result.
|
||||
|
@ -599,7 +614,7 @@ class Util {
|
|||
m1[0] * m2[2] + m1[2] * m2[3],
|
||||
m1[1] * m2[2] + m1[3] * m2[3],
|
||||
m1[0] * m2[4] + m1[2] * m2[5] + m1[4],
|
||||
m1[1] * m2[4] + m1[3] * m2[5] + m1[5]
|
||||
m1[1] * m2[4] + m1[3] * m2[5] + m1[5],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -628,14 +643,20 @@ class Util {
|
|||
Math.min(p1[0], p2[0], p3[0], p4[0]),
|
||||
Math.min(p1[1], p2[1], p3[1], p4[1]),
|
||||
Math.max(p1[0], p2[0], p3[0], p4[0]),
|
||||
Math.max(p1[1], p2[1], p3[1], p4[1])
|
||||
Math.max(p1[1], p2[1], p3[1], p4[1]),
|
||||
];
|
||||
}
|
||||
|
||||
static inverseTransform(m) {
|
||||
const d = m[0] * m[3] - m[1] * m[2];
|
||||
return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d,
|
||||
(m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d];
|
||||
return [
|
||||
m[3] / d,
|
||||
-m[1] / d,
|
||||
-m[2] / d,
|
||||
m[0] / d,
|
||||
(m[2] * m[5] - m[4] * m[3]) / d,
|
||||
(m[4] * m[1] - m[5] * m[0]) / d,
|
||||
];
|
||||
}
|
||||
|
||||
// Apply a generic 3d matrix M on a 3-vector v:
|
||||
|
@ -648,7 +669,7 @@ class Util {
|
|||
return [
|
||||
m[0] * v[0] + m[1] * v[1] + m[2] * v[2],
|
||||
m[3] * v[0] + m[4] * v[1] + m[5] * v[2],
|
||||
m[6] * v[0] + m[7] * v[1] + m[8] * v[2]
|
||||
m[6] * v[0] + m[7] * v[1] + m[8] * v[2],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -708,8 +729,10 @@ class Util {
|
|||
rect2 = Util.normalizeRect(rect2);
|
||||
|
||||
// X: first and second points belong to different rectangles?
|
||||
if ((orderedX[0] === rect1[0] && orderedX[1] === rect2[0]) ||
|
||||
(orderedX[0] === rect2[0] && orderedX[1] === rect1[0])) {
|
||||
if (
|
||||
(orderedX[0] === rect1[0] && orderedX[1] === rect2[0]) ||
|
||||
(orderedX[0] === rect2[0] && orderedX[1] === rect1[0])
|
||||
) {
|
||||
// Intersection must be between second and third points
|
||||
result[0] = orderedX[1];
|
||||
result[2] = orderedX[2];
|
||||
|
@ -718,8 +741,10 @@ class Util {
|
|||
}
|
||||
|
||||
// Y: first and second points belong to different rectangles?
|
||||
if ((orderedY[0] === rect1[1] && orderedY[1] === rect2[1]) ||
|
||||
(orderedY[0] === rect2[1] && orderedY[1] === rect1[1])) {
|
||||
if (
|
||||
(orderedY[0] === rect1[1] && orderedY[1] === rect2[1]) ||
|
||||
(orderedY[0] === rect2[1] && orderedY[1] === rect1[1])
|
||||
) {
|
||||
// Intersection must be between second and third points
|
||||
result[1] = orderedY[1];
|
||||
result[3] = orderedY[2];
|
||||
|
@ -745,18 +770,21 @@ const PDFStringTranslateTable = [
|
|||
];
|
||||
|
||||
function stringToPDFString(str) {
|
||||
const length = str.length, strBuf = [];
|
||||
if (str[0] === '\xFE' && str[1] === '\xFF') {
|
||||
const length = str.length,
|
||||
strBuf = [];
|
||||
if (str[0] === "\xFE" && str[1] === "\xFF") {
|
||||
// UTF16BE BOM
|
||||
for (let i = 2; i < length; i += 2) {
|
||||
strBuf.push(String.fromCharCode(
|
||||
(str.charCodeAt(i) << 8) | str.charCodeAt(i + 1)));
|
||||
strBuf.push(
|
||||
String.fromCharCode((str.charCodeAt(i) << 8) | str.charCodeAt(i + 1))
|
||||
);
|
||||
}
|
||||
} else if (str[0] === '\xFF' && str[1] === '\xFE') {
|
||||
} else if (str[0] === "\xFF" && str[1] === "\xFE") {
|
||||
// UTF16LE BOM
|
||||
for (let i = 2; i < length; i += 2) {
|
||||
strBuf.push(String.fromCharCode(
|
||||
(str.charCodeAt(i + 1) << 8) | str.charCodeAt(i)));
|
||||
strBuf.push(
|
||||
String.fromCharCode((str.charCodeAt(i + 1) << 8) | str.charCodeAt(i))
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < length; ++i) {
|
||||
|
@ -764,7 +792,7 @@ function stringToPDFString(str) {
|
|||
strBuf.push(code ? String.fromCharCode(code) : str.charAt(i));
|
||||
}
|
||||
}
|
||||
return strBuf.join('');
|
||||
return strBuf.join("");
|
||||
}
|
||||
|
||||
function stringToUTF8String(str) {
|
||||
|
@ -783,19 +811,19 @@ function isEmptyObj(obj) {
|
|||
}
|
||||
|
||||
function isBool(v) {
|
||||
return typeof v === 'boolean';
|
||||
return typeof v === "boolean";
|
||||
}
|
||||
|
||||
function isNum(v) {
|
||||
return typeof v === 'number';
|
||||
return typeof v === "number";
|
||||
}
|
||||
|
||||
function isString(v) {
|
||||
return typeof v === 'string';
|
||||
return typeof v === "string";
|
||||
}
|
||||
|
||||
function isArrayBuffer(v) {
|
||||
return typeof v === 'object' && v !== null && v.byteLength !== undefined;
|
||||
return typeof v === "object" && v !== null && v.byteLength !== undefined;
|
||||
}
|
||||
|
||||
function isArrayEqual(arr1, arr2) {
|
||||
|
@ -809,7 +837,7 @@ function isArrayEqual(arr1, arr2) {
|
|||
|
||||
// Checks if ch is one of the following characters: SPACE, TAB, CR or LF.
|
||||
function isSpace(ch) {
|
||||
return (ch === 0x20 || ch === 0x09 || ch === 0x0D || ch === 0x0A);
|
||||
return ch === 0x20 || ch === 0x09 || ch === 0x0d || ch === 0x0a;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -832,7 +860,7 @@ function createPromiseCapability() {
|
|||
const capability = Object.create(null);
|
||||
let isSettled = false;
|
||||
|
||||
Object.defineProperty(capability, 'settled', {
|
||||
Object.defineProperty(capability, "settled", {
|
||||
get() {
|
||||
return isSettled;
|
||||
},
|
||||
|
@ -853,22 +881,23 @@ function createPromiseCapability() {
|
|||
const createObjectURL = (function createObjectURLClosure() {
|
||||
// Blob/createObjectURL is not available, falling back to data schema.
|
||||
const digits =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
|
||||
return function createObjectURL(data, contentType, forceDataSchema = false) {
|
||||
if (!forceDataSchema && URL.createObjectURL) {
|
||||
const blob = new Blob([data], { type: contentType, });
|
||||
const blob = new Blob([data], { type: contentType });
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
let buffer = `data:${contentType};base64,`;
|
||||
for (let i = 0, ii = data.length; i < ii; i += 3) {
|
||||
const b1 = data[i] & 0xFF;
|
||||
const b2 = data[i + 1] & 0xFF;
|
||||
const b3 = data[i + 2] & 0xFF;
|
||||
const d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
|
||||
const d3 = i + 1 < ii ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
|
||||
const d4 = i + 2 < ii ? (b3 & 0x3F) : 64;
|
||||
const b1 = data[i] & 0xff;
|
||||
const b2 = data[i + 1] & 0xff;
|
||||
const b3 = data[i + 2] & 0xff;
|
||||
const d1 = b1 >> 2,
|
||||
d2 = ((b1 & 3) << 4) | (b2 >> 4);
|
||||
const d3 = i + 1 < ii ? ((b2 & 0xf) << 2) | (b3 >> 6) : 64;
|
||||
const d4 = i + 2 < ii ? b3 & 0x3f : 64;
|
||||
buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];
|
||||
}
|
||||
return buffer;
|
||||
|
|
|
@ -13,20 +13,20 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
// Patch importScripts to work around a bug in WebKit and Chrome 48-.
|
||||
// See https://crbug.com/572225 and https://webkit.org/b/153317.
|
||||
self.importScripts = (function (importScripts) {
|
||||
self.importScripts = (function(importScripts) {
|
||||
return function() {
|
||||
setTimeout(function () {}, 0);
|
||||
setTimeout(function() {}, 0);
|
||||
return importScripts.apply(this, arguments);
|
||||
};
|
||||
})(importScripts);
|
||||
|
||||
importScripts('../node_modules/systemjs/dist/system.js');
|
||||
importScripts('../systemjs.config.js');
|
||||
importScripts("../node_modules/systemjs/dist/system.js");
|
||||
importScripts("../systemjs.config.js");
|
||||
|
||||
SystemJS.import('pdfjs/core/worker').then(function () {
|
||||
SystemJS.import("pdfjs/core/worker").then(function() {
|
||||
// Worker is loaded at this point.
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue