diff --git a/media/js/pdf.js b/media/js/pdf.js index 2958f6852c..8aac86851d 100644 --- a/media/js/pdf.js +++ b/media/js/pdf.js @@ -1,8 +1,6 @@ /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - var PDFJS = {}; - (function pdfjsWrapper() { 'use strict'; PDFJS.build = '7fff630'; @@ -17,31 +15,23 @@ function getPdf(arg, callback) { var params = arg; if (typeof arg === 'string') params = { url: arg }; - var xhr = new XMLHttpRequest(); - xhr.open('GET', params.url); - var headers = params.headers; if (headers) { for (var property in headers) { if (typeof headers[property] === 'undefined') continue; - xhr.setRequestHeader(property, params.headers[property]); } } - xhr.mozResponseType = xhr.responseType = 'arraybuffer'; var protocol = params.url.indexOf(':') < 0 ? window.location.protocol : params.url.substring(0, params.url.indexOf(':') + 1); xhr.expected = (protocol === 'http:' || protocol === 'https:') ? 200 : 0; - if ('progress' in params) xhr.onprogress = params.progress || undefined; - var calledErrorBack = false; - if ('error' in params) { xhr.onerror = function errorBack() { if (!calledErrorBack) { @@ -50,7 +40,6 @@ function getPdf(arg, callback) { } } } - xhr.onreadystatechange = function getPdfOnreadystatechange(e) { if (xhr.readyState === 4) { if (xhr.status === xhr.expected) { @@ -67,17 +56,14 @@ function getPdf(arg, callback) { } globalScope.PDFJS.getPdf = getPdf; globalScope.PDFJS.pdfBug = false; - var Page = (function PageClosure() { function Page(xref, pageNumber, pageDict, ref) { this.pageNumber = pageNumber; this.pageDict = pageDict; this.xref = xref; this.ref = ref; - this.displayReadyPromise = null; } - Page.prototype = { getPageProp: function Page_getPageProp(key) { return this.pageDict.get(key); @@ -101,7 +87,6 @@ var Page = (function PageClosure() { }, get mediaBox() { var obj = this.inheritPageProp('MediaBox'); - // Reset invalid media box to letter size. if (!isArray(obj) || obj.length !== 4) obj = [0, 0, 612, 792]; return shadow(this, 'mediaBox', obj); @@ -114,7 +99,6 @@ var Page = (function PageClosure() { cropBox = Util.intersect(cropBox, mediaBox); if (!cropBox) return shadow(this, 'view', mediaBox); - return shadow(this, 'view', cropBox); }, get annotations() { @@ -131,13 +115,11 @@ var Page = (function PageClosure() { } return shadow(this, 'rotate', rotate); }, - getOperatorList: function Page_getOperatorList(handler, dependency) { var xref = this.xref; var content = this.content; var resources = this.resources; if (isArray(content)) { - // fetching items var streams = []; var i, n = content.length; var streams = []; @@ -147,13 +129,10 @@ var Page = (function PageClosure() { } else if (isStream(content)) { content.reset(); } else if (!content) { - // replacing non-existent page content with empty one content = new Stream(new Uint8Array(0)); } - var pe = this.pe = new PartialEvaluator( xref, handler, 'p' + this.pageNumber + '_'); - return pe.getOperatorList(content, resources, dependency); }, extractTextContent: function Page_extractTextContent() { @@ -161,12 +140,10 @@ var Page = (function PageClosure() { on: function nullHandlerOn() {}, send: function nullHandlerSend() {} }; - var xref = this.xref; var content = xref.fetchIfRef(this.content); var resources = xref.fetchIfRef(this.resources); if (isArray(content)) { - // fetching items var i, n = content.length; var streams = []; for (i = 0; i < n; ++i) @@ -175,25 +152,19 @@ var Page = (function PageClosure() { } else if (isStream(content)) { content.reset(); } - var pe = new PartialEvaluator( xref, handler, 'p' + this.pageNumber + '_'); return pe.getTextContent(content, resources); }, - ensureFonts: function Page_ensureFonts(fonts, callback) { this.stats.time('Font Loading'); - // Convert the font names to the corresponding font obj. for (var i = 0, ii = fonts.length; i < ii; i++) { fonts[i] = this.objs.objs[fonts[i]].data; } - - // Load all the fonts FontLoader.bind( fonts, function pageEnsureFontsFontObjs(fontObjs) { this.stats.timeEnd('Font Loading'); - callback.call(this); }.bind(this) ); @@ -237,7 +208,6 @@ var Page = (function PageClosure() { return false; } } - var annotations = this.annotations || []; var i, n = annotations.length; var items = []; @@ -250,7 +220,6 @@ var Page = (function PageClosure() { if (!isName(subtype)) continue; var rect = annotation.get('Rect'); - var item = {}; item.type = subtype.name; item.rect = rect; @@ -272,7 +241,6 @@ var Page = (function PageClosure() { TODO('other link types'); } } else if (annotation.has('Dest')) { - // simple destination link var dest = annotation.get('Dest'); item.dest = isName(dest) ? dest.name : dest; } @@ -330,10 +298,8 @@ var Page = (function PageClosure() { return items; } }; - return Page; })(); - var PDFDocument = (function PDFDocumentClosure() { function PDFDocument(arg, password) { if (isStream(arg)) @@ -343,14 +309,12 @@ var PDFDocument = (function PDFDocumentClosure() { else error('PDFDocument: Unknown argument type'); } - function init(stream, password) { assertWellFormed(stream.length > 0, 'stream must have data'); this.stream = stream; this.setup(password); this.acroForm = this.catalog.catDict.get('AcroForm'); } - function find(stream, needle, limit, backwards) { var pos = stream.pos; var end = stream.end; @@ -366,7 +330,6 @@ var PDFDocument = (function PDFDocumentClosure() { stream.pos += index; return true; /* found */ } - PDFDocument.prototype = { get linearization() { var length = this.stream.length; @@ -388,7 +351,6 @@ var PDFDocument = (function PDFDocumentClosure() { var startXRef = 0; var linearization = this.linearization; if (linearization) { - // Find end of first obj. stream.reset(); if (find(stream, 'endobj', 1024)) startXRef = stream.pos + 6; @@ -431,7 +393,6 @@ var PDFDocument = (function PDFDocumentClosure() { var stream = this.stream; stream.reset(); if (find(stream, '%PDF-', 1024)) { - // Found the header, trim off any garbage before it. stream.moveStart(); return; } @@ -448,21 +409,18 @@ var PDFDocument = (function PDFDocumentClosure() { get numPages() { var linearization = this.linearization; var num = linearization ? linearization.numPages : this.catalog.numPages; - // shadow the prototype getter return shadow(this, 'numPages', num); }, getDocumentInfo: function PDFDocument_getDocumentInfo() { var info; if (this.xref.trailer.has('Info')) { var infoDict = this.xref.trailer.get('Info'); - info = {}; infoDict.forEach(function(key, value) { info[key] = typeof value !== 'string' ? value : stringToPDFString(value); }); } - return shadow(this, 'getDocumentInfo', info); }, getFingerprint: function PDFDocument_getFingerprint() { @@ -481,21 +439,16 @@ var PDFDocument = (function PDFDocumentClosure() { fileID += Number(hash[i]).toString(16); } } - return shadow(this, 'getFingerprint', fileID); }, getPage: function PDFDocument_getPage(n) { return this.catalog.getPage(n); } }; - return PDFDocument; })(); - - /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - 'use strict'; function log(msg) { if (console && console.log) @@ -509,7 +462,6 @@ function info(msg) { PDFJS.LogManager.notify('info', msg); } } - function warn(msg) { if (verbosity >= WARNINGS) { log('Warning: ' + msg); @@ -525,7 +477,6 @@ function error(msg) { function TODO(what) { warn('TODO: ' + what); } - function backtrace() { try { throw new Error(); @@ -533,7 +484,6 @@ function backtrace() { return e.stack ? e.stack.split('\n').slice(2).join('\n') : ''; } } - function assert(cond, msg) { if (!cond) error(msg); @@ -542,7 +492,6 @@ function assertWellFormed(cond, msg) { if (!cond) error(msg); } - var LogManager = PDFJS.LogManager = (function LogManagerClosure() { var loggers = []; return { @@ -558,7 +507,6 @@ var LogManager = PDFJS.LogManager = (function LogManagerClosure() { } }; })(); - function shadow(obj, prop, value) { Object.defineProperty(obj, prop, { value: value, enumerable: true, @@ -566,20 +514,16 @@ function shadow(obj, prop, value) { writable: false }); return value; } - var PasswordException = (function PasswordExceptionClosure() { function PasswordException(msg, code) { this.name = 'PasswordException'; this.message = msg; this.code = code; } - PasswordException.prototype = new Error(); PasswordException.constructor = PasswordException; - return PasswordException; })(); - function bytesToString(bytes) { var str = ''; var length = bytes.length; @@ -587,7 +531,6 @@ function bytesToString(bytes) { str += String.fromCharCode(bytes[n]); return str; } - function stringToBytes(str) { var length = str.length; var bytes = new Uint8Array(length); @@ -595,43 +538,34 @@ function stringToBytes(str) { bytes[n] = str.charCodeAt(n) & 0xFF; return bytes; } - var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; - var Util = PDFJS.Util = (function UtilClosure() { function Util() {} - Util.makeCssRgb = function Util_makeCssRgb(r, g, b) { var ri = (255 * r) | 0, gi = (255 * g) | 0, bi = (255 * b) | 0; return 'rgb(' + ri + ',' + gi + ',' + bi + ')'; }; - Util.makeCssCmyk = function Util_makeCssCmyk(c, m, y, k) { c = (new DeviceCmykCS()).getRgb([c, m, y, k]); var ri = (255 * c[0]) | 0, gi = (255 * c[1]) | 0, bi = (255 * c[2]) | 0; return 'rgb(' + ri + ',' + gi + ',' + bi + ')'; }; - - // For 2d affine transforms Util.applyTransform = function Util_applyTransform(p, m) { var xt = p[0] * m[0] + p[1] * m[2] + m[4]; var yt = p[0] * m[1] + p[1] * m[3] + m[5]; return [xt, yt]; }; - Util.applyInverseTransform = function Util_applyInverseTransform(p, m) { var d = m[0] * m[3] - m[1] * m[2]; var xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d; var yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d; return [xt, yt]; }; - Util.inverseTransform = function Util_inverseTransform(m) { var d = m[0] * m[3] - m[1] * m[2]; return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d, (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d]; }; - Util.apply3dTransform = function Util_apply3dTransform(m, v) { return [ m[0] * v[0] + m[1] * v[1] + m[2] * v[2], @@ -639,9 +573,8 @@ var Util = PDFJS.Util = (function UtilClosure() { m[6] * v[0] + m[7] * v[1] + m[8] * v[2] ]; } - Util.normalizeRect = function Util_normalizeRect(rect) { - var r = rect.slice(0); // clone rect + var r = rect.slice(0); if (rect[0] > rect[2]) { r[0] = rect[2]; r[2] = rect[0]; @@ -652,19 +585,15 @@ var Util = PDFJS.Util = (function UtilClosure() { } return r; } - Util.intersect = function Util_intersect(rect1, rect2) { function compare(a, b) { return a - b; }; - var orderedX = [rect1[0], rect1[2], rect2[0], rect2[2]].sort(compare), orderedY = [rect1[1], rect1[3], rect2[1], rect2[3]].sort(compare), result = []; - rect1 = Util.normalizeRect(rect1); rect2 = Util.normalizeRect(rect2); - if ((orderedX[0] === rect1[0] && orderedX[1] === rect2[0]) || (orderedX[0] === rect2[0] && orderedX[1] === rect1[0])) { result[0] = orderedX[1]; @@ -672,7 +601,6 @@ var Util = PDFJS.Util = (function UtilClosure() { } else { return false; } - if ((orderedY[0] === rect1[1] && orderedY[1] === rect2[1]) || (orderedY[0] === rect2[1] && orderedY[1] === rect1[1])) { result[1] = orderedY[1]; @@ -680,17 +608,13 @@ var Util = PDFJS.Util = (function UtilClosure() { } else { return false; } - return result; }; - Util.sign = function Util_sign(num) { return num < 0 ? -1 : 1; }; - return Util; })(); - var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() { function PageViewport(viewBox, scale, rotate, offsetX, offsetY) { var centerX = (viewBox[2] + viewBox[0]) / 2; @@ -736,7 +660,6 @@ var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() { offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY ]; - this.offsetX = offsetX; this.offsetY = offsetY; this.width = width; @@ -759,7 +682,6 @@ var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() { }; return PageViewport; })(); - var PDFStringTranslateTable = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2D8, 0x2C7, 0x2C6, 0x2D9, 0x2DD, 0x2DB, 0x2DA, 0x2DC, 0, 0, 0, 0, 0, 0, 0, @@ -771,11 +693,9 @@ var PDFStringTranslateTable = [ 0x201D, 0x2018, 0x2019, 0x201A, 0x2122, 0xFB01, 0xFB02, 0x141, 0x152, 0x160, 0x178, 0x17D, 0x131, 0x142, 0x153, 0x161, 0x17E, 0, 0x20AC ]; - function stringToPDFString(str) { var i, n = str.length, str2 = ''; if (str[0] === '\xFE' && str[1] === '\xFF') { - // UTF16BE BOM for (i = 2; i < n; i += 2) str2 += String.fromCharCode( (str.charCodeAt(i) << 8) | str.charCodeAt(i + 1)); @@ -787,59 +707,45 @@ function stringToPDFString(str) { } return str2; } - function stringToUTF8String(str) { return decodeURIComponent(escape(str)); } - function isBool(v) { return typeof v == 'boolean'; } - function isInt(v) { return typeof v == 'number' && ((v | 0) == v); } - function isNum(v) { return typeof v == 'number'; } - function isString(v) { return typeof v == 'string'; } - function isNull(v) { return v === null; } - function isName(v) { return v instanceof Name; } - function isCmd(v, cmd) { return v instanceof Cmd && (!cmd || v.cmd == cmd); } - function isDict(v, type) { return v instanceof Dict && (!type || v.get('Type').name == type); } - function isArray(v) { return v instanceof Array; } - function isStream(v) { return typeof v == 'object' && v != null && ('getChar' in v); } - function isArrayBuffer(v) { return typeof v == 'object' && v != null && ('byteLength' in v); } - function isRef(v) { return v instanceof Ref; } - function isPDFFunction(v) { var fnDict; if (typeof v != 'object') @@ -852,7 +758,6 @@ function isPDFFunction(v) { return false; return fnDict.has('FunctionType'); } - var Promise = PDFJS.Promise = (function PromiseClosure() { var EMPTY_PROMISE = {}; function Promise(name, data) { @@ -894,7 +799,6 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { }; Promise.prototype = { hasData: false, - set data(value) { if (value === undefined) { return; @@ -905,19 +809,16 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { } this._data = value; this.hasData = true; - if (this.onDataCallback) { this.onDataCallback(value); } }, - get data() { if (this._data === EMPTY_PROMISE) { error('Promise ' + this.name + ': Cannot get data that isn\'t set'); } return this._data; }, - onData: function Promise_onData(callback) { if (this._data !== EMPTY_PROMISE) { callback(this._data); @@ -925,7 +826,6 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { this.onDataCallback = callback; } }, - resolve: function Promise_resolve(data) { if (this.isResolved) { error('A Promise can be resolved only once ' + this.name); @@ -933,23 +833,19 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { if (this.isRejected) { error('The Promise was already rejected ' + this.name); } - this.isResolved = true; this.data = (typeof data !== 'undefined') ? data : null; var callbacks = this.callbacks; - for (var i = 0, ii = callbacks.length; i < ii; i++) { callbacks[i].call(null, data); } }, - progress: function Promise_progress(data) { var callbacks = this.progressbacks; for (var i = 0, ii = callbacks.length; i < ii; i++) { callbacks[i].call(null, data); } }, - reject: function Promise_reject(reason, exception) { if (this.isRejected) { error('A Promise can be rejected only once ' + this.name); @@ -957,22 +853,17 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { if (this.isResolved) { error('The Promise was already resolved ' + this.name); } - this.isRejected = true; this.error = reason || null; var errbacks = this.errbacks; - for (var i = 0, ii = errbacks.length; i < ii; i++) { errbacks[i].call(null, reason, exception); } }, - then: function Promise_then(callback, errback, progressback) { if (!callback) { error('Requiring callback' + this.name); } - - // If the promise is already resolved, call the callback directly. if (this.isResolved) { var data = this.data; callback.call(null, data); @@ -984,15 +875,12 @@ var Promise = PDFJS.Promise = (function PromiseClosure() { if (errback) this.errbacks.push(errback); } - if (progressback) this.progressbacks.push(progressback); } }; - return Promise; })(); - var StatTimer = (function StatTimerClosure() { function rpad(str, pad, length) { while (str.length < length) @@ -1043,13 +931,11 @@ var StatTimer = (function StatTimerClosure() { }; return StatTimer; })(); - /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ PDFJS.getDocument = function getDocument(source) { var url, data, headers, password, parameters = {}, workerInitializedPromise, workerReadyPromise, transport; - if (typeof source === 'string') { url = source; } else if (isArrayBuffer(source)) { @@ -1060,14 +946,12 @@ PDFJS.getDocument = function getDocument(source) { headers = source.httpHeaders; password = source.password; parameters.password = password || null; - if (!url && !data) error('Invalid parameter array, need either .data or .url'); } else { error('Invalid parameter in getDocument, need either Uint8Array, ' + 'string or a parameter object'); } - workerInitializedPromise = new PDFJS.Promise(); workerReadyPromise = new PDFJS.Promise(); transport = new WorkerTransport(workerInitializedPromise, workerReadyPromise); @@ -1097,10 +981,8 @@ PDFJS.getDocument = function getDocument(source) { }); }); } - return workerReadyPromise; }; - var PDFDocumentProxy = (function PDFDocumentProxyClosure() { function PDFDocumentProxy(pdfInfo, transport) { this.pdfInfo = pdfInfo; @@ -1154,7 +1036,6 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() { }; return PDFDocumentProxy; })(); - var PDFPageProxy = (function PDFPageProxyClosure() { function PDFPageProxy(pageInfo, transport) { this.pageInfo = pageInfo; @@ -1185,7 +1066,6 @@ var PDFPageProxy = (function PDFPageProxyClosure() { getAnnotations: function PDFPageProxy_getAnnotations() { if (this.annotationsPromise) return this.annotationsPromise; - var promise = new PDFJS.Promise(); this.annotationsPromise = promise; this.transport.getAnnotations(this.pageInfo.pageIndex); @@ -1193,20 +1073,17 @@ var PDFPageProxy = (function PDFPageProxyClosure() { }, render: function PDFPageProxy_render(params) { this.renderInProgress = true; - var promise = new Promise(); var stats = this.stats; stats.time('Overall'); if (!this.displayReadyPromise) { this.displayReadyPromise = new Promise(); this.destroyed = false; - this.stats.time('Page Request'); this.transport.messageHandler.send('RenderPageRequest', { pageIndex: this.pageNumber - 1 }); } - var self = this; function complete(error) { self.renderInProgress = false; @@ -1214,21 +1091,18 @@ var PDFPageProxy = (function PDFPageProxyClosure() { delete self.operatorList; delete self.displayReadyPromise; } - if (error) promise.reject(error); else promise.resolve(); }; var continueCallback = params.continueCallback; - this.displayReadyPromise.then( function pageDisplayReadyPromise() { if (self.destroyed) { complete(); return; } - var gfx = new CanvasGraphics(params.canvasContext, this.objs, params.textLayer); try { @@ -1241,7 +1115,6 @@ var PDFPageProxy = (function PDFPageProxyClosure() { complete(reason); } ); - return promise; }, startRenderingFromOperatorList: @@ -1249,49 +1122,35 @@ var PDFPageProxy = (function PDFPageProxyClosure() { fonts) { var self = this; this.operatorList = operatorList; - var displayContinuation = function pageDisplayContinuation() { setTimeout(function pageSetTimeout() { self.displayReadyPromise.resolve(); }); }; - this.ensureFonts(fonts, function pageStartRenderingFromOperatorListEnsureFonts() { displayContinuation(); } ); }, - /** - * For internal use only. - */ ensureFonts: function PDFPageProxy_ensureFonts(fonts, callback) { this.stats.time('Font Loading'); - // Convert the font names to the corresponding font obj. for (var i = 0, ii = fonts.length; i < ii; i++) { fonts[i] = this.objs.objs[fonts[i]].data; } - - // Load all the fonts FontLoader.bind( fonts, function pageEnsureFontsFontObjs(fontObjs) { this.stats.timeEnd('Font Loading'); - callback.call(this); }.bind(this) ); }, - /** - * For internal use only. - */ display: function PDFPageProxy_display(gfx, viewport, callback, continueCallback) { var stats = this.stats; stats.time('Rendering'); - gfx.beginDrawing(viewport); - var startIdx = 0; var length = this.operatorList.fnArray.length; var operatorList = this.operatorList; @@ -1301,13 +1160,11 @@ var PDFPageProxy = (function PDFPageProxyClosure() { stepper.init(operatorList); stepper.nextBreakPoint = stepper.getNextBreakPoint(); } - var continueWrapper; if (continueCallback) continueWrapper = function() { continueCallback(next); } else continueWrapper = next; - var self = this; function next() { startIdx = gfx.executeOperatorList(operatorList, startIdx, @@ -1334,7 +1191,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() { }, getOperationList: function PDFPageProxy_getOperationList() { var promise = new PDFJS.Promise(); - var operationList = { // not implemented + var operationList = { dependencyFontsID: null, operatorList: null }; @@ -1343,7 +1200,6 @@ var PDFPageProxy = (function PDFPageProxyClosure() { }, destroy: function PDFPageProxy_destroy() { this.destroyed = true; - if (!this.renderInProgress) { delete this.operatorList; delete this.displayReadyPromise; @@ -1356,17 +1212,14 @@ var WorkerTransport = (function WorkerTransportClosure() { function WorkerTransport(workerInitializedPromise, workerReadyPromise) { this.workerReadyPromise = workerReadyPromise; this.objs = new PDFObjects(); - this.pageCache = []; this.pagePromises = []; this.fontsLoading = {}; - if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') { var workerSrc = PDFJS.workerSrc; if (typeof workerSrc === 'undefined') { error('No PDFJS.workerSrc specified'); } - try { var worker; if (PDFJS.isFirefoxExtension) { @@ -1377,10 +1230,8 @@ var WorkerTransport = (function WorkerTransportClosure() { } else { worker = new Worker(workerSrc); } - var messageHandler = new MessageHandler('main', worker); this.messageHandler = messageHandler; - messageHandler.on('test', function transportTest(supportTypedArray) { if (supportTypedArray) { this.worker = worker; @@ -1391,7 +1242,6 @@ var WorkerTransport = (function WorkerTransportClosure() { } workerInitializedPromise.resolve(); }.bind(this)); - var testObj = new Uint8Array(1); messageHandler.send('test', testObj); return; @@ -1407,7 +1257,6 @@ var WorkerTransport = (function WorkerTransportClosure() { destroy: function WorkerTransport_destroy() { if (this.worker) this.worker.terminate(); - this.pageCache = []; this.pagePromises = []; }, @@ -1418,31 +1267,25 @@ var WorkerTransport = (function WorkerTransportClosure() { }, terminate: function WorkerTransport_terminate() {} }; - var messageHandler = new MessageHandler('main', fakeWorker); this.setupMessageHandler(messageHandler); WorkerMessageHandler.setup(messageHandler); }, - setupMessageHandler: function WorkerTransport_setupMessageHandler(messageHandler) { this.messageHandler = messageHandler; - messageHandler.on('GetDoc', function transportDoc(data) { var pdfInfo = data.pdfInfo; var pdfDocument = new PDFDocumentProxy(pdfInfo, this); this.pdfDocument = pdfDocument; this.workerReadyPromise.resolve(pdfDocument); }, this); - messageHandler.on('NeedPassword', function transportPassword(data) { this.workerReadyPromise.reject(data.exception.message, data.exception); }, this); - messageHandler.on('IncorrectPassword', function transportBadPass(data) { this.workerReadyPromise.reject(data.exception.message, data.exception); }, this); - messageHandler.on('GetPage', function transportPage(data) { var pageInfo = data.pageInfo; var page = new PDFPageProxy(pageInfo, this); @@ -1450,27 +1293,22 @@ var WorkerTransport = (function WorkerTransportClosure() { var promise = this.pagePromises[pageInfo.pageIndex]; promise.resolve(page); }, this); - messageHandler.on('GetAnnotations', function transportAnnotations(data) { var annotations = data.annotations; var promise = this.pageCache[data.pageIndex].annotationsPromise; promise.resolve(annotations); }, this); - messageHandler.on('RenderPage', function transportRender(data) { var page = this.pageCache[data.pageIndex]; var depFonts = data.depFonts; - page.stats.timeEnd('Page Request'); page.startRenderingFromOperatorList(data.operatorList, depFonts); }, this); - messageHandler.on('obj', function transportObj(data) { var id = data[0]; var type = data[1]; if (this.objs.hasData(id)) return; - switch (type) { case 'JpegStream': var imageData = data[2]; @@ -1484,13 +1322,10 @@ var WorkerTransport = (function WorkerTransportClosure() { var name = data[2]; var file = data[3]; var properties = data[4]; - if (file) { - // Rewrap the ArrayBuffer in a stream. var fontFileDict = new Dict(); file = new Stream(file, 0, file.length, fontFileDict); } - var font = new Font(name, file, properties); this.objs.resolve(id, font); break; @@ -1498,7 +1333,6 @@ var WorkerTransport = (function WorkerTransportClosure() { error('Got unkown object type ' + type); } }, this); - messageHandler.on('PageError', function transportError(data) { var page = this.pageCache[data.pageNum - 1]; if (page.displayReadyPromise) @@ -1506,13 +1340,11 @@ var WorkerTransport = (function WorkerTransportClosure() { else error(data.error); }, this); - messageHandler.on('JpegDecode', function(data, promise) { var imageData = data[0]; var components = data[1]; if (components != 3 && components != 1) error('Only 3 component or 1 component can be returned'); - var img = new Image(); img.onload = (function messageHandler_onloadClosure() { var width = img.width; @@ -1524,7 +1356,6 @@ var WorkerTransport = (function WorkerTransportClosure() { var tmpCtx = tmpCanvas.getContext('2d'); tmpCtx.drawImage(img, 0, 0); var data = tmpCtx.getImageData(0, 0, width, height).data; - if (components == 3) { for (var i = 0, j = 0; i < rgbaLength; i += 4, j += 3) { buf[j] = data[i]; @@ -1542,17 +1373,14 @@ var WorkerTransport = (function WorkerTransportClosure() { img.src = src; }); }, - sendData: function WorkerTransport_sendData(data, params) { this.messageHandler.send('GetDocRequest', {data: data, params: params}); }, - getData: function WorkerTransport_sendData(promise) { this.messageHandler.send('GetData', null, function(data) { promise.resolve(data); }); }, - getPage: function WorkerTransport_getPage(pageNumber, promise) { var pageIndex = pageNumber - 1; if (pageIndex in this.pagePromises) @@ -1562,19 +1390,15 @@ var WorkerTransport = (function WorkerTransportClosure() { this.messageHandler.send('GetPageRequest', { pageIndex: pageIndex }); return promise; }, - getAnnotations: function WorkerTransport_getAnnotations(pageIndex) { this.messageHandler.send('GetAnnotationsRequest', { pageIndex: pageIndex }); } }; return WorkerTransport; - })(); - /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - 'use strict'; var TextRenderingMode = { FILL: 0, @@ -1586,16 +1410,13 @@ var TextRenderingMode = { FILL_STROKE_ADD_TO_PATH: 6, ADD_TO_PATH: 7 }; - var MIN_FONT_SIZE = 1; - function createScratchCanvas(width, height) { var canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; return canvas; } - function addContextCurrentTransform(ctx) { if (!ctx.mozCurrentTransform) { ctx._originalSave = ctx.save; @@ -1604,24 +1425,19 @@ function addContextCurrentTransform(ctx) { ctx._originalScale = ctx.scale; ctx._originalTranslate = ctx.translate; ctx._originalTransform = ctx.transform; - ctx._transformMatrix = [1, 0, 0, 1, 0, 0]; ctx._transformStack = []; - Object.defineProperty(ctx, 'mozCurrentTransform', { get: function getCurrentTransform() { return this._transformMatrix; } }); - Object.defineProperty(ctx, 'mozCurrentTransformInverse', { get: function getCurrentTransformInverse() { var m = this._transformMatrix; var a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5]; - var ad_bc = a * d - b * c; var bc_ad = b * c - a * d; - return [ d / ad_bc, b / bc_ad, @@ -1632,15 +1448,12 @@ function addContextCurrentTransform(ctx) { ]; } }); - ctx.save = function ctxSave() { var old = this._transformMatrix; this._transformStack.push(old); this._transformMatrix = old.slice(0, 6); - this._originalSave(); }; - ctx.restore = function ctxRestore() { var prev = this._transformStack.pop(); if (prev) { @@ -1648,25 +1461,20 @@ function addContextCurrentTransform(ctx) { this._originalRestore(); } }; - ctx.translate = function ctxTranslate(x, y) { var m = this._transformMatrix; m[4] = m[0] * x + m[2] * y + m[4]; m[5] = m[1] * x + m[3] * y + m[5]; - this._originalTranslate(x, y); }; - ctx.scale = function ctxScale(x, y) { var m = this._transformMatrix; m[0] = m[0] * x; m[1] = m[1] * x; m[2] = m[2] * y; m[3] = m[3] * y; - this._originalScale(x, y); }; - ctx.transform = function ctxTransform(a, b, c, d, e, f) { var m = this._transformMatrix; this._transformMatrix = [ @@ -1677,14 +1485,11 @@ function addContextCurrentTransform(ctx) { m[0] * e + m[2] * f + m[4], m[1] * e + m[3] * f + m[5] ]; - ctx._originalTransform(a, b, c, d, e, f); }; - ctx.rotate = function ctxRotate(angle) { var cosValue = Math.cos(angle); var sinValue = Math.sin(angle); - var m = this._transformMatrix; this._transformMatrix = [ m[0] * cosValue + m[2] * sinValue, @@ -1694,12 +1499,10 @@ function addContextCurrentTransform(ctx) { m[4], m[5] ]; - this._originalRotate(angle); }; } } - var CanvasExtraState = (function CanvasExtraStateClosure() { function CanvasExtraState(old) { this.alphaIsShape = false; @@ -1727,10 +1530,8 @@ var CanvasExtraState = (function CanvasExtraStateClosure() { this.fillAlpha = 1; this.strokeAlpha = 1; this.lineWidth = 1; - this.old = old; } - CanvasExtraState.prototype = { clone: function CanvasExtraState_clone() { return Object.create(this); @@ -1742,10 +1543,8 @@ var CanvasExtraState = (function CanvasExtraStateClosure() { }; return CanvasExtraState; })(); - var CanvasGraphics = (function CanvasGraphicsClosure() { var kExecutionTime = 15; - function CanvasGraphics(canvasCtx, objs, textLayer) { this.ctx = canvasCtx; this.current = new CanvasExtraState(); @@ -1759,12 +1558,10 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { addContextCurrentTransform(canvasCtx); } } - var LINE_CAP_STYLES = ['butt', 'round', 'square']; var LINE_JOIN_STYLES = ['miter', 'round', 'bevel']; var NORMAL_CLIP = {}; var EO_CLIP = {}; - CanvasGraphics.prototype = { slowCommands: { 'stroke': true, @@ -1794,16 +1591,13 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { 'paintImageMaskXObject': true, 'shadingFill': true }, - beginDrawing: function CanvasGraphics_beginDrawing(viewport) { var transform = viewport.transform; this.ctx.save(); this.ctx.transform.apply(this.ctx, transform); - if (this.textLayer) this.textLayer.beginLayout(); }, - executeOperatorList: function CanvasGraphics_executeOperatorList( operatorList, executionStartIdx, continueCallback, @@ -1812,60 +1606,47 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var fnArray = operatorList.fnArray; var i = executionStartIdx || 0; var argsArrayLen = argsArray.length; - if (argsArrayLen == i) { return i; } - var executionEndIdx; var endTime = Date.now() + kExecutionTime; - var objs = this.objs; var fnName; var slowCommands = this.slowCommands; - while (true) { if (stepper && i === stepper.nextBreakPoint) { stepper.breakIt(i, continueCallback); return i; } - fnName = fnArray[i]; - if (fnName !== 'dependency') { this[fnName].apply(this, argsArray[i]); } else { var deps = argsArray[i]; for (var n = 0, nn = deps.length; n < nn; n++) { var depObjId = deps[n]; - if (!objs.isResolved(depObjId)) { objs.get(depObjId, continueCallback); return i; } } } - i++; - if (i == argsArrayLen) { return i; } - if (continueCallback && slowCommands[fnName] && Date.now() > endTime) { setTimeout(continueCallback, 0); return i; } } }, - endDrawing: function CanvasGraphics_endDrawing() { this.ctx.restore(); - if (this.textLayer) this.textLayer.endLayout(); }, - setLineWidth: function CanvasGraphics_setLineWidth(width) { this.current.lineWidth = width; this.ctx.lineWidth = width; @@ -1894,7 +1675,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var state = states[i]; var key = state[0]; var value = state[1]; - switch (key) { case 'LW': this.setLineWidth(value); @@ -1946,7 +1726,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { transform: function CanvasGraphics_transform(a, b, c, d, e, f) { this.ctx.transform(a, b, c, d, e, f); }, - moveTo: function CanvasGraphics_moveTo(x, y) { this.ctx.moveTo(x, y); this.current.setCurrentPoint(x, y); @@ -2002,7 +1781,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { consumePath = typeof consumePath !== 'undefined' ? consumePath : true; var ctx = this.ctx; var fillColor = this.current.fillColor; - if (fillColor && fillColor.hasOwnProperty('type') && fillColor.type === 'Pattern') { ctx.save(); @@ -2023,7 +1801,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { fillStroke: function CanvasGraphics_fillStroke() { this.fill(false); this.stroke(false); - this.consumePath(); }, eoFillStroke: function CanvasGraphics_eoFillStroke() { @@ -2044,14 +1821,12 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { endPath: function CanvasGraphics_endPath() { this.consumePath(); }, - clip: function CanvasGraphics_clip() { this.pendingClip = NORMAL_CLIP; }, eoClip: function CanvasGraphics_eoClip() { this.pendingClip = EO_CLIP; }, - beginText: function CanvasGraphics_beginText() { this.current.textMatrix = IDENTITY_MATRIX; this.current.x = this.current.lineX = 0; @@ -2074,44 +1849,34 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { setFont: function CanvasGraphics_setFont(fontRefName, size) { var fontObj = this.objs.get(fontRefName); var current = this.current; - if (!fontObj) error('Can\'t find font for ' + fontRefName); - if (fontObj.fontMatrix) current.fontMatrix = fontObj.fontMatrix.slice(0); else current.fontMatrix = IDENTITY_MATRIX.slice(0); - if (current.fontMatrix[0] === 0 || current.fontMatrix[3] === 0) { warn('Invalid font matrix for font ' + fontRefName); } - if (size < 0) { size = -size; current.fontMatrix[0] *= -1; current.fontMatrix[3] *= -1; } - this.current.font = fontObj; this.current.fontSize = size; - if (fontObj.coded) return; - var name = fontObj.loadedName || 'sans-serif'; var bold = fontObj.black ? (fontObj.bold ? 'bolder' : 'bold') : (fontObj.bold ? 'bold' : 'normal'); - var italic = fontObj.italic ? 'italic' : 'normal'; var serif = fontObj.isSerifFont ? 'serif' : 'sans-serif'; var typeface = '"' + name + '", ' + serif; - var browserFontSize = size >= MIN_FONT_SIZE ? size : MIN_FONT_SIZE; this.current.fontSizeScale = browserFontSize != MIN_FONT_SIZE ? 1.0 : size / MIN_FONT_SIZE; - var rule = italic + ' ' + bold + ' ' + browserFontSize + 'px ' + typeface; this.ctx.font = rule; }, @@ -2133,7 +1898,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { }, setTextMatrix: function CanvasGraphics_setTextMatrix(a, b, c, d, e, f) { this.current.textMatrix = [a, b, c, d, e, f]; - this.current.x = this.current.lineX = 0; this.current.y = this.current.lineY = 0; }, @@ -2145,7 +1909,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var current = this.current; var textHScale = current.textHScale; var fontMatrix = current.fontMatrix || IDENTITY_MATRIX; - ctx.transform.apply(ctx, current.textMatrix); ctx.scale(1, -1); ctx.translate(current.x, -1 * current.y); @@ -2168,7 +1931,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { geometry.spaceWidth = font.spaceWidth; return geometry; }, - showText: function CanvasGraphics_showText(str, skipTextSelection) { var ctx = this.ctx; var current = this.current; @@ -2186,14 +1948,11 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var text = {str: '', length: 0, canvasWidth: 0, geom: {}}; var textSelection = textLayer && !skipTextSelection ? true : false; var textRenderingMode = current.textRenderingMode; - if (font.coded) { ctx.save(); ctx.transform.apply(ctx, current.textMatrix); ctx.translate(current.x, current.y); - ctx.scale(textHScale, 1); - if (textSelection) { this.save(); ctx.scale(1, -1); @@ -2201,26 +1960,21 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { this.restore(); } for (var i = 0; i < glyphsLength; ++i) { - var glyph = glyphs[i]; if (glyph === null) { this.ctx.translate(wordSpacing, 0); continue; } - this.save(); ctx.scale(fontSize, fontSize); ctx.transform.apply(ctx, fontMatrix); this.executeOperatorList(glyph.operatorList); this.restore(); - var transformed = Util.applyTransform([glyph.width, 0], fontMatrix); var width = transformed[0] * fontSize + Util.sign(current.fontMatrix[0]) * charSpacing; - ctx.translate(width, 0); current.x += width * textHScale; - text.str += glyph.unicode; text.length++; text.canvasWidth += width; @@ -2229,24 +1983,19 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { } else { ctx.save(); this.applyTextTransforms(); - var lineWidth = current.lineWidth; var scale = Math.abs(current.textMatrix[0] * fontMatrix[0]); if (scale == 0 || lineWidth == 0) lineWidth = this.getSinglePixelWidth(); else lineWidth /= scale; - if (textSelection) text.geom = this.getTextGeometry(); - if (fontSizeScale != 1.0) { ctx.scale(fontSizeScale, fontSizeScale); lineWidth /= fontSizeScale; } - ctx.lineWidth = lineWidth; - var x = 0; for (var i = 0; i < glyphsLength; ++i) { var glyph = glyphs[i]; @@ -2254,11 +2003,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { x += Util.sign(current.fontMatrix[0]) * wordSpacing; continue; } - var character = glyph.fontChar; var charWidth = glyph.width * fontSize * 0.001 + Util.sign(current.fontMatrix[0]) * charSpacing; - if (!glyph.disabled) { var scaledX = x / fontSizeScale; switch (textRenderingMode) { @@ -2280,9 +2027,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { break; } } - x += charWidth; - var glyphUnicode = glyph.unicode === ' ' ? '\u00A0' : glyph.unicode; var glyphUnicodeLength = glyphUnicode.length; if (glyphUnicodeLength > 1 && @@ -2297,10 +2042,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { current.x += x * textHScale2; ctx.restore(); } - if (textSelection) this.textLayer.appendText(text, font.loadedName, fontSize); - return text; }, showSpacedText: function CanvasGraphics_showSpacedText(arr) { @@ -2315,7 +2058,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var textLayer = this.textLayer; var text = {str: '', length: 0, canvasWidth: 0, geom: {}}; var textSelection = textLayer ? true : false; - if (textSelection) { ctx.save(); if (font.coded) { @@ -2328,16 +2070,14 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { text.geom = this.getTextGeometry(); ctx.restore(); } - for (var i = 0; i < arrLength; ++i) { var e = arr[i]; if (isNum(e)) { var spacingLength = -e * 0.001 * fontSize * textHScale; current.x += spacingLength; - if (textSelection) { text.canvasWidth += spacingLength; - if (e < 0 && text.geom.spaceWidth > 0) { // avoid div by zero + if (e < 0 && text.geom.spaceWidth > 0) { var numFakeSpaces = Math.round(-e / text.geom.spaceWidth); if (numFakeSpaces > 0) { text.str += '\u00A0'; @@ -2347,7 +2087,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { } } else if (isString(e)) { var shownText = this.showText(e, true); - if (textSelection) { if (shownText.str === ' ') { text.str += '\u00A0'; @@ -2361,7 +2100,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { error('TJ array element ' + e + ' is not string or num'); } } - if (textSelection) this.textLayer.appendText(text, font.loadedName, fontSize); }, @@ -2377,7 +2115,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { this.setCharSpacing(charSpacing); this.nextLineShowText(text); }, - setCharWidth: function CanvasGraphics_setCharWidth(xWidth, yWidth) { }, setCharWidthAndBounds: function CanvasGraphics_setCharWidthAndBounds(xWidth, @@ -2390,7 +2127,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { this.clip(); this.endPath(); }, - setStrokeColorSpace: function CanvasGraphics_setStrokeColorSpace(raw) { this.current.strokeColorSpace = ColorSpace.fromIR(raw); }, @@ -2411,11 +2147,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var color; if (base) { var baseComps = base.numComps; - color = []; for (var i = 0; i < baseComps; ++i) color.push(args[i]); - color = base.getRgb(color); } var pattern = new TilingPattern(IR, color, this.ctx, this.objs); @@ -2428,7 +2162,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { }, setStrokeColorN: function CanvasGraphics_setStrokeColorN(/*...*/) { var cs = this.current.strokeColorSpace; - if (cs.name == 'Pattern') { this.current.strokeColor = this.getColorN_Pattern(arguments, cs); } else { @@ -2444,7 +2177,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { }, setFillColorN: function CanvasGraphics_setFillColorN(/*...*/) { var cs = this.current.fillColorSpace; - if (cs.name == 'Pattern') { this.current.fillColor = this.getColorN_Pattern(arguments, cs); } else { @@ -2454,7 +2186,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { setStrokeGray: function CanvasGraphics_setStrokeGray(gray) { if (!(this.current.strokeColorSpace instanceof DeviceGrayCS)) this.current.strokeColorSpace = new DeviceGrayCS(); - var color = Util.makeCssRgb(gray, gray, gray); this.ctx.strokeStyle = color; this.current.strokeColor = color; @@ -2462,7 +2193,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { setFillGray: function CanvasGraphics_setFillGray(gray) { if (!(this.current.fillColorSpace instanceof DeviceGrayCS)) this.current.fillColorSpace = new DeviceGrayCS(); - var color = Util.makeCssRgb(gray, gray, gray); this.ctx.fillStyle = color; this.current.fillColor = color; @@ -2470,7 +2200,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { setStrokeRGBColor: function CanvasGraphics_setStrokeRGBColor(r, g, b) { if (!(this.current.strokeColorSpace instanceof DeviceRgbCS)) this.current.strokeColorSpace = new DeviceRgbCS(); - var color = Util.makeCssRgb(r, g, b); this.ctx.strokeStyle = color; this.current.strokeColor = color; @@ -2478,7 +2207,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { setFillRGBColor: function CanvasGraphics_setFillRGBColor(r, g, b) { if (!(this.current.fillColorSpace instanceof DeviceRgbCS)) this.current.fillColorSpace = new DeviceRgbCS(); - var color = Util.makeCssRgb(r, g, b); this.ctx.fillStyle = color; this.current.fillColor = color; @@ -2486,7 +2214,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { setStrokeCMYKColor: function CanvasGraphics_setStrokeCMYKColor(c, m, y, k) { if (!(this.current.strokeColorSpace instanceof DeviceCmykCS)) this.current.strokeColorSpace = new DeviceCmykCS(); - var color = Util.makeCssCmyk(c, m, y, k); this.ctx.strokeStyle = color; this.current.strokeColor = color; @@ -2494,57 +2221,45 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { setFillCMYKColor: function CanvasGraphics_setFillCMYKColor(c, m, y, k) { if (!(this.current.fillColorSpace instanceof DeviceCmykCS)) this.current.fillColorSpace = new DeviceCmykCS(); - var color = Util.makeCssCmyk(c, m, y, k); this.ctx.fillStyle = color; this.current.fillColor = color; }, - shadingFill: function CanvasGraphics_shadingFill(patternIR) { var ctx = this.ctx; - this.save(); var pattern = Pattern.shadingFromIR(patternIR); ctx.fillStyle = pattern.getPattern(ctx); - var inv = ctx.mozCurrentTransformInverse; if (inv) { var canvas = ctx.canvas; var width = canvas.width; var height = canvas.height; - var bl = Util.applyTransform([0, 0], inv); var br = Util.applyTransform([0, height], inv); var ul = Util.applyTransform([width, 0], inv); var ur = Util.applyTransform([width, height], inv); - var x0 = Math.min(bl[0], br[0], ul[0], ur[0]); var y0 = Math.min(bl[1], br[1], ul[1], ur[1]); var x1 = Math.max(bl[0], br[0], ul[0], ur[0]); var y1 = Math.max(bl[1], br[1], ul[1], ur[1]); - this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0); } else { this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10); } - this.restore(); }, - beginInlineImage: function CanvasGraphics_beginInlineImage() { error('Should not call beginInlineImage'); }, beginImageData: function CanvasGraphics_beginImageData() { error('Should not call beginImageData'); }, - paintFormXObjectBegin: function CanvasGraphics_paintFormXObjectBegin(matrix, bbox) { this.save(); - if (matrix && isArray(matrix) && 6 == matrix.length) this.transform.apply(this, matrix); - if (bbox && isArray(bbox) && 4 == bbox.length) { var width = bbox[2] - bbox[0]; var height = bbox[3] - bbox[1]; @@ -2553,28 +2268,21 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { this.endPath(); } }, - paintFormXObjectEnd: function CanvasGraphics_paintFormXObjectEnd() { this.restore(); }, - paintJpegXObject: function CanvasGraphics_paintJpegXObject(objId, w, h) { var domImage = this.objs.get(objId); if (!domImage) { error('Dependent image isn\'t ready yet'); } - this.save(); - var ctx = this.ctx; ctx.scale(1 / w, -1 / h); - ctx.drawImage(domImage, 0, 0, domImage.width, domImage.height, 0, -h, w, h); - this.restore(); }, - paintImageMaskXObject: function CanvasGraphics_paintImageMaskXObject( imgArray, inverseDecode, width, height) { function applyStencilMask(buffer, inverseDecode) { @@ -2599,7 +2307,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { function rescaleImage(pixels, widthScale, heightScale) { var scaledWidth = Math.ceil(width / widthScale); var scaledHeight = Math.ceil(height / heightScale); - var itemsSum = new Uint32Array(scaledWidth * scaledHeight * 4); var itemsCount = new Uint32Array(scaledWidth * scaledHeight); for (var i = 0, position = 0; i < height; i++) { @@ -2630,32 +2337,24 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { tmpCtx.putImageData(imgData, 0, 0); return tmpCanvas; } - this.save(); - var ctx = this.ctx; var w = width, h = height; ctx.scale(1 / w, -1 / h); - var tmpCanvas = createScratchCanvas(w, h); var tmpCtx = tmpCanvas.getContext('2d'); - var fillColor = this.current.fillColor; tmpCtx.fillStyle = (fillColor && fillColor.hasOwnProperty('type') && fillColor.type === 'Pattern') ? fillColor.getPattern(tmpCtx) : fillColor; tmpCtx.fillRect(0, 0, w, h); - var imgData = tmpCtx.getImageData(0, 0, w, h); var pixels = imgData.data; - applyStencilMask(pixels, inverseDecode); - var currentTransform = ctx.mozCurrentTransformInverse; var widthScale = Math.max(Math.abs(currentTransform[0]), 1); var heightScale = Math.max(Math.abs(currentTransform[3]), 1); if (widthScale >= 2 || heightScale >= 2) { - // algorithm to perform pre-scaling tmpCanvas = rescaleImage(imgData.data, widthScale, heightScale); ctx.scale(widthScale, heightScale); ctx.drawImage(tmpCanvas, 0, -h / heightScale); @@ -2665,30 +2364,23 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { } this.restore(); }, - paintImageXObject: function CanvasGraphics_paintImageXObject(objId) { var imgData = this.objs.get(objId); if (!imgData) error('Dependent image isn\'t ready yet'); - this.save(); var ctx = this.ctx; var w = imgData.width; var h = imgData.height; ctx.scale(1 / w, -1 / h); - var tmpCanvas = createScratchCanvas(w, h); var tmpCtx = tmpCanvas.getContext('2d'); this.putBinaryImageData(tmpCtx, imgData, w, h); - ctx.drawImage(tmpCanvas, 0, -h); this.restore(); }, - putBinaryImageData: function CanvasGraphics_putBinaryImageData() { }, - - markPoint: function CanvasGraphics_markPoint(tag) { }, markPointProps: function CanvasGraphics_markPointProps(tag, properties) { @@ -2700,24 +2392,18 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { }, endMarkedContent: function CanvasGraphics_endMarkedContent() { }, - - beginCompat: function CanvasGraphics_beginCompat() { TODO('ignore undefined operators (should we do that anyway?)'); }, endCompat: function CanvasGraphics_endCompat() { TODO('stop ignoring undefined operators'); }, - - consumePath: function CanvasGraphics_consumePath() { if (this.pendingClip) { var savedFillRule = null; if (this.pendingClip == EO_CLIP) savedFillRule = this.setEOFillRule(); - this.ctx.clip(); - this.pendingClip = null; if (savedFillRule !== null) this.restoreFillRule(savedFillRule); @@ -2737,23 +2423,19 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { return Math.abs(inverse[0] + inverse[2]); } }; - return CanvasGraphics; })(); - if (!isWorker) { var canvas = document.createElement('canvas'); canvas.width = 1; canvas.height = 1; var ctx = canvas.getContext('2d'); - try { ctx.putImageData({ width: 1, height: 1, data: new Uint8Array(4) }, 0, 0); - CanvasGraphics.prototype.putBinaryImageData = function CanvasGraphicsPutBinaryImageDataNative(ctx, imgData) { ctx.putImageData(imgData, 0, 0); @@ -2762,63 +2444,45 @@ if (!isWorker) { CanvasGraphics.prototype.putBinaryImageData = function CanvasGraphicsPutBinaryImageDataShim(ctx, imgData, w, h) { var tmpImgData = ctx.getImageData(0, 0, w, h); - var tmpImgDataPixels = tmpImgData.data; var len = tmpImgDataPixels.length; - while (len--) { tmpImgDataPixels[len] = imgData.data[len]; } - ctx.putImageData(tmpImgData, 0, 0); }; } } - /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - 'use strict'; - var Name = (function NameClosure() { function Name(name) { this.name = name; } - Name.prototype = {}; - return Name; })(); - var Cmd = (function CmdClosure() { function Cmd(cmd) { this.cmd = cmd; } - Cmd.prototype = {}; - var cmdCache = {}; - Cmd.get = function Cmd_get(cmd) { var cmdValue = cmdCache[cmd]; if (cmdValue) return cmdValue; - return cmdCache[cmd] = new Cmd(cmd); }; - return Cmd; })(); - var Dict = (function DictClosure() { - // xref is optional function Dict(xref) { var map = Object.create(null); - this.assignXref = function Dict_assignXref(newXref) { xref = newXref; }; - this.get = function Dict_get(key1, key2, key3) { var value; if (typeof (value = map[key1]) != 'undefined' || key1 in map || @@ -2832,13 +2496,9 @@ var Dict = (function DictClosure() { value = map[key3] || null; return xref ? xref.fetchIfRef(value) : value; }; - - // no dereferencing this.getRaw = function Dict_getRaw(key) { return map[key]; }; - - // creates new map and dereferences all Refs this.getAll = function Dict_getAll() { var all = {}; for (var key in map) { @@ -2847,56 +2507,42 @@ var Dict = (function DictClosure() { } return all; }; - this.set = function Dict_set(key, value) { map[key] = value; }; - this.has = function Dict_has(key) { return key in map; }; - this.forEach = function Dict_forEach(callback) { for (var key in map) { callback(key, this.get(key)); } }; }; - return Dict; })(); - var Ref = (function RefClosure() { function Ref(num, gen) { this.num = num; this.gen = gen; } - Ref.prototype = {}; - return Ref; })(); - -// The reference is identified by number and generation, -// this structure stores only one instance of the reference. var RefSet = (function RefSetClosure() { function RefSet() { this.dict = {}; } - RefSet.prototype = { has: function RefSet_has(ref) { return !!this.dict['R' + ref.num + '.' + ref.gen]; }, - put: function RefSet_put(ref) { this.dict['R' + ref.num + '.' + ref.gen] = ref; } }; - return RefSet; })(); - var Catalog = (function CatalogClosure() { function Catalog(xref) { this.xref = xref; @@ -2904,29 +2550,20 @@ var Catalog = (function CatalogClosure() { assertWellFormed(isDict(obj), 'catalog object is not a dictionary'); this.catDict = obj; } - Catalog.prototype = { get metadata() { var streamRef = this.catDict.getRaw('Metadata'); if (!isRef(streamRef)) return shadow(this, 'metadata', null); - var encryptMetadata = !this.xref.encrypt ? false : this.xref.encrypt.encryptMetadata; - var stream = this.xref.fetch(streamRef, !encryptMetadata); var metadata; if (stream && isDict(stream.dict)) { var type = stream.dict.get('Type'); var subtype = stream.dict.get('Subtype'); - if (isName(type) && isName(subtype) && type.name === 'Metadata' && subtype.name === 'XML') { - // XXX: This should examine the charset the XML document defines, - // however since there are currently no real means to decode - // arbitrary charsets, let's just hope that the author of the PDF - // was reasonable enough to stick with the XML default charset, - // which is UTF-8. try { metadata = stringToUTF8String(bytesToString(stream.getBytes())); } catch (e) { @@ -2934,13 +2571,11 @@ var Catalog = (function CatalogClosure() { } } } - return shadow(this, 'metadata', metadata); }, get toplevelPagesDict() { var pagesObj = this.catDict.get('Pages'); assertWellFormed(isDict(pagesObj), 'invalid top-level pages dictionary'); - // shadow the prototype getter return shadow(this, 'toplevelPagesDict', pagesObj); }, get documentOutline() { @@ -2952,8 +2587,6 @@ var Catalog = (function CatalogClosure() { var processed = new RefSet(); if (isRef(obj)) { var queue = [{obj: obj, parent: root}]; - // to avoid recursion keeping track of the items - // in the processed dictionary processed.put(obj); while (queue.length > 0) { var i = queue.shift(); @@ -3003,7 +2636,6 @@ var Catalog = (function CatalogClosure() { isInt(obj), 'page count in top level pages object is not an integer' ); - // shadow the prototype getter return shadow(this, 'num', obj); }, traverseKids: function Catalog_traverseKids(pagesDict) { @@ -3018,7 +2650,7 @@ var Catalog = (function CatalogClosure() { var obj = this.xref.fetch(kid); if (isDict(obj, 'Page') || (isDict(obj) && !obj.has('Kids'))) { pageCache.push(new Page(this.xref, pageCache.length, obj, kid)); - } else { // must be a child page dictionary + } else { assertWellFormed( isDict(obj), 'page dictionary kid reference points to wrong type of object' @@ -3031,7 +2663,6 @@ var Catalog = (function CatalogClosure() { function fetchDestination(dest) { return isDict(dest) ? dest.get('D') : dest; } - var xref = this.xref; var dests = {}, nameTreeRef, nameDictionaryRef; var obj = this.catDict.get('Names'); @@ -3039,9 +2670,7 @@ var Catalog = (function CatalogClosure() { nameTreeRef = obj.getRaw('Dests'); else if (this.catDict.has('Dests')) nameDictionaryRef = this.catDict.get('Dests'); - if (nameDictionaryRef) { - // reading simple destination dictionary obj = nameDictionaryRef; obj.forEach(function catalogForEach(key, value) { if (!value) return; @@ -3049,7 +2678,6 @@ var Catalog = (function CatalogClosure() { }); } if (nameTreeRef) { - // reading name tree var processed = new RefSet(); processed.put(nameTreeRef); var queue = [nameTreeRef]; @@ -3084,10 +2712,8 @@ var Catalog = (function CatalogClosure() { return this.pageCache[n - 1]; } }; - return Catalog; })(); - var XRef = (function XRefClosure() { function XRef(stream, startXRef, mainXRefEntriesOffset, password) { this.stream = stream; @@ -3096,85 +2722,47 @@ var XRef = (function XRefClosure() { var trailerDict = this.readXRef(startXRef); trailerDict.assignXref(this); this.trailer = trailerDict; - // prepare the XRef cache this.cache = []; - var encrypt = trailerDict.get('Encrypt'); if (encrypt) { var fileId = trailerDict.get('ID'); this.encrypt = new CipherTransformFactory(encrypt, fileId[0], password); } - - // get the root dictionary (catalog) object if (!(this.root = trailerDict.get('Root'))) error('Invalid root reference'); } - XRef.prototype = { readXRefTable: function XRef_readXRefTable(parser) { - // Example of cross-reference table: - // xref - // 0 1 <-- subsection header (first obj #, obj count) - // 0000000000 65535 f <-- actual object (offset, generation #, f/n) - // 23 2 <-- subsection header ... and so on ... - // 0000025518 00002 n - // 0000025635 00000 n - // trailer - // ... - - // Outer loop is over subsection headers var obj; while (!isCmd(obj = parser.getObj(), 'trailer')) { var first = obj, count = parser.getObj(); - if (!isInt(first) || !isInt(count)) error('Invalid XRef table: wrong types in subsection header'); - - // Inner loop is over objects themselves for (var i = 0; i < count; i++) { var entry = {}; entry.offset = parser.getObj(); entry.gen = parser.getObj(); var type = parser.getObj(); - if (isCmd(type, 'f')) entry.free = true; else if (isCmd(type, 'n')) entry.uncompressed = true; - - // Validate entry obj if (!isInt(entry.offset) || !isInt(entry.gen) || !(entry.free || entry.uncompressed)) { error('Invalid entry in XRef subsection: ' + first + ', ' + count); } - if (!this.entries[i + first]) this.entries[i + first] = entry; } } - - // Sanity check: as per spec, first object must be free if (this.entries[0] && !this.entries[0].free) error('Invalid XRef table: unexpected first object'); - - // Sanity check if (!isCmd(obj, 'trailer')) error('Invalid XRef table: could not find trailer dictionary'); - - // Read trailer dictionary, e.g. - // trailer - // << /Size 22 - // /Root 20R - // /Info 10R - // /ID [ <81b14aafa313db63dbd6f981e49f94f4> ] - // >> - // The parser goes through the entire stream << ... >> and provides - // a getter interface for the key-value table var dict = parser.getObj(); if (!isDict(dict)) error('Invalid XRef table: could not parse trailer dictionary'); - return dict; }, readXRefStream: function XRef_readXRefStream(stream) { @@ -3199,7 +2787,6 @@ var XRef = (function XRefClosure() { var type = 0, offset = 0, generation = 0; for (j = 0; j < typeFieldWidth; ++j) type = (type << 8) | stream.getByte(); - // if type field is absent, its default value = 1 if (typeFieldWidth == 0) type = 1; for (j = 0; j < offsetFieldWidth; ++j) @@ -3229,8 +2816,6 @@ var XRef = (function XRefClosure() { return streamParameters; }, indexObjects: function XRef_indexObjects() { - // Simple scan through the PDF content to find objects, - // trailers and XRef streams. function readToken(data, offset) { var token = '', ch = data[offset]; while (ch !== 13 && ch !== 10) { @@ -3244,14 +2829,12 @@ var XRef = (function XRefClosure() { function skipUntil(data, offset, what) { var length = what.length, dataLength = data.length; var skipped = 0; - // finding byte sequence while (offset < dataLength) { var i = 0; while (i < length && data[offset + i] == what[i]) ++i; if (i >= length) - break; // sequence found - + break; offset++; skipped++; } @@ -3262,7 +2845,6 @@ var XRef = (function XRefClosure() { 101, 102]); var endobjBytes = new Uint8Array([101, 110, 100, 111, 98, 106]); var xrefBytes = new Uint8Array([47, 88, 82, 101, 102]); - var stream = this.stream; stream.pos = 0; var buffer = stream.getBytes(); @@ -3276,7 +2858,7 @@ var XRef = (function XRefClosure() { ++position; continue; } - if (ch === 37) { // %-comment + if (ch === 37) { do { ++position; ch = buffer[position]; @@ -3295,28 +2877,21 @@ var XRef = (function XRefClosure() { gen: m[2] | 0, uncompressed: true }; - var contentLength = skipUntil(buffer, position, endobjBytes) + 7; var content = buffer.subarray(position, position + contentLength); - - // checking XRef stream suspect - // (it shall have '/XRef' and next char is not a letter) var xrefTagOffset = skipUntil(content, 0, xrefBytes); if (xrefTagOffset < contentLength && content[xrefTagOffset + 5] < 64) { xrefStms.push(position); - this.xrefstms[position] = 1; // don't read it recursively + this.xrefstms[position] = 1; } - position += contentLength; } else position += token.length + 1; } - // reading XRef streams for (var i = 0, ii = xrefStms.length; i < ii; ++i) { this.readXRef(xrefStms[i], true); } - // finding main trailer var dict; for (var i = 0, ii = trailers.length; i < ii; ++i) { stream.pos = trailers[i]; @@ -3324,46 +2899,33 @@ var XRef = (function XRefClosure() { var obj = parser.getObj(); if (!isCmd(obj, 'trailer')) continue; - // read the trailer dictionary if (!isDict(dict = parser.getObj())) continue; - // taking the first one with 'ID' if (dict.has('ID')) return dict; } - // no tailer with 'ID', taking last one (if exists) if (dict) return dict; - // nothing helps error('Invalid PDF structure'); }, readXRef: function XRef_readXRef(startXRef, recoveryMode) { var stream = this.stream; stream.pos = startXRef; - try { var parser = new Parser(new Lexer(stream), true, null); var obj = parser.getObj(); var dict; - - // Get dictionary if (isCmd(obj, 'xref')) { - // Parse end-of-file XRef dict = this.readXRefTable(parser); - - // Recursively get other XRefs 'XRefStm', if any obj = dict.get('XRefStm'); if (isInt(obj)) { var pos = obj; - // ignore previously loaded xref streams - // (possible infinite recursion) if (!(pos in this.xrefstms)) { this.xrefstms[pos] = 1; this.readXRef(pos); } } } else if (isInt(obj)) { - // Parse in-stream XRef if (!isInt(parser.getObj()) || !isCmd(parser.getObj(), 'obj') || !isStream(obj = parser.getObj())) { @@ -3373,25 +2935,18 @@ var XRef = (function XRefClosure() { if (!dict) error('Failed to read XRef stream'); } - - // Recursively get previous dictionary, if any obj = dict.get('Prev'); if (isInt(obj)) this.readXRef(obj, recoveryMode); else if (isRef(obj)) { - // The spec says Prev must not be a reference, i.e. "/Prev NNN" - // This is a fallback for non-compliant PDFs, i.e. "/Prev NNN 0 R" this.readXRef(obj.num, recoveryMode); } - return dict; } catch (e) { log('(while reading XRef): ' + e); } - if (recoveryMode) return; - warn('Indexing all PDF objects'); return this.indexObjects(); }, @@ -3399,7 +2954,7 @@ var XRef = (function XRefClosure() { var e = this.entries[i]; if (e === null) return null; - return e.free ? null : e; // returns null is the entry is free + return e.free ? null : e; }, fetchIfRef: function XRef_fetchIfRef(obj) { if (!isRef(obj)) @@ -3411,13 +2966,9 @@ var XRef = (function XRefClosure() { var num = ref.num; if (num in this.cache) return this.cache[num]; - var e = this.getEntry(num); - - // the referenced entry can be free if (e === null) return (this.cache[num] = e); - var gen = ref.gen; var stream, parser; if (e.uncompressed) { @@ -3434,7 +2985,6 @@ var XRef = (function XRefClosure() { error('bad XRef entry'); } if (!isCmd(obj3, 'obj')) { - // some bad pdfs use "obj1234" and really mean 1234 if (obj3.cmd.indexOf('obj') == 0) { num = parseInt(obj3.cmd.substring(3), 10); if (!isNaN(num)) @@ -3446,21 +2996,15 @@ var XRef = (function XRefClosure() { try { e = parser.getObj(this.encrypt.createCipherTransform(num, gen)); } catch (ex) { - // almost all streams must be encrypted, but sometimes - // they are not probably due to some broken generators - // re-trying without encryption return this.fetch(ref, true); } } else { e = parser.getObj(); } - // Don't cache streams since they are mutable (except images). if (!isStream(e) || e instanceof JpegStream) this.cache[num] = e; return e; } - - // compressed entry stream = this.fetch(new Ref(e.offset, 0)); if (!isStream(stream)) error('bad ObjStm stream'); @@ -3471,7 +3015,6 @@ var XRef = (function XRefClosure() { } parser = new Parser(new Lexer(stream), false, this); var i, entries = [], nums = []; - // read the object numbers to populate cache for (i = 0; i < n; ++i) { num = parser.getObj(); if (!isInt(num)) { @@ -3483,7 +3026,6 @@ var XRef = (function XRefClosure() { error('invalid object offset in the ObjStm stream: ' + offset); } } - // read stream objects for cache for (i = 0; i < n; ++i) { entries.push(parser.getObj()); this.cache[nums[i]] = entries[i]; @@ -3498,82 +3040,40 @@ var XRef = (function XRefClosure() { return this.root; } }; - return XRef; })(); - -/** - * A PDF document and page is built of many objects. E.g. there are objects - * for fonts, images, rendering code and such. These objects might get processed - * inside of a worker. The `PDFObjects` implements some basic functions to - * manage these objects. - */ var PDFObjects = (function PDFObjectsClosure() { function PDFObjects() { this.objs = {}; } - PDFObjects.prototype = { objs: null, - - /** - * Internal function. - * Ensures there is an object defined for `objId`. Stores `data` on the - * object *if* it is created. - */ ensureObj: function PDFObjects_ensureObj(objId, data) { if (this.objs[objId]) return this.objs[objId]; return this.objs[objId] = new Promise(objId, data); }, - - /** - * If called *without* callback, this returns the data of `objId` but the - * object needs to be resolved. If it isn't, this function throws. - * - * If called *with* a callback, the callback is called with the data of the - * object once the object is resolved. That means, if you call this - * function and the object is already resolved, the callback gets called - * right away. - */ get: function PDFObjects_get(objId, callback) { - // If there is a callback, then the get can be async and the object is - // not required to be resolved right now if (callback) { this.ensureObj(objId).then(callback); return null; } - - // If there isn't a callback, the user expects to get the resolved data - // directly. var obj = this.objs[objId]; - - // If there isn't an object yet or the object isn't resolved, then the - // data isn't ready yet! if (!obj || !obj.isResolved) error('Requesting object that isn\'t resolved yet ' + objId); - return obj.data; }, - - /** - * Resolves the object `objId` with optional `data`. - */ resolve: function PDFObjects_resolve(objId, data) { var objs = this.objs; - - // In case there is a promise already on this object, just resolve it. if (objs[objId]) { objs[objId].resolve(data); } else { this.ensureObj(objId, data); } }, - onData: function PDFObjects_onData(objId, callback) { this.ensureObj(objId).onData(callback); }, - isResolved: function PDFObjects_isResolved(objId) { var objs = this.objs; if (!objs[objId]) { @@ -3582,7 +3082,6 @@ var PDFObjects = (function PDFObjectsClosure() { return objs[objId].isResolved; } }, - hasData: function PDFObjects_hasData(objId) { var objs = this.objs; if (!objs[objId]) { @@ -3591,31 +3090,20 @@ var PDFObjects = (function PDFObjectsClosure() { return objs[objId].hasData; } }, - - /** - * Sets the data of an object but *doesn't* resolve it. - */ setData: function PDFObjects_setData(objId, data) { - // Watchout! If you call `this.ensureObj(objId, data)` you're going to - // create a *resolved* promise which shouldn't be the case! this.ensureObj(objId).data = data; } }; return PDFObjects; })(); - - /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - 'use strict'; - var PDFFunction = (function PDFFunctionClosure() { var CONSTRUCT_SAMPLED = 0; var CONSTRUCT_INTERPOLATED = 2; var CONSTRUCT_STICHED = 3; var CONSTRUCT_POSTSCRIPT = 4; - return { getSampleArray: function PDFFunction_getSampleArray(size, outputSize, bps, str) { @@ -3623,13 +3111,10 @@ var PDFFunction = (function PDFFunctionClosure() { for (var i = 0, ii = size.length; i < ii; i++) length *= size[i]; length *= outputSize; - var array = []; var codeSize = 0; var codeBuf = 0; - // 32 is a valid bps so shifting won't work var sampleMul = 1.0 / (Math.pow(2.0, bps) - 1); - var strBytes = str.getBytes((length * bps + 7) / 8); var strIdx = 0; for (var i = 0; i < length; i++) { @@ -3644,26 +3129,21 @@ var PDFFunction = (function PDFFunctionClosure() { } return array; }, - getIR: function PDFFunction_getIR(xref, fn) { var dict = fn.dict; if (!dict) dict = fn; - var types = [this.constructSampled, null, this.constructInterpolated, this.constructStiched, this.constructPostScript]; - var typeNum = dict.get('FunctionType'); var typeFn = types[typeNum]; if (!typeFn) error('Unknown type of function'); - return typeFn.call(this, fn, dict, xref); }, - fromIR: function PDFFunction_fromIR(IR) { var type = IR[0]; switch (type) { @@ -3678,12 +3158,10 @@ var PDFFunction = (function PDFFunctionClosure() { return this.constructPostScriptFromIR(IR); } }, - parse: function PDFFunction_parse(xref, fn) { var IR = this.getIR(xref, fn); return this.fromIR(IR); }, - constructSampled: function PDFFunction_constructSampled(str, dict) { function toMultiArray(arr) { var inputLength = arr.length; @@ -3698,16 +3176,12 @@ var PDFFunction = (function PDFFunctionClosure() { } var domain = dict.get('Domain'); var range = dict.get('Range'); - if (!domain || !range) error('No domain or range'); - var inputSize = domain.length / 2; var outputSize = range.length / 2; - domain = toMultiArray(domain); range = toMultiArray(range); - var size = dict.get('Size'); var bps = dict.get('BitsPerSample'); var order = dict.get('Order'); @@ -3715,7 +3189,6 @@ var PDFFunction = (function PDFFunctionClosure() { order = 1; if (order !== 1) error('No support for cubic spline interpolation: ' + order); - var encode = dict.get('Encode'); if (!encode) { encode = []; @@ -3725,29 +3198,22 @@ var PDFFunction = (function PDFFunctionClosure() { } } encode = toMultiArray(encode); - var decode = dict.get('Decode'); if (!decode) decode = range; else decode = toMultiArray(decode); - var samples = this.getSampleArray(size, outputSize, bps, str); - return [ CONSTRUCT_SAMPLED, inputSize, domain, encode, decode, samples, size, outputSize, Math.pow(2, bps) - 1, range ]; }, - constructSampledFromIR: function PDFFunction_constructSampledFromIR(IR) { - // See chapter 3, page 109 of the PDF reference function interpolate(x, xmin, xmax, ymin, ymax) { return ymin + ((x - xmin) * ((ymax - ymin) / (xmax - xmin))); } - return function constructSampledFromIRResult(args) { - // See chapter 3, page 110 of the PDF reference. var m = IR[1]; var domain = IR[2]; var encode = IR[3]; @@ -3757,44 +3223,29 @@ var PDFFunction = (function PDFFunctionClosure() { var n = IR[7]; var mask = IR[8]; var range = IR[9]; - if (m != args.length) error('Incorrect number of arguments: ' + inputSize + ' != ' + args.length); - var x = args; - - // Building the cube vertices: its part and sample index - // http://rjwagner49.com/Mathematics/Interpolation.pdf var cubeVertices = 1 << m; var cubeN = new Float64Array(cubeVertices); var cubeVertex = new Uint32Array(cubeVertices); for (var j = 0; j < cubeVertices; j++) cubeN[j] = 1; - var k = n, pos = 1; - // Map x_i to y_j for 0 <= i < m using the sampled function. for (var i = 0; i < m; ++i) { - // x_i' = min(max(x_i, Domain_2i), Domain_2i+1) var domain_2i = domain[i][0]; var domain_2i_1 = domain[i][1]; var xi = Math.min(Math.max(x[i], domain_2i), domain_2i_1); - - // e_i = Interpolate(x_i', Domain_2i, Domain_2i+1, - // Encode_2i, Encode_2i+1) var e = interpolate(xi, domain_2i, domain_2i_1, encode[i][0], encode[i][1]); - - // e_i' = min(max(e_i, 0), Size_i - 1) var size_i = size[i]; e = Math.min(Math.max(e, 0), size_i - 1); - - // Adjusting the cube: N and vertex sample index - var e0 = e < size_i - 1 ? Math.floor(e) : e - 1; // e1 = e0 + 1; - var n0 = e0 + 1 - e; // (e1 - e) / (e1 - e0); - var n1 = e - e0; // (e - e0) / (e1 - e0); + var e0 = e < size_i - 1 ? Math.floor(e) : e - 1; + var n0 = e0 + 1 - e; + var n1 = e - e0; var offset0 = e0 * k; - var offset1 = offset0 + k; // e1 * k + var offset1 = offset0 + k; for (var j = 0; j < cubeVertices; j++) { if (j & pos) { cubeN[j] *= n1; @@ -3804,99 +3255,72 @@ var PDFFunction = (function PDFFunctionClosure() { cubeVertex[j] += offset0; } } - k *= size_i; pos <<= 1; } - var y = new Float64Array(n); for (var j = 0; j < n; ++j) { - // Sum all cube vertices' samples portions + var rj = 0; for (var i = 0; i < cubeVertices; i++) rj += samples[cubeVertex[i] + j] * cubeN[i]; - - // r_j' = Interpolate(r_j, 0, 2^BitsPerSample - 1, - // Decode_2j, Decode_2j+1) rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]); - - // y_j = min(max(r_j, range_2j), range_2j+1) y[j] = Math.min(Math.max(rj, range[j][0]), range[j][1]); } - return y; } }, - constructInterpolated: function PDFFunction_constructInterpolated(str, dict) { var c0 = dict.get('C0') || [0]; var c1 = dict.get('C1') || [1]; var n = dict.get('N'); - if (!isArray(c0) || !isArray(c1)) error('Illegal dictionary for interpolated function'); - var length = c0.length; var diff = []; for (var i = 0; i < length; ++i) diff.push(c1[i] - c0[i]); - return [CONSTRUCT_INTERPOLATED, c0, diff, n]; }, - constructInterpolatedFromIR: function PDFFunction_constructInterpolatedFromIR(IR) { var c0 = IR[1]; var diff = IR[2]; var n = IR[3]; - var length = diff.length; - return function constructInterpolatedFromIRResult(args) { var x = n == 1 ? args[0] : Math.pow(args[0], n); - var out = []; for (var j = 0; j < length; ++j) out.push(c0[j] + (x * diff[j])); - return out; - } }, - constructStiched: function PDFFunction_constructStiched(fn, dict, xref) { var domain = dict.get('Domain'); - if (!domain) error('No domain'); - var inputSize = domain.length / 2; if (inputSize != 1) error('Bad domain for stiched function'); - var fnRefs = dict.get('Functions'); var fns = []; for (var i = 0, ii = fnRefs.length; i < ii; ++i) fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i]))); - var bounds = dict.get('Bounds'); var encode = dict.get('Encode'); - return [CONSTRUCT_STICHED, domain, bounds, encode, fns]; }, - constructStichedFromIR: function PDFFunction_constructStichedFromIR(IR) { var domain = IR[1]; var bounds = IR[2]; var encode = IR[3]; var fnsIR = IR[4]; var fns = []; - for (var i = 0, ii = fnsIR.length; i < ii; i++) { fns.push(PDFFunction.fromIR(fnsIR[i])); } - return function constructStichedFromIRResult(args) { var clip = function constructStichedFromIRClip(v, min, max) { if (v > max) @@ -3905,51 +3329,36 @@ var PDFFunction = (function PDFFunctionClosure() { v = min; return v; }; - - // clip to domain var v = clip(args[0], domain[0], domain[1]); - // calulate which bound the value is in for (var i = 0, ii = bounds.length; i < ii; ++i) { if (v < bounds[i]) break; } - - // encode value into domain of function var dmin = domain[0]; if (i > 0) dmin = bounds[i - 1]; var dmax = domain[1]; if (i < bounds.length) dmax = bounds[i]; - var rmin = encode[2 * i]; var rmax = encode[2 * i + 1]; - var v2 = rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin); - - // call the appropropriate function return fns[i]([v2]); }; }, - constructPostScript: function PDFFunction_constructPostScript(fn, dict, xref) { var domain = dict.get('Domain'); var range = dict.get('Range'); - if (!domain) error('No domain.'); - if (!range) error('No range.'); - var lexer = new PostScriptLexer(fn); var parser = new PostScriptParser(lexer); var code = parser.parse(); - return [CONSTRUCT_POSTSCRIPT, domain, range, code]; }, - constructPostScriptFromIR: function PDFFunction_constructPostScriptFromIR( IR) { var domain = IR[1]; @@ -3957,19 +3366,15 @@ var PDFFunction = (function PDFFunctionClosure() { var code = IR[3]; var numOutputs = range.length / 2; var evaluator = new PostScriptEvaluator(code); - // Cache the values for a big speed up, the cache size is limited though - // since the number of possible values can be huge from a PS function. var cache = new FunctionCache(); return function constructPostScriptFromIRResult(args) { var initialStack = []; for (var i = 0, ii = (domain.length / 2); i < ii; ++i) { initialStack.push(args[i]); } - var key = initialStack.join('_'); if (cache.has(key)) return cache.get(key); - var stack = evaluator.execute(initialStack); var transformed = []; for (i = numOutputs - 1; i >= 0; --i) { @@ -3987,10 +3392,7 @@ var PDFFunction = (function PDFFunctionClosure() { } }; })(); - var FunctionCache = (function FunctionCacheClosure() { - // Of 10 PDF's with type4 functions the maxium number of distinct values seen - // was 256. This still may need some tweaking in the future though. var MAX_CACHE_SIZE = 1024; function FunctionCache() { this.cache = {}; @@ -4012,13 +3414,11 @@ var FunctionCache = (function FunctionCacheClosure() { }; return FunctionCache; })(); - var PostScriptStack = (function PostScriptStackClosure() { var MAX_STACK_SIZE = 100; function PostScriptStack(initialStack) { this.stack = initialStack || []; } - PostScriptStack.prototype = { push: function PostScriptStack_push(value) { if (this.stack.length >= MAX_STACK_SIZE) @@ -4040,7 +3440,6 @@ var PostScriptStack = (function PostScriptStackClosure() { index: function PostScriptStack_index(n) { this.push(this.stack[this.stack.length - n - 1]); }, - // rotate the last n stack elements p times roll: function PostScriptStack_roll(n, p) { var stack = this.stack; var l = stack.length - n; @@ -4073,24 +3472,20 @@ var PostScriptEvaluator = (function PostScriptEvaluatorClosure() { while (counter < length) { operator = operators[counter++]; if (typeof operator == 'number') { - // Operator is really an operand and should be pushed to the stack. stack.push(operator); continue; } switch (operator) { - // non standard ps operators - case 'jz': // jump if false + case 'jz': b = stack.pop(); a = stack.pop(); if (!a) counter = b; break; - case 'j': // jump + case 'j': a = stack.pop(); counter = a; break; - - // all ps operators in alphabetical order (excluding if/ifelse) case 'abs': a = stack.pop(); stack.push(Math.abs(a)); @@ -4137,7 +3532,6 @@ var PostScriptEvaluator = (function PostScriptEvaluatorClosure() { stack.push(a); break; case 'cvr': - // noop break; case 'div': b = stack.pop(); @@ -4289,7 +3683,6 @@ var PostScriptEvaluator = (function PostScriptEvaluatorClosure() { }; return PostScriptEvaluator; })(); - var PostScriptParser = (function PostScriptParserClosure() { function PostScriptParser(lexer) { this.lexer = lexer; @@ -4336,15 +3729,11 @@ var PostScriptParser = (function PostScriptParserClosure() { } }, parseCondition: function PostScriptParser_parseCondition() { - // Add two place holders that will be updated later var conditionLocation = this.operators.length; this.operators.push(null, null); - this.parseBlock(); this.expect(PostScriptTokenTypes.RBRACE); if (this.accept(PostScriptTokenTypes.IF)) { - // The true block is right after the 'if' so it just falls through on - // true else it jumps and skips the true block. this.operators[conditionLocation] = this.operators.length; this.operators[conditionLocation + 1] = 'jz'; } else if (this.accept(PostScriptTokenTypes.LBRACE)) { @@ -4354,11 +3743,8 @@ var PostScriptParser = (function PostScriptParserClosure() { this.parseBlock(); this.expect(PostScriptTokenTypes.RBRACE); this.expect(PostScriptTokenTypes.IFELSE); - // The jump is added at the end of the true block to skip the false - // block. this.operators[jumpLocation] = this.operators.length; this.operators[jumpLocation + 1] = 'j'; - this.operators[conditionLocation] = endOfTrue; this.operators[conditionLocation + 1] = 'jz'; } else { @@ -4368,7 +3754,6 @@ var PostScriptParser = (function PostScriptParserClosure() { }; return PostScriptParser; })(); - var PostScriptTokenTypes = { LBRACE: 0, RBRACE: 1, @@ -4377,23 +3762,18 @@ var PostScriptTokenTypes = { IF: 4, IFELSE: 5 }; - var PostScriptToken = (function PostScriptTokenClosure() { function PostScriptToken(type, value) { this.type = type; this.value = value; } - var opCache = {}; - PostScriptToken.getOperator = function PostScriptToken_getOperator(op) { var opValue = opCache[op]; if (opValue) return opValue; - return opCache[op] = new PostScriptToken(PostScriptTokenTypes.OPERATOR, op); }; - PostScriptToken.LBRACE = new PostScriptToken(PostScriptTokenTypes.LBRACE, '{'); PostScriptToken.RBRACE = new PostScriptToken(PostScriptTokenTypes.RBRACE, @@ -4403,7 +3783,6 @@ var PostScriptToken = (function PostScriptTokenClosure() { 'IFELSE'); return PostScriptToken; })(); - var PostScriptLexer = (function PostScriptLexerClosure() { function PostScriptLexer(stream) { this.stream = stream; @@ -4414,12 +3793,9 @@ var PostScriptLexer = (function PostScriptLexerClosure() { var ch; var comment = false; var stream = this.stream; - - // skip comments while (true) { if (!(ch = stream.getChar())) return EOF; - if (comment) { if (ch == '\x0a' || ch == '\x0d') comment = false; @@ -4440,7 +3816,6 @@ var PostScriptLexer = (function PostScriptLexerClosure() { case '}': return PostScriptToken.RBRACE; } - // operator var str = ch.toLowerCase(); while (true) { ch = stream.lookChar(); @@ -4481,13 +3856,9 @@ var PostScriptLexer = (function PostScriptLexerClosure() { }; return PostScriptLexer; })(); - - /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - 'use strict'; - var ISOAdobeCharset = [ '.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', 'ampersand', 'quoteright', 'parenleft', 'parenright', @@ -4524,7 +3895,6 @@ var ISOAdobeCharset = [ 'ograve', 'otilde', 'scaron', 'uacute', 'ucircumflex', 'udieresis', 'ugrave', 'yacute', 'ydieresis', 'zcaron' ]; - var ExpertCharset = [ '.notdef', 'space', 'exclamsmall', 'Hungarumlautsmall', 'dollaroldstyle', 'dollarsuperior', 'ampersandsmall', 'Acutesmall', 'parenleftsuperior', @@ -4564,7 +3934,6 @@ var ExpertCharset = [ 'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall', 'Ydieresissmall' ]; - var ExpertSubsetCharset = [ '.notdef', 'space', 'dollaroldstyle', 'dollarsuperior', 'parenleftsuperior', 'parenrightsuperior', 'twodotenleader', @@ -4587,13 +3956,9 @@ var ExpertSubsetCharset = [ 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', 'periodinferior', 'commainferior' ]; - - /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - 'use strict'; - var CIDToUnicodeMaps = { 'Adobe-Japan1': [[32, 160], {f: 12, c: 33}, [45, 8209], {f: 46, c: 46}, 165, {f: 2, c: 93}, [95, 818], [96, 768], {f: 27, c: 97}, 166, 125, [732, 771], @@ -11521,43 +10886,29 @@ var CIDToUnicodeMaps = { {f: 39, c: 19576}, {f: 111, c: 19620}, {f: 148, c: 19738}, {f: 7, c: 19887}] }; - - /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - 'use strict'; - var ColorSpace = (function ColorSpaceClosure() { - // Constructor should define this.numComps, this.defaultColor, this.name function ColorSpace() { error('should not call ColorSpace constructor'); } - ColorSpace.prototype = { - // Input: array of size numComps representing color component values - // Output: array of rgb values, each value ranging from [0.1] getRgb: function ColorSpace_getRgb(color) { error('Should not call ColorSpace.getRgb: ' + color); }, - // Input: Uint8Array of component values, each value scaled to [0,255] - // Output: Uint8Array of rgb values, each value scaled to [0,255] getRgbBuffer: function ColorSpace_getRgbBuffer(input) { error('Should not call ColorSpace.getRgbBuffer: ' + input); } }; - ColorSpace.parse = function ColorSpace_parse(cs, xref, res) { var IR = ColorSpace.parseToIR(cs, xref, res); if (IR instanceof AlternateCS) return IR; - return ColorSpace.fromIR(IR); }; - ColorSpace.fromIR = function ColorSpace_fromIR(IR) { var name = isArray(IR) ? IR[0] : IR; - switch (name) { case 'DeviceGrayCS': return new DeviceGrayCS(); @@ -11579,7 +10930,6 @@ var ColorSpace = (function ColorSpaceClosure() { var numComps = IR[1]; var alt = IR[2]; var tintFnIR = IR[3]; - return new AlternateCS(numComps, ColorSpace.fromIR(alt), PDFFunction.fromIR(tintFnIR)); case 'LabCS': @@ -11592,7 +10942,6 @@ var ColorSpace = (function ColorSpaceClosure() { } return null; }; - ColorSpace.parseToIR = function ColorSpace_parseToIR(cs, xref, res) { if (isName(cs)) { var colorSpaces = res.get('ColorSpace'); @@ -11602,14 +10951,11 @@ var ColorSpace = (function ColorSpaceClosure() { cs = refcs; } } - cs = xref.fetchIfRef(cs); var mode; - if (isName(cs)) { mode = cs.name; this.mode = mode; - switch (mode) { case 'DeviceGray': case 'G': @@ -11628,7 +10974,6 @@ var ColorSpace = (function ColorSpaceClosure() { } else if (isArray(cs)) { mode = cs[0].name; this.mode = mode; - switch (mode) { case 'DeviceGray': case 'G': @@ -11687,19 +11032,9 @@ var ColorSpace = (function ColorSpaceClosure() { } return null; }; - /** - * Checks if a decode map matches the default decode map for a color space. - * This handles the general decode maps where there are two values per - * component. e.g. [0, 1, 0, 1, 0, 1] for a RGB color. - * This does not handle Lab, Indexed, or Pattern decode maps since they are - * slightly different. - * @param {Array} decode Decode map (usually from an image). - * @param {Number} n Number of components the color space has. - */ ColorSpace.isDefaultDecode = function ColorSpace_isDefaultDecode(decode, n) { if (!decode) return true; - if (n * 2 !== decode.length) { warning('The decode map is not the correct length'); return true; @@ -11710,16 +11045,8 @@ var ColorSpace = (function ColorSpaceClosure() { } return true; }; - return ColorSpace; })(); - -/** - * Alternate color space handles both Separation and DeviceN color spaces. A - * Separation color space is actually just a DeviceN with one color component. - * Both color spaces use a tinting function to convert colors to a base color - * space. - */ var AlternateCS = (function AlternateCSClosure() { function AlternateCS(numComps, base, tintFn) { this.name = 'Alternate'; @@ -11730,7 +11057,6 @@ var AlternateCS = (function AlternateCSClosure() { this.base = base; this.tintFn = tintFn; } - AlternateCS.prototype = { getRgb: function AlternateCS_getRgb(color) { var tinted = this.tintFn(color); @@ -11746,11 +11072,9 @@ var AlternateCS = (function AlternateCSClosure() { var baseBuf = new Uint8Array(baseNumComps * length); var numComps = this.numComps; var scaled = []; - for (var i = 0; i < length; i += numComps) { for (var z = 0; z < numComps; ++z) scaled[z] = input[i + z] * scale; - var tinted = tintFn(scaled); for (var j = 0; j < baseNumComps; ++j) baseBuf[pos++] = 255 * tinted[j]; @@ -11761,20 +11085,16 @@ var AlternateCS = (function AlternateCSClosure() { return ColorSpace.isDefaultDecode(decodeMap, this.numComps); } }; - return AlternateCS; })(); - var PatternCS = (function PatternCSClosure() { function PatternCS(baseCS) { this.name = 'Pattern'; this.base = baseCS; } PatternCS.prototype = {}; - return PatternCS; })(); - var IndexedCS = (function IndexedCSClosure() { function IndexedCS(base, highVal, lookup) { this.name = 'Indexed'; @@ -11782,11 +11102,9 @@ var IndexedCS = (function IndexedCSClosure() { this.defaultColor = [0]; this.base = base; this.highVal = highVal; - var baseNumComps = base.numComps; var length = baseNumComps * highVal; var lookupArray = new Uint8Array(length); - if (isStream(lookup)) { var bytes = lookup.getBytes(length); lookupArray.set(bytes); @@ -11798,16 +11116,13 @@ var IndexedCS = (function IndexedCSClosure() { } this.lookup = lookupArray; } - IndexedCS.prototype = { getRgb: function IndexedCS_getRgb(color) { var numComps = this.base.numComps; var start = color[0] * numComps; var c = []; - for (var i = start, ii = start + numComps; i < ii; ++i) c.push(this.lookup[i]); - return this.base.getRgb(c); }, getRgbBuffer: function IndexedCS_getRgbBuffer(input) { @@ -11817,31 +11132,26 @@ var IndexedCS = (function IndexedCSClosure() { var length = input.length; var baseBuf = new Uint8Array(length * numComps); var baseBufPos = 0; - for (var i = 0; i < length; ++i) { var lookupPos = input[i] * numComps; for (var j = 0; j < numComps; ++j) { baseBuf[baseBufPos++] = lookup[lookupPos + j]; } } - return base.getRgbBuffer(baseBuf, 8); }, isDefaultDecode: function IndexedCS_isDefaultDecode(decodeMap) { - // indexed color maps shouldn't be changed return true; } }; return IndexedCS; })(); - var DeviceGrayCS = (function DeviceGrayCSClosure() { function DeviceGrayCS() { this.name = 'DeviceGray'; this.numComps = 1; this.defaultColor = [0]; } - DeviceGrayCS.prototype = { getRgb: function DeviceGrayCS_getRgb(color) { var c = color[0]; @@ -11865,7 +11175,6 @@ var DeviceGrayCS = (function DeviceGrayCSClosure() { }; return DeviceGrayCS; })(); - var DeviceRgbCS = (function DeviceRgbCSClosure() { function DeviceRgbCS() { this.name = 'DeviceRGB'; @@ -11892,7 +11201,6 @@ var DeviceRgbCS = (function DeviceRgbCSClosure() { }; return DeviceRgbCS; })(); - var DeviceCmykCS = (function DeviceCmykCSClosure() { function DeviceCmykCS() { this.name = 'DeviceCMYK'; @@ -11902,17 +11210,12 @@ var DeviceCmykCS = (function DeviceCmykCSClosure() { DeviceCmykCS.prototype = { getRgb: function DeviceCmykCS_getRgb(color) { var c = color[0], m = color[1], y = color[2], k = color[3]; - - // CMYK -> CMY: http://www.easyrgb.com/index.php?X=MATH&H=14#text14 c = (c * (1 - k) + k); m = (m * (1 - k) + k); y = (y * (1 - k) + k); - - // CMY -> RGB: http://www.easyrgb.com/index.php?X=MATH&H=12#text12 var r = (1 - c); var g = (1 - m); var b = (1 - y); - return [r, g, b]; }, getRgbBuffer: function DeviceCmykCS_getRgbBuffer(colorBuf, bits) { @@ -11921,42 +11224,31 @@ var DeviceCmykCS = (function DeviceCmykCSClosure() { var rgbBuf = new Uint8Array(length * 3); var rgbBufPos = 0; var colorBufPos = 0; - for (var i = 0; i < length; i++) { var cmyk = []; for (var j = 0; j < 4; ++j) cmyk.push(scale * colorBuf[colorBufPos++]); - var rgb = this.getRgb(cmyk); for (var j = 0; j < 3; ++j) rgbBuf[rgbBufPos++] = Math.round(rgb[j] * 255); } - return rgbBuf; }, isDefaultDecode: function DeviceCmykCS_isDefaultDecode(decodeMap) { return ColorSpace.isDefaultDecode(decodeMap, this.numComps); } }; - return DeviceCmykCS; })(); - -// -// LabCS: Based on "PDF Reference, Sixth Ed", p.250 -// var LabCS = (function LabCSClosure() { function LabCS(whitePoint, blackPoint, range) { this.name = 'Lab'; this.numComps = 3; this.defaultColor = [0, 0, 0]; - if (!whitePoint) error('WhitePoint missing - required for color space Lab'); blackPoint = blackPoint || [0, 0, 0]; range = range || [-100, 100, -100, 100]; - - // Translate args to spec variables this.XW = whitePoint[0]; this.YW = whitePoint[1]; this.ZW = whitePoint[2]; @@ -11964,22 +11256,15 @@ var LabCS = (function LabCSClosure() { this.amax = range[1]; this.bmin = range[2]; this.bmax = range[3]; - - // These are here just for completeness - the spec doesn't offer any - // formulas that use BlackPoint in Lab this.XB = blackPoint[0]; this.YB = blackPoint[1]; this.ZB = blackPoint[2]; - - // Validate vars as per spec if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) error('Invalid WhitePoint components, no fallback available'); - if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { info('Invalid BlackPoint, falling back to default'); this.XB = this.YB = this.ZB = 0; } - if (this.amin > this.amax || this.bmin > this.bmax) { info('Invalid Range, falling back to defaults'); this.amin = -100; @@ -11988,40 +11273,28 @@ var LabCS = (function LabCSClosure() { this.bmax = 100; } }; - - // Function g(x) from spec function g(x) { if (x >= 6 / 29) return x * x * x; else return (108 / 841) * (x - 4 / 29); } - LabCS.prototype = { getRgb: function LabCS_getRgb(color) { - // Ls,as,bs <---> L*,a*,b* in the spec var Ls = color[0], as = color[1], bs = color[2]; - - // Adjust limits of 'as' and 'bs' as = as > this.amax ? this.amax : as; as = as < this.amin ? this.amin : as; bs = bs > this.bmax ? this.bmax : bs; bs = bs < this.bmin ? this.bmin : bs; - - // Computes intermediate variables X,Y,Z as per spec var M = (Ls + 16) / 116; var L = M + (as / 500); var N = M - (bs / 200); var X = this.XW * g(L); var Y = this.YW * g(M); var Z = this.ZW * g(N); - - // XYZ to RGB 3x3 matrix, from: - // http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC18 var XYZtoRGB = [3.240479, -1.537150, -0.498535, -0.969256, 1.875992, 0.041556, 0.055648, -0.204043, 1.057311]; - return Util.apply3dTransform(XYZtoRGB, [X, Y, Z]); }, getRgbBuffer: function LabCS_getRgbBuffer(input, bits) { @@ -12030,21 +11303,16 @@ var LabCS = (function LabCSClosure() { var scale = 255 / ((1 << bits) - 1); var i, length = input.length / 3; var rgbBuf = new Uint8Array(length); - var j = 0; for (i = 0; i < length; ++i) { - // Convert L*, a*, s* into RGB var rgb = this.getRgb([input[i], input[i + 1], input[i + 2]]); rgbBuf[j++] = rgb[0]; rgbBuf[j++] = rgb[1]; rgbBuf[j++] = rgb[2]; } - return rgbBuf; }, isDefaultDecode: function LabCS_isDefaultDecode(decodeMap) { - // From Table 90 in Adobe's: - // "Document management - Portable document format", 1st ed, 2008 if (decodeMap[0] === 0 && decodeMap[1] === 100 && decodeMap[2] === this.amin && decodeMap[3] === this.amax && decodeMap[4] === this.bmin && decodeMap[5] === this.bmax) @@ -12055,12 +11323,9 @@ var LabCS = (function LabCSClosure() { }; return LabCS; })(); - /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - 'use strict'; - var ARCFourCipher = (function ARCFourCipherClosure() { function ARCFourCipher(key) { this.a = 0; @@ -12077,7 +11342,6 @@ var ARCFourCipher = (function ARCFourCipherClosure() { } this.s = s; } - ARCFourCipher.prototype = { encryptBlock: function ARCFourCipher_encryptBlock(data) { var i, n = data.length, tmp, tmp2; @@ -12098,17 +11362,14 @@ var ARCFourCipher = (function ARCFourCipherClosure() { } }; ARCFourCipher.prototype.decryptBlock = ARCFourCipher.prototype.encryptBlock; - return ARCFourCipher; })(); - var calculateMD5 = (function calculateMD5Closure() { var r = new Uint8Array([ 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]); - var k = new Int32Array([ -680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, @@ -12121,11 +11382,9 @@ var calculateMD5 = (function calculateMD5Closure() { -198630844, 1126891415, -1416354905, -57434055, 1700485571, -1894986606, -1051523, -2054922799, 1873313359, -30611744, -1560198380, 1309151649, -145523070, -1120210379, 718787259, -343485551]); - function hash(data, offset, length) { var h0 = 1732584193, h1 = -271733879, h2 = -1732584194, h3 = 271733878; - // pre-processing - var paddedLength = (length + 72) & ~63; // data + 9 extra bytes + var paddedLength = (length + 72) & ~63; var padded = new Uint8Array(paddedLength); var i, j, n; for (i = 0; i < length; ++i) @@ -12142,8 +11401,6 @@ var calculateMD5 = (function calculateMD5Closure() { padded[i++] = 0; padded[i++] = 0; padded[i++] = 0; - // chunking - // TODO ArrayBuffer ? var w = new Int32Array(16); for (i = 0; i < paddedLength;) { for (j = 0; j < 16; ++j, i += 4) { @@ -12185,20 +11442,16 @@ var calculateMD5 = (function calculateMD5Closure() { } return hash; })(); - var NullCipher = (function NullCipherClosure() { function NullCipher() { } - NullCipher.prototype = { decryptBlock: function NullCipher_decryptBlock(data) { return data; } }; - return NullCipher; })(); - var AES128Cipher = (function AES128CipherClosure() { var rcon = new Uint8Array([ 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, @@ -12223,7 +11476,6 @@ var AES128Cipher = (function AES128CipherClosure() { 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d]); - var s = new Uint8Array([ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, @@ -12247,7 +11499,6 @@ var AES128Cipher = (function AES128CipherClosure() { 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]); - var inv_s = new Uint8Array([ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, @@ -12271,7 +11522,6 @@ var AES128Cipher = (function AES128CipherClosure() { 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d]); - var mix = new Uint32Array([ 0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, @@ -12316,17 +11566,13 @@ var AES128Cipher = (function AES128CipherClosure() { 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3]); - function expandKey128(cipherKey) { var b = 176, result = new Uint8Array(b); result.set(cipherKey); for (var j = 16, i = 1; j < b; ++i) { - // RotWord var t1 = result[j - 3], t2 = result[j - 2], t3 = result[j - 1], t4 = result[j - 4]; - // SubWord t1 = s[t1]; t2 = s[t2]; t3 = s[t3]; t4 = s[t4]; - // Rcon t1 = t1 ^ rcon[i]; for (var n = 0; n < 4; ++n) { result[j] = (t1 ^= result[j - 16]); j++; @@ -12337,30 +11583,24 @@ var AES128Cipher = (function AES128CipherClosure() { } return result; } - function decrypt128(input, key) { var state = new Uint8Array(16); state.set(input); var i, j, k; var t, u, v; - // AddRoundKey for (j = 0, k = 160; j < 16; ++j, ++k) state[j] ^= key[k]; for (i = 9; i >= 1; --i) { - // InvShiftRows t = state[13]; state[13] = state[9]; state[9] = state[5]; state[5] = state[1]; state[1] = t; t = state[14]; u = state[10]; state[14] = state[6]; state[10] = state[2]; state[6] = t; state[2] = u; t = state[15]; u = state[11]; v = state[7]; state[15] = state[3]; state[11] = t; state[7] = u; state[3] = v; - // InvSubBytes for (j = 0; j < 16; ++j) state[j] = inv_s[state[j]]; - // AddRoundKey for (j = 0, k = i * 16; j < 16; ++j, ++k) state[j] ^= key[k]; - // InvMixColumns for (j = 0; j < 16; j += 4) { var s0 = mix[state[j]], s1 = mix[state[j + 1]], s2 = mix[state[j + 2]], s3 = mix[state[j + 3]]; @@ -12372,7 +11612,6 @@ var AES128Cipher = (function AES128CipherClosure() { state[j + 3] = t & 0xFF; } } - // InvShiftRows t = state[13]; state[13] = state[9]; state[9] = state[5]; state[5] = state[1]; state[1] = t; t = state[14]; u = state[10]; state[14] = state[6]; @@ -12380,20 +11619,16 @@ var AES128Cipher = (function AES128CipherClosure() { t = state[15]; u = state[11]; v = state[7]; state[15] = state[3]; state[11] = t; state[7] = u; state[3] = v; for (j = 0; j < 16; ++j) { - // InvSubBytes state[j] = inv_s[state[j]]; - // AddRoundKey state[j] ^= key[j]; } return state; } - function AES128Cipher(key) { this.key = expandKey128(key); this.buffer = new Uint8Array(16); this.bufferPosition = 0; } - function decryptBlock2(data) { var i, j, ii, sourceLength = data.length, buffer = this.buffer, bufferLength = this.bufferPosition, @@ -12403,9 +11638,7 @@ var AES128Cipher = (function AES128CipherClosure() { ++bufferLength; if (bufferLength < 16) continue; - // buffer is full, decrypting var plain = decrypt128(buffer, this.key); - // xor-ing the IV vector to get plain text for (j = 0; j < 16; ++j) plain[j] ^= iv[j]; iv = buffer; @@ -12413,7 +11646,6 @@ var AES128Cipher = (function AES128CipherClosure() { buffer = new Uint8Array(16); bufferLength = 0; } - // saving incomplete buffer this.buffer = buffer; this.bufferLength = bufferLength; this.iv = iv; @@ -12421,37 +11653,30 @@ var AES128Cipher = (function AES128CipherClosure() { return new Uint8Array([]); if (result.length == 1) return result[0]; - // combining plain text blocks into one var output = new Uint8Array(16 * result.length); for (i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) output.set(result[i], j); return output; } - AES128Cipher.prototype = { decryptBlock: function AES128Cipher_decryptBlock(data) { var i, sourceLength = data.length; var buffer = this.buffer, bufferLength = this.bufferPosition; - // waiting for IV values -- they are at the start of the stream for (i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) buffer[bufferLength] = data[i]; if (bufferLength < 16) { - // need more data this.bufferLength = bufferLength; return new Uint8Array([]); } this.iv = buffer; this.buffer = new Uint8Array(16); this.bufferLength = 0; - // starting decryption this.decryptBlock = decryptBlock2; return this.decryptBlock(data.subarray(16)); } }; - return AES128Cipher; })(); - var CipherTransform = (function CipherTransformClosure() { function CipherTransform(stringCipherConstructor, streamCipherConstructor) { this.stringCipherConstructor = stringCipherConstructor; @@ -12475,14 +11700,12 @@ var CipherTransform = (function CipherTransformClosure() { }; return CipherTransform; })(); - var CipherTransformFactory = (function CipherTransformFactoryClosure() { var defaultPasswordBytes = new Uint8Array([ 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08, 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A]); - function prepareKeyData(fileId, password, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata) { var hashData = new Uint8Array(100), i = 0, j, n; @@ -12495,7 +11718,6 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { while (i < 32) { hashData[i++] = defaultPasswordBytes[j++]; } - // as now the padded password in the hashData[0..i] for (j = 0, n = ownerPassword.length; j < n; ++j) hashData[i++] = ownerPassword[j]; hashData[i++] = flags & 0xFF; @@ -12519,7 +11741,6 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { } var encryptionKey = hash.subarray(0, keyLengthInBytes); var cipher, checkData; - if (revision >= 3) { for (i = 0; i < 32; ++i) hashData[i] = defaultPasswordBytes[i]; @@ -12565,7 +11786,6 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { hash = calculateMD5(hash, 0, hash.length); } } - var cipher, userPassword; if (revision >= 3) { userPassword = ownerPassword; @@ -12582,9 +11802,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { } return userPassword; } - var identityName = new Name('Identity'); - function CipherTransformFactory(dict, fileId, password) { var filter = dict.get('Filter'); if (!isName(filter) || filter.name != 'Standard') @@ -12599,39 +11817,32 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { if (!isInt(keyLength) || keyLength < 40 || (keyLength % 8) != 0) error('invalid key length'); - // prepare keys var ownerPassword = stringToBytes(dict.get('O')); var userPassword = stringToBytes(dict.get('U')); var flags = dict.get('P'); var revision = dict.get('R'); - var encryptMetadata = algorithm == 4 && // meaningful when V is 4 - dict.get('EncryptMetadata') !== false; // makes true as default value + var encryptMetadata = algorithm == 4 && + dict.get('EncryptMetadata') !== false; this.encryptMetadata = encryptMetadata; - var fileIdBytes = stringToBytes(fileId); var passwordBytes; if (password) passwordBytes = stringToBytes(password); - var encryptionKey = prepareKeyData(fileIdBytes, passwordBytes, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata); if (!encryptionKey && !password) { throw new PasswordException('No password given', 'needpassword'); } else if (!encryptionKey && password) { - // Attempting use the password as an owner password var decodedPassword = decodeUserPassword(passwordBytes, ownerPassword, revision, keyLength); encryptionKey = prepareKeyData(fileIdBytes, decodedPassword, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata); } - if (!encryptionKey) throw new PasswordException('Incorrect Password', 'incorrectpassword'); - this.encryptionKey = encryptionKey; - if (algorithm == 4) { this.cf = dict.get('CF'); this.stmf = dict.get('StmF') || identityName; @@ -12639,7 +11850,6 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { this.eff = dict.get('EFF') || this.strf; } } - function buildObjectKey(num, gen, encryptionKey, isAes) { var key = new Uint8Array(encryptionKey.length + 9), i, n; for (i = 0, n = encryptionKey.length; i < n; ++i) @@ -12658,7 +11868,6 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { var hash = calculateMD5(key, 0, i); return hash.subarray(0, Math.min(encryptionKey.length + 5, 16)); } - function buildCipherConstructor(cf, name, num, gen, key) { var cryptFilter = cf.get(name.name); var cfm; @@ -12683,7 +11892,6 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { } error('Unknown crypto method'); } - CipherTransformFactory.prototype = { createCipherTransform: function CipherTransformFactory_createCipherTransform(num, gen) { @@ -12694,7 +11902,6 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { buildCipherConstructor(this.cf, this.strf, num, gen, this.encryptionKey)); } - // algorithms 1 and 2 var key = buildObjectKey(num, gen, this.encryptionKey, false); var cipherConstructor = function buildCipherCipherConstructor() { return new ARCFourCipher(key); @@ -12702,29 +11909,21 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() { return new CipherTransform(cipherConstructor, cipherConstructor); } }; - return CipherTransformFactory; })(); - - /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - 'use strict'; - var PartialEvaluator = (function PartialEvaluatorClosure() { function PartialEvaluator(xref, handler, uniquePrefix) { this.state = new EvalState(); this.stateStack = []; - this.xref = xref; this.handler = handler; this.uniquePrefix = uniquePrefix; this.objIdCounter = 0; } - var OP_MAP = { - // Graphics state w: 'setLineWidth', J: 'setLineCap', j: 'setLineJoin', @@ -12736,8 +11935,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { q: 'save', Q: 'restore', cm: 'transform', - - // Path m: 'moveTo', l: 'lineTo', c: 'curveTo', @@ -12755,12 +11952,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { b: 'closeFillStroke', 'b*': 'closeEOFillStroke', n: 'endPath', - - // Clipping W: 'clip', 'W*': 'eoClip', - - // Text BT: 'beginText', ET: 'endText', Tc: 'setCharSpacing', @@ -12778,12 +11971,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { TJ: 'showSpacedText', "'": 'nextLineShowText', '"': 'nextLineSetSpacingShowText', - - // Type3 fonts d0: 'setCharWidth', d1: 'setCharWidthAndBounds', - - // Color CS: 'setStrokeColorSpace', cs: 'setFillColorSpace', SC: 'setStrokeColor', @@ -12796,30 +11985,18 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { rg: 'setFillRGBColor', K: 'setStrokeCMYKColor', k: 'setFillCMYKColor', - - // Shading sh: 'shadingFill', - - // Images BI: 'beginInlineImage', ID: 'beginImageData', EI: 'endInlineImage', - - // XObjects Do: 'paintXObject', - - // Marked content MP: 'markPoint', DP: 'markPointProps', BMC: 'beginMarkedContent', BDC: 'beginMarkedContentProps', EMC: 'endMarkedContent', - - // Compatibility BX: 'beginCompat', EX: 'endCompat', - - // (reserved partial commands for the lexer) BM: null, BD: null, 'true': null, @@ -12831,18 +12008,15 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { nul: null, 'null': null }; - PartialEvaluator.prototype = { getOperatorList: function PartialEvaluator_getOperatorList(stream, resources, dependency, queue) { - var self = this; var xref = this.xref; var handler = this.handler; var uniquePrefix = this.uniquePrefix || ''; - function insertDependency(depList) { fnArray.push('dependency'); argsArray.push(depList); @@ -12853,38 +12027,27 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { } } } - function handleSetFont(fontName, font) { var loadedName = null; - var fontRes = resources.get('Font'); - assert(fontRes, 'fontRes not available'); - font = xref.fetchIfRef(font) || fontRes.get(fontName); assertWellFormed(isDict(font)); - ++self.objIdCounter; if (!font.loadedName) { font.translated = self.translateFont(font, xref, resources, dependency); if (font.translated) { - // keep track of each font we translated so the caller can - // load them asynchronously before calling display on a page loadedName = 'font_' + uniquePrefix + self.objIdCounter; font.translated.properties.loadedName = loadedName; font.loadedName = loadedName; - var translated = font.translated; - // Convert the file to an ArrayBuffer which will be turned back into - // a Stream in the main thread. if (translated.file) translated.file = translated.file.getBytes(); if (translated.properties.file) { translated.properties.file = translated.properties.file.getBytes(); } - handler.send('obj', [ loadedName, 'Font', @@ -12895,59 +12058,37 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { } } loadedName = loadedName || font.loadedName; - - // Ensure the font is ready before the font is set - // and later on used for drawing. - // OPTIMIZE: This should get insert to the operatorList only once per - // page. insertDependency([loadedName]); return loadedName; } - function buildPaintImageXObject(image, inline) { var dict = image.dict; var w = dict.get('Width', 'W'); var h = dict.get('Height', 'H'); - var imageMask = dict.get('ImageMask', 'IM') || false; if (imageMask) { - // This depends on a tmpCanvas beeing filled with the - // current fillStyle, such that processing the pixel - // data can't be done here. Instead of creating a - // complete PDFImage, only read the information needed - // for later. - var width = dict.get('Width', 'W'); var height = dict.get('Height', 'H'); var bitStrideLength = (width + 7) >> 3; var imgArray = image.getBytes(bitStrideLength * height); var decode = dict.get('Decode', 'D'); var inverseDecode = !!decode && decode[0] > 0; - fn = 'paintImageMaskXObject'; args = [imgArray, inverseDecode, width, height]; return; } - - // If there is no imageMask, create the PDFImage and a lot - // of image processing can be done here. var objId = 'img_' + uniquePrefix + (++self.objIdCounter); insertDependency([objId]); args = [objId, w, h]; - var softMask = dict.get('SMask', 'SM') || false; var mask = dict.get('Mask') || false; - if (!softMask && !mask && image instanceof JpegStream && image.isNativelySupported(xref, resources)) { - // These JPEGs don't need any more processing so we can just send it. fn = 'paintJpegXObject'; handler.send('obj', [objId, 'JpegStream', image.getIR()]); return; } - fn = 'paintImageXObject'; - PDFImage.buildImage(function(imageObj) { var drawWidth = imageObj.drawWidth; var drawHeight = imageObj.drawHeight; @@ -12961,20 +12102,16 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { handler.send('obj', [objId, 'Image', imgData]); }, handler, xref, resources, image, inline); } - if (!queue) queue = {}; - if (!queue.argsArray) { queue.argsArray = []; } if (!queue.fnArray) { queue.fnArray = []; } - var fnArray = queue.fnArray, argsArray = queue.argsArray; var dependencyArray = dependency || []; - resources = resources || new Dict(); var xobjs = resources.get('XObject') || new Dict(); var patterns = resources.get('Pattern') || new Dict(); @@ -12982,38 +12119,26 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var res = resources; var args = [], obj; var TILING_PATTERN = 1, SHADING_PATTERN = 2; - while (true) { obj = parser.getObj(); if (isEOF(obj)) break; - if (isCmd(obj)) { var cmd = obj.cmd; var fn = OP_MAP[cmd]; assertWellFormed(fn, 'Unknown command "' + cmd + '"'); - // TODO figure out how to type-check vararg functions - if ((cmd == 'SCN' || cmd == 'scn') && !args[args.length - 1].code) { - // compile tiling patterns var patternName = args[args.length - 1]; - // SCN/scn applies patterns along with normal colors if (isName(patternName)) { var pattern = patterns.get(patternName.name); if (pattern) { var dict = isStream(pattern) ? pattern.dict : pattern; var typeNum = dict.get('PatternType'); - if (typeNum == TILING_PATTERN) { - // Create an IR of the pattern code. var depIdx = dependencyArray.length; var operatorList = this.getOperatorList(pattern, dict.get('Resources') || resources, dependencyArray); - - // Add the dependencies that are required to execute the - // operatorList. insertDependency(dependencyArray.slice(depIdx)); - args = TilingPattern.getIR(operatorList, dict, args); } else if (typeNum == SHADING_PATTERN) { @@ -13028,39 +12153,25 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { } } } else if (cmd == 'Do' && !args[0].code) { - // eagerly compile XForm objects var name = args[0].name; var xobj = xobjs.get(name); if (xobj) { assertWellFormed(isStream(xobj), 'XObject should be a stream'); - var type = xobj.dict.get('Subtype'); assertWellFormed( isName(type), 'XObject should have a Name subtype' ); - if ('Form' == type.name) { var matrix = xobj.dict.get('Matrix'); var bbox = xobj.dict.get('BBox'); - fnArray.push('paintFormXObjectBegin'); argsArray.push([matrix, bbox]); - - // This adds the operatorList of the xObj to the current queue. var depIdx = dependencyArray.length; - - // Pass in the current `queue` object. That means the `fnArray` - // and the `argsArray` in this scope is reused and new commands - // are added to them. this.getOperatorList(xobj, xobj.dict.get('Resources') || resources, dependencyArray, queue); - - // Add the dependencies that are required to execute the - // operatorList. insertDependency(dependencyArray.slice(depIdx)); - fn = 'paintFormXObjectEnd'; args = []; } else if ('Image' == type.name) { @@ -13069,14 +12180,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { error('Unhandled XObject subtype ' + type.name); } } - } else if (cmd == 'Tf') { // eagerly collect all fonts + } else if (cmd == 'Tf') { args[0] = handleSetFont(args[0].name); } else if (cmd == 'EI') { buildPaintImageXObject(args[0], true); } - switch (fn) { - // Parse the ColorSpace data to a raw format. case 'setFillColorSpace': case 'setStrokeColorSpace': args = [ColorSpace.parseToIR(args[0], xref, resources)]; @@ -13085,11 +12194,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var shadingRes = res.get('Shading'); if (!shadingRes) error('No shading resource found'); - var shading = shadingRes.get(args[0].name); if (!shading) error('No shading object found'); - var shadingFill = Pattern.parseShading(shading, null, xref, res); var patternIR = shadingFill.getIR(); args = [patternIR]; @@ -13098,15 +12205,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { case 'setGState': var dictName = args[0]; var extGState = resources.get('ExtGState'); - if (!isDict(extGState) || !extGState.has(dictName.name)) break; - var gsState = extGState.get(dictName.name); - - // This array holds the converted/processed state data. var gsStateObj = []; - gsState.forEach( function canvasGraphicsSetGStateForEach(key, value) { switch (key) { @@ -13131,17 +12233,13 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { ]); break; case 'BM': - // We support the default so don't trigger the TODO. if (!isName(value) || value.name != 'Normal') TODO('graphic state operator ' + key); break; case 'SMask': - // We support the default so don't trigger the TODO. if (!isName(value) || value.name != 'None') TODO('graphic state operator ' + key); break; - // Only generate info log messages for the following since - // they are unlikey to have a big impact on the rendering. case 'OP': case 'op': case 'OPM': @@ -13156,7 +12254,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { case 'SA': case 'AIS': case 'TK': - // TODO implement these operators. info('graphic state operator ' + key); break; default: @@ -13167,8 +12264,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { ); args = [gsStateObj]; break; - } // switch - + } fnArray.push(fn); argsArray.push(args); args = []; @@ -13177,22 +12273,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { args.push(obj instanceof Dict ? obj.getAll() : obj); } } - return queue; }, - getTextContent: function partialEvaluatorGetIRQueue(stream, resources) { - var self = this; var xref = this.xref; - function handleSetFont(fontName, fontRef) { var fontRes = resources.get('Font'); - - // TODO: TOASK: Is it possible to get here? If so, what does - // args[0].name should be like??? assert(fontRes, 'fontRes not available'); - fontRes = xref.fetchIfRef(fontRes); fontRef = fontRef || fontRes.get(fontName); var font = xref.fetchIfRef(fontRef), tra; @@ -13202,13 +12290,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { } return font; } - resources = xref.fetchIfRef(resources) || new Dict(); - var parser = new Parser(new Lexer(stream), false); var res = resources; var args = [], obj; - var text = ''; var chunk = ''; var font = null; @@ -13225,8 +12310,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { if (typeof items[j] === 'string') { chunk += items[j]; } else if (items[j] < 0) { - // making all negative offsets a space - better to have - // a space in incorrect place than not have them at all chunk += ' '; } } @@ -13240,33 +12323,27 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { case '"': chunk += args[2] + ' '; break; - } // switch + } if (chunk !== '') { text += fontCharsToUnicode(chunk, font.translated.properties); chunk = ''; } - args = []; } else if (obj != null) { assertWellFormed(args.length <= 33, 'Too many arguments'); args.push(obj); } } - return text; }, - extractDataStructures: function partialEvaluatorExtractDataStructures(dict, baseDict, xref, properties) { - // 9.10.2 var toUnicode = dict.get('ToUnicode') || baseDict.get('ToUnicode'); if (toUnicode) properties.toUnicode = this.readToUnicode(toUnicode, xref, properties); - if (properties.composite) { - // CIDSystemInfo helps to match CID to glyphs var cidSystemInfo = dict.get('CIDSystemInfo'); if (isDict(cidSystemInfo)) { properties.cidSystemInfo = { @@ -13275,12 +12352,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { supplement: cidSystemInfo.get('Supplement') }; } - var cidToGidMap = dict.get('CIDToGIDMap'); if (isStream(cidToGidMap)) properties.cidToGidMap = this.readCidToGidMap(cidToGidMap); } - var flags = properties.flags; var differences = []; var baseEncoding = !!(flags & FontFlags.Symbolic) ? @@ -13293,9 +12368,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { if (baseName) baseEncoding = Encodings[baseName.name]; else - hasEncoding = false; // base encoding was not provided - - // Load the differences between the base and original + hasEncoding = false; if (encoding.has('Differences')) { var diffEncoding = encoding.get('Differences'); var index = 0; @@ -13313,12 +12386,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { error('Encoding is not a Name nor a Dict'); } } - properties.differences = differences; properties.baseEncoding = baseEncoding; properties.hasEncoding = hasEncoding; }, - readToUnicode: function PartialEvaluator_readToUnicode(toUnicode, xref, properties) { var cmapObj = toUnicode; @@ -13331,7 +12402,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var tokens = []; var token = ''; var beginArrayToken = {}; - var cmap = cmapObj.getBytes(cmapObj.length); for (var i = 0, ii = cmap.length; i < ii; i++) { var octet = cmap[i]; @@ -13341,7 +12411,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { case 'usecmap': error('usecmap is not implemented'); break; - case 'beginbfchar': case 'beginbfrange': case 'begincidchar': @@ -13349,7 +12418,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { token = ''; tokens = []; break; - case 'endcidrange': case 'endbfrange': for (var j = 0, jj = tokens.length; j < jj; j += 3) { @@ -13357,7 +12425,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var endRange = tokens[j + 1]; var code = tokens[j + 2]; if (code == 0xFFFF) { - // CMap is broken, assuming code == startRange code = startRange; } if (isArray(code)) { @@ -13374,7 +12441,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { } } break; - case 'endcidchar': case 'endbfchar': for (var j = 0, jj = tokens.length; j < jj; j += 2) { @@ -13383,23 +12449,20 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { charToUnicode[index] = code; } break; - case '': break; - default: if (token[0] >= '0' && token[0] <= '9') - token = parseInt(token, 10); // a number + token = parseInt(token, 10); tokens.push(token); token = ''; } switch (octet) { case 0x5B: - // begin list parsing + tokens.push(beginArrayToken); break; case 0x5D: - // collect array items var items = [], item; while (tokens.length && (item = tokens.pop()) != beginArrayToken) @@ -13409,17 +12472,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { } } else if (octet == 0x3E) { if (token.length) { - // Heuristic: guessing chars size by checking numbers sizes - // in the CMap entries. if (token.length == 2 && properties.composite) properties.wideChars = false; - if (token.length <= 4) { - // parsing hex number tokens.push(parseInt(token, 16)); token = ''; } else { - // parsing hex UTF-16BE numbers var str = []; for (var k = 0, kk = token.length; k < kk; k += 4) { var b = parseInt(token.substr(k, 4), 16); @@ -13445,22 +12503,17 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { return charToUnicode; }, readCidToGidMap: function PartialEvaluator_readCidToGidMap(cidToGidStream) { - // Extract the encoding from the CIDToGIDMap var glyphsData = cidToGidStream.getBytes(); - - // Set encoding 0 to later verify the font has an encoding var result = []; for (var j = 0, jj = glyphsData.length; j < jj; j++) { var glyphID = (glyphsData[j++] << 8) | glyphsData[j]; if (glyphID == 0) continue; - var code = j >> 1; result[code] = glyphID; } return result; }, - extractWidths: function PartialEvaluator_extractWidths(dict, xref, descriptor, @@ -13469,7 +12522,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var defaultWidth = 0; if (properties.composite) { defaultWidth = dict.get('DW') || 1000; - var widths = dict.get('W'); if (widths) { var start = 0, end = 0; @@ -13498,21 +12550,17 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { glyphsWidths[j++] = widths[i]; defaultWidth = parseFloat(descriptor.get('MissingWidth')) || 0; } else { - // Trying get the BaseFont metrics (see comment above). var baseFontName = dict.get('BaseFont'); if (isName(baseFontName)) { var metrics = this.getBaseFontMetrics(baseFontName.name); - glyphsWidths = metrics.widths; defaultWidth = metrics.defaultWidth; } } } - properties.defaultWidth = defaultWidth; properties.widths = glyphsWidths; }, - getBaseFontMetrics: function PartialEvaluator_getBaseFontMetrics(name) { var defaultWidth = 0, widths = []; var glyphWidths = Metrics[stdFontMap[name] || name]; @@ -13521,13 +12569,11 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { } else { widths = glyphWidths; } - return { defaultWidth: defaultWidth, widths: widths }; }, - translateFont: function PartialEvaluator_translateFont(dict, xref, resources, @@ -13535,51 +12581,33 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var baseDict = dict; var type = dict.get('Subtype'); assertWellFormed(isName(type), 'invalid font Subtype'); - var composite = false; if (type.name == 'Type0') { - // If font is a composite - // - get the descendant font - // - set the type according to the descendant font - // - get the FontDescriptor from the descendant font var df = dict.get('DescendantFonts'); if (!df) return null; - dict = isArray(df) ? xref.fetchIfRef(df[0]) : df; - type = dict.get('Subtype'); assertWellFormed(isName(type), 'invalid font Subtype'); composite = true; } var maxCharIndex = composite ? 0xFFFF : 0xFF; - var descriptor = dict.get('FontDescriptor'); if (!descriptor) { if (type.name == 'Type3') { - // FontDescriptor is only required for Type3 fonts when the document - // is a tagged pdf. Create a barbebones one to get by. descriptor = new Dict(); descriptor.set('FontName', new Name(type.name)); } else { - // Before PDF 1.5 if the font was one of the base 14 fonts, having a - // FontDescriptor was not required. - // This case is here for compatibility. var baseFontName = dict.get('BaseFont'); if (!isName(baseFontName)) return null; - - // Using base font name as a font name. baseFontName = baseFontName.name.replace(/[,_]/g, '-'); var metrics = this.getBaseFontMetrics(baseFontName); - - // Simulating descriptor flags attribute var fontNameWoStyle = baseFontName.split('-')[0]; var flags = (serifFonts[fontNameWoStyle] || (fontNameWoStyle.search(/serif/gi) != -1) ? FontFlags.Serif : 0) | (symbolsFonts[fontNameWoStyle] ? FontFlags.Symbolic : FontFlags.Nonsymbolic); - var properties = { type: type.name, widths: metrics.widths, @@ -13589,7 +12617,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { lastChar: maxCharIndex }; this.extractDataStructures(dict, dict, xref, properties); - return { name: baseFontName, dict: baseDict, @@ -13597,33 +12624,22 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { }; } } - - // According to the spec if 'FontDescriptor' is declared, 'FirstChar', - // 'LastChar' and 'Widths' should exist too, but some PDF encoders seem - // to ignore this rule when a variant of a standart font is used. - // TODO Fill the width array depending on which of the base font this is - // a variant. var firstChar = dict.get('FirstChar') || 0; var lastChar = dict.get('LastChar') || maxCharIndex; var fontName = descriptor.get('FontName'); - // Some bad pdf's have a string as the font name. if (isString(fontName)) fontName = new Name(fontName); assertWellFormed(isName(fontName), 'invalid font name'); - var fontFile = descriptor.get('FontFile', 'FontFile2', 'FontFile3'); if (fontFile) { if (fontFile.dict) { var subtype = fontFile.dict.get('Subtype'); if (subtype) subtype = subtype.name; - var length1 = fontFile.dict.get('Length1'); - var length2 = fontFile.dict.get('Length2'); } } - var properties = { type: type.name, subtype: subtype, @@ -13647,7 +12663,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { }; this.extractWidths(dict, xref, descriptor, properties); this.extractDataStructures(dict, baseDict, xref, properties); - if (type.name === 'Type3') { properties.coded = true; var charProcs = dict.get('CharProcs').getAll(); @@ -13659,7 +12674,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { this.getOperatorList(glyphStream, fontResources, dependency); } } - return { name: fontName.name, dict: baseDict, @@ -13668,25 +12682,19 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { }; } }; - return PartialEvaluator; })(); - var EvalState = (function EvalStateClosure() { function EvalState() { - // Are soft masks and alpha values shapes or opacities? this.alphaIsShape = false; this.fontSize = 0; this.textMatrix = IDENTITY_MATRIX; this.leading = 0; - // Start of text line (in text coordinates) this.lineX = 0; this.lineY = 0; - // Character and word spacing this.charSpacing = 0; this.wordSpacing = 0; this.textHScale = 1; - // Color spaces this.fillColorSpace = null; this.strokeColorSpace = null; } @@ -13694,30 +12702,15 @@ var EvalState = (function EvalStateClosure() { }; return EvalState; })(); - - /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - 'use strict'; - -/** - * Maximum time to wait for a font to be loaded by font-face rules. - */ var kMaxWaitForFontFace = 1000; - -// Unicode Private Use Area var kCmapGlyphOffset = 0xE000; var kSizeOfGlyphArea = 0x1900; var kSymbolicFontGlyphOffset = 0xF000; - -// PDF Glyph Space Units are one Thousandth of a TextSpace Unit -// except for Type 3 fonts var kPDFGlyphSpaceUnits = 1000; - -// Until hinting is fully supported this constant can be used var kHintingEnabled = false; - var FontFlags = { FixedPitch: 1, Serif: 2, @@ -13729,7 +12722,6 @@ var FontFlags = { SmallCap: 131072, ForceBold: 262144 }; - var Encodings = { ExpertEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', @@ -13966,11 +12958,6 @@ var Encodings = { 'a183', 'a184', 'a197', 'a185', 'a194', 'a198', 'a186', 'a195', 'a187', 'a188', 'a189', 'a190', 'a191'] }; - -/** - * Hold a map of decoded fonts and of the standard fourteen Type1 - * fonts and their acronyms. - */ var stdFontMap = { 'ArialNarrow': 'Helvetica', 'ArialNarrow-Bold': 'Helvetica-Bold', @@ -14021,11 +13008,6 @@ var stdFontMap = { 'TimesNewRomanPSMT-BoldItalic': 'Times-BoldItalic', 'TimesNewRomanPSMT-Italic': 'Times-Italic' }; - -/** - * Holds the map of the non-standard fonts that might be included as a standard - * fonts without glyph data. - */ var nonStdFontMap = { 'ComicSansMS': 'Comic Sans MS', 'ComicSansMS-Bold': 'Comic Sans MS-Bold', @@ -14036,7 +13018,6 @@ var nonStdFontMap = { 'LucidaConsole-BoldItalic': 'Courier-BoldOblique', 'LucidaConsole-Italic': 'Courier-Oblique' }; - var serifFonts = { 'Adobe Jenson': true, 'Adobe Text': true, 'Albertus': true, 'Aldus': true, 'Alexandria': true, 'Algerian': true, @@ -14083,27 +13064,20 @@ var serifFonts = { 'Versailles': true, 'Wanted': true, 'Weiss': true, 'Wide Latin': true, 'Windsor': true, 'XITS': true }; - var symbolsFonts = { 'Dingbats': true, 'Symbol': true, 'ZapfDingbats': true }; - -// Some characters, e.g. copyrightserif, mapped to the private use area and -// might not be displayed using standard fonts. Mapping/hacking well-known chars -// to the similar equivalents in the normal characters range. function mapPrivateUseChars(code) { switch (code) { - case 0xF8E9: // copyrightsans - case 0xF6D9: // copyrightserif - return 0x00A9; // copyright + case 0xF8E9: + case 0xF6D9: + return 0x00A9; default: return code; } } - var FontLoader = { listeningForFontLoad: false, - bind: function fontLoaderBind(fonts, callback) { function checkFontsLoaded() { for (var i = 0, ii = fonts.length; i < ii; i++) { @@ -14112,36 +13086,26 @@ var FontLoader = { return false; } } - document.documentElement.removeEventListener( 'pdfjsFontLoad', checkFontsLoaded, false); - callback(); return true; } - var rules = [], names = [], fontsToLoad = []; var fontCreateTimer = 0; - for (var i = 0, ii = fonts.length; i < ii; i++) { var font = fonts[i]; - - // Add the font to the DOM only once or skip if the font - // is already loaded. if (font.attached || font.loading == false) { continue; } font.attached = true; - fontsToLoad.push(font); - var str = ''; var data = font.data; if (data) { var length = data.length; for (var j = 0; j < length; j++) str += String.fromCharCode(data[j]); - var rule = font.bindDOM(str); if (rule) { rules.push(rule); @@ -14149,56 +13113,21 @@ var FontLoader = { } } } - this.listeningForFontLoad = false; if (!isWorker && rules.length) { FontLoader.prepareFontLoadEvent(rules, names, fontsToLoad); } - if (!checkFontsLoaded()) { document.documentElement.addEventListener( 'pdfjsFontLoad', checkFontsLoaded, false); } }, - // Set things up so that at least one pdfjsFontLoad event is - // dispatched when all the @font-face |rules| for |names| have been - // loaded in a subdocument. It's expected that the load of |rules| - // has already started in this (outer) document, so that they should - // be ordered before the load in the subdocument. prepareFontLoadEvent: function fontLoaderPrepareFontLoadEvent(rules, names, fonts) { - /** Hack begin */ - // There's no event when a font has finished downloading so the - // following code is a dirty hack to 'guess' when a font is - // ready. This code will be obsoleted by Mozilla bug 471915. - // - // The only reliable way to know if a font is loaded in Gecko - // (at the moment) is document.onload in a document with - // a @font-face rule defined in a "static" stylesheet. We use a - // subdocument in an '); {% endif %} {% if filetype == 'Document' %} - var tid= 0; var uuid = ''; var obj_id = ''; function create_session() { @@ -42,9 +41,6 @@ } }); } - function abortTimer () { - clearTimeout(tid); - } function check_status () { $.ajax({ url: '{{ SITE_ROOT }}crocodoc/status/?uuids='+ uuid + '&obj_id=' + obj_id, @@ -53,26 +49,22 @@ contentType: 'application/json; charset=utf-8', success: function(data) { if (data.length > 0) { - var status = data[0]['status'] + var status = data[0]['status']; if (status == 'QUEUED') { $('#file-view').html('

' + '文档转换任务正在排队,请稍后...' + '

'); - tid = setTimeout(check_status, 1000); + setTimeout(check_status, 1000); } else if (status == 'PROCESSING') { $('#file-view').html('

' + '文档正在转换,请稍候...' + '

'); - tid = setTimeout(check_status, 1000); - } else if (status == 'DONE') { - $('#file-view').html('

' + '文档转换成功。正在打开...' + '

'); - abortTimer(); - create_session(); + setTimeout(check_status, 1000); } else { - abortTimer(); + $('#file-view').html('

' + '文档转换成功。正在打开...' + '

'); + create_session(); } } }, error: function(xhr, ajaxOptions, thrownError) { var jsonVal = jQuery.parseJSON(xhr.responseText); $('#file-view').html('

' + jsonVal[0]['error'] + '

'); - abortTimer(); return false; } }); @@ -87,7 +79,7 @@ uuid = data[0]['uuid']; obj_id = data[0]['obj_id']; $('#file-view').html('

文档内容读取成功,开始转换...

'); - tid = setTimeout(check_status, 1000); + check_status(); } }, error: function(xhr, ajaxOptions, thrownError) { @@ -97,6 +89,7 @@ }); {% endif %} {% if filetype == 'PDF' %} + $.ajaxSetup({cache:true}); $.getScript('{{MEDIA_URL}}js/pdf.js', function() { PDFJS.workerSrc = '{{MEDIA_URL}}js/pdf.js'; $('#file-view').html('
加载中...
/
').css({'text-align':'center', 'padding':'3px'});