1/** 2 * @licstart The following is the entire license notice for the 3 * JavaScript code in this page 4 * 5 * Copyright 2023 Mozilla Foundation 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 * @licend The above is the entire license notice for the 20 * JavaScript code in this page 21 */ 22 23(function webpackUniversalModuleDefinition(root, factory) { 24 if(typeof exports === 'object' && typeof module === 'object') 25 module.exports = factory(); 26 else if(typeof define === 'function' && define.amd) 27 define("pdfjs-dist/build/pdf", [], factory); 28 else if(typeof exports === 'object') 29 exports["pdfjs-dist/build/pdf"] = factory(); 30 else 31 root["pdfjs-dist/build/pdf"] = root.pdfjsLib = factory(); 32})(globalThis, () => { 33return /******/ (() => { // webpackBootstrap 34/******/ "use strict"; 35/******/ var __webpack_modules__ = ([ 36/* 0 */, 37/* 1 */ 38/***/ ((__unused_webpack_module, exports) => { 39 40 41 42Object.defineProperty(exports, "__esModule", ({ 43 value: true 44})); 45exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.RenderingIntentFlag = exports.PromiseCapability = exp
45orts.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.MAX_IMAGE_SIZE_TO_CACHE = exports.LINE_FACTOR = exports.LINE_DESCENT_FACTOR = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FeatureTest = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.CMapCompressionType = exports.BaseException = exports.BASELINE_FACTOR = exports.AnnotationType = exports.AnnotationReplyType = exports.AnnotationMode = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationEditorType = exports.AnnotationEditorPrefix = exports.AnnotationEditorParamsType = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0; 46exports.assert = assert; 47exports.bytesToString = bytesToString; 48exports.createValidAbsoluteUrl = createValidAbsoluteUrl; 49exports.getModificationDate = getModificationDate; 50exports.getUuid = getUuid; 51exports.getVerbosityLevel = getVerbosityLevel; 52exports.info = info; 53exports.isArrayBuffer = isArrayBuffer; 54exports.isArrayEqual = isArrayEqual; 55exports.isNodeJS = void 0; 56exports.normalizeUnicode = normalizeUnicode; 57exports.objectFromMap = objectFromMap; 58exports.objectSize = objectSize; 59exports.setVerbosityLevel = setVerbosityLevel; 60exports.shadow = shadow; 61exports.string32 = string32; 62exports.stringToBytes = stringToBytes; 63exports.stringToPDFString = stringToPDFString; 64exports.stringToUTF8String = stringToUTF8String; 65exports.unreachable = unreachable; 66exports.utf8StringToString = utf8StringToString; 67exports.warn = warn; 68const isNodeJS = typeof process === "object" && process + "" === "[object process]" && !process.versions.nw && !(process.versions.electron && process.type && process.type !== "browser");
69exports.isNodeJS = isNodeJS; 70const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; 71exports.IDENTITY_MATRIX = IDENTITY_MATRIX; 72const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0]; 73exports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX; 74const MAX_IMAGE_SIZE_TO_CACHE = 10e6; 75exports.MAX_IMAGE_SIZE_TO_CACHE = MAX_IMAGE_SIZE_TO_CACHE; 76const LINE_FACTOR = 1.35; 77exports.LINE_FACTOR = LINE_FACTOR; 78const LINE_DESCENT_FACTOR = 0.35; 79exports.LINE_DESCENT_FACTOR = LINE_DESCENT_FACTOR; 80const BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR; 81exports.BASELINE_FACTOR = BASELINE_FACTOR; 82const RenderingIntentFlag = { 83 ANY: 0x01, 84 DISPLAY: 0x02, 85 PRINT: 0x04, 86 SAVE: 0x08, 87 ANNOTATIONS_FORMS: 0x10, 88 ANNOTATIONS_STORAGE: 0x20, 89 ANNOTATIONS_DISABLE: 0x40, 90 OPLIST: 0x100 91}; 92exports.RenderingIntentFlag = RenderingIntentFlag; 93const AnnotationMode = { 94 DISABLE: 0, 95 ENABLE: 1, 96 ENABLE_FORMS: 2, 97 ENABLE_STORAGE: 3 98}; 99exports.AnnotationMode = AnnotationMode; 100const AnnotationEditorPrefix = "pdfjs_internal_editor_"; 101exports.AnnotationEditorPrefix = AnnotationEditorPrefix; 102const AnnotationEditorType = { 103 DISABLE: -1, 104 NONE: 0, 105 FREETEXT: 3, 106 STAMP: 13, 107 INK: 15 108}; 109exports.AnnotationEditorType = AnnotationEditorType; 110const AnnotationEditorParamsType = { 111 RESIZE: 1, 112 FREETEXT_SIZE: 11, 113 FREETEXT_COLOR: 12, 114 FREETEXT_OPACITY: 13, 115 INK_COLOR: 21, 116 INK_THICKNESS: 22, 117 INK_OPACITY: 23 118}; 119exports.AnnotationEditorParamsType = AnnotationEditorParamsType; 120const PermissionFlag = { 121 PRINT: 0x04, 122 MODIFY_CONTENTS: 0x08, 123 COPY: 0x10, 124 MODIFY_ANNOTATIONS: 0x20, 125 FILL_INTERACTIVE_FORMS: 0x100, 126 COPY_FOR_ACCESSIBILITY: 0x200, 127 ASSEMBLE: 0x400, 128 PRINT_HIGH_QUALITY: 0x800 129}; 130exports.PermissionFlag = PermissionFlag; 131const TextRenderingMode = { 132 FILL: 0, 133 STROKE: 1, 134 FILL_STROKE: 2, 135 INVISIBLE: 3, 136 FILL_ADD_TO_PATH: 4, 137 STROKE_ADD_TO_PATH: 5, 138 FILL_STROKE_ADD_TO_PATH: 6, 139 ADD_TO_PATH: 7, 140 FILL_STROKE_MASK: 3, 141 ADD_TO_PATH_FLAG: 4 142}; 143exports.TextRenderingMode = TextRenderingMode; 144const ImageKind = { 145 GRAYSCALE_1BPP: 1, 146 RGB_24BPP: 2, 147 RGBA_32BPP: 3 148}; 149exports.ImageKind = ImageKind; 150const AnnotationType = { 151 TEXT: 1, 152 LINK: 2, 153 FREETEXT: 3, 154 LINE: 4, 155 SQUARE: 5, 156 CIRCLE: 6, 157 POLYGON: 7, 158 POLYLINE: 8, 159 HIGHLIGHT: 9, 160 UNDERLINE: 10, 161 SQUIGGLY: 11, 162 STRIKEOUT: 12, 163 STAMP: 13, 164 CARET: 14, 165 INK: 15, 166 POPUP: 16, 167 FILEATTACHMENT: 17, 168 SOUND: 18, 169 MOVIE: 19, 170 WIDGET: 20, 171 SCREEN: 21, 172 PRINTERMARK: 22, 173 TRAPNET: 23, 174 WATERMARK: 24, 175 THREED: 25, 176 REDACT: 26 177}; 178exports.AnnotationType = AnnotationType; 179const AnnotationReplyType = { 180 GROUP: "Group", 181 REPLY: "R" 182}; 183exports.AnnotationReplyType = AnnotationReplyType; 184const AnnotationFlag = { 185 INVISIBLE: 0x01, 186 HIDDEN: 0x02, 187 PRINT: 0x04, 188 NOZOOM: 0x08, 189 NOROTATE: 0x10, 190 NOVIEW: 0x20, 191 READONLY: 0x40, 192 LOCKED: 0x80, 193 TOGGLENOVIEW: 0x100, 194 LOCKEDCONTENTS: 0x200 195}; 196exports.AnnotationFlag = AnnotationFlag; 197const AnnotationFieldFlag = { 198 READONLY: 0x0000001, 199 REQUIRED: 0x0000002, 200 NOEXPORT: 0x0000004, 201 MULTILINE: 0x0001000, 202 PASSWORD: 0x0002000, 203 NOTOGGLETOOFF: 0x0004000, 204 RADIO: 0x0008000, 205 PUSHBUTTON: 0x0010000, 206 COMBO: 0x0020000, 207 EDIT: 0x0040000, 208 SORT: 0x0080000, 209 FILESELECT: 0x0100000, 210 MULTISELECT: 0x0200000, 211 DONOTSPELLCHECK: 0x0400000, 212 DONOTSCROLL: 0x0800000, 213 COMB: 0x1000000, 214 RICHTEXT: 0x2000000, 215 RADIOSINUNISON: 0x2000000, 216 COMMITONSELCHANGE: 0x4000000 217}; 218exports.AnnotationFieldFlag = AnnotationFieldFlag; 219const AnnotationBorderStyleType = { 220 SOLID: 1, 221 DASHED: 2, 222 BEVELED: 3, 223 INSET: 4, 224 UNDERLINE: 5 225}; 226exports.AnnotationBorderStyleType = AnnotationBorderStyleType; 227const AnnotationActionEventType = { 228 E: "Mouse Enter", 229 X: "Mouse Exit", 230 D: "Mouse Down", 231 U: "Mouse Up", 232 Fo: "Focus", 233 Bl: "Blur", 234 PO: "PageOpen", 235 PC: "PageClose", 236 PV: "PageVisible", 237 PI: "PageInvisible", 238 K: "Keystroke", 239 F: "Format", 240 V: "Validate", 241 C: "Calculate" 242}; 243exports.AnnotationActionEventType = AnnotationActionEventType; 244const DocumentActionEventType = { 245 WC: "WillClose", 246 WS: "WillSave", 247 DS: "DidSave", 248 WP: "WillPrint", 249 DP: "DidPrint" 250}; 251exports.DocumentActionEventType = DocumentActionEventType; 252const PageActionEventType = { 253 O: "PageOpen", 254 C: "PageClose" 255}; 256exports.PageActionEventType = PageActionEventType; 257const VerbosityLevel = { 258 ERRORS: 0, 259 WARNINGS: 1, 260 INFOS: 5 261}; 262exports.VerbosityLevel = VerbosityLevel; 263const CMapCompressionType = { 264 NONE: 0, 265 BINARY: 1 266}; 267exports.CMapCompressionType = CMapCompressionType; 268const OPS = { 269 dependency: 1, 270 setLineWidth: 2, 271 setLineCap: 3, 272 setLineJoin: 4, 273 setMiterLimit: 5, 274 setDash: 6, 275 setRenderingIntent: 7,
276 setFlatness: 8, 277 setGState: 9, 278 save: 10, 279 restore: 11, 280 transform: 12, 281 moveTo: 13, 282 lineTo: 14, 283 curveTo: 15, 284 curveTo2: 16, 285 curveTo3: 17, 286 closePath: 18, 287 rectangle: 19, 288 stroke: 20, 289 closeStroke: 21, 290 fill: 22, 291 eoFill: 23, 292 fillStroke: 24, 293 eoFillStroke: 25, 294 closeFillStroke: 26, 295 closeEOFillStroke: 27, 296 endPath: 28, 297 clip: 29, 298 eoClip: 30, 299 beginText: 31, 300 endText: 32, 301 setCharSpacing: 33, 302 setWordSpacing: 34, 303 setHScale: 35, 304 setLeading: 36, 305 setFont: 37, 306 setTextRenderingMode: 38, 307 setTextRise: 39, 308 moveText: 40, 309 setLeadingMoveText: 41, 310 setTextMatrix: 42, 311 nextLine: 43, 312 showText: 44, 313 showSpacedText: 45, 314 nextLineShowText: 46, 315 nextLineSetSpacingShowText: 47, 316 setCharWidth: 48, 317 setCharWidthAndBounds: 49, 318 setStrokeColorSpace: 50, 319 setFillColorSpace: 51, 320 setStrokeColor: 52, 321 setStrokeColorN: 53, 322 setFillColor: 54, 323 setFillColorN: 55, 324 setStrokeGray: 56, 325 setFillGray: 57, 326 setStrokeRGBColor: 58, 327 setFillRGBColor: 59, 328 setStrokeCMYKColor: 60, 329 setFillCMYKColor: 61, 330 shadingFill: 62, 331 beginInlineImage: 63, 332 beginImageData: 64, 333 endInlineImage: 65, 334 paintXObject: 66, 335 markPoint: 67, 336 markPointProps: 68, 337 beginMarkedContent: 69, 338 beginMarkedContentProps: 70, 339 endMarkedContent: 71, 340 beginCompat: 72, 341 endCompat: 73, 342 paintFormXObjectBegin: 74, 343 paintFormXObjectEnd: 75, 344 beginGroup: 76, 345 endGroup: 77, 346 beginAnnotation: 80, 347 endAnnotation: 81, 348 paintImageMaskXObject: 83, 349 paintImageMaskXObjectGroup: 84, 350 paintImageXObject: 85, 351 paintInlineImageXObject: 86, 352 paintInlineImageXObjectGroup: 87, 353 paintImageXObjectRepeat: 88, 354 paintImageMaskXObjectRepeat: 89, 355 paintSolidColorImageMask: 90, 356 constructPath: 91 357}; 358exports.OPS = OPS; 359const PasswordResponses = { 360 NEED_PASSWORD: 1, 361 INCORRECT_PASSWORD: 2 362}; 363exports.PasswordResponses = PasswordResponses; 364let verbosity = VerbosityLevel.WARNINGS; 365function setVerbosityLevel(level) { 366 if (Number.isInteger(level)) { 367 verbosity = level; 368 } 369} 370function getVerbosityLevel() { 371 return verbosity; 372} 373function info(msg) { 374 if (verbosity >= VerbosityLevel.INFOS) { 375 console.log(`Info: ${msg}`); 376 } 377} 378function warn(msg) { 379 if (verbosity >= VerbosityLevel.WARNINGS) { 380 console.log(`Warning: ${msg}`); 381 } 382} 383function unreachable(msg) { 384 throw new Error(msg); 385} 386function assert(cond, msg) { 387 if (!cond) { 388 unreachable(msg); 389 } 390} 391function _isValidProtocol(url) { 392 switch (url?.protocol) { 393 case "http:": 394 case "https:": 395 case "ftp:": 396 case "mailto:": 397 case "tel:": 398 return true; 399 default: 400 return false; 401 } 402} 403function createValidAbsoluteUrl(url, baseUrl = null, options = null) { 404 if (!url) { 405 return null; 406 } 407 try { 408 if (options && typeof url === "string") { 409 if (options.addDefaultProtocol && url.startsWith("www.")) { 410 const dots = url.match(/\./g); 411 if (dots?.length >= 2) { 412 url = `http://${url}`; 413 } 414 } 415 if (options.tryConvertEncoding) { 416 try { 417 url = stringToUTF8String(url); 418 } catch {} 419 } 420 } 421 const absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url); 422 if (_isValidProtocol(absoluteUrl)) { 423 return absoluteUrl; 424 } 425 } catch {} 426 return null; 427} 428function shadow(obj, prop, value, nonSerializable = false) { 429 Object.defineProperty(obj, prop, { 430 value, 431 enumerable: !nonSerializable, 432 configurable: true, 433 writable: false 434 }); 435 return value; 436} 437const BaseException = function BaseExceptionClosure() { 438 function BaseException(message, name) { 439 if (this.constructor === BaseException) { 440 unreachable("Cannot initialize BaseException."); 441 } 442 this.message = message; 443 this.name = name; 444 } 445 BaseException.prototype = new Error(); 446 BaseException.constructor = BaseException; 447 return BaseException; 448}(); 449exports.BaseException = BaseException; 450class PasswordException extends BaseException { 451 constructor(msg, code) { 452 super(msg, "PasswordException"); 453 this.code = code; 454 } 455} 456exports.PasswordException = PasswordException; 457class UnknownErrorException extends BaseException { 458 constructor(msg, details) { 459 super(msg, "UnknownErrorException"); 460 this.details = details; 461 } 462} 463exports.UnknownErrorException = UnknownErrorException; 464class InvalidPDFException extends BaseException { 465 constructor(msg) { 466 super(msg, "InvalidPDFException"); 467 } 468} 469exports.InvalidPDFException = InvalidPDFException; 470class MissingPDFException extends BaseException { 471 constructor(msg) { 472 super(msg, "MissingPDFException"); 473 } 474} 475exports.MissingPDFException = MissingPDFException; 476class UnexpectedResponseException extends BaseException { 477 constructor(msg, status) { 478 super(msg, "UnexpectedResponseException"); 479 this.status = status; 480 } 481} 482exports.UnexpectedResponseException = UnexpectedResponseException; 483class FormatError extends BaseException { 484 constructor(msg) { 485 super(msg, "FormatError"); 486 } 487} 488exports.FormatError = FormatError; 489class AbortException extends BaseException { 490 constructor(msg) { 491 super(msg, "AbortException"); 492 } 493} 494exports.AbortException = AbortException; 495function bytesToString(bytes) { 496 if (typeof bytes !== "object" || bytes?.length === undefined) { 497 unreachable("Invalid argument for bytesToString"); 498 } 499 const length = bytes.length; 500 const MAX_ARGUMENT_COUNT = 8192; 501 if (length < MAX_ARGUMENT_COUNT) { 502 return String.fromCharCode.apply(null, bytes); 503 } 504 const strBuf = []; 505 for (let i = 0; i < length; i += MAX_ARGUMENT_COUNT) { 506 const chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length); 507 const chunk = bytes.subarray(i, chunkEnd); 508 strBuf.push(String.fromCharCode.apply(null, chunk)); 509 } 510 return strBuf.join(""); 511} 512function stringToBytes(str) { 513 if (typeof str !== "string") { 514 unreachable("Invalid argument for stringToBytes"); 515 } 516 const length = str.length; 517 const bytes = new Uint8Array(length); 518 for (let i = 0; i < length; ++i) { 519 bytes[i] = str.charCodeAt(i) & 0xff;
520 } 521 return bytes; 522} 523function string32(value) { 524 return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff); 525} 526function objectSize(obj) { 527 return Object.keys(obj).length; 528} 529function objectFromMap(map) { 530 const obj = Object.create(null); 531 for (const [key, value] of map) { 532 obj[key] = value; 533 } 534 return obj; 535} 536function isLittleEndian() { 537 const buffer8 = new Uint8Array(4); 538 buffer8[0] = 1; 539 const view32 = new Uint32Array(buffer8.buffer, 0, 1); 540 return view32[0] === 1; 541} 542function isEvalSupported() { 543 try { 544 new Function(""); 545 return true; 546 } catch { 547 return false; 548 } 549} 550class FeatureTest { 551 static get isLittleEndian() { 552 return shadow(this, "isLittleEndian", isLittleEndian()); 553 } 554 static get isEvalSupported() { 555 return shadow(this, "isEvalSupported", isEvalSupported()); 556 } 557 static get isOffscreenCanvasSupported() { 558 return shadow(this, "isOffscreenCanvasSupported", typeof OffscreenCanvas !== "undefined"); 559 } 560 static get platform() { 561 if (typeof navigator === "undefined") { 562 return shadow(this, "platform", { 563 isWin: false, 564 isMac: false 565 }); 566 } 567 return shadow(this, "platform", { 568 isWin: navigator.platform.includes("Win"), 569 isMac: navigator.platform.includes("Mac") 570 }); 571 } 572} 573exports.FeatureTest = FeatureTest; 574const hexNumbers = [...Array(256).keys()].map(n => n.toString(16).padStart(2, "0")); 575class Util { 576 static makeHexColor(r, g, b) { 577 return `#${hexNumbers[r]}${hexNumbers[g]}${hexNumbers[b]}`; 578 } 579 static scaleMinMax(transform, minMax) { 580 let temp; 581 if (transform[0]) { 582 if (transform[0] < 0) { 583 temp = minMax[0]; 584 minMax[0] = minMax[1]; 585 minMax[1] = temp; 586 } 587 minMax[0] *= transform[0]; 588 minMax[1] *= transform[0]; 589 if (transform[3] < 0) { 590 temp = minMax[2]; 591 minMax[2] = minMax[3]; 592 minMax[3] = temp; 593 } 594 minMax[2] *= transform[3]; 595 minMax[3] *= transform[3]; 596 } else { 597 temp = minMax[0]; 598 minMax[0] = minMax[2]; 599 minMax[2] = temp; 600 temp = minMax[1]; 601 minMax[1] = minMax[3]; 602 minMax[3] = temp; 603 if (transform[1] < 0) { 604 temp = minMax[2]; 605 minMax[2] = minMax[3]; 606 minMax[3] = temp; 607 } 608 minMax[2] *= transform[1]; 609 minMax[3] *= transform[1]; 610 if (transform[2] < 0) { 611 temp = minMax[0]; 612 minMax[0] = minMax[1]; 613 minMax[1] = temp; 614 } 615 minMax[0] *= transform[2]; 616 minMax[1] *= transform[2]; 617 } 618 minMax[0] += transform[4]; 619 minMax[1] += transform[4]; 620 minMax[2] += transform[5]; 621 minMax[3] += transform[5]; 622 } 623 static transform(m1, m2) { 624 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]]; 625 } 626 static applyTransform(p, m) { 627 const xt = p[0] * m[0] + p[1] * m[2] + m[4]; 628 const yt = p[0] * m[1] + p[1] * m[3] + m[5]; 629 return [xt, yt]; 630 } 631 static applyInverseTransform(p, m) { 632 const d = m[0] * m[3] - m[1] * m[2]; 633 const xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d; 634 const yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d; 635 return [xt, yt]; 636 } 637 static getAxialAlignedBoundingBox(r, m) { 638 const p1 = this.applyTransform(r, m); 639 const p2 = this.applyTransform(r.slice(2, 4), m); 640 const p3 = this.applyTransform([r[0], r[3]], m); 641 const p4 = this.applyTransform([r[2], r[1]], m); 642 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])]; 643 } 644 static inverseTransform(m) { 645 const d = m[0] * m[3] - m[1] * m[2]; 646 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]; 647 } 648 static singularValueDecompose2dScale(m) { 649 const transpose = [m[0], m[2], m[1], m[3]]; 650 const a = m[0] * transpose[0] + m[1] * transpose[2]; 651 const b = m[0] * transpose[1] + m[1] * transpose[3]; 652 const c = m[2] * transpose[0] + m[3] * transpose[2]; 653 const d = m[2] * transpose[1] + m[3] * transpose[3]; 654 const first = (a + d) / 2; 655 const second = Math.sqrt((a + d) ** 2 - 4 * (a * d - c * b)) / 2; 656 const sx = first + second || 1; 657 const sy = first - second || 1; 658 return [Math.sqrt(sx), Math.sqrt(sy)]; 659 } 660 static normalizeRect(rect) { 661 const r = rect.slice(0); 662 if (rect[0] > rect[2]) { 663 r[0] = rect[2]; 664 r[2] = rect[0]; 665 } 666 if (rect[1] > rect[3]) { 667 r[1] = rect[3]; 668 r[3] = rect[1]; 669 } 670 return r; 671 } 672 static intersect(rect1, rect2) { 673 const xLow = Math.max(Math.min(rect1[0], rect1[2]), Math.min(rect2[0], rect2[2])); 674 const xHigh = Math.min(Math.max(rect1[0], rect1[2]), Math.max(rect2[0], rect2[2])); 675 if (xLow > xHigh) { 676 return null; 677 } 678 const yLow = Math.max(Math.min(rect1[1], rect1[3]), Math.min(rect2[1], rect2[3])); 679 const yHigh = Math.min(Math.max(rect1[1], rect1[3]), Math.max(rect2[1], rect2[3])); 680 if (yLow > yHigh) { 681 return null; 682 } 683 return [xLow, yLow, xHigh, yHigh]; 684 } 685 static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3) { 686 const tvalues = [], 687 bounds = [[], []]; 688 let a, b, c, t, t1, t2, b2ac, sqrtb2ac; 689 for (let i = 0; i < 2; ++i) { 690 if (i === 0) { 691 b = 6 * x0 - 12 * x1 + 6 * x2; 692 a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; 693 c = 3 * x1 - 3 * x0; 694 } else { 695 b = 6 * y0 - 12 * y1 + 6 * y2; 696 a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; 697 c = 3 * y1 - 3 * y0; 698 } 699 if (Math.abs(a) < 1e-12) { 700 if (Math.abs(b) < 1e-12) { 701 continue; 702 } 703 t = -c / b; 704 if (0 < t && t < 1) { 705 tvalues.push(t); 706 } 707 continue; 708 } 709 b2ac = b * b - 4 * c * a; 710 sqrtb2ac = Math.sqrt(b2ac); 711 if (b2ac < 0) { 712 continue; 713 } 714 t1 = (-b + sqrtb2ac) / (2 * a); 715 if (0 < t1 && t1 < 1) { 716 tvalues.push(t1); 717 } 718 t2 = (-b - sqrtb2ac) / (2 * a); 719 if (0 < t2 && t2 < 1) { 720 tvalues.push(t2); 721 } 722 } 723 let j = tvalues.length, 724 mt; 725 const jlen = j; 726 while (j--) { 727 t = tvalues[j]; 728 mt = 1 - t; 729 bounds[0][j] = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3; 730 bounds[1][j] = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3; 731 } 732 bounds[0][jlen] = x0; 733 bounds[1][jlen] = y0; 734 bounds[0][jlen + 1] = x3; 735 bounds[1][jlen + 1] = y3; 736 bounds[0].length = bounds[1].length = jlen + 2; 737 return [Math.min(...bounds[0]), Math.min(...bounds[1]), Math.max(...bounds[0]), Math.max(...bounds[1])]; 738 } 739} 740exports.Util = Util; 741const 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]; 742function stringToPDFString(str) { 743 if (str[0] >= "\xEF") { 744 let encoding; 745 if (str[0] === "\xFE" && str[1] === "\xFF") { 746 encoding = "utf-16be"; 747 } else if (str[0] === "\xFF" && str[1] === "\xFE") { 748 encoding = "utf-16le"; 749 } else if (str[0] === "\xEF" && str[1] === "\xBB" && str[2] === "\xBF") { 750 encoding = "utf-8"; 751 } 752 if (encoding) {
753 try { 754 const decoder = new TextDecoder(encoding, { 755 fatal: true 756 }); 757 const buffer = stringToBytes(str); 758 return decoder.decode(buffer); 759 } catch (ex) { 760 warn(`stringToPDFString: "${ex}".`); 761 } 762 } 763 } 764 const strBuf = []; 765 for (let i = 0, ii = str.length; i < ii; i++) { 766 const code = PDFStringTranslateTable[str.charCodeAt(i)]; 767 strBuf.push(code ? String.fromCharCode(code) : str.charAt(i)); 768 } 769 return strBuf.join(""); 770} 771function stringToUTF8String(str) { 772 return decodeURIComponent(escape(str)); 773} 774function utf8StringToString(str) { 775 return unescape(encodeURIComponent(str)); 776} 777function isArrayBuffer(v) { 778 return typeof v === "object" && v?.byteLength !== undefined; 779} 780function isArrayEqual(arr1, arr2) { 781 if (arr1.length !== arr2.length) { 782 return false; 783 } 784 for (let i = 0, ii = arr1.length; i < ii; i++) { 785 if (arr1[i] !== arr2[i]) { 786 return false; 787 } 788 } 789 return true; 790} 791function getModificationDate(date = new Date()) { 792 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")]; 793 return buffer.join(""); 794} 795class PromiseCapability { 796 #settled = false; 797 constructor() { 798 this.promise = new Promise((resolve, reject) => { 799 this.resolve = data => { 800 this.#settled = true; 801 resolve(data); 802 }; 803 this.reject = reason => { 804 this.#settled = true; 805 reject(reason); 806 }; 807 }); 808 } 809 get settled() { 810 return this.#settled; 811 } 812} 813exports.PromiseCapability = PromiseCapability; 814let NormalizeRegex = null; 815let NormalizationMap = null; 816function normalizeUnicode(str) { 817 if (!NormalizeRegex) { 818 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; 819 NormalizationMap = new Map([["ſt", "ſt"]]); 820 } 821 return str.replaceAll(NormalizeRegex, (_, p1, p2) => { 822 return p1 ? p1.normalize("NFKC") : NormalizationMap.get(p2); 823 }); 824} 825function getUuid() { 826 if (typeof crypto !== "undefined" && typeof crypto?.randomUUID === "function") { 827 return crypto.randomUUID(); 828 } 829 const buf = new Uint8Array(32); 830 if (typeof crypto !== "undefined" && typeof crypto?.getRandomValues === "function") { 831 crypto.getRandomValues(buf); 832 } else { 833 for (let i = 0; i < 32; i++) { 834 buf[i] = Math.floor(Math.random() * 255); 835 } 836 } 837 return bytesToString(buf); 838} 839 840/***/ }), 841/* 2 */ 842/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 843 844 845 846Object.defineProperty(exports, "__esModule", ({ 847 value: true 848})); 849exports.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; 850Object.defineProperty(exports, "SVGGraphics", ({ 851 enumerable: true, 852 get: function () { 853 return _displaySvg.SVGGraphics; 854 } 855})); 856exports.build = void 0; 857exports.getDocument = getDocument; 858exports.version = void 0; 859var _util = __w_pdfjs_require__(1); 860var _annotation_storage = __w_pdfjs_require__(3); 861var _display_utils = __w_pdfjs_require__(6); 862var _font_loader = __w_pdfjs_require__(9); 863var _displayNode_utils = __w_pdfjs_require__(10); 864var _canvas = __w_pdfjs_require__(11); 865var _worker_options = __w_pdfjs_require__(14); 866var _message_handler = __w_pdfjs_require__(15); 867var _metadata = __w_pdfjs_require__(16); 868var _optional_content_config = __w_pdfjs_require__(17); 869var _transport_stream = __w_pdfjs_require__(18); 870var _displayFetch_stream = __w_pdfjs_require__(19); 871var _displayNetwork = __w_pdfjs_require__(22); 872var _displayNode_stream = __w_pdfjs_require__(23); 873var _displaySvg = __w_pdfjs_require__(24); 874var _xfa_text = __w_pdfjs_require__(25); 875const DEFAULT_RANGE_CHUNK_SIZE = 65536; 876const RENDERING_CANCELLED_TIMEOUT = 100; 877const DELAYED_CLEANUP_TIMEOUT = 5000; 878const DefaultCanvasFactory = _util.isNodeJS ? _displayNode_utils.NodeCanvasFactory : _display_utils.DOMCanvasFactory; 879exports.DefaultCanvasFactory = DefaultCanvasFactory; 880const DefaultCMapReaderFactory = _util.isNodeJS ? _displayNode_utils.NodeCMapReaderFactory : _display_utils.DOMCMapReaderFactory; 881exports.DefaultCMapReaderFactory = DefaultCMapReaderFactory; 882const DefaultFilterFactory = _util.isNodeJS ? _displayNode_utils.NodeFilterFactory : _display_utils.DOMFilterFactory; 883exports.DefaultFilterFactory = DefaultFilterFactory; 884const DefaultStandardFontDataFactory = _util.isNodeJS ? _displayNode_utils.NodeStandardFontDataFactory : _display_utils.DOMStandardFontDataFactory; 885exports.DefaultStandardFontDataFactory = DefaultStandardFontDataFactory; 886function getDocument(src) { 887 if (typeof src === "string" || src instanceof URL) { 888 src = { 889 url: src 890 }; 891 } else if ((0, _util.isArrayBuffer)(src)) { 892 src = { 893 data: src 894 }; 895 } 896 if (typeof src !== "object") { 897 throw new Error("Invalid parameter in getDocument, need parameter object."); 898 } 899 if (!src.url && !src.data && !src.range) { 900 throw new Error("Invalid parameter object: need either .data, .range or .url"); 901 } 902 const task = new PDFDocumentLoadingTask(); 903 const { 904 docId 905 } = task; 906 const url = src.url ? getUrlProp(src.url) : null; 907 const data = src.data ? getDataProp(src.data) : null; 908 const httpHeaders = src.httpHeaders || null; 909 const withCredentials = src.withCredentials === true; 910 const password = src.password ?? null; 911 const rangeTransport = src.range instanceof PDFDataRangeTransport ? src.range : null; 912 const rangeChunkSize = Number.isInteger(src.rangeChunkSize) && src.rangeChunkSize > 0 ? src.rangeChunkSize : DEFAULT_RANGE_CHUNK_SIZE; 913 let worker = src.worker instanceof PDFWorker ? src.worker : null; 914 const verbosity = src.verbosity; 915 const docBaseUrl = typeof src.docBaseUrl === "string" && !(0, _display_utils.isDataScheme)(src.docBaseUrl) ? src.docBaseUrl : null; 916 const cMapUrl = typeof src.cMapUrl === "string" ? src.cMapUrl : null; 917 const cMapPacked = src.cMapPacked !== false; 918 const CMapReaderFactory = src.CMapReaderFactory || DefaultCMapReaderFactory; 919 const standardFontDataUrl = typeof src.standardFontDataUrl === "string" ? src.standardFontDataUrl : null; 920 const StandardFontDataFactory = src.StandardFontDataFactory || DefaultStandardFontDataFactory; 921 const ignoreErrors = src.stopAtErrors !== true; 922 const maxImageSize = Number.isInteger(src.maxImageSize) && src.maxImageSize > -1 ? src.maxImageSize : -1; 923 const isEvalSupported = src.isEvalSupported !== false; 924 const isOffscreenCanvasSupported = typeof src.isOffscreenCanvasSupported === "boolean" ? src.isOffscreenCanvasSupported : !_util.isNodeJS; 925 const canvasMaxAreaInBytes = Number.isInteger(src.canvasMaxAreaInBytes) ? src.canvasMaxAreaInBytes :
925-1; 926 const disableFontFace = typeof src.disableFontFace === "boolean" ? src.disableFontFace : _util.isNodeJS; 927 const fontExtraProperties = src.fontExtraProperties === true; 928 const enableXfa = src.enableXfa === true; 929 const ownerDocument = src.ownerDocument || globalThis.document; 930 const disableRange = src.disableRange === true; 931 const disableStream = src.disableStream === true; 932 const disableAutoFetch = src.disableAutoFetch === true; 933 const pdfBug = src.pdfBug === true; 934 const length = rangeTransport ? rangeTransport.length : src.length ?? NaN; 935 const useSystemFonts = typeof src.useSystemFonts === "boolean" ? src.useSystemFonts : !_util.isNodeJS && !disableFontFace; 936 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); 937 const canvasFactory = src.canvasFactory || new DefaultCanvasFactory({ 938 ownerDocument 939 }); 940 const filterFactory = src.filterFactory || new DefaultFilterFactory({ 941 docId, 942 ownerDocument 943 }); 944 const styleElement = null; 945 (0, _util.setVerbosityLevel)(verbosity); 946 const transportFactory = { 947 canvasFactory, 948 filterFactory 949 }; 950 if (!useWorkerFetch) { 951 transportFactory.cMapReaderFactory = new CMapReaderFactory({ 952 baseUrl: cMapUrl, 953 isCompressed: cMapPacked 954 }); 955 transportFactory.standardFontDataFactory = new StandardFontDataFactory({ 956 baseUrl: standardFontDataUrl 957 }); 958 } 959 if (!worker) { 960 const workerParams = { 961 verbosity, 962 port: _worker_options.GlobalWorkerOptions.workerPort 963 }; 964 worker = workerParams.port ? PDFWorker.fromPort(workerParams) : new PDFWorker(workerParams); 965 task._worker = worker; 966 } 967 const fetchDocParams = { 968 docId, 969 apiVersion: '3.9.179', 970 data, 971 password, 972 disableAutoFetch, 973 rangeChunkSize, 974 length, 975 docBaseUrl, 976 enableXfa, 977 evaluatorOptions: { 978 maxImageSize, 979 disableFontFace, 980 ignoreErrors, 981 isEvalSupported, 982 isOffscreenCanvasSupported, 983 canvasMaxAreaInBytes, 984 fontExtraProperties, 985 useSystemFonts, 986 cMapUrl: useWorkerFetch ? cMapUrl : null, 987 standardFontDataUrl: useWorkerFetch ? standardFontDataUrl : null 988 } 989 }; 990 const transportParams = { 991 ignoreErrors, 992 isEvalSupported, 993 disableFontFace, 994 fontExtraProperties, 995 enableXfa, 996 ownerDocument, 997 disableAutoFetch, 998 pdfBug, 999 styleElement 1000 }; 1001 worker.promise.then(function () { 1002 if (task.destroyed) { 1003 throw new Error("Loading aborted"); 1004 } 1005 const workerIdPromise = _fetchDocument(worker, fetchDocParams); 1006 const networkStreamPromise = new Promise(function (resolve) { 1007 let networkStream; 1008 if (rangeTransport) { 1009 networkStream = new _transport_stream.PDFDataTransportStream({ 1010 length, 1011 initialData: rangeTransport.initialData, 1012 progressiveDone: rangeTransport.progressiveDone, 1013 contentDispositionFilename: rangeTransport.contentDispositionFilename, 1014 disableRange, 1015 disableStream 1016 }, rangeTransport); 1017 } else if (!data) { 1018 const createPDFNetworkStream = params => { 1019 if (_util.isNodeJS) { 1020 return new _displayNode_stream.PDFNodeStream(params); 1021 } 1022 return (0, _display_utils.isValidFetchUrl)(params.url) ? new _displayFetch_stream.PDFFetchStream(params) : new _displayNetwork.PDFNetworkStream(params); 1023 }; 1024 networkStream = createPDFNetworkStream({ 1025 url, 1026 length, 1027 httpHeaders, 1028 withCredentials, 1029 rangeChunkSize, 1030 disableRange, 1031 disableStream 1032 }); 1033 } 1034 resolve(networkStream); 1035 }); 1036 return Promise.all([workerIdPromise, networkStreamPromise]).then(function ([workerId, networkStream]) { 1037 if (task.destroyed) { 1038 throw new Error("Loading aborted"); 1039 } 1040 const messageHandler = new _message_handler.MessageHandler(docId, workerId, worker.port); 1041 const transport = new WorkerTransport(messageHandler, task, networkStream, transportParams, transportFactory); 1042 task._transport = transport; 1043 messageHandler.send("Ready", null); 1044 }); 1045 }).catch(task._capability.reject); 1046 return task; 1047} 1048async function _fetchDocument(worker, source) { 1049 if (worker.destroyed) { 1050 throw new Error("Worker was destroyed"); 1051 }
1052 const workerId = await worker.messageHandler.sendWithPromise("GetDocRequest", source, source.data ? [source.data.buffer] : null); 1053 if (worker.destroyed) { 1054 throw new Error("Worker was destroyed"); 1055 } 1056 return workerId; 1057} 1058function getUrlProp(val) { 1059 if (val instanceof URL) { 1060 return val.href; 1061 } 1062 try { 1063 return new URL(val, window.location).href; 1064 } catch { 1065 if (_util.isNodeJS && typeof val === "string") { 1066 return val; 1067 } 1068 } 1069 throw new Error("Invalid PDF url data: " + "either string or URL-object is expected in the url property."); 1070} 1071function getDataProp(val) { 1072 if (_util.isNodeJS && typeof Buffer !== "undefined" && val instanceof Buffer) { 1073 throw new Error("Please provide binary data as `Uint8Array`, rather than `Buffer`."); 1074 } 1075 if (val instanceof Uint8Array && val.byteLength === val.buffer.byteLength) { 1076 return val; 1077 } 1078 if (typeof val === "string") { 1079 return (0, _util.stringToBytes)(val); 1080 } 1081 if (typeof val === "object" && !isNaN(val?.length) || (0, _util.isArrayBuffer)(val)) { 1082 return new Uint8Array(val); 1083 } 1084 throw new Error("Invalid PDF binary data: either TypedArray, " + "string, or array-like object is expected in the data property."); 1085} 1086class PDFDocumentLoadingTask { 1087 static #docId = 0; 1088 constructor() { 1089 this._capability = new _util.PromiseCapability(); 1090 this._transport = null; 1091 this._worker = null; 1092 this.docId = `d${PDFDocumentLoadingTask.#docId++}`; 1093 this.destroyed = false; 1094 this.onPassword = null; 1095 this.onProgress = null; 1096 } 1097 get promise() { 1098 return this._capability.promise; 1099 } 1100 async destroy() { 1101 this.destroyed = true; 1102 await this._transport?.destroy(); 1103 this._transport = null; 1104 if (this._worker) { 1105 this._worker.destroy(); 1106 this._worker = null; 1107 } 1108 } 1109} 1110exports.PDFDocumentLoadingTask = PDFDocumentLoadingTask; 1111class PDFDataRangeTransport { 1112 constructor(length, initialData, progressiveDone = false, contentDispositionFilename = null) { 1113 this.length = length; 1114 this.initialData = initialData; 1115 this.progressiveDone = progressiveDone; 1116 this.contentDispositionFilename = contentDispositionFilename; 1117 this._rangeListeners = []; 1118 this._progressListeners = []; 1119 this._progressiveReadListeners = []; 1120 this._progressiveDoneListeners = []; 1121 this._readyCapability = new _util.PromiseCapability(); 1122 } 1123 addRangeListener(listener) { 1124 this._rangeListeners.push(listener); 1125 } 1126 addProgressListener(listener) { 1127 this._progressListeners.push(listener); 1128 } 1129 addProgressiveReadListener(listener) { 1130 this._progressiveReadListeners.push(listener); 1131 } 1132 addProgressiveDoneListener(listener) { 1133 this._progressiveDoneListeners.push(listener); 1134 } 1135 onDataRange(begin, chunk) { 1136 for (const listener of this._rangeListeners) { 1137 listener(begin, chunk); 1138 } 1139 } 1140 onDataProgress(loaded, total) { 1141 this._readyCapability.promise.then(() => { 1142 for (const listener of this._progressListeners) { 1143 listener(loaded, total); 1144 } 1145 }); 1146 } 1147 onDataProgressiveRead(chunk) { 1148 this._readyCapability.promise.then(() => { 1149 for (const listener of this._progressiveReadListeners) { 1150 listener(chunk); 1151 } 1152 }); 1153 } 1154 onDataProgressiveDone() { 1155 this._readyCapability.promise.then(() => { 1156 for (const listener of this._progressiveDoneListeners) { 1157 listener(); 1158 } 1159 }); 1160 } 1161 transportReady() { 1162 this._readyCapability.resolve(); 1163 } 1164 requestDataRange(begin, end) { 1165 (0, _util.unreachable)("Abstract method PDFDataRangeTransport.requestDataRange"); 1166 } 1167 abort() {} 1168} 1169exports.PDFDataRangeTransport = PDFDataRangeTransport; 1170class PDFDocumentProxy { 1171 constructor(pdfInfo, transport) { 1172 this._pdfInfo = pdfInfo; 1173 this._transport = transport; 1174 } 1175 get annotationStorage() { 1176 return this._transport.annotationStorage; 1177 } 1178 get filterFactory() { 1179 return this._transport.filterFactory; 1180 } 1181 get numPages() { 1182 return this._pdfInfo.numPages; 1183 } 1184 get fingerprints() { 1185 return this._pdfInfo.fingerprints; 1186 } 1187 get isPureXfa() { 1188 return (0, _util.shadow)(this, "isPureXfa", !!this._transport._htmlForXfa); 1189 } 1190 get allXfaHtml() { 1191 return this._transport._htmlForXfa; 1192 } 1193 getPage(pageNumber) { 1194 return this._transport.getPage(pageNumber); 1195 } 1196 getPageIndex(ref) { 1197 return this._transport.getPageIndex(ref); 1198 } 1199 getDestinations() { 1200 return this._transport.getDestinations(); 1201 } 1202 getDestination(id) { 1203 return this._transport.getDestination(id); 1204 } 1205 getPageLabels() { 1206 return this._transport.getPageLabels(); 1207 } 1208 getPageLayout() { 1209 return this._transport.getPageLayout(); 1210 } 1211 getPageMode() { 1212 return this._transport.getPageMode(); 1213 } 1214 getViewerPreferences() { 1215 return this._transport.getViewerPreferences(); 1216 } 1217 getOpenAction() { 1218 return this._transport.getOpenAction(); 1219 } 1220 getAttachments() { 1221 return this._transport.getAttachments(); 1222 } 1223 getJavaScript() { 1224 return this._transport.getJavaScript(); 1225 } 1226 getJSActions() { 1227 return this._transport.getDocJSActions(); 1228 } 1229 getOutline() { 1230 return this._transport.getOutline(); 1231 } 1232 getOptionalContentConfig() { 1233 return this._transport.getOptionalContentConfig(); 1234 } 1235 getPermissions() { 1236 return this._transport.getPermissions(); 1237 } 1238 getMetadata() { 1239 return this._transport.getMetadata(); 1240 } 1241 getMarkInfo() { 1242 return this._transport.getMarkInfo(); 1243 } 1244 getData() { 1245 return this._transport.getData(); 1246 } 1247 saveDocument() { 1248 return this._transport.saveDocument(); 1249 } 1250 getDownloadInfo() { 1251 return this._transport.downloadInfoCapability.promise; 1252 } 1253 cleanup(keepLoadedFonts = false) { 1254 return this._transport.startCleanup(keepLoadedFonts || this.isPureXfa); 1255 } 1256 destroy() { 1257 return this.loadingTask.destroy(); 1258 } 1259 get loadingParams() { 1260 return this._transport.loadingParams; 1261 } 1262 get loadingTask() { 1263 return this._transport.loadingTask; 1264 } 1265 getFieldObjects() { 1266 return this._transport.getFieldObjects(); 1267 } 1268 hasJSActions() { 1269 return this._transport.hasJSActions(); 1270 } 1271 getCalculationOrderIds() { 1272 return this._transport.getCalculationOrderIds(); 1273 } 1274} 1275exports.PDFDocumentProxy = PDFDocumentProxy; 1276class PDFPageProxy { 1277 #delayedCleanupTimeout = null; 1278 #pendingCleanup = false;
1279 constructor(pageIndex, pageInfo, transport, pdfBug = false) { 1280 this._pageIndex = pageIndex; 1281 this._pageInfo = pageInfo; 1282 this._transport = transport; 1283 this._stats = pdfBug ? new _display_utils.StatTimer() : null; 1284 this._pdfBug = pdfBug; 1285 this.commonObjs = transport.commonObjs; 1286 this.objs = new PDFObjects(); 1287 this._maybeCleanupAfterRender = false; 1288 this._intentStates = new Map(); 1289 this.destroyed = false; 1290 } 1291 get pageNumber() { 1292 return this._pageIndex + 1; 1293 } 1294 get rotate() { 1295 return this._pageInfo.rotate; 1296 } 1297 get ref() { 1298 return this._pageInfo.ref; 1299 } 1300 get userUnit() { 1301 return this._pageInfo.userUnit; 1302 } 1303 get view() { 1304 return this._pageInfo.view; 1305 } 1306 getViewport({ 1307 scale, 1308 rotation = this.rotate, 1309 offsetX = 0, 1310 offsetY = 0, 1311 dontFlip = false 1312 } = {}) { 1313 return new _display_utils.PageViewport({ 1314 viewBox: this.view, 1315 scale, 1316 rotation, 1317 offsetX, 1318 offsetY, 1319 dontFlip 1320 }); 1321 } 1322 getAnnotations({ 1323 intent = "display" 1324 } = {}) { 1325 const intentArgs = this._transport.getRenderingIntent(intent); 1326 return this._transport.getAnnotations(this._pageIndex, intentArgs.renderingIntent); 1327 } 1328 getJSActions() { 1329 return this._transport.getPageJSActions(this._pageIndex); 1330 } 1331 get filterFactory() { 1332 return this._transport.filterFactory; 1333 } 1334 get isPureXfa() { 1335 return (0, _util.shadow)(this, "isPureXfa", !!this._transport._htmlForXfa); 1336 } 1337 async getXfa() { 1338 return this._transport._htmlForXfa?.children[this._pageIndex] || null; 1339 } 1340 render({ 1341 canvasContext, 1342 viewport, 1343 intent = "display", 1344 annotationMode = _util.AnnotationMode.ENABLE, 1345 transform = null, 1346 background = null, 1347 optionalContentConfigPromise = null, 1348 annotationCanvasMap = null, 1349 pageColors = null, 1350 printAnnotationStorage = null 1351 }) { 1352 this._stats?.time("Overall"); 1353 const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage); 1354 this.#pendingCleanup = false; 1355 this.#abortDelayedCleanup(); 1356 if (!optionalContentConfigPromise) { 1357 optionalContentConfigPromise = this._transport.getOptionalContentConfig(); 1358 } 1359 let intentState = this._intentStates.get(intentArgs.cacheKey); 1360 if (!intentState) { 1361 intentState = Object.create(null); 1362 this._intentStates.set(intentArgs.cacheKey, intentState); 1363 } 1364 if (intentState.streamReaderCancelTimeout) { 1365 clearTimeout(intentState.streamReaderCancelTimeout); 1366 intentState.streamReaderCancelTimeout = null; 1367 } 1368 const intentPrint = !!(intentArgs.renderingIntent & _util.RenderingIntentFlag.PRINT); 1369 if (!intentState.displayReadyCapability) { 1370 intentState.displayReadyCapability = new _util.PromiseCapability(); 1371 intentState.operatorList = { 1372 fnArray: [], 1373 argsArray: [], 1374 lastChunk: false, 1375 separateAnnots: null 1376 }; 1377 this._stats?.time("Page Request"); 1378 this._pumpOperatorList(intentArgs); 1379 } 1380 const complete = error => { 1381 intentState.renderTasks.delete(internalRenderTask); 1382 if (this._maybeCleanupAfterRender || intentPrint) { 1383 this.#pendingCleanup = true; 1384 } 1385 this.#tryCleanup(!intentPrint); 1386 if (error) { 1387 internalRenderTask.capability.reject(error); 1388 this._abortOperatorList({ 1389 intentState, 1390 reason: error instanceof Error ? error : new Error(error) 1391 }); 1392 } else { 1393 internalRenderTask.capability.resolve(); 1394 } 1395 this._stats?.timeEnd("Rendering"); 1396 this._stats?.timeEnd("Overall"); 1397 }; 1398 const internalRenderTask = new InternalRenderTask({ 1399 callback: complete, 1400 params: { 1401 canvasContext, 1402 viewport, 1403 transform, 1404 background 1405 }, 1406 objs: this.objs, 1407 commonObjs: this.commonObjs, 1408 annotationCanvasMap, 1409 operatorList: intentState.operatorList, 1410 pageIndex: this._pageIndex, 1411 canvasFactory: this._transport.canvasFactory, 1412 filterFactory: this._transport.filterFactory, 1413 useRequestAnimationFrame: !intentPrint, 1414 pdfBug: this._pdfBug, 1415 pageColors 1416 }); 1417 (intentState.renderTasks ||= new Set()).add(internalRenderTask); 1418 const renderTask = internalRenderTask.task; 1419 Promise.all([intentState.displayReadyCapability.promise, optionalContentConfigPromise]).then(([transparency, optionalContentConfig]) => { 1420 if (this.destroyed) { 1421 complete(); 1422 return; 1423 }
1424 this._stats?.time("Rendering"); 1425 internalRenderTask.initializeGraphics({ 1426 transparency, 1427 optionalContentConfig 1428 }); 1429 internalRenderTask.operatorListChanged(); 1430 }).catch(complete); 1431 return renderTask; 1432 } 1433 getOperatorList({ 1434 intent = "display", 1435 annotationMode = _util.AnnotationMode.ENABLE, 1436 printAnnotationStorage = null 1437 } = {}) { 1438 function operatorListChanged() { 1439 if (intentState.operatorList.lastChunk) { 1440 intentState.opListReadCapability.resolve(intentState.operatorList); 1441 intentState.renderTasks.delete(opListTask); 1442 } 1443 } 1444 const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage, true); 1445 let intentState = this._intentStates.get(intentArgs.cacheKey); 1446 if (!intentState) { 1447 intentState = Object.create(null); 1448 this._intentStates.set(intentArgs.cacheKey, intentState); 1449 } 1450 let opListTask; 1451 if (!intentState.opListReadCapability) { 1452 opListTask = Object.create(null); 1453 opListTask.operatorListChanged = operatorListChanged; 1454 intentState.opListReadCapability = new _util.PromiseCapability(); 1455 (intentState.renderTasks ||= new Set()).add(opListTask); 1456 intentState.operatorList = { 1457 fnArray: [], 1458 argsArray: [], 1459 lastChunk: false, 1460 separateAnnots: null 1461 }; 1462 this._stats?.time("Page Request"); 1463 this._pumpOperatorList(intentArgs); 1464 } 1465 return intentState.opListReadCapability.promise; 1466 } 1467 streamTextContent({ 1468 includeMarkedContent = false, 1469 disableNormalization = false 1470 } = {}) { 1471 const TEXT_CONTENT_CHUNK_SIZE = 100; 1472 return this._transport.messageHandler.sendWithStream("GetTextContent", { 1473 pageIndex: this._pageIndex, 1474 includeMarkedContent: includeMarkedContent === true, 1475 disableNormalization: disableNormalization === true 1476 }, { 1477 highWaterMark: TEXT_CONTENT_CHUNK_SIZE, 1478 size(textContent) { 1479 return textContent.items.length; 1480 } 1481 }); 1482 } 1483 getTextContent(params = {}) { 1484 if (this._transport._htmlForXfa) { 1485 return this.getXfa().then(xfa => { 1486 return _xfa_text.XfaText.textContent(xfa); 1487 }); 1488 } 1489 const readableStream = this.streamTextContent(params); 1490 return new Promise(function (resolve, reject) { 1491 function pump() { 1492 reader.read().then(function ({ 1493 value, 1494 done 1495 }) { 1496 if (done) { 1497 resolve(textContent); 1498 return; 1499 } 1500 Object.assign(textContent.styles, value.styles); 1501 textContent.items.push(...value.items); 1502 pump(); 1503 }, reject); 1504 } 1505 const reader = readableStream.getReader(); 1506 const textContent = { 1507 items: [], 1508 styles: Object.create(null) 1509 }; 1510 pump(); 1511 }); 1512 } 1513 getStructTree() { 1514 return this._transport.getStructTree(this._pageIndex); 1515 } 1516 _destroy() { 1517 this.destroyed = true; 1518 const waitOn = []; 1519 for (const intentState of this._intentStates.values()) { 1520 this._abortOperatorList({ 1521 intentState, 1522 reason: new Error("Page was destroyed."), 1523 force: true 1524 }); 1525 if (intentState.opListReadCapability) { 1526 continue; 1527 } 1528 for (const internalRenderTask of intentState.renderTasks) { 1529 waitOn.push(internalRenderTask.completed); 1530 internalRenderTask.cancel(); 1531 } 1532 } 1533 this.objs.clear(); 1534 this.#pendingCleanup = false; 1535 this.#abortDelayedCleanup(); 1536 return Promise.all(waitOn); 1537 } 1538 cleanup(resetStats = false) { 1539 this.#pendingCleanup = true; 1540 const success = this.#tryCleanup(false); 1541 if (resetStats && success) { 1542 this._stats &&= new _display_utils.StatTimer(); 1543 } 1544 return success; 1545 } 1546 #tryCleanup(delayed = false) { 1547 this.#abortDelayedCleanup(); 1548 if (!this.#pendingCleanup || this.destroyed) { 1549 return false; 1550 } 1551 if (delayed) { 1552 this.#delayedCleanupTimeout = setTimeout(() => { 1553 this.#delayedCleanupTimeout = null; 1554 this.#tryCleanup(false); 1555 }, DELAYED_CLEANUP_TIMEOUT); 1556 return false;
1557 } 1558 for (const { 1559 renderTasks, 1560 operatorList 1561 } of this._intentStates.values()) { 1562 if (renderTasks.size > 0 || !operatorList.lastChunk) { 1563 return false; 1564 } 1565 } 1566 this._intentStates.clear(); 1567 this.objs.clear(); 1568 this.#pendingCleanup = false; 1569 return true; 1570 } 1571 #abortDelayedCleanup() { 1572 if (this.#delayedCleanupTimeout) { 1573 clearTimeout(this.#delayedCleanupTimeout); 1574 this.#delayedCleanupTimeout = null; 1575 } 1576 } 1577 _startRenderPage(transparency, cacheKey) { 1578 const intentState = this._intentStates.get(cacheKey); 1579 if (!intentState) { 1580 return; 1581 } 1582 this._stats?.timeEnd("Page Request"); 1583 intentState.displayReadyCapability?.resolve(transparency); 1584 } 1585 _renderPageChunk(operatorListChunk, intentState) { 1586 for (let i = 0, ii = operatorListChunk.length; i < ii; i++) { 1587 intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]); 1588 intentState.operatorList.argsArray.push(operatorListChunk.argsArray[i]); 1589 } 1590 intentState.operatorList.lastChunk = operatorListChunk.lastChunk; 1591 intentState.operatorList.separateAnnots = operatorListChunk.separateAnnots; 1592 for (const internalRenderTask of intentState.renderTasks) { 1593 internalRenderTask.operatorListChanged(); 1594 } 1595 if (operatorListChunk.lastChunk) { 1596 this.#tryCleanup(true); 1597 } 1598 } 1599 _pumpOperatorList({ 1600 renderingIntent, 1601 cacheKey, 1602 annotationStorageSerializable 1603 }) { 1604 const { 1605 map, 1606 transfers 1607 } = annotationStorageSerializable; 1608 const readableStream = this._transport.messageHandler.sendWithStream("GetOperatorList", { 1609 pageIndex: this._pageIndex, 1610 intent: renderingIntent, 1611 cacheKey, 1612 annotationStorage: map 1613 }, transfers); 1614 const reader = readableStream.getReader(); 1615 const intentState = this._intentStates.get(cacheKey); 1616 intentState.streamReader = reader; 1617 const pump = () => { 1618 reader.read().then(({ 1619 value, 1620 done 1621 }) => { 1622 if (done) { 1623 intentState.streamReader = null; 1624 return; 1625 } 1626 if (this._transport.destroyed) { 1627 return; 1628 } 1629 this._renderPageChunk(value, intentState); 1630 pump(); 1631 }, reason => { 1632 intentState.streamReader = null; 1633 if (this._transport.destroyed) { 1634 return; 1635 } 1636 if (intentState.operatorList) { 1637 intentState.operatorList.lastChunk = true; 1638 for (const internalRenderTask of intentState.renderTasks) { 1639 internalRenderTask.operatorListChanged(); 1640 } 1641 this.#tryCleanup(true); 1642 } 1643 if (intentState.displayReadyCapability) { 1644 intentState.displayReadyCapability.reject(reason); 1645 } else if (intentState.opListReadCapability) { 1646 intentState.opListReadCapability.reject(reason); 1647 } else { 1648 throw reason; 1649 } 1650 }); 1651 }; 1652 pump(); 1653 } 1654 _abortOperatorList({ 1655 intentState, 1656 reason, 1657 force = false 1658 }) { 1659 if (!intentState.streamReader) { 1660 return; 1661 } 1662 if (intentState.streamReaderCancelTimeout) { 1663 clearTimeout(intentState.streamReaderCancelTimeout); 1664 intentState.streamReaderCancelTimeout = null; 1665 } 1666 if (!force) { 1667 if (intentState.renderTasks.size > 0) { 1668 return; 1669 } 1670 if (reason instanceof _display_utils.RenderingCancelledException) { 1671 let delay = RENDERING_CANCELLED_TIMEOUT; 1672 if (reason.extraDelay > 0 && reason.extraDelay < 1000) { 1673 delay += reason.extraDelay; 1674 } 1675 intentState.streamReaderCancelTimeout = setTimeout(() => { 1676 intentState.streamReaderCancelTimeout = null; 1677 this._abortOperatorList({ 1678 intentState, 1679 reason, 1680 force: true 1681 }); 1682 }, delay); 1683 return; 1684 } 1685 } 1686 intentState.streamReader.cancel(new _util.AbortException(reason.message)).catch(() => {}); 1687 intentState.streamReader = null; 1688 if (this._transport.destroyed) { 1689 return; 1690 } 1691 for (const [curCacheKey, curIntentState] of this._intentStates) { 1692 if (curIntentState === intentState) { 1693 this._intentStates.delete(curCacheKey); 1694 break; 1695 } 1696 } 1697 this.cleanup(); 1698 } 1699 get stats() { 1700 return this._stats; 1701 } 1702} 1703exports.PDFPageProxy = PDFPageProxy; 1704class LoopbackPort { 1705 #listeners = new Set(); 1706 #deferred = Promise.resolve(); 1707 postMessage(obj, transfer) { 1708 const event = { 1709 data: structuredClone(obj, transfer ? { 1710 transfer 1711 } : null) 1712 }; 1713 this.#deferred.then(() => { 1714 for (const listener of this.#listeners) { 1715 listener.call(this, event); 1716 } 1717 }); 1718 } 1719 addEventListener(name, listener) { 1720 this.#listeners.add(listener); 1721 } 1722 removeEventListener(name, listener) { 1723 this.#listeners.delete(listener); 1724 } 1725 terminate() { 1726 this.#listeners.clear(); 1727 } 1728} 1729exports.LoopbackPort = LoopbackPort; 1730const PDFWorkerUtil = { 1731 isWorkerDisabled: false, 1732 fallbackWorkerSrc: null, 1733 fakeWorkerId: 0 1734}; 1735exports.PDFWorkerUtil = PDFWorkerUtil; 1736{ 1737 if (_util.isNodeJS && typeof require === "function") { 1738 PDFWorkerUtil.isWorkerDisabled = true; 1739 PDFWorkerUtil.fallbackWorkerSrc = "./pdf.worker.js"; 1740 } else if (typeof document === "object") { 1741 const pdfjsFilePath = document?.currentScript?.src; 1742 if (pdfjsFilePath) { 1743 PDFWorkerUtil.fallbackWorkerSrc = pdfjsFilePath.replace(/(\.(?:min\.)?js)(\?.*)?$/i, ".w
1743orker$1$2"); 1744 } 1745 } 1746 PDFWorkerUtil.isSameOrigin = function (baseUrl, otherUrl) { 1747 let base; 1748 try { 1749 base = new URL(baseUrl); 1750 if (!base.origin || base.origin === "null") { 1751 return false; 1752 } 1753 } catch { 1754 return false; 1755 } 1756 const other = new URL(otherUrl, base); 1757 return base.origin === other.origin; 1758 }; 1759 PDFWorkerUtil.createCDNWrapper = function (url) { 1760 const wrapper = `importScripts("${url}");`; 1761 return URL.createObjectURL(new Blob([wrapper])); 1762 }; 1763} 1764class PDFWorker { 1765 static #workerPorts = new WeakMap(); 1766 constructor({ 1767 name = null, 1768 port = null, 1769 verbosity = (0, _util.getVerbosityLevel)() 1770 } = {}) { 1771 if (port && PDFWorker.#workerPorts.has(port)) { 1772 throw new Error("Cannot use more than one PDFWorker per port."); 1773 } 1774 this.name = name; 1775 this.destroyed = false; 1776 this.verbosity = verbosity; 1777 this._readyCapability = new _util.PromiseCapability(); 1778 this._port = null; 1779 this._webWorker = null; 1780 this._messageHandler = null; 1781 if (port) { 1782 PDFWorker.#workerPorts.set(port, this); 1783 this._initializeFromPort(port); 1784 return; 1785 } 1786 this._initialize(); 1787 } 1788 get promise() { 1789 return this._readyCapability.promise; 1790 } 1791 get port() { 1792 return this._port; 1793 } 1794 get messageHandler() { 1795 return this._messageHandler; 1796 } 1797 _initializeFromPort(port) { 1798 this._port = port; 1799 this._messageHandler = new _message_handler.MessageHandler("main", "worker", port); 1800 this._messageHandler.on("ready", function () {}); 1801 this._readyCapability.resolve(); 1802 this._messageHandler.send("configure", { 1803 verbosity: this.verbosity 1804 }); 1805 } 1806 _initialize() { 1807 if (!PDFWorkerUtil.isWorkerDisabled && !PDFWorker._mainThreadWorkerMessageHandler) { 1808 let { 1809 workerSrc 1810 } = PDFWorker; 1811 try { 1812 if (!PDFWorkerUtil.isSameOrigin(window.location.href, workerSrc)) { 1813 workerSrc = PDFWorkerUtil.createCDNWrapper(new URL(workerSrc, window.location).href); 1814 } 1815 const worker = new Worker(workerSrc); 1816 const messageHandler = new _message_handler.MessageHandler("main", "worker", worker); 1817 const terminateEarly = () => { 1818 worker.removeEventListener("error", onWorkerError); 1819 messageHandler.destroy(); 1820 worker.terminate(); 1821 if (this.destroyed) { 1822 this._readyCapability.reject(new Error("Worker was destroyed")); 1823 } else { 1824 this._setupFakeWorker(); 1825 } 1826 }; 1827 const onWorkerError = () => { 1828 if (!this._webWorker) { 1829 terminateEarly(); 1830 } 1831 }; 1832 worker.addEventListener("error", onWorkerError); 1833 messageHandler.on("test", data => { 1834 worker.removeEventListener("error", onWorkerError); 1835 if (this.destroyed) { 1836 terminateEarly(); 1837 return; 1838 } 1839 if (data) { 1840 this._messageHandler = messageHandler; 1841 this._port = worker; 1842 this._webWorker = worker; 1843 this._readyCapability.resolve(); 1844 messageHandler.send("configure", { 1845 verbosity: this.verbosity 1846 }); 1847 } else { 1848 this._setupFakeWorker(); 1849 messageHandler.destroy(); 1850 worker.terminate(); 1851 } 1852 }); 1853 messageHandler.on("ready", data => { 1854 worker.removeEventListener("error", onWorkerError); 1855 if (this.destroyed) { 1856 terminateEarly(); 1857 return; 1858 } 1859 try { 1860 sendTest(); 1861 } catch { 1862 this._setupFakeWorker(); 1863 } 1864 }); 1865 const sendTest = () => { 1866 const testObj = new Uint8Array(); 1867 messageHandler.send("test", testObj, [testObj.buffer]); 1868 }; 1869 sendTest(); 1870 return; 1871 } catch { 1872 (0, _util.info)("The worker has been disabled."); 1873 } 1874 } 1875 this._setupFakeWorker(); 1876 } 1877 _setupFakeWorker() { 1878 if (!PDFWorkerUtil.isWorkerDisabled) { 1879 (0, _util.warn)("Setting up fake worker."); 1880 PDFWorkerUtil.isWorkerDisabled = true; 1881 } 1882 PDFWorker._setupFakeWorkerGlobal.then(WorkerMessageHandler => { 1883 if (this.destroyed) { 1884 this._readyCapability.reject(new Error("Worker was destroyed")); 1885 return; 1886 } 1887 const port = new LoopbackPort(); 1888 this._port = port;
1889 const id = `fake${PDFWorkerUtil.fakeWorkerId++}`; 1890 const workerHandler = new _message_handler.MessageHandler(id + "_worker", id, port); 1891 WorkerMessageHandler.setup(workerHandler, port); 1892 const messageHandler = new _message_handler.MessageHandler(id, id + "_worker", port); 1893 this._messageHandler = messageHandler; 1894 this._readyCapability.resolve(); 1895 messageHandler.send("configure", { 1896 verbosity: this.verbosity 1897 }); 1898 }).catch(reason => { 1899 this._readyCapability.reject(new Error(`Setting up fake worker failed: "${reason.message}".`)); 1900 }); 1901 } 1902 destroy() { 1903 this.destroyed = true; 1904 if (this._webWorker) { 1905 this._webWorker.terminate(); 1906 this._webWorker = null; 1907 } 1908 PDFWorker.#workerPorts.delete(this._port); 1909 this._port = null; 1910 if (this._messageHandler) { 1911 this._messageHandler.destroy(); 1912 this._messageHandler = null; 1913 } 1914 } 1915 static fromPort(params) { 1916 if (!params?.port) { 1917 throw new Error("PDFWorker.fromPort - invalid method signature."); 1918 } 1919 if (this.#workerPorts.has(params.port)) { 1920 return this.#workerPorts.get(params.port); 1921 } 1922 return new PDFWorker(params); 1923 } 1924 static get workerSrc() { 1925 if (_worker_options.GlobalWorkerOptions.workerSrc) { 1926 return _worker_options.GlobalWorkerOptions.workerSrc; 1927 } 1928 if (PDFWorkerUtil.fallbackWorkerSrc !== null) { 1929 if (!_util.isNodeJS) { 1930 (0, _display_utils.deprecated)('No "GlobalWorkerOptions.workerSrc" specified.'); 1931 } 1932 return PDFWorkerUtil.fallbackWorkerSrc; 1933 } 1934 throw new Error('No "GlobalWorkerOptions.workerSrc" specified.'); 1935 } 1936 static get _mainThreadWorkerMessageHandler() { 1937 try { 1938 return globalThis.pdfjsWorker?.WorkerMessageHandler || null; 1939 } catch { 1940 return null; 1941 } 1942 } 1943 static get _setupFakeWorkerGlobal() { 1944 const loader = async () => { 1945 const mainWorkerMessageHandler = this._mainThreadWorkerMessageHandler; 1946 if (mainWorkerMessageHandler) { 1947 return mainWorkerMessageHandler; 1948 } 1949 if (_util.isNodeJS && typeof require === "function") { 1950 const worker = eval("require")(this.workerSrc); 1951 return worker.WorkerMessageHandler; 1952 } 1953 await (0, _display_utils.loadScript)(this.workerSrc); 1954 return window.pdfjsWorker.WorkerMessageHandler; 1955 }; 1956 return (0, _util.shadow)(this, "_setupFakeWorkerGlobal", loader()); 1957 } 1958} 1959exports.PDFWorker = PDFWorker; 1960class WorkerTransport { 1961 #methodPromises = new Map(); 1962 #pageCache = new Map(); 1963 #pagePromises = new Map(); 1964 #passwordCapability = null; 1965 constructor(messageHandler, loadingTask, networkStream, params, factory) { 1966 this.messageHandler = messageHandler; 1967 this.loadingTask = loadingTask; 1968 this.commonObjs = new PDFObjects(); 1969 this.fontLoader = new _font_loader.FontLoader({ 1970 ownerDocument: params.ownerDocument, 1971 styleElement: params.styleElement 1972 }); 1973 this._params = params; 1974 this.canvasFactory = factory.canvasFactory; 1975 this.filterFactory = factory.filterFactory; 1976 this.cMapReaderFactory = factory.cMapReaderFactory; 1977 this.standardFontDataFactory = factory.standardFontDataFactory; 1978 this.destroyed = false; 1979 this.destroyCapability = null; 1980 this._networkStream = networkStream; 1981 this._fullReader = null; 1982 this._lastProgress = null; 1983 this.downloadInfoCapability = new _util.PromiseCapability(); 1984 this.setupMessageHandler(); 1985 } 1986 #cacheSimpleMethod(name, data = null) { 1987 const cachedPromise = this.#methodPromises.get(name); 1988 if (cachedPromise) { 1989 return cachedPromise; 1990 } 1991 const promise = this.messageHandler.sendWithPromise(name, data); 1992 this.#methodPromises.set(name, promise); 1993 return promise; 1994 } 1995 get annotationStorage() { 1996 return (0, _util.shadow)(this, "annotationStorage", new _annotation_storage.AnnotationStorage()); 1997 } 1998 getRenderingIntent(intent, annotationMode = _util.AnnotationMode.ENABLE, printAnnotationStorage = null, isOpList = false) { 1999 let renderingIntent = _util.RenderingIntentFlag.DISPLAY; 2000 let annotationStorageSerializable = _annotation_storage.SerializableEmpty; 2001 switch (intent) { 2002 case "any": 2003 renderingIntent = _util.RenderingIntentFlag.ANY; 2004 break; 2005 case "display": 2006 break; 2007 case "print": 2008 renderingIntent = _util.RenderingIntentFlag.PRINT; 2009 break; 2010 default: 2011 (0, _util.warn)(`getRenderingIntent - invalid intent: ${intent}`); 2012 } 2013 switch (annotationMode) { 2014 case _util.AnnotationMode.DISABLE: 2015 renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_DISABLE; 2016 break; 2017 case _util.AnnotationMode.ENABLE: 2018 break; 2019 case _util.AnnotationMode.ENABLE_FORMS: 2020 renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_FORMS; 2021 break; 2022 case _util.AnnotationMode.ENABLE_STORAGE: 2023 renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_STORAGE; 2024 const annotationStorage = renderingIntent & _util.RenderingIntentFlag.PRINT && printAnnotationStorage instanceof _annotation_storage.PrintAnnotationStorage ? printAnnotationStorage : this.annotationStorage; 2025 annotationStorageSerializable = annotationStorage.serializable; 2026 break; 2027 default: 2028 (0, _util.warn)(`getRenderingIntent - invalid annotationMode: ${annotationMode}`); 2029 } 2030 if (isOpList) { 2031 renderingIntent += _util.RenderingIntentFlag.OPLIST; 2032 } 2033 return { 2034 renderingIntent, 2035 cacheKey: `${renderingIntent}_${annotationStorageSerializable.hash}`, 2036 annotationStorageSerializable 2037 }; 2038 } 2039 destroy() { 2040 if (this.destroyCapability) { 2041 return this.destroyCapability.promise; 2042 } 2043 this.destroyed = true; 2044 this.destroyCapability = new _util.PromiseCapability(); 2045 this.#passwordCapability?.reject(new Error("Worker was destroyed during onPassword callback")); 2046 const waitOn = []; 2047 for (const page of this.#pageCache.values()) { 2048 waitOn.push(page._destroy()); 2049 } 2050 this.#pageCache.clear(); 2051 this.#pagePromises.clear(); 2052 if (this.hasOwnProperty("annotationStorage")) { 2053 this.annotationStorage.resetModified(); 2054 }
2055 const terminated = this.messageHandler.sendWithPromise("Terminate", null); 2056 waitOn.push(terminated); 2057 Promise.all(waitOn).then(() => { 2058 this.commonObjs.clear(); 2059 this.fontLoader.clear(); 2060 this.#methodPromises.clear(); 2061 this.filterFactory.destroy(); 2062 if (this._networkStream) { 2063 this._networkStream.cancelAllRequests(new _util.AbortException("Worker was terminated.")); 2064 } 2065 if (this.messageHandler) { 2066 this.messageHandler.destroy(); 2067 this.messageHandler = null; 2068 } 2069 this.destroyCapability.resolve(); 2070 }, this.destroyCapability.reject); 2071 return this.destroyCapability.promise; 2072 } 2073 setupMessageHandler() { 2074 const { 2075 messageHandler, 2076 loadingTask 2077 } = this; 2078 messageHandler.on("GetReader", (data, sink) => { 2079 (0, _util.assert)(this._networkStream, "GetReader - no `IPDFStream` instance available."); 2080 this._fullReader = this._networkStream.getFullReader(); 2081 this._fullReader.onProgress = evt => { 2082 this._lastProgress = { 2083 loaded: evt.loaded, 2084 total: evt.total 2085 }; 2086 }; 2087 sink.onPull = () => { 2088 this._fullReader.read().then(function ({ 2089 value, 2090 done 2091 }) { 2092 if (done) { 2093 sink.close(); 2094 return; 2095 } 2096 (0, _util.assert)(value instanceof ArrayBuffer, "GetReader - expected an ArrayBuffer."); 2097 sink.enqueue(new Uint8Array(value), 1, [value]); 2098 }).catch(reason => { 2099 sink.error(reason); 2100 }); 2101 }; 2102 sink.onCancel = reason => { 2103 this._fullReader.cancel(reason); 2104 sink.ready.catch(readyReason => { 2105 if (this.destroyed) { 2106 return; 2107 } 2108 throw readyReason; 2109 }); 2110 }; 2111 }); 2112 messageHandler.on("ReaderHeadersReady", data => { 2113 const headersCapability = new _util.PromiseCapability(); 2114 const fullReader = this._fullReader; 2115 fullReader.headersReady.then(() => { 2116 if (!fullReader.isStreamingSupported || !fullReader.isRangeSupported) { 2117 if (this._lastProgress) { 2118 loadingTask.onProgress?.(this._lastProgress); 2119 } 2120 fullReader.onProgress = evt => { 2121 loadingTask.onProgress?.({ 2122 loaded: evt.loaded, 2123 total: evt.total 2124 }); 2125 }; 2126 } 2127 headersCapability.resolve({ 2128 isStreamingSupported: fullReader.isStreamingSupported, 2129 isRangeSupported: fullReader.isRangeSupported, 2130 contentLength: fullReader.contentLength 2131 }); 2132 }, headersCapability.reject); 2133 return headersCapability.promise; 2134 }); 2135 messageHandler.on("GetRangeReader", (data, sink) => { 2136 (0, _util.assert)(this._networkStream, "GetRangeReader - no `IPDFStream` instance available."); 2137 const rangeReader = this._networkStream.getRangeReader(data.begin, data.end); 2138 if (!rangeReader) { 2139 sink.close(); 2140 return; 2141 } 2142 sink.onPull = () => { 2143 rangeReader.read().then(function ({ 2144 value, 2145 done 2146 }) { 2147 if (done) { 2148 sink.close(); 2149 return; 2150 } 2151 (0, _util.assert)(value instanceof ArrayBuffer, "GetRangeReader - expected an ArrayBuffer."); 2152 sink.enqueue(new Uint8Array(value), 1, [value]); 2153 }).catch(reason => { 2154 sink.error(reason); 2155 }); 2156 }; 2157 sink.onCancel = reason => { 2158 rangeReader.cancel(reason); 2159 sink.ready.catch(readyReason => { 2160 if (this.destroyed) { 2161 return; 2162 } 2163 throw readyReason; 2164 }); 2165 }; 2166 }); 2167 messageHandler.on("GetDoc", ({ 2168 pdfInfo 2169 }) => { 2170 this._numPages = pdfInfo.numPages; 2171 this._htmlForXfa = pdfInfo.htmlForXfa; 2172 delete pdfInfo.htmlForXfa; 2173 loadingTask._capability.resolve(new PDFDocumentProxy(pdfInfo, this)); 2174 }); 2175 messageHandler.on("DocException", function (ex) { 2176 let reason; 2177 switch (ex.name) { 2178 case "PasswordException": 2179 reason = new _util.PasswordException(ex.message, ex.code); 2180 break; 2181 case "InvalidPDFException": 2182 reason = new _util.InvalidPDFException(ex.message); 2183 break; 2184 case "MissingPDFException": 2185 reason = new _util.MissingPDFException(ex.message); 2186 break; 2187 case "UnexpectedResponseException": 2188 reason = new _util.UnexpectedResponseException(ex.message, ex.status); 2189 break; 2190 case "UnknownErrorException": 2191 reason = new _util.UnknownErrorException(ex.message, ex.details); 2192 break; 2193 default: 2194 (0, _util.unreachable)("DocException - expected a valid Error."); 2195 } 2196 loadingTask._capability.reject(reason); 2197 }); 2198 messageHandler.on("PasswordRequest", exception => { 2199 this.#passwordCapability = new _util.PromiseCapability(); 2200 if (loadingTask.onPassword) { 2201 const updatePassword = password => { 2202 if (password instanceof Error) { 2203 this.#passwordCapability.reject(password); 2204 } else { 2205 this.#passwordCapability.resolve({ 2206 password 2207 }); 2208 } 2209 }; 2210 try { 2211 loadingTask.onPassword(updatePassword, exception.code); 2212 } catch (ex) { 2213 this.#passwordCapability.reject(ex); 2214 } 2215 } else { 2216 this.#passwordCapability.reject(new _util.PasswordException(exception.message, exception.code)); 2217 } 2218 return this.#passwordCapability.promise; 2219 }); 2220 messageHandler.on("DataLoaded", data => { 2221 loadingTask.onProgress?.({ 2222 loaded: data.length, 2223 total: data.length 2224 }); 2225 this.downloadInfoCapability.resolve(data); 2226 }); 2227 messageHandler.on("StartRenderPage", data => { 2228 if (this.destroyed) { 2229 return; 2230 } 2231 const page = this.#pageCache.get(data.pageIndex); 2232 page._startRenderPage(data.transparency, data.cacheKey); 2233 }); 2234 messageHandler.on("commonobj", ([id, type, exportedData]) => { 2235 if (this.destroyed) { 2236 return; 2237 } 2238 if (this.commonObjs.has(id)) { 2239 return; 2240 } 2241 switch (type) { 2242 case "Font": 2243 const params = this._params; 2244 if ("error" in exportedData) { 2245 const exportedError = exportedData.error; 2246 (0, _util.warn)(`Error during font loading: ${exportedError}`); 2247 this.commonObjs.resolve(id, exportedError); 2248 break; 2249 } 2250 const inspectFont = params.pdfBug && globalThis.FontInspector?.enabled ? (font, url) => globalThis.FontInspector.fontAdded(font, url) : null; 2251 const font = new _font_loader.FontFaceObject(exportedData, { 2252 isEvalSupported: params.isEvalSupported, 2253 disableFontFace: params.disableFontFace, 2254 ignoreErrors: params.ignoreErrors, 2255 inspectFont 2256 });
2257 this.fontLoader.bind(font).catch(reason => { 2258 return messageHandler.sendWithPromise("FontFallback", { 2259 id 2260 }); 2261 }).finally(() => { 2262 if (!params.fontExtraProperties && font.data) { 2263 font.data = null; 2264 } 2265 this.commonObjs.resolve(id, font); 2266 }); 2267 break; 2268 case "FontPath": 2269 case "Image": 2270 case "Pattern": 2271 this.commonObjs.resolve(id, exportedData); 2272 break; 2273 default: 2274 throw new Error(`Got unknown common object type ${type}`); 2275 } 2276 }); 2277 messageHandler.on("obj", ([id, pageIndex, type, imageData]) => { 2278 if (this.destroyed) { 2279 return; 2280 } 2281 const pageProxy = this.#pageCache.get(pageIndex); 2282 if (pageProxy.objs.has(id)) { 2283 return; 2284 } 2285 switch (type) { 2286 case "Image": 2287 pageProxy.objs.resolve(id, imageData); 2288 if (imageData) { 2289 let length; 2290 if (imageData.bitmap) { 2291 const { 2292 width, 2293 height 2294 } = imageData; 2295 length = width * height * 4; 2296 } else { 2297 length = imageData.data?.length || 0; 2298 } 2299 if (length > _util.MAX_IMAGE_SIZE_TO_CACHE) { 2300 pageProxy._maybeCleanupAfterRender = true; 2301 } 2302 } 2303 break; 2304 case "Pattern": 2305 pageProxy.objs.resolve(id, imageData); 2306 break; 2307 default: 2308 throw new Error(`Got unknown object type ${type}`); 2309 } 2310 }); 2311 messageHandler.on("DocProgress", data => { 2312 if (this.destroyed) { 2313 return; 2314 } 2315 loadingTask.onProgress?.({ 2316 loaded: data.loaded, 2317 total: data.total 2318 }); 2319 }); 2320 messageHandler.on("FetchBuiltInCMap", data => { 2321 if (this.destroyed) { 2322 return Promise.reject(new Error("Worker was destroyed.")); 2323 } 2324 if (!this.cMapReaderFactory) { 2325 return Promise.reject(new Error("CMapReaderFactory not initialized, see the `useWorkerFetch` parameter.")); 2326 } 2327 return this.cMapReaderFactory.fetch(data); 2328 }); 2329 messageHandler.on("FetchStandardFontData", data => { 2330 if (this.destroyed) { 2331 return Promise.reject(new Error("Worker was destroyed.")); 2332 } 2333 if (!this.standardFontDataFactory) { 2334 return Promise.reject(new Error("StandardFontDataFactory not initialized, see the `useWorkerFetch` parameter.")); 2335 } 2336 return this.standardFontDataFactory.fetch(data); 2337 }); 2338 } 2339 getData() { 2340 return this.messageHandler.sendWithPromise("GetData", null); 2341 } 2342 saveDocument() { 2343 if (this.annotationStorage.size <= 0) { 2344 (0, _util.warn)("saveDocument called while `annotationStorage` is empty, " + "please use the getData-method instead."); 2345 } 2346 const { 2347 map, 2348 transfers 2349 } = this.annotationStorage.serializable; 2350 return this.messageHandler.sendWithPromise("SaveDocument", { 2351 isPureXfa: !!this._htmlForXfa, 2352 numPages: this._numPages, 2353 annotationStorage: map, 2354 filename: this._fullReader?.filename ?? null 2355 }, transfers).finally(() => { 2356 this.annotationStorage.resetModified(); 2357 }); 2358 } 2359 getPage(pageNumber) { 2360 if (!Number.isInteger(pageNumber) || pageNumber <= 0 || pageNumber > this._numPages) { 2361 return Promise.reject(new Error("Invalid page request.")); 2362 } 2363 const pageIndex = pageNumber - 1, 2364 cachedPromise = this.#pagePromises.get(pageIndex); 2365 if (cachedPromise) { 2366 return cachedPromise; 2367 } 2368 const promise = this.messageHandler.sendWithPromise("GetPage", { 2369 pageIndex 2370 }).then(pageInfo => { 2371 if (this.destroyed) { 2372 throw new Error("Transport destroyed"); 2373 } 2374 const page = new PDFPageProxy(pageIndex, pageInfo, this, this._params.pdfBug); 2375 this.#pageCache.set(pageIndex, page); 2376 return page; 2377 }); 2378 this.#pagePromises.set(pageIndex, promise); 2379 return promise; 2380 } 2381 getPageIndex(ref) { 2382 if (typeof ref !== "object" || ref === null || !Number.isInteger(ref.num) || ref.num < 0 || !Number.isInteger(ref.gen) || ref.gen < 0) { 2383 return Promise.reject(new Error("Invalid pageIndex request.")); 2384 }
2385 return this.messageHandler.sendWithPromise("GetPageIndex", { 2386 num: ref.num, 2387 gen: ref.gen 2388 }); 2389 } 2390 getAnnotations(pageIndex, intent) { 2391 return this.messageHandler.sendWithPromise("GetAnnotations", { 2392 pageIndex, 2393 intent 2394 }); 2395 } 2396 getFieldObjects() { 2397 return this.#cacheSimpleMethod("GetFieldObjects"); 2398 } 2399 hasJSActions() { 2400 return this.#cacheSimpleMethod("HasJSActions"); 2401 } 2402 getCalculationOrderIds() { 2403 return this.messageHandler.sendWithPromise("GetCalculationOrderIds", null); 2404 } 2405 getDestinations() { 2406 return this.messageHandler.sendWithPromise("GetDestinations", null); 2407 } 2408 getDestination(id) { 2409 if (typeof id !== "string") { 2410 return Promise.reject(new Error("Invalid destination request.")); 2411 } 2412 return this.messageHandler.sendWithPromise("GetDestination", { 2413 id 2414 }); 2415 } 2416 getPageLabels() { 2417 return this.messageHandler.sendWithPromise("GetPageLabels", null); 2418 } 2419 getPageLayout() { 2420 return this.messageHandler.sendWithPromise("GetPageLayout", null); 2421 } 2422 getPageMode() { 2423 return this.messageHandler.sendWithPromise("GetPageMode", null); 2424 } 2425 getViewerPreferences() { 2426 return this.messageHandler.sendWithPromise("GetViewerPreferences", null); 2427 } 2428 getOpenAction() { 2429 return this.messageHandler.sendWithPromise("GetOpenAction", null); 2430 } 2431 getAttachments() { 2432 return this.messageHandler.sendWithPromise("GetAttachments", null); 2433 } 2434 getJavaScript() { 2435 return this.messageHandler.sendWithPromise("GetJavaScript", null); 2436 } 2437 getDocJSActions() { 2438 return this.messageHandler.sendWithPromise("GetDocJSActions", null); 2439 } 2440 getPageJSActions(pageIndex) { 2441 return this.messageHandler.sendWithPromise("GetPageJSActions", { 2442 pageIndex 2443 }); 2444 } 2445 getStructTree(pageIndex) { 2446 return this.messageHandler.sendWithPromise("GetStructTree", { 2447 pageIndex 2448 }); 2449 } 2450 getOutline() { 2451 return this.messageHandler.sendWithPromise("GetOutline", null); 2452 } 2453 getOptionalContentConfig() { 2454 return this.messageHandler.sendWithPromise("GetOptionalContentConfig", null).then(results => { 2455 return new _optional_content_config.OptionalContentConfig(results); 2456 }); 2457 } 2458 getPermissions() { 2459 return this.messageHandler.sendWithPromise("GetPermissions", null); 2460 } 2461 getMetadata() { 2462 const name = "GetMetadata", 2463 cachedPromise = this.#methodPromises.get(name); 2464 if (cachedPromise) { 2465 return cachedPromise; 2466 } 2467 const promise = this.messageHandler.sendWithPromise(name, null).then(results => { 2468 return { 2469 info: results[0], 2470 metadata: results[1] ? new _metadata.Metadata(results[1]) : null, 2471 contentDispositionFilename: this._fullReader?.filename ?? null, 2472 contentLength: this._fullReader?.contentLength ?? null 2473 }; 2474 }); 2475 this.#methodPromises.set(name, promise); 2476 return promise; 2477 } 2478 getMarkInfo() { 2479 return this.messageHandler.sendWithPromise("GetMarkInfo", null); 2480 } 2481 async startCleanup(keepLoadedFonts = false) { 2482 if (this.destroyed) { 2483 return; 2484 } 2485 await this.messageHandler.sendWithPromise("Cleanup", null); 2486 for (const page of this.#pageCache.values()) { 2487 const cleanupSuccessful = page.cleanup(); 2488 if (!cleanupSuccessful) { 2489 throw new Error(`startCleanup: Page ${page.pageNumber} is currently rendering.`); 2490 } 2491 } 2492 this.commonObjs.clear(); 2493 if (!keepLoadedFonts) { 2494 this.fontLoader.clear(); 2495 } 2496 this.#methodPromises.clear(); 2497 this.filterFactory.destroy(true); 2498 } 2499 get loadingParams() { 2500 const { 2501 disableAutoFetch, 2502 enableXfa 2503 } = this._params; 2504 return (0, _util.shadow)(this, "loadingParams", { 2505 disableAutoFetch, 2506 enableXfa 2507 }); 2508 } 2509} 2510class PDFObjects { 2511 #objs = Object.create(null); 2512 #ensureObj(objId) { 2513 const obj = this.#objs[objId]; 2514 if (obj) { 2515 return obj; 2516 } 2517 return this.#objs[objId] = { 2518 capability: new _util.PromiseCapability(), 2519 data: null 2520 }; 2521 } 2522 get(objId, callback = null) { 2523 if (callback) { 2524 const obj = this.#ensureObj(objId); 2525 obj.capability.promise.then(() => callback(obj.data)); 2526 return null; 2527 } 2528 const obj = this.#objs[objId]; 2529 if (!obj?.capability.settled) { 2530 throw new Error(`Requesting object that isn't resolved yet ${objId}.`); 2531 } 2532 return obj.data; 2533 }
2534 has(objId) { 2535 const obj = this.#objs[objId]; 2536 return obj?.capability.settled || false; 2537 } 2538 resolve(objId, data = null) { 2539 const obj = this.#ensureObj(objId); 2540 obj.data = data; 2541 obj.capability.resolve(); 2542 } 2543 clear() { 2544 for (const objId in this.#objs) { 2545 const { 2546 data 2547 } = this.#objs[objId]; 2548 data?.bitmap?.close(); 2549 } 2550 this.#objs = Object.create(null); 2551 } 2552} 2553class RenderTask { 2554 #internalRenderTask = null; 2555 constructor(internalRenderTask) { 2556 this.#internalRenderTask = internalRenderTask; 2557 this.onContinue = null; 2558 } 2559 get promise() { 2560 return this.#internalRenderTask.capability.promise; 2561 } 2562 cancel(extraDelay = 0) { 2563 this.#internalRenderTask.cancel(null, extraDelay); 2564 } 2565 get separateAnnots() { 2566 const { 2567 separateAnnots 2568 } = this.#internalRenderTask.operatorList; 2569 if (!separateAnnots) { 2570 return false; 2571 } 2572 const { 2573 annotationCanvasMap 2574 } = this.#internalRenderTask; 2575 return separateAnnots.form || separateAnnots.canvas && annotationCanvasMap?.size > 0; 2576 } 2577} 2578exports.RenderTask = RenderTask; 2579class InternalRenderTask { 2580 static #canvasInUse = new WeakSet(); 2581 constructor({ 2582 callback, 2583 params, 2584 objs, 2585 commonObjs, 2586 annotationCanvasMap, 2587 operatorList, 2588 pageIndex, 2589 canvasFactory, 2590 filterFactory, 2591 useRequestAnimationFrame = false, 2592 pdfBug = false, 2593 pageColors = null 2594 }) { 2595 this.callback = callback; 2596 this.params = params; 2597 this.objs = objs; 2598 this.commonObjs = commonObjs; 2599 this.annotationCanvasMap = annotationCanvasMap; 2600 this.operatorListIdx = null; 2601 this.operatorList = operatorList; 2602 this._pageIndex = pageIndex; 2603 this.canvasFactory = canvasFactory; 2604 this.filterFactory = filterFactory; 2605 this._pdfBug = pdfBug; 2606 this.pageColors = pageColors; 2607 this.running = false; 2608 this.graphicsReadyCallback = null; 2609 this.graphicsReady = false; 2610 this._useRequestAnimationFrame = useRequestAnimationFrame === true && typeof window !== "undefined"; 2611 this.cancelled = false; 2612 this.capability = new _util.PromiseCapability(); 2613 this.task = new RenderTask(this); 2614 this._cancelBound = this.cancel.bind(this); 2615 this._continueBound = this._continue.bind(this); 2616 this._scheduleNextBound = this._scheduleNext.bind(this); 2617 this._nextBound = this._next.bind(this); 2618 this._canvas = params.canvasContext.canvas; 2619 } 2620 get completed() { 2621 return this.capability.promise.catch(function () {}); 2622 } 2623 initializeGraphics({ 2624 transparency = false, 2625 optionalContentConfig 2626 }) { 2627 if (this.cancelled) { 2628 return; 2629 } 2630 if (this._canvas) { 2631 if (InternalRenderTask.#canvasInUse.has(this._canvas)) { 2632 throw new Error("Cannot use the same canvas during multiple render() operations. " + "Use different canvas or ensure previous operations were " + "cancelled or completed."); 2633 } 2634 InternalRenderTask.#canvasInUse.add(this._canvas); 2635 } 2636 if (this._pdfBug && globalThis.StepperManager?.enabled) { 2637 this.stepper = globalThis.StepperManager.create(this._pageIndex); 2638 this.stepper.init(this.operatorList); 2639 this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint(); 2640 } 2641 const { 2642 canvasContext, 2643 viewport, 2644 transform, 2645 background 2646 } = this.params; 2647 this.gfx = new _canvas.CanvasGraphics(canvasContext, this.commonObjs, this.objs, this.canvasFactory, this.filterFactory, { 2648 optionalContentConfig 2649 }, this.annotationCanvasMap, this.pageColors); 2650 this.gfx.beginDrawing({ 2651 transform, 2652 viewport, 2653 transparency, 2654 background 2655 }); 2656 this.operatorListIdx = 0; 2657 this.graphicsReady = true; 2658 this.graphicsReadyCallback?.(); 2659 } 2660 cancel(error = null, extraDelay = 0) { 2661 this.running = false; 2662 this.cancelled = true; 2663 this.gfx?.endDrawing(); 2664 if (this._canvas) { 2665 InternalRenderTask.#canvasInUse.delete(this._canvas); 2666 } 2667 this.callback(error || new _display_utils.RenderingCancelledException(`Rendering cancelled, page ${this._pageIndex + 1}`, extraDelay)); 2668 } 2669 operatorListChanged() { 2670 if (!this.graphicsReady) { 2671 this.graphicsReadyCallback ||= this._continueBound; 2672 return; 2673 } 2674 this.stepper?.updateOperatorList(this.operatorList); 2675 if (this.running) { 2676 return; 2677 } 2678 this._continue(); 2679 } 2680 _continue() { 2681 this.running = true; 2682 if (this.cancelled) { 2683 return; 2684 } 2685 if (this.task.onContinue) { 2686 this.task.onContinue(this._scheduleNextBound); 2687 } else { 2688 this._scheduleNext(); 2689 } 2690 } 2691 _scheduleNext() { 2692 if (this._useRequestAnimationFrame) { 2693 window.requestAnimationFrame(() => { 2694 this._nextBound().catch(this._cancelBound); 2695 }); 2696 } else {
2697 Promise.resolve().then(this._nextBound).catch(this._cancelBound); 2698 } 2699 } 2700 async _next() { 2701 if (this.cancelled) { 2702 return; 2703 } 2704 this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList, this.operatorListIdx, this._continueBound, this.stepper); 2705 if (this.operatorListIdx === this.operatorList.argsArray.length) { 2706 this.running = false; 2707 if (this.operatorList.lastChunk) { 2708 this.gfx.endDrawing(this.pageColors); 2709 if (this._canvas) { 2710 InternalRenderTask.#canvasInUse.delete(this._canvas); 2711 } 2712 this.callback(); 2713 } 2714 } 2715 } 2716} 2717const version = '3.9.179'; 2718exports.version = version; 2719const build = '1ef6fbc52'; 2720exports.build = build; 2721 2722/***/ }), 2723/* 3 */ 2724/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 2725 2726 2727 2728Object.defineProperty(exports, "__esModule", ({ 2729 value: true 2730})); 2731exports.SerializableEmpty = exports.PrintAnnotationStorage = exports.AnnotationStorage = void 0; 2732var _util = __w_pdfjs_require__(1); 2733var _editor = __w_pdfjs_require__(4); 2734var _murmurhash = __w_pdfjs_require__(8); 2735const SerializableEmpty = Object.freeze({ 2736 map: null, 2737 hash: "", 2738 transfers: undefined 2739}); 2740exports.SerializableEmpty = SerializableEmpty; 2741class AnnotationStorage { 2742 #modified = false; 2743 #storage = new Map(); 2744 constructor() { 2745 this.onSetModified = null; 2746 this.onResetModified = null; 2747 this.onAnnotationEditor = null; 2748 } 2749 getValue(key, defaultValue) { 2750 const value = this.#storage.get(key); 2751 if (value === undefined) { 2752 return defaultValue; 2753 } 2754 return Object.assign(defaultValue, value); 2755 } 2756 getRawValue(key) { 2757 return this.#storage.get(key); 2758 } 2759 remove(key) { 2760 this.#storage.delete(key); 2761 if (this.#storage.size === 0) { 2762 this.resetModified(); 2763 } 2764 if (typeof this.onAnnotationEditor === "function") { 2765 for (const value of this.#storage.values()) { 2766 if (value instanceof _editor.AnnotationEditor) { 2767 return; 2768 } 2769 } 2770 this.onAnnotationEditor(null); 2771 } 2772 } 2773 setValue(key, value) { 2774 const obj = this.#storage.get(key); 2775 let modified = false; 2776 if (obj !== undefined) { 2777 for (const [entry, val] of Object.entries(value)) { 2778 if (obj[entry] !== val) { 2779 modified = true; 2780 obj[entry] = val; 2781 } 2782 } 2783 } else { 2784 modified = true; 2785 this.#storage.set(key, value); 2786 } 2787 if (modified) { 2788 this.#setModified(); 2789 } 2790 if (value instanceof _editor.AnnotationEditor && typeof this.onAnnotationEditor === "function") { 2791 this.onAnnotationEditor(value.constructor._type); 2792 } 2793 } 2794 has(key) { 2795 return this.#storage.has(key); 2796 } 2797 getAll() { 2798 return this.#storage.size > 0 ? (0, _util.objectFromMap)(this.#storage) : null; 2799 } 2800 setAll(obj) { 2801 for (const [key, val] of Object.entries(obj)) { 2802 this.setValue(key, val); 2803 } 2804 } 2805 get size() { 2806 return this.#storage.size; 2807 } 2808 #setModified() { 2809 if (!this.#modified) { 2810 this.#modified = true; 2811 if (typeof this.onSetModified === "function") { 2812 this.onSetModified(); 2813 } 2814 } 2815 } 2816 resetModified() { 2817 if (this.#modified) { 2818 this.#modified = false; 2819 if (typeof this.onResetModified === "function") { 2820 this.onResetModified(); 2821 } 2822 } 2823 } 2824 get print() { 2825 return new PrintAnnotationStorage(this); 2826 } 2827 get serializable() { 2828 if (this.#storage.size === 0) { 2829 return SerializableEmpty; 2830 } 2831 const map = new Map(), 2832 hash = new _murmurhash.MurmurHash3_64(), 2833 transfers = []; 2834 const context = Object.create(null); 2835 let hasBitmap = false; 2836 for (const [key, val] of this.#storage) { 2837 const serialized = val instanceof _editor.AnnotationEditor ? val.serialize(false, context) : val; 2838 if (serialized) { 2839 map.set(key, serialized); 2840 hash.update(`${key}:${JSON.stringify(serialized)}`); 2841 hasBitmap ||= !!serialized.bitmap; 2842 } 2843 } 2844 if (hasBitmap) { 2845 for (const value of map.values()) { 2846 if (value.bitmap) { 2847 transfers.push(value.bitmap); 2848 } 2849 } 2850 } 2851 return map.size > 0 ? { 2852 map, 2853 hash: hash.hexdigest(), 2854 transfers 2855 } : SerializableEmpty; 2856 } 2857} 2858exports.AnnotationStorage = AnnotationStorage; 2859class PrintAnnotationStorage extends AnnotationStorage { 2860 #serializable; 2861 constructor(parent) { 2862 super(); 2863 const { 2864 map, 2865 hash, 2866 transfers 2867 } = parent.serializable; 2868 const clone = structuredClone(map, transfers ? { 2869 transfer: transfers 2870 } : null); 2871 this.#serializable = { 2872 map: clone, 2873 hash, 2874 transfers 2875 }; 2876 } 2877 get print() { 2878 (0, _util.unreachable)("Should not call PrintAnnotationStorage.print"); 2879 } 2880 get serializable() { 2881 return this.#serializable; 2882 } 2883} 2884exports.PrintAnnotationStorage = PrintAnnotationStorage; 2885 2886/***/ }), 2887/* 4 */ 2888/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 2889 2890 2891 2892Object.defineProperty(exports, "__esModule", ({ 2893 value: true 2894})); 2895exports.AnnotationEditor = void 0; 2896var _util = __w_pdfjs_require__(1); 2897var _tools = __w_pdfjs_require__(5); 2898class AnnotationEditor { 2899 #keepAspectRatio = false;
2900 #resizersDiv = null; 2901 #resizePosition = null; 2902 #boundFocusin = this.focusin.bind(this); 2903 #boundFocusout = this.focusout.bind(this); 2904 #hasBeenSelected = false; 2905 #isEditing = false; 2906 #isInEditMode = false; 2907 _uiManager = null; 2908 #zIndex = AnnotationEditor._zIndex++; 2909 static _colorManager = new _tools.ColorManager(); 2910 static _zIndex = 1; 2911 constructor(parameters) { 2912 if (this.constructor === AnnotationEditor) { 2913 (0, _util.unreachable)("Cannot initialize AnnotationEditor."); 2914 } 2915 this.parent = parameters.parent; 2916 this.id = parameters.id; 2917 this.width = this.height = null; 2918 this.pageIndex = parameters.parent.pageIndex; 2919 this.name = parameters.name; 2920 this.div = null; 2921 this._uiManager = parameters.uiManager; 2922 this.annotationElementId = null; 2923 this._willKeepAspectRatio = false; 2924 const { 2925 rotation, 2926 rawDims: { 2927 pageWidth, 2928 pageHeight, 2929 pageX, 2930 pageY 2931 } 2932 } = this.parent.viewport; 2933 this.rotation = rotation; 2934 this.pageRotation = (360 + rotation - this._uiManager.viewParameters.rotation) % 360; 2935 this.pageDimensions = [pageWidth, pageHeight]; 2936 this.pageTranslation = [pageX, pageY]; 2937 const [width, height] = this.parentDimensions; 2938 this.x = parameters.x / width; 2939 this.y = parameters.y / height; 2940 this.isAttachedToDOM = false; 2941 this.deleted = false; 2942 } 2943 static get _defaultLineColor() { 2944 return (0, _util.shadow)(this, "_defaultLineColor", this._colorManager.getHexCode("CanvasText")); 2945 } 2946 static deleteAnnotationElement(editor) { 2947 const fakeEditor = new FakeEditor({ 2948 id: editor.parent.getNextId(), 2949 parent: editor.parent, 2950 uiManager: editor._uiManager 2951 }); 2952 fakeEditor.annotationElementId = editor.annotationElementId; 2953 fakeEditor.deleted = true; 2954 fakeEditor._uiManager.addToAnnotationStorage(fakeEditor); 2955 } 2956 static initialize(_l10n) {} 2957 static updateDefaultParams(_type, _value) {} 2958 static get defaultPropertiesToUpdate() { 2959 return []; 2960 } 2961 get propertiesToUpdate() { 2962 return []; 2963 } 2964 addCommands(params) { 2965 this._uiManager.addCommands(params); 2966 } 2967 get currentLayer() { 2968 return this._uiManager.currentLayer; 2969 } 2970 setInBackground() { 2971 this.div.style.zIndex = 0; 2972 } 2973 setInForeground() { 2974 this.div.style.zIndex = this.#zIndex; 2975 } 2976 setParent(parent) { 2977 if (parent !== null) { 2978 this.pageIndex = parent.pageIndex; 2979 this.pageDimensions = parent.pageDimensions; 2980 } 2981 this.parent = parent; 2982 } 2983 focusin(event) { 2984 if (!this.#hasBeenSelected) { 2985 this.parent.setSelected(this); 2986 } else { 2987 this.#hasBeenSelected = false; 2988 } 2989 } 2990 focusout(event) { 2991 if (!this.isAttachedToDOM) { 2992 return; 2993 } 2994 const target = event.relatedTarget; 2995 if (target?.closest(`#${this.id}`)) { 2996 return; 2997 } 2998 event.preventDefault(); 2999 if (!this.parent?.isMultipleSelection) { 3000 this.commitOrRemove(); 3001 } 3002 } 3003 commitOrRemove() { 3004 if (this.isEmpty()) { 3005 this.remove(); 3006 } else { 3007 this.commit(); 3008 } 3009 } 3010 commit() { 3011 this.addToAnnotationStorage(); 3012 } 3013 addToAnnotationStorage() { 3014 this._uiManager.addToAnnotationStorage(this); 3015 } 3016 dragstart(event) { 3017 const rect = this.parent.div.getBoundingClientRect(); 3018 this.startX = event.clientX - rect.x; 3019 this.startY = event.clientY - rect.y; 3020 event.dataTransfer.setData("text/plain", this.id); 3021 event.dataTransfer.effectAllowed = "move"; 3022 } 3023 setAt(x, y, tx, ty) { 3024 const [width, height] = this.parentDimensions; 3025 [tx, ty] = this.screenToPageTranslation(tx, ty); 3026 this.x = (x + tx) / width; 3027 this.y = (y + ty) / height; 3028 this.fixAndSetPosition(); 3029 } 3030 #translate([width, height], x, y) { 3031 [x, y] = this.screenToPageTranslation(x, y); 3032 this.x += x / width; 3033 this.y += y / height; 3034 this.fixAndSetPosition(); 3035 } 3036 translate(x, y) { 3037 this.#translate(this.parentDimensions, x, y); 3038 } 3039 translateInPage(x, y) { 3040 this.#translate(this.pageDimensions, x, y); 3041 this.div.scrollIntoView({ 3042 block: "nearest" 3043 }); 3044 } 3045 fixAndSetPosition() { 3046 const [pageWidth, pageHeight] = this.pageDimensions; 3047 let { 3048 x, 3049 y, 3050 width, 3051 height 3052 } = this; 3053 width *= pageWidth; 3054 height *= pageHeight; 3055 x *= pageWidth; 3056 y *= pageHeight; 3057 switch (this.rotation) { 3058 case 0: 3059 x = Math.max(0, Math.min(pageWidth - width, x)); 3060 y = Math.max(0, Math.min(pageHeight - height, y)); 3061 break; 3062 case 90: 3063 x = Math.max(0, Math.min(pageWidth - height, x)); 3064 y = Math.min(pageHeight, Math.max(width, y)); 3065 break; 3066 case 180: 3067 x = Math.min(pageWidth, Math.max(width, x)); 3068 y = Math.min(pageHeight, Math.max(height, y)); 3069 break; 3070 case 270: 3071 x = Math.min(pageWidth, Math.max(height, x)); 3072 y = Math.max(0, Math.min(pageHeight - width, y)); 3073 break; 3074 } 3075 this.x = x / pageWidth; 3076 this.y = y / pageHeight; 3077 this.div.style.left = `${(100 * this.x).toFixed(2)}%`; 3078 this.div.style.top = `${(100 * this.y).toFixed(2)}%`; 3079 } 3080 screenToPageTranslation(x, y) { 3081 switch (this.parentRotation) { 3082 case 90: 3083 return [y, -x]; 3084 case 180: 3085 return [-x, -y]; 3086 case 270: 3087 return [-y, x]; 3088 default: 3089 return [x, y]; 3090 } 3091 } 3092 pageTranslationToScreen(x, y) { 3093 switch (this.parentRotation) { 3094 case 90: 3095 return [-y, x]; 3096 case 180: 3097 return [-x, -y]; 3098 case 270: 3099 return [y, -x]; 3100 default: 3101 return [x, y]; 3102 } 3103 } 3104 get parentScale() { 3105 return this._uiManager.viewParameters.realScale; 3106 } 3107 get parentRotation() { 3108 return (this._uiManager.viewParameters.rotation + this.pageRotation) % 360; 3109 } 3110 get parentDimensions() { 3111 const { 3112 realScale 3113 } = this._uiManager.viewParameters; 3114 const [pageWidth, pageHeight] = this.pageDimensions; 3115 return [pageWidth * realScale, pageHeight * realScale]; 3116 } 3117 setDims(width, height) { 3118 const [parentWidth, parentHeight] = this.parentDimensions; 3119 this.div.style.width = `${(100 * width / parentWidth).toFixed(2)}%`; 3120 if (!this.#keepAspectRatio) { 3121 this.div.style.height = `${(100 * height / parentHeight).toFixed(2)}%`; 3122 } 3123 } 3124 fixDims() { 3125 const { 3126 style 3127 } = this.div; 3128 const { 3129 height, 3130 width 3131 } = style; 3132 const widthPercent = width.endsWith("%"); 3133 const heightPercent = !this.#keepAspectRatio && height.endsWith("%"); 3134 if (widthPercent && heightPercent) { 3135 return; 3136 } 3137 const [parentWidth, parentHeight] = this.parentDimensions; 3138 if (!widthPercent) { 3139 style.width = `${(100 * parseFloat(width) / parentWidth).toFixed(2)}%`; 3140 } 3141 if (!this.#keepAspectRatio && !heightPercent) { 3142 style.height = `${(100 * parseFloat(height) / parentHeight).toFixed(2)}%`; 3143 } 3144 } 3145 getInitialTranslation() { 3146 return [0, 0]; 3147 } 3148 #createResizers() { 3149 if (this.#resizersDiv) { 3150 return; 3151 } 3152 this.#resizersDiv = document.createElement("div"); 3153 this.#resizersDiv.classList.add("resizers"); 3154 const classes = ["topLeft", "topRight", "bottomRight", "bottomLeft"]; 3155 if (!this._willKeepAspectRatio) { 3156 classes.push("topMiddle", "middleRight", "bottomMiddle", "middleLeft"); 3157 } 3158 for (const name of classes) { 3159 const div = document.createElement("div"); 3160 this.#resizersDiv.append(div); 3161 div.classList.add("resizer", name); 3162 div.addEventListener("pointerdown", this.#resizerPointerdown.bind(this, name)); 3163 } 3164 this.div.prepend(this.#resizersDiv); 3165 } 3166 #resizerPointerdown(name, event) { 3167 event.preventDefault(); 3168 this.#resizePosition = [event.clientX, event.clientY]; 3169 const boundResizerPointermove = this.#resizerPointermove.bind(this, name); 3170 const savedDraggable = this.div.draggable; 3171 this.div.draggable = false;
3172 const resizingClassName = `resizing${name.charAt(0).toUpperCase()}${name.slice(1)}`; 3173 this.parent.div.classList.add(resizingClassName); 3174 const pointerMoveOptions = { 3175 passive: true, 3176 capture: true 3177 }; 3178 window.addEventListener("pointermove", boundResizerPointermove, pointerMoveOptions); 3179 const pointerUpCallback = () => { 3180 this._uiManager.stopUndoAccumulation(); 3181 this.div.draggable = savedDraggable; 3182 this.parent.div.classList.remove(resizingClassName); 3183 window.removeEventListener("pointermove", boundResizerPointermove, pointerMoveOptions); 3184 }; 3185 window.addEventListener("pointerup", pointerUpCallback, { 3186 once: true 3187 }); 3188 } 3189 #resizerPointermove(name, event) { 3190 const { 3191 clientX, 3192 clientY 3193 } = event; 3194 const deltaX = clientX - this.#resizePosition[0]; 3195 const deltaY = clientY - this.#resizePosition[1]; 3196 this.#resizePosition[0] = clientX; 3197 this.#resizePosition[1] = clientY; 3198 const [parentWidth, parentHeight] = this.parentDimensions; 3199 const savedX = this.x; 3200 const savedY = this.y; 3201 const savedWidth = this.width; 3202 const savedHeight = this.height; 3203 const minWidth = AnnotationEditor.MIN_SIZE / parentWidth; 3204 const minHeight = AnnotationEditor.MIN_SIZE / parentHeight; 3205 let cmd; 3206 const round = x => Math.round(x * 10000) / 10000; 3207 const updatePosition = (width, height) => { 3208 const [pWidth, pHeight] = this.parentDimensions; 3209 this.setDims(pWidth * width, pHeight * height); 3210 this.fixAndSetPosition(); 3211 }; 3212 const undo = () => { 3213 this.width = savedWidth; 3214 this.height = savedHeight; 3215 this.x = savedX; 3216 this.y = savedY; 3217 updatePosition(savedWidth, savedHeight); 3218 }; 3219 switch (name) { 3220 case "topLeft": 3221 { 3222 if (Math.sign(deltaX) * Math.sign(deltaY) < 0) { 3223 return; 3224 } 3225 const dist = Math.hypot(deltaX, deltaY); 3226 const oldDiag = Math.hypot(savedWidth * parentWidth, savedHeight * parentHeight); 3227 const brX = round(savedX + savedWidth); 3228 const brY = round(savedY + savedHeight); 3229 const ratio = Math.max(Math.min(1 - Math.sign(deltaX) * (dist / oldDiag), 1 / savedWidth, 1 / savedHeight), minWidth / savedWidth, minHeight / savedHeight); 3230 const newWidth = round(savedWidth * ratio); 3231 const newHeight = round(savedHeight * ratio); 3232 const newX = brX - newWidth; 3233 const newY = brY - newHeight; 3234 cmd = () => { 3235 this.width = newWidth; 3236 this.height = newHeight; 3237 this.x = newX; 3238 this.y = newY; 3239 updatePosition(newWidth, newHeight); 3240 }; 3241 break; 3242 } 3243 case "topMiddle": 3244 { 3245 const bmY = round(this.y + savedHeight); 3246 const newHeight = round(Math.max(minHeight, Math.min(1, savedHeight - deltaY / parentHeight))); 3247 const newY = bmY - newHeight; 3248 cmd = () => { 3249 this.height = newHeight; 3250 this.y = newY; 3251 updatePosition(savedWidth, newHeight); 3252 }; 3253 break; 3254 } 3255 case "topRight": 3256 { 3257 if (Math.sign(deltaX) * Math.sign(deltaY) > 0) { 3258 return; 3259 } 3260 const dist = Math.hypot(deltaX, deltaY); 3261 const oldDiag = Math.hypot(this.width * parentWidth, this.height * parentHeight); 3262 const blY = round(savedY + this.height); 3263 const ratio = Math.max(Math.min(1 + Math.sign(deltaX) * (dist / oldDiag), 1 / savedWidth, 1 / savedHeight), minWidth / savedWidth, minHeight / savedHeight); 3264 const newWidth = round(savedWidth * ratio); 3265 const newHeight = round(savedHeight * ratio); 3266 const newY = blY - newHeight; 3267 cmd = () => { 3268 this.width = newWidth; 3269 this.height = newHeight; 3270 this.y = newY; 3271 updatePosition(newWidth, newHeight); 3272 }; 3273 break; 3274 } 3275 case "middleRight": 3276 { 3277 const newWidth = round(Math.max(minWidth, Math.min(1, savedWidth + deltaX / parentWidth))); 3278 cmd = () => { 3279 this.width = newWidth; 3280 updatePosition(newWidth, savedHeight); 3281 }; 3282 break; 3283 } 3284 case "bottomRight": 3285 { 3286 if (Math.sign(deltaX) * Math.sign(deltaY) < 0) { 3287 return; 3288 } 3289 const dist = Math.hypot(deltaX, deltaY); 3290 const oldDiag = Math.hypot(this.width * parentWidth, this.height * parentHeight); 3291 const ratio = Math.max(Math.min(1 + Math.sign(deltaX) * (dist / oldDiag), 1 / savedWidth, 1 / savedHeight), minWidth / savedWidth, minHeight / savedHeight); 3292 const newWidth = round(savedWidth * ratio); 3293 const newHeight = round(savedHeight * ratio); 3294 cmd = () => { 3295 this.width = newWidth; 3296 this.height = newHeight; 3297 updatePosition(newWidth, newHeight); 3298 }; 3299 break; 3300 } 3301 case "bottomMiddle": 3302 { 3303 const newHeight = round(Math.max(minHeight, Math.min(1, savedHeight + deltaY / parentHeight))); 3304 cmd = () => { 3305 this.height = newHeight; 3306 updatePosition(savedWidth, newHeight); 3307 }; 3308 break; 3309 } 3310 case "bottomLeft": 3311 { 3312 if (Math.sign(deltaX) * Math.sign(deltaY) > 0) { 3313 return; 3314 } 3315 const dist = Math.hypot(deltaX, deltaY); 3316 const oldDiag = Math.hypot(this.width * parentWidth, this.height * parentHeight); 3317 const trX = round(savedX + this.width); 3318 const ratio = Math.max(Math.min(1 - Math.sign(deltaX) * (dist / oldDiag), 1 / savedWidth, 1 / savedHeight), minWidth / savedWidth, minHeight / savedHeight); 3319 const newWidth = round(savedWidth * ratio); 3320 const newHeight = round(savedHeight * ratio); 3321 const newX = trX - newWidth; 3322 cmd = () => { 3323 this.width = newWidth; 3324 this.height = newHeight; 3325 this.x = newX; 3326 updatePosition(newWidth, newHeight); 3327 }; 3328 break; 3329 } 3330 case "middleLeft": 3331 { 3332 const mrX = round(savedX + savedWidth); 3333 const newWidth = round(Math.max(minWidth, Math.min(1, savedWidth - deltaX / parentWidth))); 3334 const newX = mrX - newWidth; 3335 cmd = () => { 3336 this.width = newWidth; 3337 this.x = newX; 3338 updatePosition(newWidth, savedHeight); 3339 }; 3340 break; 3341 } 3342 } 3343 this.addCommands({ 3344 cmd, 3345 undo, 3346 mustExec: true, 3347 type: _util.AnnotationEditorParamsType.RESIZE, 3348 overwriteIfSameType: true, 3349 keepUndo: true 3350 }); 3351 } 3352 render() { 3353 this.div = document.createElement("div"); 3354 this.div.setAttribute("data-editor-rotation", (360 - this.rotation) % 360); 3355 this.div.className = this.name; 3356 this.div.setAttribute("id", this.id); 3357 this.div.setAttribute("tabIndex", 0); 3358 this.setInForeground(); 3359 this.div.addEventListener("focusin", this.#boundFocusin); 3360 this.div.addEventListener("focusout", this.#boundFocusout); 3361 const [parentWidth, parentHeight] = this.parentDimensions; 3362 if (this.parentRotation % 180 !== 0) { 3363 this.div.style.maxWidth = `${(100 * parentHeight / parentWidth).toFixed(2)}%`; 3364 this.div.style.maxHeight = `${(100 * parentWidth / parentHeight).toFixed(2)}%`; 3365 } 3366 const [tx, ty] = this.getInitialTranslation(); 3367 this.translate(tx, ty); 3368 (0, _tools.bindEvents)(this, this.div, ["dragstart", "pointerdown"]); 3369 return this.div; 3370 } 3371 pointerdown(event) { 3372 const { 3373 isMac 3374 } = _util.FeatureTest.platform; 3375 if (event.button !== 0 || event.ctrlKey && isMac) { 3376 event.preventDefault(); 3377 return; 3378 } 3379 if (event.ctrlKey && !isMac || event.shiftKey || event.metaKey && isMac) { 3380 this.parent.toggleSelected(this); 3381 } else { 3382 this.parent.setSelected(this); 3383 } 3384 this.#hasBeenSelected = true; 3385 } 3386 getRect(tx, ty) { 3387 const scale = this.parentScale; 3388 const [pageWidth, pageHeight] = this.pageDimensions; 3389 const [pageX, pageY] = this.pageTranslation; 3390 const shiftX = tx / scale; 3391 const shiftY = ty / scale; 3392 const x = this.x * pageWidth; 3393 const y = this.y * pageHeight; 3394 const width = this.width * pageWidth; 3395 const height = this.height * pageHeight; 3396 switch (this.rotation) { 3397 case 0: 3398 return [x + shiftX + pageX, pageHeight - y - shiftY - he
3398ight + pageY, x + shiftX + width + pageX, pageHeight - y - shiftY + pageY]; 3399 case 90: 3400 return [x + shiftY + pageX, pageHeight - y + shiftX + pageY, x + shiftY + height + pageX, pageHeight - y + shiftX + width + pageY]; 3401 case 180: 3402 return [x - shiftX - width + pageX, pageHeight - y + shiftY + pageY, x - shiftX + pageX, pageHeight - y + shiftY + height + pageY]; 3403 case 270: 3404 return [x - shiftY - height + pageX, pageHeight - y - shiftX - width + pageY, x - shiftY + pageX, pageHeight - y - shiftX + pageY]; 3405 default: 3406 throw new Error("Invalid rotation"); 3407 } 3408 } 3409 getRectInCurrentCoords(rect, pageHeight) { 3410 const [x1, y1, x2, y2] = rect; 3411 const width = x2 - x1; 3412 const height = y2 - y1; 3413 switch (this.rotation) { 3414 case 0: 3415 return [x1, pageHeight - y2, width, height]; 3416 case 90: 3417 return [x1, pageHeight - y1, height, width]; 3418 case 180: 3419 return [x2, pageHeight - y1, width, height]; 3420 case 270: 3421 return [x2, pageHeight - y2, height, width]; 3422 default: 3423 throw new Error("Invalid rotation"); 3424 } 3425 } 3426 onceAdded() {} 3427 isEmpty() { 3428 return false; 3429 } 3430 enableEditMode() { 3431 this.#isInEditMode = true; 3432 } 3433 disableEditMode() { 3434 this.#isInEditMode = false; 3435 } 3436 isInEditMode() { 3437 return this.#isInEditMode; 3438 } 3439 shouldGetKeyboardEvents() { 3440 return false; 3441 } 3442 needsToBeRebuilt() { 3443 return this.div && !this.isAttachedToDOM; 3444 } 3445 rebuild() { 3446 this.div?.addEventListener("focusin", this.#boundFocusin); 3447 this.div?.addEventListener("focusout", this.#boundFocusout); 3448 } 3449 serialize(_isForCopying = false, _context = null) { 3450 (0, _util.unreachable)("An editor must be serializable"); 3451 } 3452 static deserialize(data, parent, uiManager) { 3453 const editor = new this.prototype.constructor({ 3454 parent, 3455 id: parent.getNextId(), 3456 uiManager 3457 }); 3458 editor.rotation = data.rotation; 3459 const [pageWidth, pageHeight] = editor.pageDimensions; 3460 const [x, y, width, height] = editor.getRectInCurrentCoords(data.rect, pageHeight); 3461 editor.x = x / pageWidth; 3462 editor.y = y / pageHeight; 3463 editor.width = width / pageWidth; 3464 editor.height = height / pageHeight; 3465 return editor; 3466 } 3467 remove() { 3468 this.div.removeEventListener("focusin", this.#boundFocusin); 3469 this.div.removeEventListener("focusout", this.#boundFocusout); 3470 if (!this.isEmpty()) { 3471 this.commit(); 3472 } 3473 if (this.parent) { 3474 this.parent.remove(this); 3475 } else { 3476 this._uiManager.removeEditor(this); 3477 } 3478 } 3479 get isResizable() { 3480 return false; 3481 } 3482 makeResizable() { 3483 if (this.isResizable) { 3484 this.#createResizers(); 3485 this.#resizersDiv.classList.remove("hidden"); 3486 } 3487 } 3488 select() { 3489 this.makeResizable(); 3490 this.div?.classList.add("selectedEditor"); 3491 } 3492 unselect() { 3493 this.#resizersDiv?.classList.add("hidden"); 3494 this.div?.classList.remove("selectedEditor"); 3495 if (this.div?.contains(document.activeElement)) { 3496 this._uiManager.currentLayer.div.focus(); 3497 } 3498 } 3499 updateParams(type, value) {} 3500 disableEditing() {} 3501 enableEditing() {} 3502 enterInEditMode() {} 3503 get contentDiv() { 3504 return this.div; 3505 } 3506 get isEditing() { 3507 return this.#isEditing; 3508 } 3509 set isEditing(value) { 3510 this.#isEditing = value; 3511 if (!this.parent) { 3512 return; 3513 } 3514 if (value) { 3515 this.parent.setSelected(this); 3516 this.parent.setActiveEditor(this); 3517 } else { 3518 this.parent.setActiveEditor(null); 3519 } 3520 } 3521 setAspectRatio(width, height) { 3522 this.#keepAspectRatio = true; 3523 const aspectRatio = width / height; 3524 const { 3525 style 3526 } = this.div; 3527 style.aspectRatio = aspectRatio; 3528 style.height = "auto"; 3529 } 3530 static get MIN_SIZE() { 3531 return 16; 3532 } 3533} 3534exports.AnnotationEditor = AnnotationEditor; 3535class FakeEditor extends AnnotationEditor { 3536 constructor(params) { 3537 super(params); 3538 this.annotationElementId = params.annotationElementId; 3539 this.deleted = true; 3540 } 3541 serialize() { 3542 return { 3543 id: this.annotationElementId, 3544 deleted: true, 3545 pageIndex: this.pageIndex 3546 }; 3547 } 3548} 3549 3550/***/ }), 3551/* 5 */ 3552/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 3553 3554 3555 3556Object.defineProperty(exports, "__esModule", ({ 3557 value: true 3558})); 3559exports.KeyboardManager = exports.CommandManager = exports.ColorManager = exports.AnnotationEditorUIManager = void 0; 3560exports.bindEvents = bindEvents; 3561exports.opacityToHex = opacityToHex; 3562var _util = __w_pdfjs_require__(1); 3563var _display_utils = __w_pdfjs_require__(6); 3564function bindEvents(obj, element, names) { 3565 for (const name of names) { 3566 element.addEventListener(name, obj[name].bind(obj)); 3567 } 3568} 3569function opacityToHex(opacity) { 3570 return Math.round(Math.min(255, Math.max(1, 255 * opacity))).toString(16).padStart(2, "0"); 3571} 3572class IdManager { 3573 #id = 0; 3574 getId() { 3575 return `${_util.AnnotationEditorPrefix}${this.#id++}`; 3576 } 3577} 3578class ImageManager { 3579 #baseId = (0, _util.getUuid)(); 3580 #id = 0; 3581 #cache = null; 3582 async #get(key, rawData) { 3583 this.#cache ||= new Map(); 3584 let data = this.#cache.get(key); 3585 if (data === null) { 3586 return null; 3587 } 3588 if (data?.bitmap) { 3589 data.refCounter += 1; 3590 return data; 3591 } 3592 try { 3593 data ||= { 3594 bitmap: null, 3595 id: `image_${this.#baseId}_${this.#id++}`, 3596 refCounter: 0, 3597 isSvg: false 3598 }; 3599 let image; 3600 if (typeof rawData === "string") { 3601 data.url = rawData; 3602 const response = await fetch(rawData); 3603 if (!response.ok) { 3604 throw new Error(response.statusText); 3605 } 3606 image = await response.blob(); 3607 } else { 3608 image = data.file = rawData; 3609 } 3610 if (image.type === "image/svg+xml") { 3611 const fileReader = new FileReader(); 3612 const imageElement = new Image(); 3613 const imagePromise = new Promise((resolve, reject) => { 3614 imageElement.onload = () => { 3615 data.bitmap = imageElement; 3616 data.isSvg = true; 3617 resolve(); 3618 }; 3619 fileReader.onload = () => { 3620 imageElement.src = data.svgUrl = fileReader.result; 3621 }; 3622 imageElement.onerror = fileReader.onerror = reject; 3623 });
vendor: 6,143 bytes, lines 3624-3889
3624 fileReader.readAsDataURL(image); 3625 await imagePromise; 3626 } else { 3627 data.bitmap = await createImageBitmap(image); 3628 } 3629 data.refCounter = 1; 3630 } catch (e) { 3631 console.error(e); 3632 data = null; 3633 } 3634 this.#cache.set(key, data); 3635 if (data) { 3636 this.#cache.set(data.id, data); 3637 } 3638 return data; 3639 } 3640 async getFromFile(file) { 3641 const { 3642 lastModified, 3643 name, 3644 size, 3645 type 3646 } = file; 3647 return this.#get(`${lastModified}_${name}_${size}_${type}`, file); 3648 } 3649 async getFromUrl(url) { 3650 return this.#get(url, url); 3651 } 3652 async getFromId(id) { 3653 this.#cache ||= new Map(); 3654 const data = this.#cache.get(id); 3655 if (!data) { 3656 return null; 3657 } 3658 if (data.bitmap) { 3659 data.refCounter += 1; 3660 return data; 3661 } 3662 if (data.file) { 3663 return this.getFromFile(data.file); 3664 } 3665 return this.getFromUrl(data.url); 3666 } 3667 getSvgUrl(id) { 3668 const data = this.#cache.get(id); 3669 if (!data?.isSvg) { 3670 return null; 3671 } 3672 return data.svgUrl; 3673 } 3674 deleteId(id) { 3675 this.#cache ||= new Map(); 3676 const data = this.#cache.get(id); 3677 if (!data) { 3678 return; 3679 } 3680 data.refCounter -= 1; 3681 if (data.refCounter !== 0) { 3682 return; 3683 } 3684 data.bitmap = null; 3685 } 3686 isValidId(id) { 3687 return id.startsWith(`image_${this.#baseId}_`); 3688 } 3689} 3690class CommandManager { 3691 #commands = []; 3692 #locked = false; 3693 #maxSize; 3694 #position = -1; 3695 constructor(maxSize = 128) { 3696 this.#maxSize = maxSize; 3697 } 3698 add({ 3699 cmd, 3700 undo, 3701 mustExec, 3702 type = NaN, 3703 overwriteIfSameType = false, 3704 keepUndo = false 3705 }) { 3706 if (mustExec) { 3707 cmd(); 3708 } 3709 if (this.#locked) { 3710 return; 3711 } 3712 const save = { 3713 cmd, 3714 undo, 3715 type 3716 }; 3717 if (this.#position === -1) { 3718 if (this.#commands.length > 0) { 3719 this.#commands.length = 0; 3720 } 3721 this.#position = 0; 3722 this.#commands.push(save); 3723 return; 3724 } 3725 if (overwriteIfSameType && this.#commands[this.#position].type === type) { 3726 if (keepUndo) { 3727 save.undo = this.#commands[this.#position].undo; 3728 } 3729 this.#commands[this.#position] = save; 3730 return; 3731 } 3732 const next = this.#position + 1; 3733 if (next === this.#maxSize) { 3734 this.#commands.splice(0, 1); 3735 } else { 3736 this.#position = next; 3737 if (next < this.#commands.length) { 3738 this.#commands.splice(next); 3739 } 3740 } 3741 this.#commands.push(save); 3742 } 3743 stopUndoAccumulation() { 3744 if (this.#position !== -1) { 3745 this.#commands[this.#position].type = NaN; 3746 } 3747 } 3748 undo() { 3749 if (this.#position === -1) { 3750 return; 3751 } 3752 this.#locked = true; 3753 this.#commands[this.#position].undo(); 3754 this.#locked = false; 3755 this.#position -= 1; 3756 } 3757 redo() { 3758 if (this.#position < this.#commands.length - 1) { 3759 this.#position += 1; 3760 this.#locked = true; 3761 this.#commands[this.#position].cmd(); 3762 this.#locked = false; 3763 } 3764 } 3765 hasSomethingToUndo() { 3766 return this.#position !== -1; 3767 } 3768 hasSomethingToRedo() { 3769 return this.#position < this.#commands.length - 1; 3770 } 3771 destroy() { 3772 this.#commands = null; 3773 } 3774} 3775exports.CommandManager = CommandManager; 3776class KeyboardManager { 3777 constructor(callbacks) { 3778 this.buffer = []; 3779 this.callbacks = new Map(); 3780 this.allKeys = new Set(); 3781 const { 3782 isMac 3783 } = _util.FeatureTest.platform; 3784 for (const [keys, callback, options = {}] of callbacks) { 3785 for (const key of keys) { 3786 const isMacKey = key.startsWith("mac+"); 3787 if (isMac && isMacKey) { 3788 this.callbacks.set(key.slice(4), { 3789 callback, 3790 options 3791 }); 3792 this.allKeys.add(key.split("+").at(-1)); 3793 } else if (!isMac && !isMacKey) { 3794 this.callbacks.set(key, { 3795 callback, 3796 options 3797 }); 3798 this.allKeys.add(key.split("+").at(-1)); 3799 } 3800 } 3801 } 3802 } 3803 #serialize(event) { 3804 if (event.altKey) { 3805 this.buffer.push("alt"); 3806 } 3807 if (event.ctrlKey) { 3808 this.buffer.push("ctrl"); 3809 } 3810 if (event.metaKey) { 3811 this.buffer.push("meta"); 3812 } 3813 if (event.shiftKey) { 3814 this.buffer.push("shift"); 3815 } 3816 this.buffer.push(event.key); 3817 const str = this.buffer.join("+"); 3818 this.buffer.length = 0; 3819 return str; 3820 } 3821 exec(self, event) { 3822 if (!this.allKeys.has(event.key)) { 3823 return; 3824 } 3825 const info = this.callbacks.get(this.#serialize(event)); 3826 if (!info) { 3827 return; 3828 } 3829 const { 3830 callback, 3831 options: { 3832 bubbles = false, 3833 args = [], 3834 checker = null 3835 } 3836 } = info; 3837 if (checker && !checker(self, event)) { 3838 return; 3839 } 3840 callback.bind(self, ...args)(); 3841 if (!bubbles) { 3842 event.stopPropagation(); 3843 event.preventDefault(); 3844 } 3845 } 3846} 3847exports.KeyboardManager = KeyboardManager; 3848class ColorManager { 3849 static _colorsMapping = new Map([["CanvasText", [0, 0, 0]], ["Canvas", [255, 255, 255]]]); 3850 get _colors() { 3851 const colors = new Map([["CanvasText", null], ["Canvas", null]]); 3852 (0, _display_utils.getColorValues)(colors); 3853 return (0, _util.shadow)(this, "_colors", colors); 3854 } 3855 convert(color) { 3856 const rgb = (0, _display_utils.getRGB)(color); 3857 if (!window.matchMedia("(forced-colors: active)").matches) { 3858 return rgb; 3859 } 3860 for (const [name, RGB] of this._colors) { 3861 if (RGB.every((x, i) => x === rgb[i])) { 3862 return ColorManager._colorsMapping.get(name); 3863 } 3864 } 3865 return rgb; 3866 } 3867 getHexCode(name) { 3868 const rgb = this._colors.get(name); 3869 if (!rgb) { 3870 return name; 3871 } 3872 return _util.Util.makeHexColor(...rgb); 3873 } 3874} 3875exports.ColorManager = ColorManager; 3876class AnnotationEditorUIManager { 3877 #activeEditor = null; 3878 #allEditors = new Map(); 3879 #allLayers = new Map(); 3880 #annotationStorage = null; 3881 #commandManager = new CommandManager(); 3882 #currentPageIndex = 0; 3883 #deletedAnnotationsElementIds = new Set(); 3884 #editorTypes = null; 3885 #editorsToRescale = new Set(); 3886 #eventBus = null; 3887 #filterFactory = null; 3888 #idManager = new IdManager(); 3889 #isEnabled = false;
3890 #mode = _util.AnnotationEditorType.NONE; 3891 #selectedEditors = new Set(); 3892 #pageColors = null; 3893 #boundCopy = this.copy.bind(this); 3894 #boundCut = this.cut.bind(this); 3895 #boundPaste = this.paste.bind(this); 3896 #boundKeydown = this.keydown.bind(this); 3897 #boundOnEditingAction = this.onEditingAction.bind(this); 3898 #boundOnPageChanging = this.onPageChanging.bind(this); 3899 #boundOnScaleChanging = this.onScaleChanging.bind(this); 3900 #boundOnRotationChanging = this.onRotationChanging.bind(this); 3901 #previousStates = { 3902 isEditing: false, 3903 isEmpty: true, 3904 hasSomethingToUndo: false, 3905 hasSomethingToRedo: false, 3906 hasSelectedEditor: false 3907 }; 3908 #translation = [0, 0]; 3909 #translationTimeoutId = null; 3910 #container = null; 3911 static TRANSLATE_SMALL = 1; 3912 static TRANSLATE_BIG = 10; 3913 static get _keyboardManager() { 3914 const proto = AnnotationEditorUIManager.prototype; 3915 const arrowChecker = self => { 3916 const { 3917 activeElement 3918 } = document; 3919 return activeElement && self.#container.contains(activeElement) && self.hasSomethingToControl(); 3920 }; 3921 const small = this.TRANSLATE_SMALL; 3922 const big = this.TRANSLATE_BIG; 3923 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, { 3924 args: [-small, 0], 3925 checker: arrowChecker 3926 }], [["ctrl+ArrowLeft", "mac+shift+ArrowLeft"], proto.translateSelectedEditors, { 3927 args: [-big, 0], 3928 checker: arrowChecker 3929 }], [["ArrowRight", "mac+ArrowRight"], proto.translateSelectedEditors, { 3930 args: [small, 0], 3931 checker: arrowChecker 3932 }], [["ctrl+ArrowRight", "mac+shift+ArrowRight"], proto.translateSelectedEditors, { 3933 args: [big, 0], 3934 checker: arrowChecker 3935 }], [["ArrowUp", "mac+ArrowUp"], proto.translateSelectedEditors, { 3936 args: [0, -small], 3937 checker: arrowChecker 3938 }], [["ctrl+ArrowUp", "mac+shift+ArrowUp"], proto.translateSelectedEditors, { 3939 args: [0, -big], 3940 checker: arrowChecker 3941 }], [["ArrowDown", "mac+ArrowDown"], proto.translateSelectedEditors, { 3942 args: [0, small], 3943 checker: arrowChecker 3944 }], [["ctrl+ArrowDown", "mac+shift+ArrowDown"], proto.translateSelectedEditors, { 3945 args: [0, big], 3946 checker: arrowChecker 3947 }]])); 3948 } 3949 constructor(container, eventBus, pdfDocument, pageColors) { 3950 this.#container = container; 3951 this.#eventBus = eventBus; 3952 this.#eventBus._on("editingaction", this.#boundOnEditingAction); 3953 this.#eventBus._on("pagechanging", this.#boundOnPageChanging); 3954 this.#eventBus._on("scalechanging", this.#boundOnScaleChanging); 3955 this.#eventBus._on("rotationchanging", this.#boundOnRotationChanging); 3956 this.#annotationStorage = pdfDocument.annotationStorage; 3957 this.#filterFactory = pdfDocument.filterFactory; 3958 this.#pageColors = pageColors; 3959 this.viewParameters = { 3960 realScale: _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS, 3961 rotation: 0 3962 }; 3963 } 3964 destroy() { 3965 this.#removeKeyboardManager(); 3966 this.#eventBus._off("editingaction", this.#boundOnEditingAction); 3967 this.#eventBus._off("pagechanging", this.#boundOnPageChanging); 3968 this.#eventBus._off("scalechanging", this.#boundOnScaleChanging); 3969 this.#eventBus._off("rotationchanging", this.#boundOnRotationChanging); 3970 for (const layer of this.#allLayers.values()) { 3971 layer.destroy(); 3972 } 3973 this.#allLayers.clear(); 3974 this.#allEditors.clear(); 3975 this.#editorsToRescale.clear(); 3976 this.#activeEditor = null; 3977 this.#selectedEditors.clear(); 3978 this.#commandManager.destroy(); 3979 } 3980 get hcmFilter() { 3981 return (0, _util.shadow)(this, "hcmFilter", this.#pageColors ? this.#filterFactory.addHCMFilter(this.#pageColors.foreground, this.#pageColors.background) : "none"); 3982 } 3983 onPageChanging({ 3984 pageNumber 3985 }) { 3986 this.#currentPageIndex = pageNumber - 1; 3987 } 3988 focusMainContainer() { 3989 this.#container.focus(); 3990 } 3991 addShouldRescale(editor) { 3992 this.#editorsToRescale.add(editor); 3993 } 3994 removeShouldRescale(editor) { 3995 this.#editorsToRescale.delete(editor); 3996 } 3997 onScaleChanging({ 3998 scale 3999 }) { 4000 this.commitOrRemove(); 4001 this.viewParameters.realScale = scale * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS; 4002 for (const editor of this.#editorsToRescale) { 4003 editor.onScaleChanging(); 4004 } 4005 } 4006 onRotationChanging({ 4007 pagesRotation 4008 }) { 4009 this.commitOrRemove(); 4010 this.viewParameters.rotation = pagesRotation; 4011 } 4012 addToAnnotationStorage(editor) { 4013 if (!editor.isEmpty() && this.#annotationStorage && !this.#annotationStorage.has(editor.id)) { 4014 this.#annotationStorage.setValue(editor.id, editor); 4015 } 4016 } 4017 #addKeyboardManager() { 4018 window.addEventListener("keydown", this.#boundKeydown, { 4019 capture: true 4020 }); 4021 } 4022 #removeKeyboardManager() { 4023 window.removeEventListener("keydown", this.#boundKeydown, { 4024 capture: true 4025 }); 4026 } 4027 #addCopyPasteListeners() { 4028 document.addEventListener("copy", this.#boundCopy); 4029 document.addEventListener("cut", this.#boundCut); 4030 document.addEventListener("paste", this.#boundPaste); 4031 } 4032 #removeCopyPasteListeners() { 4033 document.removeEventListener("copy", this.#boundCopy); 4034 document.removeEventListener("cut", this.#boundCut); 4035 document.removeEventListener("paste", this.#boundPaste); 4036 } 4037 copy(event) { 4038 event.preventDefault(); 4039 if (this.#activeEditor) { 4040 this.#activeEditor.commitOrRemove(); 4041 } 4042 if (!this.hasSelection) { 4043 return; 4044 } 4045 const editors = []; 4046 for (const editor of this.#selectedEditors) { 4047 const serialized = editor.serialize(true); 4048 if (serialized) { 4049 editors.push(serialized); 4050 } 4051 } 4052 if (editors.length === 0) { 4053 return; 4054 } 4055 event.clipboardData.setData("application/pdfjs", JSON.stringify(editors)); 4056 } 4057 cut(event) { 4058 this.copy(event); 4059 this.delete(); 4060 } 4061 paste(event) { 4062 event.preventDefault(); 4063 let data = event.clipboardData.getData("application/pdfjs"); 4064 if (!data) { 4065 return; 4066 } 4067 try { 4068 data = JSON.parse(data); 4069 } catch (ex) { 4070 (0, _util.warn)(`paste: "${ex.message}".`); 4071 return; 4072 } 4073 if (!Array.isArray(data)) { 4074 return; 4075 } 4076 this.unselectAll(); 4077 const layer = this.currentLayer; 4078 try { 4079 const newEditors = []; 4080 for (const editor of data) { 4081 const deserializedEditor = layer.deserialize(editor); 4082 if (!deserializedEditor) { 4083 return; 4084 } 4085 newEditors.push(deserializedEditor); 4086 } 4087 const cmd = () => { 4088 for (const editor of newEditors) { 4089 this.#addEditorToLayer(editor); 4090 } 4091 this.#selectEditors(newEditors); 4092 }; 4093 const undo = () => { 4094 for (const editor of newEditors) { 4095 editor.remove(); 4096 } 4097 }; 4098 this.addCommands({ 4099 cmd, 4100 undo, 4101 mustExec: true 4102 }); 4103 } catch (ex) { 4104 (0, _util.warn)(`paste: "${ex.message}".`); 4105 } 4106 } 4107 keydown(event) { 4108 if (!this.getActive()?.shouldGetKeyboardEvents()) { 4109 AnnotationEditorUIManager._keyboardManager.exec(this, event); 4110 } 4111 } 4112 onEditingAction(details) {
4113 if (["undo", "redo", "delete", "selectAll"].includes(details.name)) { 4114 this[details.name](); 4115 } 4116 } 4117 #dispatchUpdateStates(details) { 4118 const hasChanged = Object.entries(details).some(([key, value]) => this.#previousStates[key] !== value); 4119 if (hasChanged) { 4120 this.#eventBus.dispatch("annotationeditorstateschanged", { 4121 source: this, 4122 details: Object.assign(this.#previousStates, details) 4123 }); 4124 } 4125 } 4126 #dispatchUpdateUI(details) { 4127 this.#eventBus.dispatch("annotationeditorparamschanged", { 4128 source: this, 4129 details 4130 }); 4131 } 4132 setEditingState(isEditing) { 4133 if (isEditing) { 4134 this.#addKeyboardManager(); 4135 this.#addCopyPasteListeners(); 4136 this.#dispatchUpdateStates({ 4137 isEditing: this.#mode !== _util.AnnotationEditorType.NONE, 4138 isEmpty: this.#isEmpty(), 4139 hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(), 4140 hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(), 4141 hasSelectedEditor: false 4142 }); 4143 } else { 4144 this.#removeKeyboardManager(); 4145 this.#removeCopyPasteListeners(); 4146 this.#dispatchUpdateStates({ 4147 isEditing: false 4148 }); 4149 } 4150 } 4151 registerEditorTypes(types) { 4152 if (this.#editorTypes) { 4153 return; 4154 } 4155 this.#editorTypes = types; 4156 for (const editorType of this.#editorTypes) { 4157 this.#dispatchUpdateUI(editorType.defaultPropertiesToUpdate); 4158 } 4159 } 4160 getId() { 4161 return this.#idManager.getId(); 4162 } 4163 get currentLayer() { 4164 return this.#allLayers.get(this.#currentPageIndex); 4165 } 4166 get currentPageIndex() { 4167 return this.#currentPageIndex; 4168 } 4169 addLayer(layer) { 4170 this.#allLayers.set(layer.pageIndex, layer); 4171 if (this.#isEnabled) { 4172 layer.enable(); 4173 } else { 4174 layer.disable(); 4175 } 4176 } 4177 removeLayer(layer) { 4178 this.#allLayers.delete(layer.pageIndex); 4179 } 4180 updateMode(mode, editId = null) { 4181 this.#mode = mode; 4182 if (mode === _util.AnnotationEditorType.NONE) { 4183 this.setEditingState(false); 4184 this.#disableAll(); 4185 return; 4186 } 4187 this.setEditingState(true); 4188 this.#enableAll(); 4189 for (const layer of this.#allLayers.values()) { 4190 layer.updateMode(mode); 4191 } 4192 if (!editId) { 4193 return; 4194 } 4195 for (const editor of this.#allEditors.values()) { 4196 if (editor.annotationElementId === editId) { 4197 this.setSelected(editor); 4198 editor.enterInEditMode(); 4199 break; 4200 } 4201 } 4202 } 4203 updateToolbar(mode) { 4204 if (mode === this.#mode) { 4205 return; 4206 } 4207 this.#eventBus.dispatch("switchannotationeditormode", { 4208 source: this, 4209 mode 4210 }); 4211 } 4212 updateParams(type, value) { 4213 if (!this.#editorTypes) { 4214 return; 4215 } 4216 for (const editor of this.#selectedEditors) { 4217 editor.updateParams(type, value); 4218 } 4219 for (const editorType of this.#editorTypes) { 4220 editorType.updateDefaultParams(type, value); 4221 } 4222 } 4223 #enableAll() { 4224 if (!this.#isEnabled) { 4225 this.#isEnabled = true; 4226 for (const layer of this.#allLayers.values()) { 4227 layer.enable(); 4228 } 4229 } 4230 } 4231 #disableAll() { 4232 this.unselectAll(); 4233 if (this.#isEnabled) { 4234 this.#isEnabled = false; 4235 for (const layer of this.#allLayers.values()) { 4236 layer.disable(); 4237 } 4238 } 4239 } 4240 getEditors(pageIndex) { 4241 const editors = []; 4242 for (const editor of this.#allEditors.values()) { 4243 if (editor.pageIndex === pageIndex) { 4244 editors.push(editor); 4245 } 4246 } 4247 return editors; 4248 } 4249 getEditor(id) { 4250 return this.#allEditors.get(id); 4251 } 4252 addEditor(editor) { 4253 this.#allEditors.set(editor.id, editor); 4254 } 4255 removeEditor(editor) { 4256 this.#allEditors.delete(editor.id); 4257 this.unselect(editor); 4258 if (!editor.annotationElementId || !this.#deletedAnnotationsElementIds.has(editor.annotationElementId)) { 4259 this.#annotationStorage?.remove(editor.id); 4260 } 4261 } 4262 addDeletedAnnotationElement(editor) { 4263 this.#deletedAnnotationsElementIds.add(editor.annotationElementId); 4264 editor.deleted = true; 4265 } 4266 isDeletedAnnotationElement(annotationElementId) { 4267 return this.#deletedAnnotationsElementIds.has(annotationElementId); 4268 } 4269 removeDeletedAnnotationElement(editor) { 4270 this.#deletedAnnotationsElementIds.delete(editor.annotationElementId); 4271 editor.deleted = false;
vendor: 5,694 bytes, lines 4272-4498
4272 } 4273 #addEditorToLayer(editor) { 4274 const layer = this.#allLayers.get(editor.pageIndex); 4275 if (layer) { 4276 layer.addOrRebuild(editor); 4277 } else { 4278 this.addEditor(editor); 4279 } 4280 } 4281 setActiveEditor(editor) { 4282 if (this.#activeEditor === editor) { 4283 return; 4284 } 4285 this.#activeEditor = editor; 4286 if (editor) { 4287 this.#dispatchUpdateUI(editor.propertiesToUpdate); 4288 } 4289 } 4290 toggleSelected(editor) { 4291 if (this.#selectedEditors.has(editor)) { 4292 this.#selectedEditors.delete(editor); 4293 editor.unselect(); 4294 this.#dispatchUpdateStates({ 4295 hasSelectedEditor: this.hasSelection 4296 }); 4297 return; 4298 } 4299 this.#selectedEditors.add(editor); 4300 editor.select(); 4301 this.#dispatchUpdateUI(editor.propertiesToUpdate); 4302 this.#dispatchUpdateStates({ 4303 hasSelectedEditor: true 4304 }); 4305 } 4306 setSelected(editor) { 4307 for (const ed of this.#selectedEditors) { 4308 if (ed !== editor) { 4309 ed.unselect(); 4310 } 4311 } 4312 this.#selectedEditors.clear(); 4313 this.#selectedEditors.add(editor); 4314 editor.select(); 4315 this.#dispatchUpdateUI(editor.propertiesToUpdate); 4316 this.#dispatchUpdateStates({ 4317 hasSelectedEditor: true 4318 }); 4319 } 4320 isSelected(editor) { 4321 return this.#selectedEditors.has(editor); 4322 } 4323 unselect(editor) { 4324 editor.unselect(); 4325 this.#selectedEditors.delete(editor); 4326 this.#dispatchUpdateStates({ 4327 hasSelectedEditor: this.hasSelection 4328 }); 4329 } 4330 get hasSelection() { 4331 return this.#selectedEditors.size !== 0; 4332 } 4333 stopUndoAccumulation() { 4334 this.#commandManager.stopUndoAccumulation(); 4335 } 4336 undo() { 4337 this.#commandManager.undo(); 4338 this.#dispatchUpdateStates({ 4339 hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(), 4340 hasSomethingToRedo: true, 4341 isEmpty: this.#isEmpty() 4342 }); 4343 } 4344 redo() { 4345 this.#commandManager.redo(); 4346 this.#dispatchUpdateStates({ 4347 hasSomethingToUndo: true, 4348 hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(), 4349 isEmpty: this.#isEmpty() 4350 }); 4351 } 4352 addCommands(params) { 4353 this.#commandManager.add(params); 4354 this.#dispatchUpdateStates({ 4355 hasSomethingToUndo: true, 4356 hasSomethingToRedo: false, 4357 isEmpty: this.#isEmpty() 4358 }); 4359 } 4360 #isEmpty() { 4361 if (this.#allEditors.size === 0) { 4362 return true; 4363 } 4364 if (this.#allEditors.size === 1) { 4365 for (const editor of this.#allEditors.values()) { 4366 return editor.isEmpty(); 4367 } 4368 } 4369 return false; 4370 } 4371 delete() { 4372 this.commitOrRemove(); 4373 if (!this.hasSelection) { 4374 return; 4375 } 4376 const editors = [...this.#selectedEditors]; 4377 const cmd = () => { 4378 for (const editor of editors) { 4379 editor.remove(); 4380 } 4381 }; 4382 const undo = () => { 4383 for (const editor of editors) { 4384 this.#addEditorToLayer(editor); 4385 } 4386 }; 4387 this.addCommands({ 4388 cmd, 4389 undo, 4390 mustExec: true 4391 }); 4392 } 4393 commitOrRemove() { 4394 this.#activeEditor?.commitOrRemove(); 4395 } 4396 hasSomethingToControl() { 4397 return this.#activeEditor || this.hasSelection; 4398 } 4399 #selectEditors(editors) { 4400 this.#selectedEditors.clear(); 4401 for (const editor of editors) { 4402 if (editor.isEmpty()) { 4403 continue; 4404 } 4405 this.#selectedEditors.add(editor); 4406 editor.select(); 4407 } 4408 this.#dispatchUpdateStates({ 4409 hasSelectedEditor: true 4410 }); 4411 } 4412 selectAll() { 4413 for (const editor of this.#selectedEditors) { 4414 editor.commit(); 4415 } 4416 this.#selectEditors(this.#allEditors.values()); 4417 } 4418 unselectAll() { 4419 if (this.#activeEditor) { 4420 this.#activeEditor.commitOrRemove(); 4421 return; 4422 } 4423 if (!this.hasSelection) { 4424 return; 4425 } 4426 for (const editor of this.#selectedEditors) { 4427 editor.unselect(); 4428 } 4429 this.#selectedEditors.clear(); 4430 this.#dispatchUpdateStates({ 4431 hasSelectedEditor: false 4432 }); 4433 } 4434 translateSelectedEditors(x, y, noCommit = false) { 4435 if (!noCommit) { 4436 this.commitOrRemove(); 4437 } 4438 if (!this.hasSelection) { 4439 return; 4440 } 4441 this.#translation[0] += x; 4442 this.#translation[1] += y; 4443 const [totalX, totalY] = this.#translation; 4444 const editors = [...this.#selectedEditors]; 4445 const TIME_TO_WAIT = 1000; 4446 if (this.#translationTimeoutId) { 4447 clearTimeout(this.#translationTimeoutId); 4448 } 4449 this.#translationTimeoutId = setTimeout(() => { 4450 this.#translationTimeoutId = null; 4451 this.#translation[0] = this.#translation[1] = 0; 4452 this.addCommands({ 4453 cmd: () => { 4454 for (const editor of editors) { 4455 if (this.#allEditors.has(editor.id)) { 4456 editor.translateInPage(totalX, totalY); 4457 } 4458 } 4459 }, 4460 undo: () => { 4461 for (const editor of editors) { 4462 if (this.#allEditors.has(editor.id)) { 4463 editor.translateInPage(-totalX, -totalY); 4464 } 4465 } 4466 }, 4467 mustExec: false 4468 }); 4469 }, TIME_TO_WAIT); 4470 for (const editor of editors) { 4471 editor.translateInPage(x, y); 4472 } 4473 } 4474 isActive(editor) { 4475 return this.#activeEditor === editor; 4476 } 4477 getActive() { 4478 return this.#activeEditor; 4479 } 4480 getMode() { 4481 return this.#mode; 4482 } 4483 get imageManager() { 4484 return (0, _util.shadow)(this, "imageManager", new ImageManager()); 4485 } 4486} 4487exports.AnnotationEditorUIManager = AnnotationEditorUIManager; 4488 4489/***/ }), 4490/* 6 */ 4491/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 4492 4493 4494 4495Object.defineProperty(exports, "__esModule", ({ 4496 value: true 4497})); 4498exports.StatTimer = exports.RenderingCancelledException = exports.PixelsPerInch = exports.PageViewport = exports.PDFDateString = exports.DOMStandardFontDataFactory = exp
4498orts.DOMSVGFactory = exports.DOMFilterFactory = exports.DOMCanvasFactory = exports.DOMCMapReaderFactory = exports.AnnotationPrefix = void 0; 4499exports.deprecated = deprecated; 4500exports.getColorValues = getColorValues; 4501exports.getCurrentTransform = getCurrentTransform; 4502exports.getCurrentTransformInverse = getCurrentTransformInverse; 4503exports.getFilenameFromUrl = getFilenameFromUrl; 4504exports.getPdfFilenameFromUrl = getPdfFilenameFromUrl; 4505exports.getRGB = getRGB; 4506exports.getXfaPageViewport = getXfaPageViewport; 4507exports.isDataScheme = isDataScheme; 4508exports.isPdfFile = isPdfFile; 4509exports.isValidFetchUrl = isValidFetchUrl; 4510exports.loadScript = loadScript; 4511exports.setLayerDimensions = setLayerDimensions; 4512var _base_factory = __w_pdfjs_require__(7); 4513var _util = __w_pdfjs_require__(1); 4514const SVG_NS = "http://www.w3.org/2000/svg"; 4515const AnnotationPrefix = "pdfjs_internal_id_"; 4516exports.AnnotationPrefix = AnnotationPrefix; 4517class PixelsPerInch { 4518 static CSS = 96.0; 4519 static PDF = 72.0; 4520 static PDF_TO_CSS_UNITS = this.CSS / this.PDF; 4521} 4522exports.PixelsPerInch = PixelsPerInch; 4523class DOMFilterFactory extends _base_factory.BaseFilterFactory { 4524 #_cache; 4525 #_defs; 4526 #docId; 4527 #document; 4528 #hcmFilter; 4529 #hcmKey; 4530 #hcmUrl; 4531 #hcmHighlightFilter; 4532 #hcmHighlightKey; 4533 #hcmHighlightUrl; 4534 #id = 0; 4535 constructor({ 4536 docId, 4537 ownerDocument = globalThis.document 4538 } = {}) { 4539 super(); 4540 this.#docId = docId; 4541 this.#document = ownerDocument; 4542 } 4543 get #cache() { 4544 return this.#_cache ||= new Map(); 4545 } 4546 get #defs() { 4547 if (!this.#_defs) { 4548 const div = this.#document.createElement("div"); 4549 const { 4550 style 4551 } = div; 4552 style.visibility = "hidden"; 4553 style.contain = "strict"; 4554 style.width = style.height = 0; 4555 style.position = "absolute"; 4556 style.top = style.left = 0; 4557 style.zIndex = -1; 4558 const svg = this.#document.createElementNS(SVG_NS, "svg"); 4559 svg.setAttribute("width", 0); 4560 svg.setAttribute("height", 0); 4561 this.#_defs = this.#document.createElementNS(SVG_NS, "defs"); 4562 div.append(svg); 4563 svg.append(this.#_defs); 4564 this.#document.body.append(div); 4565 } 4566 return this.#_defs; 4567 } 4568 addFilter(maps) { 4569 if (!maps) { 4570 return "none"; 4571 } 4572 let value = this.#cache.get(maps); 4573 if (value) { 4574 return value; 4575 } 4576 let tableR, tableG, tableB, key; 4577 if (maps.length === 1) { 4578 const mapR = maps[0]; 4579 const buffer = new Array(256); 4580 for (let i = 0; i < 256; i++) { 4581 buffer[i] = mapR[i] / 255; 4582 } 4583 key = tableR = tableG = tableB = buffer.join(","); 4584 } else { 4585 const [mapR, mapG, mapB] = maps; 4586 const bufferR = new Array(256); 4587 const bufferG = new Array(256); 4588 const bufferB = new Array(256); 4589 for (let i = 0; i < 256; i++) { 4590 bufferR[i] = mapR[i] / 255; 4591 bufferG[i] = mapG[i] / 255; 4592 bufferB[i] = mapB[i] / 255; 4593 } 4594 tableR = bufferR.join(","); 4595 tableG = bufferG.join(","); 4596 tableB = bufferB.join(","); 4597 key = `${tableR}${tableG}${tableB}`; 4598 } 4599 value = this.#cache.get(key); 4600 if (value) { 4601 this.#cache.set(maps, value); 4602 return value; 4603 } 4604 const id = `g_${this.#docId}_transfer_map_${this.#id++}`; 4605 const url = `url(#${id})`; 4606 this.#cache.set(maps, url); 4607 this.#cache.set(key, url); 4608 const filter = this.#createFilter(id); 4609 this.#addTransferMapConversion(tableR, tableG, tableB, filter); 4610 return url; 4611 } 4612 addHCMFilter(fgColor, bgColor) { 4613 const key = `${fgColor}-${bgColor}`; 4614 if (this.#hcmKey === key) { 4615 return this.#hcmUrl; 4616 } 4617 this.#hcmKey = key; 4618 this.#hcmUrl = "none"; 4619 this.#hcmFilter?.remove(); 4620 if (!fgColor || !bgColor) { 4621 return this.#hcmUrl; 4622 } 4623 const fgRGB = this.#getRGB(fgColor); 4624 fgColor = _util.Util.makeHexColor(...fgRGB); 4625 const bgRGB = this.#getRGB(bgColor); 4626 bgColor = _util.Util.makeHexColor(...bgRGB); 4627 this.#defs.style.color = ""; 4628 if (fgColor === "#000000" && bgColor === "#ffffff" || fgColor === bgColor) { 4629 return this.#hcmUrl; 4630 } 4631 const map = new Array(256); 4632 for (let i = 0; i <= 255; i++) { 4633 const x = i / 255; 4634 map[i] = x <= 0.03928 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4; 4635 } 4636 const table = map.join(","); 4637 const id = `g_${this.#docId}_hcm_filter`; 4638 const filter = this.#hcmHighlightFilter = this.#createFilter(id); 4639 this.#addTransferMapConversion(table, table, table, filter); 4640 this.#addGrayConversion(filter); 4641 const getSteps = (c, n) => { 4642 const start = fgRGB[c] / 255; 4643 const end = bgRGB[c] / 255; 4644 const arr = new Array(n + 1); 4645 for (let i = 0; i <= n; i++) { 4646 arr[i] = start + i / n * (end - start); 4647 } 4648 return arr.join(","); 4649 }; 4650 this.#addTransferMapConversion(getSteps(0, 5), getSteps(1, 5), getSteps(2, 5), filter); 4651 this.#hcmUrl = `url(#${id})`; 4652 return this.#hcmUrl; 4653 } 4654 addHighlightHCMFilter(fgColor, bgColor, newFgColor, newBgColor) {
4655 const key = `${fgColor}-${bgColor}-${newFgColor}-${newBgColor}`; 4656 if (this.#hcmHighlightKey === key) { 4657 return this.#hcmHighlightUrl; 4658 } 4659 this.#hcmHighlightKey = key; 4660 this.#hcmHighlightUrl = "none"; 4661 this.#hcmHighlightFilter?.remove(); 4662 if (!fgColor || !bgColor) { 4663 return this.#hcmHighlightUrl; 4664 } 4665 const [fgRGB, bgRGB] = [fgColor, bgColor].map(this.#getRGB.bind(this)); 4666 let fgGray = Math.round(0.2126 * fgRGB[0] + 0.7152 * fgRGB[1] + 0.0722 * fgRGB[2]); 4667 let bgGray = Math.round(0.2126 * bgRGB[0] + 0.7152 * bgRGB[1] + 0.0722 * bgRGB[2]); 4668 let [newFgRGB, newBgRGB] = [newFgColor, newBgColor].map(this.#getRGB.bind(this)); 4669 if (bgGray < fgGray) { 4670 [fgGray, bgGray, newFgRGB, newBgRGB] = [bgGray, fgGray, newBgRGB, newFgRGB]; 4671 } 4672 this.#defs.style.color = ""; 4673 const getSteps = (fg, bg, n) => { 4674 const arr = new Array(256); 4675 const step = (bgGray - fgGray) / n; 4676 const newStart = fg / 255; 4677 const newStep = (bg - fg) / (255 * n); 4678 let prev = 0; 4679 for (let i = 0; i <= n; i++) { 4680 const k = Math.round(fgGray + i * step); 4681 const value = newStart + i * newStep; 4682 for (let j = prev; j <= k; j++) { 4683 arr[j] = value; 4684 } 4685 prev = k + 1; 4686 } 4687 for (let i = prev; i < 256; i++) { 4688 arr[i] = arr[prev - 1]; 4689 } 4690 return arr.join(","); 4691 }; 4692 const id = `g_${this.#docId}_hcm_highlight_filter`; 4693 const filter = this.#hcmHighlightFilter = this.#createFilter(id); 4694 this.#addGrayConversion(filter); 4695 this.#addTransferMapConversion(getSteps(newFgRGB[0], newBgRGB[0], 5), getSteps(newFgRGB[1], newBgRGB[1], 5), getSteps(newFgRGB[2], newBgRGB[2], 5), filter); 4696 this.#hcmHighlightUrl = `url(#${id})`; 4697 return this.#hcmHighlightUrl; 4698 } 4699 destroy(keepHCM = false) { 4700 if (keepHCM && (this.#hcmUrl || this.#hcmHighlightUrl)) { 4701 return; 4702 } 4703 if (this.#_defs) { 4704 this.#_defs.parentNode.parentNode.remove(); 4705 this.#_defs = null; 4706 } 4707 if (this.#_cache) { 4708 this.#_cache.clear(); 4709 this.#_cache = null; 4710 } 4711 this.#id = 0; 4712 } 4713 #addGrayConversion(filter) { 4714 const feColorMatrix = this.#document.createElementNS(SVG_NS, "feColorMatrix"); 4715 feColorMatrix.setAttribute("type", "matrix"); 4716 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"); 4717 filter.append(feColorMatrix); 4718 } 4719 #createFilter(id) { 4720 const filter = this.#document.createElementNS(SVG_NS, "filter"); 4721 filter.setAttribute("color-interpolation-filters", "sRGB"); 4722 filter.setAttribute("id", id); 4723 this.#defs.append(filter); 4724 return filter; 4725 } 4726 #appendFeFunc(feComponentTransfer, func, table) { 4727 const feFunc = this.#document.createElementNS(SVG_NS, func); 4728 feFunc.setAttribute("type", "discrete"); 4729 feFunc.setAttribute("tableValues", table); 4730 feComponentTransfer.append(feFunc); 4731 } 4732 #addTransferMapConversion(rTable, gTable, bTable, filter) { 4733 const feComponentTransfer = this.#document.createElementNS(SVG_NS, "feComponentTransfer"); 4734 filter.append(feComponentTransfer); 4735 this.#appendFeFunc(feComponentTransfer, "feFuncR", rTable); 4736 this.#appendFeFunc(feComponentTransfer, "feFuncG", gTable); 4737 this.#appendFeFunc(feComponentTransfer, "feFuncB", bTable); 4738 } 4739 #getRGB(color) { 4740 this.#defs.style.color = color; 4741 return getRGB(getComputedStyle(this.#defs).getPropertyValue("color")); 4742 } 4743} 4744exports.DOMFilterFactory = DOMFilterFactory; 4745class DOMCanvasFactory extends _base_factory.BaseCanvasFactory { 4746 constructor({ 4747 ownerDocument = globalThis.document 4748 } = {}) { 4749 super(); 4750 this._document = ownerDocument; 4751 } 4752 _createCanvas(width, height) { 4753 const canvas = this._document.createElement("canvas"); 4754 canvas.width = width; 4755 canvas.height = height; 4756 return canvas; 4757 } 4758} 4759exports.DOMCanvasFactory = DOMCanvasFactory; 4760async function fetchData(url, asTypedArray = false) { 4761 if (isValidFetchUrl(url, document.baseURI)) { 4762 const response = await fetch(url); 4763 if (!response.ok) { 4764 throw new Error(response.statusText); 4765 } 4766 return asTypedArray ? new Uint8Array(await response.arrayBuffer()) : (0, _util.stringToBytes)(await response.text()); 4767 } 4768 return new Promise((resolve, reject) => { 4769 const request = new XMLHttpRequest(); 4770 request.open("GET", url, true); 4771 if (asTypedArray) { 4772 request.responseType = "arraybuffer"; 4773 } 4774 request.onreadystatechange = () => { 4775 if (request.readyState !== XMLHttpRequest.DONE) { 4776 return; 4777 } 4778 if (request.status === 200 || request.status === 0) { 4779 let data; 4780 if (asTypedArray && request.response) { 4781 data = new Uint8Array(request.response); 4782 } else if (!asTypedArray && request.responseText) { 4783 data = (0, _util.stringToBytes)(request.responseText); 4784 } 4785 if (data) { 4786 resolve(data); 4787 return; 4788 } 4789 } 4790 reject(new Error(request.statusText)); 4791 }; 4792 request.send(null); 4793 }); 4794} 4795class DOMCMapReaderFactory extends _base_factory.BaseCMapReaderFactory { 4796 _fetchData(url, compressionType) { 4797 return fetchData(url, this.isCompressed).then(data => { 4798 return { 4799 cMapData: data, 4800 compressionType 4801 }; 4802 }); 4803 } 4804} 4805exports.DOMCMapReaderFactory = DOMCMapReaderFactory; 4806class DOMStandardFontDataFactory extends _base_factory.BaseStandardFontDataFactory { 4807 _fetchData(url) { 4808 return fetchData(url, true); 4809 } 4810} 4811exports.DOMStandardFontDataFactory = DOMStandardFontDataFactory; 4812class DOMSVGFactory extends _base_factory.BaseSVGFactory { 4813 _createSVG(type) { 4814 return document.createElementNS(SVG_NS, type); 4815 } 4816} 4817exports.DOMSVGFactory = DOMSVGFactory; 4818class PageViewport { 4819 constructor({
4820 viewBox, 4821 scale, 4822 rotation, 4823 offsetX = 0, 4824 offsetY = 0, 4825 dontFlip = false 4826 }) { 4827 this.viewBox = viewBox; 4828 this.scale = scale; 4829 this.rotation = rotation; 4830 this.offsetX = offsetX; 4831 this.offsetY = offsetY; 4832 const centerX = (viewBox[2] + viewBox[0]) / 2; 4833 const centerY = (viewBox[3] + viewBox[1]) / 2; 4834 let rotateA, rotateB, rotateC, rotateD; 4835 rotation %= 360; 4836 if (rotation < 0) { 4837 rotation += 360; 4838 } 4839 switch (rotation) { 4840 case 180: 4841 rotateA = -1; 4842 rotateB = 0; 4843 rotateC = 0; 4844 rotateD = 1; 4845 break; 4846 case 90: 4847 rotateA = 0; 4848 rotateB = 1; 4849 rotateC = 1; 4850 rotateD = 0; 4851 break; 4852 case 270: 4853 rotateA = 0; 4854 rotateB = -1; 4855 rotateC = -1; 4856 rotateD = 0; 4857 break; 4858 case 0: 4859 rotateA = 1; 4860 rotateB = 0; 4861 rotateC = 0; 4862 rotateD = -1; 4863 break; 4864 default: 4865 throw new Error("PageViewport: Invalid rotation, must be a multiple of 90 degrees."); 4866 } 4867 if (dontFlip) { 4868 rotateC = -rotateC; 4869 rotateD = -rotateD; 4870 } 4871 let offsetCanvasX, offsetCanvasY; 4872 let width, height; 4873 if (rotateA === 0) { 4874 offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX; 4875 offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY; 4876 width = (viewBox[3] - viewBox[1]) * scale; 4877 height = (viewBox[2] - viewBox[0]) * scale; 4878 } else { 4879 offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX; 4880 offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY; 4881 width = (viewBox[2] - viewBox[0]) * scale; 4882 height = (viewBox[3] - viewBox[1]) * scale; 4883 } 4884 this.transform = [rotateA * scale, rotateB * scale, rotateC * scale, rotateD * scale, offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY]; 4885 this.width = width; 4886 this.height = height; 4887 } 4888 get rawDims() { 4889 const { 4890 viewBox 4891 } = this; 4892 return (0, _util.shadow)(this, "rawDims", { 4893 pageWidth: viewBox[2] - viewBox[0], 4894 pageHeight: viewBox[3] - viewBox[1], 4895 pageX: viewBox[0], 4896 pageY: viewBox[1] 4897 }); 4898 } 4899 clone({ 4900 scale = this.scale, 4901 rotation = this.rotation, 4902 offsetX = this.offsetX, 4903 offsetY = this.offsetY, 4904 dontFlip = false 4905 } = {}) { 4906 return new PageViewport({ 4907 viewBox: this.viewBox.slice(), 4908 scale, 4909 rotation, 4910 offsetX, 4911 offsetY, 4912 dontFlip 4913 }); 4914 } 4915 convertToViewportPoint(x, y) { 4916 return _util.Util.applyTransform([x, y], this.transform); 4917 } 4918 convertToViewportRectangle(rect) { 4919 const topLeft = _util.Util.applyTransform([rect[0], rect[1]], this.transform); 4920 const bottomRight = _util.Util.applyTransform([rect[2], rect[3]], this.transform); 4921 return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]]; 4922 } 4923 convertToPdfPoint(x, y) { 4924 return _util.Util.applyInverseTransform([x, y], this.transform); 4925 } 4926} 4927exports.PageViewport = PageViewport; 4928class RenderingCancelledException extends _util.BaseException { 4929 constructor(msg, extraDelay = 0) { 4930 super(msg, "RenderingCancelledException"); 4931 this.extraDelay = extraDelay; 4932 } 4933} 4934exports.RenderingCancelledException = RenderingCancelledException; 4935function isDataScheme(url) { 4936 const ii = url.length; 4937 let i = 0; 4938 while (i < ii && url[i].trim() === "") { 4939 i++; 4940 } 4941 return url.substring(i, i + 5).toLowerCase() === "data:"; 4942} 4943function isPdfFile(filename) { 4944 return typeof filename === "string" && /\.pdf$/i.test(filename); 4945} 4946function getFilenameFromUrl(url, onlyStripPath = false) { 4947 if (!onlyStripPath) { 4948 [url] = url.split(/[#?]/, 1); 4949 } 4950 return url.substring(url.lastIndexOf("/") + 1); 4951} 4952function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") { 4953 if (typeof url !== "string") { 4954 return defaultFilename; 4955 } 4956 if (isDataScheme(url)) { 4957 (0, _util.warn)('getPdfFilenameFromUrl: ignore "data:"-URL for performance reasons.'); 4958 return defaultFilename; 4959 } 4960 const reURI = /^(?:(?:[^:]+:)?\/\/[^/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/; 4961 const reFilename = /[^/?#=]+\.pdf\b(?!.*\.pdf\b)/i; 4962 const splitURI = reURI.exec(url); 4963 let suggestedFilename = reFilename.exec(splitURI[1]) || reFilename.exec(splitURI[2]) || reFilename.exec(splitURI[3]); 4964 if (suggestedFilename) { 4965 suggestedFilename = suggestedFilename[0]; 4966 if (suggestedFilename.includes("%")) {
4967 try { 4968 suggestedFilename = reFilename.exec(decodeURIComponent(suggestedFilename))[0]; 4969 } catch {} 4970 } 4971 } 4972 return suggestedFilename || defaultFilename; 4973} 4974class StatTimer { 4975 started = Object.create(null); 4976 times = []; 4977 time(name) { 4978 if (name in this.started) { 4979 (0, _util.warn)(`Timer is already running for ${name}`); 4980 } 4981 this.started[name] = Date.now(); 4982 } 4983 timeEnd(name) { 4984 if (!(name in this.started)) { 4985 (0, _util.warn)(`Timer has not been started for ${name}`); 4986 } 4987 this.times.push({ 4988 name, 4989 start: this.started[name], 4990 end: Date.now() 4991 }); 4992 delete this.started[name]; 4993 } 4994 toString() { 4995 const outBuf = []; 4996 let longest = 0; 4997 for (const { 4998 name 4999 } of this.times) { 5000 longest = Math.max(name.length, longest); 5001 } 5002 for (const { 5003 name, 5004 start, 5005 end 5006 } of this.times) { 5007 outBuf.push(`${name.padEnd(longest)} ${end - start}ms\n`); 5008 } 5009 return outBuf.join(""); 5010 } 5011} 5012exports.StatTimer = StatTimer; 5013function isValidFetchUrl(url, baseUrl) { 5014 try { 5015 const { 5016 protocol 5017 } = baseUrl ? new URL(url, baseUrl) : new URL(url); 5018 return protocol === "http:" || protocol === "https:"; 5019 } catch { 5020 return false; 5021 } 5022} 5023function loadScript(src, removeScriptElement = false) { 5024 return new Promise((resolve, reject) => { 5025 const script = document.createElement("script"); 5026 script.src = src; 5027 script.onload = function (evt) { 5028 if (removeScriptElement) { 5029 script.remove(); 5030 } 5031 resolve(evt); 5032 }; 5033 script.onerror = function () { 5034 reject(new Error(`Cannot load script at: ${script.src}`)); 5035 }; 5036 (document.head || document.documentElement).append(script); 5037 }); 5038} 5039function deprecated(details) { 5040 console.log("Deprecated API usage: " + details); 5041} 5042let pdfDateStringRegex; 5043class PDFDateString { 5044 static toDateObject(input) { 5045 if (!input || typeof input !== "string") { 5046 return null; 5047 } 5048 pdfDateStringRegex ||= new RegExp("^D:" + "(\\d{4})" + "(\\d{2})?" + "(\\d{2})?" + "(\\d{2})?" + "(\\d{2})?" + "(\\d{2})?" + "([Z|+|-])?" + "(\\d{2})?" + "'?" + "(\\d{2})?" + "'?"); 5049 const matches = pdfDateStringRegex.exec(input); 5050 if (!matches) { 5051 return null; 5052 } 5053 const year = parseInt(matches[1], 10); 5054 let month = parseInt(matches[2], 10);
5055 month = month >= 1 && month <= 12 ? month - 1 : 0; 5056 let day = parseInt(matches[3], 10); 5057 day = day >= 1 && day <= 31 ? day : 1; 5058 let hour = parseInt(matches[4], 10); 5059 hour = hour >= 0 && hour <= 23 ? hour : 0; 5060 let minute = parseInt(matches[5], 10); 5061 minute = minute >= 0 && minute <= 59 ? minute : 0; 5062 let second = parseInt(matches[6], 10); 5063 second = second >= 0 && second <= 59 ? second : 0; 5064 const universalTimeRelation = matches[7] || "Z"; 5065 let offsetHour = parseInt(matches[8], 10); 5066 offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0; 5067 let offsetMinute = parseInt(matches[9], 10) || 0; 5068 offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0; 5069 if (universalTimeRelation === "-") { 5070 hour += offsetHour; 5071 minute += offsetMinute; 5072 } else if (universalTimeRelation === "+") { 5073 hour -= offsetHour; 5074 minute -= offsetMinute; 5075 } 5076 return new Date(Date.UTC(year, month, day, hour, minute, second)); 5077 } 5078} 5079exports.PDFDateString = PDFDateString; 5080function getXfaPageViewport(xfaPage, { 5081 scale = 1, 5082 rotation = 0 5083}) { 5084 const { 5085 width, 5086 height 5087 } = xfaPage.attributes.style; 5088 const viewBox = [0, 0, parseInt(width), parseInt(height)]; 5089 return new PageViewport({ 5090 viewBox, 5091 scale, 5092 rotation 5093 }); 5094} 5095function getRGB(color) { 5096 if (color.startsWith("#")) { 5097 const colorRGB = parseInt(color.slice(1), 16); 5098 return [(colorRGB & 0xff0000) >> 16, (colorRGB & 0x00ff00) >> 8, colorRGB & 0x0000ff]; 5099 } 5100 if (color.startsWith("rgb(")) { 5101 return color.slice(4, -1).split(",").map(x => parseInt(x)); 5102 } 5103 if (color.startsWith("rgba(")) { 5104 return color.slice(5, -1).split(",").map(x => parseInt(x)).slice(0, 3); 5105 } 5106 (0, _util.warn)(`Not a valid color format: "${color}"`); 5107 return [0, 0, 0]; 5108} 5109function getColorValues(colors) { 5110 const span = document.createElement("span"); 5111 span.style.visibility = "hidden"; 5112 document.body.append(span); 5113 for (const name of colors.keys()) { 5114 span.style.color = name; 5115 const computedColor = window.getComputedStyle(span).color; 5116 colors.set(name, getRGB(computedColor)); 5117 } 5118 span.remove(); 5119} 5120function getCurrentTransform(ctx) { 5121 const { 5122 a, 5123 b, 5124 c, 5125 d, 5126 e, 5127 f 5128 } = ctx.getTransform(); 5129 return [a, b, c, d, e, f]; 5130} 5131function getCurrentTransformInverse(ctx) { 5132 const { 5133 a, 5134 b, 5135 c, 5136 d, 5137 e, 5138 f 5139 } = ctx.getTransform().invertSelf(); 5140 return [a, b, c, d, e, f]; 5141} 5142function setLayerDimensions(div, viewport, mustFlip = false, mustRotate = true) { 5143 if (viewport instanceof PageViewport) { 5144 const { 5145 pageWidth, 5146 pageHeight 5147 } = viewport.rawDims; 5148 const { 5149 style 5150 } = div; 5151 const widthStr = `calc(var(--scale-factor) * ${pageWidth}px)`; 5152 const heightStr = `calc(var(--scale-factor) * ${pageHeight}px)`; 5153 if (!mustFlip || viewport.rotation % 180 === 0) { 5154 style.width = widthStr; 5155 style.height = heightStr; 5156 } else { 5157 style.width = heightStr; 5158 style.height = widthStr; 5159 } 5160 } 5161 if (mustRotate) { 5162 div.setAttribute("data-main-rotation", viewport.rotation); 5163 } 5164} 5165 5166/***/ }), 5167/* 7 */ 5168/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 5169 5170 5171 5172Object.defineProperty(exports, "__esModule", ({ 5173 value: true 5174})); 5175exports.BaseStandardFontDataFactory = exports.BaseSVGFactory = exports.BaseFilterFactory = exports.BaseCanvasFactory = exports.BaseCMapReaderFactory = void 0; 5176var _util = __w_pdfjs_require__(1); 5177class BaseFilterFactory { 5178 constructor() { 5179 if (this.constructor === BaseFilterFactory) { 5180 (0, _util.unreachable)("Cannot initialize BaseFilterFactory."); 5181 } 5182 } 5183 addFilter(maps) { 5184 return "none"; 5185 } 5186 addHCMFilter(fgColor, bgColor) { 5187 return "none"; 5188 } 5189 addHighlightHCMFilter(fgColor, bgColor, newFgColor, newBgColor) { 5190 return "none"; 5191 } 5192 destroy(keepHCM = false) {} 5193} 5194exports.BaseFilterFactory = BaseFilterFactory; 5195class BaseCanvasFactory { 5196 constructor() { 5197 if (this.constructor === BaseCanvasFactory) { 5198 (0, _util.unreachable)("Cannot initialize BaseCanvasFactory."); 5199 } 5200 } 5201 create(width, height) { 5202 if (width <= 0 || height <= 0) { 5203 throw new Error("Invalid canvas size"); 5204 } 5205 const canvas = this._createCanvas(width, height); 5206 return { 5207 canvas, 5208 context: canvas.getContext("2d") 5209 }; 5210 } 5211 reset(canvasAndContext, width, height) { 5212 if (!canvasAndContext.canvas) { 5213 throw new Error("Canvas is not specified"); 5214 } 5215 if (width <= 0 || height <= 0) { 5216 throw new Error("Invalid canvas size"); 5217 } 5218 canvasAndContext.canvas.width = width; 5219 canvasAndContext.canvas.height = height; 5220 } 5221 destroy(canvasAndContext) { 5222 if (!canvasAndContext.canvas) { 5223 throw new Error("Canvas is not specified"); 5224 } 5225 canvasAndContext.canvas.width = 0; 5226 canvasAndContext.canvas.height = 0; 5227 canvasAndContext.canvas = null; 5228 canvasAndContext.context = null; 5229 } 5230 _createCanvas(width, height) { 5231 (0, _util.unreachable)("Abstract method `_createCanvas` called."); 5232 } 5233} 5234exports.BaseCanvasFactory = BaseCanvasFactory; 5235class BaseCMapReaderFactory { 5236 constructor({ 5237 baseUrl = null, 5238 isCompressed = true 5239 }) { 5240 if (this.constructor === BaseCMapReaderFactory) { 5241 (0, _util.unreachable)("Cannot initialize BaseCMapReaderFactory."); 5242 } 5243 this.baseUrl = baseUrl; 5244 this.isCompressed = isCompressed; 5245 } 5246 async fetch({ 5247 name 5248 }) { 5249 if (!this.baseUrl) { 5250 throw new Error('The CMap "baseUrl" parameter must be specified, ensure that ' + 'the "cMapUrl" and "cMapPacked" API parameters are provided.'); 5251 } 5252 if (!name) { 5253 throw new Error("CMap name must be specified."); 5254 } 5255 const url = this.baseUrl + name + (this.isCompressed ? ".bcmap" : ""); 5256 const compressionType = this.isCompressed ? _util.CMapCompressionType.BINARY : _util.CMapCompressionType.NONE; 5257 return this._fetchData(url, compressionType).catch(reason => { 5258 throw new Error(`Unable to load ${this.isCompressed ? "binary " : ""}CMap at: ${url}`); 5259 }); 5260 } 5261 _fetchData(url, compressionType) { 5262 (0, _util.unreachable)("Abstract method `_fetchData` called."); 5263 } 5264} 5265exports.BaseCMapReaderFactory = BaseCMapReaderFactory; 5266class BaseStandardFontDataFactory { 5267 constructor({ 5268 baseUrl = null 5269 }) { 5270 if (this.constructor === BaseStandardFontDataFactory) { 5271 (0, _util.unreachable)("Cannot initialize BaseStandardFontDataFactory."); 5272 } 5273 this.baseUrl = baseUrl; 5274 } 5275 async fetch({ 5276 filename 5277 }) { 5278 if (!this.baseUrl) { 5279 throw new Error('The standard font "baseUrl" parameter must be specified, ensure that ' + 'the "standardFontDataUrl" API parameter is provided.'); 5280 } 5281 if (!filename) { 5282 throw new Error("Font filename must be specified."); 5283 } 5284 const url = `${this.baseUrl}${filename}`; 5285 return this._fetchData(url).catch(reason => { 5286 throw new Error(`Unable to load font data at: ${url}`); 5287 }); 5288 } 5289 _fetchData(url) { 5290 (0, _util.unreachable)("Abstract method `_fetchData` called."); 5291 } 5292} 5293exports.BaseStandardFontDataFactory = BaseStandardFontDataFactory; 5294class BaseSVGFactory { 5295 constructor() { 5296 if (this.constructor === BaseSVGFactory) { 5297 (0, _util.unreachable)("Cannot initialize BaseSVGFactory."); 5298 } 5299 } 5300 create(width, height, skipDimensions = false) { 5301 if (width <= 0 || height <= 0) { 5302 throw new Error("Invalid SVG dimensions"); 5303 } 5304 const svg = this._createSVG("svg:svg"); 5305 svg.setAttribute("version", "1.1"); 5306 if (!skipDimensions) { 5307 svg.setAttribute("width", `${width}px`); 5308 svg.setAttribute("height", `${height}px`); 5309 } 5310 svg.setAttribute("preserveAspectRatio", "none"); 5311 svg.setAttribute("viewBox", `0 0 ${width} ${height}`); 5312 return svg; 5313 } 5314 createElement(type) { 5315 if (typeof type !== "string") { 5316 throw new Error("Invalid SVG element type"); 5317 } 5318 return this._createSVG(type); 5319 } 5320 _createSVG(type) { 5321 (0, _util.unreachable)("Abstract method `_createSVG` called."); 5322 } 5323} 5324exports.BaseSVGFactory = BaseSVGFactory; 5325 5326/***/ }), 5327/* 8 */ 5328/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 5329 5330 5331 5332Object.defineProperty(exports, "__esModule", ({ 5333 value: true 5334})); 5335exports.MurmurHash3_64 = void 0; 5336var _util = __w_pdfjs_require__(1); 5337const SEED = 0xc3d2e1f0; 5338const MASK_HIGH = 0xffff0000; 5339const MASK_LOW = 0xffff; 5340class MurmurHash3_64 { 5341 constructor(seed) { 5342 this.h1 = seed ? seed & 0xffffffff : SEED; 5343 this.h2 = seed ? seed & 0xffffffff : SEED; 5344 } 5345 update(input) { 5346 let data, length; 5347 if (typeof input === "string") { 5348 data = new Uint8Array(input.length * 2); 5349 length = 0; 5350 for (let i = 0, ii = input.length; i < ii; i++) { 5351 const code = input.charCodeAt(i); 5352 if (code <= 0xff) { 5353 data[length++] = code; 5354 } else { 5355 data[length++] = code >>> 8; 5356 data[length++] = code & 0xff; 5357 } 5358 } 5359 } else if ((0, _util.isArrayBuffer)(input)) { 5360 data = input.slice(); 5361 length = data.byteLength; 5362 } else { 5363 throw new Error("Wrong data format in MurmurHash3_64_update. " + "Input must be a string or array."); 5364 } 5365 const blockCounts = length >> 2; 5366 const tailLength = length - blockCounts * 4; 5367 const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts); 5368 let k1 = 0, 5369 k2 = 0; 5370 let h1 = this.h1, 5371 h2 = this.h2; 5372 const C1 = 0xcc9e2d51, 5373 C2 = 0x1b873593; 5374 const C1_LOW = C1 & MASK_LOW, 5375 C2_LOW = C2 & MASK_LOW; 5376 for (let i = 0; i < blockCounts; i++) { 5377 if (i & 1) {
5378 k1 = dataUint32[i]; 5379 k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; 5380 k1 = k1 << 15 | k1 >>> 17; 5381 k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; 5382 h1 ^= k1; 5383 h1 = h1 << 13 | h1 >>> 19; 5384 h1 = h1 * 5 + 0xe6546b64; 5385 } else { 5386 k2 = dataUint32[i]; 5387 k2 = k2 * C1 & MASK_HIGH | k2 * C1_LOW & MASK_LOW; 5388 k2 = k2 << 15 | k2 >>> 17; 5389 k2 = k2 * C2 & MASK_HIGH | k2 * C2_LOW & MASK_LOW; 5390 h2 ^= k2; 5391 h2 = h2 << 13 | h2 >>> 19; 5392 h2 = h2 * 5 + 0xe6546b64; 5393 } 5394 } 5395 k1 = 0; 5396 switch (tailLength) { 5397 case 3: 5398 k1 ^= data[blockCounts * 4 + 2] << 16; 5399 case 2: 5400 k1 ^= data[blockCounts * 4 + 1] << 8; 5401 case 1: 5402 k1 ^= data[blockCounts * 4]; 5403 k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; 5404 k1 = k1 << 15 | k1 >>> 17; 5405 k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; 5406 if (blockCounts & 1) { 5407 h1 ^= k1; 5408 } else { 5409 h2 ^= k1; 5410 } 5411 } 5412 this.h1 = h1; 5413 this.h2 = h2; 5414 } 5415 hexdigest() { 5416 let h1 = this.h1, 5417 h2 = this.h2; 5418 h1 ^= h2 >>> 1; 5419 h1 = h1 * 0xed558ccd & MASK_HIGH | h1 * 0x8ccd & MASK_LOW; 5420 h2 = h2 * 0xff51afd7 & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16; 5421 h1 ^= h2 >>> 1; 5422 h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW; 5423 h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16; 5424 h1 ^= h2 >>> 1; 5425 return (h1 >>> 0).toString(16).padStart(8, "0") + (h2 >>> 0).toString(16).padStart(8, "0"); 5426 } 5427} 5428exports.MurmurHash3_64 = MurmurHash3_64; 5429 5430/***/ }), 5431/* 9 */ 5432/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 5433 5434 5435 5436Object.defineProperty(exports, "__esModule", ({ 5437 value: true 5438})); 5439exports.FontLoader = exports.FontFaceObject = void 0; 5440var _util = __w_pdfjs_require__(1); 5441class FontLoader { 5442 #systemFonts = new Set(); 5443 constructor({ 5444 ownerDocument = globalThis.document, 5445 styleElement = null 5446 }) { 5447 this._document = ownerDocument; 5448 this.nativeFontFaces = new Set(); 5449 this.styleElement = null; 5450 this.loadingRequests = []; 5451 this.loadTestFontId = 0; 5452 } 5453 addNativeFontFace(nativeFontFace) { 5454 this.nativeFontFaces.add(nativeFontFace); 5455 this._document.fonts.add(nativeFontFace); 5456 } 5457 removeNativeFontFace(nativeFontFace) { 5458 this.nativeFontFaces.delete(nativeFontFace); 5459 this._document.fonts.delete(nativeFontFace); 5460 } 5461 insertRule(rule) { 5462 if (!this.styleElement) { 5463 this.styleElement = this._document.createElement("style"); 5464 this._document.documentElement.getElementsByTagName("head")[0].append(this.styleElement); 5465 } 5466 const styleSheet = this.styleElement.sheet; 5467 styleSheet.insertRule(rule, styleSheet.cssRules.length); 5468 } 5469 clear() { 5470 for (const nativeFontFace of this.nativeFontFaces) { 5471 this._document.fonts.delete(nativeFontFace); 5472 } 5473 this.nativeFontFaces.clear(); 5474 this.#systemFonts.clear(); 5475 if (this.styleElement) { 5476 this.styleElement.remove(); 5477 this.styleElement = null; 5478 } 5479 } 5480 async loadSystemFont(info) { 5481 if (!info || this.#systemFonts.has(info.loadedName)) { 5482 return; 5483 } 5484 (0, _util.assert)(!this.disableFontFace, "loadSystemFont shouldn't be called when `disableFontFace` is set."); 5485 if (this.isFontLoadingAPISupported) { 5486 const { 5487 loadedName, 5488 src, 5489 style 5490 } = info; 5491 const fontFace = new FontFace(loadedName, src, style); 5492 this.addNativeFontFace(fontFace); 5493 try { 5494 await fontFace.load(); 5495 this.#systemFonts.add(loadedName); 5496 } catch { 5497 (0, _util.warn)(`Cannot load system font: ${info.baseFontName}, installing it could help to improve PDF rendering.`); 5498 this.removeNativeFontFace(fontFace); 5499 } 5500 return; 5501 } 5502 (0, _util.unreachable)("Not implemented: loadSystemFont without the Font Loading API."); 5503 } 5504 async bind(font) { 5505 if (font.attached || font.missingFile && !font.systemFontInfo) { 5506 return; 5507 } 5508 font.attached = true; 5509 if (font.systemFontInfo) { 5510 await this.loadSystemFont(font.systemFontInfo); 5511 return; 5512 } 5513 if (this.isFontLoadingAPISupported) { 5514 const nativeFontFace = font.createNativeFontFace(); 5515 if (nativeFontFace) { 5516 this.addNativeFontFace(nativeFontFace); 5517 try { 5518 await nativeFontFace.loaded; 5519 } catch (ex) { 5520 (0, _util.warn)(`Failed to load font '${nativeFontFace.family}': '${ex}'.`); 5521 font.disableFontFace = true; 5522 throw ex; 5523 } 5524 } 5525 return; 5526 } 5527 const rule = font.createFontFaceRule(); 5528 if (rule) { 5529 this.insertRule(rule); 5530 if (this.isSyncFontLoadingSupported) { 5531 return; 5532 } 5533 await new Promise(resolve => { 5534 const request = this._queueLoadingCallback(resolve); 5535 this._prepareFontLoadEvent(font, request); 5536 }); 5537 } 5538 } 5539 get isFontLoadingAPISupported() { 5540 const hasFonts = !!this._document?.fonts; 5541 return (0, _util.shadow)(this, "isFontLoadingAPISupported", hasFonts); 5542 } 5543 get isSyncFontLoadingSupported() { 5544 let supported = false;
5545 if (_util.isNodeJS) { 5546 supported = true; 5547 } else if (typeof navigator !== "undefined" && /Mozilla\/5.0.*?rv:\d+.*? Gecko/.test(navigator.userAgent)) { 5548 supported = true; 5549 } 5550 return (0, _util.shadow)(this, "isSyncFontLoadingSupported", supported); 5551 } 5552 _queueLoadingCallback(callback) { 5553 function completeRequest() { 5554 (0, _util.assert)(!request.done, "completeRequest() cannot be called twice."); 5555 request.done = true; 5556 while (loadingRequests.length > 0 && loadingRequests[0].done) { 5557 const otherRequest = loadingRequests.shift(); 5558 setTimeout(otherRequest.callback, 0); 5559 } 5560 } 5561 const { 5562 loadingRequests 5563 } = this; 5564 const request = { 5565 done: false, 5566 complete: completeRequest, 5567 callback 5568 }; 5569 loadingRequests.push(request); 5570 return request; 5571 } 5572 get _loadTestFont() { 5573 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=="); 5574 return (0, _util.shadow)(this, "_loadTestFont", testFont); 5575 } 5576 _prepareFontLoadEvent(font, request) { 5577 function int32(data, offset) { 5578 return data.charCodeAt(offset) << 24 | data.charCodeAt(offset + 1) << 16 | data.charCodeAt(offset + 2) << 8 | data.charCodeAt(offset + 3) & 0xff; 5579 } 5580 function spliceString(s, offset, remove, insert) { 5581 const chunk1 = s.substring(0, offset); 5582 const chunk2 = s.substring(offset + remove); 5583 return chunk1 + insert + chunk2; 5584 } 5585 let i, ii; 5586 const canvas = this._document.createElement("canvas"); 5587 canvas.width = 1; 5588 canvas.height = 1; 5589 const ctx = canvas.getContext("2d"); 5590 let called = 0; 5591 function isFontReady(name, callback) { 5592 if (++called > 30) { 5593 (0, _util.warn)("Load test font never loaded."); 5594 callback(); 5595 return; 5596 } 5597 ctx.font = "30px " + name; 5598 ctx.fillText(".", 0, 20); 5599 const imageData = ctx.getImageData(0, 0, 1, 1); 5600 if (imageData.data[3] > 0) { 5601 callback(); 5602 return; 5603 } 5604 setTimeout(isFontReady.bind(null, name, callback)); 5605 } 5606 const loadTestFontId = `lt${Date.now()}${this.loadTestFontId++}`; 5607 let data = this._loadTestFont; 5608 const COMMENT_OFFSET = 976; 5609 data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length, loadTestFontId); 5610 const CFF_CHECKSUM_OFFSET = 16; 5611 const XXXX_VALUE = 0x58585858; 5612 let checksum = int32(data, CFF_CHECKSUM_OFFSET); 5613 for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) { 5614 checksum = checksum - XXXX_VALUE + int32(loadTestFontId, i) | 0; 5615 } 5616 if (i < loadTestFontId.length) { 5617 checksum = checksum - XXXX_VALUE + int32(loadTestFontId + "XXX", i) | 0; 5618 }
5619 data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, (0, _util.string32)(checksum)); 5620 const url = `url(data:font/opentype;base64,${btoa(data)});`; 5621 const rule = `@font-face {font-family:"${loadTestFontId}";src:${url}}`; 5622 this.insertRule(rule); 5623 const div = this._document.createElement("div"); 5624 div.style.visibility = "hidden"; 5625 div.style.width = div.style.height = "10px"; 5626 div.style.position = "absolute"; 5627 div.style.top = div.style.left = "0px"; 5628 for (const name of [font.loadedName, loadTestFontId]) { 5629 const span = this._document.createElement("span"); 5630 span.textContent = "Hi"; 5631 span.style.fontFamily = name; 5632 div.append(span); 5633 } 5634 this._document.body.append(div); 5635 isFontReady(loadTestFontId, () => { 5636 div.remove(); 5637 request.complete(); 5638 }); 5639 } 5640} 5641exports.FontLoader = FontLoader; 5642class FontFaceObject { 5643 constructor(translatedData, { 5644 isEvalSupported = true, 5645 disableFontFace = false, 5646 ignoreErrors = false, 5647 inspectFont = null 5648 }) { 5649 this.compiledGlyphs = Object.create(null); 5650 for (const i in translatedData) { 5651 this[i] = translatedData[i]; 5652 } 5653 this.isEvalSupported = isEvalSupported !== false; 5654 this.disableFontFace = disableFontFace === true; 5655 this.ignoreErrors = ignoreErrors === true; 5656 this._inspectFont = inspectFont; 5657 } 5658 createNativeFontFace() { 5659 if (!this.data || this.disableFontFace) { 5660 return null; 5661 } 5662 let nativeFontFace; 5663 if (!this.cssFontInfo) { 5664 nativeFontFace = new FontFace(this.loadedName, this.data, {}); 5665 } else { 5666 const css = { 5667 weight: this.cssFontInfo.fontWeight 5668 }; 5669 if (this.cssFontInfo.italicAngle) { 5670 css.style = `oblique ${this.cssFontInfo.italicAngle}deg`; 5671 } 5672 nativeFontFace = new FontFace(this.cssFontInfo.fontFamily, this.data, css); 5673 } 5674 this._inspectFont?.(this); 5675 return nativeFontFace; 5676 } 5677 createFontFaceRule() { 5678 if (!this.data || this.disableFontFace) { 5679 return null; 5680 } 5681 const data = (0, _util.bytesToString)(this.data); 5682 const url = `url(data:${this.mimetype};base64,${btoa(data)});`; 5683 let rule; 5684 if (!this.cssFontInfo) { 5685 rule = `@font-face {font-family:"${this.loadedName}";src:${url}}`; 5686 } else { 5687 let css = `font-weight: ${this.cssFontInfo.fontWeight};`; 5688 if (this.cssFontInfo.italicAngle) { 5689 css += `font-style: oblique ${this.cssFontInfo.italicAngle}deg;`; 5690 } 5691 rule = `@font-face {font-family:"${this.cssFontInfo.fontFamily}";${css}src:${url}}`; 5692 } 5693 this._inspectFont?.(this, url); 5694 return rule; 5695 } 5696 getPathGenerator(objs, character) { 5697 if (this.compiledGlyphs[character] !== undefined) { 5698 return this.compiledGlyphs[character]; 5699 } 5700 let cmds; 5701 try { 5702 cmds = objs.get(this.loadedName + "_path_" + character); 5703 } catch (ex) { 5704 if (!this.ignoreErrors) { 5705 throw ex; 5706 } 5707 (0, _util.warn)(`getPathGenerator - ignoring character: "${ex}".`); 5708 return this.compiledGlyphs[character] = function (c, size) {}; 5709 } 5710 if (this.isEvalSupported && _util.FeatureTest.isEvalSupported) { 5711 const jsBuf = []; 5712 for (const current of cmds) { 5713 const args = current.args !== undefined ? current.args.join(",") : ""; 5714 jsBuf.push("c.", current.cmd, "(", args, ");\n"); 5715 } 5716 return this.compiledGlyphs[character] = new Function("c", "size", jsBuf.join("")); 5717 } 5718 return this.compiledGlyphs[character] = function (c, size) { 5719 for (const current of cmds) { 5720 if (current.cmd === "scale") { 5721 current.args = [size, -size]; 5722 } 5723 c[current.cmd].apply(c, current.args); 5724 } 5725 }; 5726 } 5727} 5728exports.FontFaceObject = FontFaceObject; 5729 5730/***/ }), 5731/* 10 */ 5732/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 5733 5734 5735 5736Object.defineProperty(exports, "__esModule", ({ 5737 value: true 5738})); 5739exports.NodeStandardFontDataFactory = exports.NodeFilterFactory = exports.NodeCanvasFactory = exports.NodeCMapReaderFactory = void 0; 5740var _base_factory = __w_pdfjs_require__(7); 5741var _util = __w_pdfjs_require__(1); 5742; 5743; 5744const fetchData = function (url) { 5745 return new Promise((resolve, reject) => { 5746 const fs = require("fs"); 5747 fs.readFile(url, (error, data) => { 5748 if (error || !data) { 5749 reject(new Error(error)); 5750 return; 5751 } 5752 resolve(new Uint8Array(data)); 5753 }); 5754 }); 5755}; 5756class NodeFilterFactory extends _base_factory.BaseFilterFactory {}
5757exports.NodeFilterFactory = NodeFilterFactory; 5758class NodeCanvasFactory extends _base_factory.BaseCanvasFactory { 5759 _createCanvas(width, height) { 5760 const Canvas = require("canvas"); 5761 return Canvas.createCanvas(width, height); 5762 } 5763} 5764exports.NodeCanvasFactory = NodeCanvasFactory; 5765class NodeCMapReaderFactory extends _base_factory.BaseCMapReaderFactory { 5766 _fetchData(url, compressionType) { 5767 return fetchData(url).then(data => { 5768 return { 5769 cMapData: data, 5770 compressionType 5771 }; 5772 }); 5773 } 5774} 5775exports.NodeCMapReaderFactory = NodeCMapReaderFactory; 5776class NodeStandardFontDataFactory extends _base_factory.BaseStandardFontDataFactory { 5777 _fetchData(url) { 5778 return fetchData(url); 5779 } 5780} 5781exports.NodeStandardFontDataFactory = NodeStandardFontDataFactory; 5782 5783/***/ }), 5784/* 11 */ 5785/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 5786 5787 5788 5789Object.defineProperty(exports, "__esModule", ({ 5790 value: true 5791})); 5792exports.CanvasGraphics = void 0; 5793var _util = __w_pdfjs_require__(1); 5794var _display_utils = __w_pdfjs_require__(6); 5795var _pattern_helper = __w_pdfjs_require__(12); 5796var _image_utils = __w_pdfjs_require__(13); 5797const MIN_FONT_SIZE = 16; 5798const MAX_FONT_SIZE = 100; 5799const MAX_GROUP_SIZE = 4096; 5800const EXECUTION_TIME = 15; 5801const EXECUTION_STEPS = 10; 5802const MAX_SIZE_TO_COMPILE = 1000; 5803const FULL_CHUNK_HEIGHT = 16; 5804function mirrorContextOperations(ctx, destCtx) { 5805 if (ctx._removeMirroring) { 5806 throw new Error("Context is already forwarding operations."); 5807 } 5808 ctx.__originalSave = ctx.save; 5809 ctx.__originalRestore = ctx.restore; 5810 ctx.__originalRotate = ctx.rotate; 5811 ctx.__originalScale = ctx.scale; 5812 ctx.__originalTranslate = ctx.translate; 5813 ctx.__originalTransform = ctx.transform; 5814 ctx.__originalSetTransform = ctx.setTransform; 5815 ctx.__originalResetTransform = ctx.resetTransform; 5816 ctx.__originalClip = ctx.clip; 5817 ctx.__originalMoveTo = ctx.moveTo; 5818 ctx.__originalLineTo = ctx.lineTo; 5819 ctx.__originalBezierCurveTo = ctx.bezierCurveTo; 5820 ctx.__originalRect = ctx.rect; 5821 ctx.__originalClosePath = ctx.closePath; 5822 ctx.__originalBeginPath = ctx.beginPath; 5823 ctx._removeMirroring = () => { 5824 ctx.save = ctx.__originalSave; 5825 ctx.restore = ctx.__originalRestore; 5826 ctx.rotate = ctx.__originalRotate; 5827 ctx.scale = ctx.__originalScale; 5828 ctx.translate = ctx.__originalTranslate; 5829 ctx.transform = ctx.__originalTransform; 5830 ctx.setTransform = ctx.__originalSetTransform; 5831 ctx.resetTransform = ctx.__originalResetTransform; 5832 ctx.clip = ctx.__originalClip; 5833 ctx.moveTo = ctx.__originalMoveTo; 5834 ctx.lineTo = ctx.__originalLineTo; 5835 ctx.bezierCurveTo = ctx.__originalBezierCurveTo; 5836 ctx.rect = ctx.__originalRect; 5837 ctx.closePath = ctx.__originalClosePath; 5838 ctx.beginPath = ctx.__originalBeginPath; 5839 delete ctx._removeMirroring; 5840 }; 5841 ctx.save = function ctxSave() { 5842 destCtx.save(); 5843 this.__originalSave(); 5844 }; 5845 ctx.restore = function ctxRestore() { 5846 destCtx.restore(); 5847 this.__originalRestore(); 5848 }; 5849 ctx.translate = function ctxTranslate(x, y) { 5850 destCtx.translate(x, y); 5851 this.__originalTranslate(x, y); 5852 }; 5853 ctx.scale = function ctxScale(x, y) { 5854 destCtx.scale(x, y); 5855 this.__originalScale(x, y); 5856 }; 5857 ctx.transform = function ctxTransform(a, b, c, d, e, f) { 5858 destCtx.transform(a, b, c, d, e, f); 5859 this.__originalTransform(a, b, c, d, e, f); 5860 }; 5861 ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) { 5862 destCtx.setTransform(a, b, c, d, e, f); 5863 this.__originalSetTransform(a, b, c, d, e, f); 5864 }; 5865 ctx.resetTransform = function ctxResetTransform() { 5866 destCtx.resetTransform(); 5867 this.__originalResetTransform(); 5868 }; 5869 ctx.rotate = function ctxRotate(angle) { 5870 destCtx.rotate(angle); 5871 this.__originalRotate(angle); 5872 }; 5873 ctx.clip = function ctxRotate(rule) { 5874 destCtx.clip(rule); 5875 this.__originalClip(rule); 5876 }; 5877 ctx.moveTo = function (x, y) { 5878 destCtx.moveTo(x, y); 5879 this.__originalMoveTo(x, y); 5880 }; 5881 ctx.lineTo = function (x, y) { 5882 destCtx.lineTo(x, y); 5883 this.__originalLineTo(x, y); 5884 }; 5885 ctx.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) { 5886 destCtx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); 5887 this.__originalBezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); 5888 }; 5889 ctx.rect = function (x, y, width, height) { 5890 destCtx.rect(x, y, width, height); 5891 this.__originalRect(x, y, width, height); 5892 }; 5893 ctx.closePath = function () { 5894 destCtx.closePath(); 5895 this.__originalClosePath(); 5896 }; 5897 ctx.beginPath = function () { 5898 destCtx.beginPath(); 5899 this.__originalBeginPath(); 5900 }; 5901} 5902class CachedCanvases { 5903 constructor(canvasFactory) { 5904 this.canvasFactory = canvasFactory; 5905 this.cache = Object.create(null); 5906 } 5907 getCanvas(id, width, height) {
5908 let canvasEntry; 5909 if (this.cache[id] !== undefined) { 5910 canvasEntry = this.cache[id]; 5911 this.canvasFactory.reset(canvasEntry, width, height); 5912 } else { 5913 canvasEntry = this.canvasFactory.create(width, height); 5914 this.cache[id] = canvasEntry; 5915 } 5916 return canvasEntry; 5917 } 5918 delete(id) { 5919 delete this.cache[id]; 5920 } 5921 clear() { 5922 for (const id in this.cache) { 5923 const canvasEntry = this.cache[id]; 5924 this.canvasFactory.destroy(canvasEntry); 5925 delete this.cache[id]; 5926 } 5927 } 5928} 5929function drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH) { 5930 const [a, b, c, d, tx, ty] = (0, _display_utils.getCurrentTransform)(ctx); 5931 if (b === 0 && c === 0) { 5932 const tlX = destX * a + tx; 5933 const rTlX = Math.round(tlX); 5934 const tlY = destY * d + ty; 5935 const rTlY = Math.round(tlY); 5936 const brX = (destX + destW) * a + tx; 5937 const rWidth = Math.abs(Math.round(brX) - rTlX) || 1; 5938 const brY = (destY + destH) * d + ty; 5939 const rHeight = Math.abs(Math.round(brY) - rTlY) || 1; 5940 ctx.setTransform(Math.sign(a), 0, 0, Math.sign(d), rTlX, rTlY); 5941 ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rWidth, rHeight); 5942 ctx.setTransform(a, b, c, d, tx, ty); 5943 return [rWidth, rHeight]; 5944 } 5945 if (a === 0 && d === 0) { 5946 const tlX = destY * c + tx; 5947 const rTlX = Math.round(tlX); 5948 const tlY = destX * b + ty; 5949 const rTlY = Math.round(tlY); 5950 const brX = (destY + destH) * c + tx; 5951 const rWidth = Math.abs(Math.round(brX) - rTlX) || 1; 5952 const brY = (destX + destW) * b + ty; 5953 const rHeight = Math.abs(Math.round(brY) - rTlY) || 1; 5954 ctx.setTransform(0, Math.sign(b), Math.sign(c), 0, rTlX, rTlY); 5955 ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rHeight, rWidth); 5956 ctx.setTransform(a, b, c, d, tx, ty); 5957 return [rHeight, rWidth]; 5958 } 5959 ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH); 5960 const scaleX = Math.hypot(a, b); 5961 const scaleY = Math.hypot(c, d); 5962 return [scaleX * destW, scaleY * destH]; 5963} 5964function compileType3Glyph(imgData) { 5965 const { 5966 width, 5967 height 5968 } = imgData; 5969 if (width > MAX_SIZE_TO_COMPILE || height > MAX_SIZE_TO_COMPILE) { 5970 return null; 5971 } 5972 const POINT_TO_PROCESS_LIMIT = 1000; 5973 const POINT_TYPES = new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]); 5974 const width1 = width + 1; 5975 let points = new Uint8Array(width1 * (height + 1)); 5976 let i, j, j0; 5977 const lineSize = width + 7 & ~7; 5978 let data = new Uint8Array(lineSize * height), 5979 pos = 0; 5980 for (const elem of imgData.data) { 5981 let mask = 128; 5982 while (mask > 0) { 5983 data[pos++] = elem & mask ? 0 : 255; 5984 mask >>= 1; 5985 } 5986 } 5987 let count = 0; 5988 pos = 0; 5989 if (data[pos] !== 0) { 5990 points[0] = 1; 5991 ++count; 5992 } 5993 for (j = 1; j < width; j++) { 5994 if (data[pos] !== data[pos + 1]) { 5995 points[j] = data[pos] ? 2 : 1; 5996 ++count; 5997 } 5998 pos++; 5999 } 6000 if (data[pos] !== 0) { 6001 points[j] = 2; 6002 ++count; 6003 } 6004 for (i = 1; i < height; i++) { 6005 pos = i * lineSize; 6006 j0 = i * width1; 6007 if (data[pos - lineSize] !== data[pos]) { 6008 points[j0] = data[pos] ? 1 : 8; 6009 ++count; 6010 } 6011 let sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0); 6012 for (j = 1; j < width; j++) { 6013 sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + (data[pos - lineSize + 1] ? 8 : 0); 6014 if (POINT_TYPES[sum]) { 6015 points[j0 + j] = POINT_TYPES[sum]; 6016 ++count; 6017 } 6018 pos++; 6019 } 6020 if (data[pos - lineSize] !== data[pos]) { 6021 points[j0 + j] = data[pos] ? 2 : 4; 6022 ++count; 6023 } 6024 if (count > POINT_TO_PROCESS_LIMIT) { 6025 return null; 6026 } 6027 } 6028 pos = lineSize * (height - 1); 6029 j0 = i * width1; 6030 if (data[pos] !== 0) { 6031 points[j0] = 8; 6032 ++count; 6033 } 6034 for (j = 1; j < width; j++) { 6035 if (data[pos] !== data[pos + 1]) { 6036 points[j0 + j] = data[pos] ? 4 : 8; 6037 ++count; 6038 } 6039 pos++; 6040 } 6041 if (data[pos] !== 0) { 6042 points[j0 + j] = 4; 6043 ++count; 6044 } 6045 if (count > POINT_TO_PROCESS_LIMIT) { 6046 return null; 6047 } 6048 const steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]); 6049 const path = new Path2D(); 6050 for (i = 0; count && i <= height; i++) { 6051 let p = i * width1; 6052 const end = p + width; 6053 while (p < end && !points[p]) { 6054 p++; 6055 } 6056 if (p === end) { 6057 continue; 6058 } 6059 path.moveTo(p % width1, i); 6060 const p0 = p; 6061 let type = points[p]; 6062 do { 6063 const step = steps[type]; 6064 do { 6065 p += step; 6066 } while (!points[p]); 6067 const pp = points[p]; 6068 if (pp !== 5 && pp !== 10) { 6069 type = pp; 6070 points[p] = 0; 6071 } else { 6072 type = pp & 0x33 * type >> 4; 6073 points[p] &= type >> 2 | type << 2; 6074 } 6075 path.lineTo(p % width1, p / width1 | 0); 6076 if (!points[p]) { 6077 --count; 6078 } 6079 } while (p0 !== p); 6080 --i; 6081 } 6082 data = null; 6083 points = null; 6084 const drawOutline = function (c) { 6085 c.save(); 6086 c.scale(1 / width, -1 / height); 6087 c.translate(0, -height); 6088 c.fill(path); 6089 c.beginPath();
6090 c.restore(); 6091 }; 6092 return drawOutline; 6093} 6094class CanvasExtraState { 6095 constructor(width, height) { 6096 this.alphaIsShape = false; 6097 this.fontSize = 0; 6098 this.fontSizeScale = 1; 6099 this.textMatrix = _util.IDENTITY_MATRIX; 6100 this.textMatrixScale = 1; 6101 this.fontMatrix = _util.FONT_IDENTITY_MATRIX; 6102 this.leading = 0; 6103 this.x = 0; 6104 this.y = 0; 6105 this.lineX = 0; 6106 this.lineY = 0; 6107 this.charSpacing = 0; 6108 this.wordSpacing = 0; 6109 this.textHScale = 1; 6110 this.textRenderingMode = _util.TextRenderingMode.FILL; 6111 this.textRise = 0; 6112 this.fillColor = "#000000"; 6113 this.strokeColor = "#000000"; 6114 this.patternFill = false; 6115 this.fillAlpha = 1; 6116 this.strokeAlpha = 1; 6117 this.lineWidth = 1; 6118 this.activeSMask = null; 6119 this.transferMaps = "none"; 6120 this.startNewPathAndClipBox([0, 0, width, height]); 6121 } 6122 clone() { 6123 const clone = Object.create(this); 6124 clone.clipBox = this.clipBox.slice(); 6125 return clone; 6126 } 6127 setCurrentPoint(x, y) { 6128 this.x = x; 6129 this.y = y; 6130 } 6131 updatePathMinMax(transform, x, y) { 6132 [x, y] = _util.Util.applyTransform([x, y], transform); 6133 this.minX = Math.min(this.minX, x); 6134 this.minY = Math.min(this.minY, y); 6135 this.maxX = Math.max(this.maxX, x); 6136 this.maxY = Math.max(this.maxY, y); 6137 } 6138 updateRectMinMax(transform, rect) { 6139 const p1 = _util.Util.applyTransform(rect, transform); 6140 const p2 = _util.Util.applyTransform(rect.slice(2), transform); 6141 this.minX = Math.min(this.minX, p1[0], p2[0]); 6142 this.minY = Math.min(this.minY, p1[1], p2[1]); 6143 this.maxX = Math.max(this.maxX, p1[0], p2[0]); 6144 this.maxY = Math.max(this.maxY, p1[1], p2[1]); 6145 } 6146 updateScalingPathMinMax(transform, minMax) { 6147 _util.Util.scaleMinMax(transform, minMax); 6148 this.minX = Math.min(this.minX, minMax[0]); 6149 this.maxX = Math.max(this.maxX, minMax[1]); 6150 this.minY = Math.min(this.minY, minMax[2]); 6151 this.maxY = Math.max(this.maxY, minMax[3]); 6152 } 6153 updateCurvePathMinMax(transform, x0, y0, x1, y1, x2, y2, x3, y3, minMax) { 6154 const box = _util.Util.bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3); 6155 if (minMax) { 6156 minMax[0] = Math.min(minMax[0], box[0], box[2]); 6157 minMax[1] = Math.max(minMax[1], box[0], box[2]); 6158 minMax[2] = Math.min(minMax[2], box[1], box[3]); 6159 minMax[3] = Math.max(minMax[3], box[1], box[3]); 6160 return; 6161 } 6162 this.updateRectMinMax(transform, box); 6163 } 6164 getPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) { 6165 const box = [this.minX, this.minY, this.maxX, this.maxY]; 6166 if (pathType === _pattern_helper.PathType.STROKE) { 6167 if (!transform) { 6168 (0, _util.unreachable)("Stroke bounding box must include transform."); 6169 } 6170 const scale = _util.Util.singularValueDecompose2dScale(transform); 6171 const xStrokePad = scale[0] * this.lineWidth / 2; 6172 const yStrokePad = scale[1] * this.lineWidth / 2; 6173 box[0] -= xStrokePad; 6174 box[1] -= yStrokePad; 6175 box[2] += xStrokePad; 6176 box[3] += yStrokePad; 6177 } 6178 return box; 6179 } 6180 updateClipFromPath() { 6181 const intersect = _util.Util.intersect(this.clipBox, this.getPathBoundingBox()); 6182 this.startNewPathAndClipBox(intersect || [0, 0, 0, 0]); 6183 } 6184 isEmptyClip() { 6185 return this.minX === Infinity; 6186 } 6187 startNewPathAndClipBox(box) { 6188 this.clipBox = box; 6189 this.minX = Infinity; 6190 this.minY = Infinity; 6191 this.maxX = 0; 6192 this.maxY = 0; 6193 } 6194 getClippedPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) { 6195 return _util.Util.intersect(this.clipBox, this.getPathBoundingBox(pathType, transform)); 6196 } 6197} 6198function putBinaryImageData(ctx, imgData) { 6199 if (typeof ImageData !== "undefined" && imgData instanceof ImageData) { 6200 ctx.putImageData(imgData, 0, 0); 6201 return; 6202 } 6203 const height = imgData.height, 6204 width = imgData.width; 6205 const partialChunkHeight = height % FULL_CHUNK_HEIGHT; 6206 const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; 6207 const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; 6208 const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); 6209 let srcPos = 0, 6210 destPos; 6211 const src = imgData.data; 6212 const dest = chunkImgData.data; 6213 let i, j, thisChunkHeight, elemsInThisChunk; 6214 if (imgData.kind === _util.ImageKind.GRAYSCALE_1BPP) { 6215 const srcLength = src.byteLength; 6216 const dest32 = new Uint32Array(dest.buffer, 0, dest.byteLength >> 2); 6217 const dest32DataLength = dest32.length; 6218 const fullSrcDiff = width + 7 >> 3; 6219 const white = 0xffffffff; 6220 const black = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; 6221 for (i = 0; i < totalChunks; i++) { 6222 thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight; 6223 destPos = 0; 6224 for (j = 0; j < thisChunkHeight; j++) { 6225 const srcDiff = srcLength - srcPos; 6226 let k = 0;
vendor: 4,451 bytes, lines 6227-6357
6227 const kEnd = srcDiff > fullSrcDiff ? width : srcDiff * 8 - 7; 6228 const kEndUnrolled = kEnd & ~7; 6229 let mask = 0; 6230 let srcByte = 0; 6231 for (; k < kEndUnrolled; k += 8) { 6232 srcByte = src[srcPos++]; 6233 dest32[destPos++] = srcByte & 128 ? white : black; 6234 dest32[destPos++] = srcByte & 64 ? white : black; 6235 dest32[destPos++] = srcByte & 32 ? white : black; 6236 dest32[destPos++] = srcByte & 16 ? white : black; 6237 dest32[destPos++] = srcByte & 8 ? white : black; 6238 dest32[destPos++] = srcByte & 4 ? white : black; 6239 dest32[destPos++] = srcByte & 2 ? white : black; 6240 dest32[destPos++] = srcByte & 1 ? white : black; 6241 } 6242 for (; k < kEnd; k++) { 6243 if (mask === 0) { 6244 srcByte = src[srcPos++]; 6245 mask = 128; 6246 } 6247 dest32[destPos++] = srcByte & mask ? white : black; 6248 mask >>= 1; 6249 } 6250 } 6251 while (destPos < dest32DataLength) { 6252 dest32[destPos++] = 0; 6253 } 6254 ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 6255 } 6256 } else if (imgData.kind === _util.ImageKind.RGBA_32BPP) { 6257 j = 0; 6258 elemsInThisChunk = width * FULL_CHUNK_HEIGHT * 4; 6259 for (i = 0; i < fullChunks; i++) { 6260 dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 6261 srcPos += elemsInThisChunk; 6262 ctx.putImageData(chunkImgData, 0, j); 6263 j += FULL_CHUNK_HEIGHT; 6264 } 6265 if (i < totalChunks) { 6266 elemsInThisChunk = width * partialChunkHeight * 4; 6267 dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 6268 ctx.putImageData(chunkImgData, 0, j); 6269 } 6270 } else if (imgData.kind === _util.ImageKind.RGB_24BPP) { 6271 thisChunkHeight = FULL_CHUNK_HEIGHT; 6272 elemsInThisChunk = width * thisChunkHeight; 6273 for (i = 0; i < totalChunks; i++) { 6274 if (i >= fullChunks) { 6275 thisChunkHeight = partialChunkHeight; 6276 elemsInThisChunk = width * thisChunkHeight; 6277 } 6278 destPos = 0; 6279 for (j = elemsInThisChunk; j--;) { 6280 dest[destPos++] = src[srcPos++]; 6281 dest[destPos++] = src[srcPos++]; 6282 dest[destPos++] = src[srcPos++]; 6283 dest[destPos++] = 255; 6284 } 6285 ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 6286 } 6287 } else { 6288 throw new Error(`bad image kind: ${imgData.kind}`); 6289 } 6290} 6291function putBinaryImageMask(ctx, imgData) { 6292 if (imgData.bitmap) { 6293 ctx.drawImage(imgData.bitmap, 0, 0); 6294 return; 6295 } 6296 const height = imgData.height, 6297 width = imgData.width; 6298 const partialChunkHeight = height % FULL_CHUNK_HEIGHT; 6299 const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; 6300 const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; 6301 const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); 6302 let srcPos = 0; 6303 const src = imgData.data; 6304 const dest = chunkImgData.data; 6305 for (let i = 0; i < totalChunks; i++) { 6306 const thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight; 6307 ({ 6308 srcPos 6309 } = (0, _image_utils.convertBlackAndWhiteToRGBA)({ 6310 src, 6311 srcPos, 6312 dest, 6313 width, 6314 height: thisChunkHeight, 6315 nonBlackColor: 0 6316 })); 6317 ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 6318 } 6319} 6320function copyCtxState(sourceCtx, destCtx) { 6321 const properties = ["strokeStyle", "fillStyle", "fillRule", "globalAlpha", "lineWidth", "lineCap", "lineJoin", "miterLimit", "globalCompositeOperation", "font", "filter"]; 6322 for (const property of properties) { 6323 if (sourceCtx[property] !== undefined) { 6324 destCtx[property] = sourceCtx[property]; 6325 } 6326 } 6327 if (sourceCtx.setLineDash !== undefined) { 6328 destCtx.setLineDash(sourceCtx.getLineDash()); 6329 destCtx.lineDashOffset = sourceCtx.lineDashOffset; 6330 } 6331} 6332function resetCtxToDefault(ctx) { 6333 ctx.strokeStyle = ctx.fillStyle = "#000000"; 6334 ctx.fillRule = "nonzero"; 6335 ctx.globalAlpha = 1; 6336 ctx.lineWidth = 1; 6337 ctx.lineCap = "butt"; 6338 ctx.lineJoin = "miter"; 6339 ctx.miterLimit = 10; 6340 ctx.globalCompositeOperation = "source-over"; 6341 ctx.font = "10px sans-serif"; 6342 if (ctx.setLineDash !== undefined) { 6343 ctx.setLineDash([]); 6344 ctx.lineDashOffset = 0; 6345 } 6346 if (!_util.isNodeJS) { 6347 const { 6348 filter 6349 } = ctx; 6350 if (filter !== "none" && filter !== "") { 6351 ctx.filter = "none"; 6352 } 6353 } 6354} 6355function composeSMaskBackdrop(bytes, r0, g0, b0) { 6356 const length = bytes.length; 6357 for (let i = 3; i < length; i += 4) {
6358 const alpha = bytes[i]; 6359 if (alpha === 0) { 6360 bytes[i - 3] = r0; 6361 bytes[i - 2] = g0; 6362 bytes[i - 1] = b0; 6363 } else if (alpha < 255) { 6364 const alpha_ = 255 - alpha; 6365 bytes[i - 3] = bytes[i - 3] * alpha + r0 * alpha_ >> 8; 6366 bytes[i - 2] = bytes[i - 2] * alpha + g0 * alpha_ >> 8; 6367 bytes[i - 1] = bytes[i - 1] * alpha + b0 * alpha_ >> 8; 6368 } 6369 } 6370} 6371function composeSMaskAlpha(maskData, layerData, transferMap) { 6372 const length = maskData.length; 6373 const scale = 1 / 255; 6374 for (let i = 3; i < length; i += 4) { 6375 const alpha = transferMap ? transferMap[maskData[i]] : maskData[i]; 6376 layerData[i] = layerData[i] * alpha * scale | 0; 6377 } 6378} 6379function composeSMaskLuminosity(maskData, layerData, transferMap) { 6380 const length = maskData.length; 6381 for (let i = 3; i < length; i += 4) { 6382 const y = maskData[i - 3] * 77 + maskData[i - 2] * 152 + maskData[i - 1] * 28; 6383 layerData[i] = transferMap ? layerData[i] * transferMap[y >> 8] >> 8 : layerData[i] * y >> 16; 6384 } 6385} 6386function genericComposeSMask(maskCtx, layerCtx, width, height, subtype, backdrop, transferMap, layerOffsetX, layerOffsetY, maskOffsetX, maskOffsetY) { 6387 const hasBackdrop = !!backdrop; 6388 const r0 = hasBackdrop ? backdrop[0] : 0; 6389 const g0 = hasBackdrop ? backdrop[1] : 0; 6390 const b0 = hasBackdrop ? backdrop[2] : 0; 6391 const composeFn = subtype === "Luminosity" ? composeSMaskLuminosity : composeSMaskAlpha; 6392 const PIXELS_TO_PROCESS = 1048576; 6393 const chunkSize = Math.min(height, Math.ceil(PIXELS_TO_PROCESS / width)); 6394 for (let row = 0; row < height; row += chunkSize) { 6395 const chunkHeight = Math.min(chunkSize, height - row); 6396 const maskData = maskCtx.getImageData(layerOffsetX - maskOffsetX, row + (layerOffsetY - maskOffsetY), width, chunkHeight); 6397 const layerData = layerCtx.getImageData(layerOffsetX, row + layerOffsetY, width, chunkHeight); 6398 if (hasBackdrop) { 6399 composeSMaskBackdrop(maskData.data, r0, g0, b0); 6400 } 6401 composeFn(maskData.data, layerData.data, transferMap); 6402 layerCtx.putImageData(layerData, layerOffsetX, row + layerOffsetY); 6403 } 6404} 6405function composeSMask(ctx, smask, layerCtx, layerBox) { 6406 const layerOffsetX = layerBox[0]; 6407 const layerOffsetY = layerBox[1]; 6408 const layerWidth = layerBox[2] - layerOffsetX; 6409 const layerHeight = layerBox[3] - layerOffsetY; 6410 if (layerWidth === 0 || layerHeight === 0) { 6411 return; 6412 } 6413 genericComposeSMask(smask.context, layerCtx, layerWidth, layerHeight, smask.subtype, smask.backdrop, smask.transferMap, layerOffsetX, layerOffsetY, smask.offsetX, smask.offsetY); 6414 ctx.save(); 6415 ctx.globalAlpha = 1; 6416 ctx.globalCompositeOperation = "source-over"; 6417 ctx.setTransform(1, 0, 0, 1, 0, 0); 6418 ctx.drawImage(layerCtx.canvas, 0, 0); 6419 ctx.restore(); 6420} 6421function getImageSmoothingEnabled(transform, interpolate) { 6422 const scale = _util.Util.singularValueDecompose2dScale(transform); 6423 scale[0] = Math.fround(scale[0]); 6424 scale[1] = Math.fround(scale[1]); 6425 const actualScale = Math.fround((globalThis.devicePixelRatio || 1) * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS); 6426 if (interpolate !== undefined) { 6427 return interpolate; 6428 } else if (scale[0] <= actualScale || scale[1] <= actualScale) { 6429 return true; 6430 } 6431 return false; 6432} 6433const LINE_CAP_STYLES = ["butt", "round", "square"]; 6434const LINE_JOIN_STYLES = ["miter", "round", "bevel"]; 6435const NORMAL_CLIP = {}; 6436const EO_CLIP = {}; 6437class CanvasGraphics { 6438 constructor(canvasCtx, commonObjs, objs, canvasFactory, filterFactory, { 6439 optionalContentConfig, 6440 markedContentStack = null 6441 }, annotationCanvasMap, pageColors) { 6442 this.ctx = canvasCtx; 6443 this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height); 6444 this.stateStack = []; 6445 this.pendingClip = null; 6446 this.pendingEOFill = false; 6447 this.res = null; 6448 this.xobjs = null; 6449 this.commonObjs = commonObjs; 6450 this.objs = objs; 6451 this.canvasFactory = canvasFactory; 6452 this.filterFactory = filterFactory; 6453 this.groupStack = []; 6454 this.processingType3 = null; 6455 this.baseTransform = null; 6456 this.baseTransformStack = []; 6457 this.groupLevel = 0; 6458 this.smaskStack = []; 6459 this.smaskCounter = 0; 6460 this.tempSMask = null; 6461 this.suspendedCtx = null; 6462 this.contentVisible = true; 6463 this.markedContentStack = markedContentStack || []; 6464 this.optionalContentConfig = optionalContentConfig; 6465 this.cachedCanvases = new CachedCanvases(this.canvasFactory); 6466 this.cachedPatterns = new Map(); 6467 this.annotationCanvasMap = annotationCanvasMap; 6468 this.viewportScale = 1; 6469 this.outputScaleX = 1; 6470 this.outputScaleY = 1;
6471 this.pageColors = pageColors; 6472 this._cachedScaleForStroking = [-1, 0]; 6473 this._cachedGetSinglePixelWidth = null; 6474 this._cachedBitmapsMap = new Map(); 6475 } 6476 getObject(data, fallback = null) { 6477 if (typeof data === "string") { 6478 return data.startsWith("g_") ? this.commonObjs.get(data) : this.objs.get(data); 6479 } 6480 return fallback; 6481 } 6482 beginDrawing({ 6483 transform, 6484 viewport, 6485 transparency = false, 6486 background = null 6487 }) { 6488 const width = this.ctx.canvas.width; 6489 const height = this.ctx.canvas.height; 6490 const savedFillStyle = this.ctx.fillStyle; 6491 this.ctx.fillStyle = background || "#ffffff"; 6492 this.ctx.fillRect(0, 0, width, height); 6493 this.ctx.fillStyle = savedFillStyle; 6494 if (transparency) { 6495 const transparentCanvas = this.cachedCanvases.getCanvas("transparent", width, height); 6496 this.compositeCtx = this.ctx; 6497 this.transparentCanvas = transparentCanvas.canvas; 6498 this.ctx = transparentCanvas.context; 6499 this.ctx.save(); 6500 this.ctx.transform(...(0, _display_utils.getCurrentTransform)(this.compositeCtx)); 6501 } 6502 this.ctx.save(); 6503 resetCtxToDefault(this.ctx); 6504 if (transform) { 6505 this.ctx.transform(...transform); 6506 this.outputScaleX = transform[0]; 6507 this.outputScaleY = transform[0]; 6508 } 6509 this.ctx.transform(...viewport.transform); 6510 this.viewportScale = viewport.scale; 6511 this.baseTransform = (0, _display_utils.getCurrentTransform)(this.ctx); 6512 } 6513 executeOperatorList(operatorList, executionStartIdx, continueCallback, stepper) { 6514 const argsArray = operatorList.argsArray; 6515 const fnArray = operatorList.fnArray; 6516 let i = executionStartIdx || 0; 6517 const argsArrayLen = argsArray.length; 6518 if (argsArrayLen === i) { 6519 return i; 6520 } 6521 const chunkOperations = argsArrayLen - i > EXECUTION_STEPS && typeof continueCallback === "function"; 6522 const endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0; 6523 let steps = 0; 6524 const commonObjs = this.commonObjs; 6525 const objs = this.objs; 6526 let fnId; 6527 while (true) { 6528 if (stepper !== undefined && i === stepper.nextBreakPoint) { 6529 stepper.breakIt(i, continueCallback); 6530 return i; 6531 } 6532 fnId = fnArray[i]; 6533 if (fnId !== _util.OPS.dependency) { 6534 this[fnId].apply(this, argsArray[i]); 6535 } else { 6536 for (const depObjId of argsArray[i]) { 6537 const objsPool = depObjId.startsWith("g_") ? commonObjs : objs; 6538 if (!objsPool.has(depObjId)) { 6539 objsPool.get(depObjId, continueCallback); 6540 return i; 6541 } 6542 } 6543 } 6544 i++; 6545 if (i === argsArrayLen) { 6546 return i; 6547 } 6548 if (chunkOperations && ++steps > EXECUTION_STEPS) { 6549 if (Date.now() > endTime) { 6550 continueCallback(); 6551 return i; 6552 } 6553 steps = 0; 6554 } 6555 } 6556 } 6557 #restoreInitialState() { 6558 while (this.stateStack.length || this.inSMaskMode) { 6559 this.restore(); 6560 } 6561 this.ctx.restore(); 6562 if (this.transparentCanvas) { 6563 this.ctx = this.compositeCtx; 6564 this.ctx.save(); 6565 this.ctx.setTransform(1, 0, 0, 1, 0, 0); 6566 this.ctx.drawImage(this.transparentCanvas, 0, 0); 6567 this.ctx.restore(); 6568 this.transparentCanvas = null; 6569 } 6570 } 6571 endDrawing() { 6572 this.#restoreInitialState(); 6573 this.cachedCanvases.clear(); 6574 this.cachedPatterns.clear(); 6575 for (const cache of this._cachedBitmapsMap.values()) { 6576 for (const canvas of cache.values()) { 6577 if (typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) { 6578 canvas.width = canvas.height = 0; 6579 } 6580 } 6581 cache.clear(); 6582 } 6583 this._cachedBitmapsMap.clear(); 6584 this.#drawFilter(); 6585 } 6586 #drawFilter() { 6587 if (this.pageColors) { 6588 const hcmFilterId = this.filterFactory.addHCMFilter(this.pageColors.foreground, this.pageColors.background); 6589 if (hcmFilterId !== "none") { 6590 const savedFilter = this.ctx.filter; 6591 this.ctx.filter = hcmFilterId; 6592 this.ctx.drawImage(this.ctx.canvas, 0, 0); 6593 this.ctx.filter = savedFilter; 6594 } 6595 } 6596 } 6597 _scaleImage(img, inverseTransform) { 6598 const width = img.width;
6599 const height = img.height; 6600 let widthScale = Math.max(Math.hypot(inverseTransform[0], inverseTransform[1]), 1); 6601 let heightScale = Math.max(Math.hypot(inverseTransform[2], inverseTransform[3]), 1); 6602 let paintWidth = width, 6603 paintHeight = height; 6604 let tmpCanvasId = "prescale1"; 6605 let tmpCanvas, tmpCtx; 6606 while (widthScale > 2 && paintWidth > 1 || heightScale > 2 && paintHeight > 1) { 6607 let newWidth = paintWidth, 6608 newHeight = paintHeight; 6609 if (widthScale > 2 && paintWidth > 1) { 6610 newWidth = paintWidth >= 16384 ? Math.floor(paintWidth / 2) - 1 || 1 : Math.ceil(paintWidth / 2); 6611 widthScale /= paintWidth / newWidth; 6612 } 6613 if (heightScale > 2 && paintHeight > 1) { 6614 newHeight = paintHeight >= 16384 ? Math.floor(paintHeight / 2) - 1 || 1 : Math.ceil(paintHeight) / 2; 6615 heightScale /= paintHeight / newHeight; 6616 } 6617 tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight); 6618 tmpCtx = tmpCanvas.context; 6619 tmpCtx.clearRect(0, 0, newWidth, newHeight); 6620 tmpCtx.drawImage(img, 0, 0, paintWidth, paintHeight, 0, 0, newWidth, newHeight); 6621 img = tmpCanvas.canvas; 6622 paintWidth = newWidth; 6623 paintHeight = newHeight; 6624 tmpCanvasId = tmpCanvasId === "prescale1" ? "prescale2" : "prescale1"; 6625 } 6626 return { 6627 img, 6628 paintWidth, 6629 paintHeight 6630 }; 6631 } 6632 _createMaskCanvas(img) { 6633 const ctx = this.ctx; 6634 const { 6635 width, 6636 height 6637 } = img; 6638 const fillColor = this.current.fillColor; 6639 const isPatternFill = this.current.patternFill; 6640 const currentTransform = (0, _display_utils.getCurrentTransform)(ctx); 6641 let cache, cacheKey, scaled, maskCanvas; 6642 if ((img.bitmap || img.data) && img.count > 1) { 6643 const mainKey = img.bitmap || img.data.buffer; 6644 cacheKey = JSON.stringify(isPatternFill ? currentTransform : [currentTransform.slice(0, 4), fillColor]); 6645 cache = this._cachedBitmapsMap.get(mainKey); 6646 if (!cache) { 6647 cache = new Map(); 6648 this._cachedBitmapsMap.set(mainKey, cache); 6649 } 6650 const cachedImage = cache.get(cacheKey); 6651 if (cachedImage && !isPatternFill) { 6652 const offsetX = Math.round(Math.min(currentTransform[0], currentTransform[2]) + currentTransform[4]); 6653 const offsetY = Math.round(Math.min(currentTransform[1], currentTransform[3]) + currentTransform[5]); 6654 return { 6655 canvas: cachedImage, 6656 offsetX, 6657 offsetY 6658 }; 6659 } 6660 scaled = cachedImage; 6661 } 6662 if (!scaled) { 6663 maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height); 6664 putBinaryImageMask(maskCanvas.context, img); 6665 } 6666 let maskToCanvas = _util.Util.transform(currentTransform, [1 / width, 0, 0, -1 / height, 0, 0]); 6667 maskToCanvas = _util.Util.transform(maskToCanvas, [1, 0, 0, 1, 0, -height]); 6668 const cord1 = _util.Util.applyTransform([0, 0], maskToCanvas); 6669 const cord2 = _util.Util.applyTransform([width, height], maskToCanvas); 6670 const rect = _util.Util.normalizeRect([cord1[0], cord1[1], cord2[0], cord2[1]]); 6671 const drawnWidth = Math.round(rect[2] - rect[0]) || 1; 6672 const drawnHeight = Math.round(rect[3] - rect[1]) || 1; 6673 const fillCanvas = this.cachedCanvases.getCanvas("fillCanvas", drawnWidth, drawnHeight); 6674 const fillCtx = fillCanvas.context; 6675 const offsetX = Math.min(cord1[0], cord2[0]); 6676 const offsetY = Math.min(cord1[1], cord2[1]); 6677 fillCtx.translate(-offsetX, -offsetY); 6678 fillCtx.transform(...maskToCanvas); 6679 if (!scaled) { 6680 scaled = this._scaleImage(maskCanvas.canvas, (0, _display_utils.getCurrentTransformInverse)(fillCtx)); 6681 scaled = scaled.img; 6682 if (cache && isPatternFill) { 6683 cache.set(cacheKey, scaled); 6684 } 6685 } 6686 fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled((0, _display_utils.getCurrentTransform)(fillCtx), img.interpolate); 6687 drawImageAtIntegerCoords(fillCtx, scaled, 0, 0, scaled.width, scaled.height, 0, 0, width, height); 6688 fillCtx.globalCompositeOperation = "source-in"; 6689 const inverse = _util.Util.transform((0, _display_utils.getCurrentTransformInverse)(fillCtx), [1, 0, 0, 1, -offsetX, -offsetY]); 6690 fillCtx.fillStyle = isPatternFill ? fillColor.getPattern(ctx, this, inverse, _pattern_helper.PathType.FILL) : fillColor; 6691 fillCtx.fillRect(0, 0, width, height); 6692 if (cache && !isPatternFill) { 6693 this.cachedCanvases.delete("fillCanvas"); 6694 cache.set(cacheKey, fillCanvas.canvas); 6695 } 6696 return {
6697 canvas: fillCanvas.canvas, 6698 offsetX: Math.round(offsetX), 6699 offsetY: Math.round(offsetY) 6700 }; 6701 } 6702 setLineWidth(width) { 6703 if (width !== this.current.lineWidth) { 6704 this._cachedScaleForStroking[0] = -1; 6705 } 6706 this.current.lineWidth = width; 6707 this.ctx.lineWidth = width; 6708 } 6709 setLineCap(style) { 6710 this.ctx.lineCap = LINE_CAP_STYLES[style]; 6711 } 6712 setLineJoin(style) { 6713 this.ctx.lineJoin = LINE_JOIN_STYLES[style]; 6714 } 6715 setMiterLimit(limit) { 6716 this.ctx.miterLimit = limit; 6717 } 6718 setDash(dashArray, dashPhase) { 6719 const ctx = this.ctx; 6720 if (ctx.setLineDash !== undefined) { 6721 ctx.setLineDash(dashArray); 6722 ctx.lineDashOffset = dashPhase; 6723 } 6724 } 6725 setRenderingIntent(intent) {} 6726 setFlatness(flatness) {} 6727 setGState(states) { 6728 for (const [key, value] of states) { 6729 switch (key) { 6730 case "LW": 6731 this.setLineWidth(value); 6732 break; 6733 case "LC": 6734 this.setLineCap(value); 6735 break; 6736 case "LJ": 6737 this.setLineJoin(value); 6738 break; 6739 case "ML": 6740 this.setMiterLimit(value); 6741 break; 6742 case "D": 6743 this.setDash(value[0], value[1]); 6744 break; 6745 case "RI": 6746 this.setRenderingIntent(value); 6747 break; 6748 case "FL": 6749 this.setFlatness(value); 6750 break; 6751 case "Font": 6752 this.setFont(value[0], value[1]); 6753 break; 6754 case "CA": 6755 this.current.strokeAlpha = value; 6756 break; 6757 case "ca": 6758 this.current.fillAlpha = value; 6759 this.ctx.globalAlpha = value; 6760 break; 6761 case "BM": 6762 this.ctx.globalCompositeOperation = value; 6763 break; 6764 case "SMask": 6765 this.current.activeSMask = value ? this.tempSMask : null; 6766 this.tempSMask = null; 6767 this.checkSMaskState(); 6768 break; 6769 case "TR": 6770 this.ctx.filter = this.current.transferMaps = this.filterFactory.addFilter(value); 6771 break; 6772 } 6773 } 6774 } 6775 get inSMaskMode() { 6776 return !!this.suspendedCtx; 6777 } 6778 checkSMaskState() { 6779 const inSMaskMode = this.inSMaskMode; 6780 if (this.current.activeSMask && !inSMaskMode) { 6781 this.beginSMaskMode(); 6782 } else if (!this.current.activeSMask && inSMaskMode) { 6783 this.endSMaskMode(); 6784 } 6785 } 6786 beginSMaskMode() { 6787 if (this.inSMaskMode) { 6788 throw new Error("beginSMaskMode called while already in smask mode"); 6789 } 6790 const drawnWidth = this.ctx.canvas.width; 6791 const drawnHeight = this.ctx.canvas.height; 6792 const cacheId = "smaskGroupAt" + this.groupLevel; 6793 const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight); 6794 this.suspendedCtx = this.ctx; 6795 this.ctx = scratchCanvas.context; 6796 const ctx = this.ctx; 6797 ctx.setTransform(...(0, _display_utils.getCurrentTransform)(this.suspendedCtx)); 6798 copyCtxState(this.suspendedCtx, ctx); 6799 mirrorContextOperations(ctx, this.suspendedCtx); 6800 this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]); 6801 } 6802 endSMaskMode() { 6803 if (!this.inSMaskMode) { 6804 throw new Error("endSMaskMode called while not in smask mode"); 6805 } 6806 this.ctx._removeMirroring(); 6807 copyCtxState(this.ctx, this.suspendedCtx); 6808 this.ctx = this.suspendedCtx; 6809 this.suspendedCtx = null; 6810 } 6811 compose(dirtyBox) { 6812 if (!this.current.activeSMask) { 6813 return; 6814 } 6815 if (!dirtyBox) { 6816 dirtyBox = [0, 0, this.ctx.canvas.width, this.ctx.canvas.height]; 6817 } else { 6818 dirtyBox[0] = Math.floor(dirtyBox[0]); 6819 dirtyBox[1] = Math.floor(dirtyBox[1]); 6820 dirtyBox[2] = Math.ceil(dirtyBox[2]); 6821 dirtyBox[3] = Math.ceil(dirtyBox[3]); 6822 } 6823 const smask = this.current.activeSMask; 6824 const suspendedCtx = this.suspendedCtx; 6825 composeSMask(suspendedCtx, smask, this.ctx, dirtyBox); 6826 this.ctx.save(); 6827 this.ctx.setTransform(1, 0, 0, 1, 0, 0); 6828 this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height); 6829 this.ctx.restore(); 6830 } 6831 save() { 6832 if (this.inSMaskMode) { 6833 copyCtxState(this.ctx, this.suspendedCtx); 6834 this.suspendedCtx.save(); 6835 } else { 6836 this.ctx.save(); 6837 } 6838 const old = this.current; 6839 this.stateStack.push(old); 6840 this.current = old.clone(); 6841 }
6842 restore() { 6843 if (this.stateStack.length === 0 && this.inSMaskMode) { 6844 this.endSMaskMode(); 6845 } 6846 if (this.stateStack.length !== 0) { 6847 this.current = this.stateStack.pop(); 6848 if (this.inSMaskMode) { 6849 this.suspendedCtx.restore(); 6850 copyCtxState(this.suspendedCtx, this.ctx); 6851 } else { 6852 this.ctx.restore(); 6853 } 6854 this.checkSMaskState(); 6855 this.pendingClip = null; 6856 this._cachedScaleForStroking[0] = -1; 6857 this._cachedGetSinglePixelWidth = null; 6858 } 6859 } 6860 transform(a, b, c, d, e, f) { 6861 this.ctx.transform(a, b, c, d, e, f); 6862 this._cachedScaleForStroking[0] = -1; 6863 this._cachedGetSinglePixelWidth = null; 6864 } 6865 constructPath(ops, args, minMax) { 6866 const ctx = this.ctx; 6867 const current = this.current; 6868 let x = current.x, 6869 y = current.y; 6870 let startX, startY; 6871 const currentTransform = (0, _display_utils.getCurrentTransform)(ctx); 6872 const isScalingMatrix = currentTransform[0] === 0 && currentTransform[3] === 0 || currentTransform[1] === 0 && currentTransform[2] === 0; 6873 const minMaxForBezier = isScalingMatrix ? minMax.slice(0) : null; 6874 for (let i = 0, j = 0, ii = ops.length; i < ii; i++) { 6875 switch (ops[i] | 0) { 6876 case _util.OPS.rectangle: 6877 x = args[j++]; 6878 y = args[j++]; 6879 const width = args[j++]; 6880 const height = args[j++]; 6881 const xw = x + width; 6882 const yh = y + height; 6883 ctx.moveTo(x, y); 6884 if (width === 0 || height === 0) { 6885 ctx.lineTo(xw, yh); 6886 } else { 6887 ctx.lineTo(xw, y); 6888 ctx.lineTo(xw, yh); 6889 ctx.lineTo(x, yh); 6890 } 6891 if (!isScalingMatrix) { 6892 current.updateRectMinMax(currentTransform, [x, y, xw, yh]); 6893 } 6894 ctx.closePath(); 6895 break; 6896 case _util.OPS.moveTo: 6897 x = args[j++]; 6898 y = args[j++]; 6899 ctx.moveTo(x, y); 6900 if (!isScalingMatrix) { 6901 current.updatePathMinMax(currentTransform, x, y); 6902 } 6903 break; 6904 case _util.OPS.lineTo: 6905 x = args[j++]; 6906 y = args[j++]; 6907 ctx.lineTo(x, y); 6908 if (!isScalingMatrix) { 6909 current.updatePathMinMax(currentTransform, x, y); 6910 } 6911 break; 6912 case _util.OPS.curveTo: 6913 startX = x; 6914 startY = y; 6915 x = args[j + 4]; 6916 y = args[j + 5]; 6917 ctx.bezierCurveTo(args[j], args[j + 1], args[j + 2], args[j + 3], x, y); 6918 current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], args[j + 2], args[j + 3], x, y, minMaxForBezier); 6919 j += 6; 6920 break; 6921 case _util.OPS.curveTo2: 6922 startX = x; 6923 startY = y; 6924 ctx.bezierCurveTo(x, y, args[j], args[j + 1], args[j + 2], args[j + 3]); 6925 current.updateCurvePathMinMax(currentTransform, startX, startY, x, y, args[j], args[j + 1], args[j + 2], args[j + 3], minMaxForBezier); 6926 x = args[j + 2]; 6927 y = args[j + 3]; 6928 j += 4; 6929 break; 6930 case _util.OPS.curveTo3: 6931 startX = x; 6932 startY = y; 6933 x = args[j + 2]; 6934 y = args[j + 3]; 6935 ctx.bezierCurveTo(args[j], args[j + 1], x, y, x, y); 6936 current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], x, y, x, y, minMaxForBezier); 6937 j += 4; 6938 break; 6939 case _util.OPS.closePath: 6940 ctx.closePath(); 6941 break; 6942 } 6943 } 6944 if (isScalingMatrix) { 6945 current.updateScalingPathMinMax(currentTransform, minMaxForBezier); 6946 } 6947 current.setCurrentPoint(x, y); 6948 } 6949 closePath() { 6950 this.ctx.closePath(); 6951 }
6952 stroke(consumePath = true) { 6953 const ctx = this.ctx; 6954 const strokeColor = this.current.strokeColor; 6955 ctx.globalAlpha = this.current.strokeAlpha; 6956 if (this.contentVisible) { 6957 if (typeof strokeColor === "object" && strokeColor?.getPattern) { 6958 ctx.save(); 6959 ctx.strokeStyle = strokeColor.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.STROKE); 6960 this.rescaleAndStroke(false); 6961 ctx.restore(); 6962 } else { 6963 this.rescaleAndStroke(true); 6964 } 6965 } 6966 if (consumePath) { 6967 this.consumePath(this.current.getClippedPathBoundingBox()); 6968 } 6969 ctx.globalAlpha = this.current.fillAlpha; 6970 } 6971 closeStroke() { 6972 this.closePath(); 6973 this.stroke(); 6974 } 6975 fill(consumePath = true) { 6976 const ctx = this.ctx; 6977 const fillColor = this.current.fillColor; 6978 const isPatternFill = this.current.patternFill; 6979 let needRestore = false; 6980 if (isPatternFill) { 6981 ctx.save(); 6982 ctx.fillStyle = fillColor.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.FILL); 6983 needRestore = true; 6984 } 6985 const intersect = this.current.getClippedPathBoundingBox(); 6986 if (this.contentVisible && intersect !== null) { 6987 if (this.pendingEOFill) { 6988 ctx.fill("evenodd"); 6989 this.pendingEOFill = false; 6990 } else { 6991 ctx.fill(); 6992 } 6993 } 6994 if (needRestore) { 6995 ctx.restore(); 6996 } 6997 if (consumePath) { 6998 this.consumePath(intersect); 6999 } 7000 } 7001 eoFill() { 7002 this.pendingEOFill = true; 7003 this.fill(); 7004 } 7005 fillStroke() { 7006 this.fill(false); 7007 this.stroke(false); 7008 this.consumePath(); 7009 } 7010 eoFillStroke() { 7011 this.pendingEOFill = true; 7012 this.fillStroke(); 7013 } 7014 closeFillStroke() { 7015 this.closePath(); 7016 this.fillStroke(); 7017 } 7018 closeEOFillStroke() { 7019 this.pendingEOFill = true; 7020 this.closePath(); 7021 this.fillStroke(); 7022 } 7023 endPath() { 7024 this.consumePath(); 7025 } 7026 clip() { 7027 this.pendingClip = NORMAL_CLIP; 7028 } 7029 eoClip() { 7030 this.pendingClip = EO_CLIP; 7031 } 7032 beginText() { 7033 this.current.textMatrix = _util.IDENTITY_MATRIX; 7034 this.current.textMatrixScale = 1; 7035 this.current.x = this.current.lineX = 0; 7036 this.current.y = this.current.lineY = 0; 7037 } 7038 endText() { 7039 const paths = this.pendingTextPaths; 7040 const ctx = this.ctx; 7041 if (paths === undefined) { 7042 ctx.beginPath(); 7043 return; 7044 } 7045 ctx.save(); 7046 ctx.beginPath(); 7047 for (const path of paths) { 7048 ctx.setTransform(...path.transform); 7049 ctx.translate(path.x, path.y); 7050 path.addToPath(ctx, path.fontSize); 7051 } 7052 ctx.restore(); 7053 ctx.clip(); 7054 ctx.beginPath(); 7055 delete this.pendingTextPaths; 7056 } 7057 setCharSpacing(spacing) { 7058 this.current.charSpacing = spacing; 7059 } 7060 setWordSpacing(spacing) { 7061 this.current.wordSpacing = spacing; 7062 } 7063 setHScale(scale) { 7064 this.current.textHScale = scale / 100; 7065 } 7066 setLeading(leading) { 7067 this.current.leading = -leading; 7068 } 7069 setFont(fontRefName, size) { 7070 const fontObj = this.commonObjs.get(fontRefName); 7071 const current = this.current; 7072 if (!fontObj) { 7073 throw new Error(`Can't find font for ${fontRefName}`); 7074 } 7075 current.fontMatrix = fontObj.fontMatrix || _util.FONT_IDENTITY_MATRIX; 7076 if (current.fontMatrix[0] === 0 || current.fontMatrix[3] === 0) { 7077 (0, _util.warn)("Invalid font matrix for font " + fontRefName); 7078 } 7079 if (size < 0) { 7080 size = -size; 7081 current.fontDirection = -1; 7082 } else { 7083 current.fontDirection = 1; 7084 } 7085 this.current.font = fontObj; 7086 this.current.fontSize = size; 7087 if (fontObj.isType3Font) { 7088 return; 7089 } 7090 const name = fontObj.loadedName || "sans-serif"; 7091 const typeface = fontObj.systemFontInfo?.css || `"${name}", ${fontObj.fallbackName}`; 7092 let bold = "normal"; 7093 if (fontObj.black) { 7094 bold = "900"; 7095 } else if (fontObj.bold) { 7096 bold = "bold"; 7097 } 7098 const italic = fontObj.italic ? "italic" : "normal"; 7099 let browserFontSize = size; 7100 if (size < MIN_FONT_SIZE) { 7101 browserFontSize = MIN_FONT_SIZE; 7102 } else if (size > MAX_FONT_SIZE) { 7103 browserFontSize = MAX_FONT_SIZE; 7104 } 7105 this.current.fontSizeScale = size / browserFontSize; 7106 this.ctx.font = `${italic} ${bold} ${browserFontSize}px ${typeface}`; 7107 } 7108 setTextRenderingMode(mode) { 7109 this.current.textRenderingMode = mode; 7110 } 7111 setTextRise(rise) { 7112 this.current.textRise = rise; 7113 } 7114 moveText(x, y) { 7115 this.current.x = this.current.lineX += x; 7116 this.current.y = this.current.lineY += y; 7117 } 7118 setLeadingMoveText(x, y) { 7119 this.setLeading(-y); 7120 this.moveText(x, y); 7121 } 7122 setTextMatrix(a, b, c, d, e, f) { 7123 this.current.textMatrix = [a, b, c, d, e, f]; 7124 this.current.textMatrixScale = Math.hypot(a, b); 7125 this.current.x = this.current.lineX = 0; 7126 this.current.y = this.current.lineY = 0; 7127 } 7128 nextLine() { 7129 this.moveText(0, this.current.leading); 7130 } 7131 paintChar(character, x, y, patternTransform) { 7132 const ctx = this.ctx; 7133 const current = this.current; 7134 const font = current.font; 7135 const textRenderingMode = current.textRenderingMode; 7136 const fontSize = current.fontSize / current.fontSizeScale; 7137 const fillStrokeMode = textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; 7138 const isAddToPathSet = !!(textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG); 7139 const patternFill = current.patternFill && !font.missingFile; 7140 let addToPath; 7141 if (font.disableFontFace || isAddToPathSet || patternFill) { 7142 addToPath = font.getPathGenerator(this.commonObjs, character); 7143 } 7144 if (font.disableFontFace || patternFill) { 7145 ctx.save(); 7146 ctx.translate(x, y); 7147 ctx.beginPath(); 7148 addToPath(ctx, fontSize); 7149 if (patternTransform) { 7150 ctx.setTransform(...patternTransform); 7151 } 7152 if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7153 ctx.fill(); 7154 } 7155 if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7156 ctx.stroke(); 7157 }
7158 ctx.restore(); 7159 } else { 7160 if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7161 ctx.fillText(character, x, y); 7162 } 7163 if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7164 ctx.strokeText(character, x, y); 7165 } 7166 } 7167 if (isAddToPathSet) { 7168 const paths = this.pendingTextPaths ||= []; 7169 paths.push({ 7170 transform: (0, _display_utils.getCurrentTransform)(ctx), 7171 x, 7172 y, 7173 fontSize, 7174 addToPath 7175 }); 7176 } 7177 } 7178 get isFontSubpixelAAEnabled() { 7179 const { 7180 context: ctx 7181 } = this.cachedCanvases.getCanvas("isFontSubpixelAAEnabled", 10, 10); 7182 ctx.scale(1.5, 1); 7183 ctx.fillText("I", 0, 10); 7184 const data = ctx.getImageData(0, 0, 10, 10).data; 7185 let enabled = false; 7186 for (let i = 3; i < data.length; i += 4) { 7187 if (data[i] > 0 && data[i] < 255) { 7188 enabled = true; 7189 break; 7190 } 7191 } 7192 return (0, _util.shadow)(this, "isFontSubpixelAAEnabled", enabled); 7193 } 7194 showText(glyphs) { 7195 const current = this.current; 7196 const font = current.font; 7197 if (font.isType3Font) { 7198 return this.showType3Text(glyphs); 7199 } 7200 const fontSize = current.fontSize; 7201 if (fontSize === 0) { 7202 return undefined; 7203 } 7204 const ctx = this.ctx; 7205 const fontSizeScale = current.fontSizeScale; 7206 const charSpacing = current.charSpacing; 7207 const wordSpacing = current.wordSpacing; 7208 const fontDirection = current.fontDirection; 7209 const textHScale = current.textHScale * fontDirection; 7210 const glyphsLength = glyphs.length; 7211 const vertical = font.vertical; 7212 const spacingDir = vertical ? 1 : -1; 7213 const defaultVMetrics = font.defaultVMetrics; 7214 const widthAdvanceScale = fontSize * current.fontMatrix[0]; 7215 const simpleFillText = current.textRenderingMode === _util.TextRenderingMode.FILL && !font.disableFontFace && !current.patternFill; 7216 ctx.save(); 7217 ctx.transform(...current.textMatrix); 7218 ctx.translate(current.x, current.y + current.textRise); 7219 if (fontDirection > 0) { 7220 ctx.scale(textHScale, -1); 7221 } else { 7222 ctx.scale(textHScale, 1); 7223 } 7224 let patternTransform; 7225 if (current.patternFill) { 7226 ctx.save(); 7227 const pattern = current.fillColor.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.FILL); 7228 patternTransform = (0, _display_utils.getCurrentTransform)(ctx); 7229 ctx.restore(); 7230 ctx.fillStyle = pattern; 7231 } 7232 let lineWidth = current.lineWidth; 7233 const scale = current.textMatrixScale; 7234 if (scale === 0 || lineWidth === 0) { 7235 const fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; 7236 if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 7237 lineWidth = this.getSinglePixelWidth(); 7238 } 7239 } else { 7240 lineWidth /= scale; 7241 } 7242 if (fontSizeScale !== 1.0) { 7243 ctx.scale(fontSizeScale, fontSizeScale); 7244 lineWidth /= fontSizeScale; 7245 } 7246 ctx.lineWidth = lineWidth; 7247 if (font.isInvalidPDFjsFont) { 7248 const chars = []; 7249 let width = 0; 7250 for (const glyph of glyphs) { 7251 chars.push(glyph.unicode); 7252 width += glyph.width; 7253 } 7254 ctx.fillText(chars.join(""), 0, 0); 7255 current.x += width * widthAdvanceScale * textHScale; 7256 ctx.restore(); 7257 this.compose(); 7258 return undefined; 7259 } 7260 let x = 0, 7261 i; 7262 for (i = 0; i < glyphsLength; ++i) { 7263 const glyph = glyphs[i];
vendor: 3,295 bytes, lines 7264-7348
7264 if (typeof glyph === "number") { 7265 x += spacingDir * glyph * fontSize / 1000; 7266 continue; 7267 } 7268 let restoreNeeded = false; 7269 const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 7270 const character = glyph.fontChar; 7271 const accent = glyph.accent; 7272 let scaledX, scaledY; 7273 let width = glyph.width; 7274 if (vertical) { 7275 const vmetric = glyph.vmetric || defaultVMetrics; 7276 const vx = -(glyph.vmetric ? vmetric[1] : width * 0.5) * widthAdvanceScale; 7277 const vy = vmetric[2] * widthAdvanceScale; 7278 width = vmetric ? -vmetric[0] : width; 7279 scaledX = vx / fontSizeScale; 7280 scaledY = (x + vy) / fontSizeScale; 7281 } else { 7282 scaledX = x / fontSizeScale; 7283 scaledY = 0; 7284 } 7285 if (font.remeasure && width > 0) { 7286 const measuredWidth = ctx.measureText(character).width * 1000 / fontSize * fontSizeScale; 7287 if (width < measuredWidth && this.isFontSubpixelAAEnabled) { 7288 const characterScaleX = width / measuredWidth; 7289 restoreNeeded = true; 7290 ctx.save(); 7291 ctx.scale(characterScaleX, 1); 7292 scaledX /= characterScaleX; 7293 } else if (width !== measuredWidth) { 7294 scaledX += (width - measuredWidth) / 2000 * fontSize / fontSizeScale; 7295 } 7296 } 7297 if (this.contentVisible && (glyph.isInFont || font.missingFile)) { 7298 if (simpleFillText && !accent) { 7299 ctx.fillText(character, scaledX, scaledY); 7300 } else { 7301 this.paintChar(character, scaledX, scaledY, patternTransform); 7302 if (accent) { 7303 const scaledAccentX = scaledX + fontSize * accent.offset.x / fontSizeScale; 7304 const scaledAccentY = scaledY - fontSize * accent.offset.y / fontSizeScale; 7305 this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY, patternTransform); 7306 } 7307 } 7308 } 7309 const charWidth = vertical ? width * widthAdvanceScale - spacing * fontDirection : width * widthAdvanceScale + spacing * fontDirection; 7310 x += charWidth; 7311 if (restoreNeeded) { 7312 ctx.restore(); 7313 } 7314 } 7315 if (vertical) { 7316 current.y -= x; 7317 } else { 7318 current.x += x * textHScale; 7319 } 7320 ctx.restore(); 7321 this.compose(); 7322 return undefined; 7323 } 7324 showType3Text(glyphs) { 7325 const ctx = this.ctx; 7326 const current = this.current; 7327 const font = current.font; 7328 const fontSize = current.fontSize; 7329 const fontDirection = current.fontDirection; 7330 const spacingDir = font.vertical ? 1 : -1; 7331 const charSpacing = current.charSpacing; 7332 const wordSpacing = current.wordSpacing; 7333 const textHScale = current.textHScale * fontDirection; 7334 const fontMatrix = current.fontMatrix || _util.FONT_IDENTITY_MATRIX; 7335 const glyphsLength = glyphs.length; 7336 const isTextInvisible = current.textRenderingMode === _util.TextRenderingMode.INVISIBLE; 7337 let i, glyph, width, spacingLength; 7338 if (isTextInvisible || fontSize === 0) { 7339 return; 7340 } 7341 this._cachedScaleForStroking[0] = -1; 7342 this._cachedGetSinglePixelWidth = null; 7343 ctx.save(); 7344 ctx.transform(...current.textMatrix); 7345 ctx.translate(current.x, current.y); 7346 ctx.scale(textHScale, fontDirection); 7347 for (i = 0; i < glyphsLength; ++i) { 7348 glyph = glyphs[i];
7349 if (typeof glyph === "number") { 7350 spacingLength = spacingDir * glyph * fontSize / 1000; 7351 this.ctx.translate(spacingLength, 0); 7352 current.x += spacingLength * textHScale; 7353 continue; 7354 } 7355 const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 7356 const operatorList = font.charProcOperatorList[glyph.operatorListId]; 7357 if (!operatorList) { 7358 (0, _util.warn)(`Type3 character "${glyph.operatorListId}" is not available.`); 7359 continue; 7360 } 7361 if (this.contentVisible) { 7362 this.processingType3 = glyph; 7363 this.save(); 7364 ctx.scale(fontSize, fontSize); 7365 ctx.transform(...fontMatrix); 7366 this.executeOperatorList(operatorList); 7367 this.restore(); 7368 } 7369 const transformed = _util.Util.applyTransform([glyph.width, 0], fontMatrix); 7370 width = transformed[0] * fontSize + spacing; 7371 ctx.translate(width, 0); 7372 current.x += width * textHScale; 7373 } 7374 ctx.restore(); 7375 this.processingType3 = null; 7376 } 7377 setCharWidth(xWidth, yWidth) {} 7378 setCharWidthAndBounds(xWidth, yWidth, llx, lly, urx, ury) { 7379 this.ctx.rect(llx, lly, urx - llx, ury - lly); 7380 this.ctx.clip(); 7381 this.endPath(); 7382 } 7383 getColorN_Pattern(IR) { 7384 let pattern; 7385 if (IR[0] === "TilingPattern") { 7386 const color = IR[1]; 7387 const baseTransform = this.baseTransform || (0, _display_utils.getCurrentTransform)(this.ctx); 7388 const canvasGraphicsFactory = { 7389 createCanvasGraphics: ctx => { 7390 return new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory, this.filterFactory, { 7391 optionalContentConfig: this.optionalContentConfig, 7392 markedContentStack: this.markedContentStack 7393 }); 7394 } 7395 }; 7396 pattern = new _pattern_helper.TilingPattern(IR, color, this.ctx, canvasGraphicsFactory, baseTransform); 7397 } else { 7398 pattern = this._getPattern(IR[1], IR[2]); 7399 } 7400 return pattern; 7401 } 7402 setStrokeColorN() { 7403 this.current.strokeColor = this.getColorN_Pattern(arguments); 7404 } 7405 setFillColorN() { 7406 this.current.fillColor = this.getColorN_Pattern(arguments); 7407 this.current.patternFill = true; 7408 } 7409 setStrokeRGBColor(r, g, b) { 7410 const color = _util.Util.makeHexColor(r, g, b); 7411 this.ctx.strokeStyle = color; 7412 this.current.strokeColor = color; 7413 } 7414 setFillRGBColor(r, g, b) { 7415 const color = _util.Util.makeHexColor(r, g, b); 7416 this.ctx.fillStyle = color; 7417 this.current.fillColor = color; 7418 this.current.patternFill = false; 7419 } 7420 _getPattern(objId, matrix = null) { 7421 let pattern; 7422 if (this.cachedPatterns.has(objId)) { 7423 pattern = this.cachedPatterns.get(objId); 7424 } else { 7425 pattern = (0, _pattern_helper.getShadingPattern)(this.getObject(objId)); 7426 this.cachedPatterns.set(objId, pattern); 7427 } 7428 if (matrix) { 7429 pattern.matrix = matrix; 7430 } 7431 return pattern; 7432 } 7433 shadingFill(objId) { 7434 if (!this.contentVisible) { 7435 return; 7436 } 7437 const ctx = this.ctx; 7438 this.save(); 7439 const pattern = this._getPattern(objId); 7440 ctx.fillStyle = pattern.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.SHADING); 7441 const inv = (0, _display_utils.getCurrentTransformInverse)(ctx); 7442 if (inv) { 7443 const { 7444 width, 7445 height 7446 } = ctx.canvas; 7447 const [x0, y0, x1, y1] = _util.Util.getAxialAlignedBoundingBox([0, 0, width, height], inv); 7448 this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0); 7449 } else { 7450 this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10); 7451 } 7452 this.compose(this.current.getClippedPathBoundingBox()); 7453 this.restore(); 7454 } 7455 beginInlineImage() { 7456 (0, _util.unreachable)("Should not call beginInlineImage"); 7457 } 7458 beginImageData() { 7459 (0, _util.unreachable)("Should not call beginImageData"); 7460 } 7461 paintFormXObjectBegin(matrix, bbox) { 7462 if (!this.contentVisible) { 7463 return; 7464 } 7465 this.save(); 7466 this.baseTransformStack.push(this.baseTransform); 7467 if (Array.isArray(matrix) && matrix.length === 6) { 7468 this.transform(...matrix); 7469 } 7470 this.baseTransform = (0, _display_utils.getCurrentTransform)(this.ctx); 7471 if (bbox) { 7472 const width = bbox[2] - bbox[0]; 7473 const height = bbox[3] - bbox[1]; 7474 this.ctx.rect(bbox[0], bbox[1], width, height); 7475 this.current.updateRectMinMax((0, _display_utils.getCurrentTransform)(this.ctx), bbox); 7476 this.clip(); 7477 this.endPath(); 7478 } 7479 } 7480 paintFormXObjectEnd() { 7481 if (!this.contentVisible) { 7482 return; 7483 }
7484 this.restore(); 7485 this.baseTransform = this.baseTransformStack.pop(); 7486 } 7487 beginGroup(group) { 7488 if (!this.contentVisible) { 7489 return; 7490 } 7491 this.save(); 7492 if (this.inSMaskMode) { 7493 this.endSMaskMode(); 7494 this.current.activeSMask = null; 7495 } 7496 const currentCtx = this.ctx; 7497 if (!group.isolated) { 7498 (0, _util.info)("TODO: Support non-isolated groups."); 7499 } 7500 if (group.knockout) { 7501 (0, _util.warn)("Knockout groups not supported."); 7502 } 7503 const currentTransform = (0, _display_utils.getCurrentTransform)(currentCtx); 7504 if (group.matrix) { 7505 currentCtx.transform(...group.matrix); 7506 } 7507 if (!group.bbox) { 7508 throw new Error("Bounding box is required."); 7509 } 7510 let bounds = _util.Util.getAxialAlignedBoundingBox(group.bbox, (0, _display_utils.getCurrentTransform)(currentCtx)); 7511 const canvasBounds = [0, 0, currentCtx.canvas.width, currentCtx.canvas.height]; 7512 bounds = _util.Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0]; 7513 const offsetX = Math.floor(bounds[0]); 7514 const offsetY = Math.floor(bounds[1]); 7515 let drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1); 7516 let drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1); 7517 let scaleX = 1, 7518 scaleY = 1; 7519 if (drawnWidth > MAX_GROUP_SIZE) { 7520 scaleX = drawnWidth / MAX_GROUP_SIZE; 7521 drawnWidth = MAX_GROUP_SIZE; 7522 } 7523 if (drawnHeight > MAX_GROUP_SIZE) { 7524 scaleY = drawnHeight / MAX_GROUP_SIZE; 7525 drawnHeight = MAX_GROUP_SIZE; 7526 } 7527 this.current.startNewPathAndClipBox([0, 0, drawnWidth, drawnHeight]); 7528 let cacheId = "groupAt" + this.groupLevel; 7529 if (group.smask) { 7530 cacheId += "_smask_" + this.smaskCounter++ % 2; 7531 } 7532 const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight); 7533 const groupCtx = scratchCanvas.context; 7534 groupCtx.scale(1 / scaleX, 1 / scaleY); 7535 groupCtx.translate(-offsetX, -offsetY); 7536 groupCtx.transform(...currentTransform); 7537 if (group.smask) { 7538 this.smaskStack.push({ 7539 canvas: scratchCanvas.canvas, 7540 context: groupCtx, 7541 offsetX, 7542 offsetY, 7543 scaleX, 7544 scaleY, 7545 subtype: group.smask.subtype, 7546 backdrop: group.smask.backdrop, 7547 transferMap: group.smask.transferMap || null, 7548 startTransformInverse: null 7549 }); 7550 } else { 7551 currentCtx.setTransform(1, 0, 0, 1, 0, 0); 7552 currentCtx.translate(offsetX, offsetY); 7553 currentCtx.scale(scaleX, scaleY); 7554 currentCtx.save(); 7555 } 7556 copyCtxState(currentCtx, groupCtx); 7557 this.ctx = groupCtx; 7558 this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]); 7559 this.groupStack.push(currentCtx); 7560 this.groupLevel++; 7561 } 7562 endGroup(group) { 7563 if (!this.contentVisible) { 7564 return; 7565 } 7566 this.groupLevel--; 7567 const groupCtx = this.ctx; 7568 const ctx = this.groupStack.pop(); 7569 this.ctx = ctx; 7570 this.ctx.imageSmoothingEnabled = false; 7571 if (group.smask) { 7572 this.tempSMask = this.smaskStack.pop(); 7573 this.restore(); 7574 } else { 7575 this.ctx.restore(); 7576 const currentMtx = (0, _display_utils.getCurrentTransform)(this.ctx); 7577 this.restore(); 7578 this.ctx.save(); 7579 this.ctx.setTransform(...currentMtx); 7580 const dirtyBox = _util.Util.getAxialAlignedBoundingBox([0, 0, groupCtx.canvas.width, groupCtx.canvas.height], currentMtx); 7581 this.ctx.drawImage(groupCtx.canvas, 0, 0); 7582 this.ctx.restore(); 7583 this.compose(dirtyBox); 7584 } 7585 } 7586 beginAnnotation(id, rect, transform, matrix, hasOwnCanvas) { 7587 this.#restoreInitialState(); 7588 resetCtxToDefault(this.ctx); 7589 this.ctx.save(); 7590 this.save(); 7591 if (this.baseTransform) { 7592 this.ctx.setTransform(...this.baseTransform); 7593 } 7594 if (Array.isArray(rect) && rect.length === 4) { 7595 const width = rect[2] - rect[0]; 7596 const height = rect[3] - rect[1]; 7597 if (hasOwnCanvas && this.annotationCanvasMap) { 7598 transform = transform.slice(); 7599 transform[4] -= rect[0]; 7600 transform[5] -= rect[1]; 7601 rect = rect.slice(); 7602 rect[0] = rect[1] = 0; 7603 rect[2] = width; 7604 rect[3] = height; 7605 const [scaleX, scaleY] = _util.Util.singularValueDecompose2dScale((0, _display_utils.getCurrentTransform)(this.ctx)); 7606 const { 7607 viewportScale 7608 } = this; 7609 const canvasWidth = Math.ceil(width * this.outputScaleX * viewportScale);
7610 const canvasHeight = Math.ceil(height * this.outputScaleY * viewportScale); 7611 this.annotationCanvas = this.canvasFactory.create(canvasWidth, canvasHeight); 7612 const { 7613 canvas, 7614 context 7615 } = this.annotationCanvas; 7616 this.annotationCanvasMap.set(id, canvas); 7617 this.annotationCanvas.savedCtx = this.ctx; 7618 this.ctx = context; 7619 this.ctx.save(); 7620 this.ctx.setTransform(scaleX, 0, 0, -scaleY, 0, height * scaleY); 7621 resetCtxToDefault(this.ctx); 7622 } else { 7623 resetCtxToDefault(this.ctx); 7624 this.ctx.rect(rect[0], rect[1], width, height); 7625 this.ctx.clip(); 7626 this.endPath(); 7627 } 7628 } 7629 this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height); 7630 this.transform(...transform); 7631 this.transform(...matrix); 7632 } 7633 endAnnotation() { 7634 if (this.annotationCanvas) { 7635 this.ctx.restore(); 7636 this.#drawFilter(); 7637 this.ctx = this.annotationCanvas.savedCtx; 7638 delete this.annotationCanvas.savedCtx; 7639 delete this.annotationCanvas; 7640 } 7641 } 7642 paintImageMaskXObject(img) { 7643 if (!this.contentVisible) { 7644 return; 7645 } 7646 const count = img.count; 7647 img = this.getObject(img.data, img); 7648 img.count = count; 7649 const ctx = this.ctx; 7650 const glyph = this.processingType3; 7651 if (glyph) { 7652 if (glyph.compiled === undefined) { 7653 glyph.compiled = compileType3Glyph(img); 7654 } 7655 if (glyph.compiled) { 7656 glyph.compiled(ctx); 7657 return; 7658 } 7659 } 7660 const mask = this._createMaskCanvas(img); 7661 const maskCanvas = mask.canvas; 7662 ctx.save(); 7663 ctx.setTransform(1, 0, 0, 1, 0, 0); 7664 ctx.drawImage(maskCanvas, mask.offsetX, mask.offsetY); 7665 ctx.restore(); 7666 this.compose(); 7667 } 7668 paintImageMaskXObjectRepeat(img, scaleX, skewX = 0, skewY = 0, scaleY, positions) { 7669 if (!this.contentVisible) { 7670 return; 7671 } 7672 img = this.getObject(img.data, img); 7673 const ctx = this.ctx; 7674 ctx.save(); 7675 const currentTransform = (0, _display_utils.getCurrentTransform)(ctx); 7676 ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0); 7677 const mask = this._createMaskCanvas(img); 7678 ctx.setTransform(1, 0, 0, 1, mask.offsetX - currentTransform[4], mask.offsetY - currentTransform[5]); 7679 for (let i = 0, ii = positions.length; i < ii; i += 2) { 7680 const trans = _util.Util.transform(currentTransform, [scaleX, skewX, skewY, scaleY, positions[i], positions[i + 1]]); 7681 const [x, y] = _util.Util.applyTransform([0, 0], trans); 7682 ctx.drawImage(mask.canvas, x, y); 7683 } 7684 ctx.restore(); 7685 this.compose(); 7686 } 7687 paintImageMaskXObjectGroup(images) { 7688 if (!this.contentVisible) { 7689 return; 7690 } 7691 const ctx = this.ctx; 7692 const fillColor = this.current.fillColor; 7693 const isPatternFill = this.current.patternFill; 7694 for (const image of images) { 7695 const { 7696 data, 7697 width, 7698 height, 7699 transform 7700 } = image; 7701 const maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height); 7702 const maskCtx = maskCanvas.context; 7703 maskCtx.save(); 7704 const img = this.getObject(data, image); 7705 putBinaryImageMask(maskCtx, img); 7706 maskCtx.globalCompositeOperation = "source-in"; 7707 maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.FILL) : fillColor; 7708 maskCtx.fillRect(0, 0, width, height); 7709 maskCtx.restore(); 7710 ctx.save(); 7711 ctx.transform(...transform); 7712 ctx.scale(1, -1); 7713 drawImageAtIntegerCoords(ctx, maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1); 7714 ctx.restore(); 7715 } 7716 this.compose(); 7717 } 7718 paintImageXObject(objId) { 7719 if (!this.contentVisible) { 7720 return; 7721 } 7722 const imgData = this.getObject(objId); 7723 if (!imgData) { 7724 (0, _util.warn)("Dependent image isn't ready yet"); 7725 return; 7726 } 7727 this.paintInlineImageXObject(imgData); 7728 } 7729 paintImageXObjectRepeat(objId, scaleX, scaleY, positions) { 7730 if (!this.contentVisible) { 7731 return; 7732 } 7733 const imgData = this.getObject(objId); 7734 if (!imgData) { 7735 (0, _util.warn)("Dependent image isn't ready yet"); 7736 return; 7737 } 7738 const width = imgData.width; 7739 const height = imgData.height; 7740 const map = []; 7741 for (let i = 0, ii = positions.length; i < ii; i += 2) { 7742 map.push({ 7743 transform: [scaleX, 0, 0, scaleY, positions[i], positions[i + 1]], 7744 x: 0, 7745 y: 0, 7746 w: width, 7747 h: height 7748 }); 7749 } 7750 this.paintInlineImageXObjectGroup(imgData, map); 7751 } 7752 applyTransferMapsToCanvas(ctx) { 7753 if (this.current.transferMaps !== "none") { 7754 ctx.filter = this.current.transferMaps; 7755 ctx.drawImage(ctx.canvas, 0, 0); 7756 ctx.filter = "none"; 7757 } 7758 return ctx.canvas; 7759 } 7760 applyTransferMapsToBitmap(imgData) { 7761 if (this.current.transferMaps === "none") { 7762 return imgData.bitmap; 7763 } 7764 const { 7765 bitmap, 7766 width, 7767 height 7768 } = imgData; 7769 const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", width, height); 7770 const tmpCtx = tmpCanvas.context; 7771 tmpCtx.filter = this.current.transferMaps; 7772 tmpCtx.drawImage(bitmap, 0, 0); 7773 tmpCtx.filter = "none"; 7774 return tmpCanvas.canvas; 7775 } 7776 paintInlineImageXObject(imgData) { 7777 if (!this.contentVisible) { 7778 return; 7779 } 7780 const width = imgData.width; 7781 const height = imgData.height; 7782 const ctx = this.ctx; 7783 this.save(); 7784 if (!_util.isNodeJS) { 7785 const { 7786 filter 7787 } = ctx; 7788 if (filter !== "none" && filter !== "") { 7789 ctx.filter = "none"; 7790 } 7791 } 7792 ctx.scale(1 / width, -1 / height); 7793 let imgToPaint; 7794 if (imgData.bitmap) { 7795 imgToPaint = this.applyTransferMapsToBitmap(imgData); 7796 } else if (typeof HTMLElement === "function" && imgData instanceof HTMLElement || !imgData.data) { 7797 imgToPaint = imgData; 7798 } else { 7799 const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", width, height); 7800 const tmpCtx = tmpCanvas.context; 7801 putBinaryImageData(tmpCtx, imgData); 7802 imgToPaint = this.applyTransferMapsToCanvas(tmpCtx); 7803 } 7804 const scaled = this._scaleImage(imgToPaint, (0, _display_utils.getCurrentTransformInverse)(ctx)); 7805 ctx.imageSmoothingEnabled = getImageSmoothingEnabled((0, _display_utils.getCurrentTransform)(ctx), imgData.interpolate); 7806 drawImageAtIntegerCoords(ctx, scaled.img, 0, 0, scaled.paintWidth, scaled.paintHeight, 0, -height, width, height); 7807 this.compose();
vendor: 4,375 bytes, lines 7808-7958
7808 this.restore(); 7809 } 7810 paintInlineImageXObjectGroup(imgData, map) { 7811 if (!this.contentVisible) { 7812 return; 7813 } 7814 const ctx = this.ctx; 7815 let imgToPaint; 7816 if (imgData.bitmap) { 7817 imgToPaint = imgData.bitmap; 7818 } else { 7819 const w = imgData.width; 7820 const h = imgData.height; 7821 const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", w, h); 7822 const tmpCtx = tmpCanvas.context; 7823 putBinaryImageData(tmpCtx, imgData); 7824 imgToPaint = this.applyTransferMapsToCanvas(tmpCtx); 7825 } 7826 for (const entry of map) { 7827 ctx.save(); 7828 ctx.transform(...entry.transform); 7829 ctx.scale(1, -1); 7830 drawImageAtIntegerCoords(ctx, imgToPaint, entry.x, entry.y, entry.w, entry.h, 0, -1, 1, 1); 7831 ctx.restore(); 7832 } 7833 this.compose(); 7834 } 7835 paintSolidColorImageMask() { 7836 if (!this.contentVisible) { 7837 return; 7838 } 7839 this.ctx.fillRect(0, 0, 1, 1); 7840 this.compose(); 7841 } 7842 markPoint(tag) {} 7843 markPointProps(tag, properties) {} 7844 beginMarkedContent(tag) { 7845 this.markedContentStack.push({ 7846 visible: true 7847 }); 7848 } 7849 beginMarkedContentProps(tag, properties) { 7850 if (tag === "OC") { 7851 this.markedContentStack.push({ 7852 visible: this.optionalContentConfig.isVisible(properties) 7853 }); 7854 } else { 7855 this.markedContentStack.push({ 7856 visible: true 7857 }); 7858 } 7859 this.contentVisible = this.isContentVisible(); 7860 } 7861 endMarkedContent() { 7862 this.markedContentStack.pop(); 7863 this.contentVisible = this.isContentVisible(); 7864 } 7865 beginCompat() {} 7866 endCompat() {} 7867 consumePath(clipBox) { 7868 const isEmpty = this.current.isEmptyClip(); 7869 if (this.pendingClip) { 7870 this.current.updateClipFromPath(); 7871 } 7872 if (!this.pendingClip) { 7873 this.compose(clipBox); 7874 } 7875 const ctx = this.ctx; 7876 if (this.pendingClip) { 7877 if (!isEmpty) { 7878 if (this.pendingClip === EO_CLIP) { 7879 ctx.clip("evenodd"); 7880 } else { 7881 ctx.clip(); 7882 } 7883 } 7884 this.pendingClip = null; 7885 } 7886 this.current.startNewPathAndClipBox(this.current.clipBox); 7887 ctx.beginPath(); 7888 } 7889 getSinglePixelWidth() { 7890 if (!this._cachedGetSinglePixelWidth) { 7891 const m = (0, _display_utils.getCurrentTransform)(this.ctx); 7892 if (m[1] === 0 && m[2] === 0) { 7893 this._cachedGetSinglePixelWidth = 1 / Math.min(Math.abs(m[0]), Math.abs(m[3])); 7894 } else { 7895 const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]); 7896 const normX = Math.hypot(m[0], m[2]); 7897 const normY = Math.hypot(m[1], m[3]); 7898 this._cachedGetSinglePixelWidth = Math.max(normX, normY) / absDet; 7899 } 7900 } 7901 return this._cachedGetSinglePixelWidth; 7902 } 7903 getScaleForStroking() { 7904 if (this._cachedScaleForStroking[0] === -1) { 7905 const { 7906 lineWidth 7907 } = this.current; 7908 const { 7909 a, 7910 b, 7911 c, 7912 d 7913 } = this.ctx.getTransform(); 7914 let scaleX, scaleY; 7915 if (b === 0 && c === 0) { 7916 const normX = Math.abs(a); 7917 const normY = Math.abs(d); 7918 if (normX === normY) { 7919 if (lineWidth === 0) { 7920 scaleX = scaleY = 1 / normX; 7921 } else { 7922 const scaledLineWidth = normX * lineWidth; 7923 scaleX = scaleY = scaledLineWidth < 1 ? 1 / scaledLineWidth : 1; 7924 } 7925 } else if (lineWidth === 0) { 7926 scaleX = 1 / normX; 7927 scaleY = 1 / normY; 7928 } else { 7929 const scaledXLineWidth = normX * lineWidth; 7930 const scaledYLineWidth = normY * lineWidth; 7931 scaleX = scaledXLineWidth < 1 ? 1 / scaledXLineWidth : 1; 7932 scaleY = scaledYLineWidth < 1 ? 1 / scaledYLineWidth : 1; 7933 } 7934 } else { 7935 const absDet = Math.abs(a * d - b * c); 7936 const normX = Math.hypot(a, b); 7937 const normY = Math.hypot(c, d); 7938 if (lineWidth === 0) { 7939 scaleX = normY / absDet; 7940 scaleY = normX / absDet; 7941 } else { 7942 const baseArea = lineWidth * absDet; 7943 scaleX = normY > baseArea ? normY / baseArea : 1; 7944 scaleY = normX > baseArea ? normX / baseArea : 1; 7945 } 7946 } 7947 this._cachedScaleForStroking[0] = scaleX; 7948 this._cachedScaleForStroking[1] = scaleY; 7949 } 7950 return this._cachedScaleForStroking; 7951 } 7952 rescaleAndStroke(saveRestore) { 7953 const { 7954 ctx 7955 } = this; 7956 const { 7957 lineWidth 7958 } = this.current;
7959 const [scaleX, scaleY] = this.getScaleForStroking(); 7960 ctx.lineWidth = lineWidth || 1; 7961 if (scaleX === 1 && scaleY === 1) { 7962 ctx.stroke(); 7963 return; 7964 } 7965 const dashes = ctx.getLineDash(); 7966 if (saveRestore) { 7967 ctx.save(); 7968 } 7969 ctx.scale(scaleX, scaleY); 7970 if (dashes.length > 0) { 7971 const scale = Math.max(scaleX, scaleY); 7972 ctx.setLineDash(dashes.map(x => x / scale)); 7973 ctx.lineDashOffset /= scale; 7974 } 7975 ctx.stroke(); 7976 if (saveRestore) { 7977 ctx.restore(); 7978 } 7979 } 7980 isContentVisible() { 7981 for (let i = this.markedContentStack.length - 1; i >= 0; i--) { 7982 if (!this.markedContentStack[i].visible) { 7983 return false; 7984 } 7985 } 7986 return true; 7987 } 7988} 7989exports.CanvasGraphics = CanvasGraphics; 7990for (const op in _util.OPS) { 7991 if (CanvasGraphics.prototype[op] !== undefined) { 7992 CanvasGraphics.prototype[_util.OPS[op]] = CanvasGraphics.prototype[op]; 7993 } 7994} 7995 7996/***/ }), 7997/* 12 */ 7998/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 7999 8000 8001 8002Object.defineProperty(exports, "__esModule", ({ 8003 value: true 8004})); 8005exports.TilingPattern = exports.PathType = void 0; 8006exports.getShadingPattern = getShadingPattern; 8007var _util = __w_pdfjs_require__(1); 8008var _display_utils = __w_pdfjs_require__(6); 8009const PathType = { 8010 FILL: "Fill", 8011 STROKE: "Stroke", 8012 SHADING: "Shading" 8013}; 8014exports.PathType = PathType; 8015function applyBoundingBox(ctx, bbox) { 8016 if (!bbox) { 8017 return; 8018 } 8019 const width = bbox[2] - bbox[0]; 8020 const height = bbox[3] - bbox[1]; 8021 const region = new Path2D(); 8022 region.rect(bbox[0], bbox[1], width, height); 8023 ctx.clip(region); 8024} 8025class BaseShadingPattern { 8026 constructor() { 8027 if (this.constructor === BaseShadingPattern) { 8028 (0, _util.unreachable)("Cannot initialize BaseShadingPattern."); 8029 } 8030 } 8031 getPattern() { 8032 (0, _util.unreachable)("Abstract method `getPattern` called."); 8033 } 8034} 8035class RadialAxialShadingPattern extends BaseShadingPattern { 8036 constructor(IR) { 8037 super(); 8038 this._type = IR[1]; 8039 this._bbox = IR[2]; 8040 this._colorStops = IR[3]; 8041 this._p0 = IR[4]; 8042 this._p1 = IR[5]; 8043 this._r0 = IR[6]; 8044 this._r1 = IR[7]; 8045 this.matrix = null; 8046 } 8047 _createGradient(ctx) { 8048 let grad; 8049 if (this._type === "axial") { 8050 grad = ctx.createLinearGradient(this._p0[0], this._p0[1], this._p1[0], this._p1[1]); 8051 } else if (this._type === "radial") { 8052 grad = ctx.createRadialGradient(this._p0[0], this._p0[1], this._r0, this._p1[0], this._p1[1], this._r1); 8053 } 8054 for (const colorStop of this._colorStops) { 8055 grad.addColorStop(colorStop[0], colorStop[1]); 8056 } 8057 return grad; 8058 } 8059 getPattern(ctx, owner, inverse, pathType) { 8060 let pattern; 8061 if (pathType === PathType.STROKE || pathType === PathType.FILL) { 8062 const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, (0, _display_utils.getCurrentTransform)(ctx)) || [0, 0, 0, 0]; 8063 const width = Math.ceil(ownerBBox[2] - ownerBBox[0]) || 1; 8064 const height = Math.ceil(ownerBBox[3] - ownerBBox[1]) || 1; 8065 const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", width, height, true); 8066 const tmpCtx = tmpCanvas.context; 8067 tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); 8068 tmpCtx.beginPath(); 8069 tmpCtx.rect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); 8070 tmpCtx.translate(-ownerBBox[0], -ownerBBox[1]); 8071 inverse = _util.Util.transform(inverse, [1, 0, 0, 1, ownerBBox[0], ownerBBox[1]]); 8072 tmpCtx.transform(...owner.baseTransform); 8073 if (this.matrix) { 8074 tmpCtx.transform(...this.matrix); 8075 } 8076 applyBoundingBox(tmpCtx, this._bbox); 8077 tmpCtx.fillStyle = this._createGradient(tmpCtx); 8078 tmpCtx.fill(); 8079 pattern = ctx.createPattern(tmpCanvas.canvas, "no-repeat"); 8080 const domMatrix = new DOMMatrix(inverse); 8081 pattern.setTransform(domMatrix); 8082 } else { 8083 applyBoundingBox(ctx, this._bbox); 8084 pattern = this._createGradient(ctx); 8085 } 8086 return pattern; 8087 } 8088} 8089function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) { 8090 const coords = context.coords, 8091 colors = context.colors; 8092 const bytes = data.data, 8093 rowSize = data.width * 4; 8094 let tmp; 8095 if (coords[p1 + 1] > coords[p2 + 1]) { 8096 tmp = p1; 8097 p1 = p2; 8098 p2 = tmp; 8099 tmp = c1; 8100 c1 = c2; 8101 c2 = tmp; 8102 } 8103 if (coords[p2 + 1] > coords[p3 + 1]) { 8104 tmp = p2; 8105 p2 = p3; 8106 p3 = tmp; 8107 tmp = c2; 8108 c2 = c3; 8109 c3 = tmp; 8110 } 8111 if (coords[p1 + 1] > coords[p2 + 1]) { 8112 tmp = p1; 8113 p1 = p2; 8114 p2 = tmp; 8115 tmp = c1; 8116 c1 = c2; 8117 c2 = tmp; 8118 } 8119 const x1 = (coords[p1] + context.offsetX) * context.scaleX; 8120 const y1 = (coords[p1 + 1] + context.offsetY) * context.scaleY; 8121 const x2 = (coords[p2] + context.offsetX) * context.scaleX; 8122 const y2 = (coords[p2 + 1] + context.offsetY) * context.scaleY; 8123 const x3 = (coords[p3] + context.offsetX) * context.scaleX; 8124 const y3 = (coords[p3 + 1] + context.offsetY) * context.scaleY; 8125 if (y1 >= y3) { 8126 return; 8127 } 8128 const c1r = colors[c1], 8129 c1g = colors[c1 + 1], 8130 c1b = colors[c1 + 2]; 8131 const c2r = colors[c2], 8132 c2g = colors[c2 + 1], 8133 c2b = colors[c2 + 2]; 8134 const c3r = colors[c3], 8135 c3g = colors[c3 + 1], 8136 c3b = colors[c3 + 2]; 8137 const minY = Math.round(y1), 8138 maxY = Math.round(y3); 8139 let xa, car, cag, cab; 8140 let xb, cbr, cbg, cbb; 8141 for (let y = minY; y <= maxY; y++) { 8142 if (y < y2) {
vendor: 4,267 bytes, lines 8143-8272
8143 const k = y < y1 ? 0 : (y1 - y) / (y1 - y2); 8144 xa = x1 - (x1 - x2) * k; 8145 car = c1r - (c1r - c2r) * k; 8146 cag = c1g - (c1g - c2g) * k; 8147 cab = c1b - (c1b - c2b) * k; 8148 } else { 8149 let k; 8150 if (y > y3) { 8151 k = 1; 8152 } else if (y2 === y3) { 8153 k = 0; 8154 } else { 8155 k = (y2 - y) / (y2 - y3); 8156 } 8157 xa = x2 - (x2 - x3) * k; 8158 car = c2r - (c2r - c3r) * k; 8159 cag = c2g - (c2g - c3g) * k; 8160 cab = c2b - (c2b - c3b) * k; 8161 } 8162 let k; 8163 if (y < y1) { 8164 k = 0; 8165 } else if (y > y3) { 8166 k = 1; 8167 } else { 8168 k = (y1 - y) / (y1 - y3); 8169 } 8170 xb = x1 - (x1 - x3) * k; 8171 cbr = c1r - (c1r - c3r) * k; 8172 cbg = c1g - (c1g - c3g) * k; 8173 cbb = c1b - (c1b - c3b) * k; 8174 const x1_ = Math.round(Math.min(xa, xb)); 8175 const x2_ = Math.round(Math.max(xa, xb)); 8176 let j = rowSize * y + x1_ * 4; 8177 for (let x = x1_; x <= x2_; x++) { 8178 k = (xa - x) / (xa - xb); 8179 if (k < 0) { 8180 k = 0; 8181 } else if (k > 1) { 8182 k = 1; 8183 } 8184 bytes[j++] = car - (car - cbr) * k | 0; 8185 bytes[j++] = cag - (cag - cbg) * k | 0; 8186 bytes[j++] = cab - (cab - cbb) * k | 0; 8187 bytes[j++] = 255; 8188 } 8189 } 8190} 8191function drawFigure(data, figure, context) { 8192 const ps = figure.coords; 8193 const cs = figure.colors; 8194 let i, ii; 8195 switch (figure.type) { 8196 case "lattice": 8197 const verticesPerRow = figure.verticesPerRow; 8198 const rows = Math.floor(ps.length / verticesPerRow) - 1; 8199 const cols = verticesPerRow - 1; 8200 for (i = 0; i < rows; i++) { 8201 let q = i * verticesPerRow; 8202 for (let j = 0; j < cols; j++, q++) { 8203 drawTriangle(data, context, ps[q], ps[q + 1], ps[q + verticesPerRow], cs[q], cs[q + 1], cs[q + verticesPerRow]); 8204 drawTriangle(data, context, ps[q + verticesPerRow + 1], ps[q + 1], ps[q + verticesPerRow], cs[q + verticesPerRow + 1], cs[q + 1], cs[q + verticesPerRow]); 8205 } 8206 } 8207 break; 8208 case "triangles": 8209 for (i = 0, ii = ps.length; i < ii; i += 3) { 8210 drawTriangle(data, context, ps[i], ps[i + 1], ps[i + 2], cs[i], cs[i + 1], cs[i + 2]); 8211 } 8212 break; 8213 default: 8214 throw new Error("illegal figure"); 8215 } 8216} 8217class MeshShadingPattern extends BaseShadingPattern { 8218 constructor(IR) { 8219 super(); 8220 this._coords = IR[2]; 8221 this._colors = IR[3]; 8222 this._figures = IR[4]; 8223 this._bounds = IR[5]; 8224 this._bbox = IR[7]; 8225 this._background = IR[8]; 8226 this.matrix = null; 8227 } 8228 _createMeshCanvas(combinedScale, backgroundColor, cachedCanvases) { 8229 const EXPECTED_SCALE = 1.1; 8230 const MAX_PATTERN_SIZE = 3000; 8231 const BORDER_SIZE = 2; 8232 const offsetX = Math.floor(this._bounds[0]); 8233 const offsetY = Math.floor(this._bounds[1]); 8234 const boundsWidth = Math.ceil(this._bounds[2]) - offsetX; 8235 const boundsHeight = Math.ceil(this._bounds[3]) - offsetY; 8236 const width = Math.min(Math.ceil(Math.abs(boundsWidth * combinedScale[0] * EXPECTED_SCALE)), MAX_PATTERN_SIZE); 8237 const height = Math.min(Math.ceil(Math.abs(boundsHeight * combinedScale[1] * EXPECTED_SCALE)), MAX_PATTERN_SIZE); 8238 const scaleX = boundsWidth / width; 8239 const scaleY = boundsHeight / height; 8240 const context = { 8241 coords: this._coords, 8242 colors: this._colors, 8243 offsetX: -offsetX, 8244 offsetY: -offsetY, 8245 scaleX: 1 / scaleX, 8246 scaleY: 1 / scaleY 8247 }; 8248 const paddedWidth = width + BORDER_SIZE * 2; 8249 const paddedHeight = height + BORDER_SIZE * 2; 8250 const tmpCanvas = cachedCanvases.getCanvas("mesh", paddedWidth, paddedHeight, false); 8251 const tmpCtx = tmpCanvas.context; 8252 const data = tmpCtx.createImageData(width, height); 8253 if (backgroundColor) { 8254 const bytes = data.data; 8255 for (let i = 0, ii = bytes.length; i < ii; i += 4) { 8256 bytes[i] = backgroundColor[0]; 8257 bytes[i + 1] = backgroundColor[1]; 8258 bytes[i + 2] = backgroundColor[2]; 8259 bytes[i + 3] = 255; 8260 } 8261 } 8262 for (const figure of this._figures) { 8263 drawFigure(data, figure, context); 8264 } 8265 tmpCtx.putImageData(data, BORDER_SIZE, BORDER_SIZE); 8266 const canvas = tmpCanvas.canvas; 8267 return { 8268 canvas, 8269 offsetX: offsetX - BORDER_SIZE * scaleX, 8270 offsetY: offsetY - BORDER_SIZE * scaleY, 8271 scaleX, 8272 scaleY
8273 }; 8274 } 8275 getPattern(ctx, owner, inverse, pathType) { 8276 applyBoundingBox(ctx, this._bbox); 8277 let scale; 8278 if (pathType === PathType.SHADING) { 8279 scale = _util.Util.singularValueDecompose2dScale((0, _display_utils.getCurrentTransform)(ctx)); 8280 } else { 8281 scale = _util.Util.singularValueDecompose2dScale(owner.baseTransform); 8282 if (this.matrix) { 8283 const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix); 8284 scale = [scale[0] * matrixScale[0], scale[1] * matrixScale[1]]; 8285 } 8286 } 8287 const temporaryPatternCanvas = this._createMeshCanvas(scale, pathType === PathType.SHADING ? null : this._background, owner.cachedCanvases); 8288 if (pathType !== PathType.SHADING) { 8289 ctx.setTransform(...owner.baseTransform); 8290 if (this.matrix) { 8291 ctx.transform(...this.matrix); 8292 } 8293 } 8294 ctx.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY); 8295 ctx.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY); 8296 return ctx.createPattern(temporaryPatternCanvas.canvas, "no-repeat"); 8297 } 8298} 8299class DummyShadingPattern extends BaseShadingPattern { 8300 getPattern() { 8301 return "hotpink"; 8302 } 8303} 8304function getShadingPattern(IR) { 8305 switch (IR[0]) { 8306 case "RadialAxial": 8307 return new RadialAxialShadingPattern(IR); 8308 case "Mesh": 8309 return new MeshShadingPattern(IR); 8310 case "Dummy": 8311 return new DummyShadingPattern(); 8312 } 8313 throw new Error(`Unknown IR type: ${IR[0]}`); 8314} 8315const PaintType = { 8316 COLORED: 1, 8317 UNCOLORED: 2 8318}; 8319class TilingPattern { 8320 static MAX_PATTERN_SIZE = 3000; 8321 constructor(IR, color, ctx, canvasGraphicsFactory, baseTransform) { 8322 this.operatorList = IR[2]; 8323 this.matrix = IR[3] || [1, 0, 0, 1, 0, 0]; 8324 this.bbox = IR[4]; 8325 this.xstep = IR[5]; 8326 this.ystep = IR[6]; 8327 this.paintType = IR[7]; 8328 this.tilingType = IR[8]; 8329 this.color = color; 8330 this.ctx = ctx; 8331 this.canvasGraphicsFactory = canvasGraphicsFactory; 8332 this.baseTransform = baseTransform; 8333 } 8334 createPatternCanvas(owner) { 8335 const operatorList = this.operatorList; 8336 const bbox = this.bbox; 8337 const xstep = this.xstep; 8338 const ystep = this.ystep; 8339 const paintType = this.paintType; 8340 const tilingType = this.tilingType; 8341 const color = this.color; 8342 const canvasGraphicsFactory = this.canvasGraphicsFactory; 8343 (0, _util.info)("TilingType: " + tilingType); 8344 const x0 = bbox[0], 8345 y0 = bbox[1], 8346 x1 = bbox[2], 8347 y1 = bbox[3]; 8348 const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix); 8349 const curMatrixScale = _util.Util.singularValueDecompose2dScale(this.baseTransform); 8350 const combinedScale = [matrixScale[0] * curMatrixScale[0], matrixScale[1] * curMatrixScale[1]]; 8351 const dimx = this.getSizeAndScale(xstep, this.ctx.canvas.width, combinedScale[0]); 8352 const dimy = this.getSizeAndScale(ystep, this.ctx.canvas.height, combinedScale[1]); 8353 const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", dimx.size, dimy.size, true); 8354 const tmpCtx = tmpCanvas.context; 8355 const graphics = canvasGraphicsFactory.createCanvasGraphics(tmpCtx); 8356 graphics.groupLevel = owner.groupLevel; 8357 this.setFillAndStrokeStyleToContext(graphics, paintType, color); 8358 let adjustedX0 = x0; 8359 let adjustedY0 = y0; 8360 let adjustedX1 = x1; 8361 let adjustedY1 = y1; 8362 if (x0 < 0) { 8363 adjustedX0 = 0; 8364 adjustedX1 += Math.abs(x0); 8365 } 8366 if (y0 < 0) { 8367 adjustedY0 = 0; 8368 adjustedY1 += Math.abs(y0); 8369 } 8370 tmpCtx.translate(-(dimx.scale * adjustedX0), -(dimy.scale * adjustedY0)); 8371 graphics.transform(dimx.scale, 0, 0, dimy.scale, 0, 0); 8372 tmpCtx.save(); 8373 this.clipBbox(graphics, adjustedX0, adjustedY0, adjustedX1, adjustedY1); 8374 graphics.baseTransform = (0, _display_utils.getCurrentTransform)(graphics.ctx); 8375 graphics.executeOperatorList(operatorList); 8376 graphics.endDrawing(); 8377 return { 8378 canvas: tmpCanvas.canvas, 8379 scaleX: dimx.scale, 8380 scaleY: dimy.scale, 8381 offsetX: adjustedX0, 8382 offsetY: adjustedY0 8383 }; 8384 } 8385 getSizeAndScale(step, realOutputSize, scale) { 8386 step = Math.abs(step); 8387 const maxSize = Math.max(TilingPattern.MAX_PATTERN_SIZE, realOutputSize);
8388 let size = Math.ceil(step * scale); 8389 if (size >= maxSize) { 8390 size = maxSize; 8391 } else { 8392 scale = size / step; 8393 } 8394 return { 8395 scale, 8396 size 8397 }; 8398 } 8399 clipBbox(graphics, x0, y0, x1, y1) { 8400 const bboxWidth = x1 - x0; 8401 const bboxHeight = y1 - y0; 8402 graphics.ctx.rect(x0, y0, bboxWidth, bboxHeight); 8403 graphics.current.updateRectMinMax((0, _display_utils.getCurrentTransform)(graphics.ctx), [x0, y0, x1, y1]); 8404 graphics.clip(); 8405 graphics.endPath(); 8406 } 8407 setFillAndStrokeStyleToContext(graphics, paintType, color) { 8408 const context = graphics.ctx, 8409 current = graphics.current; 8410 switch (paintType) { 8411 case PaintType.COLORED: 8412 const ctx = this.ctx; 8413 context.fillStyle = ctx.fillStyle; 8414 context.strokeStyle = ctx.strokeStyle; 8415 current.fillColor = ctx.fillStyle; 8416 current.strokeColor = ctx.strokeStyle; 8417 break; 8418 case PaintType.UNCOLORED: 8419 const cssColor = _util.Util.makeHexColor(color[0], color[1], color[2]); 8420 context.fillStyle = cssColor; 8421 context.strokeStyle = cssColor; 8422 current.fillColor = cssColor; 8423 current.strokeColor = cssColor; 8424 break; 8425 default: 8426 throw new _util.FormatError(`Unsupported paint type: ${paintType}`); 8427 } 8428 } 8429 getPattern(ctx, owner, inverse, pathType) { 8430 let matrix = inverse; 8431 if (pathType !== PathType.SHADING) { 8432 matrix = _util.Util.transform(matrix, owner.baseTransform); 8433 if (this.matrix) { 8434 matrix = _util.Util.transform(matrix, this.matrix); 8435 } 8436 } 8437 const temporaryPatternCanvas = this.createPatternCanvas(owner); 8438 let domMatrix = new DOMMatrix(matrix); 8439 domMatrix = domMatrix.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY); 8440 domMatrix = domMatrix.scale(1 / temporaryPatternCanvas.scaleX, 1 / temporaryPatternCanvas.scaleY); 8441 const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "repeat"); 8442 pattern.setTransform(domMatrix); 8443 return pattern; 8444 } 8445} 8446exports.TilingPattern = TilingPattern; 8447 8448/***/ }), 8449/* 13 */ 8450/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 8451 8452 8453 8454Object.defineProperty(exports, "__esModule", ({ 8455 value: true 8456})); 8457exports.convertBlackAndWhiteToRGBA = convertBlackAndWhiteToRGBA; 8458exports.convertToRGBA = convertToRGBA; 8459exports.grayToRGBA = grayToRGBA; 8460var _util = __w_pdfjs_require__(1); 8461function convertToRGBA(params) { 8462 switch (params.kind) { 8463 case _util.ImageKind.GRAYSCALE_1BPP: 8464 return convertBlackAndWhiteToRGBA(params); 8465 case _util.ImageKind.RGB_24BPP: 8466 return convertRGBToRGBA(params); 8467 } 8468 return null; 8469} 8470function convertBlackAndWhiteToRGBA({ 8471 src, 8472 srcPos = 0, 8473 dest, 8474 width, 8475 height, 8476 nonBlackColor = 0xffffffff, 8477 inverseDecode = false 8478}) { 8479 const black = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; 8480 const [zeroMapping, oneMapping] = inverseDecode ? [nonBlackColor, black] : [black, nonBlackColor]; 8481 const widthInSource = width >> 3; 8482 const widthRemainder = width & 7; 8483 const srcLength = src.length; 8484 dest = new Uint32Array(dest.buffer); 8485 let destPos = 0; 8486 for (let i = 0; i < height; i++) { 8487 for (const max = srcPos + widthInSource; srcPos < max; srcPos++) { 8488 const elem = srcPos < srcLength ? src[srcPos] : 255; 8489 dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping; 8490 dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping; 8491 dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping; 8492 dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping; 8493 dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping; 8494 dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping; 8495 dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping; 8496 dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping; 8497 } 8498 if (widthRemainder === 0) { 8499 continue; 8500 } 8501 const elem = srcPos < srcLength ? src[srcPos++] : 255; 8502 for (let j = 0; j < widthRemainder; j++) { 8503 dest[destPos++] = elem & 1 << 7 - j ? oneMapping : zeroMapping; 8504 } 8505 } 8506 return { 8507 srcPos, 8508 destPos 8509 }; 8510} 8511function convertRGBToRGBA({ 8512 src, 8513 srcPos = 0, 8514 dest, 8515 destPos = 0, 8516 width, 8517 height 8518}) { 8519 let i = 0; 8520 const len32 = src.length >> 2; 8521 const src32 = new Uint32Array(src.buffer, srcPos, len32); 8522 if (_util.FeatureTest.isLittleEndian) { 8523 for (; i < len32 - 2; i += 3, destPos += 4) { 8524 const s1 = src32[i]; 8525 const s2 = src32[i + 1]; 8526 const s3 = src32[i + 2]; 8527 dest[destPos] = s1 | 0xff000000; 8528 dest[destPos + 1] = s1 >>> 24 | s2 << 8 | 0xff000000; 8529 dest[destPos + 2] = s2 >>> 16 | s3 << 16 | 0xff000000; 8530 dest[destPos + 3] = s3 >>> 8 | 0xff000000; 8531 } 8532 for (let j = i * 4, jj = src.length; j < jj; j += 3) { 8533 dest[destPos++] = src[j] | src[j + 1] << 8 | src[j + 2] << 16 | 0xff000000; 8534 } 8535 } else { 8536 for (; i < len32 - 2; i += 3, destPos += 4) { 8537 const s1 = src32[i]; 8538 const s2 = src32[i + 1]; 8539 const s3 = src32[i + 2]; 8540 dest[destPos] = s1 | 0xff;
8541 dest[destPos + 1] = s1 << 24 | s2 >>> 8 | 0xff; 8542 dest[destPos + 2] = s2 << 16 | s3 >>> 16 | 0xff; 8543 dest[destPos + 3] = s3 << 8 | 0xff; 8544 } 8545 for (let j = i * 4, jj = src.length; j < jj; j += 3) { 8546 dest[destPos++] = src[j] << 24 | src[j + 1] << 16 | src[j + 2] << 8 | 0xff; 8547 } 8548 } 8549 return { 8550 srcPos, 8551 destPos 8552 }; 8553} 8554function grayToRGBA(src, dest) { 8555 if (_util.FeatureTest.isLittleEndian) { 8556 for (let i = 0, ii = src.length; i < ii; i++) { 8557 dest[i] = src[i] * 0x10101 | 0xff000000; 8558 } 8559 } else { 8560 for (let i = 0, ii = src.length; i < ii; i++) { 8561 dest[i] = src[i] * 0x1010100 | 0x000000ff; 8562 } 8563 } 8564} 8565 8566/***/ }), 8567/* 14 */ 8568/***/ ((__unused_webpack_module, exports) => { 8569 8570 8571 8572Object.defineProperty(exports, "__esModule", ({ 8573 value: true 8574})); 8575exports.GlobalWorkerOptions = void 0; 8576const GlobalWorkerOptions = Object.create(null); 8577exports.GlobalWorkerOptions = GlobalWorkerOptions; 8578GlobalWorkerOptions.workerPort = null; 8579GlobalWorkerOptions.workerSrc = ""; 8580 8581/***/ }), 8582/* 15 */ 8583/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 8584 8585 8586 8587Object.defineProperty(exports, "__esModule", ({ 8588 value: true 8589})); 8590exports.MessageHandler = void 0; 8591var _util = __w_pdfjs_require__(1); 8592const CallbackKind = { 8593 UNKNOWN: 0, 8594 DATA: 1, 8595 ERROR: 2 8596}; 8597const StreamKind = { 8598 UNKNOWN: 0, 8599 CANCEL: 1, 8600 CANCEL_COMPLETE: 2, 8601 CLOSE: 3, 8602 ENQUEUE: 4, 8603 ERROR: 5, 8604 PULL: 6, 8605 PULL_COMPLETE: 7, 8606 START_COMPLETE: 8 8607}; 8608function wrapReason(reason) { 8609 if (!(reason instanceof Error || typeof reason === "object" && reason !== null)) { 8610 (0, _util.unreachable)('wrapReason: Expected "reason" to be a (possibly cloned) Error.'); 8611 } 8612 switch (reason.name) { 8613 case "AbortException": 8614 return new _util.AbortException(reason.message); 8615 case "MissingPDFException": 8616 return new _util.MissingPDFException(reason.message); 8617 case "PasswordException": 8618 return new _util.PasswordException(reason.message, reason.code); 8619 case "UnexpectedResponseException": 8620 return new _util.UnexpectedResponseException(reason.message, reason.status); 8621 case "UnknownErrorException": 8622 return new _util.UnknownErrorException(reason.message, reason.details); 8623 default: 8624 return new _util.UnknownErrorException(reason.message, reason.toString()); 8625 } 8626} 8627class MessageHandler { 8628 constructor(sourceName, targetName, comObj) { 8629 this.sourceName = sourceName; 8630 this.targetName = targetName; 8631 this.comObj = comObj; 8632 this.callbackId = 1; 8633 this.streamId = 1; 8634 this.streamSinks = Object.create(null); 8635 this.streamControllers = Object.create(null); 8636 this.callbackCapabilities = Object.create(null); 8637 this.actionHandler = Object.create(null); 8638 this._onComObjOnMessage = event => { 8639 const data = event.data; 8640 if (data.targetName !== this.sourceName) { 8641 return; 8642 } 8643 if (data.stream) { 8644 this.#processStreamMessage(data); 8645 return; 8646 } 8647 if (data.callback) { 8648 const callbackId = data.callbackId; 8649 const capability = this.callbackCapabilities[callbackId]; 8650 if (!capability) { 8651 throw new Error(`Cannot resolve callback ${callbackId}`); 8652 } 8653 delete this.callbackCapabilities[callbackId]; 8654 if (data.callback === CallbackKind.DATA) { 8655 capability.resolve(data.data); 8656 } else if (data.callback === CallbackKind.ERROR) { 8657 capability.reject(wrapReason(data.reason)); 8658 } else { 8659 throw new Error("Unexpected callback case"); 8660 } 8661 return; 8662 } 8663 const action = this.actionHandler[data.action]; 8664 if (!action) { 8665 throw new Error(`Unknown action from worker: ${data.action}`); 8666 } 8667 if (data.callbackId) { 8668 const cbSourceName = this.sourceName; 8669 const cbTargetName = data.sourceName; 8670 new Promise(function (resolve) { 8671 resolve(action(data.data)); 8672 }).then(function (result) { 8673 comObj.postMessage({ 8674 sourceName: cbSourceName, 8675 targetName: cbTargetName, 8676 callback: CallbackKind.DATA, 8677 callbackId: data.callbackId, 8678 data: result 8679 }); 8680 }, function (reason) { 8681 comObj.postMessage({ 8682 sourceName: cbSourceName, 8683 targetName: cbTargetName, 8684 callback: CallbackKind.ERROR, 8685 callbackId: data.callbackId, 8686 reason: wrapReason(reason) 8687 }); 8688 }); 8689 return; 8690 } 8691 if (data.streamId) { 8692 this.#createStreamSink(data); 8693 return; 8694 } 8695 action(data.data); 8696 }; 8697 comObj.addEventListener("message", this._onComObjOnMessage); 8698 } 8699 on(actionName, handler) { 8700 const ah = this.actionHandler; 8701 if (ah[actionName]) { 8702 throw new Error(`There is already an actionName called "${actionName}"`); 8703 } 8704 ah[actionName] = handler; 8705 } 8706 send(actionName, data, transfers) { 8707 this.comObj.postMessage({ 8708 sourceName: this.sourceName, 8709 targetName: this.targetName, 8710 action: actionName, 8711 data 8712 }, transfers); 8713 }
8714 sendWithPromise(actionName, data, transfers) { 8715 const callbackId = this.callbackId++; 8716 const capability = new _util.PromiseCapability(); 8717 this.callbackCapabilities[callbackId] = capability; 8718 try { 8719 this.comObj.postMessage({ 8720 sourceName: this.sourceName, 8721 targetName: this.targetName, 8722 action: actionName, 8723 callbackId, 8724 data 8725 }, transfers); 8726 } catch (ex) { 8727 capability.reject(ex); 8728 } 8729 return capability.promise; 8730 } 8731 sendWithStream(actionName, data, queueingStrategy, transfers) { 8732 const streamId = this.streamId++, 8733 sourceName = this.sourceName, 8734 targetName = this.targetName, 8735 comObj = this.comObj; 8736 return new ReadableStream({ 8737 start: controller => { 8738 const startCapability = new _util.PromiseCapability(); 8739 this.streamControllers[streamId] = { 8740 controller, 8741 startCall: startCapability, 8742 pullCall: null, 8743 cancelCall: null, 8744 isClosed: false 8745 }; 8746 comObj.postMessage({ 8747 sourceName, 8748 targetName, 8749 action: actionName, 8750 streamId, 8751 data, 8752 desiredSize: controller.desiredSize 8753 }, transfers); 8754 return startCapability.promise; 8755 }, 8756 pull: controller => { 8757 const pullCapability = new _util.PromiseCapability(); 8758 this.streamControllers[streamId].pullCall = pullCapability; 8759 comObj.postMessage({ 8760 sourceName, 8761 targetName, 8762 stream: StreamKind.PULL, 8763 streamId, 8764 desiredSize: controller.desiredSize 8765 }); 8766 return pullCapability.promise; 8767 }, 8768 cancel: reason => { 8769 (0, _util.assert)(reason instanceof Error, "cancel must have a valid reason"); 8770 const cancelCapability = new _util.PromiseCapability(); 8771 this.streamControllers[streamId].cancelCall = cancelCapability; 8772 this.streamControllers[streamId].isClosed = true; 8773 comObj.postMessage({ 8774 sourceName, 8775 targetName, 8776 stream: StreamKind.CANCEL, 8777 streamId, 8778 reason: wrapReason(reason) 8779 }); 8780 return cancelCapability.promise; 8781 } 8782 }, queueingStrategy); 8783 } 8784 #createStreamSink(data) { 8785 const streamId = data.streamId, 8786 sourceName = this.sourceName, 8787 targetName = data.sourceName, 8788 comObj = this.comObj; 8789 const self = this, 8790 action = this.actionHandler[data.action]; 8791 const streamSink = { 8792 enqueue(chunk, size = 1, transfers) { 8793 if (this.isCancelled) { 8794 return; 8795 } 8796 const lastDesiredSize = this.desiredSize; 8797 this.desiredSize -= size; 8798 if (lastDesiredSize > 0 && this.desiredSize <= 0) { 8799 this.sinkCapability = new _util.PromiseCapability(); 8800 this.ready = this.sinkCapability.promise; 8801 } 8802 comObj.postMessage({ 8803 sourceName, 8804 targetName, 8805 stream: StreamKind.ENQUEUE, 8806 streamId, 8807 chunk 8808 }, transfers); 8809 }, 8810 close() { 8811 if (this.isCancelled) { 8812 return; 8813 } 8814 this.isCancelled = true; 8815 comObj.postMessage({ 8816 sourceName, 8817 targetName, 8818 stream: StreamKind.CLOSE, 8819 streamId 8820 }); 8821 delete self.streamSinks[streamId]; 8822 }, 8823 error(reason) { 8824 (0, _util.assert)(reason instanceof Error, "error must have a valid reason"); 8825 if (this.isCancelled) { 8826 return; 8827 } 8828 this.isCancelled = true; 8829 comObj.postMessage({ 8830 sourceName, 8831 targetName, 8832 stream: StreamKind.ERROR, 8833 streamId, 8834 reason: wrapReason(reason) 8835 }); 8836 }, 8837 sinkCapability: new _util.PromiseCapability(), 8838 onPull: null, 8839 onCancel: null, 8840 isCancelled: false, 8841 desiredSize: data.desiredSize, 8842 ready: null 8843 }; 8844 streamSink.sinkCapability.resolve(); 8845 streamSink.ready = streamSink.sinkCapability.promise; 8846 this.streamSinks[streamId] = streamSink; 8847 new Promise(function (resolve) { 8848 resolve(action(data.data, streamSink)); 8849 }).then(function () { 8850 comObj.postMessage({ 8851 sourceName, 8852 targetName, 8853 stream: StreamKind.START_COMPLETE, 8854 streamId, 8855 success: true 8856 }); 8857 }, function (reason) { 8858 comObj.postMessage({ 8859 sourceName, 8860 targetName, 8861 stream: StreamKind.START_COMPLETE, 8862 streamId, 8863 reason: wrapReason(reason) 8864 }); 8865 }); 8866 } 8867 #processStreamMessage(data) { 8868 const streamId = data.streamId, 8869 sourceName = this.sourceName, 8870 targetName = data.sourceName, 8871 comObj = this.comObj; 8872 const streamController = this.streamControllers[streamId], 8873 streamSink = this.streamSinks[streamId]; 8874 switch (data.stream) { 8875 case StreamKind.START_COMPLETE: 8876 if (data.success) { 8877 streamController.startCall.resolve(); 8878 } else { 8879 streamController.startCall.reject(wrapReason(data.reason)); 8880 } 8881 break; 8882 case StreamKind.PULL_COMPLETE: 8883 if (data.success) { 8884 streamController.pullCall.resolve(); 8885 } else { 8886 streamController.pullCall.reject(wrapReason(data.reason)); 8887 } 8888 break; 8889 case StreamKind.PULL: 8890 if (!streamSink) { 8891 comObj.postMessage({ 8892 sourceName, 8893 targetName, 8894 stream: StreamKind.PULL_COMPLETE, 8895 streamId, 8896 success: true 8897 }); 8898 break; 8899 } 8900 if (streamSink.desiredSize <= 0 && data.desiredSize > 0) { 8901 streamSink.sinkCapability.resolve(); 8902 } 8903 streamSink.desiredSize = data.desiredSize; 8904 new Promise(function (resolve) { 8905 resolve(streamSink.onPull?.()); 8906 }).then(function () { 8907 comObj.postMessage({ 8908 sourceName, 8909 targetName, 8910 stream: StreamKind.PULL_COMPLETE, 8911 streamId, 8912 success: true 8913 }); 8914 }, function (reason) { 8915 comObj.postMessage({ 8916 sourceName, 8917 targetName, 8918 stream: StreamKind.PULL_COMPLETE, 8919 streamId, 8920 reason: wrapReason(reason) 8921 }); 8922 }); 8923 break; 8924 case StreamKind.ENQUEUE: 8925 (0, _util.assert)(streamController, "enqueue should have stream controller"); 8926 if (streamController.isClosed) { 8927 break; 8928 } 8929 streamController.controller.enqueue(data.chunk); 8930 break; 8931 case StreamKind.CLOSE: 8932 (0, _util.assert)(streamController, "close should have stream controller"); 8933 if (streamController.isClosed) { 8934 break; 8935 } 8936 streamController.isClosed = true; 8937 streamController.controller.close(); 8938 this.#deleteStreamController(streamController, streamId); 8939 break; 8940 case StreamKind.ERROR: 8941 (0, _util.assert)(streamController, "error should have stream controller"); 8942 streamController.controller.error(wrapReason(data.reason)); 8943 this.#deleteStreamController(streamController, streamId); 8944 break; 8945 case StreamKind.CANCEL_COMPLETE: 8946 if (data.success) { 8947 streamController.cancelCall.resolve(); 8948 } else { 8949 streamController.cancelCall.reject(wrapReason(data.reason)); 8950 } 8951 this.#deleteStreamController(streamController, streamId); 8952 break; 8953 case StreamKind.CANCEL: 8954 if (!streamSink) { 8955 break; 8956 } 8957 new Promise(function (resolve) { 8958 resolve(streamSink.onCancel?.(wrapReason(data.reason))); 8959 }).then(function () { 8960 comObj.postMessage({ 8961 sourceName, 8962 targetName, 8963 stream: StreamKind.CANCEL_COMPLETE, 8964 streamId, 8965 success: true 8966 }); 8967 }, function (reason) { 8968 comObj.postMessage({ 8969 sourceName, 8970 targetName, 8971 stream: StreamKind.CANCEL_COMPLETE, 8972 streamId, 8973 reason: wrapReason(reason) 8974 }); 8975 }); 8976 streamSink.sinkCapability.reject(wrapReason(data.reason)); 8977 streamSink.isCancelled = true; 8978 delete this.streamSinks[streamId]; 8979 break; 8980 default: 8981 throw new Error("Unexpected stream case"); 8982 } 8983 } 8984 async #deleteStreamController(streamController, streamId) { 8985 await Promise.allSettled([streamController.startCall?.promise, streamController.pullCall?.promise, streamController.cancelCall?.promise]); 8986 delete this.streamControllers[streamId]; 8987 } 8988 destroy() { 8989 this.comObj.removeEventListener("message", this._onComObjOnMessage); 8990 } 8991} 8992exports.MessageHandler = MessageHandler; 8993 8994/***/ }), 8995/* 16 */ 8996/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 8997 8998 8999 9000Object.defineProperty(exports, "__esModule", ({ 9001 value: true 9002})); 9003exports.Metadata = void 0; 9004var _util = __w_pdfjs_require__(1); 9005class Metadata { 9006 #metadataMap; 9007 #data; 9008 constructor({ 9009 parsedData, 9010 rawData 9011 }) { 9012 this.#metadataMap = parsedData; 9013 this.#data = rawData; 9014 } 9015 getRaw() { 9016 return this.#data; 9017 } 9018 get(name) { 9019 return this.#metadataMap.get(name) ?? null; 9020 } 9021 getAll() { 9022 return (0, _util.objectFromMap)(this.#metadataMap); 9023 } 9024 has(name) { 9025 return this.#metadataMap.has(name); 9026 } 9027} 9028exports.Metadata = Metadata; 9029 9030/***/ }), 9031/* 17 */ 9032/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9033 9034 9035 9036Object.defineProperty(exports, "__esModule", ({ 9037 value: true 9038})); 9039exports.OptionalContentConfig = void 0; 9040var _util = __w_pdfjs_require__(1); 9041var _murmurhash = __w_pdfjs_require__(8); 9042const INTERNAL = Symbol("INTERNAL"); 9043class OptionalContentGroup { 9044 #visible = true; 9045 constructor(name, intent) { 9046 this.name = name; 9047 this.intent = intent; 9048 } 9049 get visible() { 9050 return this.#visible; 9051 } 9052 _setVisible(internal, visible) { 9053 if (internal !== INTERNAL) { 9054 (0, _util.unreachable)("Internal method `_setVisible` called."); 9055 } 9056 this.#visible = visible; 9057 } 9058} 9059class OptionalContentConfig { 9060 #cachedGetHash = null; 9061 #groups = new Map(); 9062 #initialHash = null; 9063 #order = null; 9064 constructor(data) { 9065 this.name = null; 9066 this.creator = null; 9067 if (data === null) { 9068 return; 9069 } 9070 this.name = data.name; 9071 this.creator = data.creator; 9072 this.#order = data.order; 9073 for (const group of data.groups) { 9074 this.#groups.set(group.id, new OptionalContentGroup(group.name, group.intent)); 9075 } 9076 if (data.baseState === "OFF") { 9077 for (const group of this.#groups.values()) { 9078 group._setVisible(INTERNAL, false); 9079 } 9080 } 9081 for (const on of data.on) { 9082 this.#groups.get(on)._setVisible(INTERNAL, true); 9083 } 9084 for (const off of data.off) { 9085 this.#groups.get(off)._setVisible(INTERNAL, false); 9086 } 9087 this.#initialHash = this.getHash(); 9088 } 9089 #evaluateVisibilityExpression(array) { 9090 const length = array.length; 9091 if (length < 2) { 9092 return true; 9093 } 9094 const operator = array[0]; 9095 for (let i = 1; i < length; i++) { 9096 const element = array[i]; 9097 let state; 9098 if (Array.isArray(element)) { 9099 state = this.#evaluateVisibilityExpression(element); 9100 } else if (this.#groups.has(element)) { 9101 state = this.#groups.get(element).visible; 9102 } else { 9103 (0, _util.warn)(`Optional content group not found: ${element}`); 9104 return true; 9105 } 9106 switch (operator) { 9107 case "And": 9108 if (!state) { 9109 return false;
9110 } 9111 break; 9112 case "Or": 9113 if (state) { 9114 return true; 9115 } 9116 break; 9117 case "Not": 9118 return !state; 9119 default: 9120 return true; 9121 } 9122 } 9123 return operator === "And"; 9124 } 9125 isVisible(group) { 9126 if (this.#groups.size === 0) { 9127 return true; 9128 } 9129 if (!group) { 9130 (0, _util.warn)("Optional content group not defined."); 9131 return true; 9132 } 9133 if (group.type === "OCG") { 9134 if (!this.#groups.has(group.id)) { 9135 (0, _util.warn)(`Optional content group not found: ${group.id}`); 9136 return true; 9137 } 9138 return this.#groups.get(group.id).visible; 9139 } else if (group.type === "OCMD") { 9140 if (group.expression) { 9141 return this.#evaluateVisibilityExpression(group.expression); 9142 } 9143 if (!group.policy || group.policy === "AnyOn") { 9144 for (const id of group.ids) { 9145 if (!this.#groups.has(id)) { 9146 (0, _util.warn)(`Optional content group not found: ${id}`); 9147 return true; 9148 } 9149 if (this.#groups.get(id).visible) { 9150 return true; 9151 } 9152 } 9153 return false; 9154 } else if (group.policy === "AllOn") { 9155 for (const id of group.ids) { 9156 if (!this.#groups.has(id)) { 9157 (0, _util.warn)(`Optional content group not found: ${id}`); 9158 return true; 9159 } 9160 if (!this.#groups.get(id).visible) { 9161 return false; 9162 } 9163 } 9164 return true; 9165 } else if (group.policy === "AnyOff") { 9166 for (const id of group.ids) { 9167 if (!this.#groups.has(id)) { 9168 (0, _util.warn)(`Optional content group not found: ${id}`); 9169 return true; 9170 } 9171 if (!this.#groups.get(id).visible) { 9172 return true; 9173 } 9174 } 9175 return false; 9176 } else if (group.policy === "AllOff") { 9177 for (const id of group.ids) { 9178 if (!this.#groups.has(id)) { 9179 (0, _util.warn)(`Optional content group not found: ${id}`); 9180 return true; 9181 } 9182 if (this.#groups.get(id).visible) { 9183 return false; 9184 } 9185 } 9186 return true; 9187 } 9188 (0, _util.warn)(`Unknown optional content policy ${group.policy}.`); 9189 return true; 9190 } 9191 (0, _util.warn)(`Unknown group type ${group.type}.`); 9192 return true; 9193 } 9194 setVisibility(id, visible = true) { 9195 if (!this.#groups.has(id)) { 9196 (0, _util.warn)(`Optional content group not found: ${id}`); 9197 return; 9198 } 9199 this.#groups.get(id)._setVisible(INTERNAL, !!visible); 9200 this.#cachedGetHash = null; 9201 } 9202 get hasInitialVisibility() { 9203 return this.getHash() === this.#initialHash; 9204 } 9205 getOrder() { 9206 if (!this.#groups.size) { 9207 return null; 9208 } 9209 if (this.#order) { 9210 return this.#order.slice(); 9211 } 9212 return [...this.#groups.keys()]; 9213 } 9214 getGroups() { 9215 return this.#groups.size > 0 ? (0, _util.objectFromMap)(this.#groups) : null; 9216 } 9217 getGroup(id) { 9218 return this.#groups.get(id) || null; 9219 } 9220 getHash() { 9221 if (this.#cachedGetHash !== null) { 9222 return this.#cachedGetHash; 9223 } 9224 const hash = new _murmurhash.MurmurHash3_64(); 9225 for (const [id, group] of this.#groups) { 9226 hash.update(`${id}:${group.visible}`); 9227 } 9228 return this.#cachedGetHash = hash.hexdigest(); 9229 } 9230} 9231exports.OptionalContentConfig = OptionalContentConfig; 9232 9233/***/ }), 9234/* 18 */ 9235/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9236 9237 9238 9239Object.defineProperty(exports, "__esModule", ({ 9240 value: true 9241})); 9242exports.PDFDataTransportStream = void 0; 9243var _util = __w_pdfjs_require__(1); 9244var _display_utils = __w_pdfjs_require__(6); 9245class PDFDataTransportStream { 9246 constructor({ 9247 length, 9248 initialData, 9249 progressiveDone = false, 9250 contentDispositionFilename = null, 9251 disableRange = false, 9252 disableStream = false 9253 }, pdfDataRangeTransport) { 9254 (0, _util.assert)(pdfDataRangeTransport, 'PDFDataTransportStream - missing required "pdfDataRangeTransport" argument.'); 9255 this._queuedChunks = []; 9256 this._progressiveDone = progressiveDone; 9257 this._contentDispositionFilename = contentDispositionFilename; 9258 if (initialData?.length > 0) { 9259 const buffer = initialData instanceof Uint8Array && initialData.byteLength === initialData.buffer.byteLength ? initialData.buffer : new Uint8Array(initialData).buffer; 9260 this._queuedChunks.push(buffer); 9261 } 9262 this._pdfDataRangeTransport = pdfDataRangeTransport; 9263 this._isStreamingSupported = !disableStream; 9264 this._isRangeSupported = !disableRange; 9265 this._contentLength = length; 9266 this._fullRequestReader = null; 9267 this._rangeReaders = []; 9268 this._pdfDataRangeTransport.addRangeListener((begin, chunk) => { 9269 this._onReceiveData({ 9270 begin, 9271 chunk 9272 }); 9273 }); 9274 this._pdfDataRangeTransport.addProgressListener((loaded, total) => { 9275 this._onProgress({ 9276 loaded, 9277 total 9278 }); 9279 }); 9280 this._pdfDataRangeTransport.addProgressiveReadListener(chunk => { 9281 this._onReceiveData({ 9282 chunk 9283 }); 9284 }); 9285 this._pdfDataRangeTransport.addProgressiveDoneListener(() => { 9286 this._onProgressiveDone(); 9287 }); 9288 this._pdfDataRangeTransport.transportReady(); 9289 } 9290 _onReceiveData({ 9291 begin, 9292 chunk 9293 }) { 9294 const buffer = chunk instanceof Uint8Array && chunk.byteLength === chunk.buffer.byteLength ? chunk.buffer : new Uint8Array(chunk).buffer; 9295 if (begin === undefined) { 9296 if (this._fullRequestReader) { 9297 this._fullRequestReader._enqueue(buffer); 9298 } else { 9299 this._queuedChunks.push(buffer); 9300 } 9301 } else { 9302 const found = this._rangeReaders.some(function (rangeReader) { 9303 if (rangeReader._begin !== begin) { 9304 return false;
9305 } 9306 rangeReader._enqueue(buffer); 9307 return true; 9308 }); 9309 (0, _util.assert)(found, "_onReceiveData - no `PDFDataTransportStreamRangeReader` instance found."); 9310 } 9311 } 9312 get _progressiveDataLength() { 9313 return this._fullRequestReader?._loaded ?? 0; 9314 } 9315 _onProgress(evt) { 9316 if (evt.total === undefined) { 9317 this._rangeReaders[0]?.onProgress?.({ 9318 loaded: evt.loaded 9319 }); 9320 } else { 9321 this._fullRequestReader?.onProgress?.({ 9322 loaded: evt.loaded, 9323 total: evt.total 9324 }); 9325 } 9326 } 9327 _onProgressiveDone() { 9328 this._fullRequestReader?.progressiveDone(); 9329 this._progressiveDone = true; 9330 } 9331 _removeRangeReader(reader) { 9332 const i = this._rangeReaders.indexOf(reader); 9333 if (i >= 0) { 9334 this._rangeReaders.splice(i, 1); 9335 } 9336 } 9337 getFullReader() { 9338 (0, _util.assert)(!this._fullRequestReader, "PDFDataTransportStream.getFullReader can only be called once."); 9339 const queuedChunks = this._queuedChunks; 9340 this._queuedChunks = null; 9341 return new PDFDataTransportStreamReader(this, queuedChunks, this._progressiveDone, this._contentDispositionFilename); 9342 } 9343 getRangeReader(begin, end) { 9344 if (end <= this._progressiveDataLength) { 9345 return null; 9346 } 9347 const reader = new PDFDataTransportStreamRangeReader(this, begin, end); 9348 this._pdfDataRangeTransport.requestDataRange(begin, end); 9349 this._rangeReaders.push(reader); 9350 return reader; 9351 } 9352 cancelAllRequests(reason) { 9353 this._fullRequestReader?.cancel(reason); 9354 for (const reader of this._rangeReaders.slice(0)) { 9355 reader.cancel(reason); 9356 } 9357 this._pdfDataRangeTransport.abort(); 9358 } 9359} 9360exports.PDFDataTransportStream = PDFDataTransportStream; 9361class PDFDataTransportStreamReader { 9362 constructor(stream, queuedChunks, progressiveDone = false, contentDispositionFilename = null) { 9363 this._stream = stream; 9364 this._done = progressiveDone || false; 9365 this._filename = (0, _display_utils.isPdfFile)(contentDispositionFilename) ? contentDispositionFilename : null; 9366 this._queuedChunks = queuedChunks || []; 9367 this._loaded = 0; 9368 for (const chunk of this._queuedChunks) { 9369 this._loaded += chunk.byteLength; 9370 } 9371 this._requests = []; 9372 this._headersReady = Promise.resolve(); 9373 stream._fullRequestReader = this; 9374 this.onProgress = null; 9375 } 9376 _enqueue(chunk) { 9377 if (this._done) { 9378 return; 9379 } 9380 if (this._requests.length > 0) { 9381 const requestCapability = this._requests.shift(); 9382 requestCapability.resolve({ 9383 value: chunk, 9384 done: false 9385 }); 9386 } else { 9387 this._queuedChunks.push(chunk); 9388 } 9389 this._loaded += chunk.byteLength; 9390 } 9391 get headersReady() { 9392 return this._headersReady; 9393 } 9394 get filename() { 9395 return this._filename; 9396 } 9397 get isRangeSupported() { 9398 return this._stream._isRangeSupported; 9399 } 9400 get isStreamingSupported() { 9401 return this._stream._isStreamingSupported; 9402 } 9403 get contentLength() { 9404 return this._stream._contentLength; 9405 } 9406 async read() { 9407 if (this._queuedChunks.length > 0) { 9408 const chunk = this._queuedChunks.shift(); 9409 return { 9410 value: chunk, 9411 done: false 9412 }; 9413 } 9414 if (this._done) { 9415 return { 9416 value: undefined, 9417 done: true 9418 }; 9419 } 9420 const requestCapability = new _util.PromiseCapability(); 9421 this._requests.push(requestCapability); 9422 return requestCapability.promise; 9423 } 9424 cancel(reason) { 9425 this._done = true; 9426 for (const requestCapability of this._requests) { 9427 requestCapability.resolve({ 9428 value: undefined, 9429 done: true 9430 }); 9431 } 9432 this._requests.length = 0; 9433 } 9434 progressiveDone() { 9435 if (this._done) { 9436 return; 9437 } 9438 this._done = true; 9439 } 9440} 9441class PDFDataTransportStreamRangeReader { 9442 constructor(stream, begin, end) { 9443 this._stream = stream; 9444 this._begin = begin; 9445 this._end = end; 9446 this._queuedChunk = null; 9447 this._requests = []; 9448 this._done = false; 9449 this.onProgress = null; 9450 } 9451 _enqueue(chunk) { 9452 if (this._done) { 9453 return; 9454 } 9455 if (this._requests.length === 0) { 9456 this._queuedChunk = chunk; 9457 } else { 9458 const requestsCapability = this._requests.shift(); 9459 requestsCapability.resolve({ 9460 value: chunk, 9461 done: false 9462 }); 9463 for (const requestCapability of this._requests) { 9464 requestCapability.resolve({ 9465 value: undefined, 9466 done: true 9467 }); 9468 } 9469 this._requests.length = 0; 9470 } 9471 this._done = true; 9472 this._stream._removeRangeReader(this); 9473 } 9474 get isStreamingSupported() { 9475 return false;
9476 } 9477 async read() { 9478 if (this._queuedChunk) { 9479 const chunk = this._queuedChunk; 9480 this._queuedChunk = null; 9481 return { 9482 value: chunk, 9483 done: false 9484 }; 9485 } 9486 if (this._done) { 9487 return { 9488 value: undefined, 9489 done: true 9490 }; 9491 } 9492 const requestCapability = new _util.PromiseCapability(); 9493 this._requests.push(requestCapability); 9494 return requestCapability.promise; 9495 } 9496 cancel(reason) { 9497 this._done = true; 9498 for (const requestCapability of this._requests) { 9499 requestCapability.resolve({ 9500 value: undefined, 9501 done: true 9502 }); 9503 } 9504 this._requests.length = 0; 9505 this._stream._removeRangeReader(this); 9506 } 9507} 9508 9509/***/ }), 9510/* 19 */ 9511/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9512 9513 9514 9515Object.defineProperty(exports, "__esModule", ({ 9516 value: true 9517})); 9518exports.PDFFetchStream = void 0; 9519var _util = __w_pdfjs_require__(1); 9520var _network_utils = __w_pdfjs_require__(20); 9521; 9522function createFetchOptions(headers, withCredentials, abortController) { 9523 return { 9524 method: "GET", 9525 headers, 9526 signal: abortController.signal, 9527 mode: "cors", 9528 credentials: withCredentials ? "include" : "same-origin", 9529 redirect: "follow" 9530 }; 9531} 9532function createHeaders(httpHeaders) { 9533 const headers = new Headers(); 9534 for (const property in httpHeaders) { 9535 const value = httpHeaders[property]; 9536 if (value === undefined) { 9537 continue; 9538 } 9539 headers.append(property, value); 9540 } 9541 return headers; 9542} 9543function getArrayBuffer(val) { 9544 if (val instanceof Uint8Array) { 9545 return val.buffer; 9546 } 9547 if (val instanceof ArrayBuffer) { 9548 return val; 9549 } 9550 (0, _util.warn)(`getArrayBuffer - unexpected data format: ${val}`); 9551 return new Uint8Array(val).buffer; 9552} 9553class PDFFetchStream { 9554 constructor(source) { 9555 this.source = source; 9556 this.isHttp = /^https?:/i.test(source.url); 9557 this.httpHeaders = this.isHttp && source.httpHeaders || {}; 9558 this._fullRequestReader = null; 9559 this._rangeRequestReaders = []; 9560 } 9561 get _progressiveDataLength() { 9562 return this._fullRequestReader?._loaded ?? 0; 9563 } 9564 getFullReader() { 9565 (0, _util.assert)(!this._fullRequestReader, "PDFFetchStream.getFullReader can only be called once."); 9566 this._fullRequestReader = new PDFFetchStreamReader(this); 9567 return this._fullRequestReader; 9568 } 9569 getRangeReader(begin, end) { 9570 if (end <= this._progressiveDataLength) { 9571 return null; 9572 } 9573 const reader = new PDFFetchStreamRangeReader(this, begin, end); 9574 this._rangeRequestReaders.push(reader); 9575 return reader; 9576 } 9577 cancelAllRequests(reason) { 9578 this._fullRequestReader?.cancel(reason); 9579 for (const reader of this._rangeRequestReaders.slice(0)) { 9580 reader.cancel(reason); 9581 } 9582 } 9583} 9584exports.PDFFetchStream = PDFFetchStream; 9585class PDFFetchStreamReader { 9586 constructor(stream) { 9587 this._stream = stream; 9588 this._reader = null; 9589 this._loaded = 0; 9590 this._filename = null; 9591 const source = stream.source; 9592 this._withCredentials = source.withCredentials || false; 9593 this._contentLength = source.length; 9594 this._headersCapability = new _util.PromiseCapability(); 9595 this._disableRange = source.disableRange || false; 9596 this._rangeChunkSize = source.rangeChunkSize; 9597 if (!this._rangeChunkSize && !this._disableRange) { 9598 this._disableRange = true; 9599 } 9600 this._abortController = new AbortController(); 9601 this._isStreamingSupported = !source.disableStream; 9602 this._isRangeSupported = !source.disableRange; 9603 this._headers = createHeaders(this._stream.httpHeaders); 9604 const url = source.url; 9605 fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(response => { 9606 if (!(0, _network_utils.validateResponseStatus)(response.status)) { 9607 throw (0, _network_utils.createResponseStatusError)(response.status, url); 9608 } 9609 this._reader = response.body.getReader(); 9610 this._headersCapability.resolve(); 9611 const getResponseHeader = name => { 9612 return response.headers.get(name); 9613 }; 9614 const { 9615 allowRangeRequests, 9616 suggestedLength 9617 } = (0, _network_utils.validateRangeRequestCapabilities)({ 9618 getResponseHeader, 9619 isHttp: this._stream.isHttp, 9620 rangeChunkSize: this._rangeChunkSize, 9621 disableRange: this._disableRange 9622 }); 9623 this._isRangeSupported = allowRangeRequests; 9624 this._contentLength = suggestedLength || this._contentLength; 9625 this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader); 9626 if (!this._isStreamingSupported && this._isRangeSupported) { 9627 this.cancel(new _util.AbortException("Streaming is disabled.")); 9628 } 9629 }).catch(this._headersCapability.reject); 9630 this.onProgress = null; 9631 } 9632 get headersReady() { 9633 return this._headersCapability.promise; 9634 } 9635 get filename() { 9636 return this._filename; 9637 } 9638 get contentLength() { 9639 return this._contentLength; 9640 } 9641 get isRangeSupported() { 9642 return this._isRangeSupported; 9643 } 9644 get isStreamingSupported() { 9645 return this._isStreamingSupported; 9646 } 9647 async read() { 9648 await this._headersCapability.promise; 9649 const { 9650 value, 9651 done 9652 } = await this._reader.read(); 9653 if (done) { 9654 return { 9655 value, 9656 done 9657 }; 9658 } 9659 this._loaded += value.byteLength; 9660 this.onProgress?.({ 9661 loaded: this._loaded, 9662 total: this._contentLength 9663 }); 9664 return { 9665 value: getArrayBuffer(value), 9666 done: false 9667 }; 9668 } 9669 cancel(reason) { 9670 this._reader?.cancel(reason); 9671 this._abortController.abort(); 9672 } 9673} 9674class PDFFetchStreamRangeReader { 9675 constructor(stream, begin, end) { 9676 this._stream = stream; 9677 this._reader = null; 9678 this._loaded = 0; 9679 const source = stream.source; 9680 this._withCredentials = source.withCredentials || false; 9681 this._readCapability = new _util.PromiseCapability(); 9682 this._isStreamingSupported = !source.disableStream; 9683 this._abortController = new AbortController(); 9684 this._headers = createHeaders(this._stream.httpHeaders); 9685 this._headers.append("Range", `bytes=${begin}
9685-${end - 1}`); 9686 const url = source.url; 9687 fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(response => { 9688 if (!(0, _network_utils.validateResponseStatus)(response.status)) { 9689 throw (0, _network_utils.createResponseStatusError)(response.status, url); 9690 } 9691 this._readCapability.resolve(); 9692 this._reader = response.body.getReader(); 9693 }).catch(this._readCapability.reject); 9694 this.onProgress = null; 9695 } 9696 get isStreamingSupported() { 9697 return this._isStreamingSupported; 9698 } 9699 async read() { 9700 await this._readCapability.promise; 9701 const { 9702 value, 9703 done 9704 } = await this._reader.read(); 9705 if (done) { 9706 return { 9707 value, 9708 done 9709 }; 9710 } 9711 this._loaded += value.byteLength; 9712 this.onProgress?.({ 9713 loaded: this._loaded 9714 }); 9715 return { 9716 value: getArrayBuffer(value), 9717 done: false 9718 }; 9719 } 9720 cancel(reason) { 9721 this._reader?.cancel(reason); 9722 this._abortController.abort(); 9723 } 9724} 9725 9726/***/ }), 9727/* 20 */ 9728/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9729 9730 9731 9732Object.defineProperty(exports, "__esModule", ({ 9733 value: true 9734})); 9735exports.createResponseStatusError = createResponseStatusError; 9736exports.extractFilenameFromHeader = extractFilenameFromHeader; 9737exports.validateRangeRequestCapabilities = validateRangeRequestCapabilities; 9738exports.validateResponseStatus = validateResponseStatus; 9739var _util = __w_pdfjs_require__(1); 9740var _content_disposition = __w_pdfjs_require__(21); 9741var _display_utils = __w_pdfjs_require__(6); 9742function validateRangeRequestCapabilities({ 9743 getResponseHeader, 9744 isHttp, 9745 rangeChunkSize, 9746 disableRange 9747}) { 9748 const returnValues = { 9749 allowRangeRequests: false, 9750 suggestedLength: undefined 9751 }; 9752 const length = parseInt(getResponseHeader("Content-Length"), 10); 9753 if (!Number.isInteger(length)) { 9754 return returnValues; 9755 } 9756 returnValues.suggestedLength = length; 9757 if (length <= 2 * rangeChunkSize) { 9758 return returnValues; 9759 } 9760 if (disableRange || !isHttp) { 9761 return returnValues; 9762 } 9763 if (getResponseHeader("Accept-Ranges") !== "bytes") { 9764 return returnValues; 9765 } 9766 const contentEncoding = getResponseHeader("Content-Encoding") || "identity"; 9767 if (contentEncoding !== "identity") { 9768 return returnValues; 9769 } 9770 returnValues.allowRangeRequests = true; 9771 return returnValues; 9772} 9773function extractFilenameFromHeader(getResponseHeader) { 9774 const contentDisposition = getResponseHeader("Content-Disposition"); 9775 if (contentDisposition) { 9776 let filename = (0, _content_disposition.getFilenameFromContentDispositionHeader)(contentDisposition); 9777 if (filename.includes("%")) { 9778 try { 9779 filename = decodeURIComponent(filename); 9780 } catch {} 9781 } 9782 if ((0, _display_utils.isPdfFile)(filename)) { 9783 return filename; 9784 } 9785 } 9786 return null; 9787} 9788function createResponseStatusError(status, url) { 9789 if (status === 404 || status === 0 && url.startsWith("file:")) { 9790 return new _util.MissingPDFException('Missing PDF "' + url + '".'); 9791 } 9792 return new _util.UnexpectedResponseException(`Unexpected server response (${status}) while retrieving PDF "${url}".`, status); 9793} 9794function validateResponseStatus(status) { 9795 return status === 200 || status === 206; 9796} 9797 9798/***/ }), 9799/* 21 */ 9800/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9801 9802 9803 9804Object.defineProperty(exports, "__esModule", ({ 9805 value: true 9806})); 9807exports.getFilenameFromContentDispositionHeader = getFilenameFromContentDispositionHeader; 9808var _util = __w_pdfjs_require__(1); 9809function getFilenameFromContentDispositionHeader(contentDisposition) { 9810 let needsEncodingFixup = true; 9811 let tmp = toParamRegExp("filename\\*", "i").exec(contentDisposition); 9812 if (tmp) { 9813 tmp = tmp[1]; 9814 let filename = rfc2616unquote(tmp); 9815 filename = unescape(filename); 9816 filename = rfc5987decode(filename); 9817 filename = rfc2047decode(filename); 9818 return fixupEncoding(filename); 9819 } 9820 tmp = rfc2231getparam(contentDisposition); 9821 if (tmp) { 9822 const filename = rfc2047decode(tmp); 9823 return fixupEncoding(filename); 9824 } 9825 tmp = toParamRegExp("filename", "i").exec(contentDisposition); 9826 if (tmp) { 9827 tmp = tmp[1]; 9828 let filename = rfc2616unquote(tmp); 9829 filename = rfc2047decode(filename); 9830 return fixupEncoding(filename); 9831 } 9832 function toParamRegExp(attributePattern, flags) { 9833 return new RegExp("(?:^|;)\\s*" + attributePattern + "\\s*=\\s*" + "(" + '[^";\\s][^;\\s]*' + "|" + '"(?:[^"\\\\]|\\\\"?)+"?' + ")", flags); 9834 } 9835 function textdecode(encoding, value) { 9836 if (encoding) { 9837 if (!/^[\x00-\xFF]+$/.test(value)) { 9838 return value; 9839 }
9840 try { 9841 const decoder = new TextDecoder(encoding, { 9842 fatal: true 9843 }); 9844 const buffer = (0, _util.stringToBytes)(value); 9845 value = decoder.decode(buffer); 9846 needsEncodingFixup = false; 9847 } catch {} 9848 } 9849 return value; 9850 } 9851 function fixupEncoding(value) { 9852 if (needsEncodingFixup && /[\x80-\xff]/.test(value)) { 9853 value = textdecode("utf-8", value); 9854 if (needsEncodingFixup) { 9855 value = textdecode("iso-8859-1", value); 9856 } 9857 } 9858 return value; 9859 } 9860 function rfc2231getparam(contentDispositionStr) { 9861 const matches = []; 9862 let match; 9863 const iter = toParamRegExp("filename\\*((?!0\\d)\\d+)(\\*?)", "ig"); 9864 while ((match = iter.exec(contentDispositionStr)) !== null) { 9865 let [, n, quot, part] = match; 9866 n = parseInt(n, 10); 9867 if (n in matches) { 9868 if (n === 0) { 9869 break; 9870 } 9871 continue; 9872 } 9873 matches[n] = [quot, part]; 9874 } 9875 const parts = []; 9876 for (let n = 0; n < matches.length; ++n) { 9877 if (!(n in matches)) { 9878 break; 9879 } 9880 let [quot, part] = matches[n]; 9881 part = rfc2616unquote(part); 9882 if (quot) { 9883 part = unescape(part); 9884 if (n === 0) { 9885 part = rfc5987decode(part); 9886 } 9887 } 9888 parts.push(part); 9889 } 9890 return parts.join(""); 9891 } 9892 function rfc2616unquote(value) { 9893 if (value.startsWith('"')) { 9894 const parts = value.slice(1).split('\\"'); 9895 for (let i = 0; i < parts.length; ++i) { 9896 const quotindex = parts[i].indexOf('"'); 9897 if (quotindex !== -1) { 9898 parts[i] = parts[i].slice(0, quotindex); 9899 parts.length = i + 1; 9900 } 9901 parts[i] = parts[i].replaceAll(/\\(.)/g, "$1"); 9902 } 9903 value = parts.join('"'); 9904 } 9905 return value; 9906 } 9907 function rfc5987decode(extvalue) { 9908 const encodingend = extvalue.indexOf("'"); 9909 if (encodingend === -1) { 9910 return extvalue; 9911 } 9912 const encoding = extvalue.slice(0, encodingend); 9913 const langvalue = extvalue.slice(encodingend + 1); 9914 const value = langvalue.replace(/^[^']*'/, ""); 9915 return textdecode(encoding, value); 9916 } 9917 function rfc2047decode(value) { 9918 if (!value.startsWith("=?") || /[\x00-\x19\x80-\xff]/.test(value)) { 9919 return value; 9920 } 9921 return value.replaceAll(/=\?([\w-]*)\?([QqBb])\?((?:[^?]|\?(?!=))*)\?=/g, function (matches, charset, encoding, text) { 9922 if (encoding === "q" || encoding === "Q") { 9923 text = text.replaceAll("_", " "); 9924 text = text.replaceAll(/=([0-9a-fA-F]{2})/g, function (match, hex) { 9925 return String.fromCharCode(parseInt(hex, 16)); 9926 }); 9927 return textdecode(charset, text); 9928 } 9929 try { 9930 text = atob(text); 9931 } catch {} 9932 return textdecode(charset, text); 9933 }); 9934 } 9935 return ""; 9936} 9937 9938/***/ }), 9939/* 22 */ 9940/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 9941 9942 9943 9944Object.defineProperty(exports, "__esModule", ({ 9945 value: true 9946})); 9947exports.PDFNetworkStream = void 0; 9948var _util = __w_pdfjs_require__(1); 9949var _network_utils = __w_pdfjs_require__(20); 9950; 9951const OK_RESPONSE = 200; 9952const PARTIAL_CONTENT_RESPONSE = 206; 9953function getArrayBuffer(xhr) { 9954 const data = xhr.response; 9955 if (typeof data !== "string") { 9956 return data; 9957 } 9958 return (0, _util.stringToBytes)(data).buffer; 9959} 9960class NetworkManager { 9961 constructor(url, args = {}) { 9962 this.url = url; 9963 this.isHttp = /^https?:/i.test(url); 9964 this.httpHeaders = this.isHttp && args.httpHeaders || Object.create(null); 9965 this.withCredentials = args.withCredentials || false; 9966 this.currXhrId = 0; 9967 this.pendingRequests = Object.create(null); 9968 } 9969 requestRange(begin, end, listeners) { 9970 const args = { 9971 begin, 9972 end 9973 }; 9974 for (const prop in listeners) { 9975 args[prop] = listeners[prop]; 9976 } 9977 return this.request(args); 9978 } 9979 requestFull(listeners) { 9980 return this.request(listeners); 9981 } 9982 request(args) { 9983 const xhr = new XMLHttpRequest(); 9984 const xhrId = this.currXhrId++; 9985 const pendingRequest = this.pendingRequests[xhrId] = { 9986 xhr 9987 }; 9988 xhr.open("GET", this.url); 9989 xhr.withCredentials = this.withCredentials; 9990 for (const property in this.httpHeaders) { 9991 const value = this.httpHeaders[property]; 9992 if (value === undefined) { 9993 continue; 9994 } 9995 xhr.setRequestHeader(property, value); 9996 } 9997 if (this.isHttp && "begin" in args && "end" in args) { 9998 xhr.setRequestHeader("Range", `bytes=${args.begin}-${args.end - 1}`); 9999 pendingRequest.expectedStatus = PARTIAL_CONTENT_RESPONSE; 10000 } else { 10001 pendingRequest.expectedStatus = OK_RESPONSE; 10002 } 10003 xhr.responseType = "arraybuffer"; 10004 if (args.onError) { 10005 xhr.onerror = function (evt) { 10006 args.onError(xhr.status); 10007 }; 10008 } 10009 xhr.onreadystatechange = this.onStateChange.bind(this, xhrId); 10010 xhr.onprogress = this.onProgress.bind(this, xhrId); 10011 pendingRequest.onHeadersReceived = args.onHeadersReceived; 10012 pendingRequest.onDone = args.onDone; 10013 pendingRequest.onError = args.onError; 10014 pendingRequest.onProgress = args.onProgress; 10015 xhr.send(null); 10016 return xhrId; 10017 } 10018 onProgress(xhrId, evt) { 10019 const pendingRequest = this.pendingRequests[xhrId]; 10020 if (!pendingRequest) { 10021 return; 10022 } 10023 pendingRequest.onProgress?.(evt); 10024 } 10025 onStateChange(xhrId, evt) { 10026 const pendingRequest = this.pendingRequests[xhrId]; 10027 if (!pendingRequest) { 10028 return; 10029 } 10030 const xhr = pendingRequest.xhr; 10031 if (xhr.readyState >= 2 && pendingRequest.onHeadersReceived) { 10032 pendingRequest.onHeadersReceived();
10033 delete pendingRequest.onHeadersReceived; 10034 } 10035 if (xhr.readyState !== 4) { 10036 return; 10037 } 10038 if (!(xhrId in this.pendingRequests)) { 10039 return; 10040 } 10041 delete this.pendingRequests[xhrId]; 10042 if (xhr.status === 0 && this.isHttp) { 10043 pendingRequest.onError?.(xhr.status); 10044 return; 10045 } 10046 const xhrStatus = xhr.status || OK_RESPONSE; 10047 const ok_response_on_range_request = xhrStatus === OK_RESPONSE && pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE; 10048 if (!ok_response_on_range_request && xhrStatus !== pendingRequest.expectedStatus) { 10049 pendingRequest.onError?.(xhr.status); 10050 return; 10051 } 10052 const chunk = getArrayBuffer(xhr); 10053 if (xhrStatus === PARTIAL_CONTENT_RESPONSE) { 10054 const rangeHeader = xhr.getResponseHeader("Content-Range"); 10055 const matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader); 10056 pendingRequest.onDone({ 10057 begin: parseInt(matches[1], 10), 10058 chunk 10059 }); 10060 } else if (chunk) { 10061 pendingRequest.onDone({ 10062 begin: 0, 10063 chunk 10064 }); 10065 } else { 10066 pendingRequest.onError?.(xhr.status); 10067 } 10068 } 10069 getRequestXhr(xhrId) { 10070 return this.pendingRequests[xhrId].xhr; 10071 } 10072 isPendingRequest(xhrId) { 10073 return xhrId in this.pendingRequests; 10074 } 10075 abortRequest(xhrId) { 10076 const xhr = this.pendingRequests[xhrId].xhr; 10077 delete this.pendingRequests[xhrId]; 10078 xhr.abort(); 10079 } 10080} 10081class PDFNetworkStream { 10082 constructor(source) { 10083 this._source = source; 10084 this._manager = new NetworkManager(source.url, { 10085 httpHeaders: source.httpHeaders, 10086 withCredentials: source.withCredentials 10087 }); 10088 this._rangeChunkSize = source.rangeChunkSize; 10089 this._fullRequestReader = null; 10090 this._rangeRequestReaders = []; 10091 } 10092 _onRangeRequestReaderClosed(reader) { 10093 const i = this._rangeRequestReaders.indexOf(reader); 10094 if (i >= 0) { 10095 this._rangeRequestReaders.splice(i, 1); 10096 } 10097 } 10098 getFullReader() { 10099 (0, _util.assert)(!this._fullRequestReader, "PDFNetworkStream.getFullReader can only be called once."); 10100 this._fullRequestReader = new PDFNetworkStreamFullRequestReader(this._manager, this._source); 10101 return this._fullRequestReader; 10102 } 10103 getRangeReader(begin, end) { 10104 const reader = new PDFNetworkStreamRangeRequestReader(this._manager, begin, end); 10105 reader.onClosed = this._onRangeRequestReaderClosed.bind(this); 10106 this._rangeRequestReaders.push(reader); 10107 return reader; 10108 } 10109 cancelAllRequests(reason) { 10110 this._fullRequestReader?.cancel(reason); 10111 for (const reader of this._rangeRequestReaders.slice(0)) { 10112 reader.cancel(reason); 10113 } 10114 } 10115} 10116exports.PDFNetworkStream = PDFNetworkStream; 10117class PDFNetworkStreamFullRequestReader { 10118 constructor(manager, source) { 10119 this._manager = manager; 10120 const args = { 10121 onHeadersReceived: this._onHeadersReceived.bind(this), 10122 onDone: this._onDone.bind(this), 10123 onError: this._onError.bind(this), 10124 onProgress: this._onProgress.bind(this) 10125 }; 10126 this._url = source.url; 10127 this._fullRequestId = manager.requestFull(args); 10128 this._headersReceivedCapability = new _util.PromiseCapability(); 10129 this._disableRange = source.disableRange || false; 10130 this._contentLength = source.length; 10131 this._rangeChunkSize = source.rangeChunkSize; 10132 if (!this._rangeChunkSize && !this._disableRange) { 10133 this._disableRange = true; 10134 } 10135 this._isStreamingSupported = false; 10136 this._isRangeSupported = false; 10137 this._cachedChunks = []; 10138 this._requests = []; 10139 this._done = false; 10140 this._storedError = undefined; 10141 this._filename = null; 10142 this.onProgress = null; 10143 } 10144 _onHeadersReceived() { 10145 const fullRequestXhrId = this._fullRequestId; 10146 const fullRequestXhr = this._manager.getRequestXhr(fullRequestXhrId); 10147 const getResponseHeader = name => { 10148 return fullRequestXhr.getResponseHeader(name); 10149 }; 10150 const { 10151 allowRangeRequests, 10152 suggestedLength 10153 } = (0, _network_utils.validateRangeRequestCapabilities)({ 10154 getResponseHeader, 10155 isHttp: this._manager.isHttp, 10156 rangeChunkSize: this._rangeChunkSize, 10157 disableRange: this._disableRange 10158 }); 10159 if (allowRangeRequests) { 10160 this._isRangeSupported = true; 10161 } 10162 this._contentLength = suggestedLength || this._contentLength; 10163 this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader); 10164 if (this._isRangeSupported) {
vendor: 4,778 bytes, lines 10165-10350
10165 this._manager.abortRequest(fullRequestXhrId); 10166 } 10167 this._headersReceivedCapability.resolve(); 10168 } 10169 _onDone(data) { 10170 if (data) { 10171 if (this._requests.length > 0) { 10172 const requestCapability = this._requests.shift(); 10173 requestCapability.resolve({ 10174 value: data.chunk, 10175 done: false 10176 }); 10177 } else { 10178 this._cachedChunks.push(data.chunk); 10179 } 10180 } 10181 this._done = true; 10182 if (this._cachedChunks.length > 0) { 10183 return; 10184 } 10185 for (const requestCapability of this._requests) { 10186 requestCapability.resolve({ 10187 value: undefined, 10188 done: true 10189 }); 10190 } 10191 this._requests.length = 0; 10192 } 10193 _onError(status) { 10194 this._storedError = (0, _network_utils.createResponseStatusError)(status, this._url); 10195 this._headersReceivedCapability.reject(this._storedError); 10196 for (const requestCapability of this._requests) { 10197 requestCapability.reject(this._storedError); 10198 } 10199 this._requests.length = 0; 10200 this._cachedChunks.length = 0; 10201 } 10202 _onProgress(evt) { 10203 this.onProgress?.({ 10204 loaded: evt.loaded, 10205 total: evt.lengthComputable ? evt.total : this._contentLength 10206 }); 10207 } 10208 get filename() { 10209 return this._filename; 10210 } 10211 get isRangeSupported() { 10212 return this._isRangeSupported; 10213 } 10214 get isStreamingSupported() { 10215 return this._isStreamingSupported; 10216 } 10217 get contentLength() { 10218 return this._contentLength; 10219 } 10220 get headersReady() { 10221 return this._headersReceivedCapability.promise; 10222 } 10223 async read() { 10224 if (this._storedError) { 10225 throw this._storedError; 10226 } 10227 if (this._cachedChunks.length > 0) { 10228 const chunk = this._cachedChunks.shift(); 10229 return { 10230 value: chunk, 10231 done: false 10232 }; 10233 } 10234 if (this._done) { 10235 return { 10236 value: undefined, 10237 done: true 10238 }; 10239 } 10240 const requestCapability = new _util.PromiseCapability(); 10241 this._requests.push(requestCapability); 10242 return requestCapability.promise; 10243 } 10244 cancel(reason) { 10245 this._done = true; 10246 this._headersReceivedCapability.reject(reason); 10247 for (const requestCapability of this._requests) { 10248 requestCapability.resolve({ 10249 value: undefined, 10250 done: true 10251 }); 10252 } 10253 this._requests.length = 0; 10254 if (this._manager.isPendingRequest(this._fullRequestId)) { 10255 this._manager.abortRequest(this._fullRequestId); 10256 } 10257 this._fullRequestReader = null; 10258 } 10259} 10260class PDFNetworkStreamRangeRequestReader { 10261 constructor(manager, begin, end) { 10262 this._manager = manager; 10263 const args = { 10264 onDone: this._onDone.bind(this), 10265 onError: this._onError.bind(this), 10266 onProgress: this._onProgress.bind(this) 10267 }; 10268 this._url = manager.url; 10269 this._requestId = manager.requestRange(begin, end, args); 10270 this._requests = []; 10271 this._queuedChunk = null; 10272 this._done = false; 10273 this._storedError = undefined; 10274 this.onProgress = null; 10275 this.onClosed = null; 10276 } 10277 _close() { 10278 this.onClosed?.(this); 10279 } 10280 _onDone(data) { 10281 const chunk = data.chunk; 10282 if (this._requests.length > 0) { 10283 const requestCapability = this._requests.shift(); 10284 requestCapability.resolve({ 10285 value: chunk, 10286 done: false 10287 }); 10288 } else { 10289 this._queuedChunk = chunk; 10290 } 10291 this._done = true; 10292 for (const requestCapability of this._requests) { 10293 requestCapability.resolve({ 10294 value: undefined, 10295 done: true 10296 }); 10297 } 10298 this._requests.length = 0; 10299 this._close(); 10300 } 10301 _onError(status) { 10302 this._storedError = (0, _network_utils.createResponseStatusError)(status, this._url); 10303 for (const requestCapability of this._requests) { 10304 requestCapability.reject(this._storedError); 10305 } 10306 this._requests.length = 0; 10307 this._queuedChunk = null; 10308 } 10309 _onProgress(evt) { 10310 if (!this.isStreamingSupported) { 10311 this.onProgress?.({ 10312 loaded: evt.loaded 10313 }); 10314 } 10315 } 10316 get isStreamingSupported() { 10317 return false; 10318 } 10319 async read() { 10320 if (this._storedError) { 10321 throw this._storedError; 10322 } 10323 if (this._queuedChunk !== null) { 10324 const chunk = this._queuedChunk; 10325 this._queuedChunk = null; 10326 return { 10327 value: chunk, 10328 done: false 10329 }; 10330 } 10331 if (this._done) { 10332 return { 10333 value: undefined, 10334 done: true 10335 }; 10336 } 10337 const requestCapability = new _util.PromiseCapability(); 10338 this._requests.push(requestCapability); 10339 return requestCapability.promise; 10340 } 10341 cancel(reason) { 10342 this._done = true; 10343 for (const requestCapability of this._requests) { 10344 requestCapability.resolve({ 10345 value: undefined, 10346 done: true 10347 }); 10348 } 10349 this._requests.length = 0; 10350 if (this._manager.isPendingRequest(this._requestId)) {
10351 this._manager.abortRequest(this._requestId); 10352 } 10353 this._close(); 10354 } 10355} 10356 10357/***/ }), 10358/* 23 */ 10359/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 10360 10361 10362 10363Object.defineProperty(exports, "__esModule", ({ 10364 value: true 10365})); 10366exports.PDFNodeStream = void 0; 10367var _util = __w_pdfjs_require__(1); 10368var _network_utils = __w_pdfjs_require__(20); 10369; 10370const fileUriRegex = /^file:\/\/\/[a-zA-Z]:\//; 10371function parseUrl(sourceUrl) { 10372 const url = require("url"); 10373 const parsedUrl = url.parse(sourceUrl); 10374 if (parsedUrl.protocol === "file:" || parsedUrl.host) { 10375 return parsedUrl; 10376 } 10377 if (/^[a-z]:[/\\]/i.test(sourceUrl)) { 10378 return url.parse(`file:///${sourceUrl}`); 10379 } 10380 if (!parsedUrl.host) { 10381 parsedUrl.protocol = "file:"; 10382 } 10383 return parsedUrl; 10384} 10385class PDFNodeStream { 10386 constructor(source) { 10387 this.source = source; 10388 this.url = parseUrl(source.url); 10389 this.isHttp = this.url.protocol === "http:" || this.url.protocol === "https:"; 10390 this.isFsUrl = this.url.protocol === "file:"; 10391 this.httpHeaders = this.isHttp && source.httpHeaders || {}; 10392 this._fullRequestReader = null; 10393 this._rangeRequestReaders = []; 10394 } 10395 get _progressiveDataLength() { 10396 return this._fullRequestReader?._loaded ?? 0; 10397 } 10398 getFullReader() { 10399 (0, _util.assert)(!this._fullRequestReader, "PDFNodeStream.getFullReader can only be called once."); 10400 this._fullRequestReader = this.isFsUrl ? new PDFNodeStreamFsFullReader(this) : new PDFNodeStreamFullReader(this); 10401 return this._fullRequestReader; 10402 } 10403 getRangeReader(start, end) { 10404 if (end <= this._progressiveDataLength) { 10405 return null; 10406 } 10407 const rangeReader = this.isFsUrl ? new PDFNodeStreamFsRangeReader(this, start, end) : new PDFNodeStreamRangeReader(this, start, end); 10408 this._rangeRequestReaders.push(rangeReader); 10409 return rangeReader; 10410 } 10411 cancelAllRequests(reason) { 10412 this._fullRequestReader?.cancel(reason); 10413 for (const reader of this._rangeRequestReaders.slice(0)) { 10414 reader.cancel(reason); 10415 } 10416 } 10417} 10418exports.PDFNodeStream = PDFNodeStream; 10419class BaseFullReader { 10420 constructor(stream) { 10421 this._url = stream.url; 10422 this._done = false; 10423 this._storedError = null; 10424 this.onProgress = null; 10425 const source = stream.source; 10426 this._contentLength = source.length; 10427 this._loaded = 0; 10428 this._filename = null; 10429 this._disableRange = source.disableRange || false; 10430 this._rangeChunkSize = source.rangeChunkSize; 10431 if (!this._rangeChunkSize && !this._disableRange) { 10432 this._disableRange = true; 10433 } 10434 this._isStreamingSupported = !source.disableStream; 10435 this._isRangeSupported = !source.disableRange; 10436 this._readableStream = null; 10437 this._readCapability = new _util.PromiseCapability(); 10438 this._headersCapability = new _util.PromiseCapability(); 10439 } 10440 get headersReady() { 10441 return this._headersCapability.promise; 10442 } 10443 get filename() { 10444 return this._filename; 10445 } 10446 get contentLength() { 10447 return this._contentLength; 10448 } 10449 get isRangeSupported() { 10450 return this._isRangeSupported; 10451 } 10452 get isStreamingSupported() { 10453 return this._isStreamingSupported; 10454 } 10455 async read() { 10456 await this._readCapability.promise; 10457 if (this._done) { 10458 return { 10459 value: undefined, 10460 done: true 10461 }; 10462 } 10463 if (this._storedError) { 10464 throw this._storedError; 10465 } 10466 const chunk = this._readableStream.read(); 10467 if (chunk === null) { 10468 this._readCapability = new _util.PromiseCapability(); 10469 return this.read(); 10470 } 10471 this._loaded += chunk.length; 10472 this.onProgress?.({ 10473 loaded: this._loaded, 10474 total: this._contentLength 10475 }); 10476 const buffer = new Uint8Array(chunk).buffer; 10477 return { 10478 value: buffer, 10479 done: false 10480 }; 10481 } 10482 cancel(reason) { 10483 if (!this._readableStream) { 10484 this._error(reason); 10485 return; 10486 } 10487 this._readableStream.destroy(reason); 10488 } 10489 _error(reason) { 10490 this._storedError = reason; 10491 this._readCapability.resolve(); 10492 } 10493 _setReadableStream(readableStream) { 10494 this._readableStream = readableStream; 10495 readableStream.on("readable", () => { 10496 this._readCapability.resolve(); 10497 }); 10498 readableStream.on("end", () => { 10499 readableStream.destroy(); 10500 this._done = true; 10501 this._readCapability.resolve(); 10502 }); 10503 readableStream.on("error", reason => { 10504 this._error(reason); 10505 }); 10506 if (!this._isStreamingSupported && this._isRangeSupported) { 10507 this._error(new _util.AbortException("streaming is disabled")); 10508 } 10509 if (this._storedError) { 10510 this._readableStream.destroy(this._storedError); 10511 } 10512 } 10513} 10514class BaseRangeReader { 10515 constructor(stream) { 10516 this._url = stream.url; 10517 this._done = false;
10518 this._storedError = null; 10519 this.onProgress = null; 10520 this._loaded = 0; 10521 this._readableStream = null; 10522 this._readCapability = new _util.PromiseCapability(); 10523 const source = stream.source; 10524 this._isStreamingSupported = !source.disableStream; 10525 } 10526 get isStreamingSupported() { 10527 return this._isStreamingSupported; 10528 } 10529 async read() { 10530 await this._readCapability.promise; 10531 if (this._done) { 10532 return { 10533 value: undefined, 10534 done: true 10535 }; 10536 } 10537 if (this._storedError) { 10538 throw this._storedError; 10539 } 10540 const chunk = this._readableStream.read(); 10541 if (chunk === null) { 10542 this._readCapability = new _util.PromiseCapability(); 10543 return this.read(); 10544 } 10545 this._loaded += chunk.length; 10546 this.onProgress?.({ 10547 loaded: this._loaded 10548 }); 10549 const buffer = new Uint8Array(chunk).buffer; 10550 return { 10551 value: buffer, 10552 done: false 10553 }; 10554 } 10555 cancel(reason) { 10556 if (!this._readableStream) { 10557 this._error(reason); 10558 return; 10559 } 10560 this._readableStream.destroy(reason); 10561 } 10562 _error(reason) { 10563 this._storedError = reason; 10564 this._readCapability.resolve(); 10565 } 10566 _setReadableStream(readableStream) { 10567 this._readableStream = readableStream; 10568 readableStream.on("readable", () => { 10569 this._readCapability.resolve(); 10570 }); 10571 readableStream.on("end", () => { 10572 readableStream.destroy(); 10573 this._done = true; 10574 this._readCapability.resolve(); 10575 }); 10576 readableStream.on("error", reason => { 10577 this._error(reason); 10578 }); 10579 if (this._storedError) { 10580 this._readableStream.destroy(this._storedError); 10581 } 10582 } 10583} 10584function createRequestOptions(parsedUrl, headers) { 10585 return { 10586 protocol: parsedUrl.protocol, 10587 auth: parsedUrl.auth, 10588 host: parsedUrl.hostname, 10589 port: parsedUrl.port, 10590 path: parsedUrl.path, 10591 method: "GET", 10592 headers 10593 }; 10594} 10595class PDFNodeStreamFullReader extends BaseFullReader { 10596 constructor(stream) { 10597 super(stream); 10598 const handleResponse = response => { 10599 if (response.statusCode === 404) { 10600 const error = new _util.MissingPDFException(`Missing PDF "${this._url}".`); 10601 this._storedError = error; 10602 this._headersCapability.reject(error); 10603 return; 10604 } 10605 this._headersCapability.resolve(); 10606 this._setReadableStream(response); 10607 const getResponseHeader = name => { 10608 return this._readableStream.headers[name.toLowerCase()]; 10609 }; 10610 const { 10611 allowRangeRequests, 10612 suggestedLength 10613 } = (0, _network_utils.validateRangeRequestCapabilities)({ 10614 getResponseHeader, 10615 isHttp: stream.isHttp, 10616 rangeChunkSize: this._rangeChunkSize, 10617 disableRange: this._disableRange 10618 }); 10619 this._isRangeSupported = allowRangeRequests; 10620 this._contentLength = suggestedLength || this._contentLength; 10621 this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader); 10622 }; 10623 this._request = null; 10624 if (this._url.protocol === "http:") { 10625 const http = require("http"); 10626 this._request = http.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse); 10627 } else { 10628 const https = require("https"); 10629 this._request = https.request(createRequestOptions(this._url, stream.httpHeaders), handleResponse); 10630 } 10631 this._request.on("error", reason => { 10632 this._storedError = reason; 10633 this._headersCapability.reject(reason); 10634 }); 10635 this._request.end(); 10636 } 10637} 10638class PDFNodeStreamRangeReader extends BaseRangeReader { 10639 constructor(stream, start, end) { 10640 super(stream); 10641 this._httpHeaders = {}; 10642 for (const property in stream.httpHeaders) { 10643 const value = stream.httpHeaders[property]; 10644 if (value === undefined) { 10645 continue; 10646 } 10647 this._httpHeaders[property] = value; 10648 } 10649 this._httpHeaders.Range = `bytes=${start}-${end - 1}`; 10650 const handleResponse = response => { 10651 if (response.statusCode === 404) { 10652 const error = new _util.MissingPDFException(`Missing PDF "${this._url}".`); 10653 this._storedError = error; 10654 return; 10655 } 10656 this._setReadableStream(response); 10657 }; 10658 this._request = null; 10659 if (this._url.protocol === "http:") { 10660 const http = require("http"); 10661 this._request = http.request(createRequestOptions(this._url, this._httpHeaders), handleResponse); 10662 } else { 10663 const https = require("https"); 10664 this._request = https.request(createRequestOptions(this._url, this._httpHeaders), handleResponse); 10665 } 10666 this._request.on("error", reason => { 10667 this._storedError = reason; 10668 }); 10669 this._request.end(); 10670 } 10671} 10672class PDFNodeStreamFsFullReader extends BaseFullReader { 10673 constructor(stream) { 10674 super(stream); 10675 let path = decodeURIComponent(this._url.path); 10676 if (fileUriRegex.test(this._url.href)) { 10677 path = path.replace(/^\//, ""); 10678 } 10679 const fs = require("fs"); 10680 fs.lstat(path, (error, stat) => { 10681 if (error) { 10682 if (error.code === "ENOENT") { 10683 error = new _util.MissingPDFException(`Missing PDF "${path}".`); 10684 } 10685 this._storedError = error; 10686 this._headersCapability.reject(error); 10687 return; 10688 } 10689 this._contentLength = stat.size; 10690 this._setReadableStream(fs.createReadStream(path)); 10691 this._headersCapability.resolve(); 10692 }); 10693 } 10694} 10695class PDFNodeStreamFsRangeReader extends BaseRangeReader { 10696 constructor(stream, start, end) { 10697 super(stream); 10698 let path = decodeURIComponent(this._url.path); 10699 if (fileUriRegex.test(this._url.href)) { 10700 path = path.replace(/^\//, ""); 10701 } 10702 const fs = require("fs"); 10703 this._setReadableStream(fs.createReadStream(path, { 10704 start, 10705 end: end - 1 10706 })); 10707 } 10708} 10709 10710/***/ }), 10711/* 24 */ 10712/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 10713 10714 10715 10716Object.defineProperty(exports, "__esModule", ({ 10717 value: true 10718})); 10719exports.SVGGraphics = void 0; 10720var _display_utils = __w_pdfjs_require__(6); 10721var _util = __w_pdfjs_require__(1); 10722; 10723const SVG_DEFAULTS = { 10724 fontStyle: "normal", 10725 fontWeight: "normal", 10726 fillColor: "#000000" 10727}; 10728const XML_NS = "http://www.w3.org/XML/1998/namespace"; 10729const XLINK_NS = "http://www.w3.org/1999/xlink"; 10730const LINE_CAP_STYLES = ["butt", "round", "square"]; 10731const LINE_JOIN_STYLES = ["miter", "round", "bevel"]; 10732const createObjectURL = function (data, contentType = "", forceDataSchema = false) { 10733 if (URL.createObjectURL && typeof Blob !== "undefined" && !forceDataSchema) { 10734 return URL.createObjectURL(new Blob([data], { 10735 type: contentType 10736 })); 10737 } 10738 const digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
10738+/="; 10739 let buffer = `data:${contentType};base64,`; 10740 for (let i = 0, ii = data.length; i < ii; i += 3) { 10741 const b1 = data[i] & 0xff; 10742 const b2 = data[i + 1] & 0xff; 10743 const b3 = data[i + 2] & 0xff; 10744 const d1 = b1 >> 2, 10745 d2 = (b1 & 3) << 4 | b2 >> 4; 10746 const d3 = i + 1 < ii ? (b2 & 0xf) << 2 | b3 >> 6 : 64; 10747 const d4 = i + 2 < ii ? b3 & 0x3f : 64; 10748 buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4]; 10749 } 10750 return buffer; 10751}; 10752const convertImgDataToPng = function () { 10753 const PNG_HEADER = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); 10754 const CHUNK_WRAPPER_SIZE = 12; 10755 const crcTable = new Int32Array(256); 10756 for (let i = 0; i < 256; i++) { 10757 let c = i; 10758 for (let h = 0; h < 8; h++) { 10759 c = c & 1 ? 0xedb88320 ^ c >> 1 & 0x7fffffff : c >> 1 & 0x7fffffff; 10760 } 10761 crcTable[i] = c; 10762 } 10763 function crc32(data, start, end) { 10764 let crc = -1; 10765 for (let i = start; i < end; i++) { 10766 const a = (crc ^ data[i]) & 0xff; 10767 const b = crcTable[a]; 10768 crc = crc >>> 8 ^ b; 10769 } 10770 return crc ^ -1; 10771 } 10772 function writePngChunk(type, body, data, offset) { 10773 let p = offset; 10774 const len = body.length; 10775 data[p] = len >> 24 & 0xff; 10776 data[p + 1] = len >> 16 & 0xff; 10777 data[p + 2] = len >> 8 & 0xff; 10778 data[p + 3] = len & 0xff; 10779 p += 4; 10780 data[p] = type.charCodeAt(0) & 0xff; 10781 data[p + 1] = type.charCodeAt(1) & 0xff; 10782 data[p + 2] = type.charCodeAt(2) & 0xff;
10783 data[p + 3] = type.charCodeAt(3) & 0xff; 10784 p += 4; 10785 data.set(body, p); 10786 p += body.length; 10787 const crc = crc32(data, offset + 4, p); 10788 data[p] = crc >> 24 & 0xff; 10789 data[p + 1] = crc >> 16 & 0xff; 10790 data[p + 2] = crc >> 8 & 0xff; 10791 data[p + 3] = crc & 0xff; 10792 } 10793 function adler32(data, start, end) { 10794 let a = 1; 10795 let b = 0; 10796 for (let i = start; i < end; ++i) { 10797 a = (a + (data[i] & 0xff)) % 65521; 10798 b = (b + a) % 65521; 10799 } 10800 return b << 16 | a; 10801 } 10802 function deflateSync(literals) { 10803 if (!_util.isNodeJS) { 10804 return deflateSyncUncompressed(literals); 10805 } 10806 try { 10807 const input = parseInt(process.versions.node) >= 8 ? literals : Buffer.from(literals); 10808 const output = require("zlib").deflateSync(input, { 10809 level: 9 10810 }); 10811 return output instanceof Uint8Array ? output : new Uint8Array(output); 10812 } catch (e) { 10813 (0, _util.warn)("Not compressing PNG because zlib.deflateSync is unavailable: " + e); 10814 } 10815 return deflateSyncUncompressed(literals); 10816 } 10817 function deflateSyncUncompressed(literals) { 10818 let len = literals.length; 10819 const maxBlockLength = 0xffff; 10820 const deflateBlocks = Math.ceil(len / maxBlockLength); 10821 const idat = new Uint8Array(2 + len + deflateBlocks * 5 + 4); 10822 let pi = 0; 10823 idat[pi++] = 0x78; 10824 idat[pi++] = 0x9c; 10825 let pos = 0; 10826 while (len > maxBlockLength) { 10827 idat[pi++] = 0x00; 10828 idat[pi++] = 0xff; 10829 idat[pi++] = 0xff; 10830 idat[pi++] = 0x00; 10831 idat[pi++] = 0x00; 10832 idat.set(literals.subarray(pos, pos + maxBlockLength), pi); 10833 pi += maxBlockLength; 10834 pos += maxBlockLength; 10835 len -= maxBlockLength; 10836 } 10837 idat[pi++] = 0x01; 10838 idat[pi++] = len & 0xff; 10839 idat[pi++] = len >> 8 & 0xff; 10840 idat[pi++] = ~len & 0xffff & 0xff; 10841 idat[pi++] = (~len & 0xffff) >> 8 & 0xff; 10842 idat.set(literals.subarray(pos), pi); 10843 pi += literals.length - pos; 10844 const adler = adler32(literals, 0, literals.length); 10845 idat[pi++] = adler >> 24 & 0xff; 10846 idat[pi++] = adler >> 16 & 0xff; 10847 idat[pi++] = adler >> 8 & 0xff; 10848 idat[pi++] = adler & 0xff; 10849 return idat; 10850 } 10851 function encode(imgData, kind, forceDataSchema, isMask) { 10852 const width = imgData.width; 10853 const height = imgData.height; 10854 let bitDepth, colorType, lineSize; 10855 const bytes = imgData.data; 10856 switch (kind) { 10857 case _util.ImageKind.GRAYSCALE_1BPP: 10858 colorType = 0; 10859 bitDepth = 1; 10860 lineSize = width + 7 >> 3; 10861 break; 10862 case _util.ImageKind.RGB_24BPP: 10863 colorType = 2; 10864 bitDepth = 8; 10865 lineSize = width * 3; 10866 break; 10867 case _util.ImageKind.RGBA_32BPP: 10868 colorType = 6; 10869 bitDepth = 8; 10870 lineSize = width * 4; 10871 break; 10872 default: 10873 throw new Error("invalid format"); 10874 } 10875 const literals = new Uint8Array((1 + lineSize) * height); 10876 let offsetLiterals = 0, 10877 offsetBytes = 0; 10878 for (let y = 0; y < height; ++y) { 10879 literals[offsetLiterals++] = 0; 10880 literals.set(bytes.subarray(offsetBytes, offsetBytes + lineSize), offsetLiterals); 10881 offsetBytes += lineSize; 10882 offsetLiterals += lineSize; 10883 } 10884 if (kind === _util.ImageKind.GRAYSCALE_1BPP && isMask) { 10885 offsetLiterals = 0; 10886 for (let y = 0; y < height; y++) { 10887 offsetLiterals++; 10888 for (let i = 0; i < lineSize; i++) { 10889 literals[offsetLiterals++] ^= 0xff; 10890 } 10891 } 10892 } 10893 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]); 10894 const idat = deflateSync(literals); 10895 const pngLength = PNG_HEADER.length + CHUNK_WRAPPER_SIZE * 3 + ihdr.length + idat.length; 10896 const data = new Uint8Array(pngLength); 10897 let offset = 0; 10898 data.set(PNG_HEADER, offset); 10899 offset += PNG_HEADER.length; 10900 writePngChunk("IHDR", ihdr, data, offset); 10901 offset += CHUNK_WRAPPER_SIZE + ihdr.length; 10902 writePngChunk("IDATA", idat, data, offset); 10903 offset += CHUNK_WRAPPER_SIZE + idat.length; 10904 writePngChunk("IEND", new Uint8Array(0), data, offset); 10905 return createObjectURL(data, "image/png", forceDataSchema); 10906 } 10907 return function convertImgDataToPng(imgData, forceDataSchema, isMask) {
10908 const kind = imgData.kind === undefined ? _util.ImageKind.GRAYSCALE_1BPP : imgData.kind; 10909 return encode(imgData, kind, forceDataSchema, isMask); 10910 }; 10911}(); 10912class SVGExtraState { 10913 constructor() { 10914 this.fontSizeScale = 1; 10915 this.fontWeight = SVG_DEFAULTS.fontWeight; 10916 this.fontSize = 0; 10917 this.textMatrix = _util.IDENTITY_MATRIX; 10918 this.fontMatrix = _util.FONT_IDENTITY_MATRIX; 10919 this.leading = 0; 10920 this.textRenderingMode = _util.TextRenderingMode.FILL; 10921 this.textMatrixScale = 1; 10922 this.x = 0; 10923 this.y = 0; 10924 this.lineX = 0; 10925 this.lineY = 0; 10926 this.charSpacing = 0; 10927 this.wordSpacing = 0; 10928 this.textHScale = 1; 10929 this.textRise = 0; 10930 this.fillColor = SVG_DEFAULTS.fillColor; 10931 this.strokeColor = "#000000"; 10932 this.fillAlpha = 1; 10933 this.strokeAlpha = 1; 10934 this.lineWidth = 1; 10935 this.lineJoin = ""; 10936 this.lineCap = ""; 10937 this.miterLimit = 0; 10938 this.dashArray = []; 10939 this.dashPhase = 0; 10940 this.dependencies = []; 10941 this.activeClipUrl = null; 10942 this.clipGroup = null; 10943 this.maskId = ""; 10944 } 10945 clone() { 10946 return Object.create(this); 10947 } 10948 setCurrentPoint(x, y) { 10949 this.x = x; 10950 this.y = y; 10951 } 10952} 10953function opListToTree(opList) { 10954 let opTree = []; 10955 const tmp = []; 10956 for (const opListElement of opList) { 10957 if (opListElement.fn === "save") { 10958 opTree.push({ 10959 fnId: 92, 10960 fn: "group", 10961 items: [] 10962 }); 10963 tmp.push(opTree); 10964 opTree = opTree.at(-1).items; 10965 continue; 10966 } 10967 if (opListElement.fn === "restore") { 10968 opTree = tmp.pop(); 10969 } else { 10970 opTree.push(opListElement); 10971 } 10972 } 10973 return opTree; 10974} 10975function pf(value) { 10976 if (Number.isInteger(value)) { 10977 return value.toString(); 10978 } 10979 const s = value.toFixed(10); 10980 let i = s.length - 1; 10981 if (s[i] !== "0") { 10982 return s; 10983 } 10984 do { 10985 i--; 10986 } while (s[i] === "0"); 10987 return s.substring(0, s[i] === "." ? i : i + 1); 10988} 10989function pm(m) { 10990 if (m[4] === 0 && m[5] === 0) { 10991 if (m[1] === 0 && m[2] === 0) { 10992 if (m[0] === 1 && m[3] === 1) { 10993 return ""; 10994 } 10995 return `scale(${pf(m[0])} ${pf(m[3])})`; 10996 } 10997 if (m[0] === m[3] && m[1] === -m[2]) { 10998 const a = Math.acos(m[0]) * 180 / Math.PI; 10999 return `rotate(${pf(a)})`; 11000 } 11001 } else if (m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1) { 11002 return `translate(${pf(m[4])} ${pf(m[5])})`; 11003 } 11004 return `matrix(${pf(m[0])} ${pf(m[1])} ${pf(m[2])} ${pf(m[3])} ${pf(m[4])} ` + `${pf(m[5])})`; 11005} 11006let clipCount = 0; 11007let maskCount = 0; 11008let shadingCount = 0; 11009class SVGGraphics { 11010 constructor(commonObjs, objs, forceDataSchema = false) { 11011 (0, _display_utils.deprecated)("The SVG back-end is no longer maintained and *may* be removed in the future."); 11012 this.svgFactory = new _display_utils.DOMSVGFactory(); 11013 this.current = new SVGExtraState(); 11014 this.transformMatrix = _util.IDENTITY_MATRIX; 11015 this.transformStack = []; 11016 this.extraStack = []; 11017 this.commonObjs = commonObjs; 11018 this.objs = objs; 11019 this.pendingClip = null; 11020 this.pendingEOFill = false; 11021 this.embedFonts = false; 11022 this.embeddedFonts = Object.create(null); 11023 this.cssStyle = null; 11024 this.forceDataSchema = !!forceDataSchema; 11025 this._operatorIdMapping = []; 11026 for (const op in _util.OPS) { 11027 this._operatorIdMapping[_util.OPS[op]] = op; 11028 } 11029 } 11030 getObject(data, fallback = null) { 11031 if (typeof data === "string") { 11032 return data.startsWith("g_") ? this.commonObjs.get(data) : this.objs.get(data); 11033 } 11034 return fallback; 11035 } 11036 save() { 11037 this.transformStack.push(this.transformMatrix); 11038 const old = this.current; 11039 this.extraStack.push(old); 11040 this.current = old.clone(); 11041 } 11042 restore() { 11043 this.transformMatrix = this.transformStack.pop(); 11044 this.current = this.extraStack.pop(); 11045 this.pendingClip = null; 11046 this.tgrp = null; 11047 } 11048 group(items) { 11049 this.save(); 11050 this.executeOpTree(items); 11051 this.restore(); 11052 } 11053 loadDependencies(operatorList) { 11054 const fnArray = operatorList.fnArray; 11055 const argsArray = operatorList.argsArray; 11056 for (let i = 0, ii = fnArray.length; i < ii; i++) { 11057 if (fnArray[i] !== _util.OPS.dependency) { 11058 continue; 11059 } 11060 for (const obj of argsArray[i]) { 11061 const objsPool = obj.startsWith("g_") ? this.commonObjs : this.objs; 11062 const promise = new Promise(resolve => { 11063 objsPool.get(obj, resolve); 11064 }); 11065 this.current.dependencies.push(promise); 11066 } 11067 } 11068 return Promise.all(this.current.dependencies); 11069 } 11070 transform(a, b, c, d, e, f) { 11071 const transformMatrix = [a, b, c, d, e, f]; 11072 this.transformMatrix = _util.Util.transform(this.transformMatrix, transformMatrix); 11073 this.tgrp = null; 11074 } 11075 getSVG(operatorList, viewport) { 11076 this.viewport = viewport; 11077 const svgElement = this._initialize(viewport); 11078 return this.loadDependencies(operatorList).then(() => { 11079 this.transformMatrix = _util.IDENTITY_MATRIX; 11080 this.executeOpTree(this.convertOpList(operatorList)); 11081 return svgElement; 11082 }); 11083 } 11084 convertOpList(operatorList) { 11085 const operatorIdMapping = this._operatorIdMapping; 11086 const argsArray = operatorList.argsArray; 11087 const fnArray = operatorList.fnArray; 11088 const opList = []; 11089 for (let i = 0, ii = fnArray.length; i < ii; i++) { 11090 const fnId = fnArray[i]; 11091 opList.push({ 11092 fnId, 11093 fn: operatorIdMapping[fnId], 11094 args: argsArray[i] 11095 }); 11096 } 11097 return opListToTree(opList); 11098 } 11099 executeOpTree(opTree) { 11100 for (const opTreeElement of opTree) { 11101 const fn = opTreeElement.fn; 11102 const fnId = opTreeElement.fnId; 11103 const args = opTreeElement.args;
11104 switch (fnId | 0) { 11105 case _util.OPS.beginText: 11106 this.beginText(); 11107 break; 11108 case _util.OPS.dependency: 11109 break; 11110 case _util.OPS.setLeading: 11111 this.setLeading(args); 11112 break; 11113 case _util.OPS.setLeadingMoveText: 11114 this.setLeadingMoveText(args[0], args[1]); 11115 break; 11116 case _util.OPS.setFont: 11117 this.setFont(args); 11118 break; 11119 case _util.OPS.showText: 11120 this.showText(args[0]); 11121 break; 11122 case _util.OPS.showSpacedText: 11123 this.showText(args[0]); 11124 break; 11125 case _util.OPS.endText: 11126 this.endText(); 11127 break; 11128 case _util.OPS.moveText: 11129 this.moveText(args[0], args[1]); 11130 break; 11131 case _util.OPS.setCharSpacing: 11132 this.setCharSpacing(args[0]); 11133 break; 11134 case _util.OPS.setWordSpacing: 11135 this.setWordSpacing(args[0]); 11136 break; 11137 case _util.OPS.setHScale: 11138 this.setHScale(args[0]); 11139 break; 11140 case _util.OPS.setTextMatrix: 11141 this.setTextMatrix(args[0], args[1], args[2], args[3], args[4], args[5]); 11142 break; 11143 case _util.OPS.setTextRise: 11144 this.setTextRise(args[0]); 11145 break; 11146 case _util.OPS.setTextRenderingMode: 11147 this.setTextRenderingMode(args[0]); 11148 break; 11149 case _util.OPS.setLineWidth: 11150 this.setLineWidth(args[0]); 11151 break; 11152 case _util.OPS.setLineJoin: 11153 this.setLineJoin(args[0]); 11154 break; 11155 case _util.OPS.setLineCap: 11156 this.setLineCap(args[0]); 11157 break; 11158 case _util.OPS.setMiterLimit: 11159 this.setMiterLimit(args[0]); 11160 break; 11161 case _util.OPS.setFillRGBColor: 11162 this.setFillRGBColor(args[0], args[1], args[2]); 11163 break; 11164 case _util.OPS.setStrokeRGBColor: 11165 this.setStrokeRGBColor(args[0], args[1], args[2]); 11166 break; 11167 case _util.OPS.setStrokeColorN: 11168 this.setStrokeColorN(args); 11169 break; 11170 case _util.OPS.setFillColorN: 11171 this.setFillColorN(args); 11172 break; 11173 case _util.OPS.shadingFill: 11174 this.shadingFill(args[0]); 11175 break; 11176 case _util.OPS.setDash: 11177 this.setDash(args[0], args[1]); 11178 break; 11179 case _util.OPS.setRenderingIntent: 11180 this.setRenderingIntent(args[0]); 11181 break; 11182 case _util.OPS.setFlatness: 11183 this.setFlatness(args[0]); 11184 break; 11185 case _util.OPS.setGState: 11186 this.setGState(args[0]); 11187 break; 11188 case _util.OPS.fill: 11189 this.fill(); 11190 break; 11191 case _util.OPS.eoFill: 11192 this.eoFill(); 11193 break; 11194 case _util.OPS.stroke: 11195 this.stroke(); 11196 break; 11197 case _util.OPS.fillStroke: 11198 this.fillStroke(); 11199 break; 11200 case _util.OPS.eoFillStroke: 11201 this.eoFillStroke(); 11202 break; 11203 case _util.OPS.clip: 11204 this.clip("nonzero"); 11205 break; 11206 case _util.OPS.eoClip: 11207 this.clip("evenodd"); 11208 break; 11209 case _util.OPS.paintSolidColorImageMask: 11210 this.paintSolidColorImageMask(); 11211 break; 11212 case _util.OPS.paintImageXObject: 11213 this.paintImageXObject(args[0]); 11214 break; 11215 case _util.OPS.paintInlineImageXObject: 11216 this.paintInlineImageXObject(args[0]); 11217 break; 11218 case _util.OPS.paintImageMaskXObject: 11219 this.paintImageMaskXObject(args[0]); 11220 break; 11221 case _util.OPS.paintFormXObjectBegin: 11222 this.paintFormXObjectBegin(args[0], args[1]); 11223 break; 11224 case _util.OPS.paintFormXObjectEnd: 11225 this.paintFormXObjectEnd(); 11226 break; 11227 case _util.OPS.closePath: 11228 this.closePath(); 11229 break; 11230 case _util.OPS.closeStroke: 11231 this.closeStroke(); 11232 break; 11233 case _util.OPS.closeFillStroke: 11234 this.closeFillStroke(); 11235 break; 11236 case _util.OPS.closeEOFillStroke: 11237 this.closeEOFillStroke(); 11238 break; 11239 case _util.OPS.nextLine: 11240 this.nextLine(); 11241 break; 11242 case _util.OPS.transform: 11243 this.transform(args[0], args[1], args[2], args[3], args[4], args[5]); 11244 break; 11245 case _util.OPS.constructPath: 11246 this.constructPath(args[0], args[1]); 11247 break; 11248 case _util.OPS.endPath: 11249 this.endPath(); 11250 break; 11251 case 92: 11252 this.group(opTreeElement.items); 11253 break; 11254 default: 11255 (0, _util.warn)(`Unimplemented operator ${fn}`); 11256 break; 11257 } 11258 } 11259 } 11260 setWordSpacing(wordSpacing) { 11261 this.current.wordSpacing = wordSpacing; 11262 } 11263 setCharSpacing(charSpacing) { 11264 this.current.charSpacing = charSpacing; 11265 } 11266 nextLine() { 11267 this.moveText(0, this.current.leading); 11268 } 11269 setTextMatrix(a, b, c, d, e, f) { 11270 const current = this.current; 11271 current.textMatrix = current.lineMatrix = [a, b, c, d, e, f]; 11272 current.textMatrixScale = Math.hypot(a, b); 11273 current.x = current.lineX = 0; 11274 current.y = current.lineY = 0; 11275 current.xcoords = []; 11276 current.ycoords = []; 11277 current.tspan = this.svgFactory.createElement("svg:tspan"); 11278 current.tspan.setAttributeNS(null, "font-family", current.fontFamily); 11279 current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`); 11280 current.tspan.setAttributeNS(null, "y", pf(-current.y)); 11281 current.txtElement = this.svgFactory.createElement("svg:text"); 11282 current.txtElement.append(current.tspan); 11283 } 11284 beginText() { 11285 const current = this.current; 11286 current.x = current.lineX = 0; 11287 current.y = current.lineY = 0; 11288 current.textMatrix = _util.IDENTITY_MATRIX; 11289 current.lineMatrix = _util.IDENTITY_MATRIX; 11290 current.textMatrixScale = 1; 11291 current.tspan = this.svgFactory.createElement("svg:tspan"); 11292 current.txtElement = this.svgFactory.createElement("svg:text"); 11293 current.txtgrp = this.svgFactory.createElement("svg:g"); 11294 current.xcoords = []; 11295 current.ycoords = []; 11296 } 11297 moveText(x, y) { 11298 const current = this.current; 11299 current.x = current.lineX += x; 11300 current.y = current.lineY += y; 11301 current.xcoords = []; 11302 current.ycoords = []; 11303 current.tspan = this.svgFactory.createElement("svg:tspan"); 11304 current.tspan.setAttributeNS(null, "font-family", current.fontFamily); 11305 current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`); 11306 current.tspan.setAttributeNS(null, "y", pf(-current.y)); 11307 } 11308 showText(glyphs) { 11309 const current = this.current; 11310 const font = current.font; 11311 const fontSize = current.fontSize; 11312 if (fontSize === 0) { 11313 return; 11314 } 11315 const fontSizeScale = current.fontSizeScale; 11316 const charSpacing = current.charSpacing; 11317 const wordSpacing = current.wordSpacing; 11318 const fontDirection = current.fontDirection; 11319 const textHScale = current.textHScale * fontDirection; 11320 const vertical = font.vertical; 11321 const spacingDir = vertical ? 1 : -1; 11322 const defaultVMetrics = font.defaultVMetrics; 11323 const widthAdvanceScale = fontSize * current.fontMatrix[0]; 11324 let x = 0; 11325 for (const glyph of glyphs) { 11326 if (glyph === null) { 11327 x += fontDirection * wordSpacing; 11328 continue; 11329 }
11329 else if (typeof glyph === "number") { 11330 x += spacingDir * glyph * fontSize / 1000; 11331 continue; 11332 } 11333 const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 11334 const character = glyph.fontChar; 11335 let scaledX, scaledY; 11336 let width = glyph.width; 11337 if (vertical) { 11338 let vx; 11339 const vmetric = glyph.vmetric || defaultVMetrics; 11340 vx = glyph.vmetric ? vmetric[1] : width * 0.5; 11341 vx = -vx * widthAdvanceScale; 11342 const vy = vmetric[2] * widthAdvanceScale; 11343 width = vmetric ? -vmetric[0] : width; 11344 scaledX = vx / fontSizeScale; 11345 scaledY = (x + vy) / fontSizeScale; 11346 } else { 11347 scaledX = x / fontSizeScale; 11348 scaledY = 0; 11349 } 11350 if (glyph.isInFont || font.missingFile) { 11351 current.xcoords.push(current.x + scaledX); 11352 if (vertical) { 11353 current.ycoords.push(-current.y + scaledY); 11354 } 11355 current.tspan.textContent += character; 11356 } else {} 11357 const charWidth = vertical ? width * widthAdvanceScale - spacing * fontDirection : width * widthAdvanceScale + spacing * fontDirection; 11358 x += charWidth; 11359 } 11360 current.tspan.setAttributeNS(null, "x", current.xcoords.map(pf).join(" ")); 11361 if (vertical) { 11362 current.tspan.setAttributeNS(null, "y", current.ycoords.map(pf).join(" ")); 11363 } else { 11364 current.tspan.setAttributeNS(null, "y", pf(-current.y)); 11365 } 11366 if (vertical) { 11367 current.y -= x; 11368 } else { 11369 current.x += x * textHScale; 11370 } 11371 current.tspan.setAttributeNS(null, "font-family", current.fontFamily); 11372 current.tspan.setAttributeNS(null, "font-size", `${pf(current.fontSize)}px`); 11373 if (current.fontStyle !== SVG_DEFAULTS.fontStyle) { 11374 current.tspan.setAttributeNS(null, "font-style", current.fontStyle); 11375 } 11376 if (current.fontWeight !== SVG_DEFAULTS.fontWeight) { 11377 current.tspan.setAttributeNS(null, "font-weight", current.fontWeight); 11378 } 11379 const fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; 11380 if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 11381 if (current.fillColor !== SVG_DEFAULTS.fillColor) { 11382 current.tspan.setAttributeNS(null, "fill", current.fillColor); 11383 } 11384 if (current.fillAlpha < 1) { 11385 current.tspan.setAttributeNS(null, "fill-opacity", current.fillAlpha); 11386 } 11387 } else if (current.textRenderingMode === _util.TextRenderingMode.ADD_TO_PATH) { 11388 current.tspan.setAttributeNS(null, "fill", "transparent"); 11389 } else { 11390 current.tspan.setAttributeNS(null, "fill", "none"); 11391 } 11392 if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { 11393 const lineWidthScale = 1 / (current.textMatrixScale || 1); 11394 this._setStrokeAttributes(current.tspan, lineWidthScale); 11395 } 11396 let textMatrix = current.textMatrix; 11397 if (current.textRise !== 0) { 11398 textMatrix = textMatrix.slice(); 11399 textMatrix[5] += current.textRise; 11400 } 11401 current.txtElement.setAttributeNS(null, "transform", `${pm(textMatrix)} scale(${pf(textHScale)}, -1)`); 11402 current.txtElement.setAttributeNS(XML_NS, "xml:space", "preserve"); 11403 current.txtElement.append(current.tspan); 11404 current.txtgrp.append(current.txtElement); 11405 this._ensureTransformGroup().append(current.txtElement); 11406 } 11407 setLeadingMoveText(x, y) { 11408 this.setLeading(-y); 11409 this.moveText(x, y); 11410 } 11411 addFontStyle(fontObj) { 11412 if (!fontObj.data) { 11413 throw new Error("addFontStyle: No font data available, " + 'ensure that the "fontExtraProperties" API parameter is set.'); 11414 } 11415 if (!this.cssStyle) { 11416 this.cssStyle = this.svgFactory.createElement("svg:style"); 11417 this.cssStyle.setAttributeNS(null, "type", "text/css"); 11418 this.defs.append(this.cssStyle); 11419 } 11420 const url = createObjectURL(fontObj.data, fontObj.mimetype, this.forceDataSchema); 11421 this.cssStyle.textContent += `@font-face { font-family: "${fontObj.loadedName}";` + ` src: url(${url}); }\n`; 11422 } 11423 setFont(details) { 11424 const current = this.current; 11425 const fontObj = this.commonObjs.get(details[0]); 11426 let size = details[1]; 11427 current.font = fontObj; 11428 if (this.embedFonts && !fontObj.missingFile && !this.embeddedFonts[fontObj.loadedName]) { 11429 this.addFontStyle(fontObj); 11430 this.embeddedFonts[fontObj.loadedName] = fontObj; 11431 } 11432 current.fontMatrix = fontObj.fontMatrix || _util.FONT_IDENTITY_MATRIX; 11433 let bold = "normal"; 11434 if (fontObj.black) { 11435 bold = "900"; 11436 } else if (fontObj.bold) { 11437 bold = "bold"; 11438 } 11439 const italic = fontObj.italic ? "italic" : "normal"; 11440 if (size < 0) { 11441 size = -size; 11442 current.fontDirection = -1; 11443 } else { 11444 current.fontDirection = 1; 11445 } 11446 current.fontSize = size; 11447 current.fontFamily = fontObj.loadedName; 11448 current.fontWeight = bold; 11449 current.fontStyle = italic; 11450 current.tspan = this.svgFactory.createElement("svg:tspan"); 11451 current.tspan.setAttributeNS(null, "y", pf(-current.y)); 11452 current.xcoords = []; 11453 current.ycoords = []; 11454 } 11455 endText() { 11456 const current = this.current; 11457 if (current.textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG && current.txtElement?.hasChildNodes()) { 11458 current.element = current.txtElement; 11459 this.clip("nonzero"); 11460 this.endPath(); 11461 } 11462 } 11463 setLineWidth(width) { 11464 if (width > 0) { 11465 this.current.lineWidth = width; 11466 } 11467 } 11468 setLineCap(style) { 11469 this.current.lineCap = LINE_CAP_STYLES[style]; 11470 } 11471 setLineJoin(style) { 11472 this.current.lineJoin = LINE_JOIN_STYLES[style]; 11473 } 11474 setMiterLimit(limit) { 11475 this.current.miterLimit = limit; 11476 } 11477 setStrokeAlpha(strokeAlpha) { 11478 this.current.strokeAlpha = strokeAlpha; 11479 } 11480 setStrokeRGBColor(r, g, b) { 11481 this.current.strokeColor = _util.Util.makeHexColor(r, g, b); 11482 } 11483 setFillAlpha(fillAlpha) { 11484 this.current.fillAlpha = fillAlpha; 11485 } 11486 setFillRGBColor(r, g, b) { 11487 this.current.fillColor = _util.Util.makeHexColor(r, g, b); 11488 this.current.tspan = this.svgFactory.createElement("svg:tspan"); 11489 this.current.xcoords = []; 11490 this.current.ycoords = []; 11491 } 11492 setStrokeColorN(args) { 11493 this.current.strokeColor = this._makeColorN_Pattern(args); 11494 } 11495 setFillColorN(args) { 11496 this.current.fillColor = this._makeColorN_Pattern(args); 11497 } 11498 shadingFill(args) { 11499 const { 11500 width, 11501 height 11502 } = this.viewport; 11503 const inv = _util.Util.inverseTransform(this.transformMatrix); 11504 const [x0, y0, x1, y1] = _util.Util.getAxialAlignedBoundingBox([0, 0, width, height], inv); 11505 const rect = this.svgFactory.createElement("svg:rect"); 11506 rect.setAttributeNS(null, "x", x0); 11507 rect.setAttributeNS(null, "y", y0); 11508 rect.setAttributeNS(null, "width", x1 - x0); 11509 rect.setAttributeNS(null, "height", y1 - y0); 11510 rect.setAttributeNS(null, "fill", this._makeShadingPattern(args)); 11511 if (this.current.fillAlpha < 1) { 11512 rect.setAttributeNS(null, "fill-opacity", this.current.fillAlpha); 11513 } 11514 this._ensureTransformGroup().append(rect); 11515 } 11516 _makeColorN_Pattern(args) { 11517 if (args[0] === "TilingPattern") { 11518 return this._makeTilingPattern(args); 11519 } 11520 return this._makeShadingPattern(args); 11521 } 11522 _makeTilingPattern(args) { 11523 const color = args[1]; 11524 const operatorList = args[2]; 11525 const matrix = args[3] || _util.IDENTITY_MATRIX; 11526 const [x0, y0, x1, y1] = args[4]; 11527 const xstep = args[5]; 11528 const ystep = args[6]; 11529 const paintType = args[7]; 11530 const tilingId = `shading${shadingCount++}`; 11531 const [tx0, ty0, tx1, ty1] = _util.Util.normalizeRect([..._util.Util.applyTransform([x0, y0
11531], matrix), ..._util.Util.applyTransform([x1, y1], matrix)]); 11532 const [xscale, yscale] = _util.Util.singularValueDecompose2dScale(matrix); 11533 const txstep = xstep * xscale; 11534 const tystep = ystep * yscale; 11535 const tiling = this.svgFactory.createElement("svg:pattern"); 11536 tiling.setAttributeNS(null, "id", tilingId); 11537 tiling.setAttributeNS(null, "patternUnits", "userSpaceOnUse"); 11538 tiling.setAttributeNS(null, "width", txstep); 11539 tiling.setAttributeNS(null, "height", tystep); 11540 tiling.setAttributeNS(null, "x", `${tx0}`); 11541 tiling.setAttributeNS(null, "y", `${ty0}`); 11542 const svg = this.svg; 11543 const transformMatrix = this.transformMatrix; 11544 const fillColor = this.current.fillColor; 11545 const strokeColor = this.current.strokeColor; 11546 const bbox = this.svgFactory.create(tx1 - tx0, ty1 - ty0); 11547 this.svg = bbox; 11548 this.transformMatrix = matrix; 11549 if (paintType === 2) { 11550 const cssColor = _util.Util.makeHexColor(...color); 11551 this.current.fillColor = cssColor; 11552 this.current.strokeColor = cssColor; 11553 } 11554 this.executeOpTree(this.convertOpList(operatorList)); 11555 this.svg = svg; 11556 this.transformMatrix = transformMatrix; 11557 this.current.fillColor = fillColor; 11558 this.current.strokeColor = strokeColor; 11559 tiling.append(bbox.childNodes[0]); 11560 this.defs.append(tiling); 11561 return `url(#${tilingId})`; 11562 } 11563 _makeShadingPattern(args) { 11564 if (typeof args === "string") { 11565 args = this.objs.get(args); 11566 } 11567 switch (args[0]) { 11568 case "RadialAxial": 11569 const shadingId = `shading${shadingCount++}`; 11570 const colorStops = args[3]; 11571 let gradient; 11572 switch (args[1]) { 11573 case "axial": 11574 const point0 = args[4]; 11575 const point1 = args[5]; 11576 gradient = this.svgFactory.createElement("svg:linearGradient"); 11577 gradient.setAttributeNS(null, "id", shadingId); 11578 gradient.setAttributeNS(null, "gradientUnits", "userSpaceOnUse"); 11579 gradient.setAttributeNS(null, "x1", point0[0]); 11580 gradient.setAttributeNS(null, "y1", point0[1]); 11581 gradient.setAttributeNS(null, "x2", point1[0]); 11582 gradient.setAttributeNS(null, "y2", point1[1]); 11583 break; 11584 case "radial": 11585 const focalPoint = args[4]; 11586 const circlePoint = args[5]; 11587 const focalRadius = args[6]; 11588 const circleRadius = args[7]; 11589 gradient = this.svgFactory.createElement("svg:radialGradient"); 11590 gradient.setAttributeNS(null, "id", shadingId); 11591 gradient.setAttributeNS(null, "gradientUnits", "userSpaceOnUse"); 11592 gradient.setAttributeNS(null, "cx", circlePoint[0]); 11593 gradient.setAttributeNS(null, "cy", circlePoint[1]); 11594 gradient.setAttributeNS(null, "r", circleRadius); 11595 gradient.setAttributeNS(null, "fx", focalPoint[0]); 11596 gradient.setAttributeNS(null, "fy", focalPoint[1]); 11597 gradient.setAttributeNS(null, "fr", focalRadius); 11598 break; 11599 default: 11600 throw new Error(`Unknown RadialAxial type: ${args[1]}`); 11601 } 11602 for (const colorStop of colorStops) { 11603 const stop = this.svgFactory.createElement("svg:stop"); 11604 stop.setAttributeNS(null, "offset", colorStop[0]); 11605 stop.setAttributeNS(null, "stop-color", colorStop[1]); 11606 gradient.append(stop); 11607 } 11608 this.defs.append(gradient); 11609 return `url(#${shadingId})`; 11610 case "Mesh": 11611 (0, _util.warn)("Unimplemented pattern Mesh"); 11612 return null; 11613 case "Dummy": 11614 return "hotpink"; 11615 default: 11616 throw new Error(`Unknown IR type: ${args[0]}`); 11617 } 11618 } 11619 setDash(dashArray, dashPhase) { 11620 this.current.dashArray = dashArray; 11621 this.current.dashPhase = dashPhase; 11622 } 11623 constructPath(ops, args) { 11624 const current = this.current; 11625 let x = current.x, 11626 y = current.y; 11627 let d = []; 11628 let j = 0; 11629 for (const op of ops) { 11630 switch (op | 0) { 11631 case _util.OPS.rectangle: 11632 x = args[j++]; 11633 y = args[j++]; 11634 const width = args[j++]; 11635 const height = args[j++]; 11636 const xw = x + width; 11637 const yh = y + height; 11638 d.push("M", pf(x), pf(y), "L", pf(xw), pf(y), "L", pf(xw), pf(yh), "L", pf(x), pf(yh), "Z"); 11639 break; 11640 case _util.OPS.moveTo: 11641 x = args[j++]; 11642 y = args[j++]; 11643 d.push("M", pf(x), pf(y)); 11644 break; 11645 case _util.OPS.lineTo: 11646 x = args[j++]; 11647 y = args[j++]; 11648 d.push("L", pf(x), pf(y)); 11649 break; 11650 case _util.OPS.curveTo: 11651 x = args[j + 4]; 11652 y = args[j + 5]; 11653 d.push("C", pf(args[j]), pf(args[j + 1]), pf(args[j + 2]), pf(args[j + 3]), pf(x), pf(y)); 11654 j += 6; 11655 break; 11656 case _util.OPS.curveTo2: 11657 d.push("C", pf(x), pf(y), pf(args[j]), pf(args[j + 1]), pf(args[j + 2]), pf(args[j + 3])); 11658 x = args[j + 2]; 11659 y = args[j + 3]; 11660 j += 4; 11661 break; 11662 case _util.OPS.curveTo3: 11663 x = args[j + 2]; 11664 y = args[j + 3]; 11665 d.push("C", pf(args[j]), pf(args[j + 1]), pf(x), pf(y), pf(x), pf(y)); 11666 j += 4; 11667 break; 11668 case _util.OPS.closePath: 11669 d.push("Z"); 11670 break; 11671 } 11672 } 11673 d = d.join(" "); 11674 if (current.path && ops.length > 0 && ops[0] !== _util.OPS.rectangle && ops[0] !== _util.OPS.moveTo) { 11675 d = current.path.getAttributeNS(null, "d") + d; 11676 } else { 11677 current.path = this.svgFactory.createElement("svg:path"); 11678 this._ensureTransformGroup().append(current.path); 11679 } 11680 current.path.setAttributeNS(null, "d", d); 11681 current.path.setAttributeNS(null, "fill", "none"); 11682 current.element = current.path; 11683 current.setCurrentPoint(x, y); 11684 } 11685 endPath() { 11686 const current = this.current; 11687 current.path = null; 11688 if (!this.pendingClip) { 11689 return; 11690 } 11691 if (!current.element) { 11692 this.pendingClip = null; 11693 return; 11694 } 11695 const clipId = `clippath${clipCount++}`; 11696 const clipPath = this.svgFactory.createElement("svg:clipPath"); 11697 clipPath.setAttributeNS(null, "id", clipId); 11698 clipPath.setAttributeNS(null, "transform", pm(this.transformMatrix)); 11699 const clipElement = current.element.cloneNode(true); 11700 if (this.pendingClip === "evenodd") { 11701 clipElement.setAttributeNS(null, "clip-rule", "evenodd"); 11702 } else { 11703 clipElement.setAttributeNS(null, "clip-rule", "nonzero"); 11704 } 11705 this.pendingClip = null; 11706 clipPath.append(clipElement); 11707 this.defs.append(clipPath); 11708 if (current.activeClipUrl) { 11709 current.clipGroup = null; 11710 for (const prev of this.extraStack) { 11711 prev.clipGroup = null; 11712 } 11713 clipPath.setAttributeNS(null, "clip-path", current.activeClipUrl); 11714 } 11715 current.activeClipUrl = `url(#${clipId})`; 11716 this.tgrp = null; 11717 } 11718 clip(type) { 11719 this.pendingClip = type; 11720 } 11721 closePath() { 11722 const current = this.current; 11723 if (current.path) { 11724 const d = `${current.path.getAttributeNS(null, "d")}Z`; 11725 current.path.setAttributeNS(null, "d", d); 11726 } 11727 } 11728 setLeading(leading) { 11729 this.current.leading = -leading; 11730 } 11731 setTextRise(textRise) { 11732 this.current.textRise = textRise; 11733 } 11734 setTextRenderingMode(textRenderingMode) { 11735 this.current.textRenderingMode = textRenderingMode; 11736 } 11737 setHScale(scale) { 11738 this.current.textHScale = scale / 100; 11739 }
11740 setRenderingIntent(intent) {} 11741 setFlatness(flatness) {} 11742 setGState(states) { 11743 for (const [key, value] of states) { 11744 switch (key) { 11745 case "LW": 11746 this.setLineWidth(value); 11747 break; 11748 case "LC": 11749 this.setLineCap(value); 11750 break; 11751 case "LJ": 11752 this.setLineJoin(value); 11753 break; 11754 case "ML": 11755 this.setMiterLimit(value); 11756 break; 11757 case "D": 11758 this.setDash(value[0], value[1]); 11759 break; 11760 case "RI": 11761 this.setRenderingIntent(value); 11762 break; 11763 case "FL": 11764 this.setFlatness(value); 11765 break; 11766 case "Font": 11767 this.setFont(value); 11768 break; 11769 case "CA": 11770 this.setStrokeAlpha(value); 11771 break; 11772 case "ca": 11773 this.setFillAlpha(value); 11774 break; 11775 default: 11776 (0, _util.warn)(`Unimplemented graphic state operator ${key}`); 11777 break; 11778 } 11779 } 11780 } 11781 fill() { 11782 const current = this.current; 11783 if (current.element) { 11784 current.element.setAttributeNS(null, "fill", current.fillColor); 11785 current.element.setAttributeNS(null, "fill-opacity", current.fillAlpha); 11786 this.endPath(); 11787 } 11788 } 11789 stroke() { 11790 const current = this.current; 11791 if (current.element) { 11792 this._setStrokeAttributes(current.element); 11793 current.element.setAttributeNS(null, "fill", "none"); 11794 this.endPath(); 11795 } 11796 } 11797 _setStrokeAttributes(element, lineWidthScale = 1) { 11798 const current = this.current; 11799 let dashArray = current.dashArray; 11800 if (lineWidthScale !== 1 && dashArray.length > 0) { 11801 dashArray = dashArray.map(function (value) { 11802 return lineWidthScale * value; 11803 }); 11804 } 11805 element.setAttributeNS(null, "stroke", current.strokeColor); 11806 element.setAttributeNS(null, "stroke-opacity", current.strokeAlpha); 11807 element.setAttributeNS(null, "stroke-miterlimit", pf(current.miterLimit)); 11808 element.setAttributeNS(null, "stroke-linecap", current.lineCap); 11809 element.setAttributeNS(null, "stroke-linejoin", current.lineJoin); 11810 element.setAttributeNS(null, "stroke-width", pf(lineWidthScale * current.lineWidth) + "px"); 11811 element.setAttributeNS(null, "stroke-dasharray", dashArray.map(pf).join(" ")); 11812 element.setAttributeNS(null, "stroke-dashoffset", pf(lineWidthScale * current.dashPhase) + "px"); 11813 } 11814 eoFill() { 11815 this.current.element?.setAttributeNS(null, "fill-rule", "evenodd"); 11816 this.fill(); 11817 } 11818 fillStroke() { 11819 this.stroke(); 11820 this.fill(); 11821 } 11822 eoFillStroke() { 11823 this.current.element?.setAttributeNS(null, "fill-rule", "evenodd"); 11824 this.fillStroke(); 11825 } 11826 closeStroke() { 11827 this.closePath(); 11828 this.stroke(); 11829 } 11830 closeFillStroke() { 11831 this.closePath(); 11832 this.fillStroke(); 11833 } 11834 closeEOFillStroke() { 11835 this.closePath(); 11836 this.eoFillStroke(); 11837 } 11838 paintSolidColorImageMask() { 11839 const rect = this.svgFactory.createElement("svg:rect"); 11840 rect.setAttributeNS(null, "x", "0"); 11841 rect.setAttributeNS(null, "y", "0"); 11842 rect.setAttributeNS(null, "width", "1px"); 11843 rect.setAttributeNS(null, "height", "1px"); 11844 rect.setAttributeNS(null, "fill", this.current.fillColor); 11845 this._ensureTransformGroup().append(rect); 11846 } 11847 paintImageXObject(objId) { 11848 const imgData = this.getObject(objId); 11849 if (!imgData) { 11850 (0, _util.warn)(`Dependent image with object ID ${objId} is not ready yet`); 11851 return; 11852 } 11853 this.paintInlineImageXObject(imgData); 11854 } 11855 paintInlineImageXObject(imgData, mask) { 11856 const width = imgData.width; 11857 const height = imgData.height; 11858 const imgSrc = convertImgDataToPng(imgData, this.forceDataSchema, !!mask); 11859 const cliprect = this.svgFactory.createElement("svg:rect"); 11860 cliprect.setAttributeNS(null, "x", "0"); 11861 cliprect.setAttributeNS(null, "y", "0"); 11862 cliprect.setAttributeNS(null, "width", pf(width)); 11863 cliprect.setAttributeNS(null, "height", pf(height)); 11864 this.current.element = cliprect; 11865 this.clip("nonzero"); 11866 const imgEl = this.svgFactory.createElement("svg:image"); 11867 imgEl.setAttributeNS(XLINK_NS, "xlink:href", imgSrc); 11868 imgEl.setAttributeNS(null, "x", "0"); 11869 imgEl.setAttributeNS(null, "y", pf(-height)); 11870 imgEl.setAttributeNS(null, "width", pf(width) + "px"); 11871 imgEl.setAttributeNS(null, "height", pf(height) + "px"); 11872 imgEl.setAttributeNS(null, "transform", `scale(${pf(1 / width)} ${pf(-1 / height)})`); 11873 if (mask) { 11874 mask.append(imgEl); 11875 } else { 11876 this._ensureTransformGroup().append(imgEl); 11877 } 11878 } 11879 paintImageMaskXObject(img) { 11880 const imgData = this.getObject(img.data, img); 11881 if (imgData.bitmap) { 11882 (0, _util.warn)("paintImageMaskXObject: ImageBitmap support is not implemented, " + "ensure that the `isOffscreenCanvasSupported` API parameter is disabled."); 11883 return; 11884 } 11885 const current = this.current; 11886 const width = imgData.width; 11887 const height = imgData.height; 11888 const fillColor = current.fillColor; 11889 current.maskId = `mask${maskCount++}`; 11890 const mask = this.svgFactory.createElement("svg:mask"); 11891 mask.setAttributeNS(null, "id", current.maskId); 11892 const rect = this.svgFactory.createElement("svg:rect"); 11893 rect.setAttributeNS(null, "x", "0"); 11894 rect.setAttributeNS(null, "y", "0"); 11895 rect.setAttributeNS(null, "width", pf(width)); 11896 rect.setAttributeNS(null, "height", pf(height)); 11897 rect.setAttributeNS(null, "fill", fillColor); 11898 rect.setAttributeNS(null, "mask", `url(#${current.maskId})`); 11899 this.defs.append(mask); 11900 this._ensureTransformGroup().append(rect); 11901 this.paintInlineImageXObject(imgData, mask); 11902 } 11903 paintFormXObjectBegin(matrix, bbox) { 11904 if (Array.isArray(matrix) && matrix.length === 6) {
11905 this.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); 11906 } 11907 if (bbox) { 11908 const width = bbox[2] - bbox[0]; 11909 const height = bbox[3] - bbox[1]; 11910 const cliprect = this.svgFactory.createElement("svg:rect"); 11911 cliprect.setAttributeNS(null, "x", bbox[0]); 11912 cliprect.setAttributeNS(null, "y", bbox[1]); 11913 cliprect.setAttributeNS(null, "width", pf(width)); 11914 cliprect.setAttributeNS(null, "height", pf(height)); 11915 this.current.element = cliprect; 11916 this.clip("nonzero"); 11917 this.endPath(); 11918 } 11919 } 11920 paintFormXObjectEnd() {} 11921 _initialize(viewport) { 11922 const svg = this.svgFactory.create(viewport.width, viewport.height); 11923 const definitions = this.svgFactory.createElement("svg:defs"); 11924 svg.append(definitions); 11925 this.defs = definitions; 11926 const rootGroup = this.svgFactory.createElement("svg:g"); 11927 rootGroup.setAttributeNS(null, "transform", pm(viewport.transform)); 11928 svg.append(rootGroup); 11929 this.svg = rootGroup; 11930 return svg; 11931 } 11932 _ensureClipGroup() { 11933 if (!this.current.clipGroup) { 11934 const clipGroup = this.svgFactory.createElement("svg:g"); 11935 clipGroup.setAttributeNS(null, "clip-path", this.current.activeClipUrl); 11936 this.svg.append(clipGroup); 11937 this.current.clipGroup = clipGroup; 11938 } 11939 return this.current.clipGroup; 11940 } 11941 _ensureTransformGroup() { 11942 if (!this.tgrp) { 11943 this.tgrp = this.svgFactory.createElement("svg:g"); 11944 this.tgrp.setAttributeNS(null, "transform", pm(this.transformMatrix)); 11945 if (this.current.activeClipUrl) { 11946 this._ensureClipGroup().append(this.tgrp); 11947 } else { 11948 this.svg.append(this.tgrp); 11949 } 11950 } 11951 return this.tgrp; 11952 } 11953} 11954exports.SVGGraphics = SVGGraphics; 11955 11956/***/ }), 11957/* 25 */ 11958/***/ ((__unused_webpack_module, exports) => { 11959 11960 11961 11962Object.defineProperty(exports, "__esModule", ({ 11963 value: true 11964})); 11965exports.XfaText = void 0; 11966class XfaText { 11967 static textContent(xfa) { 11968 const items = []; 11969 const output = { 11970 items, 11971 styles: Object.create(null) 11972 }; 11973 function walk(node) { 11974 if (!node) { 11975 return; 11976 } 11977 let str = null; 11978 const name = node.name; 11979 if (name === "#text") { 11980 str = node.value; 11981 } else if (!XfaText.shouldBuildText(name)) { 11982 return; 11983 } else if (node?.attributes?.textContent) { 11984 str = node.attributes.textContent; 11985 } else if (node.value) { 11986 str = node.value; 11987 } 11988 if (str !== null) { 11989 items.push({ 11990 str 11991 }); 11992 } 11993 if (!node.children) { 11994 return; 11995 } 11996 for (const child of node.children) { 11997 walk(child); 11998 } 11999 } 12000 walk(xfa); 12001 return output; 12002 } 12003 static shouldBuildText(name) { 12004 return !(name === "textarea" || name === "input" || name === "option" || name === "select"); 12005 } 12006} 12007exports.XfaText = XfaText; 12008 12009/***/ }), 12010/* 26 */ 12011/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 12012 12013 12014 12015Object.defineProperty(exports, "__esModule", ({ 12016 value: true 12017})); 12018exports.TextLayerRenderTask = void 0; 12019exports.renderTextLayer = renderTextLayer; 12020exports.updateTextLayer = updateTextLayer; 12021var _util = __w_pdfjs_require__(1); 12022var _display_utils = __w_pdfjs_require__(6); 12023const MAX_TEXT_DIVS_TO_RENDER = 100000; 12024const DEFAULT_FONT_SIZE = 30; 12025const DEFAULT_FONT_ASCENT = 0.8; 12026const ascentCache = new Map(); 12027function getCtx(size, isOffscreenCanvasSupported) { 12028 let ctx; 12029 if (isOffscreenCanvasSupported && _util.FeatureTest.isOffscreenCanvasSupported) { 12030 ctx = new OffscreenCanvas(size, size).getContext("2d", { 12031 alpha: false 12032 }); 12033 } else { 12034 const canvas = document.createElement("canvas"); 12035 canvas.width = canvas.height = size; 12036 ctx = canvas.getContext("2d", { 12037 alpha: false 12038 }); 12039 } 12040 return ctx; 12041} 12042function getAscent(fontFamily, isOffscreenCanvasSupported) { 12043 const cachedAscent = ascentCache.get(fontFamily); 12044 if (cachedAscent) { 12045 return cachedAscent; 12046 } 12047 const ctx = getCtx(DEFAULT_FONT_SIZE, isOffscreenCanvasSupported); 12048 ctx.font = `${DEFAULT_FONT_SIZE}px ${fontFamily}`; 12049 const metrics = ctx.measureText(""); 12050 let ascent = metrics.fontBoundingBoxAscent; 12051 let descent = Math.abs(metrics.fontBoundingBoxDescent); 12052 if (ascent) { 12053 const ratio = ascent / (ascent + descent); 12054 ascentCache.set(fontFamily, ratio); 12055 ctx.canvas.width = ctx.canvas.height = 0; 12056 return ratio; 12057 } 12058 ctx.strokeStyle = "red"; 12059 ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE); 12060 ctx.strokeText("g", 0, 0); 12061 let pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data; 12062 descent = 0; 12063 for (let i = pixels.length - 1 - 3; i >= 0; i -= 4) { 12064 if (pixels[i] > 0) {
12065 descent = Math.ceil(i / 4 / DEFAULT_FONT_SIZE); 12066 break; 12067 } 12068 } 12069 ctx.clearRect(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE); 12070 ctx.strokeText("A", 0, DEFAULT_FONT_SIZE); 12071 pixels = ctx.getImageData(0, 0, DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE).data; 12072 ascent = 0; 12073 for (let i = 0, ii = pixels.length; i < ii; i += 4) { 12074 if (pixels[i] > 0) { 12075 ascent = DEFAULT_FONT_SIZE - Math.floor(i / 4 / DEFAULT_FONT_SIZE); 12076 break; 12077 } 12078 } 12079 ctx.canvas.width = ctx.canvas.height = 0; 12080 if (ascent) { 12081 const ratio = ascent / (ascent + descent); 12082 ascentCache.set(fontFamily, ratio); 12083 return ratio; 12084 } 12085 ascentCache.set(fontFamily, DEFAULT_FONT_ASCENT); 12086 return DEFAULT_FONT_ASCENT; 12087} 12088function appendText(task, geom, styles) { 12089 const textDiv = document.createElement("span"); 12090 const textDivProperties = { 12091 angle: 0, 12092 canvasWidth: 0, 12093 hasText: geom.str !== "", 12094 hasEOL: geom.hasEOL, 12095 fontSize: 0 12096 }; 12097 task._textDivs.push(textDiv); 12098 const tx = _util.Util.transform(task._transform, geom.transform); 12099 let angle = Math.atan2(tx[1], tx[0]); 12100 const style = styles[geom.fontName]; 12101 if (style.vertical) { 12102 angle += Math.PI / 2; 12103 } 12104 const fontHeight = Math.hypot(tx[2], tx[3]); 12105 const fontAscent = fontHeight * getAscent(style.fontFamily, task._isOffscreenCanvasSupported); 12106 let left, top; 12107 if (angle === 0) { 12108 left = tx[4]; 12109 top = tx[5] - fontAscent; 12110 } else { 12111 left = tx[4] + fontAscent * Math.sin(angle); 12112 top = tx[5] - fontAscent * Math.cos(angle); 12113 } 12114 const scaleFactorStr = "calc(var(--scale-factor)*"; 12115 const divStyle = textDiv.style; 12116 if (task._container === task._rootContainer) { 12117 divStyle.left = `${(100 * left / task._pageWidth).toFixed(2)}%`; 12118 divStyle.top = `${(100 * top / task._pageHeight).toFixed(2)}%`; 12119 } else { 12120 divStyle.left = `${scaleFactorStr}${left.toFixed(2)}px)`; 12121 divStyle.top = `${scaleFactorStr}${top.toFixed(2)}px)`; 12122 } 12123 divStyle.fontSize = `${scaleFactorStr}${fontHeight.toFixed(2)}px)`; 12124 divStyle.fontFamily = style.fontFamily; 12125 textDivProperties.fontSize = fontHeight; 12126 textDiv.setAttribute("role", "presentation"); 12127 textDiv.textContent = geom.str; 12128 textDiv.dir = geom.dir; 12129 if (task._fontInspectorEnabled) { 12130 textDiv.dataset.fontName = geom.fontName; 12131 } 12132 if (angle !== 0) { 12133 textDivProperties.angle = angle * (180 / Math.PI); 12134 } 12135 let shouldScaleText = false; 12136 if (geom.str.length > 1) { 12137 shouldScaleText = true; 12138 } else if (geom.str !== " " && geom.transform[0] !== geom.transform[3]) { 12139 const absScaleX = Math.abs(geom.transform[0]), 12140 absScaleY = Math.abs(geom.transform[3]); 12141 if (absScaleX !== absScaleY && Math.max(absScaleX, absScaleY) / Math.min(absScaleX, absScaleY) > 1.5) { 12142 shouldScaleText = true; 12143 } 12144 } 12145 if (shouldScaleText) { 12146 textDivProperties.canvasWidth = style.vertical ? geom.height : geom.width; 12147 } 12148 task._textDivProperties.set(textDiv, textDivProperties); 12149 if (task._isReadableStream) { 12150 task._layoutText(textDiv); 12151 } 12152} 12153function layout(params) { 12154 const { 12155 div, 12156 scale, 12157 properties, 12158 ctx, 12159 prevFontSize, 12160 prevFontFamily 12161 } = params; 12162 const { 12163 style 12164 } = div; 12165 let transform = ""; 12166 if (properties.canvasWidth !== 0 && properties.hasText) { 12167 const { 12168 fontFamily 12169 } = style; 12170 const { 12171 canvasWidth, 12172 fontSize 12173 } = properties; 12174 if (prevFontSize !== fontSize || prevFontFamily !== fontFamily) { 12175 ctx.font = `${fontSize * scale}px ${fontFamily}`; 12176 params.prevFontSize = fontSize; 12177 params.prevFontFamily = fontFamily; 12178 } 12179 const { 12180 width 12181 } = ctx.measureText(div.textContent); 12182 if (width > 0) { 12183 transform = `scaleX(${canvasWidth * scale / width})`; 12184 } 12185 } 12186 if (properties.angle !== 0) { 12187 transform = `rotate(${properties.angle}deg) ${transform}`; 12188 } 12189 if (transform.length > 0) { 12190 style.transform = transform; 12191 } 12192} 12193function render(task) { 12194 if (task._canceled) { 12195 return; 12196 } 12197 const textDivs = task._textDivs; 12198 const capability = task._capability; 12199 const textDivsLength = textDivs.length; 12200 if (textDivsLength > MAX_TEXT_DIVS_TO_RENDER) { 12201 capability.resolve(); 12202 return; 12203 } 12204 if (!task._isReadableStream) { 12205 for (const textDiv of textDivs) { 12206 task._layoutText(textDiv); 12207 } 12208 } 12209 capability.resolve(); 12210} 12211class TextLayerRenderTask { 12212 constructor({ 12213 textContentSource, 12214 container, 12215 viewport, 12216 textDivs, 12217 textDivProperties, 12218 textContentItemsStr, 12219 isOffscreenCanvasSupported 12220 }) { 12221 this._textContentSource = textContentSource; 12222 this._isReadableStream = textContentSource instanceof ReadableStream; 12223 this._container = this._rootContainer = container; 12224 this._textDivs = textDivs || []; 12225 this._textContentItemsStr = textContentItemsStr || []; 12226 this._isOffscreenCanvasSupported = isOffscreenCanvasSupported; 12227 this._fontInspectorEnabled = !!globalThis.FontInspector?.enabled; 12228 this._reader = null; 12229 this._textDivProperties = textDivProperties || new WeakMap(); 12230 this._canceled = false;
12231 this._capability = new _util.PromiseCapability(); 12232 this._layoutTextParams = { 12233 prevFontSize: null, 12234 prevFontFamily: null, 12235 div: null, 12236 scale: viewport.scale * (globalThis.devicePixelRatio || 1), 12237 properties: null, 12238 ctx: getCtx(0, isOffscreenCanvasSupported) 12239 }; 12240 const { 12241 pageWidth, 12242 pageHeight, 12243 pageX, 12244 pageY 12245 } = viewport.rawDims; 12246 this._transform = [1, 0, 0, -1, -pageX, pageY + pageHeight]; 12247 this._pageWidth = pageWidth; 12248 this._pageHeight = pageHeight; 12249 (0, _display_utils.setLayerDimensions)(container, viewport); 12250 this._capability.promise.finally(() => { 12251 this._layoutTextParams = null; 12252 }).catch(() => {}); 12253 } 12254 get promise() { 12255 return this._capability.promise; 12256 } 12257 cancel() { 12258 this._canceled = true; 12259 if (this._reader) { 12260 this._reader.cancel(new _util.AbortException("TextLayer task cancelled.")).catch(() => {}); 12261 this._reader = null; 12262 } 12263 this._capability.reject(new _util.AbortException("TextLayer task cancelled.")); 12264 } 12265 _processItems(items, styleCache) { 12266 for (const item of items) { 12267 if (item.str === undefined) { 12268 if (item.type === "beginMarkedContentProps" || item.type === "beginMarkedContent") { 12269 const parent = this._container; 12270 this._container = document.createElement("span"); 12271 this._container.classList.add("markedContent"); 12272 if (item.id !== null) { 12273 this._container.setAttribute("id", `${item.id}`); 12274 } 12275 parent.append(this._container); 12276 } else if (item.type === "endMarkedContent") { 12277 this._container = this._container.parentNode; 12278 } 12279 continue; 12280 } 12281 this._textContentItemsStr.push(item.str); 12282 appendText(this, item, styleCache); 12283 } 12284 } 12285 _layoutText(textDiv) { 12286 const textDivProperties = this._layoutTextParams.properties = this._textDivProperties.get(textDiv); 12287 this._layoutTextParams.div = textDiv; 12288 layout(this._layoutTextParams); 12289 if (textDivProperties.hasText) { 12290 this._container.append(textDiv); 12291 } 12292 if (textDivProperties.hasEOL) { 12293 const br = document.createElement("br"); 12294 br.setAttribute("role", "presentation"); 12295 this._container.append(br); 12296 } 12297 } 12298 _render() { 12299 const capability = new _util.PromiseCapability(); 12300 let styleCache = Object.create(null); 12301 if (this._isReadableStream) { 12302 const pump = () => { 12303 this._reader.read().then(({ 12304 value, 12305 done 12306 }) => { 12307 if (done) { 12308 capability.resolve(); 12309 return; 12310 } 12311 Object.assign(styleCache, value.styles); 12312 this._processItems(value.items, styleCache); 12313 pump(); 12314 }, capability.reject); 12315 }; 12316 this._reader = this._textContentSource.getReader(); 12317 pump(); 12318 } else if (this._textContentSource) { 12319 const { 12320 items, 12321 styles 12322 } = this._textContentSource; 12323 this._processItems(items, styles); 12324 capability.resolve(); 12325 } else { 12326 throw new Error('No "textContentSource" parameter specified.'); 12327 } 12328 capability.promise.then(() => { 12329 styleCache = null; 12330 render(this); 12331 }, this._capability.reject); 12332 } 12333} 12334exports.TextLayerRenderTask = TextLayerRenderTask; 12335function renderTextLayer(params) { 12336 if (!params.textContentSource && (params.textContent || params.textContentStream)) { 12337 (0, _display_utils.deprecated)("The TextLayerRender `textContent`/`textContentStream` parameters " + "will be removed in the future, please use `textContentSource` instead."); 12338 params.textContentSource = params.textContent || params.textContentStream; 12339 } 12340 const { 12341 container, 12342 viewport 12343 }
12343 = params; 12344 const style = getComputedStyle(container); 12345 const visibility = style.getPropertyValue("visibility"); 12346 const scaleFactor = parseFloat(style.getPropertyValue("--scale-factor")); 12347 if (visibility === "visible" && (!scaleFactor || Math.abs(scaleFactor - viewport.scale) > 1e-5)) { 12348 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."); 12349 } 12350 const task = new TextLayerRenderTask(params); 12351 task._render(); 12352 return task; 12353} 12354function updateTextLayer({ 12355 container, 12356 viewport, 12357 textDivs, 12358 textDivProperties, 12359 isOffscreenCanvasSupported, 12360 mustRotate = true, 12361 mustRescale = true 12362}) { 12363 if (mustRotate) { 12364 (0, _display_utils.setLayerDimensions)(container, { 12365 rotation: viewport.rotation 12366 }); 12367 } 12368 if (mustRescale) { 12369 const ctx = getCtx(0, isOffscreenCanvasSupported); 12370 const scale = viewport.scale * (globalThis.devicePixelRatio || 1); 12371 const params = { 12372 prevFontSize: null, 12373 prevFontFamily: null, 12374 div: null, 12375 scale, 12376 properties: null, 12377 ctx 12378 }; 12379 for (const div of textDivs) { 12380 params.properties = textDivProperties.get(div); 12381 params.div = div; 12382 layout(params); 12383 } 12384 } 12385} 12386 12387/***/ }), 12388/* 27 */ 12389/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 12390 12391 12392 12393Object.defineProperty(exports, "__esModule", ({ 12394 value: true 12395})); 12396exports.AnnotationEditorLayer = void 0; 12397var _util = __w_pdfjs_require__(1); 12398var _editor = __w_pdfjs_require__(4); 12399var _tools = __w_pdfjs_require__(5); 12400var _freetext = __w_pdfjs_require__(28); 12401var _ink = __w_pdfjs_require__(33); 12402var _display_utils = __w_pdfjs_require__(6); 12403var _stamp = __w_pdfjs_require__(34); 12404class AnnotationEditorLayer { 12405 #accessibilityManager; 12406 #allowClick = false; 12407 #annotationLayer = null; 12408 #boundPointerup = this.pointerup.bind(this); 12409 #boundPointerdown = this.pointerdown.bind(this); 12410 #editors = new Map(); 12411 #hadPointerDown = false; 12412 #isCleaningUp = false; 12413 #isDisabling = false; 12414 #uiManager; 12415 static _initialized = false; 12416 constructor({ 12417 uiManager, 12418 pageIndex, 12419 div, 12420 accessibilityManager, 12421 annotationLayer, 12422 viewport, 12423 l10n 12424 }) { 12425 const editorTypes = [_freetext.FreeTextEditor, _ink.InkEditor, _stamp.StampEditor]; 12426 if (!AnnotationEditorLayer._initialized) { 12427 AnnotationEditorLayer._initialized = true; 12428 for (const editorType of editorTypes) { 12429 editorType.initialize(l10n); 12430 } 12431 } 12432 uiManager.registerEditorTypes(editorTypes); 12433 this.#uiManager = uiManager; 12434 this.pageIndex = pageIndex; 12435 this.div = div; 12436 this.#accessibilityManager = accessibilityManager; 12437 this.#annotationLayer = annotationLayer; 12438 this.viewport = viewport; 12439 this.#uiManager.addLayer(this); 12440 } 12441 get isEmpty() { 12442 return this.#editors.size === 0; 12443 } 12444 updateToolbar(mode) { 12445 this.#uiManager.updateToolbar(mode); 12446 } 12447 updateMode(mode = this.#uiManager.getMode()) { 12448 this.#cleanup(); 12449 if (mode === _util.AnnotationEditorType.INK) { 12450 this.addInkEditorIfNeeded(false); 12451 this.disableClick(); 12452 } else { 12453 this.enableClick(); 12454 } 12455 this.#uiManager.unselectAll(); 12456 if (mode !== _util.AnnotationEditorType.NONE) { 12457 this.div.classList.toggle("freeTextEditing", mode === _util.AnnotationEditorType.FREETEXT); 12458 this.div.classList.toggle("inkEditing", mode === _util.AnnotationEditorType.INK); 12459 this.div.classList.toggle("stampEditing", mode === _util.AnnotationEditorType.STAMP); 12460 this.div.hidden = false; 12461 } 12462 } 12463 addInkEditorIfNeeded(isCommitting) { 12464 if (!isCommitting && this.#uiManager.getMode() !== _util.AnnotationEditorType.INK) { 12465 return; 12466 } 12467 if (!isCommitting) { 12468 for (const editor of this.#editors.values()) { 12469 if (editor.isEmpty()) { 12470 editor.setInBackground(); 12471 return; 12472 } 12473 } 12474 } 12475 const editor = this.#createAndAddNewEditor({ 12476 offsetX: 0, 12477 offsetY: 0 12478 }); 12479 editor.setInBackground(); 12480 } 12481 setEditingState(isEditing) { 12482 this.#uiManager.setEditingState(isEditing); 12483 } 12484 addCommands(params) { 12485 this.#uiManager.addCommands(params); 12486 } 12487 enable() { 12488 this.div.style.pointerEvents = "auto"; 12489 const annotationElementIds = new Set(); 12490 for (const editor of this.#editors.values()) { 12491 editor.enableEditing(); 12492 if (editor.annotationElementId) { 12493 annotationElementIds.add(editor.annotationElementId); 12494 } 12495 } 12496 if (!this.#annotationLayer) { 12497 return; 12498 } 12499 const editables = this.#annotationLayer.getEditableAnnotations(); 12500 for (const editable of editables) { 12501 editable.hide(); 12502 if (this.#uiManager.isDeletedAnnotationElement(editable.data.id)) { 12503 continue; 12504 } 12505 if (annotationElementIds.has(editable.data.id)) { 12506 continue; 12507 } 12508 const editor = this.deserialize(editable); 12509 if (!editor) { 12510 continue; 12511 } 12512 this.addOrRebuild(editor); 12513 editor.enableEditing(); 12514 } 12515 } 12516 disable() { 12517 this.#isDisabling = true; 12518 this.div.style.pointerEvents = "none"; 12519 const hiddenAnnotationIds = new Set(); 12520 for (const editor of this.#editors.values()) { 12521 editor.disableEditing(); 12522 if (!editor.annotationElementId || editor.serialize() !== null) { 12523 hiddenAnnotationIds.add(editor.annotationElementId); 12524 continue; 12525 } 12526 this.getEditableAnnotation(editor.annotationElementId)?.show(); 12527 editor.remove(); 12528 } 12529 if (this.#annotationLayer) { 12530 const editables = this.#annotationLayer.getEditableAnnotations(); 12531 for (const editable of editables) { 12532 const { 12533 id 12534 } = editable.data; 12535 if (hiddenAnnotationIds.has(id) || this.#uiManager.isDeletedAnnotationElement(id)) { 12536 continue; 12537 } 12538 editable.show(); 12539 } 12540 } 12541 this.#cleanup(); 12542 if (this.isEmpty) { 12543 this.div.hidden = true; 12544 } 12545 this.#isDisabling = false;
12546 } 12547 getEditableAnnotation(id) { 12548 return this.#annotationLayer?.getEditableAnnotation(id) || null; 12549 } 12550 setActiveEditor(editor) { 12551 const currentActive = this.#uiManager.getActive(); 12552 if (currentActive === editor) { 12553 return; 12554 } 12555 this.#uiManager.setActiveEditor(editor); 12556 } 12557 enableClick() { 12558 this.div.addEventListener("pointerdown", this.#boundPointerdown); 12559 this.div.addEventListener("pointerup", this.#boundPointerup); 12560 } 12561 disableClick() { 12562 this.div.removeEventListener("pointerdown", this.#boundPointerdown); 12563 this.div.removeEventListener("pointerup", this.#boundPointerup); 12564 } 12565 attach(editor) { 12566 this.#editors.set(editor.id, editor); 12567 const { 12568 annotationElementId 12569 } = editor; 12570 if (annotationElementId && this.#uiManager.isDeletedAnnotationElement(annotationElementId)) { 12571 this.#uiManager.removeDeletedAnnotationElement(editor); 12572 } 12573 } 12574 detach(editor) { 12575 this.#editors.delete(editor.id); 12576 this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv); 12577 if (!this.#isDisabling && editor.annotationElementId) { 12578 this.#uiManager.addDeletedAnnotationElement(editor); 12579 } 12580 } 12581 remove(editor) { 12582 this.detach(editor); 12583 this.#uiManager.removeEditor(editor); 12584 editor.div.style.display = "none"; 12585 setTimeout(() => { 12586 editor.div.style.display = ""; 12587 editor.div.remove(); 12588 editor.isAttachedToDOM = false; 12589 if (document.activeElement === document.body) { 12590 this.#uiManager.focusMainContainer(); 12591 } 12592 }, 0); 12593 if (!this.#isCleaningUp) { 12594 this.addInkEditorIfNeeded(false); 12595 } 12596 } 12597 #changeParent(editor) { 12598 if (editor.parent === this) { 12599 return; 12600 } 12601 if (editor.annotationElementId) { 12602 this.#uiManager.addDeletedAnnotationElement(editor.annotationElementId); 12603 _editor.AnnotationEditor.deleteAnnotationElement(editor); 12604 editor.annotationElementId = null; 12605 } 12606 this.attach(editor); 12607 editor.parent?.detach(editor); 12608 editor.setParent(this); 12609 if (editor.div && editor.isAttachedToDOM) { 12610 editor.div.remove(); 12611 this.div.append(editor.div); 12612 } 12613 } 12614 add(editor) { 12615 this.#changeParent(editor); 12616 this.#uiManager.addEditor(editor); 12617 this.attach(editor); 12618 if (!editor.isAttachedToDOM) { 12619 const div = editor.render(); 12620 this.div.append(div); 12621 editor.isAttachedToDOM = true; 12622 } 12623 this.moveEditorInDOM(editor); 12624 editor.onceAdded(); 12625 this.#uiManager.addToAnnotationStorage(editor); 12626 } 12627 moveEditorInDOM(editor) { 12628 this.#accessibilityManager?.moveElementInDOM(this.div, editor.div, editor.contentDiv, true); 12629 } 12630 addOrRebuild(editor) { 12631 if (editor.needsToBeRebuilt()) { 12632 editor.rebuild(); 12633 } else { 12634 this.add(editor); 12635 } 12636 } 12637 addUndoableEditor(editor) { 12638 const cmd = () => { 12639 this.addOrRebuild(editor); 12640 }; 12641 const undo = () => { 12642 editor.remove(); 12643 }; 12644 this.addCommands({ 12645 cmd, 12646 undo, 12647 mustExec: false 12648 }); 12649 } 12650 getNextId() { 12651 return this.#uiManager.getId(); 12652 } 12653 #createNewEditor(params) { 12654 switch (this.#uiManager.getMode()) { 12655 case _util.AnnotationEditorType.FREETEXT: 12656 return new _freetext.FreeTextEditor(params); 12657 case _util.AnnotationEditorType.INK: 12658 return new _ink.InkEditor(params); 12659 case _util.AnnotationEditorType.STAMP: 12660 return new _stamp.StampEditor(params); 12661 } 12662 return null; 12663 } 12664 deserialize(data) { 12665 switch (data.annotationType ?? data.annotationEditorType) { 12666 case _util.AnnotationEditorType.FREETEXT: 12667 return _freetext.FreeTextEditor.deserialize(data, this, this.#uiManager); 12668 case _util.AnnotationEditorType.INK: 12669 return _ink.InkEditor.deserialize(data, this, this.#uiManager); 12670 case _util.AnnotationEditorType.STAMP: 12671 return _stamp.StampEditor.deserialize(data, this, this.#uiManager); 12672 } 12673 return null; 12674 } 12675 #createAndAddNewEditor(event) { 12676 const id = this.getNextId(); 12677 const editor = this.#createNewEditor({ 12678 parent: this, 12679 id, 12680 x: event.offsetX, 12681 y: event.offsetY, 12682 uiManager: this.#uiManager 12683 }); 12684 if (editor) { 12685 this.add(editor); 12686 } 12687 return editor; 12688 } 12689 setSelected(editor) { 12690 this.#uiManager.setSelected(editor); 12691 } 12692 toggleSelected(editor) { 12693 this.#uiManager.toggleSelected(editor); 12694 } 12695 isSelected(editor) { 12696 return this.#uiManager.isSelected(editor); 12697 } 12698 unselect(editor) { 12699 this.#uiManager.unselect(editor); 12700 } 12701 pointerup(event) { 12702 const { 12703 isMac 12704 } = _util.FeatureTest.platform; 12705 if (event.button !== 0 || event.ctrlKey && isMac) { 12706 return; 12707 } 12708 if (event.target !== this.div) { 12709 return; 12710 } 12711 if (!this.#hadPointerDown) { 12712 return; 12713 } 12714 this.#hadPointerDown = false;
12715 if (!this.#allowClick) { 12716 this.#allowClick = true; 12717 return; 12718 } 12719 this.#createAndAddNewEditor(event); 12720 } 12721 pointerdown(event) { 12722 if (this.#hadPointerDown) { 12723 this.#hadPointerDown = false; 12724 return; 12725 } 12726 const { 12727 isMac 12728 } = _util.FeatureTest.platform; 12729 if (event.button !== 0 || event.ctrlKey && isMac) { 12730 return; 12731 } 12732 if (event.target !== this.div) { 12733 return; 12734 } 12735 this.#hadPointerDown = true; 12736 const editor = this.#uiManager.getActive(); 12737 this.#allowClick = !editor || editor.isEmpty(); 12738 } 12739 drop(event) { 12740 const id = event.dataTransfer.getData("text/plain"); 12741 const editor = this.#uiManager.getEditor(id); 12742 if (!editor) { 12743 return; 12744 } 12745 event.preventDefault(); 12746 event.dataTransfer.dropEffect = "move"; 12747 this.#changeParent(editor); 12748 const rect = this.div.getBoundingClientRect(); 12749 const endX = event.clientX - rect.x; 12750 const endY = event.clientY - rect.y; 12751 editor.translate(endX - editor.startX, endY - editor.startY); 12752 this.moveEditorInDOM(editor); 12753 editor.div.focus(); 12754 } 12755 dragover(event) { 12756 event.preventDefault(); 12757 } 12758 destroy() { 12759 if (this.#uiManager.getActive()?.parent === this) { 12760 this.#uiManager.setActiveEditor(null); 12761 } 12762 for (const editor of this.#editors.values()) { 12763 this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv); 12764 editor.setParent(null); 12765 editor.isAttachedToDOM = false; 12766 editor.div.remove(); 12767 } 12768 this.div = null; 12769 this.#editors.clear(); 12770 this.#uiManager.removeLayer(this); 12771 } 12772 #cleanup() { 12773 this.#isCleaningUp = true; 12774 for (const editor of this.#editors.values()) { 12775 if (editor.isEmpty()) { 12776 editor.remove(); 12777 } 12778 } 12779 this.#isCleaningUp = false; 12780 } 12781 render({ 12782 viewport 12783 }) { 12784 this.viewport = viewport; 12785 (0, _display_utils.setLayerDimensions)(this.div, viewport); 12786 (0, _tools.bindEvents)(this, this.div, ["dragover", "drop"]); 12787 for (const editor of this.#uiManager.getEditors(this.pageIndex)) { 12788 this.add(editor); 12789 } 12790 this.updateMode(); 12791 } 12792 update({ 12793 viewport 12794 }) { 12795 this.#uiManager.commitOrRemove(); 12796 this.viewport = viewport; 12797 (0, _display_utils.setLayerDimensions)(this.div, { 12798 rotation: viewport.rotation 12799 }); 12800 this.updateMode(); 12801 } 12802 get pageDimensions() { 12803 const { 12804 pageWidth, 12805 pageHeight 12806 } = this.viewport.rawDims; 12807 return [pageWidth, pageHeight]; 12808 } 12809} 12810exports.AnnotationEditorLayer = AnnotationEditorLayer; 12811 12812/***/ }), 12813/* 28 */ 12814/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 12815 12816 12817 12818Object.defineProperty(exports, "__esModule", ({ 12819 value: true 12820})); 12821exports.FreeTextEditor = void 0; 12822var _util = __w_pdfjs_require__(1); 12823var _tools = __w_pdfjs_require__(5); 12824var _editor = __w_pdfjs_require__(4); 12825var _annotation_layer = __w_pdfjs_require__(29); 12826class FreeTextEditor extends _editor.AnnotationEditor { 12827 #boundEditorDivBlur = this.editorDivBlur.bind(this); 12828 #boundEditorDivFocus = this.editorDivFocus.bind(this); 12829 #boundEditorDivInput = this.editorDivInput.bind(this); 12830 #boundEditorDivKeydown = this.editorDivKeydown.bind(this); 12831 #color; 12832 #content = ""; 12833 #editorDivId = `${this.id}-editor`; 12834 #fontSize; 12835 #initialData = null; 12836 static _freeTextDefaultContent = ""; 12837 static _l10nPromise; 12838 static _internalPadding = 0; 12839 static _defaultColor = null; 12840 static _defaultFontSize = 10; 12841 static get _keyboardManager() { 12842 const proto = FreeTextEditor.prototype; 12843 const arrowChecker = self => self.isEmpty(); 12844 const small = _tools.AnnotationEditorUIManager.TRANSLATE_SMALL; 12845 const big = _tools.AnnotationEditorUIManager.TRANSLATE_BIG; 12846 return (0, _util.shadow)(this, "_keyboardManager", new _tools.KeyboardManager([[["ctrl+s", "mac+meta+s", "ctrl+p", "mac+meta+p"], proto.commitOrRemove, { 12847 bubbles: true 12848 }], [["ctrl+Enter", "mac+meta+Enter", "Escape", "mac+Escape"], proto.commitOrRemove], [["ArrowLeft", "mac+ArrowLeft"], proto._translateEmpty, { 12849 args: [-small, 0], 12850 checker: arrowChecker 12851 }], [["ctrl+ArrowLeft", "mac+shift+ArrowLeft"], proto._translateEmpty, { 12852 args: [-big, 0], 12853 checker: arrowChecker 12854 }], [["ArrowRight", "mac+ArrowRight"], proto._translateEmpty, { 12855 args: [small, 0], 12856 checker: arrowChecker 12857 }], [["ctrl+ArrowRight", "mac+shift+ArrowRight"], proto._translateEmpty, { 12858 args: [big, 0], 12859 checker: arrowChecker 12860 }], [["ArrowUp", "mac+ArrowUp"], proto._translateEmpty, { 12861 args: [0, -small], 12862 checker: arrowChecker 12863 }], [["ctrl+ArrowUp", "mac+shift+ArrowUp"], proto._translateEmpty, { 12864 args: [0, -big], 12865 checker: arrowChecker 12866 }], [["ArrowDown", "mac+ArrowDown"], proto._translateEmpty, { 12867 args: [0, small], 12868 checker: arrowChecker 12869 }], [["ctrl+ArrowDown", "mac+shift+ArrowDown"], proto._translateEmpty, { 12870 args: [0, big], 12871 checker: arrowChecker 12872 }]])); 12873 } 12874 static _type = "freetext"; 12875 constructor(params) { 12876 super({ 12877 ...params, 12878 name: "freeTextEditor" 12879 }); 12880 this.#color = params.color || FreeTextEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor; 12881 this.#fontSize = params.fontSize || FreeTextEditor._defaultFontSize; 12882 } 12883 static initialize(l10n) { 12884 this._l10nPromise = new Map(["free_text2_default_content", "editor_free_text2_aria_label"].map(str => [str, l10n.get(str)])); 12885 const style = getComputedStyle(document.documentElement); 12886 this._internalPadding = parseFloat(style.getPropertyValue("--freetext-padding")); 12887 } 12888 static updateDefaultParams(type, value) { 12889 switch (type) {
12890 case _util.AnnotationEditorParamsType.FREETEXT_SIZE: 12891 FreeTextEditor._defaultFontSize = value; 12892 break; 12893 case _util.AnnotationEditorParamsType.FREETEXT_COLOR: 12894 FreeTextEditor._defaultColor = value; 12895 break; 12896 } 12897 } 12898 updateParams(type, value) { 12899 switch (type) { 12900 case _util.AnnotationEditorParamsType.FREETEXT_SIZE: 12901 this.#updateFontSize(value); 12902 break; 12903 case _util.AnnotationEditorParamsType.FREETEXT_COLOR: 12904 this.#updateColor(value); 12905 break; 12906 } 12907 } 12908 static get defaultPropertiesToUpdate() { 12909 return [[_util.AnnotationEditorParamsType.FREETEXT_SIZE, FreeTextEditor._defaultFontSize], [_util.AnnotationEditorParamsType.FREETEXT_COLOR, FreeTextEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor]]; 12910 } 12911 get propertiesToUpdate() { 12912 return [[_util.AnnotationEditorParamsType.FREETEXT_SIZE, this.#fontSize], [_util.AnnotationEditorParamsType.FREETEXT_COLOR, this.#color]]; 12913 } 12914 #updateFontSize(fontSize) { 12915 const setFontsize = size => { 12916 this.editorDiv.style.fontSize = `calc(${size}px * var(--scale-factor))`; 12917 this.translate(0, -(size - this.#fontSize) * this.parentScale); 12918 this.#fontSize = size; 12919 this.#setEditorDimensions(); 12920 }; 12921 const savedFontsize = this.#fontSize; 12922 this.addCommands({ 12923 cmd: () => { 12924 setFontsize(fontSize); 12925 }, 12926 undo: () => { 12927 setFontsize(savedFontsize); 12928 }, 12929 mustExec: true, 12930 type: _util.AnnotationEditorParamsType.FREETEXT_SIZE, 12931 overwriteIfSameType: true, 12932 keepUndo: true 12933 }); 12934 } 12935 #updateColor(color) { 12936 const savedColor = this.#color; 12937 this.addCommands({ 12938 cmd: () => { 12939 this.#color = this.editorDiv.style.color = color; 12940 }, 12941 undo: () => { 12942 this.#color = this.editorDiv.style.color = savedColor; 12943 }, 12944 mustExec: true, 12945 type: _util.AnnotationEditorParamsType.FREETEXT_COLOR, 12946 overwriteIfSameType: true, 12947 keepUndo: true 12948 }); 12949 } 12950 _translateEmpty(x, y) { 12951 this._uiManager.translateSelectedEditors(x, y, true); 12952 } 12953 getInitialTranslation() { 12954 const scale = this.parentScale; 12955 return [-FreeTextEditor._internalPadding * scale, -(FreeTextEditor._internalPadding + this.#fontSize) * scale]; 12956 } 12957 rebuild() { 12958 super.rebuild(); 12959 if (this.div === null) { 12960 return; 12961 } 12962 if (!this.isAttachedToDOM) { 12963 this.parent.add(this); 12964 } 12965 } 12966 enableEditMode() { 12967 if (this.isInEditMode()) { 12968 return; 12969 } 12970 this.parent.setEditingState(false); 12971 this.parent.updateToolbar(_util.AnnotationEditorType.FREETEXT); 12972 super.enableEditMode(); 12973 this.overlayDiv.classList.remove("enabled"); 12974 this.editorDiv.contentEditable = true; 12975 this.div.draggable = false; 12976 this.div.removeAttribute("aria-activedescendant"); 12977 this.editorDiv.addEventListener("keydown", this.#boundEditorDivKeydown); 12978 this.editorDiv.addEventListener("focus", this.#boundEditorDivFocus); 12979 this.editorDiv.addEventListener("blur", this.#boundEditorDivBlur); 12980 this.editorDiv.addEventListener("input", this.#boundEditorDivInput); 12981 } 12982 disableEditMode() { 12983 if (!this.isInEditMode()) { 12984 return; 12985 } 12986 this.parent.setEditingState(true); 12987 super.disableEditMode(); 12988 this.overlayDiv.classList.add("enabled"); 12989 this.editorDiv.contentEditable = false; 12990 this.div.setAttribute("aria-activedescendant", this.#editorDivId); 12991 this.div.draggable = true; 12992 this.editorDiv.removeEventListener("keydown", this.#boundEditorDivKeydown); 12993 this.editorDiv.removeEventListener("focus", this.#boundEditorDivFocus); 12994 this.editorDiv.removeEventListener("blur", this.#boundEditorDivBlur); 12995 this.editorDiv.removeEventListener("input", this.#boundEditorDivInput); 12996 this.div.focus({ 12997 preventScroll: true 12998 }); 12999 this.isEditing = false; 13000 this.parent.div.classList.add("freeTextEditing"); 13001 } 13002 focusin(event) { 13003 super.focusin(event); 13004 if (event.target !== this.editorDiv) { 13005 this.editorDiv.focus(); 13006 } 13007 } 13008 onceAdded() { 13009 if (this.width) { 13010 this.#cheatInitialRect(); 13011 return; 13012 } 13013 this.enableEditMode(); 13014 this.editorDiv.focus(); 13015 } 13016 isEmpty() { 13017 return !this.editorDiv || this.editorDiv.innerText.trim() === ""; 13018 } 13019 remove() { 13020 this.isEditing = false;
13021 if (this.parent) { 13022 this.parent.setEditingState(true); 13023 this.parent.div.classList.add("freeTextEditing"); 13024 } 13025 super.remove(); 13026 } 13027 #extractText() { 13028 const divs = this.editorDiv.getElementsByTagName("div"); 13029 if (divs.length === 0) { 13030 return this.editorDiv.innerText; 13031 } 13032 const buffer = []; 13033 for (const div of divs) { 13034 buffer.push(div.innerText.replace(/\r\n?|\n/, "")); 13035 } 13036 return buffer.join("\n"); 13037 } 13038 #setEditorDimensions() { 13039 const [parentWidth, parentHeight] = this.parentDimensions; 13040 let rect; 13041 if (this.isAttachedToDOM) { 13042 rect = this.div.getBoundingClientRect(); 13043 } else { 13044 const { 13045 currentLayer, 13046 div 13047 } = this; 13048 const savedDisplay = div.style.display; 13049 div.style.display = "hidden"; 13050 currentLayer.div.append(this.div); 13051 rect = div.getBoundingClientRect(); 13052 div.remove(); 13053 div.style.display = savedDisplay; 13054 } 13055 if (this.rotation % 180 === this.parentRotation % 180) { 13056 this.width = rect.width / parentWidth; 13057 this.height = rect.height / parentHeight; 13058 } else { 13059 this.width = rect.height / parentWidth; 13060 this.height = rect.width / parentHeight; 13061 } 13062 this.fixAndSetPosition(); 13063 } 13064 commit() { 13065 if (!this.isInEditMode()) { 13066 return; 13067 } 13068 super.commit(); 13069 this.disableEditMode(); 13070 const savedText = this.#content; 13071 const newText = this.#content = this.#extractText().trimEnd(); 13072 if (savedText === newText) { 13073 return; 13074 } 13075 const setText = text => { 13076 this.#content = text; 13077 if (!text) { 13078 this.remove(); 13079 return; 13080 } 13081 this.#setContent(); 13082 this.rebuild(); 13083 this.#setEditorDimensions(); 13084 }; 13085 this.addCommands({ 13086 cmd: () => { 13087 setText(newText); 13088 }, 13089 undo: () => { 13090 setText(savedText); 13091 }, 13092 mustExec: false 13093 }); 13094 this.#setEditorDimensions(); 13095 } 13096 shouldGetKeyboardEvents() { 13097 return this.isInEditMode(); 13098 } 13099 enterInEditMode() { 13100 this.enableEditMode(); 13101 this.editorDiv.focus(); 13102 } 13103 dblclick(event) { 13104 this.enterInEditMode(); 13105 } 13106 keydown(event) { 13107 if (event.target === this.div && event.key === "Enter") { 13108 this.enterInEditMode(); 13109 } 13110 } 13111 editorDivKeydown(event) { 13112 FreeTextEditor._keyboardManager.exec(this, event); 13113 } 13114 editorDivFocus(event) { 13115 this.isEditing = true; 13116 } 13117 editorDivBlur(event) { 13118 this.isEditing = false; 13119 } 13120 editorDivInput(event) { 13121 this.parent.div.classList.toggle("freeTextEditing", this.isEmpty()); 13122 } 13123 disableEditing() { 13124 this.editorDiv.setAttribute("role", "comment"); 13125 this.editorDiv.removeAttribute("aria-multiline"); 13126 } 13127 enableEditing() { 13128 this.editorDiv.setAttribute("role", "textbox"); 13129 this.editorDiv.setAttribute("aria-multiline", true); 13130 } 13131 render() { 13132 if (this.div) { 13133 return this.div; 13134 } 13135 let baseX, baseY; 13136 if (this.width) { 13137 baseX = this.x; 13138 baseY = this.y; 13139 } 13140 super.render(); 13141 this.editorDiv = document.createElement("div"); 13142 this.editorDiv.className = "internal"; 13143 this.editorDiv.setAttribute("id", this.#editorDivId); 13144 this.enableEditing(); 13145 FreeTextEditor._l10nPromise.get("editor_free_text2_aria_label").then(msg => this.editorDiv?.setAttribute("aria-label", msg)); 13146 FreeTextEditor._l10nPromise.get("free_text2_default_content").then(msg => this.editorDiv?.setAttribute("default-content", msg)); 13147 this.editorDiv.contentEditable = true; 13148 const { 13149 style 13150 } = this.editorDiv; 13151 style.fontSize = `calc(${this.#fontSize}px * var(--scale-factor))`; 13152 style.color = this.#color; 13153 this.div.append(this.editorDiv); 13154 this.overlayDiv = document.createElement("div"); 13155 this.overlayDiv.classList.add("overlay", "enabled"); 13156 this.div.append(this.overlayDiv); 13157 (0, _tools.bindEvents)(this, this.div, ["dblclick", "keydown"]); 13158 if (this.width) { 13159 const [parentWidth, parentHeight] = this.parentDimensions; 13160 if (this.annotationElementId) { 13161 const { 13162 position 13163 } = this.#initialData; 13164 let [tx, ty] = this.getInitialTranslation(); 13165 [tx, ty] = this.pageTranslationToScreen(tx, ty); 13166 const [pageWidth, pageHeight] = this.pageDimensions; 13167 const [pageX, pageY] = this.pageTranslation; 13168 let posX, posY; 13169 switch (this.rotation) { 13170 case 0: 13171 posX = baseX + (position[0] - pageX) / pageWidth; 13172 posY = baseY + this.height - (position[1] - pageY) / pageHeight; 13173 break; 13174 case 90: 13175 posX = baseX + (position[0] - pageX) / pageWidth; 13176 posY = baseY - (position[1] - pageY) / pageHeight; 13177 [tx, ty] = [ty, -tx]; 13178 break; 13179 case 180: 13180 posX = baseX - this.width + (position[0] - pageX) / pageWidth; 13181 posY = baseY - (position[1] - pageY) / pageHeight; 13182 [tx, ty] = [-tx, -ty]; 13183 break; 13184 case 270: 13185 posX = baseX + (position[0] - pageX - this.height * pageHeight) / pageWidth; 13186 posY = baseY + (position[1] - pageY - this.width * pageWidth) / pageHeight; 13187 [tx, ty] = [-ty, tx]; 13188 break; 13189 } 13190 this.setAt(posX * parentWidth, posY * parentHeight, tx, ty); 13191 } else { 13192 this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); 13193 } 13194 this.#setContent(); 13195 this.div.draggable = true; 13196 this.editorDiv.contentEditable = false;
13197 } else { 13198 this.div.draggable = false; 13199 this.editorDiv.contentEditable = true; 13200 } 13201 return this.div; 13202 } 13203 #setContent() { 13204 this.editorDiv.replaceChildren(); 13205 if (!this.#content) { 13206 return; 13207 } 13208 for (const line of this.#content.split("\n")) { 13209 const div = document.createElement("div"); 13210 div.append(line ? document.createTextNode(line) : document.createElement("br")); 13211 this.editorDiv.append(div); 13212 } 13213 } 13214 get contentDiv() { 13215 return this.editorDiv; 13216 } 13217 static deserialize(data, parent, uiManager) { 13218 let initialData = null; 13219 if (data instanceof _annotation_layer.FreeTextAnnotationElement) { 13220 const { 13221 data: { 13222 defaultAppearanceData: { 13223 fontSize, 13224 fontColor 13225 }, 13226 rect, 13227 rotation, 13228 id 13229 }, 13230 textContent, 13231 textPosition, 13232 parent: { 13233 page: { 13234 pageNumber 13235 } 13236 } 13237 } = data; 13238 if (!textContent || textContent.length === 0) { 13239 return null; 13240 } 13241 initialData = data = { 13242 annotationType: _util.AnnotationEditorType.FREETEXT, 13243 color: Array.from(fontColor), 13244 fontSize, 13245 value: textContent.join("\n"), 13246 position: textPosition, 13247 pageIndex: pageNumber - 1, 13248 rect, 13249 rotation, 13250 id, 13251 deleted: false 13252 }; 13253 } 13254 const editor = super.deserialize(data, parent, uiManager); 13255 editor.#fontSize = data.fontSize; 13256 editor.#color = _util.Util.makeHexColor(...data.color); 13257 editor.#content = data.value; 13258 editor.annotationElementId = data.id || null; 13259 editor.#initialData = initialData; 13260 return editor; 13261 } 13262 serialize(isForCopying = false) { 13263 if (this.isEmpty()) { 13264 return null; 13265 } 13266 if (this.deleted) { 13267 return { 13268 pageIndex: this.pageIndex, 13269 id: this.annotationElementId, 13270 deleted: true 13271 }; 13272 } 13273 const padding = FreeTextEditor._internalPadding * this.parentScale; 13274 const rect = this.getRect(padding, padding); 13275 const color = _editor.AnnotationEditor._colorManager.convert(this.isAttachedToDOM ? getComputedStyle(this.editorDiv).color : this.#color); 13276 const serialized = { 13277 annotationType: _util.AnnotationEditorType.FREETEXT, 13278 color, 13279 fontSize: this.#fontSize, 13280 value: this.#content, 13281 pageIndex: this.pageIndex, 13282 rect, 13283 rotation: this.rotation 13284 }; 13285 if (isForCopying) { 13286 return serialized; 13287 } 13288 if (this.annotationElementId && !this.#hasElementChanged(serialized)) { 13289 return null; 13290 } 13291 serialized.id = this.annotationElementId; 13292 return serialized; 13293 } 13294 #hasElementChanged(serialized) { 13295 const { 13296 value, 13297 fontSize, 13298 color, 13299 rect, 13300 pageIndex 13301 } = this.#initialData; 13302 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; 13303 } 13304 #cheatInitialRect(delayed = false) { 13305 if (!this.annotationElementId) { 13306 return; 13307 } 13308 this.#setEditorDimensions(); 13309 if (!delayed && (this.width === 0 || this.height === 0)) { 13310 setTimeout(() => this.#cheatInitialRect(true), 0); 13311 return; 13312 } 13313 const padding = FreeTextEditor._internalPadding * this.parentScale; 13314 this.#initialData.rect = this.getRect(padding, padding); 13315 } 13316} 13317exports.FreeTextEditor = FreeTextEditor; 13318 13319/***/ }), 13320/* 29 */ 13321/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 13322 13323 13324 13325Object.defineProperty(exports, "__esModule", ({ 13326 value: true 13327})); 13328exports.StampAnnotationElement = exports.InkAnnotationElement = exports.FreeTextAnnotationElement = exports.AnnotationLayer = void 0; 13329var _util = __w_pdfjs_require__(1); 13330var _display_utils = __w_pdfjs_require__(6); 13331var _annotation_storage = __w_pdfjs_require__(3); 13332var _scripting_utils = __w_pdfjs_require__(30); 13333var _displayL10n_utils = __w_pdfjs_require__(31); 13334var _xfa_layer = __w_pdfjs_require__(32); 13335const DEFAULT_TAB_INDEX = 1000; 13336const DEFAULT_FONT_SIZE = 9; 13337const GetElementsByNameSet = new WeakSet(); 13338function getRectDims(rect) { 13339 return { 13340 width: rect[2] - rect[0], 13341 height: rect[3] - rect[1] 13342 }; 13343} 13344class AnnotationElementFactory { 13345 static create(parameters) { 13346 const subtype = parameters.data.annotationType; 13347 switch (subtype) { 13348 case _util.AnnotationType.LINK: 13349 return new LinkAnnotationElement(parameters); 13350 case _util.AnnotationType.TEXT: 13351 return new TextAnnotationElement(parameters); 13352 case _util.AnnotationType.WIDGET: 13353 const fieldType = parameters.data.fieldType; 13354 switch (fieldType) { 13355 case "Tx": 13356 return new TextWidgetAnnotationElement(parameters); 13357 case "Btn": 13358 if (parameters.data.radioButton) { 13359 return new RadioButtonWidgetAnnotationElement(parameters); 13360 } else if (parameters.data.checkBox) { 13361 return new CheckboxWidgetAnnotationElement(parameters); 13362 } 13363 return new PushButtonWidgetAnnotationElement(parameters); 13364 case "Ch": 13365 return new ChoiceWidgetAnnotationElement(parameters); 13366 case "Sig": 13367 return new SignatureWidgetAnnotationElement(parameters); 13368 } 13369 return new WidgetAnnotationElement(parameters); 13370 case _util.AnnotationType.POPUP: 13371 return new PopupAnnotationElement(parameters); 13372 case _util.AnnotationType.FREETEXT: 13373 return new FreeTextAnnotationElement(parameters); 13374 case _util.AnnotationType.LINE: 13375 return new LineAnnotationElement(parameters); 13376 case _util.AnnotationType.SQUARE: 13377 return new SquareAnnotationElement(parameters); 13378 case _util.AnnotationType.CIRCLE: 13379 return new CircleAnnotationElement(parameters); 13380 case _util.AnnotationType.POLYLINE: 13381 return new PolylineAnnotationElement(parameters); 13382 case _util.AnnotationType.CARET: 13383 return new CaretAnnotationElement(parameters); 13384 case _util.AnnotationType.INK: 13385 return new InkAnnotationElement(parameters); 13386 case _util.AnnotationType.POLYGON: 13387 return new PolygonAnnotationElement(parameters); 13388 case _util.AnnotationType.HIGHLIGHT: 13389 return new HighlightAnnotationElement(parameters); 13390 case _util.AnnotationType.UNDERLINE: 13391 return new UnderlineAnnotationElement(parameters); 13392 case _util.AnnotationType.SQUIGGLY: 13393 return new SquigglyAnnotationElement(parameters); 13394 case _util.AnnotationType.STRIKEOUT: 13395 return new StrikeOutAnnotationElement(parameters); 13396 case _util.AnnotationType.STAMP: 13397 return new StampAnnotationElement(parameters); 13398 case _util.AnnotationType.FILEATTACHMENT: 13399 return new FileAttachmentAnnotationElement(parameters); 13400 default: 13401 return new AnnotationElement(parameters); 13402 } 13403 } 13404} 13405class AnnotationElement { 13406 #hasBorder = false;
13407 constructor(parameters, { 13408 isRenderable = false, 13409 ignoreBorder = false, 13410 createQuadrilaterals = false 13411 } = {}) { 13412 this.isRenderable = isRenderable; 13413 this.data = parameters.data; 13414 this.layer = parameters.layer; 13415 this.linkService = parameters.linkService; 13416 this.downloadManager = parameters.downloadManager; 13417 this.imageResourcesPath = parameters.imageResourcesPath; 13418 this.renderForms = parameters.renderForms; 13419 this.svgFactory = parameters.svgFactory; 13420 this.annotationStorage = parameters.annotationStorage; 13421 this.enableScripting = parameters.enableScripting; 13422 this.hasJSActions = parameters.hasJSActions; 13423 this._fieldObjects = parameters.fieldObjects; 13424 this.parent = parameters.parent; 13425 if (isRenderable) { 13426 this.container = this._createContainer(ignoreBorder); 13427 } 13428 if (createQuadrilaterals) { 13429 this._createQuadrilaterals(); 13430 } 13431 } 13432 _createContainer(ignoreBorder) { 13433 const { 13434 data, 13435 parent: { 13436 page, 13437 viewport 13438 } 13439 } = this; 13440 const container = document.createElement("section"); 13441 container.setAttribute("data-annotation-id", data.id); 13442 container.style.zIndex = this.parent.zIndex++; 13443 if (this.data.popupRef) { 13444 container.setAttribute("aria-haspopup", "dialog"); 13445 } 13446 if (data.noRotate) { 13447 container.classList.add("norotate"); 13448 } 13449 const { 13450 pageWidth, 13451 pageHeight, 13452 pageX, 13453 pageY 13454 } = viewport.rawDims; 13455 if (!data.rect || this instanceof PopupAnnotationElement) { 13456 const { 13457 rotation 13458 } = data; 13459 if (!data.hasOwnCanvas && rotation !== 0) { 13460 this.setRotation(rotation, container); 13461 } 13462 return container; 13463 } 13464 const { 13465 width, 13466 height 13467 } = getRectDims(data.rect); 13468 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]]); 13469 if (!ignoreBorder && data.borderStyle.width > 0) { 13470 container.style.borderWidth = `${data.borderStyle.width}px`; 13471 const horizontalRadius = data.borderStyle.horizontalCornerRadius; 13472 const verticalRadius = data.borderStyle.verticalCornerRadius; 13473 if (horizontalRadius > 0 || verticalRadius > 0) { 13474 const radius = `calc(${horizontalRadius}px * var(--scale-factor)) / calc(${verticalRadius}px * var(--scale-factor))`; 13475 container.style.borderRadius = radius; 13476 } else if (this instanceof RadioButtonWidgetAnnotationElement) { 13477 const radius = `calc(${width}px * var(--scale-factor)) / calc(${height}px * var(--scale-factor))`; 13478 container.style.borderRadius = radius; 13479 } 13480 switch (data.borderStyle.style) { 13481 case _util.AnnotationBorderStyleType.SOLID: 13482 container.style.borderStyle = "solid"; 13483 break; 13484 case _util.AnnotationBorderStyleType.DASHED: 13485 container.style.borderStyle = "dashed"; 13486 break; 13487 case _util.AnnotationBorderStyleType.BEVELED: 13488 (0, _util.warn)("Unimplemented border style: beveled"); 13489 break; 13490 case _util.AnnotationBorderStyleType.INSET: 13491 (0, _util.warn)("Unimplemented border style: inset"); 13492 break; 13493 case _util.AnnotationBorderStyleType.UNDERLINE: 13494 container.style.borderBottomStyle = "solid"; 13495 break; 13496 default: 13497 break; 13498 } 13499 const borderColor = data.borderColor || null; 13500 if (borderColor) { 13501 this.#hasBorder = true; 13502 container.style.borderColor = _util.Util.makeHexColor(borderColor[0] | 0, borderColor[1] | 0, borderColor[2] | 0); 13503 } else { 13504 container.style.borderWidth = 0; 13505 } 13506 } 13507 container.style.left = `${100 * (rect[0] - pageX) / pageWidth}%`; 13508 container.style.top = `${100 * (rect[1] - pageY) / pageHeight}%`; 13509 const { 13510 rotation 13511 } = data; 13512 if (data.hasOwnCanvas || rotation === 0) { 13513 container.style.width = `${100 * width / pageWidth}%`; 13514 container.style.height = `${100 * height / pageHeight}%`; 13515 } else { 13516 this.setRotation(rotation, container); 13517 } 13518 return container; 13519 } 13520 setRotation(angle, container = this.container) { 13521 if (!this.data.rect) { 13522 return; 13523 } 13524 const { 13525 pageWidth, 13526 pageHeight 13527 } = this.parent.viewport.rawDims; 13528 const { 13529 width, 13530 height 13531 } = getRectDims(this.data.rect); 13532 let elementWidth, elementHeight; 13533 if (angle % 180 === 0) { 13534 elementWidth = 100 * width / pageWidth; 13535 elementHeight = 100 * height / pageHeight; 13536 } else { 13537 elementWidth = 100 * height / pageWidth; 13538 elementHeight = 100 * width / pageHeight; 13539 } 13540 container.style.width = `${elementWidth}%`; 13541 container.style.height = `${elementHeight}%`; 13542 container.setAttribute("data-main-rotation", (360 - angle) % 360); 13543 } 13544 get _commonActions() { 13545 const setColor = (jsName, styleName, event) => { 13546 const color = event.detail[jsName]; 13547 event.target.style[styleName] = _scripting_utils.ColorConverters[`${color[0]}_HTML`](color.slice(1)); 13548 }; 13549 return (0, _util.shadow)(this, "_commonActions", { 13550 display: event => { 13551 const hidden = event.detail.display % 2 === 1; 13552 this.container.style.visibility = hidden ? "hidden" : "visible"; 13553 this.annotationStorage.setValue(this.data.id, { 13554 hidden, 13555 print: event.detail.display === 0 || event.detail.display === 3 13556 }); 13557 }, 13558 print: event => { 13559 this.annotationStorage.setValue(this.data.id, { 13560 print: event.detail.print 13561 }); 13562 }, 13563 hidden: event => { 13564 this.container.style.visibility = event.detail.hidden ? "hidden" : "visible"; 13565 this.annotationStorage.setValue(this.data.id, { 13566 hidden: event.detail.hidden 13567 }); 13568 }, 13569 focus: event => { 13570 setTimeout(() =>
13570 event.target.focus({ 13571 preventScroll: false 13572 }), 0); 13573 }, 13574 userName: event => { 13575 event.target.title = event.detail.userName; 13576 }, 13577 readonly: event => { 13578 if (event.detail.readonly) { 13579 event.target.setAttribute("readonly", ""); 13580 } else { 13581 event.target.removeAttribute("readonly"); 13582 } 13583 }, 13584 required: event => { 13585 this._setRequired(event.target, event.detail.required); 13586 }, 13587 bgColor: event => { 13588 setColor("bgColor", "backgroundColor", event); 13589 }, 13590 fillColor: event => { 13591 setColor("fillColor", "backgroundColor", event); 13592 }, 13593 fgColor: event => { 13594 setColor("fgColor", "color", event); 13595 }, 13596 textColor: event => { 13597 setColor("textColor", "color", event); 13598 }, 13599 borderColor: event => { 13600 setColor("borderColor", "borderColor", event); 13601 }, 13602 strokeColor: event => { 13603 setColor("strokeColor", "borderColor", event); 13604 }, 13605 rotation: event => { 13606 const angle = event.detail.rotation; 13607 this.setRotation(angle); 13608 this.annotationStorage.setValue(this.data.id, { 13609 rotation: angle 13610 }); 13611 } 13612 }); 13613 } 13614 _dispatchEventFromSandbox(actions, jsEvent) { 13615 const commonActions = this._commonActions; 13616 for (const name of Object.keys(jsEvent.detail)) { 13617 const action = actions[name] || commonActions[name]; 13618 action?.(jsEvent); 13619 } 13620 } 13621 _setDefaultPropertiesFromJS(element) { 13622 if (!this.enableScripting) { 13623 return; 13624 } 13625 const storedData = this.annotationStorage.getRawValue(this.data.id); 13626 if (!storedData) { 13627 return; 13628 } 13629 const commonActions = this._commonActions; 13630 for (const [actionName, detail] of Object.entries(storedData)) { 13631 const action = commonActions[actionName]; 13632 if (action) { 13633 const eventProxy = { 13634 detail: { 13635 [actionName]: detail 13636 }, 13637 target: element 13638 }; 13639 action(eventProxy); 13640 delete storedData[actionName]; 13641 } 13642 } 13643 } 13644 _createQuadrilaterals() { 13645 if (!this.container) { 13646 return; 13647 } 13648 const { 13649 quadPoints 13650 } = this.data; 13651 if (!quadPoints) { 13652 return; 13653 } 13654 const [rectBlX, rectBlY, rectTrX, rectTrY] = this.data.rect; 13655 if (quadPoints.length === 1) { 13656 const [, { 13657 x: trX, 13658 y: trY 13659 }, { 13660 x: blX, 13661 y: blY 13662 }] = quadPoints[0]; 13663 if (rectTrX === trX && rectTrY === trY && rectBlX === blX && rectBlY === blY) { 13664 return; 13665 } 13666 } 13667 const { 13668 style 13669 } = this.container; 13670 let svgBuffer; 13671 if (this.#hasBorder) { 13672 const { 13673 borderColor, 13674 borderWidth 13675 } = style; 13676 style.borderWidth = 0; 13677 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}">`]; 13678 this.container.classList.add("hasBorder"); 13679 } 13680 const width = rectTrX - rectBlX; 13681 const height = rectTrY - rectBlY; 13682 const { 13683 svgFactory 13684 } = this; 13685 const svg = svgFactory.createElement("svg"); 13686 svg.classList.add("quadrilateralsContainer"); 13687 svg.setAttribute("width", 0); 13688 svg.setAttribute("height", 0); 13689 const defs = svgFactory.createElement("defs"); 13690 svg.append(defs); 13691 const clipPath = svgFactory.createElement("clipPath"); 13692 const id = `clippath_${this.data.id}`; 13693 clipPath.setAttribute("id", id); 13694 clipPath.setAttribute("clipPathUnits", "objectBoundingBox"); 13695 defs.append(clipPath); 13696 for (const [, { 13697 x: trX, 13698 y: trY 13699 }, { 13700 x: blX, 13701 y: blY 13702 }] of quadPoints) { 13703 const rect = svgFactory.createElement("rect"); 13704 const x = (blX - rectBlX) / width; 13705 const y = (rectTrY - trY) / height; 13706 const rectWidth = (trX - blX) / width; 13707 const rectHeight = (trY - blY) / height; 13708 rect.setAttribute("x", x); 13709 rect.setAttribute("y", y); 13710 rect.setAttribute("width", rectWidth); 13711 rect.setAttribute("height", rectHeight); 13712 clipPath.append(rect); 13713 svgBuffer?.push(`<rect vector-effect="non-scaling-stroke" x="${x}" y="${y}" width="${rectWidth}" height="${rectHeight}"/>`); 13714 } 13715 if (this.#hasBorder) { 13716 svgBuffer.push(`</g></svg>')`); 13717 style.backgroundImage = svgBuffer.join(""); 13718 } 13719 this.container.append(svg); 13720 this.container.style.clipPath = `url(#${id})`; 13721 } 13722 _createPopup() { 13723 const { 13724 container, 13725 data 13726 } = this; 13727 container.setAttribute("aria-haspopup", "dialog"); 13728 const popup = new PopupAnnotationElement({ 13729 data: { 13730 color: data.color, 13731 titleObj: data.titleObj, 13732 modificationDate: data.modificationDate, 13733 contentsObj: data.contentsObj, 13734 richText: data.richText, 13735 parentRect: data.rect, 13736 borderStyle: 0, 13737 id: `popup_${data.id}`, 13738 rotation: data.rotation 13739 }, 13740 parent: this.parent, 13741 elements: [this] 13742 }); 13743 this.parent.div.append(popup.render()); 13744 } 13745 render() { 13746 (0, _util.unreachable)("Abstract method `AnnotationElement.render` called"); 13747 } 13748 _getElementsByName(name, skipId = null) { 13749 const fields = []; 13750 if (this._fieldObjects) { 13751 const fieldObj = this._fieldObjects[name]; 13752 if (fieldObj) { 13753 for (const { 13754 page, 13755 id, 13756 exportValues 13757 } of fieldObj) { 13758 if (page === -1) { 13759 continue; 13760 } 13761 if (id === skipId) { 13762 continue; 13763 } 13764 const exportValue = typeof exportValues === "string" ? exportValues : null; 13765 const domElement = document.querySelector(`[data-element-id="${id}"]`); 13766 if (domElement && !GetElementsByNameSet.has(domElement)) { 13767 (0, _util.warn)(`_getElementsByName - element not allowed: ${id}`); 13768 continue; 13769 } 13770 fields.push({ 13771 id, 13772 exportValue, 13773 domElement 13774 }); 13775 } 13776 } 13777 return fields; 13778 } 13779 for (const domElement of document.getElementsByName(name)) { 13780 const { 13781 exportValue 13782 } = domElement; 13783 const id = domElement.getAttribute("data-element-id"); 13784 if (id === skipId) { 13785 continue; 13786 } 13787 if (!GetElementsByNameSet.has(domElement)) { 13788 continue; 13789 } 13790 fields.push({ 13791 id, 13792 exportValue, 13793 domElement 13794 }); 13795 } 13796 return fields; 13797 } 13798 show() { 13799 if (this.container) { 13800 this.container.hidden = false;
vendor: 4,141 bytes, lines 13801-13945
13801 } 13802 this.popup?.maybeShow(); 13803 } 13804 hide() { 13805 if (this.container) { 13806 this.container.hidden = true; 13807 } 13808 this.popup?.forceHide(); 13809 } 13810 getElementsToTriggerPopup() { 13811 return this.container; 13812 } 13813 addHighlightArea() { 13814 const triggers = this.getElementsToTriggerPopup(); 13815 if (Array.isArray(triggers)) { 13816 for (const element of triggers) { 13817 element.classList.add("highlightArea"); 13818 } 13819 } else { 13820 triggers.classList.add("highlightArea"); 13821 } 13822 } 13823 _editOnDoubleClick() { 13824 const { 13825 annotationEditorType: mode, 13826 data: { 13827 id: editId 13828 } 13829 } = this; 13830 this.container.addEventListener("dblclick", () => { 13831 this.linkService.eventBus?.dispatch("switchannotationeditormode", { 13832 source: this, 13833 mode, 13834 editId 13835 }); 13836 }); 13837 } 13838} 13839class LinkAnnotationElement extends AnnotationElement { 13840 constructor(parameters, options = null) { 13841 super(parameters, { 13842 isRenderable: true, 13843 ignoreBorder: !!options?.ignoreBorder, 13844 createQuadrilaterals: true 13845 }); 13846 this.isTooltipOnly = parameters.data.isTooltipOnly; 13847 } 13848 render() { 13849 const { 13850 data, 13851 linkService 13852 } = this; 13853 const link = document.createElement("a"); 13854 link.setAttribute("data-element-id", data.id); 13855 let isBound = false; 13856 if (data.url) { 13857 linkService.addLinkAttributes(link, data.url, data.newWindow); 13858 isBound = true; 13859 } else if (data.action) { 13860 this._bindNamedAction(link, data.action); 13861 isBound = true; 13862 } else if (data.attachment) { 13863 this._bindAttachment(link, data.attachment); 13864 isBound = true; 13865 } else if (data.setOCGState) { 13866 this.#bindSetOCGState(link, data.setOCGState); 13867 isBound = true; 13868 } else if (data.dest) { 13869 this._bindLink(link, data.dest); 13870 isBound = true; 13871 } else { 13872 if (data.actions && (data.actions.Action || data.actions["Mouse Up"] || data.actions["Mouse Down"]) && this.enableScripting && this.hasJSActions) { 13873 this._bindJSAction(link, data); 13874 isBound = true; 13875 } 13876 if (data.resetForm) { 13877 this._bindResetFormAction(link, data.resetForm); 13878 isBound = true; 13879 } else if (this.isTooltipOnly && !isBound) { 13880 this._bindLink(link, ""); 13881 isBound = true; 13882 } 13883 } 13884 this.container.classList.add("linkAnnotation"); 13885 if (isBound) { 13886 this.container.append(link); 13887 } 13888 return this.container; 13889 } 13890 #setInternalLink() { 13891 this.container.setAttribute("data-internal-link", ""); 13892 } 13893 _bindLink(link, destination) { 13894 link.href = this.linkService.getDestinationHash(destination); 13895 link.onclick = () => { 13896 if (destination) { 13897 this.linkService.goToDestination(destination); 13898 } 13899 return false; 13900 }; 13901 if (destination || destination === "") { 13902 this.#setInternalLink(); 13903 } 13904 } 13905 _bindNamedAction(link, action) { 13906 link.href = this.linkService.getAnchorUrl(""); 13907 link.onclick = () => { 13908 this.linkService.executeNamedAction(action); 13909 return false; 13910 }; 13911 this.#setInternalLink(); 13912 } 13913 _bindAttachment(link, attachment) { 13914 link.href = this.linkService.getAnchorUrl(""); 13915 link.onclick = () => { 13916 this.downloadManager?.openOrDownloadData(this.container, attachment.content, attachment.filename); 13917 return false; 13918 }; 13919 this.#setInternalLink(); 13920 } 13921 #bindSetOCGState(link, action) { 13922 link.href = this.linkService.getAnchorUrl(""); 13923 link.onclick = () => { 13924 this.linkService.executeSetOCGState(action); 13925 return false; 13926 }; 13927 this.#setInternalLink(); 13928 } 13929 _bindJSAction(link, data) { 13930 link.href = this.linkService.getAnchorUrl(""); 13931 const map = new Map([["Action", "onclick"], ["Mouse Up", "onmouseup"], ["Mouse Down", "onmousedown"]]); 13932 for (const name of Object.keys(data.actions)) { 13933 const jsName = map.get(name); 13934 if (!jsName) { 13935 continue; 13936 } 13937 link[jsName] = () => { 13938 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 13939 source: this, 13940 detail: { 13941 id: data.id, 13942 name 13943 } 13944 }); 13945 return false;
13946 }; 13947 } 13948 if (!link.onclick) { 13949 link.onclick = () => false; 13950 } 13951 this.#setInternalLink(); 13952 } 13953 _bindResetFormAction(link, resetForm) { 13954 const otherClickAction = link.onclick; 13955 if (!otherClickAction) { 13956 link.href = this.linkService.getAnchorUrl(""); 13957 } 13958 this.#setInternalLink(); 13959 if (!this._fieldObjects) { 13960 (0, _util.warn)(`_bindResetFormAction - "resetForm" action not supported, ` + "ensure that the `fieldObjects` parameter is provided."); 13961 if (!otherClickAction) { 13962 link.onclick = () => false; 13963 } 13964 return; 13965 } 13966 link.onclick = () => { 13967 otherClickAction?.(); 13968 const { 13969 fields: resetFormFields, 13970 refs: resetFormRefs, 13971 include 13972 } = resetForm; 13973 const allFields = []; 13974 if (resetFormFields.length !== 0 || resetFormRefs.length !== 0) { 13975 const fieldIds = new Set(resetFormRefs); 13976 for (const fieldName of resetFormFields) { 13977 const fields = this._fieldObjects[fieldName] || []; 13978 for (const { 13979 id 13980 } of fields) { 13981 fieldIds.add(id); 13982 } 13983 } 13984 for (const fields of Object.values(this._fieldObjects)) { 13985 for (const field of fields) { 13986 if (fieldIds.has(field.id) === include) { 13987 allFields.push(field); 13988 } 13989 } 13990 } 13991 } else { 13992 for (const fields of Object.values(this._fieldObjects)) { 13993 allFields.push(...fields); 13994 } 13995 } 13996 const storage = this.annotationStorage; 13997 const allIds = []; 13998 for (const field of allFields) { 13999 const { 14000 id 14001 } = field; 14002 allIds.push(id); 14003 switch (field.type) { 14004 case "text": 14005 { 14006 const value = field.defaultValue || ""; 14007 storage.setValue(id, { 14008 value 14009 }); 14010 break; 14011 } 14012 case "checkbox": 14013 case "radiobutton": 14014 { 14015 const value = field.defaultValue === field.exportValues; 14016 storage.setValue(id, { 14017 value 14018 }); 14019 break; 14020 } 14021 case "combobox": 14022 case "listbox": 14023 { 14024 const value = field.defaultValue || ""; 14025 storage.setValue(id, { 14026 value 14027 }); 14028 break; 14029 } 14030 default: 14031 continue; 14032 } 14033 const domElement = document.querySelector(`[data-element-id="${id}"]`); 14034 if (!domElement) { 14035 continue; 14036 } else if (!GetElementsByNameSet.has(domElement)) { 14037 (0, _util.warn)(`_bindResetFormAction - element not allowed: ${id}`); 14038 continue; 14039 } 14040 domElement.dispatchEvent(new Event("resetform")); 14041 } 14042 if (this.enableScripting) { 14043 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14044 source: this, 14045 detail: { 14046 id: "app", 14047 ids: allIds, 14048 name: "ResetForm" 14049 } 14050 }); 14051 } 14052 return false; 14053 }; 14054 } 14055} 14056class TextAnnotationElement extends AnnotationElement { 14057 constructor(parameters) { 14058 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 14059 super(parameters, { 14060 isRenderable 14061 }); 14062 } 14063 render() { 14064 this.container.classList.add("textAnnotation"); 14065 const image = document.createElement("img"); 14066 image.src = this.imageResourcesPath + "annotation-" + this.data.name.toLowerCase() + ".svg"; 14067 image.alt = "[{{type}} Annotation]"; 14068 image.dataset.l10nId = "text_annotation_type"; 14069 image.dataset.l10nArgs = JSON.stringify({ 14070 type: this.data.name 14071 }); 14072 if (!this.data.popupRef) { 14073 this._createPopup(); 14074 } 14075 this.container.append(image); 14076 return this.container; 14077 } 14078} 14079class WidgetAnnotationElement extends AnnotationElement { 14080 render() { 14081 if (this.data.alternativeText) { 14082 this.container.title = this.data.alternativeText; 14083 } 14084 return this.container; 14085 } 14086 showElementAndHideCanvas(element) { 14087 if (this.data.hasOwnCanvas) { 14088 if (element.previousSibling?.nodeName === "CANVAS") { 14089 element.previousSibling.hidden = true; 14090 } 14091 element.hidden = false;
14092 } 14093 } 14094 _getKeyModifier(event) { 14095 const { 14096 isWin, 14097 isMac 14098 } = _util.FeatureTest.platform; 14099 return isWin && event.ctrlKey || isMac && event.metaKey; 14100 } 14101 _setEventListener(element, baseName, eventName, valueGetter) { 14102 if (baseName.includes("mouse")) { 14103 element.addEventListener(baseName, event => { 14104 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14105 source: this, 14106 detail: { 14107 id: this.data.id, 14108 name: eventName, 14109 value: valueGetter(event), 14110 shift: event.shiftKey, 14111 modifier: this._getKeyModifier(event) 14112 } 14113 }); 14114 }); 14115 } else { 14116 element.addEventListener(baseName, event => { 14117 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14118 source: this, 14119 detail: { 14120 id: this.data.id, 14121 name: eventName, 14122 value: valueGetter(event) 14123 } 14124 }); 14125 }); 14126 } 14127 } 14128 _setEventListeners(element, names, getter) { 14129 for (const [baseName, eventName] of names) { 14130 if (eventName === "Action" || this.data.actions?.[eventName]) { 14131 this._setEventListener(element, baseName, eventName, getter); 14132 } 14133 } 14134 } 14135 _setBackgroundColor(element) { 14136 const color = this.data.backgroundColor || null; 14137 element.style.backgroundColor = color === null ? "transparent" : _util.Util.makeHexColor(color[0], color[1], color[2]); 14138 } 14139 _setTextStyle(element) { 14140 const TEXT_ALIGNMENT = ["left", "center", "right"]; 14141 const { 14142 fontColor 14143 } = this.data.defaultAppearanceData; 14144 const fontSize = this.data.defaultAppearanceData.fontSize || DEFAULT_FONT_SIZE; 14145 const style = element.style;
vendor: 25,984 bytes, lines 14146-14872
14146 let computedFontSize; 14147 const BORDER_SIZE = 2; 14148 const roundToOneDecimal = x => Math.round(10 * x) / 10; 14149 if (this.data.multiLine) { 14150 const height = Math.abs(this.data.rect[3] - this.data.rect[1] - BORDER_SIZE); 14151 const numberOfLines = Math.round(height / (_util.LINE_FACTOR * fontSize)) || 1; 14152 const lineHeight = height / numberOfLines; 14153 computedFontSize = Math.min(fontSize, roundToOneDecimal(lineHeight / _util.LINE_FACTOR)); 14154 } else { 14155 const height = Math.abs(this.data.rect[3] - this.data.rect[1] - BORDER_SIZE); 14156 computedFontSize = Math.min(fontSize, roundToOneDecimal(height / _util.LINE_FACTOR)); 14157 } 14158 style.fontSize = `calc(${computedFontSize}px * var(--scale-factor))`; 14159 style.color = _util.Util.makeHexColor(fontColor[0], fontColor[1], fontColor[2]); 14160 if (this.data.textAlignment !== null) { 14161 style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment]; 14162 } 14163 } 14164 _setRequired(element, isRequired) { 14165 if (isRequired) { 14166 element.setAttribute("required", true); 14167 } else { 14168 element.removeAttribute("required"); 14169 } 14170 element.setAttribute("aria-required", isRequired); 14171 } 14172} 14173class TextWidgetAnnotationElement extends WidgetAnnotationElement { 14174 constructor(parameters) { 14175 const isRenderable = parameters.renderForms || !parameters.data.hasAppearance && !!parameters.data.fieldValue; 14176 super(parameters, { 14177 isRenderable 14178 }); 14179 } 14180 setPropertyOnSiblings(base, key, value, keyInStorage) { 14181 const storage = this.annotationStorage; 14182 for (const element of this._getElementsByName(base.name, base.id)) { 14183 if (element.domElement) { 14184 element.domElement[key] = value; 14185 } 14186 storage.setValue(element.id, { 14187 [keyInStorage]: value 14188 }); 14189 } 14190 } 14191 render() { 14192 const storage = this.annotationStorage; 14193 const id = this.data.id; 14194 this.container.classList.add("textWidgetAnnotation"); 14195 let element = null; 14196 if (this.renderForms) { 14197 const storedData = storage.getValue(id, { 14198 value: this.data.fieldValue 14199 }); 14200 let textContent = storedData.value || ""; 14201 const maxLen = storage.getValue(id, { 14202 charLimit: this.data.maxLen 14203 }).charLimit; 14204 if (maxLen && textContent.length > maxLen) { 14205 textContent = textContent.slice(0, maxLen); 14206 } 14207 let fieldFormattedValues = storedData.formattedValue || this.data.textContent?.join("\n") || null; 14208 if (fieldFormattedValues && this.data.comb) { 14209 fieldFormattedValues = fieldFormattedValues.replaceAll(/\s+/g, ""); 14210 } 14211 const elementData = { 14212 userValue: textContent, 14213 formattedValue: fieldFormattedValues, 14214 lastCommittedValue: null, 14215 commitKey: 1 14216 }; 14217 if (this.data.multiLine) { 14218 element = document.createElement("textarea"); 14219 element.textContent = fieldFormattedValues ?? textContent; 14220 if (this.data.doNotScroll) { 14221 element.style.overflowY = "hidden"; 14222 } 14223 } else { 14224 element = document.createElement("input"); 14225 element.type = "text"; 14226 element.setAttribute("value", fieldFormattedValues ?? textContent); 14227 if (this.data.doNotScroll) { 14228 element.style.overflowX = "hidden"; 14229 } 14230 } 14231 if (this.data.hasOwnCanvas) { 14232 element.hidden = true; 14233 } 14234 GetElementsByNameSet.add(element); 14235 element.setAttribute("data-element-id", id); 14236 element.disabled = this.data.readOnly; 14237 element.name = this.data.baseFieldName || this.data.fieldName; 14238 element.tabIndex = DEFAULT_TAB_INDEX; 14239 this._setRequired(element, this.data.required); 14240 if (maxLen) { 14241 element.maxLength = maxLen; 14242 } 14243 element.addEventListener("input", event => { 14244 storage.setValue(id, { 14245 value: event.target.value 14246 }); 14247 this.setPropertyOnSiblings(element, "value", event.target.value, "value"); 14248 elementData.formattedValue = null; 14249 }); 14250 element.addEventListener("resetform", event => { 14251 const defaultValue = this.data.defaultFieldValue ?? ""; 14252 element.value = elementData.userValue = defaultValue; 14253 elementData.formattedValue = null; 14254 }); 14255 let blurListener = event => { 14256 const { 14257 formattedValue 14258 } = elementData; 14259 if (formattedValue !== null && formattedValue !== undefined) { 14260 event.target.value = formattedValue; 14261 } 14262 event.target.scrollLeft = 0; 14263 }; 14264 if (this.enableScripting && this.hasJSActions) { 14265 element.addEventListener("focus", event => { 14266 const { 14267 target 14268 } = event; 14269 if (elementData.userValue) { 14270 target.value = elementData.userValue; 14271 } 14272 elementData.lastCommittedValue = target.value; 14273 elementData.commitKey = 1; 14274 }); 14275 element.addEventListener("updatefromsandbox", jsEvent => { 14276 this.showElementAndHideCanvas(jsEvent.target); 14277 const actions = { 14278 value(event) { 14279 elementData.userValue = event.detail.value ?? ""; 14280 storage.setValue(id, { 14281 value: elementData.userValue.toString() 14282 }); 14283 event.target.value = elementData.userValue; 14284 }, 14285 formattedValue(event) { 14286 const { 14287 formattedValue 14288 } = event.detail; 14289 elementData.formattedValue = formattedValue; 14290 if (formattedValue !== null && formattedValue !== undefined && event.target !== document.activeElement) { 14291 event.target.value = formattedValue; 14292 } 14293 storage.setValue(id, { 14294 formattedValue 14295 }); 14296 }, 14297 selRange(event) { 14298 event.target.setSelectionRange(...event.detail.selRange); 14299 }, 14300 charLimit: event => { 14301 const { 14302 charLimit 14303 } = event.detail; 14304 const { 14305 target 14306 } = event; 14307 if (charLimit === 0) { 14308 target.removeAttribute("maxLength"); 14309 return; 14310 } 14311 target.setAttribute("maxLength", charLimit); 14312 let value = elementData.userValue; 14313 if (!value || value.length <= charLimit) { 14314 return; 14315 } 14316 value = value.slice(0, charLimit); 14317 target.value = elementData.userValue = value; 14318 storage.setValue(id, { 14319 value 14320 }); 14321 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14322 source: this, 14323 detail: { 14324 id, 14325 name: "Keystroke", 14326 value, 14327 willCommit: true, 14328 commitKey: 1, 14329 selStart: target.selectionStart, 14330 selEnd: target.selectionEnd 14331 } 14332 }); 14333 } 14334 }; 14335 this._dispatchEventFromSandbox(actions, jsEvent); 14336 }); 14337 element.addEventListener("keydown", event => { 14338 elementData.commitKey = 1; 14339 let commitKey = -1; 14340 if (event.key === "Escape") { 14341 commitKey = 0; 14342 } else if (event.key === "Enter" && !this.data.multiLine) { 14343 commitKey = 2; 14344 } else if (event.key === "Tab") { 14345 elementData.commitKey = 3; 14346 } 14347 if (commitKey === -1) { 14348 return; 14349 } 14350 const { 14351 value 14352 } = event.target; 14353 if (elementData.lastCommittedValue === value) { 14354 return; 14355 } 14356 elementData.lastCommittedValue = value; 14357 elementData.userValue = value; 14358 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14359 source: this, 14360 detail: { 14361 id, 14362 name: "Keystroke", 14363 value, 14364 willCommit: true, 14365 commitKey, 14366 selStart: event.target.selectionStart, 14367 selEnd: event.target.selectionEnd 14368 } 14369 }); 14370 }); 14371 const _blurListener = blurListener; 14372 blurListener = null; 14373 element.addEventListener("blur", event => { 14374 if (!event.relatedTarget) { 14375 return; 14376 } 14377 const { 14378 value 14379 } = event.target; 14380 elementData.userValue = value; 14381 if (elementData.lastCommittedValue !== value) { 14382 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14383 source: this, 14384 detail: { 14385 id, 14386 name: "Keystroke", 14387 value, 14388 willCommit: true, 14389 commitKey: elementData.commitKey, 14390 selStart: event.target.selectionStart, 14391 selEnd: event.target.selectionEnd 14392 } 14393 }); 14394 } 14395 _blurListener(event); 14396 }); 14397 if (this.data.actions?.Keystroke) { 14398 element.addEventListener("beforeinput", event => { 14399 elementData.lastCommittedValue = null; 14400 const { 14401 data, 14402 target 14403 } = event; 14404 const { 14405 value, 14406 selectionStart, 14407 selectionEnd 14408 } = target; 14409 let selStart = selectionStart, 14410 selEnd = selectionEnd; 14411 switch (event.inputType) { 14412 case "deleteWordBackward": 14413 { 14414 const match = value.substring(0, selectionStart).match(/\w*[^\w]*$/); 14415 if (match) { 14416 selStart -= match[0].length; 14417 } 14418 break; 14419 } 14420 case "deleteWordForward": 14421 { 14422 const match = value.substring(selectionStart).match(/^[^\w]*\w*/); 14423 if (match) { 14424 selEnd += match[0].length; 14425 } 14426 break; 14427 } 14428 case "deleteContentBackward": 14429 if (selectionStart === selectionEnd) { 14430 selStart -= 1; 14431 } 14432 break; 14433 case "deleteContentForward": 14434 if (selectionStart === selectionEnd) { 14435 selEnd += 1; 14436 } 14437 break; 14438 } 14439 event.preventDefault(); 14440 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14441 source: this, 14442 detail: { 14443 id, 14444 name: "Keystroke", 14445 value, 14446 change: data || "", 14447 willCommit: false, 14448 selStart, 14449 selEnd 14450 } 14451 }); 14452 }); 14453 } 14454 this._setEventListeners(element, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.value); 14455 } 14456 if (blurListener) { 14457 element.addEventListener("blur", blurListener); 14458 } 14459 if (this.data.comb) { 14460 const fieldWidth = this.data.rect[2] - this.data.rect[0]; 14461 const combWidth = fieldWidth / maxLen; 14462 element.classList.add("comb"); 14463 element.style.letterSpacing = `calc(${combWidth}px * var(--scale-factor) - 1ch)`; 14464 } 14465 } else { 14466 element = document.createElement("div"); 14467 element.textContent = this.data.fieldValue; 14468 element.style.verticalAlign = "middle"; 14469 element.style.display = "table-cell"; 14470 } 14471 this._setTextStyle(element); 14472 this._setBackgroundColor(element); 14473 this._setDefaultPropertiesFromJS(element); 14474 this.container.append(element); 14475 return this.container; 14476 } 14477} 14478class SignatureWidgetAnnotationElement extends WidgetAnnotationElement { 14479 constructor(parameters) { 14480 super(parameters, { 14481 isRenderable: !!parameters.data.hasOwnCanvas 14482 }); 14483 } 14484} 14485class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement { 14486 constructor(parameters) { 14487 super(parameters, { 14488 isRenderable: parameters.renderForms 14489 }); 14490 } 14491 render() { 14492 const storage = this.annotationStorage; 14493 const data = this.data; 14494 const id = data.id; 14495 let value = storage.getValue(id, { 14496 value: data.exportValue === data.fieldValue 14497 }).value; 14498 if (typeof value === "string") { 14499 value = value !== "Off"; 14500 storage.setValue(id, { 14501 value 14502 }); 14503 } 14504 this.container.classList.add("buttonWidgetAnnotation", "checkBox"); 14505 const element = document.createElement("input"); 14506 GetElementsByNameSet.add(element); 14507 element.setAttribute("data-element-id", id); 14508 element.disabled = data.readOnly; 14509 this._setRequired(element, this.data.required); 14510 element.type = "checkbox"; 14511 element.name = data.baseFieldName || data.fieldName; 14512 if (value) { 14513 element.setAttribute("checked", true); 14514 } 14515 element.setAttribute("exportValue", data.exportValue); 14516 element.tabIndex = DEFAULT_TAB_INDEX; 14517 element.addEventListener("change", event => { 14518 const { 14519 name, 14520 checked 14521 } = event.target; 14522 for (const checkbox of this._getElementsByName(name, id)) { 14523 const curChecked = checked && checkbox.exportValue === data.exportValue; 14524 if (checkbox.domElement) { 14525 checkbox.domElement.checked = curChecked; 14526 } 14527 storage.setValue(checkbox.id, { 14528 value: curChecked 14529 }); 14530 } 14531 storage.setValue(id, { 14532 value: checked 14533 }); 14534 }); 14535 element.addEventListener("resetform", event => { 14536 const defaultValue = data.defaultFieldValue || "Off"; 14537 event.target.checked = defaultValue === data.exportValue; 14538 }); 14539 if (this.enableScripting && this.hasJSActions) { 14540 element.addEventListener("updatefromsandbox", jsEvent => { 14541 const actions = { 14542 value(event) { 14543 event.target.checked = event.detail.value !== "Off"; 14544 storage.setValue(id, { 14545 value: event.target.checked 14546 }); 14547 } 14548 }; 14549 this._dispatchEventFromSandbox(actions, jsEvent); 14550 }); 14551 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); 14552 } 14553 this._setBackgroundColor(element); 14554 this._setDefaultPropertiesFromJS(element); 14555 this.container.append(element); 14556 return this.container; 14557 } 14558} 14559class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement { 14560 constructor(parameters) { 14561 super(parameters, { 14562 isRenderable: parameters.renderForms 14563 }); 14564 } 14565 render() { 14566 this.container.classList.add("buttonWidgetAnnotation", "radioButton"); 14567 const storage = this.annotationStorage; 14568 const data = this.data; 14569 const id = data.id; 14570 let value = storage.getValue(id, { 14571 value: data.fieldValue === data.buttonValue 14572 }).value; 14573 if (typeof value === "string") { 14574 value = value !== data.buttonValue; 14575 storage.setValue(id, { 14576 value 14577 }); 14578 } 14579 const element = document.createElement("input"); 14580 GetElementsByNameSet.add(element); 14581 element.setAttribute("data-element-id", id); 14582 element.disabled = data.readOnly; 14583 this._setRequired(element, this.data.required); 14584 element.type = "radio"; 14585 element.name = data.baseFieldName || data.fieldName; 14586 if (value) { 14587 element.setAttribute("checked", true); 14588 } 14589 element.tabIndex = DEFAULT_TAB_INDEX; 14590 element.addEventListener("change", event => { 14591 const { 14592 name, 14593 checked 14594 } = event.target; 14595 for (const radio of this._getElementsByName(name, id)) { 14596 storage.setValue(radio.id, { 14597 value: false 14598 }); 14599 } 14600 storage.setValue(id, { 14601 value: checked 14602 }); 14603 }); 14604 element.addEventListener("resetform", event => { 14605 const defaultValue = data.defaultFieldValue; 14606 event.target.checked = defaultValue !== null && defaultValue !== undefined && defaultValue === data.buttonValue; 14607 }); 14608 if (this.enableScripting && this.hasJSActions) { 14609 const pdfButtonValue = data.buttonValue; 14610 element.addEventListener("updatefromsandbox", jsEvent => { 14611 const actions = { 14612 value: event => { 14613 const checked = pdfButtonValue === event.detail.value; 14614 for (const radio of this._getElementsByName(event.target.name)) { 14615 const curChecked = checked && radio.id === id; 14616 if (radio.domElement) { 14617 radio.domElement.checked = curChecked; 14618 } 14619 storage.setValue(radio.id, { 14620 value: curChecked 14621 }); 14622 } 14623 } 14624 }; 14625 this._dispatchEventFromSandbox(actions, jsEvent); 14626 }); 14627 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); 14628 } 14629 this._setBackgroundColor(element); 14630 this._setDefaultPropertiesFromJS(element); 14631 this.container.append(element); 14632 return this.container; 14633 } 14634} 14635class PushButtonWidgetAnnotationElement extends LinkAnnotationElement { 14636 constructor(parameters) { 14637 super(parameters, { 14638 ignoreBorder: parameters.data.hasAppearance 14639 }); 14640 } 14641 render() { 14642 const container = super.render(); 14643 container.classList.add("buttonWidgetAnnotation", "pushButton"); 14644 if (this.data.alternativeText) { 14645 container.title = this.data.alternativeText; 14646 } 14647 const linkElement = container.lastChild; 14648 if (this.enableScripting && this.hasJSActions && linkElement) { 14649 this._setDefaultPropertiesFromJS(linkElement); 14650 linkElement.addEventListener("updatefromsandbox", jsEvent => { 14651 this._dispatchEventFromSandbox({}, jsEvent); 14652 }); 14653 } 14654 return container; 14655 } 14656} 14657class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { 14658 constructor(parameters) { 14659 super(parameters, { 14660 isRenderable: parameters.renderForms 14661 }); 14662 } 14663 render() { 14664 this.container.classList.add("choiceWidgetAnnotation"); 14665 const storage = this.annotationStorage; 14666 const id = this.data.id; 14667 const storedData = storage.getValue(id, { 14668 value: this.data.fieldValue 14669 }); 14670 const selectElement = document.createElement("select"); 14671 GetElementsByNameSet.add(selectElement); 14672 selectElement.setAttribute("data-element-id", id); 14673 selectElement.disabled = this.data.readOnly; 14674 this._setRequired(selectElement, this.data.required); 14675 selectElement.name = this.data.baseFieldName || this.data.fieldName; 14676 selectElement.tabIndex = DEFAULT_TAB_INDEX; 14677 let addAnEmptyEntry = this.data.combo && this.data.options.length > 0; 14678 if (!this.data.combo) { 14679 selectElement.size = this.data.options.length; 14680 if (this.data.multiSelect) { 14681 selectElement.multiple = true; 14682 } 14683 } 14684 selectElement.addEventListener("resetform", event => { 14685 const defaultValue = this.data.defaultFieldValue; 14686 for (const option of selectElement.options) { 14687 option.selected = option.value === defaultValue; 14688 } 14689 }); 14690 for (const option of this.data.options) { 14691 const optionElement = document.createElement("option"); 14692 optionElement.textContent = option.displayValue; 14693 optionElement.value = option.exportValue; 14694 if (storedData.value.includes(option.exportValue)) { 14695 optionElement.setAttribute("selected", true); 14696 addAnEmptyEntry = false; 14697 } 14698 selectElement.append(optionElement); 14699 } 14700 let removeEmptyEntry = null; 14701 if (addAnEmptyEntry) { 14702 const noneOptionElement = document.createElement("option"); 14703 noneOptionElement.value = " "; 14704 noneOptionElement.setAttribute("hidden", true); 14705 noneOptionElement.setAttribute("selected", true); 14706 selectElement.prepend(noneOptionElement); 14707 removeEmptyEntry = () => { 14708 noneOptionElement.remove(); 14709 selectElement.removeEventListener("input", removeEmptyEntry); 14710 removeEmptyEntry = null; 14711 }; 14712 selectElement.addEventListener("input", removeEmptyEntry); 14713 } 14714 const getValue = isExport => { 14715 const name = isExport ? "value" : "textContent"; 14716 const { 14717 options, 14718 multiple 14719 } = selectElement; 14720 if (!multiple) { 14721 return options.selectedIndex === -1 ? null : options[options.selectedIndex][name]; 14722 } 14723 return Array.prototype.filter.call(options, option => option.selected).map(option => option[name]); 14724 }; 14725 let selectedValues = getValue(false); 14726 const getItems = event => { 14727 const options = event.target.options; 14728 return Array.prototype.map.call(options, option => { 14729 return { 14730 displayValue: option.textContent, 14731 exportValue: option.value 14732 }; 14733 }); 14734 }; 14735 if (this.enableScripting && this.hasJSActions) { 14736 selectElement.addEventListener("updatefromsandbox", jsEvent => { 14737 const actions = { 14738 value(event) { 14739 removeEmptyEntry?.(); 14740 const value = event.detail.value; 14741 const values = new Set(Array.isArray(value) ? value : [value]); 14742 for (const option of selectElement.options) { 14743 option.selected = values.has(option.value); 14744 } 14745 storage.setValue(id, { 14746 value: getValue(true) 14747 }); 14748 selectedValues = getValue(false); 14749 }, 14750 multipleSelection(event) { 14751 selectElement.multiple = true; 14752 }, 14753 remove(event) { 14754 const options = selectElement.options; 14755 const index = event.detail.remove; 14756 options[index].selected = false; 14757 selectElement.remove(index); 14758 if (options.length > 0) { 14759 const i = Array.prototype.findIndex.call(options, option => option.selected); 14760 if (i === -1) { 14761 options[0].selected = true; 14762 } 14763 } 14764 storage.setValue(id, { 14765 value: getValue(true), 14766 items: getItems(event) 14767 }); 14768 selectedValues = getValue(false); 14769 }, 14770 clear(event) { 14771 while (selectElement.length !== 0) { 14772 selectElement.remove(0); 14773 } 14774 storage.setValue(id, { 14775 value: null, 14776 items: [] 14777 }); 14778 selectedValues = getValue(false); 14779 }, 14780 insert(event) { 14781 const { 14782 index, 14783 displayValue, 14784 exportValue 14785 } = event.detail.insert; 14786 const selectChild = selectElement.children[index]; 14787 const optionElement = document.createElement("option"); 14788 optionElement.textContent = displayValue; 14789 optionElement.value = exportValue; 14790 if (selectChild) { 14791 selectChild.before(optionElement); 14792 } else { 14793 selectElement.append(optionElement); 14794 } 14795 storage.setValue(id, { 14796 value: getValue(true), 14797 items: getItems(event) 14798 }); 14799 selectedValues = getValue(false); 14800 }, 14801 items(event) { 14802 const { 14803 items 14804 } = event.detail; 14805 while (selectElement.length !== 0) { 14806 selectElement.remove(0); 14807 } 14808 for (const item of items) { 14809 const { 14810 displayValue, 14811 exportValue 14812 } = item; 14813 const optionElement = document.createElement("option"); 14814 optionElement.textContent = displayValue; 14815 optionElement.value = exportValue; 14816 selectElement.append(optionElement); 14817 } 14818 if (selectElement.options.length > 0) { 14819 selectElement.options[0].selected = true; 14820 } 14821 storage.setValue(id, { 14822 value: getValue(true), 14823 items: getItems(event) 14824 }); 14825 selectedValues = getValue(false); 14826 }, 14827 indices(event) { 14828 const indices = new Set(event.detail.indices); 14829 for (const option of event.target.options) { 14830 option.selected = indices.has(option.index); 14831 } 14832 storage.setValue(id, { 14833 value: getValue(true) 14834 }); 14835 selectedValues = getValue(false); 14836 }, 14837 editable(event) { 14838 event.target.disabled = !event.detail.editable; 14839 } 14840 }; 14841 this._dispatchEventFromSandbox(actions, jsEvent); 14842 }); 14843 selectElement.addEventListener("input", event => { 14844 const exportValue = getValue(true); 14845 storage.setValue(id, { 14846 value: exportValue 14847 }); 14848 event.preventDefault(); 14849 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 14850 source: this, 14851 detail: { 14852 id, 14853 name: "Keystroke", 14854 value: selectedValues, 14855 changeEx: exportValue, 14856 willCommit: false, 14857 commitKey: 1, 14858 keyDown: false 14859 } 14860 }); 14861 }); 14862 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); 14863 } else { 14864 selectElement.addEventListener("input", function (event) { 14865 storage.setValue(id, { 14866 value: getValue(true) 14867 }); 14868 }); 14869 } 14870 if (this.data.combo) { 14871 this._setTextStyle(selectElement); 14872 } else {}
14873 this._setBackgroundColor(selectElement); 14874 this._setDefaultPropertiesFromJS(selectElement); 14875 this.container.append(selectElement); 14876 return this.container; 14877 } 14878} 14879class PopupAnnotationElement extends AnnotationElement { 14880 constructor(parameters) { 14881 const { 14882 data, 14883 elements 14884 } = parameters; 14885 const isRenderable = !!(data.titleObj?.str || data.contentsObj?.str || data.richText?.str); 14886 super(parameters, { 14887 isRenderable 14888 }); 14889 this.elements = elements; 14890 } 14891 render() { 14892 this.container.classList.add("popupAnnotation"); 14893 const popup = new PopupElement({ 14894 container: this.container, 14895 color: this.data.color, 14896 titleObj: this.data.titleObj, 14897 modificationDate: this.data.modificationDate, 14898 contentsObj: this.data.contentsObj, 14899 richText: this.data.richText, 14900 rect: this.data.rect, 14901 parentRect: this.data.parentRect || null, 14902 parent: this.parent, 14903 elements: this.elements, 14904 open: this.data.open 14905 }); 14906 const elementIds = []; 14907 for (const element of this.elements) { 14908 element.popup = popup; 14909 elementIds.push(element.data.id); 14910 element.addHighlightArea(); 14911 } 14912 this.container.setAttribute("aria-controls", elementIds.join(",")); 14913 return this.container; 14914 } 14915} 14916class PopupElement { 14917 #dateTimePromise = null; 14918 #boundHide = this.#hide.bind(this); 14919 #boundShow = this.#show.bind(this); 14920 #boundToggle = this.#toggle.bind(this); 14921 #color = null; 14922 #container = null; 14923 #contentsObj = null; 14924 #elements = null; 14925 #parent = null; 14926 #parentRect = null; 14927 #pinned = false; 14928 #popup = null; 14929 #rect = null; 14930 #richText = null; 14931 #titleObj = null; 14932 #wasVisible = false; 14933 constructor({ 14934 container, 14935 color, 14936 elements, 14937 titleObj, 14938 modificationDate, 14939 contentsObj, 14940 richText, 14941 parent, 14942 rect, 14943 parentRect, 14944 open 14945 }) { 14946 this.#container = container; 14947 this.#titleObj = titleObj; 14948 this.#contentsObj = contentsObj; 14949 this.#richText = richText; 14950 this.#parent = parent; 14951 this.#color = color; 14952 this.#rect = rect; 14953 this.#parentRect = parentRect; 14954 this.#elements = elements; 14955 const dateObject = _display_utils.PDFDateString.toDateObject(modificationDate); 14956 if (dateObject) { 14957 this.#dateTimePromise = parent.l10n.get("annotation_date_string", { 14958 date: dateObject.toLocaleDateString(), 14959 time: dateObject.toLocaleTimeString() 14960 }); 14961 } 14962 this.trigger = elements.flatMap(e => e.getElementsToTriggerPopup()); 14963 for (const element of this.trigger) { 14964 element.addEventListener("click", this.#boundToggle); 14965 element.addEventListener("mouseenter", this.#boundShow); 14966 element.addEventListener("mouseleave", this.#boundHide); 14967 } 14968 this.#container.hidden = true; 14969 if (open) { 14970 this.#toggle(); 14971 } 14972 } 14973 render() { 14974 if (this.#popup) { 14975 return; 14976 } 14977 const { 14978 page: { 14979 view 14980 }, 14981 viewport: { 14982 rawDims: { 14983 pageWidth, 14984 pageHeight, 14985 pageX, 14986 pageY 14987 } 14988 } 14989 } = this.#parent; 14990 const popup = this.#popup = document.createElement("div"); 14991 popup.className = "popup"; 14992 if (this.#color) { 14993 const baseColor = popup.style.outlineColor = _util.Util.makeHexColor(...this.#color); 14994 if (CSS.supports("background-color", "color-mix(in srgb, red 30%, white)")) { 14995 popup.style.backgroundColor = `color-mix(in srgb, ${baseColor} 30%, white)`; 14996 } else { 14997 const BACKGROUND_ENLIGHT = 0.7; 14998 popup.style.backgroundColor = _util.Util.makeHexColor(...this.#color.map(c => Math.floor(BACKGROUND_ENLIGHT * (255 - c) + c))); 14999 } 15000 } 15001 const header = document.createElement("span"); 15002 header.className = "header"; 15003 const title = document.createElement("h1"); 15004 header.append(title); 15005 ({ 15006 dir: title.dir, 15007 str: title.textContent 15008 } = this.#titleObj); 15009 popup.append(header); 15010 if (this.#dateTimePromise) { 15011 const modificationDate = document.createElement("span"); 15012 modificationDate.classList.add("popupDate"); 15013 this.#dateTimePromise.then(localized => { 15014 modificationDate.textContent = localized; 15015 }); 15016 header.append(modificationDate); 15017 } 15018 const contentsObj = this.#contentsObj; 15019 const richText = this.#richText; 15020 if (richText?.str && (!contentsObj?.str || contentsObj.str === richText.str)) { 15021 _xfa_layer.XfaLayer.render({ 15022 xfaHtml: richText.html, 15023 intent: "richText", 15024 div: popup 15025 }); 15026 popup.lastChild.classList.add("richText", "popupContent"); 15027 } else { 15028 const contents = this._formatContents(contentsObj); 15029 popup.append(contents); 15030 } 15031 let useParentRect = !!this.#parentRect; 15032 let rect = useParentRect ? this.#parentRect : this.#rect; 15033 for (const element of this.#elements) { 15034 if (!rect || _util.Util.intersect(element.data.rect, rect) !== null) { 15035 rect = element.data.rect; 15036 useParentRect = true; 15037 break; 15038 } 15039 } 15040 const normalizedRect = _util.Util.normalizeRect([rect[0], view[3] - rect[1] + view[
150401], rect[2], view[3] - rect[3] + view[1]]); 15041 const HORIZONTAL_SPACE_AFTER_ANNOTATION = 5; 15042 const parentWidth = useParentRect ? rect[2] - rect[0] + HORIZONTAL_SPACE_AFTER_ANNOTATION : 0; 15043 const popupLeft = normalizedRect[0] + parentWidth; 15044 const popupTop = normalizedRect[1]; 15045 const { 15046 style 15047 } = this.#container; 15048 style.left = `${100 * (popupLeft - pageX) / pageWidth}%`; 15049 style.top = `${100 * (popupTop - pageY) / pageHeight}%`; 15050 this.#container.append(popup); 15051 } 15052 _formatContents({ 15053 str, 15054 dir 15055 }) { 15056 const p = document.createElement("p"); 15057 p.classList.add("popupContent"); 15058 p.dir = dir; 15059 const lines = str.split(/(?:\r\n?|\n)/); 15060 for (let i = 0, ii = lines.length; i < ii; ++i) { 15061 const line = lines[i]; 15062 p.append(document.createTextNode(line)); 15063 if (i < ii - 1) { 15064 p.append(document.createElement("br")); 15065 } 15066 } 15067 return p; 15068 } 15069 #toggle() { 15070 this.#pinned = !this.#pinned; 15071 if (this.#pinned) { 15072 this.#show(); 15073 this.#container.addEventListener("click", this.#boundToggle); 15074 } else { 15075 this.#hide(); 15076 this.#container.removeEventListener("click", this.#boundToggle); 15077 } 15078 } 15079 #show() { 15080 if (!this.#popup) { 15081 this.render(); 15082 } 15083 if (!this.isVisible) { 15084 this.#container.hidden = false; 15085 this.#container.style.zIndex = parseInt(this.#container.style.zIndex) + 1000; 15086 } else if (this.#pinned) { 15087 this.#container.classList.add("focused"); 15088 } 15089 } 15090 #hide() { 15091 this.#container.classList.remove("focused"); 15092 if (this.#pinned || !this.isVisible) { 15093 return; 15094 } 15095 this.#container.hidden = true; 15096 this.#container.style.zIndex = parseInt(this.#container.style.zIndex) - 1000; 15097 } 15098 forceHide() { 15099 this.#wasVisible = this.isVisible; 15100 if (!this.#wasVisible) { 15101 return; 15102 } 15103 this.#container.hidden = true; 15104 } 15105 maybeShow() { 15106 if (!this.#wasVisible) { 15107 return; 15108 } 15109 this.#wasVisible = false; 15110 this.#container.hidden = false; 15111 } 15112 get isVisible() { 15113 return this.#container.hidden === false; 15114 } 15115} 15116class FreeTextAnnotationElement extends AnnotationElement { 15117 constructor(parameters) { 15118 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15119 super(parameters, { 15120 isRenderable, 15121 ignoreBorder: true 15122 }); 15123 this.textContent = parameters.data.textContent; 15124 this.textPosition = parameters.data.textPosition; 15125 this.annotationEditorType = _util.AnnotationEditorType.FREETEXT; 15126 } 15127 render() { 15128 this.container.classList.add("freeTextAnnotation"); 15129 if (this.textContent) { 15130 const content = document.createElement("div"); 15131 content.classList.add("annotationTextContent"); 15132 content.setAttribute("role", "comment"); 15133 for (const line of this.textContent) { 15134 const lineSpan = document.createElement("span"); 15135 lineSpan.textContent = line; 15136 content.append(lineSpan); 15137 } 15138 this.container.append(content); 15139 } 15140 if (!this.data.popupRef) { 15141 this._createPopup(); 15142 } 15143 this._editOnDoubleClick(); 15144 return this.container; 15145 } 15146} 15147exports.FreeTextAnnotationElement = FreeTextAnnotationElement; 15148class LineAnnotationElement extends AnnotationElement { 15149 #line = null; 15150 constructor(parameters) { 15151 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15152 super(parameters, { 15153 isRenderable, 15154 ignoreBorder: true 15155 }); 15156 } 15157 render() { 15158 this.container.classList.add("lineAnnotation"); 15159 const data = this.data; 15160 const { 15161 width, 15162 height 15163 } = getRectDims(data.rect); 15164 const svg = this.svgFactory.create(width, height, true); 15165 const line = this.#line = this.svgFactory.createElement("svg:line"); 15166 line.setAttribute("x1", data.rect[2] - data.lineCoordinates[0]); 15167 line.setAttribute("y1", data.rect[3] - data.lineCoordinates[1]); 15168 line.setAttribute("x2", data.rect[2] - data.lineCoordinates[2]); 15169 line.setAttribute("y2", data.rect[3] - data.lineCoordinates[3]); 15170 line.setAttribute("stroke-width", data.borderStyle.width || 1); 15171 line.setAttribute("stroke", "transparent"); 15172 line.setAttribute("fill", "transparent"); 15173 svg.append(line); 15174 this.container.append(svg); 15175 if (!data.popupRef) { 15176 this._createPopup(); 15177 } 15178 return this.container; 15179 } 15180 getElementsToTriggerPopup() { 15181 return this.#line; 15182 } 15183 addHighlightArea() { 15184 this.container.classList.add("highlightArea"); 15185 } 15186} 15187class SquareAnnotationElement extends AnnotationElement { 15188 #square = null; 15189 constructor(parameters) { 15190 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15191 super(parameters, { 15192 isRenderable, 15193 ignoreBorder: true 15194 }); 15195 } 15196 render() { 15197 this.container.classList.add("squareAnnotation"); 15198 const data = this.data; 15199 const { 15200 width, 15201 height 15202 } = getRectDims(data.rect); 15203 const svg = this.svgFactory.create(width, height, true); 15204 const borderWidth = data.borderStyle.width; 15205 const square = this.#square = this.svgFactory.createElement("svg:rect"); 15206 square.setAttribute("x", borderWidth / 2); 15207 square.setAttribute("y", borderWidth / 2); 15208 square.setAttribute("width", width - borderWidth); 15209 square.setAttribute("height", height - borderWidth); 15210 square.setAttribute("stroke-width", borderWidth || 1); 15211 square.setAttribute("stroke", "transparent"); 15212 square.setAttribute("fill", "transparent"); 15213 svg.append(square); 15214 this.container.append(svg); 15215 if (!data.popupRef) { 15216 this._createPopup(); 15217 } 15218 return this.container; 15219 } 15220 getElementsToTriggerPopup() { 15221 return this.#square; 15222 } 15223 addHighlightArea() { 15224 this.container.classList.add("highlightArea"); 15225 } 15226} 15227class CircleAnnotationElement extends AnnotationElement { 15228 #circle = null; 15229 constructor(parameters) { 15230 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15231 super(parameters, { 15232 isRenderable, 15233 ignoreBorder: true 15234 }); 15235 } 15236 render() { 15237 this.container.classList.add("circleAnnotation"); 15238 const data = this.data; 15239 const { 15240 width, 15241 height 15242 } = getRectDims(data.rect); 15243 const svg = this.svgFactory.create(width, height, true); 15244 const borderWidth = data.borderStyle.width; 15245 const circle = this.#circle = this.svgFactory.createElement("svg:ellipse"); 15246 circle.setAttribute("cx", width / 2); 15247 circle.setAttribute("cy", height / 2); 15248 circle.setAttribute("rx", width / 2 - borderWidth / 2); 15249 circle.setAttribute("ry", height / 2 - borderWidth / 2); 15250 circle.setAttribute("stroke-width", borderWidth || 1); 15251 circle.setAttribute("stroke", "transparent"); 15252 circle.setAttribute("fill", "transparent"); 15253 svg.append(circle); 15254 this.container.append(svg); 15255 if (!data.popupRef) { 15256 this._createPopup(); 15257 } 15258 return this.container; 15259 } 15260 getElementsToTriggerPopup() { 15261 return this.#circle; 15262 } 15263 addHighlightArea() { 15264 this.container.classList.add("highlightArea"); 15265 } 15266} 15267class PolylineAnnotationElement extends AnnotationElement { 15268 #polyline = null; 15269 constructor(parameters) { 15270 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15271 super(parameters, { 15272 isRenderable, 15273 ignoreBorder: true 15274 }); 15275 this.containerClassName = "polylineAnnotation"; 15276 this.svgElementName = "svg:polyline"; 15277 } 15278 render() { 15279 this.container.classList.add(this.containerClassName); 15280 const data = this.data; 15281 const { 15282 width, 15283 height 15284 } = getRectDims(data.rect); 15285 const svg = this.svgFactory.create(width, height, true); 15286 let points = []; 15287 for (const coordinate of data.vertices) { 15288 const x = coordinate.x - data.rect[0];
15289 const y = data.rect[3] - coordinate.y; 15290 points.push(x + "," + y); 15291 } 15292 points = points.join(" "); 15293 const polyline = this.#polyline = this.svgFactory.createElement(this.svgElementName); 15294 polyline.setAttribute("points", points); 15295 polyline.setAttribute("stroke-width", data.borderStyle.width || 1); 15296 polyline.setAttribute("stroke", "transparent"); 15297 polyline.setAttribute("fill", "transparent"); 15298 svg.append(polyline); 15299 this.container.append(svg); 15300 if (!data.popupRef) { 15301 this._createPopup(polyline, data); 15302 } 15303 return this.container; 15304 } 15305 getElementsToTriggerPopup() { 15306 return this.#polyline; 15307 } 15308 addHighlightArea() { 15309 this.container.classList.add("highlightArea"); 15310 } 15311} 15312class PolygonAnnotationElement extends PolylineAnnotationElement { 15313 constructor(parameters) { 15314 super(parameters); 15315 this.containerClassName = "polygonAnnotation"; 15316 this.svgElementName = "svg:polygon"; 15317 } 15318} 15319class CaretAnnotationElement extends AnnotationElement { 15320 constructor(parameters) { 15321 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15322 super(parameters, { 15323 isRenderable, 15324 ignoreBorder: true 15325 }); 15326 } 15327 render() { 15328 this.container.classList.add("caretAnnotation"); 15329 if (!this.data.popupRef) { 15330 this._createPopup(); 15331 } 15332 return this.container; 15333 } 15334} 15335class InkAnnotationElement extends AnnotationElement { 15336 #polylines = []; 15337 constructor(parameters) { 15338 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15339 super(parameters, { 15340 isRenderable, 15341 ignoreBorder: true 15342 }); 15343 this.containerClassName = "inkAnnotation"; 15344 this.svgElementName = "svg:polyline"; 15345 this.annotationEditorType = _util.AnnotationEditorType.INK; 15346 } 15347 render() { 15348 this.container.classList.add(this.containerClassName); 15349 const data = this.data; 15350 const { 15351 width, 15352 height 15353 } = getRectDims(data.rect); 15354 const svg = this.svgFactory.create(width, height, true); 15355 for (const inkList of data.inkLists) { 15356 let points = []; 15357 for (const coordinate of inkList) { 15358 const x = coordinate.x - data.rect[0]; 15359 const y = data.rect[3] - coordinate.y; 15360 points.push(`${x},${y}`); 15361 } 15362 points = points.join(" "); 15363 const polyline = this.svgFactory.createElement(this.svgElementName); 15364 this.#polylines.push(polyline); 15365 polyline.setAttribute("points", points); 15366 polyline.setAttribute("stroke-width", data.borderStyle.width || 1); 15367 polyline.setAttribute("stroke", "transparent"); 15368 polyline.setAttribute("fill", "transparent"); 15369 if (!data.popupRef) { 15370 this._createPopup(polyline, data); 15371 } 15372 svg.append(polyline); 15373 } 15374 this.container.append(svg); 15375 return this.container; 15376 } 15377 getElementsToTriggerPopup() { 15378 return this.#polylines; 15379 } 15380 addHighlightArea() { 15381 this.container.classList.add("highlightArea"); 15382 } 15383} 15384exports.InkAnnotationElement = InkAnnotationElement; 15385class HighlightAnnotationElement extends AnnotationElement { 15386 constructor(parameters) { 15387 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15388 super(parameters, { 15389 isRenderable, 15390 ignoreBorder: true, 15391 createQuadrilaterals: true 15392 }); 15393 } 15394 render() { 15395 if (!this.data.popupRef) { 15396 this._createPopup(); 15397 } 15398 this.container.classList.add("highlightAnnotation"); 15399 return this.container; 15400 } 15401} 15402class UnderlineAnnotationElement extends AnnotationElement { 15403 constructor(parameters) { 15404 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15405 super(parameters, { 15406 isRenderable, 15407 ignoreBorder: true, 15408 createQuadrilaterals: true 15409 }); 15410 } 15411 render() { 15412 if (!this.data.popupRef) { 15413 this._createPopup(); 15414 } 15415 this.container.classList.add("underlineAnnotation"); 15416 return this.container; 15417 } 15418} 15419class SquigglyAnnotationElement extends AnnotationElement { 15420 constructor(parameters) { 15421 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15422 super(parameters, { 15423 isRenderable, 15424 ignoreBorder: true, 15425 createQuadrilaterals: true 15426 }); 15427 } 15428 render() { 15429 if (!this.data.popupRef) { 15430 this._createPopup(); 15431 } 15432 this.container.classList.add("squigglyAnnotation"); 15433 return this.container; 15434 } 15435} 15436class StrikeOutAnnotationElement extends AnnotationElement { 15437 constructor(parameters) { 15438 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15439 super(parameters, { 15440 isRenderable, 15441 ignoreBorder: true, 15442 createQuadrilaterals: true 15443 }); 15444 } 15445 render() { 15446 if (!this.data.popupRef) { 15447 this._createPopup(); 15448 }
15449 this.container.classList.add("strikeoutAnnotation"); 15450 return this.container; 15451 } 15452} 15453class StampAnnotationElement extends AnnotationElement { 15454 constructor(parameters) { 15455 const isRenderable = !!(parameters.data.popupRef || parameters.data.titleObj?.str || parameters.data.contentsObj?.str || parameters.data.richText?.str); 15456 super(parameters, { 15457 isRenderable, 15458 ignoreBorder: true 15459 }); 15460 } 15461 render() { 15462 this.container.classList.add("stampAnnotation"); 15463 if (!this.data.popupRef) { 15464 this._createPopup(); 15465 } 15466 return this.container; 15467 } 15468} 15469exports.StampAnnotationElement = StampAnnotationElement; 15470class FileAttachmentAnnotationElement extends AnnotationElement { 15471 #trigger = null; 15472 constructor(parameters) { 15473 super(parameters, { 15474 isRenderable: true 15475 }); 15476 const { 15477 filename, 15478 content 15479 } = this.data.file; 15480 this.filename = (0, _display_utils.getFilenameFromUrl)(filename, true); 15481 this.content = content; 15482 this.linkService.eventBus?.dispatch("fileattachmentannotation", { 15483 source: this, 15484 filename, 15485 content 15486 }); 15487 } 15488 render() { 15489 this.container.classList.add("fileAttachmentAnnotation"); 15490 let trigger; 15491 if (this.data.hasAppearance) { 15492 trigger = document.createElement("div"); 15493 } else { 15494 trigger = document.createElement("img"); 15495 trigger.src = `${this.imageResourcesPath}annotation-${/paperclip/i.test(this.data.name) ? "paperclip" : "pushpin"}.svg`; 15496 } 15497 trigger.classList.add("popupTriggerArea"); 15498 trigger.addEventListener("dblclick", this._download.bind(this)); 15499 this.#trigger = trigger; 15500 if (!this.data.popupRef && (this.data.titleObj?.str || this.data.contentsObj?.str || this.data.richText)) { 15501 this._createPopup(); 15502 } 15503 this.container.append(trigger); 15504 return this.container; 15505 } 15506 getElementsToTriggerPopup() { 15507 return this.#trigger; 15508 } 15509 addHighlightArea() { 15510 this.container.classList.add("highlightArea"); 15511 } 15512 _download() { 15513 this.downloadManager?.openOrDownloadData(this.container, this.content, this.filename); 15514 } 15515} 15516class AnnotationLayer { 15517 #accessibilityManager = null; 15518 #annotationCanvasMap = null; 15519 #editableAnnotations = new Map(); 15520 constructor({ 15521 div, 15522 accessibilityManager, 15523 annotationCanvasMap, 15524 l10n, 15525 page, 15526 viewport 15527 }) { 15528 this.div = div; 15529 this.#accessibilityManager = accessibilityManager; 15530 this.#annotationCanvasMap = annotationCanvasMap; 15531 this.l10n = l10n; 15532 this.page = page; 15533 this.viewport = viewport; 15534 this.zIndex = 0; 15535 this.l10n ||= _displayL10n_utils.NullL10n; 15536 } 15537 #appendElement(element, id) { 15538 const contentElement = element.firstChild || element; 15539 contentElement.id = `${_display_utils.AnnotationPrefix}${id}`; 15540 this.div.append(element); 15541 this.#accessibilityManager?.moveElementInDOM(this.div, element, contentElement, false); 15542 } 15543 async render(params) { 15544 const { 15545 annotations 15546 } = params; 15547 const layer = this.div; 15548 (0, _display_utils.setLayerDimensions)(layer, this.viewport); 15549 const popupToElements = new Map();
15550 const elementParams = { 15551 data: null, 15552 layer, 15553 linkService: params.linkService, 15554 downloadManager: params.downloadManager, 15555 imageResourcesPath: params.imageResourcesPath || "", 15556 renderForms: params.renderForms !== false, 15557 svgFactory: new _display_utils.DOMSVGFactory(), 15558 annotationStorage: params.annotationStorage || new _annotation_storage.AnnotationStorage(), 15559 enableScripting: params.enableScripting === true, 15560 hasJSActions: params.hasJSActions, 15561 fieldObjects: params.fieldObjects, 15562 parent: this, 15563 elements: null 15564 }; 15565 for (const data of annotations) { 15566 if (data.noHTML) { 15567 continue; 15568 } 15569 const isPopupAnnotation = data.annotationType === _util.AnnotationType.POPUP; 15570 if (!isPopupAnnotation) { 15571 const { 15572 width, 15573 height 15574 } = getRectDims(data.rect); 15575 if (width <= 0 || height <= 0) { 15576 continue; 15577 } 15578 } else { 15579 const elements = popupToElements.get(data.id); 15580 if (!elements) { 15581 continue; 15582 }
15583 elementParams.elements = elements; 15584 } 15585 elementParams.data = data; 15586 const element = AnnotationElementFactory.create(elementParams); 15587 if (!element.isRenderable) { 15588 continue; 15589 } 15590 if (!isPopupAnnotation && data.popupRef) { 15591 const elements = popupToElements.get(data.popupRef); 15592 if (!elements) { 15593 popupToElements.set(data.popupRef, [element]); 15594 } else { 15595 elements.push(element); 15596 } 15597 } 15598 if (element.annotationEditorType > 0) { 15599 this.#editableAnnotations.set(element.data.id, element); 15600 } 15601 const rendered = element.render(); 15602 if (data.hidden) { 15603 rendered.style.visibility = "hidden"; 15604 } 15605 this.#appendElement(rendered, data.id); 15606 } 15607 this.#setAnnotationCanvasMap(); 15608 await this.l10n.translate(layer); 15609 } 15610 update({ 15611 viewport 15612 }) { 15613 const layer = this.div; 15614 this.viewport = viewport; 15615 (0, _display_utils.setLayerDimensions)(layer, { 15616 rotation: viewport.rotation 15617 }); 15618 this.#setAnnotationCanvasMap(); 15619 layer.hidden = false; 15620 } 15621 #setAnnotationCanvasMap() { 15622 if (!this.#annotationCanvasMap) { 15623 return; 15624 } 15625 const layer = this.div; 15626 for (const [id, canvas] of this.#annotationCanvasMap) { 15627 const element = layer.querySelector(`[data-annotation-id="${id}"]`); 15628 if (!element) { 15629 continue; 15630 } 15631 const { 15632 firstChild 15633 } = element; 15634 if (!firstChild) { 15635 element.append(canvas); 15636 } else if (firstChild.nodeName === "CANVAS") { 15637 firstChild.replaceWith(canvas); 15638 } else { 15639 firstChild.before(canvas); 15640 } 15641 } 15642 this.#annotationCanvasMap.clear(); 15643 } 15644 getEditableAnnotations() { 15645 return Array.from(this.#editableAnnotations.values()); 15646 } 15647 getEditableAnnotation(id) { 15648 return this.#editableAnnotations.get(id); 15649 } 15650} 15651exports.AnnotationLayer = AnnotationLayer; 15652 15653/***/ }), 15654/* 30 */ 15655/***/ ((__unused_webpack_module, exports) => { 15656 15657 15658 15659Object.defineProperty(exports, "__esModule", ({ 15660 value: true 15661})); 15662exports.ColorConverters = void 0; 15663function makeColorComp(n) { 15664 return Math.floor(Math.max(0, Math.min(1, n)) * 255).toString(16).padStart(2, "0"); 15665} 15666class ColorConverters { 15667 static CMYK_G([c, y, m, k]) { 15668 return ["G", 1 - Math.min(1, 0.3 * c + 0.59 * m + 0.11 * y + k)]; 15669 } 15670 static G_CMYK([g]) { 15671 return ["CMYK", 0, 0, 0, 1 - g]; 15672 } 15673 static G_RGB([g]) { 15674 return ["RGB", g, g, g]; 15675 } 15676 static G_HTML([g]) { 15677 const G = makeColorComp(g); 15678 return `#${G}${G}${G}`; 15679 } 15680 static RGB_G([r, g, b]) { 15681 return ["G", 0.3 * r + 0.59 * g + 0.11 * b]; 15682 } 15683 static RGB_HTML([r, g, b]) { 15684 const R = makeColorComp(r); 15685 const G = makeColorComp(g); 15686 const B = makeColorComp(b); 15687 return `#${R}${G}${B}`; 15688 } 15689 static T_HTML() { 15690 return "#00000000"; 15691 } 15692 static CMYK_RGB([c, y, m, k]) { 15693 return ["RGB", 1 - Math.min(1, c + k), 1 - Math.min(1, m + k), 1 - Math.min(1, y + k)]; 15694 } 15695 static CMYK_HTML(components) { 15696 const rgb = this.CMYK_RGB(components).slice(1); 15697 return this.RGB_HTML(rgb); 15698 } 15699 static RGB_CMYK([r, g, b]) { 15700 const c = 1 - r; 15701 const m = 1 - g; 15702 const y = 1 - b; 15703 const k = Math.min(c, m, y); 15704 return ["CMYK", c, m, y, k]; 15705 } 15706} 15707exports.ColorConverters = ColorConverters; 15708 15709/***/ }), 15710/* 31 */ 15711/***/ ((__unused_webpack_module, exports) => { 15712 15713 15714 15715Object.defineProperty(exports, "__esModule", ({ 15716 value: true 15717})); 15718exports.NullL10n = void 0; 15719exports.getL10nFallback = getL10nFallback; 15720const DEFAULT_L10N_STRINGS = { 15721 of_pages: "of {{pagesCount}}", 15722 page_of_pages: "({{pageNumber}} of {{pagesCount}})", 15723 document_properties_kb: "{{size_kb}} KB ({{size_b}} bytes)", 15724 document_properties_mb: "{{size_mb}} MB ({{size_b}} bytes)", 15725 document_properties_date_string: "{{date}}, {{time}}", 15726 document_properties_page_size_unit_inches: "in", 15727 document_properties_page_size_unit_millimeters: "mm", 15728 document_properties_page_size_orientation_portrait: "portrait", 15729 document_properties_page_size_orientation_landscape: "landscape", 15730 document_properties_page_size_name_a3: "A3", 15731 document_properties_page_size_name_a4: "A4", 15732 document_properties_page_size_name_letter: "Letter", 15733 document_properties_page_size_name_legal: "Legal", 15734 document_properties_page_size_dimension_string: "{{width}} × {{height}} {{unit}} ({{orientation}})", 15735 document_properties_page_size_dimension_name_string: "{{width}} × {{height}} {{unit}} ({{name}}, {{orientation}})", 15736 document_properties_linearized_yes: "Yes", 15737 document_properties_linearized_no: "No", 15738 additional_layers: "Additional Layers", 15739 page_landmark: "Page {{page}}", 15740 thumb_page_title: "Page {{page}}", 15741 thumb_page_canvas: "Thumbnail of Page {{page}}", 15742 find_reached_top: "Reached top of document, continued from bottom", 15743 find_reached_bottom: "Reached end of document, continued from top", 15744 "find_match_count[one]": "{{current}} of {{total}} match", 15745 "find_match_count[other]": "{{current}} of {{total}} matches", 15746 "find_match_count_limit[one]": "More than {{limit}} match", 15747 "find_match_count_limit[other]": "More than {{limit}} matches", 15748 find_not_found: "Phrase not found", 15749 page_scale_width: "Page Width", 15750 page_scale_fit: "Page Fit", 15751 page_scale_auto: "Automatic Zoom", 15752 page_scale_actual: "Actual Size", 15753 page_scale_percent: "{{scale}}%", 15754 loading_error: "An error occurred while loading the PDF.", 15755 invalid_file_error: "Invalid or corrupted PDF file.", 15756 missing_file_error: "Missing PDF file.", 15757 unexpected_response_error: "Unexpected server response.", 15758 rendering_error: "An error occurred while rendering the page.", 15759 annotation_date_string: "{{date}}, {{time}}", 15760 printing_not_supported: "Warning: Printing is not fully supported by this browser.", 15761 printing_not_ready: "Warning: The PDF is not fully loaded for printing.", 15762 web_fonts_disabled: "Web fonts are disabled: unable to use embedded PDF fonts.",
15763 free_text2_default_content: "Start typing…", 15764 editor_free_text2_aria_label: "Text Editor", 15765 editor_ink2_aria_label: "Draw Editor", 15766 editor_ink_canvas_aria_label: "User-created image" 15767}; 15768{ 15769 DEFAULT_L10N_STRINGS.print_progress_percent = "{{progress}}%"; 15770} 15771function getL10nFallback(key, args) { 15772 switch (key) { 15773 case "find_match_count": 15774 key = `find_match_count[${args.total === 1 ? "one" : "other"}]`; 15775 break; 15776 case "find_match_count_limit": 15777 key = `find_match_count_limit[${args.limit === 1 ? "one" : "other"}]`; 15778 break; 15779 } 15780 return DEFAULT_L10N_STRINGS[key] || ""; 15781} 15782function formatL10nValue(text, args) { 15783 if (!args) { 15784 return text; 15785 } 15786 return text.replaceAll(/\{\{\s*(\w+)\s*\}\}/g, (all, name) => { 15787 return name in args ? args[name] : "{{" + name + "}}"; 15788 }); 15789} 15790const NullL10n = { 15791 async getLanguage() { 15792 return "en-us"; 15793 }, 15794 async getDirection() { 15795 return "ltr"; 15796 }, 15797 async get(key, args = null, fallback = getL10nFallback(key, args)) { 15798 return formatL10nValue(fallback, args); 15799 }, 15800 async translate(element) {} 15801}; 15802exports.NullL10n = NullL10n; 15803 15804/***/ }), 15805/* 32 */ 15806/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 15807 15808 15809 15810Object.defineProperty(exports, "__esModule", ({ 15811 value: true 15812})); 15813exports.XfaLayer = void 0; 15814var _xfa_text = __w_pdfjs_require__(25); 15815class XfaLayer { 15816 static setupStorage(html, id, element, storage, intent) { 15817 const storedData = storage.getValue(id, { 15818 value: null 15819 }); 15820 switch (element.name) { 15821 case "textarea": 15822 if (storedData.value !== null) { 15823 html.textContent = storedData.value; 15824 } 15825 if (intent === "print") { 15826 break; 15827 } 15828 html.addEventListener("input", event => { 15829 storage.setValue(id, { 15830 value: event.target.value 15831 }); 15832 }); 15833 break; 15834 case "input": 15835 if (element.attributes.type === "radio" || element.attributes.type === "checkbox") { 15836 if (storedData.value === element.attributes.xfaOn) { 15837 html.setAttribute("checked", true); 15838 } else if (storedData.value === element.attributes.xfaOff) { 15839 html.removeAttribute("checked"); 15840 } 15841 if (intent === "print") { 15842 break; 15843 } 15844 html.addEventListener("change", event => { 15845 storage.setValue(id, { 15846 value: event.target.checked ? event.target.getAttribute("xfaOn") : event.target.getAttribute("xfaOff") 15847 }); 15848 }); 15849 } else { 15850 if (storedData.value !== null) { 15851 html.setAttribute("value", storedData.value); 15852 } 15853 if (intent === "print") { 15854 break; 15855 } 15856 html.addEventListener("input", event => { 15857 storage.setValue(id, { 15858 value: event.target.value 15859 }); 15860 }); 15861 } 15862 break; 15863 case "select": 15864 if (storedData.value !== null) { 15865 html.setAttribute("value", storedData.value); 15866 for (const option of element.children) { 15867 if (option.attributes.value === storedData.value) { 15868 option.attributes.selected = true; 15869 } else if (option.attributes.hasOwnProperty("selected")) { 15870 delete option.attributes.selected; 15871 } 15872 } 15873 } 15874 html.addEventListener("input", event => { 15875 const options = event.target.options; 15876 const value = options.selectedIndex === -1 ? "" : options[options.selectedIndex].value; 15877 storage.setValue(id, { 15878 value 15879 }); 15880 }); 15881 break; 15882 } 15883 } 15884 static setAttributes({ 15885 html, 15886 element, 15887 storage = null, 15888 intent, 15889 linkService 15890 }) { 15891 const { 15892 attributes 15893 } = element; 15894 const isHTMLAnchorElement = html instanceof HTMLAnchorElement; 15895 if (attributes.type === "radio") { 15896 attributes.name = `${attributes.name}-${intent}`; 15897 } 15898 for (const [key, value] of Object.entries(attributes)) { 15899 if (value === null || value === undefined) { 15900 continue; 15901 } 15902 switch (key) { 15903 case "class": 15904 if (value.length) { 15905 html.setAttribute(key, value.join(" ")); 15906 } 15907 break; 15908 case "dataId": 15909 break; 15910 case "id": 15911 html.setAttribute("data-element-id", value); 15912 break; 15913 case "style": 15914 Object.assign(html.style, value); 15915 break; 15916 case "textContent": 15917 html.textContent = value; 15918 break; 15919 default: 15920 if (!isHTMLAnchorElement || key !== "href" && key !== "newWindow") { 15921 html.setAttribute(key, value); 15922 } 15923 } 15924 } 15925 if (isHTMLAnchorElement) { 15926 linkService.addLinkAttributes(html, attributes.href, attributes.newWindow); 15927 } 15928 if (storage && attributes.dataId) { 15929 this.setupStorage(html, attributes.dataId, element, storage); 15930 } 15931 } 15932 static render(parameters) { 15933 const storage = parameters.annotationStorage; 15934 const linkService = parameters.linkService; 15935 const root = parameters.xfaHtml; 15936 const intent = parameters.intent || "display"; 15937 const rootHtml = document.createElement(root.name); 15938 if (root.attributes) { 15939 this.setAttributes({ 15940 html: rootHtml, 15941 element: root, 15942 intent, 15943 linkService 15944 }); 15945 } 15946 const stack = [[root, -1, rootHtml]]; 15947 const rootDiv = parameters.div; 15948 rootDiv.append(rootHtml); 15949 if (parameters.viewport) { 15950 const transform = `matrix(${parameters.viewport.transform.join(",")})`; 15951 rootDiv.style.transform = transform; 15952 } 15953 if (intent !== "richText") { 15954 rootDiv.setAttribute("class", "xfaLayer xfaFont"); 15955 } 15956 const textDivs = []; 15957 while (stack.length > 0) { 15958 const [parent, i, html] = stack.at(-1); 15959 if (i + 1 === parent.children.length) { 15960 stack.pop(); 15961 continue; 15962 } 15963 const child = parent.children[++stack.at(-1)[1]]; 15964 if (child === null) { 15965 continue; 15966 } 15967 const { 15968 name 15969 } = child; 15970 if (name === "#text") { 15971 const node = document.createTextNode(child.value); 15972 textDivs.push(node); 15973 html.append(node); 15974 continue; 15975 } 15976 const childHtml = child?.attributes?.xmlns ? document.createElementNS(child.attributes.xmlns, name) : document.createElement(name); 15977 html.append(childHtml); 15978 if (child.attributes) { 15979 this.setAttributes({ 15980 html: childHtml, 15981 element: child, 15982 storage, 15983 intent, 15984 linkService 15985 }); 15986 } 15987 if (child.children && child.children.length > 0) { 15988 stack.push([child, -1, childHtml]); 15989 } else if (child.value) { 15990 const node = document.createTextNode(child.value); 15991 if (_xfa_text.XfaText.shouldBuildText(name)) { 15992 textDivs.push(node); 15993 } 15994 childHtml.append(node); 15995 } 15996 } 15997 for (const el of rootDiv.querySelectorAll(".xfaNonInteractive input, .xfaNonInteractive textarea")) { 15998 el.setAttribute("readOnly", true); 15999 } 16000 return { 16001 textDivs 16002 }; 16003 } 16004 static update(parameters) { 16005 const transform = `matrix(${parameters.viewport.transform.join(",")})`; 16006 parameters.div.style.transform = transform; 16007 parameters.div.hidden = false;
16008 } 16009} 16010exports.XfaLayer = XfaLayer; 16011 16012/***/ }), 16013/* 33 */ 16014/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 16015 16016 16017 16018Object.defineProperty(exports, "__esModule", ({ 16019 value: true 16020})); 16021exports.InkEditor = void 0; 16022var _util = __w_pdfjs_require__(1); 16023var _editor = __w_pdfjs_require__(4); 16024var _annotation_layer = __w_pdfjs_require__(29); 16025var _tools = __w_pdfjs_require__(5); 16026class InkEditor extends _editor.AnnotationEditor { 16027 #baseHeight = 0; 16028 #baseWidth = 0; 16029 #boundCanvasContextMenu = this.canvasContextMenu.bind(this); 16030 #boundCanvasPointermove = this.canvasPointermove.bind(this); 16031 #boundCanvasPointerleave = this.canvasPointerleave.bind(this); 16032 #boundCanvasPointerup = this.canvasPointerup.bind(this); 16033 #boundCanvasPointerdown = this.canvasPointerdown.bind(this); 16034 #currentPath2D = new Path2D(); 16035 #disableEditing = false; 16036 #hasSomethingToDraw = false; 16037 #isCanvasInitialized = false; 16038 #observer = null; 16039 #realWidth = 0; 16040 #realHeight = 0; 16041 #requestFrameCallback = null; 16042 static _defaultColor = null; 16043 static _defaultOpacity = 1; 16044 static _defaultThickness = 1; 16045 static _l10nPromise; 16046 static _type = "ink"; 16047 constructor(params) { 16048 super({ 16049 ...params, 16050 name: "inkEditor" 16051 }); 16052 this.color = params.color || null; 16053 this.thickness = params.thickness || null; 16054 this.opacity = params.opacity || null; 16055 this.paths = []; 16056 this.bezierPath2D = []; 16057 this.allRawPaths = []; 16058 this.currentPath = []; 16059 this.scaleFactor = 1; 16060 this.translationX = this.translationY = 0; 16061 this.x = 0; 16062 this.y = 0; 16063 this._willKeepAspectRatio = true; 16064 } 16065 static initialize(l10n) { 16066 this._l10nPromise = new Map(["editor_ink_canvas_aria_label", "editor_ink2_aria_label"].map(str => [str, l10n.get(str)])); 16067 } 16068 static updateDefaultParams(type, value) { 16069 switch (type) { 16070 case _util.AnnotationEditorParamsType.INK_THICKNESS: 16071 InkEditor._defaultThickness = value; 16072 break; 16073 case _util.AnnotationEditorParamsType.INK_COLOR: 16074 InkEditor._defaultColor = value; 16075 break; 16076 case _util.AnnotationEditorParamsType.INK_OPACITY: 16077 InkEditor._defaultOpacity = value / 100; 16078 break; 16079 } 16080 } 16081 updateParams(type, value) { 16082 switch (type) { 16083 case _util.AnnotationEditorParamsType.INK_THICKNESS: 16084 this.#updateThickness(value); 16085 break; 16086 case _util.AnnotationEditorParamsType.INK_COLOR: 16087 this.#updateColor(value); 16088 break; 16089 case _util.AnnotationEditorParamsType.INK_OPACITY: 16090 this.#updateOpacity(value); 16091 break; 16092 } 16093 } 16094 static get defaultPropertiesToUpdate() { 16095 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)]]; 16096 } 16097 get propertiesToUpdate() { 16098 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))]]; 16099 } 16100 #updateThickness(thickness) { 16101 const savedThickness = this.thickness; 16102 this.addCommands({ 16103 cmd: () => { 16104 this.thickness = thickness; 16105 this.#fitToContent(); 16106 }, 16107 undo: () => { 16108 this.thickness = savedThickness; 16109 this.#fitToContent(); 16110 }, 16111 mustExec: true, 16112 type: _util.AnnotationEditorParamsType.INK_THICKNESS, 16113 overwriteIfSameType: true, 16114 keepUndo: true 16115 }); 16116 } 16117 #updateColor(color) { 16118 const savedColor = this.color; 16119 this.addCommands({ 16120 cmd: () => { 16121 this.color = color; 16122 this.#redraw(); 16123 }, 16124 undo: () => { 16125 this.color = savedColor; 16126 this.#redraw(); 16127 }, 16128 mustExec: true, 16129 type: _util.AnnotationEditorParamsType.INK_COLOR,
16130 overwriteIfSameType: true, 16131 keepUndo: true 16132 }); 16133 } 16134 #updateOpacity(opacity) { 16135 opacity /= 100; 16136 const savedOpacity = this.opacity; 16137 this.addCommands({ 16138 cmd: () => { 16139 this.opacity = opacity; 16140 this.#redraw(); 16141 }, 16142 undo: () => { 16143 this.opacity = savedOpacity; 16144 this.#redraw(); 16145 }, 16146 mustExec: true, 16147 type: _util.AnnotationEditorParamsType.INK_OPACITY, 16148 overwriteIfSameType: true, 16149 keepUndo: true 16150 }); 16151 } 16152 rebuild() { 16153 super.rebuild(); 16154 if (this.div === null) { 16155 return; 16156 } 16157 if (!this.canvas) { 16158 this.#createCanvas(); 16159 this.#createObserver(); 16160 } 16161 if (!this.isAttachedToDOM) { 16162 this.parent.add(this); 16163 this.#setCanvasDims(); 16164 } 16165 this.#fitToContent(); 16166 } 16167 remove() { 16168 if (this.canvas === null) { 16169 return; 16170 } 16171 if (!this.isEmpty()) { 16172 this.commit(); 16173 } 16174 this.canvas.width = this.canvas.height = 0; 16175 this.canvas.remove(); 16176 this.canvas = null; 16177 this.#observer.disconnect(); 16178 this.#observer = null; 16179 super.remove(); 16180 } 16181 setParent(parent) { 16182 if (!this.parent && parent) { 16183 this._uiManager.removeShouldRescale(this); 16184 } else if (this.parent && parent === null) { 16185 this._uiManager.addShouldRescale(this); 16186 } 16187 super.setParent(parent); 16188 } 16189 onScaleChanging() { 16190 const [parentWidth, parentHeight] = this.parentDimensions; 16191 const width = this.width * parentWidth; 16192 const height = this.height * parentHeight; 16193 this.setDimensions(width, height); 16194 } 16195 enableEditMode() { 16196 if (this.#disableEditing || this.canvas === null) { 16197 return; 16198 } 16199 super.enableEditMode(); 16200 this.div.draggable = false; 16201 this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown); 16202 } 16203 disableEditMode() { 16204 if (!this.isInEditMode() || this.canvas === null) { 16205 return; 16206 } 16207 super.disableEditMode(); 16208 this.div.draggable = !this.isEmpty(); 16209 this.div.classList.remove("editing"); 16210 this.canvas.removeEventListener("pointerdown", this.#boundCanvasPointerdown); 16211 } 16212 onceAdded() { 16213 this.div.draggable = !this.isEmpty(); 16214 } 16215 isEmpty() { 16216 return this.paths.length === 0 || this.paths.length === 1 && this.paths[0].length === 0; 16217 } 16218 #getInitialBBox() { 16219 const { 16220 parentRotation, 16221 parentDimensions: [width, height] 16222 } = this; 16223 switch (parentRotation) { 16224 case 90: 16225 return [0, height, height, width]; 16226 case 180: 16227 return [width, height, width, height]; 16228 case 270: 16229 return [width, 0, height, width]; 16230 default: 16231 return [0, 0, width, height]; 16232 } 16233 } 16234 #setStroke() { 16235 const { 16236 ctx, 16237 color, 16238 opacity, 16239 thickness, 16240 parentScale, 16241 scaleFactor 16242 } = this; 16243 ctx.lineWidth = thickness * parentScale / scaleFactor; 16244 ctx.lineCap = "round"; 16245 ctx.lineJoin = "round"; 16246 ctx.miterLimit = 10; 16247 ctx.strokeStyle = `${color}${(0, _tools.opacityToHex)(opacity)}`; 16248 } 16249 #startDrawing(x, y) { 16250 this.canvas.addEventListener("contextmenu", this.#boundCanvasContextMenu); 16251 this.canvas.addEventListener("pointerleave", this.#boundCanvasPointerleave); 16252 this.canvas.addEventListener("pointermove", this.#boundCanvasPointermove); 16253 this.canvas.addEventListener("pointerup", this.#boundCanvasPointerup); 16254 this.canvas.removeEventListener("pointerdown", this.#boundCanvasPointerdown); 16255 this.isEditing = true; 16256 if (!this.#isCanvasInitialized) { 16257 this.#isCanvasInitialized = true; 16258 this.#setCanvasDims(); 16259 this.thickness ||= InkEditor._defaultThickness; 16260 this.color ||= InkEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor; 16261 this.opacity ??= InkEditor._defaultOpacity; 16262 } 16263 this.currentPath.push([x, y]); 16264 this.#hasSomethingToDraw = false; 16265 this.#setStroke(); 16266 this.#requestFrameCallback = () => { 16267 this.#drawPoints(); 16268 if (this.#requestFrameCallback) { 16269 window.requestAnimationFrame(this.#requestFrameCallback); 16270 } 16271 }; 16272 window.requestAnimationFrame(this.#requestFrameCallback); 16273 } 16274 #draw(x, y) { 16275 const [lastX, lastY] = this.currentPath.at(-1); 16276 if (this.currentPath.length > 1 && x === lastX && y === lastY) { 16277 return; 16278 } 16279 const currentPath = this.currentPath; 16280 let path2D = this.#currentPath2D; 16281 currentPath.push([x, y]); 16282 this.#hasSomethingToDraw = true; 16283 if (currentPath.length <= 2) { 16284 path2D.moveTo(...currentPath[0]); 16285 path2D.lineTo(x, y); 16286 return; 16287 } 16288 if (currentPath.length === 3) { 16289 this.#currentPath2D = path2D = new Path2D(); 16290 path2D.moveTo(...currentPath[0]); 16291 } 16292 this.#makeBezierCurve(path2D, ...currentPath.at(-3), ...currentPath.at(-2), x, y); 16293 } 16294 #endPath() { 16295 if (this.currentPath.length === 0) { 16296 return; 16297 } 16298 const lastPoint = this.currentPath.at(-1); 16299 this.#currentPath2D.lineTo(...lastPoint); 16300 } 16301 #stopDrawing(x, y) { 16302 this.#requestFrameCallback = null; 16303 x = Math.min(Math.max(x, 0), this.canvas.width); 16304 y = Math.min(Math.max(y, 0), this.canvas.height); 16305 this.#draw(x, y); 16306 this.#endPath(); 16307 let bezier; 16308 if (this.currentPath.length !== 1) { 16309 bezier = this.#generateBezierPoints(); 16310 } else { 16311 const xy = [x, y]; 16312 bezier = [[xy, xy.slice(), xy.slice(), xy]]; 16313 } 16314 const path2D = this.#currentPath2D; 16315 const currentPath = this.currentPath; 16316 this.currentPath = []; 16317 this.#currentPath2D = new Path2D(); 16318 const cmd = () => { 16319 this.allRawPaths.push(currentPath); 16320 this.paths.push(bezier); 16321 this.bezierPath2D.push(path2D); 16322 this.rebuild(); 16323 }; 16324 const undo = () => { 16325 this.allRawPaths.pop(); 16326 this.paths.pop(); 16327 this.bezierPath2D.pop(); 16328 if (this.paths.length === 0) { 16329 this.remove(); 16330 } else { 16331 if (!this.canvas) { 16332 this.#createCanvas(); 16333 this.#createObserver(); 16334 } 16335 this.#fitToContent(); 16336 } 16337 }; 16338 this.addCommands({ 16339 cmd, 16340 undo, 16341 mustExec: true 16342 }); 16343 } 16344 #drawPoints() { 16345 if (!this.#hasSomethingToDraw) { 16346 return; 16347 } 16348 this.#hasSomethingToDraw = false;
16349 const thickness = Math.ceil(this.thickness * this.parentScale); 16350 const lastPoints = this.currentPath.slice(-3); 16351 const x = lastPoints.map(xy => xy[0]); 16352 const y = lastPoints.map(xy => xy[1]); 16353 const xMin = Math.min(...x) - thickness; 16354 const xMax = Math.max(...x) + thickness; 16355 const yMin = Math.min(...y) - thickness; 16356 const yMax = Math.max(...y) + thickness; 16357 const { 16358 ctx 16359 } = this; 16360 ctx.save(); 16361 ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 16362 for (const path of this.bezierPath2D) { 16363 ctx.stroke(path); 16364 } 16365 ctx.stroke(this.#currentPath2D); 16366 ctx.restore(); 16367 } 16368 #makeBezierCurve(path2D, x0, y0, x1, y1, x2, y2) { 16369 const prevX = (x0 + x1) / 2; 16370 const prevY = (y0 + y1) / 2; 16371 const x3 = (x1 + x2) / 2; 16372 const y3 = (y1 + y2) / 2; 16373 path2D.bezierCurveTo(prevX + 2 * (x1 - prevX) / 3, prevY + 2 * (y1 - prevY) / 3, x3 + 2 * (x1 - x3) / 3, y3 + 2 * (y1 - y3) / 3, x3, y3); 16374 } 16375 #generateBezierPoints() { 16376 const path = this.currentPath; 16377 if (path.length <= 2) { 16378 return [[path[0], path[0], path.at(-1), path.at(-1)]]; 16379 } 16380 const bezierPoints = []; 16381 let i; 16382 let [x0, y0] = path[0]; 16383 for (i = 1; i < path.length - 2; i++) { 16384 const [x1, y1] = path[i]; 16385 const [x2, y2] = path[i + 1]; 16386 const x3 = (x1 + x2) / 2; 16387 const y3 = (y1 + y2) / 2; 16388 const control1 = [x0 + 2 * (x1 - x0) / 3, y0 + 2 * (y1 - y0) / 3]; 16389 const control2 = [x3 + 2 * (x1 - x3) / 3, y3 + 2 * (y1 - y3) / 3]; 16390 bezierPoints.push([[x0, y0], control1, control2, [x3, y3]]); 16391 [x0, y0] = [x3, y3]; 16392 } 16393 const [x1, y1] = path[i]; 16394 const [x2, y2] = path[i + 1]; 16395 const control1 = [x0 + 2 * (x1 - x0) / 3, y0 + 2 * (y1 - y0) / 3]; 16396 const control2 = [x2 + 2 * (x1 - x2) / 3, y2 + 2 * (y1 - y2) / 3]; 16397 bezierPoints.push([[x0, y0], control1, control2, [x2, y2]]); 16398 return bezierPoints; 16399 } 16400 #redraw() { 16401 if (this.isEmpty()) { 16402 this.#updateTransform(); 16403 return; 16404 } 16405 this.#setStroke(); 16406 const { 16407 canvas, 16408 ctx 16409 } = this; 16410 ctx.setTransform(1, 0, 0, 1, 0, 0); 16411 ctx.clearRect(0, 0, canvas.width, canvas.height); 16412 this.#updateTransform(); 16413 for (const path of this.bezierPath2D) { 16414 ctx.stroke(path); 16415 } 16416 } 16417 commit() { 16418 if (this.#disableEditing) { 16419 return; 16420 } 16421 super.commit(); 16422 this.isEditing = false; 16423 this.disableEditMode(); 16424 this.setInForeground(); 16425 this.#disableEditing = true; 16426 this.div.classList.add("disabled"); 16427 this.#fitToContent(true); 16428 this.makeResizable(); 16429 this.parent.addInkEditorIfNeeded(true); 16430 this.parent.moveEditorInDOM(this); 16431 this.div.focus({ 16432 preventScroll: true 16433 }); 16434 } 16435 focusin(event) { 16436 super.focusin(event); 16437 this.enableEditMode(); 16438 } 16439 canvasPointerdown(event) { 16440 if (event.button !== 0 || !this.isInEditMode() || this.#disableEditing) { 16441 return; 16442 } 16443 this.setInForeground(); 16444 event.preventDefault(); 16445 if (event.type !== "mouse") { 16446 this.div.focus(); 16447 } 16448 this.#startDrawing(event.offsetX, event.offsetY); 16449 } 16450 canvasContextMenu(event) { 16451 event.preventDefault(); 16452 } 16453 canvasPointermove(event) { 16454 event.preventDefault(); 16455 this.#draw(event.offsetX, event.offsetY); 16456 } 16457 canvasPointerup(event) { 16458 event.preventDefault(); 16459 this.#endDrawing(event); 16460 } 16461 canvasPointerleave(event) { 16462 this.#endDrawing(event); 16463 } 16464 #endDrawing(event) { 16465 this.canvas.removeEventListener("pointerleave", this.#boundCanvasPointerleave); 16466 this.canvas.removeEventListener("pointermove", this.#boundCanvasPointermove); 16467 this.canvas.removeEventListener("pointerup", this.#boundCanvasPointerup); 16468 this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown); 16469 setTimeout(() => { 16470 this.canvas.removeEventListener("contextmenu", this.#boundCanvasContextMenu); 16471 }, 10); 16472 this.#stopDrawing(event.offsetX, event.offsetY); 16473 this.addToAnnotationStorage(); 16474 this.setInBackground(); 16475 } 16476 #createCanvas() { 16477 this.canvas = document.createElement("canvas"); 16478 this.canvas.width = this.canvas.height = 0; 16479 this.canvas.className = "inkEditorCanvas"; 16480 InkEditor._l10nPromise.get("editor_ink_canvas_aria_label").then(msg => this.canvas?.setAttribute("aria-label", msg)); 16481 this.div.append(this.canvas); 16482 this.ctx = this.canvas.getContext("2d"); 16483 } 16484 #createObserver() { 16485 this.#observer = new ResizeObserver(entries => {
16486 const rect = entries[0].contentRect; 16487 if (rect.width && rect.height) { 16488 this.setDimensions(rect.width, rect.height); 16489 } 16490 }); 16491 this.#observer.observe(this.div); 16492 } 16493 get isResizable() { 16494 return !this.isEmpty() && this.#disableEditing; 16495 } 16496 render() { 16497 if (this.div) { 16498 return this.div; 16499 } 16500 let baseX, baseY; 16501 if (this.width) { 16502 baseX = this.x; 16503 baseY = this.y; 16504 } 16505 super.render(); 16506 InkEditor._l10nPromise.get("editor_ink2_aria_label").then(msg => this.div?.setAttribute("aria-label", msg)); 16507 const [x, y, w, h] = this.#getInitialBBox(); 16508 this.setAt(x, y, 0, 0); 16509 this.setDims(w, h); 16510 this.#createCanvas(); 16511 if (this.width) { 16512 const [parentWidth, parentHeight] = this.parentDimensions; 16513 this.setAspectRatio(this.width * parentWidth, this.height * parentHeight); 16514 this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); 16515 this.#isCanvasInitialized = true; 16516 this.#setCanvasDims(); 16517 this.setDims(this.width * parentWidth, this.height * parentHeight); 16518 this.#redraw(); 16519 this.div.classList.add("disabled"); 16520 } else { 16521 this.div.classList.add("editing"); 16522 this.enableEditMode(); 16523 } 16524 this.#createObserver(); 16525 return this.div; 16526 } 16527 #setCanvasDims() { 16528 if (!this.#isCanvasInitialized) { 16529 return; 16530 } 16531 const [parentWidth, parentHeight] = this.parentDimensions; 16532 this.canvas.width = Math.ceil(this.width * parentWidth); 16533 this.canvas.height = Math.ceil(this.height * parentHeight); 16534 this.#updateTransform(); 16535 } 16536 setDimensions(width, height) { 16537 const roundedWidth = Math.round(width); 16538 const roundedHeight = Math.round(height); 16539 if (this.#realWidth === roundedWidth && this.#realHeight === roundedHeight) { 16540 return; 16541 } 16542 this.#realWidth = roundedWidth; 16543 this.#realHeight = roundedHeight; 16544 this.canvas.style.visibility = "hidden"; 16545 const [parentWidth, parentHeight] = this.parentDimensions; 16546 this.width = width / parentWidth; 16547 this.height = height / parentHeight; 16548 this.fixAndSetPosition(); 16549 if (this.#disableEditing) { 16550 this.#setScaleFactor(width, height); 16551 } 16552 this.#setCanvasDims(); 16553 this.#redraw(); 16554 this.canvas.style.visibility = "visible"; 16555 this.fixDims(); 16556 } 16557 #setScaleFactor(width, height) { 16558 const padding = this.#getPadding(); 16559 const scaleFactorW = (width - padding) / this.#baseWidth; 16560 const scaleFactorH = (height - padding) / this.#baseHeight; 16561 this.scaleFactor = Math.min(scaleFactorW, scaleFactorH); 16562 } 16563 #updateTransform() { 16564 const padding = this.#getPadding() / 2; 16565 this.ctx.setTransform(this.scaleFactor, 0, 0, this.scaleFactor, this.translationX * this.scaleFactor + padding, this.translationY * this.scaleFactor + padding); 16566 } 16567 static #buildPath2D(bezier) { 16568 const path2D = new Path2D(); 16569 for (let i = 0, ii = bezier.length; i < ii; i++) { 16570 const [first, control1, control2, second] = bezier[i]; 16571 if (i === 0) { 16572 path2D.moveTo(...first); 16573 } 16574 path2D.bezierCurveTo(control1[0], control1[1], control2[0], control2[1], second[0], second[1]); 16575 } 16576 return path2D; 16577 } 16578 static #toPDFCoordinates(points, rect, rotation) { 16579 const [blX, blY, trX, trY] = rect; 16580 switch (rotation) { 16581 case 0: 16582 for (let i = 0, ii = points.length; i < ii; i += 2) { 16583 points[i] += blX; 16584 points[i + 1] = trY - points[i + 1]; 16585 } 16586 break; 16587 case 90: 16588 for (let i = 0, ii = points.length; i < ii; i += 2) { 16589 const x = points[i]; 16590 points[i] = points[i + 1] + blX; 16591 points[i + 1] = x + blY; 16592 } 16593 break; 16594 case 180: 16595 for (let i = 0, ii = points.length; i < ii; i += 2) { 16596 points[i] = trX - points[i]; 16597 points[i + 1] += blY; 16598 } 16599 break; 16600 case 270: 16601 for (let i = 0, ii = points.length; i < ii; i += 2) { 16602 const x = points[i]; 16603 points[i] = trX - points[i + 1]; 16604 points[i + 1] = trY - x; 16605 } 16606 break; 16607 default: 16608 throw new Error("Invalid rotation"); 16609 } 16610 return points; 16611 } 16612 static #fromPDFCoordinates(points, rect, rotation) { 16613 const [blX, blY, trX, trY] = rect; 16614 switch (rotation) { 16615 case 0: 16616 for (let i = 0, ii = points.length; i < ii; i += 2) { 16617 points[i] -= blX; 16618 points[i + 1] = trY - points[i + 1]; 16619 } 16620 break; 16621 case 90: 16622 for (let i = 0, ii = points.length; i < ii; i += 2) { 16623 const x = points[i]; 16624 points[i] = points[i + 1] - blY; 16625 points[i + 1] = x - blX; 16626 } 16627 break; 16628 case 180: 16629 for (let i = 0, ii = points.length; i < ii; i += 2) { 16630 points[i] = trX - points[i]; 16631 points[i + 1] -= blY; 16632 } 16633 break; 16634 case 270: 16635 for (let i = 0, ii = points.length; i < ii; i += 2) { 16636 const x = points[i]; 16637 points[i] = trY - points[i + 1]; 16638 points[i + 1] = trX - x; 16639 } 16640 break; 16641 default: 16642 throw new Error("Invalid rotation"); 16643 } 16644 return points; 16645 } 16646 #serializePaths(s, tx, ty, rect) { 16647 const paths = []; 16648 const padding = this.thickness / 2; 16649 const shiftX = s * tx + padding; 16650 const shiftY = s * ty + padding; 16651 for (const bezier of this.paths) { 16652 const buffer = []; 16653 const points = []; 16654 for (let j = 0, jj = bezier.length; j < jj; j++) { 16655 const [first, control1, control2, second] = bezier[j]; 16656 const p10 = s * first[0] + shiftX; 16657 const p11 = s * first[1] + shiftY; 16658 const p20 = s * control1[0] + shiftX; 16659 const p21 = s * control1[1] + shiftY; 16660 const p30 = s * control2[0] + shiftX; 16661 const p31 = s * control2[1] + shiftY; 16662 const p40 = s * second[0] + shiftX; 16663 const p41 = s * second[1] + shiftY; 16664 if (j === 0) { 16665 buffer.push(p10, p11); 16666 points.push(p10, p11); 16667 } 16668 buffer.push(p20, p21, p30, p31, p40, p41); 16669 points.push(p20, p21); 16670 if (j === jj - 1) { 16671 points.push(p40, p41); 16672 } 16673 } 16674 paths.push({ 16675 bezier: InkEditor.#toPDFCoordinates(buffer, rect, this.rotation), 16676 points: InkEditor.#toPDFCoordinates(points, rect, this.rotation) 16677 }); 16678 } 16679 return paths; 16680 } 16681 #getBbox() { 16682 let xMin = Infinity; 16683 let xMax = -Infinity; 16684 let yMin = Infinity; 16685 let yMax = -Infinity; 16686 for (const path of this.paths) { 16687 for (const [first, control1, control2, second] of path) { 16688 const bbox = _util.Util.bezierBoundingBox(...first, ...control1, ...control2, ...second); 16689 xMin = Math.min(xMin, bbox[0]); 16690 yMin = Math.min(yMin, bbox[1]); 16691 xMax = Math.max(xMax, bbox[2]); 16692 yMax = Math.max(yMax, bbox[3]); 16693 } 16694 } 16695 return [xMin, yMin, xMax, yMax]; 16696 } 16697 #getPadding() { 16698 return this.#disableEditing ? Math.ceil(this.thickness * this.parentScale) : 0; 16699 } 16700 #fitToContent(firstTime = false) { 16701 if (this.isEmpty()) { 16702 return; 16703 } 16704 if (!this.#disableEditing) { 16705 this.#redraw(); 16706 return; 16707 } 16708 const bbox = this.#getBbox(); 16709 const padding = this.#getPadding();
16710 this.#baseWidth = Math.max(_editor.AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]); 16711 this.#baseHeight = Math.max(_editor.AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]); 16712 const width = Math.ceil(padding + this.#baseWidth * this.scaleFactor); 16713 const height = Math.ceil(padding + this.#baseHeight * this.scaleFactor); 16714 const [parentWidth, parentHeight] = this.parentDimensions; 16715 this.width = width / parentWidth; 16716 this.height = height / parentHeight; 16717 this.setAspectRatio(width, height); 16718 const prevTranslationX = this.translationX; 16719 const prevTranslationY = this.translationY; 16720 this.translationX = -bbox[0]; 16721 this.translationY = -bbox[1]; 16722 this.#setCanvasDims(); 16723 this.#redraw(); 16724 this.#realWidth = width; 16725 this.#realHeight = height; 16726 this.setDims(width, height); 16727 const unscaledPadding = firstTime ? padding / this.scaleFactor / 2 : 0; 16728 this.translate(prevTranslationX - this.translationX - unscaledPadding, prevTranslationY - this.translationY - unscaledPadding); 16729 } 16730 static deserialize(data, parent, uiManager) { 16731 if (data instanceof _annotation_layer.InkAnnotationElement) { 16732 return null; 16733 } 16734 const editor = super.deserialize(data, parent, uiManager); 16735 editor.thickness = data.thickness; 16736 editor.color = _util.Util.makeHexColor(...data.color); 16737 editor.opacity = data.opacity; 16738 const [pageWidth, pageHeight] = editor.pageDimensions; 16739 const width = editor.width * pageWidth; 16740 const height = editor.height * pageHeight; 16741 const scaleFactor = editor.parentScale; 16742 const padding = data.thickness / 2; 16743 editor.#disableEditing = true; 16744 editor.#realWidth = Math.round(width); 16745 editor.#realHeight = Math.round(height); 16746 const { 16747 paths, 16748 rect, 16749 rotation 16750 } = data; 16751 for (let { 16752 bezier 16753 } of paths) { 16754 bezier = InkEditor.#fromPDFCoordinates(bezier, rect, rotation); 16755 const path = []; 16756 editor.paths.push(path); 16757 let p0 = scaleFactor * (bezier[0] - padding); 16758 let p1 = scaleFactor * (bezier[1] - padding); 16759 for (let i = 2, ii = bezier.length; i < ii; i += 6) { 16760 const p10 = scaleFactor * (bezier[i] - padding); 16761 const p11 = scaleFactor * (bezier[i + 1] - padding); 16762 const p20 = scaleFactor * (bezier[i + 2] - padding); 16763 const p21 = scaleFactor * (bezier[i + 3] - padding); 16764 const p30 = scaleFactor * (bezier[i + 4] - padding); 16765 const p31 = scaleFactor * (bezier[i + 5] - padding); 16766 path.push([[p0, p1], [p10, p11], [p20, p21], [p30, p31]]); 16767 p0 = p30; 16768 p1 = p31; 16769 } 16770 const path2D = this.#buildPath2D(path); 16771 editor.bezierPath2D.push(path2D); 16772 } 16773 const bbox = editor.#getBbox(); 16774 editor.#baseWidth = Math.max(_editor.AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]); 16775 editor.#baseHeight = Math.max(_editor.AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]); 16776 editor.#setScaleFactor(width, height); 16777 return editor; 16778 } 16779 serialize() { 16780 if (this.isEmpty()) { 16781 return null; 16782 } 16783 const rect = this.getRect(0, 0); 16784 const color = _editor.AnnotationEditor._colorManager.convert(this.ctx.strokeStyle); 16785 return { 16786 annotationType: _util.AnnotationEditorType.INK, 16787 color, 16788 thickness: this.thickness, 16789 opacity: this.opacity, 16790 paths: this.#serializePaths(this.scaleFactor / this.parentScale, this.translationX, this.translationY, rect), 16791 pageIndex: this.pageIndex, 16792 rect, 16793 rotation: this.rotation 16794 }; 16795 } 16796} 16797exports.InkEditor = InkEditor; 16798 16799/***/ }), 16800/* 34 */ 16801/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { 16802 16803 16804 16805Object.defineProperty(exports, "__esModule", ({ 16806 value: true 16807})); 16808exports.StampEditor = void 0; 16809var _editor = __w_pdfjs_require__(4); 16810var _util = __w_pdfjs_require__(1); 16811var _display_utils = __w_pdfjs_require__(6); 16812var _annotation_layer = __w_pdfjs_require__(29); 16813class StampEditor extends _editor.AnnotationEditor { 16814 #bitmap = null; 16815 #bitmapId = null; 16816 #bitmapPromise = null; 16817 #bitmapUrl = null; 16818 #canvas = null; 16819 #observer = null; 16820 #resizeTimeoutId = null; 16821 #isSvg = false;
16822 static _type = "stamp"; 16823 constructor(params) { 16824 super({ 16825 ...params, 16826 name: "stampEditor" 16827 }); 16828 this.#bitmapUrl = params.bitmapUrl; 16829 } 16830 #getBitmap() { 16831 if (this.#bitmapId) { 16832 this._uiManager.imageManager.getFromId(this.#bitmapId).then(data => { 16833 if (!data) { 16834 this.remove(); 16835 return; 16836 } 16837 this.#bitmap = data.bitmap; 16838 this.#createCanvas(); 16839 }); 16840 return; 16841 } 16842 if (this.#bitmapUrl) { 16843 const url = this.#bitmapUrl; 16844 this.#bitmapUrl = null; 16845 this.#bitmapPromise = this._uiManager.imageManager.getFromUrl(url).then(data => { 16846 this.#bitmapPromise = null; 16847 if (!data) { 16848 this.remove(); 16849 return; 16850 } 16851 ({ 16852 bitmap: this.#bitmap, 16853 id: this.#bitmapId, 16854 isSvg: this.#isSvg 16855 } = data); 16856 this.#createCanvas(); 16857 }); 16858 return; 16859 } 16860 const input = document.createElement("input"); 16861 input.type = "file"; 16862 input.accept = "image/*"; 16863 this.#bitmapPromise = new Promise(resolve => { 16864 input.addEventListener("change", async () => { 16865 this.#bitmapPromise = null; 16866 if (!input.files || input.files.length === 0) { 16867 this.remove(); 16868 } else { 16869 const data = await this._uiManager.imageManager.getFromFile(input.files[0]); 16870 if (!data) { 16871 this.remove(); 16872 return; 16873 } 16874 ({ 16875 bitmap: this.#bitmap, 16876 id: this.#bitmapId, 16877 isSvg: this.#isSvg 16878 } = data); 16879 this.#createCanvas(); 16880 } 16881 resolve(); 16882 }); 16883 input.addEventListener("cancel", () => { 16884 this.#bitmapPromise = null; 16885 this.remove(); 16886 resolve(); 16887 }); 16888 }); 16889 input.click(); 16890 } 16891 remove() { 16892 if (this.#bitmapId) { 16893 this.#bitmap = null; 16894 this._uiManager.imageManager.deleteId(this.#bitmapId); 16895 this.#canvas?.remove(); 16896 this.#canvas = null; 16897 this.#observer?.disconnect(); 16898 this.#observer = null; 16899 } 16900 super.remove(); 16901 } 16902 rebuild() { 16903 super.rebuild(); 16904 if (this.div === null) { 16905 return; 16906 } 16907 if (this.#bitmapId) { 16908 this.#getBitmap(); 16909 } 16910 if (!this.isAttachedToDOM) { 16911 this.parent.add(this); 16912 } 16913 } 16914 onceAdded() { 16915 this.div.draggable = true; 16916 this.parent.addUndoableEditor(this); 16917 this.div.focus(); 16918 } 16919 isEmpty() { 16920 return this.#bitmapPromise === null && this.#bitmap === null && this.#bitmapUrl === null; 16921 } 16922 get isResizable() { 16923 return true; 16924 } 16925 render() { 16926 if (this.div) { 16927 return this.div; 16928 } 16929 let baseX, baseY; 16930 if (this.width) { 16931 baseX = this.x; 16932 baseY = this.y; 16933 } 16934 super.render(); 16935 if (this.#bitmap) { 16936 this.#createCanvas(); 16937 } else { 16938 this.div.classList.add("loading"); 16939 this.#getBitmap(); 16940 } 16941 if (this.width) { 16942 const [parentWidth, parentHeight] = this.parentDimensions; 16943 this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); 16944 } 16945 return this.div; 16946 } 16947 #createCanvas() { 16948 const { 16949 div 16950 } = this; 16951 let { 16952 width, 16953 height 16954 } = this.#bitmap; 16955 const [pageWidth, pageHeight] = this.pageDimensions; 16956 const MAX_RATIO = 0.75; 16957 if (this.width) { 16958 width = this.width * pageWidth; 16959 height = this.height * pageHeight; 16960 } else if (width > MAX_RATIO * pageWidth || height > MAX_RATIO * pageHeight) { 16961 const factor = Math.min(MAX_RATIO * pageWidth / width, MAX_RATIO * pageHeight / height); 16962 width *= factor; 16963 height *= factor; 16964 } 16965 const [parentWidth, parentHeight] = this.parentDimensions; 16966 this.setDims(width * parentWidth / pageWidth, height * parentHeight / pageHeight); 16967 const canvas = this.#canvas = document.createElement("canvas"); 16968 div.append(canvas); 16969 this.#drawBitmap(width, height); 16970 this.#createObserver(); 16971 div.classList.remove("loading"); 16972 } 16973 #setDimensions(width, height) { 16974 const [parentWidth, parentHeight] = this.parentDimensions; 16975 this.width = width / parentWidth; 16976 this.height = height / parentHeight; 16977 this.setDims(width, height); 16978 this.fixAndSetPosition(); 16979 if (this.#resizeTimeoutId !== null) { 16980 clearTimeout(this.#resizeTimeoutId); 16981 } 16982 const TIME_TO_WAIT = 200; 16983 this.#resizeTimeoutId = setTimeout(() => { 16984 this.#resizeTimeoutId = null; 16985 this.#drawBitmap(width, height); 16986 }, TIME_TO_WAIT); 16987 } 16988 #scaleBitmap(width, height) { 16989 const { 16990 width: bitmapWidth, 16991 height: bitmapHeight 16992 } = this.#bitmap; 16993 let newWidth = bitmapWidth; 16994 let newHeight = bitmapHeight; 16995 let bitmap = this.#bitmap; 16996 while (newWidth > 2 * width || newHeight > 2 * height) { 16997 const prevWidth = newWidth; 16998 const prevHeight = newHeight; 16999 if (newWidth > 2 * width) { 17000 newWidth = newWidth >= 16384 ? Math.floor(newWidth / 2) - 1 : Math.ceil(newWidth / 2); 17001 } 17002 if (newHeight > 2 * height) { 17003 newHeight = newHeight >= 16384 ? Math.floor(newHeight / 2) - 1 : Math.ceil(newHeight / 2); 17004 } 17005 const offscreen = new OffscreenCanvas(newWidth, newHeight); 17006 const ctx = offscreen.getContext("2d"); 17007 ctx.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight); 17008 bitmap = offscreen.transferToImageBitmap(); 17009 } 17010 return bitmap; 17011 } 17012 #drawBitmap(width, height) { 17013 const canvas = this.#canvas; 17014 if (!canvas || canvas.width === width && canvas.height === height) { 17015 return; 17016 } 17017 canvas.width = width; 17018 canvas.height = height; 17019 const bitmap = this.#isSvg ? this.#bitmap : this.#scaleBitmap(width, height); 17020 const ctx = canvas.getContext("2d"); 17021 ctx.filter = this._uiManager.hcmFilter; 17022 ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height); 17023 } 17024 #serializeBitmap(toUrl) { 17025 if (toUrl) { 17026 if (this.#isSvg) { 17027 const url = this._uiManager.imageManager.getSvgUrl(this.#bitmapId); 17028 if (url) { 17029 return url; 17030 } 17031 } 17032 const canvas = document.createElement("canvas"); 17033 ({ 17034 width: canvas.width, 17035 height: canvas.height 17036 } = this.#bitmap); 17037 const ctx = canvas.getContext("2d"); 17038 ctx.drawImage(this.#bitmap, 0, 0); 17039 return canvas.toDataURL(); 17040 } 17041 if (this.#isSvg) { 17042 const [pageWidth, pageHeight] = this.pageDimensions; 17043 const width = Math.round(this.width * pageWidth * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS); 17044 const height = Math.round(this.height * pageHeight * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS); 17045 const offscreen = new OffscreenCanvas(width, height); 17046 const ctx = offscreen.getContext("2d"); 17047 ctx.drawImage(this.#bitmap, 0, 0, this.#bitmap.width, this.#bitmap.height, 0, 0, width, height); 17048 return offscreen.transferToImageBitmap(); 17049 } 17050 return structuredClone(this.#bitmap); 17051 } 17052 #createObserver() { 17053 this.#observer = new ResizeObserver(entries => {
17054 const rect = entries[0].contentRect; 17055 if (rect.width && rect.height) { 17056 this.#setDimensions(rect.width, rect.height); 17057 } 17058 }); 17059 this.#observer.observe(this.div); 17060 } 17061 static deserialize(data, parent, uiManager) { 17062 if (data instanceof _annotation_layer.StampAnnotationElement) { 17063 return null; 17064 } 17065 const editor = super.deserialize(data, parent, uiManager); 17066 const { 17067 rect, 17068 bitmapUrl, 17069 bitmapId, 17070 isSvg 17071 } = data; 17072 if (bitmapId && uiManager.imageManager.isValidId(bitmapId)) { 17073 editor.#bitmapId = bitmapId; 17074 } else { 17075 editor.#bitmapUrl = bitmapUrl; 17076 } 17077 editor.#isSvg = isSvg; 17078 const [parentWidth, parentHeight] = editor.pageDimensions; 17079 editor.width = (rect[2] - rect[0]) / parentWidth; 17080 editor.height = (rect[3] - rect[1]) / parentHeight; 17081 return editor; 17082 } 17083 serialize(isForCopying = false, context = null) { 17084 if (this.isEmpty()) { 17085 return null; 17086 } 17087 const serialized = { 17088 annotationType: _util.AnnotationEditorType.STAMP, 17089 bitmapId: this.#bitmapId, 17090 pageIndex: this.pageIndex, 17091 rect: this.getRect(0, 0), 17092 rotation: this.rotation, 17093 isSvg: this.#isSvg 17094 }; 17095 if (isForCopying) { 17096 serialized.bitmapUrl = this.#serializeBitmap(true); 17097 return serialized; 17098 } 17099 if (context === null) { 17100 return serialized; 17101 } 17102 context.stamps ||= new Map(); 17103 const area = this.#isSvg ? (serialized.rect[2] - serialized.rect[0]) * (serialized.rect[3] - serialized.rect[1]) : null; 17104 if (!context.stamps.has(this.#bitmapId)) { 17105 context.stamps.set(this.#bitmapId, { 17106 area, 17107 serialized 17108 }); 17109 serialized.bitmap = this.#serializeBitmap(false); 17110 } else if (this.#isSvg) { 17111 const prevData = context.stamps.get(this.#bitmapId); 17112 if (area > prevData.area) { 17113 prevData.area = area; 17114 prevData.serialized.bitmap.close(); 17115 prevData.serialized.bitmap = this.#serializeBitmap(false); 17116 } 17117 } 17118 return serialized; 17119 } 17120} 17121exports.StampEditor = StampEditor; 17122 17123/***/ }) 17124/******/ ]); 17125/************************************************************************/ 17126/******/ // The module cache 17127/******/ var __webpack_module_cache__ = {}; 17128/******/ 17129/******/ // The require function 17130/******/ function __w_pdfjs_require__(moduleId) { 17131/******/ // Check if module is in cache 17132/******/ var cachedModule = __webpack_module_cache__[moduleId]; 17133/******/ if (cachedModule !== undefined) { 17134/******/ return cachedModule.exports; 17135/******/ } 17136/******/ // Create a new module (and put it into the cache) 17137/******/ var module = __webpack_module_cache__[moduleId] = { 17138/******/ // no module.id needed 17139/******/ // no module.loaded needed 17140/******/ exports: {} 17141/******/ }; 17142/******/ 17143/******/ // Execute the module function 17144/******/ __webpack_modules__[moduleId](module, module.exports, __w_pdfjs_require__); 17145/******/ 17146/******/ // Return the exports of the module 17147/******/ return module.exports; 17148/******/ } 17149/******/ 17150/************************************************************************/ 17151var __webpack_exports__ = {}; 17152// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. 17153(() => { 17154var exports = __webpack_exports__; 17155 17156 17157Object.defineProperty(exports, "__esModule", ({ 17158 value: true 17159})); 17160Object.defineProperty(exports, "AbortException", ({ 17161 enumerable: true, 17162 get: function () { 17163 return _util.AbortException; 17164 } 17165})); 17166Object.defineProperty(exports, "AnnotationEditorLayer", ({ 17167 enumerable: true, 17168 get: function () { 17169 return _annotation_editor_layer.AnnotationEditorLayer; 17170 } 17171})); 17172Object.defineProperty(exports, "AnnotationEditorParamsType", ({ 17173 enumerable: true, 17174 get: function () { 17175 return _util.AnnotationEditorParamsType; 17176 } 17177})); 17178Object.defineProperty(exports, "AnnotationEditorType", ({ 17179 enumerable: true, 17180 get: function () { 17181 return _util.AnnotationEditorType; 17182 } 17183})); 17184Object.defineProperty(exports, "AnnotationEditorUIManager", ({ 17185 enumerable: true, 17186 get: function () { 17187 return _tools.AnnotationEditorUIManager; 17188 } 17189})); 17190Object.defineProperty(exports, "AnnotationLayer", ({ 17191 enumerable: true, 17192 get: function () { 17193 return _annotation_layer.AnnotationLayer; 17194 } 17195})); 17196Object.defineProperty(exports, "AnnotationMode", ({ 17197 enumerable: true, 17198 get: function () { 17199 return _util.AnnotationMode; 17200 } 17201})); 17202Object.defineProperty(exports, "CMapCompressionType", ({ 17203 enumerable: true, 17204 get: function () { 17205 return _util.CMapCompressionType; 17206 } 17207})); 17208Object.defineProperty(exports, "FeatureTest", ({ 17209 enumerable: true, 17210 get: function () { 17211 return _util.FeatureTest; 17212 } 17213})); 17214Object.defineProperty(exports, "GlobalWorkerOptions", ({ 17215 enumerable: true, 17216 get: function () { 17217 return _worker_options.GlobalWorkerOptions; 17218 } 17219})); 17220Object.defineProperty(exports, "ImageKind", ({ 17221 enumerable: true, 17222 get: function () { 17223 return _util.ImageKind; 17224 } 17225})); 17226Object.defineProperty(exports, "InvalidPDFException", ({ 17227 enumerable: true, 17228 get: function () { 17229 return _util.InvalidPDFException; 17230 } 17231})); 17232Object.defineProperty(exports, "MissingPDFException", ({ 17233 enumerable: true, 17234 get: function () { 17235 return _util.MissingPDFException; 17236 } 17237})); 17238Object.defineProperty(exports, "OPS", ({ 17239 enumerable: true, 17240 get: function () { 17241 return _util.OPS; 17242 } 17243})); 17244Object.defineProperty(exports, "PDFDataRangeTransport", ({ 17245 enumerable: true, 17246 get: function () { 17247 return _api.PDFDataRangeTransport; 17248 } 17249})); 17250Object.defineProperty(exports, "PDFDateString", ({ 17251 enumerable: true, 17252 get: function () { 17253 return _display_utils.PDFDateString; 17254 } 17255})); 17256Object.defineProperty(exports, "PDFWorker", ({ 17257 enumerable: true, 17258 get: function () { 17259 return _api.PDFWorker; 17260 } 17261})); 17262Object.defineProperty(exports, "PasswordResponses", ({ 17263 enumerable: true, 17264 get: function () { 17265 return _util.PasswordResponses; 17266 } 17267})); 17268Object.defineProperty(exports, "PermissionFlag", ({ 17269 enumerable: true, 17270 get: function () { 17271 return _util.PermissionFlag; 17272 } 17273})); 17274Object.defineProperty(exports, "PixelsPerInch", ({ 17275 enumerable: true, 17276 get: function () { 17277 return _display_utils.PixelsPerInch; 17278 } 17279})); 17280Object.defineProperty(exports, "PromiseCapability", ({ 17281 enumerable: true, 17282 get: function () { 17283 return _util.PromiseCapability; 17284 } 17285})); 17286Object.defineProperty(exports, "RenderingCancelledException", ({ 17287 enumerable: true, 17288 get: function () { 17289 return _display_utils.RenderingCancelledException; 17290 } 17291})); 17292Object.defineProperty(exports, "SVGGraphics", ({ 17293 enumerable: true, 17294 get: function () { 17295 return _api.SVGGraphics; 17296 } 17297})); 17298Object.defineProperty(exports, "UnexpectedResponseException", ({ 17299 enumerable: true, 17300 get: function () { 17301 return _util.UnexpectedResponseException; 17302 } 17303})); 17304Object.defineProperty(exports, "Util", ({ 17305 enumerable: true, 17306 get: function () { 17307 return _util.Util; 17308 } 17309})); 17310Object.defineProperty(exports, "VerbosityLevel", ({ 17311 enumerable: true, 17312 get: function () { 17313 return _util.VerbosityLevel; 17314 } 17315})); 17316Object.defineProperty(exports, "XfaLayer", ({ 17317 enumerable: true, 17318 get: function () { 17319 return _xfa_layer.XfaLayer; 17320 } 17321}));
17322Object.defineProperty(exports, "build", ({ 17323 enumerable: true, 17324 get: function () { 17325 return _api.build; 17326 } 17327})); 17328Object.defineProperty(exports, "createValidAbsoluteUrl", ({ 17329 enumerable: true, 17330 get: function () { 17331 return _util.createValidAbsoluteUrl; 17332 } 17333})); 17334Object.defineProperty(exports, "getDocument", ({ 17335 enumerable: true, 17336 get: function () { 17337 return _api.getDocument; 17338 } 17339})); 17340Object.defineProperty(exports, "getFilenameFromUrl", ({ 17341 enumerable: true, 17342 get: function () { 17343 return _display_utils.getFilenameFromUrl; 17344 } 17345})); 17346Object.defineProperty(exports, "getPdfFilenameFromUrl", ({ 17347 enumerable: true, 17348 get: function () { 17349 return _display_utils.getPdfFilenameFromUrl; 17350 } 17351})); 17352Object.defineProperty(exports, "getXfaPageViewport", ({ 17353 enumerable: true, 17354 get: function () { 17355 return _display_utils.getXfaPageViewport; 17356 } 17357})); 17358Object.defineProperty(exports, "isDataScheme", ({ 17359 enumerable: true, 17360 get: function () { 17361 return _display_utils.isDataScheme; 17362 } 17363})); 17364Object.defineProperty(exports, "isPdfFile", ({ 17365 enumerable: true, 17366 get: function () { 17367 return _display_utils.isPdfFile; 17368 } 17369})); 17370Object.defineProperty(exports, "loadScript", ({ 17371 enumerable: true, 17372 get: function () { 17373 return _display_utils.loadScript; 17374 } 17375})); 17376Object.defineProperty(exports, "normalizeUnicode", ({ 17377 enumerable: true, 17378 get: function () { 17379 return _util.normalizeUnicode; 17380 } 17381})); 17382Object.defineProperty(exports, "renderTextLayer", ({ 17383 enumerable: true, 17384 get: function () { 17385 return _text_layer.renderTextLayer; 17386 } 17387})); 17388Object.defineProperty(exports, "setLayerDimensions", ({ 17389 enumerable: true, 17390 get: function () { 17391 return _display_utils.setLayerDimensions; 17392 } 17393})); 17394Object.defineProperty(exports, "shadow", ({ 17395 enumerable: true, 17396 get: function () { 17397 return _util.shadow; 17398 } 17399})); 17400Object.defineProperty(exports, "updateTextLayer", ({ 17401 enumerable: true, 17402 get: function () { 17403 return _text_layer.updateTextLayer; 17404 } 17405})); 17406Object.defineProperty(exports, "version", ({ 17407 enumerable: true, 17408 get: function () { 17409 return _api.version; 17410 } 17411})); 17412var _util = __w_pdfjs_require__(1); 17413var _api = __w_pdfjs_require__(2); 17414var _display_utils = __w_pdfjs_require__(6); 17415var _text_layer = __w_pdfjs_require__(26); 17416var _annotation_editor_layer = __w_pdfjs_require__(27); 17417var _tools = __w_pdfjs_require__(5); 17418var _annotation_layer = __w_pdfjs_require__(29); 17419var _worker_options = __w_pdfjs_require__(14); 17420var _xfa_layer = __w_pdfjs_require__(32); 17421const pdfjsVersion = '3.9.179'; 17422const pdfjsBuild = '1ef6fbc52'; 17423})(); 17424 17425/******/ return __webpack_exports__; 17426/******/ })() 17427; 17428}); 17429//# sourceMappingURL=pdf.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.