1/** 2 * @licstart The following is the entire license notice for the 3 * JavaScript code in this page 4 * 5 * Copyright 2023 Mozilla Foundation 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 * @licend The above is the entire license notice for the 20 * JavaScript code in this page 21 */ 22 23(function webpackUniversalModuleDefinition(root, factory) { 24 if(typeof exports === 'object' && typeof module === 'object') 25 module.exports = root.pdfjsLib = factory(); 26 else if(typeof define === 'function' && define.amd) 27 define("pdfjs-dist/build/pdf", [], () => { return (root.pdfjsLib = factory()); }); 28 else if(typeof exports === 'object') 29 exports["pdfjs-dist/build/pdf"] = root.pdfjsLib = factory(); 30 else 31 root["pdfjs-dist/build/pdf"] = root.pdfjsLib = factory(); 32})(globalThis, () => { 33return /******/ (() => { // webpackBootstrap 34/******/ "use strict"; 35/******/ var __webpack_modules__ = ([ 36/* 0 */, 37/* 1 */ 38/***/ ((__unused_webpack_module, exports) => { 39 40 41 42Object.defineProperty(exports, "__esModule", ({ 43 value: true 44})); 45exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.RenderingIntentFlag = exports.PromiseCapability = exp
45orts.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.MAX_IMAGE_SIZE_TO_CACHE = exports.LINE_FACTOR = exports.LINE_DESCENT_FACTOR = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FeatureTest = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.CMapCompressionType = exports.BaseException = exports.BASELINE_FACTOR = exports.AnnotationType = exports.AnnotationReplyType = exports.AnnotationPrefix = exports.AnnotationMode = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationEditorType = exports.AnnotationEditorPrefix = exports.AnnotationEditorParamsType = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0; 46exports.assert = assert; 47exports.bytesToString = bytesToString; 48exports.createValidAbsoluteUrl = createValidAbsoluteUrl; 49exports.getModificationDate = getModificationDate; 50exports.getUuid = getUuid; 51exports.getVerbosityLevel = getVerbosityLevel; 52exports.info = info; 53exports.isArrayBuffer = isArrayBuffer; 54exports.isArrayEqual = isArrayEqual; 55exports.isNodeJS = void 0; 56exports.normalizeUnicode = normalizeUnicode; 57exports.objectFromMap = objectFromMap; 58exports.objectSize = objectSize; 59exports.setVerbosityLevel = setVerbosityLevel; 60exports.shadow = shadow; 61exports.string32 = string32; 62exports.stringToBytes = stringToBytes; 63exports.stringToPDFString = stringToPDFString; 64exports.stringToUTF8String = stringToUTF8String; 65exports.unreachable = unreachable; 66exports.utf8StringToString = utf8StringToString; 67exports.warn = warn; 68const isNodeJS = typeof process === "object" && process + "" === "[object process]" && !process.versions.nw && !(process.versions.electron && process.type && process.type !== "browser");
vendor: 18,729 bytes, lines 69-756
69exports.isNodeJS = isNodeJS; 70const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; 71exports.IDENTITY_MATRIX = IDENTITY_MATRIX; 72const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0]; 73exports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX; 74const MAX_IMAGE_SIZE_TO_CACHE = 10e6; 75exports.MAX_IMAGE_SIZE_TO_CACHE = MAX_IMAGE_SIZE_TO_CACHE; 76const LINE_FACTOR = 1.35; 77exports.LINE_FACTOR = LINE_FACTOR; 78const LINE_DESCENT_FACTOR = 0.35; 79exports.LINE_DESCENT_FACTOR = LINE_DESCENT_FACTOR; 80const BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR; 81exports.BASELINE_FACTOR = BASELINE_FACTOR; 82const RenderingIntentFlag = { 83 ANY: 0x01, 84 DISPLAY: 0x02, 85 PRINT: 0x04, 86 SAVE: 0x08, 87 ANNOTATIONS_FORMS: 0x10, 88 ANNOTATIONS_STORAGE: 0x20, 89 ANNOTATIONS_DISABLE: 0x40, 90 OPLIST: 0x100 91}; 92exports.RenderingIntentFlag = RenderingIntentFlag; 93const AnnotationMode = { 94 DISABLE: 0, 95 ENABLE: 1, 96 ENABLE_FORMS: 2, 97 ENABLE_STORAGE: 3 98}; 99exports.AnnotationMode = AnnotationMode; 100const AnnotationEditorPrefix = "pdfjs_internal_editor_"; 101exports.AnnotationEditorPrefix = AnnotationEditorPrefix; 102const AnnotationEditorType = { 103 DISABLE: -1, 104 NONE: 0, 105 FREETEXT: 3, 106 STAMP: 13, 107 INK: 15 108}; 109exports.AnnotationEditorType = AnnotationEditorType; 110const AnnotationEditorParamsType = { 111 RESIZE: 1, 112 CREATE: 2, 113 FREETEXT_SIZE: 11, 114 FREETEXT_COLOR: 12, 115 FREETEXT_OPACITY: 13, 116 INK_COLOR: 21, 117 INK_THICKNESS: 22, 118 INK_OPACITY: 23 119}; 120exports.AnnotationEditorParamsType = AnnotationEditorParamsType; 121const PermissionFlag = { 122 PRINT: 0x04, 123 MODIFY_CONTENTS: 0x08, 124 COPY: 0x10, 125 MODIFY_ANNOTATIONS: 0x20, 126 FILL_INTERACTIVE_FORMS: 0x100, 127 COPY_FOR_ACCESSIBILITY: 0x200, 128 ASSEMBLE: 0x400, 129 PRINT_HIGH_QUALITY: 0x800 130}; 131exports.PermissionFlag = PermissionFlag; 132const TextRenderingMode = { 133 FILL: 0, 134 STROKE: 1, 135 FILL_STROKE: 2, 136 INVISIBLE: 3, 137 FILL_ADD_TO_PATH: 4, 138 STROKE_ADD_TO_PATH: 5, 139 FILL_STROKE_ADD_TO_PATH: 6, 140 ADD_TO_PATH: 7, 141 FILL_STROKE_MASK: 3, 142 ADD_TO_PATH_FLAG: 4 143}; 144exports.TextRenderingMode = TextRenderingMode; 145const ImageKind = { 146 GRAYSCALE_1BPP: 1, 147 RGB_24BPP: 2, 148 RGBA_32BPP: 3 149}; 150exports.ImageKind = ImageKind; 151const AnnotationType = { 152 TEXT: 1, 153 LINK: 2, 154 FREETEXT: 3, 155 LINE: 4, 156 SQUARE: 5, 157 CIRCLE: 6, 158 POLYGON: 7, 159 POLYLINE: 8, 160 HIGHLIGHT: 9, 161 UNDERLINE: 10, 162 SQUIGGLY: 11, 163 STRIKEOUT: 12, 164 STAMP: 13, 165 CARET: 14, 166 INK: 15, 167 POPUP: 16, 168 FILEATTACHMENT: 17, 169 SOUND: 18, 170 MOVIE: 19, 171 WIDGET: 20, 172 SCREEN: 21, 173 PRINTERMARK: 22, 174 TRAPNET: 23, 175 WATERMARK: 24, 176 THREED: 25, 177 REDACT: 26 178}; 179exports.AnnotationType = AnnotationType; 180const AnnotationReplyType = { 181 GROUP: "Group", 182 REPLY: "R" 183}; 184exports.AnnotationReplyType = AnnotationReplyType; 185const AnnotationFlag = { 186 INVISIBLE: 0x01, 187 HIDDEN: 0x02, 188 PRINT: 0x04, 189 NOZOOM: 0x08, 190 NOROTATE: 0x10, 191 NOVIEW: 0x20, 192 READONLY: 0x40, 193 LOCKED: 0x80, 194 TOGGLENOVIEW: 0x100, 195 LOCKEDCONTENTS: 0x200 196}; 197exports.AnnotationFlag = AnnotationFlag; 198const AnnotationFieldFlag = { 199 READONLY: 0x0000001, 200 REQUIRED: 0x0000002, 201 NOEXPORT: 0x0000004, 202 MULTILINE: 0x0001000, 203 PASSWORD: 0x0002000, 204 NOTOGGLETOOFF: 0x0004000, 205 RADIO: 0x0008000, 206 PUSHBUTTON: 0x0010000, 207 COMBO: 0x0020000, 208 EDIT: 0x0040000, 209 SORT: 0x0080000, 210 FILESELECT: 0x0100000, 211 MULTISELECT: 0x0200000, 212 DONOTSPELLCHECK: 0x0400000, 213 DONOTSCROLL: 0x0800000, 214 COMB: 0x1000000, 215 RICHTEXT: 0x2000000, 216 RADIOSINUNISON: 0x2000000, 217 COMMITONSELCHANGE: 0x4000000 218}; 219exports.AnnotationFieldFlag = AnnotationFieldFlag; 220const AnnotationBorderStyleType = { 221 SOLID: 1, 222 DASHED: 2, 223 BEVELED: 3, 224 INSET: 4, 225 UNDERLINE: 5 226}; 227exports.AnnotationBorderStyleType = AnnotationBorderStyleType; 228const AnnotationActionEventType = { 229 E: "Mouse Enter", 230 X: "Mouse Exit", 231 D: "Mouse Down", 232 U: "Mouse Up", 233 Fo: "Focus", 234 Bl: "Blur", 235 PO: "PageOpen", 236 PC: "PageClose", 237 PV: "PageVisible", 238 PI: "PageInvisible", 239 K: "Keystroke", 240 F: "Format", 241 V: "Validate", 242 C: "Calculate" 243}; 244exports.AnnotationActionEventType = AnnotationActionEventType; 245const DocumentActionEventType = { 246 WC: "WillClose", 247 WS: "WillSave", 248 DS: "DidSave", 249 WP: "WillPrint", 250 DP: "DidPrint" 251}; 252exports.DocumentActionEventType = DocumentActionEventType; 253const PageActionEventType = { 254 O: "PageOpen", 255 C: "PageClose" 256}; 257exports.PageActionEventType = PageActionEventType; 258const VerbosityLevel = { 259 ERRORS: 0, 260 WARNINGS: 1, 261 INFOS: 5 262}; 263exports.VerbosityLevel = VerbosityLevel; 264const CMapCompressionType = { 265 NONE: 0, 266 BINARY: 1 267}; 268exports.CMapCompressionType = CMapCompressionType; 269const OPS = { 270 dependency: 1, 271 setLineWidth: 2, 272 setLineCap: 3, 273 setLineJoin: 4, 274 setMiterLimit: 5, 275 setDash: 6, 276 setRenderingIntent: 7, 277 setFlatness: 8, 278 setGState: 9, 279 save: 10, 280 restore: 11, 281 transform: 12, 282 moveTo: 13, 283 lineTo: 14, 284 curveTo: 15, 285 curveTo2: 16, 286 curveTo3: 17, 287 closePath: 18, 288 rectangle: 19, 289 stroke: 20, 290 closeStroke: 21, 291 fill: 22, 292 eoFill: 23, 293 fillStroke: 24, 294 eoFillStroke: 25, 295 closeFillStroke: 26, 296 closeEOFillStroke: 27, 297 endPath: 28, 298 clip: 29, 299 eoClip: 30, 300 beginText: 31, 301 endText: 32, 302 setCharSpacing: 33, 303 setWordSpacing: 34, 304 setHScale: 35, 305 setLeading: 36, 306 setFont: 37, 307 setTextRenderingMode: 38, 308 setTextRise: 39, 309 moveText: 40, 310 setLeadingMoveText: 41, 311 setTextMatrix: 42, 312 nextLine: 43, 313 showText: 44, 314 showSpacedText: 45, 315 nextLineShowText: 46, 316 nextLineSetSpacingShowText: 47, 317 setCharWidth: 48, 318 setCharWidthAndBounds: 49, 319 setStrokeColorSpace: 50, 320 setFillColorSpace: 51, 321 setStrokeColor: 52, 322 setStrokeColorN: 53, 323 setFillColor: 54, 324 setFillColorN: 55, 325 setStrokeGray: 56, 326 setFillGray: 57, 327 setStrokeRGBColor: 58, 328 setFillRGBColor: 59, 329 setStrokeCMYKColor: 60, 330 setFillCMYKColor: 61, 331 shadingFill: 62, 332 beginInlineImage: 63, 333 beginImageData: 64, 334 endInlineImage: 65, 335 paintXObject: 66, 336 markPoint: 67, 337 markPointProps: 68, 338 beginMarkedContent: 69, 339 beginMarkedContentProps: 70, 340 endMarkedContent: 71, 341 beginCompat: 72, 342 endCompat: 73, 343 paintFormXObjectBegin: 74, 344 paintFormXObjectEnd: 75, 345 beginGroup: 76, 346 endGroup: 77, 347 beginAnnotation: 80, 348 endAnnotation: 81, 349 paintImageMaskXObject: 83, 350 paintImageMaskXObjectGroup: 84, 351 paintImageXObject: 85, 352 paintInlineImageXObject: 86, 353 paintInlineImageXObjectGroup: 87, 354 paintImageXObjectRepeat: 88, 355 paintImageMaskXObjectRepeat: 89, 356 paintSolidColorImageMask: 90, 357 constructPath: 91 358}; 359exports.OPS = OPS; 360const PasswordResponses = { 361 NEED_PASSWORD: 1, 362 INCORRECT_PASSWORD: 2 363}; 364exports.PasswordResponses = PasswordResponses; 365let verbosity = VerbosityLevel.WARNINGS; 366function setVerbosityLevel(level) { 367 if (Number.isInteger(level)) { 368 verbosity = level; 369 } 370} 371function getVerbosityLevel() { 372 return verbosity; 373} 374function info(msg) { 375 if (verbosity >= VerbosityLevel.INFOS) { 376 console.log(`Info: ${msg}`); 377 } 378} 379function warn(msg) { 380 if (verbosity >= VerbosityLevel.WARNINGS) { 381 console.log(`Warning: ${msg}`); 382 } 383} 384function unreachable(msg) { 385 throw new Error(msg); 386} 387function assert(cond, msg) { 388 if (!cond) { 389 unreachable(msg); 390 } 391} 392function _isValidProtocol(url) { 393 switch (url?.protocol) { 394 case "http:": 395 case "https:": 396 case "ftp:": 397 case "mailto:": 398 case "tel:": 399 return true; 400 default: 401 return false; 402 } 403} 404function createValidAbsoluteUrl(url, baseUrl = null, options = null) { 405 if (!url) { 406 return null; 407 } 408 try { 409 if (options && typeof url === "string") { 410 if (options.addDefaultProtocol && url.startsWith("www.")) { 411 const dots = url.match(/\./g); 412 if (dots?.length >= 2) { 413 url = `http://${url}`; 414 } 415 } 416 if (options.tryConvertEncoding) { 417 try { 418 url = stringToUTF8String(url); 419 } catch {} 420 } 421 } 422 const absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url); 423 if (_isValidProtocol(absoluteUrl)) { 424 return absoluteUrl; 425 } 426 } catch {} 427 return null; 428} 429function shadow(obj, prop, value, nonSerializable = false) { 430 Object.defineProperty(obj, prop, { 431 value, 432 enumerable: !nonSerializable, 433 configurable: true, 434 writable: false 435 }); 436 return value; 437} 438const BaseException = function BaseExceptionClosure() { 439 function BaseException(message, name) { 440 if (this.constructor === BaseException) { 441 unreachable("Cannot initialize BaseException."); 442 } 443 this.message = message; 444 this.name = name; 445 } 446 BaseException.prototype = new Error(); 447 BaseException.constructor = BaseException; 448 return BaseException; 449}(); 450exports.BaseException = BaseException; 451class PasswordException extends BaseException { 452 constructor(msg, code) { 453 super(msg, "PasswordException"); 454 this.code = code; 455 } 456} 457exports.PasswordException = PasswordException; 458class UnknownErrorException extends BaseException { 459 constructor(msg, details) { 460 super(msg, "UnknownErrorException"); 461 this.details = details; 462 } 463} 464exports.UnknownErrorException = UnknownErrorException; 465class InvalidPDFException extends BaseException { 466 constructor(msg) { 467 super(msg, "InvalidPDFException"); 468 } 469} 470exports.InvalidPDFException = InvalidPDFException; 471class MissingPDFException extends BaseException { 472 constructor(msg) { 473 super(msg, "MissingPDFException"); 474 } 475} 476exports.MissingPDFException = MissingPDFException; 477class UnexpectedResponseException extends BaseException { 478 constructor(msg, status) { 479 super(msg, "UnexpectedResponseException"); 480 this.status = status; 481 } 482} 483exports.UnexpectedResponseException = UnexpectedResponseException; 484class FormatError extends BaseException { 485 constructor(msg) { 486 super(msg, "FormatError"); 487 } 488} 489exports.FormatError = FormatError; 490class AbortException extends BaseException { 491 constructor(msg) { 492 super(msg, "AbortException"); 493 } 494} 495exports.AbortException = AbortException; 496function bytesToString(bytes) { 497 if (typeof bytes !== "object" || bytes?.length === undefined) { 498 unreachable("Invalid argument for bytesToString"); 499 } 500 const length = bytes.length; 501 const MAX_ARGUMENT_COUNT = 8192; 502 if (length < MAX_ARGUMENT_COUNT) { 503 return String.fromCharCode.apply(null, bytes); 504 } 505 const strBuf = []; 506 for (let i = 0; i < length; i += MAX_ARGUMENT_COUNT) { 507 const chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length); 508 const chunk = bytes.subarray(i, chunkEnd); 509 strBuf.push(String.fromCharCode.apply(null, chunk)); 510 } 511 return strBuf.join(""); 512} 513function stringToBytes(str) { 514 if (typeof str !== "string") { 515 unreachable("Invalid argument for stringToBytes"); 516 } 517 const length = str.length; 518 const bytes = new Uint8Array(length); 519 for (let i = 0; i < length; ++i) { 520 bytes[i] = str.charCodeAt(i) & 0xff; 521 } 522 return bytes; 523} 524function string32(value) { 525 return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff); 526} 527function objectSize(obj) { 528 return Object.keys(obj).length; 529} 530function objectFromMap(map) { 531 const obj = Object.create(null); 532 for (const [key, value] of map) { 533 obj[key] = value; 534 } 535 return obj; 536} 537function isLittleEndian() { 538 const buffer8 = new Uint8Array(4); 539 buffer8[0] = 1; 540 const view32 = new Uint32Array(buffer8.buffer, 0, 1); 541 return view32[0] === 1; 542} 543function isEvalSupported() { 544 try { 545 new Function(""); 546 return true; 547 } catch { 548 return false; 549 } 550} 551class FeatureTest { 552 static get isLittleEndian() { 553 return shadow(this, "isLittleEndian", isLittleEndian()); 554 } 555 static get isEvalSupported() { 556 return shadow(this, "isEvalSupported", isEvalSupported()); 557 } 558 static get isOffscreenCanvasSupported() { 559 return shadow(this, "isOffscreenCanvasSupported", typeof OffscreenCanvas !== "undefined"); 560 } 561 static get platform() { 562 if (typeof navigator === "undefined") { 563 return shadow(this, "platform", { 564 isWin: false, 565 isMac: false 566 }); 567 } 568 return shadow(this, "platform", { 569 isWin: navigator.platform.includes("Win"), 570 isMac: navigator.platform.includes("Mac") 571 }); 572 } 573 static get isCSSRoundSupported() { 574 return shadow(this, "isCSSRoundSupported", globalThis.CSS?.supports?.("width: round(1.5px, 1px)")); 575 } 576} 577exports.FeatureTest = FeatureTest; 578const hexNumbers = [...Array(256).keys()].map(n => n.toString(16).padStart(2, "0")); 579class Util { 580 static makeHexColor(r, g, b) { 581 return `#${hexNumbers[r]}${hexNumbers[g]}${hexNumbers[b]}`; 582 } 583 static scaleMinMax(transform, minMax) { 584 let temp; 585 if (transform[0]) { 586 if (transform[0] < 0) { 587 temp = minMax[0]; 588 minMax[0] = minMax[1]; 589 minMax[1] = temp; 590 } 591 minMax[0] *= transform[0]; 592 minMax[1] *= transform[0]; 593 if (transform[3] < 0) { 594 temp = minMax[2]; 595 minMax[2] = minMax[3]; 596 minMax[3] = temp; 597 } 598 minMax[2] *= transform[3]; 599 minMax[3] *= transform[3]; 600 } else { 601 temp = minMax[0]; 602 minMax[0] = minMax[2]; 603 minMax[2] = temp; 604 temp = minMax[1]; 605 minMax[1] = minMax[3]; 606 minMax[3] = temp; 607 if (transform[1] < 0) { 608 temp = minMax[2]; 609 minMax[2] = minMax[3]; 610 minMax[3] = temp; 611 } 612 minMax[2] *= transform[1]; 613 minMax[3] *= transform[1]; 614 if (transform[2] < 0) { 615 temp = minMax[0]; 616 minMax[0] = minMax[1]; 617 minMax[1] = temp; 618 } 619 minMax[0] *= transform[2]; 620 minMax[1] *= transform[2]; 621 } 622 minMax[0] += transform[4]; 623 minMax[1] += transform[4]; 624 minMax[2] += transform[5]; 625 minMax[3] += transform[5]; 626 } 627 static transform(m1, m2) { 628 return [m1[0] * m2[0] + m1[2] * m2[1], m1[1] * m2[0] + m1[3] * m2[1], m1[0] * m2[2] + m1[2] * m2[3], m1[1] * m2[2] + m1[3] * m2[3], m1[0] * m2[4] + m1[2] * m2[5] + m1[4], m1[1] * m2[4] + m1[3] * m2[5] + m1[5]]; 629 } 630 static applyTransform(p, m) { 631 const xt = p[0] * m[0] + p[1] * m[2] + m[4]; 632 const yt = p[0] * m[1] + p[1] * m[3] + m[5]; 633 return [xt, yt]; 634 } 635 static applyInverseTransform(p, m) { 636 const d = m[0] * m[3] - m[1] * m[2]; 637 const xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d; 638 const yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d; 639 return [xt, yt]; 640 } 641 static getAxialAlignedBoundingBox(r, m) { 642 const p1 = this.applyTransform(r, m); 643 const p2 = this.applyTransform(r.slice(2, 4), m); 644 const p3 = this.applyTransform([r[0], r[3]], m); 645 const p4 = this.applyTransform([r[2], r[1]], m); 646 return [Math.min(p1[0], p2[0], p3[0], p4[0]), Math.min(p1[1], p2[1], p3[1], p4[1]), Math.max(p1[0], p2[0], p3[0], p4[0]), Math.max(p1[1], p2[1], p3[1], p4[1])]; 647 } 648 static inverseTransform(m) { 649 const d = m[0] * m[3] - m[1] * m[2]; 650 return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d, (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d]; 651 } 652 static singularValueDecompose2dScale(m) { 653 const transpose = [m[0], m[2], m[1], m[3]]; 654 const a = m[0] * transpose[0] + m[1] * transpose[2]; 655 const b = m[0] * transpose[1] + m[1] * transpose[3]; 656 const c = m[2] * transpose[0] + m[3] * transpose[2]; 657 const d = m[2] * transpose[1] + m[3] * transpose[3]; 658 const first = (a + d) / 2; 659 const second = Math.sqrt((a + d) ** 2 - 4 * (a * d - c * b)) / 2; 660 const sx = first + second || 1; 661 const sy = first - second || 1; 662 return [Math.sqrt(sx), Math.sqrt(sy)]; 663 } 664 static normalizeRect(rect) { 665 const r = rect.slice(0); 666 if (rect[0] > rect[2]) { 667 r[0] = rect[2]; 668 r[2] = rect[0]; 669 } 670 if (rect[1] > rect[3]) { 671 r[1] = rect[3]; 672 r[3] = rect[1]; 673 } 674 return r; 675 } 676 static intersect(rect1, rect2) { 677 const xLow = Math.max(Math.min(rect1[0], rect1[2]), Math.min(rect2[0], rect2[2])); 678 const xHigh = Math.min(Math.max(rect1[0], rect1[2]), Math.max(rect2[0], rect2[2])); 679 if (xLow > xHigh) { 680 return null; 681 } 682 const yLow = Math.max(Math.min(rect1[1], rect1[3]), Math.min(rect2[1], rect2[3])); 683 const yHigh = Math.min(Math.max(rect1[1], rect1[3]), Math.max(rect2[1], rect2[3])); 684 if (yLow > yHigh) { 685 return null; 686 } 687 return [xLow, yLow, xHigh, yHigh]; 688 } 689 static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3) { 690 const tvalues = [], 691 bounds = [[], []]; 692 let a, b, c, t, t1, t2, b2ac, sqrtb2ac; 693 for (let i = 0; i < 2; ++i) { 694 if (i === 0) { 695 b = 6 * x0 - 12 * x1 + 6 * x2; 696 a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; 697 c = 3 * x1 - 3 * x0; 698 } else { 699 b = 6 * y0 - 12 * y1 + 6 * y2; 700 a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; 701 c = 3 * y1 - 3 * y0; 702 } 703 if (Math.abs(a) < 1e-12) { 704 if (Math.abs(b) < 1e-12) { 705 continue; 706 } 707 t = -c / b; 708 if (0 < t && t < 1) { 709 tvalues.push(t); 710 } 711 continue; 712 } 713 b2ac = b * b - 4 * c * a; 714 sqrtb2ac = Math.sqrt(b2ac); 715 if (b2ac < 0) { 716 continue; 717 } 718 t1 = (-b + sqrtb2ac) / (2 * a); 719 if (0 < t1 && t1 < 1) { 720 tvalues.push(t1); 721 } 722 t2 = (-b - sqrtb2ac) / (2 * a); 723 if (0 < t2 && t2 < 1) { 724 tvalues.push(t2); 725 } 726 } 727 let j = tvalues.length, 728 mt; 729 const jlen = j; 730 while (j--) { 731 t = tvalues[j]; 732 mt = 1 - t; 733 bounds[0][j] = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3; 734 bounds[1][j] = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3; 735 } 736 bounds[0][jlen] = x0; 737 bounds[1][jlen] = y0; 738 bounds[0][jlen + 1] = x3; 739 bounds[1][jlen + 1] = y3; 740 bounds[0].length = bounds[1].length = jlen + 2; 741 return [Math.min(...bounds[0]), Math.min(...bounds[1]), Math.max(...bounds[0]), Math.max(...bounds[1])]; 742 } 743} 744exports.Util = Util; 745const PDFStringTranslateTable = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2d8, 0x2c7, 0x2c6, 0x2d9, 0x2dd, 0x2db, 0x2da, 0x2dc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x141, 0x152, 0x160, 0x178, 0x17d, 0x131, 0x142, 0x153, 0x161, 0x17e, 0, 0x20ac]; 746function stringToPDFString(str) { 747 if (str[0] >= "\xEF") { 748 let encoding; 749 if (str[0] === "\xFE" && str[1] === "\xFF") { 750 encoding = "utf-16be"; 751 } else if (str[0] === "\xFF" && str[1] === "\xFE") { 752 encoding = "utf-16le"; 753 } else if (str[0] === "\xEF" && str[1] === "\xBB" && str[2] === "\xBF") { 754 encoding = "utf-8"; 755 } 756 if (encoding) {
757 try { 758 const decoder = new TextDecoder(encoding, { 759 fatal: true 760 }); 761 const buffer = stringToBytes(str); 762 return decoder.decode(buffer); 763 } catch (ex) { 764 warn(`stringToPDFString: "${ex}".`); 765 } 766 } 767 } 768 const strBuf = []; 769 for (let i = 0, ii = str.length; i < ii; i++) { 770 const code = PDFStringTranslateTable[str.charCodeAt(i)]; 771 strBuf.push(code ? String.fromCharCode(code) : str.charAt(i)); 772 } 773 return strBuf.join(""); 774} 775function stringToUTF8String(str) { 776 return decodeURIComponent(escape(str)); 777} 778function utf8StringToString(str) { 779 return unescape(encodeURIComponent(str)); 780} 781function isArrayBuffer(v) { 782 return typeof v === "object" && v?.byteLength !== undefined; 783} 784function isArrayEqual(arr1, arr2) { 785 if (arr1.length !== arr2.length) { 786 return false; 787 } 788 for (let i = 0, ii = arr1.length; i < ii; i++) { 789 if (arr1[i] !== arr2[i]) { 790 return false; 791 } 792 } 793 return true; 794} 795function getModificationDate(date = new Date()) { 796 const buffer = [date.getUTCFullYear().toString(), (date.getUTCMonth() + 1).toString().padStart(2, "0"), date.getUTCDate().toString().padStart(2, "0"), date.getUTCHours().toString().padStart(2, "0"), date.getUTCMinutes().toString().padStart(2, "0"), date.getUTCSeconds().toString().padStart(2, "0")]; 797 return buffer.join(""); 798} 799class PromiseCapability { 800 #settled = false; 801 constructor() { 802 this.promise = new Promise((resolve, reject) => { 803 this.resolve = data => { 804 this.#settled = true; 805 resolve(data); 806 }; 807 this.reject = reason => { 808 this.#settled = true; 809 reject(reason); 810 }; 811 }); 812 } 813 get settled() { 814 return this.#settled; 815 } 816} 817exports.PromiseCapability = PromiseCapability; 818let NormalizeRegex = null; 819let NormalizationMap = null; 820function normalizeUnicode(str) { 821 if (!NormalizeRegex) { 822 NormalizeRegex = /([\u00a0\u00b5\u037e\u0eb3\u2000-\u200a\u202f\u2126\ufb00-\ufb04\ufb06\ufb20-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufba1\ufba4-\ufba9\ufbae-\ufbb1\ufbd3-\ufbdc\ufbde-\ufbe7\ufbea-\ufbf8\ufbfc-\ufbfd\ufc00-\ufc5d\ufc64-\ufcf1\ufcf5-\ufd3d\ufd88\ufdf4\ufdfa-\ufdfb\ufe71\ufe77\ufe79\ufe7b\ufe7d]+)|(\ufb05+)/gu; 823 NormalizationMap = new Map([["ſt", "ſt"]]); 824 } 825 return str.replaceAll(NormalizeRegex, (_, p1, p2) => { 826 return p1 ? p1.normalize("NFKC") : NormalizationMap.get(p2); 827 }); 828} 829function getUuid() { 830 if (typeof crypto !== "undefined" && typeof crypto?.randomUUID === "function") { 831 return crypto.randomUUID(); 832 } 833 const buf = new Uint8Array(32); 834 if (typeof crypto !== "undefined" && typeof crypto?.getRandomValues === "function") { 835 crypto.getRandomValues(buf); 836 } else { 837 for (let i = 0; i < 32; i++) { 838 buf[i] = Math.floor(Math.random() * 255); 839 } 840 } 841 return bytesToString(buf); 842} 843const AnnotationPrefix = "pdfjs_internal_id_"; 844exports.AnnotationPrefix = AnnotationPrefix; 845 846/***/ }), 847/* 2 */ 848/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 849 850 851 852Object.defineProperty(exports, "__esModule", ({ 853 value: true 854})); 855exports.RenderTask = exports.PDFWorkerUtil = exports.PDFWorker = exports.PDFPageProxy = exports.PDFDocumentProxy = exports.PDFDocumentLoadingTask = exports.PDFDataRangeTransport = exports.LoopbackPort = exports.DefaultStandardFontDataFactory = exports.DefaultFilterFactory = exports.DefaultCanvasFactory = exports.DefaultCMapReaderFactory = void 0; 856Object.defineProperty(exports, "SVGGraphics", ({ 857 enumerable: true, 858 get: function () { 859 return _displaySvg.SVGGraphics; 860 } 861})); 862exports.build = void 0; 863exports.getDocument = getDocument; 864exports.version = void 0; 865var _util = __w_pdfjs_require__(1); 866var _annotation_storage = __w_pdfjs_require__(3); 867var _display_utils = __w_pdfjs_require__(6); 868var _font_loader = __w_pdfjs_require__(9); 869var _displayNode_utils = __w_pdfjs_require__(10); 870var _canvas = __w_pdfjs_require__(11); 871var _worker_options = __w_pdfjs_require__(14); 872var _message_handler = __w_pdfjs_require__(15); 873var _metadata = __w_pdfjs_require__(16); 874var _optional_content_config = __w_pdfjs_require__(17); 875var _transport_stream = __w_pdfjs_require__(18); 876var _displayFetch_stream = __w_pdfjs_require__(19); 877var _displayNetwork = __w_pdfjs_require__(22); 878var _displayNode_stream = __w_pdfjs_require__(23); 879var _displaySvg = __w_pdfjs_require__(24); 880var _xfa_text = __w_pdfjs_require__(25); 881const DEFAULT_RANGE_CHUNK_SIZE = 65536; 882const RENDERING_CANCELLED_TIMEOUT = 100; 883const DELAYED_CLEANUP_TIMEOUT = 5000; 884const DefaultCanvasFactory = _util.isNodeJS ? _displayNode_utils.NodeCanvasFactory : _display_utils.DOMCanvasFactory; 885exports.DefaultCanvasFactory = DefaultCanvasFactory; 886const DefaultCMapReaderFactory = _util.isNodeJS ? _displayNode_utils.NodeCMapReaderFactory : _display_utils.DOMCMapReaderFactory; 887exports.DefaultCMapReaderFactory = DefaultCMapReaderFactory; 888const DefaultFilterFactory = _util.isNodeJS ? _displayNode_utils.NodeFilterFactory : _display_utils.DOMFilterFactory; 889exports.DefaultFilterFactory = DefaultFilterFactory; 890const DefaultStandardFontDataFactory = _util.isNodeJS ? _displayNode_utils.NodeStandardFontDataFactory : _display_utils.DOMStandardFontDataFactory; 891exports.DefaultStandardFontDataFactory = DefaultStandardFontDataFactory; 892function getDocument(src) { 893 if (typeof src === "string" || src instanceof URL) { 894 src = { 895 url: src 896 }; 897 } else if ((0, _util.isArrayBuffer)(src)) { 898 src = { 899 data: src 900 }; 901 } 902 if (typeof src !== "object") { 903 throw new Error("Invalid parameter in getDocument, need parameter object."); 904 } 905 if (!src.url && !src.data && !src.range) { 906 throw new Error("Invalid parameter object: need either .data, .range or .url"); 907 } 908 const task = new PDFDocumentLoadingTask(); 909 const { 910 docId 911 } = task; 912 const url = src.url ? getUrlProp(src.url) : null; 913 const data = src.data ? getDataProp(src.data) : null; 914 const httpHeaders = src.httpHeaders || null; 915 const withCredentials = src.withCredentials === true; 916 const password = src.password ?? null; 917 const rangeTransport = src.range instanceof PDFDataRangeTransport ? src.range : null; 918 const rangeChunkSize = Number.isInteger(src.rangeChunkSize) && src.rangeChunkSize > 0 ? src.rangeChunkSize : DEFAULT_RANGE_CHUNK_SIZE; 919 let worker = src.worker instanceof PDFWorker ? src.worker : null; 920 const verbosity = src.verbosity; 921 const docBaseUrl = typeof src.docBaseUrl === "string" && !(0, _display_utils.isDataScheme)(src.docBaseUrl) ? src.docBaseUrl : null; 922 const cMapUrl = typeof src.cMapUrl === "string" ? src.cMapUrl : null; 923 const cMapPacked = src.cMapPacked !== false; 924 const CMapReaderFactory = src.CMapReaderFactory || DefaultCMapReaderFactory; 925 const standardFontDataUrl = typeof src.standardFontDataUrl === "string" ? src.standardFontDataUrl : null; 926 const StandardFontDataFactory = src.StandardFontDataFactory || DefaultStandardFontDataFactory; 927 const ignoreErrors = src.stopAtErrors !== true; 928 const maxImageSize = Number.isInteger(src.maxImageSize) && src.maxImageSize > -1 ? src.maxImageSize : -1; 929 const isEvalSupported = src.isEvalSupported !== false; 930 const isOffscreenCanvasSupported = typeof src.isOffscreenCanvasSupported === "boolean" ? src.isOffscreenCanvasSupported : !_util.isNodeJS; 931 const canvasMaxAreaInBytes = Number.isInteger(src.canvasMaxAreaInBytes) ? src.canvasMaxAreaInBytes :
931-1; 932 const disableFontFace = typeof src.disableFontFace === "boolean" ? src.disableFontFace : _util.isNodeJS; 933 const fontExtraProperties = src.fontExtraProperties === true; 934 const enableXfa = src.enableXfa === true; 935 const ownerDocument = src.ownerDocument || globalThis.document; 936 const disableRange = src.disableRange === true; 937 const disableStream = src.disableStream === true; 938 const disableAutoFetch = src.disableAutoFetch === true; 939 const pdfBug = src.pdfBug === true; 940 const length = rangeTransport ? rangeTransport.length : src.length ?? NaN; 941 const useSystemFonts = typeof src.useSystemFonts === "boolean" ? src.useSystemFonts : !_util.isNodeJS && !disableFontFace; 942 const useWorkerFetch = typeof src.useWorkerFetch === "boolean" ? src.useWorkerFetch : CMapReaderFactory === _display_utils.DOMCMapReaderFactory && StandardFontDataFactory === _display_utils.DOMStandardFontDataFactory && cMapUrl && standardFontDataUrl && (0, _display_utils.isValidFetchUrl)(cMapUrl, document.baseURI) && (0, _display_utils.isValidFetchUrl)(standardFontDataUrl, document.baseURI); 943 const canvasFactory = src.canvasFactory || new DefaultCanvasFactory({ 944 ownerDocument 945 }); 946 const filterFactory = src.filterFactory || new DefaultFilterFactory({ 947 docId, 948 ownerDocument 949 }); 950 const styleElement = null; 951 (0, _util.setVerbosityLevel)(verbosity); 952 const transportFactory = { 953 canvasFactory, 954 filterFactory 955 }; 956 if (!useWorkerFetch) { 957 transportFactory.cMapReaderFactory = new CMapReaderFactory({ 958 baseUrl: cMapUrl, 959 isCompressed: cMapPacked 960 }); 961 transportFactory.standardFontDataFactory = new StandardFontDataFactory({ 962 baseUrl: standardFontDataUrl 963 }); 964 } 965 if (!worker) { 966 const workerParams = { 967 verbosity, 968 port: _worker_options.GlobalWorkerOptions.workerPort 969 }; 970 worker = workerParams.port ? PDFWorker.fromPort(workerParams) : new PDFWorker(workerParams); 971 task._worker = worker; 972 } 973 const fetchDocParams = { 974 docId, 975 apiVersion: '3.11.174', 976 data, 977 password, 978 disableAutoFetch, 979 rangeChunkSize, 980 length, 981 docBaseUrl, 982 enableXfa, 983 evaluatorOptions: { 984 maxImageSize, 985 disableFontFace, 986 ignoreErrors, 987 isEvalSupported, 988 isOffscreenCanvasSupported, 989 canvasMaxAreaInBytes, 990 fontExtraProperties, 991 useSystemFonts, 992 cMapUrl: useWorkerFetch ? cMapUrl : null, 993 standardFontDataUrl: useWorkerFetch ? standardFontDataUrl : null 994 } 995 }; 996 const transportParams = { 997 ignoreErrors, 998 isEvalSupported, 999 disableFontFace, 1000 fontExtraProperties, 1001 enableXfa, 1002 ownerDocument, 1003 disableAutoFetch, 1004 pdfBug, 1005 styleElement 1006 }; 1007 worker.promise.then(function () { 1008 if (task.destroyed) { 1009 throw new Error("Loading aborted"); 1010 } 1011 const workerIdPromise = _fetchDocument(worker, fetchDocParams); 1012 const networkStreamPromise = new Promise(function (resolve) { 1013 let networkStream; 1014 if (rangeTransport) { 1015 networkStream = new _transport_stream.PDFDataTransportStream({ 1016 length, 1017 initialData: rangeTransport.initialData, 1018 progressiveDone: rangeTransport.progressiveDone, 1019 contentDispositionFilename: rangeTransport.contentDispositionFilename, 1020 disableRange, 1021 disableStream 1022 }, rangeTransport); 1023 } else if (!data) { 1024 const createPDFNetworkStream = params => { 1025 if (_util.isNodeJS) { 1026 return new _displayNode_stream.PDFNodeStream(params); 1027 } 1028 return (0, _display_utils.isValidFetchUrl)(params.url) ? new _displayFetch_stream.PDFFetchStream(params) : new _displayNetwork.PDFNetworkStream(params); 1029 }; 1030 networkStream = createPDFNetworkStream({ 1031 url, 1032 length, 1033 httpHeaders, 1034 withCredentials, 1035 rangeChunkSize, 1036 disableRange, 1037 disableStream 1038 }); 1039 } 1040 resolve(networkStream); 1041 }); 1042 return Promise.all([workerIdPromise, networkStreamPromise]).then(function ([workerId, networkStream]) { 1043 if (task.destroyed) { 1044 throw new Error("Loading aborted"); 1045 } 1046 const messageHandler = new _message_handler.MessageHandler(docId, workerId, worker.port); 1047 const transport = new WorkerTransport(messageHandler, task, networkStream, transportParams, transportFactory); 1048 task._transport = transport; 1049 messageHandler.send("Ready", null); 1050 }); 1051 }).catch(task._capability.reject); 1052 return task; 1053} 1054async function _fetchDocument(worker, source) { 1055 if (worker.destroyed) { 1056 throw new Error("Worker was destroyed"); 1057 }
1058 const workerId = await worker.messageHandler.sendWithPromise("GetDocRequest", source, source.data ? [source.data.buffer] : null); 1059 if (worker.destroyed) { 1060 throw new Error("Worker was destroyed"); 1061 } 1062 return workerId; 1063} 1064function getUrlProp(val) { 1065 if (val instanceof URL) { 1066 return val.href; 1067 } 1068 try { 1069 return new URL(val, window.location).href; 1070 } catch { 1071 if (_util.isNodeJS && typeof val === "string") { 1072 return val; 1073 } 1074 } 1075 throw new Error("Invalid PDF url data: " + "either string or URL-object is expected in the url property."); 1076} 1077function getDataProp(val) { 1078 if (_util.isNodeJS && typeof Buffer !== "undefined" && val instanceof Buffer) { 1079 throw new Error("Please provide binary data as `Uint8Array`, rather than `Buffer`."); 1080 } 1081 if (val instanceof Uint8Array && val.byteLength === val.buffer.byteLength) { 1082 return val; 1083 } 1084 if (typeof val === "string") { 1085 return (0, _util.stringToBytes)(val); 1086 } 1087 if (typeof val === "object" && !isNaN(val?.length) || (0, _util.isArrayBuffer)(val)) { 1088 return new Uint8Array(val); 1089 } 1090 throw new Error("Invalid PDF binary data: either TypedArray, " + "string, or array-like object is expected in the data property."); 1091} 1092class PDFDocumentLoadingTask { 1093 static #docId = 0; 1094 constructor() { 1095 this._capability = new _util.PromiseCapability(); 1096 this._transport = null; 1097 this._worker = null; 1098 this.docId = `d${PDFDocumentLoadingTask.#docId++}`; 1099 this.destroyed = false; 1100 this.onPassword = null; 1101 this.onProgress = null; 1102 } 1103 get promise() { 1104 return this._capability.promise; 1105 } 1106 async destroy() { 1107 this.destroyed = true; 1108 try { 1109 if (this._worker?.port) { 1110 this._worker._pendingDestroy = true; 1111 } 1112 await this._transport?.destroy(); 1113 } catch (ex) { 1114 if (this._worker?.port) { 1115 delete this._worker._pendingDestroy; 1116 } 1117 throw ex; 1118 } 1119 this._transport = null; 1120 if (this._worker) { 1121 this._worker.destroy(); 1122 this._worker = null; 1123 } 1124 } 1125} 1126exports.PDFDocumentLoadingTask = PDFDocumentLoadingTask; 1127class PDFDataRangeTransport { 1128 constructor(length, initialData, progressiveDone = false, contentDispositionFilename = null) { 1129 this.length = length; 1130 this.initialData = initialData; 1131 this.progressiveDone = progressiveDone; 1132 this.contentDispositionFilename = contentDispositionFilename; 1133 this._rangeListeners = []; 1134 this._progressListeners = []; 1135 this._progressiveReadListeners = []; 1136 this._progressiveDoneListeners = []; 1137 this._readyCapability = new _util.PromiseCapability(); 1138 } 1139 addRangeListener(listener) { 1140 this._rangeListeners.push(listener); 1141 } 1142 addProgressListener(listener) { 1143 this._progressListeners.push(listener); 1144 } 1145 addProgressiveReadListener(listener) { 1146 this._progressiveReadListeners.push(listener); 1147 } 1148 addProgressiveDoneListener(listener) { 1149 this._progressiveDoneListeners.push(listener); 1150 } 1151 onDataRange(begin, chunk) { 1152 for (const listener of this._rangeListeners) { 1153 listener(begin, chunk); 1154 } 1155 } 1156 onDataProgress(loaded, total) { 1157 this._readyCapability.promise.then(() => { 1158 for (const listener of this._progressListeners) { 1159 listener(loaded, total); 1160 } 1161 }); 1162 } 1163 onDataProgressiveRead(chunk) { 1164 this._readyCapability.promise.then(() => { 1165 for (const listener of this._progressiveReadListeners) { 1166 listener(chunk); 1167 } 1168 }); 1169 } 1170 onDataProgressiveDone() { 1171 this._readyCapability.promise.then(() => { 1172 for (const listener of this._progressiveDoneListeners) { 1173 listener(); 1174 } 1175 }); 1176 } 1177 transportReady() { 1178 this._readyCapability.resolve(); 1179 } 1180 requestDataRange(begin, end) { 1181 (0, _util.unreachable)("Abstract method PDFDataRangeTransport.requestDataRange"); 1182 } 1183 abort() {} 1184} 1185exports.PDFDataRangeTransport = PDFDataRangeTransport; 1186class PDFDocumentProxy { 1187 constructor(pdfInfo, transport) { 1188 this._pdfInfo = pdfInfo; 1189 this._transport = transport; 1190 Object.defineProperty(this, "getJavaScript", { 1191 value: () => { 1192 (0, _display_utils.deprecated)("`PDFDocumentProxy.getJavaScript`, " + "please use `PDFDocumentProxy.getJSActions` instead."); 1193 return this.getJSActions().then(js => { 1194 if (!js) { 1195 return js; 1196 } 1197 const jsArr = []; 1198 for (const name in js) { 1199 jsArr.push(...js[name]); 1200 } 1201 return jsArr; 1202 }); 1203 } 1204 }); 1205 } 1206 get annotationStorage() { 1207 return this._transport.annotationStorage; 1208 } 1209 get filterFactory() { 1210 return this._transport.filterFactory; 1211 } 1212 get numPages() { 1213 return this._pdfInfo.numPages; 1214 } 1215 get fingerprints() { 1216 return this._pdfInfo.fingerprints; 1217 } 1218 get isPureXfa() { 1219 return (0, _util.shadow)(this, "isPureXfa", !!this._transport._htmlForXfa); 1220 } 1221 get allXfaHtml() { 1222 return this._transport._htmlForXfa; 1223 } 1224 getPage(pageNumber) { 1225 return this._transport.getPage(pageNumber); 1226 } 1227 getPageIndex(ref) { 1228 return this._transport.getPageIndex(ref); 1229 } 1230 getDestinations() { 1231 return this._transport.getDestinations(); 1232 } 1233 getDestination(id) { 1234 return this._transport.getDestination(id); 1235 } 1236 getPageLabels() { 1237 return this._transport.getPageLabels(); 1238 } 1239 getPageLayout() { 1240 return this._transport.getPageLayout(); 1241 } 1242 getPageMode() { 1243 return this._transport.getPageMode(); 1244 } 1245 getViewerPreferences() { 1246 return this._transport.getViewerPreferences(); 1247 } 1248 getOpenAction() { 1249 return this._transport.getOpenAction(); 1250 } 1251 getAttachments() { 1252 return this._transport.getAttachments(); 1253 } 1254 getJSActions() { 1255 return this._transport.getDocJSActions(); 1256 } 1257 getOutline() { 1258 return this._transport.getOutline(); 1259 } 1260 getOptionalContentConfig() { 1261 return this._transport.getOptionalContentConfig(); 1262 } 1263 getPermissions() { 1264 return this._transport.getPermissions(); 1265 } 1266 getMetadata() { 1267 return this._transport.getMetadata(); 1268 } 1269 getMarkInfo() { 1270 return this._transport.getMarkInfo(); 1271 } 1272 getData() { 1273 return this._transport.getData(); 1274 } 1275 saveDocument() { 1276 return this._transport.saveDocument(); 1277 } 1278 getDownloadInfo() { 1279 return this._transport.downloadInfoCapability.promise; 1280 } 1281 cleanup(keepLoadedFonts = false) { 1282 return this._transport.startCleanup(keepLoadedFonts || this.isPureXfa); 1283 } 1284 destroy() { 1285 return this.loadingTask.destroy(); 1286 } 1287 get loadingParams() { 1288 return this._transport.loadingParams; 1289 } 1290 get loadingTask() { 1291 return this._transport.loadingTask; 1292 } 1293 getFieldObjects() { 1294 return this._transport.getFieldObjects(); 1295 } 1296 hasJSActions() { 1297 return this._transport.hasJSActions(); 1298 } 1299 getCalculationOrderIds() { 1300 return this._transport.getCalculationOrderIds(); 1301 } 1302} 1303exports.PDFDocumentProxy = PDFDocumentProxy; 1304class PDFPageProxy { 1305 #delayedCleanupTimeout = null; 1306 #pendingCleanup = false;
1307 constructor(pageIndex, pageInfo, transport, pdfBug = false) { 1308 this._pageIndex = pageIndex; 1309 this._pageInfo = pageInfo; 1310 this._transport = transport; 1311 this._stats = pdfBug ? new _display_utils.StatTimer() : null; 1312 this._pdfBug = pdfBug; 1313 this.commonObjs = transport.commonObjs; 1314 this.objs = new PDFObjects(); 1315 this._maybeCleanupAfterRender = false; 1316 this._intentStates = new Map(); 1317 this.destroyed = false; 1318 } 1319 get pageNumber() { 1320 return this._pageIndex + 1; 1321 } 1322 get rotate() { 1323 return this._pageInfo.rotate; 1324 } 1325 get ref() { 1326 return this._pageInfo.ref; 1327 } 1328 get userUnit() { 1329 return this._pageInfo.userUnit; 1330 } 1331 get view() { 1332 return this._pageInfo.view; 1333 } 1334 getViewport({ 1335 scale, 1336 rotation = this.rotate, 1337 offsetX = 0, 1338 offsetY = 0, 1339 dontFlip = false 1340 } = {}) { 1341 return new _display_utils.PageViewport({ 1342 viewBox: this.view, 1343 scale, 1344 rotation, 1345 offsetX, 1346 offsetY, 1347 dontFlip 1348 }); 1349 } 1350 getAnnotations({ 1351 intent = "display" 1352 } = {}) { 1353 const intentArgs = this._transport.getRenderingIntent(intent); 1354 return this._transport.getAnnotations(this._pageIndex, intentArgs.renderingIntent); 1355 } 1356 getJSActions() { 1357 return this._transport.getPageJSActions(this._pageIndex); 1358 } 1359 get filterFactory() { 1360 return this._transport.filterFactory; 1361 } 1362 get isPureXfa() { 1363 return (0, _util.shadow)(this, "isPureXfa", !!this._transport._htmlForXfa); 1364 } 1365 async getXfa() { 1366 return this._transport._htmlForXfa?.children[this._pageIndex] || null; 1367 } 1368 render({ 1369 canvasContext, 1370 viewport, 1371 intent = "display", 1372 annotationMode = _util.AnnotationMode.ENABLE, 1373 transform = null, 1374 background = null, 1375 optionalContentConfigPromise = null, 1376 annotationCanvasMap = null, 1377 pageColors = null, 1378 printAnnotationStorage = null 1379 }) { 1380 this._stats?.time("Overall"); 1381 const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage); 1382 this.#pendingCleanup = false; 1383 this.#abortDelayedCleanup(); 1384 if (!optionalContentConfigPromise) { 1385 optionalContentConfigPromise = this._transport.getOptionalContentConfig(); 1386 } 1387 let intentState = this._intentStates.get(intentArgs.cacheKey); 1388 if (!intentState) { 1389 intentState = Object.create(null); 1390 this._intentStates.set(intentArgs.cacheKey, intentState); 1391 } 1392 if (intentState.streamReaderCancelTimeout) { 1393 clearTimeout(intentState.streamReaderCancelTimeout); 1394 intentState.streamReaderCancelTimeout = null; 1395 } 1396 const intentPrint = !!(intentArgs.renderingIntent & _util.RenderingIntentFlag.PRINT); 1397 if (!intentState.displayReadyCapability) { 1398 intentState.displayReadyCapability = new _util.PromiseCapability(); 1399 intentState.operatorList = { 1400 fnArray: [], 1401 argsArray: [], 1402 lastChunk: false, 1403 separateAnnots: null 1404 }; 1405 this._stats?.time("Page Request"); 1406 this._pumpOperatorList(intentArgs); 1407 } 1408 const complete = error => { 1409 intentState.renderTasks.delete(internalRenderTask); 1410 if (this._maybeCleanupAfterRender || intentPrint) { 1411 this.#pendingCleanup = true; 1412 } 1413 this.#tryCleanup(!intentPrint); 1414 if (error) { 1415 internalRenderTask.capability.reject(error); 1416 this._abortOperatorList({ 1417 intentState, 1418 reason: error instanceof Error ? error : new Error(error) 1419 }); 1420 } else { 1421 internalRenderTask.capability.resolve(); 1422 } 1423 this._stats?.timeEnd("Rendering"); 1424 this._stats?.timeEnd("Overall"); 1425 }; 1426 const internalRenderTask = new InternalRenderTask({ 1427 callback: complete, 1428 params: { 1429 canvasContext, 1430 viewport, 1431 transform, 1432 background 1433 }, 1434 objs: this.objs, 1435 commonObjs: this.commonObjs, 1436 annotationCanvasMap, 1437 operatorList: intentState.operatorList, 1438 pageIndex: this._pageIndex, 1439 canvasFactory: this._transport.canvasFactory, 1440 filterFactory: this._transport.filterFactory, 1441 useRequestAnimationFrame: !intentPrint, 1442 pdfBug: this._pdfBug, 1443 pageColors 1444 }); 1445 (intentState.renderTasks ||= new Set()).add(internalRenderTask); 1446 const renderTask = internalRenderTask.task; 1447 Promise.all([intentState.displayReadyCapability.promise, optionalContentConfigPromise]).then(([transparency, optionalContentConfig]) => { 1448 if (this.destroyed) { 1449 complete(); 1450 return; 1451 }
1452 this._stats?.time("Rendering"); 1453 internalRenderTask.initializeGraphics({ 1454 transparency, 1455 optionalContentConfig 1456 }); 1457 internalRenderTask.operatorListChanged(); 1458 }).catch(complete); 1459 return renderTask; 1460 } 1461 getOperatorList({ 1462 intent = "display", 1463 annotationMode = _util.AnnotationMode.ENABLE, 1464 printAnnotationStorage = null 1465 } = {}) { 1466 function operatorListChanged() { 1467 if (intentState.operatorList.lastChunk) { 1468 intentState.opListReadCapability.resolve(intentState.operatorList); 1469 intentState.renderTasks.delete(opListTask); 1470 } 1471 } 1472 const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage, true); 1473 let intentState = this._intentStates.get(intentArgs.cacheKey); 1474 if (!intentState) { 1475 intentState = Object.create(null); 1476 this._intentStates.set(intentArgs.cacheKey, intentState); 1477 } 1478 let opListTask; 1479 if (!intentState.opListReadCapability) { 1480 opListTask = Object.create(null); 1481 opListTask.operatorListChanged = operatorListChanged; 1482 intentState.opListReadCapability = new _util.PromiseCapability(); 1483 (intentState.renderTasks ||= new Set()).add(opListTask); 1484 intentState.operatorList = { 1485 fnArray: [], 1486 argsArray: [], 1487 lastChunk: false, 1488 separateAnnots: null 1489 }; 1490 this._stats?.time("Page Request"); 1491 this._pumpOperatorList(intentArgs); 1492 } 1493 return intentState.opListReadCapability.promise; 1494 } 1495 streamTextContent({ 1496 includeMarkedContent = false, 1497 disableNormalization = false 1498 } = {}) { 1499 const TEXT_CONTENT_CHUNK_SIZE = 100; 1500 return this._transport.messageHandler.sendWithStream("GetTextContent", { 1501 pageIndex: this._pageIndex, 1502 includeMarkedContent: includeMarkedContent === true, 1503 disableNormalization: disableNormalization === true 1504 }, { 1505 highWaterMark: TEXT_CONTENT_CHUNK_SIZE, 1506 size(textContent) { 1507 return textContent.items.length; 1508 } 1509 }); 1510 } 1511 getTextContent(params = {}) { 1512 if (this._transport._htmlForXfa) { 1513 return this.getXfa().then(xfa => { 1514 return _xfa_text.XfaText.textContent(xfa); 1515 }); 1516 } 1517 const readableStream = this.streamTextContent(params); 1518 return new Promise(function (resolve, reject) { 1519 function pump() { 1520 reader.read().then(function ({ 1521 value, 1522 done 1523 }) { 1524 if (done) { 1525 resolve(textContent); 1526 return; 1527 } 1528 Object.assign(textContent.styles, value.styles); 1529 textContent.items.push(...value.items); 1530 pump(); 1531 }, reject); 1532 } 1533 const reader = readableStream.getReader(); 1534 const textContent = { 1535 items: [], 1536 styles: Object.create(null) 1537 }; 1538 pump(); 1539 }); 1540 } 1541 getStructTree() { 1542 return this._transport.getStructTree(this._pageIndex); 1543 } 1544 _destroy() { 1545 this.destroyed = true; 1546 const waitOn = []; 1547 for (const intentState of this._intentStates.values()) { 1548 this._abortOperatorList({ 1549 intentState, 1550 reason: new Error("Page was destroyed."), 1551 force: true 1552 }); 1553 if (intentState.opListReadCapability) { 1554 continue; 1555 } 1556 for (const internalRenderTask of intentState.renderTasks) { 1557 waitOn.push(internalRenderTask.completed); 1558 internalRenderTask.cancel(); 1559 } 1560 } 1561 this.objs.clear(); 1562 this.#pendingCleanup = false; 1563 this.#abortDelayedCleanup(); 1564 return Promise.all(waitOn); 1565 } 1566 cleanup(resetStats = false) { 1567 this.#pendingCleanup = true; 1568 const success = this.#tryCleanup(false); 1569 if (resetStats && success) { 1570 this._stats &&= new _display_utils.StatTimer(); 1571 } 1572 return success; 1573 } 1574 #tryCleanup(delayed = false) { 1575 this.#abortDelayedCleanup(); 1576 if (!this.#pendingCleanup || this.destroyed) { 1577 return false; 1578 } 1579 if (delayed) { 1580 this.#delayedCleanupTimeout = setTimeout(() => { 1581 this.#delayedCleanupTimeout = null; 1582 this.#tryCleanup(false); 1583 }, DELAYED_CLEANUP_TIMEOUT); 1584 return false;
1585 } 1586 for (const { 1587 renderTasks, 1588 operatorList 1589 } of this._intentStates.values()) { 1590 if (renderTasks.size > 0 || !operatorList.lastChunk) { 1591 return false; 1592 } 1593 } 1594 this._intentStates.clear(); 1595 this.objs.clear(); 1596 this.#pendingCleanup = false; 1597 return true; 1598 } 1599 #abortDelayedCleanup() { 1600 if (this.#delayedCleanupTimeout) { 1601 clearTimeout(this.#delayedCleanupTimeout); 1602 this.#delayedCleanupTimeout = null; 1603 } 1604 } 1605 _startRenderPage(transparency, cacheKey) { 1606 const intentState = this._intentStates.get(cacheKey); 1607 if (!intentState) { 1608 return; 1609 } 1610 this._stats?.timeEnd("Page Request"); 1611 intentState.displayReadyCapability?.resolve(transparency); 1612 } 1613 _renderPageChunk(operatorListChunk, intentState) { 1614 for (let i = 0, ii = operatorListChunk.length; i < ii; i++) { 1615 intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]); 1616 intentState.operatorList.argsArray.push(operatorListChunk.argsArray[i]); 1617 } 1618 intentState.operatorList.lastChunk = operatorListChunk.lastChunk; 1619 intentState.operatorList.separateAnnots = operatorListChunk.separateAnnots; 1620 for (const internalRenderTask of intentState.renderTasks) { 1621 internalRenderTask.operatorListChanged(); 1622 } 1623 if (operatorListChunk.lastChunk) { 1624 this.#tryCleanup(true); 1625 } 1626 } 1627 _pumpOperatorList({ 1628 renderingIntent, 1629 cacheKey, 1630 annotationStorageSerializable 1631 }) { 1632 const { 1633 map, 1634 transfers 1635 } = annotationStorageSerializable; 1636 const readableStream = this._transport.messageHandler.sendWithStream("GetOperatorList", { 1637 pageIndex: this._pageIndex, 1638 intent: renderingIntent, 1639 cacheKey, 1640 annotationStorage: map 1641 }, transfers); 1642 const reader = readableStream.getReader(); 1643 const intentState = this._intentStates.get(cacheKey); 1644 intentState.streamReader = reader; 1645 const pump = () => { 1646 reader.read().then(({ 1647 value, 1648 done 1649 }) => { 1650 if (done) { 1651 intentState.streamReader = null; 1652 return; 1653 } 1654 if (this._transport.destroyed) { 1655 return; 1656 } 1657 this._renderPageChunk(value, intentState); 1658 pump(); 1659 }, reason => { 1660 intentState.streamReader = null; 1661 if (this._transport.destroyed) { 1662 return; 1663 } 1664 if (intentState.operatorList) { 1665 intentState.operatorList.lastChunk = true; 1666 for (const internalRenderTask of intentState.renderTasks) { 1667 internalRenderTask.operatorListChanged(); 1668 } 1669 this.#tryCleanup(true); 1670 } 1671 if (intentState.displayReadyCapability) { 1672 intentState.displayReadyCapability.reject(reason); 1673 } else if (intentState.opListReadCapability) { 1674 intentState.opListReadCapability.reject(reason); 1675 } else { 1676 throw reason; 1677 } 1678 }); 1679 }; 1680 pump(); 1681 } 1682 _abortOperatorList({ 1683 intentState, 1684 reason, 1685 force = false 1686 }) { 1687 if (!intentState.streamReader) { 1688 return; 1689 } 1690 if (intentState.streamReaderCancelTimeout) { 1691 clearTimeout(intentState.streamReaderCancelTimeout); 1692 intentState.streamReaderCancelTimeout = null; 1693 } 1694 if (!force) { 1695 if (intentState.renderTasks.size > 0) { 1696 return; 1697 } 1698 if (reason instanceof _display_utils.RenderingCancelledException) { 1699 let delay = RENDERING_CANCELLED_TIMEOUT; 1700 if (reason.extraDelay > 0 && reason.extraDelay < 1000) { 1701 delay += reason.extraDelay; 1702 } 1703 intentState.streamReaderCancelTimeout = setTimeout(() => { 1704 intentState.streamReaderCancelTimeout = null; 1705 this._abortOperatorList({ 1706 intentState, 1707 reason, 1708 force: true 1709 }); 1710 }, delay); 1711 return; 1712 } 1713 } 1714 intentState.streamReader.cancel(new _util.AbortException(reason.message)).catch(() => {}); 1715 intentState.streamReader = null; 1716 if (this._transport.destroyed) { 1717 return; 1718 } 1719 for (const [curCacheKey, curIntentState] of this._intentStates) { 1720 if (curIntentState === intentState) { 1721 this._intentStates.delete(curCacheKey); 1722 break; 1723 } 1724 } 1725 this.cleanup(); 1726 } 1727 get stats() { 1728 return this._stats; 1729 } 1730} 1731exports.PDFPageProxy = PDFPageProxy; 1732class LoopbackPort { 1733 #listeners = new Set(); 1734 #deferred = Promise.resolve(); 1735 postMessage(obj, transfer) { 1736 const event = { 1737 data: structuredClone(obj, transfer ? { 1738 transfer 1739 } : null) 1740 }; 1741 this.#deferred.then(() => { 1742 for (const listener of this.#listeners) { 1743 listener.call(this, event); 1744 } 1745 }); 1746 } 1747 addEventListener(name, listener) { 1748 this.#listeners.add(listener); 1749 } 1750 removeEventListener(name, listener) { 1751 this.#listeners.delete(listener); 1752 } 1753 terminate() { 1754 this.#listeners.clear(); 1755 } 1756} 1757exports.LoopbackPort = LoopbackPort; 1758const PDFWorkerUtil = { 1759 isWorkerDisabled: false, 1760 fallbackWorkerSrc: null, 1761 fakeWorkerId: 0 1762}; 1763exports.PDFWorkerUtil = PDFWorkerUtil; 1764{ 1765 if (_util.isNodeJS && typeof require === "function") { 1766 PDFWorkerUtil.isWorkerDisabled = true; 1767 PDFWorkerUtil.fallbackWorkerSrc = "./pdf.worker.js"; 1768 } else if (typeof document === "object") { 1769 const pdfjsFilePath = document?.currentScript?.src; 1770 if (pdfjsFilePath) { 1771 PDFWorkerUtil.fallbackWorkerSrc = pdfjsFilePath.replace(/(\.(?:min\.)?js)(\?.*)?$/i, ".w
1771orker$1$2"); 1772 } 1773 } 1774 PDFWorkerUtil.isSameOrigin = function (baseUrl, otherUrl) { 1775 let base; 1776 try { 1777 base = new URL(baseUrl); 1778 if (!base.origin || base.origin === "null") { 1779 return false; 1780 } 1781 } catch { 1782 return false; 1783 } 1784 const other = new URL(otherUrl, base); 1785 return base.origin === other.origin; 1786 }; 1787 PDFWorkerUtil.createCDNWrapper = function (url) { 1788 const wrapper = `importScripts("${url}");`; 1789 return URL.createObjectURL(new Blob([wrapper])); 1790 }; 1791} 1792class PDFWorker { 1793 static #workerPorts; 1794 constructor({ 1795 name = null, 1796 port = null, 1797 verbosity = (0, _util.getVerbosityLevel)() 1798 } = {}) { 1799 this.name = name; 1800 this.destroyed = false; 1801 this.verbosity = verbosity; 1802 this._readyCapability = new _util.PromiseCapability(); 1803 this._port = null; 1804 this._webWorker = null; 1805 this._messageHandler = null; 1806 if (port) { 1807 if (PDFWorker.#workerPorts?.has(port)) { 1808 throw new Error("Cannot use more than one PDFWorker per port."); 1809 } 1810 (PDFWorker.#workerPorts ||= new WeakMap()).set(port, this); 1811 this._initializeFromPort(port); 1812 return; 1813 } 1814 this._initialize(); 1815 } 1816 get promise() { 1817 return this._readyCapability.promise; 1818 } 1819 get port() { 1820 return this._port; 1821 } 1822 get messageHandler() { 1823 return this._messageHandler; 1824 } 1825 _initializeFromPort(port) { 1826 this._port = port; 1827 this._messageHandler = new _message_handler.MessageHandler("main", "worker", port); 1828 this._messageHandler.on("ready", function () {}); 1829 this._readyCapability.resolve(); 1830 this._messageHandler.send("configure", { 1831 verbosity: this.verbosity 1832 }); 1833 } 1834 _initialize() { 1835 if (!PDFWorkerUtil.isWorkerDisabled && !PDFWorker._mainThreadWorkerMessageHandler) { 1836 let { 1837 workerSrc 1838 } = PDFWorker; 1839 try { 1840 if (!PDFWorkerUtil.isSameOrigin(window.location.href, workerSrc)) { 1841 workerSrc = PDFWorkerUtil.createCDNWrapper(new URL(workerSrc, window.location).href); 1842 } 1843 const worker = new Worker(workerSrc); 1844 const messageHandler = new _message_handler.MessageHandler("main", "worker", worker); 1845 const terminateEarly = () => { 1846 worker.removeEventListener("error", onWorkerError); 1847 messageHandler.destroy(); 1848 worker.terminate(); 1849 if (this.destroyed) { 1850 this._readyCapability.reject(new Error("Worker was destroyed")); 1851 } else { 1852 this._setupFakeWorker(); 1853 } 1854 }; 1855 const onWorkerError = () => { 1856 if (!this._webWorker) { 1857 terminateEarly(); 1858 } 1859 }; 1860 worker.addEventListener("error", onWorkerError); 1861 messageHandler.on("test", data => { 1862 worker.removeEventListener("error", onWorkerError); 1863 if (this.destroyed) { 1864 terminateEarly(); 1865 return; 1866 } 1867 if (data) { 1868 this._messageHandler = messageHandler; 1869 this._port = worker; 1870 this._webWorker = worker; 1871 this._readyCapability.resolve(); 1872 messageHandler.send("configure", { 1873 verbosity: this.verbosity 1874 }); 1875 } else { 1876 this._setupFakeWorker(); 1877 messageHandler.destroy(); 1878 worker.terminate(); 1879 } 1880 }); 1881 messageHandler.on("ready", data => { 1882 worker.removeEventListener("error", onWorkerError); 1883 if (this.destroyed) { 1884 terminateEarly(); 1885 return; 1886 } 1887 try { 1888 sendTest(); 1889 } catch { 1890 this._setupFakeWorker(); 1891 } 1892 }); 1893 const sendTest = () => { 1894 const testObj = new Uint8Array(); 1895 messageHandler.send("test", testObj, [testObj.buffer]); 1896 }; 1897 sendTest(); 1898 return; 1899 } catch { 1900 (0, _util.info)("The worker has been disabled."); 1901 } 1902 } 1903 this._setupFakeWorker(); 1904 } 1905 _setupFakeWorker() { 1906 if (!PDFWorkerUtil.isWorkerDisabled) { 1907 (0, _util.warn)("Setting up fake worker."); 1908 PDFWorkerUtil.isWorkerDisabled = true; 1909 } 1910 PDFWorker._setupFakeWorkerGlobal.then(WorkerMessageHandler => { 1911 if (this.destroyed) { 1912 this._readyCapability.reject(new Error("Worker was destroyed")); 1913 return; 1914 } 1915 const port = new LoopbackPort(); 1916 this._port = port;
1917 const id = `fake${PDFWorkerUtil.fakeWorkerId++}`; 1918 const workerHandler = new _message_handler.MessageHandler(id + "_worker", id, port); 1919 WorkerMessageHandler.setup(workerHandler, port); 1920 const messageHandler = new _message_handler.MessageHandler(id, id + "_worker", port); 1921 this._messageHandler = messageHandler; 1922 this._readyCapability.resolve(); 1923 messageHandler.send("configure", { 1924 verbosity: this.verbosity 1925 }); 1926 }).catch(reason => { 1927 this._readyCapability.reject(new Error(`Setting up fake worker failed: "${reason.message}".`)); 1928 }); 1929 } 1930 destroy() { 1931 this.destroyed = true; 1932 if (this._webWorker) { 1933 this._webWorker.terminate(); 1934 this._webWorker = null; 1935 } 1936 PDFWorker.#workerPorts?.delete(this._port); 1937 this._port = null; 1938 if (this._messageHandler) { 1939 this._messageHandler.destroy(); 1940 this._messageHandler = null; 1941 } 1942 } 1943 static fromPort(params) { 1944 if (!params?.port) { 1945 throw new Error("PDFWorker.fromPort - invalid method signature."); 1946 } 1947 const cachedPort = this.#workerPorts?.get(params.port); 1948 if (cachedPort) { 1949 if (cachedPort._pendingDestroy) { 1950 throw new Error("PDFWorker.fromPort - the worker is being destroyed.\n" + "Please remember to await `PDFDocumentLoadingTask.destroy()`-calls."); 1951 } 1952 return cachedPort; 1953 } 1954 return new PDFWorker(params); 1955 } 1956 static get workerSrc() { 1957 if (_worker_options.GlobalWorkerOptions.workerSrc) { 1958 return _worker_options.GlobalWorkerOptions.workerSrc; 1959 } 1960 if (PDFWorkerUtil.fallbackWorkerSrc !== null) { 1961 if (!_util.isNodeJS) { 1962 (0, _display_utils.deprecated)('No "GlobalWorkerOptions.workerSrc" specified.'); 1963 } 1964 return PDFWorkerUtil.fallbackWorkerSrc; 1965 } 1966 throw new Error('No "GlobalWorkerOptions.workerSrc" specified.'); 1967 } 1968 static get _mainThreadWorkerMessageHandler() { 1969 try { 1970 return globalThis.pdfjsWorker?.WorkerMessageHandler || null; 1971 } catch { 1972 return null; 1973 } 1974 } 1975 static get _setupFakeWorkerGlobal() { 1976 const loader = async () => { 1977 const mainWorkerMessageHandler = this._mainThreadWorkerMessageHandler; 1978 if (mainWorkerMessageHandler) { 1979 return mainWorkerMessageHandler; 1980 } 1981 if (_util.isNodeJS && typeof require === "function") { 1982 const worker = eval("require")(this.workerSrc); 1983 return worker.WorkerMessageHandler; 1984 } 1985 await (0, _display_utils.loadScript)(this.workerSrc); 1986 return window.pdfjsWorker.WorkerMessageHandler; 1987 }; 1988 return (0, _util.shadow)(this, "_setupFakeWorkerGlobal", loader()); 1989 } 1990} 1991exports.PDFWorker = PDFWorker; 1992class WorkerTransport { 1993 #methodPromises = new Map(); 1994 #pageCache = new Map(); 1995 #pagePromises = new Map(); 1996 #passwordCapability = null; 1997 constructor(messageHandler, loadingTask, networkStream, params, factory) { 1998 this.messageHandler = messageHandler; 1999 this.loadingTask = loadingTask; 2000 this.commonObjs = new PDFObjects(); 2001 this.fontLoader = new _font_loader.FontLoader({ 2002 ownerDocument: params.ownerDocument, 2003 styleElement: params.styleElement 2004 }); 2005 this._params = params; 2006 this.canvasFactory = factory.canvasFactory; 2007 this.filterFactory = factory.filterFactory; 2008 this.cMapReaderFactory = factory.cMapReaderFactory; 2009 this.standardFontDataFactory = factory.standardFontDataFactory; 2010 this.destroyed = false; 2011 this.destroyCapability = null; 2012 this._networkStream = networkStream; 2013 this._fullReader = null; 2014 this._lastProgress = null; 2015 this.downloadInfoCapability = new _util.PromiseCapability(); 2016 this.setupMessageHandler(); 2017 } 2018 #cacheSimpleMethod(name, data = null) { 2019 const cachedPromise = this.#methodPromises.get(name); 2020 if (cachedPromise) { 2021 return cachedPromise; 2022 } 2023 const promise = this.messageHandler.sendWithPromise(name, data); 2024 this.#methodPromises.set(name, promise); 2025 return promise; 2026 } 2027 get annotationStorage() { 2028 return (0, _util.shadow)(this, "annotationStorage", new _annotation_storage.AnnotationStorage()); 2029 }
2030 getRenderingIntent(intent, annotationMode = _util.AnnotationMode.ENABLE, printAnnotationStorage = null, isOpList = false) { 2031 let renderingIntent = _util.RenderingIntentFlag.DISPLAY; 2032 let annotationStorageSerializable = _annotation_storage.SerializableEmpty; 2033 switch (intent) { 2034 case "any": 2035 renderingIntent = _util.RenderingIntentFlag.ANY; 2036 break; 2037 case "display": 2038 break; 2039 case "print": 2040 renderingIntent = _util.RenderingIntentFlag.PRINT; 2041 break; 2042 default: 2043 (0, _util.warn)(`getRenderingIntent - invalid intent: ${intent}`); 2044 } 2045 switch (annotationMode) { 2046 case _util.AnnotationMode.DISABLE: 2047 renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_DISABLE; 2048 break; 2049 case _util.AnnotationMode.ENABLE: 2050 break; 2051 case _util.AnnotationMode.ENABLE_FORMS: 2052 renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_FORMS; 2053 break; 2054 case _util.AnnotationMode.ENABLE_STORAGE: 2055 renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_STORAGE; 2056 const annotationStorage = renderingIntent & _util.RenderingIntentFlag.PRINT && printAnnotationStorage instanceof _annotation_storage.PrintAnnotationStorage ? printAnnotationStorage : this.annotationStorage; 2057 annotationStorageSerializable = annotationStorage.serializable; 2058 break; 2059 default: 2060 (0, _util.warn)(`getRenderingIntent - invalid annotationMode: ${annotationMode}`); 2061 } 2062 if (isOpList) { 2063 renderingIntent += _util.RenderingIntentFlag.OPLIST; 2064 } 2065 return { 2066 renderingIntent, 2067 cacheKey: `${renderingIntent}_${annotationStorageSerializable.hash}`, 2068 annotationStorageSerializable 2069 }; 2070 } 2071 destroy() { 2072 if (this.destroyCapability) { 2073 return this.destroyCapability.promise; 2074 } 2075 this.destroyed = true; 2076 this.destroyCapability = new _util.PromiseCapability(); 2077 this.#passwordCapability?.reject(new Error("Worker was destroyed during onPassword callback")); 2078 const waitOn = []; 2079 for (const page of this.#pageCache.values()) { 2080 waitOn.push(page._destroy()); 2081 } 2082 this.#pageCache.clear(); 2083 this.#pagePromises.clear(); 2084 if (this.hasOwnProperty("annotationStorage")) { 2085 this.annotationStorage.resetModified(); 2086 } 2087 const terminated = this.messageHandler.sendWithPromise("Terminate", null); 2088 waitOn.push(terminated); 2089 Promise.all(waitOn).then(() => { 2090 this.commonObjs.clear(); 2091 this.fontLoader.clear(); 2092 this.#methodPromises.clear(); 2093 this.filterFactory.destroy(); 2094 this._networkStream?.cancelAllRequests(new _util.AbortException("Worker was terminated.")); 2095 if (this.messageHandler) { 2096 this.messageHandler.destroy(); 2097 this.messageHandler = null; 2098 } 2099 this.destroyCapability.resolve(); 2100 }, this.destroyCapability.reject); 2101 return this.destroyCapability.promise; 2102 } 2103 setupMessageHandler() { 2104 const { 2105 messageHandler, 2106 loadingTask 2107 } = this; 2108 messageHandler.on("GetReader", (data, sink) => { 2109 (0, _util.assert)(this._networkStream, "GetReader - no `IPDFStream` instance available."); 2110 this._fullReader = this._networkStream.getFullReader(); 2111 this._fullReader.onProgress = evt => { 2112 this._lastProgress = { 2113 loaded: evt.loaded, 2114 total: evt.total 2115 }; 2116 }; 2117 sink.onPull = () => { 2118 this._fullReader.read().then(function ({ 2119 value, 2120 done 2121 }) { 2122 if (done) { 2123 sink.close(); 2124 return; 2125 } 2126 (0, _util.assert)(value instanceof ArrayBuffer, "GetReader - expected an ArrayBuffer."); 2127 sink.enqueue(new Uint8Array(value), 1, [value]); 2128 }).catch(reason => { 2129 sink.error(reason); 2130 }); 2131 }; 2132 sink.onCancel = reason => { 2133 this._fullReader.cancel(reason); 2134 sink.ready.catch(readyReason => { 2135 if (this.destroyed) { 2136 return; 2137 } 2138 throw readyReason; 2139 }); 2140 }; 2141 }); 2142 messageHandler.on("ReaderHeadersReady", data => { 2143 const headersCapability = new _util.PromiseCapability(); 2144 const fullReader = this._fullReader; 2145 fullReader.headersReady.then(() => { 2146 if (!fullReader.isStreamingSupported || !fullReader.isRangeSupported) { 2147 if (this._lastProgress) { 2148 loadingTask.onProgress?.(this._lastProgress); 2149 } 2150 fullReader.onProgress = evt => { 2151 loadingTask.onProgress?.({ 2152 loaded: evt.loaded, 2153 total: evt.total 2154 }); 2155 }; 2156 } 2157 headersCapability.resolve({ 2158 isStreamingSupported: fullReader.isStreamingSupported, 2159 isRangeSupported: fullReader.isRangeSupported, 2160 contentLength: fullReader.contentLength 2161 }); 2162 }, headersCapability.reject); 2163 return headersCapability.promise; 2164 }); 2165 messageHandler.on("GetRangeReader", (data, sink) => { 2166 (0, _util.assert)(this._networkStream, "GetRangeReader - no `IPDFStream` instance available."); 2167 const rangeReader = this._networkStream.getRangeReader(data.begin, data.end); 2168 if (!rangeReader) { 2169 sink.close(); 2170 return; 2171 } 2172 sink.onPull = () => { 2173 rangeReader.read().then(function ({ 2174 value, 2175 done 2176 }) { 2177 if (done) { 2178 sink.close(); 2179 return; 2180 } 2181 (0, _util.assert)(value instanceof ArrayBuffer, "GetRangeReader - expected an ArrayBuffer."); 2182 sink.enqueue(new Uint8Array(value), 1, [value]); 2183 }).catch(reason => { 2184 sink.error(reason); 2185 }); 2186 }; 2187 sink.onCancel = reason => { 2188 rangeReader.cancel(reason); 2189 sink.ready.catch(readyReason => { 2190 if (this.destroyed) { 2191 return; 2192 } 2193 throw readyReason; 2194 }); 2195 }; 2196 }); 2197 messageHandler.on("GetDoc", ({ 2198 pdfInfo 2199 }) => { 2200 this._numPages = pdfInfo.numPages; 2201 this._htmlForXfa = pdfInfo.htmlForXfa; 2202 delete pdfInfo.htmlForXfa; 2203 loadingTask._capability.resolve(new PDFDocumentProxy(pdfInfo, this)); 2204 }); 2205 messageHandler.on("DocException", function (ex) { 2206 let reason; 2207 switch (ex.name) { 2208 case "PasswordException": 2209 reason = new _util.PasswordException(ex.message, ex.code); 2210 break; 2211 case "InvalidPDFException": 2212 reason = new _util.InvalidPDFException(ex.message); 2213 break; 2214 case "MissingPDFException": 2215 reason = new _util.MissingPDFException(ex.message); 2216 break; 2217 case "UnexpectedResponseException": 2218 reason = new _util.UnexpectedResponseException(ex.message, ex.status); 2219 break; 2220 case "UnknownErrorException": 2221 reason = new _util.UnknownErrorException(ex.message, ex.details); 2222 break; 2223 default: 2224 (0, _util.unreachable)("DocException - expected a valid Error."); 2225 } 2226 loadingTask._capability.reject(reason); 2227 }); 2228 messageHandler.on("PasswordRequest", exception => { 2229 this.#passwordCapability = new _util.PromiseCapability(); 2230 if (loadingTask.onPassword) { 2231 const updatePassword = password => { 2232 if (password instanceof Error) { 2233 this.#passwordCapability.reject(password); 2234 } else { 2235 this.#passwordCapability.resolve({ 2236 password 2237 }); 2238 } 2239 }; 2240 try { 2241 loadingTask.onPassword(updatePassword, exception.code); 2242 } catch (ex) { 2243 this.#passwordCapability.reject(ex); 2244 } 2245 } else { 2246 this.#passwordCapability.reject(new _util.PasswordException(exception.message, exception.code)); 2247 } 2248 return this.#passwordCapability.promise; 2249 }); 2250 messageHandler.on("DataLoaded", data => { 2251 loadingTask.onProgress?.({ 2252 loaded: data.length, 2253 total: data.length 2254 }); 2255 this.downloadInfoCapability.resolve(data); 2256 }); 2257 messageHandler.on("StartRenderPage", data => { 2258 if (this.destroyed) { 2259 return; 2260 } 2261 const page = this.#pageCache.get(data.pageIndex); 2262 page._startRenderPage(data.transparency, data.cacheKey); 2263 }); 2264 messageHandler.on("commonobj", ([id, type, exportedData]) => { 2265 if (this.destroyed) { 2266 return; 2267 } 2268 if (this.commonObjs.has(id)) { 2269 return; 2270 } 2271 switch (type) { 2272 case "Font": 2273 const params = this._params; 2274 if ("error" in exportedData) { 2275 const exportedError = exportedData.error; 2276 (0, _util.warn)(`Error during font loading: ${exportedError}`); 2277 this.commonObjs.resolve(id, exportedError); 2278 break; 2279 } 2280 const inspectFont = params.pdfBug && globalThis.FontInspector?.enabled ? (font, url) => globalThis.FontInspector.fontAdded(font, url) : null; 2281 const font = new _font_loader.FontFaceObject(exportedData, { 2282 isEvalSupported: params.isEvalSupported, 2283 disableFontFace: params.disableFontFace, 2284 ignoreErrors: params.ignoreErrors, 2285 inspectFont 2286 });
2287 this.fontLoader.bind(font).catch(reason => { 2288 return messageHandler.sendWithPromise("FontFallback", { 2289 id 2290 }); 2291 }).finally(() => { 2292 if (!params.fontExtraProperties && font.data) { 2293 font.data = null; 2294 } 2295 this.commonObjs.resolve(id, font); 2296 }); 2297 break; 2298 case "FontPath": 2299 case "Image": 2300 case "Pattern": 2301 this.commonObjs.resolve(id, exportedData); 2302 break; 2303 default: 2304 throw new Error(`Got unknown common object type ${type}`); 2305 } 2306 }); 2307 messageHandler.on("obj", ([id, pageIndex, type, imageData]) => { 2308 if (this.destroyed) { 2309 return; 2310 } 2311 const pageProxy = this.#pageCache.get(pageIndex); 2312 if (pageProxy.objs.has(id)) { 2313 return; 2314 } 2315 switch (type) { 2316 case "Image": 2317 pageProxy.objs.resolve(id, imageData); 2318 if (imageData) { 2319 let length; 2320 if (imageData.bitmap) { 2321 const { 2322 width, 2323 height 2324 } = imageData; 2325 length = width * height * 4; 2326 } else { 2327 length = imageData.data?.length || 0; 2328 } 2329 if (length > _util.MAX_IMAGE_SIZE_TO_CACHE) { 2330 pageProxy._maybeCleanupAfterRender = true; 2331 } 2332 } 2333 break; 2334 case "Pattern": 2335 pageProxy.objs.resolve(id, imageData); 2336 break; 2337 default: 2338 throw new Error(`Got unknown object type ${type}`); 2339 } 2340 }); 2341 messageHandler.on("DocProgress", data => { 2342 if (this.destroyed) { 2343 return; 2344 } 2345 loadingTask.onProgress?.({ 2346 loaded: data.loaded, 2347 total: data.total 2348 }); 2349 }); 2350 messageHandler.on("FetchBuiltInCMap", data => { 2351 if (this.destroyed) { 2352 return Promise.reject(new Error("Worker was destroyed.")); 2353 } 2354 if (!this.cMapReaderFactory) { 2355 return Promise.reject(new Error("CMapReaderFactory not initialized, see the `useWorkerFetch` parameter.")); 2356 } 2357 return this.cMapReaderFactory.fetch(data); 2358 }); 2359 messageHandler.on("FetchStandardFontData", data => { 2360 if (this.destroyed) { 2361 return Promise.reject(new Error("Worker was destroyed.")); 2362 } 2363 if (!this.standardFontDataFactory) { 2364 return Promise.reject(new Error("StandardFontDataFactory not initialized, see the `useWorkerFetch` parameter.")); 2365 } 2366 return this.standardFontDataFactory.fetch(data); 2367 }); 2368 } 2369 getData() { 2370 return this.messageHandler.sendWithPromise("GetData", null); 2371 } 2372 saveDocument() { 2373 if (this.annotationStorage.size <= 0) { 2374 (0, _util.warn)("saveDocument called while `annotationStorage` is empty, " + "please use the getData-method instead."); 2375 } 2376 const { 2377 map, 2378 transfers 2379 } = this.annotationStorage.serializable; 2380 return this.messageHandler.sendWithPromise("SaveDocument", { 2381 isPureXfa: !!this._htmlForXfa, 2382 numPages: this._numPages, 2383 annotationStorage: map, 2384 filename: this._fullReader?.filename ?? null 2385 }, transfers).finally(() => { 2386 this.annotationStorage.resetModified(); 2387 }); 2388 } 2389 getPage(pageNumber) { 2390 if (!Number.isInteger(pageNumber) || pageNumber <= 0 || pageNumber > this._numPages) { 2391 return Promise.reject(new Error("Invalid page request.")); 2392 } 2393 const pageIndex = pageNumber - 1, 2394 cachedPromise = this.#pagePromises.get(pageIndex); 2395 if (cachedPromise) { 2396 return cachedPromise; 2397 } 2398 const promise = this.messageHandler.sendWithPromise("GetPage", { 2399 pageIndex 2400 }).then(pageInfo => { 2401 if (this.destroyed) { 2402 throw new Error("Transport destroyed"); 2403 } 2404 const page = new PDFPageProxy(pageIndex, pageInfo, this, this._params.pdfBug); 2405 this.#pageCache.set(pageIndex, page); 2406 return page; 2407 }); 2408 this.#pagePromises.set(pageIndex, promise); 2409 return promise; 2410 } 2411 getPageIndex(ref) { 2412 if (typeof ref !== "object" || ref === null || !Number.isInteger(ref.num) || ref.num < 0 || !Number.isInteger(ref.gen) || ref.gen < 0) { 2413 return Promise.reject(new Error("Invalid pageIndex request.")); 2414 }
2415 return this.messageHandler.sendWithPromise("GetPageIndex", { 2416 num: ref.num, 2417 gen: ref.gen 2418 }); 2419 } 2420 getAnnotations(pageIndex, intent) { 2421 return this.messageHandler.sendWithPromise("GetAnnotations", { 2422 pageIndex, 2423 intent 2424 }); 2425 } 2426 getFieldObjects() { 2427 return this.#cacheSimpleMethod("GetFieldObjects"); 2428 } 2429 hasJSActions() { 2430 return this.#cacheSimpleMethod("HasJSActions"); 2431 } 2432 getCalculationOrderIds() { 2433 return this.messageHandler.sendWithPromise("GetCalculationOrderIds", null); 2434 } 2435 getDestinations() { 2436 return this.messageHandler.sendWithPromise("GetDestinations", null); 2437 } 2438 getDestination(id) { 2439 if (typeof id !== "string") { 2440 return Promise.reject(new Error("Invalid destination request.")); 2441 } 2442 return this.messageHandler.sendWithPromise("GetDestination", { 2443 id 2444 }); 2445 } 2446 getPageLabels() { 2447 return this.messageHandler.sendWithPromise("GetPageLabels", null); 2448 } 2449 getPageLayout() { 2450 return this.messageHandler.sendWithPromise("GetPageLayout", null); 2451 } 2452 getPageMode() { 2453 return this.messageHandler.sendWithPromise("GetPageMode", null); 2454 } 2455 getViewerPreferences() { 2456 return this.messageHandler.sendWithPromise("GetViewerPreferences", null); 2457 } 2458 getOpenAction() { 2459 return this.messageHandler.sendWithPromise("GetOpenAction", null); 2460 } 2461 getAttachments() { 2462 return this.messageHandler.sendWithPromise("GetAttachments", null); 2463 } 2464 getDocJSActions() { 2465 return this.#cacheSimpleMethod("GetDocJSActions"); 2466 } 2467 getPageJSActions(pageIndex) { 2468 return this.messageHandler.sendWithPromise("GetPageJSActions", { 2469 pageIndex 2470 }); 2471 } 2472 getStructTree(pageIndex) { 2473 return this.messageHandler.sendWithPromise("GetStructTree", { 2474 pageIndex 2475 }); 2476 } 2477 getOutline() { 2478 return this.messageHandler.sendWithPromise("GetOutline", null); 2479 } 2480 getOptionalContentConfig() { 2481 return this.messageHandler.sendWithPromise("GetOptionalContentConfig", null).then(results => { 2482 return new _optional_content_config.OptionalContentConfig(results); 2483 }); 2484 } 2485 getPermissions() { 2486 return this.messageHandler.sendWithPromise("GetPermissions", null); 2487 } 2488 getMetadata() { 2489 const name = "GetMetadata", 2490 cachedPromise = this.#methodPromises.get(name); 2491 if (cachedPromise) { 2492 return cachedPromise; 2493 } 2494 const promise = this.messageHandler.sendWithPromise(name, null).then(results => { 2495 return { 2496 info: results[0], 2497 metadata: results[1] ? new _metadata.Metadata(results[1]) : null, 2498 contentDispositionFilename: this._fullReader?.filename ?? null, 2499 contentLength: this._fullReader?.contentLength ?? null 2500 }; 2501 }); 2502 this.#methodPromises.set(name, promise); 2503 return promise; 2504 } 2505 getMarkInfo() { 2506 return this.messageHandler.sendWithPromise("GetMarkInfo", null); 2507 } 2508 async startCleanup(keepLoadedFonts = false) { 2509 if (this.destroyed) { 2510 return; 2511 } 2512 await this.messageHandler.sendWithPromise("Cleanup", null); 2513 for (const page of this.#pageCache.values()) { 2514 const cleanupSuccessful = page.cleanup(); 2515 if (!cleanupSuccessful) { 2516 throw new Error(`startCleanup: Page ${page.pageNumber} is currently rendering.`); 2517 } 2518 } 2519 this.commonObjs.clear(); 2520 if (!keepLoadedFonts) { 2521 this.fontLoader.clear(); 2522 } 2523 this.#methodPromises.clear(); 2524 this.filterFactory.destroy(true); 2525 } 2526 get loadingParams() { 2527 const { 2528 disableAutoFetch, 2529 enableXfa 2530 } = this._params; 2531 return (0, _util.shadow)(this, "loadingParams", { 2532 disableAutoFetch, 2533 enableXfa 2534 }); 2535 } 2536} 2537class PDFObjects { 2538 #objs = Object.create(null); 2539 #ensureObj(objId) { 2540 return this.#objs[objId] ||= { 2541 capability: new _util.PromiseCapability(), 2542 data: null 2543 }; 2544 } 2545 get(objId, callback = null) { 2546 if (callback) { 2547 const obj = this.#ensureObj(objId); 2548 obj.capability.promise.then(() => callback(obj.data)); 2549 return null; 2550 } 2551 const obj = this.#objs[objId]; 2552 if (!obj?.capability.settled) { 2553 throw new Error(`Requesting object that isn't resolved yet ${objId}.`); 2554 } 2555 return obj.data; 2556 }
2557 has(objId) { 2558 const obj = this.#objs[objId]; 2559 return obj?.capability.settled || false; 2560 } 2561 resolve(objId, data = null) { 2562 const obj = this.#ensureObj(objId); 2563 obj.data = data; 2564 obj.capability.resolve(); 2565 } 2566 clear() { 2567 for (const objId in this.#objs) { 2568 const { 2569 data 2570 } = this.#objs[objId]; 2571 data?.bitmap?.close(); 2572 } 2573 this.#objs = Object.create(null); 2574 } 2575} 2576class RenderTask { 2577 #internalRenderTask = null; 2578 constructor(internalRenderTask) { 2579 this.#internalRenderTask = internalRenderTask; 2580 this.onContinue = null; 2581 } 2582 get promise() { 2583 return this.#internalRenderTask.capability.promise; 2584 } 2585 cancel(extraDelay = 0) { 2586 this.#internalRenderTask.cancel(null, extraDelay); 2587 } 2588 get separateAnnots() { 2589 const { 2590 separateAnnots 2591 } = this.#internalRenderTask.operatorList; 2592 if (!separateAnnots) { 2593 return false; 2594 } 2595 const { 2596 annotationCanvasMap 2597 } = this.#internalRenderTask; 2598 return separateAnnots.form || separateAnnots.canvas && annotationCanvasMap?.size > 0; 2599 } 2600} 2601exports.RenderTask = RenderTask; 2602class InternalRenderTask { 2603 static #canvasInUse = new WeakSet(); 2604 constructor({ 2605 callback, 2606 params, 2607 objs, 2608 commonObjs, 2609 annotationCanvasMap, 2610 operatorList, 2611 pageIndex, 2612 canvasFactory, 2613 filterFactory, 2614 useRequestAnimationFrame = false, 2615 pdfBug = false, 2616 pageColors = null 2617 }) { 2618 this.callback = callback; 2619 this.params = params; 2620 this.objs = objs; 2621 this.commonObjs = commonObjs; 2622 this.annotationCanvasMap = annotationCanvasMap; 2623 this.operatorListIdx = null; 2624 this.operatorList = operatorList; 2625 this._pageIndex = pageIndex; 2626 this.canvasFactory = canvasFactory; 2627 this.filterFactory = filterFactory; 2628 this._pdfBug = pdfBug; 2629 this.pageColors = pageColors; 2630 this.running = false; 2631 this.graphicsReadyCallback = null; 2632 this.graphicsReady = false; 2633 this._useRequestAnimationFrame = useRequestAnimationFrame === true && typeof window !== "undefined"; 2634 this.cancelled = false; 2635 this.capability = new _util.PromiseCapability(); 2636 this.task = new RenderTask(this); 2637 this._cancelBound = this.cancel.bind(this); 2638 this._continueBound = this._continue.bind(this); 2639 this._scheduleNextBound = this._scheduleNext.bind(this); 2640 this._nextBound = this._next.bind(this); 2641 this._canvas = params.canvasContext.canvas; 2642 } 2643 get completed() { 2644 return this.capability.promise.catch(function () {}); 2645 } 2646 initializeGraphics({ 2647 transparency = false, 2648 optionalContentConfig 2649 }) { 2650 if (this.cancelled) { 2651 return; 2652 } 2653 if (this._canvas) { 2654 if (InternalRenderTask.#canvasInUse.has(this._canvas)) { 2655 throw new Error("Cannot use the same canvas during multiple render() operations. " + "Use different canvas or ensure previous operations were " + "cancelled or completed."); 2656 } 2657 InternalRenderTask.#canvasInUse.add(this._canvas); 2658 } 2659 if (this._pdfBug && globalThis.StepperManager?.enabled) { 2660 this.stepper = globalThis.StepperManager.create(this._pageIndex); 2661 this.stepper.init(this.operatorList); 2662 this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint(); 2663 } 2664 const { 2665 canvasContext, 2666 viewport, 2667 transform, 2668 background 2669 } = this.params; 2670 this.gfx = new _canvas.CanvasGraphics(canvasContext, this.commonObjs, this.objs, this.canvasFactory, this.filterFactory, { 2671 optionalContentConfig 2672 }, this.annotationCanvasMap, this.pageColors); 2673 this.gfx.beginDrawing({ 2674 transform, 2675 viewport, 2676 transparency, 2677 background 2678 }); 2679 this.operatorListIdx = 0; 2680 this.graphicsReady = true; 2681 this.graphicsReadyCallback?.(); 2682 } 2683 cancel(error = null, extraDelay = 0) { 2684 this.running = false; 2685 this.cancelled = true; 2686 this.gfx?.endDrawing(); 2687 InternalRenderTask.#canvasInUse.delete(this._canvas); 2688 this.callback(error || new _display_utils.RenderingCancelledException(`Rendering cancelled, page ${this._pageIndex + 1}`, extraDelay)); 2689 } 2690 operatorListChanged() { 2691 if (!this.graphicsReady) { 2692 this.graphicsReadyCallback ||= this._continueBound; 2693 return; 2694 } 2695 this.stepper?.updateOperatorList(this.operatorList); 2696 if (this.running) { 2697 return; 2698 } 2699 this._continue(); 2700 } 2701 _continue() { 2702 this.running = true; 2703 if (this.cancelled) { 2704 return; 2705 } 2706 if (this.task.onContinue) { 2707 this.task.onContinue(this._scheduleNextBound); 2708 } else { 2709 this._scheduleNext(); 2710 } 2711 } 2712 _scheduleNext() { 2713 if (this._useRequestAnimationFrame) { 2714 window.requestAnimationFrame(() => { 2715 this._nextBound().catch(this._cancelBound); 2716 }); 2717 } else {
2718 Promise.resolve().then(this._nextBound).catch(this._cancelBound); 2719 } 2720 } 2721 async _next() { 2722 if (this.cancelled) { 2723 return; 2724 } 2725 this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList, this.operatorListIdx, this._continueBound, this.stepper); 2726 if (this.operatorListIdx === this.operatorList.argsArray.length) { 2727 this.running = false; 2728 if (this.operatorList.lastChunk) { 2729 this.gfx.endDrawing(); 2730 InternalRenderTask.#canvasInUse.delete(this._canvas); 2731 this.callback(); 2732 } 2733 } 2734 } 2735} 2736const version = '3.11.174'; 2737exports.version = version; 2738const build = 'ce8716743'; 2739exports.build = build; 2740 2741/***/ }), 2742/* 3 */ 2743/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 2744 2745 2746 2747Object.defineProperty(exports, "__esModule", ({ 2748 value: true 2749})); 2750exports.SerializableEmpty = exports.PrintAnnotationStorage = exports.AnnotationStorage = void 0; 2751var _util = __w_pdfjs_require__(1); 2752var _editor = __w_pdfjs_require__(4); 2753var _murmurhash = __w_pdfjs_require__(8); 2754const SerializableEmpty = Object.freeze({ 2755 map: null, 2756 hash: "", 2757 transfers: undefined 2758}); 2759exports.SerializableEmpty = SerializableEmpty; 2760class AnnotationStorage { 2761 #modified = false; 2762 #storage = new Map(); 2763 constructor() { 2764 this.onSetModified = null; 2765 this.onResetModified = null; 2766 this.onAnnotationEditor = null; 2767 } 2768 getValue(key, defaultValue) { 2769 const value = this.#storage.get(key); 2770 if (value === undefined) { 2771 return defaultValue; 2772 } 2773 return Object.assign(defaultValue, value); 2774 } 2775 getRawValue(key) { 2776 return this.#storage.get(key); 2777 } 2778 remove(key) { 2779 this.#storage.delete(key); 2780 if (this.#storage.size === 0) { 2781 this.resetModified(); 2782 } 2783 if (typeof this.onAnnotationEditor === "function") { 2784 for (const value of this.#storage.values()) { 2785 if (value instanceof _editor.AnnotationEditor) { 2786 return; 2787 } 2788 } 2789 this.onAnnotationEditor(null); 2790 } 2791 } 2792 setValue(key, value) { 2793 const obj = this.#storage.get(key); 2794 let modified = false; 2795 if (obj !== undefined) { 2796 for (const [entry, val] of Object.entries(value)) { 2797 if (obj[entry] !== val) { 2798 modified = true; 2799 obj[entry] = val; 2800 } 2801 } 2802 } else { 2803 modified = true; 2804 this.#storage.set(key, value); 2805 } 2806 if (modified) { 2807 this.#setModified(); 2808 } 2809 if (value instanceof _editor.AnnotationEditor && typeof this.onAnnotationEditor === "function") { 2810 this.onAnnotationEditor(value.constructor._type); 2811 } 2812 } 2813 has(key) { 2814 return this.#storage.has(key); 2815 } 2816 getAll() { 2817 return this.#storage.size > 0 ? (0, _util.objectFromMap)(this.#storage) : null; 2818 } 2819 setAll(obj) { 2820 for (const [key, val] of Object.entries(obj)) { 2821 this.setValue(key, val); 2822 } 2823 } 2824 get size() { 2825 return this.#storage.size; 2826 } 2827 #setModified() { 2828 if (!this.#modified) { 2829 this.#modified = true; 2830 if (typeof this.onSetModified === "function") { 2831 this.onSetModified(); 2832 } 2833 } 2834 } 2835 resetModified() { 2836 if (this.#modified) { 2837 this.#modified = false; 2838 if (typeof this.onResetModified === "function") { 2839 this.onResetModified(); 2840 } 2841 } 2842 } 2843 get print() { 2844 return new PrintAnnotationStorage(this); 2845 } 2846 get serializable() { 2847 if (this.#storage.size === 0) { 2848 return SerializableEmpty; 2849 } 2850 const map = new Map(), 2851 hash = new _murmurhash.MurmurHash3_64(), 2852 transfers = []; 2853 const context = Object.create(null); 2854 let hasBitmap = false; 2855 for (const [key, val] of this.#storage) { 2856 const serialized = val instanceof _editor.AnnotationEditor ? val.serialize(false, context) : val; 2857 if (serialized) { 2858 map.set(key, serialized); 2859 hash.update(`${key}:${JSON.stringify(serialized)}`); 2860 hasBitmap ||= !!serialized.bitmap; 2861 } 2862 } 2863 if (hasBitmap) { 2864 for (const value of map.values()) { 2865 if (value.bitmap) { 2866 transfers.push(value.bitmap); 2867 } 2868 } 2869 } 2870 return map.size > 0 ? { 2871 map, 2872 hash: hash.hexdigest(), 2873 transfers 2874 } : SerializableEmpty; 2875 } 2876} 2877exports.AnnotationStorage = AnnotationStorage; 2878class PrintAnnotationStorage extends AnnotationStorage { 2879 #serializable; 2880 constructor(parent) { 2881 super(); 2882 const { 2883 map, 2884 hash, 2885 transfers 2886 } = parent.serializable; 2887 const clone = structuredClone(map, transfers ? { 2888 transfer: transfers 2889 } : null); 2890 this.#serializable = { 2891 map: clone, 2892 hash, 2893 transfers 2894 }; 2895 } 2896 get print() { 2897 (0, _util.unreachable)("Should not call PrintAnnotationStorage.print"); 2898 } 2899 get serializable() { 2900 return this.#serializable; 2901 } 2902} 2903exports.PrintAnnotationStorage = PrintAnnotationStorage; 2904 2905/***/ }), 2906/* 4 */ 2907/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 2908 2909 2910 2911Object.defineProperty(exports, "__esModule", ({ 2912 value: true 2913})); 2914exports.AnnotationEditor = void 0; 2915var _tools = __w_pdfjs_require__(5); 2916var _util = __w_pdfjs_require__(1); 2917var _display_utils = __w_pdfjs_require__(6); 2918class AnnotationEditor { 2919 #altText = ""; 2920 #altTextDecorative = false;
2921 #altTextButton = null; 2922 #altTextTooltip = null; 2923 #altTextTooltipTimeout = null; 2924 #keepAspectRatio = false; 2925 #resizersDiv = null; 2926 #boundFocusin = this.focusin.bind(this); 2927 #boundFocusout = this.focusout.bind(this); 2928 #hasBeenClicked = false; 2929 #isEditing = false; 2930 #isInEditMode = false; 2931 _initialOptions = Object.create(null); 2932 _uiManager = null; 2933 _focusEventsAllowed = true; 2934 _l10nPromise = null; 2935 #isDraggable = false; 2936 #zIndex = AnnotationEditor._zIndex++; 2937 static _borderLineWidth = -1; 2938 static _colorManager = new _tools.ColorManager(); 2939 static _zIndex = 1; 2940 static SMALL_EDITOR_SIZE = 0; 2941 constructor(parameters) { 2942 if (this.constructor === AnnotationEditor) { 2943 (0, _util.unreachable)("Cannot initialize AnnotationEditor."); 2944 } 2945 this.parent = parameters.parent; 2946 this.id = parameters.id; 2947 this.width = this.height = null; 2948 this.pageIndex = parameters.parent.pageIndex; 2949 this.name = parameters.name; 2950 this.div = null; 2951 this._uiManager = parameters.uiManager; 2952 this.annotationElementId = null; 2953 this._willKeepAspectRatio = false; 2954 this._initialOptions.isCentered = parameters.isCentered; 2955 this._structTreeParentId = null; 2956 const { 2957 rotation, 2958 rawDims: { 2959 pageWidth, 2960 pageHeight, 2961 pageX, 2962 pageY 2963 } 2964 } = this.parent.viewport; 2965 this.rotation = rotation; 2966 this.pageRotation = (360 + rotation - this._uiManager.viewParameters.rotation) % 360; 2967 this.pageDimensions = [pageWidth, pageHeight]; 2968 this.pageTranslation = [pageX, pageY]; 2969 const [width, height] = this.parentDimensions; 2970 this.x = parameters.x / width; 2971 this.y = parameters.y / height; 2972 this.isAttachedToDOM = false; 2973 this.deleted = false; 2974 } 2975 get editorType() { 2976 return Object.getPrototypeOf(this).constructor._type; 2977 } 2978 static get _defaultLineColor() { 2979 return (0, _util.shadow)(this, "_defaultLineColor", this._colorManager.getHexCode("CanvasText")); 2980 } 2981 static deleteAnnotationElement(editor) { 2982 const fakeEditor = new FakeEditor({ 2983 id: editor.parent.getNextId(), 2984 parent: editor.parent, 2985 uiManager: editor._uiManager 2986 }); 2987 fakeEditor.annotationElementId = editor.annotationElementId; 2988 fakeEditor.deleted = true; 2989 fakeEditor._uiManager.addToAnnotationStorage(fakeEditor); 2990 } 2991 static initialize(l10n, options = null) { 2992 AnnotationEditor._l10nPromise ||= new Map(["editor_alt_text_button_label", "editor_alt_text_edit_button_label", "editor_alt_text_decorative_tooltip"].map(str => [str, l10n.get(str)])); 2993 if (options?.strings) { 2994 for (const str of options.strings) { 2995 AnnotationEditor._l10nPromise.set(str, l10n.get(str)); 2996 } 2997 } 2998 if (AnnotationEditor._borderLineWidth !== -1) { 2999 return; 3000 } 3001 const style = getComputedStyle(document.documentElement); 3002 AnnotationEditor._borderLineWidth = parseFloat(style.getPropertyValue("--outline-width")) || 0; 3003 } 3004 static updateDefaultParams(_type, _value) {} 3005 static get defaultPropertiesToUpdate() { 3006 return []; 3007 } 3008 static isHandlingMimeForPasting(mime) { 3009 return false; 3010 } 3011 static paste(item, parent) { 3012 (0, _util.unreachable)("Not implemented"); 3013 } 3014 get propertiesToUpdate() { 3015 return []; 3016 } 3017 get _isDraggable() { 3018 return this.#isDraggable; 3019 } 3020 set _isDraggable(value) { 3021 this.#isDraggable = value; 3022 this.div?.classList.toggle("draggable", value); 3023 } 3024 center() { 3025 const [pageWidth, pageHeight] = this.pageDimensions; 3026 switch (this.parentRotation) { 3027 case 90: 3028 this.x -= this.height * pageHeight / (pageWidth * 2); 3029 this.y += this.width * pageWidth / (pageHeight * 2); 3030 break; 3031 case 180: 3032 this.x += this.width / 2; 3033 this.y += this.height / 2; 3034 break; 3035 case 270: 3036 this.x += this.height * pageHeight / (pageWidth * 2); 3037 this.y -= this.width * pageWidth / (pageHeight * 2); 3038 break; 3039 default: 3040 this.x -= this.width / 2; 3041 this.y -= this.height / 2; 3042 break; 3043 } 3044 this.fixAndSetPosition(); 3045 } 3046 addCommands(params) { 3047 this._uiManager.addCommands(params); 3048 } 3049 get currentLayer() { 3050 return this._uiManager.currentLayer; 3051 }
3052 setInBackground() { 3053 this.div.style.zIndex = 0; 3054 } 3055 setInForeground() { 3056 this.div.style.zIndex = this.#zIndex; 3057 } 3058 setParent(parent) { 3059 if (parent !== null) { 3060 this.pageIndex = parent.pageIndex; 3061 this.pageDimensions = parent.pageDimensions; 3062 } 3063 this.parent = parent; 3064 } 3065 focusin(event) { 3066 if (!this._focusEventsAllowed) { 3067 return; 3068 } 3069 if (!this.#hasBeenClicked) { 3070 this.parent.setSelected(this); 3071 } else { 3072 this.#hasBeenClicked = false; 3073 } 3074 } 3075 focusout(event) { 3076 if (!this._focusEventsAllowed) { 3077 return; 3078 } 3079 if (!this.isAttachedToDOM) { 3080 return; 3081 } 3082 const target = event.relatedTarget; 3083 if (target?.closest(`#${this.id}`)) { 3084 return; 3085 } 3086 event.preventDefault(); 3087 if (!this.parent?.isMultipleSelection) { 3088 this.commitOrRemove(); 3089 } 3090 } 3091 commitOrRemove() { 3092 if (this.isEmpty()) { 3093 this.remove(); 3094 } else { 3095 this.commit(); 3096 } 3097 } 3098 commit() { 3099 this.addToAnnotationStorage(); 3100 } 3101 addToAnnotationStorage() { 3102 this._uiManager.addToAnnotationStorage(this); 3103 } 3104 setAt(x, y, tx, ty) { 3105 const [width, height] = this.parentDimensions; 3106 [tx, ty] = this.screenToPageTranslation(tx, ty); 3107 this.x = (x + tx) / width; 3108 this.y = (y + ty) / height; 3109 this.fixAndSetPosition(); 3110 } 3111 #translate([width, height], x, y) { 3112 [x, y] = this.screenToPageTranslation(x, y); 3113 this.x += x / width; 3114 this.y += y / height; 3115 this.fixAndSetPosition(); 3116 } 3117 translate(x, y) { 3118 this.#translate(this.parentDimensions, x, y); 3119 } 3120 translateInPage(x, y) { 3121 this.#translate(this.pageDimensions, x, y); 3122 this.div.scrollIntoView({ 3123 block: "nearest" 3124 }); 3125 } 3126 drag(tx, ty) { 3127 const [parentWidth, parentHeight] = this.parentDimensions; 3128 this.x += tx / parentWidth; 3129 this.y += ty / parentHeight; 3130 if (this.parent && (this.x < 0 || this.x > 1 || this.y < 0 || this.y > 1)) { 3131 const { 3132 x, 3133 y 3134 } = this.div.getBoundingClientRect(); 3135 if (this.parent.findNewParent(this, x, y)) { 3136 this.x -= Math.floor(this.x); 3137 this.y -= Math.floor(this.y); 3138 } 3139 } 3140 let { 3141 x, 3142 y 3143 } = this; 3144 const [bx, by] = this.#getBaseTranslation(); 3145 x += bx; 3146 y += by; 3147 this.div.style.left = `${(100 * x).toFixed(2)}%`; 3148 this.div.style.top = `${(100 * y).toFixed(2)}%`; 3149 this.div.scrollIntoView({ 3150 block: "nearest" 3151 }); 3152 } 3153 #getBaseTranslation() { 3154 const [parentWidth, parentHeight] = this.parentDimensions; 3155 const { 3156 _borderLineWidth 3157 } = AnnotationEditor; 3158 const x = _borderLineWidth / parentWidth; 3159 const y = _borderLineWidth / parentHeight; 3160 switch (this.rotation) { 3161 case 90: 3162 return [-x, y]; 3163 case 180: 3164 return [x, y]; 3165 case 270: 3166 return [x, -y]; 3167 default: 3168 return [-x, -y]; 3169 } 3170 } 3171 fixAndSetPosition() { 3172 const [pageWidth, pageHeight] = this.pageDimensions; 3173 let { 3174 x, 3175 y, 3176 width, 3177 height 3178 } = this; 3179 width *= pageWidth; 3180 height *= pageHeight; 3181 x *= pageWidth; 3182 y *= pageHeight; 3183 switch (this.rotation) { 3184 case 0: 3185 x = Math.max(0, Math.min(pageWidth - width, x)); 3186 y = Math.max(0, Math.min(pageHeight - height, y)); 3187 break; 3188 case 90: 3189 x = Math.max(0, Math.min(pageWidth - height, x)); 3190 y = Math.min(pageHeight, Math.max(width, y)); 3191 break; 3192 case 180: 3193 x = Math.min(pageWidth, Math.max(width, x)); 3194 y = Math.min(pageHeight, Math.max(height, y)); 3195 break; 3196 case 270: 3197 x = Math.min(pageWidth, Math.max(height, x)); 3198 y = Math.max(0, Math.min(pageHeight - width, y)); 3199 break; 3200 } 3201 this.x = x /= pageWidth; 3202 this.y = y /= pageHeight; 3203 const [bx, by] = this.#getBaseTranslation(); 3204 x += bx; 3205 y += by; 3206 const { 3207 style 3208 } = this.div; 3209 style.left = `${(100 * x).toFixed(2)}%`; 3210 style.top = `${(100 * y).toFixed(2)}%`; 3211 this.moveInDOM(); 3212 } 3213 static #rotatePoint(x, y, angle) { 3214 switch (angle) { 3215 case 90: 3216 return [y, -x]; 3217 case 180: 3218 return [-x, -y]; 3219 case 270: 3220 return [-y, x]; 3221 default: 3222 return [x, y]; 3223 } 3224 } 3225 screenToPageTranslation(x, y) { 3226 return AnnotationEditor.#rotatePoint(x, y, this.parentRotation); 3227 } 3228 pageTranslationToScreen(x, y) { 3229 return AnnotationEditor.#rotatePoint(x, y, 360 - this.parentRotation); 3230 } 3231 #getRotationMatrix(rotation) { 3232 switch (rotation) { 3233 case 90: 3234 { 3235 const [pageWidth, pageHeight] = this.pageDimensions; 3236 return [0, -pageWidth / pageHeight, pageHeight / pageWidth, 0]; 3237 } 3238 case 180: 3239 return [-1, 0, 0, -1]; 3240 case 270: 3241 { 3242 const [pageWidth, pageHeight] = this.pageDimensions; 3243 return [0, pageWidth / pageHeight, -pageHeight / pageWidth, 0]; 3244 } 3245 default: 3246 return [1, 0, 0, 1]; 3247 } 3248 } 3249 get parentScale() { 3250 return this._uiManager.viewParameters.realScale; 3251 } 3252 get parentRotation() { 3253 return (this._uiManager.viewParameters.rotation + this.pageRotation) % 360; 3254 } 3255 get parentDimensions() { 3256 const { 3257 parentScale, 3258 pageDimensions: [pageWidth, pageHeight] 3259 } = this; 3260 const scaledWidth = pageWidth * parentScale; 3261 const scaledHeight = pageHeight * parentScale; 3262 return _util.FeatureTest.isCSSRoundSupported ? [Math.round(scaledWidth), Math.round(scaledHeight)] : [scaledWidth, scaledHeight]; 3263 } 3264 setDims(width, height) { 3265 const [parentWidth, parentHeight] = this.parentDimensions; 3266 this.div.style.width = `${(100 * width / parentWidth).toFixed(2)}%`; 3267 if (!this.#keepAspectRatio) { 3268 this.div.style.height = `${(100 * height / parentHeight).toFixed(2)}%`; 3269 } 3270 this.#altTextButton?.classList.toggle("small", width < AnnotationEditor.SMALL_EDITOR_SIZE || height < AnnotationEditor.SMALL_EDITOR_SIZE); 3271 } 3272 fixDims() { 3273 const { 3274 style 3275 } = this.div; 3276 const { 3277 height, 3278 width 3279 } = style; 3280 const widthPercent = width.endsWith("%"); 3281 const heightPercent = !this.#keepAspectRatio && height.endsWith("%"); 3282 if (widthPercent && heightPercent) { 3283 return; 3284 } 3285 const [parentWidth, parentHeight] = this.parentDimensions; 3286 if (!widthPercent) { 3287 style.width = `${(100 * parseFloat(width) / parentWidth).toFixed(2)}%`; 3288 } 3289 if (!this.#keepAspectRatio && !heightPercent) { 3290 style.height = `${(100 * parseFloat(height) / parentHeight).toFixed(2)}%`; 3291 } 3292 } 3293 getInitialTranslation() { 3294 return [0, 0]; 3295 } 3296 #createResizers() { 3297 if (this.#resizersDiv) { 3298 return; 3299 } 3300 this.#resizersDiv = document.createElement("div"); 3301 this.#resizersDiv.classList.add("resizers"); 3302 const classes = ["topLeft", "topRight", "bottomRight", "bottomLeft"]; 3303 if (!this._willKeepAspectRatio) { 3304 classes.push("topMiddle", "middleRight", "bottomMiddle", "middleLeft"); 3305 } 3306 for (const name of classes) { 3307 const div = document.createElement("div"); 3308 this.#resizersDiv.append(div); 3309 div.classList.add("resizer", name); 3310 div.addEventListener("pointerdown", this.#resizerPointerdown.bind(this, name)); 3311 div.addEventListener("contextmenu", _display_utils.noContextMenu); 3312 } 3313 this.div.prepend(this.#resizersDiv); 3314 } 3315 #resizerPointerdown(name, event) { 3316 event.preventDefault(); 3317 const { 3318 isMac 3319 } = _util.FeatureTest.platform; 3320 if (event.button !== 0 || event.ctrlKey && isMac) { 3321 return; 3322 } 3323 const boundResizerPointermove = this.#resizerPointermove.bind(this, name); 3324 const savedDraggable = this._isDraggable; 3325 this._isDraggable = false;
3326 const pointerMoveOptions = { 3327 passive: true, 3328 capture: true 3329 }; 3330 window.addEventListener("pointermove", boundResizerPointermove, pointerMoveOptions); 3331 const savedX = this.x; 3332 const savedY = this.y; 3333 const savedWidth = this.width; 3334 const savedHeight = this.height; 3335 const savedParentCursor = this.parent.div.style.cursor; 3336 const savedCursor = this.div.style.cursor; 3337 this.div.style.cursor = this.parent.div.style.cursor = window.getComputedStyle(event.target).cursor; 3338 const pointerUpCallback = () => { 3339 this._isDraggable = savedDraggable; 3340 window.removeEventListener("pointerup", pointerUpCallback); 3341 window.removeEventListener("blur", pointerUpCallback); 3342 window.removeEventListener("pointermove", boundResizerPointermove, pointerMoveOptions); 3343 this.parent.div.style.cursor = savedParentCursor; 3344 this.div.style.cursor = savedCursor; 3345 const newX = this.x; 3346 const newY = this.y; 3347 const newWidth = this.width; 3348 const newHeight = this.height; 3349 if (newX === savedX && newY === savedY && newWidth === savedWidth && newHeight === savedHeight) { 3350 return; 3351 } 3352 this.addCommands({ 3353 cmd: () => { 3354 this.width = newWidth; 3355 this.height = newHeight; 3356 this.x = newX; 3357 this.y = newY; 3358 const [parentWidth, parentHeight] = this.parentDimensions; 3359 this.setDims(parentWidth * newWidth, parentHeight * newHeight); 3360 this.fixAndSetPosition(); 3361 }, 3362 undo: () => { 3363 this.width = savedWidth; 3364 this.height = savedHeight; 3365 this.x = savedX; 3366 this.y = savedY; 3367 const [parentWidth, parentHeight] = this.parentDimensions; 3368 this.setDims(parentWidth * savedWidth, parentHeight * savedHeight); 3369 this.fixAndSetPosition(); 3370 }, 3371 mustExec: true 3372 }); 3373 }; 3374 window.addEventListener("pointerup", pointerUpCallback); 3375 window.addEventListener("blur", pointerUpCallback); 3376 } 3377 #resizerPointermove(name, event) { 3378 const [parentWidth, parentHeight] = this.parentDimensions; 3379 const savedX = this.x; 3380 const savedY = this.y; 3381 const savedWidth = this.width; 3382 const savedHeight = this.height; 3383 const minWidth = AnnotationEditor.MIN_SIZE / parentWidth; 3384 const minHeight = AnnotationEditor.MIN_SIZE / parentHeight; 3385 const round = x => Math.round(x * 10000) / 10000; 3386 const rotationMatrix = this.#getRotationMatrix(this.rotation); 3387 const transf = (x, y) => [rotationMatrix[0] * x + rotationMatrix[2] * y, rotationMatrix[1] * x + rotationMatrix[3] * y]; 3388 const invRotationMatrix = this.#getRotationMatrix(360 - this.rotation); 3389 const invTransf = (x, y) => [invRotationMatrix[0] * x + invRotationMatrix[2] * y, invRotationMatrix[1] * x + invRotationMatrix[3] * y]; 3390 let getPoint; 3391 let getOpposite; 3392 let isDiagonal = false;
3393 let isHorizontal = false; 3394 switch (name) { 3395 case "topLeft": 3396 isDiagonal = true; 3397 getPoint = (w, h) => [0, 0]; 3398 getOpposite = (w, h) => [w, h]; 3399 break; 3400 case "topMiddle": 3401 getPoint = (w, h) => [w / 2, 0]; 3402 getOpposite = (w, h) => [w / 2, h]; 3403 break; 3404 case "topRight": 3405 isDiagonal = true; 3406 getPoint = (w, h) => [w, 0]; 3407 getOpposite = (w, h) => [0, h]; 3408 break; 3409 case "middleRight": 3410 isHorizontal = true; 3411 getPoint = (w, h) => [w, h / 2]; 3412 getOpposite = (w, h) => [0, h / 2]; 3413 break; 3414 case "bottomRight": 3415 isDiagonal = true; 3416 getPoint = (w, h) => [w, h]; 3417 getOpposite = (w, h) => [0, 0]; 3418 break; 3419 case "bottomMiddle": 3420 getPoint = (w, h) => [w / 2, h]; 3421 getOpposite = (w, h) => [w / 2, 0]; 3422 break; 3423 case "bottomLeft": 3424 isDiagonal = true; 3425 getPoint = (w, h) => [0, h]; 3426 getOpposite = (w, h) => [w, 0]; 3427 break; 3428 case "middleLeft": 3429 isHorizontal = true; 3430 getPoint = (w, h) => [0, h / 2]; 3431 getOpposite = (w, h) => [w, h / 2]; 3432 break; 3433 } 3434 const point = getPoint(savedWidth, savedHeight); 3435 const oppositePoint = getOpposite(savedWidth, savedHeight); 3436 let transfOppositePoint = transf(...oppositePoint); 3437 const oppositeX = round(savedX + transfOppositePoint[0]); 3438 const oppositeY = round(savedY + transfOppositePoint[1]); 3439 let ratioX = 1; 3440 let ratioY = 1; 3441 let [deltaX, deltaY] = this.screenToPageTranslation(event.movementX, event.movementY); 3442 [deltaX, deltaY] = invTransf(deltaX / parentWidth, deltaY / parentHeight); 3443 if (isDiagonal) { 3444 const oldDiag = Math.hypot(savedWidth, savedHeight); 3445 ratioX = ratioY = Math.max(Math.min(Math.hypot(oppositePoint[0] - point[0] - deltaX, oppositePoint[1] - point[1] - deltaY) / oldDiag, 1 / savedWidth, 1 / savedHeight), minWidth / savedWidth, minHeight / savedHeight); 3446 } else if (isHorizontal) { 3447 ratioX = Math.max(minWidth, Math.min(1, Math.abs(oppositePoint[0] - point[0] - deltaX))) / savedWidth; 3448 } else { 3449 ratioY = Math.max(minHeight, Math.min(1, Math.abs(oppositePoint[1] - point[1] - deltaY))) / savedHeight; 3450 } 3451 const newWidth = round(savedWidth * ratioX); 3452 const newHeight = round(savedHeight * ratioY); 3453 transfOppositePoint = transf(...getOpposite(newWidth, newHeight)); 3454 const newX = oppositeX - transfOppositePoint[0]; 3455 const newY = oppositeY - transfOppositePoint[1]; 3456 this.width = newWidth; 3457 this.height = newHeight; 3458 this.x = newX; 3459 this.y = newY; 3460 this.setDims(parentWidth * newWidth, parentHeight * newHeight); 3461 this.fixAndSetPosition(); 3462 } 3463 async addAltTextButton() { 3464 if (this.#altTextButton) { 3465 return; 3466 } 3467 const altText = this.#altTextButton = document.createElement("button"); 3468 altText.className = "altText"; 3469 const msg = await AnnotationEditor._l10nPromise.get("editor_alt_text_button_label"); 3470 altText.textContent = msg; 3471 altText.setAttribute("aria-label", msg); 3472 altText.tabIndex = "0"; 3473 altText.addEventListener("contextmenu", _display_utils.noContextMenu); 3474 altText.addEventListener("pointerdown", event => event.stopPropagation()); 3475 altText.addEventListener("click", event => { 3476 event.preventDefault(); 3477 this._uiManager.editAltText(this); 3478 }, { 3479 capture: true 3480 }); 3481 altText.addEventListener("keydown", event => { 3482 if (event.target === altText && event.key === "Enter") { 3483 event.preventDefault(); 3484 this._uiManager.editAltText(this); 3485 } 3486 }); 3487 this.#setAltTextButtonState(); 3488 this.div.append(altText); 3489 if (!AnnotationEditor.SMALL_EDITOR_SIZE) { 3490 const PERCENT = 40; 3491 AnnotationEditor.SMALL_EDITOR_SIZE = Math.min(128, Math.round(altText.getBoundingClientRect().width * (1 + PERCENT / 100))); 3492 } 3493 } 3494 async #setAltTextButtonState() { 3495 const button = this.#altTextButton; 3496 if (!button) { 3497 return; 3498 } 3499 if (!this.#altText && !this.#altTextDecorative) { 3500 button.classList.remove("done"); 3501 this.#altTextTooltip?.remove(); 3502 return; 3503 } 3504 AnnotationEditor._l10nPromise.get("editor_alt_text_edit_button_label").then(msg => { 3505 button.setAttribute("aria-label", msg); 3506 }); 3507 let tooltip = this.#altTextTooltip; 3508 if (!tooltip) { 3509 this.#altTextTooltip = tooltip = document.createElement("span"); 3510 tooltip.className = "tooltip"; 3511 tooltip.setAttribute("role", "tooltip"); 3512 const id = tooltip.id = `alt-text-tooltip-${this.id}`; 3513 button.setAttribute("aria-describedby", id); 3514 const DELAY_TO_SHOW_TOOLTIP = 100; 3515 button.addEventListener("mouseenter", () => { 3516 this.#altTextTooltipTimeout = setTimeout(() => { 3517 this.#altTextTooltipTimeout = null; 3518 this.#altTextTooltip.classList.add("show"); 3519 this._uiManager._eventBus.dispatch("reporttelemetry", { 3520 source: this, 3521 details: { 3522 type: "editing", 3523 subtype: this.editorType, 3524 data: { 3525 action: "alt_text_tooltip" 3526 } 3527 } 3528 }); 3529 }, DELAY_TO_SHOW_TOOLTIP); 3530 }); 3531 button.addEventListener("mouseleave", () => { 3532 clearTimeout(this.#altTextTooltipTimeout); 3533 this.#altTextTooltipTimeout = null; 3534 this.#altTextTooltip?.classList.remove("show"); 3535 }); 3536 } 3537 button.classList.add("done"); 3538 tooltip.innerText = this.#altTextDecorative ? await AnnotationEditor._l10nPromise.get("editor_alt_text_decorative_tooltip") : this.#altText; 3539 if (!tooltip.parentNode) { 3540 button.append(tooltip); 3541 } 3542 } 3543 getClientDimensions() { 3544 return this.div.getBoundingClientRect(); 3545 } 3546 get altTextData() { 3547 return { 3548 altText: this.#altText, 3549 decorative: this.#altTextDecorative 3550 }; 3551 } 3552 set altTextData({ 3553 altText, 3554 decorative 3555 }) { 3556 if (this.#altText === altText && this.#altTextDecorative === decorative) { 3557 return; 3558 } 3559 this.#altText = altText; 3560 this.#altTextDecorative = decorative; 3561 this.#setAltTextButtonState(); 3562 } 3563 render() { 3564 this.div = document.createElement("div"); 3565 this.div.setAttribute("data-editor-rotation", (360 - this.rotation) % 360); 3566 this.div.className = this.name; 3567 this.div.setAttribute("id", this.id); 3568 this.div.setAttribute("tabIndex", 0); 3569 this.setInForeground(); 3570 this.div.addEventListener("focusin", this.#boundFocusin); 3571 this.div.addEventListener("focusout", this.#boundFocusout); 3572 const [parentWidth, parentHeight] = this.parentDimensions; 3573 if (this.parentRotation % 180 !== 0) { 3574 this.div.style.maxWidth = `${(100 * parentHeight / parentWidth).toFixed(2)}%`; 3575 this.div.style.maxHeight = `${(100 * parentWidth / parentHeight).toFixed(2)}%`; 3576 } 3577 const [tx, ty] = this.getInitialTranslation(); 3578 this.translate(tx, ty); 3579 (0, _tools.bindEvents)(this, this.div, ["pointerdown"]); 3580 return this.div; 3581 } 3582 pointerdown(event) { 3583 const { 3584 isMac 3585 } = _util.FeatureTest.platform; 3586 if (event.button !== 0 || event.ctrlKey && isMac) { 3587 event.preventDefault(); 3588 return; 3589 } 3590 this.#hasBeenClicked = true; 3591 this.#setUpDragSession(event); 3592 } 3593 #setUpDragSession(event) { 3594 if (!this._isDraggable) { 3595 return; 3596 } 3597 const isSelected = this._uiManager.isSelected(this); 3598 this._uiManager.setUpDragSession(); 3599 let pointerMoveOptions, pointerMoveCallback; 3600 if (isSelected) { 3601 pointerMoveOptions = { 3602 passive: true, 3603 capture: true 3604 }; 3605 pointerMoveCallback = e => { 3606 const [tx, ty] = this.screenToPageTranslation(e.movementX, e.movementY); 3607 this._uiManager.dragSelectedEditors(tx, ty); 3608 }; 3609 window.addEventListener("pointermove", pointerMoveCallback, pointerMoveOptions); 3610 } 3611 const pointerUpCallback = () => { 3612 window.removeEventListener("pointerup", pointerUpCallback); 3613 window.removeEventListener("blur", pointerUpCallback); 3614 if (isSelected) { 3615 window.removeEventListener("pointermove", pointerMoveCallback, pointerMoveOptions); 3616 } 3617 this.#hasBeenClicked = false;
3618 if (!this._uiManager.endDragSession()) { 3619 const { 3620 isMac 3621 } = _util.FeatureTest.platform; 3622 if (event.ctrlKey && !isMac || event.shiftKey || event.metaKey && isMac) { 3623 this.parent.toggleSelected(this); 3624 } else { 3625 this.parent.setSelected(this); 3626 } 3627 } 3628 }; 3629 window.addEventListener("pointerup", pointerUpCallback); 3630 window.addEventListener("blur", pointerUpCallback); 3631 } 3632 moveInDOM() { 3633 this.parent?.moveEditorInDOM(this); 3634 } 3635 _setParentAndPosition(parent, x, y) { 3636 parent.changeParent(this); 3637 this.x = x; 3638 this.y = y; 3639 this.fixAndSetPosition(); 3640 } 3641 getRect(tx, ty) { 3642 const scale = this.parentScale; 3643 const [pageWidth, pageHeight] = this.pageDimensions; 3644 const [pageX, pageY] = this.pageTranslation; 3645 const shiftX = tx / scale; 3646 const shiftY = ty / scale; 3647 const x = this.x * pageWidth; 3648 const y = this.y * pageHeight; 3649 const width = this.width * pageWidth; 3650 const height = this.height * pageHeight; 3651 switch (this.rotation) { 3652 case 0: 3653 return [x + shiftX + pageX, pageHeight - y - shiftY - height + pageY, x + shiftX + width + pageX, pageHeight - y - shiftY + pageY]; 3654 case 90: 3655 return [x + shiftY + pageX, pageHeight - y + shiftX + pageY, x + shiftY + height + pageX, pageHeight - y + shiftX + width + pageY]; 3656 case 180: 3657 return [x - shiftX - width + pageX, pageHeight - y + shiftY + pageY, x - shiftX + pageX, pageHeight - y + shiftY + height + pageY]; 3658 case 270: 3659 return [x - shiftY - height + pageX, pageHeight - y - shiftX - width + pageY, x - shiftY + pageX, pageHeight - y - shiftX + pageY]; 3660 default: 3661 throw new Error("Invalid rotation"); 3662 } 3663 } 3664 getRectInCurrentCoords(rect, pageHeight) { 3665 const [x1, y1, x2, y2] = rect; 3666 const width = x2 - x1; 3667 const height = y2 - y1; 3668 switch (this.rotation) { 3669 case 0: 3670 return [x1, pageHeight - y2, width, height]; 3671 case 90: 3672 return [x1, pageHeight - y1, height, width]; 3673 case 180: 3674 return [x2, pageHeight - y1, width, height]; 3675 case 270: 3676 return [x2, pageHeight - y2, height, width]; 3677 default: 3678 throw new Error("Invalid rotation"); 3679 } 3680 } 3681 onceAdded() {} 3682 isEmpty() { 3683 return false; 3684 } 3685 enableEditMode() { 3686 this.#isInEditMode = true; 3687 } 3688 disableEditMode() { 3689 this.#isInEditMode = false; 3690 } 3691 isInEditMode() { 3692 return this.#isInEditMode; 3693 } 3694 shouldGetKeyboardEvents() { 3695 return false; 3696 } 3697 needsToBeRebuilt() { 3698 return this.div && !this.isAttachedToDOM; 3699 } 3700 rebuild() { 3701 this.div?.addEventListener("focusin", this.#boundFocusin); 3702 this.div?.addEventListener("focusout", this.#boundFocusout); 3703 } 3704 serialize(isForCopying = false, context = null) { 3705 (0, _util.unreachable)("An editor must be serializable"); 3706 } 3707 static deserialize(data, parent, uiManager) { 3708 const editor = new this.prototype.constructor({ 3709 parent, 3710 id: parent.getNextId(), 3711 uiManager 3712 }); 3713 editor.rotation = data.rotation; 3714 const [pageWidth, pageHeight] = editor.pageDimensions; 3715 const [x, y, width, height] = editor.getRectInCurrentCoords(data.rect, pageHeight); 3716 editor.x = x / pageWidth; 3717 editor.y = y / pageHeight; 3718 editor.width = width / pageWidth; 3719 editor.height = height / pageHeight; 3720 return editor; 3721 } 3722 remove() { 3723 this.div.removeEventListener("focusin", this.#boundFocusin); 3724 this.div.removeEventListener("focusout", this.#boundFocusout); 3725 if (!this.isEmpty()) { 3726 this.commit(); 3727 } 3728 if (this.parent) { 3729 this.parent.remove(this); 3730 } else { 3731 this._uiManager.removeEditor(this); 3732 } 3733 this.#altTextButton?.remove(); 3734 this.#altTextButton = null; 3735 this.#altTextTooltip = null; 3736 } 3737 get isResizable() { 3738 return false; 3739 } 3740 makeResizable() { 3741 if (this.isResizable) { 3742 this.#createResizers(); 3743 this.#resizersDiv.classList.remove("hidden"); 3744 } 3745 } 3746 select() { 3747 this.makeResizable(); 3748 this.div?.classList.add("selectedEditor"); 3749 } 3750 unselect() { 3751 this.#resizersDiv?.classList.add("hidden"); 3752 this.div?.classList.remove("selectedEditor"); 3753 if (this.div?.contains(document.activeElement)) { 3754 this._uiManager.currentLayer.div.focus(); 3755 } 3756 } 3757 updateParams(type, value) {} 3758 disableEditing() { 3759 if (this.#altTextButton) { 3760 this.#altTextButton.hidden = true; 3761 } 3762 } 3763 enableEditing() { 3764 if (this.#altTextButton) { 3765 this.#altTextButton.hidden = false;
3766 } 3767 } 3768 enterInEditMode() {} 3769 get contentDiv() { 3770 return this.div; 3771 } 3772 get isEditing() { 3773 return this.#isEditing; 3774 } 3775 set isEditing(value) { 3776 this.#isEditing = value; 3777 if (!this.parent) { 3778 return; 3779 } 3780 if (value) { 3781 this.parent.setSelected(this); 3782 this.parent.setActiveEditor(this); 3783 } else { 3784 this.parent.setActiveEditor(null); 3785 } 3786 } 3787 setAspectRatio(width, height) { 3788 this.#keepAspectRatio = true; 3789 const aspectRatio = width / height; 3790 const { 3791 style 3792 } = this.div; 3793 style.aspectRatio = aspectRatio; 3794 style.height = "auto"; 3795 } 3796 static get MIN_SIZE() { 3797 return 16; 3798 } 3799} 3800exports.AnnotationEditor = AnnotationEditor; 3801class FakeEditor extends AnnotationEditor { 3802 constructor(params) { 3803 super(params); 3804 this.annotationElementId = params.annotationElementId; 3805 this.deleted = true; 3806 } 3807 serialize() { 3808 return { 3809 id: this.annotationElementId, 3810 deleted: true, 3811 pageIndex: this.pageIndex 3812 }; 3813 } 3814} 3815 3816/***/ }), 3817/* 5 */ 3818/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 3819 3820 3821 3822Object.defineProperty(exports, "__esModule", ({ 3823 value: true 3824})); 3825exports.KeyboardManager = exports.CommandManager = exports.ColorManager = exports.AnnotationEditorUIManager = void 0; 3826exports.bindEvents = bindEvents; 3827exports.opacityToHex = opacityToHex; 3828var _util = __w_pdfjs_require__(1); 3829var _display_utils = __w_pdfjs_require__(6); 3830function bindEvents(obj, element, names) { 3831 for (const name of names) { 3832 element.addEventListener(name, obj[name].bind(obj)); 3833 } 3834} 3835function opacityToHex(opacity) { 3836 return Math.round(Math.min(255, Math.max(1, 255 * opacity))).toString(16).padStart(2, "0"); 3837} 3838class IdManager { 3839 #id = 0; 3840 getId() { 3841 return `${_util.AnnotationEditorPrefix}${this.#id++}`; 3842 } 3843} 3844class ImageManager { 3845 #baseId = (0, _util.getUuid)(); 3846 #id = 0; 3847 #cache = null; 3848 static get _isSVGFittingCanvas() { 3849 const svg = `data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 1 1" width="1" height="1" xmlns="http://www.w3.org/2000/svg"><rect width="1" height="1" style="fill:red;"/></svg>`; 3850 const canvas = new OffscreenCanvas(1, 3); 3851 const ctx = canvas.getContext("2d"); 3852 const image = new Image(); 3853 image.src = svg; 3854 const promise = image.decode().then(() => { 3855 ctx.drawImage(image, 0, 0, 1, 1, 0, 0, 1, 3); 3856 return new Uint32Array(ctx.getImageData(0, 0, 1, 1).data.buffer)[0] === 0; 3857 }); 3858 return (0, _util.shadow)(this, "_isSVGFittingCanvas", promise); 3859 } 3860 async #get(key, rawData) { 3861 this.#cache ||= new Map(); 3862 let data = this.#cache.get(key); 3863 if (data === null) { 3864 return null; 3865 } 3866 if (data?.bitmap) { 3867 data.refCounter += 1; 3868 return data; 3869 } 3870 try { 3871 data ||= { 3872 bitmap: null, 3873 id: `image_${this.#baseId}_${this.#id++}`, 3874 refCounter: 0, 3875 isSvg: false 3876 }; 3877 let image; 3878 if (typeof rawData === "string") { 3879 data.url = rawData; 3880 const response = await fetch(rawData); 3881 if (!response.ok) { 3882 throw new Error(response.statusText); 3883 } 3884 image = await response.blob(); 3885 } else { 3886 image = data.file = rawData; 3887 } 3888 if (image.type === "image/svg+xml") { 3889 const mustRemoveAspectRatioPromise = ImageManager._isSVGFittingCanvas; 3890 const fileReader = new FileReader(); 3891 const imageElement = new Image(); 3892 const imagePromise = new Promise((resolve, reject) => { 3893 imageElement.onload = () => { 3894 data.bitmap = imageElement; 3895 data.isSvg = true; 3896 resolve(); 3897 }; 3898 fileReader.onload = async () => { 3899 const url = data.svgUrl = fileReader.result; 3900 imageElement.src = (await mustRemoveAspectRatioPromise) ? `${url}#svgView(preserveAspectRatio(none))` : url; 3901 }; 3902 imageElement.onerror = fileReader.onerror = reject; 3903 }); 3904 fileReader.readAsDataURL(image); 3905 await imagePromise; 3906 } else { 3907 data.bitmap = await createImageBitmap(image); 3908 } 3909 data.refCounter = 1; 3910 } catch (e) { 3911 console.error(e); 3912 data = null; 3913 } 3914 this.#cache.set(key, data); 3915 if (data) { 3916 this.#cache.set(data.id, data); 3917 } 3918 return data; 3919 } 3920 async getFromFile(file) { 3921 const { 3922 lastModified, 3923 name, 3924 size, 3925 type 3926 } = file; 3927 return this.#get(`${lastModified}_${name}_${size}_${type}`, file); 3928 } 3929 async getFromUrl(url) { 3930 return this.#get(url, url); 3931 } 3932 async getFromId(id) { 3933 this.#cache ||= new Map(); 3934 const data = this.#cache.get(id); 3935 if (!data) { 3936 return null; 3937 } 3938 if (data.bitmap) { 3939 data.refCounter += 1; 3940 return data; 3941 } 3942 if (data.file) { 3943 return this.getFromFile(data.file); 3944 } 3945 return this.getFromUrl(data.url); 3946 } 3947 getSvgUrl(id) { 3948 const data = this.#cache.get(id); 3949 if (!data?.isSvg) { 3950 return null; 3951 } 3952 return data.svgUrl; 3953 } 3954 deleteId(id) { 3955 this.#cache ||= new Map(); 3956 const data = this.#cache.get(id); 3957 if (!data) { 3958 return; 3959 } 3960 data.refCounter -= 1; 3961 if (data.refCounter !== 0) { 3962 return; 3963 } 3964 data.bitmap = null; 3965 } 3966 isValidId(id) { 3967 return id.startsWith(`image_${this.#baseId}_`); 3968 } 3969} 3970class CommandManager { 3971 #commands = []; 3972 #locked = false;
3973 #maxSize; 3974 #position = -1; 3975 constructor(maxSize = 128) { 3976 this.#maxSize = maxSize; 3977 } 3978 add({ 3979 cmd, 3980 undo, 3981 mustExec, 3982 type = NaN, 3983 overwriteIfSameType = false, 3984 keepUndo = false 3985 }) { 3986 if (mustExec) { 3987 cmd(); 3988 } 3989 if (this.#locked) { 3990 return; 3991 } 3992 const save = { 3993 cmd, 3994 undo, 3995 type 3996 }; 3997 if (this.#position === -1) { 3998 if (this.#commands.length > 0) { 3999 this.#commands.length = 0; 4000 } 4001 this.#position = 0; 4002 this.#commands.push(save); 4003 return; 4004 } 4005 if (overwriteIfSameType && this.#commands[this.#position].type === type) { 4006 if (keepUndo) { 4007 save.undo = this.#commands[this.#position].undo; 4008 } 4009 this.#commands[this.#position] = save; 4010 return; 4011 } 4012 const next = this.#position + 1; 4013 if (next === this.#maxSize) { 4014 this.#commands.splice(0, 1); 4015 } else { 4016 this.#position = next; 4017 if (next < this.#commands.length) { 4018 this.#commands.splice(next); 4019 } 4020 } 4021 this.#commands.push(save); 4022 } 4023 undo() { 4024 if (this.#position === -1) { 4025 return; 4026 } 4027 this.#locked = true; 4028 this.#commands[this.#position].undo(); 4029 this.#locked = false; 4030 this.#position -= 1; 4031 } 4032 redo() { 4033 if (this.#position < this.#commands.length - 1) { 4034 this.#position += 1; 4035 this.#locked = true; 4036 this.#commands[this.#position].cmd(); 4037 this.#locked = false; 4038 } 4039 } 4040 hasSomethingToUndo() { 4041 return this.#position !== -1; 4042 } 4043 hasSomethingToRedo() { 4044 return this.#position < this.#commands.length - 1; 4045 } 4046 destroy() { 4047 this.#commands = null; 4048 } 4049} 4050exports.CommandManager = CommandManager; 4051class KeyboardManager { 4052 constructor(callbacks) { 4053 this.buffer = []; 4054 this.callbacks = new Map(); 4055 this.allKeys = new Set(); 4056 const { 4057 isMac 4058 } = _util.FeatureTest.platform; 4059 for (const [keys, callback, options = {}] of callbacks) { 4060 for (const key of keys) { 4061 const isMacKey = key.startsWith("mac+"); 4062 if (isMac && isMacKey) { 4063 this.callbacks.set(key.slice(4), { 4064 callback, 4065 options 4066 }); 4067 this.allKeys.add(key.split("+").at(-1)); 4068 } else if (!isMac && !isMacKey) { 4069 this.callbacks.set(key, { 4070 callback, 4071 options 4072 }); 4073 this.allKeys.add(key.split("+").at(-1)); 4074 } 4075 } 4076 } 4077 } 4078 #serialize(event) { 4079 if (event.altKey) { 4080 this.buffer.push("alt"); 4081 } 4082 if (event.ctrlKey) { 4083 this.buffer.push("ctrl"); 4084 } 4085 if (event.metaKey) { 4086 this.buffer.push("meta"); 4087 } 4088 if (event.shiftKey) { 4089 this.buffer.push("shift"); 4090 } 4091 this.buffer.push(event.key); 4092 const str = this.buffer.join("+"); 4093 this.buffer.length = 0; 4094 return str; 4095 } 4096 exec(self, event) { 4097 if (!this.allKeys.has(event.key)) { 4098 return; 4099 } 4100 const info = this.callbacks.get(this.#serialize(event)); 4101 if (!info) { 4102 return; 4103 } 4104 const { 4105 callback, 4106 options: { 4107 bubbles = false, 4108 args = [], 4109 checker = null 4110 } 4111 } = info; 4112 if (checker && !checker(self, event)) { 4113 return; 4114 } 4115 callback.bind(self, ...args)(); 4116 if (!bubbles) { 4117 event.stopPropagation(); 4118 event.preventDefault(); 4119 } 4120 } 4121} 4122exports.KeyboardManager = KeyboardManager; 4123class ColorManager { 4124 static _colorsMapping = new Map([["CanvasText", [0, 0, 0]], ["Canvas", [255, 255, 255]]]); 4125 get _colors() { 4126 const colors = new Map([["CanvasText", null], ["Canvas", null]]); 4127 (0, _display_utils.getColorValues)(colors); 4128 return (0, _util.shadow)(this, "_colors", colors); 4129 } 4130 convert(color) { 4131 const rgb = (0, _display_utils.getRGB)(color); 4132 if (!window.matchMedia("(forced-colors: active)").matches) { 4133 return rgb; 4134 } 4135 for (const [name, RGB] of this._colors) { 4136 if (RGB.every((x, i) => x === rgb[i])) { 4137 return ColorManager._colorsMapping.get(name); 4138 } 4139 } 4140 return rgb; 4141 } 4142 getHexCode(name) { 4143 const rgb = this._colors.get(name); 4144 if (!rgb) { 4145 return name; 4146 } 4147 return _util.Util.makeHexColor(...rgb); 4148 } 4149} 4150exports.ColorManager = ColorManager; 4151class AnnotationEditorUIManager { 4152 #activeEditor = null; 4153 #allEditors = new Map(); 4154 #allLayers = new Map(); 4155 #altTextManager = null; 4156 #annotationStorage = null; 4157 #commandManager = new CommandManager(); 4158 #currentPageIndex = 0; 4159 #deletedAnnotationsElementIds = new Set(); 4160 #draggingEditors = null; 4161 #editorTypes = null; 4162 #editorsToRescale = new Set(); 4163 #filterFactory = null; 4164 #idManager = new IdManager(); 4165 #isEnabled = false;
4166 #isWaiting = false; 4167 #lastActiveElement = null; 4168 #mode = _util.AnnotationEditorType.NONE; 4169 #selectedEditors = new Set(); 4170 #pageColors = null; 4171 #boundBlur = this.blur.bind(this); 4172 #boundFocus = this.focus.bind(this); 4173 #boundCopy = this.copy.bind(this); 4174 #boundCut = this.cut.bind(this); 4175 #boundPaste = this.paste.bind(this); 4176 #boundKeydown = this.keydown.bind(this); 4177 #boundOnEditingAction = this.onEditingAction.bind(this); 4178 #boundOnPageChanging = this.onPageChanging.bind(this); 4179 #boundOnScaleChanging = this.onScaleChanging.bind(this); 4180 #boundOnRotationChanging = this.onRotationChanging.bind(this); 4181 #previousStates = { 4182 isEditing: false, 4183 isEmpty: true, 4184 hasSomethingToUndo: false, 4185 hasSomethingToRedo: false, 4186 hasSelectedEditor: false 4187 }; 4188 #translation = [0, 0]; 4189 #translationTimeoutId = null; 4190 #container = null; 4191 #viewer = null; 4192 static TRANSLATE_SMALL = 1; 4193 static TRANSLATE_BIG = 10; 4194 static get _keyboardManager() { 4195 const proto = AnnotationEditorUIManager.prototype; 4196 const arrowChecker = self => { 4197 const { 4198 activeElement 4199 } = document; 4200 return activeElement && self.#container.contains(activeElement) && self.hasSomethingToControl(); 4201 }; 4202 const small = this.TRANSLATE_SMALL; 4203 const big = this.TRANSLATE_BIG; 4204 return (0, _util.shadow)(this, "_keyboardManager", new KeyboardManager([[["ctrl+a", "mac+meta+a"], proto.selectAll], [["ctrl+z", "mac+meta+z"], proto.undo], [["ctrl+y", "ctrl+shift+z", "mac+meta+shift+z", "ctrl+shift+Z", "mac+meta+shift+Z"], proto.redo], [["Backspace", "alt+Backspace", "ctrl+Backspace", "shift+Backspace", "mac+Backspace", "mac+alt+Backspace", "mac+ctrl+Backspace", "Delete", "ctrl+Delete", "shift+Delete", "mac+Delete"], proto.delete], [["Escape", "mac+Escape"], proto.unselectAll], [["ArrowLeft", "mac+ArrowLeft"], proto.translateSelectedEditors, { 4205 args: [-small, 0], 4206 checker: arrowChecker 4207 }], [["ctrl+ArrowLeft", "mac+shift+ArrowLeft"], proto.translateSelectedEditors, { 4208 args: [-big, 0], 4209 checker: arrowChecker 4210 }], [["ArrowRight", "mac+ArrowRight"], proto.translateSelectedEditors, { 4211 args: [small, 0], 4212 checker: arrowChecker 4213 }], [["ctrl+ArrowRight", "mac+shift+ArrowRight"], proto.translateSelectedEditors, { 4214 args: [big, 0], 4215 checker: arrowChecker 4216 }], [["ArrowUp", "mac+ArrowUp"], proto.translateSelectedEditors, { 4217 args: [0, -small], 4218 checker: arrowChecker 4219 }], [["ctrl+ArrowUp", "mac+shift+ArrowUp"], proto.translateSelectedEditors, { 4220 args: [0, -big], 4221 checker: arrowChecker 4222 }], [["ArrowDown", "mac+ArrowDown"], proto.translateSelectedEditors, { 4223 args: [0, small], 4224 checker: arrowChecker 4225 }], [["ctrl+ArrowDown", "mac+shift+ArrowDown"], proto.translateSelectedEditors, { 4226 args: [0, big], 4227 checker: arrowChecker 4228 }]])); 4229 } 4230 constructor(container, viewer, altTextManager, eventBus, pdfDocument, pageColors) { 4231 this.#container = container; 4232 this.#viewer = viewer; 4233 this.#altTextManager = altTextManager; 4234 this._eventBus = eventBus; 4235 this._eventBus._on("editingaction", this.#boundOnEditingAction); 4236 this._eventBus._on("pagechanging", this.#boundOnPageChanging); 4237 this._eventBus._on("scalechanging", this.#boundOnScaleChanging); 4238 this._eventBus._on("rotationchanging", this.#boundOnRotationChanging); 4239 this.#annotationStorage = pdfDocument.annotationStorage; 4240 this.#filterFactory = pdfDocument.filterFactory; 4241 this.#pageColors = pageColors; 4242 this.viewParameters = { 4243 realScale: _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS, 4244 rotation: 0 4245 }; 4246 } 4247 destroy() { 4248 this.#removeKeyboardManager(); 4249 this.#removeFocusManager(); 4250 this._eventBus._off("editingaction", this.#boundOnEditingAction); 4251 this._eventBus._off("pagechanging", this.#boundOnPageChanging); 4252 this._eventBus._off("scalechanging", this.#boundOnScaleChanging); 4253 this._eventBus._off("rotationchanging", this.#boundOnRotationChanging); 4254 for (const layer of this.#allLayers.values()) { 4255 layer.destroy(); 4256 } 4257 this.#allLayers.clear(); 4258 this.#allEditors.clear(); 4259 this.#editorsToRescale.clear(); 4260 this.#activeEditor = null; 4261 this.#selectedEditors.clear(); 4262 this.#commandManager.destroy(); 4263 this.#altTextManager.destroy(); 4264 } 4265 get hcmFilter() { 4266 return (0, _util.shadow)(this, "hcmFilter", this.#pageColors ? this.#filterFactory.addHCMFilter(this.#pageColors.foreground, this.#pageColors.background) : "none"); 4267 } 4268 get direction() { 4269 return (0, _util.shadow)(this, "direction", getComputedStyle(this.#container).direction); 4270 } 4271 editAltText(editor) { 4272 this.#altTextManager?.editAltText(this, editor); 4273 } 4274 onPageChanging({ 4275 pageNumber 4276 }) { 4277 this.#currentPageIndex = pageNumber - 1; 4278 } 4279 focusMainContainer() { 4280 this.#container.focus(); 4281 } 4282 findParent(x, y) { 4283 for (const layer of this.#allLayers.values()) { 4284 const { 4285 x: layerX, 4286 y: layerY, 4287 width, 4288 height 4289 } = layer.div.getBoundingClientRect(); 4290 if (x >= layerX && x <= layerX + width && y >
vendor: 4,849 bytes, lines 4290-4473
4290= layerY && y <= layerY + height) { 4291 return layer; 4292 } 4293 } 4294 return null; 4295 } 4296 disableUserSelect(value = false) { 4297 this.#viewer.classList.toggle("noUserSelect", value); 4298 } 4299 addShouldRescale(editor) { 4300 this.#editorsToRescale.add(editor); 4301 } 4302 removeShouldRescale(editor) { 4303 this.#editorsToRescale.delete(editor); 4304 } 4305 onScaleChanging({ 4306 scale 4307 }) { 4308 this.commitOrRemove(); 4309 this.viewParameters.realScale = scale * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS; 4310 for (const editor of this.#editorsToRescale) { 4311 editor.onScaleChanging(); 4312 } 4313 } 4314 onRotationChanging({ 4315 pagesRotation 4316 }) { 4317 this.commitOrRemove(); 4318 this.viewParameters.rotation = pagesRotation; 4319 } 4320 addToAnnotationStorage(editor) { 4321 if (!editor.isEmpty() && this.#annotationStorage && !this.#annotationStorage.has(editor.id)) { 4322 this.#annotationStorage.setValue(editor.id, editor); 4323 } 4324 } 4325 #addFocusManager() { 4326 window.addEventListener("focus", this.#boundFocus); 4327 window.addEventListener("blur", this.#boundBlur); 4328 } 4329 #removeFocusManager() { 4330 window.removeEventListener("focus", this.#boundFocus); 4331 window.removeEventListener("blur", this.#boundBlur); 4332 } 4333 blur() { 4334 if (!this.hasSelection) { 4335 return; 4336 } 4337 const { 4338 activeElement 4339 } = document; 4340 for (const editor of this.#selectedEditors) { 4341 if (editor.div.contains(activeElement)) { 4342 this.#lastActiveElement = [editor, activeElement]; 4343 editor._focusEventsAllowed = false; 4344 break; 4345 } 4346 } 4347 } 4348 focus() { 4349 if (!this.#lastActiveElement) { 4350 return; 4351 } 4352 const [lastEditor, lastActiveElement] = this.#lastActiveElement; 4353 this.#lastActiveElement = null; 4354 lastActiveElement.addEventListener("focusin", () => { 4355 lastEditor._focusEventsAllowed = true; 4356 }, { 4357 once: true 4358 }); 4359 lastActiveElement.focus(); 4360 } 4361 #addKeyboardManager() { 4362 window.addEventListener("keydown", this.#boundKeydown, { 4363 capture: true 4364 }); 4365 } 4366 #removeKeyboardManager() { 4367 window.removeEventListener("keydown", this.#boundKeydown, { 4368 capture: true 4369 }); 4370 } 4371 #addCopyPasteListeners() { 4372 document.addEventListener("copy", this.#boundCopy); 4373 document.addEventListener("cut", this.#boundCut); 4374 document.addEventListener("paste", this.#boundPaste); 4375 } 4376 #removeCopyPasteListeners() { 4377 document.removeEventListener("copy", this.#boundCopy); 4378 document.removeEventListener("cut", this.#boundCut); 4379 document.removeEventListener("paste", this.#boundPaste); 4380 } 4381 addEditListeners() { 4382 this.#addKeyboardManager(); 4383 this.#addCopyPasteListeners(); 4384 } 4385 removeEditListeners() { 4386 this.#removeKeyboardManager(); 4387 this.#removeCopyPasteListeners(); 4388 } 4389 copy(event) { 4390 event.preventDefault(); 4391 this.#activeEditor?.commitOrRemove(); 4392 if (!this.hasSelection) { 4393 return; 4394 } 4395 const editors = []; 4396 for (const editor of this.#selectedEditors) { 4397 const serialized = editor.serialize(true); 4398 if (serialized) { 4399 editors.push(serialized); 4400 } 4401 } 4402 if (editors.length === 0) { 4403 return; 4404 } 4405 event.clipboardData.setData("application/pdfjs", JSON.stringify(editors)); 4406 } 4407 cut(event) { 4408 this.copy(event); 4409 this.delete(); 4410 } 4411 paste(event) { 4412 event.preventDefault(); 4413 const { 4414 clipboardData 4415 } = event; 4416 for (const item of clipboardData.items) { 4417 for (const editorType of this.#editorTypes) { 4418 if (editorType.isHandlingMimeForPasting(item.type)) { 4419 editorType.paste(item, this.currentLayer); 4420 return; 4421 } 4422 } 4423 } 4424 let data = clipboardData.getData("application/pdfjs"); 4425 if (!data) { 4426 return; 4427 } 4428 try { 4429 data = JSON.parse(data); 4430 } catch (ex) { 4431 (0, _util.warn)(`paste: "${ex.message}".`); 4432 return; 4433 } 4434 if (!Array.isArray(data)) { 4435 return; 4436 } 4437 this.unselectAll(); 4438 const layer = this.currentLayer; 4439 try { 4440 const newEditors = []; 4441 for (const editor of data) { 4442 const deserializedEditor = layer.deserialize(editor); 4443 if (!deserializedEditor) { 4444 return; 4445 } 4446 newEditors.push(deserializedEditor); 4447 } 4448 const cmd = () => { 4449 for (const editor of newEditors) { 4450 this.#addEditorToLayer(editor); 4451 } 4452 this.#selectEditors(newEditors); 4453 }; 4454 const undo = () => { 4455 for (const editor of newEditors) { 4456 editor.remove(); 4457 } 4458 }; 4459 this.addCommands({ 4460 cmd, 4461 undo, 4462 mustExec: true 4463 }); 4464 } catch (ex) { 4465 (0, _util.warn)(`paste: "${ex.message}".`); 4466 } 4467 } 4468 keydown(event) { 4469 if (!this.getActive()?.shouldGetKeyboardEvents()) { 4470 AnnotationEditorUIManager._keyboardManager.exec(this, event); 4471 } 4472 } 4473 onEditingAction(details) {
4474 if (["undo", "redo", "delete", "selectAll"].includes(details.name)) { 4475 this[details.name](); 4476 } 4477 } 4478 #dispatchUpdateStates(details) { 4479 const hasChanged = Object.entries(details).some(([key, value]) => this.#previousStates[key] !== value); 4480 if (hasChanged) { 4481 this._eventBus.dispatch("annotationeditorstateschanged", { 4482 source: this, 4483 details: Object.assign(this.#previousStates, details) 4484 }); 4485 } 4486 } 4487 #dispatchUpdateUI(details) { 4488 this._eventBus.dispatch("annotationeditorparamschanged", { 4489 source: this, 4490 details 4491 }); 4492 } 4493 setEditingState(isEditing) { 4494 if (isEditing) { 4495 this.#addFocusManager(); 4496 this.#addKeyboardManager(); 4497 this.#addCopyPasteListeners(); 4498 this.#dispatchUpdateStates({ 4499 isEditing: this.#mode !== _util.AnnotationEditorType.NONE, 4500 isEmpty: this.#isEmpty(), 4501 hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(), 4502 hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(), 4503 hasSelectedEditor: false 4504 }); 4505 } else { 4506 this.#removeFocusManager(); 4507 this.#removeKeyboardManager(); 4508 this.#removeCopyPasteListeners(); 4509 this.#dispatchUpdateStates({ 4510 isEditing: false 4511 }); 4512 this.disableUserSelect(false); 4513 } 4514 } 4515 registerEditorTypes(types) { 4516 if (this.#editorTypes) { 4517 return; 4518 } 4519 this.#editorTypes = types; 4520 for (const editorType of this.#editorTypes) { 4521 this.#dispatchUpdateUI(editorType.defaultPropertiesToUpdate); 4522 } 4523 } 4524 getId() { 4525 return this.#idManager.getId(); 4526 } 4527 get currentLayer() { 4528 return this.#allLayers.get(this.#currentPageIndex); 4529 } 4530 getLayer(pageIndex) { 4531 return this.#allLayers.get(pageIndex); 4532 } 4533 get currentPageIndex() { 4534 return this.#currentPageIndex; 4535 } 4536 addLayer(layer) { 4537 this.#allLayers.set(layer.pageIndex, layer); 4538 if (this.#isEnabled) { 4539 layer.enable(); 4540 } else { 4541 layer.disable(); 4542 } 4543 } 4544 removeLayer(layer) { 4545 this.#allLayers.delete(layer.pageIndex); 4546 } 4547 updateMode(mode, editId = null) { 4548 if (this.#mode === mode) { 4549 return; 4550 } 4551 this.#mode = mode; 4552 if (mode === _util.AnnotationEditorType.NONE) { 4553 this.setEditingState(false); 4554 this.#disableAll(); 4555 return; 4556 } 4557 this.setEditingState(true); 4558 this.#enableAll(); 4559 this.unselectAll(); 4560 for (const layer of this.#allLayers.values()) { 4561 layer.updateMode(mode); 4562 } 4563 if (!editId) { 4564 return; 4565 } 4566 for (const editor of this.#allEditors.values()) { 4567 if (editor.annotationElementId === editId) { 4568 this.setSelected(editor); 4569 editor.enterInEditMode(); 4570 break; 4571 } 4572 } 4573 } 4574 updateToolbar(mode) { 4575 if (mode === this.#mode) { 4576 return; 4577 } 4578 this._eventBus.dispatch("switchannotationeditormode", { 4579 source: this, 4580 mode 4581 }); 4582 } 4583 updateParams(type, value) { 4584 if (!this.#editorTypes) { 4585 return; 4586 } 4587 if (type === _util.AnnotationEditorParamsType.CREATE) { 4588 this.currentLayer.addNewEditor(type); 4589 return; 4590 } 4591 for (const editor of this.#selectedEditors) { 4592 editor.updateParams(type, value); 4593 } 4594 for (const editorType of this.#editorTypes) { 4595 editorType.updateDefaultParams(type, value); 4596 } 4597 } 4598 enableWaiting(mustWait = false) { 4599 if (this.#isWaiting === mustWait) { 4600 return; 4601 } 4602 this.#isWaiting = mustWait; 4603 for (const layer of this.#allLayers.values()) { 4604 if (mustWait) { 4605 layer.disableClick(); 4606 } else { 4607 layer.enableClick(); 4608 } 4609 layer.div.classList.toggle("waiting", mustWait); 4610 } 4611 } 4612 #enableAll() { 4613 if (!this.#isEnabled) { 4614 this.#isEnabled = true; 4615 for (const layer of this.#allLayers.values()) { 4616 layer.enable(); 4617 } 4618 } 4619 } 4620 #disableAll() { 4621 this.unselectAll(); 4622 if (this.#isEnabled) { 4623 this.#isEnabled = false; 4624 for (const layer of this.#allLayers.values()) { 4625 layer.disable(); 4626 } 4627 } 4628 } 4629 getEditors(pageIndex) { 4630 const editors = []; 4631 for (const editor of this.#allEditors.values()) { 4632 if (editor.pageIndex === pageIndex) { 4633 editors.push(editor); 4634 } 4635 } 4636 return editors; 4637 } 4638 getEditor(id) { 4639 return this.#allEditors.get(id); 4640 } 4641 addEditor(editor) { 4642 this.#allEditors.set(editor.id, editor); 4643 } 4644 removeEditor(editor) { 4645 this.#allEditors.delete(editor.id); 4646 this.unselect(editor); 4647 if (!editor.annotationElementId || !this.#deletedAnnotationsElementIds.has(editor.annotationElementId)) { 4648 this.#annotationStorage?.remove(editor.id); 4649 } 4650 } 4651 addDeletedAnnotationElement(editor) { 4652 this.#deletedAnnotationsElementIds.add(editor.annotationElementId); 4653 editor.deleted = true; 4654 } 4655 isDeletedAnnotationElement(annotationElementId) { 4656 return this.#deletedAnnotationsElementIds.has(annotationElementId); 4657 } 4658 removeDeletedAnnotationElement(editor) { 4659 this.#deletedAnnotationsElementIds.delete(editor.annotationElementId); 4660 editor.deleted = false;
vendor: 5,451 bytes, lines 4661-4879
4661 } 4662 #addEditorToLayer(editor) { 4663 const layer = this.#allLayers.get(editor.pageIndex); 4664 if (layer) { 4665 layer.addOrRebuild(editor); 4666 } else { 4667 this.addEditor(editor); 4668 } 4669 } 4670 setActiveEditor(editor) { 4671 if (this.#activeEditor === editor) { 4672 return; 4673 } 4674 this.#activeEditor = editor; 4675 if (editor) { 4676 this.#dispatchUpdateUI(editor.propertiesToUpdate); 4677 } 4678 } 4679 toggleSelected(editor) { 4680 if (this.#selectedEditors.has(editor)) { 4681 this.#selectedEditors.delete(editor); 4682 editor.unselect(); 4683 this.#dispatchUpdateStates({ 4684 hasSelectedEditor: this.hasSelection 4685 }); 4686 return; 4687 } 4688 this.#selectedEditors.add(editor); 4689 editor.select(); 4690 this.#dispatchUpdateUI(editor.propertiesToUpdate); 4691 this.#dispatchUpdateStates({ 4692 hasSelectedEditor: true 4693 }); 4694 } 4695 setSelected(editor) { 4696 for (const ed of this.#selectedEditors) { 4697 if (ed !== editor) { 4698 ed.unselect(); 4699 } 4700 } 4701 this.#selectedEditors.clear(); 4702 this.#selectedEditors.add(editor); 4703 editor.select(); 4704 this.#dispatchUpdateUI(editor.propertiesToUpdate); 4705 this.#dispatchUpdateStates({ 4706 hasSelectedEditor: true 4707 }); 4708 } 4709 isSelected(editor) { 4710 return this.#selectedEditors.has(editor); 4711 } 4712 unselect(editor) { 4713 editor.unselect(); 4714 this.#selectedEditors.delete(editor); 4715 this.#dispatchUpdateStates({ 4716 hasSelectedEditor: this.hasSelection 4717 }); 4718 } 4719 get hasSelection() { 4720 return this.#selectedEditors.size !== 0; 4721 } 4722 undo() { 4723 this.#commandManager.undo(); 4724 this.#dispatchUpdateStates({ 4725 hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(), 4726 hasSomethingToRedo: true, 4727 isEmpty: this.#isEmpty() 4728 }); 4729 } 4730 redo() { 4731 this.#commandManager.redo(); 4732 this.#dispatchUpdateStates({ 4733 hasSomethingToUndo: true, 4734 hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(), 4735 isEmpty: this.#isEmpty() 4736 }); 4737 } 4738 addCommands(params) { 4739 this.#commandManager.add(params); 4740 this.#dispatchUpdateStates({ 4741 hasSomethingToUndo: true, 4742 hasSomethingToRedo: false, 4743 isEmpty: this.#isEmpty() 4744 }); 4745 } 4746 #isEmpty() { 4747 if (this.#allEditors.size === 0) { 4748 return true; 4749 } 4750 if (this.#allEditors.size === 1) { 4751 for (const editor of this.#allEditors.values()) { 4752 return editor.isEmpty(); 4753 } 4754 } 4755 return false; 4756 } 4757 delete() { 4758 this.commitOrRemove(); 4759 if (!this.hasSelection) { 4760 return; 4761 } 4762 const editors = [...this.#selectedEditors]; 4763 const cmd = () => { 4764 for (const editor of editors) { 4765 editor.remove(); 4766 } 4767 }; 4768 const undo = () => { 4769 for (const editor of editors) { 4770 this.#addEditorToLayer(editor); 4771 } 4772 }; 4773 this.addCommands({ 4774 cmd, 4775 undo, 4776 mustExec: true 4777 }); 4778 } 4779 commitOrRemove() { 4780 this.#activeEditor?.commitOrRemove(); 4781 } 4782 hasSomethingToControl() { 4783 return this.#activeEditor || this.hasSelection; 4784 } 4785 #selectEditors(editors) { 4786 this.#selectedEditors.clear(); 4787 for (const editor of editors) { 4788 if (editor.isEmpty()) { 4789 continue; 4790 } 4791 this.#selectedEditors.add(editor); 4792 editor.select(); 4793 } 4794 this.#dispatchUpdateStates({ 4795 hasSelectedEditor: true 4796 }); 4797 } 4798 selectAll() { 4799 for (const editor of this.#selectedEditors) { 4800 editor.commit(); 4801 } 4802 this.#selectEditors(this.#allEditors.values()); 4803 } 4804 unselectAll() { 4805 if (this.#activeEditor) { 4806 this.#activeEditor.commitOrRemove(); 4807 return; 4808 } 4809 if (!this.hasSelection) { 4810 return; 4811 } 4812 for (const editor of this.#selectedEditors) { 4813 editor.unselect(); 4814 } 4815 this.#selectedEditors.clear(); 4816 this.#dispatchUpdateStates({ 4817 hasSelectedEditor: false 4818 }); 4819 } 4820 translateSelectedEditors(x, y, noCommit = false) { 4821 if (!noCommit) { 4822 this.commitOrRemove(); 4823 } 4824 if (!this.hasSelection) { 4825 return; 4826 } 4827 this.#translation[0] += x; 4828 this.#translation[1] += y; 4829 const [totalX, totalY] = this.#translation; 4830 const editors = [...this.#selectedEditors]; 4831 const TIME_TO_WAIT = 1000; 4832 if (this.#translationTimeoutId) { 4833 clearTimeout(this.#translationTimeoutId); 4834 } 4835 this.#translationTimeoutId = setTimeout(() => { 4836 this.#translationTimeoutId = null; 4837 this.#translation[0] = this.#translation[1] = 0; 4838 this.addCommands({ 4839 cmd: () => { 4840 for (const editor of editors) { 4841 if (this.#allEditors.has(editor.id)) { 4842 editor.translateInPage(totalX, totalY); 4843 } 4844 } 4845 }, 4846 undo: () => { 4847 for (const editor of editors) { 4848 if (this.#allEditors.has(editor.id)) { 4849 editor.translateInPage(-totalX, -totalY); 4850 } 4851 } 4852 }, 4853 mustExec: false 4854 }); 4855 }, TIME_TO_WAIT); 4856 for (const editor of editors) { 4857 editor.translateInPage(x, y); 4858 } 4859 } 4860 setUpDragSession() { 4861 if (!this.hasSelection) { 4862 return; 4863 } 4864 this.disableUserSelect(true); 4865 this.#draggingEditors = new Map(); 4866 for (const editor of this.#selectedEditors) { 4867 this.#draggingEditors.set(editor, { 4868 savedX: editor.x, 4869 savedY: editor.y, 4870 savedPageIndex: editor.pageIndex, 4871 newX: 0, 4872 newY: 0, 4873 newPageIndex: -1 4874 }); 4875 } 4876 } 4877 endDragSession() { 4878 if (!this.#draggingEditors) { 4879 return false;
4880 } 4881 this.disableUserSelect(false); 4882 const map = this.#draggingEditors; 4883 this.#draggingEditors = null; 4884 let mustBeAddedInUndoStack = false; 4885 for (const [{ 4886 x, 4887 y, 4888 pageIndex 4889 }, value] of map) { 4890 value.newX = x; 4891 value.newY = y; 4892 value.newPageIndex = pageIndex; 4893 mustBeAddedInUndoStack ||= x !== value.savedX || y !== value.savedY || pageIndex !== value.savedPageIndex; 4894 } 4895 if (!mustBeAddedInUndoStack) { 4896 return false; 4897 } 4898 const move = (editor, x, y, pageIndex) => { 4899 if (this.#allEditors.has(editor.id)) { 4900 const parent = this.#allLayers.get(pageIndex); 4901 if (parent) { 4902 editor._setParentAndPosition(parent, x, y); 4903 } else { 4904 editor.pageIndex = pageIndex; 4905 editor.x = x; 4906 editor.y = y; 4907 } 4908 } 4909 }; 4910 this.addCommands({ 4911 cmd: () => { 4912 for (const [editor, { 4913 newX, 4914 newY, 4915 newPageIndex 4916 }] of map) { 4917 move(editor, newX, newY, newPageIndex); 4918 } 4919 }, 4920 undo: () => { 4921 for (const [editor, { 4922 savedX, 4923 savedY, 4924 savedPageIndex 4925 }] of map) { 4926 move(editor, savedX, savedY, savedPageIndex); 4927 } 4928 }, 4929 mustExec: true 4930 }); 4931 return true; 4932 } 4933 dragSelectedEditors(tx, ty) { 4934 if (!this.#draggingEditors) { 4935 return; 4936 } 4937 for (const editor of this.#draggingEditors.keys()) { 4938 editor.drag(tx, ty); 4939 } 4940 } 4941 rebuild(editor) { 4942 if (editor.parent === null) { 4943 const parent = this.getLayer(editor.pageIndex); 4944 if (parent) { 4945 parent.changeParent(editor); 4946 parent.addOrRebuild(editor); 4947 } else { 4948 this.addEditor(editor); 4949 this.addToAnnotationStorage(editor); 4950 editor.rebuild(); 4951 } 4952 } else { 4953 editor.parent.addOrRebuild(editor); 4954 } 4955 } 4956 isActive(editor) { 4957 return this.#activeEditor === editor; 4958 } 4959 getActive() { 4960 return this.#activeEditor; 4961 } 4962 getMode() { 4963 return this.#mode; 4964 } 4965 get imageManager() { 4966 return (0, _util.shadow)(this, "imageManager", new ImageManager()); 4967 } 4968} 4969exports.AnnotationEditorUIManager = AnnotationEditorUIManager; 4970 4971/***/ }), 4972/* 6 */ 4973/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 4974 4975 4976 4977Object.defineProperty(exports, "__esModule", ({ 4978 value: true 4979})); 4980exports.StatTimer = exports.RenderingCancelledException = exports.PixelsPerInch = exports.PageViewport = exports.PDFDateString = exports.DOMStandardFontDataFactory = exports.DOMSVGFactory = exports.DOMFilterFactory = exports.DOMCanvasFactory = exports.DOMCMapReaderFactory = void 0; 4981exports.deprecated = deprecated; 4982exports.getColorValues = getColorValues; 4983exports.getCurrentTransform = getCurrentTransform; 4984exports.getCurrentTransformInverse = getCurrentTransformInverse; 4985exports.getFilenameFromUrl = getFilenameFromUrl; 4986exports.getPdfFilenameFromUrl = getPdfFilenameFromUrl; 4987exports.getRGB = getRGB; 4988exports.getXfaPageViewport = getXfaPageViewport; 4989exports.isDataScheme = isDataScheme; 4990exports.isPdfFile = isPdfFile; 4991exports.isValidFetchUrl = isValidFetchUrl; 4992exports.loadScript = loadScript; 4993exports.noContextMenu = noContextMenu; 4994exports.setLayerDimensions = setLayerDimensions; 4995var _base_factory = __w_pdfjs_require__(7); 4996var _util = __w_pdfjs_require__(1); 4997const SVG_NS = "http://www.w3.org/2000/svg"; 4998class PixelsPerInch { 4999 static CSS = 96.0; 5000 static PDF = 72.0; 5001 static PDF_TO_CSS_UNITS = this.CSS / this.PDF; 5002} 5003exports.PixelsPerInch = PixelsPerInch; 5004class DOMFilterFactory extends _base_factory.BaseFilterFactory { 5005 #_cache; 5006 #_defs; 5007 #docId; 5008 #document; 5009 #hcmFilter; 5010 #hcmKey; 5011 #hcmUrl; 5012 #hcmHighlightFilter; 5013 #hcmHighlightKey; 5014 #hcmHighlightUrl; 5015 #id = 0; 5016 constructor({ 5017 docId, 5018 ownerDocument = globalThis.document 5019 } = {}) { 5020 super(); 5021 this.#docId = docId; 5022 this.#document = ownerDocument; 5023 } 5024 get #cache() { 5025 return this.#_cache ||= new Map(); 5026 } 5027 get #defs() { 5028 if (!this.#_defs) { 5029 const div = this.#document.createElement("div"); 5030 const { 5031 style 5032 } = div; 5033 style.visibility = "hidden"; 5034 style.contain = "strict"; 5035 style.width = style.height = 0; 5036 style.position = "absolute"; 5037 style.top = style.left = 0; 5038 style.zIndex = -1; 5039 const svg = this.#document.createElementNS(SVG_NS, "svg"); 5040 svg.setAttribute("width", 0); 5041 svg.setAttribute("height", 0); 5042 this.#_defs = this.#document.createElementNS(SVG_NS, "defs"); 5043 div.append(svg); 5044 svg.append(this.#_defs); 5045 this.#document.body.append(div); 5046 } 5047 return this.#_defs; 5048 } 5049 addFilter(maps) { 5050 if (!maps) { 5051 return "none"; 5052 } 5053 let value = this.#cache.get(maps); 5054 if (value) { 5055 return value; 5056 } 5057 let tableR, tableG, tableB, key; 5058 if (maps.length === 1) { 5059 const mapR = maps[0]; 5060 const buffer = new Array(256); 5061 for (let i = 0; i < 256; i++) {
5062 buffer[i] = mapR[i] / 255; 5063 } 5064 key = tableR = tableG = tableB = buffer.join(","); 5065 } else { 5066 const [mapR, mapG, mapB] = maps; 5067 const bufferR = new Array(256); 5068 const bufferG = new Array(256); 5069 const bufferB = new Array(256); 5070 for (let i = 0; i < 256; i++) { 5071 bufferR[i] = mapR[i] / 255; 5072 bufferG[i] = mapG[i] / 255; 5073 bufferB[i] = mapB[i] / 255; 5074 } 5075 tableR = bufferR.join(","); 5076 tableG = bufferG.join(","); 5077 tableB = bufferB.join(","); 5078 key = `${tableR}${tableG}${tableB}`; 5079 } 5080 value = this.#cache.get(key); 5081 if (value) { 5082 this.#cache.set(maps, value); 5083 return value; 5084 } 5085 const id = `g_${this.#docId}_transfer_map_${this.#id++}`; 5086 const url = `url(#${id})`; 5087 this.#cache.set(maps, url); 5088 this.#cache.set(key, url); 5089 const filter = this.#createFilter(id); 5090 this.#addTransferMapConversion(tableR, tableG, tableB, filter); 5091 return url; 5092 } 5093 addHCMFilter(fgColor, bgColor) { 5094 const key = `${fgColor}-${bgColor}`; 5095 if (this.#hcmKey === key) { 5096 return this.#hcmUrl; 5097 } 5098 this.#hcmKey = key; 5099 this.#hcmUrl = "none"; 5100 this.#hcmFilter?.remove(); 5101 if (!fgColor || !bgColor) { 5102 return this.#hcmUrl; 5103 } 5104 const fgRGB = this.#getRGB(fgColor); 5105 fgColor = _util.Util.makeHexColor(...fgRGB); 5106 const bgRGB = this.#getRGB(bgColor); 5107 bgColor = _util.Util.makeHexColor(...bgRGB); 5108 this.#defs.style.color = ""; 5109 if (fgColor === "#000000" && bgColor === "#ffffff" || fgColor === bgColor) { 5110 return this.#hcmUrl; 5111 } 5112 const map = new Array(256); 5113 for (let i = 0; i <= 255; i++) { 5114 const x = i / 255; 5115 map[i] = x <= 0.03928 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4; 5116 } 5117 const table = map.join(","); 5118 const id = `g_${this.#docId}_hcm_filter`; 5119 const filter = this.#hcmHighlightFilter = this.#createFilter(id); 5120 this.#addTransferMapConversion(table, table, table, filter); 5121 this.#addGrayConversion(filter); 5122 const getSteps = (c, n) => { 5123 const start = fgRGB[c] / 255; 5124 const end = bgRGB[c] / 255; 5125 const arr = new Array(n + 1); 5126 for (let i = 0; i <= n; i++) { 5127 arr[i] = start + i / n * (end - start); 5128 } 5129 return arr.join(","); 5130 }; 5131 this.#addTransferMapConversion(getSteps(0, 5), getSteps(1, 5), getSteps(2, 5), filter); 5132 this.#hcmUrl = `url(#${id})`; 5133 return this.#hcmUrl; 5134 } 5135 addHighlightHCMFilter(fgColor, bgColor, newFgColor, newBgColor) { 5136 const key = `${fgColor}-${bgColor}-${newFgColor}-${newBgColor}`; 5137 if (this.#hcmHighlightKey === key) { 5138 return this.#hcmHighlightUrl; 5139 } 5140 this.#hcmHighlightKey = key; 5141 this.#hcmHighlightUrl = "none"; 5142 this.#hcmHighlightFilter?.remove(); 5143 if (!fgColor || !bgColor) { 5144 return this.#hcmHighlightUrl; 5145 } 5146 const [fgRGB, bgRGB] = [fgColor, bgColor].map(this.#getRGB.bind(this)); 5147 let fgGray = Math.round(0.2126 * fgRGB[0] + 0.7152 * fgRGB[1] + 0.0722 * fgRGB[2]); 5148 let bgGray = Math.round(0.2126 * bgRGB[0] + 0.7152 * bgRGB[1] + 0.0722 * bgRGB[2]); 5149 let [newFgRGB, newBgRGB] = [newFgColor, newBgColor].map(this.#getRGB.bind(this)); 5150 if (bgGray < fgGray) { 5151 [fgGray, bgGray, newFgRGB, newBgRGB] = [bgGray, fgGray, newBgRGB, newFgRGB]; 5152 } 5153 this.#defs.style.color = ""; 5154 const getSteps = (fg, bg, n) => { 5155 const arr = new Array(256); 5156 const step = (bgGray - fgGray) / n; 5157 const newStart = fg / 255; 5158 const newStep = (bg - fg) / (255 * n); 5159 let prev = 0; 5160 for (let i = 0; i <= n; i++) { 5161 const k = Math.round(fgGray + i * step); 5162 const value = newStart + i * newStep; 5163 for (let j = prev; j <= k; j++) { 5164 arr[j] = value; 5165 } 5166 prev = k + 1; 5167 } 5168 for (let i = prev; i < 256; i++) { 5169 arr[i] = arr[prev - 1]; 5170 } 5171 return arr.join(","); 5172 }; 5173 const id = `g_${this.#docId}_hcm_highlight_filter`; 5174 const filter = this.#hcmHighlightFilter = this.#createFilter(id); 5175 this.#addGrayConversion(filter); 5176 this.#addTransferMapConversion(getSteps(newFgRGB[0], newBgRGB[0], 5), getSteps(newFgRGB[1], newBgRGB[1], 5), getSteps(newFgRGB[2], newBgRGB[2], 5), filter); 5177 this.#hcmHighlightUrl = `url(#${id})`; 5178 return this.#hcmHighlightUrl; 5179 } 5180 destroy(keepHCM = false) { 5181 if (keepHCM && (this.#hcmUrl || this.#hcmHighlightUrl)) { 5182 return; 5183 } 5184 if (this.#_defs) { 5185 this.#_defs.parentNode.parentNode.remove(); 5186 this.#_defs = null; 5187 } 5188 if (this.#_cache) { 5189 this.#_cache.clear(); 5190 this.#_cache = null; 5191 } 5192 this.#id = 0; 5193 } 5194 #addGrayConversion(filter) { 5195 const feColorMatrix = this.#document.createElementNS(SVG_NS, "feColorMatrix"); 5196 feColorMatrix.setAttribute("type", "matrix"); 5197 feColorMatrix.setAttribute("values", "0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0"); 5198 filter.append(feColorMatrix); 5199 } 5200 #createFilter(id) { 5201 const filter = this.#document.createElementNS(SVG_NS, "filter"); 5202 filter.setAttribute("color-interpolation-filters", "sRGB"); 5203 filter.setAttribute("id", id); 5204 this.#defs.append(filter); 5205 return filter; 5206 } 5207 #appendFeFunc(feComponentTransfer, func, table) { 5208 const feFunc = this.#document.createElementNS(SVG_NS, func); 5209 feFunc.setAttribute("type", "discrete"); 5210 feFunc.setAttribute("tableValues", table); 5211 feComponentTransfer.append(feFunc); 5212 } 5213 #addTransferMapConversion(rTable, gTable, bTable, filter) { 5214 const feComponentTransfer = this.#document.createElementNS(SVG_NS, "feComponentTransfer"); 5215 filter.append(feComponentTransfer);
5216 this.#appendFeFunc(feComponentTransfer, "feFuncR", rTable); 5217 this.#appendFeFunc(feComponentTransfer, "feFuncG", gTable); 5218 this.#appendFeFunc(feComponentTransfer, "feFuncB", bTable); 5219 } 5220 #getRGB(color) { 5221 this.#defs.style.color = color; 5222 return getRGB(getComputedStyle(this.#defs).getPropertyValue("color")); 5223 } 5224} 5225exports.DOMFilterFactory = DOMFilterFactory; 5226class DOMCanvasFactory extends _base_factory.BaseCanvasFactory { 5227 constructor({ 5228 ownerDocument = globalThis.document 5229 } = {}) { 5230 super(); 5231 this._document = ownerDocument; 5232 } 5233 _createCanvas(width, height) { 5234 const canvas = this._document.createElement("canvas"); 5235 canvas.width = width; 5236 canvas.height = height; 5237 return canvas; 5238 } 5239} 5240exports.DOMCanvasFactory = DOMCanvasFactory; 5241async function fetchData(url, asTypedArray = false) { 5242 if (isValidFetchUrl(url, document.baseURI)) { 5243 const response = await fetch(url); 5244 if (!response.ok) { 5245 throw new Error(response.statusText); 5246 } 5247 return asTypedArray ? new Uint8Array(await response.arrayBuffer()) : (0, _util.stringToBytes)(await response.text()); 5248 } 5249 return new Promise((resolve, reject) => { 5250 const request = new XMLHttpRequest(); 5251 request.open("GET", url, true); 5252 if (asTypedArray) { 5253 request.responseType = "arraybuffer"; 5254 } 5255 request.onreadystatechange = () => { 5256 if (request.readyState !== XMLHttpRequest.DONE) { 5257 return; 5258 } 5259 if (request.status === 200 || request.status === 0) { 5260 let data; 5261 if (asTypedArray && request.response) { 5262 data = new Uint8Array(request.response); 5263 } else if (!asTypedArray && request.responseText) { 5264 data = (0, _util.stringToBytes)(request.responseText); 5265 } 5266 if (data) { 5267 resolve(data); 5268 return; 5269 } 5270 } 5271 reject(new Error(request.statusText)); 5272 }; 5273 request.send(null); 5274 }); 5275} 5276class DOMCMapReaderFactory extends _base_factory.BaseCMapReaderFactory { 5277 _fetchData(url, compressionType) { 5278 return fetchData(url, this.isCompressed).then(data => { 5279 return { 5280 cMapData: data, 5281 compressionType 5282 }; 5283 }); 5284 } 5285} 5286exports.DOMCMapReaderFactory = DOMCMapReaderFactory; 5287class DOMStandardFontDataFactory extends _base_factory.BaseStandardFontDataFactory { 5288 _fetchData(url) { 5289 return fetchData(url, true); 5290 } 5291} 5292exports.DOMStandardFontDataFactory = DOMStandardFontDataFactory; 5293class DOMSVGFactory extends _base_factory.BaseSVGFactory { 5294 _createSVG(type) { 5295 return document.createElementNS(SVG_NS, type); 5296 } 5297} 5298exports.DOMSVGFactory = DOMSVGFactory; 5299class PageViewport { 5300 constructor({ 5301 viewBox, 5302 scale, 5303 rotation, 5304 offsetX = 0, 5305 offsetY = 0, 5306 dontFlip = false 5307 }) { 5308 this.viewBox = viewBox; 5309 this.scale = scale; 5310 this.rotation = rotation; 5311 this.offsetX = offsetX; 5312 this.offsetY = offsetY; 5313 const centerX = (viewBox[2] + viewBox[0]) / 2; 5314 const centerY = (viewBox[3] + viewBox[1]) / 2; 5315 let rotateA, rotateB, rotateC, rotateD; 5316 rotation %= 360; 5317 if (rotation < 0) { 5318 rotation += 360; 5319 } 5320 switch (rotation) { 5321 case 180: 5322 rotateA = -1; 5323 rotateB = 0; 5324 rotateC = 0; 5325 rotateD = 1; 5326 break; 5327 case 90: 5328 rotateA = 0; 5329 rotateB = 1; 5330 rotateC = 1; 5331 rotateD = 0; 5332 break; 5333 case 270: 5334 rotateA = 0; 5335 rotateB = -1; 5336 rotateC = -1; 5337 rotateD = 0; 5338 break; 5339 case 0: 5340 rotateA = 1; 5341 rotateB = 0; 5342 rotateC = 0; 5343 rotateD = -1; 5344 break; 5345 default: 5346 throw new Error("PageViewport: Invalid rotation, must be a multiple of 90 degrees."); 5347 } 5348 if (dontFlip) { 5349 rotateC = -rotateC; 5350 rotateD = -rotateD; 5351 } 5352 let offsetCanvasX, offsetCanvasY; 5353 let width, height; 5354 if (rotateA === 0) { 5355 offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX; 5356 offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY; 5357 width = (viewBox[3] - viewBox[1]) * scale; 5358 height = (viewBox[2] - viewBox[0]) * scale; 5359 } else { 5360 offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX; 5361 offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY; 5362 width = (viewBox[2] - viewBox[0]) * scale; 5363 height = (viewBox[3] - viewBox[1]) * scale; 5364 } 5365 this.transform = [rotateA * scale, rotateB * scale, rotateC * scale, rotateD * scale, offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY]; 5366 this.width = width; 5367 this.height = height; 5368 } 5369 get rawDims() { 5370 const {
5371 viewBox 5372 } = this; 5373 return (0, _util.shadow)(this, "rawDims", { 5374 pageWidth: viewBox[2] - viewBox[0], 5375 pageHeight: viewBox[3] - viewBox[1], 5376 pageX: viewBox[0], 5377 pageY: viewBox[1] 5378 }); 5379 } 5380 clone({ 5381 scale = this.scale, 5382 rotation = this.rotation, 5383 offsetX = this.offsetX, 5384 offsetY = this.offsetY, 5385 dontFlip = false 5386 } = {}) { 5387 return new PageViewport({ 5388 viewBox: this.viewBox.slice(), 5389 scale, 5390 rotation, 5391 offsetX, 5392 offsetY, 5393 dontFlip 5394 }); 5395 } 5396 convertToViewportPoint(x, y) { 5397 return _util.Util.applyTransform([x, y], this.transform); 5398 } 5399 convertToViewportRectangle(rect) { 5400 const topLeft = _util.Util.applyTransform([rect[0], rect[1]], this.transform); 5401 const bottomRight = _util.Util.applyTransform([rect[2], rect[3]], this.transform); 5402 return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]]; 5403 } 5404 convertToPdfPoint(x, y) { 5405 return _util.Util.applyInverseTransform([x, y], this.transform); 5406 } 5407} 5408exports.PageViewport = PageViewport; 5409class RenderingCancelledException extends _util.BaseException { 5410 constructor(msg, extraDelay = 0) { 5411 super(msg, "RenderingCancelledException"); 5412 this.extraDelay = extraDelay; 5413 } 5414} 5415exports.RenderingCancelledException = RenderingCancelledException; 5416function isDataScheme(url) { 5417 const ii = url.length; 5418 let i = 0; 5419 while (i < ii && url[i].trim() === "") { 5420 i++; 5421 } 5422 return url.substring(i, i + 5).toLowerCase() === "data:"; 5423} 5424function isPdfFile(filename) { 5425 return typeof filename === "string" && /\.pdf$/i.test(filename); 5426} 5427function getFilenameFromUrl(url, onlyStripPath = false) { 5428 if (!onlyStripPath) { 5429 [url] = url.split(/[#?]/, 1); 5430 } 5431 return url.substring(url.lastIndexOf("/") + 1); 5432} 5433function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") { 5434 if (typeof url !== "string") { 5435 return defaultFilename; 5436 } 5437 if (isDataScheme(url)) { 5438 (0, _util.warn)('getPdfFilenameFromUrl: ignore "data:"-URL for performance reasons.'); 5439 return defaultFilename; 5440 } 5441 const reURI = /^(?:(?:[^:]+:)?\/\/[^/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/; 5442 const reFilename = /[^/?#=]+\.pdf\b(?!.*\.pdf\b)/i; 5443 const splitURI = reURI.exec(url); 5444 let suggestedFilename = reFilename.exec(splitURI[1]) || reFilename.exec(splitURI[2]) || reFilename.exec(splitURI[3]); 5445 if (suggestedFilename) { 5446 suggestedFilename = suggestedFilename[0]; 5447 if (suggestedFilename.includes("%")) { 5448 try { 5449 suggestedFilename = reFilename.exec(decodeURIComponent(suggestedFilename))[0]; 5450 } catch {} 5451 } 5452 } 5453 return suggestedFilename || defaultFilename; 5454} 5455class StatTimer { 5456 started = Object.create(null); 5457 times = []; 5458 time(name) { 5459 if (name in this.started) { 5460 (0, _util.warn)(`Timer is already running for ${name}`); 5461 } 5462 this.started[name] = Date.now(); 5463 } 5464 timeEnd(name) { 5465 if (!(name in this.started)) { 5466 (0, _util.warn)(`Timer has not been started for ${name}`); 5467 } 5468 this.times.push({ 5469 name, 5470 start: this.started[name], 5471 end: Date.now() 5472 }); 5473 delete this.started[name]; 5474 } 5475 toString() { 5476 const outBuf = []; 5477 let longest = 0; 5478 for (const { 5479 name 5480 } of this.times) { 5481 longest = Math.max(name.length, longest); 5482 } 5483 for (const { 5484 name, 5485 start, 5486 end 5487 } of this.times) { 5488 outBuf.push(`${name.padEnd(longest)} ${end - start}
5488ms\n`); 5489 } 5490 return outBuf.join(""); 5491 } 5492} 5493exports.StatTimer = StatTimer; 5494function isValidFetchUrl(url, baseUrl) { 5495 try { 5496 const { 5497 protocol 5498 } = baseUrl ? new URL(url, baseUrl) : new URL(url); 5499 return protocol === "http:" || protocol === "https:"; 5500 } catch { 5501 return false; 5502 } 5503} 5504function noContextMenu(e) { 5505 e.preventDefault(); 5506} 5507function loadScript(src, removeScriptElement = false) { 5508 return new Promise((resolve, reject) => { 5509 const script = document.createElement("script"); 5510 script.src = src; 5511 script.onload = function (evt) { 5512 if (removeScriptElement) { 5513 script.remove(); 5514 } 5515 resolve(evt); 5516 }; 5517 script.onerror = function () { 5518 reject(new Error(`Cannot load script at: ${script.src}`)); 5519 }; 5520 (document.head || document.documentElement).append(script); 5521 }); 5522} 5523function deprecated(details) { 5524 console.log("Deprecated API usage: " + details); 5525} 5526let pdfDateStringRegex; 5527class PDFDateString { 5528 static toDateObject(input) { 5529 if (!input || typeof input !== "string") { 5530 return null; 5531 } 5532 pdfDateStringRegex ||= new RegExp("^D:" + "(\\d{4})" + "(\\d{2})?" + "(\\d{2})?" + "(\\d{2})?" + "(\\d{2})?" + "(\\d{2})?" + "([Z|+|-])?" + "(\\d{2})?" + "'?" + "(\\d{2})?" + "'?"); 5533 const matches = pdfDateStringRegex.exec(input); 5534 if (!matches) { 5535 return null; 5536 } 5537 const year = parseInt(matches[1], 10); 5538 let month = parseInt(matches[2], 10);
5539 month = month >= 1 && month <= 12 ? month - 1 : 0; 5540 let day = parseInt(matches[3], 10); 5541 day = day >= 1 && day <= 31 ? day : 1; 5542 let hour = parseInt(matches[4], 10); 5543 hour = hour >= 0 && hour <= 23 ? hour : 0; 5544 let minute = parseInt(matches[5], 10); 5545 minute = minute >= 0 && minute <= 59 ? minute : 0; 5546 let second = parseInt(matches[6], 10); 5547 second = second >= 0 && second <= 59 ? second : 0; 5548 const universalTimeRelation = matches[7] || "Z"; 5549 let offsetHour = parseInt(matches[8], 10); 5550 offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0; 5551 let offsetMinute = parseInt(matches[9], 10) || 0; 5552 offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0; 5553 if (universalTimeRelation === "-") { 5554 hour += offsetHour; 5555 minute += offsetMinute; 5556 } else if (universalTimeRelation === "+") { 5557 hour -= offsetHour; 5558 minute -= offsetMinute; 5559 } 5560 return new Date(Date.UTC(year, month, day, hour, minute, second)); 5561 } 5562} 5563exports.PDFDateString = PDFDateString; 5564function getXfaPageViewport(xfaPage, { 5565 scale = 1, 5566 rotation = 0 5567}) { 5568 const { 5569 width, 5570 height 5571 } = xfaPage.attributes.style; 5572 const viewBox = [0, 0, parseInt(width), parseInt(height)]; 5573 return new PageViewport({ 5574 viewBox, 5575 scale, 5576 rotation 5577 }); 5578} 5579function getRGB(color) { 5580 if (color.startsWith("#")) { 5581 const colorRGB = parseInt(color.slice(1), 16); 5582 return [(colorRGB & 0xff0000) >> 16, (colorRGB & 0x00ff00) >> 8, colorRGB & 0x0000ff]; 5583 } 5584 if (color.startsWith("rgb(")) { 5585 return color.slice(4, -1).split(",").map(x => parseInt(x)); 5586 } 5587 if (color.startsWith("rgba(")) { 5588 return color.slice(5, -1).split(",").map(x => parseInt(x)).slice(0, 3); 5589 } 5590 (0, _util.warn)(`Not a valid color format: "${color}"`); 5591 return [0, 0, 0]; 5592} 5593function getColorValues(colors) { 5594 const span = document.createElement("span"); 5595 span.style.visibility = "hidden"; 5596 document.body.append(span); 5597 for (const name of colors.keys()) { 5598 span.style.color = name; 5599 const computedColor = window.getComputedStyle(span).color; 5600 colors.set(name, getRGB(computedColor)); 5601 } 5602 span.remove(); 5603} 5604function getCurrentTransform(ctx) { 5605 const { 5606 a, 5607 b, 5608 c, 5609 d, 5610 e, 5611 f 5612 } = ctx.getTransform(); 5613 return [a, b, c, d, e, f]; 5614} 5615function getCurrentTransformInverse(ctx) { 5616 const { 5617 a, 5618 b, 5619 c, 5620 d, 5621 e, 5622 f 5623 } = ctx.getTransform().invertSelf(); 5624 return [a, b, c, d, e, f]; 5625} 5626function setLayerDimensions(div, viewport, mustFlip = false, mustRotate = true) { 5627 if (viewport instanceof PageViewport) { 5628 const { 5629 pageWidth, 5630 pageHeight 5631 } = viewport.rawDims; 5632 const { 5633 style 5634 } = div; 5635 const useRound = _util.FeatureTest.isCSSRoundSupported; 5636 const w = `var(--scale-factor) * ${pageWidth}px`, 5637 h = `var(--scale-factor) * ${pageHeight}px`; 5638 const widthStr = useRound ? `round(${w}, 1px)` : `calc(${w})`, 5639 heightStr = useRound ? `round(${h}, 1px)` : `calc(${h})`; 5640 if (!mustFlip || viewport.rotation % 180 === 0) { 5641 style.width = widthStr; 5642 style.height = heightStr; 5643 } else { 5644 style.width = heightStr; 5645 style.height = widthStr; 5646 } 5647 } 5648 if (mustRotate) { 5649 div.setAttribute("data-main-rotation", viewport.rotation); 5650 } 5651} 5652 5653/***/ }), 5654/* 7 */ 5655/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 5656 5657 5658 5659Object.defineProperty(exports, "__esModule", ({ 5660 value: true 5661})); 5662exports.BaseStandardFontDataFactory = exports.BaseSVGFactory = exports.BaseFilterFactory = exports.BaseCanvasFactory = exports.BaseCMapReaderFactory = void 0; 5663var _util = __w_pdfjs_require__(1); 5664class BaseFilterFactory { 5665 constructor() { 5666 if (this.constructor === BaseFilterFactory) { 5667 (0, _util.unreachable)("Cannot initialize BaseFilterFactory."); 5668 } 5669 } 5670 addFilter(maps) { 5671 return "none"; 5672 } 5673 addHCMFilter(fgColor, bgColor) { 5674 return "none"; 5675 } 5676 addHighlightHCMFilter(fgColor, bgColor, newFgColor, newBgColor) { 5677 return "none"; 5678 } 5679 destroy(keepHCM = false) {} 5680} 5681exports.BaseFilterFactory = BaseFilterFactory; 5682class BaseCanvasFactory { 5683 constructor() { 5684 if (this.constructor === BaseCanvasFactory) { 5685 (0, _util.unreachable)("Cannot initialize BaseCanvasFactory."); 5686 } 5687 } 5688 create(width, height) { 5689 if (width <= 0 || height <= 0) { 5690 throw new Error("Invalid canvas size"); 5691 } 5692 const canvas = this._createCanvas(width, height); 5693 return { 5694 canvas, 5695 context: canvas.getContext("2d") 5696 }; 5697 } 5698 reset(canvasAndContext, width, height) { 5699 if (!canvasAndContext.canvas) { 5700 throw new Error("Canvas is not specified"); 5701 } 5702 if (width <= 0 || height <= 0) { 5703 throw new Error("Invalid canvas size"); 5704 } 5705 canvasAndContext.canvas.width = width; 5706 canvasAndContext.canvas.height = height; 5707 } 5708 destroy(canvasAndContext) { 5709 if (!canvasAndContext.canvas) { 5710 throw new Error("Canvas is not specified"); 5711 } 5712 canvasAndContext.canvas.width = 0; 5713 canvasAndContext.canvas.height = 0; 5714 canvasAndContext.canvas = null; 5715 canvasAndContext.context = null; 5716 } 5717 _createCanvas(width, height) { 5718 (0, _util.unreachable)("Abstract method `_createCanvas` called."); 5719 } 5720} 5721exports.BaseCanvasFactory = BaseCanvasFactory; 5722class BaseCMapReaderFactory { 5723 constructor({ 5724 baseUrl = null, 5725 isCompressed = true 5726 }) { 5727 if (this.constructor === BaseCMapReaderFactory) { 5728 (0, _util.unreachable)("Cannot initialize BaseCMapReaderFactory."); 5729 } 5730 this.baseUrl = baseUrl; 5731 this.isCompressed = isCompressed; 5732 } 5733 async fetch({ 5734 name 5735 }) { 5736 if (!this.baseUrl) { 5737 throw new Error('The CMap "baseUrl" parameter must be specified, ensure that ' + 'the "cMapUrl" and "cMapPacked" API parameters are provided.'); 5738 } 5739 if (!name) { 5740 throw new Error("CMap name must be specified."); 5741 } 5742 const url = this.baseUrl + name + (this.isCompressed ? ".bcmap" : ""); 5743 const compressionType = this.isCompressed ? _util.CMapCompressionType.BINARY : _util.CMapCompressionType.NONE; 5744 return this._fetchData(url, compressionType).catch(reason => { 5745 throw new Error(`Unable to load ${this.isCompressed ? "binary " : ""}CMap at: ${url}`); 5746 }); 5747 } 5748 _fetchData(url, compressionType) { 5749 (0, _util.unreachable)("Abstract method `_fetchData` called."); 5750 } 5751} 5752exports.BaseCMapReaderFactory = BaseCMapReaderFactory; 5753class BaseStandardFontDataFactory { 5754 constructor({ 5755 baseUrl = null 5756 }) { 5757 if (this.constructor === BaseStandardFontDataFactory) { 5758 (0, _util.unreachable)("Cannot initialize BaseStandardFontDataFactory."); 5759 } 5760 this.baseUrl = baseUrl; 5761 } 5762 async fetch({ 5763 filename 5764 }) { 5765 if (!this.baseUrl) { 5766 throw new Error('The standard font "baseUrl" parameter must be specified, ensure that ' + 'the "standardFontDataUrl" API parameter is provided.'); 5767 } 5768 if (!filename) { 5769 throw new Error("Font filename must be specified."); 5770 } 5771 const url = `${this.baseUrl}${filename}`; 5772 return this._fetchData(url).catch(reason => { 5773 throw new Error(`Unable to load font data at: ${url}`); 5774 }); 5775 } 5776 _fetchData(url) { 5777 (0, _util.unreachable)("Abstract method `_fetchData` called."); 5778 } 5779} 5780exports.BaseStandardFontDataFactory = BaseStandardFontDataFactory; 5781class BaseSVGFactory { 5782 constructor() { 5783 if (this.constructor === BaseSVGFactory) { 5784 (0, _util.unreachable)("Cannot initialize BaseSVGFactory."); 5785 } 5786 } 5787 create(width, height, skipDimensions = false) { 5788 if (width <= 0 || height <= 0) { 5789 throw new Error("Invalid SVG dimensions"); 5790 } 5791 const svg = this._createSVG("svg:svg"); 5792 svg.setAttribute("version", "1.1"); 5793 if (!skipDimensions) { 5794 svg.setAttribute("width", `${width}px`); 5795 svg.setAttribute("height", `${height}px`); 5796 } 5797 svg.setAttribute("preserveAspectRatio", "none"); 5798 svg.setAttribute("viewBox", `0 0 ${width} ${height}`); 5799 return svg; 5800 } 5801 createElement(type) { 5802 if (typeof type !== "string") { 5803 throw new Error("Invalid SVG element type"); 5804 } 5805 return this._createSVG(type); 5806 } 5807 _createSVG(type) { 5808 (0, _util.unreachable)("Abstract method `_createSVG` called."); 5809 } 5810} 5811exports.BaseSVGFactory = BaseSVGFactory; 5812 5813/***/ }), 5814/* 8 */ 5815/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 5816 5817 5818 5819Object.defineProperty(exports, "__esModule", ({ 5820 value: true 5821})); 5822exports.MurmurHash3_64 = void 0; 5823var _util = __w_pdfjs_require__(1); 5824const SEED = 0xc3d2e1f0; 5825const MASK_HIGH = 0xffff0000; 5826const MASK_LOW = 0xffff; 5827class MurmurHash3_64 { 5828 constructor(seed) { 5829 this.h1 = seed ? seed & 0xffffffff : SEED; 5830 this.h2 = seed ? seed & 0xffffffff : SEED; 5831 } 5832 update(input) { 5833 let data, length; 5834 if (typeof input === "string") { 5835 data = new Uint8Array(input.length * 2); 5836 length = 0; 5837 for (let i = 0, ii = input.length; i < ii; i++) { 5838 const code = input.charCodeAt(i); 5839 if (code <= 0xff) { 5840 data[length++] = code; 5841 } else { 5842 data[length++] = code >>> 8; 5843 data[length++] = code & 0xff; 5844 } 5845 } 5846 } else if ((0, _util.isArrayBuffer)(input)) { 5847 data = input.slice(); 5848 length = data.byteLength; 5849 } else { 5850 throw new Error("Wrong data format in MurmurHash3_64_update. " + "Input must be a string or array."); 5851 } 5852 const blockCounts = length >> 2; 5853 const tailLength = length - blockCounts * 4; 5854 const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts); 5855 let k1 = 0, 5856 k2 = 0; 5857 let h1 = this.h1, 5858 h2 = this.h2; 5859 const C1 = 0xcc9e2d51, 5860 C2 = 0x1b873593; 5861 const C1_LOW = C1 & MASK_LOW, 5862 C2_LOW = C2 & MASK_LOW; 5863 for (let i = 0; i < blockCounts; i++) { 5864 if (i & 1) {
5865 k1 = dataUint32[i]; 5866 k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; 5867 k1 = k1 << 15 | k1 >>> 17; 5868 k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; 5869 h1 ^= k1; 5870 h1 = h1 << 13 | h1 >>> 19; 5871 h1 = h1 * 5 + 0xe6546b64; 5872 } else { 5873 k2 = dataUint32[i]; 5874 k2 = k2 * C1 & MASK_HIGH | k2 * C1_LOW & MASK_LOW; 5875 k2 = k2 << 15 | k2 >>> 17; 5876 k2 = k2 * C2 & MASK_HIGH | k2 * C2_LOW & MASK_LOW; 5877 h2 ^= k2; 5878 h2 = h2 << 13 | h2 >>> 19; 5879 h2 = h2 * 5 + 0xe6546b64; 5880 } 5881 } 5882 k1 = 0; 5883 switch (tailLength) { 5884 case 3: 5885 k1 ^= data[blockCounts * 4 + 2] << 16; 5886 case 2: 5887 k1 ^= data[blockCounts * 4 + 1] << 8; 5888 case 1: 5889 k1 ^= data[blockCounts * 4]; 5890 k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; 5891 k1 = k1 << 15 | k1 >>> 17; 5892 k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; 5893 if (blockCounts & 1) { 5894 h1 ^= k1; 5895 } else { 5896 h2 ^= k1; 5897 } 5898 } 5899 this.h1 = h1; 5900 this.h2 = h2; 5901 } 5902 hexdigest() { 5903 let h1 = this.h1, 5904 h2 = this.h2; 5905 h1 ^= h2 >>> 1; 5906 h1 = h1 * 0xed558ccd & MASK_HIGH | h1 * 0x8ccd & MASK_LOW; 5907 h2 = h2 * 0xff51afd7 & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16; 5908 h1 ^= h2 >>> 1; 5909 h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW; 5910 h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16; 5911 h1 ^= h2 >>> 1; 5912 return (h1 >>> 0).toString(16).padStart(8, "0") + (h2 >>> 0).toString(16).padStart(8, "0"); 5913 } 5914} 5915exports.MurmurHash3_64 = MurmurHash3_64; 5916 5917/***/ }), 5918/* 9 */ 5919/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 5920 5921 5922 5923Object.defineProperty(exports, "__esModule", ({ 5924 value: true 5925})); 5926exports.FontLoader = exports.FontFaceObject = void 0; 5927var _util = __w_pdfjs_require__(1); 5928class FontLoader { 5929 #systemFonts = new Set(); 5930 constructor({ 5931 ownerDocument = globalThis.document, 5932 styleElement = null 5933 }) { 5934 this._document = ownerDocument; 5935 this.nativeFontFaces = new Set(); 5936 this.styleElement = null; 5937 this.loadingRequests = []; 5938 this.loadTestFontId = 0; 5939 } 5940 addNativeFontFace(nativeFontFace) { 5941 this.nativeFontFaces.add(nativeFontFace); 5942 this._document.fonts.add(nativeFontFace); 5943 } 5944 removeNativeFontFace(nativeFontFace) { 5945 this.nativeFontFaces.delete(nativeFontFace); 5946 this._document.fonts.delete(nativeFontFace); 5947 } 5948 insertRule(rule) { 5949 if (!this.styleElement) { 5950 this.styleElement = this._document.createElement("style"); 5951 this._document.documentElement.getElementsByTagName("head")[0].append(this.styleElement); 5952 } 5953 const styleSheet = this.styleElement.sheet; 5954 styleSheet.insertRule(rule, styleSheet.cssRules.length); 5955 } 5956 clear() { 5957 for (const nativeFontFace of this.nativeFontFaces) { 5958 this._document.fonts.delete(nativeFontFace); 5959 } 5960 this.nativeFontFaces.clear(); 5961 this.#systemFonts.clear(); 5962 if (this.styleElement) { 5963 this.styleElement.remove(); 5964 this.styleElement = null; 5965 } 5966 } 5967 async loadSystemFont(info) { 5968 if (!info || this.#systemFonts.has(info.loadedName)) { 5969 return; 5970 } 5971 (0, _util.assert)(!this.disableFontFace, "loadSystemFont shouldn't be called when `disableFontFace` is set."); 5972 if (this.isFontLoadingAPISupported) { 5973 const { 5974 loadedName, 5975 src, 5976 style 5977 } = info; 5978 const fontFace = new FontFace(loadedName, src, style); 5979 this.addNativeFontFace(fontFace); 5980 try { 5981 await fontFace.load(); 5982 this.#systemFonts.add(loadedName); 5983 } catch { 5984 (0, _util.warn)(`Cannot load system font: ${info.baseFontName}, installing it could help to improve PDF rendering.`); 5985 this.removeNativeFontFace(fontFace); 5986 } 5987 return; 5988 } 5989 (0, _util.unreachable)("Not implemented: loadSystemFont without the Font Loading API."); 5990 } 5991 async bind(font) { 5992 if (font.attached || font.missingFile && !font.systemFontInfo) { 5993 return; 5994 } 5995 font.attached = true; 5996 if (font.systemFontInfo) { 5997 await this.loadSystemFont(font.systemFontInfo); 5998 return; 5999 } 6000 if (this.isFontLoadingAPISupported) { 6001 const nativeFontFace = font.createNativeFontFace(); 6002 if (nativeFontFace) { 6003 this.addNativeFontFace(nativeFontFace); 6004 try { 6005 await nativeFontFace.loaded; 6006 } catch (ex) { 6007 (0, _util.warn)(`Failed to load font '${nativeFontFace.family}': '${ex}'.`); 6008 font.disableFontFace = true; 6009 throw ex; 6010 } 6011 } 6012 return; 6013 } 6014 const rule = font.createFontFaceRule(); 6015 if (rule) { 6016 this.insertRule(rule); 6017 if (this.isSyncFontLoadingSupported) { 6018 return; 6019 } 6020 await new Promise(resolve => { 6021 const request = this._queueLoadingCallback(resolve); 6022 this._prepareFontLoadEvent(font, request); 6023 }); 6024 } 6025 } 6026 get isFontLoadingAPISupported() { 6027 const hasFonts = !!this._document?.fonts; 6028 return (0, _util.shadow)(this, "isFontLoadingAPISupported", hasFonts); 6029 } 6030 get isSyncFontLoadingSupported() { 6031 let supported = false;
6032 if (_util.isNodeJS) { 6033 supported = true; 6034 } else if (typeof navigator !== "undefined" && /Mozilla\/5.0.*?rv:\d+.*? Gecko/.test(navigator.userAgent)) { 6035 supported = true; 6036 } 6037 return (0, _util.shadow)(this, "isSyncFontLoadingSupported", supported); 6038 } 6039 _queueLoadingCallback(callback) { 6040 function completeRequest() { 6041 (0, _util.assert)(!request.done, "completeRequest() cannot be called twice."); 6042 request.done = true; 6043 while (loadingRequests.length > 0 && loadingRequests[0].done) { 6044 const otherRequest = loadingRequests.shift(); 6045 setTimeout(otherRequest.callback, 0); 6046 } 6047 } 6048 const { 6049 loadingRequests 6050 } = this; 6051 const request = { 6052 done: false, 6053 complete: completeRequest, 6054 callback 6055 }; 6056 loadingRequests.push(request); 6057 return request; 6058 } 6059 get _loadTestFont() { 6060 const testFont = atob("T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQA" + "FQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAA" + "ALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgA" + "AAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1" + "AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD" + "6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACM" + "AooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4D" + "IP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAA" + "AAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUA" + "AQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgAB" + "AAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABY" + "AAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAA" + "AC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAA" + "AAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQAC" + "AQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3" + "Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTj" + "FQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA=="); 6061 return (0, _util.shadow)(this, "_loadTestFont", testFont); 6062 } 6063 _prepareFontLoadEvent(font, request) { 6064 function int32(data, offset) { 6065 return data.charCodeAt(offset) << 24 | data.charCodeAt(offset + 1) << 16 | data.charCodeAt(offset + 2) << 8 | data.charCodeAt(offset + 3) & 0xff; 6066 } 6067 function spliceString(s, offset, remove, insert) { 6068 const chunk1 = s.substring(0, offset); 6069 const chunk2 = s.substring(offset + remove); 6070 return chunk1 + insert + chunk2; 6071 } 6072 let i, ii; 6073 const canvas = this._document.createElement("canvas"); 6074 canvas.width = 1; 6075 canvas.height = 1; 6076 const ctx = canvas.getContext("2d"); 6077 let called = 0; 6078 function isFontReady(name, callback) { 6079 if (++called > 30) { 6080 (0, _util.warn)("Load test font never loaded."); 6081 callback(); 6082 return; 6083 } 6084 ctx.font = "30px " + name; 6085 ctx.fillText(".", 0, 20); 6086 const imageData = ctx.getImageData(0, 0, 1, 1); 6087 if (imageData.data[3] > 0) { 6088 callback(); 6089 return; 6090 } 6091 setTimeout(isFontReady.bind(null, name, callback)); 6092 } 6093 const loadTestFontId = `lt${Date.now()}${this.loadTestFontId++}`; 6094 let data = this._loadTestFont; 6095 const COMMENT_OFFSET = 976; 6096 data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length, loadTestFontId); 6097 const CFF_CHECKSUM_OFFSET = 16; 6098 const XXXX_VALUE = 0x58585858; 6099 let checksum = int32(data, CFF_CHECKSUM_OFFSET); 6100 for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) { 6101 checksum = checksum - XXXX_VALUE + int32(loadTestFontId, i) | 0; 6102 } 6103 if (i < loadTestFontId.length) { 6104 checksum = checksum - XXXX_VALUE + int32(loadTestFontId + "XXX", i) | 0; 6105 }
6106 data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, (0, _util.string32)(checksum)); 6107 const url = `url(data:font/opentype;base64,${btoa(data)});`; 6108 const rule = `@font-face {font-family:"${loadTestFontId}";src:${url}}`; 6109 this.insertRule(rule); 6110 const div = this._document.createElement("div"); 6111 div.style.visibility = "hidden"; 6112 div.style.width = div.style.height = "10px"; 6113 div.style.position = "absolute"; 6114 div.style.top = div.style.left = "0px"; 6115 for (const name of [font.loadedName, loadTestFontId]) { 6116 const span = this._document.createElement("span"); 6117 span.textContent = "Hi"; 6118 span.style.fontFamily = name; 6119 div.append(span); 6120 } 6121 this._document.body.append(div); 6122 isFontReady(loadTestFontId, () => { 6123 div.remove(); 6124 request.complete(); 6125 }); 6126 } 6127} 6128exports.FontLoader = FontLoader; 6129class FontFaceObject { 6130 constructor(translatedData, { 6131 isEvalSupported = true, 6132 disableFontFace = false, 6133 ignoreErrors = false, 6134 inspectFont = null 6135 }) { 6136 this.compiledGlyphs = Object.create(null); 6137 for (const i in translatedData) { 6138 this[i] = translatedData[i]; 6139 } 6140 this.isEvalSupported = isEvalSupported !== false; 6141 this.disableFontFace = disableFontFace === true; 6142 this.ignoreErrors = ignoreErrors === true; 6143 this._inspectFont = inspectFont; 6144 } 6145 createNativeFontFace() { 6146 if (!this.data || this.disableFontFace) { 6147 return null; 6148 } 6149 let nativeFontFace; 6150 if (!this.cssFontInfo) { 6151 nativeFontFace = new FontFace(this.loadedName, this.data, {}); 6152 } else { 6153 const css = { 6154 weight: this.cssFontInfo.fontWeight 6155 }; 6156 if (this.cssFontInfo.italicAngle) { 6157 css.style = `oblique ${this.cssFontInfo.italicAngle}deg`; 6158 } 6159 nativeFontFace = new FontFace(this.cssFontInfo.fontFamily, this.data, css); 6160 } 6161 this._inspectFont?.(this); 6162 return nativeFontFace; 6163 } 6164 createFontFaceRule() { 6165 if (!this.data || this.disableFontFace) { 6166 return null; 6167 } 6168 const data = (0, _util.bytesToString)(this.data); 6169 const url = `url(data:${this.mimetype};base64,${btoa(data)});`; 6170 let rule; 6171 if (!this.cssFontInfo) { 6172 rule = `@font-face {font-family:"${this.loadedName}";src:${url}}`; 6173 } else { 6174 let css = `font-weight: ${this.cssFontInfo.fontWeight};`; 6175 if (this.cssFontInfo.italicAngle) { 6176 css += `font-style: oblique ${this.cssFontInfo.italicAngle}deg;`; 6177 } 6178 rule = `@font-face {font-family:"${this.cssFontInfo.fontFamily}";${css}src:${url}}`; 6179 } 6180 this._inspectFont?.(this, url); 6181 return rule; 6182 } 6183 getPathGenerator(objs, character) { 6184 if (this.compiledGlyphs[character] !== undefined) { 6185 return this.compiledGlyphs[character]; 6186 } 6187 let cmds; 6188 try { 6189 cmds = objs.get(this.loadedName + "_path_" + character); 6190 } catch (ex) { 6191 if (!this.ignoreErrors) { 6192 throw ex; 6193 } 6194 (0, _util.warn)(`getPathGenerator - ignoring character: "${ex}".`); 6195 return this.compiledGlyphs[character] = function (c, size) {}; 6196 } 6197 if (this.isEvalSupported && _util.FeatureTest.isEvalSupported) { 6198 const jsBuf = []; 6199 for (const current of cmds) { 6200 const args = current.args !== undefined ? current.args.join(",") : ""; 6201 jsBuf.push("c.", current.cmd, "(", args, ");\n"); 6202 } 6203 return this.compiledGlyphs[character] = new Function("c", "size", jsBuf.join("")); 6204 } 6205 return this.compiledGlyphs[character] = function (c, size) { 6206 for (const current of cmds) { 6207 if (current.cmd === "scale") { 6208 current.args = [size, -size]; 6209 } 6210 c[current.cmd].apply(c, current.args); 6211 } 6212 }; 6213 } 6214} 6215exports.FontFaceObject = FontFaceObject; 6216 6217/***/ }), 6218/* 10 */ 6219/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 6220 6221 6222 6223Object.defineProperty(exports, "__esModule", ({ 6224 value: true 6225})); 6226exports.NodeStandardFontDataFactory = exports.NodeFilterFactory = exports.NodeCanvasFactory = exports.NodeCMapReaderFactory = void 0; 6227var _base_factory = __w_pdfjs_require__(7); 6228var _util = __w_pdfjs_require__(1); 6229; 6230; 6231const fetchData = function (url) { 6232 return new Promise((resolve, reject) => { 6233 const fs = require("fs"); 6234 fs.readFile(url, (error, data) => { 6235 if (error || !data) { 6236 reject(new Error(error)); 6237 return; 6238 } 6239 resolve(new Uint8Array(data)); 6240 }); 6241 }); 6242}; 6243class NodeFilterFactory extends _base_factory.BaseFilterFactory {}
6244exports.NodeFilterFactory = NodeFilterFactory; 6245class NodeCanvasFactory extends _base_factory.BaseCanvasFactory { 6246 _createCanvas(width, height) { 6247 const Canvas = require("canvas"); 6248 return Canvas.createCanvas(width, height); 6249 } 6250} 6251exports.NodeCanvasFactory = NodeCanvasFactory; 6252class NodeCMapReaderFactory extends _base_factory.BaseCMapReaderFactory { 6253 _fetchData(url, compressionType) { 6254 return fetchData(url).then(data => { 6255 return { 6256 cMapData: data, 6257 compressionType 6258 }; 6259 }); 6260 } 6261} 6262exports.NodeCMapReaderFactory = NodeCMapReaderFactory; 6263class NodeStandardFontDataFactory extends _base_factory.BaseStandardFontDataFactory { 6264 _fetchData(url) { 6265 return fetchData(url); 6266 } 6267} 6268exports.NodeStandardFontDataFactory = NodeStandardFontDataFactory; 6269 6270/***/ }), 6271/* 11 */ 6272/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 6273 6274 6275 6276Object.defineProperty(exports, "__esModule", ({ 6277 value: true 6278})); 6279exports.CanvasGraphics = void 0; 6280var _util = __w_pdfjs_require__(1); 6281var _display_utils = __w_pdfjs_require__(6); 6282var _pattern_helper = __w_pdfjs_require__(12); 6283var _image_utils = __w_pdfjs_require__(13); 6284const MIN_FONT_SIZE = 16; 6285const MAX_FONT_SIZE = 100; 6286const MAX_GROUP_SIZE = 4096; 6287const EXECUTION_TIME = 15; 6288const EXECUTION_STEPS = 10; 6289const MAX_SIZE_TO_COMPILE = 1000; 6290const FULL_CHUNK_HEIGHT = 16; 6291function mirrorContextOperations(ctx, destCtx) { 6292 if (ctx._removeMirroring) { 6293 throw new Error("Context is already forwarding operations."); 6294 } 6295 ctx.__originalSave = ctx.save; 6296 ctx.__originalRestore = ctx.restore; 6297 ctx.__originalRotate = ctx.rotate; 6298 ctx.__originalScale = ctx.scale; 6299 ctx.__originalTranslate = ctx.translate; 6300 ctx.__originalTransform = ctx.transform; 6301 ctx.__originalSetTransform = ctx.setTransform; 6302 ctx.__originalResetTransform = ctx.resetTransform; 6303 ctx.__originalClip = ctx.clip; 6304 ctx.__originalMoveTo = ctx.moveTo; 6305 ctx.__originalLineTo = ctx.lineTo; 6306 ctx.__originalBezierCurveTo = ctx.bezierCurveTo; 6307 ctx.__originalRect = ctx.rect; 6308 ctx.__originalClosePath = ctx.closePath; 6309 ctx.__originalBeginPath = ctx.beginPath; 6310 ctx._removeMirroring = () => { 6311 ctx.save = ctx.__originalSave; 6312 ctx.restore = ctx.__originalRestore; 6313 ctx.rotate = ctx.__originalRotate; 6314 ctx.scale = ctx.__originalScale; 6315 ctx.translate = ctx.__originalTranslate; 6316 ctx.transform = ctx.__originalTransform; 6317 ctx.setTransform = ctx.__originalSetTransform; 6318 ctx.resetTransform = ctx.__originalResetTransform; 6319 ctx.clip = ctx.__originalClip; 6320 ctx.moveTo = ctx.__originalMoveTo; 6321 ctx.lineTo = ctx.__originalLineTo; 6322 ctx.bezierCurveTo = ctx.__originalBezierCurveTo; 6323 ctx.rect = ctx.__originalRect; 6324 ctx.closePath = ctx.__originalClosePath; 6325 ctx.beginPath = ctx.__originalBeginPath; 6326 delete ctx._removeMirroring; 6327 }; 6328 ctx.save = function ctxSave() { 6329 destCtx.save(); 6330 this.__originalSave(); 6331 }; 6332 ctx.restore = function ctxRestore() { 6333 destCtx.restore(); 6334 this.__originalRestore(); 6335 }; 6336 ctx.translate = function ctxTranslate(x, y) { 6337 destCtx.translate(x, y); 6338 this.__originalTranslate(x, y); 6339 }; 6340 ctx.scale = function ctxScale(x, y) { 6341 destCtx.scale(x, y); 6342 this.__originalScale(x, y); 6343 }; 6344 ctx.transform = function ctxTransform(a, b, c, d, e, f) { 6345 destCtx.transform(a, b, c, d, e, f); 6346 this.__originalTransform(a, b, c, d, e, f); 6347 }; 6348 ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) { 6349 destCtx.setTransform(a, b, c, d, e, f); 6350 this.__originalSetTransform(a, b, c, d, e, f); 6351 }; 6352 ctx.resetTransform = function ctxResetTransform() { 6353 destCtx.resetTransform(); 6354 this.__originalResetTransform(); 6355 }; 6356 ctx.rotate = function ctxRotate(angle) { 6357 destCtx.rotate(angle); 6358 this.__originalRotate(angle); 6359 }; 6360 ctx.clip = function ctxRotate(rule) { 6361 destCtx.clip(rule); 6362 this.__originalClip(rule); 6363 }; 6364 ctx.moveTo = function (x, y) { 6365 destCtx.moveTo(x, y); 6366 this.__originalMoveTo(x, y); 6367 }; 6368 ctx.lineTo = function (x, y) { 6369 destCtx.lineTo(x, y); 6370 this.__originalLineTo(x, y); 6371 }; 6372 ctx.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) { 6373 destCtx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); 6374 this.__originalBezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); 6375 }; 6376 ctx.rect = function (x, y, width, height) { 6377 destCtx.rect(x, y, width, height); 6378 this.__originalRect(x, y, width, height); 6379 }; 6380 ctx.closePath = function () { 6381 destCtx.closePath(); 6382 this.__originalClosePath(); 6383 }; 6384 ctx.beginPath = function () { 6385 destCtx.beginPath(); 6386 this.__originalBeginPath(); 6387 }; 6388} 6389class CachedCanvases { 6390 constructor(canvasFactory) { 6391 this.canvasFactory = canvasFactory; 6392 this.cache = Object.create(null); 6393 } 6394 getCanvas(id, width, height) {
6395 let canvasEntry; 6396 if (this.cache[id] !== undefined) { 6397 canvasEntry = this.cache[id]; 6398 this.canvasFactory.reset(canvasEntry, width, height); 6399 } else { 6400 canvasEntry = this.canvasFactory.create(width, height); 6401 this.cache[id] = canvasEntry; 6402 } 6403 return canvasEntry; 6404 } 6405 delete(id) { 6406 delete this.cache[id]; 6407 } 6408 clear() { 6409 for (const id in this.cache) { 6410 const canvasEntry = this.cache[id]; 6411 this.canvasFactory.destroy(canvasEntry); 6412 delete this.cache[id]; 6413 } 6414 } 6415} 6416function drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH) { 6417 const [a, b, c, d, tx, ty] = (0, _display_utils.getCurrentTransform)(ctx); 6418 if (b === 0 && c === 0) { 6419 const tlX = destX * a + tx; 6420 const rTlX = Math.round(tlX); 6421 const tlY = destY * d + ty; 6422 const rTlY = Math.round(tlY); 6423 const brX = (destX + destW) * a + tx; 6424 const rWidth = Math.abs(Math.round(brX) - rTlX) || 1; 6425 const brY = (destY + destH) * d + ty; 6426 const rHeight = Math.abs(Math.round(brY) - rTlY) || 1; 6427 ctx.setTransform(Math.sign(a), 0, 0, Math.sign(d), rTlX, rTlY); 6428 ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rWidth, rHeight); 6429 ctx.setTransform(a, b, c, d, tx, ty); 6430 return [rWidth, rHeight]; 6431 } 6432 if (a === 0 && d === 0) { 6433 const tlX = destY * c + tx; 6434 const rTlX = Math.round(tlX); 6435 const tlY = destX * b + ty; 6436 const rTlY = Math.round(tlY); 6437 const brX = (destY + destH) * c + tx; 6438 const rWidth = Math.abs(Math.round(brX) - rTlX) || 1; 6439 const brY = (destX + destW) * b + ty; 6440 const rHeight = Math.abs(Math.round(brY) - rTlY) || 1; 6441 ctx.setTransform(0, Math.sign(b), Math.sign(c), 0, rTlX, rTlY); 6442 ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rHeight, rWidth); 6443 ctx.setTransform(a, b, c, d, tx, ty); 6444 return [rHeight, rWidth]; 6445 } 6446 ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH); 6447 const scaleX = Math.hypot(a, b); 6448 const scaleY = Math.hypot(c, d); 6449 return [scaleX * destW, scaleY * destH]; 6450} 6451function compileType3Glyph(imgData) { 6452 const { 6453 width, 6454 height 6455 } = imgData; 6456 if (width > MAX_SIZE_TO_COMPILE || height > MAX_SIZE_TO_COMPILE) { 6457 return null; 6458 } 6459 const POINT_TO_PROCESS_LIMIT = 1000; 6460 const POINT_TYPES = new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]); 6461 const width1 = width + 1; 6462 let points = new Uint8Array(width1 * (height + 1)); 6463 let i, j, j0; 6464 const lineSize = width + 7 & ~7; 6465 let data = new Uint8Array(lineSize * height), 6466 pos = 0; 6467 for (const elem of imgData.data) { 6468 let mask = 128; 6469 while (mask > 0) { 6470 data[pos++] = elem & mask ? 0 : 255; 6471 mask >>= 1; 6472 } 6473 } 6474 let count = 0; 6475 pos = 0; 6476 if (data[pos] !== 0) { 6477 points[0] = 1; 6478 ++count; 6479 } 6480 for (j = 1; j < width; j++) { 6481 if (data[pos] !== data[pos + 1]) { 6482 points[j] = data[pos] ? 2 : 1; 6483 ++count; 6484 } 6485 pos++; 6486 } 6487 if (data[pos] !== 0) { 6488 points[j] = 2; 6489 ++count; 6490 } 6491 for (i = 1; i < height; i++) { 6492 pos = i * lineSize; 6493 j0 = i * width1; 6494 if (data[pos - lineSize] !== data[pos]) { 6495 points[j0] = data[pos] ? 1 : 8; 6496 ++count; 6497 } 6498 let sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0); 6499 for (j = 1; j < width; j++) { 6500 sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + (data[pos - lineSize + 1] ? 8 : 0); 6501 if (POINT_TYPES[sum]) { 6502 points[j0 + j] = POINT_TYPES[sum]; 6503 ++count; 6504 } 6505 pos++; 6506 } 6507 if (data[pos - lineSize] !== data[pos]) { 6508 points[j0 + j] = data[pos] ? 2 : 4; 6509 ++count; 6510 } 6511 if (count > POINT_TO_PROCESS_LIMIT) { 6512 return null; 6513 } 6514 } 6515 pos = lineSize * (height - 1); 6516 j0 = i * width1; 6517 if (data[pos] !== 0) { 6518 points[j0] = 8; 6519 ++count; 6520 } 6521 for (j = 1; j < width; j++) { 6522 if (data[pos] !== data[pos + 1]) { 6523 points[j0 + j] = data[pos] ? 4 : 8; 6524 ++count; 6525 } 6526 pos++; 6527 } 6528 if (data[pos] !== 0) { 6529 points[j0 + j] = 4; 6530 ++count; 6531 } 6532 if (count > POINT_TO_PROCESS_LIMIT) { 6533 return null; 6534 } 6535 const steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]); 6536 const path = new Path2D(); 6537 for (i = 0; count && i <= height; i++) { 6538 let p = i * width1; 6539 const end = p + width; 6540 while (p < end && !points[p]) { 6541 p++; 6542 } 6543 if (p === end) { 6544 continue; 6545 } 6546 path.moveTo(p % width1, i); 6547 const p0 = p; 6548 let type = points[p]; 6549 do { 6550 const step = steps[type]; 6551 do { 6552 p += step; 6553 } while (!points[p]); 6554 const pp = points[p]; 6555 if (pp !== 5 && pp !== 10) { 6556 type = pp; 6557 points[p] = 0; 6558 } else { 6559 type = pp & 0x33 * type >> 4; 6560 points[p] &= type >> 2 | type << 2; 6561 } 6562 path.lineTo(p % width1, p / width1 | 0); 6563 if (!points[p]) { 6564 --count; 6565 } 6566 } while (p0 !== p); 6567 --i; 6568 } 6569 data = null; 6570 points = null; 6571 const drawOutline = function (c) { 6572 c.save(); 6573 c.scale(1 / width, -1 / height); 6574 c.translate(0, -height); 6575 c.fill(path); 6576 c.beginPath();
6577 c.restore(); 6578 }; 6579 return drawOutline; 6580} 6581class CanvasExtraState { 6582 constructor(width, height) { 6583 this.alphaIsShape = false; 6584 this.fontSize = 0; 6585 this.fontSizeScale = 1; 6586 this.textMatrix = _util.IDENTITY_MATRIX; 6587 this.textMatrixScale = 1; 6588 this.fontMatrix = _util.FONT_IDENTITY_MATRIX; 6589 this.leading = 0; 6590 this.x = 0; 6591 this.y = 0; 6592 this.lineX = 0; 6593 this.lineY = 0; 6594 this.charSpacing = 0; 6595 this.wordSpacing = 0; 6596 this.textHScale = 1; 6597 this.textRenderingMode = _util.TextRenderingMode.FILL; 6598 this.textRise = 0; 6599 this.fillColor = "#000000"; 6600 this.strokeColor = "#000000"; 6601 this.patternFill = false; 6602 this.fillAlpha = 1; 6603 this.strokeAlpha = 1; 6604 this.lineWidth = 1; 6605 this.activeSMask = null; 6606 this.transferMaps = "none"; 6607 this.startNewPathAndClipBox([0, 0, width, height]); 6608 } 6609 clone() { 6610 const clone = Object.create(this); 6611 clone.clipBox = this.clipBox.slice(); 6612 return clone; 6613 } 6614 setCurrentPoint(x, y) { 6615 this.x = x; 6616 this.y = y; 6617 } 6618 updatePathMinMax(transform, x, y) { 6619 [x, y] = _util.Util.applyTransform([x, y], transform); 6620 this.minX = Math.min(this.minX, x); 6621 this.minY = Math.min(this.minY, y); 6622 this.maxX = Math.max(this.maxX, x); 6623 this.maxY = Math.max(this.maxY, y); 6624 } 6625 updateRectMinMax(transform, rect) { 6626 const p1 = _util.Util.applyTransform(rect, transform); 6627 const p2 = _util.Util.applyTransform(rect.slice(2), transform); 6628 this.minX = Math.min(this.minX, p1[0], p2[0]); 6629 this.minY = Math.min(this.minY, p1[1], p2[1]); 6630 this.maxX = Math.max(this.maxX, p1[0], p2[0]); 6631 this.maxY = Math.max(this.maxY, p1[1], p2[1]); 6632 } 6633 updateScalingPathMinMax(transform, minMax) { 6634 _util.Util.scaleMinMax(transform, minMax); 6635 this.minX = Math.min(this.minX, minMax[0]); 6636 this.maxX = Math.max(this.maxX, minMax[1]); 6637 this.minY = Math.min(this.minY, minMax[2]); 6638 this.maxY = Math.max(this.maxY, minMax[3]); 6639 } 6640 updateCurvePathMinMax(transform, x0, y0, x1, y1, x2, y2, x3, y3, minMax) { 6641 const box = _util.Util.bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3); 6642 if (minMax) { 6643 minMax[0] = Math.min(minMax[0], box[0], box[2]); 6644 minMax[1] = Math.max(minMax[1], box[0], box[2]); 6645 minMax[2] = Math.min(minMax[2], box[1], box[3]); 6646 minMax[3] = Math.max(minMax[3], box[1], box[3]); 6647 return; 6648 } 6649 this.updateRectMinMax(transform, box); 6650 } 6651 getPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) { 6652 const box = [this.minX, this.minY, this.maxX, this.maxY]; 6653 if (pathType === _pattern_helper.PathType.STROKE) { 6654 if (!transform) { 6655 (0, _util.unreachable)("Stroke bounding box must include transform."); 6656 } 6657 const scale = _util.Util.singularValueDecompose2dScale(transform); 6658 const xStrokePad = scale[0] * this.lineWidth / 2; 6659 const yStrokePad = scale[1] * this.lineWidth / 2; 6660 box[0] -= xStrokePad; 6661 box[1] -= yStrokePad; 6662 box[2] += xStrokePad; 6663 box[3] += yStrokePad; 6664 } 6665 return box; 6666 } 6667 updateClipFromPath() { 6668 const intersect = _util.Util.intersect(this.clipBox, this.getPathBoundingBox()); 6669 this.startNewPathAndClipBox(intersect || [0, 0, 0, 0]); 6670 } 6671 isEmptyClip() { 6672 return this.minX === Infinity; 6673 } 6674 startNewPathAndClipBox(box) { 6675 this.clipBox = box; 6676 this.minX = Infinity; 6677 this.minY = Infinity; 6678 this.maxX = 0; 6679 this.maxY = 0; 6680 } 6681 getClippedPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) { 6682 return _util.Util.intersect(this.clipBox, this.getPathBoundingBox(pathType, transform)); 6683 } 6684} 6685function putBinaryImageData(ctx, imgData) { 6686 if (typeof ImageData !== "undefined" && imgData instanceof ImageData) { 6687 ctx.putImageData(imgData, 0, 0); 6688 return; 6689 } 6690 const height = imgData.height, 6691 width = imgData.width; 6692 const partialChunkHeight = height % FULL_CHUNK_HEIGHT; 6693 const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; 6694 const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; 6695 const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); 6696 let srcPos = 0, 6697 destPos; 6698 const src = imgData.data; 6699 const dest = chunkImgData.data; 6700 let i, j, thisChunkHeight, elemsInThisChunk; 6701 if (imgData.kind === _util.ImageKind.GRAYSCALE_1BPP) { 6702 const srcLength = src.byteLength; 6703 const dest32 = new Uint32Array(dest.buffer, 0, dest.byteLength >> 2); 6704 const dest32DataLength = dest32.length; 6705 const fullSrcDiff = width + 7 >> 3; 6706 const white = 0xffffffff; 6707 const black = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; 6708 for (i = 0; i < totalChunks; i++) { 6709 thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight; 6710 destPos = 0; 6711 for (j = 0; j < thisChunkHeight; j++) { 6712 const srcDiff = srcLength - srcPos; 6713 let k = 0;
6714 const kEnd = srcDiff > fullSrcDiff ? width : srcDiff * 8 - 7; 6715 const kEndUnrolled = kEnd & ~7; 6716 let mask = 0; 6717 let srcByte = 0; 6718 for (; k < kEndUnrolled; k += 8) { 6719 srcByte = src[srcPos++]; 6720 dest32[destPos++] = srcByte & 128 ? white : black; 6721 dest32[destPos++] = srcByte & 64 ? white : black; 6722 dest32[destPos++] = srcByte & 32 ? white : black; 6723 dest32[destPos++] = srcByte & 16 ? white : black; 6724 dest32[destPos++] = srcByte & 8 ? white : black; 6725 dest32[destPos++] = srcByte & 4 ? white : black; 6726 dest32[destPos++] = srcByte & 2 ? white : black; 6727 dest32[destPos++] = srcByte & 1 ? white : black; 6728 } 6729 for (; k < kEnd; k++) { 6730 if (mask === 0) { 6731 srcByte = src[srcPos++]; 6732 mask = 128; 6733 } 6734 dest32[destPos++] = srcByte & mask ? white : black; 6735 mask >>= 1; 6736 } 6737 } 6738 while (destPos < dest32DataLength) { 6739 dest32[destPos++] = 0; 6740 } 6741 ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 6742 } 6743 } else if (imgData.kind === _util.ImageKind.RGBA_32BPP) { 6744 j = 0; 6745 elemsInThisChunk = width * FULL_CHUNK_HEIGHT * 4; 6746 for (i = 0; i < fullChunks; i++) { 6747 dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 6748 srcPos += elemsInThisChunk; 6749 ctx.putImageData(chunkImgData, 0, j); 6750 j += FULL_CHUNK_HEIGHT; 6751 } 6752 if (i < totalChunks) { 6753 elemsInThisChunk = width * partialChunkHeight * 4; 6754 dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 6755 ctx.putImageData(chunkImgData, 0, j); 6756 } 6757 } else if (imgData.kind === _util.ImageKind.RGB_24BPP) { 6758 thisChunkHeight = FULL_CHUNK_HEIGHT; 6759 elemsInThisChunk = width * thisChunkHeight; 6760 for (i = 0; i < totalChunks; i++) { 6761 if (i >= fullChunks) { 6762 thisChunkHeight = partialChunkHeight; 6763 elemsInThisChunk = width * thisChunkHeight; 6764 } 6765 destPos = 0; 6766 for (j = elemsInThisChunk; j--;) { 6767 dest[destPos++] = src[srcPos++]; 6768 dest[destPos++] = src[srcPos++]; 6769 dest[destPos++] = src[srcPos++]; 6770 dest[destPos++] = 255; 6771 } 6772 ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 6773 } 6774 } else { 6775 throw new Error(`bad image kind: ${imgData.kind}`); 6776 } 6777} 6778function putBinaryImageMask(ctx, imgData) { 6779 if (imgData.bitmap) { 6780 ctx.drawImage(imgData.bitmap, 0, 0); 6781 return; 6782 } 6783 const height = imgData.height, 6784 width = imgData.width; 6785 const partialChunkHeight = height % FULL_CHUNK_HEIGHT; 6786 const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; 6787 const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; 6788 const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); 6789 let srcPos = 0; 6790 const src = imgData.data; 6791 const dest = chunkImgData.data; 6792 for (let i = 0; i < totalChunks; i++) { 6793 const thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight; 6794 ({ 6795 srcPos 6796 } = (0, _image_utils.convertBlackAndWhiteToRGBA)({ 6797 src, 6798 srcPos, 6799 dest, 6800 width, 6801 height: thisChunkHeight, 6802 nonBlackColor: 0 6803 })); 6804 ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 6805 } 6806} 6807function copyCtxState(sourceCtx, destCtx) { 6808 const properties = ["strokeStyle", "fillStyle", "fillRule", "globalAlpha", "lineWidth", "lineCap", "lineJoin", "miterLimit", "globalCompositeOperation", "font", "filter"]; 6809 for (const property of properties) { 6810 if (sourceCtx[property] !== undefined) { 6811 destCtx[property] = sourceCtx[property]; 6812 } 6813 } 6814 if (sourceCtx.setLineDash !== undefined) { 6815 destCtx.setLineDash(sourceCtx.getLineDash()); 6816 destCtx.lineDashOffset = sourceCtx.lineDashOffset; 6817 } 6818} 6819function resetCtxToDefault(ctx) { 6820 ctx.strokeStyle = ctx.fillStyle = "#000000"; 6821 ctx.fillRule = "nonzero"; 6822 ctx.globalAlpha = 1; 6823 ctx.lineWidth = 1; 6824 ctx.lineCap = "butt"; 6825 ctx.lineJoin = "miter"; 6826 ctx.miterLimit = 10; 6827 ctx.globalCompositeOperation = "source-over"; 6828 ctx.font = "10px sans-serif"; 6829 if (ctx.setLineDash !== undefined) { 6830 ctx.setLineDash([]); 6831 ctx.lineDashOffset = 0; 6832 } 6833 if (!_util.isNodeJS) { 6834 const { 6835 filter 6836 } = ctx; 6837 if (filter !== "none" && filter !== "") { 6838 ctx.filter = "none"; 6839 } 6840 } 6841} 6842function composeSMaskBackdrop(bytes, r0, g0, b0) { 6843 const length = bytes.length; 6844 for (let i = 3; i < length; i += 4) {
6845 const alpha = bytes[i]; 6846 if (alpha === 0) { 6847 bytes[i - 3] = r0; 6848 bytes[i - 2] = g0; 6849 bytes[i - 1] = b0; 6850 } else if (alpha < 255) { 6851 const alpha_ = 255 - alpha; 6852 bytes[i - 3] = bytes[i - 3] * alpha + r0 * alpha_ >> 8; 6853 bytes[i - 2] = bytes[i - 2] * alpha + g0 * alpha_ >> 8; 6854 bytes[i - 1] = bytes[i - 1] * alpha + b0 * alpha_ >> 8; 6855 } 6856 } 6857} 6858function composeSMaskAlpha(maskData, layerData, transferMap) { 6859 const length = maskData.length; 6860 const scale = 1 / 255; 6861 for (let i = 3; i < length; i += 4) { 6862 const alpha = transferMap ? transferMap[maskData[i]] : maskData[i]; 6863 layerData[i] = layerData[i] * alpha * scale | 0; 6864 } 6865} 6866function composeSMaskLuminosity(maskData, layerData, transferMap) { 6867 const length = maskData.length; 6868 for (let i = 3; i < length; i += 4) { 6869 const y = maskData[i - 3] * 77 + maskData[i - 2] * 152 + maskData[i - 1] * 28; 6870 layerData[i] = transferMap ? layerData[i] * transferMap[y >> 8] >> 8 : layerData[i] * y >> 16; 6871 } 6872} 6873function genericComposeSMask(maskCtx, layerCtx, width, height, subtype, backdrop, transferMap, layerOffsetX, layerOffsetY, maskOffsetX, maskOffsetY) { 6874 const hasBackdrop = !!backdrop; 6875 const r0 = hasBackdrop ? backdrop[0] : 0; 6876 const g0 = hasBackdrop ? backdrop[1] : 0; 6877 const b0 = hasBackdrop ? backdrop[2] : 0; 6878 const composeFn = subtype === "Luminosity" ? composeSMaskLuminosity : composeSMaskAlpha; 6879 const PIXELS_TO_PROCESS = 1048576; 6880 const chunkSize = Math.min(height, Math.ceil(PIXELS_TO_PROCESS / width)); 6881 for (let row = 0; row < height; row += chunkSize) { 6882 const chunkHeight = Math.min(chunkSize, height - row); 6883 const maskData = maskCtx.getImageData(layerOffsetX - maskOffsetX, row + (layerOffsetY - maskOffsetY), width, chunkHeight); 6884 const layerData = layerCtx.getImageData(layerOffsetX, row + layerOffsetY, width, chunkHeight); 6885 if (hasBackdrop) { 6886 composeSMaskBackdrop(maskData.data, r0, g0, b0); 6887 } 6888 composeFn(maskData.data, layerData.data, transferMap); 6889 layerCtx.putImageData(layerData, layerOffsetX, row + layerOffsetY); 6890 } 6891} 6892function composeSMask(ctx, smask, layerCtx, layerBox) { 6893 const layerOffsetX = layerBox[0]; 6894 const layerOffsetY = layerBox[1]; 6895 const layerWidth = layerBox[2] - layerOffsetX; 6896 const layerHeight = layerBox[3] - layerOffsetY; 6897 if (layerWidth === 0 || layerHeight === 0) { 6898 return; 6899 } 6900 genericComposeSMask(smask.context, layerCtx, layerWidth, layerHeight, smask.subtype, smask.backdrop, smask.transferMap, layerOffsetX, layerOffsetY, smask.offsetX, smask.offsetY); 6901 ctx.save(); 6902 ctx.globalAlpha = 1; 6903 ctx.globalCompositeOperation = "source-over"; 6904 ctx.setTransform(1, 0, 0, 1, 0, 0); 6905 ctx.drawImage(layerCtx.canvas, 0, 0); 6906 ctx.restore(); 6907} 6908function getImageSmoothingEnabled(transform, interpolate) { 6909 const scale = _util.Util.singularValueDecompose2dScale(transform); 6910 scale[0] = Math.fround(scale[0]); 6911 scale[1] = Math.fround(scale[1]); 6912 const actualScale = Math.fround((globalThis.devicePixelRatio || 1) * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS); 6913 if (interpolate !== undefined) { 6914 return interpolate; 6915 } else if (scale[0] <= actualScale || scale[1] <= actualScale) { 6916 return true; 6917 } 6918 return false; 6919} 6920const LINE_CAP_STYLES = ["butt", "round", "square"]; 6921const LINE_JOIN_STYLES = ["miter", "round", "bevel"]; 6922const NORMAL_CLIP = {}; 6923const EO_CLIP = {}; 6924class CanvasGraphics { 6925 constructor(canvasCtx, commonObjs, objs, canvasFactory, filterFactory, { 6926 optionalContentConfig, 6927 markedContentStack = null 6928 }, annotationCanvasMap, pageColors) { 6929 this.ctx = canvasCtx; 6930 this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height); 6931 this.stateStack = []; 6932 this.pendingClip = null; 6933 this.pendingEOFill = false; 6934 this.res = null; 6935 this.xobjs = null; 6936 this.commonObjs = commonObjs; 6937 this.objs = objs; 6938 this.canvasFactory = canvasFactory; 6939 this.filterFactory = filterFactory; 6940 this.groupStack = []; 6941 this.processingType3 = null; 6942 this.baseTransform = null; 6943 this.baseTransformStack = []; 6944 this.groupLevel = 0; 6945 this.smaskStack = []; 6946 this.smaskCounter = 0; 6947 this.tempSMask = null; 6948 this.suspendedCtx = null; 6949 this.contentVisible = true; 6950 this.markedContentStack = markedContentStack || []; 6951 this.optionalContentConfig = optionalContentConfig; 6952 this.cachedCanvases = new CachedCanvases(this.canvasFactory); 6953 this.cachedPatterns = new Map(); 6954 this.annotationCanvasMap = annotationCanvasMap; 6955 this.viewportScale = 1; 6956 this.outputScaleX = 1; 6957 this.outputScaleY = 1;
6958 this.pageColors = pageColors; 6959 this._cachedScaleForStroking = [-1, 0]; 6960 this._cachedGetSinglePixelWidth = null; 6961 this._cachedBitmapsMap = new Map(); 6962 } 6963 getObject(data, fallback = null) { 6964 if (typeof data === "string") { 6965 return data.startsWith("g_") ? this.commonObjs.get(data) : this.objs.get(data); 6966 } 6967 return fallback; 6968 } 6969 beginDrawing({ 6970 transform, 6971 viewport, 6972 transparency = false, 6973 background = null 6974 }) { 6975 const width = this.ctx.canvas.width; 6976 const height = this.ctx.canvas.height; 6977 const savedFillStyle = this.ctx.fillStyle; 6978 this.ctx.fillStyle = background || "#ffffff"; 6979 this.ctx.fillRect(0, 0, width, height); 6980 this.ctx.fillStyle = savedFillStyle; 6981 if (transparency) { 6982 const transparentCanvas = this.cachedCanvases.getCanvas("transparent", width, height); 6983 this.compositeCtx = this.ctx; 6984 this.transparentCanvas = transparentCanvas.canvas; 6985 this.ctx = transparentCanvas.context; 6986 this.ctx.save(); 6987 this.ctx.transform(...(0, _display_utils.getCurrentTransform)(this.compositeCtx)); 6988 } 6989 this.ctx.save(); 6990 resetCtxToDefault(this.ctx); 6991 if (transform) { 6992 this.ctx.transform(...transform); 6993 this.outputScaleX = transform[0]; 6994 this.outputScaleY = transform[0]; 6995 } 6996 this.ctx.transform(...viewport.transform); 6997 this.viewportScale = viewport.scale; 6998 this.baseTransform = (0, _display_utils.getCurrentTransform)(this.ctx); 6999 } 7000 executeOperatorList(operatorList, executionStartIdx, continueCallback, stepper) { 7001 const argsArray = operatorList.argsArray; 7002 const fnArray = operatorList.fnArray; 7003 let i = executionStartIdx || 0; 7004 const argsArrayLen = argsArray.length; 7005 if (argsArrayLen === i) { 7006 return i; 7007 } 7008 const chunkOperations = argsArrayLen - i > EXECUTION_STEPS && typeof continueCallback === "function"; 7009 const endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0; 7010 let steps = 0; 7011 const commonObjs = this.commonObjs; 7012 const objs = this.objs; 7013 let fnId; 7014 while (true) { 7015 if (stepper !== undefined && i === stepper.nextBreakPoint) { 7016 stepper.breakIt(i, continueCallback); 7017 return i; 7018 } 7019 fnId = fnArray[i]; 7020 if (fnId !== _util.OPS.dependency) { 7021 this[fnId].apply(this, argsArray[i]); 7022 } else { 7023 for (const depObjId of argsArray[i]) { 7024 const objsPool = depObjId.startsWith("g_") ? commonObjs : objs; 7025 if (!objsPool.has(depObjId)) { 7026 objsPool.get(depObjId, continueCallback); 7027 return i; 7028 } 7029 } 7030 } 7031 i++; 7032 if (i === argsArrayLen) { 7033 return i; 7034 } 7035 if (chunkOperations && ++steps > EXECUTION_STEPS) { 7036 if (Date.now() > endTime) { 7037 continueCallback(); 7038 return i; 7039 } 7040 steps = 0; 7041 } 7042 } 7043 } 7044 #restoreInitialState() { 7045 while (this.stateStack.length || this.inSMaskMode) { 7046 this.restore(); 7047 } 7048 this.ctx.restore(); 7049 if (this.transparentCanvas) { 7050 this.ctx = this.compositeCtx; 7051 this.ctx.save(); 7052 this.ctx.setTransform(1, 0, 0, 1, 0, 0); 7053 this.ctx.drawImage(this.transparentCanvas, 0, 0); 7054 this.ctx.restore(); 7055 this.transparentCanvas = null; 7056 } 7057 } 7058 endDrawing() { 7059 this.#restoreInitialState(); 7060 this.cachedCanvases.clear(); 7061 this.cachedPatterns.clear(); 7062 for (const cache of this._cachedBitmapsMap.values()) { 7063 for (const canvas of cache.values()) { 7064 if (typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) { 7065 canvas.width = canvas.height = 0; 7066 } 7067 } 7068 cache.clear(); 7069 } 7070 this._cachedBitmapsMap.clear(); 7071 this.#drawFilter(); 7072 } 7073 #drawFilter() { 7074 if (this.pageColors) { 7075 const hcmFilterId = this.filterFactory.addHCMFilter(this.pageColors.foreground, this.pageColors.background); 7076 if (hcmFilterId !== "none") { 7077 const savedFilter = this.ctx.filter; 7078 this.ctx.filter = hcmFilterId; 7079 this.ctx.drawImage(this.ctx.canvas, 0, 0); 7080 this.ctx.filter = savedFilter; 7081 } 7082 } 7083 } 7084 _scaleImage(img, inverseTransform) { 7085 const width = img.width;
7086 const height = img.height; 7087 let widthScale = Math.max(Math.hypot(inverseTransform[0], inverseTransform[1]), 1); 7088 let heightScale = Math.max(Math.hypot(inverseTransform[2], inverseTransform[3]), 1); 7089 let paintWidth = width, 7090 paintHeight = height; 7091 let tmpCanvasId = "prescale1"; 7092 let tmpCanvas, tmpCtx; 7093 while (widthScale > 2 && paintWidth > 1 || heightScale > 2 && paintHeight > 1) { 7094 let newWidth = paintWidth, 7095 newHeight = paintHeight; 7096 if (widthScale > 2 && paintWidth > 1) { 7097 newWidth = paintWidth >= 16384 ? Math.floor(paintWidth / 2) - 1 || 1 : Math.ceil(paintWidth / 2); 7098 widthScale /= paintWidth / newWidth; 7099 } 7100 if (heightScale > 2 && paintHeight > 1) { 7101 newHeight = paintHeight >= 16384 ? Math.floor(paintHeight / 2) - 1 || 1 : Math.ceil(paintHeight) / 2; 7102 heightScale /= paintHeight / newHeight; 7103 } 7104 tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight); 7105 tmpCtx = tmpCanvas.context; 7106 tmpCtx.clearRect(0, 0, newWidth, newHeight); 7107 tmpCtx.drawImage(img, 0, 0, paintWidth, paintHeight, 0, 0, newWidth, newHeight); 7108 img = tmpCanvas.canvas; 7109 paintWidth = newWidth; 7110 paintHeight = newHeight; 7111 tmpCanvasId = tmpCanvasId === "prescale1" ? "prescale2" : "prescale1"; 7112 } 7113 return { 7114 img, 7115 paintWidth, 7116 paintHeight 7117 }; 7118 } 7119 _createMaskCanvas(img) { 7120 const ctx = this.ctx; 7121 const { 7122 width, 7123 height 7124 } = img; 7125 const fillColor = this.current.fillColor; 7126 const isPatternFill = this.current.patternFill; 7127 const currentTransform = (0, _display_utils.getCurrentTransform)(ctx); 7128 let cache, cacheKey, scaled, maskCanvas; 7129 if ((img.bitmap || img.data) && img.count > 1) { 7130 const mainKey = img.bitmap || img.data.buffer; 7131 cacheKey = JSON.stringify(isPatternFill ? currentTransform : [currentTransform.slice(0, 4), fillColor]); 7132 cache = this._cachedBitmapsMap.get(mainKey); 7133 if (!cache) { 7134 cache = new Map(); 7135 this._cachedBitmapsMap.set(mainKey, cache); 7136 } 7137 const cachedImage = cache.get(cacheKey); 7138 if (cachedImage && !isPatternFill) { 7139 const offsetX = Math.round(Math.min(currentTransform[0], currentTransform[2]) + currentTransform[4]); 7140 const offsetY = Math.round(Math.min(currentTransform[1], currentTransform[3]) + currentTransform[5]); 7141 return { 7142 canvas: cachedImage, 7143 offsetX, 7144 offsetY 7145 }; 7146 } 7147 scaled = cachedImage; 7148 } 7149 if (!scaled) { 7150 maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height); 7151 putBinaryImageMask(maskCanvas.context, img); 7152 } 7153 let maskToCanvas = _util.Util.transform(currentTransform, [1 / width, 0, 0, -1 / height, 0, 0]); 7154 maskToCanvas = _util.Util.transform(maskToCanvas, [1, 0, 0, 1, 0, -height]); 7155 const cord1 = _util.Util.applyTransform([0, 0], maskToCanvas); 7156 const cord2 = _util.Util.applyTransform([width, height], maskToCanvas); 7157 const rect = _util.Util.normalizeRect([cord1[0], cord1[1], cord2[0], cord2[1]]); 7158 const drawnWidth = Math.round(rect[2] - rect[0]) || 1; 7159 const drawnHeight = Math.round(rect[3] - rect[1]) || 1; 7160 const fillCanvas = this.cachedCanvases.getCanvas("fillCanvas", drawnWidth, drawnHeight); 7161 const fillCtx = fillCanvas.context; 7162 const offsetX = Math.min(cord1[0], cord2[0]); 7163 const offsetY = Math.min(cord1[1], cord2[1]); 7164 fillCtx.translate(-offsetX, -offsetY); 7165 fillCtx.transform(...maskToCanvas); 7166 if (!scaled) { 7167 scaled = this._scaleImage(maskCanvas.canvas, (0, _display_utils.getCurrentTransformInverse)(fillCtx)); 7168 scaled = scaled.img; 7169 if (cache && isPatternFill) { 7170 cache.set(cacheKey, scaled); 7171 } 7172 } 7173 fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled((0, _display_utils.getCurrentTransform)(fillCtx), img.interpolate); 7174 drawImageAtIntegerCoords(fillCtx, scaled, 0, 0, scaled.width, scaled.height, 0, 0, width, height); 7175 fillCtx.globalCompositeOperation = "source-in"; 7176 const inverse = _util.Util.transform((0, _display_utils.getCurrentTransformInverse)(fillCtx), [1, 0, 0, 1, -offsetX, -offsetY]); 7177 fillCtx.fillStyle = isPatternFill ? fillColor.getPattern(ctx, this, inverse, _pattern_helper.PathType.FILL) : fillColor; 7178 fillCtx.fillRect(0, 0, width, height); 7179 if (cache && !isPatternFill) { 7180 this.cachedCanvases.delete("fillCanvas"); 7181 cache.set(cacheKey, fillCanvas.canvas); 7182 } 7183 return {
7184 canvas: fillCanvas.canvas, 7185 offsetX: Math.round(offsetX), 7186 offsetY: Math.round(offsetY) 7187 }; 7188 } 7189 setLineWidth(width) { 7190 if (width !== this.current.lineWidth) { 7191 this._cachedScaleForStroking[0] = -1; 7192 } 7193 this.current.lineWidth = width; 7194 this.ctx.lineWidth = width; 7195 } 7196 setLineCap(style) { 7197 this.ctx.lineCap = LINE_CAP_STYLES[style]; 7198 } 7199 setLineJoin(style) { 7200 this.ctx.lineJoin = LINE_JOIN_STYLES[style]; 7201 } 7202 setMiterLimit(limit) { 7203 this.ctx.miterLimit = limit; 7204 } 7205 setDash(dashArray, dashPhase) { 7206 const ctx = this.ctx; 7207 if (ctx.setLineDash !== undefined) { 7208 ctx.setLineDash(dashArray); 7209 ctx.lineDashOffset = dashPhase; 7210 } 7211 } 7212 setRenderingIntent(intent) {} 7213 setFlatness(flatness) {} 7214 setGState(states) { 7215 for (const [key, value] of states) { 7216 switch (key) { 7217 case "LW": 7218 this.setLineWidth(value); 7219 break; 7220 case "LC": 7221 this.setLineCap(value); 7222 break; 7223 case "LJ": 7224 this.setLineJoin(value); 7225 break; 7226 case "ML": 7227 this.setMiterLimit(value); 7228 break; 7229 case "D": 7230 this.setDash(value[0], value[1]); 7231 break; 7232 case "RI": 7233 this.setRenderingIntent(value); 7234 break; 7235 case "FL": 7236 this.setFlatness(value); 7237 break; 7238 case "Font": 7239 this.setFont(value[0], value[1]); 7240 break; 7241 case "CA": 7242 this.current.strokeAlpha = value; 7243 break; 7244 case "ca": 7245 this.current.fillAlpha = value; 7246 this.ctx.globalAlpha = value; 7247 break; 7248 case "BM": 7249 this.ctx.globalCompositeOperation = value; 7250 break; 7251 case "SMask": 7252 this.current.activeSMask = value ? this.tempSMask : null; 7253 this.tempSMask = null; 7254 this.checkSMaskState(); 7255 break; 7256 case "TR": 7257 this.ctx.filter = this.current.transferMaps = this.filterFactory.addFilter(value); 7258 break; 7259 } 7260 } 7261 } 7262 get inSMaskMode() { 7263 return !!this.suspendedCtx; 7264 } 7265 checkSMaskState() { 7266 const inSMaskMode = this.inSMaskMode; 7267 if (this.current.activeSMask && !inSMaskMode) { 7268 this.beginSMaskMode(); 7269 } else if (!this.current.activeSMask && inSMaskMode) { 7270 this.endSMaskMode(); 7271 } 7272 } 7273 beginSMaskMode() { 7274 if (this.inSMaskMode) { 7275 throw new Error("beginSMaskMode called while already in smask mode"); 7276 } 7277 const drawnWidth = this.ctx.canvas.width; 7278 const drawnHeight = this.ctx.canvas.height; 7279 const cacheId = "smaskGroupAt" + this.groupLevel; 7280 const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight); 7281 this.suspendedCtx = this.ctx; 7282 this.ctx = scratchCanvas.context; 7283 const ctx = this.ctx; 7284 ctx.setTransform(...(0, _display_utils.getCurrentTransform)(this.suspendedCtx)); 7285 copyCtxState(this.suspendedCtx, ctx); 7286 mirrorContextOperations(ctx, this.suspendedCtx); 7287 this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]); 7288 } 7289 endSMaskMode() { 7290 if (!this.inSMaskMode) { 7291 throw new Error("endSMaskMode called while not in smask mode"); 7292 } 7293 this.ctx._removeMirroring(); 7294 copyCtxState(this.ctx, this.suspendedCtx); 7295 this.ctx = this.suspendedCtx; 7296 this.suspendedCtx = null; 7297 } 7298 compose(dirtyBox) { 7299 if (!this.current.activeSMask) { 7300 return; 7301 } 7302 if (!dirtyBox) { 7303 dirtyBox = [0, 0, this.ctx.canvas.width, this.ctx.canvas.height]; 7304 } else { 7305 dirtyBox[0] = Math.floor(dirtyBox[0]); 7306 dirtyBox[1] = Math.floor(dirtyBox[1]); 7307 dirtyBox[2] = Math.ceil(dirtyBox[2]); 7308 dirtyBox[3] = Math.ceil(dirtyBox[3]); 7309 } 7310 const smask = this.current.activeSMask; 7311 const suspendedCtx = this.suspendedCtx; 7312 composeSMask(suspendedCtx, smask, this.ctx, dirtyBox); 7313 this.ctx.save(); 7314 this.ctx.setTransform(1, 0, 0, 1, 0, 0); 7315 this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height); 7316 this.ctx.restore(); 7317 } 7318 save() { 7319 if (this.inSMaskMode) { 7320 copyCtxState(this.ctx, this.suspendedCtx); 7321 this.suspendedCtx.save(); 7322 } else { 7323 this.ctx.save(); 7324 } 7325 const old = this.current; 7326 this.stateStack.push(old); 7327 this.current = old.clone(); 7328 }
7329 restore() { 7330 if (this.stateStack.length === 0 && this.inSMaskMode) { 7331 this.endSMaskMode(); 7332 } 7333 if (this.stateStack.length !== 0) { 7334 this.current = this.stateStack.pop(); 7335 if (this.inSMaskMode) { 7336 this.suspendedCtx.restore(); 7337 copyCtxState(this.suspendedCtx, this.ctx); 7338 } else { 7339 this.ctx.restore(); 7340 } 7341 this.checkSMaskState(); 7342 this.pendingClip = null; 7343 this._cachedScaleForStroking[0] = -1; 7344 this._cachedGetSinglePixelWidth = null; 7345 } 7346 } 7347 transform(a, b, c, d, e, f) { 7348 this.ctx.transform(a, b, c, d, e, f); 7349 this._cachedScaleForStroking[0] = -1; 7350 this._cachedGetSinglePixelWidth = null; 7351 } 7352 constructPath(ops, args, minMax) { 7353 const ctx = this.ctx; 7354 const current = this.current; 7355 let x = current.x, 7356 y = current.y; 7357 let startX, startY; 7358 const currentTransform = (0, _display_utils.getCurrentTransform)(ctx); 7359 const isScalingMatrix = currentTransform[0] === 0 && currentTransform[3] === 0 || currentTransform[1] === 0 && currentTransform[2] === 0; 7360 const minMaxForBezier = isScalingMatrix ? minMax.slice(0) : null; 7361 for (let i = 0, j = 0, ii = ops.length; i < ii; i++) { 7362 switch (ops[i] | 0) { 7363 case _util.OPS.rectangle: 7364 x = args[j++]; 7365 y = args[j++]; 7366 const width = args[j++]; 7367 const height = args[j++]; 7368 const xw = x + width; 7369 const yh = y + height; 7370 ctx.moveTo(x, y); 7371 if (width === 0 || height === 0) { 7372 ctx.lineTo(xw, yh); 7373 } else { 7374 ctx.lineTo(xw, y); 7375 ctx.lineTo(xw, yh); 7376 ctx.lineTo(x, yh); 7377 } 7378 if (!isScalingMatrix) { 7379 current.updateRectMinMax(currentTransform, [x, y, xw, yh]); 7380 } 7381 ctx.closePath(); 7382 break; 7383 case _util.OPS.moveTo: 7384 x = args[j++]; 7385 y = args[j++]; 7386 ctx.moveTo(x, y); 7387 if (!isScalingMatrix) { 7388 current.updatePathMinMax(currentTransform, x, y); 7389 } 7390 break; 7391 case _util.OPS.lineTo: 7392 x = args[j++]; 7393 y = args[j++]; 7394 ctx.lineTo(x, y); 7395 if (!isScalingMatrix) { 7396 current.updatePathMinMax(currentTransform, x, y); 7397 } 7398 break; 7399 case _util.OPS.curveTo: 7400 startX = x; 7401 startY = y; 7402 x = args[j + 4]; 7403 y = args[j + 5]; 7404 ctx.bezierCurveTo(args[j], args[j + 1], args[j + 2], args[j + 3], x, y); 7405 current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], args[j + 2], args[j + 3], x, y, minMaxForBezier); 7406 j += 6; 7407 break; 7408 case _util.OPS.curveTo2: 7409 startX = x; 7410 startY = y; 7411 ctx.bezierCurveTo(x, y, args[j], args[j + 1], args[j + 2], args[j + 3]); 7412 current.updateCurvePathMinMax(currentTransform, startX, startY, x, y, args[j], args[j + 1], args[j + 2], args[j + 3], minMaxForBezier); 7413 x = args[j + 2]; 7414 y = args[j + 3]; 7415 j += 4; 7416 break; 7417 case _util.OPS.curveTo3: 7418 startX = x; 7419 startY = y; 7420 x = args[j + 2]; 7421 y = args[j + 3]; 7422 ctx.bezierCurveTo(args[j], args[j + 1], x, y, x, y); 7423 current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], x, y, x, y, minMaxForBezier); 7424 j += 4; 7425 break; 7426 case _util.OPS.closePath: 7427 ctx.closePath(); 7428 break; 7429 } 7430 } 7431 if (isScalingMatrix) { 7432 current.updateScalingPathMinMax(currentTransform, minMaxForBezier); 7433 } 7434 current.setCurrentPoint(x, y); 7435 } 7436 closePath() { 7437 this.ctx.closePath(); 7438 }
7439 stroke(consumePath = true) { 7440 const ctx = this.ctx; 7441 const strokeColor = this.current.strokeColor; 7442 ctx.globalAlpha = this.current.strokeAlpha; 7443 if (this.contentVisible) { 7444 if (typeof strokeColor === "object" && strokeColor?.getPattern) { 7445 ctx.save(); 7446 ctx.strokeStyle = strokeColor.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.STROKE); 7447 this.rescaleAndStroke(false); 7448 ctx.restore(); 7449 } else { 7450 this.rescaleAndStroke(true); 7451 } 7452 } 7453 if (consumePath) { 7454 this.consumePath(this.current.getClippedPathBoundingBox()); 7455 } 7456 ctx.globalAlpha = this.current.fillAlpha; 7457 } 7458 closeStroke() { 7459 this.closePath(); 7460 this.stroke(); 7461 } 7462 fill(consumePath = true) { 7463 const ctx = this.ctx; 7464 const fillColor = this.current.fillColor; 7465 const isPatternFill = this.current.patternFill; 7466 let needRestore = false; 7467 if (isPatternFill) { 7468 ctx.save(); 7469 ctx.fillStyle = fillColor.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.FILL); 7470 needRestore = true; 7471 } 7472 const intersect = this.current.getClippedPathBoundingBox(); 7473 if (this.contentVisible && intersect !== null) { 7474 if (this.pendingEOFill) { 7475 ctx.fill("evenodd"); 7476 this.pendingEOFill = false; 7477 } else { 7478 ctx.fill(); 7479 } 7480 } 7481 if (needRestore) { 7482 ctx.restore(); 7483 } 7484 if (consumePath) { 7485 this.consumePath(intersect); 7486 } 7487 } 7488 eoFill() { 7489 this.pendingEOFill = true; 7490 this.fill(); 7491 } 7492 fillStroke() { 7493 this.fill(false); 7494 this.stroke(false); 7495 this.consumePath(); 7496 } 7497 eoFillStroke() { 7498 this.pendingEOFill = true; 7499 this.fillStroke(); 7500 } 7501 closeFillStroke() { 7502 this.closePath(); 7503 this.fillStroke(); 7504 } 7505 closeEOFillStroke() { 7506 this.pendingEOFill = true; 7507 this.closePath(); 7508 this.fillStroke(); 7509 } 7510 endPath() { 7511 this.consumePath(); 7512 } 7513 clip() { 7514 this.pendingClip = NORMAL_CLIP; 7515 } 7516 eoClip() { 7517 this.pendingClip = EO_CLIP; 7518 } 7519 beginText() { 7520 this.current.textMatrix = _util.IDENTITY_MATRIX; 7521 this.current.textMatrixScale = 1; 7522 this.current.x = this.current.lineX = 0; 7523 this.current.y = this.current.lineY = 0; 7524 } 7525 endText() { 7526 const paths = this.pendingTextPaths; 7527 const ctx = this.ctx; 7528 if (paths === undefined) { 7529 ctx.beginPath(); 7530 return; 7531 } 7532 ctx.save(); 7533 ctx.beginPath(); 7534 for (const path of paths) { 7535 ctx.setTransform(...path.transform); 7536 ctx.translate(path.x, path.y); 7537 path.addToPath(ctx, path.fontSize); 7538 } 7539 ctx.restore(); 7540 ctx.clip(); 7541 ctx.beginPath(); 7542 delete this.pendingTextPaths; 7543 } 7544 setCharSpacing(spacing) { 7545 this.current.charSpacing = spacing; 7546 } 7547 setWordSpacing(spacing) { 7548 this.current.wordSpacing = spacing; 7549 } 7550 setHScale(scale) { 7551 this.current.textHScale = scale / 100; 7552 } 7553 setLeading(leading) { 7554 this.current.leading = -leading; 7555 } 7556 setFont(fontRefName, size) { 7557 const fontObj = this.commonObjs.get(fontRefName); 7558 const current = this.current; 7559 if (!fontObj) { 7560 throw new Error(`Can't find font for ${fontRefName}`); 7561 } 7562 current.fontMatrix = fontObj.fontMatrix || _util.FONT_IDENTITY_MATRIX; 7563 if (current.fontMatrix[0] === 0 || current.fontMatrix[3] === 0) { 7564 (0, _util.warn)("Invalid font matrix for font " + fontRefName); 7565 } 7566 if (size < 0) { 7567 size = -size; 7568 current.fontDirection = -1; 7569 } else { 7570 current.fontDirection = 1; 7571 } 7572 this.current.font = fontObj; 7573 this.current.fontSize = size; 7574 if (fontObj.isType3Font) { 7575 return; 7576 } 7577 const name = fontObj.loadedName || "sans-serif"; 7578 const typeface = fontObj.systemFontInfo?.css || `"${name}", ${fontObj.fallbackName}`; 7579 let bold = "normal"; 7580 if (fontObj.black) { 7581 bold = "900"; 7582 } else if (fontObj.bold) { 7583 bold = "bold"; 7584 } 7585 const italic = fontObj.italic ? "italic" : "normal"; 7586 let browserFontSize = size; 7587 if (size < MIN_FONT_SIZE) { 7588 browserFontSize = MIN_FONT_SIZE; 7589 } else if (size > MAX_FONT_SIZE) { 7590 browserFontSize = MAX_FONT_SIZE; 7591 } 7592 this.current.fontSizeScale = size / browserFontSize; 7593 this.ctx.font = `${italic} ${bold} ${browserFontSize}px ${typeface}`; 7594 } 7595 setTextRenderingMode(mode) { 7596 this.current.textRenderingMode = mode; 7597 } 7598 setTextRise(rise) { 7599 this.current.textRise = rise; 7600 } 7601 moveText(x, y) { 7602 this.current.x = this.current.lineX += x; 7603 this.current.y = this.current.lineY += y; 7604 } 7605 setLeadingMoveText(x, y) { 7606 this.setLeading(-y); 7607 this.moveText(x, y); 7608 } 7609 setTextMatrix(a, b, c, d, e, f) { 7610 this.current.textMatrix = [a, b, c, d, e, f]; 7611 this.current.textMatrixScale = Math.hypot(a, b); 7612 this.current.x = this.current.lineX = 0; 7613 this.current.y = this.current.lineY = 0; 7614 } 7615 nextLine() { 7616 this.moveText(0, this.current.leading); 7617 } 7618 paintChar(character, x, y, patternTransform) { 7619 const ctx = this.ctx; 7620 const current = this.current; 7621 const font = current.font; 7622 const textRenderingMode = current.textRenderingMode; 7623 const fontSize = current.fontSize / current.fontSizeScale; 7624 const fillStrokeMode = textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; 7625 const isAddToPathSet = !!(textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG); 7626 const patternFill = current.patternFill && !font.missingFile; 7627 let addToPath; 7628 if (font.disableFontFace || isAddToPathSet || patternFill) { 7629 addToPath = font.getPathGenerator(this.commonObjs, character); 7630 } 7631 if (font.disableFontFace || patternFill) { 7632 ctx.save(); 7633 ctx.translate(x, y); 7634 ctx.beginPath(); 7635 addToPath(ctx, fontSize); 7636 if (patternTransform) { 7637 ctx.setTransform(...patternTransform); 7638 } 7639 if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7640 ctx.fill(); 7641 } 7642 if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7643 ctx.stroke(); 7644 }
7645 ctx.restore(); 7646 } else { 7647 if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7648 ctx.fillText(character, x, y); 7649 } 7650 if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7651 ctx.strokeText(character, x, y); 7652 } 7653 } 7654 if (isAddToPathSet) { 7655 const paths = this.pendingTextPaths ||= []; 7656 paths.push({ 7657 transform: (0, _display_utils.getCurrentTransform)(ctx), 7658 x, 7659 y, 7660 fontSize, 7661 addToPath 7662 }); 7663 } 7664 } 7665 get isFontSubpixelAAEnabled() { 7666 const { 7667 context: ctx 7668 } = this.cachedCanvases.getCanvas("isFontSubpixelAAEnabled", 10, 10); 7669 ctx.scale(1.5, 1); 7670 ctx.fillText("I", 0, 10); 7671 const data = ctx.getImageData(0, 0, 10, 10).data; 7672 let enabled = false; 7673 for (let i = 3; i < data.length; i += 4) { 7674 if (data[i] > 0 && data[i] < 255) { 7675 enabled = true; 7676 break; 7677 } 7678 } 7679 return (0, _util.shadow)(this, "isFontSubpixelAAEnabled", enabled); 7680 } 7681 showText(glyphs) { 7682 const current = this.current; 7683 const font = current.font; 7684 if (font.isType3Font) { 7685 return this.showType3Text(glyphs); 7686 } 7687 const fontSize = current.fontSize; 7688 if (fontSize === 0) { 7689 return undefined; 7690 } 7691 const ctx = this.ctx; 7692 const fontSizeScale = current.fontSizeScale; 7693 const charSpacing = current.charSpacing; 7694 const wordSpacing = current.wordSpacing; 7695 const fontDirection = current.fontDirection; 7696 const textHScale = current.textHScale * fontDirection; 7697 const glyphsLength = glyphs.length; 7698 const vertical = font.vertical; 7699 const spacingDir = vertical ? 1 : -1; 7700 const defaultVMetrics = font.defaultVMetrics; 7701 const widthAdvanceScale = fontSize * current.fontMatrix[0]; 7702 const simpleFillText = current.textRenderingMode === _util.TextRenderingMode.FILL && !font.disableFontFace && !current.patternFill; 7703 ctx.save(); 7704 ctx.transform(...current.textMatrix); 7705 ctx.translate(current.x, current.y + current.textRise); 7706 if (fontDirection > 0) { 7707 ctx.scale(textHScale, -1); 7708 } else { 7709 ctx.scale(textHScale, 1); 7710 } 7711 let patternTransform; 7712 if (current.patternFill) { 7713 ctx.save(); 7714 const pattern = current.fillColor.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.FILL); 7715 patternTransform = (0, _display_utils.getCurrentTransform)(ctx); 7716 ctx.restore(); 7717 ctx.fillStyle = pattern; 7718 } 7719 let lineWidth = current.lineWidth; 7720 const scale = current.textMatrixScale; 7721 if (scale === 0 || lineWidth === 0) { 7722 const fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; 7723 if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7724 lineWidth = this.getSinglePixelWidth(); 7725 } 7726 } else { 7727 lineWidth /= scale; 7728 } 7729 if (fontSizeScale !== 1.0) { 7730 ctx.scale(fontSizeScale, fontSizeScale); 7731 lineWidth /= fontSizeScale; 7732 } 7733 ctx.lineWidth = lineWidth; 7734 if (font.isInvalidPDFjsFont) { 7735 const chars = []; 7736 let width = 0; 7737 for (const glyph of glyphs) { 7738 chars.push(glyph.unicode); 7739 width += glyph.width; 7740 } 7741 ctx.fillText(chars.join(""), 0, 0); 7742 current.x += width * widthAdvanceScale * textHScale; 7743 ctx.restore(); 7744 this.compose(); 7745 return undefined; 7746 } 7747 let x = 0, 7748 i; 7749 for (i = 0; i < glyphsLength; ++i) { 7750 const glyph = glyphs[i];
vendor: 3,295 bytes, lines 7751-7835
7751 if (typeof glyph === "number") { 7752 x += spacingDir * glyph * fontSize / 1000; 7753 continue; 7754 } 7755 let restoreNeeded = false; 7756 const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 7757 const character = glyph.fontChar; 7758 const accent = glyph.accent; 7759 let scaledX, scaledY; 7760 let width = glyph.width; 7761 if (vertical) { 7762 const vmetric = glyph.vmetric || defaultVMetrics; 7763 const vx = -(glyph.vmetric ? vmetric[1] : width * 0.5) * widthAdvanceScale; 7764 const vy = vmetric[2] * widthAdvanceScale; 7765 width = vmetric ? -vmetric[0] : width; 7766 scaledX = vx / fontSizeScale; 7767 scaledY = (x + vy) / fontSizeScale; 7768 } else { 7769 scaledX = x / fontSizeScale; 7770 scaledY = 0; 7771 } 7772 if (font.remeasure && width > 0) { 7773 const measuredWidth = ctx.measureText(character).width * 1000 / fontSize * fontSizeScale; 7774 if (width < measuredWidth && this.isFontSubpixelAAEnabled) { 7775 const characterScaleX = width / measuredWidth; 7776 restoreNeeded = true; 7777 ctx.save(); 7778 ctx.scale(characterScaleX, 1); 7779 scaledX /= characterScaleX; 7780 } else if (width !== measuredWidth) { 7781 scaledX += (width - measuredWidth) / 2000 * fontSize / fontSizeScale; 7782 } 7783 } 7784 if (this.contentVisible && (glyph.isInFont || font.missingFile)) { 7785 if (simpleFillText && !accent) { 7786 ctx.fillText(character, scaledX, scaledY); 7787 } else { 7788 this.paintChar(character, scaledX, scaledY, patternTransform); 7789 if (accent) { 7790 const scaledAccentX = scaledX + fontSize * accent.offset.x / fontSizeScale; 7791 const scaledAccentY = scaledY - fontSize * accent.offset.y / fontSizeScale; 7792 this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY, patternTransform); 7793 } 7794 } 7795 } 7796 const charWidth = vertical ? width * widthAdvanceScale - spacing * fontDirection : width * widthAdvanceScale + spacing * fontDirection; 7797 x += charWidth; 7798 if (restoreNeeded) { 7799 ctx.restore(); 7800 } 7801 } 7802 if (vertical) { 7803 current.y -= x; 7804 } else { 7805 current.x += x * textHScale; 7806 } 7807 ctx.restore(); 7808 this.compose(); 7809 return undefined; 7810 } 7811 showType3Text(glyphs) { 7812 const ctx = this.ctx; 7813 const current = this.current; 7814 const font = current.font; 7815 const fontSize = current.fontSize; 7816 const fontDirection = current.fontDirection; 7817 const spacingDir = font.vertical ? 1 : -1; 7818 const charSpacing = current.charSpacing; 7819 const wordSpacing = current.wordSpacing; 7820 const textHScale = current.textHScale * fontDirection; 7821 const fontMatrix = current.fontMatrix || _util.FONT_IDENTITY_MATRIX; 7822 const glyphsLength = glyphs.length; 7823 const isTextInvisible = current.textRenderingMode === _util.TextRenderingMode.INVISIBLE; 7824 let i, glyph, width, spacingLength; 7825 if (isTextInvisible || fontSize === 0) { 7826 return; 7827 } 7828 this._cachedScaleForStroking[0] = -1; 7829 this._cachedGetSinglePixelWidth = null; 7830 ctx.save(); 7831 ctx.transform(...current.textMatrix); 7832 ctx.translate(current.x, current.y); 7833 ctx.scale(textHScale, fontDirection); 7834 for (i = 0; i < glyphsLength; ++i) { 7835 glyph = glyphs[i];
7836 if (typeof glyph === "number") { 7837 spacingLength = spacingDir * glyph * fontSize / 1000; 7838 this.ctx.translate(spacingLength, 0); 7839 current.x += spacingLength * textHScale; 7840 continue; 7841 } 7842 const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 7843 const operatorList = font.charProcOperatorList[glyph.operatorListId]; 7844 if (!operatorList) { 7845 (0, _util.warn)(`Type3 character "${glyph.operatorListId}" is not available.`); 7846 continue; 7847 } 7848 if (this.contentVisible) { 7849 this.processingType3 = glyph; 7850 this.save(); 7851 ctx.scale(fontSize, fontSize); 7852 ctx.transform(...fontMatrix); 7853 this.executeOperatorList(operatorList); 7854 this.restore(); 7855 } 7856 const transformed = _util.Util.applyTransform([glyph.width, 0], fontMatrix); 7857 width = transformed[0] * fontSize + spacing; 7858 ctx.translate(width, 0); 7859 current.x += width * textHScale; 7860 } 7861 ctx.restore(); 7862 this.processingType3 = null; 7863 } 7864 setCharWidth(xWidth, yWidth) {} 7865 setCharWidthAndBounds(xWidth, yWidth, llx, lly, urx, ury) { 7866 this.ctx.rect(llx, lly, urx - llx, ury - lly); 7867 this.ctx.clip(); 7868 this.endPath(); 7869 } 7870 getColorN_Pattern(IR) { 7871 let pattern; 7872 if (IR[0] === "TilingPattern") { 7873 const color = IR[1]; 7874 const baseTransform = this.baseTransform || (0, _display_utils.getCurrentTransform)(this.ctx); 7875 const canvasGraphicsFactory = { 7876 createCanvasGraphics: ctx => { 7877 return new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory, this.filterFactory, { 7878 optionalContentConfig: this.optionalContentConfig, 7879 markedContentStack: this.markedContentStack 7880 }); 7881 } 7882 }; 7883 pattern = new _pattern_helper.TilingPattern(IR, color, this.ctx, canvasGraphicsFactory, baseTransform); 7884 } else { 7885 pattern = this._getPattern(IR[1], IR[2]); 7886 } 7887 return pattern; 7888 } 7889 setStrokeColorN() { 7890 this.current.strokeColor = this.getColorN_Pattern(arguments); 7891 } 7892 setFillColorN() { 7893 this.current.fillColor = this.getColorN_Pattern(arguments); 7894 this.current.patternFill = true; 7895 } 7896 setStrokeRGBColor(r, g, b) { 7897 const color = _util.Util.makeHexColor(r, g, b); 7898 this.ctx.strokeStyle = color; 7899 this.current.strokeColor = color; 7900 } 7901 setFillRGBColor(r, g, b) { 7902 const color = _util.Util.makeHexColor(r, g, b); 7903 this.ctx.fillStyle = color; 7904 this.current.fillColor = color; 7905 this.current.patternFill = false; 7906 } 7907 _getPattern(objId, matrix = null) { 7908 let pattern; 7909 if (this.cachedPatterns.has(objId)) { 7910 pattern = this.cachedPatterns.get(objId); 7911 } else { 7912 pattern = (0, _pattern_helper.getShadingPattern)(this.getObject(objId)); 7913 this.cachedPatterns.set(objId, pattern); 7914 } 7915 if (matrix) { 7916 pattern.matrix = matrix; 7917 } 7918 return pattern; 7919 } 7920 shadingFill(objId) { 7921 if (!this.contentVisible) { 7922 return; 7923 } 7924 const ctx = this.ctx; 7925 this.save(); 7926 const pattern = this._getPattern(objId); 7927 ctx.fillStyle = pattern.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.SHADING); 7928 const inv = (0, _display_utils.getCurrentTransformInverse)(ctx); 7929 if (inv) { 7930 const { 7931 width, 7932 height 7933 } = ctx.canvas; 7934 const [x0, y0, x1, y1] = _util.Util.getAxialAlignedBoundingBox([0, 0, width, height], inv); 7935 this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0); 7936 } else { 7937 this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10); 7938 } 7939 this.compose(this.current.getClippedPathBoundingBox()); 7940 this.restore(); 7941 } 7942 beginInlineImage() { 7943 (0, _util.unreachable)("Should not call beginInlineImage"); 7944 } 7945 beginImageData() { 7946 (0, _util.unreachable)("Should not call beginImageData"); 7947 } 7948 paintFormXObjectBegin(matrix, bbox) { 7949 if (!this.contentVisible) { 7950 return; 7951 } 7952 this.save(); 7953 this.baseTransformStack.push(this.baseTransform); 7954 if (Array.isArray(matrix) && matrix.length === 6) { 7955 this.transform(...matrix); 7956 } 7957 this.baseTransform = (0, _display_utils.getCurrentTransform)(this.ctx); 7958 if (bbox) { 7959 const width = bbox[2] - bbox[0]; 7960 const height = bbox[3] - bbox[1]; 7961 this.ctx.rect(bbox[0], bbox[1], width, height); 7962 this.current.updateRectMinMax((0, _display_utils.getCurrentTransform)(this.ctx), bbox); 7963 this.clip(); 7964 this.endPath(); 7965 } 7966 } 7967 paintFormXObjectEnd() { 7968 if (!this.contentVisible) { 7969 return; 7970 }
7971 this.restore(); 7972 this.baseTransform = this.baseTransformStack.pop(); 7973 } 7974 beginGroup(group) { 7975 if (!this.contentVisible) { 7976 return; 7977 } 7978 this.save(); 7979 if (this.inSMaskMode) { 7980 this.endSMaskMode(); 7981 this.current.activeSMask = null; 7982 } 7983 const currentCtx = this.ctx; 7984 if (!group.isolated) { 7985 (0, _util.info)("TODO: Support non-isolated groups."); 7986 } 7987 if (group.knockout) { 7988 (0, _util.warn)("Knockout groups not supported."); 7989 } 7990 const currentTransform = (0, _display_utils.getCurrentTransform)(currentCtx); 7991 if (group.matrix) { 7992 currentCtx.transform(...group.matrix); 7993 } 7994 if (!group.bbox) { 7995 throw new Error("Bounding box is required."); 7996 } 7997 let bounds = _util.Util.getAxialAlignedBoundingBox(group.bbox, (0, _display_utils.getCurrentTransform)(currentCtx)); 7998 const canvasBounds = [0, 0, currentCtx.canvas.width, currentCtx.canvas.height]; 7999 bounds = _util.Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0]; 8000 const offsetX = Math.floor(bounds[0]); 8001 const offsetY = Math.floor(bounds[1]); 8002 let drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1); 8003 let drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1); 8004 let scaleX = 1, 8005 scaleY = 1; 8006 if (drawnWidth > MAX_GROUP_SIZE) { 8007 scaleX = drawnWidth / MAX_GROUP_SIZE; 8008 drawnWidth = MAX_GROUP_SIZE; 8009 } 8010 if (drawnHeight > MAX_GROUP_SIZE) { 8011 scaleY = drawnHeight / MAX_GROUP_SIZE; 8012 drawnHeight = MAX_GROUP_SIZE; 8013 } 8014 this.current.startNewPathAndClipBox([0, 0, drawnWidth, drawnHeight]); 8015 let cacheId = "groupAt" + this.groupLevel; 8016 if (group.smask) { 8017 cacheId += "_smask_" + this.smaskCounter++ % 2; 8018 } 8019 const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight); 8020 const groupCtx = scratchCanvas.context; 8021 groupCtx.scale(1 / scaleX, 1 / scaleY); 8022 groupCtx.translate(-offsetX, -offsetY); 8023 groupCtx.transform(...currentTransform); 8024 if (group.smask) { 8025 this.smaskStack.push({ 8026 canvas: scratchCanvas.canvas, 8027 context: groupCtx, 8028 offsetX, 8029 offsetY, 8030 scaleX, 8031 scaleY, 8032 subtype: group.smask.subtype, 8033 backdrop: group.smask.backdrop, 8034 transferMap: group.smask.transferMap || null, 8035 startTransformInverse: null 8036 }); 8037 } else { 8038 currentCtx.setTransform(1, 0, 0, 1, 0, 0); 8039 currentCtx.translate(offsetX, offsetY); 8040 currentCtx.scale(scaleX, scaleY); 8041 currentCtx.save(); 8042 } 8043 copyCtxState(currentCtx, groupCtx); 8044 this.ctx = groupCtx; 8045 this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]); 8046 this.groupStack.push(currentCtx); 8047 this.groupLevel++; 8048 } 8049 endGroup(group) { 8050 if (!this.contentVisible) { 8051 return; 8052 } 8053 this.groupLevel--; 8054 const groupCtx = this.ctx; 8055 const ctx = this.groupStack.pop(); 8056 this.ctx = ctx; 8057 this.ctx.imageSmoothingEnabled = false; 8058 if (group.smask) { 8059 this.tempSMask = this.smaskStack.pop(); 8060 this.restore(); 8061 } else { 8062 this.ctx.restore(); 8063 const currentMtx = (0, _display_utils.getCurrentTransform)(this.ctx); 8064 this.restore(); 8065 this.ctx.save(); 8066 this.ctx.setTransform(...currentMtx); 8067 const dirtyBox = _util.Util.getAxialAlignedBoundingBox([0, 0, groupCtx.canvas.width, groupCtx.canvas.height], currentMtx); 8068 this.ctx.drawImage(groupCtx.canvas, 0, 0); 8069 this.ctx.restore(); 8070 this.compose(dirtyBox); 8071 } 8072 } 8073 beginAnnotation(id, rect, transform, matrix, hasOwnCanvas) { 8074 this.#restoreInitialState(); 8075 resetCtxToDefault(this.ctx); 8076 this.ctx.save(); 8077 this.save(); 8078 if (this.baseTransform) { 8079 this.ctx.setTransform(...this.baseTransform); 8080 } 8081 if (Array.isArray(rect) && rect.length === 4) { 8082 const width = rect[2] - rect[0]; 8083 const height = rect[3] - rect[1]; 8084 if (hasOwnCanvas && this.annotationCanvasMap) { 8085 transform = transform.slice(); 8086 transform[4] -= rect[0]; 8087 transform[5] -= rect[1]; 8088 rect = rect.slice(); 8089 rect[0] = rect[1] = 0; 8090 rect[2] = width; 8091 rect[3] = height; 8092 const [scaleX, scaleY] = _util.Util.singularValueDecompose2dScale((0, _display_utils.getCurrentTransform)(this.ctx)); 8093 const { 8094 viewportScale 8095 } = this; 8096 const canvasWidth = Math.ceil(width * this.outputScaleX * viewportScale);
8097 const canvasHeight = Math.ceil(height * this.outputScaleY * viewportScale); 8098 this.annotationCanvas = this.canvasFactory.create(canvasWidth, canvasHeight); 8099 const { 8100 canvas, 8101 context 8102 } = this.annotationCanvas; 8103 this.annotationCanvasMap.set(id, canvas); 8104 this.annotationCanvas.savedCtx = this.ctx; 8105 this.ctx = context; 8106 this.ctx.save(); 8107 this.ctx.setTransform(scaleX, 0, 0, -scaleY, 0, height * scaleY); 8108 resetCtxToDefault(this.ctx); 8109 } else { 8110 resetCtxToDefault(this.ctx); 8111 this.ctx.rect(rect[0], rect[1], width, height); 8112 this.ctx.clip(); 8113 this.endPath(); 8114 } 8115 } 8116 this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height); 8117 this.transform(...transform); 8118 this.transform(...matrix); 8119 } 8120 endAnnotation() { 8121 if (this.annotationCanvas) { 8122 this.ctx.restore(); 8123 this.#drawFilter(); 8124 this.ctx = this.annotationCanvas.savedCtx; 8125 delete this.annotationCanvas.savedCtx; 8126 delete this.annotationCanvas; 8127 } 8128 } 8129 paintImageMaskXObject(img) { 8130 if (!this.contentVisible) { 8131 return; 8132 } 8133 const count = img.count; 8134 img = this.getObject(img.data, img); 8135 img.count = count; 8136 const ctx = this.ctx; 8137 const glyph = this.processingType3; 8138 if (glyph) { 8139 if (glyph.compiled === undefined) { 8140 glyph.compiled = compileType3Glyph(img); 8141 } 8142 if (glyph.compiled) { 8143 glyph.compiled(ctx); 8144 return; 8145 } 8146 } 8147 const mask = this._createMaskCanvas(img); 8148 const maskCanvas = mask.canvas; 8149 ctx.save(); 8150 ctx.setTransform(1, 0, 0, 1, 0, 0); 8151 ctx.drawImage(maskCanvas, mask.offsetX, mask.offsetY); 8152 ctx.restore(); 8153 this.compose(); 8154 } 8155 paintImageMaskXObjectRepeat(img, scaleX, skewX = 0, skewY = 0, scaleY, positions) { 8156 if (!this.contentVisible) { 8157 return; 8158 } 8159 img = this.getObject(img.data, img); 8160 const ctx = this.ctx; 8161 ctx.save(); 8162 const currentTransform = (0, _display_utils.getCurrentTransform)(ctx); 8163 ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0); 8164 const mask = this._createMaskCanvas(img); 8165 ctx.setTransform(1, 0, 0, 1, mask.offsetX - currentTransform[4], mask.offsetY - currentTransform[5]); 8166 for (let i = 0, ii = positions.length; i < ii; i += 2) { 8167 const trans = _util.Util.transform(currentTransform, [scaleX, skewX, skewY, scaleY, positions[i], positions[i + 1]]); 8168 const [x, y] = _util.Util.applyTransform([0, 0], trans); 8169 ctx.drawImage(mask.canvas, x, y); 8170 } 8171 ctx.restore(); 8172 this.compose(); 8173 } 8174 paintImageMaskXObjectGroup(images) { 8175 if (!this.contentVisible) { 8176 return; 8177 } 8178 const ctx = this.ctx; 8179 const fillColor = this.current.fillColor; 8180 const isPatternFill = this.current.patternFill; 8181 for (const image of images) { 8182 const { 8183 data, 8184 width, 8185 height, 8186 transform 8187 } = image; 8188 const maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height); 8189 const maskCtx = maskCanvas.context; 8190 maskCtx.save(); 8191 const img = this.getObject(data, image); 8192 putBinaryImageMask(maskCtx, img); 8193 maskCtx.globalCompositeOperation = "source-in"; 8194 maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.FILL) : fillColor; 8195 maskCtx.fillRect(0, 0, width, height); 8196 maskCtx.restore(); 8197 ctx.save(); 8198 ctx.transform(...transform); 8199 ctx.scale(1, -1); 8200 drawImageAtIntegerCoords(ctx, maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1); 8201 ctx.restore(); 8202 } 8203 this.compose(); 8204 } 8205 paintImageXObject(objId) { 8206 if (!this.contentVisible) { 8207 return; 8208 } 8209 const imgData = this.getObject(objId); 8210 if (!imgData) { 8211 (0, _util.warn)("Dependent image isn't ready yet"); 8212 return; 8213 } 8214 this.paintInlineImageXObject(imgData); 8215 } 8216 paintImageXObjectRepeat(objId, scaleX, scaleY, positions) { 8217 if (!this.contentVisible) { 8218 return; 8219 } 8220 const imgData = this.getObject(objId); 8221 if (!imgData) { 8222 (0, _util.warn)("Dependent image isn't ready yet"); 8223 return; 8224 } 8225 const width = imgData.width; 8226 const height = imgData.height; 8227 const map = []; 8228 for (let i = 0, ii = positions.length; i < ii; i += 2) { 8229 map.push({ 8230 transform: [scaleX, 0, 0, scaleY, positions[i], positions[i + 1]], 8231 x: 0, 8232 y: 0, 8233 w: width, 8234 h: height 8235 }); 8236 } 8237 this.paintInlineImageXObjectGroup(imgData, map); 8238 } 8239 applyTransferMapsToCanvas(ctx) { 8240 if (this.current.transferMaps !== "none") { 8241 ctx.filter = this.current.transferMaps; 8242 ctx.drawImage(ctx.canvas, 0, 0); 8243 ctx.filter = "none"; 8244 } 8245 return ctx.canvas; 8246 } 8247 applyTransferMapsToBitmap(imgData) { 8248 if (this.current.transferMaps === "none") { 8249 return imgData.bitmap; 8250 } 8251 const { 8252 bitmap, 8253 width, 8254 height 8255 } = imgData; 8256 const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", width, height); 8257 const tmpCtx = tmpCanvas.context; 8258 tmpCtx.filter = this.current.transferMaps; 8259 tmpCtx.drawImage(bitmap, 0, 0); 8260 tmpCtx.filter = "none"; 8261 return tmpCanvas.canvas; 8262 } 8263 paintInlineImageXObject(imgData) { 8264 if (!this.contentVisible) { 8265 return; 8266 } 8267 const width = imgData.width; 8268 const height = imgData.height; 8269 const ctx = this.ctx; 8270 this.save(); 8271 if (!_util.isNodeJS) { 8272 const { 8273 filter 8274 } = ctx; 8275 if (filter !== "none" && filter !== "") { 8276 ctx.filter = "none"; 8277 } 8278 } 8279 ctx.scale(1 / width, -1 / height); 8280 let imgToPaint; 8281 if (imgData.bitmap) { 8282 imgToPaint = this.applyTransferMapsToBitmap(imgData); 8283 } else if (typeof HTMLElement === "function" && imgData instanceof HTMLElement || !imgData.data) { 8284 imgToPaint = imgData; 8285 } else { 8286 const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", width, height); 8287 const tmpCtx = tmpCanvas.context; 8288 putBinaryImageData(tmpCtx, imgData); 8289 imgToPaint = this.applyTransferMapsToCanvas(tmpCtx); 8290 } 8291 const scaled = this._scaleImage(imgToPaint, (0, _display_utils.getCurrentTransformInverse)(ctx)); 8292 ctx.imageSmoothingEnabled = getImageSmoothingEnabled((0, _display_utils.getCurrentTransform)(ctx), imgData.interpolate); 8293 drawImageAtIntegerCoords(ctx, scaled.img, 0, 0, scaled.paintWidth, scaled.paintHeight, 0, -height, width, height); 8294 this.compose();
vendor: 4,375 bytes, lines 8295-8445
8295 this.restore(); 8296 } 8297 paintInlineImageXObjectGroup(imgData, map) { 8298 if (!this.contentVisible) { 8299 return; 8300 } 8301 const ctx = this.ctx; 8302 let imgToPaint; 8303 if (imgData.bitmap) { 8304 imgToPaint = imgData.bitmap; 8305 } else { 8306 const w = imgData.width; 8307 const h = imgData.height; 8308 const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", w, h); 8309 const tmpCtx = tmpCanvas.context; 8310 putBinaryImageData(tmpCtx, imgData); 8311 imgToPaint = this.applyTransferMapsToCanvas(tmpCtx); 8312 } 8313 for (const entry of map) { 8314 ctx.save(); 8315 ctx.transform(...entry.transform); 8316 ctx.scale(1, -1); 8317 drawImageAtIntegerCoords(ctx, imgToPaint, entry.x, entry.y, entry.w, entry.h, 0, -1, 1, 1); 8318 ctx.restore(); 8319 } 8320 this.compose(); 8321 } 8322 paintSolidColorImageMask() { 8323 if (!this.contentVisible) { 8324 return; 8325 } 8326 this.ctx.fillRect(0, 0, 1, 1); 8327 this.compose(); 8328 } 8329 markPoint(tag) {} 8330 markPointProps(tag, properties) {} 8331 beginMarkedContent(tag) { 8332 this.markedContentStack.push({ 8333 visible: true 8334 }); 8335 } 8336 beginMarkedContentProps(tag, properties) { 8337 if (tag === "OC") { 8338 this.markedContentStack.push({ 8339 visible: this.optionalContentConfig.isVisible(properties) 8340 }); 8341 } else { 8342 this.markedContentStack.push({ 8343 visible: true 8344 }); 8345 } 8346 this.contentVisible = this.isContentVisible(); 8347 } 8348 endMarkedContent() { 8349 this.markedContentStack.pop(); 8350 this.contentVisible = this.isContentVisible(); 8351 } 8352 beginCompat() {} 8353 endCompat() {} 8354 consumePath(clipBox) { 8355 const isEmpty = this.current.isEmptyClip(); 8356 if (this.pendingClip) { 8357 this.current.updateClipFromPath(); 8358 } 8359 if (!this.pendingClip) { 8360 this.compose(clipBox); 8361 } 8362 const ctx = this.ctx; 8363 if (this.pendingClip) { 8364 if (!isEmpty) { 8365 if (this.pendingClip === EO_CLIP) { 8366 ctx.clip("evenodd"); 8367 } else { 8368 ctx.clip(); 8369 } 8370 } 8371 this.pendingClip = null; 8372 } 8373 this.current.startNewPathAndClipBox(this.current.clipBox); 8374 ctx.beginPath(); 8375 } 8376 getSinglePixelWidth() { 8377 if (!this._cachedGetSinglePixelWidth) { 8378 const m = (0, _display_utils.getCurrentTransform)(this.ctx); 8379 if (m[1] === 0 && m[2] === 0) { 8380 this._cachedGetSinglePixelWidth = 1 / Math.min(Math.abs(m[0]), Math.abs(m[3])); 8381 } else { 8382 const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]); 8383 const normX = Math.hypot(m[0], m[2]); 8384 const normY = Math.hypot(m[1], m[3]); 8385 this._cachedGetSinglePixelWidth = Math.max(normX, normY) / absDet; 8386 } 8387 } 8388 return this._cachedGetSinglePixelWidth; 8389 } 8390 getScaleForStroking() { 8391 if (this._cachedScaleForStroking[0] === -1) { 8392 const { 8393 lineWidth 8394 } = this.current; 8395 const { 8396 a, 8397 b, 8398 c, 8399 d 8400 } = this.ctx.getTransform(); 8401 let scaleX, scaleY; 8402 if (b === 0 && c === 0) { 8403 const normX = Math.abs(a); 8404 const normY = Math.abs(d); 8405 if (normX === normY) { 8406 if (lineWidth === 0) { 8407 scaleX = scaleY = 1 / normX; 8408 } else { 8409 const scaledLineWidth = normX * lineWidth; 8410 scaleX = scaleY = scaledLineWidth < 1 ? 1 / scaledLineWidth : 1; 8411 } 8412 } else if (lineWidth === 0) { 8413 scaleX = 1 / normX; 8414 scaleY = 1 / normY; 8415 } else { 8416 const scaledXLineWidth = normX * lineWidth; 8417 const scaledYLineWidth = normY * lineWidth; 8418 scaleX = scaledXLineWidth < 1 ? 1 / scaledXLineWidth : 1; 8419 scaleY = scaledYLineWidth < 1 ? 1 / scaledYLineWidth : 1; 8420 } 8421 } else { 8422 const absDet = Math.abs(a * d - b * c); 8423 const normX = Math.hypot(a, b); 8424 const normY = Math.hypot(c, d); 8425 if (lineWidth === 0) { 8426 scaleX = normY / absDet; 8427 scaleY = normX / absDet; 8428 } else { 8429 const baseArea = lineWidth * absDet; 8430 scaleX = normY > baseArea ? normY / baseArea : 1; 8431 scaleY = normX > baseArea ? normX / baseArea : 1; 8432 } 8433 } 8434 this._cachedScaleForStroking[0] = scaleX; 8435 this._cachedScaleForStroking[1] = scaleY; 8436 } 8437 return this._cachedScaleForStroking; 8438 } 8439 rescaleAndStroke(saveRestore) { 8440 const { 8441 ctx 8442 } = this; 8443 const { 8444 lineWidth 8445 } = this.current;
8446 const [scaleX, scaleY] = this.getScaleForStroking(); 8447 ctx.lineWidth = lineWidth || 1; 8448 if (scaleX === 1 && scaleY === 1) { 8449 ctx.stroke(); 8450 return; 8451 } 8452 const dashes = ctx.getLineDash(); 8453 if (saveRestore) { 8454 ctx.save(); 8455 } 8456 ctx.scale(scaleX, scaleY); 8457 if (dashes.length > 0) { 8458 const scale = Math.max(scaleX, scaleY); 8459 ctx.setLineDash(dashes.map(x => x / scale)); 8460 ctx.lineDashOffset /= scale; 8461 } 8462 ctx.stroke(); 8463 if (saveRestore) { 8464 ctx.restore(); 8465 } 8466 } 8467 isContentVisible() { 8468 for (let i = this.markedContentStack.length - 1; i >= 0; i--) { 8469 if (!this.markedContentStack[i].visible) { 8470 return false; 8471 } 8472 } 8473 return true; 8474 } 8475} 8476exports.CanvasGraphics = CanvasGraphics; 8477for (const op in _util.OPS) { 8478 if (CanvasGraphics.prototype[op] !== undefined) { 8479 CanvasGraphics.prototype[_util.OPS[op]] = CanvasGraphics.prototype[op]; 8480 } 8481} 8482 8483/***/ }), 8484/* 12 */ 8485/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 8486 8487 8488 8489Object.defineProperty(exports, "__esModule", ({ 8490 value: true 8491})); 8492exports.TilingPattern = exports.PathType = void 0; 8493exports.getShadingPattern = getShadingPattern; 8494var _util = __w_pdfjs_require__(1); 8495var _display_utils = __w_pdfjs_require__(6); 8496const PathType = { 8497 FILL: "Fill", 8498 STROKE: "Stroke", 8499 SHADING: "Shading" 8500}; 8501exports.PathType = PathType; 8502function applyBoundingBox(ctx, bbox) { 8503 if (!bbox) { 8504 return; 8505 } 8506 const width = bbox[2] - bbox[0]; 8507 const height = bbox[3] - bbox[1]; 8508 const region = new Path2D(); 8509 region.rect(bbox[0], bbox[1], width, height); 8510 ctx.clip(region); 8511} 8512class BaseShadingPattern { 8513 constructor() { 8514 if (this.constructor === BaseShadingPattern) { 8515 (0, _util.unreachable)("Cannot initialize BaseShadingPattern."); 8516 } 8517 } 8518 getPattern() { 8519 (0, _util.unreachable)("Abstract method `getPattern` called."); 8520 } 8521} 8522class RadialAxialShadingPattern extends BaseShadingPattern { 8523 constructor(IR) { 8524 super(); 8525 this._type = IR[1]; 8526 this._bbox = IR[2]; 8527 this._colorStops = IR[3]; 8528 this._p0 = IR[4]; 8529 this._p1 = IR[5]; 8530 this._r0 = IR[6]; 8531 this._r1 = IR[7]; 8532 this.matrix = null; 8533 } 8534 _createGradient(ctx) { 8535 let grad; 8536 if (this._type === "axial") { 8537 grad = ctx.createLinearGradient(this._p0[0], this._p0[1], this._p1[0], this._p1[1]); 8538 } else if (this._type === "radial") { 8539 grad = ctx.createRadialGradient(this._p0[0], this._p0[1], this._r0, this._p1[0], this._p1[1], this._r1); 8540 } 8541 for (const colorStop of this._colorStops) { 8542 grad.addColorStop(colorStop[0], colorStop[1]); 8543 } 8544 return grad; 8545 } 8546 getPattern(ctx, owner, inverse, pathType) { 8547 let pattern; 8548 if (pathType === PathType.STROKE || pathType === PathType.FILL) { 8549 const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, (0, _display_utils.getCurrentTransform)(ctx)) || [0, 0, 0, 0]; 8550 const width = Math.ceil(ownerBBox[2] - ownerBBox[0]) || 1; 8551 const height = Math.ceil(ownerBBox[3] - ownerBBox[1]) || 1; 8552 const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", width, height, true); 8553 const tmpCtx = tmpCanvas.context; 8554 tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); 8555 tmpCtx.beginPath(); 8556 tmpCtx.rect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); 8557 tmpCtx.translate(-ownerBBox[0], -ownerBBox[1]); 8558 inverse = _util.Util.transform(inverse, [1, 0, 0, 1, ownerBBox[0], ownerBBox[1]]); 8559 tmpCtx.transform(...owner.baseTransform); 8560 if (this.matrix) { 8561 tmpCtx.transform(...this.matrix); 8562 } 8563 applyBoundingBox(tmpCtx, this._bbox); 8564 tmpCtx.fillStyle = this._createGradient(tmpCtx); 8565 tmpCtx.fill(); 8566 pattern = ctx.createPattern(tmpCanvas.canvas, "no-repeat"); 8567 const domMatrix = new DOMMatrix(inverse); 8568 pattern.setTransform(domMatrix); 8569 } else { 8570 applyBoundingBox(ctx, this._bbox); 8571 pattern = this._createGradient(ctx); 8572 } 8573 return pattern; 8574 } 8575} 8576function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) { 8577 const coords = context.coords, 8578 colors = context.colors; 8579 const bytes = data.data, 8580 rowSize = data.width * 4; 8581 let tmp; 8582 if (coords[p1 + 1] > coords[p2 + 1]) { 8583 tmp = p1; 8584 p1 = p2; 8585 p2 = tmp; 8586 tmp = c1; 8587 c1 = c2; 8588 c2 = tmp; 8589 } 8590 if (coords[p2 + 1] > coords[p3 + 1]) { 8591 tmp = p2; 8592 p2 = p3; 8593 p3 = tmp; 8594 tmp = c2; 8595 c2 = c3; 8596 c3 = tmp; 8597 } 8598 if (coords[p1 + 1] > coords[p2 + 1]) { 8599 tmp = p1; 8600 p1 = p2; 8601 p2 = tmp; 8602 tmp = c1; 8603 c1 = c2; 8604 c2 = tmp; 8605 } 8606 const x1 = (coords[p1] + context.offsetX) * context.scaleX; 8607 const y1 = (coords[p1 + 1] + context.offsetY) * context.scaleY; 8608 const x2 = (coords[p2] + context.offsetX) * context.scaleX; 8609 const y2 = (coords[p2 + 1] + context.offsetY) * context.scaleY; 8610 const x3 = (coords[p3] + context.offsetX) * context.scaleX; 8611 const y3 = (coords[p3 + 1] + context.offsetY) * context.scaleY; 8612 if (y1 >= y3) { 8613 return; 8614 } 8615 const c1r = colors[c1], 8616 c1g = colors[c1 + 1], 8617 c1b = colors[c1 + 2]; 8618 const c2r = colors[c2], 8619 c2g = colors[c2 + 1], 8620 c2b = colors[c2 + 2]; 8621 const c3r = colors[c3], 8622 c3g = colors[c3 + 1], 8623 c3b = colors[c3 + 2]; 8624 const minY = Math.round(y1), 8625 maxY = Math.round(y3); 8626 let xa, car, cag, cab; 8627 let xb, cbr, cbg, cbb; 8628 for (let y = minY; y <= maxY; y++) { 8629 if (y < y2) {
vendor: 4,267 bytes, lines 8630-8759
8630 const k = y < y1 ? 0 : (y1 - y) / (y1 - y2); 8631 xa = x1 - (x1 - x2) * k; 8632 car = c1r - (c1r - c2r) * k; 8633 cag = c1g - (c1g - c2g) * k; 8634 cab = c1b - (c1b - c2b) * k; 8635 } else { 8636 let k; 8637 if (y > y3) { 8638 k = 1; 8639 } else if (y2 === y3) { 8640 k = 0; 8641 } else { 8642 k = (y2 - y) / (y2 - y3); 8643 } 8644 xa = x2 - (x2 - x3) * k; 8645 car = c2r - (c2r - c3r) * k; 8646 cag = c2g - (c2g - c3g) * k; 8647 cab = c2b - (c2b - c3b) * k; 8648 } 8649 let k; 8650 if (y < y1) { 8651 k = 0; 8652 } else if (y > y3) { 8653 k = 1; 8654 } else { 8655 k = (y1 - y) / (y1 - y3); 8656 } 8657 xb = x1 - (x1 - x3) * k; 8658 cbr = c1r - (c1r - c3r) * k; 8659 cbg = c1g - (c1g - c3g) * k; 8660 cbb = c1b - (c1b - c3b) * k; 8661 const x1_ = Math.round(Math.min(xa, xb)); 8662 const x2_ = Math.round(Math.max(xa, xb)); 8663 let j = rowSize * y + x1_ * 4; 8664 for (let x = x1_; x <= x2_; x++) { 8665 k = (xa - x) / (xa - xb); 8666 if (k < 0) { 8667 k = 0; 8668 } else if (k > 1) { 8669 k = 1; 8670 } 8671 bytes[j++] = car - (car - cbr) * k | 0; 8672 bytes[j++] = cag - (cag - cbg) * k | 0; 8673 bytes[j++] = cab - (cab - cbb) * k | 0; 8674 bytes[j++] = 255; 8675 } 8676 } 8677} 8678function drawFigure(data, figure, context) { 8679 const ps = figure.coords; 8680 const cs = figure.colors; 8681 let i, ii; 8682 switch (figure.type) { 8683 case "lattice": 8684 const verticesPerRow = figure.verticesPerRow; 8685 const rows = Math.floor(ps.length / verticesPerRow) - 1; 8686 const cols = verticesPerRow - 1; 8687 for (i = 0; i < rows; i++) { 8688 let q = i * verticesPerRow; 8689 for (let j = 0; j < cols; j++, q++) { 8690 drawTriangle(data, context, ps[q], ps[q + 1], ps[q + verticesPerRow], cs[q], cs[q + 1], cs[q + verticesPerRow]); 8691 drawTriangle(data, context, ps[q + verticesPerRow + 1], ps[q + 1], ps[q + verticesPerRow], cs[q + verticesPerRow + 1], cs[q + 1], cs[q + verticesPerRow]); 8692 } 8693 } 8694 break; 8695 case "triangles": 8696 for (i = 0, ii = ps.length; i < ii; i += 3) { 8697 drawTriangle(data, context, ps[i], ps[i + 1], ps[i + 2], cs[i], cs[i + 1], cs[i + 2]); 8698 } 8699 break; 8700 default: 8701 throw new Error("illegal figure"); 8702 } 8703} 8704class MeshShadingPattern extends BaseShadingPattern { 8705 constructor(IR) { 8706 super(); 8707 this._coords = IR[2]; 8708 this._colors = IR[3]; 8709 this._figures = IR[4]; 8710 this._bounds = IR[5]; 8711 this._bbox = IR[7]; 8712 this._background = IR[8]; 8713 this.matrix = null; 8714 } 8715 _createMeshCanvas(combinedScale, backgroundColor, cachedCanvases) { 8716 const EXPECTED_SCALE = 1.1; 8717 const MAX_PATTERN_SIZE = 3000; 8718 const BORDER_SIZE = 2; 8719 const offsetX = Math.floor(this._bounds[0]); 8720 const offsetY = Math.floor(this._bounds[1]); 8721 const boundsWidth = Math.ceil(this._bounds[2]) - offsetX; 8722 const boundsHeight = Math.ceil(this._bounds[3]) - offsetY; 8723 const width = Math.min(Math.ceil(Math.abs(boundsWidth * combinedScale[0] * EXPECTED_SCALE)), MAX_PATTERN_SIZE); 8724 const height = Math.min(Math.ceil(Math.abs(boundsHeight * combinedScale[1] * EXPECTED_SCALE)), MAX_PATTERN_SIZE); 8725 const scaleX = boundsWidth / width; 8726 const scaleY = boundsHeight / height; 8727 const context = { 8728 coords: this._coords, 8729 colors: this._colors, 8730 offsetX: -offsetX, 8731 offsetY: -offsetY, 8732 scaleX: 1 / scaleX, 8733 scaleY: 1 / scaleY 8734 }; 8735 const paddedWidth = width + BORDER_SIZE * 2; 8736 const paddedHeight = height + BORDER_SIZE * 2; 8737 const tmpCanvas = cachedCanvases.getCanvas("mesh", paddedWidth, paddedHeight, false); 8738 const tmpCtx = tmpCanvas.context; 8739 const data = tmpCtx.createImageData(width, height); 8740 if (backgroundColor) { 8741 const bytes = data.data; 8742 for (let i = 0, ii = bytes.length; i < ii; i += 4) { 8743 bytes[i] = backgroundColor[0]; 8744 bytes[i + 1] = backgroundColor[1]; 8745 bytes[i + 2] = backgroundColor[2]; 8746 bytes[i + 3] = 255; 8747 } 8748 } 8749 for (const figure of this._figures) { 8750 drawFigure(data, figure, context); 8751 } 8752 tmpCtx.putImageData(data, BORDER_SIZE, BORDER_SIZE); 8753 const canvas = tmpCanvas.canvas; 8754 return { 8755 canvas, 8756 offsetX: offsetX - BORDER_SIZE * scaleX, 8757 offsetY: offsetY - BORDER_SIZE * scaleY, 8758 scaleX, 8759 scaleY
8760 }; 8761 } 8762 getPattern(ctx, owner, inverse, pathType) { 8763 applyBoundingBox(ctx, this._bbox); 8764 let scale; 8765 if (pathType === PathType.SHADING) { 8766 scale = _util.Util.singularValueDecompose2dScale((0, _display_utils.getCurrentTransform)(ctx)); 8767 } else { 8768 scale = _util.Util.singularValueDecompose2dScale(owner.baseTransform); 8769 if (this.matrix) { 8770 const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix); 8771 scale = [scale[0] * matrixScale[0], scale[1] * matrixScale[1]]; 8772 } 8773 } 8774 const temporaryPatternCanvas = this._createMeshCanvas(scale, pathType === PathType.SHADING ? null : this._background, owner.cachedCanvases); 8775 if (pathType !== PathType.SHADING) { 8776 ctx.setTransform(...owner.baseTransform); 8777 if (this.matrix) { 8778 ctx.transform(...this.matrix); 8779 } 8780 } 8781 ctx.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY); 8782 ctx.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY); 8783 return ctx.createPattern(temporaryPatternCanvas.canvas, "no-repeat"); 8784 } 8785} 8786class DummyShadingPattern extends BaseShadingPattern { 8787 getPattern() { 8788 return "hotpink"; 8789 } 8790} 8791function getShadingPattern(IR) { 8792 switch (IR[0]) { 8793 case "RadialAxial": 8794 return new RadialAxialShadingPattern(IR); 8795 case "Mesh": 8796 return new MeshShadingPattern(IR); 8797 case "Dummy": 8798 return new DummyShadingPattern(); 8799 } 8800 throw new Error(`Unknown IR type: ${IR[0]}`); 8801} 8802const PaintType = { 8803 COLORED: 1, 8804 UNCOLORED: 2 8805}; 8806class TilingPattern { 8807 static MAX_PATTERN_SIZE = 3000; 8808 constructor(IR, color, ctx, canvasGraphicsFactory, baseTransform) { 8809 this.operatorList = IR[2]; 8810 this.matrix = IR[3] || [1, 0, 0, 1, 0, 0]; 8811 this.bbox = IR[4]; 8812 this.xstep = IR[5]; 8813 this.ystep = IR[6]; 8814 this.paintType = IR[7]; 8815 this.tilingType = IR[8]; 8816 this.color = color; 8817 this.ctx = ctx; 8818 this.canvasGraphicsFactory = canvasGraphicsFactory; 8819 this.baseTransform = baseTransform; 8820 } 8821 createPatternCanvas(owner) { 8822 const operatorList = this.operatorList; 8823 const bbox = this.bbox; 8824 const xstep = this.xstep; 8825 const ystep = this.ystep; 8826 const paintType = this.paintType; 8827 const tilingType = this.tilingType; 8828 const color = this.color; 8829 const canvasGraphicsFactory = this.canvasGraphicsFactory; 8830 (0, _util.info)("TilingType: " + tilingType); 8831 const x0 = bbox[0], 8832 y0 = bbox[1], 8833 x1 = bbox[2], 8834 y1 = bbox[3]; 8835 const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix); 8836 const curMatrixScale = _util.Util.singularValueDecompose2dScale(this.baseTransform); 8837 const combinedScale = [matrixScale[0] * curMatrixScale[0], matrixScale[1] * curMatrixScale[1]]; 8838 const dimx = this.getSizeAndScale(xstep, this.ctx.canvas.width, combinedScale[0]); 8839 const dimy = this.getSizeAndScale(ystep, this.ctx.canvas.height, combinedScale[1]); 8840 const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", dimx.size, dimy.size, true); 8841 const tmpCtx = tmpCanvas.context; 8842 const graphics = canvasGraphicsFactory.createCanvasGraphics(tmpCtx); 8843 graphics.groupLevel = owner.groupLevel; 8844 this.setFillAndStrokeStyleToContext(graphics, paintType, color); 8845 let adjustedX0 = x0; 8846 let adjustedY0 = y0; 8847 let adjustedX1 = x1; 8848 let adjustedY1 = y1; 8849 if (x0 < 0) { 8850 adjustedX0 = 0; 8851 adjustedX1 += Math.abs(x0); 8852 } 8853 if (y0 < 0) { 8854 adjustedY0 = 0; 8855 adjustedY1 += Math.abs(y0); 8856 } 8857 tmpCtx.translate(-(dimx.scale * adjustedX0), -(dimy.scale * adjustedY0)); 8858 graphics.transform(dimx.scale, 0, 0, dimy.scale, 0, 0); 8859 tmpCtx.save(); 8860 this.clipBbox(graphics, adjustedX0, adjustedY0, adjustedX1, adjustedY1); 8861 graphics.baseTransform = (0, _display_utils.getCurrentTransform)(graphics.ctx); 8862 graphics.executeOperatorList(operatorList); 8863 graphics.endDrawing(); 8864 return { 8865 canvas: tmpCanvas.canvas, 8866 scaleX: dimx.scale, 8867 scaleY: dimy.scale, 8868 offsetX: adjustedX0, 8869 offsetY: adjustedY0 8870 }; 8871 } 8872 getSizeAndScale(step, realOutputSize, scale) { 8873 step = Math.abs(step); 8874 const maxSize = Math.max(TilingPattern.MAX_PATTERN_SIZE, realOutputSize);
8875 let size = Math.ceil(step * scale); 8876 if (size >= maxSize) { 8877 size = maxSize; 8878 } else { 8879 scale = size / step; 8880 } 8881 return { 8882 scale, 8883 size 8884 }; 8885 } 8886 clipBbox(graphics, x0, y0, x1, y1) { 8887 const bboxWidth = x1 - x0; 8888 const bboxHeight = y1 - y0; 8889 graphics.ctx.rect(x0, y0, bboxWidth, bboxHeight); 8890 graphics.current.updateRectMinMax((0, _display_utils.getCurrentTransform)(graphics.ctx), [x0, y0, x1, y1]); 8891 graphics.clip(); 8892 graphics.endPath(); 8893 } 8894 setFillAndStrokeStyleToContext(graphics, paintType, color) { 8895 const context = graphics.ctx, 8896 current = graphics.current; 8897 switch (paintType) { 8898 case PaintType.COLORED: 8899 const ctx = this.ctx; 8900 context.fillStyle = ctx.fillStyle; 8901 context.strokeStyle = ctx.strokeStyle; 8902 current.fillColor = ctx.fillStyle; 8903 current.strokeColor = ctx.strokeStyle; 8904 break; 8905 case PaintType.UNCOLORED: 8906 const cssColor = _util.Util.makeHexColor(color[0], color[1], color[2]); 8907 context.fillStyle = cssColor; 8908 context.strokeStyle = cssColor; 8909 current.fillColor = cssColor; 8910 current.strokeColor = cssColor; 8911 break; 8912 default: 8913 throw new _util.FormatError(`Unsupported paint type: ${paintType}`); 8914 } 8915 } 8916 getPattern(ctx, owner, inverse, pathType) { 8917 let matrix = inverse; 8918 if (pathType !== PathType.SHADING) { 8919 matrix = _util.Util.transform(matrix, owner.baseTransform); 8920 if (this.matrix) { 8921 matrix = _util.Util.transform(matrix, this.matrix); 8922 } 8923 } 8924 const temporaryPatternCanvas = this.createPatternCanvas(owner); 8925 let domMatrix = new DOMMatrix(matrix); 8926 domMatrix = domMatrix.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY); 8927 domMatrix = domMatrix.scale(1 / temporaryPatternCanvas.scaleX, 1 / temporaryPatternCanvas.scaleY); 8928 const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "repeat"); 8929 pattern.setTransform(domMatrix); 8930 return pattern; 8931 } 8932} 8933exports.TilingPattern = TilingPattern; 8934 8935/***/ }), 8936/* 13 */ 8937/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 8938 8939 8940 8941Object.defineProperty(exports, "__esModule", ({ 8942 value: true 8943})); 8944exports.convertBlackAndWhiteToRGBA = convertBlackAndWhiteToRGBA; 8945exports.convertToRGBA = convertToRGBA; 8946exports.grayToRGBA = grayToRGBA; 8947var _util = __w_pdfjs_require__(1); 8948function convertToRGBA(params) { 8949 switch (params.kind) { 8950 case _util.ImageKind.GRAYSCALE_1BPP: 8951 return convertBlackAndWhiteToRGBA(params); 8952 case _util.ImageKind.RGB_24BPP: 8953 return convertRGBToRGBA(params); 8954 } 8955 return null; 8956} 8957function convertBlackAndWhiteToRGBA({ 8958 src, 8959 srcPos = 0, 8960 dest, 8961 width, 8962 height, 8963 nonBlackColor = 0xffffffff, 8964 inverseDecode = false 8965}) { 8966 const black = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; 8967 const [zeroMapping, oneMapping] = inverseDecode ? [nonBlackColor, black] : [black, nonBlackColor]; 8968 const widthInSource = width >> 3; 8969 const widthRemainder = width & 7; 8970 const srcLength = src.length; 8971 dest = new Uint32Array(dest.buffer); 8972 let destPos = 0; 8973 for (let i = 0; i < height; i++) { 8974 for (const max = srcPos + widthInSource; srcPos < max; srcPos++) { 8975 const elem = srcPos < srcLength ? src[srcPos] : 255; 8976 dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping; 8977 dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping; 8978 dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping; 8979 dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping; 8980 dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping; 8981 dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping; 8982 dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping; 8983 dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping; 8984 } 8985 if (widthRemainder === 0) { 8986 continue; 8987 } 8988 const elem = srcPos < srcLength ? src[srcPos++] : 255; 8989 for (let j = 0; j < widthRemainder; j++) { 8990 dest[destPos++] = elem & 1 << 7 - j ? oneMapping : zeroMapping; 8991 } 8992 } 8993 return { 8994 srcPos, 8995 destPos 8996 }; 8997} 8998function convertRGBToRGBA({ 8999 src, 9000 srcPos = 0, 9001 dest, 9002 destPos = 0, 9003 width, 9004 height 9005}) { 9006 let i = 0; 9007 const len32 = src.length >> 2; 9008 const src32 = new Uint32Array(src.buffer, srcPos, len32); 9009 if (_util.FeatureTest.isLittleEndian) { 9010 for (; i < len32 - 2; i += 3, destPos += 4) { 9011 const s1 = src32[i]; 9012 const s2 = src32[i + 1]; 9013 const s3 = src32[i + 2]; 9014 dest[destPos] = s1 | 0xff000000; 9015 dest[destPos + 1] = s1 >>> 24 | s2 << 8 | 0xff000000; 9016 dest[destPos + 2] = s2 >>> 16 | s3 << 16 | 0xff000000; 9017 dest[destPos + 3] = s3 >>> 8 | 0xff000000; 9018 } 9019 for (let j = i * 4, jj = src.length; j < jj; j += 3) { 9020 dest[destPos++] = src[j] | src[j + 1] << 8 | src[j + 2] << 16 | 0xff000000; 9021 } 9022 } else { 9023 for (; i < len32 - 2; i += 3, destPos += 4) { 9024 const s1 = src32[i]; 9025 const s2 = src32[i + 1]; 9026 const s3 = src32[i + 2]; 9027 dest[destPos] = s1 | 0xff;
9028 dest[destPos + 1] = s1 << 24 | s2 >>> 8 | 0xff; 9029 dest[destPos + 2] = s2 << 16 | s3 >>> 16 | 0xff; 9030 dest[destPos + 3] = s3 << 8 | 0xff; 9031 } 9032 for (let j = i * 4, jj = src.length; j < jj; j += 3) { 9033 dest[destPos++] = src[j] << 24 | src[j + 1] << 16 | src[j + 2] << 8 | 0xff; 9034 } 9035 } 9036 return { 9037 srcPos, 9038 destPos 9039 }; 9040} 9041function grayToRGBA(src, dest) { 9042 if (_util.FeatureTest.isLittleEndian) { 9043 for (let i = 0, ii = src.length; i < ii; i++) { 9044 dest[i] = src[i] * 0x10101 | 0xff000000; 9045 } 9046 } else { 9047 for (let i = 0, ii = src.length; i < ii; i++) { 9048 dest[i] = src[i] * 0x1010100 | 0x000000ff; 9049 } 9050 } 9051} 9052 9053/***/ }), 9054/* 14 */ 9055/***/ ((__unused_webpack_module, exports) => { 9056 9057 9058 9059Object.defineProperty(exports, "__esModule", ({ 9060 value: true 9061})); 9062exports.GlobalWorkerOptions = void 0; 9063const GlobalWorkerOptions = Object.create(null); 9064exports.GlobalWorkerOptions = GlobalWorkerOptions; 9065GlobalWorkerOptions.workerPort = null; 9066GlobalWorkerOptions.workerSrc = ""; 9067 9068/***/ }), 9069/* 15 */ 9070/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9071 9072 9073 9074Object.defineProperty(exports, "__esModule", ({ 9075 value: true 9076})); 9077exports.MessageHandler = void 0; 9078var _util = __w_pdfjs_require__(1); 9079const CallbackKind = { 9080 UNKNOWN: 0, 9081 DATA: 1, 9082 ERROR: 2 9083}; 9084const StreamKind = { 9085 UNKNOWN: 0, 9086 CANCEL: 1, 9087 CANCEL_COMPLETE: 2, 9088 CLOSE: 3, 9089 ENQUEUE: 4, 9090 ERROR: 5, 9091 PULL: 6, 9092 PULL_COMPLETE: 7, 9093 START_COMPLETE: 8 9094}; 9095function wrapReason(reason) { 9096 if (!(reason instanceof Error || typeof reason === "object" && reason !== null)) { 9097 (0, _util.unreachable)('wrapReason: Expected "reason" to be a (possibly cloned) Error.'); 9098 } 9099 switch (reason.name) { 9100 case "AbortException": 9101 return new _util.AbortException(reason.message); 9102 case "MissingPDFException": 9103 return new _util.MissingPDFException(reason.message); 9104 case "PasswordException": 9105 return new _util.PasswordException(reason.message, reason.code); 9106 case "UnexpectedResponseException": 9107 return new _util.UnexpectedResponseException(reason.message, reason.status); 9108 case "UnknownErrorException": 9109 return new _util.UnknownErrorException(reason.message, reason.details); 9110 default: 9111 return new _util.UnknownErrorException(reason.message, reason.toString()); 9112 } 9113} 9114class MessageHandler { 9115 constructor(sourceName, targetName, comObj) { 9116 this.sourceName = sourceName; 9117 this.targetName = targetName; 9118 this.comObj = comObj; 9119 this.callbackId = 1; 9120 this.streamId = 1; 9121 this.streamSinks = Object.create(null); 9122 this.streamControllers = Object.create(null); 9123 this.callbackCapabilities = Object.create(null); 9124 this.actionHandler = Object.create(null); 9125 this._onComObjOnMessage = event => { 9126 const data = event.data; 9127 if (data.targetName !== this.sourceName) { 9128 return; 9129 } 9130 if (data.stream) { 9131 this.#processStreamMessage(data); 9132 return; 9133 } 9134 if (data.callback) { 9135 const callbackId = data.callbackId; 9136 const capability = this.callbackCapabilities[callbackId]; 9137 if (!capability) { 9138 throw new Error(`Cannot resolve callback ${callbackId}`); 9139 } 9140 delete this.callbackCapabilities[callbackId]; 9141 if (data.callback === CallbackKind.DATA) { 9142 capability.resolve(data.data); 9143 } else if (data.callback === CallbackKind.ERROR) { 9144 capability.reject(wrapReason(data.reason)); 9145 } else { 9146 throw new Error("Unexpected callback case"); 9147 } 9148 return; 9149 } 9150 const action = this.actionHandler[data.action]; 9151 if (!action) { 9152 throw new Error(`Unknown action from worker: ${data.action}`); 9153 } 9154 if (data.callbackId) { 9155 const cbSourceName = this.sourceName; 9156 const cbTargetName = data.sourceName; 9157 new Promise(function (resolve) { 9158 resolve(action(data.data)); 9159 }).then(function (result) { 9160 comObj.postMessage({ 9161 sourceName: cbSourceName, 9162 targetName: cbTargetName, 9163 callback: CallbackKind.DATA, 9164 callbackId: data.callbackId, 9165 data: result 9166 }); 9167 }, function (reason) { 9168 comObj.postMessage({ 9169 sourceName: cbSourceName, 9170 targetName: cbTargetName, 9171 callback: CallbackKind.ERROR, 9172 callbackId: data.callbackId, 9173 reason: wrapReason(reason) 9174 }); 9175 }); 9176 return; 9177 } 9178 if (data.streamId) { 9179 this.#createStreamSink(data); 9180 return; 9181 } 9182 action(data.data); 9183 }; 9184 comObj.addEventListener("message", this._onComObjOnMessage); 9185 } 9186 on(actionName, handler) { 9187 const ah = this.actionHandler; 9188 if (ah[actionName]) { 9189 throw new Error(`There is already an actionName called "${actionName}"`); 9190 } 9191 ah[actionName] = handler; 9192 } 9193 send(actionName, data, transfers) { 9194 this.comObj.postMessage({ 9195 sourceName: this.sourceName, 9196 targetName: this.targetName, 9197 action: actionName, 9198 data 9199 }, transfers); 9200 }
9201 sendWithPromise(actionName, data, transfers) { 9202 const callbackId = this.callbackId++; 9203 const capability = new _util.PromiseCapability(); 9204 this.callbackCapabilities[callbackId] = capability; 9205 try { 9206 this.comObj.postMessage({ 9207 sourceName: this.sourceName, 9208 targetName: this.targetName, 9209 action: actionName, 9210 callbackId, 9211 data 9212 }, transfers); 9213 } catch (ex) { 9214 capability.reject(ex); 9215 } 9216 return capability.promise; 9217 } 9218 sendWithStream(actionName, data, queueingStrategy, transfers) { 9219 const streamId = this.streamId++, 9220 sourceName = this.sourceName, 9221 targetName = this.targetName, 9222 comObj = this.comObj; 9223 return new ReadableStream({ 9224 start: controller => { 9225 const startCapability = new _util.PromiseCapability(); 9226 this.streamControllers[streamId] = { 9227 controller, 9228 startCall: startCapability, 9229 pullCall: null, 9230 cancelCall: null, 9231 isClosed: false 9232 }; 9233 comObj.postMessage({ 9234 sourceName, 9235 targetName, 9236 action: actionName, 9237 streamId, 9238 data, 9239 desiredSize: controller.desiredSize 9240 }, transfers); 9241 return startCapability.promise; 9242 }, 9243 pull: controller => { 9244 const pullCapability = new _util.PromiseCapability(); 9245 this.streamControllers[streamId].pullCall = pullCapability; 9246 comObj.postMessage({ 9247 sourceName, 9248 targetName, 9249 stream: StreamKind.PULL, 9250 streamId, 9251 desiredSize: controller.desiredSize 9252 }); 9253 return pullCapability.promise; 9254 }, 9255 cancel: reason => { 9256 (0, _util.assert)(reason instanceof Error, "cancel must have a valid reason"); 9257 const cancelCapability = new _util.PromiseCapability(); 9258 this.streamControllers[streamId].cancelCall = cancelCapability; 9259 this.streamControllers[streamId].isClosed = true; 9260 comObj.postMessage({ 9261 sourceName, 9262 targetName, 9263 stream: StreamKind.CANCEL, 9264 streamId, 9265 reason: wrapReason(reason) 9266 }); 9267 return cancelCapability.promise; 9268 } 9269 }, queueingStrategy); 9270 } 9271 #createStreamSink(data) { 9272 const streamId = data.streamId, 9273 sourceName = this.sourceName, 9274 targetName = data.sourceName, 9275 comObj = this.comObj; 9276 const self = this, 9277 action = this.actionHandler[data.action]; 9278 const streamSink = { 9279 enqueue(chunk, size = 1, transfers) { 9280 if (this.isCancelled) { 9281 return; 9282 } 9283 const lastDesiredSize = this.desiredSize; 9284 this.desiredSize -= size; 9285 if (lastDesiredSize > 0 && this.desiredSize <= 0) { 9286 this.sinkCapability = new _util.PromiseCapability(); 9287 this.ready = this.sinkCapability.promise; 9288 } 9289 comObj.postMessage({ 9290 sourceName, 9291 targetName, 9292 stream: StreamKind.ENQUEUE, 9293 streamId, 9294 chunk 9295 }, transfers); 9296 }, 9297 close() { 9298 if (this.isCancelled) { 9299 return; 9300 } 9301 this.isCancelled = true; 9302 comObj.postMessage({ 9303 sourceName, 9304 targetName, 9305 stream: StreamKind.CLOSE, 9306 streamId 9307 }); 9308 delete self.streamSinks[streamId]; 9309 }, 9310 error(reason) { 9311 (0, _util.assert)(reason instanceof Error, "error must have a valid reason"); 9312 if (this.isCancelled) { 9313 return; 9314 } 9315 this.isCancelled = true; 9316 comObj.postMessage({ 9317 sourceName, 9318 targetName, 9319 stream: StreamKind.ERROR, 9320 streamId, 9321 reason: wrapReason(reason) 9322 }); 9323 }, 9324 sinkCapability: new _util.PromiseCapability(), 9325 onPull: null, 9326 onCancel: null, 9327 isCancelled: false, 9328 desiredSize: data.desiredSize, 9329 ready: null 9330 }; 9331 streamSink.sinkCapability.resolve(); 9332 streamSink.ready = streamSink.sinkCapability.promise; 9333 this.streamSinks[streamId] = streamSink; 9334 new Promise(function (resolve) { 9335 resolve(action(data.data, streamSink)); 9336 }).then(function () { 9337 comObj.postMessage({ 9338 sourceName, 9339 targetName, 9340 stream: StreamKind.START_COMPLETE, 9341 streamId, 9342 success: true 9343 }); 9344 }, function (reason) { 9345 comObj.postMessage({ 9346 sourceName, 9347 targetName, 9348 stream: StreamKind.START_COMPLETE, 9349 streamId, 9350 reason: wrapReason(reason) 9351 }); 9352 }); 9353 } 9354 #processStreamMessage(data) { 9355 const streamId = data.streamId, 9356 sourceName = this.sourceName, 9357 targetName = data.sourceName, 9358 comObj = this.comObj; 9359 const streamController = this.streamControllers[streamId], 9360 streamSink = this.streamSinks[streamId]; 9361 switch (data.stream) { 9362 case StreamKind.START_COMPLETE: 9363 if (data.success) { 9364 streamController.startCall.resolve(); 9365 } else { 9366 streamController.startCall.reject(wrapReason(data.reason)); 9367 } 9368 break; 9369 case StreamKind.PULL_COMPLETE: 9370 if (data.success) { 9371 streamController.pullCall.resolve(); 9372 } else { 9373 streamController.pullCall.reject(wrapReason(data.reason)); 9374 } 9375 break; 9376 case StreamKind.PULL: 9377 if (!streamSink) { 9378 comObj.postMessage({ 9379 sourceName, 9380 targetName, 9381 stream: StreamKind.PULL_COMPLETE, 9382 streamId, 9383 success: true 9384 }); 9385 break; 9386 } 9387 if (streamSink.desiredSize <= 0 && data.desiredSize > 0) { 9388 streamSink.sinkCapability.resolve(); 9389 } 9390 streamSink.desiredSize = data.desiredSize; 9391 new Promise(function (resolve) { 9392 resolve(streamSink.onPull?.()); 9393 }).then(function () { 9394 comObj.postMessage({ 9395 sourceName, 9396 targetName, 9397 stream: StreamKind.PULL_COMPLETE, 9398 streamId, 9399 success: true 9400 }); 9401 }, function (reason) { 9402 comObj.postMessage({ 9403 sourceName, 9404 targetName, 9405 stream: StreamKind.PULL_COMPLETE, 9406 streamId, 9407 reason: wrapReason(reason) 9408 }); 9409 }); 9410 break; 9411 case StreamKind.ENQUEUE: 9412 (0, _util.assert)(streamController, "enqueue should have stream controller"); 9413 if (streamController.isClosed) { 9414 break; 9415 } 9416 streamController.controller.enqueue(data.chunk); 9417 break; 9418 case StreamKind.CLOSE: 9419 (0, _util.assert)(streamController, "close should have stream controller"); 9420 if (streamController.isClosed) { 9421 break; 9422 } 9423 streamController.isClosed = true; 9424 streamController.controller.close(); 9425 this.#deleteStreamController(streamController, streamId); 9426 break; 9427 case StreamKind.ERROR: 9428 (0, _util.assert)(streamController, "error should have stream controller"); 9429 streamController.controller.error(wrapReason(data.reason)); 9430 this.#deleteStreamController(streamController, streamId); 9431 break; 9432 case StreamKind.CANCEL_COMPLETE: 9433 if (data.success) { 9434 streamController.cancelCall.resolve(); 9435 } else { 9436 streamController.cancelCall.reject(wrapReason(data.reason)); 9437 } 9438 this.#deleteStreamController(streamController, streamId); 9439 break; 9440 case StreamKind.CANCEL: 9441 if (!streamSink) { 9442 break; 9443 } 9444 new Promise(function (resolve) { 9445 resolve(streamSink.onCancel?.(wrapReason(data.reason))); 9446 }).then(function () { 9447 comObj.postMessage({ 9448 sourceName, 9449 targetName, 9450 stream: StreamKind.CANCEL_COMPLETE, 9451 streamId, 9452 success: true 9453 }); 9454 }, function (reason) { 9455 comObj.postMessage({ 9456 sourceName, 9457 targetName, 9458 stream: StreamKind.CANCEL_COMPLETE, 9459 streamId, 9460 reason: wrapReason(reason) 9461 }); 9462 }); 9463 streamSink.sinkCapability.reject(wrapReason(data.reason)); 9464 streamSink.isCancelled = true; 9465 delete this.streamSinks[streamId]; 9466 break; 9467 default: 9468 throw new Error("Unexpected stream case"); 9469 } 9470 } 9471 async #deleteStreamController(streamController, streamId) { 9472 await Promise.allSettled([streamController.startCall?.promise, streamController.pullCall?.promise, streamController.cancelCall?.promise]); 9473 delete this.streamControllers[streamId]; 9474 } 9475 destroy() { 9476 this.comObj.removeEventListener("message", this._onComObjOnMessage); 9477 } 9478} 9479exports.MessageHandler = MessageHandler; 9480 9481/***/ }), 9482/* 16 */ 9483/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9484 9485 9486 9487Object.defineProperty(exports, "__esModule", ({ 9488 value: true 9489})); 9490exports.Metadata = void 0; 9491var _util = __w_pdfjs_require__(1); 9492class Metadata { 9493 #metadataMap; 9494 #data; 9495 constructor({ 9496 parsedData, 9497 rawData 9498 }) { 9499 this.#metadataMap = parsedData; 9500 this.#data = rawData; 9501 } 9502 getRaw() { 9503 return this.#data; 9504 } 9505 get(name) { 9506 return this.#metadataMap.get(name) ?? null; 9507 } 9508 getAll() { 9509 return (0, _util.objectFromMap)(this.#metadataMap); 9510 } 9511 has(name) { 9512 return this.#metadataMap.has(name); 9513 } 9514} 9515exports.Metadata = Metadata; 9516 9517/***/ }), 9518/* 17 */ 9519/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9520 9521 9522 9523Object.defineProperty(exports, "__esModule", ({ 9524 value: true 9525})); 9526exports.OptionalContentConfig = void 0; 9527var _util = __w_pdfjs_require__(1); 9528var _murmurhash = __w_pdfjs_require__(8); 9529const INTERNAL = Symbol("INTERNAL"); 9530class OptionalContentGroup { 9531 #visible = true; 9532 constructor(name, intent) { 9533 this.name = name; 9534 this.intent = intent; 9535 } 9536 get visible() { 9537 return this.#visible; 9538 } 9539 _setVisible(internal, visible) { 9540 if (internal !== INTERNAL) { 9541 (0, _util.unreachable)("Internal method `_setVisible` called."); 9542 } 9543 this.#visible = visible; 9544 } 9545} 9546class OptionalContentConfig { 9547 #cachedGetHash = null; 9548 #groups = new Map(); 9549 #initialHash = null; 9550 #order = null; 9551 constructor(data) { 9552 this.name = null; 9553 this.creator = null; 9554 if (data === null) { 9555 return; 9556 } 9557 this.name = data.name; 9558 this.creator = data.creator; 9559 this.#order = data.order; 9560 for (const group of data.groups) { 9561 this.#groups.set(group.id, new OptionalContentGroup(group.name, group.intent)); 9562 } 9563 if (data.baseState === "OFF") { 9564 for (const group of this.#groups.values()) { 9565 group._setVisible(INTERNAL, false); 9566 } 9567 } 9568 for (const on of data.on) { 9569 this.#groups.get(on)._setVisible(INTERNAL, true); 9570 } 9571 for (const off of data.off) { 9572 this.#groups.get(off)._setVisible(INTERNAL, false); 9573 } 9574 this.#initialHash = this.getHash(); 9575 } 9576 #evaluateVisibilityExpression(array) { 9577 const length = array.length; 9578 if (length < 2) { 9579 return true; 9580 } 9581 const operator = array[0]; 9582 for (let i = 1; i < length; i++) { 9583 const element = array[i]; 9584 let state; 9585 if (Array.isArray(element)) { 9586 state = this.#evaluateVisibilityExpression(element); 9587 } else if (this.#groups.has(element)) { 9588 state = this.#groups.get(element).visible; 9589 } else { 9590 (0, _util.warn)(`Optional content group not found: ${element}`); 9591 return true; 9592 } 9593 switch (operator) { 9594 case "And": 9595 if (!state) { 9596 return false;
9597 } 9598 break; 9599 case "Or": 9600 if (state) { 9601 return true; 9602 } 9603 break; 9604 case "Not": 9605 return !state; 9606 default: 9607 return true; 9608 } 9609 } 9610 return operator === "And"; 9611 } 9612 isVisible(group) { 9613 if (this.#groups.size === 0) { 9614 return true; 9615 } 9616 if (!group) { 9617 (0, _util.warn)("Optional content group not defined."); 9618 return true; 9619 } 9620 if (group.type === "OCG") { 9621 if (!this.#groups.has(group.id)) { 9622 (0, _util.warn)(`Optional content group not found: ${group.id}`); 9623 return true; 9624 } 9625 return this.#groups.get(group.id).visible; 9626 } else if (group.type === "OCMD") { 9627 if (group.expression) { 9628 return this.#evaluateVisibilityExpression(group.expression); 9629 } 9630 if (!group.policy || group.policy === "AnyOn") { 9631 for (const id of group.ids) { 9632 if (!this.#groups.has(id)) { 9633 (0, _util.warn)(`Optional content group not found: ${id}`); 9634 return true; 9635 } 9636 if (this.#groups.get(id).visible) { 9637 return true; 9638 } 9639 } 9640 return false; 9641 } else if (group.policy === "AllOn") { 9642 for (const id of group.ids) { 9643 if (!this.#groups.has(id)) { 9644 (0, _util.warn)(`Optional content group not found: ${id}`); 9645 return true; 9646 } 9647 if (!this.#groups.get(id).visible) { 9648 return false; 9649 } 9650 } 9651 return true; 9652 } else if (group.policy === "AnyOff") { 9653 for (const id of group.ids) { 9654 if (!this.#groups.has(id)) { 9655 (0, _util.warn)(`Optional content group not found: ${id}`); 9656 return true; 9657 } 9658 if (!this.#groups.get(id).visible) { 9659 return true; 9660 } 9661 } 9662 return false; 9663 } else if (group.policy === "AllOff") { 9664 for (const id of group.ids) { 9665 if (!this.#groups.has(id)) { 9666 (0, _util.warn)(`Optional content group not found: ${id}`); 9667 return true; 9668 } 9669 if (this.#groups.get(id).visible) { 9670 return false; 9671 } 9672 } 9673 return true; 9674 } 9675 (0, _util.warn)(`Unknown optional content policy ${group.policy}.`); 9676 return true; 9677 } 9678 (0, _util.warn)(`Unknown group type ${group.type}.`); 9679 return true; 9680 } 9681 setVisibility(id, visible = true) { 9682 if (!this.#groups.has(id)) { 9683 (0, _util.warn)(`Optional content group not found: ${id}`); 9684 return; 9685 } 9686 this.#groups.get(id)._setVisible(INTERNAL, !!visible); 9687 this.#cachedGetHash = null; 9688 } 9689 get hasInitialVisibility() { 9690 return this.#initialHash === null || this.getHash() === this.#initialHash; 9691 } 9692 getOrder() { 9693 if (!this.#groups.size) { 9694 return null; 9695 } 9696 if (this.#order) { 9697 return this.#order.slice(); 9698 } 9699 return [...this.#groups.keys()]; 9700 } 9701 getGroups() { 9702 return this.#groups.size > 0 ? (0, _util.objectFromMap)(this.#groups) : null; 9703 } 9704 getGroup(id) { 9705 return this.#groups.get(id) || null; 9706 } 9707 getHash() { 9708 if (this.#cachedGetHash !== null) { 9709 return this.#cachedGetHash; 9710 } 9711 const hash = new _murmurhash.MurmurHash3_64(); 9712 for (const [id, group] of this.#groups) { 9713 hash.update(`${id}:${group.visible}`); 9714 } 9715 return this.#cachedGetHash = hash.hexdigest(); 9716 } 9717} 9718exports.OptionalContentConfig = OptionalContentConfig; 9719 9720/***/ }), 9721/* 18 */ 9722/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9723 9724 9725 9726Object.defineProperty(exports, "__esModule", ({ 9727 value: true 9728})); 9729exports.PDFDataTransportStream = void 0; 9730var _util = __w_pdfjs_require__(1); 9731var _display_utils = __w_pdfjs_require__(6); 9732class PDFDataTransportStream { 9733 constructor({ 9734 length, 9735 initialData, 9736 progressiveDone = false, 9737 contentDispositionFilename = null, 9738 disableRange = false, 9739 disableStream = false 9740 }, pdfDataRangeTransport) { 9741 (0, _util.assert)(pdfDataRangeTransport, 'PDFDataTransportStream - missing required "pdfDataRangeTransport" argument.'); 9742 this._queuedChunks = []; 9743 this._progressiveDone = progressiveDone; 9744 this._contentDispositionFilename = contentDispositionFilename; 9745 if (initialData?.length > 0) { 9746 const buffer = initialData instanceof Uint8Array && initialData.byteLength === initialData.buffer.byteLength ? initialData.buffer : new Uint8Array(initialData).buffer; 9747 this._queuedChunks.push(buffer); 9748 } 9749 this._pdfDataRangeTransport = pdfDataRangeTransport; 9750 this._isStreamingSupported = !disableStream; 9751 this._isRangeSupported = !disableRange; 9752 this._contentLength = length; 9753 this._fullRequestReader = null; 9754 this._rangeReaders = []; 9755 this._pdfDataRangeTransport.addRangeListener((begin, chunk) => { 9756 this._onReceiveData({ 9757 begin, 9758 chunk 9759 }); 9760 }); 9761 this._pdfDataRangeTransport.addProgressListener((loaded, total) => { 9762 this._onProgress({ 9763 loaded, 9764 total 9765 }); 9766 }); 9767 this._pdfDataRangeTransport.addProgressiveReadListener(chunk => { 9768 this._onReceiveData({ 9769 chunk 9770 }); 9771 }); 9772 this._pdfDataRangeTransport.addProgressiveDoneListener(() => { 9773 this._onProgressiveDone(); 9774 }); 9775 this._pdfDataRangeTransport.transportReady(); 9776 } 9777 _onReceiveData({ 9778 begin, 9779 chunk 9780 }) { 9781 const buffer = chunk instanceof Uint8Array && chunk.byteLength === chunk.buffer.byteLength ? chunk.buffer : new Uint8Array(chunk).buffer; 9782 if (begin === undefined) { 9783 if (this._fullRequestReader) { 9784 this._fullRequestReader._enqueue(buffer); 9785 } else { 9786 this._queuedChunks.push(buffer); 9787 } 9788 } else { 9789 const found = this._rangeReaders.some(function (rangeReader) { 9790 if (rangeReader._begin !== begin) { 9791 return false;
9792 } 9793 rangeReader._enqueue(buffer); 9794 return true; 9795 }); 9796 (0, _util.assert)(found, "_onReceiveData - no `PDFDataTransportStreamRangeReader` instance found."); 9797 } 9798 } 9799 get _progressiveDataLength() { 9800 return this._fullRequestReader?._loaded ?? 0; 9801 } 9802 _onProgress(evt) { 9803 if (evt.total === undefined) { 9804 this._rangeReaders[0]?.onProgress?.({ 9805 loaded: evt.loaded 9806 }); 9807 } else { 9808 this._fullRequestReader?.onProgress?.({ 9809 loaded: evt.loaded, 9810 total: evt.total 9811 }); 9812 } 9813 } 9814 _onProgressiveDone() { 9815 this._fullRequestReader?.progressiveDone(); 9816 this._progressiveDone = true; 9817 } 9818 _removeRangeReader(reader) { 9819 const i = this._rangeReaders.indexOf(reader); 9820 if (i >= 0) { 9821 this._rangeReaders.splice(i, 1); 9822 } 9823 } 9824 getFullReader() { 9825 (0, _util.assert)(!this._fullRequestReader, "PDFDataTransportStream.getFullReader can only be called once."); 9826 const queuedChunks = this._queuedChunks; 9827 this._queuedChunks = null; 9828 return new PDFDataTransportStreamReader(this, queuedChunks, this._progressiveDone, this._contentDispositionFilename); 9829 } 9830 getRangeReader(begin, end) { 9831 if (end <= this._progressiveDataLength) { 9832 return null; 9833 } 9834 const reader = new PDFDataTransportStreamRangeReader(this, begin, end); 9835 this._pdfDataRangeTransport.requestDataRange(begin, end); 9836 this._rangeReaders.push(reader); 9837 return reader; 9838 } 9839 cancelAllRequests(reason) { 9840 this._fullRequestReader?.cancel(reason); 9841 for (const reader of this._rangeReaders.slice(0)) { 9842 reader.cancel(reason); 9843 } 9844 this._pdfDataRangeTransport.abort(); 9845 } 9846} 9847exports.PDFDataTransportStream = PDFDataTransportStream; 9848class PDFDataTransportStreamReader { 9849 constructor(stream, queuedChunks, progressiveDone = false, contentDispositionFilename = null) { 9850 this._stream = stream; 9851 this._done = progressiveDone || false; 9852 this._filename = (0, _display_utils.isPdfFile)(contentDispositionFilename) ? contentDispositionFilename : null; 9853 this._queuedChunks = queuedChunks || []; 9854 this._loaded = 0; 9855 for (const chunk of this._queuedChunks) { 9856 this._loaded += chunk.byteLength; 9857 } 9858 this._requests = []; 9859 this._headersReady = Promise.resolve(); 9860 stream._fullRequestReader = this; 9861 this.onProgress = null; 9862 } 9863 _enqueue(chunk) { 9864 if (this._done) { 9865 return; 9866 } 9867 if (this._requests.length > 0) { 9868 const requestCapability = this._requests.shift(); 9869 requestCapability.resolve({ 9870 value: chunk, 9871 done: false 9872 }); 9873 } else { 9874 this._queuedChunks.push(chunk); 9875 } 9876 this._loaded += chunk.byteLength; 9877 } 9878 get headersReady() { 9879 return this._headersReady; 9880 } 9881 get filename() { 9882 return this._filename; 9883 } 9884 get isRangeSupported() { 9885 return this._stream._isRangeSupported; 9886 } 9887 get isStreamingSupported() { 9888 return this._stream._isStreamingSupported; 9889 } 9890 get contentLength() { 9891 return this._stream._contentLength; 9892 } 9893 async read() { 9894 if (this._queuedChunks.length > 0) { 9895 const chunk = this._queuedChunks.shift(); 9896 return { 9897 value: chunk, 9898 done: false 9899 }; 9900 } 9901 if (this._done) { 9902 return { 9903 value: undefined, 9904 done: true 9905 }; 9906 } 9907 const requestCapability = new _util.PromiseCapability(); 9908 this._requests.push(requestCapability); 9909 return requestCapability.promise; 9910 } 9911 cancel(reason) { 9912 this._done = true; 9913 for (const requestCapability of this._requests) { 9914 requestCapability.resolve({ 9915 value: undefined, 9916 done: true 9917 }); 9918 } 9919 this._requests.length = 0; 9920 } 9921 progressiveDone() { 9922 if (this._done) { 9923 return; 9924 } 9925 this._done = true; 9926 } 9927} 9928class PDFDataTransportStreamRangeReader { 9929 constructor(stream, begin, end) { 9930 this._stream = stream; 9931 this._begin = begin; 9932 this._end = end; 9933 this._queuedChunk = null; 9934 this._requests = []; 9935 this._done = false; 9936 this.onProgress = null; 9937 } 9938 _enqueue(chunk) { 9939 if (this._done) { 9940 return; 9941 } 9942 if (this._requests.length === 0) { 9943 this._queuedChunk = chunk; 9944 } else { 9945 const requestsCapability = this._requests.shift(); 9946 requestsCapability.resolve({ 9947 value: chunk, 9948 done: false 9949 }); 9950 for (const requestCapability of this._requests) { 9951 requestCapability.resolve({ 9952 value: undefined, 9953 done: true 9954 }); 9955 } 9956 this._requests.length = 0; 9957 } 9958 this._done = true; 9959 this._stream._removeRangeReader(this); 9960 } 9961 get isStreamingSupported() { 9962 return false;
9963 } 9964 async read() { 9965 if (this._queuedChunk) { 9966 const chunk = this._queuedChunk; 9967 this._queuedChunk = null; 9968 return { 9969 value: chunk, 9970 done: false 9971 }; 9972 } 9973 if (this._done) { 9974 return { 9975 value: undefined, 9976 done: true 9977 }; 9978 } 9979 const requestCapability = new _util.PromiseCapability(); 9980 this._requests.push(requestCapability); 9981 return requestCapability.promise; 9982 } 9983 cancel(reason) { 9984 this._done = true; 9985 for (const requestCapability of this._requests) { 9986 requestCapability.resolve({ 9987 value: undefined, 9988 done: true 9989 }); 9990 } 9991 this._requests.length = 0; 9992 this._stream._removeRangeReader(this); 9993 } 9994} 9995 9996/***/ }), 9997/* 19 */ 9998/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9999 10000 10001 10002Object.defineProperty(exports, "__esModule", ({ 10003 value: true 10004})); 10005exports.PDFFetchStream = void 0; 10006var _util = __w_pdfjs_require__(1); 10007var _network_utils = __w_pdfjs_require__(20); 10008; 10009function createFetchOptions(headers, withCredentials, abortController) { 10010 return { 10011 method: "GET", 10012 headers, 10013 signal: abortController.signal, 10014 mode: "cors", 10015 credentials: withCredentials ? "include" : "same-origin", 10016 redirect: "follow" 10017 }; 10018} 10019function createHeaders(httpHeaders) { 10020 const headers = new Headers(); 10021 for (const property in httpHeaders) { 10022 const value = httpHeaders[property]; 10023 if (value === undefined) { 10024 continue; 10025 } 10026 headers.append(property, value); 10027 } 10028 return headers; 10029} 10030function getArrayBuffer(val) { 10031 if (val instanceof Uint8Array) { 10032 return val.buffer; 10033 } 10034 if (val instanceof ArrayBuffer) { 10035 return val; 10036 } 10037 (0, _util.warn)(`getArrayBuffer - unexpected data format: ${val}`); 10038 return new Uint8Array(val).buffer; 10039} 10040class PDFFetchStream { 10041 constructor(source) { 10042 this.source = source; 10043 this.isHttp = /^https?:/i.test(source.url); 10044 this.httpHeaders = this.isHttp && source.httpHeaders || {}; 10045 this._fullRequestReader = null; 10046 this._rangeRequestReaders = []; 10047 } 10048 get _progressiveDataLength() { 10049 return this._fullRequestReader?._loaded ?? 0; 10050 } 10051 getFullReader() { 10052 (0, _util.assert)(!this._fullRequestReader, "PDFFetchStream.getFullReader can only be called once."); 10053 this._fullRequestReader = new PDFFetchStreamReader(this); 10054 return this._fullRequestReader; 10055 } 10056 getRangeReader(begin, end) { 10057 if (end <= this._progressiveDataLength) { 10058 return null; 10059 } 10060 const reader = new PDFFetchStreamRangeReader(this, begin, end); 10061 this._rangeRequestReaders.push(reader); 10062 return reader; 10063 } 10064 cancelAllRequests(reason) { 10065 this._fullRequestReader?.cancel(reason); 10066 for (const reader of this._rangeRequestReaders.slice(0)) { 10067 reader.cancel(reason); 10068 } 10069 } 10070} 10071exports.PDFFetchStream = PDFFetchStream; 10072class PDFFetchStreamReader { 10073 constructor(stream) { 10074 this._stream = stream; 10075 this._reader = null; 10076 this._loaded = 0; 10077 this._filename = null; 10078 const source = stream.source; 10079 this._withCredentials = source.withCredentials || false; 10080 this._contentLength = source.length; 10081 this._headersCapability = new _util.PromiseCapability(); 10082 this._disableRange = source.disableRange || false; 10083 this._rangeChunkSize = source.rangeChunkSize; 10084 if (!this._rangeChunkSize && !this._disableRange) { 10085 this._disableRange = true; 10086 } 10087 this._abortController = new AbortController(); 10088 this._isStreamingSupported = !source.disableStream; 10089 this._isRangeSupported = !source.disableRange; 10090 this._headers = createHeaders(this._stream.httpHeaders); 10091 const url = source.url; 10092 fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(response => { 10093 if (!(0, _network_utils.validateResponseStatus)(response.status)) { 10094 throw (0, _network_utils.createResponseStatusError)(response.status, url); 10095 } 10096 this._reader = response.body.getReader(); 10097 this._headersCapability.resolve(); 10098 const getResponseHeader = name => { 10099 return response.headers.get(name); 10100 }; 10101 const { 10102 allowRangeRequests, 10103 suggestedLength 10104 } = (0, _network_utils.validateRangeRequestCapabilities)({ 10105 getResponseHeader, 10106 isHttp: this._stream.isHttp, 10107 rangeChunkSize: this._rangeChunkSize, 10108 disableRange: this._disableRange 10109 }); 10110 this._isRangeSupported = allowRangeRequests; 10111 this._contentLength = suggestedLength || this._contentLength; 10112 this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader); 10113 if (!this._isStreamingSupported && this._isRangeSupported) { 10114 this.cancel(new _util.AbortException("Streaming is disabled.")); 10115 } 10116 }).catch(this._headersCapability.reject); 10117 this.onProgress = null; 10118 } 10119 get headersReady() { 10120 return this._headersCapability.promise; 10121 } 10122 get filename() { 10123 return this._filename; 10124 } 10125 get contentLength() { 10126 return this._contentLength; 10127 } 10128 get isRangeSupported() { 10129 return this._isRangeSupported; 10130 } 10131 get isStreamingSupported() { 10132 return this._isStreamingSupported; 10133 } 10134 async read() { 10135 await this._headersCapability.promise; 10136 const { 10137 value, 10138 done 10139 } = await this._reader.read(); 10140 if (done) { 10141 return { 10142 value, 10143 done 10144 }; 10145 } 10146 this._loaded += value.byteLength; 10147 this.onProgress?.({ 10148 loaded: this._loaded, 10149 total: this._contentLength 10150 }); 10151 return { 10152 value: getArrayBuffer(value), 10153 done: false 10154 }; 10155 } 10156 cancel(reason) { 10157 this._reader?.cancel(reason); 10158 this._abortController.abort(); 10159 } 10160} 10161class PDFFetchStreamRangeReader { 10162 constructor(stream, begin, end) { 10163 this._stream = stream; 10164 this._reader = null; 10165 this._loaded = 0; 10166 const source = stream.source; 10167 this._withCredentials = source.withCredentials || false; 10168 this._readCapability = new _util.PromiseCapability(); 10169 this._isStreamingSupported = !source.disableStream; 10170 this._abortController = new AbortController(); 10171 this._headers = createHeaders(this._stream.httpHeaders); 10172 this._headers.append("Range", `bytes=${begin}
10172-${end - 1}`); 10173 const url = source.url; 10174 fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(response => { 10175 if (!(0, _network_utils.validateResponseStatus)(response.status)) { 10176 throw (0, _network_utils.createResponseStatusError)(response.status, url); 10177 } 10178 this._readCapability.resolve(); 10179 this._reader = response.body.getReader(); 10180 }).catch(this._readCapability.reject); 10181 this.onProgress = null; 10182 } 10183 get isStreamingSupported() { 10184 return this._isStreamingSupported; 10185 } 10186 async read() { 10187 await this._readCapability.promise; 10188 const { 10189 value, 10190 done 10191 } = await this._reader.read(); 10192 if (done) { 10193 return { 10194 value, 10195 done 10196 }; 10197 } 10198 this._loaded += value.byteLength; 10199 this.onProgress?.({ 10200 loaded: this._loaded 10201 }); 10202 return { 10203 value: getArrayBuffer(value), 10204 done: false 10205 }; 10206 } 10207 cancel(reason) { 10208 this._reader?.cancel(reason); 10209 this._abortController.abort(); 10210 } 10211} 10212 10213/***/ }), 10214/* 20 */ 10215/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 10216 10217 10218 10219Object.defineProperty(exports, "__esModule", ({ 10220 value: true 10221})); 10222exports.createResponseStatusError = createResponseStatusError; 10223exports.extractFilenameFromHeader = extractFilenameFromHeader; 10224exports.validateRangeRequestCapabilities = validateRangeRequestCapabilities; 10225exports.validateResponseStatus = validateResponseStatus; 10226var _util = __w_pdfjs_require__(1); 10227var _content_disposition = __w_pdfjs_require__(21); 10228var _display_utils = __w_pdfjs_require__(6); 10229function validateRangeRequestCapabilities({ 10230 getResponseHeader, 10231 isHttp, 10232 rangeChunkSize, 10233 disableRange 10234}) { 10235 const returnValues = { 10236 allowRangeRequests: false, 10237 suggestedLength: undefined 10238 }; 10239 const length = parseInt(getResponseHeader("Content-Length"), 10); 10240 if (!Number.isInteger(length)) { 10241 return returnValues; 10242 } 10243 returnValues.suggestedLength = length; 10244 if (length <= 2 * rangeChunkSize) { 10245 return returnValues; 10246 } 10247 if (disableRange || !isHttp) { 10248 return returnValues; 10249 } 10250 if (getResponseHeader("Accept-Ranges") !== "bytes") { 10251 return returnValues; 10252 } 10253 const contentEncoding = getResponseHeader("Content-Encoding") || "identity"; 10254 if (contentEncoding !== "identity") { 10255 return returnValues; 10256 } 10257 returnValues.allowRangeRequests = true; 10258 return returnValues; 10259} 10260function extractFilenameFromHeader(getResponseHeader) { 10261 const contentDisposition = getResponseHeader("Content-Disposition"); 10262 if (contentDisposition) { 10263 let filename = (0, _content_disposition.getFilenameFromContentDispositionHeader)(contentDisposition); 10264 if (filename.includes("%")) { 10265 try { 10266 filename = decodeURIComponent(filename); 10267 } catch {} 10268 } 10269 if ((0, _display_utils.isPdfFile)(filename)) { 10270 return filename; 10271 } 10272 } 10273 return null; 10274} 10275function createResponseStatusError(status, url) { 10276 if (status === 404 || status === 0 && url.startsWith("file:")) { 10277 return new _util.MissingPDFException('Missing PDF "' + url + '".'); 10278 } 10279 return new _util.UnexpectedResponseException(`Unexpected server response (${status}) while retrieving PDF "${url}".`, status); 10280} 10281function validateResponseStatus(status) { 10282 return status === 200 || status === 206; 10283} 10284 10285/***/ }), 10286/* 21 */ 10287/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 10288 10289 10290 10291Object.defineProperty(exports, "__esModule", ({ 10292 value: true 10293})); 10294exports.getFilenameFromContentDispositionHeader = getFilenameFromContentDispositionHeader; 10295var _util = __w_pdfjs_require__(1); 10296function getFilenameFromContentDispositionHeader(contentDisposition) { 10297 let needsEncodingFixup = true; 10298 let tmp = toParamRegExp("filename\\*", "i").exec(contentDisposition); 10299 if (tmp) { 10300 tmp = tmp[1]; 10301 let filename = rfc2616unquote(tmp); 10302 filename = unescape(filename); 10303 filename = rfc5987decode(filename); 10304 filename = rfc2047decode(filename); 10305 return fixupEncoding(filename); 10306 } 10307 tmp = rfc2231getparam(contentDisposition); 10308 if (tmp) { 10309 const filename = rfc2047decode(tmp); 10310 return fixupEncoding(filename); 10311 } 10312 tmp = toParamRegExp("filename", "i").exec(contentDisposition); 10313 if (tmp) { 10314 tmp = tmp[1]; 10315 let filename = rfc2616unquote(tmp); 10316 filename = rfc2047decode(filename); 10317 return fixupEncoding(filename); 10318 } 10319 function toParamRegExp(attributePattern, flags) { 10320 return new RegExp("(?:^|;)\\s*" + attributePattern + "\\s*=\\s*" + "(" + '[^";\\s][^;\\s]*' + "|" + '"(?:[^"\\\\]|\\\\"?)+"?' + ")", flags); 10321 } 10322 function textdecode(encoding, value) { 10323 if (encoding) { 10324 if (!/^[\x00-\xFF]+$/.test(value)) { 10325 return value; 10326 }
10327 try { 10328 const decoder = new TextDecoder(encoding, { 10329 fatal: true 10330 }); 10331 const buffer = (0, _util.stringToBytes)(value); 10332 value = decoder.decode(buffer); 10333 needsEncodingFixup = false; 10334 } catch {} 10335 } 10336 return value; 10337 } 10338 function fixupEncoding(value) { 10339 if (needsEncodingFixup && /[\x80-\xff]/.test(value)) { 10340 value = textdecode("utf-8", value); 10341 if (needsEncodingFixup) { 10342 value = textdecode("iso-8859-1", value); 10343 } 10344 } 10345 return value; 10346 } 10347 function rfc2231getparam(contentDispositionStr) { 10348 const matches = []; 10349 let match; 10350 const iter = toParamRegExp("filename\\*((?!0\\d)\\d+)(\\*?)", "ig"); 10351 while ((match = iter.exec(contentDispositionStr)) !== null) { 10352 let [, n, quot, part] = match; 10353 n = parseInt(n, 10); 10354 if (n in matches) { 10355 if (n === 0) { 10356 break; 10357 } 10358 continue; 10359 } 10360 matches[n] = [quot, part]; 10361 } 10362 const parts = []; 10363 for (let n = 0; n < matches.length; ++n) { 10364 if (!(n in matches)) { 10365 break; 10366 } 10367 let [quot, part] = matches[n]; 10368 part = rfc2616unquote(part); 10369 if (quot) { 10370 part = unescape(part); 10371 if (n === 0) { 10372 part = rfc5987decode(part); 10373 } 10374 } 10375 parts.push(part); 10376 } 10377 return parts.join(""); 10378 } 10379 function rfc2616unquote(value) { 10380 if (value.startsWith('"')) { 10381 const parts = value.slice(1).split('\\"'); 10382 for (let i = 0; i < parts.length; ++i) { 10383 const quotindex = parts[i].indexOf('"'); 10384 if (quotindex !== -1) { 10385 parts[i] = parts[i].slice(0, quotindex); 10386 parts.length = i + 1; 10387 } 10388 parts[i] = parts[i].replaceAll(/\\(.)/g, "$1"); 10389 } 10390 value = parts.join('"'); 10391 } 10392 return value; 10393 } 10394 function rfc5987decode(extvalue) { 10395 const encodingend = extvalue.indexOf("'"); 10396 if (encodingend === -1) { 10397 return extvalue; 10398 } 10399 const encoding = extvalue.slice(0, encodingend); 10400 const langvalue = extvalue.slice(encodingend + 1); 10401 const value = langvalue.replace(/^[^']*'/, ""); 10402 return textdecode(encoding, value); 10403 } 10404 function rfc2047decode(value) { 10405 if (!value.startsWith("=?") || /[\x00-\x19\x80-\xff]/.test(value)) { 10406 return value; 10407 } 10408 return value.replaceAll(/=\?([\w-]*)\?([QqBb])\?((?:[^?]|\?(?!=))*)\?=/g, function (matches, charset, encoding, text) { 10409 if (encoding === "q" || encoding === "Q") { 10410 text = text.replaceAll("_", " "); 10411 text = text.replaceAll(/=([0-9a-fA-F]{2})/g, function (match, hex) { 10412 return String.fromCharCode(parseInt(hex, 16)); 10413 }); 10414 return textdecode(charset, text); 10415 } 10416 try { 10417 text = atob(text); 10418 } catch {} 10419 return textdecode(charset, text); 10420 }); 10421 } 10422 return ""; 10423} 10424 10425/***/ }), 10426/* 22 */ 10427/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 10428 10429 10430 10431Object.defineProperty(exports, "__esModule", ({ 10432 value: true 10433})); 10434exports.PDFNetworkStream = void 0; 10435var _util = __w_pdfjs_require__(1); 10436var _network_utils = __w_pdfjs_require__(20); 10437; 10438const OK_RESPONSE = 200; 10439const PARTIAL_CONTENT_RESPONSE = 206; 10440function getArrayBuffer(xhr) { 10441 const data = xhr.response; 10442 if (typeof data !== "string") { 10443 return data; 10444 } 10445 return (0, _util.stringToBytes)(data).buffer; 10446} 10447class NetworkManager { 10448 constructor(url, args = {}) { 10449 this.url = url; 10450 this.isHttp = /^https?:/i.test(url); 10451 this.httpHeaders = this.isHttp && args.httpHeaders || Object.create(null); 10452 this.withCredentials = args.withCredentials || false; 10453 this.currXhrId = 0; 10454 this.pendingRequests = Object.create(null); 10455 } 10456 requestRange(begin, end, listeners) { 10457 const args = { 10458 begin, 10459 end 10460 }; 10461 for (const prop in listeners) { 10462 args[prop] = listeners[prop]; 10463 } 10464 return this.request(args); 10465 } 10466 requestFull(listeners) { 10467 return this.request(listeners); 10468 } 10469 request(args) { 10470 const xhr = new XMLHttpRequest(); 10471 const xhrId = this.currXhrId++; 10472 const pendingRequest = this.pendingRequests[xhrId] = { 10473 xhr 10474 }; 10475 xhr.open("GET", this.url); 10476 xhr.withCredentials = this.withCredentials; 10477 for (const property in this.httpHeaders) { 10478 const value = this.httpHeaders[property]; 10479 if (value === undefined) { 10480 continue; 10481 } 10482 xhr.setRequestHeader(property, value); 10483 } 10484 if (this.isHttp && "begin" in args && "end" in args) { 10485 xhr.setRequestHeader("Range", `bytes=${args.begin}-${args.end - 1}`); 10486 pendingRequest.expectedStatus = PARTIAL_CONTENT_RESPONSE; 10487 } else { 10488 pendingRequest.expectedStatus = OK_RESPONSE; 10489 } 10490 xhr.responseType = "arraybuffer"; 10491 if (args.onError) { 10492 xhr.onerror = function (evt) { 10493 args.onError(xhr.status); 10494 }; 10495 } 10496 xhr.onreadystatechange = this.onStateChange.bind(this, xhrId); 10497 xhr.onprogress = this.onProgress.bind(this, xhrId); 10498 pendingRequest.onHeadersReceived = args.onHeadersReceived; 10499 pendingRequest.onDone = args.onDone; 10500 pendingRequest.onError = args.onError; 10501 pendingRequest.onProgress = args.onProgress; 10502 xhr.send(null); 10503 return xhrId; 10504 } 10505 onProgress(xhrId, evt) { 10506 const pendingRequest = this.pendingRequests[xhrId]; 10507 if (!pendingRequest) { 10508 return; 10509 } 10510 pendingRequest.onProgress?.(evt); 10511 } 10512 onStateChange(xhrId, evt) { 10513 const pendingRequest = this.pendingRequests[xhrId]; 10514 if (!pendingRequest) { 10515 return; 10516 } 10517 const xhr = pendingRequest.xhr; 10518 if (xhr.readyState >= 2 && pendingRequest.onHeadersReceived) { 10519 pendingRequest.onHeadersReceived();
10520 delete pendingRequest.onHeadersReceived; 10521 } 10522 if (xhr.readyState !== 4) { 10523 return; 10524 } 10525 if (!(xhrId in this.pendingRequests)) { 10526 return; 10527 } 10528 delete this.pendingRequests[xhrId]; 10529 if (xhr.status === 0 && this.isHttp) { 10530 pendingRequest.onError?.(xhr.status); 10531 return; 10532 } 10533 const xhrStatus = xhr.status || OK_RESPONSE; 10534 const ok_response_on_range_request = xhrStatus === OK_RESPONSE && pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE; 10535 if (!ok_response_on_range_request && xhrStatus !== pendingRequest.expectedStatus) { 10536 pendingRequest.onError?.(xhr.status); 10537 return; 10538 } 10539 const chunk = getArrayBuffer(xhr); 10540 if (xhrStatus === PARTIAL_CONTENT_RESPONSE) { 10541 const rangeHeader = xhr.getResponseHeader("Content-Range"); 10542 const matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader); 10543 pendingRequest.onDone({ 10544 begin: parseInt(matches[1], 10), 10545 chunk 10546 }); 10547 } else if (chunk) { 10548 pendingRequest.onDone({ 10549 begin: 0, 10550 chunk 10551 }); 10552 } else { 10553 pendingRequest.onError?.(xhr.status); 10554 } 10555 } 10556 getRequestXhr(xhrId) { 10557 return this.pendingRequests[xhrId].xhr; 10558 } 10559 isPendingRequest(xhrId) { 10560 return xhrId in this.pendingRequests; 10561 } 10562 abortRequest(xhrId) { 10563 const xhr = this.pendingRequests[xhrId].xhr; 10564 delete this.pendingRequests[xhrId]; 10565 xhr.abort(); 10566 } 10567} 10568class PDFNetworkStream { 10569 constructor(source) { 10570 this._source = source; 10571 this._manager = new NetworkManager(source.url, { 10572 httpHeaders: source.httpHeaders, 10573 withCredentials: source.withCredentials 10574 }); 10575 this._rangeChunkSize = source.rangeChunkSize; 10576 this._fullRequestReader = null; 10577 this._rangeRequestReaders = []; 10578 } 10579 _onRangeRequestReaderClosed(reader) { 10580 const i = this._rangeRequestReaders.indexOf(reader); 10581 if (i >= 0) { 10582 this._rangeRequestReaders.splice(i, 1); 10583 } 10584 } 10585 getFullReader() { 10586 (0, _util.assert)(!this._fullRequestReader, "PDFNetworkStream.getFullReader can only be called once."); 10587 this._fullRequestReader = new PDFNetworkStreamFullRequestReader(this._manager, this._source); 10588 return this._fullRequestReader; 10589 } 10590 getRangeReader(begin, end) { 10591 const reader = new PDFNetworkStreamRangeRequestReader(this._manager, begin, end); 10592 reader.onClosed = this._onRangeRequestReaderClosed.bind(this); 10593 this._rangeRequestReaders.push(reader); 10594 return reader; 10595 } 10596 cancelAllRequests(reason) { 10597 this._fullRequestReader?.cancel(reason); 10598 for (const reader of this._rangeRequestReaders.slice(0)) { 10599 reader.cancel(reason); 10600 } 10601 } 10602} 10603exports.PDFNetworkStream = PDFNetworkStream; 10604class PDFNetworkStreamFullRequestReader { 10605 constructor(manager, source) { 10606 this._manager = manager; 10607 const args = { 10608 onHeadersReceived: this._onHeadersReceived.bind(this), 10609 onDone: this._onDone.bind(this), 10610 onError: this._onError.bind(this), 10611 onProgress: this._onProgress.bind(this) 10612 }; 10613 this._url = source.url; 10614 this._fullRequestId = manager.requestFull(args); 10615 this._headersReceivedCapability = new _util.PromiseCapability(); 10616 this._disableRange = source.disableRange || false; 10617 this._contentLength = source.length; 10618 this._rangeChunkSize = source.rangeChunkSize; 10619 if (!this._rangeChunkSize && !this._disableRange) { 10620 this._disableRange = true; 10621 } 10622 this._isStreamingSupported = false; 10623 this._isRangeSupported = false; 10624 this._cachedChunks = []; 10625 this._requests = []; 10626 this._done = false; 10627 this._storedError = undefined; 10628 this._filename = null; 10629 this.onProgress = null; 10630 } 10631 _onHeadersReceived() { 10632 const fullRequestXhrId = this._fullRequestId; 10633 const fullRequestXhr = this._manager.getRequestXhr(fullRequestXhrId); 10634 const getResponseHeader = name => { 10635 return fullRequestXhr.getResponseHeader(name); 10636 }; 10637 const { 10638 allowRangeRequests, 10639 suggestedLength 10640 } = (0, _network_utils.validateRangeRequestCapabilities)({ 10641 getResponseHeader, 10642 isHttp: this._manager.isHttp, 10643 rangeChunkSize: this._rangeChunkSize, 10644 disableRange: this._disableRange 10645 }); 10646 if (allowRangeRequests) { 10647 this._isRangeSupported = true; 10648 } 10649 this._contentLength = suggestedLength || this._contentLength; 10650 this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader); 10651 if (this._isRangeSupported) {
10652 this._manager.abortRequest(fullRequestXhrId); 10653 } 10654 this._headersReceivedCapability.resolve(); 10655 } 10656 _onDone(data) { 10657 if (data) { 10658 if (this._requests.length > 0) { 10659 const requestCapability = this._requests.shift(); 10660 requestCapability.resolve({ 10661 value: data.chunk, 10662 done: false 10663 }); 10664 } else { 10665 this._cachedChunks.push(data.chunk); 10666 } 10667 } 10668 this._done = true; 10669 if (this._cachedChunks.length > 0) { 10670 return; 10671 } 10672 for (const requestCapability of this._requests) { 10673 requestCapability.resolve({ 10674 value: undefined, 10675 done: true 10676 }); 10677 } 10678 this._requests.length = 0; 10679 } 10680 _onError(status) { 10681 this._storedError = (0, _network_utils.createResponseStatusError)(status, this._url); 10682 this._headersReceivedCapability.reject(this._storedError); 10683 for (const requestCapability of this._requests) { 10684 requestCapability.reject(this._storedError); 10685 } 10686 this._requests.length = 0; 10687 this._cachedChunks.length = 0; 10688 } 10689 _onProgress(evt) { 10690 this.onProgress?.({ 10691 loaded: evt.loaded, 10692 total: evt.lengthComputable ? evt.total : this._contentLength 10693 }); 10694 } 10695 get filename() { 10696 return this._filename; 10697 } 10698 get isRangeSupported() { 10699 return this._isRangeSupported; 10700 } 10701 get isStreamingSupported() { 10702 return this._isStreamingSupported; 10703 } 10704 get contentLength() { 10705 return this._contentLength; 10706 } 10707 get headersReady() { 10708 return this._headersReceivedCapability.promise; 10709 } 10710 async read() { 10711 if (this._storedError) { 10712 throw this._storedError; 10713 } 10714 if (this._cachedChunks.length > 0) { 10715 const chunk = this._cachedChunks.shift(); 10716 return { 10717 value: chunk, 10718 done: false 10719 }; 10720 } 10721 if (this._done) { 10722 return { 10723 value: undefined, 10724 done: true 10725 }; 10726 } 10727 const requestCapability = new _util.PromiseCapability(); 10728 this._requests.push(requestCapability); 10729 return requestCapability.promise; 10730 } 10731 cancel(reason) { 10732 this._done = true; 10733 this._headersReceivedCapability.reject(reason); 10734 for (const requestCapability of this._requests) { 10735 requestCapability.resolve({ 10736 value: undefined, 10737 done: true 10738 }); 10739 } 10740 this._requests.length = 0; 10741 if (this._manager.isPendingRequest(this._fullRequestId)) { 10742 this._manager.abortRequest(this._fullRequestId); 10743 } 10744 this._fullRequestReader = null; 10745 } 10746} 10747class PDFNetworkStreamRangeRequestReader { 10748 constructor(manager, begin, end) { 10749 this._manager = manager; 10750 const args = { 10751 onDone: this._onDone.bind(this), 10752 onError: this._onError.bind(this), 10753 onProgress: this._onProgress.bind(this) 10754 }; 10755 this._url = manager.url; 10756 this._requestId = manager.requestRange(begin, end, args); 10757 this._requests = []; 10758 this._queuedChunk = null; 10759 this._done = false; 10760 this._storedError = undefined; 10761 this.onProgress = null; 10762 this.onClosed = null; 10763 } 10764 _close() { 10765 this.onClosed?.(this); 10766 } 10767 _onDone(data) { 10768 const chunk = data.chunk; 10769 if (this._requests.length > 0) { 10770 const requestCapability = this._requests.shift(); 10771 requestCapability.resolve({ 10772 value: chunk, 10773 done: false 10774 }); 10775 } else { 10776 this._queuedChunk = chunk; 10777 } 10778 this._done = true; 10779 for (const requestCapability of this._requests) { 10780 requestCapability.resolve({ 10781 value: undefined, 10782 done: true 10783 }); 10784 } 10785 this._requests.length = 0; 10786 this._close(); 10787 } 10788 _onError(status) { 10789 this._storedError = (0, _network_utils.createResponseStatusError)(status, this._url); 10790 for (const requestCapability of this._requests) { 10791 requestCapability.reject(this._storedError); 10792 } 10793 this._requests.length = 0; 10794 this._queuedChunk = null; 10795 } 10796 _onProgress(evt) { 10797 if (!this.isStreamingSupported) { 10798 this.onProgress?.({ 10799 loaded: evt.loaded 10800 }); 10801 } 10802 } 10803 get isStreamingSupported() { 10804 return false; 10805 } 10806 async read() { 10807 if (this._storedError) { 10808 throw this._storedError; 10809 } 10810 if (this._queuedChunk !== null) { 10811 const chunk = this._queuedChunk; 10812 this._queuedChunk = null; 10813 return { 10814 value: chunk, 10815 done: false 10816 }; 10817 } 10818 if (this._done) { 10819 return { 10820 value: undefined, 10821 done: true 10822 }; 10823 } 10824 const requestCapability = new _util.PromiseCapability(); 10825 this._requests.push(requestCapability); 10826 return requestCapability.promise; 10827 } 10828 cancel(reason) { 10829 this._done = true; 10830 for (const requestCapability of this._requests) { 10831 requestCapability.resolve({ 10832 value: undefined, 10833 done: true 10834 }); 10835 } 10836 this._requests.length = 0; 10837 if (this._manager.isPendingRequest(this._requestId)) {
10838 this._manager.abortRequest(this._requestId); 10839 } 10840 this._close(); 10841 } 10842} 10843 10844/***/ }), 10845/* 23 */ 10846/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 10847 10848 10849 10850Object.defineProperty(exports, "__esModule", ({ 10851 value: true 10852})); 10853exports.PDFNodeStream = void 0; 10854var _util = __w_pdfjs_require__(1); 10855var _network_utils = __w_pdfjs_require__(20); 10856; 10857const fileUriRegex = /^file:\/\/\/[a-zA-Z]:\//; 10858function parseUrl(sourceUrl) { 10859 const url = require("url"); 10860 const parsedUrl = url.parse(sourceUrl); 10861 if (parsedUrl.protocol === "file:" || parsedUrl.host) { 10862 return parsedUrl; 10863 } 10864 if (/^[a-z]:[/\\]/i.test(sourceUrl)) { 10865 return url.parse(`file:///${sourceUrl}`); 10866 } 10867 if (!parsedUrl.host) { 10868 parsedUrl.protocol = "file:"; 10869 } 10870 return parsedUrl; 10871} 10872class PDFNodeStream { 10873 constructor(source) { 10874 this.source = source; 10875 this.url = parseUrl(source.url); 10876 this.isHttp = this.url.protocol === "http:" || this.url.protocol === "https:"; 10877 this.isFsUrl = this.url.protocol === "file:"; 10878 this.httpHeaders = this.isHttp && source.httpHeaders || {}; 10879 this._fullRequestReader = null; 10880 this._rangeRequestReaders = []; 10881 } 10882 get _progressiveDataLength() { 10883 return this._fullRequestReader?._loaded ?? 0; 10884 } 10885 getFullReader() { 10886 (0, _util.assert)(!this._fullRequestReader, "PDFNodeStream.getFullReader can only be called once."); 10887 this._fullRequestReader = this.isFsUrl ? new PDFNodeStreamFsFullReader(this) : new PDFNodeStreamFullReader(this); 10888 return this._fullRequestReader; 10889 } 10890 getRangeReader(start, end) { 10891 if (end <= this._progressiveDataLength) { 10892 return null; 10893 } 10894 const rangeReader = this.isFsUrl ? new PDFNodeStreamFsRangeReader(this, start, end) : new PDFNodeStreamRangeReader(this, start, end); 10895 this._rangeRequestReaders.push(rangeReader); 10896 return rangeReader; 10897 } 10898 cancelAllRequests(reason) { 10899 this._fullRequestReader?.cancel(reason); 10900 for (const reader of this._rangeRequestReaders.slice(0)) { 10901 reader.cancel(reason); 10902 } 10903 } 10904} 10905exports.PDFNodeStream = PDFNodeStream; 10906class BaseFullReader { 10907 constructor(stream) { 10908 this._url = stream.url; 10909 this._done = false; 10910 this._storedError = null; 10911 this.onProgress = null; 10912 const source = stream.source; 10913 this._contentLength = source.length; 10914 this._loaded = 0; 10915 this._filename = null; 10916 this._disableRange = source.disableRange || false; 10917 this._rangeChunkSize = source.rangeChunkSize; 10918 if (!this._rangeChunkSize && !this._disableRange) { 10919 this._disableRange = true; 10920 } 10921 this._isStreamingSupported = !source.disableStream; 10922 this._isRangeSupported = !source.disableRange; 10923 this._readableStream = null; 10924 this._readCapability = new _util.PromiseCapability(); 10925 this._headersCapability = new _util.PromiseCapability(); 10926 } 10927 get headersReady() { 10928 return this._headersCapability.promise; 10929 } 10930 get filename() { 10931 return this._filename; 10932 } 10933 get contentLength() { 10934 return this._contentLength; 10935 } 10936 get isRangeSupported() { 10937 return this._isRangeSupported; 10938 } 10939 get isStreamingSupported() { 10940 return this._isStreamingSupported; 10941 } 10942 async read() { 10943 await this._readCapability.promise; 10944 if (this._done) { 10945 return { 10946 value: undefined, 10947 done: true 10948 }; 10949 } 10950 if (this._storedError) { 10951 throw this._storedError; 10952 } 10953 const chunk = this._readableStream.read(); 10954 if (chunk === null) { 10955 this._readCapability = new _util.PromiseCapability(); 10956 return this.read(); 10957 } 10958 this._loaded += chunk.length; 10959 this.onProgress?.({ 10960 loaded: this._loaded, 10961 total: this._contentLength 10962 }); 10963 const buffer = new Uint8Array(chunk).buffer; 10964 return { 10965 value: buffer, 10966 done: false 10967 }; 10968 } 10969 cancel(reason) { 10970 if (!this._readableStream) { 10971 this._error(reason); 10972 return; 10973 } 10974 this._readableStream.destroy(reason); 10975 } 10976 _error(reason) { 10977 this._storedError = reason; 10978 this._readCapability.resolve(); 10979 } 10980 _setReadableStream(readableStream) { 10981 this._readableStream = readableStream; 10982 readableStream.on("readable", () => { 10983 this._readCapability.resolve(); 10984 }); 10985 readableStream.on("end", () => { 10986 readableStream.destroy(); 10987 this._done = true; 10988 this._readCapability.resolve(); 10989 }); 10990 readableStream.on("error", reason => { 10991 this._error(reason); 10992 }); 10993 if (!this._isStreamingSupported && this._isRangeSupported) { 10994 this._error(new _util.AbortException("streaming is disabled")); 10995 } 10996 if (this._storedError) { 10997 this._readableStream.destroy(this._storedError); 10998 } 10999 } 11000} 11001class BaseRangeReader { 11002 constructor(stream) { 11003 this._url = stream.url; 11004 this._done = false;
11005 this._storedError = null; 11006 this.onProgress = null; 11007 this._loaded = 0; 11008 this._readableStream = null; 11009 this._readCapability = new _util.PromiseCapability(); 11010 const source = stream.source; 11011 this._isStreamingSupported = !source.disableStream; 11012 } 11013 get isStreamingSupported() { 11014 return this._isStreamingSupported; 11015 } 11016 async read() { 11017 await this._readCapability.promise; 11018 if (this._done) { 11019 return { 11020 value: undefined, 11021 done: true 11022 }; 11023 } 11024 if (this._storedError) { 11025 throw this._storedError; 11026 } 11027 const chunk = this._readableStream.read(); 11028 if (chunk === null) { 11029 this._readCapability = new _util.PromiseCapability(); 11030 return this.read(); 11031 } 11032 this._loaded += chunk.length; 11033 this.onProgress?.({ 11034 loaded: this._loaded 11035 }); 11036 const buffer = new Uint8Array(chunk).buffer; 11037 return { 11038 value: buffer, 11039 done: false 11040 }; 11041 } 11042 cancel(reason) { 11043 if (!this._readableStream) { 11044 this._error(reason); 11045 return; 11046 } 11047 this._readableStream.destroy(reason); 11048 } 11049 _error(reason) { 11050 this._storedError = reason; 11051 this._readCapability.resolve(); 11052 } 11053 _setReadableStream(readableStream) { 11054 this._readableStream = readableStream; 11055 readableStream.on("readable", () => { 11056 this._readCapability.resolve(); 11057 }); 11058 readableStream.on("end", () => { 11059 readableStream.destroy(); 11060 this._done = true; 11061 this._readCapability.resolve(); 11062 }); 11063 readableStream.on("error", reason => { 11064 this._error(reason); 11065 }); 11066 if (this._storedError) { 11067 this._readableStream.destroy(this._storedError); 11068 } 11069 } 11070} 11071function createRequestOptions(parsedUrl, headers) { 11072 return { 11073 protocol: parsedUrl.protocol, 11074 auth: parsedUrl.auth, 11075 host: parsedUrl.hostname, 11076 port: parsedUrl.port, 11077 path: parsedUrl.path, 11078 method: "GET", 11079 headers 11080 }; 11081} 11082class PDFNodeStreamFullReader extends BaseFullReader { 11083 constructor(stream) { 11084 super(stream); 11085 const handleResponse = response => { 11086 if (response.statusCode === 404) { 11087 const error = new _util.MissingPDFException(`Missing PDF "${this._url}".`); 11088 this._storedError = error; 11089 this._headersCapability.reject(error); 11090 return; 11091 } 11092 this._headersCapability.resolve(); 11093 this._setReadableStream(response); 11094 const getResponseHeader = name => { 11095 return this._readableStream.headers[name.toLowerCase()]; 11096 }; 11097 const { 11098 allowRangeRequests, 11099 suggestedLength 11100 } = (0, _network_utils.validateRangeRequestCapabilities)({ 11101 getResponseHeader, 11102 isHttp: stream.isHttp, 11103 rangeChunkSize: this._rangeChunkSize, 11104 disableRange: this._disableRange 11105 }); 11106 this._isRangeSupported = allowRangeRequests; 11107 this._contentLength = suggestedLength || this._contentLength; 11108 this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader); 11109 }; 11110 this._request = null; 11111 if (this._url.protocol === "http:") { 11112 const http = require("http"); 11113 this._request = http.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse); 11114 } else { 11115 const https = require("https"); 11116 this._request = https.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse); 11117 } 11118 this._request.on("error", reason => { 11119 this._storedError = reason; 11120 this._headersCapability.reject(reason); 11121 }); 11122 this._request.end(); 11123 } 11124} 11125class PDFNodeStreamRangeReader extends BaseRangeReader { 11126 constructor(stream, start, end) { 11127 super(stream); 11128 this._httpHeaders = {}; 11129 for (const property in stream.httpHeaders) { 11130 const value = stream.httpHeaders[property]; 11131 if (value === undefined) { 11132 continue; 11133 } 11134 this._httpHeaders[property] = value; 11135 } 11136 this._httpHeaders.Range = `bytes=${start}-${end - 1}`; 11137 const handleResponse = response => { 11138 if (response.statusCode === 404) { 11139 const error = new _util.MissingPDFException(`Missing PDF "${this._url}".`); 11140 this._storedError = error; 11141 return; 11142 } 11143 this._setReadableStream(response); 11144 }; 11145 this._request = null; 11146 if (this._url.protocol === "http:") { 11147 const http = require("http"); 11148 this._request = http.request(createRequestOptions(this._url, this._httpHeaders), handleResponse); 11149 } else { 11150 const https = require("https"); 11151 this._request = https.request(createRequestOptions(this._url, this._httpHeaders), handleResponse); 11152 } 11153 this._request.on("error", reason => { 11154 this._storedError = reason; 11155 }); 11156 this._request.end(); 11157 } 11158} 11159class PDFNodeStreamFsFullReader extends BaseFullReader { 11160 constructor(stream) { 11161 super(stream); 11162 let path = decodeURIComponent(this._url.path); 11163 if (fileUriRegex.test(this._url.href)) { 11164 path = path.replace(/^\//, ""); 11165 } 11166 const fs = require("fs"); 11167 fs.lstat(path, (error, stat) => { 11168 if (error) { 11169 if (error.code === "ENOENT") { 11170 error = new _util.MissingPDFException(`Missing PDF "${path}".`); 11171 } 11172 this._storedError = error; 11173 this._headersCapability.reject(error); 11174 return; 11175 } 11176 this._contentLength = stat.size; 11177 this._setReadableStream(fs.createReadStream(path)); 11178 this._headersCapability.resolve(); 11179 }); 11180 } 11181} 11182class PDFNodeStreamFsRangeReader extends BaseRangeReader { 11183 constructor(stream, start, end) { 11184 super(stream); 11185 let path = decodeURIComponent(this._url.path); 11186 if (fileUriRegex.test(this._url.href)) { 11187 path = path.replace(/^\//, ""); 11188 } 11189 const fs = require("fs"); 11190 this._setReadableStream(fs.createReadStream(path, { 11191 start, 11192 end: end - 1 11193 })); 11194 } 11195} 11196 11197/***/ }), 11198/* 24 */ 11199/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 11200 11201 11202 11203Object.defineProperty(exports, "__esModule", ({ 11204 value: true 11205})); 11206exports.SVGGraphics = void 0; 11207var _display_utils = __w_pdfjs_require__(6); 11208var _util = __w_pdfjs_require__(1); 11209; 11210const SVG_DEFAULTS = { 11211 fontStyle: "normal", 11212 fontWeight: "normal", 11213 fillColor: "#000000" 11214}; 11215const XML_NS = "http://www.w3.org/XML/1998/namespace"; 11216const XLINK_NS = "http://www.w3.org/1999/xlink"; 11217const LINE_CAP_STYLES = ["butt", "round", "square"]; 11218const LINE_JOIN_STYLES = ["miter", "round", "bevel"]; 11219const createObjectURL = function (data, contentType = "", forceDataSchema = false) { 11220 if (URL.createObjectURL && typeof Blob !== "undefined" && !forceDataSchema) { 11221 return URL.createObjectURL(new Blob([data], { 11222 type: contentType 11223 })); 11224 } 11225 const digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
11225+/="; 11226 let buffer = `data:${contentType};base64,`; 11227 for (let i = 0, ii = data.length; i < ii; i += 3) { 11228 const b1 = data[i] & 0xff; 11229 const b2 = data[i + 1] & 0xff; 11230 const b3 = data[i + 2] & 0xff; 11231 const d1 = b1 >> 2, 11232 d2 = (b1 & 3) << 4 | b2 >> 4; 11233 const d3 = i + 1 < ii ? (b2 & 0xf) << 2 | b3 >> 6 : 64; 11234 const d4 = i + 2 < ii ? b3 & 0x3f : 64; 11235 buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4]; 11236 } 11237 return buffer; 11238}; 11239const convertImgDataToPng = function () { 11240 const PNG_HEADER = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); 11241 const CHUNK_WRAPPER_SIZE = 12; 11242 const crcTable = new Int32Array(256); 11243 for (let i = 0; i < 256; i++) { 11244 let c = i; 11245 for (let h = 0; h < 8; h++) { 11246 c = c & 1 ? 0xedb88320 ^ c >> 1 & 0x7fffffff : c >> 1 & 0x7fffffff; 11247 } 11248 crcTable[i] = c; 11249 } 11250 function crc32(data, start, end) { 11251 let crc = -1; 11252 for (let i = start; i < end; i++) { 11253 const a = (crc ^ data[i]) & 0xff; 11254 const b = crcTable[a]; 11255 crc = crc >>> 8 ^ b; 11256 } 11257 return crc ^ -1; 11258 } 11259 function writePngChunk(type, body, data, offset) { 11260 let p = offset; 11261 const len = body.length; 11262 data[p] = len >> 24 & 0xff; 11263 data[p + 1] = len >> 16 & 0xff; 11264 data[p + 2] = len >> 8 & 0xff; 11265 data[p + 3] = len & 0xff; 11266 p += 4; 11267 data[p] = type.charCodeAt(0) & 0xff; 11268 data[p + 1] = type.charCodeAt(1) & 0xff; 11269 data[p + 2] = type.charCodeAt(2) & 0xff;
11270 data[p + 3] = type.charCodeAt(3) & 0xff; 11271 p += 4; 11272 data.set(body, p); 11273 p += body.length; 11274 const crc = crc32(data, offset + 4, p); 11275 data[p] = crc >> 24 & 0xff; 11276 data[p + 1] = crc >> 16 & 0xff; 11277 data[p + 2] = crc >> 8 & 0xff; 11278 data[p + 3] = crc & 0xff; 11279 } 11280 function adler32(data, start, end) { 11281 let a = 1; 11282 let b = 0; 11283 for (let i = start; i < end; ++i) { 11284 a = (a + (data[i] & 0xff)) % 65521; 11285 b = (b + a) % 65521; 11286 } 11287 return b << 16 | a; 11288 } 11289 function deflateSync(literals) { 11290 if (!_util.isNodeJS) { 11291 return deflateSyncUncompressed(literals); 11292 } 11293 try { 11294 const input = parseInt(process.versions.node) >= 8 ? literals : Buffer.from(literals); 11295 const output = require("zlib").deflateSync(input, { 11296 level: 9 11297 }); 11298 return output instanceof Uint8Array ? output : new Uint8Array(output); 11299 } catch (e) { 11300 (0, _util.warn)("Not compressing PNG because zlib.deflateSync is unavailable: " + e); 11301 } 11302 return deflateSyncUncompressed(literals); 11303 } 11304 function deflateSyncUncompressed(literals) { 11305 let len = literals.length; 11306 const maxBlockLength = 0xffff; 11307 const deflateBlocks = Math.ceil(len / maxBlockLength); 11308 const idat = new Uint8Array(2 + len + deflateBlocks * 5 + 4); 11309 let pi = 0; 11310 idat[pi++] = 0x78; 11311 idat[pi++] = 0x9c; 11312 let pos = 0; 11313 while (len > maxBlockLength) { 11314 idat[pi++] = 0x00; 11315 idat[pi++] = 0xff; 11316 idat[pi++] = 0xff; 11317 idat[pi++] = 0x00; 11318 idat[pi++] = 0x00; 11319 idat.set(literals.subarray(pos, pos + maxBlockLength), pi); 11320 pi += maxBlockLength; 11321 pos += maxBlockLength; 11322 len -= maxBlockLength; 11323 } 11324 idat[pi++] = 0x01; 11325 idat[pi++] = len & 0xff; 11326 idat[pi++] = len >> 8 & 0xff; 11327 idat[pi++] = ~len & 0xffff & 0xff; 11328 idat[pi++] = (~len & 0xffff) >> 8 & 0xff; 11329 idat.set(literals.subarray(pos), pi); 11330 pi += literals.length - pos; 11331 const adler = adler32(literals, 0, literals.length); 11332 idat[pi++] = adler >> 24 & 0xff; 11333 idat[pi++] = adler >> 16 & 0xff; 11334 idat[pi++] = adler >> 8 & 0xff; 11335 idat[pi++] = adler & 0xff; 11336 return idat; 11337 } 11338 function encode(imgData, kind, forceDataSchema, isMask) { 11339 const width = imgData.width; 11340 const height = imgData.height; 11341 let bitDepth, colorType, lineSize; 11342 const bytes = imgData.data; 11343 switch (kind) { 11344 case _util.ImageKind.GRAYSCALE_1BPP: 11345 colorType = 0; 11346 bitDepth = 1; 11347 lineSize = width + 7 >> 3; 11348 break; 11349 case _util.ImageKind.RGB_24BPP: 11350 colorType = 2; 11351 bitDepth = 8; 11352 lineSize = width * 3; 11353 break; 11354 case _util.ImageKind.RGBA_32BPP: 11355 colorType = 6; 11356 bitDepth = 8; 11357 lineSize = width * 4; 11358 break; 11359 default: 11360 throw new Error("invalid format"); 11361 } 11362 const literals = new Uint8Array((1 + lineSize) * height); 11363 let offsetLiterals = 0, 11364 offsetBytes = 0; 11365 for (let y = 0; y < height; ++y) { 11366 literals[offsetLiterals++] = 0; 11367 literals.set(bytes.subarray(offsetBytes, offsetBytes + lineSize), offsetLiterals); 11368 offsetBytes += lineSize; 11369 offsetLiterals += lineSize; 11370 } 11371 if (kind === _util.ImageKind.GRAYSCALE_1BPP && isMask) { 11372 offsetLiterals = 0; 11373 for (let y = 0; y < height; y++) { 11374 offsetLiterals++; 11375 for (let i = 0; i < lineSize; i++) { 11376 literals[offsetLiterals++] ^= 0xff; 11377 } 11378 } 11379 } 11380 const ihdr = new Uint8Array([width >> 24 & 0xff, width >> 16 & 0xff, width >> 8 & 0xff, width & 0xff, height >> 24 & 0xff, height >> 16 & 0xff, height >> 8 & 0xff, height & 0xff, bitDepth, colorType, 0x00, 0x00, 0x00]); 11381 const idat = deflateSync(literals); 11382 const pngLength = PNG_HEADER.length + CHUNK_WRAPPER_SIZE * 3 + ihdr.length + idat.length; 11383 const data = new Uint8Array(pngLength); 11384 let offset = 0; 11385 data.set(PNG_HEADER, offset); 11386 offset += PNG_HEADER.length; 11387 writePngChunk("IHDR", ihdr, data, offset); 11388 offset += CHUNK_WRAPPER_SIZE + ihdr.length; 11389 writePngChunk("IDATA", idat, data, offset); 11390 offset += CHUNK_WRAPPER_SIZE + idat.length; 11391 writePngChunk("IEND", new Uint8Array(0), data, offset); 11392 return createObjectURL(data, "image/png", forceDataSchema); 11393 } 11394 return function convertImgDataToPng(imgData, forceDataSchema, isMask) {
11395 const kind = imgData.kind === undefined ? _util.ImageKind.GRAYSCALE_1BPP : imgData.kind; 11396 return encode(imgData, kind, forceDataSchema, isMask); 11397 }; 11398}(); 11399class SVGExtraState { 11400 constructor() { 11401 this.fontSizeScale = 1; 11402 this.fontWeight = SVG_DEFAULTS.fontWeight; 11403 this.fontSize = 0; 11404 this.textMatrix = _util.IDENTITY_MATRIX; 11405 this.fontMatrix = _util.FONT_IDENTITY_MATRIX; 11406 this.leading = 0; 11407 this.textRenderingMode = _util.TextRenderingMode.FILL; 11408 this.textMatrixScale = 1; 11409 this.x = 0; 11410 this.y = 0; 11411 this.lineX = 0; 11412 this.lineY = 0; 11413 this.charSpacing = 0; 11414 this.wordSpacing = 0; 11415 this.textHScale = 1; 11416 this.textRise = 0; 11417 this.fillColor = SVG_DEFAULTS.fillColor; 11418 this.strokeColor = "#000000"; 11419 this.fillAlpha = 1; 11420 this.strokeAlpha = 1; 11421 this.lineWidth = 1; 11422 this.lineJoin = ""; 11423 this.lineCap = ""; 11424 this.miterLimit = 0; 11425 this.dashArray = []; 11426 this.dashPhase = 0; 11427 this.dependencies = []; 11428 this.activeClipUrl = null; 11429 this.clipGroup = null; 11430 this.maskId = ""; 11431 } 11432 clone() { 11433 return Object.create(this); 11434 } 11435 setCurrentPoint(x, y) { 11436 this.x = x; 11437 this.y = y; 11438 } 11439} 11440function opListToTree(opList) { 11441 let opTree = []; 11442 const tmp = []; 11443 for (const opListElement of opList) { 11444 if (opListElement.fn === "save") { 11445 opTree.push({ 11446 fnId: 92, 11447 fn: "group", 11448 items: [] 11449 }); 11450 tmp.push(opTree); 11451 opTree = opTree.at(-1).items; 11452 continue; 11453 } 11454 if (opListElement.fn === "restore") { 11455 opTree = tmp.pop(); 11456 } else { 11457 opTree.push(opListElement); 11458 } 11459 } 11460 return opTree; 11461} 11462function pf(value) { 11463 if (Number.isInteger(value)) { 11464 return value.toString(); 11465 } 11466 const s = value.toFixed(10); 11467 let i = s.length - 1; 11468 if (s[i] !== "0") { 11469 return s; 11470 } 11471 do { 11472 i--; 11473 } while (s[i] === "0"); 11474 return s.substring(0, s[i] === "." ? i : i + 1); 11475} 11476function pm(m) { 11477 if (m[4] === 0 && m[5] === 0) { 11478 if (m[1] === 0 && m[2] === 0) { 11479 if (m[0] === 1 && m[3] === 1) { 11480 return ""; 11481 } 11482 return `scale(${pf(m[0])} ${pf(m[3])})`; 11483 } 11484 if (m[0] === m[3] && m[1] === -m[2]) { 11485 const a = Math.acos(m[0]) * 180 / Math.PI; 11486 return `rotate(${pf(a)})`; 11487 } 11488 } else if (m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1) { 11489 return `translate(${pf(m[4])} ${pf(m[5])})`; 11490 } 11491 return `matrix(${pf(m[0])} ${pf(m[1])} ${pf(m[2])} ${pf(m[3])} ${pf(m[4])} ` + `${pf(m[5])})`; 11492} 11493let clipCount = 0; 11494let maskCount = 0; 11495let shadingCount = 0; 11496class SVGGraphics { 11497 constructor(commonObjs, objs, forceDataSchema = false) { 11498 (0, _display_utils.deprecated)("The SVG back-end is no longer maintained and *may* be removed in the future."); 11499 this.svgFactory = new _display_utils.DOMSVGFactory(); 11500 this.current = new SVGExtraState(); 11501 this.transformMatrix = _util.IDENTITY_MATRIX; 11502 this.transformStack = []; 11503 this.extraStack = []; 11504 this.commonObjs = commonObjs; 11505 this.objs = objs; 11506 this.pendingClip = null; 11507 this.pendingEOFill = false; 11508 this.embedFonts = false; 11509 this.embeddedFonts = Object.create(null); 11510 this.cssStyle = null; 11511 this.forceDataSchema = !!forceDataSchema; 11512 this._operatorIdMapping = []; 11513 for (const op in _util.OPS) { 11514 this._operatorIdMapping[_util.OPS[op]] = op; 11515 } 11516 } 11517 getObject(data, fallback = null) { 11518 if (typeof data === "string") { 11519 return data.startsWith("g_") ? this.commonObjs.get(data) : this.objs.get(data); 11520 } 11521 return fallback; 11522 } 11523 save() { 11524 this.transformStack.push(this.transformMatrix); 11525 const old = this.current; 11526 this.extraStack.push(old); 11527 this.current = old.clone(); 11528 } 11529 restore() { 11530 this.transformMatrix = this.transformStack.pop(); 11531 this.current = this.extraStack.pop(); 11532 this.pendingClip = null; 11533 this.tgrp = null; 11534 } 11535 group(items) { 11536 this.save(); 11537 this.executeOpTree(items); 11538 this.restore(); 11539 } 11540 loadDependencies(operatorList) { 11541 const fnArray = operatorList.fnArray; 11542 const argsArray = operatorList.argsArray; 11543 for (let i = 0, ii = fnArray.length; i < ii; i++) { 11544 if (fnArray[i] !== _util.OPS.dependency) { 11545 continue; 11546 } 11547 for (const obj of argsArray[i]) { 11548 const objsPool = obj.startsWith("g_") ? this.commonObjs : this.objs; 11549 const promise = new Promise(resolve => { 11550 objsPool.get(obj, resolve); 11551 }); 11552 this.current.dependencies.push(promise); 11553 } 11554 } 11555 return Promise.all(this.current.dependencies); 11556 } 11557 transform(a, b, c, d, e, f) { 11558 const transformMatrix = [a, b, c, d, e, f]; 11559 this.transformMatrix = _util.Util.transform(this.transformMatrix, transformMatrix); 11560 this.tgrp = null; 11561 } 11562 getSVG(operatorList, viewport) { 11563 this.viewport = viewport; 11564 const svgElement = this._initialize(viewport); 11565 return this.loadDependencies(operatorList).then(() => { 11566 this.transformMatrix = _util.IDENTITY_MATRIX; 11567 this.executeOpTree(this.convertOpList(operatorList)); 11568 return svgElement; 11569 }); 11570 } 11571 convertOpList(operatorList) { 11572 const operatorIdMapping = this._operatorIdMapping; 11573 const argsArray = operatorList.argsArray; 11574 const fnArray = operatorList.fnArray; 11575 const opList = []; 11576 for (let i = 0, ii = fnArray.length; i < ii; i++) { 11577 const fnId = fnArray[i]; 11578 opList.push({ 11579 fnId, 11580 fn: operatorIdMapping[fnId], 11581 args: argsArray[i] 11582 }); 11583 } 11584 return opListToTree(opList); 11585 } 11586 executeOpTree(opTree) { 11587 for (const opTreeElement of opTree) { 11588 const fn = opTreeElement.fn; 11589 const fnId = opTreeElement.fnId; 11590 const args = opTreeElement.args;
11591 switch (fnId | 0) { 11592 case _util.OPS.beginText: 11593 this.beginText(); 11594 break; 11595 case _util.OPS.dependency: 11596 break; 11597 case _util.OPS.setLeading: 11598 this.setLeading(args); 11599 break; 11600 case _util.OPS.setLeadingMoveText: 11601 this.setLeadingMoveText(args[0], args[1]); 11602 break; 11603 case _util.OPS.setFont: 11604 this.setFont(args); 11605 break; 11606 case _util.OPS.showText: 11607 this.showText(args[0]); 11608 break; 11609 case _util.OPS.showSpacedText: 11610 this.showText(args[0]); 11611 break; 11612 case _util.OPS.endText: 11613 this.endText(); 11614 break; 11615 case _util.OPS.moveText: 11616 this.moveText(args[0], args[1]); 11617 break; 11618 case _util.OPS.setCharSpacing: 11619 this.setCharSpacing(args[0]); 11620 break; 11621 case _util.OPS.setWordSpacing: 11622 this.setWordSpacing(args[0]); 11623 break; 11624 case _util.OPS.setHScale: 11625 this.setHScale(args[0]); 11626 break; 11627 case _util.OPS.setTextMatrix: 11628 this.setTextMatrix(args[0], args[1], args[2], args[3], args[4], args[5]); 11629 break; 11630 case _util.OPS.setTextRise: 11631 this.setTextRise(args[0]); 11632 break; 11633 case _util.OPS.setTextRenderingMode: 11634 this.setTextRenderingMode(args[0]); 11635 break; 11636 case _util.OPS.setLineWidth: 11637 this.setLineWidth(args[0]); 11638 break; 11639 case _util.OPS.setLineJoin: 11640 this.setLineJoin(args[0]); 11641 break; 11642 case _util.OPS.setLineCap: 11643 this.setLineCap(args[0]); 11644 break; 11645 case _util.OPS.setMiterLimit: 11646 this.setMiterLimit(args[0]); 11647 break; 11648 case _util.OPS.setFillRGBColor: 11649 this.setFillRGBColor(args[0], args[1], args[2]); 11650 break; 11651 case _util.OPS.setStrokeRGBColor: 11652 this.setStrokeRGBColor(args[0], args[1], args[2]); 11653 break; 11654 case _util.OPS.setStrokeColorN: 11655 this.setStrokeColorN(args); 11656 break; 11657 case _util.OPS.setFillColorN: 11658 this.setFillColorN(args); 11659 break; 11660 case _util.OPS.shadingFill: 11661 this.shadingFill(args[0]); 11662 break; 11663 case _util.OPS.setDash: 11664 this.setDash(args[0], args[1]); 11665 break; 11666 case _util.OPS.setRenderingIntent: 11667 this.setRenderingIntent(args[0]); 11668 break; 11669 case _util.OPS.setFlatness: 11670 this.setFlatness(args[0]); 11671 break; 11672 case _util.OPS.setGState: 11673 this.setGState(args[0]); 11674 break; 11675 case _util.OPS.fill: 11676 this.fill(); 11677 break; 11678 case _util.OPS.eoFill: 11679 this.eoFill(); 11680 break; 11681 case _util.OPS.stroke: 11682 this.stroke(); 11683 break; 11684 case _util.OPS.fillStroke: 11685 this.fillStroke(); 11686 break; 11687 case _util.OPS.eoFillStroke: 11688 this.eoFillStroke(); 11689 break; 11690 case _util.OPS.clip: 11691 this.clip("nonzero"); 11692 break; 11693 case _util.OPS.eoClip: 11694 this.clip("evenodd"); 11695 break; 11696 case _util.OPS.paintSolidColorImageMask: 11697 this.paintSolidColorImageMask(); 11698 break; 11699 case _util.OPS.paintImageXObject: 11700 this.paintImageXObject(args[0]); 11701 break; 11702 case _util.OPS.paintInlineImageXObject: 11703 this.paintInlineImageXObject(args[0]); 11704 break; 11705 case _util.OPS.paintImageMaskXObject: 11706 this.paintImageMaskXObject(args[0]); 11707 break; 11708 case _util.OPS.paintFormXObjectBegin: 11709 this.paintFormXObjectBegin(args[0], args[1]); 11710 break; 11711 case _util.OPS.paintFormXObjectEnd: 11712 this.paintFormXObjectEnd(); 11713 break; 11714 case _util.OPS.closePath: 11715 this.closePath(); 11716 break; 11717 case _util.OPS.closeStroke: 11718 this.closeStroke(); 11719 break; 11720 case _util.OPS.closeFillStroke: 11721 this.closeFillStroke(); 11722 break; 11723 case _util.OPS.closeEOFillStroke: 11724 this.closeEOFillStroke(); 11725 break; 11726 case _util.OPS.nextLine: 11727 this.nextLine(); 11728 break; 11729 case _util.OPS.transform: 11730 this.transform(args[0], args[1], args[2], args[3], args[4], args[5]); 11731 break; 11732 case _util.OPS.constructPath: 11733 this.constructPath(args[0], args[1]); 11734 break; 11735 case _util.OPS.endPath: 11736 this.endPath(); 11737 break; 11738 case 92: 11739 this.group(opTreeElement.items); 11740 break; 11741 default: 11742 (0, _util.warn)(`Unimplemented operator ${fn}`); 11743 break; 11744 } 11745 } 11746 } 11747 setWordSpacing(wordSpacing) { 11748 this.current.wordSpacing = wordSpacing; 11749 } 11750 setCharSpacing(charSpacing) { 11751 this.current.charSpacing = charSpacing; 11752 } 11753 nextLine() { 11754 this.moveText(0, this.current.leading); 11755 } 11756 setTextMatrix(a, b, c, d, e, f) { 11757 const current = this.current; 11758 current.textMatrix = current.lineMatrix = [a, b, c, d, e, f]; 11759 current.textMatrixScale = Math.hypot(a, b); 11760 current.x = current.lineX = 0; 11761 current.y = current.lineY = 0; 11762 current.xcoords = []; 11763 current.ycoords = []; 11764 current.tspan = this.svgFactory.createElement("svg:tspan"); 11765 current.tspan.setAttributeNS(null, "font-family", current.fontFamily); 11766 current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`); 11767 current.tspan.setAttributeNS(null, "y", pf(-current.y)); 11768 current.txtElement = this.svgFactory.createElement("svg:text"); 11769 current.txtElement.append(current.tspan); 11770 } 11771 beginText() { 11772 const current = this.current; 11773 current.x = current.lineX = 0; 11774 current.y = current.lineY = 0; 11775 current.textMatrix = _util.IDENTITY_MATRIX; 11776 current.lineMatrix = _util.IDENTITY_MATRIX; 11777 current.textMatrixScale = 1; 11778 current.tspan = this.svgFactory.createElement("svg:tspan"); 11779 current.txtElement = this.svgFactory.createElement("svg:text"); 11780 current.txtgrp = this.svgFactory.createElement("svg:g"); 11781 current.xcoords = []; 11782 current.ycoords = []; 11783 } 11784 moveText(x, y) { 11785 const current = this.current; 11786 current.x = current.lineX += x; 11787 current.y = current.lineY += y; 11788 current.xcoords = []; 11789 current.ycoords = []; 11790 current.tspan = this.svgFactory.createElement("svg:tspan"); 11791 current.tspan.setAttributeNS(null, "font-family", current.fontFamily); 11792 current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`); 11793 current.tspan.setAttributeNS(null, "y", pf(-current.y)); 11794 } 11795 showText(glyphs) { 11796 const current = this.current; 11797 const font = current.font; 11798 const fontSize = current.fontSize; 11799 if (fontSize === 0) { 11800 return; 11801 } 11802 const fontSizeScale = current.fontSizeScale; 11803 const charSpacing = current.charSpacing; 11804 const wordSpacing = current.wordSpacing; 11805 const fontDirection = current.fontDirection; 11806 const textHScale = current.textHScale * fontDirection; 11807 const vertical = font.vertical; 11808 const spacingDir = vertical ? 1 : -1; 11809 const defaultVMetrics = font.defaultVMetrics; 11810 const widthAdvanceScale = fontSize * current.fontMatrix[0]; 11811 let x = 0; 11812 for (const glyph of glyphs) { 11813 if (glyph === null) { 11814 x += fontDirection * wordSpacing; 11815 continue; 11816 }
11816 else if (typeof glyph === "number") { 11817 x += spacingDir * glyph * fontSize / 1000; 11818 continue; 11819 } 11820 const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 11821 const character = glyph.fontChar; 11822 let scaledX, scaledY; 11823 let width = glyph.width; 11824 if (vertical) { 11825 let vx; 11826 const vmetric = glyph.vmetric || defaultVMetrics; 11827 vx = glyph.vmetric ? vmetric[1] : width * 0.5; 11828 vx = -vx * widthAdvanceScale; 11829 const vy = vmetric[2] * widthAdvanceScale; 11830 width = vmetric ? -vmetric[0] : width; 11831 scaledX = vx / fontSizeScale; 11832 scaledY = (x + vy) / fontSizeScale; 11833 } else { 11834 scaledX = x / fontSizeScale; 11835 scaledY = 0; 11836 } 11837 if (glyph.isInFont || font.missingFile) { 11838 current.xcoords.push(current.x + scaledX); 11839 if (vertical) { 11840 current.ycoords.push(-current.y + scaledY); 11841 } 11842 current.tspan.textContent += character; 11843 } else {} 11844 const charWidth = vertical ? width * widthAdvanceScale - spacing * fontDirection : width * widthAdvanceScale + spacing * fontDirection; 11845 x += charWidth; 11846 } 11847 current.tspan.setAttributeNS(null, "x", current.xcoords.map(pf).join(" ")); 11848 if (vertical) { 11849 current.tspan.setAttributeNS(null, "y", current.ycoords.map(pf).join(" ")); 11850 } else { 11851 current.tspan.setAttributeNS(null, "y", pf(-current.y)); 11852 } 11853 if (vertical) { 11854 current.y -= x; 11855 } else { 11856 current.x += x * textHScale; 11857 } 11858 current.tspan.setAttributeNS(null, "font-family", current.fontFamily); 11859 current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`); 11860 if (current.fontStyle !== SVG_DEFAULTS.fontStyle) { 11861 current.tspan.setAttributeNS(null, "font-style", current.fontStyle); 11862 } 11863 if (current.fontWeight !== SVG_DEFAULTS.fontWeight) { 11864 current.tspan.setAttributeNS(null, "font-weight", current.fontWeight); 11865 } 11866 const fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; 11867 if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 11868 if (current.fillColor !== SVG_DEFAULTS.fillColor) { 11869 current.tspan.setAttributeNS(null, "fill", current.fillColor); 11870 } 11871 if (current.fillAlpha < 1) { 11872 current.tspan.setAttributeNS(null, "fill-opacity", current.fillAlpha); 11873 } 11874 } else if (current.textRenderingMode === _util.TextRenderingMode.ADD_TO_PATH) { 11875 current.tspan.setAttributeNS(null, "fill", "transparent"); 11876 } else { 11877 current.tspan.setAttributeNS(null, "fill", "none"); 11878 } 11879 if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 11880 const lineWidthScale = 1 / (current.textMatrixScale || 1); 11881 this._setStrokeAttributes(current.tspan, lineWidthScale); 11882 } 11883 let textMatrix = current.textMatrix; 11884 if (current.textRise !== 0) { 11885 textMatrix = textMatrix.slice(); 11886 textMatrix[5] += current.textRise; 11887 } 11888 current.txtElement.setAttributeNS(null, "transform", `${pm(textMatrix)} scale(${pf(textHScale)}, -1)`); 11889 current.txtElement.setAttributeNS(XML_NS, "xml:space", "preserve"); 11890 current.txtElement.append(current.tspan); 11891 current.txtgrp.append(current.txtElement); 11892 this._ensureTransformGroup().append(current.txtElement); 11893 } 11894 setLeadingMoveText(x, y) { 11895 this.setLeading(-y); 11896 this.moveText(x, y); 11897 } 11898 addFontStyle(fontObj) { 11899 if (!fontObj.data) { 11900 throw new Error("addFontStyle: No font data available, " + 'ensure that the "fontExtraProperties" API parameter is set.'); 11901 } 11902 if (!this.cssStyle) { 11903 this.cssStyle = this.svgFactory.createElement("svg:style"); 11904 this.cssStyle.setAttributeNS(null, "type", "text/css"); 11905 this.defs.append(this.cssStyle); 11906 } 11907 const url = createObjectURL(fontObj.data, fontObj.mimetype, this.forceDataSchema); 11908 this.cssStyle.textContent += `@font-face { font-family: "${fontObj.loadedName}";` + ` src: url(${url}); }\n`; 11909 } 11910 setFont(details) { 11911 const current = this.current; 11912 const fontObj = this.commonObjs.get(details[0]); 11913 let size = details[1]; 11914 current.font = fontObj; 11915 if (this.embedFonts && !fontObj.missingFile && !this.embeddedFonts[fontObj.loadedName]) { 11916 this.addFontStyle(fontObj); 11917 this.embeddedFonts[fontObj.loadedName] = fontObj; 11918 } 11919 current.fontMatrix = fontObj.fontMatrix || _util.FONT_IDENTITY_MATRIX; 11920 let bold = "normal"; 11921 if (fontObj.black) { 11922 bold = "900"; 11923 } else if (fontObj.bold) { 11924 bold = "bold"; 11925 } 11926 const italic = fontObj.italic ? "italic" : "normal"; 11927 if (size < 0) { 11928 size = -size; 11929 current.fontDirection = -1; 11930 } else { 11931 current.fontDirection = 1; 11932 } 11933 current.fontSize = size; 11934 current.fontFamily = fontObj.loadedName; 11935 current.fontWeight = bold; 11936 current.fontStyle = italic; 11937 current.tspan = this.svgFactory.createElement("svg:tspan"); 11938 current.tspan.setAttributeNS(null, "y", pf(-current.y)); 11939 current.xcoords = []; 11940 current.ycoords = []; 11941 } 11942 endText() { 11943 const current = this.current; 11944 if (current.textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG && current.txtElement?.hasChildNodes()) { 11945 current.element = current.txtElement; 11946 this.clip("nonzero"); 11947 this.endPath(); 11948 } 11949 } 11950 setLineWidth(width) { 11951 if (width > 0) { 11952 this.current.lineWidth = width; 11953 } 11954 } 11955 setLineCap(style) { 11956 this.current.lineCap = LINE_CAP_STYLES[style]; 11957 } 11958 setLineJoin(style) { 11959 this.current.lineJoin = LINE_JOIN_STYLES[style]; 11960 } 11961 setMiterLimit(limit) { 11962 this.current.miterLimit = limit; 11963 } 11964 setStrokeAlpha(strokeAlpha) { 11965 this.current.strokeAlpha = strokeAlpha; 11966 } 11967 setStrokeRGBColor(r, g, b) { 11968 this.current.strokeColor = _util.Util.makeHexColor(r, g, b); 11969 } 11970 setFillAlpha(fillAlpha) { 11971 this.current.fillAlpha = fillAlpha; 11972 } 11973 setFillRGBColor(r, g, b) { 11974 this.current.fillColor = _util.Util.makeHexColor(r, g, b); 11975 this.current.tspan = this.svgFactory.createElement("svg:tspan"); 11976 this.current.xcoords = []; 11977 this.current.ycoords = []; 11978 } 11979 setStrokeColorN(args) { 11980 this.current.strokeColor = this._makeColorN_Pattern(args); 11981 } 11982 setFillColorN(args) { 11983 this.current.fillColor = this._makeColorN_Pattern(args); 11984 } 11985 shadingFill(args) { 11986 const { 11987 width, 11988 height 11989 } = this.viewport; 11990 const inv = _util.Util.inverseTransform(this.transformMatrix); 11991 const [x0, y0, x1, y1] = _util.Util.getAxialAlignedBoundingBox([0, 0, width, height], inv); 11992 const rect = this.svgFactory.createElement("svg:rect"); 11993 rect.setAttributeNS(null, "x", x0); 11994 rect.setAttributeNS(null, "y", y0); 11995 rect.setAttributeNS(null, "width", x1 - x0); 11996 rect.setAttributeNS(null, "height", y1 - y0); 11997 rect.setAttributeNS(null, "fill", this._makeShadingPattern(args)); 11998 if (this.current.fillAlpha < 1) { 11999 rect.setAttributeNS(null, "fill-opacity", this.current.fillAlpha); 12000 } 12001 this._ensureTransformGroup().append(rect); 12002 } 12003 _makeColorN_Pattern(args) { 12004 if (args[0] === "TilingPattern") { 12005 return this._makeTilingPattern(args); 12006 } 12007 return this._makeShadingPattern(args); 12008 } 12009 _makeTilingPattern(args) { 12010 const color = args[1]; 12011 const operatorList = args[2]; 12012 const matrix = args[3] || _util.IDENTITY_MATRIX; 12013 const [x0, y0, x1, y1] = args[4]; 12014 const xstep = args[5]; 12015 const ystep = args[6]; 12016 const paintType = args[7]; 12017 const tilingId = `shading${shadingCount++}`; 12018 const [tx0, ty0, tx1, ty1] = _util.Util.normalizeRect([..._util.Util.applyTransform([x0, y0
12018], matrix), ..._util.Util.applyTransform([x1, y1], matrix)]); 12019 const [xscale, yscale] = _util.Util.singularValueDecompose2dScale(matrix); 12020 const txstep = xstep * xscale; 12021 const tystep = ystep * yscale; 12022 const tiling = this.svgFactory.createElement("svg:pattern"); 12023 tiling.setAttributeNS(null, "id", tilingId); 12024 tiling.setAttributeNS(null, "patternUnits", "userSpaceOnUse"); 12025 tiling.setAttributeNS(null, "width", txstep); 12026 tiling.setAttributeNS(null, "height", tystep); 12027 tiling.setAttributeNS(null, "x", `${tx0}`); 12028 tiling.setAttributeNS(null, "y", `${ty0}`); 12029 const svg = this.svg; 12030 const transformMatrix = this.transformMatrix; 12031 const fillColor = this.current.fillColor; 12032 const strokeColor = this.current.strokeColor; 12033 const bbox = this.svgFactory.create(tx1 - tx0, ty1 - ty0); 12034 this.svg = bbox; 12035 this.transformMatrix = matrix; 12036 if (paintType === 2) { 12037 const cssColor = _util.Util.makeHexColor(...color); 12038 this.current.fillColor = cssColor; 12039 this.current.strokeColor = cssColor; 12040 } 12041 this.executeOpTree(this.convertOpList(operatorList)); 12042 this.svg = svg; 12043 this.transformMatrix = transformMatrix; 12044 this.current.fillColor = fillColor; 12045 this.current.strokeColor = strokeColor; 12046 tiling.append(bbox.childNodes[0]); 12047 this.defs.append(tiling); 12048 return `url(#${tilingId})`; 12049 } 12050 _makeShadingPattern(args) { 12051 if (typeof args === "string") { 12052 args = this.objs.get(args); 12053 } 12054 switch (args[0]) { 12055 case "RadialAxial": 12056 const shadingId = `shading${shadingCount++}`; 12057 const colorStops = args[3]; 12058 let gradient; 12059 switch (args[1]) { 12060 case "axial": 12061 const point0 = args[4]; 12062 const point1 = args[5]; 12063 gradient = this.svgFactory.createElement("svg:linearGradient"); 12064 gradient.setAttributeNS(null, "id", shadingId); 12065 gradient.setAttributeNS(null, "gradientUnits", "userSpaceOnUse"); 12066 gradient.setAttributeNS(null, "x1", point0[0]); 12067 gradient.setAttributeNS(null, "y1", point0[1]); 12068 gradient.setAttributeNS(null, "x2", point1[0]); 12069 gradient.setAttributeNS(null, "y2", point1[1]); 12070 break; 12071 case "radial": 12072 const focalPoint = args[4]; 12073 const circlePoint = args[5]; 12074 const focalRadius = args[6]; 12075 const circleRadius = args[7]; 12076 gradient = this.svgFactory.createElement("svg:radialGradient"); 12077 gradient.setAttributeNS(null, "id", shadingId); 12078 gradient.setAttributeNS(null, "gradientUnits", "userSpaceOnUse"); 12079 gradient.setAttributeNS(null, "cx", circlePoint[0]); 12080 gradient.setAttributeNS(null, "cy", circlePoint[1]); 12081 gradient.setAttributeNS(null, "r", circleRadius); 12082 gradient.setAttributeNS(null, "fx", focalPoint[0]); 12083 gradient.setAttributeNS(null, "fy", focalPoint[1]); 12084 gradient.setAttributeNS(null, "fr", focalRadius); 12085 break; 12086 default: 12087 throw new Error(`Unknown RadialAxial type: ${args[1]}`); 12088 } 12089 for (const colorStop of colorStops) { 12090 const stop = this.svgFactory.createElement("svg:stop"); 12091 stop.setAttributeNS(null, "offset", colorStop[0]); 12092 stop.setAttributeNS(null, "stop-color", colorStop[1]); 12093 gradient.append(stop); 12094 } 12095 this.defs.append(gradient); 12096 return `url(#${shadingId})`; 12097 case "Mesh": 12098 (0, _util.warn)("Unimplemented pattern Mesh"); 12099 return null; 12100 case "Dummy": 12101 return "hotpink"; 12102 default: 12103 throw new Error(`Unknown IR type: ${args[0]}`); 12104 } 12105 } 12106 setDash(dashArray, dashPhase) { 12107 this.current.dashArray = dashArray; 12108 this.current.dashPhase = dashPhase; 12109 } 12110 constructPath(ops, args) { 12111 const current = this.current; 12112 let x = current.x, 12113 y = current.y; 12114 let d = []; 12115 let j = 0; 12116 for (const op of ops) { 12117 switch (op | 0) { 12118 case _util.OPS.rectangle: 12119 x = args[j++]; 12120 y = args[j++]; 12121 const width = args[j++]; 12122 const height = args[j++]; 12123 const xw = x + width; 12124 const yh = y + height; 12125 d.push("M", pf(x), pf(y), "L", pf(xw), pf(y), "L", pf(xw), pf(yh), "L", pf(x), pf(yh), "Z"); 12126 break; 12127 case _util.OPS.moveTo: 12128 x = args[j++]; 12129 y = args[j++]; 12130 d.push("M", pf(x), pf(y)); 12131 break; 12132 case _util.OPS.lineTo: 12133 x = args[j++]; 12134 y = args[j++]; 12135 d.push("L", pf(x), pf(y)); 12136 break; 12137 case _util.OPS.curveTo: 12138 x = args[j + 4]; 12139 y = args[j + 5]; 12140 d.push("C", pf(args[j]), pf(args[j + 1]), pf(args[j + 2]), pf(args[j + 3]), pf(x), pf(y)); 12141 j += 6; 12142 break; 12143 case _util.OPS.curveTo2: 12144 d.push("C", pf(x), pf(y), pf(args[j]), pf(args[j + 1]), pf(args[j + 2]), pf(args[j + 3])); 12145 x = args[j + 2]; 12146 y = args[j + 3]; 12147 j += 4; 12148 break; 12149 case _util.OPS.curveTo3: 12150 x = args[j + 2]; 12151 y = args[j + 3]; 12152 d.push("C", pf(args[j]), pf(args[j + 1]), pf(x), pf(y), pf(x), pf(y)); 12153 j += 4; 12154 break; 12155 case _util.OPS.closePath: 12156 d.push("Z"); 12157 break; 12158 } 12159 } 12160 d = d.join(" "); 12161 if (current.path && ops.length > 0 && ops[0] !== _util.OPS.rectangle && ops[0] !== _util.OPS.moveTo) { 12162 d = current.path.getAttributeNS(null, "d") + d; 12163 } else { 12164 current.path = this.svgFactory.createElement("svg:path"); 12165 this._ensureTransformGroup().append(current.path); 12166 } 12167 current.path.setAttributeNS(null, "d", d); 12168 current.path.setAttributeNS(null, "fill", "none"); 12169 current.element = current.path; 12170 current.setCurrentPoint(x, y); 12171 } 12172 endPath() { 12173 const current = this.current; 12174 current.path = null; 12175 if (!this.pendingClip) { 12176 return; 12177 } 12178 if (!current.element) { 12179 this.pendingClip = null; 12180 return; 12181 } 12182 const clipId = `clippath${clipCount++}`; 12183 const clipPath = this.svgFactory.createElement("svg:clipPath"); 12184 clipPath.setAttributeNS(null, "id", clipId); 12185 clipPath.setAttributeNS(null, "transform", pm(this.transformMatrix)); 12186 const clipElement = current.element.cloneNode(true); 12187 if (this.pendingClip === "evenodd") { 12188 clipElement.setAttributeNS(null, "clip-rule", "evenodd"); 12189 } else { 12190 clipElement.setAttributeNS(null, "clip-rule", "nonzero"); 12191 } 12192 this.pendingClip = null; 12193 clipPath.append(clipElement); 12194 this.defs.append(clipPath); 12195 if (current.activeClipUrl) { 12196 current.clipGroup = null; 12197 for (const prev of this.extraStack) { 12198 prev.clipGroup = null; 12199 } 12200 clipPath.setAttributeNS(null, "clip-path", current.activeClipUrl); 12201 } 12202 current.activeClipUrl = `url(#${clipId})`; 12203 this.tgrp = null; 12204 } 12205 clip(type) { 12206 this.pendingClip = type; 12207 } 12208 closePath() { 12209 const current = this.current; 12210 if (current.path) { 12211 const d = `${current.path.getAttributeNS(null, "d")}Z`; 12212 current.path.setAttributeNS(null, "d", d); 12213 } 12214 } 12215 setLeading(leading) { 12216 this.current.leading = -leading; 12217 } 12218 setTextRise(textRise) { 12219 this.current.textRise = textRise; 12220 } 12221 setTextRenderingMode(textRenderingMode) { 12222 this.current.textRenderingMode = textRenderingMode; 12223 } 12224 setHScale(scale) { 12225 this.current.textHScale = scale / 100; 12226 }
12227 setRenderingIntent(intent) {} 12228 setFlatness(flatness) {} 12229 setGState(states) { 12230 for (const [key, value] of states) { 12231 switch (key) { 12232 case "LW": 12233 this.setLineWidth(value); 12234 break; 12235 case "LC": 12236 this.setLineCap(value); 12237 break; 12238 case "LJ": 12239 this.setLineJoin(value); 12240 break; 12241 case "ML": 12242 this.setMiterLimit(value); 12243 break; 12244 case "D": 12245 this.setDash(value[0], value[1]); 12246 break; 12247 case "RI": 12248 this.setRenderingIntent(value); 12249 break; 12250 case "FL": 12251 this.setFlatness(value); 12252 break; 12253 case "Font": 12254 this.setFont(value); 12255 break; 12256 case "CA": 12257 this.setStrokeAlpha(value); 12258 break; 12259 case "ca": 12260 this.setFillAlpha(value); 12261 break; 12262 default: 12263 (0, _util.warn)(`Unimplemented graphic state operator ${key}`); 12264 break; 12265 } 12266 } 12267 } 12268 fill() { 12269 const current = this.current; 12270 if (current.element) { 12271 current.element.setAttributeNS(null, "fill", current.fillColor); 12272 current.element.setAttributeNS(null, "fill-opacity", current.fillAlpha); 12273 this.endPath(); 12274 } 12275 } 12276 stroke() { 12277 const current = this.current; 12278 if (current.element) { 12279 this._setStrokeAttributes(current.element); 12280 current.element.setAttributeNS(null, "fill", "none"); 12281 this.endPath(); 12282 } 12283 } 12284 _setStrokeAttributes(element, lineWidthScale = 1) { 12285 const current = this.current; 12286 let dashArray = current.dashArray; 12287 if (lineWidthScale !== 1 && dashArray.length > 0) { 12288 dashArray = dashArray.map(function (value) { 12289 return lineWidthScale * value; 12290 }); 12291 } 12292 element.setAttributeNS(null, "stroke", current.strokeColor); 12293 element.setAttributeNS(null, "stroke-opacity", current.strokeAlpha); 12294 element.setAttributeNS(null, "stroke-miterlimit", pf(current.miterLimit)); 12295 element.setAttributeNS(null, "stroke-linecap", current.lineCap); 12296 element.setAttributeNS(null, "stroke-linejoin", current.lineJoin); 12297 element.setAttributeNS(null, "stroke-width", pf(lineWidthScale * current.lineWidth) + "px"); 12298 element.setAttributeNS(null, "stroke-dasharray", dashArray.map(pf).join(" ")); 12299 element.setAttributeNS(null, "stroke-dashoffset", pf(lineWidthScale * current.dashPhase) + "px"); 12300 } 12301 eoFill() { 12302 this.current.element?.setAttributeNS(null, "fill-rule", "evenodd"); 12303 this.fill(); 12304 } 12305 fillStroke() { 12306 this.stroke(); 12307 this.fill(); 12308 } 12309 eoFillStroke() { 12310 this.current.element?.setAttributeNS(null, "fill-rule", "evenodd"); 12311 this.fillStroke(); 12312 } 12313 closeStroke() { 12314 this.closePath(); 12315 this.stroke(); 12316 } 12317 closeFillStroke() { 12318 this.closePath(); 12319 this.fillStroke(); 12320 } 12321 closeEOFillStroke() { 12322 this.closePath(); 12323 this.eoFillStroke(); 12324 } 12325 paintSolidColorImageMask() { 12326 const rect = this.svgFactory.createElement("svg:rect"); 12327 rect.setAttributeNS(null, "x", "0"); 12328 rect.setAttributeNS(null, "y", "0"); 12329 rect.setAttributeNS(null, "width", "1px"); 12330 rect.setAttributeNS(null, "height", "1px"); 12331 rect.setAttributeNS(null, "fill", this.current.fillColor); 12332 this._ensureTransformGroup().append(rect); 12333 } 12334 paintImageXObject(objId) { 12335 const imgData = this.getObject(objId); 12336 if (!imgData) { 12337 (0, _util.warn)(`Dependent image with object ID ${objId} is not ready yet`); 12338 return; 12339 } 12340 this.paintInlineImageXObject(imgData); 12341 } 12342 paintInlineImageXObject(imgData, mask) { 12343 const width = imgData.width; 12344 const height = imgData.height; 12345 const imgSrc = convertImgDataToPng(imgData, this.forceDataSchema, !!mask); 12346 const cliprect = this.svgFactory.createElement("svg:rect"); 12347 cliprect.setAttributeNS(null, "x", "0"); 12348 cliprect.setAttributeNS(null, "y", "0"); 12349 cliprect.setAttributeNS(null, "width", pf(width)); 12350 cliprect.setAttributeNS(null, "height", pf(height)); 12351 this.current.element = cliprect; 12352 this.clip("nonzero"); 12353 const imgEl = this.svgFactory.createElement("svg:image"); 12354 imgEl.setAttributeNS(XLINK_NS, "xlink:href", imgSrc); 12355 imgEl.setAttributeNS(null, "x", "0"); 12356 imgEl.setAttributeNS(null, "y", pf(-height)); 12357 imgEl.setAttributeNS(null, "width", pf(width) + "px"); 12358 imgEl.setAttributeNS(null, "height", pf(height) + "px"); 12359 imgEl.setAttributeNS(null, "transform", `scale(${pf(1 / width)} ${pf(-1 / height)})`); 12360 if (mask) { 12361 mask.append(imgEl); 12362 } else { 12363 this._ensureTransformGroup().append(imgEl); 12364 } 12365 } 12366 paintImageMaskXObject(img) { 12367 const imgData = this.getObject(img.data, img); 12368 if (imgData.bitmap) { 12369 (0, _util.warn)("paintImageMaskXObject: ImageBitmap support is not implemented, " + "ensure that the `isOffscreenCanvasSupported` API parameter is disabled."); 12370 return; 12371 } 12372 const current = this.current; 12373 const width = imgData.width; 12374 const height = imgData.height; 12375 const fillColor = current.fillColor; 12376 current.maskId = `mask${maskCount++}`; 12377 const mask = this.svgFactory.createElement("svg:mask"); 12378 mask.setAttributeNS(null, "id", current.maskId); 12379 const rect = this.svgFactory.createElement("svg:rect"); 12380 rect.setAttributeNS(null, "x", "0"); 12381 rect.setAttributeNS(null, "y", "0"); 12382 rect.setAttributeNS(null, "width", pf(width)); 12383 rect.setAttributeNS(null, "height", pf(height)); 12384 rect.setAttributeNS(null, "fill", fillColor); 12385 rect.setAttributeNS(null, "mask", `url(#${current.maskId})`); 12386 this.defs.append(mask); 12387 this._ensureTransformGroup().append(rect); 12388 this.paintInlineImageXObject(imgData, mask); 12389 } 12390 paintFormXObjectBegin(matrix, bbox) { 12391 if (Array.isArray(matrix) && matrix.length === 6) {
12392 this.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); 12393 } 12394 if (bbox) { 12395 const width = bbox[2] - bbox[0]; 12396 const height = bbox[3] - bbox[1]; 12397 const cliprect = this.svgFactory.createElement("svg:rect"); 12398 cliprect.setAttributeNS(null, "x", bbox[0]); 12399 cliprect.setAttributeNS(null, "y", bbox[1]); 12400 cliprect.setAttributeNS(null, "width", pf(width)); 12401 cliprect.setAttributeNS(null, "height", pf(height)); 12402 this.current.element = cliprect; 12403 this.clip("nonzero"); 12404 this.endPath(); 12405 } 12406 } 12407 paintFormXObjectEnd() {} 12408 _initialize(viewport) { 12409 const svg = this.svgFactory.create(viewport.width, viewport.height); 12410 const definitions = this.svgFactory.createElement("svg:defs"); 12411 svg.append(definitions); 12412 this.defs = definitions; 12413 const rootGroup = this.svgFactory.createElement("svg:g"); 12414 rootGroup.setAttributeNS(null, "transform", pm(viewport.transform)); 12415 svg.append(rootGroup); 12416 this.svg = rootGroup; 12417 return svg; 12418 } 12419 _ensureClipGroup() { 12420 if (!this.current.clipGroup) { 12421 const clipGroup = this.svgFactory.createElement("svg:g"); 12422 clipGroup.setAttributeNS(null, "clip-path", this.current.activeClipUrl); 12423 this.svg.append(clipGroup); 12424 this.current.clipGroup = clipGroup; 12425 } 12426 return this.current.clipGroup; 12427 } 12428 _ensureTransformGroup() { 12429 if (!this.tgrp) { 12430 this.tgrp = this.svgFactory.createElement("svg:g"); 12431 this.tgrp.setAttributeNS(null, "transform", pm(this.transformMatrix)); 12432 if (this.current.activeClipUrl) { 12433 this._ensureClipGroup().append(this.tgrp); 12434 } else { 12435 this.svg.append(this.tgrp); 12436 } 12437 } 12438 return this.tgrp; 12439 } 12440} 12441exports.SVGGraphics = SVGGraphics; 12442 12443/***/ }), 12444/* 25 */ 12445/***/ ((__unused_webpack_module, exports) => { 12446 12447 12448 12449Object.defineProperty(exports, "__esModule", ({ 12450 value: true 12451})); 12452exports.XfaText = void 0; 12453class XfaText { 12454 static textContent(xfa) { 12455 const items = []; 12456 const output = { 12457 items, 12458 styles: Object.create(null) 12459 }; 12460 function walk(node) { 12461 if (!node) { 12462 return; 12463 } 12464 let str = null; 12465 const name = node.name; 12466 if (name === "#text") { 12467 str = node.value; 12468 } else if (!XfaText.shouldBuildText(name)) { 12469 return; 12470 } else if (node?.attributes?.textContent) { 12471 str = node.attributes.textContent; 12472 } else if (node.value) { 12473 str = node.value; 12474 } 12475 if (str !== null) { 12476 items.push({ 12477 str 12478 }); 12479 } 12480 if (!node.children) { 12481 return; 12482 } 12483 for (const child of node.children) { 12484 walk(child); 12485 } 12486 } 12487 walk(xfa); 12488 return output; 12489 } 12490 static shouldBuildText(name) { 12491 return !(name === "textarea" || name === "input" || name === "option" || name === "select"); 12492 } 12493} 12494exports.XfaText = XfaText; 12495 12496/***/ }), 12497/* 26 */ 12498/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 12499 12500 12501 12502Object.defineProperty(exports, "__esModule", ({ 12503 value: true 12504})); 12505exports.TextLayerRenderTask = void 0; 12506exports.renderTextLayer = renderTextLayer; 12507exports.updateTextLayer = updateTextLayer; 12508var _util = __w_pdfjs_require__(1); 12509var _display_utils = __w_pdfjs_require__(6); 12510const MAX_TEXT_DIVS_TO_RENDER = 100000; 12511const DEFAULT_FONT_SIZE = 30; 12512const DEFAULT_FONT_ASCENT = 0.8; 12513const ascentCache = new Map(); 12514function getCtx(size, isOffscreenCanvasSupported) { 12515 let ctx; 12516 if (isOffscreenCanvasSupported && _util.FeatureTest.isOffscreenCanvasSupported) { 12517 ctx = new OffscreenCanvas(size, size).getContext("2d", { 12518 alpha: false 12519 }); 12520 } else { 12521 const canvas = document.createElement("canvas"); 12522 canvas.width = canvas.height = size; 12523 ctx = canvas.getContext("2d", { 12524 alpha: false 12525 }); 12526 } 12527 return ctx; 12528} 12529function getAscent(fontFamily, isOffscreenCanvasSupported) { 12530 const cachedAscent = ascentCache.get(fontFamily); 12531 if (cachedAscent) { 12532 return cachedAscent; 12533 } 12534 const ctx = getCtx(DEFAULT_FONT_SIZE, isOffscreenCanvasSupported); 12535 ctx.font = `${DEFAULT_FONT_SIZE}px ${fontFamily}`; 12536 const metrics = ctx.measureText(""); 12537 let ascent = metrics.fontBoundingBoxAscent; 12538 let descent = Math.abs(metrics.fontBoundingBoxDescent); 12539 if (ascent) { 12540 const ratio = ascent / (ascent + descent); 12541 ascentCache.set(fontFamily, ratio); 12542 ctx.canvas.width = ctx.canvas.height = 0; 12543 return ratio; 12544 } 12545 ctx.strokeStyle = "red"; 12546 ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE); 12547 ctx.strokeText("g", 0, 0); 12548 let pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data; 12549 descent = 0; 12550 for (let i = pixels.length - 1 - 3; i >= 0; i -= 4) { 12551 if (pixels[i] > 0) {
12552 descent = Math.ceil(i / 4 / DEFAULT_FONT_SIZE); 12553 break; 12554 } 12555 } 12556 ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE); 12557 ctx.strokeText("A", 0, DEFAULT_FONT_SIZE); 12558 pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data; 12559 ascent = 0; 12560 for (let i = 0, ii = pixels.length; i < ii; i += 4) { 12561 if (pixels[i] > 0) { 12562 ascent = DEFAULT_FONT_SIZE - Math.floor(i / 4 / DEFAULT_FONT_SIZE); 12563 break; 12564 } 12565 } 12566 ctx.canvas.width = ctx.canvas.height = 0; 12567 if (ascent) { 12568 const ratio = ascent / (ascent + descent); 12569 ascentCache.set(fontFamily, ratio); 12570 return ratio; 12571 } 12572 ascentCache.set(fontFamily, DEFAULT_FONT_ASCENT); 12573 return DEFAULT_FONT_ASCENT; 12574} 12575function appendText(task, geom, styles) { 12576 const textDiv = document.createElement("span"); 12577 const textDivProperties = { 12578 angle: 0, 12579 canvasWidth: 0, 12580 hasText: geom.str !== "", 12581 hasEOL: geom.hasEOL, 12582 fontSize: 0 12583 }; 12584 task._textDivs.push(textDiv); 12585 const tx = _util.Util.transform(task._transform, geom.transform); 12586 let angle = Math.atan2(tx[1], tx[0]); 12587 const style = styles[geom.fontName]; 12588 if (style.vertical) { 12589 angle += Math.PI / 2; 12590 } 12591 const fontHeight = Math.hypot(tx[2], tx[3]); 12592 const fontAscent = fontHeight * getAscent(style.fontFamily, task._isOffscreenCanvasSupported); 12593 let left, top; 12594 if (angle === 0) { 12595 left = tx[4]; 12596 top = tx[5] - fontAscent; 12597 } else { 12598 left = tx[4] + fontAscent * Math.sin(angle); 12599 top = tx[5] - fontAscent * Math.cos(angle); 12600 } 12601 const scaleFactorStr = "calc(var(--scale-factor)*"; 12602 const divStyle = textDiv.style; 12603 if (task._container === task._rootContainer) { 12604 divStyle.left = `${(100 * left / task._pageWidth).toFixed(2)}%`; 12605 divStyle.top = `${(100 * top / task._pageHeight).toFixed(2)}%`; 12606 } else { 12607 divStyle.left = `${scaleFactorStr}${left.toFixed(2)}px)`; 12608 divStyle.top = `${scaleFactorStr}${top.toFixed(2)}px)`; 12609 } 12610 divStyle.fontSize = `${scaleFactorStr}${fontHeight.toFixed(2)}px)`; 12611 divStyle.fontFamily = style.fontFamily; 12612 textDivProperties.fontSize = fontHeight; 12613 textDiv.setAttribute("role", "presentation"); 12614 textDiv.textContent = geom.str; 12615 textDiv.dir = geom.dir; 12616 if (task._fontInspectorEnabled) { 12617 textDiv.dataset.fontName = geom.fontName; 12618 } 12619 if (angle !== 0) { 12620 textDivProperties.angle = angle * (180 / Math.PI); 12621 } 12622 let shouldScaleText = false; 12623 if (geom.str.length > 1) { 12624 shouldScaleText = true; 12625 } else if (geom.str !== " " && geom.transform[0] !== geom.transform[3]) { 12626 const absScaleX = Math.abs(geom.transform[0]), 12627 absScaleY = Math.abs(geom.transform[3]); 12628 if (absScaleX !== absScaleY && Math.max(absScaleX, absScaleY) / Math.min(absScaleX, absScaleY) > 1.5) { 12629 shouldScaleText = true; 12630 } 12631 } 12632 if (shouldScaleText) { 12633 textDivProperties.canvasWidth = style.vertical ? geom.height : geom.width; 12634 } 12635 task._textDivProperties.set(textDiv, textDivProperties); 12636 if (task._isReadableStream) { 12637 task._layoutText(textDiv); 12638 } 12639} 12640function layout(params) { 12641 const { 12642 div, 12643 scale, 12644 properties, 12645 ctx, 12646 prevFontSize, 12647 prevFontFamily 12648 } = params; 12649 const { 12650 style 12651 } = div; 12652 let transform = ""; 12653 if (properties.canvasWidth !== 0 && properties.hasText) { 12654 const { 12655 fontFamily 12656 } = style; 12657 const { 12658 canvasWidth, 12659 fontSize 12660 } = properties; 12661 if (prevFontSize !== fontSize || prevFontFamily !== fontFamily) { 12662 ctx.font = `${fontSize * scale}px ${fontFamily}`; 12663 params.prevFontSize = fontSize; 12664 params.prevFontFamily = fontFamily; 12665 } 12666 const { 12667 width 12668 } = ctx.measureText(div.textContent); 12669 if (width > 0) { 12670 transform = `scaleX(${canvasWidth * scale / width})`; 12671 } 12672 } 12673 if (properties.angle !== 0) { 12674 transform = `rotate(${properties.angle}deg) ${transform}`; 12675 } 12676 if (transform.length > 0) { 12677 style.transform = transform; 12678 } 12679} 12680function render(task) { 12681 if (task._canceled) { 12682 return; 12683 } 12684 const textDivs = task._textDivs; 12685 const capability = task._capability; 12686 const textDivsLength = textDivs.length; 12687 if (textDivsLength > MAX_TEXT_DIVS_TO_RENDER) { 12688 capability.resolve(); 12689 return; 12690 } 12691 if (!task._isReadableStream) { 12692 for (const textDiv of textDivs) { 12693 task._layoutText(textDiv); 12694 } 12695 } 12696 capability.resolve(); 12697} 12698class TextLayerRenderTask { 12699 constructor({ 12700 textContentSource, 12701 container, 12702 viewport, 12703 textDivs, 12704 textDivProperties, 12705 textContentItemsStr, 12706 isOffscreenCanvasSupported 12707 }) { 12708 this._textContentSource = textContentSource; 12709 this._isReadableStream = textContentSource instanceof ReadableStream; 12710 this._container = this._rootContainer = container; 12711 this._textDivs = textDivs || []; 12712 this._textContentItemsStr = textContentItemsStr || []; 12713 this._isOffscreenCanvasSupported = isOffscreenCanvasSupported; 12714 this._fontInspectorEnabled = !!globalThis.FontInspector?.enabled; 12715 this._reader = null; 12716 this._textDivProperties = textDivProperties || new WeakMap(); 12717 this._canceled = false;
12718 this._capability = new _util.PromiseCapability(); 12719 this._layoutTextParams = { 12720 prevFontSize: null, 12721 prevFontFamily: null, 12722 div: null, 12723 scale: viewport.scale * (globalThis.devicePixelRatio || 1), 12724 properties: null, 12725 ctx: getCtx(0, isOffscreenCanvasSupported) 12726 }; 12727 const { 12728 pageWidth, 12729 pageHeight, 12730 pageX, 12731 pageY 12732 } = viewport.rawDims; 12733 this._transform = [1, 0, 0, -1, -pageX, pageY + pageHeight]; 12734 this._pageWidth = pageWidth; 12735 this._pageHeight = pageHeight; 12736 (0, _display_utils.setLayerDimensions)(container, viewport); 12737 this._capability.promise.finally(() => { 12738 this._layoutTextParams = null; 12739 }).catch(() => {}); 12740 } 12741 get promise() { 12742 return this._capability.promise; 12743 } 12744 cancel() { 12745 this._canceled = true; 12746 if (this._reader) { 12747 this._reader.cancel(new _util.AbortException("TextLayer task cancelled.")).catch(() => {}); 12748 this._reader = null; 12749 } 12750 this._capability.reject(new _util.AbortException("TextLayer task cancelled.")); 12751 } 12752 _processItems(items, styleCache) { 12753 for (const item of items) { 12754 if (item.str === undefined) { 12755 if (item.type === "beginMarkedContentProps" || item.type === "beginMarkedContent") { 12756 const parent = this._container; 12757 this._container = document.createElement("span"); 12758 this._container.classList.add("markedContent"); 12759 if (item.id !== null) { 12760 this._container.setAttribute("id", `${item.id}`); 12761 } 12762 parent.append(this._container); 12763 } else if (item.type === "endMarkedContent") { 12764 this._container = this._container.parentNode; 12765 } 12766 continue; 12767 } 12768 this._textContentItemsStr.push(item.str); 12769 appendText(this, item, styleCache); 12770 } 12771 } 12772 _layoutText(textDiv) { 12773 const textDivProperties = this._layoutTextParams.properties = this._textDivProperties.get(textDiv); 12774 this._layoutTextParams.div = textDiv; 12775 layout(this._layoutTextParams); 12776 if (textDivProperties.hasText) { 12777 this._container.append(textDiv); 12778 } 12779 if (textDivProperties.hasEOL) { 12780 const br = document.createElement("br"); 12781 br.setAttribute("role", "presentation"); 12782 this._container.append(br); 12783 } 12784 } 12785 _render() { 12786 const capability = new _util.PromiseCapability(); 12787 let styleCache = Object.create(null); 12788 if (this._isReadableStream) { 12789 const pump = () => { 12790 this._reader.read().then(({ 12791 value, 12792 done 12793 }) => { 12794 if (done) { 12795 capability.resolve(); 12796 return; 12797 } 12798 Object.assign(styleCache, value.styles); 12799 this._processItems(value.items, styleCache); 12800 pump(); 12801 }, capability.reject); 12802 }; 12803 this._reader = this._textContentSource.getReader(); 12804 pump(); 12805 } else if (this._textContentSource) { 12806 const { 12807 items, 12808 styles 12809 } = this._textContentSource; 12810 this._processItems(items, styles); 12811 capability.resolve(); 12812 } else { 12813 throw new Error('No "textContentSource" parameter specified.'); 12814 } 12815 capability.promise.then(() => { 12816 styleCache = null; 12817 render(this); 12818 }, this._capability.reject); 12819 } 12820} 12821exports.TextLayerRenderTask = TextLayerRenderTask; 12822function renderTextLayer(params) { 12823 if (!params.textContentSource && (params.textContent || params.textContentStream)) { 12824 (0, _display_utils.deprecated)("The TextLayerRender `textContent`/`textContentStream` parameters " + "will be removed in the future, please use `textContentSource` instead."); 12825 params.textContentSource = params.textContent || params.textContentStream; 12826 } 12827 const { 12828 container, 12829 viewport 12830 }
12830 = params; 12831 const style = getComputedStyle(container); 12832 const visibility = style.getPropertyValue("visibility"); 12833 const scaleFactor = parseFloat(style.getPropertyValue("--scale-factor")); 12834 if (visibility === "visible" && (!scaleFactor || Math.abs(scaleFactor - viewport.scale) > 1e-5)) { 12835 console.error("The `--scale-factor` CSS-variable must be set, " + "to the same value as `viewport.scale`, " + "either on the `container`-element itself or higher up in the DOM."); 12836 } 12837 const task = new TextLayerRenderTask(params); 12838 task._render(); 12839 return task; 12840} 12841function updateTextLayer({ 12842 container, 12843 viewport, 12844 textDivs, 12845 textDivProperties, 12846 isOffscreenCanvasSupported, 12847 mustRotate = true, 12848 mustRescale = true 12849}) { 12850 if (mustRotate) { 12851 (0, _display_utils.setLayerDimensions)(container, { 12852 rotation: viewport.rotation 12853 }); 12854 } 12855 if (mustRescale) { 12856 const ctx = getCtx(0, isOffscreenCanvasSupported); 12857 const scale = viewport.scale * (globalThis.devicePixelRatio || 1); 12858 const params = { 12859 prevFontSize: null, 12860 prevFontFamily: null, 12861 div: null, 12862 scale, 12863 properties: null, 12864 ctx 12865 }; 12866 for (const div of textDivs) { 12867 params.properties = textDivProperties.get(div); 12868 params.div = div; 12869 layout(params); 12870 } 12871 } 12872} 12873 12874/***/ }), 12875/* 27 */ 12876/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 12877 12878 12879 12880Object.defineProperty(exports, "__esModule", ({ 12881 value: true 12882})); 12883exports.AnnotationEditorLayer = void 0; 12884var _util = __w_pdfjs_require__(1); 12885var _editor = __w_pdfjs_require__(4); 12886var _freetext = __w_pdfjs_require__(28); 12887var _ink = __w_pdfjs_require__(33); 12888var _display_utils = __w_pdfjs_require__(6); 12889var _stamp = __w_pdfjs_require__(34); 12890class AnnotationEditorLayer { 12891 #accessibilityManager; 12892 #allowClick = false; 12893 #annotationLayer = null; 12894 #boundPointerup = this.pointerup.bind(this); 12895 #boundPointerdown = this.pointerdown.bind(this); 12896 #editors = new Map(); 12897 #hadPointerDown = false; 12898 #isCleaningUp = false; 12899 #isDisabling = false; 12900 #uiManager; 12901 static _initialized = false; 12902 constructor({ 12903 uiManager, 12904 pageIndex, 12905 div, 12906 accessibilityManager, 12907 annotationLayer, 12908 viewport, 12909 l10n 12910 }) { 12911 const editorTypes = [_freetext.FreeTextEditor, _ink.InkEditor, _stamp.StampEditor]; 12912 if (!AnnotationEditorLayer._initialized) { 12913 AnnotationEditorLayer._initialized = true; 12914 for (const editorType of editorTypes) { 12915 editorType.initialize(l10n); 12916 } 12917 } 12918 uiManager.registerEditorTypes(editorTypes); 12919 this.#uiManager = uiManager; 12920 this.pageIndex = pageIndex; 12921 this.div = div; 12922 this.#accessibilityManager = accessibilityManager; 12923 this.#annotationLayer = annotationLayer; 12924 this.viewport = viewport; 12925 this.#uiManager.addLayer(this); 12926 } 12927 get isEmpty() { 12928 return this.#editors.size === 0; 12929 } 12930 updateToolbar(mode) { 12931 this.#uiManager.updateToolbar(mode); 12932 } 12933 updateMode(mode = this.#uiManager.getMode()) { 12934 this.#cleanup(); 12935 if (mode === _util.AnnotationEditorType.INK) { 12936 this.addInkEditorIfNeeded(false); 12937 this.disableClick(); 12938 } else { 12939 this.enableClick(); 12940 } 12941 if (mode !== _util.AnnotationEditorType.NONE) { 12942 this.div.classList.toggle("freeTextEditing", mode === _util.AnnotationEditorType.FREETEXT); 12943 this.div.classList.toggle("inkEditing", mode === _util.AnnotationEditorType.INK); 12944 this.div.classList.toggle("stampEditing", mode === _util.AnnotationEditorType.STAMP); 12945 this.div.hidden = false; 12946 } 12947 } 12948 addInkEditorIfNeeded(isCommitting) { 12949 if (!isCommitting && this.#uiManager.getMode() !== _util.AnnotationEditorType.INK) { 12950 return; 12951 } 12952 if (!isCommitting) { 12953 for (const editor of this.#editors.values()) { 12954 if (editor.isEmpty()) { 12955 editor.setInBackground(); 12956 return; 12957 } 12958 } 12959 } 12960 const editor = this.#createAndAddNewEditor({ 12961 offsetX: 0, 12962 offsetY: 0 12963 }, false); 12964 editor.setInBackground(); 12965 } 12966 setEditingState(isEditing) { 12967 this.#uiManager.setEditingState(isEditing); 12968 } 12969 addCommands(params) { 12970 this.#uiManager.addCommands(params); 12971 } 12972 enable() { 12973 this.div.style.pointerEvents = "auto"; 12974 const annotationElementIds = new Set(); 12975 for (const editor of this.#editors.values()) { 12976 editor.enableEditing(); 12977 if (editor.annotationElementId) { 12978 annotationElementIds.add(editor.annotationElementId); 12979 } 12980 } 12981 if (!this.#annotationLayer) { 12982 return; 12983 } 12984 const editables = this.#annotationLayer.getEditableAnnotations(); 12985 for (const editable of editables) { 12986 editable.hide(); 12987 if (this.#uiManager.isDeletedAnnotationElement(editable.data.id)) { 12988 continue; 12989 } 12990 if (annotationElementIds.has(editable.data.id)) { 12991 continue; 12992 } 12993 const editor = this.deserialize(editable); 12994 if (!editor) { 12995 continue; 12996 } 12997 this.addOrRebuild(editor); 12998 editor.enableEditing(); 12999 } 13000 } 13001 disable() { 13002 this.#isDisabling = true; 13003 this.div.style.pointerEvents = "none"; 13004 const hiddenAnnotationIds = new Set(); 13005 for (const editor of this.#editors.values()) { 13006 editor.disableEditing(); 13007 if (!editor.annotationElementId || editor.serialize() !== null) { 13008 hiddenAnnotationIds.add(editor.annotationElementId); 13009 continue; 13010 } 13011 this.getEditableAnnotation(editor.annotationElementId)?.show(); 13012 editor.remove(); 13013 } 13014 if (this.#annotationLayer) { 13015 const editables = this.#annotationLayer.getEditableAnnotations(); 13016 for (const editable of editables) { 13017 const { 13018 id 13019 } = editable.data; 13020 if (hiddenAnnotationIds.has(id) || this.#uiManager.isDeletedAnnotationElement(id)) { 13021 continue; 13022 } 13023 editable.show(); 13024 } 13025 } 13026 this.#cleanup(); 13027 if (this.isEmpty) { 13028 this.div.hidden = true; 13029 } 13030 this.#isDisabling = false;
13031 } 13032 getEditableAnnotation(id) { 13033 return this.#annotationLayer?.getEditableAnnotation(id) || null; 13034 } 13035 setActiveEditor(editor) { 13036 const currentActive = this.#uiManager.getActive(); 13037 if (currentActive === editor) { 13038 return; 13039 } 13040 this.#uiManager.setActiveEditor(editor); 13041 } 13042 enableClick() { 13043 this.div.addEventListener("pointerdown", this.#boundPointerdown); 13044 this.div.addEventListener("pointerup", this.#boundPointerup); 13045 } 13046 disableClick() { 13047 this.div.removeEventListener("pointerdown", this.#boundPointerdown); 13048 this.div.removeEventListener("pointerup", this.#boundPointerup); 13049 } 13050 attach(editor) { 13051 this.#editors.set(editor.id, editor); 13052 const { 13053 annotationElementId 13054 } = editor; 13055 if (annotationElementId && this.#uiManager.isDeletedAnnotationElement(annotationElementId)) { 13056 this.#uiManager.removeDeletedAnnotationElement(editor); 13057 } 13058 } 13059 detach(editor) { 13060 this.#editors.delete(editor.id); 13061 this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv); 13062 if (!this.#isDisabling && editor.annotationElementId) { 13063 this.#uiManager.addDeletedAnnotationElement(editor); 13064 } 13065 } 13066 remove(editor) { 13067 this.detach(editor); 13068 this.#uiManager.removeEditor(editor); 13069 if (editor.div.contains(document.activeElement)) { 13070 setTimeout(() => { 13071 this.#uiManager.focusMainContainer(); 13072 }, 0); 13073 } 13074 editor.div.remove(); 13075 editor.isAttachedToDOM = false; 13076 if (!this.#isCleaningUp) { 13077 this.addInkEditorIfNeeded(false); 13078 } 13079 } 13080 changeParent(editor) { 13081 if (editor.parent === this) { 13082 return; 13083 } 13084 if (editor.annotationElementId) { 13085 this.#uiManager.addDeletedAnnotationElement(editor.annotationElementId); 13086 _editor.AnnotationEditor.deleteAnnotationElement(editor); 13087 editor.annotationElementId = null; 13088 } 13089 this.attach(editor); 13090 editor.parent?.detach(editor); 13091 editor.setParent(this); 13092 if (editor.div && editor.isAttachedToDOM) { 13093 editor.div.remove(); 13094 this.div.append(editor.div); 13095 } 13096 } 13097 add(editor) { 13098 this.changeParent(editor); 13099 this.#uiManager.addEditor(editor); 13100 this.attach(editor); 13101 if (!editor.isAttachedToDOM) { 13102 const div = editor.render(); 13103 this.div.append(div); 13104 editor.isAttachedToDOM = true; 13105 } 13106 editor.fixAndSetPosition(); 13107 editor.onceAdded(); 13108 this.#uiManager.addToAnnotationStorage(editor); 13109 } 13110 moveEditorInDOM(editor) { 13111 if (!editor.isAttachedToDOM) { 13112 return; 13113 } 13114 const { 13115 activeElement 13116 } = document; 13117 if (editor.div.contains(activeElement)) { 13118 editor._focusEventsAllowed = false; 13119 setTimeout(() => { 13120 if (!editor.div.contains(document.activeElement)) { 13121 editor.div.addEventListener("focusin", () => { 13122 editor._focusEventsAllowed = true; 13123 }, { 13124 once: true 13125 }); 13126 activeElement.focus(); 13127 } else { 13128 editor._focusEventsAllowed = true; 13129 } 13130 }, 0); 13131 } 13132 editor._structTreeParentId = this.#accessibilityManager?.moveElementInDOM(this.div, editor.div, editor.contentDiv, true); 13133 } 13134 addOrRebuild(editor) { 13135 if (editor.needsToBeRebuilt()) { 13136 editor.rebuild(); 13137 } else { 13138 this.add(editor); 13139 } 13140 } 13141 addUndoableEditor(editor) { 13142 const cmd = () => editor._uiManager.rebuild(editor); 13143 const undo = () => { 13144 editor.remove(); 13145 }; 13146 this.addCommands({ 13147 cmd, 13148 undo, 13149 mustExec: false 13150 }); 13151 } 13152 getNextId() { 13153 return this.#uiManager.getId(); 13154 } 13155 #createNewEditor(params) { 13156 switch (this.#uiManager.getMode()) { 13157 case _util.AnnotationEditorType.FREETEXT: 13158 return new _freetext.FreeTextEditor(params); 13159 case _util.AnnotationEditorType.INK: 13160 return new _ink.InkEditor(params); 13161 case _util.AnnotationEditorType.STAMP: 13162 return new _stamp.StampEditor(params); 13163 } 13164 return null; 13165 } 13166 pasteEditor(mode, params) { 13167 this.#uiManager.updateToolbar(mode); 13168 this.#uiManager.updateMode(mode); 13169 const { 13170 offsetX, 13171 offsetY 13172 } = this.#getCenterPoint(); 13173 const id = this.getNextId(); 13174 const editor = this.#createNewEditor({ 13175 parent: this, 13176 id, 13177 x: offsetX, 13178 y: offsetY, 13179 uiManager: this.#uiManager, 13180 isCentered: true, 13181 ...params 13182 }); 13183 if (editor) { 13184 this.add(editor); 13185 } 13186 } 13187 deserialize(data) { 13188 switch (data.annotationType ?? data.annotationEditorType) { 13189 case _util.AnnotationEditorType.FREETEXT: 13190 return _freetext.FreeTextEditor.deserialize(data, this, this.#uiManager); 13191 case _util.AnnotationEditorType.INK: 13192 return _ink.InkEditor.deserialize(data, this, this.#uiManager); 13193 case _util.AnnotationEditorType.STAMP: 13194 return _stamp.StampEditor.deserialize(data, this, this.#uiManager); 13195 } 13196 return null; 13197 } 13198 #createAndAddNewEditor(event, isCentered) { 13199 const id = this.getNextId(); 13200 const editor = this.#createNewEditor({ 13201 parent: this, 13202 id, 13203 x: event.offsetX, 13204 y: event.offsetY, 13205 uiManager: this.#uiManager, 13206 isCentered 13207 }); 13208 if (editor) { 13209 this.add(editor); 13210 } 13211 return editor; 13212 } 13213 #getCenterPoint() { 13214 const { 13215 x, 13216 y, 13217 width, 13218 height 13219 } = this.div.getBoundingClientRect(); 13220 const tlX = Math.max(0, x); 13221 const tlY = Math.max(0, y); 13222 const brX = Math.min(window.innerWidth, x + width); 13223 const brY = Math.min(window.innerHeight, y + height); 13224 const centerX = (tlX + brX) / 2 - x; 13225 const centerY = (tlY + brY) / 2 - y; 13226 const [offsetX, offsetY] = this.viewport.rotation % 180 === 0 ? [centerX, centerY] : [centerY, centerX]; 13227 return { 13228 offsetX, 13229 offsetY 13230 }; 13231 } 13232 addNewEditor() { 13233 this.#createAndAddNewEditor(this.#getCenterPoint(), true); 13234 } 13235 setSelected(editor) { 13236 this.#uiManager.setSelected(editor); 13237 } 13238 toggleSelected(editor) { 13239 this.#uiManager.toggleSelected(editor); 13240 } 13241 isSelected(editor) { 13242 return this.#uiManager.isSelected(editor); 13243 } 13244 unselect(editor) { 13245 this.#uiManager.unselect(editor); 13246 } 13247 pointerup(event) { 13248 const { 13249 isMac 13250 } = _util.FeatureTest.platform; 13251 if (event.button !== 0 || event.ctrlKey && isMac) { 13252 return; 13253 } 13254 if (event.target !== this.div) { 13255 return; 13256 } 13257 if (!this.#hadPointerDown) { 13258 return; 13259 } 13260 this.#hadPointerDown = false;
13261 if (!this.#allowClick) { 13262 this.#allowClick = true; 13263 return; 13264 } 13265 if (this.#uiManager.getMode() === _util.AnnotationEditorType.STAMP) { 13266 this.#uiManager.unselectAll(); 13267 return; 13268 } 13269 this.#createAndAddNewEditor(event, false); 13270 } 13271 pointerdown(event) { 13272 if (this.#hadPointerDown) { 13273 this.#hadPointerDown = false; 13274 return; 13275 } 13276 const { 13277 isMac 13278 } = _util.FeatureTest.platform; 13279 if (event.button !== 0 || event.ctrlKey && isMac) { 13280 return; 13281 } 13282 if (event.target !== this.div) { 13283 return; 13284 } 13285 this.#hadPointerDown = true; 13286 const editor = this.#uiManager.getActive(); 13287 this.#allowClick = !editor || editor.isEmpty(); 13288 } 13289 findNewParent(editor, x, y) { 13290 const layer = this.#uiManager.findParent(x, y); 13291 if (layer === null || layer === this) { 13292 return false; 13293 } 13294 layer.changeParent(editor); 13295 return true; 13296 } 13297 destroy() { 13298 if (this.#uiManager.getActive()?.parent === this) { 13299 this.#uiManager.commitOrRemove(); 13300 this.#uiManager.setActiveEditor(null); 13301 } 13302 for (const editor of this.#editors.values()) { 13303 this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv); 13304 editor.setParent(null); 13305 editor.isAttachedToDOM = false; 13306 editor.div.remove(); 13307 } 13308 this.div = null; 13309 this.#editors.clear(); 13310 this.#uiManager.removeLayer(this); 13311 } 13312 #cleanup() { 13313 this.#isCleaningUp = true; 13314 for (const editor of this.#editors.values()) { 13315 if (editor.isEmpty()) { 13316 editor.remove(); 13317 } 13318 } 13319 this.#isCleaningUp = false; 13320 } 13321 render({ 13322 viewport 13323 }) { 13324 this.viewport = viewport; 13325 (0, _display_utils.setLayerDimensions)(this.div, viewport); 13326 for (const editor of this.#uiManager.getEditors(this.pageIndex)) { 13327 this.add(editor); 13328 } 13329 this.updateMode(); 13330 } 13331 update({ 13332 viewport 13333 }) { 13334 this.#uiManager.commitOrRemove(); 13335 this.viewport = viewport; 13336 (0, _display_utils.setLayerDimensions)(this.div, { 13337 rotation: viewport.rotation 13338 }); 13339 this.updateMode(); 13340 } 13341 get pageDimensions() { 13342 const { 13343 pageWidth, 13344 pageHeight 13345 } = this.viewport.rawDims; 13346 return [pageWidth, pageHeight]; 13347 } 13348} 13349exports.AnnotationEditorLayer = AnnotationEditorLayer; 13350 13351/***/ }), 13352/* 28 */ 13353/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 13354 13355 13356 13357Object.defineProperty(exports, "__esModule", ({ 13358 value: true 13359})); 13360exports.FreeTextEditor = void 0; 13361var _util = __w_pdfjs_require__(1); 13362var _tools = __w_pdfjs_require__(5); 13363var _editor = __w_pdfjs_require__(4); 13364var _annotation_layer = __w_pdfjs_require__(29); 13365class FreeTextEditor extends _editor.AnnotationEditor { 13366 #boundEditorDivBlur = this.editorDivBlur.bind(this); 13367 #boundEditorDivFocus = this.editorDivFocus.bind(this); 13368 #boundEditorDivInput = this.editorDivInput.bind(this); 13369 #boundEditorDivKeydown = this.editorDivKeydown.bind(this); 13370 #color; 13371 #content = ""; 13372 #editorDivId = `${this.id}-editor`; 13373 #fontSize; 13374 #initialData = null; 13375 static _freeTextDefaultContent = ""; 13376 static _internalPadding = 0; 13377 static _defaultColor = null; 13378 static _defaultFontSize = 10; 13379 static get _keyboardManager() { 13380 const proto = FreeTextEditor.prototype; 13381 const arrowChecker = self => self.isEmpty(); 13382 const small = _tools.AnnotationEditorUIManager.TRANSLATE_SMALL; 13383 const big = _tools.AnnotationEditorUIManager.TRANSLATE_BIG; 13384 return (0, _util.shadow)(this, "_keyboardManager", new _tools.KeyboardManager([[["ctrl+s", "mac+meta+s", "ctrl+p", "mac+meta+p"], proto.commitOrRemove, { 13385 bubbles: true 13386 }], [["ctrl+Enter", "mac+meta+Enter", "Escape", "mac+Escape"], proto.commitOrRemove], [["ArrowLeft", "mac+ArrowLeft"], proto._translateEmpty, { 13387 args: [-small, 0], 13388 checker: arrowChecker 13389 }], [["ctrl+ArrowLeft", "mac+shift+ArrowLeft"], proto._translateEmpty, { 13390 args: [-big, 0], 13391 checker: arrowChecker 13392 }], [["ArrowRight", "mac+ArrowRight"], proto._translateEmpty, { 13393 args: [small, 0], 13394 checker: arrowChecker 13395 }], [["ctrl+ArrowRight", "mac+shift+ArrowRight"], proto._translateEmpty, { 13396 args: [big, 0], 13397 checker: arrowChecker 13398 }], [["ArrowUp", "mac+ArrowUp"], proto._translateEmpty, { 13399 args: [0, -small], 13400 checker: arrowChecker 13401 }], [["ctrl+ArrowUp", "mac+shift+ArrowUp"], proto._translateEmpty, { 13402 args: [0, -big], 13403 checker: arrowChecker 13404 }], [["ArrowDown", "mac+ArrowDown"], proto._translateEmpty, { 13405 args: [0, small], 13406 checker: arrowChecker 13407 }], [["ctrl+ArrowDown", "mac+shift+ArrowDown"], proto._translateEmpty, { 13408 args: [0, big], 13409 checker: arrowChecker 13410 }]])); 13411 } 13412 static _type = "freetext"; 13413 constructor(params) { 13414 super({ 13415 ...params, 13416 name: "freeTextEditor" 13417 }); 13418 this.#color = params.color || FreeTextEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor; 13419 this.#fontSize = params.fontSize || FreeTextEditor._defaultFontSize; 13420 } 13421 static initialize(l10n) { 13422 _editor.AnnotationEditor.initialize(l10n, {
13423 strings: ["free_text2_default_content", "editor_free_text2_aria_label"] 13424 }); 13425 const style = getComputedStyle(document.documentElement); 13426 this._internalPadding = parseFloat(style.getPropertyValue("--freetext-padding")); 13427 } 13428 static updateDefaultParams(type, value) { 13429 switch (type) { 13430 case _util.AnnotationEditorParamsType.FREETEXT_SIZE: 13431 FreeTextEditor._defaultFontSize = value; 13432 break; 13433 case _util.AnnotationEditorParamsType.FREETEXT_COLOR: 13434 FreeTextEditor._defaultColor = value; 13435 break; 13436 } 13437 } 13438 updateParams(type, value) { 13439 switch (type) { 13440 case _util.AnnotationEditorParamsType.FREETEXT_SIZE: 13441 this.#updateFontSize(value); 13442 break; 13443 case _util.AnnotationEditorParamsType.FREETEXT_COLOR: 13444 this.#updateColor(value); 13445 break; 13446 } 13447 } 13448 static get defaultPropertiesToUpdate() { 13449 return [[_util.AnnotationEditorParamsType.FREETEXT_SIZE, FreeTextEditor._defaultFontSize], [_util.AnnotationEditorParamsType.FREETEXT_COLOR, FreeTextEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor]]; 13450 } 13451 get propertiesToUpdate() { 13452 return [[_util.AnnotationEditorParamsType.FREETEXT_SIZE, this.#fontSize], [_util.AnnotationEditorParamsType.FREETEXT_COLOR, this.#color]]; 13453 } 13454 #updateFontSize(fontSize) { 13455 const setFontsize = size => { 13456 this.editorDiv.style.fontSize = `calc(${size}px * var(--scale-factor))`; 13457 this.translate(0, -(size - this.#fontSize) * this.parentScale); 13458 this.#fontSize = size; 13459 this.#setEditorDimensions(); 13460 }; 13461 const savedFontsize = this.#fontSize; 13462 this.addCommands({ 13463 cmd: () => { 13464 setFontsize(fontSize); 13465 }, 13466 undo: () => { 13467 setFontsize(savedFontsize); 13468 }, 13469 mustExec: true, 13470 type: _util.AnnotationEditorParamsType.FREETEXT_SIZE, 13471 overwriteIfSameType: true, 13472 keepUndo: true 13473 }); 13474 } 13475 #updateColor(color) { 13476 const savedColor = this.#color; 13477 this.addCommands({ 13478 cmd: () => { 13479 this.#color = this.editorDiv.style.color = color; 13480 }, 13481 undo: () => { 13482 this.#color = this.editorDiv.style.color = savedColor; 13483 }, 13484 mustExec: true, 13485 type: _util.AnnotationEditorParamsType.FREETEXT_COLOR, 13486 overwriteIfSameType: true, 13487 keepUndo: true 13488 }); 13489 } 13490 _translateEmpty(x, y) { 13491 this._uiManager.translateSelectedEditors(x, y, true); 13492 } 13493 getInitialTranslation() { 13494 const scale = this.parentScale; 13495 return [-FreeTextEditor._internalPadding * scale, -(FreeTextEditor._internalPadding + this.#fontSize) * scale]; 13496 } 13497 rebuild() { 13498 if (!this.parent) { 13499 return; 13500 } 13501 super.rebuild(); 13502 if (this.div === null) { 13503 return; 13504 } 13505 if (!this.isAttachedToDOM) { 13506 this.parent.add(this); 13507 } 13508 } 13509 enableEditMode() { 13510 if (this.isInEditMode()) { 13511 return; 13512 } 13513 this.parent.setEditingState(false); 13514 this.parent.updateToolbar(_util.AnnotationEditorType.FREETEXT); 13515 super.enableEditMode(); 13516 this.overlayDiv.classList.remove("enabled"); 13517 this.editorDiv.contentEditable = true; 13518 this._isDraggable = false; 13519 this.div.removeAttribute("aria-activedescendant"); 13520 this.editorDiv.addEventListener("keydown", this.#boundEditorDivKeydown); 13521 this.editorDiv.addEventListener("focus", this.#boundEditorDivFocus); 13522 this.editorDiv.addEventListener("blur", this.#boundEditorDivBlur); 13523 this.editorDiv.addEventListener("input", this.#boundEditorDivInput); 13524 } 13525 disableEditMode() { 13526 if (!this.isInEditMode()) { 13527 return; 13528 } 13529 this.parent.setEditingState(true); 13530 super.disableEditMode(); 13531 this.overlayDiv.classList.add("enabled"); 13532 this.editorDiv.contentEditable = false; 13533 this.div.setAttribute("aria-activedescendant", this.#editorDivId); 13534 this._isDraggable = true; 13535 this.editorDiv.removeEventListener("keydown", this.#boundEditorDivKeydown); 13536 this.editorDiv.removeEventListener("focus", this.#boundEditorDivFocus); 13537 this.editorDiv.removeEventListener("blur", this.#boundEditorDivBlur); 13538 this.editorDiv.removeEventListener("input", this.#boundEditorDivInput); 13539 this.div.focus({ 13540 preventScroll: true 13541 }); 13542 this.isEditing = false;
13543 this.parent.div.classList.add("freeTextEditing"); 13544 } 13545 focusin(event) { 13546 if (!this._focusEventsAllowed) { 13547 return; 13548 } 13549 super.focusin(event); 13550 if (event.target !== this.editorDiv) { 13551 this.editorDiv.focus(); 13552 } 13553 } 13554 onceAdded() { 13555 if (this.width) { 13556 this.#cheatInitialRect(); 13557 return; 13558 } 13559 this.enableEditMode(); 13560 this.editorDiv.focus(); 13561 if (this._initialOptions?.isCentered) { 13562 this.center(); 13563 } 13564 this._initialOptions = null; 13565 } 13566 isEmpty() { 13567 return !this.editorDiv || this.editorDiv.innerText.trim() === ""; 13568 } 13569 remove() { 13570 this.isEditing = false; 13571 if (this.parent) { 13572 this.parent.setEditingState(true); 13573 this.parent.div.classList.add("freeTextEditing"); 13574 } 13575 super.remove(); 13576 } 13577 #extractText() { 13578 const divs = this.editorDiv.getElementsByTagName("div"); 13579 if (divs.length === 0) { 13580 return this.editorDiv.innerText; 13581 } 13582 const buffer = []; 13583 for (const div of divs) { 13584 buffer.push(div.innerText.replace(/\r\n?|\n/, "")); 13585 } 13586 return buffer.join("\n"); 13587 } 13588 #setEditorDimensions() { 13589 const [parentWidth, parentHeight] = this.parentDimensions; 13590 let rect; 13591 if (this.isAttachedToDOM) { 13592 rect = this.div.getBoundingClientRect(); 13593 } else { 13594 const { 13595 currentLayer, 13596 div 13597 } = this; 13598 const savedDisplay = div.style.display; 13599 div.style.display = "hidden"; 13600 currentLayer.div.append(this.div); 13601 rect = div.getBoundingClientRect(); 13602 div.remove(); 13603 div.style.display = savedDisplay; 13604 } 13605 if (this.rotation % 180 === this.parentRotation % 180) { 13606 this.width = rect.width / parentWidth; 13607 this.height = rect.height / parentHeight; 13608 } else { 13609 this.width = rect.height / parentWidth; 13610 this.height = rect.width / parentHeight; 13611 } 13612 this.fixAndSetPosition(); 13613 } 13614 commit() { 13615 if (!this.isInEditMode()) { 13616 return; 13617 } 13618 super.commit(); 13619 this.disableEditMode(); 13620 const savedText = this.#content; 13621 const newText = this.#content = this.#extractText().trimEnd(); 13622 if (savedText === newText) { 13623 return; 13624 } 13625 const setText = text => { 13626 this.#content = text; 13627 if (!text) { 13628 this.remove(); 13629 return; 13630 } 13631 this.#setContent(); 13632 this._uiManager.rebuild(this); 13633 this.#setEditorDimensions(); 13634 }; 13635 this.addCommands({ 13636 cmd: () => { 13637 setText(newText); 13638 }, 13639 undo: () => { 13640 setText(savedText); 13641 }, 13642 mustExec: false 13643 }); 13644 this.#setEditorDimensions(); 13645 } 13646 shouldGetKeyboardEvents() { 13647 return this.isInEditMode(); 13648 } 13649 enterInEditMode() { 13650 this.enableEditMode(); 13651 this.editorDiv.focus(); 13652 } 13653 dblclick(event) { 13654 this.enterInEditMode(); 13655 } 13656 keydown(event) { 13657 if (event.target === this.div && event.key === "Enter") { 13658 this.enterInEditMode(); 13659 event.preventDefault(); 13660 } 13661 } 13662 editorDivKeydown(event) { 13663 FreeTextEditor._keyboardManager.exec(this, event); 13664 } 13665 editorDivFocus(event) { 13666 this.isEditing = true; 13667 } 13668 editorDivBlur(event) { 13669 this.isEditing = false; 13670 } 13671 editorDivInput(event) { 13672 this.parent.div.classList.toggle("freeTextEditing", this.isEmpty()); 13673 } 13674 disableEditing() { 13675 this.editorDiv.setAttribute("role", "comment"); 13676 this.editorDiv.removeAttribute("aria-multiline"); 13677 } 13678 enableEditing() { 13679 this.editorDiv.setAttribute("role", "textbox"); 13680 this.editorDiv.setAttribute("aria-multiline", true); 13681 } 13682 render() { 13683 if (this.div) { 13684 return this.div; 13685 } 13686 let baseX, baseY; 13687 if (this.width) { 13688 baseX = this.x; 13689 baseY = this.y; 13690 } 13691 super.render(); 13692 this.editorDiv = document.createElement("div"); 13693 this.editorDiv.className = "internal"; 13694 this.editorDiv.setAttribute("id", this.#editorDivId); 13695 this.enableEditing(); 13696 _editor.AnnotationEditor._l10nPromise.get("editor_free_text2_aria_label").then(msg => this.editorDiv?.setAttribute("aria-label", msg)); 13697 _editor.AnnotationEditor._l10nPromise.get("free_text2_default_content").then(msg => this.editorDiv?.setAttribute("default-content", msg)); 13698 this.editorDiv.contentEditable = true; 13699 const { 13700 style 13701 } = this.editorDiv; 13702 style.fontSize = `calc(${this.#fontSize}px * var(--scale-factor))`; 13703 style.color = this.#color; 13704 this.div.append(this.editorDiv); 13705 this.overlayDiv = document.createElement("div"); 13706 this.overlayDiv.classList.add("overlay", "enabled"); 13707 this.div.append(this.overlayDiv); 13708 (0, _tools.bindEvents)(this, this.div, ["dblclick", "keydown"]); 13709 if (this.width) { 13710 const [parentWidth, parentHeight] = this.parentDimensions; 13711 if (this.annotationElementId) { 13712 const { 13713 position 13714 } = this.#initialData; 13715 let [tx, ty] = this.getInitialTranslation(); 13716 [tx, ty] = this.pageTranslationToScreen(tx, ty); 13717 const [pageWidth, pageHeight] = this.pageDimensions; 13718 const [pageX, pageY] = this.pageTranslation; 13719 let posX, posY; 13720 switch (this.rotation) { 13721 case 0: 13722 posX = baseX + (position[0] - pageX) / pageWidth; 13723 posY = baseY + this.height - (position[1] - pageY) / pageHeight; 13724 break; 13725 case 90: 13726 posX = baseX + (position[0] - pageX) / pageWidth; 13727 posY = baseY - (position[1] - pageY) / pageHeight; 13728 [tx, ty] = [ty, -tx]; 13729 break; 13730 case 180: 13731 posX = baseX - this.width + (position[0] - pageX) / pageWidth; 13732 posY = baseY - (position[1] - pageY) / pageHeight; 13733 [tx, ty] = [-tx, -ty]; 13734 break; 13735 case 270: 13736 posX = baseX + (position[0] - pageX - this.height * pageHeight) / pageWidth; 13737 posY = baseY + (position[1] - pageY - this.width * pageWidth) / pageHeight; 13738 [tx, ty] = [-ty, tx]; 13739 break; 13740 } 13741 this.setAt(posX * parentWidth, posY * parentHeight, tx, ty); 13742 } else { 13743 this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); 13744 } 13745 this.#setContent(); 13746 this._isDraggable = true; 13747 this.editorDiv.contentEditable = false;
13748 } else { 13749 this._isDraggable = false; 13750 this.editorDiv.contentEditable = true; 13751 } 13752 return this.div; 13753 } 13754 #setContent() { 13755 this.editorDiv.replaceChildren(); 13756 if (!this.#content) { 13757 return; 13758 } 13759 for (const line of this.#content.split("\n")) { 13760 const div = document.createElement("div"); 13761 div.append(line ? document.createTextNode(line) : document.createElement("br")); 13762 this.editorDiv.append(div); 13763 } 13764 } 13765 get contentDiv() { 13766 return this.editorDiv; 13767 } 13768 static deserialize(data, parent, uiManager) { 13769 let initialData = null; 13770 if (data instanceof _annotation_layer.FreeTextAnnotationElement) { 13771 const { 13772 data: { 13773 defaultAppearanceData: { 13774 fontSize, 13775 fontColor 13776 }, 13777 rect, 13778 rotation, 13779 id 13780 }, 13781 textContent, 13782 textPosition, 13783 parent: { 13784 page: { 13785 pageNumber 13786 } 13787 } 13788 } = data; 13789 if (!textContent || textContent.length === 0) { 13790 return null; 13791 } 13792 initialData = data = { 13793 annotationType: _util.AnnotationEditorType.FREETEXT, 13794 color: Array.from(fontColor), 13795 fontSize, 13796 value: textContent.join("\n"), 13797 position: textPosition, 13798 pageIndex: pageNumber - 1, 13799 rect, 13800 rotation, 13801 id, 13802 deleted: false 13803 }; 13804 } 13805 const editor = super.deserialize(data, parent, uiManager); 13806 editor.#fontSize = data.fontSize; 13807 editor.#color = _util.Util.makeHexColor(...data.color); 13808 editor.#content = data.value; 13809 editor.annotationElementId = data.id || null; 13810 editor.#initialData = initialData; 13811 return editor; 13812 } 13813 serialize(isForCopying = false) { 13814 if (this.isEmpty()) { 13815 return null; 13816 } 13817 if (this.deleted) { 13818 return { 13819 pageIndex: this.pageIndex, 13820 id: this.annotationElementId, 13821 deleted: true 13822 }; 13823 } 13824 const padding = FreeTextEditor._internalPadding * this.parentScale; 13825 const rect = this.getRect(padding, padding); 13826 const color = _editor.AnnotationEditor._colorManager.convert(this.isAttachedToDOM ? getComputedStyle(this.editorDiv).color : this.#color); 13827 const serialized = { 13828 annotationType: _util.AnnotationEditorType.FREETEXT, 13829 color, 13830 fontSize: this.#fontSize, 13831 value: this.#content, 13832 pageIndex: this.pageIndex, 13833 rect, 13834 rotation: this.rotation, 13835 structTreeParentId: this._structTreeParentId 13836 }; 13837 if (isForCopying) { 13838 return serialized; 13839 } 13840 if (this.annotationElementId && !this.#hasElementChanged(serialized)) { 13841 return null; 13842 } 13843 serialized.id = this.annotationElementId; 13844 return serialized; 13845 } 13846 #hasElementChanged(serialized) { 13847 const { 13848 value, 13849 fontSize, 13850 color, 13851 rect, 13852 pageIndex 13853 } = this.#initialData; 13854 return serialized.value !== value || serialized.fontSize !== fontSize || serialized.rect.some((x, i) => Math.abs(x - rect[i]) >= 1) || serialized.color.some((c, i) => c !== color[i]) || serialized.pageIndex !== pageIndex; 13855 } 13856 #cheatInitialRect(delayed = false) { 13857 if (!this.annotationElementId) { 13858 return; 13859 } 13860 this.#setEditorDimensions(); 13861 if (!delayed && (this.width === 0 || this.height === 0)) { 13862 setTimeout(() => this.#cheatInitialRect(true), 0); 13863 return; 13864 } 13865 const padding = FreeTextEditor._internalPadding * this.parentScale; 13866 this.#initialData.rect = this.getRect(padding, padding); 13867 } 13868} 13869exports.FreeTextEditor = FreeTextEditor; 13870 13871/***/ }), 13872/* 29 */ 13873/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 13874 13875 13876 13877Object.defineProperty(exports, "__esModule", ({ 13878 value: true 13879})); 13880exports.StampAnnotationElement = exports.InkAnnotationElement = exports.FreeTextAnnotationElement = exports.AnnotationLayer = void 0; 13881var _util = __w_pdfjs_require__(1); 13882var _display_utils = __w_pdfjs_require__(6); 13883var _annotation_storage = __w_pdfjs_require__(3); 13884var _scripting_utils = __w_pdfjs_require__(30); 13885var _displayL10n_utils = __w_pdfjs_require__(31); 13886var _xfa_layer = __w_pdfjs_require__(32); 13887const DEFAULT_TAB_INDEX = 1000; 13888const DEFAULT_FONT_SIZE = 9; 13889const GetElementsByNameSet = new WeakSet(); 13890function getRectDims(rect) { 13891 return { 13892 width: rect[2] - rect[0], 13893 height: rect[3] - rect[1] 13894 }; 13895} 13896class AnnotationElementFactory { 13897 static create(parameters) { 13898 const subtype = parameters.data.annotationType; 13899 switch (subtype) { 13900 case _util.AnnotationType.LINK: 13901 return new LinkAnnotationElement(parameters); 13902 case _util.AnnotationType.TEXT: 13903 return new TextAnnotationElement(parameters); 13904 case _util.AnnotationType.WIDGET: 13905 const fieldType = parameters.data.fieldType; 13906 switch (fieldType) { 13907 case "Tx": 13908 return new TextWidgetAnnotationElement(parameters); 13909 case "Btn": 13910 if (parameters.data.radioButton) { 13911 return new RadioButtonWidgetAnnotationElement(parameters); 13912 } else if (parameters.data.checkBox) { 13913 return new CheckboxWidgetAnnotationElement(parameters); 13914 } 13915 return new PushButtonWidgetAnnotationElement(parameters); 13916 case "Ch": 13917 return new ChoiceWidgetAnnotationElement(parameters); 13918 case "Sig": 13919 return new SignatureWidgetAnnotationElement(parameters); 13920 } 13921 return new WidgetAnnotationElement(parameters); 13922 case _util.AnnotationType.POPUP: 13923 return new PopupAnnotationElement(parameters); 13924 case _util.AnnotationType.FREETEXT: 13925 return new FreeTextAnnotationElement(parameters); 13926 case _util.AnnotationType.LINE: 13927 return new LineAnnotationElement(parameters); 13928 case _util.AnnotationType.SQUARE: 13929 return new SquareAnnotationElement(parameters); 13930 case _util.AnnotationType.CIRCLE: 13931 return new CircleAnnotationElement(parameters); 13932 case _util.AnnotationType.POLYLINE: 13933 return new PolylineAnnotationElement(parameters); 13934 case _util.AnnotationType.CARET: 13935 return new CaretAnnotationElement(parameters); 13936 case _util.AnnotationType.INK: 13937 return new InkAnnotationElement(parameters); 13938 case _util.AnnotationType.POLYGON: 13939 return new PolygonAnnotationElement(parameters); 13940 case _util.AnnotationType.HIGHLIGHT: 13941 return new HighlightAnnotationElement(parameters); 13942 case _util.AnnotationType.UNDERLINE: 13943 return new UnderlineAnnotationElement(parameters); 13944 case _util.AnnotationType.SQUIGGLY: 13945 return new SquigglyAnnotationElement(parameters); 13946 case _util.AnnotationType.STRIKEOUT: 13947 return new StrikeOutAnnotationElement(parameters); 13948 case _util.AnnotationType.STAMP: 13949 return new StampAnnotationElement(parameters); 13950 case _util.AnnotationType.FILEATTACHMENT: 13951 return new FileAttachmentAnnotationElement(parameters); 13952 default: 13953 return new AnnotationElement(parameters); 13954 } 13955 } 13956} 13957class AnnotationElement { 13958 #hasBorder = false;
13959 constructor(parameters, { 13960 isRenderable = false, 13961 ignoreBorder = false, 13962 createQuadrilaterals = false 13963 } = {}) { 13964 this.isRenderable = isRenderable; 13965 this.data = parameters.data; 13966 this.layer = parameters.layer; 13967 this.linkService = parameters.linkService; 13968 this.downloadManager = parameters.downloadManager; 13969 this.imageResourcesPath = parameters.imageResourcesPath; 13970 this.renderForms = parameters.renderForms; 13971 this.svgFactory = parameters.svgFactory; 13972 this.annotationStorage = parameters.annotationStorage; 13973 this.enableScripting = parameters.enableScripting; 13974 this.hasJSActions = parameters.hasJSActions; 13975 this._fieldObjects = parameters.fieldObjects; 13976 this.parent = parameters.parent; 13977 if (isRenderable) { 13978 this.container = this._createContainer(ignoreBorder); 13979 } 13980 if (createQuadrilaterals) { 13981 this._createQuadrilaterals(); 13982 } 13983 } 13984 static _hasPopupData({ 13985 titleObj, 13986 contentsObj, 13987 richText 13988 }) { 13989 return !!(titleObj?.str || contentsObj?.str || richText?.str); 13990 } 13991 get hasPopupData() { 13992 return AnnotationElement._hasPopupData(this.data); 13993 } 13994 _createContainer(ignoreBorder) { 13995 const { 13996 data, 13997 parent: { 13998 page, 13999 viewport 14000 } 14001 } = this; 14002 const container = document.createElement("section"); 14003 container.setAttribute("data-annotation-id", data.id); 14004 if (!(this instanceof WidgetAnnotationElement)) { 14005 container.tabIndex = DEFAULT_TAB_INDEX; 14006 } 14007 container.style.zIndex = this.parent.zIndex++; 14008 if (this.data.popupRef) { 14009 container.setAttribute("aria-haspopup", "dialog"); 14010 } 14011 if (data.noRotate) { 14012 container.classList.add("norotate"); 14013 } 14014 const { 14015 pageWidth, 14016 pageHeight, 14017 pageX, 14018 pageY 14019 } = viewport.rawDims; 14020 if (!data.rect || this instanceof PopupAnnotationElement) { 14021 const { 14022 rotation 14023 } = data; 14024 if (!data.hasOwnCanvas && rotation !== 0) { 14025 this.setRotation(rotation, container); 14026 } 14027 return container; 14028 } 14029 const { 14030 width, 14031 height 14032 } = getRectDims(data.rect); 14033 const rect = _util.Util.normalizeRect([data.rect[0], page.view[3] - data.rect[1] + page.view[1], data.rect[2], page.view[3] - data.rect[3] + page.view[1]]); 14034 if (!ignoreBorder && data.borderStyle.width > 0) { 14035 container.style.borderWidth = `${data.borderStyle.width}px`; 14036 const horizontalRadius = data.borderStyle.horizontalCornerRadius; 14037 const verticalRadius = data.borderStyle.verticalCornerRadius; 14038 if (horizontalRadius > 0 || verticalRadius > 0) { 14039 const radius = `calc(${horizontalRadius}px * var(--scale-factor)) / calc(${verticalRadius}px * var(--scale-factor))`; 14040 container.style.borderRadius = radius; 14041 } else if (this instanceof RadioButtonWidgetAnnotationElement) { 14042 const radius = `calc(${width}px * var(--scale-factor)) / calc(${height}px * var(--scale-factor))`; 14043 container.style.borderRadius = radius; 14044 } 14045 switch (data.borderStyle.style) { 14046 case _util.AnnotationBorderStyleType.SOLID: 14047 container.style.borderStyle = "solid"; 14048 break; 14049 case _util.AnnotationBorderStyleType.DASHED: 14050 container.style.borderStyle = "dashed"; 14051 break; 14052 case _util.AnnotationBorderStyleType.BEVELED: 14053 (0, _util.warn)("Unimplemented border style: beveled"); 14054 break; 14055 case _util.AnnotationBorderStyleType.INSET: 14056 (0, _util.warn)("Unimplemented border style: inset"); 14057 break; 14058 case _util.AnnotationBorderStyleType.UNDERLINE: 14059 container.style.borderBottomStyle = "solid"; 14060 break; 14061 default: 14062 break; 14063 } 14064 const borderColor = data.borderColor || null; 14065 if (borderColor) { 14066 this.#hasBorder = true; 14067 container.style.borderColor = _util.Util.makeHexColor(borderColor[0] | 0, borderColor[1] | 0, borderColor[2] | 0); 14068 } else { 14069 container.style.borderWidth = 0; 14070 } 14071 } 14072 container.style.left = `${100 * (rect[0] - pageX) / pageWidth}%`; 14073 container.style.top = `${100 * (rect[1] - pageY) / pageHeight}%`; 14074 const { 14075 rotation 14076 } = data; 14077 if (data.hasOwnCanvas || rotation === 0) { 14078 container.style.width = `${100 * width / pageWidth}%`; 14079 container.style.height = `${100 * height / pageHeight}%`; 14080 } else { 14081 this.setRotation(rotation, container); 14082 } 14083 return container; 14084 } 14085 setRotation(angle, container = this.container) { 14086 if (!this.data.rect) { 14087 return; 14088 } 14089 const { 14090 pageWidth, 14091 pageHeight 14092 } = this.parent.viewport.rawDims; 14093 const { 14094 width, 14095 height 14096 } = getRectDims(this.data.rect); 14097 let elementWidth, elementHeight; 14098 if (angle % 180 === 0) { 14099 elementWidth = 100 * width / pageWidth; 14100 elementHeight = 100 * height / pageHeight; 14101 } else { 14102 elementWidth = 100 * height / pageWidth; 14103 elementHeight = 100 * width / pageHeight; 14104 } 14105 container.style.width = `${elementWidth}%`; 14106 container.style.height = `${elementHeight}%`; 14107 container.setAttribute("data-main-rotation", (360 - angle) % 360); 14108 } 14109 get _commonActions() { 14110 const setColor = (jsName, styleName, event) => { 14111 const color = event.detail[jsName]; 14112 const colorType = color[0]; 14113 const colorArray = color.slice(1); 14114 event.target.style[styleName] = _scripting_utils.ColorConverters[`${colorType}_HTML`](colorArray); 14115 this.annotationStorage.setValue(this.data.id, { 14116 [styleName]: _scripting_utils.ColorConverters[`${colorType}_rgb`](colorArray) 14117 }); 14118 }; 14119 return (0, _util.shadow)(this, "_commonActions", { 14120 display: event => { 14121 const { 14122 display 14123 } = event.detail; 14124 const hidden = display % 2 === 1; 14125 this.container.style.visibility = hidden ? "hidden" : "visible"; 14126 this.annotationStorage.setValue(this.data.id, { 14127 noView: hidden, 14128 noPrint: display === 1 || display === 2 14129 }); 14130 }, 14131 print: event => { 14132 this.annotationStorage.setValue(this.data.id, { 14133 noPrint: !event.detail.print 14134 }); 14135 }, 14136 hidden: event => { 14137 const { 14138 hidden 14139 } = event.detail; 14140 this.container.style.visibility = hidden ? "hidden" : "visible"; 14141 this.annotationStorage.setValue(this.data.id, { 14142 noPrint: hidden, 14143 noView: hidden 14144 }); 14145 }, 14146 focus: event => { 14147 setTimeout(() =>
14147 event.target.focus({ 14148 preventScroll: false 14149 }), 0); 14150 }, 14151 userName: event => { 14152 event.target.title = event.detail.userName; 14153 }, 14154 readonly: event => { 14155 event.target.disabled = event.detail.readonly; 14156 }, 14157 required: event => { 14158 this._setRequired(event.target, event.detail.required); 14159 }, 14160 bgColor: event => { 14161 setColor("bgColor", "backgroundColor", event); 14162 }, 14163 fillColor: event => { 14164 setColor("fillColor", "backgroundColor", event); 14165 }, 14166 fgColor: event => { 14167 setColor("fgColor", "color", event); 14168 }, 14169 textColor: event => { 14170 setColor("textColor", "color", event); 14171 }, 14172 borderColor: event => { 14173 setColor("borderColor", "borderColor", event); 14174 }, 14175 strokeColor: event => { 14176 setColor("strokeColor", "borderColor", event); 14177 }, 14178 rotation: event => { 14179 const angle = event.detail.rotation; 14180 this.setRotation(angle); 14181 this.annotationStorage.setValue(this.data.id, { 14182 rotation: angle 14183 }); 14184 } 14185 }); 14186 } 14187 _dispatchEventFromSandbox(actions, jsEvent) { 14188 const commonActions = this._commonActions; 14189 for (const name of Object.keys(jsEvent.detail)) { 14190 const action = actions[name] || commonActions[name]; 14191 action?.(jsEvent); 14192 } 14193 } 14194 _setDefaultPropertiesFromJS(element) { 14195 if (!this.enableScripting) { 14196 return; 14197 } 14198 const storedData = this.annotationStorage.getRawValue(this.data.id); 14199 if (!storedData) { 14200 return; 14201 } 14202 const commonActions = this._commonActions; 14203 for (const [actionName, detail] of Object.entries(storedData)) { 14204 const action = commonActions[actionName]; 14205 if (action) { 14206 const eventProxy = { 14207 detail: { 14208 [actionName]: detail 14209 }, 14210 target: element 14211 }; 14212 action(eventProxy); 14213 delete storedData[actionName]; 14214 } 14215 } 14216 } 14217 _createQuadrilaterals() { 14218 if (!this.container) { 14219 return; 14220 } 14221 const { 14222 quadPoints 14223 } = this.data; 14224 if (!quadPoints) { 14225 return; 14226 } 14227 const [rectBlX, rectBlY, rectTrX, rectTrY] = this.data.rect; 14228 if (quadPoints.length === 1) { 14229 const [, { 14230 x: trX, 14231 y: trY 14232 }, { 14233 x: blX, 14234 y: blY 14235 }] = quadPoints[0]; 14236 if (rectTrX === trX && rectTrY === trY && rectBlX === blX && rectBlY === blY) { 14237 return; 14238 } 14239 } 14240 const { 14241 style 14242 } = this.container; 14243 let svgBuffer; 14244 if (this.#hasBorder) { 14245 const { 14246 borderColor, 14247 borderWidth 14248 } = style; 14249 style.borderWidth = 0; 14250 svgBuffer = ["url('data:image/svg+xml;utf8,", `<svg xmlns="http://www.w3.org/2000/svg"`, ` preserveAspectRatio="none" viewBox="0 0 1 1">`, `<g fill="transparent" stroke="${borderColor}" stroke-width="${borderWidth}">`]; 14251 this.container.classList.add("hasBorder"); 14252 } 14253 const width = rectTrX - rectBlX; 14254 const height = rectTrY - rectBlY; 14255 const { 14256 svgFactory 14257 } = this; 14258 const svg = svgFactory.createElement("svg"); 14259 svg.classList.add("quadrilateralsContainer"); 14260 svg.setAttribute("width", 0); 14261 svg.setAttribute("height", 0); 14262 const defs = svgFactory.createElement("defs"); 14263 svg.append(defs); 14264 const clipPath = svgFactory.createElement("clipPath"); 14265 const id = `clippath_${this.data.id}`; 14266 clipPath.setAttribute("id", id); 14267 clipPath.setAttribute("clipPathUnits", "objectBoundingBox"); 14268 defs.append(clipPath); 14269 for (const [, { 14270 x: trX, 14271 y: trY 14272 }, { 14273 x: blX, 14274 y: blY 14275 }] of quadPoints) { 14276 const rect = svgFactory.createElement("rect"); 14277 const x = (blX - rectBlX) / width; 14278 const y = (rectTrY - trY) / height; 14279 const rectWidth = (trX - blX) / width; 14280 const rectHeight = (trY - blY) / height; 14281 rect.setAttribute("x", x); 14282 rect.setAttribute("y", y); 14283 rect.setAttribute("width", rectWidth); 14284 rect.setAttribute("height", rectHeight); 14285 clipPath.append(rect); 14286 svgBuffer?.push(`<rect vector-effect="non-scaling-stroke" x="${x}" y="${y}" width="${rectWidth}" height="${rectHeight}"/>`); 14287 } 14288 if (this.#hasBorder) { 14289 svgBuffer.push(`</g></svg>')`); 14290 style.backgroundImage = svgBuffer.join(""); 14291 } 14292 this.container.append(svg); 14293 this.container.style.clipPath = `url(#${id})`; 14294 } 14295 _createPopup() { 14296 const { 14297 container, 14298 data 14299 } = this; 14300 container.setAttribute("aria-haspopup", "dialog"); 14301 const popup = new PopupAnnotationElement({ 14302 data: { 14303 color: data.color, 14304 titleObj: data.titleObj, 14305 modificationDate: data.modificationDate, 14306 contentsObj: data.contentsObj, 14307 richText: data.richText, 14308 parentRect: data.rect, 14309 borderStyle: 0, 14310 id: `popup_${data.id}`, 14311 rotation: data.rotation 14312 }, 14313 parent: this.parent, 14314 elements: [this] 14315 }); 14316 this.parent.div.append(popup.render()); 14317 } 14318 render() { 14319 (0, _util.unreachable)("Abstract method `AnnotationElement.render` called"); 14320 } 14321 _getElementsByName(name, skipId = null) { 14322 const fields = []; 14323 if (this._fieldObjects) { 14324 const fieldObj = this._fieldObjects[name]; 14325 if (fieldObj) { 14326 for (const { 14327 page, 14328 id, 14329 exportValues 14330 } of fieldObj) { 14331 if (page === -1) { 14332 continue; 14333 } 14334 if (id === skipId) { 14335 continue; 14336 } 14337 const exportValue = typeof exportValues === "string" ? exportValues : null; 14338 const domElement = document.querySelector(`[data-element-id="${id}"]`); 14339 if (domElement && !GetElementsByNameSet.has(domElement)) { 14340 (0, _util.warn)(`_getElementsByName - element not allowed: ${id}`); 14341 continue; 14342 } 14343 fields.push({ 14344 id, 14345 exportValue, 14346 domElement 14347 }); 14348 } 14349 } 14350 return fields; 14351 } 14352 for (const domElement of document.getElementsByName(name)) { 14353 const { 14354 exportValue 14355 } = domElement; 14356 const id = domElement.getAttribute("data-element-id"); 14357 if (id === skipId) { 14358 continue; 14359 } 14360 if (!GetElementsByNameSet.has(domElement)) { 14361 continue; 14362 } 14363 fields.push({ 14364 id, 14365 exportValue, 14366 domElement 14367 }); 14368 } 14369 return fields; 14370 } 14371 show() { 14372 if (this.container) { 14373 this.container.hidden = false;
vendor: 8,347 bytes, lines 14374-14663
14374 } 14375 this.popup?.maybeShow(); 14376 } 14377 hide() { 14378 if (this.container) { 14379 this.container.hidden = true; 14380 } 14381 this.popup?.forceHide(); 14382 } 14383 getElementsToTriggerPopup() { 14384 return this.container; 14385 } 14386 addHighlightArea() { 14387 const triggers = this.getElementsToTriggerPopup(); 14388 if (Array.isArray(triggers)) { 14389 for (const element of triggers) { 14390 element.classList.add("highlightArea"); 14391 } 14392 } else { 14393 triggers.classList.add("highlightArea"); 14394 } 14395 } 14396 _editOnDoubleClick() { 14397 const { 14398 annotationEditorType: mode, 14399 data: { 14400 id: editId 14401 } 14402 } = this; 14403 this.container.addEventListener("dblclick", () => { 14404 this.linkService.eventBus?.dispatch("switchannotationeditormode", { 14405 source: this, 14406 mode, 14407 editId 14408 }); 14409 }); 14410 } 14411} 14412class LinkAnnotationElement extends AnnotationElement { 14413 constructor(parameters, options = null) { 14414 super(parameters, { 14415 isRenderable: true, 14416 ignoreBorder: !!options?.ignoreBorder, 14417 createQuadrilaterals: true 14418 }); 14419 this.isTooltipOnly = parameters.data.isTooltipOnly; 14420 } 14421 render() { 14422 const { 14423 data, 14424 linkService 14425 } = this; 14426 const link = document.createElement("a"); 14427 link.setAttribute("data-element-id", data.id); 14428 let isBound = false; 14429 if (data.url) { 14430 linkService.addLinkAttributes(link, data.url, data.newWindow); 14431 isBound = true; 14432 } else if (data.action) { 14433 this._bindNamedAction(link, data.action); 14434 isBound = true; 14435 } else if (data.attachment) { 14436 this._bindAttachment(link, data.attachment); 14437 isBound = true; 14438 } else if (data.setOCGState) { 14439 this.#bindSetOCGState(link, data.setOCGState); 14440 isBound = true; 14441 } else if (data.dest) { 14442 this._bindLink(link, data.dest); 14443 isBound = true; 14444 } else { 14445 if (data.actions && (data.actions.Action || data.actions["Mouse Up"] || data.actions["Mouse Down"]) && this.enableScripting && this.hasJSActions) { 14446 this._bindJSAction(link, data); 14447 isBound = true; 14448 } 14449 if (data.resetForm) { 14450 this._bindResetFormAction(link, data.resetForm); 14451 isBound = true; 14452 } else if (this.isTooltipOnly && !isBound) { 14453 this._bindLink(link, ""); 14454 isBound = true; 14455 } 14456 } 14457 this.container.classList.add("linkAnnotation"); 14458 if (isBound) { 14459 this.container.append(link); 14460 } 14461 return this.container; 14462 } 14463 #setInternalLink() { 14464 this.container.setAttribute("data-internal-link", ""); 14465 } 14466 _bindLink(link, destination) { 14467 link.href = this.linkService.getDestinationHash(destination); 14468 link.onclick = () => { 14469 if (destination) { 14470 this.linkService.goToDestination(destination); 14471 } 14472 return false; 14473 }; 14474 if (destination || destination === "") { 14475 this.#setInternalLink(); 14476 } 14477 } 14478 _bindNamedAction(link, action) { 14479 link.href = this.linkService.getAnchorUrl(""); 14480 link.onclick = () => { 14481 this.linkService.executeNamedAction(action); 14482 return false; 14483 }; 14484 this.#setInternalLink(); 14485 } 14486 _bindAttachment(link, attachment) { 14487 link.href = this.linkService.getAnchorUrl(""); 14488 link.onclick = () => { 14489 this.downloadManager?.openOrDownloadData(this.container, attachment.content, attachment.filename); 14490 return false; 14491 }; 14492 this.#setInternalLink(); 14493 } 14494 #bindSetOCGState(link, action) { 14495 link.href = this.linkService.getAnchorUrl(""); 14496 link.onclick = () => { 14497 this.linkService.executeSetOCGState(action); 14498 return false; 14499 }; 14500 this.#setInternalLink(); 14501 } 14502 _bindJSAction(link, data) { 14503 link.href = this.linkService.getAnchorUrl(""); 14504 const map = new Map([["Action", "onclick"], ["Mouse Up", "onmouseup"], ["Mouse Down", "onmousedown"]]); 14505 for (const name of Object.keys(data.actions)) { 14506 const jsName = map.get(name); 14507 if (!jsName) { 14508 continue; 14509 } 14510 link[jsName] = () => { 14511 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14512 source: this, 14513 detail: { 14514 id: data.id, 14515 name 14516 } 14517 }); 14518 return false; 14519 }; 14520 } 14521 if (!link.onclick) { 14522 link.onclick = () => false; 14523 } 14524 this.#setInternalLink(); 14525 } 14526 _bindResetFormAction(link, resetForm) { 14527 const otherClickAction = link.onclick; 14528 if (!otherClickAction) { 14529 link.href = this.linkService.getAnchorUrl(""); 14530 } 14531 this.#setInternalLink(); 14532 if (!this._fieldObjects) { 14533 (0, _util.warn)(`_bindResetFormAction - "resetForm" action not supported, ` + "ensure that the `fieldObjects` parameter is provided."); 14534 if (!otherClickAction) { 14535 link.onclick = () => false; 14536 } 14537 return; 14538 } 14539 link.onclick = () => { 14540 otherClickAction?.(); 14541 const { 14542 fields: resetFormFields, 14543 refs: resetFormRefs, 14544 include 14545 } = resetForm; 14546 const allFields = []; 14547 if (resetFormFields.length !== 0 || resetFormRefs.length !== 0) { 14548 const fieldIds = new Set(resetFormRefs); 14549 for (const fieldName of resetFormFields) { 14550 const fields = this._fieldObjects[fieldName] || []; 14551 for (const { 14552 id 14553 } of fields) { 14554 fieldIds.add(id); 14555 } 14556 } 14557 for (const fields of Object.values(this._fieldObjects)) { 14558 for (const field of fields) { 14559 if (fieldIds.has(field.id) === include) { 14560 allFields.push(field); 14561 } 14562 } 14563 } 14564 } else { 14565 for (const fields of Object.values(this._fieldObjects)) { 14566 allFields.push(...fields); 14567 } 14568 } 14569 const storage = this.annotationStorage; 14570 const allIds = []; 14571 for (const field of allFields) { 14572 const { 14573 id 14574 } = field; 14575 allIds.push(id); 14576 switch (field.type) { 14577 case "text": 14578 { 14579 const value = field.defaultValue || ""; 14580 storage.setValue(id, { 14581 value 14582 }); 14583 break; 14584 } 14585 case "checkbox": 14586 case "radiobutton": 14587 { 14588 const value = field.defaultValue === field.exportValues; 14589 storage.setValue(id, { 14590 value 14591 }); 14592 break; 14593 } 14594 case "combobox": 14595 case "listbox": 14596 { 14597 const value = field.defaultValue || ""; 14598 storage.setValue(id, { 14599 value 14600 }); 14601 break; 14602 } 14603 default: 14604 continue; 14605 } 14606 const domElement = document.querySelector(`[data-element-id="${id}"]`); 14607 if (!domElement) { 14608 continue; 14609 } else if (!GetElementsByNameSet.has(domElement)) { 14610 (0, _util.warn)(`_bindResetFormAction - element not allowed: ${id}`); 14611 continue; 14612 } 14613 domElement.dispatchEvent(new Event("resetform")); 14614 } 14615 if (this.enableScripting) { 14616 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14617 source: this, 14618 detail: { 14619 id: "app", 14620 ids: allIds, 14621 name: "ResetForm" 14622 } 14623 }); 14624 } 14625 return false; 14626 }; 14627 } 14628} 14629class TextAnnotationElement extends AnnotationElement { 14630 constructor(parameters) { 14631 super(parameters, { 14632 isRenderable: true 14633 }); 14634 } 14635 render() { 14636 this.container.classList.add("textAnnotation"); 14637 const image = document.createElement("img"); 14638 image.src = this.imageResourcesPath + "annotation-" + this.data.name.toLowerCase() + ".svg"; 14639 image.alt = "[{{type}} Annotation]"; 14640 image.dataset.l10nId = "text_annotation_type"; 14641 image.dataset.l10nArgs = JSON.stringify({ 14642 type: this.data.name 14643 }); 14644 if (!this.data.popupRef && this.hasPopupData) { 14645 this._createPopup(); 14646 } 14647 this.container.append(image); 14648 return this.container; 14649 } 14650} 14651class WidgetAnnotationElement extends AnnotationElement { 14652 render() { 14653 if (this.data.alternativeText) { 14654 this.container.title = this.data.alternativeText; 14655 } 14656 return this.container; 14657 } 14658 showElementAndHideCanvas(element) { 14659 if (this.data.hasOwnCanvas) { 14660 if (element.previousSibling?.nodeName === "CANVAS") { 14661 element.previousSibling.hidden = true; 14662 } 14663 element.hidden = false;
14664 } 14665 } 14666 _getKeyModifier(event) { 14667 const { 14668 isWin, 14669 isMac 14670 } = _util.FeatureTest.platform; 14671 return isWin && event.ctrlKey || isMac && event.metaKey; 14672 } 14673 _setEventListener(element, elementData, baseName, eventName, valueGetter) { 14674 if (baseName.includes("mouse")) { 14675 element.addEventListener(baseName, event => { 14676 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14677 source: this, 14678 detail: { 14679 id: this.data.id, 14680 name: eventName, 14681 value: valueGetter(event), 14682 shift: event.shiftKey, 14683 modifier: this._getKeyModifier(event) 14684 } 14685 }); 14686 }); 14687 } else { 14688 element.addEventListener(baseName, event => { 14689 if (baseName === "blur") { 14690 if (!elementData.focused || !event.relatedTarget) { 14691 return; 14692 } 14693 elementData.focused = false; 14694 } else if (baseName === "focus") { 14695 if (elementData.focused) { 14696 return; 14697 } 14698 elementData.focused = true; 14699 } 14700 if (!valueGetter) { 14701 return; 14702 } 14703 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14704 source: this, 14705 detail: { 14706 id: this.data.id, 14707 name: eventName, 14708 value: valueGetter(event) 14709 } 14710 }); 14711 }); 14712 } 14713 } 14714 _setEventListeners(element, elementData, names, getter) { 14715 for (const [baseName, eventName] of names) { 14716 if (eventName === "Action" || this.data.actions?.[eventName]) { 14717 if (eventName === "Focus" || eventName === "Blur") { 14718 elementData ||= { 14719 focused: false 14720 }; 14721 } 14722 this._setEventListener(element, elementData, baseName, eventName, getter); 14723 if (eventName === "Focus" && !this.data.actions?.Blur) { 14724 this._setEventListener(element, elementData, "blur", "Blur", null); 14725 } else if (eventName === "Blur" && !this.data.actions?.Focus) { 14726 this._setEventListener(element, elementData, "focus", "Focus", null); 14727 } 14728 } 14729 } 14730 } 14731 _setBackgroundColor(element) { 14732 const color = this.data.backgroundColor || null; 14733 element.style.backgroundColor = color === null ? "transparent" : _util.Util.makeHexColor(color[0], color[1], color[2]); 14734 } 14735 _setTextStyle(element) { 14736 const TEXT_ALIGNMENT = ["left", "center", "right"]; 14737 const { 14738 fontColor 14739 } = this.data.defaultAppearanceData; 14740 const fontSize = this.data.defaultAppearanceData.fontSize || DEFAULT_FONT_SIZE; 14741 const style = element.style;
vendor: 26,111 bytes, lines 14742-15474
14742 let computedFontSize; 14743 const BORDER_SIZE = 2; 14744 const roundToOneDecimal = x => Math.round(10 * x) / 10; 14745 if (this.data.multiLine) { 14746 const height = Math.abs(this.data.rect[3] - this.data.rect[1] - BORDER_SIZE); 14747 const numberOfLines = Math.round(height / (_util.LINE_FACTOR * fontSize)) || 1; 14748 const lineHeight = height / numberOfLines; 14749 computedFontSize = Math.min(fontSize, roundToOneDecimal(lineHeight / _util.LINE_FACTOR)); 14750 } else { 14751 const height = Math.abs(this.data.rect[3] - this.data.rect[1] - BORDER_SIZE); 14752 computedFontSize = Math.min(fontSize, roundToOneDecimal(height / _util.LINE_FACTOR)); 14753 } 14754 style.fontSize = `calc(${computedFontSize}px * var(--scale-factor))`; 14755 style.color = _util.Util.makeHexColor(fontColor[0], fontColor[1], fontColor[2]); 14756 if (this.data.textAlignment !== null) { 14757 style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment]; 14758 } 14759 } 14760 _setRequired(element, isRequired) { 14761 if (isRequired) { 14762 element.setAttribute("required", true); 14763 } else { 14764 element.removeAttribute("required"); 14765 } 14766 element.setAttribute("aria-required", isRequired); 14767 } 14768} 14769class TextWidgetAnnotationElement extends WidgetAnnotationElement { 14770 constructor(parameters) { 14771 const isRenderable = parameters.renderForms || !parameters.data.hasAppearance && !!parameters.data.fieldValue; 14772 super(parameters, { 14773 isRenderable 14774 }); 14775 } 14776 setPropertyOnSiblings(base, key, value, keyInStorage) { 14777 const storage = this.annotationStorage; 14778 for (const element of this._getElementsByName(base.name, base.id)) { 14779 if (element.domElement) { 14780 element.domElement[key] = value; 14781 } 14782 storage.setValue(element.id, { 14783 [keyInStorage]: value 14784 }); 14785 } 14786 } 14787 render() { 14788 const storage = this.annotationStorage; 14789 const id = this.data.id; 14790 this.container.classList.add("textWidgetAnnotation"); 14791 let element = null; 14792 if (this.renderForms) { 14793 const storedData = storage.getValue(id, { 14794 value: this.data.fieldValue 14795 }); 14796 let textContent = storedData.value || ""; 14797 const maxLen = storage.getValue(id, { 14798 charLimit: this.data.maxLen 14799 }).charLimit; 14800 if (maxLen && textContent.length > maxLen) { 14801 textContent = textContent.slice(0, maxLen); 14802 } 14803 let fieldFormattedValues = storedData.formattedValue || this.data.textContent?.join("\n") || null; 14804 if (fieldFormattedValues && this.data.comb) { 14805 fieldFormattedValues = fieldFormattedValues.replaceAll(/\s+/g, ""); 14806 } 14807 const elementData = { 14808 userValue: textContent, 14809 formattedValue: fieldFormattedValues, 14810 lastCommittedValue: null, 14811 commitKey: 1, 14812 focused: false 14813 }; 14814 if (this.data.multiLine) { 14815 element = document.createElement("textarea"); 14816 element.textContent = fieldFormattedValues ?? textContent; 14817 if (this.data.doNotScroll) { 14818 element.style.overflowY = "hidden"; 14819 } 14820 } else { 14821 element = document.createElement("input"); 14822 element.type = "text"; 14823 element.setAttribute("value", fieldFormattedValues ?? textContent); 14824 if (this.data.doNotScroll) { 14825 element.style.overflowX = "hidden"; 14826 } 14827 } 14828 if (this.data.hasOwnCanvas) { 14829 element.hidden = true; 14830 } 14831 GetElementsByNameSet.add(element); 14832 element.setAttribute("data-element-id", id); 14833 element.disabled = this.data.readOnly; 14834 element.name = this.data.fieldName; 14835 element.tabIndex = DEFAULT_TAB_INDEX; 14836 this._setRequired(element, this.data.required); 14837 if (maxLen) { 14838 element.maxLength = maxLen; 14839 } 14840 element.addEventListener("input", event => { 14841 storage.setValue(id, { 14842 value: event.target.value 14843 }); 14844 this.setPropertyOnSiblings(element, "value", event.target.value, "value"); 14845 elementData.formattedValue = null; 14846 }); 14847 element.addEventListener("resetform", event => { 14848 const defaultValue = this.data.defaultFieldValue ?? ""; 14849 element.value = elementData.userValue = defaultValue; 14850 elementData.formattedValue = null; 14851 }); 14852 let blurListener = event => { 14853 const { 14854 formattedValue 14855 } = elementData; 14856 if (formattedValue !== null && formattedValue !== undefined) { 14857 event.target.value = formattedValue; 14858 } 14859 event.target.scrollLeft = 0; 14860 }; 14861 if (this.enableScripting && this.hasJSActions) { 14862 element.addEventListener("focus", event => { 14863 if (elementData.focused) { 14864 return; 14865 } 14866 const { 14867 target 14868 } = event; 14869 if (elementData.userValue) { 14870 target.value = elementData.userValue; 14871 } 14872 elementData.lastCommittedValue = target.value; 14873 elementData.commitKey = 1; 14874 elementData.focused = true; 14875 }); 14876 element.addEventListener("updatefromsandbox", jsEvent => { 14877 this.showElementAndHideCanvas(jsEvent.target); 14878 const actions = { 14879 value(event) { 14880 elementData.userValue = event.detail.value ?? ""; 14881 storage.setValue(id, { 14882 value: elementData.userValue.toString() 14883 }); 14884 event.target.value = elementData.userValue; 14885 }, 14886 formattedValue(event) { 14887 const { 14888 formattedValue 14889 } = event.detail; 14890 elementData.formattedValue = formattedValue; 14891 if (formattedValue !== null && formattedValue !== undefined && event.target !== document.activeElement) { 14892 event.target.value = formattedValue; 14893 } 14894 storage.setValue(id, { 14895 formattedValue 14896 }); 14897 }, 14898 selRange(event) { 14899 event.target.setSelectionRange(...event.detail.selRange); 14900 }, 14901 charLimit: event => { 14902 const { 14903 charLimit 14904 } = event.detail; 14905 const { 14906 target 14907 } = event; 14908 if (charLimit === 0) { 14909 target.removeAttribute("maxLength"); 14910 return; 14911 } 14912 target.setAttribute("maxLength", charLimit); 14913 let value = elementData.userValue; 14914 if (!value || value.length <= charLimit) { 14915 return; 14916 } 14917 value = value.slice(0, charLimit); 14918 target.value = elementData.userValue = value; 14919 storage.setValue(id, { 14920 value 14921 }); 14922 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14923 source: this, 14924 detail: { 14925 id, 14926 name: "Keystroke", 14927 value, 14928 willCommit: true, 14929 commitKey: 1, 14930 selStart: target.selectionStart, 14931 selEnd: target.selectionEnd 14932 } 14933 }); 14934 } 14935 }; 14936 this._dispatchEventFromSandbox(actions, jsEvent); 14937 }); 14938 element.addEventListener("keydown", event => { 14939 elementData.commitKey = 1; 14940 let commitKey = -1; 14941 if (event.key === "Escape") { 14942 commitKey = 0; 14943 } else if (event.key === "Enter" && !this.data.multiLine) { 14944 commitKey = 2; 14945 } else if (event.key === "Tab") { 14946 elementData.commitKey = 3; 14947 } 14948 if (commitKey === -1) { 14949 return; 14950 } 14951 const { 14952 value 14953 } = event.target; 14954 if (elementData.lastCommittedValue === value) { 14955 return; 14956 } 14957 elementData.lastCommittedValue = value; 14958 elementData.userValue = value; 14959 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14960 source: this, 14961 detail: { 14962 id, 14963 name: "Keystroke", 14964 value, 14965 willCommit: true, 14966 commitKey, 14967 selStart: event.target.selectionStart, 14968 selEnd: event.target.selectionEnd 14969 } 14970 }); 14971 }); 14972 const _blurListener = blurListener; 14973 blurListener = null; 14974 element.addEventListener("blur", event => { 14975 if (!elementData.focused || !event.relatedTarget) { 14976 return; 14977 } 14978 elementData.focused = false; 14979 const { 14980 value 14981 } = event.target; 14982 elementData.userValue = value; 14983 if (elementData.lastCommittedValue !== value) { 14984 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14985 source: this, 14986 detail: { 14987 id, 14988 name: "Keystroke", 14989 value, 14990 willCommit: true, 14991 commitKey: elementData.commitKey, 14992 selStart: event.target.selectionStart, 14993 selEnd: event.target.selectionEnd 14994 } 14995 }); 14996 } 14997 _blurListener(event); 14998 }); 14999 if (this.data.actions?.Keystroke) { 15000 element.addEventListener("beforeinput", event => { 15001 elementData.lastCommittedValue = null; 15002 const { 15003 data, 15004 target 15005 } = event; 15006 const { 15007 value, 15008 selectionStart, 15009 selectionEnd 15010 } = target; 15011 let selStart = selectionStart, 15012 selEnd = selectionEnd; 15013 switch (event.inputType) { 15014 case "deleteWordBackward": 15015 { 15016 const match = value.substring(0, selectionStart).match(/\w*[^\w]*$/); 15017 if (match) { 15018 selStart -= match[0].length; 15019 } 15020 break; 15021 } 15022 case "deleteWordForward": 15023 { 15024 const match = value.substring(selectionStart).match(/^[^\w]*\w*/); 15025 if (match) { 15026 selEnd += match[0].length; 15027 } 15028 break; 15029 } 15030 case "deleteContentBackward": 15031 if (selectionStart === selectionEnd) { 15032 selStart -= 1; 15033 } 15034 break; 15035 case "deleteContentForward": 15036 if (selectionStart === selectionEnd) { 15037 selEnd += 1; 15038 } 15039 break; 15040 } 15041 event.preventDefault(); 15042 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 15043 source: this, 15044 detail: { 15045 id, 15046 name: "Keystroke", 15047 value, 15048 change: data || "", 15049 willCommit: false, 15050 selStart, 15051 selEnd 15052 } 15053 }); 15054 }); 15055 } 15056 this._setEventListeners(element, elementData, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.value); 15057 } 15058 if (blurListener) { 15059 element.addEventListener("blur", blurListener); 15060 } 15061 if (this.data.comb) { 15062 const fieldWidth = this.data.rect[2] - this.data.rect[0]; 15063 const combWidth = fieldWidth / maxLen; 15064 element.classList.add("comb"); 15065 element.style.letterSpacing = `calc(${combWidth}px * var(--scale-factor) - 1ch)`; 15066 } 15067 } else { 15068 element = document.createElement("div"); 15069 element.textContent = this.data.fieldValue; 15070 element.style.verticalAlign = "middle"; 15071 element.style.display = "table-cell"; 15072 } 15073 this._setTextStyle(element); 15074 this._setBackgroundColor(element); 15075 this._setDefaultPropertiesFromJS(element); 15076 this.container.append(element); 15077 return this.container; 15078 } 15079} 15080class SignatureWidgetAnnotationElement extends WidgetAnnotationElement { 15081 constructor(parameters) { 15082 super(parameters, { 15083 isRenderable: !!parameters.data.hasOwnCanvas 15084 }); 15085 } 15086} 15087class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement { 15088 constructor(parameters) { 15089 super(parameters, { 15090 isRenderable: parameters.renderForms 15091 }); 15092 } 15093 render() { 15094 const storage = this.annotationStorage; 15095 const data = this.data; 15096 const id = data.id; 15097 let value = storage.getValue(id, { 15098 value: data.exportValue === data.fieldValue 15099 }).value; 15100 if (typeof value === "string") { 15101 value = value !== "Off"; 15102 storage.setValue(id, { 15103 value 15104 }); 15105 } 15106 this.container.classList.add("buttonWidgetAnnotation", "checkBox"); 15107 const element = document.createElement("input"); 15108 GetElementsByNameSet.add(element); 15109 element.setAttribute("data-element-id", id); 15110 element.disabled = data.readOnly; 15111 this._setRequired(element, this.data.required); 15112 element.type = "checkbox"; 15113 element.name = data.fieldName; 15114 if (value) { 15115 element.setAttribute("checked", true); 15116 } 15117 element.setAttribute("exportValue", data.exportValue); 15118 element.tabIndex = DEFAULT_TAB_INDEX; 15119 element.addEventListener("change", event => { 15120 const { 15121 name, 15122 checked 15123 } = event.target; 15124 for (const checkbox of this._getElementsByName(name, id)) { 15125 const curChecked = checked && checkbox.exportValue === data.exportValue; 15126 if (checkbox.domElement) { 15127 checkbox.domElement.checked = curChecked; 15128 } 15129 storage.setValue(checkbox.id, { 15130 value: curChecked 15131 }); 15132 } 15133 storage.setValue(id, { 15134 value: checked 15135 }); 15136 }); 15137 element.addEventListener("resetform", event => { 15138 const defaultValue = data.defaultFieldValue || "Off"; 15139 event.target.checked = defaultValue === data.exportValue; 15140 }); 15141 if (this.enableScripting && this.hasJSActions) { 15142 element.addEventListener("updatefromsandbox", jsEvent => { 15143 const actions = { 15144 value(event) { 15145 event.target.checked = event.detail.value !== "Off"; 15146 storage.setValue(id, { 15147 value: event.target.checked 15148 }); 15149 } 15150 }; 15151 this._dispatchEventFromSandbox(actions, jsEvent); 15152 }); 15153 this._setEventListeners(element, null, [["change", "Validate"], ["change", "Action"], ["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked); 15154 } 15155 this._setBackgroundColor(element); 15156 this._setDefaultPropertiesFromJS(element); 15157 this.container.append(element); 15158 return this.container; 15159 } 15160} 15161class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement { 15162 constructor(parameters) { 15163 super(parameters, { 15164 isRenderable: parameters.renderForms 15165 }); 15166 } 15167 render() { 15168 this.container.classList.add("buttonWidgetAnnotation", "radioButton"); 15169 const storage = this.annotationStorage; 15170 const data = this.data; 15171 const id = data.id; 15172 let value = storage.getValue(id, { 15173 value: data.fieldValue === data.buttonValue 15174 }).value; 15175 if (typeof value === "string") { 15176 value = value !== data.buttonValue; 15177 storage.setValue(id, { 15178 value 15179 }); 15180 } 15181 const element = document.createElement("input"); 15182 GetElementsByNameSet.add(element); 15183 element.setAttribute("data-element-id", id); 15184 element.disabled = data.readOnly; 15185 this._setRequired(element, this.data.required); 15186 element.type = "radio"; 15187 element.name = data.fieldName; 15188 if (value) { 15189 element.setAttribute("checked", true); 15190 } 15191 element.tabIndex = DEFAULT_TAB_INDEX; 15192 element.addEventListener("change", event => { 15193 const { 15194 name, 15195 checked 15196 } = event.target; 15197 for (const radio of this._getElementsByName(name, id)) { 15198 storage.setValue(radio.id, { 15199 value: false 15200 }); 15201 } 15202 storage.setValue(id, { 15203 value: checked 15204 }); 15205 }); 15206 element.addEventListener("resetform", event => { 15207 const defaultValue = data.defaultFieldValue; 15208 event.target.checked = defaultValue !== null && defaultValue !== undefined && defaultValue === data.buttonValue; 15209 }); 15210 if (this.enableScripting && this.hasJSActions) { 15211 const pdfButtonValue = data.buttonValue; 15212 element.addEventListener("updatefromsandbox", jsEvent => { 15213 const actions = { 15214 value: event => { 15215 const checked = pdfButtonValue === event.detail.value; 15216 for (const radio of this._getElementsByName(event.target.name)) { 15217 const curChecked = checked && radio.id === id; 15218 if (radio.domElement) { 15219 radio.domElement.checked = curChecked; 15220 } 15221 storage.setValue(radio.id, { 15222 value: curChecked 15223 }); 15224 } 15225 } 15226 }; 15227 this._dispatchEventFromSandbox(actions, jsEvent); 15228 }); 15229 this._setEventListeners(element, null, [["change", "Validate"], ["change", "Action"], ["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked); 15230 } 15231 this._setBackgroundColor(element); 15232 this._setDefaultPropertiesFromJS(element); 15233 this.container.append(element); 15234 return this.container; 15235 } 15236} 15237class PushButtonWidgetAnnotationElement extends LinkAnnotationElement { 15238 constructor(parameters) { 15239 super(parameters, { 15240 ignoreBorder: parameters.data.hasAppearance 15241 }); 15242 } 15243 render() { 15244 const container = super.render(); 15245 container.classList.add("buttonWidgetAnnotation", "pushButton"); 15246 if (this.data.alternativeText) { 15247 container.title = this.data.alternativeText; 15248 } 15249 const linkElement = container.lastChild; 15250 if (this.enableScripting && this.hasJSActions && linkElement) { 15251 this._setDefaultPropertiesFromJS(linkElement); 15252 linkElement.addEventListener("updatefromsandbox", jsEvent => { 15253 this._dispatchEventFromSandbox({}, jsEvent); 15254 }); 15255 } 15256 return container; 15257 } 15258} 15259class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { 15260 constructor(parameters) { 15261 super(parameters, { 15262 isRenderable: parameters.renderForms 15263 }); 15264 } 15265 render() { 15266 this.container.classList.add("choiceWidgetAnnotation"); 15267 const storage = this.annotationStorage; 15268 const id = this.data.id; 15269 const storedData = storage.getValue(id, { 15270 value: this.data.fieldValue 15271 }); 15272 const selectElement = document.createElement("select"); 15273 GetElementsByNameSet.add(selectElement); 15274 selectElement.setAttribute("data-element-id", id); 15275 selectElement.disabled = this.data.readOnly; 15276 this._setRequired(selectElement, this.data.required); 15277 selectElement.name = this.data.fieldName; 15278 selectElement.tabIndex = DEFAULT_TAB_INDEX; 15279 let addAnEmptyEntry = this.data.combo && this.data.options.length > 0; 15280 if (!this.data.combo) { 15281 selectElement.size = this.data.options.length; 15282 if (this.data.multiSelect) { 15283 selectElement.multiple = true; 15284 } 15285 } 15286 selectElement.addEventListener("resetform", event => { 15287 const defaultValue = this.data.defaultFieldValue; 15288 for (const option of selectElement.options) { 15289 option.selected = option.value === defaultValue; 15290 } 15291 }); 15292 for (const option of this.data.options) { 15293 const optionElement = document.createElement("option"); 15294 optionElement.textContent = option.displayValue; 15295 optionElement.value = option.exportValue; 15296 if (storedData.value.includes(option.exportValue)) { 15297 optionElement.setAttribute("selected", true); 15298 addAnEmptyEntry = false; 15299 } 15300 selectElement.append(optionElement); 15301 } 15302 let removeEmptyEntry = null; 15303 if (addAnEmptyEntry) { 15304 const noneOptionElement = document.createElement("option"); 15305 noneOptionElement.value = " "; 15306 noneOptionElement.setAttribute("hidden", true); 15307 noneOptionElement.setAttribute("selected", true); 15308 selectElement.prepend(noneOptionElement); 15309 removeEmptyEntry = () => { 15310 noneOptionElement.remove(); 15311 selectElement.removeEventListener("input", removeEmptyEntry); 15312 removeEmptyEntry = null; 15313 }; 15314 selectElement.addEventListener("input", removeEmptyEntry); 15315 } 15316 const getValue = isExport => { 15317 const name = isExport ? "value" : "textContent"; 15318 const { 15319 options, 15320 multiple 15321 } = selectElement; 15322 if (!multiple) { 15323 return options.selectedIndex === -1 ? null : options[options.selectedIndex][name]; 15324 } 15325 return Array.prototype.filter.call(options, option => option.selected).map(option => option[name]); 15326 }; 15327 let selectedValues = getValue(false); 15328 const getItems = event => { 15329 const options = event.target.options; 15330 return Array.prototype.map.call(options, option => { 15331 return { 15332 displayValue: option.textContent, 15333 exportValue: option.value 15334 }; 15335 }); 15336 }; 15337 if (this.enableScripting && this.hasJSActions) { 15338 selectElement.addEventListener("updatefromsandbox", jsEvent => { 15339 const actions = { 15340 value(event) { 15341 removeEmptyEntry?.(); 15342 const value = event.detail.value; 15343 const values = new Set(Array.isArray(value) ? value : [value]); 15344 for (const option of selectElement.options) { 15345 option.selected = values.has(option.value); 15346 } 15347 storage.setValue(id, { 15348 value: getValue(true) 15349 }); 15350 selectedValues = getValue(false); 15351 }, 15352 multipleSelection(event) { 15353 selectElement.multiple = true; 15354 }, 15355 remove(event) { 15356 const options = selectElement.options; 15357 const index = event.detail.remove; 15358 options[index].selected = false; 15359 selectElement.remove(index); 15360 if (options.length > 0) { 15361 const i = Array.prototype.findIndex.call(options, option => option.selected); 15362 if (i === -1) { 15363 options[0].selected = true; 15364 } 15365 } 15366 storage.setValue(id, { 15367 value: getValue(true), 15368 items: getItems(event) 15369 }); 15370 selectedValues = getValue(false); 15371 }, 15372 clear(event) { 15373 while (selectElement.length !== 0) { 15374 selectElement.remove(0); 15375 } 15376 storage.setValue(id, { 15377 value: null, 15378 items: [] 15379 }); 15380 selectedValues = getValue(false); 15381 }, 15382 insert(event) { 15383 const { 15384 index, 15385 displayValue, 15386 exportValue 15387 } = event.detail.insert; 15388 const selectChild = selectElement.children[index]; 15389 const optionElement = document.createElement("option"); 15390 optionElement.textContent = displayValue; 15391 optionElement.value = exportValue; 15392 if (selectChild) { 15393 selectChild.before(optionElement); 15394 } else { 15395 selectElement.append(optionElement); 15396 } 15397 storage.setValue(id, { 15398 value: getValue(true), 15399 items: getItems(event) 15400 }); 15401 selectedValues = getValue(false); 15402 }, 15403 items(event) { 15404 const { 15405 items 15406 } = event.detail; 15407 while (selectElement.length !== 0) { 15408 selectElement.remove(0); 15409 } 15410 for (const item of items) { 15411 const { 15412 displayValue, 15413 exportValue 15414 } = item; 15415 const optionElement = document.createElement("option"); 15416 optionElement.textContent = displayValue; 15417 optionElement.value = exportValue; 15418 selectElement.append(optionElement); 15419 } 15420 if (selectElement.options.length > 0) { 15421 selectElement.options[0].selected = true; 15422 } 15423 storage.setValue(id, { 15424 value: getValue(true), 15425 items: getItems(event) 15426 }); 15427 selectedValues = getValue(false); 15428 }, 15429 indices(event) { 15430 const indices = new Set(event.detail.indices); 15431 for (const option of event.target.options) { 15432 option.selected = indices.has(option.index); 15433 } 15434 storage.setValue(id, { 15435 value: getValue(true) 15436 }); 15437 selectedValues = getValue(false); 15438 }, 15439 editable(event) { 15440 event.target.disabled = !event.detail.editable; 15441 } 15442 }; 15443 this._dispatchEventFromSandbox(actions, jsEvent); 15444 }); 15445 selectElement.addEventListener("input", event => { 15446 const exportValue = getValue(true); 15447 storage.setValue(id, { 15448 value: exportValue 15449 }); 15450 event.preventDefault(); 15451 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 15452 source: this, 15453 detail: { 15454 id, 15455 name: "Keystroke", 15456 value: selectedValues, 15457 changeEx: exportValue, 15458 willCommit: false, 15459 commitKey: 1, 15460 keyDown: false 15461 } 15462 }); 15463 }); 15464 this._setEventListeners(selectElement, null, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"], ["input", "Action"], ["input", "Validate"]], event => event.target.value); 15465 } else { 15466 selectElement.addEventListener("input", function (event) { 15467 storage.setValue(id, { 15468 value: getValue(true) 15469 }); 15470 }); 15471 } 15472 if (this.data.combo) { 15473 this._setTextStyle(selectElement); 15474 } else {}
15475 this._setBackgroundColor(selectElement); 15476 this._setDefaultPropertiesFromJS(selectElement); 15477 this.container.append(selectElement); 15478 return this.container; 15479 } 15480} 15481class PopupAnnotationElement extends AnnotationElement { 15482 constructor(parameters) { 15483 const { 15484 data, 15485 elements 15486 } = parameters; 15487 super(parameters, { 15488 isRenderable: AnnotationElement._hasPopupData(data) 15489 }); 15490 this.elements = elements; 15491 } 15492 render() { 15493 this.container.classList.add("popupAnnotation"); 15494 const popup = new PopupElement({ 15495 container: this.container, 15496 color: this.data.color, 15497 titleObj: this.data.titleObj, 15498 modificationDate: this.data.modificationDate, 15499 contentsObj: this.data.contentsObj, 15500 richText: this.data.richText, 15501 rect: this.data.rect, 15502 parentRect: this.data.parentRect || null, 15503 parent: this.parent, 15504 elements: this.elements, 15505 open: this.data.open 15506 }); 15507 const elementIds = []; 15508 for (const element of this.elements) { 15509 element.popup = popup; 15510 elementIds.push(element.data.id); 15511 element.addHighlightArea(); 15512 } 15513 this.container.setAttribute("aria-controls", elementIds.map(id => `${_util.AnnotationPrefix}${id}`).join(",")); 15514 return this.container; 15515 } 15516} 15517class PopupElement { 15518 #dateTimePromise = null; 15519 #boundKeyDown = this.#keyDown.bind(this); 15520 #boundHide = this.#hide.bind(this); 15521 #boundShow = this.#show.bind(this); 15522 #boundToggle = this.#toggle.bind(this); 15523 #color = null; 15524 #container = null; 15525 #contentsObj = null; 15526 #elements = null; 15527 #parent = null; 15528 #parentRect = null; 15529 #pinned = false; 15530 #popup = null; 15531 #rect = null; 15532 #richText = null; 15533 #titleObj = null; 15534 #wasVisible = false; 15535 constructor({ 15536 container, 15537 color, 15538 elements, 15539 titleObj, 15540 modificationDate, 15541 contentsObj, 15542 richText, 15543 parent, 15544 rect, 15545 parentRect, 15546 open 15547 }) { 15548 this.#container = container; 15549 this.#titleObj = titleObj; 15550 this.#contentsObj = contentsObj; 15551 this.#richText = richText; 15552 this.#parent = parent; 15553 this.#color = color; 15554 this.#rect = rect; 15555 this.#parentRect = parentRect; 15556 this.#elements = elements; 15557 const dateObject = _display_utils.PDFDateString.toDateObject(modificationDate); 15558 if (dateObject) { 15559 this.#dateTimePromise = parent.l10n.get("annotation_date_string", { 15560 date: dateObject.toLocaleDateString(), 15561 time: dateObject.toLocaleTimeString() 15562 }); 15563 } 15564 this.trigger = elements.flatMap(e => e.getElementsToTriggerPopup()); 15565 for (const element of this.trigger) { 15566 element.addEventListener("click", this.#boundToggle); 15567 element.addEventListener("mouseenter", this.#boundShow); 15568 element.addEventListener("mouseleave", this.#boundHide); 15569 element.classList.add("popupTriggerArea"); 15570 } 15571 for (const element of elements) { 15572 element.container?.addEventListener("keydown", this.#boundKeyDown); 15573 } 15574 this.#container.hidden = true; 15575 if (open) { 15576 this.#toggle(); 15577 } 15578 } 15579 render() { 15580 if (this.#popup) { 15581 return; 15582 } 15583 const { 15584 page: { 15585 view 15586 }, 15587 viewport: { 15588 rawDims: { 15589 pageWidth, 15590 pageHeight, 15591 pageX, 15592 pageY 15593 } 15594 } 15595 } = this.#parent; 15596 const popup = this.#popup = document.createElement("div"); 15597 popup.className = "popup"; 15598 if (this.#color) { 15599 const baseColor = popup.style.outlineColor = _util.Util.makeHexColor(...this.#color); 15600 if (CSS.supports("background-color", "color-mix(in srgb, red 30%, white)")) { 15601 popup.style.backgroundColor = `color-mix(in srgb, ${baseColor} 30%, white)`; 15602 } else { 15603 const BACKGROUND_ENLIGHT = 0.7; 15604 popup.style.backgroundColor = _util.Util.makeHexColor(...this.#color.map(c => Math.floor(BACKGROUND_ENLIGHT * (255 - c) + c))); 15605 } 15606 } 15607 const header = document.createElement("span"); 15608 header.className = "header"; 15609 const title = document.createElement("h1"); 15610 header.append(title); 15611 ({ 15612 dir: title.dir, 15613 str: title.textContent 15614 } = this.#titleObj); 15615 popup.append(header); 15616 if (this.#dateTimePromise) { 15617 const modificationDate = document.createElement("span"); 15618 modificationDate.classList.add("popupDate"); 15619 this.#dateTimePromise.then(localized => { 15620 modificationDate.textContent = localized; 15621 }); 15622 header.append(modificationDate); 15623 } 15624 const contentsObj = this.#contentsObj; 15625 const richText = this.#richText; 15626 if (richText?.str && (!contentsObj?.str || contentsObj.str === richText.str)) { 15627 _xfa_layer.XfaLayer.render({ 15628 xfaHtml: richText.html, 15629 intent: "richText", 15630 div: popup 15631 }); 15632 popup.lastChild.classList.add("richText", "popupContent"); 15633 } else { 15634 const contents = this._formatContents(contentsObj); 15635 popup.append(contents); 15636 } 15637 let useParentRect = !!this.#parentRect; 15638 let rect = useParentRect ? this.#parentRect : this.#rect; 15639 for (const element of this.#elements) { 15640 if (!rect || _util.Util.intersect(element.data.rect, rect) !== null) { 15641 rect = element.data.rect; 15642 useParentRect = true; 15643 break; 15644 } 15645 } 15646 const normalizedRect = _util.Util.normalizeRect([rect[0], view[3] - rect[1] + view[
vendor: 7,780 bytes, lines 15646-15899
156461], rect[2], view[3] - rect[3] + view[1]]); 15647 const HORIZONTAL_SPACE_AFTER_ANNOTATION = 5; 15648 const parentWidth = useParentRect ? rect[2] - rect[0] + HORIZONTAL_SPACE_AFTER_ANNOTATION : 0; 15649 const popupLeft = normalizedRect[0] + parentWidth; 15650 const popupTop = normalizedRect[1]; 15651 const { 15652 style 15653 } = this.#container; 15654 style.left = `${100 * (popupLeft - pageX) / pageWidth}%`; 15655 style.top = `${100 * (popupTop - pageY) / pageHeight}%`; 15656 this.#container.append(popup); 15657 } 15658 _formatContents({ 15659 str, 15660 dir 15661 }) { 15662 const p = document.createElement("p"); 15663 p.classList.add("popupContent"); 15664 p.dir = dir; 15665 const lines = str.split(/(?:\r\n?|\n)/); 15666 for (let i = 0, ii = lines.length; i < ii; ++i) { 15667 const line = lines[i]; 15668 p.append(document.createTextNode(line)); 15669 if (i < ii - 1) { 15670 p.append(document.createElement("br")); 15671 } 15672 } 15673 return p; 15674 } 15675 #keyDown(event) { 15676 if (event.altKey || event.shiftKey || event.ctrlKey || event.metaKey) { 15677 return; 15678 } 15679 if (event.key === "Enter" || event.key === "Escape" && this.#pinned) { 15680 this.#toggle(); 15681 } 15682 } 15683 #toggle() { 15684 this.#pinned = !this.#pinned; 15685 if (this.#pinned) { 15686 this.#show(); 15687 this.#container.addEventListener("click", this.#boundToggle); 15688 this.#container.addEventListener("keydown", this.#boundKeyDown); 15689 } else { 15690 this.#hide(); 15691 this.#container.removeEventListener("click", this.#boundToggle); 15692 this.#container.removeEventListener("keydown", this.#boundKeyDown); 15693 } 15694 } 15695 #show() { 15696 if (!this.#popup) { 15697 this.render(); 15698 } 15699 if (!this.isVisible) { 15700 this.#container.hidden = false; 15701 this.#container.style.zIndex = parseInt(this.#container.style.zIndex) + 1000; 15702 } else if (this.#pinned) { 15703 this.#container.classList.add("focused"); 15704 } 15705 } 15706 #hide() { 15707 this.#container.classList.remove("focused"); 15708 if (this.#pinned || !this.isVisible) { 15709 return; 15710 } 15711 this.#container.hidden = true; 15712 this.#container.style.zIndex = parseInt(this.#container.style.zIndex) - 1000; 15713 } 15714 forceHide() { 15715 this.#wasVisible = this.isVisible; 15716 if (!this.#wasVisible) { 15717 return; 15718 } 15719 this.#container.hidden = true; 15720 } 15721 maybeShow() { 15722 if (!this.#wasVisible) { 15723 return; 15724 } 15725 this.#wasVisible = false; 15726 this.#container.hidden = false; 15727 } 15728 get isVisible() { 15729 return this.#container.hidden === false; 15730 } 15731} 15732class FreeTextAnnotationElement extends AnnotationElement { 15733 constructor(parameters) { 15734 super(parameters, { 15735 isRenderable: true, 15736 ignoreBorder: true 15737 }); 15738 this.textContent = parameters.data.textContent; 15739 this.textPosition = parameters.data.textPosition; 15740 this.annotationEditorType = _util.AnnotationEditorType.FREETEXT; 15741 } 15742 render() { 15743 this.container.classList.add("freeTextAnnotation"); 15744 if (this.textContent) { 15745 const content = document.createElement("div"); 15746 content.classList.add("annotationTextContent"); 15747 content.setAttribute("role", "comment"); 15748 for (const line of this.textContent) { 15749 const lineSpan = document.createElement("span"); 15750 lineSpan.textContent = line; 15751 content.append(lineSpan); 15752 } 15753 this.container.append(content); 15754 } 15755 if (!this.data.popupRef && this.hasPopupData) { 15756 this._createPopup(); 15757 } 15758 this._editOnDoubleClick(); 15759 return this.container; 15760 } 15761} 15762exports.FreeTextAnnotationElement = FreeTextAnnotationElement; 15763class LineAnnotationElement extends AnnotationElement { 15764 #line = null; 15765 constructor(parameters) { 15766 super(parameters, { 15767 isRenderable: true, 15768 ignoreBorder: true 15769 }); 15770 } 15771 render() { 15772 this.container.classList.add("lineAnnotation"); 15773 const data = this.data; 15774 const { 15775 width, 15776 height 15777 } = getRectDims(data.rect); 15778 const svg = this.svgFactory.create(width, height, true); 15779 const line = this.#line = this.svgFactory.createElement("svg:line"); 15780 line.setAttribute("x1", data.rect[2] - data.lineCoordinates[0]); 15781 line.setAttribute("y1", data.rect[3] - data.lineCoordinates[1]); 15782 line.setAttribute("x2", data.rect[2] - data.lineCoordinates[2]); 15783 line.setAttribute("y2", data.rect[3] - data.lineCoordinates[3]); 15784 line.setAttribute("stroke-width", data.borderStyle.width || 1); 15785 line.setAttribute("stroke", "transparent"); 15786 line.setAttribute("fill", "transparent"); 15787 svg.append(line); 15788 this.container.append(svg); 15789 if (!data.popupRef && this.hasPopupData) { 15790 this._createPopup(); 15791 } 15792 return this.container; 15793 } 15794 getElementsToTriggerPopup() { 15795 return this.#line; 15796 } 15797 addHighlightArea() { 15798 this.container.classList.add("highlightArea"); 15799 } 15800} 15801class SquareAnnotationElement extends AnnotationElement { 15802 #square = null; 15803 constructor(parameters) { 15804 super(parameters, { 15805 isRenderable: true, 15806 ignoreBorder: true 15807 }); 15808 } 15809 render() { 15810 this.container.classList.add("squareAnnotation"); 15811 const data = this.data; 15812 const { 15813 width, 15814 height 15815 } = getRectDims(data.rect); 15816 const svg = this.svgFactory.create(width, height, true); 15817 const borderWidth = data.borderStyle.width; 15818 const square = this.#square = this.svgFactory.createElement("svg:rect"); 15819 square.setAttribute("x", borderWidth / 2); 15820 square.setAttribute("y", borderWidth / 2); 15821 square.setAttribute("width", width - borderWidth); 15822 square.setAttribute("height", height - borderWidth); 15823 square.setAttribute("stroke-width", borderWidth || 1); 15824 square.setAttribute("stroke", "transparent"); 15825 square.setAttribute("fill", "transparent"); 15826 svg.append(square); 15827 this.container.append(svg); 15828 if (!data.popupRef && this.hasPopupData) { 15829 this._createPopup(); 15830 } 15831 return this.container; 15832 } 15833 getElementsToTriggerPopup() { 15834 return this.#square; 15835 } 15836 addHighlightArea() { 15837 this.container.classList.add("highlightArea"); 15838 } 15839} 15840class CircleAnnotationElement extends AnnotationElement { 15841 #circle = null; 15842 constructor(parameters) { 15843 super(parameters, { 15844 isRenderable: true, 15845 ignoreBorder: true 15846 }); 15847 } 15848 render() { 15849 this.container.classList.add("circleAnnotation"); 15850 const data = this.data; 15851 const { 15852 width, 15853 height 15854 } = getRectDims(data.rect); 15855 const svg = this.svgFactory.create(width, height, true); 15856 const borderWidth = data.borderStyle.width; 15857 const circle = this.#circle = this.svgFactory.createElement("svg:ellipse"); 15858 circle.setAttribute("cx", width / 2); 15859 circle.setAttribute("cy", height / 2); 15860 circle.setAttribute("rx", width / 2 - borderWidth / 2); 15861 circle.setAttribute("ry", height / 2 - borderWidth / 2); 15862 circle.setAttribute("stroke-width", borderWidth || 1); 15863 circle.setAttribute("stroke", "transparent"); 15864 circle.setAttribute("fill", "transparent"); 15865 svg.append(circle); 15866 this.container.append(svg); 15867 if (!data.popupRef && this.hasPopupData) { 15868 this._createPopup(); 15869 } 15870 return this.container; 15871 } 15872 getElementsToTriggerPopup() { 15873 return this.#circle; 15874 } 15875 addHighlightArea() { 15876 this.container.classList.add("highlightArea"); 15877 } 15878} 15879class PolylineAnnotationElement extends AnnotationElement { 15880 #polyline = null; 15881 constructor(parameters) { 15882 super(parameters, { 15883 isRenderable: true, 15884 ignoreBorder: true 15885 }); 15886 this.containerClassName = "polylineAnnotation"; 15887 this.svgElementName = "svg:polyline"; 15888 } 15889 render() { 15890 this.container.classList.add(this.containerClassName); 15891 const data = this.data; 15892 const { 15893 width, 15894 height 15895 } = getRectDims(data.rect); 15896 const svg = this.svgFactory.create(width, height, true); 15897 let points = []; 15898 for (const coordinate of data.vertices) { 15899 const x = coordinate.x - data.rect[0];
15900 const y = data.rect[3] - coordinate.y; 15901 points.push(x + "," + y); 15902 } 15903 points = points.join(" "); 15904 const polyline = this.#polyline = this.svgFactory.createElement(this.svgElementName); 15905 polyline.setAttribute("points", points); 15906 polyline.setAttribute("stroke-width", data.borderStyle.width || 1); 15907 polyline.setAttribute("stroke", "transparent"); 15908 polyline.setAttribute("fill", "transparent"); 15909 svg.append(polyline); 15910 this.container.append(svg); 15911 if (!data.popupRef && this.hasPopupData) { 15912 this._createPopup(); 15913 } 15914 return this.container; 15915 } 15916 getElementsToTriggerPopup() { 15917 return this.#polyline; 15918 } 15919 addHighlightArea() { 15920 this.container.classList.add("highlightArea"); 15921 } 15922} 15923class PolygonAnnotationElement extends PolylineAnnotationElement { 15924 constructor(parameters) { 15925 super(parameters); 15926 this.containerClassName = "polygonAnnotation"; 15927 this.svgElementName = "svg:polygon"; 15928 } 15929} 15930class CaretAnnotationElement extends AnnotationElement { 15931 constructor(parameters) { 15932 super(parameters, { 15933 isRenderable: true, 15934 ignoreBorder: true 15935 }); 15936 } 15937 render() { 15938 this.container.classList.add("caretAnnotation"); 15939 if (!this.data.popupRef && this.hasPopupData) { 15940 this._createPopup(); 15941 } 15942 return this.container; 15943 } 15944} 15945class InkAnnotationElement extends AnnotationElement { 15946 #polylines = []; 15947 constructor(parameters) { 15948 super(parameters, { 15949 isRenderable: true, 15950 ignoreBorder: true 15951 }); 15952 this.containerClassName = "inkAnnotation"; 15953 this.svgElementName = "svg:polyline"; 15954 this.annotationEditorType = _util.AnnotationEditorType.INK; 15955 } 15956 render() { 15957 this.container.classList.add(this.containerClassName); 15958 const data = this.data; 15959 const { 15960 width, 15961 height 15962 } = getRectDims(data.rect); 15963 const svg = this.svgFactory.create(width, height, true); 15964 for (const inkList of data.inkLists) { 15965 let points = []; 15966 for (const coordinate of inkList) { 15967 const x = coordinate.x - data.rect[0]; 15968 const y = data.rect[3] - coordinate.y; 15969 points.push(`${x},${y}`); 15970 } 15971 points = points.join(" "); 15972 const polyline = this.svgFactory.createElement(this.svgElementName); 15973 this.#polylines.push(polyline); 15974 polyline.setAttribute("points", points); 15975 polyline.setAttribute("stroke-width", data.borderStyle.width || 1); 15976 polyline.setAttribute("stroke", "transparent"); 15977 polyline.setAttribute("fill", "transparent"); 15978 if (!data.popupRef && this.hasPopupData) { 15979 this._createPopup(); 15980 } 15981 svg.append(polyline); 15982 } 15983 this.container.append(svg); 15984 return this.container; 15985 } 15986 getElementsToTriggerPopup() { 15987 return this.#polylines; 15988 } 15989 addHighlightArea() { 15990 this.container.classList.add("highlightArea"); 15991 } 15992} 15993exports.InkAnnotationElement = InkAnnotationElement; 15994class HighlightAnnotationElement extends AnnotationElement { 15995 constructor(parameters) { 15996 super(parameters, { 15997 isRenderable: true, 15998 ignoreBorder: true, 15999 createQuadrilaterals: true 16000 }); 16001 } 16002 render() { 16003 if (!this.data.popupRef && this.hasPopupData) { 16004 this._createPopup(); 16005 } 16006 this.container.classList.add("highlightAnnotation"); 16007 return this.container; 16008 } 16009} 16010class UnderlineAnnotationElement extends AnnotationElement { 16011 constructor(parameters) { 16012 super(parameters, { 16013 isRenderable: true, 16014 ignoreBorder: true, 16015 createQuadrilaterals: true 16016 }); 16017 } 16018 render() { 16019 if (!this.data.popupRef && this.hasPopupData) { 16020 this._createPopup(); 16021 } 16022 this.container.classList.add("underlineAnnotation"); 16023 return this.container; 16024 } 16025} 16026class SquigglyAnnotationElement extends AnnotationElement { 16027 constructor(parameters) { 16028 super(parameters, { 16029 isRenderable: true, 16030 ignoreBorder: true, 16031 createQuadrilaterals: true 16032 }); 16033 } 16034 render() { 16035 if (!this.data.popupRef && this.hasPopupData) { 16036 this._createPopup(); 16037 } 16038 this.container.classList.add("squigglyAnnotation"); 16039 return this.container; 16040 } 16041} 16042class StrikeOutAnnotationElement extends AnnotationElement { 16043 constructor(parameters) { 16044 super(parameters, { 16045 isRenderable: true, 16046 ignoreBorder: true, 16047 createQuadrilaterals: true 16048 }); 16049 } 16050 render() { 16051 if (!this.data.popupRef && this.hasPopupData) { 16052 this._createPopup(); 16053 }
16054 this.container.classList.add("strikeoutAnnotation"); 16055 return this.container; 16056 } 16057} 16058class StampAnnotationElement extends AnnotationElement { 16059 constructor(parameters) { 16060 super(parameters, { 16061 isRenderable: true, 16062 ignoreBorder: true 16063 }); 16064 } 16065 render() { 16066 this.container.classList.add("stampAnnotation"); 16067 if (!this.data.popupRef && this.hasPopupData) { 16068 this._createPopup(); 16069 } 16070 return this.container; 16071 } 16072} 16073exports.StampAnnotationElement = StampAnnotationElement; 16074class FileAttachmentAnnotationElement extends AnnotationElement { 16075 #trigger = null; 16076 constructor(parameters) { 16077 super(parameters, { 16078 isRenderable: true 16079 }); 16080 const { 16081 filename, 16082 content 16083 } = this.data.file; 16084 this.filename = (0, _display_utils.getFilenameFromUrl)(filename, true); 16085 this.content = content; 16086 this.linkService.eventBus?.dispatch("fileattachmentannotation", { 16087 source: this, 16088 filename, 16089 content 16090 }); 16091 } 16092 render() { 16093 this.container.classList.add("fileAttachmentAnnotation"); 16094 const { 16095 container, 16096 data 16097 } = this; 16098 let trigger; 16099 if (data.hasAppearance || data.fillAlpha === 0) { 16100 trigger = document.createElement("div"); 16101 } else { 16102 trigger = document.createElement("img"); 16103 trigger.src = `${this.imageResourcesPath}annotation-${/paperclip/i.test(data.name) ? "paperclip" : "pushpin"}.svg`; 16104 if (data.fillAlpha && data.fillAlpha < 1) { 16105 trigger.style = `filter: opacity(${Math.round(data.fillAlpha * 100)}%);`; 16106 } 16107 } 16108 trigger.addEventListener("dblclick", this.#download.bind(this)); 16109 this.#trigger = trigger; 16110 const { 16111 isMac 16112 } = _util.FeatureTest.platform; 16113 container.addEventListener("keydown", evt => { 16114 if (evt.key === "Enter" && (isMac ? evt.metaKey : evt.ctrlKey)) { 16115 this.#download(); 16116 } 16117 }); 16118 if (!data.popupRef && this.hasPopupData) { 16119 this._createPopup(); 16120 } else { 16121 trigger.classList.add("popupTriggerArea"); 16122 } 16123 container.append(trigger); 16124 return container; 16125 } 16126 getElementsToTriggerPopup() { 16127 return this.#trigger; 16128 } 16129 addHighlightArea() { 16130 this.container.classList.add("highlightArea"); 16131 } 16132 #download() { 16133 this.downloadManager?.openOrDownloadData(this.container, this.content, this.filename); 16134 } 16135} 16136class AnnotationLayer { 16137 #accessibilityManager = null; 16138 #annotationCanvasMap = null; 16139 #editableAnnotations = new Map(); 16140 constructor({ 16141 div, 16142 accessibilityManager, 16143 annotationCanvasMap, 16144 l10n, 16145 page, 16146 viewport 16147 }) { 16148 this.div = div; 16149 this.#accessibilityManager = accessibilityManager; 16150 this.#annotationCanvasMap = annotationCanvasMap; 16151 this.l10n = l10n; 16152 this.page = page; 16153 this.viewport = viewport; 16154 this.zIndex = 0; 16155 this.l10n ||= _displayL10n_utils.NullL10n; 16156 } 16157 #appendElement(element, id) { 16158 const contentElement = element.firstChild || element; 16159 contentElement.id = `${_util.AnnotationPrefix}${id}`; 16160 this.div.append(element); 16161 this.#accessibilityManager?.moveElementInDOM(this.div, element, contentElement, false); 16162 } 16163 async render(params) { 16164 const { 16165 annotations 16166 } = params; 16167 const layer = this.div; 16168 (0, _display_utils.setLayerDimensions)(layer, this.viewport); 16169 const popupToElements = new Map();
16170 const elementParams = { 16171 data: null, 16172 layer, 16173 linkService: params.linkService, 16174 downloadManager: params.downloadManager, 16175 imageResourcesPath: params.imageResourcesPath || "", 16176 renderForms: params.renderForms !== false, 16177 svgFactory: new _display_utils.DOMSVGFactory(), 16178 annotationStorage: params.annotationStorage || new _annotation_storage.AnnotationStorage(), 16179 enableScripting: params.enableScripting === true, 16180 hasJSActions: params.hasJSActions, 16181 fieldObjects: params.fieldObjects, 16182 parent: this, 16183 elements: null 16184 }; 16185 for (const data of annotations) { 16186 if (data.noHTML) { 16187 continue; 16188 } 16189 const isPopupAnnotation = data.annotationType === _util.AnnotationType.POPUP; 16190 if (!isPopupAnnotation) { 16191 const { 16192 width, 16193 height 16194 } = getRectDims(data.rect); 16195 if (width <= 0 || height <= 0) { 16196 continue; 16197 } 16198 } else { 16199 const elements = popupToElements.get(data.id); 16200 if (!elements) { 16201 continue; 16202 }
vendor: 6,252 bytes, lines 16203-16395
16203 elementParams.elements = elements; 16204 } 16205 elementParams.data = data; 16206 const element = AnnotationElementFactory.create(elementParams); 16207 if (!element.isRenderable) { 16208 continue; 16209 } 16210 if (!isPopupAnnotation && data.popupRef) { 16211 const elements = popupToElements.get(data.popupRef); 16212 if (!elements) { 16213 popupToElements.set(data.popupRef, [element]); 16214 } else { 16215 elements.push(element); 16216 } 16217 } 16218 if (element.annotationEditorType > 0) { 16219 this.#editableAnnotations.set(element.data.id, element); 16220 } 16221 const rendered = element.render(); 16222 if (data.hidden) { 16223 rendered.style.visibility = "hidden"; 16224 } 16225 this.#appendElement(rendered, data.id); 16226 } 16227 this.#setAnnotationCanvasMap(); 16228 await this.l10n.translate(layer); 16229 } 16230 update({ 16231 viewport 16232 }) { 16233 const layer = this.div; 16234 this.viewport = viewport; 16235 (0, _display_utils.setLayerDimensions)(layer, { 16236 rotation: viewport.rotation 16237 }); 16238 this.#setAnnotationCanvasMap(); 16239 layer.hidden = false; 16240 } 16241 #setAnnotationCanvasMap() { 16242 if (!this.#annotationCanvasMap) { 16243 return; 16244 } 16245 const layer = this.div; 16246 for (const [id, canvas] of this.#annotationCanvasMap) { 16247 const element = layer.querySelector(`[data-annotation-id="${id}"]`); 16248 if (!element) { 16249 continue; 16250 } 16251 const { 16252 firstChild 16253 } = element; 16254 if (!firstChild) { 16255 element.append(canvas); 16256 } else if (firstChild.nodeName === "CANVAS") { 16257 firstChild.replaceWith(canvas); 16258 } else { 16259 firstChild.before(canvas); 16260 } 16261 } 16262 this.#annotationCanvasMap.clear(); 16263 } 16264 getEditableAnnotations() { 16265 return Array.from(this.#editableAnnotations.values()); 16266 } 16267 getEditableAnnotation(id) { 16268 return this.#editableAnnotations.get(id); 16269 } 16270} 16271exports.AnnotationLayer = AnnotationLayer; 16272 16273/***/ }), 16274/* 30 */ 16275/***/ ((__unused_webpack_module, exports) => { 16276 16277 16278 16279Object.defineProperty(exports, "__esModule", ({ 16280 value: true 16281})); 16282exports.ColorConverters = void 0; 16283function makeColorComp(n) { 16284 return Math.floor(Math.max(0, Math.min(1, n)) * 255).toString(16).padStart(2, "0"); 16285} 16286function scaleAndClamp(x) { 16287 return Math.max(0, Math.min(255, 255 * x)); 16288} 16289class ColorConverters { 16290 static CMYK_G([c, y, m, k]) { 16291 return ["G", 1 - Math.min(1, 0.3 * c + 0.59 * m + 0.11 * y + k)]; 16292 } 16293 static G_CMYK([g]) { 16294 return ["CMYK", 0, 0, 0, 1 - g]; 16295 } 16296 static G_RGB([g]) { 16297 return ["RGB", g, g, g]; 16298 } 16299 static G_rgb([g]) { 16300 g = scaleAndClamp(g); 16301 return [g, g, g]; 16302 } 16303 static G_HTML([g]) { 16304 const G = makeColorComp(g); 16305 return `#${G}${G}${G}`; 16306 } 16307 static RGB_G([r, g, b]) { 16308 return ["G", 0.3 * r + 0.59 * g + 0.11 * b]; 16309 } 16310 static RGB_rgb(color) { 16311 return color.map(scaleAndClamp); 16312 } 16313 static RGB_HTML(color) { 16314 return `#${color.map(makeColorComp).join("")}`; 16315 } 16316 static T_HTML() { 16317 return "#00000000"; 16318 } 16319 static T_rgb() { 16320 return [null]; 16321 } 16322 static CMYK_RGB([c, y, m, k]) { 16323 return ["RGB", 1 - Math.min(1, c + k), 1 - Math.min(1, m + k), 1 - Math.min(1, y + k)]; 16324 } 16325 static CMYK_rgb([c, y, m, k]) { 16326 return [scaleAndClamp(1 - Math.min(1, c + k)), scaleAndClamp(1 - Math.min(1, m + k)), scaleAndClamp(1 - Math.min(1, y + k))]; 16327 } 16328 static CMYK_HTML(components) { 16329 const rgb = this.CMYK_RGB(components).slice(1); 16330 return this.RGB_HTML(rgb); 16331 } 16332 static RGB_CMYK([r, g, b]) { 16333 const c = 1 - r; 16334 const m = 1 - g; 16335 const y = 1 - b; 16336 const k = Math.min(c, m, y); 16337 return ["CMYK", c, m, y, k]; 16338 } 16339} 16340exports.ColorConverters = ColorConverters; 16341 16342/***/ }), 16343/* 31 */ 16344/***/ ((__unused_webpack_module, exports) => { 16345 16346 16347 16348Object.defineProperty(exports, "__esModule", ({ 16349 value: true 16350})); 16351exports.NullL10n = void 0; 16352exports.getL10nFallback = getL10nFallback; 16353const DEFAULT_L10N_STRINGS = { 16354 of_pages: "of {{pagesCount}}", 16355 page_of_pages: "({{pageNumber}} of {{pagesCount}})", 16356 document_properties_kb: "{{size_kb}} KB ({{size_b}} bytes)", 16357 document_properties_mb: "{{size_mb}} MB ({{size_b}} bytes)", 16358 document_properties_date_string: "{{date}}, {{time}}", 16359 document_properties_page_size_unit_inches: "in", 16360 document_properties_page_size_unit_millimeters: "mm", 16361 document_properties_page_size_orientation_portrait: "portrait", 16362 document_properties_page_size_orientation_landscape: "landscape", 16363 document_properties_page_size_name_a3: "A3", 16364 document_properties_page_size_name_a4: "A4", 16365 document_properties_page_size_name_letter: "Letter", 16366 document_properties_page_size_name_legal: "Legal", 16367 document_properties_page_size_dimension_string: "{{width}} × {{height}} {{unit}} ({{orientation}})", 16368 document_properties_page_size_dimension_name_string: "{{width}} × {{height}} {{unit}} ({{name}}, {{orientation}})", 16369 document_properties_linearized_yes: "Yes", 16370 document_properties_linearized_no: "No", 16371 additional_layers: "Additional Layers", 16372 page_landmark: "Page {{page}}", 16373 thumb_page_title: "Page {{page}}", 16374 thumb_page_canvas: "Thumbnail of Page {{page}}", 16375 find_reached_top: "Reached top of document, continued from bottom", 16376 find_reached_bottom: "Reached end of document, continued from top", 16377 "find_match_count[one]": "{{current}} of {{total}} match", 16378 "find_match_count[other]": "{{current}} of {{total}} matches", 16379 "find_match_count_limit[one]": "More than {{limit}} match", 16380 "find_match_count_limit[other]": "More than {{limit}} matches", 16381 find_not_found: "Phrase not found", 16382 page_scale_width: "Page Width", 16383 page_scale_fit: "Page Fit", 16384 page_scale_auto: "Automatic Zoom", 16385 page_scale_actual: "Actual Size", 16386 page_scale_percent: "{{scale}}%", 16387 loading_error: "An error occurred while loading the PDF.", 16388 invalid_file_error: "Invalid or corrupted PDF file.", 16389 missing_file_error: "Missing PDF file.", 16390 unexpected_response_error: "Unexpected server response.", 16391 rendering_error: "An error occurred while rendering the page.", 16392 annotation_date_string: "{{date}}, {{time}}", 16393 printing_not_supported: "Warning: Printing is not fully supported by this browser.", 16394 printing_not_ready: "Warning: The PDF is not fully loaded for printing.", 16395 web_fonts_disabled: "Web fonts are disabled: unable to use embedded PDF fonts.",
16396 free_text2_default_content: "Start typing…", 16397 editor_free_text2_aria_label: "Text Editor", 16398 editor_ink2_aria_label: "Draw Editor", 16399 editor_ink_canvas_aria_label: "User-created image", 16400 editor_alt_text_button_label: "Alt text", 16401 editor_alt_text_edit_button_label: "Edit alt text", 16402 editor_alt_text_decorative_tooltip: "Marked as decorative" 16403}; 16404{ 16405 DEFAULT_L10N_STRINGS.print_progress_percent = "{{progress}}%"; 16406} 16407function getL10nFallback(key, args) { 16408 switch (key) { 16409 case "find_match_count": 16410 key = `find_match_count[${args.total === 1 ? "one" : "other"}]`; 16411 break; 16412 case "find_match_count_limit": 16413 key = `find_match_count_limit[${args.limit === 1 ? "one" : "other"}]`; 16414 break; 16415 } 16416 return DEFAULT_L10N_STRINGS[key] || ""; 16417} 16418function formatL10nValue(text, args) { 16419 if (!args) { 16420 return text; 16421 } 16422 return text.replaceAll(/\{\{\s*(\w+)\s*\}\}/g, (all, name) => { 16423 return name in args ? args[name] : "{{" + name + "}}"; 16424 }); 16425} 16426const NullL10n = { 16427 async getLanguage() { 16428 return "en-us"; 16429 }, 16430 async getDirection() { 16431 return "ltr"; 16432 }, 16433 async get(key, args = null, fallback = getL10nFallback(key, args)) { 16434 return formatL10nValue(fallback, args); 16435 }, 16436 async translate(element) {} 16437}; 16438exports.NullL10n = NullL10n; 16439 16440/***/ }), 16441/* 32 */ 16442/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 16443 16444 16445 16446Object.defineProperty(exports, "__esModule", ({ 16447 value: true 16448})); 16449exports.XfaLayer = void 0; 16450var _xfa_text = __w_pdfjs_require__(25); 16451class XfaLayer { 16452 static setupStorage(html, id, element, storage, intent) { 16453 const storedData = storage.getValue(id, { 16454 value: null 16455 }); 16456 switch (element.name) { 16457 case "textarea": 16458 if (storedData.value !== null) { 16459 html.textContent = storedData.value; 16460 } 16461 if (intent === "print") { 16462 break; 16463 } 16464 html.addEventListener("input", event => { 16465 storage.setValue(id, { 16466 value: event.target.value 16467 }); 16468 }); 16469 break; 16470 case "input": 16471 if (element.attributes.type === "radio" || element.attributes.type === "checkbox") { 16472 if (storedData.value === element.attributes.xfaOn) { 16473 html.setAttribute("checked", true); 16474 } else if (storedData.value === element.attributes.xfaOff) { 16475 html.removeAttribute("checked"); 16476 } 16477 if (intent === "print") { 16478 break; 16479 } 16480 html.addEventListener("change", event => { 16481 storage.setValue(id, { 16482 value: event.target.checked ? event.target.getAttribute("xfaOn") : event.target.getAttribute("xfaOff") 16483 }); 16484 }); 16485 } else { 16486 if (storedData.value !== null) { 16487 html.setAttribute("value", storedData.value); 16488 } 16489 if (intent === "print") { 16490 break; 16491 } 16492 html.addEventListener("input", event => { 16493 storage.setValue(id, { 16494 value: event.target.value 16495 }); 16496 }); 16497 } 16498 break; 16499 case "select": 16500 if (storedData.value !== null) { 16501 html.setAttribute("value", storedData.value); 16502 for (const option of element.children) { 16503 if (option.attributes.value === storedData.value) { 16504 option.attributes.selected = true; 16505 } else if (option.attributes.hasOwnProperty("selected")) { 16506 delete option.attributes.selected; 16507 } 16508 } 16509 } 16510 html.addEventListener("input", event => { 16511 const options = event.target.options; 16512 const value = options.selectedIndex === -1 ? "" : options[options.selectedIndex].value; 16513 storage.setValue(id, { 16514 value 16515 }); 16516 }); 16517 break; 16518 } 16519 } 16520 static setAttributes({ 16521 html, 16522 element, 16523 storage = null, 16524 intent, 16525 linkService 16526 }) { 16527 const { 16528 attributes 16529 } = element; 16530 const isHTMLAnchorElement = html instanceof HTMLAnchorElement; 16531 if (attributes.type === "radio") { 16532 attributes.name = `${attributes.name}-${intent}`; 16533 } 16534 for (const [key, value] of Object.entries(attributes)) { 16535 if (value === null || value === undefined) { 16536 continue; 16537 } 16538 switch (key) { 16539 case "class": 16540 if (value.length) { 16541 html.setAttribute(key, value.join(" ")); 16542 } 16543 break; 16544 case "dataId": 16545 break; 16546 case "id": 16547 html.setAttribute("data-element-id", value); 16548 break; 16549 case "style": 16550 Object.assign(html.style, value); 16551 break; 16552 case "textContent": 16553 html.textContent = value; 16554 break; 16555 default: 16556 if (!isHTMLAnchorElement || key !== "href" && key !== "newWindow") { 16557 html.setAttribute(key, value); 16558 } 16559 } 16560 } 16561 if (isHTMLAnchorElement) { 16562 linkService.addLinkAttributes(html, attributes.href, attributes.newWindow); 16563 } 16564 if (storage && attributes.dataId) { 16565 this.setupStorage(html, attributes.dataId, element, storage); 16566 } 16567 } 16568 static render(parameters) { 16569 const storage = parameters.annotationStorage; 16570 const linkService = parameters.linkService; 16571 const root = parameters.xfaHtml; 16572 const intent = parameters.intent || "display"; 16573 const rootHtml = document.createElement(root.name); 16574 if (root.attributes) { 16575 this.setAttributes({ 16576 html: rootHtml, 16577 element: root, 16578 intent, 16579 linkService 16580 }); 16581 } 16582 const stack = [[root, -1, rootHtml]]; 16583 const rootDiv = parameters.div; 16584 rootDiv.append(rootHtml); 16585 if (parameters.viewport) { 16586 const transform = `matrix(${parameters.viewport.transform.join(",")})`; 16587 rootDiv.style.transform = transform; 16588 } 16589 if (intent !== "richText") { 16590 rootDiv.setAttribute("class", "xfaLayer xfaFont"); 16591 } 16592 const textDivs = []; 16593 while (stack.length > 0) { 16594 const [parent, i, html] = stack.at(-1); 16595 if (i + 1 === parent.children.length) { 16596 stack.pop(); 16597 continue; 16598 } 16599 const child = parent.children[++stack.at(-1)[1]]; 16600 if (child === null) { 16601 continue; 16602 } 16603 const { 16604 name 16605 } = child; 16606 if (name === "#text") { 16607 const node = document.createTextNode(child.value); 16608 textDivs.push(node); 16609 html.append(node); 16610 continue; 16611 } 16612 const childHtml = child?.attributes?.xmlns ? document.createElementNS(child.attributes.xmlns, name) : document.createElement(name); 16613 html.append(childHtml); 16614 if (child.attributes) { 16615 this.setAttributes({ 16616 html: childHtml, 16617 element: child, 16618 storage, 16619 intent, 16620 linkService 16621 }); 16622 } 16623 if (child.children && child.children.length > 0) { 16624 stack.push([child, -1, childHtml]); 16625 } else if (child.value) { 16626 const node = document.createTextNode(child.value); 16627 if (_xfa_text.XfaText.shouldBuildText(name)) { 16628 textDivs.push(node); 16629 } 16630 childHtml.append(node); 16631 } 16632 } 16633 for (const el of rootDiv.querySelectorAll(".xfaNonInteractive input, .xfaNonInteractive textarea")) { 16634 el.setAttribute("readOnly", true); 16635 } 16636 return { 16637 textDivs 16638 }; 16639 } 16640 static update(parameters) { 16641 const transform = `matrix(${parameters.viewport.transform.join(",")})`; 16642 parameters.div.style.transform = transform; 16643 parameters.div.hidden = false;
16644 } 16645} 16646exports.XfaLayer = XfaLayer; 16647 16648/***/ }), 16649/* 33 */ 16650/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 16651 16652 16653 16654Object.defineProperty(exports, "__esModule", ({ 16655 value: true 16656})); 16657exports.InkEditor = void 0; 16658var _util = __w_pdfjs_require__(1); 16659var _editor = __w_pdfjs_require__(4); 16660var _annotation_layer = __w_pdfjs_require__(29); 16661var _display_utils = __w_pdfjs_require__(6); 16662var _tools = __w_pdfjs_require__(5); 16663class InkEditor extends _editor.AnnotationEditor { 16664 #baseHeight = 0; 16665 #baseWidth = 0; 16666 #boundCanvasPointermove = this.canvasPointermove.bind(this); 16667 #boundCanvasPointerleave = this.canvasPointerleave.bind(this); 16668 #boundCanvasPointerup = this.canvasPointerup.bind(this); 16669 #boundCanvasPointerdown = this.canvasPointerdown.bind(this); 16670 #currentPath2D = new Path2D(); 16671 #disableEditing = false; 16672 #hasSomethingToDraw = false; 16673 #isCanvasInitialized = false; 16674 #observer = null; 16675 #realWidth = 0; 16676 #realHeight = 0; 16677 #requestFrameCallback = null; 16678 static _defaultColor = null; 16679 static _defaultOpacity = 1; 16680 static _defaultThickness = 1; 16681 static _type = "ink"; 16682 constructor(params) { 16683 super({ 16684 ...params, 16685 name: "inkEditor" 16686 }); 16687 this.color = params.color || null; 16688 this.thickness = params.thickness || null; 16689 this.opacity = params.opacity || null; 16690 this.paths = []; 16691 this.bezierPath2D = []; 16692 this.allRawPaths = []; 16693 this.currentPath = []; 16694 this.scaleFactor = 1; 16695 this.translationX = this.translationY = 0; 16696 this.x = 0; 16697 this.y = 0; 16698 this._willKeepAspectRatio = true; 16699 } 16700 static initialize(l10n) { 16701 _editor.AnnotationEditor.initialize(l10n, { 16702 strings: ["editor_ink_canvas_aria_label", "editor_ink2_aria_label"] 16703 }); 16704 } 16705 static updateDefaultParams(type, value) { 16706 switch (type) { 16707 case _util.AnnotationEditorParamsType.INK_THICKNESS: 16708 InkEditor._defaultThickness = value; 16709 break; 16710 case _util.AnnotationEditorParamsType.INK_COLOR: 16711 InkEditor._defaultColor = value; 16712 break; 16713 case _util.AnnotationEditorParamsType.INK_OPACITY: 16714 InkEditor._defaultOpacity = value / 100; 16715 break; 16716 } 16717 } 16718 updateParams(type, value) { 16719 switch (type) { 16720 case _util.AnnotationEditorParamsType.INK_THICKNESS: 16721 this.#updateThickness(value); 16722 break; 16723 case _util.AnnotationEditorParamsType.INK_COLOR: 16724 this.#updateColor(value); 16725 break; 16726 case _util.AnnotationEditorParamsType.INK_OPACITY: 16727 this.#updateOpacity(value); 16728 break; 16729 } 16730 } 16731 static get defaultPropertiesToUpdate() { 16732 return [[_util.AnnotationEditorParamsType.INK_THICKNESS, InkEditor._defaultThickness], [_util.AnnotationEditorParamsType.INK_COLOR, InkEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor], [_util.AnnotationEditorParamsType.INK_OPACITY, Math.round(InkEditor._defaultOpacity * 100)]]; 16733 } 16734 get propertiesToUpdate() { 16735 return [[_util.AnnotationEditorParamsType.INK_THICKNESS, this.thickness || InkEditor._defaultThickness], [_util.AnnotationEditorParamsType.INK_COLOR, this.color || InkEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor], [_util.AnnotationEditorParamsType.INK_OPACITY, Math.round(100 * (this.opacity ?? InkEditor._defaultOpacity))]]; 16736 } 16737 #updateThickness(thickness) { 16738 const savedThickness = this.thickness; 16739 this.addCommands({ 16740 cmd: () => { 16741 this.thickness = thickness; 16742 this.#fitToContent(); 16743 }, 16744 undo: () => { 16745 this.thickness = savedThickness; 16746 this.#fitToContent(); 16747 }, 16748 mustExec: true, 16749 type: _util.AnnotationEditorParamsType.INK_THICKNESS, 16750 overwriteIfSameType: true, 16751 keepUndo: true 16752 }); 16753 } 16754 #updateColor(color) { 16755 const savedColor = this.color; 16756 this.addCommands({ 16757 cmd: () => { 16758 this.color = color; 16759 this.#redraw(); 16760 }, 16761 undo: () => { 16762 this.color = savedColor; 16763 this.#redraw(); 16764 }, 16765 mustExec: true, 16766 type: _util.AnnotationEditorParamsType.INK_COLOR,
16767 overwriteIfSameType: true, 16768 keepUndo: true 16769 }); 16770 } 16771 #updateOpacity(opacity) { 16772 opacity /= 100; 16773 const savedOpacity = this.opacity; 16774 this.addCommands({ 16775 cmd: () => { 16776 this.opacity = opacity; 16777 this.#redraw(); 16778 }, 16779 undo: () => { 16780 this.opacity = savedOpacity; 16781 this.#redraw(); 16782 }, 16783 mustExec: true, 16784 type: _util.AnnotationEditorParamsType.INK_OPACITY, 16785 overwriteIfSameType: true, 16786 keepUndo: true 16787 }); 16788 } 16789 rebuild() { 16790 if (!this.parent) { 16791 return; 16792 } 16793 super.rebuild(); 16794 if (this.div === null) { 16795 return; 16796 } 16797 if (!this.canvas) { 16798 this.#createCanvas(); 16799 this.#createObserver(); 16800 } 16801 if (!this.isAttachedToDOM) { 16802 this.parent.add(this); 16803 this.#setCanvasDims(); 16804 } 16805 this.#fitToContent(); 16806 } 16807 remove() { 16808 if (this.canvas === null) { 16809 return; 16810 } 16811 if (!this.isEmpty()) { 16812 this.commit(); 16813 } 16814 this.canvas.width = this.canvas.height = 0; 16815 this.canvas.remove(); 16816 this.canvas = null; 16817 this.#observer.disconnect(); 16818 this.#observer = null; 16819 super.remove(); 16820 } 16821 setParent(parent) { 16822 if (!this.parent && parent) { 16823 this._uiManager.removeShouldRescale(this); 16824 } else if (this.parent && parent === null) { 16825 this._uiManager.addShouldRescale(this); 16826 } 16827 super.setParent(parent); 16828 } 16829 onScaleChanging() { 16830 const [parentWidth, parentHeight] = this.parentDimensions; 16831 const width = this.width * parentWidth; 16832 const height = this.height * parentHeight; 16833 this.setDimensions(width, height); 16834 } 16835 enableEditMode() { 16836 if (this.#disableEditing || this.canvas === null) { 16837 return; 16838 } 16839 super.enableEditMode(); 16840 this._isDraggable = false; 16841 this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown); 16842 } 16843 disableEditMode() { 16844 if (!this.isInEditMode() || this.canvas === null) { 16845 return; 16846 } 16847 super.disableEditMode(); 16848 this._isDraggable = !this.isEmpty(); 16849 this.div.classList.remove("editing"); 16850 this.canvas.removeEventListener("pointerdown", this.#boundCanvasPointerdown); 16851 } 16852 onceAdded() { 16853 this._isDraggable = !this.isEmpty(); 16854 } 16855 isEmpty() { 16856 return this.paths.length === 0 || this.paths.length === 1 && this.paths[0].length === 0; 16857 } 16858 #getInitialBBox() { 16859 const { 16860 parentRotation, 16861 parentDimensions: [width, height] 16862 } = this; 16863 switch (parentRotation) { 16864 case 90: 16865 return [0, height, height, width]; 16866 case 180: 16867 return [width, height, width, height]; 16868 case 270: 16869 return [width, 0, height, width]; 16870 default: 16871 return [0, 0, width, height]; 16872 } 16873 } 16874 #setStroke() { 16875 const { 16876 ctx, 16877 color, 16878 opacity, 16879 thickness, 16880 parentScale, 16881 scaleFactor 16882 } = this; 16883 ctx.lineWidth = thickness * parentScale / scaleFactor; 16884 ctx.lineCap = "round"; 16885 ctx.lineJoin = "round"; 16886 ctx.miterLimit = 10; 16887 ctx.strokeStyle = `${color}${(0, _tools.opacityToHex)(opacity)}`; 16888 } 16889 #startDrawing(x, y) { 16890 this.canvas.addEventListener("contextmenu", _display_utils.noContextMenu); 16891 this.canvas.addEventListener("pointerleave", this.#boundCanvasPointerleave); 16892 this.canvas.addEventListener("pointermove", this.#boundCanvasPointermove); 16893 this.canvas.addEventListener("pointerup", this.#boundCanvasPointerup); 16894 this.canvas.removeEventListener("pointerdown", this.#boundCanvasPointerdown); 16895 this.isEditing = true; 16896 if (!this.#isCanvasInitialized) { 16897 this.#isCanvasInitialized = true; 16898 this.#setCanvasDims(); 16899 this.thickness ||= InkEditor._defaultThickness; 16900 this.color ||= InkEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor; 16901 this.opacity ??= InkEditor._defaultOpacity; 16902 } 16903 this.currentPath.push([x, y]); 16904 this.#hasSomethingToDraw = false; 16905 this.#setStroke(); 16906 this.#requestFrameCallback = () => { 16907 this.#drawPoints(); 16908 if (this.#requestFrameCallback) { 16909 window.requestAnimationFrame(this.#requestFrameCallback); 16910 } 16911 }; 16912 window.requestAnimationFrame(this.#requestFrameCallback); 16913 } 16914 #draw(x, y) { 16915 const [lastX, lastY] = this.currentPath.at(-1); 16916 if (this.currentPath.length > 1 && x === lastX && y === lastY) { 16917 return; 16918 } 16919 const currentPath = this.currentPath; 16920 let path2D = this.#currentPath2D; 16921 currentPath.push([x, y]); 16922 this.#hasSomethingToDraw = true; 16923 if (currentPath.length <= 2) { 16924 path2D.moveTo(...currentPath[0]); 16925 path2D.lineTo(x, y); 16926 return; 16927 } 16928 if (currentPath.length === 3) { 16929 this.#currentPath2D = path2D = new Path2D(); 16930 path2D.moveTo(...currentPath[0]); 16931 } 16932 this.#makeBezierCurve(path2D, ...currentPath.at(-3), ...currentPath.at(-2), x, y); 16933 } 16934 #endPath() { 16935 if (this.currentPath.length === 0) { 16936 return; 16937 } 16938 const lastPoint = this.currentPath.at(-1); 16939 this.#currentPath2D.lineTo(...lastPoint); 16940 } 16941 #stopDrawing(x, y) { 16942 this.#requestFrameCallback = null; 16943 x = Math.min(Math.max(x, 0), this.canvas.width); 16944 y = Math.min(Math.max(y, 0), this.canvas.height); 16945 this.#draw(x, y); 16946 this.#endPath(); 16947 let bezier; 16948 if (this.currentPath.length !== 1) { 16949 bezier = this.#generateBezierPoints(); 16950 } else { 16951 const xy = [x, y]; 16952 bezier = [[xy, xy.slice(), xy.slice(), xy]]; 16953 } 16954 const path2D = this.#currentPath2D; 16955 const currentPath = this.currentPath; 16956 this.currentPath = []; 16957 this.#currentPath2D = new Path2D(); 16958 const cmd = () => { 16959 this.allRawPaths.push(currentPath); 16960 this.paths.push(bezier); 16961 this.bezierPath2D.push(path2D); 16962 this.rebuild(); 16963 }; 16964 const undo = () => { 16965 this.allRawPaths.pop(); 16966 this.paths.pop(); 16967 this.bezierPath2D.pop(); 16968 if (this.paths.length === 0) { 16969 this.remove(); 16970 } else { 16971 if (!this.canvas) { 16972 this.#createCanvas(); 16973 this.#createObserver(); 16974 } 16975 this.#fitToContent(); 16976 } 16977 }; 16978 this.addCommands({ 16979 cmd, 16980 undo, 16981 mustExec: true 16982 }); 16983 } 16984 #drawPoints() { 16985 if (!this.#hasSomethingToDraw) { 16986 return; 16987 } 16988 this.#hasSomethingToDraw = false;
16989 const thickness = Math.ceil(this.thickness * this.parentScale); 16990 const lastPoints = this.currentPath.slice(-3); 16991 const x = lastPoints.map(xy => xy[0]); 16992 const y = lastPoints.map(xy => xy[1]); 16993 const xMin = Math.min(...x) - thickness; 16994 const xMax = Math.max(...x) + thickness; 16995 const yMin = Math.min(...y) - thickness; 16996 const yMax = Math.max(...y) + thickness; 16997 const { 16998 ctx 16999 } = this; 17000 ctx.save(); 17001 ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 17002 for (const path of this.bezierPath2D) { 17003 ctx.stroke(path); 17004 } 17005 ctx.stroke(this.#currentPath2D); 17006 ctx.restore(); 17007 } 17008 #makeBezierCurve(path2D, x0, y0, x1, y1, x2, y2) { 17009 const prevX = (x0 + x1) / 2; 17010 const prevY = (y0 + y1) / 2; 17011 const x3 = (x1 + x2) / 2; 17012 const y3 = (y1 + y2) / 2; 17013 path2D.bezierCurveTo(prevX + 2 * (x1 - prevX) / 3, prevY + 2 * (y1 - prevY) / 3, x3 + 2 * (x1 - x3) / 3, y3 + 2 * (y1 - y3) / 3, x3, y3); 17014 } 17015 #generateBezierPoints() { 17016 const path = this.currentPath; 17017 if (path.length <= 2) { 17018 return [[path[0], path[0], path.at(-1), path.at(-1)]]; 17019 } 17020 const bezierPoints = []; 17021 let i; 17022 let [x0, y0] = path[0]; 17023 for (i = 1; i < path.length - 2; i++) { 17024 const [x1, y1] = path[i]; 17025 const [x2, y2] = path[i + 1]; 17026 const x3 = (x1 + x2) / 2; 17027 const y3 = (y1 + y2) / 2; 17028 const control1 = [x0 + 2 * (x1 - x0) / 3, y0 + 2 * (y1 - y0) / 3]; 17029 const control2 = [x3 + 2 * (x1 - x3) / 3, y3 + 2 * (y1 - y3) / 3]; 17030 bezierPoints.push([[x0, y0], control1, control2, [x3, y3]]); 17031 [x0, y0] = [x3, y3]; 17032 } 17033 const [x1, y1] = path[i]; 17034 const [x2, y2] = path[i + 1]; 17035 const control1 = [x0 + 2 * (x1 - x0) / 3, y0 + 2 * (y1 - y0) / 3]; 17036 const control2 = [x2 + 2 * (x1 - x2) / 3, y2 + 2 * (y1 - y2) / 3]; 17037 bezierPoints.push([[x0, y0], control1, control2, [x2, y2]]); 17038 return bezierPoints; 17039 } 17040 #redraw() { 17041 if (this.isEmpty()) { 17042 this.#updateTransform(); 17043 return; 17044 } 17045 this.#setStroke(); 17046 const { 17047 canvas, 17048 ctx 17049 } = this; 17050 ctx.setTransform(1, 0, 0, 1, 0, 0); 17051 ctx.clearRect(0, 0, canvas.width, canvas.height); 17052 this.#updateTransform(); 17053 for (const path of this.bezierPath2D) { 17054 ctx.stroke(path); 17055 } 17056 } 17057 commit() { 17058 if (this.#disableEditing) { 17059 return; 17060 } 17061 super.commit(); 17062 this.isEditing = false; 17063 this.disableEditMode(); 17064 this.setInForeground(); 17065 this.#disableEditing = true; 17066 this.div.classList.add("disabled"); 17067 this.#fitToContent(true); 17068 this.makeResizable(); 17069 this.parent.addInkEditorIfNeeded(true); 17070 this.moveInDOM(); 17071 this.div.focus({ 17072 preventScroll: true 17073 }); 17074 } 17075 focusin(event) { 17076 if (!this._focusEventsAllowed) { 17077 return; 17078 } 17079 super.focusin(event); 17080 this.enableEditMode(); 17081 } 17082 canvasPointerdown(event) { 17083 if (event.button !== 0 || !this.isInEditMode() || this.#disableEditing) { 17084 return; 17085 } 17086 this.setInForeground(); 17087 event.preventDefault(); 17088 if (event.type !== "mouse") { 17089 this.div.focus(); 17090 } 17091 this.#startDrawing(event.offsetX, event.offsetY); 17092 } 17093 canvasPointermove(event) { 17094 event.preventDefault(); 17095 this.#draw(event.offsetX, event.offsetY); 17096 } 17097 canvasPointerup(event) { 17098 event.preventDefault(); 17099 this.#endDrawing(event); 17100 } 17101 canvasPointerleave(event) { 17102 this.#endDrawing(event); 17103 } 17104 #endDrawing(event) { 17105 this.canvas.removeEventListener("pointerleave", this.#boundCanvasPointerleave); 17106 this.canvas.removeEventListener("pointermove", this.#boundCanvasPointermove); 17107 this.canvas.removeEventListener("pointerup", this.#boundCanvasPointerup); 17108 this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown); 17109 setTimeout(() => { 17110 this.canvas.removeEventListener("contextmenu", _display_utils.noContextMenu); 17111 }, 10); 17112 this.#stopDrawing(event.offsetX, event.offsetY); 17113 this.addToAnnotationStorage(); 17114 this.setInBackground(); 17115 } 17116 #createCanvas() { 17117 this.canvas = document.createElement("canvas"); 17118 this.canvas.width = this.canvas.height = 0; 17119 this.canvas.className = "inkEditorCanvas"; 17120 _editor.AnnotationEditor._l10nPromise.get("editor_ink_canvas_aria_label").then(msg => this.canvas?.setAttribute("aria-label", msg)); 17121 this.div.append(this.canvas); 17122 this.ctx = this.canvas.getContext("2d"); 17123 } 17124 #createObserver() { 17125 this.#observer = new ResizeObserver(entries => {
17126 const rect = entries[0].contentRect; 17127 if (rect.width && rect.height) { 17128 this.setDimensions(rect.width, rect.height); 17129 } 17130 }); 17131 this.#observer.observe(this.div); 17132 } 17133 get isResizable() { 17134 return !this.isEmpty() && this.#disableEditing; 17135 } 17136 render() { 17137 if (this.div) { 17138 return this.div; 17139 } 17140 let baseX, baseY; 17141 if (this.width) { 17142 baseX = this.x; 17143 baseY = this.y; 17144 } 17145 super.render(); 17146 _editor.AnnotationEditor._l10nPromise.get("editor_ink2_aria_label").then(msg => this.div?.setAttribute("aria-label", msg)); 17147 const [x, y, w, h] = this.#getInitialBBox(); 17148 this.setAt(x, y, 0, 0); 17149 this.setDims(w, h); 17150 this.#createCanvas(); 17151 if (this.width) { 17152 const [parentWidth, parentHeight] = this.parentDimensions; 17153 this.setAspectRatio(this.width * parentWidth, this.height * parentHeight); 17154 this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); 17155 this.#isCanvasInitialized = true; 17156 this.#setCanvasDims(); 17157 this.setDims(this.width * parentWidth, this.height * parentHeight); 17158 this.#redraw(); 17159 this.div.classList.add("disabled"); 17160 } else { 17161 this.div.classList.add("editing"); 17162 this.enableEditMode(); 17163 } 17164 this.#createObserver(); 17165 return this.div; 17166 } 17167 #setCanvasDims() { 17168 if (!this.#isCanvasInitialized) { 17169 return; 17170 } 17171 const [parentWidth, parentHeight] = this.parentDimensions; 17172 this.canvas.width = Math.ceil(this.width * parentWidth); 17173 this.canvas.height = Math.ceil(this.height * parentHeight); 17174 this.#updateTransform(); 17175 } 17176 setDimensions(width, height) { 17177 const roundedWidth = Math.round(width); 17178 const roundedHeight = Math.round(height); 17179 if (this.#realWidth === roundedWidth && this.#realHeight === roundedHeight) { 17180 return; 17181 } 17182 this.#realWidth = roundedWidth; 17183 this.#realHeight = roundedHeight; 17184 this.canvas.style.visibility = "hidden"; 17185 const [parentWidth, parentHeight] = this.parentDimensions; 17186 this.width = width / parentWidth; 17187 this.height = height / parentHeight; 17188 this.fixAndSetPosition(); 17189 if (this.#disableEditing) { 17190 this.#setScaleFactor(width, height); 17191 } 17192 this.#setCanvasDims(); 17193 this.#redraw(); 17194 this.canvas.style.visibility = "visible"; 17195 this.fixDims(); 17196 } 17197 #setScaleFactor(width, height) { 17198 const padding = this.#getPadding(); 17199 const scaleFactorW = (width - padding) / this.#baseWidth; 17200 const scaleFactorH = (height - padding) / this.#baseHeight; 17201 this.scaleFactor = Math.min(scaleFactorW, scaleFactorH); 17202 } 17203 #updateTransform() { 17204 const padding = this.#getPadding() / 2; 17205 this.ctx.setTransform(this.scaleFactor, 0, 0, this.scaleFactor, this.translationX * this.scaleFactor + padding, this.translationY * this.scaleFactor + padding); 17206 } 17207 static #buildPath2D(bezier) { 17208 const path2D = new Path2D(); 17209 for (let i = 0, ii = bezier.length; i < ii; i++) { 17210 const [first, control1, control2, second] = bezier[i]; 17211 if (i === 0) { 17212 path2D.moveTo(...first); 17213 } 17214 path2D.bezierCurveTo(control1[0], control1[1], control2[0], control2[1], second[0], second[1]); 17215 } 17216 return path2D; 17217 } 17218 static #toPDFCoordinates(points, rect, rotation) { 17219 const [blX, blY, trX, trY] = rect; 17220 switch (rotation) { 17221 case 0: 17222 for (let i = 0, ii = points.length; i < ii; i += 2) { 17223 points[i] += blX; 17224 points[i + 1] = trY - points[i + 1]; 17225 } 17226 break; 17227 case 90: 17228 for (let i = 0, ii = points.length; i < ii; i += 2) { 17229 const x = points[i]; 17230 points[i] = points[i + 1] + blX; 17231 points[i + 1] = x + blY; 17232 } 17233 break; 17234 case 180: 17235 for (let i = 0, ii = points.length; i < ii; i += 2) { 17236 points[i] = trX - points[i]; 17237 points[i + 1] += blY; 17238 } 17239 break; 17240 case 270: 17241 for (let i = 0, ii = points.length; i < ii; i += 2) { 17242 const x = points[i]; 17243 points[i] = trX - points[i + 1]; 17244 points[i + 1] = trY - x; 17245 } 17246 break; 17247 default: 17248 throw new Error("Invalid rotation"); 17249 } 17250 return points; 17251 } 17252 static #fromPDFCoordinates(points, rect, rotation) { 17253 const [blX, blY, trX, trY] = rect; 17254 switch (rotation) { 17255 case 0: 17256 for (let i = 0, ii = points.length; i < ii; i += 2) { 17257 points[i] -= blX; 17258 points[i + 1] = trY - points[i + 1]; 17259 } 17260 break; 17261 case 90: 17262 for (let i = 0, ii = points.length; i < ii; i += 2) { 17263 const x = points[i]; 17264 points[i] = points[i + 1] - blY; 17265 points[i + 1] = x - blX; 17266 } 17267 break; 17268 case 180: 17269 for (let i = 0, ii = points.length; i < ii; i += 2) { 17270 points[i] = trX - points[i]; 17271 points[i + 1] -= blY; 17272 } 17273 break; 17274 case 270: 17275 for (let i = 0, ii = points.length; i < ii; i += 2) { 17276 const x = points[i]; 17277 points[i] = trY - points[i + 1]; 17278 points[i + 1] = trX - x; 17279 } 17280 break; 17281 default: 17282 throw new Error("Invalid rotation"); 17283 } 17284 return points; 17285 } 17286 #serializePaths(s, tx, ty, rect) { 17287 const paths = []; 17288 const padding = this.thickness / 2; 17289 const shiftX = s * tx + padding; 17290 const shiftY = s * ty + padding; 17291 for (const bezier of this.paths) { 17292 const buffer = []; 17293 const points = []; 17294 for (let j = 0, jj = bezier.length; j < jj; j++) { 17295 const [first, control1, control2, second] = bezier[j]; 17296 const p10 = s * first[0] + shiftX; 17297 const p11 = s * first[1] + shiftY; 17298 const p20 = s * control1[0] + shiftX; 17299 const p21 = s * control1[1] + shiftY; 17300 const p30 = s * control2[0] + shiftX; 17301 const p31 = s * control2[1] + shiftY; 17302 const p40 = s * second[0] + shiftX; 17303 const p41 = s * second[1] + shiftY; 17304 if (j === 0) { 17305 buffer.push(p10, p11); 17306 points.push(p10, p11); 17307 } 17308 buffer.push(p20, p21, p30, p31, p40, p41); 17309 points.push(p20, p21); 17310 if (j === jj - 1) { 17311 points.push(p40, p41); 17312 } 17313 } 17314 paths.push({ 17315 bezier: InkEditor.#toPDFCoordinates(buffer, rect, this.rotation), 17316 points: InkEditor.#toPDFCoordinates(points, rect, this.rotation) 17317 }); 17318 } 17319 return paths; 17320 } 17321 #getBbox() { 17322 let xMin = Infinity; 17323 let xMax = -Infinity; 17324 let yMin = Infinity; 17325 let yMax = -Infinity; 17326 for (const path of this.paths) { 17327 for (const [first, control1, control2, second] of path) { 17328 const bbox = _util.Util.bezierBoundingBox(...first, ...control1, ...control2, ...second); 17329 xMin = Math.min(xMin, bbox[0]); 17330 yMin = Math.min(yMin, bbox[1]); 17331 xMax = Math.max(xMax, bbox[2]); 17332 yMax = Math.max(yMax, bbox[3]); 17333 } 17334 } 17335 return [xMin, yMin, xMax, yMax]; 17336 } 17337 #getPadding() { 17338 return this.#disableEditing ? Math.ceil(this.thickness * this.parentScale) : 0; 17339 } 17340 #fitToContent(firstTime = false) { 17341 if (this.isEmpty()) { 17342 return; 17343 } 17344 if (!this.#disableEditing) { 17345 this.#redraw(); 17346 return; 17347 } 17348 const bbox = this.#getBbox(); 17349 const padding = this.#getPadding();
17350 this.#baseWidth = Math.max(_editor.AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]); 17351 this.#baseHeight = Math.max(_editor.AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]); 17352 const width = Math.ceil(padding + this.#baseWidth * this.scaleFactor); 17353 const height = Math.ceil(padding + this.#baseHeight * this.scaleFactor); 17354 const [parentWidth, parentHeight] = this.parentDimensions; 17355 this.width = width / parentWidth; 17356 this.height = height / parentHeight; 17357 this.setAspectRatio(width, height); 17358 const prevTranslationX = this.translationX; 17359 const prevTranslationY = this.translationY; 17360 this.translationX = -bbox[0]; 17361 this.translationY = -bbox[1]; 17362 this.#setCanvasDims(); 17363 this.#redraw(); 17364 this.#realWidth = width; 17365 this.#realHeight = height; 17366 this.setDims(width, height); 17367 const unscaledPadding = firstTime ? padding / this.scaleFactor / 2 : 0; 17368 this.translate(prevTranslationX - this.translationX - unscaledPadding, prevTranslationY - this.translationY - unscaledPadding); 17369 } 17370 static deserialize(data, parent, uiManager) { 17371 if (data instanceof _annotation_layer.InkAnnotationElement) { 17372 return null; 17373 } 17374 const editor = super.deserialize(data, parent, uiManager); 17375 editor.thickness = data.thickness; 17376 editor.color = _util.Util.makeHexColor(...data.color); 17377 editor.opacity = data.opacity; 17378 const [pageWidth, pageHeight] = editor.pageDimensions; 17379 const width = editor.width * pageWidth; 17380 const height = editor.height * pageHeight; 17381 const scaleFactor = editor.parentScale; 17382 const padding = data.thickness / 2; 17383 editor.#disableEditing = true; 17384 editor.#realWidth = Math.round(width); 17385 editor.#realHeight = Math.round(height); 17386 const { 17387 paths, 17388 rect, 17389 rotation 17390 } = data; 17391 for (let { 17392 bezier 17393 } of paths) { 17394 bezier = InkEditor.#fromPDFCoordinates(bezier, rect, rotation); 17395 const path = []; 17396 editor.paths.push(path); 17397 let p0 = scaleFactor * (bezier[0] - padding); 17398 let p1 = scaleFactor * (bezier[1] - padding); 17399 for (let i = 2, ii = bezier.length; i < ii; i += 6) { 17400 const p10 = scaleFactor * (bezier[i] - padding); 17401 const p11 = scaleFactor * (bezier[i + 1] - padding); 17402 const p20 = scaleFactor * (bezier[i + 2] - padding); 17403 const p21 = scaleFactor * (bezier[i + 3] - padding); 17404 const p30 = scaleFactor * (bezier[i + 4] - padding); 17405 const p31 = scaleFactor * (bezier[i + 5] - padding); 17406 path.push([[p0, p1], [p10, p11], [p20, p21], [p30, p31]]); 17407 p0 = p30; 17408 p1 = p31; 17409 } 17410 const path2D = this.#buildPath2D(path); 17411 editor.bezierPath2D.push(path2D); 17412 } 17413 const bbox = editor.#getBbox(); 17414 editor.#baseWidth = Math.max(_editor.AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]); 17415 editor.#baseHeight = Math.max(_editor.AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]); 17416 editor.#setScaleFactor(width, height); 17417 return editor; 17418 } 17419 serialize() { 17420 if (this.isEmpty()) { 17421 return null; 17422 } 17423 const rect = this.getRect(0, 0); 17424 const color = _editor.AnnotationEditor._colorManager.convert(this.ctx.strokeStyle); 17425 return { 17426 annotationType: _util.AnnotationEditorType.INK, 17427 color, 17428 thickness: this.thickness, 17429 opacity: this.opacity, 17430 paths: this.#serializePaths(this.scaleFactor / this.parentScale, this.translationX, this.translationY, rect), 17431 pageIndex: this.pageIndex, 17432 rect, 17433 rotation: this.rotation, 17434 structTreeParentId: this._structTreeParentId 17435 }; 17436 } 17437} 17438exports.InkEditor = InkEditor; 17439 17440/***/ }), 17441/* 34 */ 17442/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 17443 17444 17445 17446Object.defineProperty(exports, "__esModule", ({ 17447 value: true 17448})); 17449exports.StampEditor = void 0; 17450var _util = __w_pdfjs_require__(1); 17451var _editor = __w_pdfjs_require__(4); 17452var _display_utils = __w_pdfjs_require__(6); 17453var _annotation_layer = __w_pdfjs_require__(29); 17454class StampEditor extends _editor.AnnotationEditor { 17455 #bitmap = null; 17456 #bitmapId = null; 17457 #bitmapPromise = null; 17458 #bitmapUrl = null; 17459 #bitmapFile = null; 17460 #canvas = null; 17461 #observer = null; 17462 #resizeTimeoutId = null; 17463 #isSvg = false;
17464 #hasBeenAddedInUndoStack = false; 17465 static _type = "stamp"; 17466 constructor(params) { 17467 super({ 17468 ...params, 17469 name: "stampEditor" 17470 }); 17471 this.#bitmapUrl = params.bitmapUrl; 17472 this.#bitmapFile = params.bitmapFile; 17473 } 17474 static initialize(l10n) { 17475 _editor.AnnotationEditor.initialize(l10n); 17476 } 17477 static get supportedTypes() { 17478 const types = ["apng", "avif", "bmp", "gif", "jpeg", "png", "svg+xml", "webp", "x-icon"]; 17479 return (0, _util.shadow)(this, "supportedTypes", types.map(type => `image/${type}`)); 17480 } 17481 static get supportedTypesStr() { 17482 return (0, _util.shadow)(this, "supportedTypesStr", this.supportedTypes.join(",")); 17483 } 17484 static isHandlingMimeForPasting(mime) { 17485 return this.supportedTypes.includes(mime); 17486 } 17487 static paste(item, parent) { 17488 parent.pasteEditor(_util.AnnotationEditorType.STAMP, { 17489 bitmapFile: item.getAsFile() 17490 }); 17491 } 17492 #getBitmapFetched(data, fromId = false) { 17493 if (!data) { 17494 this.remove(); 17495 return; 17496 } 17497 this.#bitmap = data.bitmap; 17498 if (!fromId) { 17499 this.#bitmapId = data.id; 17500 this.#isSvg = data.isSvg; 17501 } 17502 this.#createCanvas(); 17503 } 17504 #getBitmapDone() { 17505 this.#bitmapPromise = null; 17506 this._uiManager.enableWaiting(false); 17507 if (this.#canvas) { 17508 this.div.focus(); 17509 } 17510 } 17511 #getBitmap() { 17512 if (this.#bitmapId) { 17513 this._uiManager.enableWaiting(true); 17514 this._uiManager.imageManager.getFromId(this.#bitmapId).then(data => this.#getBitmapFetched(data, true)).finally(() => this.#getBitmapDone()); 17515 return; 17516 } 17517 if (this.#bitmapUrl) { 17518 const url = this.#bitmapUrl; 17519 this.#bitmapUrl = null; 17520 this._uiManager.enableWaiting(true); 17521 this.#bitmapPromise = this._uiManager.imageManager.getFromUrl(url).then(data => this.#getBitmapFetched(data)).finally(() => this.#getBitmapDone()); 17522 return; 17523 } 17524 if (this.#bitmapFile) { 17525 const file = this.#bitmapFile; 17526 this.#bitmapFile = null; 17527 this._uiManager.enableWaiting(true); 17528 this.#bitmapPromise = this._uiManager.imageManager.getFromFile(file).then(data => this.#getBitmapFetched(data)).finally(() => this.#getBitmapDone()); 17529 return; 17530 } 17531 const input = document.createElement("input"); 17532 input.type = "file"; 17533 input.accept = StampEditor.supportedTypesStr; 17534 this.#bitmapPromise = new Promise(resolve => { 17535 input.addEventListener("change", async () => { 17536 if (!input.files || input.files.length === 0) { 17537 this.remove(); 17538 } else { 17539 this._uiManager.enableWaiting(true); 17540 const data = await this._uiManager.imageManager.getFromFile(input.files[0]); 17541 this.#getBitmapFetched(data); 17542 } 17543 resolve(); 17544 }); 17545 input.addEventListener("cancel", () => { 17546 this.remove(); 17547 resolve(); 17548 }); 17549 }).finally(() => this.#getBitmapDone()); 17550 input.click(); 17551 } 17552 remove() { 17553 if (this.#bitmapId) { 17554 this.#bitmap = null; 17555 this._uiManager.imageManager.deleteId(this.#bitmapId); 17556 this.#canvas?.remove(); 17557 this.#canvas = null; 17558 this.#observer?.disconnect(); 17559 this.#observer = null; 17560 } 17561 super.remove(); 17562 } 17563 rebuild() { 17564 if (!this.parent) { 17565 if (this.#bitmapId) { 17566 this.#getBitmap(); 17567 } 17568 return; 17569 } 17570 super.rebuild(); 17571 if (this.div === null) { 17572 return; 17573 } 17574 if (this.#bitmapId) { 17575 this.#getBitmap(); 17576 } 17577 if (!this.isAttachedToDOM) { 17578 this.parent.add(this); 17579 } 17580 } 17581 onceAdded() { 17582 this._isDraggable = true; 17583 this.div.focus(); 17584 } 17585 isEmpty() { 17586 return !(this.#bitmapPromise || this.#bitmap || this.#bitmapUrl || this.#bitmapFile); 17587 } 17588 get isResizable() { 17589 return true; 17590 } 17591 render() { 17592 if (this.div) { 17593 return this.div; 17594 } 17595 let baseX, baseY; 17596 if (this.width) { 17597 baseX = this.x; 17598 baseY = this.y; 17599 } 17600 super.render(); 17601 this.div.hidden = true; 17602 if (this.#bitmap) { 17603 this.#createCanvas(); 17604 } else { 17605 this.#getBitmap(); 17606 } 17607 if (this.width) { 17608 const [parentWidth, parentHeight] = this.parentDimensions; 17609 this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); 17610 } 17611 return this.div; 17612 } 17613 #createCanvas() { 17614 const { 17615 div 17616 } = this; 17617 let { 17618 width, 17619 height 17620 } = this.#bitmap; 17621 const [pageWidth, pageHeight] = this.pageDimensions; 17622 const MAX_RATIO = 0.75; 17623 if (this.width) { 17624 width = this.width * pageWidth; 17625 height = this.height * pageHeight; 17626 } else if (width > MAX_RATIO * pageWidth || height > MAX_RATIO * pageHeight) { 17627 const factor = Math.min(MAX_RATIO * pageWidth / width, MAX_RATIO * pageHeight / height); 17628 width *= factor; 17629 height *= factor; 17630 } 17631 const [parentWidth, parentHeight] = this.parentDimensions; 17632 this.setDims(width * parentWidth / pageWidth, height * parentHeight / pageHeight); 17633 this._uiManager.enableWaiting(false); 17634 const canvas = this.#canvas = document.createElement("canvas"); 17635 div.append(canvas); 17636 div.hidden = false;
17637 this.#drawBitmap(width, height); 17638 this.#createObserver(); 17639 if (!this.#hasBeenAddedInUndoStack) { 17640 this.parent.addUndoableEditor(this); 17641 this.#hasBeenAddedInUndoStack = true; 17642 } 17643 this._uiManager._eventBus.dispatch("reporttelemetry", { 17644 source: this, 17645 details: { 17646 type: "editing", 17647 subtype: this.editorType, 17648 data: { 17649 action: "inserted_image" 17650 } 17651 } 17652 }); 17653 this.addAltTextButton(); 17654 } 17655 #setDimensions(width, height) { 17656 const [parentWidth, parentHeight] = this.parentDimensions; 17657 this.width = width / parentWidth; 17658 this.height = height / parentHeight; 17659 this.setDims(width, height); 17660 if (this._initialOptions?.isCentered) { 17661 this.center(); 17662 } else { 17663 this.fixAndSetPosition(); 17664 } 17665 this._initialOptions = null; 17666 if (this.#resizeTimeoutId !== null) { 17667 clearTimeout(this.#resizeTimeoutId); 17668 } 17669 const TIME_TO_WAIT = 200; 17670 this.#resizeTimeoutId = setTimeout(() => { 17671 this.#resizeTimeoutId = null; 17672 this.#drawBitmap(width, height); 17673 }, TIME_TO_WAIT); 17674 } 17675 #scaleBitmap(width, height) { 17676 const { 17677 width: bitmapWidth, 17678 height: bitmapHeight 17679 } = this.#bitmap; 17680 let newWidth = bitmapWidth; 17681 let newHeight = bitmapHeight; 17682 let bitmap = this.#bitmap; 17683 while (newWidth > 2 * width || newHeight > 2 * height) { 17684 const prevWidth = newWidth; 17685 const prevHeight = newHeight; 17686 if (newWidth > 2 * width) { 17687 newWidth = newWidth >= 16384 ? Math.floor(newWidth / 2) - 1 : Math.ceil(newWidth / 2); 17688 } 17689 if (newHeight > 2 * height) { 17690 newHeight = newHeight >= 16384 ? Math.floor(newHeight / 2) - 1 : Math.ceil(newHeight / 2); 17691 } 17692 const offscreen = new OffscreenCanvas(newWidth, newHeight); 17693 const ctx = offscreen.getContext("2d"); 17694 ctx.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight); 17695 bitmap = offscreen.transferToImageBitmap(); 17696 } 17697 return bitmap; 17698 } 17699 #drawBitmap(width, height) { 17700 width = Math.ceil(width); 17701 height = Math.ceil(height); 17702 const canvas = this.#canvas; 17703 if (!canvas || canvas.width === width && canvas.height === height) { 17704 return; 17705 } 17706 canvas.width = width; 17707 canvas.height = height; 17708 const bitmap = this.#isSvg ? this.#bitmap : this.#scaleBitmap(width, height); 17709 const ctx = canvas.getContext("2d"); 17710 ctx.filter = this._uiManager.hcmFilter; 17711 ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height); 17712 } 17713 #serializeBitmap(toUrl) { 17714 if (toUrl) { 17715 if (this.#isSvg) { 17716 const url = this._uiManager.imageManager.getSvgUrl(this.#bitmapId); 17717 if (url) { 17718 return url; 17719 } 17720 } 17721 const canvas = document.createElement("canvas"); 17722 ({ 17723 width: canvas.width, 17724 height: canvas.height 17725 } = this.#bitmap); 17726 const ctx = canvas.getContext("2d"); 17727 ctx.drawImage(this.#bitmap, 0, 0); 17728 return canvas.toDataURL(); 17729 } 17730 if (this.#isSvg) { 17731 const [pageWidth, pageHeight] = this.pageDimensions; 17732 const width = Math.round(this.width * pageWidth * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS); 17733 const height = Math.round(this.height * pageHeight * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS); 17734 const offscreen = new OffscreenCanvas(width, height); 17735 const ctx = offscreen.getContext("2d"); 17736 ctx.drawImage(this.#bitmap, 0, 0, this.#bitmap.width, this.#bitmap.height, 0, 0, width, height); 17737 return offscreen.transferToImageBitmap(); 17738 } 17739 return structuredClone(this.#bitmap); 17740 } 17741 #createObserver() { 17742 this.#observer = new ResizeObserver(entries => { 17743 const rect = entries[0].contentRect; 17744 if (rect.width && rect.height) { 17745 this.#setDimensions(rect.width, rect.height); 17746 } 17747 }); 17748 this.#observer.observe(this.div); 17749 } 17750 static deserialize(data, parent, uiManager) { 17751 if (data instanceof _annotation_layer.StampAnnotationElement) { 17752 return null; 17753 } 17754 const editor = super.deserialize(data, parent, uiManager); 17755 const { 17756 rect, 17757 bitmapUrl, 17758 bitmapId, 17759 isSvg, 17760 accessibilityData 17761 } = data; 17762 if (bitmapId && uiManager.imageManager.isValidId(bitmapId)) { 17763 editor.#bitmapId = bitmapId; 17764 } else { 17765 editor.#bitmapUrl = bitmapUrl; 17766 } 17767 editor.#isSvg = isSvg; 17768 const [parentWidth, parentHeight] = editor.pageDimensions; 17769 editor.width = (rect[2] - rect[0]) / parentWidth; 17770 editor.height = (rect[3] - rect[1]) / parentHeight; 17771 if (accessibilityData) { 17772 editor.altTextData = accessibilityData; 17773 } 17774 return editor; 17775 } 17776 serialize(isForCopying = false, context = null) { 17777 if (this.isEmpty()) { 17778 return null; 17779 } 17780 const serialized = { 17781 annotationType: _util.AnnotationEditorType.STAMP, 17782 bitmapId: this.#bitmapId, 17783 pageIndex: this.pageIndex, 17784 rect: this.getRect(0, 0), 17785 rotation: this.rotation, 17786 isSvg: this.#isSvg, 17787 structTreeParentId: this._structTreeParentId 17788 }; 17789 if (isForCopying) { 17790 serialized.bitmapUrl = this.#serializeBitmap(true); 17791 serialized.accessibilityData = this.altTextData; 17792 return serialized; 17793 } 17794 const { 17795 decorative, 17796 altText 17797 } = this.altTextData; 17798 if (!decorative && altText) { 17799 serialized.accessibilityData = { 17800 type: "Figure", 17801 alt: altText 17802 }; 17803 } 17804 if (context === null) { 17805 return serialized; 17806 } 17807 context.stamps ||= new Map(); 17808 const area = this.#isSvg ? (serialized.rect[2] - serialized.rect[0]) * (serialized.rect[3] - serialized.rect[1]) : null; 17809 if (!context.stamps.has(this.#bitmapId)) { 17810 context.stamps.set(this.#bitmapId, { 17811 area,
17812 serialized 17813 }); 17814 serialized.bitmap = this.#serializeBitmap(false); 17815 } else if (this.#isSvg) { 17816 const prevData = context.stamps.get(this.#bitmapId); 17817 if (area > prevData.area) { 17818 prevData.area = area; 17819 prevData.serialized.bitmap.close(); 17820 prevData.serialized.bitmap = this.#serializeBitmap(false); 17821 } 17822 } 17823 return serialized; 17824 } 17825} 17826exports.StampEditor = StampEditor; 17827 17828/***/ }) 17829/******/ ]); 17830/************************************************************************/ 17831/******/ // The module cache 17832/******/ var __webpack_module_cache__ = {}; 17833/******/ 17834/******/ // The require function 17835/******/ function __w_pdfjs_require__(moduleId) { 17836/******/ // Check if module is in cache 17837/******/ var cachedModule = __webpack_module_cache__[moduleId]; 17838/******/ if (cachedModule !== undefined) { 17839/******/ return cachedModule.exports; 17840/******/ } 17841/******/ // Create a new module (and put it into the cache) 17842/******/ var module = __webpack_module_cache__[moduleId] = { 17843/******/ // no module.id needed 17844/******/ // no module.loaded needed 17845/******/ exports: {} 17846/******/ }; 17847/******/ 17848/******/ // Execute the module function 17849/******/ __webpack_modules__[moduleId](module, module.exports, __w_pdfjs_require__); 17850/******/ 17851/******/ // Return the exports of the module 17852/******/ return module.exports; 17853/******/ } 17854/******/ 17855/************************************************************************/ 17856var __webpack_exports__ = {}; 17857// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. 17858(() => { 17859var exports = __webpack_exports__; 17860 17861 17862Object.defineProperty(exports, "__esModule", ({ 17863 value: true 17864})); 17865Object.defineProperty(exports, "AbortException", ({ 17866 enumerable: true, 17867 get: function () { 17868 return _util.AbortException; 17869 } 17870})); 17871Object.defineProperty(exports, "AnnotationEditorLayer", ({ 17872 enumerable: true, 17873 get: function () { 17874 return _annotation_editor_layer.AnnotationEditorLayer; 17875 } 17876})); 17877Object.defineProperty(exports, "AnnotationEditorParamsType", ({ 17878 enumerable: true, 17879 get: function () { 17880 return _util.AnnotationEditorParamsType; 17881 } 17882})); 17883Object.defineProperty(exports, "AnnotationEditorType", ({ 17884 enumerable: true, 17885 get: function () { 17886 return _util.AnnotationEditorType; 17887 } 17888})); 17889Object.defineProperty(exports, "AnnotationEditorUIManager", ({ 17890 enumerable: true, 17891 get: function () { 17892 return _tools.AnnotationEditorUIManager; 17893 } 17894})); 17895Object.defineProperty(exports, "AnnotationLayer", ({ 17896 enumerable: true, 17897 get: function () { 17898 return _annotation_layer.AnnotationLayer; 17899 } 17900})); 17901Object.defineProperty(exports, "AnnotationMode", ({ 17902 enumerable: true, 17903 get: function () { 17904 return _util.AnnotationMode; 17905 } 17906})); 17907Object.defineProperty(exports, "CMapCompressionType", ({ 17908 enumerable: true, 17909 get: function () { 17910 return _util.CMapCompressionType; 17911 } 17912})); 17913Object.defineProperty(exports, "DOMSVGFactory", ({ 17914 enumerable: true, 17915 get: function () { 17916 return _display_utils.DOMSVGFactory; 17917 } 17918})); 17919Object.defineProperty(exports, "FeatureTest", ({ 17920 enumerable: true, 17921 get: function () { 17922 return _util.FeatureTest; 17923 } 17924})); 17925Object.defineProperty(exports, "GlobalWorkerOptions", ({ 17926 enumerable: true, 17927 get: function () { 17928 return _worker_options.GlobalWorkerOptions; 17929 } 17930})); 17931Object.defineProperty(exports, "ImageKind", ({ 17932 enumerable: true, 17933 get: function () { 17934 return _util.ImageKind; 17935 } 17936})); 17937Object.defineProperty(exports, "InvalidPDFException", ({ 17938 enumerable: true, 17939 get: function () { 17940 return _util.InvalidPDFException; 17941 } 17942})); 17943Object.defineProperty(exports, "MissingPDFException", ({ 17944 enumerable: true, 17945 get: function () { 17946 return _util.MissingPDFException; 17947 } 17948})); 17949Object.defineProperty(exports, "OPS", ({ 17950 enumerable: true, 17951 get: function () { 17952 return _util.OPS; 17953 } 17954})); 17955Object.defineProperty(exports, "PDFDataRangeTransport", ({ 17956 enumerable: true, 17957 get: function () { 17958 return _api.PDFDataRangeTransport; 17959 } 17960})); 17961Object.defineProperty(exports, "PDFDateString", ({ 17962 enumerable: true, 17963 get: function () { 17964 return _display_utils.PDFDateString; 17965 } 17966})); 17967Object.defineProperty(exports, "PDFWorker", ({ 17968 enumerable: true, 17969 get: function () { 17970 return _api.PDFWorker; 17971 } 17972})); 17973Object.defineProperty(exports, "PasswordResponses", ({ 17974 enumerable: true, 17975 get: function () { 17976 return _util.PasswordResponses; 17977 } 17978})); 17979Object.defineProperty(exports, "PermissionFlag", ({ 17980 enumerable: true, 17981 get: function () { 17982 return _util.PermissionFlag; 17983 } 17984})); 17985Object.defineProperty(exports, "PixelsPerInch", ({ 17986 enumerable: true, 17987 get: function () { 17988 return _display_utils.PixelsPerInch; 17989 } 17990})); 17991Object.defineProperty(exports, "PromiseCapability", ({ 17992 enumerable: true, 17993 get: function () { 17994 return _util.PromiseCapability; 17995 } 17996})); 17997Object.defineProperty(exports, "RenderingCancelledException", ({ 17998 enumerable: true, 17999 get: function () { 18000 return _display_utils.RenderingCancelledException; 18001 } 18002})); 18003Object.defineProperty(exports, "SVGGraphics", ({ 18004 enumerable: true, 18005 get: function () { 18006 return _api.SVGGraphics; 18007 } 18008})); 18009Object.defineProperty(exports, "UnexpectedResponseException", ({ 18010 enumerable: true, 18011 get: function () { 18012 return _util.UnexpectedResponseException; 18013 } 18014})); 18015Object.defineProperty(exports, "Util", ({ 18016 enumerable: true, 18017 get: function () { 18018 return _util.Util; 18019 } 18020})); 18021Object.defineProperty(exports, "VerbosityLevel", ({ 18022 enumerable: true, 18023 get: function () { 18024 return _util.VerbosityLevel; 18025 } 18026})); 18027Object.defineProperty(exports, "XfaLayer", ({ 18028 enumerable: true, 18029 get: function () { 18030 return _xfa_layer.XfaLayer; 18031 } 18032}));
18033Object.defineProperty(exports, "build", ({ 18034 enumerable: true, 18035 get: function () { 18036 return _api.build; 18037 } 18038})); 18039Object.defineProperty(exports, "createValidAbsoluteUrl", ({ 18040 enumerable: true, 18041 get: function () { 18042 return _util.createValidAbsoluteUrl; 18043 } 18044})); 18045Object.defineProperty(exports, "getDocument", ({ 18046 enumerable: true, 18047 get: function () { 18048 return _api.getDocument; 18049 } 18050})); 18051Object.defineProperty(exports, "getFilenameFromUrl", ({ 18052 enumerable: true, 18053 get: function () { 18054 return _display_utils.getFilenameFromUrl; 18055 } 18056})); 18057Object.defineProperty(exports, "getPdfFilenameFromUrl", ({ 18058 enumerable: true, 18059 get: function () { 18060 return _display_utils.getPdfFilenameFromUrl; 18061 } 18062})); 18063Object.defineProperty(exports, "getXfaPageViewport", ({ 18064 enumerable: true, 18065 get: function () { 18066 return _display_utils.getXfaPageViewport; 18067 } 18068})); 18069Object.defineProperty(exports, "isDataScheme", ({ 18070 enumerable: true, 18071 get: function () { 18072 return _display_utils.isDataScheme; 18073 } 18074})); 18075Object.defineProperty(exports, "isPdfFile", ({ 18076 enumerable: true, 18077 get: function () { 18078 return _display_utils.isPdfFile; 18079 } 18080})); 18081Object.defineProperty(exports, "loadScript", ({ 18082 enumerable: true, 18083 get: function () { 18084 return _display_utils.loadScript; 18085 } 18086})); 18087Object.defineProperty(exports, "noContextMenu", ({ 18088 enumerable: true, 18089 get: function () { 18090 return _display_utils.noContextMenu; 18091 } 18092})); 18093Object.defineProperty(exports, "normalizeUnicode", ({ 18094 enumerable: true, 18095 get: function () { 18096 return _util.normalizeUnicode; 18097 } 18098})); 18099Object.defineProperty(exports, "renderTextLayer", ({ 18100 enumerable: true, 18101 get: function () { 18102 return _text_layer.renderTextLayer; 18103 } 18104})); 18105Object.defineProperty(exports, "setLayerDimensions", ({ 18106 enumerable: true, 18107 get: function () { 18108 return _display_utils.setLayerDimensions; 18109 } 18110})); 18111Object.defineProperty(exports, "shadow", ({ 18112 enumerable: true, 18113 get: function () { 18114 return _util.shadow; 18115 } 18116})); 18117Object.defineProperty(exports, "updateTextLayer", ({ 18118 enumerable: true, 18119 get: function () { 18120 return _text_layer.updateTextLayer; 18121 } 18122})); 18123Object.defineProperty(exports, "version", ({ 18124 enumerable: true, 18125 get: function () { 18126 return _api.version; 18127 } 18128})); 18129var _util = __w_pdfjs_require__(1); 18130var _api = __w_pdfjs_require__(2); 18131var _display_utils = __w_pdfjs_require__(6); 18132var _text_layer = __w_pdfjs_require__(26); 18133var _annotation_editor_layer = __w_pdfjs_require__(27); 18134var _tools = __w_pdfjs_require__(5); 18135var _annotation_layer = __w_pdfjs_require__(29); 18136var _worker_options = __w_pdfjs_require__(14); 18137var _xfa_layer = __w_pdfjs_require__(32); 18138const pdfjsVersion = '3.11.174'; 18139const pdfjsBuild = 'ce8716743'; 18140})(); 18141 18142/******/ return __webpack_exports__; 18143/******/ })() 18144; 18145}); 18146//# sourceMappingURL=pdf.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.