1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/extensions/pdfjs/content/build/pdf.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,8069 @@ 1.4 +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 1.6 +/* Copyright 2012 Mozilla Foundation 1.7 + * 1.8 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.9 + * you may not use this file except in compliance with the License. 1.10 + * You may obtain a copy of the License at 1.11 + * 1.12 + * http://www.apache.org/licenses/LICENSE-2.0 1.13 + * 1.14 + * Unless required by applicable law or agreed to in writing, software 1.15 + * distributed under the License is distributed on an "AS IS" BASIS, 1.16 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.17 + * See the License for the specific language governing permissions and 1.18 + * limitations under the License. 1.19 + */ 1.20 +/*jshint globalstrict: false */ 1.21 + 1.22 +// Initializing PDFJS global object (if still undefined) 1.23 +if (typeof PDFJS === 'undefined') { 1.24 + (typeof window !== 'undefined' ? window : this).PDFJS = {}; 1.25 +} 1.26 + 1.27 +PDFJS.version = '1.0.68'; 1.28 +PDFJS.build = 'ead4cbf'; 1.29 + 1.30 +(function pdfjsWrapper() { 1.31 + // Use strict in our context only - users might not want it 1.32 + 'use strict'; 1.33 + 1.34 +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.35 +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 1.36 +/* Copyright 2012 Mozilla Foundation 1.37 + * 1.38 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.39 + * you may not use this file except in compliance with the License. 1.40 + * You may obtain a copy of the License at 1.41 + * 1.42 + * http://www.apache.org/licenses/LICENSE-2.0 1.43 + * 1.44 + * Unless required by applicable law or agreed to in writing, software 1.45 + * distributed under the License is distributed on an "AS IS" BASIS, 1.46 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.47 + * See the License for the specific language governing permissions and 1.48 + * limitations under the License. 1.49 + */ 1.50 +/* globals Cmd, ColorSpace, Dict, MozBlobBuilder, Name, PDFJS, Ref, URL, 1.51 + Promise */ 1.52 + 1.53 +'use strict'; 1.54 + 1.55 +var globalScope = (typeof window === 'undefined') ? this : window; 1.56 + 1.57 +var isWorker = (typeof window == 'undefined'); 1.58 + 1.59 +var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0]; 1.60 + 1.61 +var TextRenderingMode = { 1.62 + FILL: 0, 1.63 + STROKE: 1, 1.64 + FILL_STROKE: 2, 1.65 + INVISIBLE: 3, 1.66 + FILL_ADD_TO_PATH: 4, 1.67 + STROKE_ADD_TO_PATH: 5, 1.68 + FILL_STROKE_ADD_TO_PATH: 6, 1.69 + ADD_TO_PATH: 7, 1.70 + FILL_STROKE_MASK: 3, 1.71 + ADD_TO_PATH_FLAG: 4 1.72 +}; 1.73 + 1.74 +var ImageKind = { 1.75 + GRAYSCALE_1BPP: 1, 1.76 + RGB_24BPP: 2, 1.77 + RGBA_32BPP: 3 1.78 +}; 1.79 + 1.80 +// The global PDFJS object exposes the API 1.81 +// In production, it will be declared outside a global wrapper 1.82 +// In development, it will be declared here 1.83 +if (!globalScope.PDFJS) { 1.84 + globalScope.PDFJS = {}; 1.85 +} 1.86 + 1.87 +globalScope.PDFJS.pdfBug = false; 1.88 + 1.89 +PDFJS.VERBOSITY_LEVELS = { 1.90 + errors: 0, 1.91 + warnings: 1, 1.92 + infos: 5 1.93 +}; 1.94 + 1.95 +// All the possible operations for an operator list. 1.96 +var OPS = PDFJS.OPS = { 1.97 + // Intentionally start from 1 so it is easy to spot bad operators that will be 1.98 + // 0's. 1.99 + dependency: 1, 1.100 + setLineWidth: 2, 1.101 + setLineCap: 3, 1.102 + setLineJoin: 4, 1.103 + setMiterLimit: 5, 1.104 + setDash: 6, 1.105 + setRenderingIntent: 7, 1.106 + setFlatness: 8, 1.107 + setGState: 9, 1.108 + save: 10, 1.109 + restore: 11, 1.110 + transform: 12, 1.111 + moveTo: 13, 1.112 + lineTo: 14, 1.113 + curveTo: 15, 1.114 + curveTo2: 16, 1.115 + curveTo3: 17, 1.116 + closePath: 18, 1.117 + rectangle: 19, 1.118 + stroke: 20, 1.119 + closeStroke: 21, 1.120 + fill: 22, 1.121 + eoFill: 23, 1.122 + fillStroke: 24, 1.123 + eoFillStroke: 25, 1.124 + closeFillStroke: 26, 1.125 + closeEOFillStroke: 27, 1.126 + endPath: 28, 1.127 + clip: 29, 1.128 + eoClip: 30, 1.129 + beginText: 31, 1.130 + endText: 32, 1.131 + setCharSpacing: 33, 1.132 + setWordSpacing: 34, 1.133 + setHScale: 35, 1.134 + setLeading: 36, 1.135 + setFont: 37, 1.136 + setTextRenderingMode: 38, 1.137 + setTextRise: 39, 1.138 + moveText: 40, 1.139 + setLeadingMoveText: 41, 1.140 + setTextMatrix: 42, 1.141 + nextLine: 43, 1.142 + showText: 44, 1.143 + showSpacedText: 45, 1.144 + nextLineShowText: 46, 1.145 + nextLineSetSpacingShowText: 47, 1.146 + setCharWidth: 48, 1.147 + setCharWidthAndBounds: 49, 1.148 + setStrokeColorSpace: 50, 1.149 + setFillColorSpace: 51, 1.150 + setStrokeColor: 52, 1.151 + setStrokeColorN: 53, 1.152 + setFillColor: 54, 1.153 + setFillColorN: 55, 1.154 + setStrokeGray: 56, 1.155 + setFillGray: 57, 1.156 + setStrokeRGBColor: 58, 1.157 + setFillRGBColor: 59, 1.158 + setStrokeCMYKColor: 60, 1.159 + setFillCMYKColor: 61, 1.160 + shadingFill: 62, 1.161 + beginInlineImage: 63, 1.162 + beginImageData: 64, 1.163 + endInlineImage: 65, 1.164 + paintXObject: 66, 1.165 + markPoint: 67, 1.166 + markPointProps: 68, 1.167 + beginMarkedContent: 69, 1.168 + beginMarkedContentProps: 70, 1.169 + endMarkedContent: 71, 1.170 + beginCompat: 72, 1.171 + endCompat: 73, 1.172 + paintFormXObjectBegin: 74, 1.173 + paintFormXObjectEnd: 75, 1.174 + beginGroup: 76, 1.175 + endGroup: 77, 1.176 + beginAnnotations: 78, 1.177 + endAnnotations: 79, 1.178 + beginAnnotation: 80, 1.179 + endAnnotation: 81, 1.180 + paintJpegXObject: 82, 1.181 + paintImageMaskXObject: 83, 1.182 + paintImageMaskXObjectGroup: 84, 1.183 + paintImageXObject: 85, 1.184 + paintInlineImageXObject: 86, 1.185 + paintInlineImageXObjectGroup: 87, 1.186 + paintImageXObjectRepeat: 88, 1.187 + paintImageMaskXObjectRepeat: 89, 1.188 + paintSolidColorImageMask: 90 1.189 +}; 1.190 + 1.191 +// A notice for devs. These are good for things that are helpful to devs, such 1.192 +// as warning that Workers were disabled, which is important to devs but not 1.193 +// end users. 1.194 +function info(msg) { 1.195 + if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.infos) { 1.196 + console.log('Info: ' + msg); 1.197 + } 1.198 +} 1.199 + 1.200 +// Non-fatal warnings. 1.201 +function warn(msg) { 1.202 + if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.warnings) { 1.203 + console.log('Warning: ' + msg); 1.204 + } 1.205 +} 1.206 + 1.207 +// Fatal errors that should trigger the fallback UI and halt execution by 1.208 +// throwing an exception. 1.209 +function error(msg) { 1.210 + // If multiple arguments were passed, pass them all to the log function. 1.211 + if (arguments.length > 1) { 1.212 + var logArguments = ['Error:']; 1.213 + logArguments.push.apply(logArguments, arguments); 1.214 + console.log.apply(console, logArguments); 1.215 + // Join the arguments into a single string for the lines below. 1.216 + msg = [].join.call(arguments, ' '); 1.217 + } else { 1.218 + console.log('Error: ' + msg); 1.219 + } 1.220 + console.log(backtrace()); 1.221 + UnsupportedManager.notify(UNSUPPORTED_FEATURES.unknown); 1.222 + throw new Error(msg); 1.223 +} 1.224 + 1.225 +function backtrace() { 1.226 + try { 1.227 + throw new Error(); 1.228 + } catch (e) { 1.229 + return e.stack ? e.stack.split('\n').slice(2).join('\n') : ''; 1.230 + } 1.231 +} 1.232 + 1.233 +function assert(cond, msg) { 1.234 + if (!cond) { 1.235 + error(msg); 1.236 + } 1.237 +} 1.238 + 1.239 +var UNSUPPORTED_FEATURES = PDFJS.UNSUPPORTED_FEATURES = { 1.240 + unknown: 'unknown', 1.241 + forms: 'forms', 1.242 + javaScript: 'javaScript', 1.243 + smask: 'smask', 1.244 + shadingPattern: 'shadingPattern', 1.245 + font: 'font' 1.246 +}; 1.247 + 1.248 +var UnsupportedManager = PDFJS.UnsupportedManager = 1.249 + (function UnsupportedManagerClosure() { 1.250 + var listeners = []; 1.251 + return { 1.252 + listen: function (cb) { 1.253 + listeners.push(cb); 1.254 + }, 1.255 + notify: function (featureId) { 1.256 + warn('Unsupported feature "' + featureId + '"'); 1.257 + for (var i = 0, ii = listeners.length; i < ii; i++) { 1.258 + listeners[i](featureId); 1.259 + } 1.260 + } 1.261 + }; 1.262 +})(); 1.263 + 1.264 +// Combines two URLs. The baseUrl shall be absolute URL. If the url is an 1.265 +// absolute URL, it will be returned as is. 1.266 +function combineUrl(baseUrl, url) { 1.267 + if (!url) { 1.268 + return baseUrl; 1.269 + } 1.270 + if (/^[a-z][a-z0-9+\-.]*:/i.test(url)) { 1.271 + return url; 1.272 + } 1.273 + var i; 1.274 + if (url.charAt(0) == '/') { 1.275 + // absolute path 1.276 + i = baseUrl.indexOf('://'); 1.277 + if (url.charAt(1) === '/') { 1.278 + ++i; 1.279 + } else { 1.280 + i = baseUrl.indexOf('/', i + 3); 1.281 + } 1.282 + return baseUrl.substring(0, i) + url; 1.283 + } else { 1.284 + // relative path 1.285 + var pathLength = baseUrl.length; 1.286 + i = baseUrl.lastIndexOf('#'); 1.287 + pathLength = i >= 0 ? i : pathLength; 1.288 + i = baseUrl.lastIndexOf('?', pathLength); 1.289 + pathLength = i >= 0 ? i : pathLength; 1.290 + var prefixLength = baseUrl.lastIndexOf('/', pathLength); 1.291 + return baseUrl.substring(0, prefixLength + 1) + url; 1.292 + } 1.293 +} 1.294 + 1.295 +// Validates if URL is safe and allowed, e.g. to avoid XSS. 1.296 +function isValidUrl(url, allowRelative) { 1.297 + if (!url) { 1.298 + return false; 1.299 + } 1.300 + // RFC 3986 (http://tools.ietf.org/html/rfc3986#section-3.1) 1.301 + // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) 1.302 + var protocol = /^[a-z][a-z0-9+\-.]*(?=:)/i.exec(url); 1.303 + if (!protocol) { 1.304 + return allowRelative; 1.305 + } 1.306 + protocol = protocol[0].toLowerCase(); 1.307 + switch (protocol) { 1.308 + case 'http': 1.309 + case 'https': 1.310 + case 'ftp': 1.311 + case 'mailto': 1.312 + return true; 1.313 + default: 1.314 + return false; 1.315 + } 1.316 +} 1.317 +PDFJS.isValidUrl = isValidUrl; 1.318 + 1.319 +function shadow(obj, prop, value) { 1.320 + Object.defineProperty(obj, prop, { value: value, 1.321 + enumerable: true, 1.322 + configurable: true, 1.323 + writable: false }); 1.324 + return value; 1.325 +} 1.326 + 1.327 +var PasswordResponses = PDFJS.PasswordResponses = { 1.328 + NEED_PASSWORD: 1, 1.329 + INCORRECT_PASSWORD: 2 1.330 +}; 1.331 + 1.332 +var PasswordException = (function PasswordExceptionClosure() { 1.333 + function PasswordException(msg, code) { 1.334 + this.name = 'PasswordException'; 1.335 + this.message = msg; 1.336 + this.code = code; 1.337 + } 1.338 + 1.339 + PasswordException.prototype = new Error(); 1.340 + PasswordException.constructor = PasswordException; 1.341 + 1.342 + return PasswordException; 1.343 +})(); 1.344 + 1.345 +var UnknownErrorException = (function UnknownErrorExceptionClosure() { 1.346 + function UnknownErrorException(msg, details) { 1.347 + this.name = 'UnknownErrorException'; 1.348 + this.message = msg; 1.349 + this.details = details; 1.350 + } 1.351 + 1.352 + UnknownErrorException.prototype = new Error(); 1.353 + UnknownErrorException.constructor = UnknownErrorException; 1.354 + 1.355 + return UnknownErrorException; 1.356 +})(); 1.357 + 1.358 +var InvalidPDFException = (function InvalidPDFExceptionClosure() { 1.359 + function InvalidPDFException(msg) { 1.360 + this.name = 'InvalidPDFException'; 1.361 + this.message = msg; 1.362 + } 1.363 + 1.364 + InvalidPDFException.prototype = new Error(); 1.365 + InvalidPDFException.constructor = InvalidPDFException; 1.366 + 1.367 + return InvalidPDFException; 1.368 +})(); 1.369 + 1.370 +var MissingPDFException = (function MissingPDFExceptionClosure() { 1.371 + function MissingPDFException(msg) { 1.372 + this.name = 'MissingPDFException'; 1.373 + this.message = msg; 1.374 + } 1.375 + 1.376 + MissingPDFException.prototype = new Error(); 1.377 + MissingPDFException.constructor = MissingPDFException; 1.378 + 1.379 + return MissingPDFException; 1.380 +})(); 1.381 + 1.382 +var NotImplementedException = (function NotImplementedExceptionClosure() { 1.383 + function NotImplementedException(msg) { 1.384 + this.message = msg; 1.385 + } 1.386 + 1.387 + NotImplementedException.prototype = new Error(); 1.388 + NotImplementedException.prototype.name = 'NotImplementedException'; 1.389 + NotImplementedException.constructor = NotImplementedException; 1.390 + 1.391 + return NotImplementedException; 1.392 +})(); 1.393 + 1.394 +var MissingDataException = (function MissingDataExceptionClosure() { 1.395 + function MissingDataException(begin, end) { 1.396 + this.begin = begin; 1.397 + this.end = end; 1.398 + this.message = 'Missing data [' + begin + ', ' + end + ')'; 1.399 + } 1.400 + 1.401 + MissingDataException.prototype = new Error(); 1.402 + MissingDataException.prototype.name = 'MissingDataException'; 1.403 + MissingDataException.constructor = MissingDataException; 1.404 + 1.405 + return MissingDataException; 1.406 +})(); 1.407 + 1.408 +var XRefParseException = (function XRefParseExceptionClosure() { 1.409 + function XRefParseException(msg) { 1.410 + this.message = msg; 1.411 + } 1.412 + 1.413 + XRefParseException.prototype = new Error(); 1.414 + XRefParseException.prototype.name = 'XRefParseException'; 1.415 + XRefParseException.constructor = XRefParseException; 1.416 + 1.417 + return XRefParseException; 1.418 +})(); 1.419 + 1.420 + 1.421 +function bytesToString(bytes) { 1.422 + var length = bytes.length; 1.423 + var MAX_ARGUMENT_COUNT = 8192; 1.424 + if (length < MAX_ARGUMENT_COUNT) { 1.425 + return String.fromCharCode.apply(null, bytes); 1.426 + } 1.427 + var strBuf = []; 1.428 + for (var i = 0; i < length; i += MAX_ARGUMENT_COUNT) { 1.429 + var chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length); 1.430 + var chunk = bytes.subarray(i, chunkEnd); 1.431 + strBuf.push(String.fromCharCode.apply(null, chunk)); 1.432 + } 1.433 + return strBuf.join(''); 1.434 +} 1.435 + 1.436 +function stringToArray(str) { 1.437 + var length = str.length; 1.438 + var array = []; 1.439 + for (var i = 0; i < length; ++i) { 1.440 + array[i] = str.charCodeAt(i); 1.441 + } 1.442 + return array; 1.443 +} 1.444 + 1.445 +function stringToBytes(str) { 1.446 + var length = str.length; 1.447 + var bytes = new Uint8Array(length); 1.448 + for (var i = 0; i < length; ++i) { 1.449 + bytes[i] = str.charCodeAt(i) & 0xFF; 1.450 + } 1.451 + return bytes; 1.452 +} 1.453 + 1.454 +function string32(value) { 1.455 + return String.fromCharCode((value >> 24) & 0xff, (value >> 16) & 0xff, 1.456 + (value >> 8) & 0xff, value & 0xff); 1.457 +} 1.458 + 1.459 +function log2(x) { 1.460 + var n = 1, i = 0; 1.461 + while (x > n) { 1.462 + n <<= 1; 1.463 + i++; 1.464 + } 1.465 + return i; 1.466 +} 1.467 + 1.468 +function readInt8(data, start) { 1.469 + return (data[start] << 24) >> 24; 1.470 +} 1.471 + 1.472 +function readUint16(data, offset) { 1.473 + return (data[offset] << 8) | data[offset + 1]; 1.474 +} 1.475 + 1.476 +function readUint32(data, offset) { 1.477 + return ((data[offset] << 24) | (data[offset + 1] << 16) | 1.478 + (data[offset + 2] << 8) | data[offset + 3]) >>> 0; 1.479 +} 1.480 + 1.481 +// Lazy test the endianness of the platform 1.482 +// NOTE: This will be 'true' for simulated TypedArrays 1.483 +function isLittleEndian() { 1.484 + var buffer8 = new Uint8Array(2); 1.485 + buffer8[0] = 1; 1.486 + var buffer16 = new Uint16Array(buffer8.buffer); 1.487 + return (buffer16[0] === 1); 1.488 +} 1.489 + 1.490 +Object.defineProperty(PDFJS, 'isLittleEndian', { 1.491 + configurable: true, 1.492 + get: function PDFJS_isLittleEndian() { 1.493 + return shadow(PDFJS, 'isLittleEndian', isLittleEndian()); 1.494 + } 1.495 +}); 1.496 + 1.497 + PDFJS.hasCanvasTypedArrays = true; 1.498 + 1.499 +var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; 1.500 + 1.501 +var Util = PDFJS.Util = (function UtilClosure() { 1.502 + function Util() {} 1.503 + 1.504 + Util.makeCssRgb = function Util_makeCssRgb(rgb) { 1.505 + return 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')'; 1.506 + }; 1.507 + 1.508 + Util.makeCssCmyk = function Util_makeCssCmyk(cmyk) { 1.509 + var rgb = ColorSpace.singletons.cmyk.getRgb(cmyk, 0); 1.510 + return Util.makeCssRgb(rgb); 1.511 + }; 1.512 + 1.513 + // Concatenates two transformation matrices together and returns the result. 1.514 + Util.transform = function Util_transform(m1, m2) { 1.515 + return [ 1.516 + m1[0] * m2[0] + m1[2] * m2[1], 1.517 + m1[1] * m2[0] + m1[3] * m2[1], 1.518 + m1[0] * m2[2] + m1[2] * m2[3], 1.519 + m1[1] * m2[2] + m1[3] * m2[3], 1.520 + m1[0] * m2[4] + m1[2] * m2[5] + m1[4], 1.521 + m1[1] * m2[4] + m1[3] * m2[5] + m1[5] 1.522 + ]; 1.523 + }; 1.524 + 1.525 + // For 2d affine transforms 1.526 + Util.applyTransform = function Util_applyTransform(p, m) { 1.527 + var xt = p[0] * m[0] + p[1] * m[2] + m[4]; 1.528 + var yt = p[0] * m[1] + p[1] * m[3] + m[5]; 1.529 + return [xt, yt]; 1.530 + }; 1.531 + 1.532 + Util.applyInverseTransform = function Util_applyInverseTransform(p, m) { 1.533 + var d = m[0] * m[3] - m[1] * m[2]; 1.534 + var xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d; 1.535 + var yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d; 1.536 + return [xt, yt]; 1.537 + }; 1.538 + 1.539 + // Applies the transform to the rectangle and finds the minimum axially 1.540 + // aligned bounding box. 1.541 + Util.getAxialAlignedBoundingBox = 1.542 + function Util_getAxialAlignedBoundingBox(r, m) { 1.543 + 1.544 + var p1 = Util.applyTransform(r, m); 1.545 + var p2 = Util.applyTransform(r.slice(2, 4), m); 1.546 + var p3 = Util.applyTransform([r[0], r[3]], m); 1.547 + var p4 = Util.applyTransform([r[2], r[1]], m); 1.548 + return [ 1.549 + Math.min(p1[0], p2[0], p3[0], p4[0]), 1.550 + Math.min(p1[1], p2[1], p3[1], p4[1]), 1.551 + Math.max(p1[0], p2[0], p3[0], p4[0]), 1.552 + Math.max(p1[1], p2[1], p3[1], p4[1]) 1.553 + ]; 1.554 + }; 1.555 + 1.556 + Util.inverseTransform = function Util_inverseTransform(m) { 1.557 + var d = m[0] * m[3] - m[1] * m[2]; 1.558 + return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d, 1.559 + (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d]; 1.560 + }; 1.561 + 1.562 + // Apply a generic 3d matrix M on a 3-vector v: 1.563 + // | a b c | | X | 1.564 + // | d e f | x | Y | 1.565 + // | g h i | | Z | 1.566 + // M is assumed to be serialized as [a,b,c,d,e,f,g,h,i], 1.567 + // with v as [X,Y,Z] 1.568 + Util.apply3dTransform = function Util_apply3dTransform(m, v) { 1.569 + return [ 1.570 + m[0] * v[0] + m[1] * v[1] + m[2] * v[2], 1.571 + m[3] * v[0] + m[4] * v[1] + m[5] * v[2], 1.572 + m[6] * v[0] + m[7] * v[1] + m[8] * v[2] 1.573 + ]; 1.574 + }; 1.575 + 1.576 + // This calculation uses Singular Value Decomposition. 1.577 + // The SVD can be represented with formula A = USV. We are interested in the 1.578 + // matrix S here because it represents the scale values. 1.579 + Util.singularValueDecompose2dScale = 1.580 + function Util_singularValueDecompose2dScale(m) { 1.581 + 1.582 + var transpose = [m[0], m[2], m[1], m[3]]; 1.583 + 1.584 + // Multiply matrix m with its transpose. 1.585 + var a = m[0] * transpose[0] + m[1] * transpose[2]; 1.586 + var b = m[0] * transpose[1] + m[1] * transpose[3]; 1.587 + var c = m[2] * transpose[0] + m[3] * transpose[2]; 1.588 + var d = m[2] * transpose[1] + m[3] * transpose[3]; 1.589 + 1.590 + // Solve the second degree polynomial to get roots. 1.591 + var first = (a + d) / 2; 1.592 + var second = Math.sqrt((a + d) * (a + d) - 4 * (a * d - c * b)) / 2; 1.593 + var sx = first + second || 1; 1.594 + var sy = first - second || 1; 1.595 + 1.596 + // Scale values are the square roots of the eigenvalues. 1.597 + return [Math.sqrt(sx), Math.sqrt(sy)]; 1.598 + }; 1.599 + 1.600 + // Normalize rectangle rect=[x1, y1, x2, y2] so that (x1,y1) < (x2,y2) 1.601 + // For coordinate systems whose origin lies in the bottom-left, this 1.602 + // means normalization to (BL,TR) ordering. For systems with origin in the 1.603 + // top-left, this means (TL,BR) ordering. 1.604 + Util.normalizeRect = function Util_normalizeRect(rect) { 1.605 + var r = rect.slice(0); // clone rect 1.606 + if (rect[0] > rect[2]) { 1.607 + r[0] = rect[2]; 1.608 + r[2] = rect[0]; 1.609 + } 1.610 + if (rect[1] > rect[3]) { 1.611 + r[1] = rect[3]; 1.612 + r[3] = rect[1]; 1.613 + } 1.614 + return r; 1.615 + }; 1.616 + 1.617 + // Returns a rectangle [x1, y1, x2, y2] corresponding to the 1.618 + // intersection of rect1 and rect2. If no intersection, returns 'false' 1.619 + // The rectangle coordinates of rect1, rect2 should be [x1, y1, x2, y2] 1.620 + Util.intersect = function Util_intersect(rect1, rect2) { 1.621 + function compare(a, b) { 1.622 + return a - b; 1.623 + } 1.624 + 1.625 + // Order points along the axes 1.626 + var orderedX = [rect1[0], rect1[2], rect2[0], rect2[2]].sort(compare), 1.627 + orderedY = [rect1[1], rect1[3], rect2[1], rect2[3]].sort(compare), 1.628 + result = []; 1.629 + 1.630 + rect1 = Util.normalizeRect(rect1); 1.631 + rect2 = Util.normalizeRect(rect2); 1.632 + 1.633 + // X: first and second points belong to different rectangles? 1.634 + if ((orderedX[0] === rect1[0] && orderedX[1] === rect2[0]) || 1.635 + (orderedX[0] === rect2[0] && orderedX[1] === rect1[0])) { 1.636 + // Intersection must be between second and third points 1.637 + result[0] = orderedX[1]; 1.638 + result[2] = orderedX[2]; 1.639 + } else { 1.640 + return false; 1.641 + } 1.642 + 1.643 + // Y: first and second points belong to different rectangles? 1.644 + if ((orderedY[0] === rect1[1] && orderedY[1] === rect2[1]) || 1.645 + (orderedY[0] === rect2[1] && orderedY[1] === rect1[1])) { 1.646 + // Intersection must be between second and third points 1.647 + result[1] = orderedY[1]; 1.648 + result[3] = orderedY[2]; 1.649 + } else { 1.650 + return false; 1.651 + } 1.652 + 1.653 + return result; 1.654 + }; 1.655 + 1.656 + Util.sign = function Util_sign(num) { 1.657 + return num < 0 ? -1 : 1; 1.658 + }; 1.659 + 1.660 + // TODO(mack): Rename appendToArray 1.661 + Util.concatenateToArray = function concatenateToArray(arr1, arr2) { 1.662 + Array.prototype.push.apply(arr1, arr2); 1.663 + }; 1.664 + 1.665 + Util.prependToArray = function concatenateToArray(arr1, arr2) { 1.666 + Array.prototype.unshift.apply(arr1, arr2); 1.667 + }; 1.668 + 1.669 + Util.extendObj = function extendObj(obj1, obj2) { 1.670 + for (var key in obj2) { 1.671 + obj1[key] = obj2[key]; 1.672 + } 1.673 + }; 1.674 + 1.675 + Util.getInheritableProperty = function Util_getInheritableProperty(dict, 1.676 + name) { 1.677 + while (dict && !dict.has(name)) { 1.678 + dict = dict.get('Parent'); 1.679 + } 1.680 + if (!dict) { 1.681 + return null; 1.682 + } 1.683 + return dict.get(name); 1.684 + }; 1.685 + 1.686 + Util.inherit = function Util_inherit(sub, base, prototype) { 1.687 + sub.prototype = Object.create(base.prototype); 1.688 + sub.prototype.constructor = sub; 1.689 + for (var prop in prototype) { 1.690 + sub.prototype[prop] = prototype[prop]; 1.691 + } 1.692 + }; 1.693 + 1.694 + Util.loadScript = function Util_loadScript(src, callback) { 1.695 + var script = document.createElement('script'); 1.696 + var loaded = false; 1.697 + script.setAttribute('src', src); 1.698 + if (callback) { 1.699 + script.onload = function() { 1.700 + if (!loaded) { 1.701 + callback(); 1.702 + } 1.703 + loaded = true; 1.704 + }; 1.705 + } 1.706 + document.getElementsByTagName('head')[0].appendChild(script); 1.707 + }; 1.708 + 1.709 + return Util; 1.710 +})(); 1.711 + 1.712 +var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() { 1.713 + function PageViewport(viewBox, scale, rotation, offsetX, offsetY, dontFlip) { 1.714 + this.viewBox = viewBox; 1.715 + this.scale = scale; 1.716 + this.rotation = rotation; 1.717 + this.offsetX = offsetX; 1.718 + this.offsetY = offsetY; 1.719 + 1.720 + // creating transform to convert pdf coordinate system to the normal 1.721 + // canvas like coordinates taking in account scale and rotation 1.722 + var centerX = (viewBox[2] + viewBox[0]) / 2; 1.723 + var centerY = (viewBox[3] + viewBox[1]) / 2; 1.724 + var rotateA, rotateB, rotateC, rotateD; 1.725 + rotation = rotation % 360; 1.726 + rotation = rotation < 0 ? rotation + 360 : rotation; 1.727 + switch (rotation) { 1.728 + case 180: 1.729 + rotateA = -1; rotateB = 0; rotateC = 0; rotateD = 1; 1.730 + break; 1.731 + case 90: 1.732 + rotateA = 0; rotateB = 1; rotateC = 1; rotateD = 0; 1.733 + break; 1.734 + case 270: 1.735 + rotateA = 0; rotateB = -1; rotateC = -1; rotateD = 0; 1.736 + break; 1.737 + //case 0: 1.738 + default: 1.739 + rotateA = 1; rotateB = 0; rotateC = 0; rotateD = -1; 1.740 + break; 1.741 + } 1.742 + 1.743 + if (dontFlip) { 1.744 + rotateC = -rotateC; rotateD = -rotateD; 1.745 + } 1.746 + 1.747 + var offsetCanvasX, offsetCanvasY; 1.748 + var width, height; 1.749 + if (rotateA === 0) { 1.750 + offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX; 1.751 + offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY; 1.752 + width = Math.abs(viewBox[3] - viewBox[1]) * scale; 1.753 + height = Math.abs(viewBox[2] - viewBox[0]) * scale; 1.754 + } else { 1.755 + offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX; 1.756 + offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY; 1.757 + width = Math.abs(viewBox[2] - viewBox[0]) * scale; 1.758 + height = Math.abs(viewBox[3] - viewBox[1]) * scale; 1.759 + } 1.760 + // creating transform for the following operations: 1.761 + // translate(-centerX, -centerY), rotate and flip vertically, 1.762 + // scale, and translate(offsetCanvasX, offsetCanvasY) 1.763 + this.transform = [ 1.764 + rotateA * scale, 1.765 + rotateB * scale, 1.766 + rotateC * scale, 1.767 + rotateD * scale, 1.768 + offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, 1.769 + offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY 1.770 + ]; 1.771 + 1.772 + this.width = width; 1.773 + this.height = height; 1.774 + this.fontScale = scale; 1.775 + } 1.776 + PageViewport.prototype = { 1.777 + clone: function PageViewPort_clone(args) { 1.778 + args = args || {}; 1.779 + var scale = 'scale' in args ? args.scale : this.scale; 1.780 + var rotation = 'rotation' in args ? args.rotation : this.rotation; 1.781 + return new PageViewport(this.viewBox.slice(), scale, rotation, 1.782 + this.offsetX, this.offsetY, args.dontFlip); 1.783 + }, 1.784 + convertToViewportPoint: function PageViewport_convertToViewportPoint(x, y) { 1.785 + return Util.applyTransform([x, y], this.transform); 1.786 + }, 1.787 + convertToViewportRectangle: 1.788 + function PageViewport_convertToViewportRectangle(rect) { 1.789 + var tl = Util.applyTransform([rect[0], rect[1]], this.transform); 1.790 + var br = Util.applyTransform([rect[2], rect[3]], this.transform); 1.791 + return [tl[0], tl[1], br[0], br[1]]; 1.792 + }, 1.793 + convertToPdfPoint: function PageViewport_convertToPdfPoint(x, y) { 1.794 + return Util.applyInverseTransform([x, y], this.transform); 1.795 + } 1.796 + }; 1.797 + return PageViewport; 1.798 +})(); 1.799 + 1.800 +var PDFStringTranslateTable = [ 1.801 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.802 + 0x2D8, 0x2C7, 0x2C6, 0x2D9, 0x2DD, 0x2DB, 0x2DA, 0x2DC, 0, 0, 0, 0, 0, 0, 0, 1.803 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.804 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.805 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.806 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 1.807 + 0x2013, 0x192, 0x2044, 0x2039, 0x203A, 0x2212, 0x2030, 0x201E, 0x201C, 1.808 + 0x201D, 0x2018, 0x2019, 0x201A, 0x2122, 0xFB01, 0xFB02, 0x141, 0x152, 0x160, 1.809 + 0x178, 0x17D, 0x131, 0x142, 0x153, 0x161, 0x17E, 0, 0x20AC 1.810 +]; 1.811 + 1.812 +function stringToPDFString(str) { 1.813 + var i, n = str.length, strBuf = []; 1.814 + if (str[0] === '\xFE' && str[1] === '\xFF') { 1.815 + // UTF16BE BOM 1.816 + for (i = 2; i < n; i += 2) { 1.817 + strBuf.push(String.fromCharCode( 1.818 + (str.charCodeAt(i) << 8) | str.charCodeAt(i + 1))); 1.819 + } 1.820 + } else { 1.821 + for (i = 0; i < n; ++i) { 1.822 + var code = PDFStringTranslateTable[str.charCodeAt(i)]; 1.823 + strBuf.push(code ? String.fromCharCode(code) : str.charAt(i)); 1.824 + } 1.825 + } 1.826 + return strBuf.join(''); 1.827 +} 1.828 + 1.829 +function stringToUTF8String(str) { 1.830 + return decodeURIComponent(escape(str)); 1.831 +} 1.832 + 1.833 +function isEmptyObj(obj) { 1.834 + for (var key in obj) { 1.835 + return false; 1.836 + } 1.837 + return true; 1.838 +} 1.839 + 1.840 +function isBool(v) { 1.841 + return typeof v == 'boolean'; 1.842 +} 1.843 + 1.844 +function isInt(v) { 1.845 + return typeof v == 'number' && ((v | 0) == v); 1.846 +} 1.847 + 1.848 +function isNum(v) { 1.849 + return typeof v == 'number'; 1.850 +} 1.851 + 1.852 +function isString(v) { 1.853 + return typeof v == 'string'; 1.854 +} 1.855 + 1.856 +function isNull(v) { 1.857 + return v === null; 1.858 +} 1.859 + 1.860 +function isName(v) { 1.861 + return v instanceof Name; 1.862 +} 1.863 + 1.864 +function isCmd(v, cmd) { 1.865 + return v instanceof Cmd && (!cmd || v.cmd == cmd); 1.866 +} 1.867 + 1.868 +function isDict(v, type) { 1.869 + if (!(v instanceof Dict)) { 1.870 + return false; 1.871 + } 1.872 + if (!type) { 1.873 + return true; 1.874 + } 1.875 + var dictType = v.get('Type'); 1.876 + return isName(dictType) && dictType.name == type; 1.877 +} 1.878 + 1.879 +function isArray(v) { 1.880 + return v instanceof Array; 1.881 +} 1.882 + 1.883 +function isStream(v) { 1.884 + return typeof v == 'object' && v !== null && v !== undefined && 1.885 + ('getBytes' in v); 1.886 +} 1.887 + 1.888 +function isArrayBuffer(v) { 1.889 + return typeof v == 'object' && v !== null && v !== undefined && 1.890 + ('byteLength' in v); 1.891 +} 1.892 + 1.893 +function isRef(v) { 1.894 + return v instanceof Ref; 1.895 +} 1.896 + 1.897 +function isPDFFunction(v) { 1.898 + var fnDict; 1.899 + if (typeof v != 'object') { 1.900 + return false; 1.901 + } else if (isDict(v)) { 1.902 + fnDict = v; 1.903 + } else if (isStream(v)) { 1.904 + fnDict = v.dict; 1.905 + } else { 1.906 + return false; 1.907 + } 1.908 + return fnDict.has('FunctionType'); 1.909 +} 1.910 + 1.911 +/** 1.912 + * Legacy support for PDFJS Promise implementation. 1.913 + * TODO remove eventually 1.914 + * @ignore 1.915 + */ 1.916 +var LegacyPromise = PDFJS.LegacyPromise = (function LegacyPromiseClosure() { 1.917 + return function LegacyPromise() { 1.918 + var resolve, reject; 1.919 + var promise = new Promise(function (resolve_, reject_) { 1.920 + resolve = resolve_; 1.921 + reject = reject_; 1.922 + }); 1.923 + promise.resolve = resolve; 1.924 + promise.reject = reject; 1.925 + return promise; 1.926 + }; 1.927 +})(); 1.928 + 1.929 +/** 1.930 + * Polyfill for Promises: 1.931 + * The following promise implementation tries to generally implment the 1.932 + * Promise/A+ spec. Some notable differences from other promise libaries are: 1.933 + * - There currently isn't a seperate deferred and promise object. 1.934 + * - Unhandled rejections eventually show an error if they aren't handled. 1.935 + * 1.936 + * Based off of the work in: 1.937 + * https://bugzilla.mozilla.org/show_bug.cgi?id=810490 1.938 + */ 1.939 +(function PromiseClosure() { 1.940 + if (globalScope.Promise) { 1.941 + // Promises existing in the DOM/Worker, checking presence of all/resolve 1.942 + if (typeof globalScope.Promise.all !== 'function') { 1.943 + globalScope.Promise.all = function (iterable) { 1.944 + var count = 0, results = [], resolve, reject; 1.945 + var promise = new globalScope.Promise(function (resolve_, reject_) { 1.946 + resolve = resolve_; 1.947 + reject = reject_; 1.948 + }); 1.949 + iterable.forEach(function (p, i) { 1.950 + count++; 1.951 + p.then(function (result) { 1.952 + results[i] = result; 1.953 + count--; 1.954 + if (count === 0) { 1.955 + resolve(results); 1.956 + } 1.957 + }, reject); 1.958 + }); 1.959 + if (count === 0) { 1.960 + resolve(results); 1.961 + } 1.962 + return promise; 1.963 + }; 1.964 + } 1.965 + if (typeof globalScope.Promise.resolve !== 'function') { 1.966 + globalScope.Promise.resolve = function (x) { 1.967 + return new globalScope.Promise(function (resolve) { resolve(x); }); 1.968 + }; 1.969 + } 1.970 + return; 1.971 + } 1.972 + throw new Error('DOM Promise is not present'); 1.973 +})(); 1.974 + 1.975 +var StatTimer = (function StatTimerClosure() { 1.976 + function rpad(str, pad, length) { 1.977 + while (str.length < length) { 1.978 + str += pad; 1.979 + } 1.980 + return str; 1.981 + } 1.982 + function StatTimer() { 1.983 + this.started = {}; 1.984 + this.times = []; 1.985 + this.enabled = true; 1.986 + } 1.987 + StatTimer.prototype = { 1.988 + time: function StatTimer_time(name) { 1.989 + if (!this.enabled) { 1.990 + return; 1.991 + } 1.992 + if (name in this.started) { 1.993 + warn('Timer is already running for ' + name); 1.994 + } 1.995 + this.started[name] = Date.now(); 1.996 + }, 1.997 + timeEnd: function StatTimer_timeEnd(name) { 1.998 + if (!this.enabled) { 1.999 + return; 1.1000 + } 1.1001 + if (!(name in this.started)) { 1.1002 + warn('Timer has not been started for ' + name); 1.1003 + } 1.1004 + this.times.push({ 1.1005 + 'name': name, 1.1006 + 'start': this.started[name], 1.1007 + 'end': Date.now() 1.1008 + }); 1.1009 + // Remove timer from started so it can be called again. 1.1010 + delete this.started[name]; 1.1011 + }, 1.1012 + toString: function StatTimer_toString() { 1.1013 + var i, ii; 1.1014 + var times = this.times; 1.1015 + var out = ''; 1.1016 + // Find the longest name for padding purposes. 1.1017 + var longest = 0; 1.1018 + for (i = 0, ii = times.length; i < ii; ++i) { 1.1019 + var name = times[i]['name']; 1.1020 + if (name.length > longest) { 1.1021 + longest = name.length; 1.1022 + } 1.1023 + } 1.1024 + for (i = 0, ii = times.length; i < ii; ++i) { 1.1025 + var span = times[i]; 1.1026 + var duration = span.end - span.start; 1.1027 + out += rpad(span['name'], ' ', longest) + ' ' + duration + 'ms\n'; 1.1028 + } 1.1029 + return out; 1.1030 + } 1.1031 + }; 1.1032 + return StatTimer; 1.1033 +})(); 1.1034 + 1.1035 +PDFJS.createBlob = function createBlob(data, contentType) { 1.1036 + if (typeof Blob !== 'undefined') { 1.1037 + return new Blob([data], { type: contentType }); 1.1038 + } 1.1039 + // Blob builder is deprecated in FF14 and removed in FF18. 1.1040 + var bb = new MozBlobBuilder(); 1.1041 + bb.append(data); 1.1042 + return bb.getBlob(contentType); 1.1043 +}; 1.1044 + 1.1045 +PDFJS.createObjectURL = (function createObjectURLClosure() { 1.1046 + // Blob/createObjectURL is not available, falling back to data schema. 1.1047 + var digits = 1.1048 + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 1.1049 + 1.1050 + return function createObjectURL(data, contentType) { 1.1051 + if (!PDFJS.disableCreateObjectURL && 1.1052 + typeof URL !== 'undefined' && URL.createObjectURL) { 1.1053 + var blob = PDFJS.createBlob(data, contentType); 1.1054 + return URL.createObjectURL(blob); 1.1055 + } 1.1056 + 1.1057 + var buffer = 'data:' + contentType + ';base64,'; 1.1058 + for (var i = 0, ii = data.length; i < ii; i += 3) { 1.1059 + var b1 = data[i] & 0xFF; 1.1060 + var b2 = data[i + 1] & 0xFF; 1.1061 + var b3 = data[i + 2] & 0xFF; 1.1062 + var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4); 1.1063 + var d3 = i + 1 < ii ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64; 1.1064 + var d4 = i + 2 < ii ? (b3 & 0x3F) : 64; 1.1065 + buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4]; 1.1066 + } 1.1067 + return buffer; 1.1068 + }; 1.1069 +})(); 1.1070 + 1.1071 +function MessageHandler(name, comObj) { 1.1072 + this.name = name; 1.1073 + this.comObj = comObj; 1.1074 + this.callbackIndex = 1; 1.1075 + this.postMessageTransfers = true; 1.1076 + var callbacks = this.callbacks = {}; 1.1077 + var ah = this.actionHandler = {}; 1.1078 + 1.1079 + ah['console_log'] = [function ahConsoleLog(data) { 1.1080 + console.log.apply(console, data); 1.1081 + }]; 1.1082 + ah['console_error'] = [function ahConsoleError(data) { 1.1083 + console.error.apply(console, data); 1.1084 + }]; 1.1085 + ah['_unsupported_feature'] = [function ah_unsupportedFeature(data) { 1.1086 + UnsupportedManager.notify(data); 1.1087 + }]; 1.1088 + 1.1089 + comObj.onmessage = function messageHandlerComObjOnMessage(event) { 1.1090 + var data = event.data; 1.1091 + if (data.isReply) { 1.1092 + var callbackId = data.callbackId; 1.1093 + if (data.callbackId in callbacks) { 1.1094 + var callback = callbacks[callbackId]; 1.1095 + delete callbacks[callbackId]; 1.1096 + callback(data.data); 1.1097 + } else { 1.1098 + error('Cannot resolve callback ' + callbackId); 1.1099 + } 1.1100 + } else if (data.action in ah) { 1.1101 + var action = ah[data.action]; 1.1102 + if (data.callbackId) { 1.1103 + var deferred = {}; 1.1104 + var promise = new Promise(function (resolve, reject) { 1.1105 + deferred.resolve = resolve; 1.1106 + deferred.reject = reject; 1.1107 + }); 1.1108 + deferred.promise = promise; 1.1109 + promise.then(function(resolvedData) { 1.1110 + comObj.postMessage({ 1.1111 + isReply: true, 1.1112 + callbackId: data.callbackId, 1.1113 + data: resolvedData 1.1114 + }); 1.1115 + }); 1.1116 + action[0].call(action[1], data.data, deferred); 1.1117 + } else { 1.1118 + action[0].call(action[1], data.data); 1.1119 + } 1.1120 + } else { 1.1121 + error('Unkown action from worker: ' + data.action); 1.1122 + } 1.1123 + }; 1.1124 +} 1.1125 + 1.1126 +MessageHandler.prototype = { 1.1127 + on: function messageHandlerOn(actionName, handler, scope) { 1.1128 + var ah = this.actionHandler; 1.1129 + if (ah[actionName]) { 1.1130 + error('There is already an actionName called "' + actionName + '"'); 1.1131 + } 1.1132 + ah[actionName] = [handler, scope]; 1.1133 + }, 1.1134 + /** 1.1135 + * Sends a message to the comObj to invoke the action with the supplied data. 1.1136 + * @param {String} actionName Action to call. 1.1137 + * @param {JSON} data JSON data to send. 1.1138 + * @param {function} [callback] Optional callback that will handle a reply. 1.1139 + * @param {Array} [transfers] Optional list of transfers/ArrayBuffers 1.1140 + */ 1.1141 + send: function messageHandlerSend(actionName, data, callback, transfers) { 1.1142 + var message = { 1.1143 + action: actionName, 1.1144 + data: data 1.1145 + }; 1.1146 + if (callback) { 1.1147 + var callbackId = this.callbackIndex++; 1.1148 + this.callbacks[callbackId] = callback; 1.1149 + message.callbackId = callbackId; 1.1150 + } 1.1151 + if (transfers && this.postMessageTransfers) { 1.1152 + this.comObj.postMessage(message, transfers); 1.1153 + } else { 1.1154 + this.comObj.postMessage(message); 1.1155 + } 1.1156 + } 1.1157 +}; 1.1158 + 1.1159 +function loadJpegStream(id, imageUrl, objs) { 1.1160 + var img = new Image(); 1.1161 + img.onload = (function loadJpegStream_onloadClosure() { 1.1162 + objs.resolve(id, img); 1.1163 + }); 1.1164 + img.src = imageUrl; 1.1165 +} 1.1166 + 1.1167 + 1.1168 +var ColorSpace = (function ColorSpaceClosure() { 1.1169 + // Constructor should define this.numComps, this.defaultColor, this.name 1.1170 + function ColorSpace() { 1.1171 + error('should not call ColorSpace constructor'); 1.1172 + } 1.1173 + 1.1174 + ColorSpace.prototype = { 1.1175 + /** 1.1176 + * Converts the color value to the RGB color. The color components are 1.1177 + * located in the src array starting from the srcOffset. Returns the array 1.1178 + * of the rgb components, each value ranging from [0,255]. 1.1179 + */ 1.1180 + getRgb: function ColorSpace_getRgb(src, srcOffset) { 1.1181 + var rgb = new Uint8Array(3); 1.1182 + this.getRgbItem(src, srcOffset, rgb, 0); 1.1183 + return rgb; 1.1184 + }, 1.1185 + /** 1.1186 + * Converts the color value to the RGB color, similar to the getRgb method. 1.1187 + * The result placed into the dest array starting from the destOffset. 1.1188 + */ 1.1189 + getRgbItem: function ColorSpace_getRgbItem(src, srcOffset, 1.1190 + dest, destOffset) { 1.1191 + error('Should not call ColorSpace.getRgbItem'); 1.1192 + }, 1.1193 + /** 1.1194 + * Converts the specified number of the color values to the RGB colors. 1.1195 + * The colors are located in the src array starting from the srcOffset. 1.1196 + * The result is placed into the dest array starting from the destOffset. 1.1197 + * The src array items shall be in [0,2^bits) range, the dest array items 1.1198 + * will be in [0,255] range. alpha01 indicates how many alpha components 1.1199 + * there are in the dest array; it will be either 0 (RGB array) or 1 (RGBA 1.1200 + * array). 1.1201 + */ 1.1202 + getRgbBuffer: function ColorSpace_getRgbBuffer(src, srcOffset, count, 1.1203 + dest, destOffset, bits, 1.1204 + alpha01) { 1.1205 + error('Should not call ColorSpace.getRgbBuffer'); 1.1206 + }, 1.1207 + /** 1.1208 + * Determines the number of bytes required to store the result of the 1.1209 + * conversion done by the getRgbBuffer method. As in getRgbBuffer, 1.1210 + * |alpha01| is either 0 (RGB output) or 1 (RGBA output). 1.1211 + */ 1.1212 + getOutputLength: function ColorSpace_getOutputLength(inputLength, 1.1213 + alpha01) { 1.1214 + error('Should not call ColorSpace.getOutputLength'); 1.1215 + }, 1.1216 + /** 1.1217 + * Returns true if source data will be equal the result/output data. 1.1218 + */ 1.1219 + isPassthrough: function ColorSpace_isPassthrough(bits) { 1.1220 + return false; 1.1221 + }, 1.1222 + /** 1.1223 + * Fills in the RGB colors in the destination buffer. alpha01 indicates 1.1224 + * how many alpha components there are in the dest array; it will be either 1.1225 + * 0 (RGB array) or 1 (RGBA array). 1.1226 + */ 1.1227 + fillRgb: function ColorSpace_fillRgb(dest, originalWidth, 1.1228 + originalHeight, width, height, 1.1229 + actualHeight, bpc, comps, alpha01) { 1.1230 + var count = originalWidth * originalHeight; 1.1231 + var rgbBuf = null; 1.1232 + var numComponentColors = 1 << bpc; 1.1233 + var needsResizing = originalHeight != height || originalWidth != width; 1.1234 + var i, ii; 1.1235 + 1.1236 + if (this.isPassthrough(bpc)) { 1.1237 + rgbBuf = comps; 1.1238 + } else if (this.numComps === 1 && count > numComponentColors && 1.1239 + this.name !== 'DeviceGray' && this.name !== 'DeviceRGB') { 1.1240 + // Optimization: create a color map when there is just one component and 1.1241 + // we are converting more colors than the size of the color map. We 1.1242 + // don't build the map if the colorspace is gray or rgb since those 1.1243 + // methods are faster than building a map. This mainly offers big speed 1.1244 + // ups for indexed and alternate colorspaces. 1.1245 + // 1.1246 + // TODO it may be worth while to cache the color map. While running 1.1247 + // testing I never hit a cache so I will leave that out for now (perhaps 1.1248 + // we are reparsing colorspaces too much?). 1.1249 + var allColors = bpc <= 8 ? new Uint8Array(numComponentColors) : 1.1250 + new Uint16Array(numComponentColors); 1.1251 + var key; 1.1252 + for (i = 0; i < numComponentColors; i++) { 1.1253 + allColors[i] = i; 1.1254 + } 1.1255 + var colorMap = new Uint8Array(numComponentColors * 3); 1.1256 + this.getRgbBuffer(allColors, 0, numComponentColors, colorMap, 0, bpc, 1.1257 + /* alpha01 = */ 0); 1.1258 + 1.1259 + var destPos, rgbPos; 1.1260 + if (!needsResizing) { 1.1261 + // Fill in the RGB values directly into |dest|. 1.1262 + destPos = 0; 1.1263 + for (i = 0; i < count; ++i) { 1.1264 + key = comps[i] * 3; 1.1265 + dest[destPos++] = colorMap[key]; 1.1266 + dest[destPos++] = colorMap[key + 1]; 1.1267 + dest[destPos++] = colorMap[key + 2]; 1.1268 + destPos += alpha01; 1.1269 + } 1.1270 + } else { 1.1271 + rgbBuf = new Uint8Array(count * 3); 1.1272 + rgbPos = 0; 1.1273 + for (i = 0; i < count; ++i) { 1.1274 + key = comps[i] * 3; 1.1275 + rgbBuf[rgbPos++] = colorMap[key]; 1.1276 + rgbBuf[rgbPos++] = colorMap[key + 1]; 1.1277 + rgbBuf[rgbPos++] = colorMap[key + 2]; 1.1278 + } 1.1279 + } 1.1280 + } else { 1.1281 + if (!needsResizing) { 1.1282 + // Fill in the RGB values directly into |dest|. 1.1283 + this.getRgbBuffer(comps, 0, width * actualHeight, dest, 0, bpc, 1.1284 + alpha01); 1.1285 + } else { 1.1286 + rgbBuf = new Uint8Array(count * 3); 1.1287 + this.getRgbBuffer(comps, 0, count, rgbBuf, 0, bpc, 1.1288 + /* alpha01 = */ 0); 1.1289 + } 1.1290 + } 1.1291 + 1.1292 + if (rgbBuf) { 1.1293 + if (needsResizing) { 1.1294 + rgbBuf = PDFImage.resize(rgbBuf, bpc, 3, originalWidth, 1.1295 + originalHeight, width, height); 1.1296 + } 1.1297 + rgbPos = 0; 1.1298 + destPos = 0; 1.1299 + for (i = 0, ii = width * actualHeight; i < ii; i++) { 1.1300 + dest[destPos++] = rgbBuf[rgbPos++]; 1.1301 + dest[destPos++] = rgbBuf[rgbPos++]; 1.1302 + dest[destPos++] = rgbBuf[rgbPos++]; 1.1303 + destPos += alpha01; 1.1304 + } 1.1305 + } 1.1306 + }, 1.1307 + /** 1.1308 + * True if the colorspace has components in the default range of [0, 1]. 1.1309 + * This should be true for all colorspaces except for lab color spaces 1.1310 + * which are [0,100], [-128, 127], [-128, 127]. 1.1311 + */ 1.1312 + usesZeroToOneRange: true 1.1313 + }; 1.1314 + 1.1315 + ColorSpace.parse = function ColorSpace_parse(cs, xref, res) { 1.1316 + var IR = ColorSpace.parseToIR(cs, xref, res); 1.1317 + if (IR instanceof AlternateCS) { 1.1318 + return IR; 1.1319 + } 1.1320 + return ColorSpace.fromIR(IR); 1.1321 + }; 1.1322 + 1.1323 + ColorSpace.fromIR = function ColorSpace_fromIR(IR) { 1.1324 + var name = isArray(IR) ? IR[0] : IR; 1.1325 + var whitePoint, blackPoint; 1.1326 + 1.1327 + switch (name) { 1.1328 + case 'DeviceGrayCS': 1.1329 + return this.singletons.gray; 1.1330 + case 'DeviceRgbCS': 1.1331 + return this.singletons.rgb; 1.1332 + case 'DeviceCmykCS': 1.1333 + return this.singletons.cmyk; 1.1334 + case 'CalGrayCS': 1.1335 + whitePoint = IR[1].WhitePoint; 1.1336 + blackPoint = IR[1].BlackPoint; 1.1337 + var gamma = IR[1].Gamma; 1.1338 + return new CalGrayCS(whitePoint, blackPoint, gamma); 1.1339 + case 'PatternCS': 1.1340 + var basePatternCS = IR[1]; 1.1341 + if (basePatternCS) { 1.1342 + basePatternCS = ColorSpace.fromIR(basePatternCS); 1.1343 + } 1.1344 + return new PatternCS(basePatternCS); 1.1345 + case 'IndexedCS': 1.1346 + var baseIndexedCS = IR[1]; 1.1347 + var hiVal = IR[2]; 1.1348 + var lookup = IR[3]; 1.1349 + return new IndexedCS(ColorSpace.fromIR(baseIndexedCS), hiVal, lookup); 1.1350 + case 'AlternateCS': 1.1351 + var numComps = IR[1]; 1.1352 + var alt = IR[2]; 1.1353 + var tintFnIR = IR[3]; 1.1354 + 1.1355 + return new AlternateCS(numComps, ColorSpace.fromIR(alt), 1.1356 + PDFFunction.fromIR(tintFnIR)); 1.1357 + case 'LabCS': 1.1358 + whitePoint = IR[1].WhitePoint; 1.1359 + blackPoint = IR[1].BlackPoint; 1.1360 + var range = IR[1].Range; 1.1361 + return new LabCS(whitePoint, blackPoint, range); 1.1362 + default: 1.1363 + error('Unkown name ' + name); 1.1364 + } 1.1365 + return null; 1.1366 + }; 1.1367 + 1.1368 + ColorSpace.parseToIR = function ColorSpace_parseToIR(cs, xref, res) { 1.1369 + if (isName(cs)) { 1.1370 + var colorSpaces = res.get('ColorSpace'); 1.1371 + if (isDict(colorSpaces)) { 1.1372 + var refcs = colorSpaces.get(cs.name); 1.1373 + if (refcs) { 1.1374 + cs = refcs; 1.1375 + } 1.1376 + } 1.1377 + } 1.1378 + 1.1379 + cs = xref.fetchIfRef(cs); 1.1380 + var mode; 1.1381 + 1.1382 + if (isName(cs)) { 1.1383 + mode = cs.name; 1.1384 + this.mode = mode; 1.1385 + 1.1386 + switch (mode) { 1.1387 + case 'DeviceGray': 1.1388 + case 'G': 1.1389 + return 'DeviceGrayCS'; 1.1390 + case 'DeviceRGB': 1.1391 + case 'RGB': 1.1392 + return 'DeviceRgbCS'; 1.1393 + case 'DeviceCMYK': 1.1394 + case 'CMYK': 1.1395 + return 'DeviceCmykCS'; 1.1396 + case 'Pattern': 1.1397 + return ['PatternCS', null]; 1.1398 + default: 1.1399 + error('unrecognized colorspace ' + mode); 1.1400 + } 1.1401 + } else if (isArray(cs)) { 1.1402 + mode = cs[0].name; 1.1403 + this.mode = mode; 1.1404 + var numComps, params; 1.1405 + 1.1406 + switch (mode) { 1.1407 + case 'DeviceGray': 1.1408 + case 'G': 1.1409 + return 'DeviceGrayCS'; 1.1410 + case 'DeviceRGB': 1.1411 + case 'RGB': 1.1412 + return 'DeviceRgbCS'; 1.1413 + case 'DeviceCMYK': 1.1414 + case 'CMYK': 1.1415 + return 'DeviceCmykCS'; 1.1416 + case 'CalGray': 1.1417 + params = cs[1].getAll(); 1.1418 + return ['CalGrayCS', params]; 1.1419 + case 'CalRGB': 1.1420 + return 'DeviceRgbCS'; 1.1421 + case 'ICCBased': 1.1422 + var stream = xref.fetchIfRef(cs[1]); 1.1423 + var dict = stream.dict; 1.1424 + numComps = dict.get('N'); 1.1425 + if (numComps == 1) { 1.1426 + return 'DeviceGrayCS'; 1.1427 + } else if (numComps == 3) { 1.1428 + return 'DeviceRgbCS'; 1.1429 + } else if (numComps == 4) { 1.1430 + return 'DeviceCmykCS'; 1.1431 + } 1.1432 + break; 1.1433 + case 'Pattern': 1.1434 + var basePatternCS = cs[1]; 1.1435 + if (basePatternCS) { 1.1436 + basePatternCS = ColorSpace.parseToIR(basePatternCS, xref, res); 1.1437 + } 1.1438 + return ['PatternCS', basePatternCS]; 1.1439 + case 'Indexed': 1.1440 + case 'I': 1.1441 + var baseIndexedCS = ColorSpace.parseToIR(cs[1], xref, res); 1.1442 + var hiVal = cs[2] + 1; 1.1443 + var lookup = xref.fetchIfRef(cs[3]); 1.1444 + if (isStream(lookup)) { 1.1445 + lookup = lookup.getBytes(); 1.1446 + } 1.1447 + return ['IndexedCS', baseIndexedCS, hiVal, lookup]; 1.1448 + case 'Separation': 1.1449 + case 'DeviceN': 1.1450 + var name = cs[1]; 1.1451 + numComps = 1; 1.1452 + if (isName(name)) { 1.1453 + numComps = 1; 1.1454 + } else if (isArray(name)) { 1.1455 + numComps = name.length; 1.1456 + } 1.1457 + var alt = ColorSpace.parseToIR(cs[2], xref, res); 1.1458 + var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3])); 1.1459 + return ['AlternateCS', numComps, alt, tintFnIR]; 1.1460 + case 'Lab': 1.1461 + params = cs[1].getAll(); 1.1462 + return ['LabCS', params]; 1.1463 + default: 1.1464 + error('unimplemented color space object "' + mode + '"'); 1.1465 + } 1.1466 + } else { 1.1467 + error('unrecognized color space object: "' + cs + '"'); 1.1468 + } 1.1469 + return null; 1.1470 + }; 1.1471 + /** 1.1472 + * Checks if a decode map matches the default decode map for a color space. 1.1473 + * This handles the general decode maps where there are two values per 1.1474 + * component. e.g. [0, 1, 0, 1, 0, 1] for a RGB color. 1.1475 + * This does not handle Lab, Indexed, or Pattern decode maps since they are 1.1476 + * slightly different. 1.1477 + * @param {Array} decode Decode map (usually from an image). 1.1478 + * @param {Number} n Number of components the color space has. 1.1479 + */ 1.1480 + ColorSpace.isDefaultDecode = function ColorSpace_isDefaultDecode(decode, n) { 1.1481 + if (!decode) { 1.1482 + return true; 1.1483 + } 1.1484 + 1.1485 + if (n * 2 !== decode.length) { 1.1486 + warn('The decode map is not the correct length'); 1.1487 + return true; 1.1488 + } 1.1489 + for (var i = 0, ii = decode.length; i < ii; i += 2) { 1.1490 + if (decode[i] !== 0 || decode[i + 1] != 1) { 1.1491 + return false; 1.1492 + } 1.1493 + } 1.1494 + return true; 1.1495 + }; 1.1496 + 1.1497 + ColorSpace.singletons = { 1.1498 + get gray() { 1.1499 + return shadow(this, 'gray', new DeviceGrayCS()); 1.1500 + }, 1.1501 + get rgb() { 1.1502 + return shadow(this, 'rgb', new DeviceRgbCS()); 1.1503 + }, 1.1504 + get cmyk() { 1.1505 + return shadow(this, 'cmyk', new DeviceCmykCS()); 1.1506 + } 1.1507 + }; 1.1508 + 1.1509 + return ColorSpace; 1.1510 +})(); 1.1511 + 1.1512 +/** 1.1513 + * Alternate color space handles both Separation and DeviceN color spaces. A 1.1514 + * Separation color space is actually just a DeviceN with one color component. 1.1515 + * Both color spaces use a tinting function to convert colors to a base color 1.1516 + * space. 1.1517 + */ 1.1518 +var AlternateCS = (function AlternateCSClosure() { 1.1519 + function AlternateCS(numComps, base, tintFn) { 1.1520 + this.name = 'Alternate'; 1.1521 + this.numComps = numComps; 1.1522 + this.defaultColor = new Float32Array(numComps); 1.1523 + for (var i = 0; i < numComps; ++i) { 1.1524 + this.defaultColor[i] = 1; 1.1525 + } 1.1526 + this.base = base; 1.1527 + this.tintFn = tintFn; 1.1528 + } 1.1529 + 1.1530 + AlternateCS.prototype = { 1.1531 + getRgb: ColorSpace.prototype.getRgb, 1.1532 + getRgbItem: function AlternateCS_getRgbItem(src, srcOffset, 1.1533 + dest, destOffset) { 1.1534 + var baseNumComps = this.base.numComps; 1.1535 + var input = 'subarray' in src ? 1.1536 + src.subarray(srcOffset, srcOffset + this.numComps) : 1.1537 + Array.prototype.slice.call(src, srcOffset, srcOffset + this.numComps); 1.1538 + var tinted = this.tintFn(input); 1.1539 + this.base.getRgbItem(tinted, 0, dest, destOffset); 1.1540 + }, 1.1541 + getRgbBuffer: function AlternateCS_getRgbBuffer(src, srcOffset, count, 1.1542 + dest, destOffset, bits, 1.1543 + alpha01) { 1.1544 + var tintFn = this.tintFn; 1.1545 + var base = this.base; 1.1546 + var scale = 1 / ((1 << bits) - 1); 1.1547 + var baseNumComps = base.numComps; 1.1548 + var usesZeroToOneRange = base.usesZeroToOneRange; 1.1549 + var isPassthrough = (base.isPassthrough(8) || !usesZeroToOneRange) && 1.1550 + alpha01 === 0; 1.1551 + var pos = isPassthrough ? destOffset : 0; 1.1552 + var baseBuf = isPassthrough ? dest : new Uint8Array(baseNumComps * count); 1.1553 + var numComps = this.numComps; 1.1554 + 1.1555 + var scaled = new Float32Array(numComps); 1.1556 + var i, j; 1.1557 + for (i = 0; i < count; i++) { 1.1558 + for (j = 0; j < numComps; j++) { 1.1559 + scaled[j] = src[srcOffset++] * scale; 1.1560 + } 1.1561 + var tinted = tintFn(scaled); 1.1562 + if (usesZeroToOneRange) { 1.1563 + for (j = 0; j < baseNumComps; j++) { 1.1564 + baseBuf[pos++] = tinted[j] * 255; 1.1565 + } 1.1566 + } else { 1.1567 + base.getRgbItem(tinted, 0, baseBuf, pos); 1.1568 + pos += baseNumComps; 1.1569 + } 1.1570 + } 1.1571 + if (!isPassthrough) { 1.1572 + base.getRgbBuffer(baseBuf, 0, count, dest, destOffset, 8, alpha01); 1.1573 + } 1.1574 + }, 1.1575 + getOutputLength: function AlternateCS_getOutputLength(inputLength, 1.1576 + alpha01) { 1.1577 + return this.base.getOutputLength(inputLength * 1.1578 + this.base.numComps / this.numComps, 1.1579 + alpha01); 1.1580 + }, 1.1581 + isPassthrough: ColorSpace.prototype.isPassthrough, 1.1582 + fillRgb: ColorSpace.prototype.fillRgb, 1.1583 + isDefaultDecode: function AlternateCS_isDefaultDecode(decodeMap) { 1.1584 + return ColorSpace.isDefaultDecode(decodeMap, this.numComps); 1.1585 + }, 1.1586 + usesZeroToOneRange: true 1.1587 + }; 1.1588 + 1.1589 + return AlternateCS; 1.1590 +})(); 1.1591 + 1.1592 +var PatternCS = (function PatternCSClosure() { 1.1593 + function PatternCS(baseCS) { 1.1594 + this.name = 'Pattern'; 1.1595 + this.base = baseCS; 1.1596 + } 1.1597 + PatternCS.prototype = {}; 1.1598 + 1.1599 + return PatternCS; 1.1600 +})(); 1.1601 + 1.1602 +var IndexedCS = (function IndexedCSClosure() { 1.1603 + function IndexedCS(base, highVal, lookup) { 1.1604 + this.name = 'Indexed'; 1.1605 + this.numComps = 1; 1.1606 + this.defaultColor = new Uint8Array([0]); 1.1607 + this.base = base; 1.1608 + this.highVal = highVal; 1.1609 + 1.1610 + var baseNumComps = base.numComps; 1.1611 + var length = baseNumComps * highVal; 1.1612 + var lookupArray; 1.1613 + 1.1614 + if (isStream(lookup)) { 1.1615 + lookupArray = new Uint8Array(length); 1.1616 + var bytes = lookup.getBytes(length); 1.1617 + lookupArray.set(bytes); 1.1618 + } else if (isString(lookup)) { 1.1619 + lookupArray = new Uint8Array(length); 1.1620 + for (var i = 0; i < length; ++i) { 1.1621 + lookupArray[i] = lookup.charCodeAt(i); 1.1622 + } 1.1623 + } else if (lookup instanceof Uint8Array || lookup instanceof Array) { 1.1624 + lookupArray = lookup; 1.1625 + } else { 1.1626 + error('Unrecognized lookup table: ' + lookup); 1.1627 + } 1.1628 + this.lookup = lookupArray; 1.1629 + } 1.1630 + 1.1631 + IndexedCS.prototype = { 1.1632 + getRgb: ColorSpace.prototype.getRgb, 1.1633 + getRgbItem: function IndexedCS_getRgbItem(src, srcOffset, 1.1634 + dest, destOffset) { 1.1635 + var numComps = this.base.numComps; 1.1636 + var start = src[srcOffset] * numComps; 1.1637 + this.base.getRgbItem(this.lookup, start, dest, destOffset); 1.1638 + }, 1.1639 + getRgbBuffer: function IndexedCS_getRgbBuffer(src, srcOffset, count, 1.1640 + dest, destOffset, bits, 1.1641 + alpha01) { 1.1642 + var base = this.base; 1.1643 + var numComps = base.numComps; 1.1644 + var outputDelta = base.getOutputLength(numComps, alpha01); 1.1645 + var lookup = this.lookup; 1.1646 + 1.1647 + for (var i = 0; i < count; ++i) { 1.1648 + var lookupPos = src[srcOffset++] * numComps; 1.1649 + base.getRgbBuffer(lookup, lookupPos, 1, dest, destOffset, 8, alpha01); 1.1650 + destOffset += outputDelta; 1.1651 + } 1.1652 + }, 1.1653 + getOutputLength: function IndexedCS_getOutputLength(inputLength, alpha01) { 1.1654 + return this.base.getOutputLength(inputLength * this.base.numComps, 1.1655 + alpha01); 1.1656 + }, 1.1657 + isPassthrough: ColorSpace.prototype.isPassthrough, 1.1658 + fillRgb: ColorSpace.prototype.fillRgb, 1.1659 + isDefaultDecode: function IndexedCS_isDefaultDecode(decodeMap) { 1.1660 + // indexed color maps shouldn't be changed 1.1661 + return true; 1.1662 + }, 1.1663 + usesZeroToOneRange: true 1.1664 + }; 1.1665 + return IndexedCS; 1.1666 +})(); 1.1667 + 1.1668 +var DeviceGrayCS = (function DeviceGrayCSClosure() { 1.1669 + function DeviceGrayCS() { 1.1670 + this.name = 'DeviceGray'; 1.1671 + this.numComps = 1; 1.1672 + this.defaultColor = new Float32Array([0]); 1.1673 + } 1.1674 + 1.1675 + DeviceGrayCS.prototype = { 1.1676 + getRgb: ColorSpace.prototype.getRgb, 1.1677 + getRgbItem: function DeviceGrayCS_getRgbItem(src, srcOffset, 1.1678 + dest, destOffset) { 1.1679 + var c = (src[srcOffset] * 255) | 0; 1.1680 + c = c < 0 ? 0 : c > 255 ? 255 : c; 1.1681 + dest[destOffset] = dest[destOffset + 1] = dest[destOffset + 2] = c; 1.1682 + }, 1.1683 + getRgbBuffer: function DeviceGrayCS_getRgbBuffer(src, srcOffset, count, 1.1684 + dest, destOffset, bits, 1.1685 + alpha01) { 1.1686 + var scale = 255 / ((1 << bits) - 1); 1.1687 + var j = srcOffset, q = destOffset; 1.1688 + for (var i = 0; i < count; ++i) { 1.1689 + var c = (scale * src[j++]) | 0; 1.1690 + dest[q++] = c; 1.1691 + dest[q++] = c; 1.1692 + dest[q++] = c; 1.1693 + q += alpha01; 1.1694 + } 1.1695 + }, 1.1696 + getOutputLength: function DeviceGrayCS_getOutputLength(inputLength, 1.1697 + alpha01) { 1.1698 + return inputLength * (3 + alpha01); 1.1699 + }, 1.1700 + isPassthrough: ColorSpace.prototype.isPassthrough, 1.1701 + fillRgb: ColorSpace.prototype.fillRgb, 1.1702 + isDefaultDecode: function DeviceGrayCS_isDefaultDecode(decodeMap) { 1.1703 + return ColorSpace.isDefaultDecode(decodeMap, this.numComps); 1.1704 + }, 1.1705 + usesZeroToOneRange: true 1.1706 + }; 1.1707 + return DeviceGrayCS; 1.1708 +})(); 1.1709 + 1.1710 +var DeviceRgbCS = (function DeviceRgbCSClosure() { 1.1711 + function DeviceRgbCS() { 1.1712 + this.name = 'DeviceRGB'; 1.1713 + this.numComps = 3; 1.1714 + this.defaultColor = new Float32Array([0, 0, 0]); 1.1715 + } 1.1716 + DeviceRgbCS.prototype = { 1.1717 + getRgb: ColorSpace.prototype.getRgb, 1.1718 + getRgbItem: function DeviceRgbCS_getRgbItem(src, srcOffset, 1.1719 + dest, destOffset) { 1.1720 + var r = (src[srcOffset] * 255) | 0; 1.1721 + var g = (src[srcOffset + 1] * 255) | 0; 1.1722 + var b = (src[srcOffset + 2] * 255) | 0; 1.1723 + dest[destOffset] = r < 0 ? 0 : r > 255 ? 255 : r; 1.1724 + dest[destOffset + 1] = g < 0 ? 0 : g > 255 ? 255 : g; 1.1725 + dest[destOffset + 2] = b < 0 ? 0 : b > 255 ? 255 : b; 1.1726 + }, 1.1727 + getRgbBuffer: function DeviceRgbCS_getRgbBuffer(src, srcOffset, count, 1.1728 + dest, destOffset, bits, 1.1729 + alpha01) { 1.1730 + if (bits === 8 && alpha01 === 0) { 1.1731 + dest.set(src.subarray(srcOffset, srcOffset + count * 3), destOffset); 1.1732 + return; 1.1733 + } 1.1734 + var scale = 255 / ((1 << bits) - 1); 1.1735 + var j = srcOffset, q = destOffset; 1.1736 + for (var i = 0; i < count; ++i) { 1.1737 + dest[q++] = (scale * src[j++]) | 0; 1.1738 + dest[q++] = (scale * src[j++]) | 0; 1.1739 + dest[q++] = (scale * src[j++]) | 0; 1.1740 + q += alpha01; 1.1741 + } 1.1742 + }, 1.1743 + getOutputLength: function DeviceRgbCS_getOutputLength(inputLength, 1.1744 + alpha01) { 1.1745 + return (inputLength * (3 + alpha01) / 3) | 0; 1.1746 + }, 1.1747 + isPassthrough: function DeviceRgbCS_isPassthrough(bits) { 1.1748 + return bits == 8; 1.1749 + }, 1.1750 + fillRgb: ColorSpace.prototype.fillRgb, 1.1751 + isDefaultDecode: function DeviceRgbCS_isDefaultDecode(decodeMap) { 1.1752 + return ColorSpace.isDefaultDecode(decodeMap, this.numComps); 1.1753 + }, 1.1754 + usesZeroToOneRange: true 1.1755 + }; 1.1756 + return DeviceRgbCS; 1.1757 +})(); 1.1758 + 1.1759 +var DeviceCmykCS = (function DeviceCmykCSClosure() { 1.1760 + // The coefficients below was found using numerical analysis: the method of 1.1761 + // steepest descent for the sum((f_i - color_value_i)^2) for r/g/b colors, 1.1762 + // where color_value is the tabular value from the table of sampled RGB colors 1.1763 + // from CMYK US Web Coated (SWOP) colorspace, and f_i is the corresponding 1.1764 + // CMYK color conversion using the estimation below: 1.1765 + // f(A, B,.. N) = Acc+Bcm+Ccy+Dck+c+Fmm+Gmy+Hmk+Im+Jyy+Kyk+Ly+Mkk+Nk+255 1.1766 + function convertToRgb(src, srcOffset, srcScale, dest, destOffset) { 1.1767 + var c = src[srcOffset + 0] * srcScale; 1.1768 + var m = src[srcOffset + 1] * srcScale; 1.1769 + var y = src[srcOffset + 2] * srcScale; 1.1770 + var k = src[srcOffset + 3] * srcScale; 1.1771 + 1.1772 + var r = 1.1773 + (c * (-4.387332384609988 * c + 54.48615194189176 * m + 1.1774 + 18.82290502165302 * y + 212.25662451639585 * k + 1.1775 + -285.2331026137004) + 1.1776 + m * (1.7149763477362134 * m - 5.6096736904047315 * y + 1.1777 + -17.873870861415444 * k - 5.497006427196366) + 1.1778 + y * (-2.5217340131683033 * y - 21.248923337353073 * k + 1.1779 + 17.5119270841813) + 1.1780 + k * (-21.86122147463605 * k - 189.48180835922747) + 255) | 0; 1.1781 + var g = 1.1782 + (c * (8.841041422036149 * c + 60.118027045597366 * m + 1.1783 + 6.871425592049007 * y + 31.159100130055922 * k + 1.1784 + -79.2970844816548) + 1.1785 + m * (-15.310361306967817 * m + 17.575251261109482 * y + 1.1786 + 131.35250912493976 * k - 190.9453302588951) + 1.1787 + y * (4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878) + 1.1788 + k * (-20.737325471181034 * k - 187.80453709719578) + 255) | 0; 1.1789 + var b = 1.1790 + (c * (0.8842522430003296 * c + 8.078677503112928 * m + 1.1791 + 30.89978309703729 * y - 0.23883238689178934 * k + 1.1792 + -14.183576799673286) + 1.1793 + m * (10.49593273432072 * m + 63.02378494754052 * y + 1.1794 + 50.606957656360734 * k - 112.23884253719248) + 1.1795 + y * (0.03296041114873217 * y + 115.60384449646641 * k + 1.1796 + -193.58209356861505) + 1.1797 + k * (-22.33816807309886 * k - 180.12613974708367) + 255) | 0; 1.1798 + 1.1799 + dest[destOffset] = r > 255 ? 255 : r < 0 ? 0 : r; 1.1800 + dest[destOffset + 1] = g > 255 ? 255 : g < 0 ? 0 : g; 1.1801 + dest[destOffset + 2] = b > 255 ? 255 : b < 0 ? 0 : b; 1.1802 + } 1.1803 + 1.1804 + function DeviceCmykCS() { 1.1805 + this.name = 'DeviceCMYK'; 1.1806 + this.numComps = 4; 1.1807 + this.defaultColor = new Float32Array([0, 0, 0, 1]); 1.1808 + } 1.1809 + DeviceCmykCS.prototype = { 1.1810 + getRgb: ColorSpace.prototype.getRgb, 1.1811 + getRgbItem: function DeviceCmykCS_getRgbItem(src, srcOffset, 1.1812 + dest, destOffset) { 1.1813 + convertToRgb(src, srcOffset, 1, dest, destOffset); 1.1814 + }, 1.1815 + getRgbBuffer: function DeviceCmykCS_getRgbBuffer(src, srcOffset, count, 1.1816 + dest, destOffset, bits, 1.1817 + alpha01) { 1.1818 + var scale = 1 / ((1 << bits) - 1); 1.1819 + for (var i = 0; i < count; i++) { 1.1820 + convertToRgb(src, srcOffset, scale, dest, destOffset); 1.1821 + srcOffset += 4; 1.1822 + destOffset += 3 + alpha01; 1.1823 + } 1.1824 + }, 1.1825 + getOutputLength: function DeviceCmykCS_getOutputLength(inputLength, 1.1826 + alpha01) { 1.1827 + return (inputLength / 4 * (3 + alpha01)) | 0; 1.1828 + }, 1.1829 + isPassthrough: ColorSpace.prototype.isPassthrough, 1.1830 + fillRgb: ColorSpace.prototype.fillRgb, 1.1831 + isDefaultDecode: function DeviceCmykCS_isDefaultDecode(decodeMap) { 1.1832 + return ColorSpace.isDefaultDecode(decodeMap, this.numComps); 1.1833 + }, 1.1834 + usesZeroToOneRange: true 1.1835 + }; 1.1836 + 1.1837 + return DeviceCmykCS; 1.1838 +})(); 1.1839 + 1.1840 +// 1.1841 +// CalGrayCS: Based on "PDF Reference, Sixth Ed", p.245 1.1842 +// 1.1843 +var CalGrayCS = (function CalGrayCSClosure() { 1.1844 + function CalGrayCS(whitePoint, blackPoint, gamma) { 1.1845 + this.name = 'CalGray'; 1.1846 + this.numComps = 1; 1.1847 + this.defaultColor = new Float32Array([0]); 1.1848 + 1.1849 + if (!whitePoint) { 1.1850 + error('WhitePoint missing - required for color space CalGray'); 1.1851 + } 1.1852 + blackPoint = blackPoint || [0, 0, 0]; 1.1853 + gamma = gamma || 1; 1.1854 + 1.1855 + // Translate arguments to spec variables. 1.1856 + this.XW = whitePoint[0]; 1.1857 + this.YW = whitePoint[1]; 1.1858 + this.ZW = whitePoint[2]; 1.1859 + 1.1860 + this.XB = blackPoint[0]; 1.1861 + this.YB = blackPoint[1]; 1.1862 + this.ZB = blackPoint[2]; 1.1863 + 1.1864 + this.G = gamma; 1.1865 + 1.1866 + // Validate variables as per spec. 1.1867 + if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) { 1.1868 + error('Invalid WhitePoint components for ' + this.name + 1.1869 + ', no fallback available'); 1.1870 + } 1.1871 + 1.1872 + if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { 1.1873 + info('Invalid BlackPoint for ' + this.name + ', falling back to default'); 1.1874 + this.XB = this.YB = this.ZB = 0; 1.1875 + } 1.1876 + 1.1877 + if (this.XB !== 0 || this.YB !== 0 || this.ZB !== 0) { 1.1878 + warn(this.name + ', BlackPoint: XB: ' + this.XB + ', YB: ' + this.YB + 1.1879 + ', ZB: ' + this.ZB + ', only default values are supported.'); 1.1880 + } 1.1881 + 1.1882 + if (this.G < 1) { 1.1883 + info('Invalid Gamma: ' + this.G + ' for ' + this.name + 1.1884 + ', falling back to default'); 1.1885 + this.G = 1; 1.1886 + } 1.1887 + } 1.1888 + 1.1889 + function convertToRgb(cs, src, srcOffset, dest, destOffset, scale) { 1.1890 + // A represents a gray component of a calibrated gray space. 1.1891 + // A <---> AG in the spec 1.1892 + var A = src[srcOffset] * scale; 1.1893 + var AG = Math.pow(A, cs.G); 1.1894 + 1.1895 + // Computes intermediate variables M, L, N as per spec. 1.1896 + // Except if other than default BlackPoint values are used. 1.1897 + var M = cs.XW * AG; 1.1898 + var L = cs.YW * AG; 1.1899 + var N = cs.ZW * AG; 1.1900 + 1.1901 + // Decode XYZ, as per spec. 1.1902 + var X = M; 1.1903 + var Y = L; 1.1904 + var Z = N; 1.1905 + 1.1906 + // http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html, Ch 4. 1.1907 + // This yields values in range [0, 100]. 1.1908 + var Lstar = Math.max(116 * Math.pow(Y, 1 / 3) - 16, 0); 1.1909 + 1.1910 + // Convert values to rgb range [0, 255]. 1.1911 + dest[destOffset] = Lstar * 255 / 100; 1.1912 + dest[destOffset + 1] = Lstar * 255 / 100; 1.1913 + dest[destOffset + 2] = Lstar * 255 / 100; 1.1914 + } 1.1915 + 1.1916 + CalGrayCS.prototype = { 1.1917 + getRgb: ColorSpace.prototype.getRgb, 1.1918 + getRgbItem: function CalGrayCS_getRgbItem(src, srcOffset, 1.1919 + dest, destOffset) { 1.1920 + convertToRgb(this, src, srcOffset, dest, destOffset, 1); 1.1921 + }, 1.1922 + getRgbBuffer: function CalGrayCS_getRgbBuffer(src, srcOffset, count, 1.1923 + dest, destOffset, bits, 1.1924 + alpha01) { 1.1925 + var scale = 1 / ((1 << bits) - 1); 1.1926 + 1.1927 + for (var i = 0; i < count; ++i) { 1.1928 + convertToRgb(this, src, srcOffset, dest, destOffset, scale); 1.1929 + srcOffset += 1; 1.1930 + destOffset += 3 + alpha01; 1.1931 + } 1.1932 + }, 1.1933 + getOutputLength: function CalGrayCS_getOutputLength(inputLength, alpha01) { 1.1934 + return inputLength * (3 + alpha01); 1.1935 + }, 1.1936 + isPassthrough: ColorSpace.prototype.isPassthrough, 1.1937 + fillRgb: ColorSpace.prototype.fillRgb, 1.1938 + isDefaultDecode: function CalGrayCS_isDefaultDecode(decodeMap) { 1.1939 + return ColorSpace.isDefaultDecode(decodeMap, this.numComps); 1.1940 + }, 1.1941 + usesZeroToOneRange: true 1.1942 + }; 1.1943 + return CalGrayCS; 1.1944 +})(); 1.1945 + 1.1946 +// 1.1947 +// LabCS: Based on "PDF Reference, Sixth Ed", p.250 1.1948 +// 1.1949 +var LabCS = (function LabCSClosure() { 1.1950 + function LabCS(whitePoint, blackPoint, range) { 1.1951 + this.name = 'Lab'; 1.1952 + this.numComps = 3; 1.1953 + this.defaultColor = new Float32Array([0, 0, 0]); 1.1954 + 1.1955 + if (!whitePoint) { 1.1956 + error('WhitePoint missing - required for color space Lab'); 1.1957 + } 1.1958 + blackPoint = blackPoint || [0, 0, 0]; 1.1959 + range = range || [-100, 100, -100, 100]; 1.1960 + 1.1961 + // Translate args to spec variables 1.1962 + this.XW = whitePoint[0]; 1.1963 + this.YW = whitePoint[1]; 1.1964 + this.ZW = whitePoint[2]; 1.1965 + this.amin = range[0]; 1.1966 + this.amax = range[1]; 1.1967 + this.bmin = range[2]; 1.1968 + this.bmax = range[3]; 1.1969 + 1.1970 + // These are here just for completeness - the spec doesn't offer any 1.1971 + // formulas that use BlackPoint in Lab 1.1972 + this.XB = blackPoint[0]; 1.1973 + this.YB = blackPoint[1]; 1.1974 + this.ZB = blackPoint[2]; 1.1975 + 1.1976 + // Validate vars as per spec 1.1977 + if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) { 1.1978 + error('Invalid WhitePoint components, no fallback available'); 1.1979 + } 1.1980 + 1.1981 + if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { 1.1982 + info('Invalid BlackPoint, falling back to default'); 1.1983 + this.XB = this.YB = this.ZB = 0; 1.1984 + } 1.1985 + 1.1986 + if (this.amin > this.amax || this.bmin > this.bmax) { 1.1987 + info('Invalid Range, falling back to defaults'); 1.1988 + this.amin = -100; 1.1989 + this.amax = 100; 1.1990 + this.bmin = -100; 1.1991 + this.bmax = 100; 1.1992 + } 1.1993 + } 1.1994 + 1.1995 + // Function g(x) from spec 1.1996 + function fn_g(x) { 1.1997 + if (x >= 6 / 29) { 1.1998 + return x * x * x; 1.1999 + } else { 1.2000 + return (108 / 841) * (x - 4 / 29); 1.2001 + } 1.2002 + } 1.2003 + 1.2004 + function decode(value, high1, low2, high2) { 1.2005 + return low2 + (value) * (high2 - low2) / (high1); 1.2006 + } 1.2007 + 1.2008 + // If decoding is needed maxVal should be 2^bits per component - 1. 1.2009 + function convertToRgb(cs, src, srcOffset, maxVal, dest, destOffset) { 1.2010 + // XXX: Lab input is in the range of [0, 100], [amin, amax], [bmin, bmax] 1.2011 + // not the usual [0, 1]. If a command like setFillColor is used the src 1.2012 + // values will already be within the correct range. However, if we are 1.2013 + // converting an image we have to map the values to the correct range given 1.2014 + // above. 1.2015 + // Ls,as,bs <---> L*,a*,b* in the spec 1.2016 + var Ls = src[srcOffset]; 1.2017 + var as = src[srcOffset + 1]; 1.2018 + var bs = src[srcOffset + 2]; 1.2019 + if (maxVal !== false) { 1.2020 + Ls = decode(Ls, maxVal, 0, 100); 1.2021 + as = decode(as, maxVal, cs.amin, cs.amax); 1.2022 + bs = decode(bs, maxVal, cs.bmin, cs.bmax); 1.2023 + } 1.2024 + 1.2025 + // Adjust limits of 'as' and 'bs' 1.2026 + as = as > cs.amax ? cs.amax : as < cs.amin ? cs.amin : as; 1.2027 + bs = bs > cs.bmax ? cs.bmax : bs < cs.bmin ? cs.bmin : bs; 1.2028 + 1.2029 + // Computes intermediate variables X,Y,Z as per spec 1.2030 + var M = (Ls + 16) / 116; 1.2031 + var L = M + (as / 500); 1.2032 + var N = M - (bs / 200); 1.2033 + 1.2034 + var X = cs.XW * fn_g(L); 1.2035 + var Y = cs.YW * fn_g(M); 1.2036 + var Z = cs.ZW * fn_g(N); 1.2037 + 1.2038 + var r, g, b; 1.2039 + // Using different conversions for D50 and D65 white points, 1.2040 + // per http://www.color.org/srgb.pdf 1.2041 + if (cs.ZW < 1) { 1.2042 + // Assuming D50 (X=0.9642, Y=1.00, Z=0.8249) 1.2043 + r = X * 3.1339 + Y * -1.6170 + Z * -0.4906; 1.2044 + g = X * -0.9785 + Y * 1.9160 + Z * 0.0333; 1.2045 + b = X * 0.0720 + Y * -0.2290 + Z * 1.4057; 1.2046 + } else { 1.2047 + // Assuming D65 (X=0.9505, Y=1.00, Z=1.0888) 1.2048 + r = X * 3.2406 + Y * -1.5372 + Z * -0.4986; 1.2049 + g = X * -0.9689 + Y * 1.8758 + Z * 0.0415; 1.2050 + b = X * 0.0557 + Y * -0.2040 + Z * 1.0570; 1.2051 + } 1.2052 + // clamp color values to [0,1] range then convert to [0,255] range. 1.2053 + dest[destOffset] = r <= 0 ? 0 : r >= 1 ? 255 : Math.sqrt(r) * 255 | 0; 1.2054 + dest[destOffset + 1] = g <= 0 ? 0 : g >= 1 ? 255 : Math.sqrt(g) * 255 | 0; 1.2055 + dest[destOffset + 2] = b <= 0 ? 0 : b >= 1 ? 255 : Math.sqrt(b) * 255 | 0; 1.2056 + } 1.2057 + 1.2058 + LabCS.prototype = { 1.2059 + getRgb: ColorSpace.prototype.getRgb, 1.2060 + getRgbItem: function LabCS_getRgbItem(src, srcOffset, dest, destOffset) { 1.2061 + convertToRgb(this, src, srcOffset, false, dest, destOffset); 1.2062 + }, 1.2063 + getRgbBuffer: function LabCS_getRgbBuffer(src, srcOffset, count, 1.2064 + dest, destOffset, bits, 1.2065 + alpha01) { 1.2066 + var maxVal = (1 << bits) - 1; 1.2067 + for (var i = 0; i < count; i++) { 1.2068 + convertToRgb(this, src, srcOffset, maxVal, dest, destOffset); 1.2069 + srcOffset += 3; 1.2070 + destOffset += 3 + alpha01; 1.2071 + } 1.2072 + }, 1.2073 + getOutputLength: function LabCS_getOutputLength(inputLength, alpha01) { 1.2074 + return (inputLength * (3 + alpha01) / 3) | 0; 1.2075 + }, 1.2076 + isPassthrough: ColorSpace.prototype.isPassthrough, 1.2077 + isDefaultDecode: function LabCS_isDefaultDecode(decodeMap) { 1.2078 + // XXX: Decoding is handled with the lab conversion because of the strange 1.2079 + // ranges that are used. 1.2080 + return true; 1.2081 + }, 1.2082 + usesZeroToOneRange: false 1.2083 + }; 1.2084 + return LabCS; 1.2085 +})(); 1.2086 + 1.2087 + 1.2088 + 1.2089 +var PDFFunction = (function PDFFunctionClosure() { 1.2090 + var CONSTRUCT_SAMPLED = 0; 1.2091 + var CONSTRUCT_INTERPOLATED = 2; 1.2092 + var CONSTRUCT_STICHED = 3; 1.2093 + var CONSTRUCT_POSTSCRIPT = 4; 1.2094 + 1.2095 + return { 1.2096 + getSampleArray: function PDFFunction_getSampleArray(size, outputSize, bps, 1.2097 + str) { 1.2098 + var i, ii; 1.2099 + var length = 1; 1.2100 + for (i = 0, ii = size.length; i < ii; i++) { 1.2101 + length *= size[i]; 1.2102 + } 1.2103 + length *= outputSize; 1.2104 + 1.2105 + var array = []; 1.2106 + var codeSize = 0; 1.2107 + var codeBuf = 0; 1.2108 + // 32 is a valid bps so shifting won't work 1.2109 + var sampleMul = 1.0 / (Math.pow(2.0, bps) - 1); 1.2110 + 1.2111 + var strBytes = str.getBytes((length * bps + 7) / 8); 1.2112 + var strIdx = 0; 1.2113 + for (i = 0; i < length; i++) { 1.2114 + while (codeSize < bps) { 1.2115 + codeBuf <<= 8; 1.2116 + codeBuf |= strBytes[strIdx++]; 1.2117 + codeSize += 8; 1.2118 + } 1.2119 + codeSize -= bps; 1.2120 + array.push((codeBuf >> codeSize) * sampleMul); 1.2121 + codeBuf &= (1 << codeSize) - 1; 1.2122 + } 1.2123 + return array; 1.2124 + }, 1.2125 + 1.2126 + getIR: function PDFFunction_getIR(xref, fn) { 1.2127 + var dict = fn.dict; 1.2128 + if (!dict) { 1.2129 + dict = fn; 1.2130 + } 1.2131 + 1.2132 + var types = [this.constructSampled, 1.2133 + null, 1.2134 + this.constructInterpolated, 1.2135 + this.constructStiched, 1.2136 + this.constructPostScript]; 1.2137 + 1.2138 + var typeNum = dict.get('FunctionType'); 1.2139 + var typeFn = types[typeNum]; 1.2140 + if (!typeFn) { 1.2141 + error('Unknown type of function'); 1.2142 + } 1.2143 + 1.2144 + return typeFn.call(this, fn, dict, xref); 1.2145 + }, 1.2146 + 1.2147 + fromIR: function PDFFunction_fromIR(IR) { 1.2148 + var type = IR[0]; 1.2149 + switch (type) { 1.2150 + case CONSTRUCT_SAMPLED: 1.2151 + return this.constructSampledFromIR(IR); 1.2152 + case CONSTRUCT_INTERPOLATED: 1.2153 + return this.constructInterpolatedFromIR(IR); 1.2154 + case CONSTRUCT_STICHED: 1.2155 + return this.constructStichedFromIR(IR); 1.2156 + //case CONSTRUCT_POSTSCRIPT: 1.2157 + default: 1.2158 + return this.constructPostScriptFromIR(IR); 1.2159 + } 1.2160 + }, 1.2161 + 1.2162 + parse: function PDFFunction_parse(xref, fn) { 1.2163 + var IR = this.getIR(xref, fn); 1.2164 + return this.fromIR(IR); 1.2165 + }, 1.2166 + 1.2167 + constructSampled: function PDFFunction_constructSampled(str, dict) { 1.2168 + function toMultiArray(arr) { 1.2169 + var inputLength = arr.length; 1.2170 + var out = []; 1.2171 + var index = 0; 1.2172 + for (var i = 0; i < inputLength; i += 2) { 1.2173 + out[index] = [arr[i], arr[i + 1]]; 1.2174 + ++index; 1.2175 + } 1.2176 + return out; 1.2177 + } 1.2178 + var domain = dict.get('Domain'); 1.2179 + var range = dict.get('Range'); 1.2180 + 1.2181 + if (!domain || !range) { 1.2182 + error('No domain or range'); 1.2183 + } 1.2184 + 1.2185 + var inputSize = domain.length / 2; 1.2186 + var outputSize = range.length / 2; 1.2187 + 1.2188 + domain = toMultiArray(domain); 1.2189 + range = toMultiArray(range); 1.2190 + 1.2191 + var size = dict.get('Size'); 1.2192 + var bps = dict.get('BitsPerSample'); 1.2193 + var order = dict.get('Order') || 1; 1.2194 + if (order !== 1) { 1.2195 + // No description how cubic spline interpolation works in PDF32000:2008 1.2196 + // As in poppler, ignoring order, linear interpolation may work as good 1.2197 + info('No support for cubic spline interpolation: ' + order); 1.2198 + } 1.2199 + 1.2200 + var encode = dict.get('Encode'); 1.2201 + if (!encode) { 1.2202 + encode = []; 1.2203 + for (var i = 0; i < inputSize; ++i) { 1.2204 + encode.push(0); 1.2205 + encode.push(size[i] - 1); 1.2206 + } 1.2207 + } 1.2208 + encode = toMultiArray(encode); 1.2209 + 1.2210 + var decode = dict.get('Decode'); 1.2211 + if (!decode) { 1.2212 + decode = range; 1.2213 + } else { 1.2214 + decode = toMultiArray(decode); 1.2215 + } 1.2216 + 1.2217 + var samples = this.getSampleArray(size, outputSize, bps, str); 1.2218 + 1.2219 + return [ 1.2220 + CONSTRUCT_SAMPLED, inputSize, domain, encode, decode, samples, size, 1.2221 + outputSize, Math.pow(2, bps) - 1, range 1.2222 + ]; 1.2223 + }, 1.2224 + 1.2225 + constructSampledFromIR: function PDFFunction_constructSampledFromIR(IR) { 1.2226 + // See chapter 3, page 109 of the PDF reference 1.2227 + function interpolate(x, xmin, xmax, ymin, ymax) { 1.2228 + return ymin + ((x - xmin) * ((ymax - ymin) / (xmax - xmin))); 1.2229 + } 1.2230 + 1.2231 + return function constructSampledFromIRResult(args) { 1.2232 + // See chapter 3, page 110 of the PDF reference. 1.2233 + var m = IR[1]; 1.2234 + var domain = IR[2]; 1.2235 + var encode = IR[3]; 1.2236 + var decode = IR[4]; 1.2237 + var samples = IR[5]; 1.2238 + var size = IR[6]; 1.2239 + var n = IR[7]; 1.2240 + //var mask = IR[8]; 1.2241 + var range = IR[9]; 1.2242 + 1.2243 + if (m != args.length) { 1.2244 + error('Incorrect number of arguments: ' + m + ' != ' + 1.2245 + args.length); 1.2246 + } 1.2247 + 1.2248 + var x = args; 1.2249 + 1.2250 + // Building the cube vertices: its part and sample index 1.2251 + // http://rjwagner49.com/Mathematics/Interpolation.pdf 1.2252 + var cubeVertices = 1 << m; 1.2253 + var cubeN = new Float64Array(cubeVertices); 1.2254 + var cubeVertex = new Uint32Array(cubeVertices); 1.2255 + var i, j; 1.2256 + for (j = 0; j < cubeVertices; j++) { 1.2257 + cubeN[j] = 1; 1.2258 + } 1.2259 + 1.2260 + var k = n, pos = 1; 1.2261 + // Map x_i to y_j for 0 <= i < m using the sampled function. 1.2262 + for (i = 0; i < m; ++i) { 1.2263 + // x_i' = min(max(x_i, Domain_2i), Domain_2i+1) 1.2264 + var domain_2i = domain[i][0]; 1.2265 + var domain_2i_1 = domain[i][1]; 1.2266 + var xi = Math.min(Math.max(x[i], domain_2i), domain_2i_1); 1.2267 + 1.2268 + // e_i = Interpolate(x_i', Domain_2i, Domain_2i+1, 1.2269 + // Encode_2i, Encode_2i+1) 1.2270 + var e = interpolate(xi, domain_2i, domain_2i_1, 1.2271 + encode[i][0], encode[i][1]); 1.2272 + 1.2273 + // e_i' = min(max(e_i, 0), Size_i - 1) 1.2274 + var size_i = size[i]; 1.2275 + e = Math.min(Math.max(e, 0), size_i - 1); 1.2276 + 1.2277 + // Adjusting the cube: N and vertex sample index 1.2278 + var e0 = e < size_i - 1 ? Math.floor(e) : e - 1; // e1 = e0 + 1; 1.2279 + var n0 = e0 + 1 - e; // (e1 - e) / (e1 - e0); 1.2280 + var n1 = e - e0; // (e - e0) / (e1 - e0); 1.2281 + var offset0 = e0 * k; 1.2282 + var offset1 = offset0 + k; // e1 * k 1.2283 + for (j = 0; j < cubeVertices; j++) { 1.2284 + if (j & pos) { 1.2285 + cubeN[j] *= n1; 1.2286 + cubeVertex[j] += offset1; 1.2287 + } else { 1.2288 + cubeN[j] *= n0; 1.2289 + cubeVertex[j] += offset0; 1.2290 + } 1.2291 + } 1.2292 + 1.2293 + k *= size_i; 1.2294 + pos <<= 1; 1.2295 + } 1.2296 + 1.2297 + var y = new Float64Array(n); 1.2298 + for (j = 0; j < n; ++j) { 1.2299 + // Sum all cube vertices' samples portions 1.2300 + var rj = 0; 1.2301 + for (i = 0; i < cubeVertices; i++) { 1.2302 + rj += samples[cubeVertex[i] + j] * cubeN[i]; 1.2303 + } 1.2304 + 1.2305 + // r_j' = Interpolate(r_j, 0, 2^BitsPerSample - 1, 1.2306 + // Decode_2j, Decode_2j+1) 1.2307 + rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]); 1.2308 + 1.2309 + // y_j = min(max(r_j, range_2j), range_2j+1) 1.2310 + y[j] = Math.min(Math.max(rj, range[j][0]), range[j][1]); 1.2311 + } 1.2312 + 1.2313 + return y; 1.2314 + }; 1.2315 + }, 1.2316 + 1.2317 + constructInterpolated: function PDFFunction_constructInterpolated(str, 1.2318 + dict) { 1.2319 + var c0 = dict.get('C0') || [0]; 1.2320 + var c1 = dict.get('C1') || [1]; 1.2321 + var n = dict.get('N'); 1.2322 + 1.2323 + if (!isArray(c0) || !isArray(c1)) { 1.2324 + error('Illegal dictionary for interpolated function'); 1.2325 + } 1.2326 + 1.2327 + var length = c0.length; 1.2328 + var diff = []; 1.2329 + for (var i = 0; i < length; ++i) { 1.2330 + diff.push(c1[i] - c0[i]); 1.2331 + } 1.2332 + 1.2333 + return [CONSTRUCT_INTERPOLATED, c0, diff, n]; 1.2334 + }, 1.2335 + 1.2336 + constructInterpolatedFromIR: 1.2337 + function PDFFunction_constructInterpolatedFromIR(IR) { 1.2338 + var c0 = IR[1]; 1.2339 + var diff = IR[2]; 1.2340 + var n = IR[3]; 1.2341 + 1.2342 + var length = diff.length; 1.2343 + 1.2344 + return function constructInterpolatedFromIRResult(args) { 1.2345 + var x = n == 1 ? args[0] : Math.pow(args[0], n); 1.2346 + 1.2347 + var out = []; 1.2348 + for (var j = 0; j < length; ++j) { 1.2349 + out.push(c0[j] + (x * diff[j])); 1.2350 + } 1.2351 + 1.2352 + return out; 1.2353 + 1.2354 + }; 1.2355 + }, 1.2356 + 1.2357 + constructStiched: function PDFFunction_constructStiched(fn, dict, xref) { 1.2358 + var domain = dict.get('Domain'); 1.2359 + 1.2360 + if (!domain) { 1.2361 + error('No domain'); 1.2362 + } 1.2363 + 1.2364 + var inputSize = domain.length / 2; 1.2365 + if (inputSize != 1) { 1.2366 + error('Bad domain for stiched function'); 1.2367 + } 1.2368 + 1.2369 + var fnRefs = dict.get('Functions'); 1.2370 + var fns = []; 1.2371 + for (var i = 0, ii = fnRefs.length; i < ii; ++i) { 1.2372 + fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i]))); 1.2373 + } 1.2374 + 1.2375 + var bounds = dict.get('Bounds'); 1.2376 + var encode = dict.get('Encode'); 1.2377 + 1.2378 + return [CONSTRUCT_STICHED, domain, bounds, encode, fns]; 1.2379 + }, 1.2380 + 1.2381 + constructStichedFromIR: function PDFFunction_constructStichedFromIR(IR) { 1.2382 + var domain = IR[1]; 1.2383 + var bounds = IR[2]; 1.2384 + var encode = IR[3]; 1.2385 + var fnsIR = IR[4]; 1.2386 + var fns = []; 1.2387 + 1.2388 + for (var i = 0, ii = fnsIR.length; i < ii; i++) { 1.2389 + fns.push(PDFFunction.fromIR(fnsIR[i])); 1.2390 + } 1.2391 + 1.2392 + return function constructStichedFromIRResult(args) { 1.2393 + var clip = function constructStichedFromIRClip(v, min, max) { 1.2394 + if (v > max) { 1.2395 + v = max; 1.2396 + } else if (v < min) { 1.2397 + v = min; 1.2398 + } 1.2399 + return v; 1.2400 + }; 1.2401 + 1.2402 + // clip to domain 1.2403 + var v = clip(args[0], domain[0], domain[1]); 1.2404 + // calulate which bound the value is in 1.2405 + for (var i = 0, ii = bounds.length; i < ii; ++i) { 1.2406 + if (v < bounds[i]) { 1.2407 + break; 1.2408 + } 1.2409 + } 1.2410 + 1.2411 + // encode value into domain of function 1.2412 + var dmin = domain[0]; 1.2413 + if (i > 0) { 1.2414 + dmin = bounds[i - 1]; 1.2415 + } 1.2416 + var dmax = domain[1]; 1.2417 + if (i < bounds.length) { 1.2418 + dmax = bounds[i]; 1.2419 + } 1.2420 + 1.2421 + var rmin = encode[2 * i]; 1.2422 + var rmax = encode[2 * i + 1]; 1.2423 + 1.2424 + var v2 = rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin); 1.2425 + 1.2426 + // call the appropriate function 1.2427 + return fns[i]([v2]); 1.2428 + }; 1.2429 + }, 1.2430 + 1.2431 + constructPostScript: function PDFFunction_constructPostScript(fn, dict, 1.2432 + xref) { 1.2433 + var domain = dict.get('Domain'); 1.2434 + var range = dict.get('Range'); 1.2435 + 1.2436 + if (!domain) { 1.2437 + error('No domain.'); 1.2438 + } 1.2439 + 1.2440 + if (!range) { 1.2441 + error('No range.'); 1.2442 + } 1.2443 + 1.2444 + var lexer = new PostScriptLexer(fn); 1.2445 + var parser = new PostScriptParser(lexer); 1.2446 + var code = parser.parse(); 1.2447 + 1.2448 + return [CONSTRUCT_POSTSCRIPT, domain, range, code]; 1.2449 + }, 1.2450 + 1.2451 + constructPostScriptFromIR: function PDFFunction_constructPostScriptFromIR( 1.2452 + IR) { 1.2453 + var domain = IR[1]; 1.2454 + var range = IR[2]; 1.2455 + var code = IR[3]; 1.2456 + var numOutputs = range.length / 2; 1.2457 + var evaluator = new PostScriptEvaluator(code); 1.2458 + // Cache the values for a big speed up, the cache size is limited though 1.2459 + // since the number of possible values can be huge from a PS function. 1.2460 + var cache = new FunctionCache(); 1.2461 + return function constructPostScriptFromIRResult(args) { 1.2462 + var initialStack = []; 1.2463 + for (var i = 0, ii = (domain.length / 2); i < ii; ++i) { 1.2464 + initialStack.push(args[i]); 1.2465 + } 1.2466 + 1.2467 + var key = initialStack.join('_'); 1.2468 + if (cache.has(key)) { 1.2469 + return cache.get(key); 1.2470 + } 1.2471 + 1.2472 + var stack = evaluator.execute(initialStack); 1.2473 + var transformed = []; 1.2474 + for (i = numOutputs - 1; i >= 0; --i) { 1.2475 + var out = stack.pop(); 1.2476 + var rangeIndex = 2 * i; 1.2477 + if (out < range[rangeIndex]) { 1.2478 + out = range[rangeIndex]; 1.2479 + } else if (out > range[rangeIndex + 1]) { 1.2480 + out = range[rangeIndex + 1]; 1.2481 + } 1.2482 + transformed[i] = out; 1.2483 + } 1.2484 + cache.set(key, transformed); 1.2485 + return transformed; 1.2486 + }; 1.2487 + } 1.2488 + }; 1.2489 +})(); 1.2490 + 1.2491 +var FunctionCache = (function FunctionCacheClosure() { 1.2492 + // Of 10 PDF's with type4 functions the maxium number of distinct values seen 1.2493 + // was 256. This still may need some tweaking in the future though. 1.2494 + var MAX_CACHE_SIZE = 1024; 1.2495 + function FunctionCache() { 1.2496 + this.cache = {}; 1.2497 + this.total = 0; 1.2498 + } 1.2499 + FunctionCache.prototype = { 1.2500 + has: function FunctionCache_has(key) { 1.2501 + return key in this.cache; 1.2502 + }, 1.2503 + get: function FunctionCache_get(key) { 1.2504 + return this.cache[key]; 1.2505 + }, 1.2506 + set: function FunctionCache_set(key, value) { 1.2507 + if (this.total < MAX_CACHE_SIZE) { 1.2508 + this.cache[key] = value; 1.2509 + this.total++; 1.2510 + } 1.2511 + } 1.2512 + }; 1.2513 + return FunctionCache; 1.2514 +})(); 1.2515 + 1.2516 +var PostScriptStack = (function PostScriptStackClosure() { 1.2517 + var MAX_STACK_SIZE = 100; 1.2518 + function PostScriptStack(initialStack) { 1.2519 + this.stack = initialStack || []; 1.2520 + } 1.2521 + 1.2522 + PostScriptStack.prototype = { 1.2523 + push: function PostScriptStack_push(value) { 1.2524 + if (this.stack.length >= MAX_STACK_SIZE) { 1.2525 + error('PostScript function stack overflow.'); 1.2526 + } 1.2527 + this.stack.push(value); 1.2528 + }, 1.2529 + pop: function PostScriptStack_pop() { 1.2530 + if (this.stack.length <= 0) { 1.2531 + error('PostScript function stack underflow.'); 1.2532 + } 1.2533 + return this.stack.pop(); 1.2534 + }, 1.2535 + copy: function PostScriptStack_copy(n) { 1.2536 + if (this.stack.length + n >= MAX_STACK_SIZE) { 1.2537 + error('PostScript function stack overflow.'); 1.2538 + } 1.2539 + var stack = this.stack; 1.2540 + for (var i = stack.length - n, j = n - 1; j >= 0; j--, i++) { 1.2541 + stack.push(stack[i]); 1.2542 + } 1.2543 + }, 1.2544 + index: function PostScriptStack_index(n) { 1.2545 + this.push(this.stack[this.stack.length - n - 1]); 1.2546 + }, 1.2547 + // rotate the last n stack elements p times 1.2548 + roll: function PostScriptStack_roll(n, p) { 1.2549 + var stack = this.stack; 1.2550 + var l = stack.length - n; 1.2551 + var r = stack.length - 1, c = l + (p - Math.floor(p / n) * n), i, j, t; 1.2552 + for (i = l, j = r; i < j; i++, j--) { 1.2553 + t = stack[i]; stack[i] = stack[j]; stack[j] = t; 1.2554 + } 1.2555 + for (i = l, j = c - 1; i < j; i++, j--) { 1.2556 + t = stack[i]; stack[i] = stack[j]; stack[j] = t; 1.2557 + } 1.2558 + for (i = c, j = r; i < j; i++, j--) { 1.2559 + t = stack[i]; stack[i] = stack[j]; stack[j] = t; 1.2560 + } 1.2561 + } 1.2562 + }; 1.2563 + return PostScriptStack; 1.2564 +})(); 1.2565 +var PostScriptEvaluator = (function PostScriptEvaluatorClosure() { 1.2566 + function PostScriptEvaluator(operators) { 1.2567 + this.operators = operators; 1.2568 + } 1.2569 + PostScriptEvaluator.prototype = { 1.2570 + execute: function PostScriptEvaluator_execute(initialStack) { 1.2571 + var stack = new PostScriptStack(initialStack); 1.2572 + var counter = 0; 1.2573 + var operators = this.operators; 1.2574 + var length = operators.length; 1.2575 + var operator, a, b; 1.2576 + while (counter < length) { 1.2577 + operator = operators[counter++]; 1.2578 + if (typeof operator == 'number') { 1.2579 + // Operator is really an operand and should be pushed to the stack. 1.2580 + stack.push(operator); 1.2581 + continue; 1.2582 + } 1.2583 + switch (operator) { 1.2584 + // non standard ps operators 1.2585 + case 'jz': // jump if false 1.2586 + b = stack.pop(); 1.2587 + a = stack.pop(); 1.2588 + if (!a) { 1.2589 + counter = b; 1.2590 + } 1.2591 + break; 1.2592 + case 'j': // jump 1.2593 + a = stack.pop(); 1.2594 + counter = a; 1.2595 + break; 1.2596 + 1.2597 + // all ps operators in alphabetical order (excluding if/ifelse) 1.2598 + case 'abs': 1.2599 + a = stack.pop(); 1.2600 + stack.push(Math.abs(a)); 1.2601 + break; 1.2602 + case 'add': 1.2603 + b = stack.pop(); 1.2604 + a = stack.pop(); 1.2605 + stack.push(a + b); 1.2606 + break; 1.2607 + case 'and': 1.2608 + b = stack.pop(); 1.2609 + a = stack.pop(); 1.2610 + if (isBool(a) && isBool(b)) { 1.2611 + stack.push(a && b); 1.2612 + } else { 1.2613 + stack.push(a & b); 1.2614 + } 1.2615 + break; 1.2616 + case 'atan': 1.2617 + a = stack.pop(); 1.2618 + stack.push(Math.atan(a)); 1.2619 + break; 1.2620 + case 'bitshift': 1.2621 + b = stack.pop(); 1.2622 + a = stack.pop(); 1.2623 + if (a > 0) { 1.2624 + stack.push(a << b); 1.2625 + } else { 1.2626 + stack.push(a >> b); 1.2627 + } 1.2628 + break; 1.2629 + case 'ceiling': 1.2630 + a = stack.pop(); 1.2631 + stack.push(Math.ceil(a)); 1.2632 + break; 1.2633 + case 'copy': 1.2634 + a = stack.pop(); 1.2635 + stack.copy(a); 1.2636 + break; 1.2637 + case 'cos': 1.2638 + a = stack.pop(); 1.2639 + stack.push(Math.cos(a)); 1.2640 + break; 1.2641 + case 'cvi': 1.2642 + a = stack.pop() | 0; 1.2643 + stack.push(a); 1.2644 + break; 1.2645 + case 'cvr': 1.2646 + // noop 1.2647 + break; 1.2648 + case 'div': 1.2649 + b = stack.pop(); 1.2650 + a = stack.pop(); 1.2651 + stack.push(a / b); 1.2652 + break; 1.2653 + case 'dup': 1.2654 + stack.copy(1); 1.2655 + break; 1.2656 + case 'eq': 1.2657 + b = stack.pop(); 1.2658 + a = stack.pop(); 1.2659 + stack.push(a == b); 1.2660 + break; 1.2661 + case 'exch': 1.2662 + stack.roll(2, 1); 1.2663 + break; 1.2664 + case 'exp': 1.2665 + b = stack.pop(); 1.2666 + a = stack.pop(); 1.2667 + stack.push(Math.pow(a, b)); 1.2668 + break; 1.2669 + case 'false': 1.2670 + stack.push(false); 1.2671 + break; 1.2672 + case 'floor': 1.2673 + a = stack.pop(); 1.2674 + stack.push(Math.floor(a)); 1.2675 + break; 1.2676 + case 'ge': 1.2677 + b = stack.pop(); 1.2678 + a = stack.pop(); 1.2679 + stack.push(a >= b); 1.2680 + break; 1.2681 + case 'gt': 1.2682 + b = stack.pop(); 1.2683 + a = stack.pop(); 1.2684 + stack.push(a > b); 1.2685 + break; 1.2686 + case 'idiv': 1.2687 + b = stack.pop(); 1.2688 + a = stack.pop(); 1.2689 + stack.push((a / b) | 0); 1.2690 + break; 1.2691 + case 'index': 1.2692 + a = stack.pop(); 1.2693 + stack.index(a); 1.2694 + break; 1.2695 + case 'le': 1.2696 + b = stack.pop(); 1.2697 + a = stack.pop(); 1.2698 + stack.push(a <= b); 1.2699 + break; 1.2700 + case 'ln': 1.2701 + a = stack.pop(); 1.2702 + stack.push(Math.log(a)); 1.2703 + break; 1.2704 + case 'log': 1.2705 + a = stack.pop(); 1.2706 + stack.push(Math.log(a) / Math.LN10); 1.2707 + break; 1.2708 + case 'lt': 1.2709 + b = stack.pop(); 1.2710 + a = stack.pop(); 1.2711 + stack.push(a < b); 1.2712 + break; 1.2713 + case 'mod': 1.2714 + b = stack.pop(); 1.2715 + a = stack.pop(); 1.2716 + stack.push(a % b); 1.2717 + break; 1.2718 + case 'mul': 1.2719 + b = stack.pop(); 1.2720 + a = stack.pop(); 1.2721 + stack.push(a * b); 1.2722 + break; 1.2723 + case 'ne': 1.2724 + b = stack.pop(); 1.2725 + a = stack.pop(); 1.2726 + stack.push(a != b); 1.2727 + break; 1.2728 + case 'neg': 1.2729 + a = stack.pop(); 1.2730 + stack.push(-b); 1.2731 + break; 1.2732 + case 'not': 1.2733 + a = stack.pop(); 1.2734 + if (isBool(a) && isBool(b)) { 1.2735 + stack.push(a && b); 1.2736 + } else { 1.2737 + stack.push(a & b); 1.2738 + } 1.2739 + break; 1.2740 + case 'or': 1.2741 + b = stack.pop(); 1.2742 + a = stack.pop(); 1.2743 + if (isBool(a) && isBool(b)) { 1.2744 + stack.push(a || b); 1.2745 + } else { 1.2746 + stack.push(a | b); 1.2747 + } 1.2748 + break; 1.2749 + case 'pop': 1.2750 + stack.pop(); 1.2751 + break; 1.2752 + case 'roll': 1.2753 + b = stack.pop(); 1.2754 + a = stack.pop(); 1.2755 + stack.roll(a, b); 1.2756 + break; 1.2757 + case 'round': 1.2758 + a = stack.pop(); 1.2759 + stack.push(Math.round(a)); 1.2760 + break; 1.2761 + case 'sin': 1.2762 + a = stack.pop(); 1.2763 + stack.push(Math.sin(a)); 1.2764 + break; 1.2765 + case 'sqrt': 1.2766 + a = stack.pop(); 1.2767 + stack.push(Math.sqrt(a)); 1.2768 + break; 1.2769 + case 'sub': 1.2770 + b = stack.pop(); 1.2771 + a = stack.pop(); 1.2772 + stack.push(a - b); 1.2773 + break; 1.2774 + case 'true': 1.2775 + stack.push(true); 1.2776 + break; 1.2777 + case 'truncate': 1.2778 + a = stack.pop(); 1.2779 + a = a < 0 ? Math.ceil(a) : Math.floor(a); 1.2780 + stack.push(a); 1.2781 + break; 1.2782 + case 'xor': 1.2783 + b = stack.pop(); 1.2784 + a = stack.pop(); 1.2785 + if (isBool(a) && isBool(b)) { 1.2786 + stack.push(a != b); 1.2787 + } else { 1.2788 + stack.push(a ^ b); 1.2789 + } 1.2790 + break; 1.2791 + default: 1.2792 + error('Unknown operator ' + operator); 1.2793 + break; 1.2794 + } 1.2795 + } 1.2796 + return stack.stack; 1.2797 + } 1.2798 + }; 1.2799 + return PostScriptEvaluator; 1.2800 +})(); 1.2801 + 1.2802 + 1.2803 +var HIGHLIGHT_OFFSET = 4; // px 1.2804 +var SUPPORTED_TYPES = ['Link', 'Text', 'Widget']; 1.2805 + 1.2806 +var Annotation = (function AnnotationClosure() { 1.2807 + // 12.5.5: Algorithm: Appearance streams 1.2808 + function getTransformMatrix(rect, bbox, matrix) { 1.2809 + var bounds = Util.getAxialAlignedBoundingBox(bbox, matrix); 1.2810 + var minX = bounds[0]; 1.2811 + var minY = bounds[1]; 1.2812 + var maxX = bounds[2]; 1.2813 + var maxY = bounds[3]; 1.2814 + 1.2815 + if (minX === maxX || minY === maxY) { 1.2816 + // From real-life file, bbox was [0, 0, 0, 0]. In this case, 1.2817 + // just apply the transform for rect 1.2818 + return [1, 0, 0, 1, rect[0], rect[1]]; 1.2819 + } 1.2820 + 1.2821 + var xRatio = (rect[2] - rect[0]) / (maxX - minX); 1.2822 + var yRatio = (rect[3] - rect[1]) / (maxY - minY); 1.2823 + return [ 1.2824 + xRatio, 1.2825 + 0, 1.2826 + 0, 1.2827 + yRatio, 1.2828 + rect[0] - minX * xRatio, 1.2829 + rect[1] - minY * yRatio 1.2830 + ]; 1.2831 + } 1.2832 + 1.2833 + function getDefaultAppearance(dict) { 1.2834 + var appearanceState = dict.get('AP'); 1.2835 + if (!isDict(appearanceState)) { 1.2836 + return; 1.2837 + } 1.2838 + 1.2839 + var appearance; 1.2840 + var appearances = appearanceState.get('N'); 1.2841 + if (isDict(appearances)) { 1.2842 + var as = dict.get('AS'); 1.2843 + if (as && appearances.has(as.name)) { 1.2844 + appearance = appearances.get(as.name); 1.2845 + } 1.2846 + } else { 1.2847 + appearance = appearances; 1.2848 + } 1.2849 + return appearance; 1.2850 + } 1.2851 + 1.2852 + function Annotation(params) { 1.2853 + if (params.data) { 1.2854 + this.data = params.data; 1.2855 + return; 1.2856 + } 1.2857 + 1.2858 + var dict = params.dict; 1.2859 + var data = this.data = {}; 1.2860 + 1.2861 + data.subtype = dict.get('Subtype').name; 1.2862 + var rect = dict.get('Rect') || [0, 0, 0, 0]; 1.2863 + data.rect = Util.normalizeRect(rect); 1.2864 + data.annotationFlags = dict.get('F'); 1.2865 + 1.2866 + var color = dict.get('C'); 1.2867 + if (isArray(color) && color.length === 3) { 1.2868 + // TODO(mack): currently only supporting rgb; need support different 1.2869 + // colorspaces 1.2870 + data.color = color; 1.2871 + } else { 1.2872 + data.color = [0, 0, 0]; 1.2873 + } 1.2874 + 1.2875 + // Some types of annotations have border style dict which has more 1.2876 + // info than the border array 1.2877 + if (dict.has('BS')) { 1.2878 + var borderStyle = dict.get('BS'); 1.2879 + data.borderWidth = borderStyle.has('W') ? borderStyle.get('W') : 1; 1.2880 + } else { 1.2881 + var borderArray = dict.get('Border') || [0, 0, 1]; 1.2882 + data.borderWidth = borderArray[2] || 0; 1.2883 + 1.2884 + // TODO: implement proper support for annotations with line dash patterns. 1.2885 + var dashArray = borderArray[3]; 1.2886 + if (data.borderWidth > 0 && dashArray && isArray(dashArray)) { 1.2887 + var dashArrayLength = dashArray.length; 1.2888 + if (dashArrayLength > 0) { 1.2889 + // According to the PDF specification: the elements in a dashArray 1.2890 + // shall be numbers that are nonnegative and not all equal to zero. 1.2891 + var isInvalid = false; 1.2892 + var numPositive = 0; 1.2893 + for (var i = 0; i < dashArrayLength; i++) { 1.2894 + var validNumber = (+dashArray[i] >= 0); 1.2895 + if (!validNumber) { 1.2896 + isInvalid = true; 1.2897 + break; 1.2898 + } else if (dashArray[i] > 0) { 1.2899 + numPositive++; 1.2900 + } 1.2901 + } 1.2902 + if (isInvalid || numPositive === 0) { 1.2903 + data.borderWidth = 0; 1.2904 + } 1.2905 + } 1.2906 + } 1.2907 + } 1.2908 + 1.2909 + this.appearance = getDefaultAppearance(dict); 1.2910 + data.hasAppearance = !!this.appearance; 1.2911 + data.id = params.ref.num; 1.2912 + } 1.2913 + 1.2914 + Annotation.prototype = { 1.2915 + 1.2916 + getData: function Annotation_getData() { 1.2917 + return this.data; 1.2918 + }, 1.2919 + 1.2920 + hasHtml: function Annotation_hasHtml() { 1.2921 + return false; 1.2922 + }, 1.2923 + 1.2924 + getHtmlElement: function Annotation_getHtmlElement(commonObjs) { 1.2925 + throw new NotImplementedException( 1.2926 + 'getHtmlElement() should be implemented in subclass'); 1.2927 + }, 1.2928 + 1.2929 + // TODO(mack): Remove this, it's not really that helpful. 1.2930 + getEmptyContainer: function Annotation_getEmptyContainer(tagName, rect, 1.2931 + borderWidth) { 1.2932 + assert(!isWorker, 1.2933 + 'getEmptyContainer() should be called from main thread'); 1.2934 + 1.2935 + var bWidth = borderWidth || 0; 1.2936 + 1.2937 + rect = rect || this.data.rect; 1.2938 + var element = document.createElement(tagName); 1.2939 + element.style.borderWidth = bWidth + 'px'; 1.2940 + var width = rect[2] - rect[0] - 2 * bWidth; 1.2941 + var height = rect[3] - rect[1] - 2 * bWidth; 1.2942 + element.style.width = width + 'px'; 1.2943 + element.style.height = height + 'px'; 1.2944 + return element; 1.2945 + }, 1.2946 + 1.2947 + isInvisible: function Annotation_isInvisible() { 1.2948 + var data = this.data; 1.2949 + if (data && SUPPORTED_TYPES.indexOf(data.subtype) !== -1) { 1.2950 + return false; 1.2951 + } else { 1.2952 + return !!(data && 1.2953 + data.annotationFlags && // Default: not invisible 1.2954 + data.annotationFlags & 0x1); // Invisible 1.2955 + } 1.2956 + }, 1.2957 + 1.2958 + isViewable: function Annotation_isViewable() { 1.2959 + var data = this.data; 1.2960 + return !!(!this.isInvisible() && 1.2961 + data && 1.2962 + (!data.annotationFlags || 1.2963 + !(data.annotationFlags & 0x22)) && // Hidden or NoView 1.2964 + data.rect); // rectangle is nessessary 1.2965 + }, 1.2966 + 1.2967 + isPrintable: function Annotation_isPrintable() { 1.2968 + var data = this.data; 1.2969 + return !!(!this.isInvisible() && 1.2970 + data && 1.2971 + data.annotationFlags && // Default: not printable 1.2972 + data.annotationFlags & 0x4 && // Print 1.2973 + data.rect); // rectangle is nessessary 1.2974 + }, 1.2975 + 1.2976 + loadResources: function(keys) { 1.2977 + var promise = new LegacyPromise(); 1.2978 + this.appearance.dict.getAsync('Resources').then(function(resources) { 1.2979 + if (!resources) { 1.2980 + promise.resolve(); 1.2981 + return; 1.2982 + } 1.2983 + var objectLoader = new ObjectLoader(resources.map, 1.2984 + keys, 1.2985 + resources.xref); 1.2986 + objectLoader.load().then(function() { 1.2987 + promise.resolve(resources); 1.2988 + }); 1.2989 + }.bind(this)); 1.2990 + 1.2991 + return promise; 1.2992 + }, 1.2993 + 1.2994 + getOperatorList: function Annotation_getOperatorList(evaluator) { 1.2995 + 1.2996 + var promise = new LegacyPromise(); 1.2997 + 1.2998 + if (!this.appearance) { 1.2999 + promise.resolve(new OperatorList()); 1.3000 + return promise; 1.3001 + } 1.3002 + 1.3003 + var data = this.data; 1.3004 + 1.3005 + var appearanceDict = this.appearance.dict; 1.3006 + var resourcesPromise = this.loadResources([ 1.3007 + 'ExtGState', 1.3008 + 'ColorSpace', 1.3009 + 'Pattern', 1.3010 + 'Shading', 1.3011 + 'XObject', 1.3012 + 'Font' 1.3013 + // ProcSet 1.3014 + // Properties 1.3015 + ]); 1.3016 + var bbox = appearanceDict.get('BBox') || [0, 0, 1, 1]; 1.3017 + var matrix = appearanceDict.get('Matrix') || [1, 0, 0, 1, 0 ,0]; 1.3018 + var transform = getTransformMatrix(data.rect, bbox, matrix); 1.3019 + 1.3020 + resourcesPromise.then(function(resources) { 1.3021 + var opList = new OperatorList(); 1.3022 + opList.addOp(OPS.beginAnnotation, [data.rect, transform, matrix]); 1.3023 + evaluator.getOperatorList(this.appearance, resources, opList); 1.3024 + opList.addOp(OPS.endAnnotation, []); 1.3025 + promise.resolve(opList); 1.3026 + 1.3027 + this.appearance.reset(); 1.3028 + }.bind(this)); 1.3029 + 1.3030 + return promise; 1.3031 + } 1.3032 + }; 1.3033 + 1.3034 + Annotation.getConstructor = 1.3035 + function Annotation_getConstructor(subtype, fieldType) { 1.3036 + 1.3037 + if (!subtype) { 1.3038 + return; 1.3039 + } 1.3040 + 1.3041 + // TODO(mack): Implement FreeText annotations 1.3042 + if (subtype === 'Link') { 1.3043 + return LinkAnnotation; 1.3044 + } else if (subtype === 'Text') { 1.3045 + return TextAnnotation; 1.3046 + } else if (subtype === 'Widget') { 1.3047 + if (!fieldType) { 1.3048 + return; 1.3049 + } 1.3050 + 1.3051 + if (fieldType === 'Tx') { 1.3052 + return TextWidgetAnnotation; 1.3053 + } else { 1.3054 + return WidgetAnnotation; 1.3055 + } 1.3056 + } else { 1.3057 + return Annotation; 1.3058 + } 1.3059 + }; 1.3060 + 1.3061 + // TODO(mack): Support loading annotation from data 1.3062 + Annotation.fromData = function Annotation_fromData(data) { 1.3063 + var subtype = data.subtype; 1.3064 + var fieldType = data.fieldType; 1.3065 + var Constructor = Annotation.getConstructor(subtype, fieldType); 1.3066 + if (Constructor) { 1.3067 + return new Constructor({ data: data }); 1.3068 + } 1.3069 + }; 1.3070 + 1.3071 + Annotation.fromRef = function Annotation_fromRef(xref, ref) { 1.3072 + 1.3073 + var dict = xref.fetchIfRef(ref); 1.3074 + if (!isDict(dict)) { 1.3075 + return; 1.3076 + } 1.3077 + 1.3078 + var subtype = dict.get('Subtype'); 1.3079 + subtype = isName(subtype) ? subtype.name : ''; 1.3080 + if (!subtype) { 1.3081 + return; 1.3082 + } 1.3083 + 1.3084 + var fieldType = Util.getInheritableProperty(dict, 'FT'); 1.3085 + fieldType = isName(fieldType) ? fieldType.name : ''; 1.3086 + 1.3087 + var Constructor = Annotation.getConstructor(subtype, fieldType); 1.3088 + if (!Constructor) { 1.3089 + return; 1.3090 + } 1.3091 + 1.3092 + var params = { 1.3093 + dict: dict, 1.3094 + ref: ref, 1.3095 + }; 1.3096 + 1.3097 + var annotation = new Constructor(params); 1.3098 + 1.3099 + if (annotation.isViewable() || annotation.isPrintable()) { 1.3100 + return annotation; 1.3101 + } else { 1.3102 + warn('unimplemented annotation type: ' + subtype); 1.3103 + } 1.3104 + }; 1.3105 + 1.3106 + Annotation.appendToOperatorList = function Annotation_appendToOperatorList( 1.3107 + annotations, opList, pdfManager, partialEvaluator, intent) { 1.3108 + 1.3109 + function reject(e) { 1.3110 + annotationsReadyPromise.reject(e); 1.3111 + } 1.3112 + 1.3113 + var annotationsReadyPromise = new LegacyPromise(); 1.3114 + 1.3115 + var annotationPromises = []; 1.3116 + for (var i = 0, n = annotations.length; i < n; ++i) { 1.3117 + if (intent === 'display' && annotations[i].isViewable() || 1.3118 + intent === 'print' && annotations[i].isPrintable()) { 1.3119 + annotationPromises.push( 1.3120 + annotations[i].getOperatorList(partialEvaluator)); 1.3121 + } 1.3122 + } 1.3123 + Promise.all(annotationPromises).then(function(datas) { 1.3124 + opList.addOp(OPS.beginAnnotations, []); 1.3125 + for (var i = 0, n = datas.length; i < n; ++i) { 1.3126 + var annotOpList = datas[i]; 1.3127 + opList.addOpList(annotOpList); 1.3128 + } 1.3129 + opList.addOp(OPS.endAnnotations, []); 1.3130 + annotationsReadyPromise.resolve(); 1.3131 + }, reject); 1.3132 + 1.3133 + return annotationsReadyPromise; 1.3134 + }; 1.3135 + 1.3136 + return Annotation; 1.3137 +})(); 1.3138 +PDFJS.Annotation = Annotation; 1.3139 + 1.3140 + 1.3141 +var WidgetAnnotation = (function WidgetAnnotationClosure() { 1.3142 + 1.3143 + function WidgetAnnotation(params) { 1.3144 + Annotation.call(this, params); 1.3145 + 1.3146 + if (params.data) { 1.3147 + return; 1.3148 + } 1.3149 + 1.3150 + var dict = params.dict; 1.3151 + var data = this.data; 1.3152 + 1.3153 + data.fieldValue = stringToPDFString( 1.3154 + Util.getInheritableProperty(dict, 'V') || ''); 1.3155 + data.alternativeText = stringToPDFString(dict.get('TU') || ''); 1.3156 + data.defaultAppearance = Util.getInheritableProperty(dict, 'DA') || ''; 1.3157 + var fieldType = Util.getInheritableProperty(dict, 'FT'); 1.3158 + data.fieldType = isName(fieldType) ? fieldType.name : ''; 1.3159 + data.fieldFlags = Util.getInheritableProperty(dict, 'Ff') || 0; 1.3160 + this.fieldResources = Util.getInheritableProperty(dict, 'DR') || Dict.empty; 1.3161 + 1.3162 + // Building the full field name by collecting the field and 1.3163 + // its ancestors 'T' data and joining them using '.'. 1.3164 + var fieldName = []; 1.3165 + var namedItem = dict; 1.3166 + var ref = params.ref; 1.3167 + while (namedItem) { 1.3168 + var parent = namedItem.get('Parent'); 1.3169 + var parentRef = namedItem.getRaw('Parent'); 1.3170 + var name = namedItem.get('T'); 1.3171 + if (name) { 1.3172 + fieldName.unshift(stringToPDFString(name)); 1.3173 + } else { 1.3174 + // The field name is absent, that means more than one field 1.3175 + // with the same name may exist. Replacing the empty name 1.3176 + // with the '`' plus index in the parent's 'Kids' array. 1.3177 + // This is not in the PDF spec but necessary to id the 1.3178 + // the input controls. 1.3179 + var kids = parent.get('Kids'); 1.3180 + var j, jj; 1.3181 + for (j = 0, jj = kids.length; j < jj; j++) { 1.3182 + var kidRef = kids[j]; 1.3183 + if (kidRef.num == ref.num && kidRef.gen == ref.gen) { 1.3184 + break; 1.3185 + } 1.3186 + } 1.3187 + fieldName.unshift('`' + j); 1.3188 + } 1.3189 + namedItem = parent; 1.3190 + ref = parentRef; 1.3191 + } 1.3192 + data.fullName = fieldName.join('.'); 1.3193 + } 1.3194 + 1.3195 + var parent = Annotation.prototype; 1.3196 + Util.inherit(WidgetAnnotation, Annotation, { 1.3197 + isViewable: function WidgetAnnotation_isViewable() { 1.3198 + if (this.data.fieldType === 'Sig') { 1.3199 + warn('unimplemented annotation type: Widget signature'); 1.3200 + return false; 1.3201 + } 1.3202 + 1.3203 + return parent.isViewable.call(this); 1.3204 + } 1.3205 + }); 1.3206 + 1.3207 + return WidgetAnnotation; 1.3208 +})(); 1.3209 + 1.3210 +var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() { 1.3211 + function TextWidgetAnnotation(params) { 1.3212 + WidgetAnnotation.call(this, params); 1.3213 + 1.3214 + if (params.data) { 1.3215 + return; 1.3216 + } 1.3217 + 1.3218 + this.data.textAlignment = Util.getInheritableProperty(params.dict, 'Q'); 1.3219 + } 1.3220 + 1.3221 + // TODO(mack): This dupes some of the logic in CanvasGraphics.setFont() 1.3222 + function setTextStyles(element, item, fontObj) { 1.3223 + 1.3224 + var style = element.style; 1.3225 + style.fontSize = item.fontSize + 'px'; 1.3226 + style.direction = item.fontDirection < 0 ? 'rtl': 'ltr'; 1.3227 + 1.3228 + if (!fontObj) { 1.3229 + return; 1.3230 + } 1.3231 + 1.3232 + style.fontWeight = fontObj.black ? 1.3233 + (fontObj.bold ? 'bolder' : 'bold') : 1.3234 + (fontObj.bold ? 'bold' : 'normal'); 1.3235 + style.fontStyle = fontObj.italic ? 'italic' : 'normal'; 1.3236 + 1.3237 + var fontName = fontObj.loadedName; 1.3238 + var fontFamily = fontName ? '"' + fontName + '", ' : ''; 1.3239 + // Use a reasonable default font if the font doesn't specify a fallback 1.3240 + var fallbackName = fontObj.fallbackName || 'Helvetica, sans-serif'; 1.3241 + style.fontFamily = fontFamily + fallbackName; 1.3242 + } 1.3243 + 1.3244 + 1.3245 + Util.inherit(TextWidgetAnnotation, WidgetAnnotation, { 1.3246 + hasHtml: function TextWidgetAnnotation_hasHtml() { 1.3247 + return !this.data.hasAppearance && !!this.data.fieldValue; 1.3248 + }, 1.3249 + 1.3250 + getHtmlElement: function TextWidgetAnnotation_getHtmlElement(commonObjs) { 1.3251 + assert(!isWorker, 'getHtmlElement() shall be called from main thread'); 1.3252 + 1.3253 + var item = this.data; 1.3254 + 1.3255 + var element = this.getEmptyContainer('div'); 1.3256 + element.style.display = 'table'; 1.3257 + 1.3258 + var content = document.createElement('div'); 1.3259 + content.textContent = item.fieldValue; 1.3260 + var textAlignment = item.textAlignment; 1.3261 + content.style.textAlign = ['left', 'center', 'right'][textAlignment]; 1.3262 + content.style.verticalAlign = 'middle'; 1.3263 + content.style.display = 'table-cell'; 1.3264 + 1.3265 + var fontObj = item.fontRefName ? 1.3266 + commonObjs.getData(item.fontRefName) : null; 1.3267 + setTextStyles(content, item, fontObj); 1.3268 + 1.3269 + element.appendChild(content); 1.3270 + 1.3271 + return element; 1.3272 + }, 1.3273 + 1.3274 + getOperatorList: function TextWidgetAnnotation_getOperatorList(evaluator) { 1.3275 + if (this.appearance) { 1.3276 + return Annotation.prototype.getOperatorList.call(this, evaluator); 1.3277 + } 1.3278 + 1.3279 + var promise = new LegacyPromise(); 1.3280 + var opList = new OperatorList(); 1.3281 + var data = this.data; 1.3282 + 1.3283 + // Even if there is an appearance stream, ignore it. This is the 1.3284 + // behaviour used by Adobe Reader. 1.3285 + 1.3286 + var defaultAppearance = data.defaultAppearance; 1.3287 + if (!defaultAppearance) { 1.3288 + promise.resolve(opList); 1.3289 + return promise; 1.3290 + } 1.3291 + 1.3292 + // Include any font resources found in the default appearance 1.3293 + 1.3294 + var stream = new Stream(stringToBytes(defaultAppearance)); 1.3295 + evaluator.getOperatorList(stream, this.fieldResources, opList); 1.3296 + var appearanceFnArray = opList.fnArray; 1.3297 + var appearanceArgsArray = opList.argsArray; 1.3298 + var fnArray = []; 1.3299 + 1.3300 + // TODO(mack): Add support for stroke color 1.3301 + data.rgb = [0, 0, 0]; 1.3302 + // TODO THIS DOESN'T MAKE ANY SENSE SINCE THE fnArray IS EMPTY! 1.3303 + for (var i = 0, n = fnArray.length; i < n; ++i) { 1.3304 + var fnId = appearanceFnArray[i]; 1.3305 + var args = appearanceArgsArray[i]; 1.3306 + 1.3307 + if (fnId === OPS.setFont) { 1.3308 + data.fontRefName = args[0]; 1.3309 + var size = args[1]; 1.3310 + if (size < 0) { 1.3311 + data.fontDirection = -1; 1.3312 + data.fontSize = -size; 1.3313 + } else { 1.3314 + data.fontDirection = 1; 1.3315 + data.fontSize = size; 1.3316 + } 1.3317 + } else if (fnId === OPS.setFillRGBColor) { 1.3318 + data.rgb = args; 1.3319 + } else if (fnId === OPS.setFillGray) { 1.3320 + var rgbValue = args[0] * 255; 1.3321 + data.rgb = [rgbValue, rgbValue, rgbValue]; 1.3322 + } 1.3323 + } 1.3324 + promise.resolve(opList); 1.3325 + return promise; 1.3326 + } 1.3327 + }); 1.3328 + 1.3329 + return TextWidgetAnnotation; 1.3330 +})(); 1.3331 + 1.3332 +var InteractiveAnnotation = (function InteractiveAnnotationClosure() { 1.3333 + function InteractiveAnnotation(params) { 1.3334 + Annotation.call(this, params); 1.3335 + } 1.3336 + 1.3337 + Util.inherit(InteractiveAnnotation, Annotation, { 1.3338 + hasHtml: function InteractiveAnnotation_hasHtml() { 1.3339 + return true; 1.3340 + }, 1.3341 + 1.3342 + highlight: function InteractiveAnnotation_highlight() { 1.3343 + if (this.highlightElement && 1.3344 + this.highlightElement.hasAttribute('hidden')) { 1.3345 + this.highlightElement.removeAttribute('hidden'); 1.3346 + } 1.3347 + }, 1.3348 + 1.3349 + unhighlight: function InteractiveAnnotation_unhighlight() { 1.3350 + if (this.highlightElement && 1.3351 + !this.highlightElement.hasAttribute('hidden')) { 1.3352 + this.highlightElement.setAttribute('hidden', true); 1.3353 + } 1.3354 + }, 1.3355 + 1.3356 + initContainer: function InteractiveAnnotation_initContainer() { 1.3357 + 1.3358 + var item = this.data; 1.3359 + var rect = item.rect; 1.3360 + 1.3361 + var container = this.getEmptyContainer('section', rect, item.borderWidth); 1.3362 + container.style.backgroundColor = item.color; 1.3363 + 1.3364 + var color = item.color; 1.3365 + var rgb = []; 1.3366 + for (var i = 0; i < 3; ++i) { 1.3367 + rgb[i] = Math.round(color[i] * 255); 1.3368 + } 1.3369 + item.colorCssRgb = Util.makeCssRgb(rgb); 1.3370 + 1.3371 + var highlight = document.createElement('div'); 1.3372 + highlight.className = 'annotationHighlight'; 1.3373 + highlight.style.left = highlight.style.top = -HIGHLIGHT_OFFSET + 'px'; 1.3374 + highlight.style.right = highlight.style.bottom = -HIGHLIGHT_OFFSET + 'px'; 1.3375 + highlight.setAttribute('hidden', true); 1.3376 + 1.3377 + this.highlightElement = highlight; 1.3378 + container.appendChild(this.highlightElement); 1.3379 + 1.3380 + return container; 1.3381 + } 1.3382 + }); 1.3383 + 1.3384 + return InteractiveAnnotation; 1.3385 +})(); 1.3386 + 1.3387 +var TextAnnotation = (function TextAnnotationClosure() { 1.3388 + function TextAnnotation(params) { 1.3389 + InteractiveAnnotation.call(this, params); 1.3390 + 1.3391 + if (params.data) { 1.3392 + return; 1.3393 + } 1.3394 + 1.3395 + var dict = params.dict; 1.3396 + var data = this.data; 1.3397 + 1.3398 + var content = dict.get('Contents'); 1.3399 + var title = dict.get('T'); 1.3400 + data.content = stringToPDFString(content || ''); 1.3401 + data.title = stringToPDFString(title || ''); 1.3402 + 1.3403 + if (data.hasAppearance) { 1.3404 + data.name = 'NoIcon'; 1.3405 + } else { 1.3406 + data.name = dict.has('Name') ? dict.get('Name').name : 'Note'; 1.3407 + } 1.3408 + 1.3409 + if (dict.has('C')) { 1.3410 + data.hasBgColor = true; 1.3411 + } 1.3412 + } 1.3413 + 1.3414 + var ANNOT_MIN_SIZE = 10; 1.3415 + 1.3416 + Util.inherit(TextAnnotation, InteractiveAnnotation, { 1.3417 + 1.3418 + getHtmlElement: function TextAnnotation_getHtmlElement(commonObjs) { 1.3419 + assert(!isWorker, 'getHtmlElement() shall be called from main thread'); 1.3420 + 1.3421 + var item = this.data; 1.3422 + var rect = item.rect; 1.3423 + 1.3424 + // sanity check because of OOo-generated PDFs 1.3425 + if ((rect[3] - rect[1]) < ANNOT_MIN_SIZE) { 1.3426 + rect[3] = rect[1] + ANNOT_MIN_SIZE; 1.3427 + } 1.3428 + if ((rect[2] - rect[0]) < ANNOT_MIN_SIZE) { 1.3429 + rect[2] = rect[0] + (rect[3] - rect[1]); // make it square 1.3430 + } 1.3431 + 1.3432 + var container = this.initContainer(); 1.3433 + container.className = 'annotText'; 1.3434 + 1.3435 + var image = document.createElement('img'); 1.3436 + image.style.height = container.style.height; 1.3437 + image.style.width = container.style.width; 1.3438 + var iconName = item.name; 1.3439 + image.src = PDFJS.imageResourcesPath + 'annotation-' + 1.3440 + iconName.toLowerCase() + '.svg'; 1.3441 + image.alt = '[{{type}} Annotation]'; 1.3442 + image.dataset.l10nId = 'text_annotation_type'; 1.3443 + image.dataset.l10nArgs = JSON.stringify({type: iconName}); 1.3444 + 1.3445 + var contentWrapper = document.createElement('div'); 1.3446 + contentWrapper.className = 'annotTextContentWrapper'; 1.3447 + contentWrapper.style.left = Math.floor(rect[2] - rect[0] + 5) + 'px'; 1.3448 + contentWrapper.style.top = '-10px'; 1.3449 + 1.3450 + var content = document.createElement('div'); 1.3451 + content.className = 'annotTextContent'; 1.3452 + content.setAttribute('hidden', true); 1.3453 + 1.3454 + var i, ii; 1.3455 + if (item.hasBgColor) { 1.3456 + var color = item.color; 1.3457 + var rgb = []; 1.3458 + for (i = 0; i < 3; ++i) { 1.3459 + // Enlighten the color (70%) 1.3460 + var c = Math.round(color[i] * 255); 1.3461 + rgb[i] = Math.round((255 - c) * 0.7) + c; 1.3462 + } 1.3463 + content.style.backgroundColor = Util.makeCssRgb(rgb); 1.3464 + } 1.3465 + 1.3466 + var title = document.createElement('h1'); 1.3467 + var text = document.createElement('p'); 1.3468 + title.textContent = item.title; 1.3469 + 1.3470 + if (!item.content && !item.title) { 1.3471 + content.setAttribute('hidden', true); 1.3472 + } else { 1.3473 + var e = document.createElement('span'); 1.3474 + var lines = item.content.split(/(?:\r\n?|\n)/); 1.3475 + for (i = 0, ii = lines.length; i < ii; ++i) { 1.3476 + var line = lines[i]; 1.3477 + e.appendChild(document.createTextNode(line)); 1.3478 + if (i < (ii - 1)) { 1.3479 + e.appendChild(document.createElement('br')); 1.3480 + } 1.3481 + } 1.3482 + text.appendChild(e); 1.3483 + 1.3484 + var pinned = false; 1.3485 + 1.3486 + var showAnnotation = function showAnnotation(pin) { 1.3487 + if (pin) { 1.3488 + pinned = true; 1.3489 + } 1.3490 + if (content.hasAttribute('hidden')) { 1.3491 + container.style.zIndex += 1; 1.3492 + content.removeAttribute('hidden'); 1.3493 + } 1.3494 + }; 1.3495 + 1.3496 + var hideAnnotation = function hideAnnotation(unpin) { 1.3497 + if (unpin) { 1.3498 + pinned = false; 1.3499 + } 1.3500 + if (!content.hasAttribute('hidden') && !pinned) { 1.3501 + container.style.zIndex -= 1; 1.3502 + content.setAttribute('hidden', true); 1.3503 + } 1.3504 + }; 1.3505 + 1.3506 + var toggleAnnotation = function toggleAnnotation() { 1.3507 + if (pinned) { 1.3508 + hideAnnotation(true); 1.3509 + } else { 1.3510 + showAnnotation(true); 1.3511 + } 1.3512 + }; 1.3513 + 1.3514 + image.addEventListener('click', function image_clickHandler() { 1.3515 + toggleAnnotation(); 1.3516 + }, false); 1.3517 + image.addEventListener('mouseover', function image_mouseOverHandler() { 1.3518 + showAnnotation(); 1.3519 + }, false); 1.3520 + image.addEventListener('mouseout', function image_mouseOutHandler() { 1.3521 + hideAnnotation(); 1.3522 + }, false); 1.3523 + 1.3524 + content.addEventListener('click', function content_clickHandler() { 1.3525 + hideAnnotation(true); 1.3526 + }, false); 1.3527 + } 1.3528 + 1.3529 + content.appendChild(title); 1.3530 + content.appendChild(text); 1.3531 + contentWrapper.appendChild(content); 1.3532 + container.appendChild(image); 1.3533 + container.appendChild(contentWrapper); 1.3534 + 1.3535 + return container; 1.3536 + } 1.3537 + }); 1.3538 + 1.3539 + return TextAnnotation; 1.3540 +})(); 1.3541 + 1.3542 +var LinkAnnotation = (function LinkAnnotationClosure() { 1.3543 + function LinkAnnotation(params) { 1.3544 + InteractiveAnnotation.call(this, params); 1.3545 + 1.3546 + if (params.data) { 1.3547 + return; 1.3548 + } 1.3549 + 1.3550 + var dict = params.dict; 1.3551 + var data = this.data; 1.3552 + 1.3553 + var action = dict.get('A'); 1.3554 + if (action) { 1.3555 + var linkType = action.get('S').name; 1.3556 + if (linkType === 'URI') { 1.3557 + var url = action.get('URI'); 1.3558 + if (isName(url)) { 1.3559 + // Some bad PDFs do not put parentheses around relative URLs. 1.3560 + url = '/' + url.name; 1.3561 + } else if (url) { 1.3562 + url = addDefaultProtocolToUrl(url); 1.3563 + } 1.3564 + // TODO: pdf spec mentions urls can be relative to a Base 1.3565 + // entry in the dictionary. 1.3566 + if (!isValidUrl(url, false)) { 1.3567 + url = ''; 1.3568 + } 1.3569 + data.url = url; 1.3570 + } else if (linkType === 'GoTo') { 1.3571 + data.dest = action.get('D'); 1.3572 + } else if (linkType === 'GoToR') { 1.3573 + var urlDict = action.get('F'); 1.3574 + if (isDict(urlDict)) { 1.3575 + // We assume that the 'url' is a Filspec dictionary 1.3576 + // and fetch the url without checking any further 1.3577 + url = urlDict.get('F') || ''; 1.3578 + } 1.3579 + 1.3580 + // TODO: pdf reference says that GoToR 1.3581 + // can also have 'NewWindow' attribute 1.3582 + if (!isValidUrl(url, false)) { 1.3583 + url = ''; 1.3584 + } 1.3585 + data.url = url; 1.3586 + data.dest = action.get('D'); 1.3587 + } else if (linkType === 'Named') { 1.3588 + data.action = action.get('N').name; 1.3589 + } else { 1.3590 + warn('unrecognized link type: ' + linkType); 1.3591 + } 1.3592 + } else if (dict.has('Dest')) { 1.3593 + // simple destination link 1.3594 + var dest = dict.get('Dest'); 1.3595 + data.dest = isName(dest) ? dest.name : dest; 1.3596 + } 1.3597 + } 1.3598 + 1.3599 + // Lets URLs beginning with 'www.' default to using the 'http://' protocol. 1.3600 + function addDefaultProtocolToUrl(url) { 1.3601 + if (url && url.indexOf('www.') === 0) { 1.3602 + return ('http://' + url); 1.3603 + } 1.3604 + return url; 1.3605 + } 1.3606 + 1.3607 + Util.inherit(LinkAnnotation, InteractiveAnnotation, { 1.3608 + hasOperatorList: function LinkAnnotation_hasOperatorList() { 1.3609 + return false; 1.3610 + }, 1.3611 + 1.3612 + getHtmlElement: function LinkAnnotation_getHtmlElement(commonObjs) { 1.3613 + 1.3614 + var container = this.initContainer(); 1.3615 + container.className = 'annotLink'; 1.3616 + 1.3617 + var item = this.data; 1.3618 + 1.3619 + container.style.borderColor = item.colorCssRgb; 1.3620 + container.style.borderStyle = 'solid'; 1.3621 + 1.3622 + var link = document.createElement('a'); 1.3623 + link.href = link.title = this.data.url || ''; 1.3624 + 1.3625 + container.appendChild(link); 1.3626 + 1.3627 + return container; 1.3628 + } 1.3629 + }); 1.3630 + 1.3631 + return LinkAnnotation; 1.3632 +})(); 1.3633 + 1.3634 + 1.3635 +/** 1.3636 + * The maximum allowed image size in total pixels e.g. width * height. Images 1.3637 + * above this value will not be drawn. Use -1 for no limit. 1.3638 + * @var {number} 1.3639 + */ 1.3640 +PDFJS.maxImageSize = (PDFJS.maxImageSize === undefined ? 1.3641 + -1 : PDFJS.maxImageSize); 1.3642 + 1.3643 +/** 1.3644 + * The url of where the predefined Adobe CMaps are located. Include trailing 1.3645 + * slash. 1.3646 + * @var {string} 1.3647 + */ 1.3648 +PDFJS.cMapUrl = (PDFJS.cMapUrl === undefined ? null : PDFJS.cMapUrl); 1.3649 + 1.3650 +/** 1.3651 + * Specifies if CMaps are binary packed. 1.3652 + * @var {boolean} 1.3653 + */ 1.3654 +PDFJS.cMapPacked = PDFJS.cMapPacked === undefined ? false : PDFJS.cMapPacked; 1.3655 + 1.3656 +/* 1.3657 + * By default fonts are converted to OpenType fonts and loaded via font face 1.3658 + * rules. If disabled, the font will be rendered using a built in font renderer 1.3659 + * that constructs the glyphs with primitive path commands. 1.3660 + * @var {boolean} 1.3661 + */ 1.3662 +PDFJS.disableFontFace = (PDFJS.disableFontFace === undefined ? 1.3663 + false : PDFJS.disableFontFace); 1.3664 + 1.3665 +/** 1.3666 + * Path for image resources, mainly for annotation icons. Include trailing 1.3667 + * slash. 1.3668 + * @var {string} 1.3669 + */ 1.3670 +PDFJS.imageResourcesPath = (PDFJS.imageResourcesPath === undefined ? 1.3671 + '' : PDFJS.imageResourcesPath); 1.3672 + 1.3673 +/** 1.3674 + * Disable the web worker and run all code on the main thread. This will happen 1.3675 + * automatically if the browser doesn't support workers or sending typed arrays 1.3676 + * to workers. 1.3677 + * @var {boolean} 1.3678 + */ 1.3679 +PDFJS.disableWorker = (PDFJS.disableWorker === undefined ? 1.3680 + false : PDFJS.disableWorker); 1.3681 + 1.3682 +/** 1.3683 + * Path and filename of the worker file. Required when the worker is enabled in 1.3684 + * development mode. If unspecified in the production build, the worker will be 1.3685 + * loaded based on the location of the pdf.js file. 1.3686 + * @var {string} 1.3687 + */ 1.3688 +PDFJS.workerSrc = (PDFJS.workerSrc === undefined ? null : PDFJS.workerSrc); 1.3689 + 1.3690 +/** 1.3691 + * Disable range request loading of PDF files. When enabled and if the server 1.3692 + * supports partial content requests then the PDF will be fetched in chunks. 1.3693 + * Enabled (false) by default. 1.3694 + * @var {boolean} 1.3695 + */ 1.3696 +PDFJS.disableRange = (PDFJS.disableRange === undefined ? 1.3697 + false : PDFJS.disableRange); 1.3698 + 1.3699 +/** 1.3700 + * Disable pre-fetching of PDF file data. When range requests are enabled PDF.js 1.3701 + * will automatically keep fetching more data even if it isn't needed to display 1.3702 + * the current page. This default behavior can be disabled. 1.3703 + * @var {boolean} 1.3704 + */ 1.3705 +PDFJS.disableAutoFetch = (PDFJS.disableAutoFetch === undefined ? 1.3706 + false : PDFJS.disableAutoFetch); 1.3707 + 1.3708 +/** 1.3709 + * Enables special hooks for debugging PDF.js. 1.3710 + * @var {boolean} 1.3711 + */ 1.3712 +PDFJS.pdfBug = (PDFJS.pdfBug === undefined ? false : PDFJS.pdfBug); 1.3713 + 1.3714 +/** 1.3715 + * Enables transfer usage in postMessage for ArrayBuffers. 1.3716 + * @var {boolean} 1.3717 + */ 1.3718 +PDFJS.postMessageTransfers = (PDFJS.postMessageTransfers === undefined ? 1.3719 + true : PDFJS.postMessageTransfers); 1.3720 + 1.3721 +/** 1.3722 + * Disables URL.createObjectURL usage. 1.3723 + * @var {boolean} 1.3724 + */ 1.3725 +PDFJS.disableCreateObjectURL = (PDFJS.disableCreateObjectURL === undefined ? 1.3726 + false : PDFJS.disableCreateObjectURL); 1.3727 + 1.3728 +/** 1.3729 + * Disables WebGL usage. 1.3730 + * @var {boolean} 1.3731 + */ 1.3732 +PDFJS.disableWebGL = (PDFJS.disableWebGL === undefined ? 1.3733 + true : PDFJS.disableWebGL); 1.3734 + 1.3735 +/** 1.3736 + * Controls the logging level. 1.3737 + * The constants from PDFJS.VERBOSITY_LEVELS should be used: 1.3738 + * - errors 1.3739 + * - warnings [default] 1.3740 + * - infos 1.3741 + * @var {number} 1.3742 + */ 1.3743 +PDFJS.verbosity = (PDFJS.verbosity === undefined ? 1.3744 + PDFJS.VERBOSITY_LEVELS.warnings : PDFJS.verbosity); 1.3745 + 1.3746 +/** 1.3747 + * Document initialization / loading parameters object. 1.3748 + * 1.3749 + * @typedef {Object} DocumentInitParameters 1.3750 + * @property {string} url - The URL of the PDF. 1.3751 + * @property {TypedArray} data - A typed array with PDF data. 1.3752 + * @property {Object} httpHeaders - Basic authentication headers. 1.3753 + * @property {boolean} withCredentials - Indicates whether or not cross-site 1.3754 + * Access-Control requests should be made using credentials such as cookies 1.3755 + * or authorization headers. The default is false. 1.3756 + * @property {string} password - For decrypting password-protected PDFs. 1.3757 + * @property {TypedArray} initialData - A typed array with the first portion or 1.3758 + * all of the pdf data. Used by the extension since some data is already 1.3759 + * loaded before the switch to range requests. 1.3760 + */ 1.3761 + 1.3762 +/** 1.3763 + * This is the main entry point for loading a PDF and interacting with it. 1.3764 + * NOTE: If a URL is used to fetch the PDF data a standard XMLHttpRequest(XHR) 1.3765 + * is used, which means it must follow the same origin rules that any XHR does 1.3766 + * e.g. No cross domain requests without CORS. 1.3767 + * 1.3768 + * @param {string|TypedArray|DocumentInitParameters} source Can be a url to 1.3769 + * where a PDF is located, a typed array (Uint8Array) already populated with 1.3770 + * data or parameter object. 1.3771 + * 1.3772 + * @param {Object} pdfDataRangeTransport is optional. It is used if you want 1.3773 + * to manually serve range requests for data in the PDF. See viewer.js for 1.3774 + * an example of pdfDataRangeTransport's interface. 1.3775 + * 1.3776 + * @param {function} passwordCallback is optional. It is used to request a 1.3777 + * password if wrong or no password was provided. The callback receives two 1.3778 + * parameters: function that needs to be called with new password and reason 1.3779 + * (see {PasswordResponses}). 1.3780 + * 1.3781 + * @return {Promise} A promise that is resolved with {@link PDFDocumentProxy} 1.3782 + * object. 1.3783 + */ 1.3784 +PDFJS.getDocument = function getDocument(source, 1.3785 + pdfDataRangeTransport, 1.3786 + passwordCallback, 1.3787 + progressCallback) { 1.3788 + var workerInitializedPromise, workerReadyPromise, transport; 1.3789 + 1.3790 + if (typeof source === 'string') { 1.3791 + source = { url: source }; 1.3792 + } else if (isArrayBuffer(source)) { 1.3793 + source = { data: source }; 1.3794 + } else if (typeof source !== 'object') { 1.3795 + error('Invalid parameter in getDocument, need either Uint8Array, ' + 1.3796 + 'string or a parameter object'); 1.3797 + } 1.3798 + 1.3799 + if (!source.url && !source.data) { 1.3800 + error('Invalid parameter array, need either .data or .url'); 1.3801 + } 1.3802 + 1.3803 + // copy/use all keys as is except 'url' -- full path is required 1.3804 + var params = {}; 1.3805 + for (var key in source) { 1.3806 + if (key === 'url' && typeof window !== 'undefined') { 1.3807 + params[key] = combineUrl(window.location.href, source[key]); 1.3808 + continue; 1.3809 + } 1.3810 + params[key] = source[key]; 1.3811 + } 1.3812 + 1.3813 + workerInitializedPromise = new PDFJS.LegacyPromise(); 1.3814 + workerReadyPromise = new PDFJS.LegacyPromise(); 1.3815 + transport = new WorkerTransport(workerInitializedPromise, workerReadyPromise, 1.3816 + pdfDataRangeTransport, progressCallback); 1.3817 + workerInitializedPromise.then(function transportInitialized() { 1.3818 + transport.passwordCallback = passwordCallback; 1.3819 + transport.fetchDocument(params); 1.3820 + }); 1.3821 + return workerReadyPromise; 1.3822 +}; 1.3823 + 1.3824 +/** 1.3825 + * Proxy to a PDFDocument in the worker thread. Also, contains commonly used 1.3826 + * properties that can be read synchronously. 1.3827 + * @class 1.3828 + */ 1.3829 +var PDFDocumentProxy = (function PDFDocumentProxyClosure() { 1.3830 + function PDFDocumentProxy(pdfInfo, transport) { 1.3831 + this.pdfInfo = pdfInfo; 1.3832 + this.transport = transport; 1.3833 + } 1.3834 + PDFDocumentProxy.prototype = /** @lends PDFDocumentProxy.prototype */ { 1.3835 + /** 1.3836 + * @return {number} Total number of pages the PDF contains. 1.3837 + */ 1.3838 + get numPages() { 1.3839 + return this.pdfInfo.numPages; 1.3840 + }, 1.3841 + /** 1.3842 + * @return {string} A unique ID to identify a PDF. Not guaranteed to be 1.3843 + * unique. 1.3844 + */ 1.3845 + get fingerprint() { 1.3846 + return this.pdfInfo.fingerprint; 1.3847 + }, 1.3848 + /** 1.3849 + * @param {number} pageNumber The page number to get. The first page is 1. 1.3850 + * @return {Promise} A promise that is resolved with a {@link PDFPageProxy} 1.3851 + * object. 1.3852 + */ 1.3853 + getPage: function PDFDocumentProxy_getPage(pageNumber) { 1.3854 + return this.transport.getPage(pageNumber); 1.3855 + }, 1.3856 + /** 1.3857 + * @param {{num: number, gen: number}} ref The page reference. Must have 1.3858 + * the 'num' and 'gen' properties. 1.3859 + * @return {Promise} A promise that is resolved with the page index that is 1.3860 + * associated with the reference. 1.3861 + */ 1.3862 + getPageIndex: function PDFDocumentProxy_getPageIndex(ref) { 1.3863 + return this.transport.getPageIndex(ref); 1.3864 + }, 1.3865 + /** 1.3866 + * @return {Promise} A promise that is resolved with a lookup table for 1.3867 + * mapping named destinations to reference numbers. 1.3868 + */ 1.3869 + getDestinations: function PDFDocumentProxy_getDestinations() { 1.3870 + return this.transport.getDestinations(); 1.3871 + }, 1.3872 + /** 1.3873 + * @return {Promise} A promise that is resolved with a lookup table for 1.3874 + * mapping named attachments to their content. 1.3875 + */ 1.3876 + getAttachments: function PDFDocumentProxy_getAttachments() { 1.3877 + return this.transport.getAttachments(); 1.3878 + }, 1.3879 + /** 1.3880 + * @return {Promise} A promise that is resolved with an array of all the 1.3881 + * JavaScript strings in the name tree. 1.3882 + */ 1.3883 + getJavaScript: function PDFDocumentProxy_getJavaScript() { 1.3884 + var promise = new PDFJS.LegacyPromise(); 1.3885 + var js = this.pdfInfo.javaScript; 1.3886 + promise.resolve(js); 1.3887 + return promise; 1.3888 + }, 1.3889 + /** 1.3890 + * @return {Promise} A promise that is resolved with an {Array} that is a 1.3891 + * tree outline (if it has one) of the PDF. The tree is in the format of: 1.3892 + * [ 1.3893 + * { 1.3894 + * title: string, 1.3895 + * bold: boolean, 1.3896 + * italic: boolean, 1.3897 + * color: rgb array, 1.3898 + * dest: dest obj, 1.3899 + * items: array of more items like this 1.3900 + * }, 1.3901 + * ... 1.3902 + * ]. 1.3903 + */ 1.3904 + getOutline: function PDFDocumentProxy_getOutline() { 1.3905 + var promise = new PDFJS.LegacyPromise(); 1.3906 + var outline = this.pdfInfo.outline; 1.3907 + promise.resolve(outline); 1.3908 + return promise; 1.3909 + }, 1.3910 + /** 1.3911 + * @return {Promise} A promise that is resolved with an {Object} that has 1.3912 + * info and metadata properties. Info is an {Object} filled with anything 1.3913 + * available in the information dictionary and similarly metadata is a 1.3914 + * {Metadata} object with information from the metadata section of the PDF. 1.3915 + */ 1.3916 + getMetadata: function PDFDocumentProxy_getMetadata() { 1.3917 + var promise = new PDFJS.LegacyPromise(); 1.3918 + var info = this.pdfInfo.info; 1.3919 + var metadata = this.pdfInfo.metadata; 1.3920 + promise.resolve({ 1.3921 + info: info, 1.3922 + metadata: (metadata ? new PDFJS.Metadata(metadata) : null) 1.3923 + }); 1.3924 + return promise; 1.3925 + }, 1.3926 + /** 1.3927 + * @return {Promise} A promise that is resolved with a TypedArray that has 1.3928 + * the raw data from the PDF. 1.3929 + */ 1.3930 + getData: function PDFDocumentProxy_getData() { 1.3931 + var promise = new PDFJS.LegacyPromise(); 1.3932 + this.transport.getData(promise); 1.3933 + return promise; 1.3934 + }, 1.3935 + /** 1.3936 + * @return {Promise} A promise that is resolved when the document's data 1.3937 + * is loaded. It is resolved with an {Object} that contains the length 1.3938 + * property that indicates size of the PDF data in bytes. 1.3939 + */ 1.3940 + getDownloadInfo: function PDFDocumentProxy_getDownloadInfo() { 1.3941 + return this.transport.downloadInfoPromise; 1.3942 + }, 1.3943 + /** 1.3944 + * Cleans up resources allocated by the document, e.g. created @font-face. 1.3945 + */ 1.3946 + cleanup: function PDFDocumentProxy_cleanup() { 1.3947 + this.transport.startCleanup(); 1.3948 + }, 1.3949 + /** 1.3950 + * Destroys current document instance and terminates worker. 1.3951 + */ 1.3952 + destroy: function PDFDocumentProxy_destroy() { 1.3953 + this.transport.destroy(); 1.3954 + } 1.3955 + }; 1.3956 + return PDFDocumentProxy; 1.3957 +})(); 1.3958 + 1.3959 +/** 1.3960 + * Page text content. 1.3961 + * 1.3962 + * @typedef {Object} TextContent 1.3963 + * @property {array} items - array of {@link TextItem} 1.3964 + * @property {Object} styles - {@link TextStyles} objects, indexed by font 1.3965 + * name. 1.3966 + */ 1.3967 + 1.3968 +/** 1.3969 + * Page text content part. 1.3970 + * 1.3971 + * @typedef {Object} TextItem 1.3972 + * @property {string} str - text content. 1.3973 + * @property {string} dir - text direction: 'ttb', 'ltr' or 'rtl'. 1.3974 + * @property {array} transform - transformation matrix. 1.3975 + * @property {number} width - width in device space. 1.3976 + * @property {number} height - height in device space. 1.3977 + * @property {string} fontName - font name used by pdf.js for converted font. 1.3978 + */ 1.3979 + 1.3980 +/** 1.3981 + * Text style. 1.3982 + * 1.3983 + * @typedef {Object} TextStyle 1.3984 + * @property {number} ascent - font ascent. 1.3985 + * @property {number} descent - font descent. 1.3986 + * @property {boolean} vertical - text is in vertical mode. 1.3987 + * @property {string} fontFamily - possible font family 1.3988 + */ 1.3989 + 1.3990 +/** 1.3991 + * Page render parameters. 1.3992 + * 1.3993 + * @typedef {Object} RenderParameters 1.3994 + * @property {Object} canvasContext - A 2D context of a DOM Canvas object. 1.3995 + * @property {PageViewport} viewport - Rendering viewport obtained by 1.3996 + * calling of PDFPage.getViewport method. 1.3997 + * @property {string} intent - Rendering intent, can be 'display' or 'print' 1.3998 + * (default value is 'display'). 1.3999 + * @property {Object} imageLayer - (optional) An object that has beginLayout, 1.4000 + * endLayout and appendImage functions. 1.4001 + * @property {function} continueCallback - (optional) A function that will be 1.4002 + * called each time the rendering is paused. To continue 1.4003 + * rendering call the function that is the first argument 1.4004 + * to the callback. 1.4005 + */ 1.4006 + 1.4007 +/** 1.4008 + * Proxy to a PDFPage in the worker thread. 1.4009 + * @class 1.4010 + */ 1.4011 +var PDFPageProxy = (function PDFPageProxyClosure() { 1.4012 + function PDFPageProxy(pageInfo, transport) { 1.4013 + this.pageInfo = pageInfo; 1.4014 + this.transport = transport; 1.4015 + this.stats = new StatTimer(); 1.4016 + this.stats.enabled = !!globalScope.PDFJS.enableStats; 1.4017 + this.commonObjs = transport.commonObjs; 1.4018 + this.objs = new PDFObjects(); 1.4019 + this.cleanupAfterRender = false; 1.4020 + this.pendingDestroy = false; 1.4021 + this.intentStates = {}; 1.4022 + } 1.4023 + PDFPageProxy.prototype = /** @lends PDFPageProxy.prototype */ { 1.4024 + /** 1.4025 + * @return {number} Page number of the page. First page is 1. 1.4026 + */ 1.4027 + get pageNumber() { 1.4028 + return this.pageInfo.pageIndex + 1; 1.4029 + }, 1.4030 + /** 1.4031 + * @return {number} The number of degrees the page is rotated clockwise. 1.4032 + */ 1.4033 + get rotate() { 1.4034 + return this.pageInfo.rotate; 1.4035 + }, 1.4036 + /** 1.4037 + * @return {Object} The reference that points to this page. It has 'num' and 1.4038 + * 'gen' properties. 1.4039 + */ 1.4040 + get ref() { 1.4041 + return this.pageInfo.ref; 1.4042 + }, 1.4043 + /** 1.4044 + * @return {Array} An array of the visible portion of the PDF page in the 1.4045 + * user space units - [x1, y1, x2, y2]. 1.4046 + */ 1.4047 + get view() { 1.4048 + return this.pageInfo.view; 1.4049 + }, 1.4050 + /** 1.4051 + * @param {number} scale The desired scale of the viewport. 1.4052 + * @param {number} rotate Degrees to rotate the viewport. If omitted this 1.4053 + * defaults to the page rotation. 1.4054 + * @return {PageViewport} Contains 'width' and 'height' properties along 1.4055 + * with transforms required for rendering. 1.4056 + */ 1.4057 + getViewport: function PDFPageProxy_getViewport(scale, rotate) { 1.4058 + if (arguments.length < 2) { 1.4059 + rotate = this.rotate; 1.4060 + } 1.4061 + return new PDFJS.PageViewport(this.view, scale, rotate, 0, 0); 1.4062 + }, 1.4063 + /** 1.4064 + * @return {Promise} A promise that is resolved with an {Array} of the 1.4065 + * annotation objects. 1.4066 + */ 1.4067 + getAnnotations: function PDFPageProxy_getAnnotations() { 1.4068 + if (this.annotationsPromise) { 1.4069 + return this.annotationsPromise; 1.4070 + } 1.4071 + 1.4072 + var promise = new PDFJS.LegacyPromise(); 1.4073 + this.annotationsPromise = promise; 1.4074 + this.transport.getAnnotations(this.pageInfo.pageIndex); 1.4075 + return promise; 1.4076 + }, 1.4077 + /** 1.4078 + * Begins the process of rendering a page to the desired context. 1.4079 + * @param {RenderParameters} params Page render parameters. 1.4080 + * @return {RenderTask} An object that contains the promise, which 1.4081 + * is resolved when the page finishes rendering. 1.4082 + */ 1.4083 + render: function PDFPageProxy_render(params) { 1.4084 + var stats = this.stats; 1.4085 + stats.time('Overall'); 1.4086 + 1.4087 + // If there was a pending destroy cancel it so no cleanup happens during 1.4088 + // this call to render. 1.4089 + this.pendingDestroy = false; 1.4090 + 1.4091 + var renderingIntent = ('intent' in params ? 1.4092 + (params.intent == 'print' ? 'print' : 'display') : 'display'); 1.4093 + 1.4094 + if (!this.intentStates[renderingIntent]) { 1.4095 + this.intentStates[renderingIntent] = {}; 1.4096 + } 1.4097 + var intentState = this.intentStates[renderingIntent]; 1.4098 + 1.4099 + // If there is no displayReadyPromise yet, then the operatorList was never 1.4100 + // requested before. Make the request and create the promise. 1.4101 + if (!intentState.displayReadyPromise) { 1.4102 + intentState.receivingOperatorList = true; 1.4103 + intentState.displayReadyPromise = new LegacyPromise(); 1.4104 + intentState.operatorList = { 1.4105 + fnArray: [], 1.4106 + argsArray: [], 1.4107 + lastChunk: false 1.4108 + }; 1.4109 + 1.4110 + this.stats.time('Page Request'); 1.4111 + this.transport.messageHandler.send('RenderPageRequest', { 1.4112 + pageIndex: this.pageNumber - 1, 1.4113 + intent: renderingIntent 1.4114 + }); 1.4115 + } 1.4116 + 1.4117 + var internalRenderTask = new InternalRenderTask(complete, params, 1.4118 + this.objs, 1.4119 + this.commonObjs, 1.4120 + intentState.operatorList, 1.4121 + this.pageNumber); 1.4122 + if (!intentState.renderTasks) { 1.4123 + intentState.renderTasks = []; 1.4124 + } 1.4125 + intentState.renderTasks.push(internalRenderTask); 1.4126 + var renderTask = new RenderTask(internalRenderTask); 1.4127 + 1.4128 + var self = this; 1.4129 + intentState.displayReadyPromise.then( 1.4130 + function pageDisplayReadyPromise(transparency) { 1.4131 + if (self.pendingDestroy) { 1.4132 + complete(); 1.4133 + return; 1.4134 + } 1.4135 + stats.time('Rendering'); 1.4136 + internalRenderTask.initalizeGraphics(transparency); 1.4137 + internalRenderTask.operatorListChanged(); 1.4138 + }, 1.4139 + function pageDisplayReadPromiseError(reason) { 1.4140 + complete(reason); 1.4141 + } 1.4142 + ); 1.4143 + 1.4144 + function complete(error) { 1.4145 + var i = intentState.renderTasks.indexOf(internalRenderTask); 1.4146 + if (i >= 0) { 1.4147 + intentState.renderTasks.splice(i, 1); 1.4148 + } 1.4149 + 1.4150 + if (self.cleanupAfterRender) { 1.4151 + self.pendingDestroy = true; 1.4152 + } 1.4153 + self._tryDestroy(); 1.4154 + 1.4155 + if (error) { 1.4156 + renderTask.promise.reject(error); 1.4157 + } else { 1.4158 + renderTask.promise.resolve(); 1.4159 + } 1.4160 + stats.timeEnd('Rendering'); 1.4161 + stats.timeEnd('Overall'); 1.4162 + } 1.4163 + 1.4164 + return renderTask; 1.4165 + }, 1.4166 + /** 1.4167 + * @return {Promise} That is resolved a {@link TextContent} 1.4168 + * object that represent the page text content. 1.4169 + */ 1.4170 + getTextContent: function PDFPageProxy_getTextContent() { 1.4171 + var promise = new PDFJS.LegacyPromise(); 1.4172 + this.transport.messageHandler.send('GetTextContent', { 1.4173 + pageIndex: this.pageNumber - 1 1.4174 + }, 1.4175 + function textContentCallback(textContent) { 1.4176 + promise.resolve(textContent); 1.4177 + } 1.4178 + ); 1.4179 + return promise; 1.4180 + }, 1.4181 + /** 1.4182 + * Destroys resources allocated by the page. 1.4183 + */ 1.4184 + destroy: function PDFPageProxy_destroy() { 1.4185 + this.pendingDestroy = true; 1.4186 + this._tryDestroy(); 1.4187 + }, 1.4188 + /** 1.4189 + * For internal use only. Attempts to clean up if rendering is in a state 1.4190 + * where that's possible. 1.4191 + * @ignore 1.4192 + */ 1.4193 + _tryDestroy: function PDFPageProxy__destroy() { 1.4194 + if (!this.pendingDestroy || 1.4195 + Object.keys(this.intentStates).some(function(intent) { 1.4196 + var intentState = this.intentStates[intent]; 1.4197 + return (intentState.renderTasks.length !== 0 || 1.4198 + intentState.receivingOperatorList); 1.4199 + }, this)) { 1.4200 + return; 1.4201 + } 1.4202 + 1.4203 + Object.keys(this.intentStates).forEach(function(intent) { 1.4204 + delete this.intentStates[intent]; 1.4205 + }, this); 1.4206 + this.objs.clear(); 1.4207 + this.pendingDestroy = false; 1.4208 + }, 1.4209 + /** 1.4210 + * For internal use only. 1.4211 + * @ignore 1.4212 + */ 1.4213 + _startRenderPage: function PDFPageProxy_startRenderPage(transparency, 1.4214 + intent) { 1.4215 + var intentState = this.intentStates[intent]; 1.4216 + intentState.displayReadyPromise.resolve(transparency); 1.4217 + }, 1.4218 + /** 1.4219 + * For internal use only. 1.4220 + * @ignore 1.4221 + */ 1.4222 + _renderPageChunk: function PDFPageProxy_renderPageChunk(operatorListChunk, 1.4223 + intent) { 1.4224 + var intentState = this.intentStates[intent]; 1.4225 + var i, ii; 1.4226 + // Add the new chunk to the current operator list. 1.4227 + for (i = 0, ii = operatorListChunk.length; i < ii; i++) { 1.4228 + intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]); 1.4229 + intentState.operatorList.argsArray.push( 1.4230 + operatorListChunk.argsArray[i]); 1.4231 + } 1.4232 + intentState.operatorList.lastChunk = operatorListChunk.lastChunk; 1.4233 + 1.4234 + // Notify all the rendering tasks there are more operators to be consumed. 1.4235 + for (i = 0; i < intentState.renderTasks.length; i++) { 1.4236 + intentState.renderTasks[i].operatorListChanged(); 1.4237 + } 1.4238 + 1.4239 + if (operatorListChunk.lastChunk) { 1.4240 + intentState.receivingOperatorList = false; 1.4241 + this._tryDestroy(); 1.4242 + } 1.4243 + } 1.4244 + }; 1.4245 + return PDFPageProxy; 1.4246 +})(); 1.4247 + 1.4248 +/** 1.4249 + * For internal use only. 1.4250 + * @ignore 1.4251 + */ 1.4252 +var WorkerTransport = (function WorkerTransportClosure() { 1.4253 + function WorkerTransport(workerInitializedPromise, workerReadyPromise, 1.4254 + pdfDataRangeTransport, progressCallback) { 1.4255 + this.pdfDataRangeTransport = pdfDataRangeTransport; 1.4256 + 1.4257 + this.workerReadyPromise = workerReadyPromise; 1.4258 + this.progressCallback = progressCallback; 1.4259 + this.commonObjs = new PDFObjects(); 1.4260 + 1.4261 + this.pageCache = []; 1.4262 + this.pagePromises = []; 1.4263 + this.downloadInfoPromise = new PDFJS.LegacyPromise(); 1.4264 + this.passwordCallback = null; 1.4265 + 1.4266 + // If worker support isn't disabled explicit and the browser has worker 1.4267 + // support, create a new web worker and test if it/the browser fullfills 1.4268 + // all requirements to run parts of pdf.js in a web worker. 1.4269 + // Right now, the requirement is, that an Uint8Array is still an Uint8Array 1.4270 + // as it arrives on the worker. Chrome added this with version 15. 1.4271 + if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') { 1.4272 + var workerSrc = PDFJS.workerSrc; 1.4273 + if (!workerSrc) { 1.4274 + error('No PDFJS.workerSrc specified'); 1.4275 + } 1.4276 + 1.4277 + try { 1.4278 + // Some versions of FF can't create a worker on localhost, see: 1.4279 + // https://bugzilla.mozilla.org/show_bug.cgi?id=683280 1.4280 + var worker = new Worker(workerSrc); 1.4281 + var messageHandler = new MessageHandler('main', worker); 1.4282 + this.messageHandler = messageHandler; 1.4283 + 1.4284 + messageHandler.on('test', function transportTest(data) { 1.4285 + var supportTypedArray = data && data.supportTypedArray; 1.4286 + if (supportTypedArray) { 1.4287 + this.worker = worker; 1.4288 + if (!data.supportTransfers) { 1.4289 + PDFJS.postMessageTransfers = false; 1.4290 + } 1.4291 + this.setupMessageHandler(messageHandler); 1.4292 + workerInitializedPromise.resolve(); 1.4293 + } else { 1.4294 + globalScope.PDFJS.disableWorker = true; 1.4295 + this.loadFakeWorkerFiles().then(function() { 1.4296 + this.setupFakeWorker(); 1.4297 + workerInitializedPromise.resolve(); 1.4298 + }.bind(this)); 1.4299 + } 1.4300 + }.bind(this)); 1.4301 + 1.4302 + var testObj = new Uint8Array([PDFJS.postMessageTransfers ? 255 : 0]); 1.4303 + // Some versions of Opera throw a DATA_CLONE_ERR on serializing the 1.4304 + // typed array. Also, checking if we can use transfers. 1.4305 + try { 1.4306 + messageHandler.send('test', testObj, null, [testObj.buffer]); 1.4307 + } catch (ex) { 1.4308 + info('Cannot use postMessage transfers'); 1.4309 + testObj[0] = 0; 1.4310 + messageHandler.send('test', testObj); 1.4311 + } 1.4312 + return; 1.4313 + } catch (e) { 1.4314 + info('The worker has been disabled.'); 1.4315 + } 1.4316 + } 1.4317 + // Either workers are disabled, not supported or have thrown an exception. 1.4318 + // Thus, we fallback to a faked worker. 1.4319 + globalScope.PDFJS.disableWorker = true; 1.4320 + this.loadFakeWorkerFiles().then(function() { 1.4321 + this.setupFakeWorker(); 1.4322 + workerInitializedPromise.resolve(); 1.4323 + }.bind(this)); 1.4324 + } 1.4325 + WorkerTransport.prototype = { 1.4326 + destroy: function WorkerTransport_destroy() { 1.4327 + this.pageCache = []; 1.4328 + this.pagePromises = []; 1.4329 + var self = this; 1.4330 + this.messageHandler.send('Terminate', null, function () { 1.4331 + FontLoader.clear(); 1.4332 + if (self.worker) { 1.4333 + self.worker.terminate(); 1.4334 + } 1.4335 + }); 1.4336 + }, 1.4337 + 1.4338 + loadFakeWorkerFiles: function WorkerTransport_loadFakeWorkerFiles() { 1.4339 + if (!PDFJS.fakeWorkerFilesLoadedPromise) { 1.4340 + PDFJS.fakeWorkerFilesLoadedPromise = new LegacyPromise(); 1.4341 + // In the developer build load worker_loader which in turn loads all the 1.4342 + // other files and resolves the promise. In production only the 1.4343 + // pdf.worker.js file is needed. 1.4344 + Util.loadScript(PDFJS.workerSrc, function() { 1.4345 + PDFJS.fakeWorkerFilesLoadedPromise.resolve(); 1.4346 + }); 1.4347 + } 1.4348 + return PDFJS.fakeWorkerFilesLoadedPromise; 1.4349 + }, 1.4350 + 1.4351 + setupFakeWorker: function WorkerTransport_setupFakeWorker() { 1.4352 + warn('Setting up fake worker.'); 1.4353 + // If we don't use a worker, just post/sendMessage to the main thread. 1.4354 + var fakeWorker = { 1.4355 + postMessage: function WorkerTransport_postMessage(obj) { 1.4356 + fakeWorker.onmessage({data: obj}); 1.4357 + }, 1.4358 + terminate: function WorkerTransport_terminate() {} 1.4359 + }; 1.4360 + 1.4361 + var messageHandler = new MessageHandler('main', fakeWorker); 1.4362 + this.setupMessageHandler(messageHandler); 1.4363 + 1.4364 + // If the main thread is our worker, setup the handling for the messages 1.4365 + // the main thread sends to it self. 1.4366 + PDFJS.WorkerMessageHandler.setup(messageHandler); 1.4367 + }, 1.4368 + 1.4369 + setupMessageHandler: 1.4370 + function WorkerTransport_setupMessageHandler(messageHandler) { 1.4371 + this.messageHandler = messageHandler; 1.4372 + 1.4373 + function updatePassword(password) { 1.4374 + messageHandler.send('UpdatePassword', password); 1.4375 + } 1.4376 + 1.4377 + var pdfDataRangeTransport = this.pdfDataRangeTransport; 1.4378 + if (pdfDataRangeTransport) { 1.4379 + pdfDataRangeTransport.addRangeListener(function(begin, chunk) { 1.4380 + messageHandler.send('OnDataRange', { 1.4381 + begin: begin, 1.4382 + chunk: chunk 1.4383 + }); 1.4384 + }); 1.4385 + 1.4386 + pdfDataRangeTransport.addProgressListener(function(loaded) { 1.4387 + messageHandler.send('OnDataProgress', { 1.4388 + loaded: loaded 1.4389 + }); 1.4390 + }); 1.4391 + 1.4392 + messageHandler.on('RequestDataRange', 1.4393 + function transportDataRange(data) { 1.4394 + pdfDataRangeTransport.requestDataRange(data.begin, data.end); 1.4395 + }, this); 1.4396 + } 1.4397 + 1.4398 + messageHandler.on('GetDoc', function transportDoc(data) { 1.4399 + var pdfInfo = data.pdfInfo; 1.4400 + this.numPages = data.pdfInfo.numPages; 1.4401 + var pdfDocument = new PDFDocumentProxy(pdfInfo, this); 1.4402 + this.pdfDocument = pdfDocument; 1.4403 + this.workerReadyPromise.resolve(pdfDocument); 1.4404 + }, this); 1.4405 + 1.4406 + messageHandler.on('NeedPassword', function transportPassword(data) { 1.4407 + if (this.passwordCallback) { 1.4408 + return this.passwordCallback(updatePassword, 1.4409 + PasswordResponses.NEED_PASSWORD); 1.4410 + } 1.4411 + this.workerReadyPromise.reject(data.exception.message, data.exception); 1.4412 + }, this); 1.4413 + 1.4414 + messageHandler.on('IncorrectPassword', function transportBadPass(data) { 1.4415 + if (this.passwordCallback) { 1.4416 + return this.passwordCallback(updatePassword, 1.4417 + PasswordResponses.INCORRECT_PASSWORD); 1.4418 + } 1.4419 + this.workerReadyPromise.reject(data.exception.message, data.exception); 1.4420 + }, this); 1.4421 + 1.4422 + messageHandler.on('InvalidPDF', function transportInvalidPDF(data) { 1.4423 + this.workerReadyPromise.reject(data.exception.name, data.exception); 1.4424 + }, this); 1.4425 + 1.4426 + messageHandler.on('MissingPDF', function transportMissingPDF(data) { 1.4427 + this.workerReadyPromise.reject(data.exception.message, data.exception); 1.4428 + }, this); 1.4429 + 1.4430 + messageHandler.on('UnknownError', function transportUnknownError(data) { 1.4431 + this.workerReadyPromise.reject(data.exception.message, data.exception); 1.4432 + }, this); 1.4433 + 1.4434 + messageHandler.on('DataLoaded', function transportPage(data) { 1.4435 + this.downloadInfoPromise.resolve(data); 1.4436 + }, this); 1.4437 + 1.4438 + messageHandler.on('GetPage', function transportPage(data) { 1.4439 + var pageInfo = data.pageInfo; 1.4440 + var page = new PDFPageProxy(pageInfo, this); 1.4441 + this.pageCache[pageInfo.pageIndex] = page; 1.4442 + var promise = this.pagePromises[pageInfo.pageIndex]; 1.4443 + promise.resolve(page); 1.4444 + }, this); 1.4445 + 1.4446 + messageHandler.on('GetAnnotations', function transportAnnotations(data) { 1.4447 + var annotations = data.annotations; 1.4448 + var promise = this.pageCache[data.pageIndex].annotationsPromise; 1.4449 + promise.resolve(annotations); 1.4450 + }, this); 1.4451 + 1.4452 + messageHandler.on('StartRenderPage', function transportRender(data) { 1.4453 + var page = this.pageCache[data.pageIndex]; 1.4454 + 1.4455 + page.stats.timeEnd('Page Request'); 1.4456 + page._startRenderPage(data.transparency, data.intent); 1.4457 + }, this); 1.4458 + 1.4459 + messageHandler.on('RenderPageChunk', function transportRender(data) { 1.4460 + var page = this.pageCache[data.pageIndex]; 1.4461 + 1.4462 + page._renderPageChunk(data.operatorList, data.intent); 1.4463 + }, this); 1.4464 + 1.4465 + messageHandler.on('commonobj', function transportObj(data) { 1.4466 + var id = data[0]; 1.4467 + var type = data[1]; 1.4468 + if (this.commonObjs.hasData(id)) { 1.4469 + return; 1.4470 + } 1.4471 + 1.4472 + switch (type) { 1.4473 + case 'Font': 1.4474 + var exportedData = data[2]; 1.4475 + 1.4476 + var font; 1.4477 + if ('error' in exportedData) { 1.4478 + var error = exportedData.error; 1.4479 + warn('Error during font loading: ' + error); 1.4480 + this.commonObjs.resolve(id, error); 1.4481 + break; 1.4482 + } else { 1.4483 + font = new FontFace(exportedData); 1.4484 + } 1.4485 + 1.4486 + FontLoader.bind( 1.4487 + [font], 1.4488 + function fontReady(fontObjs) { 1.4489 + this.commonObjs.resolve(id, font); 1.4490 + }.bind(this) 1.4491 + ); 1.4492 + break; 1.4493 + case 'FontPath': 1.4494 + this.commonObjs.resolve(id, data[2]); 1.4495 + break; 1.4496 + default: 1.4497 + error('Got unknown common object type ' + type); 1.4498 + } 1.4499 + }, this); 1.4500 + 1.4501 + messageHandler.on('obj', function transportObj(data) { 1.4502 + var id = data[0]; 1.4503 + var pageIndex = data[1]; 1.4504 + var type = data[2]; 1.4505 + var pageProxy = this.pageCache[pageIndex]; 1.4506 + var imageData; 1.4507 + if (pageProxy.objs.hasData(id)) { 1.4508 + return; 1.4509 + } 1.4510 + 1.4511 + switch (type) { 1.4512 + case 'JpegStream': 1.4513 + imageData = data[3]; 1.4514 + loadJpegStream(id, imageData, pageProxy.objs); 1.4515 + break; 1.4516 + case 'Image': 1.4517 + imageData = data[3]; 1.4518 + pageProxy.objs.resolve(id, imageData); 1.4519 + 1.4520 + // heuristics that will allow not to store large data 1.4521 + var MAX_IMAGE_SIZE_TO_STORE = 8000000; 1.4522 + if (imageData && 'data' in imageData && 1.4523 + imageData.data.length > MAX_IMAGE_SIZE_TO_STORE) { 1.4524 + pageProxy.cleanupAfterRender = true; 1.4525 + } 1.4526 + break; 1.4527 + default: 1.4528 + error('Got unknown object type ' + type); 1.4529 + } 1.4530 + }, this); 1.4531 + 1.4532 + messageHandler.on('DocProgress', function transportDocProgress(data) { 1.4533 + if (this.progressCallback) { 1.4534 + this.progressCallback({ 1.4535 + loaded: data.loaded, 1.4536 + total: data.total 1.4537 + }); 1.4538 + } 1.4539 + }, this); 1.4540 + 1.4541 + messageHandler.on('DocError', function transportDocError(data) { 1.4542 + this.workerReadyPromise.reject(data); 1.4543 + }, this); 1.4544 + 1.4545 + messageHandler.on('PageError', function transportError(data, intent) { 1.4546 + var page = this.pageCache[data.pageNum - 1]; 1.4547 + var intentState = page.intentStates[intent]; 1.4548 + if (intentState.displayReadyPromise) { 1.4549 + intentState.displayReadyPromise.reject(data.error); 1.4550 + } else { 1.4551 + error(data.error); 1.4552 + } 1.4553 + }, this); 1.4554 + 1.4555 + messageHandler.on('JpegDecode', function(data, deferred) { 1.4556 + var imageUrl = data[0]; 1.4557 + var components = data[1]; 1.4558 + if (components != 3 && components != 1) { 1.4559 + error('Only 3 component or 1 component can be returned'); 1.4560 + } 1.4561 + 1.4562 + var img = new Image(); 1.4563 + img.onload = (function messageHandler_onloadClosure() { 1.4564 + var width = img.width; 1.4565 + var height = img.height; 1.4566 + var size = width * height; 1.4567 + var rgbaLength = size * 4; 1.4568 + var buf = new Uint8Array(size * components); 1.4569 + var tmpCanvas = createScratchCanvas(width, height); 1.4570 + var tmpCtx = tmpCanvas.getContext('2d'); 1.4571 + tmpCtx.drawImage(img, 0, 0); 1.4572 + var data = tmpCtx.getImageData(0, 0, width, height).data; 1.4573 + var i, j; 1.4574 + 1.4575 + if (components == 3) { 1.4576 + for (i = 0, j = 0; i < rgbaLength; i += 4, j += 3) { 1.4577 + buf[j] = data[i]; 1.4578 + buf[j + 1] = data[i + 1]; 1.4579 + buf[j + 2] = data[i + 2]; 1.4580 + } 1.4581 + } else if (components == 1) { 1.4582 + for (i = 0, j = 0; i < rgbaLength; i += 4, j++) { 1.4583 + buf[j] = data[i]; 1.4584 + } 1.4585 + } 1.4586 + deferred.resolve({ data: buf, width: width, height: height}); 1.4587 + }).bind(this); 1.4588 + img.src = imageUrl; 1.4589 + }); 1.4590 + }, 1.4591 + 1.4592 + fetchDocument: function WorkerTransport_fetchDocument(source) { 1.4593 + source.disableAutoFetch = PDFJS.disableAutoFetch; 1.4594 + source.chunkedViewerLoading = !!this.pdfDataRangeTransport; 1.4595 + this.messageHandler.send('GetDocRequest', { 1.4596 + source: source, 1.4597 + disableRange: PDFJS.disableRange, 1.4598 + maxImageSize: PDFJS.maxImageSize, 1.4599 + cMapUrl: PDFJS.cMapUrl, 1.4600 + cMapPacked: PDFJS.cMapPacked, 1.4601 + disableFontFace: PDFJS.disableFontFace, 1.4602 + disableCreateObjectURL: PDFJS.disableCreateObjectURL, 1.4603 + verbosity: PDFJS.verbosity 1.4604 + }); 1.4605 + }, 1.4606 + 1.4607 + getData: function WorkerTransport_getData(promise) { 1.4608 + this.messageHandler.send('GetData', null, function(data) { 1.4609 + promise.resolve(data); 1.4610 + }); 1.4611 + }, 1.4612 + 1.4613 + getPage: function WorkerTransport_getPage(pageNumber, promise) { 1.4614 + if (pageNumber <= 0 || pageNumber > this.numPages || 1.4615 + (pageNumber|0) !== pageNumber) { 1.4616 + var pagePromise = new PDFJS.LegacyPromise(); 1.4617 + pagePromise.reject(new Error('Invalid page request')); 1.4618 + return pagePromise; 1.4619 + } 1.4620 + 1.4621 + var pageIndex = pageNumber - 1; 1.4622 + if (pageIndex in this.pagePromises) { 1.4623 + return this.pagePromises[pageIndex]; 1.4624 + } 1.4625 + promise = new PDFJS.LegacyPromise(); 1.4626 + this.pagePromises[pageIndex] = promise; 1.4627 + this.messageHandler.send('GetPageRequest', { pageIndex: pageIndex }); 1.4628 + return promise; 1.4629 + }, 1.4630 + 1.4631 + getPageIndex: function WorkerTransport_getPageIndexByRef(ref) { 1.4632 + var promise = new PDFJS.LegacyPromise(); 1.4633 + this.messageHandler.send('GetPageIndex', { ref: ref }, 1.4634 + function (pageIndex) { 1.4635 + promise.resolve(pageIndex); 1.4636 + } 1.4637 + ); 1.4638 + return promise; 1.4639 + }, 1.4640 + 1.4641 + getAnnotations: function WorkerTransport_getAnnotations(pageIndex) { 1.4642 + this.messageHandler.send('GetAnnotationsRequest', 1.4643 + { pageIndex: pageIndex }); 1.4644 + }, 1.4645 + 1.4646 + getDestinations: function WorkerTransport_getDestinations() { 1.4647 + var promise = new PDFJS.LegacyPromise(); 1.4648 + this.messageHandler.send('GetDestinations', null, 1.4649 + function transportDestinations(destinations) { 1.4650 + promise.resolve(destinations); 1.4651 + } 1.4652 + ); 1.4653 + return promise; 1.4654 + }, 1.4655 + 1.4656 + getAttachments: function WorkerTransport_getAttachments() { 1.4657 + var promise = new PDFJS.LegacyPromise(); 1.4658 + this.messageHandler.send('GetAttachments', null, 1.4659 + function transportAttachments(attachments) { 1.4660 + promise.resolve(attachments); 1.4661 + } 1.4662 + ); 1.4663 + return promise; 1.4664 + }, 1.4665 + 1.4666 + startCleanup: function WorkerTransport_startCleanup() { 1.4667 + this.messageHandler.send('Cleanup', null, 1.4668 + function endCleanup() { 1.4669 + for (var i = 0, ii = this.pageCache.length; i < ii; i++) { 1.4670 + var page = this.pageCache[i]; 1.4671 + if (page) { 1.4672 + page.destroy(); 1.4673 + } 1.4674 + } 1.4675 + this.commonObjs.clear(); 1.4676 + FontLoader.clear(); 1.4677 + }.bind(this) 1.4678 + ); 1.4679 + } 1.4680 + }; 1.4681 + return WorkerTransport; 1.4682 + 1.4683 +})(); 1.4684 + 1.4685 +/** 1.4686 + * A PDF document and page is built of many objects. E.g. there are objects 1.4687 + * for fonts, images, rendering code and such. These objects might get processed 1.4688 + * inside of a worker. The `PDFObjects` implements some basic functions to 1.4689 + * manage these objects. 1.4690 + * @ignore 1.4691 + */ 1.4692 +var PDFObjects = (function PDFObjectsClosure() { 1.4693 + function PDFObjects() { 1.4694 + this.objs = {}; 1.4695 + } 1.4696 + 1.4697 + PDFObjects.prototype = { 1.4698 + /** 1.4699 + * Internal function. 1.4700 + * Ensures there is an object defined for `objId`. 1.4701 + */ 1.4702 + ensureObj: function PDFObjects_ensureObj(objId) { 1.4703 + if (this.objs[objId]) { 1.4704 + return this.objs[objId]; 1.4705 + } 1.4706 + 1.4707 + var obj = { 1.4708 + promise: new LegacyPromise(), 1.4709 + data: null, 1.4710 + resolved: false 1.4711 + }; 1.4712 + this.objs[objId] = obj; 1.4713 + 1.4714 + return obj; 1.4715 + }, 1.4716 + 1.4717 + /** 1.4718 + * If called *without* callback, this returns the data of `objId` but the 1.4719 + * object needs to be resolved. If it isn't, this function throws. 1.4720 + * 1.4721 + * If called *with* a callback, the callback is called with the data of the 1.4722 + * object once the object is resolved. That means, if you call this 1.4723 + * function and the object is already resolved, the callback gets called 1.4724 + * right away. 1.4725 + */ 1.4726 + get: function PDFObjects_get(objId, callback) { 1.4727 + // If there is a callback, then the get can be async and the object is 1.4728 + // not required to be resolved right now 1.4729 + if (callback) { 1.4730 + this.ensureObj(objId).promise.then(callback); 1.4731 + return null; 1.4732 + } 1.4733 + 1.4734 + // If there isn't a callback, the user expects to get the resolved data 1.4735 + // directly. 1.4736 + var obj = this.objs[objId]; 1.4737 + 1.4738 + // If there isn't an object yet or the object isn't resolved, then the 1.4739 + // data isn't ready yet! 1.4740 + if (!obj || !obj.resolved) { 1.4741 + error('Requesting object that isn\'t resolved yet ' + objId); 1.4742 + } 1.4743 + 1.4744 + return obj.data; 1.4745 + }, 1.4746 + 1.4747 + /** 1.4748 + * Resolves the object `objId` with optional `data`. 1.4749 + */ 1.4750 + resolve: function PDFObjects_resolve(objId, data) { 1.4751 + var obj = this.ensureObj(objId); 1.4752 + 1.4753 + obj.resolved = true; 1.4754 + obj.data = data; 1.4755 + obj.promise.resolve(data); 1.4756 + }, 1.4757 + 1.4758 + isResolved: function PDFObjects_isResolved(objId) { 1.4759 + var objs = this.objs; 1.4760 + 1.4761 + if (!objs[objId]) { 1.4762 + return false; 1.4763 + } else { 1.4764 + return objs[objId].resolved; 1.4765 + } 1.4766 + }, 1.4767 + 1.4768 + hasData: function PDFObjects_hasData(objId) { 1.4769 + return this.isResolved(objId); 1.4770 + }, 1.4771 + 1.4772 + /** 1.4773 + * Returns the data of `objId` if object exists, null otherwise. 1.4774 + */ 1.4775 + getData: function PDFObjects_getData(objId) { 1.4776 + var objs = this.objs; 1.4777 + if (!objs[objId] || !objs[objId].resolved) { 1.4778 + return null; 1.4779 + } else { 1.4780 + return objs[objId].data; 1.4781 + } 1.4782 + }, 1.4783 + 1.4784 + clear: function PDFObjects_clear() { 1.4785 + this.objs = {}; 1.4786 + } 1.4787 + }; 1.4788 + return PDFObjects; 1.4789 +})(); 1.4790 + 1.4791 +/** 1.4792 + * Allows controlling of the rendering tasks. 1.4793 + * @class 1.4794 + */ 1.4795 +var RenderTask = (function RenderTaskClosure() { 1.4796 + function RenderTask(internalRenderTask) { 1.4797 + this.internalRenderTask = internalRenderTask; 1.4798 + /** 1.4799 + * Promise for rendering task completion. 1.4800 + * @type {Promise} 1.4801 + */ 1.4802 + this.promise = new PDFJS.LegacyPromise(); 1.4803 + } 1.4804 + 1.4805 + RenderTask.prototype = /** @lends RenderTask.prototype */ { 1.4806 + /** 1.4807 + * Cancels the rendering task. If the task is currently rendering it will 1.4808 + * not be cancelled until graphics pauses with a timeout. The promise that 1.4809 + * this object extends will resolved when cancelled. 1.4810 + */ 1.4811 + cancel: function RenderTask_cancel() { 1.4812 + this.internalRenderTask.cancel(); 1.4813 + this.promise.reject(new Error('Rendering is cancelled')); 1.4814 + }, 1.4815 + 1.4816 + /** 1.4817 + * Registers callback to indicate the rendering task completion. 1.4818 + * 1.4819 + * @param {function} onFulfilled The callback for the rendering completion. 1.4820 + * @param {function} onRejected The callback for the rendering failure. 1.4821 + * @return {Promise} A promise that is resolved after the onFulfilled or 1.4822 + * onRejected callback. 1.4823 + */ 1.4824 + then: function RenderTask_then(onFulfilled, onRejected) { 1.4825 + return this.promise.then(onFulfilled, onRejected); 1.4826 + } 1.4827 + }; 1.4828 + 1.4829 + return RenderTask; 1.4830 +})(); 1.4831 + 1.4832 +/** 1.4833 + * For internal use only. 1.4834 + * @ignore 1.4835 + */ 1.4836 +var InternalRenderTask = (function InternalRenderTaskClosure() { 1.4837 + 1.4838 + function InternalRenderTask(callback, params, objs, commonObjs, operatorList, 1.4839 + pageNumber) { 1.4840 + this.callback = callback; 1.4841 + this.params = params; 1.4842 + this.objs = objs; 1.4843 + this.commonObjs = commonObjs; 1.4844 + this.operatorListIdx = null; 1.4845 + this.operatorList = operatorList; 1.4846 + this.pageNumber = pageNumber; 1.4847 + this.running = false; 1.4848 + this.graphicsReadyCallback = null; 1.4849 + this.graphicsReady = false; 1.4850 + this.cancelled = false; 1.4851 + } 1.4852 + 1.4853 + InternalRenderTask.prototype = { 1.4854 + 1.4855 + initalizeGraphics: 1.4856 + function InternalRenderTask_initalizeGraphics(transparency) { 1.4857 + 1.4858 + if (this.cancelled) { 1.4859 + return; 1.4860 + } 1.4861 + if (PDFJS.pdfBug && 'StepperManager' in globalScope && 1.4862 + globalScope.StepperManager.enabled) { 1.4863 + this.stepper = globalScope.StepperManager.create(this.pageNumber - 1); 1.4864 + this.stepper.init(this.operatorList); 1.4865 + this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint(); 1.4866 + } 1.4867 + 1.4868 + var params = this.params; 1.4869 + this.gfx = new CanvasGraphics(params.canvasContext, this.commonObjs, 1.4870 + this.objs, params.imageLayer); 1.4871 + 1.4872 + this.gfx.beginDrawing(params.viewport, transparency); 1.4873 + this.operatorListIdx = 0; 1.4874 + this.graphicsReady = true; 1.4875 + if (this.graphicsReadyCallback) { 1.4876 + this.graphicsReadyCallback(); 1.4877 + } 1.4878 + }, 1.4879 + 1.4880 + cancel: function InternalRenderTask_cancel() { 1.4881 + this.running = false; 1.4882 + this.cancelled = true; 1.4883 + this.callback('cancelled'); 1.4884 + }, 1.4885 + 1.4886 + operatorListChanged: function InternalRenderTask_operatorListChanged() { 1.4887 + if (!this.graphicsReady) { 1.4888 + if (!this.graphicsReadyCallback) { 1.4889 + this.graphicsReadyCallback = this._continue.bind(this); 1.4890 + } 1.4891 + return; 1.4892 + } 1.4893 + 1.4894 + if (this.stepper) { 1.4895 + this.stepper.updateOperatorList(this.operatorList); 1.4896 + } 1.4897 + 1.4898 + if (this.running) { 1.4899 + return; 1.4900 + } 1.4901 + this._continue(); 1.4902 + }, 1.4903 + 1.4904 + _continue: function InternalRenderTask__continue() { 1.4905 + this.running = true; 1.4906 + if (this.cancelled) { 1.4907 + return; 1.4908 + } 1.4909 + if (this.params.continueCallback) { 1.4910 + this.params.continueCallback(this._next.bind(this)); 1.4911 + } else { 1.4912 + this._next(); 1.4913 + } 1.4914 + }, 1.4915 + 1.4916 + _next: function InternalRenderTask__next() { 1.4917 + if (this.cancelled) { 1.4918 + return; 1.4919 + } 1.4920 + this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList, 1.4921 + this.operatorListIdx, 1.4922 + this._continue.bind(this), 1.4923 + this.stepper); 1.4924 + if (this.operatorListIdx === this.operatorList.argsArray.length) { 1.4925 + this.running = false; 1.4926 + if (this.operatorList.lastChunk) { 1.4927 + this.gfx.endDrawing(); 1.4928 + this.callback(); 1.4929 + } 1.4930 + } 1.4931 + } 1.4932 + 1.4933 + }; 1.4934 + 1.4935 + return InternalRenderTask; 1.4936 +})(); 1.4937 + 1.4938 + 1.4939 +var Metadata = PDFJS.Metadata = (function MetadataClosure() { 1.4940 + function fixMetadata(meta) { 1.4941 + return meta.replace(/>\\376\\377([^<]+)/g, function(all, codes) { 1.4942 + var bytes = codes.replace(/\\([0-3])([0-7])([0-7])/g, 1.4943 + function(code, d1, d2, d3) { 1.4944 + return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1); 1.4945 + }); 1.4946 + var chars = ''; 1.4947 + for (var i = 0; i < bytes.length; i += 2) { 1.4948 + var code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1); 1.4949 + chars += code >= 32 && code < 127 && code != 60 && code != 62 && 1.4950 + code != 38 && false ? String.fromCharCode(code) : 1.4951 + '&#x' + (0x10000 + code).toString(16).substring(1) + ';'; 1.4952 + } 1.4953 + return '>' + chars; 1.4954 + }); 1.4955 + } 1.4956 + 1.4957 + function Metadata(meta) { 1.4958 + if (typeof meta === 'string') { 1.4959 + // Ghostscript produces invalid metadata 1.4960 + meta = fixMetadata(meta); 1.4961 + 1.4962 + var parser = new DOMParser(); 1.4963 + meta = parser.parseFromString(meta, 'application/xml'); 1.4964 + } else if (!(meta instanceof Document)) { 1.4965 + error('Metadata: Invalid metadata object'); 1.4966 + } 1.4967 + 1.4968 + this.metaDocument = meta; 1.4969 + this.metadata = {}; 1.4970 + this.parse(); 1.4971 + } 1.4972 + 1.4973 + Metadata.prototype = { 1.4974 + parse: function Metadata_parse() { 1.4975 + var doc = this.metaDocument; 1.4976 + var rdf = doc.documentElement; 1.4977 + 1.4978 + if (rdf.nodeName.toLowerCase() !== 'rdf:rdf') { // Wrapped in <xmpmeta> 1.4979 + rdf = rdf.firstChild; 1.4980 + while (rdf && rdf.nodeName.toLowerCase() !== 'rdf:rdf') { 1.4981 + rdf = rdf.nextSibling; 1.4982 + } 1.4983 + } 1.4984 + 1.4985 + var nodeName = (rdf) ? rdf.nodeName.toLowerCase() : null; 1.4986 + if (!rdf || nodeName !== 'rdf:rdf' || !rdf.hasChildNodes()) { 1.4987 + return; 1.4988 + } 1.4989 + 1.4990 + var children = rdf.childNodes, desc, entry, name, i, ii, length, iLength; 1.4991 + for (i = 0, length = children.length; i < length; i++) { 1.4992 + desc = children[i]; 1.4993 + if (desc.nodeName.toLowerCase() !== 'rdf:description') { 1.4994 + continue; 1.4995 + } 1.4996 + 1.4997 + for (ii = 0, iLength = desc.childNodes.length; ii < iLength; ii++) { 1.4998 + if (desc.childNodes[ii].nodeName.toLowerCase() !== '#text') { 1.4999 + entry = desc.childNodes[ii]; 1.5000 + name = entry.nodeName.toLowerCase(); 1.5001 + this.metadata[name] = entry.textContent.trim(); 1.5002 + } 1.5003 + } 1.5004 + } 1.5005 + }, 1.5006 + 1.5007 + get: function Metadata_get(name) { 1.5008 + return this.metadata[name] || null; 1.5009 + }, 1.5010 + 1.5011 + has: function Metadata_has(name) { 1.5012 + return typeof this.metadata[name] !== 'undefined'; 1.5013 + } 1.5014 + }; 1.5015 + 1.5016 + return Metadata; 1.5017 +})(); 1.5018 + 1.5019 + 1.5020 +// <canvas> contexts store most of the state we need natively. 1.5021 +// However, PDF needs a bit more state, which we store here. 1.5022 + 1.5023 +// Minimal font size that would be used during canvas fillText operations. 1.5024 +var MIN_FONT_SIZE = 16; 1.5025 +var MAX_GROUP_SIZE = 4096; 1.5026 + 1.5027 +var COMPILE_TYPE3_GLYPHS = true; 1.5028 + 1.5029 +function createScratchCanvas(width, height) { 1.5030 + var canvas = document.createElement('canvas'); 1.5031 + canvas.width = width; 1.5032 + canvas.height = height; 1.5033 + return canvas; 1.5034 +} 1.5035 + 1.5036 +function addContextCurrentTransform(ctx) { 1.5037 + // If the context doesn't expose a `mozCurrentTransform`, add a JS based on. 1.5038 + if (!ctx.mozCurrentTransform) { 1.5039 + // Store the original context 1.5040 + ctx._scaleX = ctx._scaleX || 1.0; 1.5041 + ctx._scaleY = ctx._scaleY || 1.0; 1.5042 + ctx._originalSave = ctx.save; 1.5043 + ctx._originalRestore = ctx.restore; 1.5044 + ctx._originalRotate = ctx.rotate; 1.5045 + ctx._originalScale = ctx.scale; 1.5046 + ctx._originalTranslate = ctx.translate; 1.5047 + ctx._originalTransform = ctx.transform; 1.5048 + ctx._originalSetTransform = ctx.setTransform; 1.5049 + 1.5050 + ctx._transformMatrix = [ctx._scaleX, 0, 0, ctx._scaleY, 0, 0]; 1.5051 + ctx._transformStack = []; 1.5052 + 1.5053 + Object.defineProperty(ctx, 'mozCurrentTransform', { 1.5054 + get: function getCurrentTransform() { 1.5055 + return this._transformMatrix; 1.5056 + } 1.5057 + }); 1.5058 + 1.5059 + Object.defineProperty(ctx, 'mozCurrentTransformInverse', { 1.5060 + get: function getCurrentTransformInverse() { 1.5061 + // Calculation done using WolframAlpha: 1.5062 + // http://www.wolframalpha.com/input/? 1.5063 + // i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}} 1.5064 + 1.5065 + var m = this._transformMatrix; 1.5066 + var a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5]; 1.5067 + 1.5068 + var ad_bc = a * d - b * c; 1.5069 + var bc_ad = b * c - a * d; 1.5070 + 1.5071 + return [ 1.5072 + d / ad_bc, 1.5073 + b / bc_ad, 1.5074 + c / bc_ad, 1.5075 + a / ad_bc, 1.5076 + (d * e - c * f) / bc_ad, 1.5077 + (b * e - a * f) / ad_bc 1.5078 + ]; 1.5079 + } 1.5080 + }); 1.5081 + 1.5082 + ctx.save = function ctxSave() { 1.5083 + var old = this._transformMatrix; 1.5084 + this._transformStack.push(old); 1.5085 + this._transformMatrix = old.slice(0, 6); 1.5086 + 1.5087 + this._originalSave(); 1.5088 + }; 1.5089 + 1.5090 + ctx.restore = function ctxRestore() { 1.5091 + var prev = this._transformStack.pop(); 1.5092 + if (prev) { 1.5093 + this._transformMatrix = prev; 1.5094 + this._originalRestore(); 1.5095 + } 1.5096 + }; 1.5097 + 1.5098 + ctx.translate = function ctxTranslate(x, y) { 1.5099 + var m = this._transformMatrix; 1.5100 + m[4] = m[0] * x + m[2] * y + m[4]; 1.5101 + m[5] = m[1] * x + m[3] * y + m[5]; 1.5102 + 1.5103 + this._originalTranslate(x, y); 1.5104 + }; 1.5105 + 1.5106 + ctx.scale = function ctxScale(x, y) { 1.5107 + var m = this._transformMatrix; 1.5108 + m[0] = m[0] * x; 1.5109 + m[1] = m[1] * x; 1.5110 + m[2] = m[2] * y; 1.5111 + m[3] = m[3] * y; 1.5112 + 1.5113 + this._originalScale(x, y); 1.5114 + }; 1.5115 + 1.5116 + ctx.transform = function ctxTransform(a, b, c, d, e, f) { 1.5117 + var m = this._transformMatrix; 1.5118 + this._transformMatrix = [ 1.5119 + m[0] * a + m[2] * b, 1.5120 + m[1] * a + m[3] * b, 1.5121 + m[0] * c + m[2] * d, 1.5122 + m[1] * c + m[3] * d, 1.5123 + m[0] * e + m[2] * f + m[4], 1.5124 + m[1] * e + m[3] * f + m[5] 1.5125 + ]; 1.5126 + 1.5127 + ctx._originalTransform(a, b, c, d, e, f); 1.5128 + }; 1.5129 + 1.5130 + ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) { 1.5131 + this._transformMatrix = [a, b, c, d, e, f]; 1.5132 + 1.5133 + ctx._originalSetTransform(a, b, c, d, e, f); 1.5134 + }; 1.5135 + 1.5136 + ctx.rotate = function ctxRotate(angle) { 1.5137 + var cosValue = Math.cos(angle); 1.5138 + var sinValue = Math.sin(angle); 1.5139 + 1.5140 + var m = this._transformMatrix; 1.5141 + this._transformMatrix = [ 1.5142 + m[0] * cosValue + m[2] * sinValue, 1.5143 + m[1] * cosValue + m[3] * sinValue, 1.5144 + m[0] * (-sinValue) + m[2] * cosValue, 1.5145 + m[1] * (-sinValue) + m[3] * cosValue, 1.5146 + m[4], 1.5147 + m[5] 1.5148 + ]; 1.5149 + 1.5150 + this._originalRotate(angle); 1.5151 + }; 1.5152 + } 1.5153 +} 1.5154 + 1.5155 +var CachedCanvases = (function CachedCanvasesClosure() { 1.5156 + var cache = {}; 1.5157 + return { 1.5158 + getCanvas: function CachedCanvases_getCanvas(id, width, height, 1.5159 + trackTransform) { 1.5160 + var canvasEntry; 1.5161 + if (id in cache) { 1.5162 + canvasEntry = cache[id]; 1.5163 + canvasEntry.canvas.width = width; 1.5164 + canvasEntry.canvas.height = height; 1.5165 + // reset canvas transform for emulated mozCurrentTransform, if needed 1.5166 + canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0); 1.5167 + } else { 1.5168 + var canvas = createScratchCanvas(width, height); 1.5169 + var ctx = canvas.getContext('2d'); 1.5170 + if (trackTransform) { 1.5171 + addContextCurrentTransform(ctx); 1.5172 + } 1.5173 + cache[id] = canvasEntry = {canvas: canvas, context: ctx}; 1.5174 + } 1.5175 + return canvasEntry; 1.5176 + }, 1.5177 + clear: function () { 1.5178 + cache = {}; 1.5179 + } 1.5180 + }; 1.5181 +})(); 1.5182 + 1.5183 +function compileType3Glyph(imgData) { 1.5184 + var POINT_TO_PROCESS_LIMIT = 1000; 1.5185 + 1.5186 + var width = imgData.width, height = imgData.height; 1.5187 + var i, j, j0, width1 = width + 1; 1.5188 + var points = new Uint8Array(width1 * (height + 1)); 1.5189 + var POINT_TYPES = 1.5190 + new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]); 1.5191 + 1.5192 + // decodes bit-packed mask data 1.5193 + var lineSize = (width + 7) & ~7, data0 = imgData.data; 1.5194 + var data = new Uint8Array(lineSize * height), pos = 0, ii; 1.5195 + for (i = 0, ii = data0.length; i < ii; i++) { 1.5196 + var mask = 128, elem = data0[i]; 1.5197 + while (mask > 0) { 1.5198 + data[pos++] = (elem & mask) ? 0 : 255; 1.5199 + mask >>= 1; 1.5200 + } 1.5201 + } 1.5202 + 1.5203 + // finding iteresting points: every point is located between mask pixels, 1.5204 + // so there will be points of the (width + 1)x(height + 1) grid. Every point 1.5205 + // will have flags assigned based on neighboring mask pixels: 1.5206 + // 4 | 8 1.5207 + // --P-- 1.5208 + // 2 | 1 1.5209 + // We are interested only in points with the flags: 1.5210 + // - outside corners: 1, 2, 4, 8; 1.5211 + // - inside corners: 7, 11, 13, 14; 1.5212 + // - and, intersections: 5, 10. 1.5213 + var count = 0; 1.5214 + pos = 0; 1.5215 + if (data[pos] !== 0) { 1.5216 + points[0] = 1; 1.5217 + ++count; 1.5218 + } 1.5219 + for (j = 1; j < width; j++) { 1.5220 + if (data[pos] !== data[pos + 1]) { 1.5221 + points[j] = data[pos] ? 2 : 1; 1.5222 + ++count; 1.5223 + } 1.5224 + pos++; 1.5225 + } 1.5226 + if (data[pos] !== 0) { 1.5227 + points[j] = 2; 1.5228 + ++count; 1.5229 + } 1.5230 + for (i = 1; i < height; i++) { 1.5231 + pos = i * lineSize; 1.5232 + j0 = i * width1; 1.5233 + if (data[pos - lineSize] !== data[pos]) { 1.5234 + points[j0] = data[pos] ? 1 : 8; 1.5235 + ++count; 1.5236 + } 1.5237 + // 'sum' is the position of the current pixel configuration in the 'TYPES' 1.5238 + // array (in order 8-1-2-4, so we can use '>>2' to shift the column). 1.5239 + var sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0); 1.5240 + for (j = 1; j < width; j++) { 1.5241 + sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + 1.5242 + (data[pos - lineSize + 1] ? 8 : 0); 1.5243 + if (POINT_TYPES[sum]) { 1.5244 + points[j0 + j] = POINT_TYPES[sum]; 1.5245 + ++count; 1.5246 + } 1.5247 + pos++; 1.5248 + } 1.5249 + if (data[pos - lineSize] !== data[pos]) { 1.5250 + points[j0 + j] = data[pos] ? 2 : 4; 1.5251 + ++count; 1.5252 + } 1.5253 + 1.5254 + if (count > POINT_TO_PROCESS_LIMIT) { 1.5255 + return null; 1.5256 + } 1.5257 + } 1.5258 + 1.5259 + pos = lineSize * (height - 1); 1.5260 + j0 = i * width1; 1.5261 + if (data[pos] !== 0) { 1.5262 + points[j0] = 8; 1.5263 + ++count; 1.5264 + } 1.5265 + for (j = 1; j < width; j++) { 1.5266 + if (data[pos] !== data[pos + 1]) { 1.5267 + points[j0 + j] = data[pos] ? 4 : 8; 1.5268 + ++count; 1.5269 + } 1.5270 + pos++; 1.5271 + } 1.5272 + if (data[pos] !== 0) { 1.5273 + points[j0 + j] = 4; 1.5274 + ++count; 1.5275 + } 1.5276 + if (count > POINT_TO_PROCESS_LIMIT) { 1.5277 + return null; 1.5278 + } 1.5279 + 1.5280 + // building outlines 1.5281 + var steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]); 1.5282 + var outlines = []; 1.5283 + for (i = 0; count && i <= height; i++) { 1.5284 + var p = i * width1; 1.5285 + var end = p + width; 1.5286 + while (p < end && !points[p]) { 1.5287 + p++; 1.5288 + } 1.5289 + if (p === end) { 1.5290 + continue; 1.5291 + } 1.5292 + var coords = [p % width1, i]; 1.5293 + 1.5294 + var type = points[p], p0 = p, pp; 1.5295 + do { 1.5296 + var step = steps[type]; 1.5297 + do { 1.5298 + p += step; 1.5299 + } while (!points[p]); 1.5300 + 1.5301 + pp = points[p]; 1.5302 + if (pp !== 5 && pp !== 10) { 1.5303 + // set new direction 1.5304 + type = pp; 1.5305 + // delete mark 1.5306 + points[p] = 0; 1.5307 + } else { // type is 5 or 10, ie, a crossing 1.5308 + // set new direction 1.5309 + type = pp & ((0x33 * type) >> 4); 1.5310 + // set new type for "future hit" 1.5311 + points[p] &= (type >> 2 | type << 2); 1.5312 + } 1.5313 + 1.5314 + coords.push(p % width1); 1.5315 + coords.push((p / width1) | 0); 1.5316 + --count; 1.5317 + } while (p0 !== p); 1.5318 + outlines.push(coords); 1.5319 + --i; 1.5320 + } 1.5321 + 1.5322 + var drawOutline = function(c) { 1.5323 + c.save(); 1.5324 + // the path shall be painted in [0..1]x[0..1] space 1.5325 + c.scale(1 / width, -1 / height); 1.5326 + c.translate(0, -height); 1.5327 + c.beginPath(); 1.5328 + for (var i = 0, ii = outlines.length; i < ii; i++) { 1.5329 + var o = outlines[i]; 1.5330 + c.moveTo(o[0], o[1]); 1.5331 + for (var j = 2, jj = o.length; j < jj; j += 2) { 1.5332 + c.lineTo(o[j], o[j+1]); 1.5333 + } 1.5334 + } 1.5335 + c.fill(); 1.5336 + c.beginPath(); 1.5337 + c.restore(); 1.5338 + }; 1.5339 + 1.5340 + return drawOutline; 1.5341 +} 1.5342 + 1.5343 +var CanvasExtraState = (function CanvasExtraStateClosure() { 1.5344 + function CanvasExtraState(old) { 1.5345 + // Are soft masks and alpha values shapes or opacities? 1.5346 + this.alphaIsShape = false; 1.5347 + this.fontSize = 0; 1.5348 + this.fontSizeScale = 1; 1.5349 + this.textMatrix = IDENTITY_MATRIX; 1.5350 + this.fontMatrix = FONT_IDENTITY_MATRIX; 1.5351 + this.leading = 0; 1.5352 + // Current point (in user coordinates) 1.5353 + this.x = 0; 1.5354 + this.y = 0; 1.5355 + // Start of text line (in text coordinates) 1.5356 + this.lineX = 0; 1.5357 + this.lineY = 0; 1.5358 + // Character and word spacing 1.5359 + this.charSpacing = 0; 1.5360 + this.wordSpacing = 0; 1.5361 + this.textHScale = 1; 1.5362 + this.textRenderingMode = TextRenderingMode.FILL; 1.5363 + this.textRise = 0; 1.5364 + // Color spaces 1.5365 + this.fillColorSpace = ColorSpace.singletons.gray; 1.5366 + this.fillColorSpaceObj = null; 1.5367 + this.strokeColorSpace = ColorSpace.singletons.gray; 1.5368 + this.strokeColorSpaceObj = null; 1.5369 + this.fillColorObj = null; 1.5370 + this.strokeColorObj = null; 1.5371 + // Default fore and background colors 1.5372 + this.fillColor = '#000000'; 1.5373 + this.strokeColor = '#000000'; 1.5374 + // Note: fill alpha applies to all non-stroking operations 1.5375 + this.fillAlpha = 1; 1.5376 + this.strokeAlpha = 1; 1.5377 + this.lineWidth = 1; 1.5378 + this.activeSMask = null; // nonclonable field (see the save method below) 1.5379 + 1.5380 + this.old = old; 1.5381 + } 1.5382 + 1.5383 + CanvasExtraState.prototype = { 1.5384 + clone: function CanvasExtraState_clone() { 1.5385 + return Object.create(this); 1.5386 + }, 1.5387 + setCurrentPoint: function CanvasExtraState_setCurrentPoint(x, y) { 1.5388 + this.x = x; 1.5389 + this.y = y; 1.5390 + } 1.5391 + }; 1.5392 + return CanvasExtraState; 1.5393 +})(); 1.5394 + 1.5395 +var CanvasGraphics = (function CanvasGraphicsClosure() { 1.5396 + // Defines the time the executeOperatorList is going to be executing 1.5397 + // before it stops and shedules a continue of execution. 1.5398 + var EXECUTION_TIME = 15; 1.5399 + 1.5400 + function CanvasGraphics(canvasCtx, commonObjs, objs, imageLayer) { 1.5401 + this.ctx = canvasCtx; 1.5402 + this.current = new CanvasExtraState(); 1.5403 + this.stateStack = []; 1.5404 + this.pendingClip = null; 1.5405 + this.pendingEOFill = false; 1.5406 + this.res = null; 1.5407 + this.xobjs = null; 1.5408 + this.commonObjs = commonObjs; 1.5409 + this.objs = objs; 1.5410 + this.imageLayer = imageLayer; 1.5411 + this.groupStack = []; 1.5412 + this.processingType3 = null; 1.5413 + // Patterns are painted relative to the initial page/form transform, see pdf 1.5414 + // spec 8.7.2 NOTE 1. 1.5415 + this.baseTransform = null; 1.5416 + this.baseTransformStack = []; 1.5417 + this.groupLevel = 0; 1.5418 + this.smaskStack = []; 1.5419 + this.smaskCounter = 0; 1.5420 + this.tempSMask = null; 1.5421 + if (canvasCtx) { 1.5422 + addContextCurrentTransform(canvasCtx); 1.5423 + } 1.5424 + } 1.5425 + 1.5426 + function putBinaryImageData(ctx, imgData) { 1.5427 + if (typeof ImageData !== 'undefined' && imgData instanceof ImageData) { 1.5428 + ctx.putImageData(imgData, 0, 0); 1.5429 + return; 1.5430 + } 1.5431 + 1.5432 + // Put the image data to the canvas in chunks, rather than putting the 1.5433 + // whole image at once. This saves JS memory, because the ImageData object 1.5434 + // is smaller. It also possibly saves C++ memory within the implementation 1.5435 + // of putImageData(). (E.g. in Firefox we make two short-lived copies of 1.5436 + // the data passed to putImageData()). |n| shouldn't be too small, however, 1.5437 + // because too many putImageData() calls will slow things down. 1.5438 + // 1.5439 + // Note: as written, if the last chunk is partial, the putImageData() call 1.5440 + // will (conceptually) put pixels past the bounds of the canvas. But 1.5441 + // that's ok; any such pixels are ignored. 1.5442 + 1.5443 + var height = imgData.height, width = imgData.width; 1.5444 + var fullChunkHeight = 16; 1.5445 + var fracChunks = height / fullChunkHeight; 1.5446 + var fullChunks = Math.floor(fracChunks); 1.5447 + var totalChunks = Math.ceil(fracChunks); 1.5448 + var partialChunkHeight = height - fullChunks * fullChunkHeight; 1.5449 + 1.5450 + var chunkImgData = ctx.createImageData(width, fullChunkHeight); 1.5451 + var srcPos = 0, destPos; 1.5452 + var src = imgData.data; 1.5453 + var dest = chunkImgData.data; 1.5454 + var i, j, thisChunkHeight, elemsInThisChunk; 1.5455 + 1.5456 + // There are multiple forms in which the pixel data can be passed, and 1.5457 + // imgData.kind tells us which one this is. 1.5458 + if (imgData.kind === ImageKind.GRAYSCALE_1BPP) { 1.5459 + // Grayscale, 1 bit per pixel (i.e. black-and-white). 1.5460 + var srcLength = src.byteLength; 1.5461 + var dest32 = PDFJS.hasCanvasTypedArrays ? new Uint32Array(dest.buffer) : 1.5462 + new Uint32ArrayView(dest); 1.5463 + var dest32DataLength = dest32.length; 1.5464 + var fullSrcDiff = (width + 7) >> 3; 1.5465 + var white = 0xFFFFFFFF; 1.5466 + var black = (PDFJS.isLittleEndian || !PDFJS.hasCanvasTypedArrays) ? 1.5467 + 0xFF000000 : 0x000000FF; 1.5468 + for (i = 0; i < totalChunks; i++) { 1.5469 + thisChunkHeight = 1.5470 + (i < fullChunks) ? fullChunkHeight : partialChunkHeight; 1.5471 + destPos = 0; 1.5472 + for (j = 0; j < thisChunkHeight; j++) { 1.5473 + var srcDiff = srcLength - srcPos; 1.5474 + var k = 0; 1.5475 + var kEnd = (srcDiff > fullSrcDiff) ? width : srcDiff * 8 - 7; 1.5476 + var kEndUnrolled = kEnd & ~7; 1.5477 + var mask = 0; 1.5478 + var srcByte = 0; 1.5479 + for (; k < kEndUnrolled; k += 8) { 1.5480 + srcByte = src[srcPos++]; 1.5481 + dest32[destPos++] = (srcByte & 128) ? white : black; 1.5482 + dest32[destPos++] = (srcByte & 64) ? white : black; 1.5483 + dest32[destPos++] = (srcByte & 32) ? white : black; 1.5484 + dest32[destPos++] = (srcByte & 16) ? white : black; 1.5485 + dest32[destPos++] = (srcByte & 8) ? white : black; 1.5486 + dest32[destPos++] = (srcByte & 4) ? white : black; 1.5487 + dest32[destPos++] = (srcByte & 2) ? white : black; 1.5488 + dest32[destPos++] = (srcByte & 1) ? white : black; 1.5489 + } 1.5490 + for (; k < kEnd; k++) { 1.5491 + if (mask === 0) { 1.5492 + srcByte = src[srcPos++]; 1.5493 + mask = 128; 1.5494 + } 1.5495 + 1.5496 + dest32[destPos++] = (srcByte & mask) ? white : black; 1.5497 + mask >>= 1; 1.5498 + } 1.5499 + } 1.5500 + // We ran out of input. Make all remaining pixels transparent. 1.5501 + while (destPos < dest32DataLength) { 1.5502 + dest32[destPos++] = 0; 1.5503 + } 1.5504 + 1.5505 + ctx.putImageData(chunkImgData, 0, i * fullChunkHeight); 1.5506 + } 1.5507 + } else if (imgData.kind === ImageKind.RGBA_32BPP) { 1.5508 + // RGBA, 32-bits per pixel. 1.5509 + 1.5510 + for (i = 0; i < totalChunks; i++) { 1.5511 + thisChunkHeight = 1.5512 + (i < fullChunks) ? fullChunkHeight : partialChunkHeight; 1.5513 + elemsInThisChunk = imgData.width * thisChunkHeight * 4; 1.5514 + 1.5515 + dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 1.5516 + srcPos += elemsInThisChunk; 1.5517 + 1.5518 + ctx.putImageData(chunkImgData, 0, i * fullChunkHeight); 1.5519 + } 1.5520 + } else if (imgData.kind === ImageKind.RGB_24BPP) { 1.5521 + // RGB, 24-bits per pixel. 1.5522 + for (i = 0; i < totalChunks; i++) { 1.5523 + thisChunkHeight = 1.5524 + (i < fullChunks) ? fullChunkHeight : partialChunkHeight; 1.5525 + elemsInThisChunk = imgData.width * thisChunkHeight * 3; 1.5526 + destPos = 0; 1.5527 + for (j = 0; j < elemsInThisChunk; j += 3) { 1.5528 + dest[destPos++] = src[srcPos++]; 1.5529 + dest[destPos++] = src[srcPos++]; 1.5530 + dest[destPos++] = src[srcPos++]; 1.5531 + dest[destPos++] = 255; 1.5532 + } 1.5533 + ctx.putImageData(chunkImgData, 0, i * fullChunkHeight); 1.5534 + } 1.5535 + } else { 1.5536 + error('bad image kind: ' + imgData.kind); 1.5537 + } 1.5538 + } 1.5539 + 1.5540 + function putBinaryImageMask(ctx, imgData) { 1.5541 + var height = imgData.height, width = imgData.width; 1.5542 + var fullChunkHeight = 16; 1.5543 + var fracChunks = height / fullChunkHeight; 1.5544 + var fullChunks = Math.floor(fracChunks); 1.5545 + var totalChunks = Math.ceil(fracChunks); 1.5546 + var partialChunkHeight = height - fullChunks * fullChunkHeight; 1.5547 + 1.5548 + var chunkImgData = ctx.createImageData(width, fullChunkHeight); 1.5549 + var srcPos = 0; 1.5550 + var src = imgData.data; 1.5551 + var dest = chunkImgData.data; 1.5552 + 1.5553 + for (var i = 0; i < totalChunks; i++) { 1.5554 + var thisChunkHeight = 1.5555 + (i < fullChunks) ? fullChunkHeight : partialChunkHeight; 1.5556 + 1.5557 + // Expand the mask so it can be used by the canvas. Any required 1.5558 + // inversion has already been handled. 1.5559 + var destPos = 3; // alpha component offset 1.5560 + for (var j = 0; j < thisChunkHeight; j++) { 1.5561 + var mask = 0; 1.5562 + for (var k = 0; k < width; k++) { 1.5563 + if (!mask) { 1.5564 + var elem = src[srcPos++]; 1.5565 + mask = 128; 1.5566 + } 1.5567 + dest[destPos] = (elem & mask) ? 0 : 255; 1.5568 + destPos += 4; 1.5569 + mask >>= 1; 1.5570 + } 1.5571 + } 1.5572 + ctx.putImageData(chunkImgData, 0, i * fullChunkHeight); 1.5573 + } 1.5574 + } 1.5575 + 1.5576 + function copyCtxState(sourceCtx, destCtx) { 1.5577 + var properties = ['strokeStyle', 'fillStyle', 'fillRule', 'globalAlpha', 1.5578 + 'lineWidth', 'lineCap', 'lineJoin', 'miterLimit', 1.5579 + 'globalCompositeOperation', 'font']; 1.5580 + for (var i = 0, ii = properties.length; i < ii; i++) { 1.5581 + var property = properties[i]; 1.5582 + if (property in sourceCtx) { 1.5583 + destCtx[property] = sourceCtx[property]; 1.5584 + } 1.5585 + } 1.5586 + if ('setLineDash' in sourceCtx) { 1.5587 + destCtx.setLineDash(sourceCtx.getLineDash()); 1.5588 + destCtx.lineDashOffset = sourceCtx.lineDashOffset; 1.5589 + } else if ('mozDash' in sourceCtx) { 1.5590 + destCtx.mozDash = sourceCtx.mozDash; 1.5591 + destCtx.mozDashOffset = sourceCtx.mozDashOffset; 1.5592 + } 1.5593 + } 1.5594 + 1.5595 + function genericComposeSMask(maskCtx, layerCtx, width, height, 1.5596 + subtype, backdrop) { 1.5597 + var addBackdropFn; 1.5598 + if (backdrop) { 1.5599 + addBackdropFn = function (r0, g0, b0, bytes) { 1.5600 + var length = bytes.length; 1.5601 + for (var i = 3; i < length; i += 4) { 1.5602 + var alpha = bytes[i] / 255; 1.5603 + if (alpha === 0) { 1.5604 + bytes[i - 3] = r0; 1.5605 + bytes[i - 2] = g0; 1.5606 + bytes[i - 1] = b0; 1.5607 + } else if (alpha < 1) { 1.5608 + var alpha_ = 1 - alpha; 1.5609 + bytes[i - 3] = (bytes[i - 3] * alpha + r0 * alpha_) | 0; 1.5610 + bytes[i - 2] = (bytes[i - 2] * alpha + g0 * alpha_) | 0; 1.5611 + bytes[i - 1] = (bytes[i - 1] * alpha + b0 * alpha_) | 0; 1.5612 + } 1.5613 + } 1.5614 + }.bind(null, backdrop[0], backdrop[1], backdrop[2]); 1.5615 + } else { 1.5616 + addBackdropFn = function () {}; 1.5617 + } 1.5618 + 1.5619 + var composeFn; 1.5620 + if (subtype === 'Luminosity') { 1.5621 + composeFn = function (maskDataBytes, layerDataBytes) { 1.5622 + var length = maskDataBytes.length; 1.5623 + for (var i = 3; i < length; i += 4) { 1.5624 + var y = ((maskDataBytes[i - 3] * 77) + // * 0.3 / 255 * 0x10000 1.5625 + (maskDataBytes[i - 2] * 152) + // * 0.59 .... 1.5626 + (maskDataBytes[i - 1] * 28)) | 0; // * 0.11 .... 1.5627 + layerDataBytes[i] = (layerDataBytes[i] * y) >> 16; 1.5628 + } 1.5629 + }; 1.5630 + } else { 1.5631 + composeFn = function (maskDataBytes, layerDataBytes) { 1.5632 + var length = maskDataBytes.length; 1.5633 + for (var i = 3; i < length; i += 4) { 1.5634 + var alpha = maskDataBytes[i]; 1.5635 + layerDataBytes[i] = (layerDataBytes[i] * alpha / 255) | 0; 1.5636 + } 1.5637 + }; 1.5638 + } 1.5639 + 1.5640 + // processing image in chunks to save memory 1.5641 + var PIXELS_TO_PROCESS = 65536; 1.5642 + var chunkSize = Math.min(height, Math.ceil(PIXELS_TO_PROCESS / width)); 1.5643 + for (var row = 0; row < height; row += chunkSize) { 1.5644 + var chunkHeight = Math.min(chunkSize, height - row); 1.5645 + var maskData = maskCtx.getImageData(0, row, width, chunkHeight); 1.5646 + var layerData = layerCtx.getImageData(0, row, width, chunkHeight); 1.5647 + 1.5648 + addBackdropFn(maskData.data); 1.5649 + composeFn(maskData.data, layerData.data); 1.5650 + 1.5651 + maskCtx.putImageData(layerData, 0, row); 1.5652 + } 1.5653 + } 1.5654 + 1.5655 + function composeSMask(ctx, smask, layerCtx) { 1.5656 + var mask = smask.canvas; 1.5657 + var maskCtx = smask.context; 1.5658 + 1.5659 + ctx.setTransform(smask.scaleX, 0, 0, smask.scaleY, 1.5660 + smask.offsetX, smask.offsetY); 1.5661 + 1.5662 + var backdrop; 1.5663 + if (smask.backdrop) { 1.5664 + var cs = smask.colorSpace || ColorSpace.singletons.rgb; 1.5665 + backdrop = cs.getRgb(smask.backdrop, 0); 1.5666 + } 1.5667 + if (WebGLUtils.isEnabled) { 1.5668 + var composed = WebGLUtils.composeSMask(layerCtx.canvas, mask, 1.5669 + {subtype: smask.subtype, backdrop: backdrop}); 1.5670 + ctx.setTransform(1, 0, 0, 1, 0, 0); 1.5671 + ctx.drawImage(composed, smask.offsetX, smask.offsetY); 1.5672 + return; 1.5673 + } 1.5674 + genericComposeSMask(maskCtx, layerCtx, mask.width, mask.height, 1.5675 + smask.subtype, backdrop); 1.5676 + ctx.drawImage(mask, 0, 0); 1.5677 + } 1.5678 + 1.5679 + var LINE_CAP_STYLES = ['butt', 'round', 'square']; 1.5680 + var LINE_JOIN_STYLES = ['miter', 'round', 'bevel']; 1.5681 + var NORMAL_CLIP = {}; 1.5682 + var EO_CLIP = {}; 1.5683 + 1.5684 + CanvasGraphics.prototype = { 1.5685 + 1.5686 + beginDrawing: function CanvasGraphics_beginDrawing(viewport, transparency) { 1.5687 + // For pdfs that use blend modes we have to clear the canvas else certain 1.5688 + // blend modes can look wrong since we'd be blending with a white 1.5689 + // backdrop. The problem with a transparent backdrop though is we then 1.5690 + // don't get sub pixel anti aliasing on text, so we fill with white if 1.5691 + // we can. 1.5692 + var width = this.ctx.canvas.width; 1.5693 + var height = this.ctx.canvas.height; 1.5694 + if (transparency) { 1.5695 + this.ctx.clearRect(0, 0, width, height); 1.5696 + } else { 1.5697 + this.ctx.mozOpaque = true; 1.5698 + this.ctx.save(); 1.5699 + this.ctx.fillStyle = 'rgb(255, 255, 255)'; 1.5700 + this.ctx.fillRect(0, 0, width, height); 1.5701 + this.ctx.restore(); 1.5702 + } 1.5703 + 1.5704 + var transform = viewport.transform; 1.5705 + 1.5706 + this.ctx.save(); 1.5707 + this.ctx.transform.apply(this.ctx, transform); 1.5708 + 1.5709 + this.baseTransform = this.ctx.mozCurrentTransform.slice(); 1.5710 + 1.5711 + if (this.imageLayer) { 1.5712 + this.imageLayer.beginLayout(); 1.5713 + } 1.5714 + }, 1.5715 + 1.5716 + executeOperatorList: function CanvasGraphics_executeOperatorList( 1.5717 + operatorList, 1.5718 + executionStartIdx, continueCallback, 1.5719 + stepper) { 1.5720 + var argsArray = operatorList.argsArray; 1.5721 + var fnArray = operatorList.fnArray; 1.5722 + var i = executionStartIdx || 0; 1.5723 + var argsArrayLen = argsArray.length; 1.5724 + 1.5725 + // Sometimes the OperatorList to execute is empty. 1.5726 + if (argsArrayLen == i) { 1.5727 + return i; 1.5728 + } 1.5729 + 1.5730 + var endTime = Date.now() + EXECUTION_TIME; 1.5731 + 1.5732 + var commonObjs = this.commonObjs; 1.5733 + var objs = this.objs; 1.5734 + var fnId; 1.5735 + var deferred = Promise.resolve(); 1.5736 + 1.5737 + while (true) { 1.5738 + if (stepper && i === stepper.nextBreakPoint) { 1.5739 + stepper.breakIt(i, continueCallback); 1.5740 + return i; 1.5741 + } 1.5742 + 1.5743 + fnId = fnArray[i]; 1.5744 + 1.5745 + if (fnId !== OPS.dependency) { 1.5746 + this[fnId].apply(this, argsArray[i]); 1.5747 + } else { 1.5748 + var deps = argsArray[i]; 1.5749 + for (var n = 0, nn = deps.length; n < nn; n++) { 1.5750 + var depObjId = deps[n]; 1.5751 + var common = depObjId.substring(0, 2) == 'g_'; 1.5752 + 1.5753 + // If the promise isn't resolved yet, add the continueCallback 1.5754 + // to the promise and bail out. 1.5755 + if (!common && !objs.isResolved(depObjId)) { 1.5756 + objs.get(depObjId, continueCallback); 1.5757 + return i; 1.5758 + } 1.5759 + if (common && !commonObjs.isResolved(depObjId)) { 1.5760 + commonObjs.get(depObjId, continueCallback); 1.5761 + return i; 1.5762 + } 1.5763 + } 1.5764 + } 1.5765 + 1.5766 + i++; 1.5767 + 1.5768 + // If the entire operatorList was executed, stop as were done. 1.5769 + if (i == argsArrayLen) { 1.5770 + return i; 1.5771 + } 1.5772 + 1.5773 + // If the execution took longer then a certain amount of time, schedule 1.5774 + // to continue exeution after a short delay. 1.5775 + // However, this is only possible if a 'continueCallback' is passed in. 1.5776 + if (continueCallback && Date.now() > endTime) { 1.5777 + deferred.then(continueCallback); 1.5778 + return i; 1.5779 + } 1.5780 + 1.5781 + // If the operatorList isn't executed completely yet OR the execution 1.5782 + // time was short enough, do another execution round. 1.5783 + } 1.5784 + }, 1.5785 + 1.5786 + endDrawing: function CanvasGraphics_endDrawing() { 1.5787 + this.ctx.restore(); 1.5788 + CachedCanvases.clear(); 1.5789 + WebGLUtils.clear(); 1.5790 + 1.5791 + if (this.imageLayer) { 1.5792 + this.imageLayer.endLayout(); 1.5793 + } 1.5794 + }, 1.5795 + 1.5796 + // Graphics state 1.5797 + setLineWidth: function CanvasGraphics_setLineWidth(width) { 1.5798 + this.current.lineWidth = width; 1.5799 + this.ctx.lineWidth = width; 1.5800 + }, 1.5801 + setLineCap: function CanvasGraphics_setLineCap(style) { 1.5802 + this.ctx.lineCap = LINE_CAP_STYLES[style]; 1.5803 + }, 1.5804 + setLineJoin: function CanvasGraphics_setLineJoin(style) { 1.5805 + this.ctx.lineJoin = LINE_JOIN_STYLES[style]; 1.5806 + }, 1.5807 + setMiterLimit: function CanvasGraphics_setMiterLimit(limit) { 1.5808 + this.ctx.miterLimit = limit; 1.5809 + }, 1.5810 + setDash: function CanvasGraphics_setDash(dashArray, dashPhase) { 1.5811 + var ctx = this.ctx; 1.5812 + if ('setLineDash' in ctx) { 1.5813 + ctx.setLineDash(dashArray); 1.5814 + ctx.lineDashOffset = dashPhase; 1.5815 + } else { 1.5816 + ctx.mozDash = dashArray; 1.5817 + ctx.mozDashOffset = dashPhase; 1.5818 + } 1.5819 + }, 1.5820 + setRenderingIntent: function CanvasGraphics_setRenderingIntent(intent) { 1.5821 + // Maybe if we one day fully support color spaces this will be important 1.5822 + // for now we can ignore. 1.5823 + // TODO set rendering intent? 1.5824 + }, 1.5825 + setFlatness: function CanvasGraphics_setFlatness(flatness) { 1.5826 + // There's no way to control this with canvas, but we can safely ignore. 1.5827 + // TODO set flatness? 1.5828 + }, 1.5829 + setGState: function CanvasGraphics_setGState(states) { 1.5830 + for (var i = 0, ii = states.length; i < ii; i++) { 1.5831 + var state = states[i]; 1.5832 + var key = state[0]; 1.5833 + var value = state[1]; 1.5834 + 1.5835 + switch (key) { 1.5836 + case 'LW': 1.5837 + this.setLineWidth(value); 1.5838 + break; 1.5839 + case 'LC': 1.5840 + this.setLineCap(value); 1.5841 + break; 1.5842 + case 'LJ': 1.5843 + this.setLineJoin(value); 1.5844 + break; 1.5845 + case 'ML': 1.5846 + this.setMiterLimit(value); 1.5847 + break; 1.5848 + case 'D': 1.5849 + this.setDash(value[0], value[1]); 1.5850 + break; 1.5851 + case 'RI': 1.5852 + this.setRenderingIntent(value); 1.5853 + break; 1.5854 + case 'FL': 1.5855 + this.setFlatness(value); 1.5856 + break; 1.5857 + case 'Font': 1.5858 + this.setFont(value[0], value[1]); 1.5859 + break; 1.5860 + case 'CA': 1.5861 + this.current.strokeAlpha = state[1]; 1.5862 + break; 1.5863 + case 'ca': 1.5864 + this.current.fillAlpha = state[1]; 1.5865 + this.ctx.globalAlpha = state[1]; 1.5866 + break; 1.5867 + case 'BM': 1.5868 + if (value && value.name && (value.name !== 'Normal')) { 1.5869 + var mode = value.name.replace(/([A-Z])/g, 1.5870 + function(c) { 1.5871 + return '-' + c.toLowerCase(); 1.5872 + } 1.5873 + ).substring(1); 1.5874 + this.ctx.globalCompositeOperation = mode; 1.5875 + if (this.ctx.globalCompositeOperation !== mode) { 1.5876 + warn('globalCompositeOperation "' + mode + 1.5877 + '" is not supported'); 1.5878 + } 1.5879 + } else { 1.5880 + this.ctx.globalCompositeOperation = 'source-over'; 1.5881 + } 1.5882 + break; 1.5883 + case 'SMask': 1.5884 + if (this.current.activeSMask) { 1.5885 + this.endSMaskGroup(); 1.5886 + } 1.5887 + this.current.activeSMask = value ? this.tempSMask : null; 1.5888 + if (this.current.activeSMask) { 1.5889 + this.beginSMaskGroup(); 1.5890 + } 1.5891 + this.tempSMask = null; 1.5892 + break; 1.5893 + } 1.5894 + } 1.5895 + }, 1.5896 + beginSMaskGroup: function CanvasGraphics_beginSMaskGroup() { 1.5897 + 1.5898 + var activeSMask = this.current.activeSMask; 1.5899 + var drawnWidth = activeSMask.canvas.width; 1.5900 + var drawnHeight = activeSMask.canvas.height; 1.5901 + var cacheId = 'smaskGroupAt' + this.groupLevel; 1.5902 + var scratchCanvas = CachedCanvases.getCanvas( 1.5903 + cacheId, drawnWidth, drawnHeight, true); 1.5904 + 1.5905 + var currentCtx = this.ctx; 1.5906 + var currentTransform = currentCtx.mozCurrentTransform; 1.5907 + this.ctx.save(); 1.5908 + 1.5909 + var groupCtx = scratchCanvas.context; 1.5910 + groupCtx.scale(1 / activeSMask.scaleX, 1 / activeSMask.scaleY); 1.5911 + groupCtx.translate(-activeSMask.offsetX, -activeSMask.offsetY); 1.5912 + groupCtx.transform.apply(groupCtx, currentTransform); 1.5913 + 1.5914 + copyCtxState(currentCtx, groupCtx); 1.5915 + this.ctx = groupCtx; 1.5916 + this.setGState([ 1.5917 + ['BM', 'Normal'], 1.5918 + ['ca', 1], 1.5919 + ['CA', 1] 1.5920 + ]); 1.5921 + this.groupStack.push(currentCtx); 1.5922 + this.groupLevel++; 1.5923 + }, 1.5924 + endSMaskGroup: function CanvasGraphics_endSMaskGroup() { 1.5925 + var groupCtx = this.ctx; 1.5926 + this.groupLevel--; 1.5927 + this.ctx = this.groupStack.pop(); 1.5928 + 1.5929 + composeSMask(this.ctx, this.current.activeSMask, groupCtx); 1.5930 + this.ctx.restore(); 1.5931 + }, 1.5932 + save: function CanvasGraphics_save() { 1.5933 + this.ctx.save(); 1.5934 + var old = this.current; 1.5935 + this.stateStack.push(old); 1.5936 + this.current = old.clone(); 1.5937 + if (this.current.activeSMask) { 1.5938 + this.current.activeSMask = null; 1.5939 + } 1.5940 + }, 1.5941 + restore: function CanvasGraphics_restore() { 1.5942 + var prev = this.stateStack.pop(); 1.5943 + if (prev) { 1.5944 + if (this.current.activeSMask) { 1.5945 + this.endSMaskGroup(); 1.5946 + } 1.5947 + 1.5948 + this.current = prev; 1.5949 + this.ctx.restore(); 1.5950 + } 1.5951 + }, 1.5952 + transform: function CanvasGraphics_transform(a, b, c, d, e, f) { 1.5953 + this.ctx.transform(a, b, c, d, e, f); 1.5954 + }, 1.5955 + 1.5956 + // Path 1.5957 + moveTo: function CanvasGraphics_moveTo(x, y) { 1.5958 + this.ctx.moveTo(x, y); 1.5959 + this.current.setCurrentPoint(x, y); 1.5960 + }, 1.5961 + lineTo: function CanvasGraphics_lineTo(x, y) { 1.5962 + this.ctx.lineTo(x, y); 1.5963 + this.current.setCurrentPoint(x, y); 1.5964 + }, 1.5965 + curveTo: function CanvasGraphics_curveTo(x1, y1, x2, y2, x3, y3) { 1.5966 + this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3); 1.5967 + this.current.setCurrentPoint(x3, y3); 1.5968 + }, 1.5969 + curveTo2: function CanvasGraphics_curveTo2(x2, y2, x3, y3) { 1.5970 + var current = this.current; 1.5971 + this.ctx.bezierCurveTo(current.x, current.y, x2, y2, x3, y3); 1.5972 + current.setCurrentPoint(x3, y3); 1.5973 + }, 1.5974 + curveTo3: function CanvasGraphics_curveTo3(x1, y1, x3, y3) { 1.5975 + this.curveTo(x1, y1, x3, y3, x3, y3); 1.5976 + this.current.setCurrentPoint(x3, y3); 1.5977 + }, 1.5978 + closePath: function CanvasGraphics_closePath() { 1.5979 + this.ctx.closePath(); 1.5980 + }, 1.5981 + rectangle: function CanvasGraphics_rectangle(x, y, width, height) { 1.5982 + if (width === 0) { 1.5983 + width = this.getSinglePixelWidth(); 1.5984 + } 1.5985 + if (height === 0) { 1.5986 + height = this.getSinglePixelWidth(); 1.5987 + } 1.5988 + 1.5989 + this.ctx.rect(x, y, width, height); 1.5990 + }, 1.5991 + stroke: function CanvasGraphics_stroke(consumePath) { 1.5992 + consumePath = typeof consumePath !== 'undefined' ? consumePath : true; 1.5993 + var ctx = this.ctx; 1.5994 + var strokeColor = this.current.strokeColor; 1.5995 + if (this.current.lineWidth === 0) { 1.5996 + ctx.lineWidth = this.getSinglePixelWidth(); 1.5997 + } 1.5998 + // For stroke we want to temporarily change the global alpha to the 1.5999 + // stroking alpha. 1.6000 + ctx.globalAlpha = this.current.strokeAlpha; 1.6001 + if (strokeColor && strokeColor.hasOwnProperty('type') && 1.6002 + strokeColor.type === 'Pattern') { 1.6003 + // for patterns, we transform to pattern space, calculate 1.6004 + // the pattern, call stroke, and restore to user space 1.6005 + ctx.save(); 1.6006 + ctx.strokeStyle = strokeColor.getPattern(ctx, this); 1.6007 + ctx.stroke(); 1.6008 + ctx.restore(); 1.6009 + } else { 1.6010 + ctx.stroke(); 1.6011 + } 1.6012 + if (consumePath) { 1.6013 + this.consumePath(); 1.6014 + } 1.6015 + // Restore the global alpha to the fill alpha 1.6016 + ctx.globalAlpha = this.current.fillAlpha; 1.6017 + }, 1.6018 + closeStroke: function CanvasGraphics_closeStroke() { 1.6019 + this.closePath(); 1.6020 + this.stroke(); 1.6021 + }, 1.6022 + fill: function CanvasGraphics_fill(consumePath) { 1.6023 + consumePath = typeof consumePath !== 'undefined' ? consumePath : true; 1.6024 + var ctx = this.ctx; 1.6025 + var fillColor = this.current.fillColor; 1.6026 + var needRestore = false; 1.6027 + 1.6028 + if (fillColor && fillColor.hasOwnProperty('type') && 1.6029 + fillColor.type === 'Pattern') { 1.6030 + ctx.save(); 1.6031 + ctx.fillStyle = fillColor.getPattern(ctx, this); 1.6032 + needRestore = true; 1.6033 + } 1.6034 + 1.6035 + if (this.pendingEOFill) { 1.6036 + if ('mozFillRule' in this.ctx) { 1.6037 + this.ctx.mozFillRule = 'evenodd'; 1.6038 + this.ctx.fill(); 1.6039 + this.ctx.mozFillRule = 'nonzero'; 1.6040 + } else { 1.6041 + try { 1.6042 + this.ctx.fill('evenodd'); 1.6043 + } catch (ex) { 1.6044 + // shouldn't really happen, but browsers might think differently 1.6045 + this.ctx.fill(); 1.6046 + } 1.6047 + } 1.6048 + this.pendingEOFill = false; 1.6049 + } else { 1.6050 + this.ctx.fill(); 1.6051 + } 1.6052 + 1.6053 + if (needRestore) { 1.6054 + ctx.restore(); 1.6055 + } 1.6056 + if (consumePath) { 1.6057 + this.consumePath(); 1.6058 + } 1.6059 + }, 1.6060 + eoFill: function CanvasGraphics_eoFill() { 1.6061 + this.pendingEOFill = true; 1.6062 + this.fill(); 1.6063 + }, 1.6064 + fillStroke: function CanvasGraphics_fillStroke() { 1.6065 + this.fill(false); 1.6066 + this.stroke(false); 1.6067 + 1.6068 + this.consumePath(); 1.6069 + }, 1.6070 + eoFillStroke: function CanvasGraphics_eoFillStroke() { 1.6071 + this.pendingEOFill = true; 1.6072 + this.fillStroke(); 1.6073 + }, 1.6074 + closeFillStroke: function CanvasGraphics_closeFillStroke() { 1.6075 + this.closePath(); 1.6076 + this.fillStroke(); 1.6077 + }, 1.6078 + closeEOFillStroke: function CanvasGraphics_closeEOFillStroke() { 1.6079 + this.pendingEOFill = true; 1.6080 + this.closePath(); 1.6081 + this.fillStroke(); 1.6082 + }, 1.6083 + endPath: function CanvasGraphics_endPath() { 1.6084 + this.consumePath(); 1.6085 + }, 1.6086 + 1.6087 + // Clipping 1.6088 + clip: function CanvasGraphics_clip() { 1.6089 + this.pendingClip = NORMAL_CLIP; 1.6090 + }, 1.6091 + eoClip: function CanvasGraphics_eoClip() { 1.6092 + this.pendingClip = EO_CLIP; 1.6093 + }, 1.6094 + 1.6095 + // Text 1.6096 + beginText: function CanvasGraphics_beginText() { 1.6097 + this.current.textMatrix = IDENTITY_MATRIX; 1.6098 + this.current.x = this.current.lineX = 0; 1.6099 + this.current.y = this.current.lineY = 0; 1.6100 + }, 1.6101 + endText: function CanvasGraphics_endText() { 1.6102 + if (!('pendingTextPaths' in this)) { 1.6103 + this.ctx.beginPath(); 1.6104 + return; 1.6105 + } 1.6106 + var paths = this.pendingTextPaths; 1.6107 + var ctx = this.ctx; 1.6108 + 1.6109 + ctx.save(); 1.6110 + ctx.beginPath(); 1.6111 + for (var i = 0; i < paths.length; i++) { 1.6112 + var path = paths[i]; 1.6113 + ctx.setTransform.apply(ctx, path.transform); 1.6114 + ctx.translate(path.x, path.y); 1.6115 + path.addToPath(ctx, path.fontSize); 1.6116 + } 1.6117 + ctx.restore(); 1.6118 + ctx.clip(); 1.6119 + ctx.beginPath(); 1.6120 + delete this.pendingTextPaths; 1.6121 + }, 1.6122 + setCharSpacing: function CanvasGraphics_setCharSpacing(spacing) { 1.6123 + this.current.charSpacing = spacing; 1.6124 + }, 1.6125 + setWordSpacing: function CanvasGraphics_setWordSpacing(spacing) { 1.6126 + this.current.wordSpacing = spacing; 1.6127 + }, 1.6128 + setHScale: function CanvasGraphics_setHScale(scale) { 1.6129 + this.current.textHScale = scale / 100; 1.6130 + }, 1.6131 + setLeading: function CanvasGraphics_setLeading(leading) { 1.6132 + this.current.leading = -leading; 1.6133 + }, 1.6134 + setFont: function CanvasGraphics_setFont(fontRefName, size) { 1.6135 + var fontObj = this.commonObjs.get(fontRefName); 1.6136 + var current = this.current; 1.6137 + 1.6138 + if (!fontObj) { 1.6139 + error('Can\'t find font for ' + fontRefName); 1.6140 + } 1.6141 + 1.6142 + current.fontMatrix = (fontObj.fontMatrix ? 1.6143 + fontObj.fontMatrix : FONT_IDENTITY_MATRIX); 1.6144 + 1.6145 + // A valid matrix needs all main diagonal elements to be non-zero 1.6146 + // This also ensures we bypass FF bugzilla bug #719844. 1.6147 + if (current.fontMatrix[0] === 0 || 1.6148 + current.fontMatrix[3] === 0) { 1.6149 + warn('Invalid font matrix for font ' + fontRefName); 1.6150 + } 1.6151 + 1.6152 + // The spec for Tf (setFont) says that 'size' specifies the font 'scale', 1.6153 + // and in some docs this can be negative (inverted x-y axes). 1.6154 + if (size < 0) { 1.6155 + size = -size; 1.6156 + current.fontDirection = -1; 1.6157 + } else { 1.6158 + current.fontDirection = 1; 1.6159 + } 1.6160 + 1.6161 + this.current.font = fontObj; 1.6162 + this.current.fontSize = size; 1.6163 + 1.6164 + if (fontObj.coded) { 1.6165 + return; // we don't need ctx.font for Type3 fonts 1.6166 + } 1.6167 + 1.6168 + var name = fontObj.loadedName || 'sans-serif'; 1.6169 + var bold = fontObj.black ? (fontObj.bold ? 'bolder' : 'bold') : 1.6170 + (fontObj.bold ? 'bold' : 'normal'); 1.6171 + 1.6172 + var italic = fontObj.italic ? 'italic' : 'normal'; 1.6173 + var typeface = '"' + name + '", ' + fontObj.fallbackName; 1.6174 + 1.6175 + // Some font backends cannot handle fonts below certain size. 1.6176 + // Keeping the font at minimal size and using the fontSizeScale to change 1.6177 + // the current transformation matrix before the fillText/strokeText. 1.6178 + // See https://bugzilla.mozilla.org/show_bug.cgi?id=726227 1.6179 + var browserFontSize = size >= MIN_FONT_SIZE ? size : MIN_FONT_SIZE; 1.6180 + this.current.fontSizeScale = browserFontSize != MIN_FONT_SIZE ? 1.0 : 1.6181 + size / MIN_FONT_SIZE; 1.6182 + 1.6183 + var rule = italic + ' ' + bold + ' ' + browserFontSize + 'px ' + typeface; 1.6184 + this.ctx.font = rule; 1.6185 + }, 1.6186 + setTextRenderingMode: function CanvasGraphics_setTextRenderingMode(mode) { 1.6187 + this.current.textRenderingMode = mode; 1.6188 + }, 1.6189 + setTextRise: function CanvasGraphics_setTextRise(rise) { 1.6190 + this.current.textRise = rise; 1.6191 + }, 1.6192 + moveText: function CanvasGraphics_moveText(x, y) { 1.6193 + this.current.x = this.current.lineX += x; 1.6194 + this.current.y = this.current.lineY += y; 1.6195 + }, 1.6196 + setLeadingMoveText: function CanvasGraphics_setLeadingMoveText(x, y) { 1.6197 + this.setLeading(-y); 1.6198 + this.moveText(x, y); 1.6199 + }, 1.6200 + setTextMatrix: function CanvasGraphics_setTextMatrix(a, b, c, d, e, f) { 1.6201 + this.current.textMatrix = [a, b, c, d, e, f]; 1.6202 + 1.6203 + this.current.x = this.current.lineX = 0; 1.6204 + this.current.y = this.current.lineY = 0; 1.6205 + }, 1.6206 + nextLine: function CanvasGraphics_nextLine() { 1.6207 + this.moveText(0, this.current.leading); 1.6208 + }, 1.6209 + applyTextTransforms: function CanvasGraphics_applyTextTransforms() { 1.6210 + var ctx = this.ctx; 1.6211 + var current = this.current; 1.6212 + ctx.transform.apply(ctx, current.textMatrix); 1.6213 + ctx.translate(current.x, current.y + current.textRise); 1.6214 + if (current.fontDirection > 0) { 1.6215 + ctx.scale(current.textHScale, -1); 1.6216 + } else { 1.6217 + ctx.scale(-current.textHScale, 1); 1.6218 + } 1.6219 + }, 1.6220 + 1.6221 + paintChar: function (character, x, y) { 1.6222 + var ctx = this.ctx; 1.6223 + var current = this.current; 1.6224 + var font = current.font; 1.6225 + var fontSize = current.fontSize / current.fontSizeScale; 1.6226 + var textRenderingMode = current.textRenderingMode; 1.6227 + var fillStrokeMode = textRenderingMode & 1.6228 + TextRenderingMode.FILL_STROKE_MASK; 1.6229 + var isAddToPathSet = !!(textRenderingMode & 1.6230 + TextRenderingMode.ADD_TO_PATH_FLAG); 1.6231 + 1.6232 + var addToPath; 1.6233 + if (font.disableFontFace || isAddToPathSet) { 1.6234 + addToPath = font.getPathGenerator(this.commonObjs, character); 1.6235 + } 1.6236 + 1.6237 + if (font.disableFontFace) { 1.6238 + ctx.save(); 1.6239 + ctx.translate(x, y); 1.6240 + ctx.beginPath(); 1.6241 + addToPath(ctx, fontSize); 1.6242 + if (fillStrokeMode === TextRenderingMode.FILL || 1.6243 + fillStrokeMode === TextRenderingMode.FILL_STROKE) { 1.6244 + ctx.fill(); 1.6245 + } 1.6246 + if (fillStrokeMode === TextRenderingMode.STROKE || 1.6247 + fillStrokeMode === TextRenderingMode.FILL_STROKE) { 1.6248 + ctx.stroke(); 1.6249 + } 1.6250 + ctx.restore(); 1.6251 + } else { 1.6252 + if (fillStrokeMode === TextRenderingMode.FILL || 1.6253 + fillStrokeMode === TextRenderingMode.FILL_STROKE) { 1.6254 + ctx.fillText(character, x, y); 1.6255 + } 1.6256 + if (fillStrokeMode === TextRenderingMode.STROKE || 1.6257 + fillStrokeMode === TextRenderingMode.FILL_STROKE) { 1.6258 + ctx.strokeText(character, x, y); 1.6259 + } 1.6260 + } 1.6261 + 1.6262 + if (isAddToPathSet) { 1.6263 + var paths = this.pendingTextPaths || (this.pendingTextPaths = []); 1.6264 + paths.push({ 1.6265 + transform: ctx.mozCurrentTransform, 1.6266 + x: x, 1.6267 + y: y, 1.6268 + fontSize: fontSize, 1.6269 + addToPath: addToPath 1.6270 + }); 1.6271 + } 1.6272 + }, 1.6273 + 1.6274 + get isFontSubpixelAAEnabled() { 1.6275 + // Checks if anti-aliasing is enabled when scaled text is painted. 1.6276 + // On Windows GDI scaled fonts looks bad. 1.6277 + var ctx = document.createElement('canvas').getContext('2d'); 1.6278 + ctx.scale(1.5, 1); 1.6279 + ctx.fillText('I', 0, 10); 1.6280 + var data = ctx.getImageData(0, 0, 10, 10).data; 1.6281 + var enabled = false; 1.6282 + for (var i = 3; i < data.length; i += 4) { 1.6283 + if (data[i] > 0 && data[i] < 255) { 1.6284 + enabled = true; 1.6285 + break; 1.6286 + } 1.6287 + } 1.6288 + return shadow(this, 'isFontSubpixelAAEnabled', enabled); 1.6289 + }, 1.6290 + 1.6291 + showText: function CanvasGraphics_showText(glyphs) { 1.6292 + var ctx = this.ctx; 1.6293 + var current = this.current; 1.6294 + var font = current.font; 1.6295 + var fontSize = current.fontSize; 1.6296 + var fontSizeScale = current.fontSizeScale; 1.6297 + var charSpacing = current.charSpacing; 1.6298 + var wordSpacing = current.wordSpacing; 1.6299 + var textHScale = current.textHScale * current.fontDirection; 1.6300 + var fontMatrix = current.fontMatrix || FONT_IDENTITY_MATRIX; 1.6301 + var glyphsLength = glyphs.length; 1.6302 + var vertical = font.vertical; 1.6303 + var defaultVMetrics = font.defaultVMetrics; 1.6304 + var i, glyph, width; 1.6305 + 1.6306 + if (fontSize === 0) { 1.6307 + return; 1.6308 + } 1.6309 + 1.6310 + // Type3 fonts - each glyph is a "mini-PDF" 1.6311 + if (font.coded) { 1.6312 + ctx.save(); 1.6313 + ctx.transform.apply(ctx, current.textMatrix); 1.6314 + ctx.translate(current.x, current.y); 1.6315 + 1.6316 + ctx.scale(textHScale, 1); 1.6317 + 1.6318 + for (i = 0; i < glyphsLength; ++i) { 1.6319 + glyph = glyphs[i]; 1.6320 + if (glyph === null) { 1.6321 + // word break 1.6322 + this.ctx.translate(wordSpacing, 0); 1.6323 + current.x += wordSpacing * textHScale; 1.6324 + continue; 1.6325 + } 1.6326 + 1.6327 + this.processingType3 = glyph; 1.6328 + this.save(); 1.6329 + ctx.scale(fontSize, fontSize); 1.6330 + ctx.transform.apply(ctx, fontMatrix); 1.6331 + this.executeOperatorList(glyph.operatorList); 1.6332 + this.restore(); 1.6333 + 1.6334 + var transformed = Util.applyTransform([glyph.width, 0], fontMatrix); 1.6335 + width = ((transformed[0] * fontSize + charSpacing) * 1.6336 + current.fontDirection); 1.6337 + 1.6338 + ctx.translate(width, 0); 1.6339 + current.x += width * textHScale; 1.6340 + } 1.6341 + ctx.restore(); 1.6342 + this.processingType3 = null; 1.6343 + } else { 1.6344 + ctx.save(); 1.6345 + this.applyTextTransforms(); 1.6346 + 1.6347 + var lineWidth = current.lineWidth; 1.6348 + var a1 = current.textMatrix[0], b1 = current.textMatrix[1]; 1.6349 + var scale = Math.sqrt(a1 * a1 + b1 * b1); 1.6350 + if (scale === 0 || lineWidth === 0) { 1.6351 + lineWidth = this.getSinglePixelWidth(); 1.6352 + } else { 1.6353 + lineWidth /= scale; 1.6354 + } 1.6355 + 1.6356 + if (fontSizeScale != 1.0) { 1.6357 + ctx.scale(fontSizeScale, fontSizeScale); 1.6358 + lineWidth /= fontSizeScale; 1.6359 + } 1.6360 + 1.6361 + ctx.lineWidth = lineWidth; 1.6362 + 1.6363 + var x = 0; 1.6364 + for (i = 0; i < glyphsLength; ++i) { 1.6365 + glyph = glyphs[i]; 1.6366 + if (glyph === null) { 1.6367 + // word break 1.6368 + x += current.fontDirection * wordSpacing; 1.6369 + continue; 1.6370 + } 1.6371 + 1.6372 + var restoreNeeded = false; 1.6373 + var character = glyph.fontChar; 1.6374 + var vmetric = glyph.vmetric || defaultVMetrics; 1.6375 + if (vertical) { 1.6376 + var vx = glyph.vmetric ? vmetric[1] : glyph.width * 0.5; 1.6377 + vx = -vx * fontSize * current.fontMatrix[0]; 1.6378 + var vy = vmetric[2] * fontSize * current.fontMatrix[0]; 1.6379 + } 1.6380 + width = vmetric ? -vmetric[0] : glyph.width; 1.6381 + var charWidth = width * fontSize * current.fontMatrix[0] + 1.6382 + charSpacing * current.fontDirection; 1.6383 + var accent = glyph.accent; 1.6384 + 1.6385 + var scaledX, scaledY, scaledAccentX, scaledAccentY; 1.6386 + 1.6387 + if (vertical) { 1.6388 + scaledX = vx / fontSizeScale; 1.6389 + scaledY = (x + vy) / fontSizeScale; 1.6390 + } else { 1.6391 + scaledX = x / fontSizeScale; 1.6392 + scaledY = 0; 1.6393 + } 1.6394 + 1.6395 + if (font.remeasure && width > 0 && this.isFontSubpixelAAEnabled) { 1.6396 + // some standard fonts may not have the exact width, trying to 1.6397 + // rescale per character 1.6398 + var measuredWidth = ctx.measureText(character).width * 1000 / 1.6399 + current.fontSize * current.fontSizeScale; 1.6400 + var characterScaleX = width / measuredWidth; 1.6401 + restoreNeeded = true; 1.6402 + ctx.save(); 1.6403 + ctx.scale(characterScaleX, 1); 1.6404 + scaledX /= characterScaleX; 1.6405 + if (accent) { 1.6406 + scaledAccentX /= characterScaleX; 1.6407 + } 1.6408 + } 1.6409 + 1.6410 + this.paintChar(character, scaledX, scaledY); 1.6411 + if (accent) { 1.6412 + scaledAccentX = scaledX + accent.offset.x / fontSizeScale; 1.6413 + scaledAccentY = scaledY - accent.offset.y / fontSizeScale; 1.6414 + this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY); 1.6415 + } 1.6416 + 1.6417 + x += charWidth; 1.6418 + 1.6419 + if (restoreNeeded) { 1.6420 + ctx.restore(); 1.6421 + } 1.6422 + } 1.6423 + if (vertical) { 1.6424 + current.y -= x * textHScale; 1.6425 + } else { 1.6426 + current.x += x * textHScale; 1.6427 + } 1.6428 + ctx.restore(); 1.6429 + } 1.6430 + }, 1.6431 + showSpacedText: function CanvasGraphics_showSpacedText(arr) { 1.6432 + var current = this.current; 1.6433 + var font = current.font; 1.6434 + var fontSize = current.fontSize; 1.6435 + // TJ array's number is independent from fontMatrix 1.6436 + var textHScale = current.textHScale * 0.001 * current.fontDirection; 1.6437 + var arrLength = arr.length; 1.6438 + var vertical = font.vertical; 1.6439 + 1.6440 + for (var i = 0; i < arrLength; ++i) { 1.6441 + var e = arr[i]; 1.6442 + if (isNum(e)) { 1.6443 + var spacingLength = -e * fontSize * textHScale; 1.6444 + if (vertical) { 1.6445 + current.y += spacingLength; 1.6446 + } else { 1.6447 + current.x += spacingLength; 1.6448 + } 1.6449 + 1.6450 + } else { 1.6451 + this.showText(e); 1.6452 + } 1.6453 + } 1.6454 + }, 1.6455 + nextLineShowText: function CanvasGraphics_nextLineShowText(text) { 1.6456 + this.nextLine(); 1.6457 + this.showText(text); 1.6458 + }, 1.6459 + nextLineSetSpacingShowText: 1.6460 + function CanvasGraphics_nextLineSetSpacingShowText(wordSpacing, 1.6461 + charSpacing, 1.6462 + text) { 1.6463 + this.setWordSpacing(wordSpacing); 1.6464 + this.setCharSpacing(charSpacing); 1.6465 + this.nextLineShowText(text); 1.6466 + }, 1.6467 + 1.6468 + // Type3 fonts 1.6469 + setCharWidth: function CanvasGraphics_setCharWidth(xWidth, yWidth) { 1.6470 + // We can safely ignore this since the width should be the same 1.6471 + // as the width in the Widths array. 1.6472 + }, 1.6473 + setCharWidthAndBounds: function CanvasGraphics_setCharWidthAndBounds(xWidth, 1.6474 + yWidth, 1.6475 + llx, 1.6476 + lly, 1.6477 + urx, 1.6478 + ury) { 1.6479 + // TODO According to the spec we're also suppose to ignore any operators 1.6480 + // that set color or include images while processing this type3 font. 1.6481 + this.rectangle(llx, lly, urx - llx, ury - lly); 1.6482 + this.clip(); 1.6483 + this.endPath(); 1.6484 + }, 1.6485 + 1.6486 + // Color 1.6487 + setStrokeColorSpace: function CanvasGraphics_setStrokeColorSpace(raw) { 1.6488 + this.current.strokeColorSpace = ColorSpace.fromIR(raw); 1.6489 + }, 1.6490 + setFillColorSpace: function CanvasGraphics_setFillColorSpace(raw) { 1.6491 + this.current.fillColorSpace = ColorSpace.fromIR(raw); 1.6492 + }, 1.6493 + setStrokeColor: function CanvasGraphics_setStrokeColor(/*...*/) { 1.6494 + var cs = this.current.strokeColorSpace; 1.6495 + var rgbColor = cs.getRgb(arguments, 0); 1.6496 + var color = Util.makeCssRgb(rgbColor); 1.6497 + this.ctx.strokeStyle = color; 1.6498 + this.current.strokeColor = color; 1.6499 + }, 1.6500 + getColorN_Pattern: function CanvasGraphics_getColorN_Pattern(IR, cs) { 1.6501 + var pattern; 1.6502 + if (IR[0] == 'TilingPattern') { 1.6503 + var args = IR[1]; 1.6504 + var base = cs.base; 1.6505 + var color; 1.6506 + if (base) { 1.6507 + color = base.getRgb(args, 0); 1.6508 + } 1.6509 + pattern = new TilingPattern(IR, color, this.ctx, this.objs, 1.6510 + this.commonObjs, this.baseTransform); 1.6511 + } else { 1.6512 + pattern = getShadingPatternFromIR(IR); 1.6513 + } 1.6514 + return pattern; 1.6515 + }, 1.6516 + setStrokeColorN: function CanvasGraphics_setStrokeColorN(/*...*/) { 1.6517 + var cs = this.current.strokeColorSpace; 1.6518 + 1.6519 + if (cs.name == 'Pattern') { 1.6520 + this.current.strokeColor = this.getColorN_Pattern(arguments, cs); 1.6521 + } else { 1.6522 + this.setStrokeColor.apply(this, arguments); 1.6523 + } 1.6524 + }, 1.6525 + setFillColor: function CanvasGraphics_setFillColor(/*...*/) { 1.6526 + var cs = this.current.fillColorSpace; 1.6527 + var rgbColor = cs.getRgb(arguments, 0); 1.6528 + var color = Util.makeCssRgb(rgbColor); 1.6529 + this.ctx.fillStyle = color; 1.6530 + this.current.fillColor = color; 1.6531 + }, 1.6532 + setFillColorN: function CanvasGraphics_setFillColorN(/*...*/) { 1.6533 + var cs = this.current.fillColorSpace; 1.6534 + 1.6535 + if (cs.name == 'Pattern') { 1.6536 + this.current.fillColor = this.getColorN_Pattern(arguments, cs); 1.6537 + } else { 1.6538 + this.setFillColor.apply(this, arguments); 1.6539 + } 1.6540 + }, 1.6541 + setStrokeGray: function CanvasGraphics_setStrokeGray(gray) { 1.6542 + this.current.strokeColorSpace = ColorSpace.singletons.gray; 1.6543 + 1.6544 + var rgbColor = this.current.strokeColorSpace.getRgb(arguments, 0); 1.6545 + var color = Util.makeCssRgb(rgbColor); 1.6546 + this.ctx.strokeStyle = color; 1.6547 + this.current.strokeColor = color; 1.6548 + }, 1.6549 + setFillGray: function CanvasGraphics_setFillGray(gray) { 1.6550 + this.current.fillColorSpace = ColorSpace.singletons.gray; 1.6551 + 1.6552 + var rgbColor = this.current.fillColorSpace.getRgb(arguments, 0); 1.6553 + var color = Util.makeCssRgb(rgbColor); 1.6554 + this.ctx.fillStyle = color; 1.6555 + this.current.fillColor = color; 1.6556 + }, 1.6557 + setStrokeRGBColor: function CanvasGraphics_setStrokeRGBColor(r, g, b) { 1.6558 + this.current.strokeColorSpace = ColorSpace.singletons.rgb; 1.6559 + 1.6560 + var rgbColor = this.current.strokeColorSpace.getRgb(arguments, 0); 1.6561 + var color = Util.makeCssRgb(rgbColor); 1.6562 + this.ctx.strokeStyle = color; 1.6563 + this.current.strokeColor = color; 1.6564 + }, 1.6565 + setFillRGBColor: function CanvasGraphics_setFillRGBColor(r, g, b) { 1.6566 + this.current.fillColorSpace = ColorSpace.singletons.rgb; 1.6567 + 1.6568 + var rgbColor = this.current.fillColorSpace.getRgb(arguments, 0); 1.6569 + var color = Util.makeCssRgb(rgbColor); 1.6570 + this.ctx.fillStyle = color; 1.6571 + this.current.fillColor = color; 1.6572 + }, 1.6573 + setStrokeCMYKColor: function CanvasGraphics_setStrokeCMYKColor(c, m, y, k) { 1.6574 + this.current.strokeColorSpace = ColorSpace.singletons.cmyk; 1.6575 + 1.6576 + var color = Util.makeCssCmyk(arguments); 1.6577 + this.ctx.strokeStyle = color; 1.6578 + this.current.strokeColor = color; 1.6579 + }, 1.6580 + setFillCMYKColor: function CanvasGraphics_setFillCMYKColor(c, m, y, k) { 1.6581 + this.current.fillColorSpace = ColorSpace.singletons.cmyk; 1.6582 + 1.6583 + var color = Util.makeCssCmyk(arguments); 1.6584 + this.ctx.fillStyle = color; 1.6585 + this.current.fillColor = color; 1.6586 + }, 1.6587 + 1.6588 + shadingFill: function CanvasGraphics_shadingFill(patternIR) { 1.6589 + var ctx = this.ctx; 1.6590 + 1.6591 + this.save(); 1.6592 + var pattern = getShadingPatternFromIR(patternIR); 1.6593 + ctx.fillStyle = pattern.getPattern(ctx, this, true); 1.6594 + 1.6595 + var inv = ctx.mozCurrentTransformInverse; 1.6596 + if (inv) { 1.6597 + var canvas = ctx.canvas; 1.6598 + var width = canvas.width; 1.6599 + var height = canvas.height; 1.6600 + 1.6601 + var bl = Util.applyTransform([0, 0], inv); 1.6602 + var br = Util.applyTransform([0, height], inv); 1.6603 + var ul = Util.applyTransform([width, 0], inv); 1.6604 + var ur = Util.applyTransform([width, height], inv); 1.6605 + 1.6606 + var x0 = Math.min(bl[0], br[0], ul[0], ur[0]); 1.6607 + var y0 = Math.min(bl[1], br[1], ul[1], ur[1]); 1.6608 + var x1 = Math.max(bl[0], br[0], ul[0], ur[0]); 1.6609 + var y1 = Math.max(bl[1], br[1], ul[1], ur[1]); 1.6610 + 1.6611 + this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0); 1.6612 + } else { 1.6613 + // HACK to draw the gradient onto an infinite rectangle. 1.6614 + // PDF gradients are drawn across the entire image while 1.6615 + // Canvas only allows gradients to be drawn in a rectangle 1.6616 + // The following bug should allow us to remove this. 1.6617 + // https://bugzilla.mozilla.org/show_bug.cgi?id=664884 1.6618 + 1.6619 + this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10); 1.6620 + } 1.6621 + 1.6622 + this.restore(); 1.6623 + }, 1.6624 + 1.6625 + // Images 1.6626 + beginInlineImage: function CanvasGraphics_beginInlineImage() { 1.6627 + error('Should not call beginInlineImage'); 1.6628 + }, 1.6629 + beginImageData: function CanvasGraphics_beginImageData() { 1.6630 + error('Should not call beginImageData'); 1.6631 + }, 1.6632 + 1.6633 + paintFormXObjectBegin: function CanvasGraphics_paintFormXObjectBegin(matrix, 1.6634 + bbox) { 1.6635 + this.save(); 1.6636 + this.baseTransformStack.push(this.baseTransform); 1.6637 + 1.6638 + if (matrix && isArray(matrix) && 6 == matrix.length) { 1.6639 + this.transform.apply(this, matrix); 1.6640 + } 1.6641 + 1.6642 + this.baseTransform = this.ctx.mozCurrentTransform; 1.6643 + 1.6644 + if (bbox && isArray(bbox) && 4 == bbox.length) { 1.6645 + var width = bbox[2] - bbox[0]; 1.6646 + var height = bbox[3] - bbox[1]; 1.6647 + this.rectangle(bbox[0], bbox[1], width, height); 1.6648 + this.clip(); 1.6649 + this.endPath(); 1.6650 + } 1.6651 + }, 1.6652 + 1.6653 + paintFormXObjectEnd: function CanvasGraphics_paintFormXObjectEnd() { 1.6654 + this.restore(); 1.6655 + this.baseTransform = this.baseTransformStack.pop(); 1.6656 + }, 1.6657 + 1.6658 + beginGroup: function CanvasGraphics_beginGroup(group) { 1.6659 + this.save(); 1.6660 + var currentCtx = this.ctx; 1.6661 + // TODO non-isolated groups - according to Rik at adobe non-isolated 1.6662 + // group results aren't usually that different and they even have tools 1.6663 + // that ignore this setting. Notes from Rik on implmenting: 1.6664 + // - When you encounter an transparency group, create a new canvas with 1.6665 + // the dimensions of the bbox 1.6666 + // - copy the content from the previous canvas to the new canvas 1.6667 + // - draw as usual 1.6668 + // - remove the backdrop alpha: 1.6669 + // alphaNew = 1 - (1 - alpha)/(1 - alphaBackdrop) with 'alpha' the alpha 1.6670 + // value of your transparency group and 'alphaBackdrop' the alpha of the 1.6671 + // backdrop 1.6672 + // - remove background color: 1.6673 + // colorNew = color - alphaNew *colorBackdrop /(1 - alphaNew) 1.6674 + if (!group.isolated) { 1.6675 + info('TODO: Support non-isolated groups.'); 1.6676 + } 1.6677 + 1.6678 + // TODO knockout - supposedly possible with the clever use of compositing 1.6679 + // modes. 1.6680 + if (group.knockout) { 1.6681 + warn('Knockout groups not supported.'); 1.6682 + } 1.6683 + 1.6684 + var currentTransform = currentCtx.mozCurrentTransform; 1.6685 + if (group.matrix) { 1.6686 + currentCtx.transform.apply(currentCtx, group.matrix); 1.6687 + } 1.6688 + assert(group.bbox, 'Bounding box is required.'); 1.6689 + 1.6690 + // Based on the current transform figure out how big the bounding box 1.6691 + // will actually be. 1.6692 + var bounds = Util.getAxialAlignedBoundingBox( 1.6693 + group.bbox, 1.6694 + currentCtx.mozCurrentTransform); 1.6695 + // Clip the bounding box to the current canvas. 1.6696 + var canvasBounds = [0, 1.6697 + 0, 1.6698 + currentCtx.canvas.width, 1.6699 + currentCtx.canvas.height]; 1.6700 + bounds = Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0]; 1.6701 + // Use ceil in case we're between sizes so we don't create canvas that is 1.6702 + // too small and make the canvas at least 1x1 pixels. 1.6703 + var offsetX = Math.floor(bounds[0]); 1.6704 + var offsetY = Math.floor(bounds[1]); 1.6705 + var drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1); 1.6706 + var drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1); 1.6707 + var scaleX = 1, scaleY = 1; 1.6708 + if (drawnWidth > MAX_GROUP_SIZE) { 1.6709 + scaleX = drawnWidth / MAX_GROUP_SIZE; 1.6710 + drawnWidth = MAX_GROUP_SIZE; 1.6711 + } 1.6712 + if (drawnHeight > MAX_GROUP_SIZE) { 1.6713 + scaleY = drawnHeight / MAX_GROUP_SIZE; 1.6714 + drawnHeight = MAX_GROUP_SIZE; 1.6715 + } 1.6716 + 1.6717 + var cacheId = 'groupAt' + this.groupLevel; 1.6718 + if (group.smask) { 1.6719 + // Using two cache entries is case if masks are used one after another. 1.6720 + cacheId += '_smask_' + ((this.smaskCounter++) % 2); 1.6721 + } 1.6722 + var scratchCanvas = CachedCanvases.getCanvas( 1.6723 + cacheId, drawnWidth, drawnHeight, true); 1.6724 + var groupCtx = scratchCanvas.context; 1.6725 + 1.6726 + // Since we created a new canvas that is just the size of the bounding box 1.6727 + // we have to translate the group ctx. 1.6728 + groupCtx.scale(1 / scaleX, 1 / scaleY); 1.6729 + groupCtx.translate(-offsetX, -offsetY); 1.6730 + groupCtx.transform.apply(groupCtx, currentTransform); 1.6731 + 1.6732 + if (group.smask) { 1.6733 + // Saving state and cached mask to be used in setGState. 1.6734 + this.smaskStack.push({ 1.6735 + canvas: scratchCanvas.canvas, 1.6736 + context: groupCtx, 1.6737 + offsetX: offsetX, 1.6738 + offsetY: offsetY, 1.6739 + scaleX: scaleX, 1.6740 + scaleY: scaleY, 1.6741 + subtype: group.smask.subtype, 1.6742 + backdrop: group.smask.backdrop, 1.6743 + colorSpace: group.colorSpace && ColorSpace.fromIR(group.colorSpace) 1.6744 + }); 1.6745 + } else { 1.6746 + // Setup the current ctx so when the group is popped we draw it at the 1.6747 + // right location. 1.6748 + currentCtx.setTransform(1, 0, 0, 1, 0, 0); 1.6749 + currentCtx.translate(offsetX, offsetY); 1.6750 + currentCtx.scale(scaleX, scaleY); 1.6751 + } 1.6752 + // The transparency group inherits all off the current graphics state 1.6753 + // except the blend mode, soft mask, and alpha constants. 1.6754 + copyCtxState(currentCtx, groupCtx); 1.6755 + this.ctx = groupCtx; 1.6756 + this.setGState([ 1.6757 + ['BM', 'Normal'], 1.6758 + ['ca', 1], 1.6759 + ['CA', 1] 1.6760 + ]); 1.6761 + this.groupStack.push(currentCtx); 1.6762 + this.groupLevel++; 1.6763 + }, 1.6764 + 1.6765 + endGroup: function CanvasGraphics_endGroup(group) { 1.6766 + this.groupLevel--; 1.6767 + var groupCtx = this.ctx; 1.6768 + this.ctx = this.groupStack.pop(); 1.6769 + // Turn off image smoothing to avoid sub pixel interpolation which can 1.6770 + // look kind of blurry for some pdfs. 1.6771 + if ('imageSmoothingEnabled' in this.ctx) { 1.6772 + this.ctx.imageSmoothingEnabled = false; 1.6773 + } else { 1.6774 + this.ctx.mozImageSmoothingEnabled = false; 1.6775 + } 1.6776 + if (group.smask) { 1.6777 + this.tempSMask = this.smaskStack.pop(); 1.6778 + } else { 1.6779 + this.ctx.drawImage(groupCtx.canvas, 0, 0); 1.6780 + } 1.6781 + this.restore(); 1.6782 + }, 1.6783 + 1.6784 + beginAnnotations: function CanvasGraphics_beginAnnotations() { 1.6785 + this.save(); 1.6786 + this.current = new CanvasExtraState(); 1.6787 + }, 1.6788 + 1.6789 + endAnnotations: function CanvasGraphics_endAnnotations() { 1.6790 + this.restore(); 1.6791 + }, 1.6792 + 1.6793 + beginAnnotation: function CanvasGraphics_beginAnnotation(rect, transform, 1.6794 + matrix) { 1.6795 + this.save(); 1.6796 + 1.6797 + if (rect && isArray(rect) && 4 == rect.length) { 1.6798 + var width = rect[2] - rect[0]; 1.6799 + var height = rect[3] - rect[1]; 1.6800 + this.rectangle(rect[0], rect[1], width, height); 1.6801 + this.clip(); 1.6802 + this.endPath(); 1.6803 + } 1.6804 + 1.6805 + this.transform.apply(this, transform); 1.6806 + this.transform.apply(this, matrix); 1.6807 + }, 1.6808 + 1.6809 + endAnnotation: function CanvasGraphics_endAnnotation() { 1.6810 + this.restore(); 1.6811 + }, 1.6812 + 1.6813 + paintJpegXObject: function CanvasGraphics_paintJpegXObject(objId, w, h) { 1.6814 + var domImage = this.objs.get(objId); 1.6815 + if (!domImage) { 1.6816 + warn('Dependent image isn\'t ready yet'); 1.6817 + return; 1.6818 + } 1.6819 + 1.6820 + this.save(); 1.6821 + 1.6822 + var ctx = this.ctx; 1.6823 + // scale the image to the unit square 1.6824 + ctx.scale(1 / w, -1 / h); 1.6825 + 1.6826 + ctx.drawImage(domImage, 0, 0, domImage.width, domImage.height, 1.6827 + 0, -h, w, h); 1.6828 + if (this.imageLayer) { 1.6829 + var currentTransform = ctx.mozCurrentTransformInverse; 1.6830 + var position = this.getCanvasPosition(0, 0); 1.6831 + this.imageLayer.appendImage({ 1.6832 + objId: objId, 1.6833 + left: position[0], 1.6834 + top: position[1], 1.6835 + width: w / currentTransform[0], 1.6836 + height: h / currentTransform[3] 1.6837 + }); 1.6838 + } 1.6839 + this.restore(); 1.6840 + }, 1.6841 + 1.6842 + paintImageMaskXObject: function CanvasGraphics_paintImageMaskXObject(img) { 1.6843 + var ctx = this.ctx; 1.6844 + var width = img.width, height = img.height; 1.6845 + 1.6846 + var glyph = this.processingType3; 1.6847 + 1.6848 + if (COMPILE_TYPE3_GLYPHS && glyph && !('compiled' in glyph)) { 1.6849 + var MAX_SIZE_TO_COMPILE = 1000; 1.6850 + if (width <= MAX_SIZE_TO_COMPILE && height <= MAX_SIZE_TO_COMPILE) { 1.6851 + glyph.compiled = 1.6852 + compileType3Glyph({data: img.data, width: width, height: height}); 1.6853 + } else { 1.6854 + glyph.compiled = null; 1.6855 + } 1.6856 + } 1.6857 + 1.6858 + if (glyph && glyph.compiled) { 1.6859 + glyph.compiled(ctx); 1.6860 + return; 1.6861 + } 1.6862 + 1.6863 + var maskCanvas = CachedCanvases.getCanvas('maskCanvas', width, height); 1.6864 + var maskCtx = maskCanvas.context; 1.6865 + maskCtx.save(); 1.6866 + 1.6867 + putBinaryImageMask(maskCtx, img); 1.6868 + 1.6869 + maskCtx.globalCompositeOperation = 'source-in'; 1.6870 + 1.6871 + var fillColor = this.current.fillColor; 1.6872 + maskCtx.fillStyle = (fillColor && fillColor.hasOwnProperty('type') && 1.6873 + fillColor.type === 'Pattern') ? 1.6874 + fillColor.getPattern(maskCtx, this) : fillColor; 1.6875 + maskCtx.fillRect(0, 0, width, height); 1.6876 + 1.6877 + maskCtx.restore(); 1.6878 + 1.6879 + this.paintInlineImageXObject(maskCanvas.canvas); 1.6880 + }, 1.6881 + 1.6882 + paintImageMaskXObjectRepeat: 1.6883 + function CanvasGraphics_paintImageMaskXObjectRepeat(imgData, scaleX, 1.6884 + scaleY, positions) { 1.6885 + var width = imgData.width; 1.6886 + var height = imgData.height; 1.6887 + var ctx = this.ctx; 1.6888 + 1.6889 + var maskCanvas = CachedCanvases.getCanvas('maskCanvas', width, height); 1.6890 + var maskCtx = maskCanvas.context; 1.6891 + maskCtx.save(); 1.6892 + 1.6893 + putBinaryImageMask(maskCtx, imgData); 1.6894 + 1.6895 + maskCtx.globalCompositeOperation = 'source-in'; 1.6896 + 1.6897 + var fillColor = this.current.fillColor; 1.6898 + maskCtx.fillStyle = (fillColor && fillColor.hasOwnProperty('type') && 1.6899 + fillColor.type === 'Pattern') ? 1.6900 + fillColor.getPattern(maskCtx, this) : fillColor; 1.6901 + maskCtx.fillRect(0, 0, width, height); 1.6902 + 1.6903 + maskCtx.restore(); 1.6904 + 1.6905 + for (var i = 0, ii = positions.length; i < ii; i += 2) { 1.6906 + ctx.save(); 1.6907 + ctx.transform(scaleX, 0, 0, scaleY, positions[i], positions[i + 1]); 1.6908 + ctx.scale(1, -1); 1.6909 + ctx.drawImage(maskCanvas.canvas, 0, 0, width, height, 1.6910 + 0, -1, 1, 1); 1.6911 + ctx.restore(); 1.6912 + } 1.6913 + }, 1.6914 + 1.6915 + paintImageMaskXObjectGroup: 1.6916 + function CanvasGraphics_paintImageMaskXObjectGroup(images) { 1.6917 + var ctx = this.ctx; 1.6918 + 1.6919 + for (var i = 0, ii = images.length; i < ii; i++) { 1.6920 + var image = images[i]; 1.6921 + var width = image.width, height = image.height; 1.6922 + 1.6923 + var maskCanvas = CachedCanvases.getCanvas('maskCanvas', width, height); 1.6924 + var maskCtx = maskCanvas.context; 1.6925 + maskCtx.save(); 1.6926 + 1.6927 + putBinaryImageMask(maskCtx, image); 1.6928 + 1.6929 + maskCtx.globalCompositeOperation = 'source-in'; 1.6930 + 1.6931 + var fillColor = this.current.fillColor; 1.6932 + maskCtx.fillStyle = (fillColor && fillColor.hasOwnProperty('type') && 1.6933 + fillColor.type === 'Pattern') ? 1.6934 + fillColor.getPattern(maskCtx, this) : fillColor; 1.6935 + maskCtx.fillRect(0, 0, width, height); 1.6936 + 1.6937 + maskCtx.restore(); 1.6938 + 1.6939 + ctx.save(); 1.6940 + ctx.transform.apply(ctx, image.transform); 1.6941 + ctx.scale(1, -1); 1.6942 + ctx.drawImage(maskCanvas.canvas, 0, 0, width, height, 1.6943 + 0, -1, 1, 1); 1.6944 + ctx.restore(); 1.6945 + } 1.6946 + }, 1.6947 + 1.6948 + paintImageXObject: function CanvasGraphics_paintImageXObject(objId) { 1.6949 + var imgData = this.objs.get(objId); 1.6950 + if (!imgData) { 1.6951 + warn('Dependent image isn\'t ready yet'); 1.6952 + return; 1.6953 + } 1.6954 + 1.6955 + this.paintInlineImageXObject(imgData); 1.6956 + }, 1.6957 + 1.6958 + paintImageXObjectRepeat: 1.6959 + function CanvasGraphics_paintImageXObjectRepeat(objId, scaleX, scaleY, 1.6960 + positions) { 1.6961 + var imgData = this.objs.get(objId); 1.6962 + if (!imgData) { 1.6963 + warn('Dependent image isn\'t ready yet'); 1.6964 + return; 1.6965 + } 1.6966 + 1.6967 + var width = imgData.width; 1.6968 + var height = imgData.height; 1.6969 + var map = []; 1.6970 + for (var i = 0, ii = positions.length; i < ii; i += 2) { 1.6971 + map.push({transform: [scaleX, 0, 0, scaleY, positions[i], 1.6972 + positions[i + 1]], x: 0, y: 0, w: width, h: height}); 1.6973 + } 1.6974 + this.paintInlineImageXObjectGroup(imgData, map); 1.6975 + }, 1.6976 + 1.6977 + paintInlineImageXObject: 1.6978 + function CanvasGraphics_paintInlineImageXObject(imgData) { 1.6979 + var width = imgData.width; 1.6980 + var height = imgData.height; 1.6981 + var ctx = this.ctx; 1.6982 + 1.6983 + this.save(); 1.6984 + // scale the image to the unit square 1.6985 + ctx.scale(1 / width, -1 / height); 1.6986 + 1.6987 + var currentTransform = ctx.mozCurrentTransformInverse; 1.6988 + var a = currentTransform[0], b = currentTransform[1]; 1.6989 + var widthScale = Math.max(Math.sqrt(a * a + b * b), 1); 1.6990 + var c = currentTransform[2], d = currentTransform[3]; 1.6991 + var heightScale = Math.max(Math.sqrt(c * c + d * d), 1); 1.6992 + 1.6993 + var imgToPaint, tmpCanvas; 1.6994 + // instanceof HTMLElement does not work in jsdom node.js module 1.6995 + if (imgData instanceof HTMLElement || !imgData.data) { 1.6996 + imgToPaint = imgData; 1.6997 + } else { 1.6998 + tmpCanvas = CachedCanvases.getCanvas('inlineImage', width, height); 1.6999 + var tmpCtx = tmpCanvas.context; 1.7000 + putBinaryImageData(tmpCtx, imgData); 1.7001 + imgToPaint = tmpCanvas.canvas; 1.7002 + } 1.7003 + 1.7004 + var paintWidth = width, paintHeight = height; 1.7005 + var tmpCanvasId = 'prescale1'; 1.7006 + // Vertial or horizontal scaling shall not be more than 2 to not loose the 1.7007 + // pixels during drawImage operation, painting on the temporary canvas(es) 1.7008 + // that are twice smaller in size 1.7009 + while ((widthScale > 2 && paintWidth > 1) || 1.7010 + (heightScale > 2 && paintHeight > 1)) { 1.7011 + var newWidth = paintWidth, newHeight = paintHeight; 1.7012 + if (widthScale > 2 && paintWidth > 1) { 1.7013 + newWidth = Math.ceil(paintWidth / 2); 1.7014 + widthScale /= paintWidth / newWidth; 1.7015 + } 1.7016 + if (heightScale > 2 && paintHeight > 1) { 1.7017 + newHeight = Math.ceil(paintHeight / 2); 1.7018 + heightScale /= paintHeight / newHeight; 1.7019 + } 1.7020 + tmpCanvas = CachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight); 1.7021 + tmpCtx = tmpCanvas.context; 1.7022 + tmpCtx.clearRect(0, 0, newWidth, newHeight); 1.7023 + tmpCtx.drawImage(imgToPaint, 0, 0, paintWidth, paintHeight, 1.7024 + 0, 0, newWidth, newHeight); 1.7025 + imgToPaint = tmpCanvas.canvas; 1.7026 + paintWidth = newWidth; 1.7027 + paintHeight = newHeight; 1.7028 + tmpCanvasId = tmpCanvasId === 'prescale1' ? 'prescale2' : 'prescale1'; 1.7029 + } 1.7030 + ctx.drawImage(imgToPaint, 0, 0, paintWidth, paintHeight, 1.7031 + 0, -height, width, height); 1.7032 + 1.7033 + if (this.imageLayer) { 1.7034 + var position = this.getCanvasPosition(0, -height); 1.7035 + this.imageLayer.appendImage({ 1.7036 + imgData: imgData, 1.7037 + left: position[0], 1.7038 + top: position[1], 1.7039 + width: width / currentTransform[0], 1.7040 + height: height / currentTransform[3] 1.7041 + }); 1.7042 + } 1.7043 + this.restore(); 1.7044 + }, 1.7045 + 1.7046 + paintInlineImageXObjectGroup: 1.7047 + function CanvasGraphics_paintInlineImageXObjectGroup(imgData, map) { 1.7048 + var ctx = this.ctx; 1.7049 + var w = imgData.width; 1.7050 + var h = imgData.height; 1.7051 + 1.7052 + var tmpCanvas = CachedCanvases.getCanvas('inlineImage', w, h); 1.7053 + var tmpCtx = tmpCanvas.context; 1.7054 + putBinaryImageData(tmpCtx, imgData); 1.7055 + 1.7056 + for (var i = 0, ii = map.length; i < ii; i++) { 1.7057 + var entry = map[i]; 1.7058 + ctx.save(); 1.7059 + ctx.transform.apply(ctx, entry.transform); 1.7060 + ctx.scale(1, -1); 1.7061 + ctx.drawImage(tmpCanvas.canvas, entry.x, entry.y, entry.w, entry.h, 1.7062 + 0, -1, 1, 1); 1.7063 + if (this.imageLayer) { 1.7064 + var position = this.getCanvasPosition(entry.x, entry.y); 1.7065 + this.imageLayer.appendImage({ 1.7066 + imgData: imgData, 1.7067 + left: position[0], 1.7068 + top: position[1], 1.7069 + width: w, 1.7070 + height: h 1.7071 + }); 1.7072 + } 1.7073 + ctx.restore(); 1.7074 + } 1.7075 + }, 1.7076 + 1.7077 + paintSolidColorImageMask: 1.7078 + function CanvasGraphics_paintSolidColorImageMask() { 1.7079 + this.ctx.fillRect(0, 0, 1, 1); 1.7080 + }, 1.7081 + 1.7082 + // Marked content 1.7083 + 1.7084 + markPoint: function CanvasGraphics_markPoint(tag) { 1.7085 + // TODO Marked content. 1.7086 + }, 1.7087 + markPointProps: function CanvasGraphics_markPointProps(tag, properties) { 1.7088 + // TODO Marked content. 1.7089 + }, 1.7090 + beginMarkedContent: function CanvasGraphics_beginMarkedContent(tag) { 1.7091 + // TODO Marked content. 1.7092 + }, 1.7093 + beginMarkedContentProps: function CanvasGraphics_beginMarkedContentProps( 1.7094 + tag, properties) { 1.7095 + // TODO Marked content. 1.7096 + }, 1.7097 + endMarkedContent: function CanvasGraphics_endMarkedContent() { 1.7098 + // TODO Marked content. 1.7099 + }, 1.7100 + 1.7101 + // Compatibility 1.7102 + 1.7103 + beginCompat: function CanvasGraphics_beginCompat() { 1.7104 + // TODO ignore undefined operators (should we do that anyway?) 1.7105 + }, 1.7106 + endCompat: function CanvasGraphics_endCompat() { 1.7107 + // TODO stop ignoring undefined operators 1.7108 + }, 1.7109 + 1.7110 + // Helper functions 1.7111 + 1.7112 + consumePath: function CanvasGraphics_consumePath() { 1.7113 + if (this.pendingClip) { 1.7114 + if (this.pendingClip == EO_CLIP) { 1.7115 + if ('mozFillRule' in this.ctx) { 1.7116 + this.ctx.mozFillRule = 'evenodd'; 1.7117 + this.ctx.clip(); 1.7118 + this.ctx.mozFillRule = 'nonzero'; 1.7119 + } else { 1.7120 + try { 1.7121 + this.ctx.clip('evenodd'); 1.7122 + } catch (ex) { 1.7123 + // shouldn't really happen, but browsers might think differently 1.7124 + this.ctx.clip(); 1.7125 + } 1.7126 + } 1.7127 + } else { 1.7128 + this.ctx.clip(); 1.7129 + } 1.7130 + this.pendingClip = null; 1.7131 + } 1.7132 + this.ctx.beginPath(); 1.7133 + }, 1.7134 + getSinglePixelWidth: function CanvasGraphics_getSinglePixelWidth(scale) { 1.7135 + var inverse = this.ctx.mozCurrentTransformInverse; 1.7136 + // max of the current horizontal and vertical scale 1.7137 + return Math.sqrt(Math.max( 1.7138 + (inverse[0] * inverse[0] + inverse[1] * inverse[1]), 1.7139 + (inverse[2] * inverse[2] + inverse[3] * inverse[3]))); 1.7140 + }, 1.7141 + getCanvasPosition: function CanvasGraphics_getCanvasPosition(x, y) { 1.7142 + var transform = this.ctx.mozCurrentTransform; 1.7143 + return [ 1.7144 + transform[0] * x + transform[2] * y + transform[4], 1.7145 + transform[1] * x + transform[3] * y + transform[5] 1.7146 + ]; 1.7147 + } 1.7148 + }; 1.7149 + 1.7150 + for (var op in OPS) { 1.7151 + CanvasGraphics.prototype[OPS[op]] = CanvasGraphics.prototype[op]; 1.7152 + } 1.7153 + 1.7154 + return CanvasGraphics; 1.7155 +})(); 1.7156 + 1.7157 + 1.7158 + 1.7159 +var WebGLUtils = (function WebGLUtilsClosure() { 1.7160 + function loadShader(gl, code, shaderType) { 1.7161 + var shader = gl.createShader(shaderType); 1.7162 + gl.shaderSource(shader, code); 1.7163 + gl.compileShader(shader); 1.7164 + var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); 1.7165 + if (!compiled) { 1.7166 + var errorMsg = gl.getShaderInfoLog(shader); 1.7167 + throw new Error('Error during shader compilation: ' + errorMsg); 1.7168 + } 1.7169 + return shader; 1.7170 + } 1.7171 + function createVertexShader(gl, code) { 1.7172 + return loadShader(gl, code, gl.VERTEX_SHADER); 1.7173 + } 1.7174 + function createFragmentShader(gl, code) { 1.7175 + return loadShader(gl, code, gl.FRAGMENT_SHADER); 1.7176 + } 1.7177 + function createProgram(gl, shaders) { 1.7178 + var program = gl.createProgram(); 1.7179 + for (var i = 0, ii = shaders.length; i < ii; ++i) { 1.7180 + gl.attachShader(program, shaders[i]); 1.7181 + } 1.7182 + gl.linkProgram(program); 1.7183 + var linked = gl.getProgramParameter(program, gl.LINK_STATUS); 1.7184 + if (!linked) { 1.7185 + var errorMsg = gl.getProgramInfoLog(program); 1.7186 + throw new Error('Error during program linking: ' + errorMsg); 1.7187 + } 1.7188 + return program; 1.7189 + } 1.7190 + function createTexture(gl, image, textureId) { 1.7191 + gl.activeTexture(textureId); 1.7192 + var texture = gl.createTexture(); 1.7193 + gl.bindTexture(gl.TEXTURE_2D, texture); 1.7194 + 1.7195 + // Set the parameters so we can render any size image. 1.7196 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 1.7197 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 1.7198 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 1.7199 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 1.7200 + 1.7201 + // Upload the image into the texture. 1.7202 + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); 1.7203 + return texture; 1.7204 + } 1.7205 + 1.7206 + var currentGL, currentCanvas; 1.7207 + function generageGL() { 1.7208 + if (currentGL) { 1.7209 + return; 1.7210 + } 1.7211 + currentCanvas = document.createElement('canvas'); 1.7212 + currentGL = currentCanvas.getContext('webgl', 1.7213 + { premultipliedalpha: false }); 1.7214 + } 1.7215 + 1.7216 + var smaskVertexShaderCode = '\ 1.7217 + attribute vec2 a_position; \ 1.7218 + attribute vec2 a_texCoord; \ 1.7219 + \ 1.7220 + uniform vec2 u_resolution; \ 1.7221 + \ 1.7222 + varying vec2 v_texCoord; \ 1.7223 + \ 1.7224 + void main() { \ 1.7225 + vec2 clipSpace = (a_position / u_resolution) * 2.0 - 1.0; \ 1.7226 + gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1); \ 1.7227 + \ 1.7228 + v_texCoord = a_texCoord; \ 1.7229 + } '; 1.7230 + 1.7231 + var smaskFragmentShaderCode = '\ 1.7232 + precision mediump float; \ 1.7233 + \ 1.7234 + uniform vec4 u_backdrop; \ 1.7235 + uniform int u_subtype; \ 1.7236 + uniform sampler2D u_image; \ 1.7237 + uniform sampler2D u_mask; \ 1.7238 + \ 1.7239 + varying vec2 v_texCoord; \ 1.7240 + \ 1.7241 + void main() { \ 1.7242 + vec4 imageColor = texture2D(u_image, v_texCoord); \ 1.7243 + vec4 maskColor = texture2D(u_mask, v_texCoord); \ 1.7244 + if (u_backdrop.a > 0.0) { \ 1.7245 + maskColor.rgb = maskColor.rgb * maskColor.a + \ 1.7246 + u_backdrop.rgb * (1.0 - maskColor.a); \ 1.7247 + } \ 1.7248 + float lum; \ 1.7249 + if (u_subtype == 0) { \ 1.7250 + lum = maskColor.a; \ 1.7251 + } else { \ 1.7252 + lum = maskColor.r * 0.3 + maskColor.g * 0.59 + \ 1.7253 + maskColor.b * 0.11; \ 1.7254 + } \ 1.7255 + imageColor.a *= lum; \ 1.7256 + imageColor.rgb *= imageColor.a; \ 1.7257 + gl_FragColor = imageColor; \ 1.7258 + } '; 1.7259 + 1.7260 + var smaskCache = null; 1.7261 + 1.7262 + function initSmaskGL() { 1.7263 + var canvas, gl; 1.7264 + 1.7265 + generageGL(); 1.7266 + canvas = currentCanvas; 1.7267 + currentCanvas = null; 1.7268 + gl = currentGL; 1.7269 + currentGL = null; 1.7270 + 1.7271 + // setup a GLSL program 1.7272 + var vertexShader = createVertexShader(gl, smaskVertexShaderCode); 1.7273 + var fragmentShader = createFragmentShader(gl, smaskFragmentShaderCode); 1.7274 + var program = createProgram(gl, [vertexShader, fragmentShader]); 1.7275 + gl.useProgram(program); 1.7276 + 1.7277 + var cache = {}; 1.7278 + cache.gl = gl; 1.7279 + cache.canvas = canvas; 1.7280 + cache.resolutionLocation = gl.getUniformLocation(program, 'u_resolution'); 1.7281 + cache.positionLocation = gl.getAttribLocation(program, 'a_position'); 1.7282 + cache.backdropLocation = gl.getUniformLocation(program, 'u_backdrop'); 1.7283 + cache.subtypeLocation = gl.getUniformLocation(program, 'u_subtype'); 1.7284 + 1.7285 + var texCoordLocation = gl.getAttribLocation(program, 'a_texCoord'); 1.7286 + var texLayerLocation = gl.getUniformLocation(program, 'u_image'); 1.7287 + var texMaskLocation = gl.getUniformLocation(program, 'u_mask'); 1.7288 + 1.7289 + // provide texture coordinates for the rectangle. 1.7290 + var texCoordBuffer = gl.createBuffer(); 1.7291 + gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer); 1.7292 + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 1.7293 + 0.0, 0.0, 1.7294 + 1.0, 0.0, 1.7295 + 0.0, 1.0, 1.7296 + 0.0, 1.0, 1.7297 + 1.0, 0.0, 1.7298 + 1.0, 1.0]), gl.STATIC_DRAW); 1.7299 + gl.enableVertexAttribArray(texCoordLocation); 1.7300 + gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0); 1.7301 + 1.7302 + gl.uniform1i(texLayerLocation, 0); 1.7303 + gl.uniform1i(texMaskLocation, 1); 1.7304 + 1.7305 + smaskCache = cache; 1.7306 + } 1.7307 + 1.7308 + function composeSMask(layer, mask, properties) { 1.7309 + var width = layer.width, height = layer.height; 1.7310 + 1.7311 + if (!smaskCache) { 1.7312 + initSmaskGL(); 1.7313 + } 1.7314 + var cache = smaskCache,canvas = cache.canvas, gl = cache.gl; 1.7315 + canvas.width = width; 1.7316 + canvas.height = height; 1.7317 + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); 1.7318 + gl.uniform2f(cache.resolutionLocation, width, height); 1.7319 + 1.7320 + if (properties.backdrop) { 1.7321 + gl.uniform4f(cache.resolutionLocation, properties.backdrop[0], 1.7322 + properties.backdrop[1], properties.backdrop[2], 1); 1.7323 + } else { 1.7324 + gl.uniform4f(cache.resolutionLocation, 0, 0, 0, 0); 1.7325 + } 1.7326 + gl.uniform1i(cache.subtypeLocation, 1.7327 + properties.subtype === 'Luminosity' ? 1 : 0); 1.7328 + 1.7329 + // Create a textures 1.7330 + var texture = createTexture(gl, layer, gl.TEXTURE0); 1.7331 + var maskTexture = createTexture(gl, mask, gl.TEXTURE1); 1.7332 + 1.7333 + 1.7334 + // Create a buffer and put a single clipspace rectangle in 1.7335 + // it (2 triangles) 1.7336 + var buffer = gl.createBuffer(); 1.7337 + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 1.7338 + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 1.7339 + 0, 0, 1.7340 + width, 0, 1.7341 + 0, height, 1.7342 + 0, height, 1.7343 + width, 0, 1.7344 + width, height]), gl.STATIC_DRAW); 1.7345 + gl.enableVertexAttribArray(cache.positionLocation); 1.7346 + gl.vertexAttribPointer(cache.positionLocation, 2, gl.FLOAT, false, 0, 0); 1.7347 + 1.7348 + // draw 1.7349 + gl.clearColor(0, 0, 0, 0); 1.7350 + gl.enable(gl.BLEND); 1.7351 + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); 1.7352 + gl.clear(gl.COLOR_BUFFER_BIT); 1.7353 + 1.7354 + gl.drawArrays(gl.TRIANGLES, 0, 6); 1.7355 + 1.7356 + gl.flush(); 1.7357 + 1.7358 + gl.deleteTexture(texture); 1.7359 + gl.deleteTexture(maskTexture); 1.7360 + gl.deleteBuffer(buffer); 1.7361 + 1.7362 + return canvas; 1.7363 + } 1.7364 + 1.7365 + var figuresVertexShaderCode = '\ 1.7366 + attribute vec2 a_position; \ 1.7367 + attribute vec3 a_color; \ 1.7368 + \ 1.7369 + uniform vec2 u_resolution; \ 1.7370 + uniform vec2 u_scale; \ 1.7371 + uniform vec2 u_offset; \ 1.7372 + \ 1.7373 + varying vec4 v_color; \ 1.7374 + \ 1.7375 + void main() { \ 1.7376 + vec2 position = (a_position + u_offset) * u_scale; \ 1.7377 + vec2 clipSpace = (position / u_resolution) * 2.0 - 1.0; \ 1.7378 + gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1); \ 1.7379 + \ 1.7380 + v_color = vec4(a_color / 255.0, 1.0); \ 1.7381 + } '; 1.7382 + 1.7383 + var figuresFragmentShaderCode = '\ 1.7384 + precision mediump float; \ 1.7385 + \ 1.7386 + varying vec4 v_color; \ 1.7387 + \ 1.7388 + void main() { \ 1.7389 + gl_FragColor = v_color; \ 1.7390 + } '; 1.7391 + 1.7392 + var figuresCache = null; 1.7393 + 1.7394 + function initFiguresGL() { 1.7395 + var canvas, gl; 1.7396 + 1.7397 + generageGL(); 1.7398 + canvas = currentCanvas; 1.7399 + currentCanvas = null; 1.7400 + gl = currentGL; 1.7401 + currentGL = null; 1.7402 + 1.7403 + // setup a GLSL program 1.7404 + var vertexShader = createVertexShader(gl, figuresVertexShaderCode); 1.7405 + var fragmentShader = createFragmentShader(gl, figuresFragmentShaderCode); 1.7406 + var program = createProgram(gl, [vertexShader, fragmentShader]); 1.7407 + gl.useProgram(program); 1.7408 + 1.7409 + var cache = {}; 1.7410 + cache.gl = gl; 1.7411 + cache.canvas = canvas; 1.7412 + cache.resolutionLocation = gl.getUniformLocation(program, 'u_resolution'); 1.7413 + cache.scaleLocation = gl.getUniformLocation(program, 'u_scale'); 1.7414 + cache.offsetLocation = gl.getUniformLocation(program, 'u_offset'); 1.7415 + cache.positionLocation = gl.getAttribLocation(program, 'a_position'); 1.7416 + cache.colorLocation = gl.getAttribLocation(program, 'a_color'); 1.7417 + 1.7418 + figuresCache = cache; 1.7419 + } 1.7420 + 1.7421 + function drawFigures(width, height, backgroundColor, figures, context) { 1.7422 + if (!figuresCache) { 1.7423 + initFiguresGL(); 1.7424 + } 1.7425 + var cache = figuresCache, canvas = cache.canvas, gl = cache.gl; 1.7426 + 1.7427 + canvas.width = width; 1.7428 + canvas.height = height; 1.7429 + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); 1.7430 + gl.uniform2f(cache.resolutionLocation, width, height); 1.7431 + 1.7432 + // count triangle points 1.7433 + var count = 0; 1.7434 + var i, ii, rows; 1.7435 + for (i = 0, ii = figures.length; i < ii; i++) { 1.7436 + switch (figures[i].type) { 1.7437 + case 'lattice': 1.7438 + rows = (figures[i].coords.length / figures[i].verticesPerRow) | 0; 1.7439 + count += (rows - 1) * (figures[i].verticesPerRow - 1) * 6; 1.7440 + break; 1.7441 + case 'triangles': 1.7442 + count += figures[i].coords.length; 1.7443 + break; 1.7444 + } 1.7445 + } 1.7446 + // transfer data 1.7447 + var coords = new Float32Array(count * 2); 1.7448 + var colors = new Uint8Array(count * 3); 1.7449 + var coordsMap = context.coords, colorsMap = context.colors; 1.7450 + var pIndex = 0, cIndex = 0; 1.7451 + for (i = 0, ii = figures.length; i < ii; i++) { 1.7452 + var figure = figures[i], ps = figure.coords, cs = figure.colors; 1.7453 + switch (figure.type) { 1.7454 + case 'lattice': 1.7455 + var cols = figure.verticesPerRow; 1.7456 + rows = (ps.length / cols) | 0; 1.7457 + for (var row = 1; row < rows; row++) { 1.7458 + var offset = row * cols + 1; 1.7459 + for (var col = 1; col < cols; col++, offset++) { 1.7460 + coords[pIndex] = coordsMap[ps[offset - cols - 1]]; 1.7461 + coords[pIndex + 1] = coordsMap[ps[offset - cols - 1] + 1]; 1.7462 + coords[pIndex + 2] = coordsMap[ps[offset - cols]]; 1.7463 + coords[pIndex + 3] = coordsMap[ps[offset - cols] + 1]; 1.7464 + coords[pIndex + 4] = coordsMap[ps[offset - 1]]; 1.7465 + coords[pIndex + 5] = coordsMap[ps[offset - 1] + 1]; 1.7466 + colors[cIndex] = colorsMap[cs[offset - cols - 1]]; 1.7467 + colors[cIndex + 1] = colorsMap[cs[offset - cols - 1] + 1]; 1.7468 + colors[cIndex + 2] = colorsMap[cs[offset - cols - 1] + 2]; 1.7469 + colors[cIndex + 3] = colorsMap[cs[offset - cols]]; 1.7470 + colors[cIndex + 4] = colorsMap[cs[offset - cols] + 1]; 1.7471 + colors[cIndex + 5] = colorsMap[cs[offset - cols] + 2]; 1.7472 + colors[cIndex + 6] = colorsMap[cs[offset - 1]]; 1.7473 + colors[cIndex + 7] = colorsMap[cs[offset - 1] + 1]; 1.7474 + colors[cIndex + 8] = colorsMap[cs[offset - 1] + 2]; 1.7475 + 1.7476 + coords[pIndex + 6] = coords[pIndex + 2]; 1.7477 + coords[pIndex + 7] = coords[pIndex + 3]; 1.7478 + coords[pIndex + 8] = coords[pIndex + 4]; 1.7479 + coords[pIndex + 9] = coords[pIndex + 5]; 1.7480 + coords[pIndex + 10] = coordsMap[ps[offset]]; 1.7481 + coords[pIndex + 11] = coordsMap[ps[offset] + 1]; 1.7482 + colors[cIndex + 9] = colors[cIndex + 3]; 1.7483 + colors[cIndex + 10] = colors[cIndex + 4]; 1.7484 + colors[cIndex + 11] = colors[cIndex + 5]; 1.7485 + colors[cIndex + 12] = colors[cIndex + 6]; 1.7486 + colors[cIndex + 13] = colors[cIndex + 7]; 1.7487 + colors[cIndex + 14] = colors[cIndex + 8]; 1.7488 + colors[cIndex + 15] = colorsMap[cs[offset]]; 1.7489 + colors[cIndex + 16] = colorsMap[cs[offset] + 1]; 1.7490 + colors[cIndex + 17] = colorsMap[cs[offset] + 2]; 1.7491 + pIndex += 12; 1.7492 + cIndex += 18; 1.7493 + } 1.7494 + } 1.7495 + break; 1.7496 + case 'triangles': 1.7497 + for (var j = 0, jj = ps.length; j < jj; j++) { 1.7498 + coords[pIndex] = coordsMap[ps[j]]; 1.7499 + coords[pIndex + 1] = coordsMap[ps[j] + 1]; 1.7500 + colors[cIndex] = colorsMap[cs[i]]; 1.7501 + colors[cIndex + 1] = colorsMap[cs[j] + 1]; 1.7502 + colors[cIndex + 2] = colorsMap[cs[j] + 2]; 1.7503 + pIndex += 2; 1.7504 + cIndex += 3; 1.7505 + } 1.7506 + break; 1.7507 + } 1.7508 + } 1.7509 + 1.7510 + // draw 1.7511 + if (backgroundColor) { 1.7512 + gl.clearColor(backgroundColor[0] / 255, backgroundColor[1] / 255, 1.7513 + backgroundColor[2] / 255, 1.0); 1.7514 + } else { 1.7515 + gl.clearColor(0, 0, 0, 0); 1.7516 + } 1.7517 + gl.clear(gl.COLOR_BUFFER_BIT); 1.7518 + 1.7519 + var coordsBuffer = gl.createBuffer(); 1.7520 + gl.bindBuffer(gl.ARRAY_BUFFER, coordsBuffer); 1.7521 + gl.bufferData(gl.ARRAY_BUFFER, coords, gl.STATIC_DRAW); 1.7522 + gl.enableVertexAttribArray(cache.positionLocation); 1.7523 + gl.vertexAttribPointer(cache.positionLocation, 2, gl.FLOAT, false, 0, 0); 1.7524 + 1.7525 + var colorsBuffer = gl.createBuffer(); 1.7526 + gl.bindBuffer(gl.ARRAY_BUFFER, colorsBuffer); 1.7527 + gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); 1.7528 + gl.enableVertexAttribArray(cache.colorLocation); 1.7529 + gl.vertexAttribPointer(cache.colorLocation, 3, gl.UNSIGNED_BYTE, false, 1.7530 + 0, 0); 1.7531 + 1.7532 + gl.uniform2f(cache.scaleLocation, context.scaleX, context.scaleY); 1.7533 + gl.uniform2f(cache.offsetLocation, context.offsetX, context.offsetY); 1.7534 + 1.7535 + gl.drawArrays(gl.TRIANGLES, 0, count); 1.7536 + 1.7537 + gl.flush(); 1.7538 + 1.7539 + gl.deleteBuffer(coordsBuffer); 1.7540 + gl.deleteBuffer(colorsBuffer); 1.7541 + 1.7542 + return canvas; 1.7543 + } 1.7544 + 1.7545 + function cleanup() { 1.7546 + smaskCache = null; 1.7547 + figuresCache = null; 1.7548 + } 1.7549 + 1.7550 + return { 1.7551 + get isEnabled() { 1.7552 + if (PDFJS.disableWebGL) { 1.7553 + return false; 1.7554 + } 1.7555 + var enabled = false; 1.7556 + try { 1.7557 + generageGL(); 1.7558 + enabled = !!currentGL; 1.7559 + } catch (e) { } 1.7560 + return shadow(this, 'isEnabled', enabled); 1.7561 + }, 1.7562 + composeSMask: composeSMask, 1.7563 + drawFigures: drawFigures, 1.7564 + clear: cleanup 1.7565 + }; 1.7566 +})(); 1.7567 + 1.7568 + 1.7569 +var ShadingIRs = {}; 1.7570 + 1.7571 +ShadingIRs.RadialAxial = { 1.7572 + fromIR: function RadialAxial_fromIR(raw) { 1.7573 + var type = raw[1]; 1.7574 + var colorStops = raw[2]; 1.7575 + var p0 = raw[3]; 1.7576 + var p1 = raw[4]; 1.7577 + var r0 = raw[5]; 1.7578 + var r1 = raw[6]; 1.7579 + return { 1.7580 + type: 'Pattern', 1.7581 + getPattern: function RadialAxial_getPattern(ctx) { 1.7582 + var grad; 1.7583 + if (type === 'axial') { 1.7584 + grad = ctx.createLinearGradient(p0[0], p0[1], p1[0], p1[1]); 1.7585 + } else if (type === 'radial') { 1.7586 + grad = ctx.createRadialGradient(p0[0], p0[1], r0, p1[0], p1[1], r1); 1.7587 + } 1.7588 + 1.7589 + for (var i = 0, ii = colorStops.length; i < ii; ++i) { 1.7590 + var c = colorStops[i]; 1.7591 + grad.addColorStop(c[0], c[1]); 1.7592 + } 1.7593 + return grad; 1.7594 + } 1.7595 + }; 1.7596 + } 1.7597 +}; 1.7598 + 1.7599 +var createMeshCanvas = (function createMeshCanvasClosure() { 1.7600 + function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) { 1.7601 + // Very basic Gouraud-shaded triangle rasterization algorithm. 1.7602 + var coords = context.coords, colors = context.colors; 1.7603 + var bytes = data.data, rowSize = data.width * 4; 1.7604 + var tmp; 1.7605 + if (coords[p1 + 1] > coords[p2 + 1]) { 1.7606 + tmp = p1; p1 = p2; p2 = tmp; tmp = c1; c1 = c2; c2 = tmp; 1.7607 + } 1.7608 + if (coords[p2 + 1] > coords[p3 + 1]) { 1.7609 + tmp = p2; p2 = p3; p3 = tmp; tmp = c2; c2 = c3; c3 = tmp; 1.7610 + } 1.7611 + if (coords[p1 + 1] > coords[p2 + 1]) { 1.7612 + tmp = p1; p1 = p2; p2 = tmp; tmp = c1; c1 = c2; c2 = tmp; 1.7613 + } 1.7614 + var x1 = (coords[p1] + context.offsetX) * context.scaleX; 1.7615 + var y1 = (coords[p1 + 1] + context.offsetY) * context.scaleY; 1.7616 + var x2 = (coords[p2] + context.offsetX) * context.scaleX; 1.7617 + var y2 = (coords[p2 + 1] + context.offsetY) * context.scaleY; 1.7618 + var x3 = (coords[p3] + context.offsetX) * context.scaleX; 1.7619 + var y3 = (coords[p3 + 1] + context.offsetY) * context.scaleY; 1.7620 + if (y1 >= y3) { 1.7621 + return; 1.7622 + } 1.7623 + var c1r = colors[c1], c1g = colors[c1 + 1], c1b = colors[c1 + 2]; 1.7624 + var c2r = colors[c2], c2g = colors[c2 + 1], c2b = colors[c2 + 2]; 1.7625 + var c3r = colors[c3], c3g = colors[c3 + 1], c3b = colors[c3 + 2]; 1.7626 + 1.7627 + var minY = Math.round(y1), maxY = Math.round(y3); 1.7628 + var xa, car, cag, cab; 1.7629 + var xb, cbr, cbg, cbb; 1.7630 + var k; 1.7631 + for (var y = minY; y <= maxY; y++) { 1.7632 + if (y < y2) { 1.7633 + k = y < y1 ? 0 : y1 === y2 ? 1 : (y1 - y) / (y1 - y2); 1.7634 + xa = x1 - (x1 - x2) * k; 1.7635 + car = c1r - (c1r - c2r) * k; 1.7636 + cag = c1g - (c1g - c2g) * k; 1.7637 + cab = c1b - (c1b - c2b) * k; 1.7638 + } else { 1.7639 + k = y > y3 ? 1 : y2 === y3 ? 0 : (y2 - y) / (y2 - y3); 1.7640 + xa = x2 - (x2 - x3) * k; 1.7641 + car = c2r - (c2r - c3r) * k; 1.7642 + cag = c2g - (c2g - c3g) * k; 1.7643 + cab = c2b - (c2b - c3b) * k; 1.7644 + } 1.7645 + k = y < y1 ? 0 : y > y3 ? 1 : (y1 - y) / (y1 - y3); 1.7646 + xb = x1 - (x1 - x3) * k; 1.7647 + cbr = c1r - (c1r - c3r) * k; 1.7648 + cbg = c1g - (c1g - c3g) * k; 1.7649 + cbb = c1b - (c1b - c3b) * k; 1.7650 + var x1_ = Math.round(Math.min(xa, xb)); 1.7651 + var x2_ = Math.round(Math.max(xa, xb)); 1.7652 + var j = rowSize * y + x1_ * 4; 1.7653 + for (var x = x1_; x <= x2_; x++) { 1.7654 + k = (xa - x) / (xa - xb); 1.7655 + k = k < 0 ? 0 : k > 1 ? 1 : k; 1.7656 + bytes[j++] = (car - (car - cbr) * k) | 0; 1.7657 + bytes[j++] = (cag - (cag - cbg) * k) | 0; 1.7658 + bytes[j++] = (cab - (cab - cbb) * k) | 0; 1.7659 + bytes[j++] = 255; 1.7660 + } 1.7661 + } 1.7662 + } 1.7663 + 1.7664 + function drawFigure(data, figure, context) { 1.7665 + var ps = figure.coords; 1.7666 + var cs = figure.colors; 1.7667 + var i, ii; 1.7668 + switch (figure.type) { 1.7669 + case 'lattice': 1.7670 + var verticesPerRow = figure.verticesPerRow; 1.7671 + var rows = Math.floor(ps.length / verticesPerRow) - 1; 1.7672 + var cols = verticesPerRow - 1; 1.7673 + for (i = 0; i < rows; i++) { 1.7674 + var q = i * verticesPerRow; 1.7675 + for (var j = 0; j < cols; j++, q++) { 1.7676 + drawTriangle(data, context, 1.7677 + ps[q], ps[q + 1], ps[q + verticesPerRow], 1.7678 + cs[q], cs[q + 1], cs[q + verticesPerRow]); 1.7679 + drawTriangle(data, context, 1.7680 + ps[q + verticesPerRow + 1], ps[q + 1], ps[q + verticesPerRow], 1.7681 + cs[q + verticesPerRow + 1], cs[q + 1], cs[q + verticesPerRow]); 1.7682 + } 1.7683 + } 1.7684 + break; 1.7685 + case 'triangles': 1.7686 + for (i = 0, ii = ps.length; i < ii; i += 3) { 1.7687 + drawTriangle(data, context, 1.7688 + ps[i], ps[i + 1], ps[i + 2], 1.7689 + cs[i], cs[i + 1], cs[i + 2]); 1.7690 + } 1.7691 + break; 1.7692 + default: 1.7693 + error('illigal figure'); 1.7694 + break; 1.7695 + } 1.7696 + } 1.7697 + 1.7698 + function createMeshCanvas(bounds, combinesScale, coords, colors, figures, 1.7699 + backgroundColor) { 1.7700 + // we will increase scale on some weird factor to let antialiasing take 1.7701 + // care of "rough" edges 1.7702 + var EXPECTED_SCALE = 1.1; 1.7703 + // MAX_PATTERN_SIZE is used to avoid OOM situation. 1.7704 + var MAX_PATTERN_SIZE = 3000; // 10in @ 300dpi shall be enough 1.7705 + 1.7706 + var offsetX = Math.floor(bounds[0]); 1.7707 + var offsetY = Math.floor(bounds[1]); 1.7708 + var boundsWidth = Math.ceil(bounds[2]) - offsetX; 1.7709 + var boundsHeight = Math.ceil(bounds[3]) - offsetY; 1.7710 + 1.7711 + var width = Math.min(Math.ceil(Math.abs(boundsWidth * combinesScale[0] * 1.7712 + EXPECTED_SCALE)), MAX_PATTERN_SIZE); 1.7713 + var height = Math.min(Math.ceil(Math.abs(boundsHeight * combinesScale[1] * 1.7714 + EXPECTED_SCALE)), MAX_PATTERN_SIZE); 1.7715 + var scaleX = boundsWidth / width; 1.7716 + var scaleY = boundsHeight / height; 1.7717 + 1.7718 + var context = { 1.7719 + coords: coords, 1.7720 + colors: colors, 1.7721 + offsetX: -offsetX, 1.7722 + offsetY: -offsetY, 1.7723 + scaleX: 1 / scaleX, 1.7724 + scaleY: 1 / scaleY 1.7725 + }; 1.7726 + 1.7727 + var canvas, tmpCanvas, i, ii; 1.7728 + if (WebGLUtils.isEnabled) { 1.7729 + canvas = WebGLUtils.drawFigures(width, height, backgroundColor, 1.7730 + figures, context); 1.7731 + 1.7732 + // https://bugzilla.mozilla.org/show_bug.cgi?id=972126 1.7733 + tmpCanvas = CachedCanvases.getCanvas('mesh', width, height, false); 1.7734 + tmpCanvas.context.drawImage(canvas, 0, 0); 1.7735 + canvas = tmpCanvas.canvas; 1.7736 + } else { 1.7737 + tmpCanvas = CachedCanvases.getCanvas('mesh', width, height, false); 1.7738 + var tmpCtx = tmpCanvas.context; 1.7739 + 1.7740 + var data = tmpCtx.createImageData(width, height); 1.7741 + if (backgroundColor) { 1.7742 + var bytes = data.data; 1.7743 + for (i = 0, ii = bytes.length; i < ii; i += 4) { 1.7744 + bytes[i] = backgroundColor[0]; 1.7745 + bytes[i + 1] = backgroundColor[1]; 1.7746 + bytes[i + 2] = backgroundColor[2]; 1.7747 + bytes[i + 3] = 255; 1.7748 + } 1.7749 + } 1.7750 + for (i = 0; i < figures.length; i++) { 1.7751 + drawFigure(data, figures[i], context); 1.7752 + } 1.7753 + tmpCtx.putImageData(data, 0, 0); 1.7754 + canvas = tmpCanvas.canvas; 1.7755 + } 1.7756 + 1.7757 + return {canvas: canvas, offsetX: offsetX, offsetY: offsetY, 1.7758 + scaleX: scaleX, scaleY: scaleY}; 1.7759 + } 1.7760 + return createMeshCanvas; 1.7761 +})(); 1.7762 + 1.7763 +ShadingIRs.Mesh = { 1.7764 + fromIR: function Mesh_fromIR(raw) { 1.7765 + //var type = raw[1]; 1.7766 + var coords = raw[2]; 1.7767 + var colors = raw[3]; 1.7768 + var figures = raw[4]; 1.7769 + var bounds = raw[5]; 1.7770 + var matrix = raw[6]; 1.7771 + //var bbox = raw[7]; 1.7772 + var background = raw[8]; 1.7773 + return { 1.7774 + type: 'Pattern', 1.7775 + getPattern: function Mesh_getPattern(ctx, owner, shadingFill) { 1.7776 + var combinedScale; 1.7777 + // Obtain scale from matrix and current transformation matrix. 1.7778 + if (shadingFill) { 1.7779 + combinedScale = Util.singularValueDecompose2dScale( 1.7780 + ctx.mozCurrentTransform); 1.7781 + } else { 1.7782 + var matrixScale = Util.singularValueDecompose2dScale(matrix); 1.7783 + var curMatrixScale = Util.singularValueDecompose2dScale( 1.7784 + owner.baseTransform); 1.7785 + combinedScale = [matrixScale[0] * curMatrixScale[0], 1.7786 + matrixScale[1] * curMatrixScale[1]]; 1.7787 + } 1.7788 + 1.7789 + 1.7790 + // Rasterizing on the main thread since sending/queue large canvases 1.7791 + // might cause OOM. 1.7792 + var temporaryPatternCanvas = createMeshCanvas(bounds, combinedScale, 1.7793 + coords, colors, figures, shadingFill ? null : background); 1.7794 + 1.7795 + if (!shadingFill) { 1.7796 + ctx.setTransform.apply(ctx, owner.baseTransform); 1.7797 + if (matrix) { 1.7798 + ctx.transform.apply(ctx, matrix); 1.7799 + } 1.7800 + } 1.7801 + 1.7802 + ctx.translate(temporaryPatternCanvas.offsetX, 1.7803 + temporaryPatternCanvas.offsetY); 1.7804 + ctx.scale(temporaryPatternCanvas.scaleX, 1.7805 + temporaryPatternCanvas.scaleY); 1.7806 + 1.7807 + return ctx.createPattern(temporaryPatternCanvas.canvas, 'no-repeat'); 1.7808 + } 1.7809 + }; 1.7810 + } 1.7811 +}; 1.7812 + 1.7813 +ShadingIRs.Dummy = { 1.7814 + fromIR: function Dummy_fromIR() { 1.7815 + return { 1.7816 + type: 'Pattern', 1.7817 + getPattern: function Dummy_fromIR_getPattern() { 1.7818 + return 'hotpink'; 1.7819 + } 1.7820 + }; 1.7821 + } 1.7822 +}; 1.7823 + 1.7824 +function getShadingPatternFromIR(raw) { 1.7825 + var shadingIR = ShadingIRs[raw[0]]; 1.7826 + if (!shadingIR) { 1.7827 + error('Unknown IR type: ' + raw[0]); 1.7828 + } 1.7829 + return shadingIR.fromIR(raw); 1.7830 +} 1.7831 + 1.7832 +var TilingPattern = (function TilingPatternClosure() { 1.7833 + var PaintType = { 1.7834 + COLORED: 1, 1.7835 + UNCOLORED: 2 1.7836 + }; 1.7837 + 1.7838 + var MAX_PATTERN_SIZE = 3000; // 10in @ 300dpi shall be enough 1.7839 + 1.7840 + function TilingPattern(IR, color, ctx, objs, commonObjs, baseTransform) { 1.7841 + this.name = IR[1][0].name; 1.7842 + this.operatorList = IR[2]; 1.7843 + this.matrix = IR[3] || [1, 0, 0, 1, 0, 0]; 1.7844 + this.bbox = IR[4]; 1.7845 + this.xstep = IR[5]; 1.7846 + this.ystep = IR[6]; 1.7847 + this.paintType = IR[7]; 1.7848 + this.tilingType = IR[8]; 1.7849 + this.color = color; 1.7850 + this.objs = objs; 1.7851 + this.commonObjs = commonObjs; 1.7852 + this.baseTransform = baseTransform; 1.7853 + this.type = 'Pattern'; 1.7854 + this.ctx = ctx; 1.7855 + } 1.7856 + 1.7857 + TilingPattern.prototype = { 1.7858 + createPatternCanvas: function TilinPattern_createPatternCanvas(owner) { 1.7859 + var operatorList = this.operatorList; 1.7860 + var bbox = this.bbox; 1.7861 + var xstep = this.xstep; 1.7862 + var ystep = this.ystep; 1.7863 + var paintType = this.paintType; 1.7864 + var tilingType = this.tilingType; 1.7865 + var color = this.color; 1.7866 + var objs = this.objs; 1.7867 + var commonObjs = this.commonObjs; 1.7868 + 1.7869 + info('TilingType: ' + tilingType); 1.7870 + 1.7871 + var x0 = bbox[0], y0 = bbox[1], x1 = bbox[2], y1 = bbox[3]; 1.7872 + 1.7873 + var topLeft = [x0, y0]; 1.7874 + // we want the canvas to be as large as the step size 1.7875 + var botRight = [x0 + xstep, y0 + ystep]; 1.7876 + 1.7877 + var width = botRight[0] - topLeft[0]; 1.7878 + var height = botRight[1] - topLeft[1]; 1.7879 + 1.7880 + // Obtain scale from matrix and current transformation matrix. 1.7881 + var matrixScale = Util.singularValueDecompose2dScale(this.matrix); 1.7882 + var curMatrixScale = Util.singularValueDecompose2dScale( 1.7883 + this.baseTransform); 1.7884 + var combinedScale = [matrixScale[0] * curMatrixScale[0], 1.7885 + matrixScale[1] * curMatrixScale[1]]; 1.7886 + 1.7887 + // MAX_PATTERN_SIZE is used to avoid OOM situation. 1.7888 + // Use width and height values that are as close as possible to the end 1.7889 + // result when the pattern is used. Too low value makes the pattern look 1.7890 + // blurry. Too large value makes it look too crispy. 1.7891 + width = Math.min(Math.ceil(Math.abs(width * combinedScale[0])), 1.7892 + MAX_PATTERN_SIZE); 1.7893 + 1.7894 + height = Math.min(Math.ceil(Math.abs(height * combinedScale[1])), 1.7895 + MAX_PATTERN_SIZE); 1.7896 + 1.7897 + var tmpCanvas = CachedCanvases.getCanvas('pattern', width, height, true); 1.7898 + var tmpCtx = tmpCanvas.context; 1.7899 + var graphics = new CanvasGraphics(tmpCtx, commonObjs, objs); 1.7900 + graphics.groupLevel = owner.groupLevel; 1.7901 + 1.7902 + this.setFillAndStrokeStyleToContext(tmpCtx, paintType, color); 1.7903 + 1.7904 + this.setScale(width, height, xstep, ystep); 1.7905 + this.transformToScale(graphics); 1.7906 + 1.7907 + // transform coordinates to pattern space 1.7908 + var tmpTranslate = [1, 0, 0, 1, -topLeft[0], -topLeft[1]]; 1.7909 + graphics.transform.apply(graphics, tmpTranslate); 1.7910 + 1.7911 + this.clipBbox(graphics, bbox, x0, y0, x1, y1); 1.7912 + 1.7913 + graphics.executeOperatorList(operatorList); 1.7914 + return tmpCanvas.canvas; 1.7915 + }, 1.7916 + 1.7917 + setScale: function TilingPattern_setScale(width, height, xstep, ystep) { 1.7918 + this.scale = [width / xstep, height / ystep]; 1.7919 + }, 1.7920 + 1.7921 + transformToScale: function TilingPattern_transformToScale(graphics) { 1.7922 + var scale = this.scale; 1.7923 + var tmpScale = [scale[0], 0, 0, scale[1], 0, 0]; 1.7924 + graphics.transform.apply(graphics, tmpScale); 1.7925 + }, 1.7926 + 1.7927 + scaleToContext: function TilingPattern_scaleToContext() { 1.7928 + var scale = this.scale; 1.7929 + this.ctx.scale(1 / scale[0], 1 / scale[1]); 1.7930 + }, 1.7931 + 1.7932 + clipBbox: function clipBbox(graphics, bbox, x0, y0, x1, y1) { 1.7933 + if (bbox && isArray(bbox) && 4 == bbox.length) { 1.7934 + var bboxWidth = x1 - x0; 1.7935 + var bboxHeight = y1 - y0; 1.7936 + graphics.rectangle(x0, y0, bboxWidth, bboxHeight); 1.7937 + graphics.clip(); 1.7938 + graphics.endPath(); 1.7939 + } 1.7940 + }, 1.7941 + 1.7942 + setFillAndStrokeStyleToContext: 1.7943 + function setFillAndStrokeStyleToContext(context, paintType, color) { 1.7944 + switch (paintType) { 1.7945 + case PaintType.COLORED: 1.7946 + var ctx = this.ctx; 1.7947 + context.fillStyle = ctx.fillStyle; 1.7948 + context.strokeStyle = ctx.strokeStyle; 1.7949 + break; 1.7950 + case PaintType.UNCOLORED: 1.7951 + var rgbColor = ColorSpace.singletons.rgb.getRgb(color, 0); 1.7952 + var cssColor = Util.makeCssRgb(rgbColor); 1.7953 + context.fillStyle = cssColor; 1.7954 + context.strokeStyle = cssColor; 1.7955 + break; 1.7956 + default: 1.7957 + error('Unsupported paint type: ' + paintType); 1.7958 + } 1.7959 + }, 1.7960 + 1.7961 + getPattern: function TilingPattern_getPattern(ctx, owner) { 1.7962 + var temporaryPatternCanvas = this.createPatternCanvas(owner); 1.7963 + 1.7964 + ctx = this.ctx; 1.7965 + ctx.setTransform.apply(ctx, this.baseTransform); 1.7966 + ctx.transform.apply(ctx, this.matrix); 1.7967 + this.scaleToContext(); 1.7968 + 1.7969 + return ctx.createPattern(temporaryPatternCanvas, 'repeat'); 1.7970 + } 1.7971 + }; 1.7972 + 1.7973 + return TilingPattern; 1.7974 +})(); 1.7975 + 1.7976 + 1.7977 +PDFJS.disableFontFace = false; 1.7978 + 1.7979 +var FontLoader = { 1.7980 + insertRule: function fontLoaderInsertRule(rule) { 1.7981 + var styleElement = document.getElementById('PDFJS_FONT_STYLE_TAG'); 1.7982 + if (!styleElement) { 1.7983 + styleElement = document.createElement('style'); 1.7984 + styleElement.id = 'PDFJS_FONT_STYLE_TAG'; 1.7985 + document.documentElement.getElementsByTagName('head')[0].appendChild( 1.7986 + styleElement); 1.7987 + } 1.7988 + 1.7989 + var styleSheet = styleElement.sheet; 1.7990 + styleSheet.insertRule(rule, styleSheet.cssRules.length); 1.7991 + }, 1.7992 + 1.7993 + clear: function fontLoaderClear() { 1.7994 + var styleElement = document.getElementById('PDFJS_FONT_STYLE_TAG'); 1.7995 + if (styleElement) { 1.7996 + styleElement.parentNode.removeChild(styleElement); 1.7997 + } 1.7998 + }, 1.7999 + bind: function fontLoaderBind(fonts, callback) { 1.8000 + assert(!isWorker, 'bind() shall be called from main thread'); 1.8001 + 1.8002 + for (var i = 0, ii = fonts.length; i < ii; i++) { 1.8003 + var font = fonts[i]; 1.8004 + if (font.attached) { 1.8005 + continue; 1.8006 + } 1.8007 + 1.8008 + font.attached = true; 1.8009 + font.bindDOM() 1.8010 + } 1.8011 + 1.8012 + setTimeout(callback); 1.8013 + } 1.8014 +}; 1.8015 + 1.8016 +var FontFace = (function FontFaceClosure() { 1.8017 + function FontFace(name, file, properties) { 1.8018 + this.compiledGlyphs = {}; 1.8019 + if (arguments.length === 1) { 1.8020 + // importing translated data 1.8021 + var data = arguments[0]; 1.8022 + for (var i in data) { 1.8023 + this[i] = data[i]; 1.8024 + } 1.8025 + return; 1.8026 + } 1.8027 + } 1.8028 + FontFace.prototype = { 1.8029 + bindDOM: function FontFace_bindDOM() { 1.8030 + if (!this.data) { 1.8031 + return null; 1.8032 + } 1.8033 + 1.8034 + if (PDFJS.disableFontFace) { 1.8035 + this.disableFontFace = true; 1.8036 + return null; 1.8037 + } 1.8038 + 1.8039 + var data = bytesToString(new Uint8Array(this.data)); 1.8040 + var fontName = this.loadedName; 1.8041 + 1.8042 + // Add the font-face rule to the document 1.8043 + var url = ('url(data:' + this.mimetype + ';base64,' + 1.8044 + window.btoa(data) + ');'); 1.8045 + var rule = '@font-face { font-family:"' + fontName + '";src:' + url + '}'; 1.8046 + FontLoader.insertRule(rule); 1.8047 + 1.8048 + if (PDFJS.pdfBug && 'FontInspector' in globalScope && 1.8049 + globalScope['FontInspector'].enabled) { 1.8050 + globalScope['FontInspector'].fontAdded(this, url); 1.8051 + } 1.8052 + 1.8053 + return rule; 1.8054 + }, 1.8055 + 1.8056 + getPathGenerator: function (objs, character) { 1.8057 + if (!(character in this.compiledGlyphs)) { 1.8058 + var js = objs.get(this.loadedName + '_path_' + character); 1.8059 + /*jshint -W054 */ 1.8060 + this.compiledGlyphs[character] = new Function('c', 'size', js); 1.8061 + } 1.8062 + return this.compiledGlyphs[character]; 1.8063 + } 1.8064 + }; 1.8065 + return FontFace; 1.8066 +})(); 1.8067 + 1.8068 + 1.8069 +}).call((typeof window === 'undefined') ? this : window); 1.8070 + 1.8071 + 1.8072 +