1/** @license 2 * 3 * jsPDF - PDF Document creation from JavaScript 4 * Version 2.5.1 Built on 2022-01-28T15:37:57.789Z 5 * CommitID 00000000 6 * 7 * Copyright (c) 2010-2021 James Hall <[email protected]>, https://github.com/MrRio/jsPDF 8 * 2015-2021 yWorks GmbH, http://www.yworks.com 9 * 2015-2021 Lukas Holländer <[email protected]>, https://github.com/HackbrettXXX 10 * 2016-2018 Aras Abbasi <[email protected]> 11 * 2010 Aaron Spike, https://github.com/acspike 12 * 2012 Willow Systems Corporation, https://github.com/willowsystems 13 * 2012 Pablo Hess, https://github.com/pablohess 14 * 2012 Florian Jenett, https://github.com/fjenett 15 * 2013 Warren Weckesser, https://github.com/warrenweckesser 16 * 2013 Youssef Beddad, https://github.com/lifof 17 * 2013 Lee Driscoll, https://github.com/lsdriscoll 18 * 2013 Stefan Slonevskiy, https://github.com/stefslon 19 * 2013 Jeremy Morel, https://github.com/jmorel 20 * 2013 Christoph Hartmann, https://github.com/chris-rock 21 * 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria 22 * 2014 James Makes, https://github.com/dollaruw 23 * 2014 Diego Casorran, https://github.com/diegocr 24 * 2014 Steven Spungin, https://github.com/Flamenco 25 * 2014 Kenneth Glassey, https://github.com/Gavvers 26 * 27 * Permission is hereby granted, free of charge, to any person obtaining 28 * a copy of this software and associated documentation files (the 29 * "Software"), to deal in the Software without restriction, including 30 * without limitation the rights to use, copy, modify, merge, publish, 31 * distribute, sublicense, and/or sell copies of the Software, and to 32 * permit persons to whom the Software is furnished to do so, subject to 33 * the following conditions: 34 * 35 * The above copyright notice and this permission notice shall be 36 * included in all copies or substantial portions of the Software. 37 * 38 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 39 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 40 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 41 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 42 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 43 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 44 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 45 * 46 * Contributor(s): 47 * siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango, 48 * kim3er, mfo, alnorth, Flamenco 49 */ 50 51(function (global, factory) { 52 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 53 typeof define === 'function' && define.amd ? define(['exports'], factory) : 54 (global = global || self, factory(global.jspdf = {})); 55}(this, (function (exports) { 'use strict'; 56 57 function _typeof(obj) { 58 "@babel/helpers - typeof"; 59 60 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 61 _typeof = function (obj) { 62 return typeof obj; 63 }; 64 } else { 65 _typeof = function (obj) { 66 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 67 }; 68 } 69 70 return _typeof(obj); 71 } 72 73 var globalObject = function () { 74 return "undefined" !== typeof window ? window : "undefined" !== typeof global ? global : "undefined" !== typeof self ? self : this; 75 }(); 76 77 function consoleLog() { 78 if (globalObject.console && typeof globalObject.console.log === "function") { 79 globalObject.console.log.apply(globalObject.console, arguments); 80 } 81 } 82 83 function consoleWarn(str) { 84 if (globalObject.console) { 85 if (typeof globalObject.console.warn === "function") { 86 globalObject.console.warn.apply(globalObject.console, arguments); 87 } else { 88 consoleLog.call(null, arguments); 89 } 90 } 91 } 92 93 function consoleError(str) { 94 if (globalObject.console) { 95 if (typeof globalObject.console.error === "function") { 96 globalObject.console.error.apply(globalObject.console, arguments); 97 } else { 98 consoleLog(str); 99 } 100 } 101 } 102 103 var console = { 104 log: consoleLog, 105 warn: consoleWarn, 106 error: consoleError 107 }; 108 109 function bom(blob, opts) { 110 if (typeof opts === "undefined") opts = { 111 autoBom: false 112 };else if (_typeof(opts) !== "object") { 113 console.warn("Deprecated: Expected third argument to be a object"); 114 opts = { 115 autoBom: !opts 116 }; 117 } // prepend BOM for UTF-8 XML and text/* types (including HTML) 118 // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF 119 120 if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { 121 return new Blob([String.fromCharCode(0xfeff), blob], { 122 type: blob.type 123 }); 124 } 125 126 return blob; 127 } 128 129 function download(url, name, opts) { 130 var xhr = new XMLHttpRequest(); 131 xhr.open("GET", url); 132 xhr.responseType = "blob"; 133 134 xhr.onload = function () { 135 saveAs(xhr.response, name, opts); 136 }; 137 138 xhr.onerror = function () { 139 console.error("could not download file"); 140 }; 141 142 xhr.send(); 143 } 144 145 function corsEnabled(url) { 146 var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker 147 148 xhr.open("HEAD", url, false); 149 150 try { 151 xhr.send(); 152 } catch (e) {} 153 154 return xhr.status >= 200 && xhr.status <= 299; 155 } // `a.click()` doesn't work for all browsers (#465) 156 157 158 function click(node) { 159 try { 160 node.dispatchEvent(new MouseEvent("click")); 161 } catch (e) { 162 var evt = document.createEvent("MouseEvents"); 163 evt.initMouseEvent("click", true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null); 164 node.dispatchEvent(evt); 165 } 166 } 167 168 var saveAs = globalObject.saveAs || ( // probably in some web worker 169 (typeof window === "undefined" ? "undefined" : _typeof(window)) !== "object" || window !== globalObject ? function saveAs() { 170 /* noop */ 171 } : // Use download attribute first if possible (#193 Lumia mobile) unless this is a native app 172 typeof HTMLAnchorElement !== "undefined" && "download" in HTMLAnchorElement.prototype ? function saveAs(blob, name, opts) { 173 var URL = globalObject.URL || globalObject.webkitURL; 174 var a = document.createElement("a"); 175 name = name || blob.name || "download";
vendor: 113,971 bytes, lines 176-3826
176 a.download = name; 177 a.rel = "noopener"; // tabnabbing 178 // TODO: detect chrome extensions & packaged apps 179 // a.target = '_blank' 180 181 if (typeof blob === "string") { 182 // Support regular links 183 a.href = blob; 184 185 if (a.origin !== location.origin) { 186 corsEnabled(a.href) ? download(blob, name, opts) : click(a, a.target = "_blank"); 187 } else { 188 click(a); 189 } 190 } else { 191 // Support blobs 192 a.href = URL.createObjectURL(blob); 193 setTimeout(function () { 194 URL.revokeObjectURL(a.href); 195 }, 4e4); // 40s 196 197 setTimeout(function () { 198 click(a); 199 }, 0); 200 } 201 } : // Use msSaveOrOpenBlob as a second approach 202 "msSaveOrOpenBlob" in navigator ? function saveAs(blob, name, opts) { 203 name = name || blob.name || "download"; 204 205 if (typeof blob === "string") { 206 if (corsEnabled(blob)) { 207 download(blob, name, opts); 208 } else { 209 var a = document.createElement("a"); 210 a.href = blob; 211 a.target = "_blank"; 212 setTimeout(function () { 213 click(a); 214 }); 215 } 216 } else { 217 navigator.msSaveOrOpenBlob(bom(blob, opts), name); 218 } 219 } : // Fallback to using FileReader and a popup 220 function saveAs(blob, name, opts, popup) { 221 // Open a popup immediately do go around popup blocker 222 // Mostly only available on user interaction and the fileReader is async so... 223 popup = popup || open("", "_blank"); 224 225 if (popup) { 226 popup.document.title = popup.document.body.innerText = "downloading..."; 227 } 228 229 if (typeof blob === "string") return download(blob, name, opts); 230 var force = blob.type === "application/octet-stream"; 231 232 var isSafari = /constructor/i.test(globalObject.HTMLElement) || globalObject.safari; 233 234 var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent); 235 236 if ((isChromeIOS || force && isSafari) && (typeof FileReader === "undefined" ? "undefined" : _typeof(FileReader)) === "object") { 237 // Safari doesn't allow downloading of blob URLs 238 var reader = new FileReader(); 239 240 reader.onloadend = function () { 241 var url = reader.result; 242 url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, "data:attachment/file;"); 243 if (popup) popup.location.href = url;else location = url; 244 popup = null; // reverse-tabnabbing #460 245 }; 246 247 reader.readAsDataURL(blob); 248 } else { 249 var URL = globalObject.URL || globalObject.webkitURL; 250 var url = URL.createObjectURL(blob); 251 if (popup) popup.location = url;else location.href = url; 252 popup = null; // reverse-tabnabbing #460 253 254 setTimeout(function () { 255 URL.revokeObjectURL(url); 256 }, 4e4); // 40s 257 } 258 }); 259 260 /** 261 * A class to parse color values 262 * @author Stoyan Stefanov <[email protected]> 263 * {@link http://www.phpied.com/rgb-color-parser-in-javascript/} 264 * @license Use it if you like it 265 */ 266 function RGBColor(color_string) { 267 color_string = color_string || ""; 268 this.ok = false; // strip any leading # 269 270 if (color_string.charAt(0) == "#") { 271 // remove # if any 272 color_string = color_string.substr(1, 6); 273 } 274 275 color_string = color_string.replace(/ /g, ""); 276 color_string = color_string.toLowerCase(); 277 var channels; // before getting into regexps, try simple matches 278 // and overwrite the input 279 280 var simple_colors = { 281 aliceblue: "f0f8ff", 282 antiquewhite: "faebd7", 283 aqua: "00ffff", 284 aquamarine: "7fffd4", 285 azure: "f0ffff", 286 beige: "f5f5dc", 287 bisque: "ffe4c4", 288 black: "000000", 289 blanchedalmond: "ffebcd", 290 blue: "0000ff", 291 blueviolet: "8a2be2", 292 brown: "a52a2a", 293 burlywood: "deb887", 294 cadetblue: "5f9ea0", 295 chartreuse: "7fff00", 296 chocolate: "d2691e", 297 coral: "ff7f50", 298 cornflowerblue: "6495ed", 299 cornsilk: "fff8dc", 300 crimson: "dc143c", 301 cyan: "00ffff", 302 darkblue: "00008b", 303 darkcyan: "008b8b", 304 darkgoldenrod: "b8860b", 305 darkgray: "a9a9a9", 306 darkgreen: "006400", 307 darkkhaki: "bdb76b", 308 darkmagenta: "8b008b", 309 darkolivegreen: "556b2f", 310 darkorange: "ff8c00", 311 darkorchid: "9932cc", 312 darkred: "8b0000", 313 darksalmon: "e9967a", 314 darkseagreen: "8fbc8f", 315 darkslateblue: "483d8b", 316 darkslategray: "2f4f4f", 317 darkturquoise: "00ced1", 318 darkviolet: "9400d3", 319 deeppink: "ff1493", 320 deepskyblue: "00bfff", 321 dimgray: "696969", 322 dodgerblue: "1e90ff", 323 feldspar: "d19275", 324 firebrick: "b22222", 325 floralwhite: "fffaf0", 326 forestgreen: "228b22", 327 fuchsia: "ff00ff", 328 gainsboro: "dcdcdc", 329 ghostwhite: "f8f8ff", 330 gold: "ffd700", 331 goldenrod: "daa520", 332 gray: "808080", 333 green: "008000", 334 greenyellow: "adff2f", 335 honeydew: "f0fff0", 336 hotpink: "ff69b4", 337 indianred: "cd5c5c", 338 indigo: "4b0082", 339 ivory: "fffff0", 340 khaki: "f0e68c", 341 lavender: "e6e6fa", 342 lavenderblush: "fff0f5", 343 lawngreen: "7cfc00", 344 lemonchiffon: "fffacd", 345 lightblue: "add8e6", 346 lightcoral: "f08080", 347 lightcyan: "e0ffff", 348 lightgoldenrodyellow: "fafad2", 349 lightgrey: "d3d3d3", 350 lightgreen: "90ee90", 351 lightpink: "ffb6c1", 352 lightsalmon: "ffa07a", 353 lightseagreen: "20b2aa", 354 lightskyblue: "87cefa", 355 lightslateblue: "8470ff", 356 lightslategray: "778899", 357 lightsteelblue: "b0c4de", 358 lightyellow: "ffffe0", 359 lime: "00ff00", 360 limegreen: "32cd32", 361 linen: "faf0e6", 362 magenta: "ff00ff", 363 maroon: "800000", 364 mediumaquamarine: "66cdaa", 365 mediumblue: "0000cd", 366 mediumorchid: "ba55d3", 367 mediumpurple: "9370d8", 368 mediumseagreen: "3cb371", 369 mediumslateblue: "7b68ee", 370 mediumspringgreen: "00fa9a", 371 mediumturquoise: "48d1cc", 372 mediumvioletred: "c71585", 373 midnightblue: "191970", 374 mintcream: "f5fffa", 375 mistyrose: "ffe4e1", 376 moccasin: "ffe4b5", 377 navajowhite: "ffdead", 378 navy: "000080", 379 oldlace: "fdf5e6", 380 olive: "808000", 381 olivedrab: "6b8e23", 382 orange: "ffa500", 383 orangered: "ff4500", 384 orchid: "da70d6", 385 palegoldenrod: "eee8aa", 386 palegreen: "98fb98", 387 paleturquoise: "afeeee", 388 palevioletred: "d87093", 389 papayawhip: "ffefd5", 390 peachpuff: "ffdab9", 391 peru: "cd853f", 392 pink: "ffc0cb", 393 plum: "dda0dd", 394 powderblue: "b0e0e6", 395 purple: "800080", 396 red: "ff0000", 397 rosybrown: "bc8f8f", 398 royalblue: "4169e1", 399 saddlebrown: "8b4513", 400 salmon: "fa8072", 401 sandybrown: "f4a460", 402 seagreen: "2e8b57", 403 seashell: "fff5ee", 404 sienna: "a0522d", 405 silver: "c0c0c0", 406 skyblue: "87ceeb", 407 slateblue: "6a5acd", 408 slategray: "708090", 409 snow: "fffafa", 410 springgreen: "00ff7f", 411 steelblue: "4682b4", 412 tan: "d2b48c", 413 teal: "008080", 414 thistle: "d8bfd8", 415 tomato: "ff6347", 416 turquoise: "40e0d0", 417 violet: "ee82ee", 418 violetred: "d02090", 419 wheat: "f5deb3", 420 white: "ffffff", 421 whitesmoke: "f5f5f5", 422 yellow: "ffff00", 423 yellowgreen: "9acd32" 424 }; 425 color_string = simple_colors[color_string] || color_string; // array of color definition objects 426 427 var color_defs = [{ 428 re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, 429 example: ["rgb(123, 234, 45)", "rgb(255,234,245)"], 430 process: function process(bits) { 431 return [parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3])]; 432 } 433 }, { 434 re: /^(\w{2})(\w{2})(\w{2})$/, 435 example: ["#00ff00", "336699"], 436 process: function process(bits) { 437 return [parseInt(bits[1], 16), parseInt(bits[2], 16), parseInt(bits[3], 16)]; 438 } 439 }, { 440 re: /^(\w{1})(\w{1})(\w{1})$/, 441 example: ["#fb0", "f0f"], 442 process: function process(bits) { 443 return [parseInt(bits[1] + bits[1], 16), parseInt(bits[2] + bits[2], 16), parseInt(bits[3] + bits[3], 16)]; 444 } 445 }]; // search through the definitions to find a match 446 447 for (var i = 0; i < color_defs.length; i++) { 448 var re = color_defs[i].re; 449 var processor = color_defs[i].process; 450 var bits = re.exec(color_string); 451 452 if (bits) { 453 channels = processor(bits); 454 this.r = channels[0]; 455 this.g = channels[1]; 456 this.b = channels[2]; 457 this.ok = true; 458 } 459 } // validate/cleanup values 460 461 462 this.r = this.r < 0 || isNaN(this.r) ? 0 : this.r > 255 ? 255 : this.r; 463 this.g = this.g < 0 || isNaN(this.g) ? 0 : this.g > 255 ? 255 : this.g; 464 this.b = this.b < 0 || isNaN(this.b) ? 0 : this.b > 255 ? 255 : this.b; // some getters 465 466 this.toRGB = function () { 467 return "rgb(" + this.r + ", " + this.g + ", " + this.b + ")"; 468 }; 469 470 this.toHex = function () { 471 var r = this.r.toString(16); 472 var g = this.g.toString(16); 473 var b = this.b.toString(16); 474 if (r.length == 1) r = "0" + r; 475 if (g.length == 1) g = "0" + g; 476 if (b.length == 1) b = "0" + b; 477 return "#" + r + g + b; 478 }; 479 } 480 481 var atob, btoa; 482 483 (function () { 484 atob = globalObject.atob.bind(globalObject); 485 btoa = globalObject.btoa.bind(globalObject); 486 return; 487 })(); 488 489 /** 490 * @license 491 * Joseph Myers does not specify a particular license for his work. 492 * 493 * Author: Joseph Myers 494 * Accessed from: http://www.myersdaily.org/joseph/javascript/md5.js 495 * 496 * Modified by: Owen Leong 497 */ 498 function md5cycle(x, k) { 499 var a = x[0], 500 b = x[1], 501 c = x[2], 502 d = x[3]; 503 a = ff(a, b, c, d, k[0], 7, -680876936); 504 d = ff(d, a, b, c, k[1], 12, -389564586); 505 c = ff(c, d, a, b, k[2], 17, 606105819); 506 b = ff(b, c, d, a, k[3], 22, -1044525330); 507 a = ff(a, b, c, d, k[4], 7, -176418897); 508 d = ff(d, a, b, c, k[5], 12, 1200080426); 509 c = ff(c, d, a, b, k[6], 17, -1473231341); 510 b = ff(b, c, d, a, k[7], 22, -45705983); 511 a = ff(a, b, c, d, k[8], 7, 1770035416); 512 d = ff(d, a, b, c, k[9], 12, -1958414417); 513 c = ff(c, d, a, b, k[10], 17, -42063); 514 b = ff(b, c, d, a, k[11], 22, -1990404162); 515 a = ff(a, b, c, d, k[12], 7, 1804603682); 516 d = ff(d, a, b, c, k[13], 12, -40341101); 517 c = ff(c, d, a, b, k[14], 17, -1502002290); 518 b = ff(b, c, d, a, k[15], 22, 1236535329); 519 a = gg(a, b, c, d, k[1], 5, -165796510); 520 d = gg(d, a, b, c, k[6], 9, -1069501632); 521 c = gg(c, d, a, b, k[11], 14, 643717713); 522 b = gg(b, c, d, a, k[0], 20, -373897302); 523 a = gg(a, b, c, d, k[5], 5, -701558691); 524 d = gg(d, a, b, c, k[10], 9, 38016083); 525 c = gg(c, d, a, b, k[15], 14, -660478335); 526 b = gg(b, c, d, a, k[4], 20, -405537848); 527 a = gg(a, b, c, d, k[9], 5, 568446438); 528 d = gg(d, a, b, c, k[14], 9, -1019803690); 529 c = gg(c, d, a, b, k[3], 14, -187363961); 530 b = gg(b, c, d, a, k[8], 20, 1163531501); 531 a = gg(a, b, c, d, k[13], 5, -1444681467); 532 d = gg(d, a, b, c, k[2], 9, -51403784); 533 c = gg(c, d, a, b, k[7], 14, 1735328473); 534 b = gg(b, c, d, a, k[12], 20, -1926607734); 535 a = hh(a, b, c, d, k[5], 4, -378558); 536 d = hh(d, a, b, c, k[8], 11, -2022574463); 537 c = hh(c, d, a, b, k[11], 16, 1839030562); 538 b = hh(b, c, d, a, k[14], 23, -35309556); 539 a = hh(a, b, c, d, k[1], 4, -1530992060); 540 d = hh(d, a, b, c, k[4], 11, 1272893353); 541 c = hh(c, d, a, b, k[7], 16, -155497632); 542 b = hh(b, c, d, a, k[10], 23, -1094730640); 543 a = hh(a, b, c, d, k[13], 4, 681279174); 544 d = hh(d, a, b, c, k[0], 11, -358537222); 545 c = hh(c, d, a, b, k[3], 16, -722521979); 546 b = hh(b, c, d, a, k[6], 23, 76029189); 547 a = hh(a, b, c, d, k[9], 4, -640364487); 548 d = hh(d, a, b, c, k[12], 11, -421815835); 549 c = hh(c, d, a, b, k[15], 16, 530742520); 550 b = hh(b, c, d, a, k[2], 23, -995338651); 551 a = ii(a, b, c, d, k[0], 6, -198630844); 552 d = ii(d, a, b, c, k[7], 10, 1126891415); 553 c = ii(c, d, a, b, k[14], 15, -1416354905); 554 b = ii(b, c, d, a, k[5], 21, -57434055); 555 a = ii(a, b, c, d, k[12], 6, 1700485571); 556 d = ii(d, a, b, c, k[3], 10, -1894986606); 557 c = ii(c, d, a, b, k[10], 15, -1051523); 558 b = ii(b, c, d, a, k[1], 21, -2054922799); 559 a = ii(a, b, c, d, k[8], 6, 1873313359); 560 d = ii(d, a, b, c, k[15], 10, -30611744); 561 c = ii(c, d, a, b, k[6], 15, -1560198380); 562 b = ii(b, c, d, a, k[13], 21, 1309151649); 563 a = ii(a, b, c, d, k[4], 6, -145523070); 564 d = ii(d, a, b, c, k[11], 10, -1120210379); 565 c = ii(c, d, a, b, k[2], 15, 718787259); 566 b = ii(b, c, d, a, k[9], 21, -343485551); 567 x[0] = add32(a, x[0]); 568 x[1] = add32(b, x[1]); 569 x[2] = add32(c, x[2]); 570 x[3] = add32(d, x[3]); 571 } 572 573 function cmn(q, a, b, x, s, t) { 574 a = add32(add32(a, q), add32(x, t)); 575 return add32(a << s | a >>> 32 - s, b); 576 } 577 578 function ff(a, b, c, d, x, s, t) { 579 return cmn(b & c | ~b & d, a, b, x, s, t); 580 } 581 582 function gg(a, b, c, d, x, s, t) { 583 return cmn(b & d | c & ~d, a, b, x, s, t); 584 } 585 586 function hh(a, b, c, d, x, s, t) { 587 return cmn(b ^ c ^ d, a, b, x, s, t); 588 } 589 590 function ii(a, b, c, d, x, s, t) { 591 return cmn(c ^ (b | ~d), a, b, x, s, t); 592 } 593 594 function md51(s) { 595 // txt = ''; 596 var n = s.length, 597 state = [1732584193, -271733879, -1732584194, 271733878], 598 i; 599 600 for (i = 64; i <= s.length; i += 64) { 601 md5cycle(state, md5blk(s.substring(i - 64, i))); 602 } 603 604 s = s.substring(i - 64); 605 var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 606 607 for (i = 0; i < s.length; i++) { 608 tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3); 609 } 610 611 tail[i >> 2] |= 0x80 << (i % 4 << 3); 612 613 if (i > 55) { 614 md5cycle(state, tail); 615 616 for (i = 0; i < 16; i++) { 617 tail[i] = 0; 618 } 619 } 620 621 tail[14] = n * 8; 622 md5cycle(state, tail); 623 return state; 624 } 625 /* there needs to be support for Unicode here, 626 * unless we pretend that we can redefine the MD-5 627 * algorithm for multi-byte characters (perhaps 628 * by adding every four 16-bit characters and 629 * shortening the sum to 32 bits). Otherwise 630 * I suggest performing MD-5 as if every character 631 * was two bytes--e.g., 0040 0025 = @%--but then 632 * how will an ordinary MD-5 sum be matched? 633 * There is no way to standardize text to something 634 * like UTF-8 before transformation; speed cost is 635 * utterly prohibitive. The JavaScript standard 636 * itself needs to look at this: it should start 637 * providing access to strings as preformed UTF-8 638 * 8-bit unsigned value arrays. 639 */ 640 641 642 function md5blk(s) { 643 /* I figured global was faster. */ 644 var md5blks = [], 645 i; 646 /* Andy King said do it this way. */ 647 648 for (i = 0; i < 64; i += 4) { 649 md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24); 650 } 651 652 return md5blks; 653 } 654 655 var hex_chr = "0123456789abcdef".split(""); 656 657 function rhex(n) { 658 var s = "", 659 j = 0; 660 661 for (; j < 4; j++) { 662 s += hex_chr[n >> j * 8 + 4 & 0x0f] + hex_chr[n >> j * 8 & 0x0f]; 663 } 664 665 return s; 666 } 667 668 function hex(x) { 669 for (var i = 0; i < x.length; i++) { 670 x[i] = rhex(x[i]); 671 } 672 673 return x.join(""); 674 } // Converts a 4-byte number to byte string 675 676 677 function singleToByteString(n) { 678 return String.fromCharCode((n & 0xff) >> 0, (n & 0xff00) >> 8, (n & 0xff0000) >> 16, (n & 0xff000000) >> 24); 679 } // Converts an array of numbers to a byte string 680 681 682 function toByteString(x) { 683 return x.map(singleToByteString).join(""); 684 } // Returns the MD5 hash as a byte string 685 686 687 function md5Bin(s) { 688 return toByteString(md51(s)); 689 } // Returns MD5 hash as a hex string 690 691 692 function md5(s) { 693 return hex(md51(s)); 694 } 695 696 var md5Check = md5("hello") != "5d41402abc4b2a76b9719d911017c592"; 697 698 function add32(a, b) { 699 if (md5Check) { 700 /* if the md5Check does not match 701 the expected value, we're dealing 702 with an old browser and need 703 this function. */ 704 var lsw = (a & 0xffff) + (b & 0xffff), 705 msw = (a >> 16) + (b >> 16) + (lsw >> 16); 706 return msw << 16 | lsw & 0xffff; 707 } else { 708 /* this function is much faster, 709 so if possible we use it. Some IEs 710 are the only ones I know of that 711 need the idiotic second function, 712 generated by an if clause. */ 713 return a + b & 0xffffffff; 714 } 715 } 716 717 /** 718 * @license 719 * FPDF is released under a permissive license: there is no usage restriction. 720 * You may embed it freely in your application (commercial or not), with or 721 * without modifications. 722 * 723 * Reference: http://www.fpdf.org/en/script/script37.php 724 */ 725 function repeat(str, num) { 726 return new Array(num + 1).join(str); 727 } 728 /** 729 * Converts a byte string to a hex string 730 * 731 * @name rc4 732 * @function 733 * @param {string} key Byte string of encryption key 734 * @param {string} data Byte string of data to be encrypted 735 * @returns {string} Encrypted string 736 */ 737 738 739 function rc4(key, data) { 740 var lastKey, lastState; 741 742 if (key !== lastKey) { 743 var k = repeat(key, (256 / key.length >> 0) + 1); 744 var state = []; 745 746 for (var i = 0; i < 256; i++) { 747 state[i] = i; 748 } 749 750 var j = 0; 751 752 for (var i = 0; i < 256; i++) { 753 var t = state[i]; 754 j = (j + t + k.charCodeAt(i)) % 256; 755 state[i] = state[j]; 756 state[j] = t; 757 } 758 759 lastKey = key; 760 lastState = state; 761 } else { 762 state = lastState; 763 } 764 765 var length = data.length; 766 var a = 0; 767 var b = 0; 768 var out = ""; 769 770 for (var i = 0; i < length; i++) { 771 a = (a + 1) % 256; 772 t = state[a]; 773 b = (b + t) % 256; 774 state[a] = state[b]; 775 state[b] = t; 776 k = state[(state[a] + state[b]) % 256]; 777 out += String.fromCharCode(data.charCodeAt(i) ^ k); 778 } 779 780 return out; 781 } 782 783 /** 784 * @license 785 * Licensed under the MIT License. 786 * http://opensource.org/licenses/mit-license 787 * Author: Owen Leong (@owenl131) 788 * Date: 15 Oct 2020 789 * References: 790 * https://www.cs.cmu.edu/~dst/Adobe/Gallery/anon21jul01-pdf-encryption.txt 791 * https://github.com/foliojs/pdfkit/blob/master/lib/security.js 792 * http://www.fpdf.org/en/script/script37.php 793 */ 794 var permissionOptions = { 795 print: 4, 796 modify: 8, 797 copy: 16, 798 "annot-forms": 32 799 }; 800 /** 801 * Initializes encryption settings 802 * 803 * @name constructor 804 * @function 805 * @param {Array} permissions Permissions allowed for user, "print", "modify", "copy" and "annot-forms". 806 * @param {String} userPassword Permissions apply to this user. Leaving this empty means the document 807 * is not password protected but viewer has the above permissions. 808 * @param {String} ownerPassword Owner has full functionalities to the file. 809 * @param {String} fileId As hex string, should be same as the file ID in the trailer. 810 * @example 811 * var security = new PDFSecurity(["print"]) 812 */ 813 814 function PDFSecurity(permissions, userPassword, ownerPassword, fileId) { 815 this.v = 1; // algorithm 1, future work can add in more recent encryption schemes 816 817 this.r = 2; // revision 2 818 // set flags for what functionalities the user can access 819 820 var protection = 192; 821 permissions.forEach(function (perm) { 822 if (typeof permissionOptions.perm !== "undefined") { 823 throw new Error("Invalid permission: " + perm); 824 } 825 826 protection += permissionOptions[perm]; 827 }); // padding is used to pad the passwords to 32 bytes, also is hashed and stored in the final PDF 828 829 this.padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08" + "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A"; 830 var paddedUserPassword = (userPassword + this.padding).substr(0, 32); 831 var paddedOwnerPassword = (ownerPassword + this.padding).substr(0, 32); 832 this.O = this.processOwnerPassword(paddedUserPassword, paddedOwnerPassword); 833 this.P = -((protection ^ 255) + 1); 834 this.encryptionKey = md5Bin(paddedUserPassword + this.O + this.lsbFirstWord(this.P) + this.hexToBytes(fileId)).substr(0, 5); 835 this.U = rc4(this.encryptionKey, this.padding); 836 } 837 /** 838 * Breaks down a 4-byte number into its individual bytes, with the least significant bit first 839 * 840 * @name lsbFirstWord 841 * @function 842 * @param {number} data 32-bit number 843 * @returns {Array} 844 */ 845 846 847 PDFSecurity.prototype.lsbFirstWord = function (data) { 848 return String.fromCharCode(data >> 0 & 0xff, data >> 8 & 0xff, data >> 16 & 0xff, data >> 24 & 0xff); 849 }; 850 /** 851 * Converts a byte string to a hex string 852 * 853 * @name toHexString 854 * @function 855 * @param {String} byteString Byte string 856 * @returns {String} 857 */ 858 859 860 PDFSecurity.prototype.toHexString = function (byteString) { 861 return byteString.split("").map(function (byte) { 862 return ("0" + (byte.charCodeAt(0) & 0xff).toString(16)).slice(-2); 863 }).join(""); 864 }; 865 /** 866 * Converts a hex string to a byte string 867 * 868 * @name hexToBytes 869 * @function 870 * @param {String} hex Hex string 871 * @returns {String} 872 */ 873 874 875 PDFSecurity.prototype.hexToBytes = function (hex) { 876 for (var bytes = [], c = 0; c < hex.length; c += 2) { 877 bytes.push(String.fromCharCode(parseInt(hex.substr(c, 2), 16))); 878 } 879 880 return bytes.join(""); 881 }; 882 /** 883 * Computes the 'O' field in the encryption dictionary 884 * 885 * @name processOwnerPassword 886 * @function 887 * @param {String} paddedUserPassword Byte string of padded user password 888 * @param {String} paddedOwnerPassword Byte string of padded owner password 889 * @returns {String} 890 */ 891 892 893 PDFSecurity.prototype.processOwnerPassword = function (paddedUserPassword, paddedOwnerPassword) { 894 var key = md5Bin(paddedOwnerPassword).substr(0, 5); 895 return rc4(key, paddedUserPassword); 896 }; 897 /** 898 * Returns an encryptor function which can take in a byte string and returns the encrypted version 899 * 900 * @name encryptor 901 * @function 902 * @param {number} objectId 903 * @param {number} generation Not sure what this is for, you can set it to 0 904 * @returns {Function} 905 * @example 906 * out("stream"); 907 * encryptor = security.encryptor(object.id, 0); 908 * out(encryptor(data)); 909 * out("endstream"); 910 */ 911 912 913 PDFSecurity.prototype.encryptor = function (objectId, generation) { 914 var key = md5Bin(this.encryptionKey + String.fromCharCode(objectId & 0xff, objectId >> 8 & 0xff, objectId >> 16 & 0xff, generation & 0xff, generation >> 8 & 0xff)).substr(0, 10); 915 return function (data) { 916 return rc4(key, data); 917 }; 918 }; 919 920 /** 921 * Convert string to `PDF Name Object`. 922 * Detail: PDF Reference 1.3 - Chapter 3.2.4 Name Object 923 * @param str 924 */ 925 function toPDFName(str) { 926 // eslint-disable-next-line no-control-regex 927 if (/[^\u0000-\u00ff]/.test(str)) { 928 // non ascii string 929 throw new Error("Invalid PDF Name Object: " + str + ", Only accept ASCII characters."); 930 } 931 932 var result = "", 933 strLength = str.length; 934 935 for (var i = 0; i < strLength; i++) { 936 var charCode = str.charCodeAt(i); 937 938 if (charCode < 0x21 || charCode === 0x23 939 /* # */ 940 || charCode === 0x25 941 /* % */ 942 || charCode === 0x28 943 /* ( */ 944 || charCode === 0x29 945 /* ) */ 946 || charCode === 0x2f 947 /* / */ 948 || charCode === 0x3c 949 /* < */ 950 || charCode === 0x3e 951 /* > */ 952 || charCode === 0x5b 953 /* [ */ 954 || charCode === 0x5d 955 /* ] */ 956 || charCode === 0x7b 957 /* { */ 958 || charCode === 0x7d 959 /* } */ 960 || charCode > 0x7e) { 961 // Char CharCode hexStr paddingHexStr Result 962 // "\t" 9 9 09 #09 963 // " " 32 20 20 #20 964 // "©" 169 a9 a9 #a9 965 var hexStr = charCode.toString(16), 966 paddingHexStr = ("0" + hexStr).slice(-2); 967 result += "#" + paddingHexStr; 968 } else { 969 // Other ASCII printable characters between 0x21 <= X <= 0x7e 970 result += str[i]; 971 } 972 } 973 974 return result; 975 } 976 977 /** 978 * jsPDF's Internal PubSub Implementation. 979 * Backward compatible rewritten on 2014 by 980 * Diego Casorran, https://github.com/diegocr 981 * 982 * @class 983 * @name PubSub 984 * @ignore 985 */ 986 987 function PubSub(context) { 988 if (_typeof(context) !== "object") { 989 throw new Error("Invalid Context passed to initialize PubSub (jsPDF-module)"); 990 } 991 992 var topics = {}; 993 994 this.subscribe = function (topic, callback, once) { 995 once = once || false; 996 997 if (typeof topic !== "string" || typeof callback !== "function" || typeof once !== "boolean") { 998 throw new Error("Invalid arguments passed to PubSub.subscribe (jsPDF-module)"); 999 } 1000 1001 if (!topics.hasOwnProperty(topic)) { 1002 topics[topic] = {}; 1003 } 1004 1005 var token = Math.random().toString(35); 1006 topics[topic][token] = [callback, !!once]; 1007 return token; 1008 }; 1009 1010 this.unsubscribe = function (token) { 1011 for (var topic in topics) { 1012 if (topics[topic][token]) { 1013 delete topics[topic][token]; 1014 1015 if (Object.keys(topics[topic]).length === 0) { 1016 delete topics[topic]; 1017 } 1018 1019 return true; 1020 } 1021 } 1022 1023 return false; 1024 }; 1025 1026 this.publish = function (topic) { 1027 if (topics.hasOwnProperty(topic)) { 1028 var args = Array.prototype.slice.call(arguments, 1), 1029 tokens = []; 1030 1031 for (var token in topics[topic]) { 1032 var sub = topics[topic][token]; 1033 1034 try { 1035 sub[0].apply(context, args); 1036 } catch (ex) { 1037 if (globalObject.console) { 1038 console.error("jsPDF PubSub Error", ex.message, ex); 1039 } 1040 } 1041 1042 if (sub[1]) tokens.push(token); 1043 } 1044 1045 if (tokens.length) tokens.forEach(this.unsubscribe); 1046 } 1047 }; 1048 1049 this.getTopics = function () { 1050 return topics; 1051 }; 1052 } 1053 1054 function GState(parameters) { 1055 if (!(this instanceof GState)) { 1056 return new GState(parameters); 1057 } 1058 /** 1059 * @name GState#opacity 1060 * @type {any} 1061 */ 1062 1063 /** 1064 * @name GState#stroke-opacity 1065 * @type {any} 1066 */ 1067 1068 1069 var supported = "opacity,stroke-opacity".split(","); 1070 1071 for (var p in parameters) { 1072 if (parameters.hasOwnProperty(p) && supported.indexOf(p) >= 0) { 1073 this[p] = parameters[p]; 1074 } 1075 } 1076 /** 1077 * @name GState#id 1078 * @type {string} 1079 */ 1080 1081 1082 this.id = ""; // set by addGState() 1083 1084 /** 1085 * @name GState#objectNumber 1086 * @type {number} 1087 */ 1088 1089 this.objectNumber = -1; // will be set by putGState() 1090 } 1091 1092 GState.prototype.equals = function equals(other) { 1093 var ignore = "id,objectNumber,equals"; 1094 var p; 1095 if (!other || _typeof(other) !== _typeof(this)) return false; 1096 var count = 0; 1097 1098 for (p in this) { 1099 if (ignore.indexOf(p) >= 0) continue; 1100 if (this.hasOwnProperty(p) && !other.hasOwnProperty(p)) return false; 1101 if (this[p] !== other[p]) return false; 1102 count++; 1103 } 1104 1105 for (p in other) { 1106 if (other.hasOwnProperty(p) && ignore.indexOf(p) < 0) count--; 1107 } 1108 1109 return count === 0; 1110 }; 1111 1112 function Pattern(gState, matrix) { 1113 this.gState = gState; 1114 this.matrix = matrix; 1115 this.id = ""; // set by addPattern() 1116 1117 this.objectNumber = -1; // will be set by putPattern() 1118 } 1119 1120 function ShadingPattern(type, coords, colors, gState, matrix) { 1121 if (!(this instanceof ShadingPattern)) { 1122 return new ShadingPattern(type, coords, colors, gState, matrix); 1123 } // see putPattern() for information how they are realized 1124 1125 1126 this.type = type === "axial" ? 2 : 3; 1127 this.coords = coords; 1128 this.colors = colors; 1129 Pattern.call(this, gState, matrix); 1130 } 1131 1132 function TilingPattern(boundingBox, xStep, yStep, gState, matrix) { 1133 if (!(this instanceof TilingPattern)) { 1134 return new TilingPattern(boundingBox, xStep, yStep, gState, matrix); 1135 } 1136 1137 this.boundingBox = boundingBox; 1138 this.xStep = xStep; 1139 this.yStep = yStep; 1140 this.stream = ""; // set by endTilingPattern(); 1141 1142 this.cloneIndex = 0; 1143 Pattern.call(this, gState, matrix); 1144 } 1145 /** 1146 * Creates new jsPDF document object instance. 1147 * @name jsPDF 1148 * @class 1149 * @param {Object} [options] - Collection of settings initializing the jsPDF-instance 1150 * @param {string} [options.orientation=portrait] - Orientation of the first page. Possible values are "portrait" or "landscape" (or shortcuts "p" or "l").<br /> 1151 * @param {string} [options.unit=mm] Measurement unit (base unit) to be used when coordinates are specified.<br /> 1152 * Possible values are "pt" (points), "mm", "cm", "in", "px", "pc", "em" or "ex". Note that in order to get the correct scaling for "px" 1153 * units, you need to enable the hotfix "px_scaling" by setting options.hotfixes = ["px_scaling"]. 1154 * @param {string/Array} [options.format=a4] The format of the first page. Can be:<ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br /> 1155 * Default is "a4". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array, e.g. [595.28, 841.89] 1156 * @param {boolean} [options.putOnlyUsedFonts=false] Only put fonts into the PDF, which were used. 1157 * @param {boolean} [options.compress=false] Compress the generated PDF. 1158 * @param {number} [options.precision=16] Precision of the element-positions. 1159 * @param {number} [options.userUnit=1.0] Not to be confused with the base unit. Please inform yourself before you use it. 1160 * @param {string[]} [options.hotfixes] An array of strings to enable hotfixes such as correct pixel scaling. 1161 * @param {Object} [options.encryption] 1162 * @param {string} [options.encryption.userPassword] Password for the user bound by the given permissions list. 1163 * @param {string} [options.encryption.ownerPassword] Both userPassword and ownerPassword should be set for proper authentication. 1164 * @param {string[]} [options.encryption.userPermissions] Array of permissions "print", "modify", "copy", "annot-forms", accessible by the user. 1165 * @param {number|"smart"} [options.floatPrecision=16] 1166 * @returns {jsPDF} jsPDF-instance 1167 * @description 1168 * ``` 1169 * { 1170 * orientation: 'p', 1171 * unit: 'mm', 1172 * format: 'a4', 1173 * putOnlyUsedFonts:true, 1174 * floatPrecision: 16 // or "smart", default is 16 1175 * } 1176 * ``` 1177 * 1178 * @constructor 1179 */ 1180 1181 1182 function jsPDF(options) { 1183 var orientation = typeof arguments[0] === "string" ? arguments[0] : "p"; 1184 var unit = arguments[1]; 1185 var format = arguments[2]; 1186 var compressPdf = arguments[3]; 1187 var filters = []; 1188 var userUnit = 1.0; 1189 var precision; 1190 var floatPrecision = 16; 1191 var defaultPathOperation = "S"; 1192 var encryptionOptions = null; 1193 options = options || {}; 1194 1195 if (_typeof(options) === "object") { 1196 orientation = options.orientation; 1197 unit = options.unit || unit; 1198 format = options.format || format; 1199 compressPdf = options.compress || options.compressPdf || compressPdf; 1200 encryptionOptions = options.encryption || null; 1201 1202 if (encryptionOptions !== null) { 1203 encryptionOptions.userPassword = encryptionOptions.userPassword || ""; 1204 encryptionOptions.ownerPassword = encryptionOptions.ownerPassword || ""; 1205 encryptionOptions.userPermissions = encryptionOptions.userPermissions || []; 1206 } 1207 1208 userUnit = typeof options.userUnit === "number" ? Math.abs(options.userUnit) : 1.0; 1209 1210 if (typeof options.precision !== "undefined") { 1211 precision = options.precision; 1212 } 1213 1214 if (typeof options.floatPrecision !== "undefined") { 1215 floatPrecision = options.floatPrecision; 1216 } 1217 1218 defaultPathOperation = options.defaultPathOperation || "S"; 1219 } 1220 1221 filters = options.filters || (compressPdf === true ? ["FlateEncode"] : filters); 1222 unit = unit || "mm"; 1223 orientation = ("" + (orientation || "P")).toLowerCase(); 1224 var putOnlyUsedFonts = options.putOnlyUsedFonts || false; 1225 var usedFonts = {}; 1226 var API = { 1227 internal: {}, 1228 __private__: {} 1229 }; 1230 API.__private__.PubSub = PubSub; 1231 var pdfVersion = "1.3"; 1232 1233 var getPdfVersion = API.__private__.getPdfVersion = function () { 1234 return pdfVersion; 1235 }; 1236 1237 API.__private__.setPdfVersion = function (value) { 1238 pdfVersion = value; 1239 }; // Size in pt of various paper formats 1240 1241 1242 var pageFormats = { 1243 a0: [2383.94, 3370.39], 1244 a1: [1683.78, 2383.94], 1245 a2: [1190.55, 1683.78], 1246 a3: [841.89, 1190.55], 1247 a4: [595.28, 841.89], 1248 a5: [419.53, 595.28], 1249 a6: [297.64, 419.53], 1250 a7: [209.76, 297.64], 1251 a8: [147.4, 209.76], 1252 a9: [104.88, 147.4], 1253 a10: [73.7, 104.88], 1254 b0: [2834.65, 4008.19], 1255 b1: [2004.09, 2834.65], 1256 b2: [1417.32, 2004.09], 1257 b3: [1000.63, 1417.32], 1258 b4: [708.66, 1000.63], 1259 b5: [498.9, 708.66], 1260 b6: [354.33, 498.9], 1261 b7: [249.45, 354.33], 1262 b8: [175.75, 249.45], 1263 b9: [124.72, 175.75], 1264 b10: [87.87, 124.72], 1265 c0: [2599.37, 3676.54], 1266 c1: [1836.85, 2599.37], 1267 c2: [1298.27, 1836.85], 1268 c3: [918.43, 1298.27], 1269 c4: [649.13, 918.43], 1270 c5: [459.21, 649.13], 1271 c6: [323.15, 459.21], 1272 c7: [229.61, 323.15], 1273 c8: [161.57, 229.61], 1274 c9: [113.39, 161.57], 1275 c10: [79.37, 113.39], 1276 dl: [311.81, 623.62], 1277 letter: [612, 792], 1278 "government-letter": [576, 756], 1279 legal: [612, 1008], 1280 "junior-legal": [576, 360], 1281 ledger: [1224, 792], 1282 tabloid: [792, 1224], 1283 "credit-card": [153, 243] 1284 }; 1285 1286 API.__private__.getPageFormats = function () { 1287 return pageFormats; 1288 }; 1289 1290 var getPageFormat = API.__private__.getPageFormat = function (value) { 1291 return pageFormats[value]; 1292 }; 1293 1294 format = format || "a4"; 1295 var ApiMode = { 1296 COMPAT: "compat", 1297 ADVANCED: "advanced" 1298 }; 1299 var apiMode = ApiMode.COMPAT; 1300 1301 function advancedAPI() { 1302 // prepend global change of basis matrix 1303 // (Now, instead of converting every coordinate to the pdf coordinate system, we apply a matrix 1304 // that does this job for us (however, texts, images and similar objects must be drawn bottom up)) 1305 this.saveGraphicsState(); 1306 out(new Matrix(scaleFactor, 0, 0, -scaleFactor, 0, getPageHeight() * scaleFactor).toString() + " cm"); 1307 this.setFontSize(this.getFontSize() / scaleFactor); // The default in MrRio's implementation is "S" (stroke), whereas the default in the yWorks implementation 1308 // was "n" (none). Although this has nothing to do with transforms, we should use the API switch here. 1309 1310 defaultPathOperation = "n"; 1311 apiMode = ApiMode.ADVANCED; 1312 } 1313 1314 function compatAPI() { 1315 this.restoreGraphicsState(); 1316 defaultPathOperation = "S"; 1317 apiMode = ApiMode.COMPAT; 1318 } 1319 /** 1320 * @function combineFontStyleAndFontWeight 1321 * @param {string} fontStyle Fontstyle or variant. Example: "italic". 1322 * @param {number | string} fontWeight Weight of the Font. Example: "normal" | 400 1323 * @returns {string} 1324 * @private 1325 */ 1326 1327 1328 var combineFontStyleAndFontWeight = API.__private__.combineFontStyleAndFontWeight = function (fontStyle, fontWeight) { 1329 if (fontStyle == "bold" && fontWeight == "normal" || fontStyle == "bold" && fontWeight == 400 || fontStyle == "normal" && fontWeight == "italic" || fontStyle == "bold" && fontWeight == "italic") { 1330 throw new Error("Invalid Combination of fontweight and fontstyle"); 1331 } 1332 1333 if (fontWeight) { 1334 fontStyle = fontWeight == 400 || fontWeight === "normal" ? fontStyle === "italic" ? "italic" : "normal" : (fontWeight == 700 || fontWeight === "bold") && fontStyle === "normal" ? "bold" : (fontWeight == 700 ? "bold" : fontWeight) + "" + fontStyle; 1335 } 1336 1337 return fontStyle; 1338 }; 1339 /** 1340 * @callback ApiSwitchBody 1341 * @param {jsPDF} pdf 1342 */ 1343 1344 /** 1345 * For compatibility reasons jsPDF offers two API modes which differ in the way they convert between the the usual 1346 * screen coordinates and the PDF coordinate system. 1347 * - "compat": Offers full compatibility across all plugins but does not allow arbitrary transforms 1348 * - "advanced": Allows arbitrary transforms and more advanced features like pattern fills. Some plugins might 1349 * not support this mode, though. 1350 * Initial mode is "compat". 1351 * 1352 * You can either provide a callback to the body argument, which means that jsPDF will automatically switch back to 1353 * the original API mode afterwards; or you can omit the callback and switch back manually using {@link compatAPI}. 1354 * 1355 * Note, that the calls to {@link saveGraphicsState} and {@link restoreGraphicsState} need to be balanced within the 1356 * callback or between calls of this method and its counterpart {@link compatAPI}. Calls to {@link beginFormObject} 1357 * or {@link beginTilingPattern} need to be closed by their counterparts before switching back to "compat" API mode. 1358 * 1359 * @param {ApiSwitchBody=} body When provided, this callback will be called after the API mode has been switched. 1360 * The API mode will be switched back automatically afterwards. 1361 * @returns {jsPDF} 1362 * @memberof jsPDF# 1363 * @name advancedAPI 1364 */ 1365 1366 1367 API.advancedAPI = function (body) { 1368 var doSwitch = apiMode === ApiMode.COMPAT; 1369 1370 if (doSwitch) { 1371 advancedAPI.call(this); 1372 } 1373 1374 if (typeof body !== "function") { 1375 return this; 1376 } 1377 1378 body(this); 1379 1380 if (doSwitch) { 1381 compatAPI.call(this); 1382 } 1383 1384 return this; 1385 }; 1386 /** 1387 * Switches to "compat" API mode. See {@link advancedAPI} for more details. 1388 * 1389 * @param {ApiSwitchBody=} body When provided, this callback will be called after the API mode has been switched. 1390 * The API mode will be switched back automatically afterwards. 1391 * @return {jsPDF} 1392 * @memberof jsPDF# 1393 * @name compatApi 1394 */ 1395 1396 1397 API.compatAPI = function (body) { 1398 var doSwitch = apiMode === ApiMode.ADVANCED; 1399 1400 if (doSwitch) { 1401 compatAPI.call(this); 1402 } 1403 1404 if (typeof body !== "function") { 1405 return this; 1406 } 1407 1408 body(this); 1409 1410 if (doSwitch) { 1411 advancedAPI.call(this); 1412 } 1413 1414 return this; 1415 }; 1416 /** 1417 * @return {boolean} True iff the current API mode is "advanced". See {@link advancedAPI}. 1418 * @memberof jsPDF# 1419 * @name isAdvancedAPI 1420 */ 1421 1422 1423 API.isAdvancedAPI = function () { 1424 return apiMode === ApiMode.ADVANCED; 1425 }; 1426 1427 var advancedApiModeTrap = function advancedApiModeTrap(methodName) { 1428 if (apiMode !== ApiMode.ADVANCED) { 1429 throw new Error(methodName + " is only available in 'advanced' API mode. " + "You need to call advancedAPI() first."); 1430 } 1431 }; 1432 1433 var roundToPrecision = API.roundToPrecision = API.__private__.roundToPrecision = function (number, parmPrecision) { 1434 var tmpPrecision = precision || parmPrecision; 1435 1436 if (isNaN(number) || isNaN(tmpPrecision)) { 1437 throw new Error("Invalid argument passed to jsPDF.roundToPrecision"); 1438 } 1439 1440 return number.toFixed(tmpPrecision).replace(/0+$/, ""); 1441 }; // high precision float 1442 1443 1444 var hpf; 1445 1446 if (typeof floatPrecision === "number") { 1447 hpf = API.hpf = API.__private__.hpf = function (number) { 1448 if (isNaN(number)) { 1449 throw new Error("Invalid argument passed to jsPDF.hpf"); 1450 } 1451 1452 return roundToPrecision(number, floatPrecision); 1453 }; 1454 } else if (floatPrecision === "smart") { 1455 hpf = API.hpf = API.__private__.hpf = function (number) { 1456 if (isNaN(number)) { 1457 throw new Error("Invalid argument passed to jsPDF.hpf"); 1458 } 1459 1460 if (number > -1 && number < 1) { 1461 return roundToPrecision(number, 16); 1462 } else { 1463 return roundToPrecision(number, 5); 1464 } 1465 }; 1466 } else { 1467 hpf = API.hpf = API.__private__.hpf = function (number) { 1468 if (isNaN(number)) { 1469 throw new Error("Invalid argument passed to jsPDF.hpf"); 1470 } 1471 1472 return roundToPrecision(number, 16); 1473 }; 1474 } 1475 1476 var f2 = API.f2 = API.__private__.f2 = function (number) { 1477 if (isNaN(number)) { 1478 throw new Error("Invalid argument passed to jsPDF.f2"); 1479 } 1480 1481 return roundToPrecision(number, 2); 1482 }; 1483 1484 var f3 = API.__private__.f3 = function (number) { 1485 if (isNaN(number)) { 1486 throw new Error("Invalid argument passed to jsPDF.f3"); 1487 } 1488 1489 return roundToPrecision(number, 3); 1490 }; 1491 1492 var scale = API.scale = API.__private__.scale = function (number) { 1493 if (isNaN(number)) { 1494 throw new Error("Invalid argument passed to jsPDF.scale"); 1495 } 1496 1497 if (apiMode === ApiMode.COMPAT) { 1498 return number * scaleFactor; 1499 } else if (apiMode === ApiMode.ADVANCED) { 1500 return number; 1501 } 1502 }; 1503 1504 var transformY = function transformY(y) { 1505 if (apiMode === ApiMode.COMPAT) { 1506 return getPageHeight() - y; 1507 } else if (apiMode === ApiMode.ADVANCED) { 1508 return y; 1509 } 1510 }; 1511 1512 var transformScaleY = function transformScaleY(y) { 1513 return scale(transformY(y)); 1514 }; 1515 /** 1516 * @name setPrecision 1517 * @memberof jsPDF# 1518 * @function 1519 * @instance 1520 * @param {string} precision 1521 * @returns {jsPDF} 1522 */ 1523 1524 1525 API.__private__.setPrecision = API.setPrecision = function (value) { 1526 if (typeof parseInt(value, 10) === "number") { 1527 precision = parseInt(value, 10); 1528 } 1529 }; 1530 1531 var fileId = "00000000000000000000000000000000"; 1532 1533 var getFileId = API.__private__.getFileId = function () { 1534 return fileId; 1535 }; 1536 1537 var setFileId = API.__private__.setFileId = function (value) { 1538 if (typeof value !== "undefined" && /^[a-fA-F0-9]{32}$/.test(value)) { 1539 fileId = value.toUpperCase(); 1540 } else { 1541 fileId = fileId.split("").map(function () { 1542 return "ABCDEF0123456789".charAt(Math.floor(Math.random() * 16)); 1543 }).join(""); 1544 } 1545 1546 if (encryptionOptions !== null) { 1547 encryption = new PDFSecurity(encryptionOptions.userPermissions, encryptionOptions.userPassword, encryptionOptions.ownerPassword, fileId); 1548 } 1549 1550 return fileId; 1551 }; 1552 /** 1553 * @name setFileId 1554 * @memberof jsPDF# 1555 * @function 1556 * @instance 1557 * @param {string} value GUID. 1558 * @returns {jsPDF} 1559 */ 1560 1561 1562 API.setFileId = function (value) { 1563 setFileId(value); 1564 return this; 1565 }; 1566 /** 1567 * @name getFileId 1568 * @memberof jsPDF# 1569 * @function 1570 * @instance 1571 * 1572 * @returns {string} GUID. 1573 */ 1574 1575 1576 API.getFileId = function () { 1577 return getFileId(); 1578 }; 1579 1580 var creationDate; 1581 1582 var convertDateToPDFDate = API.__private__.convertDateToPDFDate = function (parmDate) { 1583 var result = ""; 1584 var tzoffset = parmDate.getTimezoneOffset(), 1585 tzsign = tzoffset < 0 ? "+" : "-", 1586 tzhour = Math.floor(Math.abs(tzoffset / 60)), 1587 tzmin = Math.abs(tzoffset % 60), 1588 timeZoneString = [tzsign, padd2(tzhour), "'", padd2(tzmin), "'"].join(""); 1589 result = ["D:", parmDate.getFullYear(), padd2(parmDate.getMonth() + 1), padd2(parmDate.getDate()), padd2(parmDate.getHours()), padd2(parmDate.getMinutes()), padd2(parmDate.getSeconds()), timeZoneString].join(""); 1590 return result; 1591 }; 1592 1593 var convertPDFDateToDate = API.__private__.convertPDFDateToDate = function (parmPDFDate) { 1594 var year = parseInt(parmPDFDate.substr(2, 4), 10); 1595 var month = parseInt(parmPDFDate.substr(6, 2), 10) - 1; 1596 var date = parseInt(parmPDFDate.substr(8, 2), 10); 1597 var hour = parseInt(parmPDFDate.substr(10, 2), 10); 1598 var minutes = parseInt(parmPDFDate.substr(12, 2), 10); 1599 var seconds = parseInt(parmPDFDate.substr(14, 2), 10); // var timeZoneHour = parseInt(parmPDFDate.substr(16, 2), 10); 1600 // var timeZoneMinutes = parseInt(parmPDFDate.substr(20, 2), 10); 1601 1602 var resultingDate = new Date(year, month, date, hour, minutes, seconds, 0); 1603 return resultingDate; 1604 }; 1605 1606 var setCreationDate = API.__private__.setCreationDate = function (date) { 1607 var tmpCreationDateString; 1608 var regexPDFCreationDate = /^D:(20[0-2][0-9]|203[0-7]|19[7-9][0-9])(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])(0[0-9]|1[0-9]|2[0-3])(0[0-9]|[1-5][0-9])(0[0-9]|[1-5][0-9])(\+0[0-9]|\+1[0-4]|-0[0-9]|-1[0-1])'(0[0-9]|[1-5][0-9])'?$/; 1609 1610 if (typeof date === "undefined") { 1611 date = new Date(); 1612 } 1613 1614 if (date instanceof Date) { 1615 tmpCreationDateString = convertDateToPDFDate(date); 1616 } else if (regexPDFCreationDate.test(date)) { 1617 tmpCreationDateString = date; 1618 } else { 1619 throw new Error("Invalid argument passed to jsPDF.setCreationDate"); 1620 } 1621 1622 creationDate = tmpCreationDateString; 1623 return creationDate; 1624 }; 1625 1626 var getCreationDate = API.__private__.getCreationDate = function (type) { 1627 var result = creationDate; 1628 1629 if (type === "jsDate") { 1630 result = convertPDFDateToDate(creationDate); 1631 } 1632 1633 return result; 1634 }; 1635 /** 1636 * @name setCreationDate 1637 * @memberof jsPDF# 1638 * @function 1639 * @instance 1640 * @param {Object} date 1641 * @returns {jsPDF} 1642 */ 1643 1644 1645 API.setCreationDate = function (date) { 1646 setCreationDate(date); 1647 return this; 1648 }; 1649 /** 1650 * @name getCreationDate 1651 * @memberof jsPDF# 1652 * @function 1653 * @instance 1654 * @param {Object} type 1655 * @returns {Object} 1656 */ 1657 1658 1659 API.getCreationDate = function (type) { 1660 return getCreationDate(type); 1661 }; 1662 1663 var padd2 = API.__private__.padd2 = function (number) { 1664 return ("0" + parseInt(number)).slice(-2); 1665 }; 1666 1667 var padd2Hex = API.__private__.padd2Hex = function (hexString) { 1668 hexString = hexString.toString(); 1669 return ("00" + hexString).substr(hexString.length); 1670 }; 1671 1672 var objectNumber = 0; // 'n' Current object number 1673 1674 var offsets = []; // List of offsets. Activated and reset by buildDocument(). Pupulated by various calls buildDocument makes. 1675 1676 var content = []; 1677 var contentLength = 0; 1678 var additionalObjects = []; 1679 var pages = []; 1680 var currentPage; 1681 var hasCustomDestination = false; 1682 var outputDestination = content; 1683 1684 var resetDocument = function resetDocument() { 1685 //reset fields relevant for objectNumber generation and xref. 1686 objectNumber = 0; 1687 contentLength = 0; 1688 content = []; 1689 offsets = []; 1690 additionalObjects = []; 1691 rootDictionaryObjId = newObjectDeferred(); 1692 resourceDictionaryObjId = newObjectDeferred(); 1693 }; 1694 1695 API.__private__.setCustomOutputDestination = function (destination) { 1696 hasCustomDestination = true; 1697 outputDestination = destination; 1698 }; 1699 1700 var setOutputDestination = function setOutputDestination(destination) { 1701 if (!hasCustomDestination) { 1702 outputDestination = destination; 1703 } 1704 }; 1705 1706 API.__private__.resetCustomOutputDestination = function () { 1707 hasCustomDestination = false; 1708 outputDestination = content; 1709 }; 1710 1711 var out = API.__private__.out = function (string) { 1712 string = string.toString(); 1713 contentLength += string.length + 1; 1714 outputDestination.push(string); 1715 return outputDestination; 1716 }; 1717 1718 var write = API.__private__.write = function (value) { 1719 return out(arguments.length === 1 ? value.toString() : Array.prototype.join.call(arguments, " ")); 1720 }; 1721 1722 var getArrayBuffer = API.__private__.getArrayBuffer = function (data) { 1723 var len = data.length, 1724 ab = new ArrayBuffer(len), 1725 u8 = new Uint8Array(ab); 1726 1727 while (len--) { 1728 u8[len] = data.charCodeAt(len); 1729 } 1730 1731 return ab; 1732 }; 1733 1734 var standardFonts = [["Helvetica", "helvetica", "normal", "WinAnsiEncoding"], ["Helvetica-Bold", "helvetica", "bold", "WinAnsiEncoding"], ["Helvetica-Oblique", "helvetica", "italic", "WinAnsiEncoding"], ["Helvetica-BoldOblique", "helvetica", "bolditalic", "WinAnsiEncoding"], ["Courier", "courier", "normal", "WinAnsiEncoding"], ["Courier-Bold", "courier", "bold", "WinAnsiEncoding"], ["Courier-Oblique", "courier", "italic", "WinAnsiEncoding"], ["Courier-BoldOblique", "courier", "bolditalic", "WinAnsiEncoding"], ["Times-Roman", "times", "normal", "WinAnsiEncoding"], ["Times-Bold", "times", "bold", "WinAnsiEncoding"], ["Times-Italic", "times", "italic", "WinAnsiEncoding"], ["Times-BoldItalic", "times", "bolditalic", "WinAnsiEncoding"], ["ZapfDingbats", "zapfdingbats", "normal", null], ["Symbol", "symbol", "normal", null]]; 1735 1736 API.__private__.getStandardFonts = function () { 1737 return standardFonts; 1738 }; 1739 1740 var activeFontSize = options.fontSize || 16; 1741 /** 1742 * Sets font size for upcoming text elements. 1743 * 1744 * @param {number} size Font size in points. 1745 * @function 1746 * @instance 1747 * @returns {jsPDF} 1748 * @memberof jsPDF# 1749 * @name setFontSize 1750 */ 1751 1752 API.__private__.setFontSize = API.setFontSize = function (size) { 1753 if (apiMode === ApiMode.ADVANCED) { 1754 activeFontSize = size / scaleFactor; 1755 } else { 1756 activeFontSize = size; 1757 } 1758 1759 return this; 1760 }; 1761 /** 1762 * Gets the fontsize for upcoming text elements. 1763 * 1764 * @function 1765 * @instance 1766 * @returns {number} 1767 * @memberof jsPDF# 1768 * @name getFontSize 1769 */ 1770 1771 1772 var getFontSize = API.__private__.getFontSize = API.getFontSize = function () { 1773 if (apiMode === ApiMode.COMPAT) { 1774 return activeFontSize; 1775 } else { 1776 return activeFontSize * scaleFactor; 1777 } 1778 }; 1779 1780 var R2L = options.R2L || false; 1781 /** 1782 * Set value of R2L functionality. 1783 * 1784 * @param {boolean} value 1785 * @function 1786 * @instance 1787 * @returns {jsPDF} jsPDF-instance 1788 * @memberof jsPDF# 1789 * @name setR2L 1790 */ 1791 1792 API.__private__.setR2L = API.setR2L = function (value) { 1793 R2L = value; 1794 return this; 1795 }; 1796 /** 1797 * Get value of R2L functionality. 1798 * 1799 * @function 1800 * @instance 1801 * @returns {boolean} jsPDF-instance 1802 * @memberof jsPDF# 1803 * @name getR2L 1804 */ 1805 1806 1807 API.__private__.getR2L = API.getR2L = function () { 1808 return R2L; 1809 }; 1810 1811 var zoomMode; // default: 1; 1812 1813 var setZoomMode = API.__private__.setZoomMode = function (zoom) { 1814 var validZoomModes = [undefined, null, "fullwidth", "fullheight", "fullpage", "original"]; 1815 1816 if (/^(?:\d+\.\d*|\d*\.\d+|\d+)%$/.test(zoom)) { 1817 zoomMode = zoom; 1818 } else if (!isNaN(zoom)) { 1819 zoomMode = parseInt(zoom, 10); 1820 } else if (validZoomModes.indexOf(zoom) !== -1) { 1821 zoomMode = zoom; 1822 } else { 1823 throw new Error('zoom must be Integer (e.g. 2), a percentage Value (e.g. 300%) or fullwidth, fullheight, fullpage, original. "' + zoom + '" is not recognized.'); 1824 } 1825 }; 1826 1827 API.__private__.getZoomMode = function () { 1828 return zoomMode; 1829 }; 1830 1831 var pageMode; // default: 'UseOutlines'; 1832 1833 var setPageMode = API.__private__.setPageMode = function (pmode) { 1834 var validPageModes = [undefined, null, "UseNone", "UseOutlines", "UseThumbs", "FullScreen"]; 1835 1836 if (validPageModes.indexOf(pmode) == -1) { 1837 throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. "' + pmode + '" is not recognized.'); 1838 } 1839 1840 pageMode = pmode; 1841 }; 1842 1843 API.__private__.getPageMode = function () { 1844 return pageMode; 1845 }; 1846 1847 var layoutMode; // default: 'continuous'; 1848 1849 var setLayoutMode = API.__private__.setLayoutMode = function (layout) { 1850 var validLayoutModes = [undefined, null, "continuous", "single", "twoleft", "tworight", "two"]; 1851 1852 if (validLayoutModes.indexOf(layout) == -1) { 1853 throw new Error('Layout mode must be one of continuous, single, twoleft, tworight. "' + layout + '" is not recognized.'); 1854 } 1855 1856 layoutMode = layout; 1857 }; 1858 1859 API.__private__.getLayoutMode = function () { 1860 return layoutMode; 1861 }; 1862 /** 1863 * Set the display mode options of the page like zoom and layout. 1864 * 1865 * @name setDisplayMode 1866 * @memberof jsPDF# 1867 * @function 1868 * @instance 1869 * @param {integer|String} zoom You can pass an integer or percentage as 1870 * a string. 2 will scale the document up 2x, '200%' will scale up by the 1871 * same amount. You can also set it to 'fullwidth', 'fullheight', 1872 * 'fullpage', or 'original'. 1873 * 1874 * Only certain PDF readers support this, such as Adobe Acrobat. 1875 * 1876 * @param {string} layout Layout mode can be: 'continuous' - this is the 1877 * default continuous scroll. 'single' - the single page mode only shows one 1878 * page at a time. 'twoleft' - two column left mode, first page starts on 1879 * the left, and 'tworight' - pages are laid out in two columns, with the 1880 * first page on the right. This would be used for books. 1881 * @param {string} pmode 'UseOutlines' - it shows the 1882 * outline of the document on the left. 'UseThumbs' - shows thumbnails along 1883 * the left. 'FullScreen' - prompts the user to enter fullscreen mode. 1884 * 1885 * @returns {jsPDF} 1886 */ 1887 1888 1889 API.__private__.setDisplayMode = API.setDisplayMode = function (zoom, layout, pmode) { 1890 setZoomMode(zoom); 1891 setLayoutMode(layout); 1892 setPageMode(pmode); 1893 return this; 1894 }; 1895 1896 var documentProperties = { 1897 title: "", 1898 subject: "", 1899 author: "", 1900 keywords: "", 1901 creator: "" 1902 }; 1903 1904 API.__private__.getDocumentProperty = function (key) { 1905 if (Object.keys(documentProperties).indexOf(key) === -1) { 1906 throw new Error("Invalid argument passed to jsPDF.getDocumentProperty"); 1907 } 1908 1909 return documentProperties[key]; 1910 }; 1911 1912 API.__private__.getDocumentProperties = function () { 1913 return documentProperties; 1914 }; 1915 /** 1916 * Adds a properties to the PDF document. 1917 * 1918 * @param {Object} A property_name-to-property_value object structure. 1919 * @function 1920 * @instance 1921 * @returns {jsPDF} 1922 * @memberof jsPDF# 1923 * @name setDocumentProperties 1924 */ 1925 1926 1927 API.__private__.setDocumentProperties = API.setProperties = API.setDocumentProperties = function (properties) { 1928 // copying only those properties we can render. 1929 for (var property in documentProperties) { 1930 if (documentProperties.hasOwnProperty(property) && properties[property]) { 1931 documentProperties[property] = properties[property]; 1932 } 1933 } 1934 1935 return this; 1936 }; 1937 1938 API.__private__.setDocumentProperty = function (key, value) { 1939 if (Object.keys(documentProperties).indexOf(key) === -1) { 1940 throw new Error("Invalid arguments passed to jsPDF.setDocumentProperty"); 1941 } 1942 1943 return documentProperties[key] = value; 1944 }; 1945 1946 var fonts = {}; // collection of font objects, where key is fontKey - a dynamically created label for a given font. 1947 1948 var fontmap = {}; // mapping structure fontName > fontStyle > font key - performance layer. See addFont() 1949 1950 var activeFontKey; // will be string representing the KEY of the font as combination of fontName + fontStyle 1951 1952 var fontStateStack = []; // 1953 1954 var patterns = {}; // collection of pattern objects 1955 1956 var patternMap = {}; // see fonts 1957 1958 var gStates = {}; // collection of graphic state objects 1959 1960 var gStatesMap = {}; // see fonts 1961 1962 var activeGState = null; 1963 var scaleFactor; // Scale factor 1964 1965 var page = 0; 1966 var pagesContext = []; 1967 var events = new PubSub(API); 1968 var hotfixes = options.hotfixes || []; 1969 var renderTargets = {}; 1970 var renderTargetMap = {}; 1971 var renderTargetStack = []; 1972 var pageX; 1973 var pageY; 1974 var pageMatrix; // only used for FormObjects 1975 1976 /** 1977 * A matrix object for 2D homogenous transformations: <br> 1978 * | a b 0 | <br> 1979 * | c d 0 | <br> 1980 * | e f 1 | <br> 1981 * pdf multiplies matrices righthand: v' = v x m1 x m2 x ... 1982 * 1983 * @class 1984 * @name Matrix 1985 * @param {number} sx 1986 * @param {number} shy 1987 * @param {number} shx 1988 * @param {number} sy 1989 * @param {number} tx 1990 * @param {number} ty 1991 * @constructor 1992 */ 1993 1994 var Matrix = function Matrix(sx, shy, shx, sy, tx, ty) { 1995 if (!(this instanceof Matrix)) { 1996 return new Matrix(sx, shy, shx, sy, tx, ty); 1997 } 1998 1999 if (isNaN(sx)) sx = 1; 2000 if (isNaN(shy)) shy = 0; 2001 if (isNaN(shx)) shx = 0; 2002 if (isNaN(sy)) sy = 1; 2003 if (isNaN(tx)) tx = 0; 2004 if (isNaN(ty)) ty = 0; 2005 this._matrix = [sx, shy, shx, sy, tx, ty]; 2006 }; 2007 /** 2008 * @name sx 2009 * @memberof Matrix# 2010 */ 2011 2012 2013 Object.defineProperty(Matrix.prototype, "sx", { 2014 get: function get() { 2015 return this._matrix[0]; 2016 }, 2017 set: function set(value) { 2018 this._matrix[0] = value; 2019 } 2020 }); 2021 /** 2022 * @name shy 2023 * @memberof Matrix# 2024 */ 2025 2026 Object.defineProperty(Matrix.prototype, "shy", { 2027 get: function get() { 2028 return this._matrix[1]; 2029 }, 2030 set: function set(value) { 2031 this._matrix[1] = value; 2032 } 2033 }); 2034 /** 2035 * @name shx 2036 * @memberof Matrix# 2037 */ 2038 2039 Object.defineProperty(Matrix.prototype, "shx", { 2040 get: function get() { 2041 return this._matrix[2]; 2042 }, 2043 set: function set(value) { 2044 this._matrix[2] = value; 2045 } 2046 }); 2047 /** 2048 * @name sy 2049 * @memberof Matrix# 2050 */ 2051 2052 Object.defineProperty(Matrix.prototype, "sy", { 2053 get: function get() { 2054 return this._matrix[3]; 2055 }, 2056 set: function set(value) { 2057 this._matrix[3] = value; 2058 } 2059 }); 2060 /** 2061 * @name tx 2062 * @memberof Matrix# 2063 */ 2064 2065 Object.defineProperty(Matrix.prototype, "tx", { 2066 get: function get() { 2067 return this._matrix[4]; 2068 }, 2069 set: function set(value) { 2070 this._matrix[4] = value; 2071 } 2072 }); 2073 /** 2074 * @name ty 2075 * @memberof Matrix# 2076 */ 2077 2078 Object.defineProperty(Matrix.prototype, "ty", { 2079 get: function get() { 2080 return this._matrix[5]; 2081 }, 2082 set: function set(value) { 2083 this._matrix[5] = value; 2084 } 2085 }); 2086 Object.defineProperty(Matrix.prototype, "a", { 2087 get: function get() { 2088 return this._matrix[0]; 2089 }, 2090 set: function set(value) { 2091 this._matrix[0] = value; 2092 } 2093 }); 2094 Object.defineProperty(Matrix.prototype, "b", { 2095 get: function get() { 2096 return this._matrix[1]; 2097 }, 2098 set: function set(value) { 2099 this._matrix[1] = value; 2100 } 2101 }); 2102 Object.defineProperty(Matrix.prototype, "c", { 2103 get: function get() { 2104 return this._matrix[2]; 2105 }, 2106 set: function set(value) { 2107 this._matrix[2] = value; 2108 } 2109 }); 2110 Object.defineProperty(Matrix.prototype, "d", { 2111 get: function get() { 2112 return this._matrix[3]; 2113 }, 2114 set: function set(value) { 2115 this._matrix[3] = value; 2116 } 2117 }); 2118 Object.defineProperty(Matrix.prototype, "e", { 2119 get: function get() { 2120 return this._matrix[4]; 2121 }, 2122 set: function set(value) { 2123 this._matrix[4] = value; 2124 } 2125 }); 2126 Object.defineProperty(Matrix.prototype, "f", { 2127 get: function get() { 2128 return this._matrix[5]; 2129 }, 2130 set: function set(value) { 2131 this._matrix[5] = value; 2132 } 2133 }); 2134 /** 2135 * @name rotation 2136 * @memberof Matrix# 2137 */ 2138 2139 Object.defineProperty(Matrix.prototype, "rotation", { 2140 get: function get() { 2141 return Math.atan2(this.shx, this.sx); 2142 } 2143 }); 2144 /** 2145 * @name scaleX 2146 * @memberof Matrix# 2147 */ 2148 2149 Object.defineProperty(Matrix.prototype, "scaleX", { 2150 get: function get() { 2151 return this.decompose().scale.sx; 2152 } 2153 }); 2154 /** 2155 * @name scaleY 2156 * @memberof Matrix# 2157 */ 2158 2159 Object.defineProperty(Matrix.prototype, "scaleY", { 2160 get: function get() { 2161 return this.decompose().scale.sy; 2162 } 2163 }); 2164 /** 2165 * @name isIdentity 2166 * @memberof Matrix# 2167 */ 2168 2169 Object.defineProperty(Matrix.prototype, "isIdentity", { 2170 get: function get() { 2171 if (this.sx !== 1) { 2172 return false; 2173 } 2174 2175 if (this.shy !== 0) { 2176 return false; 2177 } 2178 2179 if (this.shx !== 0) { 2180 return false; 2181 } 2182 2183 if (this.sy !== 1) { 2184 return false; 2185 } 2186 2187 if (this.tx !== 0) { 2188 return false; 2189 } 2190 2191 if (this.ty !== 0) { 2192 return false; 2193 } 2194 2195 return true; 2196 } 2197 }); 2198 /** 2199 * Join the Matrix Values to a String 2200 * 2201 * @function join 2202 * @param {string} separator Specifies a string to separate each pair of adjacent elements of the array. The separator is converted to a string if necessary. If omitted, the array elements are separated with a comma (","). If separator is an empty string, all elements are joined without any characters in between them. 2203 * @returns {string} A string with all array elements joined. 2204 * @memberof Matrix# 2205 */ 2206 2207 Matrix.prototype.join = function (separator) { 2208 return [this.sx, this.shy, this.shx, this.sy, this.tx, this.ty].map(hpf).join(separator); 2209 }; 2210 /** 2211 * Multiply the matrix with given Matrix 2212 * 2213 * @function multiply 2214 * @param matrix 2215 * @returns {Matrix} 2216 * @memberof Matrix# 2217 */ 2218 2219 2220 Matrix.prototype.multiply = function (matrix) { 2221 var sx = matrix.sx * this.sx + matrix.shy * this.shx; 2222 var shy = matrix.sx * this.shy + matrix.shy * this.sy; 2223 var shx = matrix.shx * this.sx + matrix.sy * this.shx; 2224 var sy = matrix.shx * this.shy + matrix.sy * this.sy; 2225 var tx = matrix.tx * this.sx + matrix.ty * this.shx + this.tx; 2226 var ty = matrix.tx * this.shy + matrix.ty * this.sy + this.ty; 2227 return new Matrix(sx, shy, shx, sy, tx, ty); 2228 }; 2229 /** 2230 * @function decompose 2231 * @memberof Matrix# 2232 */ 2233 2234 2235 Matrix.prototype.decompose = function () { 2236 var a = this.sx; 2237 var b = this.shy; 2238 var c = this.shx; 2239 var d = this.sy; 2240 var e = this.tx; 2241 var f = this.ty; 2242 var scaleX = Math.sqrt(a * a + b * b); 2243 a /= scaleX; 2244 b /= scaleX; 2245 var shear = a * c + b * d; 2246 c -= a * shear; 2247 d -= b * shear; 2248 var scaleY = Math.sqrt(c * c + d * d); 2249 c /= scaleY; 2250 d /= scaleY; 2251 shear /= scaleY; 2252 2253 if (a * d < b * c) { 2254 a = -a; 2255 b = -b; 2256 shear = -shear; 2257 scaleX = -scaleX; 2258 } 2259 2260 return { 2261 scale: new Matrix(scaleX, 0, 0, scaleY, 0, 0), 2262 translate: new Matrix(1, 0, 0, 1, e, f), 2263 rotate: new Matrix(a, b, -b, a, 0, 0), 2264 skew: new Matrix(1, 0, shear, 1, 0, 0) 2265 }; 2266 }; 2267 /** 2268 * @function toString 2269 * @memberof Matrix# 2270 */ 2271 2272 2273 Matrix.prototype.toString = function (parmPrecision) { 2274 return this.join(" "); 2275 }; 2276 /** 2277 * @function inversed 2278 * @memberof Matrix# 2279 */ 2280 2281 2282 Matrix.prototype.inversed = function () { 2283 var a = this.sx, 2284 b = this.shy, 2285 c = this.shx, 2286 d = this.sy, 2287 e = this.tx, 2288 f = this.ty; 2289 var quot = 1 / (a * d - b * c); 2290 var aInv = d * quot; 2291 var bInv = -b * quot; 2292 var cInv = -c * quot; 2293 var dInv = a * quot; 2294 var eInv = -aInv * e - cInv * f; 2295 var fInv = -bInv * e - dInv * f; 2296 return new Matrix(aInv, bInv, cInv, dInv, eInv, fInv); 2297 }; 2298 /** 2299 * @function applyToPoint 2300 * @memberof Matrix# 2301 */ 2302 2303 2304 Matrix.prototype.applyToPoint = function (pt) { 2305 var x = pt.x * this.sx + pt.y * this.shx + this.tx; 2306 var y = pt.x * this.shy + pt.y * this.sy + this.ty; 2307 return new Point(x, y); 2308 }; 2309 /** 2310 * @function applyToRectangle 2311 * @memberof Matrix# 2312 */ 2313 2314 2315 Matrix.prototype.applyToRectangle = function (rect) { 2316 var pt1 = this.applyToPoint(rect); 2317 var pt2 = this.applyToPoint(new Point(rect.x + rect.w, rect.y + rect.h)); 2318 return new Rectangle(pt1.x, pt1.y, pt2.x - pt1.x, pt2.y - pt1.y); 2319 }; 2320 /** 2321 * Clone the Matrix 2322 * 2323 * @function clone 2324 * @memberof Matrix# 2325 * @name clone 2326 * @instance 2327 */ 2328 2329 2330 Matrix.prototype.clone = function () { 2331 var sx = this.sx; 2332 var shy = this.shy; 2333 var shx = this.shx; 2334 var sy = this.sy; 2335 var tx = this.tx; 2336 var ty = this.ty; 2337 return new Matrix(sx, shy, shx, sy, tx, ty); 2338 }; 2339 2340 API.Matrix = Matrix; 2341 /** 2342 * Multiplies two matrices. (see {@link Matrix}) 2343 * @param {Matrix} m1 2344 * @param {Matrix} m2 2345 * @memberof jsPDF# 2346 * @name matrixMult 2347 */ 2348 2349 var matrixMult = API.matrixMult = function (m1, m2) { 2350 return m2.multiply(m1); 2351 }; 2352 /** 2353 * The identity matrix (equivalent to new Matrix(1, 0, 0, 1, 0, 0)). 2354 * @type {Matrix} 2355 * @memberof! jsPDF# 2356 * @name identityMatrix 2357 */ 2358 2359 2360 var identityMatrix = new Matrix(1, 0, 0, 1, 0, 0); 2361 API.unitMatrix = API.identityMatrix = identityMatrix; 2362 /** 2363 * Adds a new pattern for later use. 2364 * @param {String} key The key by it can be referenced later. The keys must be unique! 2365 * @param {API.Pattern} pattern The pattern 2366 */ 2367 2368 var addPattern = function addPattern(key, pattern) { 2369 // only add it if it is not already present (the keys provided by the user must be unique!) 2370 if (patternMap[key]) return; 2371 var prefix = pattern instanceof ShadingPattern ? "Sh" : "P"; 2372 var patternKey = prefix + (Object.keys(patterns).length + 1).toString(10); 2373 pattern.id = patternKey; 2374 patternMap[key] = patternKey; 2375 patterns[patternKey] = pattern; 2376 events.publish("addPattern", pattern); 2377 }; 2378 /** 2379 * A pattern describing a shading pattern. 2380 * 2381 * Only available in "advanced" API mode. 2382 * 2383 * @param {String} type One of "axial" or "radial" 2384 * @param {Array<Number>} coords Either [x1, y1, x2, y2] for "axial" type describing the two interpolation points 2385 * or [x1, y1, r, x2, y2, r2] for "radial" describing inner and the outer circle. 2386 * @param {Array<Object>} colors An array of objects with the fields "offset" and "color". "offset" describes 2387 * the offset in parameter space [0, 1]. "color" is an array of length 3 describing RGB values in [0, 255]. 2388 * @param {GState=} gState An additional graphics state that gets applied to the pattern (optional). 2389 * @param {Matrix=} matrix A matrix that describes the transformation between the pattern coordinate system 2390 * and the use coordinate system (optional). 2391 * @constructor 2392 * @extends API.Pattern 2393 */ 2394 2395 2396 API.ShadingPattern = ShadingPattern; 2397 /** 2398 * A PDF Tiling pattern. 2399 * 2400 * Only available in "advanced" API mode. 2401 * 2402 * @param {Array.<Number>} boundingBox The bounding box at which one pattern cell gets clipped. 2403 * @param {Number} xStep Horizontal spacing between pattern cells. 2404 * @param {Number} yStep Vertical spacing between pattern cells. 2405 * @param {API.GState=} gState An additional graphics state that gets applied to the pattern (optional). 2406 * @param {Matrix=} matrix A matrix that describes the transformation between the pattern coordinate system 2407 * and the use coordinate system (optional). 2408 * @constructor 2409 * @extends API.Pattern 2410 */ 2411 2412 API.TilingPattern = TilingPattern; 2413 /** 2414 * Adds a new {@link API.ShadingPattern} for later use. Only available in "advanced" API mode. 2415 * @param {String} key 2416 * @param {Pattern} pattern 2417 * @function 2418 * @returns {jsPDF} 2419 * @memberof jsPDF# 2420 * @name addPattern 2421 */ 2422 2423 API.addShadingPattern = function (key, pattern) { 2424 advancedApiModeTrap("addShadingPattern()"); 2425 addPattern(key, pattern); 2426 return this; 2427 }; 2428 /** 2429 * Begins a new tiling pattern. All subsequent render calls are drawn to this pattern until {@link API.endTilingPattern} 2430 * gets called. Only available in "advanced" API mode. 2431 * @param {API.Pattern} pattern 2432 * @memberof jsPDF# 2433 * @name beginTilingPattern 2434 */ 2435 2436 2437 API.beginTilingPattern = function (pattern) { 2438 advancedApiModeTrap("beginTilingPattern()"); 2439 beginNewRenderTarget(pattern.boundingBox[0], pattern.boundingBox[1], pattern.boundingBox[2] - pattern.boundingBox[0], pattern.boundingBox[3] - pattern.boundingBox[1], pattern.matrix); 2440 }; 2441 /** 2442 * Ends a tiling pattern and sets the render target to the one active before {@link API.beginTilingPattern} has been called. 2443 * 2444 * Only available in "advanced" API mode. 2445 * 2446 * @param {string} key A unique key that is used to reference this pattern at later use. 2447 * @param {API.Pattern} pattern The pattern to end. 2448 * @memberof jsPDF# 2449 * @name endTilingPattern 2450 */ 2451 2452 2453 API.endTilingPattern = function (key, pattern) { 2454 advancedApiModeTrap("endTilingPattern()"); // retrieve the stream 2455 2456 pattern.stream = pages[currentPage].join("\n"); 2457 addPattern(key, pattern); 2458 events.publish("endTilingPattern", pattern); // restore state from stack 2459 2460 renderTargetStack.pop().restore(); 2461 }; 2462 2463 var newObject = API.__private__.newObject = function () { 2464 var oid = newObjectDeferred(); 2465 newObjectDeferredBegin(oid, true); 2466 return oid; 2467 }; // Does not output the object. The caller must call newObjectDeferredBegin(oid) before outputing any data 2468 2469 2470 var newObjectDeferred = API.__private__.newObjectDeferred = function () { 2471 objectNumber++; 2472 2473 offsets[objectNumber] = function () { 2474 return contentLength; 2475 }; 2476 2477 return objectNumber; 2478 }; 2479 2480 var newObjectDeferredBegin = function newObjectDeferredBegin(oid, doOutput) { 2481 doOutput = typeof doOutput === "boolean" ? doOutput : false; 2482 offsets[oid] = contentLength; 2483 2484 if (doOutput) { 2485 out(oid + " 0 obj"); 2486 } 2487 2488 return oid; 2489 }; // Does not output the object until after the pages have been output. 2490 // Returns an object containing the objectId and content. 2491 // All pages have been added so the object ID can be estimated to start right after. 2492 // This does not modify the current objectNumber; It must be updated after the newObjects are output. 2493 2494 2495 var newAdditionalObject = API.__private__.newAdditionalObject = function () { 2496 var objId = newObjectDeferred(); 2497 var obj = { 2498 objId: objId, 2499 content: "" 2500 }; 2501 additionalObjects.push(obj); 2502 return obj; 2503 }; 2504 2505 var rootDictionaryObjId = newObjectDeferred(); 2506 var resourceDictionaryObjId = newObjectDeferred(); ///////////////////// 2507 // Private functions 2508 ///////////////////// 2509 2510 var decodeColorString = API.__private__.decodeColorString = function (color) { 2511 var colorEncoded = color.split(" "); 2512 2513 if (colorEncoded.length === 2 && (colorEncoded[1] === "g" || colorEncoded[1] === "G")) { 2514 // convert grayscale value to rgb so that it can be converted to hex for consistency 2515 var floatVal = parseFloat(colorEncoded[0]); 2516 colorEncoded = [floatVal, floatVal, floatVal, "r"]; 2517 } else if (colorEncoded.length === 5 && (colorEncoded[4] === "k" || colorEncoded[4] === "K")) { 2518 // convert CMYK values to rbg so that it can be converted to hex for consistency 2519 var red = (1.0 - colorEncoded[0]) * (1.0 - colorEncoded[3]); 2520 var green = (1.0 - colorEncoded[1]) * (1.0 - colorEncoded[3]); 2521 var blue = (1.0 - colorEncoded[2]) * (1.0 - colorEncoded[3]); 2522 colorEncoded = [red, green, blue, "r"]; 2523 } 2524 2525 var colorAsRGB = "#"; 2526 2527 for (var i = 0; i < 3; i++) { 2528 colorAsRGB += ("0" + Math.floor(parseFloat(colorEncoded[i]) * 255).toString(16)).slice(-2); 2529 } 2530 2531 return colorAsRGB; 2532 }; 2533 2534 var encodeColorString = API.__private__.encodeColorString = function (options) { 2535 var color; 2536 2537 if (typeof options === "string") { 2538 options = { 2539 ch1: options 2540 }; 2541 } 2542 2543 var ch1 = options.ch1; 2544 var ch2 = options.ch2; 2545 var ch3 = options.ch3; 2546 var ch4 = options.ch4; 2547 var letterArray = options.pdfColorType === "draw" ? ["G", "RG", "K"] : ["g", "rg", "k"]; 2548 2549 if (typeof ch1 === "string" && ch1.charAt(0) !== "#") { 2550 var rgbColor = new RGBColor(ch1); 2551 2552 if (rgbColor.ok) { 2553 ch1 = rgbColor.toHex(); 2554 } else if (!/^\d*\.?\d*$/.test(ch1)) { 2555 throw new Error('Invalid color "' + ch1 + '" passed to jsPDF.encodeColorString.'); 2556 } 2557 } //convert short rgb to long form 2558 2559 2560 if (typeof ch1 === "string" && /^#[0-9A-Fa-f]{3}$/.test(ch1)) { 2561 ch1 = "#" + ch1[1] + ch1[1] + ch1[2] + ch1[2] + ch1[3] + ch1[3]; 2562 } 2563 2564 if (typeof ch1 === "string" && /^#[0-9A-Fa-f]{6}$/.test(ch1)) { 2565 var hex = parseInt(ch1.substr(1), 16); 2566 ch1 = hex >> 16 & 255; 2567 ch2 = hex >> 8 & 255; 2568 ch3 = hex & 255; 2569 } 2570 2571 if (typeof ch2 === "undefined" || typeof ch4 === "undefined" && ch1 === ch2 && ch2 === ch3) { 2572 // Gray color space. 2573 if (typeof ch1 === "string") { 2574 color = ch1 + " " + letterArray[0]; 2575 } else { 2576 switch (options.precision) { 2577 case 2: 2578 color = f2(ch1 / 255) + " " + letterArray[0]; 2579 break; 2580 2581 case 3: 2582 default: 2583 color = f3(ch1 / 255) + " " + letterArray[0]; 2584 } 2585 } 2586 } else if (typeof ch4 === "undefined" || _typeof(ch4) === "object") { 2587 // assume RGBA 2588 if (ch4 && !isNaN(ch4.a)) { 2589 //TODO Implement transparency. 2590 //WORKAROUND use white for now, if transparent, otherwise handle as rgb 2591 if (ch4.a === 0) { 2592 color = ["1.", "1.", "1.", letterArray[1]].join(" "); 2593 return color; 2594 } 2595 } // assume RGB 2596 2597 2598 if (typeof ch1 === "string") { 2599 color = [ch1, ch2, ch3, letterArray[1]].join(" "); 2600 } else { 2601 switch (options.precision) { 2602 case 2: 2603 color = [f2(ch1 / 255), f2(ch2 / 255), f2(ch3 / 255), letterArray[1]].join(" "); 2604 break; 2605 2606 default: 2607 case 3: 2608 color = [f3(ch1 / 255), f3(ch2 / 255), f3(ch3 / 255), letterArray[1]].join(" "); 2609 } 2610 } 2611 } else { 2612 // assume CMYK 2613 if (typeof ch1 === "string") { 2614 color = [ch1, ch2, ch3, ch4, letterArray[2]].join(" "); 2615 } else { 2616 switch (options.precision) { 2617 case 2: 2618 color = [f2(ch1), f2(ch2), f2(ch3), f2(ch4), letterArray[2]].join(" "); 2619 break; 2620 2621 case 3: 2622 default: 2623 color = [f3(ch1), f3(ch2), f3(ch3), f3(ch4), letterArray[2]].join(" "); 2624 } 2625 } 2626 } 2627 2628 return color; 2629 }; 2630 2631 var getFilters = API.__private__.getFilters = function () { 2632 return filters; 2633 }; 2634 2635 var putStream = API.__private__.putStream = function (options) { 2636 options = options || {}; 2637 var data = options.data || ""; 2638 var filters = options.filters || getFilters(); 2639 var alreadyAppliedFilters = options.alreadyAppliedFilters || []; 2640 var addLength1 = options.addLength1 || false; 2641 var valueOfLength1 = data.length; 2642 var objectId = options.objectId; 2643 2644 var encryptor = function encryptor(data) { 2645 return data; 2646 }; 2647 2648 if (encryptionOptions !== null && typeof objectId == "undefined") { 2649 throw new Error("ObjectId must be passed to putStream for file encryption"); 2650 } 2651 2652 if (encryptionOptions !== null) { 2653 encryptor = encryption.encryptor(objectId, 0); 2654 } 2655 2656 var processedData = {}; 2657 2658 if (filters === true) { 2659 filters = ["FlateEncode"]; 2660 } 2661 2662 var keyValues = options.additionalKeyValues || []; 2663 2664 if (typeof jsPDF.API.processDataByFilters !== "undefined") { 2665 processedData = jsPDF.API.processDataByFilters(data, filters); 2666 } else { 2667 processedData = { 2668 data: data, 2669 reverseChain: [] 2670 }; 2671 } 2672 2673 var filterAsString = processedData.reverseChain + (Array.isArray(alreadyAppliedFilters) ? alreadyAppliedFilters.join(" ") : alreadyAppliedFilters.toString()); 2674 2675 if (processedData.data.length !== 0) { 2676 keyValues.push({ 2677 key: "Length", 2678 value: processedData.data.length 2679 }); 2680 2681 if (addLength1 === true) { 2682 keyValues.push({ 2683 key: "Length1", 2684 value: valueOfLength1 2685 }); 2686 } 2687 } 2688 2689 if (filterAsString.length != 0) { 2690 if (filterAsString.split("/").length - 1 === 1) { 2691 keyValues.push({ 2692 key: "Filter", 2693 value: filterAsString 2694 }); 2695 } else { 2696 keyValues.push({ 2697 key: "Filter", 2698 value: "[" + filterAsString + "]" 2699 }); 2700 2701 for (var j = 0; j < keyValues.length; j += 1) { 2702 if (keyValues[j].key === "DecodeParms") { 2703 var decodeParmsArray = []; 2704 2705 for (var i = 0; i < processedData.reverseChain.split("/").length - 1; i += 1) { 2706 decodeParmsArray.push("null"); 2707 } 2708 2709 decodeParmsArray.push(keyValues[j].value); 2710 keyValues[j].value = "[" + decodeParmsArray.join(" ") + "]"; 2711 } 2712 } 2713 } 2714 } 2715 2716 out("<<"); 2717 2718 for (var k = 0; k < keyValues.length; k++) { 2719 out("/" + keyValues[k].key + " " + keyValues[k].value); 2720 } 2721 2722 out(">>"); 2723 2724 if (processedData.data.length !== 0) { 2725 out("stream"); 2726 out(encryptor(processedData.data)); 2727 out("endstream"); 2728 } 2729 }; 2730 2731 var putPage = API.__private__.putPage = function (page) { 2732 var pageNumber = page.number; 2733 var data = page.data; 2734 var pageObjectNumber = page.objId; 2735 var pageContentsObjId = page.contentsObjId; 2736 newObjectDeferredBegin(pageObjectNumber, true); 2737 out("<</Type /Page"); 2738 out("/Parent " + page.rootDictionaryObjId + " 0 R"); 2739 out("/Resources " + page.resourceDictionaryObjId + " 0 R"); 2740 out("/MediaBox [" + parseFloat(hpf(page.mediaBox.bottomLeftX)) + " " + parseFloat(hpf(page.mediaBox.bottomLeftY)) + " " + hpf(page.mediaBox.topRightX) + " " + hpf(page.mediaBox.topRightY) + "]"); 2741 2742 if (page.cropBox !== null) { 2743 out("/CropBox [" + hpf(page.cropBox.bottomLeftX) + " " + hpf(page.cropBox.bottomLeftY) + " " + hpf(page.cropBox.topRightX) + " " + hpf(page.cropBox.topRightY) + "]"); 2744 } 2745 2746 if (page.bleedBox !== null) { 2747 out("/BleedBox [" + hpf(page.bleedBox.bottomLeftX) + " " + hpf(page.bleedBox.bottomLeftY) + " " + hpf(page.bleedBox.topRightX) + " " + hpf(page.bleedBox.topRightY) + "]"); 2748 } 2749 2750 if (page.trimBox !== null) { 2751 out("/TrimBox [" + hpf(page.trimBox.bottomLeftX) + " " + hpf(page.trimBox.bottomLeftY) + " " + hpf(page.trimBox.topRightX) + " " + hpf(page.trimBox.topRightY) + "]"); 2752 } 2753 2754 if (page.artBox !== null) { 2755 out("/ArtBox [" + hpf(page.artBox.bottomLeftX) + " " + hpf(page.artBox.bottomLeftY) + " " + hpf(page.artBox.topRightX) + " " + hpf(page.artBox.topRightY) + "]"); 2756 } 2757 2758 if (typeof page.userUnit === "number" && page.userUnit !== 1.0) { 2759 out("/UserUnit " + page.userUnit); 2760 } 2761 2762 events.publish("putPage", { 2763 objId: pageObjectNumber, 2764 pageContext: pagesContext[pageNumber], 2765 pageNumber: pageNumber, 2766 page: data 2767 }); 2768 out("/Contents " + pageContentsObjId + " 0 R"); 2769 out(">>"); 2770 out("endobj"); // Page content 2771 2772 var pageContent = data.join("\n"); 2773 2774 if (apiMode === ApiMode.ADVANCED) { 2775 // if the user forgot to switch back to COMPAT mode, we must balance the graphics stack again 2776 pageContent += "\nQ"; 2777 } 2778 2779 newObjectDeferredBegin(pageContentsObjId, true); 2780 putStream({ 2781 data: pageContent, 2782 filters: getFilters(), 2783 objectId: pageContentsObjId 2784 }); 2785 out("endobj"); 2786 return pageObjectNumber; 2787 }; 2788 2789 var putPages = API.__private__.putPages = function () { 2790 var n, 2791 i, 2792 pageObjectNumbers = []; 2793 2794 for (n = 1; n <= page; n++) { 2795 pagesContext[n].objId = newObjectDeferred(); 2796 pagesContext[n].contentsObjId = newObjectDeferred(); 2797 } 2798 2799 for (n = 1; n <= page; n++) { 2800 pageObjectNumbers.push(putPage({ 2801 number: n, 2802 data: pages[n], 2803 objId: pagesContext[n].objId, 2804 contentsObjId: pagesContext[n].contentsObjId, 2805 mediaBox: pagesContext[n].mediaBox, 2806 cropBox: pagesContext[n].cropBox, 2807 bleedBox: pagesContext[n].bleedBox, 2808 trimBox: pagesContext[n].trimBox, 2809 artBox: pagesContext[n].artBox, 2810 userUnit: pagesContext[n].userUnit, 2811 rootDictionaryObjId: rootDictionaryObjId, 2812 resourceDictionaryObjId: resourceDictionaryObjId 2813 })); 2814 } 2815 2816 newObjectDeferredBegin(rootDictionaryObjId, true); 2817 out("<</Type /Pages"); 2818 var kids = "/Kids ["; 2819 2820 for (i = 0; i < page; i++) { 2821 kids += pageObjectNumbers[i] + " 0 R "; 2822 } 2823 2824 out(kids + "]"); 2825 out("/Count " + page); 2826 out(">>"); 2827 out("endobj"); 2828 events.publish("postPutPages"); 2829 }; 2830 2831 var putFont = function putFont(font) { 2832 events.publish("putFont", { 2833 font: font, 2834 out: out, 2835 newObject: newObject, 2836 putStream: putStream 2837 }); 2838 2839 if (font.isAlreadyPutted !== true) { 2840 font.objectNumber = newObject(); 2841 out("<<"); 2842 out("/Type /Font"); 2843 out("/BaseFont /" + toPDFName(font.postScriptName)); 2844 out("/Subtype /Type1"); 2845 2846 if (typeof font.encoding === "string") { 2847 out("/Encoding /" + font.encoding); 2848 } 2849 2850 out("/FirstChar 32"); 2851 out("/LastChar 255"); 2852 out(">>"); 2853 out("endobj"); 2854 } 2855 }; 2856 2857 var putFonts = function putFonts() { 2858 for (var fontKey in fonts) { 2859 if (fonts.hasOwnProperty(fontKey)) { 2860 if (putOnlyUsedFonts === false || putOnlyUsedFonts === true && usedFonts.hasOwnProperty(fontKey)) { 2861 putFont(fonts[fontKey]); 2862 } 2863 } 2864 } 2865 }; 2866 2867 var putXObject = function putXObject(xObject) { 2868 xObject.objectNumber = newObject(); 2869 var options = []; 2870 options.push({ 2871 key: "Type", 2872 value: "/XObject" 2873 }); 2874 options.push({ 2875 key: "Subtype", 2876 value: "/Form" 2877 }); 2878 options.push({ 2879 key: "BBox", 2880 value: "[" + [hpf(xObject.x), hpf(xObject.y), hpf(xObject.x + xObject.width), hpf(xObject.y + xObject.height)].join(" ") + "]" 2881 }); 2882 options.push({ 2883 key: "Matrix", 2884 value: "[" + xObject.matrix.toString() + "]" 2885 }); // TODO: /Resources 2886 2887 var stream = xObject.pages[1].join("\n"); 2888 putStream({ 2889 data: stream, 2890 additionalKeyValues: options, 2891 objectId: xObject.objectNumber 2892 }); 2893 out("endobj"); 2894 }; 2895 2896 var putXObjects = function putXObjects() { 2897 for (var xObjectKey in renderTargets) { 2898 if (renderTargets.hasOwnProperty(xObjectKey)) { 2899 putXObject(renderTargets[xObjectKey]); 2900 } 2901 } 2902 }; 2903 2904 var interpolateAndEncodeRGBStream = function interpolateAndEncodeRGBStream(colors, numberSamples) { 2905 var tValues = []; 2906 var t; 2907 var dT = 1.0 / (numberSamples - 1); 2908 2909 for (t = 0.0; t < 1.0; t += dT) { 2910 tValues.push(t); 2911 } 2912 2913 tValues.push(1.0); // add first and last control point if not present 2914 2915 if (colors[0].offset != 0.0) { 2916 var c0 = { 2917 offset: 0.0, 2918 color: colors[0].color 2919 }; 2920 colors.unshift(c0); 2921 } 2922 2923 if (colors[colors.length - 1].offset != 1.0) { 2924 var c1 = { 2925 offset: 1.0, 2926 color: colors[colors.length - 1].color 2927 }; 2928 colors.push(c1); 2929 } 2930 2931 var out = ""; 2932 var index = 0; 2933 2934 for (var i = 0; i < tValues.length; i++) { 2935 t = tValues[i]; 2936 2937 while (t > colors[index + 1].offset) { 2938 index++; 2939 } 2940 2941 var a = colors[index].offset; 2942 var b = colors[index + 1].offset; 2943 var d = (t - a) / (b - a); 2944 var aColor = colors[index].color; 2945 var bColor = colors[index + 1].color; 2946 out += padd2Hex(Math.round((1 - d) * aColor[0] + d * bColor[0]).toString(16)) + padd2Hex(Math.round((1 - d) * aColor[1] + d * bColor[1]).toString(16)) + padd2Hex(Math.round((1 - d) * aColor[2] + d * bColor[2]).toString(16)); 2947 } 2948 2949 return out.trim(); 2950 }; 2951 2952 var putShadingPattern = function putShadingPattern(pattern, numberSamples) { 2953 /* 2954 Axial patterns shade between the two points specified in coords, radial patterns between the inner 2955 and outer circle. 2956 The user can specify an array (colors) that maps t-Values in [0, 1] to RGB colors. These are now 2957 interpolated to equidistant samples and written to pdf as a sample (type 0) function. 2958 */ 2959 // The number of color samples that should be used to describe the shading. 2960 // The higher, the more accurate the gradient will be. 2961 numberSamples || (numberSamples = 21); 2962 var funcObjectNumber = newObject(); 2963 var stream = interpolateAndEncodeRGBStream(pattern.colors, numberSamples); 2964 var options = []; 2965 options.push({ 2966 key: "FunctionType", 2967 value: "0" 2968 }); 2969 options.push({ 2970 key: "Domain", 2971 value: "[0.0 1.0]" 2972 }); 2973 options.push({ 2974 key: "Size", 2975 value: "[" + numberSamples + "]" 2976 }); 2977 options.push({ 2978 key: "BitsPerSample", 2979 value: "8" 2980 }); 2981 options.push({ 2982 key: "Range", 2983 value: "[0.0 1.0 0.0 1.0 0.0 1.0]" 2984 }); 2985 options.push({ 2986 key: "Decode", 2987 value: "[0.0 1.0 0.0 1.0 0.0 1.0]" 2988 }); 2989 putStream({ 2990 data: stream, 2991 additionalKeyValues: options, 2992 alreadyAppliedFilters: ["/ASCIIHexDecode"], 2993 objectId: funcObjectNumber 2994 }); 2995 out("endobj"); 2996 pattern.objectNumber = newObject(); 2997 out("<< /ShadingType " + pattern.type); 2998 out("/ColorSpace /DeviceRGB"); 2999 var coords = "/Coords [" + hpf(parseFloat(pattern.coords[0])) + " " + // x1 3000 hpf(parseFloat(pattern.coords[1])) + " "; // y1 3001 3002 if (pattern.type === 2) { 3003 // axial 3004 coords += hpf(parseFloat(pattern.coords[2])) + " " + // x2 3005 hpf(parseFloat(pattern.coords[3])); // y2 3006 } else { 3007 // radial 3008 coords += hpf(parseFloat(pattern.coords[2])) + " " + // r1 3009 hpf(parseFloat(pattern.coords[3])) + " " + // x2 3010 hpf(parseFloat(pattern.coords[4])) + " " + // y2 3011 hpf(parseFloat(pattern.coords[5])); // r2 3012 } 3013 3014 coords += "]"; 3015 out(coords); 3016 3017 if (pattern.matrix) { 3018 out("/Matrix [" + pattern.matrix.toString() + "]"); 3019 } 3020 3021 out("/Function " + funcObjectNumber + " 0 R"); 3022 out("/Extend [true true]"); 3023 out(">>"); 3024 out("endobj"); 3025 }; 3026 3027 var putTilingPattern = function putTilingPattern(pattern, deferredResourceDictionaryIds) { 3028 var resourcesObjectId = newObjectDeferred(); 3029 var patternObjectId = newObject(); 3030 deferredResourceDictionaryIds.push({ 3031 resourcesOid: resourcesObjectId, 3032 objectOid: patternObjectId 3033 }); 3034 pattern.objectNumber = patternObjectId; 3035 var options = []; 3036 options.push({ 3037 key: "Type", 3038 value: "/Pattern" 3039 }); 3040 options.push({ 3041 key: "PatternType", 3042 value: "1" 3043 }); // tiling pattern 3044 3045 options.push({ 3046 key: "PaintType", 3047 value: "1" 3048 }); // colored tiling pattern 3049 3050 options.push({ 3051 key: "TilingType", 3052 value: "1" 3053 }); // constant spacing 3054 3055 options.push({ 3056 key: "BBox", 3057 value: "[" + pattern.boundingBox.map(hpf).join(" ") + "]" 3058 }); 3059 options.push({ 3060 key: "XStep", 3061 value: hpf(pattern.xStep) 3062 }); 3063 options.push({ 3064 key: "YStep", 3065 value: hpf(pattern.yStep) 3066 }); 3067 options.push({ 3068 key: "Resources", 3069 value: resourcesObjectId + " 0 R" 3070 }); 3071 3072 if (pattern.matrix) { 3073 options.push({ 3074 key: "Matrix", 3075 value: "[" + pattern.matrix.toString() + "]" 3076 }); 3077 } 3078 3079 putStream({ 3080 data: pattern.stream, 3081 additionalKeyValues: options, 3082 objectId: pattern.objectNumber 3083 }); 3084 out("endobj"); 3085 }; 3086 3087 var putPatterns = function putPatterns(deferredResourceDictionaryIds) { 3088 var patternKey; 3089 3090 for (patternKey in patterns) { 3091 if (patterns.hasOwnProperty(patternKey)) { 3092 if (patterns[patternKey] instanceof ShadingPattern) { 3093 putShadingPattern(patterns[patternKey]); 3094 } else if (patterns[patternKey] instanceof TilingPattern) { 3095 putTilingPattern(patterns[patternKey], deferredResourceDictionaryIds); 3096 } 3097 } 3098 } 3099 }; 3100 3101 var putGState = function putGState(gState) { 3102 gState.objectNumber = newObject(); 3103 out("<<"); 3104 3105 for (var p in gState) { 3106 switch (p) { 3107 case "opacity": 3108 out("/ca " + f2(gState[p])); 3109 break; 3110 3111 case "stroke-opacity": 3112 out("/CA " + f2(gState[p])); 3113 break; 3114 } 3115 } 3116 3117 out(">>"); 3118 out("endobj"); 3119 }; 3120 3121 var putGStates = function putGStates() { 3122 var gStateKey; 3123 3124 for (gStateKey in gStates) { 3125 if (gStates.hasOwnProperty(gStateKey)) { 3126 putGState(gStates[gStateKey]); 3127 } 3128 } 3129 }; 3130 3131 var putXobjectDict = function putXobjectDict() { 3132 out("/XObject <<"); 3133 3134 for (var xObjectKey in renderTargets) { 3135 if (renderTargets.hasOwnProperty(xObjectKey) && renderTargets[xObjectKey].objectNumber >= 0) { 3136 out("/" + xObjectKey + " " + renderTargets[xObjectKey].objectNumber + " 0 R"); 3137 } 3138 } // Loop through images, or other data objects 3139 3140 3141 events.publish("putXobjectDict"); 3142 out(">>"); 3143 }; 3144 3145 var putEncryptionDict = function putEncryptionDict() { 3146 encryption.oid = newObject(); 3147 out("<<"); 3148 out("/Filter /Standard"); 3149 out("/V " + encryption.v); 3150 out("/R " + encryption.r); 3151 out("/U <" + encryption.toHexString(encryption.U) + ">"); 3152 out("/O <" + encryption.toHexString(encryption.O) + ">"); 3153 out("/P " + encryption.P); 3154 out(">>"); 3155 out("endobj"); 3156 }; 3157 3158 var putFontDict = function putFontDict() { 3159 out("/Font <<"); 3160 3161 for (var fontKey in fonts) { 3162 if (fonts.hasOwnProperty(fontKey)) { 3163 if (putOnlyUsedFonts === false || putOnlyUsedFonts === true && usedFonts.hasOwnProperty(fontKey)) { 3164 out("/" + fontKey + " " + fonts[fontKey].objectNumber + " 0 R"); 3165 } 3166 } 3167 } 3168 3169 out(">>"); 3170 }; 3171 3172 var putShadingPatternDict = function putShadingPatternDict() { 3173 if (Object.keys(patterns).length > 0) { 3174 out("/Shading <<"); 3175 3176 for (var patternKey in patterns) { 3177 if (patterns.hasOwnProperty(patternKey) && patterns[patternKey] instanceof ShadingPattern && patterns[patternKey].objectNumber >= 0) { 3178 out("/" + patternKey + " " + patterns[patternKey].objectNumber + " 0 R"); 3179 } 3180 } 3181 3182 events.publish("putShadingPatternDict"); 3183 out(">>"); 3184 } 3185 }; 3186 3187 var putTilingPatternDict = function putTilingPatternDict(objectOid) { 3188 if (Object.keys(patterns).length > 0) { 3189 out("/Pattern <<"); 3190 3191 for (var patternKey in patterns) { 3192 if (patterns.hasOwnProperty(patternKey) && patterns[patternKey] instanceof API.TilingPattern && patterns[patternKey].objectNumber >= 0 && patterns[patternKey].objectNumber < objectOid // prevent cyclic dependencies 3193 ) { 3194 out("/" + patternKey + " " + patterns[patternKey].objectNumber + " 0 R"); 3195 } 3196 } 3197 3198 events.publish("putTilingPatternDict"); 3199 out(">>"); 3200 } 3201 }; 3202 3203 var putGStatesDict = function putGStatesDict() { 3204 if (Object.keys(gStates).length > 0) { 3205 var gStateKey; 3206 out("/ExtGState <<"); 3207 3208 for (gStateKey in gStates) { 3209 if (gStates.hasOwnProperty(gStateKey) && gStates[gStateKey].objectNumber >= 0) { 3210 out("/" + gStateKey + " " + gStates[gStateKey].objectNumber + " 0 R"); 3211 } 3212 } 3213 3214 events.publish("putGStateDict"); 3215 out(">>"); 3216 } 3217 }; 3218 3219 var putResourceDictionary = function putResourceDictionary(objectIds) { 3220 newObjectDeferredBegin(objectIds.resourcesOid, true); 3221 out("<<"); 3222 out("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"); 3223 putFontDict(); 3224 putShadingPatternDict(); 3225 putTilingPatternDict(objectIds.objectOid); 3226 putGStatesDict(); 3227 putXobjectDict(); 3228 out(">>"); 3229 out("endobj"); 3230 }; 3231 3232 var putResources = function putResources() { 3233 // FormObjects, Patterns etc. might use other FormObjects/Patterns/Images 3234 // which means their resource dictionaries must contain the already resolved 3235 // object ids. For this reason we defer the serialization of the resource 3236 // dicts until all objects have been serialized and have object ids. 3237 // 3238 // In order to prevent cyclic dependencies (which Adobe Reader doesn't like), 3239 // we only put all oids that are smaller than the oid of the object the 3240 // resource dict belongs to. This is correct behavior, since the streams 3241 // may only use other objects that have already been defined and thus appear 3242 // earlier in their respective collection. 3243 // Currently, this only affects tiling patterns, but a (more) correct 3244 // implementation of FormObjects would also define their own resource dicts. 3245 var deferredResourceDictionaryIds = []; 3246 putFonts(); 3247 putGStates(); 3248 putXObjects(); 3249 putPatterns(deferredResourceDictionaryIds); 3250 events.publish("putResources"); 3251 deferredResourceDictionaryIds.forEach(putResourceDictionary); 3252 putResourceDictionary({ 3253 resourcesOid: resourceDictionaryObjId, 3254 objectOid: Number.MAX_SAFE_INTEGER // output all objects 3255 3256 }); 3257 events.publish("postPutResources"); 3258 }; 3259 3260 var putAdditionalObjects = function putAdditionalObjects() { 3261 events.publish("putAdditionalObjects"); 3262 3263 for (var i = 0; i < additionalObjects.length; i++) { 3264 var obj = additionalObjects[i]; 3265 newObjectDeferredBegin(obj.objId, true); 3266 out(obj.content); 3267 out("endobj"); 3268 } 3269 3270 events.publish("postPutAdditionalObjects"); 3271 }; 3272 3273 var addFontToFontDictionary = function addFontToFontDictionary(font) { 3274 fontmap[font.fontName] = fontmap[font.fontName] || {}; 3275 fontmap[font.fontName][font.fontStyle] = font.id; 3276 }; 3277 3278 var addFont = function addFont(postScriptName, fontName, fontStyle, encoding, isStandardFont) { 3279 var font = { 3280 id: "F" + (Object.keys(fonts).length + 1).toString(10), 3281 postScriptName: postScriptName, 3282 fontName: fontName, 3283 fontStyle: fontStyle, 3284 encoding: encoding, 3285 isStandardFont: isStandardFont || false, 3286 metadata: {} 3287 }; 3288 events.publish("addFont", { 3289 font: font, 3290 instance: this 3291 }); 3292 fonts[font.id] = font; 3293 addFontToFontDictionary(font); 3294 return font.id; 3295 }; 3296 3297 var addFonts = function addFonts(arrayOfFonts) { 3298 for (var i = 0, l = standardFonts.length; i < l; i++) { 3299 var fontKey = addFont.call(this, arrayOfFonts[i][0], arrayOfFonts[i][1], arrayOfFonts[i][2], standardFonts[i][3], true); 3300 3301 if (putOnlyUsedFonts === false) { 3302 usedFonts[fontKey] = true; 3303 } // adding aliases for standard fonts, this time matching the capitalization 3304 3305 3306 var parts = arrayOfFonts[i][0].split("-"); 3307 addFontToFontDictionary({ 3308 id: fontKey, 3309 fontName: parts[0], 3310 fontStyle: parts[1] || "" 3311 }); 3312 } 3313 3314 events.publish("addFonts", { 3315 fonts: fonts, 3316 dictionary: fontmap 3317 }); 3318 }; 3319 3320 var SAFE = function __safeCall(fn) { 3321 fn.foo = function __safeCallWrapper() { 3322 try { 3323 return fn.apply(this, arguments); 3324 } catch (e) { 3325 var stack = e.stack || ""; 3326 if (~stack.indexOf(" at ")) stack = stack.split(" at ")[1]; 3327 var m = "Error in function " + stack.split("\n")[0].split("<")[0] + ": " + e.message; 3328 3329 if (globalObject.console) { 3330 globalObject.console.error(m, e); 3331 if (globalObject.alert) alert(m); 3332 } else { 3333 throw new Error(m); 3334 } 3335 } 3336 }; 3337 3338 fn.foo.bar = fn; 3339 return fn.foo; 3340 }; 3341 3342 var to8bitStream = function to8bitStream(text, flags) { 3343 /** 3344 * PDF 1.3 spec: 3345 * "For text strings encoded in Unicode, the first two bytes must be 254 followed by 3346 * 255, representing the Unicode byte order marker, U+FEFF. (This sequence conflicts 3347 * with the PDFDocEncoding character sequence thorn ydieresis, which is unlikely 3348 * to be a meaningful beginning of a word or phrase.) The remainder of the 3349 * string consists of Unicode character codes, according to the UTF-16 encoding 3350 * specified in the Unicode standard, version 2.0. Commonly used Unicode values 3351 * are represented as 2 bytes per character, with the high-order byte appearing first 3352 * in the string." 3353 * 3354 * In other words, if there are chars in a string with char code above 255, we 3355 * recode the string to UCS2 BE - string doubles in length and BOM is prepended. 3356 * 3357 * HOWEVER! 3358 * Actual *content* (body) text (as opposed to strings used in document properties etc) 3359 * does NOT expect BOM. There, it is treated as a literal GID (Glyph ID) 3360 * 3361 * Because of Adobe's focus on "you subset your fonts!" you are not supposed to have 3362 * a font that maps directly Unicode (UCS2 / UTF16BE) code to font GID, but you could 3363 * fudge it with "Identity-H" encoding and custom CIDtoGID map that mimics Unicode 3364 * code page. There, however, all characters in the stream are treated as GIDs, 3365 * including BOM, which is the reason we need to skip BOM in content text (i.e. that 3366 * that is tied to a font). 3367 * 3368 * To signal this "special" PDFEscape / to8bitStream handling mode, 3369 * API.text() function sets (unless you overwrite it with manual values 3370 * given to API.text(.., flags) ) 3371 * flags.autoencode = true 3372 * flags.noBOM = true 3373 * 3374 * =================================================================================== 3375 * `flags` properties relied upon: 3376 * .sourceEncoding = string with encoding label. 3377 * "Unicode" by default. = encoding of the incoming text. 3378 * pass some non-existing encoding name 3379 * (ex: 'Do not touch my strings! I know what I am doing.') 3380 * to make encoding code skip the encoding step. 3381 * .outputEncoding = Either valid PDF encoding name 3382 * (must be supported by jsPDF font metrics, otherwise no encoding) 3383 * or a JS object, where key = sourceCharCode, value = outputCharCode 3384 * missing keys will be treated as: sourceCharCode === outputCharCode 3385 * .noBOM 3386 * See comment higher above for explanation for why this is important 3387 * .autoencode 3388 * See comment higher above for explanation for why this is important 3389 */ 3390 var i, l, sourceEncoding, encodingBlock, outputEncoding, newtext, isUnicode, ch, bch; 3391 flags = flags || {}; 3392 sourceEncoding = flags.sourceEncoding || "Unicode"; 3393 outputEncoding = flags.outputEncoding; // This 'encoding' section relies on font metrics format 3394 // attached to font objects by, among others, 3395 // "Willow Systems' standard_font_metrics plugin" 3396 // see jspdf.plugin.standard_font_metrics.js for format 3397 // of the font.metadata.encoding Object. 3398 // It should be something like 3399 // .encoding = {'codePages':['WinANSI....'], 'WinANSI...':{code:code, ...}} 3400 // .widths = {0:width, code:width, ..., 'fof':divisor} 3401 // .kerning = {code:{previous_char_code:shift, ..., 'fof':-divisor},...} 3402 3403 if ((flags.autoencode || outputEncoding) && fonts[activeFontKey].metadata && fonts[activeFontKey].metadata[sourceEncoding] && fonts[activeFontKey].metadata[sourceEncoding].encoding) { 3404 encodingBlock = fonts[activeFontKey].metadata[sourceEncoding].encoding; // each font has default encoding. Some have it clearly defined. 3405 3406 if (!outputEncoding && fonts[activeFontKey].encoding) { 3407 outputEncoding = fonts[activeFontKey].encoding; 3408 } // Hmmm, the above did not work? Let's try again, in different place. 3409 3410 3411 if (!outputEncoding && encodingBlock.codePages) { 3412 outputEncoding = encodingBlock.codePages[0]; // let's say, first one is the default 3413 } 3414 3415 if (typeof outputEncoding === "string") { 3416 outputEncoding = encodingBlock[outputEncoding]; 3417 } // we want output encoding to be a JS Object, where 3418 // key = sourceEncoding's character code and 3419 // value = outputEncoding's character code. 3420 3421 3422 if (outputEncoding) { 3423 isUnicode = false; 3424 newtext = []; 3425 3426 for (i = 0, l = text.length; i < l; i++) { 3427 ch = outputEncoding[text.charCodeAt(i)]; 3428 3429 if (ch) { 3430 newtext.push(String.fromCharCode(ch)); 3431 } else { 3432 newtext.push(text[i]); 3433 } // since we are looping over chars anyway, might as well 3434 // check for residual unicodeness 3435 3436 3437 if (newtext[i].charCodeAt(0) >> 8) { 3438 /* more than 255 */ 3439 isUnicode = true; 3440 } 3441 } 3442 3443 text = newtext.join(""); 3444 } 3445 } 3446 3447 i = text.length; // isUnicode may be set to false above. Hence the triple-equal to undefined 3448 3449 while (isUnicode === undefined && i !== 0) { 3450 if (text.charCodeAt(i - 1) >> 8) { 3451 /* more than 255 */ 3452 isUnicode = true; 3453 } 3454 3455 i--; 3456 } 3457 3458 if (!isUnicode) { 3459 return text; 3460 } 3461 3462 newtext = flags.noBOM ? [] : [254, 255]; 3463 3464 for (i = 0, l = text.length; i < l; i++) { 3465 ch = text.charCodeAt(i); 3466 bch = ch >> 8; // divide by 256 3467 3468 if (bch >> 8) { 3469 /* something left after dividing by 256 second time */ 3470 throw new Error("Character at position " + i + " of string '" + text + "' exceeds 16bits. Cannot be encoded into UCS-2 BE"); 3471 } 3472 3473 newtext.push(bch); 3474 newtext.push(ch - (bch << 8)); 3475 } 3476 3477 return String.fromCharCode.apply(undefined, newtext); 3478 }; 3479 3480 var pdfEscape = API.__private__.pdfEscape = API.pdfEscape = function (text, flags) { 3481 /** 3482 * Replace '/', '(', and ')' with pdf-safe versions 3483 * 3484 * Doing to8bitStream does NOT make this PDF display unicode text. For that 3485 * we also need to reference a unicode font and embed it - royal pain in the rear. 3486 * 3487 * There is still a benefit to to8bitStream - PDF simply cannot handle 16bit chars, 3488 * which JavaScript Strings are happy to provide. So, while we still cannot display 3489 * 2-byte characters property, at least CONDITIONALLY converting (entire string containing) 3490 * 16bit chars to (USC-2-BE) 2-bytes per char + BOM streams we ensure that entire PDF 3491 * is still parseable. 3492 * This will allow immediate support for unicode in document properties strings. 3493 */ 3494 return to8bitStream(text, flags).replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)"); 3495 }; 3496 3497 var beginPage = API.__private__.beginPage = function (format) { 3498 pages[++page] = []; 3499 pagesContext[page] = { 3500 objId: 0, 3501 contentsObjId: 0, 3502 userUnit: Number(userUnit), 3503 artBox: null, 3504 bleedBox: null, 3505 cropBox: null, 3506 trimBox: null, 3507 mediaBox: { 3508 bottomLeftX: 0, 3509 bottomLeftY: 0, 3510 topRightX: Number(format[0]), 3511 topRightY: Number(format[1]) 3512 } 3513 }; 3514 3515 _setPage(page); 3516 3517 setOutputDestination(pages[currentPage]); 3518 }; 3519 3520 var _addPage = function _addPage(parmFormat, parmOrientation) { 3521 var dimensions, width, height; 3522 orientation = parmOrientation || orientation; 3523 3524 if (typeof parmFormat === "string") { 3525 dimensions = getPageFormat(parmFormat.toLowerCase()); 3526 3527 if (Array.isArray(dimensions)) { 3528 width = dimensions[0]; 3529 height = dimensions[1]; 3530 } 3531 } 3532 3533 if (Array.isArray(parmFormat)) { 3534 width = parmFormat[0] * scaleFactor; 3535 height = parmFormat[1] * scaleFactor; 3536 } 3537 3538 if (isNaN(width)) { 3539 width = format[0]; 3540 height = format[1]; 3541 } 3542 3543 if (width > 14400 || height > 14400) { 3544 console.warn("A page in a PDF can not be wider or taller than 14400 userUnit. jsPDF limits the width/height to 14400"); 3545 width = Math.min(14400, width); 3546 height = Math.min(14400, height); 3547 } 3548 3549 format = [width, height]; 3550 3551 switch (orientation.substr(0, 1)) { 3552 case "l": 3553 if (height > width) { 3554 format = [height, width]; 3555 } 3556 3557 break; 3558 3559 case "p": 3560 if (width > height) { 3561 format = [height, width]; 3562 } 3563 3564 break; 3565 } 3566 3567 beginPage(format); // Set line width 3568 3569 setLineWidth(lineWidth); // Set draw color 3570 3571 out(strokeColor); // resurrecting non-default line caps, joins 3572 3573 if (lineCapID !== 0) { 3574 out(lineCapID + " J"); 3575 } 3576 3577 if (lineJoinID !== 0) { 3578 out(lineJoinID + " j"); 3579 } 3580 3581 events.publish("addPage", { 3582 pageNumber: page 3583 }); 3584 }; 3585 3586 var _deletePage = function _deletePage(n) { 3587 if (n > 0 && n <= page) { 3588 pages.splice(n, 1); 3589 pagesContext.splice(n, 1); 3590 page--; 3591 3592 if (currentPage > page) { 3593 currentPage = page; 3594 } 3595 3596 this.setPage(currentPage); 3597 } 3598 }; 3599 3600 var _setPage = function _setPage(n) { 3601 if (n > 0 && n <= page) { 3602 currentPage = n; 3603 } 3604 }; 3605 3606 var getNumberOfPages = API.__private__.getNumberOfPages = API.getNumberOfPages = function () { 3607 return pages.length - 1; 3608 }; 3609 /** 3610 * Returns a document-specific font key - a label assigned to a 3611 * font name + font type combination at the time the font was added 3612 * to the font inventory. 3613 * 3614 * Font key is used as label for the desired font for a block of text 3615 * to be added to the PDF document stream. 3616 * @private 3617 * @function 3618 * @param fontName {string} can be undefined on "falthy" to indicate "use current" 3619 * @param fontStyle {string} can be undefined on "falthy" to indicate "use current" 3620 * @returns {string} Font key. 3621 * @ignore 3622 */ 3623 3624 3625 var getFont = function getFont(fontName, fontStyle, options) { 3626 var key = undefined, 3627 fontNameLowerCase; 3628 options = options || {}; 3629 fontName = fontName !== undefined ? fontName : fonts[activeFontKey].fontName; 3630 fontStyle = fontStyle !== undefined ? fontStyle : fonts[activeFontKey].fontStyle; 3631 fontNameLowerCase = fontName.toLowerCase(); 3632 3633 if (fontmap[fontNameLowerCase] !== undefined && fontmap[fontNameLowerCase][fontStyle] !== undefined) { 3634 key = fontmap[fontNameLowerCase][fontStyle]; 3635 } else if (fontmap[fontName] !== undefined && fontmap[fontName][fontStyle] !== undefined) { 3636 key = fontmap[fontName][fontStyle]; 3637 } else { 3638 if (options.disableWarning === false) { 3639 console.warn("Unable to look up font label for font '" + fontName + "', '" + fontStyle + "'. Refer to getFontList() for available fonts."); 3640 } 3641 } 3642 3643 if (!key && !options.noFallback) { 3644 key = fontmap["times"][fontStyle]; 3645 3646 if (key == null) { 3647 key = fontmap["times"]["normal"]; 3648 } 3649 } 3650 3651 return key; 3652 }; 3653 3654 var putInfo = API.__private__.putInfo = function () { 3655 var objectId = newObject(); 3656 3657 var encryptor = function encryptor(data) { 3658 return data; 3659 }; 3660 3661 if (encryptionOptions !== null) { 3662 encryptor = encryption.encryptor(objectId, 0); 3663 } 3664 3665 out("<<"); 3666 out("/Producer (" + pdfEscape(encryptor("jsPDF " + jsPDF.version)) + ")"); 3667 3668 for (var key in documentProperties) { 3669 if (documentProperties.hasOwnProperty(key) && documentProperties[key]) { 3670 out("/" + key.substr(0, 1).toUpperCase() + key.substr(1) + " (" + pdfEscape(encryptor(documentProperties[key])) + ")"); 3671 } 3672 } 3673 3674 out("/CreationDate (" + pdfEscape(encryptor(creationDate)) + ")"); 3675 out(">>"); 3676 out("endobj"); 3677 }; 3678 3679 var putCatalog = API.__private__.putCatalog = function (options) { 3680 options = options || {}; 3681 var tmpRootDictionaryObjId = options.rootDictionaryObjId || rootDictionaryObjId; 3682 newObject(); 3683 out("<<"); 3684 out("/Type /Catalog"); 3685 out("/Pages " + tmpRootDictionaryObjId + " 0 R"); // PDF13ref Section 7.2.1 3686 3687 if (!zoomMode) zoomMode = "fullwidth"; 3688 3689 switch (zoomMode) { 3690 case "fullwidth": 3691 out("/OpenAction [3 0 R /FitH null]"); 3692 break; 3693 3694 case "fullheight": 3695 out("/OpenAction [3 0 R /FitV null]"); 3696 break; 3697 3698 case "fullpage": 3699 out("/OpenAction [3 0 R /Fit]"); 3700 break; 3701 3702 case "original": 3703 out("/OpenAction [3 0 R /XYZ null null 1]"); 3704 break; 3705 3706 default: 3707 var pcn = "" + zoomMode; 3708 if (pcn.substr(pcn.length - 1) === "%") zoomMode = parseInt(zoomMode) / 100; 3709 3710 if (typeof zoomMode === "number") { 3711 out("/OpenAction [3 0 R /XYZ null null " + f2(zoomMode) + "]"); 3712 } 3713 3714 } 3715 3716 if (!layoutMode) layoutMode = "continuous"; 3717 3718 switch (layoutMode) { 3719 case "continuous": 3720 out("/PageLayout /OneColumn"); 3721 break; 3722 3723 case "single": 3724 out("/PageLayout /SinglePage"); 3725 break; 3726 3727 case "two": 3728 case "twoleft": 3729 out("/PageLayout /TwoColumnLeft"); 3730 break; 3731 3732 case "tworight": 3733 out("/PageLayout /TwoColumnRight"); 3734 break; 3735 } 3736 3737 if (pageMode) { 3738 /** 3739 * A name object specifying how the document should be displayed when opened: 3740 * UseNone : Neither document outline nor thumbnail images visible -- DEFAULT 3741 * UseOutlines : Document outline visible 3742 * UseThumbs : Thumbnail images visible 3743 * FullScreen : Full-screen mode, with no menu bar, window controls, or any other window visible 3744 */ 3745 out("/PageMode /" + pageMode); 3746 } 3747 3748 events.publish("putCatalog"); 3749 out(">>"); 3750 out("endobj"); 3751 }; 3752 3753 var putTrailer = API.__private__.putTrailer = function () { 3754 out("trailer"); 3755 out("<<"); 3756 out("/Size " + (objectNumber + 1)); // Root and Info must be the last and second last objects written respectively 3757 3758 out("/Root " + objectNumber + " 0 R"); 3759 out("/Info " + (objectNumber - 1) + " 0 R"); 3760 3761 if (encryptionOptions !== null) { 3762 out("/Encrypt " + encryption.oid + " 0 R"); 3763 } 3764 3765 out("/ID [ <" + fileId + "> <" + fileId + "> ]"); 3766 out(">>"); 3767 }; 3768 3769 var putHeader = API.__private__.putHeader = function () { 3770 out("%PDF-" + pdfVersion); 3771 out("%\xBA\xDF\xAC\xE0"); 3772 }; 3773 3774 var putXRef = API.__private__.putXRef = function () { 3775 var p = "0000000000"; 3776 out("xref"); 3777 out("0 " + (objectNumber + 1)); 3778 out("0000000000 65535 f "); 3779 3780 for (var i = 1; i <= objectNumber; i++) { 3781 var offset = offsets[i]; 3782 3783 if (typeof offset === "function") { 3784 out((p + offsets[i]()).slice(-10) + " 00000 n "); 3785 } else { 3786 if (typeof offsets[i] !== "undefined") { 3787 out((p + offsets[i]).slice(-10) + " 00000 n "); 3788 } else { 3789 out("0000000000 00000 n "); 3790 } 3791 } 3792 } 3793 }; 3794 3795 var buildDocument = API.__private__.buildDocument = function () { 3796 resetDocument(); 3797 setOutputDestination(content); 3798 events.publish("buildDocument"); 3799 putHeader(); 3800 putPages(); 3801 putAdditionalObjects(); 3802 putResources(); 3803 if (encryptionOptions !== null) putEncryptionDict(); 3804 putInfo(); 3805 putCatalog(); 3806 var offsetOfXRef = contentLength; 3807 putXRef(); 3808 putTrailer(); 3809 out("startxref"); 3810 out("" + offsetOfXRef); 3811 out("%%EOF"); 3812 setOutputDestination(pages[currentPage]); 3813 return content.join("\n"); 3814 }; 3815 3816 var getBlob = API.__private__.getBlob = function (data) { 3817 return new Blob([getArrayBuffer(data)], { 3818 type: "application/pdf" 3819 }); 3820 }; 3821 /** 3822 * Generates the PDF document. 3823 * 3824 * If `type` argument is undefined, output is raw body of resulting PDF returned as a string. 3825 * 3826 * @param {string}
3826 type A string identifying one of the possible output types.<br/> 3827 * Possible values are: <br/> 3828 * 'arraybuffer' -> (ArrayBuffer)<br/> 3829 * 'blob' -> (Blob)<br/> 3830 * 'bloburi'/'bloburl' -> (string)<br/> 3831 * 'datauristring'/'dataurlstring' -> (string)<br/> 3832 * 'datauri'/'dataurl' -> (undefined) -> change location to generated datauristring/dataurlstring<br/> 3833 * 'dataurlnewwindow' -> (window | null | undefined) throws error if global isn't a window object(node)<br/> 3834 * 'pdfobjectnewwindow' -> (window | null) throws error if global isn't a window object(node)<br/> 3835 * 'pdfjsnewwindow' -> (wind | null) 3836 * @param {Object|string} options An object providing some additional signalling to PDF generator.<br/> 3837 * Possible options are 'filename'.<br/> 3838 * A string can be passed instead of {filename:string} and defaults to 'generated.pdf' 3839 * @function 3840 * @instance 3841 * @returns {string|window|ArrayBuffer|Blob|jsPDF|null|undefined} 3842 * @memberof jsPDF# 3843 * @name output 3844 */ 3845 3846 3847 var output = API.output = API.__private__.output = SAFE(function output(type, options) { 3848 options = options || {}; 3849 3850 if (typeof options === "string") { 3851 options = { 3852 filename: options 3853 }; 3854 } else { 3855 options.filename = options.filename || "generated.pdf"; 3856 } 3857 3858 switch (type) { 3859 case undefined: 3860 return buildDocument(); 3861 3862 case "save": 3863 API.save(options.filename); 3864 break; 3865 3866 case "arraybuffer": 3867 return getArrayBuffer(buildDocument()); 3868 3869 case "blob": 3870 return getBlob(buildDocument()); 3871 3872 case "bloburi": 3873 case "bloburl": 3874 // Developer is responsible of calling revokeObjectURL 3875 if (typeof globalObject.URL !== "undefined" && typeof globalObject.URL.createObjectURL === "function") { 3876 return globalObject.URL && globalObject.URL.createObjectURL(getBlob(buildDocument())) || void 0; 3877 } else { 3878 console.warn("bloburl is not supported by your system, because URL.createObjectURL is not supported by your browser."); 3879 } 3880 3881 break; 3882 3883 case "datauristring": 3884 case "dataurlstring": 3885 var dataURI = ""; 3886 var pdfDocument = buildDocument(); 3887 3888 try { 3889 dataURI = btoa(pdfDocument); 3890 } catch (e) { 3891 dataURI = btoa(unescape(encodeURIComponent(pdfDocument))); 3892 } 3893 3894 return "data:application/pdf;filename=" + options.filename + ";base64," + dataURI; 3895 3896 case "pdfobjectnewwindow": 3897 if (Object.prototype.toString.call(globalObject) === "[object Window]") { 3898 var pdfObjectUrl = "https://cdnjs.cloudflare.com/ajax/libs/pdfobject/2.1.1/pdfobject.min.js"; 3899 var integrity = ' integrity="sha512-4ze/a9/4jqu+tX9dfOqJYSvyYd5M6qum/3HpCLr+/Jqf0whc37VUbkpNGHR7/8pSnCFw47T1fmIpwBV7UySh3g==" crossorigin="anonymous"'; 3900 3901 if (options.pdfObjectUrl) { 3902 pdfObjectUrl = options.pdfObjectUrl; 3903 integrity = ""; 3904 } 3905 3906 var htmlForNewWindow = "<html>" + '<style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;} </style><body><script src="' + pdfObjectUrl + '"' + integrity + '></script><script >PDFObject.embed("' + this.output("dataurlstring") + '", ' + JSON.stringify(options) + ");</script></body></html>"; 3907 var nW = globalObject.open(); 3908 3909 if (nW !== null) { 3910 nW.document.write(htmlForNewWindow); 3911 } 3912 3913 return nW; 3914 } else { 3915 throw new Error("The option pdfobjectnewwindow just works in a browser-environment."); 3916 } 3917 3918 case "pdfjsnewwindow": 3919 if (Object.prototype.toString.call(globalObject) === "[object Window]") { 3920 var pdfJsUrl = options.pdfJsUrl || "examples/PDF.js/web/viewer.html"; 3921 var htmlForPDFjsNewWindow = "<html>" + "<style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;} </style>" + '<body><iframe id="pdfViewer" src="' + pdfJsUrl + "?file=&downloadName=" + options.filename + '" width="500px" height="400px" />' + "</body></html>"; 3922 var PDFjsNewWindow = globalObject.open(); 3923 3924 if (PDFjsNewWindow !== null) { 3925 PDFjsNewWindow.document.write(htmlForPDFjsNewWindow); 3926 var scope = this; 3927 3928 PDFjsNewWindow.document.documentElement.querySelector("#pdfViewer").onload = function () { 3929 PDFjsNewWindow.document.title = options.filename; 3930 PDFjsNewWindow.document.documentElement.querySelector("#pdfViewer").contentWindow.PDFViewerApplication.open(scope.output("bloburl")); 3931 }; 3932 } 3933 3934 return PDFjsNewWindow; 3935 } else { 3936 throw new Error("The option pdfjsnewwindow just works in a browser-environment."); 3937 } 3938 3939 case "dataurlnewwindow": 3940 if (Object.prototype.toString.call(globalObject) === "[object Window]") { 3941 var htmlForDataURLNewWindow = "<html>" + "<style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;} </style>" + "<body>" + '<iframe src="' + this.output("datauristring", options) + '"></iframe>' + "</body></html>"; 3942 var dataURLNewWindow = globalObject.open(); 3943 3944 if (dataURLNewWindow !== null) { 3945 dataURLNewWindow.document.write(htmlForDataURLNewWindow); 3946 dataURLNewWindow.document.title = options.filename; 3947 } 3948 3949 if (dataURLNewWindow || typeof safari === "undefined") return dataURLNewWindow; 3950 } else { 3951 throw new Error("The option dataurlnewwindow just works in a browser-environment."); 3952 } 3953 3954 break; 3955 3956 case "datauri": 3957 case "dataurl": 3958 return globalObject.document.location.href = this.output("datauristring", options); 3959 3960 default: 3961 return null; 3962 } 3963 }); 3964 /** 3965 * Used to see if a supplied hotfix was requested when the pdf instance was created. 3966 * @param {string} hotfixName - The name of the hotfix to check. 3967 * @returns {boolean} 3968 */ 3969 3970 var hasHotfix = function hasHotfix(hotfixName) {
vendor: 5,864 bytes, lines 3971-4194
3971 return Array.isArray(hotfixes) === true && hotfixes.indexOf(hotfixName) > -1; 3972 }; 3973 3974 switch (unit) { 3975 case "pt": 3976 scaleFactor = 1; 3977 break; 3978 3979 case "mm": 3980 scaleFactor = 72 / 25.4; 3981 break; 3982 3983 case "cm": 3984 scaleFactor = 72 / 2.54; 3985 break; 3986 3987 case "in": 3988 scaleFactor = 72; 3989 break; 3990 3991 case "px": 3992 if (hasHotfix("px_scaling") == true) { 3993 scaleFactor = 72 / 96; 3994 } else { 3995 scaleFactor = 96 / 72; 3996 } 3997 3998 break; 3999 4000 case "pc": 4001 scaleFactor = 12; 4002 break; 4003 4004 case "em": 4005 scaleFactor = 12; 4006 break; 4007 4008 case "ex": 4009 scaleFactor = 6; 4010 break; 4011 4012 default: 4013 if (typeof unit === "number") { 4014 scaleFactor = unit; 4015 } else { 4016 throw new Error("Invalid unit: " + unit); 4017 } 4018 4019 } 4020 4021 var encryption = null; 4022 setCreationDate(); 4023 setFileId(); 4024 4025 var getEncryptor = function getEncryptor(objectId) { 4026 if (encryptionOptions !== null) { 4027 return encryption.encryptor(objectId, 0); 4028 } 4029 4030 return function (data) { 4031 return data; 4032 }; 4033 }; //--------------------------------------- 4034 // Public API 4035 4036 4037 var getPageInfo = API.__private__.getPageInfo = API.getPageInfo = function (pageNumberOneBased) { 4038 if (isNaN(pageNumberOneBased) || pageNumberOneBased % 1 !== 0) { 4039 throw new Error("Invalid argument passed to jsPDF.getPageInfo"); 4040 } 4041 4042 var objId = pagesContext[pageNumberOneBased].objId; 4043 return { 4044 objId: objId, 4045 pageNumber: pageNumberOneBased, 4046 pageContext: pagesContext[pageNumberOneBased] 4047 }; 4048 }; 4049 4050 var getPageInfoByObjId = API.__private__.getPageInfoByObjId = function (objId) { 4051 if (isNaN(objId) || objId % 1 !== 0) { 4052 throw new Error("Invalid argument passed to jsPDF.getPageInfoByObjId"); 4053 } 4054 4055 for (var pageNumber in pagesContext) { 4056 if (pagesContext[pageNumber].objId === objId) { 4057 break; 4058 } 4059 } 4060 4061 return getPageInfo(pageNumber); 4062 }; 4063 4064 var getCurrentPageInfo = API.__private__.getCurrentPageInfo = API.getCurrentPageInfo = function () { 4065 return { 4066 objId: pagesContext[currentPage].objId, 4067 pageNumber: currentPage, 4068 pageContext: pagesContext[currentPage] 4069 }; 4070 }; 4071 /** 4072 * Adds (and transfers the focus to) new page to the PDF document. 4073 * @param format {String/Array} The format of the new page. Can be: <ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br /> 4074 * Default is "a4". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array, e.g. [595.28, 841.89] 4075 * @param orientation {string} Orientation of the new page. Possible values are "portrait" or "landscape" (or shortcuts "p" (Default), "l"). 4076 * @function 4077 * @instance 4078 * @returns {jsPDF} 4079 * 4080 * @memberof jsPDF# 4081 * @name addPage 4082 */ 4083 4084 4085 API.addPage = function () { 4086 _addPage.apply(this, arguments); 4087 4088 return this; 4089 }; 4090 /** 4091 * Adds (and transfers the focus to) new page to the PDF document. 4092 * @function 4093 * @instance 4094 * @returns {jsPDF} 4095 * 4096 * @memberof jsPDF# 4097 * @name setPage 4098 * @param {number} page Switch the active page to the page number specified (indexed starting at 1). 4099 * @example 4100 * doc = jsPDF() 4101 * doc.addPage() 4102 * doc.addPage() 4103 * doc.text('I am on page 3', 10, 10) 4104 * doc.setPage(1) 4105 * doc.text('I am on page 1', 10, 10) 4106 */ 4107 4108 4109 API.setPage = function () { 4110 _setPage.apply(this, arguments); 4111 4112 setOutputDestination.call(this, pages[currentPage]); 4113 return this; 4114 }; 4115 /** 4116 * @name insertPage 4117 * @memberof jsPDF# 4118 * 4119 * @function 4120 * @instance 4121 * @param {Object} beforePage 4122 * @returns {jsPDF} 4123 */ 4124 4125 4126 API.insertPage = function (beforePage) { 4127 this.addPage(); 4128 this.movePage(currentPage, beforePage); 4129 return this; 4130 }; 4131 /** 4132 * @name movePage 4133 * @memberof jsPDF# 4134 * @function 4135 * @instance 4136 * @param {number} targetPage 4137 * @param {number} beforePage 4138 * @returns {jsPDF} 4139 */ 4140 4141 4142 API.movePage = function (targetPage, beforePage) { 4143 var tmpPages, tmpPagesContext; 4144 4145 if (targetPage > beforePage) { 4146 tmpPages = pages[targetPage]; 4147 tmpPagesContext = pagesContext[targetPage]; 4148 4149 for (var i = targetPage; i > beforePage; i--) { 4150 pages[i] = pages[i - 1]; 4151 pagesContext[i] = pagesContext[i - 1]; 4152 } 4153 4154 pages[beforePage] = tmpPages; 4155 pagesContext[beforePage] = tmpPagesContext; 4156 this.setPage(beforePage); 4157 } else if (targetPage < beforePage) { 4158 tmpPages = pages[targetPage]; 4159 tmpPagesContext = pagesContext[targetPage]; 4160 4161 for (var j = targetPage; j < beforePage; j++) { 4162 pages[j] = pages[j + 1]; 4163 pagesContext[j] = pagesContext[j + 1]; 4164 } 4165 4166 pages[beforePage] = tmpPages; 4167 pagesContext[beforePage] = tmpPagesContext; 4168 this.setPage(beforePage); 4169 } 4170 4171 return this; 4172 }; 4173 /** 4174 * Deletes a page from the PDF. 4175 * @name deletePage 4176 * @memberof jsPDF# 4177 * @function 4178 * @param {number} targetPage 4179 * @instance 4180 * @returns {jsPDF} 4181 */ 4182 4183 4184 API.deletePage = function () { 4185 _deletePage.apply(this, arguments); 4186 4187 return this; 4188 }; 4189 /** 4190 * Adds text to page. Supports adding multiline text when 'text' argument is an Array of Strings. 4191 * 4192 * @function 4193 * @instance 4194 * @param {String|Array}
4194 text String or array of strings to be added to the page. Each line is shifted one line down per font, spacing settings declared before this call. 4195 * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page. 4196 * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page. 4197 * @param {Object} [options] - Collection of settings signaling how the text must be encoded. 4198 * @param {string} [options.align=left] - The alignment of the text, possible values: left, center, right, justify. 4199 * @param {string} [options.baseline=alphabetic] - Sets text baseline used when drawing the text, possible values: alphabetic, ideographic, bottom, top, middle, hanging 4200 * @param {number|Matrix} [options.angle=0] - Rotate the text clockwise or counterclockwise. Expects the angle in degree. 4201 * @param {number} [options.rotationDirection=1] - Direction of the rotation. 0 = clockwise, 1 = counterclockwise. 4202 * @param {number} [options.charSpace=0] - The space between each letter. 4203 * @param {number} [options.horizontalScale=1] - Horizontal scale of the text as a factor of the regular size. 4204 * @param {number} [options.lineHeightFactor=1.15] - The lineheight of each line. 4205 * @param {Object} [options.flags] - Flags for to8bitStream. 4206 * @param {boolean} [options.flags.noBOM=true] - Don't add BOM to Unicode-text. 4207 * @param {boolean} [options.flags.autoencode=true] - Autoencode the Text. 4208 * @param {number} [options.maxWidth=0] - Split the text by given width, 0 = no split. 4209 * @param {string} [options.renderingMode=fill] - Set how the text should be rendered, possible values: fill, stroke, fillThenStroke, invisible, fillAndAddForClipping, strokeAndAddPathForClipping, fillThenStrokeAndAddToPathForClipping, addToPathForClipping. 4210 * @param {boolean} [options.isInputVisual] - Option for the BidiEngine 4211 * @param {boolean} [options.isOutputVisual] - Option for the BidiEngine 4212 * @param {boolean} [options.isInputRtl] - Option for the BidiEngine 4213 * @param {boolean} [options.isOutputRtl] - Option for the BidiEngine 4214 * @param {boolean} [options.isSymmetricSwapping] - Option for the BidiEngine 4215 * @param {number|Matrix} transform If transform is a number the text will be rotated by this value around the anchor set by x and y. 4216 * 4217 * If it is a Matrix, this matrix gets directly applied to the text, which allows shearing 4218 * effects etc.; the x and y offsets are then applied AFTER the coordinate system has been established by this 4219 * matrix. This means passing a rotation matrix that is equivalent to some rotation angle will in general yield a 4220 * DIFFERENT result. A matrix is only allowed in "advanced" API mode. 4221 * @returns {jsPDF} 4222 * @memberof jsPDF# 4223 * @name text 4224 */ 4225 4226 4227 API.__private__.text = API.text = function (text, x, y, options, transform) { 4228 /* 4229 * Inserts something like this into PDF 4230 * BT 4231 * /F1 16 Tf % Font name + size 4232 * 16 TL % How many units down for next line in multiline text 4233 * 0 g % color 4234 * 28.35 813.54 Td % position 4235 * (line one) Tj 4236 * T* (line two) Tj 4237 * T* (line three) Tj 4238 * ET 4239 */ 4240 options = options || {}; 4241 var scope = options.scope || this; 4242 var payload, da, angle, align, charSpace, maxWidth, flags, horizontalScale; // Pre-August-2012 the order of arguments was function(x, y, text, flags) 4243 // in effort to make all calls have similar signature like 4244 // function(data, coordinates... , miscellaneous) 4245 // this method had its args flipped. 4246 // code below allows backward compatibility with old arg order. 4247 4248 if (typeof text === "number" && typeof x === "number" && (typeof y === "string" || Array.isArray(y))) { 4249 var tmp = y; 4250 y = x; 4251 x = text; 4252 text = tmp; 4253 } 4254 4255 var transformationMatrix; 4256 4257 if (arguments[3] instanceof Matrix === false) { 4258 flags = arguments[3]; 4259 angle = arguments[4]; 4260 align = arguments[5]; 4261 4262 if (_typeof(flags) !== "object" || flags === null) { 4263 if (typeof angle === "string") { 4264 align = angle; 4265 angle = null; 4266 } 4267 4268 if (typeof flags === "string") { 4269 align = flags; 4270 flags = null; 4271 } 4272
vendor: 50,021 bytes, lines 4273-5764
4273 if (typeof flags === "number") { 4274 angle = flags; 4275 flags = null; 4276 } 4277 4278 options = { 4279 flags: flags, 4280 angle: angle, 4281 align: align 4282 }; 4283 } 4284 } else { 4285 advancedApiModeTrap("The transform parameter of text() with a Matrix value"); 4286 transformationMatrix = transform; 4287 } 4288 4289 if (isNaN(x) || isNaN(y) || typeof text === "undefined" || text === null) { 4290 throw new Error("Invalid arguments passed to jsPDF.text"); 4291 } 4292 4293 if (text.length === 0) { 4294 return scope; 4295 } 4296 4297 var xtra = ""; 4298 var isHex = false; 4299 var lineHeight = typeof options.lineHeightFactor === "number" ? options.lineHeightFactor : lineHeightFactor; 4300 var scaleFactor = scope.internal.scaleFactor; 4301 4302 function ESC(s) { 4303 s = s.split("\t").join(Array(options.TabLen || 9).join(" ")); 4304 return pdfEscape(s, flags); 4305 } 4306 4307 function transformTextToSpecialArray(text) { 4308 //we don't want to destroy original text array, so cloning it 4309 var sa = text.concat(); 4310 var da = []; 4311 var len = sa.length; 4312 var curDa; //we do array.join('text that must not be PDFescaped") 4313 //thus, pdfEscape each component separately 4314 4315 while (len--) { 4316 curDa = sa.shift(); 4317 4318 if (typeof curDa === "string") { 4319 da.push(curDa); 4320 } else { 4321 if (Array.isArray(text) && (curDa.length === 1 || curDa[1] === undefined && curDa[2] === undefined)) { 4322 da.push(curDa[0]); 4323 } else { 4324 da.push([curDa[0], curDa[1], curDa[2]]); 4325 } 4326 } 4327 } 4328 4329 return da; 4330 } 4331 4332 function processTextByFunction(text, processingFunction) { 4333 var result; 4334 4335 if (typeof text === "string") { 4336 result = processingFunction(text)[0]; 4337 } else if (Array.isArray(text)) { 4338 //we don't want to destroy original text array, so cloning it 4339 var sa = text.concat(); 4340 var da = []; 4341 var len = sa.length; 4342 var curDa; 4343 var tmpResult; //we do array.join('text that must not be PDFescaped") 4344 //thus, pdfEscape each component separately 4345 4346 while (len--) { 4347 curDa = sa.shift(); 4348 4349 if (typeof curDa === "string") { 4350 da.push(processingFunction(curDa)[0]); 4351 } else if (Array.isArray(curDa) && typeof curDa[0] === "string") { 4352 tmpResult = processingFunction(curDa[0], curDa[1], curDa[2]); 4353 da.push([tmpResult[0], tmpResult[1], tmpResult[2]]); 4354 } 4355 } 4356 4357 result = da; 4358 } 4359 4360 return result; 4361 } //Check if text is of type String 4362 4363 4364 var textIsOfTypeString = false; 4365 var tmpTextIsOfTypeString = true; 4366 4367 if (typeof text === "string") { 4368 textIsOfTypeString = true; 4369 } else if (Array.isArray(text)) { 4370 //we don't want to destroy original text array, so cloning it 4371 var sa = text.concat(); 4372 da = []; 4373 var len = sa.length; 4374 var curDa; //we do array.join('text that must not be PDFescaped") 4375 //thus, pdfEscape each component separately 4376 4377 while (len--) { 4378 curDa = sa.shift(); 4379 4380 if (typeof curDa !== "string" || Array.isArray(curDa) && typeof curDa[0] !== "string") { 4381 tmpTextIsOfTypeString = false; 4382 } 4383 } 4384 4385 textIsOfTypeString = tmpTextIsOfTypeString; 4386 } 4387 4388 if (textIsOfTypeString === false) { 4389 throw new Error('Type of text must be string or Array. "' + text + '" is not recognized.'); 4390 } //If there are any newlines in text, we assume 4391 //the user wanted to print multiple lines, so break the 4392 //text up into an array. If the text is already an array, 4393 //we assume the user knows what they are doing. 4394 //Convert text into an array anyway to simplify 4395 //later code. 4396 4397 4398 if (typeof text === "string") { 4399 if (text.match(/[\r?\n]/)) { 4400 text = text.split(/\r\n|\r|\n/g); 4401 } else { 4402 text = [text]; 4403 } 4404 } //baseline 4405 4406 4407 var height = activeFontSize / scope.internal.scaleFactor; 4408 var descent = height * (lineHeight - 1); 4409 4410 switch (options.baseline) { 4411 case "bottom": 4412 y -= descent; 4413 break; 4414 4415 case "top": 4416 y += height - descent; 4417 break; 4418 4419 case "hanging": 4420 y += height - 2 * descent; 4421 break; 4422 4423 case "middle": 4424 y += height / 2 - descent; 4425 break; 4426 } //multiline 4427 4428 4429 maxWidth = options.maxWidth || 0; 4430 4431 if (maxWidth > 0) { 4432 if (typeof text === "string") { 4433 text = scope.splitTextToSize(text, maxWidth); 4434 } else if (Object.prototype.toString.call(text) === "[object Array]") { 4435 text = text.reduce(function (acc, textLine) { 4436 return acc.concat(scope.splitTextToSize(textLine, maxWidth)); 4437 }, []); 4438 } 4439 } //creating Payload-Object to make text byRef 4440 4441 4442 payload = { 4443 text: text, 4444 x: x, 4445 y: y, 4446 options: options, 4447 mutex: { 4448 pdfEscape: pdfEscape, 4449 activeFontKey: activeFontKey, 4450 fonts: fonts, 4451 activeFontSize: activeFontSize 4452 } 4453 }; 4454 events.publish("preProcessText", payload); 4455 text = payload.text; 4456 options = payload.options; //angle 4457 4458 angle = options.angle; 4459 4460 if (transformationMatrix instanceof Matrix === false && angle && typeof angle === "number") { 4461 angle *= Math.PI / 180; 4462 4463 if (options.rotationDirection === 0) { 4464 angle = -angle; 4465 } 4466 4467 if (apiMode === ApiMode.ADVANCED) { 4468 angle = -angle; 4469 } 4470 4471 var c = Math.cos(angle); 4472 var s = Math.sin(angle); 4473 transformationMatrix = new Matrix(c, s, -s, c, 0, 0); 4474 } else if (angle && angle instanceof Matrix) { 4475 transformationMatrix = angle; 4476 } 4477 4478 if (apiMode === ApiMode.ADVANCED && !transformationMatrix) { 4479 transformationMatrix = identityMatrix; 4480 } //charSpace 4481 4482 4483 charSpace = options.charSpace || activeCharSpace; 4484 4485 if (typeof charSpace !== "undefined") { 4486 xtra += hpf(scale(charSpace)) + " Tc\n"; 4487 this.setCharSpace(this.getCharSpace() || 0); 4488 } 4489 4490 horizontalScale = options.horizontalScale; 4491 4492 if (typeof horizontalScale !== "undefined") { 4493 xtra += hpf(horizontalScale * 100) + " Tz\n"; 4494 } //lang 4495 4496 4497 var lang = options.lang; 4498 4499 4500 var renderingMode = -1; 4501 var parmRenderingMode = typeof options.renderingMode !== "undefined" ? options.renderingMode : options.stroke; 4502 var pageContext = scope.internal.getCurrentPageInfo().pageContext; 4503 4504 switch (parmRenderingMode) { 4505 case 0: 4506 case false: 4507 case "fill": 4508 renderingMode = 0; 4509 break; 4510 4511 case 1: 4512 case true: 4513 case "stroke": 4514 renderingMode = 1; 4515 break; 4516 4517 case 2: 4518 case "fillThenStroke": 4519 renderingMode = 2; 4520 break; 4521 4522 case 3: 4523 case "invisible": 4524 renderingMode = 3; 4525 break; 4526 4527 case 4: 4528 case "fillAndAddForClipping": 4529 renderingMode = 4; 4530 break; 4531 4532 case 5: 4533 case "strokeAndAddPathForClipping": 4534 renderingMode = 5; 4535 break; 4536 4537 case 6: 4538 case "fillThenStrokeAndAddToPathForClipping": 4539 renderingMode = 6; 4540 break; 4541 4542 case 7: 4543 case "addToPathForClipping": 4544 renderingMode = 7; 4545 break; 4546 } 4547 4548 var usedRenderingMode = typeof pageContext.usedRenderingMode !== "undefined" ? pageContext.usedRenderingMode : -1; //if the coder wrote it explicitly to use a specific 4549 //renderingMode, then use it 4550 4551 if (renderingMode !== -1) { 4552 xtra += renderingMode + " Tr\n"; //otherwise check if we used the rendering Mode already 4553 //if so then set the rendering Mode... 4554 } else if (usedRenderingMode !== -1) { 4555 xtra += "0 Tr\n"; 4556 } 4557 4558 if (renderingMode !== -1) { 4559 pageContext.usedRenderingMode = renderingMode; 4560 } //align 4561 4562 4563 align = options.align || "left"; 4564 var leading = activeFontSize * lineHeight; 4565 var pageWidth = scope.internal.pageSize.getWidth(); 4566 var activeFont = fonts[activeFontKey]; 4567 charSpace = options.charSpace || activeCharSpace; 4568 maxWidth = options.maxWidth || 0; 4569 var lineWidths; 4570 flags = Object.assign({ 4571 autoencode: true, 4572 noBOM: true 4573 }, options.flags); 4574 var wordSpacingPerLine = []; 4575 4576 if (Object.prototype.toString.call(text) === "[object Array]") { 4577 da = transformTextToSpecialArray(text); 4578 var newY; 4579 4580 if (align !== "left") { 4581 lineWidths = da.map(function (v) { 4582 return scope.getStringUnitWidth(v, { 4583 font: activeFont, 4584 charSpace: charSpace, 4585 fontSize: activeFontSize, 4586 doKerning: false 4587 }) * activeFontSize / scaleFactor; 4588 }); 4589 } //The first line uses the "main" Td setting, 4590 //and the subsequent lines are offset by the 4591 //previous line's x coordinate. 4592 4593 4594 var prevWidth = 0; 4595 var newX; 4596 4597 if (align === "right") { 4598 //The passed in x coordinate defines the 4599 //rightmost point of the text. 4600 x -= lineWidths[0]; 4601 text = []; 4602 len = da.length; 4603 4604 for (var i = 0; i < len; i++) { 4605 if (i === 0) { 4606 newX = getHorizontalCoordinate(x); 4607 newY = getVerticalCoordinate(y); 4608 } else { 4609 newX = scale(prevWidth - lineWidths[i]); 4610 newY = -leading; 4611 } 4612 4613 text.push([da[i], newX, newY]); 4614 prevWidth = lineWidths[i]; 4615 } 4616 } else if (align === "center") { 4617 //The passed in x coordinate defines 4618 //the center point. 4619 x -= lineWidths[0] / 2; 4620 text = []; 4621 len = da.length; 4622 4623 for (var j = 0; j < len; j++) { 4624 if (j === 0) { 4625 newX = getHorizontalCoordinate(x); 4626 newY = getVerticalCoordinate(y); 4627 } else { 4628 newX = scale((prevWidth - lineWidths[j]) / 2); 4629 newY = -leading; 4630 } 4631 4632 text.push([da[j], newX, newY]); 4633 prevWidth = lineWidths[j]; 4634 } 4635 } else if (align === "left") { 4636 text = []; 4637 len = da.length; 4638 4639 for (var h = 0; h < len; h++) { 4640 text.push(da[h]); 4641 } 4642 } else if (align === "justify") { 4643 text = []; 4644 len = da.length; 4645 maxWidth = maxWidth !== 0 ? maxWidth : pageWidth; 4646 4647 for (var l = 0; l < len; l++) { 4648 newY = l === 0 ? getVerticalCoordinate(y) : -leading; 4649 newX = l === 0 ? getHorizontalCoordinate(x) : 0; 4650 4651 if (l < len - 1) { 4652 wordSpacingPerLine.push(hpf(scale((maxWidth - lineWidths[l]) / (da[l].split(" ").length - 1)))); 4653 } else { 4654 wordSpacingPerLine.push(0); 4655 } 4656 4657 text.push([da[l], newX, newY]); 4658 } 4659 } else { 4660 throw new Error('Unrecognized alignment option, use "left", "center", "right" or "justify".'); 4661 } 4662 } //R2L 4663 4664 4665 var doReversing = typeof options.R2L === "boolean" ? options.R2L : R2L; 4666 4667 if (doReversing === true) { 4668 text = processTextByFunction(text, function (text, posX, posY) { 4669 return [text.split("").reverse().join(""), posX, posY]; 4670 }); 4671 } //creating Payload-Object to make text byRef 4672 4673 4674 payload = { 4675 text: text, 4676 x: x, 4677 y: y, 4678 options: options, 4679 mutex: { 4680 pdfEscape: pdfEscape, 4681 activeFontKey: activeFontKey, 4682 fonts: fonts, 4683 activeFontSize: activeFontSize 4684 } 4685 }; 4686 events.publish("postProcessText", payload); 4687 text = payload.text; 4688 isHex = payload.mutex.isHex || false; //Escaping 4689 4690 var activeFontEncoding = fonts[activeFontKey].encoding; 4691 4692 if (activeFontEncoding === "WinAnsiEncoding" || activeFontEncoding === "StandardEncoding") { 4693 text = processTextByFunction(text, function (text, posX, posY) { 4694 return [ESC(text), posX, posY]; 4695 }); 4696 } 4697 4698 da = transformTextToSpecialArray(text); 4699 text = []; 4700 var STRING = 0; 4701 var ARRAY = 1; 4702 var variant = Array.isArray(da[0]) ? ARRAY : STRING; 4703 var posX; 4704 var posY; 4705 var content; 4706 var wordSpacing = ""; 4707 4708 var generatePosition = function generatePosition(parmPosX, parmPosY, parmTransformationMatrix) { 4709 var position = ""; 4710 4711 if (parmTransformationMatrix instanceof Matrix) { 4712 // It is kind of more intuitive to apply a plain rotation around the text anchor set by x and y 4713 // but when the user supplies an arbitrary transformation matrix, the x and y offsets should be applied 4714 // in the coordinate system established by this matrix 4715 if (typeof options.angle === "number") { 4716 parmTransformationMatrix = matrixMult(parmTransformationMatrix, new Matrix(1, 0, 0, 1, parmPosX, parmPosY)); 4717 } else { 4718 parmTransformationMatrix = matrixMult(new Matrix(1, 0, 0, 1, parmPosX, parmPosY), parmTransformationMatrix); 4719 } 4720 4721 if (apiMode === ApiMode.ADVANCED) { 4722 parmTransformationMatrix = matrixMult(new Matrix(1, 0, 0, -1, 0, 0), parmTransformationMatrix); 4723 } 4724 4725 position = parmTransformationMatrix.join(" ") + " Tm\n"; 4726 } else { 4727 position = hpf(parmPosX) + " " + hpf(parmPosY) + " Td\n"; 4728 } 4729 4730 return position; 4731 }; 4732 4733 for (var lineIndex = 0; lineIndex < da.length; lineIndex++) { 4734 wordSpacing = ""; 4735 4736 switch (variant) { 4737 case ARRAY: 4738 content = (isHex ? "<" : "(") + da[lineIndex][0] + (isHex ? ">" : ")"); 4739 posX = parseFloat(da[lineIndex][1]); 4740 posY = parseFloat(da[lineIndex][2]); 4741 break; 4742 4743 case STRING: 4744 content = (isHex ? "<" : "(") + da[lineIndex] + (isHex ? ">" : ")"); 4745 posX = getHorizontalCoordinate(x); 4746 posY = getVerticalCoordinate(y); 4747 break; 4748 } 4749 4750 if (typeof wordSpacingPerLine !== "undefined" && typeof wordSpacingPerLine[lineIndex] !== "undefined") { 4751 wordSpacing = wordSpacingPerLine[lineIndex] + " Tw\n"; 4752 } 4753 4754 if (lineIndex === 0) { 4755 text.push(wordSpacing + generatePosition(posX, posY, transformationMatrix) + content); 4756 } else if (variant === STRING) { 4757 text.push(wordSpacing + content); 4758 } else if (variant === ARRAY) { 4759 text.push(wordSpacing + generatePosition(posX, posY, transformationMatrix) + content); 4760 } 4761 } 4762 4763 text = variant === STRING ? text.join(" Tj\nT* ") : text.join(" Tj\n"); 4764 text += " Tj\n"; 4765 var result = "BT\n/"; 4766 result += activeFontKey + " " + activeFontSize + " Tf\n"; // font face, style, size 4767 4768 result += hpf(activeFontSize * lineHeight) + " TL\n"; // line spacing 4769 4770 result += textColor + "\n"; 4771 result += xtra; 4772 result += text; 4773 result += "ET"; 4774 out(result); 4775 usedFonts[activeFontKey] = true; 4776 return scope; 4777 }; // PDF supports these path painting and clip path operators: 4778 // 4779 // S - stroke 4780 // s - close/stroke 4781 // f (F) - fill non-zero 4782 // f* - fill evenodd 4783 // B - fill stroke nonzero 4784 // B* - fill stroke evenodd 4785 // b - close fill stroke nonzero 4786 // b* - close fill stroke evenodd 4787 // n - nothing (consume path) 4788 // W - clip nonzero 4789 // W* - clip evenodd 4790 // 4791 // In order to keep the API small, we omit the close-and-fill/stroke operators and provide a separate close() 4792 // method. 4793 4794 /** 4795 * 4796 * @name clip 4797 * @function 4798 * @instance 4799 * @param {string} rule Only possible value is 'evenodd' 4800 * @returns {jsPDF} 4801 * @memberof jsPDF# 4802 * @description All .clip() after calling drawing ops with a style argument of null. 4803 */ 4804 4805 4806 var clip = API.__private__.clip = API.clip = function (rule) { 4807 // Call .clip() after calling drawing ops with a style argument of null 4808 // W is the PDF clipping op 4809 if ("evenodd" === rule) { 4810 out("W*"); 4811 } else { 4812 out("W"); 4813 } 4814 4815 return this; 4816 }; 4817 /** 4818 * @name clipEvenOdd 4819 * @function 4820 * @instance 4821 * @returns {jsPDF} 4822 * @memberof jsPDF# 4823 * @description Modify the current clip path by intersecting it with the current path using the even-odd rule. Note 4824 * that this will NOT consume the current path. In order to only use this path for clipping call 4825 * {@link API.discardPath} afterwards. 4826 */ 4827 4828 4829 API.clipEvenOdd = function () { 4830 return clip("evenodd"); 4831 }; 4832 /** 4833 * Consumes the current path without any effect. Mainly used in combination with {@link clip} or 4834 * {@link clipEvenOdd}. The PDF "n" operator. 4835 * @name discardPath 4836 * @function 4837 * @instance 4838 * @returns {jsPDF} 4839 * @memberof jsPDF# 4840 */ 4841 4842 4843 API.__private__.discardPath = API.discardPath = function () { 4844 out("n"); 4845 return this; 4846 }; 4847 4848 var isValidStyle = API.__private__.isValidStyle = function (style) { 4849 var validStyleVariants = [undefined, null, "S", "D", "F", "DF", "FD", "f", "f*", "B", "B*", "n"]; 4850 var result = false; 4851 4852 if (validStyleVariants.indexOf(style) !== -1) { 4853 result = true; 4854 } 4855 4856 return result; 4857 }; 4858 4859 API.__private__.setDefaultPathOperation = API.setDefaultPathOperation = function (operator) { 4860 if (isValidStyle(operator)) { 4861 defaultPathOperation = operator; 4862 } 4863 4864 return this; 4865 }; 4866 4867 var getStyle = API.__private__.getStyle = API.getStyle = function (style) { 4868 // see path-painting operators in PDF spec 4869 var op = defaultPathOperation; // stroke 4870 4871 switch (style) { 4872 case "D": 4873 case "S": 4874 op = "S"; // stroke 4875 4876 break; 4877 4878 case "F": 4879 op = "f"; // fill 4880 4881 break; 4882 4883 case "FD": 4884 case "DF": 4885 op = "B"; 4886 break; 4887 4888 case "f": 4889 case "f*": 4890 case "B": 4891 case "B*": 4892 /* 4893 Allow direct use of these PDF path-painting operators: 4894 - f fill using nonzero winding number rule 4895 - f* fill using even-odd rule 4896 - B fill then stroke with fill using non-zero winding number rule 4897 - B* fill then stroke with fill using even-odd rule 4898 */ 4899 op = style; 4900 break; 4901 } 4902 4903 return op; 4904 }; 4905 /** 4906 * Close the current path. The PDF "h" operator. 4907 * @name close 4908 * @function 4909 * @instance 4910 * @returns {jsPDF} 4911 * @memberof jsPDF# 4912 */ 4913 4914 4915 var close = API.close = function () { 4916 out("h"); 4917 return this; 4918 }; 4919 /** 4920 * Stroke the path. The PDF "S" operator. 4921 * @name stroke 4922 * @function 4923 * @instance 4924 * @returns {jsPDF} 4925 * @memberof jsPDF# 4926 */ 4927 4928 4929 API.stroke = function () { 4930 out("S"); 4931 return this; 4932 }; 4933 /** 4934 * Fill the current path using the nonzero winding number rule. If a pattern is provided, the path will be filled 4935 * with this pattern, otherwise with the current fill color. Equivalent to the PDF "f" operator. 4936 * @name fill 4937 * @function 4938 * @instance 4939 * @param {PatternData=} pattern If provided the path will be filled with this pattern 4940 * @returns {jsPDF} 4941 * @memberof jsPDF# 4942 */ 4943 4944 4945 API.fill = function (pattern) { 4946 fillWithOptionalPattern("f", pattern); 4947 return this; 4948 }; 4949 /** 4950 * Fill the current path using the even-odd rule. The PDF f* operator. 4951 * @see API.fill 4952 * @name fillEvenOdd 4953 * @function 4954 * @instance 4955 * @param {PatternData=} pattern If provided the path will be filled with this pattern 4956 * @returns {jsPDF} 4957 * @memberof jsPDF# 4958 */ 4959 4960 4961 API.fillEvenOdd = function (pattern) { 4962 fillWithOptionalPattern("f*", pattern); 4963 return this; 4964 }; 4965 /** 4966 * Fill using the nonzero winding number rule and then stroke the current Path. The PDF "B" operator. 4967 * @see API.fill 4968 * @name fillStroke 4969 * @function 4970 * @instance 4971 * @param {PatternData=} pattern If provided the path will be stroked with this pattern 4972 * @returns {jsPDF} 4973 * @memberof jsPDF# 4974 */ 4975 4976 4977 API.fillStroke = function (pattern) { 4978 fillWithOptionalPattern("B", pattern); 4979 return this; 4980 }; 4981 /** 4982 * Fill using the even-odd rule and then stroke the current Path. The PDF "B" operator. 4983 * @see API.fill 4984 * @name fillStrokeEvenOdd 4985 * @function 4986 * @instance 4987 * @param {PatternData=} pattern If provided the path will be fill-stroked with this pattern 4988 * @returns {jsPDF} 4989 * @memberof jsPDF# 4990 */ 4991 4992 4993 API.fillStrokeEvenOdd = function (pattern) { 4994 fillWithOptionalPattern("B*", pattern); 4995 return this; 4996 }; 4997 4998 var fillWithOptionalPattern = function fillWithOptionalPattern(style, pattern) { 4999 if (_typeof(pattern) === "object") { 5000 fillWithPattern(pattern, style); 5001 } else { 5002 out(style); 5003 } 5004 }; 5005 5006 var putStyle = function putStyle(style) { 5007 if (style === null || apiMode === ApiMode.ADVANCED && style === undefined) { 5008 return; 5009 } 5010 5011 style = getStyle(style); // stroking / filling / both the path 5012 5013 out(style); 5014 }; 5015 5016 function cloneTilingPattern(patternKey, boundingBox, xStep, yStep, matrix) { 5017 var clone = new TilingPattern(boundingBox || this.boundingBox, xStep || this.xStep, yStep || this.yStep, this.gState, matrix || this.matrix); 5018 clone.stream = this.stream; 5019 var key = patternKey + "$$" + this.cloneIndex++ + "$$"; 5020 addPattern(key, clone); 5021 return clone; 5022 } 5023 5024 var fillWithPattern = function fillWithPattern(patternData, style) { 5025 var patternId = patternMap[patternData.key]; 5026 var pattern = patterns[patternId]; 5027 5028 if (pattern instanceof ShadingPattern) { 5029 out("q"); 5030 out(clipRuleFromStyle(style)); 5031 5032 if (pattern.gState) { 5033 API.setGState(pattern.gState); 5034 } 5035 5036 out(patternData.matrix.toString() + " cm"); 5037 out("/" + patternId + " sh"); 5038 out("Q"); 5039 } else if (pattern instanceof TilingPattern) { 5040 // pdf draws patterns starting at the bottom left corner and they are not affected by the global transformation, 5041 // so we must flip them 5042 var matrix = new Matrix(1, 0, 0, -1, 0, getPageHeight()); 5043 5044 if (patternData.matrix) { 5045 matrix = matrix.multiply(patternData.matrix || identityMatrix); // we cannot apply a matrix to the pattern on use so we must abuse the pattern matrix and create new instances 5046 // for each use 5047 5048 patternId = cloneTilingPattern.call(pattern, patternData.key, patternData.boundingBox, patternData.xStep, patternData.yStep, matrix).id; 5049 } 5050 5051 out("q"); 5052 out("/Pattern cs"); 5053 out("/" + patternId + " scn"); 5054 5055 if (pattern.gState) { 5056 API.setGState(pattern.gState); 5057 } 5058 5059 out(style); 5060 out("Q"); 5061 } 5062 }; 5063 5064 var clipRuleFromStyle = function clipRuleFromStyle(style) { 5065 switch (style) { 5066 case "f": 5067 case "F": 5068 return "W n"; 5069 5070 case "f*": 5071 return "W* n"; 5072 5073 case "B": 5074 return "W S"; 5075 5076 case "B*": 5077 return "W* S"; 5078 // these two are for compatibility reasons (in the past, calling any primitive method with a shading pattern 5079 // and "n"/"S" as style would still fill/fill and stroke the path) 5080 5081 case "S": 5082 return "W S"; 5083 5084 case "n": 5085 return "W n"; 5086 } 5087 }; 5088 /** 5089 * Begin a new subpath by moving the current point to coordinates (x, y). The PDF "m" operator. 5090 * @param {number} x 5091 * @param {number} y 5092 * @name moveTo 5093 * @function 5094 * @instance 5095 * @memberof jsPDF# 5096 * @returns {jsPDF} 5097 */ 5098 5099 5100 var moveTo = API.moveTo = function (x, y) { 5101 out(hpf(scale(x)) + " " + hpf(transformScaleY(y)) + " m"); 5102 return this; 5103 }; 5104 /** 5105 * Append a straight line segment from the current point to the point (x, y). The PDF "l" operator. 5106 * @param {number} x 5107 * @param {number} y 5108 * @memberof jsPDF# 5109 * @name lineTo 5110 * @function 5111 * @instance 5112 * @memberof jsPDF# 5113 * @returns {jsPDF} 5114 */ 5115 5116 5117 var lineTo = API.lineTo = function (x, y) { 5118 out(hpf(scale(x)) + " " + hpf(transformScaleY(y)) + " l"); 5119 return this; 5120 }; 5121 /** 5122 * Append a cubic Bézier curve to the current path. The curve shall extend from the current point to the point 5123 * (x3, y3), using (x1, y1) and (x2, y2) as Bézier control points. The new current point shall be (x3, x3). 5124 * @param {number} x1 5125 * @param {number} y1 5126 * @param {number} x2 5127 * @param {number} y2 5128 * @param {number} x3 5129 * @param {number} y3 5130 * @memberof jsPDF# 5131 * @name curveTo 5132 * @function 5133 * @instance 5134 * @memberof jsPDF# 5135 * @returns {jsPDF} 5136 */ 5137 5138 5139 var curveTo = API.curveTo = function (x1, y1, x2, y2, x3, y3) { 5140 out([hpf(scale(x1)), hpf(transformScaleY(y1)), hpf(scale(x2)), hpf(transformScaleY(y2)), hpf(scale(x3)), hpf(transformScaleY(y3)), "c"].join(" ")); 5141 return this; 5142 }; 5143 /** 5144 * Draw a line on the current page. 5145 * 5146 * @name line 5147 * @function 5148 * @instance 5149 * @param {number} x1 5150 * @param {number} y1 5151 * @param {number} x2 5152 * @param {number} y2 5153 * @param {string} style A string specifying the painting style or null. Valid styles include: 'S' [default] - stroke, 'F' - fill, and 'DF' (or 'FD') - fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument. default: 'S' 5154 * @returns {jsPDF} 5155 * @memberof jsPDF# 5156 */ 5157 5158 5159 API.__private__.line = API.line = function (x1, y1, x2, y2, style) { 5160 if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2) || !isValidStyle(style)) { 5161 throw new Error("Invalid arguments passed to jsPDF.line"); 5162 } 5163 5164 if (apiMode === ApiMode.COMPAT) { 5165 return this.lines([[x2 - x1, y2 - y1]], x1, y1, [1, 1], style || "S"); 5166 } else { 5167 return this.lines([[x2 - x1, y2 - y1]], x1, y1, [1, 1]).stroke(); 5168 } 5169 }; 5170 /** 5171 * @typedef {Object} PatternData 5172 * {Matrix|undefined} matrix 5173 * {Number|undefined} xStep 5174 * {Number|undefined} yStep 5175 * {Array.<Number>|undefined} boundingBox 5176 */ 5177 5178 /** 5179 * Adds series of curves (straight lines or cubic bezier curves) to canvas, starting at `x`, `y` coordinates. 5180 * All data points in `lines` are relative to last line origin. 5181 * `x`, `y` become x1,y1 for first line / curve in the set. 5182 * For lines you only need to specify [x2, y2] - (ending point) vector against x1, y1 starting point. 5183 * For bezier curves you need to specify [x2,y2,x3,y3,x4,y4] - vectors to control points 1, 2, ending point. All vectors are against the start of the curve - x1,y1. 5184 * 5185 * @example .lines([[2,2],[-2,2],[1,1,2,2,3,3],[2,1]], 212,110, [1,1], 'F', false) // line, line, bezier curve, line 5186 * @param {Array} lines Array of *vector* shifts as pairs (lines) or sextets (cubic bezier curves). 5187 * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page 5188 * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page 5189 * @param {number} scale (Defaults to [1.0,1.0]) x,y Scaling factor for all vectors. Elements can be any floating number Sub-one makes drawing smaller. Over-one grows the drawing. Negative flips the direction. 5190 * @param {string=} style A string specifying the painting style or null. Valid styles include: 5191 * 'S' [default] - stroke, 5192 * 'F' - fill, 5193 * and 'DF' (or 'FD') - fill then stroke. 5194 * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple 5195 * method calls. The last drawing method call used to define the shape should not have a null style argument. 5196 * 5197 * In "advanced" API mode this parameter is deprecated. 5198 * @param {Boolean=} closed If true, the path is closed with a straight line from the end of the last curve to the starting point. 5199 * @function 5200 * @instance 5201 * @returns {jsPDF} 5202 * @memberof jsPDF# 5203 * @name lines 5204 */ 5205 5206 5207 API.__private__.lines = API.lines = function (lines, x, y, scale, style, closed) { 5208 var scalex, scaley, i, l, leg, x2, y2, x3, y3, x4, y4, tmp; // Pre-August-2012 the order of arguments was function(x, y, lines, scale, style) 5209 // in effort to make all calls have similar signature like 5210 // function(content, coordinateX, coordinateY , miscellaneous) 5211 // this method had its args flipped. 5212 // code below allows backward compatibility with old arg order. 5213 5214 if (typeof lines === "number") { 5215 tmp = y; 5216 y = x; 5217 x = lines; 5218 lines = tmp; 5219 } 5220 5221 scale = scale || [1, 1]; 5222 closed = closed || false; 5223 5224 if (isNaN(x) || isNaN(y) || !Array.isArray(lines) || !Array.isArray(scale) || !isValidStyle(style) || typeof closed !== "boolean") { 5225 throw new Error("Invalid arguments passed to jsPDF.lines"); 5226 } // starting point 5227 5228 5229 moveTo(x, y); 5230 scalex = scale[0]; 5231 scaley = scale[1]; 5232 l = lines.length; //, x2, y2 // bezier only. In page default measurement "units", *after* scaling 5233 //, x3, y3 // bezier only. In page default measurement "units", *after* scaling 5234 // ending point for all, lines and bezier. . In page default measurement "units", *after* scaling 5235 5236 x4 = x; // last / ending point = starting point for first item. 5237 5238 y4 = y; // last / ending point = starting point for first item. 5239 5240 for (i = 0; i < l; i++) { 5241 leg = lines[i]; 5242 5243 if (leg.length === 2) { 5244 // simple line 5245 x4 = leg[0] * scalex + x4; // here last x4 was prior ending point 5246 5247 y4 = leg[1] * scaley + y4; // here last y4 was prior ending point 5248 5249 lineTo(x4, y4); 5250 } else { 5251 // bezier curve 5252 x2 = leg[0] * scalex + x4; // here last x4 is prior ending point 5253 5254 y2 = leg[1] * scaley + y4; // here last y4 is prior ending point 5255 5256 x3 = leg[2] * scalex + x4; // here last x4 is prior ending point 5257 5258 y3 = leg[3] * scaley + y4; // here last y4 is prior ending point 5259 5260 x4 = leg[4] * scalex + x4; // here last x4 was prior ending point 5261 5262 y4 = leg[5] * scaley + y4; // here last y4 was prior ending point 5263 5264 curveTo(x2, y2, x3, y3, x4, y4); 5265 } 5266 } 5267 5268 if (closed) { 5269 close(); 5270 } 5271 5272 putStyle(style); 5273 return this; 5274 }; 5275 /** 5276 * Similar to {@link API.lines} but all coordinates are interpreted as absolute coordinates instead of relative. 5277 * @param {Array<Object>} lines An array of {op: operator, c: coordinates} object, where op is one of "m" (move to), "l" (line to) 5278 * "c" (cubic bezier curve) and "h" (close (sub)path)). c is an array of coordinates. "m" and "l" expect two, "c" 5279 * six and "h" an empty array (or undefined). 5280 * @function 5281 * @returns {jsPDF} 5282 * @memberof jsPDF# 5283 * @name path 5284 */ 5285 5286 5287 API.path = function (lines) { 5288 for (var i = 0; i < lines.length; i++) { 5289 var leg = lines[i]; 5290 var coords = leg.c; 5291 5292 switch (leg.op) { 5293 case "m": 5294 moveTo(coords[0], coords[1]); 5295 break; 5296 5297 case "l": 5298 lineTo(coords[0], coords[1]); 5299 break; 5300 5301 case "c": 5302 curveTo.apply(this, coords); 5303 break; 5304 5305 case "h": 5306 close(); 5307 break; 5308 } 5309 } 5310 5311 return this; 5312 }; 5313 /** 5314 * Adds a rectangle to PDF. 5315 * 5316 * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page 5317 * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page 5318 * @param {number} w Width (in units declared at inception of PDF document) 5319 * @param {number} h Height (in units declared at inception of PDF document) 5320 * @param {string=} style A string specifying the painting style or null. Valid styles include: 5321 * 'S' [default] - stroke, 5322 * 'F' - fill, 5323 * and 'DF' (or 'FD') - fill then stroke. 5324 * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple 5325 * method calls. The last drawing method call used to define the shape should not have a null style argument. 5326 * 5327 * In "advanced" API mode this parameter is deprecated. 5328 * @function 5329 * @instance 5330 * @returns {jsPDF} 5331 * @memberof jsPDF# 5332 * @name rect 5333 */ 5334 5335 5336 API.__private__.rect = API.rect = function (x, y, w, h, style) { 5337 if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h) || !isValidStyle(style)) { 5338 throw new Error("Invalid arguments passed to jsPDF.rect"); 5339 } 5340 5341 if (apiMode === ApiMode.COMPAT) { 5342 h = -h; 5343 } 5344 5345 out([hpf(scale(x)), hpf(transformScaleY(y)), hpf(scale(w)), hpf(scale(h)), "re"].join(" ")); 5346 putStyle(style); 5347 return this; 5348 }; 5349 /** 5350 * Adds a triangle to PDF. 5351 * 5352 * @param {number} x1 Coordinate (in units declared at inception of PDF document) against left edge of the page 5353 * @param {number} y1 Coordinate (in units declared at inception of PDF document) against upper edge of the page 5354 * @param {number} x2 Coordinate (in units declared at inception of PDF document) against left edge of the page 5355 * @param {number} y2 Coordinate (in units declared at inception of PDF document) against upper edge of the page 5356 * @param {number} x3 Coordinate (in units declared at inception of PDF document) against left edge of the page 5357 * @param {number} y3 Coordinate (in units declared at inception of PDF document) against upper edge of the page 5358 * @param {string=} style A string specifying the painting style or null. Valid styles include: 5359 * 'S' [default] - stroke, 5360 * 'F' - fill, 5361 * and 'DF' (or 'FD') - fill then stroke. 5362 * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple 5363 * method calls. The last drawing method call used to define the shape should not have a null style argument. 5364 * 5365 * In "advanced" API mode this parameter is deprecated. 5366 * @function 5367 * @instance 5368 * @returns {jsPDF} 5369 * @memberof jsPDF# 5370 * @name triangle 5371 */ 5372 5373 5374 API.__private__.triangle = API.triangle = function (x1, y1, x2, y2, x3, y3, style) { 5375 if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2) || isNaN(x3) || isNaN(y3) || !isValidStyle(style)) { 5376 throw new Error("Invalid arguments passed to jsPDF.triangle"); 5377 } 5378 5379 this.lines([[x2 - x1, y2 - y1], // vector to point 2 5380 [x3 - x2, y3 - y2], // vector to point 3 5381 [x1 - x3, y1 - y3] // closing vector back to point 1 5382 ], x1, y1, // start of path 5383 [1, 1], style, true); 5384 return this; 5385 }; 5386 /** 5387 * Adds a rectangle with rounded corners to PDF. 5388 * 5389 * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page 5390 * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page 5391 * @param {number} w Width (in units declared at inception of PDF document) 5392 * @param {number} h Height (in units declared at inception of PDF document) 5393 * @param {number} rx Radius along x axis (in units declared at inception of PDF document) 5394 * @param {number} ry Radius along y axis (in units declared at inception of PDF document) 5395 * @param {string=} style A string specifying the painting style or null. Valid styles include: 5396 * 'S' [default] - stroke, 5397 * 'F' - fill, 5398 * and 'DF' (or 'FD') - fill then stroke. 5399 * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple 5400 * method calls. The last drawing method call used to define the shape should not have a null style argument. 5401 * 5402 * In "advanced" API mode this parameter is deprecated. 5403 * @function 5404 * @instance 5405 * @returns {jsPDF} 5406 * @memberof jsPDF# 5407 * @name roundedRect 5408 */ 5409 5410 5411 API.__private__.roundedRect = API.roundedRect = function (x, y, w, h, rx, ry, style) { 5412 if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h) || isNaN(rx) || isNaN(ry) || !isValidStyle(style)) { 5413 throw new Error("Invalid arguments passed to jsPDF.roundedRect"); 5414 } 5415 5416 var MyArc = 4 / 3 * (Math.SQRT2 - 1); 5417 rx = Math.min(rx, w * 0.5); 5418 ry = Math.min(ry, h * 0.5); 5419 this.lines([[w - 2 * rx, 0], [rx * MyArc, 0, rx, ry - ry * MyArc, rx, ry], [0, h - 2 * ry], [0, ry * MyArc, -(rx * MyArc), ry, -rx, ry], [-w + 2 * rx, 0], [-(rx * MyArc), 0, -rx, -(ry * MyArc), -rx, -ry], [0, -h + 2 * ry], [0, -(ry * MyArc), rx * MyArc, -ry, rx, -ry]], x + rx, y, // start of path 5420 [1, 1], style, true); 5421 return this; 5422 }; 5423 /** 5424 * Adds an ellipse to PDF. 5425 * 5426 * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page 5427 * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page 5428 * @param {number} rx Radius along x axis (in units declared at inception of PDF document) 5429 * @param {number} ry Radius along y axis (in units declared at inception of PDF document) 5430 * @param {string=} style A string specifying the painting style or null. Valid styles include: 5431 * 'S' [default] - stroke, 5432 * 'F' - fill, 5433 * and 'DF' (or 'FD') - fill then stroke. 5434 * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple 5435 * method calls. The last drawing method call used to define the shape should not have a null style argument. 5436 * 5437 * In "advanced" API mode this parameter is deprecated. 5438 * @function 5439 * @instance 5440 * @returns {jsPDF} 5441 * @memberof jsPDF# 5442 * @name ellipse 5443 */ 5444 5445 5446 API.__private__.ellipse = API.ellipse = function (x, y, rx, ry, style) { 5447 if (isNaN(x) || isNaN(y) || isNaN(rx) || isNaN(ry) || !isValidStyle(style)) { 5448 throw new Error("Invalid arguments passed to jsPDF.ellipse"); 5449 } 5450 5451 var lx = 4 / 3 * (Math.SQRT2 - 1) * rx, 5452 ly = 4 / 3 * (Math.SQRT2 - 1) * ry; 5453 moveTo(x + rx, y); 5454 curveTo(x + rx, y - ly, x + lx, y - ry, x, y - ry); 5455 curveTo(x - lx, y - ry, x - rx, y - ly, x - rx, y); 5456 curveTo(x - rx, y + ly, x - lx, y + ry, x, y + ry); 5457 curveTo(x + lx, y + ry, x + rx, y + ly, x + rx, y); 5458 putStyle(style); 5459 return this; 5460 }; 5461 /** 5462 * Adds an circle to PDF. 5463 * 5464 * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page 5465 * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page 5466 * @param {number} r Radius (in units declared at inception of PDF document) 5467 * @param {string=} style A string specifying the painting style or null. Valid styles include: 5468 * 'S' [default] - stroke, 5469 * 'F' - fill, 5470 * and 'DF' (or 'FD') - fill then stroke. 5471 * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple 5472 * method calls. The last drawing method call used to define the shape should not have a null style argument. 5473 * 5474 * In "advanced" API mode this parameter is deprecated. 5475 * @function 5476 * @instance 5477 * @returns {jsPDF} 5478 * @memberof jsPDF# 5479 * @name circle 5480 */ 5481 5482 5483 API.__private__.circle = API.circle = function (x, y, r, style) { 5484 if (isNaN(x) || isNaN(y) || isNaN(r) || !isValidStyle(style)) { 5485 throw new Error("Invalid arguments passed to jsPDF.circle"); 5486 } 5487 5488 return this.ellipse(x, y, r, r, style); 5489 }; 5490 /** 5491 * Sets text font face, variant for upcoming text elements. 5492 * See output of jsPDF.getFontList() for possible font names, styles. 5493 * 5494 * @param {string} fontName Font name or family. Example: "times". 5495 * @param {string} fontStyle Font style or variant. Example: "italic". 5496 * @param {number | string} fontWeight Weight of the Font. Example: "normal" | 400 5497 * @function 5498 * @instance 5499 * @returns {jsPDF} 5500 * @memberof jsPDF# 5501 * @name setFont 5502 */ 5503 5504 5505 API.setFont = function (fontName, fontStyle, fontWeight) { 5506 if (fontWeight) { 5507 fontStyle = combineFontStyleAndFontWeight(fontStyle, fontWeight); 5508 } 5509 5510 activeFontKey = getFont(fontName, fontStyle, { 5511 disableWarning: false 5512 }); 5513 return this; 5514 }; 5515 /** 5516 * Gets text font face, variant for upcoming text elements. 5517 * 5518 * @function 5519 * @instance 5520 * @returns {Object} 5521 * @memberof jsPDF# 5522 * @name getFont 5523 */ 5524 5525 5526 var getFontEntry = API.__private__.getFont = API.getFont = function () { 5527 return fonts[getFont.apply(API, arguments)]; 5528 }; 5529 /** 5530 * Returns an object - a tree of fontName to fontStyle relationships available to 5531 * active PDF document. 5532 * 5533 * @public 5534 * @function 5535 * @instance 5536 * @returns {Object} Like {'times':['normal', 'italic', ... ], 'arial':['normal', 'bold', ... ], ... } 5537 * @memberof jsPDF# 5538 * @name getFontList 5539 */ 5540 5541 5542 API.__private__.getFontList = API.getFontList = function () { 5543 var list = {}, 5544 fontName, 5545 fontStyle; 5546 5547 for (fontName in fontmap) { 5548 if (fontmap.hasOwnProperty(fontName)) { 5549 list[fontName] = []; 5550 5551 for (fontStyle in fontmap[fontName]) { 5552 if (fontmap[fontName].hasOwnProperty(fontStyle)) { 5553 list[fontName].push(fontStyle); 5554 } 5555 } 5556 } 5557 } 5558 5559 return list; 5560 }; 5561 /** 5562 * Add a custom font to the current instance. 5563 * 5564 * @param {string} postScriptName PDF specification full name for the font. 5565 * @param {string} id PDF-document-instance-specific label assinged to the font. 5566 * @param {string} fontStyle Style of the Font. 5567 * @param {number | string} fontWeight Weight of the Font. 5568 * @param {Object} encoding Encoding_name-to-Font_metrics_object mapping. 5569 * @function 5570 * @instance 5571 * @memberof jsPDF# 5572 * @name addFont 5573 * @returns {string} fontId 5574 */ 5575 5576 5577 API.addFont = function (postScriptName, fontName, fontStyle, fontWeight, encoding) { 5578 var encodingOptions = ["StandardEncoding", "MacRomanEncoding", "Identity-H", "WinAnsiEncoding"]; 5579 5580 if (arguments[3] && encodingOptions.indexOf(arguments[3]) !== -1) { 5581 //IE 11 fix 5582 encoding = arguments[3]; 5583 } else if (arguments[3] && encodingOptions.indexOf(arguments[3]) == -1) { 5584 fontStyle = combineFontStyleAndFontWeight(fontStyle, fontWeight); 5585 } 5586 5587 encoding = encoding || "Identity-H"; 5588 return addFont.call(this, postScriptName, fontName, fontStyle, encoding); 5589 }; 5590 5591 var lineWidth = options.lineWidth || 0.200025; // 2mm 5592 5593 /** 5594 * Gets the line width, default: 0.200025. 5595 * 5596 * @function 5597 * @instance 5598 * @returns {number} lineWidth 5599 * @memberof jsPDF# 5600 * @name getLineWidth 5601 */ 5602 5603 var getLineWidth = API.__private__.getLineWidth = API.getLineWidth = function () { 5604 return lineWidth; 5605 }; 5606 /** 5607 * Sets line width for upcoming lines. 5608 * 5609 * @param {number} width Line width (in units declared at inception of PDF document). 5610 * @function 5611 * @instance 5612 * @returns {jsPDF} 5613 * @memberof jsPDF# 5614 * @name setLineWidth 5615 */ 5616 5617 5618 var setLineWidth = API.__private__.setLineWidth = API.setLineWidth = function (width) { 5619 lineWidth = width; 5620 out(hpf(scale(width)) + " w"); 5621 return this; 5622 }; 5623 /** 5624 * Sets the dash pattern for upcoming lines. 5625 * 5626 * To reset the settings simply call the method without any parameters. 5627 * @param {Array<number>} dashArray An array containing 0-2 numbers. The first number sets the length of the 5628 * dashes, the second number the length of the gaps. If the second number is missing, the gaps are considered 5629 * to be as long as the dashes. An empty array means solid, unbroken lines. 5630 * @param {number} dashPhase The phase lines start with. 5631 * @function 5632 * @instance 5633 * @returns {jsPDF} 5634 * @memberof jsPDF# 5635 * @name setLineDashPattern 5636 */ 5637 5638 5639 API.__private__.setLineDash = jsPDF.API.setLineDash = jsPDF.API.setLineDashPattern = function (dashArray, dashPhase) { 5640 dashArray = dashArray || []; 5641 dashPhase = dashPhase || 0; 5642 5643 if (isNaN(dashPhase) || !Array.isArray(dashArray)) { 5644 throw new Error("Invalid arguments passed to jsPDF.setLineDash"); 5645 } 5646 5647 dashArray = dashArray.map(function (x) { 5648 return hpf(scale(x)); 5649 }).join(" "); 5650 dashPhase = hpf(scale(dashPhase)); 5651 out("[" + dashArray + "] " + dashPhase + " d"); 5652 return this; 5653 }; 5654 5655 var lineHeightFactor; 5656 5657 var getLineHeight = API.__private__.getLineHeight = API.getLineHeight = function () { 5658 return activeFontSize * lineHeightFactor; 5659 }; 5660 5661 API.__private__.getLineHeight = API.getLineHeight = function () { 5662 return activeFontSize * lineHeightFactor; 5663 }; 5664 /** 5665 * Sets the LineHeightFactor of proportion. 5666 * 5667 * @param {number} value LineHeightFactor value. Default: 1.15. 5668 * @function 5669 * @instance 5670 * @returns {jsPDF} 5671 * @memberof jsPDF# 5672 * @name setLineHeightFactor 5673 */ 5674 5675 5676 var setLineHeightFactor = API.__private__.setLineHeightFactor = API.setLineHeightFactor = function (value) { 5677 value = value || 1.15; 5678 5679 if (typeof value === "number") { 5680 lineHeightFactor = value; 5681 } 5682 5683 return this; 5684 }; 5685 /** 5686 * Gets the LineHeightFactor, default: 1.15. 5687 * 5688 * @function 5689 * @instance 5690 * @returns {number} lineHeightFactor 5691 * @memberof jsPDF# 5692 * @name getLineHeightFactor 5693 */ 5694 5695 5696 var getLineHeightFactor = API.__private__.getLineHeightFactor = API.getLineHeightFactor = function () { 5697 return lineHeightFactor; 5698 }; 5699 5700 setLineHeightFactor(options.lineHeight); 5701 5702 var getHorizontalCoordinate = API.__private__.getHorizontalCoordinate = function (value) { 5703 return scale(value); 5704 }; 5705 5706 var getVerticalCoordinate = API.__private__.getVerticalCoordinate = function (value) { 5707 if (apiMode === ApiMode.ADVANCED) { 5708 return value; 5709 } else { 5710 var pageHeight = pagesContext[currentPage].mediaBox.topRightY - pagesContext[currentPage].mediaBox.bottomLeftY; 5711 return pageHeight - scale(value); 5712 } 5713 }; 5714 5715 var getHorizontalCoordinateString = API.__private__.getHorizontalCoordinateString = API.getHorizontalCoordinateString = function (value) { 5716 return hpf(getHorizontalCoordinate(value)); 5717 }; 5718 5719 var getVerticalCoordinateString = API.__private__.getVerticalCoordinateString = API.getVerticalCoordinateString = function (value) { 5720 return hpf(getVerticalCoordinate(value)); 5721 }; 5722 5723 var strokeColor = options.strokeColor || "0 G"; 5724 /** 5725 * Gets the stroke color for upcoming elements. 5726 * 5727 * @function 5728 * @instance 5729 * @returns {string} colorAsHex 5730 * @memberof jsPDF# 5731 * @name getDrawColor 5732 */ 5733 5734 API.__private__.getStrokeColor = API.getDrawColor = function () { 5735 return decodeColorString(strokeColor); 5736 }; 5737 /** 5738 * Sets the stroke color for upcoming elements. 5739 * 5740 * Depending on the number of arguments given, Gray, RGB, or CMYK 5741 * color space is implied. 5742 * 5743 * When only ch1 is given, "Gray" color space is implied and it 5744 * must be a value in the range from 0.00 (solid black) to to 1.00 (white) 5745 * if values are communicated as String types, or in range from 0 (black) 5746 * to 255 (white) if communicated as Number type. 5747 * The RGB-like 0-255 range is provided for backward compatibility. 5748 * 5749 * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each 5750 * value must be in the range from 0.00 (minimum intensity) to to 1.00 5751 * (max intensity) if values are communicated as String types, or 5752 * from 0 (min intensity) to to 255 (max intensity) if values are communicated 5753 * as Number types. 5754 * The RGB-like 0-255 range is provided for backward compatibility. 5755 * 5756 * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each 5757 * value must be a in the range from 0.00 (0% concentration) to to 5758 * 1.00 (100% concentration) 5759 * 5760 * Because JavaScript treats fixed point numbers badly (rounds to 5761 * floating point nearest to binary representation) it is highly advised to 5762 * communicate the fractional numbers as String types, not JavaScript Number type. 5763 * 5764 * @param {Number|String} ch1 Color channel value or {string}
5764 ch1 color value in hexadecimal, example: '#FFFFFF'. 5765 * @param {Number} ch2 Color channel value. 5766 * @param {Number} ch3 Color channel value. 5767 * @param {Number} ch4 Color channel value. 5768 * 5769 * @function 5770 * @instance 5771 * @returns {jsPDF} 5772 * @memberof jsPDF# 5773 * @name setDrawColor 5774 */ 5775 5776 5777 API.__private__.setStrokeColor = API.setDrawColor = function (ch1, ch2, ch3, ch4) { 5778 var options = { 5779 ch1: ch1, 5780 ch2: ch2, 5781 ch3: ch3, 5782 ch4: ch4, 5783 pdfColorType: "draw", 5784 precision: 2 5785 }; 5786 strokeColor = encodeColorString(options); 5787 out(strokeColor); 5788 return this; 5789 }; 5790 5791 var fillColor = options.fillColor || "0 g"; 5792 /** 5793 * Gets the fill color for upcoming elements. 5794 * 5795 * @function 5796 * @instance 5797 * @returns {string} colorAsHex 5798 * @memberof jsPDF# 5799 * @name getFillColor 5800 */ 5801 5802 API.__private__.getFillColor = API.getFillColor = function () { 5803 return decodeColorString(fillColor); 5804 }; 5805 /** 5806 * Sets the fill color for upcoming elements. 5807 * 5808 * Depending on the number of arguments given, Gray, RGB, or CMYK 5809 * color space is implied. 5810 * 5811 * When only ch1 is given, "Gray" color space is implied and it 5812 * must be a value in the range from 0.00 (solid black) to to 1.00 (white) 5813 * if values are communicated as String types, or in range from 0 (black) 5814 * to 255 (white) if communicated as Number type. 5815 * The RGB-like 0-255 range is provided for backward compatibility. 5816 * 5817 * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each 5818 * value must be in the range from 0.00 (minimum intensity) to to 1.00 5819 * (max intensity) if values are communicated as String types, or 5820 * from 0 (min intensity) to to 255 (max intensity) if values are communicated 5821 * as Number types. 5822 * The RGB-like 0-255 range is provided for backward compatibility. 5823 * 5824 * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each 5825 * value must be a in the range from 0.00 (0% concentration) to to 5826 * 1.00 (100% concentration) 5827 * 5828 * Because JavaScript treats fixed point numbers badly (rounds to 5829 * floating point nearest to binary representation) it is highly advised to 5830 * communicate the fractional numbers as String types, not JavaScript Number type. 5831 * 5832 * @param {Number|String} ch1 Color channel value or {string} ch1 color value in hexadecimal, example: '#FFFFFF'. 5833 * @param {Number} ch2 Color channel value. 5834 * @param {Number} ch3 Color channel value. 5835 * @param {Number} ch4 Color channel value. 5836 * 5837 * @function 5838 * @instance 5839 * @returns {jsPDF} 5840 * @memberof jsPDF# 5841 * @name setFillColor 5842 */ 5843 5844 5845 API.__private__.setFillColor = API.setFillColor = function (ch1, ch2, ch3, ch4) { 5846 var options = { 5847 ch1: ch1, 5848 ch2: ch2, 5849 ch3: ch3, 5850 ch4: ch4, 5851 pdfColorType: "fill", 5852 precision: 2 5853 }; 5854 fillColor = encodeColorString(options); 5855 out(fillColor); 5856 return this; 5857 }; 5858 5859 var textColor = options.textColor || "0 g"; 5860 /** 5861 * Gets the text color for upcoming elements. 5862 * 5863 * @function 5864 * @instance 5865 * @returns {string} colorAsHex 5866 * @memberof jsPDF# 5867 * @name getTextColor 5868 */ 5869 5870 var getTextColor = API.__private__.getTextColor = API.getTextColor = function () { 5871 return decodeColorString(textColor); 5872 }; 5873 /** 5874 * Sets the text color for upcoming elements. 5875 * 5876 * Depending on the number of arguments given, Gray, RGB, or CMYK 5877 * color space is implied. 5878 * 5879 * When only ch1 is given, "Gray" color space is implied and it 5880 * must be a value in the range from 0.00 (solid black) to to 1.00 (white) 5881 * if values are communicated as String types, or in range from 0 (black) 5882 * to 255 (white) if communicated as Number type. 5883 * The RGB-like 0-255 range is provided for backward compatibility. 5884 * 5885 * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each 5886 * value must be in the range from 0.00 (minimum intensity) to to 1.00 5887 * (max intensity) if values are communicated as String types, or 5888 * from 0 (min intensity) to to 255 (max intensity) if values are communicated 5889 * as Number types. 5890 * The RGB-like 0-255 range is provided for backward compatibility. 5891 * 5892 * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each 5893 * value must be a in the range from 0.00 (0% concentration) to to 5894 * 1.00 (100% concentration) 5895 * 5896 * Because JavaScript treats fixed point numbers badly (rounds to 5897 * floating point nearest to binary representation) it is highly advised to 5898 * communicate the fractional numbers as String types, not JavaScript Number type. 5899 * 5900 * @param {Number|String} ch1 Color channel value or {string}
vendor: 11,927 bytes, lines 5900-6358
5900 ch1 color value in hexadecimal, example: '#FFFFFF'. 5901 * @param {Number} ch2 Color channel value. 5902 * @param {Number} ch3 Color channel value. 5903 * @param {Number} ch4 Color channel value. 5904 * 5905 * @function 5906 * @instance 5907 * @returns {jsPDF} 5908 * @memberof jsPDF# 5909 * @name setTextColor 5910 */ 5911 5912 5913 API.__private__.setTextColor = API.setTextColor = function (ch1, ch2, ch3, ch4) { 5914 var options = { 5915 ch1: ch1, 5916 ch2: ch2, 5917 ch3: ch3, 5918 ch4: ch4, 5919 pdfColorType: "text", 5920 precision: 3 5921 }; 5922 textColor = encodeColorString(options); 5923 return this; 5924 }; 5925 5926 var activeCharSpace = options.charSpace; 5927 /** 5928 * Get global value of CharSpace. 5929 * 5930 * @function 5931 * @instance 5932 * @returns {number} charSpace 5933 * @memberof jsPDF# 5934 * @name getCharSpace 5935 */ 5936 5937 var getCharSpace = API.__private__.getCharSpace = API.getCharSpace = function () { 5938 return parseFloat(activeCharSpace || 0); 5939 }; 5940 /** 5941 * Set global value of CharSpace. 5942 * 5943 * @param {number} charSpace 5944 * @function 5945 * @instance 5946 * @returns {jsPDF} jsPDF-instance 5947 * @memberof jsPDF# 5948 * @name setCharSpace 5949 */ 5950 5951 5952 API.__private__.setCharSpace = API.setCharSpace = function (charSpace) { 5953 if (isNaN(charSpace)) { 5954 throw new Error("Invalid argument passed to jsPDF.setCharSpace"); 5955 } 5956 5957 activeCharSpace = charSpace; 5958 return this; 5959 }; 5960 5961 var lineCapID = 0; 5962 /** 5963 * Is an Object providing a mapping from human-readable to 5964 * integer flag values designating the varieties of line cap 5965 * and join styles. 5966 * 5967 * @memberof jsPDF# 5968 * @name CapJoinStyles 5969 */ 5970 5971 API.CapJoinStyles = { 5972 0: 0, 5973 butt: 0, 5974 but: 0, 5975 miter: 0, 5976 1: 1, 5977 round: 1, 5978 rounded: 1, 5979 circle: 1, 5980 2: 2, 5981 projecting: 2, 5982 project: 2, 5983 square: 2, 5984 bevel: 2 5985 }; 5986 /** 5987 * Sets the line cap styles. 5988 * See {jsPDF.CapJoinStyles} for variants. 5989 * 5990 * @param {String|Number} style A string or number identifying the type of line cap. 5991 * @function 5992 * @instance 5993 * @returns {jsPDF} 5994 * @memberof jsPDF# 5995 * @name setLineCap 5996 */ 5997 5998 API.__private__.setLineCap = API.setLineCap = function (style) { 5999 var id = API.CapJoinStyles[style]; 6000 6001 if (id === undefined) { 6002 throw new Error("Line cap style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles"); 6003 } 6004 6005 lineCapID = id; 6006 out(id + " J"); 6007 return this; 6008 }; 6009 6010 var lineJoinID = 0; 6011 /** 6012 * Sets the line join styles. 6013 * See {jsPDF.CapJoinStyles} for variants. 6014 * 6015 * @param {String|Number} style A string or number identifying the type of line join. 6016 * @function 6017 * @instance 6018 * @returns {jsPDF} 6019 * @memberof jsPDF# 6020 * @name setLineJoin 6021 */ 6022 6023 API.__private__.setLineJoin = API.setLineJoin = function (style) { 6024 var id = API.CapJoinStyles[style]; 6025 6026 if (id === undefined) { 6027 throw new Error("Line join style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles"); 6028 } 6029 6030 lineJoinID = id; 6031 out(id + " j"); 6032 return this; 6033 }; 6034 /** 6035 * Sets the miterLimit property, which effects the maximum miter length. 6036 * 6037 * @param {number} length The length of the miter 6038 * @function 6039 * @instance 6040 * @returns {jsPDF} 6041 * @memberof jsPDF# 6042 * @name setLineMiterLimit 6043 */ 6044 6045 API.__private__.setLineMiterLimit = API.__private__.setMiterLimit = API.setLineMiterLimit = API.setMiterLimit = function (length) { 6046 length = length || 0; 6047 6048 if (isNaN(length)) { 6049 throw new Error("Invalid argument passed to jsPDF.setLineMiterLimit"); 6050 } 6051 6052 out(hpf(scale(length)) + " M"); 6053 return this; 6054 }; 6055 /** 6056 * An object representing a pdf graphics state. 6057 * @class GState 6058 */ 6059 6060 /** 6061 * 6062 * @param parameters A parameter object that contains all properties this graphics state wants to set. 6063 * Supported are: opacity, stroke-opacity 6064 * @constructor 6065 */ 6066 6067 6068 API.GState = GState; 6069 /** 6070 * Sets a either previously added {@link GState} (via {@link addGState}) or a new {@link GState}. 6071 * @param {String|GState} gState If type is string, a previously added GState is used, if type is GState 6072 * it will be added before use. 6073 * @function 6074 * @returns {jsPDF} 6075 * @memberof jsPDF# 6076 * @name setGState 6077 */ 6078 6079 API.setGState = function (gState) { 6080 if (typeof gState === "string") { 6081 gState = gStates[gStatesMap[gState]]; 6082 } else { 6083 gState = addGState(null, gState); 6084 } 6085 6086 if (!gState.equals(activeGState)) { 6087 out("/" + gState.id + " gs"); 6088 activeGState = gState; 6089 } 6090 }; 6091 /** 6092 * Adds a new Graphics State. Duplicates are automatically eliminated. 6093 * @param {String} key Might also be null, if no later reference to this gState is needed 6094 * @param {Object} gState The gState object 6095 */ 6096 6097 6098 var addGState = function addGState(key, gState) { 6099 // only add it if it is not already present (the keys provided by the user must be unique!) 6100 if (key && gStatesMap[key]) return; 6101 var duplicate = false; 6102 6103 for (var s in gStates) { 6104 if (gStates.hasOwnProperty(s)) { 6105 if (gStates[s].equals(gState)) { 6106 duplicate = true; 6107 break; 6108 } 6109 } 6110 } 6111 6112 if (duplicate) { 6113 gState = gStates[s]; 6114 } else { 6115 var gStateKey = "GS" + (Object.keys(gStates).length + 1).toString(10); 6116 gStates[gStateKey] = gState; 6117 gState.id = gStateKey; 6118 } // several user keys may point to the same GState object 6119 6120 6121 key && (gStatesMap[key] = gState.id); 6122 events.publish("addGState", gState); 6123 return gState; 6124 }; 6125 /** 6126 * Adds a new {@link GState} for later use. See {@link setGState}. 6127 * @param {String} key 6128 * @param {GState} gState 6129 * @function 6130 * @instance 6131 * @returns {jsPDF} 6132 * 6133 * @memberof jsPDF# 6134 * @name addGState 6135 */ 6136 6137 6138 API.addGState = function (key, gState) { 6139 addGState(key, gState); 6140 return this; 6141 }; 6142 /** 6143 * Saves the current graphics state ("pushes it on the stack"). It can be restored by {@link restoreGraphicsState} 6144 * later. Here, the general pdf graphics state is meant, also including the current transformation matrix, 6145 * fill and stroke colors etc. 6146 * @function 6147 * @returns {jsPDF} 6148 * @memberof jsPDF# 6149 * @name saveGraphicsState 6150 */ 6151 6152 6153 API.saveGraphicsState = function () { 6154 out("q"); // as we cannot set font key and size independently we must keep track of both 6155 6156 fontStateStack.push({ 6157 key: activeFontKey, 6158 size: activeFontSize, 6159 color: textColor 6160 }); 6161 return this; 6162 }; 6163 /** 6164 * Restores a previously saved graphics state saved by {@link saveGraphicsState} ("pops the stack"). 6165 * @function 6166 * @returns {jsPDF} 6167 * @memberof jsPDF# 6168 * @name restoreGraphicsState 6169 */ 6170 6171 6172 API.restoreGraphicsState = function () { 6173 out("Q"); // restore previous font state 6174 6175 var fontState = fontStateStack.pop(); 6176 activeFontKey = fontState.key; 6177 activeFontSize = fontState.size; 6178 textColor = fontState.color; 6179 activeGState = null; 6180 return this; 6181 }; 6182 /** 6183 * Appends this matrix to the left of all previously applied matrices. 6184 * 6185 * @param {Matrix} matrix 6186 * @function 6187 * @returns {jsPDF} 6188 * @memberof jsPDF# 6189 * @name setCurrentTransformationMatrix 6190 */ 6191 6192 6193 API.setCurrentTransformationMatrix = function (matrix) { 6194 out(matrix.toString() + " cm"); 6195 return this; 6196 }; 6197 /** 6198 * Inserts a debug comment into the generated pdf. 6199 * @function 6200 * @instance 6201 * @param {String} text 6202 * @returns {jsPDF} 6203 * @memberof jsPDF# 6204 * @name comment 6205 */ 6206 6207 6208 API.comment = function (text) { 6209 out("#" + text); 6210 return this; 6211 }; 6212 /** 6213 * Point 6214 */ 6215 6216 6217 var Point = function Point(x, y) { 6218 var _x = x || 0; 6219 6220 Object.defineProperty(this, "x", { 6221 enumerable: true, 6222 get: function get() { 6223 return _x; 6224 }, 6225 set: function set(value) { 6226 if (!isNaN(value)) { 6227 _x = parseFloat(value); 6228 } 6229 } 6230 }); 6231 6232 var _y = y || 0; 6233 6234 Object.defineProperty(this, "y", { 6235 enumerable: true, 6236 get: function get() { 6237 return _y; 6238 }, 6239 set: function set(value) { 6240 if (!isNaN(value)) { 6241 _y = parseFloat(value); 6242 } 6243 } 6244 }); 6245 var _type = "pt"; 6246 Object.defineProperty(this, "type", { 6247 enumerable: true, 6248 get: function get() { 6249 return _type; 6250 }, 6251 set: function set(value) { 6252 _type = value.toString(); 6253 } 6254 }); 6255 return this; 6256 }; 6257 /** 6258 * Rectangle 6259 */ 6260 6261 6262 var Rectangle = function Rectangle(x, y, w, h) { 6263 Point.call(this, x, y); 6264 this.type = "rect"; 6265 6266 var _w = w || 0; 6267 6268 Object.defineProperty(this, "w", { 6269 enumerable: true, 6270 get: function get() { 6271 return _w; 6272 }, 6273 set: function set(value) { 6274 if (!isNaN(value)) { 6275 _w = parseFloat(value); 6276 } 6277 } 6278 }); 6279 6280 var _h = h || 0; 6281 6282 Object.defineProperty(this, "h", { 6283 enumerable: true, 6284 get: function get() { 6285 return _h; 6286 }, 6287 set: function set(value) { 6288 if (!isNaN(value)) { 6289 _h = parseFloat(value); 6290 } 6291 } 6292 }); 6293 return this; 6294 }; 6295 /** 6296 * FormObject/RenderTarget 6297 */ 6298 6299 6300 var RenderTarget = function RenderTarget() { 6301 this.page = page; 6302 this.currentPage = currentPage; 6303 this.pages = pages.slice(0); 6304 this.pagesContext = pagesContext.slice(0); 6305 this.x = pageX; 6306 this.y = pageY; 6307 this.matrix = pageMatrix; 6308 this.width = getPageWidth(currentPage); 6309 this.height = getPageHeight(currentPage); 6310 this.outputDestination = outputDestination; 6311 this.id = ""; // set by endFormObject() 6312 6313 this.objectNumber = -1; // will be set by putXObject() 6314 }; 6315 6316 RenderTarget.prototype.restore = function () { 6317 page = this.page; 6318 currentPage = this.currentPage; 6319 pagesContext = this.pagesContext; 6320 pages = this.pages; 6321 pageX = this.x; 6322 pageY = this.y; 6323 pageMatrix = this.matrix; 6324 setPageWidth(currentPage, this.width); 6325 setPageHeight(currentPage, this.height); 6326 outputDestination = this.outputDestination; 6327 }; 6328 6329 var beginNewRenderTarget = function beginNewRenderTarget(x, y, width, height, matrix) { 6330 // save current state 6331 renderTargetStack.push(new RenderTarget()); // clear pages 6332 6333 page = currentPage = 0; 6334 pages = []; 6335 pageX = x; 6336 pageY = y; 6337 pageMatrix = matrix; 6338 beginPage([width, height]); 6339 }; 6340 6341 var endFormObject = function endFormObject(key) { 6342 // only add it if it is not already present (the keys provided by the user must be unique!) 6343 if (renderTargetMap[key]) { 6344 renderTargetStack.pop().restore(); 6345 return; 6346 } // save the created xObject 6347 6348 6349 var newXObject = new RenderTarget(); 6350 var xObjectId = "Xo" + (Object.keys(renderTargets).length + 1).toString(10); 6351 newXObject.id = xObjectId; 6352 renderTargetMap[key] = xObjectId; 6353 renderTargets[xObjectId] = newXObject; 6354 events.publish("addFormObject", newXObject); // restore state from stack 6355 6356 renderTargetStack.pop().restore(); 6357 }; 6358 /**
6359 * Starts a new pdf form object, which means that all consequent draw calls target a new independent object 6360 * until {@link endFormObject} is called. The created object can be referenced and drawn later using 6361 * {@link doFormObject}. Nested form objects are possible. 6362 * x, y, width, height set the bounding box that is used to clip the content. 6363 * 6364 * @param {number} x 6365 * @param {number} y 6366 * @param {number} width 6367 * @param {number} height 6368 * @param {Matrix} matrix The matrix that will be applied to convert the form objects coordinate system to 6369 * the parent's. 6370 * @function 6371 * @returns {jsPDF} 6372 * @memberof jsPDF# 6373 * @name beginFormObject 6374 */ 6375 6376 6377 API.beginFormObject = function (x, y, width, height, matrix) { 6378 // The user can set the output target to a new form object. Nested form objects are possible. 6379 // Currently, they use the resource dictionary of the surrounding stream. This should be changed, as 6380 // the PDF-Spec states: 6381 // "In PDF 1.2 and later versions, form XObjects may be independent of the content streams in which 6382 // they appear, and this is strongly recommended although not requiredIn PDF 1.2 and later versions, 6383 // form XObjects may be independent of the content streams in which they appear, and this is strongly 6384 // recommended although not required" 6385 beginNewRenderTarget(x, y, width, height, matrix); 6386 return this; 6387 }; 6388 /** 6389 * Completes and saves the form object. 6390 * @param {String} key The key by which this form object can be referenced. 6391 * @function 6392 * @returns {jsPDF} 6393 * @memberof jsPDF# 6394 * @name endFormObject 6395 */ 6396 6397 6398 API.endFormObject = function (key) { 6399 endFormObject(key); 6400 return this; 6401 }; 6402 /** 6403 * Draws the specified form object by referencing to the respective pdf XObject created with 6404 * {@link API.beginFormObject} and {@link endFormObject}. 6405 * The location is determined by matrix. 6406 * 6407 * @param {String} key The key to the form object. 6408 * @param {Matrix} matrix The matrix applied before drawing the form object. 6409 * @function 6410 * @returns {jsPDF} 6411 * @memberof jsPDF# 6412 * @name doFormObject 6413 */ 6414 6415 6416 API.doFormObject = function (key, matrix) { 6417 var xObject = renderTargets[renderTargetMap[key]]; 6418 out("q"); 6419 out(matrix.toString() + " cm"); 6420 out("/" + xObject.id + " Do"); 6421 out("Q"); 6422 return this; 6423 }; 6424 /** 6425 * Returns the form object specified by key. 6426 * @param key {String} 6427 * @returns {{x: number, y: number, width: number, height: number, matrix: Matrix}} 6428 * @function 6429 * @returns {jsPDF} 6430 * @memberof jsPDF# 6431 * @name getFormObject 6432 */ 6433 6434 6435 API.getFormObject = function (key) { 6436 var xObject = renderTargets[renderTargetMap[key]]; 6437 return { 6438 x: xObject.x, 6439 y: xObject.y, 6440 width: xObject.width, 6441 height: xObject.height, 6442 matrix: xObject.matrix 6443 }; 6444 }; 6445 /** 6446 * Saves as PDF document. An alias of jsPDF.output('save', 'filename.pdf'). 6447 * Uses FileSaver.js-method saveAs. 6448 * 6449 * @memberof jsPDF# 6450 * @name save 6451 * @function 6452 * @instance 6453 * @param {string} filename The filename including extension. 6454 * @param {Object} options An Object with additional options, possible options: 'returnPromise'. 6455 * @returns {jsPDF|Promise} jsPDF-instance */ 6456 6457 6458 API.save = function (filename, options) { 6459 filename = filename || "generated.pdf"; 6460 options = options || {}; 6461 options.returnPromise = options.returnPromise || false; 6462 6463 if (options.returnPromise === false) { 6464 saveAs(getBlob(buildDocument()), filename); 6465 6466 if (typeof saveAs.unload === "function") { 6467 if (globalObject.setTimeout) { 6468 setTimeout(saveAs.unload, 911); 6469 } 6470 } 6471 6472 return this; 6473 } else { 6474 return new Promise(function (resolve, reject) { 6475 try { 6476 var result = saveAs(getBlob(buildDocument()), filename); 6477 6478 if (typeof saveAs.unload === "function") { 6479 if (globalObject.setTimeout) { 6480 setTimeout(saveAs.unload, 911); 6481 } 6482 } 6483 6484 resolve(result); 6485 } catch (e) { 6486 reject(e.message); 6487 } 6488 }); 6489 } 6490 }; // applying plugins (more methods) ON TOP of built-in API. 6491 // this is intentional as we allow plugins to override 6492 // built-ins 6493 6494 6495 for (var plugin in jsPDF.API) { 6496 if (jsPDF.API.hasOwnProperty(plugin)) { 6497 if (plugin === "events" && jsPDF.API.events.length) { 6498 (function (events, newEvents) { 6499 // jsPDF.API.events is a JS Array of Arrays 6500 // where each Array is a pair of event name, handler 6501 // Events were added by plugins to the jsPDF instantiator. 6502 // These are always added to the new instance and some ran 6503 // during instantiation. 6504 var eventname, handler_and_args, i; 6505 6506 for (i = newEvents.length - 1; i !== -1; i--) { 6507 // subscribe takes 3 args: 'topic', function, runonce_flag 6508 // if undefined, runonce is false. 6509 // users can attach callback directly, 6510 // or they can attach an array with [callback, runonce_flag] 6511 // that's what the "apply" magic is for below.
vendor: 66,795 bytes, lines 6512-8851
6512 eventname = newEvents[i][0]; 6513 handler_and_args = newEvents[i][1]; 6514 events.subscribe.apply(events, [eventname].concat(typeof handler_and_args === "function" ? [handler_and_args] : handler_and_args)); 6515 } 6516 })(events, jsPDF.API.events); 6517 } else { 6518 API[plugin] = jsPDF.API[plugin]; 6519 } 6520 } 6521 } 6522 6523 var getPageWidth = API.getPageWidth = function (pageNumber) { 6524 pageNumber = pageNumber || currentPage; 6525 return (pagesContext[pageNumber].mediaBox.topRightX - pagesContext[pageNumber].mediaBox.bottomLeftX) / scaleFactor; 6526 }; 6527 6528 var setPageWidth = API.setPageWidth = function (pageNumber, value) { 6529 pagesContext[pageNumber].mediaBox.topRightX = value * scaleFactor + pagesContext[pageNumber].mediaBox.bottomLeftX; 6530 }; 6531 6532 var getPageHeight = API.getPageHeight = function (pageNumber) { 6533 pageNumber = pageNumber || currentPage; 6534 return (pagesContext[pageNumber].mediaBox.topRightY - pagesContext[pageNumber].mediaBox.bottomLeftY) / scaleFactor; 6535 }; 6536 6537 var setPageHeight = API.setPageHeight = function (pageNumber, value) { 6538 pagesContext[pageNumber].mediaBox.topRightY = value * scaleFactor + pagesContext[pageNumber].mediaBox.bottomLeftY; 6539 }; 6540 /** 6541 * Object exposing internal API to plugins 6542 * @public 6543 * @ignore 6544 */ 6545 6546 6547 API.internal = { 6548 pdfEscape: pdfEscape, 6549 getStyle: getStyle, 6550 getFont: getFontEntry, 6551 getFontSize: getFontSize, 6552 getCharSpace: getCharSpace, 6553 getTextColor: getTextColor, 6554 getLineHeight: getLineHeight, 6555 getLineHeightFactor: getLineHeightFactor, 6556 getLineWidth: getLineWidth, 6557 write: write, 6558 getHorizontalCoordinate: getHorizontalCoordinate, 6559 getVerticalCoordinate: getVerticalCoordinate, 6560 getCoordinateString: getHorizontalCoordinateString, 6561 getVerticalCoordinateString: getVerticalCoordinateString, 6562 collections: {}, 6563 newObject: newObject, 6564 newAdditionalObject: newAdditionalObject, 6565 newObjectDeferred: newObjectDeferred, 6566 newObjectDeferredBegin: newObjectDeferredBegin, 6567 getFilters: getFilters, 6568 putStream: putStream, 6569 events: events, 6570 scaleFactor: scaleFactor, 6571 pageSize: { 6572 getWidth: function getWidth() { 6573 return getPageWidth(currentPage); 6574 }, 6575 setWidth: function setWidth(value) { 6576 setPageWidth(currentPage, value); 6577 }, 6578 getHeight: function getHeight() { 6579 return getPageHeight(currentPage); 6580 }, 6581 setHeight: function setHeight(value) { 6582 setPageHeight(currentPage, value); 6583 } 6584 }, 6585 encryptionOptions: encryptionOptions, 6586 encryption: encryption, 6587 getEncryptor: getEncryptor, 6588 output: output, 6589 getNumberOfPages: getNumberOfPages, 6590 pages: pages, 6591 out: out, 6592 f2: f2, 6593 f3: f3, 6594 getPageInfo: getPageInfo, 6595 getPageInfoByObjId: getPageInfoByObjId, 6596 getCurrentPageInfo: getCurrentPageInfo, 6597 getPDFVersion: getPdfVersion, 6598 Point: Point, 6599 Rectangle: Rectangle, 6600 Matrix: Matrix, 6601 hasHotfix: hasHotfix //Expose the hasHotfix check so plugins can also check them. 6602 6603 }; 6604 Object.defineProperty(API.internal.pageSize, "width", { 6605 get: function get() { 6606 return getPageWidth(currentPage); 6607 }, 6608 set: function set(value) { 6609 setPageWidth(currentPage, value); 6610 }, 6611 enumerable: true, 6612 configurable: true 6613 }); 6614 Object.defineProperty(API.internal.pageSize, "height", { 6615 get: function get() { 6616 return getPageHeight(currentPage); 6617 }, 6618 set: function set(value) { 6619 setPageHeight(currentPage, value); 6620 }, 6621 enumerable: true, 6622 configurable: true 6623 }); ////////////////////////////////////////////////////// 6624 // continuing initialization of jsPDF Document object 6625 ////////////////////////////////////////////////////// 6626 // Add the first page automatically 6627 6628 addFonts.call(API, standardFonts); 6629 activeFontKey = "F1"; 6630 6631 _addPage(format, orientation); 6632 6633 events.publish("initialized"); 6634 return API; 6635 } 6636 /** 6637 * jsPDF.API is a STATIC property of jsPDF class. 6638 * jsPDF.API is an object you can add methods and properties to. 6639 * The methods / properties you add will show up in new jsPDF objects. 6640 * 6641 * One property is prepopulated. It is the 'events' Object. Plugin authors can add topics, 6642 * callbacks to this object. These will be reassigned to all new instances of jsPDF. 6643 * 6644 * @static 6645 * @public 6646 * @memberof jsPDF# 6647 * @name API 6648 * 6649 * @example 6650 * jsPDF.API.mymethod = function(){ 6651 * // 'this' will be ref to internal API object. see jsPDF source 6652 * // , so you can refer to built-in methods like so: 6653 * // this.line(....) 6654 * // this.text(....) 6655 * } 6656 * var pdfdoc = new jsPDF() 6657 * pdfdoc.mymethod() // <- !!!!!! 6658 */ 6659 6660 6661 jsPDF.API = { 6662 events: [] 6663 }; 6664 /** 6665 * The version of jsPDF. 6666 * @name version 6667 * @type {string} 6668 * @memberof jsPDF# 6669 */ 6670 6671 jsPDF.version = "2.5.1"; 6672 6673 var jsPDFAPI = jsPDF.API; 6674 var scaleFactor = 1; 6675 6676 var pdfEscape = function pdfEscape(value) { 6677 return value.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)"); 6678 }; 6679 6680 var pdfUnescape = function pdfUnescape(value) { 6681 return value.replace(/\\\\/g, "\\").replace(/\\\(/g, "(").replace(/\\\)/g, ")"); 6682 }; 6683 6684 var f2 = function f2(number) { 6685 return number.toFixed(2); // Ie, %.2f 6686 }; 6687 6688 var f5 = function f5(number) { 6689 return number.toFixed(5); // Ie, %.2f 6690 }; 6691 6692 jsPDFAPI.__acroform__ = {}; 6693 6694 var inherit = function inherit(child, parent) { 6695 child.prototype = Object.create(parent.prototype); 6696 child.prototype.constructor = child; 6697 }; 6698 6699 var scale = function scale(x) { 6700 return x * scaleFactor; 6701 }; 6702 6703 var createFormXObject = function createFormXObject(formObject) { 6704 var xobj = new AcroFormXObject(); 6705 var height = AcroFormAppearance.internal.getHeight(formObject) || 0; 6706 var width = AcroFormAppearance.internal.getWidth(formObject) || 0; 6707 xobj.BBox = [0, 0, Number(f2(width)), Number(f2(height))]; 6708 return xobj; 6709 }; 6710 /** 6711 * Bit-Operations 6712 */ 6713 6714 6715 var setBit = jsPDFAPI.__acroform__.setBit = function (number, bitPosition) { 6716 number = number || 0; 6717 bitPosition = bitPosition || 0; 6718 6719 if (isNaN(number) || isNaN(bitPosition)) { 6720 throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.setBit"); 6721 } 6722 6723 var bitMask = 1 << bitPosition; 6724 number |= bitMask; 6725 return number; 6726 }; 6727 6728 var clearBit = jsPDFAPI.__acroform__.clearBit = function (number, bitPosition) { 6729 number = number || 0; 6730 bitPosition = bitPosition || 0; 6731 6732 if (isNaN(number) || isNaN(bitPosition)) { 6733 throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.clearBit"); 6734 } 6735 6736 var bitMask = 1 << bitPosition; 6737 number &= ~bitMask; 6738 return number; 6739 }; 6740 6741 var getBit = jsPDFAPI.__acroform__.getBit = function (number, bitPosition) { 6742 if (isNaN(number) || isNaN(bitPosition)) { 6743 throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.getBit"); 6744 } 6745 6746 return (number & 1 << bitPosition) === 0 ? 0 : 1; 6747 }; 6748 /* 6749 * Ff starts counting the bit position at 1 and not like javascript at 0 6750 */ 6751 6752 6753 var getBitForPdf = jsPDFAPI.__acroform__.getBitForPdf = function (number, bitPosition) { 6754 if (isNaN(number) || isNaN(bitPosition)) { 6755 throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.getBitForPdf"); 6756 } 6757 6758 return getBit(number, bitPosition - 1); 6759 }; 6760 6761 var setBitForPdf = jsPDFAPI.__acroform__.setBitForPdf = function (number, bitPosition) { 6762 if (isNaN(number) || isNaN(bitPosition)) { 6763 throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.setBitForPdf"); 6764 } 6765 6766 return setBit(number, bitPosition - 1); 6767 }; 6768 6769 var clearBitForPdf = jsPDFAPI.__acroform__.clearBitForPdf = function (number, bitPosition) { 6770 if (isNaN(number) || isNaN(bitPosition)) { 6771 throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.clearBitForPdf"); 6772 } 6773 6774 return clearBit(number, bitPosition - 1); 6775 }; 6776 6777 var calculateCoordinates = jsPDFAPI.__acroform__.calculateCoordinates = function (args, scope) { 6778 var getHorizontalCoordinate = scope.internal.getHorizontalCoordinate; 6779 var getVerticalCoordinate = scope.internal.getVerticalCoordinate; 6780 var x = args[0]; 6781 var y = args[1]; 6782 var w = args[2]; 6783 var h = args[3]; 6784 var coordinates = {}; 6785 coordinates.lowerLeft_X = getHorizontalCoordinate(x) || 0; 6786 coordinates.lowerLeft_Y = getVerticalCoordinate(y + h) || 0; 6787 coordinates.upperRight_X = getHorizontalCoordinate(x + w) || 0; 6788 coordinates.upperRight_Y = getVerticalCoordinate(y) || 0; 6789 return [Number(f2(coordinates.lowerLeft_X)), Number(f2(coordinates.lowerLeft_Y)), Number(f2(coordinates.upperRight_X)), Number(f2(coordinates.upperRight_Y))]; 6790 }; 6791 6792 var calculateAppearanceStream = function calculateAppearanceStream(formObject) { 6793 if (formObject.appearanceStreamContent) { 6794 return formObject.appearanceStreamContent; 6795 } 6796 6797 if (!formObject.V && !formObject.DV) { 6798 return; 6799 } // else calculate it 6800 6801 6802 var stream = []; 6803 var text = formObject._V || formObject.DV; 6804 var calcRes = calculateX(formObject, text); 6805 var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id; //PDF 32000-1:2008, page 444 6806 6807 stream.push("/Tx BMC"); 6808 stream.push("q"); 6809 stream.push("BT"); // Begin Text 6810 6811 stream.push(formObject.scope.__private__.encodeColorString(formObject.color)); 6812 stream.push("/" + fontKey + " " + f2(calcRes.fontSize) + " Tf"); 6813 stream.push("1 0 0 1 0 0 Tm"); // Transformation Matrix 6814 6815 stream.push(calcRes.text); 6816 stream.push("ET"); // End Text 6817 6818 stream.push("Q"); 6819 stream.push("EMC"); 6820 var appearanceStreamContent = createFormXObject(formObject); 6821 appearanceStreamContent.scope = formObject.scope; 6822 appearanceStreamContent.stream = stream.join("\n"); 6823 return appearanceStreamContent; 6824 }; 6825 6826 var calculateX = function calculateX(formObject, text) { 6827 var maxFontSize = formObject.fontSize === 0 ? formObject.maxFontSize : formObject.fontSize; 6828 var returnValue = { 6829 text: "", 6830 fontSize: "" 6831 }; // Remove Brackets 6832 6833 text = text.substr(0, 1) == "(" ? text.substr(1) : text; 6834 text = text.substr(text.length - 1) == ")" ? text.substr(0, text.length - 1) : text; // split into array of words 6835 6836 var textSplit = text.split(" "); 6837 6838 if (formObject.multiline) { 6839 textSplit = textSplit.map(function (word) { 6840 return word.split("\n"); 6841 }); 6842 } else { 6843 textSplit = textSplit.map(function (word) { 6844 return [word]; 6845 }); 6846 } 6847 6848 var fontSize = maxFontSize; // The Starting fontSize (The Maximum) 6849 6850 var lineSpacing = 2; 6851 var borderPadding = 2; 6852 var height = AcroFormAppearance.internal.getHeight(formObject) || 0; 6853 height = height < 0 ? -height : height; 6854 var width = AcroFormAppearance.internal.getWidth(formObject) || 0; 6855 width = width < 0 ? -width : width; 6856 6857 var isSmallerThanWidth = function isSmallerThanWidth(i, lastLine, fontSize) { 6858 if (i + 1 < textSplit.length) { 6859 var tmp = lastLine + " " + textSplit[i + 1][0]; 6860 var TextWidth = calculateFontSpace(tmp, formObject, fontSize).width; 6861 var FieldWidth = width - 2 * borderPadding; 6862 return TextWidth <= FieldWidth; 6863 } else { 6864 return false; 6865 } 6866 }; 6867 6868 fontSize++; 6869 6870 FontSize: while (fontSize > 0) { 6871 text = ""; 6872 fontSize--; 6873 var textHeight = calculateFontSpace("3", formObject, fontSize).height; 6874 var startY = formObject.multiline ? height - fontSize : (height - textHeight) / 2; 6875 startY += lineSpacing; 6876 var startX; 6877 var lastY = startY; 6878 var firstWordInLine = 0, 6879 lastWordInLine = 0; 6880 var lastLength; 6881 var currWord = 0; 6882 6883 if (fontSize <= 0) { 6884 // In case, the Text doesn't fit at all 6885 fontSize = 12; 6886 text = "(...) Tj\n"; 6887 text += "% Width of Text: " + calculateFontSpace(text, formObject, fontSize).width + ", FieldWidth:" + width + "\n"; 6888 break; 6889 } 6890 6891 var lastLine = ""; 6892 var lineCount = 0; 6893 6894 Line: for (var i = 0; i < textSplit.length; i++) { 6895 if (textSplit.hasOwnProperty(i)) { 6896 var isWithNewLine = false; 6897 6898 if (textSplit[i].length !== 1 && currWord !== textSplit[i].length - 1) { 6899 if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) { 6900 continue FontSize; 6901 } 6902 6903 lastLine += textSplit[i][currWord]; 6904 isWithNewLine = true; 6905 lastWordInLine = i; 6906 i--; 6907 } else { 6908 lastLine += textSplit[i][currWord] + " "; 6909 lastLine = lastLine.substr(lastLine.length - 1) == " " ? lastLine.substr(0, lastLine.length - 1) : lastLine; 6910 var key = parseInt(i); 6911 var nextLineIsSmaller = isSmallerThanWidth(key, lastLine, fontSize); 6912 var isLastWord = i >= textSplit.length - 1; 6913 6914 if (nextLineIsSmaller && !isLastWord) { 6915 lastLine += " "; 6916 currWord = 0; 6917 continue; // Line 6918 } else if (!nextLineIsSmaller && !isLastWord) { 6919 if (!formObject.multiline) { 6920 continue FontSize; 6921 } else { 6922 if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) { 6923 // If the Text is higher than the 6924 // FieldObject 6925 continue FontSize; 6926 } 6927 6928 lastWordInLine = key; // go on 6929 } 6930 } else if (isLastWord) { 6931 lastWordInLine = key; 6932 } else { 6933 if (formObject.multiline && (textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) { 6934 // If the Text is higher than the FieldObject 6935 continue FontSize; 6936 } 6937 } 6938 } // Remove last blank 6939 6940 6941 var line = ""; 6942 6943 for (var x = firstWordInLine; x <= lastWordInLine; x++) { 6944 var currLine = textSplit[x]; 6945 6946 if (formObject.multiline) { 6947 if (x === lastWordInLine) { 6948 line += currLine[currWord] + " "; 6949 currWord = (currWord + 1) % currLine.length; 6950 continue; 6951 } 6952 6953 if (x === firstWordInLine) { 6954 line += currLine[currLine.length - 1] + " "; 6955 continue; 6956 } 6957 } 6958 6959 line += currLine[0] + " "; 6960 } // Remove last blank 6961 6962 6963 line = line.substr(line.length - 1) == " " ? line.substr(0, line.length - 1) : line; // lastLength -= blankSpace.width; 6964 6965 lastLength = calculateFontSpace(line, formObject, fontSize).width; // Calculate startX 6966 6967 switch (formObject.textAlign) { 6968 case "right": 6969 startX = width - lastLength - borderPadding; 6970 break; 6971 6972 case "center": 6973 startX = (width - lastLength) / 2; 6974 break; 6975 6976 case "left": 6977 default: 6978 startX = borderPadding; 6979 break; 6980 } 6981 6982 text += f2(startX) + " " + f2(lastY) + " Td\n"; 6983 text += "(" + pdfEscape(line) + ") Tj\n"; // reset X in PDF 6984 6985 text += -f2(startX) + " 0 Td\n"; // After a Line, adjust y position 6986 6987 lastY = -(fontSize + lineSpacing); // Reset for next iteration step 6988 6989 lastLength = 0; 6990 firstWordInLine = isWithNewLine ? lastWordInLine : lastWordInLine + 1; 6991 lineCount++; 6992 lastLine = ""; 6993 continue Line; 6994 } 6995 } 6996 6997 break; 6998 } 6999 7000 returnValue.text = text; 7001 returnValue.fontSize = fontSize; 7002 return returnValue; 7003 }; 7004 /** 7005 * Small workaround for calculating the TextMetric approximately. 7006 * 7007 * @param text 7008 * @param fontsize 7009 * @returns {TextMetrics} (Has Height and Width) 7010 */ 7011 7012 7013 var calculateFontSpace = function calculateFontSpace(text, formObject, fontSize) { 7014 var font = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle); 7015 var width = formObject.scope.getStringUnitWidth(text, { 7016 font: font, 7017 fontSize: parseFloat(fontSize), 7018 charSpace: 0 7019 }) * parseFloat(fontSize); 7020 var height = formObject.scope.getStringUnitWidth("3", { 7021 font: font, 7022 fontSize: parseFloat(fontSize), 7023 charSpace: 0 7024 }) * parseFloat(fontSize) * 1.5; 7025 return { 7026 height: height, 7027 width: width 7028 }; 7029 }; 7030 7031 var acroformPluginTemplate = { 7032 fields: [], 7033 xForms: [], 7034 7035 /** 7036 * acroFormDictionaryRoot contains information about the AcroForm 7037 * Dictionary 0: The Event-Token, the AcroFormDictionaryCallback has 7038 * 1: The Object ID of the Root 7039 */ 7040 acroFormDictionaryRoot: null, 7041 7042 /** 7043 * After the PDF gets evaluated, the reference to the root has to be 7044 * reset, this indicates, whether the root has already been printed 7045 * out 7046 */ 7047 printedOut: false, 7048 internal: null, 7049 isInitialized: false 7050 }; 7051 7052 var annotReferenceCallback = function annotReferenceCallback(scope) { 7053 //set objId to undefined and force it to get a new objId on buildDocument 7054 scope.internal.acroformPlugin.acroFormDictionaryRoot.objId = undefined; 7055 var fields = scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields; 7056 7057 for (var i in fields) { 7058 if (fields.hasOwnProperty(i)) { 7059 var formObject = fields[i]; //set objId to undefined and force it to get a new objId on buildDocument 7060 7061 formObject.objId = undefined; // add Annot Reference! 7062 7063 if (formObject.hasAnnotation) { 7064 // If theres an Annotation Widget in the Form Object, put the 7065 // Reference in the /Annot array 7066 createAnnotationReference(formObject, scope); 7067 } 7068 } 7069 } 7070 }; 7071 7072 var putForm = function putForm(formObject) { 7073 if (formObject.scope.internal.acroformPlugin.printedOut) { 7074 formObject.scope.internal.acroformPlugin.printedOut = false; 7075 formObject.scope.internal.acroformPlugin.acroFormDictionaryRoot = null; 7076 } 7077 7078 formObject.scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(formObject); 7079 }; 7080 /** 7081 * Create the Reference to the widgetAnnotation, so that it gets referenced 7082 * in the Annot[] int the+ (Requires the Annotation Plugin) 7083 */ 7084 7085 7086 var createAnnotationReference = function createAnnotationReference(object, scope) { 7087 var options = { 7088 type: "reference", 7089 object: object 7090 }; 7091 7092 var findEntry = function findEntry(entry) { 7093 return entry.type === options.type && entry.object === options.object; 7094 }; 7095 7096 if (scope.internal.getPageInfo(object.page).pageContext.annotations.find(findEntry) === undefined) { 7097 scope.internal.getPageInfo(object.page).pageContext.annotations.push(options); 7098 } 7099 }; // Callbacks 7100 7101 7102 var putCatalogCallback = function putCatalogCallback(scope) { 7103 // Put reference to AcroForm to DocumentCatalog 7104 if (typeof scope.internal.acroformPlugin.acroFormDictionaryRoot !== "undefined") { 7105 // for safety, shouldn't normally be the case 7106 scope.internal.write("/AcroForm " + scope.internal.acroformPlugin.acroFormDictionaryRoot.objId + " " + 0 + " R"); 7107 } else { 7108 throw new Error("putCatalogCallback: Root missing."); 7109 } 7110 }; 7111 /** 7112 * Adds /Acroform X 0 R to Document Catalog, and creates the AcroForm 7113 * Dictionary 7114 */ 7115 7116 7117 var AcroFormDictionaryCallback = function AcroFormDictionaryCallback(scope) { 7118 // Remove event 7119 scope.internal.events.unsubscribe(scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID); 7120 delete scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID; 7121 scope.internal.acroformPlugin.printedOut = true; 7122 }; 7123 /** 7124 * Creates the single Fields and writes them into the Document 7125 * 7126 * If fieldArray is set, use the fields that are inside it instead of the 7127 * fields from the AcroRoot (for the FormXObjects...) 7128 */ 7129 7130 7131 var createFieldCallback = function createFieldCallback(fieldArray, scope) { 7132 var standardFields = !fieldArray; 7133 7134 if (!fieldArray) { 7135 // in case there is no fieldArray specified, we want to print out 7136 // the Fields of the AcroForm 7137 // Print out Root 7138 scope.internal.newObjectDeferredBegin(scope.internal.acroformPlugin.acroFormDictionaryRoot.objId, true); 7139 scope.internal.acroformPlugin.acroFormDictionaryRoot.putStream(); 7140 } 7141 7142 fieldArray = fieldArray || scope.internal.acroformPlugin.acroFormDictionaryRoot.Kids; 7143 7144 for (var i in fieldArray) { 7145 if (fieldArray.hasOwnProperty(i)) { 7146 var fieldObject = fieldArray[i]; 7147 var keyValueList = []; 7148 var oldRect = fieldObject.Rect; 7149 7150 if (fieldObject.Rect) { 7151 fieldObject.Rect = calculateCoordinates(fieldObject.Rect, scope); 7152 } // Start Writing the Object 7153 7154 7155 scope.internal.newObjectDeferredBegin(fieldObject.objId, true); 7156 fieldObject.DA = AcroFormAppearance.createDefaultAppearanceStream(fieldObject); 7157 7158 if (_typeof(fieldObject) === "object" && typeof fieldObject.getKeyValueListForStream === "function") { 7159 keyValueList = fieldObject.getKeyValueListForStream(); 7160 } 7161 7162 fieldObject.Rect = oldRect; 7163 7164 if (fieldObject.hasAppearanceStream && !fieldObject.appearanceStreamContent) { 7165 // Calculate Appearance 7166 var appearance = calculateAppearanceStream(fieldObject); 7167 keyValueList.push({ 7168 key: "AP", 7169 value: "<</N " + appearance + ">>" 7170 }); 7171 scope.internal.acroformPlugin.xForms.push(appearance); 7172 } // Assume AppearanceStreamContent is a Array with N,R,D (at least 7173 // one of them!) 7174 7175 7176 if (fieldObject.appearanceStreamContent) { 7177 var appearanceStreamString = ""; // Iterate over N,R and D 7178 7179 for (var k in fieldObject.appearanceStreamContent) { 7180 if (fieldObject.appearanceStreamContent.hasOwnProperty(k)) { 7181 var value = fieldObject.appearanceStreamContent[k]; 7182 appearanceStreamString += "/" + k + " "; 7183 appearanceStreamString += "<<"; 7184 7185 if (Object.keys(value).length >= 1 || Array.isArray(value)) { 7186 // appearanceStream is an Array or Object! 7187 for (var i in value) { 7188 if (value.hasOwnProperty(i)) { 7189 var obj = value[i]; 7190 7191 if (typeof obj === "function") { 7192 // if Function is referenced, call it in order 7193 // to get the FormXObject 7194 obj = obj.call(scope, fieldObject); 7195 } 7196 7197 appearanceStreamString += "/" + i + " " + obj + " "; // In case the XForm is already used, e.g. OffState 7198 // of CheckBoxes, don't add it 7199 7200 if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj); 7201 } 7202 } 7203 } else { 7204 obj = value; 7205 7206 if (typeof obj === "function") { 7207 // if Function is referenced, call it in order to 7208 // get the FormXObject 7209 obj = obj.call(scope, fieldObject); 7210 } 7211 7212 appearanceStreamString += "/" + i + " " + obj; 7213 if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj); 7214 } 7215 7216 appearanceStreamString += ">>"; 7217 } 7218 } // appearance stream is a normal Object.. 7219 7220 7221 keyValueList.push({ 7222 key: "AP", 7223 value: "<<\n" + appearanceStreamString + ">>" 7224 }); 7225 } 7226 7227 scope.internal.putStream({ 7228 additionalKeyValues: keyValueList, 7229 objectId: fieldObject.objId 7230 }); 7231 scope.internal.out("endobj"); 7232 } 7233 } 7234 7235 if (standardFields) { 7236 createXFormObjectCallback(scope.internal.acroformPlugin.xForms, scope); 7237 } 7238 }; 7239 7240 var createXFormObjectCallback = function createXFormObjectCallback(fieldArray, scope) { 7241 for (var i in fieldArray) { 7242 if (fieldArray.hasOwnProperty(i)) { 7243 var key = i; 7244 var fieldObject = fieldArray[i]; // Start Writing the Object 7245 7246 scope.internal.newObjectDeferredBegin(fieldObject.objId, true); 7247 7248 if (_typeof(fieldObject) === "object" && typeof fieldObject.putStream === "function") { 7249 fieldObject.putStream(); 7250 } 7251 7252 delete fieldArray[key]; 7253 } 7254 } 7255 }; 7256 7257 var initializeAcroForm = function initializeAcroForm(scope, formObject) { 7258 formObject.scope = scope; 7259 7260 if (scope.internal !== undefined && (scope.internal.acroformPlugin === undefined || scope.internal.acroformPlugin.isInitialized === false)) { 7261 AcroFormField.FieldNum = 0; 7262 scope.internal.acroformPlugin = JSON.parse(JSON.stringify(acroformPluginTemplate)); 7263 7264 if (scope.internal.acroformPlugin.acroFormDictionaryRoot) { 7265 throw new Error("Exception while creating AcroformDictionary"); 7266 } 7267 7268 scaleFactor = scope.internal.scaleFactor; // The Object Number of the AcroForm Dictionary 7269 7270 scope.internal.acroformPlugin.acroFormDictionaryRoot = new AcroFormDictionary(); 7271 scope.internal.acroformPlugin.acroFormDictionaryRoot.scope = scope; // add Callback for creating the AcroForm Dictionary 7272 7273 scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID = scope.internal.events.subscribe("postPutResources", function () { 7274 AcroFormDictionaryCallback(scope); 7275 }); 7276 scope.internal.events.subscribe("buildDocument", function () { 7277 annotReferenceCallback(scope); 7278 }); // buildDocument 7279 // Register event, that is triggered when the DocumentCatalog is 7280 // written, in order to add /AcroForm 7281 7282 scope.internal.events.subscribe("putCatalog", function () { 7283 putCatalogCallback(scope); 7284 }); // Register event, that creates all Fields 7285 7286 scope.internal.events.subscribe("postPutPages", function (fieldArray) { 7287 createFieldCallback(fieldArray, scope); 7288 }); 7289 scope.internal.acroformPlugin.isInitialized = true; 7290 } 7291 }; //PDF 32000-1:2008, page 26, 7.3.6 7292 7293 7294 var arrayToPdfArray = jsPDFAPI.__acroform__.arrayToPdfArray = function (array, objId, scope) { 7295 var encryptor = function encryptor(data) { 7296 return data; 7297 }; 7298 7299 if (Array.isArray(array)) { 7300 var content = "["; 7301 7302 for (var i = 0; i < array.length; i++) { 7303 if (i !== 0) { 7304 content += " "; 7305 } 7306 7307 switch (_typeof(array[i])) { 7308 case "boolean": 7309 case "number": 7310 case "object": 7311 content += array[i].toString(); 7312 break; 7313 7314 case "string": 7315 if (array[i].substr(0, 1) !== "/") { 7316 if (typeof objId !== "undefined" && scope) encryptor = scope.internal.getEncryptor(objId); 7317 content += "(" + pdfEscape(encryptor(array[i].toString())) + ")"; 7318 } else { 7319 content += array[i].toString(); 7320 } 7321 7322 break; 7323 } 7324 } 7325 7326 content += "]"; 7327 return content; 7328 } 7329 7330 throw new Error("Invalid argument passed to jsPDF.__acroform__.arrayToPdfArray"); 7331 }; 7332 7333 function getMatches(string, regex, index) { 7334 index || (index = 1); // default to the first capturing group 7335 7336 var matches = []; 7337 var match; 7338 7339 while (match = regex.exec(string)) { 7340 matches.push(match[index]); 7341 } 7342 7343 return matches; 7344 } 7345 7346 var pdfArrayToStringArray = function pdfArrayToStringArray(array) { 7347 var result = []; 7348 7349 if (typeof array === "string") { 7350 result = getMatches(array, /\((.*?)\)/g); 7351 } 7352 7353 return result; 7354 }; 7355 7356 var toPdfString = function toPdfString(string, objId, scope) { 7357 var encryptor = function encryptor(data) { 7358 return data; 7359 }; 7360 7361 if (typeof objId !== "undefined" && scope) encryptor = scope.internal.getEncryptor(objId); 7362 string = string || ""; 7363 string.toString(); 7364 string = "(" + pdfEscape(encryptor(string)) + ")"; 7365 return string; 7366 }; // ########################## 7367 // Classes 7368 // ########################## 7369 7370 /** 7371 * @class AcroFormPDFObject 7372 * @classdesc A AcroFormPDFObject 7373 */ 7374 7375 7376 var AcroFormPDFObject = function AcroFormPDFObject() { 7377 this._objId = undefined; 7378 this._scope = undefined; 7379 /** 7380 * @name AcroFormPDFObject#objId 7381 * @type {any} 7382 */ 7383 7384 Object.defineProperty(this, "objId", { 7385 get: function get() { 7386 if (typeof this._objId === "undefined") { 7387 if (typeof this.scope === "undefined") { 7388 return undefined; 7389 } 7390 7391 this._objId = this.scope.internal.newObjectDeferred(); 7392 } 7393 7394 return this._objId; 7395 }, 7396 set: function set(value) { 7397 this._objId = value; 7398 } 7399 }); 7400 Object.defineProperty(this, "scope", { 7401 value: this._scope, 7402 writable: true 7403 }); 7404 }; 7405 /** 7406 * @function AcroFormPDFObject.toString 7407 */ 7408 7409 7410 AcroFormPDFObject.prototype.toString = function () { 7411 return this.objId + " 0 R"; 7412 }; 7413 7414 AcroFormPDFObject.prototype.putStream = function () { 7415 var keyValueList = this.getKeyValueListForStream(); 7416 this.scope.internal.putStream({ 7417 data: this.stream, 7418 additionalKeyValues: keyValueList, 7419 objectId: this.objId 7420 }); 7421 this.scope.internal.out("endobj"); 7422 }; 7423 /** 7424 * Returns an key-value-List of all non-configurable Variables from the Object 7425 * 7426 * @name getKeyValueListForStream 7427 * @returns {string} 7428 */ 7429 7430 7431 AcroFormPDFObject.prototype.getKeyValueListForStream = function () { 7432 var keyValueList = []; 7433 var keys = Object.getOwnPropertyNames(this).filter(function (key) { 7434 return key != "content" && key != "appearanceStreamContent" && key != "scope" && key != "objId" && key.substring(0, 1) != "_"; 7435 }); 7436 7437 for (var i in keys) { 7438 if (Object.getOwnPropertyDescriptor(this, keys[i]).configurable === false) { 7439 var key = keys[i]; 7440 var value = this[key]; 7441 7442 if (value) { 7443 if (Array.isArray(value)) { 7444 keyValueList.push({ 7445 key: key, 7446 value: arrayToPdfArray(value, this.objId, this.scope) 7447 }); 7448 } else if (value instanceof AcroFormPDFObject) { 7449 // In case it is a reference to another PDFObject, 7450 // take the reference number 7451 value.scope = this.scope; 7452 keyValueList.push({ 7453 key: key, 7454 value: value.objId + " 0 R" 7455 }); 7456 } else if (typeof value !== "function") { 7457 keyValueList.push({ 7458 key: key, 7459 value: value 7460 }); 7461 } 7462 } 7463 } 7464 } 7465 7466 return keyValueList; 7467 }; 7468 7469 var AcroFormXObject = function AcroFormXObject() { 7470 AcroFormPDFObject.call(this); 7471 Object.defineProperty(this, "Type", { 7472 value: "/XObject", 7473 configurable: false, 7474 writable: true 7475 }); 7476 Object.defineProperty(this, "Subtype", { 7477 value: "/Form", 7478 configurable: false, 7479 writable: true 7480 }); 7481 Object.defineProperty(this, "FormType", { 7482 value: 1, 7483 configurable: false, 7484 writable: true 7485 }); 7486 var _BBox = []; 7487 Object.defineProperty(this, "BBox", { 7488 configurable: false, 7489 get: function get() { 7490 return _BBox; 7491 }, 7492 set: function set(value) { 7493 _BBox = value; 7494 } 7495 }); 7496 Object.defineProperty(this, "Resources", { 7497 value: "2 0 R", 7498 configurable: false, 7499 writable: true 7500 }); 7501 7502 var _stream; 7503 7504 Object.defineProperty(this, "stream", { 7505 enumerable: false, 7506 configurable: true, 7507 set: function set(value) { 7508 _stream = value.trim(); 7509 }, 7510 get: function get() { 7511 if (_stream) { 7512 return _stream; 7513 } else { 7514 return null; 7515 } 7516 } 7517 }); 7518 }; 7519 7520 inherit(AcroFormXObject, AcroFormPDFObject); 7521 7522 var AcroFormDictionary = function AcroFormDictionary() { 7523 AcroFormPDFObject.call(this); 7524 var _Kids = []; 7525 Object.defineProperty(this, "Kids", { 7526 enumerable: false, 7527 configurable: true, 7528 get: function get() { 7529 if (_Kids.length > 0) { 7530 return _Kids; 7531 } else { 7532 return undefined; 7533 } 7534 } 7535 }); 7536 Object.defineProperty(this, "Fields", { 7537 enumerable: false, 7538 configurable: false, 7539 get: function get() { 7540 return _Kids; 7541 } 7542 }); // Default Appearance 7543 7544 var _DA; 7545 7546 Object.defineProperty(this, "DA", { 7547 enumerable: false, 7548 configurable: false, 7549 get: function get() { 7550 if (!_DA) { 7551 return undefined; 7552 } 7553 7554 var encryptor = function encryptor(data) { 7555 return data; 7556 }; 7557 7558 if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId); 7559 return "(" + pdfEscape(encryptor(_DA)) + ")"; 7560 }, 7561 set: function set(value) { 7562 _DA = value; 7563 } 7564 }); 7565 }; 7566 7567 inherit(AcroFormDictionary, AcroFormPDFObject); 7568 /** 7569 * The Field Object contains the Variables, that every Field needs 7570 * 7571 * @class AcroFormField 7572 * @classdesc An AcroForm FieldObject 7573 */ 7574 7575 var AcroFormField = function AcroFormField() { 7576 AcroFormPDFObject.call(this); //Annotation-Flag See Table 165 7577 7578 var _F = 4; 7579 Object.defineProperty(this, "F", { 7580 enumerable: false, 7581 configurable: false, 7582 get: function get() { 7583 return _F; 7584 }, 7585 set: function set(value) { 7586 if (!isNaN(value)) { 7587 _F = value; 7588 } else { 7589 throw new Error('Invalid value "' + value + '" for attribute F supplied.'); 7590 } 7591 } 7592 }); 7593 /** 7594 * (PDF 1.2) If set, print the annotation when the page is printed. If clear, never print the annotation, regardless of wether is is displayed on the screen. 7595 * NOTE 2 This can be useful for annotations representing interactive pushbuttons, which would serve no meaningful purpose on the printed page. 7596 * 7597 * @name AcroFormField#showWhenPrinted 7598 * @default true 7599 * @type {boolean} 7600 */ 7601 7602 Object.defineProperty(this, "showWhenPrinted", { 7603 enumerable: true, 7604 configurable: true, 7605 get: function get() { 7606 return Boolean(getBitForPdf(_F, 3)); 7607 }, 7608 set: function set(value) { 7609 if (Boolean(value) === true) { 7610 this.F = setBitForPdf(_F, 3); 7611 } else { 7612 this.F = clearBitForPdf(_F, 3); 7613 } 7614 } 7615 }); 7616 var _Ff = 0; 7617 Object.defineProperty(this, "Ff", { 7618 enumerable: false, 7619 configurable: false, 7620 get: function get() { 7621 return _Ff; 7622 }, 7623 set: function set(value) { 7624 if (!isNaN(value)) { 7625 _Ff = value; 7626 } else { 7627 throw new Error('Invalid value "' + value + '" for attribute Ff supplied.'); 7628 } 7629 } 7630 }); 7631 var _Rect = []; 7632 Object.defineProperty(this, "Rect", { 7633 enumerable: false, 7634 configurable: false, 7635 get: function get() { 7636 if (_Rect.length === 0) { 7637 return undefined; 7638 } 7639 7640 return _Rect; 7641 }, 7642 set: function set(value) { 7643 if (typeof value !== "undefined") { 7644 _Rect = value; 7645 } else { 7646 _Rect = []; 7647 } 7648 } 7649 }); 7650 /** 7651 * The x-position of the field. 7652 * 7653 * @name AcroFormField#x 7654 * @default null 7655 * @type {number} 7656 */ 7657 7658 Object.defineProperty(this, "x", { 7659 enumerable: true, 7660 configurable: true, 7661 get: function get() { 7662 if (!_Rect || isNaN(_Rect[0])) { 7663 return 0; 7664 } 7665 7666 return _Rect[0]; 7667 }, 7668 set: function set(value) { 7669 _Rect[0] = value; 7670 } 7671 }); 7672 /** 7673 * The y-position of the field. 7674 * 7675 * @name AcroFormField#y 7676 * @default null 7677 * @type {number} 7678 */ 7679 7680 Object.defineProperty(this, "y", { 7681 enumerable: true, 7682 configurable: true, 7683 get: function get() { 7684 if (!_Rect || isNaN(_Rect[1])) { 7685 return 0; 7686 } 7687 7688 return _Rect[1]; 7689 }, 7690 set: function set(value) { 7691 _Rect[1] = value; 7692 } 7693 }); 7694 /** 7695 * The width of the field. 7696 * 7697 * @name AcroFormField#width 7698 * @default null 7699 * @type {number} 7700 */ 7701 7702 Object.defineProperty(this, "width", { 7703 enumerable: true, 7704 configurable: true, 7705 get: function get() { 7706 if (!_Rect || isNaN(_Rect[2])) { 7707 return 0; 7708 } 7709 7710 return _Rect[2]; 7711 }, 7712 set: function set(value) { 7713 _Rect[2] = value; 7714 } 7715 }); 7716 /** 7717 * The height of the field. 7718 * 7719 * @name AcroFormField#height 7720 * @default null 7721 * @type {number} 7722 */ 7723 7724 Object.defineProperty(this, "height", { 7725 enumerable: true, 7726 configurable: true, 7727 get: function get() { 7728 if (!_Rect || isNaN(_Rect[3])) { 7729 return 0; 7730 } 7731 7732 return _Rect[3]; 7733 }, 7734 set: function set(value) { 7735 _Rect[3] = value; 7736 } 7737 }); 7738 var _FT = ""; 7739 Object.defineProperty(this, "FT", { 7740 enumerable: true, 7741 configurable: false, 7742 get: function get() { 7743 return _FT; 7744 }, 7745 set: function set(value) { 7746 switch (value) { 7747 case "/Btn": 7748 case "/Tx": 7749 case "/Ch": 7750 case "/Sig": 7751 _FT = value; 7752 break; 7753 7754 default: 7755 throw new Error('Invalid value "' + value + '" for attribute FT supplied.'); 7756 } 7757 } 7758 }); 7759 var _T = null; 7760 Object.defineProperty(this, "T", { 7761 enumerable: true, 7762 configurable: false, 7763 get: function get() { 7764 if (!_T || _T.length < 1) { 7765 // In case of a Child from a Radio´Group, you don't need a FieldName 7766 if (this instanceof AcroFormChildClass) { 7767 return undefined; 7768 } 7769 7770 _T = "FieldObject" + AcroFormField.FieldNum++; 7771 } 7772 7773 var encryptor = function encryptor(data) { 7774 return data; 7775 }; 7776 7777 if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId); 7778 return "(" + pdfEscape(encryptor(_T)) + ")"; 7779 }, 7780 set: function set(value) { 7781 _T = value.toString(); 7782 } 7783 }); 7784 /** 7785 * (Optional) The partial field name (see 12.7.3.2, âField Namesâ). 7786 * 7787 * @name AcroFormField#fieldName 7788 * @default null 7789 * @type {string} 7790 */ 7791 7792 Object.defineProperty(this, "fieldName", { 7793 configurable: true, 7794 enumerable: true, 7795 get: function get() { 7796 return _T; 7797 }, 7798 set: function set(value) { 7799 _T = value; 7800 } 7801 }); 7802 var _fontName = "helvetica"; 7803 /** 7804 * The fontName of the font to be used. 7805 * 7806 * @name AcroFormField#fontName 7807 * @default 'helvetica' 7808 * @type {string} 7809 */ 7810 7811 Object.defineProperty(this, "fontName", { 7812 enumerable: true, 7813 configurable: true, 7814 get: function get() { 7815 return _fontName; 7816 }, 7817 set: function set(value) { 7818 _fontName = value; 7819 } 7820 }); 7821 var _fontStyle = "normal"; 7822 /** 7823 * The fontStyle of the font to be used. 7824 * 7825 * @name AcroFormField#fontStyle 7826 * @default 'normal' 7827 * @type {string} 7828 */ 7829 7830 Object.defineProperty(this, "fontStyle", { 7831 enumerable: true, 7832 configurable: true, 7833 get: function get() { 7834 return _fontStyle; 7835 }, 7836 set: function set(value) { 7837 _fontStyle = value; 7838 } 7839 }); 7840 var _fontSize = 0; 7841 /** 7842 * The fontSize of the font to be used. 7843 * 7844 * @name AcroFormField#fontSize 7845 * @default 0 (for auto) 7846 * @type {number} 7847 */ 7848 7849 Object.defineProperty(this, "fontSize", { 7850 enumerable: true, 7851 configurable: true, 7852 get: function get() { 7853 return _fontSize; 7854 }, 7855 set: function set(value) { 7856 _fontSize = value; 7857 } 7858 }); 7859 var _maxFontSize = undefined; 7860 /** 7861 * The maximum fontSize of the font to be used. 7862 * 7863 * @name AcroFormField#maxFontSize 7864 * @default 0 (for auto) 7865 * @type {number} 7866 */ 7867 7868 Object.defineProperty(this, "maxFontSize", { 7869 enumerable: true, 7870 configurable: true, 7871 get: function get() { 7872 if (_maxFontSize === undefined) { 7873 // use the old default value here - the value is some kind of random as it depends on the scaleFactor (user unit) 7874 // ("50" is transformed to the "user space" but then used in "pdf space") 7875 return 50 / scaleFactor; 7876 } else { 7877 return _maxFontSize; 7878 } 7879 }, 7880 set: function set(value) { 7881 _maxFontSize = value; 7882 } 7883 }); 7884 var _color = "black"; 7885 /** 7886 * The color of the text 7887 * 7888 * @name AcroFormField#color 7889 * @default 'black' 7890 * @type {string|rgba} 7891 */ 7892 7893 Object.defineProperty(this, "color", { 7894 enumerable: true, 7895 configurable: true, 7896 get: function get() { 7897 return _color; 7898 }, 7899 set: function set(value) { 7900 _color = value; 7901 } 7902 }); 7903 var _DA = "/F1 0 Tf 0 g"; // Defines the default appearance (Needed for variable Text) 7904 7905 Object.defineProperty(this, "DA", { 7906 enumerable: true, 7907 configurable: false, 7908 get: function get() { 7909 if (!_DA || this instanceof AcroFormChildClass || this instanceof AcroFormTextField) { 7910 return undefined; 7911 } 7912 7913 return toPdfString(_DA, this.objId, this.scope); 7914 }, 7915 set: function set(value) { 7916 value = value.toString(); 7917 _DA = value; 7918 } 7919 }); 7920 var _DV = null; 7921 Object.defineProperty(this, "DV", { 7922 enumerable: false, 7923 configurable: false, 7924 get: function get() { 7925 if (!_DV) { 7926 return undefined; 7927 } 7928 7929 if (this instanceof AcroFormButton === false) { 7930 return toPdfString(_DV, this.objId, this.scope); 7931 } 7932 7933 return _DV; 7934 }, 7935 set: function set(value) { 7936 value = value.toString(); 7937 7938 if (this instanceof AcroFormButton === false) { 7939 if (value.substr(0, 1) === "(") { 7940 _DV = pdfUnescape(value.substr(1, value.length - 2)); 7941 } else { 7942 _DV = pdfUnescape(value); 7943 } 7944 } else { 7945 _DV = value; 7946 } 7947 } 7948 }); 7949 /** 7950 * (Optional; inheritable) The default value to which the field reverts when a reset-form action is executed (see 12.7.5.3, âReset-Form Actionâ). The format of this value is the same as that of value. 7951 * 7952 * @name AcroFormField#defaultValue 7953 * @default null 7954 * @type {any} 7955 */ 7956 7957 Object.defineProperty(this, "defaultValue", { 7958 enumerable: true, 7959 configurable: true, 7960 get: function get() { 7961 if (this instanceof AcroFormButton === true) { 7962 return pdfUnescape(_DV.substr(1, _DV.length - 1)); 7963 } else { 7964 return _DV; 7965 } 7966 }, 7967 set: function set(value) { 7968 value = value.toString(); 7969 7970 if (this instanceof AcroFormButton === true) { 7971 _DV = "/" + value; 7972 } else { 7973 _DV = value; 7974 } 7975 } 7976 }); 7977 var _V = null; 7978 Object.defineProperty(this, "_V", { 7979 enumerable: false, 7980 configurable: false, 7981 get: function get() { 7982 if (!_V) { 7983 return undefined; 7984 } 7985 7986 return _V; 7987 }, 7988 set: function set(value) { 7989 this.V = value; 7990 } 7991 }); 7992 Object.defineProperty(this, "V", { 7993 enumerable: false, 7994 configurable: false, 7995 get: function get() { 7996 if (!_V) { 7997 return undefined; 7998 } 7999 8000 if (this instanceof AcroFormButton === false) { 8001 return toPdfString(_V, this.objId, this.scope); 8002 } 8003 8004 return _V; 8005 }, 8006 set: function set(value) { 8007 value = value.toString(); 8008 8009 if (this instanceof AcroFormButton === false) { 8010 if (value.substr(0, 1) === "(") { 8011 _V = pdfUnescape(value.substr(1, value.length - 2)); 8012 } else { 8013 _V = pdfUnescape(value); 8014 } 8015 } else { 8016 _V = value; 8017 } 8018 } 8019 }); 8020 /** 8021 * (Optional; inheritable) The fieldâs value, whose format varies depending on the field type. See the descriptions of individual field types for further information. 8022 * 8023 * @name AcroFormField#value 8024 * @default null 8025 * @type {any} 8026 */ 8027 8028 Object.defineProperty(this, "value", { 8029 enumerable: true, 8030 configurable: true, 8031 get: function get() { 8032 if (this instanceof AcroFormButton === true) { 8033 return pdfUnescape(_V.substr(1, _V.length - 1)); 8034 } else { 8035 return _V; 8036 } 8037 }, 8038 set: function set(value) { 8039 value = value.toString(); 8040 8041 if (this instanceof AcroFormButton === true) { 8042 _V = "/" + value; 8043 } else { 8044 _V = value; 8045 } 8046 } 8047 }); 8048 /** 8049 * Check if field has annotations 8050 * 8051 * @name AcroFormField#hasAnnotation 8052 * @readonly 8053 * @type {boolean} 8054 */ 8055 8056 Object.defineProperty(this, "hasAnnotation", { 8057 enumerable: true, 8058 configurable: true, 8059 get: function get() { 8060 return this.Rect; 8061 } 8062 }); 8063 Object.defineProperty(this, "Type", { 8064 enumerable: true, 8065 configurable: false, 8066 get: function get() { 8067 return this.hasAnnotation ? "/Annot" : null; 8068 } 8069 }); 8070 Object.defineProperty(this, "Subtype", { 8071 enumerable: true, 8072 configurable: false, 8073 get: function get() { 8074 return this.hasAnnotation ? "/Widget" : null; 8075 } 8076 }); 8077 var _hasAppearanceStream = false; 8078 /** 8079 * true if field has an appearanceStream 8080 * 8081 * @name AcroFormField#hasAppearanceStream 8082 * @readonly 8083 * @type {boolean} 8084 */ 8085 8086 Object.defineProperty(this, "hasAppearanceStream", { 8087 enumerable: true, 8088 configurable: true, 8089 get: function get() { 8090 return _hasAppearanceStream; 8091 }, 8092 set: function set(value) { 8093 value = Boolean(value); 8094 _hasAppearanceStream = value; 8095 } 8096 }); 8097 /** 8098 * The page on which the AcroFormField is placed 8099 * 8100 * @name AcroFormField#page 8101 * @type {number} 8102 */ 8103 8104 var _page; 8105 8106 Object.defineProperty(this, "page", { 8107 enumerable: true, 8108 configurable: true, 8109 get: function get() { 8110 if (!_page) { 8111 return undefined; 8112 } 8113 8114 return _page; 8115 }, 8116 set: function set(value) { 8117 _page = value; 8118 } 8119 }); 8120 /** 8121 * If set, the user may not change the value of the field. Any associated widget annotations will not interact with the user; that is, they will not respond to mouse clicks or change their appearance in response to mouse motions. This flag is useful for fields whose values are computed or imported from a database. 8122 * 8123 * @name AcroFormField#readOnly 8124 * @default false 8125 * @type {boolean} 8126 */ 8127 8128 Object.defineProperty(this, "readOnly", { 8129 enumerable: true, 8130 configurable: true, 8131 get: function get() { 8132 return Boolean(getBitForPdf(this.Ff, 1)); 8133 }, 8134 set: function set(value) { 8135 if (Boolean(value) === true) { 8136 this.Ff = setBitForPdf(this.Ff, 1); 8137 } else { 8138 this.Ff = clearBitForPdf(this.Ff, 1); 8139 } 8140 } 8141 }); 8142 /** 8143 * If set, the field shall have a value at the time it is exported by a submitform action (see 12.7.5.2, âSubmit-Form Actionâ). 8144 * 8145 * @name AcroFormField#required 8146 * @default false 8147 * @type {boolean} 8148 */ 8149 8150 Object.defineProperty(this, "required", { 8151 enumerable: true, 8152 configurable: true, 8153 get: function get() { 8154 return Boolean(getBitForPdf(this.Ff, 2)); 8155 }, 8156 set: function set(value) { 8157 if (Boolean(value) === true) { 8158 this.Ff = setBitForPdf(this.Ff, 2); 8159 } else { 8160 this.Ff = clearBitForPdf(this.Ff, 2); 8161 } 8162 } 8163 }); 8164 /** 8165 * If set, the field shall not be exported by a submit-form action (see 12.7.5.2, âSubmit-Form Actionâ) 8166 * 8167 * @name AcroFormField#noExport 8168 * @default false 8169 * @type {boolean} 8170 */ 8171 8172 Object.defineProperty(this, "noExport", { 8173 enumerable: true, 8174 configurable: true, 8175 get: function get() { 8176 return Boolean(getBitForPdf(this.Ff, 3)); 8177 }, 8178 set: function set(value) { 8179 if (Boolean(value) === true) { 8180 this.Ff = setBitForPdf(this.Ff, 3); 8181 } else { 8182 this.Ff = clearBitForPdf(this.Ff, 3); 8183 } 8184 } 8185 }); 8186 var _Q = null; 8187 Object.defineProperty(this, "Q", { 8188 enumerable: true, 8189 configurable: false, 8190 get: function get() { 8191 if (_Q === null) { 8192 return undefined; 8193 } 8194 8195 return _Q; 8196 }, 8197 set: function set(value) { 8198 if ([0, 1, 2].indexOf(value) !== -1) { 8199 _Q = value; 8200 } else { 8201 throw new Error('Invalid value "' + value + '" for attribute Q supplied.'); 8202 } 8203 } 8204 }); 8205 /** 8206 * (Optional; inheritable) A code specifying the form of quadding (justification) that shall be used in displaying the text: 8207 * 'left', 'center', 'right' 8208 * 8209 * @name AcroFormField#textAlign 8210 * @default 'left' 8211 * @type {string} 8212 */ 8213 8214 Object.defineProperty(this, "textAlign", { 8215 get: function get() { 8216 var result; 8217 8218 switch (_Q) { 8219 case 0: 8220 default: 8221 result = "left"; 8222 break; 8223 8224 case 1: 8225 result = "center"; 8226 break; 8227 8228 case 2: 8229 result = "right"; 8230 break; 8231 } 8232 8233 return result; 8234 }, 8235 configurable: true, 8236 enumerable: true, 8237 set: function set(value) { 8238 switch (value) { 8239 case "right": 8240 case 2: 8241 _Q = 2; 8242 break; 8243 8244 case "center": 8245 case 1: 8246 _Q = 1; 8247 break; 8248 8249 case "left": 8250 case 0: 8251 default: 8252 _Q = 0; 8253 } 8254 } 8255 }); 8256 }; 8257 8258 inherit(AcroFormField, AcroFormPDFObject); 8259 /** 8260 * @class AcroFormChoiceField 8261 * @extends AcroFormField 8262 */ 8263 8264 var AcroFormChoiceField = function AcroFormChoiceField() { 8265 AcroFormField.call(this); // Field Type = Choice Field 8266 8267 this.FT = "/Ch"; // options 8268 8269 this.V = "()"; 8270 this.fontName = "zapfdingbats"; // Top Index 8271 8272 var _TI = 0; 8273 Object.defineProperty(this, "TI", { 8274 enumerable: true, 8275 configurable: false, 8276 get: function get() { 8277 return _TI; 8278 }, 8279 set: function set(value) { 8280 _TI = value; 8281 } 8282 }); 8283 /** 8284 * (Optional) For scrollable list boxes, the top index (the index in the Opt array of the first option visible in the list). Default value: 0. 8285 * 8286 * @name AcroFormChoiceField#topIndex 8287 * @default 0 8288 * @type {number} 8289 */ 8290 8291 Object.defineProperty(this, "topIndex", { 8292 enumerable: true, 8293 configurable: true, 8294 get: function get() { 8295 return _TI; 8296 }, 8297 set: function set(value) { 8298 _TI = value; 8299 } 8300 }); 8301 var _Opt = []; 8302 Object.defineProperty(this, "Opt", { 8303 enumerable: true, 8304 configurable: false, 8305 get: function get() { 8306 return arrayToPdfArray(_Opt, this.objId, this.scope); 8307 }, 8308 set: function set(value) { 8309 _Opt = pdfArrayToStringArray(value); 8310 } 8311 }); 8312 /** 8313 * @memberof AcroFormChoiceField 8314 * @name getOptions 8315 * @function 8316 * @instance 8317 * @returns {array} array of Options 8318 */ 8319 8320 this.getOptions = function () { 8321 return _Opt; 8322 }; 8323 /** 8324 * @memberof AcroFormChoiceField 8325 * @name setOptions 8326 * @function 8327 * @instance 8328 * @param {array} value 8329 */ 8330 8331 8332 this.setOptions = function (value) { 8333 _Opt = value; 8334 8335 if (this.sort) { 8336 _Opt.sort(); 8337 } 8338 }; 8339 /** 8340 * @memberof AcroFormChoiceField 8341 * @name addOption 8342 * @function 8343 * @instance 8344 * @param {string} value 8345 */ 8346 8347 8348 this.addOption = function (value) { 8349 value = value || ""; 8350 value = value.toString(); 8351 8352 _Opt.push(value); 8353 8354 if (this.sort) { 8355 _Opt.sort(); 8356 } 8357 }; 8358 /** 8359 * @memberof AcroFormChoiceField 8360 * @name removeOption 8361 * @function 8362 * @instance 8363 * @param {string} value 8364 * @param {boolean} allEntries (default: false) 8365 */ 8366 8367 8368 this.removeOption = function (value, allEntries) { 8369 allEntries = allEntries || false; 8370 value = value || ""; 8371 value = value.toString(); 8372 8373 while (_Opt.indexOf(value) !== -1) { 8374 _Opt.splice(_Opt.indexOf(value), 1); 8375 8376 if (allEntries === false) { 8377 break; 8378 } 8379 } 8380 }; 8381 /** 8382 * If set, the field is a combo box; if clear, the field is a list box. 8383 * 8384 * @name AcroFormChoiceField#combo 8385 * @default false 8386 * @type {boolean} 8387 */ 8388 8389 8390 Object.defineProperty(this, "combo", { 8391 enumerable: true, 8392 configurable: true, 8393 get: function get() { 8394 return Boolean(getBitForPdf(this.Ff, 18)); 8395 }, 8396 set: function set(value) { 8397 if (Boolean(value) === true) { 8398 this.Ff = setBitForPdf(this.Ff, 18); 8399 } else { 8400 this.Ff = clearBitForPdf(this.Ff, 18); 8401 } 8402 } 8403 }); 8404 /** 8405 * If set, the combo box shall include an editable text box as well as a drop-down list; if clear, it shall include only a drop-down list. This flag shall be used only if the Combo flag is set. 8406 * 8407 * @name AcroFormChoiceField#edit 8408 * @default false 8409 * @type {boolean} 8410 */ 8411 8412 Object.defineProperty(this, "edit", { 8413 enumerable: true, 8414 configurable: true, 8415 get: function get() { 8416 return Boolean(getBitForPdf(this.Ff, 19)); 8417 }, 8418 set: function set(value) { 8419 //PDF 32000-1:2008, page 444 8420 if (this.combo === true) { 8421 if (Boolean(value) === true) { 8422 this.Ff = setBitForPdf(this.Ff, 19); 8423 } else { 8424 this.Ff = clearBitForPdf(this.Ff, 19); 8425 } 8426 } 8427 } 8428 }); 8429 /** 8430 * If set, the fieldâs option items shall be sorted alphabetically. This flag is intended for use by writers, not by readers. Conforming readers shall display the options in the order in which they occur in the Opt array (see Table 231). 8431 * 8432 * @name AcroFormChoiceField#sort 8433 * @default false 8434 * @type {boolean} 8435 */ 8436 8437 Object.defineProperty(this, "sort", { 8438 enumerable: true, 8439 configurable: true, 8440 get: function get() { 8441 return Boolean(getBitForPdf(this.Ff, 20)); 8442 }, 8443 set: function set(value) { 8444 if (Boolean(value) === true) { 8445 this.Ff = setBitForPdf(this.Ff, 20); 8446 8447 _Opt.sort(); 8448 } else { 8449 this.Ff = clearBitForPdf(this.Ff, 20); 8450 } 8451 } 8452 }); 8453 /** 8454 * (PDF 1.4) If set, more than one of the fieldâs option items may be selected simultaneously; if clear, at most one item shall be selected 8455 * 8456 * @name AcroFormChoiceField#multiSelect 8457 * @default false 8458 * @type {boolean} 8459 */ 8460 8461 Object.defineProperty(this, "multiSelect", { 8462 enumerable: true, 8463 configurable: true, 8464 get: function get() { 8465 return Boolean(getBitForPdf(this.Ff, 22)); 8466 }, 8467 set: function set(value) { 8468 if (Boolean(value) === true) { 8469 this.Ff = setBitForPdf(this.Ff, 22); 8470 } else { 8471 this.Ff = clearBitForPdf(this.Ff, 22); 8472 } 8473 } 8474 }); 8475 /** 8476 * (PDF 1.4) If set, text entered in the field shall not be spellchecked. This flag shall not be used unless the Combo and Edit flags are both set. 8477 * 8478 * @name AcroFormChoiceField#doNotSpellCheck 8479 * @default false 8480 * @type {boolean} 8481 */ 8482 8483 Object.defineProperty(this, "doNotSpellCheck", { 8484 enumerable: true, 8485 configurable: true, 8486 get: function get() { 8487 return Boolean(getBitForPdf(this.Ff, 23)); 8488 }, 8489 set: function set(value) { 8490 if (Boolean(value) === true) { 8491 this.Ff = setBitForPdf(this.Ff, 23); 8492 } else { 8493 this.Ff = clearBitForPdf(this.Ff, 23); 8494 } 8495 } 8496 }); 8497 /** 8498 * (PDF 1.5) If set, the new value shall be committed as soon as a selection is made (commonly with the pointing device). In this case, supplying a value for a field involves three actions: selecting the field for fill-in, selecting a choice for the fill-in value, and leaving that field, which finalizes or âcommitsâ the data choice and triggers any actions associated with the entry or changing of this data. If this flag is on, then processing does not wait for leaving the field action to occur, but immediately proceeds to the third step. 8499 * This option enables applications to perform an action once a selection is made, without requiring the user to exit the field. If clear, the new value is not committed until the user exits the field. 8500 * 8501 * @name AcroFormChoiceField#commitOnSelChange 8502 * @default false 8503 * @type {boolean} 8504 */ 8505 8506 Object.defineProperty(this, "commitOnSelChange", { 8507 enumerable: true, 8508 configurable: true, 8509 get: function get() { 8510 return Boolean(getBitForPdf(this.Ff, 27)); 8511 }, 8512 set: function set(value) { 8513 if (Boolean(value) === true) { 8514 this.Ff = setBitForPdf(this.Ff, 27); 8515 } else { 8516 this.Ff = clearBitForPdf(this.Ff, 27); 8517 } 8518 } 8519 }); 8520 this.hasAppearanceStream = false; 8521 }; 8522 8523 inherit(AcroFormChoiceField, AcroFormField); 8524 /** 8525 * @class AcroFormListBox 8526 * @extends AcroFormChoiceField 8527 * @extends AcroFormField 8528 */ 8529 8530 var AcroFormListBox = function AcroFormListBox() { 8531 AcroFormChoiceField.call(this); 8532 this.fontName = "helvetica"; //PDF 32000-1:2008, page 444 8533 8534 this.combo = false; 8535 }; 8536 8537 inherit(AcroFormListBox, AcroFormChoiceField); 8538 /** 8539 * @class AcroFormComboBox 8540 * @extends AcroFormListBox 8541 * @extends AcroFormChoiceField 8542 * @extends AcroFormField 8543 */ 8544 8545 var AcroFormComboBox = function AcroFormComboBox() { 8546 AcroFormListBox.call(this); 8547 this.combo = true; 8548 }; 8549 8550 inherit(AcroFormComboBox, AcroFormListBox); 8551 /** 8552 * @class AcroFormEditBox 8553 * @extends AcroFormComboBox 8554 * @extends AcroFormListBox 8555 * @extends AcroFormChoiceField 8556 * @extends AcroFormField 8557 */ 8558 8559 var AcroFormEditBox = function AcroFormEditBox() { 8560 AcroFormComboBox.call(this); 8561 this.edit = true; 8562 }; 8563 8564 inherit(AcroFormEditBox, AcroFormComboBox); 8565 /** 8566 * @class AcroFormButton 8567 * @extends AcroFormField 8568 */ 8569 8570 var AcroFormButton = function AcroFormButton() { 8571 AcroFormField.call(this); 8572 this.FT = "/Btn"; 8573 /** 8574 * (Radio buttons only) If set, exactly one radio button shall be selected at all times; selecting the currently selected button has no effect. If clear, clicking the selected button deselects it, leaving no button selected. 8575 * 8576 * @name AcroFormButton#noToggleToOff 8577 * @type {boolean} 8578 */ 8579 8580 Object.defineProperty(this, "noToggleToOff", { 8581 enumerable: true, 8582 configurable: true, 8583 get: function get() { 8584 return Boolean(getBitForPdf(this.Ff, 15)); 8585 }, 8586 set: function set(value) { 8587 if (Boolean(value) === true) { 8588 this.Ff = setBitForPdf(this.Ff, 15); 8589 } else { 8590 this.Ff = clearBitForPdf(this.Ff, 15); 8591 } 8592 } 8593 }); 8594 /** 8595 * If set, the field is a set of radio buttons; if clear, the field is a checkbox. This flag may be set only if the Pushbutton flag is clear. 8596 * 8597 * @name AcroFormButton#radio 8598 * @type {boolean} 8599 */ 8600 8601 Object.defineProperty(this, "radio", { 8602 enumerable: true, 8603 configurable: true, 8604 get: function get() { 8605 return Boolean(getBitForPdf(this.Ff, 16)); 8606 }, 8607 set: function set(value) { 8608 if (Boolean(value) === true) { 8609 this.Ff = setBitForPdf(this.Ff, 16); 8610 } else { 8611 this.Ff = clearBitForPdf(this.Ff, 16); 8612 } 8613 } 8614 }); 8615 /** 8616 * If set, the field is a pushbutton that does not retain a permanent value. 8617 * 8618 * @name AcroFormButton#pushButton 8619 * @type {boolean} 8620 */ 8621 8622 Object.defineProperty(this, "pushButton", { 8623 enumerable: true, 8624 configurable: true, 8625 get: function get() { 8626 return Boolean(getBitForPdf(this.Ff, 17)); 8627 }, 8628 set: function set(value) { 8629 if (Boolean(value) === true) { 8630 this.Ff = setBitForPdf(this.Ff, 17); 8631 } else { 8632 this.Ff = clearBitForPdf(this.Ff, 17); 8633 } 8634 } 8635 }); 8636 /** 8637 * (PDF 1.5) If set, a group of radio buttons within a radio button field that use the same value for the on state will turn on and off in unison; that is if one is checked, they are all checked. If clear, the buttons are mutually exclusive (the same behavior as HTML radio buttons). 8638 * 8639 * @name AcroFormButton#radioIsUnison 8640 * @type {boolean} 8641 */ 8642 8643 Object.defineProperty(this, "radioIsUnison", { 8644 enumerable: true, 8645 configurable: true, 8646 get: function get() { 8647 return Boolean(getBitForPdf(this.Ff, 26)); 8648 }, 8649 set: function set(value) { 8650 if (Boolean(value) === true) { 8651 this.Ff = setBitForPdf(this.Ff, 26); 8652 } else { 8653 this.Ff = clearBitForPdf(this.Ff, 26); 8654 } 8655 } 8656 }); 8657 var _MK = {}; 8658 Object.defineProperty(this, "MK", { 8659 enumerable: false, 8660 configurable: false, 8661 get: function get() { 8662 var encryptor = function encryptor(data) { 8663 return data; 8664 }; 8665 8666 if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId); 8667 8668 if (Object.keys(_MK).length !== 0) { 8669 var result = []; 8670 result.push("<<"); 8671 var key; 8672 8673 for (key in _MK) { 8674 result.push("/" + key + " (" + pdfEscape(encryptor(_MK[key])) + ")"); 8675 } 8676 8677 result.push(">>"); 8678 return result.join("\n"); 8679 } 8680 8681 return undefined; 8682 }, 8683 set: function set(value) { 8684 if (_typeof(value) === "object") { 8685 _MK = value; 8686 } 8687 } 8688 }); 8689 /** 8690 * From the PDF reference: 8691 * (Optional, button fields only) The widget annotation's normal caption which shall be displayed when it is not interacting with the user. 8692 * Unlike the remaining entries listed in this Table which apply only to widget annotations associated with pushbutton fields (see Pushbuttons in 12.7.4.2, "Button Fields"), the CA entry may be used with any type of button field, including check boxes (see Check Boxes in 12.7.4.2, "Button Fields") and radio buttons (Radio Buttons in 12.7.4.2, "Button Fields"). 8693 * 8694 * - '8' = Cross, 8695 * - 'l' = Circle, 8696 * - '' = nothing 8697 * @name AcroFormButton#caption 8698 * @type {string} 8699 */ 8700 8701 Object.defineProperty(this, "caption", { 8702 enumerable: true, 8703 configurable: true, 8704 get: function get() { 8705 return _MK.CA || ""; 8706 }, 8707 set: function set(value) { 8708 if (typeof value === "string") { 8709 _MK.CA = value; 8710 } 8711 } 8712 }); 8713 8714 var _AS; 8715 8716 Object.defineProperty(this, "AS", { 8717 enumerable: false, 8718 configurable: false, 8719 get: function get() { 8720 return _AS; 8721 }, 8722 set: function set(value) { 8723 _AS = value; 8724 } 8725 }); 8726 /** 8727 * (Required if the appearance dictionary AP contains one or more subdictionaries; PDF 1.2) The annotation's appearance state, which selects the applicable appearance stream from an appearance subdictionary (see Section 12.5.5, "Appearance Streams") 8728 * 8729 * @name AcroFormButton#appearanceState 8730 * @type {any} 8731 */ 8732 8733 Object.defineProperty(this, "appearanceState", { 8734 enumerable: true, 8735 configurable: true, 8736 get: function get() { 8737 return _AS.substr(1, _AS.length - 1); 8738 }, 8739 set: function set(value) { 8740 _AS = "/" + value; 8741 } 8742 }); 8743 }; 8744 8745 inherit(AcroFormButton, AcroFormField); 8746 /** 8747 * @class AcroFormPushButton 8748 * @extends AcroFormButton 8749 * @extends AcroFormField 8750 */ 8751 8752 var AcroFormPushButton = function AcroFormPushButton() { 8753 AcroFormButton.call(this); 8754 this.pushButton = true; 8755 }; 8756 8757 inherit(AcroFormPushButton, AcroFormButton); 8758 /** 8759 * @class AcroFormRadioButton 8760 * @extends AcroFormButton 8761 * @extends AcroFormField 8762 */ 8763 8764 var AcroFormRadioButton = function AcroFormRadioButton() { 8765 AcroFormButton.call(this); 8766 this.radio = true; 8767 this.pushButton = false; 8768 var _Kids = []; 8769 Object.defineProperty(this, "Kids", { 8770 enumerable: true, 8771 configurable: false, 8772 get: function get() { 8773 return _Kids; 8774 }, 8775 set: function set(value) { 8776 if (typeof value !== "undefined") { 8777 _Kids = value; 8778 } else { 8779 _Kids = []; 8780 } 8781 } 8782 }); 8783 }; 8784 8785 inherit(AcroFormRadioButton, AcroFormButton); 8786 /** 8787 * The Child class of a RadioButton (the radioGroup) -> The single Buttons 8788 * 8789 * @class AcroFormChildClass 8790 * @extends AcroFormField 8791 * @ignore 8792 */ 8793 8794 var AcroFormChildClass = function AcroFormChildClass() { 8795 AcroFormField.call(this); 8796 8797 var _parent; 8798 8799 Object.defineProperty(this, "Parent", { 8800 enumerable: false, 8801 configurable: false, 8802 get: function get() { 8803 return _parent; 8804 }, 8805 set: function set(value) { 8806 _parent = value; 8807 } 8808 }); 8809 8810 var _optionName; 8811 8812 Object.defineProperty(this, "optionName", { 8813 enumerable: false, 8814 configurable: true, 8815 get: function get() { 8816 return _optionName; 8817 }, 8818 set: function set(value) { 8819 _optionName = value; 8820 } 8821 }); 8822 var _MK = {}; 8823 Object.defineProperty(this, "MK", { 8824 enumerable: false, 8825 configurable: false, 8826 get: function get() { 8827 var encryptor = function encryptor(data) { 8828 return data; 8829 }; 8830 8831 if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId); 8832 var result = []; 8833 result.push("<<"); 8834 var key; 8835 8836 for (key in _MK) { 8837 result.push("/" + key + " (" + pdfEscape(encryptor(_MK[key])) + ")"); 8838 } 8839 8840 result.push(">>"); 8841 return result.join("\n"); 8842 }, 8843 set: function set(value) { 8844 if (_typeof(value) === "object") { 8845 _MK = value; 8846 } 8847 } 8848 }); 8849 /** 8850 * From the PDF reference: 8851 * (Optional, button fields only) The widget annotation's normal caption which shall be displayed when it is not interacting with the user.
8852 * Unlike the remaining entries listed in this Table which apply only to widget annotations associated with pushbutton fields (see Pushbuttons in 12.7.4.2, "Button Fields"), the CA entry may be used with any type of button field, including check boxes (see Check Boxes in 12.7.4.2, "Button Fields") and radio buttons (Radio Buttons in 12.7.4.2, "Button Fields"). 8853 * 8854 * - '8' = Cross, 8855 * - 'l' = Circle, 8856 * - '' = nothing 8857 * @name AcroFormButton#caption 8858 * @type {string} 8859 */ 8860 8861 Object.defineProperty(this, "caption", { 8862 enumerable: true, 8863 configurable: true, 8864 get: function get() { 8865 return _MK.CA || ""; 8866 }, 8867 set: function set(value) { 8868 if (typeof value === "string") { 8869 _MK.CA = value; 8870 } 8871 } 8872 }); 8873 8874 var _AS; 8875 8876 Object.defineProperty(this, "AS", { 8877 enumerable: false, 8878 configurable: false, 8879 get: function get() { 8880 return _AS; 8881 }, 8882 set: function set(value) { 8883 _AS = value; 8884 } 8885 }); 8886 /** 8887 * (Required if the appearance dictionary AP contains one or more subdictionaries; PDF 1.2) The annotation's appearance state, which selects the applicable appearance stream from an appearance subdictionary (see Section 12.5.5, "Appearance Streams") 8888 * 8889 * @name AcroFormButton#appearanceState 8890 * @type {any} 8891 */ 8892 8893 Object.defineProperty(this, "appearanceState", { 8894 enumerable: true, 8895 configurable: true, 8896 get: function get() { 8897 return _AS.substr(1, _AS.length - 1); 8898 }, 8899 set: function set(value) { 8900 _AS = "/" + value; 8901 } 8902 }); 8903 this.caption = "l"; 8904 this.appearanceState = "Off"; // todo: set AppearanceType as variable that can be set from the 8905 // outside... 8906 8907 this._AppearanceType = AcroFormAppearance.RadioButton.Circle; // The Default appearanceType is the Circle 8908 8909 this.appearanceStreamContent = this._AppearanceType.createAppearanceStream(this.optionName); 8910 }; 8911 8912 inherit(AcroFormChildClass, AcroFormField); 8913 8914 AcroFormRadioButton.prototype.setAppearance = function (appearance) { 8915 if (!("createAppearanceStream" in appearance && "getCA" in appearance)) { 8916 throw new Error("Couldn't assign Appearance to RadioButton. Appearance was Invalid!"); 8917 } 8918 8919 for (var objId in this.Kids) { 8920 if (this.Kids.hasOwnProperty(objId)) { 8921 var child = this.Kids[objId]; 8922 child.appearanceStreamContent = appearance.createAppearanceStream(child.optionName); 8923 child.caption = appearance.getCA(); 8924 } 8925 } 8926 }; 8927 8928 AcroFormRadioButton.prototype.createOption = function (name) { 8929 // Create new Child for RadioGroup 8930 var child = new AcroFormChildClass(); 8931 child.Parent = this; 8932 child.optionName = name; // Add to Parent 8933 8934 this.Kids.push(child); 8935 addField.call(this.scope, child); 8936 return child; 8937 }; 8938 /** 8939 * @class AcroFormCheckBox 8940 * @extends AcroFormButton 8941 * @extends AcroFormField 8942 */ 8943 8944 8945 var AcroFormCheckBox = function AcroFormCheckBox() { 8946 AcroFormButton.call(this); 8947 this.fontName = "zapfdingbats"; 8948 this.caption = "3"; 8949 this.appearanceState = "On"; 8950 this.value = "On"; 8951 this.textAlign = "center"; 8952 this.appearanceStreamContent = AcroFormAppearance.CheckBox.createAppearanceStream(); 8953 }; 8954 8955 inherit(AcroFormCheckBox, AcroFormButton); 8956 /** 8957 * @class AcroFormTextField 8958 * @extends AcroFormField 8959 */ 8960 8961 var AcroFormTextField = function AcroFormTextField() { 8962 AcroFormField.call(this); 8963 this.FT = "/Tx"; 8964 /** 8965 * If set, the field may contain multiple lines of text; if clear, the fieldâs text shall be restricted to a single line. 8966 * 8967 * @name AcroFormTextField#multiline 8968 * @type {boolean} 8969 */ 8970 8971 Object.defineProperty(this, "multiline", { 8972 enumerable: true, 8973 configurable: true, 8974 get: function get() { 8975 return Boolean(getBitForPdf(this.Ff, 13)); 8976 }, 8977 set: function set(value) { 8978 if (Boolean(value) === true) { 8979 this.Ff = setBitForPdf(this.Ff, 13); 8980 } else { 8981 this.Ff = clearBitForPdf(this.Ff, 13); 8982 } 8983 } 8984 }); 8985 /** 8986 * (PDF 1.4) If set, the text entered in the field represents the pathname of a file whose contents shall be submitted as the value of the field. 8987 * 8988 * @name AcroFormTextField#fileSelect 8989 * @type {boolean} 8990 */ 8991 8992 Object.defineProperty(this, "fileSelect", { 8993 enumerable: true, 8994 configurable: true, 8995 get: function get() { 8996 return Boolean(getBitForPdf(this.Ff, 21)); 8997 }, 8998 set: function set(value) { 8999 if (Boolean(value) === true) { 9000 this.Ff = setBitForPdf(this.Ff, 21); 9001 } else { 9002 this.Ff = clearBitForPdf(this.Ff, 21); 9003 } 9004 } 9005 }); 9006 /** 9007 * (PDF 1.4) If set, text entered in the field shall not be spell-checked. 9008 * 9009 * @name AcroFormTextField#doNotSpellCheck 9010 * @type {boolean} 9011 */ 9012 9013 Object.defineProperty(this, "doNotSpellCheck", { 9014 enumerable: true, 9015 configurable: true, 9016 get: function get() { 9017 return Boolean(getBitForPdf(this.Ff, 23)); 9018 }, 9019 set: function set(value) { 9020 if (Boolean(value) === true) { 9021 this.Ff = setBitForPdf(this.Ff, 23); 9022 } else { 9023 this.Ff = clearBitForPdf(this.Ff, 23); 9024 } 9025 } 9026 }); 9027 /** 9028 * (PDF 1.4) If set, the field shall not scroll (horizontally for single-line fields, vertically for multiple-line fields) to accommodate more text than fits within its annotation rectangle. Once the field is full, no further text shall be accepted for interactive form filling; for noninteractive form filling, the filler should take care not to add more character than will visibly fit in the defined area. 9029 * 9030 * @name AcroFormTextField#doNotScroll 9031 * @type {boolean} 9032 */ 9033 9034 Object.defineProperty(this, "doNotScroll", { 9035 enumerable: true, 9036 configurable: true, 9037 get: function get() { 9038 return Boolean(getBitForPdf(this.Ff, 24)); 9039 }, 9040 set: function set(value) { 9041 if (Boolean(value) === true) { 9042 this.Ff = setBitForPdf(this.Ff, 24); 9043 } else { 9044 this.Ff = clearBitForPdf(this.Ff, 24); 9045 } 9046 } 9047 }); 9048 /** 9049 * (PDF 1.5) May be set only if the MaxLen entry is present in the text field dictionary (see Table 229) and if the Multiline, Password, and FileSelect flags are clear. If set, the field shall be automatically divi
vendor: 36,020 bytes, lines 9049-10083
9049ded into as many equally spaced positions, or combs, as the value of MaxLen, and the text is laid out into those combs. 9050 * 9051 * @name AcroFormTextField#comb 9052 * @type {boolean} 9053 */ 9054 9055 Object.defineProperty(this, "comb", { 9056 enumerable: true, 9057 configurable: true, 9058 get: function get() { 9059 return Boolean(getBitForPdf(this.Ff, 25)); 9060 }, 9061 set: function set(value) { 9062 if (Boolean(value) === true) { 9063 this.Ff = setBitForPdf(this.Ff, 25); 9064 } else { 9065 this.Ff = clearBitForPdf(this.Ff, 25); 9066 } 9067 } 9068 }); 9069 /** 9070 * (PDF 1.5) If set, the value of this field shall be a rich text string (see 12.7.3.4, âRich Text Stringsâ). If the field has a value, the RV entry of the field dictionary (Table 222) shall specify the rich text string. 9071 * 9072 * @name AcroFormTextField#richText 9073 * @type {boolean} 9074 */ 9075 9076 Object.defineProperty(this, "richText", { 9077 enumerable: true, 9078 configurable: true, 9079 get: function get() { 9080 return Boolean(getBitForPdf(this.Ff, 26)); 9081 }, 9082 set: function set(value) { 9083 if (Boolean(value) === true) { 9084 this.Ff = setBitForPdf(this.Ff, 26); 9085 } else { 9086 this.Ff = clearBitForPdf(this.Ff, 26); 9087 } 9088 } 9089 }); 9090 var _MaxLen = null; 9091 Object.defineProperty(this, "MaxLen", { 9092 enumerable: true, 9093 configurable: false, 9094 get: function get() { 9095 return _MaxLen; 9096 }, 9097 set: function set(value) { 9098 _MaxLen = value; 9099 } 9100 }); 9101 /** 9102 * (Optional; inheritable) The maximum length of the fieldâs text, in characters. 9103 * 9104 * @name AcroFormTextField#maxLength 9105 * @type {number} 9106 */ 9107 9108 Object.defineProperty(this, "maxLength", { 9109 enumerable: true, 9110 configurable: true, 9111 get: function get() { 9112 return _MaxLen; 9113 }, 9114 set: function set(value) { 9115 if (Number.isInteger(value)) { 9116 _MaxLen = value; 9117 } 9118 } 9119 }); 9120 Object.defineProperty(this, "hasAppearanceStream", { 9121 enumerable: true, 9122 configurable: true, 9123 get: function get() { 9124 return this.V || this.DV; 9125 } 9126 }); 9127 }; 9128 9129 inherit(AcroFormTextField, AcroFormField); 9130 /** 9131 * @class AcroFormPasswordField 9132 * @extends AcroFormTextField 9133 * @extends AcroFormField 9134 */ 9135 9136 var AcroFormPasswordField = function AcroFormPasswordField() { 9137 AcroFormTextField.call(this); 9138 /** 9139 * If set, the field is intended for entering a secure password that should not be echoed visibly to the screen. Characters typed from the keyboard shall instead be echoed in some unreadable form, such as asterisks or bullet characters. 9140 * NOTE To protect password confidentiality, readers should never store the value of the text field in the PDF file if this flag is set. 9141 * 9142 * @name AcroFormTextField#password 9143 * @type {boolean} 9144 */ 9145 9146 Object.defineProperty(this, "password", { 9147 enumerable: true, 9148 configurable: true, 9149 get: function get() { 9150 return Boolean(getBitForPdf(this.Ff, 14)); 9151 }, 9152 set: function set(value) { 9153 if (Boolean(value) === true) { 9154 this.Ff = setBitForPdf(this.Ff, 14); 9155 } else { 9156 this.Ff = clearBitForPdf(this.Ff, 14); 9157 } 9158 } 9159 }); 9160 this.password = true; 9161 }; 9162 9163 inherit(AcroFormPasswordField, AcroFormTextField); // Contains Methods for creating standard appearances 9164 9165 var AcroFormAppearance = { 9166 CheckBox: { 9167 createAppearanceStream: function createAppearanceStream() { 9168 var appearance = { 9169 N: { 9170 On: AcroFormAppearance.CheckBox.YesNormal 9171 }, 9172 D: { 9173 On: AcroFormAppearance.CheckBox.YesPushDown, 9174 Off: AcroFormAppearance.CheckBox.OffPushDown 9175 } 9176 }; 9177 return appearance; 9178 }, 9179 9180 /** 9181 * Returns the standard On Appearance for a CheckBox 9182 * 9183 * @returns {AcroFormXObject} 9184 */ 9185 YesPushDown: function YesPushDown(formObject) { 9186 var xobj = createFormXObject(formObject); 9187 xobj.scope = formObject.scope; 9188 var stream = []; 9189 var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id; 9190 9191 var encodedColor = formObject.scope.__private__.encodeColorString(formObject.color); 9192 9193 var calcRes = calculateX(formObject, formObject.caption); 9194 stream.push("0.749023 g"); 9195 stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re"); 9196 stream.push("f"); 9197 stream.push("BMC"); 9198 stream.push("q"); 9199 stream.push("0 0 1 rg"); 9200 stream.push("/" + fontKey + " " + f2(calcRes.fontSize) + " Tf " + encodedColor); 9201 stream.push("BT"); 9202 stream.push(calcRes.text); 9203 stream.push("ET"); 9204 stream.push("Q"); 9205 stream.push("EMC"); 9206 xobj.stream = stream.join("\n"); 9207 return xobj; 9208 }, 9209 YesNormal: function YesNormal(formObject) { 9210 var xobj = createFormXObject(formObject); 9211 xobj.scope = formObject.scope; 9212 var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id; 9213 9214 var encodedColor = formObject.scope.__private__.encodeColorString(formObject.color); 9215 9216 var stream = []; 9217 var height = AcroFormAppearance.internal.getHeight(formObject); 9218 var width = AcroFormAppearance.internal.getWidth(formObject); 9219 var calcRes = calculateX(formObject, formObject.caption); 9220 stream.push("1 g"); 9221 stream.push("0 0 " + f2(width) + " " + f2(height) + " re"); 9222 stream.push("f"); 9223 stream.push("q"); 9224 stream.push("0 0 1 rg"); 9225 stream.push("0 0 " + f2(width - 1) + " " + f2(height - 1) + " re"); 9226 stream.push("W"); 9227 stream.push("n"); 9228 stream.push("0 g"); 9229 stream.push("BT"); 9230 stream.push("/" + fontKey + " " + f2(calcRes.fontSize) + " Tf " + encodedColor); 9231 stream.push(calcRes.text); 9232 stream.push("ET"); 9233 stream.push("Q"); 9234 xobj.stream = stream.join("\n"); 9235 return xobj; 9236 }, 9237 9238 /** 9239 * Returns the standard Off Appearance for a CheckBox 9240 * 9241 * @returns {AcroFormXObject} 9242 */ 9243 OffPushDown: function OffPushDown(formObject) { 9244 var xobj = createFormXObject(formObject); 9245 xobj.scope = formObject.scope; 9246 var stream = []; 9247 stream.push("0.749023 g"); 9248 stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re"); 9249 stream.push("f"); 9250 xobj.stream = stream.join("\n"); 9251 return xobj; 9252 } 9253 }, 9254 RadioButton: { 9255 Circle: { 9256 createAppearanceStream: function createAppearanceStream(name) { 9257 var appearanceStreamContent = { 9258 D: { 9259 Off: AcroFormAppearance.RadioButton.Circle.OffPushDown 9260 }, 9261 N: {} 9262 }; 9263 appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Circle.YesNormal; 9264 appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Circle.YesPushDown; 9265 return appearanceStreamContent; 9266 }, 9267 getCA: function getCA() { 9268 return "l"; 9269 }, 9270 YesNormal: function YesNormal(formObject) { 9271 var xobj = createFormXObject(formObject); 9272 xobj.scope = formObject.scope; 9273 var stream = []; // Make the Radius of the Circle relative to min(height, width) of formObject 9274 9275 var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4; // The Borderpadding... 9276 9277 DotRadius = Number((DotRadius * 0.9).toFixed(5)); 9278 var c = AcroFormAppearance.internal.Bezier_C; 9279 var DotRadiusBezier = Number((DotRadius * c).toFixed(5)); 9280 /* 9281 * The Following is a Circle created with Bezier-Curves. 9282 */ 9283 9284 stream.push("q"); 9285 stream.push("1 0 0 1 " + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + " " + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + " cm"); 9286 stream.push(DotRadius + " 0 m"); 9287 stream.push(DotRadius + " " + DotRadiusBezier + " " + DotRadiusBezier + " " + DotRadius + " 0 " + DotRadius + " c"); 9288 stream.push("-" + DotRadiusBezier + " " + DotRadius + " -" + DotRadius + " " + DotRadiusBezier + " -" + DotRadius + " 0 c"); 9289 stream.push("-" + DotRadius + " -" + DotRadiusBezier + " -" + DotRadiusBezier + " -" + DotRadius + " 0 -" + DotRadius + " c"); 9290 stream.push(DotRadiusBezier + " -" + DotRadius + " " + DotRadius + " -" + DotRadiusBezier + " " + DotRadius + " 0 c"); 9291 stream.push("f"); 9292 stream.push("Q"); 9293 xobj.stream = stream.join("\n"); 9294 return xobj; 9295 }, 9296 YesPushDown: function YesPushDown(formObject) { 9297 var xobj = createFormXObject(formObject); 9298 xobj.scope = formObject.scope; 9299 var stream = []; 9300 var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4; // The Borderpadding... 9301 9302 DotRadius = Number((DotRadius * 0.9).toFixed(5)); // Save results for later use; no need to waste 9303 // processor ticks on doing math 9304 9305 var k = Number((DotRadius * 2).toFixed(5)); 9306 var kc = Number((k * AcroFormAppearance.internal.Bezier_C).toFixed(5)); 9307 var dc = Number((DotRadius * AcroFormAppearance.internal.Bezier_C).toFixed(5)); 9308 stream.push("0.749023 g"); 9309 stream.push("q"); 9310 stream.push("1 0 0 1 " + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + " " + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + " cm"); 9311 stream.push(k + " 0 m"); 9312 stream.push(k + " " + kc + " " + kc + " " + k + " 0 " + k + " c"); 9313 stream.push("-" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c"); 9314 stream.push("-" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c"); 9315 stream.push(kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c"); 9316 stream.push("f"); 9317 stream.push("Q"); 9318 stream.push("0 g"); 9319 stream.push("q"); 9320 stream.push("1 0 0 1 " + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + " " + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + " cm"); 9321 stream.push(DotRadius + " 0 m"); 9322 stream.push("" + DotRadius + " " + dc + " " + dc + " " + DotRadius + " 0 " + DotRadius + " c"); 9323 stream.push("-" + dc + " " + DotRadius + " -" + DotRadius + " " + dc + " -" + DotRadius + " 0 c"); 9324 stream.push("-" + DotRadius + " -" + dc + " -" + dc + " -" + DotRadius + " 0 -" + DotRadius + " c"); 9325 stream.push(dc + " -" + DotRadius + " " + DotRadius + " -" + dc + " " + DotRadius + " 0 c"); 9326 stream.push("f"); 9327 stream.push("Q"); 9328 xobj.stream = stream.join("\n"); 9329 return xobj; 9330 }, 9331 OffPushDown: function OffPushDown(formObject) { 9332 var xobj = createFormXObject(formObject); 9333 xobj.scope = formObject.scope; 9334 var stream = []; 9335 var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4; // The Borderpadding... 9336 9337 DotRadius = Number((DotRadius * 0.9).toFixed(5)); // Save results for later use; no need to waste 9338 // processor ticks on doing math 9339 9340 var k = Number((DotRadius * 2).toFixed(5)); 9341 var kc = Number((k * AcroFormAppearance.internal.Bezier_C).toFixed(5)); 9342 stream.push("0.749023 g"); 9343 stream.push("q"); 9344 stream.push("1 0 0 1 " + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + " " + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + " cm"); 9345 stream.push(k + " 0 m"); 9346 stream.push(k + " " + kc + " " + kc + " " + k + " 0 " + k + " c"); 9347 stream.push("-" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c"); 9348 stream.push("-" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c"); 9349 stream.push(kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c"); 9350 stream.push("f"); 9351 stream.push("Q"); 9352 xobj.stream = stream.join("\n"); 9353 return xobj; 9354 } 9355 }, 9356 Cross: { 9357 /** 9358 * Creates the Actual AppearanceDictionary-References 9359 * 9360 * @param {string} name 9361 * @returns {Object} 9362 * @ignore 9363 */ 9364 createAppearanceStream: function createAppearanceStream(name) { 9365 var appearanceStreamContent = { 9366 D: { 9367 Off: AcroFormAppearance.RadioButton.Cross.OffPushDown 9368 }, 9369 N: {} 9370 }; 9371 appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Cross.YesNormal; 9372 appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Cross.YesPushDown; 9373 return appearanceStreamContent; 9374 }, 9375 getCA: function getCA() { 9376 return "8"; 9377 }, 9378 YesNormal: function YesNormal(formObject) { 9379 var xobj = createFormXObject(formObject); 9380 xobj.scope = formObject.scope; 9381 var stream = []; 9382 var cross = AcroFormAppearance.internal.calculateCross(formObject); 9383 stream.push("q"); 9384 stream.push("1 1 " + f2(AcroFormAppearance.internal.getWidth(formObject) - 2) + " " + f2(AcroFormAppearance.internal.getHeight(formObject) - 2) + " re"); 9385 stream.push("W"); 9386 stream.push("n"); 9387 stream.push(f2(cross.x1.x) + " " + f2(cross.x1.y) + " m"); 9388 stream.push(f2(cross.x2.x) + " " + f2(cross.x2.y) + " l"); 9389 stream.push(f2(cross.x4.x) + " " + f2(cross.x4.y) + " m"); 9390 stream.push(f2(cross.x3.x) + " " + f2(cross.x3.y) + " l"); 9391 stream.push("s"); 9392 stream.push("Q"); 9393 xobj.stream = stream.join("\n"); 9394 return xobj; 9395 }, 9396 YesPushDown: function YesPushDown(formObject) { 9397 var xobj = createFormXObject(formObject); 9398 xobj.scope = formObject.scope; 9399 var cross = AcroFormAppearance.internal.calculateCross(formObject); 9400 var stream = []; 9401 stream.push("0.749023 g"); 9402 stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re"); 9403 stream.push("f"); 9404 stream.push("q"); 9405 stream.push("1 1 " + f2(AcroFormAppearance.internal.getWidth(formObject) - 2) + " " + f2(AcroFormAppearance.internal.getHeight(formObject) - 2) + " re"); 9406 stream.push("W"); 9407 stream.push("n"); 9408 stream.push(f2(cross.x1.x) + " " + f2(cross.x1.y) + " m"); 9409 stream.push(f2(cross.x2.x) + " " + f2(cross.x2.y) + " l"); 9410 stream.push(f2(cross.x4.x) + " " + f2(cross.x4.y) + " m"); 9411 stream.push(f2(cross.x3.x) + " " + f2(cross.x3.y) + " l"); 9412 stream.push("s"); 9413 stream.push("Q"); 9414 xobj.stream = stream.join("\n"); 9415 return xobj; 9416 }, 9417 OffPushDown: function OffPushDown(formObject) { 9418 var xobj = createFormXObject(formObject); 9419 xobj.scope = formObject.scope; 9420 var stream = []; 9421 stream.push("0.749023 g"); 9422 stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re"); 9423 stream.push("f"); 9424 xobj.stream = stream.join("\n"); 9425 return xobj; 9426 } 9427 } 9428 }, 9429 9430 /** 9431 * Returns the standard Appearance 9432 * 9433 * @returns {AcroFormXObject} 9434 */ 9435 createDefaultAppearanceStream: function createDefaultAppearanceStream(formObject) { 9436 // Set Helvetica to Standard Font (size: auto) 9437 // Color: Black 9438 var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id; 9439 9440 var encodedColor = formObject.scope.__private__.encodeColorString(formObject.color); 9441 9442 var fontSize = formObject.fontSize; 9443 var result = "/" + fontKey + " " + fontSize + " Tf " + encodedColor; 9444 return result; 9445 } 9446 }; 9447 AcroFormAppearance.internal = { 9448 Bezier_C: 0.551915024494, 9449 calculateCross: function calculateCross(formObject) { 9450 var width = AcroFormAppearance.internal.getWidth(formObject); 9451 var height = AcroFormAppearance.internal.getHeight(formObject); 9452 var a = Math.min(width, height); 9453 var cross = { 9454 x1: { 9455 // upperLeft 9456 x: (width - a) / 2, 9457 y: (height - a) / 2 + a // height - borderPadding 9458 9459 }, 9460 x2: { 9461 // lowerRight 9462 x: (width - a) / 2 + a, 9463 y: (height - a) / 2 // borderPadding 9464 9465 }, 9466 x3: { 9467 // lowerLeft 9468 x: (width - a) / 2, 9469 y: (height - a) / 2 // borderPadding 9470 9471 }, 9472 x4: { 9473 // upperRight 9474 x: (width - a) / 2 + a, 9475 y: (height - a) / 2 + a // height - borderPadding 9476 9477 } 9478 }; 9479 return cross; 9480 } 9481 }; 9482 9483 AcroFormAppearance.internal.getWidth = function (formObject) { 9484 var result = 0; 9485 9486 if (_typeof(formObject) === "object") { 9487 result = scale(formObject.Rect[2]); 9488 } 9489 9490 return result; 9491 }; 9492 9493 AcroFormAppearance.internal.getHeight = function (formObject) { 9494 var result = 0; 9495 9496 if (_typeof(formObject) === "object") { 9497 result = scale(formObject.Rect[3]); 9498 } 9499 9500 return result; 9501 }; // Public: 9502 9503 /** 9504 * Add an AcroForm-Field to the jsPDF-instance 9505 * 9506 * @name addField 9507 * @function 9508 * @instance 9509 * @param {Object} fieldObject 9510 * @returns {jsPDF} 9511 */ 9512 9513 9514 var addField = jsPDFAPI.addField = function (fieldObject) { 9515 initializeAcroForm(this, fieldObject); 9516 9517 if (fieldObject instanceof AcroFormField) { 9518 putForm(fieldObject); 9519 } else { 9520 throw new Error("Invalid argument passed to jsPDF.addField."); 9521 } 9522 9523 fieldObject.page = fieldObject.scope.internal.getCurrentPageInfo().pageNumber; 9524 return this; 9525 }; 9526 9527 jsPDFAPI.AcroFormChoiceField = AcroFormChoiceField; 9528 jsPDFAPI.AcroFormListBox = AcroFormListBox; 9529 jsPDFAPI.AcroFormComboBox = AcroFormComboBox; 9530 jsPDFAPI.AcroFormEditBox = AcroFormEditBox; 9531 jsPDFAPI.AcroFormButton = AcroFormButton; 9532 jsPDFAPI.AcroFormPushButton = AcroFormPushButton; 9533 jsPDFAPI.AcroFormRadioButton = AcroFormRadioButton; 9534 jsPDFAPI.AcroFormCheckBox = AcroFormCheckBox; 9535 jsPDFAPI.AcroFormTextField = AcroFormTextField; 9536 jsPDFAPI.AcroFormPasswordField = AcroFormPasswordField; 9537 jsPDFAPI.AcroFormAppearance = AcroFormAppearance; 9538 jsPDFAPI.AcroForm = { 9539 ChoiceField: AcroFormChoiceField, 9540 ListBox: AcroFormListBox, 9541 ComboBox: AcroFormComboBox, 9542 EditBox: AcroFormEditBox, 9543 Button: AcroFormButton, 9544 PushButton: AcroFormPushButton, 9545 RadioButton: AcroFormRadioButton, 9546 CheckBox: AcroFormCheckBox, 9547 TextField: AcroFormTextField, 9548 PasswordField: AcroFormPasswordField, 9549 Appearance: AcroFormAppearance 9550 }; 9551 jsPDF.AcroForm = { 9552 ChoiceField: AcroFormChoiceField, 9553 ListBox: AcroFormListBox, 9554 ComboBox: AcroFormComboBox, 9555 EditBox: AcroFormEditBox, 9556 Button: AcroFormButton, 9557 PushButton: AcroFormPushButton, 9558 RadioButton: AcroFormRadioButton, 9559 CheckBox: AcroFormCheckBox, 9560 TextField: AcroFormTextField, 9561 PasswordField: AcroFormPasswordField, 9562 Appearance: AcroFormAppearance 9563 }; 9564 var AcroForm = jsPDF.AcroForm; 9565 9566 (function (jsPDFAPI) { 9567 9568 var namespace = "addImage_"; 9569 jsPDFAPI.__addimage__ = {}; 9570 var UNKNOWN = "UNKNOWN"; // Heuristic selection of a good batch for large array .apply. Not limiting make the call overflow. 9571 // With too small batch iteration will be slow as more calls are made, 9572 // higher values cause larger and slower garbage collection. 9573 9574 var ARRAY_APPLY_BATCH = 8192; 9575 var imageFileTypeHeaders = { 9576 PNG: [[0x89, 0x50, 0x4e, 0x47]], 9577 TIFF: [[0x4d, 0x4d, 0x00, 0x2a], //Motorola 9578 [0x49, 0x49, 0x2a, 0x00] //Intel 9579 ], 9580 JPEG: [[0xff, 0xd8, 0xff, 0xe0, undefined, undefined, 0x4a, 0x46, 0x49, 0x46, 0x00], //JFIF 9581 [0xff, 0xd8, 0xff, 0xe1, undefined, undefined, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00], //Exif 9582 [0xff, 0xd8, 0xff, 0xdb], //JPEG RAW 9583 [0xff, 0xd8, 0xff, 0xee] //EXIF RAW 9584 ], 9585 JPEG2000: [[0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20]], 9586 GIF87a: [[0x47, 0x49, 0x46, 0x38, 0x37, 0x61]], 9587 GIF89a: [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61]], 9588 WEBP: [[0x52, 0x49, 0x46, 0x46, undefined, undefined, undefined, undefined, 0x57, 0x45, 0x42, 0x50]], 9589 BMP: [[0x42, 0x4d], //BM - Windows 3.1x, 95, NT, ... etc. 9590 [0x42, 0x41], //BA - OS/2 struct bitmap array 9591 [0x43, 0x49], //CI - OS/2 struct color icon 9592 [0x43, 0x50], //CP - OS/2 const color pointer 9593 [0x49, 0x43], //IC - OS/2 struct icon 9594 [0x50, 0x54] //PT - OS/2 pointer 9595 ] 9596 }; 9597 /** 9598 * Recognize filetype of Image by magic-bytes 9599 * 9600 * https://en.wikipedia.org/wiki/List_of_file_signatures 9601 * 9602 * @name getImageFileTypeByImageData 9603 * @public 9604 * @function 9605 * @param {string|arraybuffer} imageData imageData as binary String or arraybuffer 9606 * @param {string} format format of file if filetype-recognition fails, e.g. 'JPEG' 9607 * 9608 * @returns {string} filetype of Image 9609 */ 9610 9611 var getImageFileTypeByImageData = jsPDFAPI.__addimage__.getImageFileTypeByImageData = function (imageData, fallbackFormat) { 9612 fallbackFormat = fallbackFormat || UNKNOWN; 9613 var i; 9614 var j; 9615 var result = UNKNOWN; 9616 var headerSchemata; 9617 var compareResult; 9618 var fileType; 9619 9620 if (fallbackFormat === "RGBA" || imageData.data !== undefined && imageData.data instanceof Uint8ClampedArray && "height" in imageData && "width" in imageData) { 9621 return "RGBA"; 9622 } 9623 9624 if (isArrayBufferView(imageData)) { 9625 for (fileType in imageFileTypeHeaders) { 9626 headerSchemata = imageFileTypeHeaders[fileType]; 9627 9628 for (i = 0; i < headerSchemata.length; i += 1) { 9629 compareResult = true; 9630 9631 for (j = 0; j < headerSchemata[i].length; j += 1) { 9632 if (headerSchemata[i][j] === undefined) { 9633 continue; 9634 } 9635 9636 if (headerSchemata[i][j] !== imageData[j]) { 9637 compareResult = false; 9638 break; 9639 } 9640 } 9641 9642 if (compareResult === true) { 9643 result = fileType; 9644 break; 9645 } 9646 } 9647 } 9648 } else { 9649 for (fileType in imageFileTypeHeaders) { 9650 headerSchemata = imageFileTypeHeaders[fileType]; 9651 9652 for (i = 0; i < headerSchemata.length; i += 1) { 9653 compareResult = true; 9654 9655 for (j = 0; j < headerSchemata[i].length; j += 1) { 9656 if (headerSchemata[i][j] === undefined) { 9657 continue; 9658 } 9659 9660 if (headerSchemata[i][j] !== imageData.charCodeAt(j)) { 9661 compareResult = false; 9662 break; 9663 } 9664 } 9665 9666 if (compareResult === true) { 9667 result = fileType; 9668 break; 9669 } 9670 } 9671 } 9672 } 9673 9674 if (result === UNKNOWN && fallbackFormat !== UNKNOWN) { 9675 result = fallbackFormat; 9676 } 9677 9678 return result; 9679 }; // Image functionality ported from pdf.js 9680 9681 9682 var putImage = function putImage(image) { 9683 var out = this.internal.write; 9684 var putStream = this.internal.putStream; 9685 var getFilters = this.internal.getFilters; 9686 var filter = getFilters(); 9687 9688 while (filter.indexOf("FlateEncode") !== -1) { 9689 filter.splice(filter.indexOf("FlateEncode"), 1); 9690 } 9691 9692 image.objectId = this.internal.newObject(); 9693 var additionalKeyValues = []; 9694 additionalKeyValues.push({ 9695 key: "Type", 9696 value: "/XObject" 9697 }); 9698 additionalKeyValues.push({ 9699 key: "Subtype", 9700 value: "/Image" 9701 }); 9702 additionalKeyValues.push({ 9703 key: "Width", 9704 value: image.width 9705 }); 9706 additionalKeyValues.push({ 9707 key: "Height", 9708 value: image.height 9709 }); 9710 9711 if (image.colorSpace === color_spaces.INDEXED) { 9712 additionalKeyValues.push({ 9713 key: "ColorSpace", 9714 value: "[/Indexed /DeviceRGB " + ( // if an indexed png defines more than one colour with transparency, we've created a sMask 9715 image.palette.length / 3 - 1) + " " + ("sMask" in image && typeof image.sMask !== "undefined" ? image.objectId + 2 : image.objectId + 1) + " 0 R]" 9716 }); 9717 } else { 9718 additionalKeyValues.push({ 9719 key: "ColorSpace", 9720 value: "/" + image.colorSpace 9721 }); 9722 9723 if (image.colorSpace === color_spaces.DEVICE_CMYK) { 9724 additionalKeyValues.push({ 9725 key: "Decode", 9726 value: "[1 0 1 0 1 0 1 0]" 9727 }); 9728 } 9729 } 9730 9731 additionalKeyValues.push({ 9732 key: "BitsPerComponent", 9733 value: image.bitsPerComponent 9734 }); 9735 9736 if ("decodeParameters" in image && typeof image.decodeParameters !== "undefined") { 9737 additionalKeyValues.push({ 9738 key: "DecodeParms", 9739 value: "<<" + image.decodeParameters + ">>" 9740 }); 9741 } 9742 9743 if ("transparency" in image && Array.isArray(image.transparency)) { 9744 var transparency = "", 9745 i = 0, 9746 len = image.transparency.length; 9747 9748 for (; i < len; i++) { 9749 transparency += image.transparency[i] + " " + image.transparency[i] + " "; 9750 } 9751 9752 additionalKeyValues.push({ 9753 key: "Mask", 9754 value: "[" + transparency + "]" 9755 }); 9756 } 9757 9758 if (typeof image.sMask !== "undefined") { 9759 additionalKeyValues.push({ 9760 key: "SMask", 9761 value: image.objectId + 1 + " 0 R" 9762 }); 9763 } 9764 9765 var alreadyAppliedFilters = typeof image.filter !== "undefined" ? ["/" + image.filter] : undefined; 9766 putStream({ 9767 data: image.data, 9768 additionalKeyValues: additionalKeyValues, 9769 alreadyAppliedFilters: alreadyAppliedFilters, 9770 objectId: image.objectId 9771 }); 9772 out("endobj"); // Soft mask 9773 9774 if ("sMask" in image && typeof image.sMask !== "undefined") { 9775 var decodeParameters = "/Predictor " + image.predictor + " /Colors 1 /BitsPerComponent " + image.bitsPerComponent + " /Columns " + image.width; 9776 var sMask = { 9777 width: image.width, 9778 height: image.height, 9779 colorSpace: "DeviceGray", 9780 bitsPerComponent: image.bitsPerComponent, 9781 decodeParameters: decodeParameters, 9782 data: image.sMask 9783 }; 9784 9785 if ("filter" in image) { 9786 sMask.filter = image.filter; 9787 } 9788 9789 putImage.call(this, sMask); 9790 } //Palette 9791 9792 9793 if (image.colorSpace === color_spaces.INDEXED) { 9794 var objId = this.internal.newObject(); //out('<< /Filter / ' + img['f'] +' /Length ' + img['pal'].length + '>>'); 9795 //putStream(zlib.compress(img['pal'])); 9796 9797 putStream({ 9798 data: arrayBufferToBinaryString(new Uint8Array(image.palette)), 9799 objectId: objId 9800 }); 9801 out("endobj"); 9802 } 9803 }; 9804 9805 var putResourcesCallback = function putResourcesCallback() { 9806 var images = this.internal.collections[namespace + "images"]; 9807 9808 for (var i in images) { 9809 putImage.call(this, images[i]); 9810 } 9811 }; 9812 9813 var putXObjectsDictCallback = function putXObjectsDictCallback() { 9814 var images = this.internal.collections[namespace + "images"], 9815 out = this.internal.write, 9816 image; 9817 9818 for (var i in images) { 9819 image = images[i]; 9820 out("/I" + image.index, image.objectId, "0", "R"); 9821 } 9822 }; 9823 9824 var checkCompressValue = function checkCompressValue(value) { 9825 if (value && typeof value === "string") value = value.toUpperCase(); 9826 return value in jsPDFAPI.image_compression ? value : image_compression.NONE; 9827 }; 9828 9829 var initialize = function initialize() { 9830 if (!this.internal.collections[namespace + "images"]) { 9831 this.internal.collections[namespace + "images"] = {}; 9832 this.internal.events.subscribe("putResources", putResourcesCallback); 9833 this.internal.events.subscribe("putXobjectDict", putXObjectsDictCallback); 9834 } 9835 }; 9836 9837 var getImages = function getImages() { 9838 var images = this.internal.collections[namespace + "images"]; 9839 initialize.call(this); 9840 return images; 9841 }; 9842 9843 var getImageIndex = function getImageIndex() { 9844 return Object.keys(this.internal.collections[namespace + "images"]).length; 9845 }; 9846 9847 var notDefined = function notDefined(value) { 9848 return typeof value === "undefined" || value === null || value.length === 0; 9849 }; 9850 9851 var generateAliasFromImageData = function generateAliasFromImageData(imageData) { 9852 if (typeof imageData === "string" || isArrayBufferView(imageData)) { 9853 return sHashCode(imageData); 9854 } else if (isArrayBufferView(imageData.data)) { 9855 return sHashCode(imageData.data); 9856 } 9857 9858 return null; 9859 }; 9860 9861 var isImageTypeSupported = function isImageTypeSupported(type) { 9862 return typeof jsPDFAPI["process" + type.toUpperCase()] === "function"; 9863 }; 9864 9865 var isDOMElement = function isDOMElement(object) { 9866 return _typeof(object) === "object" && object.nodeType === 1; 9867 }; 9868 9869 var getImageDataFromElement = function getImageDataFromElement(element, format) { 9870 //if element is an image which uses data url definition, just return the dataurl 9871 if (element.nodeName === "IMG" && element.hasAttribute("src")) { 9872 var src = "" + element.getAttribute("src"); //is base64 encoded dataUrl, directly process it 9873 9874 if (src.indexOf("data:image/") === 0) { 9875 return atob(unescape(src).split("base64,").pop()); 9876 } //it is probably an url, try to load it 9877 9878 9879 var tmpImageData = jsPDFAPI.loadFile(src, true); 9880 9881 if (tmpImageData !== undefined) { 9882 return tmpImageData; 9883 } 9884 } 9885 9886 if (element.nodeName === "CANVAS") { 9887 if (element.width === 0 || element.height === 0) { 9888 throw new Error("Given canvas must have data. Canvas width: " + element.width + ", height: " + element.height); 9889 } 9890 9891 var mimeType; 9892 9893 switch (format) { 9894 case "PNG": 9895 mimeType = "image/png"; 9896 break; 9897 9898 case "WEBP": 9899 mimeType = "image/webp"; 9900 break; 9901 9902 case "JPEG": 9903 case "JPG": 9904 default: 9905 mimeType = "image/jpeg"; 9906 break; 9907 } 9908 9909 return atob(element.toDataURL(mimeType, 1.0).split("base64,").pop()); 9910 } 9911 }; 9912 9913 var checkImagesForAlias = function checkImagesForAlias(alias) { 9914 var images = this.internal.collections[namespace + "images"]; 9915 9916 if (images) { 9917 for (var e in images) { 9918 if (alias === images[e].alias) { 9919 return images[e]; 9920 } 9921 } 9922 } 9923 }; 9924 9925 var determineWidthAndHeight = function determineWidthAndHeight(width, height, image) { 9926 if (!width && !height) { 9927 width = -96; 9928 height = -96; 9929 } 9930 9931 if (width < 0) { 9932 width = -1 * image.width * 72 / width / this.internal.scaleFactor; 9933 } 9934 9935 if (height < 0) { 9936 height = -1 * image.height * 72 / height / this.internal.scaleFactor; 9937 } 9938 9939 if (width === 0) { 9940 width = height * image.width / image.height; 9941 } 9942 9943 if (height === 0) { 9944 height = width * image.height / image.width; 9945 } 9946 9947 return [width, height]; 9948 }; 9949 9950 var writeImageToPDF = function writeImageToPDF(x, y, width, height, image, rotation) { 9951 var dims = determineWidthAndHeight.call(this, width, height, image), 9952 coord = this.internal.getCoordinateString, 9953 vcoord = this.internal.getVerticalCoordinateString; 9954 var images = getImages.call(this); 9955 width = dims[0]; 9956 height = dims[1]; 9957 images[image.index] = image; 9958 9959 if (rotation) { 9960 rotation *= Math.PI / 180; 9961 var c = Math.cos(rotation); 9962 var s = Math.sin(rotation); //like in pdf Reference do it 4 digits instead of 2 9963 9964 var f4 = function f4(number) { 9965 return number.toFixed(4); 9966 }; 9967 9968 var rotationTransformationMatrix = [f4(c), f4(s), f4(s * -1), f4(c), 0, 0, "cm"]; 9969 } 9970 9971 this.internal.write("q"); //Save graphics state 9972 9973 if (rotation) { 9974 this.internal.write([1, "0", "0", 1, coord(x), vcoord(y + height), "cm"].join(" ")); //Translate 9975 9976 this.internal.write(rotationTransformationMatrix.join(" ")); //Rotate 9977 9978 this.internal.write([coord(width), "0", "0", coord(height), "0", "0", "cm"].join(" ")); //Scale 9979 } else { 9980 this.internal.write([coord(width), "0", "0", coord(height), coord(x), vcoord(y + height), "cm"].join(" ")); //Translate and Scale 9981 } 9982 9983 if (this.isAdvancedAPI()) { 9984 // draw image bottom up when in "advanced" API mode 9985 this.internal.write([1, 0, 0, -1, 0, 0, "cm"].join(" ")); 9986 } 9987 9988 this.internal.write("/I" + image.index + " Do"); //Paint Image 9989 9990 this.internal.write("Q"); //Restore graphics state 9991 }; 9992 /** 9993 * COLOR SPACES 9994 */ 9995 9996 9997 var color_spaces = jsPDFAPI.color_spaces = { 9998 DEVICE_RGB: "DeviceRGB", 9999 DEVICE_GRAY: "DeviceGray", 10000 DEVICE_CMYK: "DeviceCMYK", 10001 CAL_GREY: "CalGray", 10002 CAL_RGB: "CalRGB", 10003 LAB: "Lab", 10004 ICC_BASED: "ICCBased", 10005 INDEXED: "Indexed", 10006 PATTERN: "Pattern", 10007 SEPARATION: "Separation", 10008 DEVICE_N: "DeviceN" 10009 }; 10010 /** 10011 * DECODE METHODS 10012 */ 10013 10014 jsPDFAPI.decode = { 10015 DCT_DECODE: "DCTDecode", 10016 FLATE_DECODE: "FlateDecode", 10017 LZW_DECODE: "LZWDecode", 10018 JPX_DECODE: "JPXDecode", 10019 JBIG2_DECODE: "JBIG2Decode", 10020 ASCII85_DECODE: "ASCII85Decode", 10021 ASCII_HEX_DECODE: "ASCIIHexDecode", 10022 RUN_LENGTH_DECODE: "RunLengthDecode", 10023 CCITT_FAX_DECODE: "CCITTFaxDecode" 10024 }; 10025 /** 10026 * IMAGE COMPRESSION TYPES 10027 */ 10028 10029 var image_compression = jsPDFAPI.image_compression = { 10030 NONE: "NONE", 10031 FAST: "FAST", 10032 MEDIUM: "MEDIUM", 10033 SLOW: "SLOW" 10034 }; 10035 /** 10036 * @name sHashCode 10037 * @function 10038 * @param {string} data 10039 * @returns {string} 10040 */ 10041 10042 var sHashCode = jsPDFAPI.__addimage__.sHashCode = function (data) { 10043 var hash = 0, 10044 i, 10045 len; 10046 10047 if (typeof data === "string") { 10048 len = data.length; 10049 10050 for (i = 0; i < len; i++) { 10051 hash = (hash << 5) - hash + data.charCodeAt(i); 10052 hash |= 0; // Convert to 32bit integer 10053 } 10054 } else if (isArrayBufferView(data)) { 10055 len = data.byteLength / 2; 10056 10057 for (i = 0; i < len; i++) { 10058 hash = (hash << 5) - hash + data[i]; 10059 hash |= 0; // Convert to 32bit integer 10060 } 10061 } 10062 10063 return hash; 10064 }; 10065 /** 10066 * Validates if given String is a valid Base64-String 10067 * 10068 * @name validateStringAsBase64 10069 * @public 10070 * @function 10071 * @param {String} possible Base64-String 10072 * 10073 * @returns {boolean} 10074 */ 10075 10076 10077 var validateStringAsBase64 = jsPDFAPI.__addimage__.validateStringAsBase64 = function (possibleBase64String) { 10078 possibleBase64String = possibleBase64String || ""; 10079 possibleBase64String.toString().trim(); 10080 var result = true; 10081 10082 if (possibleBase64String.length === 0) { 10083 result = false;
10084 } 10085 10086 if (possibleBase64String.length % 4 !== 0) { 10087 result = false; 10088 } 10089 10090 if (/^[A-Za-z0-9+/]+$/.test(possibleBase64String.substr(0, possibleBase64String.length - 2)) === false) { 10091 result = false; 10092 } 10093 10094 if (/^[A-Za-z0-9/][A-Za-z0-9+/]|[A-Za-z0-9+/]=|==$/.test(possibleBase64String.substr(-2)) === false) { 10095 result = false; 10096 } 10097 10098 return result; 10099 }; 10100 /** 10101 * Strips out and returns info from a valid base64 data URI 10102 * 10103 * @name extractImageFromDataUrl 10104 * @function 10105 * @param {string} dataUrl a valid data URI of format 'data:[<MIME-type>][;base64],<data>' 10106 * @returns {Array}an Array containing the following 10107 * [0] the complete data URI 10108 * [1] <MIME-type> 10109 * [2] format - the second part of the mime-type i.e 'png' in 'image/png' 10110 * [4] <data> 10111 */ 10112 10113 10114 var extractImageFromDataUrl = jsPDFAPI.__addimage__.extractImageFromDataUrl = function (dataUrl) { 10115 dataUrl = dataUrl || ""; 10116 var dataUrlParts = dataUrl.split("base64,"); 10117 var result = null; 10118 10119 if (dataUrlParts.length === 2) { 10120 var extractedInfo = /^data:(\w*\/\w*);*(charset=(?!charset=)[\w=-]*)*;*$/.exec(dataUrlParts[0]); 10121 10122 if (Array.isArray(extractedInfo)) { 10123 result = { 10124 mimeType: extractedInfo[1], 10125 charset: extractedInfo[2], 10126 data: dataUrlParts[1] 10127 }; 10128 } 10129 } 10130 10131 return result; 10132 }; 10133 /** 10134 * Check to see if ArrayBuffer is supported 10135 * 10136 * @name supportsArrayBuffer 10137 * @function 10138 * @returns {boolean} 10139 */ 10140 10141 10142 var supportsArrayBuffer = jsPDFAPI.__addimage__.supportsArrayBuffer = function () { 10143 return typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; 10144 }; 10145 /** 10146 * Tests supplied object to determine if ArrayBuffer 10147 * 10148 * @name isArrayBuffer 10149 * @function 10150 * @param {Object} object an Object 10151 * 10152 * @returns {boolean} 10153 */ 10154 10155 10156 jsPDFAPI.__addimage__.isArrayBuffer = function (object) { 10157 return supportsArrayBuffer() && object instanceof ArrayBuffer; 10158 }; 10159 /** 10160 * Tests supplied object to determine if it implements the ArrayBufferView (TypedArray) interface 10161 * 10162 * @name isArrayBufferView 10163 * @function 10164 * @param {Object} object an Object 10165 * @returns {boolean} 10166 */ 10167 10168 10169 var isArrayBufferView = jsPDFAPI.__addimage__.isArrayBufferView = function (object) { 10170 return supportsArrayBuffer() && typeof Uint32Array !== "undefined" && (object instanceof Int8Array || object instanceof Uint8Array || typeof Uint8ClampedArray !== "undefined" && object instanceof Uint8ClampedArray || object instanceof Int16Array || object instanceof Uint16Array || object instanceof Int32Array || object instanceof Uint32Array || object instanceof Float32Array || object instanceof Float64Array); 10171 }; 10172 /** 10173 * Convert Binary String to ArrayBuffer 10174 * 10175 * @name binaryStringToUint8Array 10176 * @public 10177 * @function 10178 * @param {string} BinaryString with ImageData 10179 * @returns {Uint8Array} 10180 */ 10181 10182 10183 var binaryStringToUint8Array = jsPDFAPI.__addimage__.binaryStringToUint8Array = function (binary_string) { 10184 var len = binary_string.length; 10185 var bytes = new Uint8Array(len); 10186 10187 for (var i = 0; i < len; i++) { 10188 bytes[i] = binary_string.charCodeAt(i); 10189 } 10190 10191 return bytes; 10192 }; 10193 /** 10194 * Convert the Buffer to a Binary String 10195 * 10196 * @name arrayBufferToBinaryString 10197 * @public 10198 * @function 10199 * @param {ArrayBuffer|ArrayBufferView} ArrayBuffer buffer or bufferView with ImageData 10200 * 10201 * @returns {String} 10202 */ 10203 10204 10205 var arrayBufferToBinaryString = jsPDFAPI.__addimage__.arrayBufferToBinaryString = function (buffer) { 10206 var out = ""; // There are calls with both ArrayBuffer and already converted Uint8Array or other BufferView. 10207 // Do not copy the array if input is already an array. 10208 10209 var buf = isArrayBufferView(buffer) ? buffer : new Uint8Array(buffer); 10210 10211 for (var i = 0; i < buf.length; i += ARRAY_APPLY_BATCH) { 10212 // Limit the amount of characters being parsed to prevent overflow. 10213 // Note that while TextDecoder would be faster, it does not have the same 10214 // functionality as fromCharCode with any provided encodings as of 3/2021. 10215 out += String.fromCharCode.apply(null, buf.subarray(i, i + ARRAY_APPLY_BATCH)); 10216 } 10217 10218 return out; 10219 }; 10220 /** 10221 * Possible parameter for addImage, an RGBA buffer with size. 10222 * 10223 * @typedef {Object} RGBAData 10224 * @property {Uint8ClampedArray} data - Single dimensional array of RGBA values. For example from canvas getImageData. 10225 * @property {number} width - Image width as the data does not carry this information in itself. 10226 * @property {number} height - Image height as the data does not carry this information in itself. 10227 */ 10228 10229 /** 10230 * Adds an Image to the PDF. 10231 * 10232 * @name addImage 10233 * @public 10234 * @function 10235 * @param {string|HTMLImageElement|HTMLCanvasElement|Uint8Array|RGBAData} imageData imageData as base64 encoded DataUrl or Image-HTMLElement or Canvas-HTMLElement or object c
10235ontaining RGBA array (like output from canvas.getImageData). 10236 * @param {string} format format of file if filetype-recognition fails or in case of a Canvas-Element needs to be specified (default for Canvas is JPEG), e.g. 'JPEG', 'PNG', 'WEBP' 10237 * @param {number} x x Coordinate (in units declared at inception of PDF document) against left edge of the page 10238 * @param {number} y y Coordinate (in units declared at inception of PDF document) against upper edge of the page 10239 * @param {number} width width of the image (in units declared at inception of PDF document) 10240 * @param {number} height height of the Image (in units declared at inception of PDF document) 10241 * @param {string} alias alias of the image (if used multiple times) 10242 * @param {string} compression compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW' 10243 * @param {number} rotation rotation of the image in degrees (0-359) 10244 * 10245 * @returns jsPDF 10246 */ 10247 10248 10249 jsPDFAPI.addImage = function () { 10250 var imageData, format, x, y, w, h, alias, compression, rotation; 10251 imageData = arguments[0]; 10252 10253 if (typeof arguments[1] === "number") { 10254 format = UNKNOWN; 10255 x = arguments[1]; 10256 y = arguments[2]; 10257 w = arguments[3]; 10258 h = arguments[4]; 10259 alias = arguments[5]; 10260 compression = arguments[6]; 10261 rotation = arguments[7]; 10262 } else { 10263 format = arguments[1]; 10264 x = arguments[2]; 10265 y = arguments[3]; 10266 w = arguments[4]; 10267 h = arguments[5]; 10268 alias = arguments[6]; 10269 compression = arguments[7]; 10270 rotation = arguments[8]; 10271 } 10272 10273 if (_typeof(imageData) === "object" && !isDOMElement(imageData) && "imageData" in imageData) { 10274 var options = imageData; 10275 imageData = options.imageData; 10276 format = options.format || format || UNKNOWN; 10277 x = options.x || x || 0; 10278 y = options.y || y || 0; 10279 w = options.w || options.width || w; 10280 h = options.h || options.height || h; 10281 alias = options.alias || alias; 10282 compression = options.compression || compression; 10283 rotation = options.rotation || options.angle || rotation; 10284 } //If compression is not explicitly set, determine if we should use compression 10285 10286 10287 var filter = this.internal.getFilters(); 10288 10289 if (compression === undefined && filter.indexOf("FlateEncode") !== -1) { 10290 compression = "SLOW"; 10291 } 10292 10293 if (isNaN(x) || isNaN(y)) { 10294 throw new Error("Invalid coordinates passed to jsPDF.addImage"); 10295 } 10296 10297 initialize.call(this); 10298 var image = processImageData.call(this, imageData, format, alias, compression); 10299 writeImageToPDF.call(this, x, y, w, h, image, rotation); 10300 return this; 10301 }; 10302 10303 var processImageData = function processImageData(imageData, format, alias, compression) { 10304 var result, dataAsBinaryString; 10305 10306 if (typeof imageData === "string" && getImageFileTypeByImageData(imageData) === UNKNOWN) { 10307 imageData = unescape(imageData); 10308 var tmpImageData = convertBase64ToBinaryString(imageData, false); 10309 10310 if (tmpImageData !== "") { 10311 imageData = tmpImageData; 10312 } else { 10313 tmpImageData = jsPDFAPI.loadFile(imageData, true); 10314 10315 if (tmpImageData !== undefined) { 10316 imageData = tmpImageData; 10317 } 10318 } 10319 } 10320 10321 if (isDOMElement(imageData)) { 10322 imageData = getImageDataFromElement(imageData, format); 10323 } 10324 10325 format = getImageFileTypeByImageData(imageData, format); 10326 10327 if (!isImageTypeSupported(format)) { 10328 throw new Error("addImage does not support files of type '" + format + "', please ensure that a plugin for '" + format + "' support is added."); 10329 } // now do the heavy lifting 10330 10331 10332 if (notDefined(alias)) { 10333 alias = generateAliasFromImageData(imageData); 10334 } 10335 10336 result = checkImagesForAlias.call(this, alias); 10337 10338 if (!result) { 10339 if (supportsArrayBuffer()) { 10340 // no need to convert if imageData is already uint8array 10341 if (!(imageData instanceof Uint8Array) && format !== "RGBA") { 10342 dataAsBinaryString = imageData; 10343 imageData = binaryStringToUint8Array(imageData); 10344 } 10345 } 10346 10347 result = this["process" + format.toUpperCase()](imageData, getImageIndex.call(this), alias, checkCompressValue(compression), dataAsBinaryString); 10348 } 10349 10350 if (!result) { 10351 throw new Error("An unknown error occurred whilst processing the image."); 10352 } 10353 10354 return result; 10355 }; 10356 /** 10357 * @name convertBase64ToBinaryString 10358 * @function 10359 * @param {string} stringData 10360 * @returns {string} binary string 10361 */ 10362 10363 10364 var convertBase64ToBinaryString = jsPDFAPI.__addimage__.convertBase64ToBinaryString = function (stringData, throwError) { 10365 throwError = typeof throwError === "boolean" ? throwError : true; 10366 var base64Info; 10367 var imageData = ""; 10368 var rawData; 10369 10370 if (typeof stringData === "string") { 10371 base64Info = extractImageFromDataUrl(stringData); 10372 rawData = base64Info !== null ? base64Info.data : stringData; 10373 10374 try { 10375 imageData = atob(rawData); 10376 } catch (e) { 10377 if (throwError) {
vendor: 70,551 bytes, lines 10378-12564
10378 if (!validateStringAsBase64(rawData)) { 10379 throw new Error("Supplied Data is not a valid base64-String jsPDF.convertBase64ToBinaryString "); 10380 } else { 10381 throw new Error("atob-Error in jsPDF.convertBase64ToBinaryString " + e.message); 10382 } 10383 } 10384 } 10385 } 10386 10387 return imageData; 10388 }; 10389 /** 10390 * @name getImageProperties 10391 * @function 10392 * @param {Object} imageData 10393 * @returns {Object} 10394 */ 10395 10396 10397 jsPDFAPI.getImageProperties = function (imageData) { 10398 var image; 10399 var tmpImageData = ""; 10400 var format; 10401 10402 if (isDOMElement(imageData)) { 10403 imageData = getImageDataFromElement(imageData); 10404 } 10405 10406 if (typeof imageData === "string" && getImageFileTypeByImageData(imageData) === UNKNOWN) { 10407 tmpImageData = convertBase64ToBinaryString(imageData, false); 10408 10409 if (tmpImageData === "") { 10410 tmpImageData = jsPDFAPI.loadFile(imageData) || ""; 10411 } 10412 10413 imageData = tmpImageData; 10414 } 10415 10416 format = getImageFileTypeByImageData(imageData); 10417 10418 if (!isImageTypeSupported(format)) { 10419 throw new Error("addImage does not support files of type '" + format + "', please ensure that a plugin for '" + format + "' support is added."); 10420 } 10421 10422 if (supportsArrayBuffer() && !(imageData instanceof Uint8Array)) { 10423 imageData = binaryStringToUint8Array(imageData); 10424 } 10425 10426 image = this["process" + format.toUpperCase()](imageData); 10427 10428 if (!image) { 10429 throw new Error("An unknown error occurred whilst processing the image"); 10430 } 10431 10432 image.fileType = format; 10433 return image; 10434 }; 10435 })(jsPDF.API); 10436 10437 /** 10438 * @license 10439 * Copyright (c) 2014 Steven Spungin (TwelveTone LLC) [email protected] 10440 * 10441 * Licensed under the MIT License. 10442 * http://opensource.org/licenses/mit-license 10443 */ 10444 10445 (function (jsPDFAPI) { 10446 10447 var notEmpty = function notEmpty(obj) { 10448 if (typeof obj != "undefined") { 10449 if (obj != "") { 10450 return true; 10451 } 10452 } 10453 }; 10454 10455 jsPDF.API.events.push(["addPage", function (addPageData) { 10456 var pageInfo = this.internal.getPageInfo(addPageData.pageNumber); 10457 pageInfo.pageContext.annotations = []; 10458 }]); 10459 jsPDFAPI.events.push(["putPage", function (putPageData) { 10460 var getHorizontalCoordinateString = this.internal.getCoordinateString; 10461 var getVerticalCoordinateString = this.internal.getVerticalCoordinateString; 10462 var pageInfo = this.internal.getPageInfoByObjId(putPageData.objId); 10463 var pageAnnos = putPageData.pageContext.annotations; 10464 var anno, rect, line; 10465 var found = false; 10466 10467 for (var a = 0; a < pageAnnos.length && !found; a++) { 10468 anno = pageAnnos[a]; 10469 10470 switch (anno.type) { 10471 case "link": 10472 if (notEmpty(anno.options.url) || notEmpty(anno.options.pageNumber)) { 10473 found = true; 10474 } 10475 10476 break; 10477 10478 case "reference": 10479 case "text": 10480 case "freetext": 10481 found = true; 10482 break; 10483 } 10484 } 10485 10486 if (found == false) { 10487 return; 10488 } 10489 10490 this.internal.write("/Annots ["); 10491 10492 for (var i = 0; i < pageAnnos.length; i++) { 10493 anno = pageAnnos[i]; 10494 var escape = this.internal.pdfEscape; 10495 var encryptor = this.internal.getEncryptor(putPageData.objId); 10496 10497 switch (anno.type) { 10498 case "reference": 10499 // References to Widget Annotations (for AcroForm Fields) 10500 this.internal.write(" " + anno.object.objId + " 0 R "); 10501 break; 10502 10503 case "text": 10504 // Create a an object for both the text and the popup 10505 var objText = this.internal.newAdditionalObject(); 10506 var objPopup = this.internal.newAdditionalObject(); 10507 var encryptorText = this.internal.getEncryptor(objText.objId); 10508 var title = anno.title || "Note"; 10509 rect = "/Rect [" + getHorizontalCoordinateString(anno.bounds.x) + " " + getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) + " " + getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w) + " " + getVerticalCoordinateString(anno.bounds.y) + "] "; 10510 line = "<</Type /Annot /Subtype /" + "Text" + " " + rect + "/Contents (" + escape(encryptorText(anno.contents)) + ")"; 10511 line += " /Popup " + objPopup.objId + " 0 R"; 10512 line += " /P " + pageInfo.objId + " 0 R"; 10513 line += " /T (" + escape(encryptorText(title)) + ") >>"; 10514 objText.content = line; 10515 var parent = objText.objId + " 0 R"; 10516 var popoff = 30; 10517 rect = "/Rect [" + getHorizontalCoordinateString(anno.bounds.x + popoff) + " " + getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) + " " + getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w + popoff) + " " + getVerticalCoordinateString(anno.bounds.y) + "] "; 10518 line = "<</Type /Annot /Subtype /" + "Popup" + " " + rect + " /Parent " + parent; 10519 10520 if (anno.open) { 10521 line += " /Open true"; 10522 } 10523 10524 line += " >>"; 10525 objPopup.content = line; 10526 this.internal.write(objText.objId, "0 R", objPopup.objId, "0 R"); 10527 break; 10528 10529 case "freetext": 10530 rect = "/Rect [" + getHorizontalCoordinateString(anno.bounds.x) + " " + getVerticalCoordinateString(anno.bounds.y) + " " + getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w) + " " + getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) + "] "; 10531 var color = anno.color || "#000000"; 10532 line = "<</Type /Annot /Subtype /" + "FreeText" + " " + rect + "/Contents (" + escape(encryptor(anno.contents)) + ")"; 10533 line += " /DS(font: Helvetica,sans-serif 12.0pt; text-align:left; color:#" + color + ")"; 10534 line += " /Border [0 0 0]"; 10535 line += " >>"; 10536 this.internal.write(line); 10537 break; 10538 10539 case "link": 10540 if (anno.options.name) { 10541 var loc = this.annotations._nameMap[anno.options.name]; 10542 anno.options.pageNumber = loc.page; 10543 anno.options.top = loc.y; 10544 } else { 10545 if (!anno.options.top) { 10546 anno.options.top = 0; 10547 } 10548 } 10549 10550 rect = "/Rect [" + anno.finalBounds.x + " " + anno.finalBounds.y + " " + anno.finalBounds.w + " " + anno.finalBounds.h + "] "; 10551 line = ""; 10552 10553 if (anno.options.url) { 10554 line = "<</Type /Annot /Subtype /Link " + rect + "/Border [0 0 0] /A <</S /URI /URI (" + escape(encryptor(anno.options.url)) + ") >>"; 10555 } else if (anno.options.pageNumber) { 10556 // first page is 0 10557 var info = this.internal.getPageInfo(anno.options.pageNumber); 10558 line = "<</Type /Annot /Subtype /Link " + rect + "/Border [0 0 0] /Dest [" + info.objId + " 0 R"; 10559 anno.options.magFactor = anno.options.magFactor || "XYZ"; 10560 10561 switch (anno.options.magFactor) { 10562 case "Fit": 10563 line += " /Fit]"; 10564 break; 10565 10566 case "FitH": 10567 line += " /FitH " + anno.options.top + "]"; 10568 break; 10569 10570 case "FitV": 10571 anno.options.left = anno.options.left || 0; 10572 line += " /FitV " + anno.options.left + "]"; 10573 break; 10574 10575 case "XYZ": 10576 default: 10577 var top = getVerticalCoordinateString(anno.options.top); 10578 anno.options.left = anno.options.left || 0; // 0 or null zoom will not change zoom factor 10579 10580 if (typeof anno.options.zoom === "undefined") { 10581 anno.options.zoom = 0; 10582 } 10583 10584 line += " /XYZ " + anno.options.left + " " + top + " " + anno.options.zoom + "]"; 10585 break; 10586 } 10587 } 10588 10589 if (line != "") { 10590 line += " >>"; 10591 this.internal.write(line); 10592 } 10593 10594 break; 10595 } 10596 } 10597 10598 this.internal.write("]"); 10599 }]); 10600 /** 10601 * @name createAnnotation 10602 * @function 10603 * @param {Object} options 10604 */ 10605 10606 jsPDFAPI.createAnnotation = function (options) { 10607 var pageInfo = this.internal.getCurrentPageInfo(); 10608 10609 switch (options.type) { 10610 case "link": 10611 this.link(options.bounds.x, options.bounds.y, options.bounds.w, options.bounds.h, options); 10612 break; 10613 10614 case "text": 10615 case "freetext": 10616 pageInfo.pageContext.annotations.push(options); 10617 break; 10618 } 10619 }; 10620 /** 10621 * Create a link 10622 * 10623 * valid options 10624 * <li> pageNumber or url [required] 10625 * <p>If pageNumber is specified, top and zoom may also be specified</p> 10626 * @name link 10627 * @function 10628 * @param {number} x 10629 * @param {number} y 10630 * @param {number} w 10631 * @param {number} h 10632 * @param {Object} options 10633 */ 10634 10635 10636 jsPDFAPI.link = function (x, y, w, h, options) { 10637 var pageInfo = this.internal.getCurrentPageInfo(); 10638 var getHorizontalCoordinateString = this.internal.getCoordinateString; 10639 var getVerticalCoordinateString = this.internal.getVerticalCoordinateString; 10640 pageInfo.pageContext.annotations.push({ 10641 finalBounds: { 10642 x: getHorizontalCoordinateString(x), 10643 y: getVerticalCoordinateString(y), 10644 w: getHorizontalCoordinateString(x + w), 10645 h: getVerticalCoordinateString(y + h) 10646 }, 10647 options: options, 10648 type: "link" 10649 }); 10650 }; 10651 /** 10652 * Currently only supports single line text. 10653 * Returns the width of the text/link 10654 * 10655 * @name textWithLink 10656 * @function 10657 * @param {string} text 10658 * @param {number} x 10659 * @param {number} y 10660 * @param {Object} options 10661 * @returns {number} width the width of the text/link 10662 */ 10663 10664 10665 jsPDFAPI.textWithLink = function (text, x, y, options) { 10666 var totalLineWidth = this.getTextWidth(text); 10667 var lineHeight = this.internal.getLineHeight() / this.internal.scaleFactor; 10668 var linkHeight, linkWidth; // Checking if maxWidth option is passed to determine lineWidth and number of lines for each line 10669 10670 if (options.maxWidth !== undefined) { 10671 var maxWidth = options.maxWidth; 10672 linkWidth = maxWidth; 10673 var numOfLines = this.splitTextToSize(text, linkWidth).length; 10674 linkHeight = Math.ceil(lineHeight * numOfLines); 10675 } else { 10676 linkWidth = totalLineWidth; 10677 linkHeight = lineHeight; 10678 } 10679 10680 this.text(text, x, y, options); //TODO We really need the text baseline height to do this correctly. 10681 // Or ability to draw text on top, bottom, center, or baseline. 10682 10683 y += lineHeight * 0.2; //handle x position based on the align option 10684 10685 if (options.align === "center") { 10686 x = x - totalLineWidth / 2; //since starting from center move the x position by half of text width 10687 } 10688 10689 if (options.align === "right") { 10690 x = x - totalLineWidth; 10691 } 10692 10693 this.link(x, y - lineHeight, linkWidth, linkHeight, options); 10694 return totalLineWidth; 10695 }; //TODO move into external library 10696 10697 /** 10698 * @name getTextWidth 10699 * @function 10700 * @param {string} text 10701 * @returns {number} txtWidth 10702 */ 10703 10704 10705 jsPDFAPI.getTextWidth = function (text) { 10706 var fontSize = this.internal.getFontSize(); 10707 var txtWidth = this.getStringUnitWidth(text) * fontSize / this.internal.scaleFactor; 10708 return txtWidth; 10709 }; 10710 10711 return this; 10712 })(jsPDF.API); 10713 10714 /** 10715 * @license 10716 * Copyright (c) 2017 Aras Abbasi 10717 * 10718 * Licensed under the MIT License. 10719 * http://opensource.org/licenses/mit-license 10720 */ 10721 /** 10722 * jsPDF arabic parser PlugIn 10723 * 10724 * @name arabic 10725 * @module 10726 */ 10727 10728 (function (jsPDFAPI) { 10729 /** 10730 * Arabic shape substitutions: char code => (isolated, final, initial, medial). 10731 * Arabic Substition A 10732 */ 10733 10734 var arabicSubstitionA = { 10735 0x0621: [0xfe80], 10736 // ARABIC LETTER HAMZA 10737 0x0622: [0xfe81, 0xfe82], 10738 // ARABIC LETTER ALEF WITH MADDA ABOVE 10739 0x0623: [0xfe83, 0xfe84], 10740 // ARABIC LETTER ALEF WITH HAMZA ABOVE 10741 0x0624: [0xfe85, 0xfe86], 10742 // ARABIC LETTER WAW WITH HAMZA ABOVE 10743 0x0625: [0xfe87, 0xfe88], 10744 // ARABIC LETTER ALEF WITH HAMZA BELOW 10745 0x0626: [0xfe89, 0xfe8a, 0xfe8b, 0xfe8c], 10746 // ARABIC LETTER YEH WITH HAMZA ABOVE 10747 0x0627: [0xfe8d, 0xfe8e], 10748 // ARABIC LETTER ALEF 10749 0x0628: [0xfe8f, 0xfe90, 0xfe91, 0xfe92], 10750 // ARABIC LETTER BEH 10751 0x0629: [0xfe93, 0xfe94], 10752 // ARABIC LETTER TEH MARBUTA 10753 0x062a: [0xfe95, 0xfe96, 0xfe97, 0xfe98], 10754 // ARABIC LETTER TEH 10755 0x062b: [0xfe99, 0xfe9a, 0xfe9b, 0xfe9c], 10756 // ARABIC LETTER THEH 10757 0x062c: [0xfe9d, 0xfe9e, 0xfe9f, 0xfea0], 10758 // ARABIC LETTER JEEM 10759 0x062d: [0xfea1, 0xfea2, 0xfea3, 0xfea4], 10760 // ARABIC LETTER HAH 10761 0x062e: [0xfea5, 0xfea6, 0xfea7, 0xfea8], 10762 // ARABIC LETTER KHAH 10763 0x062f: [0xfea9, 0xfeaa], 10764 // ARABIC LETTER DAL 10765 0x0630: [0xfeab, 0xfeac], 10766 // ARABIC LETTER THAL 10767 0x0631: [0xfead, 0xfeae], 10768 // ARABIC LETTER REH 10769 0x0632: [0xfeaf, 0xfeb0], 10770 // ARABIC LETTER ZAIN 10771 0x0633: [0xfeb1, 0xfeb2, 0xfeb3, 0xfeb4], 10772 // ARABIC LETTER SEEN 10773 0x0634: [0xfeb5, 0xfeb6, 0xfeb7, 0xfeb8], 10774 // ARABIC LETTER SHEEN 10775 0x0635: [0xfeb9, 0xfeba, 0xfebb, 0xfebc], 10776 // ARABIC LETTER SAD 10777 0x0636: [0xfebd, 0xfebe, 0xfebf, 0xfec0], 10778 // ARABIC LETTER DAD 10779 0x0637: [0xfec1, 0xfec2, 0xfec3, 0xfec4], 10780 // ARABIC LETTER TAH 10781 0x0638: [0xfec5, 0xfec6, 0xfec7, 0xfec8], 10782 // ARABIC LETTER ZAH 10783 0x0639: [0xfec9, 0xfeca, 0xfecb, 0xfecc], 10784 // ARABIC LETTER AIN 10785 0x063a: [0xfecd, 0xfece, 0xfecf, 0xfed0], 10786 // ARABIC LETTER GHAIN 10787 0x0641: [0xfed1, 0xfed2, 0xfed3, 0xfed4], 10788 // ARABIC LETTER FEH 10789 0x0642: [0xfed5, 0xfed6, 0xfed7, 0xfed8], 10790 // ARABIC LETTER QAF 10791 0x0643: [0xfed9, 0xfeda, 0xfedb, 0xfedc], 10792 // ARABIC LETTER KAF 10793 0x0644: [0xfedd, 0xfede, 0xfedf, 0xfee0], 10794 // ARABIC LETTER LAM 10795 0x0645: [0xfee1, 0xfee2, 0xfee3, 0xfee4], 10796 // ARABIC LETTER MEEM 10797 0x0646: [0xfee5, 0xfee6, 0xfee7, 0xfee8], 10798 // ARABIC LETTER NOON 10799 0x0647: [0xfee9, 0xfeea, 0xfeeb, 0xfeec], 10800 // ARABIC LETTER HEH 10801 0x0648: [0xfeed, 0xfeee], 10802 // ARABIC LETTER WAW 10803 0x0649: [0xfeef, 0xfef0, 64488, 64489], 10804 // ARABIC LETTER ALEF MAKSURA 10805 0x064a: [0xfef1, 0xfef2, 0xfef3, 0xfef4], 10806 // ARABIC LETTER YEH 10807 0x0671: [0xfb50, 0xfb51], 10808 // ARABIC LETTER ALEF WASLA 10809 0x0677: [0xfbdd], 10810 // ARABIC LETTER U WITH HAMZA ABOVE 10811 0x0679: [0xfb66, 0xfb67, 0xfb68, 0xfb69], 10812 // ARABIC LETTER TTEH 10813 0x067a: [0xfb5e, 0xfb5f, 0xfb60, 0xfb61], 10814 // ARABIC LETTER TTEHEH 10815 0x067b: [0xfb52, 0xfb53, 0xfb54, 0xfb55], 10816 // ARABIC LETTER BEEH 10817 0x067e: [0xfb56, 0xfb57, 0xfb58, 0xfb59], 10818 // ARABIC LETTER PEH 10819 0x067f: [0xfb62, 0xfb63, 0xfb64, 0xfb65], 10820 // ARABIC LETTER TEHEH 10821 0x0680: [0xfb5a, 0xfb5b, 0xfb5c, 0xfb5d], 10822 // ARABIC LETTER BEHEH 10823 0x0683: [0xfb76, 0xfb77, 0xfb78, 0xfb79], 10824 // ARABIC LETTER NYEH 10825 0x0684: [0xfb72, 0xfb73, 0xfb74, 0xfb75], 10826 // ARABIC LETTER DYEH 10827 0x0686: [0xfb7a, 0xfb7b, 0xfb7c, 0xfb7d], 10828 // ARABIC LETTER TCHEH 10829 0x0687: [0xfb7e, 0xfb7f, 0xfb80, 0xfb81], 10830 // ARABIC LETTER TCHEHEH 10831 0x0688: [0xfb88, 0xfb89], 10832 // ARABIC LETTER DDAL 10833 0x068c: [0xfb84, 0xfb85], 10834 // ARABIC LETTER DAHAL 10835 0x068d: [0xfb82, 0xfb83], 10836 // ARABIC LETTER DDAHAL 10837 0x068e: [0xfb86, 0xfb87], 10838 // ARABIC LETTER DUL 10839 0x0691: [0xfb8c, 0xfb8d], 10840 // ARABIC LETTER RREH 10841 0x0698: [0xfb8a, 0xfb8b], 10842 // ARABIC LETTER JEH 10843 0x06a4: [0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d], 10844 // ARABIC LETTER VEH 10845 0x06a6: [0xfb6e, 0xfb6f, 0xfb70, 0xfb71], 10846 // ARABIC LETTER PEHEH 10847 0x06a9: [0xfb8e, 0xfb8f, 0xfb90, 0xfb91], 10848 // ARABIC LETTER KEHEH 10849 0x06ad: [0xfbd3, 0xfbd4, 0xfbd5, 0xfbd6], 10850 // ARABIC LETTER NG 10851 0x06af: [0xfb92, 0xfb93, 0xfb94, 0xfb95], 10852 // ARABIC LETTER GAF 10853 0x06b1: [0xfb9a, 0xfb9b, 0xfb9c, 0xfb9d], 10854 // ARABIC LETTER NGOEH 10855 0x06b3: [0xfb96, 0xfb97, 0xfb98, 0xfb99], 10856 // ARABIC LETTER GUEH 10857 0x06ba: [0xfb9e, 0xfb9f], 10858 // ARABIC LETTER NOON GHUNNA 10859 0x06bb: [0xfba0, 0xfba1, 0xfba2, 0xfba3], 10860 // ARABIC LETTER RNOON 10861 0x06be: [0xfbaa, 0xfbab, 0xfbac, 0xfbad], 10862 // ARABIC LETTER HEH DOACHASHMEE 10863 0x06c0: [0xfba4, 0xfba5], 10864 // ARABIC LETTER HEH WITH YEH ABOVE 10865 0x06c1: [0xfba6, 0xfba7, 0xfba8, 0xfba9], 10866 // ARABIC LETTER HEH GOAL 10867 0x06c5: [0xfbe0, 0xfbe1], 10868 // ARABIC LETTER KIRGHIZ OE 10869 0x06c6: [0xfbd9, 0xfbda], 10870 // ARABIC LETTER OE 10871 0x06c7: [0xfbd7, 0xfbd8], 10872 // ARABIC LETTER U 10873 0x06c8: [0xfbdb, 0xfbdc], 10874 // ARABIC LETTER YU 10875 0x06c9: [0xfbe2, 0xfbe3], 10876 // ARABIC LETTER KIRGHIZ YU 10877 0x06cb: [0xfbde, 0xfbdf], 10878 // ARABIC LETTER VE 10879 0x06cc: [0xfbfc, 0xfbfd, 0xfbfe, 0xfbff], 10880 // ARABIC LETTER FARSI YEH 10881 0x06d0: [0xfbe4, 0xfbe5, 0xfbe6, 0xfbe7], 10882 //ARABIC LETTER E 10883 0x06d2: [0xfbae, 0xfbaf], 10884 // ARABIC LETTER YEH BARREE 10885 0x06d3: [0xfbb0, 0xfbb1] // ARABIC LETTER YEH BARREE WITH HAMZA ABOVE 10886 10887 }; 10888 /* 10889 var ligaturesSubstitutionA = { 10890 0xFBEA: []// ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM 10891 }; 10892 */ 10893 10894 var ligatures = { 10895 0xfedf: { 10896 0xfe82: 0xfef5, 10897 // ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM 10898 0xfe84: 0xfef7, 10899 // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM 10900 0xfe88: 0xfef9, 10901 // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM 10902 0xfe8e: 0xfefb // ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM 10903 10904 }, 10905 0xfee0: { 10906 0xfe82: 0xfef6, 10907 // ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM 10908 0xfe84: 0xfef8, 10909 // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM 10910 0xfe88: 0xfefa, 10911 // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM 10912 0xfe8e: 0xfefc // ARABIC LIGATURE LAM WITH ALEF FINAL FORM 10913 10914 }, 10915 0xfe8d: { 10916 0xfedf: { 10917 0xfee0: { 10918 0xfeea: 0xfdf2 10919 } 10920 } 10921 }, 10922 // ALLAH 10923 0x0651: { 10924 0x064c: 0xfc5e, 10925 // Shadda + Dammatan 10926 0x064d: 0xfc5f, 10927 // Shadda + Kasratan 10928 0x064e: 0xfc60, 10929 // Shadda + Fatha 10930 0x064f: 0xfc61, 10931 // Shadda + Damma 10932 0x0650: 0xfc62 // Shadda + Kasra 10933 10934 } 10935 }; 10936 var arabic_diacritics = { 10937 1612: 64606, 10938 // Shadda + Dammatan 10939 1613: 64607, 10940 // Shadda + Kasratan 10941 1614: 64608, 10942 // Shadda + Fatha 10943 1615: 64609, 10944 // Shadda + Damma 10945 1616: 64610 // Shadda + Kasra 10946 10947 }; 10948 var alfletter = [1570, 1571, 1573, 1575]; 10949 var noChangeInForm = -1; 10950 var isolatedForm = 0; 10951 var finalForm = 1; 10952 var initialForm = 2; 10953 var medialForm = 3; 10954 jsPDFAPI.__arabicParser__ = {}; //private 10955 10956 var isInArabicSubstitutionA = jsPDFAPI.__arabicParser__.isInArabicSubstitutionA = function (letter) { 10957 return typeof arabicSubstitionA[letter.charCodeAt(0)] !== "undefined"; 10958 }; 10959 10960 var isArabicLetter = jsPDFAPI.__arabicParser__.isArabicLetter = function (letter) { 10961 return typeof letter === "string" && /^[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]+$/.test(letter); 10962 }; 10963 10964 var isArabicEndLetter = jsPDFAPI.__arabicParser__.isArabicEndLetter = function (letter) { 10965 return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length <= 2; 10966 }; 10967 10968 var isArabicAlfLetter = jsPDFAPI.__arabicParser__.isArabicAlfLetter = function (letter) { 10969 return isArabicLetter(letter) && alfletter.indexOf(letter.charCodeAt(0)) >= 0; 10970 }; 10971 10972 jsPDFAPI.__arabicParser__.arabicLetterHasIsolatedForm = function (letter) { 10973 return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length >= 1; 10974 }; 10975 10976 var arabicLetterHasFinalForm = jsPDFAPI.__arabicParser__.arabicLetterHasFinalForm = function (letter) { 10977 return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length >= 2; 10978 }; 10979 10980 jsPDFAPI.__arabicParser__.arabicLetterHasInitialForm = function (letter) { 10981 return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length >= 3; 10982 }; 10983 10984 var arabicLetterHasMedialForm = jsPDFAPI.__arabicParser__.arabicLetterHasMedialForm = function (letter) { 10985 return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length == 4; 10986 }; 10987 10988 var resolveLigatures = jsPDFAPI.__arabicParser__.resolveLigatures = function (letters) { 10989 var i = 0; 10990 var tmpLigatures = ligatures; 10991 var result = ""; 10992 var effectedLetters = 0; 10993 10994 for (i = 0; i < letters.length; i += 1) { 10995 if (typeof tmpLigatures[letters.charCodeAt(i)] !== "undefined") { 10996 effectedLetters++; 10997 tmpLigatures = tmpLigatures[letters.charCodeAt(i)]; 10998 10999 if (typeof tmpLigatures === "number") { 11000 result += String.fromCharCode(tmpLigatures); 11001 tmpLigatures = ligatures; 11002 effectedLetters = 0; 11003 } 11004 11005 if (i === letters.length - 1) { 11006 tmpLigatures = ligatures; 11007 result += letters.charAt(i - (effectedLetters - 1)); 11008 i = i - (effectedLetters - 1); 11009 effectedLetters = 0; 11010 } 11011 } else { 11012 tmpLigatures = ligatures; 11013 result += letters.charAt(i - effectedLetters); 11014 i = i - effectedLetters; 11015 effectedLetters = 0; 11016 } 11017 } 11018 11019 return result; 11020 }; 11021 11022 jsPDFAPI.__arabicParser__.isArabicDiacritic = function (letter) { 11023 return letter !== undefined && arabic_diacritics[letter.charCodeAt(0)] !== undefined; 11024 }; 11025 11026 var getCorrectForm = jsPDFAPI.__arabicParser__.getCorrectForm = function (currentChar, beforeChar, nextChar) { 11027 if (!isArabicLetter(currentChar)) { 11028 return -1; 11029 } 11030 11031 if (isInArabicSubstitutionA(currentChar) === false) { 11032 return noChangeInForm; 11033 } 11034 11035 if (!arabicLetterHasFinalForm(currentChar) || !isArabicLetter(beforeChar) && !isArabicLetter(nextChar) || !isArabicLetter(nextChar) && isArabicEndLetter(beforeChar) || isArabicEndLetter(currentChar) && !isArabicLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicAlfLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicEndLetter(beforeChar)) { 11036 return isolatedForm; 11037 } 11038 11039 if (arabicLetterHasMedialForm(currentChar) && isArabicLetter(beforeChar) && !isArabicEndLetter(beforeChar) && isArabicLetter(nextChar) && arabicLetterHasFinalForm(nextChar)) { 11040 return medialForm; 11041 } 11042 11043 if (isArabicEndLetter(currentChar) || !isArabicLetter(nextChar)) { 11044 return finalForm; 11045 } 11046 11047 return initialForm; 11048 }; 11049 /** 11050 * @name processArabic 11051 * @function 11052 * @param {string} text 11053 * @returns {string} 11054 */ 11055 11056 11057 var parseArabic = function parseArabic(text) { 11058 text = text || ""; 11059 var result = ""; 11060 var i = 0; 11061 var j = 0; 11062 var position = 0; 11063 var currentLetter = ""; 11064 var prevLetter = ""; 11065 var nextLetter = ""; 11066 var words = text.split("\\s+"); 11067 var newWords = []; 11068 11069 for (i = 0; i < words.length; i += 1) { 11070 newWords.push(""); 11071 11072 for (j = 0; j < words[i].length; j += 1) { 11073 currentLetter = words[i][j]; 11074 prevLetter = words[i][j - 1]; 11075 nextLetter = words[i][j + 1]; 11076 11077 if (isArabicLetter(currentLetter)) { 11078 position = getCorrectForm(currentLetter, prevLetter, nextLetter); 11079 11080 if (position !== -1) { 11081 newWords[i] += String.fromCharCode(arabicSubstitionA[currentLetter.charCodeAt(0)][position]); 11082 } else { 11083 newWords[i] += currentLetter; 11084 } 11085 } else { 11086 newWords[i] += currentLetter; 11087 } 11088 } 11089 11090 newWords[i] = resolveLigatures(newWords[i]); 11091 } 11092 11093 result = newWords.join(" "); 11094 return result; 11095 }; 11096 11097 var processArabic = jsPDFAPI.__arabicParser__.processArabic = jsPDFAPI.processArabic = function () { 11098 var text = typeof arguments[0] === "string" ? arguments[0] : arguments[0].text; 11099 var tmpText = []; 11100 var result; 11101 11102 if (Array.isArray(text)) { 11103 var i = 0; 11104 tmpText = []; 11105 11106 for (i = 0; i < text.length; i += 1) { 11107 if (Array.isArray(text[i])) { 11108 tmpText.push([parseArabic(text[i][0]), text[i][1], text[i][2]]); 11109 } else { 11110 tmpText.push([parseArabic(text[i])]); 11111 } 11112 } 11113 11114 result = tmpText; 11115 } else { 11116 result = parseArabic(text); 11117 } 11118 11119 if (typeof arguments[0] === "string") { 11120 return result; 11121 } else { 11122 arguments[0].text = result; 11123 return arguments[0]; 11124 } 11125 }; 11126 11127 jsPDFAPI.events.push(["preProcessText", processArabic]); 11128 })(jsPDF.API); 11129 11130 /** @license 11131 * jsPDF Autoprint Plugin 11132 * 11133 * Licensed under the MIT License. 11134 * http://opensource.org/licenses/mit-license 11135 */ 11136 /** 11137 * @name autoprint 11138 * @module 11139 */ 11140 11141 (function (jsPDFAPI) { 11142 /** 11143 * Makes the PDF automatically open the print-Dialog when opened in a PDF-viewer. 11144 * 11145 * @name autoPrint 11146 * @function 11147 * @param {Object} options (optional) Set the attribute variant to 'non-conform' (default) or 'javascript' to activate different methods of automatic printing when opening in a PDF-viewer . 11148 * @returns {jsPDF} 11149 * @example 11150 * var doc = new jsPDF(); 11151 * doc.text(10, 10, 'This is a test'); 11152 * doc.autoPrint({variant: 'non-conform'}); 11153 * doc.save('autoprint.pdf'); 11154 */ 11155 11156 jsPDFAPI.autoPrint = function (options) { 11157 11158 var refAutoPrintTag; 11159 options = options || {}; 11160 options.variant = options.variant || "non-conform"; 11161 11162 switch (options.variant) { 11163 case "javascript": 11164 //https://github.com/Rob--W/pdf.js/commit/c676ecb5a0f54677b9f3340c3ef2cf42225453bb 11165 this.addJS("print({});"); 11166 break; 11167 11168 case "non-conform": 11169 default: 11170 this.internal.events.subscribe("postPutResources", function () { 11171 refAutoPrintTag = this.internal.newObject(); 11172 this.internal.out("<<"); 11173 this.internal.out("/S /Named"); 11174 this.internal.out("/Type /Action"); 11175 this.internal.out("/N /Print"); 11176 this.internal.out(">>"); 11177 this.internal.out("endobj"); 11178 }); 11179 this.internal.events.subscribe("putCatalog", function () { 11180 this.internal.out("/OpenAction " + refAutoPrintTag + " 0 R"); 11181 }); 11182 break; 11183 } 11184 11185 return this; 11186 }; 11187 })(jsPDF.API); 11188 11189 /** 11190 * @license 11191 * Copyright (c) 2014 Steven Spungin (TwelveTone LLC) [email protected] 11192 * 11193 * Licensed under the MIT License. 11194 * http://opensource.org/licenses/mit-license 11195 */ 11196 /** 11197 * jsPDF Canvas PlugIn 11198 * This plugin mimics the HTML5 Canvas 11199 * 11200 * The goal is to provide a way for current canvas users to print directly to a PDF. 11201 * @name canvas 11202 * @module 11203 */ 11204 11205 (function (jsPDFAPI) { 11206 /** 11207 * @class Canvas 11208 * @classdesc A Canvas Wrapper for jsPDF 11209 */ 11210 11211 var Canvas = function Canvas() { 11212 var jsPdfInstance = undefined; 11213 Object.defineProperty(this, "pdf", { 11214 get: function get() { 11215 return jsPdfInstance; 11216 }, 11217 set: function set(value) { 11218 jsPdfInstance = value; 11219 } 11220 }); 11221 var _width = 150; 11222 /** 11223 * The height property is a positive integer reflecting the height HTML attribute of the <canvas> element interpreted in CSS pixels. When the attribute is not specified, or if it is set to an invalid value, like a negative, the default value of 150 is used. 11224 * This is one of the two properties, the other being width, that controls the size of the canvas. 11225 * 11226 * @name width 11227 */ 11228 11229 Object.defineProperty(this, "width", { 11230 get: function get() { 11231 return _width; 11232 }, 11233 set: function set(value) { 11234 if (isNaN(value) || Number.isInteger(value) === false || value < 0) { 11235 _width = 150; 11236 } else { 11237 _width = value; 11238 } 11239 11240 if (this.getContext("2d").pageWrapXEnabled) { 11241 this.getContext("2d").pageWrapX = _width + 1; 11242 } 11243 } 11244 }); 11245 var _height = 300; 11246 /** 11247 * The width property is a positive integer reflecting the width HTML attribute of the <canvas> element interpreted in CSS pixels. When the attribute is not specified, or if it is set to an invalid value, like a negative, the default value of 300 is used. 11248 * This is one of the two properties, the other being height, that controls the size of the canvas. 11249 * 11250 * @name height 11251 */ 11252 11253 Object.defineProperty(this, "height", { 11254 get: function get() { 11255 return _height; 11256 }, 11257 set: function set(value) { 11258 if (isNaN(value) || Number.isInteger(value) === false || value < 0) { 11259 _height = 300; 11260 } else { 11261 _height = value; 11262 } 11263 11264 if (this.getContext("2d").pageWrapYEnabled) { 11265 this.getContext("2d").pageWrapY = _height + 1; 11266 } 11267 } 11268 }); 11269 var _childNodes = []; 11270 Object.defineProperty(this, "childNodes", { 11271 get: function get() { 11272 return _childNodes; 11273 }, 11274 set: function set(value) { 11275 _childNodes = value; 11276 } 11277 }); 11278 var _style = {}; 11279 Object.defineProperty(this, "style", { 11280 get: function get() { 11281 return _style; 11282 }, 11283 set: function set(value) { 11284 _style = value; 11285 } 11286 }); 11287 Object.defineProperty(this, "parentNode", {}); 11288 }; 11289 /** 11290 * The getContext() method returns a drawing context on the canvas, or null if the context identifier is not supported. 11291 * 11292 * @name getContext 11293 * @function 11294 * @param {string} contextType Is a String containing the context identifier defining the drawing context associated to the canvas. Possible value is "2d", leading to the creation of a Context2D object representing a two-dimensional rendering context. 11295 * @param {object} contextAttributes 11296 */ 11297 11298 11299 Canvas.prototype.getContext = function (contextType, contextAttributes) { 11300 contextType = contextType || "2d"; 11301 var key; 11302 11303 if (contextType !== "2d") { 11304 return null; 11305 } 11306 11307 for (key in contextAttributes) { 11308 if (this.pdf.context2d.hasOwnProperty(key)) { 11309 this.pdf.context2d[key] = contextAttributes[key]; 11310 } 11311 } 11312 11313 this.pdf.context2d._canvas = this; 11314 return this.pdf.context2d; 11315 }; 11316 /** 11317 * The toDataURL() method is just a stub to throw an error if accidently called. 11318 * 11319 * @name toDataURL 11320 * @function 11321 */ 11322 11323 11324 Canvas.prototype.toDataURL = function () { 11325 throw new Error("toDataURL is not implemented."); 11326 }; 11327 11328 jsPDFAPI.events.push(["initialized", function () { 11329 this.canvas = new Canvas(); 11330 this.canvas.pdf = this; 11331 }]); 11332 return this; 11333 })(jsPDF.API); 11334 11335 /** 11336 * @name cell 11337 * @module 11338 */ 11339 11340 (function (jsPDFAPI) { 11341 11342 var NO_MARGINS = { 11343 left: 0, 11344 top: 0, 11345 bottom: 0, 11346 right: 0 11347 }; 11348 var px2pt = 0.264583 * 72 / 25.4; 11349 var printingHeaderRow = false; 11350 11351 var _initialize = function _initialize() { 11352 if (typeof this.internal.__cell__ === "undefined") { 11353 this.internal.__cell__ = {}; 11354 this.internal.__cell__.padding = 3; 11355 this.internal.__cell__.headerFunction = undefined; 11356 this.internal.__cell__.margins = Object.assign({}, NO_MARGINS); 11357 this.internal.__cell__.margins.width = this.getPageWidth(); 11358 11359 _reset.call(this); 11360 } 11361 }; 11362 11363 var _reset = function _reset() { 11364 this.internal.__cell__.lastCell = new Cell(); 11365 this.internal.__cell__.pages = 1; 11366 }; 11367 11368 var Cell = function Cell() { 11369 var _x = arguments[0]; 11370 Object.defineProperty(this, "x", { 11371 enumerable: true, 11372 get: function get() { 11373 return _x; 11374 }, 11375 set: function set(value) { 11376 _x = value; 11377 } 11378 }); 11379 var _y = arguments[1]; 11380 Object.defineProperty(this, "y", { 11381 enumerable: true, 11382 get: function get() { 11383 return _y; 11384 }, 11385 set: function set(value) { 11386 _y = value; 11387 } 11388 }); 11389 var _width = arguments[2]; 11390 Object.defineProperty(this, "width", { 11391 enumerable: true, 11392 get: function get() { 11393 return _width; 11394 }, 11395 set: function set(value) { 11396 _width = value; 11397 } 11398 }); 11399 var _height = arguments[3]; 11400 Object.defineProperty(this, "height", { 11401 enumerable: true, 11402 get: function get() { 11403 return _height; 11404 }, 11405 set: function set(value) { 11406 _height = value; 11407 } 11408 }); 11409 var _text = arguments[4]; 11410 Object.defineProperty(this, "text", { 11411 enumerable: true, 11412 get: function get() { 11413 return _text; 11414 }, 11415 set: function set(value) { 11416 _text = value; 11417 } 11418 }); 11419 var _lineNumber = arguments[5]; 11420 Object.defineProperty(this, "lineNumber", { 11421 enumerable: true, 11422 get: function get() { 11423 return _lineNumber; 11424 }, 11425 set: function set(value) { 11426 _lineNumber = value; 11427 } 11428 }); 11429 var _align = arguments[6]; 11430 Object.defineProperty(this, "align", { 11431 enumerable: true, 11432 get: function get() { 11433 return _align; 11434 }, 11435 set: function set(value) { 11436 _align = value; 11437 } 11438 }); 11439 return this; 11440 }; 11441 11442 Cell.prototype.clone = function () { 11443 return new Cell(this.x, this.y, this.width, this.height, this.text, this.lineNumber, this.align); 11444 }; 11445 11446 Cell.prototype.toArray = function () { 11447 return [this.x, this.y, this.width, this.height, this.text, this.lineNumber, this.align]; 11448 }; 11449 /** 11450 * @name setHeaderFunction 11451 * @function 11452 * @param {function} func 11453 */ 11454 11455 11456 jsPDFAPI.setHeaderFunction = function (func) { 11457 _initialize.call(this); 11458 11459 this.internal.__cell__.headerFunction = typeof func === "function" ? func : undefined; 11460 return this; 11461 }; 11462 /** 11463 * @name getTextDimensions 11464 * @function 11465 * @param {string} txt 11466 * @returns {Object} dimensions 11467 */ 11468 11469 11470 jsPDFAPI.getTextDimensions = function (text, options) { 11471 _initialize.call(this); 11472 11473 options = options || {}; 11474 var fontSize = options.fontSize || this.getFontSize(); 11475 var font = options.font || this.getFont(); 11476 var scaleFactor = options.scaleFactor || this.internal.scaleFactor; 11477 var width = 0; 11478 var amountOfLines = 0; 11479 var height = 0; 11480 var tempWidth = 0; 11481 var scope = this; 11482 11483 if (!Array.isArray(text) && typeof text !== "string") { 11484 if (typeof text === "number") { 11485 text = String(text); 11486 } else { 11487 throw new Error("getTextDimensions expects text-parameter to be of type String or type Number or an Array of Strings."); 11488 } 11489 } 11490 11491 var maxWidth = options.maxWidth; 11492 11493 if (maxWidth > 0) { 11494 if (typeof text === "string") { 11495 text = this.splitTextToSize(text, maxWidth); 11496 } else if (Object.prototype.toString.call(text) === "[object Array]") { 11497 text = text.reduce(function (acc, textLine) { 11498 return acc.concat(scope.splitTextToSize(textLine, maxWidth)); 11499 }, []); 11500 } 11501 } else { 11502 // Without the else clause, it will not work if you do not pass along maxWidth 11503 text = Array.isArray(text) ? text : [text]; 11504 } 11505 11506 for (var i = 0; i < text.length; i++) { 11507 tempWidth = this.getStringUnitWidth(text[i], { 11508 font: font 11509 }) * fontSize; 11510 11511 if (width < tempWidth) { 11512 width = tempWidth; 11513 } 11514 } 11515 11516 if (width !== 0) { 11517 amountOfLines = text.length; 11518 } 11519 11520 width = width / scaleFactor; 11521 height = Math.max((amountOfLines * fontSize * this.getLineHeightFactor() - fontSize * (this.getLineHeightFactor() - 1)) / scaleFactor, 0); 11522 return { 11523 w: width, 11524 h: height 11525 }; 11526 }; 11527 /** 11528 * @name cellAddPage 11529 * @function 11530 */ 11531 11532 11533 jsPDFAPI.cellAddPage = function () { 11534 _initialize.call(this); 11535 11536 this.addPage(); 11537 var margins = this.internal.__cell__.margins || NO_MARGINS; 11538 this.internal.__cell__.lastCell = new Cell(margins.left, margins.top, undefined, undefined); 11539 this.internal.__cell__.pages += 1; 11540 return this; 11541 }; 11542 /** 11543 * @name cell 11544 * @function 11545 * @param {number} x 11546 * @param {number} y 11547 * @param {number} width 11548 * @param {number} height 11549 * @param {string} text 11550 * @param {number} lineNumber lineNumber 11551 * @param {string} align 11552 * @return {jsPDF} jsPDF-instance 11553 */ 11554 11555 11556 var cell = jsPDFAPI.cell = function () { 11557 var currentCell; 11558 11559 if (arguments[0] instanceof Cell) { 11560 currentCell = arguments[0]; 11561 } else { 11562 currentCell = new Cell(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]); 11563 } 11564 11565 _initialize.call(this); 11566 11567 var lastCell = this.internal.__cell__.lastCell; 11568 var padding = this.internal.__cell__.padding; 11569 var margins = this.internal.__cell__.margins || NO_MARGINS; 11570 var tableHeaderRow = this.internal.__cell__.tableHeaderRow; 11571 var printHeaders = this.internal.__cell__.printHeaders; // If this is not the first cell, we must change its position 11572 11573 if (typeof lastCell.lineNumber !== "undefined") { 11574 if (lastCell.lineNumber === currentCell.lineNumber) { 11575 //Same line 11576 currentCell.x = (lastCell.x || 0) + (lastCell.width || 0); 11577 currentCell.y = lastCell.y || 0; 11578 } else { 11579 //New line 11580 if (lastCell.y + lastCell.height + currentCell.height + margins.bottom > this.getPageHeight()) { 11581 this.cellAddPage(); 11582 currentCell.y = margins.top; 11583 11584 if (printHeaders && tableHeaderRow) { 11585 this.printHeaderRow(currentCell.lineNumber, true); 11586 currentCell.y += tableHeaderRow[0].height; 11587 } 11588 } else { 11589 currentCell.y = lastCell.y + lastCell.height || currentCell.y; 11590 } 11591 } 11592 } 11593 11594 if (typeof currentCell.text[0] !== "undefined") { 11595 this.rect(currentCell.x, currentCell.y, currentCell.width, currentCell.height, printingHeaderRow === true ? "FD" : undefined); 11596 11597 if (currentCell.align === "right") { 11598 this.text(currentCell.text, currentCell.x + currentCell.width - padding, currentCell.y + padding, { 11599 align: "right", 11600 baseline: "top" 11601 }); 11602 } else if (currentCell.align === "center") { 11603 this.text(currentCell.text, currentCell.x + currentCell.width / 2, currentCell.y + padding, { 11604 align: "center", 11605 baseline: "top", 11606 maxWidth: currentCell.width - padding - padding 11607 }); 11608 } else { 11609 this.text(currentCell.text, currentCell.x + padding, currentCell.y + padding, { 11610 align: "left", 11611 baseline: "top", 11612 maxWidth: currentCell.width - padding - padding 11613 }); 11614 } 11615 } 11616 11617 this.internal.__cell__.lastCell = currentCell; 11618 return this; 11619 }; 11620 /** 11621 * Create a table from a set of data. 11622 * @name table 11623 * @function 11624 * @param {Integer} [x] : left-position for top-left corner of table 11625 * @param {Integer} [y] top-position for top-left corner of table 11626 * @param {Object[]} [data] An array of objects containing key-value pairs corresponding to a row of data. 11627 * @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost 11628 * @param {Object} [config.printHeaders] True to print column headers at the top of every page 11629 * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value 11630 * @param {Object} [config.margins] margin values for left, top, bottom, and width 11631 * @param {Object} [config.fontSize] Integer fontSize to use (optional) 11632 * @param {Object} [config.padding] cell-padding in pt to use (optional) 11633 * @param {Object} [config.headerBackgroundColor] default is #c8c8c8 (optional) 11634 * @param {Object} [config.headerTextColor] default is #000 (optional) 11635 * @param {Object} [config.rowStart] callback to handle before print each row (optional) 11636 * @param {Object} [config.cellStart] callback to handle before print each cell (optional) 11637 * @returns {jsPDF} jsPDF-instance 11638 */ 11639 11640 11641 jsPDFAPI.table = function (x, y, data, headers, config) { 11642 _initialize.call(this); 11643 11644 if (!data) { 11645 throw new Error("No data for PDF table."); 11646 } 11647 11648 config = config || {}; 11649 var headerNames = [], 11650 headerLabels = [], 11651 headerAligns = [], 11652 i, 11653 columnMatrix = {}, 11654 columnWidths = {}, 11655 column, 11656 columnMinWidths = [], 11657 j, 11658 tableHeaderConfigs = [], 11659 //set up defaults. If a value is provided in config, defaults will be overwritten: 11660 autoSize = config.autoSize || false, 11661 printHeaders = config.printHeaders === false ? false : true, 11662 fontSize = config.css && typeof config.css["font-size"] !== "undefined" ? config.css["font-size"] * 16 : config.fontSize || 12, 11663 margins = config.margins || Object.assign({ 11664 width: this.getPageWidth() 11665 }, NO_MARGINS), 11666 padding = typeof config.padding === "number" ? config.padding : 3, 11667 headerBackgroundColor = config.headerBackgroundColor || "#c8c8c8", 11668 headerTextColor = config.headerTextColor || "#000"; 11669 11670 _reset.call(this); 11671 11672 this.internal.__cell__.printHeaders = printHeaders; 11673 this.internal.__cell__.margins = margins; 11674 this.internal.__cell__.table_font_size = fontSize; 11675 this.internal.__cell__.padding = padding; 11676 this.internal.__cell__.headerBackgroundColor = headerBackgroundColor; 11677 this.internal.__cell__.headerTextColor = headerTextColor; 11678 this.setFontSize(fontSize); // Set header values 11679 11680 if (headers === undefined || headers === null) { 11681 // No headers defined so we derive from data 11682 headerNames = Object.keys(data[0]); 11683 headerLabels = headerNames; 11684 headerAligns = headerNames.map(function () { 11685 return "left"; 11686 }); 11687 } else if (Array.isArray(headers) && _typeof(headers[0]) === "object") { 11688 headerNames = headers.map(function (header) { 11689 return header.name; 11690 }); 11691 headerLabels = headers.map(function (header) { 11692 return header.prompt || header.name || ""; 11693 }); 11694 headerAligns = headers.map(function (header) { 11695 return header.align || "left"; 11696 }); // Split header configs into names and prompts 11697 11698 for (i = 0; i < headers.length; i += 1) { 11699 columnWidths[headers[i].name] = headers[i].width * px2pt; 11700 } 11701 } else if (Array.isArray(headers) && typeof headers[0] === "string") { 11702 headerNames = headers; 11703 headerLabels = headerNames; 11704 headerAligns = headerNames.map(function () { 11705 return "left"; 11706 }); 11707 } 11708 11709 if (autoSize || Array.isArray(headers) && typeof headers[0] === "string") { 11710 var headerName; 11711 11712 for (i = 0; i < headerNames.length; i += 1) { 11713 headerName = headerNames[i]; // Create a matrix of columns e.g., {column_title: [row1_Record, row2_Record]} 11714 11715 columnMatrix[headerName] = data.map(function (rec) { 11716 return rec[headerName]; 11717 }); // get header width 11718 11719 this.setFont(undefined, "bold"); 11720 columnMinWidths.push(this.getTextDimensions(headerLabels[i], { 11721 fontSize: this.internal.__cell__.table_font_size, 11722 scaleFactor: this.internal.scaleFactor 11723 }).w); 11724 column = columnMatrix[headerName]; // get cell widths 11725 11726 this.setFont(undefined, "normal"); 11727 11728 for (j = 0; j < column.length; j += 1) { 11729 columnMinWidths.push(this.getTextDimensions(column[j], { 11730 fontSize: this.internal.__cell__.table_font_size, 11731 scaleFactor: this.internal.scaleFactor 11732 }).w); 11733 } // get final column width 11734 11735 11736 columnWidths[headerName] = Math.max.apply(null, columnMinWidths) + padding + padding; //have to reset 11737 11738 columnMinWidths = []; 11739 } 11740 } // -- Construct the table 11741 11742 11743 if (printHeaders) { 11744 var row = {}; 11745 11746 for (i = 0; i < headerNames.length; i += 1) { 11747 row[headerNames[i]] = {}; 11748 row[headerNames[i]].text = headerLabels[i]; 11749 row[headerNames[i]].align = headerAligns[i]; 11750 } 11751 11752 var rowHeight = calculateLineHeight.call(this, row, columnWidths); // Construct the header row 11753 11754 tableHeaderConfigs = headerNames.map(function (value) { 11755 return new Cell(x, y, columnWidths[value], rowHeight, row[value].text, undefined, row[value].align); 11756 }); // Store the table header config 11757 11758 this.setTableHeaderRow(tableHeaderConfigs); // Print the header for the start of the table 11759 11760 this.printHeaderRow(1, false); 11761 } // Construct the data rows 11762 11763 11764 var align = headers.reduce(function (pv, cv) { 11765 pv[cv.name] = cv.align; 11766 return pv; 11767 }, {}); 11768 11769 for (i = 0; i < data.length; i += 1) { 11770 if ("rowStart" in config && config.rowStart instanceof Function) { 11771 config.rowStart({ 11772 row: i, 11773 data: data[i] 11774 }, this); 11775 } 11776 11777 var lineHeight = calculateLineHeight.call(this, data[i], columnWidths); 11778 11779 for (j = 0; j < headerNames.length; j += 1) { 11780 var cellData = data[i][headerNames[j]]; 11781 11782 if ("cellStart" in config && config.cellStart instanceof Function) { 11783 config.cellStart({ 11784 row: i, 11785 col: j, 11786 data: cellData 11787 }, this); 11788 } 11789 11790 cell.call(this, new Cell(x, y, columnWidths[headerNames[j]], lineHeight, cellData, i + 2, align[headerNames[j]])); 11791 } 11792 } 11793 11794 this.internal.__cell__.table_x = x; 11795 this.internal.__cell__.table_y = y; 11796 return this; 11797 }; 11798 /** 11799 * Calculate the height for containing the highest column 11800 * 11801 * @name calculateLineHeight 11802 * @function 11803 * @param {Object[]} model is the line of data we want to calculate the height of 11804 * @param {Integer[]} columnWidths is size of each column 11805 * @returns {number} lineHeight 11806 * @private 11807 */ 11808 11809 11810 var calculateLineHeight = function calculateLineHeight(model, columnWidths) { 11811 var padding = this.internal.__cell__.padding; 11812 var fontSize = this.internal.__cell__.table_font_size; 11813 var scaleFactor = this.internal.scaleFactor; 11814 return Object.keys(model).map(function (key) { 11815 var value = model[key]; 11816 return this.splitTextToSize(value.hasOwnProperty("text") ? value.text : value, columnWidths[key] - padding - padding); 11817 }, this).map(function (value) { 11818 return this.getLineHeightFactor() * value.length * fontSize / scaleFactor + padding + padding; 11819 }, this).reduce(function (pv, cv) { 11820 return Math.max(pv, cv); 11821 }, 0); 11822 }; 11823 /** 11824 * Store the config for outputting a table header 11825 * 11826 * @name setTableHeaderRow 11827 * @function 11828 * @param {Object[]} config 11829 * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell 11830 * except the lineNumber parameter is excluded 11831 */ 11832 11833 11834 jsPDFAPI.setTableHeaderRow = function (config) { 11835 _initialize.call(this); 11836 11837 this.internal.__cell__.tableHeaderRow = config; 11838 }; 11839 /** 11840 * Output the store header row 11841 * 11842 * @name printHeaderRow 11843 * @function 11844 * @param {number} lineNumber The line number to output the header at 11845 * @param {boolean} new_page 11846 */ 11847 11848 11849 jsPDFAPI.printHeaderRow = function (lineNumber, new_page) { 11850 _initialize.call(this); 11851 11852 if (!this.internal.__cell__.tableHeaderRow) { 11853 throw new Error("Property tableHeaderRow does not exist."); 11854 } 11855 11856 var tableHeaderCell; 11857 printingHeaderRow = true; 11858 11859 if (typeof this.internal.__cell__.headerFunction === "function") { 11860 var position = this.internal.__cell__.headerFunction(this, this.internal.__cell__.pages); 11861 11862 this.internal.__cell__.lastCell = new Cell(position[0], position[1], position[2], position[3], undefined, -1); 11863 } 11864 11865 this.setFont(undefined, "bold"); 11866 var tempHeaderConf = []; 11867 11868 for (var i = 0; i < this.internal.__cell__.tableHeaderRow.length; i += 1) { 11869 tableHeaderCell = this.internal.__cell__.tableHeaderRow[i].clone(); 11870 11871 if (new_page) { 11872 tableHeaderCell.y = this.internal.__cell__.margins.top || 0; 11873 tempHeaderConf.push(tableHeaderCell); 11874 } 11875 11876 tableHeaderCell.lineNumber = lineNumber; 11877 var currentTextColor = this.getTextColor(); 11878 this.setTextColor(this.internal.__cell__.headerTextColor); 11879 this.setFillColor(this.internal.__cell__.headerBackgroundColor); 11880 cell.call(this, tableHeaderCell); 11881 this.setTextColor(currentTextColor); 11882 } 11883 11884 if (tempHeaderConf.length > 0) { 11885 this.setTableHeaderRow(tempHeaderConf); 11886 } 11887 11888 this.setFont(undefined, "normal"); 11889 printingHeaderRow = false; 11890 }; 11891 })(jsPDF.API); 11892 11893 function toLookup(arr) { 11894 return arr.reduce(function (lookup, name, index) { 11895 lookup[name] = index; 11896 return lookup; 11897 }, {}); 11898 } 11899 11900 var fontStyleOrder = { 11901 italic: ["italic", "oblique", "normal"], 11902 oblique: ["oblique", "italic", "normal"], 11903 normal: ["normal", "oblique", "italic"] 11904 }; 11905 var fontStretchOrder = ["ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "normal", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded"]; // For a given font-stretch value, we need to know where to start our search 11906 // from in the fontStretchOrder list. 11907 11908 var fontStretchLookup = toLookup(fontStretchOrder); 11909 var fontWeights = [100, 200, 300, 400, 500, 600, 700, 800, 900]; 11910 var fontWeightsLookup = toLookup(fontWeights); 11911 11912 function normalizeFontStretch(stretch) { 11913 stretch = stretch || "normal"; 11914 return typeof fontStretchLookup[stretch] === "number" ? stretch : "normal"; 11915 } 11916 11917 function normalizeFontStyle(style) { 11918 style = style || "normal"; 11919 return fontStyleOrder[style] ? style : "normal"; 11920 } 11921 11922 function normalizeFontWeight(weight) { 11923 if (!weight) { 11924 return 400; 11925 } 11926 11927 if (typeof weight === "number") { 11928 // Ignore values which aren't valid font-weights. 11929 return weight >= 100 && weight <= 900 && weight % 100 === 0 ? weight : 400; 11930 } 11931 11932 if (/^\d00$/.test(weight)) { 11933 return parseInt(weight); 11934 } 11935 11936 switch (weight) { 11937 case "bold": 11938 return 700; 11939 11940 case "normal": 11941 default: 11942 return 400; 11943 } 11944 } 11945 11946 function normalizeFontFace(fontFace) { 11947 var family = fontFace.family.replace(/"|'/g, "").toLowerCase(); 11948 var style = normalizeFontStyle(fontFace.style); 11949 var weight = normalizeFontWeight(fontFace.weight); 11950 var stretch = normalizeFontStretch(fontFace.stretch); 11951 return { 11952 family: family, 11953 style: style, 11954 weight: weight, 11955 stretch: stretch, 11956 src: fontFace.src || [], 11957 // The ref property maps this font-face to the font 11958 // added by the .addFont() method. 11959 ref: fontFace.ref || { 11960 name: family, 11961 style: [stretch, style, weight].join(" ") 11962 } 11963 }; 11964 } 11965 /** 11966 * Turns a list of font-faces into a map, for easier lookup when resolving 11967 * fonts. 11968 * @private 11969 */ 11970 11971 function buildFontFaceMap(fontFaces) { 11972 var map = {}; 11973 11974 for (var i = 0; i < fontFaces.length; ++i) { 11975 var normalized = normalizeFontFace(fontFaces[i]); 11976 var name = normalized.family; 11977 var stretch = normalized.stretch; 11978 var style = normalized.style; 11979 var weight = normalized.weight; 11980 map[name] = map[name] || {}; 11981 map[name][stretch] = map[name][stretch] || {}; 11982 map[name][stretch][style] = map[name][stretch][style] || {}; 11983 map[name][stretch][style][weight] = normalized; 11984 } 11985 11986 return map; 11987 } 11988 /** 11989 * Searches a map of stretches, weights, etc. in the given direction and 11990 * then, if no match has been found, in the opposite directions. 11991 * 11992 * @param {Object.<string, any>} matchingSet A map of the various font variations. 11993 * @param {any[]} order The order of the different variations 11994 * @param {number} pivot The starting point of the search in the order list. 11995 * @param {number} dir The initial direction of the search (desc = -1, asc = 1) 11996 * @private 11997 */ 11998 11999 function searchFromPivot(matchingSet, order, pivot, dir) { 12000 var i; 12001 12002 for (i = pivot; i >= 0 && i < order.length; i += dir) { 12003 if (matchingSet[order[i]]) { 12004 return matchingSet[order[i]]; 12005 } 12006 } 12007 12008 for (i = pivot; i >= 0 && i < order.length; i -= dir) { 12009 if (matchingSet[order[i]]) { 12010 return matchingSet[order[i]]; 12011 } 12012 } 12013 } 12014 12015 function resolveFontStretch(stretch, matchingSet) { 12016 if (matchingSet[stretch]) { 12017 return matchingSet[stretch]; 12018 } 12019 12020 var pivot = fontStretchLookup[stretch]; // If the font-stretch value is normal or more condensed, we want to 12021 // start with a descending search, otherwise we should do ascending. 12022 12023 var dir = pivot <= fontStretchLookup["normal"] ? -1 : 1; 12024 var match = searchFromPivot(matchingSet, fontStretchOrder, pivot, dir); 12025 12026 if (!match) { 12027 // Since a font-family cannot exist without having at least one stretch value 12028 // we should never reach this point. 12029 throw new Error("Could not find a matching font-stretch value for " + stretch); 12030 } 12031 12032 return match; 12033 } 12034 12035 function resolveFontStyle(fontStyle, matchingSet) { 12036 if (matchingSet[fontStyle]) { 12037 return matchingSet[fontStyle]; 12038 } 12039 12040 var ordering = fontStyleOrder[fontStyle]; 12041 12042 for (var i = 0; i < ordering.length; ++i) { 12043 if (matchingSet[ordering[i]]) { 12044 return matchingSet[ordering[i]]; 12045 } 12046 } // Since a font-family cannot exist without having at least one style value 12047 // we should never reach this point. 12048 12049 12050 throw new Error("Could not find a matching font-style for " + fontStyle); 12051 } 12052 12053 function resolveFontWeight(weight, matchingSet) { 12054 if (matchingSet[weight]) { 12055 return matchingSet[weight]; 12056 } 12057 12058 if (weight === 400 && matchingSet[500]) { 12059 return matchingSet[500]; 12060 } 12061 12062 if (weight === 500 && matchingSet[400]) { 12063 return matchingSet[400]; 12064 } 12065 12066 var pivot = fontWeightsLookup[weight]; // If the font-stretch value is normal or more condensed, we want to 12067 // start with a descending search, otherwise we should do ascending. 12068 12069 var dir = weight < 400 ? -1 : 1; 12070 var match = searchFromPivot(matchingSet, fontWeights, pivot, dir); 12071 12072 if (!match) { 12073 // Since a font-family cannot exist without having at least one stretch value 12074 // we should never reach this point. 12075 throw new Error("Could not find a matching font-weight for value " + weight); 12076 } 12077 12078 return match; 12079 } 12080 12081 var defaultGenericFontFamilies = { 12082 "sans-serif": "helvetica", 12083 fixed: "courier", 12084 monospace: "courier", 12085 terminal: "courier", 12086 cursive: "times", 12087 fantasy: "times", 12088 serif: "times" 12089 }; 12090 var systemFonts = { 12091 caption: "times", 12092 icon: "times", 12093 menu: "times", 12094 "message-box": "times", 12095 "small-caption": "times", 12096 "status-bar": "times" 12097 }; 12098 12099 function ruleToString(rule) { 12100 return [rule.stretch, rule.style, rule.weight, rule.family].join(" "); 12101 } 12102 12103 function resolveFontFace(fontFaceMap, rules, opts) { 12104 opts = opts || {}; 12105 var defaultFontFamily = opts.defaultFontFamily || "times"; 12106 var genericFontFamilies = Object.assign({}, defaultGenericFontFamilies, opts.genericFontFamilies || {}); 12107 var rule = null; 12108 var matches = null; 12109 12110 for (var i = 0; i < rules.length; ++i) { 12111 rule = normalizeFontFace(rules[i]); 12112 12113 if (genericFontFamilies[rule.family]) { 12114 rule.family = genericFontFamilies[rule.family]; 12115 } 12116 12117 if (fontFaceMap.hasOwnProperty(rule.family)) { 12118 matches = fontFaceMap[rule.family]; 12119 break; 12120 } 12121 } // Always fallback to a known font family. 12122 12123 12124 matches = matches || fontFaceMap[defaultFontFamily]; 12125 12126 if (!matches) { 12127 // At this point we should definitiely have a font family, but if we 12128 // don't there is something wrong with our configuration 12129 throw new Error("Could not find a font-family for the rule '" + ruleToString(rule) + "' and default family '" + defaultFontFamily + "'."); 12130 } 12131 12132 matches = resolveFontStretch(rule.stretch, matches); 12133 matches = resolveFontStyle(rule.style, matches); 12134 matches = resolveFontWeight(rule.weight, matches); 12135 12136 if (!matches) { 12137 // We should've fount 12138 throw new Error("Failed to resolve a font for the rule '" + ruleToString(rule) + "'."); 12139 } 12140 12141 return matches; 12142 } 12143 12144 function eatWhiteSpace(input) { 12145 return input.trimLeft(); 12146 } 12147 12148 function parseQuotedFontFamily(input, quote) { 12149 var index = 0; 12150 12151 while (index < input.length) { 12152 var current = input.charAt(index); 12153 12154 if (current === quote) { 12155 return [input.substring(0, index), input.substring(index + 1)]; 12156 } 12157 12158 index += 1; 12159 } // Unexpected end of input 12160 12161 12162 return null; 12163 } 12164 12165 function parseNonQuotedFontFamily(input) { 12166 // It implements part of the identifier parser here: https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier 12167 // 12168 // NOTE: This parser pretty much ignores escaped identifiers and that there is a thing called unicode. 12169 // 12170 // Breakdown of regexp: 12171 // -[a-z_] - when identifier starts with a hyphen, you're not allowed to have another hyphen or a digit 12172 // [a-z_] - allow a-z and underscore at beginning of input 12173 // [a-z0-9_-]* - after that, anything goes 12174 var match = input.match(/^(-[a-z_]|[a-z_])[a-z0-9_-]*/i); // non quoted value contains illegal characters 12175 12176 if (match === null) { 12177 return null; 12178 } 12179 12180 return [match[0], input.substring(match[0].length)]; 12181 } 12182 12183 var defaultFont = ["times"]; 12184 function parseFontFamily(input) { 12185 var result = []; 12186 var ch, parsed; 12187 var remaining = input.trim(); 12188 12189 if (remaining === "") { 12190 return defaultFont; 12191 } 12192 12193 if (remaining in systemFonts) { 12194 return [systemFonts[remaining]]; 12195 } 12196 12197 while (remaining !== "") { 12198 parsed = null; 12199 remaining = eatWhiteSpace(remaining); 12200 ch = remaining.charAt(0); 12201 12202 switch (ch) { 12203 case '"': 12204 case "'": 12205 parsed = parseQuotedFontFamily(remaining.substring(1), ch); 12206 break; 12207 12208 default: 12209 parsed = parseNonQuotedFontFamily(remaining); 12210 break; 12211 } 12212 12213 if (parsed === null) { 12214 return defaultFont; 12215 } 12216 12217 result.push(parsed[0]); 12218 remaining = eatWhiteSpace(parsed[1]); // We expect end of input or a comma separator here 12219 12220 if (remaining !== "" && remaining.charAt(0) !== ",") { 12221 return defaultFont; 12222 } 12223 12224 remaining = remaining.replace(/^,/, ""); 12225 } 12226 12227 return result; 12228 } 12229 12230 /** 12231 * This plugin mimics the HTML5 CanvasRenderingContext2D. 12232 * 12233 * The goal is to provide a way for current canvas implementations to print directly to a PDF. 12234 * 12235 * @name context2d 12236 * @module 12237 */ 12238 12239 (function (jsPDFAPI) { 12240 12241 var ContextLayer = function ContextLayer(ctx) { 12242 ctx = ctx || {}; 12243 this.isStrokeTransparent = ctx.isStrokeTransparent || false; 12244 this.strokeOpacity = ctx.strokeOpacity || 1; 12245 this.strokeStyle = ctx.strokeStyle || "#000000"; 12246 this.fillStyle = ctx.fillStyle || "#000000"; 12247 this.isFillTransparent = ctx.isFillTransparent || false; 12248 this.fillOpacity = ctx.fillOpacity || 1; 12249 this.font = ctx.font || "10px sans-serif"; 12250 this.textBaseline = ctx.textBaseline || "alphabetic"; 12251 this.textAlign = ctx.textAlign || "left"; 12252 this.lineWidth = ctx.lineWidth || 1; 12253 this.lineJoin = ctx.lineJoin || "miter"; 12254 this.lineCap = ctx.lineCap || "butt"; 12255 this.path = ctx.path || []; 12256 this.transform = typeof ctx.transform !== "undefined" ? ctx.transform.clone() : new Matrix(); 12257 this.globalCompositeOperation = ctx.globalCompositeOperation || "normal"; 12258 this.globalAlpha = ctx.globalAlpha || 1.0; 12259 this.clip_path = ctx.clip_path || []; 12260 this.currentPoint = ctx.currentPoint || new Point(); 12261 this.miterLimit = ctx.miterLimit || 10.0; 12262 this.lastPoint = ctx.lastPoint || new Point(); 12263 this.lineDashOffset = ctx.lineDashOffset || 0.0; 12264 this.lineDash = ctx.lineDash || []; 12265 this.margin = ctx.margin || [0, 0, 0, 0]; 12266 this.prevPageLastElemOffset = ctx.prevPageLastElemOffset || 0; 12267 this.ignoreClearRect = typeof ctx.ignoreClearRect === "boolean" ? ctx.ignoreClearRect : true; 12268 return this; 12269 }; //stub 12270 12271 12272 var f2, getHorizontalCoordinateString, getVerticalCoordinateString, getHorizontalCoordinate, getVerticalCoordinate, Point, Rectangle, Matrix, _ctx; 12273 12274 jsPDFAPI.events.push(["initialized", function () { 12275 this.context2d = new Context2D(this); 12276 f2 = this.internal.f2; 12277 getHorizontalCoordinateString = this.internal.getCoordinateString; 12278 getVerticalCoordinateString = this.internal.getVerticalCoordinateString; 12279 getHorizontalCoordinate = this.internal.getHorizontalCoordinate; 12280 getVerticalCoordinate = this.internal.getVerticalCoordinate; 12281 Point = this.internal.Point; 12282 Rectangle = this.internal.Rectangle; 12283 Matrix = this.internal.Matrix; 12284 _ctx = new ContextLayer(); 12285 }]); 12286 12287 var Context2D = function Context2D(pdf) { 12288 Object.defineProperty(this, "canvas", { 12289 get: function get() { 12290 return { 12291 parentNode: false, 12292 style: false 12293 }; 12294 } 12295 }); 12296 var _pdf = pdf; 12297 Object.defineProperty(this, "pdf", { 12298 get: function get() { 12299 return _pdf; 12300 } 12301 }); 12302 var _pageWrapXEnabled = false; 12303 /** 12304 * @name pageWrapXEnabled 12305 * @type {boolean} 12306 * @default false 12307 */ 12308 12309 Object.defineProperty(this, "pageWrapXEnabled", { 12310 get: function get() { 12311 return _pageWrapXEnabled; 12312 }, 12313 set: function set(value) { 12314 _pageWrapXEnabled = Boolean(value); 12315 } 12316 }); 12317 var _pageWrapYEnabled = false; 12318 /** 12319 * @name pageWrapYEnabled 12320 * @type {boolean} 12321 * @default true 12322 */ 12323 12324 Object.defineProperty(this, "pageWrapYEnabled", { 12325 get: function get() { 12326 return _pageWrapYEnabled; 12327 }, 12328 set: function set(value) { 12329 _pageWrapYEnabled = Boolean(value); 12330 } 12331 }); 12332 var _posX = 0; 12333 /** 12334 * @name posX 12335 * @type {number} 12336 * @default 0 12337 */ 12338 12339 Object.defineProperty(this, "posX", { 12340 get: function get() { 12341 return _posX; 12342 }, 12343 set: function set(value) { 12344 if (!isNaN(value)) { 12345 _posX = value; 12346 } 12347 } 12348 }); 12349 var _posY = 0; 12350 /** 12351 * @name posY 12352 * @type {number} 12353 * @default 0 12354 */ 12355 12356 Object.defineProperty(this, "posY", { 12357 get: function get() { 12358 return _posY; 12359 }, 12360 set: function set(value) { 12361 if (!isNaN(value)) { 12362 _posY = value; 12363 } 12364 } 12365 }); 12366 /** 12367 * Gets or sets the page margin when using auto paging. Has no effect when {@link autoPaging} is off. 12368 * @name margin 12369 * @type {number|number[]} 12370 * @default [0, 0, 0, 0] 12371 */ 12372 12373 Object.defineProperty(this, "margin", { 12374 get: function get() { 12375 return _ctx.margin; 12376 }, 12377 set: function set(value) { 12378 var margin; 12379 12380 if (typeof value === "number") { 12381 margin = [value, value, value, value]; 12382 } else { 12383 margin = new Array(4); 12384 margin[0] = value[0]; 12385 margin[1] = value.length >= 2 ? value[1] : margin[0]; 12386 margin[2] = value.length >= 3 ? value[2] : margin[0]; 12387 margin[3] = value.length >= 4 ? value[3] : margin[1]; 12388 } 12389 12390 _ctx.margin = margin; 12391 } 12392 }); 12393 var _autoPaging = false; 12394 /** 12395 * Gets or sets the auto paging mode. When auto paging is enabled, the context2d will automatically draw on the 12396 * next page if a shape or text chunk doesn't fit entirely on the current page. The context2d will create new 12397 * pages if required. 12398 * 12399 * Context2d supports different modes: 12400 * <ul> 12401 * <li> 12402 * <code>false</code>: Auto paging is disabled. 12403 * </li> 12404 * <li> 12405 * <code>true</code> or <code>'slice'</code>: Will cut shapes or text chunks across page breaks. Will possibly 12406 * slice text in half, making it difficult to read. 12407 * </li> 12408 * <li> 12409 * <code>'text'</code>: Trys not to cut text in half across page breaks. Works best for documents consisting 12410 * mostly of a single column of text. 12411 * </li> 12412 * </ul> 12413 * @name Context2D#autoPaging 12414 * @type {boolean|"slice"|"text"} 12415 * @default false 12416 */ 12417 12418 Object.defineProperty(this, "autoPaging", { 12419 get: function get() { 12420 return _autoPaging; 12421 }, 12422 set: function set(value) { 12423 _autoPaging = value; 12424 } 12425 }); 12426 var lastBreak = 0; 12427 /** 12428 * @name lastBreak 12429 * @type {number} 12430 * @default 0 12431 */ 12432 12433 Object.defineProperty(this, "lastBreak", { 12434 get: function get() { 12435 return lastBreak; 12436 }, 12437 set: function set(value) { 12438 lastBreak = value; 12439 } 12440 }); 12441 var pageBreaks = []; 12442 /** 12443 * Y Position of page breaks. 12444 * @name pageBreaks 12445 * @type {number} 12446 * @default 0 12447 */ 12448 12449 Object.defineProperty(this, "pageBreaks", { 12450 get: function get() { 12451 return pageBreaks; 12452 }, 12453 set: function set(value) { 12454 pageBreaks = value; 12455 } 12456 }); 12457 /** 12458 * @name ctx 12459 * @type {object} 12460 * @default {} 12461 */ 12462 12463 Object.defineProperty(this, "ctx", { 12464 get: function get() { 12465 return _ctx; 12466 }, 12467 set: function set(value) { 12468 if (value instanceof ContextLayer) { 12469 _ctx = value; 12470 } 12471 } 12472 }); 12473 /** 12474 * @name path 12475 * @type {array} 12476 * @default [] 12477 */ 12478 12479 Object.defineProperty(this, "path", { 12480 get: function get() { 12481 return _ctx.path; 12482 }, 12483 set: function set(value) { 12484 _ctx.path = value; 12485 } 12486 }); 12487 /** 12488 * @name ctxStack 12489 * @type {array} 12490 * @default [] 12491 */ 12492 12493 var _ctxStack = []; 12494 Object.defineProperty(this, "ctxStack", { 12495 get: function get() { 12496 return _ctxStack; 12497 }, 12498 set: function set(value) { 12499 _ctxStack = value; 12500 } 12501 }); 12502 /** 12503 * Sets or returns the color, gradient, or pattern used to fill the drawing 12504 * 12505 * @name fillStyle 12506 * @default #000000 12507 * @property {(color|gradient|pattern)} value The color of the drawing. Default value is #000000<br /> 12508 * A gradient object (linear or radial) used to fill the drawing (not supported by context2d)<br /> 12509 * A pattern object to use to fill the drawing (not supported by context2d) 12510 */ 12511 12512 Object.defineProperty(this, "fillStyle", { 12513 get: function get() { 12514 return this.ctx.fillStyle; 12515 }, 12516 set: function set(value) { 12517 var rgba; 12518 rgba = getRGBA(value); 12519 this.ctx.fillStyle = rgba.style; 12520 this.ctx.isFillTransparent = rgba.a === 0; 12521 this.ctx.fillOpacity = rgba.a; 12522 this.pdf.setFillColor(rgba.r, rgba.g, rgba.b, { 12523 a: rgba.a 12524 }); 12525 this.pdf.setTextColor(rgba.r, rgba.g, rgba.b, { 12526 a: rgba.a 12527 }); 12528 } 12529 }); 12530 /** 12531 * Sets or returns the color, gradient, or pattern used for strokes 12532 * 12533 * @name strokeStyle 12534 * @default #000000 12535 * @property {color} color A CSS color value that indicates the stroke color of the drawing. Default value is #000000 (not supported by context2d) 12536 * @property {gradient} gradient A gradient object (linear or radial) used to create a gradient stroke (not supported by context2d) 12537 * @property {pattern} pattern A pattern object used to create a pattern stroke (not supported by context2d) 12538 */ 12539 12540 Object.defineProperty(this, "strokeStyle", { 12541 get: function get() { 12542 return this.ctx.strokeStyle; 12543 }, 12544 set: function set(value) { 12545 var rgba = getRGBA(value); 12546 this.ctx.strokeStyle = rgba.style; 12547 this.ctx.isStrokeTransparent = rgba.a === 0; 12548 this.ctx.strokeOpacity = rgba.a; 12549 12550 if (rgba.a === 0) { 12551 this.pdf.setDrawColor(255, 255, 255); 12552 } else if (rgba.a === 1) { 12553 this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b); 12554 } else { 12555 this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b); 12556 } 12557 } 12558 }); 12559 /** 12560 * Sets or returns the style of the end caps for a line 12561 * 12562 * @name lineCap 12563 * @default butt 12564 * @property {(butt|round|square)} lineCap butt A flat edge is added to each end of the line <br/>
12565 * round A rounded end cap is added to each end of the line<br/> 12566 * square A square end cap is added to each end of the line<br/> 12567 */ 12568 12569 Object.defineProperty(this, "lineCap", { 12570 get: function get() { 12571 return this.ctx.lineCap; 12572 }, 12573 set: function set(value) { 12574 if (["butt", "round", "square"].indexOf(value) !== -1) { 12575 this.ctx.lineCap = value; 12576 this.pdf.setLineCap(value); 12577 } 12578 } 12579 }); 12580 /** 12581 * Sets or returns the current line width 12582 * 12583 * @name lineWidth 12584 * @default 1 12585 * @property {number} lineWidth The current line width, in pixels 12586 */ 12587 12588 Object.defineProperty(this, "lineWidth", { 12589 get: function get() { 12590 return this.ctx.lineWidth; 12591 }, 12592 set: function set(value) { 12593 if (!isNaN(value)) { 12594 this.ctx.lineWidth = value; 12595 this.pdf.setLineWidth(value); 12596 } 12597 } 12598 }); 12599 /** 12600 * Sets or returns the type of corner created, when two lines meet 12601 */ 12602 12603 Object.defineProperty(this, "lineJoin", { 12604 get: function get() { 12605 return this.ctx.lineJoin; 12606 }, 12607 set: function set(value) { 12608 if (["bevel", "round", "miter"].indexOf(value) !== -1) { 12609 this.ctx.lineJoin = value; 12610 this.pdf.setLineJoin(value); 12611 } 12612 } 12613 }); 12614 /** 12615 * A number specifying the miter limit ratio in coordinate space units. Zero, negative, Infinity, and NaN values are ignored. The default value is 10.0. 12616 * 12617 * @name miterLimit 12618 * @default 10 12619 */ 12620 12621 Object.defineProperty(this, "miterLimit", { 12622 get: function get() { 12623 return this.ctx.miterLimit; 12624 }, 12625 set: function set(value) { 12626 if (!isNaN(value)) { 12627 this.ctx.miterLimit = value; 12628 this.pdf.setMiterLimit(value); 12629 } 12630 } 12631 }); 12632 Object.defineProperty(this, "textBaseline", { 12633 get: function get() { 12634 return this.ctx.textBaseline; 12635 }, 12636 set: function set(value) { 12637 this.ctx.textBaseline = value; 12638 } 12639 }); 12640 Object.defineProperty(this, "textAlign", { 12641 get: function get() { 12642 return this.ctx.textAlign; 12643 }, 12644 set: function set(value) { 12645 if (["right", "end", "center", "left", "start"].indexOf(value) !== -1) { 12646 this.ctx.textAlign = value; 12647 } 12648 } 12649 }); 12650 var _fontFaceMap = null; 12651 12652 function getFontFaceMap(pdf, fontFaces) { 12653 if (_fontFaceMap === null) { 12654 var fontMap = pdf.getFontList(); 12655 var convertedFontFaces = convertToFontFaces(fontMap); 12656 _fontFaceMap = buildFontFaceMap(convertedFontFaces.concat(fontFaces)); 12657 } 12658 12659 return _fontFaceMap; 12660 } 12661 12662 function convertToFontFaces(fontMap) { 12663 var fontFaces = []; 12664 Object.keys(fontMap).forEach(function (family) { 12665 var styles = fontMap[family]; 12666 styles.forEach(function (style) { 12667 var fontFace = null; 12668 12669 switch (style) { 12670 case "bold": 12671 fontFace = { 12672 family: family, 12673 weight: "bold" 12674 }; 12675 break; 12676 12677 case "italic": 12678 fontFace = { 12679 family: family, 12680 style: "italic" 12681 }; 12682 break; 12683 12684 case "bolditalic": 12685 fontFace = { 12686 family: family, 12687 weight: "bold", 12688 style: "italic" 12689 }; 12690 break; 12691 12692 case "": 12693 case "normal": 12694 fontFace = { 12695 family: family 12696 }; 12697 break; 12698 } // If font-face is still null here, it is a font with some styling we don't recognize and 12699 // cannot map or it is a font added via the fontFaces option of .html(). 12700 12701 12702 if (fontFace !== null) { 12703 fontFace.ref = { 12704 name: family, 12705 style: style 12706 }; 12707 fontFaces.push(fontFace); 12708 } 12709 }); 12710 }); 12711 return fontFaces; 12712 } 12713 12714 var _fontFaces = null; 12715 /** 12716 * A map of available font-faces, as passed in the options of 12717 * .html(). If set a limited implementation of the font style matching 12718 * algorithm defined by https://www.w3.org/TR/css-fonts-3/#font-matching-algorithm 12719 * will be used. If not set it will fallback to previous behavior. 12720 */ 12721 12722 Object.defineProperty(this, "fontFaces", { 12723 get: function get() { 12724 return _fontFaces; 12725 }, 12726 set: function set(value) { 12727 _fontFaceMap = null; 12728 _fontFaces = value; 12729 } 12730 }); 12731 Object.defineProperty(this, "font", { 12732 get: function get() { 12733 return this.ctx.font; 12734 }, 12735 set: function set(value) { 12736 this.ctx.font = value; 12737 var rx, matches; //source: https://stackoverflow.com/a/10136041 12738 // eslint-disable-next-line no-useless-escape 12739
vendor: 9,636 bytes, lines 12740-13025
12740 rx = /^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:\%|in|[cem]m|ex|p[ctx]))(?:\s*\/\s*(normal|[.\d]+(?:\%|in|[cem]m|ex|p[ctx])))?\s*([-_,\"\'\sa-z]+?)\s*$/i; 12741 matches = rx.exec(value); 12742 12743 if (matches !== null) { 12744 var fontStyle = matches[1]; 12745 var fontVariant = matches[2]; 12746 var fontWeight = matches[3]; 12747 var fontSize = matches[4]; 12748 var lineHeight = matches[5]; 12749 var fontFamily = matches[6]; 12750 } else { 12751 return; 12752 } 12753 12754 var rxFontSize = /^([.\d]+)((?:%|in|[cem]m|ex|p[ctx]))$/i; 12755 var fontSizeUnit = rxFontSize.exec(fontSize)[2]; 12756 12757 if ("px" === fontSizeUnit) { 12758 fontSize = Math.floor(parseFloat(fontSize) * this.pdf.internal.scaleFactor); 12759 } else if ("em" === fontSizeUnit) { 12760 fontSize = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize()); 12761 } else { 12762 fontSize = Math.floor(parseFloat(fontSize) * this.pdf.internal.scaleFactor); 12763 } 12764 12765 this.pdf.setFontSize(fontSize); 12766 var parts = parseFontFamily(fontFamily); 12767 12768 if (this.fontFaces) { 12769 var fontFaceMap = getFontFaceMap(this.pdf, this.fontFaces); 12770 var rules = parts.map(function (ff) { 12771 return { 12772 family: ff, 12773 stretch: "normal", 12774 // TODO: Extract font-stretch from font rule (perhaps write proper parser for it?) 12775 weight: fontWeight, 12776 style: fontStyle 12777 }; 12778 }); 12779 var font = resolveFontFace(fontFaceMap, rules); 12780 this.pdf.setFont(font.ref.name, font.ref.style); 12781 return; 12782 } 12783 12784 var style = ""; 12785 12786 if (fontWeight === "bold" || parseInt(fontWeight, 10) >= 700 || fontStyle === "bold") { 12787 style = "bold"; 12788 } 12789 12790 if (fontStyle === "italic") { 12791 style += "italic"; 12792 } 12793 12794 if (style.length === 0) { 12795 style = "normal"; 12796 } 12797 12798 var jsPdfFontName = ""; 12799 var fallbackFonts = { 12800 arial: "Helvetica", 12801 Arial: "Helvetica", 12802 verdana: "Helvetica", 12803 Verdana: "Helvetica", 12804 helvetica: "Helvetica", 12805 Helvetica: "Helvetica", 12806 "sans-serif": "Helvetica", 12807 fixed: "Courier", 12808 monospace: "Courier", 12809 terminal: "Courier", 12810 cursive: "Times", 12811 fantasy: "Times", 12812 serif: "Times" 12813 }; 12814 12815 for (var i = 0; i < parts.length; i++) { 12816 if (this.pdf.internal.getFont(parts[i], style, { 12817 noFallback: true, 12818 disableWarning: true 12819 }) !== undefined) { 12820 jsPdfFontName = parts[i]; 12821 break; 12822 } else if (style === "bolditalic" && this.pdf.internal.getFont(parts[i], "bold", { 12823 noFallback: true, 12824 disableWarning: true 12825 }) !== undefined) { 12826 jsPdfFontName = parts[i]; 12827 style = "bold"; 12828 } else if (this.pdf.internal.getFont(parts[i], "normal", { 12829 noFallback: true, 12830 disableWarning: true 12831 }) !== undefined) { 12832 jsPdfFontName = parts[i]; 12833 style = "normal"; 12834 break; 12835 } 12836 } 12837 12838 if (jsPdfFontName === "") { 12839 for (var j = 0; j < parts.length; j++) { 12840 if (fallbackFonts[parts[j]]) { 12841 jsPdfFontName = fallbackFonts[parts[j]]; 12842 break; 12843 } 12844 } 12845 } 12846 12847 jsPdfFontName = jsPdfFontName === "" ? "Times" : jsPdfFontName; 12848 this.pdf.setFont(jsPdfFontName, style); 12849 } 12850 }); 12851 Object.defineProperty(this, "globalCompositeOperation", { 12852 get: function get() { 12853 return this.ctx.globalCompositeOperation; 12854 }, 12855 set: function set(value) { 12856 this.ctx.globalCompositeOperation = value; 12857 } 12858 }); 12859 Object.defineProperty(this, "globalAlpha", { 12860 get: function get() { 12861 return this.ctx.globalAlpha; 12862 }, 12863 set: function set(value) { 12864 this.ctx.globalAlpha = value; 12865 } 12866 }); 12867 /** 12868 * A float specifying the amount of the line dash offset. The default value is 0.0. 12869 * 12870 * @name lineDashOffset 12871 * @default 0.0 12872 */ 12873 12874 Object.defineProperty(this, "lineDashOffset", { 12875 get: function get() { 12876 return this.ctx.lineDashOffset; 12877 }, 12878 set: function set(value) { 12879 this.ctx.lineDashOffset = value; 12880 setLineDash.call(this); 12881 } 12882 }); // Not HTML API 12883 12884 Object.defineProperty(this, "lineDash", { 12885 get: function get() { 12886 return this.ctx.lineDash; 12887 }, 12888 set: function set(value) { 12889 this.ctx.lineDash = value; 12890 setLineDash.call(this); 12891 } 12892 }); // Not HTML API 12893 12894 Object.defineProperty(this, "ignoreClearRect", { 12895 get: function get() { 12896 return this.ctx.ignoreClearRect; 12897 }, 12898 set: function set(value) { 12899 this.ctx.ignoreClearRect = Boolean(value); 12900 } 12901 }); 12902 }; 12903 /** 12904 * Sets the line dash pattern used when stroking lines. 12905 * @name setLineDash 12906 * @function 12907 * @description It uses an array of values that specify alternating lengths of lines and gaps which describe the pattern. 12908 */ 12909 12910 12911 Context2D.prototype.setLineDash = function (dashArray) { 12912 this.lineDash = dashArray; 12913 }; 12914 /** 12915 * gets the current line dash pattern. 12916 * @name getLineDash 12917 * @function 12918 * @returns {Array} An Array of numbers that specify distances to alternately draw a line and a gap (in coordinate space units). If the number, when setting the elements, is odd, the elements of the array get copied and concatenated. For example, setting the line dash to [5, 15, 25] will result in getting back [5, 15, 25, 5, 15, 25]. 12919 */ 12920 12921 12922 Context2D.prototype.getLineDash = function () { 12923 if (this.lineDash.length % 2) { 12924 // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getLineDash#return_value 12925 return this.lineDash.concat(this.lineDash); 12926 } else { 12927 // The copied value is returned to prevent contamination from outside. 12928 return this.lineDash.slice(); 12929 } 12930 }; 12931 12932 Context2D.prototype.fill = function () { 12933 pathPreProcess.call(this, "fill", false); 12934 }; 12935 /** 12936 * Actually draws the path you have defined 12937 * 12938 * @name stroke 12939 * @function 12940 * @description The stroke() method actually draws the path you have defined with all those moveTo() and lineTo() methods. The default color is black. 12941 */ 12942 12943 12944 Context2D.prototype.stroke = function () { 12945 pathPreProcess.call(this, "stroke", false); 12946 }; 12947 /** 12948 * Begins a path, or resets the current 12949 * 12950 * @name beginPath 12951 * @function 12952 * @description The beginPath() method begins a path, or resets the current path. 12953 */ 12954 12955 12956 Context2D.prototype.beginPath = function () { 12957 this.path = [{ 12958 type: "begin" 12959 }]; 12960 }; 12961 /** 12962 * Moves the path to the specified point in the canvas, without creating a line 12963 * 12964 * @name moveTo 12965 * @function 12966 * @param x {Number} The x-coordinate of where to move the path to 12967 * @param y {Number} The y-coordinate of where to move the path to 12968 */ 12969 12970 12971 Context2D.prototype.moveTo = function (x, y) { 12972 if (isNaN(x) || isNaN(y)) { 12973 console.error("jsPDF.context2d.moveTo: Invalid arguments", arguments); 12974 throw new Error("Invalid arguments passed to jsPDF.context2d.moveTo"); 12975 } 12976 12977 var pt = this.ctx.transform.applyToPoint(new Point(x, y)); 12978 this.path.push({ 12979 type: "mt", 12980 x: pt.x, 12981 y: pt.y 12982 }); 12983 this.ctx.lastPoint = new Point(x, y); 12984 }; 12985 /** 12986 * Creates a path from the current point back to the starting point 12987 * 12988 * @name closePath 12989 * @function 12990 * @description The closePath() method creates a path from the current point back to the starting point. 12991 */ 12992 12993 12994 Context2D.prototype.closePath = function () { 12995 var pathBegin = new Point(0, 0); 12996 var i = 0; 12997 12998 for (i = this.path.length - 1; i !== -1; i--) { 12999 if (this.path[i].type === "begin") { 13000 if (_typeof(this.path[i + 1]) === "object" && typeof this.path[i + 1].x === "number") { 13001 pathBegin = new Point(this.path[i + 1].x, this.path[i + 1].y); 13002 break; 13003 } 13004 } 13005 } 13006 13007 this.path.push({ 13008 type: "close" 13009 }); 13010 this.ctx.lastPoint = new Point(pathBegin.x, pathBegin.y); 13011 }; 13012 /** 13013 * Adds a new point and creates a line to that point from the last specified point in the canvas 13014 * 13015 * @name lineTo 13016 * @function 13017 * @param x The x-coordinate of where to create the line to 13018 * @param y The y-coordinate of where to create the line to 13019 * @description The lineTo() method adds a new point and creates a line TO that point FROM the last specified point in the canvas (this method does not draw the line). 13020 */ 13021 13022 13023 Context2D.prototype.lineTo = function (x, y) { 13024 if (isNaN(x) || isNaN(y)) { 13025 console.error("jsPDF.context2d.lineTo: Invalid arguments", arguments);
13026 throw new Error("Invalid arguments passed to jsPDF.context2d.lineTo"); 13027 } 13028 13029 var pt = this.ctx.transform.applyToPoint(new Point(x, y)); 13030 this.path.push({ 13031 type: "lt", 13032 x: pt.x, 13033 y: pt.y 13034 }); 13035 this.ctx.lastPoint = new Point(pt.x, pt.y); 13036 }; 13037 /** 13038 * Clips a region of any shape and size from the original canvas 13039 * 13040 * @name clip 13041 * @function 13042 * @description The clip() method clips a region of any shape and size from the original canvas. 13043 */ 13044 13045 13046 Context2D.prototype.clip = function () { 13047 this.ctx.clip_path = JSON.parse(JSON.stringify(this.path)); 13048 pathPreProcess.call(this, null, true); 13049 }; 13050 /** 13051 * Creates a cubic Bézier curve 13052 * 13053 * @name quadraticCurveTo 13054 * @function 13055 * @param cpx {Number} The x-coordinate of the Bézier control point 13056 * @param cpy {Number} The y-coordinate of the Bézier control point 13057 * @param x {Number} The x-coordinate of the ending point 13058 * @param y {Number} The y-coordinate of the ending point 13059 * @description The quadraticCurveTo() method adds a point to the current path by using the specified control points that represent a quadratic Bézier curve.<br /><br /> A quadratic Bézier curve requires two points. The first point is a control point that is used in the quadratic Bézier calculation and the second point is the ending point for the curve. The starting point for the curve is the last point in the current path. If a path does not exist, use the beginPath() and moveTo() methods to define a starting point. 13060 */ 13061 13062 13063 Context2D.prototype.quadraticCurveTo = function (cpx, cpy, x, y) { 13064 if (isNaN(x) || isNaN(y) || isNaN(cpx) || isNaN(cpy)) { 13065 console.error("jsPDF.context2d.quadraticCurveTo: Invalid arguments", arguments); 13066 throw new Error("Invalid arguments passed to jsPDF.context2d.quadraticCurveTo"); 13067 } 13068 13069 var pt0 = this.ctx.transform.applyToPoint(new Point(x, y)); 13070 var pt1 = this.ctx.transform.applyToPoint(new Point(cpx, cpy)); 13071 this.path.push({ 13072 type: "qct", 13073 x1: pt1.x, 13074 y1: pt1.y, 13075 x: pt0.x, 13076 y: pt0.y 13077 }); 13078 this.ctx.lastPoint = new Point(pt0.x, pt0.y); 13079 }; 13080 /** 13081 * Creates a cubic Bézier curve 13082 * 13083 * @name bezierCurveTo 13084 * @function 13085 * @param cp1x {Number} The x-coordinate of the first Bézier control point 13086 * @param cp1y {Number} The y-coordinate of the first Bézier control point 13087 * @param cp2x {Number} The x-coordinate of the second Bézier control point 13088 * @param cp2y {Number} The y-coordinate of the second Bézier control point 13089 * @param x {Number} The x-coordinate of the ending point 13090 * @param y {Number} The y-coordinate of the ending point 13091 * @description The bezierCurveTo() method adds a point to the current path by using the specified control points that represent a cubic Bézier curve. <br /><br />A cubic bezier curve requires three points. The first two points are control points that are used in the cubic Bézier calculation and the last point is the ending point for the curve. The starting point for the curve is the last point in the current path. If a path does not exist, use the beginPath() and moveTo() methods to define a starting point. 13092 */ 13093 13094 13095 Context2D.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) { 13096 if (isNaN(x) || isNaN(y) || isNaN(cp1x) || isNaN(cp1y) || isNaN(cp2x) || isNaN(cp2y)) { 13097 console.error("jsPDF.context2d.bezierCurveTo: Invalid arguments", arguments); 13098 throw new Error("Invalid arguments passed to jsPDF.context2d.bezierCurveTo"); 13099 } 13100 13101 var pt0 = this.ctx.transform.applyToPoint(new Point(x, y)); 13102 var pt1 = this.ctx.transform.applyToPoint(new Point(cp1x, cp1y)); 13103 var pt2 = this.ctx.transform.applyToPoint(new Point(cp2x, cp2y)); 13104 this.path.push({ 13105 type: "bct", 13106 x1: pt1.x, 13107 y1: pt1.y, 13108 x2: pt2.x, 13109 y2: pt2.y, 13110 x: pt0.x, 13111 y: pt0.y 13112 }); 13113 this.ctx.lastPoint = new Point(pt0.x, pt0.y); 13114 }; 13115 /** 13116 * Creates an arc/curve (used to create circles, or parts of circles) 13117 * 13118 * @name arc 13119 * @function 13120 * @param x {Number} The x-coordinate of the center of the circle 13121 * @param y {Number} The y-coordinate of the center of the circle 13122 * @param radius {Number} The radius of the circle 13123 * @param startAngle {Number} The starting angle, in radians (0 is at the 3 o'clock position of the arc's circle) 13124 * @param endAngle {Number} The ending angle, in radians 13125 * @param counterclockwise {Boolean} Optional. Specifies whether the drawing should be counterclockwise or clockwise. False is default, and indicates clockwise, while true indicates counter-clockwise.
vendor: 50,408 bytes, lines 13126-14588
13126 * @description The arc() method creates an arc/curve (used to create circles, or parts of circles). 13127 */ 13128 13129 13130 Context2D.prototype.arc = function (x, y, radius, startAngle, endAngle, counterclockwise) { 13131 if (isNaN(x) || isNaN(y) || isNaN(radius) || isNaN(startAngle) || isNaN(endAngle)) { 13132 console.error("jsPDF.context2d.arc: Invalid arguments", arguments); 13133 throw new Error("Invalid arguments passed to jsPDF.context2d.arc"); 13134 } 13135 13136 counterclockwise = Boolean(counterclockwise); 13137 13138 if (!this.ctx.transform.isIdentity) { 13139 var xpt = this.ctx.transform.applyToPoint(new Point(x, y)); 13140 x = xpt.x; 13141 y = xpt.y; 13142 var x_radPt = this.ctx.transform.applyToPoint(new Point(0, radius)); 13143 var x_radPt0 = this.ctx.transform.applyToPoint(new Point(0, 0)); 13144 radius = Math.sqrt(Math.pow(x_radPt.x - x_radPt0.x, 2) + Math.pow(x_radPt.y - x_radPt0.y, 2)); 13145 } 13146 13147 if (Math.abs(endAngle - startAngle) >= 2 * Math.PI) { 13148 startAngle = 0; 13149 endAngle = 2 * Math.PI; 13150 } 13151 13152 this.path.push({ 13153 type: "arc", 13154 x: x, 13155 y: y, 13156 radius: radius, 13157 startAngle: startAngle, 13158 endAngle: endAngle, 13159 counterclockwise: counterclockwise 13160 }); // this.ctx.lastPoint(new Point(pt.x,pt.y)); 13161 }; 13162 /** 13163 * Creates an arc/curve between two tangents 13164 * 13165 * @name arcTo 13166 * @function 13167 * @param x1 {Number} The x-coordinate of the first tangent 13168 * @param y1 {Number} The y-coordinate of the first tangent 13169 * @param x2 {Number} The x-coordinate of the second tangent 13170 * @param y2 {Number} The y-coordinate of the second tangent 13171 * @param radius The radius of the arc 13172 * @description The arcTo() method creates an arc/curve between two tangents on the canvas. 13173 */ 13174 // eslint-disable-next-line no-unused-vars 13175 13176 13177 Context2D.prototype.arcTo = function (x1, y1, x2, y2, radius) { 13178 throw new Error("arcTo not implemented."); 13179 }; 13180 /** 13181 * Creates a rectangle 13182 * 13183 * @name rect 13184 * @function 13185 * @param x {Number} The x-coordinate of the upper-left corner of the rectangle 13186 * @param y {Number} The y-coordinate of the upper-left corner of the rectangle 13187 * @param w {Number} The width of the rectangle, in pixels 13188 * @param h {Number} The height of the rectangle, in pixels 13189 * @description The rect() method creates a rectangle. 13190 */ 13191 13192 13193 Context2D.prototype.rect = function (x, y, w, h) { 13194 if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) { 13195 console.error("jsPDF.context2d.rect: Invalid arguments", arguments); 13196 throw new Error("Invalid arguments passed to jsPDF.context2d.rect"); 13197 } 13198 13199 this.moveTo(x, y); 13200 this.lineTo(x + w, y); 13201 this.lineTo(x + w, y + h); 13202 this.lineTo(x, y + h); 13203 this.lineTo(x, y); 13204 this.lineTo(x + w, y); 13205 this.lineTo(x, y); 13206 }; 13207 /** 13208 * Draws a "filled" rectangle 13209 * 13210 * @name fillRect 13211 * @function 13212 * @param x {Number} The x-coordinate of the upper-left corner of the rectangle 13213 * @param y {Number} The y-coordinate of the upper-left corner of the rectangle 13214 * @param w {Number} The width of the rectangle, in pixels 13215 * @param h {Number} The height of the rectangle, in pixels 13216 * @description The fillRect() method draws a "filled" rectangle. The default color of the fill is black. 13217 */ 13218 13219 13220 Context2D.prototype.fillRect = function (x, y, w, h) { 13221 if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) { 13222 console.error("jsPDF.context2d.fillRect: Invalid arguments", arguments); 13223 throw new Error("Invalid arguments passed to jsPDF.context2d.fillRect"); 13224 } 13225 13226 if (isFillTransparent.call(this)) { 13227 return; 13228 } 13229 13230 var tmp = {}; 13231 13232 if (this.lineCap !== "butt") { 13233 tmp.lineCap = this.lineCap; 13234 this.lineCap = "butt"; 13235 } 13236 13237 if (this.lineJoin !== "miter") { 13238 tmp.lineJoin = this.lineJoin; 13239 this.lineJoin = "miter"; 13240 } 13241 13242 this.beginPath(); 13243 this.rect(x, y, w, h); 13244 this.fill(); 13245 13246 if (tmp.hasOwnProperty("lineCap")) { 13247 this.lineCap = tmp.lineCap; 13248 } 13249 13250 if (tmp.hasOwnProperty("lineJoin")) { 13251 this.lineJoin = tmp.lineJoin; 13252 } 13253 }; 13254 /** 13255 * Draws a rectangle (no fill) 13256 * 13257 * @name strokeRect 13258 * @function 13259 * @param x {Number} The x-coordinate of the upper-left corner of the rectangle 13260 * @param y {Number} The y-coordinate of the upper-left corner of the rectangle 13261 * @param w {Number} The width of the rectangle, in pixels 13262 * @param h {Number} The height of the rectangle, in pixels 13263 * @description The strokeRect() method draws a rectangle (no fill). The default color of the stroke is black. 13264 */ 13265 13266 13267 Context2D.prototype.strokeRect = function strokeRect(x, y, w, h) { 13268 if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) { 13269 console.error("jsPDF.context2d.strokeRect: Invalid arguments", arguments); 13270 throw new Error("Invalid arguments passed to jsPDF.context2d.strokeRect"); 13271 } 13272 13273 if (isStrokeTransparent.call(this)) { 13274 return; 13275 } 13276 13277 this.beginPath(); 13278 this.rect(x, y, w, h); 13279 this.stroke(); 13280 }; 13281 /** 13282 * Clears the specified pixels within a given rectangle 13283 * 13284 * @name clearRect 13285 * @function 13286 * @param x {Number} The x-coordinate of the upper-left corner of the rectangle 13287 * @param y {Number} The y-coordinate of the upper-left corner of the rectangle 13288 * @param w {Number} The width of the rectangle to clear, in pixels 13289 * @param h {Number} The height of the rectangle to clear, in pixels 13290 * @description We cannot clear PDF commands that were already written to PDF, so we use white instead. <br /> 13291 * As a special case, read a special flag (ignoreClearRect) and do nothing if it is set. 13292 * This results in all calls to clearRect() to do nothing, and keep the canvas transparent. 13293 * This flag is stored in the save/restore context and is managed the same way as other drawing states. 13294 * 13295 */ 13296 13297 13298 Context2D.prototype.clearRect = function (x, y, w, h) { 13299 if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) { 13300 console.error("jsPDF.context2d.clearRect: Invalid arguments", arguments); 13301 throw new Error("Invalid arguments passed to jsPDF.context2d.clearRect"); 13302 } 13303 13304 if (this.ignoreClearRect) { 13305 return; 13306 } 13307 13308 this.fillStyle = "#ffffff"; 13309 this.fillRect(x, y, w, h); 13310 }; 13311 /** 13312 * Saves the state of the current context 13313 * 13314 * @name save 13315 * @function 13316 */ 13317 13318 13319 Context2D.prototype.save = function (doStackPush) { 13320 doStackPush = typeof doStackPush === "boolean" ? doStackPush : true; 13321 var tmpPageNumber = this.pdf.internal.getCurrentPageInfo().pageNumber; 13322 13323 for (var i = 0; i < this.pdf.internal.getNumberOfPages(); i++) { 13324 this.pdf.setPage(i + 1); 13325 this.pdf.internal.out("q"); 13326 } 13327 13328 this.pdf.setPage(tmpPageNumber); 13329 13330 if (doStackPush) { 13331 this.ctx.fontSize = this.pdf.internal.getFontSize(); 13332 var ctx = new ContextLayer(this.ctx); 13333 this.ctxStack.push(this.ctx); 13334 this.ctx = ctx; 13335 } 13336 }; 13337 /** 13338 * Returns previously saved path state and attributes 13339 * 13340 * @name restore 13341 * @function 13342 */ 13343 13344 13345 Context2D.prototype.restore = function (doStackPop) { 13346 doStackPop = typeof doStackPop === "boolean" ? doStackPop : true; 13347 var tmpPageNumber = this.pdf.internal.getCurrentPageInfo().pageNumber; 13348 13349 for (var i = 0; i < this.pdf.internal.getNumberOfPages(); i++) { 13350 this.pdf.setPage(i + 1); 13351 this.pdf.internal.out("Q"); 13352 } 13353 13354 this.pdf.setPage(tmpPageNumber); 13355 13356 if (doStackPop && this.ctxStack.length !== 0) { 13357 this.ctx = this.ctxStack.pop(); 13358 this.fillStyle = this.ctx.fillStyle; 13359 this.strokeStyle = this.ctx.strokeStyle; 13360 this.font = this.ctx.font; 13361 this.lineCap = this.ctx.lineCap; 13362 this.lineWidth = this.ctx.lineWidth; 13363 this.lineJoin = this.ctx.lineJoin; 13364 this.lineDash = this.ctx.lineDash; 13365 this.lineDashOffset = this.ctx.lineDashOffset; 13366 } 13367 }; 13368 /** 13369 * @name toDataURL 13370 * @function 13371 */ 13372 13373 13374 Context2D.prototype.toDataURL = function () { 13375 throw new Error("toDataUrl not implemented."); 13376 }; //helper functions 13377 13378 /** 13379 * Get the decimal values of r, g, b and a 13380 * 13381 * @name getRGBA 13382 * @function 13383 * @private 13384 * @ignore 13385 */ 13386 13387 13388 var getRGBA = function getRGBA(style) { 13389 var rxRgb = /rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/; 13390 var rxRgba = /rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/; 13391 var rxTransparent = /transparent|rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*0+\s*\)/; 13392 var r, g, b, a; 13393 13394 if (style.isCanvasGradient === true) { 13395 style = style.getColor(); 13396 } 13397 13398 if (!style) { 13399 return { 13400 r: 0, 13401 g: 0, 13402 b: 0, 13403 a: 0, 13404 style: style 13405 }; 13406 } 13407 13408 if (rxTransparent.test(style)) { 13409 r = 0; 13410 g = 0; 13411 b = 0; 13412 a = 0; 13413 } else { 13414 var matches = rxRgb.exec(style); 13415 13416 if (matches !== null) { 13417 r = parseInt(matches[1]); 13418 g = parseInt(matches[2]); 13419 b = parseInt(matches[3]); 13420 a = 1; 13421 } else { 13422 matches = rxRgba.exec(style); 13423 13424 if (matches !== null) { 13425 r = parseInt(matches[1]); 13426 g = parseInt(matches[2]); 13427 b = parseInt(matches[3]); 13428 a = parseFloat(matches[4]); 13429 } else { 13430 a = 1; 13431 13432 if (typeof style === "string" && style.charAt(0) !== "#") { 13433 var rgbColor = new RGBColor(style); 13434 13435 if (rgbColor.ok) { 13436 style = rgbColor.toHex(); 13437 } else { 13438 style = "#000000"; 13439 } 13440 } 13441 13442 if (style.length === 4) { 13443 r = style.substring(1, 2); 13444 r += r; 13445 g = style.substring(2, 3); 13446 g += g; 13447 b = style.substring(3, 4); 13448 b += b; 13449 } else { 13450 r = style.substring(1, 3); 13451 g = style.substring(3, 5); 13452 b = style.substring(5, 7); 13453 } 13454 13455 r = parseInt(r, 16); 13456 g = parseInt(g, 16); 13457 b = parseInt(b, 16); 13458 } 13459 } 13460 } 13461 13462 return { 13463 r: r, 13464 g: g, 13465 b: b, 13466 a: a, 13467 style: style 13468 }; 13469 }; 13470 /** 13471 * @name isFillTransparent 13472 * @function 13473 * @private 13474 * @ignore 13475 * @returns {Boolean} 13476 */ 13477 13478 13479 var isFillTransparent = function isFillTransparent() { 13480 return this.ctx.isFillTransparent || this.globalAlpha == 0; 13481 }; 13482 /** 13483 * @name isStrokeTransparent 13484 * @function 13485 * @private 13486 * @ignore 13487 * @returns {Boolean} 13488 */ 13489 13490 13491 var isStrokeTransparent = function isStrokeTransparent() { 13492 return Boolean(this.ctx.isStrokeTransparent || this.globalAlpha == 0); 13493 }; 13494 /** 13495 * Draws "filled" text on the canvas 13496 * 13497 * @name fillText 13498 * @function 13499 * @param text {String} Specifies the text that will be written on the canvas 13500 * @param x {Number} The x coordinate where to start painting the text (relative to the canvas) 13501 * @param y {Number} The y coordinate where to start painting the text (relative to the canvas) 13502 * @param maxWidth {Number} Optional. The maximum allowed width of the text, in pixels 13503 * @description The fillText() method draws filled text on the canvas. The default color of the text is black. 13504 */ 13505 13506 13507 Context2D.prototype.fillText = function (text, x, y, maxWidth) { 13508 if (isNaN(x) || isNaN(y) || typeof text !== "string") { 13509 console.error("jsPDF.context2d.fillText: Invalid arguments", arguments); 13510 throw new Error("Invalid arguments passed to jsPDF.context2d.fillText"); 13511 } 13512 13513 maxWidth = isNaN(maxWidth) ? undefined : maxWidth; 13514 13515 if (isFillTransparent.call(this)) { 13516 return; 13517 } 13518 13519 var degs = rad2deg(this.ctx.transform.rotation); // We only use X axis as scale hint 13520 13521 var scale = this.ctx.transform.scaleX; 13522 putText.call(this, { 13523 text: text, 13524 x: x, 13525 y: y, 13526 scale: scale, 13527 angle: degs, 13528 align: this.textAlign, 13529 maxWidth: maxWidth 13530 }); 13531 }; 13532 /** 13533 * Draws text on the canvas (no fill) 13534 * 13535 * @name strokeText 13536 * @function 13537 * @param text {String} Specifies the text that will be written on the canvas 13538 * @param x {Number} The x coordinate where to start painting the text (relative to the canvas) 13539 * @param y {Number} The y coordinate where to start painting the text (relative to the canvas) 13540 * @param maxWidth {Number} Optional. The maximum allowed width of the text, in pixels 13541 * @description The strokeText() method draws text (with no fill) on the canvas. The default color of the text is black. 13542 */ 13543 13544 13545 Context2D.prototype.strokeText = function (text, x, y, maxWidth) { 13546 if (isNaN(x) || isNaN(y) || typeof text !== "string") { 13547 console.error("jsPDF.context2d.strokeText: Invalid arguments", arguments); 13548 throw new Error("Invalid arguments passed to jsPDF.context2d.strokeText"); 13549 } 13550 13551 if (isStrokeTransparent.call(this)) { 13552 return; 13553 } 13554 13555 maxWidth = isNaN(maxWidth) ? undefined : maxWidth; 13556 var degs = rad2deg(this.ctx.transform.rotation); 13557 var scale = this.ctx.transform.scaleX; 13558 putText.call(this, { 13559 text: text, 13560 x: x, 13561 y: y, 13562 scale: scale, 13563 renderingMode: "stroke", 13564 angle: degs, 13565 align: this.textAlign, 13566 maxWidth: maxWidth 13567 }); 13568 }; 13569 /** 13570 * Returns an object that contains the width of the specified text 13571 * 13572 * @name measureText 13573 * @function 13574 * @param text {String} The text to be measured 13575 * @description The measureText() method returns an object that contains the width of the specified text, in pixels. 13576 * @returns {Number} 13577 */ 13578 13579 13580 Context2D.prototype.measureText = function (text) { 13581 if (typeof text !== "string") { 13582 console.error("jsPDF.context2d.measureText: Invalid arguments", arguments); 13583 throw new Error("Invalid arguments passed to jsPDF.context2d.measureText"); 13584 } 13585 13586 var pdf = this.pdf; 13587 var k = this.pdf.internal.scaleFactor; 13588 var fontSize = pdf.internal.getFontSize(); 13589 var txtWidth = pdf.getStringUnitWidth(text) * fontSize / pdf.internal.scaleFactor; 13590 txtWidth *= Math.round(k * 96 / 72 * 10000) / 10000; 13591 13592 var TextMetrics = function TextMetrics(options) { 13593 options = options || {}; 13594 13595 var _width = options.width || 0; 13596 13597 Object.defineProperty(this, "width", { 13598 get: function get() { 13599 return _width; 13600 } 13601 }); 13602 return this; 13603 }; 13604 13605 return new TextMetrics({ 13606 width: txtWidth 13607 }); 13608 }; //Transformations 13609 13610 /** 13611 * Scales the current drawing bigger or smaller 13612 * 13613 * @name scale 13614 * @function 13615 * @param scalewidth {Number} Scales the width of the current drawing (1=100%, 0.5=50%, 2=200%, etc.) 13616 * @param scaleheight {Number} Scales the height of the current drawing (1=100%, 0.5=50%, 2=200%, etc.) 13617 * @description The scale() method scales the current drawing, bigger or smaller. 13618 */ 13619 13620 13621 Context2D.prototype.scale = function (scalewidth, scaleheight) { 13622 if (isNaN(scalewidth) || isNaN(scaleheight)) { 13623 console.error("jsPDF.context2d.scale: Invalid arguments", arguments); 13624 throw new Error("Invalid arguments passed to jsPDF.context2d.scale"); 13625 } 13626 13627 var matrix = new Matrix(scalewidth, 0.0, 0.0, scaleheight, 0.0, 0.0); 13628 this.ctx.transform = this.ctx.transform.multiply(matrix); 13629 }; 13630 /** 13631 * Rotates the current drawing 13632 * 13633 * @name rotate 13634 * @function 13635 * @param angle {Number} The rotation angle, in radians. 13636 * @description To calculate from degrees to radians: degrees*Math.PI/180. <br /> 13637 * Example: to rotate 5 degrees, specify the following: 5*Math.PI/180 13638 */ 13639 13640 13641 Context2D.prototype.rotate = function (angle) { 13642 if (isNaN(angle)) { 13643 console.error("jsPDF.context2d.rotate: Invalid arguments", arguments); 13644 throw new Error("Invalid arguments passed to jsPDF.context2d.rotate"); 13645 } 13646 13647 var matrix = new Matrix(Math.cos(angle), Math.sin(angle), -Math.sin(angle), Math.cos(angle), 0.0, 0.0); 13648 this.ctx.transform = this.ctx.transform.multiply(matrix); 13649 }; 13650 /** 13651 * Remaps the (0,0) position on the canvas 13652 * 13653 * @name translate 13654 * @function 13655 * @param x {Number} The value to add to horizontal (x) coordinates 13656 * @param y {Number} The value to add to vertical (y) coordinates 13657 * @description The translate() method remaps the (0,0) position on the canvas. 13658 */ 13659 13660 13661 Context2D.prototype.translate = function (x, y) { 13662 if (isNaN(x) || isNaN(y)) { 13663 console.error("jsPDF.context2d.translate: Invalid arguments", arguments); 13664 throw new Error("Invalid arguments passed to jsPDF.context2d.translate"); 13665 } 13666 13667 var matrix = new Matrix(1.0, 0.0, 0.0, 1.0, x, y); 13668 this.ctx.transform = this.ctx.transform.multiply(matrix); 13669 }; 13670 /** 13671 * Replaces the current transformation matrix for the drawing 13672 * 13673 * @name transform 13674 * @function 13675 * @param a {Number} Horizontal scaling 13676 * @param b {Number} Horizontal skewing 13677 * @param c {Number} Vertical skewing 13678 * @param d {Number} Vertical scaling 13679 * @param e {Number} Horizontal moving 13680 * @param f {Number} Vertical moving 13681 * @description Each object on the canvas has a current transformation matrix.<br /><br />The transform() method replaces the current transformation matrix. It multiplies the current transformation matrix with the matrix described by:<br /><br /><br /><br />a c e<br /><br />b d f<br /><br />0 0 1<br /><br />In other words, the transform() method lets you scale, rotate, move, and skew the current context. 13682 */ 13683 13684 13685 Context2D.prototype.transform = function (a, b, c, d, e, f) { 13686 if (isNaN(a) || isNaN(b) || isNaN(c) || isNaN(d) || isNaN(e) || isNaN(f)) { 13687 console.error("jsPDF.context2d.transform: Invalid arguments", arguments); 13688 throw new Error("Invalid arguments passed to jsPDF.context2d.transform"); 13689 } 13690 13691 var matrix = new Matrix(a, b, c, d, e, f); 13692 this.ctx.transform = this.ctx.transform.multiply(matrix); 13693 }; 13694 /** 13695 * Resets the current transform to the identity matrix. Then runs transform() 13696 * 13697 * @name setTransform 13698 * @function 13699 * @param a {Number} Horizontal scaling 13700 * @param b {Number} Horizontal skewing 13701 * @param c {Number} Vertical skewing 13702 * @param d {Number} Vertical scaling 13703 * @param e {Number} Horizontal moving 13704 * @param f {Number} Vertical moving 13705 * @description Each object on the canvas has a current transformation matrix. <br /><br />The setTransform() method resets the current transform to the identity matrix, and then runs transform() with the same arguments.<br /><br />In other words, the setTransform() method lets you scale, rotate, move, and skew the current context. 13706 */ 13707 13708 13709 Context2D.prototype.setTransform = function (a, b, c, d, e, f) { 13710 a = isNaN(a) ? 1 : a; 13711 b = isNaN(b) ? 0 : b; 13712 c = isNaN(c) ? 0 : c; 13713 d = isNaN(d) ? 1 : d; 13714 e = isNaN(e) ? 0 : e; 13715 f = isNaN(f) ? 0 : f; 13716 this.ctx.transform = new Matrix(a, b, c, d, e, f); 13717 }; 13718 13719 var hasMargins = function hasMargins() { 13720 return this.margin[0] > 0 || this.margin[1] > 0 || this.margin[2] > 0 || this.margin[3] > 0; 13721 }; 13722 /** 13723 * Draws an image, canvas, or video onto the canvas 13724 * 13725 * @function 13726 * @param img {} Specifies the image, canvas, or video element to use 13727 * @param sx {Number} Optional. The x coordinate where to start clipping 13728 * @param sy {Number} Optional. The y coordinate where to start clipping 13729 * @param swidth {Number} Optional. The width of the clipped image 13730 * @param sheight {Number} Optional. The height of the clipped image 13731 * @param x {Number} The x coordinate where to place the image on the canvas 13732 * @param y {Number} The y coordinate where to place the image on the canvas 13733 * @param width {Number} Optional. The width of the image to use (stretch or reduce the image) 13734 * @param height {Number} Optional. The height of the image to use (stretch or reduce the image) 13735 */ 13736 13737 13738 Context2D.prototype.drawImage = function (img, sx, sy, swidth, sheight, x, y, width, height) { 13739 var imageProperties = this.pdf.getImageProperties(img); 13740 var factorX = 1; 13741 var factorY = 1; 13742 var clipFactorX = 1; 13743 var clipFactorY = 1; 13744 13745 if (typeof swidth !== "undefined" && typeof width !== "undefined") { 13746 clipFactorX = width / swidth; 13747 clipFactorY = height / sheight; 13748 factorX = imageProperties.width / swidth * width / swidth; 13749 factorY = imageProperties.height / sheight * height / sheight; 13750 } //is sx and sy are set and x and y not, set x and y with values of sx and sy 13751 13752 13753 if (typeof x === "undefined") { 13754 x = sx; 13755 y = sy; 13756 sx = 0; 13757 sy = 0; 13758 } 13759 13760 if (typeof swidth !== "undefined" && typeof width === "undefined") { 13761 width = swidth; 13762 height = sheight; 13763 } 13764 13765 if (typeof swidth === "undefined" && typeof width === "undefined") { 13766 width = imageProperties.width; 13767 height = imageProperties.height; 13768 } 13769 13770 var decomposedTransformationMatrix = this.ctx.transform.decompose(); 13771 var angle = rad2deg(decomposedTransformationMatrix.rotate.shx); 13772 var matrix = new Matrix(); 13773 matrix = matrix.multiply(decomposedTransformationMatrix.translate); 13774 matrix = matrix.multiply(decomposedTransformationMatrix.skew); 13775 matrix = matrix.multiply(decomposedTransformationMatrix.scale); 13776 var xRect = matrix.applyToRectangle(new Rectangle(x - sx * clipFactorX, y - sy * clipFactorY, swidth * factorX, sheight * factorY)); 13777 var pageArray = getPagesByPath.call(this, xRect); 13778 var pages = []; 13779 13780 for (var ii = 0; ii < pageArray.length; ii += 1) { 13781 if (pages.indexOf(pageArray[ii]) === -1) { 13782 pages.push(pageArray[ii]); 13783 } 13784 } 13785 13786 sortPages(pages); 13787 var clipPath; 13788 13789 if (this.autoPaging) { 13790 var min = pages[0]; 13791 var max = pages[pages.length - 1]; 13792 13793 for (var i = min; i < max + 1; i++) { 13794 this.pdf.setPage(i); 13795 var pageWidthMinusMargins = this.pdf.internal.pageSize.width - this.margin[3] - this.margin[1]; 13796 var topMargin = i === 1 ? this.posY + this.margin[0] : this.margin[0]; 13797 var firstPageHeight = this.pdf.internal.pageSize.height - this.posY - this.margin[0] - this.margin[2]; 13798 var pageHeightMinusMargins = this.pdf.internal.pageSize.height - this.margin[0] - this.margin[2]; 13799 var previousPageHeightSum = i === 1 ? 0 : firstPageHeight + (i - 2) * pageHeightMinusMargins; 13800 13801 if (this.ctx.clip_path.length !== 0) { 13802 var tmpPaths = this.path; 13803 clipPath = JSON.parse(JSON.stringify(this.ctx.clip_path)); 13804 this.path = pathPositionRedo(clipPath, this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset); 13805 drawPaths.call(this, "fill", true); 13806 this.path = tmpPaths; 13807 } 13808 13809 var tmpRect = JSON.parse(JSON.stringify(xRect)); 13810 tmpRect = pathPositionRedo([tmpRect], this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset)[0]; 13811 var needsClipping = (i > min || i < max) && hasMargins.call(this); 13812 13813 if (needsClipping) { 13814 this.pdf.saveGraphicsState(); 13815 this.pdf.rect(this.margin[3], this.margin[0], pageWidthMinusMargins, pageHeightMinusMargins, null).clip().discardPath(); 13816 } 13817 13818 this.pdf.addImage(img, "JPEG", tmpRect.x, tmpRect.y, tmpRect.w, tmpRect.h, null, null, angle); 13819 13820 if (needsClipping) { 13821 this.pdf.restoreGraphicsState(); 13822 } 13823 } 13824 } else { 13825 this.pdf.addImage(img, "JPEG", xRect.x, xRect.y, xRect.w, xRect.h, null, null, angle); 13826 } 13827 }; 13828 13829 var getPagesByPath = function getPagesByPath(path, pageWrapX, pageWrapY) { 13830 var result = []; 13831 pageWrapX = pageWrapX || this.pdf.internal.pageSize.width; 13832 pageWrapY = pageWrapY || this.pdf.internal.pageSize.height - this.margin[0] - this.margin[2]; 13833 var yOffset = this.posY + this.ctx.prevPageLastElemOffset; 13834 13835 switch (path.type) { 13836 default: 13837 case "mt": 13838 case "lt": 13839 result.push(Math.floor((path.y + yOffset) / pageWrapY) + 1); 13840 break; 13841 13842 case "arc": 13843 result.push(Math.floor((path.y + yOffset - path.radius) / pageWrapY) + 1); 13844 result.push(Math.floor((path.y + yOffset + path.radius) / pageWrapY) + 1); 13845 break; 13846 13847 case "qct": 13848 var rectOfQuadraticCurve = getQuadraticCurveBoundary(this.ctx.lastPoint.x, this.ctx.lastPoint.y, path.x1, path.y1, path.x, path.y); 13849 result.push(Math.floor((rectOfQuadraticCurve.y + yOffset) / pageWrapY) + 1); 13850 result.push(Math.floor((rectOfQuadraticCurve.y + rectOfQuadraticCurve.h + yOffset) / pageWrapY) + 1); 13851 break; 13852 13853 case "bct": 13854 var rectOfBezierCurve = getBezierCurveBoundary(this.ctx.lastPoint.x, this.ctx.lastPoint.y, path.x1, path.y1, path.x2, path.y2, path.x, path.y); 13855 result.push(Math.floor((rectOfBezierCurve.y + yOffset) / pageWrapY) + 1); 13856 result.push(Math.floor((rectOfBezierCurve.y + rectOfBezierCurve.h + yOffset) / pageWrapY) + 1); 13857 break; 13858 13859 case "rect": 13860 result.push(Math.floor((path.y + yOffset) / pageWrapY) + 1); 13861 result.push(Math.floor((path.y + path.h + yOffset) / pageWrapY) + 1); 13862 } 13863 13864 for (var i = 0; i < result.length; i += 1) { 13865 while (this.pdf.internal.getNumberOfPages() < result[i]) { 13866 addPage.call(this); 13867 } 13868 } 13869 13870 return result; 13871 }; 13872 13873 var addPage = function addPage() { 13874 var fillStyle = this.fillStyle; 13875 var strokeStyle = this.strokeStyle; 13876 var font = this.font; 13877 var lineCap = this.lineCap; 13878 var lineWidth = this.lineWidth; 13879 var lineJoin = this.lineJoin; 13880 this.pdf.addPage(); 13881 this.fillStyle = fillStyle; 13882 this.strokeStyle = strokeStyle; 13883 this.font = font; 13884 this.lineCap = lineCap; 13885 this.lineWidth = lineWidth; 13886 this.lineJoin = lineJoin; 13887 }; 13888 13889 var pathPositionRedo = function pathPositionRedo(paths, x, y) { 13890 for (var i = 0; i < paths.length; i++) { 13891 switch (paths[i].type) { 13892 case "bct": 13893 paths[i].x2 += x; 13894 paths[i].y2 += y; 13895 13896 case "qct": 13897 paths[i].x1 += x; 13898 paths[i].y1 += y; 13899 13900 case "mt": 13901 case "lt": 13902 case "arc": 13903 default: 13904 paths[i].x += x; 13905 paths[i].y += y; 13906 } 13907 } 13908 13909 return paths; 13910 }; 13911 13912 var sortPages = function sortPages(pages) { 13913 return pages.sort(function (a, b) { 13914 return a - b; 13915 }); 13916 }; 13917 13918 var pathPreProcess = function pathPreProcess(rule, isClip) { 13919 var fillStyle = this.fillStyle; 13920 var strokeStyle = this.strokeStyle; 13921 var lineCap = this.lineCap; 13922 var oldLineWidth = this.lineWidth; 13923 var lineWidth = Math.abs(oldLineWidth * this.ctx.transform.scaleX); 13924 var lineJoin = this.lineJoin; 13925 var origPath = JSON.parse(JSON.stringify(this.path)); 13926 var xPath = JSON.parse(JSON.stringify(this.path)); 13927 var clipPath; 13928 var tmpPath; 13929 var pages = []; 13930 13931 for (var i = 0; i < xPath.length; i++) { 13932 if (typeof xPath[i].x !== "undefined") { 13933 var page = getPagesByPath.call(this, xPath[i]); 13934 13935 for (var ii = 0; ii < page.length; ii += 1) { 13936 if (pages.indexOf(page[ii]) === -1) { 13937 pages.push(page[ii]); 13938 } 13939 } 13940 } 13941 } 13942 13943 for (var j = 0; j < pages.length; j++) { 13944 while (this.pdf.internal.getNumberOfPages() < pages[j]) { 13945 addPage.call(this); 13946 } 13947 } 13948 13949 sortPages(pages); 13950 13951 if (this.autoPaging) { 13952 var min = pages[0]; 13953 var max = pages[pages.length - 1]; 13954 13955 for (var k = min; k < max + 1; k++) { 13956 this.pdf.setPage(k); 13957 this.fillStyle = fillStyle; 13958 this.strokeStyle = strokeStyle; 13959 this.lineCap = lineCap; 13960 this.lineWidth = lineWidth; 13961 this.lineJoin = lineJoin; 13962 var pageWidthMinusMargins = this.pdf.internal.pageSize.width - this.margin[3] - this.margin[1]; 13963 var topMargin = k === 1 ? this.posY + this.margin[0] : this.margin[0]; 13964 var firstPageHeight = this.pdf.internal.pageSize.height - this.posY - this.margin[0] - this.margin[2]; 13965 var pageHeightMinusMargins = this.pdf.internal.pageSize.height - this.margin[0] - this.margin[2]; 13966 var previousPageHeightSum = k === 1 ? 0 : firstPageHeight + (k - 2) * pageHeightMinusMargins; 13967 13968 if (this.ctx.clip_path.length !== 0) { 13969 var tmpPaths = this.path; 13970 clipPath = JSON.parse(JSON.stringify(this.ctx.clip_path)); 13971 this.path = pathPositionRedo(clipPath, this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset); 13972 drawPaths.call(this, rule, true); 13973 this.path = tmpPaths; 13974 } 13975 13976 tmpPath = JSON.parse(JSON.stringify(origPath)); 13977 this.path = pathPositionRedo(tmpPath, this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset); 13978 13979 if (isClip === false || k === 0) { 13980 var needsClipping = (k > min || k < max) && hasMargins.call(this); 13981 13982 if (needsClipping) { 13983 this.pdf.saveGraphicsState(); 13984 this.pdf.rect(this.margin[3], this.margin[0], pageWidthMinusMargins, pageHeightMinusMargins, null).clip().discardPath(); 13985 } 13986 13987 drawPaths.call(this, rule, isClip); 13988 13989 if (needsClipping) { 13990 this.pdf.restoreGraphicsState(); 13991 } 13992 } 13993 13994 this.lineWidth = oldLineWidth; 13995 } 13996 } else { 13997 this.lineWidth = lineWidth; 13998 drawPaths.call(this, rule, isClip); 13999 this.lineWidth = oldLineWidth; 14000 } 14001 14002 this.path = origPath; 14003 }; 14004 /** 14005 * Processes the paths 14006 * 14007 * @function 14008 * @param rule {String} 14009 * @param isClip {Boolean} 14010 * @private 14011 * @ignore 14012 */ 14013 14014 14015 var drawPaths = function drawPaths(rule, isClip) { 14016 if (rule === "stroke" && !isClip && isStrokeTransparent.call(this)) { 14017 return; 14018 } 14019 14020 if (rule !== "stroke" && !isClip && isFillTransparent.call(this)) { 14021 return; 14022 } 14023 14024 var moves = []; //var alpha = (this.ctx.fillOpacity < 1) ? this.ctx.fillOpacity : this.ctx.globalAlpha; 14025 14026 var delta; 14027 var xPath = this.path; 14028 14029 for (var i = 0; i < xPath.length; i++) { 14030 var pt = xPath[i]; 14031 14032 switch (pt.type) { 14033 case "begin": 14034 moves.push({ 14035 begin: true 14036 }); 14037 break; 14038 14039 case "close": 14040 moves.push({ 14041 close: true 14042 }); 14043 break; 14044 14045 case "mt": 14046 moves.push({ 14047 start: pt, 14048 deltas: [], 14049 abs: [] 14050 }); 14051 break; 14052 14053 case "lt": 14054 var iii = moves.length; 14055 14056 if (xPath[i - 1] && !isNaN(xPath[i - 1].x)) { 14057 delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y]; 14058 14059 if (iii > 0) { 14060 for (iii; iii >= 0; iii--) { 14061 if (moves[iii - 1].close !== true && moves[iii - 1].begin !== true) { 14062 moves[iii - 1].deltas.push(delta); 14063 moves[iii - 1].abs.push(pt); 14064 break; 14065 } 14066 } 14067 } 14068 } 14069 14070 break; 14071 14072 case "bct": 14073 delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y]; 14074 moves[moves.length - 1].deltas.push(delta); 14075 break; 14076 14077 case "qct": 14078 var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x); 14079 var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y); 14080 var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x); 14081 var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y); 14082 var x3 = pt.x; 14083 var y3 = pt.y; 14084 delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y]; 14085 moves[moves.length - 1].deltas.push(delta); 14086 break; 14087 14088 case "arc": 14089 moves.push({ 14090 deltas: [], 14091 abs: [], 14092 arc: true 14093 }); 14094 14095 if (Array.isArray(moves[moves.length - 1].abs)) { 14096 moves[moves.length - 1].abs.push(pt); 14097 } 14098 14099 break; 14100 } 14101 } 14102 14103 var style; 14104 14105 if (!isClip) { 14106 if (rule === "stroke") { 14107 style = "stroke"; 14108 } else { 14109 style = "fill"; 14110 } 14111 } else { 14112 style = null; 14113 } 14114 14115 var began = false; 14116 14117 for (var k = 0; k < moves.length; k++) { 14118 if (moves[k].arc) { 14119 var arcs = moves[k].abs; 14120 14121 for (var ii = 0; ii < arcs.length; ii++) { 14122 var arc = arcs[ii]; 14123 14124 if (arc.type === "arc") { 14125 drawArc.call(this, arc.x, arc.y, arc.radius, arc.startAngle, arc.endAngle, arc.counterclockwise, undefined, isClip, !began); 14126 } else { 14127 drawLine.call(this, arc.x, arc.y); 14128 } 14129 14130 began = true; 14131 } 14132 } else if (moves[k].close === true) { 14133 this.pdf.internal.out("h"); 14134 began = false; 14135 } else if (moves[k].begin !== true) { 14136 var x = moves[k].start.x; 14137 var y = moves[k].start.y; 14138 drawLines.call(this, moves[k].deltas, x, y); 14139 began = true; 14140 } 14141 } 14142 14143 if (style) { 14144 putStyle.call(this, style); 14145 } 14146 14147 if (isClip) { 14148 doClip.call(this); 14149 } 14150 }; 14151 14152 var getBaseline = function getBaseline(y) { 14153 var height = this.pdf.internal.getFontSize() / this.pdf.internal.scaleFactor; 14154 var descent = height * (this.pdf.internal.getLineHeightFactor() - 1); 14155 14156 switch (this.ctx.textBaseline) { 14157 case "bottom": 14158 return y - descent; 14159 14160 case "top": 14161 return y + height - descent; 14162 14163 case "hanging": 14164 return y + height - 2 * descent; 14165 14166 case "middle": 14167 return y + height / 2 - descent; 14168 14169 case "ideographic": 14170 // TODO not implemented 14171 return y; 14172 14173 case "alphabetic": 14174 default: 14175 return y; 14176 } 14177 }; 14178 14179 var getTextBottom = function getTextBottom(yBaseLine) { 14180 var height = this.pdf.internal.getFontSize() / this.pdf.internal.scaleFactor; 14181 var descent = height * (this.pdf.internal.getLineHeightFactor() - 1); 14182 return yBaseLine + descent; 14183 }; 14184 14185 Context2D.prototype.createLinearGradient = function createLinearGradient() { 14186 var canvasGradient = function canvasGradient() {}; 14187 14188 canvasGradient.colorStops = []; 14189 14190 canvasGradient.addColorStop = function (offset, color) { 14191 this.colorStops.push([offset, color]); 14192 }; 14193 14194 canvasGradient.getColor = function () { 14195 if (this.colorStops.length === 0) { 14196 return "#000000"; 14197 } 14198 14199 return this.colorStops[0][1]; 14200 }; 14201 14202 canvasGradient.isCanvasGradient = true; 14203 return canvasGradient; 14204 }; 14205 14206 Context2D.prototype.createPattern = function createPattern() { 14207 return this.createLinearGradient(); 14208 }; 14209 14210 Context2D.prototype.createRadialGradient = function createRadialGradient() { 14211 return this.createLinearGradient(); 14212 }; 14213 /** 14214 * 14215 * @param x Edge point X 14216 * @param y Edge point Y 14217 * @param r Radius 14218 * @param a1 start angle 14219 * @param a2 end angle 14220 * @param counterclockwise 14221 * @param style 14222 * @param isClip 14223 */ 14224 14225 14226 var drawArc = function drawArc(x, y, r, a1, a2, counterclockwise, style, isClip, includeMove) { 14227 // http://hansmuller-flex.blogspot.com/2011/10/more-about-approximating-circular-arcs.html 14228 var curves = createArc.call(this, r, a1, a2, counterclockwise); 14229 14230 for (var i = 0; i < curves.length; i++) { 14231 var curve = curves[i]; 14232 14233 if (i === 0) { 14234 if (includeMove) { 14235 doMove.call(this, curve.x1 + x, curve.y1 + y); 14236 } else { 14237 drawLine.call(this, curve.x1 + x, curve.y1 + y); 14238 } 14239 } 14240 14241 drawCurve.call(this, x, y, curve.x2, curve.y2, curve.x3, curve.y3, curve.x4, curve.y4); 14242 } 14243 14244 if (!isClip) { 14245 putStyle.call(this, style); 14246 } else { 14247 doClip.call(this); 14248 } 14249 }; 14250 14251 var putStyle = function putStyle(style) { 14252 switch (style) { 14253 case "stroke": 14254 this.pdf.internal.out("S"); 14255 break; 14256 14257 case "fill": 14258 this.pdf.internal.out("f"); 14259 break; 14260 } 14261 }; 14262 14263 var doClip = function doClip() { 14264 this.pdf.clip(); 14265 this.pdf.discardPath(); 14266 }; 14267 14268 var doMove = function doMove(x, y) { 14269 this.pdf.internal.out(getHorizontalCoordinateString(x) + " " + getVerticalCoordinateString(y) + " m"); 14270 }; 14271 14272 var putText = function putText(options) { 14273 var textAlign; 14274 14275 switch (options.align) { 14276 case "right": 14277 case "end": 14278 textAlign = "right"; 14279 break; 14280 14281 case "center": 14282 textAlign = "center"; 14283 break; 14284 14285 case "left": 14286 case "start": 14287 default: 14288 textAlign = "left"; 14289 break; 14290 } 14291 14292 var textDimensions = this.pdf.getTextDimensions(options.text); 14293 var yBaseLine = getBaseline.call(this, options.y); 14294 var yBottom = getTextBottom.call(this, yBaseLine); 14295 var yTop = yBottom - textDimensions.h; 14296 var pt = this.ctx.transform.applyToPoint(new Point(options.x, yBaseLine)); 14297 var decomposedTransformationMatrix = this.ctx.transform.decompose(); 14298 var matrix = new Matrix(); 14299 matrix = matrix.multiply(decomposedTransformationMatrix.translate); 14300 matrix = matrix.multiply(decomposedTransformationMatrix.skew); 14301 matrix = matrix.multiply(decomposedTransformationMatrix.scale); 14302 var baselineRect = this.ctx.transform.applyToRectangle(new Rectangle(options.x, yBaseLine, textDimensions.w, textDimensions.h)); 14303 var textBounds = matrix.applyToRectangle(new Rectangle(options.x, yTop, textDimensions.w, textDimensions.h)); 14304 var pageArray = getPagesByPath.call(this, textBounds); 14305 var pages = []; 14306 14307 for (var ii = 0; ii < pageArray.length; ii += 1) { 14308 if (pages.indexOf(pageArray[ii]) === -1) { 14309 pages.push(pageArray[ii]); 14310 } 14311 } 14312 14313 sortPages(pages); 14314 var clipPath, oldSize, oldLineWidth; 14315 14316 if (this.autoPaging) { 14317 var min = pages[0]; 14318 var max = pages[pages.length - 1]; 14319 14320 for (var i = min; i < max + 1; i++) { 14321 this.pdf.setPage(i); 14322 var topMargin = i === 1 ? this.posY + this.margin[0] : this.margin[0]; 14323 var firstPageHeight = this.pdf.internal.pageSize.height - this.posY - this.margin[0] - this.margin[2]; 14324 var pageHeightMinusBottomMargin = this.pdf.internal.pageSize.height - this.margin[2]; 14325 var pageHeightMinusMargins = pageHeightMinusBottomMargin - this.margin[0]; 14326 var pageWidthMinusRightMargin = this.pdf.internal.pageSize.width - this.margin[1]; 14327 var pageWidthMinusMargins = pageWidthMinusRightMargin - this.margin[3]; 14328 var previousPageHeightSum = i === 1 ? 0 : firstPageHeight + (i - 2) * pageHeightMinusMargins; 14329 14330 if (this.ctx.clip_path.length !== 0) { 14331 var tmpPaths = this.path; 14332 clipPath = JSON.parse(JSON.stringify(this.ctx.clip_path)); 14333 this.path = pathPositionRedo(clipPath, this.posX + this.margin[3], -1 * previousPageHeightSum + topMargin); 14334 drawPaths.call(this, "fill", true); 14335 this.path = tmpPaths; 14336 } 14337 14338 var textBoundsOnPage = pathPositionRedo([JSON.parse(JSON.stringify(textBounds))], this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset)[0]; 14339 14340 if (options.scale >= 0.01) { 14341 oldSize = this.pdf.internal.getFontSize(); 14342 this.pdf.setFontSize(oldSize * options.scale); 14343 oldLineWidth = this.lineWidth; 14344 this.lineWidth = oldLineWidth * options.scale; 14345 } 14346 14347 var doSlice = this.autoPaging !== "text"; 14348 14349 if (doSlice || textBoundsOnPage.y + textBoundsOnPage.h <= pageHeightMinusBottomMargin) { 14350 if (doSlice || textBoundsOnPage.y >= topMargin && textBoundsOnPage.x <= pageWidthMinusRightMargin) { 14351 var croppedText = doSlice ? options.text : this.pdf.splitTextToSize(options.text, options.maxWidth || pageWidthMinusRightMargin - textBoundsOnPage.x)[0]; 14352 var baseLineRectOnPage = pathPositionRedo([JSON.parse(JSON.stringify(baselineRect))], this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset)[0]; 14353 var needsClipping = doSlice && (i > min || i < max) && hasMargins.call(this); 14354 14355 if (needsClipping) { 14356 this.pdf.saveGraphicsState(); 14357 this.pdf.rect(this.margin[3], this.margin[0], pageWidthMinusMargins, pageHeightMinusMargins, null).clip().discardPath(); 14358 } 14359 14360 this.pdf.text(croppedText, baseLineRectOnPage.x, baseLineRectOnPage.y, { 14361 angle: options.angle, 14362 align: textAlign, 14363 renderingMode: options.renderingMode 14364 }); 14365 14366 if (needsClipping) { 14367 this.pdf.restoreGraphicsState(); 14368 } 14369 } 14370 } else { 14371 // This text is the last element of the page, but it got cut off due to the margin 14372 // so we render it in the next page 14373 if (textBoundsOnPage.y < pageHeightMinusBottomMargin) { 14374 // As a result, all other elements have their y offset increased 14375 this.ctx.prevPageLastElemOffset += pageHeightMinusBottomMargin - textBoundsOnPage.y; 14376 } 14377 } 14378 14379 if (options.scale >= 0.01) { 14380 this.pdf.setFontSize(oldSize); 14381 this.lineWidth = oldLineWidth; 14382 } 14383 } 14384 } else { 14385 if (options.scale >= 0.01) { 14386 oldSize = this.pdf.internal.getFontSize(); 14387 this.pdf.setFontSize(oldSize * options.scale); 14388 oldLineWidth = this.lineWidth; 14389 this.lineWidth = oldLineWidth * options.scale; 14390 } 14391 14392 this.pdf.text(options.text, pt.x + this.posX, pt.y + this.posY, { 14393 angle: options.angle, 14394 align: textAlign, 14395 renderingMode: options.renderingMode, 14396 maxWidth: options.maxWidth 14397 }); 14398 14399 if (options.scale >= 0.01) { 14400 this.pdf.setFontSize(oldSize); 14401 this.lineWidth = oldLineWidth; 14402 } 14403 } 14404 }; 14405 14406 var drawLine = function drawLine(x, y, prevX, prevY) { 14407 prevX = prevX || 0; 14408 prevY = prevY || 0; 14409 this.pdf.internal.out(getHorizontalCoordinateString(x + prevX) + " " + getVerticalCoordinateString(y + prevY) + " l"); 14410 }; 14411 14412 var drawLines = function drawLines(lines, x, y) { 14413 return this.pdf.lines(lines, x, y, null, null); 14414 }; 14415 14416 var drawCurve = function drawCurve(x, y, x1, y1, x2, y2, x3, y3) { 14417 this.pdf.internal.out([f2(getHorizontalCoordinate(x1 + x)), f2(getVerticalCoordinate(y1 + y)), f2(getHorizontalCoordinate(x2 + x)), f2(getVerticalCoordinate(y2 + y)), f2(getHorizontalCoordinate(x3 + x)), f2(getVerticalCoordinate(y3 + y)), "c"].join(" ")); 14418 }; 14419 /** 14420 * Return a array of objects that represent bezier curves which approximate the circular arc centered at the origin, from startAngle to endAngle (radians) with the specified radius. 14421 * 14422 * Each bezier curve is an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points. 14423 * @function createArc 14424 */ 14425 14426 14427 var createArc = function createArc(radius, startAngle, endAngle, anticlockwise) { 14428 var EPSILON = 0.00001; // Roughly 1/1000th of a degree, see below 14429 14430 var twoPi = Math.PI * 2; 14431 var halfPi = Math.PI / 2.0; 14432 14433 while (startAngle > endAngle) { 14434 startAngle = startAngle - twoPi; 14435 } 14436 14437 var totalAngle = Math.abs(endAngle - startAngle); 14438 14439 if (totalAngle < twoPi) { 14440 if (anticlockwise) { 14441 totalAngle = twoPi - totalAngle; 14442 } 14443 } // Compute the sequence of arc curves, up to PI/2 at a time. 14444 14445 14446 var curves = []; // clockwise or counterclockwise 14447 14448 var sgn = anticlockwise ? -1 : +1; 14449 var a1 = startAngle; 14450 14451 for (; totalAngle > EPSILON;) { 14452 var remain = sgn * Math.min(totalAngle, halfPi); 14453 var a2 = a1 + remain; 14454 curves.push(createSmallArc.call(this, radius, a1, a2)); 14455 totalAngle -= Math.abs(a2 - a1); 14456 a1 = a2; 14457 } 14458 14459 return curves; 14460 }; 14461 /** 14462 * Cubic bezier approximation of a circular arc centered at the origin, from (radians) a1 to a2, where a2-a1 < pi/2. The arc's radius is r. 14463 * 14464 * Returns an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points. 14465 * 14466 * This algorithm is based on the approach described in: A. Riškus, "Approximation of a Cubic Bezier Curve by Circular Arcs and Vice Versa," Information Technology and Control, 35(4), 2006 pp. 371-378. 14467 */ 14468 14469 14470 var createSmallArc = function createSmallArc(r, a1, a2) { 14471 var a = (a2 - a1) / 2.0; 14472 var x4 = r * Math.cos(a); 14473 var y4 = r * Math.sin(a); 14474 var x1 = x4; 14475 var y1 = -y4; 14476 var q1 = x1 * x1 + y1 * y1; 14477 var q2 = q1 + x1 * x4 + y1 * y4; 14478 var k2 = 4 / 3 * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4); 14479 var x2 = x1 - k2 * y1; 14480 var y2 = y1 + k2 * x1; 14481 var x3 = x2; 14482 var y3 = -y2; 14483 var ar = a + a1; 14484 var cos_ar = Math.cos(ar); 14485 var sin_ar = Math.sin(ar); 14486 return { 14487 x1: r * Math.cos(a1), 14488 y1: r * Math.sin(a1), 14489 x2: x2 * cos_ar - y2 * sin_ar, 14490 y2: x2 * sin_ar + y2 * cos_ar, 14491 x3: x3 * cos_ar - y3 * sin_ar, 14492 y3: x3 * sin_ar + y3 * cos_ar, 14493 x4: r * Math.cos(a2), 14494 y4: r * Math.sin(a2) 14495 }; 14496 }; 14497 14498 var rad2deg = function rad2deg(value) { 14499 return value * 180 / Math.PI; 14500 }; 14501 14502 var getQuadraticCurveBoundary = function getQuadraticCurveBoundary(sx, sy, cpx, cpy, ex, ey) { 14503 var midX1 = sx + (cpx - sx) * 0.5; 14504 var midY1 = sy + (cpy - sy) * 0.5; 14505 var midX2 = ex + (cpx - ex) * 0.5; 14506 var midY2 = ey + (cpy - ey) * 0.5; 14507 var resultX1 = Math.min(sx, ex, midX1, midX2); 14508 var resultX2 = Math.max(sx, ex, midX1, midX2); 14509 var resultY1 = Math.min(sy, ey, midY1, midY2); 14510 var resultY2 = Math.max(sy, ey, midY1, midY2); 14511 return new Rectangle(resultX1, resultY1, resultX2 - resultX1, resultY2 - resultY1); 14512 }; //De Casteljau algorithm 14513 14514 14515 var getBezierCurveBoundary = function getBezierCurveBoundary(ax, ay, bx, by, cx, cy, dx, dy) { 14516 var tobx = bx - ax; 14517 var toby = by - ay; 14518 var tocx = cx - bx; 14519 var tocy = cy - by; 14520 var todx = dx - cx; 14521 var tody = dy - cy; 14522 var precision = 40; 14523 var d, i, px, py, qx, qy, rx, ry, tx, ty, sx, sy, x, y, minx, miny, maxx, maxy, toqx, toqy, torx, tory, totx, toty; 14524 14525 for (i = 0; i < precision + 1; i++) { 14526 d = i / precision; 14527 px = ax + d * tobx; 14528 py = ay + d * toby; 14529 qx = bx + d * tocx; 14530 qy = by + d * tocy; 14531 rx = cx + d * todx; 14532 ry = cy + d * tody; 14533 toqx = qx - px; 14534 toqy = qy - py; 14535 torx = rx - qx; 14536 tory = ry - qy; 14537 sx = px + d * toqx; 14538 sy = py + d * toqy; 14539 tx = qx + d * torx; 14540 ty = qy + d * tory; 14541 totx = tx - sx; 14542 toty = ty - sy; 14543 x = sx + d * totx; 14544 y = sy + d * toty; 14545 14546 if (i == 0) { 14547 minx = x; 14548 miny = y; 14549 maxx = x; 14550 maxy = y; 14551 } else { 14552 minx = Math.min(minx, x); 14553 miny = Math.min(miny, y); 14554 maxx = Math.max(maxx, x); 14555 maxy = Math.max(maxy, y); 14556 } 14557 } 14558 14559 return new Rectangle(Math.round(minx), Math.round(miny), Math.round(maxx - minx), Math.round(maxy - miny)); 14560 }; 14561 14562 var getPrevLineDashValue = function getPrevLineDashValue(lineDash, lineDashOffset) { 14563 return JSON.stringify({ 14564 lineDash: lineDash, 14565 lineDashOffset: lineDashOffset 14566 }); 14567 }; 14568 14569 var setLineDash = function setLineDash() { 14570 // Avoid unnecessary line dash declarations. 14571 if (!this.prevLineDash && !this.ctx.lineDash.length && !this.ctx.lineDashOffset) { 14572 return; 14573 } // Avoid unnecessary line dash declarations. 14574 14575 14576 var nextLineDash = getPrevLineDashValue(this.ctx.lineDash, this.ctx.lineDashOffset); 14577 14578 if (this.prevLineDash !== nextLineDash) { 14579 this.pdf.setLineDash(this.ctx.lineDash, this.ctx.lineDashOffset); 14580 this.prevLineDash = nextLineDash; 14581 } 14582 }; 14583 })(jsPDF.API); 14584 14585 // DEFLATE is a complex format; to read this code, you should probably check the RFC first: 14586 // https://tools.ietf.org/html/rfc1951 14587 // You may also wish to take a look at the guide I made about this program: 14588 // https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad
vendor: 22,879 bytes, lines 14589-15422
14589 // Much of the following code is similar to that of UZIP.js: 14590 // https://github.com/photopea/UZIP.js 14591 // Many optimizations have been made, so the bundle size is ultimately smaller but performance is similar. 14592 // Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint 14593 // is better for memory in most engines (I *think*). 14594 // Mediocre shim 14595 var Worker; 14596 14597 try { 14598 Worker = require('worker_threads').Worker; 14599 } catch (e) {} 14600 14601 var u8 = Uint8Array, 14602 u16 = Uint16Array, 14603 u32 = Uint32Array; // fixed length extra bits 14604 14605 var fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 14606 /* unused */ 14607 0, 0, 14608 /* impossible */ 14609 0]); // fixed distance extra bits 14610 // see fleb note 14611 14612 var fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14613 /* unused */ 14614 0, 0]); // code length index map 14615 14616 var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); // get base, reverse index map from extra bits 14617 14618 var freb = function (eb, start) { 14619 var b = new u16(31); 14620 14621 for (var i = 0; i < 31; ++i) { 14622 b[i] = start += 1 << eb[i - 1]; 14623 } // numbers here are at max 18 bits 14624 14625 14626 var r = new u32(b[30]); 14627 14628 for (var i = 1; i < 30; ++i) { 14629 for (var j = b[i]; j < b[i + 1]; ++j) { 14630 r[j] = j - b[i] << 5 | i; 14631 } 14632 } 14633 14634 return [b, r]; 14635 }; 14636 14637 var _a = freb(fleb, 2), 14638 fl = _a[0], 14639 revfl = _a[1]; // we can ignore the fact that the other numbers are wrong; they never happen anyway 14640 14641 14642 fl[28] = 258, revfl[258] = 28; 14643 14644 var _b = freb(fdeb, 0), 14645 fd = _b[0], 14646 revfd = _b[1]; // map of value to reverse (assuming 16 bits) 14647 14648 14649 var rev = new u16(32768); 14650 14651 for (var i = 0; i < 32768; ++i) { 14652 // reverse table algorithm from SO 14653 var x = (i & 0xAAAA) >>> 1 | (i & 0x5555) << 1; 14654 x = (x & 0xCCCC) >>> 2 | (x & 0x3333) << 2; 14655 x = (x & 0xF0F0) >>> 4 | (x & 0x0F0F) << 4; 14656 rev[i] = ((x & 0xFF00) >>> 8 | (x & 0x00FF) << 8) >>> 1; 14657 } // create huffman tree from u8 "map": index -> code length for code index 14658 // mb (max bits) must be at most 15 14659 // TODO: optimize/split up? 14660 14661 14662 var hMap = function (cd, mb, r) { 14663 var s = cd.length; // index 14664 14665 var i = 0; // u16 "map": index -> # of codes with bit length = index 14666 14667 var l = new u16(mb); // length of cd must be 288 (total # of codes) 14668 14669 for (; i < s; ++i) ++l[cd[i] - 1]; // u16 "map": index -> minimum code for bit length = index 14670 14671 14672 var le = new u16(mb); 14673 14674 for (i = 0; i < mb; ++i) { 14675 le[i] = le[i - 1] + l[i - 1] << 1; 14676 } 14677 14678 var co; 14679 14680 if (r) { 14681 // u16 "map": index -> number of actual bits, symbol for code 14682 co = new u16(1 << mb); // bits to remove for reverser 14683 14684 var rvb = 15 - mb; 14685 14686 for (i = 0; i < s; ++i) { 14687 // ignore 0 lengths 14688 if (cd[i]) { 14689 // num encoding both symbol and bits read 14690 var sv = i << 4 | cd[i]; // free bits 14691 14692 var r_1 = mb - cd[i]; // start value 14693 14694 var v = le[cd[i] - 1]++ << r_1; // m is end value 14695 14696 for (var m = v | (1 << r_1) - 1; v <= m; ++v) { 14697 // every 16 bit value starting with the code yields the same result 14698 co[rev[v] >>> rvb] = sv; 14699 } 14700 } 14701 } 14702 } else { 14703 co = new u16(s); 14704 14705 for (i = 0; i < s; ++i) co[i] = rev[le[cd[i] - 1]++] >>> 15 - cd[i]; 14706 } 14707 14708 return co; 14709 }; // fixed length tree 14710 14711 14712 var flt = new u8(288); 14713 14714 for (var i = 0; i < 144; ++i) flt[i] = 8; 14715 14716 for (var i = 144; i < 256; ++i) flt[i] = 9; 14717 14718 for (var i = 256; i < 280; ++i) flt[i] = 7; 14719 14720 for (var i = 280; i < 288; ++i) flt[i] = 8; // fixed distance tree 14721 14722 14723 var fdt = new u8(32); 14724 14725 for (var i = 0; i < 32; ++i) fdt[i] = 5; // fixed length map 14726 14727 14728 var flm = /*#__PURE__*/hMap(flt, 9, 0), 14729 flrm = /*#__PURE__*/hMap(flt, 9, 1); // fixed distance map 14730 14731 var fdm = /*#__PURE__*/hMap(fdt, 5, 0), 14732 fdrm = /*#__PURE__*/hMap(fdt, 5, 1); // find max of array 14733 14734 var max = function (a) { 14735 var m = a[0]; 14736 14737 for (var i = 1; i < a.length; ++i) { 14738 if (a[i] > m) m = a[i]; 14739 } 14740 14741 return m; 14742 }; // read d, starting at bit p and mask with m 14743 14744 14745 var bits = function (d, p, m) { 14746 var o = p / 8 >> 0; 14747 return (d[o] | d[o + 1] << 8) >>> (p & 7) & m; 14748 }; // read d, starting at bit p continuing for at least 16 bits 14749 14750 14751 var bits16 = function (d, p) { 14752 var o = p / 8 >> 0; 14753 return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >>> (p & 7); 14754 }; // get end of byte 14755 14756 14757 var shft = function (p) { 14758 return (p / 8 >> 0) + (p & 7 && 1); 14759 }; // typed array slice - allows garbage collector to free original reference, 14760 // while being more compatible than .slice 14761 14762 14763 var slc = function (v, s, e) { 14764 if (s == null || s < 0) s = 0; 14765 if (e == null || e > v.length) e = v.length; // can't use .constructor in case user-supplied 14766 14767 var n = new (v instanceof u16 ? u16 : v instanceof u32 ? u32 : u8)(e - s); 14768 n.set(v.subarray(s, e)); 14769 return n; 14770 }; // expands raw DEFLATE data 14771 14772 14773 var inflt = function (dat, buf, st) { 14774 // source length 14775 var sl = dat.length; // have to estimate size 14776 14777 var noBuf = !buf || st; // no state 14778 14779 var noSt = !st || st.i; 14780 if (!st) st = {}; // Assumes roughly 33% compression ratio average 14781 14782 if (!buf) buf = new u8(sl * 3); // ensure buffer can fit at least l elements 14783 14784 var cbuf = function (l) { 14785 var bl = buf.length; // need to increase size to fit 14786 14787 if (l > bl) { 14788 // Double or set to necessary, whichever is greater 14789 var nbuf = new u8(Math.max(bl * 2, l)); 14790 nbuf.set(buf); 14791 buf = nbuf; 14792 } 14793 }; // last chunk bitpos bytes 14794 14795 14796 var final = st.f || 0, 14797 pos = st.p || 0, 14798 bt = st.b || 0, 14799 lm = st.l, 14800 dm = st.d, 14801 lbt = st.m, 14802 dbt = st.n; // total bits 14803 14804 var tbts = sl * 8; 14805 14806 do { 14807 if (!lm) { 14808 // BFINAL - this is only 1 when last chunk is next 14809 st.f = final = bits(dat, pos, 1); // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman 14810 14811 var type = bits(dat, pos + 1, 3); 14812 pos += 3; 14813 14814 if (!type) { 14815 // go to end of byte boundary 14816 var s = shft(pos) + 4, 14817 l = dat[s - 4] | dat[s - 3] << 8, 14818 t = s + l; 14819 14820 if (t > sl) { 14821 if (noSt) throw 'unexpected EOF'; 14822 break; 14823 } // ensure size 14824 14825 14826 if (noBuf) cbuf(bt + l); // Copy over uncompressed data 14827 14828 buf.set(dat.subarray(s, t), bt); // Get new bitpos, update byte count 14829 14830 st.b = bt += l, st.p = pos = t * 8; 14831 continue; 14832 } else if (type == 1) lm = flrm, dm = fdrm, lbt = 9, dbt = 5;else if (type == 2) { 14833 // literal lengths 14834 var hLit = bits(dat, pos, 31) + 257, 14835 hcLen = bits(dat, pos + 10, 15) + 4; 14836 var tl = hLit + bits(dat, pos + 5, 31) + 1; 14837 pos += 14; // length+distance tree 14838 14839 var ldt = new u8(tl); // code length tree 14840 14841 var clt = new u8(19); 14842 14843 for (var i = 0; i < hcLen; ++i) { 14844 // use index map to get real code 14845 clt[clim[i]] = bits(dat, pos + i * 3, 7); 14846 } 14847 14848 pos += hcLen * 3; // code lengths bits 14849 14850 var clb = max(clt), 14851 clbmsk = (1 << clb) - 1; 14852 if (!noSt && pos + tl * (clb + 7) > tbts) break; // code lengths map 14853 14854 var clm = hMap(clt, clb, 1); 14855 14856 for (var i = 0; i < tl;) { 14857 var r = clm[bits(dat, pos, clbmsk)]; // bits read 14858 14859 pos += r & 15; // symbol 14860 14861 var s = r >>> 4; // code length to copy 14862 14863 if (s < 16) { 14864 ldt[i++] = s; 14865 } else { 14866 // copy count 14867 var c = 0, 14868 n = 0; 14869 if (s == 16) n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];else if (s == 17) n = 3 + bits(dat, pos, 7), pos += 3;else if (s == 18) n = 11 + bits(dat, pos, 127), pos += 7; 14870 14871 while (n--) ldt[i++] = c; 14872 } 14873 } // length tree distance tree 14874 14875 14876 var lt = ldt.subarray(0, hLit), 14877 dt = ldt.subarray(hLit); // max length bits 14878 14879 lbt = max(lt); // max dist bits 14880 14881 dbt = max(dt); 14882 lm = hMap(lt, lbt, 1); 14883 dm = hMap(dt, dbt, 1); 14884 } else throw 'invalid block type'; 14885 14886 if (pos > tbts) throw 'unexpected EOF'; 14887 } // Make sure the buffer can hold this + the largest possible addition 14888 // Maximum chunk size (practically, theoretically infinite) is 2^17; 14889 14890 14891 if (noBuf) cbuf(bt + 131072); 14892 var lms = (1 << lbt) - 1, 14893 dms = (1 << dbt) - 1; 14894 var mxa = lbt + dbt + 18; 14895 14896 while (noSt || pos + mxa < tbts) { 14897 // bits read, code 14898 var c = lm[bits16(dat, pos) & lms], 14899 sym = c >>> 4; 14900 pos += c & 15; 14901 if (pos > tbts) throw 'unexpected EOF'; 14902 if (!c) throw 'invalid length/literal'; 14903 if (sym < 256) buf[bt++] = sym;else if (sym == 256) { 14904 lm = null; 14905 break; 14906 } else { 14907 var add = sym - 254; // no extra bits needed if less 14908 14909 if (sym > 264) { 14910 // index 14911 var i = sym - 257, 14912 b = fleb[i]; 14913 add = bits(dat, pos, (1 << b) - 1) + fl[i]; 14914 pos += b; 14915 } // dist 14916 14917 14918 var d = dm[bits16(dat, pos) & dms], 14919 dsym = d >>> 4; 14920 if (!d) throw 'invalid distance'; 14921 pos += d & 15; 14922 var dt = fd[dsym]; 14923 14924 if (dsym > 3) { 14925 var b = fdeb[dsym]; 14926 dt += bits16(dat, pos) & (1 << b) - 1, pos += b; 14927 } 14928 14929 if (pos > tbts) throw 'unexpected EOF'; 14930 if (noBuf) cbuf(bt + 131072); 14931 var end = bt + add; 14932 14933 for (; bt < end; bt += 4) { 14934 buf[bt] = buf[bt - dt]; 14935 buf[bt + 1] = buf[bt + 1 - dt]; 14936 buf[bt + 2] = buf[bt + 2 - dt]; 14937 buf[bt + 3] = buf[bt + 3 - dt]; 14938 } 14939 14940 bt = end; 14941 } 14942 } 14943 14944 st.l = lm, st.p = pos, st.b = bt; 14945 if (lm) final = 1, st.m = lbt, st.d = dm, st.n = dbt; 14946 } while (!final); 14947 14948 return bt == buf.length ? buf : slc(buf, 0, bt); 14949 }; // starting at p, write the minimum number of bits that can hold v to d 14950 14951 14952 var wbits = function (d, p, v) { 14953 v <<= p & 7; 14954 var o = p / 8 >> 0; 14955 d[o] |= v; 14956 d[o + 1] |= v >>> 8; 14957 }; // starting at p, write the minimum number of bits (>8) that can hold v to d 14958 14959 14960 var wbits16 = function (d, p, v) { 14961 v <<= p & 7; 14962 var o = p / 8 >> 0; 14963 d[o] |= v; 14964 d[o + 1] |= v >>> 8; 14965 d[o + 2] |= v >>> 16; 14966 }; // creates code lengths from a frequency table 14967 14968 14969 var hTree = function (d, mb) { 14970 // Need extra info to make a tree 14971 var t = []; 14972 14973 for (var i = 0; i < d.length; ++i) { 14974 if (d[i]) t.push({ 14975 s: i, 14976 f: d[i] 14977 }); 14978 } 14979 14980 var s = t.length; 14981 var t2 = t.slice(); 14982 if (!s) return [new u8(0), 0]; 14983 14984 if (s == 1) { 14985 var v = new u8(t[0].s + 1); 14986 v[t[0].s] = 1; 14987 return [v, 1]; 14988 } 14989 14990 t.sort(function (a, b) { 14991 return a.f - b.f; 14992 }); // after i2 reaches last ind, will be stopped 14993 // freq must be greater than largest possible number of symbols 14994 14995 t.push({ 14996 s: -1, 14997 f: 25001 14998 }); 14999 var l = t[0], 15000 r = t[1], 15001 i0 = 0, 15002 i1 = 1, 15003 i2 = 2; 15004 t[0] = { 15005 s: -1, 15006 f: l.f + r.f, 15007 l: l, 15008 r: r 15009 }; // efficient algorithm from UZIP.js 15010 // i0 is lookbehind, i2 is lookahead - after processing two low-freq 15011 // symbols that combined have high freq, will start processing i2 (high-freq, 15012 // non-composite) symbols instead 15013 // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/ 15014 15015 while (i1 != s - 1) { 15016 l = t[t[i0].f < t[i2].f ? i0++ : i2++]; 15017 r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++]; 15018 t[i1++] = { 15019 s: -1, 15020 f: l.f + r.f, 15021 l: l, 15022 r: r 15023 }; 15024 } 15025 15026 var maxSym = t2[0].s; 15027 15028 for (var i = 1; i < s; ++i) { 15029 if (t2[i].s > maxSym) maxSym = t2[i].s; 15030 } // code lengths 15031 15032 15033 var tr = new u16(maxSym + 1); // max bits in tree 15034 15035 var mbt = ln(t[i1 - 1], tr, 0); 15036 15037 if (mbt > mb) { 15038 // more algorithms from UZIP.js 15039 // TODO: find out how this code works (debt) 15040 // ind debt 15041 var i = 0, 15042 dt = 0; // left cost 15043 15044 var lft = mbt - mb, 15045 cst = 1 << lft; 15046 t2.sort(function (a, b) { 15047 return tr[b.s] - tr[a.s] || a.f - b.f; 15048 }); 15049 15050 for (; i < s; ++i) { 15051 var i2_1 = t2[i].s; 15052 15053 if (tr[i2_1] > mb) { 15054 dt += cst - (1 << mbt - tr[i2_1]); 15055 tr[i2_1] = mb; 15056 } else break; 15057 } 15058 15059 dt >>>= lft; 15060 15061 while (dt > 0) { 15062 var i2_2 = t2[i].s; 15063 if (tr[i2_2] < mb) dt -= 1 << mb - tr[i2_2]++ - 1;else ++i; 15064 } 15065 15066 for (; i >= 0 && dt; --i) { 15067 var i2_3 = t2[i].s; 15068 15069 if (tr[i2_3] == mb) { 15070 --tr[i2_3]; 15071 ++dt; 15072 } 15073 } 15074 15075 mbt = mb; 15076 } 15077 15078 return [new u8(tr), mbt]; 15079 }; // get the max length and assign length codes 15080 15081 15082 var ln = function (n, l, d) { 15083 return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : l[n.s] = d; 15084 }; // length codes generation 15085 15086 15087 var lc = function (c) { 15088 var s = c.length; // Note that the semicolon was intentional 15089 15090 while (s && !c[--s]); 15091 15092 var cl = new u16(++s); // ind num streak 15093 15094 var cli = 0, 15095 cln = c[0], 15096 cls = 1; 15097 15098 var w = function (v) { 15099 cl[cli++] = v; 15100 }; 15101 15102 for (var i = 1; i <= s; ++i) { 15103 if (c[i] == cln && i != s) ++cls;else { 15104 if (!cln && cls > 2) { 15105 for (; cls > 138; cls -= 138) w(32754); 15106 15107 if (cls > 2) { 15108 w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305); 15109 cls = 0; 15110 } 15111 } else if (cls > 3) { 15112 w(cln), --cls; 15113 15114 for (; cls > 6; cls -= 6) w(8304); 15115 15116 if (cls > 2) w(cls - 3 << 5 | 8208), cls = 0; 15117 } 15118 15119 while (cls--) w(cln); 15120 15121 cls = 1; 15122 cln = c[i]; 15123 } 15124 } 15125 15126 return [cl.subarray(0, cli), s]; 15127 }; // calculate the length of output from tree, code lengths 15128 15129 15130 var clen = function (cf, cl) { 15131 var l = 0; 15132 15133 for (var i = 0; i < cl.length; ++i) l += cf[i] * cl[i]; 15134 15135 return l; 15136 }; // writes a fixed block 15137 // returns the new bit pos 15138 15139 15140 var wfblk = function (out, pos, dat) { 15141 // no need to write 00 as type: TypedArray defaults to 0 15142 var s = dat.length; 15143 var o = shft(pos + 2); 15144 out[o] = s & 255; 15145 out[o + 1] = s >>> 8; 15146 out[o + 2] = out[o] ^ 255; 15147 out[o + 3] = out[o + 1] ^ 255; 15148 15149 for (var i = 0; i < s; ++i) out[o + i + 4] = dat[i]; 15150 15151 return (o + 4 + s) * 8; 15152 }; // writes a block 15153 15154 15155 var wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) { 15156 wbits(out, p++, final); 15157 ++lf[256]; 15158 15159 var _a = hTree(lf, 15), 15160 dlt = _a[0], 15161 mlb = _a[1]; 15162 15163 var _b = hTree(df, 15), 15164 ddt = _b[0], 15165 mdb = _b[1]; 15166 15167 var _c = lc(dlt), 15168 lclt = _c[0], 15169 nlc = _c[1]; 15170 15171 var _d = lc(ddt), 15172 lcdt = _d[0], 15173 ndc = _d[1]; 15174 15175 var lcfreq = new u16(19); 15176 15177 for (var i = 0; i < lclt.length; ++i) lcfreq[lclt[i] & 31]++; 15178 15179 for (var i = 0; i < lcdt.length; ++i) lcfreq[lcdt[i] & 31]++; 15180 15181 var _e = hTree(lcfreq, 7), 15182 lct = _e[0], 15183 mlcb = _e[1]; 15184 15185 var nlcc = 19; 15186 15187 for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc); 15188 15189 var flen = bl + 5 << 3; 15190 var ftlen = clen(lf, flt) + clen(df, fdt) + eb; 15191 var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]); 15192 if (flen <= ftlen && flen <= dtlen) return wfblk(out, p, dat.subarray(bs, bs + bl)); 15193 var lm, ll, dm, dl; 15194 wbits(out, p, 1 + (dtlen < ftlen)), p += 2; 15195 15196 if (dtlen < ftlen) { 15197 lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt; 15198 var llm = hMap(lct, mlcb, 0); 15199 wbits(out, p, nlc - 257); 15200 wbits(out, p + 5, ndc - 1); 15201 wbits(out, p + 10, nlcc - 4); 15202 p += 14; 15203 15204 for (var i = 0; i < nlcc; ++i) wbits(out, p + 3 * i, lct[clim[i]]); 15205 15206 p += 3 * nlcc; 15207 var lcts = [lclt, lcdt]; 15208 15209 for (var it = 0; it < 2; ++it) { 15210 var clct = lcts[it]; 15211 15212 for (var i = 0; i < clct.length; ++i) { 15213 var len = clct[i] & 31; 15214 wbits(out, p, llm[len]), p += lct[len]; 15215 if (len > 15) wbits(out, p, clct[i] >>> 5 & 127), p += clct[i] >>> 12; 15216 } 15217 } 15218 } else { 15219 lm = flm, ll = flt, dm = fdm, dl = fdt; 15220 } 15221 15222 for (var i = 0; i < li; ++i) { 15223 if (syms[i] > 255) { 15224 var len = syms[i] >>> 18 & 31; 15225 wbits16(out, p, lm[len + 257]), p += ll[len + 257]; 15226 if (len > 7) wbits(out, p, syms[i] >>> 23 & 31), p += fleb[len]; 15227 var dst = syms[i] & 31; 15228 wbits16(out, p, dm[dst]), p += dl[dst]; 15229 if (dst > 3) wbits16(out, p, syms[i] >>> 5 & 8191), p += fdeb[dst]; 15230 } else { 15231 wbits16(out, p, lm[syms[i]]), p += ll[syms[i]]; 15232 } 15233 } 15234 15235 wbits16(out, p, lm[256]); 15236 return p + ll[256]; 15237 }; // deflate options (nice << 13) | chain 15238 15239 15240 var deo = /*#__PURE__*/new u32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]); // empty 15241 15242 var et = /*#__PURE__*/new u8(0); // compresses data into a raw DEFLATE buffer 15243 15244 var dflt = function (dat, lvl, plvl, pre, post, lst) { 15245 var s = dat.length; 15246 var o = new u8(pre + s + 5 * (1 + Math.floor(s / 7000)) + post); // writing to this writes to the output buffer 15247 15248 var w = o.subarray(pre, o.length - post); 15249 var pos = 0; 15250 15251 if (!lvl || s < 8) { 15252 for (var i = 0; i <= s; i += 65535) { 15253 // end 15254 var e = i + 65535; 15255 15256 if (e < s) { 15257 // write full block 15258 pos = wfblk(w, pos, dat.subarray(i, e)); 15259 } else { 15260 // write final block 15261 w[i] = lst; 15262 pos = wfblk(w, pos, dat.subarray(i, s)); 15263 } 15264 } 15265 } else { 15266 var opt = deo[lvl - 1]; 15267 var n = opt >>> 13, 15268 c = opt & 8191; 15269 var msk_1 = (1 << plvl) - 1; // prev 2-byte val map curr 2-byte val map 15270 15271 var prev = new u16(32768), 15272 head = new u16(msk_1 + 1); 15273 var bs1_1 = Math.ceil(plvl / 3), 15274 bs2_1 = 2 * bs1_1; 15275 15276 var hsh = function (i) { 15277 return (dat[i] ^ dat[i + 1] << bs1_1 ^ dat[i + 2] << bs2_1) & msk_1; 15278 }; // 24576 is an arbitrary number of maximum symbols per block 15279 // 424 buffer for last block 15280 15281 15282 var syms = new u32(25000); // length/literal freq distance freq 15283 15284 var lf = new u16(288), 15285 df = new u16(32); // l/lcnt exbits index l/lind waitdx bitpos 15286 15287 var lc_1 = 0, 15288 eb = 0, 15289 i = 0, 15290 li = 0, 15291 wi = 0, 15292 bs = 0; 15293 15294 for (; i < s; ++i) { 15295 // hash value 15296 var hv = hsh(i); // index mod 32768 15297 15298 var imod = i & 32767; // previous index with this value 15299 15300 var pimod = head[hv]; 15301 prev[imod] = pimod; 15302 head[hv] = imod; // We always should modify head and prev, but only add symbols if 15303 // this data is not yet processed ("wait" for wait index) 15304 15305 if (wi <= i) { 15306 // bytes remaining 15307 var rem = s - i; 15308 15309 if ((lc_1 > 7000 || li > 24576) && rem > 423) { 15310 pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos); 15311 li = lc_1 = eb = 0, bs = i; 15312 15313 for (var j = 0; j < 286; ++j) lf[j] = 0; 15314 15315 for (var j = 0; j < 30; ++j) df[j] = 0; 15316 } // len dist chain 15317 15318 15319 var l = 2, 15320 d = 0, 15321 ch_1 = c, 15322 dif = imod - pimod & 32767; 15323 15324 if (rem > 2 && hv == hsh(i - dif)) { 15325 var maxn = Math.min(n, rem) - 1; 15326 var maxd = Math.min(32767, i); // max possible length 15327 // not capped at dif because decompressors implement "rolling" index population 15328 15329 var ml = Math.min(258, rem); 15330 15331 while (dif <= maxd && --ch_1 && imod != pimod) { 15332 if (dat[i + l] == dat[i + l - dif]) { 15333 var nl = 0; 15334 15335 for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl); 15336 15337 if (nl > l) { 15338 l = nl, d = dif; // break out early when we reach "nice" (we are satisfied enough) 15339 15340 if (nl > maxn) break; // now, find the rarest 2-byte sequence within this 15341 // length of literals and search for that instead. 15342 // Much faster than just using the start 15343 15344 var mmd = Math.min(dif, nl - 2); 15345 var md = 0; 15346 15347 for (var j = 0; j < mmd; ++j) { 15348 var ti = i - dif + j + 32768 & 32767; 15349 var pti = prev[ti]; 15350 var cd = ti - pti + 32768 & 32767; 15351 if (cd > md) md = cd, pimod = ti; 15352 } 15353 } 15354 } // check the previous match 15355 15356 15357 imod = pimod, pimod = prev[imod]; 15358 dif += imod - pimod + 32768 & 32767; 15359 } 15360 } // d will be nonzero only when a match was found 15361 15362 15363 if (d) { 15364 // store both dist and len data in one Uint32 15365 // Make sure this is recognized as a len/dist with 28th bit (2^28) 15366 syms[li++] = 268435456 | revfl[l] << 18 | revfd[d]; 15367 var lin = revfl[l] & 31, 15368 din = revfd[d] & 31; 15369 eb += fleb[lin] + fdeb[din]; 15370 ++lf[257 + lin]; 15371 ++df[din]; 15372 wi = i + l; 15373 ++lc_1; 15374 } else { 15375 syms[li++] = dat[i]; 15376 ++lf[dat[i]]; 15377 } 15378 } 15379 } 15380 15381 pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos); // this is the easiest way to avoid needing to maintain state 15382 15383 if (!lst) pos = wfblk(w, pos, et); 15384 } 15385 15386 return slc(o, 0, pre + shft(pos) + post); 15387 }; // CRC32 table 15388 15389 15390 var adler = function () { 15391 var a = 1, 15392 b = 0; 15393 return { 15394 p: function (d) { 15395 // closures have awful performance 15396 var n = a, 15397 m = b; 15398 var l = d.length; 15399 15400 for (var i = 0; i != l;) { 15401 var e = Math.min(i + 5552, l); 15402 15403 for (; i < e; ++i) n += d[i], m += n; 15404 15405 n %= 65521, m %= 65521; 15406 } 15407 15408 a = n, b = m; 15409 }, 15410 d: function () { 15411 return (a >>> 8 << 16 | (b & 255) << 8 | b >>> 8) + ((a & 255) << 23) * 2; 15412 } 15413 }; 15414 }; 15415 15416 var dopt = function (dat, opt, pre, post, st) { 15417 return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 12 + opt.mem, pre, post, !st); 15418 }; // Walmart object spread 15419 15420 15421 var wbytes = function (d, b, v) { 15422 for (; v; ++b) d[b] = v, v >>
vendor: 12,805 bytes, lines 15422-15859
15422>= 8; 15423 }; // gzip header 15424 15425 15426 var zlh = function (c, o) { 15427 var lv = o.level, 15428 fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2; 15429 c[0] = 120, c[1] = fl << 6 | (fl ? 32 - 2 * fl : 1); 15430 }; // zlib valid 15431 15432 15433 var zlv = function (d) { 15434 if ((d[0] & 15) != 8 || d[0] >>> 4 > 7 || (d[0] << 8 | d[1]) % 31) throw 'invalid zlib data'; 15435 if (d[1] & 32) throw 'invalid zlib data: preset dictionaries not supported'; 15436 }; 15437 /** 15438 * Compress data with Zlib 15439 * @param data The data to compress 15440 * @param opts The compression options 15441 * @returns The zlib-compressed version of the data 15442 */ 15443 15444 function zlibSync(data, opts) { 15445 if (opts === void 0) { 15446 opts = {}; 15447 } 15448 15449 var a = adler(); 15450 a.p(data); 15451 var d = dopt(data, opts, 2, 4); 15452 return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d; 15453 } 15454 /** 15455 * Expands Zlib data 15456 * @param data The data to decompress 15457 * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length. 15458 * @returns The decompressed version of the data 15459 */ 15460 15461 function unzlibSync(data, out) { 15462 return inflt((zlv(data), data.subarray(2, -4)), out); 15463 } // Default algorithm for compression (used because having a known output size allows faster decompression) 15464 15465 /** 15466 * @license 15467 * jsPDF filters PlugIn 15468 * Copyright (c) 2014 Aras Abbasi 15469 * 15470 * Licensed under the MIT License. 15471 * http://opensource.org/licenses/mit-license 15472 */ 15473 15474 (function (jsPDFAPI) { 15475 15476 var ASCII85Encode = function ASCII85Encode(a) { 15477 var b, c, d, e, f, g, h, i, j, k; // eslint-disable-next-line no-control-regex 15478 15479 for (!/[^\x00-\xFF]/.test(a), b = "\x00\x00\x00\x00".slice(a.length % 4 || 4), a += b, c = [], d = 0, e = a.length; e > d; d += 4) { 15480 f = (a.charCodeAt(d) << 24) + (a.charCodeAt(d + 1) << 16) + (a.charCodeAt(d + 2) << 8) + a.charCodeAt(d + 3), 0 !== f ? (k = f % 85, f = (f - k) / 85, j = f % 85, f = (f - j) / 85, i = f % 85, f = (f - i) / 85, h = f % 85, f = (f - h) / 85, g = f % 85, c.push(g + 33, h + 33, i + 33, j + 33, k + 33)) : c.push(122); 15481 } 15482 15483 return function (a, b) { 15484 for (var c = b; c > 0; c--) { 15485 a.pop(); 15486 } 15487 }(c, b.length), String.fromCharCode.apply(String, c) + "~>"; 15488 }; 15489 15490 var ASCII85Decode = function ASCII85Decode(a) { 15491 var c, 15492 d, 15493 e, 15494 f, 15495 g, 15496 h = String, 15497 l = "length", 15498 w = 255, 15499 x = "charCodeAt", 15500 y = "slice", 15501 z = "replace"; 15502 15503 for ("~>" === a[y](-2), a = a[y](0, -2)[z](/\s/g, "")[z]("z", "!!!!!"), c = "uuuuu"[y](a[l] % 5 || 5), a += c, e = [], f = 0, g = a[l]; g > f; f += 5) { 15504 d = 52200625 * (a[x](f) - 33) + 614125 * (a[x](f + 1) - 33) + 7225 * (a[x](f + 2) - 33) + 85 * (a[x](f + 3) - 33) + (a[x](f + 4) - 33), e.push(w & d >> 24, w & d >> 16, w & d >> 8, w & d); 15505 } 15506 15507 return function (a, b) { 15508 for (var c = b; c > 0; c--) { 15509 a.pop(); 15510 } 15511 }(e, c[l]), h.fromCharCode.apply(h, e); 15512 }; 15513 15514 var ASCIIHexEncode = function ASCIIHexEncode(value) { 15515 return value.split("").map(function (value) { 15516 return ("0" + value.charCodeAt().toString(16)).slice(-2); 15517 }).join("") + ">"; 15518 }; 15519 15520 var ASCIIHexDecode = function ASCIIHexDecode(value) { 15521 var regexCheckIfHex = new RegExp(/^([0-9A-Fa-f]{2})+$/); 15522 value = value.replace(/\s/g, ""); 15523 15524 if (value.indexOf(">") !== -1) { 15525 value = value.substr(0, value.indexOf(">")); 15526 } 15527 15528 if (value.length % 2) { 15529 value += "0"; 15530 } 15531 15532 if (regexCheckIfHex.test(value) === false) { 15533 return ""; 15534 } 15535 15536 var result = ""; 15537 15538 for (var i = 0; i < value.length; i += 2) { 15539 result += String.fromCharCode("0x" + (value[i] + value[i + 1])); 15540 } 15541 15542 return result; 15543 }; 15544 /* 15545 var FlatePredictors = { 15546 None: 1, 15547 TIFF: 2, 15548 PNG_None: 10, 15549 PNG_Sub: 11, 15550 PNG_Up: 12, 15551 PNG_Average: 13, 15552 PNG_Paeth: 14, 15553 PNG_Optimum: 15 15554 }; 15555 */ 15556 15557 15558 var FlateEncode = function FlateEncode(data) { 15559 var arr = new Uint8Array(data.length); 15560 var i = data.length; 15561 15562 while (i--) { 15563 arr[i] = data.charCodeAt(i); 15564 } 15565 15566 arr = zlibSync(arr); 15567 data = arr.reduce(function (data, byte) { 15568 return data + String.fromCharCode(byte); 15569 }, ""); 15570 return data; 15571 }; 15572 15573 jsPDFAPI.processDataByFilters = function (origData, filterChain) { 15574 15575 var i = 0; 15576 var data = origData || ""; 15577 var reverseChain = []; 15578 filterChain = filterChain || []; 15579 15580 if (typeof filterChain === "string") { 15581 filterChain = [filterChain]; 15582 } 15583 15584 for (i = 0; i < filterChain.length; i += 1) { 15585 switch (filterChain[i]) { 15586 case "ASCII85Decode": 15587 case "/ASCII85Decode": 15588 data = ASCII85Decode(data); 15589 reverseChain.push("/ASCII85Encode"); 15590 break; 15591 15592 case "ASCII85Encode": 15593 case "/ASCII85Encode": 15594 data = ASCII85Encode(data); 15595 reverseChain.push("/ASCII85Decode"); 15596 break; 15597 15598 case "ASCIIHexDecode": 15599 case "/ASCIIHexDecode": 15600 data = ASCIIHexDecode(data); 15601 reverseChain.push("/ASCIIHexEncode"); 15602 break; 15603 15604 case "ASCIIHexEncode": 15605 case "/ASCIIHexEncode": 15606 data = ASCIIHexEncode(data); 15607 reverseChain.push("/ASCIIHexDecode"); 15608 break; 15609 15610 case "FlateEncode": 15611 case "/FlateEncode": 15612 data = FlateEncode(data); 15613 reverseChain.push("/FlateDecode"); 15614 break; 15615 15616 default: 15617 throw new Error('The filter: "' + filterChain[i] + '" is not implemented'); 15618 } 15619 } 15620 15621 return { 15622 data: data, 15623 reverseChain: reverseChain.reverse().join(" ") 15624 }; 15625 }; 15626 })(jsPDF.API); 15627 15628 /** 15629 * @license 15630 * jsPDF fileloading PlugIn 15631 * Copyright (c) 2018 Aras Abbasi ([email protected]) 15632 * 15633 * Licensed under the MIT License. 15634 * http://opensource.org/licenses/mit-license 15635 */ 15636 /** 15637 * @name fileloading 15638 * @module 15639 */ 15640 15641 (function (jsPDFAPI) { 15642 /** 15643 * @name loadFile 15644 * @function 15645 * @param {string} url 15646 * @param {boolean} sync 15647 * @param {function} callback 15648 * @returns {string|undefined} result 15649 */ 15650 15651 jsPDFAPI.loadFile = function (url, sync, callback) { 15652 return browserRequest(url, sync, callback); 15653 }; 15654 /** 15655 * @name loadImageFile 15656 * @function 15657 * @param {string} path 15658 * @param {boolean} sync 15659 * @param {function} callback 15660 */ 15661 15662 15663 jsPDFAPI.loadImageFile = jsPDFAPI.loadFile; 15664 15665 function browserRequest(url, sync, callback) { 15666 sync = sync === false ? false : true; 15667 callback = typeof callback === "function" ? callback : function () {}; 15668 var result = undefined; 15669 15670 var xhr = function xhr(url, sync, callback) { 15671 var request = new XMLHttpRequest(); 15672 var i = 0; 15673 15674 var sanitizeUnicode = function sanitizeUnicode(data) { 15675 var dataLength = data.length; 15676 var charArray = []; 15677 var StringFromCharCode = String.fromCharCode; //Transform Unicode to ASCII 15678 15679 for (i = 0; i < dataLength; i += 1) { 15680 charArray.push(StringFromCharCode(data.charCodeAt(i) & 0xff)); 15681 } 15682 15683 return charArray.join(""); 15684 }; 15685 15686 request.open("GET", url, !sync); // XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com] 15687 15688 request.overrideMimeType("text/plain; charset=x-user-defined"); 15689 15690 if (sync === false) { 15691 request.onload = function () { 15692 if (request.status === 200) { 15693 callback(sanitizeUnicode(this.responseText)); 15694 } else { 15695 callback(undefined); 15696 } 15697 }; 15698 } 15699 15700 request.send(null); 15701 15702 if (sync && request.status === 200) { 15703 return sanitizeUnicode(request.responseText); 15704 } 15705 }; 15706 15707 try { 15708 result = xhr(url, sync, callback); // eslint-disable-next-line no-empty 15709 } catch (e) {} 15710 15711 return result; 15712 } 15713 })(jsPDF.API); 15714 15715 /** 15716 * jsPDF html PlugIn 15717 * 15718 * @name html 15719 * @module 15720 */ 15721 15722 (function (jsPDFAPI) { 15723 15724 function loadHtml2Canvas() { 15725 return function () { 15726 if (globalObject["html2canvas"]) { 15727 return Promise.resolve(globalObject["html2canvas"]); 15728 } 15729 15730 if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") { 15731 return new Promise(function (resolve, reject) { 15732 try { 15733 resolve(require("html2canvas")); 15734 } catch (e) { 15735 reject(e); 15736 } 15737 }); 15738 } 15739 15740 if (typeof define === "function" && define.amd) { 15741 return new Promise(function (resolve, reject) { 15742 try { 15743 require(["html2canvas"], resolve); 15744 } catch (e) { 15745 reject(e); 15746 } 15747 }); 15748 } 15749 15750 return Promise.reject(new Error("Could not load html2canvas")); 15751 }().catch(function (e) { 15752 return Promise.reject(new Error("Could not load html2canvas: " + e)); 15753 }).then(function (html2canvas) { 15754 return html2canvas.default ? html2canvas.default : html2canvas; 15755 }); 15756 } 15757 15758 function loadDomPurify() { 15759 return function () { 15760 if (globalObject["DOMPurify"]) { 15761 return Promise.resolve(globalObject["DOMPurify"]); 15762 } 15763 15764 if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") { 15765 return new Promise(function (resolve, reject) { 15766 try { 15767 resolve(require("dompurify")); 15768 } catch (e) { 15769 reject(e); 15770 } 15771 }); 15772 } 15773 15774 if (typeof define === "function" && define.amd) { 15775 return new Promise(function (resolve, reject) { 15776 try { 15777 require(["dompurify"], resolve); 15778 } catch (e) { 15779 reject(e); 15780 } 15781 }); 15782 } 15783 15784 return Promise.reject(new Error("Could not load dompurify")); 15785 }().catch(function (e) { 15786 return Promise.reject(new Error("Could not load dompurify: " + e)); 15787 }).then(function (dompurify) { 15788 return dompurify.default ? dompurify.default : dompurify; 15789 }); 15790 } 15791 /** 15792 * Determine the type of a variable/object. 15793 * 15794 * @private 15795 * @ignore 15796 */ 15797 15798 15799 var objType = function objType(obj) { 15800 var type = _typeof(obj); 15801 15802 if (type === "undefined") return "undefined";else if (type === "string" || obj instanceof String) return "string";else if (type === "number" || obj instanceof Number) return "number";else if (type === "function" || obj instanceof Function) return "function";else if (!!obj && obj.constructor === Array) return "array";else if (obj && obj.nodeType === 1) return "element";else if (type === "object") return "object";else return "unknown"; 15803 }; 15804 /** 15805 * Create an HTML element with optional className, innerHTML, and style. 15806 * 15807 * @private 15808 * @ignore 15809 */ 15810 15811 15812 var createElement = function createElement(tagName, opt) { 15813 var el = document.createElement(tagName); 15814 if (opt.className) el.className = opt.className; 15815 15816 if (opt.innerHTML && opt.dompurify) { 15817 el.innerHTML = opt.dompurify.sanitize(opt.innerHTML); 15818 } 15819 15820 for (var key in opt.style) { 15821 el.style[key] = opt.style[key]; 15822 } 15823 15824 return el; 15825 }; 15826 /** 15827 * Deep-clone a node and preserve contents/properties. 15828 * 15829 * @private 15830 * @ignore 15831 */ 15832 15833 15834 var cloneNode = function cloneNode(node, javascriptEnabled) { 15835 // Recursively clone the node. 15836 var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false); 15837 15838 for (var child = node.firstChild; child; child = child.nextSibling) { 15839 if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== "SCRIPT") { 15840 clone.appendChild(cloneNode(child, javascriptEnabled)); 15841 } 15842 } 15843 15844 if (node.nodeType === 1) { 15845 // Preserve contents/properties of special nodes. 15846 if (node.nodeName === "CANVAS") { 15847 clone.width = node.width; 15848 clone.height = node.height; 15849 clone.getContext("2d").drawImage(node, 0, 0); 15850 } else if (node.nodeName === "TEXTAREA" || node.nodeName === "SELECT") { 15851 clone.value = node.value; 15852 } // Preserve the node's scroll position when it loads. 15853 15854 15855 clone.addEventListener("load", function () { 15856 clone.scrollTop = node.scrollTop; 15857 clone.scrollLeft = node.scrollLeft; 15858 }, true); 15859 }
vendor: 26,443 bytes, lines 15859-16627
15859 // Return the cloned node. 15860 15861 15862 return clone; 15863 }; 15864 /* ----- CONSTRUCTOR ----- */ 15865 15866 15867 var Worker = function Worker(opt) { 15868 // Create the root parent for the proto chain, and the starting Worker. 15869 var root = Object.assign(Worker.convert(Promise.resolve()), JSON.parse(JSON.stringify(Worker.template))); 15870 var self = Worker.convert(Promise.resolve(), root); // Set progress, optional settings, and return. 15871 15872 self = self.setProgress(1, Worker, 1, [Worker]); 15873 self = self.set(opt); 15874 return self; 15875 }; // Boilerplate for subclassing Promise. 15876 15877 15878 Worker.prototype = Object.create(Promise.prototype); 15879 Worker.prototype.constructor = Worker; // Converts/casts promises into Workers. 15880 15881 Worker.convert = function convert(promise, inherit) { 15882 // Uses prototypal inheritance to receive changes made to ancestors' properties. 15883 promise.__proto__ = inherit || Worker.prototype; 15884 return promise; 15885 }; 15886 15887 Worker.template = { 15888 prop: { 15889 src: null, 15890 container: null, 15891 overlay: null, 15892 canvas: null, 15893 img: null, 15894 pdf: null, 15895 pageSize: null, 15896 callback: function callback() {} 15897 }, 15898 progress: { 15899 val: 0, 15900 state: null, 15901 n: 0, 15902 stack: [] 15903 }, 15904 opt: { 15905 filename: "file.pdf", 15906 margin: [0, 0, 0, 0], 15907 enableLinks: true, 15908 x: 0, 15909 y: 0, 15910 html2canvas: {}, 15911 jsPDF: {}, 15912 backgroundColor: "transparent" 15913 } 15914 }; 15915 /* ----- FROM / TO ----- */ 15916 15917 Worker.prototype.from = function from(src, type) { 15918 function getType(src) { 15919 switch (objType(src)) { 15920 case "string": 15921 return "string"; 15922 15923 case "element": 15924 return src.nodeName.toLowerCase() === "canvas" ? "canvas" : "element"; 15925 15926 default: 15927 return "unknown"; 15928 } 15929 } 15930 15931 return this.then(function from_main() { 15932 type = type || getType(src); 15933 15934 switch (type) { 15935 case "string": 15936 return this.then(loadDomPurify).then(function (dompurify) { 15937 return this.set({ 15938 src: createElement("div", { 15939 innerHTML: src, 15940 dompurify: dompurify 15941 }) 15942 }); 15943 }); 15944 15945 case "element": 15946 return this.set({ 15947 src: src 15948 }); 15949 15950 case "canvas": 15951 return this.set({ 15952 canvas: src 15953 }); 15954 15955 case "img": 15956 return this.set({ 15957 img: src 15958 }); 15959 15960 default: 15961 return this.error("Unknown source type."); 15962 } 15963 }); 15964 }; 15965 15966 Worker.prototype.to = function to(target) { 15967 // Route the 'to' request to the appropriate method. 15968 switch (target) { 15969 case "container": 15970 return this.toContainer(); 15971 15972 case "canvas": 15973 return this.toCanvas(); 15974 15975 case "img": 15976 return this.toImg(); 15977 15978 case "pdf": 15979 return this.toPdf(); 15980 15981 default: 15982 return this.error("Invalid target."); 15983 } 15984 }; 15985 15986 Worker.prototype.toContainer = function toContainer() { 15987 // Set up function prerequisites. 15988 var prereqs = [function checkSrc() { 15989 return this.prop.src || this.error("Cannot duplicate - no source HTML."); 15990 }, function checkPageSize() { 15991 return this.prop.pageSize || this.setPageSize(); 15992 }]; 15993 return this.thenList(prereqs).then(function toContainer_main() { 15994 // Define the CSS styles for the container and its overlay parent. 15995 var overlayCSS = { 15996 position: "fixed", 15997 overflow: "hidden", 15998 zIndex: 1000, 15999 left: "-100000px", 16000 right: 0, 16001 bottom: 0, 16002 top: 0 16003 }; 16004 var containerCSS = { 16005 position: "relative", 16006 display: "inline-block", 16007 width: (typeof this.opt.width === "number" && !isNaN(this.opt.width) && typeof this.opt.windowWidth === "number" && !isNaN(this.opt.windowWidth) ? this.opt.windowWidth : Math.max(this.prop.src.clientWidth, this.prop.src.scrollWidth, this.prop.src.offsetWidth)) + "px", 16008 left: 0, 16009 right: 0, 16010 top: 0, 16011 margin: "auto", 16012 backgroundColor: this.opt.backgroundColor 16013 }; // Set the overlay to hidden (could be changed in the future to provide a print preview). 16014 16015 var source = cloneNode(this.prop.src, this.opt.html2canvas.javascriptEnabled); 16016 16017 if (source.tagName === "BODY") { 16018 containerCSS.height = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight) + "px"; 16019 } 16020 16021 this.prop.overlay = createElement("div", { 16022 className: "html2pdf__overlay", 16023 style: overlayCSS 16024 }); 16025 this.prop.container = createElement("div", { 16026 className: "html2pdf__container", 16027 style: containerCSS 16028 }); 16029 this.prop.container.appendChild(source); 16030 this.prop.container.firstChild.appendChild(createElement("div", { 16031 style: { 16032 clear: "both", 16033 border: "0 none transparent", 16034 margin: 0, 16035 padding: 0, 16036 height: 0 16037 } 16038 })); 16039 this.prop.container.style.float = "none"; 16040 this.prop.overlay.appendChild(this.prop.container); 16041 document.body.appendChild(this.prop.overlay); 16042 this.prop.container.firstChild.style.position = "relative"; 16043 this.prop.container.height = Math.max(this.prop.container.firstChild.clientHeight, this.prop.container.firstChild.scrollHeight, this.prop.container.firstChild.offsetHeight) + "px"; 16044 }); 16045 }; 16046 16047 Worker.prototype.toCanvas = function toCanvas() { 16048 // Set up function prerequisites. 16049 var prereqs = [function checkContainer() { 16050 return document.body.contains(this.prop.container) || this.toContainer(); 16051 }]; // Fulfill prereqs then create the canvas. 16052 16053 return this.thenList(prereqs).then(loadHtml2Canvas).then(function toCanvas_main(html2canvas) { 16054 // Handle old-fashioned 'onrendered' argument. 16055 var options = Object.assign({}, this.opt.html2canvas); 16056 delete options.onrendered; 16057 return html2canvas(this.prop.container, options); 16058 }).then(function toCanvas_post(canvas) { 16059 // Handle old-fashioned 'onrendered' argument. 16060 var onRendered = this.opt.html2canvas.onrendered || function () {}; 16061 16062 onRendered(canvas); 16063 this.prop.canvas = canvas; 16064 document.body.removeChild(this.prop.overlay); 16065 }); 16066 }; 16067 16068 Worker.prototype.toContext2d = function toContext2d() { 16069 // Set up function prerequisites. 16070 var prereqs = [function checkContainer() { 16071 return document.body.contains(this.prop.container) || this.toContainer(); 16072 }]; // Fulfill prereqs then create the canvas. 16073 16074 return this.thenList(prereqs).then(loadHtml2Canvas).then(function toContext2d_main(html2canvas) { 16075 // Handle old-fashioned 'onrendered' argument. 16076 var pdf = this.opt.jsPDF; 16077 var fontFaces = this.opt.fontFaces; 16078 var scale = typeof this.opt.width === "number" && !isNaN(this.opt.width) && typeof this.opt.windowWidth === "number" && !isNaN(this.opt.windowWidth) ? this.opt.width / this.opt.windowWidth : 1; 16079 var options = Object.assign({ 16080 async: true, 16081 allowTaint: true, 16082 scale: scale, 16083 scrollX: this.opt.scrollX || 0, 16084 scrollY: this.opt.scrollY || 0, 16085 backgroundColor: "#ffffff", 16086 imageTimeout: 15000, 16087 logging: true, 16088 proxy: null, 16089 removeContainer: true, 16090 foreignObjectRendering: false, 16091 useCORS: false 16092 }, this.opt.html2canvas); 16093 delete options.onrendered; 16094 pdf.context2d.autoPaging = typeof this.opt.autoPaging === "undefined" ? true : this.opt.autoPaging; 16095 pdf.context2d.posX = this.opt.x; 16096 pdf.context2d.posY = this.opt.y; 16097 pdf.context2d.margin = this.opt.margin; 16098 pdf.context2d.fontFaces = fontFaces; 16099 16100 if (fontFaces) { 16101 for (var i = 0; i < fontFaces.length; ++i) { 16102 var font = fontFaces[i]; 16103 var src = font.src.find(function (src) { 16104 return src.format === "truetype"; 16105 }); 16106 16107 if (src) { 16108 pdf.addFont(src.url, font.ref.name, font.ref.style); 16109 } 16110 } 16111 } 16112 16113 options.windowHeight = options.windowHeight || 0; 16114 options.windowHeight = options.windowHeight == 0 ? Math.max(this.prop.container.clientHeight, this.prop.container.scrollHeight, this.prop.container.offsetHeight) : options.windowHeight; 16115 pdf.context2d.save(true); 16116 return html2canvas(this.prop.container, options); 16117 }).then(function toContext2d_post(canvas) { 16118 this.opt.jsPDF.context2d.restore(true); // Handle old-fashioned 'onrendered' argument. 16119 16120 var onRendered = this.opt.html2canvas.onrendered || function () {}; 16121 16122 onRendered(canvas); 16123 this.prop.canvas = canvas; 16124 document.body.removeChild(this.prop.overlay); 16125 }); 16126 }; 16127 16128 Worker.prototype.toImg = function toImg() { 16129 // Set up function prerequisites. 16130 var prereqs = [function checkCanvas() { 16131 return this.prop.canvas || this.toCanvas(); 16132 }]; // Fulfill prereqs then create the image. 16133 16134 return this.thenList(prereqs).then(function toImg_main() { 16135 var imgData = this.prop.canvas.toDataURL("image/" + this.opt.image.type, this.opt.image.quality); 16136 this.prop.img = document.createElement("img"); 16137 this.prop.img.src = imgData; 16138 }); 16139 }; 16140 16141 Worker.prototype.toPdf = function toPdf() { 16142 // Set up function prerequisites. 16143 var prereqs = [function checkContext2d() { 16144 return this.toContext2d(); 16145 } //function checkCanvas() { return this.prop.canvas || this.toCanvas(); } 16146 ]; // Fulfill prereqs then create the image. 16147 16148 return this.thenList(prereqs).then(function toPdf_main() { 16149 // Create local copies of frequently used properties. 16150 this.prop.pdf = this.prop.pdf || this.opt.jsPDF; 16151 }); 16152 }; 16153 /* ----- OUTPUT / SAVE ----- */ 16154 16155 16156 Worker.prototype.output = function output(type, options, src) { 16157 // Redirect requests to the correct function (outputPdf / outputImg). 16158 src = src || "pdf"; 16159 16160 if (src.toLowerCase() === "img" || src.toLowerCase() === "image") { 16161 return this.outputImg(type, options); 16162 } else { 16163 return this.outputPdf(type, options); 16164 } 16165 }; 16166 16167 Worker.prototype.outputPdf = function outputPdf(type, options) { 16168 // Set up function prerequisites. 16169 var prereqs = [function checkPdf() { 16170 return this.prop.pdf || this.toPdf(); 16171 }]; // Fulfill prereqs then perform the appropriate output. 16172 16173 return this.thenList(prereqs).then(function outputPdf_main() { 16174 /* Currently implemented output types: 16175 * https://rawgit.com/MrRio/jsPDF/master/docs/jspdf.js.html#line992 16176 * save(options), arraybuffer, blob, bloburi/bloburl, 16177 * datauristring/dataurlstring, dataurlnewwindow, datauri/dataurl 16178 */ 16179 return this.prop.pdf.output(type, options); 16180 }); 16181 }; 16182 16183 Worker.prototype.outputImg = function outputImg(type) { 16184 // Set up function prerequisites. 16185 var prereqs = [function checkImg() { 16186 return this.prop.img || this.toImg(); 16187 }]; // Fulfill prereqs then perform the appropriate output. 16188 16189 return this.thenList(prereqs).then(function outputImg_main() { 16190 switch (type) { 16191 case undefined: 16192 case "img": 16193 return this.prop.img; 16194 16195 case "datauristring": 16196 case "dataurlstring": 16197 return this.prop.img.src; 16198 16199 case "datauri": 16200 case "dataurl": 16201 return document.location.href = this.prop.img.src; 16202 16203 default: 16204 throw 'Image output type "' + type + '" is not supported.'; 16205 } 16206 }); 16207 }; 16208 16209 Worker.prototype.save = function save(filename) { 16210 // Set up function prerequisites. 16211 var prereqs = [function checkPdf() { 16212 return this.prop.pdf || this.toPdf(); 16213 }]; // Fulfill prereqs, update the filename (if provided), and save the PDF. 16214 16215 return this.thenList(prereqs).set(filename ? { 16216 filename: filename 16217 } : null).then(function save_main() { 16218 this.prop.pdf.save(this.opt.filename); 16219 }); 16220 }; 16221 16222 Worker.prototype.doCallback = function doCallback() { 16223 // Set up function prerequisites. 16224 var prereqs = [function checkPdf() { 16225 return this.prop.pdf || this.toPdf(); 16226 }]; // Fulfill prereqs, update the filename (if provided), and save the PDF. 16227 16228 return this.thenList(prereqs).then(function doCallback_main() { 16229 this.prop.callback(this.prop.pdf); 16230 }); 16231 }; 16232 /* ----- SET / GET ----- */ 16233 16234 16235 Worker.prototype.set = function set(opt) { 16236 // TODO: Implement ordered pairs? 16237 // Silently ignore invalid or empty input. 16238 if (objType(opt) !== "object") { 16239 return this; 16240 } // Build an array of setter functions to queue. 16241 16242 16243 var fns = Object.keys(opt || {}).map(function (key) { 16244 if (key in Worker.template.prop) { 16245 // Set pre-defined properties. 16246 return function set_prop() { 16247 this.prop[key] = opt[key]; 16248 }; 16249 } else { 16250 switch (key) { 16251 case "margin": 16252 return this.setMargin.bind(this, opt.margin); 16253 16254 case "jsPDF": 16255 return function set_jsPDF() { 16256 this.opt.jsPDF = opt.jsPDF; 16257 return this.setPageSize(); 16258 }; 16259 16260 case "pageSize": 16261 return this.setPageSize.bind(this, opt.pageSize); 16262 16263 default: 16264 // Set any other properties in opt. 16265 return function set_opt() { 16266 this.opt[key] = opt[key]; 16267 }; 16268 } 16269 } 16270 }, this); // Set properties within the promise chain. 16271 16272 return this.then(function set_main() { 16273 return this.thenList(fns); 16274 }); 16275 }; 16276 16277 Worker.prototype.get = function get(key, cbk) { 16278 return this.then(function get_main() { 16279 // Fetch the requested property, either as a predefined prop or in opt. 16280 var val = key in Worker.template.prop ? this.prop[key] : this.opt[key]; 16281 return cbk ? cbk(val) : val; 16282 }); 16283 }; 16284 16285 Worker.prototype.setMargin = function setMargin(margin) { 16286 return this.then(function setMargin_main() { 16287 // Parse the margin property. 16288 switch (objType(margin)) { 16289 case "number": 16290 margin = [margin, margin, margin, margin]; 16291 // eslint-disable-next-line no-fallthrough 16292 16293 case "array": 16294 if (margin.length === 2) { 16295 margin = [margin[0], margin[1], margin[0], margin[1]]; 16296 } 16297 16298 if (margin.length === 4) { 16299 break; 16300 } 16301 16302 // eslint-disable-next-line no-fallthrough 16303 16304 default: 16305 return this.error("Invalid margin array."); 16306 } // Set the margin property, then update pageSize. 16307 16308 16309 this.opt.margin = margin; 16310 }).then(this.setPageSize); 16311 }; 16312 16313 Worker.prototype.setPageSize = function setPageSize(pageSize) { 16314 function toPx(val, k) { 16315 return Math.floor(val * k / 72 * 96); 16316 } 16317 16318 return this.then(function setPageSize_main() { 16319 // Retrieve page-size based on jsPDF settings, if not explicitly provided. 16320 pageSize = pageSize || jsPDF.getPageSize(this.opt.jsPDF); // Add 'inner' field if not present. 16321 16322 if (!pageSize.hasOwnProperty("inner")) { 16323 pageSize.inner = { 16324 width: pageSize.width - this.opt.margin[1] - this.opt.margin[3], 16325 height: pageSize.height - this.opt.margin[0] - this.opt.margin[2] 16326 }; 16327 pageSize.inner.px = { 16328 width: toPx(pageSize.inner.width, pageSize.k), 16329 height: toPx(pageSize.inner.height, pageSize.k) 16330 }; 16331 pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width; 16332 } // Attach pageSize to this. 16333 16334 16335 this.prop.pageSize = pageSize; 16336 }); 16337 }; 16338 16339 Worker.prototype.setProgress = function setProgress(val, state, n, stack) { 16340 // Immediately update all progress values. 16341 if (val != null) this.progress.val = val; 16342 if (state != null) this.progress.state = state; 16343 if (n != null) this.progress.n = n; 16344 if (stack != null) this.progress.stack = stack; 16345 this.progress.ratio = this.progress.val / this.progress.state; // Return this for command chaining. 16346 16347 return this; 16348 }; 16349 16350 Worker.prototype.updateProgress = function updateProgress(val, state, n, stack) { 16351 // Immediately update all progress values, using setProgress. 16352 return this.setProgress(val ? this.progress.val + val : null, state ? state : null, n ? this.progress.n + n : null, stack ? this.progress.stack.concat(stack) : null); 16353 }; 16354 /* ----- PROMISE MAPPING ----- */ 16355 16356 16357 Worker.prototype.then = function then(onFulfilled, onRejected) { 16358 // Wrap `this` for encapsulation. 16359 var self = this; 16360 return this.thenCore(onFulfilled, onRejected, function then_main(onFulfilled, onRejected) { 16361 // Update progress while queuing, calling, and resolving `then`. 16362 self.updateProgress(null, null, 1, [onFulfilled]); 16363 return Promise.prototype.then.call(this, function then_pre(val) { 16364 self.updateProgress(null, onFulfilled); 16365 return val; 16366 }).then(onFulfilled, onRejected).then(function then_post(val) { 16367 self.updateProgress(1); 16368 return val; 16369 }); 16370 }); 16371 }; 16372 16373 Worker.prototype.thenCore = function thenCore(onFulfilled, onRejected, thenBase) { 16374 // Handle optional thenBase parameter. 16375 thenBase = thenBase || Promise.prototype.then; // Wrap `this` for encapsulation and bind it to the promise handlers. 16376 16377 var self = this; 16378 16379 if (onFulfilled) { 16380 onFulfilled = onFulfilled.bind(self); 16381 } 16382 16383 if (onRejected) { 16384 onRejected = onRejected.bind(self); 16385 } // Cast self into a Promise to avoid polyfills recursively defining `then`. 16386 16387 16388 var isNative = Promise.toString().indexOf("[native code]") !== -1 && Promise.name === "Promise"; 16389 var selfPromise = isNative ? self : Worker.convert(Object.assign({}, self), Promise.prototype); // Return the promise, after casting it into a Worker and preserving props. 16390 16391 var returnVal = thenBase.call(selfPromise, onFulfilled, onRejected); 16392 return Worker.convert(returnVal, self.__proto__); 16393 }; 16394 16395 Worker.prototype.thenExternal = function thenExternal(onFulfilled, onRejected) { 16396 // Call `then` and return a standard promise (exits the Worker chain). 16397 return Promise.prototype.then.call(this, onFulfilled, onRejected); 16398 }; 16399 16400 Worker.prototype.thenList = function thenList(fns) { 16401 // Queue a series of promise 'factories' into the promise chain. 16402 var self = this; 16403 fns.forEach(function thenList_forEach(fn) { 16404 self = self.thenCore(fn); 16405 }); 16406 return self; 16407 }; 16408 16409 Worker.prototype["catch"] = function (onRejected) { 16410 // Bind `this` to the promise handler, call `catch`, and return a Worker. 16411 if (onRejected) { 16412 onRejected = onRejected.bind(this); 16413 } 16414 16415 var returnVal = Promise.prototype["catch"].call(this, onRejected); 16416 return Worker.convert(returnVal, this); 16417 }; 16418 16419 Worker.prototype.catchExternal = function catchExternal(onRejected) { 16420 // Call `catch` and return a standard promise (exits the Worker chain). 16421 return Promise.prototype["catch"].call(this, onRejected); 16422 }; 16423 16424 Worker.prototype.error = function error(msg) { 16425 // Throw the error in the Promise chain. 16426 return this.then(function error_main() { 16427 throw new Error(msg); 16428 }); 16429 }; 16430 /* ----- ALIASES ----- */ 16431 16432 16433 Worker.prototype.using = Worker.prototype.set; 16434 Worker.prototype.saveAs = Worker.prototype.save; 16435 Worker.prototype.export = Worker.prototype.output; 16436 Worker.prototype.run = Worker.prototype.then; // Get dimensions of a PDF page, as determined by jsPDF. 16437 16438 jsPDF.getPageSize = function (orientation, unit, format) { 16439 // Decode options object 16440 if (_typeof(orientation) === "object") { 16441 var options = orientation; 16442 orientation = options.orientation; 16443 unit = options.unit || unit; 16444 format = options.format || format; 16445 } // Default options 16446 16447 16448 unit = unit || "mm"; 16449 format = format || "a4"; 16450 orientation = ("" + (orientation || "P")).toLowerCase(); 16451 var format_as_string = ("" + format).toLowerCase(); // Size in pt of various paper formats 16452 16453 var pageFormats = { 16454 a0: [2383.94, 3370.39], 16455 a1: [1683.78, 2383.94], 16456 a2: [1190.55, 1683.78], 16457 a3: [841.89, 1190.55], 16458 a4: [595.28, 841.89], 16459 a5: [419.53, 595.28], 16460 a6: [297.64, 419.53], 16461 a7: [209.76, 297.64], 16462 a8: [147.4, 209.76], 16463 a9: [104.88, 147.4], 16464 a10: [73.7, 104.88], 16465 b0: [2834.65, 4008.19], 16466 b1: [2004.09, 2834.65], 16467 b2: [1417.32, 2004.09], 16468 b3: [1000.63, 1417.32], 16469 b4: [708.66, 1000.63], 16470 b5: [498.9, 708.66], 16471 b6: [354.33, 498.9], 16472 b7: [249.45, 354.33], 16473 b8: [175.75, 249.45], 16474 b9: [124.72, 175.75], 16475 b10: [87.87, 124.72], 16476 c0: [2599.37, 3676.54], 16477 c1: [1836.85, 2599.37], 16478 c2: [1298.27, 1836.85], 16479 c3: [918.43, 1298.27], 16480 c4: [649.13, 918.43], 16481 c5: [459.21, 649.13], 16482 c6: [323.15, 459.21], 16483 c7: [229.61, 323.15], 16484 c8: [161.57, 229.61], 16485 c9: [113.39, 161.57], 16486 c10: [79.37, 113.39], 16487 dl: [311.81, 623.62], 16488 letter: [612, 792], 16489 "government-letter": [576, 756], 16490 legal: [612, 1008], 16491 "junior-legal": [576, 360], 16492 ledger: [1224, 792], 16493 tabloid: [792, 1224], 16494 "credit-card": [153, 243] 16495 }; 16496 var k; // Unit conversion 16497 16498 switch (unit) { 16499 case "pt": 16500 k = 1; 16501 break; 16502 16503 case "mm": 16504 k = 72 / 25.4; 16505 break; 16506 16507 case "cm": 16508 k = 72 / 2.54; 16509 break; 16510 16511 case "in": 16512 k = 72; 16513 break; 16514 16515 case "px": 16516 k = 72 / 96; 16517 break; 16518 16519 case "pc": 16520 k = 12; 16521 break; 16522 16523 case "em": 16524 k = 12; 16525 break; 16526 16527 case "ex": 16528 k = 6; 16529 break; 16530 16531 default: 16532 throw "Invalid unit: " + unit; 16533 } 16534 16535 var pageHeight = 0; 16536 var pageWidth = 0; // Dimensions are stored as user units and converted to points on output 16537 16538 if (pageFormats.hasOwnProperty(format_as_string)) { 16539 pageHeight = pageFormats[format_as_string][1] / k; 16540 pageWidth = pageFormats[format_as_string][0] / k; 16541 } else { 16542 try { 16543 pageHeight = format[1]; 16544 pageWidth = format[0]; 16545 } catch (err) { 16546 throw new Error("Invalid format: " + format); 16547 } 16548 } 16549 16550 var tmp; // Handle page orientation 16551 16552 if (orientation === "p" || orientation === "portrait") { 16553 orientation = "p"; 16554 16555 if (pageWidth > pageHeight) { 16556 tmp = pageWidth; 16557 pageWidth = pageHeight; 16558 pageHeight = tmp; 16559 } 16560 } else if (orientation === "l" || orientation === "landscape") { 16561 orientation = "l"; 16562 16563 if (pageHeight > pageWidth) { 16564 tmp = pageWidth; 16565 pageWidth = pageHeight; 16566 pageHeight = tmp; 16567 } 16568 } else { 16569 throw "Invalid orientation: " + orientation; 16570 } // Return information (k is the unit conversion ratio from pts) 16571 16572 16573 var info = { 16574 width: pageWidth, 16575 height: pageHeight, 16576 unit: unit, 16577 k: k, 16578 orientation: orientation 16579 }; 16580 return info; 16581 }; 16582 /** 16583 * @typedef FontFace 16584 * 16585 * The font-face type implements an interface similar to that of the font-face CSS rule, 16586 * and is used by jsPDF to match fonts when the font property of CanvasRenderingContext2D 16587 * is updated. 16588 * 16589 * All properties expect values similar to those in the font-face CSS rule. A difference 16590 * is the font-family, which do not need to be enclosed in double-quotes when containing 16591 * spaces like in CSS. 16592 * 16593 * @property {string} family The name of the font-family. 16594 * @property {string|undefined} style The style that this font-face defines, e.g. 'italic'. 16595 * @property {string|number|undefined} weight The weight of the font, either as a string or a number (400, 500, 600, e.g.) 16596 * @property {string|undefined} stretch The stretch of the font, e.g. condensed, normal, expanded. 16597 * @property {Object[]} src A list of URLs from where fonts of various formats can be fetched. 16598 * @property {string} [src] url A URL to a font of a specific format. 16599 * @property {string} [src] format Format of the font referenced by the URL. 16600 */ 16601 16602 /** 16603 * Generate a PDF from an HTML element or string using. 16604 * 16605 * @name html 16606 * @function 16607 * @param {HTMLElement|string} source The source HTMLElement or a string containing HTML. 16608 * @param {Object} [options] Collection of settings 16609 * @param {function} [options.callback] The mandatory callback-function gets as first parameter the current jsPDF instance 16610 * @param {(number|number[])=} [options.margin] Page margins [top, right, bottom, left]. Default is 0. 16611 * @param {(boolean|'slice'|'text')=} [options.autoPaging] The auto paging mode. 16612 * <ul> 16613 * <li> 16614 * <code>false</code>: Auto paging is disabled. 16615 * </li> 16616 * <li> 16617 * <code>true</code> or <code>'slice'</code>: Will cut shapes or text chunks across page breaks. Will possibly 16618 * slice text in half, making it difficult to read. 16619 * </li> 16620 * <li> 16621 * <code>'text'</code>: Trys not to cut text in half across page breaks. Works best for documents consisting 16622 * mostly of a single column of text. 16623 * </li> 16624 * </ul> 16625 * Default is <code>true</code>. 16626 * @param {string} [options.filename] name of the file 16627 * @param {HTMLOptionImage}
16627 [options.image] image settings when converting HTML to image 16628 * @param {Html2CanvasOptions} [options.html2canvas] html2canvas options 16629 * @param {FontFace[]} [options.fontFaces] A list of font-faces to match when resolving fonts. Fonts will be added to the PDF based on the specified URL. If omitted, the font match algorithm falls back to old algorithm. 16630 * @param {jsPDF} [options.jsPDF] jsPDF instance 16631 * @param {number=} [options.x] x position on the PDF document in jsPDF units. 16632 * @param {number=} [options.y] y position on the PDF document in jsPDF units. 16633 * @param {number=} [options.width] The target width in the PDF document in jsPDF units. The rendered element will be 16634 * scaled such that it fits into the specified width. Has no effect if either the <code>html2canvas.scale<code> is 16635 * specified or the <code>windowWidth</code> option is NOT specified. 16636 * @param {number=} [options.windowWidth] The window width in CSS pixels. In contrast to the 16637 * <code>html2canvas.windowWidth</code> option, this option affects the actual container size while rendering and 16638 * does NOT affect CSS media queries. This option only has an effect, if the <code>width<code> option is also specified. 16639 * 16640 * @example 16641 * var doc = new jsPDF(); 16642 * 16643 * doc.html(document.body, { 16644 * callback: function (doc) { 16645 * doc.save(); 16646 * }, 16647 * x: 10, 16648 * y: 10 16649 * }); 16650 */ 16651 16652 16653 jsPDFAPI.html = function (src, options) { 16654 16655 options = options || {}; 16656 16657 options.callback = options.callback || function () {}; 16658 16659 options.html2canvas = options.html2canvas || {}; 16660 options.html2canvas.canvas = options.html2canvas.canvas || this.canvas; 16661 options.jsPDF = options.jsPDF || this; 16662 options.fontFaces = options.fontFaces ? options.fontFaces.map(normalizeFontFace) : null; // Create a new worker with the given options. 16663 16664 var worker = new Worker(options); 16665 16666 if (!options.worker) { 16667 // If worker is not set to true, perform the traditional 'simple' operation. 16668 return worker.from(src).doCallback(); 16669 } else { 16670 // Otherwise, return the worker for new Promise-based operation. 16671 return worker; 16672 } 16673 }; 16674 })(jsPDF.API); 16675 16676 /** 16677 * @license 16678 * ==================================================================== 16679 * Copyright (c) 2013 Youssef Beddad, [email protected] 16680 * 16681 * Permission is hereby granted, free of charge, to any person obtaining 16682 * a copy of this software and associated documentation files (the 16683 * "Software"), to deal in the Software without restriction, including 16684 * without limitation the rights to use, copy, modify, merge, publish, 16685 * distribute, sublicense, and/or sell copies of the Software, and to 16686 * permit persons to whom the Software is furnished to do so, subject to 16687 * the following conditions: 16688 * 16689 * The above copyright notice and this permission notice shall be 16690 * included in all copies or substantial portions of the Software. 16691 * 16692 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16693 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16694 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 16695 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 16696 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16697 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 16698 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16699 * ==================================================================== 16700 */ 16701 /** 16702 * jsPDF JavaScript plugin 16703 * 16704 * @name javascript 16705 * @module 16706 */ 16707 16708 (function (jsPDFAPI) { 16709 16710 var jsNamesObj, jsJsObj, text; 16711 /** 16712 * @name addJS 16713 * @function 16714 * @param {string} javascript The javascript to be embedded into the PDF-file. 16715 * @returns {jsPDF} 16716 */ 16717 16718 jsPDFAPI.addJS = function (javascript) { 16719 text = javascript; 16720 this.internal.events.subscribe("postPutResources", function () { 16721 jsNamesObj = this.internal.newObject(); 16722 this.internal.out("<<"); 16723 this.internal.out("/Names [(EmbeddedJS) " + (jsNamesObj + 1) + " 0 R]"); 16724 this.internal.out(">>"); 16725 this.internal.out("endobj"); 16726 jsJsObj = this.internal.newObject(); 16727 this.internal.out("<<"); 16728 this.internal.out("/S /JavaScript");
vendor: 5,584 bytes, lines 16729-16914
16729 this.internal.out("/JS (" + text + ")"); 16730 this.internal.out(">>"); 16731 this.internal.out("endobj"); 16732 }); 16733 this.internal.events.subscribe("putCatalog", function () { 16734 if (jsNamesObj !== undefined && jsJsObj !== undefined) { 16735 this.internal.out("/Names <</JavaScript " + jsNamesObj + " 0 R>>"); 16736 } 16737 }); 16738 return this; 16739 }; 16740 })(jsPDF.API); 16741 16742 /** 16743 * @license 16744 * Copyright (c) 2014 Steven Spungin (TwelveTone LLC) [email protected] 16745 * 16746 * Licensed under the MIT License. 16747 * http://opensource.org/licenses/mit-license 16748 */ 16749 /** 16750 * jsPDF Outline PlugIn 16751 * 16752 * Generates a PDF Outline 16753 * @name outline 16754 * @module 16755 */ 16756 16757 (function (jsPDFAPI) { 16758 16759 var namesOid; //var destsGoto = []; 16760 16761 jsPDFAPI.events.push(["postPutResources", function () { 16762 var pdf = this; 16763 var rx = /^(\d+) 0 obj$/; // Write action goto objects for each page 16764 // this.outline.destsGoto = []; 16765 // for (var i = 0; i < totalPages; i++) { 16766 // var id = pdf.internal.newObject(); 16767 // this.outline.destsGoto.push(id); 16768 // pdf.internal.write("<</D[" + (i * 2 + 3) + " 0 R /XYZ null 16769 // null null]/S/GoTo>> endobj"); 16770 // } 16771 // 16772 // for (var i = 0; i < dests.length; i++) { 16773 // pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0 16774 // R"); 16775 // } 16776 // 16777 16778 if (this.outline.root.children.length > 0) { 16779 var lines = pdf.outline.render().split(/\r\n/); 16780 16781 for (var i = 0; i < lines.length; i++) { 16782 var line = lines[i]; 16783 var m = rx.exec(line); 16784 16785 if (m != null) { 16786 var oid = m[1]; 16787 pdf.internal.newObjectDeferredBegin(oid, false); 16788 } 16789 16790 pdf.internal.write(line); 16791 } 16792 } // This code will write named destination for each page reference 16793 // (page_1, etc) 16794 16795 16796 if (this.outline.createNamedDestinations) { 16797 var totalPages = this.internal.pages.length; // WARNING: this assumes jsPDF starts on page 3 and pageIDs 16798 // follow 5, 7, 9, etc 16799 // Write destination objects for each page 16800 16801 var dests = []; 16802 16803 for (var i = 0; i < totalPages; i++) { 16804 var id = pdf.internal.newObject(); 16805 dests.push(id); 16806 var info = pdf.internal.getPageInfo(i + 1); 16807 pdf.internal.write("<< /D[" + info.objId + " 0 R /XYZ null null null]>> endobj"); 16808 } // assign a name for each destination 16809 16810 16811 var names2Oid = pdf.internal.newObject(); 16812 pdf.internal.write("<< /Names [ "); 16813 16814 for (var i = 0; i < dests.length; i++) { 16815 pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0 R"); 16816 } 16817 16818 pdf.internal.write(" ] >>", "endobj"); // var kids = pdf.internal.newObject(); 16819 // pdf.internal.write('<< /Kids [ ' + names2Oid + ' 0 R'); 16820 // pdf.internal.write(' ] >>', 'endobj'); 16821 16822 namesOid = pdf.internal.newObject(); 16823 pdf.internal.write("<< /Dests " + names2Oid + " 0 R"); 16824 pdf.internal.write(">>", "endobj"); 16825 } 16826 }]); 16827 jsPDFAPI.events.push(["putCatalog", function () { 16828 var pdf = this; 16829 16830 if (pdf.outline.root.children.length > 0) { 16831 pdf.internal.write("/Outlines", this.outline.makeRef(this.outline.root)); 16832 16833 if (this.outline.createNamedDestinations) { 16834 pdf.internal.write("/Names " + namesOid + " 0 R"); 16835 } // Open with Bookmarks showing 16836 // pdf.internal.write("/PageMode /UseOutlines"); 16837 16838 } 16839 }]); 16840 jsPDFAPI.events.push(["initialized", function () { 16841 var pdf = this; 16842 pdf.outline = { 16843 createNamedDestinations: false, 16844 root: { 16845 children: [] 16846 } 16847 }; 16848 /** 16849 * Options: pageNumber 16850 */ 16851 16852 pdf.outline.add = function (parent, title, options) { 16853 var item = { 16854 title: title, 16855 options: options, 16856 children: [] 16857 }; 16858 16859 if (parent == null) { 16860 parent = this.root; 16861 } 16862 16863 parent.children.push(item); 16864 return item; 16865 }; 16866 16867 pdf.outline.render = function () { 16868 this.ctx = {}; 16869 this.ctx.val = ""; 16870 this.ctx.pdf = pdf; 16871 this.genIds_r(this.root); 16872 this.renderRoot(this.root); 16873 this.renderItems(this.root); 16874 return this.ctx.val; 16875 }; 16876 16877 pdf.outline.genIds_r = function (node) { 16878 node.id = pdf.internal.newObjectDeferred(); 16879 16880 for (var i = 0; i < node.children.length; i++) { 16881 this.genIds_r(node.children[i]); 16882 } 16883 }; 16884 16885 pdf.outline.renderRoot = function (node) { 16886 this.objStart(node); 16887 this.line("/Type /Outlines"); 16888 16889 if (node.children.length > 0) { 16890 this.line("/First " + this.makeRef(node.children[0])); 16891 this.line("/Last " + this.makeRef(node.children[node.children.length - 1])); 16892 } 16893 16894 this.line("/Count " + this.count_r({ 16895 count: 0 16896 }, node)); 16897 this.objEnd(); 16898 }; 16899 16900 pdf.outline.renderItems = function (node) { 16901 var getVerticalCoordinateString = this.ctx.pdf.internal.getVerticalCoordinateString; 16902 16903 for (var i = 0; i < node.children.length; i++) { 16904 var item = node.children[i]; 16905 this.objStart(item); 16906 this.line("/Title " + this.makeString(item.title)); 16907 this.line("/Parent " + this.makeRef(node)); 16908 16909 if (i > 0) { 16910 this.line("/Prev " + this.makeRef(node.children[i - 1])); 16911 } 16912 16913 if (i < node.children.length - 1) { 16914 this.line("/Next " + this.makeRef(node.children[i + 1])
16914); 16915 } 16916 16917 if (item.children.length > 0) { 16918 this.line("/First " + this.makeRef(item.children[0])); 16919 this.line("/Last " + this.makeRef(item.children[item.children.length - 1])); 16920 } 16921 16922 var count = this.count = this.count_r({ 16923 count: 0 16924 }, item); 16925 16926 if (count > 0) { 16927 this.line("/Count " + count); 16928 } 16929 16930 if (item.options) { 16931 if (item.options.pageNumber) { 16932 // Explicit Destination 16933 //WARNING this assumes page ids are 3,5,7, etc. 16934 var info = pdf.internal.getPageInfo(item.options.pageNumber); 16935 this.line("/Dest " + "[" + info.objId + " 0 R /XYZ 0 " + getVerticalCoordinateString(0) + " 0]"); // this line does not work on all clients (pageNumber instead of page ref) 16936 //this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() + ' 0]'); 16937 // Named Destination 16938 // this.line('/Dest (page_' + (item.options.pageNumber) + ')'); 16939 // Action Destination 16940 // var id = pdf.internal.newObject(); 16941 // pdf.internal.write('<</D[' + (item.options.pageNumber - 1) + ' /XYZ null null null]/S/GoTo>> endobj'); 16942 // this.line('/A ' + id + ' 0 R' ); 16943 } 16944 } 16945 16946 this.objEnd(); 16947 } 16948 16949 for (var z = 0; z < node.children.length; z++) { 16950 this.renderItems(node.children[z]); 16951 } 16952 }; 16953 16954 pdf.outline.line = function (text) { 16955 this.ctx.val += text + "\r\n"; 16956 }; 16957 16958 pdf.outline.makeRef = function (node) { 16959 return node.id + " 0 R"; 16960 }; 16961 16962 pdf.outline.makeString = function (val) { 16963 return "(" + pdf.internal.pdfEscape(val) + ")"; 16964 }; 16965 16966 pdf.outline.objStart = function (node) { 16967 this.ctx.val += "\r\n" + node.id + " 0 obj" + "\r\n<<\r\n"; 16968 }; 16969 16970 pdf.outline.objEnd = function () { 16971 this.ctx.val += ">> \r\n" + "endobj" + "\r\n"; 16972 }; 16973 16974 pdf.outline.count_r = function (ctx, node) { 16975 for (var i = 0; i < node.children.length; i++) { 16976 ctx.count++; 16977 this.count_r(ctx, node.children[i]); 16978 } 16979 16980 return ctx.count; 16981 }; 16982 }]); 16983 return this; 16984 })(jsPDF.API); 16985 16986 /** 16987 * @license 16988 * 16989 * Licensed under the MIT License. 16990 * http://opensource.org/licenses/mit-license 16991 */ 16992 /** 16993 * jsPDF jpeg Support PlugIn 16994 * 16995 * @name jpeg_support 16996 * @module 16997 */ 16998 16999 (function (jsPDFAPI) { 17000 /** 17001 * 0xc0 (SOF) Huffman - Baseline DCT 17002 * 0xc1 (SOF) Huffman - Extended sequential DCT 17003 * 0xc2 Progressive DCT (SOF2) 17004 * 0xc3 Spatial (sequential) lossless (SOF3) 17005 * 0xc4 Differential sequential DCT (SOF5) 17006 * 0xc5 Differential progressive DCT (SOF6) 17007 * 0xc6 Differential spatial (SOF7) 17008 * 0xc7 17009 */ 17010 17011 var markers = [0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7]; //takes a string imgData containing the raw bytes of 17012 //a jpeg image and returns [width, height] 17013 //Algorithm from: http://www.64lines.com/jpeg-width-height 17014 17015 var getJpegInfo = function getJpegInfo(imgData) { 17016 var width, height, numcomponents; 17017 var blockLength = imgData.charCodeAt(4) * 256 + imgData.charCodeAt(5); 17018 var len = imgData.length; 17019 var result = { 17020 width: 0, 17021 height: 0, 17022 numcomponents: 1 17023 }; 17024 17025 for (var i = 4; i < len; i += 2) { 17026 i += blockLength; 17027 17028 if (markers.indexOf(imgData.charCodeAt(i + 1)) !== -1) { 17029 height = imgData.charCodeAt(i + 5) * 256 + imgData.charCodeAt(i + 6); 17030 width = imgData.charCodeAt(i + 7) * 256 + imgData.charCodeAt(i + 8); 17031 numcomponents = imgData.charCodeAt(i + 9); 17032 result = { 17033 width: width, 17034 height: height, 17035 numcomponents: numcomponents 17036 }; 17037 break; 17038 } else { 17039 blockLength = imgData.charCodeAt(i + 2) * 256 + imgData.charCodeAt(i + 3); 17040 } 17041 } 17042 17043 return result; 17044 }; 17045 /** 17046 * @ignore 17047 */ 17048 17049 17050 jsPDFAPI.processJPEG = function (data, index, alias, compression, dataAsBinaryString, colorSpace) { 17051 var filter = this.decode.DCT_DECODE, 17052 bpc = 8, 17053 dims, 17054 result = null; 17055 17056 if (typeof data === "string" || this.__addimage__.isArrayBuffer(data) || this.__addimage__.isArrayBufferView(data)) { 17057 // if we already have a stored binary string rep use that 17058 data = dataAsBinaryString || data; 17059 data = this.__addimage__.isArrayBuffer(data) ? new Uint8Array(data) : data; 17060 data = this.__addimage__.isArrayBufferView(data) ? this.__addimage__.arrayBufferToBinaryString(data) : data; 17061 dims = getJpegInfo(data); 17062 17063 switch (dims.numcomponents) { 17064 case 1: 17065 colorSpace = this.color_spaces.DEVICE_GRAY; 17066 break; 17067 17068 case 4: 17069 colorSpace = this.color_spaces.DEVICE_CMYK; 17070 break; 17071 17072 case 3: 17073 colorSpace = this.color_spaces.DEVICE_RGB; 17074 break; 17075 } 17076 17077 result = { 17078 data: data, 17079 width: dims.width, 17080 height: dims.height, 17081 colorSpace: colorSpace, 17082 bitsPerComponent: bpc, 17083 filter: filter, 17084 index: index, 17085 alias: alias 17086 }; 17087 } 17088 17089 return result; 17090 }; 17091 })(jsPDF.API); 17092 17093 // Generated by CoffeeScript 1.4.0 17094 17095 var PNG = function () { 17096 var APNG_BLEND_OP_SOURCE, APNG_DISPOSE_OP_BACKGROUND, APNG_DISPOSE_OP_PREVIOUS, makeImage, scratchCanvas, scratchCtx; 17097 APNG_DISPOSE_OP_BACKGROUND = 1; 17098 APNG_DISPOSE_OP_PREVIOUS = 2; 17099 APNG_BLEND_OP_SOURCE = 0; 17100 17101 function PNG(data) { 17102 var chunkSize, colors, palLen, delayDen, delayNum, frame, i, index, key, section, palShort, text, _i, _j, _ref; 17103 17104 this.data = data; 17105 this.pos = 8; 17106 this.palette = []; 17107 this.imgData = []; 17108 this.transparency = {}; 17109 this.animation = null; 17110 this.text = {}; 17111 frame = null; 17112 17113 while (true) { 17114 chunkSize = this.readUInt32(); 17115 17116 section = function () { 17117 var _i, _results; 17118 17119 _results = []; 17120 17121 for (i = _i = 0; _i < 4; i = ++_i) { 17122 _results.push(String.fromCharCode(this.data[this.pos++])); 17123 } 17124 17125 return _results; 17126 }.call(this).join(""); 17127 17128 switch (section) { 17129 case "IHDR": 17130 this.width = this.readUInt32(); 17131 this.height = this.readUInt32(); 17132 this.bits = this.data[this.pos++]; 17133 this.colorType = this.data[this.pos++]; 17134 this.compressionMethod = this.data[this.pos++]; 17135 this.filterMethod = this.data[this.pos++]; 17136 this.interlaceMethod = this.data[this.pos++]; 17137 break; 17138 17139 case "acTL": 17140 this.animation = { 17141 numFrames: this.readUInt32(), 17142 numPlays: this.readUInt32() || Infinity, 17143 frames: [] 17144 }; 17145 break; 17146 17147 case "PLTE": 17148 this.palette = this.read(chunkSize); 17149 break; 17150 17151 case "fcTL": 17152 if (frame) { 17153 this.animation.frames.push(frame); 17154 } 17155 17156 this.pos += 4; 17157 frame = { 17158 width: this.readUInt32(), 17159 height: this.readUInt32(), 17160 xOffset: this.readUInt32(), 17161 yOffset: this.readUInt32() 17162 }; 17163 delayNum = this.readUInt16(); 17164 delayDen = this.readUInt16() || 100; 17165 frame.delay = 1000 * delayNum / delayDen; 17166 frame.disposeOp = this.data[this.pos++]; 17167 frame.blendOp = this.data[this.pos++]; 17168 frame.data = []; 17169 break; 17170 17171 case "IDAT": 17172 case "fdAT": 17173 if (section === "fdAT") { 17174 this.pos += 4; 17175 chunkSize -= 4; 17176 } 17177 17178 data = (frame != null ? frame.data : void 0) || this.imgData; 17179 17180 for (i = _i = 0; 0 <= chunkSize ? _i < chunkSize : _i > chunkSize; i = 0 <= chunkSize ? ++_i : --_i) { 17181 data.push(this.data[this.pos++]); 17182 } 17183 17184 break; 17185 17186 case "tRNS": 17187 this.transparency = {}; 17188 17189 switch (this.colorType) { 17190 case 3: 17191 palLen = this.palette.length / 3; 17192 this.transparency.indexed = this.read(chunkSize); 17193 if (this.transparency.indexed.length > palLen) throw new Error("More transparent colors than palette size"); 17194 /* 17195 * According to the PNG spec trns should be increased to the same size as palette if shorter 17196 */ 17197 //palShort = 255 - this.transparency.indexed.length; 17198 17199 palShort = palLen - this.transparency.indexed.length; 17200 17201 if (palShort > 0) { 17202 for (i = _j = 0; 0 <= palShort ? _j < palShort : _j > palShort; i = 0 <= palShort ? ++_j : --_j) { 17203 this.transparency.indexed.push(255); 17204 } 17205 } 17206 17207 break; 17208 17209 case 0: 17210 this.transparency.grayscale = this.read(chunkSize)[0]; 17211 break; 17212 17213 case 2: 17214 this.transparency.rgb = this.read(chunkSize); 17215 } 17216 17217 break; 17218 17219 case "tEXt": 17220 text = this.read(chunkSize); 17221 index = text.indexOf(0); 17222 key = String.fromCharCode.apply(String, text.slice(0, index)); 17223 this.text[key] = String.fromCharCode.apply(String, text.slice(index + 1)); 17224 break; 17225 17226 case "IEND": 17227 if (frame) { 17228 this.animation.frames.push(frame); 17229 } 17230 17231 this.colors = function () { 17232 switch (this.colorType) { 17233 case 0: 17234 case 3: 17235 case 4: 17236 return 1; 17237 17238 case 2: 17239 case 6: 17240 return 3; 17241 } 17242 }.call(this); 17243 17244 this.hasAlphaChannel = (_ref = this.colorType) === 4 || _ref === 6; 17245 colors = this.colors + (this.hasAlphaChannel ? 1 : 0); 17246 this.pixelBitlength = this.bits * colors; 17247 17248 this.colorSpace = function () { 17249 switch (this.colors) { 17250 case 1: 17251 return "DeviceGray"; 17252 17253 case 3: 17254 return "DeviceRGB"; 17255 } 17256 }.call(this); 17257 17258 this.imgData = new Uint8Array(this.imgData); 17259 return; 17260 17261 default: 17262 this.pos += chunkSize; 17263 } 17264 17265 this.pos += 4; 17266 17267 if (this.pos > this.data.length) { 17268 throw new Error("Incomplete or corrupt PNG file"); 17269 } 17270 } 17271 } 17272 17273 PNG.prototype.read = function (bytes) { 17274 var i, _i, _results; 17275 17276 _results = []; 17277 17278 for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) { 17279 _results.push(this.data[this.pos++]); 17280 } 17281 17282 return _results; 17283 }; 17284 17285 PNG.prototype.readUInt32 = function () { 17286 var b1, b2, b3, b4; 17287 b1 = this.data[this.pos++] << 24; 17288 b2 = this.data[this.pos++] << 16; 17289 b3 = this.data[this.pos++] << 8; 17290 b4 = this.data[this.pos++]; 17291 return b1 | b2 | b3 | b4; 17292 }; 17293
17294 PNG.prototype.readUInt16 = function () { 17295 var b1, b2; 17296 b1 = this.data[this.pos++] << 8; 17297 b2 = this.data[this.pos++]; 17298 return b1 | b2; 17299 }; 17300 17301 PNG.prototype.decodePixels = function (data) { 17302 var pixelBytes = this.pixelBitlength / 8; 17303 var fullPixels = new Uint8Array(this.width * this.height * pixelBytes); 17304 var pos = 0; 17305 17306 var _this = this; 17307 17308 if (data == null) { 17309 data = this.imgData; 17310 } 17311 17312 if (data.length === 0) { 17313 return new Uint8Array(0); 17314 } 17315 17316 data = unzlibSync(data); 17317 17318 function pass(x0, y0, dx, dy) { 17319 var abyte, c, col, i, left, length, p, pa, paeth, pb, pc, pixels, row, scanlineLength, upper, upperLeft, _i, _j, _k, _l, _m; 17320 17321 var w = Math.ceil((_this.width - x0) / dx), 17322 h = Math.ceil((_this.height - y0) / dy); 17323 var isFull = _this.width == w && _this.height == h; 17324 scanlineLength = pixelBytes * w; 17325 pixels = isFull ? fullPixels : new Uint8Array(scanlineLength * h); 17326 length = data.length; 17327 row = 0; 17328 c = 0; 17329 17330 while (row < h && pos < length) { 17331 switch (data[pos++]) { 17332 case 0: 17333 for (i = _i = 0; _i < scanlineLength; i = _i += 1) { 17334 pixels[c++] = data[pos++]; 17335 } 17336 17337 break; 17338 17339 case 1: 17340 for (i = _j = 0; _j < scanlineLength; i = _j += 1) { 17341 abyte = data[pos++]; 17342 left = i < pixelBytes ? 0 : pixels[c - pixelBytes]; 17343 pixels[c++] = (abyte + left) % 256; 17344 } 17345 17346 break; 17347 17348 case 2: 17349 for (i = _k = 0; _k < scanlineLength; i = _k += 1) { 17350 abyte = data[pos++]; 17351 col = (i - i % pixelBytes) / pixelBytes; 17352 upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + i % pixelBytes]; 17353 pixels[c++] = (upper + abyte) % 256; 17354 } 17355 17356 break; 17357 17358 case 3: 17359 for (i = _l = 0; _l < scanlineLength; i = _l += 1) { 17360 abyte = data[pos++]; 17361 col = (i - i % pixelBytes) / pixelBytes; 17362 left = i < pixelBytes ? 0 : pixels[c - pixelBytes]; 17363 upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + i % pixelBytes]; 17364 pixels[c++] = (abyte + Math.floor((left + upper) / 2)) % 256; 17365 } 17366 17367 break; 17368 17369 case 4: 17370 for (i = _m = 0; _m < scanlineLength; i = _m += 1) { 17371 abyte = data[pos++]; 17372 col = (i - i % pixelBytes) / pixelBytes; 17373 left = i < pixelBytes ? 0 : pixels[c - pixelBytes]; 17374 17375 if (row === 0) { 17376 upper = upperLeft = 0; 17377 } else { 17378 upper = pixels[(row - 1) * scanlineLength + col * pixelBytes + i % pixelBytes]; 17379 upperLeft = col && pixels[(row - 1) * scanlineLength + (col - 1) * pixelBytes + i % pixelBytes]; 17380 } 17381 17382 p = left + upper - upperLeft; 17383 pa = Math.abs(p - left); 17384 pb = Math.abs(p - upper); 17385 pc = Math.abs(p - upperLeft); 17386 17387 if (pa <= pb && pa <= pc) { 17388 paeth = left; 17389 } else if (pb <= pc) { 17390 paeth = upper; 17391 } else { 17392 paeth = upperLeft; 17393 } 17394 17395 pixels[c++] = (abyte + paeth) % 256; 17396 } 17397 17398 break; 17399 17400 default: 17401 throw new Error("Invalid filter algorithm: " + data[pos - 1]); 17402 } 17403 17404 if (!isFull) { 17405 var fullPos = ((y0 + row * dy) * _this.width + x0) * pixelBytes; 17406 var partPos = row * scanlineLength; 17407 17408 for (i = 0; i < w; i += 1) { 17409 for (var j = 0; j < pixelBytes; j += 1) { 17410 fullPixels[fullPos++] = pixels[partPos++]; 17411 } 17412 17413 fullPos += (dx - 1) * pixelBytes; 17414 } 17415 } 17416 17417 row++; 17418 } 17419 } 17420 17421 if (_this.interlaceMethod == 1) { 17422 /* 17423 1 6 4 6 2 6 4 6 17424 7 7 7 7 7 7 7 7 17425 5 6 5 6 5 6 5 6 17426 7 7 7 7 7 7 7 7 17427 3 6 4 6 3 6 4 6 17428 7 7 7 7 7 7 7 7 17429 5 6 5 6 5 6 5 6 17430 7 7 7 7 7 7 7 7 17431 */ 17432 pass(0, 0, 8, 8); // 1 17433 17434 /* NOTE these seem to follow the pattern: 17435 * pass(x, 0, 2*x, 2*x); 17436 * pass(0, x, x, 2*x); 17437 * with x being 4, 2, 1. 17438 */ 17439 17440 pass(4, 0, 8, 8); // 2 17441 17442 pass(0, 4, 4, 8); // 3 17443 17444 pass(2, 0, 4, 4); // 4 17445 17446 pass(0, 2, 2, 4); // 5 17447 17448 pass(1, 0, 2, 2); // 6 17449 17450 pass(0, 1, 1, 2); // 7 17451 } else { 17452 pass(0, 0, 1, 1); 17453 } 17454 17455 return fullPixels; 17456 }; 17457 17458 PNG.prototype.decodePalette = function () { 17459 var c, i, length, palette, pos, ret, transparency, _i, _ref, _ref1; 17460 17461 palette = this.palette; 17462 transparency = this.transparency.indexed || []; 17463 ret = new Uint8Array((transparency.length || 0) + palette.length); 17464 pos = 0; 17465 length = palette.length; 17466 c = 0; 17467 17468 for (i = _i = 0, _ref = length; _i < _ref; i = _i += 3) { 17469 ret[pos++] = palette[i]; 17470 ret[pos++] = palette[i + 1]; 17471 ret[pos++] = palette[i + 2]; 17472 ret[pos++] = (_ref1 = transparency[c++]) != null ? _ref1 : 255; 17473 } 17474 17475 return ret; 17476 }; 17477 17478 PNG.prototype.copyToImageData = function (imageData, pixels) { 17479 var alpha, colors, data, i, input, j, k, length, palette, v, _ref; 17480 17481 colors = this.colors; 17482 palette = null; 17483 alpha = this.hasAlphaChannel; 17484 17485 if (this.palette.length) { 17486 palette = (_ref = this._decodedPalette) != null ? _ref : this._decodedPalette = this.decodePalette(); 17487 colors = 4; 17488 alpha = true; 17489 } 17490 17491 data = imageData.data || imageData; 17492 length = data.length; 17493 input = palette || pixels; 17494 i = j = 0; 17495 17496 if (colors === 1) { 17497 while (i < length) { 17498 k = palette ? pixels[i / 4] * 4 : j; 17499 v = input[k++]; 17500 data[i++] = v; 17501 data[i++] = v; 17502 data[i++] = v; 17503 data[i++] = alpha ? input[k++] : 255; 17504 j = k; 17505 } 17506 } else { 17507 while (i < length) { 17508 k = palette ? pixels[i / 4] * 4 : j; 17509 data[i++] = input[k++]; 17510 data[i++] = input[k++]; 17511 data[i++] = input[k++]; 17512 data[i++] = alpha ? input[k++] : 255; 17513 j = k; 17514 } 17515 } 17516 }; 17517 17518 PNG.prototype.decode = function () { 17519 var ret; 17520 ret = new Uint8Array(this.width * this.height * 4); 17521 this.copyToImageData(ret, this.decodePixels()); 17522 return ret; 17523 }; 17524 17525 var hasBrowserCanvas = function hasBrowserCanvas() { 17526 if (Object.prototype.toString.call(globalObject) === "[object Window]") { 17527 try { 17528 scratchCanvas = globalObject.document.createElement("canvas"); 17529 scratchCtx = scratchCanvas.getContext("2d"); 17530 } catch (e) { 17531 return false;
17532 } 17533 17534 return true; 17535 } 17536 17537 return false; 17538 }; 17539 17540 hasBrowserCanvas(); 17541 17542 makeImage = function makeImage(imageData) { 17543 if (hasBrowserCanvas() === true) { 17544 var img; 17545 scratchCtx.width = imageData.width; 17546 scratchCtx.height = imageData.height; 17547 scratchCtx.clearRect(0, 0, imageData.width, imageData.height); 17548 scratchCtx.putImageData(imageData, 0, 0); 17549 img = new Image(); 17550 img.src = scratchCanvas.toDataURL(); 17551 return img; 17552 } 17553 17554 throw new Error("This method requires a Browser with Canvas-capability."); 17555 }; 17556 17557 PNG.prototype.decodeFrames = function (ctx) { 17558 var frame, i, imageData, pixels, _i, _len, _ref, _results; 17559 17560 if (!this.animation) { 17561 return; 17562 } 17563 17564 _ref = this.animation.frames; 17565 _results = []; 17566 17567 for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { 17568 frame = _ref[i]; 17569 imageData = ctx.createImageData(frame.width, frame.height); 17570 pixels = this.decodePixels(new Uint8Array(frame.data)); 17571 this.copyToImageData(imageData, pixels); 17572 frame.imageData = imageData; 17573 17574 _results.push(frame.image = makeImage(imageData)); 17575 } 17576 17577 return _results; 17578 }; 17579 17580 PNG.prototype.renderFrame = function (ctx, number) { 17581 var frame, frames, prev; 17582 frames = this.animation.frames; 17583 frame = frames[number]; 17584 prev = frames[number - 1]; 17585 17586 if (number === 0) { 17587 ctx.clearRect(0, 0, this.width, this.height); 17588 } 17589 17590 if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_BACKGROUND) { 17591 ctx.clearRect(prev.xOffset, prev.yOffset, prev.width, prev.height); 17592 } else if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_PREVIOUS) { 17593 ctx.putImageData(prev.imageData, prev.xOffset, prev.yOffset); 17594 } 17595 17596 if (frame.blendOp === APNG_BLEND_OP_SOURCE) { 17597 ctx.clearRect(frame.xOffset, frame.yOffset, frame.width, frame.height); 17598 } 17599 17600 return ctx.drawImage(frame.image, frame.xOffset, frame.yOffset); 17601 }; 17602 17603 PNG.prototype.animate = function (ctx) { 17604 var _doFrame, 17605 frameNumber, 17606 frames, 17607 numFrames, 17608 numPlays, 17609 _ref, 17610 _this = this; 17611 17612 frameNumber = 0; 17613 _ref = this.animation, numFrames = _ref.numFrames, frames = _ref.frames, numPlays = _ref.numPlays; 17614 return (_doFrame = function doFrame() { 17615 var f, frame; 17616 f = frameNumber++ % numFrames; 17617 frame = frames[f]; 17618 17619 _this.renderFrame(ctx, f); 17620 17621 if (numFrames > 1 && frameNumber / numFrames < numPlays) { 17622 return _this.animation._timeout = setTimeout(_doFrame, frame.delay); 17623 } 17624 })(); 17625 }; 17626 17627 PNG.prototype.stopAnimation = function () { 17628 var _ref; 17629 17630 return clearTimeout((_ref = this.animation) != null ? _ref._timeout : void 0); 17631 }; 17632 17633 PNG.prototype.render = function (canvas) { 17634 var ctx, data; 17635 17636 if (canvas._png) { 17637 canvas._png.stopAnimation(); 17638 } 17639 17640 canvas._png = this; 17641 canvas.width = this.width; 17642 canvas.height = this.height; 17643 ctx = canvas.getContext("2d"); 17644 17645 if (this.animation) { 17646 this.decodeFrames(ctx); 17647 return this.animate(ctx); 17648 } else { 17649 data = ctx.createImageData(this.width, this.height); 17650 this.copyToImageData(data, this.decodePixels()); 17651 return ctx.putImageData(data, 0, 0); 17652 } 17653 }; 17654 17655 return PNG; 17656 }(); 17657 17658 /** 17659 * @license 17660 * 17661 * Copyright (c) 2014 James Robb, https://github.com/jamesbrobb 17662 * 17663 * Permission is hereby granted, free of charge, to any person obtaining 17664 * a copy of this software and associated documentation files (the 17665 * "Software"), to deal in the Software without restriction, including 17666 * without limitation the rights to use, copy, modify, merge, publish, 17667 * distribute, sublicense, and/or sell copies of the Software, and to 17668 * permit persons to whom the Software is furnished to do so, subject to 17669 * the following conditions: 17670 * 17671 * The above copyright notice and this permission notice shall be 17672 * included in all copies or substantial portions of the Software. 17673 * 17674 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17675 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17676 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17677 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 17678 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 17679 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 17680 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17681 * ==================================================================== 17682 */ 17683 /** 17684 * jsPDF PNG PlugIn 17685 * @name png_support 17686 * @module 17687 */ 17688 17689 (function (jsPDFAPI) { 17690 /* 17691 * @see http://www.w3.org/TR/PNG-Chunks.html 17692 * 17693 Color Allowed Interpretation 17694 Type Bit Depths
17695 0 1,2,4,8,16 Each pixel is a grayscale sample. 17696 2 8,16 Each pixel is an R,G,B triple. 17697 3 1,2,4,8 Each pixel is a palette index; 17698 a PLTE chunk must appear. 17699 4 8,16 Each pixel is a grayscale sample, 17700 followed by an alpha sample. 17701 6 8,16 Each pixel is an R,G,B triple, 17702 followed by an alpha sample. 17703 */ 17704 17705 /* 17706 * PNG filter method types 17707 * 17708 * @see http://www.w3.org/TR/PNG-Filters.html 17709 * @see http://www.libpng.org/pub/png/book/chapter09.html 17710 * 17711 * This is what the value 'Predictor' in decode params relates to 17712 * 17713 * 15 is "optimal prediction", which means the prediction algorithm can change from line to line. 17714 * In that case, you actually have to read the first byte off each line for the prediction algorthim (which should be 0-4, corresponding to PDF 10-14) and select the appropriate unprediction algorithm based on that byte. 17715 * 17716 0 None 17717 1 Sub 17718 2 Up 17719 3 Average 17720 4 Paeth 17721 */ 17722 17723 var canCompress = function canCompress(value) { 17724 return value !== jsPDFAPI.image_compression.NONE && hasCompressionJS(); 17725 }; 17726 17727 var hasCompressionJS = function hasCompressionJS() { 17728 return typeof zlibSync === "function"; 17729 }; 17730 17731 var compressBytes = function compressBytes(bytes, lineLength, colorsPerPixel, compression) { 17732 var level = 4; 17733 var filter_method = filterUp; 17734 17735 switch (compression) { 17736 case jsPDFAPI.image_compression.FAST: 17737 level = 1; 17738 filter_method = filterSub; 17739 break; 17740 17741 case jsPDFAPI.image_compression.MEDIUM: 17742 level = 6; 17743 filter_method = filterAverage; 17744 break; 17745 17746 case jsPDFAPI.image_compression.SLOW: 17747 level = 9; 17748 filter_method = filterPaeth; 17749 break; 17750 } 17751 17752 bytes = applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method); 17753 var dat = zlibSync(bytes, { 17754 level: level 17755 }); 17756 return jsPDFAPI.__addimage__.arrayBufferToBinaryString(dat); 17757 }; 17758 17759 var applyPngFilterMethod = function applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method) { 17760 var lines = bytes.length / lineLength, 17761 result = new Uint8Array(bytes.length + lines), 17762 filter_methods = getFilterMethods(), 17763 line, 17764 prevLine, 17765 offset; 17766 17767 for (var i = 0; i < lines; i += 1) { 17768 offset = i * lineLength; 17769 line = bytes.subarray(offset, offset + lineLength); 17770 17771 if (filter_method) { 17772 result.set(filter_method(line, colorsPerPixel, prevLine), offset + i); 17773 } else { 17774 var len = filter_methods.length, 17775 results = []; 17776 17777 for (var j; j < len; j += 1) { 17778 results[j] = filter_methods[j](line, colorsPerPixel, prevLine); 17779 } 17780 17781 var ind = getIndexOfSmallestSum(results.concat()); 17782 result.set(results[ind], offset + i); 17783 } 17784 17785 prevLine = line; 17786 } 17787 17788 return result; 17789 }; 17790 17791 var filterNone = function filterNone(line) { 17792 /*var result = new Uint8Array(line.length + 1); 17793 result[0] = 0; 17794 result.set(line, 1);*/ 17795 var result = Array.apply([], line); 17796 result.unshift(0); 17797 return result; 17798 }; 17799 17800 var filterSub = function filterSub(line, colorsPerPixel) { 17801 var result = [], 17802 len = line.length, 17803 left; 17804 result[0] = 1; 17805 17806 for (var i = 0; i < len; i += 1) { 17807 left = line[i - colorsPerPixel] || 0; 17808 result[i + 1] = line[i] - left + 0x0100 & 0xff;
17809 } 17810 17811 return result; 17812 }; 17813 17814 var filterUp = function filterUp(line, colorsPerPixel, prevLine) { 17815 var result = [], 17816 len = line.length, 17817 up; 17818 result[0] = 2; 17819 17820 for (var i = 0; i < len; i += 1) { 17821 up = prevLine && prevLine[i] || 0; 17822 result[i + 1] = line[i] - up + 0x0100 & 0xff; 17823 } 17824 17825 return result; 17826 }; 17827 17828 var filterAverage = function filterAverage(line, colorsPerPixel, prevLine) { 17829 var result = [], 17830 len = line.length, 17831 left, 17832 up; 17833 result[0] = 3; 17834 17835 for (var i = 0; i < len; i += 1) { 17836 left = line[i - colorsPerPixel] || 0; 17837 up = prevLine && prevLine[i] || 0; 17838 result[i + 1] = line[i] + 0x0100 - (left + up >>> 1) & 0xff; 17839 } 17840 17841 return result; 17842 }; 17843 17844 var filterPaeth = function filterPaeth(line, colorsPerPixel, prevLine) { 17845 var result = [], 17846 len = line.length, 17847 left, 17848 up, 17849 upLeft, 17850 paeth; 17851 result[0] = 4; 17852 17853 for (var i = 0; i < len; i += 1) { 17854 left = line[i - colorsPerPixel] || 0; 17855 up = prevLine && prevLine[i] || 0; 17856 upLeft = prevLine && prevLine[i - colorsPerPixel] || 0; 17857 paeth = paethPredictor(left, up, upLeft); 17858 result[i + 1] = line[i] - paeth + 0x0100 & 0xff;
17859 } 17860 17861 return result; 17862 }; 17863 17864 var paethPredictor = function paethPredictor(left, up, upLeft) { 17865 if (left === up && up === upLeft) { 17866 return left; 17867 } 17868 17869 var pLeft = Math.abs(up - upLeft), 17870 pUp = Math.abs(left - upLeft), 17871 pUpLeft = Math.abs(left + up - upLeft - upLeft); 17872 return pLeft <= pUp && pLeft <= pUpLeft ? left : pUp <= pUpLeft ? up : upLeft; 17873 }; 17874 17875 var getFilterMethods = function getFilterMethods() { 17876 return [filterNone, filterSub, filterUp, filterAverage, filterPaeth]; 17877 }; 17878 17879 var getIndexOfSmallestSum = function getIndexOfSmallestSum(arrays) { 17880 var sum = arrays.map(function (value) { 17881 return value.reduce(function (pv, cv) { 17882 return pv + Math.abs(cv); 17883 }, 0); 17884 }); 17885 return sum.indexOf(Math.min.apply(null, sum)); 17886 }; 17887 17888 var getPredictorFromCompression = function getPredictorFromCompression(compression) { 17889 var predictor; 17890 17891 switch (compression) { 17892 case jsPDFAPI.image_compression.FAST: 17893 predictor = 11; 17894 break; 17895 17896 case jsPDFAPI.image_compression.MEDIUM: 17897 predictor = 13; 17898 break; 17899 17900 case jsPDFAPI.image_compression.SLOW: 17901 predictor = 14; 17902 break; 17903 17904 default: 17905 predictor = 12; 17906 break; 17907 } 17908 17909 return predictor; 17910 }; 17911 /** 17912 * @name processPNG 17913 * @function 17914 * @ignore 17915 */ 17916 17917 17918 jsPDFAPI.processPNG = function (imageData, index, alias, compression) { 17919 17920 var colorSpace, 17921 filter = this.decode.FLATE_DECODE, 17922 bitsPerComponent, 17923 image, 17924 decodeParameters = "", 17925 trns, 17926 colors, 17927 pal, 17928 smask, 17929 pixels, 17930 len, 17931 alphaData, 17932 imgData, 17933 hasColors, 17934 pixel, 17935 i, 17936 n; 17937 if (this.__addimage__.isArrayBuffer(imageData)) imageData = new Uint8Array(imageData); 17938 17939 if (this.__addimage__.isArrayBufferView(imageData)) { 17940 image = new PNG(imageData); 17941 imageData = image.imgData; 17942 bitsPerComponent = image.bits; 17943 colorSpace = image.colorSpace; 17944 colors = image.colors; 17945 /* 17946 * colorType 6 - Each pixel is an R,G,B triple, followed by an alpha sample. 17947 * 17948 * colorType 4 - Each pixel is a grayscale sample, followed by an alpha sample. 17949 * 17950 * Extract alpha to create two separate images, using the alpha as a sMask 17951 */ 17952 17953 if ([4, 6].indexOf(image.colorType) !== -1) { 17954 /* 17955 * processes 8 bit RGBA and grayscale + alpha images 17956 */ 17957 if (image.bits === 8) { 17958 pixels = image.pixelBitlength == 32 ? new Uint32Array(image.decodePixels().buffer) : image.pixelBitlength == 16 ? new Uint16Array(image.decodePixels().buffer) : new Uint8Array(image.decodePixels().buffer); 17959 len = pixels.length; 17960 imgData = new Uint8Array(len * image.colors); 17961 alphaData = new Uint8Array(len); 17962 var pDiff = image.pixelBitlength - image.bits; 17963 i = 0; 17964 n = 0; 17965 var pbl; 17966 17967 for (; i < len; i++) { 17968 pixel = pixels[i]; 17969 pbl = 0; 17970 17971 while (pbl < pDiff) { 17972 imgData[n++] = pixel >>> pbl & 0xff; 17973 pbl = pbl + image.bits; 17974 } 17975 17976 alphaData[i] = pixel >>> pbl & 0xff; 17977 } 17978 } 17979 /* 17980 * processes 16 bit RGBA and grayscale + alpha images 17981 */ 17982 17983 17984 if (image.bits === 16) { 17985 pixels = new Uint32Array(image.decodePixels().buffer); 17986 len = pixels.length; 17987 imgData = new Uint8Array(len * (32 / image.pixelBitlength) * image.colors); 17988 alphaData = new Uint8Array(len * (32 / image.pixelBitlength)); 17989 hasColors = image.colors > 1; 17990 i = 0; 17991 n = 0; 17992 var a = 0; 17993 17994 while (i < len) { 17995 pixel = pixels[i++]; 17996 imgData[n++] = pixel >>> 0 & 0xff; 17997 17998 if (hasColors) { 17999 imgData[n++] = pixel >>> 16 & 0xff;
18000 pixel = pixels[i++]; 18001 imgData[n++] = pixel >>> 0 & 0xff; 18002 } 18003 18004 alphaData[a++] = pixel >>> 16 & 0xff; 18005 } 18006 18007 bitsPerComponent = 8; 18008 } 18009 18010 if (canCompress(compression)) { 18011 imageData = compressBytes(imgData, image.width * image.colors, image.colors, compression); 18012 smask = compressBytes(alphaData, image.width, 1, compression); 18013 } else { 18014 imageData = imgData; 18015 smask = alphaData; 18016 filter = undefined; 18017 } 18018 } 18019 /* 18020 * Indexed png. Each pixel is a palette index. 18021 */ 18022 18023 18024 if (image.colorType === 3) { 18025 colorSpace = this.color_spaces.INDEXED; 18026 pal = image.palette; 18027 18028 if (image.transparency.indexed) { 18029 var trans = image.transparency.indexed; 18030 var total = 0; 18031 i = 0; 18032 len = trans.length; 18033 18034 for (; i < len; ++i) { 18035 total += trans[i]; 18036 } 18037 18038 total = total / 255; 18039 /* 18040 * a single color is specified as 100% transparent (0), 18041 * so we set trns to use a /Mask with that index 18042 */ 18043 18044 if (total === len - 1 && trans.indexOf(0) !== -1) { 18045 trns = [trans.indexOf(0)]; 18046 /* 18047 * there's more than one colour within the palette that specifies 18048 * a transparency value less than 255, so we unroll the pixels to create an image sMask 18049 */ 18050 } else if (total !== len) { 18051 pixels = image.decodePixels(); 18052 alphaData = new Uint8Array(pixels.length); 18053 i = 0; 18054 len = pixels.length; 18055 18056 for (; i < len; i++) { 18057 alphaData[i] = trans[pixels[i]]; 18058 } 18059 18060 smask = compressBytes(alphaData, image.width, 1); 18061 } 18062 } 18063 } 18064 18065 var predictor = getPredictorFromCompression(compression); 18066 18067 if (filter === this.decode.FLATE_DECODE) { 18068 decodeParameters = "/Predictor " + predictor + " "; 18069 } 18070 18071 decodeParameters += "/Colors " + colors + " /BitsPerComponent " + bitsPerComponent + " /Columns " + image.width; 18072 18073 if (this.__addimage__.isArrayBuffer(imageData) || this.__addimage__.isArrayBufferView(imageData)) { 18074 imageData = this.__addimage__.arrayBufferToBinaryString(imageData); 18075 } 18076 18077 if (smask && this.__addimage__.isArrayBuffer(smask) || this.__addimage__.isArrayBufferView(smask)) { 18078 smask = this.__addimage__.arrayBufferToBinaryString(smask); 18079 } 18080 18081 return { 18082 alias: alias, 18083 data: imageData, 18084 index: index, 18085 filter: filter, 18086 decodeParameters: decodeParameters, 18087 transparency: trns, 18088 palette: pal, 18089 sMask: smask, 18090 predictor: predictor, 18091 width: image.width, 18092 height: image.height, 18093 bitsPerComponent: bitsPerComponent, 18094 colorSpace: colorSpace 18095 }; 18096 } 18097 }; 18098 })(jsPDF.API); 18099 18100 /** 18101 * @license 18102 * (c) Dean McNamee <[email protected]>, 2013. 18103 * 18104 * https://github.com/deanm/omggif 18105 * 18106 * Permission is hereby granted, free of charge, to any person obtaining a copy 18107 * of this software and associated documentation files (the "Software"), to 18108 * deal in the Software without restriction, including without limitation the 18109 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 18110 * sell copies of the Software, and to permit persons to whom the Software is 18111 * furnished to do so, subject to the following conditions: 18112 * 18113 * The above copyright notice and this permission notice shall be included in 18114 * all copies or substantial portions of the Software. 18115 * 18116 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18117 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18118 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18119 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18120 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18121 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18122 * IN THE SOFTWARE. 18123 * 18124 * omggif is a JavaScript implementation of a GIF 89a encoder and decoder, 18125 * including animation and compression. It does not rely on any specific 18126 * underlying system, so should run in the browser, Node, or Plask. 18127 */ 18128 18129 function GifReader(buf) { 18130 var p = 0; // - Header (GIF87a or GIF89a). 18131 18132 if (buf[p++] !== 0x47 || buf[p++] !== 0x49 || buf[p++] !== 0x46 || buf[p++] !== 0x38 || (buf[p++] + 1 & 0xfd) !== 0x38 || buf[p++] !== 0x61) { 18133 throw new Error("Invalid GIF 87a/89a header."); 18134 } // - Logical Screen Descriptor. 18135 18136 18137 var width = buf[p++] | buf[p++] << 8; 18138 var height = buf[p++] | buf[p++] << 8; 18139 var pf0 = buf[p++]; // <Packed Fields>. 18140 18141 var global_palette_flag = pf0 >> 7; 18142 var num_global_colors_pow2 = pf0 & 0x7; 18143 var num_global_colors = 1 << num_global_colors_pow2 + 1; 18144 var background = buf[p++]; 18145 buf[p++]; // Pixel aspect ratio (unused?). 18146 18147 var global_palette_offset = null; 18148 var global_palette_size = null; 18149 18150 if (global_palette_flag) { 18151 global_palette_offset = p; 18152 global_palette_size = num_global_colors; 18153 p += num_global_colors * 3; // Seek past palette. 18154 } 18155 18156 var no_eof = true; 18157 var frames = [];
vendor: 18,334 bytes, lines 18158-18635
18158 var delay = 0; 18159 var transparent_index = null; 18160 var disposal = 0; // 0 - No disposal specified. 18161 18162 var loop_count = null; 18163 this.width = width; 18164 this.height = height; 18165 18166 while (no_eof && p < buf.length) { 18167 switch (buf[p++]) { 18168 case 0x21: 18169 // Graphics Control Extension Block 18170 switch (buf[p++]) { 18171 case 0xff: 18172 // Application specific block 18173 // Try if it's a Netscape block (with animation loop counter). 18174 if (buf[p] !== 0x0b || // 21 FF already read, check block size. 18175 // NETSCAPE2.0 18176 buf[p + 1] == 0x4e && buf[p + 2] == 0x45 && buf[p + 3] == 0x54 && buf[p + 4] == 0x53 && buf[p + 5] == 0x43 && buf[p + 6] == 0x41 && buf[p + 7] == 0x50 && buf[p + 8] == 0x45 && buf[p + 9] == 0x32 && buf[p + 10] == 0x2e && buf[p + 11] == 0x30 && // Sub-block 18177 buf[p + 12] == 0x03 && buf[p + 13] == 0x01 && buf[p + 16] == 0) { 18178 p += 14; 18179 loop_count = buf[p++] | buf[p++] << 8; 18180 p++; // Skip terminator. 18181 } else { 18182 // We don't know what it is, just try to get past it. 18183 p += 12; 18184 18185 while (true) { 18186 // Seek through subblocks. 18187 var block_size = buf[p++]; // Bad block size (ex: undefined from an out of bounds read). 18188 18189 if (!(block_size >= 0)) throw Error("Invalid block size"); 18190 if (block_size === 0) break; // 0 size is terminator 18191 18192 p += block_size; 18193 } 18194 } 18195 18196 break; 18197 18198 case 0xf9: 18199 // Graphics Control Extension 18200 if (buf[p++] !== 0x4 || buf[p + 4] !== 0) throw new Error("Invalid graphics extension block."); 18201 var pf1 = buf[p++]; 18202 delay = buf[p++] | buf[p++] << 8; 18203 transparent_index = buf[p++]; 18204 if ((pf1 & 1) === 0) transparent_index = null; 18205 disposal = pf1 >> 2 & 0x7; 18206 p++; // Skip terminator. 18207 18208 break; 18209 18210 case 0xfe: 18211 // Comment Extension. 18212 while (true) { 18213 // Seek through subblocks. 18214 var block_size = buf[p++]; // Bad block size (ex: undefined from an out of bounds read). 18215 18216 if (!(block_size >= 0)) throw Error("Invalid block size"); 18217 if (block_size === 0) break; // 0 size is terminator 18218 // console.log(buf.slice(p, p+block_size).toString('ascii')); 18219 18220 p += block_size; 18221 } 18222 18223 break; 18224 18225 default: 18226 throw new Error("Unknown graphic control label: 0x" + buf[p - 1].toString(16)); 18227 } 18228 18229 break; 18230 18231 case 0x2c: 18232 // Image Descriptor. 18233 var x = buf[p++] | buf[p++] << 8; 18234 var y = buf[p++] | buf[p++] << 8; 18235 var w = buf[p++] | buf[p++] << 8; 18236 var h = buf[p++] | buf[p++] << 8; 18237 var pf2 = buf[p++]; 18238 var local_palette_flag = pf2 >> 7; 18239 var interlace_flag = pf2 >> 6 & 1; 18240 var num_local_colors_pow2 = pf2 & 0x7; 18241 var num_local_colors = 1 << num_local_colors_pow2 + 1; 18242 var palette_offset = global_palette_offset; 18243 var palette_size = global_palette_size; 18244 var has_local_palette = false; 18245 18246 if (local_palette_flag) { 18247 var has_local_palette = true; 18248 palette_offset = p; // Override with local palette. 18249 18250 palette_size = num_local_colors; 18251 p += num_local_colors * 3; // Seek past palette. 18252 } 18253 18254 var data_offset = p; 18255 p++; // codesize 18256 18257 while (true) { 18258 var block_size = buf[p++]; // Bad block size (ex: undefined from an out of bounds read). 18259 18260 if (!(block_size >= 0)) throw Error("Invalid block size"); 18261 if (block_size === 0) break; // 0 size is terminator 18262 18263 p += block_size; 18264 } 18265 18266 frames.push({ 18267 x: x, 18268 y: y, 18269 width: w, 18270 height: h, 18271 has_local_palette: has_local_palette, 18272 palette_offset: palette_offset, 18273 palette_size: palette_size, 18274 data_offset: data_offset, 18275 data_length: p - data_offset, 18276 transparent_index: transparent_index, 18277 interlaced: !!interlace_flag, 18278 delay: delay, 18279 disposal: disposal 18280 }); 18281 break; 18282 18283 case 0x3b: 18284 // Trailer Marker (end of file). 18285 no_eof = false; 18286 break; 18287 18288 default: 18289 throw new Error("Unknown gif block: 0x" + buf[p - 1].toString(16)); 18290 } 18291 } 18292 18293 this.numFrames = function () { 18294 return frames.length; 18295 }; 18296 18297 this.loopCount = function () { 18298 return loop_count; 18299 }; 18300 18301 this.frameInfo = function (frame_num) { 18302 if (frame_num < 0 || frame_num >= frames.length) throw new Error("Frame index out of range."); 18303 return frames[frame_num]; 18304 }; 18305 18306 this.decodeAndBlitFrameBGRA = function (frame_num, pixels) { 18307 var frame = this.frameInfo(frame_num); 18308 var num_pixels = frame.width * frame.height; 18309 var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices. 18310 18311 GifReaderLZWOutputIndexStream(buf, frame.data_offset, index_stream, num_pixels); 18312 var palette_offset = frame.palette_offset; // NOTE(deanm): It seems to be much faster to compare index to 256 than 18313 // to === null. Not sure why, but CompareStub_EQ_STRICT shows up high in 18314 // the profile, not sure if it's related to using a Uint8Array. 18315 18316 var trans = frame.transparent_index; 18317 if (trans === null) trans = 256; // We are possibly just blitting to a portion of the entire frame. 18318 // That is a subrect within the framerect, so the additional pixels 18319 // must be skipped over after we finished a scanline. 18320 18321 var framewidth = frame.width; 18322 var framestride = width - framewidth; 18323 var xleft = framewidth; // Number of subrect pixels left in scanline. 18324 // Output indices of the top left and bottom right corners of the subrect. 18325 18326 var opbeg = (frame.y * width + frame.x) * 4; 18327 var opend = ((frame.y + frame.height) * width + frame.x) * 4; 18328 var op = opbeg; 18329 var scanstride = framestride * 4; // Use scanstride to skip past the rows when interlacing. This is skipping 18330 // 7 rows for the first two passes, then 3 then 1. 18331 18332 if (frame.interlaced === true) { 18333 scanstride += width * 4 * 7; // Pass 1. 18334 } 18335 18336 var interlaceskip = 8; // Tracking the row interval in the current pass. 18337 18338 for (var i = 0, il = index_stream.length; i < il; ++i) { 18339 var index = index_stream[i]; 18340 18341 if (xleft === 0) { 18342 // Beginning of new scan line 18343 op += scanstride; 18344 xleft = framewidth; 18345 18346 if (op >= opend) { 18347 // Catch the wrap to switch passes when interlacing. 18348 scanstride = framestride * 4 + width * 4 * (interlaceskip - 1); // interlaceskip / 2 * 4 is interlaceskip << 1. 18349 18350 op = opbeg + (framewidth + framestride) * (interlaceskip << 1); 18351 interlaceskip >>= 1; 18352 } 18353 } 18354 18355 if (index === trans) { 18356 op += 4; 18357 } else { 18358 var r = buf[palette_offset + index * 3]; 18359 var g = buf[palette_offset + index * 3 + 1]; 18360 var b = buf[palette_offset + index * 3 + 2]; 18361 pixels[op++] = b; 18362 pixels[op++] = g; 18363 pixels[op++] = r; 18364 pixels[op++] = 255; 18365 } 18366 18367 --xleft; 18368 } 18369 }; // I will go to copy and paste hell one day... 18370 18371 18372 this.decodeAndBlitFrameRGBA = function (frame_num, pixels) { 18373 var frame = this.frameInfo(frame_num); 18374 var num_pixels = frame.width * frame.height; 18375 var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices. 18376 18377 GifReaderLZWOutputIndexStream(buf, frame.data_offset, index_stream, num_pixels); 18378 var palette_offset = frame.palette_offset; // NOTE(deanm): It seems to be much faster to compare index to 256 than 18379 // to === null. Not sure why, but CompareStub_EQ_STRICT shows up high in 18380 // the profile, not sure if it's related to using a Uint8Array. 18381 18382 var trans = frame.transparent_index; 18383 if (trans === null) trans = 256; // We are possibly just blitting to a portion of the entire frame. 18384 // That is a subrect within the framerect, so the additional pixels 18385 // must be skipped over after we finished a scanline. 18386 18387 var framewidth = frame.width; 18388 var framestride = width - framewidth; 18389 var xleft = framewidth; // Number of subrect pixels left in scanline. 18390 // Output indices of the top left and bottom right corners of the subrect. 18391 18392 var opbeg = (frame.y * width + frame.x) * 4; 18393 var opend = ((frame.y + frame.height) * width + frame.x) * 4; 18394 var op = opbeg; 18395 var scanstride = framestride * 4; // Use scanstride to skip past the rows when interlacing. This is skipping 18396 // 7 rows for the first two passes, then 3 then 1. 18397 18398 if (frame.interlaced === true) { 18399 scanstride += width * 4 * 7; // Pass 1. 18400 } 18401 18402 var interlaceskip = 8; // Tracking the row interval in the current pass. 18403 18404 for (var i = 0, il = index_stream.length; i < il; ++i) { 18405 var index = index_stream[i]; 18406 18407 if (xleft === 0) { 18408 // Beginning of new scan line 18409 op += scanstride; 18410 xleft = framewidth; 18411 18412 if (op >= opend) { 18413 // Catch the wrap to switch passes when interlacing. 18414 scanstride = framestride * 4 + width * 4 * (interlaceskip - 1); // interlaceskip / 2 * 4 is interlaceskip << 1. 18415 18416 op = opbeg + (framewidth + framestride) * (interlaceskip << 1); 18417 interlaceskip >>= 1; 18418 } 18419 } 18420 18421 if (index === trans) { 18422 op += 4; 18423 } else { 18424 var r = buf[palette_offset + index * 3]; 18425 var g = buf[palette_offset + index * 3 + 1]; 18426 var b = buf[palette_offset + index * 3 + 2]; 18427 pixels[op++] = r; 18428 pixels[op++] = g; 18429 pixels[op++] = b; 18430 pixels[op++] = 255; 18431 } 18432 18433 --xleft; 18434 } 18435 }; 18436 } 18437 18438 function GifReaderLZWOutputIndexStream(code_stream, p, output, output_length) { 18439 var min_code_size = code_stream[p++]; 18440 var clear_code = 1 << min_code_size; 18441 var eoi_code = clear_code + 1; 18442 var next_code = eoi_code + 1; 18443 var cur_code_size = min_code_size + 1; // Number of bits per code. 18444 // NOTE: This shares the same name as the encoder, but has a different 18445 // meaning here. Here this masks each code coming from the code stream. 18446 18447 var code_mask = (1 << cur_code_size) - 1; 18448 var cur_shift = 0; 18449 var cur = 0; 18450 var op = 0; // Output pointer. 18451 18452 var subblock_size = code_stream[p++]; // TODO(deanm): Would using a TypedArray be any faster? At least it would 18453 // solve the fast mode / backing store uncertainty. 18454 // var code_table = Array(4096); 18455 18456 var code_table = new Int32Array(4096); // Can be signed, we only use 20 bits. 18457 18458 var prev_code = null; // Track code-1. 18459 18460 while (true) { 18461 // Read up to two bytes, making sure we always 12-bits for max sized code. 18462 while (cur_shift < 16) { 18463 if (subblock_size === 0) break; // No more data to be read. 18464 18465 cur |= code_stream[p++] << cur_shift; 18466 cur_shift += 8; 18467 18468 if (subblock_size === 1) { 18469 // Never let it get to 0 to hold logic above. 18470 subblock_size = code_stream[p++]; // Next subblock. 18471 } else { 18472 --subblock_size; 18473 } 18474 } // TODO(deanm): We should never really get here, we should have received 18475 // and EOI. 18476 18477 18478 if (cur_shift < cur_code_size) break; 18479 var code = cur & code_mask; 18480 cur >>= cur_code_size; 18481 cur_shift -= cur_code_size; // TODO(deanm): Maybe should check that the first code was a clear code, 18482 // at least this is what you're supposed to do. But actually our encoder 18483 // now doesn't emit a clear code first anyway. 18484 18485 if (code === clear_code) { 18486 // We don't actually have to clear the table. This could be a good idea 18487 // for greater error checking, but we don't really do any anyway. We 18488 // will just track it with next_code and overwrite old entries. 18489 next_code = eoi_code + 1; 18490 cur_code_size = min_code_size + 1; 18491 code_mask = (1 << cur_code_size) - 1; // Don't update prev_code ? 18492 18493 prev_code = null; 18494 continue; 18495 } else if (code === eoi_code) { 18496 break; 18497 } // We have a similar situation as the decoder, where we want to store 18498 // variable length entries (code table entries), but we want to do in a 18499 // faster manner than an array of arrays. The code below stores sort of a 18500 // linked list within the code table, and then "chases" through it to 18501 // construct the dictionary entries. When a new entry is created, just the 18502 // last byte is stored, and the rest (prefix) of the entry is only 18503 // referenced by its table entry. Then the code chases through the 18504 // prefixes until it reaches a single byte code. We have to chase twice, 18505 // first to compute the length, and then to actually copy the data to the 18506 // output (backwards, since we know the length). The alternative would be 18507 // storing something in an intermediate stack, but that doesn't make any 18508 // more sense. I implemented an approach where it also stored the length 18509 // in the code table, although it's a bit tricky because you run out of 18510 // bits (12 + 12 + 8), but I didn't measure much improvements (the table 18511 // entries are generally not the long). Even when I created benchmarks for 18512 // very long table entries the complexity did not seem worth it. 18513 // The code table stores the prefix entry in 12 bits and then the suffix 18514 // byte in 8 bits, so each entry is 20 bits. 18515 18516 18517 var chase_code = code < next_code ? code : prev_code; // Chase what we will output, either {CODE} or {CODE-1}. 18518 18519 var chase_length = 0; 18520 var chase = chase_code; 18521 18522 while (chase > clear_code) { 18523 chase = code_table[chase] >> 8; 18524 ++chase_length; 18525 } 18526 18527 var k = chase; 18528 var op_end = op + chase_length + (chase_code !== code ? 1 : 0); 18529 18530 if (op_end > output_length) { 18531 console.log("Warning, gif stream longer than expected."); 18532 return; 18533 } // Already have the first byte from the chase, might as well write it fast. 18534 18535 18536 output[op++] = k; 18537 op += chase_length; 18538 var b = op; // Track pointer, writing backwards. 18539 18540 if (chase_code !== code) // The case of emitting {CODE-1} + k. 18541 output[op++] = k; 18542 chase = chase_code; 18543 18544 while (chase_length--) { 18545 chase = code_table[chase]; 18546 output[--b] = chase & 0xff; // Write backwards. 18547 18548 chase >>= 8; // Pull down to the prefix code. 18549 } 18550 18551 if (prev_code !== null && next_code < 4096) { 18552 code_table[next_code++] = prev_code << 8 | k; // TODO(deanm): Figure out this clearing vs code growth logic better. I 18553 // have an feeling that it should just happen somewhere else, for now it 18554 // is awkward between when we grow past the max and then hit a clear code. 18555 // For now just check if we hit the max 12-bits (then a clear code should 18556 // follow, also of course encoded in 12-bits). 18557 18558 if (next_code >= code_mask + 1 && cur_code_size < 12) { 18559 ++cur_code_size; 18560 code_mask = code_mask << 1 | 1; 18561 } 18562 } 18563 18564 prev_code = code; 18565 } 18566 18567 if (op !== output_length) { 18568 console.log("Warning, gif stream shorter than expected."); 18569 } 18570 18571 return output; 18572 } 18573 18574 /** 18575 * @license 18576 Copyright (c) 2008, Adobe Systems Incorporated 18577 All rights reserved. 18578 18579 Redistribution and use in source and binary forms, with or without 18580 modification, are permitted provided that the following conditions are 18581 met: 18582 18583 * Redistributions of source code must retain the above copyright notice, 18584 this list of conditions and the following disclaimer. 18585 18586 * Redistributions in binary form must reproduce the above copyright 18587 notice, this list of conditions and the following disclaimer in the 18588 documentation and/or other materials provided with the distribution. 18589 18590 * Neither the name of Adobe Systems Incorporated nor the names of its 18591 contributors may be used to endorse or promote products derived from 18592 this software without specific prior written permission. 18593 18594 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 18595 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18596 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18597 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18598 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18599 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18600 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 18601 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 18602 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 18603 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 18604 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 18605 */ 18606 18607 /* 18608 JPEG encoder ported to JavaScript and optimized by Andreas Ritter, www.bytestrom.eu, 11/2009 18609 18610 Basic GUI blocking jpeg encoder 18611 */ 18612 function JPEGEncoder(quality) { 18613 var ffloor = Math.floor; 18614 var YTable = new Array(64); 18615 var UVTable = new Array(64); 18616 var fdtbl_Y = new Array(64); 18617 var fdtbl_UV = new Array(64); 18618 var YDC_HT; 18619 var UVDC_HT; 18620 var YAC_HT; 18621 var UVAC_HT; 18622 var bitcode = new Array(65535); 18623 var category = new Array(65535); 18624 var outputfDCTQuant = new Array(64); 18625 var DU = new Array(64); 18626 var byteout = []; 18627 var bytenew = 0; 18628 var bytepos = 7; 18629 var YDU = new Array(64); 18630 var UDU = new Array(64); 18631 var VDU = new Array(64); 18632 var clt = new Array(256); 18633 var RGB_YUV_TABLE = new Array(2048); 18634 var currentQuality; 18635 var ZigZag = [0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53,
1863510, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63]; 18636 var std_dc_luminance_nrcodes = [0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]; 18637 var std_dc_luminance_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; 18638 var std_ac_luminance_nrcodes = [0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d]; 18639 var std_ac_luminance_values = [0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa]; 18640 var std_dc_chrominance_nrcodes = [0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]; 18641 var std_dc_chrominance_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; 18642 var std_ac_chrominance_nrcodes = [0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77]; 18643 var std_ac_chrominance_values = [0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa]; 18644 18645 function initQuantTables(sf) { 18646 var YQT = [16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99]; 18647 18648 for (var i = 0; i < 64; i++) { 18649 var t = ffloor((YQT[i] * sf + 50) / 100); 18650 t = Math.min(Math.max(t, 1), 255); 18651 YTable[ZigZag[i]] = t; 18652 } 18653 18654 var UVQT = [17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99]; 18655 18656 for (var j = 0; j < 64; j++) {
vendor: 140,191 bytes, lines 18657-23709
18657 var u = ffloor((UVQT[j] * sf + 50) / 100); 18658 u = Math.min(Math.max(u, 1), 255); 18659 UVTable[ZigZag[j]] = u; 18660 } 18661 18662 var aasf = [1.0, 1.387039845, 1.306562965, 1.175875602, 1.0, 0.785694958, 0.5411961, 0.275899379]; 18663 var k = 0; 18664 18665 for (var row = 0; row < 8; row++) { 18666 for (var col = 0; col < 8; col++) { 18667 fdtbl_Y[k] = 1.0 / (YTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0); 18668 fdtbl_UV[k] = 1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0); 18669 k++; 18670 } 18671 } 18672 } 18673 18674 function computeHuffmanTbl(nrcodes, std_table) { 18675 var codevalue = 0; 18676 var pos_in_table = 0; 18677 var HT = new Array(); 18678 18679 for (var k = 1; k <= 16; k++) { 18680 for (var j = 1; j <= nrcodes[k]; j++) { 18681 HT[std_table[pos_in_table]] = []; 18682 HT[std_table[pos_in_table]][0] = codevalue; 18683 HT[std_table[pos_in_table]][1] = k; 18684 pos_in_table++; 18685 codevalue++; 18686 } 18687 18688 codevalue *= 2; 18689 } 18690 18691 return HT; 18692 } 18693 18694 function initHuffmanTbl() { 18695 YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes, std_dc_luminance_values); 18696 UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes, std_dc_chrominance_values); 18697 YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes, std_ac_luminance_values); 18698 UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes, std_ac_chrominance_values); 18699 } 18700 18701 function initCategoryNumber() { 18702 var nrlower = 1; 18703 var nrupper = 2; 18704 18705 for (var cat = 1; cat <= 15; cat++) { 18706 //Positive numbers 18707 for (var nr = nrlower; nr < nrupper; nr++) { 18708 category[32767 + nr] = cat; 18709 bitcode[32767 + nr] = []; 18710 bitcode[32767 + nr][1] = cat; 18711 bitcode[32767 + nr][0] = nr; 18712 } //Negative numbers 18713 18714 18715 for (var nrneg = -(nrupper - 1); nrneg <= -nrlower; nrneg++) { 18716 category[32767 + nrneg] = cat; 18717 bitcode[32767 + nrneg] = []; 18718 bitcode[32767 + nrneg][1] = cat; 18719 bitcode[32767 + nrneg][0] = nrupper - 1 + nrneg; 18720 } 18721 18722 nrlower <<= 1; 18723 nrupper <<= 1; 18724 } 18725 } 18726 18727 function initRGBYUVTable() { 18728 for (var i = 0; i < 256; i++) { 18729 RGB_YUV_TABLE[i] = 19595 * i; 18730 RGB_YUV_TABLE[i + 256 >> 0] = 38470 * i; 18731 RGB_YUV_TABLE[i + 512 >> 0] = 7471 * i + 0x8000; 18732 RGB_YUV_TABLE[i + 768 >> 0] = -11059 * i; 18733 RGB_YUV_TABLE[i + 1024 >> 0] = -21709 * i; 18734 RGB_YUV_TABLE[i + 1280 >> 0] = 32768 * i + 0x807fff; 18735 RGB_YUV_TABLE[i + 1536 >> 0] = -27439 * i; 18736 RGB_YUV_TABLE[i + 1792 >> 0] = -5329 * i; 18737 } 18738 } // IO functions 18739 18740 18741 function writeBits(bs) { 18742 var value = bs[0]; 18743 var posval = bs[1] - 1; 18744 18745 while (posval >= 0) { 18746 if (value & 1 << posval) { 18747 bytenew |= 1 << bytepos; 18748 } 18749 18750 posval--; 18751 bytepos--; 18752 18753 if (bytepos < 0) { 18754 if (bytenew == 0xff) { 18755 writeByte(0xff); 18756 writeByte(0); 18757 } else { 18758 writeByte(bytenew); 18759 } 18760 18761 bytepos = 7; 18762 bytenew = 0; 18763 } 18764 } 18765 } 18766 18767 function writeByte(value) { 18768 //byteout.push(clt[value]); // write char directly instead of converting later 18769 byteout.push(value); 18770 } 18771 18772 function writeWord(value) { 18773 writeByte(value >> 8 & 0xff); 18774 writeByte(value & 0xff); 18775 } // DCT & quantization core 18776 18777 18778 function fDCTQuant(data, fdtbl) { 18779 var d0, d1, d2, d3, d4, d5, d6, d7; 18780 /* Pass 1: process rows. */ 18781 18782 var dataOff = 0; 18783 var i; 18784 var I8 = 8; 18785 var I64 = 64; 18786 18787 for (i = 0; i < I8; ++i) { 18788 d0 = data[dataOff]; 18789 d1 = data[dataOff + 1]; 18790 d2 = data[dataOff + 2]; 18791 d3 = data[dataOff + 3]; 18792 d4 = data[dataOff + 4]; 18793 d5 = data[dataOff + 5]; 18794 d6 = data[dataOff + 6]; 18795 d7 = data[dataOff + 7]; 18796 var tmp0 = d0 + d7; 18797 var tmp7 = d0 - d7; 18798 var tmp1 = d1 + d6; 18799 var tmp6 = d1 - d6; 18800 var tmp2 = d2 + d5; 18801 var tmp5 = d2 - d5; 18802 var tmp3 = d3 + d4; 18803 var tmp4 = d3 - d4; 18804 /* Even part */ 18805 18806 var tmp10 = tmp0 + tmp3; 18807 /* phase 2 */ 18808 18809 var tmp13 = tmp0 - tmp3; 18810 var tmp11 = tmp1 + tmp2; 18811 var tmp12 = tmp1 - tmp2; 18812 data[dataOff] = tmp10 + tmp11; 18813 /* phase 3 */ 18814 18815 data[dataOff + 4] = tmp10 - tmp11; 18816 var z1 = (tmp12 + tmp13) * 0.707106781; 18817 /* c4 */ 18818 18819 data[dataOff + 2] = tmp13 + z1; 18820 /* phase 5 */ 18821 18822 data[dataOff + 6] = tmp13 - z1; 18823 /* Odd part */ 18824 18825 tmp10 = tmp4 + tmp5; 18826 /* phase 2 */ 18827 18828 tmp11 = tmp5 + tmp6; 18829 tmp12 = tmp6 + tmp7; 18830 /* The rotator is modified from fig 4-8 to avoid extra negations. */ 18831 18832 var z5 = (tmp10 - tmp12) * 0.382683433; 18833 /* c6 */ 18834 18835 var z2 = 0.5411961 * tmp10 + z5; 18836 /* c2-c6 */ 18837 18838 var z4 = 1.306562965 * tmp12 + z5; 18839 /* c2+c6 */ 18840 18841 var z3 = tmp11 * 0.707106781; 18842 /* c4 */ 18843 18844 var z11 = tmp7 + z3; 18845 /* phase 5 */ 18846 18847 var z13 = tmp7 - z3; 18848 data[dataOff + 5] = z13 + z2; 18849 /* phase 6 */ 18850 18851 data[dataOff + 3] = z13 - z2; 18852 data[dataOff + 1] = z11 + z4; 18853 data[dataOff + 7] = z11 - z4; 18854 dataOff += 8; 18855 /* advance pointer to next row */ 18856 } 18857 /* Pass 2: process columns. */ 18858 18859 18860 dataOff = 0; 18861 18862 for (i = 0; i < I8; ++i) { 18863 d0 = data[dataOff]; 18864 d1 = data[dataOff + 8]; 18865 d2 = data[dataOff + 16]; 18866 d3 = data[dataOff + 24]; 18867 d4 = data[dataOff + 32]; 18868 d5 = data[dataOff + 40]; 18869 d6 = data[dataOff + 48]; 18870 d7 = data[dataOff + 56]; 18871 var tmp0p2 = d0 + d7; 18872 var tmp7p2 = d0 - d7; 18873 var tmp1p2 = d1 + d6; 18874 var tmp6p2 = d1 - d6; 18875 var tmp2p2 = d2 + d5; 18876 var tmp5p2 = d2 - d5; 18877 var tmp3p2 = d3 + d4; 18878 var tmp4p2 = d3 - d4; 18879 /* Even part */ 18880 18881 var tmp10p2 = tmp0p2 + tmp3p2; 18882 /* phase 2 */ 18883 18884 var tmp13p2 = tmp0p2 - tmp3p2; 18885 var tmp11p2 = tmp1p2 + tmp2p2; 18886 var tmp12p2 = tmp1p2 - tmp2p2; 18887 data[dataOff] = tmp10p2 + tmp11p2; 18888 /* phase 3 */ 18889 18890 data[dataOff + 32] = tmp10p2 - tmp11p2; 18891 var z1p2 = (tmp12p2 + tmp13p2) * 0.707106781; 18892 /* c4 */ 18893 18894 data[dataOff + 16] = tmp13p2 + z1p2; 18895 /* phase 5 */ 18896 18897 data[dataOff + 48] = tmp13p2 - z1p2; 18898 /* Odd part */ 18899 18900 tmp10p2 = tmp4p2 + tmp5p2; 18901 /* phase 2 */ 18902 18903 tmp11p2 = tmp5p2 + tmp6p2; 18904 tmp12p2 = tmp6p2 + tmp7p2; 18905 /* The rotator is modified from fig 4-8 to avoid extra negations. */ 18906 18907 var z5p2 = (tmp10p2 - tmp12p2) * 0.382683433; 18908 /* c6 */ 18909 18910 var z2p2 = 0.5411961 * tmp10p2 + z5p2; 18911 /* c2-c6 */ 18912 18913 var z4p2 = 1.306562965 * tmp12p2 + z5p2; 18914 /* c2+c6 */ 18915 18916 var z3p2 = tmp11p2 * 0.707106781; 18917 /* c4 */ 18918 18919 var z11p2 = tmp7p2 + z3p2; 18920 /* phase 5 */ 18921 18922 var z13p2 = tmp7p2 - z3p2; 18923 data[dataOff + 40] = z13p2 + z2p2; 18924 /* phase 6 */ 18925 18926 data[dataOff + 24] = z13p2 - z2p2; 18927 data[dataOff + 8] = z11p2 + z4p2; 18928 data[dataOff + 56] = z11p2 - z4p2; 18929 dataOff++; 18930 /* advance pointer to next column */ 18931 } // Quantize/descale the coefficients 18932 18933 18934 var fDCTQuant; 18935 18936 for (i = 0; i < I64; ++i) { 18937 // Apply the quantization and scaling factor & Round to nearest integer 18938 fDCTQuant = data[i] * fdtbl[i]; 18939 outputfDCTQuant[i] = fDCTQuant > 0.0 ? fDCTQuant + 0.5 | 0 : fDCTQuant - 0.5 | 0; //outputfDCTQuant[i] = fround(fDCTQuant); 18940 } 18941 18942 return outputfDCTQuant; 18943 } 18944 18945 function writeAPP0() { 18946 writeWord(0xffe0); // marker 18947 18948 writeWord(16); // length 18949 18950 writeByte(0x4a); // J 18951 18952 writeByte(0x46); // F 18953 18954 writeByte(0x49); // I 18955 18956 writeByte(0x46); // F 18957 18958 writeByte(0); // = "JFIF",'\0' 18959 18960 writeByte(1); // versionhi 18961 18962 writeByte(1); // versionlo 18963 18964 writeByte(0); // xyunits 18965 18966 writeWord(1); // xdensity 18967 18968 writeWord(1); // ydensity 18969 18970 writeByte(0); // thumbnwidth 18971 18972 writeByte(0); // thumbnheight 18973 } 18974 18975 function writeSOF0(width, height) { 18976 writeWord(0xffc0); // marker 18977 18978 writeWord(17); // length, truecolor YUV JPG 18979 18980 writeByte(8); // precision 18981 18982 writeWord(height); 18983 writeWord(width); 18984 writeByte(3); // nrofcomponents 18985 18986 writeByte(1); // IdY 18987 18988 writeByte(0x11); // HVY 18989 18990 writeByte(0); // QTY 18991 18992 writeByte(2); // IdU 18993 18994 writeByte(0x11); // HVU 18995 18996 writeByte(1); // QTU 18997 18998 writeByte(3); // IdV 18999 19000 writeByte(0x11); // HVV 19001 19002 writeByte(1); // QTV 19003 } 19004 19005 function writeDQT() { 19006 writeWord(0xffdb); // marker 19007 19008 writeWord(132); // length 19009 19010 writeByte(0); 19011 19012 for (var i = 0; i < 64; i++) { 19013 writeByte(YTable[i]); 19014 } 19015 19016 writeByte(1); 19017 19018 for (var j = 0; j < 64; j++) { 19019 writeByte(UVTable[j]); 19020 } 19021 } 19022 19023 function writeDHT() { 19024 writeWord(0xffc4); // marker 19025 19026 writeWord(0x01a2); // length 19027 19028 writeByte(0); // HTYDCinfo 19029 19030 for (var i = 0; i < 16; i++) { 19031 writeByte(std_dc_luminance_nrcodes[i + 1]); 19032 } 19033 19034 for (var j = 0; j <= 11; j++) { 19035 writeByte(std_dc_luminance_values[j]); 19036 } 19037 19038 writeByte(0x10); // HTYACinfo 19039 19040 for (var k = 0; k < 16; k++) { 19041 writeByte(std_ac_luminance_nrcodes[k + 1]); 19042 } 19043 19044 for (var l = 0; l <= 161; l++) { 19045 writeByte(std_ac_luminance_values[l]); 19046 } 19047 19048 writeByte(1); // HTUDCinfo 19049 19050 for (var m = 0; m < 16; m++) { 19051 writeByte(std_dc_chrominance_nrcodes[m + 1]); 19052 } 19053 19054 for (var n = 0; n <= 11; n++) { 19055 writeByte(std_dc_chrominance_values[n]); 19056 } 19057 19058 writeByte(0x11); // HTUACinfo 19059 19060 for (var o = 0; o < 16; o++) { 19061 writeByte(std_ac_chrominance_nrcodes[o + 1]); 19062 } 19063 19064 for (var p = 0; p <= 161; p++) { 19065 writeByte(std_ac_chrominance_values[p]); 19066 } 19067 } 19068 19069 function writeSOS() { 19070 writeWord(0xffda); // marker 19071 19072 writeWord(12); // length 19073 19074 writeByte(3); // nrofcomponents 19075 19076 writeByte(1); // IdY 19077 19078 writeByte(0); // HTY 19079 19080 writeByte(2); // IdU 19081 19082 writeByte(0x11); // HTU 19083 19084 writeByte(3); // IdV 19085 19086 writeByte(0x11); // HTV 19087 19088 writeByte(0); // Ss 19089 19090 writeByte(0x3f); // Se 19091 19092 writeByte(0); // Bf 19093 } 19094 19095 function processDU(CDU, fdtbl, DC, HTDC, HTAC) { 19096 var EOB = HTAC[0x00]; 19097 var M16zeroes = HTAC[0xf0]; 19098 var pos; 19099 var I16 = 16; 19100 var I63 = 63; 19101 var I64 = 64; 19102 var DU_DCT = fDCTQuant(CDU, fdtbl); //ZigZag reorder 19103 19104 for (var j = 0; j < I64; ++j) { 19105 DU[ZigZag[j]] = DU_DCT[j]; 19106 } 19107 19108 var Diff = DU[0] - DC; 19109 DC = DU[0]; //Encode DC 19110 19111 if (Diff == 0) { 19112 writeBits(HTDC[0]); // Diff might be 0 19113 } else { 19114 pos = 32767 + Diff; 19115 writeBits(HTDC[category[pos]]); 19116 writeBits(bitcode[pos]); 19117 } //Encode ACs 19118 19119 19120 var end0pos = 63; // was const... which is crazy 19121 19122 while (end0pos > 0 && DU[end0pos] == 0) { 19123 end0pos--; 19124 } //end0pos = first element in reverse order !=0 19125 19126 19127 if (end0pos == 0) { 19128 writeBits(EOB); 19129 return DC; 19130 } 19131 19132 var i = 1; 19133 var lng; 19134 19135 while (i <= end0pos) { 19136 var startpos = i; 19137 19138 while (DU[i] == 0 && i <= end0pos) { 19139 ++i; 19140 } 19141 19142 var nrzeroes = i - startpos; 19143 19144 if (nrzeroes >= I16) { 19145 lng = nrzeroes >> 4; 19146 19147 for (var nrmarker = 1; nrmarker <= lng; ++nrmarker) { 19148 writeBits(M16zeroes); 19149 } 19150 19151 nrzeroes = nrzeroes & 0xf; 19152 } 19153 19154 pos = 32767 + DU[i]; 19155 writeBits(HTAC[(nrzeroes << 4) + category[pos]]); 19156 writeBits(bitcode[pos]); 19157 i++; 19158 } 19159 19160 if (end0pos != I63) { 19161 writeBits(EOB); 19162 } 19163 19164 return DC; 19165 } 19166 19167 function initCharLookupTable() { 19168 var sfcc = String.fromCharCode; 19169 19170 for (var i = 0; i < 256; i++) { 19171 ///// ACHTUNG // 255 19172 clt[i] = sfcc(i); 19173 } 19174 } 19175 19176 this.encode = function (image, quality // image data object 19177 ) { 19178 if (quality) setQuality(quality); // Initialize bit writer 19179 19180 byteout = new Array(); 19181 bytenew = 0; 19182 bytepos = 7; // Add JPEG headers 19183 19184 writeWord(0xffd8); // SOI 19185 19186 writeAPP0(); 19187 writeDQT(); 19188 writeSOF0(image.width, image.height); 19189 writeDHT(); 19190 writeSOS(); // Encode 8x8 macroblocks 19191 19192 var DCY = 0; 19193 var DCU = 0; 19194 var DCV = 0; 19195 bytenew = 0; 19196 bytepos = 7; 19197 this.encode.displayName = "_encode_"; 19198 var imageData = image.data; 19199 var width = image.width; 19200 var height = image.height; 19201 var quadWidth = width * 4; 19202 var x, 19203 y = 0; 19204 var r, g, b; 19205 var start, p, col, row, pos; 19206 19207 while (y < height) { 19208 x = 0; 19209 19210 while (x < quadWidth) { 19211 start = quadWidth * y + x; 19212 col = -1; 19213 row = 0; 19214 19215 for (pos = 0; pos < 64; pos++) { 19216 row = pos >> 3; // /8 19217 19218 col = (pos & 7) * 4; // %8 19219 19220 p = start + row * quadWidth + col; 19221 19222 if (y + row >= height) { 19223 // padding bottom 19224 p -= quadWidth * (y + 1 + row - height); 19225 } 19226 19227 if (x + col >= quadWidth) { 19228 // padding right 19229 p -= x + col - quadWidth + 4; 19230 } 19231 19232 r = imageData[p++]; 19233 g = imageData[p++]; 19234 b = imageData[p++]; 19235 /* // calculate YUV values dynamically 19236 YDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80 19237 UDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b)); 19238 VDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b)); 19239 */ 19240 // use lookup table (slightly faster) 19241 19242 YDU[pos] = (RGB_YUV_TABLE[r] + RGB_YUV_TABLE[g + 256 >> 0] + RGB_YUV_TABLE[b + 512 >> 0] >> 16) - 128; 19243 UDU[pos] = (RGB_YUV_TABLE[r + 768 >> 0] + RGB_YUV_TABLE[g + 1024 >> 0] + RGB_YUV_TABLE[b + 1280 >> 0] >> 16) - 128; 19244 VDU[pos] = (RGB_YUV_TABLE[r + 1280 >> 0] + RGB_YUV_TABLE[g + 1536 >> 0] + RGB_YUV_TABLE[b + 1792 >> 0] >> 16) - 128; 19245 } 19246 19247 DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT); 19248 DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); 19249 DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); 19250 x += 32; 19251 } 19252 19253 y += 8; 19254 } //////////////////////////////////////////////////////////////// 19255 // Do the bit alignment of the EOI marker 19256 19257 19258 if (bytepos >= 0) { 19259 var fillbits = []; 19260 fillbits[1] = bytepos + 1; 19261 fillbits[0] = (1 << bytepos + 1) - 1; 19262 writeBits(fillbits); 19263 } 19264 19265 writeWord(0xffd9); //EOI 19266 19267 return new Uint8Array(byteout); 19268 }; 19269 19270 function setQuality(quality) { 19271 quality = Math.min(Math.max(quality, 1), 100); 19272 if (currentQuality == quality) return; // don't recalc if unchanged 19273 19274 var sf = quality < 50 ? Math.floor(5000 / quality) : Math.floor(200 - quality * 2); 19275 initQuantTables(sf); 19276 currentQuality = quality; //console.log('Quality set to: '+quality +'%'); 19277 } 19278 19279 function init() { 19280 quality = quality || 50; // Create tables 19281 19282 initCharLookupTable(); 19283 initHuffmanTbl(); 19284 initCategoryNumber(); 19285 initRGBYUVTable(); 19286 setQuality(quality); 19287 } 19288 19289 init(); 19290 } 19291 19292 /** 19293 * @license 19294 * Copyright (c) 2017 Aras Abbasi 19295 * 19296 * Licensed under the MIT License. 19297 * http://opensource.org/licenses/mit-license 19298 */ 19299 /** 19300 * jsPDF Gif Support PlugIn 19301 * 19302 * @name gif_support 19303 * @module 19304 */ 19305 19306 (function (jsPDFAPI) { 19307 19308 jsPDFAPI.processGIF89A = function (imageData, index, alias, compression) { 19309 var reader = new GifReader(imageData); 19310 var width = reader.width, 19311 height = reader.height; 19312 var qu = 100; 19313 var pixels = []; 19314 reader.decodeAndBlitFrameRGBA(0, pixels); 19315 var rawImageData = { 19316 data: pixels, 19317 width: width, 19318 height: height 19319 }; 19320 var encoder = new JPEGEncoder(qu); 19321 var data = encoder.encode(rawImageData, qu); 19322 return jsPDFAPI.processJPEG.call(this, data, index, alias, compression); 19323 }; 19324 19325 jsPDFAPI.processGIF87A = jsPDFAPI.processGIF89A; 19326 })(jsPDF.API); 19327 19328 /** 19329 * @author shaozilee 19330 * 19331 * Bmp format decoder,support 1bit 4bit 8bit 24bit bmp 19332 * 19333 */ 19334 19335 function BmpDecoder(buffer, is_with_alpha) { 19336 this.pos = 0; 19337 this.buffer = buffer; 19338 this.datav = new DataView(buffer.buffer); 19339 this.is_with_alpha = !!is_with_alpha; 19340 this.bottom_up = true; 19341 this.flag = String.fromCharCode(this.buffer[0]) + String.fromCharCode(this.buffer[1]); 19342 this.pos += 2; 19343 if (["BM", "BA", "CI", "CP", "IC", "PT"].indexOf(this.flag) === -1) throw new Error("Invalid BMP File"); 19344 this.parseHeader(); 19345 this.parseBGR(); 19346 } 19347 19348 BmpDecoder.prototype.parseHeader = function () { 19349 this.fileSize = this.datav.getUint32(this.pos, true); 19350 this.pos += 4; 19351 this.reserved = this.datav.getUint32(this.pos, true); 19352 this.pos += 4; 19353 this.offset = this.datav.getUint32(this.pos, true); 19354 this.pos += 4; 19355 this.headerSize = this.datav.getUint32(this.pos, true); 19356 this.pos += 4; 19357 this.width = this.datav.getUint32(this.pos, true); 19358 this.pos += 4; 19359 this.height = this.datav.getInt32(this.pos, true); 19360 this.pos += 4; 19361 this.planes = this.datav.getUint16(this.pos, true); 19362 this.pos += 2; 19363 this.bitPP = this.datav.getUint16(this.pos, true); 19364 this.pos += 2; 19365 this.compress = this.datav.getUint32(this.pos, true); 19366 this.pos += 4; 19367 this.rawSize = this.datav.getUint32(this.pos, true); 19368 this.pos += 4; 19369 this.hr = this.datav.getUint32(this.pos, true); 19370 this.pos += 4; 19371 this.vr = this.datav.getUint32(this.pos, true); 19372 this.pos += 4; 19373 this.colors = this.datav.getUint32(this.pos, true); 19374 this.pos += 4; 19375 this.importantColors = this.datav.getUint32(this.pos, true); 19376 this.pos += 4; 19377 19378 if (this.bitPP === 16 && this.is_with_alpha) { 19379 this.bitPP = 15; 19380 } 19381 19382 if (this.bitPP < 15) { 19383 var len = this.colors === 0 ? 1 << this.bitPP : this.colors; 19384 this.palette = new Array(len); 19385 19386 for (var i = 0; i < len; i++) { 19387 var blue = this.datav.getUint8(this.pos++, true); 19388 var green = this.datav.getUint8(this.pos++, true); 19389 var red = this.datav.getUint8(this.pos++, true); 19390 var quad = this.datav.getUint8(this.pos++, true); 19391 this.palette[i] = { 19392 red: red, 19393 green: green, 19394 blue: blue, 19395 quad: quad 19396 }; 19397 } 19398 } 19399 19400 if (this.height < 0) { 19401 this.height *= -1; 19402 this.bottom_up = false; 19403 } 19404 }; 19405 19406 BmpDecoder.prototype.parseBGR = function () { 19407 this.pos = this.offset; 19408 19409 try { 19410 var bitn = "bit" + this.bitPP; 19411 var len = this.width * this.height * 4; 19412 this.data = new Uint8Array(len); 19413 this[bitn](); 19414 } catch (e) { 19415 console.log("bit decode error:" + e); 19416 } 19417 }; 19418 19419 BmpDecoder.prototype.bit1 = function () { 19420 var xlen = Math.ceil(this.width / 8); 19421 var mode = xlen % 4; 19422 var y; 19423 19424 for (y = this.height - 1; y >= 0; y--) { 19425 var line = this.bottom_up ? y : this.height - 1 - y; 19426 19427 for (var x = 0; x < xlen; x++) { 19428 var b = this.datav.getUint8(this.pos++, true); 19429 var location = line * this.width * 4 + x * 8 * 4; 19430 19431 for (var i = 0; i < 8; i++) { 19432 if (x * 8 + i < this.width) { 19433 var rgb = this.palette[b >> 7 - i & 0x1]; 19434 this.data[location + i * 4] = rgb.blue; 19435 this.data[location + i * 4 + 1] = rgb.green; 19436 this.data[location + i * 4 + 2] = rgb.red; 19437 this.data[location + i * 4 + 3] = 0xff; 19438 } else { 19439 break; 19440 } 19441 } 19442 } 19443 19444 if (mode !== 0) { 19445 this.pos += 4 - mode; 19446 } 19447 } 19448 }; 19449 19450 BmpDecoder.prototype.bit4 = function () { 19451 var xlen = Math.ceil(this.width / 2); 19452 var mode = xlen % 4; 19453 19454 for (var y = this.height - 1; y >= 0; y--) { 19455 var line = this.bottom_up ? y : this.height - 1 - y; 19456 19457 for (var x = 0; x < xlen; x++) { 19458 var b = this.datav.getUint8(this.pos++, true); 19459 var location = line * this.width * 4 + x * 2 * 4; 19460 var before = b >> 4; 19461 var after = b & 0x0f; 19462 var rgb = this.palette[before]; 19463 this.data[location] = rgb.blue; 19464 this.data[location + 1] = rgb.green; 19465 this.data[location + 2] = rgb.red; 19466 this.data[location + 3] = 0xff; 19467 if (x * 2 + 1 >= this.width) break; 19468 rgb = this.palette[after]; 19469 this.data[location + 4] = rgb.blue; 19470 this.data[location + 4 + 1] = rgb.green; 19471 this.data[location + 4 + 2] = rgb.red; 19472 this.data[location + 4 + 3] = 0xff; 19473 } 19474 19475 if (mode !== 0) { 19476 this.pos += 4 - mode; 19477 } 19478 } 19479 }; 19480 19481 BmpDecoder.prototype.bit8 = function () { 19482 var mode = this.width % 4; 19483 19484 for (var y = this.height - 1; y >= 0; y--) { 19485 var line = this.bottom_up ? y : this.height - 1 - y; 19486 19487 for (var x = 0; x < this.width; x++) { 19488 var b = this.datav.getUint8(this.pos++, true); 19489 var location = line * this.width * 4 + x * 4; 19490 19491 if (b < this.palette.length) { 19492 var rgb = this.palette[b]; 19493 this.data[location] = rgb.red; 19494 this.data[location + 1] = rgb.green; 19495 this.data[location + 2] = rgb.blue; 19496 this.data[location + 3] = 0xff; 19497 } else { 19498 this.data[location] = 0xff; 19499 this.data[location + 1] = 0xff; 19500 this.data[location + 2] = 0xff; 19501 this.data[location + 3] = 0xff; 19502 } 19503 } 19504 19505 if (mode !== 0) { 19506 this.pos += 4 - mode; 19507 } 19508 } 19509 }; 19510 19511 BmpDecoder.prototype.bit15 = function () { 19512 var dif_w = this.width % 3; 19513 19514 var _11111 = parseInt("11111", 2), 19515 _1_5 = _11111; 19516 19517 for (var y = this.height - 1; y >= 0; y--) { 19518 var line = this.bottom_up ? y : this.height - 1 - y; 19519 19520 for (var x = 0; x < this.width; x++) { 19521 var B = this.datav.getUint16(this.pos, true); 19522 this.pos += 2; 19523 var blue = (B & _1_5) / _1_5 * 255 | 0; 19524 var green = (B >> 5 & _1_5) / _1_5 * 255 | 0; 19525 var red = (B >> 10 & _1_5) / _1_5 * 255 | 0; 19526 var alpha = B >> 15 ? 0xff : 0x00; 19527 var location = line * this.width * 4 + x * 4; 19528 this.data[location] = red; 19529 this.data[location + 1] = green; 19530 this.data[location + 2] = blue; 19531 this.data[location + 3] = alpha; 19532 } //skip extra bytes 19533 19534 19535 this.pos += dif_w; 19536 } 19537 }; 19538 19539 BmpDecoder.prototype.bit16 = function () { 19540 var dif_w = this.width % 3; 19541 19542 var _11111 = parseInt("11111", 2), 19543 _1_5 = _11111; 19544 19545 var _111111 = parseInt("111111", 2), 19546 _1_6 = _111111; 19547 19548 for (var y = this.height - 1; y >= 0; y--) { 19549 var line = this.bottom_up ? y : this.height - 1 - y; 19550 19551 for (var x = 0; x < this.width; x++) { 19552 var B = this.datav.getUint16(this.pos, true); 19553 this.pos += 2; 19554 var alpha = 0xff; 19555 var blue = (B & _1_5) / _1_5 * 255 | 0; 19556 var green = (B >> 5 & _1_6) / _1_6 * 255 | 0; 19557 var red = (B >> 11) / _1_5 * 255 | 0; 19558 var location = line * this.width * 4 + x * 4; 19559 this.data[location] = red; 19560 this.data[location + 1] = green; 19561 this.data[location + 2] = blue; 19562 this.data[location + 3] = alpha; 19563 } //skip extra bytes 19564 19565 19566 this.pos += dif_w; 19567 } 19568 }; 19569 19570 BmpDecoder.prototype.bit24 = function () { 19571 //when height > 0 19572 for (var y = this.height - 1; y >= 0; y--) { 19573 var line = this.bottom_up ? y : this.height - 1 - y; 19574 19575 for (var x = 0; x < this.width; x++) { 19576 var blue = this.datav.getUint8(this.pos++, true); 19577 var green = this.datav.getUint8(this.pos++, true); 19578 var red = this.datav.getUint8(this.pos++, true); 19579 var location = line * this.width * 4 + x * 4; 19580 this.data[location] = red; 19581 this.data[location + 1] = green; 19582 this.data[location + 2] = blue; 19583 this.data[location + 3] = 0xff; 19584 } //skip extra bytes 19585 19586 19587 this.pos += this.width % 4; 19588 } 19589 }; 19590 /** 19591 * add 32bit decode func 19592 * @author soubok 19593 */ 19594 19595 19596 BmpDecoder.prototype.bit32 = function () { 19597 //when height > 0 19598 for (var y = this.height - 1; y >= 0; y--) { 19599 var line = this.bottom_up ? y : this.height - 1 - y; 19600 19601 for (var x = 0; x < this.width; x++) { 19602 var blue = this.datav.getUint8(this.pos++, true); 19603 var green = this.datav.getUint8(this.pos++, true); 19604 var red = this.datav.getUint8(this.pos++, true); 19605 var alpha = this.datav.getUint8(this.pos++, true); 19606 var location = line * this.width * 4 + x * 4; 19607 this.data[location] = red; 19608 this.data[location + 1] = green; 19609 this.data[location + 2] = blue; 19610 this.data[location + 3] = alpha; 19611 } //skip extra bytes 19612 //this.pos += (this.width % 4); 19613 19614 } 19615 }; 19616 19617 BmpDecoder.prototype.getData = function () { 19618 return this.data; 19619 }; 19620 19621 /** 19622 * @license 19623 * Copyright (c) 2018 Aras Abbasi 19624 * 19625 * Licensed under the MIT License. 19626 * http://opensource.org/licenses/mit-license 19627 */ 19628 19629 /** 19630 * jsPDF bmp Support PlugIn 19631 * @name bmp_support 19632 * @module 19633 */ 19634 19635 (function (jsPDFAPI) { 19636 19637 jsPDFAPI.processBMP = function (imageData, index, alias, compression) { 19638 var reader = new BmpDecoder(imageData, false); 19639 var width = reader.width, 19640 height = reader.height; 19641 var qu = 100; 19642 var pixels = reader.getData(); 19643 var rawImageData = { 19644 data: pixels, 19645 width: width, 19646 height: height 19647 }; 19648 var encoder = new JPEGEncoder(qu); 19649 var data = encoder.encode(rawImageData, qu); 19650 return jsPDFAPI.processJPEG.call(this, data, index, alias, compression); 19651 }; 19652 })(jsPDF.API); 19653 19654 function WebPDecoder(imageData) { 19655 19656 function x(F) { 19657 if (!F) throw Error("assert :P"); 19658 } 19659 19660 function fa(F, L, J) { 19661 for (var H = 0; 4 > H; H++) { 19662 if (F[L + H] != J.charCodeAt(H)) return !0; 19663 } 19664 19665 return !1; 19666 } 19667 19668 function I(F, L, J, H, Z) { 19669 for (var O = 0; O < Z; O++) { 19670 F[L + O] = J[H + O]; 19671 } 19672 } 19673 19674 function M(F, L, J, H) { 19675 for (var Z = 0; Z < H; Z++) { 19676 F[L + Z] = J; 19677 } 19678 } 19679 19680 function V(F) { 19681 return new Int32Array(F); 19682 } 19683 19684 function wa(F, L) { 19685 for (var J = [], H = 0; H < F; H++) { 19686 J.push(new L()); 19687 } 19688 19689 return J; 19690 } 19691 19692 function wb() { 19693 function F(J, H, Z) { 19694 for (var O = Z[H], L = 0; L < O; L++) { 19695 J.push(Z.length > H + 1 ? [] : 0); 19696 if (Z.length < H + 1) break; 19697 F(J[L], H + 1, Z); 19698 } 19699 } 19700 19701 var L = []; 19702 F(L, 0, [3, 11]); 19703 return L; 19704 } 19705 19706 function Ed(F, L) { 19707 function J(H, O, F) { 19708 for (var Z = F[O], ma = 0; ma < Z; ma++) { 19709 H.push(F.length > O + 1 ? [] : new L()); 19710 if (F.length < O + 1) break; 19711 J(H[ma], O + 1, F); 19712 } 19713 } 19714 19715 var H = []; 19716 J(H, 0, F); 19717 return H; 19718 } 19719 19720 var _WebPDecoder = function _WebPDecoder() { 19721 var self = this; 19722 19723 function L(a, b) { 19724 for (var c = 1 << b - 1 >>> 0; a & c;) { 19725 c >>>= 1; 19726 } 19727 19728 return c ? (a & c - 1) + c : a; 19729 } 19730 19731 function J(a, b, c, d, e) { 19732 x(!(d % c)); 19733 19734 do { 19735 d -= c, a[b + d] = e; 19736 } while (0 < d); 19737 } 19738 19739 function H(a, b, c, d, e, f) { 19740 var g = b, 19741 h = 1 << c, 19742 k, 19743 l, 19744 m = V(16), 19745 n = V(16); 19746 x(0 != e); 19747 x(null != d); 19748 x(null != a); 19749 x(0 < c); 19750 19751 for (l = 0; l < e; ++l) { 19752 if (15 < d[l]) return 0; 19753 ++m[d[l]]; 19754 } 19755 19756 if (m[0] == e) return 0; 19757 n[1] = 0; 19758 19759 for (k = 1; 15 > k; ++k) { 19760 if (m[k] > 1 << k) return 0; 19761 n[k + 1] = n[k] + m[k]; 19762 } 19763 19764 for (l = 0; l < e; ++l) { 19765 k = d[l], 0 < d[l] && (f[n[k]++] = l); 19766 } 19767 19768 if (1 == n[15]) return d = new O(), d.g = 0, d.value = f[0], J(a, g, 1, h, d), h; 19769 var r = -1, 19770 q = h - 1, 19771 t = 0, 19772 v = 1, 19773 p = 1, 19774 u, 19775 w = 1 << c; 19776 l = 0; 19777 k = 1; 19778 19779 for (e = 2; k <= c; ++k, e <<= 1) { 19780 p <<= 1; 19781 v += p; 19782 p -= m[k]; 19783 if (0 > p) return 0; 19784 19785 for (; 0 < m[k]; --m[k]) { 19786 d = new O(), d.g = k, d.value = f[l++], J(a, g + t, e, w, d), t = L(t, k); 19787 } 19788 } 19789 19790 k = c + 1; 19791 19792 for (e = 2; 15 >= k; ++k, e <<= 1) { 19793 p <<= 1; 19794 v += p; 19795 p -= m[k]; 19796 if (0 > p) return 0; 19797 19798 for (; 0 < m[k]; --m[k]) { 19799 d = new O(); 19800 19801 if ((t & q) != r) { 19802 g += w; 19803 r = k; 19804 19805 for (u = 1 << r - c; 15 > r;) { 19806 u -= m[r]; 19807 if (0 >= u) break; 19808 ++r; 19809 u <<= 1; 19810 } 19811 19812 u = r - c; 19813 w = 1 << u; 19814 h += w; 19815 r = t & q; 19816 a[b + r].g = u + c; 19817 a[b + r].value = g - b - r; 19818 } 19819 19820 d.g = k - c; 19821 d.value = f[l++]; 19822 J(a, g + (t >> c), e, w, d); 19823 t = L(t, k); 19824 } 19825 } 19826 19827 return v != 2 * n[15] - 1 ? 0 : h; 19828 } 19829 19830 function Z(a, b, c, d, e) { 19831 x(2328 >= e); 19832 if (512 >= e) var f = V(512);else if (f = V(e), null == f) return 0; 19833 return H(a, b, c, d, e, f); 19834 } 19835 19836 function O() { 19837 this.value = this.g = 0; 19838 } 19839 19840 function Fd() { 19841 this.value = this.g = 0; 19842 } 19843 19844 function Ub() { 19845 this.G = wa(5, O); 19846 this.H = V(5); 19847 this.jc = this.Qb = this.qb = this.nd = 0; 19848 this.pd = wa(xb, Fd); 19849 } 19850 19851 function ma(a, b, c, d) { 19852 x(null != a); 19853 x(null != b); 19854 x(2147483648 > d); 19855 a.Ca = 254; 19856 a.I = 0; 19857 a.b = -8; 19858 a.Ka = 0; 19859 a.oa = b; 19860 a.pa = c; 19861 a.Jd = b; 19862 a.Yc = c + d; 19863 a.Zc = 4 <= d ? c + d - 4 + 1 : c; 19864 Qa(a); 19865 } 19866 19867 function na(a, b) { 19868 for (var c = 0; 0 < b--;) { 19869 c |= K(a, 128) << b; 19870 } 19871 19872 return c; 19873 } 19874 19875 function ca(a, b) { 19876 var c = na(a, b); 19877 return G(a) ? -c : c; 19878 } 19879 19880 function cb(a, b, c, d) { 19881 var e, 19882 f = 0; 19883 x(null != a); 19884 x(null != b); 19885 x(4294967288 > d); 19886 a.Sb = d; 19887 a.Ra = 0; 19888 a.u = 0; 19889 a.h = 0; 19890 4 < d && (d = 4); 19891 19892 for (e = 0; e < d; ++e) { 19893 f += b[c + e] << 8 * e; 19894 } 19895 19896 a.Ra = f; 19897 a.bb = d; 19898 a.oa = b; 19899 a.pa = c; 19900 } 19901 19902 function Vb(a) { 19903 for (; 8 <= a.u && a.bb < a.Sb;) { 19904 a.Ra >>>= 8, a.Ra += a.oa[a.pa + a.bb] << ob - 8 >>> 0, ++a.bb, a.u -= 8; 19905 } 19906 19907 db(a) && (a.h = 1, a.u = 0); 19908 } 19909 19910 function D(a, b) { 19911 x(0 <= b); 19912 19913 if (!a.h && b <= Gd) { 19914 var c = pb(a) & Hd[b]; 19915 a.u += b; 19916 Vb(a); 19917 return c; 19918 } 19919 19920 a.h = 1; 19921 return a.u = 0; 19922 } 19923 19924 function Wb() { 19925 this.b = this.Ca = this.I = 0; 19926 this.oa = []; 19927 this.pa = 0; 19928 this.Jd = []; 19929 this.Yc = 0; 19930 this.Zc = []; 19931 this.Ka = 0; 19932 } 19933 19934 function Ra() { 19935 this.Ra = 0; 19936 this.oa = []; 19937 this.h = this.u = this.bb = this.Sb = this.pa = 0; 19938 } 19939 19940 function pb(a) { 19941 return a.Ra >>> (a.u & ob - 1) >>> 0; 19942 } 19943 19944 function db(a) { 19945 x(a.bb <= a.Sb); 19946 return a.h || a.bb == a.Sb && a.u > ob; 19947 } 19948 19949 function qb(a, b) { 19950 a.u = b; 19951 a.h = db(a); 19952 } 19953 19954 function Sa(a) { 19955 a.u >= Xb && (x(a.u >= Xb), Vb(a)); 19956 } 19957 19958 function Qa(a) { 19959 x(null != a && null != a.oa); 19960 a.pa < a.Zc ? (a.I = (a.oa[a.pa++] | a.I << 8) >>> 0, a.b += 8) : (x(null != a && null != a.oa), a.pa < a.Yc ? (a.b += 8, a.I = a.oa[a.pa++] | a.I << 8) : a.Ka ? a.b = 0 : (a.I <<= 8, a.b += 8, a.Ka = 1)); 19961 } 19962 19963 function G(a) { 19964 return na(a, 1); 19965 } 19966 19967 function K(a, b) { 19968 var c = a.Ca; 19969 0 > a.b && Qa(a); 19970 var d = a.b, 19971 e = c * b >>> 8, 19972 f = (a.I >>> d > e) + 0; 19973 f ? (c -= e, a.I -= e + 1 << d >>> 0) : c = e + 1; 19974 d = c; 19975 19976 for (e = 0; 256 <= d;) { 19977 e += 8, d >>= 8; 19978 } 19979 19980 d = 7 ^ e + Id[d]; 19981 a.b -= d; 19982 a.Ca = (c << d) - 1; 19983 return f; 19984 } 19985 19986 function ra(a, b, c) { 19987 a[b + 0] = c >> 24 & 255; 19988 a[b + 1] = c >> 16 & 255; 19989 a[b + 2] = c >> 8 & 255; 19990 a[b + 3] = c >> 0 & 255; 19991 } 19992 19993 function Ta(a, b) { 19994 return a[b + 0] << 0 | a[b + 1] << 8; 19995 } 19996 19997 function Yb(a, b) { 19998 return Ta(a, b) | a[b + 2] << 16; 19999 } 20000 20001 function Ha(a, b) { 20002 return Ta(a, b) | Ta(a, b + 2) << 16; 20003 } 20004 20005 function Zb(a, b) { 20006 var c = 1 << b; 20007 x(null != a); 20008 x(0 < b); 20009 a.X = V(c); 20010 if (null == a.X) return 0; 20011 a.Mb = 32 - b; 20012 a.Xa = b; 20013 return 1; 20014 } 20015 20016 function $b(a, b) { 20017 x(null != a); 20018 x(null != b); 20019 x(a.Xa == b.Xa); 20020 I(b.X, 0, a.X, 0, 1 << b.Xa); 20021 } 20022 20023 function ac() { 20024 this.X = []; 20025 this.Xa = this.Mb = 0; 20026 } 20027 20028 function bc(a, b, c, d) { 20029 x(null != c); 20030 x(null != d); 20031 var e = c[0], 20032 f = d[0]; 20033 0 == e && (e = (a * f + b / 2) / b); 20034 0 == f && (f = (b * e + a / 2) / a); 20035 if (0 >= e || 0 >= f) return 0; 20036 c[0] = e; 20037 d[0] = f; 20038 return 1; 20039 } 20040 20041 function xa(a, b) { 20042 return a + (1 << b) - 1 >>> b; 20043 } 20044 20045 function yb(a, b) { 20046 return ((a & 4278255360) + (b & 4278255360) >>> 0 & 4278255360) + ((a & 16711935) + (b & 16711935) >>> 0 & 16711935) >>> 0; 20047 } 20048 20049 function X(a, b) { 20050 self[b] = function (b, d, e, f, g, h, k) { 20051 var c; 20052 20053 for (c = 0; c < g; ++c) { 20054 var m = self[a](h[k + c - 1], e, f + c); 20055 h[k + c] = yb(b[d + c], m); 20056 } 20057 }; 20058 } 20059 20060 function Jd() { 20061 this.ud = this.hd = this.jd = 0; 20062 } 20063 20064 function aa(a, b) { 20065 return (((a ^ b) & 4278124286) >>> 1) + (a & b) >>> 0; 20066 } 20067 20068 function sa(a) { 20069 if (0 <= a && 256 > a) return a; 20070 if (0 > a) return 0; 20071 if (255 < a) return 255; 20072 } 20073 20074 function eb(a, b) { 20075 return sa(a + (a - b + 0.5 >> 1)); 20076 } 20077 20078 function Ia(a, b, c) { 20079 return Math.abs(b - c) - Math.abs(a - c); 20080 } 20081 20082 function cc(a, b, c, d, e, f, g) { 20083 d = f[g - 1]; 20084 20085 for (c = 0; c < e; ++c) { 20086 f[g + c] = d = yb(a[b + c], d); 20087 } 20088 } 20089 20090 function Kd(a, b, c, d, e) { 20091 var f; 20092 20093 for (f = 0; f < c; ++f) { 20094 var g = a[b + f], 20095 h = g >> 8 & 255, 20096 k = g & 16711935, 20097 k = k + ((h << 16) + h), 20098 k = k & 16711935; 20099 d[e + f] = (g & 4278255360) + k >>> 0; 20100 } 20101 } 20102 20103 function dc(a, b) { 20104 b.jd = a >> 0 & 255; 20105 b.hd = a >> 8 & 255; 20106 b.ud = a >> 16 & 255; 20107 } 20108 20109 function Ld(a, b, c, d, e, f) { 20110 var g; 20111 20112 for (g = 0; g < d; ++g) { 20113 var h = b[c + g], 20114 k = h >>> 8, 20115 l = h >>> 16, 20116 m = h, 20117 l = l + ((a.jd << 24 >> 24) * (k << 24 >> 24) >>> 5), 20118 l = l & 255, 20119 m = m + ((a.hd << 24 >> 24) * (k << 24 >> 24) >>> 5), 20120 m = m + ((a.ud << 24 >> 24) * (l << 24 >> 24) >>> 5), 20121 m = m & 255; 20122 e[f + g] = (h & 4278255360) + (l << 16) + m; 20123 } 20124 } 20125 20126 function ec(a, b, c, d, e) { 20127 self[b] = function (a, b, c, k, l, m, n, r, q) { 20128 for (k = n; k < r; ++k) { 20129 for (n = 0; n < q; ++n) { 20130 l[m++] = e(c[d(a[b++])]); 20131 } 20132 } 20133 }; 20134 20135 self[a] = function (a, b, h, k, l, m, n) { 20136 var f = 8 >> a.b, 20137 g = a.Ea, 20138 t = a.K[0], 20139 v = a.w; 20140 if (8 > f) for (a = (1 << a.b) - 1, v = (1 << f) - 1; b < h; ++b) { 20141 var p = 0, 20142 u; 20143 20144 for (u = 0; u < g; ++u) { 20145 u & a || (p = d(k[l++])), m[n++] = e(t[p & v]), p >>= f; 20146 } 20147 } else self["VP8LMapColor" + c](k, l, t, v, m, n, b, h, g); 20148 }; 20149 } 20150 20151 function Md(a, b, c, d, e) { 20152 for (c = b + c; b < c;) { 20153 var f = a[b++]; 20154 d[e++] = f >> 16 & 255; 20155 d[e++] = f >> 8 & 255; 20156 d[e++] = f >> 0 & 255; 20157 } 20158 } 20159 20160 function Nd(a, b, c, d, e) { 20161 for (c = b + c; b < c;) { 20162 var f = a[b++]; 20163 d[e++] = f >> 16 & 255; 20164 d[e++] = f >> 8 & 255; 20165 d[e++] = f >> 0 & 255; 20166 d[e++] = f >> 24 & 255; 20167 } 20168 } 20169 20170 function Od(a, b, c, d, e) { 20171 for (c = b + c; b < c;) { 20172 var f = a[b++], 20173 g = f >> 16 & 240 | f >> 12 & 15, 20174 f = f >> 0 & 240 | f >> 28 & 15; 20175 d[e++] = g; 20176 d[e++] = f; 20177 } 20178 } 20179 20180 function Pd(a, b, c, d, e) { 20181 for (c = b + c; b < c;) { 20182 var f = a[b++], 20183 g = f >> 16 & 248 | f >> 13 & 7, 20184 f = f >> 5 & 224 | f >> 3 & 31; 20185 d[e++] = g; 20186 d[e++] = f; 20187 } 20188 } 20189 20190 function Qd(a, b, c, d, e) { 20191 for (c = b + c; b < c;) { 20192 var f = a[b++]; 20193 d[e++] = f >> 0 & 255; 20194 d[e++] = f >> 8 & 255; 20195 d[e++] = f >> 16 & 255; 20196 } 20197 } 20198 20199 function fb(a, b, c, d, e, f) { 20200 if (0 == f) for (c = b + c; b < c;) { 20201 f = a[b++], ra(d, (f[0] >> 24 | f[1] >> 8 & 65280 | f[2] << 8 & 16711680 | f[3] << 24) >>> 0), e += 32; 20202 } else I(d, e, a, b, c); 20203 } 20204 20205 function gb(a, b) { 20206 self[b][0] = self[a + "0"]; 20207 self[b][1] = self[a + "1"]; 20208 self[b][2] = self[a + "2"]; 20209 self[b][3] = self[a + "3"]; 20210 self[b][4] = self[a + "4"]; 20211 self[b][5] = self[a + "5"]; 20212 self[b][6] = self[a + "6"]; 20213 self[b][7] = self[a + "7"]; 20214 self[b][8] = self[a + "8"]; 20215 self[b][9] = self[a + "9"]; 20216 self[b][10] = self[a + "10"]; 20217 self[b][11] = self[a + "11"]; 20218 self[b][12] = self[a + "12"]; 20219 self[b][13] = self[a + "13"]; 20220 self[b][14] = self[a + "0"]; 20221 self[b][15] = self[a + "0"]; 20222 } 20223 20224 function hb(a) { 20225 return a == zb || a == Ab || a == Ja || a == Bb; 20226 } 20227 20228 function Rd() { 20229 this.eb = []; 20230 this.size = this.A = this.fb = 0; 20231 } 20232 20233 function Sd() { 20234 this.y = []; 20235 this.f = []; 20236 this.ea = []; 20237 this.F = []; 20238 this.Tc = this.Ed = this.Cd = this.Fd = this.lb = this.Db = this.Ab = this.fa = this.J = this.W = this.N = this.O = 0; 20239 } 20240 20241 function Cb() { 20242 this.Rd = this.height = this.width = this.S = 0; 20243 this.f = {}; 20244 this.f.RGBA = new Rd(); 20245 this.f.kb = new Sd(); 20246 this.sd = null; 20247 } 20248 20249 function Td() { 20250 this.width = [0]; 20251 this.height = [0]; 20252 this.Pd = [0]; 20253 this.Qd = [0]; 20254 this.format = [0]; 20255 } 20256 20257 function Ud() { 20258 this.Id = this.fd = this.Md = this.hb = this.ib = this.da = this.bd = this.cd = this.j = this.v = this.Da = this.Sd = this.ob = 0; 20259 } 20260 20261 function Vd(a) { 20262 alert("todo:WebPSamplerProcessPlane"); 20263 return a.T; 20264 } 20265 20266 function Wd(a, b) { 20267 var c = a.T, 20268 d = b.ba.f.RGBA, 20269 e = d.eb, 20270 f = d.fb + a.ka * d.A, 20271 g = P[b.ba.S], 20272 h = a.y, 20273 k = a.O, 20274 l = a.f, 20275 m = a.N, 20276 n = a.ea, 20277 r = a.W, 20278 q = b.cc, 20279 t = b.dc, 20280 v = b.Mc, 20281 p = b.Nc, 20282 u = a.ka, 20283 w = a.ka + a.T, 20284 y = a.U, 20285 A = y + 1 >> 1; 20286 0 == u ? g(h, k, null, null, l, m, n, r, l, m, n, r, e, f, null, null, y) : (g(b.ec, b.fc, h, k, q, t, v, p, l, m, n, r, e, f - d.A, e, f, y), ++c); 20287 20288 for (; u + 2 < w; u += 2) { 20289 q = l, t = m, v = n, p = r, m += a.Rc, r += a.Rc, f += 2 * d.A, k += 2 * a.fa, g(h, k - a.fa, h, k, q, t, v, p, l, m, n, r, e, f - d.A, e, f, y); 20290 } 20291 20292 k += a.fa; 20293 a.j + w < a.o ? (I(b.ec, b.fc, h, k, y), I(b.cc, b.dc, l, m, A), I(b.Mc, b.Nc, n, r, A), c--) : w & 1 || g(h, k, null, null, l, m, n, r, l, m, n, r, e, f + d.A, null, null, y); 20294 return c; 20295 } 20296 20297 function Xd(a, b, c) { 20298 var d = a.F, 20299 e = [a.J]; 20300 20301 if (null != d) { 20302 var f = a.U, 20303 g = b.ba.S, 20304 h = g == ya || g == Ja; 20305 b = b.ba.f.RGBA; 20306 var k = [0], 20307 l = a.ka; 20308 k[0] = a.T; 20309 a.Kb && (0 == l ? --k[0] : (--l, e[0] -= a.width), a.j + a.ka + a.T == a.o && (k[0] = a.o - a.j - l)); 20310 var m = b.eb, 20311 l = b.fb + l * b.A; 20312 a = fc(d, e[0], a.width, f, k, m, l + (h ? 0 : 3), b.A); 20313 x(c == k); 20314 a && hb(g) && za(m, l, h, f, k, b.A); 20315 } 20316 20317 return 0; 20318 } 20319 20320 function gc(a) { 20321 var b = a.ma, 20322 c = b.ba.S, 20323 d = 11 > c, 20324 e = c == Ua || c == Va || c == ya || c == Db || 12 == c || hb(c); 20325 b.memory = null; 20326 b.Ib = null; 20327 b.Jb = null; 20328 b.Nd = null; 20329 if (!hc(b.Oa, a, e ? 11 : 12)) return 0; 20330 e && hb(c) && ic(); 20331 if (a.da) alert("todo:use_scaling");else { 20332 if (d) { 20333 if (b.Ib = Vd, a.Kb) { 20334 c = a.U + 1 >> 1; 20335 b.memory = V(a.U + 2 * c); 20336 if (null == b.memory) return 0; 20337 b.ec = b.memory; 20338 b.fc = 0; 20339 b.cc = b.ec; 20340 b.dc = b.fc + a.U; 20341 b.Mc = b.cc; 20342 b.Nc = b.dc + c; 20343 b.Ib = Wd; 20344 ic(); 20345 } 20346 } else alert("todo:EmitYUV"); 20347 20348 e && (b.Jb = Xd, d && Aa()); 20349 } 20350 20351 if (d && !jc) { 20352 for (a = 0; 256 > a; ++a) { 20353 Yd[a] = 89858 * (a - 128) + Ba >> Wa, Zd[a] = -22014 * (a - 128) + Ba, $d[a] = -45773 * (a - 128), ae[a] = 113618 * (a - 128) + Ba >> Wa; 20354 } 20355 20356 for (a = ta; a < Eb; ++a) { 20357 b = 76283 * (a - 16) + Ba >> Wa, be[a - ta] = ga(b, 255), ce[a - ta] = ga(b + 8 >> 4, 15); 20358 } 20359 20360 jc = 1; 20361 } 20362 20363 return 1; 20364 } 20365 20366 function kc(a) { 20367 var b = a.ma, 20368 c = a.U, 20369 d = a.T; 20370 x(!(a.ka & 1)); 20371 if (0 >= c || 0 >= d) return 0; 20372 c = b.Ib(a, b); 20373 null != b.Jb && b.Jb(a, b, c); 20374 b.Dc += c; 20375 return 1; 20376 } 20377 20378 function lc(a) { 20379 a.ma.memory = null; 20380 } 20381 20382 function mc(a, b, c, d) { 20383 if (47 != D(a, 8)) return 0; 20384 b[0] = D(a, 14) + 1; 20385 c[0] = D(a, 14) + 1; 20386 d[0] = D(a, 1); 20387 return 0 != D(a, 3) ? 0 : !a.h; 20388 } 20389 20390 function ib(a, b) { 20391 if (4 > a) return a + 1; 20392 var c = a - 2 >> 1; 20393 return (2 + (a & 1) << c) + D(b, c) + 1; 20394 } 20395 20396 function nc(a, b) { 20397 if (120 < b) return b - 120; 20398 var c = de[b - 1], 20399 c = (c >> 4) * a + (8 - (c & 15)); 20400 return 1 <= c ? c : 1; 20401 } 20402 20403 function ua(a, b, c) { 20404 var d = pb(c); 20405 b += d & 255; 20406 var e = a[b].g - 8; 20407 0 < e && (qb(c, c.u + 8), d = pb(c), b += a[b].value, b += d & (1 << e) - 1); 20408 qb(c, c.u + a[b].g); 20409 return a[b].value; 20410 } 20411 20412 function ub(a, b, c) { 20413 c.g += a.g; 20414 c.value += a.value << b >>> 0; 20415 x(8 >= c.g); 20416 return a.g; 20417 } 20418 20419 function ha(a, b, c) { 20420 var d = a.xc; 20421 b = 0 == d ? 0 : a.vc[a.md * (c >> d) + (b >> d)]; 20422 x(b < a.Wb); 20423 return a.Ya[b]; 20424 } 20425 20426 function oc(a, b, c, d) { 20427 var e = a.ab, 20428 f = a.c * b, 20429 g = a.C; 20430 b = g + b; 20431 var h = c, 20432 k = d; 20433 d = a.Ta; 20434 20435 for (c = a.Ua; 0 < e--;) { 20436 var l = a.gc[e], 20437 m = g, 20438 n = b, 20439 r = h, 20440 q = k, 20441 k = d, 20442 h = c, 20443 t = l.Ea; 20444 x(m < n); 20445 x(n <= l.nc); 20446 20447 switch (l.hc) { 20448 case 2: 20449 pc(r, q, (n - m) * t, k, h); 20450 break; 20451 20452 case 0: 20453 var v = l, 20454 p = m, 20455 u = n, 20456 w = k, 20457 y = h, 20458 A = v.Ea; 20459 0 == p && (ee(r, q, null, null, 1, w, y), cc(r, q + 1, 0, 0, A - 1, w, y + 1), q += A, y += A, ++p); 20460 20461 for (var E = 1 << v.b, B = E - 1, C = xa(A, v.b), N = v.K, v = v.w + (p >> v.b) * C; p < u;) { 20462 var z = N, 20463 Q = v, 20464 S = 1; 20465 20466 for (fe(r, q, w, y - A, 1, w, y); S < A;) { 20467 var K = qc[z[Q++] >> 8 & 15], 20468 D = (S & ~B) + E; 20469 D > A && (D = A); 20470 K(r, q + +S, w, y + S - A, D - S, w, y + S); 20471 S = D; 20472 } 20473 20474 q += A; 20475 y += A; 20476 ++p; 20477 p & B || (v += C); 20478 } 20479 20480 n != l.nc && I(k, h - t, k, h + (n - m - 1) * t, t); 20481 break; 20482 20483 case 1: 20484 t = r; 20485 u = q; 20486 r = l.Ea; 20487 q = 1 << l.b; 20488 w = q - 1; 20489 y = r & ~w; 20490 A = r - y; 20491 p = xa(r, l.b); 20492 E = l.K; 20493 20494 for (l = l.w + (m >> l.b) * p; m < n;) { 20495 B = E; 20496 C = l; 20497 N = new Jd(); 20498 v = u + y; 20499 20500 for (z = u + r; u < v;) { 20501 dc(B[C++], N), Fb(N, t, u, q, k, h), u += q, h += q; 20502 } 20503 20504 u < z && (dc(B[C++], N), Fb(N, t, u, A, k, h), u += A, h += A); 20505 ++m; 20506 m & w || (l += p); 20507 } 20508 20509 break; 20510 20511 case 3: 20512 if (r == k && q == h && 0 < l.b) { 20513 y = (n - m) * xa(l.Ea, l.b); 20514 t = h + (n - m) * t - y; 20515 u = k; 20516 r = t; 20517 q = k; 20518 w = h; 20519 A = y; 20520 p = []; 20521 20522 for (y = A - 1; 0 <= y; --y) { 20523 p[y] = q[w + y]; 20524 } 20525 20526 for (y = A - 1; 0 <= y; --y) { 20527 u[r + y] = p[y]; 20528 } 20529 20530 rc(l, m, n, k, t, k, h); 20531 } else rc(l, m, n, r, q, k, h); 20532 20533 } 20534 20535 h = d; 20536 k = c; 20537 } 20538 20539 k != c && I(d, c, h, k, f); 20540 } 20541 20542 function ge(a, b) { 20543 var c = a.V, 20544 d = a.Ba + a.c * a.C, 20545 e = b - a.C; 20546 x(b <= a.l.o); 20547 x(16 >= e); 20548 20549 if (0 < e) { 20550 var f = a.l, 20551 g = a.Ta, 20552 h = a.Ua, 20553 k = f.width; 20554 oc(a, e, c, d); 20555 h = [h]; 20556 c = a.C; 20557 d = b; 20558 e = h; 20559 x(c < d); 20560 x(f.v < f.va); 20561 d > f.o && (d = f.o); 20562 20563 if (c < f.j) { 20564 var l = f.j - c, 20565 c = f.j; 20566 e[0] += l * k; 20567 } 20568 20569 c >= d ? c = 0 : (e[0] += 4 * f.v, f.ka = c - f.j, f.U = f.va - f.v, f.T = d - c, c = 1); 20570 20571 if (c) { 20572 h = h[0]; 20573 c = a.ca; 20574 20575 if (11 > c.S) { 20576 for (var m = c.f.RGBA, d = c.S, e = f.U, f = f.T, l = m.eb, n = m.A, r = f, m = m.fb + a.Ma * m.A; 0 < r--;) { 20577 var q = g, 20578 t = h, 20579 v = e, 20580 p = l, 20581 u = m; 20582 20583 switch (d) { 20584 case Ca: 20585 sc(q, t, v, p, u); 20586 break; 20587 20588 case Ua: 20589 Gb(q, t, v, p, u); 20590 break; 20591 20592 case zb: 20593 Gb(q, t, v, p, u); 20594 za(p, u, 0, v, 1, 0); 20595 break; 20596 20597 case tc: 20598 uc(q, t, v, p, u); 20599 break; 20600 20601 case Va: 20602 fb(q, t, v, p, u, 1); 20603 break; 20604 20605 case Ab: 20606 fb(q, t, v, p, u, 1); 20607 za(p, u, 0, v, 1, 0); 20608 break; 20609 20610 case ya: 20611 fb(q, t, v, p, u, 0); 20612 break; 20613 20614 case Ja: 20615 fb(q, t, v, p, u, 0); 20616 za(p, u, 1, v, 1, 0); 20617 break; 20618 20619 case Db: 20620 Hb(q, t, v, p, u); 20621 break; 20622 20623 case Bb: 20624 Hb(q, t, v, p, u); 20625 vc(p, u, v, 1, 0); 20626 break; 20627 20628 case wc: 20629 xc(q, t, v, p, u); 20630 break; 20631 20632 default: 20633 x(0); 20634 } 20635 20636 h += k; 20637 m += n; 20638 } 20639 20640 a.Ma += f; 20641 } else alert("todo:EmitRescaledRowsYUVA"); 20642 20643 x(a.Ma <= c.height); 20644 } 20645 } 20646 20647 a.C = b; 20648 x(a.C <= a.i); 20649 } 20650 20651 function yc(a) { 20652 var b; 20653 if (0 < a.ua) return 0; 20654 20655 for (b = 0; b < a.Wb; ++b) { 20656 var c = a.Ya[b].G, 20657 d = a.Ya[b].H; 20658 if (0 < c[1][d[1] + 0].g || 0 < c[2][d[2] + 0].g || 0 < c[3][d[3] + 0].g) return 0; 20659 } 20660 20661 return 1; 20662 } 20663 20664 function zc(a, b, c, d, e, f) { 20665 if (0 != a.Z) { 20666 var g = a.qd, 20667 h = a.rd; 20668 20669 for (x(null != ia[a.Z]); b < c; ++b) { 20670 ia[a.Z](g, h, d, e, d, e, f), g = d, h = e, e += f; 20671 } 20672 20673 a.qd = g; 20674 a.rd = h; 20675 } 20676 } 20677 20678 function Ib(a, b) { 20679 var c = a.l.ma, 20680 d = 0 == c.Z || 1 == c.Z ? a.l.j : a.C, 20681 d = a.C < d ? d : a.C; 20682 x(b <= a.l.o); 20683 20684 if (b > d) { 20685 var e = a.l.width, 20686 f = c.ca, 20687 g = c.tb + e * d, 20688 h = a.V, 20689 k = a.Ba + a.c * d, 20690 l = a.gc; 20691 x(1 == a.ab); 20692 x(3 == l[0].hc); 20693 he(l[0], d, b, h, k, f, g); 20694 zc(c, d, b, f, g, e); 20695 } 20696 20697 a.C = a.Ma = b; 20698 } 20699 20700 function Jb(a, b, c, d, e, f, g) { 20701 var h = a.$ / d, 20702 k = a.$ % d, 20703 l = a.m, 20704 m = a.s, 20705 n = c + a.$, 20706 r = n; 20707 e = c + d * e; 20708 var q = c + d * f, 20709 t = 280 + m.ua, 20710 v = a.Pb ? h : 16777216, 20711 p = 0 < m.ua ? m.Wa : null, 20712 u = m.wc, 20713 w = n < q ? ha(m, k, h) : null; 20714 x(a.C < f); 20715 x(q <= e); 20716 var y = !1; 20717 20718 a: for (;;) { 20719 for (; y || n < q;) { 20720 var A = 0; 20721 20722 if (h >= v) { 20723 var v = a, 20724 E = n - c; 20725 x(v.Pb); 20726 v.wd = v.m; 20727 v.xd = E; 20728 0 < v.s.ua && $b(v.s.Wa, v.s.vb); 20729 v = h + ie; 20730 } 20731 20732 k & u || (w = ha(m, k, h)); 20733 x(null != w); 20734 w.Qb && (b[n] = w.qb, y = !0); 20735 if (!y) if (Sa(l), w.jc) { 20736 var A = l, 20737 E = b, 20738 B = n, 20739 C = w.pd[pb(A) & xb - 1]; 20740 x(w.jc); 20741 256 > C.g ? (qb(A, A.u + C.g), E[B] = C.value, A = 0) : (qb(A, A.u + C.g - 256), x(256 <= C.value), A = C.value); 20742 0 == A && (y = !0); 20743 } else A = ua(w.G[0], w.H[0], l); 20744 if (l.h) break; 20745 20746 if (y || 256 > A) { 20747 if (!y) if (w.nd) b[n] = (w.qb | A << 8) >>> 0;else { 20748 Sa(l); 20749 y = ua(w.G[1], w.H[1], l); 20750 Sa(l); 20751 E = ua(w.G[2], w.H[2], l); 20752 B = ua(w.G[3], w.H[3], l); 20753 if (l.h) break; 20754 b[n] = (B << 24 | y << 16 | A << 8 | E) >>> 0; 20755 } 20756 y = !1; 20757 ++n; 20758 ++k; 20759 if (k >= d && (k = 0, ++h, null != g && h <= f && !(h % 16) && g(a, h), null != p)) for (; r < n;) { 20760 A = b[r++], p.X[(506832829 * A & 4294967295) >>> p.Mb] = A; 20761 } 20762 } else if (280 > A) { 20763 A = ib(A - 256, l); 20764 E = ua(w.G[4], w.H[4], l); 20765 Sa(l); 20766 E = ib(E, l); 20767 E = nc(d, E); 20768 if (l.h) break; 20769 if (n - c < E || e - n < A) break a;else for (B = 0; B < A; ++B) { 20770 b[n + B] = b[n + B - E]; 20771 } 20772 n += A; 20773 20774 for (k += A; k >= d;) { 20775 k -= d, ++h, null != g && h <= f && !(h % 16) && g(a, h); 20776 } 20777 20778 x(n <= e); 20779 k & u && (w = ha(m, k, h)); 20780 if (null != p) for (; r < n;) { 20781 A = b[r++], p.X[(506832829 * A & 4294967295) >>> p.Mb] = A; 20782 } 20783 } else if (A < t) { 20784 y = A - 280; 20785 20786 for (x(null != p); r < n;) { 20787 A = b[r++], p.X[(506832829 * A & 4294967295) >>> p.Mb] = A; 20788 } 20789 20790 A = n; 20791 E = p; 20792 x(!(y >>> E.Xa)); 20793 b[A] = E.X[y]; 20794 y = !0; 20795 } else break a; 20796 20797 y || x(l.h == db(l)); 20798 } 20799 20800 if (a.Pb && l.h && n < e) x(a.m.h), a.a = 5, a.m = a.wd, a.$ = a.xd, 0 < a.s.ua && $b(a.s.vb, a.s.Wa);else if (l.h) break a;else null != g && g(a, h > f ? f : h), a.a = 0, a.$ = n - c; 20801 return 1; 20802 } 20803 20804 a.a = 3; 20805 return 0; 20806 } 20807 20808 function Ac(a) { 20809 x(null != a); 20810 a.vc = null; 20811 a.yc = null; 20812 a.Ya = null; 20813 var b = a.Wa; 20814 null != b && (b.X = null); 20815 a.vb = null; 20816 x(null != a); 20817 } 20818 20819 function Bc() { 20820 var a = new je(); 20821 if (null == a) return null; 20822 a.a = 0; 20823 a.xb = Cc; 20824 gb("Predictor", "VP8LPredictors"); 20825 gb("Predictor", "VP8LPredictors_C"); 20826 gb("PredictorAdd", "VP8LPredictorsAdd"); 20827 gb("PredictorAdd", "VP8LPredictorsAdd_C"); 20828 pc = Kd; 20829 Fb = Ld; 20830 sc = Md; 20831 Gb = Nd; 20832 Hb = Od; 20833 xc = Pd; 20834 uc = Qd; 20835 self.VP8LMapColor32b = ke; 20836 self.VP8LMapColor8b = le; 20837 return a; 20838 } 20839 20840 function rb(a, b, c, d, e) { 20841 var f = 1, 20842 g = [a], 20843 h = [b], 20844 k = d.m, 20845 l = d.s, 20846 m = null, 20847 n = 0; 20848 20849 a: for (;;) { 20850 if (c) for (; f && D(k, 1);) { 20851 var r = g, 20852 q = h, 20853 t = d, 20854 v = 1, 20855 p = t.m, 20856 u = t.gc[t.ab], 20857 w = D(p, 2); 20858 if (t.Oc & 1 << w) f = 0;else { 20859 t.Oc |= 1 << w; 20860 u.hc = w; 20861 u.Ea = r[0]; 20862 u.nc = q[0]; 20863 u.K = [null]; 20864 ++t.ab; 20865 x(4 >= t.ab); 20866 20867 switch (w) { 20868 case 0: 20869 case 1: 20870 u.b = D(p, 3) + 2; 20871 v = rb(xa(u.Ea, u.b), xa(u.nc, u.b), 0, t, u.K); 20872 u.K = u.K[0]; 20873 break; 20874 20875 case 3: 20876 var y = D(p, 8) + 1, 20877 A = 16 < y ? 0 : 4 < y ? 1 : 2 < y ? 2 : 3; 20878 r[0] = xa(u.Ea, A); 20879 u.b = A; 20880 var v = rb(y, 1, 0, t, u.K), 20881 E; 20882 20883 if (E = v) { 20884 var B, 20885 C = y, 20886 N = u, 20887 z = 1 << (8 >> N.b), 20888 Q = V(z); 20889 if (null == Q) E = 0;else { 20890 var S = N.K[0], 20891 K = N.w; 20892 Q[0] = N.K[0][0]; 20893 20894 for (B = 1; B < 1 * C; ++B) { 20895 Q[B] = yb(S[K + B], Q[B - 1]); 20896 } 20897 20898 for (; B < 4 * z; ++B) { 20899 Q[B] = 0; 20900 } 20901 20902 N.K[0] = null; 20903 N.K[0] = Q; 20904 E = 1; 20905 } 20906 } 20907 20908 v = E; 20909 break; 20910 20911 case 2: 20912 break; 20913 20914 default: 20915 x(0); 20916 } 20917 20918 f = v; 20919 } 20920 } 20921 g = g[0]; 20922 h = h[0]; 20923 20924 if (f && D(k, 1) && (n = D(k, 4), f = 1 <= n && 11 >= n, !f)) { 20925 d.a = 3; 20926 break a; 20927 } 20928 20929 var H; 20930 if (H = f) b: { 20931 var F = d, 20932 G = g, 20933 L = h, 20934 J = n, 20935 T = c, 20936 Da, 20937 ba, 20938 X = F.m, 20939 R = F.s, 20940 P = [null], 20941 U, 20942 W = 1, 20943 aa = 0, 20944 na = me[J]; 20945 20946 c: for (;;) { 20947 if (T && D(X, 1)) { 20948 var ca = D(X, 3) + 2, 20949 ga = xa(G, ca), 20950 ka = xa(L, ca), 20951 qa = ga * ka; 20952 if (!rb(ga, ka, 0, F, P)) break c; 20953 P = P[0]; 20954 R.xc = ca; 20955 20956 for (Da = 0; Da < qa; ++Da) { 20957 var ia = P[Da] >> 8 & 65535; 20958 P[Da] = ia; 20959 ia >= W && (W = ia + 1); 20960 } 20961 } 20962 20963 if (X.h) break c; 20964 20965 for (ba = 0; 5 > ba; ++ba) { 20966 var Y = Dc[ba]; 20967 !ba && 0 < J && (Y += 1 << J); 20968 aa < Y && (aa = Y); 20969 } 20970 20971 var ma = wa(W * na, O); 20972 var ua = W, 20973 va = wa(ua, Ub); 20974 if (null == va) var la = null;else x(65536 >= ua), la = va; 20975 var ha = V(aa); 20976 20977 if (null == la || null == ha || null == ma) { 20978 F.a = 1; 20979 break c; 20980 } 20981 20982 var pa = ma; 20983 20984 for (Da = U = 0; Da < W; ++Da) { 20985 var ja = la[Da], 20986 da = ja.G, 20987 ea = ja.H, 20988 Fa = 0, 20989 ra = 1, 20990 Ha = 0; 20991 20992 for (ba = 0; 5 > ba; ++ba) { 20993 Y = Dc[ba]; 20994 da[ba] = pa; 20995 ea[ba] = U; 20996 !ba && 0 < J && (Y += 1 << J); 20997 20998 d: { 20999 var sa, 21000 za = Y, 21001 ta = F, 21002 oa = ha, 21003 db = pa, 21004 eb = U, 21005 Ia = 0, 21006 Ka = ta.m, 21007 fb = D(Ka, 1); 21008 M(oa, 0, 0, za); 21009 21010 if (fb) { 21011 var gb = D(Ka, 1) + 1, 21012 hb = D(Ka, 1), 21013 Ja = D(Ka, 0 == hb ? 1 : 8); 21014 oa[Ja] = 1; 21015 2 == gb && (Ja = D(Ka, 8), oa[Ja] = 1); 21016 var ya = 1; 21017 } else { 21018 var Ua = V(19), 21019 Va = D(Ka, 4) + 4; 21020 21021 if (19 < Va) { 21022 ta.a = 3; 21023 var Aa = 0; 21024 break d; 21025 } 21026 21027 for (sa = 0; sa < Va; ++sa) { 21028 Ua[ne[sa]] = D(Ka, 3); 21029 } 21030 21031 var Ba = void 0, 21032 sb = void 0, 21033 Wa = ta, 21034 ib = Ua, 21035 Ca = za, 21036 Xa = oa, 21037 Oa = 0, 21038 La = Wa.m, 21039 Ya = 8, 21040 Za = wa(128, O); 21041 21042 e: for (;;) { 21043 if (!Z(Za, 0, 7, ib, 19)) break e; 21044 21045 if (D(La, 1)) { 21046 var kb = 2 + 2 * D(La, 3), 21047 Ba = 2 + D(La, kb); 21048 if (Ba > Ca) break e; 21049 } else Ba = Ca; 21050 21051 for (sb = 0; sb < Ca && Ba--;) { 21052 Sa(La); 21053 var $a = Za[0 + (pb(La) & 127)]; 21054 qb(La, La.u + $a.g); 21055 var jb = $a.value; 21056 if (16 > jb) Xa[sb++] = jb, 0 != jb && (Ya = jb);else { 21057 var lb = 16 == jb, 21058 ab = jb - 16, 21059 mb = oe[ab], 21060 bb = D(La, pe[ab]) + mb; 21061 if (sb + bb > Ca) break e;else for (var nb = lb ? Ya : 0; 0 < bb--;) { 21062 Xa[sb++] = nb; 21063 } 21064 } 21065 } 21066 21067 Oa = 1; 21068 break e; 21069 } 21070 21071 Oa || (Wa.a = 3); 21072 ya = Oa; 21073 } 21074 21075 (ya = ya && !Ka.h) && (Ia = Z(db, eb, 8, oa, za)); 21076 ya && 0 != Ia ? Aa = Ia : (ta.a = 3, Aa = 0); 21077 } 21078 21079 if (0 == Aa) break c; 21080 ra && 1 == qe[ba] && (ra = 0 == pa[U].g); 21081 Fa += pa[U].g; 21082 U += Aa; 21083 21084 if (3 >= ba) { 21085 var Pa = ha[0], 21086 tb; 21087 21088 for (tb = 1; tb < Y; ++tb) { 21089 ha[tb] > Pa && (Pa = ha[tb]); 21090 } 21091 21092 Ha += Pa; 21093 } 21094 } 21095 21096 ja.nd = ra; 21097 ja.Qb = 0; 21098 ra && (ja.qb = (da[3][ea[3] + 0].value << 24 | da[1][ea[1] + 0].value << 16 | da[2][ea[2] + 0].value) >>> 0, 0 == Fa && 256 > da[0][ea[0] + 0].value && (ja.Qb = 1, ja.qb += da[0][ea[0] + 0].value << 8)); 21099 ja.jc = !ja.Qb && 6 > Ha; 21100 21101 if (ja.jc) { 21102 var Ga, 21103 Ea = ja; 21104 21105 for (Ga = 0; Ga < xb; ++Ga) { 21106 var Ma = Ga, 21107 Na = Ea.pd[Ma], 21108 vb = Ea.G[0][Ea.H[0] + Ma]; 21109 256 <= vb.value ? (Na.g = vb.g + 256, Na.value = vb.value) : (Na.g = 0, Na.value = 0, Ma >>= ub(vb, 8, Na), Ma >>= ub(Ea.G[1][Ea.H[1] + Ma], 16, Na), Ma >>= ub(Ea.G[2][Ea.H[2] + Ma], 0, Na), ub(Ea.G[3][Ea.H[3] + Ma], 24, Na)); 21110 } 21111 } 21112 } 21113 21114 R.vc = P; 21115 R.Wb = W; 21116 R.Ya = la; 21117 R.yc = ma; 21118 H = 1; 21119 break b; 21120 } 21121 21122 H = 0; 21123 } 21124 f = H; 21125 21126 if (!f) { 21127 d.a = 3; 21128 break a; 21129 } 21130 21131 if (0 < n) { 21132 if (l.ua = 1 << n, !Zb(l.Wa, n)) { 21133 d.a = 1; 21134 f = 0; 21135 break a; 21136 } 21137 } else l.ua = 0; 21138 21139 var Qa = d, 21140 cb = g, 21141 ob = h, 21142 Ra = Qa.s, 21143 Ta = Ra.xc; 21144 Qa.c = cb; 21145 Qa.i = ob; 21146 Ra.md = xa(cb, Ta); 21147 Ra.wc = 0 == Ta ? -1 : (1 << Ta) - 1; 21148 21149 if (c) { 21150 d.xb = re; 21151 break a; 21152 } 21153 21154 m = V(g * h); 21155 21156 if (null == m) { 21157 d.a = 1; 21158 f = 0; 21159 break a; 21160 } 21161 21162 f = (f = Jb(d, m, 0, g, h, h, null)) && !k.h; 21163 break a; 21164 } 21165 21166 f ? (null != e ? e[0] = m : (x(null == m), x(c)), d.$ = 0, c || Ac(l)) : Ac(l); 21167 return f; 21168 } 21169 21170 function Ec(a, b) { 21171 var c = a.c * a.i, 21172 d = c + b + 16 * b; 21173 x(a.c <= b); 21174 a.V = V(d); 21175 if (null == a.V) return a.Ta = null, a.Ua = 0, a.a = 1, 0; 21176 a.Ta = a.V; 21177 a.Ua = a.Ba + c + b; 21178 return 1; 21179 } 21180 21181 function se(a, b) { 21182 var c = a.C, 21183 d = b - c, 21184 e = a.V, 21185 f = a.Ba + a.c * c; 21186 21187 for (x(b <= a.l.o); 0 < d;) { 21188 var g = 16 < d ? 16 : d, 21189 h = a.l.ma, 21190 k = a.l.width, 21191 l = k * g, 21192 m = h.ca, 21193 n = h.tb + k * c, 21194 r = a.Ta, 21195 q = a.Ua; 21196 oc(a, g, e, f); 21197 Fc(r, q, m, n, l); 21198 zc(h, c, c + g, m, n, k); 21199 d -= g; 21200 e += g * a.c; 21201 c += g; 21202 } 21203 21204 x(c == b); 21205 a.C = a.Ma = b; 21206 } 21207 21208 function te(a, b) { 21209 var c = [0], 21210 d = [0], 21211 e = [0]; 21212 21213 a: for (;;) { 21214 if (null == a) return 0; 21215 if (null == b) return a.a = 2, 0; 21216 a.l = b; 21217 a.a = 0; 21218 cb(a.m, b.data, b.w, b.ha); 21219 21220 if (!mc(a.m, c, d, e)) { 21221 a.a = 3; 21222 break a; 21223 } 21224 21225 a.xb = Cc; 21226 b.width = c[0]; 21227 b.height = d[0]; 21228 if (!rb(c[0], d[0], 1, a, null)) break a; 21229 return 1; 21230 } 21231 21232 x(0 != a.a); 21233 return 0; 21234 } 21235 21236 function ue() { 21237 this.ub = this.yd = this.td = this.Rb = 0; 21238 } 21239 21240 function ve() { 21241 this.Kd = this.Ld = this.Ud = this.Td = this.i = this.c = 0; 21242 } 21243 21244 function we() { 21245 this.Fb = this.Bb = this.Cb = 0; 21246 this.Zb = V(4); 21247 this.Lb = V(4); 21248 } 21249 21250 function Gc() { 21251 this.Yb = wb(); 21252 } 21253 21254 function xe() { 21255 this.jb = V(3); 21256 this.Wc = Ed([4, 8], Gc); 21257 this.Xc = Ed([4, 17], Gc); 21258 } 21259 21260 function ye() { 21261 this.Pc = this.wb = this.Tb = this.zd = 0; 21262 this.vd = new V(4); 21263 this.od = new V(4); 21264 } 21265 21266 function Xa() { 21267 this.ld = this.La = this.dd = this.tc = 0; 21268 } 21269 21270 function Hc() { 21271 this.Na = this.la = 0; 21272 } 21273 21274 function ze() { 21275 this.Sc = [0, 0]; 21276 this.Eb = [0, 0]; 21277 this.Qc = [0, 0]; 21278 this.ia = this.lc = 0; 21279 } 21280 21281 function Kb() { 21282 this.ad = V(384); 21283 this.Za = 0; 21284 this.Ob = V(16); 21285 this.$b = this.Ad = this.ia = this.Gc = this.Hc = this.Dd = 0; 21286 } 21287 21288 function Ae() { 21289 this.uc = this.M = this.Nb = 0; 21290 this.wa = Array(new Xa()); 21291 this.Y = 0; 21292 this.ya = Array(new Kb()); 21293 this.aa = 0; 21294 this.l = new Oa(); 21295 } 21296 21297 function Ic() { 21298 this.y = V(16); 21299 this.f = V(8); 21300 this.ea = V(8); 21301 } 21302 21303 function Be() { 21304 this.cb = this.a = 0; 21305 this.sc = ""; 21306 this.m = new Wb(); 21307 this.Od = new ue(); 21308 this.Kc = new ve(); 21309 this.ed = new ye(); 21310 this.Qa = new we(); 21311 this.Ic = this.$c = this.Aa = 0; 21312 this.D = new Ae(); 21313 this.Xb = this.Va = this.Hb = this.zb = this.yb = this.Ub = this.za = 0; 21314 this.Jc = wa(8, Wb); 21315 this.ia = 0; 21316 this.pb = wa(4, ze); 21317 this.Pa = new xe(); 21318 this.Bd = this.kc = 0; 21319 this.Ac = []; 21320 this.Bc = 0; 21321 this.zc = [0, 0, 0, 0]; 21322 this.Gd = Array(new Ic()); 21323 this.Hd = 0; 21324 this.rb = Array(new Hc()); 21325 this.sb = 0; 21326 this.wa = Array(new Xa()); 21327 this.Y = 0; 21328 this.oc = []; 21329 this.pc = 0; 21330 this.sa = []; 21331 this.ta = 0; 21332 this.qa = []; 21333 this.ra = 0; 21334 this.Ha = []; 21335 this.B = this.R = this.Ia = 0; 21336 this.Ec = []; 21337 this.M = this.ja = this.Vb = this.Fc = 0; 21338 this.ya = Array(new Kb()); 21339 this.L = this.aa = 0; 21340 this.gd = Ed([4, 2], Xa); 21341 this.ga = null; 21342 this.Fa = []; 21343 this.Cc = this.qc = this.P = 0; 21344 this.Gb = []; 21345 this.Uc = 0; 21346 this.mb = []; 21347 this.nb = 0; 21348 this.rc = []; 21349 this.Ga = this.Vc = 0; 21350 } 21351 21352 function ga(a, b) { 21353 return 0 > a ? 0 : a > b ? b : a; 21354 } 21355 21356 function Oa() { 21357 this.T = this.U = this.ka = this.height = this.width = 0; 21358 this.y = []; 21359 this.f = []; 21360 this.ea = []; 21361 this.Rc = this.fa = this.W = this.N = this.O = 0; 21362 this.ma = "void"; 21363 this.put = "VP8IoPutHook"; 21364 this.ac = "VP8IoSetupHook"; 21365 this.bc = "VP8IoTeardownHook"; 21366 this.ha = this.Kb = 0; 21367 this.data = []; 21368 this.hb = this.ib = this.da = this.o = this.j = this.va = this.v = this.Da = this.ob = this.w = 0; 21369 this.F = []; 21370 this.J = 0; 21371 } 21372 21373 function Ce() { 21374 var a = new Be(); 21375 null != a && (a.a = 0, a.sc = "OK", a.cb = 0, a.Xb = 0, oa || (oa = De)); 21376 return a; 21377 } 21378 21379 function T(a, b, c) { 21380 0 == a.a && (a.a = b, a.sc = c, a.cb = 0); 21381 return 0; 21382 } 21383 21384 function Jc(a, b, c) { 21385 return 3 <= c && 157 == a[b + 0] && 1 == a[b + 1] && 42 == a[b + 2]; 21386 } 21387 21388 function Kc(a, b) { 21389 if (null == a) return 0; 21390 a.a = 0; 21391 a.sc = "OK"; 21392 if (null == b) return T(a, 2, "null VP8Io passed to VP8GetHeaders()"); 21393 var c = b.data; 21394 var d = b.w; 21395 var e = b.ha; 21396 if (4 > e) return T(a, 7, "Truncated header."); 21397 var f = c[d + 0] | c[d + 1] << 8 | c[d + 2] << 16; 21398 var g = a.Od; 21399 g.Rb = !(f & 1); 21400 g.td = f >> 1 & 7; 21401 g.yd = f >> 4 & 1; 21402 g.ub = f >> 5; 21403 if (3 < g.td) return T(a, 3, "Incorrect keyframe parameters."); 21404 if (!g.yd) return T(a, 4, "Frame not displayable."); 21405 d += 3; 21406 e -= 3; 21407 var h = a.Kc; 21408 21409 if (g.Rb) { 21410 if (7 > e) return T(a, 7, "cannot parse picture header"); 21411 if (!Jc(c, d, e)) return T(a, 3, "Bad code word"); 21412 h.c = (c[d + 4] << 8 | c[d + 3]) & 16383; 21413 h.Td = c[d + 4] >> 6; 21414 h.i = (c[d + 6] << 8 | c[d + 5]) & 16383; 21415 h.Ud = c[d + 6] >> 6; 21416 d += 7; 21417 e -= 7; 21418 a.za = h.c + 15 >> 4; 21419 a.Ub = h.i + 15 >> 4; 21420 b.width = h.c; 21421 b.height = h.i; 21422 b.Da = 0; 21423 b.j = 0; 21424 b.v = 0; 21425 b.va = b.width; 21426 b.o = b.height; 21427 b.da = 0; 21428 b.ib = b.width; 21429 b.hb = b.height; 21430 b.U = b.width; 21431 b.T = b.height; 21432 f = a.Pa; 21433 M(f.jb, 0, 255, f.jb.length); 21434 f = a.Qa; 21435 x(null != f); 21436 f.Cb = 0; 21437 f.Bb = 0; 21438 f.Fb = 1; 21439 M(f.Zb, 0, 0, f.Zb.length); 21440 M(f.Lb, 0, 0, f.Lb); 21441 } 21442 21443 if (g.ub > e) return T(a, 7, "bad partition length"); 21444 f = a.m; 21445 ma(f, c, d, g.ub); 21446 d += g.ub; 21447 e -= g.ub; 21448 g.Rb && (h.Ld = G(f), h.Kd = G(f)); 21449 h = a.Qa; 21450 var k = a.Pa, 21451 l; 21452 x(null != f); 21453 x(null != h); 21454 h.Cb = G(f); 21455 21456 if (h.Cb) { 21457 h.Bb = G(f); 21458 21459 if (G(f)) { 21460 h.Fb = G(f); 21461 21462 for (l = 0; 4 > l; ++l) { 21463 h.Zb[l] = G(f) ? ca(f, 7) : 0; 21464 } 21465 21466 for (l = 0; 4 > l; ++l) { 21467 h.Lb[l] = G(f) ? ca(f, 6) : 0; 21468 } 21469 } 21470 21471 if (h.Bb) for (l = 0; 3 > l; ++l) { 21472 k.jb[l] = G(f) ? na(f, 8) : 255; 21473 } 21474 } else h.Bb = 0; 21475 21476 if (f.Ka) return T(a, 3, "cannot parse segment header"); 21477 h = a.ed; 21478 h.zd = G(f); 21479 h.Tb = na(f, 6); 21480 h.wb = na(f, 3); 21481 h.Pc = G(f); 21482 21483 if (h.Pc && G(f)) { 21484 for (k = 0; 4 > k; ++k) { 21485 G(f) && (h.vd[k] = ca(f, 6)); 21486 } 21487 21488 for (k = 0; 4 > k; ++k) { 21489 G(f) && (h.od[k] = ca(f, 6)); 21490 } 21491 } 21492 21493 a.L = 0 == h.Tb ? 0 : h.zd ? 1 : 2; 21494 if (f.Ka) return T(a, 3, "cannot parse filter header"); 21495 l = d; 21496 var m = e; 21497 e = l; 21498 d = l + m; 21499 h = m; 21500 a.Xb = (1 << na(a.m, 2)) - 1; 21501 k = a.Xb; 21502 if (m < 3 * k) c = 7;else { 21503 l += 3 * k; 21504 h -= 3 * k; 21505 21506 for (m = 0; m < k; ++m) { 21507 var n = c[e + 0] | c[e + 1] << 8 | c[e + 2] << 16; 21508 n > h && (n = h); 21509 ma(a.Jc[+m], c, l, n); 21510 l += n; 21511 h -= n; 21512 e += 3; 21513 } 21514 21515 ma(a.Jc[+k], c, l, h); 21516 c = l < d ? 0 : 5; 21517 } 21518 if (0 != c) return T(a, c, "cannot parse partitions"); 21519 l = a.m; 21520 c = na(l, 7); 21521 e = G(l) ? ca(l, 4) : 0; 21522 d = G(l) ? ca(l, 4) : 0; 21523 h = G(l) ? ca(l, 4) : 0; 21524 k = G(l) ? ca(l, 4) : 0; 21525 l = G(l) ? ca(l, 4) : 0; 21526 m = a.Qa; 21527 21528 for (n = 0; 4 > n; ++n) { 21529 if (m.Cb) { 21530 var r = m.Zb[n]; 21531 m.Fb || (r += c); 21532 } else if (0 < n) { 21533 a.pb[n] = a.pb[0]; 21534 continue; 21535 } else r = c; 21536 21537 var q = a.pb[n]; 21538 q.Sc[0] = Lb[ga(r + e, 127)]; 21539 q.Sc[1] = Mb[ga(r + 0, 127)]; 21540 q.Eb[0] = 2 * Lb[ga(r + d, 127)]; 21541 q.Eb[1] = 101581 * Mb[ga(r + h, 127)] >> 16; 21542 8 > q.Eb[1] && (q.Eb[1] = 8); 21543 q.Qc[0] = Lb[ga(r + k, 117)]; 21544 q.Qc[1] = Mb[ga(r + l, 127)]; 21545 q.lc = r + l; 21546 } 21547 21548 if (!g.Rb) return T(a, 4, "Not a key frame."); 21549 G(f); 21550 g = a.Pa; 21551 21552 for (c = 0; 4 > c; ++c) { 21553 for (e = 0; 8 > e; ++e) { 21554 for (d = 0; 3 > d; ++d) { 21555 for (h = 0; 11 > h; ++h) { 21556 k = K(f, Ee[c][e][d][h]) ? na(f, 8) : Fe[c][e][d][h], g.Wc[c][e].Yb[d][h] = k; 21557 } 21558 } 21559 } 21560 21561 for (e = 0; 17 > e; ++e) { 21562 g.Xc[c][e] = g.Wc[c][Ge[e]]; 21563 } 21564 } 21565 21566 a.kc = G(f); 21567 a.kc && (a.Bd = na(f, 8)); 21568 return a.cb = 1; 21569 } 21570 21571 function De(a, b, c, d, e, f, g) { 21572 var h = b[e].Yb[c]; 21573 21574 for (c = 0; 16 > e; ++e) { 21575 if (!K(a, h[c + 0])) return e; 21576 21577 for (; !K(a, h[c + 1]);) { 21578 if (h = b[++e].Yb[0], c = 0, 16 == e) return 16; 21579 } 21580 21581 var k = b[e + 1].Yb; 21582 21583 if (K(a, h[c + 2])) { 21584 var l = a, 21585 m = h, 21586 n = c; 21587 var r = 0; 21588 if (K(l, m[n + 3])) { 21589 if (K(l, m[n + 6])) { 21590 h = 0; 21591 r = K(l, m[n + 8]); 21592 m = K(l, m[n + 9 + r]); 21593 n = 2 * r + m; 21594 r = 0; 21595 21596 for (m = He[n]; m[h]; ++h) { 21597 r += r + K(l, m[h]); 21598 } 21599 21600 r += 3 + (8 << n); 21601 } else K(l, m[n + 7]) ? (r = 7 + 2 * K(l, 165), r += K(l, 145)) : r = 5 + K(l, 159); 21602 } else K(l, m[n + 4]) ? r = 3 + K(l, m[n + 5]) : r = 2; 21603 h = k[2]; 21604 } else r = 1, h = k[1]; 21605 21606 k = g + Ie[e]; 21607 l = a; 21608 0 > l.b && Qa(l); 21609 var m = l.b, 21610 n = l.Ca >> 1, 21611 q = n - (l.I >> m) >> 31; 21612 --l.b; 21613 l.Ca += q; 21614 l.Ca |= 1; 21615 l.I -= (n + 1 & q) << m; 21616 f[k] = ((r ^ q) - q) * d[(0 < e) + 0]; 21617 } 21618 21619 return 16; 21620 } 21621 21622 function Lc(a) { 21623 var b = a.rb[a.sb - 1]; 21624 b.la = 0; 21625 b.Na = 0; 21626 M(a.zc, 0, 0, a.zc.length); 21627 a.ja = 0; 21628 } 21629 21630 function Je(a, b) { 21631 for (a.M = 0; a.M < a.Va; ++a.M) { 21632 var c = a.Jc[a.M & a.Xb], 21633 d = a.m, 21634 e = a, 21635 f; 21636 21637 for (f = 0; f < e.za; ++f) { 21638 var g = d; 21639 var h = e; 21640 var k = h.Ac, 21641 l = h.Bc + 4 * f, 21642 m = h.zc, 21643 n = h.ya[h.aa + f]; 21644 h.Qa.Bb ? n.$b = K(g, h.Pa.jb[0]) ? 2 + K(g, h.Pa.jb[2]) : K(g, h.Pa.jb[1]) : n.$b = 0; 21645 h.kc && (n.Ad = K(g, h.Bd)); 21646 n.Za = !K(g, 145) + 0; 21647 21648 if (n.Za) { 21649 var r = n.Ob, 21650 q = 0; 21651 21652 for (h = 0; 4 > h; ++h) { 21653 var t = m[0 + h]; 21654 var v; 21655 21656 for (v = 0; 4 > v; ++v) { 21657 t = Ke[k[l + v]][t]; 21658 21659 for (var p = Mc[K(g, t[0])]; 0 < p;) { 21660 p = Mc[2 * p + K(g, t[p])]; 21661 } 21662 21663 t = -p; 21664 k[l + v] = t; 21665 } 21666 21667 I(r, q, k, l, 4); 21668 q += 4; 21669 m[0 + h] = t; 21670 } 21671 } else t = K(g, 156) ? K(g, 128) ? 1 : 3 : K(g, 163) ? 2 : 0, n.Ob[0] = t, M(k, l, t, 4), M(m, 0, t, 4); 21672 21673 n.Dd = K(g, 142) ? K(g, 114) ? K(g, 183) ? 1 : 3 : 2 : 0; 21674 } 21675 21676 if (e.m.Ka) return T(a, 7, "Premature end-of-partition0 encountered."); 21677 21678 for (; a.ja < a.za; ++a.ja) { 21679 d = a; 21680 e = c; 21681 g = d.rb[d.sb - 1]; 21682 k = d.rb[d.sb + d.ja]; 21683 f = d.ya[d.aa + d.ja]; 21684 if (l = d.kc ? f.Ad : 0) g.la = k.la = 0, f.Za || (g.Na = k.Na = 0), f.Hc = 0, f.Gc = 0, f.ia = 0;else { 21685 var u, 21686 w, 21687 g = k, 21688 k = e, 21689 l = d.Pa.Xc, 21690 m = d.ya[d.aa + d.ja], 21691 n = d.pb[m.$b]; 21692 h = m.ad; 21693 r = 0; 21694 q = d.rb[d.sb - 1]; 21695 t = v = 0; 21696 M(h, r, 0, 384); 21697 21698 if (m.Za) { 21699 var y = 0; 21700 var A = l[3]; 21701 } else { 21702 p = V(16); 21703 var E = g.Na + q.Na; 21704 E = oa(k, l[1], E, n.Eb, 0, p, 0); 21705 g.Na = q.Na = (0 < E) + 0; 21706 if (1 < E) Nc(p, 0, h, r);else { 21707 var B = p[0] + 3 >> 3; 21708 21709 for (p = 0; 256 > p; p += 16) { 21710 h[r + p] = B; 21711 } 21712 } 21713 y = 1; 21714 A = l[0]; 21715 } 21716 21717 var C = g.la & 15; 21718 var N = q.la & 15; 21719 21720 for (p = 0; 4 > p; ++p) { 21721 var z = N & 1; 21722 21723 for (B = w = 0; 4 > B; ++B) { 21724 E = z + (C & 1), E = oa(k, A, E, n.Sc, y, h, r), z = E > y, C = C >> 1 | z << 7, w = w << 2 | (3 < E ? 3 : 1 < E ? 2 : 0 != h[r + 0]), r += 16; 21725 } 21726 21727 C >>= 4; 21728 N = N >> 1 | z << 7; 21729 v = (v << 8 | w) >>> 0; 21730 } 21731 21732 A = C; 21733 y = N >> 4; 21734 21735 for (u = 0; 4 > u; u += 2) { 21736 w = 0; 21737 C = g.la >> 4 + u; 21738 N = q.la >> 4 + u; 21739 21740 for (p = 0; 2 > p; ++p) { 21741 z = N & 1; 21742 21743 for (B = 0; 2 > B; ++B) { 21744 E = z + (C & 1), E = oa(k, l[2], E, n.Qc, 0, h, r), z = 0 < E, C = C >> 1 | z << 3, w = w << 2 | (3 < E ? 3 : 1 < E ? 2 : 0 != h[r + 0]), r += 16; 21745 } 21746 21747 C >>= 2; 21748 N = N >> 1 | z << 5; 21749 } 21750 21751 t |= w << 4 * u; 21752 A |= C << 4 << u; 21753 y |= (N & 240) << u; 21754 } 21755 21756 g.la = A; 21757 q.la = y; 21758 m.Hc = v; 21759 m.Gc = t; 21760 m.ia = t & 43690 ? 0 : n.ia; 21761 l = !(v | t); 21762 } 21763 0 < d.L && (d.wa[d.Y + d.ja] = d.gd[f.$b][f.Za], d.wa[d.Y + d.ja].La |= !l); 21764 if (e.Ka) return T(a, 7, "Premature end-of-file encountered."); 21765 } 21766 21767 Lc(a); 21768 c = a; 21769 d = b; 21770 e = 1; 21771 f = c.D; 21772 g = 0 < c.L && c.M >= c.zb && c.M <= c.Va; 21773 if (0 == c.Aa) a: { 21774 f.M = c.M, f.uc = g, Oc(c, f), e = 1; 21775 w = c.D; 21776 f = w.Nb; 21777 t = Ya[c.L]; 21778 g = t * c.R; 21779 k = t / 2 * c.B; 21780 p = 16 * f * c.R; 21781 B = 8 * f * c.B; 21782 l = c.sa; 21783 m = c.ta - g + p; 21784 n = c.qa; 21785 h = c.ra - k + B; 21786 r = c.Ha; 21787 q = c.Ia - k + B; 21788 C = w.M; 21789 N = 0 == C; 21790 v = C >= c.Va - 1; 21791 2 == c.Aa && Oc(c, w); 21792 if (w.uc) for (E = c, z = E.D.M, x(E.D.uc), w = E.yb; w < E.Hb; ++w) { 21793 var Q = E; 21794 y = w; 21795 A = z; 21796 var S = Q.D, 21797 D = S.Nb; 21798 u = Q.R; 21799 var S = S.wa[S.Y + y], 21800 F = Q.sa, 21801 H = Q.ta + 16 * D * u + 16 * y, 21802 J = S.dd, 21803 G = S.tc; 21804 if (0 != G) if (x(3 <= G), 1 == Q.L) 0 < y && Pc(F, H, u, G + 4), S.La && Qc(F, H, u, G), 0 < A && Rc(F, H, u, G + 4), S.La && Sc(F, H, u, G);else { 21805 var L = Q.B, 21806 O = Q.qa, 21807 P = Q.ra + 8 * D * L + 8 * y, 21808 R = Q.Ha, 21809 Q = Q.Ia + 8 * D * L + 8 * y, 21810 D = S.ld; 21811 0 < y && (Tc(F, H, u, G + 4, J, D), Uc(O, P, R, Q, L, G + 4, J, D)); 21812 S.La && (Vc(F, H, u, G, J, D), Wc(O, P, R, Q, L, G, J, D)); 21813 0 < A && (Xc(F, H, u, G + 4, J, D), Yc(O, P, R, Q, L, G + 4, J, D)); 21814 S.La && (Zc(F, H, u, G, J, D), $c(O, P, R, Q, L, G, J, D)); 21815 } 21816 } 21817 c.ia && alert("todo:DitherRow"); 21818 21819 if (null != d.put) { 21820 w = 16 * C; 21821 C = 16 * (C + 1); 21822 N ? (d.y = c.sa, d.O = c.ta + p, d.f = c.qa, d.N = c.ra + B, d.ea = c.Ha, d.W = c.Ia + B) : (w -= t, d.y = l, d.O = m, d.f = n, d.N = h, d.ea = r, d.W = q); 21823 v || (C -= t); 21824 C > d.o && (C = d.o); 21825 d.F = null; 21826 d.J = null; 21827 21828 if (null != c.Fa && 0 < c.Fa.length && w < C && (d.J = Le(c, d, w, C - w), d.F = c.mb, null == d.F && 0 == d.F.length)) { 21829 e = T(c, 3, "Could not decode alpha data."); 21830 break a; 21831 } 21832 21833 w < d.j && (t = d.j - w, w = d.j, x(!(t & 1)), d.O += c.R * t, d.N += c.B * (t >> 1), d.W += c.B * (t >> 1), null != d.F && (d.J += d.width * t)); 21834 w < C && (d.O += d.v, d.N += d.v >> 1, d.W += d.v >> 1, null != d.F && (d.J += d.v), d.ka = w - d.j, d.U = d.va - d.v, d.T = C - w, e = d.put(d)); 21835 } 21836 21837 f + 1 != c.Ic || v || (I(c.sa, c.ta - g, l, m + 16 * c.R, g), I(c.qa, c.ra - k, n, h + 8 * c.B, k), I(c.Ha, c.Ia - k, r, q + 8 * c.B, k)); 21838 } 21839 if (!e) return T(a, 6, "Output aborted."); 21840 } 21841 21842 return 1; 21843 } 21844 21845 function Me(a, b) { 21846 if (null == a) return 0; 21847 if (null == b) return T(a, 2, "NULL VP8Io parameter in VP8Decode()."); 21848 if (!a.cb && !Kc(a, b)) return 0; 21849 x(a.cb); 21850 21851 if (null == b.ac || b.ac(b)) { 21852 b.ob && (a.L = 0); 21853 var c = Ya[a.L]; 21854 2 == a.L ? (a.yb = 0, a.zb = 0) : (a.yb = b.v - c >> 4, a.zb = b.j - c >> 4, 0 > a.yb && (a.yb = 0), 0 > a.zb && (a.zb = 0)); 21855 a.Va = b.o + 15 + c >> 4; 21856 a.Hb = b.va + 15 + c >> 4; 21857 a.Hb > a.za && (a.Hb = a.za); 21858 a.Va > a.Ub && (a.Va = a.Ub); 21859 21860 if (0 < a.L) { 21861 var d = a.ed; 21862 21863 for (c = 0; 4 > c; ++c) { 21864 var e; 21865 21866 if (a.Qa.Cb) { 21867 var f = a.Qa.Lb[c]; 21868 a.Qa.Fb || (f += d.Tb); 21869 } else f = d.Tb; 21870 21871 for (e = 0; 1 >= e; ++e) { 21872 var g = a.gd[c][e], 21873 h = f; 21874 d.Pc && (h += d.vd[0], e && (h += d.od[0])); 21875 h = 0 > h ? 0 : 63 < h ? 63 : h; 21876 21877 if (0 < h) { 21878 var k = h; 21879 0 < d.wb && (k = 4 < d.wb ? k >> 2 : k >> 1, k > 9 - d.wb && (k = 9 - d.wb)); 21880 1 > k && (k = 1); 21881 g.dd = k; 21882 g.tc = 2 * h + k; 21883 g.ld = 40 <= h ? 2 : 15 <= h ? 1 : 0; 21884 } else g.tc = 0; 21885 21886 g.La = e; 21887 } 21888 } 21889 } 21890 21891 c = 0; 21892 } else T(a, 6, "Frame setup failed"), c = a.a; 21893 21894 if (c = 0 == c) { 21895 if (c) { 21896 a.$c = 0; 21897 0 < a.Aa || (a.Ic = Ne); 21898 21899 b: { 21900 c = a.Ic; 21901 var k = a.za, 21902 d = 4 * k, 21903 l = 32 * k, 21904 m = k + 1, 21905 n = 0 < a.L ? k * (0 < a.Aa ? 2 : 1) : 0, 21906 r = (2 == a.Aa ? 2 : 1) * k; 21907 e = 3 * (16 * c + Ya[a.L]) / 2 * l; 21908 f = null != a.Fa && 0 < a.Fa.length ? a.Kc.c * a.Kc.i : 0; 21909 g = d + 832 + e + f; 21910 if (g != g) c = 0;else { 21911 if (g > a.Vb) { 21912 a.Vb = 0; 21913 a.Ec = V(g); 21914 a.Fc = 0; 21915 21916 if (null == a.Ec) { 21917 c = T(a, 1, "no memory during frame initialization."); 21918 break b; 21919 } 21920 21921 a.Vb = g; 21922 } 21923 21924 g = a.Ec; 21925 h = a.Fc; 21926 a.Ac = g; 21927 a.Bc = h; 21928 h += d; 21929 a.Gd = wa(l, Ic); 21930 a.Hd = 0; 21931 a.rb = wa(m + 1, Hc); 21932 a.sb = 1; 21933 a.wa = n ? wa(n, Xa) : null; 21934 a.Y = 0; 21935 a.D.Nb = 0; 21936 a.D.wa = a.wa; 21937 a.D.Y = a.Y; 21938 0 < a.Aa && (a.D.Y += k); 21939 x(!0); 21940 a.oc = g; 21941 a.pc = h; 21942 h += 832; 21943 a.ya = wa(r, Kb); 21944 a.aa = 0; 21945 a.D.ya = a.ya; 21946 a.D.aa = a.aa; 21947 2 == a.Aa && (a.D.aa += k); 21948 a.R = 16 * k; 21949 a.B = 8 * k; 21950 l = Ya[a.L]; 21951 k = l * a.R; 21952 l = l / 2 * a.B; 21953 a.sa = g; 21954 a.ta = h + k; 21955 a.qa = a.sa; 21956 a.ra = a.ta + 16 * c * a.R + l; 21957 a.Ha = a.qa; 21958 a.Ia = a.ra + 8 * c * a.B + l; 21959 a.$c = 0; 21960 h += e; 21961 a.mb = f ? g : null; 21962 a.nb = f ? h : null; 21963 x(h + f <= a.Fc + a.Vb); 21964 Lc(a); 21965 M(a.Ac, a.Bc, 0, d); 21966 c = 1; 21967 } 21968 } 21969 21970 if (c) { 21971 b.ka = 0; 21972 b.y = a.sa; 21973 b.O = a.ta; 21974 b.f = a.qa; 21975 b.N = a.ra; 21976 b.ea = a.Ha; 21977 b.Vd = a.Ia; 21978 b.fa = a.R; 21979 b.Rc = a.B; 21980 b.F = null; 21981 b.J = 0; 21982 21983 if (!ad) { 21984 for (c = -255; 255 >= c; ++c) { 21985 bd[255 + c] = 0 > c ? -c : c; 21986 } 21987 21988 for (c = -1020; 1020 >= c; ++c) { 21989 cd[1020 + c] = -128 > c ? -128 : 127 < c ? 127 : c; 21990 } 21991 21992 for (c = -112; 112 >= c; ++c) { 21993 dd[112 + c] = -16 > c ? -16 : 15 < c ? 15 : c; 21994 } 21995 21996 for (c = -255; 510 >= c; ++c) { 21997 ed[255 + c] = 0 > c ? 0 : 255 < c ? 255 : c; 21998 } 21999 22000 ad = 1; 22001 } 22002 22003 Nc = Oe; 22004 Za = Pe; 22005 Nb = Qe; 22006 pa = Re; 22007 Ob = Se; 22008 fd = Te; 22009 Xc = Ue; 22010 Tc = Ve; 22011 Yc = We; 22012 Uc = Xe; 22013 Zc = Ye; 22014 Vc = Ze; 22015 $c = $e; 22016 Wc = af; 22017 Rc = gd; 22018 Pc = hd; 22019 Sc = bf; 22020 Qc = cf; 22021 W[0] = df; 22022 W[1] = ef; 22023 W[2] = ff; 22024 W[3] = gf; 22025 W[4] = hf; 22026 W[5] = jf; 22027 W[6] = kf; 22028 W[7] = lf; 22029 W[8] = mf; 22030 W[9] = nf; 22031 Y[0] = of; 22032 Y[1] = pf; 22033 Y[2] = qf; 22034 Y[3] = rf; 22035 Y[4] = sf; 22036 Y[5] = tf; 22037 Y[6] = uf; 22038 ka[0] = vf; 22039 ka[1] = wf; 22040 ka[2] = xf; 22041 ka[3] = yf; 22042 ka[4] = zf; 22043 ka[5] = Af; 22044 ka[6] = Bf; 22045 c = 1; 22046 } else c = 0; 22047 } 22048 22049 c && (c = Je(a, b)); 22050 null != b.bc && b.bc(b); 22051 c &= 1; 22052 } 22053 22054 if (!c) return 0; 22055 a.cb = 0; 22056 return c; 22057 } 22058 22059 function qa(a, b, c, d, e) { 22060 e = a[b + c + 32 * d] + (e >> 3); 22061 a[b + c + 32 * d] = e & -256 ? 0 > e ? 0 : 255 : e; 22062 } 22063 22064 function kb(a, b, c, d, e, f) { 22065 qa(a, b, 0, c, d + e); 22066 qa(a, b, 1, c, d + f); 22067 qa(a, b, 2, c, d - f); 22068 qa(a, b, 3, c, d - e); 22069 } 22070 22071 function da(a) { 22072 return (20091 * a >> 16) + a; 22073 } 22074 22075 function id(a, b, c, d) { 22076 var e = 0, 22077 f; 22078 var g = V(16); 22079 22080 for (f = 0; 4 > f; ++f) { 22081 var h = a[b + 0] + a[b + 8]; 22082 var k = a[b + 0] - a[b + 8]; 22083 var l = (35468 * a[b + 4] >> 16) - da(a[b + 12]); 22084 var m = da(a[b + 4]) + (35468 * a[b + 12] >> 16); 22085 g[e + 0] = h + m; 22086 g[e + 1] = k + l; 22087 g[e + 2] = k - l; 22088 g[e + 3] = h - m; 22089 e += 4; 22090 b++; 22091 } 22092 22093 for (f = e = 0; 4 > f; ++f) { 22094 a = g[e + 0] + 4, h = a + g[e + 8], k = a - g[e + 8], l = (35468 * g[e + 4] >> 16) - da(g[e + 12]), m = da(g[e + 4]) + (35468 * g[e + 12] >> 16), qa(c, d, 0, 0, h + m), qa(c, d, 1, 0, k + l), qa(c, d, 2, 0, k - l), qa(c, d, 3, 0, h - m), e++, d += 32; 22095 } 22096 } 22097 22098 function Te(a, b, c, d) { 22099 var e = a[b + 0] + 4, 22100 f = 35468 * a[b + 4] >> 16, 22101 g = da(a[b + 4]), 22102 h = 35468 * a[b + 1] >> 16; 22103 a = da(a[b + 1]); 22104 kb(c, d, 0, e + g, a, h); 22105 kb(c, d, 1, e + f, a, h); 22106 kb(c, d, 2, e - f, a, h); 22107 kb(c, d, 3, e - g, a, h); 22108 } 22109 22110 function Pe(a, b, c, d, e) { 22111 id(a, b, c, d); 22112 e && id(a, b + 16, c, d + 4); 22113 } 22114 22115 function Qe(a, b, c, d) { 22116 Za(a, b + 0, c, d, 1); 22117 Za(a, b + 32, c, d + 128, 1); 22118 } 22119 22120 function Re(a, b, c, d) { 22121 a = a[b + 0] + 4; 22122 var e; 22123 22124 for (e = 0; 4 > e; ++e) { 22125 for (b = 0; 4 > b; ++b) { 22126 qa(c, d, b, e, a); 22127 } 22128 } 22129 } 22130 22131 function Se(a, b, c, d) { 22132 a[b + 0] && pa(a, b + 0, c, d); 22133 a[b + 16] && pa(a, b + 16, c, d + 4); 22134 a[b + 32] && pa(a, b + 32, c, d + 128); 22135 a[b + 48] && pa(a, b + 48, c, d + 128 + 4); 22136 } 22137 22138 function Oe(a, b, c, d) { 22139 var e = V(16), 22140 f; 22141 22142 for (f = 0; 4 > f; ++f) { 22143 var g = a[b + 0 + f] + a[b + 12 + f]; 22144 var h = a[b + 4 + f] + a[b + 8 + f]; 22145 var k = a[b + 4 + f] - a[b + 8 + f]; 22146 var l = a[b + 0 + f] - a[b + 12 + f]; 22147 e[0 + f] = g + h; 22148 e[8 + f] = g - h; 22149 e[4 + f] = l + k; 22150 e[12 + f] = l - k; 22151 } 22152 22153 for (f = 0; 4 > f; ++f) { 22154 a = e[0 + 4 * f] + 3, g = a + e[3 + 4 * f], h = e[1 + 4 * f] + e[2 + 4 * f], k = e[1 + 4 * f] - e[2 + 4 * f], l = a - e[3 + 4 * f], c[d + 0] = g + h >> 3, c[d + 16] = l + k >> 3, c[d + 32] = g - h >> 3, c[d + 48] = l - k >> 3, d += 64; 22155 } 22156 } 22157 22158 function Pb(a, b, c) { 22159 var d = b - 32, 22160 e = R, 22161 f = 255 - a[d - 1], 22162 g; 22163 22164 for (g = 0; g < c; ++g) { 22165 var h = e, 22166 k = f + a[b - 1], 22167 l; 22168 22169 for (l = 0; l < c; ++l) { 22170 a[b + l] = h[k + a[d + l]]; 22171 } 22172 22173 b += 32; 22174 } 22175 } 22176 22177 function ef(a, b) { 22178 Pb(a, b, 4); 22179 } 22180 22181 function wf(a, b) { 22182 Pb(a, b, 8); 22183 } 22184 22185 function pf(a, b) { 22186 Pb(a, b, 16); 22187 } 22188 22189 function qf(a, b) { 22190 var c; 22191 22192 for (c = 0; 16 > c; ++c) { 22193 I(a, b + 32 * c, a, b - 32, 16); 22194 } 22195 } 22196 22197 function rf(a, b) { 22198 var c; 22199 22200 for (c = 16; 0 < c; --c) { 22201 M(a, b, a[b - 1], 16), b += 32; 22202 } 22203 } 22204 22205 function $a(a, b, c) { 22206 var d; 22207 22208 for (d = 0; 16 > d; ++d) { 22209 M(b, c + 32 * d, a, 16); 22210 } 22211 } 22212 22213 function of(a, b) { 22214 var c = 16, 22215 d; 22216 22217 for (d = 0; 16 > d; ++d) { 22218 c += a[b - 1 + 32 * d] + a[b + d - 32]; 22219 } 22220 22221 $a(c >> 5, a, b); 22222 } 22223 22224 function sf(a, b) { 22225 var c = 8, 22226 d; 22227 22228 for (d = 0; 16 > d; ++d) { 22229 c += a[b - 1 + 32 * d]; 22230 } 22231 22232 $a(c >> 4, a, b); 22233 } 22234 22235 function tf(a, b) { 22236 var c = 8, 22237 d; 22238 22239 for (d = 0; 16 > d; ++d) { 22240 c += a[b + d - 32]; 22241 } 22242 22243 $a(c >> 4, a, b); 22244 } 22245 22246 function uf(a, b) { 22247 $a(128, a, b); 22248 } 22249 22250 function z(a, b, c) { 22251 return a + 2 * b + c + 2 >> 2; 22252 } 22253 22254 function ff(a, b) { 22255 var c = b - 32, 22256 c = new Uint8Array([z(a[c - 1], a[c + 0], a[c + 1]), z(a[c + 0], a[c + 1], a[c + 2]), z(a[c + 1], a[c + 2], a[c + 3]), z(a[c + 2], a[c + 3], a[c + 4])]), 22257 d; 22258 22259 for (d = 0; 4 > d; ++d) { 22260 I(a, b + 32 * d, c, 0, c.length); 22261 } 22262 } 22263 22264 function gf(a, b) { 22265 var c = a[b - 1], 22266 d = a[b - 1 + 32], 22267 e = a[b - 1 + 64], 22268 f = a[b - 1 + 96]; 22269 ra(a, b + 0, 16843009 * z(a[b - 1 - 32], c, d)); 22270 ra(a, b + 32, 16843009 * z(c, d, e)); 22271 ra(a, b + 64, 16843009 * z(d, e, f)); 22272 ra(a, b + 96, 16843009 * z(e, f, f)); 22273 } 22274 22275 function df(a, b) { 22276 var c = 4, 22277 d; 22278 22279 for (d = 0; 4 > d; ++d) { 22280 c += a[b + d - 32] + a[b - 1 + 32 * d]; 22281 } 22282 22283 c >>= 3; 22284 22285 for (d = 0; 4 > d; ++d) { 22286 M(a, b + 32 * d, c, 4); 22287 } 22288 } 22289 22290 function hf(a, b) { 22291 var c = a[b - 1 + 0], 22292 d = a[b - 1 + 32], 22293 e = a[b - 1 + 64], 22294 f = a[b - 1 - 32], 22295 g = a[b + 0 - 32], 22296 h = a[b + 1 - 32], 22297 k = a[b + 2 - 32], 22298 l = a[b + 3 - 32]; 22299 a[b + 0 + 96] = z(d, e, a[b - 1 + 96]); 22300 a[b + 1 + 96] = a[b + 0 + 64] = z(c, d, e); 22301 a[b + 2 + 96] = a[b + 1 + 64] = a[b + 0 + 32] = z(f, c, d); 22302 a[b + 3 + 96] = a[b + 2 + 64] = a[b + 1 + 32] = a[b + 0 + 0] = z(g, f, c); 22303 a[b + 3 + 64] = a[b + 2 + 32] = a[b + 1 + 0] = z(h, g, f); 22304 a[b + 3 + 32] = a[b + 2 + 0] = z(k, h, g); 22305 a[b + 3 + 0] = z(l, k, h); 22306 } 22307 22308 function kf(a, b) { 22309 var c = a[b + 1 - 32], 22310 d = a[b + 2 - 32], 22311 e = a[b + 3 - 32], 22312 f = a[b + 4 - 32], 22313 g = a[b + 5 - 32], 22314 h = a[b + 6 - 32], 22315 k = a[b + 7 - 32]; 22316 a[b + 0 + 0] = z(a[b + 0 - 32], c, d); 22317 a[b + 1 + 0] = a[b + 0 + 32] = z(c, d, e); 22318 a[b + 2 + 0] = a[b + 1 + 32] = a[b + 0 + 64] = z(d, e, f); 22319 a[b + 3 + 0] = a[b + 2 + 32] = a[b + 1 + 64] = a[b + 0 + 96] = z(e, f, g); 22320 a[b + 3 + 32] = a[b + 2 + 64] = a[b + 1 + 96] = z(f, g, h); 22321 a[b + 3 + 64] = a[b + 2 + 96] = z(g, h, k); 22322 a[b + 3 + 96] = z(h, k, k); 22323 } 22324 22325 function jf(a, b) { 22326 var c = a[b - 1 + 0], 22327 d = a[b - 1 + 32], 22328 e = a[b - 1 + 64], 22329 f = a[b - 1 - 32], 22330 g = a[b + 0 - 32], 22331 h = a[b + 1 - 32], 22332 k = a[b + 2 - 32], 22333 l = a[b + 3 - 32]; 22334 a[b + 0 + 0] = a[b + 1 + 64] = f + g + 1 >> 1; 22335 a[b + 1 + 0] = a[b + 2 + 64] = g + h + 1 >> 1; 22336 a[b + 2 + 0] = a[b + 3 + 64] = h + k + 1 >> 1; 22337 a[b + 3 + 0] = k + l + 1 >> 1; 22338 a[b + 0 + 96] = z(e, d, c); 22339 a[b + 0 + 64] = z(d, c, f); 22340 a[b + 0 + 32] = a[b + 1 + 96] = z(c, f, g); 22341 a[b + 1 + 32] = a[b + 2 + 96] = z(f, g, h); 22342 a[b + 2 + 32] = a[b + 3 + 96] = z(g, h, k); 22343 a[b + 3 + 32] = z(h, k, l); 22344 } 22345 22346 function lf(a, b) { 22347 var c = a[b + 0 - 32], 22348 d = a[b + 1 - 32], 22349 e = a[b + 2 - 32], 22350 f = a[b + 3 - 32], 22351 g = a[b + 4 - 32], 22352 h = a[b + 5 - 32], 22353 k = a[b + 6 - 32], 22354 l = a[b + 7 - 32]; 22355 a[b + 0 + 0] = c + d + 1 >> 1; 22356 a[b + 1 + 0] = a[b + 0 + 64] = d + e + 1 >> 1; 22357 a[b + 2 + 0] = a[b + 1 + 64] = e + f + 1 >> 1; 22358 a[b + 3 + 0] = a[b + 2 + 64] = f + g + 1 >> 1; 22359 a[b + 0 + 32] = z(c, d, e); 22360 a[b + 1 + 32] = a[b + 0 + 96] = z(d, e, f); 22361 a[b + 2 + 32] = a[b + 1 + 96] = z(e, f, g); 22362 a[b + 3 + 32] = a[b + 2 + 96] = z(f, g, h); 22363 a[b + 3 + 64] = z(g, h, k); 22364 a[b + 3 + 96] = z(h, k, l); 22365 } 22366 22367 function nf(a, b) { 22368 var c = a[b - 1 + 0], 22369 d = a[b - 1 + 32], 22370 e = a[b - 1 + 64], 22371 f = a[b - 1 + 96]; 22372 a[b + 0 + 0] = c + d + 1 >> 1; 22373 a[b + 2 + 0] = a[b + 0 + 32] = d + e + 1 >> 1; 22374 a[b + 2 + 32] = a[b + 0 + 64] = e + f + 1 >> 1; 22375 a[b + 1 + 0] = z(c, d, e); 22376 a[b + 3 + 0] = a[b + 1 + 32] = z(d, e, f); 22377 a[b + 3 + 32] = a[b + 1 + 64] = z(e, f, f); 22378 a[b + 3 + 64] = a[b + 2 + 64] = a[b + 0 + 96] = a[b + 1 + 96] = a[b + 2 + 96] = a[b + 3 + 96] = f; 22379 } 22380 22381 function mf(a, b) { 22382 var c = a[b - 1 + 0], 22383 d = a[b - 1 + 32], 22384 e = a[b - 1 + 64], 22385 f = a[b - 1 + 96], 22386 g = a[b - 1 - 32], 22387 h = a[b + 0 - 32], 22388 k = a[b + 1 - 32], 22389 l = a[b + 2 - 32]; 22390 a[b + 0 + 0] = a[b + 2 + 32] = c + g + 1 >> 1; 22391 a[b + 0 + 32] = a[b + 2 + 64] = d + c + 1 >> 1; 22392 a[b + 0 + 64] = a[b + 2 + 96] = e + d + 1 >> 1; 22393 a[b + 0 + 96] = f + e + 1 >> 1; 22394 a[b + 3 + 0] = z(h, k, l); 22395 a[b + 2 + 0] = z(g, h, k); 22396 a[b + 1 + 0] = a[b + 3 + 32] = z(c, g, h); 22397 a[b + 1 + 32] = a[b + 3 + 64] = z(d, c, g); 22398 a[b + 1 + 64] = a[b + 3 + 96] = z(e, d, c); 22399 a[b + 1 + 96] = z(f, e, d); 22400 } 22401 22402 function xf(a, b) { 22403 var c; 22404 22405 for (c = 0; 8 > c; ++c) { 22406 I(a, b + 32 * c, a, b - 32, 8); 22407 } 22408 } 22409 22410 function yf(a, b) { 22411 var c; 22412 22413 for (c = 0; 8 > c; ++c) { 22414 M(a, b, a[b - 1], 8), b += 32; 22415 } 22416 } 22417 22418 function lb(a, b, c) { 22419 var d; 22420 22421 for (d = 0; 8 > d; ++d) { 22422 M(b, c + 32 * d, a, 8); 22423 } 22424 } 22425 22426 function vf(a, b) { 22427 var c = 8, 22428 d; 22429 22430 for (d = 0; 8 > d; ++d) { 22431 c += a[b + d - 32] + a[b - 1 + 32 * d]; 22432 } 22433 22434 lb(c >> 4, a, b); 22435 } 22436 22437 function Af(a, b) { 22438 var c = 4, 22439 d; 22440 22441 for (d = 0; 8 > d; ++d) { 22442 c += a[b + d - 32]; 22443 } 22444 22445 lb(c >> 3, a, b); 22446 } 22447 22448 function zf(a, b) { 22449 var c = 4, 22450 d; 22451 22452 for (d = 0; 8 > d; ++d) { 22453 c += a[b - 1 + 32 * d]; 22454 } 22455 22456 lb(c >> 3, a, b); 22457 } 22458 22459 function Bf(a, b) { 22460 lb(128, a, b); 22461 } 22462 22463 function ab(a, b, c) { 22464 var d = a[b - c], 22465 e = a[b + 0], 22466 f = 3 * (e - d) + Qb[1020 + a[b - 2 * c] - a[b + c]], 22467 g = mb[112 + (f + 4 >> 3)]; 22468 a[b - c] = R[255 + d + mb[112 + (f + 3 >> 3)]]; 22469 a[b + 0] = R[255 + e - g]; 22470 } 22471 22472 function jd(a, b, c, d) { 22473 var e = a[b + 0], 22474 f = a[b + c]; 22475 return U[255 + a[b - 2 * c] - a[b - c]] > d || U[255 + f - e] > d; 22476 } 22477 22478 function kd(a, b, c, d) { 22479 return 4 * U[255 + a[b - c] - a[b + 0]] + U[255 + a[b - 2 * c] - a[b + c]] <= d; 22480 } 22481 22482 function ld(a, b, c, d, e) { 22483 var f = a[b - 3 * c], 22484 g = a[b - 2 * c], 22485 h = a[b - c], 22486 k = a[b + 0], 22487 l = a[b + c], 22488 m = a[b + 2 * c], 22489 n = a[b + 3 * c]; 22490 return 4 * U[255 + h - k] + U[255 + g - l] > d ? 0 : U[255 + a[b - 4 * c] - f] <= e && U[255 + f - g] <= e && U[255 + g - h] <= e && U[255 + n - m] <= e && U[255 + m - l] <= e && U[255 + l - k] <= e; 22491 } 22492 22493 function gd(a, b, c, d) { 22494 var e = 2 * d + 1; 22495 22496 for (d = 0; 16 > d; ++d) { 22497 kd(a, b + d, c, e) && ab(a, b + d, c); 22498 } 22499 } 22500 22501 function hd(a, b, c, d) { 22502 var e = 2 * d + 1; 22503 22504 for (d = 0; 16 > d; ++d) { 22505 kd(a, b + d * c, 1, e) && ab(a, b + d * c, 1); 22506 } 22507 } 22508 22509 function bf(a, b, c, d) { 22510 var e; 22511 22512 for (e = 3; 0 < e; --e) { 22513 b += 4 * c, gd(a, b, c, d); 22514 } 22515 } 22516 22517 function cf(a, b, c, d) { 22518 var e; 22519 22520 for (e = 3; 0 < e; --e) { 22521 b += 4, hd(a, b, c, d); 22522 } 22523 } 22524 22525 function ea(a, b, c, d, e, f, g, h) { 22526 for (f = 2 * f + 1; 0 < e--;) { 22527 if (ld(a, b, c, f, g)) if (jd(a, b, c, h)) ab(a, b, c);else { 22528 var k = a, 22529 l = b, 22530 m = c, 22531 n = k[l - 2 * m], 22532 r = k[l - m], 22533 q = k[l + 0], 22534 t = k[l + m], 22535 v = k[l + 2 * m], 22536 p = Qb[1020 + 3 * (q - r) + Qb[1020 + n - t]], 22537 u = 27 * p + 63 >> 7, 22538 w = 18 * p + 63 >> 7, 22539 p = 9 * p + 63 >> 7; 22540 k[l - 3 * m] = R[255 + k[l - 3 * m] + p]; 22541 k[l - 2 * m] = R[255 + n + w]; 22542 k[l - m] = R[255 + r + u]; 22543 k[l + 0] = R[255 + q - u]; 22544 k[l + m] = R[255 + t - w]; 22545 k[l + 2 * m] = R[255 + v - p]; 22546 } 22547 b += d; 22548 } 22549 } 22550 22551 function Fa(a, b, c, d, e, f, g, h) { 22552 for (f = 2 * f + 1; 0 < e--;) { 22553 if (ld(a, b, c, f, g)) if (jd(a, b, c, h)) ab(a, b, c);else { 22554 var k = a, 22555 l = b, 22556 m = c, 22557 n = k[l - m], 22558 r = k[l + 0], 22559 q = k[l + m], 22560 t = 3 * (r - n), 22561 v = mb[112 + (t + 4 >> 3)], 22562 t = mb[112 + (t + 3 >> 3)], 22563 p = v + 1 >> 1; 22564 k[l - 2 * m] = R[255 + k[l - 2 * m] + p]; 22565 k[l - m] = R[255 + n + t]; 22566 k[l + 0] = R[255 + r - v]; 22567 k[l + m] = R[255 + q - p]; 22568 } 22569 b += d; 22570 } 22571 } 22572 22573 function Ue(a, b, c, d, e, f) { 22574 ea(a, b, c, 1, 16, d, e, f); 22575 } 22576 22577 function Ve(a, b, c, d, e, f) { 22578 ea(a, b, 1, c, 16, d, e, f); 22579 } 22580 22581 function Ye(a, b, c, d, e, f) { 22582 var g; 22583 22584 for (g = 3; 0 < g; --g) { 22585 b += 4 * c, Fa(a, b, c, 1, 16, d, e, f); 22586 } 22587 } 22588 22589 function Ze(a, b, c, d, e, f) { 22590 var g; 22591 22592 for (g = 3; 0 < g; --g) { 22593 b += 4, Fa(a, b, 1, c, 16, d, e, f); 22594 } 22595 } 22596 22597 function We(a, b, c, d, e, f, g, h) { 22598 ea(a, b, e, 1, 8, f, g, h); 22599 ea(c, d, e, 1, 8, f, g, h); 22600 } 22601 22602 function Xe(a, b, c, d, e, f, g, h) { 22603 ea(a, b, 1, e, 8, f, g, h); 22604 ea(c, d, 1, e, 8, f, g, h); 22605 } 22606 22607 function $e(a, b, c, d, e, f, g, h) { 22608 Fa(a, b + 4 * e, e, 1, 8, f, g, h); 22609 Fa(c, d + 4 * e, e, 1, 8, f, g, h); 22610 } 22611 22612 function af(a, b, c, d, e, f, g, h) { 22613 Fa(a, b + 4, 1, e, 8, f, g, h); 22614 Fa(c, d + 4, 1, e, 8, f, g, h); 22615 } 22616 22617 function Cf() { 22618 this.ba = new Cb(); 22619 this.ec = []; 22620 this.cc = []; 22621 this.Mc = []; 22622 this.Dc = this.Nc = this.dc = this.fc = 0; 22623 this.Oa = new Ud(); 22624 this.memory = 0; 22625 this.Ib = "OutputFunc"; 22626 this.Jb = "OutputAlphaFunc"; 22627 this.Nd = "OutputRowFunc"; 22628 } 22629 22630 function md() { 22631 this.data = []; 22632 this.offset = this.kd = this.ha = this.w = 0; 22633 this.na = []; 22634 this.xa = this.gb = this.Ja = this.Sa = this.P = 0; 22635 } 22636 22637 function Df() { 22638 this.nc = this.Ea = this.b = this.hc = 0; 22639 this.K = []; 22640 this.w = 0; 22641 } 22642 22643 function Ef() { 22644 this.ua = 0; 22645 this.Wa = new ac(); 22646 this.vb = new ac(); 22647 this.md = this.xc = this.wc = 0; 22648 this.vc = []; 22649 this.Wb = 0; 22650 this.Ya = new Ub(); 22651 this.yc = new O(); 22652 } 22653 22654 function je() { 22655 this.xb = this.a = 0; 22656 this.l = new Oa(); 22657 this.ca = new Cb(); 22658 this.V = []; 22659 this.Ba = 0; 22660 this.Ta = []; 22661 this.Ua = 0; 22662 this.m = new Ra(); 22663 this.Pb = 0; 22664 this.wd = new Ra(); 22665 this.Ma = this.$ = this.C = this.i = this.c = this.xd = 0; 22666 this.s = new Ef(); 22667 this.ab = 0; 22668 this.gc = wa(4, Df); 22669 this.Oc = 0; 22670 } 22671 22672 function Ff() { 22673 this.Lc = this.Z = this.$a = this.i = this.c = 0; 22674 this.l = new Oa(); 22675 this.ic = 0; 22676 this.ca = []; 22677 this.tb = 0; 22678 this.qd = null; 22679 this.rd = 0; 22680 } 22681 22682 function Rb(a, b, c, d, e, f, g) { 22683 a = null == a ? 0 : a[b + 0]; 22684 22685 for (b = 0; b < g; ++b) { 22686 e[f + b] = a + c[d + b] & 255, a = e[f + b]; 22687 } 22688 } 22689 22690 function Gf(a, b, c, d, e, f, g) { 22691 if (null == a) Rb(null, null, c, d, e, f, g);else { 22692 var h; 22693 22694 for (h = 0; h < g; ++h) { 22695 e[f + h] = a[b + h] + c[d + h] & 255; 22696 } 22697 } 22698 } 22699 22700 function Hf(a, b, c, d, e, f, g) { 22701 if (null == a) Rb(null, null, c, d, e, f, g);else { 22702 var h = a[b + 0], 22703 k = h, 22704 l = h, 22705 m; 22706 22707 for (m = 0; m < g; ++m) { 22708 h = a[b + m], k = l + h - k, l = c[d + m] + (k & -256 ? 0 > k ? 0 : 255 : k) & 255, k = h, e[f + m] = l; 22709 } 22710 } 22711 } 22712 22713 function Le(a, b, c, d) { 22714 var e = b.width, 22715 f = b.o; 22716 x(null != a && null != b); 22717 if (0 > c || 0 >= d || c + d > f) return null; 22718 22719 if (!a.Cc) { 22720 if (null == a.ga) { 22721 a.ga = new Ff(); 22722 var g; 22723 (g = null == a.ga) || (g = b.width * b.o, x(0 == a.Gb.length), a.Gb = V(g), a.Uc = 0, null == a.Gb ? g = 0 : (a.mb = a.Gb, a.nb = a.Uc, a.rc = null, g = 1), g = !g); 22724 22725 if (!g) { 22726 g = a.ga; 22727 var h = a.Fa, 22728 k = a.P, 22729 l = a.qc, 22730 m = a.mb, 22731 n = a.nb, 22732 r = k + 1, 22733 q = l - 1, 22734 t = g.l; 22735 x(null != h && null != m && null != b); 22736 ia[0] = null; 22737 ia[1] = Rb; 22738 ia[2] = Gf; 22739 ia[3] = Hf; 22740 g.ca = m; 22741 g.tb = n; 22742 g.c = b.width; 22743 g.i = b.height; 22744 x(0 < g.c && 0 < g.i); 22745 if (1 >= l) b = 0;else if (g.$a = h[k + 0] >> 0 & 3, g.Z = h[k + 0] >> 2 & 3, g.Lc = h[k + 0] >> 4 & 3, k = h[k + 0] >> 6 & 3, 0 > g.$a || 1 < g.$a || 4 <= g.Z || 1 < g.Lc || k) b = 0;else if (t.put = kc, t.ac = gc, t.bc = lc, t.ma = g, t.width = b.width, t.height = b.height, t.Da = b.Da, t.v = b.v, t.va = b.va, t.j = b.j, t.o = b.o, g.$a) b: { 22746 x(1 == g.$a), b = Bc(); 22747 22748 c: for (;;) { 22749 if (null == b) { 22750 b = 0; 22751 break b; 22752 } 22753 22754 x(null != g); 22755 g.mc = b; 22756 b.c = g.c; 22757 b.i = g.i; 22758 b.l = g.l; 22759 b.l.ma = g; 22760 b.l.width = g.c; 22761 b.l.height = g.i; 22762 b.a = 0; 22763 cb(b.m, h, r, q); 22764 if (!rb(g.c, g.i, 1, b, null)) break c; 22765 1 == b.ab && 3 == b.gc[0].hc && yc(b.s) ? (g.ic = 1, h = b.c * b.i, b.Ta = null, b.Ua = 0, b.V = V(h), b.Ba = 0, null == b.V ? (b.a = 1, b = 0) : b = 1) : (g.ic = 0, b = Ec(b, g.c)); 22766 if (!b) break c; 22767 b = 1; 22768 break b; 22769 } 22770 22771 g.mc = null; 22772 b = 0; 22773 } else b = q >= g.c * g.i; 22774 g = !b; 22775 } 22776 22777 if (g) return null; 22778 1 != a.ga.Lc ? a.Ga = 0 : d = f - c; 22779 } 22780 22781 x(null != a.ga); 22782 x(c + d <= f); 22783 22784 a: { 22785 h = a.ga; 22786 b = h.c; 22787 f = h.l.o; 22788 22789 if (0 == h.$a) { 22790 r = a.rc; 22791 q = a.Vc; 22792 t = a.Fa; 22793 k = a.P + 1 + c * b; 22794 l = a.mb; 22795 m = a.nb + c * b; 22796 x(k <= a.P + a.qc); 22797 if (0 != h.Z) for (x(null != ia[h.Z]), g = 0; g < d; ++g) { 22798 ia[h.Z](r, q, t, k, l, m, b), r = l, q = m, m += b, k += b; 22799 } else for (g = 0; g < d; ++g) { 22800 I(l, m, t, k, b), r = l, q = m, m += b, k += b; 22801 } 22802 a.rc = r; 22803 a.Vc = q; 22804 } else { 22805 x(null != h.mc); 22806 b = c + d; 22807 g = h.mc; 22808 x(null != g); 22809 x(b <= g.i); 22810 if (g.C >= b) b = 1;else if (h.ic || Aa(), h.ic) { 22811 var h = g.V, 22812 r = g.Ba, 22813 q = g.c, 22814 v = g.i, 22815 t = 1, 22816 k = g.$ / q, 22817 l = g.$ % q, 22818 m = g.m, 22819 n = g.s, 22820 p = g.$, 22821 u = q * v, 22822 w = q * b, 22823 y = n.wc, 22824 A = p < w ? ha(n, l, k) : null; 22825 x(p <= u); 22826 x(b <= v); 22827 x(yc(n)); 22828 22829 c: for (;;) { 22830 for (; !m.h && p < w;) { 22831 l & y || (A = ha(n, l, k)); 22832 x(null != A); 22833 Sa(m); 22834 v = ua(A.G[0], A.H[0], m); 22835 if (256 > v) h[r + p] = v, ++p, ++l, l >= q && (l = 0, ++k, k <= b && !(k % 16) && Ib(g, k));else if (280 > v) { 22836 var v = ib(v - 256, m); 22837 var E = ua(A.G[4], A.H[4], m); 22838 Sa(m); 22839 E = ib(E, m); 22840 E = nc(q, E); 22841 22842 if (p >= E && u - p >= v) { 22843 var B; 22844 22845 for (B = 0; B < v; ++B) { 22846 h[r + p + B] = h[r + p + B - E]; 22847 } 22848 } else { 22849 t = 0; 22850 break c; 22851 } 22852 22853 p += v; 22854 22855 for (l += v; l >= q;) { 22856 l -= q, ++k, k <= b && !(k % 16) && Ib(g, k); 22857 } 22858 22859 p < w && l & y && (A = ha(n, l, k)); 22860 } else { 22861 t = 0; 22862 break c; 22863 } 22864 x(m.h == db(m)); 22865 } 22866 22867 Ib(g, k > b ? b : k); 22868 break c; 22869 } 22870 22871 !t || m.h && p < u ? (t = 0, g.a = m.h ? 5 : 3) : g.$ = p; 22872 b = t; 22873 } else b = Jb(g, g.V, g.Ba, g.c, g.i, b, se); 22874 22875 if (!b) { 22876 d = 0; 22877 break a; 22878 } 22879 } 22880 22881 c + d >= f && (a.Cc = 1); 22882 d = 1; 22883 } 22884 22885 if (!d) return null; 22886 if (a.Cc && (d = a.ga, null != d && (d.mc = null), a.ga = null, 0 < a.Ga)) return alert("todo:WebPDequantizeLevels"), null; 22887 } 22888 22889 return a.nb + c * e; 22890 } 22891 22892 function If(a, b, c, d, e, f) { 22893 for (; 0 < e--;) { 22894 var g = a, 22895 h = b + (c ? 1 : 0), 22896 k = a, 22897 l = b + (c ? 0 : 3), 22898 m; 22899 22900 for (m = 0; m < d; ++m) { 22901 var n = k[l + 4 * m]; 22902 255 != n && (n *= 32897, g[h + 4 * m + 0] = g[h + 4 * m + 0] * n >> 23, g[h + 4 * m + 1] = g[h + 4 * m + 1] * n >> 23, g[h + 4 * m + 2] = g[h + 4 * m + 2] * n >> 23); 22903 } 22904 22905 b += f; 22906 } 22907 } 22908 22909 function Jf(a, b, c, d, e) { 22910 for (; 0 < d--;) { 22911 var f; 22912 22913 for (f = 0; f < c; ++f) { 22914 var g = a[b + 2 * f + 0], 22915 h = a[b + 2 * f + 1], 22916 k = h & 15, 22917 l = 4369 * k, 22918 h = (h & 240 | h >> 4) * l >> 16; 22919 a[b + 2 * f + 0] = (g & 240 | g >> 4) * l >> 16 & 240 | (g & 15 | g << 4) * l >> 16 >> 4 & 15; 22920 a[b + 2 * f + 1] = h & 240 | k; 22921 } 22922 22923 b += e; 22924 } 22925 } 22926 22927 function Kf(a, b, c, d, e, f, g, h) { 22928 var k = 255, 22929 l, 22930 m; 22931 22932 for (m = 0; m < e; ++m) { 22933 for (l = 0; l < d; ++l) { 22934 var n = a[b + l]; 22935 f[g + 4 * l] = n; 22936 k &= n; 22937 } 22938 22939 b += c; 22940 g += h; 22941 } 22942 22943 return 255 != k; 22944 } 22945 22946 function Lf(a, b, c, d, e) { 22947 var f; 22948 22949 for (f = 0; f < e; ++f) { 22950 c[d + f] = a[b + f] >> 8; 22951 } 22952 } 22953 22954 function Aa() { 22955 za = If; 22956 vc = Jf; 22957 fc = Kf; 22958 Fc = Lf; 22959 } 22960 22961 function va(a, b, c) { 22962 self[a] = function (a, e, f, g, h, k, l, m, n, r, q, t, v, p, u, w, y) { 22963 var d, 22964 E = y - 1 >> 1; 22965 var B = h[k + 0] | l[m + 0] << 16; 22966 var C = n[r + 0] | q[t + 0] << 16; 22967 x(null != a); 22968 var z = 3 * B + C + 131074 >> 2; 22969 b(a[e + 0], z & 255, z >> 16, v, p); 22970 null != f && (z = 3 * C + B + 131074 >> 2, b(f[g + 0], z & 255, z >> 16, u, w)); 22971 22972 for (d = 1; d <= E; ++d) { 22973 var D = h[k + d] | l[m + d] << 16; 22974 var G = n[r + d] | q[t + d] << 16; 22975 var F = B + D + C + G + 524296; 22976 var H = F + 2 * (D + C) >> 3; 22977 F = F + 2 * (B + G) >> 3; 22978 z = H + B >> 1; 22979 B = F + D >> 1; 22980 b(a[e + 2 * d - 1], z & 255, z >> 16, v, p + (2 * d - 1) * c); 22981 b(a[e + 2 * d - 0], B & 255, B >> 16, v, p + (2 * d - 0) * c); 22982 null != f && (z = F + C >> 1, B = H + G >> 1, b(f[g + 2 * d - 1], z & 255, z >> 16, u, w + (2 * d - 1) * c), b(f[g + 2 * d + 0], B & 255, B >> 16, u, w + (2 * d + 0) * c)); 22983 B = D; 22984 C = G; 22985 } 22986 22987 y & 1 || (z = 3 * B + C + 131074 >> 2, b(a[e + y - 1], z & 255, z >> 16, v, p + (y - 1) * c), null != f && (z = 3 * C + B + 131074 >> 2, b(f[g + y - 1], z & 255, z >> 16, u, w + (y - 1) * c))); 22988 }; 22989 } 22990 22991 function ic() { 22992 P[Ca] = Mf; 22993 P[Ua] = nd; 22994 P[tc] = Nf; 22995 P[Va] = od; 22996 P[ya] = pd; 22997 P[Db] = qd; 22998 P[wc] = Of; 22999 P[zb] = nd; 23000 P[Ab] = od; 23001 P[Ja] = pd; 23002 P[Bb] = qd; 23003 } 23004 23005 function Sb(a) { 23006 return a & ~Pf ? 0 > a ? 0 : 255 : a >> rd; 23007 } 23008 23009 function bb(a, b) { 23010 return Sb((19077 * a >> 8) + (26149 * b >> 8) - 14234); 23011 } 23012 23013 function nb(a, b, c) { 23014 return Sb((19077 * a >> 8) - (6419 * b >> 8) - (13320 * c >> 8) + 8708); 23015 } 23016 23017 function Pa(a, b) { 23018 return Sb((19077 * a >> 8) + (33050 * b >> 8) - 17685); 23019 } 23020 23021 function Ga(a, b, c, d, e) { 23022 d[e + 0] = bb(a, c); 23023 d[e + 1] = nb(a, b, c); 23024 d[e + 2] = Pa(a, b); 23025 } 23026 23027 function Tb(a, b, c, d, e) { 23028 d[e + 0] = Pa(a, b); 23029 d[e + 1] = nb(a, b, c); 23030 d[e + 2] = bb(a, c); 23031 } 23032 23033 function sd(a, b, c, d, e) { 23034 var f = nb(a, b, c); 23035 b = f << 3 & 224 | Pa(a, b) >> 3; 23036 d[e + 0] = bb(a, c) & 248 | f >> 5; 23037 d[e + 1] = b; 23038 } 23039 23040 function td(a, b, c, d, e) { 23041 var f = Pa(a, b) & 240 | 15; 23042 d[e + 0] = bb(a, c) & 240 | nb(a, b, c) >> 4; 23043 d[e + 1] = f; 23044 } 23045 23046 function ud(a, b, c, d, e) { 23047 d[e + 0] = 255; 23048 Ga(a, b, c, d, e + 1); 23049 } 23050 23051 function vd(a, b, c, d, e) { 23052 Tb(a, b, c, d, e); 23053 d[e + 3] = 255; 23054 } 23055 23056 function wd(a, b, c, d, e) { 23057 Ga(a, b, c, d, e); 23058 d[e + 3] = 255; 23059 } 23060 23061 function ga(a, b) { 23062 return 0 > a ? 0 : a > b ? b : a; 23063 } 23064 23065 function la(a, b, c) { 23066 self[a] = function (a, e, f, g, h, k, l, m, n) { 23067 for (var d = m + (n & -2) * c; m != d;) { 23068 b(a[e + 0], f[g + 0], h[k + 0], l, m), b(a[e + 1], f[g + 0], h[k + 0], l, m + c), e += 2, ++g, ++k, m += 2 * c; 23069 } 23070 23071 n & 1 && b(a[e + 0], f[g + 0], h[k + 0], l, m); 23072 }; 23073 } 23074 23075 function xd(a, b, c) { 23076 return 0 == c ? 0 == a ? 0 == b ? 6 : 5 : 0 == b ? 4 : 0 : c; 23077 } 23078 23079 function yd(a, b, c, d, e) { 23080 switch (a >>> 30) { 23081 case 3: 23082 Za(b, c, d, e, 0); 23083 break; 23084 23085 case 2: 23086 fd(b, c, d, e); 23087 break; 23088 23089 case 1: 23090 pa(b, c, d, e); 23091 } 23092 } 23093 23094 function Oc(a, b) { 23095 var c, 23096 d, 23097 e = b.M, 23098 f = b.Nb, 23099 g = a.oc, 23100 h = a.pc + 40, 23101 k = a.oc, 23102 l = a.pc + 584, 23103 m = a.oc, 23104 n = a.pc + 600; 23105 23106 for (c = 0; 16 > c; ++c) { 23107 g[h + 32 * c - 1] = 129; 23108 } 23109 23110 for (c = 0; 8 > c; ++c) { 23111 k[l + 32 * c - 1] = 129, m[n + 32 * c - 1] = 129; 23112 } 23113 23114 0 < e ? g[h - 1 - 32] = k[l - 1 - 32] = m[n - 1 - 32] = 129 : (M(g, h - 32 - 1, 127, 21), M(k, l - 32 - 1, 127, 9), M(m, n - 32 - 1, 127, 9)); 23115 23116 for (d = 0; d < a.za; ++d) { 23117 var r = b.ya[b.aa + d]; 23118 23119 if (0 < d) { 23120 for (c = -1; 16 > c; ++c) { 23121 I(g, h + 32 * c - 4, g, h + 32 * c + 12, 4); 23122 } 23123 23124 for (c = -1; 8 > c; ++c) { 23125 I(k, l + 32 * c - 4, k, l + 32 * c + 4, 4), I(m, n + 32 * c - 4, m, n + 32 * c + 4, 4); 23126 } 23127 } 23128 23129 var q = a.Gd, 23130 t = a.Hd + d, 23131 v = r.ad, 23132 p = r.Hc; 23133 0 < e && (I(g, h - 32, q[t].y, 0, 16), I(k, l - 32, q[t].f, 0, 8), I(m, n - 32, q[t].ea, 0, 8)); 23134 23135 if (r.Za) { 23136 var u = g; 23137 var w = h - 32 + 16; 23138 0 < e && (d >= a.za - 1 ? M(u, w, q[t].y[15], 4) : I(u, w, q[t + 1].y, 0, 4)); 23139 23140 for (c = 0; 4 > c; c++) { 23141 u[w + 128 + c] = u[w + 256 + c] = u[w + 384 + c] = u[w + 0 + c]; 23142 } 23143 23144 for (c = 0; 16 > c; ++c, p <<= 2) { 23145 u = g, w = h + zd[c], W[r.Ob[c]](u, w), yd(p, v, 16 * +c, u, w); 23146 } 23147 } else if (u = xd(d, e, r.Ob[0]), Y[u](g, h), 0 != p) for (c = 0; 16 > c; ++c, p <<= 2) { 23148 yd(p, v, 16 * +c, g, h + zd[c]); 23149 } 23150 23151 c = r.Gc; 23152 u = xd(d, e, r.Dd); 23153 ka[u](k, l); 23154 ka[u](m, n); 23155 r = c >> 0; 23156 p = v; 23157 u = k; 23158 w = l; 23159 r & 255 && (r & 170 ? Nb(p, 256, u, w) : Ob(p, 256, u, w)); 23160 c >>= 8; 23161 r = m; 23162 p = n; 23163 c & 255 && (c & 170 ? Nb(v, 320, r, p) : Ob(v, 320, r, p)); 23164 e < a.Ub - 1 && (I(q[t].y, 0, g, h + 480, 16), I(q[t].f, 0, k, l + 224, 8), I(q[t].ea, 0, m, n + 224, 8)); 23165 c = 8 * f * a.B; 23166 q = a.sa; 23167 t = a.ta + 16 * d + 16 * f * a.R; 23168 v = a.qa; 23169 r = a.ra + 8 * d + c; 23170 p = a.Ha; 23171 u = a.Ia + 8 * d + c; 23172 23173 for (c = 0; 16 > c; ++c) { 23174 I(q, t + c * a.R, g, h + 32 * c, 16); 23175 } 23176 23177 for (c = 0; 8 > c; ++c) { 23178 I(v, r + c * a.B, k, l + 32 * c, 8), I(p, u + c * a.B, m, n + 32 * c, 8); 23179 } 23180 } 23181 } 23182 23183 function Ad(a, b, c, d, e, f, g, h, k) { 23184 var l = [0], 23185 m = [0], 23186 n = 0, 23187 r = null != k ? k.kd : 0, 23188 q = null != k ? k : new md(); 23189 if (null == a || 12 > c) return 7; 23190 q.data = a; 23191 q.w = b; 23192 q.ha = c; 23193 b = [b]; 23194 c = [c]; 23195 q.gb = [q.gb]; 23196 23197 a: { 23198 var t = b; 23199 var v = c; 23200 var p = q.gb; 23201 x(null != a); 23202 x(null != v); 23203 x(null != p); 23204 p[0] = 0; 23205 23206 if (12 <= v[0] && !fa(a, t[0], "RIFF")) { 23207 if (fa(a, t[0] + 8, "WEBP")) { 23208 p = 3; 23209 break a; 23210 } 23211 23212 var u = Ha(a, t[0] + 4); 23213 23214 if (12 > u || 4294967286 < u) { 23215 p = 3; 23216 break a; 23217 } 23218 23219 if (r && u > v[0] - 8) { 23220 p = 7; 23221 break a; 23222 } 23223 23224 p[0] = u; 23225 t[0] += 12; 23226 v[0] -= 12; 23227 } 23228 23229 p = 0; 23230 } 23231 23232 if (0 != p) return p; 23233 u = 0 < q.gb[0]; 23234 23235 for (c = c[0];;) { 23236 t = [0]; 23237 n = [n]; 23238 23239 a: { 23240 var w = a; 23241 v = b; 23242 p = c; 23243 var y = n, 23244 A = l, 23245 z = m, 23246 B = t; 23247 y[0] = 0; 23248 if (8 > p[0]) p = 7;else { 23249 if (!fa(w, v[0], "VP8X")) { 23250 if (10 != Ha(w, v[0] + 4)) { 23251 p = 3; 23252 break a; 23253 } 23254 23255 if (18 > p[0]) { 23256 p = 7; 23257 break a; 23258 } 23259 23260 var C = Ha(w, v[0] + 8); 23261 var D = 1 + Yb(w, v[0] + 12); 23262 w = 1 + Yb(w, v[0] + 15); 23263 23264 if (2147483648 <= D * w) { 23265 p = 3; 23266 break a; 23267 } 23268 23269 null != B && (B[0] = C); 23270 null != A && (A[0] = D); 23271 null != z && (z[0] = w); 23272 v[0] += 18; 23273 p[0] -= 18; 23274 y[0] = 1; 23275 } 23276 23277 p = 0; 23278 } 23279 } 23280 23281 n = n[0]; 23282 t = t[0]; 23283 if (0 != p) return p; 23284 v = !!(t & 2); 23285 if (!u && n) return 3; 23286 null != f && (f[0] = !!(t & 16)); 23287 null != g && (g[0] = v); 23288 null != h && (h[0] = 0); 23289 g = l[0]; 23290 t = m[0]; 23291 23292 if (n && v && null == k) { 23293 p = 0; 23294 break; 23295 } 23296 23297 if (4 > c) { 23298 p = 7; 23299 break; 23300 } 23301 23302 if (u && n || !u && !n && !fa(a, b[0], "ALPH")) { 23303 c = [c]; 23304 q.na = [q.na]; 23305 q.P = [q.P]; 23306 q.Sa = [q.Sa]; 23307 23308 a: { 23309 C = a; 23310 p = b; 23311 u = c; 23312 var y = q.gb, 23313 A = q.na, 23314 z = q.P, 23315 B = q.Sa; 23316 D = 22; 23317 x(null != C); 23318 x(null != u); 23319 w = p[0]; 23320 var F = u[0]; 23321 x(null != A); 23322 x(null != B); 23323 A[0] = null; 23324 z[0] = null; 23325 23326 for (B[0] = 0;;) { 23327 p[0] = w; 23328 u[0] = F; 23329 23330 if (8 > F) { 23331 p = 7; 23332 break a; 23333 } 23334 23335 var G = Ha(C, w + 4); 23336 23337 if (4294967286 < G) { 23338 p = 3; 23339 break a; 23340 } 23341 23342 var H = 8 + G + 1 & -2; 23343 D += H; 23344 23345 if (0 < y && D > y) { 23346 p = 3; 23347 break a; 23348 } 23349 23350 if (!fa(C, w, "VP8 ") || !fa(C, w, "VP8L")) { 23351 p = 0; 23352 break a; 23353 } 23354 23355 if (F[0] < H) { 23356 p = 7; 23357 break a; 23358 } 23359 23360 fa(C, w, "ALPH") || (A[0] = C, z[0] = w + 8, B[0] = G); 23361 w += H; 23362 F -= H; 23363 } 23364 } 23365 23366 c = c[0]; 23367 q.na = q.na[0]; 23368 q.P = q.P[0]; 23369 q.Sa = q.Sa[0]; 23370 if (0 != p) break; 23371 } 23372 23373 c = [c]; 23374 q.Ja = [q.Ja]; 23375 q.xa = [q.xa]; 23376 23377 a: if (y = a, p = b, u = c, A = q.gb[0], z = q.Ja, B = q.xa, C = p[0], w = !fa(y, C, "VP8 "), D = !fa(y, C, "VP8L"), x(null != y), x(null != u), x(null != z), x(null != B), 8 > u[0]) p = 7;else { 23378 if (w || D) { 23379 y = Ha(y, C + 4); 23380 23381 if (12 <= A && y > A - 12) { 23382 p = 3; 23383 break a; 23384 } 23385 23386 if (r && y > u[0] - 8) { 23387 p = 7; 23388 break a; 23389 } 23390 23391 z[0] = y; 23392 p[0] += 8; 23393 u[0] -= 8; 23394 B[0] = D; 23395 } else B[0] = 5 <= u[0] && 47 == y[C + 0] && !(y[C + 4] >> 5), z[0] = u[0]; 23396 23397 p = 0; 23398 } 23399 23400 c = c[0]; 23401 q.Ja = q.Ja[0]; 23402 q.xa = q.xa[0]; 23403 b = b[0]; 23404 if (0 != p) break; 23405 if (4294967286 < q.Ja) return 3; 23406 null == h || v || (h[0] = q.xa ? 2 : 1); 23407 g = [g]; 23408 t = [t]; 23409 23410 if (q.xa) { 23411 if (5 > c) { 23412 p = 7; 23413 break; 23414 } 23415 23416 h = g; 23417 r = t; 23418 v = f; 23419 null == a || 5 > c ? a = 0 : 5 <= c && 47 == a[b + 0] && !(a[b + 4] >> 5) ? (u = [0], y = [0], A = [0], z = new Ra(), cb(z, a, b, c), mc(z, u, y, A) ? (null != h && (h[0] = u[0]), null != r && (r[0] = y[0]), null != v && (v[0] = A[0]), a = 1) : a = 0) : a = 0; 23420 } else { 23421 if (10 > c) { 23422 p = 7; 23423 break; 23424 } 23425 23426 h = t; 23427 null == a || 10 > c || !Jc(a, b + 3, c - 3) ? a = 0 : (r = a[b + 0] | a[b + 1] << 8 | a[b + 2] << 16, v = (a[b + 7] << 8 | a[b + 6]) & 16383, a = (a[b + 9] << 8 | a[b + 8]) & 16383, r & 1 || 3 < (r >> 1 & 7) || !(r >> 4 & 1) || r >> 5 >= q.Ja || !v || !a ? a = 0 : (g && (g[0] = v), h && (h[0] = a), a = 1)); 23428 } 23429 23430 if (!a) return 3; 23431 g = g[0]; 23432 t = t[0]; 23433 if (n && (l[0] != g || m[0] != t)) return 3; 23434 null != k && (k[0] = q, k.offset = b - k.w, x(4294967286 > b - k.w), x(k.offset == k.ha - c)); 23435 break; 23436 } 23437 23438 return 0 == p || 7 == p && n && null == k ? (null != f && (f[0] |= null != q.na && 0 < q.na.length), null != d && (d[0] = g), null != e && (e[0] = t), 0) : p; 23439 } 23440 23441 function hc(a, b, c) { 23442 var d = b.width, 23443 e = b.height, 23444 f = 0, 23445 g = 0, 23446 h = d, 23447 k = e; 23448 b.Da = null != a && 0 < a.Da; 23449 if (b.Da && (h = a.cd, k = a.bd, f = a.v, g = a.j, 11 > c || (f &= -2, g &= -2), 0 > f || 0 > g || 0 >= h || 0 >= k || f + h > d || g + k > e)) return 0; 23450 b.v = f; 23451 b.j = g; 23452 b.va = f + h; 23453 b.o = g + k; 23454 b.U = h; 23455 b.T = k; 23456 b.da = null != a && 0 < a.da; 23457 23458 if (b.da) { 23459 c = [a.ib]; 23460 f = [a.hb]; 23461 if (!bc(h, k, c, f)) return 0; 23462 b.ib = c[0]; 23463 b.hb = f[0]; 23464 } 23465 23466 b.ob = null != a && a.ob; 23467 b.Kb = null == a || !a.Sd; 23468 b.da && (b.ob = b.ib < 3 * d / 4 && b.hb < 3 * e / 4, b.Kb = 0); 23469 return 1; 23470 } 23471 23472 function Bd(a) { 23473 if (null == a) return 2; 23474 23475 if (11 > a.S) { 23476 var b = a.f.RGBA; 23477 b.fb += (a.height - 1) * b.A; 23478 b.A = -b.A; 23479 } else b = a.f.kb, a = a.height, b.O += (a - 1) * b.fa, b.fa = -b.fa, b.N += (a - 1 >> 1) * b.Ab, b.Ab = -b.Ab, b.W += (a - 1 >> 1) * b.Db, b.Db = -b.Db, null != b.F && (b.J += (a - 1) * b.lb, b.lb = -b.lb); 23480 23481 return 0; 23482 } 23483 23484 function Cd(a, b, c, d) { 23485 if (null == d || 0 >= a || 0 >= b) return 2; 23486 23487 if (null != c) { 23488 if (c.Da) { 23489 var e = c.cd, 23490 f = c.bd, 23491 g = c.v & -2, 23492 h = c.j & -2; 23493 if (0 > g || 0 > h || 0 >= e || 0 >= f || g + e > a || h + f > b) return 2; 23494 a = e; 23495 b = f; 23496 } 23497 23498 if (c.da) { 23499 e = [c.ib]; 23500 f = [c.hb]; 23501 if (!bc(a, b, e, f)) return 2; 23502 a = e[0]; 23503 b = f[0]; 23504 } 23505 } 23506 23507 d.width = a; 23508 d.height = b; 23509 23510 a: { 23511 var k = d.width; 23512 var l = d.height; 23513 a = d.S; 23514 if (0 >= k || 0 >= l || !(a >= Ca && 13 > a)) a = 2;else { 23515 if (0 >= d.Rd && null == d.sd) { 23516 var g = f = e = b = 0, 23517 h = k * Dd[a], 23518 m = h * l; 23519 11 > a || (b = (k + 1) / 2, f = (l + 1) / 2 * b, 12 == a && (e = k, g = e * l)); 23520 l = V(m + 2 * f + g); 23521 23522 if (null == l) { 23523 a = 1; 23524 break a; 23525 } 23526 23527 d.sd = l; 23528 11 > a ? (k = d.f.RGBA, k.eb = l, k.fb = 0, k.A = h, k.size = m) : (k = d.f.kb, k.y = l, k.O = 0, k.fa = h, k.Fd = m, k.f = l, k.N = 0 + m, k.Ab = b, k.Cd = f, k.ea = l, k.W = 0 + m + f, k.Db = b, k.Ed = f, 12 == a && (k.F = l, k.J = 0 + m + 2 * f), k.Tc = g, k.lb = e); 23529 } 23530 23531 b = 1; 23532 e = d.S; 23533 f = d.width; 23534 g = d.height; 23535 if (e >= Ca && 13 > e) { 23536 if (11 > e) a = d.f.RGBA, h = Math.abs(a.A), b &= h * (g - 1) + f <= a.size, b &= h >= f * Dd[e], b &= null != a.eb;else { 23537 a = d.f.kb; 23538 h = (f + 1) / 2; 23539 m = (g + 1) / 2; 23540 k = Math.abs(a.fa); 23541 var l = Math.abs(a.Ab), 23542 n = Math.abs(a.Db), 23543 r = Math.abs(a.lb), 23544 q = r * (g - 1) + f; 23545 b &= k * (g - 1) + f <= a.Fd; 23546 b &= l * (m - 1) + h <= a.Cd; 23547 b &= n * (m - 1) + h <= a.Ed; 23548 b = b & k >= f & l >= h & n >= h; 23549 b &= null != a.y; 23550 b &= null != a.f; 23551 b &= null != a.ea; 23552 12 == e && (b &= r >= f, b &= q <= a.Tc, b &= null != a.F); 23553 } 23554 } else b = 0; 23555 a = b ? 0 : 2; 23556 } 23557 } 23558 23559 if (0 != a) return a; 23560 null != c && c.fd && (a = Bd(d)); 23561 return a; 23562 } 23563 23564 var xb = 64, 23565 Hd = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215], 23566 Gd = 24, 23567 ob = 32, 23568 Xb = 8, 23569 Id = [0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7]; 23570 X("Predictor0", "PredictorAdd0"); 23571 23572 self.Predictor0 = function () { 23573 return 4278190080; 23574 }; 23575 23576 self.Predictor1 = function (a) { 23577 return a; 23578 }; 23579 23580 self.Predictor2 = function (a, b, c) { 23581 return b[c + 0]; 23582 }; 23583 23584 self.Predictor3 = function (a, b, c) { 23585 return b[c + 1]; 23586 }; 23587 23588 self.Predictor4 = function (a, b, c) { 23589 return b[c - 1]; 23590 }; 23591 23592 self.Predictor5 = function (a, b, c) { 23593 return aa(aa(a, b[c + 1]), b[c + 0]); 23594 }; 23595 23596 self.Predictor6 = function (a, b, c) { 23597 return aa(a, b[c - 1]); 23598 }; 23599 23600 self.Predictor7 = function (a, b, c) { 23601 return aa(a, b[c + 0]); 23602 }; 23603 23604 self.Predictor8 = function (a, b, c) { 23605 return aa(b[c - 1], b[c + 0]); 23606 }; 23607 23608 self.Predictor9 = function (a, b, c) { 23609 return aa(b[c + 0], b[c + 1]); 23610 }; 23611 23612 self.Predictor10 = function (a, b, c) { 23613 return aa(aa(a, b[c - 1]), aa(b[c + 0], b[c + 1])); 23614 }; 23615 23616 self.Predictor11 = function (a, b, c) { 23617 var d = b[c + 0]; 23618 b = b[c - 1]; 23619 return 0 >= Ia(d >> 24 & 255, a >> 24 & 255, b >> 24 & 255) + Ia(d >> 16 & 255, a >> 16 & 255, b >> 16 & 255) + Ia(d >> 8 & 255, a >> 8 & 255, b >> 8 & 255) + Ia(d & 255, a & 255, b & 255) ? d : a; 23620 }; 23621 23622 self.Predictor12 = function (a, b, c) { 23623 var d = b[c + 0]; 23624 b = b[c - 1]; 23625 return (sa((a >> 24 & 255) + (d >> 24 & 255) - (b >> 24 & 255)) << 24 | sa((a >> 16 & 255) + (d >> 16 & 255) - (b >> 16 & 255)) << 16 | sa((a >> 8 & 255) + (d >> 8 & 255) - (b >> 8 & 255)) << 8 | sa((a & 255) + (d & 255) - (b & 255))) >>> 0; 23626 }; 23627 23628 self.Predictor13 = function (a, b, c) { 23629 var d = b[c - 1]; 23630 a = aa(a, b[c + 0]); 23631 return (eb(a >> 24 & 255, d >> 24 & 255) << 24 | eb(a >> 16 & 255, d >> 16 & 255) << 16 | eb(a >> 8 & 255, d >> 8 & 255) << 8 | eb(a >> 0 & 255, d >> 0 & 255)) >>> 0; 23632 }; 23633 23634 var ee = self.PredictorAdd0; 23635 self.PredictorAdd1 = cc; 23636 X("Predictor2", "PredictorAdd2"); 23637 X("Predictor3", "PredictorAdd3"); 23638 X("Predictor4", "PredictorAdd4"); 23639 X("Predictor5", "PredictorAdd5"); 23640 X("Predictor6", "PredictorAdd6"); 23641 X("Predictor7", "PredictorAdd7"); 23642 X("Predictor8", "PredictorAdd8"); 23643 X("Predictor9", "PredictorAdd9"); 23644 X("Predictor10", "PredictorAdd10"); 23645 X("Predictor11", "PredictorAdd11"); 23646 X("Predictor12", "PredictorAdd12"); 23647 X("Predictor13", "PredictorAdd13"); 23648 var fe = self.PredictorAdd2; 23649 ec("ColorIndexInverseTransform", "MapARGB", "32b", function (a) { 23650 return a >> 8 & 255; 23651 }, function (a) { 23652 return a; 23653 }); 23654 ec("VP8LColorIndexInverseTransformAlpha", "MapAlpha", "8b", function (a) { 23655 return a; 23656 }, function (a) { 23657 return a >> 8 & 255; 23658 }); 23659 var rc = self.ColorIndexInverseTransform, 23660 ke = self.MapARGB, 23661 he = self.VP8LColorIndexInverseTransformAlpha, 23662 le = self.MapAlpha, 23663 pc, 23664 qc = self.VP8LPredictorsAdd = []; 23665 qc.length = 16; 23666 (self.VP8LPredictors = []).length = 16; 23667 (self.VP8LPredictorsAdd_C = []).length = 16; 23668 (self.VP8LPredictors_C = []).length = 16; 23669 var Fb, 23670 sc, 23671 Gb, 23672 Hb, 23673 xc, 23674 uc, 23675 bd = V(511), 23676 cd = V(2041), 23677 dd = V(225), 23678 ed = V(767), 23679 ad = 0, 23680 Qb = cd, 23681 mb = dd, 23682 R = ed, 23683 U = bd, 23684 Ca = 0, 23685 Ua = 1, 23686 tc = 2, 23687 Va = 3, 23688 ya = 4, 23689 Db = 5, 23690 wc = 6, 23691 zb = 7, 23692 Ab = 8, 23693 Ja = 9, 23694 Bb = 10, 23695 pe = [2, 3, 7], 23696 oe = [3, 3, 11], 23697 Dc = [280, 256, 256, 256, 40], 23698 qe = [0, 1, 1, 1, 0], 23699 ne = [17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 23700 de = [24, 7, 23, 25, 40, 6, 39, 41, 22, 26, 38, 42, 56, 5, 55, 57, 21, 27, 54, 58, 37, 43, 72, 4, 71, 73, 20, 28, 53, 59, 70, 74, 36, 44, 88, 69, 75, 52, 60, 3, 87, 89, 19, 29, 86, 90, 35, 45, 68, 76, 85, 91, 51, 61, 104, 2, 103, 105, 18, 30, 102, 106, 34, 46, 84, 92, 67, 77, 101, 107, 50, 62, 120, 1, 119, 121, 83, 93, 17, 31, 100, 108, 66, 78, 118, 122, 33, 47, 117, 123, 49, 63, 99, 109, 82, 94, 0, 116, 124, 65, 79, 16, 32, 98, 110, 48, 115, 125, 81, 95, 64, 114, 126, 97, 111, 80, 113, 127, 96, 112], 23701 me = [2954, 2956, 2958, 2962, 2970, 2986, 3018, 3082, 3212, 3468, 3980, 5004], 23702 ie = 8, 23703 Lb = [4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 93, 95, 96, 98, 100, 101, 102, 104, 106, 108, 110, 112, 114, 116, 118, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 143, 145, 148, 151, 154, 157], 23704 Mb = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 119, 122, 125, 128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284], 23705 oa = null, 23706 He = [[173, 148, 140, 0], [176, 155, 140, 135, 0], [180, 157, 141, 134, 130, 0], [254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0]], 23707 Ie = [0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15], 23708 Mc = [-0, 1, -1, 2, -2, 3, 4, 6, -3, 5, -4, -5, -6, 7, -7, 8, -8, -9], 23709 Fe = [[[[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]], [[253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128], [189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128], [106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128]], [[1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128], [181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128], [78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128]], [[1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128], [184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128], [77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128]], [[1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128], [170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128], [37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128]], [[1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128], [207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128], [102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128]], [[1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128], [177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128], [80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128]], [[1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]]], [[[198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62], [131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1], [68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128]], [[1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128], [184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128], [81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128]], [[1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128], [99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128], [23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128]], [[1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128], [109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128], [44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128]], [[1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128], [94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128], [22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128]], [[1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128], [124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128], [35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128]], [[1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128], [121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128], [45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128]], [[1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128], [203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128], [137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128]]], [[[253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128], [175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128], [73, 17, 171, 221, 161, 179, 236, 167, 255, 234,
23709128]], [[1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128], [239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128], [155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128]], [[1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128], [201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128], [69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128]], [[1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128], [223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128], [141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128]], [[1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128], [190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128], [149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128]], [[1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128], [247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128], [240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128]], [[1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128], [213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128], [55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128]], [[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]]], [[[202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255], [126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128], [61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128]], [[1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128], [166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128], [39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128]], [[1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128], [124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128], [24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128]], [[1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128], [149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128], [28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128]], [[1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128], [123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128], [20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128]], [[1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128], [168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128], [47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128]], [[1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128], [141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128], [42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128]], [[1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128]]]], 23710 Ke = [[[231, 120, 48, 89, 115, 113, 120, 152, 112], [152, 179, 64, 126, 170, 118, 46, 70, 95], [175, 69, 143, 80, 85, 82, 72, 155, 103], [56, 58, 10, 171, 218, 189, 17, 13, 152], [114, 26, 17, 163, 44, 195, 21, 10, 173], [121, 24, 80, 195, 26, 62, 44, 64, 85], [144, 71, 10, 38, 171, 213, 144, 34, 26], [170, 46, 55, 19, 136, 160, 33, 206, 71], [63, 20, 8, 114, 114, 208, 12, 9, 226], [81, 40, 11, 96, 182, 84, 29, 16, 36]], [[134, 183, 89, 137, 98, 101, 106, 165, 148], [72, 187, 100, 130, 157, 111, 32, 75, 80], [66, 102, 16
237107, 99, 74, 62, 40, 234, 128], [41, 53, 9, 178, 241, 141, 26, 8, 107], [74, 43, 26, 146, 73, 166, 49, 23, 157], [65, 38, 105, 160, 51, 52, 31, 115, 128], [104, 79, 12, 27, 217, 255, 87, 17, 7], [87, 68, 71, 44, 114, 51, 15, 186, 23], [47, 41, 14, 110, 182, 183, 21, 17, 194], [66, 45, 25, 102, 197, 189, 23, 18, 22]], [[88, 88, 147, 150, 42, 46, 45, 196, 205], [43, 97, 183, 117, 85, 38, 35, 179, 61], [39, 53, 200, 87, 26, 21, 43, 232, 171], [56, 34, 51, 104, 114, 102, 29, 93, 77], [39, 28, 85, 171, 58, 165, 90, 98, 64], [34, 22, 116, 206, 23, 34, 43, 166, 73], [107, 54, 32, 26, 51, 1, 81, 43, 31], [68, 25, 106, 22, 64, 171, 36, 225, 114], [34, 19, 21, 102, 132, 188, 16, 76, 124], [62, 18, 78, 95, 85, 57, 50, 48, 51]], [[193, 101, 35, 159, 215, 111, 89, 46, 111], [60, 148, 31, 172, 219, 228, 21, 18, 111], [112, 113, 77, 85, 179, 255, 38, 120, 114], [40, 42, 1, 196, 245, 209, 10, 25, 109], [88, 43, 29, 140, 166, 213, 37, 43, 154], [61, 63, 30, 155, 67, 45, 68, 1, 209], [100, 80, 8, 43, 154, 1, 51, 26, 71], [142, 78, 78, 16, 255, 128, 34, 197, 171], [41, 40, 5, 102, 211, 183, 4, 1, 221], [51, 50, 17, 168, 209, 192, 23, 25, 82]], [[138, 31, 36, 171, 27, 166, 38, 44, 229], [67, 87, 58, 169, 82, 115, 26, 59, 179], [63, 59, 90, 180, 59, 166, 93, 73, 154], [40, 40, 21, 116, 143, 209, 34, 39, 175], [47, 15, 16, 183, 34, 223, 49, 45, 183], [46, 17, 33, 183, 6, 98, 15, 32, 183], [57, 46, 22, 24, 128, 1, 54, 17, 37], [65, 32, 73, 115, 28, 128, 23, 128, 205], [40, 3, 9, 115, 51, 192, 18, 6, 223], [87, 37, 9, 115, 59, 77, 64, 21, 47]], [[104, 55, 44, 218, 9, 54, 53, 130, 226], [64, 90, 70, 205, 40, 41, 23, 26, 57], [54, 57, 112, 184, 5, 41, 38, 166, 213], [30, 34, 26, 133, 152, 116, 10, 32, 134], [39, 19, 53, 221, 26, 114, 32, 73, 255], [31, 9, 65, 234, 2, 15, 1, 118, 73], [75, 32, 12, 51, 192, 255, 160, 43, 51], [88, 31, 35, 67, 102, 85, 55, 186, 85], [56, 21, 23, 111, 59, 205, 45, 37, 192], [55, 38, 70, 124, 73, 102, 1, 34, 98]], [[125, 98, 42, 88, 104, 85, 117, 175, 82], [95, 84, 53, 89, 128, 100, 113, 101, 45], [75, 79, 123, 47, 51, 128, 81, 171, 1], [57, 17, 5, 71, 102, 57, 53, 41, 49], [38, 33, 13, 121, 57, 73, 26, 1, 85], [41, 10, 67, 138, 77, 110, 90, 47, 114], [115, 21, 2, 10, 102, 255, 166, 23, 6], [101, 29, 16, 10, 85, 128, 101, 196, 26], [57, 18, 10, 102, 102, 213, 34, 20, 43], [117, 20, 15, 36, 163, 128, 68, 1, 26]], [[102, 61, 71, 37, 34, 53, 31, 243, 192], [69, 60, 71, 38, 73, 119, 28, 222, 37], [68, 45, 128, 34, 1, 47, 11, 245, 171], [62, 17, 19, 70, 146, 85, 55, 62, 70], [37, 43, 37, 154, 100, 163, 85, 160, 1], [63, 9, 92, 136, 28, 64, 32, 201, 85], [75, 15, 9, 9, 64, 255, 184, 119, 16], [86, 6, 28, 5, 64, 255, 25, 248, 1], [56, 8, 17, 132, 137, 255, 55, 116, 128], [58, 15, 20, 82, 135, 57, 26, 121, 40]], [[164, 50, 31, 137, 154, 133, 25, 35, 218], [51, 103, 44, 131, 131, 123, 31, 6, 158], [86, 40, 64, 135, 148, 224, 45, 183, 128], [22, 26, 17, 131, 240, 154, 14, 1, 209], [45, 16, 21, 91, 64, 222, 7, 1, 197], [56, 21, 39, 155, 60, 138, 23, 102, 213], [83, 12, 13, 54, 192, 255, 68, 47, 28], [85, 26, 85, 85, 128, 128, 32, 146, 171], [18, 11, 7, 63, 144, 171, 4, 4, 246], [35, 27, 10, 146, 174, 171, 12, 26, 128]], [[190, 80, 35, 99, 180, 80, 126, 54, 45], [85, 126, 47, 87, 176, 51, 41, 20, 32], [101, 75, 128, 139, 118, 146, 116, 128, 85], [56, 41, 15, 176, 236, 85, 37, 9, 62], [71, 30, 17, 119, 118, 255, 17, 18, 138], [101, 38, 60, 138, 55, 70, 43, 26, 142], [146, 36, 19, 30, 171, 255, 97, 27, 20], [138, 45, 61, 62, 219, 1, 81, 188, 64], [32, 41, 20, 117, 151, 142, 20, 21, 163], [112, 19, 12, 61, 195, 128, 48, 4, 24]]], 23711 Ee = [[[[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255], [223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255], [249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255], [234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255], [239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255], [251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255], [250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]], [[[217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255], [234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255]], [[255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255]], [[255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255], [249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255], [247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255], [250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]], [[[186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255], [234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255], [251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255]], [[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255]], [[255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]], [[[248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255], [248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255], [246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255], [252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255]], [[255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255], [248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255], [253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255]], [[255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255], [245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255], [253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255], [252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255], [249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255], [250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]]], 23712 Ge = [0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 0], 23713 Nc, 23714 Y = [], 23715 W = [], 23716 ka = [], 23717 Za, 23718 fd, 23719 Nb, 23720 pa, 23721 Ob, 23722 Xc, 23723 Tc, 23724 Yc, 23725 Uc, 23726 Zc, 23727 Vc, 23728 $c, 23729 Wc, 23730 Rc, 23731 Pc, 23732 Sc, 23733 Qc,
vendor: 7,620 bytes, lines 23734-23961
23734 re = 1, 23735 Cc = 2, 23736 ia = [], 23737 za, 23738 vc, 23739 fc, 23740 Fc, 23741 P = []; 23742 va("UpsampleRgbLinePair", Ga, 3); 23743 va("UpsampleBgrLinePair", Tb, 3); 23744 va("UpsampleRgbaLinePair", wd, 4); 23745 va("UpsampleBgraLinePair", vd, 4); 23746 va("UpsampleArgbLinePair", ud, 4); 23747 va("UpsampleRgba4444LinePair", td, 2); 23748 va("UpsampleRgb565LinePair", sd, 2); 23749 var Mf = self.UpsampleRgbLinePair, 23750 Nf = self.UpsampleBgrLinePair, 23751 nd = self.UpsampleRgbaLinePair, 23752 od = self.UpsampleBgraLinePair, 23753 pd = self.UpsampleArgbLinePair, 23754 qd = self.UpsampleRgba4444LinePair, 23755 Of = self.UpsampleRgb565LinePair, 23756 Wa = 16, 23757 Ba = 1 << Wa - 1, 23758 ta = -227, 23759 Eb = 482, 23760 rd = 6, 23761 Pf = (256 << rd) - 1, 23762 jc = 0, 23763 Yd = V(256), 23764 ae = V(256), 23765 $d = V(256), 23766 Zd = V(256), 23767 be = V(Eb - ta), 23768 ce = V(Eb - ta); 23769 la("YuvToRgbRow", Ga, 3); 23770 la("YuvToBgrRow", Tb, 3); 23771 la("YuvToRgbaRow", wd, 4); 23772 la("YuvToBgraRow", vd, 4); 23773 la("YuvToArgbRow", ud, 4); 23774 la("YuvToRgba4444Row", td, 2); 23775 la("YuvToRgb565Row", sd, 2); 23776 var zd = [0, 4, 8, 12, 128, 132, 136, 140, 256, 260, 264, 268, 384, 388, 392, 396], 23777 Ya = [0, 2, 8], 23778 Qf = [8, 7, 6, 4, 4, 2, 2, 2, 1, 1, 1, 1], 23779 Ne = 1; 23780 23781 this.WebPDecodeRGBA = function (a, b, c, d, e) { 23782 var f = Ua; 23783 var g = new Cf(), 23784 h = new Cb(); 23785 g.ba = h; 23786 h.S = f; 23787 h.width = [h.width]; 23788 h.height = [h.height]; 23789 var k = h.width; 23790 var l = h.height, 23791 m = new Td(); 23792 if (null == m || null == a) var n = 2;else x(null != m), n = Ad(a, b, c, m.width, m.height, m.Pd, m.Qd, m.format, null); 23793 0 != n ? k = 0 : (null != k && (k[0] = m.width[0]), null != l && (l[0] = m.height[0]), k = 1); 23794 23795 if (k) { 23796 h.width = h.width[0]; 23797 h.height = h.height[0]; 23798 null != d && (d[0] = h.width); 23799 null != e && (e[0] = h.height); 23800 23801 b: { 23802 d = new Oa(); 23803 e = new md(); 23804 e.data = a; 23805 e.w = b; 23806 e.ha = c; 23807 e.kd = 1; 23808 b = [0]; 23809 x(null != e); 23810 a = Ad(e.data, e.w, e.ha, null, null, null, b, null, e); 23811 (0 == a || 7 == a) && b[0] && (a = 4); 23812 b = a; 23813 23814 if (0 == b) { 23815 x(null != g); 23816 d.data = e.data; 23817 d.w = e.w + e.offset; 23818 d.ha = e.ha - e.offset; 23819 d.put = kc; 23820 d.ac = gc; 23821 d.bc = lc; 23822 d.ma = g; 23823 23824 if (e.xa) { 23825 a = Bc(); 23826 23827 if (null == a) { 23828 g = 1; 23829 break b; 23830 } 23831 23832 if (te(a, d)) { 23833 b = Cd(d.width, d.height, g.Oa, g.ba); 23834 23835 if (d = 0 == b) { 23836 c: { 23837 d = a; 23838 23839 d: for (;;) { 23840 if (null == d) { 23841 d = 0; 23842 break c; 23843 } 23844 23845 x(null != d.s.yc); 23846 x(null != d.s.Ya); 23847 x(0 < d.s.Wb); 23848 c = d.l; 23849 x(null != c); 23850 e = c.ma; 23851 x(null != e); 23852 23853 if (0 != d.xb) { 23854 d.ca = e.ba; 23855 d.tb = e.tb; 23856 x(null != d.ca); 23857 23858 if (!hc(e.Oa, c, Va)) { 23859 d.a = 2; 23860 break d; 23861 } 23862 23863 if (!Ec(d, c.width)) break d; 23864 if (c.da) break d; 23865 (c.da || hb(d.ca.S)) && Aa(); 23866 11 > d.ca.S || (alert("todo:WebPInitConvertARGBToYUV"), null != d.ca.f.kb.F && Aa()); 23867 23868 if (d.Pb && 0 < d.s.ua && null == d.s.vb.X && !Zb(d.s.vb, d.s.Wa.Xa)) { 23869 d.a = 1; 23870 break d; 23871 } 23872 23873 d.xb = 0; 23874 } 23875 23876 if (!Jb(d, d.V, d.Ba, d.c, d.i, c.o, ge)) break d; 23877 e.Dc = d.Ma; 23878 d = 1; 23879 break c; 23880 } 23881 23882 x(0 != d.a); 23883 d = 0; 23884 } 23885 23886 d = !d; 23887 } 23888 23889 d && (b = a.a); 23890 } else b = a.a; 23891 } else { 23892 a = new Ce(); 23893 23894 if (null == a) { 23895 g = 1; 23896 break b; 23897 } 23898 23899 a.Fa = e.na; 23900 a.P = e.P; 23901 a.qc = e.Sa; 23902 23903 if (Kc(a, d)) { 23904 if (b = Cd(d.width, d.height, g.Oa, g.ba), 0 == b) { 23905 a.Aa = 0; 23906 c = g.Oa; 23907 e = a; 23908 x(null != e); 23909 23910 if (null != c) { 23911 k = c.Md; 23912 k = 0 > k ? 0 : 100 < k ? 255 : 255 * k / 100; 23913 23914 if (0 < k) { 23915 for (l = m = 0; 4 > l; ++l) { 23916 n = e.pb[l], 12 > n.lc && (n.ia = k * Qf[0 > n.lc ? 0 : n.lc] >> 3), m |= n.ia; 23917 } 23918 23919 m && (alert("todo:VP8InitRandom"), e.ia = 1); 23920 } 23921 23922 e.Ga = c.Id; 23923 100 < e.Ga ? e.Ga = 100 : 0 > e.Ga && (e.Ga = 0); 23924 } 23925 23926 Me(a, d) || (b = a.a); 23927 } 23928 } else b = a.a; 23929 } 23930 23931 0 == b && null != g.Oa && g.Oa.fd && (b = Bd(g.ba)); 23932 } 23933 23934 g = b; 23935 } 23936 23937 f = 0 != g ? null : 11 > f ? h.f.RGBA.eb : h.f.kb.y; 23938 } else f = null; 23939 23940 return f; 23941 }; 23942 23943 var Dd = [3, 4, 3, 4, 4, 2, 2, 4, 4, 4, 2, 1, 1]; 23944 }; 23945 23946 new _WebPDecoder(); 23947 /** @license 23948 * Copyright (c) 2017 Dominik Homberger 23949 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 23950 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 23951 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23952 https://webpjs.appspot.com 23953 WebPRiffParser [email protected] 23954 */ 23955 23956 function memcmp(data, data_off, str, size) { 23957 for (var i = 0; i < size; i++) { 23958 if (data[data_off + i] != str.charCodeAt(i)) return true; 23959 } 23960 23961 return false;
23962 } 23963 23964 function GetTag(data, data_off) { 23965 var str = ""; 23966 23967 for (var i = 0; i < 4; i++) { 23968 str += String.fromCharCode(data[data_off++]); 23969 } 23970 23971 return str; 23972 } 23973 23974 function GetLE16(data, data_off) { 23975 return data[data_off + 0] << 0 | data[data_off + 1] << 8; 23976 } 23977 23978 function GetLE24(data, data_off) { 23979 return (data[data_off + 0] << 0 | data[data_off + 1] << 8 | data[data_off + 2] << 16) >>> 0; 23980 } 23981 23982 function GetLE32(data, data_off) { 23983 return (data[data_off + 0] << 0 | data[data_off + 1] << 8 | data[data_off + 2] << 16 | data[data_off + 3] << 24) >>> 0; 23984 } 23985 23986 function WebPRiffParser(src, src_off) { 23987 var imagearray = {}; 23988 var i = 0; 23989 var alpha_chunk = false; 23990 var alpha_size = 0; 23991 var alpha_offset = 0; 23992 imagearray["frames"] = []; 23993 if (memcmp(src, src_off, "RIFF", 4)) return; 23994 src_off += 4; 23995 var riff_size = GetLE32(src, src_off) + 8; 23996 src_off += 8; 23997 23998 while (src_off < src.length) { 23999 var fourcc = GetTag(src, src_off); 24000 src_off += 4; 24001 var payload_size = GetLE32(src, src_off); 24002 src_off += 4; 24003 var payload_size_padded = payload_size + (payload_size & 1); 24004 24005 switch (fourcc) { 24006 case "VP8 ": 24007 case "VP8L": 24008 if (typeof imagearray["frames"][i] === "undefined") imagearray["frames"][i] = {}; 24009 var obj = imagearray["frames"][i]; 24010 var height = [0]; 24011 var width = [0]; 24012 obj["src_off"] = alpha_chunk ? alpha_offset : src_off - 8; 24013 obj["src_size"] = alpha_size + payload_size + 8; //var rgba = webpdecoder.WebPDecodeRGBA(src,(alpha_chunk?alpha_offset:src_off-8),alpha_size+payload_size+8,width,height); 24014 //imagearray[i]={'rgba':rgba,'width':width[0],'height':height[0]}; 24015 24016 i++; 24017 24018 if (alpha_chunk) { 24019 alpha_chunk = false; 24020 alpha_size = 0; 24021 alpha_offset = 0; 24022 } 24023 24024 break; 24025 24026 case "VP8X": 24027 var obj = imagearray["header"] = {}; 24028 var feature_flags = obj["feature_flags"] = src[src_off]; 24029 var src_off_ = src_off + 4; 24030 var canvas_width = obj["canvas_width"] = 1 + GetLE24(src, src_off_); 24031 src_off_ += 3; 24032 var canvas_height = obj["canvas_height"] = 1 + GetLE24(src, src_off_); 24033 src_off_ += 3; 24034 break; 24035 24036 case "ALPH": 24037 alpha_chunk = true; 24038 alpha_size = payload_size_padded + 8; 24039 alpha_offset = src_off - 8; 24040 break; 24041 24042 case "ANIM": 24043 var obj = imagearray["header"]; 24044 var bgcolor = obj["bgcolor"] = GetLE32(src, src_off); 24045 src_off_ = src_off + 4; 24046 var loop_count = obj["loop_count"] = GetLE16(src, src_off_); 24047 src_off_ += 2; 24048 break; 24049 24050 case "ANMF": 24051 var offset_x = 0, 24052 offset_y = 0, 24053 width = 0, 24054 height = 0, 24055 duration = 0, 24056 blend = 0, 24057 dispose = 0, 24058 temp = 0; 24059 var obj = imagearray["frames"][i] = {}; 24060 obj["offset_x"] = offset_x = 2 * GetLE24(src, src_off); 24061 src_off += 3; 24062 obj["offset_y"] = offset_y = 2 * GetLE24(src, src_off); 24063 src_off += 3; 24064 obj["width"] = width = 1 + GetLE24(src, src_off); 24065 src_off += 3; 24066 obj["height"] = height = 1 + GetLE24(src, src_off); 24067 src_off += 3; 24068 obj["duration"] = duration = GetLE24(src, src_off); 24069 src_off += 3; 24070 temp = src[src_off++]; 24071 obj["dispose"] = dispose = temp & 1; 24072 obj["blend"] = blend = temp >> 1 & 1; 24073 break; 24074 } 24075 24076 if (fourcc != "ANMF") src_off += payload_size_padded; 24077 } 24078 24079 return imagearray; 24080 } 24081 24082 var height = [0]; 24083 var width = [0]; 24084 var pixels = []; 24085 var webpdecoder = new _WebPDecoder(); 24086 var response = imageData; 24087 var imagearray = WebPRiffParser(response, 0); 24088 imagearray["response"] = response; 24089 imagearray["rgbaoutput"] = true; 24090 imagearray["dataurl"] = false;
vendor: 5,115 bytes, lines 24091-24263
24091 var header = imagearray["header"] ? imagearray["header"] : null; 24092 var frames = imagearray["frames"] ? imagearray["frames"] : null; 24093 24094 if (header) { 24095 header["loop_counter"] = header["loop_count"]; 24096 height = [header["canvas_height"]]; 24097 width = [header["canvas_width"]]; 24098 24099 for (var f = 0; f < frames.length; f++) { 24100 if (frames[f]["blend"] == 0) { 24101 break; 24102 } 24103 } 24104 } 24105 24106 var frame = frames[0]; 24107 var rgba = webpdecoder.WebPDecodeRGBA(response, frame["src_off"], frame["src_size"], width, height); 24108 frame["rgba"] = rgba; 24109 frame["imgwidth"] = width[0]; 24110 frame["imgheight"] = height[0]; 24111 24112 for (var i = 0; i < width[0] * height[0] * 4; i++) { 24113 pixels[i] = rgba[i]; 24114 } 24115 24116 this.width = width; 24117 this.height = height; 24118 this.data = pixels; 24119 return this; 24120 } 24121 24122 WebPDecoder.prototype.getData = function () { 24123 return this.data; 24124 }; 24125 24126 /** 24127 * @license 24128 * Copyright (c) 2019 Aras Abbasi 24129 * 24130 * Licensed under the MIT License. 24131 * http://opensource.org/licenses/mit-license 24132 */ 24133 /** 24134 * jsPDF webp Support PlugIn 24135 * 24136 * @name webp_support 24137 * @module 24138 */ 24139 24140 (function (jsPDFAPI) { 24141 24142 jsPDFAPI.processWEBP = function (imageData, index, alias, compression) { 24143 var reader = new WebPDecoder(imageData, false); 24144 var width = reader.width, 24145 height = reader.height; 24146 var qu = 100; 24147 var pixels = reader.getData(); 24148 var rawImageData = { 24149 data: pixels, 24150 width: width, 24151 height: height 24152 }; 24153 var encoder = new JPEGEncoder(qu); 24154 var data = encoder.encode(rawImageData, qu); 24155 return jsPDFAPI.processJPEG.call(this, data, index, alias, compression); 24156 }; 24157 })(jsPDF.API); 24158 24159 /** 24160 * @license 24161 * 24162 * Copyright (c) 2021 Antti Palola, https://github.com/Pantura 24163 * 24164 * Permission is hereby granted, free of charge, to any person obtaining 24165 * a copy of this software and associated documentation files (the 24166 * "Software"), to deal in the Software without restriction, including 24167 * without limitation the rights to use, copy, modify, merge, publish, 24168 * distribute, sublicense, and/or sell copies of the Software, and to 24169 * permit persons to whom the Software is furnished to do so, subject to 24170 * the following conditions: 24171 * 24172 * The above copyright notice and this permission notice shall be 24173 * included in all copies or substantial portions of the Software. 24174 * 24175 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24176 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24177 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24178 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24179 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24180 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24181 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24182 * ==================================================================== 24183 */ 24184 /** 24185 * jsPDF RGBA array PlugIn 24186 * @name rgba_support 24187 * @module 24188 */ 24189 24190 (function (jsPDFAPI) { 24191 /** 24192 * @name processRGBA 24193 * @function 24194 * 24195 * Process RGBA Array. This is a one-dimension array with pixel data [red, green, blue, alpha, red, green, ...]. 24196 * RGBA array data can be obtained from DOM canvas getImageData. 24197 * @ignore 24198 */ 24199 24200 jsPDFAPI.processRGBA = function (imageData, index, alias) { 24201 24202 var imagePixels = imageData.data; 24203 var length = imagePixels.length; // jsPDF takes alpha data separately so extract that. 24204 24205 var rgbOut = new Uint8Array(length / 4 * 3); 24206 var alphaOut = new Uint8Array(length / 4); 24207 var outIndex = 0; 24208 var alphaIndex = 0; 24209 24210 for (var i = 0; i < length; i += 4) { 24211 var r = imagePixels[i]; 24212 var g = imagePixels[i + 1]; 24213 var b = imagePixels[i + 2]; 24214 var alpha = imagePixels[i + 3]; 24215 rgbOut[outIndex++] = r; 24216 rgbOut[outIndex++] = g; 24217 rgbOut[outIndex++] = b; 24218 alphaOut[alphaIndex++] = alpha; 24219 } 24220 24221 var rgbData = this.__addimage__.arrayBufferToBinaryString(rgbOut); 24222 24223 var alphaData = this.__addimage__.arrayBufferToBinaryString(alphaOut); 24224 24225 return { 24226 alpha: alphaData, 24227 data: rgbData, 24228 index: index, 24229 alias: alias, 24230 colorSpace: "DeviceRGB", 24231 bitsPerComponent: 8, 24232 width: imageData.width, 24233 height: imageData.height 24234 }; 24235 }; 24236 })(jsPDF.API); 24237 24238 /** 24239 * @license 24240 * Licensed under the MIT License. 24241 * http://opensource.org/licenses/mit-license 24242 */ 24243 /** 24244 * jsPDF setLanguage Plugin 24245 * 24246 * @name setLanguage 24247 * @module 24248 */ 24249 24250 (function (jsPDFAPI) { 24251 /** 24252 * Add Language Tag to the generated PDF 24253 * 24254 * @name setLanguage 24255 * @function 24256 * @param {string} langCode The Language code as ISO-639-1 (e.g. 'en') or as country language code (e.g. 'en-GB'). 24257 * @returns {jsPDF} 24258 * @example 24259 * var doc = new jsPDF() 24260 * doc.text(10, 10, 'This is a test') 24261 * doc.setLanguage("en-US") 24262 * doc.save('english.pdf') 24263 */
vendor: 5,873 bytes, lines 24264-24464
24264 24265 jsPDFAPI.setLanguage = function (langCode) { 24266 24267 var langCodes = { 24268 af: "Afrikaans", 24269 sq: "Albanian", 24270 ar: "Arabic (Standard)", 24271 "ar-DZ": "Arabic (Algeria)", 24272 "ar-BH": "Arabic (Bahrain)", 24273 "ar-EG": "Arabic (Egypt)", 24274 "ar-IQ": "Arabic (Iraq)", 24275 "ar-JO": "Arabic (Jordan)", 24276 "ar-KW": "Arabic (Kuwait)", 24277 "ar-LB": "Arabic (Lebanon)", 24278 "ar-LY": "Arabic (Libya)", 24279 "ar-MA": "Arabic (Morocco)", 24280 "ar-OM": "Arabic (Oman)", 24281 "ar-QA": "Arabic (Qatar)", 24282 "ar-SA": "Arabic (Saudi Arabia)", 24283 "ar-SY": "Arabic (Syria)", 24284 "ar-TN": "Arabic (Tunisia)", 24285 "ar-AE": "Arabic (U.A.E.)", 24286 "ar-YE": "Arabic (Yemen)", 24287 an: "Aragonese", 24288 hy: "Armenian", 24289 as: "Assamese", 24290 ast: "Asturian", 24291 az: "Azerbaijani", 24292 eu: "Basque", 24293 be: "Belarusian", 24294 bn: "Bengali", 24295 bs: "Bosnian", 24296 br: "Breton", 24297 bg: "Bulgarian", 24298 my: "Burmese", 24299 ca: "Catalan", 24300 ch: "Chamorro", 24301 ce: "Chechen", 24302 zh: "Chinese", 24303 "zh-HK": "Chinese (Hong Kong)", 24304 "zh-CN": "Chinese (PRC)", 24305 "zh-SG": "Chinese (Singapore)", 24306 "zh-TW": "Chinese (Taiwan)", 24307 cv: "Chuvash", 24308 co: "Corsican", 24309 cr: "Cree", 24310 hr: "Croatian", 24311 cs: "Czech", 24312 da: "Danish", 24313 nl: "Dutch (Standard)", 24314 "nl-BE": "Dutch (Belgian)", 24315 en: "English", 24316 "en-AU": "English (Australia)", 24317 "en-BZ": "English (Belize)", 24318 "en-CA": "English (Canada)", 24319 "en-IE": "English (Ireland)", 24320 "en-JM": "English (Jamaica)", 24321 "en-NZ": "English (New Zealand)", 24322 "en-PH": "English (Philippines)", 24323 "en-ZA": "English (South Africa)", 24324 "en-TT": "English (Trinidad & Tobago)", 24325 "en-GB": "English (United Kingdom)", 24326 "en-US": "English (United States)", 24327 "en-ZW": "English (Zimbabwe)", 24328 eo: "Esperanto", 24329 et: "Estonian", 24330 fo: "Faeroese", 24331 fj: "Fijian", 24332 fi: "Finnish", 24333 fr: "French (Standard)", 24334 "fr-BE": "French (Belgium)", 24335 "fr-CA": "French (Canada)", 24336 "fr-FR": "French (France)", 24337 "fr-LU": "French (Luxembourg)", 24338 "fr-MC": "French (Monaco)", 24339 "fr-CH": "French (Switzerland)", 24340 fy: "Frisian", 24341 fur: "Friulian", 24342 gd: "Gaelic (Scots)", 24343 "gd-IE": "Gaelic (Irish)", 24344 gl: "Galacian", 24345 ka: "Georgian", 24346 de: "German (Standard)", 24347 "de-AT": "German (Austria)", 24348 "de-DE": "German (Germany)", 24349 "de-LI": "German (Liechtenstein)", 24350 "de-LU": "German (Luxembourg)", 24351 "de-CH": "German (Switzerland)", 24352 el: "Greek", 24353 gu: "Gujurati", 24354 ht: "Haitian", 24355 he: "Hebrew", 24356 hi: "Hindi", 24357 hu: "Hungarian", 24358 is: "Icelandic", 24359 id: "Indonesian", 24360 iu: "Inuktitut", 24361 ga: "Irish", 24362 it: "Italian (Standard)", 24363 "it-CH": "Italian (Switzerland)", 24364 ja: "Japanese", 24365 kn: "Kannada", 24366 ks: "Kashmiri", 24367 kk: "Kazakh", 24368 km: "Khmer", 24369 ky: "Kirghiz", 24370 tlh: "Klingon", 24371 ko: "Korean", 24372 "ko-KP": "Korean (North Korea)", 24373 "ko-KR": "Korean (South Korea)", 24374 la: "Latin", 24375 lv: "Latvian", 24376 lt: "Lithuanian", 24377 lb: "Luxembourgish", 24378 mk: "North Macedonia", 24379 ms: "Malay", 24380 ml: "Malayalam", 24381 mt: "Maltese", 24382 mi: "Maori", 24383 mr: "Marathi", 24384 mo: "Moldavian", 24385 nv: "Navajo", 24386 ng: "Ndonga", 24387 ne: "Nepali", 24388 no: "Norwegian", 24389 nb: "Norwegian (Bokmal)", 24390 nn: "Norwegian (Nynorsk)", 24391 oc: "Occitan", 24392 or: "Oriya", 24393 om: "Oromo", 24394 fa: "Persian", 24395 "fa-IR": "Persian/Iran", 24396 pl: "Polish", 24397 pt: "Portuguese", 24398 "pt-BR": "Portuguese (Brazil)", 24399 pa: "Punjabi", 24400 "pa-IN": "Punjabi (India)", 24401 "pa-PK": "Punjabi (Pakistan)", 24402 qu: "Quechua", 24403 rm: "Rhaeto-Romanic", 24404 ro: "Romanian", 24405 "ro-MO": "Romanian (Moldavia)", 24406 ru: "Russian", 24407 "ru-MO": "Russian (Moldavia)", 24408 sz: "Sami (Lappish)", 24409 sg: "Sango", 24410 sa: "Sanskrit", 24411 sc: "Sardinian", 24412 sd: "Sindhi", 24413 si: "Singhalese", 24414 sr: "Serbian", 24415 sk: "Slovak", 24416 sl: "Slovenian", 24417 so: "Somani", 24418 sb: "Sorbian", 24419 es: "Spanish", 24420 "es-AR": "Spanish (Argentina)", 24421 "es-BO": "Spanish (Bolivia)", 24422 "es-CL": "Spanish (Chile)", 24423 "es-CO": "Spanish (Colombia)", 24424 "es-CR": "Spanish (Costa Rica)", 24425 "es-DO": "Spanish (Dominican Republic)", 24426 "es-EC": "Spanish (Ecuador)", 24427 "es-SV": "Spanish (El Salvador)", 24428 "es-GT": "Spanish (Guatemala)", 24429 "es-HN": "Spanish (Honduras)", 24430 "es-MX": "Spanish (Mexico)", 24431 "es-NI": "Spanish (Nicaragua)", 24432 "es-PA": "Spanish (Panama)", 24433 "es-PY": "Spanish (Paraguay)", 24434 "es-PE": "Spanish (Peru)", 24435 "es-PR": "Spanish (Puerto Rico)", 24436 "es-ES": "Spanish (Spain)", 24437 "es-UY": "Spanish (Uruguay)", 24438 "es-VE": "Spanish (Venezuela)", 24439 sx: "Sutu", 24440 sw: "Swahili", 24441 sv: "Swedish", 24442 "sv-FI": "Swedish (Finland)", 24443 "sv-SV": "Swedish (Sweden)", 24444 ta: "Tamil", 24445 tt: "Tatar", 24446 te: "Teluga", 24447 th: "Thai", 24448 tig: "Tigre", 24449 ts: "Tsonga", 24450 tn: "Tswana", 24451 tr: "Turkish", 24452 tk: "Turkmen", 24453 uk: "Ukrainian", 24454 hsb: "Upper Sorbian", 24455 ur: "Urdu", 24456 ve: "Venda", 24457 vi: "Vietnamese", 24458 vo: "Volapuk", 24459 wa: "Walloon", 24460 cy: "Welsh", 24461 xh: "Xhosa", 24462 ji: "Yiddish", 24463 zu: "Zulu" 24464 };
vendor: 12,007 bytes, lines 24465-24823
24465 24466 if (this.internal.languageSettings === undefined) { 24467 this.internal.languageSettings = {}; 24468 this.internal.languageSettings.isSubscribed = false; 24469 } 24470 24471 if (langCodes[langCode] !== undefined) { 24472 this.internal.languageSettings.languageCode = langCode; 24473 24474 if (this.internal.languageSettings.isSubscribed === false) { 24475 this.internal.events.subscribe("putCatalog", function () { 24476 this.internal.write("/Lang (" + this.internal.languageSettings.languageCode + ")"); 24477 }); 24478 this.internal.languageSettings.isSubscribed = true; 24479 } 24480 } 24481 24482 return this; 24483 }; 24484 })(jsPDF.API); 24485 24486 /** 24487 * jsPDF split_text_to_size plugin 24488 * 24489 * @name split_text_to_size 24490 * @module 24491 */ 24492 24493 (function (API) { 24494 /** 24495 * Returns an array of length matching length of the 'word' string, with each 24496 * cell occupied by the width of the char in that position. 24497 * 24498 * @name getCharWidthsArray 24499 * @function 24500 * @param {string} text 24501 * @param {Object} options 24502 * @returns {Array} 24503 */ 24504 24505 var getCharWidthsArray = API.getCharWidthsArray = function (text, options) { 24506 options = options || {}; 24507 var activeFont = options.font || this.internal.getFont(); 24508 var fontSize = options.fontSize || this.internal.getFontSize(); 24509 var charSpace = options.charSpace || this.internal.getCharSpace(); 24510 var widths = options.widths ? options.widths : activeFont.metadata.Unicode.widths; 24511 var widthsFractionOf = widths.fof ? widths.fof : 1; 24512 var kerning = options.kerning ? options.kerning : activeFont.metadata.Unicode.kerning; 24513 var kerningFractionOf = kerning.fof ? kerning.fof : 1; 24514 var doKerning = options.doKerning === false ? false : true; 24515 var kerningValue = 0; 24516 var i; 24517 var length = text.length; 24518 var char_code; 24519 var prior_char_code = 0; //for kerning 24520 24521 var default_char_width = widths[0] || widthsFractionOf; 24522 var output = []; 24523 24524 for (i = 0; i < length; i++) { 24525 char_code = text.charCodeAt(i); 24526 24527 if (typeof activeFont.metadata.widthOfString === "function") { 24528 output.push((activeFont.metadata.widthOfGlyph(activeFont.metadata.characterToGlyph(char_code)) + charSpace * (1000 / fontSize) || 0) / 1000); 24529 } else { 24530 if (doKerning && _typeof(kerning[char_code]) === "object" && !isNaN(parseInt(kerning[char_code][prior_char_code], 10))) { 24531 kerningValue = kerning[char_code][prior_char_code] / kerningFractionOf; 24532 } else { 24533 kerningValue = 0; 24534 } 24535 24536 output.push((widths[char_code] || default_char_width) / widthsFractionOf + kerningValue); 24537 } 24538 24539 prior_char_code = char_code; 24540 } 24541 24542 return output; 24543 }; 24544 /** 24545 * Returns a widths of string in a given font, if the font size is set as 1 point. 24546 * 24547 * In other words, this is "proportional" value. For 1 unit of font size, the length 24548 * of the string will be that much. 24549 * 24550 * Multiply by font size to get actual width in *points* 24551 * Then divide by 72 to get inches or divide by (72/25.6) to get 'mm' etc. 24552 * 24553 * @name getStringUnitWidth 24554 * @public 24555 * @function 24556 * @param {string} text 24557 * @param {string} options 24558 * @returns {number} result 24559 */ 24560 24561 24562 var getStringUnitWidth = API.getStringUnitWidth = function (text, options) { 24563 options = options || {}; 24564 var fontSize = options.fontSize || this.internal.getFontSize(); 24565 var font = options.font || this.internal.getFont(); 24566 var charSpace = options.charSpace || this.internal.getCharSpace(); 24567 var result = 0; 24568 24569 if (API.processArabic) { 24570 text = API.processArabic(text); 24571 } 24572 24573 if (typeof font.metadata.widthOfString === "function") { 24574 result = font.metadata.widthOfString(text, fontSize, charSpace) / fontSize; 24575 } else { 24576 result = getCharWidthsArray.apply(this, arguments).reduce(function (pv, cv) { 24577 return pv + cv; 24578 }, 0); 24579 } 24580 24581 return result; 24582 }; 24583 /** 24584 returns array of lines 24585 */ 24586 24587 24588 var splitLongWord = function splitLongWord(word, widths_array, firstLineMaxLen, maxLen) { 24589 var answer = []; // 1st, chop off the piece that can fit on the hanging line. 24590 24591 var i = 0, 24592 l = word.length, 24593 workingLen = 0; 24594 24595 while (i !== l && workingLen + widths_array[i] < firstLineMaxLen) { 24596 workingLen += widths_array[i]; 24597 i++; 24598 } // this is first line. 24599 24600 24601 answer.push(word.slice(0, i)); // 2nd. Split the rest into maxLen pieces. 24602 24603 var startOfLine = i; 24604 workingLen = 0; 24605 24606 while (i !== l) { 24607 if (workingLen + widths_array[i] > maxLen) { 24608 answer.push(word.slice(startOfLine, i)); 24609 workingLen = 0; 24610 startOfLine = i; 24611 } 24612 24613 workingLen += widths_array[i]; 24614 i++; 24615 } 24616 24617 if (startOfLine !== i) { 24618 answer.push(word.slice(startOfLine, i)); 24619 } 24620 24621 return answer; 24622 }; // Note, all sizing inputs for this function must be in "font measurement units" 24623 // By default, for PDF, it's "point". 24624 24625 24626 var splitParagraphIntoLines = function splitParagraphIntoLines(text, maxlen, options) { 24627 // at this time works only on Western scripts, ones with space char 24628 // separating the words. Feel free to expand. 24629 if (!options) { 24630 options = {}; 24631 } 24632 24633 var line = [], 24634 lines = [line], 24635 line_length = options.textIndent || 0, 24636 separator_length = 0, 24637 current_word_length = 0, 24638 word, 24639 widths_array, 24640 words = text.split(" "), 24641 spaceCharWidth = getCharWidthsArray.apply(this, [" ", options])[0], 24642 i, 24643 l, 24644 tmp, 24645 lineIndent; 24646 24647 if (options.lineIndent === -1) { 24648 lineIndent = words[0].length + 2; 24649 } else { 24650 lineIndent = options.lineIndent || 0; 24651 } 24652 24653 if (lineIndent) { 24654 var pad = Array(lineIndent).join(" "), 24655 wrds = []; 24656 words.map(function (wrd) { 24657 wrd = wrd.split(/\s*\n/); 24658 24659 if (wrd.length > 1) { 24660 wrds = wrds.concat(wrd.map(function (wrd, idx) { 24661 return (idx && wrd.length ? "\n" : "") + wrd; 24662 })); 24663 } else { 24664 wrds.push(wrd[0]); 24665 } 24666 }); 24667 words = wrds; 24668 lineIndent = getStringUnitWidth.apply(this, [pad, options]); 24669 } 24670 24671 for (i = 0, l = words.length; i < l; i++) { 24672 var force = 0; 24673 word = words[i]; 24674 24675 if (lineIndent && word[0] == "\n") { 24676 word = word.substr(1); 24677 force = 1; 24678 } 24679 24680 widths_array = getCharWidthsArray.apply(this, [word, options]); 24681 current_word_length = widths_array.reduce(function (pv, cv) { 24682 return pv + cv; 24683 }, 0); 24684 24685 if (line_length + separator_length + current_word_length > maxlen || force) { 24686 if (current_word_length > maxlen) { 24687 // this happens when you have space-less long URLs for example. 24688 // we just chop these to size. We do NOT insert hiphens 24689 tmp = splitLongWord.apply(this, [word, widths_array, maxlen - (line_length + separator_length), maxlen]); // first line we add to existing line object 24690 24691 line.push(tmp.shift()); // it's ok to have extra space indicator there 24692 // last line we make into new line object 24693 24694 line = [tmp.pop()]; // lines in the middle we apped to lines object as whole lines 24695 24696 while (tmp.length) { 24697 lines.push([tmp.shift()]); // single fragment occupies whole line 24698 } 24699 24700 current_word_length = widths_array.slice(word.length - (line[0] ? line[0].length : 0)).reduce(function (pv, cv) { 24701 return pv + cv; 24702 }, 0); 24703 } else { 24704 // just put it on a new line 24705 line = [word]; 24706 } // now we attach new line to lines 24707 24708 24709 lines.push(line); 24710 line_length = current_word_length + lineIndent; 24711 separator_length = spaceCharWidth; 24712 } else { 24713 line.push(word); 24714 line_length += separator_length + current_word_length; 24715 separator_length = spaceCharWidth; 24716 } 24717 } 24718 24719 var postProcess; 24720 24721 if (lineIndent) { 24722 postProcess = function postProcess(ln, idx) { 24723 return (idx ? pad : "") + ln.join(" "); 24724 }; 24725 } else { 24726 postProcess = function postProcess(ln) { 24727 return ln.join(" "); 24728 }; 24729 } 24730 24731 return lines.map(postProcess); 24732 }; 24733 /** 24734 * Splits a given string into an array of strings. Uses 'size' value 24735 * (in measurement units declared as default for the jsPDF instance) 24736 * and the font's "widths" and "Kerning" tables, where available, to 24737 * determine display length of a given string for a given font. 24738 * 24739 * We use character's 100% of unit size (height) as width when Width 24740 * table or other default width is not available. 24741 * 24742 * @name splitTextToSize 24743 * @public 24744 * @function 24745 * @param {string} text Unencoded, regular JavaScript (Unicode, UTF-16 / UCS-2) string. 24746 * @param {number} size Nominal number, measured in units default to this instance of jsPDF. 24747 * @param {Object} options Optional flags needed for chopper to do the right thing. 24748 * @returns {Array} array Array with strings chopped to size. 24749 */ 24750 24751 24752 API.splitTextToSize = function (text, maxlen, options) { 24753 24754 options = options || {}; 24755 24756 var fsize = options.fontSize || this.internal.getFontSize(), 24757 newOptions = function (options) { 24758 var widths = { 24759 0: 1 24760 }, 24761 kerning = {}; 24762 24763 if (!options.widths || !options.kerning) { 24764 var f = this.internal.getFont(options.fontName, options.fontStyle), 24765 encoding = "Unicode"; // NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE 24766 // Actual JavaScript-native String's 16bit char codes used. 24767 // no multi-byte logic here 24768 24769 if (f.metadata[encoding]) { 24770 return { 24771 widths: f.metadata[encoding].widths || widths, 24772 kerning: f.metadata[encoding].kerning || kerning 24773 }; 24774 } else { 24775 return { 24776 font: f.metadata, 24777 fontSize: this.internal.getFontSize(), 24778 charSpace: this.internal.getCharSpace() 24779 }; 24780 } 24781 } else { 24782 return { 24783 widths: options.widths, 24784 kerning: options.kerning 24785 }; 24786 } 24787 }.call(this, options); // first we split on end-of-line chars 24788 24789 24790 var paragraphs; 24791 24792 if (Array.isArray(text)) { 24793 paragraphs = text; 24794 } else { 24795 paragraphs = String(text).split(/\r?\n/); 24796 } // now we convert size (max length of line) into "font size units" 24797 // at present time, the "font size unit" is always 'point' 24798 // 'proportional' means, "in proportion to font size" 24799 24800 24801 var fontUnit_maxLen = 1.0 * this.internal.scaleFactor * maxlen / fsize; // at this time, fsize is always in "points" regardless of the default measurement unit of the doc. 24802 // this may change in the future? 24803 // until then, proportional_maxlen is likely to be in 'points' 24804 // If first line is to be indented (shorter or longer) than maxLen 24805 // we indicate that by using CSS-style "text-indent" option. 24806 // here it's in font units too (which is likely 'points') 24807 // it can be negative (which makes the first line longer than maxLen) 24808 24809 newOptions.textIndent = options.textIndent ? options.textIndent * 1.0 * this.internal.scaleFactor / fsize : 0; 24810 newOptions.lineIndent = options.lineIndent; 24811 var i, 24812 l, 24813 output = []; 24814 24815 for (i = 0, l = paragraphs.length; i < l; i++) { 24816 output = output.concat(splitParagraphIntoLines.apply(this, [paragraphs[i], fontUnit_maxLen, newOptions])); 24817 } 24818 24819 return output; 24820 }; 24821 })(jsPDF.API); 24822 24823 /**
24824 * This file adds the standard font metrics to jsPDF. 24825 * 24826 * Font metrics data is reprocessed derivative of contents of 24827 * "Font Metrics for PDF Core 14 Fonts" package, which exhibits the following copyright and license: 24828 * 24829 * Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. 24830 * 24831 * This file and the 14 PostScript(R) AFM files it accompanies may be used, 24832 * copied, and distributed for any purpose and without charge, with or without 24833 * modification, provided that all copyright notices are retained; that the AFM 24834 * files are not distributed without this file; that all modifications to this 24835 * file or any of the AFM files are prominently noted in the modified file(s); 24836 * and that this paragraph is not modified. Adobe Systems has no responsibility 24837 * or obligation to support the use of the AFM files. 24838 * 24839 * @name standard_fonts_metrics 24840 * @module 24841 */ 24842 24843 (function (API) { 24844 24845 API.__fontmetrics__ = API.__fontmetrics__ || {}; 24846 var decoded = "0123456789abcdef", 24847 encoded = "klmnopqrstuvwxyz", 24848 mappingUncompress = {}, 24849 mappingCompress = {}; 24850 24851 for (var i = 0; i < encoded.length; i++) { 24852 mappingUncompress[encoded[i]] = decoded[i]; 24853 mappingCompress[decoded[i]] = encoded[i]; 24854 } 24855 24856 var hex = function hex(value) { 24857 return "0x" + parseInt(value, 10).toString(16); 24858 }; 24859 24860 var compress = API.__fontmetrics__.compress = function (data) { 24861 var vals = ["{"]; 24862 var value, keystring, valuestring, numberprefix; 24863 24864 for (var key in data) { 24865 value = data[key]; 24866 24867 if (!isNaN(parseInt(key, 10))) { 24868 key = parseInt(key, 10); 24869 keystring = hex(key).slice(2); 24870 keystring = keystring.slice(0, -1) + mappingCompress[keystring.slice(-1)]; 24871 } else { 24872 keystring = "'" + key + "'"; 24873 } 24874 24875 if (typeof value == "number") { 24876 if (value < 0) { 24877 valuestring = hex(value).slice(3); 24878 numberprefix = "-"; 24879 } else { 24880 valuestring = hex(value).slice(2); 24881 numberprefix = ""; 24882 } 24883 24884 valuestring = numberprefix + valuestring.slice(0, -1) + mappingCompress[valuestring.slice(-1)]; 24885 } else { 24886 if (_typeof(value) === "object") { 24887 valuestring = compress(value); 24888 } else { 24889 throw new Error("Don't know what to do with value type " + _typeof(value) + "."); 24890 } 24891 } 24892 24893 vals.push(keystring + valuestring); 24894 } 24895 24896 vals.push("}"); 24897 return vals.join(""); 24898 }; 24899 /** 24900 * Uncompresses data compressed into custom, base16-like format. 24901 * 24902 * @public 24903 * @function 24904 * @param 24905 * @returns {Type} 24906 */ 24907 24908 24909 var uncompress = API.__fontmetrics__.uncompress = function (data) { 24910 if (typeof data !== "string") { 24911 throw new Error("Invalid argument passed to uncompress."); 24912 } 24913 24914 var output = {}, 24915 sign = 1, 24916 stringparts, 24917 // undef. will be [] in string mode 24918 activeobject = output, 24919 parentchain = [], 24920 parent_key_pair, 24921 keyparts = "", 24922 valueparts = "", 24923 key, 24924 // undef. will be Truthy when Key is resolved. 24925 datalen = data.length - 1, 24926 // stripping ending } 24927 ch; 24928 24929 for (var i = 1; i < datalen; i += 1) { 24930 // - { } ' are special. 24931 ch = data[i]; 24932 24933 if (ch == "'") { 24934 if (stringparts) { 24935 // end of string mode 24936 key = stringparts.join(""); 24937 stringparts = undefined; 24938 } else { 24939 // start of string mode 24940 stringparts = []; 24941 } 24942 } else if (stringparts) { 24943 stringparts.push(ch); 24944 } else if (ch == "{") { 24945 // start of object 24946 parentchain.push([activeobject, key]); 24947 activeobject = {}; 24948 key = undefined; 24949 } else if (ch == "}") { 24950 // end of object 24951 parent_key_pair = parentchain.pop(); 24952 parent_key_pair[0][parent_key_pair[1]] = activeobject; 24953 key = undefined; 24954 activeobject = parent_key_pair[0]; 24955 } else if (ch == "-") { 24956 sign = -1; 24957 } else { 24958 // must be number 24959 if (key === undefined) { 24960 if (mappingUncompress.hasOwnProperty(ch)) { 24961 keyparts += mappingUncompress[ch]; 24962 key = parseInt(keyparts, 16) * sign; 24963 sign = +1; 24964 keyparts = ""; 24965 } else { 24966 keyparts += ch; 24967 } 24968 } else { 24969 if (mappingUncompress.hasOwnProperty(ch)) { 24970 valueparts += mappingUncompress[ch]; 24971 activeobject[key] = parseInt(valueparts, 16) * sign; 24972 sign = +1; 24973 key = undefined; 24974 valueparts = ""; 24975 } else { 24976 valueparts += ch; 24977 } 24978 } 24979 } 24980 } 24981 24982 return output; 24983 }; // encoding = 'Unicode' 24984 // NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE. NO clever BOM behavior 24985 // Actual 16bit char codes used. 24986 // no multi-byte logic here 24987 // Unicode characters to WinAnsiEncoding: 24988 // {402: 131, 8211: 150, 8212: 151, 8216: 145, 8217: 146, 8218: 130, 8220: 147, 8221: 148, 8222: 132, 8224: 134, 8225: 135, 8226: 149, 8230: 133, 8364: 128, 8240:137, 8249: 139, 8250: 155, 710: 136, 8482: 153, 338: 140, 339: 156, 732: 152, 352: 138, 353: 154, 376: 159, 381: 142, 382: 158} 24989 // as you can see, all Unicode chars are outside of 0-255 range. No char code conflicts. 24990 // this means that you can give Win cp1252 encoded strings to jsPDF for rendering directly 24991 // as well as give strings with some (supported by these fonts) Unicode characters and 24992 // these will be mapped to win cp1252
24993 // for example, you can send char code (cp1252) 0x80 or (unicode) 0x20AC, getting "Euro" glyph displayed in both cases. 24994 24995 24996 var encodingBlock = { 24997 codePages: ["WinAnsiEncoding"], 24998 WinAnsiEncoding: uncompress("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}") 24999 }; 25000 var encodings = { 25001 Unicode: { 25002 Courier: encodingBlock, 25003 "Courier-Bold": encodingBlock, 25004 "Courier-BoldOblique": encodingBlock, 25005 "Courier-Oblique": encodingBlock, 25006 Helvetica: encodingBlock, 25007 "Helvetica-Bold": encodingBlock, 25008 "Helvetica-BoldOblique": encodingBlock, 25009 "Helvetica-Oblique": encodingBlock, 25010 "Times-Roman": encodingBlock, 25011 "Times-Bold": encodingBlock, 25012 "Times-BoldItalic": encodingBlock, 25013 "Times-Italic": encodingBlock // , 'Symbol' 25014 // , 'ZapfDingbats' 25015 25016 } 25017 }; 25018 var fontMetrics = { 25019 Unicode: { 25020 // all sizing numbers are n/fontMetricsFractionOf = one font size unit 25021 // this means that if fontMetricsFractionOf = 1000, and letter A's width is 476, it's 25022 // width is 476/1000 or 47.6% of its height (regardless of font size) 25023 // At this time this value applies to "widths" and "kerning" numbers. 25024 // char code 0 represents "default" (average) width - use it for chars missing in this table. 25025 // key 'fof' represents the "fontMetricsFractionOf" value
vendor: 14,961 bytes, lines 25025-25041
25025 25026 "Courier-Oblique": uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"), 25027 "Times-BoldItalic": uncompress("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}"), 25028 "Helvetica-Bold": uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"), 25029 Courier: uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"), 25030 "Courier-BoldOblique": uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"), 25031 "Times-Bold": uncompress("{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}"), 25032 Symbol: uncompress("{'widths'{k3uaw4r19m3m2k1t2l2l202m2y2n3m2p5n202q6o3k3m2s2l2t2l2v3r2w1t3m3m2y1t2z1wbk2sbl3r'fof'6o3n3m3o3m3p3m3q3m3r3m3s3m3t3m3u1w3v1w3w3r3x3r3y3r3z2wbp3t3l3m5v2l5x2l5z3m2q4yfr3r7v3k7w1o7x3k}'kerning'{'fof'-6o}}"), 25033 Helvetica: uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}"), 25034 "Helvetica-BoldOblique": uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"), 25035 ZapfDingbats: uncompress("{'widths'{k4u2k1w'fof'6o}'kerning'{'fof'-6o}}"), 25036 "Courier-Bold": uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"), 25037 "Times-Italic": uncompress("{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}"), 25038 "Times-Roman": uncompress("{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}"), 25039 "Helvetica-Oblique": uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}") 25040 } 25041 };
vendor: 4,228 bytes, lines 25042-25184
25042 /* 25043 This event handler is fired when a new jsPDF object is initialized 25044 This event handler appends metrics data to standard fonts within 25045 that jsPDF instance. The metrics are mapped over Unicode character 25046 codes, NOT CIDs or other codes matching the StandardEncoding table of the 25047 standard PDF fonts. 25048 Future: 25049 Also included is the encoding maping table, converting Unicode (UCS-2, UTF-16) 25050 char codes to StandardEncoding character codes. The encoding table is to be used 25051 somewhere around "pdfEscape" call. 25052 */ 25053 25054 API.events.push(["addFont", function (data) { 25055 var font = data.font; 25056 var metrics = fontMetrics["Unicode"][font.postScriptName]; 25057 25058 if (metrics) { 25059 font.metadata["Unicode"] = {}; 25060 font.metadata["Unicode"].widths = metrics.widths; 25061 font.metadata["Unicode"].kerning = metrics.kerning; 25062 } 25063 25064 var encodingBlock = encodings["Unicode"][font.postScriptName]; 25065 25066 if (encodingBlock) { 25067 font.metadata["Unicode"].encoding = encodingBlock; 25068 font.encoding = encodingBlock.codePages[0]; 25069 } 25070 }]); // end of adding event handler 25071 })(jsPDF.API); 25072 25073 /** 25074 * @license 25075 * Licensed under the MIT License. 25076 * http://opensource.org/licenses/mit-license 25077 */ 25078 /** 25079 * @name ttfsupport 25080 * @module 25081 */ 25082 25083 (function (jsPDF) { 25084 25085 var binaryStringToUint8Array = function binaryStringToUint8Array(binary_string) { 25086 var len = binary_string.length; 25087 var bytes = new Uint8Array(len); 25088 25089 for (var i = 0; i < len; i++) { 25090 bytes[i] = binary_string.charCodeAt(i); 25091 } 25092 25093 return bytes; 25094 }; 25095 25096 var addFont = function addFont(font, file) { 25097 // eslint-disable-next-line no-control-regex 25098 if (/^\x00\x01\x00\x00/.test(file)) { 25099 file = binaryStringToUint8Array(file); 25100 } else { 25101 file = binaryStringToUint8Array(atob(file)); 25102 } 25103 25104 font.metadata = jsPDF.API.TTFFont.open(file); 25105 font.metadata.Unicode = font.metadata.Unicode || { 25106 encoding: {}, 25107 kerning: {}, 25108 widths: [] 25109 }; 25110 font.metadata.glyIdsUsed = [0]; 25111 }; 25112 25113 jsPDF.API.events.push(["addFont", function (data) { 25114 var file = undefined; 25115 var font = data.font; 25116 var instance = data.instance; 25117 25118 if (font.isStandardFont) { 25119 return; 25120 } 25121 25122 if (typeof instance !== "undefined") { 25123 if (instance.existsFileInVFS(font.postScriptName) === false) { 25124 file = instance.loadFile(font.postScriptName); 25125 } else { 25126 file = instance.getFileFromVFS(font.postScriptName); 25127 } 25128 25129 if (typeof file !== "string") { 25130 throw new Error("Font is not stored as string-data in vFS, import fonts or remove declaration doc.addFont('" + font.postScriptName + "')."); 25131 } 25132 25133 addFont(font, file); 25134 } else { 25135 throw new Error("Font does not exist in vFS, import fonts or remove declaration doc.addFont('" + font.postScriptName + "')."); 25136 } 25137 }]); // end of adding event handler 25138 })(jsPDF); 25139 25140 /** 25141 * jsPDF SVG plugin 25142 * 25143 * @name svg 25144 * @module 25145 */ 25146 25147 (function (jsPDFAPI) { 25148 25149 function loadCanvg() { 25150 return function () { 25151 if (globalObject["canvg"]) { 25152 return Promise.resolve(globalObject["canvg"]); 25153 } 25154 25155 if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") { 25156 return new Promise(function (resolve, reject) { 25157 try { 25158 resolve(require("canvg")); 25159 } catch (e) { 25160 reject(e); 25161 } 25162 }); 25163 } 25164 25165 if (typeof define === "function" && define.amd) { 25166 return new Promise(function (resolve, reject) { 25167 try { 25168 require(["canvg"], resolve); 25169 } catch (e) { 25170 reject(e); 25171 } 25172 }); 25173 } 25174 25175 return Promise.reject(new Error("Could not load canvg")); 25176 }().catch(function (e) { 25177 return Promise.reject(new Error("Could not load canvg: " + e)); 25178 }).then(function (canvg) { 25179 return canvg.default ? canvg.default : canvg; 25180 }); 25181 } 25182 /** 25183 * Parses SVG XML and saves it as image into the PDF. 25184 *
25185 * Depends on canvas-element and canvg 25186 * 25187 * @name addSvgAsImage 25188 * @public 25189 * @function 25190 * @param {string} SVG-Data as Text 25191 * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page 25192 * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page 25193 * @param {number} width of SVG-Image (in units declared at inception of PDF document) 25194 * @param {number} height of SVG-Image (in units declared at inception of PDF document) 25195 * @param {string} alias of SVG-Image (if used multiple times) 25196 * @param {string} compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW' 25197 * @param {number} rotation of the image in degrees (0-359) 25198 * 25199 * @returns jsPDF jsPDF-instance 25200 */ 25201 25202 25203 jsPDFAPI.addSvgAsImage = function (svg, x, y, w, h, alias, compression, rotation) { 25204 if (isNaN(x) || isNaN(y)) { 25205 console.error("jsPDF.addSvgAsImage: Invalid coordinates", arguments); 25206 throw new Error("Invalid coordinates passed to jsPDF.addSvgAsImage"); 25207 } 25208 25209 if (isNaN(w) || isNaN(h)) { 25210 console.error("jsPDF.addSvgAsImage: Invalid measurements", arguments); 25211 throw new Error("Invalid measurements (width and/or height) passed to jsPDF.addSvgAsImage"); 25212 } 25213 25214 var canvas = document.createElement("canvas"); 25215 canvas.width = w; 25216 canvas.height = h; 25217 var ctx = canvas.getContext("2d"); 25218 ctx.fillStyle = "#fff"; /// set white fill style 25219 25220 ctx.fillRect(0, 0, canvas.width, canvas.height); 25221 var options = { 25222 ignoreMouse: true, 25223 ignoreAnimation: true, 25224 ignoreDimensions: true 25225 }; 25226 var doc = this; 25227 return loadCanvg().then(function (canvg) { 25228 return canvg.fromString(ctx, svg, options); 25229 }, function () { 25230 return Promise.reject(new Error("Could not load canvg.")); 25231 }).then(function (instance) { 25232 return instance.render(options); 25233 }).then(function () { 25234 doc.addImage(canvas.toDataURL("image/jpeg", 1.0), x, y, w, h, compression, rotation); 25235 }); 25236 }; 25237 })(jsPDF.API); 25238 25239 /** 25240 * @license 25241 * ==================================================================== 25242 * Copyright (c) 2013 Eduardo Menezes de Morais, [email protected] 25243 * 25244 * Permission is hereby granted, free of charge, to any person obtaining 25245 * a copy of this software and associated documentation files (the 25246 * "Software"), to deal in the Software without restriction, including 25247 * without limitation the rights to use, copy, modify, merge, publish, 25248 * distribute, sublicense, and/or sell copies of the Software, and to 25249 * permit persons to whom the Software is furnished to do so, subject to 25250 * the following conditions: 25251 * 25252 * The above copyright notice and this permission notice shall be 25253 * included in all copies or substantial portions of the Software. 25254 * 25255 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25256 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25257 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25258 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25259 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25260 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25261 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25262 * ==================================================================== 25263 */ 25264 /** 25265 * jsPDF total_pages plugin 25266 * @name total_pages 25267 * @module 25268 */ 25269 25270 (function (jsPDFAPI) { 25271 /** 25272 * @name putTotalPages 25273 * @function 25274 * @param {string} pageExpression Regular Expression 25275 * @returns {jsPDF} jsPDF-instance 25276 */ 25277 25278 jsPDFAPI.putTotalPages = function (pageExpression) { 25279 25280 var replaceExpression; 25281 var totalNumberOfPages = 0; 25282 25283 if (parseInt(this.internal.getFont().id.substr(1), 10) < 15) { 25284 replaceExpression = new RegExp(pageExpression, "g"); 25285 totalNumberOfPages = this.internal.getNumberOfPages(); 25286 } else { 25287 replaceExpression = new RegExp(this.pdfEscape16(pageExpression, this.internal.getFont()), "g"); 25288 totalNumberOfPages = this.pdfEscape16(this.internal.getNumberOfPages() + "", this.internal.getFont()); 25289 } 25290 25291 for (var n = 1; n <= this.internal.getNumberOfPages(); n++) { 25292 for (var i = 0; i < this.internal.pages[n].length; i++) { 25293 this.internal.pages[n][i] = this.internal.pages[n][i].replace(replaceExpression, totalNumberOfPages); 25294 } 25295 } 25296 25297 return this; 25298 }; 25299 })(jsPDF.API); 25300 25301 /** 25302 * Adds the ability to set ViewerPreferences and by thus 25303 * controlling the way the document is to be presented on the 25304 * screen or in print. 25305 * @name viewerpreferences 25306 * @module 25307 */ 25308 25309 (function (jsPDFAPI) { 25310 /** 25311 * Set the ViewerPreferences of the generated PDF 25312 * 25313 * @name viewerPreferences 25314 * @function 25315 * @public 25316 * @param {Object} options Array with the ViewerPreferences<br /> 25317 * Example: doc.viewerPreferences({"FitWindow":true});<br /> 25318 * <br /> 25319 * You can set following preferences:<br /> 25320 * <br/> 25321 * <b>HideToolbar</b> <i>(boolean)</i><br /> 25322 * Default value: false<br /> 25323 * <br /> 25324 * <b>HideMenubar</b> <i>(boolean)</i><br /> 25325 * Default value: false.<br /> 25326 * <br /> 25327 * <b>HideWindowUI</b> <i>(boolean)</i><br /> 25328 * Default value: false.<br /> 25329 * <br /> 25330 * <b>FitWindow</b> <i>(boolean)</i><br /> 25331 * Default value: false.<br /> 25332 * <br /> 25333 * <b>CenterWindow</b> <i>(boolean)</i><br /> 25334 * Default value: false<br /> 25335 * <br /> 25336 * <b>DisplayDocTitle</b> <i>(boolean)</i><br /> 25337 * Default value: false.<br /> 25338 * <br /> 25339 * <b>NonFullScreenPageMode</b> <i>(string)</i><br /> 25340 * Possible values: UseNone, UseOutlines, UseThumbs, UseOC<br /> 25341 * Default value: UseNone<br/> 25342 * <br /> 25343 * <b>Direction</b> <i>(string)</i><br /> 25344 * Possible values: L2R, R2L<br /> 25345 * Default value: L2R.<br /> 25346 * <br /> 25347 * <b>ViewArea</b> <i>(string)</i><br /> 25348 * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br /> 25349 * Default value: CropBox.<br /> 25350 * <br /> 25351 * <b>ViewClip</b> <i>(string)</i><br /> 25352 * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br /> 25353 * Default value: CropBox<br /> 25354 * <br /> 25355 * <b>PrintArea</b> <i>(string)</i><br /> 25356 * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br /> 25357 * Default value: CropBox<br /> 25358 * <br /> 25359 * <b>PrintClip</b> <i>(string)</i><br /> 25360 * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br /> 25361 * Default value: CropBox.<br /> 25362 * <br /> 25363 * <b>PrintScaling</b> <i>(string)</i><br /> 25364 * Possible values: AppDefault, None<br /> 25365 * Default value: AppDefault.<br /> 25366 * <br /> 25367 * <b>Duplex</b> <i>(string)</i><br /> 25368 * Possible values: Simplex, DuplexFlipLongEdge, DuplexFlipShortEdge
25369 * Default value: none<br /> 25370 * <br /> 25371 * <b>PickTrayByPDFSize</b> <i>(boolean)</i><br /> 25372 * Default value: false<br /> 25373 * <br /> 25374 * <b>PrintPageRange</b> <i>(Array)</i><br /> 25375 * Example: [[1,5], [7,9]]<br /> 25376 * Default value: as defined by PDF viewer application<br /> 25377 * <br /> 25378 * <b>NumCopies</b> <i>(Number)</i><br /> 25379 * Possible values: 1, 2, 3, 4, 5<br /> 25380 * Default value: 1<br /> 25381 * <br /> 25382 * For more information see the PDF Reference, sixth edition on Page 577 25383 * @param {boolean} doReset True to reset the settings 25384 * @function 25385 * @returns jsPDF jsPDF-instance 25386 * @example 25387 * var doc = new jsPDF() 25388 * doc.text('This is a test', 10, 10) 25389 * doc.viewerPreferences({'FitWindow': true}, true) 25390 * doc.save("viewerPreferences.pdf") 25391 * 25392 * // Example printing 10 copies, using cropbox, and hiding UI. 25393 * doc.viewerPreferences({ 25394 * 'HideWindowUI': true, 25395 * 'PrintArea': 'CropBox', 25396 * 'NumCopies': 10 25397 * }) 25398 */ 25399 25400 jsPDFAPI.viewerPreferences = function (options, doReset) { 25401 options = options || {}; 25402 doReset = doReset || false; 25403 var configuration; 25404 var configurationTemplate = { 25405 HideToolbar: { 25406 defaultValue: false, 25407 value: false, 25408 type: "boolean", 25409 explicitSet: false, 25410 valueSet: [true, false], 25411 pdfVersion: 1.3 25412 }, 25413 HideMenubar: { 25414 defaultValue: false, 25415 value: false, 25416 type: "boolean", 25417 explicitSet: false, 25418 valueSet: [true, false], 25419 pdfVersion: 1.3 25420 }, 25421 HideWindowUI: { 25422 defaultValue: false, 25423 value: false, 25424 type: "boolean", 25425 explicitSet: false, 25426 valueSet: [true, false], 25427 pdfVersion: 1.3 25428 }, 25429 FitWindow: { 25430 defaultValue: false, 25431 value: false, 25432 type: "boolean", 25433 explicitSet: false, 25434 valueSet: [true, false], 25435 pdfVersion: 1.3 25436 }, 25437 CenterWindow: { 25438 defaultValue: false, 25439 value: false, 25440 type: "boolean", 25441 explicitSet: false, 25442 valueSet: [true, false], 25443 pdfVersion: 1.3 25444 }, 25445 DisplayDocTitle: { 25446 defaultValue: false, 25447 value: false, 25448 type: "boolean", 25449 explicitSet: false, 25450 valueSet: [true, false], 25451 pdfVersion: 1.4 25452 }, 25453 NonFullScreenPageMode: { 25454 defaultValue: "UseNone", 25455 value: "UseNone", 25456 type: "name", 25457 explicitSet: false, 25458 valueSet: ["UseNone", "UseOutlines", "UseThumbs", "UseOC"], 25459 pdfVersion: 1.3 25460 }, 25461 Direction: { 25462 defaultValue: "L2R", 25463 value: "L2R", 25464 type: "name", 25465 explicitSet: false, 25466 valueSet: ["L2R", "R2L"], 25467 pdfVersion: 1.3 25468 }, 25469 ViewArea: { 25470 defaultValue: "CropBox", 25471 value: "CropBox", 25472 type: "name", 25473 explicitSet: false, 25474 valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], 25475 pdfVersion: 1.4 25476 }, 25477 ViewClip: { 25478 defaultValue: "CropBox", 25479 value: "CropBox", 25480 type: "name", 25481 explicitSet: false, 25482 valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], 25483 pdfVersion: 1.4 25484 }, 25485 PrintArea: { 25486 defaultValue: "CropBox", 25487 value: "CropBox", 25488 type: "name", 25489 explicitSet: false, 25490 valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], 25491 pdfVersion: 1.4 25492 }, 25493 PrintClip: { 25494 defaultValue: "CropBox", 25495 value: "CropBox", 25496 type: "name", 25497 explicitSet: false, 25498 valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], 25499 pdfVersion: 1.4 25500 }, 25501 PrintScaling: { 25502 defaultValue: "AppDefault", 25503 value: "AppDefault", 25504 type: "name", 25505 explicitSet: false, 25506 valueSet: ["AppDefault", "None"], 25507 pdfVersion: 1.6 25508 }, 25509 Duplex: { 25510 defaultValue: "", 25511 value: "none", 25512 type: "name", 25513 explicitSet: false, 25514 valueSet: ["Simplex", "DuplexFlipShortEdge", "DuplexFlipLongEdge", "none"], 25515 pdfVersion: 1.7 25516 }, 25517 PickTrayByPDFSize: { 25518 defaultValue: false, 25519 value: false, 25520 type: "boolean", 25521 explicitSet: false, 25522 valueSet: [true, false], 25523 pdfVersion: 1.7 25524 }, 25525 PrintPageRange: { 25526 defaultValue: "", 25527 value: "", 25528 type: "array", 25529 explicitSet: false, 25530 valueSet: null, 25531 pdfVersion: 1.7 25532 }, 25533 NumCopies: { 25534 defaultValue: 1, 25535 value: 1, 25536 type: "integer", 25537 explicitSet: false, 25538 valueSet: null, 25539 pdfVersion: 1.7 25540 } 25541 }; 25542 var configurationKeys = Object.keys(configurationTemplate); 25543 var rangeArray = []; 25544 var i = 0; 25545 var j = 0; 25546 var k = 0; 25547 var isValid; 25548 var method; 25549 var value; 25550 25551 function arrayContainsElement(array, element) { 25552 var iterator; 25553 var result = false;
vendor: 20,374 bytes, lines 25554-26129
25554 25555 for (iterator = 0; iterator < array.length; iterator += 1) { 25556 if (array[iterator] === element) { 25557 result = true; 25558 } 25559 } 25560 25561 return result; 25562 } 25563 25564 if (this.internal.viewerpreferences === undefined) { 25565 this.internal.viewerpreferences = {}; 25566 this.internal.viewerpreferences.configuration = JSON.parse(JSON.stringify(configurationTemplate)); 25567 this.internal.viewerpreferences.isSubscribed = false; 25568 } 25569 25570 configuration = this.internal.viewerpreferences.configuration; 25571 25572 if (options === "reset" || doReset === true) { 25573 var len = configurationKeys.length; 25574 25575 for (k = 0; k < len; k += 1) { 25576 configuration[configurationKeys[k]].value = configuration[configurationKeys[k]].defaultValue; 25577 configuration[configurationKeys[k]].explicitSet = false; 25578 } 25579 } 25580 25581 if (_typeof(options) === "object") { 25582 for (method in options) { 25583 value = options[method]; 25584 25585 if (arrayContainsElement(configurationKeys, method) && value !== undefined) { 25586 if (configuration[method].type === "boolean" && typeof value === "boolean") { 25587 configuration[method].value = value; 25588 } else if (configuration[method].type === "name" && arrayContainsElement(configuration[method].valueSet, value)) { 25589 configuration[method].value = value; 25590 } else if (configuration[method].type === "integer" && Number.isInteger(value)) { 25591 configuration[method].value = value; 25592 } else if (configuration[method].type === "array") { 25593 for (i = 0; i < value.length; i += 1) { 25594 isValid = true; 25595 25596 if (value[i].length === 1 && typeof value[i][0] === "number") { 25597 rangeArray.push(String(value[i] - 1)); 25598 } else if (value[i].length > 1) { 25599 for (j = 0; j < value[i].length; j += 1) { 25600 if (typeof value[i][j] !== "number") { 25601 isValid = false; 25602 } 25603 } 25604 25605 if (isValid === true) { 25606 rangeArray.push([value[i][0] - 1, value[i][1] - 1].join(" ")); 25607 } 25608 } 25609 } 25610 25611 configuration[method].value = "[" + rangeArray.join(" ") + "]"; 25612 } else { 25613 configuration[method].value = configuration[method].defaultValue; 25614 } 25615 25616 configuration[method].explicitSet = true; 25617 } 25618 } 25619 } 25620 25621 if (this.internal.viewerpreferences.isSubscribed === false) { 25622 this.internal.events.subscribe("putCatalog", function () { 25623 var pdfDict = []; 25624 var vPref; 25625 25626 for (vPref in configuration) { 25627 if (configuration[vPref].explicitSet === true) { 25628 if (configuration[vPref].type === "name") { 25629 pdfDict.push("/" + vPref + " /" + configuration[vPref].value); 25630 } else { 25631 pdfDict.push("/" + vPref + " " + configuration[vPref].value); 25632 } 25633 } 25634 } 25635 25636 if (pdfDict.length !== 0) { 25637 this.internal.write("/ViewerPreferences\n<<\n" + pdfDict.join("\n") + "\n>>"); 25638 } 25639 }); 25640 this.internal.viewerpreferences.isSubscribed = true; 25641 } 25642 25643 this.internal.viewerpreferences.configuration = configuration; 25644 return this; 25645 }; 25646 })(jsPDF.API); 25647 25648 /** ==================================================================== 25649 * @license 25650 * jsPDF XMP metadata plugin 25651 * Copyright (c) 2016 Jussi Utunen, [email protected] 25652 * 25653 * Permission is hereby granted, free of charge, to any person obtaining 25654 * a copy of this software and associated documentation files (the 25655 * "Software"), to deal in the Software without restriction, including 25656 * without limitation the rights to use, copy, modify, merge, publish, 25657 * distribute, sublicense, and/or sell copies of the Software, and to 25658 * permit persons to whom the Software is furnished to do so, subject to 25659 * the following conditions: 25660 * 25661 * The above copyright notice and this permission notice shall be 25662 * included in all copies or substantial portions of the Software. 25663 * 25664 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25665 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25666 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25667 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25668 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25669 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25670 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25671 * ==================================================================== 25672 */ 25673 /** 25674 * @name xmp_metadata 25675 * @module 25676 */ 25677 25678 (function (jsPDFAPI) { 25679 25680 var postPutResources = function postPutResources() { 25681 var xmpmeta_beginning = '<x:xmpmeta xmlns:x="adobe:ns:meta/">'; 25682 var rdf_beginning = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:jspdf="' + this.internal.__metadata__.namespaceuri + '"><jspdf:metadata>'; 25683 var rdf_ending = "</jspdf:metadata></rdf:Description></rdf:RDF>"; 25684 var xmpmeta_ending = "</x:xmpmeta>"; 25685 var utf8_xmpmeta_beginning = unescape(encodeURIComponent(xmpmeta_beginning)); 25686 var utf8_rdf_beginning = unescape(encodeURIComponent(rdf_beginning)); 25687 var utf8_metadata = unescape(encodeURIComponent(this.internal.__metadata__.metadata)); 25688 var utf8_rdf_ending = unescape(encodeURIComponent(rdf_ending)); 25689 var utf8_xmpmeta_ending = unescape(encodeURIComponent(xmpmeta_ending)); 25690 var total_len = utf8_rdf_beginning.length + utf8_metadata.length + utf8_rdf_ending.length + utf8_xmpmeta_beginning.length + utf8_xmpmeta_ending.length; 25691 this.internal.__metadata__.metadata_object_number = this.internal.newObject(); 25692 this.internal.write("<< /Type /Metadata /Subtype /XML /Length " + total_len + " >>"); 25693 this.internal.write("stream"); 25694 this.internal.write(utf8_xmpmeta_beginning + utf8_rdf_beginning + utf8_metadata + utf8_rdf_ending + utf8_xmpmeta_ending); 25695 this.internal.write("endstream"); 25696 this.internal.write("endobj"); 25697 }; 25698 25699 var putCatalog = function putCatalog() { 25700 if (this.internal.__metadata__.metadata_object_number) { 25701 this.internal.write("/Metadata " + this.internal.__metadata__.metadata_object_number + " 0 R"); 25702 } 25703 }; 25704 /** 25705 * Adds XMP formatted metadata to PDF 25706 * 25707 * @name addMetadata 25708 * @function 25709 * @param {String} metadata The actual metadata to be added. The metadata shall be stored as XMP simple value. Note that if the metadata string contains XML markup characters "<", ">" or "&", those characters should be written using XML entities. 25710 * @param {String} namespaceuri Sets the namespace URI for the metadata. Last character should be slash or hash. 25711 * @returns {jsPDF} jsPDF-instance 25712 */ 25713 25714 25715 jsPDFAPI.addMetadata = function (metadata, namespaceuri) { 25716 if (typeof this.internal.__metadata__ === "undefined") { 25717 this.internal.__metadata__ = { 25718 metadata: metadata, 25719 namespaceuri: namespaceuri || "http://jspdf.default.namespaceuri/" 25720 }; 25721 this.internal.events.subscribe("putCatalog", putCatalog); 25722 this.internal.events.subscribe("postPutResources", postPutResources); 25723 } 25724 25725 return this; 25726 }; 25727 })(jsPDF.API); 25728 25729 /** 25730 * @name utf8 25731 * @module 25732 */ 25733 25734 (function (jsPDF) { 25735 25736 var jsPDFAPI = jsPDF.API; 25737 /***************************************************************************************************/ 25738 25739 /* function : pdfEscape16 */ 25740 25741 /* comment : The character id of a 2-byte string is converted to a hexadecimal number by obtaining */ 25742 25743 /* the corresponding glyph id and width, and then adding padding to the string. */ 25744 25745 /***************************************************************************************************/ 25746 25747 var pdfEscape16 = jsPDFAPI.pdfEscape16 = function (text, font) { 25748 var widths = font.metadata.Unicode.widths; 25749 var padz = ["", "0", "00", "000", "0000"]; 25750 var ar = [""]; 25751 25752 for (var i = 0, l = text.length, t; i < l; ++i) { 25753 t = font.metadata.characterToGlyph(text.charCodeAt(i)); 25754 font.metadata.glyIdsUsed.push(t); 25755 font.metadata.toUnicode[t] = text.charCodeAt(i); 25756 25757 if (widths.indexOf(t) == -1) { 25758 widths.push(t); 25759 widths.push([parseInt(font.metadata.widthOfGlyph(t), 10)]); 25760 } 25761 25762 if (t == "0") { 25763 //Spaces are not allowed in cmap. 25764 return ar.join(""); 25765 } else { 25766 t = t.toString(16); 25767 ar.push(padz[4 - t.length], t); 25768 } 25769 } 25770 25771 return ar.join(""); 25772 }; 25773 25774 var toUnicodeCmap = function toUnicodeCmap(map) { 25775 var code, codes, range, unicode, unicodeMap, _i, _len; 25776 25777 unicodeMap = "/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n/CIDSystemInfo <<\n /Registry (Adobe)\n /Ordering (UCS)\n /Supplement 0\n>> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n1 begincodespacerange\n<0000><ffff>\nendcodespacerange"; 25778 codes = Object.keys(map).sort(function (a, b) { 25779 return a - b; 25780 }); 25781 range = []; 25782 25783 for (_i = 0, _len = codes.length; _i < _len; _i++) { 25784 code = codes[_i]; 25785 25786 if (range.length >= 100) { 25787 unicodeMap += "\n" + range.length + " beginbfchar\n" + range.join("\n") + "\nendbfchar"; 25788 range = []; 25789 } 25790 25791 if (map[code] !== undefined && map[code] !== null && typeof map[code].toString === "function") { 25792 unicode = ("0000" + map[code].toString(16)).slice(-4); 25793 code = ("0000" + (+code).toString(16)).slice(-4); 25794 range.push("<" + code + "><" + unicode + ">"); 25795 } 25796 } 25797 25798 if (range.length) { 25799 unicodeMap += "\n" + range.length + " beginbfchar\n" + range.join("\n") + "\nendbfchar\n"; 25800 } 25801 25802 unicodeMap += "endcmap\nCMapName currentdict /CMap defineresource pop\nend\nend"; 25803 return unicodeMap; 25804 }; 25805 25806 var identityHFunction = function identityHFunction(options) { 25807 var font = options.font; 25808 var out = options.out; 25809 var newObject = options.newObject; 25810 var putStream = options.putStream; 25811 25812 if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === "Identity-H") { 25813 //Tag with Identity-H 25814 var widths = font.metadata.Unicode.widths; 25815 var data = font.metadata.subset.encode(font.metadata.glyIdsUsed, 1); 25816 var pdfOutput = data; 25817 var pdfOutput2 = ""; 25818 25819 for (var i = 0; i < pdfOutput.length; i++) { 25820 pdfOutput2 += String.fromCharCode(pdfOutput[i]); 25821 } 25822 25823 var fontTable = newObject(); 25824 putStream({ 25825 data: pdfOutput2, 25826 addLength1: true, 25827 objectId: fontTable 25828 }); 25829 out("endobj"); 25830 var cmap = newObject(); 25831 var cmapData = toUnicodeCmap(font.metadata.toUnicode); 25832 putStream({ 25833 data: cmapData, 25834 addLength1: true, 25835 objectId: cmap 25836 }); 25837 out("endobj"); 25838 var fontDescriptor = newObject(); 25839 out("<<"); 25840 out("/Type /FontDescriptor"); 25841 out("/FontName /" + toPDFName(font.fontName)); 25842 out("/FontFile2 " + fontTable + " 0 R"); 25843 out("/FontBBox " + jsPDF.API.PDFObject.convert(font.metadata.bbox)); 25844 out("/Flags " + font.metadata.flags); 25845 out("/StemV " + font.metadata.stemV); 25846 out("/ItalicAngle " + font.metadata.italicAngle); 25847 out("/Ascent " + font.metadata.ascender); 25848 out("/Descent " + font.metadata.decender); 25849 out("/CapHeight " + font.metadata.capHeight); 25850 out(">>"); 25851 out("endobj"); 25852 var DescendantFont = newObject(); 25853 out("<<"); 25854 out("/Type /Font"); 25855 out("/BaseFont /" + toPDFName(font.fontName)); 25856 out("/FontDescriptor " + fontDescriptor + " 0 R"); 25857 out("/W " + jsPDF.API.PDFObject.convert(widths)); 25858 out("/CIDToGIDMap /Identity"); 25859 out("/DW 1000"); 25860 out("/Subtype /CIDFontType2"); 25861 out("/CIDSystemInfo"); 25862 out("<<"); 25863 out("/Supplement 0"); 25864 out("/Registry (Adobe)"); 25865 out("/Ordering (" + font.encoding + ")"); 25866 out(">>"); 25867 out(">>"); 25868 out("endobj"); 25869 font.objectNumber = newObject(); 25870 out("<<"); 25871 out("/Type /Font"); 25872 out("/Subtype /Type0"); 25873 out("/ToUnicode " + cmap + " 0 R"); 25874 out("/BaseFont /" + toPDFName(font.fontName)); 25875 out("/Encoding /" + font.encoding); 25876 out("/DescendantFonts [" + DescendantFont + " 0 R]"); 25877 out(">>"); 25878 out("endobj"); 25879 font.isAlreadyPutted = true; 25880 } 25881 }; 25882 25883 jsPDFAPI.events.push(["putFont", function (args) { 25884 identityHFunction(args); 25885 }]); 25886 25887 var winAnsiEncodingFunction = function winAnsiEncodingFunction(options) { 25888 var font = options.font; 25889 var out = options.out; 25890 var newObject = options.newObject; 25891 var putStream = options.putStream; 25892 25893 if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === "WinAnsiEncoding") { 25894 //Tag with WinAnsi encoding 25895 var data = font.metadata.rawData; 25896 var pdfOutput = data; 25897 var pdfOutput2 = ""; 25898 25899 for (var i = 0; i < pdfOutput.length; i++) { 25900 pdfOutput2 += String.fromCharCode(pdfOutput[i]); 25901 } 25902 25903 var fontTable = newObject(); 25904 putStream({ 25905 data: pdfOutput2, 25906 addLength1: true, 25907 objectId: fontTable 25908 }); 25909 out("endobj"); 25910 var cmap = newObject(); 25911 var cmapData = toUnicodeCmap(font.metadata.toUnicode); 25912 putStream({ 25913 data: cmapData, 25914 addLength1: true, 25915 objectId: cmap 25916 }); 25917 out("endobj"); 25918 var fontDescriptor = newObject(); 25919 out("<<"); 25920 out("/Descent " + font.metadata.decender); 25921 out("/CapHeight " + font.metadata.capHeight); 25922 out("/StemV " + font.metadata.stemV); 25923 out("/Type /FontDescriptor"); 25924 out("/FontFile2 " + fontTable + " 0 R"); 25925 out("/Flags 96"); 25926 out("/FontBBox " + jsPDF.API.PDFObject.convert(font.metadata.bbox)); 25927 out("/FontName /" + toPDFName(font.fontName)); 25928 out("/ItalicAngle " + font.metadata.italicAngle); 25929 out("/Ascent " + font.metadata.ascender); 25930 out(">>"); 25931 out("endobj"); 25932 font.objectNumber = newObject(); 25933 25934 for (var j = 0; j < font.metadata.hmtx.widths.length; j++) { 25935 font.metadata.hmtx.widths[j] = parseInt(font.metadata.hmtx.widths[j] * (1000 / font.metadata.head.unitsPerEm)); //Change the width of Em units to Point units. 25936 } 25937 25938 out("<</Subtype/TrueType/Type/Font/ToUnicode " + cmap + " 0 R/BaseFont/" + toPDFName(font.fontName) + "/FontDescriptor " + fontDescriptor + " 0 R" + "/Encoding/" + font.encoding + " /FirstChar 29 /LastChar 255 /Widths " + jsPDF.API.PDFObject.convert(font.metadata.hmtx.widths) + ">>"); 25939 out("endobj"); 25940 font.isAlreadyPutted = true; 25941 } 25942 }; 25943 25944 jsPDFAPI.events.push(["putFont", function (args) { 25945 winAnsiEncodingFunction(args); 25946 }]); 25947 25948 var utf8TextFunction = function utf8TextFunction(args) { 25949 var text = args.text || ""; 25950 var x = args.x; 25951 var y = args.y; 25952 var options = args.options || {}; 25953 var mutex = args.mutex || {}; 25954 var pdfEscape = mutex.pdfEscape; 25955 var activeFontKey = mutex.activeFontKey; 25956 var fonts = mutex.fonts; 25957 var key = activeFontKey; 25958 var str = "", 25959 s = 0, 25960 cmapConfirm; 25961 var strText = ""; 25962 var encoding = fonts[key].encoding; 25963 25964 if (fonts[key].encoding !== "Identity-H") { 25965 return { 25966 text: text, 25967 x: x, 25968 y: y, 25969 options: options, 25970 mutex: mutex 25971 }; 25972 } 25973 25974 strText = text; 25975 key = activeFontKey; 25976 25977 if (Array.isArray(text)) { 25978 strText = text[0]; 25979 } 25980 25981 for (s = 0; s < strText.length; s += 1) { 25982 if (fonts[key].metadata.hasOwnProperty("cmap")) { 25983 cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)]; 25984 /* 25985 if (Object.prototype.toString.call(text) === '[object Array]') { 25986 var i = 0; 25987 // for (i = 0; i < text.length; i += 1) { 25988 if (Object.prototype.toString.call(text[s]) === '[object Array]') { 25989 cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s][0].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id 25990 } else { 25991 } 25992 //} 25993 } else { 25994 cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id 25995 }*/ 25996 } 25997 25998 if (!cmapConfirm) { 25999 if (strText[s].charCodeAt(0) < 256 && fonts[key].metadata.hasOwnProperty("Unicode")) { 26000 str += strText[s]; 26001 } else { 26002 str += ""; 26003 } 26004 } else { 26005 str += strText[s]; 26006 } 26007 } 26008 26009 var result = ""; 26010 26011 if (parseInt(key.slice(1)) < 14 || encoding === "WinAnsiEncoding") { 26012 //For the default 13 font 26013 result = pdfEscape(str, key).split("").map(function (cv) { 26014 return cv.charCodeAt(0).toString(16); 26015 }).join(""); 26016 } else if (encoding === "Identity-H") { 26017 result = pdfEscape16(str, fonts[key]); 26018 } 26019 26020 mutex.isHex = true; 26021 return { 26022 text: result, 26023 x: x, 26024 y: y, 26025 options: options, 26026 mutex: mutex 26027 }; 26028 }; 26029 26030 var utf8EscapeFunction = function utf8EscapeFunction(parms) { 26031 var text = parms.text || "", 26032 x = parms.x, 26033 y = parms.y, 26034 options = parms.options, 26035 mutex = parms.mutex; 26036 var tmpText = []; 26037 var args = { 26038 text: text, 26039 x: x, 26040 y: y, 26041 options: options, 26042 mutex: mutex 26043 }; 26044 26045 if (Array.isArray(text)) { 26046 var i = 0; 26047 26048 for (i = 0; i < text.length; i += 1) { 26049 if (Array.isArray(text[i])) { 26050 if (text[i].length === 3) { 26051 tmpText.push([utf8TextFunction(Object.assign({}, args, { 26052 text: text[i][0] 26053 })).text, text[i][1], text[i][2]]); 26054 } else { 26055 tmpText.push(utf8TextFunction(Object.assign({}, args, { 26056 text: text[i] 26057 })).text); 26058 } 26059 } else { 26060 tmpText.push(utf8TextFunction(Object.assign({}, args, { 26061 text: text[i] 26062 })).text); 26063 } 26064 } 26065 26066 parms.text = tmpText; 26067 } else { 26068 parms.text = utf8TextFunction(Object.assign({}, args, { 26069 text: text 26070 })).text; 26071 } 26072 }; 26073 26074 jsPDFAPI.events.push(["postProcessText", utf8EscapeFunction]); 26075 })(jsPDF); 26076 26077 /** 26078 * @license 26079 * jsPDF virtual FileSystem functionality 26080 * 26081 * Licensed under the MIT License. 26082 * http://opensource.org/licenses/mit-license 26083 */ 26084 /** 26085 * Use the vFS to handle files 26086 * 26087 * @name vFS 26088 * @module 26089 */ 26090 26091 (function (jsPDFAPI) { 26092 26093 var _initializeVFS = function _initializeVFS() { 26094 if (typeof this.internal.vFS === "undefined") { 26095 this.internal.vFS = {}; 26096 } 26097 26098 return true; 26099 }; 26100 /** 26101 * Check if the file exists in the vFS 26102 * 26103 * @name existsFileInVFS 26104 * @function 26105 * @param {string} Possible filename in the vFS. 26106 * @returns {boolean} 26107 * @example 26108 * doc.existsFileInVFS("someFile.txt"); 26109 */ 26110 26111 26112 jsPDFAPI.existsFileInVFS = function (filename) { 26113 _initializeVFS.call(this); 26114 26115 return typeof this.internal.vFS[filename] !== "undefined"; 26116 }; 26117 /** 26118 * Add a file to the vFS 26119 * 26120 * @name addFileToVFS 26121 * @function 26122 * @param {string} filename The name of the file which should be added. 26123 * @param {string} filecontent The content of the file. 26124 * @returns {jsPDF} 26125 * @example 26126 * doc.addFileToVFS("someFile.txt", "BADFACE1"); 26127 */ 26128 26129
26130 jsPDFAPI.addFileToVFS = function (filename, filecontent) { 26131 _initializeVFS.call(this); 26132 26133 this.internal.vFS[filename] = filecontent; 26134 return this; 26135 }; 26136 /** 26137 * Get the file from the vFS 26138 * 26139 * @name getFileFromVFS 26140 * @function 26141 * @param {string} The name of the file which gets requested. 26142 * @returns {string} 26143 * @example 26144 * doc.getFileFromVFS("someFile.txt"); 26145 */ 26146 26147 26148 jsPDFAPI.getFileFromVFS = function (filename) { 26149 _initializeVFS.call(this); 26150 26151 if (typeof this.internal.vFS[filename] !== "undefined") { 26152 return this.internal.vFS[filename]; 26153 } 26154 26155 return null; 26156 }; 26157 })(jsPDF.API); 26158 26159 /** 26160 * @license 26161 * Unicode Bidi Engine based on the work of Alex Shensis (@asthensis) 26162 * MIT License 26163 */ 26164 26165 (function (jsPDF) { 26166 /** 26167 * Table of Unicode types. 26168 * 26169 * Generated by: 26170 * 26171 * var bidi = require("./bidi/index"); 26172 * var bidi_accumulate = bidi.slice(0, 256).concat(bidi.slice(0x0500, 0x0500 + 256 * 3)). 26173 * concat(bidi.slice(0x2000, 0x2000 + 256)).concat(bidi.slice(0xFB00, 0xFB00 + 256)). 26174 * concat(bidi.slice(0xFE00, 0xFE00 + 2 * 256)); 26175 * 26176 * for( var i = 0; i < bidi_accumulate.length; i++) { 26177 * if(bidi_accumulate[i] === undefined || bidi_accumulate[i] === 'ON') 26178 * bidi_accumulate[i] = 'N'; //mark as neutral to conserve space and substitute undefined 26179 * } 26180 * var bidiAccumulateStr = 'return [ "' + bidi_accumulate.toString().replace(/,/g, '", "') + '" ];'; 26181 * require("fs").writeFile('unicode-types.js', bidiAccumulateStr); 26182 * 26183 * Based on: 26184 * https://github.com/mathiasbynens/unicode-8.0.0 26185 */ 26186 26187 var bidiUnicodeTypes = ["BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "S", "B", "S", "WS", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "B", "B", "B", "S", "WS", "N", "N", "ET", "ET", "ET", "N", "N", "N", "N", "N", "ES", "CS", "ES", "CS", "CS", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "CS", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "BN", "BN", "BN", "BN", "BN", "BN", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "CS", "N", "ET", "ET", "ET", "ET", "N", "N", "N", "N", "L", "N", "N", "BN", "N", "N", "ET", "ET", "EN", "EN", "N", "L", "N", "N", "N", "EN", "L", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "L", "L", "L", "L", "L", "L", "L", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "L", "N", "N", "N", "N", "N", "ET", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "R", "NSM", "R", "NSM", "NSM", "R", "NSM", "NSM", "R", "NSM", "N", "N", "N", "N", "N", "N", "N", "N", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "N", "N", "N", "N", "N", "R", "R", "R", "R", "R", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "AN", "AN", "AN", "AN", "AN", "AN", "N", "N", "AL", "ET", "ET", "AL", "CS", "AL", "N", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "N", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "ET", "AN", "AN", "AL", "AL", "AL", "NSM", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "NSM", "NSM", "N", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "N", "AL", "AL", "NSM", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "N", "N", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "R", "R", "N", "N", "N", "N", "R", "N", "N", "N", "N", "N", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "BN", "BN", "BN", "L", "R", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "WS", "B", "LRE", "RLE", "PDF", "LRO", "RLO", "CS", "ET", "ET", "ET", "ET", "ET", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "CS", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "WS", "BN", "BN", "BN", "BN", "BN", "N", "LRI", "RLI", "FSI", "PDI", "BN", "BN", "BN", "BN", "BN", "BN", "EN", "L", "N", "N", "EN", "EN", "EN", "EN", "EN", "EN", "ES", "ES", "N", "N", "N", "L", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "ES", "ES", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "R", "NSM", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "ES", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "N", "R", "R", "R", "R", "R", "N", "R", "N", "R", "R", "N", "R", "R", "N", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "CS", "N", "CS", "N", "N", "CS", "N", "N", "N", "N", "N", "N", "N", "N", "N", "ET", "N", "N", "ES", "ES", "N", "N", "N", "N", "N", "ET", "ET", "N", "N", "N", "N", "N", "AL", "AL", "AL", "AL", "AL", "N", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "N", "N", "BN", "N", "N", "N", "ET", "ET", "ET", "N", "N", "N", "N", "N", "ES", "CS", "ES", "CS", "CS", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "CS", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "L", "L", "L", "L", "L", "L", "N", "N", "L", "L", "L", "L", "L", "L", "N", "N", "L", "L", "L", "L", "L", "L", "N", "N", "L", "L", "L", "N", "N", "N", "ET", "ET", "N", "N", "N", "ET", "ET", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N"]; 26188 /** 26189 * Unicode Bidi algorithm compliant Bidi engine. 26190 * For reference see http://unicode.org/reports/tr9/ 26191 */ 26192 26193 /** 26194 * constructor ( options ) 26195 * 26196 * Initializes Bidi engine 26197 * 26198 * @param {Object} See 'setOptions' below for detailed description. 26199 * options are cashed between invocation of 'doBidiReorder' method 26200 * 26201 * sample usage pattern of BidiEngine: 26202 * var opt = { 26203 * isInputVisual: true, 26204 * isInputRtl: false, 26205 * isOutputVisual: false, 26206 * isOutputRtl: false, 26207 * isSymmetricSwapping: true 26208 * } 26209 * var sourceToTarget = [], levels = []; 26210 * var bidiEng = Globalize.bidiEngine(opt);
vendor: 75,010 bytes, lines 26211-28708
26211 * var src = "text string to be reordered"; 26212 * var ret = bidiEng.doBidiReorder(src, sourceToTarget, levels); 26213 */ 26214 26215 jsPDF.__bidiEngine__ = jsPDF.prototype.__bidiEngine__ = function (options) { 26216 var _UNICODE_TYPES = _bidiUnicodeTypes; 26217 var _STATE_TABLE_LTR = [[0, 3, 0, 1, 0, 0, 0], [0, 3, 0, 1, 2, 2, 0], [0, 3, 0, 0x11, 2, 0, 1], [0, 3, 5, 5, 4, 1, 0], [0, 3, 0x15, 0x15, 4, 0, 1], [0, 3, 5, 5, 4, 2, 0]]; 26218 var _STATE_TABLE_RTL = [[2, 0, 1, 1, 0, 1, 0], [2, 0, 1, 1, 0, 2, 0], [2, 0, 2, 1, 3, 2, 0], [2, 0, 2, 0x21, 3, 1, 1]]; 26219 var _TYPE_NAMES_MAP = { 26220 L: 0, 26221 R: 1, 26222 EN: 2, 26223 AN: 3, 26224 N: 4, 26225 B: 5, 26226 S: 6 26227 }; 26228 var _UNICODE_RANGES_MAP = { 26229 0: 0, 26230 5: 1, 26231 6: 2, 26232 7: 3, 26233 0x20: 4, 26234 0xfb: 5, 26235 0xfe: 6, 26236 0xff: 7 26237 }; 26238 var _SWAP_TABLE = ["(", ")", "(", "<", ">", "<", "[", "]", "[", "{", "}", "{", "\xAB", "\xBB", "\xAB", "\u2039", "\u203A", "\u2039", "\u2045", "\u2046", "\u2045", "\u207D", "\u207E", "\u207D", "\u208D", "\u208E", "\u208D", "\u2264", "\u2265", "\u2264", "\u2329", "\u232A", "\u2329", "\uFE59", "\uFE5A", "\uFE59", "\uFE5B", "\uFE5C", "\uFE5B", "\uFE5D", "\uFE5E", "\uFE5D", "\uFE64", "\uFE65", "\uFE64"]; 26239 26240 var _LTR_RANGES_REG_EXPR = new RegExp(/^([1-4|9]|1[0-9]|2[0-9]|3[0168]|4[04589]|5[012]|7[78]|159|16[0-9]|17[0-2]|21[569]|22[03489]|250)$/); 26241 26242 var _lastArabic = false, 26243 _hasUbatB, 26244 _hasUbatS, 26245 DIR_LTR = 0, 26246 DIR_RTL = 1, 26247 _isInVisual, 26248 _isInRtl, 26249 _isOutVisual, 26250 _isOutRtl, 26251 _isSymmetricSwapping, 26252 _dir = DIR_LTR; 26253 26254 this.__bidiEngine__ = {}; 26255 26256 var _init = function _init(text, sourceToTargetMap) { 26257 if (sourceToTargetMap) { 26258 for (var i = 0; i < text.length; i++) { 26259 sourceToTargetMap[i] = i; 26260 } 26261 } 26262 26263 if (_isInRtl === undefined) { 26264 _isInRtl = _isContextualDirRtl(text); 26265 } 26266 26267 if (_isOutRtl === undefined) { 26268 _isOutRtl = _isContextualDirRtl(text); 26269 } 26270 }; // for reference see 3.2 in http://unicode.org/reports/tr9/ 26271 // 26272 26273 26274 var _getCharType = function _getCharType(ch) { 26275 var charCode = ch.charCodeAt(), 26276 range = charCode >> 8, 26277 rangeIdx = _UNICODE_RANGES_MAP[range]; 26278 26279 if (rangeIdx !== undefined) { 26280 return _UNICODE_TYPES[rangeIdx * 256 + (charCode & 0xff)]; 26281 } else if (range === 0xfc || range === 0xfd) { 26282 return "AL"; 26283 } else if (_LTR_RANGES_REG_EXPR.test(range)) { 26284 //unlikely case 26285 return "L"; 26286 } else if (range === 8) { 26287 // even less likely 26288 return "R"; 26289 } 26290 26291 return "N"; //undefined type, mark as neutral 26292 }; 26293 26294 var _isContextualDirRtl = function _isContextualDirRtl(text) { 26295 for (var i = 0, charType; i < text.length; i++) { 26296 charType = _getCharType(text.charAt(i)); 26297 26298 if (charType === "L") { 26299 return false; 26300 } else if (charType === "R") { 26301 return true; 26302 } 26303 } 26304 26305 return false; 26306 }; // for reference see 3.3.4 & 3.3.5 in http://unicode.org/reports/tr9/ 26307 // 26308 26309 26310 var _resolveCharType = function _resolveCharType(chars, types, resolvedTypes, index) { 26311 var cType = types[index], 26312 wType, 26313 nType, 26314 i, 26315 len; 26316 26317 switch (cType) { 26318 case "L": 26319 case "R": 26320 _lastArabic = false; 26321 break; 26322 26323 case "N": 26324 case "AN": 26325 break; 26326 26327 case "EN": 26328 if (_lastArabic) { 26329 cType = "AN"; 26330 } 26331 26332 break; 26333 26334 case "AL": 26335 _lastArabic = true; 26336 cType = "R"; 26337 break; 26338 26339 case "WS": 26340 cType = "N"; 26341 break; 26342 26343 case "CS": 26344 if (index < 1 || index + 1 >= types.length || (wType = resolvedTypes[index - 1]) !== "EN" && wType !== "AN" || (nType = types[index + 1]) !== "EN" && nType !== "AN") { 26345 cType = "N"; 26346 } else if (_lastArabic) { 26347 nType = "AN"; 26348 } 26349 26350 cType = nType === wType ? nType : "N"; 26351 break; 26352 26353 case "ES": 26354 wType = index > 0 ? resolvedTypes[index - 1] : "B"; 26355 cType = wType === "EN" && index + 1 < types.length && types[index + 1] === "EN" ? "EN" : "N"; 26356 break; 26357 26358 case "ET": 26359 if (index > 0 && resolvedTypes[index - 1] === "EN") { 26360 cType = "EN"; 26361 break; 26362 } else if (_lastArabic) { 26363 cType = "N"; 26364 break; 26365 } 26366 26367 i = index + 1; 26368 len = types.length; 26369 26370 while (i < len && types[i] === "ET") { 26371 i++; 26372 } 26373 26374 if (i < len && types[i] === "EN") { 26375 cType = "EN"; 26376 } else { 26377 cType = "N"; 26378 } 26379 26380 break; 26381 26382 case "NSM": 26383 if (_isInVisual && !_isInRtl) { 26384 //V->L 26385 len = types.length; 26386 i = index + 1; 26387 26388 while (i < len && types[i] === "NSM") { 26389 i++; 26390 } 26391 26392 if (i < len) { 26393 var c = chars[index]; 26394 var rtlCandidate = c >= 0x0591 && c <= 0x08ff || c === 0xfb1e; 26395 wType = types[i]; 26396 26397 if (rtlCandidate && (wType === "R" || wType === "AL")) { 26398 cType = "R"; 26399 break; 26400 } 26401 } 26402 } 26403 26404 if (index < 1 || (wType = types[index - 1]) === "B") { 26405 cType = "N"; 26406 } else { 26407 cType = resolvedTypes[index - 1]; 26408 } 26409 26410 break; 26411 26412 case "B": 26413 _lastArabic = false; 26414 _hasUbatB = true; 26415 cType = _dir; 26416 break; 26417 26418 case "S": 26419 _hasUbatS = true; 26420 cType = "N"; 26421 break; 26422 26423 case "LRE": 26424 case "RLE": 26425 case "LRO": 26426 case "RLO": 26427 case "PDF": 26428 _lastArabic = false; 26429 break; 26430 26431 case "BN": 26432 cType = "N"; 26433 break; 26434 } 26435 26436 return cType; 26437 }; 26438 26439 var _handleUbatS = function _handleUbatS(types, levels, length) { 26440 for (var i = 0; i < length; i++) { 26441 if (types[i] === "S") { 26442 levels[i] = _dir; 26443 26444 for (var j = i - 1; j >= 0; j--) { 26445 if (types[j] === "WS") { 26446 levels[j] = _dir; 26447 } else { 26448 break; 26449 } 26450 } 26451 } 26452 } 26453 }; 26454 26455 var _invertString = function _invertString(text, sourceToTargetMap, levels) { 26456 var charArray = text.split(""); 26457 26458 if (levels) { 26459 _computeLevels(charArray, levels, { 26460 hiLevel: _dir 26461 }); 26462 } 26463 26464 charArray.reverse(); 26465 sourceToTargetMap && sourceToTargetMap.reverse(); 26466 return charArray.join(""); 26467 }; // For reference see 3.3 in http://unicode.org/reports/tr9/ 26468 // 26469 26470 26471 var _computeLevels = function _computeLevels(chars, levels, params) { 26472 var action, 26473 condition, 26474 i, 26475 index, 26476 newLevel, 26477 prevState, 26478 condPos = -1, 26479 len = chars.length, 26480 newState = 0, 26481 resolvedTypes = [], 26482 stateTable = _dir ? _STATE_TABLE_RTL : _STATE_TABLE_LTR, 26483 types = []; 26484 _lastArabic = false; 26485 _hasUbatB = false; 26486 _hasUbatS = false; 26487 26488 for (i = 0; i < len; i++) { 26489 types[i] = _getCharType(chars[i]); 26490 } 26491 26492 for (index = 0; index < len; index++) { 26493 prevState = newState; 26494 resolvedTypes[index] = _resolveCharType(chars, types, resolvedTypes, index); 26495 newState = stateTable[prevState][_TYPE_NAMES_MAP[resolvedTypes[index]]]; 26496 action = newState & 0xf0; 26497 newState &= 0x0f; 26498 levels[index] = newLevel = stateTable[newState][5]; 26499 26500 if (action > 0) { 26501 if (action === 0x10) { 26502 for (i = condPos; i < index; i++) { 26503 levels[i] = 1; 26504 } 26505 26506 condPos = -1; 26507 } else { 26508 condPos = -1; 26509 } 26510 } 26511 26512 condition = stateTable[newState][6]; 26513 26514 if (condition) { 26515 if (condPos === -1) { 26516 condPos = index; 26517 } 26518 } else { 26519 if (condPos > -1) { 26520 for (i = condPos; i < index; i++) { 26521 levels[i] = newLevel; 26522 } 26523 26524 condPos = -1; 26525 } 26526 } 26527 26528 if (types[index] === "B") { 26529 levels[index] = 0; 26530 } 26531 26532 params.hiLevel |= newLevel; 26533 } 26534 26535 if (_hasUbatS) { 26536 _handleUbatS(types, levels, len); 26537 } 26538 }; // for reference see 3.4 in http://unicode.org/reports/tr9/ 26539 // 26540 26541 26542 var _invertByLevel = function _invertByLevel(level, charArray, sourceToTargetMap, levels, params) { 26543 if (params.hiLevel < level) { 26544 return; 26545 } 26546 26547 if (level === 1 && _dir === DIR_RTL && !_hasUbatB) { 26548 charArray.reverse(); 26549 sourceToTargetMap && sourceToTargetMap.reverse(); 26550 return; 26551 } 26552 26553 var ch, 26554 high, 26555 end, 26556 low, 26557 len = charArray.length, 26558 start = 0; 26559 26560 while (start < len) { 26561 if (levels[start] >= level) { 26562 end = start + 1; 26563 26564 while (end < len && levels[end] >= level) { 26565 end++; 26566 } 26567 26568 for (low = start, high = end - 1; low < high; low++, high--) { 26569 ch = charArray[low]; 26570 charArray[low] = charArray[high]; 26571 charArray[high] = ch; 26572 26573 if (sourceToTargetMap) { 26574 ch = sourceToTargetMap[low]; 26575 sourceToTargetMap[low] = sourceToTargetMap[high]; 26576 sourceToTargetMap[high] = ch; 26577 } 26578 } 26579 26580 start = end; 26581 } 26582 26583 start++; 26584 } 26585 }; // for reference see 7 & BD16 in http://unicode.org/reports/tr9/ 26586 // 26587 26588 26589 var _symmetricSwap = function _symmetricSwap(charArray, levels, params) { 26590 if (params.hiLevel !== 0 && _isSymmetricSwapping) { 26591 for (var i = 0, index; i < charArray.length; i++) { 26592 if (levels[i] === 1) { 26593 index = _SWAP_TABLE.indexOf(charArray[i]); 26594 26595 if (index >= 0) { 26596 charArray[i] = _SWAP_TABLE[index + 1]; 26597 } 26598 } 26599 } 26600 } 26601 }; 26602 26603 var _reorder = function _reorder(text, sourceToTargetMap, levels) { 26604 var charArray = text.split(""), 26605 params = { 26606 hiLevel: _dir 26607 }; 26608 26609 if (!levels) { 26610 levels = []; 26611 } 26612 26613 _computeLevels(charArray, levels, params); 26614 26615 _symmetricSwap(charArray, levels, params); 26616 26617 _invertByLevel(DIR_RTL + 1, charArray, sourceToTargetMap, levels, params); 26618 26619 _invertByLevel(DIR_RTL, charArray, sourceToTargetMap, levels, params); 26620 26621 return charArray.join(""); 26622 }; // doBidiReorder( text, sourceToTargetMap, levels ) 26623 // Performs Bidi reordering by implementing Unicode Bidi algorithm. 26624 // Returns reordered string 26625 // @text [String]: 26626 // - input string to be reordered, this is input parameter 26627 // $sourceToTargetMap [Array] (optional) 26628 // - resultant mapping between input and output strings, this is output parameter 26629 // $levels [Array] (optional) 26630 // - array of calculated Bidi levels, , this is output parameter 26631 26632 26633 this.__bidiEngine__.doBidiReorder = function (text, sourceToTargetMap, levels) { 26634 _init(text, sourceToTargetMap); 26635 26636 if (!_isInVisual && _isOutVisual && !_isOutRtl) { 26637 // LLTR->VLTR, LRTL->VLTR 26638 _dir = _isInRtl ? DIR_RTL : DIR_LTR; 26639 text = _reorder(text, sourceToTargetMap, levels); 26640 } else if (_isInVisual && _isOutVisual && _isInRtl ^ _isOutRtl) { 26641 // VRTL->VLTR, VLTR->VRTL 26642 _dir = _isInRtl ? DIR_RTL : DIR_LTR; 26643 text = _invertString(text, sourceToTargetMap, levels); 26644 } else if (!_isInVisual && _isOutVisual && _isOutRtl) { 26645 // LLTR->VRTL, LRTL->VRTL 26646 _dir = _isInRtl ? DIR_RTL : DIR_LTR; 26647 text = _reorder(text, sourceToTargetMap, levels); 26648 text = _invertString(text, sourceToTargetMap); 26649 } else if (_isInVisual && !_isInRtl && !_isOutVisual && !_isOutRtl) { 26650 // VLTR->LLTR 26651 _dir = DIR_LTR; 26652 text = _reorder(text, sourceToTargetMap, levels); 26653 } else if (_isInVisual && !_isOutVisual && _isInRtl ^ _isOutRtl) { 26654 // VLTR->LRTL, VRTL->LLTR 26655 text = _invertString(text, sourceToTargetMap); 26656 26657 if (_isInRtl) { 26658 //LLTR -> VLTR 26659 _dir = DIR_LTR; 26660 text = _reorder(text, sourceToTargetMap, levels); 26661 } else { 26662 //LRTL -> VRTL 26663 _dir = DIR_RTL; 26664 text = _reorder(text, sourceToTargetMap, levels); 26665 text = _invertString(text, sourceToTargetMap); 26666 } 26667 } else if (_isInVisual && _isInRtl && !_isOutVisual && _isOutRtl) { 26668 // VRTL->LRTL 26669 _dir = DIR_RTL; 26670 text = _reorder(text, sourceToTargetMap, levels); 26671 text = _invertString(text, sourceToTargetMap); 26672 } else if (!_isInVisual && !_isOutVisual && _isInRtl ^ _isOutRtl) { 26673 // LRTL->LLTR, LLTR->LRTL 26674 var isSymmetricSwappingOrig = _isSymmetricSwapping; 26675 26676 if (_isInRtl) { 26677 //LRTL->LLTR 26678 _dir = DIR_RTL; 26679 text = _reorder(text, sourceToTargetMap, levels); 26680 _dir = DIR_LTR; 26681 _isSymmetricSwapping = false; 26682 text = _reorder(text, sourceToTargetMap, levels); 26683 _isSymmetricSwapping = isSymmetricSwappingOrig; 26684 } else { 26685 //LLTR->LRTL 26686 _dir = DIR_LTR; 26687 text = _reorder(text, sourceToTargetMap, levels); 26688 text = _invertString(text, sourceToTargetMap); 26689 _dir = DIR_RTL; 26690 _isSymmetricSwapping = false; 26691 text = _reorder(text, sourceToTargetMap, levels); 26692 _isSymmetricSwapping = isSymmetricSwappingOrig; 26693 text = _invertString(text, sourceToTargetMap); 26694 } 26695 } 26696 26697 return text; 26698 }; 26699 /** 26700 * @name setOptions( options ) 26701 * @function 26702 * Sets options for Bidi conversion 26703 * @param {Object}: 26704 * - isInputVisual {boolean} (defaults to false): allowed values: true(Visual mode), false(Logical mode) 26705 * - isInputRtl {boolean}: allowed values true(Right-to-left direction), false (Left-to-right directiion), undefined(Contectual direction, i.e.direction defined by first strong character of input string) 26706 * - isOutputVisual {boolean} (defaults to false): allowed values: true(Visual mode), false(Logical mode) 26707 * - isOutputRtl {boolean}: allowed values true(Right-to-left direction), false (Left-to-right directiion), undefined(Contectual direction, i.e.direction defined by first strong characterof input string) 26708 * - isSymmetricSwapping {boolean} (defaults to false): allowed values true(needs symmetric swapping), false (no need in symmetric swapping), 26709 */ 26710 26711 26712 this.__bidiEngine__.setOptions = function (options) { 26713 if (options) { 26714 _isInVisual = options.isInputVisual; 26715 _isOutVisual = options.isOutputVisual; 26716 _isInRtl = options.isInputRtl; 26717 _isOutRtl = options.isOutputRtl; 26718 _isSymmetricSwapping = options.isSymmetricSwapping; 26719 } 26720 }; 26721 26722 this.__bidiEngine__.setOptions(options); 26723 26724 return this.__bidiEngine__; 26725 }; 26726 26727 var _bidiUnicodeTypes = bidiUnicodeTypes; 26728 var bidiEngine = new jsPDF.__bidiEngine__({ 26729 isInputVisual: true 26730 }); 26731 26732 var bidiEngineFunction = function bidiEngineFunction(args) { 26733 var text = args.text; 26734 var x = args.x; 26735 var y = args.y; 26736 var options = args.options || {}; 26737 var mutex = args.mutex || {}; 26738 var lang = options.lang; 26739 var tmpText = []; 26740 options.isInputVisual = typeof options.isInputVisual === "boolean" ? options.isInputVisual : true; 26741 bidiEngine.setOptions(options); 26742 26743 if (Object.prototype.toString.call(text) === "[object Array]") { 26744 var i = 0; 26745 tmpText = []; 26746 26747 for (i = 0; i < text.length; i += 1) { 26748 if (Object.prototype.toString.call(text[i]) === "[object Array]") { 26749 tmpText.push([bidiEngine.doBidiReorder(text[i][0]), text[i][1], text[i][2]]); 26750 } else { 26751 tmpText.push([bidiEngine.doBidiReorder(text[i])]); 26752 } 26753 } 26754 26755 args.text = tmpText; 26756 } else { 26757 args.text = bidiEngine.doBidiReorder(text); 26758 } 26759 26760 bidiEngine.setOptions({ 26761 isInputVisual: true 26762 }); 26763 }; 26764 26765 jsPDF.API.events.push(["postProcessText", bidiEngineFunction]); 26766 })(jsPDF); 26767 26768 /* eslint-disable no-control-regex */ 26769 26770 jsPDF.API.TTFFont = function () { 26771 /************************************************************************/ 26772 26773 /* function : open */ 26774 26775 /* comment : Decode the encoded ttf content and create a TTFFont object. */ 26776 26777 /************************************************************************/ 26778 TTFFont.open = function (file) { 26779 return new TTFFont(file); 26780 }; 26781 /***************************************************************/ 26782 26783 /* function : TTFFont gernerator */ 26784 26785 /* comment : Decode TTF contents are parsed, Data, */ 26786 26787 /* Subset object is created, and registerTTF function is called.*/ 26788 26789 /***************************************************************/ 26790 26791 26792 function TTFFont(rawData) { 26793 var data; 26794 this.rawData = rawData; 26795 data = this.contents = new Data(rawData); 26796 this.contents.pos = 4; 26797 26798 if (data.readString(4) === "ttcf") { 26799 throw new Error("TTCF not supported."); 26800 } else { 26801 data.pos = 0; 26802 this.parse(); 26803 this.subset = new Subset(this); 26804 this.registerTTF(); 26805 } 26806 } 26807 /********************************************************/ 26808 26809 /* function : parse */ 26810 26811 /* comment : TTF Parses the file contents by each table.*/ 26812 26813 /********************************************************/ 26814 26815 26816 TTFFont.prototype.parse = function () { 26817 this.directory = new Directory(this.contents); 26818 this.head = new HeadTable(this); 26819 this.name = new NameTable(this); 26820 this.cmap = new CmapTable(this); 26821 this.toUnicode = {}; 26822 this.hhea = new HheaTable(this); 26823 this.maxp = new MaxpTable(this); 26824 this.hmtx = new HmtxTable(this); 26825 this.post = new PostTable(this); 26826 this.os2 = new OS2Table(this); 26827 this.loca = new LocaTable(this); 26828 this.glyf = new GlyfTable(this); 26829 this.ascender = this.os2.exists && this.os2.ascender || this.hhea.ascender; 26830 this.decender = this.os2.exists && this.os2.decender || this.hhea.decender; 26831 this.lineGap = this.os2.exists && this.os2.lineGap || this.hhea.lineGap; 26832 return this.bbox = [this.head.xMin, this.head.yMin, this.head.xMax, this.head.yMax]; 26833 }; 26834 /***************************************************************/ 26835 26836 /* function : registerTTF */ 26837 26838 /* comment : Get the value to assign pdf font descriptors. */ 26839 26840 /***************************************************************/ 26841 26842 26843 TTFFont.prototype.registerTTF = function () { 26844 var e, hi, low, raw, _ref; 26845 26846 this.scaleFactor = 1000.0 / this.head.unitsPerEm; 26847 26848 this.bbox = function () { 26849 var _i, _len, _ref, _results; 26850 26851 _ref = this.bbox; 26852 _results = []; 26853 26854 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 26855 e = _ref[_i]; 26856 26857 _results.push(Math.round(e * this.scaleFactor)); 26858 } 26859 26860 return _results; 26861 }.call(this); 26862 26863 this.stemV = 0; 26864 26865 if (this.post.exists) { 26866 raw = this.post.italic_angle; 26867 hi = raw >> 16; 26868 low = raw & 0xff; 26869 26870 if ((hi & 0x8000) !== 0) { 26871 hi = -((hi ^ 0xffff) + 1); 26872 } 26873 26874 this.italicAngle = +("" + hi + "." + low); 26875 } else { 26876 this.italicAngle = 0; 26877 } 26878 26879 this.ascender = Math.round(this.ascender * this.scaleFactor); 26880 this.decender = Math.round(this.decender * this.scaleFactor); 26881 this.lineGap = Math.round(this.lineGap * this.scaleFactor); 26882 this.capHeight = this.os2.exists && this.os2.capHeight || this.ascender; 26883 this.xHeight = this.os2.exists && this.os2.xHeight || 0; 26884 this.familyClass = (this.os2.exists && this.os2.familyClass || 0) >> 8; 26885 this.isSerif = (_ref = this.familyClass) === 1 || _ref === 2 || _ref === 3 || _ref === 4 || _ref === 5 || _ref === 7; 26886 this.isScript = this.familyClass === 10; 26887 this.flags = 0; 26888 26889 if (this.post.isFixedPitch) { 26890 this.flags |= 1 << 0; 26891 } 26892 26893 if (this.isSerif) { 26894 this.flags |= 1 << 1; 26895 } 26896 26897 if (this.isScript) { 26898 this.flags |= 1 << 3; 26899 } 26900 26901 if (this.italicAngle !== 0) { 26902 this.flags |= 1 << 6; 26903 } 26904 26905 this.flags |= 1 << 5; 26906 26907 if (!this.cmap.unicode) { 26908 throw new Error("No unicode cmap for font"); 26909 } 26910 }; 26911 26912 TTFFont.prototype.characterToGlyph = function (character) { 26913 var _ref; 26914 26915 return ((_ref = this.cmap.unicode) != null ? _ref.codeMap[character] : void 0) || 0; 26916 }; 26917 26918 TTFFont.prototype.widthOfGlyph = function (glyph) { 26919 var scale; 26920 scale = 1000.0 / this.head.unitsPerEm; 26921 return this.hmtx.forGlyph(glyph).advance * scale; 26922 }; 26923 26924 TTFFont.prototype.widthOfString = function (string, size, charSpace) { 26925 var charCode, i, scale, width, _ref; 26926 26927 string = "" + string; 26928 width = 0; 26929 26930 for (i = 0, _ref = string.length; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) { 26931 charCode = string.charCodeAt(i); 26932 width += this.widthOfGlyph(this.characterToGlyph(charCode)) + charSpace * (1000 / size) || 0; 26933 } 26934 26935 scale = size / 1000; 26936 return width * scale; 26937 }; 26938 26939 TTFFont.prototype.lineHeight = function (size, includeGap) { 26940 var gap; 26941 26942 if (includeGap == null) { 26943 includeGap = false; 26944 } 26945 26946 gap = includeGap ? this.lineGap : 0; 26947 return (this.ascender + gap - this.decender) / 1000 * size; 26948 }; 26949 26950 return TTFFont; 26951 }(); 26952 /************************************************************************************************/ 26953 26954 /* function : Data */ 26955 26956 /* comment : The ttf data decoded and stored in an array is read and written to the Data object.*/ 26957 26958 /************************************************************************************************/ 26959 26960 26961 var Data = function () { 26962 function Data(data) { 26963 this.data = data != null ? data : []; 26964 this.pos = 0; 26965 this.length = this.data.length; 26966 } 26967 26968 Data.prototype.readByte = function () { 26969 return this.data[this.pos++]; 26970 }; 26971 26972 Data.prototype.writeByte = function (byte) { 26973 return this.data[this.pos++] = byte; 26974 }; 26975 26976 Data.prototype.readUInt32 = function () { 26977 var b1, b2, b3, b4; 26978 b1 = this.readByte() * 0x1000000; 26979 b2 = this.readByte() << 16; 26980 b3 = this.readByte() << 8; 26981 b4 = this.readByte(); 26982 return b1 + b2 + b3 + b4; 26983 }; 26984 26985 Data.prototype.writeUInt32 = function (val) { 26986 this.writeByte(val >>> 24 & 0xff); 26987 this.writeByte(val >> 16 & 0xff); 26988 this.writeByte(val >> 8 & 0xff); 26989 return this.writeByte(val & 0xff); 26990 }; 26991 26992 Data.prototype.readInt32 = function () { 26993 var int; 26994 int = this.readUInt32(); 26995 26996 if (int >= 0x80000000) { 26997 return int - 0x100000000; 26998 } else { 26999 return int; 27000 } 27001 }; 27002 27003 Data.prototype.writeInt32 = function (val) { 27004 if (val < 0) { 27005 val += 0x100000000; 27006 } 27007 27008 return this.writeUInt32(val); 27009 }; 27010 27011 Data.prototype.readUInt16 = function () { 27012 var b1, b2; 27013 b1 = this.readByte() << 8; 27014 b2 = this.readByte(); 27015 return b1 | b2; 27016 }; 27017 27018 Data.prototype.writeUInt16 = function (val) { 27019 this.writeByte(val >> 8 & 0xff); 27020 return this.writeByte(val & 0xff); 27021 }; 27022 27023 Data.prototype.readInt16 = function () { 27024 var int; 27025 int = this.readUInt16(); 27026 27027 if (int >= 0x8000) { 27028 return int - 0x10000; 27029 } else { 27030 return int; 27031 } 27032 }; 27033 27034 Data.prototype.writeInt16 = function (val) { 27035 if (val < 0) { 27036 val += 0x10000; 27037 } 27038 27039 return this.writeUInt16(val); 27040 }; 27041 27042 Data.prototype.readString = function (length) { 27043 var i, ret; 27044 ret = []; 27045 27046 for (i = 0; 0 <= length ? i < length : i > length; i = 0 <= length ? ++i : --i) { 27047 ret[i] = String.fromCharCode(this.readByte()); 27048 } 27049 27050 return ret.join(""); 27051 }; 27052 27053 Data.prototype.writeString = function (val) { 27054 var i, _ref, _results; 27055 27056 _results = []; 27057 27058 for (i = 0, _ref = val.length; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) { 27059 _results.push(this.writeByte(val.charCodeAt(i))); 27060 } 27061 27062 return _results; 27063 }; 27064 /*Data.prototype.stringAt = function (pos, length) { 27065 this.pos = pos; 27066 return this.readString(length); 27067 };*/ 27068 27069 27070 Data.prototype.readShort = function () { 27071 return this.readInt16(); 27072 }; 27073 27074 Data.prototype.writeShort = function (val) { 27075 return this.writeInt16(val); 27076 }; 27077 27078 Data.prototype.readLongLong = function () { 27079 var b1, b2, b3, b4, b5, b6, b7, b8; 27080 b1 = this.readByte(); 27081 b2 = this.readByte(); 27082 b3 = this.readByte(); 27083 b4 = this.readByte(); 27084 b5 = this.readByte(); 27085 b6 = this.readByte(); 27086 b7 = this.readByte(); 27087 b8 = this.readByte(); 27088 27089 if (b1 & 0x80) { 27090 return ((b1 ^ 0xff) * 0x100000000000000 + (b2 ^ 0xff) * 0x1000000000000 + (b3 ^ 0xff) * 0x10000000000 + (b4 ^ 0xff) * 0x100000000 + (b5 ^ 0xff) * 0x1000000 + (b6 ^ 0xff) * 0x10000 + (b7 ^ 0xff) * 0x100 + (b8 ^ 0xff) + 1) * -1; 27091 } 27092 27093 return b1 * 0x100000000000000 + b2 * 0x1000000000000 + b3 * 0x10000000000 + b4 * 0x100000000 + b5 * 0x1000000 + b6 * 0x10000 + b7 * 0x100 + b8; 27094 }; 27095 27096 Data.prototype.writeLongLong = function (val) { 27097 var high, low; 27098 high = Math.floor(val / 0x100000000); 27099 low = val & 0xffffffff; 27100 this.writeByte(high >> 24 & 0xff); 27101 this.writeByte(high >> 16 & 0xff); 27102 this.writeByte(high >> 8 & 0xff); 27103 this.writeByte(high & 0xff); 27104 this.writeByte(low >> 24 & 0xff); 27105 this.writeByte(low >> 16 & 0xff); 27106 this.writeByte(low >> 8 & 0xff); 27107 return this.writeByte(low & 0xff); 27108 }; 27109 27110 Data.prototype.readInt = function () { 27111 return this.readInt32(); 27112 }; 27113 27114 Data.prototype.writeInt = function (val) { 27115 return this.writeInt32(val); 27116 }; 27117 /*Data.prototype.slice = function (start, end) { 27118 return this.data.slice(start, end); 27119 };*/ 27120 27121 27122 Data.prototype.read = function (bytes) { 27123 var buf, i; 27124 buf = []; 27125 27126 for (i = 0; 0 <= bytes ? i < bytes : i > bytes; i = 0 <= bytes ? ++i : --i) { 27127 buf.push(this.readByte()); 27128 } 27129 27130 return buf; 27131 }; 27132 27133 Data.prototype.write = function (bytes) { 27134 var byte, i, _len, _results; 27135 27136 _results = []; 27137 27138 for (i = 0, _len = bytes.length; i < _len; i++) { 27139 byte = bytes[i]; 27140 27141 _results.push(this.writeByte(byte)); 27142 } 27143 27144 return _results; 27145 }; 27146 27147 return Data; 27148 }(); 27149 27150 var Directory = function () { 27151 var checksum; 27152 /*****************************************************************************************************/ 27153 27154 /* function : Directory generator */ 27155 27156 /* comment : Initialize the offset, tag, length, and checksum for each table for the font to be used.*/ 27157 27158 /*****************************************************************************************************/ 27159 27160 function Directory(data) { 27161 var entry, i, _ref; 27162 27163 this.scalarType = data.readInt(); 27164 this.tableCount = data.readShort(); 27165 this.searchRange = data.readShort(); 27166 this.entrySelector = data.readShort(); 27167 this.rangeShift = data.readShort(); 27168 this.tables = {}; 27169 27170 for (i = 0, _ref = this.tableCount; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) { 27171 entry = { 27172 tag: data.readString(4), 27173 checksum: data.readInt(), 27174 offset: data.readInt(), 27175 length: data.readInt() 27176 }; 27177 this.tables[entry.tag] = entry; 27178 } 27179 } 27180 /********************************************************************************************************/ 27181 27182 /* function : encode */ 27183 27184 /* comment : It encodes and stores the font table object and information used for the directory object. */ 27185 27186 /********************************************************************************************************/ 27187 27188 27189 Directory.prototype.encode = function (tables) { 27190 var adjustment, directory, directoryLength, entrySelector, headOffset, log2, offset, rangeShift, searchRange, sum, table, tableCount, tableData, tag; 27191 tableCount = Object.keys(tables).length; 27192 log2 = Math.log(2); 27193 searchRange = Math.floor(Math.log(tableCount) / log2) * 16; 27194 entrySelector = Math.floor(searchRange / log2); 27195 rangeShift = tableCount * 16 - searchRange; 27196 directory = new Data(); 27197 directory.writeInt(this.scalarType); 27198 directory.writeShort(tableCount); 27199 directory.writeShort(searchRange); 27200 directory.writeShort(entrySelector); 27201 directory.writeShort(rangeShift); 27202 directoryLength = tableCount * 16; 27203 offset = directory.pos + directoryLength; 27204 headOffset = null; 27205 tableData = []; 27206 27207 for (tag in tables) { 27208 table = tables[tag]; 27209 directory.writeString(tag); 27210 directory.writeInt(checksum(table)); 27211 directory.writeInt(offset); 27212 directory.writeInt(table.length); 27213 tableData = tableData.concat(table); 27214 27215 if (tag === "head") { 27216 headOffset = offset; 27217 } 27218 27219 offset += table.length; 27220 27221 while (offset % 4) { 27222 tableData.push(0); 27223 offset++; 27224 } 27225 } 27226 27227 directory.write(tableData); 27228 sum = checksum(directory.data); 27229 adjustment = 0xb1b0afba - sum; 27230 directory.pos = headOffset + 8; 27231 directory.writeUInt32(adjustment); 27232 return directory.data; 27233 }; 27234 /***************************************************************/ 27235 27236 /* function : checksum */ 27237 27238 /* comment : Duplicate the table for the tag. */ 27239 27240 /***************************************************************/ 27241 27242 27243 checksum = function checksum(data) { 27244 var i, sum, tmp, _ref; 27245 27246 data = __slice.call(data); 27247 27248 while (data.length % 4) { 27249 data.push(0); 27250 } 27251 27252 tmp = new Data(data); 27253 sum = 0; 27254 27255 for (i = 0, _ref = data.length; i < _ref; i = i += 4) { 27256 sum += tmp.readUInt32(); 27257 } 27258 27259 return sum & 0xffffffff; 27260 }; 27261 27262 return Directory; 27263 }(); 27264 27265 var Table, 27266 __hasProp = {}.hasOwnProperty, 27267 __extends = function __extends(child, parent) { 27268 for (var key in parent) { 27269 if (__hasProp.call(parent, key)) child[key] = parent[key]; 27270 } 27271 27272 function ctor() { 27273 this.constructor = child; 27274 } 27275 27276 ctor.prototype = parent.prototype; 27277 child.prototype = new ctor(); 27278 child.__super__ = parent.prototype; 27279 return child; 27280 }; 27281 /***************************************************************/ 27282 27283 /* function : Table */ 27284 27285 /* comment : Save info for each table, and parse the table. */ 27286 27287 /***************************************************************/ 27288 27289 27290 Table = function () { 27291 function Table(file) { 27292 var info; 27293 this.file = file; 27294 info = this.file.directory.tables[this.tag]; 27295 this.exists = !!info; 27296 27297 if (info) { 27298 this.offset = info.offset, this.length = info.length; 27299 this.parse(this.file.contents); 27300 } 27301 } 27302 27303 Table.prototype.parse = function () {}; 27304 27305 Table.prototype.encode = function () {}; 27306 27307 Table.prototype.raw = function () { 27308 if (!this.exists) { 27309 return null; 27310 } 27311 27312 this.file.contents.pos = this.offset; 27313 return this.file.contents.read(this.length); 27314 }; 27315 27316 return Table; 27317 }(); 27318 27319 var HeadTable = function (_super) { 27320 __extends(HeadTable, _super); 27321 27322 function HeadTable() { 27323 return HeadTable.__super__.constructor.apply(this, arguments); 27324 } 27325 27326 HeadTable.prototype.tag = "head"; 27327 27328 HeadTable.prototype.parse = function (data) { 27329 data.pos = this.offset; 27330 this.version = data.readInt(); 27331 this.revision = data.readInt(); 27332 this.checkSumAdjustment = data.readInt(); 27333 this.magicNumber = data.readInt(); 27334 this.flags = data.readShort(); 27335 this.unitsPerEm = data.readShort(); 27336 this.created = data.readLongLong(); 27337 this.modified = data.readLongLong(); 27338 this.xMin = data.readShort(); 27339 this.yMin = data.readShort(); 27340 this.xMax = data.readShort(); 27341 this.yMax = data.readShort(); 27342 this.macStyle = data.readShort(); 27343 this.lowestRecPPEM = data.readShort(); 27344 this.fontDirectionHint = data.readShort(); 27345 this.indexToLocFormat = data.readShort(); 27346 return this.glyphDataFormat = data.readShort(); 27347 }; 27348 27349 HeadTable.prototype.encode = function (indexToLocFormat) { 27350 var table; 27351 table = new Data(); 27352 table.writeInt(this.version); 27353 table.writeInt(this.revision); 27354 table.writeInt(this.checkSumAdjustment); 27355 table.writeInt(this.magicNumber); 27356 table.writeShort(this.flags); 27357 table.writeShort(this.unitsPerEm); 27358 table.writeLongLong(this.created); 27359 table.writeLongLong(this.modified); 27360 table.writeShort(this.xMin); 27361 table.writeShort(this.yMin); 27362 table.writeShort(this.xMax); 27363 table.writeShort(this.yMax); 27364 table.writeShort(this.macStyle); 27365 table.writeShort(this.lowestRecPPEM); 27366 table.writeShort(this.fontDirectionHint); 27367 table.writeShort(indexToLocFormat); 27368 table.writeShort(this.glyphDataFormat); 27369 return table.data; 27370 }; 27371 27372 return HeadTable; 27373 }(Table); 27374 /************************************************************************************/ 27375 27376 /* function : CmapEntry */ 27377 27378 /* comment : Cmap Initializes and encodes object information (required by pdf spec).*/ 27379 27380 /************************************************************************************/ 27381 27382 27383 var CmapEntry = function () { 27384 function CmapEntry(data, offset) { 27385 var code, count, endCode, glyphId, glyphIds, i, idDelta, idRangeOffset, index, saveOffset, segCount, segCountX2, start, startCode, tail, _j, _k, _len; 27386 27387 this.platformID = data.readUInt16(); 27388 this.encodingID = data.readShort(); 27389 this.offset = offset + data.readInt(); 27390 saveOffset = data.pos; 27391 data.pos = this.offset; 27392 this.format = data.readUInt16(); 27393 this.length = data.readUInt16(); 27394 this.language = data.readUInt16(); 27395 this.isUnicode = this.platformID === 3 && this.encodingID === 1 && this.format === 4 || this.platformID === 0 && this.format === 4; 27396 this.codeMap = {}; 27397 27398 switch (this.format) { 27399 case 0: 27400 for (i = 0; i < 256; ++i) { 27401 this.codeMap[i] = data.readByte(); 27402 } 27403 27404 break; 27405 27406 case 4: 27407 segCountX2 = data.readUInt16(); 27408 segCount = segCountX2 / 2; 27409 data.pos += 6; 27410 27411 endCode = function () { 27412 var _j, _results; 27413 27414 _results = []; 27415 27416 for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) { 27417 _results.push(data.readUInt16()); 27418 } 27419 27420 return _results; 27421 }(); 27422 27423 data.pos += 2; 27424 27425 startCode = function () { 27426 var _j, _results; 27427 27428 _results = []; 27429 27430 for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) { 27431 _results.push(data.readUInt16()); 27432 } 27433 27434 return _results; 27435 }(); 27436 27437 idDelta = function () { 27438 var _j, _results; 27439 27440 _results = []; 27441 27442 for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) { 27443 _results.push(data.readUInt16()); 27444 } 27445 27446 return _results; 27447 }(); 27448 27449 idRangeOffset = function () { 27450 var _j, _results; 27451 27452 _results = []; 27453 27454 for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) { 27455 _results.push(data.readUInt16()); 27456 } 27457 27458 return _results; 27459 }(); 27460 27461 count = (this.length - data.pos + this.offset) / 2; 27462 27463 glyphIds = function () { 27464 var _j, _results; 27465 27466 _results = []; 27467 27468 for (i = _j = 0; 0 <= count ? _j < count : _j > count; i = 0 <= count ? ++_j : --_j) { 27469 _results.push(data.readUInt16()); 27470 } 27471 27472 return _results; 27473 }(); 27474 27475 for (i = _j = 0, _len = endCode.length; _j < _len; i = ++_j) { 27476 tail = endCode[i]; 27477 start = startCode[i]; 27478 27479 for (code = _k = start; start <= tail ? _k <= tail : _k >= tail; code = start <= tail ? ++_k : --_k) { 27480 if (idRangeOffset[i] === 0) { 27481 glyphId = code + idDelta[i]; 27482 } else { 27483 index = idRangeOffset[i] / 2 + (code - start) - (segCount - i); 27484 glyphId = glyphIds[index] || 0; 27485 27486 if (glyphId !== 0) { 27487 glyphId += idDelta[i]; 27488 } 27489 } 27490 27491 this.codeMap[code] = glyphId & 0xffff; 27492 } 27493 } 27494 27495 } 27496 27497 data.pos = saveOffset; 27498 } 27499 27500 CmapEntry.encode = function (charmap, encoding) { 27501 var charMap, code, codeMap, codes, delta, deltas, diff, endCode, endCodes, entrySelector, glyphIDs, i, id, indexes, last, map, nextID, offset, old, rangeOffsets, rangeShift, searchRange, segCount, segCountX2, startCode, startCodes, startGlyph, subtable, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _len6, _len7, _m, _n, _name, _o, _p, _q; 27502 27503 subtable = new Data(); 27504 codes = Object.keys(charmap).sort(function (a, b) { 27505 return a - b; 27506 }); 27507 27508 switch (encoding) { 27509 case "macroman": 27510 id = 0; 27511 27512 indexes = function () { 27513 var _results = []; 27514 27515 for (i = 0; i < 256; ++i) { 27516 _results.push(0); 27517 } 27518 27519 return _results; 27520 }(); 27521 27522 map = { 27523 0: 0 27524 }; 27525 codeMap = {}; 27526 27527 for (_i = 0, _len = codes.length; _i < _len; _i++) { 27528 code = codes[_i]; 27529 27530 if (map[_name = charmap[code]] == null) { 27531 map[_name] = ++id; 27532 } 27533 27534 codeMap[code] = { 27535 old: charmap[code], 27536 new: map[charmap[code]] 27537 }; 27538 indexes[code] = map[charmap[code]]; 27539 } 27540 27541 subtable.writeUInt16(1); 27542 subtable.writeUInt16(0); 27543 subtable.writeUInt32(12); 27544 subtable.writeUInt16(0); 27545 subtable.writeUInt16(262); 27546 subtable.writeUInt16(0); 27547 subtable.write(indexes); 27548 return { 27549 charMap: codeMap, 27550 subtable: subtable.data, 27551 maxGlyphID: id + 1 27552 }; 27553 27554 case "unicode": 27555 startCodes = []; 27556 endCodes = []; 27557 nextID = 0; 27558 map = {}; 27559 charMap = {}; 27560 last = diff = null; 27561 27562 for (_j = 0, _len1 = codes.length; _j < _len1; _j++) { 27563 code = codes[_j]; 27564 old = charmap[code]; 27565 27566 if (map[old] == null) { 27567 map[old] = ++nextID; 27568 } 27569 27570 charMap[code] = { 27571 old: old, 27572 new: map[old] 27573 }; 27574 delta = map[old] - code; 27575 27576 if (last == null || delta !== diff) { 27577 if (last) { 27578 endCodes.push(last); 27579 } 27580 27581 startCodes.push(code); 27582 diff = delta; 27583 } 27584 27585 last = code; 27586 } 27587 27588 if (last) { 27589 endCodes.push(last); 27590 } 27591 27592 endCodes.push(0xffff); 27593 startCodes.push(0xffff); 27594 segCount = startCodes.length; 27595 segCountX2 = segCount * 2; 27596 searchRange = 2 * Math.pow(Math.log(segCount) / Math.LN2, 2); 27597 entrySelector = Math.log(searchRange / 2) / Math.LN2; 27598 rangeShift = 2 * segCount - searchRange; 27599 deltas = []; 27600 rangeOffsets = []; 27601 glyphIDs = []; 27602 27603 for (i = _k = 0, _len2 = startCodes.length; _k < _len2; i = ++_k) { 27604 startCode = startCodes[i]; 27605 endCode = endCodes[i]; 27606 27607 if (startCode === 0xffff) { 27608 deltas.push(0); 27609 rangeOffsets.push(0); 27610 break; 27611 } 27612 27613 startGlyph = charMap[startCode]["new"]; 27614 27615 if (startCode - startGlyph >= 0x8000) { 27616 deltas.push(0); 27617 rangeOffsets.push(2 * (glyphIDs.length + segCount - i)); 27618 27619 for (code = _l = startCode; startCode <= endCode ? _l <= endCode : _l >= endCode; code = startCode <= endCode ? ++_l : --_l) { 27620 glyphIDs.push(charMap[code]["new"]); 27621 } 27622 } else { 27623 deltas.push(startGlyph - startCode); 27624 rangeOffsets.push(0); 27625 } 27626 } 27627 27628 subtable.writeUInt16(3); 27629 subtable.writeUInt16(1); 27630 subtable.writeUInt32(12); 27631 subtable.writeUInt16(4); 27632 subtable.writeUInt16(16 + segCount * 8 + glyphIDs.length * 2); 27633 subtable.writeUInt16(0); 27634 subtable.writeUInt16(segCountX2); 27635 subtable.writeUInt16(searchRange); 27636 subtable.writeUInt16(entrySelector); 27637 subtable.writeUInt16(rangeShift); 27638 27639 for (_m = 0, _len3 = endCodes.length; _m < _len3; _m++) { 27640 code = endCodes[_m]; 27641 subtable.writeUInt16(code); 27642 } 27643 27644 subtable.writeUInt16(0); 27645 27646 for (_n = 0, _len4 = startCodes.length; _n < _len4; _n++) { 27647 code = startCodes[_n]; 27648 subtable.writeUInt16(code); 27649 } 27650 27651 for (_o = 0, _len5 = deltas.length; _o < _len5; _o++) { 27652 delta = deltas[_o]; 27653 subtable.writeUInt16(delta); 27654 } 27655 27656 for (_p = 0, _len6 = rangeOffsets.length; _p < _len6; _p++) { 27657 offset = rangeOffsets[_p]; 27658 subtable.writeUInt16(offset); 27659 } 27660 27661 for (_q = 0, _len7 = glyphIDs.length; _q < _len7; _q++) { 27662 id = glyphIDs[_q]; 27663 subtable.writeUInt16(id); 27664 } 27665 27666 return { 27667 charMap: charMap, 27668 subtable: subtable.data, 27669 maxGlyphID: nextID + 1 27670 }; 27671 } 27672 }; 27673 27674 return CmapEntry; 27675 }(); 27676 27677 var CmapTable = function (_super) { 27678 __extends(CmapTable, _super); 27679 27680 function CmapTable() { 27681 return CmapTable.__super__.constructor.apply(this, arguments); 27682 } 27683 27684 CmapTable.prototype.tag = "cmap"; 27685 27686 CmapTable.prototype.parse = function (data) { 27687 var entry, i, tableCount; 27688 data.pos = this.offset; 27689 this.version = data.readUInt16(); 27690 tableCount = data.readUInt16(); 27691 this.tables = []; 27692 this.unicode = null; 27693 27694 for (i = 0; 0 <= tableCount ? i < tableCount : i > tableCount; i = 0 <= tableCount ? ++i : --i) { 27695 entry = new CmapEntry(data, this.offset); 27696 this.tables.push(entry); 27697 27698 if (entry.isUnicode) { 27699 if (this.unicode == null) { 27700 this.unicode = entry; 27701 } 27702 } 27703 } 27704 27705 return true; 27706 }; 27707 /*************************************************************************/ 27708 27709 /* function : encode */ 27710 27711 /* comment : Encode the cmap table corresponding to the input character. */ 27712 27713 /*************************************************************************/ 27714 27715 27716 CmapTable.encode = function (charmap, encoding) { 27717 var result, table; 27718 27719 if (encoding == null) { 27720 encoding = "macroman"; 27721 } 27722 27723 result = CmapEntry.encode(charmap, encoding); 27724 table = new Data(); 27725 table.writeUInt16(0); 27726 table.writeUInt16(1); 27727 result.table = table.data.concat(result.subtable); 27728 return result; 27729 }; 27730 27731 return CmapTable; 27732 }(Table); 27733 27734 var HheaTable = function (_super) { 27735 __extends(HheaTable, _super); 27736 27737 function HheaTable() { 27738 return HheaTable.__super__.constructor.apply(this, arguments); 27739 } 27740 27741 HheaTable.prototype.tag = "hhea"; 27742 27743 HheaTable.prototype.parse = function (data) { 27744 data.pos = this.offset; 27745 this.version = data.readInt(); 27746 this.ascender = data.readShort(); 27747 this.decender = data.readShort(); 27748 this.lineGap = data.readShort(); 27749 this.advanceWidthMax = data.readShort(); 27750 this.minLeftSideBearing = data.readShort(); 27751 this.minRightSideBearing = data.readShort(); 27752 this.xMaxExtent = data.readShort(); 27753 this.caretSlopeRise = data.readShort(); 27754 this.caretSlopeRun = data.readShort(); 27755 this.caretOffset = data.readShort(); 27756 data.pos += 4 * 2; 27757 this.metricDataFormat = data.readShort(); 27758 return this.numberOfMetrics = data.readUInt16(); 27759 }; 27760 /*HheaTable.prototype.encode = function (ids) { 27761 var i, table, _i, _ref; 27762 table = new Data; 27763 table.writeInt(this.version); 27764 table.writeShort(this.ascender); 27765 table.writeShort(this.decender); 27766 table.writeShort(this.lineGap); 27767 table.writeShort(this.advanceWidthMax); 27768 table.writeShort(this.minLeftSideBearing); 27769 table.writeShort(this.minRightSideBearing); 27770 table.writeShort(this.xMaxExtent); 27771 table.writeShort(this.caretSlopeRise); 27772 table.writeShort(this.caretSlopeRun); 27773 table.writeShort(this.caretOffset); 27774 for (i = _i = 0, _ref = 4 * 2; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { 27775 table.writeByte(0); 27776 } 27777 table.writeShort(this.metricDataFormat); 27778 table.writeUInt16(ids.length); 27779 return table.data; 27780 };*/ 27781 27782 27783 return HheaTable; 27784 }(Table); 27785 27786 var OS2Table = function (_super) { 27787 __extends(OS2Table, _super); 27788 27789 function OS2Table() { 27790 return OS2Table.__super__.constructor.apply(this, arguments); 27791 } 27792 27793 OS2Table.prototype.tag = "OS/2"; 27794 27795 OS2Table.prototype.parse = function (data) { 27796 data.pos = this.offset; 27797 this.version = data.readUInt16(); 27798 this.averageCharWidth = data.readShort(); 27799 this.weightClass = data.readUInt16(); 27800 this.widthClass = data.readUInt16(); 27801 this.type = data.readShort(); 27802 this.ySubscriptXSize = data.readShort(); 27803 this.ySubscriptYSize = data.readShort(); 27804 this.ySubscriptXOffset = data.readShort(); 27805 this.ySubscriptYOffset = data.readShort(); 27806 this.ySuperscriptXSize = data.readShort(); 27807 this.ySuperscriptYSize = data.readShort(); 27808 this.ySuperscriptXOffset = data.readShort(); 27809 this.ySuperscriptYOffset = data.readShort(); 27810 this.yStrikeoutSize = data.readShort(); 27811 this.yStrikeoutPosition = data.readShort(); 27812 this.familyClass = data.readShort(); 27813 27814 this.panose = function () { 27815 var i, _results; 27816 27817 _results = []; 27818 27819 for (i = 0; i < 10; ++i) { 27820 _results.push(data.readByte()); 27821 } 27822 27823 return _results; 27824 }(); 27825 27826 this.charRange = function () { 27827 var i, _results; 27828 27829 _results = []; 27830 27831 for (i = 0; i < 4; ++i) { 27832 _results.push(data.readInt()); 27833 } 27834 27835 return _results; 27836 }(); 27837 27838 this.vendorID = data.readString(4); 27839 this.selection = data.readShort(); 27840 this.firstCharIndex = data.readShort(); 27841 this.lastCharIndex = data.readShort(); 27842 27843 if (this.version > 0) { 27844 this.ascent = data.readShort(); 27845 this.descent = data.readShort(); 27846 this.lineGap = data.readShort(); 27847 this.winAscent = data.readShort(); 27848 this.winDescent = data.readShort(); 27849 27850 this.codePageRange = function () { 27851 var i, _results; 27852 27853 _results = []; 27854 27855 for (i = 0; i < 2; i = ++i) { 27856 _results.push(data.readInt()); 27857 } 27858 27859 return _results; 27860 }(); 27861 27862 if (this.version > 1) { 27863 this.xHeight = data.readShort(); 27864 this.capHeight = data.readShort(); 27865 this.defaultChar = data.readShort(); 27866 this.breakChar = data.readShort(); 27867 return this.maxContext = data.readShort(); 27868 } 27869 } 27870 }; 27871 /*OS2Table.prototype.encode = function () { 27872 return this.raw(); 27873 };*/ 27874 27875 27876 return OS2Table; 27877 }(Table); 27878 27879 var PostTable = function (_super) { 27880 27881 __extends(PostTable, _super); 27882 27883 function PostTable() { 27884 return PostTable.__super__.constructor.apply(this, arguments); 27885 } 27886 27887 PostTable.prototype.tag = "post"; 27888 27889 PostTable.prototype.parse = function (data) { 27890 var length, numberOfGlyphs, _results; 27891 27892 data.pos = this.offset; 27893 this.format = data.readInt(); 27894 this.italicAngle = data.readInt(); 27895 this.underlinePosition = data.readShort(); 27896 this.underlineThickness = data.readShort(); 27897 this.isFixedPitch = data.readInt(); 27898 this.minMemType42 = data.readInt(); 27899 this.maxMemType42 = data.readInt(); 27900 this.minMemType1 = data.readInt(); 27901 this.maxMemType1 = data.readInt(); 27902 27903 switch (this.format) { 27904 case 0x00010000: 27905 break; 27906 27907 case 0x00020000: 27908 numberOfGlyphs = data.readUInt16(); 27909 this.glyphNameIndex = []; 27910 var i; 27911 27912 for (i = 0; 0 <= numberOfGlyphs ? i < numberOfGlyphs : i > numberOfGlyphs; i = 0 <= numberOfGlyphs ? ++i : --i) { 27913 this.glyphNameIndex.push(data.readUInt16()); 27914 } 27915 27916 this.names = []; 27917 _results = []; 27918 27919 while (data.pos < this.offset + this.length) { 27920 length = data.readByte(); 27921 27922 _results.push(this.names.push(data.readString(length))); 27923 } 27924 27925 return _results; 27926 27927 case 0x00025000: 27928 numberOfGlyphs = data.readUInt16(); 27929 return this.offsets = data.read(numberOfGlyphs); 27930 27931 case 0x00030000: 27932 break; 27933 27934 case 0x00040000: 27935 return this.map = function () { 27936 var _j, _ref, _results1; 27937 27938 _results1 = []; 27939 27940 for (i = _j = 0, _ref = this.file.maxp.numGlyphs; 0 <= _ref ? _j < _ref : _j > _ref; i = 0 <= _ref ? ++_j : --_j) { 27941 _results1.push(data.readUInt32()); 27942 } 27943 27944 return _results1; 27945 }.call(this); 27946 } 27947 }; 27948 return PostTable; 27949 }(Table); 27950 /*********************************************************************************************************/ 27951 27952 /* function : NameEntry */ 27953 27954 /* comment : Store copyright information, platformID, encodingID, and languageID in the NameEntry object.*/ 27955 27956 /*********************************************************************************************************/ 27957 27958 27959 var NameEntry = function () { 27960 function NameEntry(raw, entry) { 27961 this.raw = raw; 27962 this.length = raw.length; 27963 this.platformID = entry.platformID; 27964 this.encodingID = entry.encodingID; 27965 this.languageID = entry.languageID; 27966 } 27967 27968 return NameEntry; 27969 }(); 27970 27971 var NameTable = function (_super) { 27972 27973 __extends(NameTable, _super); 27974 27975 function NameTable() { 27976 return NameTable.__super__.constructor.apply(this, arguments); 27977 } 27978 27979 NameTable.prototype.tag = "name"; 27980 27981 NameTable.prototype.parse = function (data) { 27982 var count, entries, entry, i, name, stringOffset, strings, text, _j, _len, _name; 27983 27984 data.pos = this.offset; 27985 data.readShort(); //format 27986 27987 count = data.readShort(); 27988 stringOffset = data.readShort(); 27989 entries = []; 27990 27991 for (i = 0; 0 <= count ? i < count : i > count; i = 0 <= count ? ++i : --i) { 27992 entries.push({ 27993 platformID: data.readShort(), 27994 encodingID: data.readShort(), 27995 languageID: data.readShort(), 27996 nameID: data.readShort(), 27997 length: data.readShort(), 27998 offset: this.offset + stringOffset + data.readShort() 27999 }); 28000 } 28001 28002 strings = {}; 28003 28004 for (i = _j = 0, _len = entries.length; _j < _len; i = ++_j) { 28005 entry = entries[i]; 28006 data.pos = entry.offset; 28007 text = data.readString(entry.length); 28008 name = new NameEntry(text, entry); 28009 28010 if (strings[_name = entry.nameID] == null) { 28011 strings[_name] = []; 28012 } 28013 28014 strings[entry.nameID].push(name); 28015 } 28016 28017 this.strings = strings; 28018 this.copyright = strings[0]; 28019 this.fontFamily = strings[1]; 28020 this.fontSubfamily = strings[2]; 28021 this.uniqueSubfamily = strings[3]; 28022 this.fontName = strings[4]; 28023 this.version = strings[5]; 28024 28025 try { 28026 this.postscriptName = strings[6][0].raw.replace(/[\x00-\x19\x80-\xff]/g, ""); 28027 } catch (e) { 28028 this.postscriptName = strings[4][0].raw.replace(/[\x00-\x19\x80-\xff]/g, ""); 28029 } 28030 28031 this.trademark = strings[7]; 28032 this.manufacturer = strings[8]; 28033 this.designer = strings[9]; 28034 this.description = strings[10]; 28035 this.vendorUrl = strings[11]; 28036 this.designerUrl = strings[12]; 28037 this.license = strings[13]; 28038 this.licenseUrl = strings[14]; 28039 this.preferredFamily = strings[15]; 28040 this.preferredSubfamily = strings[17]; 28041 this.compatibleFull = strings[18]; 28042 return this.sampleText = strings[19]; 28043 }; 28044 /*NameTable.prototype.encode = function () { 28045 var id, list, nameID, nameTable, postscriptName, strCount, strTable, string, strings, table, val, _i, _len, _ref; 28046 strings = {}; 28047 _ref = this.strings; 28048 for (id in _ref) { 28049 val = _ref[id]; 28050 strings[id] = val; 28051 } 28052 postscriptName = new NameEntry("" + subsetTag + "+" + this.postscriptName, { 28053 platformID: 1 28054 , encodingID: 0 28055 , languageID: 0 28056 }); 28057 strings[6] = [postscriptName]; 28058 subsetTag = successorOf(subsetTag); 28059 strCount = 0; 28060 for (id in strings) { 28061 list = strings[id]; 28062 if (list != null) { 28063 strCount += list.length; 28064 } 28065 } 28066 table = new Data; 28067 strTable = new Data; 28068 table.writeShort(0); 28069 table.writeShort(strCount); 28070 table.writeShort(6 + 12 * strCount); 28071 for (nameID in strings) { 28072 list = strings[nameID]; 28073 if (list != null) { 28074 for (_i = 0, _len = list.length; _i < _len; _i++) { 28075 string = list[_i]; 28076 table.writeShort(string.platformID); 28077 table.writeShort(string.encodingID); 28078 table.writeShort(string.languageID); 28079 table.writeShort(nameID); 28080 table.writeShort(string.length); 28081 table.writeShort(strTable.pos); 28082 strTable.writeString(string.raw); 28083 } 28084 } 28085 } 28086 return nameTable = { 28087 postscriptName: postscriptName.raw 28088 , table: table.data.concat(strTable.data) 28089 }; 28090 };*/ 28091 28092 return NameTable; 28093 }(Table); 28094 28095 var MaxpTable = function (_super) { 28096 __extends(MaxpTable, _super); 28097 28098 function MaxpTable() { 28099 return MaxpTable.__super__.constructor.apply(this, arguments); 28100 } 28101 28102 MaxpTable.prototype.tag = "maxp"; 28103 28104 MaxpTable.prototype.parse = function (data) { 28105 data.pos = this.offset; 28106 this.version = data.readInt(); 28107 this.numGlyphs = data.readUInt16(); 28108 this.maxPoints = data.readUInt16(); 28109 this.maxContours = data.readUInt16(); 28110 this.maxCompositePoints = data.readUInt16(); 28111 this.maxComponentContours = data.readUInt16(); 28112 this.maxZones = data.readUInt16(); 28113 this.maxTwilightPoints = data.readUInt16(); 28114 this.maxStorage = data.readUInt16(); 28115 this.maxFunctionDefs = data.readUInt16(); 28116 this.maxInstructionDefs = data.readUInt16(); 28117 this.maxStackElements = data.readUInt16(); 28118 this.maxSizeOfInstructions = data.readUInt16(); 28119 this.maxComponentElements = data.readUInt16(); 28120 return this.maxComponentDepth = data.readUInt16(); 28121 }; 28122 /*MaxpTable.prototype.encode = function (ids) { 28123 var table; 28124 table = new Data; 28125 table.writeInt(this.version); 28126 table.writeUInt16(ids.length); 28127 table.writeUInt16(this.maxPoints); 28128 table.writeUInt16(this.maxContours); 28129 table.writeUInt16(this.maxCompositePoints); 28130 table.writeUInt16(this.maxComponentContours); 28131 table.writeUInt16(this.maxZones); 28132 table.writeUInt16(this.maxTwilightPoints); 28133 table.writeUInt16(this.maxStorage); 28134 table.writeUInt16(this.maxFunctionDefs); 28135 table.writeUInt16(this.maxInstructionDefs); 28136 table.writeUInt16(this.maxStackElements); 28137 table.writeUInt16(this.maxSizeOfInstructions); 28138 table.writeUInt16(this.maxComponentElements); 28139 table.writeUInt16(this.maxComponentDepth); 28140 return table.data; 28141 };*/ 28142 28143 28144 return MaxpTable; 28145 }(Table); 28146 28147 var HmtxTable = function (_super) { 28148 __extends(HmtxTable, _super); 28149 28150 function HmtxTable() { 28151 return HmtxTable.__super__.constructor.apply(this, arguments); 28152 } 28153 28154 HmtxTable.prototype.tag = "hmtx"; 28155 28156 HmtxTable.prototype.parse = function (data) { 28157 var i, last, lsbCount, m, _j, _ref, _results; 28158 28159 data.pos = this.offset; 28160 this.metrics = []; 28161 28162 for (i = 0, _ref = this.file.hhea.numberOfMetrics; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) { 28163 this.metrics.push({ 28164 advance: data.readUInt16(), 28165 lsb: data.readInt16() 28166 }); 28167 } 28168 28169 lsbCount = this.file.maxp.numGlyphs - this.file.hhea.numberOfMetrics; 28170 28171 this.leftSideBearings = function () { 28172 var _j, _results; 28173 28174 _results = []; 28175 28176 for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) { 28177 _results.push(data.readInt16()); 28178 } 28179 28180 return _results; 28181 }(); 28182 28183 this.widths = function () { 28184 var _j, _len, _ref1, _results; 28185 28186 _ref1 = this.metrics; 28187 _results = []; 28188 28189 for (_j = 0, _len = _ref1.length; _j < _len; _j++) { 28190 m = _ref1[_j]; 28191 28192 _results.push(m.advance); 28193 } 28194 28195 return _results; 28196 }.call(this); 28197 28198 last = this.widths[this.widths.length - 1]; 28199 _results = []; 28200 28201 for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) { 28202 _results.push(this.widths.push(last)); 28203 } 28204 28205 return _results; 28206 }; 28207 /***************************************************************/ 28208 28209 /* function : forGlyph */ 28210 28211 /* comment : Returns the advance width and lsb for this glyph. */ 28212 28213 /***************************************************************/ 28214 28215 28216 HmtxTable.prototype.forGlyph = function (id) { 28217 if (id in this.metrics) { 28218 return this.metrics[id]; 28219 } 28220 28221 return { 28222 advance: this.metrics[this.metrics.length - 1].advance, 28223 lsb: this.leftSideBearings[id - this.metrics.length] 28224 }; 28225 }; 28226 /*HmtxTable.prototype.encode = function (mapping) { 28227 var id, metric, table, _i, _len; 28228 table = new Data; 28229 for (_i = 0, _len = mapping.length; _i < _len; _i++) { 28230 id = mapping[_i]; 28231 metric = this.forGlyph(id); 28232 table.writeUInt16(metric.advance); 28233 table.writeUInt16(metric.lsb); 28234 } 28235 return table.data; 28236 };*/ 28237 28238 28239 return HmtxTable; 28240 }(Table); 28241 28242 var __slice = [].slice; 28243 28244 var GlyfTable = function (_super) { 28245 __extends(GlyfTable, _super); 28246 28247 function GlyfTable() { 28248 return GlyfTable.__super__.constructor.apply(this, arguments); 28249 } 28250 28251 GlyfTable.prototype.tag = "glyf"; 28252 28253 GlyfTable.prototype.parse = function () { 28254 return this.cache = {}; 28255 }; 28256 28257 GlyfTable.prototype.glyphFor = function (id) { 28258 var data, index, length, loca, numberOfContours, raw, xMax, xMin, yMax, yMin; 28259 28260 if (id in this.cache) { 28261 return this.cache[id]; 28262 } 28263 28264 loca = this.file.loca; 28265 data = this.file.contents; 28266 index = loca.indexOf(id); 28267 length = loca.lengthOf(id); 28268 28269 if (length === 0) { 28270 return this.cache[id] = null; 28271 } 28272 28273 data.pos = this.offset + index; 28274 raw = new Data(data.read(length)); 28275 numberOfContours = raw.readShort(); 28276 xMin = raw.readShort(); 28277 yMin = raw.readShort(); 28278 xMax = raw.readShort(); 28279 yMax = raw.readShort(); 28280 28281 if (numberOfContours === -1) { 28282 this.cache[id] = new CompoundGlyph(raw, xMin, yMin, xMax, yMax); 28283 } else { 28284 this.cache[id] = new SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax); 28285 } 28286 28287 return this.cache[id]; 28288 }; 28289 28290 GlyfTable.prototype.encode = function (glyphs, mapping, old2new) { 28291 var glyph, id, offsets, table, _i, _len; 28292 28293 table = []; 28294 offsets = []; 28295 28296 for (_i = 0, _len = mapping.length; _i < _len; _i++) { 28297 id = mapping[_i]; 28298 glyph = glyphs[id]; 28299 offsets.push(table.length); 28300 28301 if (glyph) { 28302 table = table.concat(glyph.encode(old2new)); 28303 } 28304 } 28305 28306 offsets.push(table.length); 28307 return { 28308 table: table, 28309 offsets: offsets 28310 }; 28311 }; 28312 28313 return GlyfTable; 28314 }(Table); 28315 28316 var SimpleGlyph = function () { 28317 /**************************************************************************/ 28318 28319 /* function : SimpleGlyph */ 28320 28321 /* comment : Stores raw, xMin, yMin, xMax, and yMax values for this glyph.*/ 28322 28323 /**************************************************************************/ 28324 function SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax) { 28325 this.raw = raw; 28326 this.numberOfContours = numberOfContours; 28327 this.xMin = xMin; 28328 this.yMin = yMin; 28329 this.xMax = xMax; 28330 this.yMax = yMax; 28331 this.compound = false; 28332 } 28333 28334 SimpleGlyph.prototype.encode = function () { 28335 return this.raw.data; 28336 }; 28337 28338 return SimpleGlyph; 28339 }(); 28340 28341 var CompoundGlyph = function () { 28342 var ARG_1_AND_2_ARE_WORDS, MORE_COMPONENTS, WE_HAVE_AN_X_AND_Y_SCALE, WE_HAVE_A_SCALE, WE_HAVE_A_TWO_BY_TWO; 28343 ARG_1_AND_2_ARE_WORDS = 0x0001; 28344 WE_HAVE_A_SCALE = 0x0008; 28345 MORE_COMPONENTS = 0x0020; 28346 WE_HAVE_AN_X_AND_Y_SCALE = 0x0040; 28347 WE_HAVE_A_TWO_BY_TWO = 0x0080; 28348 /********************************************************************************************************************/ 28349 28350 /* function : CompoundGlypg generator */ 28351 28352 /* comment : It stores raw, xMin, yMin, xMax, yMax, glyph id, and glyph offset for the corresponding compound glyph.*/ 28353 28354 /********************************************************************************************************************/ 28355 28356 function CompoundGlyph(raw, xMin, yMin, xMax, yMax) { 28357 var data, flags; 28358 this.raw = raw; 28359 this.xMin = xMin; 28360 this.yMin = yMin; 28361 this.xMax = xMax; 28362 this.yMax = yMax; 28363 this.compound = true; 28364 this.glyphIDs = []; 28365 this.glyphOffsets = []; 28366 data = this.raw; 28367 28368 while (true) { 28369 flags = data.readShort(); 28370 this.glyphOffsets.push(data.pos); 28371 this.glyphIDs.push(data.readUInt16()); 28372 28373 if (!(flags & MORE_COMPONENTS)) { 28374 break; 28375 } 28376 28377 if (flags & ARG_1_AND_2_ARE_WORDS) { 28378 data.pos += 4; 28379 } else { 28380 data.pos += 2; 28381 } 28382 28383 if (flags & WE_HAVE_A_TWO_BY_TWO) { 28384 data.pos += 8; 28385 } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { 28386 data.pos += 4; 28387 } else if (flags & WE_HAVE_A_SCALE) { 28388 data.pos += 2; 28389 } 28390 } 28391 } 28392 /****************************************************************************************************************/ 28393 28394 /* function : CompoundGlypg encode */ 28395 28396 /* comment : After creating a table for the characters you typed, you call directory.encode to encode the table.*/ 28397 28398 /****************************************************************************************************************/ 28399 28400 28401 CompoundGlyph.prototype.encode = function () { 28402 var i, result, _len, _ref; 28403 28404 result = new Data(__slice.call(this.raw.data)); 28405 _ref = this.glyphIDs; 28406 28407 for (i = 0, _len = _ref.length; i < _len; ++i) { 28408 result.pos = this.glyphOffsets[i]; 28409 } 28410 28411 return result.data; 28412 }; 28413 28414 return CompoundGlyph; 28415 }(); 28416 28417 var LocaTable = function (_super) { 28418 __extends(LocaTable, _super); 28419 28420 function LocaTable() { 28421 return LocaTable.__super__.constructor.apply(this, arguments); 28422 } 28423 28424 LocaTable.prototype.tag = "loca"; 28425 28426 LocaTable.prototype.parse = function (data) { 28427 var format, i; 28428 data.pos = this.offset; 28429 format = this.file.head.indexToLocFormat; 28430 28431 if (format === 0) { 28432 return this.offsets = function () { 28433 var _ref, _results; 28434 28435 _results = []; 28436 28437 for (i = 0, _ref = this.length; i < _ref; i += 2) { 28438 _results.push(data.readUInt16() * 2); 28439 } 28440 28441 return _results; 28442 }.call(this); 28443 } else { 28444 return this.offsets = function () { 28445 var _ref, _results; 28446 28447 _results = []; 28448 28449 for (i = 0, _ref = this.length; i < _ref; i += 4) { 28450 _results.push(data.readUInt32()); 28451 } 28452 28453 return _results; 28454 }.call(this); 28455 } 28456 }; 28457 28458 LocaTable.prototype.indexOf = function (id) { 28459 return this.offsets[id]; 28460 }; 28461 28462 LocaTable.prototype.lengthOf = function (id) { 28463 return this.offsets[id + 1] - this.offsets[id]; 28464 }; 28465 28466 LocaTable.prototype.encode = function (offsets, activeGlyphs) { 28467 var LocaTable = new Uint32Array(this.offsets.length); 28468 var glyfPtr = 0; 28469 var listGlyf = 0; 28470 28471 for (var k = 0; k < LocaTable.length; ++k) { 28472 LocaTable[k] = glyfPtr; 28473 28474 if (listGlyf < activeGlyphs.length && activeGlyphs[listGlyf] == k) { 28475 ++listGlyf; 28476 LocaTable[k] = glyfPtr; 28477 var start = this.offsets[k]; 28478 var len = this.offsets[k + 1] - start; 28479 28480 if (len > 0) { 28481 glyfPtr += len; 28482 } 28483 } 28484 } 28485 28486 var newLocaTable = new Array(LocaTable.length * 4); 28487 28488 for (var j = 0; j < LocaTable.length; ++j) { 28489 newLocaTable[4 * j + 3] = LocaTable[j] & 0x000000ff; 28490 newLocaTable[4 * j + 2] = (LocaTable[j] & 0x0000ff00) >> 8; 28491 newLocaTable[4 * j + 1] = (LocaTable[j] & 0x00ff0000) >> 16; 28492 newLocaTable[4 * j] = (LocaTable[j] & 0xff000000) >> 24; 28493 } 28494 28495 return newLocaTable; 28496 }; 28497 28498 return LocaTable; 28499 }(Table); 28500 /************************************************************************************/ 28501 28502 /* function : invert */ 28503 28504 /* comment : Change the object's (key: value) to create an object with (value: key).*/ 28505 28506 /************************************************************************************/ 28507 28508 28509 var invert = function invert(object) { 28510 var key, ret, val; 28511 ret = {}; 28512 28513 for (key in object) { 28514 val = object[key]; 28515 ret[val] = key; 28516 } 28517 28518 return ret; 28519 }; 28520 /*var successorOf = function (input) { 28521 var added, alphabet, carry, i, index, isUpperCase, last, length, next, result; 28522 alphabet = 'abcdefghijklmnopqrstuvwxyz'; 28523 length = alphabet.length; 28524 result = input; 28525 i = input.length; 28526 while (i >= 0) { 28527 last = input.charAt(--i); 28528 if (isNaN(last)) { 28529 index = alphabet.indexOf(last.toLowerCase()); 28530 if (index === -1) { 28531 next = last; 28532 carry = true; 28533 } 28534 else { 28535 next = alphabet.charAt((index + 1) % length); 28536 isUpperCase = last === last.toUpperCase(); 28537 if (isUpperCase) { 28538 next = next.toUpperCase(); 28539 } 28540 carry = index + 1 >= length; 28541 if (carry && i === 0) { 28542 added = isUpperCase ? 'A' : 'a'; 28543 result = added + next + result.slice(1); 28544 break; 28545 } 28546 } 28547 } 28548 else { 28549 next = +last + 1; 28550 carry = next > 9; 28551 if (carry) { 28552 next = 0; 28553 } 28554 if (carry && i === 0) { 28555 result = '1' + next + result.slice(1); 28556 break; 28557 } 28558 } 28559 result = result.slice(0, i) + next + result.slice(i + 1); 28560 if (!carry) { 28561 break; 28562 } 28563 } 28564 return result; 28565 };*/ 28566 28567 28568 var Subset = function () { 28569 function Subset(font) { 28570 this.font = font; 28571 this.subset = {}; 28572 this.unicodes = {}; 28573 this.next = 33; 28574 } 28575 /*Subset.prototype.use = function (character) { 28576 var i, _i, _ref; 28577 if (typeof character === 'string') { 28578 for (i = _i = 0, _ref = character.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { 28579 this.use(character.charCodeAt(i)); 28580 } 28581 return; 28582 } 28583 if (!this.unicodes[character]) { 28584 this.subset[this.next] = character; 28585 return this.unicodes[character] = this.next++; 28586 } 28587 };*/ 28588 28589 /*Subset.prototype.encodeText = function (text) { 28590 var char, i, string, _i, _ref; 28591 string = ''; 28592 for (i = _i = 0, _ref = text.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { 28593 char = this.unicodes[text.charCodeAt(i)]; 28594 string += String.fromCharCode(char); 28595 } 28596 return string; 28597 };*/ 28598 28599 /***************************************************************/ 28600 28601 /* function : generateCmap */ 28602 28603 /* comment : Returns the unicode cmap for this font. */ 28604 28605 /***************************************************************/ 28606 28607 28608 Subset.prototype.generateCmap = function () { 28609 var mapping, roman, unicode, unicodeCmap, _ref; 28610 28611 unicodeCmap = this.font.cmap.tables[0].codeMap; 28612 mapping = {}; 28613 _ref = this.subset; 28614 28615 for (roman in _ref) { 28616 unicode = _ref[roman]; 28617 mapping[roman] = unicodeCmap[unicode]; 28618 } 28619 28620 return mapping; 28621 }; 28622 /*Subset.prototype.glyphIDs = function () { 28623 var ret, roman, unicode, unicodeCmap, val, _ref; 28624 unicodeCmap = this.font.cmap.tables[0].codeMap; 28625 ret = [0]; 28626 _ref = this.subset; 28627 for (roman in _ref) { 28628 unicode = _ref[roman]; 28629 val = unicodeCmap[unicode]; 28630 if ((val != null) && __indexOf.call(ret, val) < 0) { 28631 ret.push(val); 28632 } 28633 } 28634 return ret.sort(); 28635 };*/ 28636 28637 /******************************************************************/ 28638 28639 /* function : glyphsFor */ 28640 28641 /* comment : Returns simple glyph objects for the input character.*/ 28642 28643 /******************************************************************/ 28644 28645 28646 Subset.prototype.glyphsFor = function (glyphIDs) { 28647 var additionalIDs, glyph, glyphs, id, _i, _len, _ref; 28648 28649 glyphs = {}; 28650 28651 for (_i = 0, _len = glyphIDs.length; _i < _len; _i++) { 28652 id = glyphIDs[_i]; 28653 glyphs[id] = this.font.glyf.glyphFor(id); 28654 } 28655 28656 additionalIDs = []; 28657 28658 for (id in glyphs) { 28659 glyph = glyphs[id]; 28660 28661 if (glyph != null ? glyph.compound : void 0) { 28662 additionalIDs.push.apply(additionalIDs, glyph.glyphIDs); 28663 } 28664 } 28665 28666 if (additionalIDs.length > 0) { 28667 _ref = this.glyphsFor(additionalIDs); 28668 28669 for (id in _ref) { 28670 glyph = _ref[id]; 28671 glyphs[id] = glyph; 28672 } 28673 } 28674 28675 return glyphs; 28676 }; 28677 /***************************************************************/ 28678 28679 /* function : encode */ 28680 28681 /* comment : Encode various tables for the characters you use. */ 28682 28683 /***************************************************************/ 28684 28685 28686 Subset.prototype.encode = function (glyID, indexToLocFormat) { 28687 var cmap, code, glyf, glyphs, id, ids, loca, new2old, newIDs, nextGlyphID, old2new, oldID, oldIDs, tables, _ref; 28688 28689 cmap = CmapTable.encode(this.generateCmap(), "unicode"); 28690 glyphs = this.glyphsFor(glyID); 28691 old2new = { 28692 0: 0 28693 }; 28694 _ref = cmap.charMap; 28695 28696 for (code in _ref) { 28697 ids = _ref[code]; 28698 old2new[ids.old] = ids["new"]; 28699 } 28700 28701 nextGlyphID = cmap.maxGlyphID; 28702 28703 for (oldID in glyphs) { 28704 if (!(oldID in old2new)) { 28705 old2new[oldID] = nextGlyphID++; 28706 } 28707 } 28708
vendor: 3,649 bytes, lines 28709-28833
28709 new2old = invert(old2new); 28710 newIDs = Object.keys(new2old).sort(function (a, b) { 28711 return a - b; 28712 }); 28713 28714 oldIDs = function () { 28715 var _i, _len, _results; 28716 28717 _results = []; 28718 28719 for (_i = 0, _len = newIDs.length; _i < _len; _i++) { 28720 id = newIDs[_i]; 28721 28722 _results.push(new2old[id]); 28723 } 28724 28725 return _results; 28726 }(); 28727 28728 glyf = this.font.glyf.encode(glyphs, oldIDs, old2new); 28729 loca = this.font.loca.encode(glyf.offsets, oldIDs); 28730 tables = { 28731 cmap: this.font.cmap.raw(), 28732 glyf: glyf.table, 28733 loca: loca, 28734 hmtx: this.font.hmtx.raw(), 28735 hhea: this.font.hhea.raw(), 28736 maxp: this.font.maxp.raw(), 28737 post: this.font.post.raw(), 28738 name: this.font.name.raw(), 28739 head: this.font.head.encode(indexToLocFormat) 28740 }; 28741 28742 if (this.font.os2.exists) { 28743 tables["OS/2"] = this.font.os2.raw(); 28744 } 28745 28746 return this.font.directory.encode(tables); 28747 }; 28748 28749 return Subset; 28750 }(); 28751 28752 jsPDF.API.PDFObject = function () { 28753 var pad; 28754 28755 function PDFObject() {} 28756 28757 pad = function pad(str, length) { 28758 return (Array(length + 1).join("0") + str).slice(-length); 28759 }; 28760 /*****************************************************************************/ 28761 28762 /* function : convert */ 28763 28764 /* comment :Converts pdf tag's / FontBBox and array values in / W to strings */ 28765 28766 /*****************************************************************************/ 28767 28768 28769 PDFObject.convert = function (object) { 28770 var e, items, key, out, val; 28771 28772 if (Array.isArray(object)) { 28773 items = function () { 28774 var _i, _len, _results; 28775 28776 _results = []; 28777 28778 for (_i = 0, _len = object.length; _i < _len; _i++) { 28779 e = object[_i]; 28780 28781 _results.push(PDFObject.convert(e)); 28782 } 28783 28784 return _results; 28785 }().join(" "); 28786 28787 return "[" + items + "]"; 28788 } else if (typeof object === "string") { 28789 return "/" + object; 28790 } else if (object != null ? object.isString : void 0) { 28791 return "(" + object + ")"; 28792 } else if (object instanceof Date) { 28793 return "(D:" + pad(object.getUTCFullYear(), 4) + pad(object.getUTCMonth(), 2) + pad(object.getUTCDate(), 2) + pad(object.getUTCHours(), 2) + pad(object.getUTCMinutes(), 2) + pad(object.getUTCSeconds(), 2) + "Z)"; 28794 } else if ({}.toString.call(object) === "[object Object]") { 28795 out = ["<<"]; 28796 28797 for (key in object) { 28798 val = object[key]; 28799 out.push("/" + key + " " + PDFObject.convert(val)); 28800 } 28801 28802 out.push(">>"); 28803 return out.join("\n"); 28804 } else { 28805 return "" + object; 28806 } 28807 }; 28808 28809 return PDFObject; 28810 }(); 28811 28812 exports.AcroForm = AcroForm; 28813 exports.AcroFormAppearance = AcroFormAppearance; 28814 exports.AcroFormButton = AcroFormButton; 28815 exports.AcroFormCheckBox = AcroFormCheckBox; 28816 exports.AcroFormChoiceField = AcroFormChoiceField; 28817 exports.AcroFormComboBox = AcroFormComboBox; 28818 exports.AcroFormEditBox = AcroFormEditBox; 28819 exports.AcroFormListBox = AcroFormListBox; 28820 exports.AcroFormPasswordField = AcroFormPasswordField; 28821 exports.AcroFormPushButton = AcroFormPushButton; 28822 exports.AcroFormRadioButton = AcroFormRadioButton; 28823 exports.AcroFormTextField = AcroFormTextField; 28824 exports.GState = GState; 28825 exports.ShadingPattern = ShadingPattern; 28826 exports.TilingPattern = TilingPattern; 28827 exports.default = jsPDF; 28828 exports.jsPDF = jsPDF; 28829 28830 Object.defineProperty(exports, '__esModule', { value: true }); 28831 28832}))); 28833//# sourceMappingURL=jspdf.umd.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.