summaryrefslogtreecommitdiffstats
path: root/apps/files_pdfviewer/js/pdfjs/src/util.js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_pdfviewer/js/pdfjs/src/util.js')
-rw-r--r--[-rwxr-xr-x]apps/files_pdfviewer/js/pdfjs/src/util.js218
1 files changed, 201 insertions, 17 deletions
diff --git a/apps/files_pdfviewer/js/pdfjs/src/util.js b/apps/files_pdfviewer/js/pdfjs/src/util.js
index 4fb96f062a8..de7f3c1d548 100755..100644
--- a/apps/files_pdfviewer/js/pdfjs/src/util.js
+++ b/apps/files_pdfviewer/js/pdfjs/src/util.js
@@ -76,24 +76,102 @@ function stringToBytes(str) {
var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
-var Util = (function utilUtil() {
- function constructor() {}
- constructor.makeCssRgb = function makergb(r, g, b) {
+var 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 + ')';
};
- constructor.makeCssCmyk = function makecmyk(c, m, y, k) {
+
+ 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 + ')';
};
- constructor.applyTransform = function apply(p, m) {
+
+ // 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];
};
- return constructor;
+ // Apply a generic 3d matrix M on a 3-vector v:
+ // | a b c | | X |
+ // | d e f | x | Y |
+ // | g h i | | Z |
+ // M is assumed to be serialized as [a,b,c,d,e,f,g,h,i],
+ // with v as [X,Y,Z]
+ Util.apply3dTransform = function Util_apply3dTransform(m, v) {
+ return [
+ m[0] * v[0] + m[1] * v[1] + m[2] * v[2],
+ m[3] * v[0] + m[4] * v[1] + m[5] * v[2],
+ m[6] * v[0] + m[7] * v[1] + m[8] * v[2]
+ ];
+ }
+
+ // Normalize rectangle rect=[x1, y1, x2, y2] so that (x1,y1) < (x2,y2)
+ // For coordinate systems whose origin lies in the bottom-left, this
+ // means normalization to (BL,TR) ordering. For systems with origin in the
+ // top-left, this means (TL,BR) ordering.
+ Util.normalizeRect = function Util_normalizeRect(rect) {
+ var r = rect.slice(0); // clone rect
+ if (rect[0] > rect[2]) {
+ r[0] = rect[2];
+ r[2] = rect[0];
+ }
+ if (rect[1] > rect[3]) {
+ r[1] = rect[3];
+ r[3] = rect[1];
+ }
+ return r;
+ }
+
+ // Returns a rectangle [x1, y1, x2, y2] corresponding to the
+ // intersection of rect1 and rect2. If no intersection, returns 'false'
+ // The rectangle coordinates of rect1, rect2 should be [x1, y1, x2, y2]
+ Util.intersect = function Util_intersect(rect1, rect2) {
+ function compare(a, b) {
+ return a - b;
+ };
+
+ // Order points along the axes
+ 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);
+
+ // X: first and second points belong to different rectangles?
+ if ((orderedX[0] === rect1[0] && orderedX[1] === rect2[0]) ||
+ (orderedX[0] === rect2[0] && orderedX[1] === rect1[0])) {
+ // Intersection must be between second and third points
+ result[0] = orderedX[1];
+ result[2] = orderedX[2];
+ } else {
+ return false;
+ }
+
+ // Y: first and second points belong to different rectangles?
+ if ((orderedY[0] === rect1[1] && orderedY[1] === rect2[1]) ||
+ (orderedY[0] === rect2[1] && orderedY[1] === rect1[1])) {
+ // Intersection must be between second and third points
+ result[1] = orderedY[1];
+ result[3] = orderedY[2];
+ } else {
+ return false;
+ }
+
+ return result;
+ }
+
+ Util.sign = function Util_sign(num) {
+ return num < 0 ? -1 : 1;
+ };
+
+ return Util;
})();
var PDFStringTranslateTable = [
@@ -197,7 +275,7 @@ function isPDFFunction(v) {
* can be set. If any of these happens twice or the data is required before
* it was set, an exception is throw.
*/
-var Promise = (function promise() {
+var Promise = (function PromiseClosure() {
var EMPTY_PROMISE = {};
/**
@@ -206,6 +284,8 @@ var Promise = (function promise() {
*/
function Promise(name, data) {
this.name = name;
+ this.isRejected = false;
+ this.error = null;
// If you build a promise and pass in some data it's already resolved.
if (data != null) {
this.isResolved = true;
@@ -216,8 +296,35 @@ var Promise = (function promise() {
this._data = EMPTY_PROMISE;
}
this.callbacks = [];
+ this.errbacks = [];
+ };
+ /**
+ * Builds a promise that is resolved when all the passed in promises are
+ * resolved.
+ * @param {Promise[]} promises Array of promises to wait for.
+ * @return {Promise} New dependant promise.
+ */
+ Promise.all = function Promise_all(promises) {
+ var deferred = new Promise();
+ var unresolved = promises.length;
+ var results = [];
+ if (unresolved === 0) {
+ deferred.resolve(results);
+ return deferred;
+ }
+ for (var i = 0; i < unresolved; ++i) {
+ var promise = promises[i];
+ promise.then((function(i) {
+ return function(value) {
+ results[i] = value;
+ unresolved--;
+ if (unresolved === 0)
+ deferred.resolve(results);
+ };
+ })(i));
+ }
+ return deferred;
};
-
Promise.prototype = {
hasData: false,
@@ -226,8 +333,8 @@ var Promise = (function promise() {
return;
}
if (this._data !== EMPTY_PROMISE) {
- throw 'Promise ' + this.name +
- ': Cannot set the data of a promise twice';
+ error('Promise ' + this.name +
+ ': Cannot set the data of a promise twice');
}
this._data = value;
this.hasData = true;
@@ -239,12 +346,12 @@ var Promise = (function promise() {
get data() {
if (this._data === EMPTY_PROMISE) {
- throw 'Promise ' + this.name + ': Cannot get data that isn\'t set';
+ error('Promise ' + this.name + ': Cannot get data that isn\'t set');
}
return this._data;
},
- onData: function promiseOnData(callback) {
+ onData: function Promise_onData(callback) {
if (this._data !== EMPTY_PROMISE) {
callback(this._data);
} else {
@@ -252,13 +359,16 @@ var Promise = (function promise() {
}
},
- resolve: function promiseResolve(data) {
+ resolve: function Promise_resolve(data) {
if (this.isResolved) {
- throw 'A Promise can be resolved only once ' + this.name;
+ error('A Promise can be resolved only once ' + this.name);
+ }
+ if (this.isRejected) {
+ error('The Promise was already rejected ' + this.name);
}
this.isResolved = true;
- this.data = data;
+ this.data = data || null;
var callbacks = this.callbacks;
for (var i = 0, ii = callbacks.length; i < ii; i++) {
@@ -266,17 +376,39 @@ var Promise = (function promise() {
}
},
- then: function promiseThen(callback) {
+ reject: function Promise_reject(reason) {
+ if (this.isRejected) {
+ error('A Promise can be rejected only once ' + this.name);
+ }
+ 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);
+ }
+ },
+
+ then: function Promise_then(callback, errback) {
if (!callback) {
- throw 'Requiring callback' + this.name;
+ 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);
+ } else if (this.isRejected && errback) {
+ var error = this.error;
+ errback.call(null, error);
} else {
this.callbacks.push(callback);
+ if (errback)
+ this.errbacks.push(errback);
}
}
};
@@ -284,3 +416,55 @@ var Promise = (function promise() {
return Promise;
})();
+var StatTimer = (function StatTimerClosure() {
+ function rpad(str, pad, length) {
+ while (str.length < length)
+ str += pad;
+ return str;
+ }
+ function StatTimer() {
+ this.started = {};
+ this.times = [];
+ this.enabled = true;
+ }
+ StatTimer.prototype = {
+ time: function StatTimer_time(name) {
+ if (!this.enabled)
+ return;
+ if (name in this.started)
+ throw 'Timer is already running for ' + name;
+ this.started[name] = Date.now();
+ },
+ timeEnd: function StatTimer_timeEnd(name) {
+ if (!this.enabled)
+ return;
+ if (!(name in this.started))
+ throw 'Timer has not been started for ' + name;
+ this.times.push({
+ 'name': name,
+ 'start': this.started[name],
+ 'end': Date.now()
+ });
+ // Remove timer from started so it can be called again.
+ delete this.started[name];
+ },
+ toString: function StatTimer_toString() {
+ var times = this.times;
+ var out = '';
+ // Find the longest name for padding purposes.
+ var longest = 0;
+ for (var i = 0, ii = times.length; i < ii; ++i) {
+ var name = times[i]['name'];
+ if (name.length > longest)
+ longest = name.length;
+ }
+ for (var i = 0, ii = times.length; i < ii; ++i) {
+ var span = times[i];
+ var duration = span.end - span.start;
+ out += rpad(span['name'], ' ', longest) + ' ' + duration + 'ms\n';
+ }
+ return out;
+ }
+ };
+ return StatTimer;
+})();