annotation.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. /* Copyright 2017 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. 'use strict';
  16. var sharedUtil = require('../shared/util.js');
  17. var corePrimitives = require('./primitives.js');
  18. var coreStream = require('./stream.js');
  19. var coreColorSpace = require('./colorspace.js');
  20. var coreObj = require('./obj.js');
  21. var coreEvaluator = require('./evaluator.js');
  22. var AnnotationBorderStyleType = sharedUtil.AnnotationBorderStyleType;
  23. var AnnotationFieldFlag = sharedUtil.AnnotationFieldFlag;
  24. var AnnotationFlag = sharedUtil.AnnotationFlag;
  25. var AnnotationType = sharedUtil.AnnotationType;
  26. var OPS = sharedUtil.OPS;
  27. var Util = sharedUtil.Util;
  28. var isArray = sharedUtil.isArray;
  29. var isInt = sharedUtil.isInt;
  30. var stringToBytes = sharedUtil.stringToBytes;
  31. var stringToPDFString = sharedUtil.stringToPDFString;
  32. var warn = sharedUtil.warn;
  33. var Dict = corePrimitives.Dict;
  34. var isDict = corePrimitives.isDict;
  35. var isName = corePrimitives.isName;
  36. var isRef = corePrimitives.isRef;
  37. var isStream = corePrimitives.isStream;
  38. var Stream = coreStream.Stream;
  39. var ColorSpace = coreColorSpace.ColorSpace;
  40. var Catalog = coreObj.Catalog;
  41. var ObjectLoader = coreObj.ObjectLoader;
  42. var FileSpec = coreObj.FileSpec;
  43. var OperatorList = coreEvaluator.OperatorList;
  44. function AnnotationFactory() {}
  45. AnnotationFactory.prototype = {
  46. create: function AnnotationFactory_create(xref, ref, pdfManager, idFactory) {
  47. var dict = xref.fetchIfRef(ref);
  48. if (!isDict(dict)) {
  49. return;
  50. }
  51. var id = isRef(ref) ? ref.toString() : 'annot_' + idFactory.createObjId();
  52. var subtype = dict.get('Subtype');
  53. subtype = isName(subtype) ? subtype.name : null;
  54. var parameters = {
  55. xref: xref,
  56. dict: dict,
  57. ref: isRef(ref) ? ref : null,
  58. subtype: subtype,
  59. id: id,
  60. pdfManager: pdfManager
  61. };
  62. switch (subtype) {
  63. case 'Link':
  64. return new LinkAnnotation(parameters);
  65. case 'Text':
  66. return new TextAnnotation(parameters);
  67. case 'Widget':
  68. var fieldType = Util.getInheritableProperty(dict, 'FT');
  69. fieldType = isName(fieldType) ? fieldType.name : null;
  70. switch (fieldType) {
  71. case 'Tx':
  72. return new TextWidgetAnnotation(parameters);
  73. case 'Btn':
  74. return new ButtonWidgetAnnotation(parameters);
  75. case 'Ch':
  76. return new ChoiceWidgetAnnotation(parameters);
  77. }
  78. warn('Unimplemented widget field type "' + fieldType + '", ' + 'falling back to base field type.');
  79. return new WidgetAnnotation(parameters);
  80. case 'Popup':
  81. return new PopupAnnotation(parameters);
  82. case 'Line':
  83. return new LineAnnotation(parameters);
  84. case 'Highlight':
  85. return new HighlightAnnotation(parameters);
  86. case 'Underline':
  87. return new UnderlineAnnotation(parameters);
  88. case 'Squiggly':
  89. return new SquigglyAnnotation(parameters);
  90. case 'StrikeOut':
  91. return new StrikeOutAnnotation(parameters);
  92. case 'FileAttachment':
  93. return new FileAttachmentAnnotation(parameters);
  94. default:
  95. if (!subtype) {
  96. warn('Annotation is missing the required /Subtype.');
  97. } else {
  98. warn('Unimplemented annotation type "' + subtype + '", ' + 'falling back to base annotation.');
  99. }
  100. return new Annotation(parameters);
  101. }
  102. }
  103. };
  104. var Annotation = function AnnotationClosure() {
  105. function getTransformMatrix(rect, bbox, matrix) {
  106. var bounds = Util.getAxialAlignedBoundingBox(bbox, matrix);
  107. var minX = bounds[0];
  108. var minY = bounds[1];
  109. var maxX = bounds[2];
  110. var maxY = bounds[3];
  111. if (minX === maxX || minY === maxY) {
  112. return [1, 0, 0, 1, rect[0], rect[1]];
  113. }
  114. var xRatio = (rect[2] - rect[0]) / (maxX - minX);
  115. var yRatio = (rect[3] - rect[1]) / (maxY - minY);
  116. return [xRatio, 0, 0, yRatio, rect[0] - minX * xRatio, rect[1] - minY * yRatio];
  117. }
  118. function Annotation(params) {
  119. var dict = params.dict;
  120. this.setFlags(dict.get('F'));
  121. this.setRectangle(dict.getArray('Rect'));
  122. this.setColor(dict.getArray('C'));
  123. this.setBorderStyle(dict);
  124. this.setAppearance(dict);
  125. this.data = {};
  126. this.data.id = params.id;
  127. this.data.subtype = params.subtype;
  128. this.data.annotationFlags = this.flags;
  129. this.data.rect = this.rectangle;
  130. this.data.color = this.color;
  131. this.data.borderStyle = this.borderStyle;
  132. this.data.hasAppearance = !!this.appearance;
  133. }
  134. Annotation.prototype = {
  135. _hasFlag: function Annotation_hasFlag(flags, flag) {
  136. return !!(flags & flag);
  137. },
  138. _isViewable: function Annotation_isViewable(flags) {
  139. return !this._hasFlag(flags, AnnotationFlag.INVISIBLE) && !this._hasFlag(flags, AnnotationFlag.HIDDEN) && !this._hasFlag(flags, AnnotationFlag.NOVIEW);
  140. },
  141. _isPrintable: function AnnotationFlag_isPrintable(flags) {
  142. return this._hasFlag(flags, AnnotationFlag.PRINT) && !this._hasFlag(flags, AnnotationFlag.INVISIBLE) && !this._hasFlag(flags, AnnotationFlag.HIDDEN);
  143. },
  144. get viewable() {
  145. if (this.flags === 0) {
  146. return true;
  147. }
  148. return this._isViewable(this.flags);
  149. },
  150. get printable() {
  151. if (this.flags === 0) {
  152. return false;
  153. }
  154. return this._isPrintable(this.flags);
  155. },
  156. setFlags: function Annotation_setFlags(flags) {
  157. this.flags = isInt(flags) && flags > 0 ? flags : 0;
  158. },
  159. hasFlag: function Annotation_hasFlag(flag) {
  160. return this._hasFlag(this.flags, flag);
  161. },
  162. setRectangle: function Annotation_setRectangle(rectangle) {
  163. if (isArray(rectangle) && rectangle.length === 4) {
  164. this.rectangle = Util.normalizeRect(rectangle);
  165. } else {
  166. this.rectangle = [0, 0, 0, 0];
  167. }
  168. },
  169. setColor: function Annotation_setColor(color) {
  170. var rgbColor = new Uint8Array(3);
  171. if (!isArray(color)) {
  172. this.color = rgbColor;
  173. return;
  174. }
  175. switch (color.length) {
  176. case 0:
  177. this.color = null;
  178. break;
  179. case 1:
  180. ColorSpace.singletons.gray.getRgbItem(color, 0, rgbColor, 0);
  181. this.color = rgbColor;
  182. break;
  183. case 3:
  184. ColorSpace.singletons.rgb.getRgbItem(color, 0, rgbColor, 0);
  185. this.color = rgbColor;
  186. break;
  187. case 4:
  188. ColorSpace.singletons.cmyk.getRgbItem(color, 0, rgbColor, 0);
  189. this.color = rgbColor;
  190. break;
  191. default:
  192. this.color = rgbColor;
  193. break;
  194. }
  195. },
  196. setBorderStyle: function Annotation_setBorderStyle(borderStyle) {
  197. this.borderStyle = new AnnotationBorderStyle();
  198. if (!isDict(borderStyle)) {
  199. return;
  200. }
  201. if (borderStyle.has('BS')) {
  202. var dict = borderStyle.get('BS');
  203. var dictType = dict.get('Type');
  204. if (!dictType || isName(dictType, 'Border')) {
  205. this.borderStyle.setWidth(dict.get('W'));
  206. this.borderStyle.setStyle(dict.get('S'));
  207. this.borderStyle.setDashArray(dict.getArray('D'));
  208. }
  209. } else if (borderStyle.has('Border')) {
  210. var array = borderStyle.getArray('Border');
  211. if (isArray(array) && array.length >= 3) {
  212. this.borderStyle.setHorizontalCornerRadius(array[0]);
  213. this.borderStyle.setVerticalCornerRadius(array[1]);
  214. this.borderStyle.setWidth(array[2]);
  215. if (array.length === 4) {
  216. this.borderStyle.setDashArray(array[3]);
  217. }
  218. }
  219. } else {
  220. this.borderStyle.setWidth(0);
  221. }
  222. },
  223. setAppearance: function Annotation_setAppearance(dict) {
  224. this.appearance = null;
  225. var appearanceStates = dict.get('AP');
  226. if (!isDict(appearanceStates)) {
  227. return;
  228. }
  229. var normalAppearanceState = appearanceStates.get('N');
  230. if (isStream(normalAppearanceState)) {
  231. this.appearance = normalAppearanceState;
  232. return;
  233. }
  234. if (!isDict(normalAppearanceState)) {
  235. return;
  236. }
  237. var as = dict.get('AS');
  238. if (!isName(as) || !normalAppearanceState.has(as.name)) {
  239. return;
  240. }
  241. this.appearance = normalAppearanceState.get(as.name);
  242. },
  243. _preparePopup: function Annotation_preparePopup(dict) {
  244. if (!dict.has('C')) {
  245. this.data.color = null;
  246. }
  247. this.data.hasPopup = dict.has('Popup');
  248. this.data.title = stringToPDFString(dict.get('T') || '');
  249. this.data.contents = stringToPDFString(dict.get('Contents') || '');
  250. },
  251. loadResources: function Annotation_loadResources(keys) {
  252. return this.appearance.dict.getAsync('Resources').then(function (resources) {
  253. if (!resources) {
  254. return;
  255. }
  256. var objectLoader = new ObjectLoader(resources.map, keys, resources.xref);
  257. return objectLoader.load().then(function () {
  258. return resources;
  259. });
  260. });
  261. },
  262. getOperatorList: function Annotation_getOperatorList(evaluator, task, renderForms) {
  263. var _this = this;
  264. if (!this.appearance) {
  265. return Promise.resolve(new OperatorList());
  266. }
  267. var data = this.data;
  268. var appearanceDict = this.appearance.dict;
  269. var resourcesPromise = this.loadResources(['ExtGState', 'ColorSpace', 'Pattern', 'Shading', 'XObject', 'Font']);
  270. var bbox = appearanceDict.getArray('BBox') || [0, 0, 1, 1];
  271. var matrix = appearanceDict.getArray('Matrix') || [1, 0, 0, 1, 0, 0];
  272. var transform = getTransformMatrix(data.rect, bbox, matrix);
  273. return resourcesPromise.then(function (resources) {
  274. var opList = new OperatorList();
  275. opList.addOp(OPS.beginAnnotation, [data.rect, transform, matrix]);
  276. return evaluator.getOperatorList({
  277. stream: _this.appearance,
  278. task: task,
  279. resources: resources,
  280. operatorList: opList
  281. }).then(function () {
  282. opList.addOp(OPS.endAnnotation, []);
  283. _this.appearance.reset();
  284. return opList;
  285. });
  286. });
  287. }
  288. };
  289. return Annotation;
  290. }();
  291. var AnnotationBorderStyle = function AnnotationBorderStyleClosure() {
  292. function AnnotationBorderStyle() {
  293. this.width = 1;
  294. this.style = AnnotationBorderStyleType.SOLID;
  295. this.dashArray = [3];
  296. this.horizontalCornerRadius = 0;
  297. this.verticalCornerRadius = 0;
  298. }
  299. AnnotationBorderStyle.prototype = {
  300. setWidth: function AnnotationBorderStyle_setWidth(width) {
  301. if (width === (width | 0)) {
  302. this.width = width;
  303. }
  304. },
  305. setStyle: function AnnotationBorderStyle_setStyle(style) {
  306. if (!style) {
  307. return;
  308. }
  309. switch (style.name) {
  310. case 'S':
  311. this.style = AnnotationBorderStyleType.SOLID;
  312. break;
  313. case 'D':
  314. this.style = AnnotationBorderStyleType.DASHED;
  315. break;
  316. case 'B':
  317. this.style = AnnotationBorderStyleType.BEVELED;
  318. break;
  319. case 'I':
  320. this.style = AnnotationBorderStyleType.INSET;
  321. break;
  322. case 'U':
  323. this.style = AnnotationBorderStyleType.UNDERLINE;
  324. break;
  325. default:
  326. break;
  327. }
  328. },
  329. setDashArray: function AnnotationBorderStyle_setDashArray(dashArray) {
  330. if (isArray(dashArray) && dashArray.length > 0) {
  331. var isValid = true;
  332. var allZeros = true;
  333. for (var i = 0, len = dashArray.length; i < len; i++) {
  334. var element = dashArray[i];
  335. var validNumber = +element >= 0;
  336. if (!validNumber) {
  337. isValid = false;
  338. break;
  339. } else if (element > 0) {
  340. allZeros = false;
  341. }
  342. }
  343. if (isValid && !allZeros) {
  344. this.dashArray = dashArray;
  345. } else {
  346. this.width = 0;
  347. }
  348. } else if (dashArray) {
  349. this.width = 0;
  350. }
  351. },
  352. setHorizontalCornerRadius: function AnnotationBorderStyle_setHorizontalCornerRadius(radius) {
  353. if (radius === (radius | 0)) {
  354. this.horizontalCornerRadius = radius;
  355. }
  356. },
  357. setVerticalCornerRadius: function AnnotationBorderStyle_setVerticalCornerRadius(radius) {
  358. if (radius === (radius | 0)) {
  359. this.verticalCornerRadius = radius;
  360. }
  361. }
  362. };
  363. return AnnotationBorderStyle;
  364. }();
  365. var WidgetAnnotation = function WidgetAnnotationClosure() {
  366. function WidgetAnnotation(params) {
  367. Annotation.call(this, params);
  368. var dict = params.dict;
  369. var data = this.data;
  370. data.annotationType = AnnotationType.WIDGET;
  371. data.fieldName = this._constructFieldName(dict);
  372. data.fieldValue = Util.getInheritableProperty(dict, 'V', true);
  373. data.alternativeText = stringToPDFString(dict.get('TU') || '');
  374. data.defaultAppearance = Util.getInheritableProperty(dict, 'DA') || '';
  375. var fieldType = Util.getInheritableProperty(dict, 'FT');
  376. data.fieldType = isName(fieldType) ? fieldType.name : null;
  377. this.fieldResources = Util.getInheritableProperty(dict, 'DR') || Dict.empty;
  378. data.fieldFlags = Util.getInheritableProperty(dict, 'Ff');
  379. if (!isInt(data.fieldFlags) || data.fieldFlags < 0) {
  380. data.fieldFlags = 0;
  381. }
  382. data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY);
  383. if (data.fieldType === 'Sig') {
  384. this.setFlags(AnnotationFlag.HIDDEN);
  385. }
  386. }
  387. Util.inherit(WidgetAnnotation, Annotation, {
  388. _constructFieldName: function WidgetAnnotation_constructFieldName(dict) {
  389. if (!dict.has('T') && !dict.has('Parent')) {
  390. warn('Unknown field name, falling back to empty field name.');
  391. return '';
  392. }
  393. if (!dict.has('Parent')) {
  394. return stringToPDFString(dict.get('T'));
  395. }
  396. var fieldName = [];
  397. if (dict.has('T')) {
  398. fieldName.unshift(stringToPDFString(dict.get('T')));
  399. }
  400. var loopDict = dict;
  401. while (loopDict.has('Parent')) {
  402. loopDict = loopDict.get('Parent');
  403. if (!isDict(loopDict)) {
  404. break;
  405. }
  406. if (loopDict.has('T')) {
  407. fieldName.unshift(stringToPDFString(loopDict.get('T')));
  408. }
  409. }
  410. return fieldName.join('.');
  411. },
  412. hasFieldFlag: function WidgetAnnotation_hasFieldFlag(flag) {
  413. return !!(this.data.fieldFlags & flag);
  414. }
  415. });
  416. return WidgetAnnotation;
  417. }();
  418. var TextWidgetAnnotation = function TextWidgetAnnotationClosure() {
  419. function TextWidgetAnnotation(params) {
  420. WidgetAnnotation.call(this, params);
  421. this.data.fieldValue = stringToPDFString(this.data.fieldValue || '');
  422. var alignment = Util.getInheritableProperty(params.dict, 'Q');
  423. if (!isInt(alignment) || alignment < 0 || alignment > 2) {
  424. alignment = null;
  425. }
  426. this.data.textAlignment = alignment;
  427. var maximumLength = Util.getInheritableProperty(params.dict, 'MaxLen');
  428. if (!isInt(maximumLength) || maximumLength < 0) {
  429. maximumLength = null;
  430. }
  431. this.data.maxLen = maximumLength;
  432. this.data.multiLine = this.hasFieldFlag(AnnotationFieldFlag.MULTILINE);
  433. this.data.comb = this.hasFieldFlag(AnnotationFieldFlag.COMB) && !this.hasFieldFlag(AnnotationFieldFlag.MULTILINE) && !this.hasFieldFlag(AnnotationFieldFlag.PASSWORD) && !this.hasFieldFlag(AnnotationFieldFlag.FILESELECT) && this.data.maxLen !== null;
  434. }
  435. Util.inherit(TextWidgetAnnotation, WidgetAnnotation, {
  436. getOperatorList: function TextWidgetAnnotation_getOperatorList(evaluator, task, renderForms) {
  437. var operatorList = new OperatorList();
  438. if (renderForms) {
  439. return Promise.resolve(operatorList);
  440. }
  441. if (this.appearance) {
  442. return Annotation.prototype.getOperatorList.call(this, evaluator, task, renderForms);
  443. }
  444. if (!this.data.defaultAppearance) {
  445. return Promise.resolve(operatorList);
  446. }
  447. var stream = new Stream(stringToBytes(this.data.defaultAppearance));
  448. return evaluator.getOperatorList({
  449. stream: stream,
  450. task: task,
  451. resources: this.fieldResources,
  452. operatorList: operatorList
  453. }).then(function () {
  454. return operatorList;
  455. });
  456. }
  457. });
  458. return TextWidgetAnnotation;
  459. }();
  460. var ButtonWidgetAnnotation = function ButtonWidgetAnnotationClosure() {
  461. function ButtonWidgetAnnotation(params) {
  462. WidgetAnnotation.call(this, params);
  463. this.data.checkBox = !this.hasFieldFlag(AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
  464. if (this.data.checkBox) {
  465. if (!isName(this.data.fieldValue)) {
  466. return;
  467. }
  468. this.data.fieldValue = this.data.fieldValue.name;
  469. }
  470. this.data.radioButton = this.hasFieldFlag(AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(AnnotationFieldFlag.PUSHBUTTON);
  471. if (this.data.radioButton) {
  472. this.data.fieldValue = this.data.buttonValue = null;
  473. var fieldParent = params.dict.get('Parent');
  474. if (isDict(fieldParent) && fieldParent.has('V')) {
  475. var fieldParentValue = fieldParent.get('V');
  476. if (isName(fieldParentValue)) {
  477. this.data.fieldValue = fieldParentValue.name;
  478. }
  479. }
  480. var appearanceStates = params.dict.get('AP');
  481. if (!isDict(appearanceStates)) {
  482. return;
  483. }
  484. var normalAppearanceState = appearanceStates.get('N');
  485. if (!isDict(normalAppearanceState)) {
  486. return;
  487. }
  488. var keys = normalAppearanceState.getKeys();
  489. for (var i = 0, ii = keys.length; i < ii; i++) {
  490. if (keys[i] !== 'Off') {
  491. this.data.buttonValue = keys[i];
  492. break;
  493. }
  494. }
  495. }
  496. }
  497. Util.inherit(ButtonWidgetAnnotation, WidgetAnnotation, {
  498. getOperatorList: function ButtonWidgetAnnotation_getOperatorList(evaluator, task, renderForms) {
  499. var operatorList = new OperatorList();
  500. if (renderForms) {
  501. return Promise.resolve(operatorList);
  502. }
  503. if (this.appearance) {
  504. return Annotation.prototype.getOperatorList.call(this, evaluator, task, renderForms);
  505. }
  506. return Promise.resolve(operatorList);
  507. }
  508. });
  509. return ButtonWidgetAnnotation;
  510. }();
  511. var ChoiceWidgetAnnotation = function ChoiceWidgetAnnotationClosure() {
  512. function ChoiceWidgetAnnotation(params) {
  513. WidgetAnnotation.call(this, params);
  514. this.data.options = [];
  515. var options = Util.getInheritableProperty(params.dict, 'Opt');
  516. if (isArray(options)) {
  517. var xref = params.xref;
  518. for (var i = 0, ii = options.length; i < ii; i++) {
  519. var option = xref.fetchIfRef(options[i]);
  520. var isOptionArray = isArray(option);
  521. this.data.options[i] = {
  522. exportValue: isOptionArray ? xref.fetchIfRef(option[0]) : option,
  523. displayValue: isOptionArray ? xref.fetchIfRef(option[1]) : option
  524. };
  525. }
  526. }
  527. if (!isArray(this.data.fieldValue)) {
  528. this.data.fieldValue = [this.data.fieldValue];
  529. }
  530. this.data.combo = this.hasFieldFlag(AnnotationFieldFlag.COMBO);
  531. this.data.multiSelect = this.hasFieldFlag(AnnotationFieldFlag.MULTISELECT);
  532. }
  533. Util.inherit(ChoiceWidgetAnnotation, WidgetAnnotation, {
  534. getOperatorList: function ChoiceWidgetAnnotation_getOperatorList(evaluator, task, renderForms) {
  535. var operatorList = new OperatorList();
  536. if (renderForms) {
  537. return Promise.resolve(operatorList);
  538. }
  539. return Annotation.prototype.getOperatorList.call(this, evaluator, task, renderForms);
  540. }
  541. });
  542. return ChoiceWidgetAnnotation;
  543. }();
  544. var TextAnnotation = function TextAnnotationClosure() {
  545. var DEFAULT_ICON_SIZE = 22;
  546. function TextAnnotation(parameters) {
  547. Annotation.call(this, parameters);
  548. this.data.annotationType = AnnotationType.TEXT;
  549. if (this.data.hasAppearance) {
  550. this.data.name = 'NoIcon';
  551. } else {
  552. this.data.rect[1] = this.data.rect[3] - DEFAULT_ICON_SIZE;
  553. this.data.rect[2] = this.data.rect[0] + DEFAULT_ICON_SIZE;
  554. this.data.name = parameters.dict.has('Name') ? parameters.dict.get('Name').name : 'Note';
  555. }
  556. this._preparePopup(parameters.dict);
  557. }
  558. Util.inherit(TextAnnotation, Annotation, {});
  559. return TextAnnotation;
  560. }();
  561. var LinkAnnotation = function LinkAnnotationClosure() {
  562. function LinkAnnotation(params) {
  563. Annotation.call(this, params);
  564. var data = this.data;
  565. data.annotationType = AnnotationType.LINK;
  566. Catalog.parseDestDictionary({
  567. destDict: params.dict,
  568. resultObj: data,
  569. docBaseUrl: params.pdfManager.docBaseUrl
  570. });
  571. }
  572. Util.inherit(LinkAnnotation, Annotation, {});
  573. return LinkAnnotation;
  574. }();
  575. var PopupAnnotation = function PopupAnnotationClosure() {
  576. function PopupAnnotation(parameters) {
  577. Annotation.call(this, parameters);
  578. this.data.annotationType = AnnotationType.POPUP;
  579. var dict = parameters.dict;
  580. var parentItem = dict.get('Parent');
  581. if (!parentItem) {
  582. warn('Popup annotation has a missing or invalid parent annotation.');
  583. return;
  584. }
  585. var parentSubtype = parentItem.get('Subtype');
  586. this.data.parentType = isName(parentSubtype) ? parentSubtype.name : null;
  587. this.data.parentId = dict.getRaw('Parent').toString();
  588. this.data.title = stringToPDFString(parentItem.get('T') || '');
  589. this.data.contents = stringToPDFString(parentItem.get('Contents') || '');
  590. if (!parentItem.has('C')) {
  591. this.data.color = null;
  592. } else {
  593. this.setColor(parentItem.getArray('C'));
  594. this.data.color = this.color;
  595. }
  596. if (!this.viewable) {
  597. var parentFlags = parentItem.get('F');
  598. if (this._isViewable(parentFlags)) {
  599. this.setFlags(parentFlags);
  600. }
  601. }
  602. }
  603. Util.inherit(PopupAnnotation, Annotation, {});
  604. return PopupAnnotation;
  605. }();
  606. var LineAnnotation = function LineAnnotationClosure() {
  607. function LineAnnotation(parameters) {
  608. Annotation.call(this, parameters);
  609. this.data.annotationType = AnnotationType.LINE;
  610. var dict = parameters.dict;
  611. this.data.lineCoordinates = Util.normalizeRect(dict.getArray('L'));
  612. this._preparePopup(dict);
  613. }
  614. Util.inherit(LineAnnotation, Annotation, {});
  615. return LineAnnotation;
  616. }();
  617. var HighlightAnnotation = function HighlightAnnotationClosure() {
  618. function HighlightAnnotation(parameters) {
  619. Annotation.call(this, parameters);
  620. this.data.annotationType = AnnotationType.HIGHLIGHT;
  621. this._preparePopup(parameters.dict);
  622. }
  623. Util.inherit(HighlightAnnotation, Annotation, {});
  624. return HighlightAnnotation;
  625. }();
  626. var UnderlineAnnotation = function UnderlineAnnotationClosure() {
  627. function UnderlineAnnotation(parameters) {
  628. Annotation.call(this, parameters);
  629. this.data.annotationType = AnnotationType.UNDERLINE;
  630. this._preparePopup(parameters.dict);
  631. }
  632. Util.inherit(UnderlineAnnotation, Annotation, {});
  633. return UnderlineAnnotation;
  634. }();
  635. var SquigglyAnnotation = function SquigglyAnnotationClosure() {
  636. function SquigglyAnnotation(parameters) {
  637. Annotation.call(this, parameters);
  638. this.data.annotationType = AnnotationType.SQUIGGLY;
  639. this._preparePopup(parameters.dict);
  640. }
  641. Util.inherit(SquigglyAnnotation, Annotation, {});
  642. return SquigglyAnnotation;
  643. }();
  644. var StrikeOutAnnotation = function StrikeOutAnnotationClosure() {
  645. function StrikeOutAnnotation(parameters) {
  646. Annotation.call(this, parameters);
  647. this.data.annotationType = AnnotationType.STRIKEOUT;
  648. this._preparePopup(parameters.dict);
  649. }
  650. Util.inherit(StrikeOutAnnotation, Annotation, {});
  651. return StrikeOutAnnotation;
  652. }();
  653. var FileAttachmentAnnotation = function FileAttachmentAnnotationClosure() {
  654. function FileAttachmentAnnotation(parameters) {
  655. Annotation.call(this, parameters);
  656. var file = new FileSpec(parameters.dict.get('FS'), parameters.xref);
  657. this.data.annotationType = AnnotationType.FILEATTACHMENT;
  658. this.data.file = file.serializable;
  659. this._preparePopup(parameters.dict);
  660. }
  661. Util.inherit(FileAttachmentAnnotation, Annotation, {});
  662. return FileAttachmentAnnotation;
  663. }();
  664. exports.Annotation = Annotation;
  665. exports.AnnotationBorderStyle = AnnotationBorderStyle;
  666. exports.AnnotationFactory = AnnotationFactory;