[Pkg-javascript-commits] [pdf.js] 23/161: Caches last parsed resource image, recornizes image repeats
David Prévot
taffit at moszumanska.debian.org
Sat Apr 19 14:16:19 UTC 2014
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository pdf.js.
commit f48f57e30a06171ed1ba56fd73fed3e0a864c852
Author: Yury Delendik <ydelendik at mozilla.com>
Date: Mon Feb 24 08:00:08 2014 -0600
Caches last parsed resource image, recornizes image repeats
---
src/core/evaluator.js | 89 ++++++++++++++++++++++++++++++++++++++++++++++++---
src/display/canvas.js | 21 +++++++++++-
src/shared/util.js | 3 +-
3 files changed, 106 insertions(+), 7 deletions(-)
diff --git a/src/core/evaluator.js b/src/core/evaluator.js
index 63c7ad8..d05f1ee 100644
--- a/src/core/evaluator.js
+++ b/src/core/evaluator.js
@@ -124,7 +124,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
},
buildPaintImageXObject: function PartialEvaluator_buildPaintImageXObject(
- resources, image, inline, operatorList) {
+ resources, image, inline, operatorList,
+ cacheKey, cache) {
var self = this;
var dict = image.dict;
var w = dict.get('Width', 'W');
@@ -197,8 +198,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
self.handler.send('obj', [objId, self.pageIndex, 'Image', imgData],
null, [imgData.data.buffer]);
}, self.handler, self.xref, resources, image, inline);
-
operatorList.addOp(OPS.paintImageXObject, args);
+ if (cacheKey) {
+ cache.key = cacheKey;
+ cache.fn = OPS.paintImageXObject;
+ cache.args = args;
+ }
},
handleSMask: function PartialEvaluator_handleSmask(smask, resources,
@@ -452,6 +457,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
var self = this;
var xref = this.xref;
var handler = this.handler;
+ var imageCache = {};
operatorList = operatorList || new OperatorList();
@@ -507,6 +513,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
// eagerly compile XForm objects
var name = args[0].name;
+ if (imageCache.key === name) {
+ operatorList.addOp(imageCache.fn, imageCache.args);
+ args = [];
+ continue;
+ }
+
var xobj = xobjs.get(name);
if (xobj) {
assertWellFormed(
@@ -525,7 +537,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
continue;
} else if ('Image' == type.name) {
self.buildPaintImageXObject(resources, xobj, false,
- operatorList);
+ operatorList, name, imageCache);
args = [];
continue;
} else {
@@ -641,6 +653,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
resources = xref.fetchIfRef(resources) || new Dict();
// The xobj is parsed iff it's needed, e.g. if there is a `DO` cmd.
var xobjs = null;
+ var xobjsCache = {};
var preprocessor = new EvaluatorPreprocessor(stream, xref);
var res = resources;
@@ -735,6 +748,13 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}
var name = args[0].name;
+ if (xobjsCache.key === name) {
+ if (xobjsCache.texts) {
+ Util.concatenateToArray(bidiTexts, xobjsCache.texts);
+ }
+ break;
+ }
+
var xobj = xobjs.get(name);
if (!xobj)
break;
@@ -746,14 +766,19 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
'XObject should have a Name subtype'
);
- if ('Form' !== type.name)
+ if ('Form' !== type.name) {
+ xobjsCache.key = name;
+ xobjsCache.texts = null;
break;
+ }
var formTexts = this.getTextContent(
xobj,
xobj.dict.get('Resources') || resources,
textState
);
+ xobjsCache.key = name;
+ xobjsCache.texts = formTexts;
Util.concatenateToArray(bidiTexts, formTexts);
break;
case OPS.setGState:
@@ -1240,7 +1265,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
})();
var OperatorList = (function OperatorListClosure() {
- var CHUNK_SIZE = 100;
+ var CHUNK_SIZE = 1000;
function getTransfers(queue) {
var transfers = [];
@@ -1777,6 +1802,60 @@ var QueueOptimizer = (function QueueOptimizerClosure() {
});
addState(InitialState,
+ [OPS.save, OPS.transform, OPS.paintImageXObject, OPS.restore],
+ function (context) {
+ var MIN_IMAGES_IN_BLOCK = 3;
+ var MAX_IMAGES_IN_BLOCK = 1000;
+
+ var fnArray = context.fnArray, argsArray = context.argsArray;
+ var j = context.currentOperation - 3, i = j + 4;
+ if (argsArray[j + 1][1] !== 0 || argsArray[j + 1][2] !== 0) {
+ return;
+ }
+ var ii = context.operationsLength;
+ for (; i + 3 < ii && fnArray[i - 4] === fnArray[i]; i += 4) {
+ if (fnArray[i - 3] !== fnArray[i + 1] ||
+ fnArray[i - 2] !== fnArray[i + 2] ||
+ fnArray[i - 1] !== fnArray[i + 3]) {
+ break;
+ }
+ if (argsArray[i - 2][0] !== argsArray[i + 2][0]) {
+ break; // different image
+ }
+ var prevTransformArgs = argsArray[i - 3];
+ var transformArgs = argsArray[i + 1];
+ if (prevTransformArgs[0] !== transformArgs[0] ||
+ prevTransformArgs[1] !== transformArgs[1] ||
+ prevTransformArgs[2] !== transformArgs[2] ||
+ prevTransformArgs[3] !== transformArgs[3]) {
+ break; // different transform
+ }
+ }
+ var count = Math.min((i - j) >> 2, MAX_IMAGES_IN_BLOCK);
+ if (count < MIN_IMAGES_IN_BLOCK) {
+ context.currentOperation = i - 1;
+ return;
+ }
+
+ var positions = new Float32Array(count * 2);
+ i = j + 1;
+ for (var q = 0; q < count; q++) {
+ var transformArgs = argsArray[i];
+ positions[(q << 1)] = transformArgs[4];
+ positions[(q << 1) + 1] = transformArgs[5];
+ i += 4;
+ }
+ var args = [argsArray[j + 2][0], argsArray[j + 1][0],
+ argsArray[j + 1][3], positions];
+ // replacing queue items
+ squash(fnArray, j, count * 4, OPS.paintImageMaskXObjectRepeat);
+ argsArray.splice(j, count * 4, args);
+
+ context.currentOperation = j;
+ context.operationsLength -= count * 4 - 1;
+ });
+
+ addState(InitialState,
[OPS.beginText, OPS.setFont, OPS.setTextMatrix, OPS.showText, OPS.endText],
function (context) {
// moving single chars with same font into beginText/endText groups
diff --git a/src/display/canvas.js b/src/display/canvas.js
index 3942f55..0226b87 100644
--- a/src/display/canvas.js
+++ b/src/display/canvas.js
@@ -1959,12 +1959,31 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
paintImageXObject: function CanvasGraphics_paintImageXObject(objId) {
var imgData = this.objs.get(objId);
- if (!imgData)
+ if (!imgData) {
error('Dependent image isn\'t ready yet');
+ }
this.paintInlineImageXObject(imgData);
},
+ paintImageMaskXObjectRepeat:
+ function CanvasGraphics_paintImageMaskXObjectRepeat(objId, scaleX, scaleY,
+ positions) {
+ var imgData = this.objs.get(objId);
+ if (!imgData) {
+ error('Dependent image isn\'t ready yet');
+ }
+
+ var width = imgData.width;
+ var height = imgData.height;
+ var map = [];
+ for (var i = 0, ii = positions.length; i < ii; i += 2) {
+ map.push({transform: [scaleX, 0, 0, scaleY, positions[i],
+ positions[i + 1]], x: 0, y: 0, w: width, h: height});
+ }
+ this.paintInlineImageXObjectGroup(imgData, map);
+ },
+
paintInlineImageXObject:
function CanvasGraphics_paintInlineImageXObject(imgData) {
var width = imgData.width;
diff --git a/src/shared/util.js b/src/shared/util.js
index 07de8e3..65b07a5 100644
--- a/src/shared/util.js
+++ b/src/shared/util.js
@@ -149,7 +149,8 @@ var OPS = PDFJS.OPS = {
paintImageMaskXObjectGroup: 84,
paintImageXObject: 85,
paintInlineImageXObject: 86,
- paintInlineImageXObjectGroup: 87
+ paintInlineImageXObjectGroup: 87,
+ paintImageMaskXObjectRepeat: 88
};
// A notice for devs. These are good for things that are helpful to devs, such
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/pdf.js.git
More information about the Pkg-javascript-commits
mailing list