1window.ngxZone.runOutsideAngular(() => { 2/** 3 * @licstart The following is the entire license notice for the 4 * JavaScript code in this page 5 * 6 * Copyright 2023 Mozilla Foundation 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 * @licend The above is the entire license notice for the 21 * JavaScript code in this page 22 */ 23 24(function webpackUniversalModuleDefinition(root, factory) { 25 if(typeof exports === 'object' && typeof module === 'object') 26 module.exports = root.pdfjsLib = factory(); 27 else if(typeof define === 'function' && define.amd) 28 define("pdfjs-dist/build/pdf", [], () => { return (root.pdfjsLib = factory()); }); 29 else if(typeof exports === 'object') 30 exports["pdfjs-dist/build/pdf"] = root.pdfjsLib = factory(); 31 else 32 root["pdfjs-dist/build/pdf"] = root.pdfjsLib = factory(); 33})(globalThis, () => { 34return /******/ (() => { // webpackBootstrap 35/******/ "use strict"; 36/******/ var __webpack_modules__ = ([ 37/* 0 */, 38/* 1 */ 39/***/ ((__unused_webpack_module, exports) => { 40 41 42 43Object.defineProperty(exports, "__esModule", ({ 44 value: true 45})); 46exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.RenderingIntentFlag = exports.PromiseCapability = exp
46orts.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.AnnotationMode = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationEditorType = exports.AnnotationEditorPrefix = exports.AnnotationEditorParamsType = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0; 47exports.assert = assert; 48exports.bytesToString = bytesToString; 49exports.createValidAbsoluteUrl = createValidAbsoluteUrl; 50exports.getModificationDate = getModificationDate; 51exports.getUuid = getUuid; 52exports.getVerbosityLevel = getVerbosityLevel; 53exports.info = info; 54exports.isArrayBuffer = isArrayBuffer; 55exports.isArrayEqual = isArrayEqual; 56exports.isNodeJS = void 0; 57exports.normalizeUnicode = normalizeUnicode; 58exports.objectFromMap = objectFromMap; 59exports.objectSize = objectSize; 60exports.setVerbosityLevel = setVerbosityLevel; 61exports.shadow = shadow; 62exports.string32 = string32; 63exports.stringToBytes = stringToBytes; 64exports.stringToPDFString = stringToPDFString; 65exports.stringToUTF8String = stringToUTF8String; 66exports.unreachable = unreachable; 67exports.utf8StringToString = utf8StringToString; 68exports.warn = warn; 69const isNodeJS = exports.isNodeJS = typeof process === "object" && process + "" === "[object process]" && !process.versions.nw && !(process.versions.electron && process.type && process.type !== "browser"); 70const IDENTITY_MATRIX = exports.IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; 71const FONT_IDENTITY_MATRIX = exports.FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0]; 72const MAX_IMAGE_SIZE_TO_CACHE = exports.MAX_IMAGE_SIZE_TO_CACHE = 10e6; 73const LINE_FACTOR = exports.LINE_FACTOR = 1.35; 74const LINE_DESCENT_FACTOR = exports.LINE_DESCENT_FACTOR = 0.35; 75const BASELINE_FACTOR = exports.BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR; 76const RenderingIntentFlag = exports.RenderingIntentFlag = { 77 ANY: 0x01, 78 DISPLAY: 0x02, 79 PRINT: 0x04, 80 SAVE: 0x08, 81 ANNOTATIONS_FORMS: 0x10, 82 ANNOTATIONS_STORAGE: 0x20, 83 ANNOTATIONS_DISABLE: 0x40, 84 OPLIST: 0x100 85}; 86const AnnotationMode = exports.AnnotationMode = { 87 DISABLE: 0, 88 ENABLE: 1, 89 ENABLE_FORMS: 2, 90 ENABLE_STORAGE: 3 91}; 92const AnnotationEditorPrefix = exports.AnnotationEditorPrefix = "pdfjs_internal_editor_"; 93const AnnotationEditorType = exports.AnnotationEditorType = { 94 DISABLE: -1, 95 NONE: 0, 96 FREETEXT: 3, 97 STAMP: 13, 98 INK: 15 99}; 100const AnnotationEditorParamsType = exports.AnnotationEditorParamsType = { 101 RESIZE: 1, 102 CREATE: 2, 103 FREETEXT_SIZE: 11, 104 FREETEXT_COLOR: 12, 105 FREETEXT_OPACITY: 13, 106 INK_COLOR: 21, 107 INK_THICKNESS: 22, 108 INK_OPACITY: 23 109}; 110const PermissionFlag = exports.PermissionFlag = { 111 PRINT: 0x04, 112 MODIFY_CONTENTS: 0x08, 113 COPY: 0x10, 114 MODIFY_ANNOTATIONS: 0x20, 115 FILL_INTERACTIVE_FORMS: 0x100, 116 COPY_FOR_ACCESSIBILITY: 0x200, 117 ASSEMBLE: 0x400, 118 PRINT_HIGH_QUALITY: 0x800 119}; 120const TextRenderingMode = exports.TextRenderingMode = { 121 FILL: 0, 122 STROKE: 1, 123 FILL_STROKE: 2, 124 INVISIBLE: 3, 125 FILL_ADD_TO_PATH: 4, 126 STROKE_ADD_TO_PATH: 5, 127 FILL_STROKE_ADD_TO_PATH: 6, 128 ADD_TO_PATH: 7, 129 FILL_STROKE_MASK: 3, 130 ADD_TO_PATH_FLAG: 4 131}; 132const ImageKind = exports.ImageKind = { 133 GRAYSCALE_1BPP: 1, 134 RGB_24BPP: 2, 135 RGBA_32BPP: 3 136}; 137const AnnotationType = exports.AnnotationType = { 138 TEXT: 1, 139 LINK: 2, 140 FREETEXT: 3, 141 LINE: 4, 142 SQUARE: 5, 143 CIRCLE: 6, 144 POLYGON: 7, 145 POLYLINE: 8, 146 HIGHLIGHT: 9, 147 UNDERLINE: 10, 148 SQUIGGLY: 11, 149 STRIKEOUT: 12, 150 STAMP: 13, 151 CARET: 14, 152 INK: 15, 153 POPUP: 16, 154 FILEATTACHMENT: 17, 155 SOUND: 18, 156 MOVIE: 19, 157 WIDGET: 20, 158 SCREEN: 21, 159 PRINTERMARK: 22, 160 TRAPNET: 23, 161 WATERMARK: 24, 162 THREED: 25, 163 REDACT: 26 164}; 165const AnnotationReplyType = exports.AnnotationReplyType = { 166 GROUP: "Group", 167 REPLY: "R" 168}; 169const AnnotationFlag = exports.AnnotationFlag = { 170 INVISIBLE: 0x01, 171 HIDDEN: 0x02, 172 PRINT: 0x04, 173 NOZOOM: 0x08,
174 NOROTATE: 0x10, 175 NOVIEW: 0x20, 176 READONLY: 0x40, 177 LOCKED: 0x80, 178 TOGGLENOVIEW: 0x100, 179 LOCKEDCONTENTS: 0x200 180}; 181const AnnotationFieldFlag = exports.AnnotationFieldFlag = { 182 READONLY: 0x0000001, 183 REQUIRED: 0x0000002, 184 NOEXPORT: 0x0000004, 185 MULTILINE: 0x0001000, 186 PASSWORD: 0x0002000, 187 NOTOGGLETOOFF: 0x0004000, 188 RADIO: 0x0008000, 189 PUSHBUTTON: 0x0010000, 190 COMBO: 0x0020000, 191 EDIT: 0x0040000, 192 SORT: 0x0080000, 193 FILESELECT: 0x0100000, 194 MULTISELECT: 0x0200000, 195 DONOTSPELLCHECK: 0x0400000, 196 DONOTSCROLL: 0x0800000, 197 COMB: 0x1000000, 198 RICHTEXT: 0x2000000, 199 RADIOSINUNISON: 0x2000000, 200 COMMITONSELCHANGE: 0x4000000 201}; 202const AnnotationBorderStyleType = exports.AnnotationBorderStyleType = { 203 SOLID: 1, 204 DASHED: 2, 205 BEVELED: 3, 206 INSET: 4, 207 UNDERLINE: 5 208}; 209const AnnotationActionEventType = exports.AnnotationActionEventType = { 210 E: "Mouse Enter", 211 X: "Mouse Exit", 212 D: "Mouse Down", 213 U: "Mouse Up", 214 Fo: "Focus", 215 Bl: "Blur", 216 PO: "PageOpen", 217 PC: "PageClose", 218 PV: "PageVisible", 219 PI: "PageInvisible", 220 K: "Keystroke", 221 F: "Format", 222 V: "Validate", 223 C: "Calculate" 224}; 225const DocumentActionEventType = exports.DocumentActionEventType = { 226 WC: "WillClose", 227 WS: "WillSave", 228 DS: "DidSave", 229 WP: "WillPrint", 230 DP: "DidPrint" 231}; 232const PageActionEventType = exports.PageActionEventType = { 233 O: "PageOpen", 234 C: "PageClose" 235}; 236const VerbosityLevel = exports.VerbosityLevel = { 237 ERRORS: 0, 238 WARNINGS: 1, 239 INFOS: 5 240}; 241const CMapCompressionType = exports.CMapCompressionType = { 242 NONE: 0, 243 BINARY: 1 244}; 245const OPS = exports.OPS = { 246 dependency: 1, 247 setLineWidth: 2, 248 setLineCap: 3, 249 setLineJoin: 4, 250 setMiterLimit: 5, 251 setDash: 6, 252 setRenderingIntent: 7, 253 setFlatness: 8, 254 setGState: 9, 255 save: 10, 256 restore: 11, 257 transform: 12, 258 moveTo: 13, 259 lineTo: 14, 260 curveTo: 15, 261 curveTo2: 16,
262 curveTo3: 17, 263 closePath: 18, 264 rectangle: 19, 265 stroke: 20, 266 closeStroke: 21, 267 fill: 22, 268 eoFill: 23, 269 fillStroke: 24, 270 eoFillStroke: 25, 271 closeFillStroke: 26, 272 closeEOFillStroke: 27, 273 endPath: 28, 274 clip: 29, 275 eoClip: 30, 276 beginText: 31, 277 endText: 32, 278 setCharSpacing: 33, 279 setWordSpacing: 34, 280 setHScale: 35, 281 setLeading: 36, 282 setFont: 37, 283 setTextRenderingMode: 38, 284 setTextRise: 39, 285 moveText: 40, 286 setLeadingMoveText: 41, 287 setTextMatrix: 42, 288 nextLine: 43, 289 showText: 44, 290 showSpacedText: 45, 291 nextLineShowText: 46, 292 nextLineSetSpacingShowText: 47, 293 setCharWidth: 48, 294 setCharWidthAndBounds: 49, 295 setStrokeColorSpace: 50, 296 setFillColorSpace: 51, 297 setStrokeColor: 52, 298 setStrokeColorN: 53, 299 setFillColor: 54, 300 setFillColorN: 55, 301 setStrokeGray: 56, 302 setFillGray: 57, 303 setStrokeRGBColor: 58, 304 setFillRGBColor: 59, 305 setStrokeCMYKColor: 60, 306 setFillCMYKColor: 61, 307 shadingFill: 62, 308 beginInlineImage: 63, 309 beginImageData: 64, 310 endInlineImage: 65, 311 paintXObject: 66, 312 markPoint: 67, 313 markPointProps: 68, 314 beginMarkedContent: 69, 315 beginMarkedContentProps: 70, 316 endMarkedContent: 71, 317 beginCompat: 72, 318 endCompat: 73, 319 paintFormXObjectBegin: 74, 320 paintFormXObjectEnd: 75, 321 beginGroup: 76, 322 endGroup: 77, 323 beginAnnotation: 80, 324 endAnnotation: 81, 325 paintImageMaskXObject: 83, 326 paintImageMaskXObjectGroup: 84, 327 paintImageXObject: 85, 328 paintInlineImageXObject: 86, 329 paintInlineImageXObjectGroup: 87, 330 paintImageXObjectRepeat: 88, 331 paintImageMaskXObjectRepeat: 89, 332 paintSolidColorImageMask: 90, 333 constructPath: 91 334}; 335const PasswordResponses = exports.PasswordResponses = { 336 NEED_PASSWORD: 1, 337 INCORRECT_PASSWORD: 2 338}; 339let verbosity = VerbosityLevel.WARNINGS; 340function setVerbosityLevel(level) { 341 if (Number.isInteger(level)) { 342 verbosity = level; 343 } 344} 345function getVerbosityLevel() { 346 return verbosity; 347} 348function info(msg) { 349 if (verbosity >= VerbosityLevel.INFOS) { 350 if (typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope) { 351 console.log(`Info: ${msg}`); 352 } else if (Window && globalThis.ngxConsole) { 353 globalThis.ngxConsole.log(`Info: ${msg}`); 354 } else { 355 console.log(`Info: ${msg}`); 356 } 357 } 358} 359function warn(msg) { 360 if (verbosity >= VerbosityLevel.WARNINGS) { 361 if (typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope) { 362 console.log(`Warning: ${msg}`); 363 } else if (Window && globalThis.ngxConsole) { 364 globalThis.ngxConsole.log(`Warning: ${msg}`); 365 } else { 366 console.log(`Warning: ${msg}`); 367 } 368 } 369} 370function unreachable(msg) { 371 throw new Error(msg); 372} 373function assert(cond, msg) { 374 if (!cond) { 375 unreachable(msg); 376 } 377} 378function _isValidProtocol(url) { 379 switch (url?.protocol) { 380 case "http:": 381 case "https:": 382 case "ftp:": 383 case "mailto:": 384 case "tel:": 385 case "capacitor": 386 return true; 387 default: 388 return false; 389 } 390} 391function createValidAbsoluteUrl(url, baseUrl = null, options = null) { 392 if (!url) { 393 return null; 394 } 395 try { 396 if (options && typeof url === "string") { 397 if (options.addDefaultProtocol && url.startsWith("www.")) { 398 const dots = url.match(/\./g); 399 if (dots?.length >= 2) { 400 url = `http://${url}`; 401 } 402 } 403 if (options.tryConvertEncoding) { 404 try { 405 url = stringToUTF8String(url); 406 } catch {} 407 } 408 } 409 const absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url); 410 if (_isValidProtocol(absoluteUrl)) { 411 return absoluteUrl; 412 } 413 } catch {} 414 return null; 415} 416function shadow(obj, prop, value, nonSerializable = false) { 417 Object.defineProperty(obj, prop, { 418 value, 419 enumerable: !nonSerializable, 420 configurable: true, 421 writable: false 422 }); 423 return value; 424} 425const BaseException = exports.BaseException = function BaseExceptionClosure() { 426 function BaseException(message, name) { 427 if (this.constructor === BaseException) { 428 unreachable("Cannot initialize BaseException."); 429 } 430 this.message = message; 431 this.name = name; 432 } 433 BaseException.prototype = new Error(); 434 BaseException.constructor = BaseException; 435 return BaseException; 436}(); 437class PasswordException extends BaseException { 438 constructor(msg, code) { 439 super(msg, "PasswordException"); 440 this.code = code; 441 } 442} 443exports.PasswordException = PasswordException; 444class UnknownErrorException extends BaseException { 445 constructor(msg, details) { 446 super(msg, "UnknownErrorException"); 447 this.details = details; 448 } 449} 450exports.UnknownErrorException = UnknownErrorException; 451class InvalidPDFException extends BaseException { 452 constructor(msg) { 453 super(msg, "InvalidPDFException"); 454 } 455} 456exports.InvalidPDFException = InvalidPDFException; 457class MissingPDFException extends BaseException { 458 constructor(msg) { 459 super(msg, "MissingPDFException"); 460 } 461} 462exports.MissingPDFException = MissingPDFException; 463class UnexpectedResponseException extends BaseException { 464 constructor(msg, status) { 465 super(msg, "UnexpectedResponseException"); 466 this.status = status; 467 } 468} 469exports.UnexpectedResponseException = UnexpectedResponseException; 470class FormatError extends BaseException { 471 constructor(msg) { 472 super(msg, "FormatError"); 473 } 474} 475exports.FormatError = FormatError; 476class AbortException extends BaseException { 477 constructor(msg) { 478 super(msg, "AbortException"); 479 } 480} 481exports.AbortException = AbortException; 482function bytesToString(bytes) { 483 if (typeof bytes !== "object" || bytes?.length === undefined) { 484 unreachable("Invalid argument for bytesToString"); 485 } 486 const length = bytes.length; 487 const MAX_ARGUMENT_COUNT = 8192; 488 if (length < MAX_ARGUMENT_COUNT) { 489 return String.fromCharCode.apply(null, bytes); 490 } 491 const strBuf = []; 492 for (let i = 0; i < length; i += MAX_ARGUMENT_COUNT) { 493 const chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length); 494 const chunk = bytes.subarray(i, chunkEnd); 495 strBuf.push(String.fromCharCode.apply(null, chunk)); 496 } 497 return strBuf.join(""); 498} 499function stringToBytes(str) { 500 if (typeof str !== "string") { 501 unreachable("Invalid argument for stringToBytes"); 502 } 503 const length = str.length; 504 const bytes = new Uint8Array(length); 505 for (let i = 0; i < length; ++i) { 506 bytes[i] = str.charCodeAt(i) & 0xff;
vendor: 8,096 bytes, lines 507-742
507 } 508 return bytes; 509} 510function string32(value) { 511 return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff); 512} 513function objectSize(obj) { 514 return Object.keys(obj).length; 515} 516function objectFromMap(map) { 517 const obj = Object.create(null); 518 for (const [key, value] of map) { 519 obj[key] = value; 520 } 521 return obj; 522} 523function isLittleEndian() { 524 const buffer8 = new Uint8Array(4); 525 buffer8[0] = 1; 526 const view32 = new Uint32Array(buffer8.buffer, 0, 1); 527 return view32[0] === 1; 528} 529function isEvalSupported() { 530 try { 531 new Function(""); 532 return true; 533 } catch { 534 return false; 535 } 536} 537class FeatureTest { 538 static get isLittleEndian() { 539 return shadow(this, "isLittleEndian", isLittleEndian()); 540 } 541 static get isEvalSupported() { 542 return shadow(this, "isEvalSupported", isEvalSupported()); 543 } 544 static get isOffscreenCanvasSupported() { 545 return shadow(this, "isOffscreenCanvasSupported", typeof OffscreenCanvas !== "undefined"); 546 } 547 static get platform() { 548 if (typeof navigator === "undefined") { 549 return shadow(this, "platform", { 550 isWin: false, 551 isMac: false 552 }); 553 } 554 return shadow(this, "platform", { 555 isWin: navigator.platform.includes("Win"), 556 isMac: navigator.platform.includes("Mac") 557 }); 558 } 559 static get isCSSRoundSupported() { 560 return shadow(this, "isCSSRoundSupported", globalThis.CSS?.supports?.("width: round(1.5px, 1px)")); 561 } 562} 563exports.FeatureTest = FeatureTest; 564const hexNumbers = [...Array(256).keys()].map(n => n.toString(16).padStart(2, "0")); 565class Util { 566 static makeHexColor(r, g, b) { 567 return `#${hexNumbers[r]}${hexNumbers[g]}${hexNumbers[b]}`; 568 } 569 static scaleMinMax(transform, minMax) { 570 let temp; 571 if (transform[0]) { 572 if (transform[0] < 0) { 573 temp = minMax[0]; 574 minMax[0] = minMax[1]; 575 minMax[1] = temp; 576 } 577 minMax[0] *= transform[0]; 578 minMax[1] *= transform[0]; 579 if (transform[3] < 0) { 580 temp = minMax[2]; 581 minMax[2] = minMax[3]; 582 minMax[3] = temp; 583 } 584 minMax[2] *= transform[3]; 585 minMax[3] *= transform[3]; 586 } else { 587 temp = minMax[0]; 588 minMax[0] = minMax[2]; 589 minMax[2] = temp; 590 temp = minMax[1]; 591 minMax[1] = minMax[3]; 592 minMax[3] = temp; 593 if (transform[1] < 0) { 594 temp = minMax[2]; 595 minMax[2] = minMax[3]; 596 minMax[3] = temp; 597 } 598 minMax[2] *= transform[1]; 599 minMax[3] *= transform[1]; 600 if (transform[2] < 0) { 601 temp = minMax[0]; 602 minMax[0] = minMax[1]; 603 minMax[1] = temp; 604 } 605 minMax[0] *= transform[2]; 606 minMax[1] *= transform[2]; 607 } 608 minMax[0] += transform[4]; 609 minMax[1] += transform[4]; 610 minMax[2] += transform[5]; 611 minMax[3] += transform[5]; 612 } 613 static transform(m1, m2) { 614 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]]; 615 } 616 static applyTransform(p, m) { 617 const xt = p[0] * m[0] + p[1] * m[2] + m[4]; 618 const yt = p[0] * m[1] + p[1] * m[3] + m[5]; 619 return [xt, yt]; 620 } 621 static applyInverseTransform(p, m) { 622 const d = m[0] * m[3] - m[1] * m[2]; 623 const xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d; 624 const yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d; 625 return [xt, yt]; 626 } 627 static getAxialAlignedBoundingBox(r, m) { 628 const p1 = this.applyTransform(r, m); 629 const p2 = this.applyTransform(r.slice(2, 4), m); 630 const p3 = this.applyTransform([r[0], r[3]], m); 631 const p4 = this.applyTransform([r[2], r[1]], m); 632 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])]; 633 } 634 static inverseTransform(m) { 635 const d = m[0] * m[3] - m[1] * m[2]; 636 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]; 637 } 638 static singularValueDecompose2dScale(m) { 639 const transpose = [m[0], m[2], m[1], m[3]]; 640 const a = m[0] * transpose[0] + m[1] * transpose[2]; 641 const b = m[0] * transpose[1] + m[1] * transpose[3]; 642 const c = m[2] * transpose[0] + m[3] * transpose[2]; 643 const d = m[2] * transpose[1] + m[3] * transpose[3]; 644 const first = (a + d) / 2; 645 const second = Math.sqrt((a + d) ** 2 - 4 * (a * d - c * b)) / 2; 646 const sx = first + second || 1; 647 const sy = first - second || 1; 648 return [Math.sqrt(sx), Math.sqrt(sy)]; 649 } 650 static normalizeRect(rect) { 651 const r = rect.slice(0); 652 if (rect[0] > rect[2]) { 653 r[0] = rect[2]; 654 r[2] = rect[0]; 655 } 656 if (rect[1] > rect[3]) { 657 r[1] = rect[3]; 658 r[3] = rect[1]; 659 } 660 return r; 661 } 662 static intersect(rect1, rect2) { 663 const xLow = Math.max(Math.min(rect1[0], rect1[2]), Math.min(rect2[0], rect2[2])); 664 const xHigh = Math.min(Math.max(rect1[0], rect1[2]), Math.max(rect2[0], rect2[2])); 665 if (xLow > xHigh) { 666 return null; 667 } 668 const yLow = Math.max(Math.min(rect1[1], rect1[3]), Math.min(rect2[1], rect2[3])); 669 const yHigh = Math.min(Math.max(rect1[1], rect1[3]), Math.max(rect2[1], rect2[3])); 670 if (yLow > yHigh) { 671 return null; 672 } 673 return [xLow, yLow, xHigh, yHigh]; 674 } 675 static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3) { 676 const tvalues = [], 677 bounds = [[], []]; 678 let a, b, c, t, t1, t2, b2ac, sqrtb2ac; 679 for (let i = 0; i < 2; ++i) { 680 if (i === 0) { 681 b = 6 * x0 - 12 * x1 + 6 * x2; 682 a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; 683 c = 3 * x1 - 3 * x0; 684 } else { 685 b = 6 * y0 - 12 * y1 + 6 * y2; 686 a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; 687 c = 3 * y1 - 3 * y0; 688 } 689 if (Math.abs(a) < 1e-12) { 690 if (Math.abs(b) < 1e-12) { 691 continue; 692 } 693 t = -c / b; 694 if (0 < t && t < 1) { 695 tvalues.push(t); 696 } 697 continue; 698 } 699 b2ac = b * b - 4 * c * a; 700 sqrtb2ac = Math.sqrt(b2ac); 701 if (b2ac < 0) { 702 continue; 703 } 704 t1 = (-b + sqrtb2ac) / (2 * a); 705 if (0 < t1 && t1 < 1) { 706 tvalues.push(t1); 707 } 708 t2 = (-b - sqrtb2ac) / (2 * a); 709 if (0 < t2 && t2 < 1) { 710 tvalues.push(t2); 711 } 712 } 713 let j = tvalues.length, 714 mt; 715 const jlen = j; 716 while (j--) { 717 t = tvalues[j]; 718 mt = 1 - t; 719 bounds[0][j] = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3; 720 bounds[1][j] = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3; 721 } 722 bounds[0][jlen] = x0; 723 bounds[1][jlen] = y0; 724 bounds[0][jlen + 1] = x3; 725 bounds[1][jlen + 1] = y3; 726 bounds[0].length = bounds[1].length = jlen + 2; 727 return [Math.min(...bounds[0]), Math.min(...bounds[1]), Math.max(...bounds[0]), Math.max(...bounds[1])]; 728 } 729} 730exports.Util = Util; 731const 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]; 732function stringToPDFString(str) { 733 if (str[0] >= "\xEF") { 734 let encoding; 735 if (str[0] === "\xFE" && str[1] === "\xFF") { 736 encoding = "utf-16be"; 737 } else if (str[0] === "\xFF" && str[1] === "\xFE") { 738 encoding = "utf-16le"; 739 } else if (str[0] === "\xEF" && str[1] === "\xBB" && str[2] === "\xBF") { 740 encoding = "utf-8"; 741 } 742 if (encoding) {
743 try { 744 const decoder = new TextDecoder(encoding, { 745 fatal: true 746 }); 747 const buffer = stringToBytes(str); 748 return decoder.decode(buffer); 749 } catch (ex) { 750 warn(`stringToPDFString: "${ex}".`); 751 } 752 } 753 } 754 const strBuf = []; 755 for (let i = 0, ii = str.length; i < ii; i++) { 756 const code = PDFStringTranslateTable[str.charCodeAt(i)]; 757 strBuf.push(code ? String.fromCharCode(code) : str.charAt(i)); 758 } 759 return strBuf.join(""); 760} 761function stringToUTF8String(str) { 762 return decodeURIComponent(escape(str)); 763} 764function utf8StringToString(str) { 765 return unescape(encodeURIComponent(str)); 766} 767function isArrayBuffer(v) { 768 return typeof v === "object" && v?.byteLength !== undefined; 769} 770function isArrayEqual(arr1, arr2) { 771 if (arr1.length !== arr2.length) { 772 return false; 773 } 774 for (let i = 0, ii = arr1.length; i < ii; i++) { 775 if (arr1[i] !== arr2[i]) { 776 return false; 777 } 778 } 779 return true; 780} 781function getModificationDate(date = new Date()) { 782 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")]; 783 return buffer.join(""); 784} 785class PromiseCapability { 786 #settled = false; 787 constructor() { 788 this.promise = new Promise((resolve, reject) => { 789 this.resolve = data => { 790 this.#settled = true; 791 resolve(data); 792 }; 793 this.reject = reason => { 794 this.#settled = true; 795 reject(reason); 796 }; 797 }); 798 } 799 get settled() { 800 return this.#settled; 801 } 802} 803exports.PromiseCapability = PromiseCapability; 804let NormalizeRegex = null; 805let NormalizationMap = null; 806function normalizeUnicode(str) { 807 if (!NormalizeRegex) { 808 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; 809 NormalizationMap = new Map([["ſt", "ſt"]]); 810 } 811 return str.replaceAll(NormalizeRegex, (_, p1, p2) => { 812 return p1 ? p1.normalize("NFKC") : NormalizationMap.get(p2); 813 }); 814} 815function getUuid() { 816 if (typeof crypto !== "undefined" && typeof crypto?.randomUUID === "function") { 817 return crypto.randomUUID(); 818 } 819 const buf = new Uint8Array(32); 820 if (typeof crypto !== "undefined" && typeof crypto?.getRandomValues === "function") { 821 crypto.getRandomValues(buf); 822 } else { 823 for (let i = 0; i < 32; i++) { 824 buf[i] = Math.floor(Math.random() * 255); 825 } 826 } 827 return bytesToString(buf); 828} 829 830/***/ }), 831/* 2 */ 832/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 833 834 835 836Object.defineProperty(exports, "__esModule", ({ 837 value: true 838})); 839exports.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; 840Object.defineProperty(exports, "SVGGraphics", ({ 841 enumerable: true, 842 get: function () { 843 return _displaySvg.SVGGraphics; 844 } 845})); 846exports.build = void 0; 847exports.getDocument = getDocument; 848exports.version = void 0; 849var _util = __w_pdfjs_require__(1); 850var _annotation_storage = __w_pdfjs_require__(3); 851var _display_utils = __w_pdfjs_require__(6); 852var _font_loader = __w_pdfjs_require__(9); 853var _displayNode_utils = __w_pdfjs_require__(10); 854var _canvas = __w_pdfjs_require__(11); 855var _worker_options = __w_pdfjs_require__(14); 856var _message_handler = __w_pdfjs_require__(15); 857var _metadata = __w_pdfjs_require__(16); 858var _optional_content_config = __w_pdfjs_require__(17); 859var _transport_stream = __w_pdfjs_require__(18); 860var _displayFetch_stream = __w_pdfjs_require__(19); 861var _displayNetwork = __w_pdfjs_require__(22); 862var _displayNode_stream = __w_pdfjs_require__(23); 863var _displaySvg = __w_pdfjs_require__(24); 864var _xfa_text = __w_pdfjs_require__(25); 865const DEFAULT_RANGE_CHUNK_SIZE = 65536; 866const RENDERING_CANCELLED_TIMEOUT = 100; 867const DELAYED_CLEANUP_TIMEOUT = 5000; 868const ServiceWorkerOptions = { 869 showUnverifiedSignatures: false 870}; 871window.ServiceWorkerOptions = ServiceWorkerOptions;
872const DefaultCanvasFactory = exports.DefaultCanvasFactory = _util.isNodeJS ? _displayNode_utils.NodeCanvasFactory : _display_utils.DOMCanvasFactory; 873const DefaultCMapReaderFactory = exports.DefaultCMapReaderFactory = _util.isNodeJS ? _displayNode_utils.NodeCMapReaderFactory : _display_utils.DOMCMapReaderFactory; 874const DefaultFilterFactory = exports.DefaultFilterFactory = _util.isNodeJS ? _displayNode_utils.NodeFilterFactory : _display_utils.DOMFilterFactory; 875const DefaultStandardFontDataFactory = exports.DefaultStandardFontDataFactory = _util.isNodeJS ? _displayNode_utils.NodeStandardFontDataFactory : _display_utils.DOMStandardFontDataFactory; 876function getDocument(src) { 877 if (typeof src === "string" || src instanceof URL) { 878 src = { 879 url: src 880 }; 881 } else if ((0, _util.isArrayBuffer)(src)) { 882 src = { 883 data: src 884 }; 885 } 886 if (typeof src !== "object") { 887 throw new Error("Invalid parameter in getDocument, need parameter object."); 888 } 889 if (!src.url && !src.data && !src.range) { 890 throw new Error("Invalid parameter object: need either .data, .range or .url"); 891 } 892 const task = new PDFDocumentLoadingTask(); 893 const { 894 docId 895 } = task; 896 const url = src.url ? getUrlProp(src.url, src.baseHref) : null; 897 const data = src.data ? getDataProp(src.data) : null; 898 const httpHeaders = src.httpHeaders || null; 899 const withCredentials = src.withCredentials === true; 900 const password = src.password ?? null; 901 const rangeTransport = src.range instanceof PDFDataRangeTransport ? src.range : null; 902 const rangeChunkSize = Number.isInteger(src.rangeChunkSize) && src.rangeChunkSize > 0 ? src.rangeChunkSize : DEFAULT_RANGE_CHUNK_SIZE; 903 let worker = src.worker instanceof PDFWorker ? src.worker : null; 904 const verbosity = src.verbosity; 905 const docBaseUrl = typeof src.docBaseUrl === "string" && !(0, _display_utils.isDataScheme)(src.docBaseUrl) ? src.docBaseUrl : null; 906 const cMapUrl = typeof src.cMapUrl === "function" ? src.cMapUrl() : typeof src.cMapUrl === "string" ? src.cMapUrl : null; 907 const cMapPacked = src.cMapPacked !== false; 908 const CMapReaderFactory = src.CMapReaderFactory || DefaultCMapReaderFactory; 909 const standardFontDataUrl = typeof src.standardFontDataUrl === "function" ? src.standardFontDataUrl() : typeof src.standardFontDataUrl === "string" ? src.standardFontDataUrl : null; 910 const StandardFontDataFactory = src.StandardFontDataFactory || DefaultStandardFontDataFactory; 911 const ignoreErrors = src.stopAtErrors !== true; 912 const maxImageSize = Number.isInteger(src.maxImageSize) && src.maxImageSize > -1 ? src.maxImageSize : -1; 913 const isEvalSupported = src.isEvalSupported !== false; 914 const isOffscreenCanvasSupported = typeof src.isOffscreenCanvasSupported === "boolean" ? src.isOffscreenCanvasSupported : !_util.isNodeJS; 915 const canvasMaxAreaInBytes = Number.isInteger(src.canvasMaxAreaInBytes) ? src.canvasMaxAreaInBytes : -1; 916 const disableFontFace = typeof src.disableFontFace === "boolean" ? src.disableFontFace : _util.isNodeJS; 917 const fontExtraProperties = src.fontExtraProperties === true; 918 const enableXfa = src.enableXfa === true; 919 const ownerDocument = src.ownerDocument || globalThis.document; 920 const disableRange = src.disableRange === true; 921 const disableStream = src.disableStream === true; 922 const disableAutoFetch = src.disableAutoFetch === true; 923 const pdfBug = src.pdfBug === true; 924 const length = rangeTransport ? rangeTransport.length : src.length ?? NaN; 925 const useSystemFonts = typeof src.useSystemFonts === "boolean" ? src.useSystemFonts : !_util.isNodeJS && !disableFontFace; 926 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); 927 const canvasFactory = src.canvasFactory || new DefaultCanvasFactory({ 928 ownerDocument 929 }); 930 const filterFactory = src.filterFactory || new DefaultFilterFactory({ 931 docId, 932 ownerDocument 933 }); 934 const styleElement = null; 935 (0, _util.setVerbosityLevel)(verbosity); 936 const transportFactory = { 937 canvasFactory, 938 filterFactory 939 }; 940 if (!useWorkerFetch) { 941 transportFactory.cMapReaderFactory = new CMapReaderFactory({ 942 baseUrl: cMapUrl, 943 isCompressed: cMapPacked 944 }); 945 transportFactory.standardFontDataFactory = new StandardFontDataFactory({ 946 baseUrl: standardFontDataUrl 947 }); 948 } 949 if (!worker) { 950 const workerParams = { 951 verbosity, 952 port: _worker_options.GlobalWorkerOptions.workerPort 953 }; 954 worker = workerParams.port ? PDFWorker.fromPort(workerParams) : new PDFWorker(workerParams); 955 task._worker = worker; 956 } 957 const fetchDocParams = { 958 docId, 959 apiVersion: '3.10.560', 960 data, 961 password, 962 disableAutoFetch, 963 rangeChunkSize, 964 length, 965 docBaseUrl, 966 enableXfa, 967 evaluatorOptions: { 968 maxImageSize, 969 disableFontFace, 970 ignoreErrors, 971 isEvalSupported, 972 isOffscreenCanvasSupported, 973 canvasMaxAreaInBytes, 974 fontExtraProperties, 975 useSystemFonts, 976 cMapUrl: useWorkerFetch ? cMapUrl : null, 977 standardFontDataUrl: useWorkerFetch ? standardFontDataUrl : null 978 } 979 }; 980 const transportParams = { 981 ignoreErrors, 982 isEvalSupported, 983 disableFontFace, 984 fontExtraProperties, 985 enableXfa, 986 ownerDocument, 987 disableAutoFetch, 988 pdfBug, 989 styleElement 990 }; 991 worker.promise.then(function () { 992 if (task.destroyed) { 993 throw new Error("Loading aborted"); 994 } 995 const workerIdPromise = _fetchDocument(worker, fetchDocParams); 996 const networkStreamPromise = new Promise(function (resolve) { 997 let networkStream; 998 if (rangeTransport) { 999 networkStream = new _transport_stream.PDFDataTransportStream({ 1000 length, 1001 initialData: rangeTransport.initialData, 1002 progressiveDone: rangeTransport.progressiveDone, 1003 contentDispositionFilename: rangeTransport.contentDispositionFilename, 1004 disableRange, 1005 disableStream 1006 }, rangeTransport); 1007 } else if (!data) { 1008 const createPDFNetworkStream = params => { 1009 if (_util.isNodeJS) { 1010 return new _displayNode_stream.PDFNodeStream(params); 1011 } 1012 return (0, _display_utils.isValidFetchUrl)(params.url) ? new _displayFetch_stream.PDFFetchStream(params) : new _displayNetwork.PDFNetworkStream(params); 1013 }; 1014 networkStream = createPDFNetworkStream({ 1015 url, 1016 length, 1017 httpHeaders, 1018 withCredentials, 1019 rangeChunkSize, 1020 disableRange, 1021 disableStream 1022 }); 1023 } 1024 resolve(networkStream); 1025 }); 1026 return Promise.all([workerIdPromise, networkStreamPromise]).then(function ([workerId, networkStream]) { 1027 if (task.destroyed) { 1028 throw new Error("Loading aborted"); 1029 } 1030 const messageHandler = new _message_handler.MessageHandler(docId, workerId, worker.port); 1031 const transport = new WorkerTransport(messageHandler, task, networkStream, transportParams, transportFactory); 1032 task._transport = transport; 1033 messageHandler.send("showUnverifiedSignatures", window.ServiceWorkerOptions.showUnverifiedSignatures); 1034 messageHandler.send("Ready", null); 1035 }); 1036 }).catch(task._capability.reject); 1037 return task; 1038} 1039async function _fetchDocument(worker, source) { 1040 if (worker.destroyed) { 1041 throw new Error("Worker was destroyed"); 1042 }
1043 const workerId = await worker.messageHandler.sendWithPromise("GetDocRequest", source, source.data ? [source.data.buffer] : null); 1044 if (worker.destroyed) { 1045 throw new Error("Worker was destroyed"); 1046 } 1047 return workerId; 1048} 1049function getUrlProp(val, baseHref) { 1050 if (val instanceof URL) { 1051 return val.href; 1052 } 1053 try { 1054 if (baseHref) { 1055 return new URL(val, window.location.origin + baseHref).href; 1056 } else { 1057 return new URL(val, window.location).href; 1058 } 1059 } catch (ex) { 1060 if (_util.isNodeJS && typeof val === "string") { 1061 return val; 1062 } 1063 } 1064 throw new Error("Invalid PDF url data: " + "either string or URL-object is expected in the url property."); 1065} 1066function getDataProp(val) { 1067 if (_util.isNodeJS && typeof Buffer !== "undefined" && val instanceof Buffer) { 1068 throw new Error("Please provide binary data as `Uint8Array`, rather than `Buffer`."); 1069 } 1070 if (val instanceof Uint8Array && val.byteLength === val.buffer.byteLength) { 1071 return val; 1072 } 1073 if (typeof val === "string") { 1074 return (0, _util.stringToBytes)(val); 1075 } 1076 if (typeof val === "object" && !isNaN(val?.length) || (0, _util.isArrayBuffer)(val)) { 1077 return new Uint8Array(val); 1078 } 1079 throw new Error("Invalid PDF binary data: either TypedArray, " + "string, or array-like object is expected in the data property."); 1080} 1081class PDFDocumentLoadingTask { 1082 static #docId = 0; 1083 constructor() { 1084 this._capability = new _util.PromiseCapability(); 1085 this._transport = null; 1086 this._worker = null; 1087 this.docId = `d${PDFDocumentLoadingTask.#docId++}`; 1088 this.destroyed = false; 1089 this.onPassword = null; 1090 this.onProgress = null; 1091 } 1092 get promise() { 1093 return this._capability.promise; 1094 } 1095 async destroy() { 1096 this.destroyed = true; 1097 try { 1098 if (this._worker?.port) { 1099 this._worker._pendingDestroy = true; 1100 } 1101 await this._transport?.destroy(); 1102 } catch (ex) { 1103 if (this._worker?.port) { 1104 delete this._worker._pendingDestroy; 1105 } 1106 throw ex; 1107 } 1108 this._transport = null; 1109 if (this._worker) { 1110 this._worker.destroy(); 1111 this._worker = null; 1112 } 1113 } 1114} 1115exports.PDFDocumentLoadingTask = PDFDocumentLoadingTask; 1116class PDFDataRangeTransport { 1117 constructor(length, initialData, progressiveDone = false, contentDispositionFilename = null) { 1118 this.length = length; 1119 this.initialData = initialData; 1120 this.progressiveDone = progressiveDone; 1121 this.contentDispositionFilename = contentDispositionFilename; 1122 this._rangeListeners = []; 1123 this._progressListeners = []; 1124 this._progressiveReadListeners = []; 1125 this._progressiveDoneListeners = []; 1126 this._readyCapability = new _util.PromiseCapability(); 1127 } 1128 addRangeListener(listener) { 1129 this._rangeListeners.push(listener); 1130 } 1131 addProgressListener(listener) { 1132 this._progressListeners.push(listener); 1133 } 1134 addProgressiveReadListener(listener) { 1135 this._progressiveReadListeners.push(listener); 1136 } 1137 addProgressiveDoneListener(listener) { 1138 this._progressiveDoneListeners.push(listener); 1139 } 1140 onDataRange(begin, chunk) { 1141 for (const listener of this._rangeListeners) { 1142 listener(begin, chunk); 1143 } 1144 } 1145 onDataProgress(loaded, total) { 1146 this._readyCapability.promise.then(() => { 1147 for (const listener of this._progressListeners) { 1148 listener(loaded, total); 1149 } 1150 }); 1151 } 1152 onDataProgressiveRead(chunk) { 1153 this._readyCapability.promise.then(() => { 1154 for (const listener of this._progressiveReadListeners) { 1155 listener(chunk); 1156 } 1157 }); 1158 } 1159 onDataProgressiveDone() { 1160 this._readyCapability.promise.then(() => { 1161 for (const listener of this._progressiveDoneListeners) { 1162 listener(); 1163 } 1164 }); 1165 } 1166 transportReady() { 1167 this._readyCapability.resolve(); 1168 } 1169 requestDataRange(begin, end) { 1170 (0, _util.unreachable)("Abstract method PDFDataRangeTransport.requestDataRange"); 1171 } 1172 abort() {} 1173} 1174exports.PDFDataRangeTransport = PDFDataRangeTransport; 1175class PDFDocumentProxy { 1176 constructor(pdfInfo, transport) { 1177 this._pdfInfo = pdfInfo; 1178 this._transport = transport; 1179 Object.defineProperty(this, "getJavaScript", { 1180 value: () => { 1181 (0, _display_utils.deprecated)("`PDFDocumentProxy.getJavaScript`, " + "please use `PDFDocumentProxy.getJSActions` instead."); 1182 return this.getJSActions().then(js => { 1183 if (!js) { 1184 return js; 1185 } 1186 const jsArr = []; 1187 for (const name in js) { 1188 jsArr.push(...js[name]); 1189 } 1190 return jsArr; 1191 }); 1192 } 1193 }); 1194 } 1195 get annotationStorage() { 1196 return this._transport.annotationStorage; 1197 } 1198 get filterFactory() { 1199 return this._transport.filterFactory; 1200 } 1201 get numPages() { 1202 return this._pdfInfo.numPages; 1203 } 1204 get fingerprints() { 1205 return this._pdfInfo.fingerprints; 1206 } 1207 get isPureXfa() { 1208 return (0, _util.shadow)(this, "isPureXfa", !!this._transport._htmlForXfa); 1209 } 1210 get allXfaHtml() { 1211 return this._transport._htmlForXfa; 1212 } 1213 getPage(pageNumber) { 1214 return this._transport.getPage(pageNumber); 1215 } 1216 getPageIndex(ref) { 1217 return this._transport.getPageIndex(ref); 1218 } 1219 getDestinations() { 1220 return this._transport.getDestinations(); 1221 } 1222 getDestination(id) { 1223 return this._transport.getDestination(id); 1224 } 1225 getPageLabels() { 1226 return this._transport.getPageLabels(); 1227 } 1228 getPageLayout() { 1229 return this._transport.getPageLayout(); 1230 } 1231 getPageMode() { 1232 return this._transport.getPageMode(); 1233 } 1234 getViewerPreferences() { 1235 return this._transport.getViewerPreferences(); 1236 } 1237 getOpenAction() { 1238 return this._transport.getOpenAction(); 1239 } 1240 getAttachments() { 1241 return this._transport.getAttachments(); 1242 } 1243 getJSActions() { 1244 return this._transport.getDocJSActions(); 1245 } 1246 getOutline() { 1247 return this._transport.getOutline(); 1248 } 1249 getOptionalContentConfig() { 1250 return this._transport.getOptionalContentConfig(); 1251 } 1252 getPermissions() { 1253 return this._transport.getPermissions(); 1254 } 1255 getMetadata() { 1256 return this._transport.getMetadata(); 1257 } 1258 getMarkInfo() { 1259 return this._transport.getMarkInfo(); 1260 } 1261 getData() { 1262 return this._transport.getData(); 1263 } 1264 saveDocument() { 1265 return this._transport.saveDocument(); 1266 } 1267 getDownloadInfo() { 1268 return this._transport.downloadInfoCapability.promise; 1269 } 1270 cleanup(keepLoadedFonts = false) { 1271 return this._transport.startCleanup(keepLoadedFonts || this.isPureXfa); 1272 } 1273 destroy() { 1274 return this.loadingTask.destroy(); 1275 } 1276 get loadingParams() { 1277 return this._transport.loadingParams; 1278 } 1279 get loadingTask() { 1280 return this._transport.loadingTask; 1281 } 1282 getFieldObjects() { 1283 return this._transport.getFieldObjects(); 1284 } 1285 hasJSActions() { 1286 return this._transport.hasJSActions(); 1287 } 1288 getCalculationOrderIds() { 1289 return this._transport.getCalculationOrderIds(); 1290 } 1291} 1292exports.PDFDocumentProxy = PDFDocumentProxy; 1293class PDFPageProxy { 1294 #delayedCleanupTimeout = null; 1295 #pendingCleanup = false;
1296 constructor(pageIndex, pageInfo, transport, pdfBug = false) { 1297 this._pageIndex = pageIndex; 1298 this._pageInfo = pageInfo; 1299 this._transport = transport; 1300 this._stats = pdfBug ? new _display_utils.StatTimer() : null; 1301 this._pdfBug = pdfBug; 1302 this.commonObjs = transport.commonObjs; 1303 this.objs = new PDFObjects(); 1304 this._maybeCleanupAfterRender = false; 1305 this._intentStates = new Map(); 1306 this.destroyed = false; 1307 } 1308 get pageNumber() { 1309 return this._pageIndex + 1; 1310 } 1311 get rotate() { 1312 return this._pageInfo.rotate; 1313 } 1314 get ref() { 1315 return this._pageInfo.ref; 1316 } 1317 get userUnit() { 1318 return this._pageInfo.userUnit; 1319 } 1320 get view() { 1321 return this._pageInfo.view; 1322 } 1323 getViewport({ 1324 scale, 1325 rotation = this.rotate, 1326 offsetX = 0, 1327 offsetY = 0, 1328 dontFlip = false 1329 } = {}) { 1330 return new _display_utils.PageViewport({ 1331 viewBox: this.view, 1332 scale, 1333 rotation, 1334 offsetX, 1335 offsetY, 1336 dontFlip 1337 }); 1338 } 1339 getAnnotations({ 1340 intent = "display" 1341 } = {}) { 1342 const intentArgs = this._transport.getRenderingIntent(intent); 1343 return this._transport.getAnnotations(this._pageIndex, intentArgs.renderingIntent); 1344 } 1345 getJSActions() { 1346 return this._transport.getPageJSActions(this._pageIndex); 1347 } 1348 get filterFactory() { 1349 return this._transport.filterFactory; 1350 } 1351 get isPureXfa() { 1352 return (0, _util.shadow)(this, "isPureXfa", !!this._transport._htmlForXfa); 1353 } 1354 async getXfa() { 1355 return this._transport._htmlForXfa?.children[this._pageIndex] || null; 1356 } 1357 render({ 1358 canvasContext, 1359 viewport, 1360 intent = "display", 1361 annotationMode = _util.AnnotationMode.ENABLE, 1362 transform = null, 1363 background = null, 1364 optionalContentConfigPromise = null, 1365 annotationCanvasMap = null, 1366 pageColors = null, 1367 printAnnotationStorage = null 1368 }) { 1369 this._stats?.time("Overall"); 1370 const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage); 1371 this.#pendingCleanup = false; 1372 this.#abortDelayedCleanup(); 1373 if (!optionalContentConfigPromise) { 1374 optionalContentConfigPromise = this._transport.getOptionalContentConfig(); 1375 } 1376 let intentState = this._intentStates.get(intentArgs.cacheKey); 1377 if (!intentState) { 1378 intentState = Object.create(null); 1379 this._intentStates.set(intentArgs.cacheKey, intentState); 1380 } 1381 if (intentState.streamReaderCancelTimeout) { 1382 clearTimeout(intentState.streamReaderCancelTimeout); 1383 intentState.streamReaderCancelTimeout = null; 1384 } 1385 const intentPrint = !!(intentArgs.renderingIntent & _util.RenderingIntentFlag.PRINT); 1386 if (!intentState.displayReadyCapability) { 1387 intentState.displayReadyCapability = new _util.PromiseCapability(); 1388 intentState.operatorList = { 1389 fnArray: [], 1390 argsArray: [], 1391 lastChunk: false, 1392 separateAnnots: null 1393 }; 1394 this._stats?.time("Page Request"); 1395 this._pumpOperatorList(intentArgs); 1396 } 1397 const complete = error => { 1398 intentState.renderTasks.delete(internalRenderTask); 1399 if (this._maybeCleanupAfterRender || intentPrint) { 1400 this.#pendingCleanup = true; 1401 } 1402 this.#tryCleanup(!intentPrint); 1403 if (error) { 1404 internalRenderTask.capability.reject(error); 1405 this._abortOperatorList({ 1406 intentState, 1407 reason: error instanceof Error ? error : new Error(error) 1408 }); 1409 } else { 1410 internalRenderTask.capability.resolve(); 1411 } 1412 this._stats?.timeEnd("Rendering"); 1413 this._stats?.timeEnd("Overall"); 1414 }; 1415 const internalRenderTask = new InternalRenderTask({ 1416 callback: complete, 1417 params: { 1418 canvasContext, 1419 viewport, 1420 transform, 1421 background 1422 }, 1423 objs: this.objs, 1424 commonObjs: this.commonObjs, 1425 annotationCanvasMap, 1426 operatorList: intentState.operatorList, 1427 pageIndex: this._pageIndex, 1428 canvasFactory: this._transport.canvasFactory, 1429 filterFactory: this._transport.filterFactory, 1430 useRequestAnimationFrame: !intentPrint, 1431 pdfBug: this._pdfBug, 1432 pageColors 1433 }); 1434 (intentState.renderTasks ||= new Set()).add(internalRenderTask); 1435 const renderTask = internalRenderTask.task; 1436 Promise.all([intentState.displayReadyCapability.promise, optionalContentConfigPromise]).then(([transparency, optionalContentConfig]) => { 1437 if (this.destroyed) { 1438 complete(); 1439 return; 1440 }
1441 this._stats?.time("Rendering"); 1442 internalRenderTask.initializeGraphics({ 1443 transparency, 1444 optionalContentConfig 1445 }); 1446 internalRenderTask.operatorListChanged(); 1447 }).catch(complete); 1448 return renderTask; 1449 } 1450 getOperatorList({ 1451 intent = "display", 1452 annotationMode = _util.AnnotationMode.ENABLE, 1453 printAnnotationStorage = null 1454 } = {}) { 1455 function operatorListChanged() { 1456 if (intentState.operatorList.lastChunk) { 1457 intentState.opListReadCapability.resolve(intentState.operatorList); 1458 intentState.renderTasks.delete(opListTask); 1459 } 1460 } 1461 const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage, true); 1462 let intentState = this._intentStates.get(intentArgs.cacheKey); 1463 if (!intentState) { 1464 intentState = Object.create(null); 1465 this._intentStates.set(intentArgs.cacheKey, intentState); 1466 } 1467 let opListTask; 1468 if (!intentState.opListReadCapability) { 1469 opListTask = Object.create(null); 1470 opListTask.operatorListChanged = operatorListChanged; 1471 intentState.opListReadCapability = new _util.PromiseCapability(); 1472 (intentState.renderTasks ||= new Set()).add(opListTask); 1473 intentState.operatorList = { 1474 fnArray: [], 1475 argsArray: [], 1476 lastChunk: false, 1477 separateAnnots: null 1478 }; 1479 this._stats?.time("Page Request"); 1480 this._pumpOperatorList(intentArgs); 1481 } 1482 return intentState.opListReadCapability.promise; 1483 } 1484 streamTextContent({ 1485 includeMarkedContent = false, 1486 disableNormalization = false 1487 } = {}) { 1488 const TEXT_CONTENT_CHUNK_SIZE = 100; 1489 return this._transport.messageHandler.sendWithStream("GetTextContent", { 1490 pageIndex: this._pageIndex, 1491 includeMarkedContent: includeMarkedContent === true, 1492 disableNormalization: disableNormalization === true 1493 }, { 1494 highWaterMark: TEXT_CONTENT_CHUNK_SIZE, 1495 size(textContent) { 1496 return textContent.items.length; 1497 } 1498 }); 1499 } 1500 getTextContent(params = {}) { 1501 if (this._transport._htmlForXfa) { 1502 return this.getXfa().then(xfa => { 1503 return _xfa_text.XfaText.textContent(xfa); 1504 }); 1505 } 1506 const readableStream = this.streamTextContent(params); 1507 return new Promise(function (resolve, reject) { 1508 function pump() { 1509 reader.read().then(function ({ 1510 value, 1511 done 1512 }) { 1513 if (done) { 1514 resolve(textContent); 1515 return; 1516 } 1517 Object.assign(textContent.styles, value.styles); 1518 textContent.items.push(...value.items); 1519 pump(); 1520 }, reject); 1521 } 1522 const reader = readableStream.getReader(); 1523 const textContent = { 1524 items: [], 1525 styles: Object.create(null) 1526 }; 1527 pump(); 1528 }); 1529 } 1530 getStructTree() { 1531 return this._transport.getStructTree(this._pageIndex); 1532 } 1533 _destroy() { 1534 this.destroyed = true; 1535 const waitOn = []; 1536 for (const intentState of this._intentStates.values()) { 1537 this._abortOperatorList({ 1538 intentState, 1539 reason: new Error("Page was destroyed."), 1540 force: true 1541 }); 1542 if (intentState.opListReadCapability) { 1543 continue; 1544 } 1545 for (const internalRenderTask of intentState.renderTasks) { 1546 waitOn.push(internalRenderTask.completed); 1547 internalRenderTask.cancel(); 1548 } 1549 } 1550 this.objs.clear(); 1551 this.#pendingCleanup = false; 1552 this.#abortDelayedCleanup(); 1553 return Promise.all(waitOn); 1554 } 1555 cleanup(resetStats = false) { 1556 this.#pendingCleanup = true; 1557 const success = this.#tryCleanup(false); 1558 if (resetStats && success) { 1559 this._stats &&= new _display_utils.StatTimer(); 1560 } 1561 return success; 1562 } 1563 #tryCleanup(delayed = false) { 1564 this.#abortDelayedCleanup(); 1565 if (!this.#pendingCleanup || this.destroyed) { 1566 return false; 1567 } 1568 if (delayed) { 1569 this.#delayedCleanupTimeout = setTimeout(() => { 1570 this.#delayedCleanupTimeout = null; 1571 this.#tryCleanup(false); 1572 }, DELAYED_CLEANUP_TIMEOUT); 1573 return false;
1574 } 1575 for (const { 1576 renderTasks, 1577 operatorList 1578 } of this._intentStates.values()) { 1579 if (renderTasks.size > 0 || !operatorList.lastChunk) { 1580 return false; 1581 } 1582 } 1583 this._intentStates.clear(); 1584 this.objs.clear(); 1585 this.#pendingCleanup = false; 1586 return true; 1587 } 1588 #abortDelayedCleanup() { 1589 if (this.#delayedCleanupTimeout) { 1590 clearTimeout(this.#delayedCleanupTimeout); 1591 this.#delayedCleanupTimeout = null; 1592 } 1593 } 1594 _startRenderPage(transparency, cacheKey) { 1595 const intentState = this._intentStates.get(cacheKey); 1596 if (!intentState) { 1597 return; 1598 } 1599 this._stats?.timeEnd("Page Request"); 1600 intentState.displayReadyCapability?.resolve(transparency); 1601 } 1602 _renderPageChunk(operatorListChunk, intentState) { 1603 for (let i = 0, ii = operatorListChunk.length; i < ii; i++) { 1604 intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]); 1605 intentState.operatorList.argsArray.push(operatorListChunk.argsArray[i]); 1606 } 1607 intentState.operatorList.lastChunk = operatorListChunk.lastChunk; 1608 intentState.operatorList.separateAnnots = operatorListChunk.separateAnnots; 1609 for (const internalRenderTask of intentState.renderTasks) { 1610 internalRenderTask.operatorListChanged(); 1611 } 1612 if (operatorListChunk.lastChunk) { 1613 this.#tryCleanup(true); 1614 } 1615 } 1616 _pumpOperatorList({ 1617 renderingIntent, 1618 cacheKey, 1619 annotationStorageSerializable 1620 }) { 1621 const { 1622 map, 1623 transfers 1624 } = annotationStorageSerializable; 1625 const readableStream = this._transport.messageHandler.sendWithStream("GetOperatorList", { 1626 pageIndex: this._pageIndex, 1627 intent: renderingIntent, 1628 cacheKey, 1629 annotationStorage: map 1630 }, transfers); 1631 const reader = readableStream.getReader(); 1632 const intentState = this._intentStates.get(cacheKey); 1633 intentState.streamReader = reader; 1634 const pump = () => { 1635 reader.read().then(({ 1636 value, 1637 done 1638 }) => { 1639 if (done) { 1640 intentState.streamReader = null; 1641 return; 1642 } 1643 if (this._transport.destroyed) { 1644 return; 1645 } 1646 this._renderPageChunk(value, intentState); 1647 pump(); 1648 }, reason => { 1649 intentState.streamReader = null; 1650 if (this._transport.destroyed) { 1651 return; 1652 } 1653 if (intentState.operatorList) { 1654 intentState.operatorList.lastChunk = true; 1655 for (const internalRenderTask of intentState.renderTasks) { 1656 internalRenderTask.operatorListChanged(); 1657 } 1658 this.#tryCleanup(true); 1659 } 1660 if (intentState.displayReadyCapability) { 1661 intentState.displayReadyCapability.reject(reason); 1662 } else if (intentState.opListReadCapability) { 1663 intentState.opListReadCapability.reject(reason); 1664 } else { 1665 throw reason; 1666 } 1667 }); 1668 }; 1669 pump(); 1670 } 1671 _abortOperatorList({ 1672 intentState, 1673 reason, 1674 force = false 1675 }) { 1676 if (!intentState.streamReader) { 1677 return; 1678 } 1679 if (intentState.streamReaderCancelTimeout) { 1680 clearTimeout(intentState.streamReaderCancelTimeout); 1681 intentState.streamReaderCancelTimeout = null; 1682 } 1683 if (!force) { 1684 if (intentState.renderTasks.size > 0) { 1685 return; 1686 } 1687 if (reason instanceof _display_utils.RenderingCancelledException) { 1688 let delay = RENDERING_CANCELLED_TIMEOUT; 1689 if (reason.extraDelay > 0 && reason.extraDelay < 1000) { 1690 delay += reason.extraDelay; 1691 } 1692 intentState.streamReaderCancelTimeout = setTimeout(() => { 1693 intentState.streamReaderCancelTimeout = null; 1694 this._abortOperatorList({ 1695 intentState, 1696 reason, 1697 force: true 1698 }); 1699 }, delay); 1700 return; 1701 } 1702 } 1703 intentState.streamReader.cancel(new _util.AbortException(reason.message)).catch(() => {}); 1704 intentState.streamReader = null; 1705 if (this._transport.destroyed) { 1706 return; 1707 } 1708 for (const [curCacheKey, curIntentState] of this._intentStates) { 1709 if (curIntentState === intentState) { 1710 this._intentStates.delete(curCacheKey); 1711 break; 1712 } 1713 } 1714 this.cleanup(); 1715 } 1716 get stats() { 1717 return this._stats; 1718 } 1719} 1720exports.PDFPageProxy = PDFPageProxy; 1721class LoopbackPort { 1722 #listeners = new Set(); 1723 #deferred = Promise.resolve(); 1724 postMessage(obj, transfer) { 1725 const event = { 1726 data: structuredClone(obj, transfer ? { 1727 transfer 1728 } : null) 1729 }; 1730 this.#deferred.then(() => { 1731 for (const listener of this.#listeners) { 1732 listener.call(this, event); 1733 } 1734 }); 1735 } 1736 addEventListener(name, listener) { 1737 this.#listeners.add(listener); 1738 } 1739 removeEventListener(name, listener) { 1740 this.#listeners.delete(listener); 1741 } 1742 terminate() { 1743 this.#listeners.clear(); 1744 } 1745} 1746exports.LoopbackPort = LoopbackPort; 1747const PDFWorkerUtil = exports.PDFWorkerUtil = { 1748 isWorkerDisabled: false, 1749 fallbackWorkerSrc: null, 1750 fakeWorkerId: 0 1751}; 1752{ 1753 if (_util.isNodeJS && typeof require === "function") { 1754 PDFWorkerUtil.isWorkerDisabled = true; 1755 PDFWorkerUtil.fallbackWorkerSrc = "./pdf.worker.js"; 1756 } else if (typeof document === "object") { 1757 const pdfjsFilePath = document?.currentScript?.src; 1758 if (pdfjsFilePath) { 1759 PDFWorkerUtil.fallbackWorkerSrc = pdfjsFilePath.replace(/(\.(?:min\.)?js)(\?.*)?$/i, ".w
1759orker$1$2"); 1760 } 1761 } 1762 PDFWorkerUtil.isSameOrigin = function (baseUrl, otherUrl) { 1763 let base; 1764 try { 1765 base = new URL(baseUrl); 1766 if (!base.origin || base.origin === "null") { 1767 return false; 1768 } 1769 } catch { 1770 return false; 1771 } 1772 const other = new URL(otherUrl, base); 1773 return base.origin === other.origin; 1774 }; 1775 PDFWorkerUtil.createCDNWrapper = function (url) { 1776 const wrapper = `importScripts("${url}");`; 1777 return URL.createObjectURL(new Blob([wrapper])); 1778 }; 1779} 1780class PDFWorker { 1781 static #workerPorts; 1782 constructor({ 1783 name = null, 1784 port = null, 1785 verbosity = (0, _util.getVerbosityLevel)() 1786 } = {}) { 1787 this.name = name; 1788 this.destroyed = false; 1789 this.verbosity = verbosity; 1790 this._readyCapability = new _util.PromiseCapability(); 1791 this._port = null; 1792 this._webWorker = null; 1793 this._messageHandler = null; 1794 if (port) { 1795 if (PDFWorker.#workerPorts?.has(port)) { 1796 throw new Error("Cannot use more than one PDFWorker per port."); 1797 } 1798 (PDFWorker.#workerPorts ||= new WeakMap()).set(port, this); 1799 this._initializeFromPort(port); 1800 return; 1801 } 1802 this._initialize(); 1803 } 1804 get promise() { 1805 return this._readyCapability.promise; 1806 } 1807 get port() { 1808 return this._port; 1809 } 1810 get messageHandler() { 1811 return this._messageHandler; 1812 } 1813 _initializeFromPort(port) { 1814 this._port = port; 1815 this._messageHandler = new _message_handler.MessageHandler("main", "worker", port); 1816 this._messageHandler.on("ready", function () {}); 1817 this._readyCapability.resolve(); 1818 this._messageHandler.send("configure", { 1819 verbosity: this.verbosity 1820 }); 1821 } 1822 #generateTrustedURL(sourcePath) { 1823 if (window.trustedTypes) { 1824 const sanitizer = window.trustedTypes.createPolicy("foo", { 1825 createScriptURL: url => url 1826 }); 1827 return sanitizer.createScriptURL(sourcePath); 1828 } 1829 return sourcePath; 1830 } 1831 _initialize() { 1832 if (!PDFWorkerUtil.isWorkerDisabled && !PDFWorker._mainThreadWorkerMessageHandler) { 1833 let { 1834 workerSrc 1835 } = PDFWorker; 1836 try { 1837 if (!PDFWorkerUtil.isSameOrigin(window.location.href, workerSrc)) { 1838 workerSrc = PDFWorkerUtil.createCDNWrapper(new URL(workerSrc, window.location).href); 1839 } 1840 const worker = new Worker(this.#generateTrustedURL(workerSrc)); 1841 const messageHandler = new _message_handler.MessageHandler("main", "worker", worker); 1842 const terminateEarly = () => { 1843 worker.removeEventListener("error", onWorkerError); 1844 messageHandler.destroy(); 1845 worker.terminate(); 1846 if (this.destroyed) { 1847 this._readyCapability.reject(new Error("Worker was destroyed")); 1848 } else { 1849 this._setupFakeWorker(); 1850 } 1851 }; 1852 const onWorkerError = () => { 1853 if (!this._webWorker) { 1854 terminateEarly(); 1855 } 1856 }; 1857 worker.addEventListener("error", onWorkerError); 1858 messageHandler.on("test", data => { 1859 worker.removeEventListener("error", onWorkerError); 1860 if (this.destroyed) { 1861 terminateEarly(); 1862 return; 1863 } 1864 if (data) { 1865 this._messageHandler = messageHandler; 1866 this._port = worker; 1867 this._webWorker = worker; 1868 this._readyCapability.resolve(); 1869 messageHandler.send("configure", { 1870 verbosity: this.verbosity 1871 }); 1872 } else { 1873 this._setupFakeWorker(); 1874 messageHandler.destroy(); 1875 worker.terminate(); 1876 } 1877 }); 1878 messageHandler.on("ready", data => { 1879 worker.removeEventListener("error", onWorkerError); 1880 if (this.destroyed) { 1881 terminateEarly(); 1882 return; 1883 } 1884 try { 1885 sendTest(); 1886 } catch { 1887 this._setupFakeWorker(); 1888 } 1889 }); 1890 const sendTest = () => { 1891 const testObj = new Uint8Array(); 1892 messageHandler.send("test", testObj, [testObj.buffer]); 1893 }; 1894 sendTest(); 1895 return; 1896 } catch { 1897 (0, _util.info)("The worker has been disabled."); 1898 } 1899 } 1900 this._setupFakeWorker(); 1901 } 1902 _setupFakeWorker() { 1903 if (!PDFWorkerUtil.isWorkerDisabled) { 1904 (0, _util.warn)("Setting up fake worker."); 1905 PDFWorkerUtil.isWorkerDisabled = true; 1906 } 1907 PDFWorker._setupFakeWorkerGlobal.then(WorkerMessageHandler => { 1908 if (this.destroyed) { 1909 this._readyCapability.reject(new Error("Worker was destroyed")); 1910 return; 1911 } 1912 const port = new LoopbackPort(); 1913 this._port = port;
1914 const id = `fake${PDFWorkerUtil.fakeWorkerId++}`; 1915 const workerHandler = new _message_handler.MessageHandler(id + "_worker", id, port); 1916 WorkerMessageHandler.setup(workerHandler, port); 1917 const messageHandler = new _message_handler.MessageHandler(id, id + "_worker", port); 1918 this._messageHandler = messageHandler; 1919 this._readyCapability.resolve(); 1920 messageHandler.send("configure", { 1921 verbosity: this.verbosity 1922 }); 1923 }).catch(reason => { 1924 this._readyCapability.reject(new Error(`Setting up fake worker failed: "${reason.message}".`)); 1925 }); 1926 } 1927 destroy() { 1928 this.destroyed = true; 1929 if (this._webWorker) { 1930 this._webWorker.terminate(); 1931 this._webWorker = null; 1932 } 1933 PDFWorker.#workerPorts?.delete(this._port); 1934 this._port = null; 1935 if (this._messageHandler) { 1936 this._messageHandler.destroy(); 1937 this._messageHandler = null; 1938 } 1939 } 1940 static fromPort(params) { 1941 if (!params?.port) { 1942 throw new Error("PDFWorker.fromPort - invalid method signature."); 1943 } 1944 const cachedPort = this.#workerPorts?.get(params.port); 1945 if (cachedPort) { 1946 if (cachedPort._pendingDestroy) { 1947 throw new Error("PDFWorker.fromPort - the worker is being destroyed.\n" + "Please remember to await `PDFDocumentLoadingTask.destroy()`-calls."); 1948 } 1949 return cachedPort; 1950 } 1951 return new PDFWorker(params); 1952 } 1953 static get workerSrc() { 1954 if (_worker_options.GlobalWorkerOptions.workerSrc) { 1955 if (_worker_options.GlobalWorkerOptions.workerSrc.constructor.name === "Function") { 1956 return _worker_options.GlobalWorkerOptions.workerSrc(); 1957 } 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 if (this._canvas) { 2688 InternalRenderTask.#canvasInUse.delete(this._canvas); 2689 } 2690 this.callback(error || new _display_utils.RenderingCancelledException(`Rendering cancelled, page ${this._pageIndex + 1}`, extraDelay)); 2691 } 2692 operatorListChanged() { 2693 if (!this.graphicsReady) { 2694 this.graphicsReadyCallback ||= this._continueBound; 2695 return; 2696 } 2697 this.stepper?.updateOperatorList(this.operatorList); 2698 if (this.running) { 2699 return; 2700 } 2701 this._continue(); 2702 } 2703 _continue() { 2704 this.running = true; 2705 if (this.cancelled) { 2706 return; 2707 } 2708 if (this.task.onContinue) { 2709 this.task.onContinue(this._scheduleNextBound); 2710 } else { 2711 this._scheduleNext(); 2712 } 2713 } 2714 _scheduleNext() { 2715 window.ngxZone.runOutsideAngular(() => { 2716 if (this._useRequestAnimationFrame) { 2717 window.requestAnimationFrame(() => { 2718 this._nextBound().catch(this._cancelBound); 2719 }); 2720 } else {
2721 Promise.resolve().then(this._nextBound).catch(this._cancelBound); 2722 } 2723 }); 2724 } 2725 async _next() { 2726 if (this.cancelled) { 2727 return; 2728 } 2729 this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList, this.operatorListIdx, this._continueBound, this.stepper); 2730 if (this.operatorListIdx === this.operatorList.argsArray.length) { 2731 this.running = false; 2732 if (this.operatorList.lastChunk) { 2733 this.gfx.endDrawing(this.pageColors); 2734 if (this._canvas) { 2735 InternalRenderTask.#canvasInUse.delete(this._canvas); 2736 } 2737 this.callback(); 2738 } 2739 } 2740 } 2741} 2742const version = exports.version = '3.10.560'; 2743const build = exports.build = 'cc30dd43d'; 2744 2745/***/ }), 2746/* 3 */ 2747/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 2748 2749 2750 2751Object.defineProperty(exports, "__esModule", ({ 2752 value: true 2753})); 2754exports.SerializableEmpty = exports.PrintAnnotationStorage = exports.AnnotationStorage = void 0; 2755var _util = __w_pdfjs_require__(1); 2756var _editor = __w_pdfjs_require__(4); 2757var _murmurhash = __w_pdfjs_require__(8); 2758const SerializableEmpty = exports.SerializableEmpty = Object.freeze({ 2759 map: null, 2760 hash: "", 2761 transfers: undefined 2762}); 2763class AnnotationStorage { 2764 #modified = false; 2765 #storage = new Map(); 2766 constructor() { 2767 this.onSetModified = null; 2768 this.onResetModified = null; 2769 this.onAnnotationEditor = null; 2770 } 2771 getValue(key, defaultValue) { 2772 const value = this.#storage.get(key); 2773 if (value === undefined) { 2774 return defaultValue; 2775 } 2776 return Object.assign(defaultValue, value); 2777 } 2778 getRawValue(key) { 2779 return this.#storage.get(key); 2780 } 2781 remove(key) { 2782 this.#storage.delete(key); 2783 if (this.#storage.size === 0) { 2784 this.resetModified(); 2785 } 2786 if (typeof this.onAnnotationEditor === "function") { 2787 for (const value of this.#storage.values()) { 2788 if (value instanceof _editor.AnnotationEditor) { 2789 return; 2790 } 2791 } 2792 this.onAnnotationEditor(null); 2793 } 2794 } 2795 setValue(key, value) { 2796 const obj = this.#storage.get(key); 2797 let modified = false; 2798 if (obj !== undefined) { 2799 for (const [entry, val] of Object.entries(value)) { 2800 if (obj[entry] !== val) { 2801 modified = true; 2802 obj[entry] = val; 2803 } 2804 } 2805 } else { 2806 modified = true; 2807 this.#storage.set(key, value); 2808 } 2809 if (modified) { 2810 this.#setModified(); 2811 } 2812 if (value instanceof _editor.AnnotationEditor && typeof this.onAnnotationEditor === "function") { 2813 this.onAnnotationEditor(value.constructor._type); 2814 } 2815 } 2816 has(key) { 2817 return this.#storage.has(key); 2818 } 2819 getAll() { 2820 return this.#storage.size > 0 ? (0, _util.objectFromMap)(this.#storage) : null; 2821 } 2822 setAll(obj) { 2823 for (const [key, val] of Object.entries(obj)) { 2824 this.setValue(key, val); 2825 } 2826 } 2827 get size() { 2828 return this.#storage.size; 2829 } 2830 #setModified() { 2831 if (!this.#modified) { 2832 this.#modified = true; 2833 if (typeof this.onSetModified === "function") { 2834 this.onSetModified(); 2835 } 2836 } 2837 } 2838 resetModified() { 2839 if (this.#modified) { 2840 this.#modified = false; 2841 if (typeof this.onResetModified === "function") { 2842 this.onResetModified(); 2843 } 2844 } 2845 } 2846 get print() { 2847 return new PrintAnnotationStorage(this); 2848 } 2849 get serializable() { 2850 if (this.#storage.size === 0) { 2851 return SerializableEmpty; 2852 } 2853 const map = new Map(), 2854 hash = new _murmurhash.MurmurHash3_64(), 2855 transfers = []; 2856 const context = Object.create(null); 2857 let hasBitmap = false; 2858 for (const [key, val] of this.#storage) { 2859 const serialized = val instanceof _editor.AnnotationEditor ? val.serialize(false, context) : val; 2860 if (serialized) { 2861 map.set(key, serialized); 2862 hash.update(`${key}:${JSON.stringify(serialized)}`); 2863 hasBitmap ||= !!serialized.bitmap; 2864 } 2865 } 2866 if (hasBitmap) { 2867 for (const value of map.values()) { 2868 if (value.bitmap) { 2869 transfers.push(value.bitmap); 2870 } 2871 } 2872 } 2873 return map.size > 0 ? { 2874 map, 2875 hash: hash.hexdigest(), 2876 transfers 2877 } : SerializableEmpty; 2878 } 2879} 2880exports.AnnotationStorage = AnnotationStorage; 2881class PrintAnnotationStorage extends AnnotationStorage { 2882 #serializable; 2883 constructor(parent) { 2884 super(); 2885 const { 2886 map, 2887 hash, 2888 transfers 2889 } = parent.serializable; 2890 const clone = structuredClone(map, transfers ? { 2891 transfer: transfers 2892 } : null); 2893 this.#serializable = { 2894 map: clone, 2895 hash, 2896 transfers 2897 }; 2898 } 2899 get print() { 2900 (0, _util.unreachable)("Should not call PrintAnnotationStorage.print"); 2901 } 2902 get serializable() { 2903 return this.#serializable; 2904 } 2905} 2906exports.PrintAnnotationStorage = PrintAnnotationStorage; 2907 2908/***/ }), 2909/* 4 */ 2910/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 2911 2912 2913 2914Object.defineProperty(exports, "__esModule", ({ 2915 value: true 2916})); 2917exports.AnnotationEditor = void 0; 2918var _tools = __w_pdfjs_require__(5); 2919var _util = __w_pdfjs_require__(1); 2920class AnnotationEditor { 2921 #keepAspectRatio = false;
2922 #resizersDiv = null; 2923 #boundFocusin = this.focusin.bind(this); 2924 #boundFocusout = this.focusout.bind(this); 2925 #hasBeenClicked = false; 2926 #isEditing = false; 2927 #isInEditMode = false; 2928 _initialOptions = Object.create(null); 2929 _uiManager = null; 2930 _focusEventsAllowed = true; 2931 #isDraggable = false; 2932 #zIndex = AnnotationEditor._zIndex++; 2933 doNotMove = false; 2934 static _colorManager = new _tools.ColorManager(); 2935 static _zIndex = 1; 2936 constructor(parameters) { 2937 if (this.constructor === AnnotationEditor) { 2938 (0, _util.unreachable)("Cannot initialize AnnotationEditor."); 2939 } 2940 this.parent = parameters.parent; 2941 this.id = parameters.id; 2942 this.width = this.height = null; 2943 this.pageIndex = parameters.parent.pageIndex; 2944 this.name = parameters.name; 2945 this.div = null; 2946 this._uiManager = parameters.uiManager; 2947 this.annotationElementId = null; 2948 this._willKeepAspectRatio = false; 2949 this._initialOptions.isCentered = parameters.isCentered; 2950 const { 2951 rotation, 2952 rawDims: { 2953 pageWidth, 2954 pageHeight, 2955 pageX, 2956 pageY 2957 } 2958 } = this.parent.viewport; 2959 this.rotation = rotation; 2960 this.pageRotation = (360 + rotation - this._uiManager.viewParameters.rotation) % 360; 2961 this.pageDimensions = [pageWidth, pageHeight]; 2962 this.pageTranslation = [pageX, pageY]; 2963 const [width, height] = this.parentDimensions; 2964 this.x = parameters.x / width; 2965 this.y = parameters.y / height; 2966 this.isAttachedToDOM = false; 2967 this.deleted = false; 2968 } 2969 static get _defaultLineColor() { 2970 return (0, _util.shadow)(this, "_defaultLineColor", this._colorManager.getHexCode("CanvasText")); 2971 } 2972 static deleteAnnotationElement(editor) { 2973 const fakeEditor = new FakeEditor({ 2974 id: editor.parent.getNextId(), 2975 parent: editor.parent, 2976 uiManager: editor._uiManager 2977 }); 2978 fakeEditor.annotationElementId = editor.annotationElementId; 2979 fakeEditor.deleted = true; 2980 fakeEditor._uiManager.addToAnnotationStorage(fakeEditor); 2981 } 2982 static initialize(_l10n) {} 2983 static updateDefaultParams(_type, _value) {} 2984 static get defaultPropertiesToUpdate() { 2985 return []; 2986 } 2987 static isHandlingMimeForPasting(_mime) { 2988 return false; 2989 } 2990 static paste(item, parent) { 2991 (0, _util.unreachable)("Not implemented"); 2992 } 2993 get propertiesToUpdate() { 2994 return []; 2995 } 2996 get _isDraggable() { 2997 return this.#isDraggable; 2998 } 2999 set _isDraggable(value) { 3000 this.#isDraggable = value; 3001 this.div?.classList.toggle("draggable", value); 3002 } 3003 center() { 3004 const [pageWidth, pageHeight] = this.pageDimensions; 3005 switch (this.parentRotation) { 3006 case 90: 3007 this.x -= this.height * pageHeight / (pageWidth * 2); 3008 this.y += this.width * pageWidth / (pageHeight * 2); 3009 break; 3010 case 180: 3011 this.x += this.width / 2; 3012 this.y += this.height / 2; 3013 break; 3014 case 270: 3015 this.x += this.height * pageHeight / (pageWidth * 2); 3016 this.y -= this.width * pageWidth / (pageHeight * 2); 3017 break; 3018 default: 3019 this.x -= this.width / 2; 3020 this.y -= this.height / 2; 3021 break; 3022 } 3023 this.fixAndSetPosition(); 3024 } 3025 addCommands(params) { 3026 this._uiManager.addCommands(params); 3027 } 3028 get currentLayer() { 3029 return this._uiManager.currentLayer; 3030 } 3031 setInBackground() { 3032 this.div.style.zIndex = 0; 3033 } 3034 setInForeground() { 3035 this.div.style.zIndex = this.#zIndex; 3036 } 3037 setParent(parent) { 3038 if (parent !== null) { 3039 this.pageIndex = parent.pageIndex; 3040 this.pageDimensions = parent.pageDimensions; 3041 } 3042 this.parent = parent; 3043 } 3044 focusin(event) { 3045 if (!this._focusEventsAllowed) { 3046 return; 3047 } 3048 if (!this.#hasBeenClicked) { 3049 this.parent.setSelected(this); 3050 } else { 3051 this.#hasBeenClicked = false; 3052 } 3053 } 3054 focusout(event) { 3055 if (!this._focusEventsAllowed) { 3056 return; 3057 } 3058 if (!this.isAttachedToDOM) { 3059 return; 3060 } 3061 const target = event.relatedTarget; 3062 if (target?.closest(`#${this.id}`)) { 3063 return; 3064 } 3065 event.preventDefault(); 3066 if (!this.parent?.isMultipleSelection) { 3067 this.commitOrRemove(); 3068 } 3069 } 3070 commitOrRemove() { 3071 if (this.isEmpty()) { 3072 this.remove(); 3073 } else { 3074 this.commit(); 3075 } 3076 } 3077 commit() { 3078 this.addToAnnotationStorage(); 3079 } 3080 addToAnnotationStorage() { 3081 this._uiManager.addToAnnotationStorage(this); 3082 } 3083 setAt(x, y, tx, ty) { 3084 const [width, height] = this.parentDimensions; 3085 [tx, ty] = this.screenToPageTranslation(tx, ty); 3086 if (this.doNotMove) { 3087 [tx, ty] = [0, 0]; 3088 } 3089 this.x = (x + tx) / width; 3090 this.y = (y + ty) / height; 3091 this.fixAndSetPosition(); 3092 } 3093 #translate([width, height], x, y) { 3094 [x, y] = this.screenToPageTranslation(x, y); 3095 this.x += x / width; 3096 this.y += y / height; 3097 this.fixAndSetPosition(); 3098 } 3099 translate(x, y) { 3100 this.#translate(this.parentDimensions, x, y); 3101 } 3102 translateInPage(x, y) { 3103 this.#translate(this.pageDimensions, x, y); 3104 this.moveInDOM(); 3105 this.div.scrollIntoView({ 3106 block: "nearest" 3107 }); 3108 } 3109 drag(tx, ty) { 3110 const [parentWidth, parentHeight] = this.parentDimensions; 3111 this.x += tx / parentWidth; 3112 this.y += ty / parentHeight; 3113 if (this.x < 0 || this.x > 1 || this.y < 0 || this.y > 1) { 3114 const { 3115 x, 3116 y 3117 } = this.div.getBoundingClientRect(); 3118 if (this.parent.findNewParent(this, x, y)) { 3119 this.x -= Math.floor(this.x); 3120 this.y -= Math.floor(this.y); 3121 } 3122 } 3123 this.div.style.left = `${(100 * this.x).toFixed(2)}%`; 3124 this.div.style.top = `${(100 * this.y).toFixed(2)}%`; 3125 this.div.scrollIntoView({ 3126 block: "nearest" 3127 }); 3128 } 3129 fixAndSetPosition() { 3130 const [pageWidth, pageHeight] = this.pageDimensions; 3131 let { 3132 x, 3133 y, 3134 width, 3135 height 3136 } = this; 3137 width *= pageWidth; 3138 height *= pageHeight; 3139 x *= pageWidth; 3140 y *= pageHeight; 3141 switch (this.rotation) { 3142 case 0: 3143 x = Math.max(0, Math.min(pageWidth - width, x)); 3144 y = Math.max(0, Math.min(pageHeight - height, y)); 3145 break; 3146 case 90: 3147 x = Math.max(0, Math.min(pageWidth - height, x)); 3148 y = Math.min(pageHeight, Math.max(width, y)); 3149 break; 3150 case 180: 3151 x = Math.min(pageWidth, Math.max(width, x)); 3152 y = Math.min(pageHeight, Math.max(height, y)); 3153 break; 3154 case 270: 3155 x = Math.min(pageWidth, Math.max(height, x)); 3156 y = Math.max(0, Math.min(pageHeight - width, y)); 3157 break; 3158 } 3159 this.x = x / pageWidth; 3160 this.y = y / pageHeight; 3161 this.div.style.left = `${(100 * this.x).toFixed(2)}%`; 3162 this.div.style.top = `${(100 * this.y).toFixed(2)}%`; 3163 } 3164 static #rotatePoint(x, y, angle) { 3165 switch (angle) { 3166 case 90: 3167 return [y, -x]; 3168 case 180: 3169 return [-x, -y]; 3170 case 270: 3171 return [-y, x]; 3172 default: 3173 return [x, y]; 3174 } 3175 } 3176 screenToPageTranslation(x, y) { 3177 return AnnotationEditor.#rotatePoint(x, y, this.parentRotation); 3178 } 3179 pageTranslationToScreen(x, y) { 3180 return AnnotationEditor.#rotatePoint(x, y, 360 - this.parentRotation); 3181 } 3182 #getRotationMatrix(rotation) { 3183 switch (rotation) { 3184 case 90: 3185 { 3186 const [pageWidth, pageHeight] = this.pageDimensions; 3187 return [0, -pageWidth / pageHeight, pageHeight / pageWidth, 0]; 3188 } 3189 case 180: 3190 return [-1, 0, 0, -1]; 3191 case 270: 3192 { 3193 const [pageWidth, pageHeight] = this.pageDimensions; 3194 return [0, pageWidth / pageHeight, -pageHeight / pageWidth, 0]; 3195 } 3196 default: 3197 return [1, 0, 0, 1]; 3198 } 3199 } 3200 get parentScale() { 3201 return this._uiManager.viewParameters.realScale; 3202 } 3203 get parentRotation() { 3204 return (this._uiManager.viewParameters.rotation + this.pageRotation) % 360; 3205 } 3206 get parentDimensions() { 3207 const { 3208 parentScale, 3209 pageDimensions: [pageWidth, pageHeight] 3210 } = this; 3211 const scaledWidth = pageWidth * parentScale; 3212 const scaledHeight = pageHeight * parentScale; 3213 return _util.FeatureTest.isCSSRoundSupported ? [Math.round(scaledWidth), Math.round(scaledHeight)] : [scaledWidth, scaledHeight]; 3214 } 3215 setDims(width, height) { 3216 const [parentWidth, parentHeight] = this.parentDimensions; 3217 this.div.style.width = `${(100 * width / parentWidth).toFixed(2)}%`; 3218 if (!this.#keepAspectRatio) { 3219 this.div.style.height = `${(100 * height / parentHeight).toFixed(2)}%`; 3220 } 3221 } 3222 fixDims() { 3223 const { 3224 style 3225 } = this.div; 3226 const { 3227 height, 3228 width 3229 } = style; 3230 const widthPercent = width.endsWith("%"); 3231 const heightPercent = !this.#keepAspectRatio && height.endsWith("%"); 3232 if (widthPercent && heightPercent) { 3233 return; 3234 } 3235 const [parentWidth, parentHeight] = this.parentDimensions; 3236 if (!widthPercent) { 3237 style.width = `${(100 * parseFloat(width) / parentWidth).toFixed(2)}%`; 3238 } 3239 if (!this.#keepAspectRatio && !heightPercent) { 3240 style.height = `${(100 * parseFloat(height) / parentHeight).toFixed(2)}%`; 3241 } 3242 } 3243 getInitialTranslation() { 3244 return [0, 0]; 3245 } 3246 static #noContextMenu(e) { 3247 e.preventDefault(); 3248 } 3249 #createResizers() { 3250 if (this.#resizersDiv) { 3251 return; 3252 } 3253 this.#resizersDiv = document.createElement("div"); 3254 this.#resizersDiv.classList.add("resizers"); 3255 const classes = ["topLeft", "topRight", "bottomRight", "bottomLeft"]; 3256 if (!this._willKeepAspectRatio) { 3257 classes.push("topMiddle", "middleRight", "bottomMiddle", "middleLeft"); 3258 } 3259 for (const name of classes) { 3260 const div = document.createElement("div"); 3261 this.#resizersDiv.append(div); 3262 div.classList.add("resizer", name); 3263 div.addEventListener("pointerdown", this.#resizerPointerdown.bind(this, name)); 3264 div.addEventListener("contextmenu", AnnotationEditor.#noContextMenu); 3265 } 3266 this.div.prepend(this.#resizersDiv); 3267 } 3268 #resizerPointerdown(name, event) { 3269 event.preventDefault(); 3270 const { 3271 isMac 3272 } = _util.FeatureTest.platform; 3273 if (event.button !== 0 || event.ctrlKey && isMac) { 3274 return; 3275 } 3276 const boundResizerPointermove = this.#resizerPointermove.bind(this, name); 3277 const savedDraggable = this._isDraggable; 3278 this._isDraggable = false;
3279 const pointerMoveOptions = { 3280 passive: true, 3281 capture: true 3282 }; 3283 window.addEventListener("pointermove", boundResizerPointermove, pointerMoveOptions); 3284 const savedX = this.x; 3285 const savedY = this.y; 3286 const savedWidth = this.width; 3287 const savedHeight = this.height; 3288 const savedParentCursor = this.parent.div.style.cursor; 3289 const savedCursor = this.div.style.cursor; 3290 this.div.style.cursor = this.parent.div.style.cursor = window.getComputedStyle(event.target).cursor; 3291 const pointerUpCallback = () => { 3292 this._isDraggable = savedDraggable; 3293 window.removeEventListener("pointerup", pointerUpCallback); 3294 window.removeEventListener("blur", pointerUpCallback); 3295 window.removeEventListener("pointermove", boundResizerPointermove, pointerMoveOptions); 3296 this.parent.div.style.cursor = savedParentCursor; 3297 this.div.style.cursor = savedCursor; 3298 const newX = this.x; 3299 const newY = this.y; 3300 const newWidth = this.width; 3301 const newHeight = this.height; 3302 if (newX === savedX && newY === savedY && newWidth === savedWidth && newHeight === savedHeight) { 3303 return; 3304 } 3305 this.addCommands({ 3306 cmd: () => { 3307 this.width = newWidth; 3308 this.height = newHeight; 3309 this.x = newX; 3310 this.y = newY; 3311 const [parentWidth, parentHeight] = this.parentDimensions; 3312 this.setDims(parentWidth * newWidth, parentHeight * newHeight); 3313 this.fixAndSetPosition(); 3314 this.moveInDOM(); 3315 }, 3316 undo: () => { 3317 this.width = savedWidth; 3318 this.height = savedHeight; 3319 this.x = savedX; 3320 this.y = savedY; 3321 const [parentWidth, parentHeight] = this.parentDimensions; 3322 this.setDims(parentWidth * savedWidth, parentHeight * savedHeight); 3323 this.fixAndSetPosition(); 3324 this.moveInDOM(); 3325 }, 3326 mustExec: true 3327 }); 3328 }; 3329 window.addEventListener("pointerup", pointerUpCallback); 3330 window.addEventListener("blur", pointerUpCallback); 3331 } 3332 #resizerPointermove(name, event) { 3333 const [parentWidth, parentHeight] = this.parentDimensions; 3334 const savedX = this.x; 3335 const savedY = this.y; 3336 const savedWidth = this.width; 3337 const savedHeight = this.height; 3338 const minWidth = AnnotationEditor.MIN_SIZE / parentWidth; 3339 const minHeight = AnnotationEditor.MIN_SIZE / parentHeight; 3340 const round = x => Math.round(x * 10000) / 10000; 3341 const rotationMatrix = this.#getRotationMatrix(this.rotation); 3342 const transf = (x, y) => [rotationMatrix[0] * x + rotationMatrix[2] * y, rotationMatrix[1] * x + rotationMatrix[3] * y]; 3343 const invRotationMatrix = this.#getRotationMatrix(360 - this.rotation); 3344 const invTransf = (x, y) => [invRotationMatrix[0] * x + invRotationMatrix[2] * y, invRotationMatrix[1] * x + invRotationMatrix[3] * y]; 3345 let getPoint; 3346 let getOpposite; 3347 let isDiagonal = false;
3348 let isHorizontal = false; 3349 switch (name) { 3350 case "topLeft": 3351 isDiagonal = true; 3352 getPoint = (w, h) => [0, 0]; 3353 getOpposite = (w, h) => [w, h]; 3354 break; 3355 case "topMiddle": 3356 getPoint = (w, h) => [w / 2, 0]; 3357 getOpposite = (w, h) => [w / 2, h]; 3358 break; 3359 case "topRight": 3360 isDiagonal = true; 3361 getPoint = (w, h) => [w, 0]; 3362 getOpposite = (w, h) => [0, h]; 3363 break; 3364 case "middleRight": 3365 isHorizontal = true; 3366 getPoint = (w, h) => [w, h / 2]; 3367 getOpposite = (w, h) => [0, h / 2]; 3368 break; 3369 case "bottomRight": 3370 isDiagonal = true; 3371 getPoint = (w, h) => [w, h]; 3372 getOpposite = (w, h) => [0, 0]; 3373 break; 3374 case "bottomMiddle": 3375 getPoint = (w, h) => [w / 2, h]; 3376 getOpposite = (w, h) => [w / 2, 0]; 3377 break; 3378 case "bottomLeft": 3379 isDiagonal = true; 3380 getPoint = (w, h) => [0, h]; 3381 getOpposite = (w, h) => [w, 0]; 3382 break; 3383 case "middleLeft": 3384 isHorizontal = true; 3385 getPoint = (w, h) => [0, h / 2]; 3386 getOpposite = (w, h) => [w, h / 2]; 3387 break; 3388 } 3389 const point = getPoint(savedWidth, savedHeight); 3390 const oppositePoint = getOpposite(savedWidth, savedHeight); 3391 let transfOppositePoint = transf(...oppositePoint); 3392 const oppositeX = round(savedX + transfOppositePoint[0]); 3393 const oppositeY = round(savedY + transfOppositePoint[1]); 3394 let ratioX = 1; 3395 let ratioY = 1; 3396 let [deltaX, deltaY] = this.screenToPageTranslation(event.movementX, event.movementY); 3397 [deltaX, deltaY] = invTransf(deltaX / parentWidth, deltaY / parentHeight); 3398 if (isDiagonal) { 3399 const oldDiag = Math.hypot(savedWidth, savedHeight); 3400 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); 3401 } else if (isHorizontal) { 3402 ratioX = Math.max(minWidth, Math.min(1, Math.abs(oppositePoint[0] - point[0] - deltaX))) / savedWidth; 3403 } else { 3404 ratioY = Math.max(minHeight, Math.min(1, Math.abs(oppositePoint[1] - point[1] - deltaY))) / savedHeight; 3405 } 3406 const newWidth = round(savedWidth * ratioX); 3407 const newHeight = round(savedHeight * ratioY); 3408 transfOppositePoint = transf(...getOpposite(newWidth, newHeight)); 3409 const newX = oppositeX - transfOppositePoint[0]; 3410 const newY = oppositeY - transfOppositePoint[1]; 3411 this.width = newWidth; 3412 this.height = newHeight; 3413 this.x = newX; 3414 this.y = newY; 3415 this.setDims(parentWidth * newWidth, parentHeight * newHeight); 3416 this.fixAndSetPosition(); 3417 } 3418 render() { 3419 this.div = document.createElement("div"); 3420 this.div.setAttribute("data-editor-rotation", (360 - this.rotation) % 360); 3421 this.div.className = this.name; 3422 this.div.setAttribute("id", this.id); 3423 this.div.setAttribute("tabIndex", 0); 3424 this.setInForeground(); 3425 this.div.addEventListener("focusin", this.#boundFocusin); 3426 this.div.addEventListener("focusout", this.#boundFocusout); 3427 const [parentWidth, parentHeight] = this.parentDimensions; 3428 if (this.parentRotation % 180 !== 0) { 3429 this.div.style.maxWidth = `${(100 * parentHeight / parentWidth).toFixed(2)}%`; 3430 this.div.style.maxHeight = `${(100 * parentWidth / parentHeight).toFixed(2)}%`; 3431 } 3432 const [tx, ty] = this.getInitialTranslation(); 3433 this.translate(tx, ty); 3434 (0, _tools.bindEvents)(this, this.div, ["pointerdown"]); 3435 return this.div; 3436 } 3437 pointerdown(event) { 3438 const { 3439 isMac 3440 } = _util.FeatureTest.platform; 3441 if (event.button !== 0 || event.ctrlKey && isMac) { 3442 event.preventDefault(); 3443 return; 3444 } 3445 this.#hasBeenClicked = true; 3446 this.#setUpDragSession(event); 3447 } 3448 #setUpDragSession(event) { 3449 if (!this._isDraggable) { 3450 return; 3451 } 3452 const isSelected = this._uiManager.isSelected(this); 3453 this._uiManager.setUpDragSession(); 3454 let pointerMoveOptions, pointerMoveCallback; 3455 if (isSelected) { 3456 pointerMoveOptions = { 3457 passive: true, 3458 capture: true 3459 }; 3460 pointerMoveCallback = e => { 3461 const [tx, ty] = this.screenToPageTranslation(e.movementX, e.movementY); 3462 this._uiManager.dragSelectedEditors(tx, ty); 3463 }; 3464 window.addEventListener("pointermove", pointerMoveCallback, pointerMoveOptions); 3465 } 3466 const pointerUpCallback = () => { 3467 window.removeEventListener("pointerup", pointerUpCallback); 3468 window.removeEventListener("blur", pointerUpCallback); 3469 if (isSelected) { 3470 window.removeEventListener("pointermove", pointerMoveCallback, pointerMoveOptions); 3471 } 3472 this.#hasBeenClicked = false;
3473 if (!this._uiManager.endDragSession()) { 3474 const { 3475 isMac 3476 } = _util.FeatureTest.platform; 3477 if (event.ctrlKey && !isMac || event.shiftKey || event.metaKey && isMac) { 3478 this.parent.toggleSelected(this); 3479 } else { 3480 this.parent.setSelected(this); 3481 } 3482 } 3483 }; 3484 window.addEventListener("pointerup", pointerUpCallback); 3485 window.addEventListener("blur", pointerUpCallback); 3486 } 3487 moveInDOM() { 3488 this.parent.moveEditorInDOM(this); 3489 } 3490 _setParentAndPosition(parent, x, y) { 3491 parent.changeParent(this); 3492 this.x = x; 3493 this.y = y; 3494 this.fixAndSetPosition(); 3495 this.moveInDOM(); 3496 } 3497 getRect(tx, ty) { 3498 const scale = this.parentScale; 3499 const [pageWidth, pageHeight] = this.pageDimensions; 3500 const [pageX, pageY] = this.pageTranslation; 3501 const shiftX = tx / scale; 3502 const shiftY = ty / scale; 3503 const x = this.x * pageWidth; 3504 const y = this.y * pageHeight; 3505 const width = this.width * pageWidth; 3506 const height = this.height * pageHeight; 3507 switch (this.rotation) { 3508 case 0: 3509 return [x + shiftX + pageX, pageHeight - y - shiftY - height + pageY, x + shiftX + width + pageX, pageHeight - y - shiftY + pageY]; 3510 case 90: 3511 return [x + shiftY + pageX, pageHeight - y + shiftX + pageY, x + shiftY + height + pageX, pageHeight - y + shiftX + width + pageY]; 3512 case 180: 3513 return [x - shiftX - width + pageX, pageHeight - y + shiftY + pageY, x - shiftX + pageX, pageHeight - y + shiftY + height + pageY]; 3514 case 270: 3515 return [x - shiftY - height + pageX, pageHeight - y - shiftX - width + pageY, x - shiftY + pageX, pageHeight - y - shiftX + pageY]; 3516 default: 3517 throw new Error("Invalid rotation"); 3518 } 3519 } 3520 getRectInCurrentCoords(rect, pageHeight) { 3521 const [x1, y1, x2, y2] = rect; 3522 const width = x2 - x1; 3523 const height = y2 - y1; 3524 switch (this.rotation) { 3525 case 0: 3526 return [x1, pageHeight - y2, width, height]; 3527 case 90: 3528 return [x1, pageHeight - y1, height, width]; 3529 case 180: 3530 return [x2, pageHeight - y1, width, height]; 3531 case 270: 3532 return [x2, pageHeight - y2, height, width]; 3533 default: 3534 throw new Error("Invalid rotation"); 3535 } 3536 } 3537 onceAdded() {} 3538 isEmpty() { 3539 return false; 3540 } 3541 enableEditMode() { 3542 this.#isInEditMode = true; 3543 } 3544 disableEditMode() { 3545 this.#isInEditMode = false; 3546 } 3547 isInEditMode() { 3548 return this.#isInEditMode; 3549 } 3550 shouldGetKeyboardEvents() { 3551 return false; 3552 } 3553 needsToBeRebuilt() { 3554 return this.div && !this.isAttachedToDOM; 3555 } 3556 rebuild() { 3557 this.div?.addEventListener("focusin", this.#boundFocusin); 3558 this.div?.addEventListener("focusout", this.#boundFocusout); 3559 } 3560 serialize(_isForCopying = false, _context = null) { 3561 (0, _util.unreachable)("An editor must be serializable"); 3562 } 3563 static deserialize(data, parent, uiManager) { 3564 const editor = new this.prototype.constructor({ 3565 parent, 3566 id: parent.getNextId(), 3567 uiManager 3568 }); 3569 editor.rotation = data.rotation; 3570 const [pageWidth, pageHeight] = editor.pageDimensions; 3571 const [x, y, width, height] = editor.getRectInCurrentCoords(data.rect, pageHeight); 3572 editor.x = x / pageWidth; 3573 editor.y = y / pageHeight; 3574 editor.width = width / pageWidth; 3575 editor.height = height / pageHeight; 3576 return editor; 3577 } 3578 remove() { 3579 this.div.removeEventListener("focusin", this.#boundFocusin); 3580 this.div.removeEventListener("focusout", this.#boundFocusout); 3581 if (!this.isEmpty()) { 3582 this.commit(); 3583 } 3584 if (this.parent) { 3585 this.parent.remove(this); 3586 } else { 3587 this._uiManager.removeEditor(this); 3588 } 3589 } 3590 get isResizable() { 3591 return false; 3592 } 3593 makeResizable() { 3594 if (this.isResizable) { 3595 this.#createResizers(); 3596 this.#resizersDiv.classList.remove("hidden"); 3597 } 3598 } 3599 select() { 3600 this.makeResizable(); 3601 this.div?.classList.add("selectedEditor"); 3602 } 3603 unselect() { 3604 this.#resizersDiv?.classList.add("hidden"); 3605 this.div?.classList.remove("selectedEditor"); 3606 if (this.div?.contains(document.activeElement)) { 3607 this._uiManager.currentLayer.div.focus(); 3608 } 3609 } 3610 updateParams(type, value) {} 3611 disableEditing() {} 3612 enableEditing() {} 3613 enterInEditMode() {} 3614 get contentDiv() { 3615 return this.div; 3616 } 3617 get isEditing() { 3618 return this.#isEditing; 3619 } 3620 set isEditing(value) { 3621 this.#isEditing = value; 3622 if (!this.parent) { 3623 return; 3624 } 3625 if (value) { 3626 this.parent.setSelected(this); 3627 this.parent.setActiveEditor(this); 3628 } else { 3629 this.parent.setActiveEditor(null); 3630 } 3631 } 3632 setAspectRatio(width, height) { 3633 this.#keepAspectRatio = true; 3634 const aspectRatio = width / height; 3635 const { 3636 style 3637 } = this.div; 3638 style.aspectRatio = aspectRatio; 3639 style.height = "auto"; 3640 } 3641 static get MIN_SIZE() { 3642 return 16; 3643 } 3644} 3645exports.AnnotationEditor = AnnotationEditor; 3646class FakeEditor extends AnnotationEditor { 3647 constructor(params) { 3648 super(params); 3649 this.annotationElementId = params.annotationElementId; 3650 this.deleted = true; 3651 } 3652 serialize() { 3653 return { 3654 id: this.annotationElementId, 3655 deleted: true, 3656 pageIndex: this.pageIndex 3657 }; 3658 } 3659} 3660 3661/***/ }), 3662/* 5 */ 3663/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 3664 3665 3666 3667Object.defineProperty(exports, "__esModule", ({ 3668 value: true 3669})); 3670exports.KeyboardManager = exports.CommandManager = exports.ColorManager = exports.AnnotationEditorUIManager = void 0; 3671exports.bindEvents = bindEvents; 3672exports.opacityToHex = opacityToHex; 3673var _util = __w_pdfjs_require__(1); 3674var _display_utils = __w_pdfjs_require__(6); 3675function bindEvents(obj, element, names) { 3676 for (const name of names) { 3677 element.addEventListener(name, obj[name].bind(obj)); 3678 } 3679} 3680function opacityToHex(opacity) { 3681 return Math.round(Math.min(255, Math.max(1, 255 * opacity))).toString(16).padStart(2, "0"); 3682} 3683class IdManager { 3684 #id = 0; 3685 getId() { 3686 return `${_util.AnnotationEditorPrefix}${this.#id++}`; 3687 } 3688} 3689class ImageManager { 3690 #baseId = (0, _util.getUuid)(); 3691 #id = 0; 3692 #cache = null; 3693 static get _isSVGFittingCanvas() { 3694 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>`; 3695 const canvas = new OffscreenCanvas(1, 3); 3696 const ctx = canvas.getContext("2d"); 3697 const image = new Image(); 3698 image.src = svg; 3699 const promise = image.decode().then(() => { 3700 ctx.drawImage(image, 0, 0, 1, 1, 0, 0, 1, 3); 3701 return new Uint32Array(ctx.getImageData(0, 0, 1, 1).data.buffer)[0] === 0; 3702 }); 3703 return (0, _util.shadow)(this, "_isSVGFittingCanvas", promise); 3704 } 3705 async #get(key, rawData) { 3706 this.#cache ||= new Map(); 3707 let data = this.#cache.get(key); 3708 if (data === null) { 3709 return null; 3710 } 3711 if (data?.bitmap) { 3712 data.refCounter += 1; 3713 return data; 3714 } 3715 try { 3716 data ||= { 3717 bitmap: null, 3718 id: `image_${this.#baseId}_${this.#id++}`, 3719 refCounter: 0, 3720 isSvg: false 3721 }; 3722 let image; 3723 if (typeof rawData === "string") { 3724 data.url = rawData; 3725 const response = await fetch(rawData); 3726 if (!response.ok) { 3727 throw new Error(response.statusText); 3728 } 3729 image = await response.blob(); 3730 } else { 3731 image = data.file = rawData; 3732 } 3733 if (image.type === "image/svg+xml") { 3734 const mustRemoveAspectRatioPromise = ImageManager._isSVGFittingCanvas; 3735 const fileReader = new FileReader(); 3736 const imageElement = new Image(); 3737 const imagePromise = new Promise((resolve, reject) => { 3738 imageElement.onload = () => { 3739 data.bitmap = imageElement; 3740 data.isSvg = true; 3741 resolve(); 3742 }; 3743 fileReader.onload = async () => { 3744 const url = data.svgUrl = fileReader.result; 3745 imageElement.src = (await mustRemoveAspectRatioPromise) ? `${url}#svgView(preserveAspectRatio(none))` : url; 3746 }; 3747 imageElement.onerror = fileReader.onerror = reject; 3748 });
vendor: 6,143 bytes, lines 3749-4015
3749 fileReader.readAsDataURL(image); 3750 await imagePromise; 3751 } else { 3752 data.bitmap = await createImageBitmap(image); 3753 } 3754 data.refCounter = 1; 3755 } catch (e) { 3756 console.error(e); 3757 data = null; 3758 } 3759 this.#cache.set(key, data); 3760 if (data) { 3761 this.#cache.set(data.id, data); 3762 } 3763 return data; 3764 } 3765 async getFromFile(file) { 3766 const { 3767 lastModified, 3768 name, 3769 size, 3770 type 3771 } = file; 3772 return this.#get(`${lastModified}_${name}_${size}_${type}`, file); 3773 } 3774 async getFromUrl(url) { 3775 return this.#get(url, url); 3776 } 3777 async getFromId(id) { 3778 this.#cache ||= new Map(); 3779 const data = this.#cache.get(id); 3780 if (!data) { 3781 return null; 3782 } 3783 if (data.bitmap) { 3784 data.refCounter += 1; 3785 return data; 3786 } 3787 if (data.file) { 3788 return this.getFromFile(data.file); 3789 } 3790 return this.getFromUrl(data.url); 3791 } 3792 getSvgUrl(id) { 3793 const data = this.#cache.get(id); 3794 if (!data?.isSvg) { 3795 return null; 3796 } 3797 return data.svgUrl; 3798 } 3799 deleteId(id) { 3800 this.#cache ||= new Map(); 3801 const data = this.#cache.get(id); 3802 if (!data) { 3803 return; 3804 } 3805 data.refCounter -= 1; 3806 if (data.refCounter !== 0) { 3807 return; 3808 } 3809 data.bitmap = null; 3810 } 3811 isValidId(id) { 3812 return id.startsWith(`image_${this.#baseId}_`); 3813 } 3814} 3815class CommandManager { 3816 #commands = []; 3817 #locked = false; 3818 #maxSize; 3819 #position = -1; 3820 constructor(maxSize = 128) { 3821 this.#maxSize = maxSize; 3822 } 3823 add({ 3824 cmd, 3825 undo, 3826 mustExec, 3827 type = NaN, 3828 overwriteIfSameType = false, 3829 keepUndo = false 3830 }) { 3831 if (mustExec) { 3832 cmd(); 3833 } 3834 if (this.#locked) { 3835 return; 3836 } 3837 const save = { 3838 cmd, 3839 undo, 3840 type 3841 }; 3842 if (this.#position === -1) { 3843 if (this.#commands.length > 0) { 3844 this.#commands.length = 0; 3845 } 3846 this.#position = 0; 3847 this.#commands.push(save); 3848 return; 3849 } 3850 if (overwriteIfSameType && this.#commands[this.#position].type === type) { 3851 if (keepUndo) { 3852 save.undo = this.#commands[this.#position].undo; 3853 } 3854 this.#commands[this.#position] = save; 3855 return; 3856 } 3857 const next = this.#position + 1; 3858 if (next === this.#maxSize) { 3859 this.#commands.splice(0, 1); 3860 } else { 3861 this.#position = next; 3862 if (next < this.#commands.length) { 3863 this.#commands.splice(next); 3864 } 3865 } 3866 this.#commands.push(save); 3867 } 3868 undo() { 3869 if (this.#position === -1) { 3870 return; 3871 } 3872 this.#locked = true; 3873 this.#commands[this.#position].undo(); 3874 this.#locked = false; 3875 this.#position -= 1; 3876 } 3877 redo() { 3878 if (this.#position < this.#commands.length - 1) { 3879 this.#position += 1; 3880 this.#locked = true; 3881 this.#commands[this.#position].cmd(); 3882 this.#locked = false; 3883 } 3884 } 3885 hasSomethingToUndo() { 3886 return this.#position !== -1; 3887 } 3888 hasSomethingToRedo() { 3889 return this.#position < this.#commands.length - 1; 3890 } 3891 destroy() { 3892 this.#commands = null; 3893 } 3894 reset() { 3895 this.#commands = []; 3896 this.#position = -1; 3897 this.#locked = false; 3898 } 3899} 3900exports.CommandManager = CommandManager; 3901class KeyboardManager { 3902 constructor(callbacks) { 3903 this.buffer = []; 3904 this.callbacks = new Map(); 3905 this.allKeys = new Set(); 3906 const { 3907 isMac 3908 } = _util.FeatureTest.platform; 3909 for (const [keys, callback, options = {}] of callbacks) { 3910 for (const key of keys) { 3911 const isMacKey = key.startsWith("mac+"); 3912 if (isMac && isMacKey) { 3913 this.callbacks.set(key.slice(4), { 3914 callback, 3915 options 3916 }); 3917 this.allKeys.add(key.split("+").at(-1)); 3918 } else if (!isMac && !isMacKey) { 3919 this.callbacks.set(key, { 3920 callback, 3921 options 3922 }); 3923 this.allKeys.add(key.split("+").at(-1)); 3924 } 3925 } 3926 } 3927 } 3928 #serialize(event) { 3929 if (event.altKey) { 3930 this.buffer.push("alt"); 3931 } 3932 if (event.ctrlKey) { 3933 this.buffer.push("ctrl"); 3934 } 3935 if (event.metaKey) { 3936 this.buffer.push("meta"); 3937 } 3938 if (event.shiftKey) { 3939 this.buffer.push("shift"); 3940 } 3941 this.buffer.push(event.key); 3942 const str = this.buffer.join("+"); 3943 this.buffer.length = 0; 3944 return str; 3945 } 3946 exec(self, event) { 3947 if (!this.allKeys.has(event.key)) { 3948 return; 3949 } 3950 const info = this.callbacks.get(this.#serialize(event)); 3951 if (!info) { 3952 return; 3953 } 3954 const { 3955 callback, 3956 options: { 3957 bubbles = false, 3958 args = [], 3959 checker = null 3960 } 3961 } = info; 3962 if (checker && !checker(self, event)) { 3963 return; 3964 } 3965 callback.bind(self, ...args)(); 3966 if (!bubbles) { 3967 event.stopPropagation(); 3968 event.preventDefault(); 3969 } 3970 } 3971} 3972exports.KeyboardManager = KeyboardManager; 3973class ColorManager { 3974 static _colorsMapping = new Map([["CanvasText", [0, 0, 0]], ["Canvas", [255, 255, 255]]]); 3975 get _colors() { 3976 const colors = new Map([["CanvasText", null], ["Canvas", null]]); 3977 (0, _display_utils.getColorValues)(colors); 3978 return (0, _util.shadow)(this, "_colors", colors); 3979 } 3980 convert(color) { 3981 const rgb = (0, _display_utils.getRGB)(color); 3982 if (!window.matchMedia("(forced-colors: active)").matches) { 3983 return rgb; 3984 } 3985 for (const [name, RGB] of this._colors) { 3986 if (RGB.every((x, i) => x === rgb[i])) { 3987 return ColorManager._colorsMapping.get(name); 3988 } 3989 } 3990 return rgb; 3991 } 3992 getHexCode(name) { 3993 const rgb = this._colors.get(name); 3994 if (!rgb) { 3995 return name; 3996 } 3997 return _util.Util.makeHexColor(...rgb); 3998 } 3999} 4000exports.ColorManager = ColorManager; 4001class AnnotationEditorUIManager { 4002 #activeEditor = null; 4003 #allEditors = new Map(); 4004 #allLayers = new Map(); 4005 #annotationStorage = null; 4006 #commandManager = new CommandManager(); 4007 #currentPageIndex = 0; 4008 #deletedAnnotationsElementIds = new Set(); 4009 #draggingEditors = null; 4010 #editorTypes = null; 4011 #editorsToRescale = new Set(); 4012 #eventBus = null; 4013 #filterFactory = null; 4014 #idManager = new IdManager(); 4015 #isEnabled = false;
4016 #isWaiting = false; 4017 #lastActiveElement = null; 4018 #mode = _util.AnnotationEditorType.NONE; 4019 #selectedEditors = new Set(); 4020 #pageColors = null; 4021 #boundBlur = this.blur.bind(this); 4022 #boundFocus = this.focus.bind(this); 4023 #boundCopy = this.copy.bind(this); 4024 #boundCut = this.cut.bind(this); 4025 #boundPaste = this.paste.bind(this); 4026 #boundKeydown = this.keydown.bind(this); 4027 #boundOnEditingAction = this.onEditingAction.bind(this); 4028 #boundOnPageChanging = this.onPageChanging.bind(this); 4029 #boundOnScaleChanging = this.onScaleChanging.bind(this); 4030 #boundOnRotationChanging = this.onRotationChanging.bind(this); 4031 #previousStates = { 4032 isEditing: false, 4033 isEmpty: true, 4034 hasSomethingToUndo: false, 4035 hasSomethingToRedo: false, 4036 hasSelectedEditor: false 4037 }; 4038 #translation = [0, 0]; 4039 #translationTimeoutId = null; 4040 #container = null; 4041 #viewer = null; 4042 static TRANSLATE_SMALL = 1; 4043 static TRANSLATE_BIG = 10; 4044 static get _keyboardManager() { 4045 const proto = AnnotationEditorUIManager.prototype; 4046 const arrowChecker = self => { 4047 const { 4048 activeElement 4049 } = document; 4050 return activeElement && self.#container.contains(activeElement) && self.hasSomethingToControl(); 4051 }; 4052 const small = this.TRANSLATE_SMALL; 4053 const big = this.TRANSLATE_BIG; 4054 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, { 4055 args: [-small, 0], 4056 checker: arrowChecker 4057 }], [["ctrl+ArrowLeft", "mac+shift+ArrowLeft"], proto.translateSelectedEditors, { 4058 args: [-big, 0], 4059 checker: arrowChecker 4060 }], [["ArrowRight", "mac+ArrowRight"], proto.translateSelectedEditors, { 4061 args: [small, 0], 4062 checker: arrowChecker 4063 }], [["ctrl+ArrowRight", "mac+shift+ArrowRight"], proto.translateSelectedEditors, { 4064 args: [big, 0], 4065 checker: arrowChecker 4066 }], [["ArrowUp", "mac+ArrowUp"], proto.translateSelectedEditors, { 4067 args: [0, -small], 4068 checker: arrowChecker 4069 }], [["ctrl+ArrowUp", "mac+shift+ArrowUp"], proto.translateSelectedEditors, { 4070 args: [0, -big], 4071 checker: arrowChecker 4072 }], [["ArrowDown", "mac+ArrowDown"], proto.translateSelectedEditors, { 4073 args: [0, small], 4074 checker: arrowChecker 4075 }], [["ctrl+ArrowDown", "mac+shift+ArrowDown"], proto.translateSelectedEditors, { 4076 args: [0, big], 4077 checker: arrowChecker 4078 }]])); 4079 } 4080 constructor(container, viewer, eventBus, pdfDocument, pageColors) { 4081 this.#container = container; 4082 this.#viewer = viewer; 4083 this.#eventBus = eventBus; 4084 this.#eventBus._on("editingaction", this.#boundOnEditingAction); 4085 this.#eventBus._on("pagechanging", this.#boundOnPageChanging); 4086 this.#eventBus._on("scalechanging", this.#boundOnScaleChanging); 4087 this.#eventBus._on("rotationchanging", this.#boundOnRotationChanging); 4088 this.#annotationStorage = pdfDocument.annotationStorage; 4089 this.#filterFactory = pdfDocument.filterFactory; 4090 this.#pageColors = pageColors; 4091 this.viewParameters = { 4092 realScale: _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS, 4093 rotation: 0 4094 }; 4095 } 4096 destroy() { 4097 this.#removeKeyboardManager(); 4098 this.#removeFocusManager(); 4099 this.#eventBus._off("editingaction", this.#boundOnEditingAction); 4100 this.#eventBus._off("pagechanging", this.#boundOnPageChanging); 4101 this.#eventBus._off("scalechanging", this.#boundOnScaleChanging); 4102 this.#eventBus._off("rotationchanging", this.#boundOnRotationChanging); 4103 for (const layer of this.#allLayers.values()) { 4104 layer.destroy(); 4105 } 4106 this.#allLayers.clear(); 4107 this.#allEditors.clear(); 4108 this.#editorsToRescale.clear(); 4109 this.#activeEditor = null; 4110 this.#selectedEditors.clear(); 4111 this.#commandManager.destroy(); 4112 } 4113 get hcmFilter() { 4114 return (0, _util.shadow)(this, "hcmFilter", this.#pageColors ? this.#filterFactory.addHCMFilter(this.#pageColors.foreground, this.#pageColors.background) : "none"); 4115 } 4116 onPageChanging({ 4117 pageNumber 4118 }) { 4119 this.#currentPageIndex = pageNumber - 1; 4120 } 4121 focusMainContainer() { 4122 this.#container.focus(); 4123 } 4124 findParent(x, y) { 4125 for (const layer of this.#allLayers.values()) { 4126 const { 4127 x: layerX, 4128 y: layerY, 4129 width, 4130 height 4131 } = layer.div.getBoundingClientRect(); 4132 if (x >= layerX && x <= layerX + width && y >
4132= layerY && y <= layerY + height) { 4133 return layer; 4134 } 4135 } 4136 return null; 4137 } 4138 disableUserSelect(value = false) { 4139 this.#viewer.classList.toggle("noUserSelect", value); 4140 } 4141 addShouldRescale(editor) { 4142 this.#editorsToRescale.add(editor); 4143 } 4144 removeShouldRescale(editor) { 4145 this.#editorsToRescale.delete(editor); 4146 } 4147 onScaleChanging({ 4148 scale 4149 }) { 4150 this.commitOrRemove(); 4151 this.viewParameters.realScale = scale * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS; 4152 for (const editor of this.#editorsToRescale) { 4153 editor.onScaleChanging(); 4154 } 4155 } 4156 onRotationChanging({ 4157 pagesRotation 4158 }) { 4159 this.commitOrRemove(); 4160 this.viewParameters.rotation = pagesRotation; 4161 } 4162 addToAnnotationStorage(editor) { 4163 if (!editor.isEmpty() && this.#annotationStorage && !this.#annotationStorage.has(editor.id)) { 4164 this.#annotationStorage.setValue(editor.id, editor); 4165 } 4166 } 4167 #addFocusManager() { 4168 window.addEventListener("focus", this.#boundFocus); 4169 window.addEventListener("blur", this.#boundBlur); 4170 } 4171 #removeFocusManager() { 4172 window.removeEventListener("focus", this.#boundFocus); 4173 window.removeEventListener("blur", this.#boundBlur); 4174 } 4175 blur() { 4176 if (!this.hasSelection) { 4177 return; 4178 } 4179 const { 4180 activeElement 4181 } = document; 4182 for (const editor of this.#selectedEditors) { 4183 if (editor.div.contains(activeElement)) { 4184 this.#lastActiveElement = [editor, activeElement]; 4185 editor._focusEventsAllowed = false; 4186 break; 4187 } 4188 } 4189 } 4190 focus() { 4191 if (!this.#lastActiveElement) { 4192 return; 4193 } 4194 const [lastEditor, lastActiveElement] = this.#lastActiveElement; 4195 this.#lastActiveElement = null; 4196 lastActiveElement.addEventListener("focusin", () => { 4197 lastEditor._focusEventsAllowed = true; 4198 }, { 4199 once: true 4200 }); 4201 lastActiveElement.focus(); 4202 } 4203 #addKeyboardManager() { 4204 window.addEventListener("keydown", this.#boundKeydown, { 4205 capture: true 4206 }); 4207 } 4208 #removeKeyboardManager() { 4209 window.removeEventListener("keydown", this.#boundKeydown, { 4210 capture: true 4211 }); 4212 } 4213 #addCopyPasteListeners() { 4214 document.addEventListener("copy", this.#boundCopy); 4215 document.addEventListener("cut", this.#boundCut); 4216 document.addEventListener("paste", this.#boundPaste); 4217 } 4218 #removeCopyPasteListeners() { 4219 document.removeEventListener("copy", this.#boundCopy); 4220 document.removeEventListener("cut", this.#boundCut); 4221 document.removeEventListener("paste", this.#boundPaste); 4222 } 4223 copy(event) { 4224 event.preventDefault(); 4225 this.#activeEditor?.commitOrRemove(); 4226 if (!this.hasSelection) { 4227 return; 4228 } 4229 const editors = []; 4230 for (const editor of this.#selectedEditors) { 4231 const serialized = editor.serialize(true); 4232 if (serialized) { 4233 editors.push(serialized); 4234 } 4235 } 4236 if (editors.length === 0) { 4237 return; 4238 } 4239 event.clipboardData.setData("application/pdfjs", JSON.stringify(editors)); 4240 } 4241 cut(event) { 4242 this.copy(event); 4243 this.delete(); 4244 } 4245 paste(event) { 4246 event.preventDefault(); 4247 const { 4248 clipboardData 4249 } = event; 4250 for (const item of clipboardData.items) { 4251 for (const editorType of this.#editorTypes) { 4252 if (editorType.isHandlingMimeForPasting(item.type)) { 4253 editorType.paste(item, this.currentLayer); 4254 return; 4255 } 4256 } 4257 } 4258 const data = clipboardData.getData("application/pdfjs"); 4259 this.addSerializedEditor(data); 4260 } 4261 addSerializedEditor(data, activateEditorIfNecessary = false, doNotMove = false, ignorePageNumber = true) { 4262 if (!data) { 4263 return; 4264 } 4265 try { 4266 if (typeof data === "string") { 4267 data = JSON.parse(data); 4268 } 4269 } catch (ex) { 4270 (0, _util.warn)(`paste: "${ex.message}".`); 4271 return; 4272 } 4273 if (!Array.isArray(data)) { 4274 return; 4275 } 4276 const previousMode = this.#mode; 4277 if (activateEditorIfNecessary && previousMode === _util.AnnotationEditorType.NONE) { 4278 this.updateMode(_util.AnnotationEditorType.FREETEXT); 4279 } 4280 this.unselectAll(); 4281 try { 4282 const newEditors = []; 4283 for (const editor of data) { 4284 const pageNumberMissing = editor.pageIndex === undefined; 4285 const useCurrentPage = ignorePageNumber || pageNumberMissing; 4286 const layer = useCurrentPage ? this.currentLayer : this.getLayer(editor.pageIndex); 4287 const deserializedEditor = layer.deserialize(editor); 4288 if (!deserializedEditor) { 4289 return; 4290 } 4291 deserializedEditor.doNotMove = doNotMove; 4292 newEditors.push(deserializedEditor); 4293 } 4294 const cmd = () => { 4295 for (const editor of newEditors) { 4296 this.#addEditorToLayer(editor); 4297 } 4298 this.#selectEditors(newEditors); 4299 }; 4300 const undo = () => { 4301 for (const editor of newEditors) { 4302 editor.remove(); 4303 } 4304 }; 4305 this.addCommands({ 4306 cmd, 4307 undo, 4308 mustExec: true 4309 }); 4310 } catch (ex) { 4311 (0, _util.warn)(`paste: "${ex.message}".`); 4312 } 4313 if (activateEditorIfNecessary && previousMode !== this.#mode) { 4314 this.updateMode(previousMode); 4315 } 4316 } 4317 keydown(event) { 4318 if (!this.getActive()?.shouldGetKeyboardEvents()) { 4319 AnnotationEditorUIManager._keyboardManager.exec(this, event); 4320 } 4321 } 4322 onEditingAction(details) {
4323 if (["undo", "redo", "delete", "selectAll"].includes(details.name)) { 4324 this[details.name](); 4325 } 4326 } 4327 #dispatchUpdateStates(details) { 4328 const hasChanged = Object.entries(details).some(([key, value]) => this.#previousStates[key] !== value); 4329 if (hasChanged) { 4330 this.#eventBus.dispatch("annotationeditorstateschanged", { 4331 source: this, 4332 details: Object.assign(this.#previousStates, details) 4333 }); 4334 } 4335 } 4336 #dispatchUpdateUI(details) { 4337 this.#eventBus.dispatch("annotationeditorparamschanged", { 4338 source: this, 4339 details 4340 }); 4341 } 4342 setEditingState(isEditing) { 4343 if (isEditing) { 4344 this.#addFocusManager(); 4345 this.#addKeyboardManager(); 4346 this.#addCopyPasteListeners(); 4347 this.#dispatchUpdateStates({ 4348 isEditing: this.#mode !== _util.AnnotationEditorType.NONE, 4349 isEmpty: this.#isEmpty(), 4350 hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(), 4351 hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(), 4352 hasSelectedEditor: false 4353 }); 4354 } else { 4355 this.#removeFocusManager(); 4356 this.#removeKeyboardManager(); 4357 this.#removeCopyPasteListeners(); 4358 this.#dispatchUpdateStates({ 4359 isEditing: false 4360 }); 4361 this.disableUserSelect(false); 4362 } 4363 } 4364 registerEditorTypes(types) { 4365 if (this.#editorTypes) { 4366 return; 4367 } 4368 this.#editorTypes = types; 4369 for (const editorType of this.#editorTypes) { 4370 this.#dispatchUpdateUI(editorType.defaultPropertiesToUpdate); 4371 } 4372 } 4373 getId() { 4374 return this.#idManager.getId(); 4375 } 4376 get currentLayer() { 4377 return this.#allLayers.get(this.#currentPageIndex); 4378 } 4379 getLayer(pageIndex) { 4380 return this.#allLayers.get(pageIndex); 4381 } 4382 get currentPageIndex() { 4383 return this.#currentPageIndex; 4384 } 4385 addLayer(layer) { 4386 this.#allLayers.set(layer.pageIndex, layer); 4387 if (this.#isEnabled) { 4388 layer.enable(); 4389 } else { 4390 layer.disable(); 4391 } 4392 } 4393 removeLayer(layer) { 4394 this.#allLayers.delete(layer.pageIndex); 4395 } 4396 updateMode(mode, editId = null) { 4397 if (this.#mode === mode) { 4398 return; 4399 } 4400 this.#mode = mode; 4401 if (mode === _util.AnnotationEditorType.NONE) { 4402 this.setEditingState(false); 4403 this.#disableAll(); 4404 return; 4405 } 4406 this.setEditingState(true); 4407 this.#enableAll(); 4408 this.unselectAll(); 4409 for (const layer of this.#allLayers.values()) { 4410 layer.updateMode(mode); 4411 } 4412 if (!editId) { 4413 return; 4414 } 4415 for (const editor of this.#allEditors.values()) { 4416 if (editor.annotationElementId === editId) { 4417 this.setSelected(editor); 4418 editor.enterInEditMode(); 4419 break; 4420 } 4421 } 4422 } 4423 updateToolbar(mode) { 4424 if (mode === this.#mode) { 4425 return; 4426 } 4427 this.#eventBus.dispatch("switchannotationeditormode", { 4428 source: this, 4429 mode 4430 }); 4431 } 4432 updateParams(type, value) { 4433 if (!this.#editorTypes) { 4434 return; 4435 } 4436 if (type === _util.AnnotationEditorParamsType.CREATE) { 4437 this.currentLayer.addNewEditor(type); 4438 return; 4439 } 4440 for (const editor of this.#selectedEditors) { 4441 editor.updateParams(type, value); 4442 } 4443 for (const editorType of this.#editorTypes) { 4444 editorType.updateDefaultParams(type, value); 4445 } 4446 } 4447 enableWaiting(mustWait = false) { 4448 if (this.#isWaiting === mustWait) { 4449 return; 4450 } 4451 this.#isWaiting = mustWait; 4452 for (const layer of this.#allLayers.values()) { 4453 if (mustWait) { 4454 layer.disableClick(); 4455 } else { 4456 layer.enableClick(); 4457 } 4458 layer.div.classList.toggle("waiting", mustWait); 4459 } 4460 } 4461 #enableAll() { 4462 if (!this.#isEnabled) { 4463 this.#isEnabled = true; 4464 for (const layer of this.#allLayers.values()) { 4465 layer.enable(); 4466 } 4467 } 4468 } 4469 #disableAll() { 4470 this.unselectAll(); 4471 if (this.#isEnabled) { 4472 this.#isEnabled = false; 4473 for (const layer of this.#allLayers.values()) { 4474 layer.disable(); 4475 } 4476 } 4477 } 4478 getEditors(pageIndex) { 4479 const editors = []; 4480 for (const editor of this.#allEditors.values()) { 4481 if (editor.pageIndex === pageIndex) { 4482 editors.push(editor); 4483 } 4484 } 4485 return editors; 4486 } 4487 getEditor(id) { 4488 return this.#allEditors.get(id); 4489 } 4490 addEditor(editor) { 4491 this.#allEditors.set(editor.id, editor); 4492 } 4493 removeEditor(editor) { 4494 this.#allEditors.delete(editor.id); 4495 this.unselect(editor); 4496 if (!editor.annotationElementId || !this.#deletedAnnotationsElementIds.has(editor.annotationElementId)) { 4497 this.#annotationStorage?.remove(editor.id); 4498 } 4499 } 4500 addDeletedAnnotationElement(editor) { 4501 this.#deletedAnnotationsElementIds.add(editor.annotationElementId); 4502 editor.deleted = true; 4503 } 4504 isDeletedAnnotationElement(annotationElementId) { 4505 return this.#deletedAnnotationsElementIds.has(annotationElementId); 4506 } 4507 removeDeletedAnnotationElement(editor) { 4508 this.#deletedAnnotationsElementIds.delete(editor.annotationElementId); 4509 editor.deleted = false;
vendor: 5,458 bytes, lines 4510-4728
4510 } 4511 #addEditorToLayer(editor) { 4512 const layer = this.#allLayers.get(editor.pageIndex); 4513 if (layer) { 4514 layer.addOrRebuild(editor); 4515 } else { 4516 this.addEditor(editor); 4517 } 4518 } 4519 setActiveEditor(editor) { 4520 if (this.#activeEditor === editor) { 4521 return; 4522 } 4523 this.#activeEditor = editor; 4524 if (editor) { 4525 this.#dispatchUpdateUI(editor.propertiesToUpdate); 4526 } 4527 } 4528 toggleSelected(editor) { 4529 if (this.#selectedEditors.has(editor)) { 4530 this.#selectedEditors.delete(editor); 4531 editor.unselect(); 4532 this.#dispatchUpdateStates({ 4533 hasSelectedEditor: this.hasSelection 4534 }); 4535 return; 4536 } 4537 this.#selectedEditors.add(editor); 4538 editor.select(); 4539 this.#dispatchUpdateUI(editor.propertiesToUpdate); 4540 this.#dispatchUpdateStates({ 4541 hasSelectedEditor: true 4542 }); 4543 } 4544 setSelected(editor) { 4545 for (const ed of this.#selectedEditors) { 4546 if (ed !== editor) { 4547 ed.unselect(); 4548 } 4549 } 4550 this.#selectedEditors.clear(); 4551 this.#selectedEditors.add(editor); 4552 editor.select(); 4553 this.#dispatchUpdateUI(editor.propertiesToUpdate); 4554 this.#dispatchUpdateStates({ 4555 hasSelectedEditor: true 4556 }); 4557 } 4558 isSelected(editor) { 4559 return this.#selectedEditors.has(editor); 4560 } 4561 unselect(editor) { 4562 editor.unselect(); 4563 this.#selectedEditors.delete(editor); 4564 this.#dispatchUpdateStates({ 4565 hasSelectedEditor: this.hasSelection 4566 }); 4567 } 4568 get hasSelection() { 4569 return this.#selectedEditors.size !== 0; 4570 } 4571 undo() { 4572 this.#commandManager.undo(); 4573 this.#dispatchUpdateStates({ 4574 hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(), 4575 hasSomethingToRedo: true, 4576 isEmpty: this.#isEmpty() 4577 }); 4578 } 4579 redo() { 4580 this.#commandManager.redo(); 4581 this.#dispatchUpdateStates({ 4582 hasSomethingToUndo: true, 4583 hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(), 4584 isEmpty: this.#isEmpty() 4585 }); 4586 } 4587 addCommands(params) { 4588 this.#commandManager.add(params); 4589 this.#dispatchUpdateStates({ 4590 hasSomethingToUndo: true, 4591 hasSomethingToRedo: false, 4592 isEmpty: this.#isEmpty() 4593 }); 4594 } 4595 #isEmpty() { 4596 if (this.#allEditors.size === 0) { 4597 return true; 4598 } 4599 if (this.#allEditors.size === 1) { 4600 for (const editor of this.#allEditors.values()) { 4601 return editor.isEmpty(); 4602 } 4603 } 4604 return false; 4605 } 4606 delete() { 4607 this.commitOrRemove(); 4608 if (!this.hasSelection) { 4609 return; 4610 } 4611 const editors = [...this.#selectedEditors]; 4612 const cmd = () => { 4613 for (const editor of editors) { 4614 editor.remove(); 4615 } 4616 }; 4617 const undo = () => { 4618 for (const editor of editors) { 4619 this.#addEditorToLayer(editor); 4620 } 4621 }; 4622 this.addCommands({ 4623 cmd, 4624 undo, 4625 mustExec: true 4626 }); 4627 } 4628 commitOrRemove() { 4629 this.#activeEditor?.commitOrRemove(); 4630 } 4631 hasSomethingToControl() { 4632 return this.#activeEditor || this.hasSelection; 4633 } 4634 #selectEditors(editors) { 4635 this.#selectedEditors.clear(); 4636 for (const editor of editors) { 4637 if (editor.isEmpty()) { 4638 continue; 4639 } 4640 this.#selectedEditors.add(editor); 4641 editor.select(); 4642 } 4643 this.#dispatchUpdateStates({ 4644 hasSelectedEditor: true 4645 }); 4646 } 4647 selectAll() { 4648 for (const editor of this.#selectedEditors) { 4649 editor.commit(); 4650 } 4651 this.#selectEditors(this.#allEditors.values()); 4652 } 4653 unselectAll() { 4654 if (this.#activeEditor) { 4655 this.#activeEditor.commitOrRemove(); 4656 return; 4657 } 4658 if (!this.hasSelection) { 4659 return; 4660 } 4661 for (const editor of this.#selectedEditors) { 4662 editor.unselect(); 4663 } 4664 this.#selectedEditors.clear(); 4665 this.#dispatchUpdateStates({ 4666 hasSelectedEditor: false 4667 }); 4668 } 4669 translateSelectedEditors(x, y, noCommit = false) { 4670 if (!noCommit) { 4671 this.commitOrRemove(); 4672 } 4673 if (!this.hasSelection) { 4674 return; 4675 } 4676 this.#translation[0] += x; 4677 this.#translation[1] += y; 4678 const [totalX, totalY] = this.#translation; 4679 const editors = [...this.#selectedEditors]; 4680 const TIME_TO_WAIT = 1000; 4681 if (this.#translationTimeoutId) { 4682 clearTimeout(this.#translationTimeoutId); 4683 } 4684 this.#translationTimeoutId = setTimeout(() => { 4685 this.#translationTimeoutId = null; 4686 this.#translation[0] = this.#translation[1] = 0; 4687 this.addCommands({ 4688 cmd: () => { 4689 for (const editor of editors) { 4690 if (this.#allEditors.has(editor.id)) { 4691 editor.translateInPage(totalX, totalY); 4692 } 4693 } 4694 }, 4695 undo: () => { 4696 for (const editor of editors) { 4697 if (this.#allEditors.has(editor.id)) { 4698 editor.translateInPage(-totalX, -totalY); 4699 } 4700 } 4701 }, 4702 mustExec: false 4703 }); 4704 }, TIME_TO_WAIT); 4705 for (const editor of editors) { 4706 editor.translateInPage(x, y); 4707 } 4708 } 4709 setUpDragSession() { 4710 if (!this.hasSelection) { 4711 return; 4712 } 4713 this.disableUserSelect(true); 4714 this.#draggingEditors = new Map(); 4715 for (const editor of this.#selectedEditors) { 4716 this.#draggingEditors.set(editor, { 4717 savedX: editor.x, 4718 savedY: editor.y, 4719 savedPageIndex: editor.parent.pageIndex, 4720 newX: 0, 4721 newY: 0, 4722 newPageIndex: -1 4723 }); 4724 } 4725 } 4726 endDragSession() { 4727 if (!this.#draggingEditors) { 4728 return false;
4729 } 4730 this.disableUserSelect(false); 4731 const map = this.#draggingEditors; 4732 this.#draggingEditors = null; 4733 let mustBeAddedInUndoStack = false; 4734 for (const [{ 4735 x, 4736 y, 4737 parent 4738 }, value] of map) { 4739 value.newX = x; 4740 value.newY = y; 4741 value.newPageIndex = parent.pageIndex; 4742 mustBeAddedInUndoStack ||= x !== value.savedX || y !== value.savedY || parent.pageIndex !== value.savedPageIndex; 4743 } 4744 if (!mustBeAddedInUndoStack) { 4745 return false; 4746 } 4747 const move = (editor, x, y, pageIndex) => { 4748 if (this.#allEditors.has(editor.id)) { 4749 const parent = this.#allLayers.get(pageIndex); 4750 if (parent) { 4751 editor._setParentAndPosition(parent, x, y); 4752 } else { 4753 editor.pageIndex = pageIndex; 4754 editor.x = x; 4755 editor.y = y; 4756 } 4757 } 4758 }; 4759 this.addCommands({ 4760 cmd: () => { 4761 for (const [editor, { 4762 newX, 4763 newY, 4764 newPageIndex 4765 }] of map) { 4766 move(editor, newX, newY, newPageIndex); 4767 } 4768 }, 4769 undo: () => { 4770 for (const [editor, { 4771 savedX, 4772 savedY, 4773 savedPageIndex 4774 }] of map) { 4775 move(editor, savedX, savedY, savedPageIndex); 4776 } 4777 }, 4778 mustExec: true 4779 }); 4780 return true; 4781 } 4782 dragSelectedEditors(tx, ty) { 4783 if (!this.#draggingEditors) { 4784 return; 4785 } 4786 for (const editor of this.#draggingEditors.keys()) { 4787 editor.drag(tx, ty); 4788 } 4789 } 4790 rebuild(editor) { 4791 if (editor.parent === null) { 4792 const parent = this.getLayer(editor.pageIndex); 4793 if (parent) { 4794 parent.changeParent(editor); 4795 parent.addOrRebuild(editor); 4796 } else { 4797 this.addEditor(editor); 4798 this.addToAnnotationStorage(editor); 4799 editor.rebuild(); 4800 } 4801 } else { 4802 editor.parent.addOrRebuild(editor); 4803 } 4804 } 4805 isActive(editor) { 4806 return this.#activeEditor === editor; 4807 } 4808 getActive() { 4809 return this.#activeEditor; 4810 } 4811 getMode() { 4812 return this.#mode; 4813 } 4814 get imageManager() { 4815 return (0, _util.shadow)(this, "imageManager", new ImageManager()); 4816 } 4817 removeEditors(filterFunction = () => true) { 4818 let hasChanged = false; 4819 this.#allLayers.forEach(layer => layer.setCleaningUp(true)); 4820 this.#allEditors.forEach(editor => { 4821 if (filterFunction(editor.serialize())) { 4822 editor.remove(); 4823 hasChanged = true; 4824 } 4825 }); 4826 this.#allLayers.forEach(layer => layer.setCleaningUp(false)); 4827 if (hasChanged) { 4828 this.#dispatchUpdateStates({ 4829 hasSomethingToUndo: false, 4830 hasSomethingToRedo: false, 4831 isEmpty: this.#isEmpty() 4832 }); 4833 this.#commandManager.reset(); 4834 } 4835 } 4836} 4837exports.AnnotationEditorUIManager = AnnotationEditorUIManager; 4838 4839/***/ }), 4840/* 6 */ 4841/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 4842 4843 4844 4845Object.defineProperty(exports, "__esModule", ({ 4846 value: true 4847})); 4848exports.StatTimer = exports.RenderingCancelledException = exports.PixelsPerInch = exports.PageViewport = exports.PDFDateString = exports.DOMStandardFontDataFactory = exports.DOMSVGFactory = exports.DOMFilterFactory = exports.DOMCanvasFactory = exports.DOMCMapReaderFactory = exports.AnnotationPrefix = void 0; 4849exports.deprecated = deprecated; 4850exports.getColorValues = getColorValues; 4851exports.getCurrentTransform = getCurrentTransform; 4852exports.getCurrentTransformInverse = getCurrentTransformInverse; 4853exports.getFilenameFromUrl = getFilenameFromUrl; 4854exports.getPdfFilenameFromUrl = getPdfFilenameFromUrl; 4855exports.getRGB = getRGB; 4856exports.getXfaPageViewport = getXfaPageViewport; 4857exports.isDataScheme = isDataScheme; 4858exports.isPdfFile = isPdfFile; 4859exports.isValidFetchUrl = isValidFetchUrl; 4860exports.loadScript = loadScript; 4861exports.setLayerDimensions = setLayerDimensions; 4862var _base_factory = __w_pdfjs_require__(7); 4863var _util = __w_pdfjs_require__(1); 4864const SVG_NS = "http://www.w3.org/2000/svg"; 4865const AnnotationPrefix = exports.AnnotationPrefix = "pdfjs_internal_id_"; 4866class PixelsPerInch { 4867 static CSS = 96.0; 4868 static PDF = 72.0; 4869 static PDF_TO_CSS_UNITS = this.CSS / this.PDF; 4870} 4871exports.PixelsPerInch = PixelsPerInch; 4872class DOMFilterFactory extends _base_factory.BaseFilterFactory { 4873 #_cache; 4874 #_defs; 4875 #docId; 4876 #document; 4877 #hcmFilter; 4878 #hcmKey; 4879 #hcmUrl; 4880 #hcmHighlightFilter; 4881 #hcmHighlightKey; 4882 #hcmHighlightUrl; 4883 #id = 0; 4884 constructor({ 4885 docId, 4886 ownerDocument = globalThis.document 4887 } = {}) { 4888 super(); 4889 this.#docId = docId; 4890 this.#document = ownerDocument; 4891 } 4892 get #cache() { 4893 return this.#_cache ||= new Map(); 4894 } 4895 get #defs() { 4896 if (!this.#_defs) { 4897 const div = this.#document.createElement("div"); 4898 const { 4899 style 4900 } = div; 4901 style.visibility = "hidden"; 4902 style.contain = "strict"; 4903 style.width = style.height = 0; 4904 style.position = "absolute"; 4905 style.top = style.left = 0; 4906 style.zIndex = -1; 4907 const svg = this.#document.createElementNS(SVG_NS, "svg"); 4908 svg.setAttribute("width", 0); 4909 svg.setAttribute("height", 0); 4910 this.#_defs = this.#document.createElementNS(SVG_NS, "defs"); 4911 div.append(svg); 4912 svg.append(this.#_defs); 4913 this.#document.body.append(div); 4914 } 4915 return this.#_defs; 4916 } 4917 addFilter(maps) { 4918 if (!maps) { 4919 return "none"; 4920 } 4921 let value = this.#cache.get(maps); 4922 if (value) { 4923 return value; 4924 } 4925 let tableR, tableG, tableB, key; 4926 if (maps.length === 1) { 4927 const mapR = maps[0]; 4928 const buffer = new Array(256); 4929 for (let i = 0; i < 256; i++) {
4930 buffer[i] = mapR[i] / 255; 4931 } 4932 key = tableR = tableG = tableB = buffer.join(","); 4933 } else { 4934 const [mapR, mapG, mapB] = maps; 4935 const bufferR = new Array(256); 4936 const bufferG = new Array(256); 4937 const bufferB = new Array(256); 4938 for (let i = 0; i < 256; i++) { 4939 bufferR[i] = mapR[i] / 255; 4940 bufferG[i] = mapG[i] / 255; 4941 bufferB[i] = mapB[i] / 255; 4942 } 4943 tableR = bufferR.join(","); 4944 tableG = bufferG.join(","); 4945 tableB = bufferB.join(","); 4946 key = `${tableR}${tableG}${tableB}`; 4947 } 4948 value = this.#cache.get(key); 4949 if (value) { 4950 this.#cache.set(maps, value); 4951 return value; 4952 } 4953 const id = `g_${this.#docId}_transfer_map_${this.#id++}`; 4954 const url = `url(#${id})`; 4955 this.#cache.set(maps, url); 4956 this.#cache.set(key, url); 4957 const filter = this.#createFilter(id); 4958 this.#addTransferMapConversion(tableR, tableG, tableB, filter); 4959 return url; 4960 } 4961 addHCMFilter(fgColor, bgColor) { 4962 const key = `${fgColor}-${bgColor}`; 4963 if (this.#hcmKey === key) { 4964 return this.#hcmUrl; 4965 } 4966 this.#hcmKey = key; 4967 this.#hcmUrl = "none"; 4968 this.#hcmFilter?.remove(); 4969 if (!fgColor || !bgColor) { 4970 return this.#hcmUrl; 4971 } 4972 const fgRGB = this.#getRGB(fgColor); 4973 fgColor = _util.Util.makeHexColor(...fgRGB); 4974 const bgRGB = this.#getRGB(bgColor); 4975 bgColor = _util.Util.makeHexColor(...bgRGB); 4976 this.#defs.style.color = ""; 4977 if (fgColor === "#000000" && bgColor === "#ffffff" || fgColor === bgColor) { 4978 return this.#hcmUrl; 4979 } 4980 const map = new Array(256); 4981 for (let i = 0; i <= 255; i++) { 4982 const x = i / 255; 4983 map[i] = x <= 0.03928 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4; 4984 } 4985 const table = map.join(","); 4986 const id = `g_${this.#docId}_hcm_filter`; 4987 const filter = this.#hcmHighlightFilter = this.#createFilter(id); 4988 this.#addTransferMapConversion(table, table, table, filter); 4989 this.#addGrayConversion(filter); 4990 const getSteps = (c, n) => { 4991 const start = fgRGB[c] / 255; 4992 const end = bgRGB[c] / 255; 4993 const arr = new Array(n + 1); 4994 for (let i = 0; i <= n; i++) { 4995 arr[i] = start + i / n * (end - start); 4996 } 4997 return arr.join(","); 4998 }; 4999 this.#addTransferMapConversion(getSteps(0, 5), getSteps(1, 5), getSteps(2, 5), filter); 5000 this.#hcmUrl = `url(#${id})`; 5001 return this.#hcmUrl; 5002 } 5003 addHighlightHCMFilter(fgColor, bgColor, newFgColor, newBgColor) { 5004 const key = `${fgColor}-${bgColor}-${newFgColor}-${newBgColor}`; 5005 if (this.#hcmHighlightKey === key) { 5006 return this.#hcmHighlightUrl; 5007 } 5008 this.#hcmHighlightKey = key; 5009 this.#hcmHighlightUrl = "none"; 5010 this.#hcmHighlightFilter?.remove(); 5011 if (!fgColor || !bgColor) { 5012 return this.#hcmHighlightUrl; 5013 } 5014 const [fgRGB, bgRGB] = [fgColor, bgColor].map(this.#getRGB.bind(this)); 5015 let fgGray = Math.round(0.2126 * fgRGB[0] + 0.7152 * fgRGB[1] + 0.0722 * fgRGB[2]); 5016 let bgGray = Math.round(0.2126 * bgRGB[0] + 0.7152 * bgRGB[1] + 0.0722 * bgRGB[2]); 5017 let [newFgRGB, newBgRGB] = [newFgColor, newBgColor].map(this.#getRGB.bind(this)); 5018 if (bgGray < fgGray) { 5019 [fgGray, bgGray, newFgRGB, newBgRGB] = [bgGray, fgGray, newBgRGB, newFgRGB]; 5020 } 5021 this.#defs.style.color = ""; 5022 const getSteps = (fg, bg, n) => { 5023 const arr = new Array(256); 5024 const step = (bgGray - fgGray) / n; 5025 const newStart = fg / 255; 5026 const newStep = (bg - fg) / (255 * n); 5027 let prev = 0; 5028 for (let i = 0; i <= n; i++) { 5029 const k = Math.round(fgGray + i * step); 5030 const value = newStart + i * newStep; 5031 for (let j = prev; j <= k; j++) { 5032 arr[j] = value; 5033 } 5034 prev = k + 1; 5035 } 5036 for (let i = prev; i < 256; i++) { 5037 arr[i] = arr[prev - 1]; 5038 } 5039 return arr.join(","); 5040 }; 5041 const id = `g_${this.#docId}_hcm_highlight_filter`; 5042 const filter = this.#hcmHighlightFilter = this.#createFilter(id); 5043 this.#addGrayConversion(filter); 5044 this.#addTransferMapConversion(getSteps(newFgRGB[0], newBgRGB[0], 5), getSteps(newFgRGB[1], newBgRGB[1], 5), getSteps(newFgRGB[2], newBgRGB[2], 5), filter); 5045 this.#hcmHighlightUrl = `url(#${id})`; 5046 return this.#hcmHighlightUrl; 5047 } 5048 destroy(keepHCM = false) { 5049 if (keepHCM && (this.#hcmUrl || this.#hcmHighlightUrl)) { 5050 return; 5051 } 5052 if (this.#_defs) { 5053 this.#_defs.parentNode.parentNode.remove(); 5054 this.#_defs = null; 5055 } 5056 if (this.#_cache) { 5057 this.#_cache.clear(); 5058 this.#_cache = null; 5059 } 5060 this.#id = 0; 5061 } 5062 #addGrayConversion(filter) { 5063 const feColorMatrix = this.#document.createElementNS(SVG_NS, "feColorMatrix"); 5064 feColorMatrix.setAttribute("type", "matrix"); 5065 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"); 5066 filter.append(feColorMatrix); 5067 } 5068 #createFilter(id) { 5069 const filter = this.#document.createElementNS(SVG_NS, "filter"); 5070 filter.setAttribute("color-interpolation-filters", "sRGB"); 5071 filter.setAttribute("id", id); 5072 this.#defs.append(filter); 5073 return filter; 5074 } 5075 #appendFeFunc(feComponentTransfer, func, table) { 5076 const feFunc = this.#document.createElementNS(SVG_NS, func); 5077 feFunc.setAttribute("type", "discrete"); 5078 feFunc.setAttribute("tableValues", table); 5079 feComponentTransfer.append(feFunc); 5080 } 5081 #addTransferMapConversion(rTable, gTable, bTable, filter) { 5082 const feComponentTransfer = this.#document.createElementNS(SVG_NS, "feComponentTransfer"); 5083 filter.append(feComponentTransfer);
5084 this.#appendFeFunc(feComponentTransfer, "feFuncR", rTable); 5085 this.#appendFeFunc(feComponentTransfer, "feFuncG", gTable); 5086 this.#appendFeFunc(feComponentTransfer, "feFuncB", bTable); 5087 } 5088 #getRGB(color) { 5089 this.#defs.style.color = color; 5090 return getRGB(getComputedStyle(this.#defs).getPropertyValue("color")); 5091 } 5092} 5093exports.DOMFilterFactory = DOMFilterFactory; 5094class DOMCanvasFactory extends _base_factory.BaseCanvasFactory { 5095 constructor({ 5096 ownerDocument = globalThis.document 5097 } = {}) { 5098 super(); 5099 this._document = ownerDocument; 5100 } 5101 _createCanvas(width, height) { 5102 const canvas = this._document.createElement("canvas"); 5103 canvas.width = width; 5104 canvas.height = height; 5105 return canvas; 5106 } 5107} 5108exports.DOMCanvasFactory = DOMCanvasFactory; 5109async function fetchData(url, asTypedArray = false) { 5110 if (isValidFetchUrl(url, document.baseURI)) { 5111 const response = await fetch(url); 5112 if (!response.ok) { 5113 throw new Error(response.statusText); 5114 } 5115 return asTypedArray ? new Uint8Array(await response.arrayBuffer()) : (0, _util.stringToBytes)(await response.text()); 5116 } 5117 return new Promise((resolve, reject) => { 5118 const request = new XMLHttpRequest(); 5119 request.open("GET", url, true); 5120 if (asTypedArray) { 5121 request.responseType = "arraybuffer"; 5122 } 5123 request.onreadystatechange = () => { 5124 if (request.readyState !== XMLHttpRequest.DONE) { 5125 return; 5126 } 5127 if (request.status === 200 || request.status === 0) { 5128 let data; 5129 if (asTypedArray && request.response) { 5130 data = new Uint8Array(request.response); 5131 } else if (!asTypedArray && request.responseText) { 5132 data = (0, _util.stringToBytes)(request.responseText); 5133 } 5134 if (data) { 5135 resolve(data); 5136 return; 5137 } 5138 } 5139 reject(new Error(request.statusText)); 5140 }; 5141 request.send(null); 5142 }); 5143} 5144class DOMCMapReaderFactory extends _base_factory.BaseCMapReaderFactory { 5145 _fetchData(url, compressionType) { 5146 return fetchData(url, this.isCompressed).then(data => { 5147 return { 5148 cMapData: data, 5149 compressionType 5150 }; 5151 }); 5152 } 5153} 5154exports.DOMCMapReaderFactory = DOMCMapReaderFactory; 5155class DOMStandardFontDataFactory extends _base_factory.BaseStandardFontDataFactory { 5156 _fetchData(url) { 5157 return fetchData(url, true); 5158 } 5159} 5160exports.DOMStandardFontDataFactory = DOMStandardFontDataFactory; 5161class DOMSVGFactory extends _base_factory.BaseSVGFactory { 5162 _createSVG(type) { 5163 return document.createElementNS(SVG_NS, type); 5164 } 5165} 5166exports.DOMSVGFactory = DOMSVGFactory; 5167class PageViewport { 5168 constructor({ 5169 viewBox, 5170 scale, 5171 rotation, 5172 offsetX = 0, 5173 offsetY = 0, 5174 dontFlip = false 5175 }) { 5176 this.viewBox = viewBox; 5177 this.scale = scale; 5178 this.rotation = rotation; 5179 this.offsetX = offsetX; 5180 this.offsetY = offsetY; 5181 const centerX = (viewBox[2] + viewBox[0]) / 2; 5182 const centerY = (viewBox[3] + viewBox[1]) / 2; 5183 let rotateA, rotateB, rotateC, rotateD; 5184 rotation %= 360; 5185 if (rotation < 0) { 5186 rotation += 360; 5187 } 5188 switch (rotation) { 5189 case 180: 5190 rotateA = -1; 5191 rotateB = 0; 5192 rotateC = 0; 5193 rotateD = 1; 5194 break; 5195 case 90: 5196 rotateA = 0; 5197 rotateB = 1; 5198 rotateC = 1; 5199 rotateD = 0; 5200 break; 5201 case 270: 5202 rotateA = 0; 5203 rotateB = -1; 5204 rotateC = -1; 5205 rotateD = 0; 5206 break; 5207 case 0: 5208 rotateA = 1; 5209 rotateB = 0; 5210 rotateC = 0; 5211 rotateD = -1; 5212 break; 5213 default: 5214 throw new Error("PageViewport: Invalid rotation, must be a multiple of 90 degrees."); 5215 } 5216 if (dontFlip) { 5217 rotateC = -rotateC; 5218 rotateD = -rotateD; 5219 } 5220 let offsetCanvasX, offsetCanvasY; 5221 let width, height; 5222 if (rotateA === 0) { 5223 offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX; 5224 offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY; 5225 width = (viewBox[3] - viewBox[1]) * scale; 5226 height = (viewBox[2] - viewBox[0]) * scale; 5227 } else { 5228 offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX; 5229 offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY; 5230 width = (viewBox[2] - viewBox[0]) * scale; 5231 height = (viewBox[3] - viewBox[1]) * scale; 5232 } 5233 this.transform = [rotateA * scale, rotateB * scale, rotateC * scale, rotateD * scale, offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY]; 5234 this.width = width; 5235 this.height = height; 5236 } 5237 get rawDims() { 5238 const {
5239 viewBox 5240 } = this; 5241 return (0, _util.shadow)(this, "rawDims", { 5242 pageWidth: viewBox[2] - viewBox[0], 5243 pageHeight: viewBox[3] - viewBox[1], 5244 pageX: viewBox[0], 5245 pageY: viewBox[1] 5246 }); 5247 } 5248 clone({ 5249 scale = this.scale, 5250 rotation = this.rotation, 5251 offsetX = this.offsetX, 5252 offsetY = this.offsetY, 5253 dontFlip = false 5254 } = {}) { 5255 return new PageViewport({ 5256 viewBox: this.viewBox.slice(), 5257 scale, 5258 rotation, 5259 offsetX, 5260 offsetY, 5261 dontFlip 5262 }); 5263 } 5264 convertToViewportPoint(x, y) { 5265 return _util.Util.applyTransform([x, y], this.transform); 5266 } 5267 convertToViewportRectangle(rect) { 5268 const topLeft = _util.Util.applyTransform([rect[0], rect[1]], this.transform); 5269 const bottomRight = _util.Util.applyTransform([rect[2], rect[3]], this.transform); 5270 return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]]; 5271 } 5272 convertToPdfPoint(x, y) { 5273 return _util.Util.applyInverseTransform([x, y], this.transform); 5274 } 5275} 5276exports.PageViewport = PageViewport; 5277class RenderingCancelledException extends _util.BaseException { 5278 constructor(msg, extraDelay = 0) { 5279 super(msg, "RenderingCancelledException"); 5280 this.extraDelay = extraDelay; 5281 } 5282} 5283exports.RenderingCancelledException = RenderingCancelledException; 5284function isDataScheme(url) { 5285 const ii = url.length; 5286 let i = 0; 5287 while (i < ii && url[i].trim() === "") { 5288 i++; 5289 } 5290 return url.substring(i, i + 5).toLowerCase() === "data:"; 5291} 5292function isPdfFile(filename) { 5293 return typeof filename === "string" && /\.pdf$/i.test(filename); 5294} 5295function getFilenameFromUrl(url, onlyStripPath = false) { 5296 if (!onlyStripPath) { 5297 [url] = url.split(/[#?]/, 1); 5298 } 5299 return url.substring(url.lastIndexOf("/") + 1); 5300} 5301function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") { 5302 if (window.PDFViewerApplication.appConfig.filenameForDownload) { 5303 return window.PDFViewerApplication.appConfig.filenameForDownload; 5304 } 5305 if (typeof url !== "string") { 5306 return defaultFilename; 5307 } 5308 if (isDataScheme(url)) { 5309 (0, _util.warn)('getPdfFilenameFromUrl: ignore "data:"-URL for performance reasons.'); 5310 return defaultFilename; 5311 } 5312 const reURI = /^(?:(?:[^:]+:)?\/\/[^/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/; 5313 const reFilename = /[^/?#=]+\.pdf\b(?!.*\.pdf\b)/i; 5314 const splitURI = reURI.exec(url); 5315 let suggestedFilename = reFilename.exec(splitURI[1]) || reFilename.exec(splitURI[2]) || reFilename.exec(splitURI[3]); 5316 if (suggestedFilename) { 5317 suggestedFilename = suggestedFilename[0]; 5318 if (suggestedFilename.includes("%")) { 5319 try { 5320 suggestedFilename = reFilename.exec(decodeURIComponent(suggestedFilename))[0]; 5321 } catch {} 5322 } 5323 } 5324 return suggestedFilename || defaultFilename; 5325} 5326class StatTimer { 5327 started = Object.create(null); 5328 times = []; 5329 time(name) { 5330 if (name in this.started) { 5331 (0, _util.warn)(`Timer is already running for ${name}`); 5332 } 5333 this.started[name] = Date.now(); 5334 } 5335 timeEnd(name) { 5336 if (!(name in this.started)) { 5337 (0, _util.warn)(`Timer has not been started for ${name}`); 5338 } 5339 this.times.push({ 5340 name, 5341 start: this.started[name], 5342 end: Date.now() 5343 }); 5344 delete this.started[name]; 5345 } 5346 toString() { 5347 const outBuf = []; 5348 let longest = 0; 5349 for (const { 5350 name 5351 } of this.times) { 5352 longest = Math.max(name.length, longest); 5353 } 5354 for (const { 5355 name, 5356 start, 5357 end 5358 } of this.times) { 5359 outBuf.push(`${name.padEnd(longest)} ${end - start}
5359ms\n`); 5360 } 5361 return outBuf.join(""); 5362 } 5363} 5364exports.StatTimer = StatTimer; 5365function isValidFetchUrl(url, baseUrl) { 5366 try { 5367 const { 5368 protocol 5369 } = baseUrl ? new URL(url, baseUrl) : new URL(url); 5370 return protocol === "http:" || protocol === "https:" || protocol === "capacitor:"; 5371 } catch { 5372 return false; 5373 } 5374} 5375function generateTrustedURL(sourcePath) { 5376 if (window.trustedTypes) { 5377 const sanitizer = window.trustedTypes.createPolicy("foo", { 5378 createScriptURL: url => url 5379 }); 5380 return sanitizer.createScriptURL(sourcePath); 5381 } 5382 return sourcePath; 5383} 5384function loadScript(src, removeScriptElement = false) { 5385 return new Promise((resolve, reject) => { 5386 const script = document.createElement("script"); 5387 let source = src; 5388 if (src.constructor.name === "Function") { 5389 source = src(); 5390 } 5391 const secureSource = generateTrustedURL(source); 5392 script.src = secureSource; 5393 script.onload = function (evt) { 5394 if (removeScriptElement) { 5395 script.remove(); 5396 } 5397 resolve(evt); 5398 }; 5399 script.onerror = function (error) { 5400 globalThis.ngxConsole.log(error); 5401 reject(new Error(`Cannot load script at: ${script.src}`)); 5402 }; 5403 (document.head || document.documentElement).append(script); 5404 }); 5405} 5406function deprecated(details) { 5407 globalThis.ngxConsole.log("Deprecated API usage: " + details); 5408} 5409let pdfDateStringRegex; 5410class PDFDateString { 5411 static toDateObject(input) { 5412 if (!input || typeof input !== "string") { 5413 return null; 5414 } 5415 pdfDateStringRegex ||= new RegExp("^D:" + "(\\d{4})" + "(\\d{2})?" + "(\\d{2})?" + "(\\d{2})?" + "(\\d{2})?" + "(\\d{2})?" + "([Z|+|-])?" + "(\\d{2})?" + "'?" + "(\\d{2})?" + "'?"); 5416 const matches = pdfDateStringRegex.exec(input); 5417 if (!matches) { 5418 return null; 5419 } 5420 const year = parseInt(matches[1], 10); 5421 let month = parseInt(matches[2], 10);
5422 month = month >= 1 && month <= 12 ? month - 1 : 0; 5423 let day = parseInt(matches[3], 10); 5424 day = day >= 1 && day <= 31 ? day : 1; 5425 let hour = parseInt(matches[4], 10); 5426 hour = hour >= 0 && hour <= 23 ? hour : 0; 5427 let minute = parseInt(matches[5], 10); 5428 minute = minute >= 0 && minute <= 59 ? minute : 0; 5429 let second = parseInt(matches[6], 10); 5430 second = second >= 0 && second <= 59 ? second : 0; 5431 const universalTimeRelation = matches[7] || "Z"; 5432 let offsetHour = parseInt(matches[8], 10); 5433 offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0; 5434 let offsetMinute = parseInt(matches[9], 10) || 0; 5435 offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0; 5436 if (universalTimeRelation === "-") { 5437 hour += offsetHour; 5438 minute += offsetMinute; 5439 } else if (universalTimeRelation === "+") { 5440 hour -= offsetHour; 5441 minute -= offsetMinute; 5442 } 5443 return new Date(Date.UTC(year, month, day, hour, minute, second)); 5444 } 5445} 5446exports.PDFDateString = PDFDateString; 5447function getXfaPageViewport(xfaPage, { 5448 scale = 1, 5449 rotation = 0 5450}) { 5451 const { 5452 width, 5453 height 5454 } = xfaPage.attributes.style; 5455 const viewBox = [0, 0, parseInt(width), parseInt(height)]; 5456 return new PageViewport({ 5457 viewBox, 5458 scale, 5459 rotation 5460 }); 5461} 5462function getRGB(color) { 5463 if (color.startsWith("#")) { 5464 const colorRGB = parseInt(color.slice(1), 16); 5465 return [(colorRGB & 0xff0000) >> 16, (colorRGB & 0x00ff00) >> 8, colorRGB & 0x0000ff]; 5466 } 5467 if (color.startsWith("rgb(")) { 5468 return color.slice(4, -1).split(",").map(x => parseInt(x)); 5469 } 5470 if (color.startsWith("rgba(")) { 5471 return color.slice(5, -1).split(",").map(x => parseInt(x)).slice(0, 3); 5472 } 5473 (0, _util.warn)(`Not a valid color format: "${color}"`); 5474 return [0, 0, 0]; 5475} 5476function getColorValues(colors) { 5477 const span = document.createElement("span"); 5478 span.style.visibility = "hidden"; 5479 document.body.append(span); 5480 for (const name of colors.keys()) { 5481 span.style.color = name; 5482 const computedColor = window.getComputedStyle(span).color; 5483 colors.set(name, getRGB(computedColor)); 5484 } 5485 span.remove(); 5486} 5487function getCurrentTransform(ctx) { 5488 const { 5489 a, 5490 b, 5491 c, 5492 d, 5493 e, 5494 f 5495 } = ctx.getTransform(); 5496 return [a, b, c, d, e, f]; 5497} 5498function getCurrentTransformInverse(ctx) { 5499 const { 5500 a, 5501 b, 5502 c, 5503 d, 5504 e, 5505 f 5506 } = ctx.getTransform().invertSelf(); 5507 return [a, b, c, d, e, f]; 5508} 5509function setLayerDimensions(div, viewport, mustFlip = false, mustRotate = true) { 5510 if (viewport instanceof PageViewport) { 5511 const { 5512 pageWidth, 5513 pageHeight 5514 } = viewport.rawDims; 5515 const { 5516 style 5517 } = div; 5518 const useRound = _util.FeatureTest.isCSSRoundSupported; 5519 const w = `var(--scale-factor) * ${pageWidth}px`, 5520 h = `var(--scale-factor) * ${pageHeight}px`; 5521 const widthStr = useRound ? `round(${w}, 1px)` : `calc(${w})`, 5522 heightStr = useRound ? `round(${h}, 1px)` : `calc(${h})`; 5523 if (!mustFlip || viewport.rotation % 180 === 0) { 5524 style.width = widthStr; 5525 style.height = heightStr; 5526 } else { 5527 style.width = heightStr; 5528 style.height = widthStr; 5529 } 5530 } 5531 if (mustRotate) { 5532 div.setAttribute("data-main-rotation", viewport.rotation); 5533 } 5534} 5535 5536/***/ }), 5537/* 7 */ 5538/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 5539 5540 5541 5542Object.defineProperty(exports, "__esModule", ({ 5543 value: true 5544})); 5545exports.BaseStandardFontDataFactory = exports.BaseSVGFactory = exports.BaseFilterFactory = exports.BaseCanvasFactory = exports.BaseCMapReaderFactory = void 0; 5546var _util = __w_pdfjs_require__(1); 5547class BaseFilterFactory { 5548 constructor() { 5549 if (this.constructor === BaseFilterFactory) { 5550 (0, _util.unreachable)("Cannot initialize BaseFilterFactory."); 5551 } 5552 } 5553 addFilter(maps) { 5554 return "none"; 5555 } 5556 addHCMFilter(fgColor, bgColor) { 5557 return "none"; 5558 } 5559 addHighlightHCMFilter(fgColor, bgColor, newFgColor, newBgColor) { 5560 return "none"; 5561 } 5562 destroy(keepHCM = false) {} 5563} 5564exports.BaseFilterFactory = BaseFilterFactory; 5565class BaseCanvasFactory { 5566 constructor() { 5567 if (this.constructor === BaseCanvasFactory) { 5568 (0, _util.unreachable)("Cannot initialize BaseCanvasFactory."); 5569 } 5570 } 5571 create(width, height) { 5572 if (width <= 0 || height <= 0) { 5573 throw new Error("Invalid canvas size"); 5574 } 5575 const canvas = this._createCanvas(width, height); 5576 const options = window.pdfDefaultOptions.activateWillReadFrequentlyFlag ? { 5577 willReadFrequently: true 5578 } : undefined; 5579 const context = canvas.getContext("2d", options); 5580 return { 5581 canvas, 5582 context 5583 }; 5584 } 5585 reset(canvasAndContext, width, height) { 5586 if (!canvasAndContext.canvas) { 5587 throw new Error("Canvas is not specified"); 5588 } 5589 if (width <= 0 || height <= 0) { 5590 throw new Error("Invalid canvas size"); 5591 } 5592 canvasAndContext.canvas.width = width; 5593 canvasAndContext.canvas.height = height; 5594 } 5595 destroy(canvasAndContext) { 5596 if (!canvasAndContext.canvas) { 5597 throw new Error("Canvas is not specified"); 5598 } 5599 canvasAndContext.canvas.width = 0; 5600 canvasAndContext.canvas.height = 0; 5601 canvasAndContext.canvas = null; 5602 canvasAndContext.context = null; 5603 } 5604 _createCanvas(width, height) { 5605 (0, _util.unreachable)("Abstract method `_createCanvas` called."); 5606 } 5607} 5608exports.BaseCanvasFactory = BaseCanvasFactory; 5609class BaseCMapReaderFactory { 5610 constructor({ 5611 baseUrl = null, 5612 isCompressed = true 5613 }) { 5614 if (this.constructor === BaseCMapReaderFactory) { 5615 (0, _util.unreachable)("Cannot initialize BaseCMapReaderFactory."); 5616 } 5617 this.baseUrl = baseUrl; 5618 this.isCompressed = isCompressed; 5619 } 5620 async fetch({ 5621 name 5622 }) { 5623 if (!this.baseUrl) { 5624 throw new Error('The CMap "baseUrl" parameter must be specified, ensure that ' + 'the "cMapUrl" and "cMapPacked" API parameters are provided.'); 5625 } 5626 if (!name) { 5627 throw new Error("CMap name must be specified."); 5628 } 5629 const url = this.baseUrl + name + (this.isCompressed ? ".bcmap" : ""); 5630 const compressionType = this.isCompressed ? _util.CMapCompressionType.BINARY : _util.CMapCompressionType.NONE; 5631 return this._fetchData(url, compressionType).catch(reason => { 5632 throw new Error(`Unable to load ${this.isCompressed ? "binary " : ""}CMap at: ${url}`); 5633 }); 5634 } 5635 _fetchData(url, compressionType) { 5636 (0, _util.unreachable)("Abstract method `_fetchData` called."); 5637 } 5638} 5639exports.BaseCMapReaderFactory = BaseCMapReaderFactory; 5640class BaseStandardFontDataFactory { 5641 constructor({ 5642 baseUrl = null 5643 }) { 5644 if (this.constructor === BaseStandardFontDataFactory) { 5645 (0, _util.unreachable)("Cannot initialize BaseStandardFontDataFactory."); 5646 } 5647 this.baseUrl = baseUrl; 5648 } 5649 async fetch({ 5650 filename 5651 }) { 5652 if (!this.baseUrl) { 5653 throw new Error('The standard font "baseUrl" parameter must be specified, ensure that ' + 'the "standardFontDataUrl" API parameter is provided.'); 5654 } 5655 if (!filename) { 5656 throw new Error("Font filename must be specified."); 5657 } 5658 const url = `${this.baseUrl}${filename}`; 5659 return this._fetchData(url).catch(reason => { 5660 throw new Error(`Unable to load font data at: ${url}`); 5661 }); 5662 } 5663 _fetchData(url) { 5664 (0, _util.unreachable)("Abstract method `_fetchData` called."); 5665 } 5666} 5667exports.BaseStandardFontDataFactory = BaseStandardFontDataFactory; 5668class BaseSVGFactory { 5669 constructor() { 5670 if (this.constructor === BaseSVGFactory) { 5671 (0, _util.unreachable)("Cannot initialize BaseSVGFactory."); 5672 } 5673 } 5674 create(width, height, skipDimensions = false) { 5675 if (width <= 0 || height <= 0) { 5676 throw new Error("Invalid SVG dimensions"); 5677 } 5678 const svg = this._createSVG("svg:svg"); 5679 svg.setAttribute("version", "1.1"); 5680 if (!skipDimensions) { 5681 svg.setAttribute("width", `${width}px`); 5682 svg.setAttribute("height", `${height}px`); 5683 } 5684 svg.setAttribute("preserveAspectRatio", "none"); 5685 svg.setAttribute("viewBox", `0 0 ${width} ${height}`); 5686 return svg; 5687 } 5688 createElement(type) { 5689 if (typeof type !== "string") { 5690 throw new Error("Invalid SVG element type"); 5691 } 5692 return this._createSVG(type); 5693 } 5694 _createSVG(type) { 5695 (0, _util.unreachable)("Abstract method `_createSVG` called."); 5696 } 5697} 5698exports.BaseSVGFactory = BaseSVGFactory; 5699 5700/***/ }), 5701/* 8 */ 5702/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 5703 5704 5705 5706Object.defineProperty(exports, "__esModule", ({ 5707 value: true 5708})); 5709exports.MurmurHash3_64 = void 0; 5710var _util = __w_pdfjs_require__(1); 5711const SEED = 0xc3d2e1f0; 5712const MASK_HIGH = 0xffff0000; 5713const MASK_LOW = 0xffff; 5714class MurmurHash3_64 { 5715 constructor(seed) { 5716 this.h1 = seed ? seed & 0xffffffff : SEED; 5717 this.h2 = seed ? seed & 0xffffffff : SEED; 5718 } 5719 update(input) { 5720 let data, length; 5721 if (typeof input === "string") { 5722 data = new Uint8Array(input.length * 2); 5723 length = 0; 5724 for (let i = 0, ii = input.length; i < ii; i++) { 5725 const code = input.charCodeAt(i); 5726 if (code <= 0xff) { 5727 data[length++] = code; 5728 } else { 5729 data[length++] = code >>> 8; 5730 data[length++] = code & 0xff; 5731 } 5732 } 5733 } else if ((0, _util.isArrayBuffer)(input)) { 5734 data = input.slice(); 5735 length = data.byteLength; 5736 } else { 5737 throw new Error("Wrong data format in MurmurHash3_64_update. " + "Input must be a string or array."); 5738 } 5739 const blockCounts = length >> 2; 5740 const tailLength = length - blockCounts * 4; 5741 const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts); 5742 let k1 = 0, 5743 k2 = 0; 5744 let h1 = this.h1, 5745 h2 = this.h2; 5746 const C1 = 0xcc9e2d51, 5747 C2 = 0x1b873593; 5748 const C1_LOW = C1 & MASK_LOW, 5749 C2_LOW = C2 & MASK_LOW; 5750 for (let i = 0; i < blockCounts; i++) { 5751 if (i & 1) {
5752 k1 = dataUint32[i]; 5753 k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; 5754 k1 = k1 << 15 | k1 >>> 17; 5755 k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; 5756 h1 ^= k1; 5757 h1 = h1 << 13 | h1 >>> 19; 5758 h1 = h1 * 5 + 0xe6546b64; 5759 } else { 5760 k2 = dataUint32[i]; 5761 k2 = k2 * C1 & MASK_HIGH | k2 * C1_LOW & MASK_LOW; 5762 k2 = k2 << 15 | k2 >>> 17; 5763 k2 = k2 * C2 & MASK_HIGH | k2 * C2_LOW & MASK_LOW; 5764 h2 ^= k2; 5765 h2 = h2 << 13 | h2 >>> 19; 5766 h2 = h2 * 5 + 0xe6546b64; 5767 } 5768 } 5769 k1 = 0; 5770 switch (tailLength) { 5771 case 3: 5772 k1 ^= data[blockCounts * 4 + 2] << 16; 5773 case 2: 5774 k1 ^= data[blockCounts * 4 + 1] << 8; 5775 case 1: 5776 k1 ^= data[blockCounts * 4]; 5777 k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; 5778 k1 = k1 << 15 | k1 >>> 17; 5779 k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; 5780 if (blockCounts & 1) { 5781 h1 ^= k1; 5782 } else { 5783 h2 ^= k1; 5784 } 5785 } 5786 this.h1 = h1; 5787 this.h2 = h2; 5788 } 5789 hexdigest() { 5790 let h1 = this.h1, 5791 h2 = this.h2; 5792 h1 ^= h2 >>> 1; 5793 h1 = h1 * 0xed558ccd & MASK_HIGH | h1 * 0x8ccd & MASK_LOW; 5794 h2 = h2 * 0xff51afd7 & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16; 5795 h1 ^= h2 >>> 1; 5796 h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW; 5797 h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16; 5798 h1 ^= h2 >>> 1; 5799 return (h1 >>> 0).toString(16).padStart(8, "0") + (h2 >>> 0).toString(16).padStart(8, "0"); 5800 } 5801} 5802exports.MurmurHash3_64 = MurmurHash3_64; 5803 5804/***/ }), 5805/* 9 */ 5806/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 5807 5808 5809 5810Object.defineProperty(exports, "__esModule", ({ 5811 value: true 5812})); 5813exports.FontLoader = exports.FontFaceObject = void 0; 5814var _util = __w_pdfjs_require__(1); 5815class FontLoader { 5816 #systemFonts = new Set(); 5817 constructor({ 5818 ownerDocument = globalThis.document, 5819 styleElement = null 5820 }) { 5821 this._document = ownerDocument; 5822 this.nativeFontFaces = new Set(); 5823 this.styleElement = null; 5824 this.loadingRequests = []; 5825 this.loadTestFontId = 0; 5826 } 5827 addNativeFontFace(nativeFontFace) { 5828 this.nativeFontFaces.add(nativeFontFace); 5829 this._document.fonts.add(nativeFontFace); 5830 } 5831 removeNativeFontFace(nativeFontFace) { 5832 this.nativeFontFaces.delete(nativeFontFace); 5833 this._document.fonts.delete(nativeFontFace); 5834 } 5835 insertRule(rule) { 5836 if (!this.styleElement) { 5837 this.styleElement = this._document.createElement("style"); 5838 this._document.documentElement.getElementsByTagName("head")[0].append(this.styleElement); 5839 } 5840 const styleSheet = this.styleElement.sheet; 5841 styleSheet.insertRule(rule, styleSheet.cssRules.length); 5842 } 5843 clear() { 5844 for (const nativeFontFace of this.nativeFontFaces) { 5845 this._document.fonts.delete(nativeFontFace); 5846 } 5847 this.nativeFontFaces.clear(); 5848 this.#systemFonts.clear(); 5849 if (this.styleElement) { 5850 this.styleElement.remove(); 5851 this.styleElement = null; 5852 } 5853 } 5854 async loadSystemFont(info) { 5855 if (!info || this.#systemFonts.has(info.loadedName)) { 5856 return; 5857 } 5858 (0, _util.assert)(!this.disableFontFace, "loadSystemFont shouldn't be called when `disableFontFace` is set."); 5859 if (this.isFontLoadingAPISupported) { 5860 const { 5861 loadedName, 5862 src, 5863 style 5864 } = info; 5865 const fontFace = new FontFace(loadedName, src, style); 5866 this.addNativeFontFace(fontFace); 5867 try { 5868 await fontFace.load(); 5869 this.#systemFonts.add(loadedName); 5870 } catch { 5871 (0, _util.warn)(`Cannot load system font: ${info.baseFontName}, installing it could help to improve PDF rendering.`); 5872 this.removeNativeFontFace(fontFace); 5873 } 5874 return; 5875 } 5876 (0, _util.unreachable)("Not implemented: loadSystemFont without the Font Loading API."); 5877 } 5878 async bind(font) { 5879 if (font.attached || font.missingFile && !font.systemFontInfo) { 5880 return; 5881 } 5882 font.attached = true; 5883 if (font.systemFontInfo) { 5884 await this.loadSystemFont(font.systemFontInfo); 5885 return; 5886 } 5887 if (this.isFontLoadingAPISupported) { 5888 const nativeFontFace = font.createNativeFontFace(); 5889 if (nativeFontFace) { 5890 this.addNativeFontFace(nativeFontFace); 5891 try { 5892 await nativeFontFace.loaded; 5893 } catch (ex) { 5894 (0, _util.warn)(`Failed to load font '${nativeFontFace.family}': '${ex}'.`); 5895 font.disableFontFace = true; 5896 throw ex; 5897 } 5898 } 5899 return; 5900 } 5901 const rule = font.createFontFaceRule(); 5902 if (rule) { 5903 this.insertRule(rule); 5904 if (this.isSyncFontLoadingSupported) { 5905 return; 5906 } 5907 await new Promise(resolve => { 5908 const request = this._queueLoadingCallback(resolve); 5909 this._prepareFontLoadEvent(font, request); 5910 }); 5911 } 5912 } 5913 get isFontLoadingAPISupported() { 5914 const hasFonts = !!this._document?.fonts; 5915 return (0, _util.shadow)(this, "isFontLoadingAPISupported", hasFonts); 5916 } 5917 get isSyncFontLoadingSupported() { 5918 let supported = false;
5919 if (_util.isNodeJS) { 5920 supported = true; 5921 } else if (typeof navigator !== "undefined" && /Mozilla\/5.0.*?rv:\d+.*? Gecko/.test(navigator.userAgent)) { 5922 supported = true; 5923 } 5924 return (0, _util.shadow)(this, "isSyncFontLoadingSupported", supported); 5925 } 5926 _queueLoadingCallback(callback) { 5927 function completeRequest() { 5928 (0, _util.assert)(!request.done, "completeRequest() cannot be called twice."); 5929 request.done = true; 5930 while (loadingRequests.length > 0 && loadingRequests[0].done) { 5931 const otherRequest = loadingRequests.shift(); 5932 setTimeout(otherRequest.callback, 0); 5933 } 5934 } 5935 const { 5936 loadingRequests 5937 } = this; 5938 const request = { 5939 done: false, 5940 complete: completeRequest, 5941 callback 5942 }; 5943 loadingRequests.push(request); 5944 return request; 5945 } 5946 get _loadTestFont() { 5947 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=="); 5948 return (0, _util.shadow)(this, "_loadTestFont", testFont); 5949 } 5950 _prepareFontLoadEvent(font, request) { 5951 function int32(data, offset) { 5952 return data.charCodeAt(offset) << 24 | data.charCodeAt(offset + 1) << 16 | data.charCodeAt(offset + 2) << 8 | data.charCodeAt(offset + 3) & 0xff; 5953 } 5954 function spliceString(s, offset, remove, insert) { 5955 const chunk1 = s.substring(0, offset); 5956 const chunk2 = s.substring(offset + remove); 5957 return chunk1 + insert + chunk2; 5958 } 5959 let i, ii; 5960 const canvas = this._document.createElement("canvas"); 5961 canvas.width = 1; 5962 canvas.height = 1; 5963 const options = window.pdfDefaultOptions.activateWillReadFrequentlyFlag ? { 5964 willReadFrequently: true 5965 } : undefined; 5966 const ctx = canvas.getContext("2d", options); 5967 let called = 0; 5968 function isFontReady(name, callback) { 5969 if (++called > 30) { 5970 (0, _util.warn)("Load test font never loaded."); 5971 callback(); 5972 return; 5973 } 5974 ctx.font = "30px " + name; 5975 ctx.fillText(".", 0, 20); 5976 const imageData = ctx.getImageData(0, 0, 1, 1); 5977 if (imageData.data[3] > 0) { 5978 callback(); 5979 return; 5980 } 5981 setTimeout(isFontReady.bind(null, name, callback)); 5982 } 5983 const loadTestFontId = `lt${Date.now()}${this.loadTestFontId++}`; 5984 let data = this._loadTestFont; 5985 const COMMENT_OFFSET = 976; 5986 data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length, loadTestFontId); 5987 const CFF_CHECKSUM_OFFSET = 16; 5988 const XXXX_VALUE = 0x58585858; 5989 let checksum = int32(data, CFF_CHECKSUM_OFFSET); 5990 for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) { 5991 checksum = checksum - XXXX_VALUE + int32(loadTestFontId, i) | 0; 5992 } 5993 if (i < loadTestFontId.length) { 5994 checksum = checksum - XXXX_VALUE + int32(loadTestFontId + "XXX", i) | 0; 5995 }
5996 data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, (0, _util.string32)(checksum)); 5997 const url = `url(data:font/opentype;base64,${btoa(data)});`; 5998 const rule = `@font-face {font-family:"${loadTestFontId}";src:${url}}`; 5999 this.insertRule(rule); 6000 const div = this._document.createElement("div"); 6001 div.style.visibility = "hidden"; 6002 div.style.width = div.style.height = "10px"; 6003 div.style.position = "absolute"; 6004 div.style.top = div.style.left = "0px"; 6005 for (const name of [font.loadedName, loadTestFontId]) { 6006 const span = this._document.createElement("span"); 6007 span.textContent = "Hi"; 6008 span.style.fontFamily = name; 6009 div.append(span); 6010 } 6011 this._document.body.append(div); 6012 isFontReady(loadTestFontId, () => { 6013 div.remove(); 6014 request.complete(); 6015 }); 6016 } 6017} 6018exports.FontLoader = FontLoader; 6019class FontFaceObject { 6020 constructor(translatedData, { 6021 isEvalSupported = true, 6022 disableFontFace = false, 6023 ignoreErrors = false, 6024 inspectFont = null 6025 }) { 6026 this.compiledGlyphs = Object.create(null); 6027 for (const i in translatedData) { 6028 this[i] = translatedData[i]; 6029 } 6030 this.isEvalSupported = isEvalSupported !== false; 6031 this.disableFontFace = disableFontFace === true; 6032 this.ignoreErrors = ignoreErrors === true; 6033 this._inspectFont = inspectFont; 6034 } 6035 createNativeFontFace() { 6036 if (!this.data || this.disableFontFace) { 6037 return null; 6038 } 6039 let nativeFontFace; 6040 if (!this.cssFontInfo) { 6041 nativeFontFace = new FontFace(this.loadedName, this.data, {}); 6042 } else { 6043 const css = { 6044 weight: this.cssFontInfo.fontWeight 6045 }; 6046 if (this.cssFontInfo.italicAngle) { 6047 css.style = `oblique ${this.cssFontInfo.italicAngle}deg`; 6048 } 6049 nativeFontFace = new FontFace(this.cssFontInfo.fontFamily, this.data, css); 6050 } 6051 this._inspectFont?.(this); 6052 return nativeFontFace; 6053 } 6054 createFontFaceRule() { 6055 if (!this.data || this.disableFontFace) { 6056 return null; 6057 } 6058 const data = (0, _util.bytesToString)(this.data); 6059 const url = `url(data:${this.mimetype};base64,${btoa(data)});`; 6060 let rule; 6061 if (!this.cssFontInfo) { 6062 rule = `@font-face {font-family:"${this.loadedName}";src:${url}}`; 6063 } else { 6064 let css = `font-weight: ${this.cssFontInfo.fontWeight};`; 6065 if (this.cssFontInfo.italicAngle) { 6066 css += `font-style: oblique ${this.cssFontInfo.italicAngle}deg;`; 6067 } 6068 rule = `@font-face {font-family:"${this.cssFontInfo.fontFamily}";${css}src:${url}}`; 6069 } 6070 this._inspectFont?.(this, url); 6071 return rule; 6072 } 6073 getPathGenerator(objs, character) { 6074 if (this.compiledGlyphs[character] !== undefined) { 6075 return this.compiledGlyphs[character]; 6076 } 6077 let cmds; 6078 try { 6079 cmds = objs.get(this.loadedName + "_path_" + character); 6080 } catch (ex) { 6081 if (!this.ignoreErrors) { 6082 throw ex; 6083 } 6084 (0, _util.warn)(`getPathGenerator - ignoring character: "${ex}".`); 6085 return this.compiledGlyphs[character] = function (c, size) {}; 6086 } 6087 if (this.isEvalSupported && _util.FeatureTest.isEvalSupported) { 6088 const jsBuf = []; 6089 for (const current of cmds) { 6090 const args = current.args !== undefined ? current.args.join(",") : ""; 6091 jsBuf.push("c.", current.cmd, "(", args, ");\n"); 6092 } 6093 return this.compiledGlyphs[character] = new Function("c", "size", jsBuf.join("")); 6094 } 6095 return this.compiledGlyphs[character] = function (c, size) { 6096 for (const current of cmds) { 6097 if (current.cmd === "scale") { 6098 current.args = [size, -size]; 6099 } 6100 c[current.cmd].apply(c, current.args); 6101 } 6102 }; 6103 } 6104} 6105exports.FontFaceObject = FontFaceObject; 6106 6107/***/ }), 6108/* 10 */ 6109/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 6110 6111 6112 6113Object.defineProperty(exports, "__esModule", ({ 6114 value: true 6115})); 6116exports.NodeStandardFontDataFactory = exports.NodeFilterFactory = exports.NodeCanvasFactory = exports.NodeCMapReaderFactory = void 0; 6117var _base_factory = __w_pdfjs_require__(7); 6118var _util = __w_pdfjs_require__(1); 6119; 6120; 6121const fetchData = function (url) { 6122 return new Promise((resolve, reject) => { 6123 const fs = require("fs"); 6124 fs.readFile(url, (error, data) => { 6125 if (error || !data) { 6126 reject(new Error(error)); 6127 return; 6128 } 6129 resolve(new Uint8Array(data)); 6130 }); 6131 }); 6132}; 6133class NodeFilterFactory extends _base_factory.BaseFilterFactory {}
6134exports.NodeFilterFactory = NodeFilterFactory; 6135class NodeCanvasFactory extends _base_factory.BaseCanvasFactory { 6136 _createCanvas(width, height) { 6137 const Canvas = require("canvas"); 6138 return Canvas.createCanvas(width, height); 6139 } 6140} 6141exports.NodeCanvasFactory = NodeCanvasFactory; 6142class NodeCMapReaderFactory extends _base_factory.BaseCMapReaderFactory { 6143 _fetchData(url, compressionType) { 6144 return fetchData(url).then(data => { 6145 return { 6146 cMapData: data, 6147 compressionType 6148 }; 6149 }); 6150 } 6151} 6152exports.NodeCMapReaderFactory = NodeCMapReaderFactory; 6153class NodeStandardFontDataFactory extends _base_factory.BaseStandardFontDataFactory { 6154 _fetchData(url) { 6155 return fetchData(url); 6156 } 6157} 6158exports.NodeStandardFontDataFactory = NodeStandardFontDataFactory; 6159 6160/***/ }), 6161/* 11 */ 6162/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 6163 6164 6165 6166Object.defineProperty(exports, "__esModule", ({ 6167 value: true 6168})); 6169exports.CanvasGraphics = void 0; 6170var _util = __w_pdfjs_require__(1); 6171var _display_utils = __w_pdfjs_require__(6); 6172var _pattern_helper = __w_pdfjs_require__(12); 6173var _image_utils = __w_pdfjs_require__(13); 6174const MIN_FONT_SIZE = 16; 6175const MAX_FONT_SIZE = 100; 6176const MAX_GROUP_SIZE = 4096; 6177const EXECUTION_TIME = 15; 6178const EXECUTION_STEPS = 10; 6179const MAX_SIZE_TO_COMPILE = 1000; 6180const FULL_CHUNK_HEIGHT = 16; 6181function mirrorContextOperations(ctx, destCtx) { 6182 if (ctx._removeMirroring) { 6183 throw new Error("Context is already forwarding operations."); 6184 } 6185 ctx.__originalSave = ctx.save; 6186 ctx.__originalRestore = ctx.restore; 6187 ctx.__originalRotate = ctx.rotate; 6188 ctx.__originalScale = ctx.scale; 6189 ctx.__originalTranslate = ctx.translate; 6190 ctx.__originalTransform = ctx.transform; 6191 ctx.__originalSetTransform = ctx.setTransform; 6192 ctx.__originalResetTransform = ctx.resetTransform; 6193 ctx.__originalClip = ctx.clip; 6194 ctx.__originalMoveTo = ctx.moveTo; 6195 ctx.__originalLineTo = ctx.lineTo; 6196 ctx.__originalBezierCurveTo = ctx.bezierCurveTo; 6197 ctx.__originalRect = ctx.rect; 6198 ctx.__originalClosePath = ctx.closePath; 6199 ctx.__originalBeginPath = ctx.beginPath; 6200 ctx._removeMirroring = () => { 6201 ctx.save = ctx.__originalSave; 6202 ctx.restore = ctx.__originalRestore; 6203 ctx.rotate = ctx.__originalRotate; 6204 ctx.scale = ctx.__originalScale; 6205 ctx.translate = ctx.__originalTranslate; 6206 ctx.transform = ctx.__originalTransform; 6207 ctx.setTransform = ctx.__originalSetTransform; 6208 ctx.resetTransform = ctx.__originalResetTransform; 6209 ctx.clip = ctx.__originalClip; 6210 ctx.moveTo = ctx.__originalMoveTo; 6211 ctx.lineTo = ctx.__originalLineTo; 6212 ctx.bezierCurveTo = ctx.__originalBezierCurveTo; 6213 ctx.rect = ctx.__originalRect; 6214 ctx.closePath = ctx.__originalClosePath; 6215 ctx.beginPath = ctx.__originalBeginPath; 6216 delete ctx._removeMirroring; 6217 }; 6218 ctx.save = function ctxSave() { 6219 destCtx.save(); 6220 this.__originalSave(); 6221 }; 6222 ctx.restore = function ctxRestore() { 6223 destCtx.restore(); 6224 this.__originalRestore(); 6225 }; 6226 ctx.translate = function ctxTranslate(x, y) { 6227 destCtx.translate(x, y); 6228 this.__originalTranslate(x, y); 6229 }; 6230 ctx.scale = function ctxScale(x, y) { 6231 destCtx.scale(x, y); 6232 this.__originalScale(x, y); 6233 }; 6234 ctx.transform = function ctxTransform(a, b, c, d, e, f) { 6235 destCtx.transform(a, b, c, d, e, f); 6236 this.__originalTransform(a, b, c, d, e, f); 6237 }; 6238 ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) { 6239 destCtx.setTransform(a, b, c, d, e, f); 6240 this.__originalSetTransform(a, b, c, d, e, f); 6241 }; 6242 ctx.resetTransform = function ctxResetTransform() { 6243 destCtx.resetTransform(); 6244 this.__originalResetTransform(); 6245 }; 6246 ctx.rotate = function ctxRotate(angle) { 6247 destCtx.rotate(angle); 6248 this.__originalRotate(angle); 6249 }; 6250 ctx.clip = function ctxRotate(rule) { 6251 destCtx.clip(rule); 6252 this.__originalClip(rule); 6253 }; 6254 ctx.moveTo = function (x, y) { 6255 destCtx.moveTo(x, y); 6256 this.__originalMoveTo(x, y); 6257 }; 6258 ctx.lineTo = function (x, y) { 6259 destCtx.lineTo(x, y); 6260 this.__originalLineTo(x, y); 6261 }; 6262 ctx.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) { 6263 destCtx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); 6264 this.__originalBezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); 6265 }; 6266 ctx.rect = function (x, y, width, height) { 6267 destCtx.rect(x, y, width, height); 6268 this.__originalRect(x, y, width, height); 6269 }; 6270 ctx.closePath = function () { 6271 destCtx.closePath(); 6272 this.__originalClosePath(); 6273 }; 6274 ctx.beginPath = function () { 6275 destCtx.beginPath(); 6276 this.__originalBeginPath(); 6277 }; 6278} 6279class CachedCanvases { 6280 constructor(canvasFactory) { 6281 this.canvasFactory = canvasFactory; 6282 this.cache = Object.create(null); 6283 } 6284 getCanvas(id, width, height) {
6285 let canvasEntry; 6286 if (this.cache[id] !== undefined) { 6287 canvasEntry = this.cache[id]; 6288 this.canvasFactory.reset(canvasEntry, width, height); 6289 } else { 6290 canvasEntry = this.canvasFactory.create(width, height); 6291 this.cache[id] = canvasEntry; 6292 } 6293 return canvasEntry; 6294 } 6295 delete(id) { 6296 delete this.cache[id]; 6297 } 6298 clear() { 6299 for (const id in this.cache) { 6300 const canvasEntry = this.cache[id]; 6301 this.canvasFactory.destroy(canvasEntry); 6302 delete this.cache[id]; 6303 } 6304 } 6305} 6306function drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH) { 6307 const [a, b, c, d, tx, ty] = (0, _display_utils.getCurrentTransform)(ctx); 6308 if (b === 0 && c === 0) { 6309 const tlX = destX * a + tx; 6310 const rTlX = Math.round(tlX); 6311 const tlY = destY * d + ty; 6312 const rTlY = Math.round(tlY); 6313 const brX = (destX + destW) * a + tx; 6314 const rWidth = Math.abs(Math.round(brX) - rTlX) || 1; 6315 const brY = (destY + destH) * d + ty; 6316 const rHeight = Math.abs(Math.round(brY) - rTlY) || 1; 6317 ctx.setTransform(Math.sign(a), 0, 0, Math.sign(d), rTlX, rTlY); 6318 ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rWidth, rHeight); 6319 ctx.setTransform(a, b, c, d, tx, ty); 6320 return [rWidth, rHeight]; 6321 } 6322 if (a === 0 && d === 0) { 6323 const tlX = destY * c + tx; 6324 const rTlX = Math.round(tlX); 6325 const tlY = destX * b + ty; 6326 const rTlY = Math.round(tlY); 6327 const brX = (destY + destH) * c + tx; 6328 const rWidth = Math.abs(Math.round(brX) - rTlX) || 1; 6329 const brY = (destX + destW) * b + ty; 6330 const rHeight = Math.abs(Math.round(brY) - rTlY) || 1; 6331 ctx.setTransform(0, Math.sign(b), Math.sign(c), 0, rTlX, rTlY); 6332 ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rHeight, rWidth); 6333 ctx.setTransform(a, b, c, d, tx, ty); 6334 return [rHeight, rWidth]; 6335 } 6336 ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH); 6337 const scaleX = Math.hypot(a, b); 6338 const scaleY = Math.hypot(c, d); 6339 return [scaleX * destW, scaleY * destH]; 6340} 6341function compileType3Glyph(imgData) { 6342 const { 6343 width, 6344 height 6345 } = imgData; 6346 if (width > MAX_SIZE_TO_COMPILE || height > MAX_SIZE_TO_COMPILE) { 6347 return null; 6348 } 6349 const POINT_TO_PROCESS_LIMIT = 1000; 6350 const POINT_TYPES = new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]); 6351 const width1 = width + 1; 6352 let points = new Uint8Array(width1 * (height + 1)); 6353 let i, j, j0; 6354 const lineSize = width + 7 & ~7; 6355 let data = new Uint8Array(lineSize * height), 6356 pos = 0; 6357 for (const elem of imgData.data) { 6358 let mask = 128; 6359 while (mask > 0) { 6360 data[pos++] = elem & mask ? 0 : 255; 6361 mask >>= 1; 6362 } 6363 } 6364 let count = 0; 6365 pos = 0; 6366 if (data[pos] !== 0) { 6367 points[0] = 1; 6368 ++count; 6369 } 6370 for (j = 1; j < width; j++) { 6371 if (data[pos] !== data[pos + 1]) { 6372 points[j] = data[pos] ? 2 : 1; 6373 ++count; 6374 } 6375 pos++; 6376 } 6377 if (data[pos] !== 0) { 6378 points[j] = 2; 6379 ++count; 6380 } 6381 for (i = 1; i < height; i++) { 6382 pos = i * lineSize; 6383 j0 = i * width1; 6384 if (data[pos - lineSize] !== data[pos]) { 6385 points[j0] = data[pos] ? 1 : 8; 6386 ++count; 6387 } 6388 let sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0); 6389 for (j = 1; j < width; j++) { 6390 sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + (data[pos - lineSize + 1] ? 8 : 0); 6391 if (POINT_TYPES[sum]) { 6392 points[j0 + j] = POINT_TYPES[sum]; 6393 ++count; 6394 } 6395 pos++; 6396 } 6397 if (data[pos - lineSize] !== data[pos]) { 6398 points[j0 + j] = data[pos] ? 2 : 4; 6399 ++count; 6400 } 6401 if (count > POINT_TO_PROCESS_LIMIT) { 6402 return null; 6403 } 6404 } 6405 pos = lineSize * (height - 1); 6406 j0 = i * width1; 6407 if (data[pos] !== 0) { 6408 points[j0] = 8; 6409 ++count; 6410 } 6411 for (j = 1; j < width; j++) { 6412 if (data[pos] !== data[pos + 1]) { 6413 points[j0 + j] = data[pos] ? 4 : 8; 6414 ++count; 6415 } 6416 pos++; 6417 } 6418 if (data[pos] !== 0) { 6419 points[j0 + j] = 4; 6420 ++count; 6421 } 6422 if (count > POINT_TO_PROCESS_LIMIT) { 6423 return null; 6424 } 6425 const steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]); 6426 const path = new Path2D(); 6427 for (i = 0; count && i <= height; i++) { 6428 let p = i * width1; 6429 const end = p + width; 6430 while (p < end && !points[p]) { 6431 p++; 6432 } 6433 if (p === end) { 6434 continue; 6435 } 6436 path.moveTo(p % width1, i); 6437 const p0 = p; 6438 let type = points[p]; 6439 do { 6440 const step = steps[type]; 6441 do { 6442 p += step; 6443 } while (!points[p]); 6444 const pp = points[p]; 6445 if (pp !== 5 && pp !== 10) { 6446 type = pp; 6447 points[p] = 0; 6448 } else { 6449 type = pp & 0x33 * type >> 4; 6450 points[p] &= type >> 2 | type << 2; 6451 } 6452 path.lineTo(p % width1, p / width1 | 0); 6453 if (!points[p]) { 6454 --count; 6455 } 6456 } while (p0 !== p); 6457 --i; 6458 } 6459 data = null; 6460 points = null; 6461 const drawOutline = function (c) { 6462 c.save(); 6463 c.scale(1 / width, -1 / height); 6464 c.translate(0, -height); 6465 c.fill(path); 6466 c.beginPath();
6467 c.restore(); 6468 }; 6469 return drawOutline; 6470} 6471class CanvasExtraState { 6472 constructor(width, height) { 6473 this.alphaIsShape = false; 6474 this.fontSize = 0; 6475 this.fontSizeScale = 1; 6476 this.textMatrix = _util.IDENTITY_MATRIX; 6477 this.textMatrixScale = 1; 6478 this.fontMatrix = _util.FONT_IDENTITY_MATRIX; 6479 this.leading = 0; 6480 this.x = 0; 6481 this.y = 0; 6482 this.lineX = 0; 6483 this.lineY = 0; 6484 this.charSpacing = 0; 6485 this.wordSpacing = 0; 6486 this.textHScale = 1; 6487 this.textRenderingMode = _util.TextRenderingMode.FILL; 6488 this.textRise = 0; 6489 this.fillColor = "#000000"; 6490 this.strokeColor = "#000000"; 6491 this.patternFill = false; 6492 this.fillAlpha = 1; 6493 this.strokeAlpha = 1; 6494 this.lineWidth = 1; 6495 this.activeSMask = null; 6496 this.transferMaps = "none"; 6497 this.startNewPathAndClipBox([0, 0, width, height]); 6498 } 6499 clone() { 6500 const clone = Object.create(this); 6501 clone.clipBox = this.clipBox.slice(); 6502 return clone; 6503 } 6504 setCurrentPoint(x, y) { 6505 this.x = x; 6506 this.y = y; 6507 } 6508 updatePathMinMax(transform, x, y) { 6509 [x, y] = _util.Util.applyTransform([x, y], transform); 6510 this.minX = Math.min(this.minX, x); 6511 this.minY = Math.min(this.minY, y); 6512 this.maxX = Math.max(this.maxX, x); 6513 this.maxY = Math.max(this.maxY, y); 6514 } 6515 updateRectMinMax(transform, rect) { 6516 const p1 = _util.Util.applyTransform(rect, transform); 6517 const p2 = _util.Util.applyTransform(rect.slice(2), transform); 6518 this.minX = Math.min(this.minX, p1[0], p2[0]); 6519 this.minY = Math.min(this.minY, p1[1], p2[1]); 6520 this.maxX = Math.max(this.maxX, p1[0], p2[0]); 6521 this.maxY = Math.max(this.maxY, p1[1], p2[1]); 6522 } 6523 updateScalingPathMinMax(transform, minMax) { 6524 _util.Util.scaleMinMax(transform, minMax); 6525 this.minX = Math.min(this.minX, minMax[0]); 6526 this.maxX = Math.max(this.maxX, minMax[1]); 6527 this.minY = Math.min(this.minY, minMax[2]); 6528 this.maxY = Math.max(this.maxY, minMax[3]); 6529 } 6530 updateCurvePathMinMax(transform, x0, y0, x1, y1, x2, y2, x3, y3, minMax) { 6531 const box = _util.Util.bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3); 6532 if (minMax) { 6533 minMax[0] = Math.min(minMax[0], box[0], box[2]); 6534 minMax[1] = Math.max(minMax[1], box[0], box[2]); 6535 minMax[2] = Math.min(minMax[2], box[1], box[3]); 6536 minMax[3] = Math.max(minMax[3], box[1], box[3]); 6537 return; 6538 } 6539 this.updateRectMinMax(transform, box); 6540 } 6541 getPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) { 6542 const box = [this.minX, this.minY, this.maxX, this.maxY]; 6543 if (pathType === _pattern_helper.PathType.STROKE) { 6544 if (!transform) { 6545 (0, _util.unreachable)("Stroke bounding box must include transform."); 6546 } 6547 const scale = _util.Util.singularValueDecompose2dScale(transform); 6548 const xStrokePad = scale[0] * this.lineWidth / 2; 6549 const yStrokePad = scale[1] * this.lineWidth / 2; 6550 box[0] -= xStrokePad; 6551 box[1] -= yStrokePad; 6552 box[2] += xStrokePad; 6553 box[3] += yStrokePad; 6554 } 6555 return box; 6556 } 6557 updateClipFromPath() { 6558 const intersect = _util.Util.intersect(this.clipBox, this.getPathBoundingBox()); 6559 this.startNewPathAndClipBox(intersect || [0, 0, 0, 0]); 6560 } 6561 isEmptyClip() { 6562 return this.minX === Infinity; 6563 } 6564 startNewPathAndClipBox(box) { 6565 this.clipBox = box; 6566 this.minX = Infinity; 6567 this.minY = Infinity; 6568 this.maxX = 0; 6569 this.maxY = 0; 6570 } 6571 getClippedPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) { 6572 return _util.Util.intersect(this.clipBox, this.getPathBoundingBox(pathType, transform)); 6573 } 6574} 6575function putBinaryImageData(ctx, imgData) { 6576 if (typeof ImageData !== "undefined" && imgData instanceof ImageData) { 6577 ctx.putImageData(imgData, 0, 0); 6578 return; 6579 } 6580 const height = imgData.height, 6581 width = imgData.width; 6582 const partialChunkHeight = height % FULL_CHUNK_HEIGHT; 6583 const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; 6584 const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; 6585 const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); 6586 let srcPos = 0, 6587 destPos; 6588 const src = imgData.data; 6589 const dest = chunkImgData.data; 6590 let i, j, thisChunkHeight, elemsInThisChunk; 6591 if (imgData.kind === _util.ImageKind.GRAYSCALE_1BPP) { 6592 const srcLength = src.byteLength; 6593 const dest32 = new Uint32Array(dest.buffer, 0, dest.byteLength >> 2); 6594 const dest32DataLength = dest32.length; 6595 const fullSrcDiff = width + 7 >> 3; 6596 const white = 0xffffffff; 6597 const black = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; 6598 for (i = 0; i < totalChunks; i++) { 6599 thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight; 6600 destPos = 0; 6601 for (j = 0; j < thisChunkHeight; j++) { 6602 const srcDiff = srcLength - srcPos; 6603 let k = 0;
6604 const kEnd = srcDiff > fullSrcDiff ? width : srcDiff * 8 - 7; 6605 const kEndUnrolled = kEnd & ~7; 6606 let mask = 0; 6607 let srcByte = 0; 6608 for (; k < kEndUnrolled; k += 8) { 6609 srcByte = src[srcPos++]; 6610 dest32[destPos++] = srcByte & 128 ? white : black; 6611 dest32[destPos++] = srcByte & 64 ? white : black; 6612 dest32[destPos++] = srcByte & 32 ? white : black; 6613 dest32[destPos++] = srcByte & 16 ? white : black; 6614 dest32[destPos++] = srcByte & 8 ? white : black; 6615 dest32[destPos++] = srcByte & 4 ? white : black; 6616 dest32[destPos++] = srcByte & 2 ? white : black; 6617 dest32[destPos++] = srcByte & 1 ? white : black; 6618 } 6619 for (; k < kEnd; k++) { 6620 if (mask === 0) { 6621 srcByte = src[srcPos++]; 6622 mask = 128; 6623 } 6624 dest32[destPos++] = srcByte & mask ? white : black; 6625 mask >>= 1; 6626 } 6627 } 6628 while (destPos < dest32DataLength) { 6629 dest32[destPos++] = 0; 6630 } 6631 ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 6632 } 6633 } else if (imgData.kind === _util.ImageKind.RGBA_32BPP) { 6634 j = 0; 6635 elemsInThisChunk = width * FULL_CHUNK_HEIGHT * 4; 6636 for (i = 0; i < fullChunks; i++) { 6637 dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 6638 srcPos += elemsInThisChunk; 6639 ctx.putImageData(chunkImgData, 0, j); 6640 j += FULL_CHUNK_HEIGHT; 6641 } 6642 if (i < totalChunks) { 6643 elemsInThisChunk = width * partialChunkHeight * 4; 6644 dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 6645 ctx.putImageData(chunkImgData, 0, j); 6646 } 6647 } else if (imgData.kind === _util.ImageKind.RGB_24BPP) { 6648 thisChunkHeight = FULL_CHUNK_HEIGHT; 6649 elemsInThisChunk = width * thisChunkHeight; 6650 for (i = 0; i < totalChunks; i++) { 6651 if (i >= fullChunks) { 6652 thisChunkHeight = partialChunkHeight; 6653 elemsInThisChunk = width * thisChunkHeight; 6654 } 6655 destPos = 0; 6656 for (j = elemsInThisChunk; j--;) { 6657 dest[destPos++] = src[srcPos++]; 6658 dest[destPos++] = src[srcPos++]; 6659 dest[destPos++] = src[srcPos++]; 6660 dest[destPos++] = 255; 6661 } 6662 ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 6663 } 6664 } else { 6665 throw new Error(`bad image kind: ${imgData.kind}`); 6666 } 6667} 6668function putBinaryImageMask(ctx, imgData) { 6669 if (imgData.bitmap) { 6670 ctx.drawImage(imgData.bitmap, 0, 0); 6671 return; 6672 } 6673 const height = imgData.height, 6674 width = imgData.width; 6675 const partialChunkHeight = height % FULL_CHUNK_HEIGHT; 6676 const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; 6677 const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; 6678 const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); 6679 let srcPos = 0; 6680 const src = imgData.data; 6681 const dest = chunkImgData.data; 6682 for (let i = 0; i < totalChunks; i++) { 6683 const thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight; 6684 ({ 6685 srcPos 6686 } = (0, _image_utils.convertBlackAndWhiteToRGBA)({ 6687 src, 6688 srcPos, 6689 dest, 6690 width, 6691 height: thisChunkHeight, 6692 nonBlackColor: 0 6693 })); 6694 ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 6695 } 6696} 6697function copyCtxState(sourceCtx, destCtx) { 6698 const properties = ["strokeStyle", "fillStyle", "fillRule", "globalAlpha", "lineWidth", "lineCap", "lineJoin", "miterLimit", "globalCompositeOperation", "font", "filter"]; 6699 for (const property of properties) { 6700 if (sourceCtx[property] !== undefined) { 6701 destCtx[property] = sourceCtx[property]; 6702 } 6703 } 6704 if (sourceCtx.setLineDash !== undefined) { 6705 destCtx.setLineDash(sourceCtx.getLineDash()); 6706 destCtx.lineDashOffset = sourceCtx.lineDashOffset; 6707 } 6708} 6709function resetCtxToDefault(ctx) { 6710 ctx.strokeStyle = ctx.fillStyle = "#000000"; 6711 ctx.fillRule = "nonzero"; 6712 ctx.globalAlpha = 1; 6713 ctx.lineWidth = 1; 6714 ctx.lineCap = "butt"; 6715 ctx.lineJoin = "miter"; 6716 ctx.miterLimit = 10; 6717 ctx.globalCompositeOperation = "source-over"; 6718 ctx.font = "10px sans-serif"; 6719 if (ctx.setLineDash !== undefined) { 6720 ctx.setLineDash([]); 6721 ctx.lineDashOffset = 0; 6722 } 6723 if (!_util.isNodeJS) { 6724 const { 6725 filter 6726 } = ctx; 6727 if (filter !== "none" && filter !== "") { 6728 ctx.filter = "none"; 6729 } 6730 } 6731} 6732function composeSMaskBackdrop(bytes, r0, g0, b0) { 6733 const length = bytes.length; 6734 for (let i = 3; i < length; i += 4) {
6735 const alpha = bytes[i]; 6736 if (alpha === 0) { 6737 bytes[i - 3] = r0; 6738 bytes[i - 2] = g0; 6739 bytes[i - 1] = b0; 6740 } else if (alpha < 255) { 6741 const alpha_ = 255 - alpha; 6742 bytes[i - 3] = bytes[i - 3] * alpha + r0 * alpha_ >> 8; 6743 bytes[i - 2] = bytes[i - 2] * alpha + g0 * alpha_ >> 8; 6744 bytes[i - 1] = bytes[i - 1] * alpha + b0 * alpha_ >> 8; 6745 } 6746 } 6747} 6748function composeSMaskAlpha(maskData, layerData, transferMap) { 6749 const length = maskData.length; 6750 const scale = 1 / 255; 6751 for (let i = 3; i < length; i += 4) { 6752 const alpha = transferMap ? transferMap[maskData[i]] : maskData[i]; 6753 layerData[i] = layerData[i] * alpha * scale | 0; 6754 } 6755} 6756function composeSMaskLuminosity(maskData, layerData, transferMap) { 6757 const length = maskData.length; 6758 for (let i = 3; i < length; i += 4) { 6759 const y = maskData[i - 3] * 77 + maskData[i - 2] * 152 + maskData[i - 1] * 28; 6760 layerData[i] = transferMap ? layerData[i] * transferMap[y >> 8] >> 8 : layerData[i] * y >> 16; 6761 } 6762} 6763function genericComposeSMask(maskCtx, layerCtx, width, height, subtype, backdrop, transferMap, layerOffsetX, layerOffsetY, maskOffsetX, maskOffsetY) { 6764 const hasBackdrop = !!backdrop; 6765 const r0 = hasBackdrop ? backdrop[0] : 0; 6766 const g0 = hasBackdrop ? backdrop[1] : 0; 6767 const b0 = hasBackdrop ? backdrop[2] : 0; 6768 const composeFn = subtype === "Luminosity" ? composeSMaskLuminosity : composeSMaskAlpha; 6769 const PIXELS_TO_PROCESS = 1048576; 6770 const chunkSize = Math.min(height, Math.ceil(PIXELS_TO_PROCESS / width)); 6771 for (let row = 0; row < height; row += chunkSize) { 6772 const chunkHeight = Math.min(chunkSize, height - row); 6773 const maskData = maskCtx.getImageData(layerOffsetX - maskOffsetX, row + (layerOffsetY - maskOffsetY), width, chunkHeight); 6774 const layerData = layerCtx.getImageData(layerOffsetX, row + layerOffsetY, width, chunkHeight); 6775 if (hasBackdrop) { 6776 composeSMaskBackdrop(maskData.data, r0, g0, b0); 6777 } 6778 composeFn(maskData.data, layerData.data, transferMap); 6779 layerCtx.putImageData(layerData, layerOffsetX, row + layerOffsetY); 6780 } 6781} 6782function composeSMask(ctx, smask, layerCtx, layerBox) { 6783 const layerOffsetX = layerBox[0]; 6784 const layerOffsetY = layerBox[1]; 6785 const layerWidth = layerBox[2] - layerOffsetX; 6786 const layerHeight = layerBox[3] - layerOffsetY; 6787 if (layerWidth === 0 || layerHeight === 0) { 6788 return; 6789 } 6790 genericComposeSMask(smask.context, layerCtx, layerWidth, layerHeight, smask.subtype, smask.backdrop, smask.transferMap, layerOffsetX, layerOffsetY, smask.offsetX, smask.offsetY); 6791 ctx.save(); 6792 ctx.globalAlpha = 1; 6793 ctx.globalCompositeOperation = "source-over"; 6794 ctx.setTransform(1, 0, 0, 1, 0, 0); 6795 ctx.drawImage(layerCtx.canvas, 0, 0); 6796 ctx.restore(); 6797} 6798function getImageSmoothingEnabled(transform, interpolate) { 6799 const scale = _util.Util.singularValueDecompose2dScale(transform); 6800 scale[0] = Math.fround(scale[0]); 6801 scale[1] = Math.fround(scale[1]); 6802 const actualScale = Math.fround((globalThis.devicePixelRatio || 1) * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS); 6803 if (interpolate !== undefined) { 6804 return interpolate; 6805 } else if (scale[0] <= actualScale || scale[1] <= actualScale) { 6806 return true; 6807 } 6808 return false; 6809} 6810const LINE_CAP_STYLES = ["butt", "round", "square"]; 6811const LINE_JOIN_STYLES = ["miter", "round", "bevel"]; 6812const NORMAL_CLIP = {}; 6813const EO_CLIP = {}; 6814class CanvasGraphics { 6815 constructor(canvasCtx, commonObjs, objs, canvasFactory, filterFactory, { 6816 optionalContentConfig, 6817 markedContentStack = null 6818 }, annotationCanvasMap, pageColors) { 6819 this.ctx = canvasCtx; 6820 this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height); 6821 this.stateStack = []; 6822 this.pendingClip = null; 6823 this.pendingEOFill = false; 6824 this.res = null; 6825 this.xobjs = null; 6826 this.commonObjs = commonObjs; 6827 this.objs = objs; 6828 this.canvasFactory = canvasFactory; 6829 this.filterFactory = filterFactory; 6830 this.groupStack = []; 6831 this.processingType3 = null; 6832 this.baseTransform = null; 6833 this.baseTransformStack = []; 6834 this.groupLevel = 0; 6835 this.smaskStack = []; 6836 this.smaskCounter = 0; 6837 this.tempSMask = null; 6838 this.suspendedCtx = null; 6839 this.contentVisible = true; 6840 this.markedContentStack = markedContentStack || []; 6841 this.optionalContentConfig = optionalContentConfig; 6842 this.cachedCanvases = new CachedCanvases(this.canvasFactory); 6843 this.cachedPatterns = new Map(); 6844 this.annotationCanvasMap = annotationCanvasMap; 6845 this.viewportScale = 1; 6846 this.outputScaleX = 1; 6847 this.outputScaleY = 1;
6848 this.pageColors = pageColors; 6849 this._cachedScaleForStroking = [-1, 0]; 6850 this._cachedGetSinglePixelWidth = null; 6851 this._cachedBitmapsMap = new Map(); 6852 } 6853 getObject(data, fallback = null) { 6854 if (typeof data === "string") { 6855 return data.startsWith("g_") ? this.commonObjs.get(data) : this.objs.get(data); 6856 } 6857 return fallback; 6858 } 6859 beginDrawing({ 6860 transform, 6861 viewport, 6862 transparency = false, 6863 background = null 6864 }) { 6865 const width = this.ctx.canvas.width; 6866 const height = this.ctx.canvas.height; 6867 const savedFillStyle = this.ctx.fillStyle; 6868 this.ctx.fillStyle = background || "#ffffff"; 6869 this.ctx.fillRect(0, 0, width, height); 6870 this.ctx.fillStyle = savedFillStyle; 6871 if (transparency) { 6872 const transparentCanvas = this.cachedCanvases.getCanvas("transparent", width, height); 6873 this.compositeCtx = this.ctx; 6874 this.transparentCanvas = transparentCanvas.canvas; 6875 this.ctx = transparentCanvas.context; 6876 this.ctx.save(); 6877 this.ctx.transform(...(0, _display_utils.getCurrentTransform)(this.compositeCtx)); 6878 } 6879 this.ctx.save(); 6880 resetCtxToDefault(this.ctx); 6881 if (transform) { 6882 this.ctx.transform(...transform); 6883 this.outputScaleX = transform[0]; 6884 this.outputScaleY = transform[0]; 6885 } 6886 this.ctx.transform(...viewport.transform); 6887 this.viewportScale = viewport.scale; 6888 this.baseTransform = (0, _display_utils.getCurrentTransform)(this.ctx); 6889 } 6890 executeOperatorList(operatorList, executionStartIdx, continueCallback, stepper) { 6891 const argsArray = operatorList.argsArray; 6892 const fnArray = operatorList.fnArray; 6893 let i = executionStartIdx || 0; 6894 const argsArrayLen = argsArray.length; 6895 if (argsArrayLen === i) { 6896 return i; 6897 } 6898 const chunkOperations = argsArrayLen - i > EXECUTION_STEPS && typeof continueCallback === "function"; 6899 const endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0; 6900 let steps = 0; 6901 const commonObjs = this.commonObjs; 6902 const objs = this.objs; 6903 let fnId; 6904 while (true) { 6905 if (stepper !== undefined && i === stepper.nextBreakPoint) { 6906 stepper.breakIt(i, continueCallback); 6907 return i; 6908 } 6909 fnId = fnArray[i]; 6910 if (fnId !== _util.OPS.dependency) { 6911 this[fnId].apply(this, argsArray[i]); 6912 } else { 6913 for (const depObjId of argsArray[i]) { 6914 const objsPool = depObjId.startsWith("g_") ? commonObjs : objs; 6915 if (!objsPool.has(depObjId)) { 6916 objsPool.get(depObjId, continueCallback); 6917 return i; 6918 } 6919 } 6920 } 6921 i++; 6922 if (i === argsArrayLen) { 6923 return i; 6924 } 6925 if (chunkOperations && ++steps > EXECUTION_STEPS) { 6926 if (Date.now() > endTime) { 6927 continueCallback(); 6928 return i; 6929 } 6930 steps = 0; 6931 } 6932 } 6933 } 6934 #restoreInitialState() { 6935 while (this.stateStack.length || this.inSMaskMode) { 6936 this.restore(); 6937 } 6938 this.ctx.restore(); 6939 if (this.transparentCanvas) { 6940 this.ctx = this.compositeCtx; 6941 this.ctx.save(); 6942 this.ctx.setTransform(1, 0, 0, 1, 0, 0); 6943 this.ctx.drawImage(this.transparentCanvas, 0, 0); 6944 this.ctx.restore(); 6945 this.transparentCanvas = null; 6946 } 6947 } 6948 endDrawing() { 6949 this.#restoreInitialState(); 6950 this.cachedCanvases.clear(); 6951 this.cachedPatterns.clear(); 6952 for (const cache of this._cachedBitmapsMap.values()) { 6953 for (const canvas of cache.values()) { 6954 if (typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) { 6955 canvas.width = canvas.height = 0; 6956 } 6957 } 6958 cache.clear(); 6959 } 6960 this._cachedBitmapsMap.clear(); 6961 this.#drawFilter(); 6962 } 6963 #drawFilter() { 6964 if (this.pageColors) { 6965 const hcmFilterId = this.filterFactory.addHCMFilter(this.pageColors.foreground, this.pageColors.background); 6966 if (hcmFilterId !== "none") { 6967 const savedFilter = this.ctx.filter; 6968 this.ctx.filter = hcmFilterId; 6969 this.ctx.drawImage(this.ctx.canvas, 0, 0); 6970 this.ctx.filter = savedFilter; 6971 } 6972 } 6973 } 6974 _scaleImage(img, inverseTransform) { 6975 const width = img.width;
6976 const height = img.height; 6977 let widthScale = Math.max(Math.hypot(inverseTransform[0], inverseTransform[1]), 1); 6978 let heightScale = Math.max(Math.hypot(inverseTransform[2], inverseTransform[3]), 1); 6979 let paintWidth = width, 6980 paintHeight = height; 6981 let tmpCanvasId = "prescale1"; 6982 let tmpCanvas, tmpCtx; 6983 while (widthScale > 2 && paintWidth > 1 || heightScale > 2 && paintHeight > 1) { 6984 let newWidth = paintWidth, 6985 newHeight = paintHeight; 6986 if (widthScale > 2 && paintWidth > 1) { 6987 newWidth = paintWidth >= 16384 ? Math.floor(paintWidth / 2) - 1 || 1 : Math.ceil(paintWidth / 2); 6988 widthScale /= paintWidth / newWidth; 6989 } 6990 if (heightScale > 2 && paintHeight > 1) { 6991 newHeight = paintHeight >= 16384 ? Math.floor(paintHeight / 2) - 1 || 1 : Math.ceil(paintHeight) / 2; 6992 heightScale /= paintHeight / newHeight; 6993 } 6994 tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight); 6995 tmpCtx = tmpCanvas.context; 6996 tmpCtx.clearRect(0, 0, newWidth, newHeight); 6997 tmpCtx.drawImage(img, 0, 0, paintWidth, paintHeight, 0, 0, newWidth, newHeight); 6998 img = tmpCanvas.canvas; 6999 paintWidth = newWidth; 7000 paintHeight = newHeight; 7001 tmpCanvasId = tmpCanvasId === "prescale1" ? "prescale2" : "prescale1"; 7002 } 7003 return { 7004 img, 7005 paintWidth, 7006 paintHeight 7007 }; 7008 } 7009 _createMaskCanvas(img) { 7010 const ctx = this.ctx; 7011 const { 7012 width, 7013 height 7014 } = img; 7015 const fillColor = this.current.fillColor; 7016 const isPatternFill = this.current.patternFill; 7017 const currentTransform = (0, _display_utils.getCurrentTransform)(ctx); 7018 let cache, cacheKey, scaled, maskCanvas; 7019 if ((img.bitmap || img.data) && img.count > 1) { 7020 const mainKey = img.bitmap || img.data.buffer; 7021 cacheKey = JSON.stringify(isPatternFill ? currentTransform : [currentTransform.slice(0, 4), fillColor]); 7022 cache = this._cachedBitmapsMap.get(mainKey); 7023 if (!cache) { 7024 cache = new Map(); 7025 this._cachedBitmapsMap.set(mainKey, cache); 7026 } 7027 const cachedImage = cache.get(cacheKey); 7028 if (cachedImage && !isPatternFill) { 7029 const offsetX = Math.round(Math.min(currentTransform[0], currentTransform[2]) + currentTransform[4]); 7030 const offsetY = Math.round(Math.min(currentTransform[1], currentTransform[3]) + currentTransform[5]); 7031 return { 7032 canvas: cachedImage, 7033 offsetX, 7034 offsetY 7035 }; 7036 } 7037 scaled = cachedImage; 7038 } 7039 if (!scaled) { 7040 maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height); 7041 putBinaryImageMask(maskCanvas.context, img); 7042 } 7043 let maskToCanvas = _util.Util.transform(currentTransform, [1 / width, 0, 0, -1 / height, 0, 0]); 7044 maskToCanvas = _util.Util.transform(maskToCanvas, [1, 0, 0, 1, 0, -height]); 7045 const cord1 = _util.Util.applyTransform([0, 0], maskToCanvas); 7046 const cord2 = _util.Util.applyTransform([width, height], maskToCanvas); 7047 const rect = _util.Util.normalizeRect([cord1[0], cord1[1], cord2[0], cord2[1]]); 7048 const drawnWidth = Math.round(rect[2] - rect[0]) || 1; 7049 const drawnHeight = Math.round(rect[3] - rect[1]) || 1; 7050 const fillCanvas = this.cachedCanvases.getCanvas("fillCanvas", drawnWidth, drawnHeight); 7051 const fillCtx = fillCanvas.context; 7052 const offsetX = Math.min(cord1[0], cord2[0]); 7053 const offsetY = Math.min(cord1[1], cord2[1]); 7054 fillCtx.translate(-offsetX, -offsetY); 7055 fillCtx.transform(...maskToCanvas); 7056 if (!scaled) { 7057 scaled = this._scaleImage(maskCanvas.canvas, (0, _display_utils.getCurrentTransformInverse)(fillCtx)); 7058 scaled = scaled.img; 7059 if (cache && isPatternFill) { 7060 cache.set(cacheKey, scaled); 7061 } 7062 } 7063 fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled((0, _display_utils.getCurrentTransform)(fillCtx), img.interpolate); 7064 drawImageAtIntegerCoords(fillCtx, scaled, 0, 0, scaled.width, scaled.height, 0, 0, width, height); 7065 fillCtx.globalCompositeOperation = "source-in"; 7066 const inverse = _util.Util.transform((0, _display_utils.getCurrentTransformInverse)(fillCtx), [1, 0, 0, 1, -offsetX, -offsetY]); 7067 fillCtx.fillStyle = isPatternFill ? fillColor.getPattern(ctx, this, inverse, _pattern_helper.PathType.FILL) : fillColor; 7068 fillCtx.fillRect(0, 0, width, height); 7069 if (cache && !isPatternFill) { 7070 this.cachedCanvases.delete("fillCanvas"); 7071 cache.set(cacheKey, fillCanvas.canvas); 7072 } 7073 return {
7074 canvas: fillCanvas.canvas, 7075 offsetX: Math.round(offsetX), 7076 offsetY: Math.round(offsetY) 7077 }; 7078 } 7079 setLineWidth(width) { 7080 if (width !== this.current.lineWidth) { 7081 this._cachedScaleForStroking[0] = -1; 7082 } 7083 this.current.lineWidth = width; 7084 this.ctx.lineWidth = width; 7085 } 7086 setLineCap(style) { 7087 this.ctx.lineCap = LINE_CAP_STYLES[style]; 7088 } 7089 setLineJoin(style) { 7090 this.ctx.lineJoin = LINE_JOIN_STYLES[style]; 7091 } 7092 setMiterLimit(limit) { 7093 this.ctx.miterLimit = limit; 7094 } 7095 setDash(dashArray, dashPhase) { 7096 const ctx = this.ctx; 7097 if (ctx.setLineDash !== undefined) { 7098 ctx.setLineDash(dashArray); 7099 ctx.lineDashOffset = dashPhase; 7100 } 7101 } 7102 setRenderingIntent(intent) {} 7103 setFlatness(flatness) {} 7104 setGState(states) { 7105 for (const [key, value] of states) { 7106 switch (key) { 7107 case "LW": 7108 this.setLineWidth(value); 7109 break; 7110 case "LC": 7111 this.setLineCap(value); 7112 break; 7113 case "LJ": 7114 this.setLineJoin(value); 7115 break; 7116 case "ML": 7117 this.setMiterLimit(value); 7118 break; 7119 case "D": 7120 this.setDash(value[0], value[1]); 7121 break; 7122 case "RI": 7123 this.setRenderingIntent(value); 7124 break; 7125 case "FL": 7126 this.setFlatness(value); 7127 break; 7128 case "Font": 7129 this.setFont(value[0], value[1]); 7130 break; 7131 case "CA": 7132 this.current.strokeAlpha = value; 7133 break; 7134 case "ca": 7135 this.current.fillAlpha = value; 7136 this.ctx.globalAlpha = value; 7137 break; 7138 case "BM": 7139 this.ctx.globalCompositeOperation = value; 7140 break; 7141 case "SMask": 7142 this.current.activeSMask = value ? this.tempSMask : null; 7143 this.tempSMask = null; 7144 this.checkSMaskState(); 7145 break; 7146 case "TR": 7147 this.ctx.filter = this.current.transferMaps = this.filterFactory.addFilter(value); 7148 break; 7149 } 7150 } 7151 } 7152 get inSMaskMode() { 7153 return !!this.suspendedCtx; 7154 } 7155 checkSMaskState() { 7156 const inSMaskMode = this.inSMaskMode; 7157 if (this.current.activeSMask && !inSMaskMode) { 7158 this.beginSMaskMode(); 7159 } else if (!this.current.activeSMask && inSMaskMode) { 7160 this.endSMaskMode(); 7161 } 7162 } 7163 beginSMaskMode() { 7164 if (this.inSMaskMode) { 7165 throw new Error("beginSMaskMode called while already in smask mode"); 7166 } 7167 const drawnWidth = this.ctx.canvas.width; 7168 const drawnHeight = this.ctx.canvas.height; 7169 const cacheId = "smaskGroupAt" + this.groupLevel; 7170 const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight); 7171 this.suspendedCtx = this.ctx; 7172 this.ctx = scratchCanvas.context; 7173 const ctx = this.ctx; 7174 ctx.setTransform(...(0, _display_utils.getCurrentTransform)(this.suspendedCtx)); 7175 copyCtxState(this.suspendedCtx, ctx); 7176 mirrorContextOperations(ctx, this.suspendedCtx); 7177 this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]); 7178 } 7179 endSMaskMode() { 7180 if (!this.inSMaskMode) { 7181 throw new Error("endSMaskMode called while not in smask mode"); 7182 } 7183 this.ctx._removeMirroring(); 7184 copyCtxState(this.ctx, this.suspendedCtx); 7185 this.ctx = this.suspendedCtx; 7186 this.suspendedCtx = null; 7187 } 7188 compose(dirtyBox) { 7189 if (!this.current.activeSMask) { 7190 return; 7191 } 7192 if (!dirtyBox) { 7193 dirtyBox = [0, 0, this.ctx.canvas.width, this.ctx.canvas.height]; 7194 } else { 7195 dirtyBox[0] = Math.floor(dirtyBox[0]); 7196 dirtyBox[1] = Math.floor(dirtyBox[1]); 7197 dirtyBox[2] = Math.ceil(dirtyBox[2]); 7198 dirtyBox[3] = Math.ceil(dirtyBox[3]); 7199 } 7200 const smask = this.current.activeSMask; 7201 const suspendedCtx = this.suspendedCtx; 7202 composeSMask(suspendedCtx, smask, this.ctx, dirtyBox); 7203 this.ctx.save(); 7204 this.ctx.setTransform(1, 0, 0, 1, 0, 0); 7205 this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height); 7206 this.ctx.restore(); 7207 } 7208 save() { 7209 if (this.inSMaskMode) { 7210 copyCtxState(this.ctx, this.suspendedCtx); 7211 this.suspendedCtx.save(); 7212 } else { 7213 this.ctx.save(); 7214 } 7215 const old = this.current; 7216 this.stateStack.push(old); 7217 this.current = old.clone(); 7218 }
7219 restore() { 7220 if (this.stateStack.length === 0 && this.inSMaskMode) { 7221 this.endSMaskMode(); 7222 } 7223 if (this.stateStack.length !== 0) { 7224 this.current = this.stateStack.pop(); 7225 if (this.inSMaskMode) { 7226 this.suspendedCtx.restore(); 7227 copyCtxState(this.suspendedCtx, this.ctx); 7228 } else { 7229 this.ctx.restore(); 7230 } 7231 this.checkSMaskState(); 7232 this.pendingClip = null; 7233 this._cachedScaleForStroking[0] = -1; 7234 this._cachedGetSinglePixelWidth = null; 7235 } 7236 } 7237 transform(a, b, c, d, e, f) { 7238 this.ctx.transform(a, b, c, d, e, f); 7239 this._cachedScaleForStroking[0] = -1; 7240 this._cachedGetSinglePixelWidth = null; 7241 } 7242 constructPath(ops, args, minMax) { 7243 const ctx = this.ctx; 7244 const current = this.current; 7245 let x = current.x, 7246 y = current.y; 7247 let startX, startY; 7248 const currentTransform = (0, _display_utils.getCurrentTransform)(ctx); 7249 const isScalingMatrix = currentTransform[0] === 0 && currentTransform[3] === 0 || currentTransform[1] === 0 && currentTransform[2] === 0; 7250 const minMaxForBezier = isScalingMatrix ? minMax.slice(0) : null; 7251 for (let i = 0, j = 0, ii = ops.length; i < ii; i++) { 7252 switch (ops[i] | 0) { 7253 case _util.OPS.rectangle: 7254 x = args[j++]; 7255 y = args[j++]; 7256 const width = args[j++]; 7257 const height = args[j++]; 7258 const xw = x + width; 7259 const yh = y + height; 7260 ctx.moveTo(x, y); 7261 if (width === 0 || height === 0) { 7262 ctx.lineTo(xw, yh); 7263 } else { 7264 ctx.lineTo(xw, y); 7265 ctx.lineTo(xw, yh); 7266 ctx.lineTo(x, yh); 7267 } 7268 if (!isScalingMatrix) { 7269 current.updateRectMinMax(currentTransform, [x, y, xw, yh]); 7270 } 7271 ctx.closePath(); 7272 break; 7273 case _util.OPS.moveTo: 7274 x = args[j++]; 7275 y = args[j++]; 7276 ctx.moveTo(x, y); 7277 if (!isScalingMatrix) { 7278 current.updatePathMinMax(currentTransform, x, y); 7279 } 7280 break; 7281 case _util.OPS.lineTo: 7282 x = args[j++]; 7283 y = args[j++]; 7284 ctx.lineTo(x, y); 7285 if (!isScalingMatrix) { 7286 current.updatePathMinMax(currentTransform, x, y); 7287 } 7288 break; 7289 case _util.OPS.curveTo: 7290 startX = x; 7291 startY = y; 7292 x = args[j + 4]; 7293 y = args[j + 5]; 7294 ctx.bezierCurveTo(args[j], args[j + 1], args[j + 2], args[j + 3], x, y); 7295 current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], args[j + 2], args[j + 3], x, y, minMaxForBezier); 7296 j += 6; 7297 break; 7298 case _util.OPS.curveTo2: 7299 startX = x; 7300 startY = y; 7301 ctx.bezierCurveTo(x, y, args[j], args[j + 1], args[j + 2], args[j + 3]); 7302 current.updateCurvePathMinMax(currentTransform, startX, startY, x, y, args[j], args[j + 1], args[j + 2], args[j + 3], minMaxForBezier); 7303 x = args[j + 2]; 7304 y = args[j + 3]; 7305 j += 4; 7306 break; 7307 case _util.OPS.curveTo3: 7308 startX = x; 7309 startY = y; 7310 x = args[j + 2]; 7311 y = args[j + 3]; 7312 ctx.bezierCurveTo(args[j], args[j + 1], x, y, x, y); 7313 current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], x, y, x, y, minMaxForBezier); 7314 j += 4; 7315 break; 7316 case _util.OPS.closePath: 7317 ctx.closePath(); 7318 break; 7319 } 7320 } 7321 if (isScalingMatrix) { 7322 current.updateScalingPathMinMax(currentTransform, minMaxForBezier); 7323 } 7324 current.setCurrentPoint(x, y); 7325 } 7326 closePath() { 7327 this.ctx.closePath(); 7328 }
7329 stroke(consumePath = true) { 7330 const ctx = this.ctx; 7331 const strokeColor = this.current.strokeColor; 7332 ctx.globalAlpha = this.current.strokeAlpha; 7333 if (this.contentVisible) { 7334 if (typeof strokeColor === "object" && strokeColor?.getPattern) { 7335 ctx.save(); 7336 ctx.strokeStyle = strokeColor.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.STROKE); 7337 this.rescaleAndStroke(false); 7338 ctx.restore(); 7339 } else { 7340 this.rescaleAndStroke(true); 7341 } 7342 } 7343 if (consumePath) { 7344 this.consumePath(this.current.getClippedPathBoundingBox()); 7345 } 7346 ctx.globalAlpha = this.current.fillAlpha; 7347 } 7348 closeStroke() { 7349 this.closePath(); 7350 this.stroke(); 7351 } 7352 fill(consumePath = true) { 7353 const ctx = this.ctx; 7354 const fillColor = this.current.fillColor; 7355 const isPatternFill = this.current.patternFill; 7356 let needRestore = false; 7357 if (isPatternFill) { 7358 ctx.save(); 7359 ctx.fillStyle = fillColor.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.FILL); 7360 needRestore = true; 7361 } 7362 const intersect = this.current.getClippedPathBoundingBox(); 7363 if (this.contentVisible && intersect !== null) { 7364 if (this.pendingEOFill) { 7365 ctx.fill("evenodd"); 7366 this.pendingEOFill = false; 7367 } else { 7368 ctx.fill(); 7369 } 7370 } 7371 if (needRestore) { 7372 ctx.restore(); 7373 } 7374 if (consumePath) { 7375 this.consumePath(intersect); 7376 } 7377 } 7378 eoFill() { 7379 this.pendingEOFill = true; 7380 this.fill(); 7381 } 7382 fillStroke() { 7383 this.fill(false); 7384 this.stroke(false); 7385 this.consumePath(); 7386 } 7387 eoFillStroke() { 7388 this.pendingEOFill = true; 7389 this.fillStroke(); 7390 } 7391 closeFillStroke() { 7392 this.closePath(); 7393 this.fillStroke(); 7394 } 7395 closeEOFillStroke() { 7396 this.pendingEOFill = true; 7397 this.closePath(); 7398 this.fillStroke(); 7399 } 7400 endPath() { 7401 this.consumePath(); 7402 } 7403 clip() { 7404 this.pendingClip = NORMAL_CLIP; 7405 } 7406 eoClip() { 7407 this.pendingClip = EO_CLIP; 7408 } 7409 beginText() { 7410 this.current.textMatrix = _util.IDENTITY_MATRIX; 7411 this.current.textMatrixScale = 1; 7412 this.current.x = this.current.lineX = 0; 7413 this.current.y = this.current.lineY = 0; 7414 } 7415 endText() { 7416 const paths = this.pendingTextPaths; 7417 const ctx = this.ctx; 7418 if (paths === undefined) { 7419 ctx.beginPath(); 7420 return; 7421 } 7422 ctx.save(); 7423 ctx.beginPath(); 7424 for (const path of paths) { 7425 ctx.setTransform(...path.transform); 7426 ctx.translate(path.x, path.y); 7427 path.addToPath(ctx, path.fontSize); 7428 } 7429 ctx.restore(); 7430 ctx.clip(); 7431 ctx.beginPath(); 7432 delete this.pendingTextPaths; 7433 } 7434 setCharSpacing(spacing) { 7435 this.current.charSpacing = spacing; 7436 } 7437 setWordSpacing(spacing) { 7438 this.current.wordSpacing = spacing; 7439 } 7440 setHScale(scale) { 7441 this.current.textHScale = scale / 100; 7442 } 7443 setLeading(leading) { 7444 this.current.leading = -leading; 7445 } 7446 setFont(fontRefName, size) { 7447 const fontObj = this.commonObjs.get(fontRefName); 7448 const current = this.current; 7449 if (!fontObj) { 7450 throw new Error(`Can't find font for ${fontRefName}`); 7451 } 7452 current.fontMatrix = fontObj.fontMatrix || _util.FONT_IDENTITY_MATRIX; 7453 if (current.fontMatrix[0] === 0 || current.fontMatrix[3] === 0) { 7454 (0, _util.warn)("Invalid font matrix for font " + fontRefName); 7455 } 7456 if (size < 0) { 7457 size = -size; 7458 current.fontDirection = -1; 7459 } else { 7460 current.fontDirection = 1; 7461 } 7462 this.current.font = fontObj; 7463 this.current.fontSize = size; 7464 if (fontObj.isType3Font) { 7465 return; 7466 } 7467 const name = fontObj.loadedName || "sans-serif"; 7468 const typeface = fontObj.systemFontInfo?.css || `"${name}", ${fontObj.fallbackName}`; 7469 let bold = "normal"; 7470 if (fontObj.black) { 7471 bold = "900"; 7472 } else if (fontObj.bold) { 7473 bold = "bold"; 7474 } 7475 const italic = fontObj.italic ? "italic" : "normal"; 7476 let browserFontSize = size; 7477 if (size < MIN_FONT_SIZE) { 7478 browserFontSize = MIN_FONT_SIZE; 7479 } else if (size > MAX_FONT_SIZE) { 7480 browserFontSize = MAX_FONT_SIZE; 7481 } 7482 this.current.fontSizeScale = size / browserFontSize; 7483 this.ctx.font = `${italic} ${bold} ${browserFontSize}px ${typeface}`; 7484 } 7485 setTextRenderingMode(mode) { 7486 this.current.textRenderingMode = mode; 7487 } 7488 setTextRise(rise) { 7489 this.current.textRise = rise; 7490 } 7491 moveText(x, y) { 7492 this.current.x = this.current.lineX += x; 7493 this.current.y = this.current.lineY += y; 7494 } 7495 setLeadingMoveText(x, y) { 7496 this.setLeading(-y); 7497 this.moveText(x, y); 7498 } 7499 setTextMatrix(a, b, c, d, e, f) { 7500 this.current.textMatrix = [a, b, c, d, e, f]; 7501 this.current.textMatrixScale = Math.hypot(a, b); 7502 this.current.x = this.current.lineX = 0; 7503 this.current.y = this.current.lineY = 0; 7504 } 7505 nextLine() { 7506 this.moveText(0, this.current.leading); 7507 } 7508 paintChar(character, x, y, patternTransform) { 7509 const ctx = this.ctx; 7510 const current = this.current; 7511 const font = current.font; 7512 const textRenderingMode = current.textRenderingMode; 7513 const fontSize = current.fontSize / current.fontSizeScale; 7514 const fillStrokeMode = textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; 7515 const isAddToPathSet = !!(textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG); 7516 const patternFill = current.patternFill && !font.missingFile; 7517 let addToPath; 7518 if (font.disableFontFace || isAddToPathSet || patternFill) { 7519 addToPath = font.getPathGenerator(this.commonObjs, character); 7520 } 7521 if (font.disableFontFace || patternFill) { 7522 ctx.save(); 7523 ctx.translate(x, y); 7524 ctx.beginPath(); 7525 addToPath(ctx, fontSize); 7526 if (patternTransform) { 7527 ctx.setTransform(...patternTransform); 7528 } 7529 if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7530 ctx.fill(); 7531 } 7532 if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7533 ctx.stroke(); 7534 }
7535 ctx.restore(); 7536 } else { 7537 if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7538 ctx.fillText(character, x, y); 7539 } 7540 if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7541 ctx.strokeText(character, x, y); 7542 } 7543 } 7544 if (isAddToPathSet) { 7545 const paths = this.pendingTextPaths ||= []; 7546 paths.push({ 7547 transform: (0, _display_utils.getCurrentTransform)(ctx), 7548 x, 7549 y, 7550 fontSize, 7551 addToPath 7552 }); 7553 } 7554 } 7555 get isFontSubpixelAAEnabled() { 7556 const { 7557 context: ctx 7558 } = this.cachedCanvases.getCanvas("isFontSubpixelAAEnabled", 10, 10); 7559 ctx.scale(1.5, 1); 7560 ctx.fillText("I", 0, 10); 7561 const data = ctx.getImageData(0, 0, 10, 10).data; 7562 let enabled = false; 7563 for (let i = 3; i < data.length; i += 4) { 7564 if (data[i] > 0 && data[i] < 255) { 7565 enabled = true; 7566 break; 7567 } 7568 } 7569 return (0, _util.shadow)(this, "isFontSubpixelAAEnabled", enabled); 7570 } 7571 showText(glyphs) { 7572 const current = this.current; 7573 const font = current.font; 7574 if (font.isType3Font) { 7575 return this.showType3Text(glyphs); 7576 } 7577 const fontSize = current.fontSize; 7578 if (fontSize === 0) { 7579 return undefined; 7580 } 7581 const ctx = this.ctx; 7582 const fontSizeScale = current.fontSizeScale; 7583 const charSpacing = current.charSpacing; 7584 const wordSpacing = current.wordSpacing; 7585 const fontDirection = current.fontDirection; 7586 const textHScale = current.textHScale * fontDirection; 7587 const glyphsLength = glyphs.length; 7588 const vertical = font.vertical; 7589 const spacingDir = vertical ? 1 : -1; 7590 const defaultVMetrics = font.defaultVMetrics; 7591 const widthAdvanceScale = fontSize * current.fontMatrix[0]; 7592 const simpleFillText = current.textRenderingMode === _util.TextRenderingMode.FILL && !font.disableFontFace && !current.patternFill; 7593 ctx.save(); 7594 ctx.transform(...current.textMatrix); 7595 ctx.translate(current.x, current.y + current.textRise); 7596 if (fontDirection > 0) { 7597 ctx.scale(textHScale, -1); 7598 } else { 7599 ctx.scale(textHScale, 1); 7600 } 7601 let patternTransform; 7602 if (current.patternFill) { 7603 ctx.save(); 7604 const pattern = current.fillColor.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.FILL); 7605 patternTransform = (0, _display_utils.getCurrentTransform)(ctx); 7606 ctx.restore(); 7607 ctx.fillStyle = pattern; 7608 } 7609 let lineWidth = current.lineWidth; 7610 const scale = current.textMatrixScale; 7611 if (scale === 0 || lineWidth === 0) { 7612 const fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; 7613 if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7614 lineWidth = this.getSinglePixelWidth(); 7615 } 7616 } else { 7617 lineWidth /= scale; 7618 } 7619 if (fontSizeScale !== 1.0) { 7620 ctx.scale(fontSizeScale, fontSizeScale); 7621 lineWidth /= fontSizeScale; 7622 } 7623 ctx.lineWidth = lineWidth; 7624 if (font.isInvalidPDFjsFont) { 7625 const chars = []; 7626 let width = 0; 7627 for (const glyph of glyphs) { 7628 chars.push(glyph.unicode); 7629 width += glyph.width; 7630 } 7631 ctx.fillText(chars.join(""), 0, 0); 7632 current.x += width * widthAdvanceScale * textHScale; 7633 ctx.restore(); 7634 this.compose(); 7635 return undefined; 7636 } 7637 let x = 0, 7638 i; 7639 for (i = 0; i < glyphsLength; ++i) { 7640 const glyph = glyphs[i];
vendor: 3,295 bytes, lines 7641-7725
7641 if (typeof glyph === "number") { 7642 x += spacingDir * glyph * fontSize / 1000; 7643 continue; 7644 } 7645 let restoreNeeded = false; 7646 const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 7647 const character = glyph.fontChar; 7648 const accent = glyph.accent; 7649 let scaledX, scaledY; 7650 let width = glyph.width; 7651 if (vertical) { 7652 const vmetric = glyph.vmetric || defaultVMetrics; 7653 const vx = -(glyph.vmetric ? vmetric[1] : width * 0.5) * widthAdvanceScale; 7654 const vy = vmetric[2] * widthAdvanceScale; 7655 width = vmetric ? -vmetric[0] : width; 7656 scaledX = vx / fontSizeScale; 7657 scaledY = (x + vy) / fontSizeScale; 7658 } else { 7659 scaledX = x / fontSizeScale; 7660 scaledY = 0; 7661 } 7662 if (font.remeasure && width > 0) { 7663 const measuredWidth = ctx.measureText(character).width * 1000 / fontSize * fontSizeScale; 7664 if (width < measuredWidth && this.isFontSubpixelAAEnabled) { 7665 const characterScaleX = width / measuredWidth; 7666 restoreNeeded = true; 7667 ctx.save(); 7668 ctx.scale(characterScaleX, 1); 7669 scaledX /= characterScaleX; 7670 } else if (width !== measuredWidth) { 7671 scaledX += (width - measuredWidth) / 2000 * fontSize / fontSizeScale; 7672 } 7673 } 7674 if (this.contentVisible && (glyph.isInFont || font.missingFile)) { 7675 if (simpleFillText && !accent) { 7676 ctx.fillText(character, scaledX, scaledY); 7677 } else { 7678 this.paintChar(character, scaledX, scaledY, patternTransform); 7679 if (accent) { 7680 const scaledAccentX = scaledX + fontSize * accent.offset.x / fontSizeScale; 7681 const scaledAccentY = scaledY - fontSize * accent.offset.y / fontSizeScale; 7682 this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY, patternTransform); 7683 } 7684 } 7685 } 7686 const charWidth = vertical ? width * widthAdvanceScale - spacing * fontDirection : width * widthAdvanceScale + spacing * fontDirection; 7687 x += charWidth; 7688 if (restoreNeeded) { 7689 ctx.restore(); 7690 } 7691 } 7692 if (vertical) { 7693 current.y -= x; 7694 } else { 7695 current.x += x * textHScale; 7696 } 7697 ctx.restore(); 7698 this.compose(); 7699 return undefined; 7700 } 7701 showType3Text(glyphs) { 7702 const ctx = this.ctx; 7703 const current = this.current; 7704 const font = current.font; 7705 const fontSize = current.fontSize; 7706 const fontDirection = current.fontDirection; 7707 const spacingDir = font.vertical ? 1 : -1; 7708 const charSpacing = current.charSpacing; 7709 const wordSpacing = current.wordSpacing; 7710 const textHScale = current.textHScale * fontDirection; 7711 const fontMatrix = current.fontMatrix || _util.FONT_IDENTITY_MATRIX; 7712 const glyphsLength = glyphs.length; 7713 const isTextInvisible = current.textRenderingMode === _util.TextRenderingMode.INVISIBLE; 7714 let i, glyph, width, spacingLength; 7715 if (isTextInvisible || fontSize === 0) { 7716 return; 7717 } 7718 this._cachedScaleForStroking[0] = -1; 7719 this._cachedGetSinglePixelWidth = null; 7720 ctx.save(); 7721 ctx.transform(...current.textMatrix); 7722 ctx.translate(current.x, current.y); 7723 ctx.scale(textHScale, fontDirection); 7724 for (i = 0; i < glyphsLength; ++i) { 7725 glyph = glyphs[i];
7726 if (typeof glyph === "number") { 7727 spacingLength = spacingDir * glyph * fontSize / 1000; 7728 this.ctx.translate(spacingLength, 0); 7729 current.x += spacingLength * textHScale; 7730 continue; 7731 } 7732 const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 7733 const operatorList = font.charProcOperatorList[glyph.operatorListId]; 7734 if (!operatorList) { 7735 (0, _util.warn)(`Type3 character "${glyph.operatorListId}" is not available.`); 7736 continue; 7737 } 7738 if (this.contentVisible) { 7739 this.processingType3 = glyph; 7740 this.save(); 7741 ctx.scale(fontSize, fontSize); 7742 ctx.transform(...fontMatrix); 7743 this.executeOperatorList(operatorList); 7744 this.restore(); 7745 } 7746 const transformed = _util.Util.applyTransform([glyph.width, 0], fontMatrix); 7747 width = transformed[0] * fontSize + spacing; 7748 ctx.translate(width, 0); 7749 current.x += width * textHScale; 7750 } 7751 ctx.restore(); 7752 this.processingType3 = null; 7753 } 7754 setCharWidth(xWidth, yWidth) {} 7755 setCharWidthAndBounds(xWidth, yWidth, llx, lly, urx, ury) { 7756 this.ctx.rect(llx, lly, urx - llx, ury - lly); 7757 this.ctx.clip(); 7758 this.endPath(); 7759 } 7760 getColorN_Pattern(IR) { 7761 let pattern; 7762 if (IR[0] === "TilingPattern") { 7763 const color = IR[1]; 7764 const baseTransform = this.baseTransform || (0, _display_utils.getCurrentTransform)(this.ctx); 7765 const canvasGraphicsFactory = { 7766 createCanvasGraphics: ctx => { 7767 return new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory, this.filterFactory, { 7768 optionalContentConfig: this.optionalContentConfig, 7769 markedContentStack: this.markedContentStack 7770 }); 7771 } 7772 }; 7773 pattern = new _pattern_helper.TilingPattern(IR, color, this.ctx, canvasGraphicsFactory, baseTransform); 7774 } else { 7775 pattern = this._getPattern(IR[1], IR[2]); 7776 } 7777 return pattern; 7778 } 7779 setStrokeColorN() { 7780 this.current.strokeColor = this.getColorN_Pattern(arguments); 7781 } 7782 setFillColorN() { 7783 this.current.fillColor = this.getColorN_Pattern(arguments); 7784 this.current.patternFill = true; 7785 } 7786 setStrokeRGBColor(r, g, b) { 7787 const color = _util.Util.makeHexColor(r, g, b); 7788 this.ctx.strokeStyle = color; 7789 this.current.strokeColor = color; 7790 } 7791 setFillRGBColor(r, g, b) { 7792 const color = _util.Util.makeHexColor(r, g, b); 7793 this.ctx.fillStyle = color; 7794 this.current.fillColor = color; 7795 this.current.patternFill = false; 7796 } 7797 _getPattern(objId, matrix = null) { 7798 let pattern; 7799 if (this.cachedPatterns.has(objId)) { 7800 pattern = this.cachedPatterns.get(objId); 7801 } else { 7802 pattern = (0, _pattern_helper.getShadingPattern)(this.getObject(objId)); 7803 this.cachedPatterns.set(objId, pattern); 7804 } 7805 if (matrix) { 7806 pattern.matrix = matrix; 7807 } 7808 return pattern; 7809 } 7810 shadingFill(objId) { 7811 if (!this.contentVisible) { 7812 return; 7813 } 7814 const ctx = this.ctx; 7815 this.save(); 7816 const pattern = this._getPattern(objId); 7817 ctx.fillStyle = pattern.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.SHADING); 7818 const inv = (0, _display_utils.getCurrentTransformInverse)(ctx); 7819 if (inv) { 7820 const { 7821 width, 7822 height 7823 } = ctx.canvas; 7824 const [x0, y0, x1, y1] = _util.Util.getAxialAlignedBoundingBox([0, 0, width, height], inv); 7825 this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0); 7826 } else { 7827 this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10); 7828 } 7829 this.compose(this.current.getClippedPathBoundingBox()); 7830 this.restore(); 7831 } 7832 beginInlineImage() { 7833 (0, _util.unreachable)("Should not call beginInlineImage"); 7834 } 7835 beginImageData() { 7836 (0, _util.unreachable)("Should not call beginImageData"); 7837 } 7838 paintFormXObjectBegin(matrix, bbox) { 7839 if (!this.contentVisible) { 7840 return; 7841 } 7842 this.save(); 7843 this.baseTransformStack.push(this.baseTransform); 7844 if (Array.isArray(matrix) && matrix.length === 6) { 7845 this.transform(...matrix); 7846 } 7847 this.baseTransform = (0, _display_utils.getCurrentTransform)(this.ctx); 7848 if (bbox) { 7849 const width = bbox[2] - bbox[0]; 7850 const height = bbox[3] - bbox[1]; 7851 this.ctx.rect(bbox[0], bbox[1], width, height); 7852 this.current.updateRectMinMax((0, _display_utils.getCurrentTransform)(this.ctx), bbox); 7853 this.clip(); 7854 this.endPath(); 7855 } 7856 } 7857 paintFormXObjectEnd() { 7858 if (!this.contentVisible) { 7859 return; 7860 }
7861 this.restore(); 7862 this.baseTransform = this.baseTransformStack.pop(); 7863 } 7864 beginGroup(group) { 7865 if (!this.contentVisible) { 7866 return; 7867 } 7868 this.save(); 7869 if (this.inSMaskMode) { 7870 this.endSMaskMode(); 7871 this.current.activeSMask = null; 7872 } 7873 const currentCtx = this.ctx; 7874 if (!group.isolated) { 7875 (0, _util.info)("TODO: Support non-isolated groups."); 7876 } 7877 if (group.knockout) { 7878 (0, _util.warn)("Knockout groups not supported."); 7879 } 7880 const currentTransform = (0, _display_utils.getCurrentTransform)(currentCtx); 7881 if (group.matrix) { 7882 currentCtx.transform(...group.matrix); 7883 } 7884 if (!group.bbox) { 7885 throw new Error("Bounding box is required."); 7886 } 7887 let bounds = _util.Util.getAxialAlignedBoundingBox(group.bbox, (0, _display_utils.getCurrentTransform)(currentCtx)); 7888 const canvasBounds = [0, 0, currentCtx.canvas.width, currentCtx.canvas.height]; 7889 bounds = _util.Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0]; 7890 const offsetX = Math.floor(bounds[0]); 7891 const offsetY = Math.floor(bounds[1]); 7892 let drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1); 7893 let drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1); 7894 let scaleX = 1, 7895 scaleY = 1; 7896 if (drawnWidth > MAX_GROUP_SIZE) { 7897 scaleX = drawnWidth / MAX_GROUP_SIZE; 7898 drawnWidth = MAX_GROUP_SIZE; 7899 } 7900 if (drawnHeight > MAX_GROUP_SIZE) { 7901 scaleY = drawnHeight / MAX_GROUP_SIZE; 7902 drawnHeight = MAX_GROUP_SIZE; 7903 } 7904 this.current.startNewPathAndClipBox([0, 0, drawnWidth, drawnHeight]); 7905 let cacheId = "groupAt" + this.groupLevel; 7906 if (group.smask) { 7907 cacheId += "_smask_" + this.smaskCounter++ % 2; 7908 } 7909 const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight); 7910 const groupCtx = scratchCanvas.context; 7911 groupCtx.scale(1 / scaleX, 1 / scaleY); 7912 groupCtx.translate(-offsetX, -offsetY); 7913 groupCtx.transform(...currentTransform); 7914 if (group.smask) { 7915 this.smaskStack.push({ 7916 canvas: scratchCanvas.canvas, 7917 context: groupCtx, 7918 offsetX, 7919 offsetY, 7920 scaleX, 7921 scaleY, 7922 subtype: group.smask.subtype, 7923 backdrop: group.smask.backdrop, 7924 transferMap: group.smask.transferMap || null, 7925 startTransformInverse: null 7926 }); 7927 } else { 7928 currentCtx.setTransform(1, 0, 0, 1, 0, 0); 7929 currentCtx.translate(offsetX, offsetY); 7930 currentCtx.scale(scaleX, scaleY); 7931 currentCtx.save(); 7932 } 7933 copyCtxState(currentCtx, groupCtx); 7934 this.ctx = groupCtx; 7935 this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]); 7936 this.groupStack.push(currentCtx); 7937 this.groupLevel++; 7938 } 7939 endGroup(group) { 7940 if (!this.contentVisible) { 7941 return; 7942 } 7943 this.groupLevel--; 7944 const groupCtx = this.ctx; 7945 const ctx = this.groupStack.pop(); 7946 this.ctx = ctx; 7947 this.ctx.imageSmoothingEnabled = false; 7948 if (group.smask) { 7949 this.tempSMask = this.smaskStack.pop(); 7950 this.restore(); 7951 } else { 7952 this.ctx.restore(); 7953 const currentMtx = (0, _display_utils.getCurrentTransform)(this.ctx); 7954 this.restore(); 7955 this.ctx.save(); 7956 this.ctx.setTransform(...currentMtx); 7957 const dirtyBox = _util.Util.getAxialAlignedBoundingBox([0, 0, groupCtx.canvas.width, groupCtx.canvas.height], currentMtx); 7958 this.ctx.drawImage(groupCtx.canvas, 0, 0); 7959 this.ctx.restore(); 7960 this.compose(dirtyBox); 7961 } 7962 } 7963 beginAnnotation(id, rect, transform, matrix, hasOwnCanvas) { 7964 this.#restoreInitialState(); 7965 resetCtxToDefault(this.ctx); 7966 this.ctx.save(); 7967 this.save(); 7968 if (this.baseTransform) { 7969 this.ctx.setTransform(...this.baseTransform); 7970 } 7971 if (Array.isArray(rect) && rect.length === 4) { 7972 const width = rect[2] - rect[0]; 7973 const height = rect[3] - rect[1]; 7974 if (hasOwnCanvas && this.annotationCanvasMap) { 7975 transform = transform.slice(); 7976 transform[4] -= rect[0]; 7977 transform[5] -= rect[1]; 7978 rect = rect.slice(); 7979 rect[0] = rect[1] = 0; 7980 rect[2] = width; 7981 rect[3] = height; 7982 const [scaleX, scaleY] = _util.Util.singularValueDecompose2dScale((0, _display_utils.getCurrentTransform)(this.ctx)); 7983 const { 7984 viewportScale 7985 } = this; 7986 const canvasWidth = Math.ceil(width * this.outputScaleX * viewportScale);
7987 const canvasHeight = Math.ceil(height * this.outputScaleY * viewportScale); 7988 this.annotationCanvas = this.canvasFactory.create(canvasWidth, canvasHeight); 7989 const { 7990 canvas, 7991 context 7992 } = this.annotationCanvas; 7993 this.annotationCanvasMap.set(id, canvas); 7994 this.annotationCanvas.savedCtx = this.ctx; 7995 this.ctx = context; 7996 this.ctx.save(); 7997 this.ctx.setTransform(scaleX, 0, 0, -scaleY, 0, height * scaleY); 7998 resetCtxToDefault(this.ctx); 7999 } else { 8000 resetCtxToDefault(this.ctx); 8001 this.ctx.rect(rect[0], rect[1], width, height); 8002 this.ctx.clip(); 8003 this.endPath(); 8004 } 8005 } 8006 this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height); 8007 this.transform(...transform); 8008 this.transform(...matrix); 8009 } 8010 endAnnotation() { 8011 if (this.annotationCanvas) { 8012 this.ctx.restore(); 8013 this.#drawFilter(); 8014 this.ctx = this.annotationCanvas.savedCtx; 8015 delete this.annotationCanvas.savedCtx; 8016 delete this.annotationCanvas; 8017 } 8018 } 8019 paintImageMaskXObject(img) { 8020 if (!this.contentVisible) { 8021 return; 8022 } 8023 const count = img.count; 8024 img = this.getObject(img.data, img); 8025 img.count = count; 8026 const ctx = this.ctx; 8027 const glyph = this.processingType3; 8028 if (glyph) { 8029 if (glyph.compiled === undefined) { 8030 glyph.compiled = compileType3Glyph(img); 8031 } 8032 if (glyph.compiled) { 8033 glyph.compiled(ctx); 8034 return; 8035 } 8036 } 8037 const mask = this._createMaskCanvas(img); 8038 const maskCanvas = mask.canvas; 8039 ctx.save(); 8040 ctx.setTransform(1, 0, 0, 1, 0, 0); 8041 ctx.drawImage(maskCanvas, mask.offsetX, mask.offsetY); 8042 ctx.restore(); 8043 this.compose(); 8044 } 8045 paintImageMaskXObjectRepeat(img, scaleX, skewX = 0, skewY = 0, scaleY, positions) { 8046 if (!this.contentVisible) { 8047 return; 8048 } 8049 img = this.getObject(img.data, img); 8050 const ctx = this.ctx; 8051 ctx.save(); 8052 const currentTransform = (0, _display_utils.getCurrentTransform)(ctx); 8053 ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0); 8054 const mask = this._createMaskCanvas(img); 8055 ctx.setTransform(1, 0, 0, 1, mask.offsetX - currentTransform[4], mask.offsetY - currentTransform[5]); 8056 for (let i = 0, ii = positions.length; i < ii; i += 2) { 8057 const trans = _util.Util.transform(currentTransform, [scaleX, skewX, skewY, scaleY, positions[i], positions[i + 1]]); 8058 const [x, y] = _util.Util.applyTransform([0, 0], trans); 8059 ctx.drawImage(mask.canvas, x, y); 8060 } 8061 ctx.restore(); 8062 this.compose(); 8063 } 8064 paintImageMaskXObjectGroup(images) { 8065 if (!this.contentVisible) { 8066 return; 8067 } 8068 const ctx = this.ctx; 8069 const fillColor = this.current.fillColor; 8070 const isPatternFill = this.current.patternFill; 8071 for (const image of images) { 8072 const { 8073 data, 8074 width, 8075 height, 8076 transform 8077 } = image; 8078 const maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height); 8079 const maskCtx = maskCanvas.context; 8080 maskCtx.save(); 8081 const img = this.getObject(data, image); 8082 putBinaryImageMask(maskCtx, img); 8083 maskCtx.globalCompositeOperation = "source-in"; 8084 maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.FILL) : fillColor; 8085 maskCtx.fillRect(0, 0, width, height); 8086 maskCtx.restore(); 8087 ctx.save(); 8088 ctx.transform(...transform); 8089 ctx.scale(1, -1); 8090 drawImageAtIntegerCoords(ctx, maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1); 8091 ctx.restore(); 8092 } 8093 this.compose(); 8094 } 8095 paintImageXObject(objId) { 8096 if (!this.contentVisible) { 8097 return; 8098 } 8099 const imgData = this.getObject(objId); 8100 if (!imgData) { 8101 (0, _util.warn)("Dependent image isn't ready yet"); 8102 return; 8103 } 8104 this.paintInlineImageXObject(imgData); 8105 } 8106 paintImageXObjectRepeat(objId, scaleX, scaleY, positions) { 8107 if (!this.contentVisible) { 8108 return; 8109 } 8110 const imgData = this.getObject(objId); 8111 if (!imgData) { 8112 (0, _util.warn)("Dependent image isn't ready yet"); 8113 return; 8114 } 8115 const width = imgData.width; 8116 const height = imgData.height; 8117 const map = []; 8118 for (let i = 0, ii = positions.length; i < ii; i += 2) { 8119 map.push({ 8120 transform: [scaleX, 0, 0, scaleY, positions[i], positions[i + 1]], 8121 x: 0, 8122 y: 0, 8123 w: width, 8124 h: height 8125 }); 8126 } 8127 this.paintInlineImageXObjectGroup(imgData, map); 8128 } 8129 applyTransferMapsToCanvas(ctx) { 8130 if (this.current.transferMaps !== "none") { 8131 ctx.filter = this.current.transferMaps; 8132 ctx.drawImage(ctx.canvas, 0, 0); 8133 ctx.filter = "none"; 8134 } 8135 return ctx.canvas; 8136 } 8137 applyTransferMapsToBitmap(imgData) { 8138 if (this.current.transferMaps === "none") { 8139 return imgData.bitmap; 8140 } 8141 const { 8142 bitmap, 8143 width, 8144 height 8145 } = imgData; 8146 const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", width, height); 8147 const tmpCtx = tmpCanvas.context; 8148 tmpCtx.filter = this.current.transferMaps; 8149 tmpCtx.drawImage(bitmap, 0, 0); 8150 tmpCtx.filter = "none"; 8151 return tmpCanvas.canvas; 8152 } 8153 paintInlineImageXObject(imgData) { 8154 if (!this.contentVisible) { 8155 return; 8156 } 8157 const width = imgData.width; 8158 const height = imgData.height; 8159 const ctx = this.ctx; 8160 this.save(); 8161 if (!_util.isNodeJS) { 8162 const { 8163 filter 8164 } = ctx; 8165 if (filter !== "none" && filter !== "") { 8166 ctx.filter = "none"; 8167 } 8168 } 8169 ctx.scale(1 / width, -1 / height); 8170 let imgToPaint; 8171 if (imgData.bitmap) { 8172 imgToPaint = this.applyTransferMapsToBitmap(imgData); 8173 } else if (typeof HTMLElement === "function" && imgData instanceof HTMLElement || !imgData.data) { 8174 imgToPaint = imgData; 8175 } else { 8176 const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", width, height); 8177 const tmpCtx = tmpCanvas.context; 8178 putBinaryImageData(tmpCtx, imgData); 8179 imgToPaint = this.applyTransferMapsToCanvas(tmpCtx); 8180 } 8181 const scaled = this._scaleImage(imgToPaint, (0, _display_utils.getCurrentTransformInverse)(ctx)); 8182 ctx.imageSmoothingEnabled = getImageSmoothingEnabled((0, _display_utils.getCurrentTransform)(ctx), imgData.interpolate); 8183 drawImageAtIntegerCoords(ctx, scaled.img, 0, 0, scaled.paintWidth, scaled.paintHeight, 0, -height, width, height); 8184 this.compose();
vendor: 4,375 bytes, lines 8185-8335
8185 this.restore(); 8186 } 8187 paintInlineImageXObjectGroup(imgData, map) { 8188 if (!this.contentVisible) { 8189 return; 8190 } 8191 const ctx = this.ctx; 8192 let imgToPaint; 8193 if (imgData.bitmap) { 8194 imgToPaint = imgData.bitmap; 8195 } else { 8196 const w = imgData.width; 8197 const h = imgData.height; 8198 const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", w, h); 8199 const tmpCtx = tmpCanvas.context; 8200 putBinaryImageData(tmpCtx, imgData); 8201 imgToPaint = this.applyTransferMapsToCanvas(tmpCtx); 8202 } 8203 for (const entry of map) { 8204 ctx.save(); 8205 ctx.transform(...entry.transform); 8206 ctx.scale(1, -1); 8207 drawImageAtIntegerCoords(ctx, imgToPaint, entry.x, entry.y, entry.w, entry.h, 0, -1, 1, 1); 8208 ctx.restore(); 8209 } 8210 this.compose(); 8211 } 8212 paintSolidColorImageMask() { 8213 if (!this.contentVisible) { 8214 return; 8215 } 8216 this.ctx.fillRect(0, 0, 1, 1); 8217 this.compose(); 8218 } 8219 markPoint(tag) {} 8220 markPointProps(tag, properties) {} 8221 beginMarkedContent(tag) { 8222 this.markedContentStack.push({ 8223 visible: true 8224 }); 8225 } 8226 beginMarkedContentProps(tag, properties) { 8227 if (tag === "OC") { 8228 this.markedContentStack.push({ 8229 visible: this.optionalContentConfig.isVisible(properties) 8230 }); 8231 } else { 8232 this.markedContentStack.push({ 8233 visible: true 8234 }); 8235 } 8236 this.contentVisible = this.isContentVisible(); 8237 } 8238 endMarkedContent() { 8239 this.markedContentStack.pop(); 8240 this.contentVisible = this.isContentVisible(); 8241 } 8242 beginCompat() {} 8243 endCompat() {} 8244 consumePath(clipBox) { 8245 const isEmpty = this.current.isEmptyClip(); 8246 if (this.pendingClip) { 8247 this.current.updateClipFromPath(); 8248 } 8249 if (!this.pendingClip) { 8250 this.compose(clipBox); 8251 } 8252 const ctx = this.ctx; 8253 if (this.pendingClip) { 8254 if (!isEmpty) { 8255 if (this.pendingClip === EO_CLIP) { 8256 ctx.clip("evenodd"); 8257 } else { 8258 ctx.clip(); 8259 } 8260 } 8261 this.pendingClip = null; 8262 } 8263 this.current.startNewPathAndClipBox(this.current.clipBox); 8264 ctx.beginPath(); 8265 } 8266 getSinglePixelWidth() { 8267 if (!this._cachedGetSinglePixelWidth) { 8268 const m = (0, _display_utils.getCurrentTransform)(this.ctx); 8269 if (m[1] === 0 && m[2] === 0) { 8270 this._cachedGetSinglePixelWidth = 1 / Math.min(Math.abs(m[0]), Math.abs(m[3])); 8271 } else { 8272 const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]); 8273 const normX = Math.hypot(m[0], m[2]); 8274 const normY = Math.hypot(m[1], m[3]); 8275 this._cachedGetSinglePixelWidth = Math.max(normX, normY) / absDet; 8276 } 8277 } 8278 return this._cachedGetSinglePixelWidth; 8279 } 8280 getScaleForStroking() { 8281 if (this._cachedScaleForStroking[0] === -1) { 8282 const { 8283 lineWidth 8284 } = this.current; 8285 const { 8286 a, 8287 b, 8288 c, 8289 d 8290 } = this.ctx.getTransform(); 8291 let scaleX, scaleY; 8292 if (b === 0 && c === 0) { 8293 const normX = Math.abs(a); 8294 const normY = Math.abs(d); 8295 if (normX === normY) { 8296 if (lineWidth === 0) { 8297 scaleX = scaleY = 1 / normX; 8298 } else { 8299 const scaledLineWidth = normX * lineWidth; 8300 scaleX = scaleY = scaledLineWidth < 1 ? 1 / scaledLineWidth : 1; 8301 } 8302 } else if (lineWidth === 0) { 8303 scaleX = 1 / normX; 8304 scaleY = 1 / normY; 8305 } else { 8306 const scaledXLineWidth = normX * lineWidth; 8307 const scaledYLineWidth = normY * lineWidth; 8308 scaleX = scaledXLineWidth < 1 ? 1 / scaledXLineWidth : 1; 8309 scaleY = scaledYLineWidth < 1 ? 1 / scaledYLineWidth : 1; 8310 } 8311 } else { 8312 const absDet = Math.abs(a * d - b * c); 8313 const normX = Math.hypot(a, b); 8314 const normY = Math.hypot(c, d); 8315 if (lineWidth === 0) { 8316 scaleX = normY / absDet; 8317 scaleY = normX / absDet; 8318 } else { 8319 const baseArea = lineWidth * absDet; 8320 scaleX = normY > baseArea ? normY / baseArea : 1; 8321 scaleY = normX > baseArea ? normX / baseArea : 1; 8322 } 8323 } 8324 this._cachedScaleForStroking[0] = scaleX; 8325 this._cachedScaleForStroking[1] = scaleY; 8326 } 8327 return this._cachedScaleForStroking; 8328 } 8329 rescaleAndStroke(saveRestore) { 8330 const { 8331 ctx 8332 } = this; 8333 const { 8334 lineWidth 8335 } = this.current;
8336 const [scaleX, scaleY] = this.getScaleForStroking(); 8337 ctx.lineWidth = lineWidth || 1; 8338 if (scaleX === 1 && scaleY === 1) { 8339 ctx.stroke(); 8340 return; 8341 } 8342 const dashes = ctx.getLineDash(); 8343 if (saveRestore) { 8344 ctx.save(); 8345 } 8346 ctx.scale(scaleX, scaleY); 8347 if (dashes.length > 0) { 8348 const scale = Math.max(scaleX, scaleY); 8349 ctx.setLineDash(dashes.map(x => x / scale)); 8350 ctx.lineDashOffset /= scale; 8351 } 8352 ctx.stroke(); 8353 if (saveRestore) { 8354 ctx.restore(); 8355 } 8356 } 8357 isContentVisible() { 8358 for (let i = this.markedContentStack.length - 1; i >= 0; i--) { 8359 if (!this.markedContentStack[i].visible) { 8360 return false; 8361 } 8362 } 8363 return true; 8364 } 8365} 8366exports.CanvasGraphics = CanvasGraphics; 8367for (const op in _util.OPS) { 8368 if (CanvasGraphics.prototype[op] !== undefined) { 8369 CanvasGraphics.prototype[_util.OPS[op]] = CanvasGraphics.prototype[op]; 8370 } 8371} 8372 8373/***/ }), 8374/* 12 */ 8375/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 8376 8377 8378 8379Object.defineProperty(exports, "__esModule", ({ 8380 value: true 8381})); 8382exports.TilingPattern = exports.PathType = void 0; 8383exports.getShadingPattern = getShadingPattern; 8384var _util = __w_pdfjs_require__(1); 8385var _display_utils = __w_pdfjs_require__(6); 8386const PathType = exports.PathType = { 8387 FILL: "Fill", 8388 STROKE: "Stroke", 8389 SHADING: "Shading" 8390}; 8391function applyBoundingBox(ctx, bbox) { 8392 if (!bbox) { 8393 return; 8394 } 8395 const width = bbox[2] - bbox[0]; 8396 const height = bbox[3] - bbox[1]; 8397 const region = new Path2D(); 8398 region.rect(bbox[0], bbox[1], width, height); 8399 ctx.clip(region); 8400} 8401class BaseShadingPattern { 8402 constructor() { 8403 if (this.constructor === BaseShadingPattern) { 8404 (0, _util.unreachable)("Cannot initialize BaseShadingPattern."); 8405 } 8406 } 8407 getPattern() { 8408 (0, _util.unreachable)("Abstract method `getPattern` called."); 8409 } 8410} 8411class RadialAxialShadingPattern extends BaseShadingPattern { 8412 constructor(IR) { 8413 super(); 8414 this._type = IR[1]; 8415 this._bbox = IR[2]; 8416 this._colorStops = IR[3]; 8417 this._p0 = IR[4]; 8418 this._p1 = IR[5]; 8419 this._r0 = IR[6]; 8420 this._r1 = IR[7]; 8421 this.matrix = null; 8422 } 8423 _createGradient(ctx) { 8424 let grad; 8425 if (this._type === "axial") { 8426 grad = ctx.createLinearGradient(this._p0[0], this._p0[1], this._p1[0], this._p1[1]); 8427 } else if (this._type === "radial") { 8428 grad = ctx.createRadialGradient(this._p0[0], this._p0[1], this._r0, this._p1[0], this._p1[1], this._r1); 8429 } 8430 for (const colorStop of this._colorStops) { 8431 grad.addColorStop(colorStop[0], colorStop[1]); 8432 } 8433 return grad; 8434 } 8435 getPattern(ctx, owner, inverse, pathType) { 8436 let pattern; 8437 if (pathType === PathType.STROKE || pathType === PathType.FILL) { 8438 const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, (0, _display_utils.getCurrentTransform)(ctx)) || [0, 0, 0, 0]; 8439 const width = Math.ceil(ownerBBox[2] - ownerBBox[0]) || 1; 8440 const height = Math.ceil(ownerBBox[3] - ownerBBox[1]) || 1; 8441 const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", width, height, true); 8442 const tmpCtx = tmpCanvas.context; 8443 tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); 8444 tmpCtx.beginPath(); 8445 tmpCtx.rect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); 8446 tmpCtx.translate(-ownerBBox[0], -ownerBBox[1]); 8447 inverse = _util.Util.transform(inverse, [1, 0, 0, 1, ownerBBox[0], ownerBBox[1]]); 8448 tmpCtx.transform(...owner.baseTransform); 8449 if (this.matrix) { 8450 tmpCtx.transform(...this.matrix); 8451 } 8452 applyBoundingBox(tmpCtx, this._bbox); 8453 tmpCtx.fillStyle = this._createGradient(tmpCtx); 8454 tmpCtx.fill(); 8455 pattern = ctx.createPattern(tmpCanvas.canvas, "no-repeat"); 8456 const domMatrix = new DOMMatrix(inverse); 8457 pattern.setTransform(domMatrix); 8458 } else { 8459 applyBoundingBox(ctx, this._bbox); 8460 pattern = this._createGradient(ctx); 8461 } 8462 return pattern; 8463 } 8464} 8465function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) { 8466 const coords = context.coords, 8467 colors = context.colors; 8468 const bytes = data.data, 8469 rowSize = data.width * 4; 8470 let tmp; 8471 if (coords[p1 + 1] > coords[p2 + 1]) { 8472 tmp = p1; 8473 p1 = p2; 8474 p2 = tmp; 8475 tmp = c1; 8476 c1 = c2; 8477 c2 = tmp; 8478 } 8479 if (coords[p2 + 1] > coords[p3 + 1]) { 8480 tmp = p2; 8481 p2 = p3; 8482 p3 = tmp; 8483 tmp = c2; 8484 c2 = c3; 8485 c3 = tmp; 8486 } 8487 if (coords[p1 + 1] > coords[p2 + 1]) { 8488 tmp = p1; 8489 p1 = p2; 8490 p2 = tmp; 8491 tmp = c1; 8492 c1 = c2; 8493 c2 = tmp; 8494 } 8495 const x1 = (coords[p1] + context.offsetX) * context.scaleX; 8496 const y1 = (coords[p1 + 1] + context.offsetY) * context.scaleY; 8497 const x2 = (coords[p2] + context.offsetX) * context.scaleX; 8498 const y2 = (coords[p2 + 1] + context.offsetY) * context.scaleY; 8499 const x3 = (coords[p3] + context.offsetX) * context.scaleX; 8500 const y3 = (coords[p3 + 1] + context.offsetY) * context.scaleY; 8501 if (y1 >= y3) { 8502 return; 8503 } 8504 const c1r = colors[c1], 8505 c1g = colors[c1 + 1], 8506 c1b = colors[c1 + 2]; 8507 const c2r = colors[c2], 8508 c2g = colors[c2 + 1], 8509 c2b = colors[c2 + 2]; 8510 const c3r = colors[c3], 8511 c3g = colors[c3 + 1], 8512 c3b = colors[c3 + 2]; 8513 const minY = Math.round(y1), 8514 maxY = Math.round(y3); 8515 let xa, car, cag, cab; 8516 let xb, cbr, cbg, cbb; 8517 for (let y = minY; y <= maxY; y++) { 8518 if (y < y2) {
vendor: 4,267 bytes, lines 8519-8648
8519 const k = y < y1 ? 0 : (y1 - y) / (y1 - y2); 8520 xa = x1 - (x1 - x2) * k; 8521 car = c1r - (c1r - c2r) * k; 8522 cag = c1g - (c1g - c2g) * k; 8523 cab = c1b - (c1b - c2b) * k; 8524 } else { 8525 let k; 8526 if (y > y3) { 8527 k = 1; 8528 } else if (y2 === y3) { 8529 k = 0; 8530 } else { 8531 k = (y2 - y) / (y2 - y3); 8532 } 8533 xa = x2 - (x2 - x3) * k; 8534 car = c2r - (c2r - c3r) * k; 8535 cag = c2g - (c2g - c3g) * k; 8536 cab = c2b - (c2b - c3b) * k; 8537 } 8538 let k; 8539 if (y < y1) { 8540 k = 0; 8541 } else if (y > y3) { 8542 k = 1; 8543 } else { 8544 k = (y1 - y) / (y1 - y3); 8545 } 8546 xb = x1 - (x1 - x3) * k; 8547 cbr = c1r - (c1r - c3r) * k; 8548 cbg = c1g - (c1g - c3g) * k; 8549 cbb = c1b - (c1b - c3b) * k; 8550 const x1_ = Math.round(Math.min(xa, xb)); 8551 const x2_ = Math.round(Math.max(xa, xb)); 8552 let j = rowSize * y + x1_ * 4; 8553 for (let x = x1_; x <= x2_; x++) { 8554 k = (xa - x) / (xa - xb); 8555 if (k < 0) { 8556 k = 0; 8557 } else if (k > 1) { 8558 k = 1; 8559 } 8560 bytes[j++] = car - (car - cbr) * k | 0; 8561 bytes[j++] = cag - (cag - cbg) * k | 0; 8562 bytes[j++] = cab - (cab - cbb) * k | 0; 8563 bytes[j++] = 255; 8564 } 8565 } 8566} 8567function drawFigure(data, figure, context) { 8568 const ps = figure.coords; 8569 const cs = figure.colors; 8570 let i, ii; 8571 switch (figure.type) { 8572 case "lattice": 8573 const verticesPerRow = figure.verticesPerRow; 8574 const rows = Math.floor(ps.length / verticesPerRow) - 1; 8575 const cols = verticesPerRow - 1; 8576 for (i = 0; i < rows; i++) { 8577 let q = i * verticesPerRow; 8578 for (let j = 0; j < cols; j++, q++) { 8579 drawTriangle(data, context, ps[q], ps[q + 1], ps[q + verticesPerRow], cs[q], cs[q + 1], cs[q + verticesPerRow]); 8580 drawTriangle(data, context, ps[q + verticesPerRow + 1], ps[q + 1], ps[q + verticesPerRow], cs[q + verticesPerRow + 1], cs[q + 1], cs[q + verticesPerRow]); 8581 } 8582 } 8583 break; 8584 case "triangles": 8585 for (i = 0, ii = ps.length; i < ii; i += 3) { 8586 drawTriangle(data, context, ps[i], ps[i + 1], ps[i + 2], cs[i], cs[i + 1], cs[i + 2]); 8587 } 8588 break; 8589 default: 8590 throw new Error("illegal figure"); 8591 } 8592} 8593class MeshShadingPattern extends BaseShadingPattern { 8594 constructor(IR) { 8595 super(); 8596 this._coords = IR[2]; 8597 this._colors = IR[3]; 8598 this._figures = IR[4]; 8599 this._bounds = IR[5]; 8600 this._bbox = IR[7]; 8601 this._background = IR[8]; 8602 this.matrix = null; 8603 } 8604 _createMeshCanvas(combinedScale, backgroundColor, cachedCanvases) { 8605 const EXPECTED_SCALE = 1.1; 8606 const MAX_PATTERN_SIZE = 3000; 8607 const BORDER_SIZE = 2; 8608 const offsetX = Math.floor(this._bounds[0]); 8609 const offsetY = Math.floor(this._bounds[1]); 8610 const boundsWidth = Math.ceil(this._bounds[2]) - offsetX; 8611 const boundsHeight = Math.ceil(this._bounds[3]) - offsetY; 8612 const width = Math.min(Math.ceil(Math.abs(boundsWidth * combinedScale[0] * EXPECTED_SCALE)), MAX_PATTERN_SIZE); 8613 const height = Math.min(Math.ceil(Math.abs(boundsHeight * combinedScale[1] * EXPECTED_SCALE)), MAX_PATTERN_SIZE); 8614 const scaleX = boundsWidth / width; 8615 const scaleY = boundsHeight / height; 8616 const context = { 8617 coords: this._coords, 8618 colors: this._colors, 8619 offsetX: -offsetX, 8620 offsetY: -offsetY, 8621 scaleX: 1 / scaleX, 8622 scaleY: 1 / scaleY 8623 }; 8624 const paddedWidth = width + BORDER_SIZE * 2; 8625 const paddedHeight = height + BORDER_SIZE * 2; 8626 const tmpCanvas = cachedCanvases.getCanvas("mesh", paddedWidth, paddedHeight, false); 8627 const tmpCtx = tmpCanvas.context; 8628 const data = tmpCtx.createImageData(width, height); 8629 if (backgroundColor) { 8630 const bytes = data.data; 8631 for (let i = 0, ii = bytes.length; i < ii; i += 4) { 8632 bytes[i] = backgroundColor[0]; 8633 bytes[i + 1] = backgroundColor[1]; 8634 bytes[i + 2] = backgroundColor[2]; 8635 bytes[i + 3] = 255; 8636 } 8637 } 8638 for (const figure of this._figures) { 8639 drawFigure(data, figure, context); 8640 } 8641 tmpCtx.putImageData(data, BORDER_SIZE, BORDER_SIZE); 8642 const canvas = tmpCanvas.canvas; 8643 return { 8644 canvas, 8645 offsetX: offsetX - BORDER_SIZE * scaleX, 8646 offsetY: offsetY - BORDER_SIZE * scaleY, 8647 scaleX, 8648 scaleY
8649 }; 8650 } 8651 getPattern(ctx, owner, inverse, pathType) { 8652 applyBoundingBox(ctx, this._bbox); 8653 let scale; 8654 if (pathType === PathType.SHADING) { 8655 scale = _util.Util.singularValueDecompose2dScale((0, _display_utils.getCurrentTransform)(ctx)); 8656 } else { 8657 scale = _util.Util.singularValueDecompose2dScale(owner.baseTransform); 8658 if (this.matrix) { 8659 const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix); 8660 scale = [scale[0] * matrixScale[0], scale[1] * matrixScale[1]]; 8661 } 8662 } 8663 const temporaryPatternCanvas = this._createMeshCanvas(scale, pathType === PathType.SHADING ? null : this._background, owner.cachedCanvases); 8664 if (pathType !== PathType.SHADING) { 8665 ctx.setTransform(...owner.baseTransform); 8666 if (this.matrix) { 8667 ctx.transform(...this.matrix); 8668 } 8669 } 8670 ctx.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY); 8671 ctx.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY); 8672 return ctx.createPattern(temporaryPatternCanvas.canvas, "no-repeat"); 8673 } 8674} 8675class DummyShadingPattern extends BaseShadingPattern { 8676 getPattern() { 8677 return "hotpink"; 8678 } 8679} 8680function getShadingPattern(IR) { 8681 switch (IR[0]) { 8682 case "RadialAxial": 8683 return new RadialAxialShadingPattern(IR); 8684 case "Mesh": 8685 return new MeshShadingPattern(IR); 8686 case "Dummy": 8687 return new DummyShadingPattern(); 8688 } 8689 throw new Error(`Unknown IR type: ${IR[0]}`); 8690} 8691const PaintType = { 8692 COLORED: 1, 8693 UNCOLORED: 2 8694}; 8695class TilingPattern { 8696 static MAX_PATTERN_SIZE = 3000; 8697 constructor(IR, color, ctx, canvasGraphicsFactory, baseTransform) { 8698 this.operatorList = IR[2]; 8699 this.matrix = IR[3] || [1, 0, 0, 1, 0, 0]; 8700 this.bbox = IR[4]; 8701 this.xstep = IR[5]; 8702 this.ystep = IR[6]; 8703 this.paintType = IR[7]; 8704 this.tilingType = IR[8]; 8705 this.color = color; 8706 this.ctx = ctx; 8707 this.canvasGraphicsFactory = canvasGraphicsFactory; 8708 this.baseTransform = baseTransform; 8709 } 8710 createPatternCanvas(owner) { 8711 const operatorList = this.operatorList; 8712 const bbox = this.bbox; 8713 const xstep = this.xstep; 8714 const ystep = this.ystep; 8715 const paintType = this.paintType; 8716 const tilingType = this.tilingType; 8717 const color = this.color; 8718 const canvasGraphicsFactory = this.canvasGraphicsFactory; 8719 (0, _util.info)("TilingType: " + tilingType); 8720 const x0 = bbox[0], 8721 y0 = bbox[1], 8722 x1 = bbox[2], 8723 y1 = bbox[3]; 8724 const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix); 8725 const curMatrixScale = _util.Util.singularValueDecompose2dScale(this.baseTransform); 8726 const combinedScale = [matrixScale[0] * curMatrixScale[0], matrixScale[1] * curMatrixScale[1]]; 8727 const dimx = this.getSizeAndScale(xstep, this.ctx.canvas.width, combinedScale[0]); 8728 const dimy = this.getSizeAndScale(ystep, this.ctx.canvas.height, combinedScale[1]); 8729 const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", dimx.size, dimy.size, true); 8730 const tmpCtx = tmpCanvas.context; 8731 const graphics = canvasGraphicsFactory.createCanvasGraphics(tmpCtx); 8732 graphics.groupLevel = owner.groupLevel; 8733 this.setFillAndStrokeStyleToContext(graphics, paintType, color); 8734 let adjustedX0 = x0; 8735 let adjustedY0 = y0; 8736 let adjustedX1 = x1; 8737 let adjustedY1 = y1; 8738 if (x0 < 0) { 8739 adjustedX0 = 0; 8740 adjustedX1 += Math.abs(x0); 8741 } 8742 if (y0 < 0) { 8743 adjustedY0 = 0; 8744 adjustedY1 += Math.abs(y0); 8745 } 8746 tmpCtx.translate(-(dimx.scale * adjustedX0), -(dimy.scale * adjustedY0)); 8747 graphics.transform(dimx.scale, 0, 0, dimy.scale, 0, 0); 8748 tmpCtx.save(); 8749 this.clipBbox(graphics, adjustedX0, adjustedY0, adjustedX1, adjustedY1); 8750 graphics.baseTransform = (0, _display_utils.getCurrentTransform)(graphics.ctx); 8751 graphics.executeOperatorList(operatorList); 8752 graphics.endDrawing(); 8753 return { 8754 canvas: tmpCanvas.canvas, 8755 scaleX: dimx.scale, 8756 scaleY: dimy.scale, 8757 offsetX: adjustedX0, 8758 offsetY: adjustedY0 8759 }; 8760 } 8761 getSizeAndScale(step, realOutputSize, scale) { 8762 step = Math.abs(step); 8763 const maxSize = Math.max(TilingPattern.MAX_PATTERN_SIZE, realOutputSize);
8764 let size = Math.ceil(step * scale); 8765 if (size >= maxSize) { 8766 size = maxSize; 8767 } else { 8768 scale = size / step; 8769 } 8770 return { 8771 scale, 8772 size 8773 }; 8774 } 8775 clipBbox(graphics, x0, y0, x1, y1) { 8776 const bboxWidth = x1 - x0; 8777 const bboxHeight = y1 - y0; 8778 graphics.ctx.rect(x0, y0, bboxWidth, bboxHeight); 8779 graphics.current.updateRectMinMax((0, _display_utils.getCurrentTransform)(graphics.ctx), [x0, y0, x1, y1]); 8780 graphics.clip(); 8781 graphics.endPath(); 8782 } 8783 setFillAndStrokeStyleToContext(graphics, paintType, color) { 8784 const context = graphics.ctx, 8785 current = graphics.current; 8786 switch (paintType) { 8787 case PaintType.COLORED: 8788 const ctx = this.ctx; 8789 context.fillStyle = ctx.fillStyle; 8790 context.strokeStyle = ctx.strokeStyle; 8791 current.fillColor = ctx.fillStyle; 8792 current.strokeColor = ctx.strokeStyle; 8793 break; 8794 case PaintType.UNCOLORED: 8795 const cssColor = _util.Util.makeHexColor(color[0], color[1], color[2]); 8796 context.fillStyle = cssColor; 8797 context.strokeStyle = cssColor; 8798 current.fillColor = cssColor; 8799 current.strokeColor = cssColor; 8800 break; 8801 default: 8802 throw new _util.FormatError(`Unsupported paint type: ${paintType}`); 8803 } 8804 } 8805 getPattern(ctx, owner, inverse, pathType) { 8806 let matrix = inverse; 8807 if (pathType !== PathType.SHADING) { 8808 matrix = _util.Util.transform(matrix, owner.baseTransform); 8809 if (this.matrix) { 8810 matrix = _util.Util.transform(matrix, this.matrix); 8811 } 8812 } 8813 const temporaryPatternCanvas = this.createPatternCanvas(owner); 8814 let domMatrix = new DOMMatrix(matrix); 8815 domMatrix = domMatrix.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY); 8816 domMatrix = domMatrix.scale(1 / temporaryPatternCanvas.scaleX, 1 / temporaryPatternCanvas.scaleY); 8817 const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "repeat"); 8818 pattern.setTransform(domMatrix); 8819 return pattern; 8820 } 8821} 8822exports.TilingPattern = TilingPattern; 8823 8824/***/ }), 8825/* 13 */ 8826/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 8827 8828 8829 8830Object.defineProperty(exports, "__esModule", ({ 8831 value: true 8832})); 8833exports.convertBlackAndWhiteToRGBA = convertBlackAndWhiteToRGBA; 8834exports.convertToRGBA = convertToRGBA; 8835exports.grayToRGBA = grayToRGBA; 8836var _util = __w_pdfjs_require__(1); 8837function convertToRGBA(params) { 8838 switch (params.kind) { 8839 case _util.ImageKind.GRAYSCALE_1BPP: 8840 return convertBlackAndWhiteToRGBA(params); 8841 case _util.ImageKind.RGB_24BPP: 8842 return convertRGBToRGBA(params); 8843 } 8844 return null; 8845} 8846function convertBlackAndWhiteToRGBA({ 8847 src, 8848 srcPos = 0, 8849 dest, 8850 width, 8851 height, 8852 nonBlackColor = 0xffffffff, 8853 inverseDecode = false 8854}) { 8855 const black = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; 8856 const [zeroMapping, oneMapping] = inverseDecode ? [nonBlackColor, black] : [black, nonBlackColor]; 8857 const widthInSource = width >> 3; 8858 const widthRemainder = width & 7; 8859 const srcLength = src.length; 8860 dest = new Uint32Array(dest.buffer); 8861 let destPos = 0; 8862 for (let i = 0; i < height; i++) { 8863 for (const max = srcPos + widthInSource; srcPos < max; srcPos++) { 8864 const elem = srcPos < srcLength ? src[srcPos] : 255; 8865 dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping; 8866 dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping; 8867 dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping; 8868 dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping; 8869 dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping; 8870 dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping; 8871 dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping; 8872 dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping; 8873 } 8874 if (widthRemainder === 0) { 8875 continue; 8876 } 8877 const elem = srcPos < srcLength ? src[srcPos++] : 255; 8878 for (let j = 0; j < widthRemainder; j++) { 8879 dest[destPos++] = elem & 1 << 7 - j ? oneMapping : zeroMapping; 8880 } 8881 } 8882 return { 8883 srcPos, 8884 destPos 8885 }; 8886} 8887function convertRGBToRGBA({ 8888 src, 8889 srcPos = 0, 8890 dest, 8891 destPos = 0, 8892 width, 8893 height 8894}) { 8895 let i = 0; 8896 const len32 = src.length >> 2; 8897 const src32 = new Uint32Array(src.buffer, srcPos, len32); 8898 if (_util.FeatureTest.isLittleEndian) { 8899 for (; i < len32 - 2; i += 3, destPos += 4) { 8900 const s1 = src32[i]; 8901 const s2 = src32[i + 1]; 8902 const s3 = src32[i + 2]; 8903 dest[destPos] = s1 | 0xff000000; 8904 dest[destPos + 1] = s1 >>> 24 | s2 << 8 | 0xff000000; 8905 dest[destPos + 2] = s2 >>> 16 | s3 << 16 | 0xff000000; 8906 dest[destPos + 3] = s3 >>> 8 | 0xff000000; 8907 } 8908 for (let j = i * 4, jj = src.length; j < jj; j += 3) { 8909 dest[destPos++] = src[j] | src[j + 1] << 8 | src[j + 2] << 16 | 0xff000000; 8910 } 8911 } else { 8912 for (; i < len32 - 2; i += 3, destPos += 4) { 8913 const s1 = src32[i]; 8914 const s2 = src32[i + 1]; 8915 const s3 = src32[i + 2]; 8916 dest[destPos] = s1 | 0xff;
8917 dest[destPos + 1] = s1 << 24 | s2 >>> 8 | 0xff; 8918 dest[destPos + 2] = s2 << 16 | s3 >>> 16 | 0xff; 8919 dest[destPos + 3] = s3 << 8 | 0xff; 8920 } 8921 for (let j = i * 4, jj = src.length; j < jj; j += 3) { 8922 dest[destPos++] = src[j] << 24 | src[j + 1] << 16 | src[j + 2] << 8 | 0xff; 8923 } 8924 } 8925 return { 8926 srcPos, 8927 destPos 8928 }; 8929} 8930function grayToRGBA(src, dest) { 8931 if (_util.FeatureTest.isLittleEndian) { 8932 for (let i = 0, ii = src.length; i < ii; i++) { 8933 dest[i] = src[i] * 0x10101 | 0xff000000; 8934 } 8935 } else { 8936 for (let i = 0, ii = src.length; i < ii; i++) { 8937 dest[i] = src[i] * 0x1010100 | 0x000000ff; 8938 } 8939 } 8940} 8941 8942/***/ }), 8943/* 14 */ 8944/***/ ((__unused_webpack_module, exports) => { 8945 8946 8947 8948Object.defineProperty(exports, "__esModule", ({ 8949 value: true 8950})); 8951exports.GlobalWorkerOptions = void 0; 8952const GlobalWorkerOptions = exports.GlobalWorkerOptions = Object.create(null); 8953GlobalWorkerOptions.workerPort = null; 8954GlobalWorkerOptions.workerSrc = ""; 8955 8956/***/ }), 8957/* 15 */ 8958/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 8959 8960 8961 8962Object.defineProperty(exports, "__esModule", ({ 8963 value: true 8964})); 8965exports.MessageHandler = void 0; 8966var _util = __w_pdfjs_require__(1); 8967const CallbackKind = { 8968 UNKNOWN: 0, 8969 DATA: 1, 8970 ERROR: 2 8971}; 8972const StreamKind = { 8973 UNKNOWN: 0, 8974 CANCEL: 1, 8975 CANCEL_COMPLETE: 2, 8976 CLOSE: 3, 8977 ENQUEUE: 4, 8978 ERROR: 5, 8979 PULL: 6, 8980 PULL_COMPLETE: 7, 8981 START_COMPLETE: 8 8982}; 8983function wrapReason(reason) { 8984 if (!(reason instanceof Error || typeof reason === "object" && reason !== null)) { 8985 (0, _util.unreachable)('wrapReason: Expected "reason" to be a (possibly cloned) Error.'); 8986 } 8987 switch (reason.name) { 8988 case "AbortException": 8989 return new _util.AbortException(reason.message); 8990 case "MissingPDFException": 8991 return new _util.MissingPDFException(reason.message); 8992 case "PasswordException": 8993 return new _util.PasswordException(reason.message, reason.code); 8994 case "UnexpectedResponseException": 8995 return new _util.UnexpectedResponseException(reason.message, reason.status); 8996 case "UnknownErrorException": 8997 return new _util.UnknownErrorException(reason.message, reason.details); 8998 default: 8999 return new _util.UnknownErrorException(reason.message, reason.toString()); 9000 } 9001} 9002class MessageHandler { 9003 constructor(sourceName, targetName, comObj) { 9004 this.sourceName = sourceName; 9005 this.targetName = targetName; 9006 this.comObj = comObj; 9007 this.callbackId = 1; 9008 this.streamId = 1; 9009 this.streamSinks = Object.create(null); 9010 this.streamControllers = Object.create(null); 9011 this.callbackCapabilities = Object.create(null); 9012 this.actionHandler = Object.create(null); 9013 this._onComObjOnMessage = event => { 9014 const data = event.data; 9015 if (data.targetName !== this.sourceName) { 9016 return; 9017 } 9018 if (data.stream) { 9019 this.#processStreamMessage(data); 9020 return; 9021 } 9022 if (data.callback) { 9023 const callbackId = data.callbackId; 9024 const capability = this.callbackCapabilities[callbackId]; 9025 if (!capability) { 9026 throw new Error(`Cannot resolve callback ${callbackId}`); 9027 } 9028 delete this.callbackCapabilities[callbackId]; 9029 if (data.callback === CallbackKind.DATA) { 9030 capability.resolve(data.data); 9031 } else if (data.callback === CallbackKind.ERROR) { 9032 capability.reject(wrapReason(data.reason)); 9033 } else { 9034 throw new Error("Unexpected callback case"); 9035 } 9036 return; 9037 } 9038 const action = this.actionHandler[data.action]; 9039 if (!action) { 9040 throw new Error(`Unknown action from worker: ${data.action}`); 9041 } 9042 if (data.callbackId) { 9043 const cbSourceName = this.sourceName; 9044 const cbTargetName = data.sourceName; 9045 new Promise(function (resolve) { 9046 resolve(action(data.data)); 9047 }).then(function (result) { 9048 comObj.postMessage({ 9049 sourceName: cbSourceName, 9050 targetName: cbTargetName, 9051 callback: CallbackKind.DATA, 9052 callbackId: data.callbackId, 9053 data: result 9054 }); 9055 }, function (reason) { 9056 comObj.postMessage({ 9057 sourceName: cbSourceName, 9058 targetName: cbTargetName, 9059 callback: CallbackKind.ERROR, 9060 callbackId: data.callbackId, 9061 reason: wrapReason(reason) 9062 }); 9063 }); 9064 return; 9065 } 9066 if (data.streamId) { 9067 this.#createStreamSink(data); 9068 return; 9069 } 9070 action(data.data); 9071 }; 9072 comObj.addEventListener("message", this._onComObjOnMessage); 9073 } 9074 on(actionName, handler) { 9075 const ah = this.actionHandler; 9076 if (ah[actionName]) { 9077 throw new Error(`There is already an actionName called "${actionName}"`); 9078 } 9079 ah[actionName] = handler; 9080 } 9081 send(actionName, data, transfers) { 9082 this.comObj.postMessage({ 9083 sourceName: this.sourceName, 9084 targetName: this.targetName, 9085 action: actionName, 9086 data 9087 }, transfers); 9088 }
9089 sendWithPromise(actionName, data, transfers) { 9090 const callbackId = this.callbackId++; 9091 const capability = new _util.PromiseCapability(); 9092 this.callbackCapabilities[callbackId] = capability; 9093 try { 9094 this.comObj.postMessage({ 9095 sourceName: this.sourceName, 9096 targetName: this.targetName, 9097 action: actionName, 9098 callbackId, 9099 data 9100 }, transfers); 9101 } catch (ex) { 9102 capability.reject(ex); 9103 } 9104 return capability.promise; 9105 } 9106 sendWithStream(actionName, data, queueingStrategy, transfers) { 9107 const streamId = this.streamId++, 9108 sourceName = this.sourceName, 9109 targetName = this.targetName, 9110 comObj = this.comObj; 9111 return new ReadableStream({ 9112 start: controller => { 9113 const startCapability = new _util.PromiseCapability(); 9114 this.streamControllers[streamId] = { 9115 controller, 9116 startCall: startCapability, 9117 pullCall: null, 9118 cancelCall: null, 9119 isClosed: false 9120 }; 9121 comObj.postMessage({ 9122 sourceName, 9123 targetName, 9124 action: actionName, 9125 streamId, 9126 data, 9127 desiredSize: controller.desiredSize 9128 }, transfers); 9129 return startCapability.promise; 9130 }, 9131 pull: controller => { 9132 const pullCapability = new _util.PromiseCapability(); 9133 this.streamControllers[streamId].pullCall = pullCapability; 9134 comObj.postMessage({ 9135 sourceName, 9136 targetName, 9137 stream: StreamKind.PULL, 9138 streamId, 9139 desiredSize: controller.desiredSize 9140 }); 9141 return pullCapability.promise; 9142 }, 9143 cancel: reason => { 9144 (0, _util.assert)(reason instanceof Error, "cancel must have a valid reason"); 9145 const cancelCapability = new _util.PromiseCapability(); 9146 this.streamControllers[streamId].cancelCall = cancelCapability; 9147 this.streamControllers[streamId].isClosed = true; 9148 comObj.postMessage({ 9149 sourceName, 9150 targetName, 9151 stream: StreamKind.CANCEL, 9152 streamId, 9153 reason: wrapReason(reason) 9154 }); 9155 return cancelCapability.promise; 9156 } 9157 }, queueingStrategy); 9158 } 9159 #createStreamSink(data) { 9160 const streamId = data.streamId, 9161 sourceName = this.sourceName, 9162 targetName = data.sourceName, 9163 comObj = this.comObj; 9164 const self = this, 9165 action = this.actionHandler[data.action]; 9166 const streamSink = { 9167 enqueue(chunk, size = 1, transfers) { 9168 if (this.isCancelled) { 9169 return; 9170 } 9171 const lastDesiredSize = this.desiredSize; 9172 this.desiredSize -= size; 9173 if (lastDesiredSize > 0 && this.desiredSize <= 0) { 9174 this.sinkCapability = new _util.PromiseCapability(); 9175 this.ready = this.sinkCapability.promise; 9176 } 9177 comObj.postMessage({ 9178 sourceName, 9179 targetName, 9180 stream: StreamKind.ENQUEUE, 9181 streamId, 9182 chunk 9183 }, transfers); 9184 }, 9185 close() { 9186 if (this.isCancelled) { 9187 return; 9188 } 9189 this.isCancelled = true; 9190 comObj.postMessage({ 9191 sourceName, 9192 targetName, 9193 stream: StreamKind.CLOSE, 9194 streamId 9195 }); 9196 delete self.streamSinks[streamId]; 9197 }, 9198 error(reason) { 9199 (0, _util.assert)(reason instanceof Error, "error must have a valid reason"); 9200 if (this.isCancelled) { 9201 return; 9202 } 9203 this.isCancelled = true; 9204 comObj.postMessage({ 9205 sourceName, 9206 targetName, 9207 stream: StreamKind.ERROR, 9208 streamId, 9209 reason: wrapReason(reason) 9210 }); 9211 }, 9212 sinkCapability: new _util.PromiseCapability(), 9213 onPull: null, 9214 onCancel: null, 9215 isCancelled: false, 9216 desiredSize: data.desiredSize, 9217 ready: null 9218 }; 9219 streamSink.sinkCapability.resolve(); 9220 streamSink.ready = streamSink.sinkCapability.promise; 9221 this.streamSinks[streamId] = streamSink; 9222 new Promise(function (resolve) { 9223 resolve(action(data.data, streamSink)); 9224 }).then(function () { 9225 comObj.postMessage({ 9226 sourceName, 9227 targetName, 9228 stream: StreamKind.START_COMPLETE, 9229 streamId, 9230 success: true 9231 }); 9232 }, function (reason) { 9233 comObj.postMessage({ 9234 sourceName, 9235 targetName, 9236 stream: StreamKind.START_COMPLETE, 9237 streamId, 9238 reason: wrapReason(reason) 9239 }); 9240 }); 9241 } 9242 #processStreamMessage(data) { 9243 const streamId = data.streamId, 9244 sourceName = this.sourceName, 9245 targetName = data.sourceName, 9246 comObj = this.comObj; 9247 const streamController = this.streamControllers[streamId], 9248 streamSink = this.streamSinks[streamId]; 9249 switch (data.stream) { 9250 case StreamKind.START_COMPLETE: 9251 if (data.success) { 9252 streamController.startCall.resolve(); 9253 } else { 9254 streamController.startCall.reject(wrapReason(data.reason)); 9255 } 9256 break; 9257 case StreamKind.PULL_COMPLETE: 9258 if (data.success) { 9259 streamController.pullCall.resolve(); 9260 } else { 9261 streamController.pullCall.reject(wrapReason(data.reason)); 9262 } 9263 break; 9264 case StreamKind.PULL: 9265 if (!streamSink) { 9266 comObj.postMessage({ 9267 sourceName, 9268 targetName, 9269 stream: StreamKind.PULL_COMPLETE, 9270 streamId, 9271 success: true 9272 }); 9273 break; 9274 } 9275 if (streamSink.desiredSize <= 0 && data.desiredSize > 0) { 9276 streamSink.sinkCapability.resolve(); 9277 } 9278 streamSink.desiredSize = data.desiredSize; 9279 new Promise(function (resolve) { 9280 resolve(streamSink.onPull?.()); 9281 }).then(function () { 9282 comObj.postMessage({ 9283 sourceName, 9284 targetName, 9285 stream: StreamKind.PULL_COMPLETE, 9286 streamId, 9287 success: true 9288 }); 9289 }, function (reason) { 9290 comObj.postMessage({ 9291 sourceName, 9292 targetName, 9293 stream: StreamKind.PULL_COMPLETE, 9294 streamId, 9295 reason: wrapReason(reason) 9296 }); 9297 }); 9298 break; 9299 case StreamKind.ENQUEUE: 9300 (0, _util.assert)(streamController, "enqueue should have stream controller"); 9301 if (streamController.isClosed) { 9302 break; 9303 } 9304 streamController.controller.enqueue(data.chunk); 9305 break; 9306 case StreamKind.CLOSE: 9307 (0, _util.assert)(streamController, "close should have stream controller"); 9308 if (streamController.isClosed) { 9309 break; 9310 } 9311 streamController.isClosed = true; 9312 streamController.controller.close(); 9313 this.#deleteStreamController(streamController, streamId); 9314 break; 9315 case StreamKind.ERROR: 9316 (0, _util.assert)(streamController, "error should have stream controller"); 9317 streamController.controller.error(wrapReason(data.reason)); 9318 this.#deleteStreamController(streamController, streamId); 9319 break; 9320 case StreamKind.CANCEL_COMPLETE: 9321 if (data.success) { 9322 streamController.cancelCall.resolve(); 9323 } else { 9324 streamController.cancelCall.reject(wrapReason(data.reason)); 9325 } 9326 this.#deleteStreamController(streamController, streamId); 9327 break; 9328 case StreamKind.CANCEL: 9329 if (!streamSink) { 9330 break; 9331 } 9332 new Promise(function (resolve) { 9333 resolve(streamSink.onCancel?.(wrapReason(data.reason))); 9334 }).then(function () { 9335 comObj.postMessage({ 9336 sourceName, 9337 targetName, 9338 stream: StreamKind.CANCEL_COMPLETE, 9339 streamId, 9340 success: true 9341 }); 9342 }, function (reason) { 9343 comObj.postMessage({ 9344 sourceName, 9345 targetName, 9346 stream: StreamKind.CANCEL_COMPLETE, 9347 streamId, 9348 reason: wrapReason(reason) 9349 }); 9350 }); 9351 streamSink.sinkCapability.reject(wrapReason(data.reason)); 9352 streamSink.isCancelled = true; 9353 delete this.streamSinks[streamId]; 9354 break; 9355 default: 9356 throw new Error("Unexpected stream case"); 9357 } 9358 } 9359 async #deleteStreamController(streamController, streamId) { 9360 await Promise.allSettled([streamController.startCall?.promise, streamController.pullCall?.promise, streamController.cancelCall?.promise]); 9361 delete this.streamControllers[streamId]; 9362 } 9363 destroy() { 9364 this.comObj.removeEventListener("message", this._onComObjOnMessage); 9365 } 9366} 9367exports.MessageHandler = MessageHandler; 9368 9369/***/ }), 9370/* 16 */ 9371/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9372 9373 9374 9375Object.defineProperty(exports, "__esModule", ({ 9376 value: true 9377})); 9378exports.Metadata = void 0; 9379var _util = __w_pdfjs_require__(1); 9380class Metadata { 9381 #metadataMap; 9382 #data; 9383 constructor({ 9384 parsedData, 9385 rawData 9386 }) { 9387 this.#metadataMap = parsedData; 9388 this.#data = rawData; 9389 } 9390 getRaw() { 9391 return this.#data; 9392 } 9393 get(name) { 9394 return this.#metadataMap.get(name) ?? null; 9395 } 9396 getAll() { 9397 return (0, _util.objectFromMap)(this.#metadataMap); 9398 } 9399 has(name) { 9400 return this.#metadataMap.has(name); 9401 } 9402} 9403exports.Metadata = Metadata; 9404 9405/***/ }), 9406/* 17 */ 9407/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9408 9409 9410 9411Object.defineProperty(exports, "__esModule", ({ 9412 value: true 9413})); 9414exports.OptionalContentConfig = void 0; 9415var _util = __w_pdfjs_require__(1); 9416var _murmurhash = __w_pdfjs_require__(8); 9417const INTERNAL = Symbol("INTERNAL"); 9418class OptionalContentGroup { 9419 #visible = true; 9420 constructor(name, intent) { 9421 this.name = name; 9422 this.intent = intent; 9423 } 9424 get visible() { 9425 return this.#visible; 9426 } 9427 _setVisible(internal, visible) { 9428 if (internal !== INTERNAL) { 9429 (0, _util.unreachable)("Internal method `_setVisible` called."); 9430 } 9431 this.#visible = visible; 9432 } 9433} 9434class OptionalContentConfig { 9435 #cachedGetHash = null; 9436 #groups = new Map(); 9437 #initialHash = null; 9438 #order = null; 9439 constructor(data) { 9440 this.name = null; 9441 this.creator = null; 9442 if (data === null) { 9443 return; 9444 } 9445 this.name = data.name; 9446 this.creator = data.creator; 9447 this.#order = data.order; 9448 for (const group of data.groups) { 9449 this.#groups.set(group.id, new OptionalContentGroup(group.name, group.intent)); 9450 } 9451 if (data.baseState === "OFF") { 9452 for (const group of this.#groups.values()) { 9453 group._setVisible(INTERNAL, false); 9454 } 9455 } 9456 for (const on of data.on) { 9457 this.#groups.get(on)._setVisible(INTERNAL, true); 9458 } 9459 for (const off of data.off) { 9460 this.#groups.get(off)._setVisible(INTERNAL, false); 9461 } 9462 this.#initialHash = this.getHash(); 9463 } 9464 #evaluateVisibilityExpression(array) { 9465 const length = array.length; 9466 if (length < 2) { 9467 return true; 9468 } 9469 const operator = array[0]; 9470 for (let i = 1; i < length; i++) { 9471 const element = array[i]; 9472 let state; 9473 if (Array.isArray(element)) { 9474 state = this.#evaluateVisibilityExpression(element); 9475 } else if (this.#groups.has(element)) { 9476 state = this.#groups.get(element).visible; 9477 } else { 9478 (0, _util.warn)(`Optional content group not found: ${element}`); 9479 return true; 9480 } 9481 switch (operator) { 9482 case "And": 9483 if (!state) { 9484 return false;
9485 } 9486 break; 9487 case "Or": 9488 if (state) { 9489 return true; 9490 } 9491 break; 9492 case "Not": 9493 return !state; 9494 default: 9495 return true; 9496 } 9497 } 9498 return operator === "And"; 9499 } 9500 isVisible(group) { 9501 if (this.#groups.size === 0) { 9502 return true; 9503 } 9504 if (!group) { 9505 (0, _util.warn)("Optional content group not defined."); 9506 return true; 9507 } 9508 if (group.type === "OCG") { 9509 if (!this.#groups.has(group.id)) { 9510 (0, _util.warn)(`Optional content group not found: ${group.id}`); 9511 return true; 9512 } 9513 return this.#groups.get(group.id).visible; 9514 } else if (group.type === "OCMD") { 9515 if (group.expression) { 9516 return this.#evaluateVisibilityExpression(group.expression); 9517 } 9518 if (!group.policy || group.policy === "AnyOn") { 9519 for (const id of group.ids) { 9520 if (!this.#groups.has(id)) { 9521 (0, _util.warn)(`Optional content group not found: ${id}`); 9522 return true; 9523 } 9524 if (this.#groups.get(id).visible) { 9525 return true; 9526 } 9527 } 9528 return false; 9529 } else if (group.policy === "AllOn") { 9530 for (const id of group.ids) { 9531 if (!this.#groups.has(id)) { 9532 (0, _util.warn)(`Optional content group not found: ${id}`); 9533 return true; 9534 } 9535 if (!this.#groups.get(id).visible) { 9536 return false; 9537 } 9538 } 9539 return true; 9540 } else if (group.policy === "AnyOff") { 9541 for (const id of group.ids) { 9542 if (!this.#groups.has(id)) { 9543 (0, _util.warn)(`Optional content group not found: ${id}`); 9544 return true; 9545 } 9546 if (!this.#groups.get(id).visible) { 9547 return true; 9548 } 9549 } 9550 return false; 9551 } else if (group.policy === "AllOff") { 9552 for (const id of group.ids) { 9553 if (!this.#groups.has(id)) { 9554 (0, _util.warn)(`Optional content group not found: ${id}`); 9555 return true; 9556 } 9557 if (this.#groups.get(id).visible) { 9558 return false; 9559 } 9560 } 9561 return true; 9562 } 9563 (0, _util.warn)(`Unknown optional content policy ${group.policy}.`); 9564 return true; 9565 } 9566 (0, _util.warn)(`Unknown group type ${group.type}.`); 9567 return true; 9568 } 9569 setVisibility(id, visible = true) { 9570 if (!this.#groups.has(id)) { 9571 (0, _util.warn)(`Optional content group not found: ${id}`); 9572 return; 9573 } 9574 this.#groups.get(id)._setVisible(INTERNAL, !!visible); 9575 this.#cachedGetHash = null; 9576 } 9577 get hasInitialVisibility() { 9578 return this.#initialHash === null || this.getHash() === this.#initialHash; 9579 } 9580 getOrder() { 9581 if (!this.#groups.size) { 9582 return null; 9583 } 9584 if (this.#order) { 9585 return this.#order.slice(); 9586 } 9587 return [...this.#groups.keys()]; 9588 } 9589 getGroups() { 9590 return this.#groups.size > 0 ? (0, _util.objectFromMap)(this.#groups) : null; 9591 } 9592 getGroup(id) { 9593 return this.#groups.get(id) || null; 9594 } 9595 getHash() { 9596 if (this.#cachedGetHash !== null) { 9597 return this.#cachedGetHash; 9598 } 9599 const hash = new _murmurhash.MurmurHash3_64(); 9600 for (const [id, group] of this.#groups) { 9601 hash.update(`${id}:${group.visible}`); 9602 } 9603 return this.#cachedGetHash = hash.hexdigest(); 9604 } 9605} 9606exports.OptionalContentConfig = OptionalContentConfig; 9607 9608/***/ }), 9609/* 18 */ 9610/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9611 9612 9613 9614Object.defineProperty(exports, "__esModule", ({ 9615 value: true 9616})); 9617exports.PDFDataTransportStream = void 0; 9618var _util = __w_pdfjs_require__(1); 9619var _display_utils = __w_pdfjs_require__(6); 9620class PDFDataTransportStream { 9621 constructor({ 9622 length, 9623 initialData, 9624 progressiveDone = false, 9625 contentDispositionFilename = null, 9626 disableRange = false, 9627 disableStream = false 9628 }, pdfDataRangeTransport) { 9629 (0, _util.assert)(pdfDataRangeTransport, 'PDFDataTransportStream - missing required "pdfDataRangeTransport" argument.'); 9630 this._queuedChunks = []; 9631 this._progressiveDone = progressiveDone; 9632 this._contentDispositionFilename = contentDispositionFilename; 9633 if (initialData?.length > 0) { 9634 const buffer = initialData instanceof Uint8Array && initialData.byteLength === initialData.buffer.byteLength ? initialData.buffer : new Uint8Array(initialData).buffer; 9635 this._queuedChunks.push(buffer); 9636 } 9637 this._pdfDataRangeTransport = pdfDataRangeTransport; 9638 this._isStreamingSupported = !disableStream; 9639 this._isRangeSupported = !disableRange; 9640 this._contentLength = length; 9641 this._fullRequestReader = null; 9642 this._rangeReaders = []; 9643 this._pdfDataRangeTransport.addRangeListener((begin, chunk) => { 9644 this._onReceiveData({ 9645 begin, 9646 chunk 9647 }); 9648 }); 9649 this._pdfDataRangeTransport.addProgressListener((loaded, total) => { 9650 this._onProgress({ 9651 loaded, 9652 total 9653 }); 9654 }); 9655 this._pdfDataRangeTransport.addProgressiveReadListener(chunk => { 9656 this._onReceiveData({ 9657 chunk 9658 }); 9659 }); 9660 this._pdfDataRangeTransport.addProgressiveDoneListener(() => { 9661 this._onProgressiveDone(); 9662 }); 9663 this._pdfDataRangeTransport.transportReady(); 9664 } 9665 _onReceiveData({ 9666 begin, 9667 chunk 9668 }) { 9669 const buffer = chunk instanceof Uint8Array && chunk.byteLength === chunk.buffer.byteLength ? chunk.buffer : new Uint8Array(chunk).buffer; 9670 if (begin === undefined) { 9671 if (this._fullRequestReader) { 9672 this._fullRequestReader._enqueue(buffer); 9673 } else { 9674 this._queuedChunks.push(buffer); 9675 } 9676 } else { 9677 const found = this._rangeReaders.some(function (rangeReader) { 9678 if (rangeReader._begin !== begin) { 9679 return false;
9680 } 9681 rangeReader._enqueue(buffer); 9682 return true; 9683 }); 9684 (0, _util.assert)(found, "_onReceiveData - no `PDFDataTransportStreamRangeReader` instance found."); 9685 } 9686 } 9687 get _progressiveDataLength() { 9688 return this._fullRequestReader?._loaded ?? 0; 9689 } 9690 _onProgress(evt) { 9691 if (evt.total === undefined) { 9692 this._rangeReaders[0]?.onProgress?.({ 9693 loaded: evt.loaded 9694 }); 9695 } else { 9696 this._fullRequestReader?.onProgress?.({ 9697 loaded: evt.loaded, 9698 total: evt.total 9699 }); 9700 } 9701 } 9702 _onProgressiveDone() { 9703 this._fullRequestReader?.progressiveDone(); 9704 this._progressiveDone = true; 9705 } 9706 _removeRangeReader(reader) { 9707 const i = this._rangeReaders.indexOf(reader); 9708 if (i >= 0) { 9709 this._rangeReaders.splice(i, 1); 9710 } 9711 } 9712 getFullReader() { 9713 (0, _util.assert)(!this._fullRequestReader, "PDFDataTransportStream.getFullReader can only be called once."); 9714 const queuedChunks = this._queuedChunks; 9715 this._queuedChunks = null; 9716 return new PDFDataTransportStreamReader(this, queuedChunks, this._progressiveDone, this._contentDispositionFilename); 9717 } 9718 getRangeReader(begin, end) { 9719 if (end <= this._progressiveDataLength) { 9720 return null; 9721 } 9722 const reader = new PDFDataTransportStreamRangeReader(this, begin, end); 9723 this._pdfDataRangeTransport.requestDataRange(begin, end); 9724 this._rangeReaders.push(reader); 9725 return reader; 9726 } 9727 cancelAllRequests(reason) { 9728 this._fullRequestReader?.cancel(reason); 9729 for (const reader of this._rangeReaders.slice(0)) { 9730 reader.cancel(reason); 9731 } 9732 this._pdfDataRangeTransport.abort(); 9733 } 9734} 9735exports.PDFDataTransportStream = PDFDataTransportStream; 9736class PDFDataTransportStreamReader { 9737 constructor(stream, queuedChunks, progressiveDone = false, contentDispositionFilename = null) { 9738 this._stream = stream; 9739 this._done = progressiveDone || false; 9740 this._filename = (0, _display_utils.isPdfFile)(contentDispositionFilename) ? contentDispositionFilename : null; 9741 this._queuedChunks = queuedChunks || []; 9742 this._loaded = 0; 9743 for (const chunk of this._queuedChunks) { 9744 this._loaded += chunk.byteLength; 9745 } 9746 this._requests = []; 9747 this._headersReady = Promise.resolve(); 9748 stream._fullRequestReader = this; 9749 this.onProgress = null; 9750 } 9751 _enqueue(chunk) { 9752 if (this._done) { 9753 return; 9754 } 9755 if (this._requests.length > 0) { 9756 const requestCapability = this._requests.shift(); 9757 requestCapability.resolve({ 9758 value: chunk, 9759 done: false 9760 }); 9761 } else { 9762 this._queuedChunks.push(chunk); 9763 } 9764 this._loaded += chunk.byteLength; 9765 } 9766 get headersReady() { 9767 return this._headersReady; 9768 } 9769 get filename() { 9770 return this._filename; 9771 } 9772 get isRangeSupported() { 9773 return this._stream._isRangeSupported; 9774 } 9775 get isStreamingSupported() { 9776 return this._stream._isStreamingSupported; 9777 } 9778 get contentLength() { 9779 return this._stream._contentLength; 9780 } 9781 async read() { 9782 if (this._queuedChunks.length > 0) { 9783 const chunk = this._queuedChunks.shift(); 9784 return { 9785 value: chunk, 9786 done: false 9787 }; 9788 } 9789 if (this._done) { 9790 return { 9791 value: undefined, 9792 done: true 9793 }; 9794 } 9795 const requestCapability = new _util.PromiseCapability(); 9796 this._requests.push(requestCapability); 9797 return requestCapability.promise; 9798 } 9799 cancel(reason) { 9800 this._done = true; 9801 for (const requestCapability of this._requests) { 9802 requestCapability.resolve({ 9803 value: undefined, 9804 done: true 9805 }); 9806 } 9807 this._requests.length = 0; 9808 } 9809 progressiveDone() { 9810 if (this._done) { 9811 return; 9812 } 9813 this._done = true; 9814 } 9815} 9816class PDFDataTransportStreamRangeReader { 9817 constructor(stream, begin, end) { 9818 this._stream = stream; 9819 this._begin = begin; 9820 this._end = end; 9821 this._queuedChunk = null; 9822 this._requests = []; 9823 this._done = false; 9824 this.onProgress = null; 9825 } 9826 _enqueue(chunk) { 9827 if (this._done) { 9828 return; 9829 } 9830 if (this._requests.length === 0) { 9831 this._queuedChunk = chunk; 9832 } else { 9833 const requestsCapability = this._requests.shift(); 9834 requestsCapability.resolve({ 9835 value: chunk, 9836 done: false 9837 }); 9838 for (const requestCapability of this._requests) { 9839 requestCapability.resolve({ 9840 value: undefined, 9841 done: true 9842 }); 9843 } 9844 this._requests.length = 0; 9845 } 9846 this._done = true; 9847 this._stream._removeRangeReader(this); 9848 } 9849 get isStreamingSupported() { 9850 return false;
9851 } 9852 async read() { 9853 if (this._queuedChunk) { 9854 const chunk = this._queuedChunk; 9855 this._queuedChunk = null; 9856 return { 9857 value: chunk, 9858 done: false 9859 }; 9860 } 9861 if (this._done) { 9862 return { 9863 value: undefined, 9864 done: true 9865 }; 9866 } 9867 const requestCapability = new _util.PromiseCapability(); 9868 this._requests.push(requestCapability); 9869 return requestCapability.promise; 9870 } 9871 cancel(reason) { 9872 this._done = true; 9873 for (const requestCapability of this._requests) { 9874 requestCapability.resolve({ 9875 value: undefined, 9876 done: true 9877 }); 9878 } 9879 this._requests.length = 0; 9880 this._stream._removeRangeReader(this); 9881 } 9882} 9883 9884/***/ }), 9885/* 19 */ 9886/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9887 9888 9889 9890Object.defineProperty(exports, "__esModule", ({ 9891 value: true 9892})); 9893exports.PDFFetchStream = void 0; 9894var _util = __w_pdfjs_require__(1); 9895var _network_utils = __w_pdfjs_require__(20); 9896; 9897function createFetchOptions(headers, withCredentials, abortController) { 9898 return { 9899 method: "GET", 9900 headers, 9901 signal: abortController.signal, 9902 mode: "cors", 9903 credentials: withCredentials ? "include" : "same-origin", 9904 redirect: "follow" 9905 }; 9906} 9907function createHeaders(httpHeaders) { 9908 const headers = new Headers(); 9909 for (const property in httpHeaders) { 9910 const value = httpHeaders[property]; 9911 if (value === undefined) { 9912 continue; 9913 } 9914 headers.append(property, value); 9915 } 9916 return headers; 9917} 9918function getArrayBuffer(val) { 9919 if (val instanceof Uint8Array) { 9920 return val.buffer; 9921 } 9922 if (val instanceof ArrayBuffer) { 9923 return val; 9924 } 9925 (0, _util.warn)(`getArrayBuffer - unexpected data format: ${val}`); 9926 return new Uint8Array(val).buffer; 9927} 9928class PDFFetchStream { 9929 constructor(source) { 9930 this.source = source; 9931 this.isHttp = /^https?:/i.test(source.url); 9932 this.httpHeaders = this.isHttp && source.httpHeaders || {}; 9933 this._fullRequestReader = null; 9934 this._rangeRequestReaders = []; 9935 } 9936 get _progressiveDataLength() { 9937 return this._fullRequestReader?._loaded ?? 0; 9938 } 9939 getFullReader() { 9940 (0, _util.assert)(!this._fullRequestReader, "PDFFetchStream.getFullReader can only be called once."); 9941 this._fullRequestReader = new PDFFetchStreamReader(this); 9942 return this._fullRequestReader; 9943 } 9944 getRangeReader(begin, end) { 9945 if (end <= this._progressiveDataLength) { 9946 return null; 9947 } 9948 const reader = new PDFFetchStreamRangeReader(this, begin, end); 9949 this._rangeRequestReaders.push(reader); 9950 return reader; 9951 } 9952 cancelAllRequests(reason) { 9953 this._fullRequestReader?.cancel(reason); 9954 for (const reader of this._rangeRequestReaders.slice(0)) { 9955 reader.cancel(reason); 9956 } 9957 } 9958} 9959exports.PDFFetchStream = PDFFetchStream; 9960class PDFFetchStreamReader { 9961 constructor(stream) { 9962 this._stream = stream; 9963 this._reader = null; 9964 this._loaded = 0; 9965 this._filename = null; 9966 const source = stream.source; 9967 this._withCredentials = source.withCredentials || false; 9968 this._contentLength = source.length; 9969 this._headersCapability = new _util.PromiseCapability(); 9970 this._disableRange = source.disableRange || false; 9971 this._rangeChunkSize = source.rangeChunkSize; 9972 if (!this._rangeChunkSize && !this._disableRange) { 9973 this._disableRange = true; 9974 } 9975 this._abortController = new AbortController(); 9976 this._isStreamingSupported = !source.disableStream; 9977 this._isRangeSupported = !source.disableRange; 9978 this._headers = createHeaders(this._stream.httpHeaders); 9979 const url = source.url; 9980 fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(response => { 9981 if (!(0, _network_utils.validateResponseStatus)(response.status)) { 9982 throw (0, _network_utils.createResponseStatusError)(response.status, url); 9983 } 9984 this._reader = response.body.getReader(); 9985 this._headersCapability.resolve(); 9986 const getResponseHeader = name => { 9987 return response.headers.get(name); 9988 }; 9989 const { 9990 allowRangeRequests, 9991 suggestedLength 9992 } = (0, _network_utils.validateRangeRequestCapabilities)({ 9993 getResponseHeader, 9994 isHttp: this._stream.isHttp, 9995 rangeChunkSize: this._rangeChunkSize, 9996 disableRange: this._disableRange 9997 }); 9998 this._isRangeSupported = allowRangeRequests; 9999 this._contentLength = suggestedLength || this._contentLength; 10000 this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader); 10001 if (!this._isStreamingSupported && this._isRangeSupported) { 10002 this.cancel(new _util.AbortException("Streaming is disabled.")); 10003 } 10004 }).catch(this._headersCapability.reject); 10005 this.onProgress = null; 10006 } 10007 get headersReady() { 10008 return this._headersCapability.promise; 10009 } 10010 get filename() { 10011 return this._filename; 10012 } 10013 get contentLength() { 10014 return this._contentLength; 10015 } 10016 get isRangeSupported() { 10017 return this._isRangeSupported; 10018 } 10019 get isStreamingSupported() { 10020 return this._isStreamingSupported; 10021 } 10022 async read() { 10023 await this._headersCapability.promise; 10024 const { 10025 value, 10026 done 10027 } = await this._reader.read(); 10028 if (done) { 10029 return { 10030 value, 10031 done 10032 }; 10033 } 10034 this._loaded += value.byteLength; 10035 this.onProgress?.({ 10036 loaded: this._loaded, 10037 total: this._contentLength 10038 }); 10039 return { 10040 value: getArrayBuffer(value), 10041 done: false 10042 }; 10043 } 10044 cancel(reason) { 10045 this._reader?.cancel(reason); 10046 this._abortController.abort(); 10047 } 10048} 10049class PDFFetchStreamRangeReader { 10050 constructor(stream, begin, end) { 10051 this._stream = stream; 10052 this._reader = null; 10053 this._loaded = 0; 10054 const source = stream.source; 10055 this._withCredentials = source.withCredentials || false; 10056 this._readCapability = new _util.PromiseCapability(); 10057 this._isStreamingSupported = !source.disableStream; 10058 this._abortController = new AbortController(); 10059 this._headers = createHeaders(this._stream.httpHeaders); 10060 this._headers.append("Range", `bytes=${begin}
10060-${end - 1}`); 10061 const url = source.url; 10062 fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(response => { 10063 if (!(0, _network_utils.validateResponseStatus)(response.status)) { 10064 throw (0, _network_utils.createResponseStatusError)(response.status, url); 10065 } 10066 this._readCapability.resolve(); 10067 this._reader = response.body.getReader(); 10068 }).catch(this._readCapability.reject); 10069 this.onProgress = null; 10070 } 10071 get isStreamingSupported() { 10072 return this._isStreamingSupported; 10073 } 10074 async read() { 10075 await this._readCapability.promise; 10076 const { 10077 value, 10078 done 10079 } = await this._reader.read(); 10080 if (done) { 10081 return { 10082 value, 10083 done 10084 }; 10085 } 10086 this._loaded += value.byteLength; 10087 this.onProgress?.({ 10088 loaded: this._loaded 10089 }); 10090 return { 10091 value: getArrayBuffer(value), 10092 done: false 10093 }; 10094 } 10095 cancel(reason) { 10096 this._reader?.cancel(reason); 10097 this._abortController.abort(); 10098 } 10099} 10100 10101/***/ }), 10102/* 20 */ 10103/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 10104 10105 10106 10107Object.defineProperty(exports, "__esModule", ({ 10108 value: true 10109})); 10110exports.createResponseStatusError = createResponseStatusError; 10111exports.extractFilenameFromHeader = extractFilenameFromHeader; 10112exports.validateRangeRequestCapabilities = validateRangeRequestCapabilities; 10113exports.validateResponseStatus = validateResponseStatus; 10114var _util = __w_pdfjs_require__(1); 10115var _content_disposition = __w_pdfjs_require__(21); 10116var _display_utils = __w_pdfjs_require__(6); 10117function validateRangeRequestCapabilities({ 10118 getResponseHeader, 10119 isHttp, 10120 rangeChunkSize, 10121 disableRange 10122}) { 10123 const returnValues = { 10124 allowRangeRequests: false, 10125 suggestedLength: undefined 10126 }; 10127 const length = parseInt(getResponseHeader("Content-Length"), 10); 10128 if (!Number.isInteger(length)) { 10129 return returnValues; 10130 } 10131 returnValues.suggestedLength = length; 10132 if (length <= 2 * rangeChunkSize) { 10133 return returnValues; 10134 } 10135 if (disableRange || !isHttp) { 10136 return returnValues; 10137 } 10138 if (getResponseHeader("Accept-Ranges") !== "bytes") { 10139 return returnValues; 10140 } 10141 const contentEncoding = getResponseHeader("Content-Encoding") || "identity"; 10142 if (contentEncoding !== "identity") { 10143 return returnValues; 10144 } 10145 returnValues.allowRangeRequests = true; 10146 return returnValues; 10147} 10148function extractFilenameFromHeader(getResponseHeader) { 10149 const contentDisposition = getResponseHeader("Content-Disposition"); 10150 if (contentDisposition) { 10151 let filename = (0, _content_disposition.getFilenameFromContentDispositionHeader)(contentDisposition); 10152 if (filename.includes("%")) { 10153 try { 10154 filename = decodeURIComponent(filename); 10155 } catch {} 10156 } 10157 if ((0, _display_utils.isPdfFile)(filename)) { 10158 return filename; 10159 } 10160 } 10161 return null; 10162} 10163function createResponseStatusError(status, url) { 10164 if (status === 404 || status === 0 && url.startsWith("file:")) { 10165 return new _util.MissingPDFException('Missing PDF "' + url + '".'); 10166 } 10167 return new _util.UnexpectedResponseException(`Unexpected server response (${status}) while retrieving PDF "${url}".`, status); 10168} 10169function validateResponseStatus(status) { 10170 return status === 200 || status === 206; 10171} 10172 10173/***/ }), 10174/* 21 */ 10175/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 10176 10177 10178 10179Object.defineProperty(exports, "__esModule", ({ 10180 value: true 10181})); 10182exports.getFilenameFromContentDispositionHeader = getFilenameFromContentDispositionHeader; 10183var _util = __w_pdfjs_require__(1); 10184function getFilenameFromContentDispositionHeader(contentDisposition) { 10185 let needsEncodingFixup = true; 10186 let tmp = toParamRegExp("filename\\*", "i").exec(contentDisposition); 10187 if (tmp) { 10188 tmp = tmp[1]; 10189 let filename = rfc2616unquote(tmp); 10190 filename = unescape(filename); 10191 filename = rfc5987decode(filename); 10192 filename = rfc2047decode(filename); 10193 return fixupEncoding(filename); 10194 } 10195 tmp = rfc2231getparam(contentDisposition); 10196 if (tmp) { 10197 const filename = rfc2047decode(tmp); 10198 return fixupEncoding(filename); 10199 } 10200 tmp = toParamRegExp("filename", "i").exec(contentDisposition); 10201 if (tmp) { 10202 tmp = tmp[1]; 10203 let filename = rfc2616unquote(tmp); 10204 filename = rfc2047decode(filename); 10205 return fixupEncoding(filename); 10206 } 10207 function toParamRegExp(attributePattern, flags) { 10208 return new RegExp("(?:^|;)\\s*" + attributePattern + "\\s*=\\s*" + "(" + '[^";\\s][^;\\s]*' + "|" + '"(?:[^"\\\\]|\\\\"?)+"?' + ")", flags); 10209 } 10210 function textdecode(encoding, value) { 10211 if (encoding) { 10212 if (!/^[\x00-\xFF]+$/.test(value)) { 10213 return value; 10214 }
10215 try { 10216 const decoder = new TextDecoder(encoding, { 10217 fatal: true 10218 }); 10219 const buffer = (0, _util.stringToBytes)(value); 10220 value = decoder.decode(buffer); 10221 needsEncodingFixup = false; 10222 } catch {} 10223 } 10224 return value; 10225 } 10226 function fixupEncoding(value) { 10227 if (needsEncodingFixup && /[\x80-\xff]/.test(value)) { 10228 value = textdecode("utf-8", value); 10229 if (needsEncodingFixup) { 10230 value = textdecode("iso-8859-1", value); 10231 } 10232 } 10233 return value; 10234 } 10235 function rfc2231getparam(contentDispositionStr) { 10236 const matches = []; 10237 let match; 10238 const iter = toParamRegExp("filename\\*((?!0\\d)\\d+)(\\*?)", "ig"); 10239 while ((match = iter.exec(contentDispositionStr)) !== null) { 10240 let [, n, quot, part] = match; 10241 n = parseInt(n, 10); 10242 if (n in matches) { 10243 if (n === 0) { 10244 break; 10245 } 10246 continue; 10247 } 10248 matches[n] = [quot, part]; 10249 } 10250 const parts = []; 10251 for (let n = 0; n < matches.length; ++n) { 10252 if (!(n in matches)) { 10253 break; 10254 } 10255 let [quot, part] = matches[n]; 10256 part = rfc2616unquote(part); 10257 if (quot) { 10258 part = unescape(part); 10259 if (n === 0) { 10260 part = rfc5987decode(part); 10261 } 10262 } 10263 parts.push(part); 10264 } 10265 return parts.join(""); 10266 } 10267 function rfc2616unquote(value) { 10268 if (value.startsWith('"')) { 10269 const parts = value.slice(1).split('\\"'); 10270 for (let i = 0; i < parts.length; ++i) { 10271 const quotindex = parts[i].indexOf('"'); 10272 if (quotindex !== -1) { 10273 parts[i] = parts[i].slice(0, quotindex); 10274 parts.length = i + 1; 10275 } 10276 parts[i] = parts[i].replaceAll(/\\(.)/g, "$1"); 10277 } 10278 value = parts.join('"'); 10279 } 10280 return value; 10281 } 10282 function rfc5987decode(extvalue) { 10283 const encodingend = extvalue.indexOf("'"); 10284 if (encodingend === -1) { 10285 return extvalue; 10286 } 10287 const encoding = extvalue.slice(0, encodingend); 10288 const langvalue = extvalue.slice(encodingend + 1); 10289 const value = langvalue.replace(/^[^']*'/, ""); 10290 return textdecode(encoding, value); 10291 } 10292 function rfc2047decode(value) { 10293 if (!value.startsWith("=?") || /[\x00-\x19\x80-\xff]/.test(value)) { 10294 return value; 10295 } 10296 return value.replaceAll(/=\?([\w-]*)\?([QqBb])\?((?:[^?]|\?(?!=))*)\?=/g, function (matches, charset, encoding, text) { 10297 if (encoding === "q" || encoding === "Q") { 10298 text = text.replaceAll("_", " "); 10299 text = text.replaceAll(/=([0-9a-fA-F]{2})/g, function (match, hex) { 10300 return String.fromCharCode(parseInt(hex, 16)); 10301 }); 10302 return textdecode(charset, text); 10303 } 10304 try { 10305 text = atob(text); 10306 } catch {} 10307 return textdecode(charset, text); 10308 }); 10309 } 10310 return ""; 10311} 10312 10313/***/ }), 10314/* 22 */ 10315/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 10316 10317 10318 10319Object.defineProperty(exports, "__esModule", ({ 10320 value: true 10321})); 10322exports.PDFNetworkStream = void 0; 10323var _util = __w_pdfjs_require__(1); 10324var _network_utils = __w_pdfjs_require__(20); 10325; 10326const OK_RESPONSE = 200; 10327const PARTIAL_CONTENT_RESPONSE = 206; 10328function getArrayBuffer(xhr) { 10329 const data = xhr.response; 10330 if (typeof data !== "string") { 10331 return data; 10332 } 10333 return (0, _util.stringToBytes)(data).buffer; 10334} 10335class NetworkManager { 10336 constructor(url, args = {}) { 10337 this.url = url; 10338 this.isHttp = /^https?:/i.test(url); 10339 this.httpHeaders = this.isHttp && args.httpHeaders || Object.create(null); 10340 this.withCredentials = args.withCredentials || false; 10341 this.currXhrId = 0; 10342 this.pendingRequests = Object.create(null); 10343 } 10344 requestRange(begin, end, listeners) { 10345 const args = { 10346 begin, 10347 end 10348 }; 10349 for (const prop in listeners) { 10350 args[prop] = listeners[prop]; 10351 } 10352 return this.request(args); 10353 } 10354 requestFull(listeners) { 10355 return this.request(listeners); 10356 } 10357 request(args) { 10358 const xhr = new XMLHttpRequest(); 10359 const xhrId = this.currXhrId++; 10360 const pendingRequest = this.pendingRequests[xhrId] = { 10361 xhr 10362 }; 10363 xhr.open("GET", this.url); 10364 xhr.withCredentials = this.withCredentials; 10365 for (const property in this.httpHeaders) { 10366 const value = this.httpHeaders[property]; 10367 if (value === undefined) { 10368 continue; 10369 } 10370 xhr.setRequestHeader(property, value); 10371 } 10372 if (this.isHttp && "begin" in args && "end" in args) { 10373 xhr.setRequestHeader("Range", `bytes=${args.begin}-${args.end - 1}`); 10374 pendingRequest.expectedStatus = PARTIAL_CONTENT_RESPONSE; 10375 } else { 10376 pendingRequest.expectedStatus = OK_RESPONSE; 10377 } 10378 xhr.responseType = "arraybuffer"; 10379 if (args.onError) { 10380 xhr.onerror = function (evt) { 10381 args.onError(xhr.status); 10382 }; 10383 } 10384 xhr.onreadystatechange = this.onStateChange.bind(this, xhrId); 10385 xhr.onprogress = this.onProgress.bind(this, xhrId); 10386 pendingRequest.onHeadersReceived = args.onHeadersReceived; 10387 pendingRequest.onDone = args.onDone; 10388 pendingRequest.onError = args.onError; 10389 pendingRequest.onProgress = args.onProgress; 10390 xhr.send(null); 10391 return xhrId; 10392 } 10393 onProgress(xhrId, evt) { 10394 const pendingRequest = this.pendingRequests[xhrId]; 10395 if (!pendingRequest) { 10396 return; 10397 } 10398 pendingRequest.onProgress?.(evt); 10399 } 10400 onStateChange(xhrId, evt) { 10401 const pendingRequest = this.pendingRequests[xhrId]; 10402 if (!pendingRequest) { 10403 return; 10404 } 10405 const xhr = pendingRequest.xhr; 10406 if (xhr.readyState >= 2 && pendingRequest.onHeadersReceived) { 10407 pendingRequest.onHeadersReceived();
10408 delete pendingRequest.onHeadersReceived; 10409 } 10410 if (xhr.readyState !== 4) { 10411 return; 10412 } 10413 if (!(xhrId in this.pendingRequests)) { 10414 return; 10415 } 10416 delete this.pendingRequests[xhrId]; 10417 if (xhr.status === 0 && this.isHttp) { 10418 pendingRequest.onError?.(xhr.status); 10419 return; 10420 } 10421 const xhrStatus = xhr.status || OK_RESPONSE; 10422 const ok_response_on_range_request = xhrStatus === OK_RESPONSE && pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE; 10423 if (!ok_response_on_range_request && xhrStatus !== pendingRequest.expectedStatus) { 10424 pendingRequest.onError?.(xhr.status); 10425 return; 10426 } 10427 const chunk = getArrayBuffer(xhr); 10428 if (xhrStatus === PARTIAL_CONTENT_RESPONSE) { 10429 const rangeHeader = xhr.getResponseHeader("Content-Range"); 10430 const matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader); 10431 pendingRequest.onDone({ 10432 begin: parseInt(matches[1], 10), 10433 chunk 10434 }); 10435 } else if (chunk) { 10436 pendingRequest.onDone({ 10437 begin: 0, 10438 chunk 10439 }); 10440 } else { 10441 pendingRequest.onError?.(xhr.status); 10442 } 10443 } 10444 getRequestXhr(xhrId) { 10445 return this.pendingRequests[xhrId].xhr; 10446 } 10447 isPendingRequest(xhrId) { 10448 return xhrId in this.pendingRequests; 10449 } 10450 abortRequest(xhrId) { 10451 const xhr = this.pendingRequests[xhrId].xhr; 10452 delete this.pendingRequests[xhrId]; 10453 xhr.abort(); 10454 } 10455} 10456class PDFNetworkStream { 10457 constructor(source) { 10458 this._source = source; 10459 this._manager = new NetworkManager(source.url, { 10460 httpHeaders: source.httpHeaders, 10461 withCredentials: source.withCredentials 10462 }); 10463 this._rangeChunkSize = source.rangeChunkSize; 10464 this._fullRequestReader = null; 10465 this._rangeRequestReaders = []; 10466 } 10467 _onRangeRequestReaderClosed(reader) { 10468 const i = this._rangeRequestReaders.indexOf(reader); 10469 if (i >= 0) { 10470 this._rangeRequestReaders.splice(i, 1); 10471 } 10472 } 10473 getFullReader() { 10474 (0, _util.assert)(!this._fullRequestReader, "PDFNetworkStream.getFullReader can only be called once."); 10475 this._fullRequestReader = new PDFNetworkStreamFullRequestReader(this._manager, this._source); 10476 return this._fullRequestReader; 10477 } 10478 getRangeReader(begin, end) { 10479 const reader = new PDFNetworkStreamRangeRequestReader(this._manager, begin, end); 10480 reader.onClosed = this._onRangeRequestReaderClosed.bind(this); 10481 this._rangeRequestReaders.push(reader); 10482 return reader; 10483 } 10484 cancelAllRequests(reason) { 10485 this._fullRequestReader?.cancel(reason); 10486 for (const reader of this._rangeRequestReaders.slice(0)) { 10487 reader.cancel(reason); 10488 } 10489 } 10490} 10491exports.PDFNetworkStream = PDFNetworkStream; 10492class PDFNetworkStreamFullRequestReader { 10493 constructor(manager, source) { 10494 this._manager = manager; 10495 const args = { 10496 onHeadersReceived: this._onHeadersReceived.bind(this), 10497 onDone: this._onDone.bind(this), 10498 onError: this._onError.bind(this), 10499 onProgress: this._onProgress.bind(this) 10500 }; 10501 this._url = source.url; 10502 this._fullRequestId = manager.requestFull(args); 10503 this._headersReceivedCapability = new _util.PromiseCapability(); 10504 this._disableRange = source.disableRange || false; 10505 this._contentLength = source.length; 10506 this._rangeChunkSize = source.rangeChunkSize; 10507 if (!this._rangeChunkSize && !this._disableRange) { 10508 this._disableRange = true; 10509 } 10510 this._isStreamingSupported = false; 10511 this._isRangeSupported = false; 10512 this._cachedChunks = []; 10513 this._requests = []; 10514 this._done = false; 10515 this._storedError = undefined; 10516 this._filename = null; 10517 this.onProgress = null; 10518 } 10519 _onHeadersReceived() { 10520 const fullRequestXhrId = this._fullRequestId; 10521 const fullRequestXhr = this._manager.getRequestXhr(fullRequestXhrId); 10522 const getResponseHeader = name => { 10523 return fullRequestXhr.getResponseHeader(name); 10524 }; 10525 const { 10526 allowRangeRequests, 10527 suggestedLength 10528 } = (0, _network_utils.validateRangeRequestCapabilities)({ 10529 getResponseHeader, 10530 isHttp: this._manager.isHttp, 10531 rangeChunkSize: this._rangeChunkSize, 10532 disableRange: this._disableRange 10533 }); 10534 if (allowRangeRequests) { 10535 this._isRangeSupported = true; 10536 } 10537 this._contentLength = suggestedLength || this._contentLength; 10538 this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader); 10539 if (this._isRangeSupported) {
10540 this._manager.abortRequest(fullRequestXhrId); 10541 } 10542 this._headersReceivedCapability.resolve(); 10543 } 10544 _onDone(data) { 10545 if (data) { 10546 if (this._requests.length > 0) { 10547 const requestCapability = this._requests.shift(); 10548 requestCapability.resolve({ 10549 value: data.chunk, 10550 done: false 10551 }); 10552 } else { 10553 this._cachedChunks.push(data.chunk); 10554 } 10555 } 10556 this._done = true; 10557 if (this._cachedChunks.length > 0) { 10558 return; 10559 } 10560 for (const requestCapability of this._requests) { 10561 requestCapability.resolve({ 10562 value: undefined, 10563 done: true 10564 }); 10565 } 10566 this._requests.length = 0; 10567 } 10568 _onError(status) { 10569 this._storedError = (0, _network_utils.createResponseStatusError)(status, this._url); 10570 this._headersReceivedCapability.reject(this._storedError); 10571 for (const requestCapability of this._requests) { 10572 requestCapability.reject(this._storedError); 10573 } 10574 this._requests.length = 0; 10575 this._cachedChunks.length = 0; 10576 } 10577 _onProgress(evt) { 10578 this.onProgress?.({ 10579 loaded: evt.loaded, 10580 total: evt.lengthComputable ? evt.total : this._contentLength 10581 }); 10582 } 10583 get filename() { 10584 return this._filename; 10585 } 10586 get isRangeSupported() { 10587 return this._isRangeSupported; 10588 } 10589 get isStreamingSupported() { 10590 return this._isStreamingSupported; 10591 } 10592 get contentLength() { 10593 return this._contentLength; 10594 } 10595 get headersReady() { 10596 return this._headersReceivedCapability.promise; 10597 } 10598 async read() { 10599 if (this._storedError) { 10600 throw this._storedError; 10601 } 10602 if (this._cachedChunks.length > 0) { 10603 const chunk = this._cachedChunks.shift(); 10604 return { 10605 value: chunk, 10606 done: false 10607 }; 10608 } 10609 if (this._done) { 10610 return { 10611 value: undefined, 10612 done: true 10613 }; 10614 } 10615 const requestCapability = new _util.PromiseCapability(); 10616 this._requests.push(requestCapability); 10617 return requestCapability.promise; 10618 } 10619 cancel(reason) { 10620 this._done = true; 10621 this._headersReceivedCapability.reject(reason); 10622 for (const requestCapability of this._requests) { 10623 requestCapability.resolve({ 10624 value: undefined, 10625 done: true 10626 }); 10627 } 10628 this._requests.length = 0; 10629 if (this._manager.isPendingRequest(this._fullRequestId)) { 10630 this._manager.abortRequest(this._fullRequestId); 10631 } 10632 this._fullRequestReader = null; 10633 } 10634} 10635class PDFNetworkStreamRangeRequestReader { 10636 constructor(manager, begin, end) { 10637 this._manager = manager; 10638 const args = { 10639 onDone: this._onDone.bind(this), 10640 onError: this._onError.bind(this), 10641 onProgress: this._onProgress.bind(this) 10642 }; 10643 this._url = manager.url; 10644 this._requestId = manager.requestRange(begin, end, args); 10645 this._requests = []; 10646 this._queuedChunk = null; 10647 this._done = false; 10648 this._storedError = undefined; 10649 this.onProgress = null; 10650 this.onClosed = null; 10651 } 10652 _close() { 10653 this.onClosed?.(this); 10654 } 10655 _onDone(data) { 10656 const chunk = data.chunk; 10657 if (this._requests.length > 0) { 10658 const requestCapability = this._requests.shift(); 10659 requestCapability.resolve({ 10660 value: chunk, 10661 done: false 10662 }); 10663 } else { 10664 this._queuedChunk = chunk; 10665 } 10666 this._done = true; 10667 for (const requestCapability of this._requests) { 10668 requestCapability.resolve({ 10669 value: undefined, 10670 done: true 10671 }); 10672 } 10673 this._requests.length = 0; 10674 this._close(); 10675 } 10676 _onError(status) { 10677 this._storedError = (0, _network_utils.createResponseStatusError)(status, this._url); 10678 for (const requestCapability of this._requests) { 10679 requestCapability.reject(this._storedError); 10680 } 10681 this._requests.length = 0; 10682 this._queuedChunk = null; 10683 } 10684 _onProgress(evt) { 10685 if (!this.isStreamingSupported) { 10686 this.onProgress?.({ 10687 loaded: evt.loaded 10688 }); 10689 } 10690 } 10691 get isStreamingSupported() { 10692 return false; 10693 } 10694 async read() { 10695 if (this._storedError) { 10696 throw this._storedError; 10697 } 10698 if (this._queuedChunk !== null) { 10699 const chunk = this._queuedChunk; 10700 this._queuedChunk = null; 10701 return { 10702 value: chunk, 10703 done: false 10704 }; 10705 } 10706 if (this._done) { 10707 return { 10708 value: undefined, 10709 done: true 10710 }; 10711 } 10712 const requestCapability = new _util.PromiseCapability(); 10713 this._requests.push(requestCapability); 10714 return requestCapability.promise; 10715 } 10716 cancel(reason) { 10717 this._done = true; 10718 for (const requestCapability of this._requests) { 10719 requestCapability.resolve({ 10720 value: undefined, 10721 done: true 10722 }); 10723 } 10724 this._requests.length = 0; 10725 if (this._manager.isPendingRequest(this._requestId)) {
10726 this._manager.abortRequest(this._requestId); 10727 } 10728 this._close(); 10729 } 10730} 10731 10732/***/ }), 10733/* 23 */ 10734/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 10735 10736 10737 10738Object.defineProperty(exports, "__esModule", ({ 10739 value: true 10740})); 10741exports.PDFNodeStream = void 0; 10742var _util = __w_pdfjs_require__(1); 10743var _network_utils = __w_pdfjs_require__(20); 10744; 10745const fileUriRegex = /^file:\/\/\/[a-zA-Z]:\//; 10746function parseUrl(sourceUrl) { 10747 const url = require("url"); 10748 const parsedUrl = url.parse(sourceUrl); 10749 if (parsedUrl.protocol === "file:" || parsedUrl.host) { 10750 return parsedUrl; 10751 } 10752 if (/^[a-z]:[/\\]/i.test(sourceUrl)) { 10753 return url.parse(`file:///${sourceUrl}`); 10754 } 10755 if (!parsedUrl.host) { 10756 parsedUrl.protocol = "file:"; 10757 } 10758 return parsedUrl; 10759} 10760class PDFNodeStream { 10761 constructor(source) { 10762 this.source = source; 10763 this.url = parseUrl(source.url); 10764 this.isHttp = this.url.protocol === "http:" || this.url.protocol === "https:" || this.url.protocol === "capacitor:"; 10765 this.isFsUrl = this.url.protocol === "file:"; 10766 this.httpHeaders = this.isHttp && source.httpHeaders || {}; 10767 this._fullRequestReader = null; 10768 this._rangeRequestReaders = []; 10769 } 10770 get _progressiveDataLength() { 10771 return this._fullRequestReader?._loaded ?? 0; 10772 } 10773 getFullReader() { 10774 (0, _util.assert)(!this._fullRequestReader, "PDFNodeStream.getFullReader can only be called once."); 10775 this._fullRequestReader = this.isFsUrl ? new PDFNodeStreamFsFullReader(this) : new PDFNodeStreamFullReader(this); 10776 return this._fullRequestReader; 10777 } 10778 getRangeReader(start, end) { 10779 if (end <= this._progressiveDataLength) { 10780 return null; 10781 } 10782 const rangeReader = this.isFsUrl ? new PDFNodeStreamFsRangeReader(this, start, end) : new PDFNodeStreamRangeReader(this, start, end); 10783 this._rangeRequestReaders.push(rangeReader); 10784 return rangeReader; 10785 } 10786 cancelAllRequests(reason) { 10787 this._fullRequestReader?.cancel(reason); 10788 for (const reader of this._rangeRequestReaders.slice(0)) { 10789 reader.cancel(reason); 10790 } 10791 } 10792} 10793exports.PDFNodeStream = PDFNodeStream; 10794class BaseFullReader { 10795 constructor(stream) { 10796 this._url = stream.url; 10797 this._done = false; 10798 this._storedError = null; 10799 this.onProgress = null; 10800 const source = stream.source; 10801 this._contentLength = source.length; 10802 this._loaded = 0; 10803 this._filename = null; 10804 this._disableRange = source.disableRange || false; 10805 this._rangeChunkSize = source.rangeChunkSize; 10806 if (!this._rangeChunkSize && !this._disableRange) { 10807 this._disableRange = true; 10808 } 10809 this._isStreamingSupported = !source.disableStream; 10810 this._isRangeSupported = !source.disableRange; 10811 this._readableStream = null; 10812 this._readCapability = new _util.PromiseCapability(); 10813 this._headersCapability = new _util.PromiseCapability(); 10814 } 10815 get headersReady() { 10816 return this._headersCapability.promise; 10817 } 10818 get filename() { 10819 return this._filename; 10820 } 10821 get contentLength() { 10822 return this._contentLength; 10823 } 10824 get isRangeSupported() { 10825 return this._isRangeSupported; 10826 } 10827 get isStreamingSupported() { 10828 return this._isStreamingSupported; 10829 } 10830 async read() { 10831 await this._readCapability.promise; 10832 if (this._done) { 10833 return { 10834 value: undefined, 10835 done: true 10836 }; 10837 } 10838 if (this._storedError) { 10839 throw this._storedError; 10840 } 10841 const chunk = this._readableStream.read(); 10842 if (chunk === null) { 10843 this._readCapability = new _util.PromiseCapability(); 10844 return this.read(); 10845 } 10846 this._loaded += chunk.length; 10847 this.onProgress?.({ 10848 loaded: this._loaded, 10849 total: this._contentLength 10850 }); 10851 const buffer = new Uint8Array(chunk).buffer; 10852 return { 10853 value: buffer, 10854 done: false 10855 }; 10856 } 10857 cancel(reason) { 10858 if (!this._readableStream) { 10859 this._error(reason); 10860 return; 10861 } 10862 this._readableStream.destroy(reason); 10863 } 10864 _error(reason) { 10865 this._storedError = reason; 10866 this._readCapability.resolve(); 10867 } 10868 _setReadableStream(readableStream) { 10869 this._readableStream = readableStream; 10870 readableStream.on("readable", () => { 10871 this._readCapability.resolve(); 10872 }); 10873 readableStream.on("end", () => { 10874 readableStream.destroy(); 10875 this._done = true; 10876 this._readCapability.resolve(); 10877 }); 10878 readableStream.on("error", reason => { 10879 this._error(reason); 10880 }); 10881 if (!this._isStreamingSupported && this._isRangeSupported) { 10882 this._error(new _util.AbortException("streaming is disabled")); 10883 } 10884 if (this._storedError) { 10885 this._readableStream.destroy(this._storedError); 10886 } 10887 } 10888} 10889class BaseRangeReader { 10890 constructor(stream) { 10891 this._url = stream.url; 10892 this._done = false;
10893 this._storedError = null; 10894 this.onProgress = null; 10895 this._loaded = 0; 10896 this._readableStream = null; 10897 this._readCapability = new _util.PromiseCapability(); 10898 const source = stream.source; 10899 this._isStreamingSupported = !source.disableStream; 10900 } 10901 get isStreamingSupported() { 10902 return this._isStreamingSupported; 10903 } 10904 async read() { 10905 await this._readCapability.promise; 10906 if (this._done) { 10907 return { 10908 value: undefined, 10909 done: true 10910 }; 10911 } 10912 if (this._storedError) { 10913 throw this._storedError; 10914 } 10915 const chunk = this._readableStream.read(); 10916 if (chunk === null) { 10917 this._readCapability = new _util.PromiseCapability(); 10918 return this.read(); 10919 } 10920 this._loaded += chunk.length; 10921 this.onProgress?.({ 10922 loaded: this._loaded 10923 }); 10924 const buffer = new Uint8Array(chunk).buffer; 10925 return { 10926 value: buffer, 10927 done: false 10928 }; 10929 } 10930 cancel(reason) { 10931 if (!this._readableStream) { 10932 this._error(reason); 10933 return; 10934 } 10935 this._readableStream.destroy(reason); 10936 } 10937 _error(reason) { 10938 this._storedError = reason; 10939 this._readCapability.resolve(); 10940 } 10941 _setReadableStream(readableStream) { 10942 this._readableStream = readableStream; 10943 readableStream.on("readable", () => { 10944 this._readCapability.resolve(); 10945 }); 10946 readableStream.on("end", () => { 10947 readableStream.destroy(); 10948 this._done = true; 10949 this._readCapability.resolve(); 10950 }); 10951 readableStream.on("error", reason => { 10952 this._error(reason); 10953 }); 10954 if (this._storedError) { 10955 this._readableStream.destroy(this._storedError); 10956 } 10957 } 10958} 10959function createRequestOptions(parsedUrl, headers) { 10960 return { 10961 protocol: parsedUrl.protocol, 10962 auth: parsedUrl.auth, 10963 host: parsedUrl.hostname, 10964 port: parsedUrl.port, 10965 path: parsedUrl.path, 10966 method: "GET", 10967 headers 10968 }; 10969} 10970class PDFNodeStreamFullReader extends BaseFullReader { 10971 constructor(stream) { 10972 super(stream); 10973 const handleResponse = response => { 10974 if (response.statusCode === 404) { 10975 const error = new _util.MissingPDFException(`Missing PDF "${this._url}".`); 10976 this._storedError = error; 10977 this._headersCapability.reject(error); 10978 return; 10979 } 10980 this._headersCapability.resolve(); 10981 this._setReadableStream(response); 10982 const getResponseHeader = name => { 10983 return this._readableStream.headers[name.toLowerCase()]; 10984 }; 10985 const { 10986 allowRangeRequests, 10987 suggestedLength 10988 } = (0, _network_utils.validateRangeRequestCapabilities)({ 10989 getResponseHeader, 10990 isHttp: stream.isHttp, 10991 rangeChunkSize: this._rangeChunkSize, 10992 disableRange: this._disableRange 10993 }); 10994 this._isRangeSupported = allowRangeRequests; 10995 this._contentLength = suggestedLength || this._contentLength; 10996 this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader); 10997 }; 10998 this._request = null; 10999 if (this._url.protocol === "http:") { 11000 const http = require("http"); 11001 this._request = http.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse); 11002 } else { 11003 const https = require("https"); 11004 this._request = https.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse); 11005 } 11006 this._request.on("error", reason => { 11007 this._storedError = reason; 11008 this._headersCapability.reject(reason); 11009 }); 11010 this._request.end(); 11011 } 11012} 11013class PDFNodeStreamRangeReader extends BaseRangeReader { 11014 constructor(stream, start, end) { 11015 super(stream); 11016 this._httpHeaders = {}; 11017 for (const property in stream.httpHeaders) { 11018 const value = stream.httpHeaders[property]; 11019 if (value === undefined) { 11020 continue; 11021 } 11022 this._httpHeaders[property] = value; 11023 } 11024 this._httpHeaders.Range = `bytes=${start}-${end - 1}`; 11025 const handleResponse = response => { 11026 if (response.statusCode === 404) { 11027 const error = new _util.MissingPDFException(`Missing PDF "${this._url}".`); 11028 this._storedError = error; 11029 return; 11030 } 11031 this._setReadableStream(response); 11032 }; 11033 this._request = null; 11034 if (this._url.protocol === "http:") { 11035 const http = require("http"); 11036 this._request = http.request(createRequestOptions(this._url, this._httpHeaders), handleResponse); 11037 } else { 11038 const https = require("https"); 11039 this._request = https.request(createRequestOptions(this._url, this._httpHeaders), handleResponse); 11040 } 11041 this._request.on("error", reason => { 11042 this._storedError = reason; 11043 }); 11044 this._request.end(); 11045 } 11046} 11047class PDFNodeStreamFsFullReader extends BaseFullReader { 11048 constructor(stream) { 11049 super(stream); 11050 let path = decodeURIComponent(this._url.path); 11051 if (fileUriRegex.test(this._url.href)) { 11052 path = path.replace(/^\//, ""); 11053 } 11054 const fs = require("fs"); 11055 fs.lstat(path, (error, stat) => { 11056 if (error) { 11057 if (error.code === "ENOENT") { 11058 error = new _util.MissingPDFException(`Missing PDF "${path}".`); 11059 } 11060 this._storedError = error; 11061 this._headersCapability.reject(error); 11062 return; 11063 } 11064 this._contentLength = stat.size; 11065 this._setReadableStream(fs.createReadStream(path)); 11066 this._headersCapability.resolve(); 11067 }); 11068 } 11069} 11070class PDFNodeStreamFsRangeReader extends BaseRangeReader { 11071 constructor(stream, start, end) { 11072 super(stream); 11073 let path = decodeURIComponent(this._url.path); 11074 if (fileUriRegex.test(this._url.href)) { 11075 path = path.replace(/^\//, ""); 11076 } 11077 const fs = require("fs"); 11078 this._setReadableStream(fs.createReadStream(path, { 11079 start, 11080 end: end - 1 11081 })); 11082 } 11083} 11084 11085/***/ }), 11086/* 24 */ 11087/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 11088 11089 11090 11091Object.defineProperty(exports, "__esModule", ({ 11092 value: true 11093})); 11094exports.SVGGraphics = void 0; 11095var _display_utils = __w_pdfjs_require__(6); 11096var _util = __w_pdfjs_require__(1); 11097; 11098const SVG_DEFAULTS = { 11099 fontStyle: "normal", 11100 fontWeight: "normal", 11101 fillColor: "#000000" 11102}; 11103const XML_NS = "http://www.w3.org/XML/1998/namespace"; 11104const XLINK_NS = "http://www.w3.org/1999/xlink"; 11105const LINE_CAP_STYLES = ["butt", "round", "square"]; 11106const LINE_JOIN_STYLES = ["miter", "round", "bevel"]; 11107const createObjectURL = function (data, contentType = "", forceDataSchema = false) { 11108 if (URL.createObjectURL && typeof Blob !== "undefined" && !forceDataSchema) { 11109 return URL.createObjectURL(new Blob([data], { 11110 type: contentType 11111 })); 11112 } 11113 const digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
11113+/="; 11114 let buffer = `data:${contentType};base64,`; 11115 for (let i = 0, ii = data.length; i < ii; i += 3) { 11116 const b1 = data[i] & 0xff; 11117 const b2 = data[i + 1] & 0xff; 11118 const b3 = data[i + 2] & 0xff; 11119 const d1 = b1 >> 2, 11120 d2 = (b1 & 3) << 4 | b2 >> 4; 11121 const d3 = i + 1 < ii ? (b2 & 0xf) << 2 | b3 >> 6 : 64; 11122 const d4 = i + 2 < ii ? b3 & 0x3f : 64; 11123 buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4]; 11124 } 11125 return buffer; 11126}; 11127const convertImgDataToPng = function () { 11128 const PNG_HEADER = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); 11129 const CHUNK_WRAPPER_SIZE = 12; 11130 const crcTable = new Int32Array(256); 11131 for (let i = 0; i < 256; i++) { 11132 let c = i; 11133 for (let h = 0; h < 8; h++) { 11134 c = c & 1 ? 0xedb88320 ^ c >> 1 & 0x7fffffff : c >> 1 & 0x7fffffff; 11135 } 11136 crcTable[i] = c; 11137 } 11138 function crc32(data, start, end) { 11139 let crc = -1; 11140 for (let i = start; i < end; i++) { 11141 const a = (crc ^ data[i]) & 0xff; 11142 const b = crcTable[a]; 11143 crc = crc >>> 8 ^ b; 11144 } 11145 return crc ^ -1; 11146 } 11147 function writePngChunk(type, body, data, offset) { 11148 let p = offset; 11149 const len = body.length; 11150 data[p] = len >> 24 & 0xff; 11151 data[p + 1] = len >> 16 & 0xff; 11152 data[p + 2] = len >> 8 & 0xff; 11153 data[p + 3] = len & 0xff; 11154 p += 4; 11155 data[p] = type.charCodeAt(0) & 0xff; 11156 data[p + 1] = type.charCodeAt(1) & 0xff; 11157 data[p + 2] = type.charCodeAt(2) & 0xff;
11158 data[p + 3] = type.charCodeAt(3) & 0xff; 11159 p += 4; 11160 data.set(body, p); 11161 p += body.length; 11162 const crc = crc32(data, offset + 4, p); 11163 data[p] = crc >> 24 & 0xff; 11164 data[p + 1] = crc >> 16 & 0xff; 11165 data[p + 2] = crc >> 8 & 0xff; 11166 data[p + 3] = crc & 0xff; 11167 } 11168 function adler32(data, start, end) { 11169 let a = 1; 11170 let b = 0; 11171 for (let i = start; i < end; ++i) { 11172 a = (a + (data[i] & 0xff)) % 65521; 11173 b = (b + a) % 65521; 11174 } 11175 return b << 16 | a; 11176 } 11177 function deflateSync(literals) { 11178 if (!_util.isNodeJS) { 11179 return deflateSyncUncompressed(literals); 11180 } 11181 try { 11182 const input = parseInt(process.versions.node) >= 8 ? literals : Buffer.from(literals); 11183 const output = require("zlib").deflateSync(input, { 11184 level: 9 11185 }); 11186 return output instanceof Uint8Array ? output : new Uint8Array(output); 11187 } catch (e) { 11188 (0, _util.warn)("Not compressing PNG because zlib.deflateSync is unavailable: " + e); 11189 } 11190 return deflateSyncUncompressed(literals); 11191 } 11192 function deflateSyncUncompressed(literals) { 11193 let len = literals.length; 11194 const maxBlockLength = 0xffff; 11195 const deflateBlocks = Math.ceil(len / maxBlockLength); 11196 const idat = new Uint8Array(2 + len + deflateBlocks * 5 + 4); 11197 let pi = 0; 11198 idat[pi++] = 0x78; 11199 idat[pi++] = 0x9c; 11200 let pos = 0; 11201 while (len > maxBlockLength) { 11202 idat[pi++] = 0x00; 11203 idat[pi++] = 0xff; 11204 idat[pi++] = 0xff; 11205 idat[pi++] = 0x00; 11206 idat[pi++] = 0x00; 11207 idat.set(literals.subarray(pos, pos + maxBlockLength), pi); 11208 pi += maxBlockLength; 11209 pos += maxBlockLength; 11210 len -= maxBlockLength; 11211 } 11212 idat[pi++] = 0x01; 11213 idat[pi++] = len & 0xff; 11214 idat[pi++] = len >> 8 & 0xff; 11215 idat[pi++] = ~len & 0xffff & 0xff; 11216 idat[pi++] = (~len & 0xffff) >> 8 & 0xff; 11217 idat.set(literals.subarray(pos), pi); 11218 pi += literals.length - pos; 11219 const adler = adler32(literals, 0, literals.length); 11220 idat[pi++] = adler >> 24 & 0xff; 11221 idat[pi++] = adler >> 16 & 0xff; 11222 idat[pi++] = adler >> 8 & 0xff; 11223 idat[pi++] = adler & 0xff; 11224 return idat; 11225 } 11226 function encode(imgData, kind, forceDataSchema, isMask) { 11227 const width = imgData.width; 11228 const height = imgData.height; 11229 let bitDepth, colorType, lineSize; 11230 const bytes = imgData.data; 11231 switch (kind) { 11232 case _util.ImageKind.GRAYSCALE_1BPP: 11233 colorType = 0; 11234 bitDepth = 1; 11235 lineSize = width + 7 >> 3; 11236 break; 11237 case _util.ImageKind.RGB_24BPP: 11238 colorType = 2; 11239 bitDepth = 8; 11240 lineSize = width * 3; 11241 break; 11242 case _util.ImageKind.RGBA_32BPP: 11243 colorType = 6; 11244 bitDepth = 8; 11245 lineSize = width * 4; 11246 break; 11247 default: 11248 throw new Error("invalid format"); 11249 } 11250 const literals = new Uint8Array((1 + lineSize) * height); 11251 let offsetLiterals = 0, 11252 offsetBytes = 0; 11253 for (let y = 0; y < height; ++y) { 11254 literals[offsetLiterals++] = 0; 11255 literals.set(bytes.subarray(offsetBytes, offsetBytes + lineSize), offsetLiterals); 11256 offsetBytes += lineSize; 11257 offsetLiterals += lineSize; 11258 } 11259 if (kind === _util.ImageKind.GRAYSCALE_1BPP && isMask) { 11260 offsetLiterals = 0; 11261 for (let y = 0; y < height; y++) { 11262 offsetLiterals++; 11263 for (let i = 0; i < lineSize; i++) { 11264 literals[offsetLiterals++] ^= 0xff; 11265 } 11266 } 11267 } 11268 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]); 11269 const idat = deflateSync(literals); 11270 const pngLength = PNG_HEADER.length + CHUNK_WRAPPER_SIZE * 3 + ihdr.length + idat.length; 11271 const data = new Uint8Array(pngLength); 11272 let offset = 0; 11273 data.set(PNG_HEADER, offset); 11274 offset += PNG_HEADER.length; 11275 writePngChunk("IHDR", ihdr, data, offset); 11276 offset += CHUNK_WRAPPER_SIZE + ihdr.length; 11277 writePngChunk("IDATA", idat, data, offset); 11278 offset += CHUNK_WRAPPER_SIZE + idat.length; 11279 writePngChunk("IEND", new Uint8Array(0), data, offset); 11280 return createObjectURL(data, "image/png", forceDataSchema); 11281 } 11282 return function convertImgDataToPng(imgData, forceDataSchema, isMask) {
11283 const kind = imgData.kind === undefined ? _util.ImageKind.GRAYSCALE_1BPP : imgData.kind; 11284 return encode(imgData, kind, forceDataSchema, isMask); 11285 }; 11286}(); 11287class SVGExtraState { 11288 constructor() { 11289 this.fontSizeScale = 1; 11290 this.fontWeight = SVG_DEFAULTS.fontWeight; 11291 this.fontSize = 0; 11292 this.textMatrix = _util.IDENTITY_MATRIX; 11293 this.fontMatrix = _util.FONT_IDENTITY_MATRIX; 11294 this.leading = 0; 11295 this.textRenderingMode = _util.TextRenderingMode.FILL; 11296 this.textMatrixScale = 1; 11297 this.x = 0; 11298 this.y = 0; 11299 this.lineX = 0; 11300 this.lineY = 0; 11301 this.charSpacing = 0; 11302 this.wordSpacing = 0; 11303 this.textHScale = 1; 11304 this.textRise = 0; 11305 this.fillColor = SVG_DEFAULTS.fillColor; 11306 this.strokeColor = "#000000"; 11307 this.fillAlpha = 1; 11308 this.strokeAlpha = 1; 11309 this.lineWidth = 1; 11310 this.lineJoin = ""; 11311 this.lineCap = ""; 11312 this.miterLimit = 0; 11313 this.dashArray = []; 11314 this.dashPhase = 0; 11315 this.dependencies = []; 11316 this.activeClipUrl = null; 11317 this.clipGroup = null; 11318 this.maskId = ""; 11319 } 11320 clone() { 11321 return Object.create(this); 11322 } 11323 setCurrentPoint(x, y) { 11324 this.x = x; 11325 this.y = y; 11326 } 11327} 11328function opListToTree(opList) { 11329 let opTree = []; 11330 const tmp = []; 11331 for (const opListElement of opList) { 11332 if (opListElement.fn === "save") { 11333 opTree.push({ 11334 fnId: 92, 11335 fn: "group", 11336 items: [] 11337 }); 11338 tmp.push(opTree); 11339 opTree = opTree.at(-1).items; 11340 continue; 11341 } 11342 if (opListElement.fn === "restore") { 11343 opTree = tmp.pop(); 11344 } else { 11345 opTree.push(opListElement); 11346 } 11347 } 11348 return opTree; 11349} 11350function pf(value) { 11351 if (Number.isInteger(value)) { 11352 return value.toString(); 11353 } 11354 const s = value.toFixed(10); 11355 let i = s.length - 1; 11356 if (s[i] !== "0") { 11357 return s; 11358 } 11359 do { 11360 i--; 11361 } while (s[i] === "0"); 11362 return s.substring(0, s[i] === "." ? i : i + 1); 11363} 11364function pm(m) { 11365 if (m[4] === 0 && m[5] === 0) { 11366 if (m[1] === 0 && m[2] === 0) { 11367 if (m[0] === 1 && m[3] === 1) { 11368 return ""; 11369 } 11370 return `scale(${pf(m[0])} ${pf(m[3])})`; 11371 } 11372 if (m[0] === m[3] && m[1] === -m[2]) { 11373 const a = Math.acos(m[0]) * 180 / Math.PI; 11374 return `rotate(${pf(a)})`; 11375 } 11376 } else if (m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1) { 11377 return `translate(${pf(m[4])} ${pf(m[5])})`; 11378 } 11379 return `matrix(${pf(m[0])} ${pf(m[1])} ${pf(m[2])} ${pf(m[3])} ${pf(m[4])} ` + `${pf(m[5])})`; 11380} 11381let clipCount = 0; 11382let maskCount = 0; 11383let shadingCount = 0; 11384class SVGGraphics { 11385 constructor(commonObjs, objs, forceDataSchema = false) { 11386 (0, _display_utils.deprecated)("The SVG back-end is no longer maintained and *may* be removed in the future."); 11387 this.svgFactory = new _display_utils.DOMSVGFactory(); 11388 this.current = new SVGExtraState(); 11389 this.transformMatrix = _util.IDENTITY_MATRIX; 11390 this.transformStack = []; 11391 this.extraStack = []; 11392 this.commonObjs = commonObjs; 11393 this.objs = objs; 11394 this.pendingClip = null; 11395 this.pendingEOFill = false; 11396 this.embedFonts = false; 11397 this.embeddedFonts = Object.create(null); 11398 this.cssStyle = null; 11399 this.forceDataSchema = !!forceDataSchema; 11400 this._operatorIdMapping = []; 11401 for (const op in _util.OPS) { 11402 this._operatorIdMapping[_util.OPS[op]] = op; 11403 } 11404 } 11405 getObject(data, fallback = null) { 11406 if (typeof data === "string") { 11407 return data.startsWith("g_") ? this.commonObjs.get(data) : this.objs.get(data); 11408 } 11409 return fallback; 11410 } 11411 save() { 11412 this.transformStack.push(this.transformMatrix); 11413 const old = this.current; 11414 this.extraStack.push(old); 11415 this.current = old.clone(); 11416 } 11417 restore() { 11418 this.transformMatrix = this.transformStack.pop(); 11419 this.current = this.extraStack.pop(); 11420 this.pendingClip = null; 11421 this.tgrp = null; 11422 } 11423 group(items) { 11424 this.save(); 11425 this.executeOpTree(items); 11426 this.restore(); 11427 } 11428 loadDependencies(operatorList) { 11429 const fnArray = operatorList.fnArray; 11430 const argsArray = operatorList.argsArray; 11431 for (let i = 0, ii = fnArray.length; i < ii; i++) { 11432 if (fnArray[i] !== _util.OPS.dependency) { 11433 continue; 11434 } 11435 for (const obj of argsArray[i]) { 11436 const objsPool = obj.startsWith("g_") ? this.commonObjs : this.objs; 11437 const promise = new Promise(resolve => { 11438 objsPool.get(obj, resolve); 11439 }); 11440 this.current.dependencies.push(promise); 11441 } 11442 } 11443 return Promise.all(this.current.dependencies); 11444 } 11445 transform(a, b, c, d, e, f) { 11446 const transformMatrix = [a, b, c, d, e, f]; 11447 this.transformMatrix = _util.Util.transform(this.transformMatrix, transformMatrix); 11448 this.tgrp = null; 11449 } 11450 getSVG(operatorList, viewport) { 11451 this.viewport = viewport; 11452 const svgElement = this._initialize(viewport); 11453 return this.loadDependencies(operatorList).then(() => { 11454 this.transformMatrix = _util.IDENTITY_MATRIX; 11455 this.executeOpTree(this.convertOpList(operatorList)); 11456 return svgElement; 11457 }); 11458 } 11459 convertOpList(operatorList) { 11460 const operatorIdMapping = this._operatorIdMapping; 11461 const argsArray = operatorList.argsArray; 11462 const fnArray = operatorList.fnArray; 11463 const opList = []; 11464 for (let i = 0, ii = fnArray.length; i < ii; i++) { 11465 const fnId = fnArray[i]; 11466 opList.push({ 11467 fnId, 11468 fn: operatorIdMapping[fnId], 11469 args: argsArray[i] 11470 }); 11471 } 11472 return opListToTree(opList); 11473 } 11474 executeOpTree(opTree) { 11475 for (const opTreeElement of opTree) { 11476 const fn = opTreeElement.fn; 11477 const fnId = opTreeElement.fnId; 11478 const args = opTreeElement.args;
11479 switch (fnId | 0) { 11480 case _util.OPS.beginText: 11481 this.beginText(); 11482 break; 11483 case _util.OPS.dependency: 11484 break; 11485 case _util.OPS.setLeading: 11486 this.setLeading(args); 11487 break; 11488 case _util.OPS.setLeadingMoveText: 11489 this.setLeadingMoveText(args[0], args[1]); 11490 break; 11491 case _util.OPS.setFont: 11492 this.setFont(args); 11493 break; 11494 case _util.OPS.showText: 11495 this.showText(args[0]); 11496 break; 11497 case _util.OPS.showSpacedText: 11498 this.showText(args[0]); 11499 break; 11500 case _util.OPS.endText: 11501 this.endText(); 11502 break; 11503 case _util.OPS.moveText: 11504 this.moveText(args[0], args[1]); 11505 break; 11506 case _util.OPS.setCharSpacing: 11507 this.setCharSpacing(args[0]); 11508 break; 11509 case _util.OPS.setWordSpacing: 11510 this.setWordSpacing(args[0]); 11511 break; 11512 case _util.OPS.setHScale: 11513 this.setHScale(args[0]); 11514 break; 11515 case _util.OPS.setTextMatrix: 11516 this.setTextMatrix(args[0], args[1], args[2], args[3], args[4], args[5]); 11517 break; 11518 case _util.OPS.setTextRise: 11519 this.setTextRise(args[0]); 11520 break; 11521 case _util.OPS.setTextRenderingMode: 11522 this.setTextRenderingMode(args[0]); 11523 break; 11524 case _util.OPS.setLineWidth: 11525 this.setLineWidth(args[0]); 11526 break; 11527 case _util.OPS.setLineJoin: 11528 this.setLineJoin(args[0]); 11529 break; 11530 case _util.OPS.setLineCap: 11531 this.setLineCap(args[0]); 11532 break; 11533 case _util.OPS.setMiterLimit: 11534 this.setMiterLimit(args[0]); 11535 break; 11536 case _util.OPS.setFillRGBColor: 11537 this.setFillRGBColor(args[0], args[1], args[2]); 11538 break; 11539 case _util.OPS.setStrokeRGBColor: 11540 this.setStrokeRGBColor(args[0], args[1], args[2]); 11541 break; 11542 case _util.OPS.setStrokeColorN: 11543 this.setStrokeColorN(args); 11544 break; 11545 case _util.OPS.setFillColorN: 11546 this.setFillColorN(args); 11547 break; 11548 case _util.OPS.shadingFill: 11549 this.shadingFill(args[0]); 11550 break; 11551 case _util.OPS.setDash: 11552 this.setDash(args[0], args[1]); 11553 break; 11554 case _util.OPS.setRenderingIntent: 11555 this.setRenderingIntent(args[0]); 11556 break; 11557 case _util.OPS.setFlatness: 11558 this.setFlatness(args[0]); 11559 break; 11560 case _util.OPS.setGState: 11561 this.setGState(args[0]); 11562 break; 11563 case _util.OPS.fill: 11564 this.fill(); 11565 break; 11566 case _util.OPS.eoFill: 11567 this.eoFill(); 11568 break; 11569 case _util.OPS.stroke: 11570 this.stroke(); 11571 break; 11572 case _util.OPS.fillStroke: 11573 this.fillStroke(); 11574 break; 11575 case _util.OPS.eoFillStroke: 11576 this.eoFillStroke(); 11577 break; 11578 case _util.OPS.clip: 11579 this.clip("nonzero"); 11580 break; 11581 case _util.OPS.eoClip: 11582 this.clip("evenodd"); 11583 break; 11584 case _util.OPS.paintSolidColorImageMask: 11585 this.paintSolidColorImageMask(); 11586 break; 11587 case _util.OPS.paintImageXObject: 11588 this.paintImageXObject(args[0]); 11589 break; 11590 case _util.OPS.paintInlineImageXObject: 11591 this.paintInlineImageXObject(args[0]); 11592 break; 11593 case _util.OPS.paintImageMaskXObject: 11594 this.paintImageMaskXObject(args[0]); 11595 break; 11596 case _util.OPS.paintFormXObjectBegin: 11597 this.paintFormXObjectBegin(args[0], args[1]); 11598 break; 11599 case _util.OPS.paintFormXObjectEnd: 11600 this.paintFormXObjectEnd(); 11601 break; 11602 case _util.OPS.closePath: 11603 this.closePath(); 11604 break; 11605 case _util.OPS.closeStroke: 11606 this.closeStroke(); 11607 break; 11608 case _util.OPS.closeFillStroke: 11609 this.closeFillStroke(); 11610 break; 11611 case _util.OPS.closeEOFillStroke: 11612 this.closeEOFillStroke(); 11613 break; 11614 case _util.OPS.nextLine: 11615 this.nextLine(); 11616 break; 11617 case _util.OPS.transform: 11618 this.transform(args[0], args[1], args[2], args[3], args[4], args[5]); 11619 break; 11620 case _util.OPS.constructPath: 11621 this.constructPath(args[0], args[1]); 11622 break; 11623 case _util.OPS.endPath: 11624 this.endPath(); 11625 break; 11626 case 92: 11627 this.group(opTreeElement.items); 11628 break; 11629 default: 11630 (0, _util.warn)(`Unimplemented operator ${fn}`); 11631 break; 11632 } 11633 } 11634 } 11635 setWordSpacing(wordSpacing) { 11636 this.current.wordSpacing = wordSpacing; 11637 } 11638 setCharSpacing(charSpacing) { 11639 this.current.charSpacing = charSpacing; 11640 } 11641 nextLine() { 11642 this.moveText(0, this.current.leading); 11643 } 11644 setTextMatrix(a, b, c, d, e, f) { 11645 const current = this.current; 11646 current.textMatrix = current.lineMatrix = [a, b, c, d, e, f]; 11647 current.textMatrixScale = Math.hypot(a, b); 11648 current.x = current.lineX = 0; 11649 current.y = current.lineY = 0; 11650 current.xcoords = []; 11651 current.ycoords = []; 11652 current.tspan = this.svgFactory.createElement("svg:tspan"); 11653 current.tspan.setAttributeNS(null, "font-family", current.fontFamily); 11654 current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`); 11655 current.tspan.setAttributeNS(null, "y", pf(-current.y)); 11656 current.txtElement = this.svgFactory.createElement("svg:text"); 11657 current.txtElement.append(current.tspan); 11658 } 11659 beginText() { 11660 const current = this.current; 11661 current.x = current.lineX = 0; 11662 current.y = current.lineY = 0; 11663 current.textMatrix = _util.IDENTITY_MATRIX; 11664 current.lineMatrix = _util.IDENTITY_MATRIX; 11665 current.textMatrixScale = 1; 11666 current.tspan = this.svgFactory.createElement("svg:tspan"); 11667 current.txtElement = this.svgFactory.createElement("svg:text"); 11668 current.txtgrp = this.svgFactory.createElement("svg:g"); 11669 current.xcoords = []; 11670 current.ycoords = []; 11671 } 11672 moveText(x, y) { 11673 const current = this.current; 11674 current.x = current.lineX += x; 11675 current.y = current.lineY += y; 11676 current.xcoords = []; 11677 current.ycoords = []; 11678 current.tspan = this.svgFactory.createElement("svg:tspan"); 11679 current.tspan.setAttributeNS(null, "font-family", current.fontFamily); 11680 current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`); 11681 current.tspan.setAttributeNS(null, "y", pf(-current.y)); 11682 } 11683 showText(glyphs) { 11684 const current = this.current; 11685 const font = current.font; 11686 const fontSize = current.fontSize; 11687 if (fontSize === 0) { 11688 return; 11689 } 11690 const fontSizeScale = current.fontSizeScale; 11691 const charSpacing = current.charSpacing; 11692 const wordSpacing = current.wordSpacing; 11693 const fontDirection = current.fontDirection; 11694 const textHScale = current.textHScale * fontDirection; 11695 const vertical = font.vertical; 11696 const spacingDir = vertical ? 1 : -1; 11697 const defaultVMetrics = font.defaultVMetrics; 11698 const widthAdvanceScale = fontSize * current.fontMatrix[0]; 11699 let x = 0; 11700 for (const glyph of glyphs) { 11701 if (glyph === null) { 11702 x += fontDirection * wordSpacing; 11703 continue; 11704 }
11704 else if (typeof glyph === "number") { 11705 x += spacingDir * glyph * fontSize / 1000; 11706 continue; 11707 } 11708 const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 11709 const character = glyph.fontChar; 11710 let scaledX, scaledY; 11711 let width = glyph.width; 11712 if (vertical) { 11713 let vx; 11714 const vmetric = glyph.vmetric || defaultVMetrics; 11715 vx = glyph.vmetric ? vmetric[1] : width * 0.5; 11716 vx = -vx * widthAdvanceScale; 11717 const vy = vmetric[2] * widthAdvanceScale; 11718 width = vmetric ? -vmetric[0] : width; 11719 scaledX = vx / fontSizeScale; 11720 scaledY = (x + vy) / fontSizeScale; 11721 } else { 11722 scaledX = x / fontSizeScale; 11723 scaledY = 0; 11724 } 11725 if (glyph.isInFont || font.missingFile) { 11726 current.xcoords.push(current.x + scaledX); 11727 if (vertical) { 11728 current.ycoords.push(-current.y + scaledY); 11729 } 11730 current.tspan.textContent += character; 11731 } else {} 11732 const charWidth = vertical ? width * widthAdvanceScale - spacing * fontDirection : width * widthAdvanceScale + spacing * fontDirection; 11733 x += charWidth; 11734 } 11735 current.tspan.setAttributeNS(null, "x", current.xcoords.map(pf).join(" ")); 11736 if (vertical) { 11737 current.tspan.setAttributeNS(null, "y", current.ycoords.map(pf).join(" ")); 11738 } else { 11739 current.tspan.setAttributeNS(null, "y", pf(-current.y)); 11740 } 11741 if (vertical) { 11742 current.y -= x; 11743 } else { 11744 current.x += x * textHScale; 11745 } 11746 current.tspan.setAttributeNS(null, "font-family", current.fontFamily); 11747 current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`); 11748 if (current.fontStyle !== SVG_DEFAULTS.fontStyle) { 11749 current.tspan.setAttributeNS(null, "font-style", current.fontStyle); 11750 } 11751 if (current.fontWeight !== SVG_DEFAULTS.fontWeight) { 11752 current.tspan.setAttributeNS(null, "font-weight", current.fontWeight); 11753 } 11754 const fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; 11755 if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 11756 if (current.fillColor !== SVG_DEFAULTS.fillColor) { 11757 current.tspan.setAttributeNS(null, "fill", current.fillColor); 11758 } 11759 if (current.fillAlpha < 1) { 11760 current.tspan.setAttributeNS(null, "fill-opacity", current.fillAlpha); 11761 } 11762 } else if (current.textRenderingMode === _util.TextRenderingMode.ADD_TO_PATH) { 11763 current.tspan.setAttributeNS(null, "fill", "transparent"); 11764 } else { 11765 current.tspan.setAttributeNS(null, "fill", "none"); 11766 } 11767 if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 11768 const lineWidthScale = 1 / (current.textMatrixScale || 1); 11769 this._setStrokeAttributes(current.tspan, lineWidthScale); 11770 } 11771 let textMatrix = current.textMatrix; 11772 if (current.textRise !== 0) { 11773 textMatrix = textMatrix.slice(); 11774 textMatrix[5] += current.textRise; 11775 } 11776 current.txtElement.setAttributeNS(null, "transform", `${pm(textMatrix)} scale(${pf(textHScale)}, -1)`); 11777 current.txtElement.setAttributeNS(XML_NS, "xml:space", "preserve"); 11778 current.txtElement.append(current.tspan); 11779 current.txtgrp.append(current.txtElement); 11780 this._ensureTransformGroup().append(current.txtElement); 11781 } 11782 setLeadingMoveText(x, y) { 11783 this.setLeading(-y); 11784 this.moveText(x, y); 11785 } 11786 addFontStyle(fontObj) { 11787 if (!fontObj.data) { 11788 throw new Error("addFontStyle: No font data available, " + 'ensure that the "fontExtraProperties" API parameter is set.'); 11789 } 11790 if (!this.cssStyle) { 11791 this.cssStyle = this.svgFactory.createElement("svg:style"); 11792 this.cssStyle.setAttributeNS(null, "type", "text/css"); 11793 this.defs.append(this.cssStyle); 11794 } 11795 const url = createObjectURL(fontObj.data, fontObj.mimetype, this.forceDataSchema); 11796 this.cssStyle.textContent += `@font-face { font-family: "${fontObj.loadedName}";` + ` src: url(${url}); }\n`; 11797 } 11798 setFont(details) { 11799 const current = this.current; 11800 const fontObj = this.commonObjs.get(details[0]); 11801 let size = details[1]; 11802 current.font = fontObj; 11803 if (this.embedFonts && !fontObj.missingFile && !this.embeddedFonts[fontObj.loadedName]) { 11804 this.addFontStyle(fontObj); 11805 this.embeddedFonts[fontObj.loadedName] = fontObj; 11806 } 11807 current.fontMatrix = fontObj.fontMatrix || _util.FONT_IDENTITY_MATRIX; 11808 let bold = "normal"; 11809 if (fontObj.black) { 11810 bold = "900"; 11811 } else if (fontObj.bold) { 11812 bold = "bold"; 11813 } 11814 const italic = fontObj.italic ? "italic" : "normal"; 11815 if (size < 0) { 11816 size = -size; 11817 current.fontDirection = -1; 11818 } else { 11819 current.fontDirection = 1; 11820 } 11821 current.fontSize = size; 11822 current.fontFamily = fontObj.loadedName; 11823 current.fontWeight = bold; 11824 current.fontStyle = italic; 11825 current.tspan = this.svgFactory.createElement("svg:tspan"); 11826 current.tspan.setAttributeNS(null, "y", pf(-current.y)); 11827 current.xcoords = []; 11828 current.ycoords = []; 11829 } 11830 endText() { 11831 const current = this.current; 11832 if (current.textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG && current.txtElement?.hasChildNodes()) { 11833 current.element = current.txtElement; 11834 this.clip("nonzero"); 11835 this.endPath(); 11836 } 11837 } 11838 setLineWidth(width) { 11839 if (width > 0) { 11840 this.current.lineWidth = width; 11841 } 11842 } 11843 setLineCap(style) { 11844 this.current.lineCap = LINE_CAP_STYLES[style]; 11845 } 11846 setLineJoin(style) { 11847 this.current.lineJoin = LINE_JOIN_STYLES[style]; 11848 } 11849 setMiterLimit(limit) { 11850 this.current.miterLimit = limit; 11851 } 11852 setStrokeAlpha(strokeAlpha) { 11853 this.current.strokeAlpha = strokeAlpha; 11854 } 11855 setStrokeRGBColor(r, g, b) { 11856 this.current.strokeColor = _util.Util.makeHexColor(r, g, b); 11857 } 11858 setFillAlpha(fillAlpha) { 11859 this.current.fillAlpha = fillAlpha; 11860 } 11861 setFillRGBColor(r, g, b) { 11862 this.current.fillColor = _util.Util.makeHexColor(r, g, b); 11863 this.current.tspan = this.svgFactory.createElement("svg:tspan"); 11864 this.current.xcoords = []; 11865 this.current.ycoords = []; 11866 } 11867 setStrokeColorN(args) { 11868 this.current.strokeColor = this._makeColorN_Pattern(args); 11869 } 11870 setFillColorN(args) { 11871 this.current.fillColor = this._makeColorN_Pattern(args); 11872 } 11873 shadingFill(args) { 11874 const { 11875 width, 11876 height 11877 } = this.viewport; 11878 const inv = _util.Util.inverseTransform(this.transformMatrix); 11879 const [x0, y0, x1, y1] = _util.Util.getAxialAlignedBoundingBox([0, 0, width, height], inv); 11880 const rect = this.svgFactory.createElement("svg:rect"); 11881 rect.setAttributeNS(null, "x", x0); 11882 rect.setAttributeNS(null, "y", y0); 11883 rect.setAttributeNS(null, "width", x1 - x0); 11884 rect.setAttributeNS(null, "height", y1 - y0); 11885 rect.setAttributeNS(null, "fill", this._makeShadingPattern(args)); 11886 if (this.current.fillAlpha < 1) { 11887 rect.setAttributeNS(null, "fill-opacity", this.current.fillAlpha); 11888 } 11889 this._ensureTransformGroup().append(rect); 11890 } 11891 _makeColorN_Pattern(args) { 11892 if (args[0] === "TilingPattern") { 11893 return this._makeTilingPattern(args); 11894 } 11895 return this._makeShadingPattern(args); 11896 } 11897 _makeTilingPattern(args) { 11898 const color = args[1]; 11899 const operatorList = args[2]; 11900 const matrix = args[3] || _util.IDENTITY_MATRIX; 11901 const [x0, y0, x1, y1] = args[4]; 11902 const xstep = args[5]; 11903 const ystep = args[6]; 11904 const paintType = args[7]; 11905 const tilingId = `shading${shadingCount++}`; 11906 const [tx0, ty0, tx1, ty1] = _util.Util.normalizeRect([..._util.Util.applyTransform([x0, y0
11906], matrix), ..._util.Util.applyTransform([x1, y1], matrix)]); 11907 const [xscale, yscale] = _util.Util.singularValueDecompose2dScale(matrix); 11908 const txstep = xstep * xscale; 11909 const tystep = ystep * yscale; 11910 const tiling = this.svgFactory.createElement("svg:pattern"); 11911 tiling.setAttributeNS(null, "id", tilingId); 11912 tiling.setAttributeNS(null, "patternUnits", "userSpaceOnUse"); 11913 tiling.setAttributeNS(null, "width", txstep); 11914 tiling.setAttributeNS(null, "height", tystep); 11915 tiling.setAttributeNS(null, "x", `${tx0}`); 11916 tiling.setAttributeNS(null, "y", `${ty0}`); 11917 const svg = this.svg; 11918 const transformMatrix = this.transformMatrix; 11919 const fillColor = this.current.fillColor; 11920 const strokeColor = this.current.strokeColor; 11921 const bbox = this.svgFactory.create(tx1 - tx0, ty1 - ty0); 11922 this.svg = bbox; 11923 this.transformMatrix = matrix; 11924 if (paintType === 2) { 11925 const cssColor = _util.Util.makeHexColor(...color); 11926 this.current.fillColor = cssColor; 11927 this.current.strokeColor = cssColor; 11928 } 11929 this.executeOpTree(this.convertOpList(operatorList)); 11930 this.svg = svg; 11931 this.transformMatrix = transformMatrix; 11932 this.current.fillColor = fillColor; 11933 this.current.strokeColor = strokeColor; 11934 tiling.append(bbox.childNodes[0]); 11935 this.defs.append(tiling); 11936 return `url(#${tilingId})`; 11937 } 11938 _makeShadingPattern(args) { 11939 if (typeof args === "string") { 11940 args = this.objs.get(args); 11941 } 11942 switch (args[0]) { 11943 case "RadialAxial": 11944 const shadingId = `shading${shadingCount++}`; 11945 const colorStops = args[3]; 11946 let gradient; 11947 switch (args[1]) { 11948 case "axial": 11949 const point0 = args[4]; 11950 const point1 = args[5]; 11951 gradient = this.svgFactory.createElement("svg:linearGradient"); 11952 gradient.setAttributeNS(null, "id", shadingId); 11953 gradient.setAttributeNS(null, "gradientUnits", "userSpaceOnUse"); 11954 gradient.setAttributeNS(null, "x1", point0[0]); 11955 gradient.setAttributeNS(null, "y1", point0[1]); 11956 gradient.setAttributeNS(null, "x2", point1[0]); 11957 gradient.setAttributeNS(null, "y2", point1[1]); 11958 break; 11959 case "radial": 11960 const focalPoint = args[4]; 11961 const circlePoint = args[5]; 11962 const focalRadius = args[6]; 11963 const circleRadius = args[7]; 11964 gradient = this.svgFactory.createElement("svg:radialGradient"); 11965 gradient.setAttributeNS(null, "id", shadingId); 11966 gradient.setAttributeNS(null, "gradientUnits", "userSpaceOnUse"); 11967 gradient.setAttributeNS(null, "cx", circlePoint[0]); 11968 gradient.setAttributeNS(null, "cy", circlePoint[1]); 11969 gradient.setAttributeNS(null, "r", circleRadius); 11970 gradient.setAttributeNS(null, "fx", focalPoint[0]); 11971 gradient.setAttributeNS(null, "fy", focalPoint[1]); 11972 gradient.setAttributeNS(null, "fr", focalRadius); 11973 break; 11974 default: 11975 throw new Error(`Unknown RadialAxial type: ${args[1]}`); 11976 } 11977 for (const colorStop of colorStops) { 11978 const stop = this.svgFactory.createElement("svg:stop"); 11979 stop.setAttributeNS(null, "offset", colorStop[0]); 11980 stop.setAttributeNS(null, "stop-color", colorStop[1]); 11981 gradient.append(stop); 11982 } 11983 this.defs.append(gradient); 11984 return `url(#${shadingId})`; 11985 case "Mesh": 11986 (0, _util.warn)("Unimplemented pattern Mesh"); 11987 return null; 11988 case "Dummy": 11989 return "hotpink"; 11990 default: 11991 throw new Error(`Unknown IR type: ${args[0]}`); 11992 } 11993 } 11994 setDash(dashArray, dashPhase) { 11995 this.current.dashArray = dashArray; 11996 this.current.dashPhase = dashPhase; 11997 } 11998 constructPath(ops, args) { 11999 const current = this.current; 12000 let x = current.x, 12001 y = current.y; 12002 let d = []; 12003 let j = 0; 12004 for (const op of ops) { 12005 switch (op | 0) { 12006 case _util.OPS.rectangle: 12007 x = args[j++]; 12008 y = args[j++]; 12009 const width = args[j++]; 12010 const height = args[j++]; 12011 const xw = x + width; 12012 const yh = y + height; 12013 d.push("M", pf(x), pf(y), "L", pf(xw), pf(y), "L", pf(xw), pf(yh), "L", pf(x), pf(yh), "Z"); 12014 break; 12015 case _util.OPS.moveTo: 12016 x = args[j++]; 12017 y = args[j++]; 12018 d.push("M", pf(x), pf(y)); 12019 break; 12020 case _util.OPS.lineTo: 12021 x = args[j++]; 12022 y = args[j++]; 12023 d.push("L", pf(x), pf(y)); 12024 break; 12025 case _util.OPS.curveTo: 12026 x = args[j + 4]; 12027 y = args[j + 5]; 12028 d.push("C", pf(args[j]), pf(args[j + 1]), pf(args[j + 2]), pf(args[j + 3]), pf(x), pf(y)); 12029 j += 6; 12030 break; 12031 case _util.OPS.curveTo2: 12032 d.push("C", pf(x), pf(y), pf(args[j]), pf(args[j + 1]), pf(args[j + 2]), pf(args[j + 3])); 12033 x = args[j + 2]; 12034 y = args[j + 3]; 12035 j += 4; 12036 break; 12037 case _util.OPS.curveTo3: 12038 x = args[j + 2]; 12039 y = args[j + 3]; 12040 d.push("C", pf(args[j]), pf(args[j + 1]), pf(x), pf(y), pf(x), pf(y)); 12041 j += 4; 12042 break; 12043 case _util.OPS.closePath: 12044 d.push("Z"); 12045 break; 12046 } 12047 } 12048 d = d.join(" "); 12049 if (current.path && ops.length > 0 && ops[0] !== _util.OPS.rectangle && ops[0] !== _util.OPS.moveTo) { 12050 d = current.path.getAttributeNS(null, "d") + d; 12051 } else { 12052 current.path = this.svgFactory.createElement("svg:path"); 12053 this._ensureTransformGroup().append(current.path); 12054 } 12055 current.path.setAttributeNS(null, "d", d); 12056 current.path.setAttributeNS(null, "fill", "none"); 12057 current.element = current.path; 12058 current.setCurrentPoint(x, y); 12059 } 12060 endPath() { 12061 const current = this.current; 12062 current.path = null; 12063 if (!this.pendingClip) { 12064 return; 12065 } 12066 if (!current.element) { 12067 this.pendingClip = null; 12068 return; 12069 } 12070 const clipId = `clippath${clipCount++}`; 12071 const clipPath = this.svgFactory.createElement("svg:clipPath"); 12072 clipPath.setAttributeNS(null, "id", clipId); 12073 clipPath.setAttributeNS(null, "transform", pm(this.transformMatrix)); 12074 const clipElement = current.element.cloneNode(true); 12075 if (this.pendingClip === "evenodd") { 12076 clipElement.setAttributeNS(null, "clip-rule", "evenodd"); 12077 } else { 12078 clipElement.setAttributeNS(null, "clip-rule", "nonzero"); 12079 } 12080 this.pendingClip = null; 12081 clipPath.append(clipElement); 12082 this.defs.append(clipPath); 12083 if (current.activeClipUrl) { 12084 current.clipGroup = null; 12085 for (const prev of this.extraStack) { 12086 prev.clipGroup = null; 12087 } 12088 clipPath.setAttributeNS(null, "clip-path", current.activeClipUrl); 12089 } 12090 current.activeClipUrl = `url(#${clipId})`; 12091 this.tgrp = null; 12092 } 12093 clip(type) { 12094 this.pendingClip = type; 12095 } 12096 closePath() { 12097 const current = this.current; 12098 if (current.path) { 12099 const d = `${current.path.getAttributeNS(null, "d")}Z`; 12100 current.path.setAttributeNS(null, "d", d); 12101 } 12102 } 12103 setLeading(leading) { 12104 this.current.leading = -leading; 12105 } 12106 setTextRise(textRise) { 12107 this.current.textRise = textRise; 12108 } 12109 setTextRenderingMode(textRenderingMode) { 12110 this.current.textRenderingMode = textRenderingMode; 12111 } 12112 setHScale(scale) { 12113 this.current.textHScale = scale / 100; 12114 }
12115 setRenderingIntent(intent) {} 12116 setFlatness(flatness) {} 12117 setGState(states) { 12118 for (const [key, value] of states) { 12119 switch (key) { 12120 case "LW": 12121 this.setLineWidth(value); 12122 break; 12123 case "LC": 12124 this.setLineCap(value); 12125 break; 12126 case "LJ": 12127 this.setLineJoin(value); 12128 break; 12129 case "ML": 12130 this.setMiterLimit(value); 12131 break; 12132 case "D": 12133 this.setDash(value[0], value[1]); 12134 break; 12135 case "RI": 12136 this.setRenderingIntent(value); 12137 break; 12138 case "FL": 12139 this.setFlatness(value); 12140 break; 12141 case "Font": 12142 this.setFont(value); 12143 break; 12144 case "CA": 12145 this.setStrokeAlpha(value); 12146 break; 12147 case "ca": 12148 this.setFillAlpha(value); 12149 break; 12150 default: 12151 (0, _util.warn)(`Unimplemented graphic state operator ${key}`); 12152 break; 12153 } 12154 } 12155 } 12156 fill() { 12157 const current = this.current; 12158 if (current.element) { 12159 current.element.setAttributeNS(null, "fill", current.fillColor); 12160 current.element.setAttributeNS(null, "fill-opacity", current.fillAlpha); 12161 this.endPath(); 12162 } 12163 } 12164 stroke() { 12165 const current = this.current; 12166 if (current.element) { 12167 this._setStrokeAttributes(current.element); 12168 current.element.setAttributeNS(null, "fill", "none"); 12169 this.endPath(); 12170 } 12171 } 12172 _setStrokeAttributes(element, lineWidthScale = 1) { 12173 const current = this.current; 12174 let dashArray = current.dashArray; 12175 if (lineWidthScale !== 1 && dashArray.length > 0) { 12176 dashArray = dashArray.map(function (value) { 12177 return lineWidthScale * value; 12178 }); 12179 } 12180 element.setAttributeNS(null, "stroke", current.strokeColor); 12181 element.setAttributeNS(null, "stroke-opacity", current.strokeAlpha); 12182 element.setAttributeNS(null, "stroke-miterlimit", pf(current.miterLimit)); 12183 element.setAttributeNS(null, "stroke-linecap", current.lineCap); 12184 element.setAttributeNS(null, "stroke-linejoin", current.lineJoin); 12185 element.setAttributeNS(null, "stroke-width", pf(lineWidthScale * current.lineWidth) + "px"); 12186 element.setAttributeNS(null, "stroke-dasharray", dashArray.map(pf).join(" ")); 12187 element.setAttributeNS(null, "stroke-dashoffset", pf(lineWidthScale * current.dashPhase) + "px"); 12188 } 12189 eoFill() { 12190 this.current.element?.setAttributeNS(null, "fill-rule", "evenodd"); 12191 this.fill(); 12192 } 12193 fillStroke() { 12194 this.stroke(); 12195 this.fill(); 12196 } 12197 eoFillStroke() { 12198 this.current.element?.setAttributeNS(null, "fill-rule", "evenodd"); 12199 this.fillStroke(); 12200 } 12201 closeStroke() { 12202 this.closePath(); 12203 this.stroke(); 12204 } 12205 closeFillStroke() { 12206 this.closePath(); 12207 this.fillStroke(); 12208 } 12209 closeEOFillStroke() { 12210 this.closePath(); 12211 this.eoFillStroke(); 12212 } 12213 paintSolidColorImageMask() { 12214 const rect = this.svgFactory.createElement("svg:rect"); 12215 rect.setAttributeNS(null, "x", "0"); 12216 rect.setAttributeNS(null, "y", "0"); 12217 rect.setAttributeNS(null, "width", "1px"); 12218 rect.setAttributeNS(null, "height", "1px"); 12219 rect.setAttributeNS(null, "fill", this.current.fillColor); 12220 this._ensureTransformGroup().append(rect); 12221 } 12222 paintImageXObject(objId) { 12223 const imgData = this.getObject(objId); 12224 if (!imgData) { 12225 (0, _util.warn)(`Dependent image with object ID ${objId} is not ready yet`); 12226 return; 12227 } 12228 this.paintInlineImageXObject(imgData); 12229 } 12230 paintInlineImageXObject(imgData, mask) { 12231 const width = imgData.width; 12232 const height = imgData.height; 12233 const imgSrc = convertImgDataToPng(imgData, this.forceDataSchema, !!mask); 12234 const cliprect = this.svgFactory.createElement("svg:rect"); 12235 cliprect.setAttributeNS(null, "x", "0"); 12236 cliprect.setAttributeNS(null, "y", "0"); 12237 cliprect.setAttributeNS(null, "width", pf(width)); 12238 cliprect.setAttributeNS(null, "height", pf(height)); 12239 this.current.element = cliprect; 12240 this.clip("nonzero"); 12241 const imgEl = this.svgFactory.createElement("svg:image"); 12242 imgEl.setAttributeNS(XLINK_NS, "xlink:href", imgSrc); 12243 imgEl.setAttributeNS(null, "x", "0"); 12244 imgEl.setAttributeNS(null, "y", pf(-height)); 12245 imgEl.setAttributeNS(null, "width", pf(width) + "px"); 12246 imgEl.setAttributeNS(null, "height", pf(height) + "px"); 12247 imgEl.setAttributeNS(null, "transform", `scale(${pf(1 / width)} ${pf(-1 / height)})`); 12248 if (mask) { 12249 mask.append(imgEl); 12250 } else { 12251 this._ensureTransformGroup().append(imgEl); 12252 } 12253 } 12254 paintImageMaskXObject(img) { 12255 const imgData = this.getObject(img.data, img); 12256 if (imgData.bitmap) { 12257 (0, _util.warn)("paintImageMaskXObject: ImageBitmap support is not implemented, " + "ensure that the `isOffscreenCanvasSupported` API parameter is disabled."); 12258 return; 12259 } 12260 const current = this.current; 12261 const width = imgData.width; 12262 const height = imgData.height; 12263 const fillColor = current.fillColor; 12264 current.maskId = `mask${maskCount++}`; 12265 const mask = this.svgFactory.createElement("svg:mask"); 12266 mask.setAttributeNS(null, "id", current.maskId); 12267 const rect = this.svgFactory.createElement("svg:rect"); 12268 rect.setAttributeNS(null, "x", "0"); 12269 rect.setAttributeNS(null, "y", "0"); 12270 rect.setAttributeNS(null, "width", pf(width)); 12271 rect.setAttributeNS(null, "height", pf(height)); 12272 rect.setAttributeNS(null, "fill", fillColor); 12273 rect.setAttributeNS(null, "mask", `url(#${current.maskId})`); 12274 this.defs.append(mask); 12275 this._ensureTransformGroup().append(rect); 12276 this.paintInlineImageXObject(imgData, mask); 12277 } 12278 paintFormXObjectBegin(matrix, bbox) { 12279 if (Array.isArray(matrix) && matrix.length === 6) {
12280 this.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); 12281 } 12282 if (bbox) { 12283 const width = bbox[2] - bbox[0]; 12284 const height = bbox[3] - bbox[1]; 12285 const cliprect = this.svgFactory.createElement("svg:rect"); 12286 cliprect.setAttributeNS(null, "x", bbox[0]); 12287 cliprect.setAttributeNS(null, "y", bbox[1]); 12288 cliprect.setAttributeNS(null, "width", pf(width)); 12289 cliprect.setAttributeNS(null, "height", pf(height)); 12290 this.current.element = cliprect; 12291 this.clip("nonzero"); 12292 this.endPath(); 12293 } 12294 } 12295 paintFormXObjectEnd() {} 12296 _initialize(viewport) { 12297 const svg = this.svgFactory.create(viewport.width, viewport.height); 12298 const definitions = this.svgFactory.createElement("svg:defs"); 12299 svg.append(definitions); 12300 this.defs = definitions; 12301 const rootGroup = this.svgFactory.createElement("svg:g"); 12302 rootGroup.setAttributeNS(null, "transform", pm(viewport.transform)); 12303 svg.append(rootGroup); 12304 this.svg = rootGroup; 12305 return svg; 12306 } 12307 _ensureClipGroup() { 12308 if (!this.current.clipGroup) { 12309 const clipGroup = this.svgFactory.createElement("svg:g"); 12310 clipGroup.setAttributeNS(null, "clip-path", this.current.activeClipUrl); 12311 this.svg.append(clipGroup); 12312 this.current.clipGroup = clipGroup; 12313 } 12314 return this.current.clipGroup; 12315 } 12316 _ensureTransformGroup() { 12317 if (!this.tgrp) { 12318 this.tgrp = this.svgFactory.createElement("svg:g"); 12319 this.tgrp.setAttributeNS(null, "transform", pm(this.transformMatrix)); 12320 if (this.current.activeClipUrl) { 12321 this._ensureClipGroup().append(this.tgrp); 12322 } else { 12323 this.svg.append(this.tgrp); 12324 } 12325 } 12326 return this.tgrp; 12327 } 12328} 12329exports.SVGGraphics = SVGGraphics; 12330 12331/***/ }), 12332/* 25 */ 12333/***/ ((__unused_webpack_module, exports) => { 12334 12335 12336 12337Object.defineProperty(exports, "__esModule", ({ 12338 value: true 12339})); 12340exports.XfaText = void 0; 12341class XfaText { 12342 static textContent(xfa) { 12343 const items = []; 12344 const output = { 12345 items, 12346 styles: Object.create(null) 12347 }; 12348 function walk(node) { 12349 if (!node) { 12350 return; 12351 } 12352 let str = null; 12353 const name = node.name; 12354 if (name === "#text") { 12355 str = node.value; 12356 } else if (!XfaText.shouldBuildText(name)) { 12357 return; 12358 } else if (node?.attributes?.textContent) { 12359 str = node.attributes.textContent; 12360 } else if (node.value) { 12361 str = node.value; 12362 } 12363 if (str !== null) { 12364 items.push({ 12365 str 12366 }); 12367 } 12368 if (!node.children) { 12369 return; 12370 } 12371 for (const child of node.children) { 12372 walk(child); 12373 } 12374 } 12375 walk(xfa); 12376 return output; 12377 } 12378 static shouldBuildText(name) { 12379 return !(name === "textarea" || name === "input" || name === "option" || name === "select"); 12380 } 12381} 12382exports.XfaText = XfaText; 12383 12384/***/ }), 12385/* 26 */ 12386/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 12387 12388 12389 12390Object.defineProperty(exports, "__esModule", ({ 12391 value: true 12392})); 12393exports.TextLayerRenderTask = void 0; 12394exports.renderTextLayer = renderTextLayer; 12395exports.updateTextLayer = updateTextLayer; 12396var _util = __w_pdfjs_require__(1); 12397var _display_utils = __w_pdfjs_require__(6); 12398const MAX_TEXT_DIVS_TO_RENDER = 100000; 12399const DEFAULT_FONT_SIZE = 30; 12400const DEFAULT_FONT_ASCENT = 0.8; 12401const ascentCache = new Map(); 12402function getCtx(size, isOffscreenCanvasSupported) { 12403 let ctx; 12404 const options = window.pdfDefaultOptions.activateWillReadFrequentlyFlag ? { 12405 willReadFrequently: true, 12406 alpha: false 12407 } : { 12408 alpha: false 12409 }; 12410 if (isOffscreenCanvasSupported && _util.FeatureTest.isOffscreenCanvasSupported) { 12411 ctx = new OffscreenCanvas(size, size).getContext("2d", options); 12412 } else { 12413 const canvas = document.createElement("canvas"); 12414 canvas.width = canvas.height = size; 12415 ctx = canvas.getContext("2d", options); 12416 } 12417 return ctx; 12418} 12419function getAscent(fontFamily, isOffscreenCanvasSupported) { 12420 const cachedAscent = ascentCache.get(fontFamily); 12421 if (cachedAscent) { 12422 return cachedAscent; 12423 } 12424 const ctx = getCtx(DEFAULT_FONT_SIZE, isOffscreenCanvasSupported); 12425 ctx.font = `${DEFAULT_FONT_SIZE}px ${fontFamily}`; 12426 const metrics = ctx.measureText(""); 12427 let ascent = metrics?.fontBoundingBoxAscent; 12428 let descent = Math.abs(metrics?.fontBoundingBoxDescent); 12429 if (ascent) { 12430 const ratio = ascent / (ascent + descent); 12431 ascentCache.set(fontFamily, ratio); 12432 ctx.canvas.width = ctx.canvas.height = 0; 12433 return ratio; 12434 } 12435 ctx.strokeStyle = "red"; 12436 ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE); 12437 ctx.strokeText("g", 0, 0); 12438 let pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data; 12439 descent = 0; 12440 for (let i = pixels.length - 1 - 3; i >= 0; i -= 4) { 12441 if (pixels[i] > 0) {
12442 descent = Math.ceil(i / 4 / DEFAULT_FONT_SIZE); 12443 break; 12444 } 12445 } 12446 ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE); 12447 ctx.strokeText("A", 0, DEFAULT_FONT_SIZE); 12448 pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data; 12449 ascent = 0; 12450 for (let i = 0, ii = pixels.length; i < ii; i += 4) { 12451 if (pixels[i] > 0) { 12452 ascent = DEFAULT_FONT_SIZE - Math.floor(i / 4 / DEFAULT_FONT_SIZE); 12453 break; 12454 } 12455 } 12456 ctx.canvas.width = ctx.canvas.height = 0; 12457 if (ascent) { 12458 const ratio = ascent / (ascent + descent); 12459 ascentCache.set(fontFamily, ratio); 12460 return ratio; 12461 } 12462 ascentCache.set(fontFamily, DEFAULT_FONT_ASCENT); 12463 return DEFAULT_FONT_ASCENT; 12464} 12465function appendText(task, geom, styles) { 12466 const textDiv = document.createElement("span"); 12467 const textDivProperties = { 12468 angle: 0, 12469 canvasWidth: 0, 12470 hasText: geom.str !== "", 12471 hasEOL: geom.hasEOL, 12472 fontSize: 0 12473 }; 12474 task._textDivs.push(textDiv); 12475 const tx = _util.Util.transform(task._transform, geom.transform); 12476 let angle = Math.atan2(tx[1], tx[0]); 12477 const style = styles[geom.fontName]; 12478 if (style.vertical) { 12479 angle += Math.PI / 2; 12480 } 12481 const fontHeight = Math.hypot(tx[2], tx[3]); 12482 const fontAscent = fontHeight * getAscent(style.fontFamily, task._isOffscreenCanvasSupported); 12483 let left, top; 12484 if (angle === 0) { 12485 left = tx[4]; 12486 top = tx[5] - fontAscent; 12487 } else { 12488 left = tx[4] + fontAscent * Math.sin(angle); 12489 top = tx[5] - fontAscent * Math.cos(angle); 12490 } 12491 const scaleFactorStr = "calc(var(--scale-factor)*"; 12492 const divStyle = textDiv.style; 12493 if (task._container === task._rootContainer) { 12494 divStyle.left = `${(100 * left / task._pageWidth).toFixed(2)}%`; 12495 divStyle.top = `${(100 * top / task._pageHeight).toFixed(2)}%`; 12496 } else { 12497 divStyle.left = `${scaleFactorStr}${left.toFixed(2)}px)`; 12498 divStyle.top = `${scaleFactorStr}${top.toFixed(2)}px)`; 12499 } 12500 divStyle.fontSize = `${scaleFactorStr}${fontHeight.toFixed(2)}px)`; 12501 divStyle.fontFamily = style.fontFamily; 12502 textDivProperties.fontSize = fontHeight; 12503 textDiv.setAttribute("role", "presentation"); 12504 textDiv.textContent = geom.str; 12505 textDiv.dir = geom.dir; 12506 if (task._fontInspectorEnabled) { 12507 textDiv.dataset.fontName = geom.fontName; 12508 } 12509 if (angle !== 0) { 12510 textDivProperties.angle = angle * (180 / Math.PI); 12511 } 12512 let shouldScaleText = false; 12513 if (geom.str.length > 1) { 12514 shouldScaleText = true; 12515 } else if (geom.str !== " " && geom.transform[0] !== geom.transform[3]) { 12516 const absScaleX = Math.abs(geom.transform[0]), 12517 absScaleY = Math.abs(geom.transform[3]); 12518 if (absScaleX !== absScaleY && Math.max(absScaleX, absScaleY) / Math.min(absScaleX, absScaleY) > 1.5) { 12519 shouldScaleText = true; 12520 } 12521 } 12522 if (shouldScaleText) { 12523 textDivProperties.canvasWidth = style.vertical ? geom.height : geom.width; 12524 } 12525 task._textDivProperties.set(textDiv, textDivProperties); 12526 if (task._isReadableStream) { 12527 task._layoutText(textDiv); 12528 } 12529} 12530function layout(params) { 12531 const { 12532 div, 12533 scale, 12534 properties, 12535 ctx, 12536 prevFontSize, 12537 prevFontFamily 12538 } = params; 12539 const { 12540 style 12541 } = div; 12542 let transform = ""; 12543 if (properties.canvasWidth !== 0 && properties.hasText) { 12544 const { 12545 fontFamily 12546 } = style; 12547 const { 12548 canvasWidth, 12549 fontSize 12550 } = properties; 12551 if (prevFontSize !== fontSize || prevFontFamily !== fontFamily) { 12552 ctx.font = `${fontSize * scale}px ${fontFamily}`; 12553 params.prevFontSize = fontSize; 12554 params.prevFontFamily = fontFamily; 12555 } 12556 try { 12557 const { 12558 width 12559 } = ctx.measureText(div.textContent); 12560 if (width > 0) { 12561 transform = `scaleX(${canvasWidth * scale / width})`; 12562 } 12563 } catch (fingerprintIsBlockedException) {} 12564 } 12565 if (properties.angle !== 0) { 12566 transform = `rotate(${properties.angle}deg) ${transform}`; 12567 } 12568 if (transform.length > 0) { 12569 style.transform = transform; 12570 } 12571} 12572function render(task) { 12573 if (task._canceled) { 12574 return; 12575 } 12576 const textDivs = task._textDivs; 12577 const capability = task._capability; 12578 const textDivsLength = textDivs.length; 12579 if (textDivsLength > MAX_TEXT_DIVS_TO_RENDER) { 12580 capability.resolve(); 12581 return; 12582 } 12583 if (!task._isReadableStream) { 12584 for (const textDiv of textDivs) { 12585 task._layoutText(textDiv); 12586 } 12587 } 12588 capability.resolve(); 12589} 12590class TextLayerRenderTask { 12591 constructor({ 12592 textContentSource, 12593 container, 12594 viewport, 12595 textDivs, 12596 textDivProperties, 12597 textContentItemsStr, 12598 isOffscreenCanvasSupported 12599 }) { 12600 this._textContentSource = textContentSource; 12601 this._isReadableStream = textContentSource instanceof ReadableStream; 12602 this._container = this._rootContainer = container; 12603 this._textDivs = textDivs || []; 12604 this._textContentItemsStr = textContentItemsStr || []; 12605 this._isOffscreenCanvasSupported = isOffscreenCanvasSupported; 12606 this._fontInspectorEnabled = !!globalThis.FontInspector?.enabled; 12607 this._reader = null; 12608 this._textDivProperties = textDivProperties || new WeakMap(); 12609 this._canceled = false;
12610 this._capability = new _util.PromiseCapability(); 12611 this._layoutTextParams = { 12612 prevFontSize: null, 12613 prevFontFamily: null, 12614 div: null, 12615 scale: viewport.scale * (globalThis.devicePixelRatio || 1), 12616 properties: null, 12617 ctx: getCtx(0, isOffscreenCanvasSupported) 12618 }; 12619 const { 12620 pageWidth, 12621 pageHeight, 12622 pageX, 12623 pageY 12624 } = viewport.rawDims; 12625 this._transform = [1, 0, 0, -1, -pageX, pageY + pageHeight]; 12626 this._pageWidth = pageWidth; 12627 this._pageHeight = pageHeight; 12628 (0, _display_utils.setLayerDimensions)(container, viewport); 12629 this._capability.promise.finally(() => { 12630 this._layoutTextParams = null; 12631 }).catch(() => {}); 12632 } 12633 get promise() { 12634 return this._capability.promise; 12635 } 12636 cancel() { 12637 this._canceled = true; 12638 if (this._reader) { 12639 this._reader.cancel(new _util.AbortException("TextLayer task cancelled.")).catch(() => {}); 12640 this._reader = null; 12641 } 12642 this._capability.reject(new _util.AbortException("TextLayer task cancelled.")); 12643 } 12644 _processItems(items, styleCache) { 12645 for (const item of items) { 12646 if (item.str === undefined) { 12647 if (item.type === "beginMarkedContentProps" || item.type === "beginMarkedContent") { 12648 const parent = this._container; 12649 this._container = document.createElement("span"); 12650 this._container.classList.add("markedContent"); 12651 if (item.id !== null) { 12652 this._container.setAttribute("id", `${item.id}`); 12653 } 12654 parent.append(this._container); 12655 } else if (item.type === "endMarkedContent") { 12656 this._container = this._container.parentNode; 12657 } 12658 continue; 12659 } 12660 this._textContentItemsStr.push(item.str); 12661 appendText(this, item, styleCache); 12662 } 12663 } 12664 _layoutText(textDiv) { 12665 const textDivProperties = this._layoutTextParams.properties = this._textDivProperties.get(textDiv); 12666 this._layoutTextParams.div = textDiv; 12667 layout(this._layoutTextParams); 12668 if (textDivProperties.hasText) { 12669 this._container.append(textDiv); 12670 } 12671 if (textDivProperties.hasEOL) { 12672 const br = document.createElement("br"); 12673 br.setAttribute("role", "presentation"); 12674 this._container.append(br); 12675 } 12676 } 12677 _render() { 12678 const capability = new _util.PromiseCapability(); 12679 let styleCache = Object.create(null); 12680 if (this._isReadableStream) { 12681 const pump = () => { 12682 this._reader.read().then(({ 12683 value, 12684 done 12685 }) => { 12686 if (done) { 12687 capability.resolve(); 12688 return; 12689 } 12690 Object.assign(styleCache, value.styles); 12691 this._processItems(value.items, styleCache); 12692 pump(); 12693 }, capability.reject); 12694 }; 12695 this._reader = this._textContentSource.getReader(); 12696 pump(); 12697 } else if (this._textContentSource) { 12698 const { 12699 items, 12700 styles 12701 } = this._textContentSource; 12702 this._processItems(items, styles); 12703 capability.resolve(); 12704 } else { 12705 throw new Error('No "textContentSource" parameter specified.'); 12706 } 12707 capability.promise.then(() => { 12708 styleCache = null; 12709 render(this); 12710 }, this._capability.reject); 12711 } 12712} 12713exports.TextLayerRenderTask = TextLayerRenderTask; 12714function renderTextLayer(params) { 12715 if (!params.textContentSource && (params.textContent || params.textContentStream)) { 12716 (0, _display_utils.deprecated)("The TextLayerRender `textContent`/`textContentStream` parameters " + "will be removed in the future, please use `textContentSource` instead."); 12717 params.textContentSource = params.textContent || params.textContentStream; 12718 } 12719 const { 12720 container, 12721 viewport 12722 }
12722 = params; 12723 const style = getComputedStyle(container); 12724 const visibility = style.getPropertyValue("visibility"); 12725 const scaleFactor = parseFloat(style.getPropertyValue("--scale-factor")); 12726 if (visibility === "visible" && (!scaleFactor || Math.abs(scaleFactor - viewport.scale) > 1e-5)) { 12727 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."); 12728 } 12729 const task = new TextLayerRenderTask(params); 12730 task._render(); 12731 return task; 12732} 12733function updateTextLayer({ 12734 container, 12735 viewport, 12736 textDivs, 12737 textDivProperties, 12738 isOffscreenCanvasSupported, 12739 mustRotate = true, 12740 mustRescale = true 12741}) { 12742 if (mustRotate) { 12743 (0, _display_utils.setLayerDimensions)(container, { 12744 rotation: viewport.rotation 12745 }); 12746 } 12747 if (mustRescale) { 12748 const ctx = getCtx(0, isOffscreenCanvasSupported); 12749 const scale = viewport.scale * (globalThis.devicePixelRatio || 1); 12750 const params = { 12751 prevFontSize: null, 12752 prevFontFamily: null, 12753 div: null, 12754 scale, 12755 properties: null, 12756 ctx 12757 }; 12758 for (const div of textDivs) { 12759 params.properties = textDivProperties.get(div); 12760 params.div = div; 12761 layout(params); 12762 } 12763 } 12764} 12765 12766/***/ }), 12767/* 27 */ 12768/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 12769 12770 12771 12772Object.defineProperty(exports, "__esModule", ({ 12773 value: true 12774})); 12775exports.AnnotationEditorLayer = void 0; 12776var _util = __w_pdfjs_require__(1); 12777var _editor = __w_pdfjs_require__(4); 12778var _freetext = __w_pdfjs_require__(28); 12779var _ink = __w_pdfjs_require__(33); 12780var _display_utils = __w_pdfjs_require__(6); 12781var _stamp = __w_pdfjs_require__(34); 12782class AnnotationEditorLayer { 12783 #accessibilityManager; 12784 #allowClick = false; 12785 #annotationLayer = null; 12786 #boundPointerup = this.pointerup.bind(this); 12787 #boundPointerdown = this.pointerdown.bind(this); 12788 #editors = new Map(); 12789 #hadPointerDown = false; 12790 #isCleaningUp = false; 12791 #isDisabling = false; 12792 #uiManager; 12793 static _initialized = false; 12794 constructor({ 12795 uiManager, 12796 pageIndex, 12797 div, 12798 accessibilityManager, 12799 annotationLayer, 12800 viewport, 12801 l10n 12802 }) { 12803 const editorTypes = [_freetext.FreeTextEditor, _ink.InkEditor, _stamp.StampEditor]; 12804 if (!AnnotationEditorLayer._initialized) { 12805 AnnotationEditorLayer._initialized = true; 12806 for (const editorType of editorTypes) { 12807 editorType.initialize(l10n); 12808 } 12809 } 12810 uiManager.registerEditorTypes(editorTypes); 12811 this.#uiManager = uiManager; 12812 this.pageIndex = pageIndex; 12813 this.div = div; 12814 this.#accessibilityManager = accessibilityManager; 12815 this.#annotationLayer = annotationLayer; 12816 this.viewport = viewport; 12817 this.#uiManager.addLayer(this); 12818 } 12819 get isEmpty() { 12820 return this.#editors.size === 0; 12821 } 12822 updateToolbar(mode) { 12823 this.#uiManager.updateToolbar(mode); 12824 } 12825 updateMode(mode = this.#uiManager.getMode()) { 12826 this.#cleanup(); 12827 if (mode === _util.AnnotationEditorType.INK) { 12828 this.addInkEditorIfNeeded(false); 12829 this.disableClick(); 12830 } else { 12831 this.enableClick(); 12832 } 12833 if (mode !== _util.AnnotationEditorType.NONE) { 12834 this.div.classList.toggle("freeTextEditing", mode === _util.AnnotationEditorType.FREETEXT); 12835 this.div.classList.toggle("inkEditing", mode === _util.AnnotationEditorType.INK); 12836 this.div.classList.toggle("stampEditing", mode === _util.AnnotationEditorType.STAMP); 12837 this.div.hidden = false; 12838 } 12839 } 12840 addInkEditorIfNeeded(isCommitting) { 12841 if (!isCommitting && this.#uiManager.getMode() !== _util.AnnotationEditorType.INK) { 12842 return; 12843 } 12844 if (!isCommitting) { 12845 for (const editor of this.#editors.values()) { 12846 if (editor.isEmpty()) { 12847 editor.setInBackground(); 12848 return; 12849 } 12850 } 12851 } 12852 const editor = this.#createAndAddNewEditor({ 12853 offsetX: 0, 12854 offsetY: 0 12855 }, false); 12856 editor.setInBackground(); 12857 } 12858 setEditingState(isEditing) { 12859 this.#uiManager.setEditingState(isEditing); 12860 } 12861 addCommands(params) { 12862 this.#uiManager.addCommands(params); 12863 } 12864 enable() { 12865 this.div.style.pointerEvents = "auto"; 12866 const annotationElementIds = new Set(); 12867 for (const editor of this.#editors.values()) { 12868 editor.enableEditing(); 12869 if (editor.annotationElementId) { 12870 annotationElementIds.add(editor.annotationElementId); 12871 } 12872 } 12873 if (!this.#annotationLayer) { 12874 return; 12875 } 12876 const editables = this.#annotationLayer.getEditableAnnotations(); 12877 for (const editable of editables) { 12878 editable.hide(); 12879 if (this.#uiManager.isDeletedAnnotationElement(editable.data.id)) { 12880 continue; 12881 } 12882 if (annotationElementIds.has(editable.data.id)) { 12883 continue; 12884 } 12885 const editor = this.deserialize(editable); 12886 if (!editor) { 12887 continue; 12888 } 12889 this.addOrRebuild(editor); 12890 editor.enableEditing(); 12891 } 12892 } 12893 disable() { 12894 this.#isDisabling = true; 12895 this.div.style.pointerEvents = "none"; 12896 const hiddenAnnotationIds = new Set(); 12897 for (const editor of this.#editors.values()) { 12898 editor.disableEditing(); 12899 if (!editor.annotationElementId || editor.serialize() !== null) { 12900 hiddenAnnotationIds.add(editor.annotationElementId); 12901 continue; 12902 } 12903 this.getEditableAnnotation(editor.annotationElementId)?.show(); 12904 editor.remove(); 12905 } 12906 if (this.#annotationLayer) { 12907 const editables = this.#annotationLayer.getEditableAnnotations(); 12908 for (const editable of editables) { 12909 const { 12910 id 12911 } = editable.data; 12912 if (hiddenAnnotationIds.has(id) || this.#uiManager.isDeletedAnnotationElement(id)) { 12913 continue; 12914 } 12915 editable.show(); 12916 } 12917 } 12918 this.#cleanup(); 12919 if (this.isEmpty) { 12920 this.div.hidden = true; 12921 } 12922 this.#isDisabling = false;
12923 } 12924 getEditableAnnotation(id) { 12925 return this.#annotationLayer?.getEditableAnnotation(id) || null; 12926 } 12927 setActiveEditor(editor) { 12928 const currentActive = this.#uiManager.getActive(); 12929 if (currentActive === editor) { 12930 return; 12931 } 12932 this.#uiManager.setActiveEditor(editor); 12933 } 12934 enableClick() { 12935 this.div.addEventListener("pointerdown", this.#boundPointerdown); 12936 this.div.addEventListener("pointerup", this.#boundPointerup); 12937 } 12938 disableClick() { 12939 this.div.removeEventListener("pointerdown", this.#boundPointerdown); 12940 this.div.removeEventListener("pointerup", this.#boundPointerup); 12941 } 12942 attach(editor) { 12943 this.#editors.set(editor.id, editor); 12944 const { 12945 annotationElementId 12946 } = editor; 12947 if (annotationElementId && this.#uiManager.isDeletedAnnotationElement(annotationElementId)) { 12948 this.#uiManager.removeDeletedAnnotationElement(editor); 12949 } 12950 } 12951 detach(editor) { 12952 this.#editors.delete(editor.id); 12953 this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv); 12954 if (!this.#isDisabling && editor.annotationElementId) { 12955 this.#uiManager.addDeletedAnnotationElement(editor); 12956 } 12957 } 12958 remove(editor) { 12959 this.detach(editor); 12960 this.#uiManager.removeEditor(editor); 12961 if (editor.div.contains(document.activeElement)) { 12962 setTimeout(() => { 12963 this.#uiManager.focusMainContainer(); 12964 }, 0); 12965 } 12966 editor.div.remove(); 12967 editor.isAttachedToDOM = false; 12968 if (!this.#isCleaningUp) { 12969 this.addInkEditorIfNeeded(false); 12970 } 12971 } 12972 changeParent(editor) { 12973 if (editor.parent === this) { 12974 return; 12975 } 12976 if (editor.annotationElementId) { 12977 this.#uiManager.addDeletedAnnotationElement(editor.annotationElementId); 12978 _editor.AnnotationEditor.deleteAnnotationElement(editor); 12979 editor.annotationElementId = null; 12980 } 12981 this.attach(editor); 12982 editor.parent?.detach(editor); 12983 editor.setParent(this); 12984 if (editor.div && editor.isAttachedToDOM) { 12985 editor.div.remove(); 12986 this.div.append(editor.div); 12987 } 12988 } 12989 add(editor) { 12990 this.changeParent(editor); 12991 this.#uiManager.addEditor(editor); 12992 this.attach(editor); 12993 if (!editor.isAttachedToDOM) { 12994 const div = editor.render(); 12995 this.div.append(div); 12996 editor.isAttachedToDOM = true; 12997 } 12998 this.moveEditorInDOM(editor); 12999 editor.onceAdded(); 13000 this.#uiManager.addToAnnotationStorage(editor); 13001 } 13002 moveEditorInDOM(editor) { 13003 if (!editor.isAttachedToDOM) { 13004 return; 13005 } 13006 const { 13007 activeElement 13008 } = document; 13009 if (editor.div.contains(activeElement)) { 13010 editor._focusEventsAllowed = false; 13011 setTimeout(() => { 13012 editor.div.addEventListener("focusin", () => { 13013 editor._focusEventsAllowed = true; 13014 }, { 13015 once: true 13016 }); 13017 activeElement.focus(); 13018 }, 0); 13019 } 13020 this.#accessibilityManager?.moveElementInDOM(this.div, editor.div, editor.contentDiv, true); 13021 } 13022 addOrRebuild(editor) { 13023 if (editor.needsToBeRebuilt()) { 13024 editor.rebuild(); 13025 } else { 13026 this.add(editor); 13027 } 13028 } 13029 addUndoableEditor(editor) { 13030 const cmd = () => editor._uiManager.rebuild(editor); 13031 const undo = () => { 13032 editor.remove(); 13033 }; 13034 this.addCommands({ 13035 cmd, 13036 undo, 13037 mustExec: false 13038 }); 13039 } 13040 getNextId() { 13041 return this.#uiManager.getId(); 13042 } 13043 #createNewEditor(params) { 13044 switch (this.#uiManager.getMode()) { 13045 case _util.AnnotationEditorType.FREETEXT: 13046 return new _freetext.FreeTextEditor(params); 13047 case _util.AnnotationEditorType.INK: 13048 return new _ink.InkEditor(params); 13049 case _util.AnnotationEditorType.STAMP: 13050 return new _stamp.StampEditor(params); 13051 } 13052 return null; 13053 } 13054 pasteEditor(mode, params) { 13055 this.#uiManager.updateToolbar(mode); 13056 this.#uiManager.updateMode(mode); 13057 const { 13058 offsetX, 13059 offsetY 13060 } = this.#getCenterPoint(); 13061 const id = this.getNextId(); 13062 const editor = this.#createNewEditor({ 13063 parent: this, 13064 id, 13065 x: offsetX, 13066 y: offsetY, 13067 uiManager: this.#uiManager, 13068 isCentered: true, 13069 ...params 13070 }); 13071 if (editor) { 13072 this.add(editor); 13073 } 13074 } 13075 deserialize(data) { 13076 switch (data.annotationType ?? data.annotationEditorType) { 13077 case _util.AnnotationEditorType.FREETEXT: 13078 return _freetext.FreeTextEditor.deserialize(data, this, this.#uiManager); 13079 case _util.AnnotationEditorType.INK: 13080 return _ink.InkEditor.deserialize(data, this, this.#uiManager); 13081 case _util.AnnotationEditorType.STAMP: 13082 return _stamp.StampEditor.deserialize(data, this, this.#uiManager); 13083 } 13084 return null; 13085 } 13086 #createAndAddNewEditor(event, isCentered) { 13087 const id = this.getNextId(); 13088 const editor = this.#createNewEditor({ 13089 parent: this, 13090 id, 13091 x: event.offsetX, 13092 y: event.offsetY, 13093 uiManager: this.#uiManager, 13094 isCentered 13095 }); 13096 if (editor) { 13097 this.add(editor); 13098 } 13099 return editor; 13100 } 13101 #getCenterPoint() { 13102 const { 13103 x, 13104 y, 13105 width, 13106 height 13107 } = this.div.getBoundingClientRect(); 13108 const tlX = Math.max(0, x); 13109 const tlY = Math.max(0, y); 13110 const brX = Math.min(window.innerWidth, x + width); 13111 const brY = Math.min(window.innerHeight, y + height); 13112 const centerX = (tlX + brX) / 2 - x; 13113 const centerY = (tlY + brY) / 2 - y; 13114 const [offsetX, offsetY] = this.viewport.rotation % 180 === 0 ? [centerX, centerY] : [centerY, centerX]; 13115 return { 13116 offsetX, 13117 offsetY 13118 }; 13119 } 13120 addNewEditor() { 13121 this.#createAndAddNewEditor(this.#getCenterPoint(), true); 13122 } 13123 setSelected(editor) { 13124 this.#uiManager.setSelected(editor); 13125 } 13126 toggleSelected(editor) { 13127 this.#uiManager.toggleSelected(editor); 13128 } 13129 isSelected(editor) { 13130 return this.#uiManager.isSelected(editor); 13131 } 13132 unselect(editor) { 13133 this.#uiManager.unselect(editor); 13134 } 13135 pointerup(event) { 13136 const { 13137 isMac 13138 } = _util.FeatureTest.platform; 13139 if (event.button !== 0 || event.ctrlKey && isMac) { 13140 return; 13141 } 13142 if (event.target !== this.div) { 13143 return; 13144 } 13145 if (!this.#hadPointerDown) { 13146 return; 13147 } 13148 this.#hadPointerDown = false;
13149 if (!this.#allowClick) { 13150 this.#allowClick = true; 13151 return; 13152 } 13153 if (this.#uiManager.getMode() === _util.AnnotationEditorType.STAMP) { 13154 this.#uiManager.unselectAll(); 13155 return; 13156 } 13157 this.#createAndAddNewEditor(event, false); 13158 } 13159 pointerdown(event) { 13160 if (this.#hadPointerDown) { 13161 this.#hadPointerDown = false; 13162 return; 13163 } 13164 const { 13165 isMac 13166 } = _util.FeatureTest.platform; 13167 if (event.button !== 0 || event.ctrlKey && isMac) { 13168 return; 13169 } 13170 if (event.target !== this.div) { 13171 return; 13172 } 13173 this.#hadPointerDown = true; 13174 const editor = this.#uiManager.getActive(); 13175 this.#allowClick = !editor || editor.isEmpty(); 13176 } 13177 findNewParent(editor, x, y) { 13178 const layer = this.#uiManager.findParent(x, y); 13179 if (layer === null || layer === this) { 13180 return false; 13181 } 13182 layer.changeParent(editor); 13183 return true; 13184 } 13185 destroy() { 13186 if (this.#uiManager.getActive()?.parent === this) { 13187 this.#uiManager.setActiveEditor(null); 13188 } 13189 for (const editor of this.#editors.values()) { 13190 this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv); 13191 editor.setParent(null); 13192 editor.isAttachedToDOM = false; 13193 editor.div.remove(); 13194 } 13195 this.div = null; 13196 this.#editors.clear(); 13197 this.#uiManager.removeLayer(this); 13198 } 13199 #cleanup() { 13200 this.#isCleaningUp = true; 13201 for (const editor of this.#editors.values()) { 13202 if (editor.isEmpty()) { 13203 editor.remove(); 13204 } 13205 } 13206 this.#isCleaningUp = false; 13207 } 13208 render({ 13209 viewport 13210 }) { 13211 this.viewport = viewport; 13212 (0, _display_utils.setLayerDimensions)(this.div, viewport); 13213 for (const editor of this.#uiManager.getEditors(this.pageIndex)) { 13214 this.add(editor); 13215 } 13216 this.updateMode(); 13217 } 13218 update({ 13219 viewport 13220 }) { 13221 this.#uiManager.commitOrRemove(); 13222 this.viewport = viewport; 13223 (0, _display_utils.setLayerDimensions)(this.div, { 13224 rotation: viewport.rotation 13225 }); 13226 this.updateMode(); 13227 } 13228 get pageDimensions() { 13229 const { 13230 pageWidth, 13231 pageHeight 13232 } = this.viewport.rawDims; 13233 return [pageWidth, pageHeight]; 13234 } 13235 setCleaningUp(isCleaningUp) { 13236 this.#isCleaningUp = isCleaningUp; 13237 } 13238} 13239exports.AnnotationEditorLayer = AnnotationEditorLayer; 13240 13241/***/ }), 13242/* 28 */ 13243/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 13244 13245 13246 13247Object.defineProperty(exports, "__esModule", ({ 13248 value: true 13249})); 13250exports.FreeTextEditor = void 0; 13251var _util = __w_pdfjs_require__(1); 13252var _tools = __w_pdfjs_require__(5); 13253var _editor = __w_pdfjs_require__(4); 13254var _annotation_layer = __w_pdfjs_require__(29); 13255class FreeTextEditor extends _editor.AnnotationEditor { 13256 #boundEditorDivBlur = this.editorDivBlur.bind(this); 13257 #boundEditorDivFocus = this.editorDivFocus.bind(this); 13258 #boundEditorDivInput = this.editorDivInput.bind(this); 13259 #boundEditorDivKeydown = this.editorDivKeydown.bind(this); 13260 #color; 13261 #content = ""; 13262 #editorDivId = `${this.id}-editor`; 13263 #fontSize; 13264 #initialData = null; 13265 static _freeTextDefaultContent = ""; 13266 static _l10nPromise; 13267 static _internalPadding = 0; 13268 static _defaultColor = null; 13269 static _defaultFontSize = 10; 13270 static get _keyboardManager() { 13271 const proto = FreeTextEditor.prototype; 13272 const arrowChecker = self => self.isEmpty(); 13273 const small = _tools.AnnotationEditorUIManager.TRANSLATE_SMALL; 13274 const big = _tools.AnnotationEditorUIManager.TRANSLATE_BIG; 13275 return (0, _util.shadow)(this, "_keyboardManager", new _tools.KeyboardManager([[["ctrl+s", "mac+meta+s", "ctrl+p", "mac+meta+p"], proto.commitOrRemove, { 13276 bubbles: true 13277 }], [["ctrl+Enter", "mac+meta+Enter", "Escape", "mac+Escape"], proto.commitOrRemove], [["ArrowLeft", "mac+ArrowLeft"], proto._translateEmpty, { 13278 args: [-small, 0], 13279 checker: arrowChecker 13280 }], [["ctrl+ArrowLeft", "mac+shift+ArrowLeft"], proto._translateEmpty, { 13281 args: [-big, 0], 13282 checker: arrowChecker 13283 }], [["ArrowRight", "mac+ArrowRight"], proto._translateEmpty, { 13284 args: [small, 0], 13285 checker: arrowChecker 13286 }], [["ctrl+ArrowRight", "mac+shift+ArrowRight"], proto._translateEmpty, { 13287 args: [big, 0], 13288 checker: arrowChecker 13289 }], [["ArrowUp", "mac+ArrowUp"], proto._translateEmpty, { 13290 args: [0, -small], 13291 checker: arrowChecker 13292 }], [["ctrl+ArrowUp", "mac+shift+ArrowUp"], proto._translateEmpty, { 13293 args: [0, -big], 13294 checker: arrowChecker 13295 }], [["ArrowDown", "mac+ArrowDown"], proto._translateEmpty, { 13296 args: [0, small], 13297 checker: arrowChecker 13298 }], [["ctrl+ArrowDown", "mac+shift+ArrowDown"], proto._translateEmpty, { 13299 args: [0, big], 13300 checker: arrowChecker 13301 }]])); 13302 } 13303 static _type = "freetext"; 13304 constructor(params) { 13305 super({ 13306 ...params, 13307 name: "freeTextEditor" 13308 }); 13309 this.#color = params.color || FreeTextEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor; 13310 this.#fontSize = params.fontSize || FreeTextEditor._defaultFontSize; 13311 } 13312 static initialize(l10n) { 13313 this._l10nPromise = new Map(["free_text2_default_content", "editor_free_text2_aria_label"].map(str => [str, l10n.get(str)])); 13314 const style = getComputedStyle(document.documentElement); 13315 this._internalPadding = parseFloat(style.getPropertyValue("--freetext-padding")); 13316 } 13317 static updateDefaultParams(type, value) { 13318 switch (type) {
13319 case _util.AnnotationEditorParamsType.FREETEXT_SIZE: 13320 FreeTextEditor._defaultFontSize = value; 13321 break; 13322 case _util.AnnotationEditorParamsType.FREETEXT_COLOR: 13323 FreeTextEditor._defaultColor = value; 13324 break; 13325 } 13326 } 13327 updateParams(type, value) { 13328 switch (type) { 13329 case _util.AnnotationEditorParamsType.FREETEXT_SIZE: 13330 this.#updateFontSize(value); 13331 break; 13332 case _util.AnnotationEditorParamsType.FREETEXT_COLOR: 13333 this.#updateColor(value); 13334 break; 13335 } 13336 } 13337 static get defaultPropertiesToUpdate() { 13338 return [[_util.AnnotationEditorParamsType.FREETEXT_SIZE, FreeTextEditor._defaultFontSize], [_util.AnnotationEditorParamsType.FREETEXT_COLOR, FreeTextEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor]]; 13339 } 13340 get propertiesToUpdate() { 13341 return [[_util.AnnotationEditorParamsType.FREETEXT_SIZE, this.#fontSize], [_util.AnnotationEditorParamsType.FREETEXT_COLOR, this.#color]]; 13342 } 13343 #updateFontSize(fontSize) { 13344 const setFontsize = size => { 13345 this.editorDiv.style.fontSize = `calc(${size}px * var(--scale-factor))`; 13346 this.translate(0, -(size - this.#fontSize) * this.parentScale); 13347 this.#fontSize = size; 13348 this.#setEditorDimensions(); 13349 }; 13350 const savedFontsize = this.#fontSize; 13351 this.addCommands({ 13352 cmd: () => { 13353 setFontsize(fontSize); 13354 }, 13355 undo: () => { 13356 setFontsize(savedFontsize); 13357 }, 13358 mustExec: true, 13359 type: _util.AnnotationEditorParamsType.FREETEXT_SIZE, 13360 overwriteIfSameType: true, 13361 keepUndo: true 13362 }); 13363 } 13364 #updateColor(color) { 13365 const savedColor = this.#color; 13366 this.addCommands({ 13367 cmd: () => { 13368 this.#color = this.editorDiv.style.color = color; 13369 }, 13370 undo: () => { 13371 this.#color = this.editorDiv.style.color = savedColor; 13372 }, 13373 mustExec: true, 13374 type: _util.AnnotationEditorParamsType.FREETEXT_COLOR, 13375 overwriteIfSameType: true, 13376 keepUndo: true 13377 }); 13378 } 13379 _translateEmpty(x, y) { 13380 this._uiManager.translateSelectedEditors(x, y, true); 13381 } 13382 getInitialTranslation() { 13383 const scale = this.parentScale; 13384 return [-FreeTextEditor._internalPadding * scale, -(FreeTextEditor._internalPadding + this.#fontSize) * scale]; 13385 } 13386 rebuild() { 13387 if (!this.parent) { 13388 return; 13389 } 13390 super.rebuild(); 13391 if (this.div === null) { 13392 return; 13393 } 13394 if (!this.isAttachedToDOM) { 13395 this.parent.add(this); 13396 } 13397 } 13398 enableEditMode() { 13399 if (this.isInEditMode()) { 13400 return; 13401 } 13402 this.parent.setEditingState(false); 13403 this.parent.updateToolbar(_util.AnnotationEditorType.FREETEXT); 13404 super.enableEditMode(); 13405 this.overlayDiv.classList.remove("enabled"); 13406 this.editorDiv.contentEditable = true; 13407 this._isDraggable = false; 13408 this.div.removeAttribute("aria-activedescendant"); 13409 this.editorDiv.addEventListener("keydown", this.#boundEditorDivKeydown); 13410 this.editorDiv.addEventListener("focus", this.#boundEditorDivFocus); 13411 this.editorDiv.addEventListener("blur", this.#boundEditorDivBlur); 13412 this.editorDiv.addEventListener("input", this.#boundEditorDivInput); 13413 } 13414 disableEditMode() { 13415 if (!this.isInEditMode()) { 13416 return; 13417 } 13418 this.parent.setEditingState(true); 13419 super.disableEditMode(); 13420 this.overlayDiv.classList.add("enabled"); 13421 this.editorDiv.contentEditable = false; 13422 this.div.setAttribute("aria-activedescendant", this.#editorDivId); 13423 this._isDraggable = true; 13424 this.editorDiv.removeEventListener("keydown", this.#boundEditorDivKeydown); 13425 this.editorDiv.removeEventListener("focus", this.#boundEditorDivFocus); 13426 this.editorDiv.removeEventListener("blur", this.#boundEditorDivBlur); 13427 this.editorDiv.removeEventListener("input", this.#boundEditorDivInput); 13428 this.div.focus({ 13429 preventScroll: true 13430 }); 13431 this.isEditing = false; 13432 this.parent.div.classList.add("freeTextEditing"); 13433 } 13434 focusin(event) { 13435 if (!this._focusEventsAllowed) { 13436 return; 13437 } 13438 super.focusin(event); 13439 if (event.target !== this.editorDiv) { 13440 this.editorDiv.focus(); 13441 } 13442 } 13443 onceAdded() { 13444 if (this.width) { 13445 this.#cheatInitialRect(); 13446 return; 13447 } 13448 this.enableEditMode(); 13449 this.editorDiv.focus(); 13450 if (this._initialOptions?.isCentered) { 13451 this.center(); 13452 } 13453 this._initialOptions = null; 13454 } 13455 isEmpty() { 13456 return !this.editorDiv || this.editorDiv.innerText.trim() === ""; 13457 } 13458 remove() { 13459 this.isEditing = false;
13460 if (this.parent) { 13461 this.parent.setEditingState(true); 13462 this.parent.div.classList.add("freeTextEditing"); 13463 } 13464 super.remove(); 13465 } 13466 #extractText() { 13467 const divs = this.editorDiv.getElementsByTagName("div"); 13468 if (divs.length === 0) { 13469 return this.editorDiv.innerText; 13470 } 13471 const buffer = []; 13472 for (const div of divs) { 13473 buffer.push(div.innerText.replace(/\r\n?|\n/, "")); 13474 } 13475 return buffer.join("\n"); 13476 } 13477 #setEditorDimensions() { 13478 const [parentWidth, parentHeight] = this.parentDimensions; 13479 let rect; 13480 if (this.isAttachedToDOM) { 13481 rect = this.div.getBoundingClientRect(); 13482 } else { 13483 const { 13484 currentLayer, 13485 div 13486 } = this; 13487 const savedDisplay = div.style.display; 13488 div.style.display = "hidden"; 13489 currentLayer.div.append(this.div); 13490 rect = div.getBoundingClientRect(); 13491 div.remove(); 13492 div.style.display = savedDisplay; 13493 } 13494 if (this.rotation % 180 === this.parentRotation % 180) { 13495 this.width = rect.width / parentWidth; 13496 this.height = rect.height / parentHeight; 13497 } else { 13498 this.width = rect.height / parentWidth; 13499 this.height = rect.width / parentHeight; 13500 } 13501 this.fixAndSetPosition(); 13502 } 13503 commit() { 13504 if (!this.isInEditMode()) { 13505 return; 13506 } 13507 super.commit(); 13508 this.disableEditMode(); 13509 const savedText = this.#content; 13510 const newText = this.#content = this.#extractText().trimEnd(); 13511 if (savedText === newText) { 13512 return; 13513 } 13514 const setText = text => { 13515 this.#content = text; 13516 if (!text) { 13517 this.remove(); 13518 return; 13519 } 13520 this.#setContent(); 13521 this._uiManager.rebuild(this); 13522 this.#setEditorDimensions(); 13523 }; 13524 this.addCommands({ 13525 cmd: () => { 13526 setText(newText); 13527 }, 13528 undo: () => { 13529 setText(savedText); 13530 }, 13531 mustExec: false 13532 }); 13533 this.#setEditorDimensions(); 13534 } 13535 shouldGetKeyboardEvents() { 13536 return this.isInEditMode(); 13537 } 13538 enterInEditMode() { 13539 this.enableEditMode(); 13540 this.editorDiv.focus(); 13541 } 13542 dblclick(event) { 13543 this.enterInEditMode(); 13544 } 13545 keydown(event) { 13546 if (event.target === this.div && event.key === "Enter") { 13547 this.enterInEditMode(); 13548 event.preventDefault(); 13549 } 13550 } 13551 editorDivKeydown(event) { 13552 FreeTextEditor._keyboardManager.exec(this, event); 13553 } 13554 editorDivFocus(event) { 13555 this.isEditing = true; 13556 } 13557 editorDivBlur(event) { 13558 this.isEditing = false; 13559 } 13560 editorDivInput(event) { 13561 this.parent.div.classList.toggle("freeTextEditing", this.isEmpty()); 13562 } 13563 disableEditing() { 13564 this.editorDiv.setAttribute("role", "comment"); 13565 this.editorDiv.removeAttribute("aria-multiline"); 13566 } 13567 enableEditing() { 13568 this.editorDiv.setAttribute("role", "textbox"); 13569 this.editorDiv.setAttribute("aria-multiline", true); 13570 } 13571 render() { 13572 if (this.div) { 13573 return this.div; 13574 } 13575 let baseX, baseY; 13576 if (this.width) { 13577 baseX = this.x; 13578 baseY = this.y; 13579 } 13580 super.render(); 13581 this.editorDiv = document.createElement("div"); 13582 this.editorDiv.className = "internal"; 13583 this.editorDiv.setAttribute("id", this.#editorDivId); 13584 this.enableEditing(); 13585 FreeTextEditor._l10nPromise.get("editor_free_text2_aria_label").then(msg => this.editorDiv?.setAttribute("aria-label", msg)); 13586 FreeTextEditor._l10nPromise.get("free_text2_default_content").then(msg => this.editorDiv?.setAttribute("default-content", msg)); 13587 this.editorDiv.contentEditable = true; 13588 const { 13589 style 13590 } = this.editorDiv; 13591 style.fontSize = `calc(${this.#fontSize}px * var(--scale-factor))`; 13592 style.color = this.#color; 13593 this.div.append(this.editorDiv); 13594 this.overlayDiv = document.createElement("div"); 13595 this.overlayDiv.classList.add("overlay", "enabled"); 13596 this.div.append(this.overlayDiv); 13597 (0, _tools.bindEvents)(this, this.div, ["dblclick", "keydown"]); 13598 if (this.width) { 13599 const [parentWidth, parentHeight] = this.parentDimensions; 13600 if (this.annotationElementId) { 13601 const { 13602 position 13603 } = this.#initialData; 13604 let [tx, ty] = this.getInitialTranslation(); 13605 [tx, ty] = this.pageTranslationToScreen(tx, ty); 13606 const [pageWidth, pageHeight] = this.pageDimensions; 13607 const [pageX, pageY] = this.pageTranslation; 13608 let posX, posY; 13609 switch (this.rotation) { 13610 case 0: 13611 posX = baseX + (position[0] - pageX) / pageWidth; 13612 posY = baseY + this.height - (position[1] - pageY) / pageHeight; 13613 break; 13614 case 90: 13615 posX = baseX + (position[0] - pageX) / pageWidth; 13616 posY = baseY - (position[1] - pageY) / pageHeight; 13617 [tx, ty] = [ty, -tx]; 13618 break; 13619 case 180: 13620 posX = baseX - this.width + (position[0] - pageX) / pageWidth; 13621 posY = baseY - (position[1] - pageY) / pageHeight; 13622 [tx, ty] = [-tx, -ty]; 13623 break; 13624 case 270: 13625 posX = baseX + (position[0] - pageX - this.height * pageHeight) / pageWidth; 13626 posY = baseY + (position[1] - pageY - this.width * pageWidth) / pageHeight; 13627 [tx, ty] = [-ty, tx]; 13628 break; 13629 } 13630 this.setAt(posX * parentWidth, posY * parentHeight, tx, ty); 13631 } else { 13632 this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); 13633 } 13634 this.#setContent(); 13635 this._isDraggable = true; 13636 this.editorDiv.contentEditable = false;
13637 } else { 13638 this._isDraggable = false; 13639 this.editorDiv.contentEditable = true; 13640 } 13641 return this.div; 13642 } 13643 #setContent() { 13644 this.editorDiv.replaceChildren(); 13645 if (!this.#content) { 13646 return; 13647 } 13648 for (const line of this.#content.split("\n")) { 13649 const div = document.createElement("div"); 13650 div.append(line ? document.createTextNode(line) : document.createElement("br")); 13651 this.editorDiv.append(div); 13652 } 13653 } 13654 get contentDiv() { 13655 return this.editorDiv; 13656 } 13657 static deserialize(data, parent, uiManager) { 13658 let initialData = null; 13659 if (data instanceof _annotation_layer.FreeTextAnnotationElement) { 13660 const { 13661 data: { 13662 defaultAppearanceData: { 13663 fontSize, 13664 fontColor 13665 }, 13666 rect, 13667 rotation, 13668 id 13669 }, 13670 textContent, 13671 textPosition, 13672 parent: { 13673 page: { 13674 pageNumber 13675 } 13676 } 13677 } = data; 13678 if (!textContent || textContent.length === 0) { 13679 return null; 13680 } 13681 initialData = data = { 13682 annotationType: _util.AnnotationEditorType.FREETEXT, 13683 color: Array.from(fontColor), 13684 fontSize, 13685 value: textContent.join("\n"), 13686 position: textPosition, 13687 pageIndex: pageNumber - 1, 13688 rect, 13689 rotation, 13690 id, 13691 deleted: false 13692 }; 13693 } 13694 const editor = super.deserialize(data, parent, uiManager); 13695 editor.#fontSize = data.fontSize; 13696 editor.#color = _util.Util.makeHexColor(...data.color); 13697 editor.#content = data.value; 13698 editor.annotationElementId = data.id || null; 13699 editor.#initialData = initialData; 13700 return editor; 13701 } 13702 serialize(isForCopying = false) { 13703 if (this.isEmpty()) { 13704 return null; 13705 } 13706 if (this.deleted) { 13707 return { 13708 pageIndex: this.pageIndex, 13709 id: this.annotationElementId, 13710 deleted: true 13711 }; 13712 } 13713 const padding = FreeTextEditor._internalPadding * this.parentScale; 13714 const rect = this.getRect(padding, padding); 13715 const color = _editor.AnnotationEditor._colorManager.convert(this.isAttachedToDOM ? getComputedStyle(this.editorDiv).color : this.#color); 13716 const serialized = { 13717 annotationType: _util.AnnotationEditorType.FREETEXT, 13718 color, 13719 fontSize: this.#fontSize, 13720 value: this.#content, 13721 pageIndex: this.pageIndex, 13722 rect, 13723 rotation: this.rotation 13724 }; 13725 if (isForCopying) { 13726 return serialized; 13727 } 13728 if (this.annotationElementId && !this.#hasElementChanged(serialized)) { 13729 return null; 13730 } 13731 serialized.id = this.annotationElementId; 13732 return serialized; 13733 } 13734 #hasElementChanged(serialized) { 13735 const { 13736 value, 13737 fontSize, 13738 color, 13739 rect, 13740 pageIndex 13741 } = this.#initialData; 13742 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; 13743 } 13744 #cheatInitialRect(delayed = false) { 13745 if (!this.annotationElementId) { 13746 return; 13747 } 13748 this.#setEditorDimensions(); 13749 if (!delayed && (this.width === 0 || this.height === 0)) { 13750 setTimeout(() => this.#cheatInitialRect(true), 0); 13751 return; 13752 } 13753 const padding = FreeTextEditor._internalPadding * this.parentScale; 13754 this.#initialData.rect = this.getRect(padding, padding); 13755 } 13756} 13757exports.FreeTextEditor = FreeTextEditor; 13758 13759/***/ }), 13760/* 29 */ 13761/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 13762 13763 13764 13765Object.defineProperty(exports, "__esModule", ({ 13766 value: true 13767})); 13768exports.StampAnnotationElement = exports.InkAnnotationElement = exports.FreeTextAnnotationElement = exports.AnnotationLayer = void 0; 13769var _util = __w_pdfjs_require__(1); 13770var _display_utils = __w_pdfjs_require__(6); 13771var _annotation_storage = __w_pdfjs_require__(3); 13772var _scripting_utils = __w_pdfjs_require__(30); 13773var _displayL10n_utils = __w_pdfjs_require__(31); 13774var _xfa_layer = __w_pdfjs_require__(32); 13775const DEFAULT_TAB_INDEX = 1000; 13776const DEFAULT_FONT_SIZE = 9; 13777const GetElementsByNameSet = new WeakSet(); 13778function getRectDims(rect) { 13779 return { 13780 width: rect[2] - rect[0], 13781 height: rect[3] - rect[1] 13782 }; 13783} 13784class AnnotationElementFactory { 13785 static create(parameters) { 13786 const subtype = parameters.data.annotationType; 13787 switch (subtype) { 13788 case _util.AnnotationType.LINK: 13789 return new LinkAnnotationElement(parameters); 13790 case _util.AnnotationType.TEXT: 13791 return new TextAnnotationElement(parameters); 13792 case _util.AnnotationType.WIDGET: 13793 const fieldType = parameters.data.fieldType; 13794 switch (fieldType) { 13795 case "Tx": 13796 return new TextWidgetAnnotationElement(parameters); 13797 case "Btn": 13798 if (parameters.data.radioButton) { 13799 return new RadioButtonWidgetAnnotationElement(parameters); 13800 } else if (parameters.data.checkBox) { 13801 return new CheckboxWidgetAnnotationElement(parameters); 13802 } 13803 return new PushButtonWidgetAnnotationElement(parameters); 13804 case "Ch": 13805 return new ChoiceWidgetAnnotationElement(parameters); 13806 case "Sig": 13807 return new SignatureWidgetAnnotationElement(parameters); 13808 } 13809 return new WidgetAnnotationElement(parameters); 13810 case _util.AnnotationType.POPUP: 13811 return new PopupAnnotationElement(parameters); 13812 case _util.AnnotationType.FREETEXT: 13813 return new FreeTextAnnotationElement(parameters); 13814 case _util.AnnotationType.LINE: 13815 return new LineAnnotationElement(parameters); 13816 case _util.AnnotationType.SQUARE: 13817 return new SquareAnnotationElement(parameters); 13818 case _util.AnnotationType.CIRCLE: 13819 return new CircleAnnotationElement(parameters); 13820 case _util.AnnotationType.POLYLINE: 13821 return new PolylineAnnotationElement(parameters); 13822 case _util.AnnotationType.CARET: 13823 return new CaretAnnotationElement(parameters); 13824 case _util.AnnotationType.INK: 13825 return new InkAnnotationElement(parameters); 13826 case _util.AnnotationType.POLYGON: 13827 return new PolygonAnnotationElement(parameters); 13828 case _util.AnnotationType.HIGHLIGHT: 13829 return new HighlightAnnotationElement(parameters); 13830 case _util.AnnotationType.UNDERLINE: 13831 return new UnderlineAnnotationElement(parameters); 13832 case _util.AnnotationType.SQUIGGLY: 13833 return new SquigglyAnnotationElement(parameters); 13834 case _util.AnnotationType.STRIKEOUT: 13835 return new StrikeOutAnnotationElement(parameters); 13836 case _util.AnnotationType.STAMP: 13837 return new StampAnnotationElement(parameters); 13838 case _util.AnnotationType.FILEATTACHMENT: 13839 return new FileAttachmentAnnotationElement(parameters); 13840 default: 13841 return new AnnotationElement(parameters); 13842 } 13843 } 13844} 13845class AnnotationElement { 13846 #hasBorder = false;
13847 constructor(parameters, { 13848 isRenderable = false, 13849 ignoreBorder = false, 13850 createQuadrilaterals = false 13851 } = {}) { 13852 this.isRenderable = isRenderable; 13853 this.data = parameters.data; 13854 this.layer = parameters.layer; 13855 this.linkService = parameters.linkService; 13856 this.downloadManager = parameters.downloadManager; 13857 this.imageResourcesPath = parameters.imageResourcesPath; 13858 this.renderForms = parameters.renderForms; 13859 this.svgFactory = parameters.svgFactory; 13860 this.annotationStorage = parameters.annotationStorage; 13861 this.enableScripting = parameters.enableScripting; 13862 this.hasJSActions = parameters.hasJSActions; 13863 this._fieldObjects = parameters.fieldObjects; 13864 this.parent = parameters.parent; 13865 if (isRenderable) { 13866 this.container = this._createContainer(ignoreBorder); 13867 } 13868 if (createQuadrilaterals) { 13869 this._createQuadrilaterals(); 13870 } 13871 } 13872 _createContainer(ignoreBorder) { 13873 const { 13874 data, 13875 parent: { 13876 page, 13877 viewport 13878 } 13879 } = this; 13880 const container = document.createElement("section"); 13881 container.setAttribute("data-annotation-id", data.id); 13882 container.style.zIndex = this.parent.zIndex++; 13883 if (this.data.popupRef) { 13884 container.setAttribute("aria-haspopup", "dialog"); 13885 } 13886 if (data.noRotate) { 13887 container.classList.add("norotate"); 13888 } 13889 const { 13890 pageWidth, 13891 pageHeight, 13892 pageX, 13893 pageY 13894 } = viewport.rawDims; 13895 if (!data.rect || this instanceof PopupAnnotationElement) { 13896 const { 13897 rotation 13898 } = data; 13899 if (!data.hasOwnCanvas && rotation !== 0) { 13900 this.setRotation(rotation, container); 13901 } 13902 return container; 13903 } 13904 const { 13905 width, 13906 height 13907 } = getRectDims(data.rect); 13908 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]]); 13909 if (!ignoreBorder && data.borderStyle.width > 0) { 13910 container.style.borderWidth = `${data.borderStyle.width}px`; 13911 const horizontalRadius = data.borderStyle.horizontalCornerRadius; 13912 const verticalRadius = data.borderStyle.verticalCornerRadius; 13913 if (horizontalRadius > 0 || verticalRadius > 0) { 13914 const radius = `calc(${horizontalRadius}px * var(--scale-factor)) / calc(${verticalRadius}px * var(--scale-factor))`; 13915 container.style.borderRadius = radius; 13916 } else if (this instanceof RadioButtonWidgetAnnotationElement) { 13917 const radius = `calc(${width}px * var(--scale-factor)) / calc(${height}px * var(--scale-factor))`; 13918 container.style.borderRadius = radius; 13919 } 13920 switch (data.borderStyle.style) { 13921 case _util.AnnotationBorderStyleType.SOLID: 13922 container.style.borderStyle = "solid"; 13923 break; 13924 case _util.AnnotationBorderStyleType.DASHED: 13925 container.style.borderStyle = "dashed"; 13926 break; 13927 case _util.AnnotationBorderStyleType.BEVELED: 13928 (0, _util.warn)("Unimplemented border style: beveled"); 13929 break; 13930 case _util.AnnotationBorderStyleType.INSET: 13931 (0, _util.warn)("Unimplemented border style: inset"); 13932 break; 13933 case _util.AnnotationBorderStyleType.UNDERLINE: 13934 container.style.borderBottomStyle = "solid"; 13935 break; 13936 default: 13937 break; 13938 } 13939 const borderColor = data.borderColor || null; 13940 if (borderColor) { 13941 this.#hasBorder = true; 13942 container.style.borderColor = _util.Util.makeHexColor(borderColor[0] | 0, borderColor[1] | 0, borderColor[2] | 0); 13943 } else { 13944 container.style.borderWidth = 0; 13945 } 13946 } 13947 container.style.left = `${100 * (rect[0] - pageX) / pageWidth}%`; 13948 container.style.top = `${100 * (rect[1] - pageY) / pageHeight}%`; 13949 const { 13950 rotation 13951 } = data; 13952 if (data.hasOwnCanvas || rotation === 0) { 13953 container.style.width = `${100 * width / pageWidth}%`; 13954 container.style.height = `${100 * height / pageHeight}%`; 13955 } else { 13956 this.setRotation(rotation, container); 13957 } 13958 return container; 13959 } 13960 setRotation(angle, container = this.container) { 13961 if (!this.data.rect) { 13962 return; 13963 } 13964 const { 13965 pageWidth, 13966 pageHeight 13967 } = this.parent.viewport.rawDims; 13968 const { 13969 width, 13970 height 13971 } = getRectDims(this.data.rect); 13972 let elementWidth, elementHeight; 13973 if (angle % 180 === 0) { 13974 elementWidth = 100 * width / pageWidth; 13975 elementHeight = 100 * height / pageHeight; 13976 } else { 13977 elementWidth = 100 * height / pageWidth; 13978 elementHeight = 100 * width / pageHeight; 13979 } 13980 container.style.width = `${elementWidth}%`; 13981 container.style.height = `${elementHeight}%`; 13982 container.setAttribute("data-main-rotation", (360 - angle) % 360); 13983 } 13984 get _commonActions() { 13985 const setColor = (jsName, styleName, event) => { 13986 const color = event.detail[jsName]; 13987 const colorType = color[0]; 13988 const colorArray = color.slice(1); 13989 event.target.style[styleName] = _scripting_utils.ColorConverters[`${colorType}_HTML`](colorArray); 13990 this.annotationStorage.setValue(this.data.id, { 13991 [styleName]: _scripting_utils.ColorConverters[`${colorType}_rgb`](colorArray) 13992 }); 13993 }; 13994 return (0, _util.shadow)(this, "_commonActions", { 13995 display: event => { 13996 const { 13997 display 13998 } = event.detail; 13999 const hidden = display % 2 === 1; 14000 this.container.style.visibility = hidden ? "hidden" : "visible"; 14001 this.annotationStorage.setValue(this.data.id, { 14002 noView: hidden, 14003 noPrint: display === 1 || display === 2 14004 }); 14005 }, 14006 print: event => { 14007 this.annotationStorage.setValue(this.data.id, { 14008 noPrint: !event.detail.print 14009 }); 14010 }, 14011 hidden: event => { 14012 const { 14013 hidden 14014 } = event.detail; 14015 this.container.style.visibility = hidden ? "hidden" : "visible"; 14016 this.annotationStorage.setValue(this.data.id, { 14017 noPrint: hidden, 14018 noView: hidden 14019 }); 14020 }, 14021 focus: event => { 14022 setTimeout(() =>
14022 event.target.focus({ 14023 preventScroll: false 14024 }), 0); 14025 }, 14026 userName: event => { 14027 event.target.title = event.detail.userName; 14028 }, 14029 readonly: event => { 14030 event.target.disabled = event.detail.readonly; 14031 }, 14032 required: event => { 14033 this._setRequired(event.target, event.detail.required); 14034 }, 14035 bgColor: event => { 14036 setColor("bgColor", "backgroundColor", event); 14037 }, 14038 fillColor: event => { 14039 setColor("fillColor", "backgroundColor", event); 14040 }, 14041 fgColor: event => { 14042 setColor("fgColor", "color", event); 14043 }, 14044 textColor: event => { 14045 setColor("textColor", "color", event); 14046 }, 14047 borderColor: event => { 14048 setColor("borderColor", "borderColor", event); 14049 }, 14050 strokeColor: event => { 14051 setColor("strokeColor", "borderColor", event); 14052 }, 14053 rotation: event => { 14054 const angle = event.detail.rotation; 14055 this.setRotation(angle); 14056 this.annotationStorage.setValue(this.data.id, { 14057 rotation: angle 14058 }); 14059 } 14060 }); 14061 } 14062 _dispatchEventFromSandbox(actions, jsEvent) { 14063 const commonActions = this._commonActions; 14064 for (const name of Object.keys(jsEvent.detail)) { 14065 const action = actions[name] || commonActions[name]; 14066 action?.(jsEvent); 14067 } 14068 } 14069 _setDefaultPropertiesFromJS(element) { 14070 if (!this.enableScripting) { 14071 return; 14072 } 14073 const storedData = this.annotationStorage.getRawValue(this.data.id); 14074 if (!storedData) { 14075 return; 14076 } 14077 const commonActions = this._commonActions; 14078 for (const [actionName, detail] of Object.entries(storedData)) { 14079 const action = commonActions[actionName]; 14080 if (action) { 14081 const eventProxy = { 14082 detail: { 14083 [actionName]: detail 14084 }, 14085 target: element 14086 }; 14087 action(eventProxy); 14088 delete storedData[actionName]; 14089 } 14090 } 14091 } 14092 _createQuadrilaterals() { 14093 if (!this.container) { 14094 return; 14095 } 14096 const { 14097 quadPoints 14098 } = this.data; 14099 if (!quadPoints) { 14100 return; 14101 } 14102 const [rectBlX, rectBlY, rectTrX, rectTrY] = this.data.rect; 14103 if (quadPoints.length === 1) { 14104 const [, { 14105 x: trX, 14106 y: trY 14107 }, { 14108 x: blX, 14109 y: blY 14110 }] = quadPoints[0]; 14111 if (rectTrX === trX && rectTrY === trY && rectBlX === blX && rectBlY === blY) { 14112 return; 14113 } 14114 } 14115 const { 14116 style 14117 } = this.container; 14118 let svgBuffer; 14119 if (this.#hasBorder) { 14120 const { 14121 borderColor, 14122 borderWidth 14123 } = style; 14124 style.borderWidth = 0; 14125 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}">`]; 14126 this.container.classList.add("hasBorder"); 14127 } 14128 const width = rectTrX - rectBlX; 14129 const height = rectTrY - rectBlY; 14130 const { 14131 svgFactory 14132 } = this; 14133 const svg = svgFactory.createElement("svg"); 14134 svg.classList.add("quadrilateralsContainer"); 14135 svg.setAttribute("width", 0); 14136 svg.setAttribute("height", 0); 14137 const defs = svgFactory.createElement("defs"); 14138 svg.append(defs); 14139 const clipPath = svgFactory.createElement("clipPath"); 14140 const id = `clippath_${this.data.id}`; 14141 clipPath.setAttribute("id", id); 14142 clipPath.setAttribute("clipPathUnits", "objectBoundingBox"); 14143 defs.append(clipPath); 14144 for (const [, { 14145 x: trX, 14146 y: trY 14147 }, { 14148 x: blX, 14149 y: blY 14150 }] of quadPoints) { 14151 const rect = svgFactory.createElement("rect"); 14152 const x = (blX - rectBlX) / width; 14153 const y = (rectTrY - trY) / height; 14154 const rectWidth = (trX - blX) / width; 14155 const rectHeight = (trY - blY) / height; 14156 rect.setAttribute("x", x); 14157 rect.setAttribute("y", y); 14158 rect.setAttribute("width", rectWidth); 14159 rect.setAttribute("height", rectHeight); 14160 clipPath.append(rect); 14161 svgBuffer?.push(`<rect vector-effect="non-scaling-stroke" x="${x}" y="${y}" width="${rectWidth}" height="${rectHeight}"/>`); 14162 } 14163 if (this.#hasBorder) { 14164 svgBuffer.push(`</g></svg>')`); 14165 style.backgroundImage = svgBuffer.join(""); 14166 } 14167 this.container.append(svg); 14168 this.container.style.clipPath = `url(#${id})`; 14169 } 14170 _createPopup() { 14171 const { 14172 container, 14173 data 14174 } = this; 14175 container.setAttribute("aria-haspopup", "dialog"); 14176 const popup = new PopupAnnotationElement({ 14177 data: { 14178 color: data.color, 14179 titleObj: data.titleObj, 14180 modificationDate: data.modificationDate, 14181 contentsObj: data.contentsObj, 14182 richText: data.richText, 14183 parentRect: data.rect, 14184 borderStyle: 0, 14185 id: `popup_${data.id}`, 14186 rotation: data.rotation 14187 }, 14188 parent: this.parent, 14189 elements: [this] 14190 }); 14191 this.parent.div.append(popup.render()); 14192 } 14193 render() { 14194 (0, _util.unreachable)("Abstract method `AnnotationElement.render` called"); 14195 } 14196 _getElementsByName(name, skipId = null) { 14197 const fields = []; 14198 if (this._fieldObjects) { 14199 const fieldObj = this._fieldObjects[name]; 14200 if (fieldObj) { 14201 for (const { 14202 page, 14203 id, 14204 exportValues 14205 } of fieldObj) { 14206 if (page === -1) { 14207 continue; 14208 } 14209 if (id === skipId) { 14210 continue; 14211 } 14212 const exportValue = typeof exportValues === "string" ? exportValues : null; 14213 const domElement = document.querySelector(`[data-element-id="${id}"]`); 14214 if (domElement && !GetElementsByNameSet.has(domElement)) { 14215 (0, _util.warn)(`_getElementsByName - element not allowed: ${id}`); 14216 continue; 14217 } 14218 fields.push({ 14219 id, 14220 exportValue, 14221 domElement 14222 }); 14223 } 14224 } 14225 return fields; 14226 } 14227 for (const domElement of document.getElementsByName(name)) { 14228 const { 14229 exportValue 14230 } = domElement; 14231 const id = domElement.getAttribute("data-element-id"); 14232 if (id === skipId) { 14233 continue; 14234 } 14235 if (!GetElementsByNameSet.has(domElement)) { 14236 continue; 14237 } 14238 fields.push({ 14239 id, 14240 exportValue, 14241 domElement 14242 }); 14243 } 14244 return fields; 14245 } 14246 show() { 14247 if (this.container) { 14248 this.container.hidden = false;
vendor: 4,141 bytes, lines 14249-14393
14249 } 14250 this.popup?.maybeShow(); 14251 } 14252 hide() { 14253 if (this.container) { 14254 this.container.hidden = true; 14255 } 14256 this.popup?.forceHide(); 14257 } 14258 getElementsToTriggerPopup() { 14259 return this.container; 14260 } 14261 addHighlightArea() { 14262 const triggers = this.getElementsToTriggerPopup(); 14263 if (Array.isArray(triggers)) { 14264 for (const element of triggers) { 14265 element.classList.add("highlightArea"); 14266 } 14267 } else { 14268 triggers.classList.add("highlightArea"); 14269 } 14270 } 14271 _editOnDoubleClick() { 14272 const { 14273 annotationEditorType: mode, 14274 data: { 14275 id: editId 14276 } 14277 } = this; 14278 this.container.addEventListener("dblclick", () => { 14279 this.linkService.eventBus?.dispatch("switchannotationeditormode", { 14280 source: this, 14281 mode, 14282 editId 14283 }); 14284 }); 14285 } 14286} 14287class LinkAnnotationElement extends AnnotationElement { 14288 constructor(parameters, options = null) { 14289 super(parameters, { 14290 isRenderable: true, 14291 ignoreBorder: !!options?.ignoreBorder, 14292 createQuadrilaterals: true 14293 }); 14294 this.isTooltipOnly = parameters.data.isTooltipOnly; 14295 } 14296 render() { 14297 const { 14298 data, 14299 linkService 14300 } = this; 14301 const link = document.createElement("a"); 14302 link.setAttribute("data-element-id", data.id); 14303 let isBound = false; 14304 if (data.url) { 14305 linkService.addLinkAttributes(link, data.url, data.newWindow); 14306 isBound = true; 14307 } else if (data.action) { 14308 this._bindNamedAction(link, data.action); 14309 isBound = true; 14310 } else if (data.attachment) { 14311 this._bindAttachment(link, data.attachment); 14312 isBound = true; 14313 } else if (data.setOCGState) { 14314 this.#bindSetOCGState(link, data.setOCGState); 14315 isBound = true; 14316 } else if (data.dest) { 14317 this._bindLink(link, data.dest); 14318 isBound = true; 14319 } else { 14320 if (data.actions && (data.actions.Action || data.actions["Mouse Up"] || data.actions["Mouse Down"]) && this.enableScripting && this.hasJSActions) { 14321 this._bindJSAction(link, data); 14322 isBound = true; 14323 } 14324 if (data.resetForm) { 14325 this._bindResetFormAction(link, data.resetForm); 14326 isBound = true; 14327 } else if (this.isTooltipOnly && !isBound) { 14328 this._bindLink(link, ""); 14329 isBound = true; 14330 } 14331 } 14332 this.container.classList.add("linkAnnotation"); 14333 if (isBound) { 14334 this.container.append(link); 14335 } 14336 return this.container; 14337 } 14338 #setInternalLink() { 14339 this.container.setAttribute("data-internal-link", ""); 14340 } 14341 _bindLink(link, destination) { 14342 link.href = this.linkService.getDestinationHash(destination); 14343 link.onclick = () => { 14344 if (destination) { 14345 this.linkService.goToDestination(destination); 14346 } 14347 return false; 14348 }; 14349 if (destination || destination === "") { 14350 this.#setInternalLink(); 14351 } 14352 } 14353 _bindNamedAction(link, action) { 14354 link.href = this.linkService.getAnchorUrl(""); 14355 link.onclick = () => { 14356 this.linkService.executeNamedAction(action); 14357 return false; 14358 }; 14359 this.#setInternalLink(); 14360 } 14361 _bindAttachment(link, attachment) { 14362 link.href = this.linkService.getAnchorUrl(""); 14363 link.onclick = () => { 14364 this.downloadManager?.openOrDownloadData(this.container, attachment.content, attachment.filename); 14365 return false; 14366 }; 14367 this.#setInternalLink(); 14368 } 14369 #bindSetOCGState(link, action) { 14370 link.href = this.linkService.getAnchorUrl(""); 14371 link.onclick = () => { 14372 this.linkService.executeSetOCGState(action); 14373 return false; 14374 }; 14375 this.#setInternalLink(); 14376 } 14377 _bindJSAction(link, data) { 14378 link.href = this.linkService.getAnchorUrl(""); 14379 const map = new Map([["Action", "onclick"], ["Mouse Up", "onmouseup"], ["Mouse Down", "onmousedown"]]); 14380 for (const name of Object.keys(data.actions)) { 14381 const jsName = map.get(name); 14382 if (!jsName) { 14383 continue; 14384 } 14385 link[jsName] = () => { 14386 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14387 source: this, 14388 detail: { 14389 id: data.id, 14390 name 14391 } 14392 }); 14393 return false;
14394 }; 14395 } 14396 if (!link.onclick) { 14397 link.onclick = () => false; 14398 } 14399 this.#setInternalLink(); 14400 } 14401 _bindResetFormAction(link, resetForm) { 14402 const otherClickAction = link.onclick; 14403 if (!otherClickAction) { 14404 link.href = this.linkService.getAnchorUrl(""); 14405 } 14406 this.#setInternalLink(); 14407 if (!this._fieldObjects) { 14408 (0, _util.warn)(`_bindResetFormAction - "resetForm" action not supported, ` + "ensure that the `fieldObjects` parameter is provided."); 14409 if (!otherClickAction) { 14410 link.onclick = () => false; 14411 } 14412 return; 14413 } 14414 link.onclick = () => { 14415 otherClickAction?.(); 14416 const { 14417 fields: resetFormFields, 14418 refs: resetFormRefs, 14419 include 14420 } = resetForm; 14421 const allFields = []; 14422 if (resetFormFields.length !== 0 || resetFormRefs.length !== 0) { 14423 const fieldIds = new Set(resetFormRefs); 14424 for (const fieldName of resetFormFields) { 14425 const fields = this._fieldObjects[fieldName] || []; 14426 for (const { 14427 id 14428 } of fields) { 14429 fieldIds.add(id); 14430 } 14431 } 14432 for (const fields of Object.values(this._fieldObjects)) { 14433 for (const field of fields) { 14434 if (fieldIds.has(field.id) === include) { 14435 allFields.push(field); 14436 } 14437 } 14438 } 14439 } else { 14440 for (const fields of Object.values(this._fieldObjects)) { 14441 allFields.push(...fields); 14442 } 14443 } 14444 const storage = this.annotationStorage; 14445 const allIds = []; 14446 for (const field of allFields) { 14447 const { 14448 id 14449 } = field; 14450 allIds.push(id); 14451 switch (field.type) { 14452 case "text": 14453 { 14454 const value = field.defaultValue || ""; 14455 storage.setValue(id, { 14456 value 14457 }); 14458 window.updateAngularFormValue(id, { 14459 value 14460 }); 14461 break; 14462 } 14463 case "checkbox": 14464 case "radiobutton": 14465 { 14466 const value = field.defaultValue === field.exportValues; 14467 storage.setValue(id, { 14468 value 14469 }); 14470 window.updateAngularFormValue(id, { 14471 value 14472 }); 14473 break; 14474 } 14475 case "combobox": 14476 case "listbox": 14477 { 14478 const value = field.defaultValue || ""; 14479 storage.setValue(id, { 14480 value 14481 }); 14482 window.updateAngularFormValue(id, { 14483 value 14484 }); 14485 break; 14486 } 14487 default: 14488 continue; 14489 } 14490 const domElement = document.querySelector(`[data-element-id="${id}"]`); 14491 if (!domElement) { 14492 continue; 14493 } else if (!GetElementsByNameSet.has(domElement)) { 14494 (0, _util.warn)(`_bindResetFormAction - element not allowed: ${id}`); 14495 continue; 14496 } 14497 domElement.dispatchEvent(new Event("resetform")); 14498 } 14499 if (this.enableScripting) { 14500 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14501 source: this, 14502 detail: { 14503 id: "app", 14504 ids: allIds, 14505 name: "ResetForm" 14506 } 14507 }); 14508 } 14509 return false; 14510 }; 14511 } 14512} 14513class TextAnnotationElement extends AnnotationElement { 14514 constructor(parameters) { 14515 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 14516 super(parameters, { 14517 isRenderable 14518 }); 14519 } 14520 render() { 14521 this.container.classList.add("textAnnotation"); 14522 const image = document.createElement("img"); 14523 image.src = this.imageResourcesPath + "annotation-" + this.data.name.toLowerCase() + ".svg"; 14524 image.alt = "[{{type}} Annotation]"; 14525 image.dataset.l10nId = "text_annotation_type"; 14526 image.dataset.l10nArgs = JSON.stringify({ 14527 type: this.data.name 14528 }); 14529 if (!this.data.popupRef) { 14530 this._createPopup(); 14531 } 14532 this.container.append(image); 14533 return this.container; 14534 } 14535} 14536class WidgetAnnotationElement extends AnnotationElement { 14537 render() { 14538 if (this.data.alternativeText) { 14539 this.container.title = this.data.alternativeText; 14540 } 14541 return this.container; 14542 } 14543 showElementAndHideCanvas(element) { 14544 if (this.data.hasOwnCanvas) { 14545 if (element.previousSibling?.nodeName === "CANVAS") { 14546 element.previousSibling.hidden = true; 14547 } 14548 element.hidden = false;
14549 } 14550 } 14551 _getKeyModifier(event) { 14552 const { 14553 isWin, 14554 isMac 14555 } = _util.FeatureTest.platform; 14556 return isWin && event.ctrlKey || isMac && event.metaKey; 14557 } 14558 _setEventListener(element, baseName, eventName, valueGetter) { 14559 if (baseName.includes("mouse")) { 14560 element.addEventListener(baseName, event => { 14561 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14562 source: this, 14563 detail: { 14564 id: this.data.id, 14565 name: eventName, 14566 value: valueGetter(event), 14567 shift: event.shiftKey, 14568 modifier: this._getKeyModifier(event) 14569 } 14570 }); 14571 }); 14572 } else { 14573 element.addEventListener(baseName, event => { 14574 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14575 source: this, 14576 detail: { 14577 id: this.data.id, 14578 name: eventName, 14579 value: valueGetter(event) 14580 } 14581 }); 14582 }); 14583 } 14584 } 14585 _setEventListeners(element, names, getter) { 14586 for (const [baseName, eventName] of names) { 14587 if (eventName === "Action" || this.data.actions?.[eventName]) { 14588 this._setEventListener(element, baseName, eventName, getter); 14589 } 14590 } 14591 } 14592 _setBackgroundColor(element) { 14593 const color = this.data.backgroundColor || null; 14594 element.style.backgroundColor = color === null ? "transparent" : _util.Util.makeHexColor(color[0], color[1], color[2]); 14595 } 14596 _setTextStyle(element) { 14597 const TEXT_ALIGNMENT = ["left", "center", "right"]; 14598 const { 14599 fontColor 14600 } = this.data.defaultAppearanceData; 14601 const fontSize = this.data.defaultAppearanceData.fontSize || DEFAULT_FONT_SIZE; 14602 const style = element.style;
14603 let computedFontSize; 14604 const BORDER_SIZE = 2; 14605 const roundToOneDecimal = x => Math.round(10 * x) / 10; 14606 if (this.data.multiLine) { 14607 const height = Math.abs(this.data.rect[3] - this.data.rect[1] - BORDER_SIZE); 14608 const numberOfLines = Math.round(height / (_util.LINE_FACTOR * fontSize)) || 1; 14609 const lineHeight = height / numberOfLines; 14610 computedFontSize = Math.min(fontSize, roundToOneDecimal(lineHeight / _util.LINE_FACTOR)); 14611 } else { 14612 const height = Math.abs(this.data.rect[3] - this.data.rect[1] - BORDER_SIZE); 14613 computedFontSize = Math.min(fontSize, roundToOneDecimal(height / _util.LINE_FACTOR)); 14614 } 14615 style.fontSize = `calc(${computedFontSize}px * var(--scale-factor))`; 14616 style.color = _util.Util.makeHexColor(fontColor[0], fontColor[1], fontColor[2]); 14617 if (this.data.textAlignment !== null) { 14618 style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment]; 14619 } 14620 } 14621 _setRequired(element, isRequired) { 14622 if (isRequired) { 14623 element.setAttribute("required", true); 14624 } else { 14625 element.removeAttribute("required"); 14626 } 14627 element.setAttribute("aria-required", isRequired); 14628 } 14629} 14630class TextWidgetAnnotationElement extends WidgetAnnotationElement { 14631 constructor(parameters) { 14632 const isRenderable = parameters.renderForms || !parameters.data.hasAppearance && !!parameters.data.fieldValue; 14633 super(parameters, { 14634 isRenderable 14635 }); 14636 } 14637 setPropertyOnSiblings(base, key, value, keyInStorage) { 14638 const storage = this.annotationStorage; 14639 for (const element of this._getElementsByName(base.name, base.id)) { 14640 if (element.domElement) { 14641 element.domElement[key] = value; 14642 } 14643 storage.setValue(element.id, { 14644 [keyInStorage]: value 14645 }); 14646 } 14647 } 14648 render() { 14649 const storage = this.annotationStorage; 14650 const id = this.data.id; 14651 this.container.classList.add("textWidgetAnnotation"); 14652 let element = null; 14653 if (this.renderForms) { 14654 const angularData = window.getFormValueFromAngular(this.data.fieldName); 14655 const formData = storage.getValue(id, { 14656 value: this.data.fieldValue 14657 }); 14658 const storedData = angularData.value ? angularData : formData; 14659 if (angularData !== formData) { 14660 storage.setValue(id, { 14661 value: angularData.value 14662 }); 14663 storedData.formattedValue = angularData.value; 14664 } 14665 let textContent = storedData.value || ""; 14666 const maxLen = storage.getValue(id, { 14667 charLimit: this.data.maxLen 14668 }).charLimit; 14669 if (maxLen && textContent.length > maxLen) { 14670 textContent = textContent.slice(0, maxLen); 14671 } 14672 let fieldFormattedValues = storedData.formattedValue || this.data.textContent?.join("\n") || null; 14673 if (fieldFormattedValues && this.data.comb) { 14674 fieldFormattedValues = fieldFormattedValues.replaceAll(/\s+/g, ""); 14675 } 14676 const elementData = { 14677 userValue: textContent, 14678 formattedValue: fieldFormattedValues, 14679 lastCommittedValue: null, 14680 commitKey: 1 14681 }; 14682 if (this.data.multiLine) { 14683 element = document.createElement("textarea"); 14684 element.textContent = fieldFormattedValues ?? textContent; 14685 if (this.data.doNotScroll) { 14686 element.style.overflowY = "hidden"; 14687 } 14688 } else { 14689 element = document.createElement("input"); 14690 element.type = "text"; 14691 element.setAttribute("value", fieldFormattedValues ?? textContent); 14692 if (this.data.doNotScroll) { 14693 element.style.overflowX = "hidden"; 14694 } 14695 } 14696 if (this.data.hasOwnCanvas) { 14697 element.hidden = true; 14698 } 14699 GetElementsByNameSet.add(element); 14700 element.setAttribute("data-element-id", id); 14701 element.disabled = this.data.readOnly; 14702 element.name = this.data.fieldName; 14703 element.tabIndex = DEFAULT_TAB_INDEX; 14704 this._setRequired(element, this.data.required); 14705 if (maxLen) { 14706 element.maxLength = maxLen; 14707 } 14708 element.addEventListener("input", event => { 14709 storage.setValue(id, { 14710 value: event.target.value 14711 });
14712 window.updateAngularFormValue(id, { 14713 value: event.target.value 14714 }); 14715 this.setPropertyOnSiblings(element, "value", event.target.value, "value"); 14716 elementData.formattedValue = null; 14717 }); 14718 element.addEventListener("resetform", event => { 14719 const defaultValue = this.data.defaultFieldValue ?? ""; 14720 element.value = elementData.userValue = defaultValue; 14721 elementData.formattedValue = null; 14722 }); 14723 let blurListener = event => { 14724 const { 14725 formattedValue 14726 } = elementData; 14727 if (formattedValue !== null && formattedValue !== undefined) { 14728 event.target.value = formattedValue; 14729 } 14730 event.target.scrollLeft = 0; 14731 }; 14732 window.registerAcroformField(id, element, storedData.value); 14733 element.addEventListener("updateFromAngular", newvalue => storage.setValue(id, { 14734 value: newvalue.detail 14735 })); 14736 if (this.enableScripting && this.hasJSActions) { 14737 element.addEventListener("focus", event => { 14738 const { 14739 target 14740 } = event; 14741 if (elementData.userValue) { 14742 target.value = elementData.userValue; 14743 } 14744 elementData.lastCommittedValue = target.value; 14745 elementData.commitKey = 1; 14746 }); 14747 element.addEventListener("updatefromsandbox", jsEvent => { 14748 this.showElementAndHideCanvas(jsEvent.target); 14749 const actions = { 14750 value(event) { 14751 elementData.userValue = event.detail.value ?? ""; 14752 storage.setValue(id, { 14753 value: elementData.userValue.toString() 14754 }); 14755 window.updateAngularFormValue(id, { 14756 value: elementData.userValue.toString() 14757 }); 14758 event.target.value = elementData.userValue; 14759 }, 14760 formattedValue(event) { 14761 const { 14762 formattedValue 14763 } = event.detail; 14764 elementData.formattedValue = formattedValue; 14765 if (formattedValue !== null && formattedValue !== undefined && event.target !== document.activeElement) { 14766 event.target.value = formattedValue; 14767 } 14768 storage.setValue(id, { 14769 formattedValue 14770 }); 14771 window.updateAngularFormValue(id, { 14772 formattedValue 14773 }); 14774 }, 14775 selRange(event) { 14776 event.target.setSelectionRange(...event.detail.selRange); 14777 }, 14778 charLimit: event => { 14779 const { 14780 charLimit 14781 } = event.detail; 14782 const { 14783 target 14784 } = event; 14785 if (charLimit === 0) { 14786 target.removeAttribute("maxLength"); 14787 return; 14788 } 14789 target.setAttribute("maxLength", charLimit); 14790 let value = elementData.userValue; 14791 if (!value || value.length <= charLimit) { 14792 return; 14793 } 14794 value = value.slice(0, charLimit); 14795 target.value = elementData.userValue = value; 14796 storage.setValue(id, { 14797 value 14798 }); 14799 window.updateAngularFormValue(id, { 14800 value 14801 }); 14802 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14803 source: this, 14804 detail: { 14805 id, 14806 name: "Keystroke", 14807 value, 14808 willCommit: true, 14809 commitKey: 1, 14810 selStart: target.selectionStart, 14811 selEnd: target.selectionEnd 14812 } 14813 }); 14814 } 14815 }; 14816 this._dispatchEventFromSandbox(actions, jsEvent); 14817 }); 14818 element.addEventListener("keydown", event => { 14819 elementData.commitKey = 1; 14820 let commitKey = -1; 14821 if (event.key === "Escape") { 14822 commitKey = 0; 14823 } else if (event.key === "Enter" && !this.data.multiLine) { 14824 commitKey = 2; 14825 } else if (event.key === "Tab") { 14826 elementData.commitKey = 3; 14827 } 14828 if (commitKey === -1) { 14829 return; 14830 } 14831 const { 14832 value 14833 } = event.target; 14834 if (elementData.lastCommittedValue === value) { 14835 return; 14836 } 14837 elementData.lastCommittedValue = value; 14838 elementData.userValue = value; 14839 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14840 source: this, 14841 detail: { 14842 id, 14843 name: "Keystroke", 14844 value, 14845 willCommit: true, 14846 commitKey, 14847 selStart: event.target.selectionStart, 14848 selEnd: event.target.selectionEnd 14849 } 14850 }); 14851 }); 14852 const _blurListener = blurListener; 14853 blurListener = null; 14854 element.addEventListener("blur", event => { 14855 if (!event.relatedTarget) { 14856 return; 14857 } 14858 const { 14859 value 14860 } = event.target; 14861 elementData.userValue = value; 14862 if (elementData.lastCommittedValue !== value) { 14863 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14864 source: this, 14865 detail: { 14866 id, 14867 name: "Keystroke", 14868 value, 14869 willCommit: true, 14870 commitKey: elementData.commitKey, 14871 selStart: event.target.selectionStart, 14872 selEnd: event.target.selectionEnd 14873 } 14874 }); 14875 } 14876 _blurListener(event); 14877 }); 14878 if (this.data.actions?.Keystroke) { 14879 element.addEventListener("beforeinput", event => { 14880 elementData.lastCommittedValue = null; 14881 const { 14882 data, 14883 target 14884 } = event; 14885 const { 14886 value, 14887 selectionStart, 14888 selectionEnd 14889 } = target; 14890 let selStart = selectionStart, 14891 selEnd = selectionEnd; 14892 switch (event.inputType) { 14893 case "deleteWordBackward": 14894 { 14895 const match = value.substring(0, selectionStart).match(/\w*[^\
14895w]*$/); 14896 if (match) { 14897 selStart -= match[0].length; 14898 } 14899 break; 14900 } 14901 case "deleteWordForward": 14902 { 14903 const match = value.substring(selectionStart).match(/^[^\w]*\w*/); 14904 if (match) { 14905 selEnd += match[0].length; 14906 } 14907 break; 14908 } 14909 case "deleteContentBackward": 14910 if (selectionStart === selectionEnd) { 14911 selStart -= 1; 14912 } 14913 break; 14914 case "deleteContentForward": 14915 if (selectionStart === selectionEnd) { 14916 selEnd += 1; 14917 } 14918 break; 14919 } 14920 event.preventDefault(); 14921 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14922 source: this, 14923 detail: { 14924 id, 14925 name: "Keystroke", 14926 value, 14927 change: data || "", 14928 willCommit: false, 14929 selStart, 14930 selEnd 14931 } 14932 }); 14933 }); 14934 } 14935 this._setEventListeners(element, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.value); 14936 } 14937 if (blurListener) { 14938 element.addEventListener("blur", blurListener); 14939 } 14940 if (this.data.comb) { 14941 const fieldWidth = this.data.rect[2] - this.data.rect[0]; 14942 const combWidth = fieldWidth / maxLen; 14943 element.classList.add("comb"); 14944 element.style.letterSpacing = `calc(${combWidth}px * var(--scale-factor) - 1ch)`; 14945 } 14946 } else { 14947 element = document.createElement("div"); 14948 element.textContent = this.data.fieldValue; 14949 element.style.verticalAlign = "middle"; 14950 element.style.display = "table-cell"; 14951 } 14952 this._setTextStyle(element); 14953 this._setBackgroundColor(element); 14954 this._setDefaultPropertiesFromJS(element); 14955 this.container.append(element); 14956 return this.container; 14957 } 14958} 14959class SignatureWidgetAnnotationElement extends WidgetAnnotationElement { 14960 constructor(parameters) { 14961 super(parameters, { 14962 isRenderable: !!parameters.data.hasOwnCanvas 14963 }); 14964 } 14965} 14966class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement { 14967 constructor(parameters) { 14968 super(parameters, { 14969 isRenderable: parameters.renderForms 14970 }); 14971 } 14972 render() { 14973 const storage = this.annotationStorage; 14974 const data = this.data; 14975 const id = data.id; 14976 const angularData = window.getFormValueFromAngular(this.data.fieldName); 14977 const formValue = storage.getValue(id, { 14978 value: data.exportValue === data.fieldValue 14979 }).value; 14980 let angularValue = undefined; 14981 if (angularData.value) { 14982 angularValue = angularData.value === true || angularData.value === data.exportValue; 14983 } 14984 let value = angularValue !== undefined ? angularValue : formValue; 14985 let updateAngularValueNecessary = false; 14986 if (typeof value === "string") { 14987 value = value === data.exportValue; 14988 storage.setValue(id, { 14989 value 14990 }); 14991 updateAngularValueNecessary = true; 14992 } else if (angularData?.value !== undefined && angularData.value !== formValue) { 14993 value = angularData.value === data.exportValue; 14994 storage.setValue(id, { 14995 value 14996 }); 14997 } 14998 this.container.classList.add("buttonWidgetAnnotation", "checkBox"); 14999 const element = document.createElement("input"); 15000 GetElementsByNameSet.add(element); 15001 element.setAttribute("data-element-id", id); 15002 element.disabled = data.readOnly; 15003 this._setRequired(element, this.data.required); 15004 element.type = "checkbox"; 15005 element.name = data.fieldName; 15006 if (value) { 15007 element.setAttribute("checked", true); 15008 } 15009 element.setAttribute("exportValue", data.exportValue); 15010 element.tabIndex = DEFAULT_TAB_INDEX; 15011 element.addEventListener("change", event => { 15012 const { 15013 name, 15014 checked 15015 } = event.target; 15016 for (const checkbox of this._getElementsByName(name, id)) { 15017 const curChecked = checked && checkbox.exportValue === data.exportValue; 15018 if (checkbox.domElement) { 15019 checkbox.domElement.checked = curChecked; 15020 } 15021 storage.setValue(checkbox.id, { 15022 value: curChecked 15023 });
15024 window.updateAngularFormValue(id, { 15025 value: curChecked 15026 }); 15027 } 15028 storage.setValue(id, { 15029 value: checked 15030 }); 15031 window.updateAngularFormValue(id, { 15032 value: checked 15033 }); 15034 }); 15035 element.addEventListener("resetform", event => { 15036 const defaultValue = data.defaultFieldValue || "Off"; 15037 event.target.checked = defaultValue === data.exportValue; 15038 }); 15039 window.registerAcroformField(id, element, value ? data.exportValue : undefined, undefined, data.fieldValue); 15040 element.addEventListener("updateFromAngular", newvalue => storage.setValue(id, { 15041 value: newvalue.detail 15042 })); 15043 if (updateAngularValueNecessary) { 15044 window.updateAngularFormValue(id, { 15045 value 15046 }); 15047 } 15048 if (this.enableScripting && this.hasJSActions) { 15049 element.addEventListener("updatefromsandbox", jsEvent => { 15050 const actions = { 15051 value(event) { 15052 event.target.checked = event.detail.value !== "Off"; 15053 storage.setValue(id, { 15054 value: event.target.checked 15055 }); 15056 window.updateAngularFormValue(id, { 15057 value: event.target.value 15058 }); 15059 } 15060 }; 15061 this._dispatchEventFromSandbox(actions, jsEvent); 15062 }); 15063 this._setEventListeners(element, [["change", "Validate"], ["change", "Action"], ["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked); 15064 } 15065 this._setBackgroundColor(element); 15066 this._setDefaultPropertiesFromJS(element); 15067 this.container.append(element); 15068 return this.container; 15069 } 15070} 15071class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement { 15072 constructor(parameters) { 15073 super(parameters, { 15074 isRenderable: parameters.renderForms 15075 }); 15076 } 15077 render() { 15078 this.container.classList.add("buttonWidgetAnnotation", "radioButton"); 15079 const storage = this.annotationStorage; 15080 const data = this.data; 15081 const id = data.id; 15082 const angularData = window.getFormValueFromAngular(this.data.fieldName); 15083 const formValue = storage.getValue(id, { 15084 value: data.fieldValue === data.buttonValue 15085 }).value; 15086 let value = angularData.value ?? formValue; 15087 if (typeof value === "string" || angularData !== formValue) { 15088 value = value === data.buttonValue; 15089 storage.setValue(id, { 15090 value 15091 }); 15092 } else if (value) { 15093 window.updateAngularFormValue(id, { 15094 value: data.buttonValue 15095 }); 15096 } 15097 const element = document.createElement("input"); 15098 GetElementsByNameSet.add(element); 15099 element.setAttribute("data-element-id", id); 15100 element.disabled = data.readOnly; 15101 this._setRequired(element, this.data.required); 15102 element.type = "radio"; 15103 element.name = data.fieldName; 15104 if (value) { 15105 element.setAttribute("checked", true); 15106 } 15107 element.tabIndex = DEFAULT_TAB_INDEX; 15108 element.addEventListener("change", event => { 15109 const { 15110 name, 15111 checked 15112 } = event.target; 15113 for (const radio of this._getElementsByName(name, id)) { 15114 storage.setValue(radio.id, { 15115 value: false 15116 }); 15117 window.updateAngularFormValue(radio.id, { 15118 value: false 15119 }); 15120 } 15121 storage.setValue(id, { 15122 value: checked 15123 }); 15124 window.updateAngularFormValue(id, { 15125 value: checked 15126 }); 15127 }); 15128 element.addEventListener("resetform", event => { 15129 const defaultValue = data.defaultFieldValue; 15130 event.target.checked = defaultValue !== null && defaultValue !== undefined && defaultValue === data.buttonValue; 15131 }); 15132 window.registerAcroformField(id, element, value ? data.buttonValue : undefined, data.buttonValue); 15133 element.addEventListener("updateFromAngular", newvalue => storage.setValue(id, { 15134 value: newvalue.detail 15135 })); 15136 if (this.enableScripting && this.hasJSActions) { 15137 const pdfButtonValue = data.buttonValue; 15138 element.addEventListener("updatefromsandbox", jsEvent => { 15139 const actions = { 15140 value: event => { 15141 const checked = pdfButtonValue === event.detail.value; 15142 for (const radio of this._getElementsByName(event.target.name)) { 15143 const curChecked = checked && radio.id === id; 15144 if (radio.domElement) { 15145 radio.domElement.checked = curChecked; 15146 } 15147 storage.setValue(radio.id, { 15148 value: curChecked 15149 });
vendor: 10,121 bytes, lines 15150-15427
15150 window.updateAngularFormValue(id, { 15151 value: curChecked 15152 }); 15153 } 15154 } 15155 }; 15156 this._dispatchEventFromSandbox(actions, jsEvent); 15157 }); 15158 this._setEventListeners(element, [["change", "Validate"], ["change", "Action"], ["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked); 15159 } 15160 this._setBackgroundColor(element); 15161 this._setDefaultPropertiesFromJS(element); 15162 this.container.append(element); 15163 return this.container; 15164 } 15165} 15166class PushButtonWidgetAnnotationElement extends LinkAnnotationElement { 15167 constructor(parameters) { 15168 super(parameters, { 15169 ignoreBorder: parameters.data.hasAppearance 15170 }); 15171 } 15172 render() { 15173 const container = super.render(); 15174 container.classList.add("buttonWidgetAnnotation", "pushButton"); 15175 if (this.data.alternativeText) { 15176 container.title = this.data.alternativeText; 15177 } 15178 const linkElement = container.lastChild; 15179 if (this.enableScripting && this.hasJSActions && linkElement) { 15180 this._setDefaultPropertiesFromJS(linkElement); 15181 linkElement.addEventListener("updatefromsandbox", jsEvent => { 15182 this._dispatchEventFromSandbox({}, jsEvent); 15183 }); 15184 } 15185 return container; 15186 } 15187} 15188class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { 15189 constructor(parameters) { 15190 super(parameters, { 15191 isRenderable: parameters.renderForms 15192 }); 15193 } 15194 render() { 15195 this.container.classList.add("choiceWidgetAnnotation"); 15196 const storage = this.annotationStorage; 15197 const id = this.data.id; 15198 const angularData = window.getFormValueFromAngular(this.data.fieldName); 15199 const formData = storage.getValue(id, { 15200 value: this.data.fieldValue 15201 }); 15202 const storedData = angularData.value ? angularData : formData; 15203 if (angularData !== formData) { 15204 storage.setValue(id, { 15205 value: angularData.value 15206 }); 15207 } 15208 const selectElement = document.createElement("select"); 15209 GetElementsByNameSet.add(selectElement); 15210 selectElement.setAttribute("data-element-id", id); 15211 selectElement.disabled = this.data.readOnly; 15212 this._setRequired(selectElement, this.data.required); 15213 selectElement.name = this.data.fieldName; 15214 selectElement.tabIndex = DEFAULT_TAB_INDEX; 15215 let addAnEmptyEntry = this.data.combo && this.data.options.length > 0; 15216 if (!this.data.combo) { 15217 selectElement.size = this.data.options.length; 15218 if (this.data.multiSelect) { 15219 selectElement.multiple = true; 15220 } 15221 } 15222 selectElement.addEventListener("resetform", event => { 15223 const defaultValue = this.data.defaultFieldValue; 15224 for (const option of selectElement.options) { 15225 option.selected = option.value === defaultValue; 15226 } 15227 }); 15228 for (const option of this.data.options) { 15229 const optionElement = document.createElement("option"); 15230 optionElement.textContent = option.displayValue; 15231 optionElement.value = option.exportValue; 15232 if (storedData.value.includes(option.exportValue)) { 15233 optionElement.setAttribute("selected", true); 15234 addAnEmptyEntry = false; 15235 } 15236 selectElement.append(optionElement); 15237 } 15238 let removeEmptyEntry = null; 15239 if (addAnEmptyEntry) { 15240 const noneOptionElement = document.createElement("option"); 15241 noneOptionElement.value = " "; 15242 noneOptionElement.setAttribute("hidden", true); 15243 noneOptionElement.setAttribute("selected", true); 15244 selectElement.prepend(noneOptionElement); 15245 removeEmptyEntry = () => { 15246 noneOptionElement.remove(); 15247 selectElement.removeEventListener("input", removeEmptyEntry); 15248 removeEmptyEntry = null; 15249 }; 15250 selectElement.addEventListener("input", removeEmptyEntry); 15251 } 15252 const getValue = isExport => { 15253 const name = isExport ? "value" : "textContent"; 15254 const { 15255 options, 15256 multiple 15257 } = selectElement; 15258 if (!multiple) { 15259 return options.selectedIndex === -1 ? null : options[options.selectedIndex][name]; 15260 } 15261 return Array.prototype.filter.call(options, option => option.selected).map(option => option[name]); 15262 }; 15263 let selectedValues = getValue(false); 15264 const getItems = event => { 15265 const options = event.target.options; 15266 return Array.prototype.map.call(options, option => { 15267 return { 15268 displayValue: option.textContent, 15269 exportValue: option.value 15270 }; 15271 }); 15272 }; 15273 window.registerAcroformField(id, selectElement, selectedValues); 15274 selectElement.addEventListener("updateFromAngular", newvalue => storage.setValue(id, { 15275 value: newvalue.detail 15276 })); 15277 if (this.enableScripting && this.hasJSActions) { 15278 selectElement.addEventListener("updatefromsandbox", jsEvent => { 15279 const actions = { 15280 value(event) { 15281 removeEmptyEntry?.(); 15282 const value = event.detail.value; 15283 const values = new Set(Array.isArray(value) ? value : [value]); 15284 for (const option of selectElement.options) { 15285 option.selected = values.has(option.value); 15286 } 15287 storage.setValue(id, { 15288 value: getValue(true) 15289 }); 15290 selectedValues = getValue(false); 15291 window.updateAngularFormValue(id, { 15292 value: selectedValues 15293 }); 15294 }, 15295 multipleSelection(event) { 15296 selectElement.multiple = true; 15297 }, 15298 remove(event) { 15299 const options = selectElement.options; 15300 const index = event.detail.remove; 15301 options[index].selected = false; 15302 selectElement.remove(index); 15303 if (options.length > 0) { 15304 const i = Array.prototype.findIndex.call(options, option => option.selected); 15305 if (i === -1) { 15306 options[0].selected = true; 15307 } 15308 } 15309 storage.setValue(id, { 15310 value: getValue(true), 15311 items: getItems(event) 15312 }); 15313 selectedValues = getValue(false); 15314 }, 15315 clear(event) { 15316 while (selectElement.length !== 0) { 15317 selectElement.remove(0); 15318 } 15319 storage.setValue(id, { 15320 value: null, 15321 items: [] 15322 }); 15323 selectedValues = getValue(false); 15324 window.updateAngularFormValue(id, { 15325 value: selectedValues 15326 }); 15327 }, 15328 insert(event) { 15329 const { 15330 index, 15331 displayValue, 15332 exportValue 15333 } = event.detail.insert; 15334 const selectChild = selectElement.children[index]; 15335 const optionElement = document.createElement("option"); 15336 optionElement.textContent = displayValue; 15337 optionElement.value = exportValue; 15338 if (selectChild) { 15339 selectChild.before(optionElement); 15340 } else { 15341 selectElement.append(optionElement); 15342 } 15343 storage.setValue(id, { 15344 value: getValue(true), 15345 items: getItems(event) 15346 }); 15347 selectedValues = getValue(false); 15348 window.updateAngularFormValue(id, { 15349 value: selectedValues 15350 }); 15351 }, 15352 items(event) { 15353 const { 15354 items 15355 } = event.detail; 15356 while (selectElement.length !== 0) { 15357 selectElement.remove(0); 15358 } 15359 for (const item of items) { 15360 const { 15361 displayValue, 15362 exportValue 15363 } = item; 15364 const optionElement = document.createElement("option"); 15365 optionElement.textContent = displayValue; 15366 optionElement.value = exportValue; 15367 selectElement.append(optionElement); 15368 } 15369 if (selectElement.options.length > 0) { 15370 selectElement.options[0].selected = true; 15371 } 15372 storage.setValue(id, { 15373 value: getValue(true), 15374 items: getItems(event) 15375 }); 15376 selectedValues = getValue(false); 15377 window.updateAngularFormValue(id, { 15378 value: selectedValues 15379 }); 15380 }, 15381 indices(event) { 15382 const indices = new Set(event.detail.indices); 15383 for (const option of event.target.options) { 15384 option.selected = indices.has(option.index); 15385 } 15386 storage.setValue(id, { 15387 value: getValue(true) 15388 }); 15389 selectedValues = getValue(false); 15390 window.updateAngularFormValue(id, { 15391 value: selectedValues 15392 }); 15393 }, 15394 editable(event) { 15395 event.target.disabled = !event.detail.editable; 15396 } 15397 }; 15398 this._dispatchEventFromSandbox(actions, jsEvent); 15399 }); 15400 selectElement.addEventListener("input", event => { 15401 const exportValue = getValue(true); 15402 storage.setValue(id, { 15403 value: exportValue 15404 }); 15405 window.updateAngularFormValue(id, { 15406 value: exportValue 15407 }); 15408 event.preventDefault(); 15409 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 15410 source: this, 15411 detail: { 15412 id, 15413 name: "Keystroke", 15414 value: selectedValues, 15415 changeEx: exportValue, 15416 willCommit: false, 15417 commitKey: 1, 15418 keyDown: false 15419 } 15420 }); 15421 }); 15422 this._setEventListeners(selectElement, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"], ["input", "Action"], ["input", "Validate"]], event => event.target.value); 15423 } else { 15424 selectElement.addEventListener("input", function (event) { 15425 storage.setValue(id, { 15426 value: getValue(true) 15427 });
15428 window.updateAngularFormValue(id, { 15429 value: getValue(true) 15430 }); 15431 }); 15432 } 15433 if (this.data.combo) { 15434 this._setTextStyle(selectElement); 15435 } else {} 15436 this._setBackgroundColor(selectElement); 15437 this._setDefaultPropertiesFromJS(selectElement); 15438 this.container.append(selectElement); 15439 return this.container; 15440 } 15441} 15442class PopupAnnotationElement extends AnnotationElement { 15443 constructor(parameters) { 15444 const { 15445 data, 15446 elements 15447 } = parameters; 15448 const isRenderable = !!(data.titleObj?.str || data.contentsObj?.str || data.richText?.str); 15449 super(parameters, { 15450 isRenderable 15451 }); 15452 this.elements = elements; 15453 } 15454 render() { 15455 this.container.classList.add("popupAnnotation"); 15456 const popup = new PopupElement({ 15457 container: this.container, 15458 color: this.data.color, 15459 titleObj: this.data.titleObj, 15460 modificationDate: this.data.modificationDate, 15461 contentsObj: this.data.contentsObj, 15462 richText: this.data.richText, 15463 rect: this.data.rect, 15464 parentRect: this.data.parentRect || null, 15465 parent: this.parent, 15466 elements: this.elements, 15467 open: this.data.open 15468 }); 15469 const elementIds = []; 15470 for (const element of this.elements) { 15471 element.popup = popup; 15472 elementIds.push(element.data.id); 15473 element.addHighlightArea(); 15474 } 15475 this.container.setAttribute("aria-controls", elementIds.join(",")); 15476 return this.container; 15477 } 15478} 15479class PopupElement { 15480 #dateTimePromise = null; 15481 #boundHide = this.#hide.bind(this); 15482 #boundShow = this.#show.bind(this); 15483 #boundToggle = this.#toggle.bind(this); 15484 #color = null; 15485 #container = null; 15486 #contentsObj = null; 15487 #elements = null; 15488 #parent = null; 15489 #parentRect = null; 15490 #pinned = false; 15491 #popup = null; 15492 #rect = null; 15493 #richText = null; 15494 #titleObj = null; 15495 #wasVisible = false; 15496 constructor({ 15497 container, 15498 color, 15499 elements, 15500 titleObj, 15501 modificationDate, 15502 contentsObj, 15503 richText, 15504 parent, 15505 rect, 15506 parentRect, 15507 open 15508 }) { 15509 this.#container = container; 15510 this.#titleObj = titleObj; 15511 this.#contentsObj = contentsObj; 15512 this.#richText = richText; 15513 this.#parent = parent; 15514 this.#color = color; 15515 this.#rect = rect; 15516 this.#parentRect = parentRect; 15517 this.#elements = elements; 15518 const dateObject = _display_utils.PDFDateString.toDateObject(modificationDate); 15519 if (dateObject) { 15520 this.#dateTimePromise = parent.l10n.get("annotation_date_string", { 15521 date: dateObject.toLocaleDateString(), 15522 time: dateObject.toLocaleTimeString() 15523 }); 15524 } 15525 this.trigger = elements.flatMap(e => e.getElementsToTriggerPopup()); 15526 for (const element of this.trigger) { 15527 element.addEventListener("click", this.#boundToggle); 15528 element.addEventListener("mouseenter", this.#boundShow); 15529 element.addEventListener("mouseleave", this.#boundHide); 15530 } 15531 this.#container.hidden = true; 15532 if (open) { 15533 this.#toggle(); 15534 } 15535 } 15536 render() { 15537 if (this.#popup) { 15538 return; 15539 } 15540 const { 15541 page: { 15542 view 15543 }, 15544 viewport: { 15545 rawDims: { 15546 pageWidth, 15547 pageHeight, 15548 pageX, 15549 pageY 15550 } 15551 } 15552 } = this.#parent; 15553 const popup = this.#popup = document.createElement("div"); 15554 popup.className = "popup"; 15555 if (this.#color) { 15556 const baseColor = popup.style.outlineColor = _util.Util.makeHexColor(...this.#color); 15557 if (CSS.supports("background-color", "color-mix(in srgb, red 30%, white)")) { 15558 popup.style.backgroundColor = `color-mix(in srgb, ${baseColor} 30%, white)`; 15559 } else { 15560 const BACKGROUND_ENLIGHT = 0.7; 15561 popup.style.backgroundColor = _util.Util.makeHexColor(...this.#color.map(c => Math.floor(BACKGROUND_ENLIGHT * (255 - c) + c))); 15562 } 15563 } 15564 const header = document.createElement("span"); 15565 header.className = "header"; 15566 const title = document.createElement("h1"); 15567 header.append(title); 15568 ({ 15569 dir: title.dir, 15570 str: title.textContent 15571 } = this.#titleObj); 15572 popup.append(header); 15573 if (this.#dateTimePromise) { 15574 const modificationDate = document.createElement("span"); 15575 modificationDate.classList.add("popupDate"); 15576 this.#dateTimePromise.then(localized => { 15577 modificationDate.textContent = localized; 15578 }); 15579 header.append(modificationDate); 15580 } 15581 const contentsObj = this.#contentsObj; 15582 const richText = this.#richText; 15583 if (richText?.str && (!contentsObj?.str || contentsObj.str === richText.str)) { 15584 _xfa_layer.XfaLayer.render({ 15585 xfaHtml: richText.html, 15586 intent: "richText", 15587 div: popup 15588 }); 15589 popup.lastChild.classList.add("richText", "popupContent"); 15590 } else { 15591 const contents = this._formatContents(contentsObj); 15592 popup.append(contents); 15593 } 15594 let useParentRect = !!this.#parentRect; 15595 let rect = useParentRect ? this.#parentRect : this.#rect; 15596 for (const element of this.#elements) { 15597 if (!rect || _util.Util.intersect(element.data.rect, rect) !== null) { 15598 rect = element.data.rect; 15599 useParentRect = true; 15600 break; 15601 } 15602 } 15603 const normalizedRect = _util.Util.normalizeRect([rect[0], view[3] - rect[1] + view[
156031], rect[2], view[3] - rect[3] + view[1]]); 15604 const HORIZONTAL_SPACE_AFTER_ANNOTATION = 5; 15605 const parentWidth = useParentRect ? rect[2] - rect[0] + HORIZONTAL_SPACE_AFTER_ANNOTATION : 0; 15606 const popupLeft = normalizedRect[0] + parentWidth; 15607 const popupTop = normalizedRect[1]; 15608 const { 15609 style 15610 } = this.#container; 15611 style.left = `${100 * (popupLeft - pageX) / pageWidth}%`; 15612 style.top = `${100 * (popupTop - pageY) / pageHeight}%`; 15613 this.#container.append(popup); 15614 } 15615 _formatContents({ 15616 str, 15617 dir 15618 }) { 15619 const p = document.createElement("p"); 15620 p.classList.add("popupContent"); 15621 p.dir = dir; 15622 const lines = str.split(/(?:\r\n?|\n)/); 15623 for (let i = 0, ii = lines.length; i < ii; ++i) { 15624 const line = lines[i]; 15625 p.append(document.createTextNode(line)); 15626 if (i < ii - 1) { 15627 p.append(document.createElement("br")); 15628 } 15629 } 15630 return p; 15631 } 15632 #toggle() { 15633 this.#pinned = !this.#pinned; 15634 if (this.#pinned) { 15635 this.#show(); 15636 this.#container.addEventListener("click", this.#boundToggle); 15637 } else { 15638 this.#hide(); 15639 this.#container.removeEventListener("click", this.#boundToggle); 15640 } 15641 } 15642 #show() { 15643 if (!this.#popup) { 15644 this.render(); 15645 } 15646 if (!this.isVisible) { 15647 this.#container.hidden = false; 15648 this.#container.style.zIndex = parseInt(this.#container.style.zIndex) + 1000; 15649 } else if (this.#pinned) { 15650 this.#container.classList.add("focused"); 15651 } 15652 } 15653 #hide() { 15654 this.#container.classList.remove("focused"); 15655 if (this.#pinned || !this.isVisible) { 15656 return; 15657 } 15658 this.#container.hidden = true; 15659 this.#container.style.zIndex = parseInt(this.#container.style.zIndex) - 1000; 15660 } 15661 forceHide() { 15662 this.#wasVisible = this.isVisible; 15663 if (!this.#wasVisible) { 15664 return; 15665 } 15666 this.#container.hidden = true; 15667 } 15668 maybeShow() { 15669 if (!this.#wasVisible) { 15670 return; 15671 } 15672 this.#wasVisible = false; 15673 this.#container.hidden = false; 15674 } 15675 get isVisible() { 15676 return this.#container.hidden === false; 15677 } 15678} 15679class FreeTextAnnotationElement extends AnnotationElement { 15680 constructor(parameters) { 15681 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15682 super(parameters, { 15683 isRenderable, 15684 ignoreBorder: true 15685 }); 15686 this.textContent = parameters.data.textContent; 15687 this.textPosition = parameters.data.textPosition; 15688 this.annotationEditorType = _util.AnnotationEditorType.FREETEXT; 15689 } 15690 render() { 15691 this.container.classList.add("freeTextAnnotation"); 15692 if (this.textContent) { 15693 const content = document.createElement("div"); 15694 content.classList.add("annotationTextContent"); 15695 content.setAttribute("role", "comment"); 15696 for (const line of this.textContent) { 15697 const lineSpan = document.createElement("span"); 15698 lineSpan.textContent = line; 15699 content.append(lineSpan); 15700 } 15701 this.container.append(content); 15702 } 15703 if (!this.data.popupRef) { 15704 this._createPopup(); 15705 } 15706 this._editOnDoubleClick(); 15707 return this.container; 15708 } 15709} 15710exports.FreeTextAnnotationElement = FreeTextAnnotationElement; 15711class LineAnnotationElement extends AnnotationElement { 15712 #line = null; 15713 constructor(parameters) { 15714 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15715 super(parameters, { 15716 isRenderable, 15717 ignoreBorder: true 15718 }); 15719 } 15720 render() { 15721 this.container.classList.add("lineAnnotation"); 15722 const data = this.data; 15723 const { 15724 width, 15725 height 15726 } = getRectDims(data.rect); 15727 const svg = this.svgFactory.create(width, height, true); 15728 const line = this.#line = this.svgFactory.createElement("svg:line"); 15729 line.setAttribute("x1", data.rect[2] - data.lineCoordinates[0]); 15730 line.setAttribute("y1", data.rect[3] - data.lineCoordinates[1]); 15731 line.setAttribute("x2", data.rect[2] - data.lineCoordinates[2]); 15732 line.setAttribute("y2", data.rect[3] - data.lineCoordinates[3]); 15733 line.setAttribute("stroke-width", data.borderStyle.width || 1); 15734 line.setAttribute("stroke", "transparent"); 15735 line.setAttribute("fill", "transparent"); 15736 svg.append(line); 15737 this.container.append(svg); 15738 if (!data.popupRef) { 15739 this._createPopup(); 15740 } 15741 return this.container; 15742 } 15743 getElementsToTriggerPopup() { 15744 return this.#line; 15745 } 15746 addHighlightArea() { 15747 this.container.classList.add("highlightArea"); 15748 } 15749} 15750class SquareAnnotationElement extends AnnotationElement { 15751 #square = null; 15752 constructor(parameters) { 15753 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15754 super(parameters, { 15755 isRenderable, 15756 ignoreBorder: true 15757 }); 15758 } 15759 render() { 15760 this.container.classList.add("squareAnnotation"); 15761 const data = this.data; 15762 const { 15763 width, 15764 height 15765 } = getRectDims(data.rect); 15766 const svg = this.svgFactory.create(width, height, true); 15767 const borderWidth = data.borderStyle.width; 15768 const square = this.#square = this.svgFactory.createElement("svg:rect"); 15769 square.setAttribute("x", borderWidth / 2); 15770 square.setAttribute("y", borderWidth / 2); 15771 square.setAttribute("width", width - borderWidth); 15772 square.setAttribute("height", height - borderWidth); 15773 square.setAttribute("stroke-width", borderWidth || 1); 15774 square.setAttribute("stroke", "transparent"); 15775 square.setAttribute("fill", "transparent"); 15776 svg.append(square); 15777 this.container.append(svg); 15778 if (!data.popupRef) { 15779 this._createPopup(); 15780 } 15781 return this.container; 15782 } 15783 getElementsToTriggerPopup() { 15784 return this.#square; 15785 } 15786 addHighlightArea() { 15787 this.container.classList.add("highlightArea"); 15788 } 15789} 15790class CircleAnnotationElement extends AnnotationElement { 15791 #circle = null; 15792 constructor(parameters) { 15793 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15794 super(parameters, { 15795 isRenderable, 15796 ignoreBorder: true 15797 }); 15798 } 15799 render() { 15800 this.container.classList.add("circleAnnotation"); 15801 const data = this.data; 15802 const { 15803 width, 15804 height 15805 } = getRectDims(data.rect); 15806 const svg = this.svgFactory.create(width, height, true); 15807 const borderWidth = data.borderStyle.width; 15808 const circle = this.#circle = this.svgFactory.createElement("svg:ellipse"); 15809 circle.setAttribute("cx", width / 2); 15810 circle.setAttribute("cy", height / 2); 15811 circle.setAttribute("rx", width / 2 - borderWidth / 2); 15812 circle.setAttribute("ry", height / 2 - borderWidth / 2); 15813 circle.setAttribute("stroke-width", borderWidth || 1); 15814 circle.setAttribute("stroke", "transparent"); 15815 circle.setAttribute("fill", "transparent"); 15816 svg.append(circle); 15817 this.container.append(svg); 15818 if (!data.popupRef) { 15819 this._createPopup(); 15820 } 15821 return this.container; 15822 } 15823 getElementsToTriggerPopup() { 15824 return this.#circle; 15825 } 15826 addHighlightArea() { 15827 this.container.classList.add("highlightArea"); 15828 } 15829} 15830class PolylineAnnotationElement extends AnnotationElement { 15831 #polyline = null; 15832 constructor(parameters) { 15833 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15834 super(parameters, { 15835 isRenderable, 15836 ignoreBorder: true 15837 }); 15838 this.containerClassName = "polylineAnnotation"; 15839 this.svgElementName = "svg:polyline"; 15840 } 15841 render() { 15842 this.container.classList.add(this.containerClassName); 15843 const data = this.data; 15844 const { 15845 width, 15846 height 15847 } = getRectDims(data.rect); 15848 const svg = this.svgFactory.create(width, height, true); 15849 let points = []; 15850 for (const coordinate of data.vertices) { 15851 const x = coordinate.x - data.rect[0];
15852 const y = data.rect[3] - coordinate.y; 15853 points.push(x + "," + y); 15854 } 15855 points = points.join(" "); 15856 const polyline = this.#polyline = this.svgFactory.createElement(this.svgElementName); 15857 polyline.setAttribute("points", points); 15858 polyline.setAttribute("stroke-width", data.borderStyle.width || 1); 15859 polyline.setAttribute("stroke", "transparent"); 15860 polyline.setAttribute("fill", "transparent"); 15861 svg.append(polyline); 15862 this.container.append(svg); 15863 if (!data.popupRef) { 15864 this._createPopup(polyline, data); 15865 } 15866 return this.container; 15867 } 15868 getElementsToTriggerPopup() { 15869 return this.#polyline; 15870 } 15871 addHighlightArea() { 15872 this.container.classList.add("highlightArea"); 15873 } 15874} 15875class PolygonAnnotationElement extends PolylineAnnotationElement { 15876 constructor(parameters) { 15877 super(parameters); 15878 this.containerClassName = "polygonAnnotation"; 15879 this.svgElementName = "svg:polygon"; 15880 } 15881} 15882class CaretAnnotationElement extends AnnotationElement { 15883 constructor(parameters) { 15884 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15885 super(parameters, { 15886 isRenderable, 15887 ignoreBorder: true 15888 }); 15889 } 15890 render() { 15891 this.container.classList.add("caretAnnotation"); 15892 if (!this.data.popupRef) { 15893 this._createPopup(); 15894 } 15895 return this.container; 15896 } 15897} 15898class InkAnnotationElement extends AnnotationElement { 15899 #polylines = []; 15900 constructor(parameters) { 15901 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15902 super(parameters, { 15903 isRenderable, 15904 ignoreBorder: true 15905 }); 15906 this.containerClassName = "inkAnnotation"; 15907 this.svgElementName = "svg:polyline"; 15908 this.annotationEditorType = _util.AnnotationEditorType.INK; 15909 } 15910 render() { 15911 this.container.classList.add(this.containerClassName); 15912 const data = this.data; 15913 const { 15914 width, 15915 height 15916 } = getRectDims(data.rect); 15917 const svg = this.svgFactory.create(width, height, true); 15918 for (const inkList of data.inkLists) { 15919 let points = []; 15920 for (const coordinate of inkList) { 15921 const x = coordinate.x - data.rect[0]; 15922 const y = data.rect[3] - coordinate.y; 15923 points.push(`${x},${y}`); 15924 } 15925 points = points.join(" "); 15926 const polyline = this.svgFactory.createElement(this.svgElementName); 15927 this.#polylines.push(polyline); 15928 polyline.setAttribute("points", points); 15929 polyline.setAttribute("stroke-width", data.borderStyle.width || 1); 15930 polyline.setAttribute("stroke", "transparent"); 15931 polyline.setAttribute("fill", "transparent"); 15932 if (!data.popupRef) { 15933 this._createPopup(polyline, data); 15934 } 15935 svg.append(polyline); 15936 } 15937 this.container.append(svg); 15938 return this.container; 15939 } 15940 getElementsToTriggerPopup() { 15941 return this.#polylines; 15942 } 15943 addHighlightArea() { 15944 this.container.classList.add("highlightArea"); 15945 } 15946} 15947exports.InkAnnotationElement = InkAnnotationElement; 15948class HighlightAnnotationElement extends AnnotationElement { 15949 constructor(parameters) { 15950 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15951 super(parameters, { 15952 isRenderable, 15953 ignoreBorder: true, 15954 createQuadrilaterals: true 15955 }); 15956 } 15957 render() { 15958 if (!this.data.popupRef) { 15959 this._createPopup(); 15960 } 15961 this.container.classList.add("highlightAnnotation"); 15962 return this.container; 15963 } 15964} 15965class UnderlineAnnotationElement extends AnnotationElement { 15966 constructor(parameters) { 15967 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15968 super(parameters, { 15969 isRenderable, 15970 ignoreBorder: true, 15971 createQuadrilaterals: true 15972 }); 15973 } 15974 render() { 15975 if (!this.data.popupRef) { 15976 this._createPopup(); 15977 } 15978 this.container.classList.add("underlineAnnotation"); 15979 return this.container; 15980 } 15981} 15982class SquigglyAnnotationElement extends AnnotationElement { 15983 constructor(parameters) { 15984 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15985 super(parameters, { 15986 isRenderable, 15987 ignoreBorder: true, 15988 createQuadrilaterals: true 15989 }); 15990 } 15991 render() { 15992 if (!this.data.popupRef) { 15993 this._createPopup(); 15994 } 15995 this.container.classList.add("squigglyAnnotation"); 15996 return this.container; 15997 } 15998} 15999class StrikeOutAnnotationElement extends AnnotationElement { 16000 constructor(parameters) { 16001 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 16002 super(parameters, { 16003 isRenderable, 16004 ignoreBorder: true, 16005 createQuadrilaterals: true 16006 }); 16007 } 16008 render() { 16009 if (!this.data.popupRef) { 16010 this._createPopup(); 16011 }
16012 this.container.classList.add("strikeoutAnnotation"); 16013 return this.container; 16014 } 16015} 16016class StampAnnotationElement extends AnnotationElement { 16017 constructor(parameters) { 16018 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 16019 super(parameters, { 16020 isRenderable, 16021 ignoreBorder: true 16022 }); 16023 } 16024 render() { 16025 this.container.classList.add("stampAnnotation"); 16026 if (!this.data.popupRef) { 16027 this._createPopup(); 16028 } 16029 return this.container; 16030 } 16031} 16032exports.StampAnnotationElement = StampAnnotationElement; 16033class FileAttachmentAnnotationElement extends AnnotationElement { 16034 #trigger = null; 16035 constructor(parameters) { 16036 super(parameters, { 16037 isRenderable: true 16038 }); 16039 const { 16040 filename, 16041 content 16042 } = this.data.file; 16043 this.filename = (0, _display_utils.getFilenameFromUrl)(filename, true); 16044 this.content = content; 16045 this.linkService.eventBus?.dispatch("fileattachmentannotation", { 16046 source: this, 16047 filename, 16048 content 16049 }); 16050 } 16051 render() { 16052 this.container.classList.add("fileAttachmentAnnotation"); 16053 const { 16054 data 16055 } = this; 16056 let trigger; 16057 if (data.hasAppearance || data.fillAlpha === 0) { 16058 trigger = document.createElement("div"); 16059 } else { 16060 trigger = document.createElement("img"); 16061 trigger.src = `${this.imageResourcesPath}annotation-${/paperclip/i.test(data.name) ? "paperclip" : "pushpin"}.svg`; 16062 if (data.fillAlpha && data.fillAlpha < 1) { 16063 trigger.style = `filter: opacity(${Math.round(data.fillAlpha * 100)}%);`; 16064 } 16065 } 16066 trigger.classList.add("popupTriggerArea"); 16067 trigger.addEventListener("dblclick", this._download.bind(this)); 16068 this.#trigger = trigger; 16069 if (!data.popupRef && (data.titleObj?.str || data.contentsObj?.str || data.richText)) { 16070 this._createPopup(); 16071 } 16072 this.container.append(trigger); 16073 return this.container; 16074 } 16075 getElementsToTriggerPopup() { 16076 return this.#trigger; 16077 } 16078 addHighlightArea() { 16079 this.container.classList.add("highlightArea"); 16080 } 16081 _download() { 16082 this.downloadManager?.openOrDownloadData(this.container, this.content, this.filename); 16083 } 16084} 16085class AnnotationLayer { 16086 #accessibilityManager = null; 16087 #annotationCanvasMap = null; 16088 #editableAnnotations = new Map(); 16089 constructor({ 16090 div, 16091 accessibilityManager, 16092 annotationCanvasMap, 16093 l10n, 16094 page, 16095 viewport 16096 }) { 16097 this.div = div; 16098 this.#accessibilityManager = accessibilityManager; 16099 this.#annotationCanvasMap = annotationCanvasMap; 16100 this.l10n = l10n; 16101 this.page = page; 16102 this.viewport = viewport; 16103 this.zIndex = 0; 16104 this.l10n ||= _displayL10n_utils.NullL10n; 16105 } 16106 #appendElement(element, id) { 16107 const contentElement = element.firstChild || element; 16108 contentElement.id = `${_display_utils.AnnotationPrefix}${id}`; 16109 this.div.append(element); 16110 this.#accessibilityManager?.moveElementInDOM(this.div, element, contentElement, false); 16111 } 16112 async render(params) { 16113 const { 16114 annotations 16115 } = params; 16116 const layer = this.div; 16117 (0, _display_utils.setLayerDimensions)(layer, this.viewport); 16118 const popupToElements = new Map();
16119 const elementParams = { 16120 data: null, 16121 layer, 16122 linkService: params.linkService, 16123 downloadManager: params.downloadManager, 16124 imageResourcesPath: params.imageResourcesPath || "", 16125 renderForms: params.renderForms !== false, 16126 svgFactory: new _display_utils.DOMSVGFactory(), 16127 annotationStorage: params.annotationStorage || new _annotation_storage.AnnotationStorage(), 16128 enableScripting: params.enableScripting === true, 16129 hasJSActions: params.hasJSActions, 16130 fieldObjects: params.fieldObjects, 16131 parent: this, 16132 elements: null 16133 }; 16134 for (const data of annotations) { 16135 if (data.noHTML) { 16136 continue; 16137 } 16138 const isPopupAnnotation = data.annotationType === _util.AnnotationType.POPUP; 16139 if (!isPopupAnnotation) { 16140 const { 16141 width, 16142 height 16143 } = getRectDims(data.rect); 16144 if (width <= 0 || height <= 0) { 16145 continue; 16146 } 16147 } else { 16148 const elements = popupToElements.get(data.id); 16149 if (!elements) { 16150 continue; 16151 }
vendor: 6,252 bytes, lines 16152-16344
16152 elementParams.elements = elements; 16153 } 16154 elementParams.data = data; 16155 const element = AnnotationElementFactory.create(elementParams); 16156 if (!element.isRenderable) { 16157 continue; 16158 } 16159 if (!isPopupAnnotation && data.popupRef) { 16160 const elements = popupToElements.get(data.popupRef); 16161 if (!elements) { 16162 popupToElements.set(data.popupRef, [element]); 16163 } else { 16164 elements.push(element); 16165 } 16166 } 16167 if (element.annotationEditorType > 0) { 16168 this.#editableAnnotations.set(element.data.id, element); 16169 } 16170 const rendered = element.render(); 16171 if (data.hidden) { 16172 rendered.style.visibility = "hidden"; 16173 } 16174 this.#appendElement(rendered, data.id); 16175 } 16176 this.#setAnnotationCanvasMap(); 16177 await this.l10n.translate(layer); 16178 } 16179 update({ 16180 viewport 16181 }) { 16182 const layer = this.div; 16183 this.viewport = viewport; 16184 (0, _display_utils.setLayerDimensions)(layer, { 16185 rotation: viewport.rotation 16186 }); 16187 this.#setAnnotationCanvasMap(); 16188 layer.hidden = false; 16189 } 16190 #setAnnotationCanvasMap() { 16191 if (!this.#annotationCanvasMap) { 16192 return; 16193 } 16194 const layer = this.div; 16195 for (const [id, canvas] of this.#annotationCanvasMap) { 16196 const element = layer.querySelector(`[data-annotation-id="${id}"]`); 16197 if (!element) { 16198 continue; 16199 } 16200 const { 16201 firstChild 16202 } = element; 16203 if (!firstChild) { 16204 element.append(canvas); 16205 } else if (firstChild.nodeName === "CANVAS") { 16206 firstChild.replaceWith(canvas); 16207 } else { 16208 firstChild.before(canvas); 16209 } 16210 } 16211 this.#annotationCanvasMap.clear(); 16212 } 16213 getEditableAnnotations() { 16214 return Array.from(this.#editableAnnotations.values()); 16215 } 16216 getEditableAnnotation(id) { 16217 return this.#editableAnnotations.get(id); 16218 } 16219} 16220exports.AnnotationLayer = AnnotationLayer; 16221 16222/***/ }), 16223/* 30 */ 16224/***/ ((__unused_webpack_module, exports) => { 16225 16226 16227 16228Object.defineProperty(exports, "__esModule", ({ 16229 value: true 16230})); 16231exports.ColorConverters = void 0; 16232function makeColorComp(n) { 16233 return Math.floor(Math.max(0, Math.min(1, n)) * 255).toString(16).padStart(2, "0"); 16234} 16235function scaleAndClamp(x) { 16236 return Math.max(0, Math.min(255, 255 * x)); 16237} 16238class ColorConverters { 16239 static CMYK_G([c, y, m, k]) { 16240 return ["G", 1 - Math.min(1, 0.3 * c + 0.59 * m + 0.11 * y + k)]; 16241 } 16242 static G_CMYK([g]) { 16243 return ["CMYK", 0, 0, 0, 1 - g]; 16244 } 16245 static G_RGB([g]) { 16246 return ["RGB", g, g, g]; 16247 } 16248 static G_rgb([g]) { 16249 g = scaleAndClamp(g); 16250 return [g, g, g]; 16251 } 16252 static G_HTML([g]) { 16253 const G = makeColorComp(g); 16254 return `#${G}${G}${G}`; 16255 } 16256 static RGB_G([r, g, b]) { 16257 return ["G", 0.3 * r + 0.59 * g + 0.11 * b]; 16258 } 16259 static RGB_rgb(color) { 16260 return color.map(scaleAndClamp); 16261 } 16262 static RGB_HTML(color) { 16263 return `#${color.map(makeColorComp).join("")}`; 16264 } 16265 static T_HTML() { 16266 return "#00000000"; 16267 } 16268 static T_rgb() { 16269 return [null]; 16270 } 16271 static CMYK_RGB([c, y, m, k]) { 16272 return ["RGB", 1 - Math.min(1, c + k), 1 - Math.min(1, m + k), 1 - Math.min(1, y + k)]; 16273 } 16274 static CMYK_rgb([c, y, m, k]) { 16275 return [scaleAndClamp(1 - Math.min(1, c + k)), scaleAndClamp(1 - Math.min(1, m + k)), scaleAndClamp(1 - Math.min(1, y + k))]; 16276 } 16277 static CMYK_HTML(components) { 16278 const rgb = this.CMYK_RGB(components).slice(1); 16279 return this.RGB_HTML(rgb); 16280 } 16281 static RGB_CMYK([r, g, b]) { 16282 const c = 1 - r; 16283 const m = 1 - g; 16284 const y = 1 - b; 16285 const k = Math.min(c, m, y); 16286 return ["CMYK", c, m, y, k]; 16287 } 16288} 16289exports.ColorConverters = ColorConverters; 16290 16291/***/ }), 16292/* 31 */ 16293/***/ ((__unused_webpack_module, exports) => { 16294 16295 16296 16297Object.defineProperty(exports, "__esModule", ({ 16298 value: true 16299})); 16300exports.NullL10n = void 0; 16301exports.getL10nFallback = getL10nFallback; 16302const DEFAULT_L10N_STRINGS = { 16303 of_pages: "of {{pagesCount}}", 16304 page_of_pages: "({{pageNumber}} of {{pagesCount}})", 16305 document_properties_kb: "{{size_kb}} KB ({{size_b}} bytes)", 16306 document_properties_mb: "{{size_mb}} MB ({{size_b}} bytes)", 16307 document_properties_date_string: "{{date}}, {{time}}", 16308 document_properties_page_size_unit_inches: "in", 16309 document_properties_page_size_unit_millimeters: "mm", 16310 document_properties_page_size_orientation_portrait: "portrait", 16311 document_properties_page_size_orientation_landscape: "landscape", 16312 document_properties_page_size_name_a3: "A3", 16313 document_properties_page_size_name_a4: "A4", 16314 document_properties_page_size_name_letter: "Letter", 16315 document_properties_page_size_name_legal: "Legal", 16316 document_properties_page_size_dimension_string: "{{width}} × {{height}} {{unit}} ({{orientation}})", 16317 document_properties_page_size_dimension_name_string: "{{width}} × {{height}} {{unit}} ({{name}}, {{orientation}})", 16318 document_properties_linearized_yes: "Yes", 16319 document_properties_linearized_no: "No", 16320 additional_layers: "Additional Layers", 16321 page_landmark: "Page {{page}}", 16322 thumb_page_title: "Page {{page}}", 16323 thumb_page_canvas: "Thumbnail of Page {{page}}", 16324 find_reached_top: "Reached top of document, continued from bottom", 16325 find_reached_bottom: "Reached end of document, continued from top", 16326 "find_match_count[one]": "{{current}} of {{total}} match", 16327 "find_match_count[other]": "{{current}} of {{total}} matches", 16328 "find_match_count_limit[one]": "More than {{limit}} match", 16329 "find_match_count_limit[other]": "More than {{limit}} matches", 16330 find_not_found: "Phrase not found", 16331 page_scale_width: "Page Width", 16332 page_scale_fit: "Page Fit", 16333 page_scale_auto: "Automatic Zoom", 16334 page_scale_actual: "Actual Size", 16335 page_scale_percent: "{{scale}}%", 16336 loading_error: "An error occurred while loading the PDF.", 16337 invalid_file_error: "Invalid or corrupted PDF file.", 16338 missing_file_error: "Missing PDF file.", 16339 unexpected_response_error: "Unexpected server response.", 16340 rendering_error: "An error occurred while rendering the page.", 16341 annotation_date_string: "{{date}}, {{time}}", 16342 printing_not_supported: "Warning: Printing is not fully supported by this browser.", 16343 printing_not_ready: "Warning: The PDF is not fully loaded for printing.", 16344 web_fonts_disabled: "Web fonts are disabled: unable to use embedded PDF fonts.",
16345 free_text2_default_content: "Start typing…", 16346 editor_free_text2_aria_label: "Text Editor", 16347 editor_ink2_aria_label: "Draw Editor", 16348 editor_ink_canvas_aria_label: "User-created image" 16349}; 16350{ 16351 DEFAULT_L10N_STRINGS.print_progress_percent = "{{progress}}%"; 16352} 16353function getL10nFallback(key, args) { 16354 switch (key) { 16355 case "find_match_count": 16356 key = `find_match_count[${args.total === 1 ? "one" : "other"}]`; 16357 break; 16358 case "find_match_count_limit": 16359 key = `find_match_count_limit[${args.limit === 1 ? "one" : "other"}]`; 16360 break; 16361 } 16362 return DEFAULT_L10N_STRINGS[key] || ""; 16363} 16364function formatL10nValue(text, args) { 16365 if (!args) { 16366 return text; 16367 } 16368 return text.replaceAll(/\{\{\s*(\w+)\s*\}\}/g, (all, name) => { 16369 return name in args ? args[name] : "{{" + name + "}}"; 16370 }); 16371} 16372const NullL10n = exports.NullL10n = { 16373 async getLanguage() { 16374 return "en-us"; 16375 }, 16376 async getDirection() { 16377 return "ltr"; 16378 }, 16379 async get(key, args = null, fallback = getL10nFallback(key, args)) { 16380 return formatL10nValue(fallback, args); 16381 }, 16382 async translate(element) {} 16383}; 16384 16385/***/ }), 16386/* 32 */ 16387/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 16388 16389 16390 16391Object.defineProperty(exports, "__esModule", ({ 16392 value: true 16393})); 16394exports.XfaLayer = void 0; 16395var _xfa_text = __w_pdfjs_require__(25); 16396class XfaLayer { 16397 static setupStorage(html, id, element, storage, intent) { 16398 const angularData = window.getFormValueFromAngular(html); 16399 if (angularData.value) { 16400 storage.setValue(id, angularData); 16401 } 16402 const storedData = angularData.value ? angularData : storage.getValue(id, { 16403 value: null 16404 }); 16405 window.registerXFAField(html, storedData); 16406 html.addEventListener("updateFromAngular", value => storage.setValue(id, { 16407 value: value.detail 16408 })); 16409 switch (element.name) { 16410 case "textarea": 16411 if (storedData.value !== null) { 16412 html.textContent = storedData.value; 16413 } 16414 if (intent === "print") { 16415 break; 16416 } 16417 html.addEventListener("input", event => { 16418 window.updateAngularFormValue(html, { 16419 value: event.target.value 16420 }); 16421 storage.setValue(id, { 16422 value: event.target.value 16423 }); 16424 }); 16425 break; 16426 case "input": 16427 if (element.attributes.type === "radio" || element.attributes.type === "checkbox") { 16428 if (storedData.value === element.attributes.xfaOn) { 16429 html.setAttribute("checked", true); 16430 } else { 16431 html.removeAttribute("checked"); 16432 } 16433 if (intent === "print") { 16434 break; 16435 } 16436 html.addEventListener("change", event => { 16437 window.updateAngularFormValue(html, { 16438 value: event.target.checked ? event.target.getAttribute("xfaOn") : event.target.getAttribute("xfaOff") 16439 }); 16440 storage.setValue(id, { 16441 value: event.target.checked ? event.target.getAttribute("xfaOn") : event.target.getAttribute("xfaOff") 16442 }); 16443 }); 16444 } else { 16445 if (storedData.value !== null) { 16446 html.setAttribute("value", storedData.value); 16447 } 16448 if (intent === "print") { 16449 break; 16450 } 16451 html.addEventListener("input", event => { 16452 window.updateAngularFormValue(html, { 16453 value: event.target.value 16454 }); 16455 storage.setValue(id, { 16456 value: event.target.value 16457 }); 16458 }); 16459 } 16460 break; 16461 case "select": 16462 if (storedData.value !== null) { 16463 html.setAttribute("value", storedData.value); 16464 for (const option of element.children) { 16465 if (option.attributes.value === storedData.value) { 16466 option.attributes.selected = true; 16467 } else if (option.attributes.hasOwnProperty("selected")) { 16468 delete option.attributes.selected; 16469 } 16470 } 16471 } 16472 html.addEventListener("input", event => { 16473 const options = event.target.options; 16474 const value = options.selectedIndex === -1 ? "" : options[options.selectedIndex].value;
16475 window.updateAngularFormValue(html, { 16476 value 16477 }); 16478 storage.setValue(id, { 16479 value 16480 }); 16481 }); 16482 break; 16483 } 16484 } 16485 static setAttributes({ 16486 html, 16487 element, 16488 storage = null, 16489 intent, 16490 linkService 16491 }) { 16492 const { 16493 attributes 16494 } = element; 16495 const isHTMLAnchorElement = html instanceof HTMLAnchorElement; 16496 if (attributes.type === "radio") { 16497 attributes.name = `${attributes.name}-${intent}`; 16498 } 16499 for (const [key, value] of Object.entries(attributes)) { 16500 if (value === null || value === undefined) { 16501 continue; 16502 } 16503 switch (key) { 16504 case "class": 16505 if (value.length) { 16506 html.setAttribute(key, value.join(" ")); 16507 } 16508 break; 16509 case "dataId": 16510 break; 16511 case "id": 16512 html.setAttribute("data-element-id", value); 16513 break; 16514 case "style": 16515 Object.assign(html.style, value); 16516 break; 16517 case "textContent": 16518 html.textContent = value; 16519 break; 16520 default: 16521 if (!isHTMLAnchorElement || key !== "href" && key !== "newWindow") { 16522 html.setAttribute(key, value); 16523 } 16524 } 16525 } 16526 if (isHTMLAnchorElement) { 16527 linkService.addLinkAttributes(html, attributes.href, attributes.newWindow); 16528 } 16529 if (storage && attributes.dataId) { 16530 this.setupStorage(html, attributes.dataId, element, storage); 16531 } 16532 } 16533 static render(parameters) { 16534 const storage = parameters.annotationStorage; 16535 const linkService = parameters.linkService; 16536 const root = parameters.xfaHtml; 16537 const intent = parameters.intent || "display"; 16538 const rootHtml = document.createElement(root.name); 16539 if (root.attributes) { 16540 this.setAttributes({ 16541 html: rootHtml, 16542 element: root, 16543 intent, 16544 linkService 16545 }); 16546 } 16547 const stack = [[root, -1, rootHtml]]; 16548 const rootDiv = parameters.div; 16549 rootDiv.append(rootHtml); 16550 if (parameters.viewport) { 16551 const transform = `matrix(${parameters.viewport.transform.join(",")})`; 16552 rootDiv.style.transform = transform; 16553 } 16554 if (intent !== "richText") { 16555 rootDiv.setAttribute("class", "xfaLayer xfaFont"); 16556 } 16557 const textDivs = []; 16558 while (stack.length > 0) { 16559 const [parent, i, html] = stack.at(-1); 16560 if (i + 1 === parent.children.length) { 16561 stack.pop(); 16562 continue; 16563 } 16564 const child = parent.children[++stack.at(-1)[1]]; 16565 if (child === null) { 16566 continue; 16567 } 16568 const { 16569 name 16570 } = child; 16571 if (name === "#text") { 16572 const node = document.createTextNode(child.value); 16573 textDivs.push(node); 16574 html.append(node); 16575 continue; 16576 } 16577 const childHtml = child?.attributes?.xmlns ? document.createElementNS(child.attributes.xmlns, name) : document.createElement(name); 16578 html.append(childHtml); 16579 if (child.attributes) { 16580 this.setAttributes({ 16581 html: childHtml, 16582 element: child, 16583 storage, 16584 intent, 16585 linkService 16586 }); 16587 } 16588 if (child.children && child.children.length > 0) { 16589 stack.push([child, -1, childHtml]); 16590 } else if (child.value) { 16591 const node = document.createTextNode(child.value); 16592 if (_xfa_text.XfaText.shouldBuildText(name)) { 16593 textDivs.push(node); 16594 } 16595 childHtml.append(node); 16596 } 16597 } 16598 for (const el of rootDiv.querySelectorAll(".xfaNonInteractive input, .xfaNonInteractive textarea")) { 16599 el.setAttribute("readOnly", true); 16600 } 16601 return { 16602 textDivs 16603 }; 16604 } 16605 static update(parameters) { 16606 const transform = `matrix(${parameters.viewport.transform.join(",")})`; 16607 parameters.div.style.transform = transform; 16608 parameters.div.hidden = false; 16609 } 16610} 16611exports.XfaLayer = XfaLayer; 16612 16613/***/ }), 16614/* 33 */ 16615/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 16616 16617 16618 16619Object.defineProperty(exports, "__esModule", ({ 16620 value: true 16621})); 16622exports.InkEditor = void 0; 16623var _util = __w_pdfjs_require__(1); 16624var _editor = __w_pdfjs_require__(4); 16625var _annotation_layer = __w_pdfjs_require__(29); 16626var _tools = __w_pdfjs_require__(5); 16627class InkEditor extends _editor.AnnotationEditor { 16628 #baseHeight = 0;
16629 #baseWidth = 0; 16630 #boundCanvasContextMenu = this.canvasContextMenu.bind(this); 16631 #boundCanvasPointermove = this.canvasPointermove.bind(this); 16632 #boundCanvasPointerleave = this.canvasPointerleave.bind(this); 16633 #boundCanvasPointerup = this.canvasPointerup.bind(this); 16634 #boundCanvasPointerdown = this.canvasPointerdown.bind(this); 16635 #currentPath2D = new Path2D(); 16636 #disableEditing = false; 16637 #hasSomethingToDraw = false; 16638 #isCanvasInitialized = false; 16639 #observer = null; 16640 #realWidth = 0; 16641 #realHeight = 0; 16642 #requestFrameCallback = null; 16643 static _defaultColor = null; 16644 static _defaultOpacity = 1; 16645 static _defaultThickness = 1; 16646 static _l10nPromise; 16647 static _type = "ink"; 16648 constructor(params) { 16649 super({ 16650 ...params, 16651 name: "inkEditor" 16652 }); 16653 this.color = params.color || null; 16654 this.thickness = params.thickness || null; 16655 this.opacity = params.opacity || null; 16656 this.paths = []; 16657 this.bezierPath2D = []; 16658 this.allRawPaths = []; 16659 this.currentPath = []; 16660 this.scaleFactor = 1; 16661 this.translationX = this.translationY = 0; 16662 this.x = 0; 16663 this.y = 0; 16664 this._willKeepAspectRatio = true; 16665 } 16666 static initialize(l10n) { 16667 this._l10nPromise = new Map(["editor_ink_canvas_aria_label", "editor_ink2_aria_label"].map(str => [str, l10n.get(str)])); 16668 } 16669 static updateDefaultParams(type, value) { 16670 switch (type) { 16671 case _util.AnnotationEditorParamsType.INK_THICKNESS: 16672 InkEditor._defaultThickness = value; 16673 break; 16674 case _util.AnnotationEditorParamsType.INK_COLOR: 16675 InkEditor._defaultColor = value; 16676 break; 16677 case _util.AnnotationEditorParamsType.INK_OPACITY: 16678 InkEditor._defaultOpacity = value / 100; 16679 break; 16680 } 16681 } 16682 updateParams(type, value) { 16683 switch (type) { 16684 case _util.AnnotationEditorParamsType.INK_THICKNESS: 16685 this.#updateThickness(value); 16686 break; 16687 case _util.AnnotationEditorParamsType.INK_COLOR: 16688 this.#updateColor(value); 16689 break; 16690 case _util.AnnotationEditorParamsType.INK_OPACITY: 16691 this.#updateOpacity(value); 16692 break; 16693 } 16694 } 16695 static get defaultPropertiesToUpdate() { 16696 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)]]; 16697 } 16698 get propertiesToUpdate() { 16699 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))]]; 16700 } 16701 #updateThickness(thickness) { 16702 const savedThickness = this.thickness; 16703 this.addCommands({ 16704 cmd: () => { 16705 this.thickness = thickness; 16706 this.#fitToContent(); 16707 }, 16708 undo: () => { 16709 this.thickness = savedThickness; 16710 this.#fitToContent(); 16711 }, 16712 mustExec: true, 16713 type: _util.AnnotationEditorParamsType.INK_THICKNESS, 16714 overwriteIfSameType: true, 16715 keepUndo: true 16716 }); 16717 } 16718 #updateColor(color) { 16719 const savedColor = this.color; 16720 this.addCommands({ 16721 cmd: () => { 16722 this.color = color; 16723 this.#redraw(); 16724 }, 16725 undo: () => { 16726 this.color = savedColor; 16727 this.#redraw(); 16728 }, 16729 mustExec: true, 16730 type: _util.AnnotationEditorParamsType.INK_COLOR,
16731 overwriteIfSameType: true, 16732 keepUndo: true 16733 }); 16734 } 16735 #updateOpacity(opacity) { 16736 opacity /= 100; 16737 const savedOpacity = this.opacity; 16738 this.addCommands({ 16739 cmd: () => { 16740 this.opacity = opacity; 16741 this.#redraw(); 16742 }, 16743 undo: () => { 16744 this.opacity = savedOpacity; 16745 this.#redraw(); 16746 }, 16747 mustExec: true, 16748 type: _util.AnnotationEditorParamsType.INK_OPACITY, 16749 overwriteIfSameType: true, 16750 keepUndo: true 16751 }); 16752 } 16753 rebuild() { 16754 if (!this.parent) { 16755 return; 16756 } 16757 super.rebuild(); 16758 if (this.div === null) { 16759 return; 16760 } 16761 if (!this.canvas) { 16762 this.#createCanvas(); 16763 this.#createObserver(); 16764 } 16765 if (!this.isAttachedToDOM) { 16766 this.parent.add(this); 16767 this.#setCanvasDims(); 16768 } 16769 this.#fitToContent(); 16770 } 16771 remove() { 16772 if (this.canvas === null) { 16773 return; 16774 } 16775 if (!this.isEmpty()) { 16776 this.commit(); 16777 } 16778 this.canvas.width = this.canvas.height = 0; 16779 this.canvas.remove(); 16780 this.canvas = null; 16781 this.#observer.disconnect(); 16782 this.#observer = null; 16783 super.remove(); 16784 } 16785 setParent(parent) { 16786 if (!this.parent && parent) { 16787 this._uiManager.removeShouldRescale(this); 16788 } else if (this.parent && parent === null) { 16789 this._uiManager.addShouldRescale(this); 16790 } 16791 super.setParent(parent); 16792 } 16793 onScaleChanging() { 16794 const [parentWidth, parentHeight] = this.parentDimensions; 16795 const width = this.width * parentWidth; 16796 const height = this.height * parentHeight; 16797 this.setDimensions(width, height); 16798 } 16799 enableEditMode() { 16800 if (this.#disableEditing || this.canvas === null) { 16801 return; 16802 } 16803 super.enableEditMode(); 16804 this._isDraggable = false; 16805 this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown); 16806 } 16807 disableEditMode() { 16808 if (!this.isInEditMode() || this.canvas === null) { 16809 return; 16810 } 16811 super.disableEditMode(); 16812 this._isDraggable = !this.isEmpty(); 16813 this.div.classList.remove("editing"); 16814 this.canvas.removeEventListener("pointerdown", this.#boundCanvasPointerdown); 16815 } 16816 onceAdded() { 16817 this._isDraggable = !this.isEmpty(); 16818 } 16819 isEmpty() { 16820 return this.paths.length === 0 || this.paths.length === 1 && this.paths[0].length === 0; 16821 } 16822 #getInitialBBox() { 16823 const { 16824 parentRotation, 16825 parentDimensions: [width, height] 16826 } = this; 16827 switch (parentRotation) { 16828 case 90: 16829 return [0, height, height, width]; 16830 case 180: 16831 return [width, height, width, height]; 16832 case 270: 16833 return [width, 0, height, width]; 16834 default: 16835 return [0, 0, width, height]; 16836 } 16837 } 16838 #setStroke() { 16839 const { 16840 ctx, 16841 color, 16842 opacity, 16843 thickness, 16844 parentScale, 16845 scaleFactor 16846 } = this; 16847 ctx.lineWidth = thickness * parentScale / scaleFactor; 16848 ctx.lineCap = "round"; 16849 ctx.lineJoin = "round"; 16850 ctx.miterLimit = 10; 16851 ctx.strokeStyle = `${color}${(0, _tools.opacityToHex)(opacity)}`; 16852 } 16853 #startDrawing(x, y) { 16854 this.canvas.addEventListener("contextmenu", this.#boundCanvasContextMenu); 16855 this.canvas.addEventListener("pointerleave", this.#boundCanvasPointerleave); 16856 this.canvas.addEventListener("pointermove", this.#boundCanvasPointermove); 16857 this.canvas.addEventListener("pointerup", this.#boundCanvasPointerup); 16858 this.canvas.removeEventListener("pointerdown", this.#boundCanvasPointerdown); 16859 this.isEditing = true; 16860 if (!this.#isCanvasInitialized) { 16861 this.#isCanvasInitialized = true; 16862 this.#setCanvasDims(); 16863 this.thickness ||= InkEditor._defaultThickness; 16864 this.color ||= InkEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor; 16865 this.opacity ??= InkEditor._defaultOpacity; 16866 } 16867 this.currentPath.push([x, y]); 16868 this.#hasSomethingToDraw = false; 16869 this.#setStroke(); 16870 this.#requestFrameCallback = () => { 16871 this.#drawPoints(); 16872 if (this.#requestFrameCallback) { 16873 window.requestAnimationFrame(this.#requestFrameCallback); 16874 } 16875 }; 16876 window.requestAnimationFrame(this.#requestFrameCallback); 16877 } 16878 #draw(x, y) { 16879 const [lastX, lastY] = this.currentPath.at(-1); 16880 if (this.currentPath.length > 1 && x === lastX && y === lastY) { 16881 return; 16882 } 16883 const currentPath = this.currentPath; 16884 let path2D = this.#currentPath2D; 16885 currentPath.push([x, y]); 16886 this.#hasSomethingToDraw = true; 16887 if (currentPath.length <= 2) { 16888 path2D.moveTo(...currentPath[0]); 16889 path2D.lineTo(x, y); 16890 return; 16891 } 16892 if (currentPath.length === 3) { 16893 this.#currentPath2D = path2D = new Path2D(); 16894 path2D.moveTo(...currentPath[0]); 16895 } 16896 this.#makeBezierCurve(path2D, ...currentPath.at(-3), ...currentPath.at(-2), x, y); 16897 } 16898 #endPath() { 16899 if (this.currentPath.length === 0) { 16900 return; 16901 } 16902 const lastPoint = this.currentPath.at(-1); 16903 this.#currentPath2D.lineTo(...lastPoint); 16904 } 16905 #stopDrawing(x, y) { 16906 this.#requestFrameCallback = null; 16907 x = Math.min(Math.max(x, 0), this.canvas.width); 16908 y = Math.min(Math.max(y, 0), this.canvas.height); 16909 this.#draw(x, y); 16910 this.#endPath(); 16911 let bezier; 16912 if (this.currentPath.length !== 1) { 16913 bezier = this.#generateBezierPoints(); 16914 } else { 16915 const xy = [x, y]; 16916 bezier = [[xy, xy.slice(), xy.slice(), xy]]; 16917 } 16918 const path2D = this.#currentPath2D; 16919 const currentPath = this.currentPath; 16920 this.currentPath = []; 16921 this.#currentPath2D = new Path2D(); 16922 const cmd = () => { 16923 this.allRawPaths.push(currentPath); 16924 this.paths.push(bezier); 16925 this.bezierPath2D.push(path2D); 16926 this.rebuild(); 16927 }; 16928 const undo = () => { 16929 this.allRawPaths.pop(); 16930 this.paths.pop(); 16931 this.bezierPath2D.pop(); 16932 if (this.paths.length === 0) { 16933 this.remove(); 16934 } else { 16935 if (!this.canvas) { 16936 this.#createCanvas(); 16937 this.#createObserver(); 16938 } 16939 this.#fitToContent(); 16940 } 16941 }; 16942 this.addCommands({ 16943 cmd, 16944 undo, 16945 mustExec: true 16946 }); 16947 } 16948 #drawPoints() { 16949 if (!this.#hasSomethingToDraw) { 16950 return; 16951 } 16952 this.#hasSomethingToDraw = false;
16953 const thickness = Math.ceil(this.thickness * this.parentScale); 16954 const lastPoints = this.currentPath.slice(-3); 16955 const x = lastPoints.map(xy => xy[0]); 16956 const y = lastPoints.map(xy => xy[1]); 16957 const xMin = Math.min(...x) - thickness; 16958 const xMax = Math.max(...x) + thickness; 16959 const yMin = Math.min(...y) - thickness; 16960 const yMax = Math.max(...y) + thickness; 16961 const { 16962 ctx 16963 } = this; 16964 ctx.save(); 16965 ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 16966 for (const path of this.bezierPath2D) { 16967 ctx.stroke(path); 16968 } 16969 ctx.stroke(this.#currentPath2D); 16970 ctx.restore(); 16971 } 16972 #makeBezierCurve(path2D, x0, y0, x1, y1, x2, y2) { 16973 const prevX = (x0 + x1) / 2; 16974 const prevY = (y0 + y1) / 2; 16975 const x3 = (x1 + x2) / 2; 16976 const y3 = (y1 + y2) / 2; 16977 path2D.bezierCurveTo(prevX + 2 * (x1 - prevX) / 3, prevY + 2 * (y1 - prevY) / 3, x3 + 2 * (x1 - x3) / 3, y3 + 2 * (y1 - y3) / 3, x3, y3); 16978 } 16979 #generateBezierPoints() { 16980 const path = this.currentPath; 16981 if (path.length <= 2) { 16982 return [[path[0], path[0], path.at(-1), path.at(-1)]]; 16983 } 16984 const bezierPoints = []; 16985 let i; 16986 let [x0, y0] = path[0]; 16987 for (i = 1; i < path.length - 2; i++) { 16988 const [x1, y1] = path[i]; 16989 const [x2, y2] = path[i + 1]; 16990 const x3 = (x1 + x2) / 2; 16991 const y3 = (y1 + y2) / 2; 16992 const control1 = [x0 + 2 * (x1 - x0) / 3, y0 + 2 * (y1 - y0) / 3]; 16993 const control2 = [x3 + 2 * (x1 - x3) / 3, y3 + 2 * (y1 - y3) / 3]; 16994 bezierPoints.push([[x0, y0], control1, control2, [x3, y3]]); 16995 [x0, y0] = [x3, y3]; 16996 } 16997 const [x1, y1] = path[i]; 16998 const [x2, y2] = path[i + 1]; 16999 const control1 = [x0 + 2 * (x1 - x0) / 3, y0 + 2 * (y1 - y0) / 3]; 17000 const control2 = [x2 + 2 * (x1 - x2) / 3, y2 + 2 * (y1 - y2) / 3]; 17001 bezierPoints.push([[x0, y0], control1, control2, [x2, y2]]); 17002 return bezierPoints; 17003 } 17004 #redraw() { 17005 if (this.isEmpty()) { 17006 this.#updateTransform(); 17007 return; 17008 } 17009 this.#setStroke(); 17010 const { 17011 canvas, 17012 ctx 17013 } = this; 17014 ctx.setTransform(1, 0, 0, 1, 0, 0); 17015 ctx.clearRect(0, 0, canvas.width, canvas.height); 17016 this.#updateTransform(); 17017 for (const path of this.bezierPath2D) { 17018 ctx.stroke(path); 17019 } 17020 } 17021 commit() { 17022 if (this.#disableEditing) { 17023 return; 17024 } 17025 super.commit(); 17026 this.isEditing = false; 17027 this.disableEditMode(); 17028 this.setInForeground(); 17029 this.#disableEditing = true; 17030 this.div.classList.add("disabled"); 17031 this.#fitToContent(true); 17032 this.makeResizable(); 17033 this.parent.addInkEditorIfNeeded(true); 17034 this.moveInDOM(); 17035 this.div.focus({ 17036 preventScroll: true 17037 }); 17038 } 17039 focusin(event) { 17040 if (!this._focusEventsAllowed) { 17041 return; 17042 } 17043 super.focusin(event); 17044 this.enableEditMode(); 17045 } 17046 canvasPointerdown(event) { 17047 if (event.button !== 0 || !this.isInEditMode() || this.#disableEditing) { 17048 return; 17049 } 17050 this.setInForeground(); 17051 event.preventDefault(); 17052 if (event.type !== "mouse") { 17053 this.div.focus({ 17054 preventScroll: true 17055 }); 17056 } 17057 this.#startDrawing(event.offsetX, event.offsetY); 17058 } 17059 canvasContextMenu(event) { 17060 event.preventDefault(); 17061 } 17062 canvasPointermove(event) { 17063 event.preventDefault(); 17064 this.#draw(event.offsetX, event.offsetY); 17065 } 17066 canvasPointerup(event) { 17067 event.preventDefault(); 17068 this.#endDrawing(event); 17069 } 17070 canvasPointerleave(event) { 17071 this.#endDrawing(event); 17072 } 17073 #endDrawing(event) { 17074 this.canvas.removeEventListener("pointerleave", this.#boundCanvasPointerleave); 17075 this.canvas.removeEventListener("pointermove", this.#boundCanvasPointermove); 17076 this.canvas.removeEventListener("pointerup", this.#boundCanvasPointerup); 17077 this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown); 17078 setTimeout(() => { 17079 this.canvas.removeEventListener("contextmenu", this.#boundCanvasContextMenu); 17080 }, 10); 17081 this.#stopDrawing(event.offsetX, event.offsetY); 17082 this.addToAnnotationStorage(); 17083 this.setInBackground(); 17084 } 17085 #createCanvas() { 17086 this.canvas = document.createElement("canvas"); 17087 this.canvas.width = this.canvas.height = 0; 17088 this.canvas.className = "inkEditorCanvas"; 17089 InkEditor._l10nPromise.get("editor_ink_canvas_aria_label").then(msg => this.canvas?.setAttribute("aria-label", msg)); 17090 this.div.append(this.canvas); 17091 const options = window.pdfDefaultOptions.activateWillReadFrequentlyFlag ? { 17092 willReadFrequently: true 17093 } : undefined; 17094 this.ctx = this.canvas.getContext("2d", options); 17095 } 17096 #createObserver() { 17097 this.#observer = new ResizeObserver(entries => {
17098 const rect = entries[0].contentRect; 17099 if (rect.width && rect.height) { 17100 this.setDimensions(rect.width, rect.height); 17101 } 17102 }); 17103 this.#observer.observe(this.div); 17104 } 17105 get isResizable() { 17106 return !this.isEmpty() && this.#disableEditing; 17107 } 17108 render() { 17109 if (this.div) { 17110 return this.div; 17111 } 17112 let baseX, baseY; 17113 if (this.width) { 17114 baseX = this.x; 17115 baseY = this.y; 17116 } 17117 super.render(); 17118 InkEditor._l10nPromise.get("editor_ink2_aria_label").then(msg => this.div?.setAttribute("aria-label", msg)); 17119 const [x, y, w, h] = this.#getInitialBBox(); 17120 this.setAt(x, y, 0, 0); 17121 this.setDims(w, h); 17122 this.#createCanvas(); 17123 if (this.width) { 17124 const [parentWidth, parentHeight] = this.parentDimensions; 17125 this.setAspectRatio(this.width * parentWidth, this.height * parentHeight); 17126 this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); 17127 this.#isCanvasInitialized = true; 17128 this.#setCanvasDims(); 17129 this.setDims(this.width * parentWidth, this.height * parentHeight); 17130 this.#redraw(); 17131 this.div.classList.add("disabled"); 17132 } else { 17133 this.div.classList.add("editing"); 17134 this.enableEditMode(); 17135 } 17136 this.#createObserver(); 17137 return this.div; 17138 } 17139 #setCanvasDims() { 17140 if (!this.#isCanvasInitialized) { 17141 return; 17142 } 17143 const [parentWidth, parentHeight] = this.parentDimensions; 17144 this.canvas.width = Math.ceil(this.width * parentWidth); 17145 this.canvas.height = Math.ceil(this.height * parentHeight); 17146 this.#updateTransform(); 17147 } 17148 setDimensions(width, height) { 17149 const roundedWidth = Math.round(width); 17150 const roundedHeight = Math.round(height); 17151 if (this.#realWidth === roundedWidth && this.#realHeight === roundedHeight) { 17152 return; 17153 } 17154 this.#realWidth = roundedWidth; 17155 this.#realHeight = roundedHeight; 17156 this.canvas.style.visibility = "hidden"; 17157 const [parentWidth, parentHeight] = this.parentDimensions; 17158 this.width = width / parentWidth; 17159 this.height = height / parentHeight; 17160 this.fixAndSetPosition(); 17161 if (this.#disableEditing) { 17162 this.#setScaleFactor(width, height); 17163 } 17164 this.#setCanvasDims(); 17165 this.#redraw(); 17166 this.canvas.style.visibility = "visible"; 17167 this.fixDims(); 17168 } 17169 #setScaleFactor(width, height) { 17170 const padding = this.#getPadding(); 17171 const scaleFactorW = (width - padding) / this.#baseWidth; 17172 const scaleFactorH = (height - padding) / this.#baseHeight; 17173 this.scaleFactor = Math.min(scaleFactorW, scaleFactorH); 17174 } 17175 #updateTransform() { 17176 const padding = this.#getPadding() / 2; 17177 this.ctx.setTransform(this.scaleFactor, 0, 0, this.scaleFactor, this.translationX * this.scaleFactor + padding, this.translationY * this.scaleFactor + padding); 17178 } 17179 static #buildPath2D(bezier) { 17180 const path2D = new Path2D(); 17181 for (let i = 0, ii = bezier.length; i < ii; i++) { 17182 const [first, control1, control2, second] = bezier[i]; 17183 if (i === 0) { 17184 path2D.moveTo(...first); 17185 } 17186 path2D.bezierCurveTo(control1[0], control1[1], control2[0], control2[1], second[0], second[1]); 17187 } 17188 return path2D; 17189 } 17190 static #toPDFCoordinates(points, rect, rotation) { 17191 const [blX, blY, trX, trY] = rect; 17192 switch (rotation) { 17193 case 0: 17194 for (let i = 0, ii = points.length; i < ii; i += 2) { 17195 points[i] += blX; 17196 points[i + 1] = trY - points[i + 1]; 17197 } 17198 break; 17199 case 90: 17200 for (let i = 0, ii = points.length; i < ii; i += 2) { 17201 const x = points[i]; 17202 points[i] = points[i + 1] + blX; 17203 points[i + 1] = x + blY; 17204 } 17205 break; 17206 case 180: 17207 for (let i = 0, ii = points.length; i < ii; i += 2) { 17208 points[i] = trX - points[i]; 17209 points[i + 1] += blY; 17210 } 17211 break; 17212 case 270: 17213 for (let i = 0, ii = points.length; i < ii; i += 2) { 17214 const x = points[i]; 17215 points[i] = trX - points[i + 1]; 17216 points[i + 1] = trY - x; 17217 } 17218 break; 17219 default: 17220 throw new Error("Invalid rotation"); 17221 } 17222 return points; 17223 } 17224 static #fromPDFCoordinates(points, rect, rotation) { 17225 const [blX, blY, trX, trY] = rect; 17226 switch (rotation) { 17227 case 0: 17228 for (let i = 0, ii = points.length; i < ii; i += 2) { 17229 points[i] -= blX; 17230 points[i + 1] = trY - points[i + 1]; 17231 } 17232 break; 17233 case 90: 17234 for (let i = 0, ii = points.length; i < ii; i += 2) { 17235 const x = points[i]; 17236 points[i] = points[i + 1] - blY; 17237 points[i + 1] = x - blX; 17238 } 17239 break; 17240 case 180: 17241 for (let i = 0, ii = points.length; i < ii; i += 2) { 17242 points[i] = trX - points[i]; 17243 points[i + 1] -= blY; 17244 } 17245 break; 17246 case 270: 17247 for (let i = 0, ii = points.length; i < ii; i += 2) { 17248 const x = points[i]; 17249 points[i] = trY - points[i + 1]; 17250 points[i + 1] = trX - x; 17251 } 17252 break; 17253 default: 17254 throw new Error("Invalid rotation"); 17255 } 17256 return points; 17257 } 17258 #serializePaths(s, tx, ty, rect) { 17259 const paths = []; 17260 const padding = this.thickness / 2; 17261 const shiftX = s * tx + padding; 17262 const shiftY = s * ty + padding; 17263 for (const bezier of this.paths) { 17264 const buffer = []; 17265 const points = []; 17266 for (let j = 0, jj = bezier.length; j < jj; j++) { 17267 const [first, control1, control2, second] = bezier[j]; 17268 const p10 = s * first[0] + shiftX; 17269 const p11 = s * first[1] + shiftY; 17270 const p20 = s * control1[0] + shiftX; 17271 const p21 = s * control1[1] + shiftY; 17272 const p30 = s * control2[0] + shiftX; 17273 const p31 = s * control2[1] + shiftY; 17274 const p40 = s * second[0] + shiftX; 17275 const p41 = s * second[1] + shiftY; 17276 if (j === 0) { 17277 buffer.push(p10, p11); 17278 points.push(p10, p11); 17279 } 17280 buffer.push(p20, p21, p30, p31, p40, p41); 17281 points.push(p20, p21); 17282 if (j === jj - 1) { 17283 points.push(p40, p41); 17284 } 17285 } 17286 paths.push({ 17287 bezier: InkEditor.#toPDFCoordinates(buffer, rect, this.rotation), 17288 points: InkEditor.#toPDFCoordinates(points, rect, this.rotation) 17289 }); 17290 } 17291 return paths; 17292 } 17293 #getBbox() { 17294 let xMin = Infinity; 17295 let xMax = -Infinity; 17296 let yMin = Infinity; 17297 let yMax = -Infinity; 17298 for (const path of this.paths) { 17299 for (const [first, control1, control2, second] of path) { 17300 const bbox = _util.Util.bezierBoundingBox(...first, ...control1, ...control2, ...second); 17301 xMin = Math.min(xMin, bbox[0]); 17302 yMin = Math.min(yMin, bbox[1]); 17303 xMax = Math.max(xMax, bbox[2]); 17304 yMax = Math.max(yMax, bbox[3]); 17305 } 17306 } 17307 return [xMin, yMin, xMax, yMax]; 17308 } 17309 #getPadding() { 17310 return this.#disableEditing ? Math.ceil(this.thickness * this.parentScale) : 0; 17311 } 17312 #fitToContent(firstTime = false) { 17313 if (this.isEmpty()) { 17314 return; 17315 } 17316 if (!this.#disableEditing) { 17317 this.#redraw(); 17318 return; 17319 } 17320 const bbox = this.#getBbox(); 17321 const padding = this.#getPadding();
17322 this.#baseWidth = Math.max(_editor.AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]); 17323 this.#baseHeight = Math.max(_editor.AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]); 17324 const width = Math.ceil(padding + this.#baseWidth * this.scaleFactor); 17325 const height = Math.ceil(padding + this.#baseHeight * this.scaleFactor); 17326 const [parentWidth, parentHeight] = this.parentDimensions; 17327 this.width = width / parentWidth; 17328 this.height = height / parentHeight; 17329 this.setAspectRatio(width, height); 17330 const prevTranslationX = this.translationX; 17331 const prevTranslationY = this.translationY; 17332 this.translationX = -bbox[0]; 17333 this.translationY = -bbox[1]; 17334 this.#setCanvasDims(); 17335 this.#redraw(); 17336 this.#realWidth = width; 17337 this.#realHeight = height; 17338 this.setDims(width, height); 17339 const unscaledPadding = firstTime ? padding / this.scaleFactor / 2 : 0; 17340 this.translate(prevTranslationX - this.translationX - unscaledPadding, prevTranslationY - this.translationY - unscaledPadding); 17341 } 17342 static deserialize(data, parent, uiManager) { 17343 if (data instanceof _annotation_layer.InkAnnotationElement) { 17344 return null; 17345 } 17346 const editor = super.deserialize(data, parent, uiManager); 17347 editor.thickness = data.thickness; 17348 editor.color = _util.Util.makeHexColor(...data.color); 17349 editor.opacity = data.opacity; 17350 const [pageWidth, pageHeight] = editor.pageDimensions; 17351 const width = editor.width * pageWidth; 17352 const height = editor.height * pageHeight; 17353 const scaleFactor = editor.parentScale; 17354 const padding = data.thickness / 2; 17355 editor.#disableEditing = true; 17356 editor.#realWidth = Math.round(width); 17357 editor.#realHeight = Math.round(height); 17358 const { 17359 paths, 17360 rect, 17361 rotation 17362 } = data; 17363 for (let { 17364 bezier 17365 } of paths) { 17366 bezier = InkEditor.#fromPDFCoordinates(bezier, rect, rotation); 17367 const path = []; 17368 editor.paths.push(path); 17369 let p0 = scaleFactor * (bezier[0] - padding); 17370 let p1 = scaleFactor * (bezier[1] - padding); 17371 for (let i = 2, ii = bezier.length; i < ii; i += 6) { 17372 const p10 = scaleFactor * (bezier[i] - padding); 17373 const p11 = scaleFactor * (bezier[i + 1] - padding); 17374 const p20 = scaleFactor * (bezier[i + 2] - padding); 17375 const p21 = scaleFactor * (bezier[i + 3] - padding); 17376 const p30 = scaleFactor * (bezier[i + 4] - padding); 17377 const p31 = scaleFactor * (bezier[i + 5] - padding); 17378 path.push([[p0, p1], [p10, p11], [p20, p21], [p30, p31]]); 17379 p0 = p30; 17380 p1 = p31; 17381 } 17382 const path2D = this.#buildPath2D(path); 17383 editor.bezierPath2D.push(path2D); 17384 } 17385 const bbox = editor.#getBbox(); 17386 editor.#baseWidth = Math.max(_editor.AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]); 17387 editor.#baseHeight = Math.max(_editor.AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]); 17388 editor.#setScaleFactor(width, height); 17389 return editor; 17390 } 17391 serialize() { 17392 if (this.isEmpty()) { 17393 return null; 17394 } 17395 const rect = this.getRect(0, 0); 17396 const color = _editor.AnnotationEditor._colorManager.convert(this.ctx.strokeStyle); 17397 return { 17398 annotationType: _util.AnnotationEditorType.INK, 17399 color, 17400 thickness: this.thickness, 17401 opacity: this.opacity, 17402 paths: this.#serializePaths(this.scaleFactor / this.parentScale, this.translationX, this.translationY, rect), 17403 pageIndex: this.pageIndex, 17404 rect, 17405 rotation: this.rotation 17406 }; 17407 } 17408} 17409exports.InkEditor = InkEditor; 17410 17411/***/ }), 17412/* 34 */ 17413/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 17414 17415 17416 17417Object.defineProperty(exports, "__esModule", ({ 17418 value: true 17419})); 17420exports.StampEditor = void 0; 17421var _util = __w_pdfjs_require__(1); 17422var _editor = __w_pdfjs_require__(4); 17423var _display_utils = __w_pdfjs_require__(6); 17424var _annotation_layer = __w_pdfjs_require__(29); 17425class StampEditor extends _editor.AnnotationEditor { 17426 #bitmap = null; 17427 #bitmapId = null; 17428 #bitmapPromise = null; 17429 #bitmapUrl = null; 17430 #bitmapFile = null; 17431 #canvas = null; 17432 #observer = null; 17433 #resizeTimeoutId = null; 17434 #isSvg = false;
17435 #hasBeenAddedInUndoStack = false; 17436 static _type = "stamp"; 17437 constructor(params) { 17438 super({ 17439 ...params, 17440 name: "stampEditor" 17441 }); 17442 this.#bitmapUrl = params.bitmapUrl; 17443 this.#bitmapFile = params.bitmapFile; 17444 } 17445 static get supportedTypes() { 17446 const types = ["apng", "avif", "bmp", "gif", "jpeg", "png", "svg+xml", "webp", "x-icon"]; 17447 return (0, _util.shadow)(this, "supportedTypes", types.map(type => `image/${type}`)); 17448 } 17449 static get supportedTypesStr() { 17450 return (0, _util.shadow)(this, "supportedTypesStr", this.supportedTypes.join(",")); 17451 } 17452 static isHandlingMimeForPasting(mime) { 17453 return this.supportedTypes.includes(mime); 17454 } 17455 static paste(item, parent) { 17456 parent.pasteEditor(_util.AnnotationEditorType.STAMP, { 17457 bitmapFile: item.getAsFile() 17458 }); 17459 } 17460 #getBitmapFetched(data, fromId = false) { 17461 if (!data) { 17462 this.remove(); 17463 return; 17464 } 17465 this.#bitmap = data.bitmap; 17466 if (!fromId) { 17467 this.#bitmapId = data.id; 17468 this.#isSvg = data.isSvg; 17469 } 17470 this.#createCanvas(); 17471 } 17472 #getBitmapDone() { 17473 this.#bitmapPromise = null; 17474 this._uiManager.enableWaiting(false); 17475 if (this.#canvas) { 17476 this.div.focus(); 17477 } 17478 } 17479 #getBitmap() { 17480 if (this.#bitmapId) { 17481 this._uiManager.enableWaiting(true); 17482 this._uiManager.imageManager.getFromId(this.#bitmapId).then(data => this.#getBitmapFetched(data, true)).finally(() => this.#getBitmapDone()); 17483 return; 17484 } 17485 if (this.#bitmapUrl) { 17486 const url = this.#bitmapUrl; 17487 this.#bitmapUrl = null; 17488 this._uiManager.enableWaiting(true); 17489 this.#bitmapPromise = this._uiManager.imageManager.getFromUrl(url).then(data => this.#getBitmapFetched(data)).finally(() => this.#getBitmapDone()); 17490 return; 17491 } 17492 if (this.#bitmapFile) { 17493 const file = this.#bitmapFile; 17494 this.#bitmapFile = null; 17495 this._uiManager.enableWaiting(true); 17496 this.#bitmapPromise = this._uiManager.imageManager.getFromFile(file).then(data => this.#getBitmapFetched(data)).finally(() => this.#getBitmapDone()); 17497 return; 17498 } 17499 const input = document.createElement("input"); 17500 input.type = "file"; 17501 input.accept = StampEditor.supportedTypesStr; 17502 this.#bitmapPromise = new Promise(resolve => { 17503 input.addEventListener("change", async () => { 17504 if (!input.files || input.files.length === 0) { 17505 this.remove(); 17506 } else { 17507 this._uiManager.enableWaiting(true); 17508 const data = await this._uiManager.imageManager.getFromFile(input.files[0]); 17509 this.#getBitmapFetched(data); 17510 } 17511 resolve(); 17512 }); 17513 input.addEventListener("cancel", () => { 17514 this.remove(); 17515 resolve(); 17516 }); 17517 }).finally(() => this.#getBitmapDone()); 17518 input.click(); 17519 } 17520 remove() { 17521 if (this.#bitmapId) { 17522 this.#bitmap = null; 17523 this._uiManager.imageManager.deleteId(this.#bitmapId); 17524 this.#canvas?.remove(); 17525 this.#canvas = null; 17526 this.#observer?.disconnect(); 17527 this.#observer = null; 17528 } 17529 super.remove(); 17530 } 17531 rebuild() { 17532 if (!this.parent) { 17533 if (this.#bitmapId) { 17534 this.#getBitmap(); 17535 } 17536 return; 17537 } 17538 super.rebuild(); 17539 if (this.div === null) { 17540 return; 17541 } 17542 if (this.#bitmapId) { 17543 this.#getBitmap(); 17544 } 17545 if (!this.isAttachedToDOM) { 17546 this.parent.add(this); 17547 } 17548 } 17549 onceAdded() { 17550 this._isDraggable = true; 17551 this.div.focus(); 17552 } 17553 isEmpty() { 17554 return !(this.#bitmapPromise || this.#bitmap || this.#bitmapUrl || this.#bitmapFile); 17555 } 17556 get isResizable() { 17557 return true; 17558 } 17559 render() { 17560 if (this.div) { 17561 return this.div; 17562 } 17563 let baseX, baseY; 17564 if (this.width) { 17565 baseX = this.x; 17566 baseY = this.y; 17567 } 17568 super.render(); 17569 this.div.hidden = true; 17570 if (this.#bitmap) { 17571 this.#createCanvas(); 17572 } else { 17573 this.#getBitmap(); 17574 } 17575 if (this.width) { 17576 const [parentWidth, parentHeight] = this.parentDimensions; 17577 this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); 17578 } 17579 return this.div; 17580 } 17581 #createCanvas() { 17582 const { 17583 div 17584 } = this; 17585 let { 17586 width, 17587 height 17588 } = this.#bitmap; 17589 const [pageWidth, pageHeight] = this.pageDimensions; 17590 const MAX_RATIO = 0.75; 17591 if (this.width) { 17592 width = this.width * pageWidth; 17593 height = this.height * pageHeight; 17594 } else if (width > MAX_RATIO * pageWidth || height > MAX_RATIO * pageHeight) { 17595 const factor = Math.min(MAX_RATIO * pageWidth / width, MAX_RATIO * pageHeight / height); 17596 width *= factor; 17597 height *= factor; 17598 } 17599 const [parentWidth, parentHeight] = this.parentDimensions; 17600 this.setDims(width * parentWidth / pageWidth, height * parentHeight / pageHeight); 17601 this._uiManager.enableWaiting(false); 17602 const canvas = this.#canvas = document.createElement("canvas"); 17603 div.append(canvas); 17604 div.hidden = false;
17605 this.#drawBitmap(width, height); 17606 this.#createObserver(); 17607 if (!this.#hasBeenAddedInUndoStack) { 17608 this.parent.addUndoableEditor(this); 17609 this.#hasBeenAddedInUndoStack = true; 17610 } 17611 } 17612 #setDimensions(width, height) { 17613 const [parentWidth, parentHeight] = this.parentDimensions; 17614 this.width = width / parentWidth; 17615 this.height = height / parentHeight; 17616 this.setDims(width, height); 17617 if (this._initialOptions?.isCentered) { 17618 this.center(); 17619 } else { 17620 this.fixAndSetPosition(); 17621 } 17622 this._initialOptions = null; 17623 if (this.#resizeTimeoutId !== null) { 17624 clearTimeout(this.#resizeTimeoutId); 17625 } 17626 const TIME_TO_WAIT = 200; 17627 this.#resizeTimeoutId = setTimeout(() => { 17628 this.#resizeTimeoutId = null; 17629 this.#drawBitmap(width, height); 17630 }, TIME_TO_WAIT); 17631 } 17632 #scaleBitmap(width, height) { 17633 const { 17634 width: bitmapWidth, 17635 height: bitmapHeight 17636 } = this.#bitmap; 17637 let newWidth = bitmapWidth; 17638 let newHeight = bitmapHeight; 17639 let bitmap = this.#bitmap; 17640 while (newWidth > 2 * width || newHeight > 2 * height) { 17641 const prevWidth = newWidth; 17642 const prevHeight = newHeight; 17643 if (newWidth > 2 * width) { 17644 newWidth = newWidth >= 16384 ? Math.floor(newWidth / 2) - 1 : Math.ceil(newWidth / 2); 17645 } 17646 if (newHeight > 2 * height) { 17647 newHeight = newHeight >= 16384 ? Math.floor(newHeight / 2) - 1 : Math.ceil(newHeight / 2); 17648 } 17649 const offscreen = new OffscreenCanvas(newWidth, newHeight); 17650 const ctx = offscreen.getContext("2d"); 17651 ctx.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight); 17652 bitmap = offscreen.transferToImageBitmap(); 17653 } 17654 return bitmap; 17655 } 17656 #drawBitmap(width, height) { 17657 width = Math.ceil(width); 17658 height = Math.ceil(height); 17659 const canvas = this.#canvas; 17660 if (!canvas || canvas.width === width && canvas.height === height) { 17661 return; 17662 } 17663 canvas.width = width; 17664 canvas.height = height; 17665 const bitmap = this.#isSvg ? this.#bitmap : this.#scaleBitmap(width, height); 17666 const ctx = canvas.getContext("2d"); 17667 ctx.filter = this._uiManager.hcmFilter; 17668 ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height); 17669 } 17670 #serializeBitmap(toUrl) { 17671 if (toUrl) { 17672 if (this.#isSvg) { 17673 const url = this._uiManager.imageManager.getSvgUrl(this.#bitmapId); 17674 if (url) { 17675 return url; 17676 } 17677 } 17678 const canvas = document.createElement("canvas"); 17679 ({ 17680 width: canvas.width, 17681 height: canvas.height 17682 } = this.#bitmap); 17683 const ctx = canvas.getContext("2d"); 17684 ctx.drawImage(this.#bitmap, 0, 0); 17685 return canvas.toDataURL(); 17686 } 17687 if (this.#isSvg) { 17688 const [pageWidth, pageHeight] = this.pageDimensions; 17689 const width = Math.round(this.width * pageWidth * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS); 17690 const height = Math.round(this.height * pageHeight * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS); 17691 const offscreen = new OffscreenCanvas(width, height); 17692 const ctx = offscreen.getContext("2d"); 17693 ctx.drawImage(this.#bitmap, 0, 0, this.#bitmap.width, this.#bitmap.height, 0, 0, width, height); 17694 return offscreen.transferToImageBitmap(); 17695 } 17696 return structuredClone(this.#bitmap); 17697 } 17698 #createObserver() { 17699 this.#observer = new ResizeObserver(entries => { 17700 const rect = entries[0].contentRect; 17701 if (rect.width && rect.height) { 17702 this.#setDimensions(rect.width, rect.height); 17703 } 17704 }); 17705 this.#observer.observe(this.div); 17706 } 17707 static deserialize(data, parent, uiManager) { 17708 if (data instanceof _annotation_layer.StampAnnotationElement) { 17709 return null; 17710 } 17711 const editor = super.deserialize(data, parent, uiManager); 17712 const { 17713 rect, 17714 bitmapUrl, 17715 bitmapId, 17716 isSvg 17717 } = data; 17718 if (bitmapId && uiManager.imageManager.isValidId(bitmapId)) { 17719 editor.#bitmapId = bitmapId; 17720 } else { 17721 editor.#bitmapUrl = bitmapUrl; 17722 } 17723 editor.#isSvg = isSvg; 17724 const [parentWidth, parentHeight] = editor.pageDimensions; 17725 editor.width = (rect[2] - rect[0]) / parentWidth; 17726 editor.height = (rect[3] - rect[1]) / parentHeight; 17727 return editor; 17728 } 17729 serialize(isForCopying = false, context = null) { 17730 if (this.isEmpty()) { 17731 return null; 17732 } 17733 const serialized = { 17734 annotationType: _util.AnnotationEditorType.STAMP, 17735 bitmapId: this.#bitmapId, 17736 pageIndex: this.pageIndex, 17737 rect: this.getRect(0, 0), 17738 rotation: this.rotation, 17739 isSvg: this.#isSvg 17740 }; 17741 if (isForCopying) { 17742 serialized.bitmapUrl = this.#serializeBitmap(true); 17743 return serialized; 17744 } 17745 if (context === null) { 17746 return serialized; 17747 } 17748 context.stamps ||= new Map(); 17749 const area = this.#isSvg ? (serialized.rect[2] - serialized.rect[0]) * (serialized.rect[3] - serialized.rect[1]) : null; 17750 if (!context.stamps.has(this.#bitmapId)) { 17751 context.stamps.set(this.#bitmapId, { 17752 area,
17753 serialized 17754 }); 17755 serialized.bitmap = this.#serializeBitmap(false); 17756 } else if (this.#isSvg) { 17757 const prevData = context.stamps.get(this.#bitmapId); 17758 if (area > prevData.area) { 17759 prevData.area = area; 17760 prevData.serialized.bitmap.close(); 17761 prevData.serialized.bitmap = this.#serializeBitmap(false); 17762 } 17763 } 17764 return serialized; 17765 } 17766} 17767exports.StampEditor = StampEditor; 17768 17769/***/ }) 17770/******/ ]); 17771/************************************************************************/ 17772/******/ // The module cache 17773/******/ var __webpack_module_cache__ = {}; 17774/******/ 17775/******/ // The require function 17776/******/ function __w_pdfjs_require__(moduleId) { 17777/******/ // Check if module is in cache 17778/******/ var cachedModule = __webpack_module_cache__[moduleId]; 17779/******/ if (cachedModule !== undefined) { 17780/******/ return cachedModule.exports; 17781/******/ } 17782/******/ // Create a new module (and put it into the cache) 17783/******/ var module = __webpack_module_cache__[moduleId] = { 17784/******/ // no module.id needed 17785/******/ // no module.loaded needed 17786/******/ exports: {} 17787/******/ }; 17788/******/ 17789/******/ // Execute the module function 17790/******/ __webpack_modules__[moduleId](module, module.exports, __w_pdfjs_require__); 17791/******/ 17792/******/ // Return the exports of the module 17793/******/ return module.exports; 17794/******/ } 17795/******/ 17796/************************************************************************/ 17797var __webpack_exports__ = {}; 17798// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. 17799(() => { 17800var exports = __webpack_exports__; 17801 17802 17803Object.defineProperty(exports, "__esModule", ({ 17804 value: true 17805})); 17806Object.defineProperty(exports, "AbortException", ({ 17807 enumerable: true, 17808 get: function () { 17809 return _util.AbortException; 17810 } 17811})); 17812Object.defineProperty(exports, "AnnotationEditorLayer", ({ 17813 enumerable: true, 17814 get: function () { 17815 return _annotation_editor_layer.AnnotationEditorLayer; 17816 } 17817})); 17818Object.defineProperty(exports, "AnnotationEditorParamsType", ({ 17819 enumerable: true, 17820 get: function () { 17821 return _util.AnnotationEditorParamsType; 17822 } 17823})); 17824Object.defineProperty(exports, "AnnotationEditorType", ({ 17825 enumerable: true, 17826 get: function () { 17827 return _util.AnnotationEditorType; 17828 } 17829})); 17830Object.defineProperty(exports, "AnnotationEditorUIManager", ({ 17831 enumerable: true, 17832 get: function () { 17833 return _tools.AnnotationEditorUIManager; 17834 } 17835})); 17836Object.defineProperty(exports, "AnnotationLayer", ({ 17837 enumerable: true, 17838 get: function () { 17839 return _annotation_layer.AnnotationLayer; 17840 } 17841})); 17842Object.defineProperty(exports, "AnnotationMode", ({ 17843 enumerable: true, 17844 get: function () { 17845 return _util.AnnotationMode; 17846 } 17847})); 17848Object.defineProperty(exports, "CMapCompressionType", ({ 17849 enumerable: true, 17850 get: function () { 17851 return _util.CMapCompressionType; 17852 } 17853})); 17854Object.defineProperty(exports, "FeatureTest", ({ 17855 enumerable: true, 17856 get: function () { 17857 return _util.FeatureTest; 17858 } 17859})); 17860Object.defineProperty(exports, "GlobalWorkerOptions", ({ 17861 enumerable: true, 17862 get: function () { 17863 return _worker_options.GlobalWorkerOptions; 17864 } 17865})); 17866Object.defineProperty(exports, "ImageKind", ({ 17867 enumerable: true, 17868 get: function () { 17869 return _util.ImageKind; 17870 } 17871})); 17872Object.defineProperty(exports, "InvalidPDFException", ({ 17873 enumerable: true, 17874 get: function () { 17875 return _util.InvalidPDFException; 17876 } 17877})); 17878Object.defineProperty(exports, "MissingPDFException", ({ 17879 enumerable: true, 17880 get: function () { 17881 return _util.MissingPDFException; 17882 } 17883})); 17884Object.defineProperty(exports, "OPS", ({ 17885 enumerable: true, 17886 get: function () { 17887 return _util.OPS; 17888 } 17889})); 17890Object.defineProperty(exports, "PDFDataRangeTransport", ({ 17891 enumerable: true, 17892 get: function () { 17893 return _api.PDFDataRangeTransport; 17894 } 17895})); 17896Object.defineProperty(exports, "PDFDateString", ({ 17897 enumerable: true, 17898 get: function () { 17899 return _display_utils.PDFDateString; 17900 } 17901})); 17902Object.defineProperty(exports, "PDFWorker", ({ 17903 enumerable: true, 17904 get: function () { 17905 return _api.PDFWorker; 17906 } 17907})); 17908Object.defineProperty(exports, "PasswordResponses", ({ 17909 enumerable: true, 17910 get: function () { 17911 return _util.PasswordResponses; 17912 } 17913})); 17914Object.defineProperty(exports, "PermissionFlag", ({ 17915 enumerable: true, 17916 get: function () { 17917 return _util.PermissionFlag; 17918 } 17919})); 17920Object.defineProperty(exports, "PixelsPerInch", ({ 17921 enumerable: true, 17922 get: function () { 17923 return _display_utils.PixelsPerInch; 17924 } 17925})); 17926Object.defineProperty(exports, "PromiseCapability", ({ 17927 enumerable: true, 17928 get: function () { 17929 return _util.PromiseCapability; 17930 } 17931})); 17932Object.defineProperty(exports, "RenderingCancelledException", ({ 17933 enumerable: true, 17934 get: function () { 17935 return _display_utils.RenderingCancelledException; 17936 } 17937})); 17938Object.defineProperty(exports, "SVGGraphics", ({ 17939 enumerable: true, 17940 get: function () { 17941 return _api.SVGGraphics; 17942 } 17943})); 17944Object.defineProperty(exports, "UnexpectedResponseException", ({ 17945 enumerable: true, 17946 get: function () { 17947 return _util.UnexpectedResponseException; 17948 } 17949})); 17950Object.defineProperty(exports, "Util", ({ 17951 enumerable: true, 17952 get: function () { 17953 return _util.Util; 17954 } 17955})); 17956Object.defineProperty(exports, "VerbosityLevel", ({ 17957 enumerable: true, 17958 get: function () { 17959 return _util.VerbosityLevel; 17960 } 17961})); 17962Object.defineProperty(exports, "XfaLayer", ({ 17963 enumerable: true, 17964 get: function () { 17965 return _xfa_layer.XfaLayer; 17966 } 17967}));
17968Object.defineProperty(exports, "build", ({ 17969 enumerable: true, 17970 get: function () { 17971 return _api.build; 17972 } 17973})); 17974Object.defineProperty(exports, "createValidAbsoluteUrl", ({ 17975 enumerable: true, 17976 get: function () { 17977 return _util.createValidAbsoluteUrl; 17978 } 17979})); 17980Object.defineProperty(exports, "getDocument", ({ 17981 enumerable: true, 17982 get: function () { 17983 return _api.getDocument; 17984 } 17985})); 17986Object.defineProperty(exports, "getFilenameFromUrl", ({ 17987 enumerable: true, 17988 get: function () { 17989 return _display_utils.getFilenameFromUrl; 17990 } 17991})); 17992Object.defineProperty(exports, "getPdfFilenameFromUrl", ({ 17993 enumerable: true, 17994 get: function () { 17995 return _display_utils.getPdfFilenameFromUrl; 17996 } 17997})); 17998Object.defineProperty(exports, "getXfaPageViewport", ({ 17999 enumerable: true, 18000 get: function () { 18001 return _display_utils.getXfaPageViewport; 18002 } 18003})); 18004Object.defineProperty(exports, "isDataScheme", ({ 18005 enumerable: true, 18006 get: function () { 18007 return _display_utils.isDataScheme; 18008 } 18009})); 18010Object.defineProperty(exports, "isPdfFile", ({ 18011 enumerable: true, 18012 get: function () { 18013 return _display_utils.isPdfFile; 18014 } 18015})); 18016Object.defineProperty(exports, "loadScript", ({ 18017 enumerable: true, 18018 get: function () { 18019 return _display_utils.loadScript; 18020 } 18021})); 18022Object.defineProperty(exports, "normalizeUnicode", ({ 18023 enumerable: true, 18024 get: function () { 18025 return _util.normalizeUnicode; 18026 } 18027})); 18028Object.defineProperty(exports, "renderTextLayer", ({ 18029 enumerable: true, 18030 get: function () { 18031 return _text_layer.renderTextLayer; 18032 } 18033})); 18034Object.defineProperty(exports, "setLayerDimensions", ({ 18035 enumerable: true, 18036 get: function () { 18037 return _display_utils.setLayerDimensions; 18038 } 18039})); 18040Object.defineProperty(exports, "shadow", ({ 18041 enumerable: true, 18042 get: function () { 18043 return _util.shadow; 18044 } 18045})); 18046Object.defineProperty(exports, "updateTextLayer", ({ 18047 enumerable: true, 18048 get: function () { 18049 return _text_layer.updateTextLayer; 18050 } 18051})); 18052Object.defineProperty(exports, "version", ({ 18053 enumerable: true, 18054 get: function () { 18055 return _api.version; 18056 } 18057})); 18058var _util = __w_pdfjs_require__(1); 18059var _api = __w_pdfjs_require__(2); 18060var _display_utils = __w_pdfjs_require__(6); 18061var _text_layer = __w_pdfjs_require__(26); 18062var _annotation_editor_layer = __w_pdfjs_require__(27); 18063var _tools = __w_pdfjs_require__(5); 18064var _annotation_layer = __w_pdfjs_require__(29); 18065var _worker_options = __w_pdfjs_require__(14); 18066var _xfa_layer = __w_pdfjs_require__(32); 18067const pdfjsVersion = '3.10.560'; 18068const pdfjsBuild = 'cc30dd43d'; 18069})(); 18070 18071/******/ return __webpack_exports__; 18072/******/ })() 18073; 18074}); 18075});
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.