From c67037e268bf5d70fd002891e4673cae43eb4d6e Mon Sep 17 00:00:00 2001 From: sbarman Date: Thu, 21 Jul 2011 11:51:39 -0700 Subject: [PATCH 01/16] added ability to write data to file --- fonts.js | 8 ++++++++ utils/fonts_utils.js | 4 +--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/fonts.js b/fonts.js index 77ad85a00..e4a426cbe 100755 --- a/fonts.js +++ b/fonts.js @@ -384,6 +384,14 @@ var Font = (function Font() { break; } + var fileArr = []; + file.reset(); + for (var i = 0, ii = file.length; i < ii; ++i) + fileArr.push(file[i]); + + writeToFile(data, '/tmp/' + name + '_orig'); + writeToFile(fileArr, '/tmp/' + name + '_new'); + this.data = data; this.textMatrix = properties.textMatrix || IDENTITY_MATRIX; this.type = properties.type; diff --git a/utils/fonts_utils.js b/utils/fonts_utils.js index edfc22186..98ea60757 100644 --- a/utils/fonts_utils.js +++ b/utils/fonts_utils.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: */ -'use strict'; - /** * The Type2 reader code below is only used for debugging purpose since Type2 * is only a CharString format and is never used directly as a Font file. @@ -391,7 +389,7 @@ function writeToFile(aBytes, aFilePath) { var stream = Cc['@mozilla.org/network/file-output-stream;1'] .createInstance(Ci.nsIFileOutputStream); - stream.init(file, 0x04 | 0x08 | 0x20, 0x180, 0); + stream.init(file, 0x04 | 0x08 | 0x20, 0666, 0); var bos = Cc['@mozilla.org/binaryoutputstream;1'] .createInstance(Ci.nsIBinaryOutputStream); From dbc6d67ea6fc8d37628d45f34bb67f79e3ecaba8 Mon Sep 17 00:00:00 2001 From: sbarman Date: Thu, 21 Jul 2011 15:13:18 -0700 Subject: [PATCH 02/16] added include to fonts_util.js --- web/viewer.html | 1 + 1 file changed, 1 insertion(+) diff --git a/web/viewer.html b/web/viewer.html index df9604db4..96012d6d8 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -10,6 +10,7 @@ + From 7d5470a7e551c2f6b8383362f73bdff22ddd7fca Mon Sep 17 00:00:00 2001 From: sbarman Date: Thu, 21 Jul 2011 15:13:49 -0700 Subject: [PATCH 03/16] added include to fonts_util.js --- web/viewer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/viewer.html b/web/viewer.html index 96012d6d8..bf708c4ff 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -10,7 +10,7 @@ - + From c4d81646dc558f76e1cac3b06a351314c391cfb7 Mon Sep 17 00:00:00 2001 From: sbarman Date: Thu, 21 Jul 2011 15:18:00 -0700 Subject: [PATCH 04/16] fixed reading from sream --- fonts.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fonts.js b/fonts.js index e4a426cbe..3a52ae83a 100755 --- a/fonts.js +++ b/fonts.js @@ -386,11 +386,12 @@ var Font = (function Font() { var fileArr = []; file.reset(); + file = file.getBytes(); for (var i = 0, ii = file.length; i < ii; ++i) fileArr.push(file[i]); - writeToFile(data, '/tmp/' + name + '_orig'); - writeToFile(fileArr, '/tmp/' + name + '_new'); + writeToFile(data, '/tmp/' + name + '_new'); + writeToFile(fileArr, '/tmp/' + name + '_orig'); this.data = data; this.textMatrix = properties.textMatrix || IDENTITY_MATRIX; From 23d37f98dbdf99ed0a22ba1b7ad4d83ee023931e Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 16 Aug 2011 10:25:02 -0700 Subject: [PATCH 05/16] working on subroutines --- fonts.js | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/fonts.js b/fonts.js index 66d8428e2..e38edef8d 100755 --- a/fonts.js +++ b/fonts.js @@ -1598,6 +1598,17 @@ var Type1Parser = function() { var c = ''; var count = eexecStr.length; for (var i = 0; i < count; i++) { + var getToken = function() { + while(i < count && (eexecStr[i] == ' ' || eexecStr[i] == '\n')) + ++i; + + var t = ''; + while(i < count && !(eexecStr[i] == ' ' || eexecStr[i] == '\n')) + t += eexecStr[i++]; + + return t; + } + var c = eexecStr[i]; if ((glyphsSection || subrsSection) && c == 'R') { @@ -1627,7 +1638,25 @@ var Type1Parser = function() { glyphsSection = true; break; case '/Subrs': - subrsSection = true; + ++i; + var num = parseInt(getToken()); + getToken(); // read in 'array' + for (var j = 0; j < num; ++j) { + var t = getToken(); // read in 'dup' + if (t == 'ND') + break; + var index = parseInt(getToken()); + if (index > j) + j = index; + var length = parseInt(getToken()); + getToken(); // read in 'RD' + var data = eexec.slice(i + 1, i + 1 + length); + var encoded = decrypt(data, kCharStringsEncryptionKey, 4); + var str = decodeCharString(encoded); + i = i + 1 + length; + getToken(); //read in 'NP' + program.subrs[index] = str.charstring; + } break; case '/BlueValues': case '/OtherBlues': @@ -1909,8 +1938,13 @@ CFF.prototype = { for (var i = 0; i < bias; i++) type2Subrs.push([0x0B]); - for (var i = 0; i < count; i++) - type2Subrs.push(this.flattenCharstring(type1Subrs[i], this.commandsMap)); + for (var i = 0; i < count; i++) { + var subr = type1Subrs[i]; + if (!subr) + subr = [0x0B]; + + type2Subrs.push(this.flattenCharstring(subr, this.commandsMap)); + } return type2Subrs; }, From c592d5ed3b8a95a4392996f1222943645553d7ae Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 16 Aug 2011 14:49:12 -0700 Subject: [PATCH 06/16] still mucking with subroutines --- fonts.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fonts.js b/fonts.js index e38edef8d..356d7f948 100755 --- a/fonts.js +++ b/fonts.js @@ -1469,7 +1469,7 @@ var Type1Parser = function() { var value = ''; var count = array.length; for (var i = 0; i < count; i++) { - value = parseInt(array[i]); + value = array[i]; if (value < 32) { var command = null; @@ -1479,8 +1479,8 @@ var Type1Parser = function() { // TODO Clean this code if (escape == 16) { var index = charstring.pop(); - var argc = charstring.pop(); - var data = charstring.pop(); +// var argc = charstring.pop(); +// var data = charstring.pop(); // If the flex mechanishm is not used in a font program, Adobe // state that that entries 0, 1 and 2 can simply be replace by @@ -1492,8 +1492,8 @@ var Type1Parser = function() { // This is the same things about hint replacement, if it is not used // entry 3 can be replaced by {3} if (index == 3) { - charstring.push(3); - i++; +// charstring.push(3); +// i++; continue; } } @@ -1532,11 +1532,11 @@ var Type1Parser = function() { value = command; } else if (value <= 246) { - value = parseInt(value) - 139; + value = value - 139; } else if (value <= 250) { - value = ((value - 247) * 256) + parseInt(array[++i]) + 108; + value = ((value - 247) * 256) + array[++i] + 108; } else if (value <= 254) { - value = -((value - 251) * 256) - parseInt(array[++i]) - 108; + value = -((value - 251) * 256) - array[++i] - 108; } else { value = (array[++i] & 0xff) << 24 | (array[++i] & 0xff) << 16 | (array[++i] & 0xff) << 8 | (array[++i] & 0xff) << 0; From 9f615036d9ff1709e348764bc799a2b8b33fb682 Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 16 Aug 2011 16:14:29 -0700 Subject: [PATCH 07/16] Still testing type1 charstring conversion --- fonts.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fonts.js b/fonts.js index e2f278523..77183a602 100755 --- a/fonts.js +++ b/fonts.js @@ -1488,8 +1488,9 @@ var Type1Parser = function() { // TODO Clean this code if (escape == 16) { var index = charstring.pop(); -// var argc = charstring.pop(); -// var data = charstring.pop(); + var argc = charstring.pop(); + for (var j = 0; j < argc; j++) + var data = charstring.pop(); // If the flex mechanishm is not used in a font program, Adobe // state that that entries 0, 1 and 2 can simply be replace by @@ -1501,8 +1502,8 @@ var Type1Parser = function() { // This is the same things about hint replacement, if it is not used // entry 3 can be replaced by {3} if (index == 3) { -// charstring.push(3); -// i++; + charstring.push(3); + i++; continue; } } From 2ef990059765e71ca2f35c7b6c90bc61e163d9ed Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 16 Aug 2011 16:47:48 -0700 Subject: [PATCH 08/16] implemented curve2, partial fix for #325 --- pdf.js | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/pdf.js b/pdf.js index 79ae776f6..081abfd20 100644 --- a/pdf.js +++ b/pdf.js @@ -4,7 +4,7 @@ 'use strict'; var ERRORS = 0, WARNINGS = 1, TODOS = 5; -var verbosity = WARNINGS; +var verbosity = TODOS; function log(msg) { if (console && console.log) @@ -4137,6 +4137,9 @@ var CanvasExtraState = (function() { this.charSpacing = 0; this.wordSpacing = 0; this.textHScale = 1; + // Path variables + this.pathX = 0; + this.pathY = 0; // Color spaces this.fillColorSpaceObj = null; this.strokeColorSpaceObj = null; @@ -4276,18 +4279,39 @@ var CanvasGraphics = (function() { // Path moveTo: function(x, y) { this.ctx.moveTo(x, y); + + var current = this.current; + current.pathX = x; + current.pathY = y; }, lineTo: function(x, y) { this.ctx.lineTo(x, y); + + var current = this.current; + current.pathX = x; + current.pathY = y; }, curveTo: function(x1, y1, x2, y2, x3, y3) { this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3); + + var current = this.current; + current.pathX = x3; + current.pathY = y3; }, curveTo2: function(x2, y2, x3, y3) { - TODO("'v' operator: need current point in gfx context"); + var current = this.current; + this.ctx.bezierCurveTo(current.pathX, current.pathY, x2, y2, x3, y3); +// TODO("'v' operator: need current point in gfx context"); + + current.pathX = x3; + current.pathY = y3; }, curveTo3: function(x1, y1, x3, y3) { this.curveTo(x1, y1, x3, y3, x3, y3); + + var current = this.current; + current.pathX = x3; + current.pathY = y3; }, closePath: function() { this.ctx.closePath(); From 8351877f1670c8b28f3a45ba4f002e41d4c7dda8 Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 16 Aug 2011 16:49:26 -0700 Subject: [PATCH 09/16] cleanup --- pdf.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pdf.js b/pdf.js index 081abfd20..d9c1007bb 100644 --- a/pdf.js +++ b/pdf.js @@ -4,7 +4,7 @@ 'use strict'; var ERRORS = 0, WARNINGS = 1, TODOS = 5; -var verbosity = TODOS; +var verbosity = WARNINGS; function log(msg) { if (console && console.log) @@ -4301,7 +4301,6 @@ var CanvasGraphics = (function() { curveTo2: function(x2, y2, x3, y3) { var current = this.current; this.ctx.bezierCurveTo(current.pathX, current.pathY, x2, y2, x3, y3); -// TODO("'v' operator: need current point in gfx context"); current.pathX = x3; current.pathY = y3; From 7ae84533c60844aab6584608a4ea30bfc2f27513 Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 16 Aug 2011 18:15:20 -0700 Subject: [PATCH 10/16] added stiched functions --- pdf.js | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/pdf.js b/pdf.js index d9c1007bb..45f5484f6 100644 --- a/pdf.js +++ b/pdf.js @@ -5727,7 +5727,7 @@ var PDFFunction = (function() { if (!typeFn) error('Unknown type of function'); - typeFn.call(this, fn, dict); + typeFn.call(this, fn, dict, xref); }; constructor.prototype = { @@ -5872,9 +5872,58 @@ var PDFFunction = (function() { return out; } }, - constructStiched: function() { - TODO('unhandled type of function'); - this.func = function() { return [255, 105, 180]; } + constructStiched: function(fn, dict, xref) { + var domain = dict.get('Domain'); + var range = dict.get('Range'); + + 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(new PDFFunction(xref, xref.fetchIfRef(fnRefs[i]))); + + var bounds = dict.get('Bounds'); + var encode = dict.get('Encode'); + + this.func = function(args) { + var clip = function(v, min, max) { + if (v > max) + v = max; + else if (v < min) + 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].func([v2]); + } }, constructPostScript: function() { TODO('unhandled type of function'); From a7353ad737ad51593e1a00b7bbefffc39f8cf2fc Mon Sep 17 00:00:00 2001 From: sbarman Date: Wed, 17 Aug 2011 09:22:54 -0700 Subject: [PATCH 11/16] combined pathX/Y with x/y and wrote setCurrentPoint function --- pdf.js | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/pdf.js b/pdf.js index 45f5484f6..2afed5f6b 100644 --- a/pdf.js +++ b/pdf.js @@ -4137,9 +4137,6 @@ var CanvasExtraState = (function() { this.charSpacing = 0; this.wordSpacing = 0; this.textHScale = 1; - // Path variables - this.pathX = 0; - this.pathY = 0; // Color spaces this.fillColorSpaceObj = null; this.strokeColorSpaceObj = null; @@ -4152,7 +4149,11 @@ var CanvasExtraState = (function() { constructor.prototype = { clone: function canvasextra_clone() { return Object.create(this); - } + }, + setCurrentPoint: function canvasextra_setCurrentPoint(x, y) { + this.x = x; + this.y = y; + }, }; return constructor; })(); @@ -4279,38 +4280,24 @@ var CanvasGraphics = (function() { // Path moveTo: function(x, y) { this.ctx.moveTo(x, y); - - var current = this.current; - current.pathX = x; - current.pathY = y; + this.current.setCurrentPoint(x, y); }, lineTo: function(x, y) { this.ctx.lineTo(x, y); - - var current = this.current; - current.pathX = x; - current.pathY = y; + this.current.setCurrentPoint(x, y); }, curveTo: function(x1, y1, x2, y2, x3, y3) { this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3); - - var current = this.current; - current.pathX = x3; - current.pathY = y3; + this.current.setCurrentPoint(x3, y3); }, curveTo2: function(x2, y2, x3, y3) { var current = this.current; - this.ctx.bezierCurveTo(current.pathX, current.pathY, x2, y2, x3, y3); - - current.pathX = x3; - current.pathY = y3; + this.ctx.bezierCurveTo(current.x, current.y, x2, y2, x3, y3); + current.setCurrentPoint(x3, y3); }, curveTo3: function(x1, y1, x3, y3) { this.curveTo(x1, y1, x3, y3, x3, y3); - - var current = this.current; - current.pathX = x3; - current.pathY = y3; + this.current.setCurrentPoint(x3, y3); }, closePath: function() { this.ctx.closePath(); From bd567fc322b60096659035dcd8c00c852249447a Mon Sep 17 00:00:00 2001 From: sbarman Date: Wed, 17 Aug 2011 15:55:09 -0700 Subject: [PATCH 12/16] working font --- fonts.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fonts.js b/fonts.js index 77183a602..a55fc63a2 100755 --- a/fonts.js +++ b/fonts.js @@ -1490,7 +1490,7 @@ var Type1Parser = function() { var index = charstring.pop(); var argc = charstring.pop(); for (var j = 0; j < argc; j++) - var data = charstring.pop(); + charstring.push('drop'); // If the flex mechanishm is not used in a font program, Adobe // state that that entries 0, 1 and 2 can simply be replace by @@ -1976,6 +1976,8 @@ CFF.prototype = { 'sub': [12, 11], 'div': [12, 12], 'pop': [1, 12, 18], +// 'pop': [], + 'drop' : [12, 18], 'endchar': 14, 'rmoveto': 21, 'hmoveto': 22, From 8ff8a92244350d6fac72954957fcaa1426cb29c6 Mon Sep 17 00:00:00 2001 From: sbarman Date: Wed, 17 Aug 2011 16:00:54 -0700 Subject: [PATCH 13/16] Revert "Merge branch 'writeToFile' into hmm" This reverts commit 9b91fca34702e37b7f6d7eb958e8d70f51b2602d, reversing changes made to c592d5ed3b8a95a4392996f1222943645553d7ae. --- fonts.js | 9 --------- utils/fonts_utils.js | 4 +++- web/viewer.html | 1 - 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/fonts.js b/fonts.js index a55fc63a2..a4976b0ac 100755 --- a/fonts.js +++ b/fonts.js @@ -446,15 +446,6 @@ var Font = (function Font() { break; } - var fileArr = []; - file.reset(); - file = file.getBytes(); - for (var i = 0, ii = file.length; i < ii; ++i) - fileArr.push(file[i]); - - writeToFile(data, '/tmp/' + name + '_new'); - writeToFile(fileArr, '/tmp/' + name + '_orig'); - this.data = data; this.type = properties.type; this.textMatrix = properties.textMatrix; diff --git a/utils/fonts_utils.js b/utils/fonts_utils.js index 98ea60757..edfc22186 100644 --- a/utils/fonts_utils.js +++ b/utils/fonts_utils.js @@ -1,6 +1,8 @@ /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ +'use strict'; + /** * The Type2 reader code below is only used for debugging purpose since Type2 * is only a CharString format and is never used directly as a Font file. @@ -389,7 +391,7 @@ function writeToFile(aBytes, aFilePath) { var stream = Cc['@mozilla.org/network/file-output-stream;1'] .createInstance(Ci.nsIFileOutputStream); - stream.init(file, 0x04 | 0x08 | 0x20, 0666, 0); + stream.init(file, 0x04 | 0x08 | 0x20, 0x180, 0); var bos = Cc['@mozilla.org/binaryoutputstream;1'] .createInstance(Ci.nsIBinaryOutputStream); diff --git a/web/viewer.html b/web/viewer.html index 5498d8a1c..285dadb01 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -10,7 +10,6 @@ - From a24ec410ee7ee81ba74eb7700395a5420a1dd28a Mon Sep 17 00:00:00 2001 From: sbarman Date: Wed, 17 Aug 2011 16:04:14 -0700 Subject: [PATCH 14/16] cleanup --- fonts.js | 1 - 1 file changed, 1 deletion(-) diff --git a/fonts.js b/fonts.js index a4976b0ac..1860df2e5 100755 --- a/fonts.js +++ b/fonts.js @@ -1967,7 +1967,6 @@ CFF.prototype = { 'sub': [12, 11], 'div': [12, 12], 'pop': [1, 12, 18], -// 'pop': [], 'drop' : [12, 18], 'endchar': 14, 'rmoveto': 21, From b7ac83da32110de6ea6af123a70a8a25362dec83 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Thu, 18 Aug 2011 07:43:45 -0500 Subject: [PATCH 15/16] LZW reducing memory usage --- pdf.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pdf.js b/pdf.js index 2afed5f6b..eab5a35e2 100644 --- a/pdf.js +++ b/pdf.js @@ -1990,7 +1990,7 @@ var LZWStream = (function() { this.cachedData = 0; this.bitsCached = 0; - var maxLzwDictionarySize = 4097; + var maxLzwDictionarySize = 4096; var lzwState = { earlyChange: earlyChange, codeLength: 9, @@ -2036,6 +2036,9 @@ var LZWStream = (function() { var i, j, q; var lzwState = this.lzwState; + if (!lzwState) + return; // eof was found + var earlyChange = lzwState.earlyChange; var nextCode = lzwState.nextCode; var dictionaryValues = lzwState.dictionaryValues; @@ -2073,6 +2076,7 @@ var LZWStream = (function() { continue; } else { this.eof = true; + delete this.lzwState; break; } From fd0423b5c79c359b69f72175f77651a92d18489f Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Thu, 18 Aug 2011 19:55:14 -0500 Subject: [PATCH 16/16] image load pending --- pdf.js | 92 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 19 deletions(-) diff --git a/pdf.js b/pdf.js index eab5a35e2..34af6521f 100644 --- a/pdf.js +++ b/pdf.js @@ -806,6 +806,11 @@ var JpegStream = (function() { // create DOM image var img = new Image(); + img.onload = (function() { + this.loaded = true; + if (this.onLoad) + this.onLoad(); + }).bind(this); img.src = 'data:image/jpeg;base64,' + window.btoa(bytesToString(bytes)); this.domImage = img; } @@ -822,6 +827,44 @@ var JpegStream = (function() { return constructor; })(); +// Simple object to track the loading images +// Initialy for every that is in loading call imageLoading() +// and, when images onload is fired, call imageLoaded() +// When all images are loaded, the onLoad event is fired. +var ImagesLoader = (function() { + function constructor() { + this.loading = 0; + } + + constructor.prototype = { + imageLoading: function() { + ++this.loading; + }, + + imageLoaded: function() { + if (--this.loading == 0 && this.onLoad) { + this.onLoad(); + delete this.onLoad; + } + }, + + bind: function(jpegStream) { + if (jpegStream.loaded) + return; + this.imageLoading(); + jpegStream.onLoad = this.imageLoaded.bind(this); + }, + + notifyOnLoad: function(callback) { + if (this.loading == 0) + callback(); + this.onLoad = callback; + } + }; + + return constructor; +})(); + var DecryptStream = (function() { function constructor(str, decrypt) { this.str = str; @@ -3127,6 +3170,7 @@ var Page = (function() { create: Date.now(), compile: 0.0, fonts: 0.0, + images: 0.0, render: 0.0 }; this.xref = xref; @@ -3201,25 +3245,33 @@ var Page = (function() { var gfx = new CanvasGraphics(canvasCtx); var fonts = []; + var images = new ImagesLoader() - this.compile(gfx, fonts); + this.compile(gfx, fonts, images); stats.compile = Date.now(); + var displayContinuation = function() { + // Always defer call to display() to work around bug in + // Firefox error reporting from XHR callbacks. + setTimeout(function() { + var exc = null; + try { + self.display(gfx); + stats.render = Date.now(); + } catch (e) { + exc = e.toString(); + } + continuation(exc); + }); + }; + var fontObjs = FontLoader.bind( fonts, function() { stats.fonts = Date.now(); - // Always defer call to display() to work around bug in - // Firefox error reporting from XHR callbacks. - setTimeout(function() { - var exc = null; - try { - self.display(gfx); - stats.render = Date.now(); - } catch (e) { - exc = e.toString(); - } - continuation(exc); + images.notifyOnLoad(function() { + stats.images = Date.now(); + displayContinuation(); }); }); @@ -3228,7 +3280,7 @@ var Page = (function() { }, - compile: function(gfx, fonts) { + compile: function(gfx, fonts, images) { if (this.code) { // content was compiled return; @@ -3240,14 +3292,14 @@ var Page = (function() { if (!IsArray(this.content)) { // content is not an array, shortcut content = xref.fetchIfRef(this.content); - this.code = gfx.compile(content, xref, resources, fonts); + this.code = gfx.compile(content, xref, resources, fonts, images); return; } // the content is an array, compiling all items var i, n = this.content.length, compiledItems = []; for (i = 0; i < n; ++i) { content = xref.fetchIfRef(this.content[i]); - compiledItems.push(gfx.compile(content, xref, resources, fonts)); + compiledItems.push(gfx.compile(content, xref, resources, fonts, images)); } // creating the function that executes all compiled items this.code = function(gfx) { @@ -3787,7 +3839,7 @@ var PartialEvaluator = (function() { }; constructor.prototype = { - eval: function(stream, xref, resources, fonts) { + eval: function(stream, xref, resources, fonts, images) { resources = xref.fetchIfRef(resources) || new Dict(); var xobjs = xref.fetchIfRef(resources.get('XObject')) || new Dict(); var patterns = xref.fetchIfRef(resources.get('Pattern')) || new Dict(); @@ -3832,8 +3884,10 @@ var PartialEvaluator = (function() { if ('Form' == type.name) { args[0].code = this.eval(xobj, xref, xobj.dict.get('Resources'), - fonts); + fonts, images); } + if (xobj instanceof JpegStream) + images.bind(xobj); // monitoring image load } } else if (cmd == 'Tf') { // eagerly collect all fonts var fontRes = resources.get('Font'); @@ -4209,9 +4263,9 @@ var CanvasGraphics = (function() { this.ctx.scale(cw / mediaBox.width, ch / mediaBox.height); }, - compile: function(stream, xref, resources, fonts) { + compile: function(stream, xref, resources, fonts, images) { var pe = new PartialEvaluator(); - return pe.eval(stream, xref, resources, fonts); + return pe.eval(stream, xref, resources, fonts, images); }, execute: function(code, xref, resources) {