2013-03-21 17:04:44 +09:00
|
|
|
/* Copyright 2012 Mozilla Foundation
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2017-04-02 23:14:30 +09:00
|
|
|
import {
|
|
|
|
AnnotationBorderStyleType, AnnotationFieldFlag, AnnotationFlag,
|
|
|
|
AnnotationType, isArray, isInt, 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 { OperatorList } from './evaluator';
|
|
|
|
import { Stream } from './stream';
|
2015-11-22 01:32:47 +09:00
|
|
|
|
2015-07-26 23:47:28 +09:00
|
|
|
/**
|
2015-11-13 04:39:58 +09:00
|
|
|
* @class
|
|
|
|
* @alias AnnotationFactory
|
2015-07-26 23:47:28 +09:00
|
|
|
*/
|
|
|
|
function AnnotationFactory() {}
|
2015-11-13 04:39:58 +09:00
|
|
|
AnnotationFactory.prototype = /** @lends AnnotationFactory.prototype */ {
|
2015-07-26 23:47:28 +09:00
|
|
|
/**
|
|
|
|
* @param {XRef} xref
|
|
|
|
* @param {Object} ref
|
2016-10-01 19:05:07 +09:00
|
|
|
* @param {PDFManager} pdfManager
|
2017-01-09 00:51:30 +09:00
|
|
|
* @param {Object} idFactory
|
2015-07-26 23:47:28 +09:00
|
|
|
* @returns {Annotation}
|
|
|
|
*/
|
2017-01-09 00:51:30 +09:00
|
|
|
create: function AnnotationFactory_create(xref, ref, pdfManager, idFactory) {
|
2015-07-26 23:47:28 +09:00
|
|
|
var dict = xref.fetchIfRef(ref);
|
|
|
|
if (!isDict(dict)) {
|
|
|
|
return;
|
|
|
|
}
|
2017-01-09 00:51:30 +09:00
|
|
|
var id = isRef(ref) ? ref.toString() : 'annot_' + idFactory.createObjId();
|
2015-07-26 23:47:28 +09:00
|
|
|
|
|
|
|
// Determine the annotation's subtype.
|
|
|
|
var subtype = dict.get('Subtype');
|
2016-07-24 21:32:48 +09:00
|
|
|
subtype = isName(subtype) ? subtype.name : null;
|
2015-07-26 23:47:28 +09:00
|
|
|
|
|
|
|
// Return the right annotation object based on the subtype and field type.
|
|
|
|
var parameters = {
|
2017-04-27 19:58:44 +09:00
|
|
|
xref,
|
|
|
|
dict,
|
2016-08-26 23:01:25 +09:00
|
|
|
ref: isRef(ref) ? ref : null,
|
2017-04-27 19:58:44 +09:00
|
|
|
subtype,
|
|
|
|
id,
|
|
|
|
pdfManager,
|
2015-07-26 23:47:28 +09:00
|
|
|
};
|
|
|
|
|
|
|
|
switch (subtype) {
|
|
|
|
case 'Link':
|
|
|
|
return new LinkAnnotation(parameters);
|
|
|
|
|
|
|
|
case 'Text':
|
|
|
|
return new TextAnnotation(parameters);
|
|
|
|
|
|
|
|
case 'Widget':
|
|
|
|
var fieldType = Util.getInheritableProperty(dict, 'FT');
|
2016-09-06 06:46:52 +09:00
|
|
|
fieldType = isName(fieldType) ? fieldType.name : null;
|
|
|
|
|
|
|
|
switch (fieldType) {
|
|
|
|
case 'Tx':
|
|
|
|
return new TextWidgetAnnotation(parameters);
|
2016-11-04 21:01:42 +09:00
|
|
|
case 'Btn':
|
|
|
|
return new ButtonWidgetAnnotation(parameters);
|
2016-09-25 08:45:49 +09:00
|
|
|
case 'Ch':
|
|
|
|
return new ChoiceWidgetAnnotation(parameters);
|
2015-07-26 23:47:28 +09:00
|
|
|
}
|
2016-09-06 06:46:52 +09:00
|
|
|
warn('Unimplemented widget field type "' + fieldType + '", ' +
|
|
|
|
'falling back to base field type.');
|
2015-07-26 23:47:28 +09:00
|
|
|
return new WidgetAnnotation(parameters);
|
|
|
|
|
2015-12-23 05:31:56 +09:00
|
|
|
case 'Popup':
|
|
|
|
return new PopupAnnotation(parameters);
|
|
|
|
|
2017-04-03 03:50:17 +09:00
|
|
|
case 'Line':
|
|
|
|
return new LineAnnotation(parameters);
|
|
|
|
|
2016-01-01 23:31:46 +09:00
|
|
|
case 'Highlight':
|
|
|
|
return new HighlightAnnotation(parameters);
|
|
|
|
|
2015-12-28 08:33:41 +09:00
|
|
|
case 'Underline':
|
|
|
|
return new UnderlineAnnotation(parameters);
|
|
|
|
|
2015-12-30 23:28:26 +09:00
|
|
|
case 'Squiggly':
|
|
|
|
return new SquigglyAnnotation(parameters);
|
|
|
|
|
2015-12-29 23:09:28 +09:00
|
|
|
case 'StrikeOut':
|
|
|
|
return new StrikeOutAnnotation(parameters);
|
|
|
|
|
2016-02-15 04:44:00 +09:00
|
|
|
case 'FileAttachment':
|
|
|
|
return new FileAttachmentAnnotation(parameters);
|
|
|
|
|
2015-07-26 23:47:28 +09:00
|
|
|
default:
|
2016-07-24 21:32:48 +09:00
|
|
|
if (!subtype) {
|
|
|
|
warn('Annotation is missing the required /Subtype.');
|
|
|
|
} else {
|
|
|
|
warn('Unimplemented annotation type "' + subtype + '", ' +
|
|
|
|
'falling back to base annotation.');
|
|
|
|
}
|
2015-07-26 23:47:28 +09:00
|
|
|
return new Annotation(parameters);
|
|
|
|
}
|
Fix inconsistent spacing and trailing commas in objects in `src/core/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
*Unfortunately this patch is fairly big, even though it only covers the `src/core` folder, but splitting it even further seemed difficult.*
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
Please note: This patch was created automatically, using the ESLint --fix command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/src/core/evaluator.js b/src/core/evaluator.js
index abab9027..dcd3594b 100644
--- a/src/core/evaluator.js
+++ b/src/core/evaluator.js
@@ -2785,7 +2785,8 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
t['Tz'] = { id: OPS.setHScale, numArgs: 1, variableArgs: false, };
t['TL'] = { id: OPS.setLeading, numArgs: 1, variableArgs: false, };
t['Tf'] = { id: OPS.setFont, numArgs: 2, variableArgs: false, };
- t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1, variableArgs: false, };
+ t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1,
+ variableArgs: false, };
t['Ts'] = { id: OPS.setTextRise, numArgs: 1, variableArgs: false, };
t['Td'] = { id: OPS.moveText, numArgs: 2, variableArgs: false, };
t['TD'] = { id: OPS.setLeadingMoveText, numArgs: 2, variableArgs: false, };
diff --git a/src/core/jbig2.js b/src/core/jbig2.js
index 5a17d482..71671541 100644
--- a/src/core/jbig2.js
+++ b/src/core/jbig2.js
@@ -123,19 +123,22 @@ var Jbig2Image = (function Jbig2ImageClosure() {
{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -2, y: 0, },
{ x: -1, y: 0, }],
[{ x: -3, y: -1, }, { x: -2, y: -1, }, { x: -1, y: -1, }, { x: 0, y: -1, },
- { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, }, { x: -1, y: 0, }]
+ { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, },
+ { x: -1, y: 0, }]
];
var RefinementTemplates = [
{
coding: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }],
- reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, },
- { x: 1, y: 0, }, { x: -1, y: 1, }, { x: 0, y: 1, }, { x: 1, y: 1, }],
+ reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, },
+ { x: 0, y: 0, }, { x: 1, y: 0, }, { x: -1, y: 1, },
+ { x: 0, y: 1, }, { x: 1, y: 1, }],
},
{
- coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }],
- reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, }, { x: 1, y: 0, },
- { x: 0, y: 1, }, { x: 1, y: 1, }],
+ coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, },
+ { x: -1, y: 0, }],
+ reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, },
+ { x: 1, y: 0, }, { x: 0, y: 1, }, { x: 1, y: 1, }],
}
];
```
2017-06-02 18:16:24 +09:00
|
|
|
},
|
2015-07-26 23:47:28 +09:00
|
|
|
};
|
2014-03-07 23:48:42 +09:00
|
|
|
|
2013-03-21 17:04:44 +09:00
|
|
|
var Annotation = (function AnnotationClosure() {
|
|
|
|
// 12.5.5: Algorithm: Appearance streams
|
|
|
|
function getTransformMatrix(rect, bbox, matrix) {
|
|
|
|
var bounds = Util.getAxialAlignedBoundingBox(bbox, matrix);
|
|
|
|
var minX = bounds[0];
|
|
|
|
var minY = bounds[1];
|
|
|
|
var maxX = bounds[2];
|
|
|
|
var maxY = bounds[3];
|
|
|
|
|
|
|
|
if (minX === maxX || minY === maxY) {
|
|
|
|
// From real-life file, bbox was [0, 0, 0, 0]. In this case,
|
|
|
|
// just apply the transform for rect
|
|
|
|
return [1, 0, 0, 1, rect[0], rect[1]];
|
|
|
|
}
|
|
|
|
|
|
|
|
var xRatio = (rect[2] - rect[0]) / (maxX - minX);
|
|
|
|
var yRatio = (rect[3] - rect[1]) / (maxY - minY);
|
|
|
|
return [
|
|
|
|
xRatio,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
yRatio,
|
|
|
|
rect[0] - minX * xRatio,
|
|
|
|
rect[1] - minY * yRatio
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
function Annotation(params) {
|
|
|
|
var dict = params.dict;
|
2015-11-22 07:25:17 +09:00
|
|
|
|
|
|
|
this.setFlags(dict.get('F'));
|
2016-03-26 22:41:15 +09:00
|
|
|
this.setRectangle(dict.getArray('Rect'));
|
2016-05-06 02:16:35 +09:00
|
|
|
this.setColor(dict.getArray('C'));
|
2014-12-26 04:44:16 +09:00
|
|
|
this.setBorderStyle(dict);
|
2017-02-13 07:05:10 +09:00
|
|
|
this.setAppearance(dict);
|
2015-11-29 00:08:34 +09:00
|
|
|
|
|
|
|
// Expose public properties using a data object.
|
|
|
|
this.data = {};
|
2016-08-26 23:01:25 +09:00
|
|
|
this.data.id = params.id;
|
2016-07-24 21:32:48 +09:00
|
|
|
this.data.subtype = params.subtype;
|
2015-11-29 00:08:34 +09:00
|
|
|
this.data.annotationFlags = this.flags;
|
|
|
|
this.data.rect = this.rectangle;
|
|
|
|
this.data.color = this.color;
|
|
|
|
this.data.borderStyle = this.borderStyle;
|
|
|
|
this.data.hasAppearance = !!this.appearance;
|
2013-03-21 17:04:44 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
Annotation.prototype = {
|
2016-05-25 00:35:45 +09:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
_hasFlag: function Annotation_hasFlag(flags, flag) {
|
|
|
|
return !!(flags & flag);
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
_isViewable: function Annotation_isViewable(flags) {
|
|
|
|
return !this._hasFlag(flags, AnnotationFlag.INVISIBLE) &&
|
|
|
|
!this._hasFlag(flags, AnnotationFlag.HIDDEN) &&
|
|
|
|
!this._hasFlag(flags, AnnotationFlag.NOVIEW);
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
_isPrintable: function AnnotationFlag_isPrintable(flags) {
|
|
|
|
return this._hasFlag(flags, AnnotationFlag.PRINT) &&
|
|
|
|
!this._hasFlag(flags, AnnotationFlag.INVISIBLE) &&
|
|
|
|
!this._hasFlag(flags, AnnotationFlag.HIDDEN);
|
|
|
|
},
|
|
|
|
|
2015-11-22 07:25:17 +09:00
|
|
|
/**
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
get viewable() {
|
2016-05-25 00:35:45 +09:00
|
|
|
if (this.flags === 0) {
|
|
|
|
return true;
|
2015-11-22 07:25:17 +09:00
|
|
|
}
|
2016-05-25 00:35:45 +09:00
|
|
|
return this._isViewable(this.flags);
|
2015-11-22 07:25:17 +09:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
get printable() {
|
2016-05-25 00:35:45 +09:00
|
|
|
if (this.flags === 0) {
|
|
|
|
return false;
|
2015-11-22 07:25:17 +09:00
|
|
|
}
|
2016-05-25 00:35:45 +09:00
|
|
|
return this._isPrintable(this.flags);
|
2015-11-22 07:25:17 +09:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the flags.
|
|
|
|
*
|
|
|
|
* @public
|
|
|
|
* @memberof Annotation
|
|
|
|
* @param {number} flags - Unsigned 32-bit integer specifying annotation
|
|
|
|
* characteristics
|
|
|
|
* @see {@link shared/util.js}
|
|
|
|
*/
|
|
|
|
setFlags: function Annotation_setFlags(flags) {
|
2016-05-25 00:35:45 +09:00
|
|
|
this.flags = (isInt(flags) && flags > 0) ? flags : 0;
|
2015-11-22 07:25:17 +09:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if a provided flag is set.
|
|
|
|
*
|
|
|
|
* @public
|
|
|
|
* @memberof Annotation
|
|
|
|
* @param {number} flag - Hexadecimal representation for an annotation
|
|
|
|
* characteristic
|
|
|
|
* @return {boolean}
|
|
|
|
* @see {@link shared/util.js}
|
|
|
|
*/
|
|
|
|
hasFlag: function Annotation_hasFlag(flag) {
|
2016-05-25 00:35:45 +09:00
|
|
|
return this._hasFlag(this.flags, flag);
|
2015-11-22 07:25:17 +09:00
|
|
|
},
|
|
|
|
|
2015-07-21 05:01:47 +09:00
|
|
|
/**
|
|
|
|
* Set the rectangle.
|
|
|
|
*
|
|
|
|
* @public
|
|
|
|
* @memberof Annotation
|
|
|
|
* @param {Array} rectangle - The rectangle array with exactly four entries
|
|
|
|
*/
|
|
|
|
setRectangle: function Annotation_setRectangle(rectangle) {
|
|
|
|
if (isArray(rectangle) && rectangle.length === 4) {
|
|
|
|
this.rectangle = Util.normalizeRect(rectangle);
|
|
|
|
} else {
|
|
|
|
this.rectangle = [0, 0, 0, 0];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2015-07-15 23:59:25 +09:00
|
|
|
/**
|
|
|
|
* Set the color and take care of color space conversion.
|
|
|
|
*
|
|
|
|
* @public
|
|
|
|
* @memberof Annotation
|
|
|
|
* @param {Array} color - The color array containing either 0
|
|
|
|
* (transparent), 1 (grayscale), 3 (RGB) or
|
|
|
|
* 4 (CMYK) elements
|
|
|
|
*/
|
|
|
|
setColor: function Annotation_setColor(color) {
|
|
|
|
var rgbColor = new Uint8Array(3); // Black in RGB color space (default)
|
|
|
|
if (!isArray(color)) {
|
|
|
|
this.color = rgbColor;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (color.length) {
|
|
|
|
case 0: // Transparent, which we indicate with a null value
|
|
|
|
this.color = null;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: // Convert grayscale to RGB
|
|
|
|
ColorSpace.singletons.gray.getRgbItem(color, 0, rgbColor, 0);
|
|
|
|
this.color = rgbColor;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: // Convert RGB percentages to RGB
|
|
|
|
ColorSpace.singletons.rgb.getRgbItem(color, 0, rgbColor, 0);
|
|
|
|
this.color = rgbColor;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4: // Convert CMYK to RGB
|
|
|
|
ColorSpace.singletons.cmyk.getRgbItem(color, 0, rgbColor, 0);
|
|
|
|
this.color = rgbColor;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
this.color = rgbColor;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2014-12-26 04:24:28 +09:00
|
|
|
/**
|
|
|
|
* Set the border style (as AnnotationBorderStyle object).
|
|
|
|
*
|
|
|
|
* @public
|
|
|
|
* @memberof Annotation
|
|
|
|
* @param {Dict} borderStyle - The border style dictionary
|
|
|
|
*/
|
|
|
|
setBorderStyle: function Annotation_setBorderStyle(borderStyle) {
|
2015-11-29 00:08:34 +09:00
|
|
|
this.borderStyle = new AnnotationBorderStyle();
|
2014-12-26 04:24:28 +09:00
|
|
|
if (!isDict(borderStyle)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (borderStyle.has('BS')) {
|
|
|
|
var dict = borderStyle.get('BS');
|
2016-08-04 22:13:37 +09:00
|
|
|
var dictType = dict.get('Type');
|
2014-12-26 04:24:28 +09:00
|
|
|
|
2016-08-04 22:13:37 +09:00
|
|
|
if (!dictType || isName(dictType, 'Border')) {
|
2014-12-26 04:24:28 +09:00
|
|
|
this.borderStyle.setWidth(dict.get('W'));
|
|
|
|
this.borderStyle.setStyle(dict.get('S'));
|
2016-05-06 02:16:35 +09:00
|
|
|
this.borderStyle.setDashArray(dict.getArray('D'));
|
2014-12-26 04:24:28 +09:00
|
|
|
}
|
|
|
|
} else if (borderStyle.has('Border')) {
|
2016-05-06 02:16:35 +09:00
|
|
|
var array = borderStyle.getArray('Border');
|
2014-12-26 04:24:28 +09:00
|
|
|
if (isArray(array) && array.length >= 3) {
|
|
|
|
this.borderStyle.setHorizontalCornerRadius(array[0]);
|
|
|
|
this.borderStyle.setVerticalCornerRadius(array[1]);
|
|
|
|
this.borderStyle.setWidth(array[2]);
|
|
|
|
|
|
|
|
if (array.length === 4) { // Dash array available
|
|
|
|
this.borderStyle.setDashArray(array[3]);
|
|
|
|
}
|
|
|
|
}
|
2015-07-06 21:48:59 +09:00
|
|
|
} else {
|
|
|
|
// There are no border entries in the dictionary. According to the
|
|
|
|
// specification, we should draw a solid border of width 1 in that
|
|
|
|
// case, but Adobe Reader did not implement that part of the
|
|
|
|
// specification and instead draws no border at all, so we do the same.
|
|
|
|
// See also https://github.com/mozilla/pdf.js/issues/6179.
|
|
|
|
this.borderStyle.setWidth(0);
|
2014-12-26 04:24:28 +09:00
|
|
|
}
|
|
|
|
},
|
2013-03-21 17:04:44 +09:00
|
|
|
|
2017-02-13 07:05:10 +09:00
|
|
|
/**
|
|
|
|
* Set the (normal) appearance.
|
|
|
|
*
|
|
|
|
* @public
|
|
|
|
* @memberof Annotation
|
|
|
|
* @param {Dict} dict - The annotation's data dictionary
|
|
|
|
*/
|
|
|
|
setAppearance: function Annotation_setAppearance(dict) {
|
|
|
|
this.appearance = null;
|
|
|
|
|
|
|
|
var appearanceStates = dict.get('AP');
|
|
|
|
if (!isDict(appearanceStates)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// In case the normal appearance is a stream, then it is used directly.
|
|
|
|
var normalAppearanceState = appearanceStates.get('N');
|
|
|
|
if (isStream(normalAppearanceState)) {
|
|
|
|
this.appearance = normalAppearanceState;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!isDict(normalAppearanceState)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// In case the normal appearance is a dictionary, the `AS` entry provides
|
|
|
|
// the key of the stream in this dictionary.
|
|
|
|
var as = dict.get('AS');
|
|
|
|
if (!isName(as) || !normalAppearanceState.has(as.name)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.appearance = normalAppearanceState.get(as.name);
|
|
|
|
},
|
|
|
|
|
2016-02-23 08:21:28 +09:00
|
|
|
/**
|
|
|
|
* Prepare the annotation for working with a popup in the display layer.
|
|
|
|
*
|
|
|
|
* @private
|
|
|
|
* @memberof Annotation
|
|
|
|
* @param {Dict} dict - The annotation's data dictionary
|
|
|
|
*/
|
|
|
|
_preparePopup: function Annotation_preparePopup(dict) {
|
|
|
|
if (!dict.has('C')) {
|
|
|
|
// Fall back to the default background color.
|
|
|
|
this.data.color = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.data.hasPopup = dict.has('Popup');
|
|
|
|
this.data.title = stringToPDFString(dict.get('T') || '');
|
|
|
|
this.data.contents = stringToPDFString(dict.get('Contents') || '');
|
|
|
|
},
|
|
|
|
|
2014-05-02 07:52:03 +09:00
|
|
|
loadResources: function Annotation_loadResources(keys) {
|
2017-05-02 18:14:53 +09:00
|
|
|
return this.appearance.dict.getAsync('Resources').then((resources) => {
|
|
|
|
if (!resources) {
|
|
|
|
return;
|
|
|
|
}
|
2017-06-13 17:22:11 +09:00
|
|
|
let objectLoader = new ObjectLoader(resources, keys, resources.xref);
|
|
|
|
|
2017-05-02 18:14:53 +09:00
|
|
|
return objectLoader.load().then(function() {
|
|
|
|
return resources;
|
|
|
|
});
|
|
|
|
});
|
2013-06-05 09:57:52 +09:00
|
|
|
},
|
|
|
|
|
2016-09-19 05:31:08 +09:00
|
|
|
getOperatorList: function Annotation_getOperatorList(evaluator, task,
|
|
|
|
renderForms) {
|
2013-03-21 17:04:44 +09:00
|
|
|
if (!this.appearance) {
|
2014-05-10 10:21:15 +09:00
|
|
|
return Promise.resolve(new OperatorList());
|
2013-03-21 17:04:44 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
var data = this.data;
|
|
|
|
var appearanceDict = this.appearance.dict;
|
2013-06-05 09:57:52 +09:00
|
|
|
var resourcesPromise = this.loadResources([
|
|
|
|
'ExtGState',
|
|
|
|
'ColorSpace',
|
|
|
|
'Pattern',
|
|
|
|
'Shading',
|
|
|
|
'XObject',
|
|
|
|
'Font'
|
|
|
|
// ProcSet
|
|
|
|
// Properties
|
|
|
|
]);
|
2016-05-06 02:16:35 +09:00
|
|
|
var bbox = appearanceDict.getArray('BBox') || [0, 0, 1, 1];
|
2016-12-11 03:58:36 +09:00
|
|
|
var matrix = appearanceDict.getArray('Matrix') || [1, 0, 0, 1, 0, 0];
|
2013-03-21 17:04:44 +09:00
|
|
|
var transform = getTransformMatrix(data.rect, bbox, matrix);
|
2014-05-10 10:21:15 +09:00
|
|
|
|
2017-05-02 18:14:53 +09:00
|
|
|
return resourcesPromise.then((resources) => {
|
[api-minor] Always allow e.g. rendering to continue even if there are errors, and add a `stopAtErrors` parameter to `getDocument` to opt-out of this behaviour (issue 6342, issue 3795, bug 1130815)
Other PDF readers, e.g. Adobe Reader and PDFium (in Chrome), will attempt to render as much of a page as possible even if there are errors present.
Currently we just bail as soon the first error is hit, which means that we'll usually not render anything in these cases and just display a blank page instead.
NOTE: This patch changes the default behaviour of the PDF.js API to always attempt to recover as much data as possible, even when encountering errors during e.g. `getOperatorList`/`getTextContent`, which thus improve our handling of corrupt PDF files and allow the default viewer to handle errors slightly more gracefully.
In the event that an API consumer wishes to use the old behaviour, where we stop parsing as soon as an error is encountered, the `stopAtErrors` parameter can be set at `getDocument`.
Fixes, inasmuch it's possible since the PDF files are corrupt, e.g. issue 6342, issue 3795, and [bug 1130815](https://bugzilla.mozilla.org/show_bug.cgi?id=1130815) (and probably others too).
2017-02-19 22:03:08 +09:00
|
|
|
var opList = new OperatorList();
|
|
|
|
opList.addOp(OPS.beginAnnotation, [data.rect, transform, matrix]);
|
Change the signatures of the `PartialEvaluator` "constructor" and its `getOperatorList`/`getTextContent` methods to take parameter objects
Currently these methods accept a large number of parameters, which creates quite unwieldy call-sites. When invoking them, you have to remember not only what arguments to supply, but also the correct order, to avoid runtime errors.
Furthermore, since some of the parameters are optional, you also have to remember to pass e.g. `null` or `undefined` for those ones.
Also, adding new parameters to these methods (which happens occasionally), often becomes unnecessarily tedious (based on personal experience).
Please note that I do *not* think that we need/should convert *every* single method in `evaluator.js` (or elsewhere in `/core` files) to take parameter objects. However, in my opinion, once a method starts relying on approximately five parameter (or even more), passing them in individually becomes quite cumbersome.
With these changes, I obviously needed to update the `evaluator_spec.js` unit-tests. The main change there, except the new method signatures[1], is that it's now re-using *one* `PartialEvalutor` instance, since I couldn't see any compelling reason for creating a new one in every single test.
*Note:* If this patch is accepted, my intention is to (time permitting) see if it makes sense to convert additional methods in `evaluator.js` (and other `/core` files) in a similar fashion, but I figured that it'd be a good idea to limit the initial scope somewhat.
---
[1] A fun fact here, note how the `PartialEvaluator` signature used in `evaluator_spec.js` wasn't even correct in the current `master`.
2017-04-30 06:13:51 +09:00
|
|
|
return evaluator.getOperatorList({
|
|
|
|
stream: this.appearance,
|
|
|
|
task,
|
|
|
|
resources,
|
|
|
|
operatorList: opList,
|
|
|
|
}).then(() => {
|
[api-minor] Always allow e.g. rendering to continue even if there are errors, and add a `stopAtErrors` parameter to `getDocument` to opt-out of this behaviour (issue 6342, issue 3795, bug 1130815)
Other PDF readers, e.g. Adobe Reader and PDFium (in Chrome), will attempt to render as much of a page as possible even if there are errors present.
Currently we just bail as soon the first error is hit, which means that we'll usually not render anything in these cases and just display a blank page instead.
NOTE: This patch changes the default behaviour of the PDF.js API to always attempt to recover as much data as possible, even when encountering errors during e.g. `getOperatorList`/`getTextContent`, which thus improve our handling of corrupt PDF files and allow the default viewer to handle errors slightly more gracefully.
In the event that an API consumer wishes to use the old behaviour, where we stop parsing as soon as an error is encountered, the `stopAtErrors` parameter can be set at `getDocument`.
Fixes, inasmuch it's possible since the PDF files are corrupt, e.g. issue 6342, issue 3795, and [bug 1130815](https://bugzilla.mozilla.org/show_bug.cgi?id=1130815) (and probably others too).
2017-02-19 22:03:08 +09:00
|
|
|
opList.addOp(OPS.endAnnotation, []);
|
2017-05-02 18:14:53 +09:00
|
|
|
this.appearance.reset();
|
[api-minor] Always allow e.g. rendering to continue even if there are errors, and add a `stopAtErrors` parameter to `getDocument` to opt-out of this behaviour (issue 6342, issue 3795, bug 1130815)
Other PDF readers, e.g. Adobe Reader and PDFium (in Chrome), will attempt to render as much of a page as possible even if there are errors present.
Currently we just bail as soon the first error is hit, which means that we'll usually not render anything in these cases and just display a blank page instead.
NOTE: This patch changes the default behaviour of the PDF.js API to always attempt to recover as much data as possible, even when encountering errors during e.g. `getOperatorList`/`getTextContent`, which thus improve our handling of corrupt PDF files and allow the default viewer to handle errors slightly more gracefully.
In the event that an API consumer wishes to use the old behaviour, where we stop parsing as soon as an error is encountered, the `stopAtErrors` parameter can be set at `getDocument`.
Fixes, inasmuch it's possible since the PDF files are corrupt, e.g. issue 6342, issue 3795, and [bug 1130815](https://bugzilla.mozilla.org/show_bug.cgi?id=1130815) (and probably others too).
2017-02-19 22:03:08 +09:00
|
|
|
return opList;
|
2014-05-10 10:21:15 +09:00
|
|
|
});
|
[api-minor] Always allow e.g. rendering to continue even if there are errors, and add a `stopAtErrors` parameter to `getDocument` to opt-out of this behaviour (issue 6342, issue 3795, bug 1130815)
Other PDF readers, e.g. Adobe Reader and PDFium (in Chrome), will attempt to render as much of a page as possible even if there are errors present.
Currently we just bail as soon the first error is hit, which means that we'll usually not render anything in these cases and just display a blank page instead.
NOTE: This patch changes the default behaviour of the PDF.js API to always attempt to recover as much data as possible, even when encountering errors during e.g. `getOperatorList`/`getTextContent`, which thus improve our handling of corrupt PDF files and allow the default viewer to handle errors slightly more gracefully.
In the event that an API consumer wishes to use the old behaviour, where we stop parsing as soon as an error is encountered, the `stopAtErrors` parameter can be set at `getDocument`.
Fixes, inasmuch it's possible since the PDF files are corrupt, e.g. issue 6342, issue 3795, and [bug 1130815](https://bugzilla.mozilla.org/show_bug.cgi?id=1130815) (and probably others too).
2017-02-19 22:03:08 +09:00
|
|
|
});
|
Fix inconsistent spacing and trailing commas in objects in `src/core/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
*Unfortunately this patch is fairly big, even though it only covers the `src/core` folder, but splitting it even further seemed difficult.*
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
Please note: This patch was created automatically, using the ESLint --fix command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/src/core/evaluator.js b/src/core/evaluator.js
index abab9027..dcd3594b 100644
--- a/src/core/evaluator.js
+++ b/src/core/evaluator.js
@@ -2785,7 +2785,8 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
t['Tz'] = { id: OPS.setHScale, numArgs: 1, variableArgs: false, };
t['TL'] = { id: OPS.setLeading, numArgs: 1, variableArgs: false, };
t['Tf'] = { id: OPS.setFont, numArgs: 2, variableArgs: false, };
- t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1, variableArgs: false, };
+ t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1,
+ variableArgs: false, };
t['Ts'] = { id: OPS.setTextRise, numArgs: 1, variableArgs: false, };
t['Td'] = { id: OPS.moveText, numArgs: 2, variableArgs: false, };
t['TD'] = { id: OPS.setLeadingMoveText, numArgs: 2, variableArgs: false, };
diff --git a/src/core/jbig2.js b/src/core/jbig2.js
index 5a17d482..71671541 100644
--- a/src/core/jbig2.js
+++ b/src/core/jbig2.js
@@ -123,19 +123,22 @@ var Jbig2Image = (function Jbig2ImageClosure() {
{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -2, y: 0, },
{ x: -1, y: 0, }],
[{ x: -3, y: -1, }, { x: -2, y: -1, }, { x: -1, y: -1, }, { x: 0, y: -1, },
- { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, }, { x: -1, y: 0, }]
+ { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, },
+ { x: -1, y: 0, }]
];
var RefinementTemplates = [
{
coding: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }],
- reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, },
- { x: 1, y: 0, }, { x: -1, y: 1, }, { x: 0, y: 1, }, { x: 1, y: 1, }],
+ reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, },
+ { x: 0, y: 0, }, { x: 1, y: 0, }, { x: -1, y: 1, },
+ { x: 0, y: 1, }, { x: 1, y: 1, }],
},
{
- coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }],
- reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, }, { x: 1, y: 0, },
- { x: 0, y: 1, }, { x: 1, y: 1, }],
+ coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, },
+ { x: -1, y: 0, }],
+ reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, },
+ { x: 1, y: 0, }, { x: 0, y: 1, }, { x: 1, y: 1, }],
}
];
```
2017-06-02 18:16:24 +09:00
|
|
|
},
|
2013-03-21 17:04:44 +09:00
|
|
|
};
|
|
|
|
|
|
|
|
return Annotation;
|
|
|
|
})();
|
|
|
|
|
2014-12-26 04:11:23 +09:00
|
|
|
/**
|
|
|
|
* Contains all data regarding an annotation's border style.
|
|
|
|
*
|
|
|
|
* @class
|
|
|
|
*/
|
|
|
|
var AnnotationBorderStyle = (function AnnotationBorderStyleClosure() {
|
|
|
|
/**
|
|
|
|
* @constructor
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
function AnnotationBorderStyle() {
|
|
|
|
this.width = 1;
|
|
|
|
this.style = AnnotationBorderStyleType.SOLID;
|
|
|
|
this.dashArray = [3];
|
|
|
|
this.horizontalCornerRadius = 0;
|
|
|
|
this.verticalCornerRadius = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
AnnotationBorderStyle.prototype = {
|
|
|
|
/**
|
|
|
|
* Set the width.
|
|
|
|
*
|
|
|
|
* @public
|
|
|
|
* @memberof AnnotationBorderStyle
|
|
|
|
* @param {integer} width - The width
|
|
|
|
*/
|
|
|
|
setWidth: function AnnotationBorderStyle_setWidth(width) {
|
|
|
|
if (width === (width | 0)) {
|
|
|
|
this.width = width;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the style.
|
|
|
|
*
|
|
|
|
* @public
|
|
|
|
* @memberof AnnotationBorderStyle
|
|
|
|
* @param {Object} style - The style object
|
|
|
|
* @see {@link shared/util.js}
|
|
|
|
*/
|
|
|
|
setStyle: function AnnotationBorderStyle_setStyle(style) {
|
|
|
|
if (!style) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch (style.name) {
|
|
|
|
case 'S':
|
|
|
|
this.style = AnnotationBorderStyleType.SOLID;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'D':
|
|
|
|
this.style = AnnotationBorderStyleType.DASHED;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'B':
|
|
|
|
this.style = AnnotationBorderStyleType.BEVELED;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'I':
|
|
|
|
this.style = AnnotationBorderStyleType.INSET;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'U':
|
|
|
|
this.style = AnnotationBorderStyleType.UNDERLINE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the dash array.
|
|
|
|
*
|
|
|
|
* @public
|
|
|
|
* @memberof AnnotationBorderStyle
|
|
|
|
* @param {Array} dashArray - The dash array with at least one element
|
|
|
|
*/
|
|
|
|
setDashArray: function AnnotationBorderStyle_setDashArray(dashArray) {
|
|
|
|
// We validate the dash array, but we do not use it because CSS does not
|
|
|
|
// allow us to change spacing of dashes. For more information, visit
|
|
|
|
// http://www.w3.org/TR/css3-background/#the-border-style.
|
|
|
|
if (isArray(dashArray) && dashArray.length > 0) {
|
|
|
|
// According to the PDF specification: the elements in a dashArray
|
|
|
|
// shall be numbers that are nonnegative and not all equal to zero.
|
|
|
|
var isValid = true;
|
|
|
|
var allZeros = true;
|
|
|
|
for (var i = 0, len = dashArray.length; i < len; i++) {
|
|
|
|
var element = dashArray[i];
|
|
|
|
var validNumber = (+element >= 0);
|
|
|
|
if (!validNumber) {
|
|
|
|
isValid = false;
|
|
|
|
break;
|
|
|
|
} else if (element > 0) {
|
|
|
|
allZeros = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (isValid && !allZeros) {
|
|
|
|
this.dashArray = dashArray;
|
|
|
|
} else {
|
|
|
|
this.width = 0; // Adobe behavior when the array is invalid.
|
|
|
|
}
|
|
|
|
} else if (dashArray) {
|
|
|
|
this.width = 0; // Adobe behavior when the array is invalid.
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the horizontal corner radius (from a Border dictionary).
|
|
|
|
*
|
|
|
|
* @public
|
|
|
|
* @memberof AnnotationBorderStyle
|
|
|
|
* @param {integer} radius - The horizontal corner radius
|
|
|
|
*/
|
|
|
|
setHorizontalCornerRadius:
|
|
|
|
function AnnotationBorderStyle_setHorizontalCornerRadius(radius) {
|
|
|
|
if (radius === (radius | 0)) {
|
|
|
|
this.horizontalCornerRadius = radius;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the vertical corner radius (from a Border dictionary).
|
|
|
|
*
|
|
|
|
* @public
|
|
|
|
* @memberof AnnotationBorderStyle
|
|
|
|
* @param {integer} radius - The vertical corner radius
|
|
|
|
*/
|
|
|
|
setVerticalCornerRadius:
|
|
|
|
function AnnotationBorderStyle_setVerticalCornerRadius(radius) {
|
|
|
|
if (radius === (radius | 0)) {
|
|
|
|
this.verticalCornerRadius = radius;
|
|
|
|
}
|
Fix inconsistent spacing and trailing commas in objects in `src/core/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
*Unfortunately this patch is fairly big, even though it only covers the `src/core` folder, but splitting it even further seemed difficult.*
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
Please note: This patch was created automatically, using the ESLint --fix command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/src/core/evaluator.js b/src/core/evaluator.js
index abab9027..dcd3594b 100644
--- a/src/core/evaluator.js
+++ b/src/core/evaluator.js
@@ -2785,7 +2785,8 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
t['Tz'] = { id: OPS.setHScale, numArgs: 1, variableArgs: false, };
t['TL'] = { id: OPS.setLeading, numArgs: 1, variableArgs: false, };
t['Tf'] = { id: OPS.setFont, numArgs: 2, variableArgs: false, };
- t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1, variableArgs: false, };
+ t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1,
+ variableArgs: false, };
t['Ts'] = { id: OPS.setTextRise, numArgs: 1, variableArgs: false, };
t['Td'] = { id: OPS.moveText, numArgs: 2, variableArgs: false, };
t['TD'] = { id: OPS.setLeadingMoveText, numArgs: 2, variableArgs: false, };
diff --git a/src/core/jbig2.js b/src/core/jbig2.js
index 5a17d482..71671541 100644
--- a/src/core/jbig2.js
+++ b/src/core/jbig2.js
@@ -123,19 +123,22 @@ var Jbig2Image = (function Jbig2ImageClosure() {
{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -2, y: 0, },
{ x: -1, y: 0, }],
[{ x: -3, y: -1, }, { x: -2, y: -1, }, { x: -1, y: -1, }, { x: 0, y: -1, },
- { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, }, { x: -1, y: 0, }]
+ { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, },
+ { x: -1, y: 0, }]
];
var RefinementTemplates = [
{
coding: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }],
- reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, },
- { x: 1, y: 0, }, { x: -1, y: 1, }, { x: 0, y: 1, }, { x: 1, y: 1, }],
+ reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, },
+ { x: 0, y: 0, }, { x: 1, y: 0, }, { x: -1, y: 1, },
+ { x: 0, y: 1, }, { x: 1, y: 1, }],
},
{
- coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }],
- reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, }, { x: 1, y: 0, },
- { x: 0, y: 1, }, { x: 1, y: 1, }],
+ coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, },
+ { x: -1, y: 0, }],
+ reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, },
+ { x: 1, y: 0, }, { x: 0, y: 1, }, { x: 1, y: 1, }],
}
];
```
2017-06-02 18:16:24 +09:00
|
|
|
},
|
2014-12-26 04:11:23 +09:00
|
|
|
};
|
|
|
|
|
|
|
|
return AnnotationBorderStyle;
|
|
|
|
})();
|
|
|
|
|
2013-03-21 17:04:44 +09:00
|
|
|
var WidgetAnnotation = (function WidgetAnnotationClosure() {
|
|
|
|
function WidgetAnnotation(params) {
|
|
|
|
Annotation.call(this, params);
|
|
|
|
|
|
|
|
var dict = params.dict;
|
|
|
|
var data = this.data;
|
|
|
|
|
2015-12-15 22:52:17 +09:00
|
|
|
data.annotationType = AnnotationType.WIDGET;
|
2016-11-02 08:07:31 +09:00
|
|
|
data.fieldName = this._constructFieldName(dict);
|
2016-09-25 08:45:49 +09:00
|
|
|
data.fieldValue = Util.getInheritableProperty(dict, 'V',
|
|
|
|
/* getArray = */ true);
|
2013-03-21 17:04:44 +09:00
|
|
|
data.alternativeText = stringToPDFString(dict.get('TU') || '');
|
|
|
|
data.defaultAppearance = Util.getInheritableProperty(dict, 'DA') || '';
|
|
|
|
var fieldType = Util.getInheritableProperty(dict, 'FT');
|
2016-09-06 06:46:52 +09:00
|
|
|
data.fieldType = isName(fieldType) ? fieldType.name : null;
|
2014-03-26 23:07:38 +09:00
|
|
|
this.fieldResources = Util.getInheritableProperty(dict, 'DR') || Dict.empty;
|
2013-03-21 17:04:44 +09:00
|
|
|
|
2016-09-14 23:32:51 +09:00
|
|
|
data.fieldFlags = Util.getInheritableProperty(dict, 'Ff');
|
|
|
|
if (!isInt(data.fieldFlags) || data.fieldFlags < 0) {
|
|
|
|
data.fieldFlags = 0;
|
|
|
|
}
|
|
|
|
|
2016-09-25 08:45:49 +09:00
|
|
|
data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY);
|
|
|
|
|
2016-09-06 06:46:52 +09:00
|
|
|
// Hide signatures because we cannot validate them.
|
2015-11-22 07:25:17 +09:00
|
|
|
if (data.fieldType === 'Sig') {
|
|
|
|
this.setFlags(AnnotationFlag.HIDDEN);
|
|
|
|
}
|
2016-11-02 08:07:31 +09:00
|
|
|
}
|
2015-11-22 07:25:17 +09:00
|
|
|
|
2016-11-02 08:07:31 +09:00
|
|
|
Util.inherit(WidgetAnnotation, Annotation, {
|
|
|
|
/**
|
|
|
|
* Construct the (fully qualified) field name from the (partial) field
|
|
|
|
* names of the field and its ancestors.
|
|
|
|
*
|
|
|
|
* @private
|
|
|
|
* @memberof WidgetAnnotation
|
|
|
|
* @param {Dict} dict - Complete widget annotation dictionary
|
|
|
|
* @return {string}
|
|
|
|
*/
|
|
|
|
_constructFieldName: function WidgetAnnotation_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 no parent exists, the partial and fully qualified names are equal.
|
|
|
|
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.
|
|
|
|
var fieldName = [];
|
|
|
|
if (dict.has('T')) {
|
|
|
|
fieldName.unshift(stringToPDFString(dict.get('T')));
|
|
|
|
}
|
|
|
|
|
|
|
|
var loopDict = dict;
|
|
|
|
while (loopDict.has('Parent')) {
|
|
|
|
loopDict = loopDict.get('Parent');
|
2017-03-10 07:51:52 +09:00
|
|
|
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
|
|
|
|
// dictionary, but `null` for example (issue 8143).
|
|
|
|
break;
|
|
|
|
}
|
2016-11-02 08:07:31 +09:00
|
|
|
|
|
|
|
if (loopDict.has('T')) {
|
|
|
|
fieldName.unshift(stringToPDFString(loopDict.get('T')));
|
2013-03-21 17:04:44 +09:00
|
|
|
}
|
|
|
|
}
|
2016-11-02 08:07:31 +09:00
|
|
|
return fieldName.join('.');
|
|
|
|
},
|
2013-03-21 17:04:44 +09:00
|
|
|
|
2016-09-14 23:32:51 +09:00
|
|
|
/**
|
|
|
|
* Check if a provided field flag is set.
|
|
|
|
*
|
|
|
|
* @public
|
|
|
|
* @memberof WidgetAnnotation
|
2016-09-22 04:06:44 +09:00
|
|
|
* @param {number} flag - Hexadecimal representation for an annotation
|
|
|
|
* field characteristic
|
2016-09-14 23:32:51 +09:00
|
|
|
* @return {boolean}
|
|
|
|
* @see {@link shared/util.js}
|
|
|
|
*/
|
|
|
|
hasFieldFlag: function WidgetAnnotation_hasFieldFlag(flag) {
|
2016-09-22 04:06:44 +09:00
|
|
|
return !!(this.data.fieldFlags & flag);
|
2016-09-14 23:32:51 +09:00
|
|
|
},
|
|
|
|
});
|
2013-03-21 17:04:44 +09:00
|
|
|
|
|
|
|
return WidgetAnnotation;
|
|
|
|
})();
|
|
|
|
|
2013-03-26 07:32:47 +09:00
|
|
|
var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() {
|
|
|
|
function TextWidgetAnnotation(params) {
|
|
|
|
WidgetAnnotation.call(this, params);
|
|
|
|
|
2016-09-25 08:45:49 +09:00
|
|
|
// The field value is always a string.
|
|
|
|
this.data.fieldValue = stringToPDFString(this.data.fieldValue || '');
|
|
|
|
|
2016-09-13 21:57:11 +09:00
|
|
|
// Determine the alignment of text in the field.
|
|
|
|
var alignment = Util.getInheritableProperty(params.dict, 'Q');
|
|
|
|
if (!isInt(alignment) || alignment < 0 || alignment > 2) {
|
|
|
|
alignment = null;
|
|
|
|
}
|
|
|
|
this.data.textAlignment = alignment;
|
|
|
|
|
|
|
|
// Determine the maximum length of text in the field.
|
|
|
|
var maximumLength = Util.getInheritableProperty(params.dict, 'MaxLen');
|
|
|
|
if (!isInt(maximumLength) || maximumLength < 0) {
|
|
|
|
maximumLength = null;
|
|
|
|
}
|
|
|
|
this.data.maxLen = maximumLength;
|
2016-09-14 23:32:51 +09:00
|
|
|
|
|
|
|
// Process field flags for the display layer.
|
|
|
|
this.data.multiLine = this.hasFieldFlag(AnnotationFieldFlag.MULTILINE);
|
2016-09-20 07:04:11 +09:00
|
|
|
this.data.comb = this.hasFieldFlag(AnnotationFieldFlag.COMB) &&
|
|
|
|
!this.hasFieldFlag(AnnotationFieldFlag.MULTILINE) &&
|
|
|
|
!this.hasFieldFlag(AnnotationFieldFlag.PASSWORD) &&
|
|
|
|
!this.hasFieldFlag(AnnotationFieldFlag.FILESELECT) &&
|
|
|
|
this.data.maxLen !== null;
|
2013-03-26 07:32:47 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
Util.inherit(TextWidgetAnnotation, WidgetAnnotation, {
|
2016-09-19 05:31:08 +09:00
|
|
|
getOperatorList:
|
|
|
|
function TextWidgetAnnotation_getOperatorList(evaluator, task,
|
|
|
|
renderForms) {
|
2016-09-15 05:49:37 +09:00
|
|
|
var operatorList = new OperatorList();
|
|
|
|
|
|
|
|
// Do not render form elements on the canvas when interactive forms are
|
|
|
|
// enabled. The display layer is responsible for rendering them instead.
|
2016-09-19 05:31:08 +09:00
|
|
|
if (renderForms) {
|
2016-09-15 05:49:37 +09:00
|
|
|
return Promise.resolve(operatorList);
|
|
|
|
}
|
|
|
|
|
2013-08-23 04:29:06 +09:00
|
|
|
if (this.appearance) {
|
2016-09-19 05:31:08 +09:00
|
|
|
return Annotation.prototype.getOperatorList.call(this, evaluator, task,
|
|
|
|
renderForms);
|
2013-08-23 04:29:06 +09:00
|
|
|
}
|
2013-05-29 10:16:21 +09:00
|
|
|
|
2013-03-26 07:32:47 +09:00
|
|
|
// Even if there is an appearance stream, ignore it. This is the
|
|
|
|
// behaviour used by Adobe Reader.
|
2016-09-15 04:51:21 +09:00
|
|
|
if (!this.data.defaultAppearance) {
|
|
|
|
return Promise.resolve(operatorList);
|
2013-03-26 07:32:47 +09:00
|
|
|
}
|
|
|
|
|
2016-09-15 04:51:21 +09:00
|
|
|
var stream = new Stream(stringToBytes(this.data.defaultAppearance));
|
Change the signatures of the `PartialEvaluator` "constructor" and its `getOperatorList`/`getTextContent` methods to take parameter objects
Currently these methods accept a large number of parameters, which creates quite unwieldy call-sites. When invoking them, you have to remember not only what arguments to supply, but also the correct order, to avoid runtime errors.
Furthermore, since some of the parameters are optional, you also have to remember to pass e.g. `null` or `undefined` for those ones.
Also, adding new parameters to these methods (which happens occasionally), often becomes unnecessarily tedious (based on personal experience).
Please note that I do *not* think that we need/should convert *every* single method in `evaluator.js` (or elsewhere in `/core` files) to take parameter objects. However, in my opinion, once a method starts relying on approximately five parameter (or even more), passing them in individually becomes quite cumbersome.
With these changes, I obviously needed to update the `evaluator_spec.js` unit-tests. The main change there, except the new method signatures[1], is that it's now re-using *one* `PartialEvalutor` instance, since I couldn't see any compelling reason for creating a new one in every single test.
*Note:* If this patch is accepted, my intention is to (time permitting) see if it makes sense to convert additional methods in `evaluator.js` (and other `/core` files) in a similar fashion, but I figured that it'd be a good idea to limit the initial scope somewhat.
---
[1] A fun fact here, note how the `PartialEvaluator` signature used in `evaluator_spec.js` wasn't even correct in the current `master`.
2017-04-30 06:13:51 +09:00
|
|
|
return evaluator.getOperatorList({
|
|
|
|
stream,
|
|
|
|
task,
|
|
|
|
resources: this.fieldResources,
|
|
|
|
operatorList,
|
|
|
|
}).then(function () {
|
[api-minor] Always allow e.g. rendering to continue even if there are errors, and add a `stopAtErrors` parameter to `getDocument` to opt-out of this behaviour (issue 6342, issue 3795, bug 1130815)
Other PDF readers, e.g. Adobe Reader and PDFium (in Chrome), will attempt to render as much of a page as possible even if there are errors present.
Currently we just bail as soon the first error is hit, which means that we'll usually not render anything in these cases and just display a blank page instead.
NOTE: This patch changes the default behaviour of the PDF.js API to always attempt to recover as much data as possible, even when encountering errors during e.g. `getOperatorList`/`getTextContent`, which thus improve our handling of corrupt PDF files and allow the default viewer to handle errors slightly more gracefully.
In the event that an API consumer wishes to use the old behaviour, where we stop parsing as soon as an error is encountered, the `stopAtErrors` parameter can be set at `getDocument`.
Fixes, inasmuch it's possible since the PDF files are corrupt, e.g. issue 6342, issue 3795, and [bug 1130815](https://bugzilla.mozilla.org/show_bug.cgi?id=1130815) (and probably others too).
2017-02-19 22:03:08 +09:00
|
|
|
return operatorList;
|
|
|
|
});
|
Fix inconsistent spacing and trailing commas in objects in `src/core/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
*Unfortunately this patch is fairly big, even though it only covers the `src/core` folder, but splitting it even further seemed difficult.*
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
Please note: This patch was created automatically, using the ESLint --fix command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/src/core/evaluator.js b/src/core/evaluator.js
index abab9027..dcd3594b 100644
--- a/src/core/evaluator.js
+++ b/src/core/evaluator.js
@@ -2785,7 +2785,8 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
t['Tz'] = { id: OPS.setHScale, numArgs: 1, variableArgs: false, };
t['TL'] = { id: OPS.setLeading, numArgs: 1, variableArgs: false, };
t['Tf'] = { id: OPS.setFont, numArgs: 2, variableArgs: false, };
- t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1, variableArgs: false, };
+ t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1,
+ variableArgs: false, };
t['Ts'] = { id: OPS.setTextRise, numArgs: 1, variableArgs: false, };
t['Td'] = { id: OPS.moveText, numArgs: 2, variableArgs: false, };
t['TD'] = { id: OPS.setLeadingMoveText, numArgs: 2, variableArgs: false, };
diff --git a/src/core/jbig2.js b/src/core/jbig2.js
index 5a17d482..71671541 100644
--- a/src/core/jbig2.js
+++ b/src/core/jbig2.js
@@ -123,19 +123,22 @@ var Jbig2Image = (function Jbig2ImageClosure() {
{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -2, y: 0, },
{ x: -1, y: 0, }],
[{ x: -3, y: -1, }, { x: -2, y: -1, }, { x: -1, y: -1, }, { x: 0, y: -1, },
- { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, }, { x: -1, y: 0, }]
+ { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, },
+ { x: -1, y: 0, }]
];
var RefinementTemplates = [
{
coding: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }],
- reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, },
- { x: 1, y: 0, }, { x: -1, y: 1, }, { x: 0, y: 1, }, { x: 1, y: 1, }],
+ reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, },
+ { x: 0, y: 0, }, { x: 1, y: 0, }, { x: -1, y: 1, },
+ { x: 0, y: 1, }, { x: 1, y: 1, }],
},
{
- coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }],
- reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, }, { x: 1, y: 0, },
- { x: 0, y: 1, }, { x: 1, y: 1, }],
+ coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, },
+ { x: -1, y: 0, }],
+ reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, },
+ { x: 1, y: 0, }, { x: 0, y: 1, }, { x: 1, y: 1, }],
}
];
```
2017-06-02 18:16:24 +09:00
|
|
|
},
|
2013-03-26 07:32:47 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
return TextWidgetAnnotation;
|
|
|
|
})();
|
|
|
|
|
2016-11-04 21:01:42 +09:00
|
|
|
var ButtonWidgetAnnotation = (function ButtonWidgetAnnotationClosure() {
|
|
|
|
function ButtonWidgetAnnotation(params) {
|
|
|
|
WidgetAnnotation.call(this, params);
|
|
|
|
|
2016-12-16 07:49:46 +09:00
|
|
|
this.data.checkBox = !this.hasFieldFlag(AnnotationFieldFlag.RADIO) &&
|
|
|
|
!this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
|
|
|
|
if (this.data.checkBox) {
|
|
|
|
if (!isName(this.data.fieldValue)) {
|
|
|
|
return;
|
|
|
|
}
|
2016-11-04 21:01:42 +09:00
|
|
|
this.data.fieldValue = this.data.fieldValue.name;
|
|
|
|
}
|
2016-12-16 06:58:27 +09:00
|
|
|
|
2016-12-16 07:49:46 +09:00
|
|
|
this.data.radioButton = this.hasFieldFlag(AnnotationFieldFlag.RADIO) &&
|
|
|
|
!this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
|
|
|
|
if (this.data.radioButton) {
|
2016-12-16 06:58:27 +09:00
|
|
|
this.data.fieldValue = this.data.buttonValue = null;
|
|
|
|
|
|
|
|
// The parent field's `V` entry holds a `Name` object with the appearance
|
|
|
|
// state of whichever child field is currently in the "on" state.
|
|
|
|
var fieldParent = params.dict.get('Parent');
|
2017-02-07 00:57:06 +09:00
|
|
|
if (isDict(fieldParent) && fieldParent.has('V')) {
|
|
|
|
var fieldParentValue = fieldParent.get('V');
|
|
|
|
if (isName(fieldParentValue)) {
|
|
|
|
this.data.fieldValue = fieldParentValue.name;
|
|
|
|
}
|
2016-12-16 06:58:27 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
// The button's value corresponds to its appearance state.
|
|
|
|
var appearanceStates = params.dict.get('AP');
|
|
|
|
if (!isDict(appearanceStates)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var normalAppearanceState = appearanceStates.get('N');
|
|
|
|
if (!isDict(normalAppearanceState)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var keys = normalAppearanceState.getKeys();
|
|
|
|
for (var i = 0, ii = keys.length; i < ii; i++) {
|
|
|
|
if (keys[i] !== 'Off') {
|
|
|
|
this.data.buttonValue = keys[i];
|
|
|
|
break;
|
2016-11-04 21:01:42 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Util.inherit(ButtonWidgetAnnotation, WidgetAnnotation, {
|
|
|
|
getOperatorList:
|
|
|
|
function ButtonWidgetAnnotation_getOperatorList(evaluator, task,
|
|
|
|
renderForms) {
|
|
|
|
var operatorList = new OperatorList();
|
|
|
|
|
|
|
|
// Do not render form elements on the canvas when interactive forms are
|
|
|
|
// enabled. The display layer is responsible for rendering them instead.
|
|
|
|
if (renderForms) {
|
|
|
|
return Promise.resolve(operatorList);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.appearance) {
|
|
|
|
return Annotation.prototype.getOperatorList.call(this, evaluator, task,
|
2016-12-16 07:49:46 +09:00
|
|
|
renderForms);
|
2016-11-04 21:01:42 +09:00
|
|
|
}
|
|
|
|
return Promise.resolve(operatorList);
|
Fix inconsistent spacing and trailing commas in objects in `src/core/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
*Unfortunately this patch is fairly big, even though it only covers the `src/core` folder, but splitting it even further seemed difficult.*
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
Please note: This patch was created automatically, using the ESLint --fix command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/src/core/evaluator.js b/src/core/evaluator.js
index abab9027..dcd3594b 100644
--- a/src/core/evaluator.js
+++ b/src/core/evaluator.js
@@ -2785,7 +2785,8 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
t['Tz'] = { id: OPS.setHScale, numArgs: 1, variableArgs: false, };
t['TL'] = { id: OPS.setLeading, numArgs: 1, variableArgs: false, };
t['Tf'] = { id: OPS.setFont, numArgs: 2, variableArgs: false, };
- t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1, variableArgs: false, };
+ t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1,
+ variableArgs: false, };
t['Ts'] = { id: OPS.setTextRise, numArgs: 1, variableArgs: false, };
t['Td'] = { id: OPS.moveText, numArgs: 2, variableArgs: false, };
t['TD'] = { id: OPS.setLeadingMoveText, numArgs: 2, variableArgs: false, };
diff --git a/src/core/jbig2.js b/src/core/jbig2.js
index 5a17d482..71671541 100644
--- a/src/core/jbig2.js
+++ b/src/core/jbig2.js
@@ -123,19 +123,22 @@ var Jbig2Image = (function Jbig2ImageClosure() {
{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -2, y: 0, },
{ x: -1, y: 0, }],
[{ x: -3, y: -1, }, { x: -2, y: -1, }, { x: -1, y: -1, }, { x: 0, y: -1, },
- { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, }, { x: -1, y: 0, }]
+ { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, },
+ { x: -1, y: 0, }]
];
var RefinementTemplates = [
{
coding: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }],
- reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, },
- { x: 1, y: 0, }, { x: -1, y: 1, }, { x: 0, y: 1, }, { x: 1, y: 1, }],
+ reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, },
+ { x: 0, y: 0, }, { x: 1, y: 0, }, { x: -1, y: 1, },
+ { x: 0, y: 1, }, { x: 1, y: 1, }],
},
{
- coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }],
- reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, }, { x: 1, y: 0, },
- { x: 0, y: 1, }, { x: 1, y: 1, }],
+ coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, },
+ { x: -1, y: 0, }],
+ reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, },
+ { x: 1, y: 0, }, { x: 0, y: 1, }, { x: 1, y: 1, }],
}
];
```
2017-06-02 18:16:24 +09:00
|
|
|
},
|
2016-11-04 21:01:42 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
return ButtonWidgetAnnotation;
|
|
|
|
})();
|
|
|
|
|
2016-09-25 08:45:49 +09:00
|
|
|
var ChoiceWidgetAnnotation = (function ChoiceWidgetAnnotationClosure() {
|
|
|
|
function ChoiceWidgetAnnotation(params) {
|
|
|
|
WidgetAnnotation.call(this, params);
|
|
|
|
|
|
|
|
// Determine the options. The options array may consist of strings or
|
|
|
|
// arrays. If the array consists of arrays, then the first element of
|
|
|
|
// each array is the export value and the second element of each array is
|
|
|
|
// the display value. If the array consists of strings, then these
|
|
|
|
// represent both the export and display value. In this case, we convert
|
|
|
|
// it to an array of arrays as well for convenience in the display layer.
|
2017-02-26 07:34:26 +09:00
|
|
|
// Note that the specification does not state that the `Opt` field is
|
|
|
|
// inheritable, but in practice PDF generators do make annotations
|
|
|
|
// inherit the options from a parent annotation (issue 8094).
|
2016-09-25 08:45:49 +09:00
|
|
|
this.data.options = [];
|
|
|
|
|
2017-02-26 07:34:26 +09:00
|
|
|
var options = Util.getInheritableProperty(params.dict, 'Opt');
|
2016-09-25 08:45:49 +09:00
|
|
|
if (isArray(options)) {
|
2016-12-17 21:34:18 +09:00
|
|
|
var xref = params.xref;
|
2016-09-25 08:45:49 +09:00
|
|
|
for (var i = 0, ii = options.length; i < ii; i++) {
|
2016-12-17 21:34:18 +09:00
|
|
|
var option = xref.fetchIfRef(options[i]);
|
|
|
|
var isOptionArray = isArray(option);
|
2016-09-25 08:45:49 +09:00
|
|
|
|
|
|
|
this.data.options[i] = {
|
2016-12-17 21:34:18 +09:00
|
|
|
exportValue: isOptionArray ? xref.fetchIfRef(option[0]) : option,
|
|
|
|
displayValue: isOptionArray ? xref.fetchIfRef(option[1]) : option,
|
2016-09-25 08:45:49 +09:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Determine the field value. In this case, it may be a string or an
|
|
|
|
// array of strings. For convenience in the display layer, convert the
|
|
|
|
// string to an array of one string as well.
|
|
|
|
if (!isArray(this.data.fieldValue)) {
|
|
|
|
this.data.fieldValue = [this.data.fieldValue];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process field flags for the display layer.
|
|
|
|
this.data.combo = this.hasFieldFlag(AnnotationFieldFlag.COMBO);
|
|
|
|
this.data.multiSelect = this.hasFieldFlag(AnnotationFieldFlag.MULTISELECT);
|
|
|
|
}
|
|
|
|
|
|
|
|
Util.inherit(ChoiceWidgetAnnotation, WidgetAnnotation, {
|
|
|
|
getOperatorList:
|
|
|
|
function ChoiceWidgetAnnotation_getOperatorList(evaluator, task,
|
|
|
|
renderForms) {
|
|
|
|
var operatorList = new OperatorList();
|
|
|
|
|
|
|
|
// Do not render form elements on the canvas when interactive forms are
|
|
|
|
// enabled. The display layer is responsible for rendering them instead.
|
|
|
|
if (renderForms) {
|
|
|
|
return Promise.resolve(operatorList);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Annotation.prototype.getOperatorList.call(this, evaluator, task,
|
|
|
|
renderForms);
|
Fix inconsistent spacing and trailing commas in objects in `src/core/` files, so we can enable the `comma-dangle` and `object-curly-spacing` ESLint rules later on
*Unfortunately this patch is fairly big, even though it only covers the `src/core` folder, but splitting it even further seemed difficult.*
http://eslint.org/docs/rules/comma-dangle
http://eslint.org/docs/rules/object-curly-spacing
Given that we currently have quite inconsistent object formatting, fixing this in *one* big patch probably wouldn't be feasible (since I cannot imagine anyone wanting to review that); hence I've opted to try and do this piecewise instead.
Please note: This patch was created automatically, using the ESLint --fix command line option. In a couple of places this caused lines to become too long, and I've fixed those manually; please refer to the interdiff below for the only hand-edits in this patch.
```diff
diff --git a/src/core/evaluator.js b/src/core/evaluator.js
index abab9027..dcd3594b 100644
--- a/src/core/evaluator.js
+++ b/src/core/evaluator.js
@@ -2785,7 +2785,8 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
t['Tz'] = { id: OPS.setHScale, numArgs: 1, variableArgs: false, };
t['TL'] = { id: OPS.setLeading, numArgs: 1, variableArgs: false, };
t['Tf'] = { id: OPS.setFont, numArgs: 2, variableArgs: false, };
- t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1, variableArgs: false, };
+ t['Tr'] = { id: OPS.setTextRenderingMode, numArgs: 1,
+ variableArgs: false, };
t['Ts'] = { id: OPS.setTextRise, numArgs: 1, variableArgs: false, };
t['Td'] = { id: OPS.moveText, numArgs: 2, variableArgs: false, };
t['TD'] = { id: OPS.setLeadingMoveText, numArgs: 2, variableArgs: false, };
diff --git a/src/core/jbig2.js b/src/core/jbig2.js
index 5a17d482..71671541 100644
--- a/src/core/jbig2.js
+++ b/src/core/jbig2.js
@@ -123,19 +123,22 @@ var Jbig2Image = (function Jbig2ImageClosure() {
{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -2, y: 0, },
{ x: -1, y: 0, }],
[{ x: -3, y: -1, }, { x: -2, y: -1, }, { x: -1, y: -1, }, { x: 0, y: -1, },
- { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, }, { x: -1, y: 0, }]
+ { x: 1, y: -1, }, { x: -4, y: 0, }, { x: -3, y: 0, }, { x: -2, y: 0, },
+ { x: -1, y: 0, }]
];
var RefinementTemplates = [
{
coding: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }],
- reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, },
- { x: 1, y: 0, }, { x: -1, y: 1, }, { x: 0, y: 1, }, { x: 1, y: 1, }],
+ reference: [{ x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, },
+ { x: 0, y: 0, }, { x: 1, y: 0, }, { x: -1, y: 1, },
+ { x: 0, y: 1, }, { x: 1, y: 1, }],
},
{
- coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, }, { x: -1, y: 0, }],
- reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, }, { x: 1, y: 0, },
- { x: 0, y: 1, }, { x: 1, y: 1, }],
+ coding: [{ x: -1, y: -1, }, { x: 0, y: -1, }, { x: 1, y: -1, },
+ { x: -1, y: 0, }],
+ reference: [{ x: 0, y: -1, }, { x: -1, y: 0, }, { x: 0, y: 0, },
+ { x: 1, y: 0, }, { x: 0, y: 1, }, { x: 1, y: 1, }],
}
];
```
2017-06-02 18:16:24 +09:00
|
|
|
},
|
2016-09-25 08:45:49 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
return ChoiceWidgetAnnotation;
|
|
|
|
})();
|
|
|
|
|
2013-03-21 17:04:44 +09:00
|
|
|
var TextAnnotation = (function TextAnnotationClosure() {
|
2015-12-23 05:31:56 +09:00
|
|
|
var DEFAULT_ICON_SIZE = 22; // px
|
2013-03-21 17:04:44 +09:00
|
|
|
|
2015-12-23 05:31:56 +09:00
|
|
|
function TextAnnotation(parameters) {
|
|
|
|
Annotation.call(this, parameters);
|
2013-03-21 17:04:44 +09:00
|
|
|
|
2015-12-23 05:31:56 +09:00
|
|
|
this.data.annotationType = AnnotationType.TEXT;
|
2013-03-21 17:04:44 +09:00
|
|
|
|
2015-12-23 05:31:56 +09:00
|
|
|
if (this.data.hasAppearance) {
|
|
|
|
this.data.name = 'NoIcon';
|
2014-03-07 23:48:42 +09:00
|
|
|
} else {
|
2015-12-23 05:31:56 +09:00
|
|
|
this.data.rect[1] = this.data.rect[3] - DEFAULT_ICON_SIZE;
|
|
|
|
this.data.rect[2] = this.data.rect[0] + DEFAULT_ICON_SIZE;
|
2016-02-23 08:21:28 +09:00
|
|
|
this.data.name = parameters.dict.has('Name') ?
|
|
|
|
parameters.dict.get('Name').name : 'Note';
|
2015-12-23 05:31:56 +09:00
|
|
|
}
|
2016-02-23 08:21:28 +09:00
|
|
|
this._preparePopup(parameters.dict);
|
2014-03-07 23:48:42 +09:00
|
|
|
}
|
2013-03-21 17:04:44 +09:00
|
|
|
|
2015-11-29 00:08:34 +09:00
|
|
|
Util.inherit(TextAnnotation, Annotation, {});
|
2013-03-21 17:04:44 +09:00
|
|
|
|
|
|
|
return TextAnnotation;
|
|
|
|
})();
|
|
|
|
|
|
|
|
var LinkAnnotation = (function LinkAnnotationClosure() {
|
|
|
|
function LinkAnnotation(params) {
|
2015-07-06 18:58:26 +09:00
|
|
|
Annotation.call(this, params);
|
2013-03-21 17:04:44 +09:00
|
|
|
|
|
|
|
var data = this.data;
|
2014-06-18 07:43:33 +09:00
|
|
|
data.annotationType = AnnotationType.LINK;
|
2013-03-21 17:04:44 +09:00
|
|
|
|
2016-09-30 23:08:03 +09:00
|
|
|
Catalog.parseDestDictionary({
|
|
|
|
destDict: params.dict,
|
|
|
|
resultObj: data,
|
2016-10-01 19:05:07 +09:00
|
|
|
docBaseUrl: params.pdfManager.docBaseUrl,
|
2016-09-30 23:08:03 +09:00
|
|
|
});
|
2016-03-03 21:07:22 +09:00
|
|
|
}
|
|
|
|
|
2015-11-29 00:08:34 +09:00
|
|
|
Util.inherit(LinkAnnotation, Annotation, {});
|
2013-03-21 17:04:44 +09:00
|
|
|
|
|
|
|
return LinkAnnotation;
|
|
|
|
})();
|
2015-11-22 01:32:47 +09:00
|
|
|
|
2015-12-23 05:31:56 +09:00
|
|
|
var PopupAnnotation = (function PopupAnnotationClosure() {
|
|
|
|
function PopupAnnotation(parameters) {
|
|
|
|
Annotation.call(this, parameters);
|
|
|
|
|
|
|
|
this.data.annotationType = AnnotationType.POPUP;
|
|
|
|
|
|
|
|
var dict = parameters.dict;
|
|
|
|
var parentItem = dict.get('Parent');
|
|
|
|
if (!parentItem) {
|
|
|
|
warn('Popup annotation has a missing or invalid parent annotation.');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-03 03:50:17 +09:00
|
|
|
var parentSubtype = parentItem.get('Subtype');
|
|
|
|
this.data.parentType = isName(parentSubtype) ? parentSubtype.name : null;
|
2015-12-23 05:31:56 +09:00
|
|
|
this.data.parentId = dict.getRaw('Parent').toString();
|
|
|
|
this.data.title = stringToPDFString(parentItem.get('T') || '');
|
|
|
|
this.data.contents = stringToPDFString(parentItem.get('Contents') || '');
|
|
|
|
|
|
|
|
if (!parentItem.has('C')) {
|
|
|
|
// Fall back to the default background color.
|
|
|
|
this.data.color = null;
|
|
|
|
} else {
|
2016-05-06 02:16:35 +09:00
|
|
|
this.setColor(parentItem.getArray('C'));
|
2015-12-23 05:31:56 +09:00
|
|
|
this.data.color = this.color;
|
|
|
|
}
|
2016-05-25 00:35:45 +09:00
|
|
|
|
|
|
|
// If the Popup annotation is not viewable, but the parent annotation is,
|
|
|
|
// 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) {
|
|
|
|
var parentFlags = parentItem.get('F');
|
|
|
|
if (this._isViewable(parentFlags)) {
|
|
|
|
this.setFlags(parentFlags);
|
|
|
|
}
|
|
|
|
}
|
2015-12-23 05:31:56 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
Util.inherit(PopupAnnotation, Annotation, {});
|
|
|
|
|
|
|
|
return PopupAnnotation;
|
|
|
|
})();
|
|
|
|
|
2017-04-03 03:50:17 +09:00
|
|
|
var LineAnnotation = (function LineAnnotationClosure() {
|
|
|
|
function LineAnnotation(parameters) {
|
|
|
|
Annotation.call(this, parameters);
|
|
|
|
|
|
|
|
this.data.annotationType = AnnotationType.LINE;
|
|
|
|
|
|
|
|
var dict = parameters.dict;
|
|
|
|
this.data.lineCoordinates = Util.normalizeRect(dict.getArray('L'));
|
|
|
|
this._preparePopup(dict);
|
|
|
|
}
|
|
|
|
|
|
|
|
Util.inherit(LineAnnotation, Annotation, {});
|
|
|
|
|
|
|
|
return LineAnnotation;
|
|
|
|
})();
|
|
|
|
|
2016-01-01 23:31:46 +09:00
|
|
|
var HighlightAnnotation = (function HighlightAnnotationClosure() {
|
|
|
|
function HighlightAnnotation(parameters) {
|
|
|
|
Annotation.call(this, parameters);
|
|
|
|
|
|
|
|
this.data.annotationType = AnnotationType.HIGHLIGHT;
|
2016-02-23 08:21:28 +09:00
|
|
|
this._preparePopup(parameters.dict);
|
2016-01-01 23:31:46 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
Util.inherit(HighlightAnnotation, Annotation, {});
|
|
|
|
|
|
|
|
return HighlightAnnotation;
|
|
|
|
})();
|
|
|
|
|
2015-12-28 08:33:41 +09:00
|
|
|
var UnderlineAnnotation = (function UnderlineAnnotationClosure() {
|
|
|
|
function UnderlineAnnotation(parameters) {
|
|
|
|
Annotation.call(this, parameters);
|
|
|
|
|
|
|
|
this.data.annotationType = AnnotationType.UNDERLINE;
|
2016-02-23 08:21:28 +09:00
|
|
|
this._preparePopup(parameters.dict);
|
2015-12-28 08:33:41 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
Util.inherit(UnderlineAnnotation, Annotation, {});
|
|
|
|
|
|
|
|
return UnderlineAnnotation;
|
|
|
|
})();
|
|
|
|
|
2015-12-30 23:28:26 +09:00
|
|
|
var SquigglyAnnotation = (function SquigglyAnnotationClosure() {
|
|
|
|
function SquigglyAnnotation(parameters) {
|
|
|
|
Annotation.call(this, parameters);
|
|
|
|
|
|
|
|
this.data.annotationType = AnnotationType.SQUIGGLY;
|
2016-02-23 08:21:28 +09:00
|
|
|
this._preparePopup(parameters.dict);
|
2015-12-30 23:28:26 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
Util.inherit(SquigglyAnnotation, Annotation, {});
|
|
|
|
|
|
|
|
return SquigglyAnnotation;
|
|
|
|
})();
|
|
|
|
|
2015-12-29 23:09:28 +09:00
|
|
|
var StrikeOutAnnotation = (function StrikeOutAnnotationClosure() {
|
|
|
|
function StrikeOutAnnotation(parameters) {
|
|
|
|
Annotation.call(this, parameters);
|
|
|
|
|
|
|
|
this.data.annotationType = AnnotationType.STRIKEOUT;
|
2016-02-23 08:21:28 +09:00
|
|
|
this._preparePopup(parameters.dict);
|
2015-12-29 23:09:28 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
Util.inherit(StrikeOutAnnotation, Annotation, {});
|
|
|
|
|
|
|
|
return StrikeOutAnnotation;
|
|
|
|
})();
|
|
|
|
|
2016-02-15 04:44:00 +09:00
|
|
|
var FileAttachmentAnnotation = (function FileAttachmentAnnotationClosure() {
|
|
|
|
function FileAttachmentAnnotation(parameters) {
|
|
|
|
Annotation.call(this, parameters);
|
|
|
|
|
2016-02-23 08:21:28 +09:00
|
|
|
var file = new FileSpec(parameters.dict.get('FS'), parameters.xref);
|
2016-02-15 04:44:00 +09:00
|
|
|
|
|
|
|
this.data.annotationType = AnnotationType.FILEATTACHMENT;
|
|
|
|
this.data.file = file.serializable;
|
2016-02-23 08:21:28 +09:00
|
|
|
this._preparePopup(parameters.dict);
|
2016-02-15 04:44:00 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
Util.inherit(FileAttachmentAnnotation, Annotation, {});
|
|
|
|
|
|
|
|
return FileAttachmentAnnotation;
|
|
|
|
})();
|
|
|
|
|
2017-04-02 23:14:30 +09:00
|
|
|
export {
|
|
|
|
Annotation,
|
|
|
|
AnnotationBorderStyle,
|
|
|
|
AnnotationFactory,
|
|
|
|
};
|