pdfjs updated from github

This commit is contained in:
Thomas Müller 2012-04-15 15:59:31 +02:00
parent b3ae2208b1
commit f36d31f74d
39 changed files with 15893 additions and 4836 deletions

10044
apps/files_pdfviewer/js/pdfjs/build/pdf.js Executable file → Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,432 @@
/* -*- 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 bidi = PDFJS.bidi = (function bidiClosure() {
// Character types for symbols from 0000 to 00FF.
var baseTypes = [
'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'S', 'B', 'S', 'WS',
'B', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',
'BN', 'BN', 'B', 'B', 'B', 'S', 'WS', 'ON', 'ON', 'ET', 'ET', 'ET', 'ON',
'ON', 'ON', 'ON', 'ON', 'ON', 'CS', 'ON', 'CS', 'ON', 'EN', 'EN', 'EN',
'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'ON', 'ON', 'ON', 'ON', 'ON',
'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'ON', 'ON',
'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
'L', 'ON', 'ON', 'ON', 'ON', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'B', 'BN',
'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',
'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN',
'BN', 'CS', 'ON', 'ET', 'ET', 'ET', 'ET', 'ON', 'ON', 'ON', 'ON', 'L', 'ON',
'ON', 'ON', 'ON', 'ON', 'ET', 'ET', 'EN', 'EN', 'ON', 'L', 'ON', 'ON', 'ON',
'EN', 'L', 'ON', 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L',
'L', 'L', 'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L'
];
// Character types for symbols from 0600 to 06FF
var arabicTypes = [
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'CS', 'AL', 'ON', 'ON', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM',
'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN',
'AN', 'ET', 'AN', 'AN', 'AL', 'AL', 'AL', 'NSM', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM',
'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'ON', 'NSM',
'NSM', 'NSM', 'NSM', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL',
'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL'
];
function isOdd(i) {
return (i & 1) != 0;
}
function isEven(i) {
return (i & 1) == 0;
}
function findUnequal(arr, start, value) {
var j;
for (var j = start, jj = arr.length; j < jj; ++j) {
if (arr[j] != value)
return j;
}
return j;
}
function setValues(arr, start, end, value) {
for (var j = start; j < end; ++j) {
arr[j] = value;
}
}
function reverseValues(arr, start, end) {
for (var i = start, j = end - 1; i < j; ++i, --j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
function mirrorGlyphs(c) {
/*
# BidiMirroring-1.txt
0028; 0029 # LEFT PARENTHESIS
0029; 0028 # RIGHT PARENTHESIS
003C; 003E # LESS-THAN SIGN
003E; 003C # GREATER-THAN SIGN
005B; 005D # LEFT SQUARE BRACKET
005D; 005B # RIGHT SQUARE BRACKET
007B; 007D # LEFT CURLY BRACKET
007D; 007B # RIGHT CURLY BRACKET
00AB; 00BB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
00BB; 00AB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
*/
switch (c) {
case '(':
return ')';
case ')':
return '(';
case '<':
return '>';
case '>':
return '<';
case ']':
return '[';
case '[':
return ']';
case '}':
return '{';
case '{':
return '}';
case '\u00AB':
return '\u00BB';
case '\u00BB':
return '\u00AB';
default:
return c;
}
}
function bidi(text, startLevel) {
var str = text.str;
var strLength = str.length;
if (strLength == 0)
return str;
// get types, fill arrays
var chars = [];
var types = [];
var oldtypes = [];
var numBidi = 0;
for (var i = 0; i < strLength; ++i) {
chars[i] = str.charAt(i);
var charCode = str.charCodeAt(i);
var charType = 'L';
if (charCode <= 0x00ff)
charType = baseTypes[charCode];
else if (0x0590 <= charCode && charCode <= 0x05f4)
charType = 'R';
else if (0x0600 <= charCode && charCode <= 0x06ff)
charType = arabicTypes[charCode & 0xff];
else if (0x0700 <= charCode && charCode <= 0x08AC)
charType = 'AL';
if (charType == 'R' || charType == 'AL' || charType == 'AN')
numBidi++;
oldtypes[i] = types[i] = charType;
}
// detect the bidi method
// if there are no rtl characters then no bidi needed
// if less than 30% chars are rtl then string is primarily ltr
// if more than 30% chars are rtl then string is primarily rtl
if (numBidi == 0) {
text.direction = 'ltr';
return str;
}
if (startLevel == -1) {
if ((strLength / numBidi) < 0.3) {
text.direction = 'ltr';
startLevel = 0;
} else {
text.direction = 'rtl';
startLevel = 1;
}
}
var levels = [];
for (var i = 0; i < strLength; ++i) {
levels[i] = startLevel;
}
/*
X1-X10: skip most of this, since we are NOT doing the embeddings.
*/
var e = isOdd(startLevel) ? 'R' : 'L';
var sor = e;
var eor = sor;
/*
W1. Examine each non-spacing mark (NSM) in the level run, and change the
type of the NSM to the type of the previous character. If the NSM is at the
start of the level run, it will get the type of sor.
*/
var lastType = sor;
for (var i = 0; i < strLength; ++i) {
if (types[i] == 'NSM')
types[i] = lastType;
else
lastType = types[i];
}
/*
W2. Search backwards from each instance of a European number until the
first strong type (R, L, AL, or sor) is found. If an AL is found, change
the type of the European number to Arabic number.
*/
var lastType = sor;
for (var i = 0; i < strLength; ++i) {
var t = types[i];
if (t == 'EN')
types[i] = (lastType == 'AL') ? 'AN' : 'EN';
else if (t == 'R' || t == 'L' || t == 'AL')
lastType = t;
}
/*
W3. Change all ALs to R.
*/
for (var i = 0; i < strLength; ++i) {
var t = types[i];
if (t == 'AL')
types[i] = 'R';
}
/*
W4. A single European separator between two European numbers changes to a
European number. A single common separator between two numbers of the same
type changes to that type:
*/
for (var i = 1; i < strLength - 1; ++i) {
if (types[i] == 'ES' && types[i - 1] == 'EN' && types[i + 1] == 'EN')
types[i] = 'EN';
if (types[i] == 'CS' && (types[i - 1] == 'EN' || types[i - 1] == 'AN') &&
types[i + 1] == types[i - 1])
types[i] = types[i - 1];
}
/*
W5. A sequence of European terminators adjacent to European numbers changes
to all European numbers:
*/
for (var i = 0; i < strLength; ++i) {
if (types[i] == 'EN') {
// do before
for (var j = i - 1; j >= 0; --j) {
if (types[j] != 'ET')
break;
types[j] = 'EN';
}
// do after
for (var j = i + 1; j < strLength; --j) {
if (types[j] != 'ET')
break;
types[j] = 'EN';
}
}
}
/*
W6. Otherwise, separators and terminators change to Other Neutral:
*/
for (var i = 0; i < strLength; ++i) {
var t = types[i];
if (t == 'WS' || t == 'ES' || t == 'ET' || t == 'CS')
types[i] = 'ON';
}
/*
W7. Search backwards from each instance of a European number until the
first strong type (R, L, or sor) is found. If an L is found, then change
the type of the European number to L.
*/
var lastType = sor;
for (var i = 0; i < strLength; ++i) {
var t = types[i];
if (t == 'EN')
types[i] = (lastType == 'L') ? 'L' : 'EN';
else if (t == 'R' || t == 'L')
lastType = t;
}
/*
N1. A sequence of neutrals takes the direction of the surrounding strong
text if the text on both sides has the same direction. European and Arabic
numbers are treated as though they were R. Start-of-level-run (sor) and
end-of-level-run (eor) are used at level run boundaries.
*/
for (var i = 0; i < strLength; ++i) {
if (types[i] == 'ON') {
var end = findUnequal(types, i + 1, 'ON');
var before = sor;
if (i > 0)
before = types[i - 1];
var after = eor;
if (end + 1 < strLength)
after = types[end + 1];
if (before != 'L')
before = 'R';
if (after != 'L')
after = 'R';
if (before == after)
setValues(types, i, end, before);
i = end - 1; // reset to end (-1 so next iteration is ok)
}
}
/*
N2. Any remaining neutrals take the embedding direction.
*/
for (var i = 0; i < strLength; ++i) {
if (types[i] == 'ON')
types[i] = e;
}
/*
I1. For all characters with an even (left-to-right) embedding direction,
those of type R go up one level and those of type AN or EN go up two
levels.
I2. For all characters with an odd (right-to-left) embedding direction,
those of type L, EN or AN go up one level.
*/
for (var i = 0; i < strLength; ++i) {
var t = types[i];
if (isEven(levels[i])) {
if (t == 'R') {
levels[i] += 1;
} else if (t == 'AN' || t == 'EN') {
levels[i] += 2;
}
} else { // isOdd, so
if (t == 'L' || t == 'AN' || t == 'EN') {
levels[i] += 1;
}
}
}
/*
L1. On each line, reset the embedding level of the following characters to
the paragraph embedding level:
segment separators,
paragraph separators,
any sequence of whitespace characters preceding a segment separator or
paragraph separator, and any sequence of white space characters at the end
of the line.
*/
// don't bother as text is only single line
/*
L2. From the highest level found in the text to the lowest odd level on
each line, reverse any contiguous sequence of characters that are at that
level or higher.
*/
// find highest level & lowest odd level
var highestLevel = -1;
var lowestOddLevel = 99;
for (var i = 0, ii = levels.length; i < ii; ++i) {
var level = levels[i];
if (highestLevel < level)
highestLevel = level;
if (lowestOddLevel > level && isOdd(level))
lowestOddLevel = level;
}
// now reverse between those limits
for (var level = highestLevel; level >= lowestOddLevel; --level) {
// find segments to reverse
var start = -1;
for (var i = 0, ii = levels.length; i < ii; ++i) {
if (levels[i] < level) {
if (start >= 0) {
reverseValues(chars, start, i);
start = -1;
}
} else if (start < 0) {
start = i;
}
}
if (start >= 0) {
reverseValues(chars, start, levels.length);
}
}
/*
L3. Combining marks applied to a right-to-left base character will at this
point precede their base character. If the rendering engine expects them to
follow the base characters in the final display process, then the ordering
of the marks and the base character must be reversed.
*/
// don't bother for now
/*
L4. A character that possesses the mirrored property as specified by
Section 4.7, Mirrored, must be depicted by a mirrored glyph if the resolved
directionality of that character is R.
*/
// don't mirror as characters are already mirrored in the pdf
// Finally, return string
var result = '';
for (var i = 0, ii = chars.length; i < ii; ++i) {
var ch = chars[i];
if (ch != '<' && ch != '>')
result += ch;
}
return result;
}
return bidi;
})();

784
apps/files_pdfviewer/js/pdfjs/src/canvas.js Executable file → Normal file

File diff suppressed because it is too large Load Diff

0
apps/files_pdfviewer/js/pdfjs/src/charsets.js Executable file → Normal file
View File

0
apps/files_pdfviewer/js/pdfjs/src/cidmaps.js Executable file → Normal file
View File

311
apps/files_pdfviewer/js/pdfjs/src/colorspace.js Executable file → Normal file
View File

@ -3,34 +3,34 @@
'use strict';
var ColorSpace = (function colorSpaceColorSpace() {
var ColorSpace = (function ColorSpaceClosure() {
// Constructor should define this.numComps, this.defaultColor, this.name
function constructor() {
function ColorSpace() {
error('should not call ColorSpace constructor');
}
constructor.prototype = {
ColorSpace.prototype = {
// Input: array of size numComps representing color component values
// Output: array of rgb values, each value ranging from [0.1]
getRgb: function colorSpaceGetRgb(color) {
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 colorSpaceGetRgbBuffer(input) {
getRgbBuffer: function ColorSpace_getRgbBuffer(input) {
error('Should not call ColorSpace.getRgbBuffer: ' + input);
}
};
constructor.parse = function colorSpaceParse(cs, xref, res) {
var IR = constructor.parseToIR(cs, xref, res);
ColorSpace.parse = function ColorSpace_parse(cs, xref, res) {
var IR = ColorSpace.parseToIR(cs, xref, res);
if (IR instanceof AlternateCS)
return IR;
return constructor.fromIR(IR);
return ColorSpace.fromIR(IR);
};
constructor.fromIR = function colorSpaceFromIR(IR) {
ColorSpace.fromIR = function ColorSpace_fromIR(IR) {
var name = isArray(IR) ? IR[0] : IR;
switch (name) {
@ -57,15 +57,20 @@ var ColorSpace = (function colorSpaceColorSpace() {
return new AlternateCS(numComps, ColorSpace.fromIR(alt),
PDFFunction.fromIR(tintFnIR));
case 'LabCS':
var whitePoint = IR[1].WhitePoint;
var blackPoint = IR[1].BlackPoint;
var range = IR[1].Range;
return new LabCS(whitePoint, blackPoint, range);
default:
error('Unkown name ' + name);
}
return null;
};
constructor.parseToIR = function colorSpaceParseToIR(cs, xref, res) {
ColorSpace.parseToIR = function ColorSpace_parseToIR(cs, xref, res) {
if (isName(cs)) {
var colorSpaces = xref.fetchIfRef(res.get('ColorSpace'));
var colorSpaces = res.get('ColorSpace');
if (isDict(colorSpaces)) {
var refcs = colorSpaces.get(cs.name);
if (refcs)
@ -130,6 +135,7 @@ var ColorSpace = (function colorSpaceColorSpace() {
basePatternCS = ColorSpace.parseToIR(basePatternCS, xref, res);
return ['PatternCS', basePatternCS];
case 'Indexed':
case 'I':
var baseIndexedCS = ColorSpace.parseToIR(cs[1], xref, res);
var hiVal = cs[2] + 1;
var lookup = xref.fetchIfRef(cs[3]);
@ -146,6 +152,8 @@ var ColorSpace = (function colorSpaceColorSpace() {
var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3]));
return ['AlternateCS', numComps, alt, tintFnIR];
case 'Lab':
var params = cs[1].getAll();
return ['LabCS', params];
default:
error('unimplemented color space object "' + mode + '"');
}
@ -154,8 +162,31 @@ var ColorSpace = (function colorSpaceColorSpace() {
}
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;
return constructor;
if (n * 2 !== decode.length) {
warning('The decode map is not the correct length');
return true;
}
for (var i = 0, ii = decode.length; i < ii; i += 2) {
if (decode[i] != 0 || decode[i + 1] != 1)
return false;
}
return true;
};
return ColorSpace;
})();
/**
@ -164,8 +195,8 @@ var ColorSpace = (function colorSpaceColorSpace() {
* Both color spaces use a tinting function to convert colors to a base color
* space.
*/
var AlternateCS = (function alternateCS() {
function constructor(numComps, base, tintFn) {
var AlternateCS = (function AlternateCSClosure() {
function AlternateCS(numComps, base, tintFn) {
this.name = 'Alternate';
this.numComps = numComps;
this.defaultColor = [];
@ -175,12 +206,12 @@ var AlternateCS = (function alternateCS() {
this.tintFn = tintFn;
}
constructor.prototype = {
getRgb: function altcs_getRgb(color) {
AlternateCS.prototype = {
getRgb: function AlternateCS_getRgb(color) {
var tinted = this.tintFn(color);
return this.base.getRgb(tinted);
},
getRgbBuffer: function altcs_getRgbBuffer(input, bits) {
getRgbBuffer: function AlternateCS_getRgbBuffer(input, bits) {
var tintFn = this.tintFn;
var base = this.base;
var scale = 1 / ((1 << bits) - 1);
@ -189,7 +220,7 @@ var AlternateCS = (function alternateCS() {
var baseNumComps = base.numComps;
var baseBuf = new Uint8Array(baseNumComps * length);
var numComps = this.numComps;
var scaled = new Array(numComps);
var scaled = [];
for (var i = 0; i < length; i += numComps) {
for (var z = 0; z < numComps; ++z)
@ -200,24 +231,27 @@ var AlternateCS = (function alternateCS() {
baseBuf[pos++] = 255 * tinted[j];
}
return base.getRgbBuffer(baseBuf, 8);
},
isDefaultDecode: function AlternateCS_isDefaultDecode(decodeMap) {
return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
}
};
return constructor;
return AlternateCS;
})();
var PatternCS = (function patternCS() {
function constructor(baseCS) {
var PatternCS = (function PatternCSClosure() {
function PatternCS(baseCS) {
this.name = 'Pattern';
this.base = baseCS;
}
constructor.prototype = {};
PatternCS.prototype = {};
return constructor;
return PatternCS;
})();
var IndexedCS = (function indexedCS() {
function constructor(base, highVal, lookup) {
var IndexedCS = (function IndexedCSClosure() {
function IndexedCS(base, highVal, lookup) {
this.name = 'Indexed';
this.numComps = 1;
this.defaultColor = [0];
@ -240,8 +274,8 @@ var IndexedCS = (function indexedCS() {
this.lookup = lookupArray;
}
constructor.prototype = {
getRgb: function indexcs_getRgb(color) {
IndexedCS.prototype = {
getRgb: function IndexedCS_getRgb(color) {
var numComps = this.base.numComps;
var start = color[0] * numComps;
var c = [];
@ -251,7 +285,7 @@ var IndexedCS = (function indexedCS() {
return this.base.getRgb(c);
},
getRgbBuffer: function indexcs_getRgbBuffer(input) {
getRgbBuffer: function IndexedCS_getRgbBuffer(input) {
var base = this.base;
var numComps = base.numComps;
var lookup = this.lookup;
@ -267,24 +301,28 @@ var IndexedCS = (function indexedCS() {
}
return base.getRgbBuffer(baseBuf, 8);
},
isDefaultDecode: function IndexedCS_isDefaultDecode(decodeMap) {
// indexed color maps shouldn't be changed
return true;
}
};
return constructor;
return IndexedCS;
})();
var DeviceGrayCS = (function deviceGrayCS() {
function constructor() {
var DeviceGrayCS = (function DeviceGrayCSClosure() {
function DeviceGrayCS() {
this.name = 'DeviceGray';
this.numComps = 1;
this.defaultColor = [0];
}
constructor.prototype = {
getRgb: function graycs_getRgb(color) {
DeviceGrayCS.prototype = {
getRgb: function DeviceGrayCS_getRgb(color) {
var c = color[0];
return [c, c, c];
},
getRgbBuffer: function graycs_getRgbBuffer(input, bits) {
getRgbBuffer: function DeviceGrayCS_getRgbBuffer(input, bits) {
var scale = 255 / ((1 << bits) - 1);
var length = input.length;
var rgbBuf = new Uint8Array(length * 3);
@ -295,22 +333,25 @@ var DeviceGrayCS = (function deviceGrayCS() {
rgbBuf[j++] = c;
}
return rgbBuf;
},
isDefaultDecode: function DeviceGrayCS_isDefaultDecode(decodeMap) {
return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
}
};
return constructor;
return DeviceGrayCS;
})();
var DeviceRgbCS = (function deviceRgbCS() {
function constructor() {
var DeviceRgbCS = (function DeviceRgbCSClosure() {
function DeviceRgbCS() {
this.name = 'DeviceRGB';
this.numComps = 3;
this.defaultColor = [0, 0, 0];
}
constructor.prototype = {
getRgb: function rgbcs_getRgb(color) {
DeviceRgbCS.prototype = {
getRgb: function DeviceRgbCS_getRgb(color) {
return color;
},
getRgbBuffer: function rgbcs_getRgbBuffer(input, bits) {
getRgbBuffer: function DeviceRgbCS_getRgbBuffer(input, bits) {
if (bits == 8)
return input;
var scale = 255 / ((1 << bits) - 1);
@ -319,73 +360,37 @@ var DeviceRgbCS = (function deviceRgbCS() {
for (i = 0; i < length; ++i)
rgbBuf[i] = (scale * input[i]) | 0;
return rgbBuf;
},
isDefaultDecode: function DeviceRgbCS_isDefaultDecode(decodeMap) {
return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
}
};
return constructor;
return DeviceRgbCS;
})();
var DeviceCmykCS = (function deviceCmykCS() {
function constructor() {
var DeviceCmykCS = (function DeviceCmykCSClosure() {
function DeviceCmykCS() {
this.name = 'DeviceCMYK';
this.numComps = 4;
this.defaultColor = [0, 0, 0, 1];
}
constructor.prototype = {
getRgb: function cmykcs_getRgb(color) {
DeviceCmykCS.prototype = {
getRgb: function DeviceCmykCS_getRgb(color) {
var c = color[0], m = color[1], y = color[2], k = color[3];
var c1 = 1 - c, m1 = 1 - m, y1 = 1 - y, k1 = 1 - k;
var x, r, g, b;
// this is a matrix multiplication, unrolled for performance
// code is taken from the poppler implementation
x = c1 * m1 * y1 * k1; // 0 0 0 0
r = g = b = x;
x = c1 * m1 * y1 * k; // 0 0 0 1
r += 0.1373 * x;
g += 0.1216 * x;
b += 0.1255 * x;
x = c1 * m1 * y * k1; // 0 0 1 0
r += x;
g += 0.9490 * x;
x = c1 * m1 * y * k; // 0 0 1 1
r += 0.1098 * x;
g += 0.1020 * x;
x = c1 * m * y1 * k1; // 0 1 0 0
r += 0.9255 * x;
b += 0.5490 * x;
x = c1 * m * y1 * k; // 0 1 0 1
r += 0.1412 * x;
x = c1 * m * y * k1; // 0 1 1 0
r += 0.9294 * x;
g += 0.1098 * x;
b += 0.1412 * x;
x = c1 * m * y * k; // 0 1 1 1
r += 0.1333 * x;
x = c * m1 * y1 * k1; // 1 0 0 0
g += 0.6784 * x;
b += 0.9373 * x;
x = c * m1 * y1 * k; // 1 0 0 1
g += 0.0588 * x;
b += 0.1412 * x;
x = c * m1 * y * k1; // 1 0 1 0
g += 0.6510 * x;
b += 0.3137 * x;
x = c * m1 * y * k; // 1 0 1 1
g += 0.0745 * x;
x = c * m * y1 * k1; // 1 1 0 0
r += 0.1804 * x;
g += 0.1922 * x;
b += 0.5725 * x;
x = c * m * y1 * k; // 1 1 0 1
b += 0.0078 * x;
x = c * m * y * k1; // 1 1 1 0
r += 0.2118 * x;
g += 0.2119 * x;
b += 0.2235 * x;
// 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 cmykcs_getRgbBuffer(colorBuf, bits) {
getRgbBuffer: function DeviceCmykCS_getRgbBuffer(colorBuf, bits) {
var scale = 1 / ((1 << bits) - 1);
var length = colorBuf.length / 4;
var rgbBuf = new Uint8Array(length * 3);
@ -403,9 +408,125 @@ var DeviceCmykCS = (function deviceCmykCS() {
}
return rgbBuf;
},
isDefaultDecode: function DeviceCmykCS_isDefaultDecode(decodeMap) {
return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
}
};
return constructor;
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];
this.amin = range[0];
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) {
warn('Invalid BlackPoint, falling back to default');
this.XB = this.YB = this.ZB = 0;
}
if (this.amin > this.amax || this.bmin > this.bmax) {
warn('Invalid Range, falling back to defaults');
this.amin = -100;
this.amax = 100;
this.bmin = -100;
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) {
if (bits == 8)
return input;
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)
return true;
else
return false;
}
};
return LabCS;
})();

616
apps/files_pdfviewer/js/pdfjs/src/core.js Executable file → Normal file
View File

@ -5,6 +5,8 @@
var globalScope = (typeof window === 'undefined') ? this : window;
var isWorker = (typeof window == 'undefined');
var ERRORS = 0, WARNINGS = 1, TODOS = 5;
var verbosity = WARNINGS;
@ -31,7 +33,9 @@ function getPdf(arg, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', params.url);
xhr.mozResponseType = xhr.responseType = 'arraybuffer';
xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200;
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;
@ -39,41 +43,43 @@ function getPdf(arg, callback) {
if ('error' in params)
xhr.onerror = params.error || undefined;
xhr.onreadystatechange = function getPdfOnreadystatechange() {
if (xhr.readyState === 4 && xhr.status === xhr.expected) {
var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
xhr.responseArrayBuffer || xhr.response);
callback(data);
xhr.onreadystatechange = function getPdfOnreadystatechange(e) {
if (xhr.readyState === 4) {
if (xhr.status === xhr.expected) {
var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
xhr.responseArrayBuffer || xhr.response);
callback(data);
} else if (params.error) {
params.error(e);
}
}
};
xhr.send(null);
}
globalScope.PDFJS.getPdf = getPdf;
globalScope.PDFJS.pdfBug = false;
var Page = (function pagePage() {
function constructor(xref, pageNumber, pageDict, ref) {
var Page = (function PageClosure() {
function Page(xref, pageNumber, pageDict, ref) {
this.pageNumber = pageNumber;
this.pageDict = pageDict;
this.stats = {
create: Date.now(),
compile: 0.0,
fonts: 0.0,
images: 0.0,
render: 0.0
};
this.stats = new StatTimer();
this.stats.enabled = !!globalScope.PDFJS.enableStats;
this.xref = xref;
this.ref = ref;
this.displayReadyPromise = null;
}
constructor.prototype = {
getPageProp: function pageGetPageProp(key) {
return this.xref.fetchIfRef(this.pageDict.get(key));
Page.prototype = {
getPageProp: function Page_getPageProp(key) {
return this.pageDict.get(key);
},
inheritPageProp: function pageInheritPageProp(key) {
inheritPageProp: function Page_inheritPageProp(key) {
var dict = this.pageDict;
var obj = dict.get(key);
while (obj === undefined) {
dict = this.xref.fetchIfRef(dict.get('Parent'));
dict = dict.get('Parent');
if (!dict)
break;
obj = dict.get(key);
@ -94,23 +100,35 @@ var Page = (function pagePage() {
return shadow(this, 'mediaBox', obj);
},
get view() {
var obj = this.inheritPageProp('CropBox');
var cropBox = this.inheritPageProp('CropBox');
var view = {
x: 0,
y: 0,
width: this.width,
height: this.height
};
if (isArray(obj) && obj.length == 4) {
var tl = this.rotatePoint(obj[0], obj[1]);
var br = this.rotatePoint(obj[2], obj[3]);
view.x = Math.min(tl.x, br.x);
view.y = Math.min(tl.y, br.y);
view.width = Math.abs(tl.x - br.x);
view.height = Math.abs(tl.y - br.y);
}
if (!isArray(cropBox) || cropBox.length !== 4)
return shadow(this, 'view', view);
return shadow(this, 'cropBox', view);
var mediaBox = this.mediaBox;
var offsetX = mediaBox[0], offsetY = mediaBox[1];
// From the spec, 6th ed., p.963:
// "The crop, bleed, trim, and art boxes should not ordinarily
// extend beyond the boundaries of the media box. If they do, they are
// effectively reduced to their intersection with the media box."
cropBox = Util.intersect(cropBox, mediaBox);
if (!cropBox)
return shadow(this, 'view', view);
var tl = this.rotatePoint(cropBox[0] - offsetX, cropBox[1] - offsetY);
var br = this.rotatePoint(cropBox[2] - offsetX, cropBox[3] - offsetY);
view.x = Math.min(tl.x, br.x);
view.y = Math.min(tl.y, br.y);
view.width = Math.abs(tl.x - br.x);
view.height = Math.abs(tl.y - br.y);
return shadow(this, 'view', view);
},
get annotations() {
return shadow(this, 'annotations', this.inheritPageProp('Annots'));
@ -152,77 +170,80 @@ var Page = (function pagePage() {
return shadow(this, 'rotate', rotate);
},
startRenderingFromIRQueue: function pageStartRenderingFromIRQueue(
IRQueue, fonts) {
startRenderingFromOperatorList:
function Page_startRenderingFromOperatorList(operatorList, fonts) {
var self = this;
this.IRQueue = IRQueue;
var gfx = new CanvasGraphics(this.ctx, this.objs);
this.operatorList = operatorList;
var displayContinuation = function pageDisplayContinuation() {
// Always defer call to display() to work around bug in
// Firefox error reporting from XHR callbacks.
setTimeout(function pageSetTimeout() {
try {
self.display(gfx, self.callback);
} catch (e) {
if (self.callback) self.callback(e.toString());
throw e;
}
self.displayReadyPromise.resolve();
});
};
this.ensureFonts(fonts,
function pageStartRenderingFromIRQueueEnsureFonts() {
displayContinuation();
});
function pageStartRenderingFromOperatorListEnsureFonts() {
displayContinuation();
}
);
},
getIRQueue: function pageGetIRQueue(handler, dependency) {
if (this.IRQueue) {
getOperatorList: function Page_getOperatorList(handler, dependency) {
if (this.operatorList) {
// content was compiled
return this.IRQueue;
return this.operatorList;
}
this.stats.time('Build IR Queue');
var xref = this.xref;
var content = xref.fetchIfRef(this.content);
var resources = xref.fetchIfRef(this.resources);
var content = this.content;
var resources = this.resources;
if (isArray(content)) {
// fetching items
var i, n = content.length;
for (i = 0; i < n; ++i)
content[i] = xref.fetchIfRef(content[i]);
content = new StreamsSequenceStream(content);
} 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 + '_');
var IRQueue = {};
return (this.IRQueue = pe.getIRQueue(content, resources, IRQueue,
dependency));
this.operatorList = pe.getOperatorList(content, resources, dependency);
this.stats.timeEnd('Build IR Queue');
return this.operatorList;
},
ensureFonts: function pageEnsureFonts(fonts, callback) {
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
var fontObjs = FontLoader.bind(
FontLoader.bind(
fonts,
function pageEnsureFontsFontObjs(fontObjs) {
this.stats.fonts = Date.now();
this.stats.timeEnd('Font Loading');
callback.call(this);
}.bind(this),
this.objs
}.bind(this)
);
},
display: function pageDisplay(gfx, callback) {
display: function Page_display(gfx, callback) {
var stats = this.stats;
stats.time('Rendering');
var xref = this.xref;
var resources = xref.fetchIfRef(this.resources);
var mediaBox = xref.fetchIfRef(this.mediaBox);
var resources = this.resources;
var mediaBox = this.mediaBox;
assertWellFormed(isDict(resources), 'invalid page resources');
gfx.xref = xref;
@ -233,20 +254,29 @@ var Page = (function pagePage() {
rotate: this.rotate });
var startIdx = 0;
var length = this.IRQueue.fnArray.length;
var IRQueue = this.IRQueue;
var length = this.operatorList.fnArray.length;
var operatorList = this.operatorList;
var stepper = null;
if (PDFJS.pdfBug && StepperManager.enabled) {
stepper = StepperManager.create(this.pageNumber);
stepper.init(operatorList);
stepper.nextBreakPoint = stepper.getNextBreakPoint();
}
var self = this;
function next() {
startIdx = gfx.executeIRQueue(IRQueue, startIdx, next);
startIdx =
gfx.executeOperatorList(operatorList, startIdx, next, stepper);
if (startIdx == length) {
self.stats.render = Date.now();
gfx.endDrawing();
stats.timeEnd('Rendering');
stats.timeEnd('Overall');
if (callback) callback();
}
}
next();
},
rotatePoint: function pageRotatePoint(x, y, reverse) {
rotatePoint: function Page_rotatePoint(x, y, reverse) {
var rotate = reverse ? (360 - this.rotate) : this.rotate;
switch (rotate) {
case 180:
@ -261,58 +291,183 @@ var Page = (function pagePage() {
return {x: x, y: this.height - y};
}
},
getLinks: function pageGetLinks() {
var xref = this.xref;
var annotations = xref.fetchIfRef(this.annotations) || [];
var i, n = annotations.length;
getLinks: function Page_getLinks() {
var links = [];
var annotations = pageGetAnnotations();
var i, n = annotations.length;
for (i = 0; i < n; ++i) {
var annotation = xref.fetch(annotations[i]);
if (annotations[i].type != 'Link')
continue;
links.push(annotations[i]);
}
return links;
},
getAnnotations: function Page_getAnnotations() {
var xref = this.xref;
function getInheritableProperty(annotation, name) {
var item = annotation;
while (item && !item.has(name)) {
item = item.get('Parent');
}
if (!item)
return null;
return item.get(name);
}
function isValidUrl(url) {
if (!url)
return false;
var colon = url.indexOf(':');
if (colon < 0)
return false;
var protocol = url.substr(0, colon);
switch (protocol) {
case 'http':
case 'https':
case 'ftp':
return true;
default:
return false;
}
}
var annotations = this.annotations || [];
var i, n = annotations.length;
var items = [];
for (i = 0; i < n; ++i) {
var annotationRef = annotations[i];
var annotation = xref.fetch(annotationRef);
if (!isDict(annotation))
continue;
var subtype = annotation.get('Subtype');
if (!isName(subtype) || subtype.name != 'Link')
if (!isName(subtype))
continue;
var rect = annotation.get('Rect');
var topLeftCorner = this.rotatePoint(rect[0], rect[1]);
var bottomRightCorner = this.rotatePoint(rect[2], rect[3]);
var link = {};
link.x = Math.min(topLeftCorner.x, bottomRightCorner.x);
link.y = Math.min(topLeftCorner.y, bottomRightCorner.y);
link.width = Math.abs(topLeftCorner.x - bottomRightCorner.x);
link.height = Math.abs(topLeftCorner.y - bottomRightCorner.y);
var a = this.xref.fetchIfRef(annotation.get('A'));
if (a) {
switch (a.get('S').name) {
case 'URI':
link.url = a.get('URI');
var item = {};
item.type = subtype.name;
item.x = Math.min(topLeftCorner.x, bottomRightCorner.x);
item.y = Math.min(topLeftCorner.y, bottomRightCorner.y);
item.width = Math.abs(topLeftCorner.x - bottomRightCorner.x);
item.height = Math.abs(topLeftCorner.y - bottomRightCorner.y);
switch (subtype.name) {
case 'Link':
var a = annotation.get('A');
if (a) {
switch (a.get('S').name) {
case 'URI':
var url = a.get('URI');
// TODO: pdf spec mentions urls can be relative to a Base
// entry in the dictionary.
if (!isValidUrl(url))
url = '';
item.url = url;
break;
case 'GoTo':
item.dest = a.get('D');
break;
default:
TODO('other link types');
}
} else if (annotation.has('Dest')) {
// simple destination link
var dest = annotation.get('Dest');
item.dest = isName(dest) ? dest.name : dest;
}
break;
case 'Widget':
var fieldType = getInheritableProperty(annotation, 'FT');
if (!isName(fieldType))
break;
case 'GoTo':
link.dest = a.get('D');
break;
default:
TODO('other link types');
}
} else if (annotation.has('Dest')) {
// simple destination link
var dest = annotation.get('Dest');
link.dest = isName(dest) ? dest.name : dest;
item.fieldType = fieldType.name;
// Building the full field name by collecting the field and
// its ancestors 'T' properties and joining them using '.'.
var fieldName = [];
var namedItem = annotation, ref = annotationRef;
while (namedItem) {
var parent = namedItem.get('Parent');
var parentRef = namedItem.getRaw('Parent');
var name = namedItem.get('T');
if (name) {
fieldName.unshift(stringToPDFString(name));
} else {
// The field name is absent, that means more than one field
// with the same name may exist. Replacing the empty name
// with the '`' plus index in the parent's 'Kids' array.
// This is not in the PDF spec but necessary to id the
// the input controls.
var kids = parent.get('Kids');
var j, jj;
for (j = 0, jj = kids.length; j < jj; j++) {
var kidRef = kids[j];
if (kidRef.num == ref.num && kidRef.gen == ref.gen)
break;
}
fieldName.unshift('`' + j);
}
namedItem = parent;
ref = parentRef;
}
item.fullName = fieldName.join('.');
var alternativeText = stringToPDFString(annotation.get('TU') || '');
item.alternativeText = alternativeText;
var da = getInheritableProperty(annotation, 'DA') || '';
var m = /([\d\.]+)\sTf/.exec(da);
if (m)
item.fontSize = parseFloat(m[1]);
item.textAlignment = getInheritableProperty(annotation, 'Q');
item.flags = getInheritableProperty(annotation, 'Ff') || 0;
break;
case 'Text':
var content = annotation.get('Contents');
var title = annotation.get('T');
item.content = stringToPDFString(content || '');
item.title = stringToPDFString(title || '');
item.name = annotation.get('Name').name;
break;
default:
TODO('unimplemented annotation type: ' + subtype.name);
break;
}
links.push(link);
items.push(item);
}
return links;
return items;
},
startRendering: function pageStartRendering(ctx, callback) {
this.ctx = ctx;
this.callback = callback;
startRendering: function Page_startRendering(ctx, callback, textLayer) {
var stats = this.stats;
stats.time('Overall');
// If there is no displayReadyPromise yet, then the operatorList was never
// requested before. Make the request and create the promise.
if (!this.displayReadyPromise) {
this.pdf.startRendering(this);
this.displayReadyPromise = new Promise();
}
this.startRenderingTime = Date.now();
this.pdf.startRendering(this);
// Once the operatorList and fonts are loaded, do the actual rendering.
this.displayReadyPromise.then(
function pageDisplayReadyPromise() {
var gfx = new CanvasGraphics(ctx, this.objs, textLayer);
try {
this.display(gfx, callback);
} catch (e) {
if (callback)
callback(e);
else
error(e);
}
}.bind(this),
function pageDisplayReadPromiseError(reason) {
if (callback)
callback(reason);
else
error(reason);
}
);
}
};
return constructor;
return Page;
})();
/**
@ -321,12 +476,9 @@ var Page = (function pagePage() {
* Right now there exists one PDFDocModel on the main thread + one object
* for each worker. If there is no worker support enabled, there are two
* `PDFDocModel` objects on the main thread created.
* TODO: Refactor the internal object structure, such that there is no
* need for the `PDFDocModel` anymore and there is only one object on the
* main thread and not one entire copy on each worker instance.
*/
var PDFDocModel = (function pdfDoc() {
function constructor(arg, callback) {
var PDFDocModel = (function PDFDocModelClosure() {
function PDFDocModel(arg, callback) {
if (isStream(arg))
init.call(this, arg);
else if (isArrayBuffer(arg))
@ -339,6 +491,7 @@ var PDFDocModel = (function pdfDoc() {
assertWellFormed(stream.length > 0, 'stream must have data');
this.stream = stream;
this.setup();
this.acroForm = this.catalog.catDict.get('AcroForm');
}
function find(stream, needle, limit, backwards) {
@ -357,7 +510,7 @@ var PDFDocModel = (function pdfDoc() {
return true; /* found */
}
constructor.prototype = {
PDFDocModel.prototype = {
get linearization() {
var length = this.stream.length;
var linearization = false;
@ -379,12 +532,17 @@ var PDFDocModel = (function pdfDoc() {
if (find(stream, 'endobj', 1024))
startXRef = stream.pos + 6;
} else {
// Find startxref at the end of the file.
var start = stream.end - 1024;
if (start < 0)
start = 0;
stream.pos = start;
if (find(stream, 'startxref', 1024, true)) {
// Find startxref by jumping backward from the end of the file.
var step = 1024;
var found = false, pos = stream.end;
while (!found && pos > 0) {
pos -= step - 'startxref'.length;
if (pos < 0)
pos = 0;
stream.pos = pos;
found = find(stream, 'startxref', step, true);
}
if (found) {
stream.skip(9);
var ch;
do {
@ -413,7 +571,7 @@ var PDFDocModel = (function pdfDoc() {
},
// Find the header, remove leading garbage and setup the stream
// starting from the header.
checkHeader: function pdfDocCheckHeader() {
checkHeader: function PDFDocModel_checkHeader() {
var stream = this.stream;
stream.reset();
if (find(stream, '%PDF-', 1024)) {
@ -423,12 +581,13 @@ var PDFDocModel = (function pdfDoc() {
}
// May not be a PDF file, continue anyway.
},
setup: function pdfDocSetup(ownerPassword, userPassword) {
setup: function PDFDocModel_setup(ownerPassword, userPassword) {
this.checkHeader();
this.xref = new XRef(this.stream,
this.startXRef,
this.mainXRefEntriesOffset);
this.catalog = new Catalog(this.xref);
var xref = new XRef(this.stream,
this.startXRef,
this.mainXRefEntriesOffset);
this.xref = xref;
this.catalog = new Catalog(xref);
},
get numPages() {
var linearization = this.linearization;
@ -436,16 +595,51 @@ var PDFDocModel = (function pdfDoc() {
// shadow the prototype getter
return shadow(this, 'numPages', num);
},
getPage: function pdfDocGetPage(n) {
getDocumentInfo: function PDFDocModel_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 PDFDocModel_getFingerprint() {
var xref = this.xref, fileID;
if (xref.trailer.has('ID')) {
fileID = '';
var id = xref.trailer.get('ID')[0];
id.split('').forEach(function(el) {
fileID += Number(el.charCodeAt(0)).toString(16);
});
} else {
// If we got no fileID, then we generate one,
// from the first 100 bytes of PDF
var data = this.stream.bytes.subarray(0, 100);
var hash = calculateMD5(data, 0, data.length);
fileID = '';
for (var i = 0, length = hash.length; i < length; i++) {
fileID += Number(hash[i]).toString(16);
}
}
return shadow(this, 'getFingerprint', fileID);
},
getPage: function PDFDocModel_getPage(n) {
return this.catalog.getPage(n);
}
};
return constructor;
return PDFDocModel;
})();
var PDFDoc = (function pdfDoc() {
function constructor(arg, callback) {
var PDFDoc = (function PDFDocClosure() {
function PDFDoc(arg, callback) {
var stream = null;
var data = null;
@ -461,9 +655,10 @@ var PDFDoc = (function pdfDoc() {
this.data = data;
this.stream = stream;
this.pdf = new PDFDocModel(stream);
this.catalog = this.pdf.catalog;
this.pdfModel = new PDFDocModel(stream);
this.fingerprint = this.pdfModel.getFingerprint();
this.info = this.pdfModel.getDocumentInfo();
this.catalog = this.pdfModel.catalog;
this.objs = new PDFObjects();
this.pageCache = [];
@ -478,49 +673,59 @@ var PDFDoc = (function pdfDoc() {
if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') {
var workerSrc = PDFJS.workerSrc;
if (typeof workerSrc === 'undefined') {
throw 'No PDFJS.workerSrc specified';
error('No PDFJS.workerSrc specified');
}
var worker;
try {
worker = new Worker(workerSrc);
} catch (e) {
// Some versions of FF can't create a worker on localhost, see:
// https://bugzilla.mozilla.org/show_bug.cgi?id=683280
globalScope.PDFJS.disableWorker = true;
this.setupFakeWorker();
return;
}
var messageHandler = new MessageHandler('main', worker);
// Tell the worker the file it was created from.
messageHandler.send('workerSrc', workerSrc);
messageHandler.on('test', function pdfDocTest(supportTypedArray) {
if (supportTypedArray) {
this.worker = worker;
this.setupMessageHandler(messageHandler);
var worker;
if (PDFJS.isFirefoxExtension) {
// The firefox extension can't load the worker from the resource://
// url so we have to inline the script and then use the blob loader.
var bb = new MozBlobBuilder();
bb.append(document.querySelector('#PDFJS_SCRIPT_TAG').textContent);
var blobUrl = window.URL.createObjectURL(bb.getBlob());
worker = new Worker(blobUrl);
} else {
this.setupFakeWorker();
// Some versions of FF can't create a worker on localhost, see:
// https://bugzilla.mozilla.org/show_bug.cgi?id=683280
worker = new Worker(workerSrc);
}
}.bind(this));
var testObj = new Uint8Array(1);
messageHandler.send('test', testObj);
} else {
this.setupFakeWorker();
var messageHandler = new MessageHandler('main', worker);
messageHandler.on('test', function pdfDocTest(supportTypedArray) {
if (supportTypedArray) {
this.worker = worker;
this.setupMessageHandler(messageHandler);
} else {
globalScope.PDFJS.disableWorker = true;
this.setupFakeWorker();
}
}.bind(this));
var testObj = new Uint8Array(1);
// Some versions of Opera throw a DATA_CLONE_ERR on
// serializing the typed array.
messageHandler.send('test', testObj);
return;
} catch (e) {
warn('The worker has been disabled.');
}
}
// Either workers are disabled, not supported or have thrown an exception.
// Thus, we fallback to a faked worker.
globalScope.PDFJS.disableWorker = true;
this.setupFakeWorker();
}
constructor.prototype = {
setupFakeWorker: function() {
PDFDoc.prototype = {
setupFakeWorker: function PDFDoc_setupFakeWorker() {
// If we don't use a worker, just post/sendMessage to the main thread.
var fakeWorker = {
postMessage: function pdfDocPostMessage(obj) {
postMessage: function PDFDoc_postMessage(obj) {
fakeWorker.onmessage({data: obj});
},
terminate: function pdfDocTerminate() {}
terminate: function PDFDoc_terminate() {}
};
var messageHandler = new MessageHandler('main', fakeWorker);
@ -532,7 +737,7 @@ var PDFDoc = (function pdfDoc() {
},
setupMessageHandler: function(messageHandler) {
setupMessageHandler: function PDFDoc_setupMessageHandler(messageHandler) {
this.messageHandler = messageHandler;
messageHandler.on('page', function pdfDocPage(data) {
@ -540,7 +745,8 @@ var PDFDoc = (function pdfDoc() {
var page = this.pageCache[pageNum];
var depFonts = data.depFonts;
page.startRenderingFromIRQueue(data.IRQueue, depFonts);
page.stats.timeEnd('Page Request');
page.startRenderingFromOperatorList(data.operatorList, depFonts);
}, this);
messageHandler.on('obj', function pdfDocObj(data) {
@ -549,8 +755,12 @@ var PDFDoc = (function pdfDoc() {
switch (type) {
case 'JpegStream':
var IR = data[2];
new JpegImageLoader(id, IR, this.objs);
var imageData = data[2];
loadJpegStream(id, imageData, this.objs);
break;
case 'Image':
var imageData = data[2];
this.objs.resolve(id, imageData);
break;
case 'Font':
var name = data[2];
@ -558,46 +768,63 @@ var PDFDoc = (function pdfDoc() {
var properties = data[4];
if (file) {
// Rewrap the ArrayBuffer in a stream.
var fontFileDict = new Dict();
fontFileDict.map = file.dict.map;
var fontFile = new Stream(file.bytes, file.start,
file.end - file.start, fontFileDict);
// Check if this is a FlateStream. Otherwise just use the created
// Stream one. This makes complex_ttf_font.pdf work.
var cmf = file.bytes[0];
if ((cmf & 0x0f) == 0x08) {
file = new FlateStream(fontFile);
} else {
file = fontFile;
}
file = new Stream(file, 0, file.length, fontFileDict);
}
// For now, resolve the font object here direclty. The real font
// object is then created in FontLoader.bind().
this.objs.resolve(id, {
name: name,
file: file,
properties: properties
});
// At this point, only the font object is created but the font is
// not yet attached to the DOM. This is done in `FontLoader.bind`.
var font = new Font(name, file, properties);
this.objs.resolve(id, font);
break;
default:
throw 'Got unkown object type ' + type;
error('Got unkown object type ' + type);
}
}, this);
messageHandler.on('font_ready', function pdfDocFontReady(data) {
var id = data[0];
var font = new FontShape(data[1]);
messageHandler.on('page_error', function pdfDocError(data) {
var page = this.pageCache[data.pageNum];
if (page.displayReadyPromise)
page.displayReadyPromise.reject(data.error);
else
error(data.error);
}, this);
// If there is no string, then there is nothing to attach to the DOM.
if (!font.str) {
this.objs.resolve(id, font);
} else {
this.objs.setData(id, font);
}
}.bind(this));
messageHandler.on('jpeg_decode', 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;
var height = img.height;
var size = width * height;
var rgbaLength = size * 4;
var buf = new Uint8Array(size * components);
var tmpCanvas = createScratchCanvas(width, height);
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];
buf[j + 1] = data[i + 1];
buf[j + 2] = data[i + 2];
}
} else if (components == 1) {
for (var i = 0, j = 0; i < rgbaLength; i += 4, j++) {
buf[j] = data[i];
}
}
promise.resolve({ data: buf, width: width, height: height});
}).bind(this);
var src = 'data:image/jpeg;base64,' + window.btoa(imageData);
img.src = src;
});
setTimeout(function pdfDocFontReadySetTimeout() {
messageHandler.send('doc', this.data);
@ -606,21 +833,22 @@ var PDFDoc = (function pdfDoc() {
},
get numPages() {
return this.pdf.numPages;
return this.pdfModel.numPages;
},
startRendering: function pdfDocStartRendering(page) {
startRendering: function PDFDoc_startRendering(page) {
// The worker might not be ready to receive the page request yet.
this.workerReadyPromise.then(function pdfDocStartRenderingThen() {
page.stats.time('Page Request');
this.messageHandler.send('page_request', page.pageNumber + 1);
}.bind(this));
},
getPage: function pdfDocGetPage(n) {
getPage: function PDFDoc_getPage(n) {
if (this.pageCache[n])
return this.pageCache[n];
var page = this.pdf.getPage(n);
var page = this.pdfModel.getPage(n);
// Add a reference to the objects such that Page can forward the reference
// to the CanvasGraphics and so on.
page.objs = this.objs;
@ -628,7 +856,7 @@ var PDFDoc = (function pdfDoc() {
return (this.pageCache[n] = page);
},
destroy: function pdfDocDestroy() {
destroy: function PDFDoc_destroy() {
if (this.worker)
this.worker.terminate();
@ -645,7 +873,7 @@ var PDFDoc = (function pdfDoc() {
}
};
return constructor;
return PDFDoc;
})();
globalScope.PDFJS.PDFDoc = PDFDoc;

59
apps/files_pdfviewer/js/pdfjs/src/crypto.js Executable file → Normal file
View File

@ -3,8 +3,8 @@
'use strict';
var ARCFourCipher = (function arcFourCipher() {
function constructor(key) {
var ARCFourCipher = (function ARCFourCipherClosure() {
function ARCFourCipher(key) {
this.a = 0;
this.b = 0;
var s = new Uint8Array(256);
@ -20,8 +20,8 @@ var ARCFourCipher = (function arcFourCipher() {
this.s = s;
}
constructor.prototype = {
encryptBlock: function arcFourCipherEncryptBlock(data) {
ARCFourCipher.prototype = {
encryptBlock: function ARCFourCipher_encryptBlock(data) {
var i, n = data.length, tmp, tmp2;
var a = this.a, b = this.b, s = this.s;
var output = new Uint8Array(n);
@ -39,12 +39,12 @@ var ARCFourCipher = (function arcFourCipher() {
return output;
}
};
constructor.prototype.decryptBlock = constructor.prototype.encryptBlock;
ARCFourCipher.prototype.decryptBlock = ARCFourCipher.prototype.encryptBlock;
return constructor;
return ARCFourCipher;
})();
var calculateMD5 = (function calculateMD5() {
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,
@ -128,20 +128,20 @@ var calculateMD5 = (function calculateMD5() {
return hash;
})();
var NullCipher = (function nullCipher() {
function constructor() {
var NullCipher = (function NullCipherClosure() {
function NullCipher() {
}
constructor.prototype = {
decryptBlock: function nullCipherDecryptBlock(data) {
NullCipher.prototype = {
decryptBlock: function NullCipher_decryptBlock(data) {
return data;
}
};
return constructor;
return NullCipher;
})();
var AES128Cipher = (function aes128Cipher() {
var AES128Cipher = (function AES128CipherClosure() {
var rcon = new Uint8Array([
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c,
0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a,
@ -330,7 +330,7 @@ var AES128Cipher = (function aes128Cipher() {
return state;
}
function constructor(key) {
function AES128Cipher(key) {
this.key = expandKey128(key);
this.buffer = new Uint8Array(16);
this.bufferPosition = 0;
@ -370,8 +370,8 @@ var AES128Cipher = (function aes128Cipher() {
return output;
}
constructor.prototype = {
decryptBlock: function aes128CipherDecryptBlock(data) {
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
@ -391,16 +391,16 @@ var AES128Cipher = (function aes128Cipher() {
}
};
return constructor;
return AES128Cipher;
})();
var CipherTransform = (function cipherTransform() {
function constructor(stringCipherConstructor, streamCipherConstructor) {
var CipherTransform = (function CipherTransformClosure() {
function CipherTransform(stringCipherConstructor, streamCipherConstructor) {
this.stringCipherConstructor = stringCipherConstructor;
this.streamCipherConstructor = streamCipherConstructor;
}
constructor.prototype = {
createStream: function cipherTransformCreateStream(stream) {
CipherTransform.prototype = {
createStream: function CipherTransform_createStream(stream) {
var cipher = new this.streamCipherConstructor();
return new DecryptStream(stream,
function cipherTransformDecryptStream(data) {
@ -408,17 +408,17 @@ var CipherTransform = (function cipherTransform() {
}
);
},
decryptString: function cipherTransformDecryptString(s) {
decryptString: function CipherTransform_decryptString(s) {
var cipher = new this.stringCipherConstructor();
var data = stringToBytes(s);
data = cipher.decryptBlock(data);
return bytesToString(data);
}
};
return constructor;
return CipherTransform;
})();
var CipherTransformFactory = (function cipherTransformFactory() {
var CipherTransformFactory = (function CipherTransformFactoryClosure() {
function prepareKeyData(fileId, password, ownerPassword, userPassword,
flags, revision, keyLength, encryptMetadata) {
var defaultPasswordBytes = new Uint8Array([
@ -490,7 +490,7 @@ var CipherTransformFactory = (function cipherTransformFactory() {
var identityName = new Name('Identity');
function constructor(dict, fileId, password) {
function CipherTransformFactory(dict, fileId, password) {
var filter = dict.get('Filter');
if (!isName(filter) || filter.name != 'Standard')
error('unknown encryption method');
@ -570,12 +570,11 @@ var CipherTransformFactory = (function cipherTransformFactory() {
};
}
error('Unknown crypto method');
return null;
}
constructor.prototype = {
createCipherTransform: function buildCipherCreateCipherTransform(num,
gen) {
CipherTransformFactory.prototype = {
createCipherTransform:
function CipherTransformFactory_createCipherTransform(num, gen) {
if (this.algorithm == 4) {
return new CipherTransform(
buildCipherConstructor(this.cf, this.stmf,
@ -592,6 +591,6 @@ var CipherTransformFactory = (function cipherTransformFactory() {
}
};
return constructor;
return CipherTransformFactory;
})();

365
apps/files_pdfviewer/js/pdfjs/src/evaluator.js Executable file → Normal file
View File

@ -3,8 +3,8 @@
'use strict';
var PartialEvaluator = (function partialEvaluator() {
function constructor(xref, handler, uniquePrefix) {
var PartialEvaluator = (function PartialEvaluatorClosure() {
function PartialEvaluator(xref, handler, uniquePrefix) {
this.state = new EvalState();
this.stateStack = [];
@ -111,14 +111,27 @@ var PartialEvaluator = (function partialEvaluator() {
EX: 'endCompat'
};
constructor.prototype = {
getIRQueue: function partialEvaluatorGetIRQueue(stream, resources,
queue, dependency) {
function splitCombinedOperations(operations) {
// Two operations can be combined together, trying to find which two
// operations were concatenated.
for (var i = operations.length - 1; i > 0; i--) {
var op1 = operations.substring(0, i), op2 = operations.substring(i);
if (op1 in OP_MAP && op2 in OP_MAP)
return [op1, op2]; // operations found
}
return 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;
var uniquePrefix = this.uniquePrefix || '';
function insertDependency(depList) {
fnArray.push('dependency');
@ -131,18 +144,14 @@ var PartialEvaluator = (function partialEvaluator() {
}
}
function handleSetFont(fontName, fontRef) {
function handleSetFont(fontName, font) {
var loadedName = null;
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);
font = xref.fetchIfRef(font) || fontRes.get(fontName);
assertWellFormed(isDict(font));
if (!font.translated) {
font.translated = self.translateFont(font, xref, resources,
@ -155,6 +164,15 @@ var PartialEvaluator = (function partialEvaluator() {
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',
@ -168,7 +186,7 @@ var PartialEvaluator = (function partialEvaluator() {
// Ensure the font is ready before the font is set
// and later on used for drawing.
// TODO: This should get insert to the IRQueue only once per
// OPTIMIZE: This should get insert to the operatorList only once per
// page.
insertDependency([loadedName]);
return loadedName;
@ -179,65 +197,60 @@ var PartialEvaluator = (function partialEvaluator() {
var w = dict.get('Width', 'W');
var h = dict.get('Height', 'H');
if (image instanceof JpegStream && image.isNative) {
var objId = 'img_' + uniquePrefix + (++self.objIdCounter);
handler.send('obj', [objId, 'JpegStream', image.getIR()]);
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.
// Add the dependency on the image object.
insertDependency([objId]);
// The normal fn.
fn = 'paintJpegXObject';
args = [objId, w, h];
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;
}
// Needs to be rendered ourself.
// Figure out if the image has an imageMask.
var imageMask = dict.get('ImageMask', 'IM') || false;
// If there is no imageMask, create the PDFImage and a lot
// of image processing can be done here.
if (!imageMask) {
var imageObj = new PDFImage(xref, resources, image, inline);
var objId = 'img_' + uniquePrefix + (++self.objIdCounter);
insertDependency([objId]);
args = [objId, w, h];
if (imageObj.imageMask) {
throw 'Can\'t handle this in the web worker :/';
}
var imgData = {
width: w,
height: h,
data: new Uint8Array(w * h * 4)
};
var pixels = imgData.data;
imageObj.fillRgbaBuffer(pixels, imageObj.decode);
fn = 'paintImageXObject';
args = [imgData];
var softMask = dict.get('SMask', 'IM') || false;
if (!softMask && 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;
}
// 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.
fn = 'paintImageMaskXObject';
fn = 'paintImageXObject';
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;
args = [imgArray, inverseDecode, width, height];
PDFImage.buildImage(function(imageObj) {
var drawWidth = imageObj.drawWidth;
var drawHeight = imageObj.drawHeight;
var imgData = {
width: drawWidth,
height: drawHeight,
data: new Uint8Array(drawWidth * drawHeight * 4)
};
var pixels = imgData.data;
imageObj.fillRgbaBuffer(pixels, drawWidth, drawHeight);
handler.send('obj', [objId, 'Image', imgData]);
}, handler, xref, resources, image, inline);
}
uniquePrefix = uniquePrefix || '';
if (!queue)
queue = {};
if (!queue.argsArray) {
queue.argsArray = [];
}
@ -248,45 +261,48 @@ var PartialEvaluator = (function partialEvaluator() {
var fnArray = queue.fnArray, argsArray = queue.argsArray;
var dependencyArray = dependency || [];
resources = xref.fetchIfRef(resources) || new Dict();
var xobjs = xref.fetchIfRef(resources.get('XObject')) || new Dict();
var patterns = xref.fetchIfRef(resources.get('Pattern')) || new Dict();
var parser = new Parser(new Lexer(stream), false);
resources = resources || new Dict();
var xobjs = resources.get('XObject') || new Dict();
var patterns = resources.get('Pattern') || new Dict();
var parser = new Parser(new Lexer(stream), false, xref);
var res = resources;
var hasNextObj = false, nextObj;
var args = [], obj;
var getObjBt = function getObjBt() {
parser = this.oldParser;
return { name: 'BT' };
};
var TILING_PATTERN = 1, SHADING_PATTERN = 2;
while (!isEOF(obj = parser.getObj())) {
while (true) {
if (hasNextObj) {
obj = nextObj;
hasNextObj = false;
} else {
obj = parser.getObj();
if (isEOF(obj))
break;
}
if (isCmd(obj)) {
var cmd = obj.cmd;
var fn = OP_MAP[cmd];
if (!fn) {
// invalid content command, trying to recover
if (cmd.substr(-2) == 'BT') {
fn = OP_MAP[cmd.substr(0, cmd.length - 2)];
// feeding 'BT' on next interation
parser = {
getObj: getObjBt,
oldParser: parser
};
var cmds = splitCombinedOperations(cmd);
if (cmds) {
cmd = cmds[0];
fn = OP_MAP[cmd];
// feeding other command on the next interation
hasNextObj = true;
nextObj = Cmd.get(cmds[1]);
}
}
assertWellFormed(fn, 'Unknown command "' + cmd + '"');
// TODO figure out how to type-check vararg functions
if ((cmd == 'SCN' || cmd == 'scn') && !args[args.length - 1].code) {
// Use the IR version for setStroke/FillColorN.
fn += '_IR';
// compile tiling patterns
var patternName = args[args.length - 1];
// SCN/scn applies patterns along with normal colors
if (isName(patternName)) {
var pattern = xref.fetchIfRef(patterns.get(patternName.name));
var pattern = patterns.get(patternName.name);
if (pattern) {
var dict = isStream(pattern) ? pattern.dict : pattern;
var typeNum = dict.get('PatternType');
@ -294,21 +310,20 @@ var PartialEvaluator = (function partialEvaluator() {
if (typeNum == TILING_PATTERN) {
// Create an IR of the pattern code.
var depIdx = dependencyArray.length;
var queueObj = {};
var codeIR = this.getIRQueue(pattern, dict.get('Resources'),
queueObj, dependencyArray);
var operatorList = this.getOperatorList(pattern,
dict.get('Resources') || resources, dependencyArray);
// Add the dependencies that are required to execute the
// codeIR.
// operatorList.
insertDependency(dependencyArray.slice(depIdx));
args = TilingPattern.getIR(codeIR, dict, args);
args = TilingPattern.getIR(operatorList, dict, args);
}
else if (typeNum == SHADING_PATTERN) {
var shading = xref.fetchIfRef(dict.get('Shading'));
var shading = dict.get('Shading');
var matrix = dict.get('Matrix');
var pattern = Pattern.parseShading(shading, matrix, xref, res,
null /*ctx*/);
var pattern = Pattern.parseShading(shading, matrix, xref,
res);
args = pattern.getIR();
} else {
error('Unkown PatternType ' + typeNum);
@ -320,7 +335,6 @@ var PartialEvaluator = (function partialEvaluator() {
var name = args[0].name;
var xobj = xobjs.get(name);
if (xobj) {
xobj = xref.fetchIfRef(xobj);
assertWellFormed(isStream(xobj), 'XObject should be a stream');
var type = xobj.dict.get('Subtype');
@ -336,14 +350,18 @@ var PartialEvaluator = (function partialEvaluator() {
fnArray.push('paintFormXObjectBegin');
argsArray.push([matrix, bbox]);
// This adds the IRQueue of the xObj to the current queue.
// This adds the operatorList of the xObj to the current queue.
var depIdx = dependencyArray.length;
this.getIRQueue(xobj, xobj.dict.get('Resources'), queue,
dependencyArray);
// 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
// codeIR.
// operatorList.
insertDependency(dependencyArray.slice(depIdx));
fn = 'paintFormXObjectEnd';
@ -367,28 +385,27 @@ var PartialEvaluator = (function partialEvaluator() {
args = [ColorSpace.parseToIR(args[0], xref, resources)];
break;
case 'shadingFill':
var shadingRes = xref.fetchIfRef(res.get('Shading'));
var shadingRes = res.get('Shading');
if (!shadingRes)
error('No shading resource found');
var shading = xref.fetchIfRef(shadingRes.get(args[0].name));
var shading = shadingRes.get(args[0].name);
if (!shading)
error('No shading object found');
var shadingFill = Pattern.parseShading(shading, null, xref, res,
null);
var shadingFill = Pattern.parseShading(shading, null, xref, res);
var patternIR = shadingFill.getIR();
args = [patternIR];
fn = 'shadingFill';
break;
case 'setGState':
var dictName = args[0];
var extGState = xref.fetchIfRef(resources.get('ExtGState'));
var extGState = resources.get('ExtGState');
if (!isDict(extGState) || !extGState.has(dictName.name))
break;
var gsState = xref.fetchIfRef(extGState.get(dictName.name));
var gsState = extGState.get(dictName.name);
// This array holds the converted/processed state data.
var gsStateObj = [];
@ -453,10 +470,7 @@ var PartialEvaluator = (function partialEvaluator() {
}
}
return {
fnArray: fnArray,
argsArray: argsArray
};
return queue;
},
extractDataStructures: function
@ -470,7 +484,7 @@ var PartialEvaluator = (function partialEvaluator() {
if (properties.composite) {
// CIDSystemInfo helps to match CID to glyphs
var cidSystemInfo = xref.fetchIfRef(dict.get('CIDSystemInfo'));
var cidSystemInfo = dict.get('CIDSystemInfo');
if (isDict(cidSystemInfo)) {
properties.cidSystemInfo = {
registry: cidSystemInfo.get('Registry'),
@ -479,20 +493,24 @@ var PartialEvaluator = (function partialEvaluator() {
};
}
var cidToGidMap = xref.fetchIfRef(dict.get('CIDToGIDMap'));
var cidToGidMap = dict.get('CIDToGIDMap');
if (isStream(cidToGidMap))
properties.cidToGidMap = this.readCidToGidMap(cidToGidMap);
}
var flags = properties.flags;
var differences = [];
var baseEncoding = Encodings.StandardEncoding;
var baseEncoding = !!(flags & FontFlags.Symbolic) ?
Encodings.symbolsEncoding : Encodings.StandardEncoding;
var hasEncoding = dict.has('Encoding');
if (hasEncoding) {
var encoding = xref.fetchIfRef(dict.get('Encoding'));
var encoding = dict.get('Encoding');
if (isDict(encoding)) {
var baseName = encoding.get('BaseEncoding');
if (baseName)
baseEncoding = Encodings[baseName.name];
else
hasEncoding = false; // base encoding was not provided
// Load the differences between the base and original
if (encoding.has('Differences')) {
@ -512,14 +530,14 @@ var PartialEvaluator = (function partialEvaluator() {
error('Encoding is not a Name nor a Dict');
}
}
properties.differences = differences;
properties.baseEncoding = baseEncoding;
properties.hasEncoding = hasEncoding;
},
readToUnicode:
function partialEvaluatorReadToUnicode(toUnicode, xref) {
var cmapObj = xref.fetchIfRef(toUnicode);
readToUnicode: function PartialEvaluator_readToUnicode(toUnicode, xref) {
var cmapObj = toUnicode;
var charToUnicode = [];
if (isName(cmapObj)) {
var isIdentityMap = cmapObj.name.substr(0, 9) == 'Identity-';
@ -532,9 +550,9 @@ var PartialEvaluator = (function partialEvaluator() {
var cmap = cmapObj.getBytes(cmapObj.length);
for (var i = 0, ii = cmap.length; i < ii; i++) {
var byte = cmap[i];
if (byte == 0x20 || byte == 0x0D || byte == 0x0A ||
byte == 0x3C || byte == 0x5B || byte == 0x5D) {
var octet = cmap[i];
if (octet == 0x20 || octet == 0x0D || octet == 0x0A ||
octet == 0x3C || octet == 0x5B || octet == 0x5D) {
switch (token) {
case 'usecmap':
error('usecmap is not implemented');
@ -554,9 +572,21 @@ var PartialEvaluator = (function partialEvaluator() {
var startRange = tokens[j];
var endRange = tokens[j + 1];
var code = tokens[j + 2];
while (startRange <= endRange) {
charToUnicode[startRange] = code++;
++startRange;
if (code == 0xFFFF) {
// CMap is broken, assuming code == startRange
code = startRange;
}
if (isArray(code)) {
var codeindex = 0;
while (startRange <= endRange) {
charToUnicode[startRange] = code[codeindex++];
++startRange;
}
} else {
while (startRange <= endRange) {
charToUnicode[startRange] = code++;
++startRange;
}
}
}
break;
@ -579,7 +609,7 @@ var PartialEvaluator = (function partialEvaluator() {
tokens.push(token);
token = '';
}
switch (byte) {
switch (octet) {
case 0x5B:
// begin list parsing
tokens.push(beginArrayToken);
@ -593,21 +623,39 @@ var PartialEvaluator = (function partialEvaluator() {
tokens.push(items);
break;
}
} else if (byte == 0x3E) {
} else if (octet == 0x3E) {
if (token.length) {
// parsing hex number
tokens.push(parseInt(token, 16));
token = '';
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);
if (b <= 0x10) {
k += 4;
b = (b << 16) | parseInt(token.substr(k, 4), 16);
b -= 0x10000;
str.push(0xD800 | (b >> 10));
str.push(0xDC00 | (b & 0x3FF));
break;
}
str.push(b);
}
tokens.push(String.fromCharCode.apply(String, str));
token = '';
}
}
} else {
token += String.fromCharCode(byte);
token += String.fromCharCode(octet);
}
}
}
return charToUnicode;
},
readCidToGidMap:
function partialEvaluatorReadCidToGidMap(cidToGidStream) {
readCidToGidMap: function PartialEvaluator_readCidToGidMap(cidToGidStream) {
// Extract the encoding from the CIDToGIDMap
var glyphsData = cidToGidStream.getBytes();
@ -624,16 +672,16 @@ var PartialEvaluator = (function partialEvaluator() {
return result;
},
extractWidths: function partialEvaluatorWidths(dict,
extractWidths: function PartialEvaluator_extractWidths(dict,
xref,
descriptor,
properties) {
var glyphsWidths = [];
var defaultWidth = 0;
if (properties.composite) {
defaultWidth = xref.fetchIfRef(dict.get('DW')) || 1000;
defaultWidth = dict.get('DW') || 1000;
var widths = xref.fetchIfRef(dict.get('W'));
var widths = dict.get('W');
if (widths) {
var start = 0, end = 0;
for (var i = 0, ii = widths.length; i < ii; i++) {
@ -654,7 +702,7 @@ var PartialEvaluator = (function partialEvaluator() {
}
} else {
var firstChar = properties.firstChar;
var widths = xref.fetchIfRef(dict.get('Widths'));
var widths = dict.get('Widths');
if (widths) {
var j = firstChar;
for (var i = 0, ii = widths.length; i < ii; i++)
@ -676,7 +724,7 @@ var PartialEvaluator = (function partialEvaluator() {
properties.widths = glyphsWidths;
},
getBaseFontMetrics: function getBaseFontMetrics(name) {
getBaseFontMetrics: function PartialEvaluator_getBaseFontMetrics(name) {
var defaultWidth = 0, widths = [];
var glyphWidths = Metrics[stdFontMap[name] || name];
if (isNum(glyphWidths)) {
@ -691,8 +739,10 @@ var PartialEvaluator = (function partialEvaluator() {
};
},
translateFont: function partialEvaluatorTranslateFont(dict, xref, resources,
dependency) {
translateFont: function PartialEvaluator_translateFont(dict,
xref,
resources,
dependency) {
var baseDict = dict;
var type = dict.get('Subtype');
assertWellFormed(isName(type), 'invalid font Subtype');
@ -707,10 +757,7 @@ var PartialEvaluator = (function partialEvaluator() {
if (!df)
return null;
if (isRef(df))
df = xref.fetch(df);
dict = xref.fetchIfRef(isRef(df) ? df : df[0]);
dict = isArray(df) ? xref.fetchIfRef(df[0]) : df;
type = dict.get('Subtype');
assertWellFormed(isName(type), 'invalid font Subtype');
@ -718,7 +765,7 @@ var PartialEvaluator = (function partialEvaluator() {
}
var maxCharIndex = composite ? 0xFFFF : 0xFF;
var descriptor = xref.fetchIfRef(dict.get('FontDescriptor'));
var descriptor = dict.get('FontDescriptor');
if (!descriptor) {
if (type.name == 'Type3') {
// FontDescriptor is only required for Type3 fonts when the document
@ -737,10 +784,18 @@ var PartialEvaluator = (function partialEvaluator() {
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,
defaultWidth: metrics.defaultWidth,
flags: flags,
firstChar: 0,
lastChar: maxCharIndex
};
@ -752,34 +807,31 @@ var PartialEvaluator = (function partialEvaluator() {
properties: properties
};
}
}
// According to the spec if 'FontDescriptor' is declared, 'FirstChar',
// 'LastChar' and 'Widths' should exists too, but some PDF encoders seems
// '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 = xref.fetchIfRef(dict.get('FirstChar')) || 0;
var lastChar = xref.fetchIfRef(dict.get('LastChar')) || maxCharIndex;
var fontName = xref.fetchIfRef(descriptor.get('FontName'));
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) {
fontFile = xref.fetchIfRef(fontFile);
if (fontFile.dict) {
var subtype = fontFile.dict.get('Subtype');
if (subtype)
subtype = subtype.name;
var length1 = fontFile.dict.get('Length1');
if (!isInt(length1))
length1 = xref.fetchIfRef(length1);
var length2 = fontFile.dict.get('Length2');
if (!isInt(length2))
length2 = xref.fetchIfRef(length2);
}
}
@ -808,15 +860,14 @@ var PartialEvaluator = (function partialEvaluator() {
if (type.name === 'Type3') {
properties.coded = true;
var charProcs = xref.fetchIfRef(dict.get('CharProcs'));
var fontResources = xref.fetchIfRef(dict.get('Resources')) || resources;
var charProcs = dict.get('CharProcs').getAll();
var fontResources = dict.get('Resources') || resources;
properties.resources = fontResources;
properties.charProcIRQueues = {};
for (var key in charProcs.map) {
var glyphStream = xref.fetchIfRef(charProcs.map[key]);
var queueObj = {};
properties.charProcIRQueues[key] =
this.getIRQueue(glyphStream, fontResources, queueObj, dependency);
properties.charProcOperatorList = {};
for (var key in charProcs) {
var glyphStream = charProcs[key];
properties.charProcOperatorList[key] =
this.getOperatorList(glyphStream, fontResources, dependency);
}
}
@ -829,11 +880,11 @@ var PartialEvaluator = (function partialEvaluator() {
}
};
return constructor;
return PartialEvaluator;
})();
var EvalState = (function evalState() {
function constructor() {
var EvalState = (function EvalStateClosure() {
function EvalState() {
// Are soft masks and alpha values shapes or opacities?
this.alphaIsShape = false;
this.fontSize = 0;
@ -850,8 +901,8 @@ var EvalState = (function evalState() {
this.fillColorSpace = null;
this.strokeColorSpace = null;
}
constructor.prototype = {
EvalState.prototype = {
};
return constructor;
return EvalState;
})();

2859
apps/files_pdfviewer/js/pdfjs/src/fonts.js Executable file → Normal file

File diff suppressed because it is too large Load Diff

729
apps/files_pdfviewer/js/pdfjs/src/function.js Executable file → Normal file
View File

@ -3,14 +3,14 @@
'use strict';
var PDFFunction = (function pdfFunction() {
var PDFFunction = (function PDFFunctionClosure() {
var CONSTRUCT_SAMPLED = 0;
var CONSTRUCT_INTERPOLATED = 2;
var CONSTRUCT_STICHED = 3;
var CONSTRUCT_POSTSCRIPT = 4;
return {
getSampleArray: function pdfFunctionGetSampleArray(size, outputSize, bps,
getSampleArray: function PDFFunction_getSampleArray(size, outputSize, bps,
str) {
var length = 1;
for (var i = 0, ii = size.length; i < ii; i++)
@ -38,7 +38,7 @@ var PDFFunction = (function pdfFunction() {
return array;
},
getIR: function pdfFunctionGetIR(xref, fn) {
getIR: function PDFFunction_getIR(xref, fn) {
var dict = fn.dict;
if (!dict)
dict = fn;
@ -57,7 +57,7 @@ var PDFFunction = (function pdfFunction() {
return typeFn.call(this, fn, dict, xref);
},
fromIR: function pdfFunctionFromIR(IR) {
fromIR: function PDFFunction_fromIR(IR) {
var type = IR[0];
switch (type) {
case CONSTRUCT_SAMPLED:
@ -72,16 +72,16 @@ var PDFFunction = (function pdfFunction() {
}
},
parse: function pdfFunctionParse(xref, fn) {
parse: function PDFFunction_parse(xref, fn) {
var IR = this.getIR(xref, fn);
return this.fromIR(IR);
},
constructSampled: function pdfFunctionConstructSampled(str, dict) {
constructSampled: function PDFFunction_constructSampled(str, dict) {
function toMultiArray(arr) {
var inputLength = arr.length;
var outputLength = arr.length / 2;
var out = new Array(outputLength);
var out = [];
var index = 0;
for (var i = 0; i < inputLength; i += 2) {
out[index] = [arr[i], arr[i + 1]];
@ -125,114 +125,104 @@ var PDFFunction = (function pdfFunction() {
else
decode = toMultiArray(decode);
// Precalc the multipliers
var inputMul = new Float64Array(inputSize);
for (var i = 0; i < inputSize; ++i) {
inputMul[i] = (encode[i][1] - encode[i][0]) /
(domain[i][1] - domain[i][0]);
}
var idxMul = new Int32Array(inputSize);
idxMul[0] = outputSize;
for (i = 1; i < inputSize; ++i) {
idxMul[i] = idxMul[i - 1] * size[i - 1];
}
var nSamples = outputSize;
for (i = 0; i < inputSize; ++i)
nSamples *= size[i];
var samples = this.getSampleArray(size, outputSize, bps, str);
return [
CONSTRUCT_SAMPLED, inputSize, domain, encode, decode, samples, size,
outputSize, bps, range, inputMul, idxMul, nSamples
outputSize, Math.pow(2, bps) - 1, range
];
},
constructSampledFromIR: function pdfFunctionConstructSampledFromIR(IR) {
var inputSize = IR[1];
var domain = IR[2];
var encode = IR[3];
var decode = IR[4];
var samples = IR[5];
var size = IR[6];
var outputSize = IR[7];
var bps = IR[8];
var range = IR[9];
var inputMul = IR[10];
var idxMul = IR[11];
var nSamples = IR[12];
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) {
if (inputSize != args.length)
// See chapter 3, page 110 of the PDF reference.
var m = IR[1];
var domain = IR[2];
var encode = IR[3];
var decode = IR[4];
var samples = IR[5];
var size = IR[6];
var n = IR[7];
var mask = IR[8];
var range = IR[9];
if (m != args.length)
error('Incorrect number of arguments: ' + inputSize + ' != ' +
args.length);
// Most of the below is a port of Poppler's implementation.
// TODO: There's a few other ways to do multilinear interpolation such
// as piecewise, which is much faster but an approximation.
var out = new Float64Array(outputSize);
var x;
var e = new Array(inputSize);
var efrac0 = new Float64Array(inputSize);
var efrac1 = new Float64Array(inputSize);
var sBuf = new Float64Array(1 << inputSize);
var i, j, k, idx, t;
// map input values into sample array
for (i = 0; i < inputSize; ++i) {
x = (args[i] - domain[i][0]) * inputMul[i] + encode[i][0];
if (x < 0) {
x = 0;
} else if (x > size[i] - 1) {
x = size[i] - 1;
}
e[i] = [Math.floor(x), 0];
if ((e[i][1] = e[i][0] + 1) >= size[i]) {
// this happens if in[i] = domain[i][1]
e[i][1] = e[i][0];
}
efrac1[i] = x - e[i][0];
efrac0[i] = 1 - efrac1[i];
}
var x = args;
// for each output, do m-linear interpolation
for (i = 0; i < outputSize; ++i) {
// 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;
// pull 2^m values out of the sample array
for (j = 0; j < (1 << inputSize); ++j) {
idx = i;
for (k = 0, t = j; k < inputSize; ++k, t >>= 1) {
idx += idxMul[k] * (e[k][t & 1]);
}
if (idx >= 0 && idx < nSamples) {
sBuf[j] = samples[idx];
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 offset0 = e0 * k;
var offset1 = offset0 + k; // e1 * k
for (var j = 0; j < cubeVertices; j++) {
if (j & pos) {
cubeN[j] *= n1;
cubeVertex[j] += offset1;
} else {
sBuf[j] = 0; // TODO Investigate if this is what Adobe does
cubeN[j] *= n0;
cubeVertex[j] += offset0;
}
}
// do m sets of interpolations
for (j = 0, t = (1 << inputSize); j < inputSize; ++j, t >>= 1) {
for (k = 0; k < t; k += 2) {
sBuf[k >> 1] = efrac0[j] * sBuf[k] + efrac1[j] * sBuf[k + 1];
}
}
// map output value to range
out[i] = (sBuf[0] * (decode[i][1] - decode[i][0]) + decode[i][0]);
if (out[i] < range[i][0]) {
out[i] = range[i][0];
} else if (out[i] > range[i][1]) {
out[i] = range[i][1];
}
k *= size_i;
pos <<= 1;
}
return out;
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 pdfFunctionConstructInterpolated(str, dict) {
constructInterpolated: function PDFFunction_constructInterpolated(str,
dict) {
var c0 = dict.get('C0') || [0];
var c1 = dict.get('C1') || [1];
var n = dict.get('N');
@ -249,7 +239,7 @@ var PDFFunction = (function pdfFunction() {
},
constructInterpolatedFromIR:
function pdfFunctionconstructInterpolatedFromIR(IR) {
function PDFFunction_constructInterpolatedFromIR(IR) {
var c0 = IR[1];
var diff = IR[2];
var n = IR[3];
@ -268,9 +258,8 @@ var PDFFunction = (function pdfFunction() {
}
},
constructStiched: function pdfFunctionConstructStiched(fn, dict, xref) {
constructStiched: function PDFFunction_constructStiched(fn, dict, xref) {
var domain = dict.get('Domain');
var range = dict.get('Range');
if (!domain)
error('No domain');
@ -290,7 +279,7 @@ var PDFFunction = (function pdfFunction() {
return [CONSTRUCT_STICHED, domain, bounds, encode, fns];
},
constructStichedFromIR: function pdfFunctionConstructStichedFromIR(IR) {
constructStichedFromIR: function PDFFunction_constructStichedFromIR(IR) {
var domain = IR[1];
var bounds = IR[2];
var encode = IR[3];
@ -336,16 +325,550 @@ var PDFFunction = (function pdfFunction() {
};
},
constructPostScript: function pdfFunctionConstructPostScript() {
return [CONSTRUCT_POSTSCRIPT];
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 pdfFunctionConstructPostScriptFromIR() {
TODO('unhandled type of function');
return function constructPostScriptFromIRResult() {
return [255, 105, 180];
constructPostScriptFromIR: function PDFFunction_constructPostScriptFromIR(
IR) {
var domain = IR[1];
var range = IR[2];
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) {
var out = stack.pop();
var rangeIndex = 2 * i;
if (out < range[rangeIndex])
out = range[rangeIndex];
else if (out > range[rangeIndex + 1])
out = range[rangeIndex + 1];
transformed[i] = out;
}
cache.set(key, transformed);
return transformed;
};
}
};
})();
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 = {};
this.total = 0;
}
FunctionCache.prototype = {
has: function FunctionCache_has(key) {
return key in this.cache;
},
get: function FunctionCache_get(key) {
return this.cache[key];
},
set: function FunctionCache_set(key, value) {
if (this.total < MAX_CACHE_SIZE) {
this.cache[key] = value;
this.total++;
}
}
};
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)
error('PostScript function stack overflow.');
this.stack.push(value);
},
pop: function PostScriptStack_pop() {
if (this.stack.length <= 0)
error('PostScript function stack underflow.');
return this.stack.pop();
},
copy: function PostScriptStack_copy(n) {
if (this.stack.length + n >= MAX_STACK_SIZE)
error('PostScript function stack overflow.');
var stack = this.stack;
for (var i = stack.length - n, j = n - 1; j >= 0; j--, i++)
stack.push(stack[i]);
},
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;
var r = stack.length - 1, c = l + (p - Math.floor(p / n) * n), i, j, t;
for (i = l, j = r; i < j; i++, j--) {
t = stack[i]; stack[i] = stack[j]; stack[j] = t;
}
for (i = l, j = c - 1; i < j; i++, j--) {
t = stack[i]; stack[i] = stack[j]; stack[j] = t;
}
for (i = c, j = r; i < j; i++, j--) {
t = stack[i]; stack[i] = stack[j]; stack[j] = t;
}
}
};
return PostScriptStack;
})();
var PostScriptEvaluator = (function PostScriptEvaluatorClosure() {
function PostScriptEvaluator(operators, operands) {
this.operators = operators;
this.operands = operands;
}
PostScriptEvaluator.prototype = {
execute: function PostScriptEvaluator_execute(initialStack) {
var stack = new PostScriptStack(initialStack);
var counter = 0;
var operators = this.operators;
var length = operators.length;
var operator, a, b;
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
b = stack.pop();
a = stack.pop();
if (!a)
counter = b;
break;
case 'j': // jump
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));
break;
case 'add':
b = stack.pop();
a = stack.pop();
stack.push(a + b);
break;
case 'and':
b = stack.pop();
a = stack.pop();
if (isBool(a) && isBool(b))
stack.push(a && b);
else
stack.push(a & b);
break;
case 'atan':
a = stack.pop();
stack.push(Math.atan(a));
break;
case 'bitshift':
b = stack.pop();
a = stack.pop();
if (a > 0)
stack.push(a << b);
else
stack.push(a >> b);
break;
case 'ceiling':
a = stack.pop();
stack.push(Math.ceil(a));
break;
case 'copy':
a = stack.pop();
stack.copy(a);
break;
case 'cos':
a = stack.pop();
stack.push(Math.cos(a));
break;
case 'cvi':
a = stack.pop() | 0;
stack.push(a);
break;
case 'cvr':
// noop
break;
case 'div':
b = stack.pop();
a = stack.pop();
stack.push(a / b);
break;
case 'dup':
stack.copy(1);
break;
case 'eq':
b = stack.pop();
a = stack.pop();
stack.push(a == b);
break;
case 'exch':
stack.roll(2, 1);
break;
case 'exp':
b = stack.pop();
a = stack.pop();
stack.push(Math.pow(a, b));
break;
case 'false':
stack.push(false);
break;
case 'floor':
a = stack.pop();
stack.push(Math.floor(a));
break;
case 'ge':
b = stack.pop();
a = stack.pop();
stack.push(a >= b);
break;
case 'gt':
b = stack.pop();
a = stack.pop();
stack.push(a > b);
break;
case 'idiv':
b = stack.pop();
a = stack.pop();
stack.push((a / b) | 0);
break;
case 'index':
a = stack.pop();
stack.index(a);
break;
case 'le':
b = stack.pop();
a = stack.pop();
stack.push(a <= b);
break;
case 'ln':
a = stack.pop();
stack.push(Math.log(a));
break;
case 'log':
a = stack.pop();
stack.push(Math.log(a) / Math.LN10);
break;
case 'lt':
b = stack.pop();
a = stack.pop();
stack.push(a < b);
break;
case 'mod':
b = stack.pop();
a = stack.pop();
stack.push(a % b);
break;
case 'mul':
b = stack.pop();
a = stack.pop();
stack.push(a * b);
break;
case 'ne':
b = stack.pop();
a = stack.pop();
stack.push(a != b);
break;
case 'neg':
a = stack.pop();
stack.push(-b);
break;
case 'not':
a = stack.pop();
if (isBool(a) && isBool(b))
stack.push(a && b);
else
stack.push(a & b);
break;
case 'or':
b = stack.pop();
a = stack.pop();
if (isBool(a) && isBool(b))
stack.push(a || b);
else
stack.push(a | b);
break;
case 'pop':
stack.pop();
break;
case 'roll':
b = stack.pop();
a = stack.pop();
stack.roll(a, b);
break;
case 'round':
a = stack.pop();
stack.push(Math.round(a));
break;
case 'sin':
a = stack.pop();
stack.push(Math.sin(a));
break;
case 'sqrt':
a = stack.pop();
stack.push(Math.sqrt(a));
break;
case 'sub':
b = stack.pop();
a = stack.pop();
stack.push(a - b);
break;
case 'true':
stack.push(true);
break;
case 'truncate':
a = stack.pop();
a = a < 0 ? Math.ceil(a) : Math.floor(a);
stack.push(a);
break;
case 'xor':
b = stack.pop();
a = stack.pop();
if (isBool(a) && isBool(b))
stack.push(a != b);
else
stack.push(a ^ b);
break;
default:
error('Unknown operator ' + operator);
break;
}
}
return stack.stack;
}
};
return PostScriptEvaluator;
})();
var PostScriptParser = (function PostScriptParserClosure() {
function PostScriptParser(lexer) {
this.lexer = lexer;
this.operators = [];
this.token;
this.prev;
}
PostScriptParser.prototype = {
nextToken: function PostScriptParser_nextToken() {
this.prev = this.token;
this.token = this.lexer.getToken();
},
accept: function PostScriptParser_accept(type) {
if (this.token.type == type) {
this.nextToken();
return true;
}
return false;
},
expect: function PostScriptParser_expect(type) {
if (this.accept(type))
return true;
error('Unexpected symbol: found ' + this.token.type + ' expected ' +
type + '.');
},
parse: function PostScriptParser_parse() {
this.nextToken();
this.expect(PostScriptTokenTypes.LBRACE);
this.parseBlock();
this.expect(PostScriptTokenTypes.RBRACE);
return this.operators;
},
parseBlock: function PostScriptParser_parseBlock() {
while (true) {
if (this.accept(PostScriptTokenTypes.NUMBER)) {
this.operators.push(this.prev.value);
} else if (this.accept(PostScriptTokenTypes.OPERATOR)) {
this.operators.push(this.prev.value);
} else if (this.accept(PostScriptTokenTypes.LBRACE)) {
this.parseCondition();
} else {
return;
}
}
},
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)) {
var jumpLocation = this.operators.length;
this.operators.push(null, null);
var endOfTrue = this.operators.length;
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 {
error('PS Function: error parsing conditional.');
}
}
};
return PostScriptParser;
})();
var PostScriptTokenTypes = {
LBRACE: 0,
RBRACE: 1,
NUMBER: 2,
OPERATOR: 3,
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,
'}');
PostScriptToken.IF = new PostScriptToken(PostScriptTokenTypes.IF, 'IF');
PostScriptToken.IFELSE = new PostScriptToken(PostScriptTokenTypes.IFELSE,
'IFELSE');
return PostScriptToken;
})();
var PostScriptLexer = (function PostScriptLexerClosure() {
function PostScriptLexer(stream) {
this.stream = stream;
}
PostScriptLexer.prototype = {
getToken: function PostScriptLexer_getToken() {
var s = '';
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;
} else if (ch == '%') {
comment = true;
} else if (!Lexer.isSpace(ch)) {
break;
}
}
switch (ch) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '+': case '-': case '.':
return new PostScriptToken(PostScriptTokenTypes.NUMBER,
this.getNumber(ch));
case '{':
return PostScriptToken.LBRACE;
case '}':
return PostScriptToken.RBRACE;
}
// operator
var str = ch.toLowerCase();
while (true) {
ch = stream.lookChar().toLowerCase();
if (ch >= 'a' && ch <= 'z')
str += ch;
else
break;
stream.skip();
}
switch (str) {
case 'if':
return PostScriptToken.IF;
case 'ifelse':
return PostScriptToken.IFELSE;
default:
return PostScriptToken.getOperator(str);
}
},
getNumber: function PostScriptLexer_getNumber(ch) {
var str = ch;
var stream = this.stream;
while (true) {
ch = stream.lookChar();
if ((ch >= '0' && ch <= '9') || ch == '-' || ch == '.')
str += ch;
else
break;
stream.skip();
}
var value = parseFloat(str);
if (isNaN(value))
error('Invalid floating point number: ' + value);
return value;
}
};
return PostScriptLexer;
})();

84
apps/files_pdfviewer/js/pdfjs/src/glyphlist.js Executable file → Normal file
View File

@ -1508,27 +1508,7 @@ var GlyphsUnicode = {
dalet: 0x05D3,
daletdagesh: 0xFB33,
daletdageshhebrew: 0xFB33,
dalethatafpatah: 0x05D305B2,
dalethatafpatahhebrew: 0x05D305B2,
dalethatafsegol: 0x05D305B1,
dalethatafsegolhebrew: 0x05D305B1,
dalethebrew: 0x05D3,
dalethiriq: 0x05D305B4,
dalethiriqhebrew: 0x05D305B4,
daletholam: 0x05D305B9,
daletholamhebrew: 0x05D305B9,
daletpatah: 0x05D305B7,
daletpatahhebrew: 0x05D305B7,
daletqamats: 0x05D305B8,
daletqamatshebrew: 0x05D305B8,
daletqubuts: 0x05D305BB,
daletqubutshebrew: 0x05D305BB,
daletsegol: 0x05D305B6,
daletsegolhebrew: 0x05D305B6,
daletsheva: 0x05D305B0,
daletshevahebrew: 0x05D305B0,
dalettsere: 0x05D305B5,
dalettserehebrew: 0x05D305B5,
dalfinalarabic: 0xFEAA,
dammaarabic: 0x064F,
dammalowarabic: 0x064F,
@ -1845,10 +1825,6 @@ var GlyphsUnicode = {
finalkafdagesh: 0xFB3A,
finalkafdageshhebrew: 0xFB3A,
finalkafhebrew: 0x05DA,
finalkafqamats: 0x05DA05B8,
finalkafqamatshebrew: 0x05DA05B8,
finalkafsheva: 0x05DA05B0,
finalkafshevahebrew: 0x05DA05B0,
finalmem: 0x05DD,
finalmemhebrew: 0x05DD,
finalnun: 0x05DF,
@ -2037,14 +2013,7 @@ var GlyphsUnicode = {
hakatakanahalfwidth: 0xFF8A,
halantgurmukhi: 0x0A4D,
hamzaarabic: 0x0621,
hamzadammaarabic: 0x0621064F,
hamzadammatanarabic: 0x0621064C,
hamzafathaarabic: 0x0621064E,
hamzafathatanarabic: 0x0621064B,
hamzalowarabic: 0x0621,
hamzalowkasraarabic: 0x06210650,
hamzalowkasratanarabic: 0x0621064D,
hamzasukunarabic: 0x06210652,
hangulfiller: 0x3164,
hardsigncyrillic: 0x044A,
harpoonleftbarbup: 0x21BC,
@ -2476,10 +2445,6 @@ var GlyphsUnicode = {
lameddagesh: 0xFB3C,
lameddageshhebrew: 0xFB3C,
lamedhebrew: 0x05DC,
lamedholam: 0x05DC05B9,
lamedholamdagesh: '05DC 05B9 05BC',
lamedholamdageshhebrew: '05DC 05B9 05BC',
lamedholamhebrew: 0x05DC05B9,
lamfinalarabic: 0xFEDE,
lamhahinitialarabic: 0xFCCA,
laminitialarabic: 0xFEDF,
@ -2489,8 +2454,6 @@ var GlyphsUnicode = {
lammedialarabic: 0xFEE0,
lammeemhahinitialarabic: 0xFD88,
lammeeminitialarabic: 0xFCCC,
lammeemjeeminitialarabic: 'FEDF FEE4 FEA0',
lammeemkhahinitialarabic: 'FEDF FEE4 FEA8',
largecircle: 0x25EF,
lbar: 0x019A,
lbelt: 0x026C,
@ -2787,7 +2750,6 @@ var GlyphsUnicode = {
noonfinalarabic: 0xFEE6,
noonghunnaarabic: 0x06BA,
noonghunnafinalarabic: 0xFB9F,
noonhehinitialarabic: 0xFEE7FEEC,
nooninitialarabic: 0xFEE7,
noonjeeminitialarabic: 0xFCD2,
noonjeemisolatedarabic: 0xFC4B,
@ -3159,27 +3121,7 @@ var GlyphsUnicode = {
qof: 0x05E7,
qofdagesh: 0xFB47,
qofdageshhebrew: 0xFB47,
qofhatafpatah: 0x05E705B2,
qofhatafpatahhebrew: 0x05E705B2,
qofhatafsegol: 0x05E705B1,
qofhatafsegolhebrew: 0x05E705B1,
qofhebrew: 0x05E7,
qofhiriq: 0x05E705B4,
qofhiriqhebrew: 0x05E705B4,
qofholam: 0x05E705B9,
qofholamhebrew: 0x05E705B9,
qofpatah: 0x05E705B7,
qofpatahhebrew: 0x05E705B7,
qofqamats: 0x05E705B8,
qofqamatshebrew: 0x05E705B8,
qofqubuts: 0x05E705BB,
qofqubutshebrew: 0x05E705BB,
qofsegol: 0x05E705B6,
qofsegolhebrew: 0x05E705B6,
qofsheva: 0x05E705B0,
qofshevahebrew: 0x05E705B0,
qoftsere: 0x05E705B5,
qoftserehebrew: 0x05E705B5,
qparen: 0x24AC,
quarternote: 0x2669,
qubuts: 0x05BB,
@ -3253,32 +3195,11 @@ var GlyphsUnicode = {
reharmenian: 0x0580,
rehfinalarabic: 0xFEAE,
rehiragana: 0x308C,
rehyehaleflamarabic: '0631 FEF3 FE8E 0644',
rekatakana: 0x30EC,
rekatakanahalfwidth: 0xFF9A,
resh: 0x05E8,
reshdageshhebrew: 0xFB48,
reshhatafpatah: 0x05E805B2,
reshhatafpatahhebrew: 0x05E805B2,
reshhatafsegol: 0x05E805B1,
reshhatafsegolhebrew: 0x05E805B1,
reshhebrew: 0x05E8,
reshhiriq: 0x05E805B4,
reshhiriqhebrew: 0x05E805B4,
reshholam: 0x05E805B9,
reshholamhebrew: 0x05E805B9,
reshpatah: 0x05E805B7,
reshpatahhebrew: 0x05E805B7,
reshqamats: 0x05E805B8,
reshqamatshebrew: 0x05E805B8,
reshqubuts: 0x05E805BB,
reshqubutshebrew: 0x05E805BB,
reshsegol: 0x05E805B6,
reshsegolhebrew: 0x05E805B6,
reshsheva: 0x05E805B0,
reshshevahebrew: 0x05E805B0,
reshtsere: 0x05E805B5,
reshtserehebrew: 0x05E805B5,
reversedtilde: 0x223D,
reviahebrew: 0x0597,
reviamugrashhebrew: 0x0597,
@ -3477,7 +3398,6 @@ var GlyphsUnicode = {
shaddadammaarabic: 0xFC61,
shaddadammatanarabic: 0xFC5E,
shaddafathaarabic: 0xFC60,
shaddafathatanarabic: 0x0651064B,
shaddakasraarabic: 0xFC62,
shaddakasratanarabic: 0xFC5F,
shade: 0x2592,
@ -3674,7 +3594,6 @@ var GlyphsUnicode = {
tchehfinalarabic: 0xFB7B,
tchehinitialarabic: 0xFB7C,
tchehmedialarabic: 0xFB7D,
tchehmeeminitialarabic: 0xFB7CFEE4,
tcircle: 0x24E3,
tcircumflexbelow: 0x1E71,
tcommaaccent: 0x0163,
@ -4287,6 +4206,7 @@ var GlyphsUnicode = {
zretroflexhook: 0x0290,
zstroke: 0x01B6,
zuhiragana: 0x305A,
zukatakana: 0x30BA
zukatakana: 0x30BA,
'.notdef': 0x0000
};

270
apps/files_pdfviewer/js/pdfjs/src/image.js Executable file → Normal file
View File

@ -3,8 +3,37 @@
'use strict';
var PDFImage = (function pdfImage() {
function constructor(xref, res, image, inline) {
var PDFImage = (function PDFImageClosure() {
/**
* Decode the image in the main thread if it supported. Resovles the promise
* when the image data is ready.
*/
function handleImageData(handler, xref, res, image, promise) {
if (image instanceof JpegStream && image.isNativelyDecodable(xref, res)) {
// For natively supported jpegs send them to the main thread for decoding.
var dict = image.dict;
var colorSpace = dict.get('ColorSpace', 'CS');
colorSpace = ColorSpace.parse(colorSpace, xref, res);
var numComps = colorSpace.numComps;
handler.send('jpeg_decode', [image.getIR(), numComps], function(message) {
var data = message.data;
var stream = new Stream(data, 0, data.length, image.dict);
promise.resolve(stream);
});
} else {
promise.resolve(image);
}
}
/**
* Decode and clamp a value. The formula is different from the spec because we
* don't decode to float range [0,1], we decode it in the [0,max] range.
*/
function decodeAndClamp(value, addend, coefficient, max) {
value = addend + value * coefficient;
// Clamp the value to the range
return value < 0 ? 0 : value > max ? max : value;
}
function PDFImage(xref, res, image, inline, smask) {
this.image = image;
if (image.getParams) {
// JPX/JPEG2000 streams directly contain bits per component
@ -49,34 +78,143 @@ var PDFImage = (function pdfImage() {
}
this.decode = dict.get('Decode', 'D');
this.needsDecode = false;
if (this.decode && this.colorSpace &&
!this.colorSpace.isDefaultDecode(this.decode)) {
this.needsDecode = true;
// Do some preprocessing to avoid more math.
var max = (1 << bitsPerComponent) - 1;
this.decodeCoefficients = [];
this.decodeAddends = [];
for (var i = 0, j = 0; i < this.decode.length; i += 2, ++j) {
var dmin = this.decode[i];
var dmax = this.decode[i + 1];
this.decodeCoefficients[j] = dmax - dmin;
this.decodeAddends[j] = max * dmin;
}
}
var mask = xref.fetchIfRef(dict.get('Mask'));
var smask = xref.fetchIfRef(dict.get('SMask'));
var mask = dict.get('Mask');
if (mask) {
TODO('masked images');
} else if (smask) {
this.smask = new PDFImage(xref, res, smask);
this.smask = new PDFImage(xref, res, smask, false);
}
}
/**
* Handles processing of image data and calls the callback with an argument
* of a PDFImage when the image is ready to be used.
*/
PDFImage.buildImage = function PDFImage_buildImage(callback, handler, xref,
res, image, inline) {
var imageDataPromise = new Promise();
var smaskPromise = new Promise();
// The image data and smask data may not be ready yet, wait till both are
// resolved.
Promise.all([imageDataPromise, smaskPromise]).then(function(results) {
var imageData = results[0], smaskData = results[1];
var image = new PDFImage(xref, res, imageData, inline, smaskData);
callback(image);
});
constructor.prototype = {
getComponents: function getComponents(buffer, decodeMap) {
handleImageData(handler, xref, res, image, imageDataPromise);
var smask = image.dict.get('SMask');
if (smask)
handleImageData(handler, xref, res, smask, smaskPromise);
else
smaskPromise.resolve(null);
};
/**
* Resize an image using the nearest neighbor algorithm. Currently only
* supports one and three component images.
* @param {TypedArray} pixels The original image with one component.
* @param {Number} bpc Number of bits per component.
* @param {Number} components Number of color components, 1 or 3 is supported.
* @param {Number} w1 Original width.
* @param {Number} h1 Original height.
* @param {Number} w2 New width.
* @param {Number} h2 New height.
* @return {TypedArray} Resized image data.
*/
PDFImage.resize = function PDFImage_resize(pixels, bpc, components,
w1, h1, w2, h2) {
var length = w2 * h2 * components;
var temp = bpc <= 8 ? new Uint8Array(length) :
bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length);
var xRatio = w1 / w2;
var yRatio = h1 / h2;
var px, py, newIndex, oldIndex;
for (var i = 0; i < h2; i++) {
for (var j = 0; j < w2; j++) {
px = Math.floor(j * xRatio);
py = Math.floor(i * yRatio);
newIndex = (i * w2) + j;
oldIndex = ((py * w1) + px);
if (components === 1) {
temp[newIndex] = pixels[oldIndex];
} else if (components === 3) {
newIndex *= 3;
oldIndex *= 3;
temp[newIndex] = pixels[oldIndex];
temp[newIndex + 1] = pixels[oldIndex + 1];
temp[newIndex + 2] = pixels[oldIndex + 2];
}
}
}
return temp;
};
PDFImage.prototype = {
get drawWidth() {
if (!this.smask)
return this.width;
return Math.max(this.width, this.smask.width);
},
get drawHeight() {
if (!this.smask)
return this.height;
return Math.max(this.height, this.smask.height);
},
getComponents: function PDFImage_getComponents(buffer) {
var bpc = this.bpc;
if (bpc == 8)
var needsDecode = this.needsDecode;
var decodeMap = this.decode;
// This image doesn't require any extra work.
if (bpc == 8 && !needsDecode)
return buffer;
var bufferLength = buffer.length;
var width = this.width;
var height = this.height;
var numComps = this.numComps;
var length = width * height;
var length = width * height * numComps;
var bufferPos = 0;
var output = bpc <= 8 ? new Uint8Array(length) :
bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length);
var rowComps = width * numComps;
var decodeAddends, decodeCoefficients;
if (needsDecode) {
decodeAddends = this.decodeAddends;
decodeCoefficients = this.decodeCoefficients;
}
var max = (1 << bpc) - 1;
if (bpc == 1) {
if (bpc == 8) {
// Optimization for reading 8 bpc images that have a decode.
for (var i = 0, ii = length; i < ii; ++i) {
var compIndex = i % numComps;
var value = buffer[i];
value = decodeAndClamp(value, decodeAddends[compIndex],
decodeCoefficients[compIndex], max);
output[i] = value;
}
} else if (bpc == 1) {
// Optimization for reading 1 bpc images.
var valueZero = 0, valueOne = 1;
if (decodeMap) {
valueZero = decodeMap[0] ? 1 : 0;
@ -101,8 +239,7 @@ var PDFImage = (function pdfImage() {
output[i] = !(buf & mask) ? valueZero : valueOne;
}
} else {
if (decodeMap != null)
TODO('interpolate component values');
// The general case that handles all other bpc values.
var bits = 0, buf = 0;
for (var i = 0, ii = length; i < ii; ++i) {
if (i % rowComps == 0) {
@ -116,51 +253,44 @@ var PDFImage = (function pdfImage() {
}
var remainingBits = bits - bpc;
output[i] = buf >> remainingBits;
var value = buf >> remainingBits;
if (needsDecode) {
var compIndex = i % numComps;
value = decodeAndClamp(value, decodeAddends[compIndex],
decodeCoefficients[compIndex], max);
}
output[i] = value;
buf = buf & ((1 << remainingBits) - 1);
bits = remainingBits;
}
}
return output;
},
getOpacity: function getOpacity() {
getOpacity: function PDFImage_getOpacity(width, height) {
var smask = this.smask;
var width = this.width;
var height = this.height;
var buf = new Uint8Array(width * height);
var originalWidth = this.width;
var originalHeight = this.height;
var buf;
if (smask) {
if (smask.image.getImage) {
// smask is a DOM image
var tempCanvas = new ScratchCanvas(width, height);
var tempCtx = tempCanvas.getContext('2d');
var domImage = smask.image.getImage();
tempCtx.drawImage(domImage, 0, 0, domImage.width, domImage.height,
0, 0, width, height);
var data = tempCtx.getImageData(0, 0, width, height).data;
for (var i = 0, j = 0, ii = width * height; i < ii; ++i, j += 4)
buf[i] = data[j]; // getting first component value
return buf;
}
var sw = smask.width;
var sh = smask.height;
if (sw != this.width || sh != this.height)
error('smask dimensions do not match image dimensions: ' + sw +
' != ' + this.width + ', ' + sh + ' != ' + this.height);
buf = new Uint8Array(sw * sh);
smask.fillGrayBuffer(buf);
return buf;
if (sw != width || sh != height)
buf = PDFImage.resize(buf, smask.bps, 1, sw, sh, width, height);
} else {
buf = new Uint8Array(width * height);
for (var i = 0, ii = width * height; i < ii; ++i)
buf[i] = 255;
}
return buf;
},
applyStencilMask: function applyStencilMask(buffer, inverseDecode) {
applyStencilMask: function PDFImage_applyStencilMask(buffer,
inverseDecode) {
var width = this.width, height = this.height;
var bitStrideLength = (width + 7) >> 3;
this.image.reset();
var imgArray = this.image.getBytes(bitStrideLength * height);
var imgArray = this.getImageBytes(bitStrideLength * height);
var imgArrayPos = 0;
var i, j, mask, buf;
// removing making non-masked pixels transparent
@ -180,21 +310,23 @@ var PDFImage = (function pdfImage() {
}
}
},
fillRgbaBuffer: function fillRgbaBuffer(buffer, decodeMap) {
fillRgbaBuffer: function PDFImage_fillRgbaBuffer(buffer, width, height) {
var numComps = this.numComps;
var width = this.width;
var height = this.height;
var originalWidth = this.width;
var originalHeight = this.height;
var bpc = this.bpc;
// rows start at byte boundary;
var rowBytes = (width * numComps * bpc + 7) >> 3;
this.image.reset();
var imgArray = this.image.getBytes(height * rowBytes);
var rowBytes = (originalWidth * numComps * bpc + 7) >> 3;
var imgArray = this.getImageBytes(originalHeight * rowBytes);
var comps = this.colorSpace.getRgbBuffer(
this.getComponents(imgArray, decodeMap), bpc);
this.getComponents(imgArray), bpc);
if (originalWidth != width || originalHeight != height)
comps = PDFImage.resize(comps, this.bpc, 3, originalWidth,
originalHeight, width, height);
var compsPos = 0;
var opacity = this.getOpacity();
var opacity = this.getOpacity(width, height);
var opacityPos = 0;
var length = width * height * 4;
@ -205,7 +337,7 @@ var PDFImage = (function pdfImage() {
buffer[i + 3] = opacity[opacityPos++];
}
},
fillGrayBuffer: function fillGrayBuffer(buffer) {
fillGrayBuffer: function PDFImage_fillGrayBuffer(buffer) {
var numComps = this.numComps;
if (numComps != 1)
error('Reading gray scale from a color image: ' + numComps);
@ -216,42 +348,28 @@ var PDFImage = (function pdfImage() {
// rows start at byte boundary;
var rowBytes = (width * numComps * bpc + 7) >> 3;
this.image.reset();
var imgArray = this.image.getBytes(height * rowBytes);
var imgArray = this.getImageBytes(height * rowBytes);
var comps = this.getComponents(imgArray);
var length = width * height;
// we aren't using a colorspace so we need to scale the value
var scale = 255 / ((1 << bpc) - 1);
for (var i = 0; i < length; ++i)
buffer[i] = comps[i];
buffer[i] = (scale * comps[i]) | 0;
},
getImageBytes: function PDFImage_getImageBytes(length) {
this.image.reset();
return this.image.getBytes(length);
}
};
return constructor;
return PDFImage;
})();
var JpegImageLoader = (function jpegImage() {
function JpegImageLoader(objId, imageData, objs) {
var src = 'data:image/jpeg;base64,' + window.btoa(imageData);
var img = new Image();
img.onload = (function jpegImageLoaderOnload() {
this.loaded = true;
objs.resolve(objId, this);
if (this.onLoad)
this.onLoad();
}).bind(this);
img.src = src;
this.domImage = img;
}
JpegImageLoader.prototype = {
getImage: function jpegImageLoaderGetImage() {
return this.domImage;
}
};
return JpegImageLoader;
})();
function loadJpegStream(id, imageData, objs) {
var img = new Image();
img.onload = (function loadJpegStream_onloadClosure() {
objs.resolve(id, img);
});
img.src = 'data:image/jpeg;base64,' + window.btoa(imageData);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,66 @@
/* -*- 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 Metadata = PDFJS.Metadata = (function MetadataClosure() {
function Metadata(meta) {
if (typeof meta === 'string') {
var parser = new DOMParser();
meta = parser.parseFromString(meta, 'application/xml');
} else if (!(meta instanceof Document)) {
error('Metadata: Invalid metadata object');
}
this.metaDocument = meta;
this.metadata = {};
this.parse();
}
Metadata.prototype = {
parse: function Metadata_parse() {
var doc = this.metaDocument;
var rdf = doc.documentElement;
if (rdf.nodeName.toLowerCase() !== 'rdf:rdf') { // Wrapped in <xmpmeta>
rdf = rdf.firstChild;
while (rdf && rdf.nodeName.toLowerCase() !== 'rdf:rdf')
rdf = rdf.nextSibling;
}
var nodeName = (rdf) ? rdf.nodeName.toLowerCase() : null;
if (!rdf || nodeName !== 'rdf:rdf' || !rdf.hasChildNodes())
return;
var childNodes = rdf.childNodes, desc, namespace, entries, entry;
for (var i = 0, length = childNodes.length; i < length; i++) {
desc = childNodes[i];
if (desc.nodeName.toLowerCase() !== 'rdf:description')
continue;
entries = [];
for (var ii = 0, iLength = desc.childNodes.length; ii < iLength; ii++) {
if (desc.childNodes[ii].nodeName.toLowerCase() !== '#text')
entries.push(desc.childNodes[ii]);
}
for (ii = 0, iLength = entries.length; ii < iLength; ii++) {
var entry = entries[ii];
var name = entry.nodeName.toLowerCase();
this.metadata[name] = entry.textContent.trim();
}
}
},
get: function Metadata_get(name) {
return this.metadata[name] || null;
},
has: function Metadata_has(name) {
return typeof this.metadata[name] !== 'undefined';
}
};
return Metadata;
})();

3
apps/files_pdfviewer/js/pdfjs/src/metrics.js Executable file → Normal file
View File

@ -3,6 +3,9 @@
'use strict';
// The Metrics object contains glyph widths (in glyph space units).
// As per PDF spec, for most fonts (Type 3 being an exception) a glyph
// space unit corresponds to 1/1000th of text space unit.
var Metrics = {
'Courier': 600,
'Courier-Bold': 600,

416
apps/files_pdfviewer/js/pdfjs/src/obj.js Executable file → Normal file
View File

@ -3,121 +3,157 @@
'use strict';
var Name = (function nameName() {
function constructor(name) {
var Name = (function NameClosure() {
function Name(name) {
this.name = name;
}
constructor.prototype = {
};
Name.prototype = {};
return constructor;
return Name;
})();
var Cmd = (function cmdCmd() {
function constructor(cmd) {
var Cmd = (function CmdClosure() {
function Cmd(cmd) {
this.cmd = cmd;
}
constructor.prototype = {
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 constructor;
return Cmd;
})();
var Dict = (function dictDict() {
function constructor() {
var Dict = (function DictClosure() {
// xref is optional
function Dict(xref) {
// Map should only be used internally, use functions below to access.
this.map = Object.create(null);
this.xref = xref;
}
constructor.prototype = {
get: function dictGet(key1, key2, key3) {
Dict.prototype = {
// automatically dereferences Ref objects
get: function Dict_get(key1, key2, key3) {
var value;
var xref = this.xref;
if (typeof (value = this.map[key1]) != 'undefined' || key1 in this.map ||
typeof key2 == 'undefined') {
return value;
return xref ? this.xref.fetchIfRef(value) : value;
}
if (typeof (value = this.map[key2]) != 'undefined' || key2 in this.map ||
typeof key3 == 'undefined') {
return value;
return xref ? this.xref.fetchIfRef(value) : value;
}
return this.map[key3] || null;
value = this.map[key3] || null;
return xref ? this.xref.fetchIfRef(value) : value;
},
// no dereferencing
getRaw: function Dict_getRaw(key) {
return this.map[key];
},
// creates new map and dereferences all Refs
getAll: function Dict_getAll() {
var all = {};
for (var key in this.map)
all[key] = this.get(key);
return all;
},
set: function dictSet(key, value) {
set: function Dict_set(key, value) {
this.map[key] = value;
},
has: function dictHas(key) {
has: function Dict_has(key) {
return key in this.map;
},
forEach: function dictForEach(callback) {
forEach: function Dict_forEach(callback) {
for (var key in this.map) {
callback(key, this.map[key]);
callback(key, this.get(key));
}
}
};
return constructor;
return Dict;
})();
var Ref = (function refRef() {
function constructor(num, gen) {
var Ref = (function RefClosure() {
function Ref(num, gen) {
this.num = num;
this.gen = gen;
}
constructor.prototype = {
};
Ref.prototype = {};
return constructor;
return Ref;
})();
// The reference is identified by number and generation,
// this structure stores only one instance of the reference.
var RefSet = (function refSet() {
function constructor() {
var RefSet = (function RefSetClosure() {
function RefSet() {
this.dict = {};
}
constructor.prototype = {
has: function refSetHas(ref) {
RefSet.prototype = {
has: function RefSet_has(ref) {
return !!this.dict['R' + ref.num + '.' + ref.gen];
},
put: function refSetPut(ref) {
put: function RefSet_put(ref) {
this.dict['R' + ref.num + '.' + ref.gen] = ref;
}
};
return constructor;
return RefSet;
})();
var Catalog = (function catalogCatalog() {
function constructor(xref) {
var Catalog = (function CatalogClosure() {
function Catalog(xref) {
this.xref = xref;
var obj = xref.getCatalogObj();
assertWellFormed(isDict(obj), 'catalog object is not a dictionary');
this.catDict = obj;
}
constructor.prototype = {
Catalog.prototype = {
get metadata() {
var stream = this.catDict.get('Metadata');
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') {
metadata = stringToPDFString(bytesToString(stream.getBytes()));
}
}
return shadow(this, 'metadata', metadata);
},
get toplevelPagesDict() {
var pagesObj = this.catDict.get('Pages');
assertWellFormed(isRef(pagesObj), 'invalid top-level pages reference');
var xrefObj = this.xref.fetch(pagesObj);
assertWellFormed(isDict(xrefObj), 'invalid top-level pages dictionary');
assertWellFormed(isDict(pagesObj), 'invalid top-level pages dictionary');
// shadow the prototype getter
return shadow(this, 'toplevelPagesDict', xrefObj);
return shadow(this, 'toplevelPagesDict', pagesObj);
},
get documentOutline() {
var obj = this.catDict.get('Outlines');
var xref = this.xref;
var obj = this.catDict.get('Outlines');
var root = { items: [] };
if (isRef(obj)) {
obj = xref.fetch(obj).get('First');
if (isDict(obj)) {
obj = obj.getRaw('First');
var processed = new RefSet();
if (isRef(obj)) {
var queue = [{obj: obj, parent: root}];
@ -126,18 +162,20 @@ var Catalog = (function catalogCatalog() {
processed.put(obj);
while (queue.length > 0) {
var i = queue.shift();
var outlineDict = xref.fetch(i.obj);
var outlineDict = xref.fetchIfRef(i.obj);
if (outlineDict === null)
continue;
if (!outlineDict.has('Title'))
error('Invalid outline item');
var dest = outlineDict.get('A');
if (dest)
dest = xref.fetchIfRef(dest).get('D');
dest = dest.get('D');
else if (outlineDict.has('Dest')) {
dest = outlineDict.get('Dest');
dest = outlineDict.getRaw('Dest');
if (isName(dest))
dest = dest.name;
}
var title = xref.fetchIfRef(outlineDict.get('Title'));
var title = outlineDict.get('Title');
var outlineItem = {
dest: dest,
title: stringToPDFString(title),
@ -148,12 +186,12 @@ var Catalog = (function catalogCatalog() {
items: []
};
i.parent.items.push(outlineItem);
obj = outlineDict.get('First');
obj = outlineDict.getRaw('First');
if (isRef(obj) && !processed.has(obj)) {
queue.push({obj: obj, parent: outlineItem});
processed.put(obj);
}
obj = outlineDict.get('Next');
obj = outlineDict.getRaw('Next');
if (isRef(obj) && !processed.has(obj)) {
queue.push({obj: obj, parent: i.parent});
processed.put(obj);
@ -173,7 +211,7 @@ var Catalog = (function catalogCatalog() {
// shadow the prototype getter
return shadow(this, 'num', obj);
},
traverseKids: function catalogTraverseKids(pagesDict) {
traverseKids: function Catalog_traverseKids(pagesDict) {
var pageCache = this.pageCache;
var kids = pagesDict.get('Kids');
assertWellFormed(isArray(kids),
@ -181,7 +219,7 @@ var Catalog = (function catalogCatalog() {
for (var i = 0, ii = kids.length; i < ii; ++i) {
var kid = kids[i];
assertWellFormed(isRef(kid),
'page dictionary kid is not a reference');
'page dictionary kid is not a reference');
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));
@ -195,8 +233,7 @@ var Catalog = (function catalogCatalog() {
}
},
get destinations() {
function fetchDestination(xref, ref) {
var dest = xref.fetchIfRef(ref);
function fetchDestination(dest) {
return isDict(dest) ? dest.get('D') : dest;
}
@ -204,16 +241,16 @@ var Catalog = (function catalogCatalog() {
var dests = {}, nameTreeRef, nameDictionaryRef;
var obj = this.catDict.get('Names');
if (obj)
nameTreeRef = xref.fetchIfRef(obj).get('Dests');
nameTreeRef = obj.getRaw('Dests');
else if (this.catDict.has('Dests'))
nameDictionaryRef = this.catDict.get('Dests');
if (nameDictionaryRef) {
// reading simple destination dictionary
obj = xref.fetchIfRef(nameDictionaryRef);
obj = nameDictionaryRef;
obj.forEach(function catalogForEach(key, value) {
if (!value) return;
dests[key] = fetchDestination(xref, value);
dests[key] = fetchDestination(value);
});
}
if (nameTreeRef) {
@ -237,13 +274,13 @@ var Catalog = (function catalogCatalog() {
}
var names = obj.get('Names');
for (i = 0, n = names.length; i < n; i += 2) {
dests[names[i]] = fetchDestination(xref, names[i + 1]);
dests[names[i]] = fetchDestination(xref.fetchIfRef(names[i + 1]));
}
}
}
return shadow(this, 'destinations', dests);
},
getPage: function catalogGetPage(n) {
getPage: function Catalog_getPage(n) {
var pageCache = this.pageCache;
if (!pageCache) {
pageCache = this.pageCache = [];
@ -253,105 +290,101 @@ var Catalog = (function catalogCatalog() {
}
};
return constructor;
return Catalog;
})();
var XRef = (function xRefXRef() {
function constructor(stream, startXRef, mainXRefEntriesOffset) {
var XRef = (function XRefClosure() {
function XRef(stream, startXRef, mainXRefEntriesOffset) {
this.stream = stream;
this.entries = [];
this.xrefstms = {};
var trailerDict = this.readXRef(startXRef);
trailerDict.xref = 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(this.fetch(encrypt),
this.encrypt = new CipherTransformFactory(encrypt,
fileId[0] /*, password */);
}
// get the root dictionary (catalog) object
if (!isRef(this.root = trailerDict.get('Root')))
if (!(this.root = trailerDict.get('Root')))
error('Invalid root reference');
}
constructor.prototype = {
readXRefTable: function readXRefTable(parser) {
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 (true) {
if (isCmd(obj = parser.getObj(), 'trailer'))
break;
if (!isInt(obj))
error('Invalid XRef table');
var first = obj;
if (!isInt(obj = parser.getObj()))
error('Invalid XRef table');
var n = obj;
if (first < 0 || n < 0 || (first + n) != ((first + n) | 0))
error('Invalid XRef table: ' + first + ', ' + n);
for (var i = first; i < first + n; ++i) {
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 = {};
if (!isInt(obj = parser.getObj()))
error('Invalid XRef table: ' + first + ', ' + n);
entry.offset = obj;
if (!isInt(obj = parser.getObj()))
error('Invalid XRef table: ' + first + ', ' + n);
entry.gen = obj;
obj = parser.getObj();
if (isCmd(obj, 'n')) {
entry.uncompressed = true;
} else if (isCmd(obj, 'f')) {
entry.offset = parser.getObj();
entry.gen = parser.getObj();
var type = parser.getObj();
if (isCmd(type, 'f'))
entry.free = true;
} else {
error('Invalid XRef table: ' + first + ', ' + n);
}
if (!this.entries[i]) {
// In some buggy PDF files the xref table claims to start at 1
// instead of 0.
if (i == 1 && first == 1 &&
entry.offset == 0 && entry.gen == 65535 && entry.free) {
i = first = 0;
}
this.entries[i] = entry;
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;
}
}
// read the trailer dictionary
var dict;
if (!isDict(dict = parser.getObj()))
error('Invalid XRef table');
// Sanity check: as per spec, first object must have these properties
if (this.entries[0] &&
!(this.entries[0].gen === 65535 && this.entries[0].free))
error('Invalid XRef table: unexpected first object');
// get the 'Prev' pointer
var prev;
obj = dict.get('Prev');
if (isInt(obj)) {
prev = obj;
} else if (isRef(obj)) {
// certain buggy PDF generators generate "/Prev NNN 0 R" instead
// of "/Prev NNN"
prev = obj.num;
}
if (prev) {
this.readXRef(prev);
}
// Sanity check
if (!isCmd(obj, 'trailer'))
error('Invalid XRef table: could not find trailer dictionary');
// check for 'XRefStm' key
if (isInt(obj = dict.get('XRefStm'))) {
var pos = obj;
// ignore previously loaded xref streams (possible infinite recursion)
if (!(pos in this.xrefstms)) {
this.xrefstms[pos] = 1;
this.readXRef(pos);
}
}
// 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 readXRefStream(stream) {
readXRefStream: function XRef_readXRefStream(stream) {
var streamParameters = stream.parameters;
var byteWidths = streamParameters.get('W');
var range = streamParameters.get('Index');
@ -400,12 +433,9 @@ var XRef = (function xRefXRef() {
}
range.splice(0, 2);
}
var prev = streamParameters.get('Prev');
if (isInt(prev))
this.readXRef(prev);
return streamParameters;
},
indexObjects: function indexObjects() {
indexObjects: function XRef_indexObjects() {
// Simple scan through the PDF content to find objects,
// trailers and XRef streams.
function readToken(data, offset) {
@ -497,7 +527,7 @@ var XRef = (function xRefXRef() {
var dict;
for (var i = 0, ii = trailers.length; i < ii; ++i) {
stream.pos = trailers[i];
var parser = new Parser(new Lexer(stream), true);
var parser = new Parser(new Lexer(stream), true, null);
var obj = parser.getObj();
if (!isCmd(obj, 'trailer'))
continue;
@ -513,50 +543,88 @@ var XRef = (function xRefXRef() {
return dict;
// nothing helps
error('Invalid PDF structure');
return null;
},
readXRef: function readXref(startXRef) {
readXRef: function XRef_readXRef(startXRef) {
var stream = this.stream;
stream.pos = startXRef;
var parser = new Parser(new Lexer(stream), true);
var obj = parser.getObj();
// parse an old-style xref table
if (isCmd(obj, 'xref'))
return this.readXRefTable(parser);
// parse an xref stream
if (isInt(obj)) {
if (!isInt(parser.getObj()) ||
!isCmd(parser.getObj(), 'obj') ||
!isStream(obj = parser.getObj())) {
error('Invalid XRef stream');
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())) {
error('Invalid XRef stream');
}
dict = this.readXRefStream(obj);
}
return this.readXRefStream(obj);
// Recursively get previous dictionary, if any
obj = dict.get('Prev');
if (isInt(obj))
this.readXRef(obj);
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);
}
return dict;
} catch (e) {
log('(while reading XRef): ' + e);
}
warn('Indexing all PDF objects');
return this.indexObjects();
},
getEntry: function xRefGetEntry(i) {
getEntry: function XRef_getEntry(i) {
var e = this.entries[i];
if (e.free)
error('reading an XRef stream not implemented yet');
return e;
if (e === null)
return null;
return e.free ? null : e; // returns null is the entry is free
},
fetchIfRef: function xRefFetchIfRef(obj) {
fetchIfRef: function XRef_fetchIfRef(obj) {
if (!isRef(obj))
return obj;
return this.fetch(obj);
},
fetch: function xRefFetch(ref, suppressEncryption) {
fetch: function XRef_fetch(ref, suppressEncryption) {
assertWellFormed(isRef(ref), 'ref object is not a reference');
var num = ref.num;
var e = this.cache[num];
if (e)
return e;
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);
e = this.getEntry(num);
var gen = ref.gen;
var stream, parser;
if (e.uncompressed) {
if (e.gen != gen)
throw ('inconsistent generation in XRef');
error('inconsistent generation in XRef');
stream = this.stream.makeSubStream(e.offset);
parser = new Parser(new Lexer(stream), true, this);
var obj1 = parser.getObj();
@ -589,7 +657,7 @@ var XRef = (function xRefXRef() {
e = parser.getObj();
}
// Don't cache streams since they are mutable (except images).
if (!isStream(e) || e.getImage)
if (!isStream(e) || e instanceof JpegStream)
this.cache[num] = e;
return e;
}
@ -603,7 +671,7 @@ var XRef = (function xRefXRef() {
if (!isInt(first) || !isInt(n)) {
error('invalid first and n parameters for ObjStm stream');
}
parser = new Parser(new Lexer(stream), false);
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) {
@ -628,12 +696,12 @@ var XRef = (function xRefXRef() {
}
return e;
},
getCatalogObj: function xRefGetCatalogObj() {
return this.fetch(this.root);
getCatalogObj: function XRef_getCatalogObj() {
return this.root;
}
};
return constructor;
return XRef;
})();
/**
@ -642,7 +710,7 @@ var XRef = (function xRefXRef() {
* inside of a worker. The `PDFObjects` implements some basic functions to
* manage these objects.
*/
var PDFObjects = (function pdfObjects() {
var PDFObjects = (function PDFObjectsClosure() {
function PDFObjects() {
this.objs = {};
}
@ -655,7 +723,7 @@ var PDFObjects = (function pdfObjects() {
* Ensures there is an object defined for `objId`. Stores `data` on the
* object *if* it is created.
*/
ensureObj: function pdfObjectsEnsureObj(objId, data) {
ensureObj: function PDFObjects_ensureObj(objId, data) {
if (this.objs[objId])
return this.objs[objId];
return this.objs[objId] = new Promise(objId, data);
@ -670,7 +738,7 @@ var PDFObjects = (function pdfObjects() {
* function and the object is already resolved, the callback gets called
* right away.
*/
get: function pdfObjectsGet(objId, callback) {
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) {
@ -684,18 +752,16 @@ var PDFObjects = (function pdfObjects() {
// If there isn't an object yet or the object isn't resolved, then the
// data isn't ready yet!
if (!obj || !obj.isResolved) {
throw 'Requesting object that isn\'t resolved yet ' + objId;
return null;
} else {
return obj.data;
}
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 pdfObjectsResolve(objId, data) {
resolve: function PDFObjects_resolve(objId, data) {
var objs = this.objs;
// In case there is a promise already on this object, just resolve it.
@ -706,11 +772,11 @@ var PDFObjects = (function pdfObjects() {
}
},
onData: function pdfObjectsOnData(objId, callback) {
onData: function PDFObjects_onData(objId, callback) {
this.ensureObj(objId).onData(callback);
},
isResolved: function pdfObjectsIsResolved(objId) {
isResolved: function PDFObjects_isResolved(objId) {
var objs = this.objs;
if (!objs[objId]) {
return false;
@ -719,7 +785,7 @@ var PDFObjects = (function pdfObjects() {
}
},
hasData: function pdfObjectsHasData(objId) {
hasData: function PDFObjects_hasData(objId) {
var objs = this.objs;
if (!objs[objId]) {
return false;
@ -731,7 +797,7 @@ var PDFObjects = (function pdfObjects() {
/**
* Sets the data of an object but *doesn't* resolve it.
*/
setData: function pdfObjectsSetData(objId, data) {
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;

181
apps/files_pdfviewer/js/pdfjs/src/parser.js Executable file → Normal file
View File

@ -9,8 +9,8 @@ function isEOF(v) {
return v == EOF;
}
var Parser = (function parserParser() {
function constructor(lexer, allowStreams, xref) {
var Parser = (function ParserClosure() {
function Parser(lexer, allowStreams, xref) {
this.lexer = lexer;
this.allowStreams = allowStreams;
this.xref = xref;
@ -18,12 +18,12 @@ var Parser = (function parserParser() {
this.refill();
}
constructor.prototype = {
refill: function parserRefill() {
Parser.prototype = {
refill: function Parser_refill() {
this.buf1 = this.lexer.getObj();
this.buf2 = this.lexer.getObj();
},
shift: function parserShift() {
shift: function Parser_shift() {
if (isCmd(this.buf2, 'ID')) {
this.buf1 = this.buf2;
this.buf2 = null;
@ -34,7 +34,7 @@ var Parser = (function parserParser() {
this.buf2 = this.lexer.getObj();
}
},
getObj: function parserGetObj(cipherTransform) {
getObj: function Parser_getObj(cipherTransform) {
if (isCmd(this.buf1, 'BI')) { // inline image
this.shift();
return this.makeInlineImage(cipherTransform);
@ -51,17 +51,16 @@ var Parser = (function parserParser() {
}
if (isCmd(this.buf1, '<<')) { // dictionary or stream
this.shift();
var dict = new Dict();
var dict = new Dict(this.xref);
while (!isCmd(this.buf1, '>>') && !isEOF(this.buf1)) {
if (!isName(this.buf1)) {
if (!isName(this.buf1))
error('Dictionary key must be a name object');
} else {
var key = this.buf1.name;
this.shift();
if (isEOF(this.buf1))
break;
dict.set(key, this.getObj(cipherTransform));
}
var key = this.buf1.name;
this.shift();
if (isEOF(this.buf1))
break;
dict.set(key, this.getObj(cipherTransform));
}
if (isEOF(this.buf1))
error('End of file inside dictionary');
@ -99,38 +98,37 @@ var Parser = (function parserParser() {
this.shift();
return obj;
},
makeInlineImage: function parserMakeInlineImage(cipherTransform) {
makeInlineImage: function Parser_makeInlineImage(cipherTransform) {
var lexer = this.lexer;
var stream = lexer.stream;
// parse dictionary
var dict = new Dict();
while (!isCmd(this.buf1, 'ID') && !isEOF(this.buf1)) {
if (!isName(this.buf1)) {
if (!isName(this.buf1))
error('Dictionary key must be a name object');
} else {
var key = this.buf1.name;
this.shift();
if (isEOF(this.buf1))
break;
dict.set(key, this.getObj(cipherTransform));
}
var key = this.buf1.name;
this.shift();
if (isEOF(this.buf1))
break;
dict.set(key, this.getObj(cipherTransform));
}
// parse image stream
var startPos = stream.pos;
// searching for the /\sEI\s/
// searching for the /EI\s/
var state = 0, ch;
while (state != 4 && (ch = stream.getByte()) != null) {
switch (ch) {
case 0x20:
case 0x0D:
case 0x0A:
state = state === 3 ? 4 : 1;
state = state === 3 ? 4 : 0;
break;
case 0x45:
state = state === 1 ? 2 : 0;
state = 2;
break;
case 0x49:
state = state === 2 ? 3 : 0;
@ -157,12 +155,16 @@ var Parser = (function parserParser() {
imageStream = this.filter(imageStream, dict, length);
imageStream.parameters = dict;
this.buf2 = new Cmd('EI');
this.buf2 = Cmd.get('EI');
this.shift();
return imageStream;
},
makeStream: function parserMakeStream(dict, cipherTransform) {
fetchIfRef: function Parser_fetchIfRef(obj) {
// not relying on the xref.fetchIfRef -- xref might not be set
return isRef(obj) ? this.xref.fetch(obj) : obj;
},
makeStream: function Parser_makeStream(dict, cipherTransform) {
var lexer = this.lexer;
var stream = lexer.stream;
@ -171,14 +173,9 @@ var Parser = (function parserParser() {
var pos = stream.pos;
// get length
var length = dict.get('Length');
var xref = this.xref;
if (xref)
length = xref.fetchIfRef(length);
if (!isInt(length)) {
var length = this.fetchIfRef(dict.get('Length'));
if (!isInt(length))
error('Bad ' + length + ' attribute in stream');
length = 0;
}
// skip over the stream data
stream.pos = pos + length;
@ -195,9 +192,9 @@ var Parser = (function parserParser() {
stream.parameters = dict;
return stream;
},
filter: function parserFilter(stream, dict, length) {
var filter = dict.get('Filter', 'F');
var params = dict.get('DecodeParms', 'DP');
filter: function Parser_filter(stream, dict, length) {
var filter = this.fetchIfRef(dict.get('Filter', 'F'));
var params = this.fetchIfRef(dict.get('DecodeParms', 'DP'));
if (isName(filter))
return this.makeFilter(stream, filter.name, length, params);
if (isArray(filter)) {
@ -207,25 +204,25 @@ var Parser = (function parserParser() {
filter = filterArray[i];
if (!isName(filter))
error('Bad filter name: ' + filter);
else {
params = null;
if (isArray(paramsArray) && (i in paramsArray))
params = paramsArray[i];
stream = this.makeFilter(stream, filter.name, length, params);
// after the first stream the length variable is invalid
length = null;
}
params = null;
if (isArray(paramsArray) && (i in paramsArray))
params = paramsArray[i];
stream = this.makeFilter(stream, filter.name, length, params);
// after the first stream the length variable is invalid
length = null;
}
}
return stream;
},
makeFilter: function parserMakeFilter(stream, name, length, params) {
makeFilter: function Parser_makeFilter(stream, name, length, params) {
if (name == 'FlateDecode' || name == 'Fl') {
if (params) {
return new PredictorStream(new FlateStream(stream), params);
}
return new FlateStream(stream);
} else if (name == 'LZWDecode' || name == 'LZW') {
}
if (name == 'LZWDecode' || name == 'LZW') {
var earlyChange = 1;
if (params) {
if (params.has('EarlyChange'))
@ -234,31 +231,41 @@ var Parser = (function parserParser() {
new LZWStream(stream, earlyChange), params);
}
return new LZWStream(stream, earlyChange);
} else if (name == 'DCTDecode' || name == 'DCT') {
}
if (name == 'DCTDecode' || name == 'DCT') {
var bytes = stream.getBytes(length);
return new JpegStream(bytes, stream.dict, this.xref);
} else if (name == 'ASCII85Decode' || name == 'A85') {
return new Ascii85Stream(stream);
} else if (name == 'ASCIIHexDecode' || name == 'AHx') {
return new AsciiHexStream(stream);
} else if (name == 'CCITTFaxDecode' || name == 'CCF') {
return new CCITTFaxStream(stream, params);
} else {
TODO('filter "' + name + '" not supported yet');
}
if (name == 'JPXDecode' || name == 'JPX') {
var bytes = stream.getBytes(length);
return new JpxStream(bytes, stream.dict);
}
if (name == 'ASCII85Decode' || name == 'A85') {
return new Ascii85Stream(stream);
}
if (name == 'ASCIIHexDecode' || name == 'AHx') {
return new AsciiHexStream(stream);
}
if (name == 'CCITTFaxDecode' || name == 'CCF') {
return new CCITTFaxStream(stream, params);
}
if (name == 'RunLengthDecode') {
return new RunLengthStream(stream);
}
warn('filter "' + name + '" not supported yet');
return stream;
}
};
return constructor;
return Parser;
})();
var Lexer = (function lexer() {
function constructor(stream) {
var Lexer = (function LexerClosure() {
function Lexer(stream) {
this.stream = stream;
}
constructor.isSpace = function lexerIsSpace(ch) {
Lexer.isSpace = function Lexer_isSpace(ch) {
return ch == ' ' || ch == '\t' || ch == '\x0d' || ch == '\x0a';
};
@ -292,8 +299,8 @@ var Lexer = (function lexer() {
return -1;
}
constructor.prototype = {
getNumber: function lexerGetNumber(ch) {
Lexer.prototype = {
getNumber: function Lexer_getNumber(ch) {
var floating = false;
var str = ch;
var stream = this.stream;
@ -321,7 +328,7 @@ var Lexer = (function lexer() {
error('Invalid floating point number: ' + value);
return value;
},
getString: function lexerGetString() {
getString: function Lexer_getString() {
var numParen = 1;
var done = false;
var str = '';
@ -405,7 +412,7 @@ var Lexer = (function lexer() {
} while (!done);
return str;
},
getName: function lexerGetName(ch) {
getName: function Lexer_getName(ch) {
var str = '';
var stream = this.stream;
while (!!(ch = stream.lookChar()) && !specialChars[ch.charCodeAt(0)]) {
@ -432,7 +439,7 @@ var Lexer = (function lexer() {
str.length);
return new Name(str);
},
getHexString: function lexerGetHexString(ch) {
getHexString: function Lexer_getHexString(ch) {
var str = '';
var stream = this.stream;
for (;;) {
@ -461,7 +468,7 @@ var Lexer = (function lexer() {
}
return str;
},
getObj: function lexerGetObj() {
getObj: function Lexer_getObj() {
// skip whitespace and comments
var comment = false;
var stream = this.stream;
@ -492,14 +499,14 @@ var Lexer = (function lexer() {
// array punctuation
case '[':
case ']':
return new Cmd(ch);
return Cmd.get(ch);
// hex string or dict punctuation
case '<':
ch = stream.lookChar();
if (ch == '<') {
// dict punctuation
stream.skip();
return new Cmd('<<');
return Cmd.get('<<');
}
return this.getHexString(ch);
// dict punctuation
@ -507,25 +514,23 @@ var Lexer = (function lexer() {
ch = stream.lookChar();
if (ch == '>') {
stream.skip();
return new Cmd('>>');
return Cmd.get('>>');
}
case '{':
case '}':
return new Cmd(ch);
return Cmd.get(ch);
// fall through
case ')':
error('Illegal character: ' + ch);
return Error;
}
// command
var str = ch;
while (!!(ch = stream.lookChar()) && !specialChars[ch.charCodeAt(0)]) {
stream.skip();
if (str.length == 128) {
if (str.length == 128)
error('Command token too long: ' + str.length);
break;
}
str += ch;
}
if (str == 'true')
@ -534,9 +539,9 @@ var Lexer = (function lexer() {
return false;
if (str == 'null')
return null;
return new Cmd(str);
return Cmd.get(str);
},
skipToNextLine: function lexerSkipToNextLine() {
skipToNextLine: function Lexer_skipToNextLine() {
var stream = this.stream;
while (true) {
var ch = stream.getChar();
@ -549,17 +554,17 @@ var Lexer = (function lexer() {
}
}
},
skip: function lexerSkip() {
skip: function Lexer_skip() {
this.stream.skip();
}
};
return constructor;
return Lexer;
})();
var Linearization = (function linearizationLinearization() {
function constructor(stream) {
this.parser = new Parser(new Lexer(stream), false);
var Linearization = (function LinearizationClosure() {
function Linearization(stream) {
this.parser = new Parser(new Lexer(stream), false, null);
var obj1 = this.parser.getObj();
var obj2 = this.parser.getObj();
var obj3 = this.parser.getObj();
@ -572,8 +577,8 @@ var Linearization = (function linearizationLinearization() {
}
}
constructor.prototype = {
getInt: function linearizationGetInt(name) {
Linearization.prototype = {
getInt: function Linearization_getInt(name) {
var linDict = this.linDict;
var obj;
if (isDict(linDict) &&
@ -582,9 +587,8 @@ var Linearization = (function linearizationLinearization() {
return obj;
}
error('"' + name + '" field in linearization table is invalid');
return 0;
},
getHint: function linearizationGetHint(index) {
getHint: function Linearization_getHint(index) {
var linDict = this.linDict;
var obj1, obj2;
if (isDict(linDict) &&
@ -595,7 +599,6 @@ var Linearization = (function linearizationLinearization() {
return obj2;
}
error('Hints table in linearization table is invalid: ' + index);
return 0;
},
get length() {
if (!isDict(this.linDict))
@ -631,6 +634,6 @@ var Linearization = (function linearizationLinearization() {
}
};
return constructor;
return Linearization;
})();

148
apps/files_pdfviewer/js/pdfjs/src/pattern.js Executable file → Normal file
View File

@ -3,48 +3,53 @@
'use strict';
var Pattern = (function patternPattern() {
var PatternType = {
AXIAL: 2,
RADIAL: 3
};
var Pattern = (function PatternClosure() {
// Constructor should define this.getPattern
function constructor() {
function Pattern() {
error('should not call Pattern constructor');
}
constructor.prototype = {
Pattern.prototype = {
// Input: current Canvas context
// Output: the appropriate fillStyle or strokeStyle
getPattern: function pattern_getStyle(ctx) {
getPattern: function Pattern_getPattern(ctx) {
error('Should not call Pattern.getStyle: ' + ctx);
}
};
constructor.shadingFromIR = function pattern_shadingFromIR(ctx, raw) {
return Shadings[raw[0]].fromIR(ctx, raw);
Pattern.shadingFromIR = function Pattern_shadingFromIR(raw) {
return Shadings[raw[0]].fromIR(raw);
};
constructor.parseShading = function pattern_shading(shading, matrix, xref,
res, ctx) {
Pattern.parseShading = function Pattern_parseShading(shading, matrix, xref,
res) {
var dict = isStream(shading) ? shading.dict : shading;
var type = dict.get('ShadingType');
switch (type) {
case 2:
case 3:
// both radial and axial shadings are handled by RadialAxial shading
return new Shadings.RadialAxial(dict, matrix, xref, res, ctx);
case PatternType.AXIAL:
case PatternType.RADIAL:
// Both radial and axial shadings are handled by RadialAxial shading.
return new Shadings.RadialAxial(dict, matrix, xref, res);
default:
return new Shadings.Dummy();
}
};
return constructor;
return Pattern;
})();
var Shadings = {};
// Radial and axial shading have very similar implementations
// If needed, the implementations can be broken into two classes
Shadings.RadialAxial = (function radialAxialShading() {
function constructor(dict, matrix, xref, res, ctx) {
Shadings.RadialAxial = (function RadialAxialClosure() {
function RadialAxial(dict, matrix, xref, res, ctx) {
this.matrix = matrix;
this.coordsArr = dict.get('Coords');
this.shadingType = dict.get('ShadingType');
@ -74,10 +79,9 @@ Shadings.RadialAxial = (function radialAxialShading() {
this.extendEnd = extendEnd;
var fnObj = dict.get('Function');
fnObj = xref.fetchIfRef(fnObj);
if (isArray(fnObj))
error('No support for array of functions');
else if (!isPDFFunction(fnObj))
if (!isPDFFunction(fnObj))
error('Invalid function');
var fn = PDFFunction.parse(xref, fnObj);
@ -89,56 +93,60 @@ Shadings.RadialAxial = (function radialAxialShading() {
var colorStops = [];
for (var i = t0; i <= t1; i += step) {
var color = fn([i]);
var rgbColor = Util.makeCssRgb.apply(this, cs.getRgb(color));
colorStops.push([(i - t0) / diff, rgbColor]);
var rgbColor = cs.getRgb(fn([i]));
var cssColor = Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]);
colorStops.push([(i - t0) / diff, cssColor]);
}
this.colorStops = colorStops;
}
constructor.fromIR = function radialAxialShadingGetIR(ctx, raw) {
RadialAxial.fromIR = function RadialAxial_fromIR(raw) {
var type = raw[1];
var colorStops = raw[2];
var p0 = raw[3];
var p1 = raw[4];
var r0 = raw[5];
var r1 = raw[6];
return {
type: 'Pattern',
getPattern: function(ctx) {
var curMatrix = ctx.mozCurrentTransform;
if (curMatrix) {
var userMatrix = ctx.mozCurrentTransformInverse;
var curMatrix = ctx.mozCurrentTransform;
if (curMatrix) {
var userMatrix = ctx.mozCurrentTransformInverse;
p0 = Util.applyTransform(p0, curMatrix);
p0 = Util.applyTransform(p0, userMatrix);
p0 = Util.applyTransform(p0, curMatrix);
p0 = Util.applyTransform(p0, userMatrix);
p1 = Util.applyTransform(p1, curMatrix);
p1 = Util.applyTransform(p1, userMatrix);
}
p1 = Util.applyTransform(p1, curMatrix);
p1 = Util.applyTransform(p1, userMatrix);
}
var grad;
if (type == PatternType.AXIAL)
grad = ctx.createLinearGradient(p0[0], p0[1], p1[0], p1[1]);
else if (type == PatternType.RADIAL)
grad = ctx.createRadialGradient(p0[0], p0[1], r0, p1[0], p1[1], r1);
var grad;
if (type == 2)
grad = ctx.createLinearGradient(p0[0], p0[1], p1[0], p1[1]);
else if (type == 3)
grad = ctx.createRadialGradient(p0[0], p0[1], r0, p1[0], p1[1], r1);
for (var i = 0, ii = colorStops.length; i < ii; ++i) {
var c = colorStops[i];
grad.addColorStop(c[0], c[1]);
}
return grad;
for (var i = 0, ii = colorStops.length; i < ii; ++i) {
var c = colorStops[i];
grad.addColorStop(c[0], c[1]);
}
return grad;
}
};
};
constructor.prototype = {
getIR: function radialAxialShadingGetIR() {
RadialAxial.prototype = {
getIR: function RadialAxial_getIR() {
var coordsArr = this.coordsArr;
var type = this.shadingType;
if (type == 2) {
if (type == PatternType.AXIAL) {
var p0 = [coordsArr[0], coordsArr[1]];
var p1 = [coordsArr[2], coordsArr[3]];
var r0 = null;
var r1 = null;
} else if (type == 3) {
} else if (type == PatternType.RADIAL) {
var p0 = [coordsArr[0], coordsArr[1]];
var p1 = [coordsArr[3], coordsArr[4]];
var r0 = coordsArr[2];
@ -157,31 +165,35 @@ Shadings.RadialAxial = (function radialAxialShading() {
}
};
return constructor;
return RadialAxial;
})();
Shadings.Dummy = (function dummyShading() {
function constructor() {
Shadings.Dummy = (function DummyClosure() {
function Dummy() {
this.type = 'Pattern';
}
constructor.fromIR = function dummyShadingFromIR() {
Dummy.fromIR = function Dummy_fromIR() {
return 'hotpink';
};
constructor.prototype = {
getIR: function dummyShadingGetIR() {
Dummy.prototype = {
getIR: function Dummy_getIR() {
return ['Dummy'];
}
};
return constructor;
return Dummy;
})();
var TilingPattern = (function tilingPattern() {
var PAINT_TYPE_COLORED = 1, PAINT_TYPE_UNCOLORED = 2;
var TilingPattern = (function TilingPatternClosure() {
var PaintType = {
COLORED: 1,
UNCOLORED: 2
};
var MAX_PATTERN_SIZE = 512;
function TilingPattern(IR, color, ctx, objs) {
var IRQueue = IR[2];
var operatorList = IR[2];
this.matrix = IR[3];
var bbox = IR[4];
var xstep = IR[5];
@ -204,30 +216,30 @@ var TilingPattern = (function tilingPattern() {
var width = botRight[0] - topLeft[0];
var height = botRight[1] - topLeft[1];
// TODO: hack to avoid OOM, we would idealy compute the tiling
// TODO: hack to avoid OOM, we would ideally compute the tiling
// pattern to be only as large as the acual size in device space
// This could be computed with .mozCurrentTransform, but still
// needs to be implemented
while (Math.abs(width) > 512 || Math.abs(height) > 512) {
width = 512;
height = 512;
while (Math.abs(width) > MAX_PATTERN_SIZE ||
Math.abs(height) > MAX_PATTERN_SIZE) {
width = height = MAX_PATTERN_SIZE;
}
var tmpCanvas = new ScratchCanvas(width, height);
var tmpCanvas = createScratchCanvas(width, height);
// set the new canvas element context as the graphics context
var tmpCtx = tmpCanvas.getContext('2d');
var graphics = new CanvasGraphics(tmpCtx, objs);
switch (paintType) {
case PAINT_TYPE_COLORED:
case PaintType.COLORED:
tmpCtx.fillStyle = ctx.fillStyle;
tmpCtx.strokeStyle = ctx.strokeStyle;
break;
case PAINT_TYPE_UNCOLORED:
color = Util.makeCssRgb.apply(this, color);
tmpCtx.fillStyle = color;
tmpCtx.strokeStyle = color;
case PaintType.UNCOLORED:
var cssColor = Util.makeCssRgb(this, color[0], color[1], color[2]);
tmpCtx.fillStyle = cssColor;
tmpCtx.strokeStyle = cssColor;
break;
default:
error('Unsupported paint type: ' + paintType);
@ -250,12 +262,12 @@ var TilingPattern = (function tilingPattern() {
graphics.endPath();
}
graphics.executeIRQueue(IRQueue);
graphics.executeOperatorList(operatorList);
this.canvas = tmpCanvas;
}
TilingPattern.getIR = function tiling_getIR(codeIR, dict, args) {
TilingPattern.getIR = function TilingPattern_getIR(operatorList, dict, args) {
var matrix = dict.get('Matrix');
var bbox = dict.get('BBox');
var xstep = dict.get('XStep');
@ -263,12 +275,12 @@ var TilingPattern = (function tilingPattern() {
var paintType = dict.get('PaintType');
return [
'TilingPattern', args, codeIR, matrix, bbox, xstep, ystep, paintType
'TilingPattern', args, operatorList, matrix, bbox, xstep, ystep, paintType
];
};
TilingPattern.prototype = {
getPattern: function tiling_getPattern() {
getPattern: function TilingPattern_getPattern() {
var matrix = this.matrix;
var curMatrix = this.curMatrix;
var ctx = this.ctx;

0
apps/files_pdfviewer/js/pdfjs/src/pdf.js Executable file → Normal file
View File

487
apps/files_pdfviewer/js/pdfjs/src/stream.js Executable file → Normal file
View File

@ -3,8 +3,8 @@
'use strict';
var Stream = (function streamStream() {
function constructor(arrayBuffer, start, length, dict) {
var Stream = (function StreamClosure() {
function Stream(arrayBuffer, start, length, dict) {
this.bytes = new Uint8Array(arrayBuffer);
this.start = start || 0;
this.pos = this.start;
@ -14,18 +14,18 @@ var Stream = (function streamStream() {
// required methods for a stream. if a particular stream does not
// implement these, an error should be thrown
constructor.prototype = {
Stream.prototype = {
get length() {
return this.end - this.start;
},
getByte: function stream_getByte() {
getByte: function Stream_getByte() {
if (this.pos >= this.end)
return null;
return this.bytes[this.pos++];
},
// returns subarray of original buffer
// should only be read
getBytes: function stream_getBytes(length) {
getBytes: function Stream_getBytes(length) {
var bytes = this.bytes;
var pos = this.pos;
var strEnd = this.end;
@ -40,38 +40,38 @@ var Stream = (function streamStream() {
this.pos = end;
return bytes.subarray(pos, end);
},
lookChar: function stream_lookChar() {
lookChar: function Stream_lookChar() {
if (this.pos >= this.end)
return null;
return String.fromCharCode(this.bytes[this.pos]);
},
getChar: function stream_getChar() {
getChar: function Stream_getChar() {
if (this.pos >= this.end)
return null;
return String.fromCharCode(this.bytes[this.pos++]);
},
skip: function stream_skip(n) {
skip: function Stream_skip(n) {
if (!n)
n = 1;
this.pos += n;
},
reset: function stream_reset() {
reset: function Stream_reset() {
this.pos = this.start;
},
moveStart: function stream_moveStart() {
moveStart: function Stream_moveStart() {
this.start = this.pos;
},
makeSubStream: function stream_makeSubstream(start, length, dict) {
makeSubStream: function Stream_makeSubStream(start, length, dict) {
return new Stream(this.bytes.buffer, start, length, dict);
},
isStream: true
};
return constructor;
return Stream;
})();
var StringStream = (function stringStream() {
function constructor(str) {
var StringStream = (function StringStreamClosure() {
function StringStream(str) {
var length = str.length;
var bytes = new Uint8Array(length);
for (var n = 0; n < length; ++n)
@ -79,22 +79,22 @@ var StringStream = (function stringStream() {
Stream.call(this, bytes);
}
constructor.prototype = Stream.prototype;
StringStream.prototype = Stream.prototype;
return constructor;
return StringStream;
})();
// super class for the decoding streams
var DecodeStream = (function decodeStream() {
function constructor() {
var DecodeStream = (function DecodeStreamClosure() {
function DecodeStream() {
this.pos = 0;
this.bufferLength = 0;
this.eof = false;
this.buffer = null;
}
constructor.prototype = {
ensureBuffer: function decodestream_ensureBuffer(requested) {
DecodeStream.prototype = {
ensureBuffer: function DecodeStream_ensureBuffer(requested) {
var buffer = this.buffer;
var current = buffer ? buffer.byteLength : 0;
if (requested < current)
@ -107,7 +107,7 @@ var DecodeStream = (function decodeStream() {
buffer2[i] = buffer[i];
return (this.buffer = buffer2);
},
getByte: function decodestream_getByte() {
getByte: function DecodeStream_getByte() {
var pos = this.pos;
while (this.bufferLength <= pos) {
if (this.eof)
@ -116,7 +116,7 @@ var DecodeStream = (function decodeStream() {
}
return this.buffer[this.pos++];
},
getBytes: function decodestream_getBytes(length) {
getBytes: function DecodeStream_getBytes(length) {
var end, pos = this.pos;
if (length) {
@ -144,7 +144,7 @@ var DecodeStream = (function decodeStream() {
this.pos = end;
return this.buffer.subarray(pos, end);
},
lookChar: function decodestream_lookChar() {
lookChar: function DecodeStream_lookChar() {
var pos = this.pos;
while (this.bufferLength <= pos) {
if (this.eof)
@ -153,7 +153,7 @@ var DecodeStream = (function decodeStream() {
}
return String.fromCharCode(this.buffer[this.pos]);
},
getChar: function decodestream_getChar() {
getChar: function DecodeStream_getChar() {
var pos = this.pos;
while (this.bufferLength <= pos) {
if (this.eof)
@ -162,40 +162,40 @@ var DecodeStream = (function decodeStream() {
}
return String.fromCharCode(this.buffer[this.pos++]);
},
makeSubStream: function decodestream_makeSubstream(start, length, dict) {
makeSubStream: function DecodeStream_makeSubStream(start, length, dict) {
var end = start + length;
while (this.bufferLength <= end && !this.eof)
this.readBlock();
return new Stream(this.buffer, start, length, dict);
},
skip: function decodestream_skip(n) {
skip: function DecodeStream_skip(n) {
if (!n)
n = 1;
this.pos += n;
},
reset: function decodestream_reset() {
reset: function DecodeStream_reset() {
this.pos = 0;
}
};
return constructor;
return DecodeStream;
})();
var FakeStream = (function fakeStream() {
function constructor(stream) {
var FakeStream = (function FakeStreamClosure() {
function FakeStream(stream) {
this.dict = stream.dict;
DecodeStream.call(this);
}
constructor.prototype = Object.create(DecodeStream.prototype);
constructor.prototype.readBlock = function fakeStreamReadBlock() {
FakeStream.prototype = Object.create(DecodeStream.prototype);
FakeStream.prototype.readBlock = function FakeStream_readBlock() {
var bufferLength = this.bufferLength;
bufferLength += 1024;
var buffer = this.ensureBuffer(bufferLength);
this.bufferLength = bufferLength;
};
constructor.prototype.getBytes = function fakeStreamGetBytes(length) {
FakeStream.prototype.getBytes = function FakeStream_getBytes(length) {
var end, pos = this.pos;
if (length) {
@ -217,18 +217,20 @@ var FakeStream = (function fakeStream() {
return this.buffer.subarray(pos, end);
};
return constructor;
return FakeStream;
})();
var StreamsSequenceStream = (function streamSequenceStream() {
function constructor(streams) {
var StreamsSequenceStream = (function StreamsSequenceStreamClosure() {
function StreamsSequenceStream(streams) {
this.streams = streams;
DecodeStream.call(this);
}
constructor.prototype = Object.create(DecodeStream.prototype);
StreamsSequenceStream.prototype = Object.create(DecodeStream.prototype);
StreamsSequenceStream.prototype.readBlock =
function streamSequenceStreamReadBlock() {
constructor.prototype.readBlock = function streamSequenceStreamReadBlock() {
var streams = this.streams;
if (streams.length == 0) {
this.eof = true;
@ -243,10 +245,10 @@ var StreamsSequenceStream = (function streamSequenceStream() {
this.bufferLength = newLength;
};
return constructor;
return StreamsSequenceStream;
})();
var FlateStream = (function flateStream() {
var FlateStream = (function FlateStreamClosure() {
var codeLenCodeMap = new Uint32Array([
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
]);
@ -339,7 +341,7 @@ var FlateStream = (function flateStream() {
0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000
]), 5];
function constructor(stream) {
function FlateStream(stream) {
var bytes = stream.getBytes();
var bytesPos = 0;
@ -364,9 +366,9 @@ var FlateStream = (function flateStream() {
DecodeStream.call(this);
}
constructor.prototype = Object.create(DecodeStream.prototype);
FlateStream.prototype = Object.create(DecodeStream.prototype);
constructor.prototype.getBits = function flateStreamGetBits(bits) {
FlateStream.prototype.getBits = function FlateStream_getBits(bits) {
var codeSize = this.codeSize;
var codeBuf = this.codeBuf;
var bytes = this.bytes;
@ -386,7 +388,7 @@ var FlateStream = (function flateStream() {
return b;
};
constructor.prototype.getCode = function flateStreamGetCode(table) {
FlateStream.prototype.getCode = function FlateStream_getCode(table) {
var codes = table[0];
var maxLen = table[1];
var codeSize = this.codeSize;
@ -412,7 +414,7 @@ var FlateStream = (function flateStream() {
return codeVal;
};
constructor.prototype.generateHuffmanTable =
FlateStream.prototype.generateHuffmanTable =
function flateStreamGenerateHuffmanTable(lengths) {
var n = lengths.length;
@ -451,7 +453,7 @@ var FlateStream = (function flateStream() {
return [codes, maxLen];
};
constructor.prototype.readBlock = function flateStreamReadBlock() {
FlateStream.prototype.readBlock = function FlateStream_readBlock() {
// read block header
var hdr = this.getBits(3);
if (hdr & 1)
@ -582,11 +584,11 @@ var FlateStream = (function flateStream() {
}
};
return constructor;
return FlateStream;
})();
var PredictorStream = (function predictorStream() {
function constructor(stream, params) {
var PredictorStream = (function PredictorStreamClosure() {
function PredictorStream(stream, params) {
var predictor = this.predictor = params.get('Predictor') || 1;
if (predictor <= 1)
@ -613,15 +615,14 @@ var PredictorStream = (function predictorStream() {
return this;
}
constructor.prototype = Object.create(DecodeStream.prototype);
PredictorStream.prototype = Object.create(DecodeStream.prototype);
constructor.prototype.readBlockTiff =
PredictorStream.prototype.readBlockTiff =
function predictorStreamReadBlockTiff() {
var rowBytes = this.rowBytes;
var bufferLength = this.bufferLength;
var buffer = this.ensureBuffer(bufferLength + rowBytes);
var currentRow = buffer.subarray(bufferLength, bufferLength + rowBytes);
var bits = this.bits;
var colors = this.colors;
@ -630,6 +631,7 @@ var PredictorStream = (function predictorStream() {
var inbuf = 0, outbuf = 0;
var inbits = 0, outbits = 0;
var pos = bufferLength;
if (bits === 1) {
for (var i = 0; i < rowBytes; ++i) {
@ -637,19 +639,21 @@ var PredictorStream = (function predictorStream() {
inbuf = (inbuf << 8) | c;
// bitwise addition is exclusive or
// first shift inbuf and then add
currentRow[i] = (c ^ (inbuf >> colors)) & 0xFF;
buffer[pos++] = (c ^ (inbuf >> colors)) & 0xFF;
// truncate inbuf (assumes colors < 16)
inbuf &= 0xFFFF;
}
} else if (bits === 8) {
for (var i = 0; i < colors; ++i)
currentRow[i] = rawBytes[i];
for (; i < rowBytes; ++i)
currentRow[i] = currentRow[i - colors] + rawBytes[i];
buffer[pos++] = rawBytes[i];
for (; i < rowBytes; ++i) {
buffer[pos] = buffer[pos - colors] + rawBytes[i];
pos++;
}
} else {
var compArray = new Uint8Array(colors + 1);
var bitMask = (1 << bits) - 1;
var j = 0, k = 0;
var j = 0, k = bufferLength;
var columns = this.columns;
for (var i = 0; i < columns; ++i) {
for (var kk = 0; kk < colors; ++kk) {
@ -663,20 +667,22 @@ var PredictorStream = (function predictorStream() {
outbuf = (outbuf << bits) | compArray[kk];
outbits += bits;
if (outbits >= 8) {
currentRow[k++] = (outbuf >> (outbits - 8)) & 0xFF;
buffer[k++] = (outbuf >> (outbits - 8)) & 0xFF;
outbits -= 8;
}
}
}
if (outbits > 0) {
currentRow[k++] = (outbuf << (8 - outbits)) +
buffer[k++] = (outbuf << (8 - outbits)) +
(inbuf & ((1 << (8 - outbits)) - 1));
}
}
this.bufferLength += rowBytes;
};
constructor.prototype.readBlockPng = function predictorStreamReadBlockPng() {
PredictorStream.prototype.readBlockPng =
function predictorStreamReadBlockPng() {
var rowBytes = this.rowBytes;
var pixBytes = this.pixBytes;
@ -686,32 +692,35 @@ var PredictorStream = (function predictorStream() {
var bufferLength = this.bufferLength;
var buffer = this.ensureBuffer(bufferLength + rowBytes);
var currentRow = buffer.subarray(bufferLength, bufferLength + rowBytes);
var prevRow = buffer.subarray(bufferLength - rowBytes, bufferLength);
if (prevRow.length == 0)
prevRow = new Uint8Array(rowBytes);
var j = bufferLength;
switch (predictor) {
case 0:
for (var i = 0; i < rowBytes; ++i)
currentRow[i] = rawBytes[i];
buffer[j++] = rawBytes[i];
break;
case 1:
for (var i = 0; i < pixBytes; ++i)
currentRow[i] = rawBytes[i];
for (; i < rowBytes; ++i)
currentRow[i] = (currentRow[i - pixBytes] + rawBytes[i]) & 0xFF;
buffer[j++] = rawBytes[i];
for (; i < rowBytes; ++i) {
buffer[j] = (buffer[j - pixBytes] + rawBytes[i]) & 0xFF;
j++;
}
break;
case 2:
for (var i = 0; i < rowBytes; ++i)
currentRow[i] = (prevRow[i] + rawBytes[i]) & 0xFF;
buffer[j++] = (prevRow[i] + rawBytes[i]) & 0xFF;
break;
case 3:
for (var i = 0; i < pixBytes; ++i)
currentRow[i] = (prevRow[i] >> 1) + rawBytes[i];
buffer[j++] = (prevRow[i] >> 1) + rawBytes[i];
for (; i < rowBytes; ++i) {
currentRow[i] = (((prevRow[i] + currentRow[i - pixBytes]) >> 1) +
buffer[j] = (((prevRow[i] + buffer[j - pixBytes]) >> 1) +
rawBytes[i]) & 0xFF;
j++;
}
break;
case 4:
@ -720,12 +729,12 @@ var PredictorStream = (function predictorStream() {
for (var i = 0; i < pixBytes; ++i) {
var up = prevRow[i];
var c = rawBytes[i];
currentRow[i] = up + c;
buffer[j++] = up + c;
}
for (; i < rowBytes; ++i) {
var up = prevRow[i];
var upLeft = prevRow[i - pixBytes];
var left = currentRow[i - pixBytes];
var left = buffer[j - pixBytes];
var p = left + up - upLeft;
var pa = p - left;
@ -740,11 +749,11 @@ var PredictorStream = (function predictorStream() {
var c = rawBytes[i];
if (pa <= pb && pa <= pc)
currentRow[i] = left + c;
buffer[j++] = left + c;
else if (pb <= pc)
currentRow[i] = up + c;
buffer[j++] = up + c;
else
currentRow[i] = upLeft + c;
buffer[j++] = upLeft + c;
}
break;
default:
@ -753,7 +762,7 @@ var PredictorStream = (function predictorStream() {
this.bufferLength += rowBytes;
};
return constructor;
return PredictorStream;
})();
/**
@ -763,7 +772,7 @@ var PredictorStream = (function predictorStream() {
* a library to decode these images and the stream behaves like all the other
* DecodeStreams.
*/
var JpegStream = (function jpegStream() {
var JpegStream = (function JpegStreamClosure() {
function isAdobeImage(bytes) {
var maxBytesScanned = Math.max(bytes.length - 16, 1024);
// Looking for APP14, 'Adobe'
@ -794,63 +803,184 @@ var JpegStream = (function jpegStream() {
return newBytes;
}
function constructor(bytes, dict, xref) {
function JpegStream(bytes, dict, xref) {
// TODO: per poppler, some images may have 'junk' before that
// need to be removed
this.dict = dict;
// Flag indicating wether the image can be natively loaded.
this.isNative = true;
this.colorTransform = -1;
this.isAdobeImage = false;
this.colorTransform = dict.get('ColorTransform') || -1;
if (isAdobeImage(bytes)) {
// when bug 674619 land, let's check if browser can do
// normal cmyk and then we won't have to the following
var cs = xref.fetchIfRef(dict.get('ColorSpace'));
// DeviceRGB and DeviceGray are the only Adobe images that work natively
if (isName(cs) && (cs.name === 'DeviceRGB' || cs.name === 'DeviceGray')) {
bytes = fixAdobeImage(bytes);
this.src = bytesToString(bytes);
} else {
this.colorTransform = dict.get('ColorTransform');
this.isNative = false;
this.bytes = bytes;
}
} else {
this.src = bytesToString(bytes);
this.isAdobeImage = true;
bytes = fixAdobeImage(bytes);
}
this.bytes = bytes;
DecodeStream.call(this);
}
constructor.prototype = Object.create(DecodeStream.prototype);
JpegStream.prototype = Object.create(DecodeStream.prototype);
constructor.prototype.ensureBuffer = function jpegStreamEnsureBuffer(req) {
JpegStream.prototype.ensureBuffer = function JpegStream_ensureBuffer(req) {
if (this.bufferLength)
return;
var jpegImage = new JpegImage();
jpegImage.colorTransform = this.colorTransform;
jpegImage.parse(this.bytes);
var width = jpegImage.width;
var height = jpegImage.height;
var data = jpegImage.getData(width, height);
try {
var jpegImage = new JpegImage();
if (this.colorTransform != -1)
jpegImage.colorTransform = this.colorTransform;
jpegImage.parse(this.bytes);
var width = jpegImage.width;
var height = jpegImage.height;
var data = jpegImage.getData(width, height);
this.buffer = data;
this.bufferLength = data.length;
} catch (e) {
error('JPEG error: ' + e);
}
};
JpegStream.prototype.getIR = function JpegStream_getIR() {
return bytesToString(this.bytes);
};
JpegStream.prototype.getChar = function JpegStream_getChar() {
error('internal error: getChar is not valid on JpegStream');
};
/**
* Checks if the image can be decoded and displayed by the browser without any
* further processing such as color space conversions.
*/
JpegStream.prototype.isNativelySupported =
function JpegStream_isNativelySupported(xref, res) {
var cs = ColorSpace.parse(this.dict.get('ColorSpace'), xref, res);
// when bug 674619 lands, let's check if browser can do
// normal cmyk and then we won't need to decode in JS
if (cs.name === 'DeviceGray' || cs.name === 'DeviceRGB')
return true;
if (cs.name === 'DeviceCMYK' && !this.isAdobeImage &&
this.colorTransform < 1)
return true;
return false;
};
/**
* Checks if the image can be decoded by the browser.
*/
JpegStream.prototype.isNativelyDecodable =
function JpegStream_isNativelyDecodable(xref, res) {
var cs = ColorSpace.parse(this.dict.get('ColorSpace'), xref, res);
var numComps = cs.numComps;
if (numComps == 1 || numComps == 3)
return true;
return false;
};
return JpegStream;
})();
/**
* For JPEG 2000's we use a library to decode these images and
* the stream behaves like all the other DecodeStreams.
*/
var JpxStream = (function JpxStreamClosure() {
function JpxStream(bytes, dict) {
this.dict = dict;
this.bytes = bytes;
DecodeStream.call(this);
}
JpxStream.prototype = Object.create(DecodeStream.prototype);
JpxStream.prototype.ensureBuffer = function JpxStream_ensureBuffer(req) {
if (this.bufferLength)
return;
var jpxImage = new JpxImage();
jpxImage.parse(this.bytes);
var width = jpxImage.width;
var height = jpxImage.height;
var componentsCount = jpxImage.componentsCount;
if (componentsCount != 1 && componentsCount != 3 && componentsCount != 4)
error('JPX with ' + componentsCount + ' components is not supported');
var data = new Uint8Array(width * height * componentsCount);
for (var k = 0, kk = jpxImage.tiles.length; k < kk; k++) {
var tileCompoments = jpxImage.tiles[k];
var tileWidth = tileCompoments[0].width;
var tileHeight = tileCompoments[0].height;
var tileLeft = tileCompoments[0].left;
var tileTop = tileCompoments[0].top;
var dataPosition, sourcePosition, data0, data1, data2, data3, rowFeed;
switch (componentsCount) {
case 1:
data0 = tileCompoments[0].items;
dataPosition = width * tileTop + tileLeft;
rowFeed = width - tileWidth;
sourcePosition = 0;
for (var j = 0; j < tileHeight; j++) {
for (var i = 0; i < tileWidth; i++)
data[dataPosition++] = data0[sourcePosition++];
dataPosition += rowFeed;
}
break;
case 3:
data0 = tileCompoments[0].items;
data1 = tileCompoments[1].items;
data2 = tileCompoments[2].items;
dataPosition = (width * tileTop + tileLeft) * 3;
rowFeed = (width - tileWidth) * 3;
sourcePosition = 0;
for (var j = 0; j < tileHeight; j++) {
for (var i = 0; i < tileWidth; i++) {
data[dataPosition++] = data0[sourcePosition];
data[dataPosition++] = data1[sourcePosition];
data[dataPosition++] = data2[sourcePosition];
sourcePosition++;
}
dataPosition += rowFeed;
}
break;
case 4:
data0 = tileCompoments[0].items;
data1 = tileCompoments[1].items;
data2 = tileCompoments[2].items;
data3 = tileCompoments[3].items;
dataPosition = (width * tileTop + tileLeft) * 4;
rowFeed = (width - tileWidth) * 4;
sourcePosition = 0;
for (var j = 0; j < tileHeight; j++) {
for (var i = 0; i < tileWidth; i++) {
data[dataPosition++] = data0[sourcePosition];
data[dataPosition++] = data1[sourcePosition];
data[dataPosition++] = data2[sourcePosition];
data[dataPosition++] = data3[sourcePosition];
sourcePosition++;
}
dataPosition += rowFeed;
}
break;
}
}
this.buffer = data;
this.bufferLength = data.length;
};
constructor.prototype.getIR = function jpegStreamGetIR() {
return this.src;
};
constructor.prototype.getChar = function jpegStreamGetChar() {
error('internal error: getChar is not valid on JpegStream');
JpxStream.prototype.getChar = function JpxStream_getChar() {
error('internal error: getChar is not valid on JpxStream');
};
return constructor;
return JpxStream;
})();
var DecryptStream = (function decryptStream() {
function constructor(str, decrypt) {
var DecryptStream = (function DecryptStreamClosure() {
function DecryptStream(str, decrypt) {
this.str = str;
this.dict = str.dict;
this.decrypt = decrypt;
@ -860,9 +990,9 @@ var DecryptStream = (function decryptStream() {
var chunkSize = 512;
constructor.prototype = Object.create(DecodeStream.prototype);
DecryptStream.prototype = Object.create(DecodeStream.prototype);
constructor.prototype.readBlock = function decryptStreamReadBlock() {
DecryptStream.prototype.readBlock = function DecryptStream_readBlock() {
var chunk = this.str.getBytes(chunkSize);
if (!chunk || chunk.length == 0) {
this.eof = true;
@ -879,11 +1009,11 @@ var DecryptStream = (function decryptStream() {
this.bufferLength = bufferLength;
};
return constructor;
return DecryptStream;
})();
var Ascii85Stream = (function ascii85Stream() {
function constructor(str) {
var Ascii85Stream = (function Ascii85StreamClosure() {
function Ascii85Stream(str) {
this.str = str;
this.dict = str.dict;
this.input = new Uint8Array(5);
@ -891,9 +1021,9 @@ var Ascii85Stream = (function ascii85Stream() {
DecodeStream.call(this);
}
constructor.prototype = Object.create(DecodeStream.prototype);
Ascii85Stream.prototype = Object.create(DecodeStream.prototype);
constructor.prototype.readBlock = function ascii85StreamReadBlock() {
Ascii85Stream.prototype.readBlock = function Ascii85Stream_readBlock() {
var tildaCode = '~'.charCodeAt(0);
var zCode = 'z'.charCodeAt(0);
var str = this.str;
@ -948,11 +1078,11 @@ var Ascii85Stream = (function ascii85Stream() {
}
};
return constructor;
return Ascii85Stream;
})();
var AsciiHexStream = (function asciiHexStream() {
function constructor(str) {
var AsciiHexStream = (function AsciiHexStreamClosure() {
function AsciiHexStream(str) {
this.str = str;
this.dict = str.dict;
@ -986,9 +1116,9 @@ var AsciiHexStream = (function asciiHexStream() {
102: 15
};
constructor.prototype = Object.create(DecodeStream.prototype);
AsciiHexStream.prototype = Object.create(DecodeStream.prototype);
constructor.prototype.readBlock = function asciiHexStreamReadBlock() {
AsciiHexStream.prototype.readBlock = function AsciiHexStream_readBlock() {
var gtCode = '>'.charCodeAt(0), bytes = this.str.getBytes(), c, n,
decodeLength, buffer, bufferLength, i, length;
@ -1018,10 +1148,55 @@ var AsciiHexStream = (function asciiHexStream() {
this.eof = true;
};
return constructor;
return AsciiHexStream;
})();
var CCITTFaxStream = (function ccittFaxStream() {
var RunLengthStream = (function RunLengthStreamClosure() {
function RunLengthStream(str) {
this.str = str;
this.dict = str.dict;
DecodeStream.call(this);
}
RunLengthStream.prototype = Object.create(DecodeStream.prototype);
RunLengthStream.prototype.readBlock = function RunLengthStream_readBlock() {
// The repeatHeader has following format. The first byte defines type of run
// and amount of bytes to repeat/copy: n = 0 through 127 - copy next n bytes
// (in addition to the second byte from the header), n = 129 through 255 -
// duplicate the second byte from the header (257 - n) times, n = 128 - end.
var repeatHeader = this.str.getBytes(2);
if (!repeatHeader || repeatHeader.length < 2 || repeatHeader[0] == 128) {
this.eof = true;
return;
}
var bufferLength = this.bufferLength;
var n = repeatHeader[0];
if (n < 128) {
// copy n bytes
var buffer = this.ensureBuffer(bufferLength + n + 1);
buffer[bufferLength++] = repeatHeader[1];
if (n > 0) {
var source = this.str.getBytes(n);
buffer.set(source, bufferLength);
bufferLength += n;
}
} else {
n = 257 - n;
var b = repeatHeader[1];
var buffer = this.ensureBuffer(bufferLength + n + 1);
for (var i = 0; i < n; i++)
buffer[bufferLength++] = b;
}
this.bufferLength = bufferLength;
};
return RunLengthStream;
})();
var CCITTFaxStream = (function CCITTFaxStreamClosure() {
var ccittEOL = -2;
var twoDimPass = 0;
@ -1449,7 +1624,7 @@ var CCITTFaxStream = (function ccittFaxStream() {
[2, 2], [2, 2], [2, 2], [2, 2]
];
function constructor(str, params) {
function CCITTFaxStream(str, params) {
this.str = str;
this.dict = str.dict;
@ -1494,9 +1669,9 @@ var CCITTFaxStream = (function ccittFaxStream() {
DecodeStream.call(this);
}
constructor.prototype = Object.create(DecodeStream.prototype);
CCITTFaxStream.prototype = Object.create(DecodeStream.prototype);
constructor.prototype.readBlock = function ccittFaxStreamReadBlock() {
CCITTFaxStream.prototype.readBlock = function CCITTFaxStream_readBlock() {
while (!this.eof) {
var c = this.lookChar();
this.buf = EOF;
@ -1505,7 +1680,7 @@ var CCITTFaxStream = (function ccittFaxStream() {
}
};
constructor.prototype.addPixels =
CCITTFaxStream.prototype.addPixels =
function ccittFaxStreamAddPixels(a1, blackPixels) {
var codingLine = this.codingLine;
var codingPos = this.codingPos;
@ -1525,7 +1700,7 @@ var CCITTFaxStream = (function ccittFaxStream() {
this.codingPos = codingPos;
};
constructor.prototype.addPixelsNeg =
CCITTFaxStream.prototype.addPixelsNeg =
function ccittFaxStreamAddPixelsNeg(a1, blackPixels) {
var codingLine = this.codingLine;
var codingPos = this.codingPos;
@ -1554,7 +1729,7 @@ var CCITTFaxStream = (function ccittFaxStream() {
this.codingPos = codingPos;
};
constructor.prototype.lookChar = function ccittFaxStreamLookChar() {
CCITTFaxStream.prototype.lookChar = function CCITTFaxStream_lookChar() {
if (this.buf != EOF)
return this.buf;
@ -1852,10 +2027,10 @@ var CCITTFaxStream = (function ccittFaxStream() {
// values. The first array element indicates whether a valid code is being
// returned. The second array element is the actual code. The third array
// element indicates whether EOF was reached.
var findTableCode = function ccittFaxStreamFindTableCode(start, end, table,
limit) {
var limitValue = limit || 0;
CCITTFaxStream.prototype.findTableCode =
function ccittFaxStreamFindTableCode(start, end, table, limit) {
var limitValue = limit || 0;
for (var i = start; i <= end; ++i) {
var code = this.lookBits(i);
if (code == EOF)
@ -1873,18 +2048,20 @@ var CCITTFaxStream = (function ccittFaxStream() {
return [false, 0, false];
};
constructor.prototype.getTwoDimCode = function ccittFaxStreamGetTwoDimCode() {
CCITTFaxStream.prototype.getTwoDimCode =
function ccittFaxStreamGetTwoDimCode() {
var code = 0;
var p;
if (this.eoblock) {
code = this.lookBits(7);
p = twoDimTable[code];
if (p[0] > 0) {
if (p && p[0] > 0) {
this.eatBits(p[0]);
return p[1];
}
} else {
var result = findTableCode(1, 7, twoDimTable);
var result = this.findTableCode(1, 7, twoDimTable);
if (result[0] && result[2])
return result[1];
}
@ -1892,7 +2069,9 @@ var CCITTFaxStream = (function ccittFaxStream() {
return EOF;
};
constructor.prototype.getWhiteCode = function ccittFaxStreamGetWhiteCode() {
CCITTFaxStream.prototype.getWhiteCode =
function ccittFaxStreamGetWhiteCode() {
var code = 0;
var p;
var n;
@ -1911,11 +2090,11 @@ var CCITTFaxStream = (function ccittFaxStream() {
return p[1];
}
} else {
var result = findTableCode(1, 9, whiteTable2);
var result = this.findTableCode(1, 9, whiteTable2);
if (result[0])
return result[1];
result = findTableCode(11, 12, whiteTable1);
result = this.findTableCode(11, 12, whiteTable1);
if (result[0])
return result[1];
}
@ -1924,7 +2103,9 @@ var CCITTFaxStream = (function ccittFaxStream() {
return 1;
};
constructor.prototype.getBlackCode = function ccittFaxStreamGetBlackCode() {
CCITTFaxStream.prototype.getBlackCode =
function ccittFaxStreamGetBlackCode() {
var code, p;
if (this.eoblock) {
code = this.lookBits(13);
@ -1942,15 +2123,15 @@ var CCITTFaxStream = (function ccittFaxStream() {
return p[1];
}
} else {
var result = findTableCode(2, 6, blackTable3);
var result = this.findTableCode(2, 6, blackTable3);
if (result[0])
return result[1];
result = findTableCode(7, 12, blackTable2, 64);
result = this.findTableCode(7, 12, blackTable2, 64);
if (result[0])
return result[1];
result = findTableCode(10, 13, blackTable1);
result = this.findTableCode(10, 13, blackTable1);
if (result[0])
return result[1];
}
@ -1959,7 +2140,7 @@ var CCITTFaxStream = (function ccittFaxStream() {
return 1;
};
constructor.prototype.lookBits = function ccittFaxStreamLookBits(n) {
CCITTFaxStream.prototype.lookBits = function CCITTFaxStream_lookBits(n) {
var c;
while (this.inputBits < n) {
if ((c = this.str.getByte()) == null) {
@ -1974,16 +2155,16 @@ var CCITTFaxStream = (function ccittFaxStream() {
return (this.inputBuf >> (this.inputBits - n)) & (0xFFFF >> (16 - n));
};
constructor.prototype.eatBits = function ccittFaxStreamEatBits(n) {
CCITTFaxStream.prototype.eatBits = function CCITTFaxStream_eatBits(n) {
if ((this.inputBits -= n) < 0)
this.inputBits = 0;
};
return constructor;
return CCITTFaxStream;
})();
var LZWStream = (function lzwStream() {
function constructor(str, earlyChange) {
var LZWStream = (function LZWStreamClosure() {
function LZWStream(str, earlyChange) {
this.str = str;
this.dict = str.dict;
this.cachedData = 0;
@ -2009,9 +2190,9 @@ var LZWStream = (function lzwStream() {
DecodeStream.call(this);
}
constructor.prototype = Object.create(DecodeStream.prototype);
LZWStream.prototype = Object.create(DecodeStream.prototype);
constructor.prototype.readBits = function lzwStreamReadBits(n) {
LZWStream.prototype.readBits = function LZWStream_readBits(n) {
var bitsCached = this.bitsCached;
var cachedData = this.cachedData;
while (bitsCached < n) {
@ -2029,7 +2210,7 @@ var LZWStream = (function lzwStream() {
return (cachedData >>> bitsCached) & ((1 << n) - 1);
};
constructor.prototype.readBlock = function lzwStreamReadBlock() {
LZWStream.prototype.readBlock = function LZWStream_readBlock() {
var blockSize = 512;
var estimatedDecodedSize = blockSize * 2, decodedSizeDelta = blockSize;
var i, j, q;
@ -2108,6 +2289,6 @@ var LZWStream = (function lzwStream() {
this.bufferLength = currentBufferLength;
};
return constructor;
return LZWStream;
})();

218
apps/files_pdfviewer/js/pdfjs/src/util.js Executable file → Normal file
View File

@ -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;
})();

View File

6
apps/files_pdfviewer/js/pdfjs/src/utils/fonts_utils.js Executable file → Normal file
View File

@ -122,9 +122,9 @@ function readFontDictData(aString, aMap) {
token = '';
var parsed = false;
while (!parsed) {
var byte = aString[i++];
var octet = aString[i++];
var nibbles = [parseInt(byte / 16, 10), parseInt(byte % 16, 10)];
var nibbles = [parseInt(octet / 16, 10), parseInt(octet % 16, 10)];
for (var j = 0; j < nibbles.length; j++) {
var nibble = nibbles[j];
switch (nibble) {
@ -336,7 +336,7 @@ var Type2Parser = function type2Parser(aFilePath) {
var privateDict = [];
for (var i = 0; i < priv.size; i++)
privateDict.push(aStream.getByte());
dump('private:' + privateDict);
dump('privateData:' + privateDict);
parseAsToken(privateDict, CFFDictPrivateDataMap);
for (var p in font.map)

154
apps/files_pdfviewer/js/pdfjs/src/worker.js Executable file → Normal file
View File

@ -6,6 +6,8 @@
function MessageHandler(name, comObj) {
this.name = name;
this.comObj = comObj;
this.callbackIndex = 1;
var callbacks = this.callbacks = {};
var ah = this.actionHandler = {};
ah['console_log'] = [function ahConsoleLog(data) {
@ -17,11 +19,32 @@ function MessageHandler(name, comObj) {
comObj.onmessage = function messageHandlerComObjOnMessage(event) {
var data = event.data;
if (data.action in ah) {
if (data.isReply) {
var callbackId = data.callbackId;
if (data.callbackId in callbacks) {
var callback = callbacks[callbackId];
delete callbacks[callbackId];
callback(data.data);
} else {
error('Cannot resolve callback ' + callbackId);
}
} else if (data.action in ah) {
var action = ah[data.action];
action[0].call(action[1], data.data);
if (data.callbackId) {
var promise = new Promise();
promise.then(function(resolvedData) {
comObj.postMessage({
isReply: true,
callbackId: data.callbackId,
data: resolvedData
});
});
action[0].call(action[1], data.data, promise);
} else {
action[0].call(action[1], data.data);
}
} else {
throw 'Unkown action from worker: ' + data.action;
error('Unkown action from worker: ' + data.action);
}
};
}
@ -30,44 +53,47 @@ MessageHandler.prototype = {
on: function messageHandlerOn(actionName, handler, scope) {
var ah = this.actionHandler;
if (ah[actionName]) {
throw 'There is already an actionName called "' + actionName + '"';
error('There is already an actionName called "' + actionName + '"');
}
ah[actionName] = [handler, scope];
},
send: function messageHandlerSend(actionName, data) {
this.comObj.postMessage({
/**
* Sends a message to the comObj to invoke the action with the supplied data.
* @param {String} actionName Action to call.
* @param {JSON} data JSON data to send.
* @param {function} [callback] Optional callback that will handle a reply.
*/
send: function messageHandlerSend(actionName, data, callback) {
var message = {
action: actionName,
data: data
});
};
if (callback) {
var callbackId = this.callbackIndex++;
this.callbacks[callbackId] = callback;
message.callbackId = callbackId;
}
this.comObj.postMessage(message);
}
};
var WorkerMessageHandler = {
setup: function wphSetup(handler) {
var pdfDoc = null;
var pdfModel = null;
handler.on('test', function wphSetupTest(data) {
handler.send('test', data instanceof Uint8Array);
});
handler.on('workerSrc', function wphSetupWorkerSrc(data) {
// In development, the `workerSrc` message is handled in the
// `worker_loader.js` file. In production the workerProcessHandler is
// called for this. This servers as a dummy to prevent calling an
// undefined action `workerSrc`.
});
handler.on('doc', function wphSetupDoc(data) {
// Create only the model of the PDFDoc, which is enough for
// processing the content of the pdf.
pdfDoc = new PDFDocModel(new Stream(data));
pdfModel = new PDFDocModel(new Stream(data));
});
handler.on('page_request', function wphSetupPageRequest(pageNum) {
pageNum = parseInt(pageNum);
var page = pdfDoc.getPage(pageNum);
// The following code does quite the same as
// Page.prototype.startRendering, but stops at one point and sends the
@ -77,12 +103,42 @@ var WorkerMessageHandler = {
var start = Date.now();
var dependency = [];
var operatorList = null;
try {
var page = pdfModel.getPage(pageNum);
// Pre compile the pdf page and fetch the fonts/images.
operatorList = page.getOperatorList(handler, dependency);
} catch (e) {
var minimumStackMessage =
'worker.js: while trying to getPage() and getOperatorList()';
// Pre compile the pdf page and fetch the fonts/images.
var IRQueue = page.getIRQueue(handler, dependency);
// Turn the error into an obj that can be serialized
if (typeof e === 'string') {
e = {
message: e,
stack: minimumStackMessage
};
} else if (typeof e === 'object') {
e = {
message: e.message || e.toString(),
stack: e.stack || minimumStackMessage
};
} else {
e = {
message: 'Unknown exception type: ' + (typeof e),
stack: minimumStackMessage
};
}
console.log('page=%d - getIRQueue: time=%dms, len=%d', pageNum,
Date.now() - start, IRQueue.fnArray.length);
handler.send('page_error', {
pageNum: pageNum,
error: e
});
return;
}
console.log('page=%d - getOperatorList: time=%dms, len=%d', pageNum,
Date.now() - start, operatorList.fnArray.length);
// Filter the dependecies for fonts.
var fonts = {};
@ -95,59 +151,10 @@ var WorkerMessageHandler = {
handler.send('page', {
pageNum: pageNum,
IRQueue: IRQueue,
operatorList: operatorList,
depFonts: Object.keys(fonts)
});
}, this);
handler.on('font', function wphSetupFont(data) {
var objId = data[0];
var name = data[1];
var file = data[2];
var properties = data[3];
var font = {
name: name,
file: file,
properties: properties
};
// Some fonts don't have a file, e.g. the build in ones like Arial.
if (file) {
var fontFileDict = new Dict();
fontFileDict.map = file.dict.map;
var fontFile = new Stream(file.bytes, file.start,
file.end - file.start, fontFileDict);
// Check if this is a FlateStream. Otherwise just use the created
// Stream one. This makes complex_ttf_font.pdf work.
var cmf = file.bytes[0];
if ((cmf & 0x0f) == 0x08) {
font.file = new FlateStream(fontFile);
} else {
font.file = fontFile;
}
}
var obj = new Font(font.name, font.file, font.properties);
var str = '';
var objData = obj.data;
if (objData) {
var length = objData.length;
for (var j = 0; j < length; ++j)
str += String.fromCharCode(objData[j]);
}
obj.str = str;
// Remove the data array form the font object, as it's not needed
// anymore as we sent over the ready str.
delete obj.data;
handler.send('font_ready', [objId, obj]);
});
}
};
@ -168,6 +175,7 @@ var workerConsole = {
action: 'console_error',
data: args
});
throw 'pdf.js execution error';
},
time: function time(name) {
@ -177,7 +185,7 @@ var workerConsole = {
timeEnd: function timeEnd(name) {
var time = consoleTimer[name];
if (time == null) {
throw 'Unkown timer name ' + name;
error('Unkown timer name ' + name);
}
this.log('Timer:', name, Date.now() - time);
}

73
apps/files_pdfviewer/js/pdfjs/src/worker_loader.js Executable file → Normal file
View File

@ -3,51 +3,32 @@
'use strict';
function onMessageLoader(evt) {
// Reset the `onmessage` function as it was only set to call
// this function the first time a message is passed to the worker
// but shouldn't get called anytime afterwards.
this.onmessage = null;
// List of files to include;
var files = [
'core.js',
'util.js',
'canvas.js',
'obj.js',
'function.js',
'charsets.js',
'cidmaps.js',
'colorspace.js',
'crypto.js',
'evaluator.js',
'fonts.js',
'glyphlist.js',
'image.js',
'metrics.js',
'parser.js',
'pattern.js',
'stream.js',
'worker.js',
'../external/jpgjs/jpg.js',
'jpx.js',
'bidi.js'
];
if (evt.data.action !== 'workerSrc') {
throw 'Worker expects first message to be `workerSrc`';
}
// Content of `PDFJS.workerSrc` as defined on the main thread.
var workerSrc = evt.data.data;
// Extract the directory that contains the source files to load.
// Assuming the source files have the same relative possition as the
// `workerSrc` file.
var dir = workerSrc.substring(0, workerSrc.lastIndexOf('/') + 1);
// List of files to include;
var files = [
'core.js',
'util.js',
'canvas.js',
'obj.js',
'function.js',
'charsets.js',
'cidmaps.js',
'colorspace.js',
'crypto.js',
'evaluator.js',
'fonts.js',
'glyphlist.js',
'image.js',
'metrics.js',
'parser.js',
'pattern.js',
'stream.js',
'worker.js',
'../external/jpgjs/jpg.js'
];
// Load all the files.
for (var i = 0; i < files.length; i++) {
importScripts(dir + files[i]);
}
// Load all the files.
for (var i = 0; i < files.length; i++) {
importScripts(files[i]);
}
this.onmessage = onMessageLoader;

3
apps/files_pdfviewer/js/pdfjs/web/images/bookmark.svg Executable file → Normal file
View File

@ -20,7 +20,8 @@
height="48.000000px"
width="48.000000px"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
version="1.1"
viewbox="0 0 48 48">
<defs
id="defs3">
<inkscape:perspective

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -0,0 +1,3 @@
<svg height="40" width="40" xmlns="http://www.w3.org/2000/svg">
<path d="M2.379,14.729 5.208,11.899 12.958,19.648 25.877,6.733 28.707,9.561 12.958,25.308z" fill="#333333"></path>
</svg>

After

Width:  |  Height:  |  Size: 188 B

View File

@ -0,0 +1,3 @@
<svg height="40" width="40" xmlns="http://www.w3.org/2000/svg">
<path d="M16,5.333c-7.732,0-14,4.701-14,10.5c0,1.982,0.741,3.833,2.016,5.414L2,25.667l5.613-1.441c2.339,1.317,5.237,2.107,8.387,2.107c7.732,0,14-4.701,14-10.5C30,10.034,23.732,5.333,16,5.333z" fill="#333333"></path>
</svg>

After

Width:  |  Height:  |  Size: 289 B

View File

@ -16,7 +16,8 @@
id="svg2994"
height="48px"
width="48px"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
inkscape:output_extension="org.inkscape.output.svg.inkscape"
viewbox="0 0 48 48">
<defs
id="defs3">
<inkscape:perspective

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

3
apps/files_pdfviewer/js/pdfjs/web/images/download.svg Executable file → Normal file
View File

@ -16,7 +16,8 @@
id="svg2913"
height="48px"
width="48px"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
inkscape:output_extension="org.inkscape.output.svg.inkscape"
viewbox="0 0 48 48">
<defs
id="defs3">
<inkscape:perspective

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

3
apps/files_pdfviewer/js/pdfjs/web/images/go-down.svg Executable file → Normal file
View File

@ -19,7 +19,8 @@
inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
inkscape:export-xdpi="90.000000"
inkscape:export-ydpi="90.000000"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
inkscape:output_extension="org.inkscape.output.svg.inkscape"
viewbox="0 0 48 48">
<defs
id="defs3">
<inkscape:perspective

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

3
apps/files_pdfviewer/js/pdfjs/web/images/go-up.svg Executable file → Normal file
View File

@ -19,7 +19,8 @@
inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
inkscape:export-xdpi="90.000000"
inkscape:export-ydpi="90.000000"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
inkscape:output_extension="org.inkscape.output.svg.inkscape"
viewbox="0 0 48 48">
<defs
id="defs3">
<inkscape:perspective

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,297 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48"
height="48"
id="svg3075"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="pin-down.svg"
viewPort="0 0 48 48">
<defs
id="defs3077">
<linearGradient
inkscape:collect="always"
id="linearGradient3804">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3806" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3808" />
</linearGradient>
<linearGradient
id="linearGradient3965">
<stop
id="stop3967"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
style="stop-color:#ffffff;stop-opacity:0"
offset="1"
id="stop3969" />
</linearGradient>
<linearGradient
id="linearGradient3885">
<stop
style="stop-color:#a8b5e9;stop-opacity:1;"
offset="0"
id="stop3889" />
<stop
id="stop3891"
offset="1"
style="stop-color:#1d4488;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3865">
<stop
style="stop-color:#0e0ec3;stop-opacity:0"
offset="0"
id="stop3867" />
<stop
id="stop3883"
offset="0.5"
style="stop-color:#95b1e4;stop-opacity:1;" />
<stop
style="stop-color:#0d29c0;stop-opacity:1;"
offset="1"
id="stop3869" />
</linearGradient>
<linearGradient
id="linearGradient3853">
<stop
style="stop-color:#717171;stop-opacity:1;"
offset="0"
id="stop3855" />
<stop
id="stop3861"
offset="0.5"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
style="stop-color:#818181;stop-opacity:1;"
offset="1"
id="stop3857" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3885"
id="radialGradient3792"
cx="13.508819"
cy="30.521608"
fx="13.508819"
fy="30.521608"
r="13.254341"
gradientTransform="matrix(1,0,0,1.045977,0,-1.4434017)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3885"
id="linearGradient3802"
x1="15.306904"
y1="13.407407"
x2="29.35461"
y2="30.15519"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2304178,0,0,1.1235308,-2.1158755,998.83747)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3804"
id="radialGradient3812"
cx="20.111172"
cy="28.238274"
fx="20.111172"
fy="28.238274"
r="7.6291947"
gradientTransform="matrix(1.2304178,0,0,1.1452771,-2.1158755,998.22337)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3885"
id="radialGradient3822"
cx="23.985939"
cy="24.847366"
fx="23.985939"
fy="24.847366"
r="10.593476"
gradientTransform="matrix(0.63682384,0.44303926,-1.1714282,1.6838088,35.523491,-26.055439)"
gradientUnits="userSpaceOnUse" />
<filter
inkscape:collect="always"
id="filter3856"
x="-0.30370581"
width="1.6074116"
y="-0.32771564"
height="1.6554313">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="4.7808869"
id="feGaussianBlur3858" />
</filter>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3885"
id="radialGradient3865"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,1.045977,0,-1.4434017)"
cx="13.508819"
cy="30.521608"
fx="13.508819"
fy="30.521608"
r="13.254341" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3885"
id="linearGradient3867"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2304178,0,0,1.1235308,-2.1158755,998.83747)"
x1="15.306904"
y1="13.407407"
x2="29.35461"
y2="30.15519" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3804"
id="radialGradient3869"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.2304178,0,0,1.1452771,-2.1158755,998.22337)"
cx="20.111172"
cy="28.238274"
fx="20.111172"
fy="28.238274"
r="7.6291947" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3885"
id="radialGradient3871"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.63682384,0.44303926,-1.1714282,1.6838088,35.523491,-26.055439)"
cx="23.985939"
cy="24.847366"
fx="23.985939"
fy="24.847366"
r="10.593476" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3885"
id="linearGradient3875"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98683814,0,0,0.9524914,3.4991888,1004.1467)"
x1="15.306904"
y1="13.407407"
x2="29.35461"
y2="30.15519" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3804"
id="radialGradient3877"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.195641,0.23932984,-0.18533175,0.95255553,4.5333676,999.33159)"
cx="20.111172"
cy="28.238274"
fx="20.111172"
fy="28.238274"
r="7.6291947" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3885"
id="radialGradient3880"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5847553,0.52693722,-0.99805104,2.7064773,14.11088,-45.304477)"
cx="18.133854"
cy="19.778509"
fx="18.133854"
fy="19.778509"
r="10.593476" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3885"
id="radialGradient3882"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,1.045977,0,-1.4434017)"
cx="13.508819"
cy="30.521608"
fx="13.508819"
fy="30.521608"
r="13.254341" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4.9558805"
inkscape:cx="3.0237013"
inkscape:cy="17.287267"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1291"
inkscape:window-height="776"
inkscape:window-x="16"
inkscape:window-y="0"
inkscape:window-maximized="0" />
<metadata
id="metadata3080">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1004.3622)">
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3856)"
d="m 14.326415,1019.2702 c -8.3327876,4.0675 -9.8235436,10.8833 -8.8783416,15.1336 4.6840646,7.9754 8.3608166,13.8165 24.0118786,12.9139 9.657617,-3.7312 12.9762,-9.3269 13.519293,-15.7389 -0.547269,-4.3839 -1.957958,-9.3396 -5.649854,-14.9317 -3.965534,-2.471 -6.300859,-4.4246 -10.290805,-4.2374 -8.25193,0.5026 -8.752485,4.4502 -12.712171,6.8605 z"
id="path3826"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc"
transform="matrix(0.69099294,0,0,0.75978808,7.3427938,249.11025)" />
<path
sodipodi:type="arc"
style="fill:url(#radialGradient3882);fill-opacity:1;stroke:none"
id="path3011"
sodipodi:cx="21.176477"
sodipodi:cy="31.393986"
sodipodi:rx="13.254341"
sodipodi:ry="13.863736"
d="m 34.430819,31.393986 a 13.254341,13.863736 0 1 1 -26.5086827,0 13.254341,13.863736 0 1 1 26.5086827,0 z"
transform="matrix(0.98683814,0,0,0.83062636,2.696034,1005.3655)" />
<path
style="fill:url(#linearGradient3875);fill-opacity:1;stroke:url(#radialGradient3877);stroke-width:0.9695127;stroke-opacity:1"
d="m 17.246758,1026.7905 c -1.7156,4.5052 -2.482464,10.6205 8.726963,10.7476 4.849099,-1.8941 3.522783,-5.3561 6.021544,-11.8282 l -10.973104,-1.5977 z"
id="path3794"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:type="arc"
style="fill:url(#radialGradient3880);fill-opacity:1;stroke:none"
id="path3814"
sodipodi:cx="24.718111"
sodipodi:cy="23.38278"
sodipodi:rx="10.593476"
sodipodi:ry="9.6854639"
d="m 35.311587,23.38278 a 10.593476,9.6854639 0 1 1 -21.186952,0 10.593476,9.6854639 0 1 1 21.186952,0 z"
transform="matrix(0.85425691,0,0,0.84187503,3.9779774,1006.7561)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@ -0,0 +1,230 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48"
height="48"
id="svg3075"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="pin-up.svg"
viewPort="0 0 48 48">
<defs
id="defs3077">
<linearGradient
id="linearGradient3965">
<stop
id="stop3967"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
style="stop-color:#ffffff;stop-opacity:0"
offset="1"
id="stop3969" />
</linearGradient>
<linearGradient
id="linearGradient3885">
<stop
style="stop-color:#a8b5e9;stop-opacity:1;"
offset="0"
id="stop3889" />
<stop
id="stop3891"
offset="1"
style="stop-color:#1d4488;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3865">
<stop
style="stop-color:#0e0ec3;stop-opacity:1;"
offset="0"
id="stop3867" />
<stop
id="stop3883"
offset="0.5"
style="stop-color:#95b1e4;stop-opacity:1;" />
<stop
style="stop-color:#0d29c0;stop-opacity:1;"
offset="1"
id="stop3869" />
</linearGradient>
<linearGradient
id="linearGradient3853">
<stop
style="stop-color:#717171;stop-opacity:1;"
offset="0"
id="stop3855" />
<stop
id="stop3861"
offset="0.5"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
style="stop-color:#818181;stop-opacity:1;"
offset="1"
id="stop3857" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3853"
id="linearGradient3859"
x1="7.7696066"
y1="34.979828"
x2="11.854106"
y2="39.107044"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(4.8388015,1001.6582)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3885"
id="radialGradient3871"
cx="14.801222"
cy="1030.6609"
fx="14.801222"
fy="1030.6609"
r="10.177785"
gradientTransform="matrix(1,0,0,1.0108042,4.8388015,-13.880529)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3865"
id="linearGradient3881"
x1="15.012629"
y1="11.922465"
x2="31.098303"
y2="28.858271"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.97315436,4.8388015,1002.4769)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3885"
id="radialGradient3909"
cx="16.437693"
cy="22.596292"
fx="16.437693"
fy="22.596292"
r="1.7789712"
gradientTransform="matrix(1,0,0,8.3599999,0,-166.30871)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3865"
id="linearGradient3927"
x1="26.47109"
y1="1010.7343"
x2="35.294788"
y2="1019.8425"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(4.5541661,-2.1347654)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3965"
id="radialGradient3995"
cx="23.189369"
cy="25.704245"
fx="23.189369"
fy="25.704245"
r="37.336674"
gradientTransform="matrix(1,0,0,1.0332422,0,-0.85446479)"
gradientUnits="userSpaceOnUse" />
<filter
inkscape:collect="always"
id="filter4009"
x="-0.19299152"
width="1.385983"
y="-0.18351803"
height="1.3670361">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="3.8667902"
id="feGaussianBlur4011" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.2819435"
inkscape:cx="18.697469"
inkscape:cy="17.287267"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="970"
inkscape:window-height="778"
inkscape:window-x="284"
inkscape:window-y="0"
inkscape:window-maximized="0" />
<metadata
id="metadata3080">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1004.3622)">
<path
style="fill:url(#radialGradient3995);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1.0;filter:url(#filter4009)"
d="M -0.85390618,50.988672 14.231769,27.790888 C 12.21393,25.133052 9.5514307,24.605255 9.9622384,18.824874 13.947134,14.236899 17.362759,16.258973 21.347654,16.54779 l 8.966014,-8.6813789 c 1.467204,-2.4778468 -1.023584,-4.6422045 0.569271,-7.25820222 4.802307,-0.84764718 6.662499,1.15219542 11.527733,6.26197842 4.061691,4.1873637 5.648882,7.0611607 4.411848,9.5352857 -1.075122,2.776443 -4.518349,-0.692782 -5.835025,0.56927 l -9.108332,10.104556 c -0.418785,3.74872 2.078647,7.861968 -1.280859,11.243098 -4.132171,0.818036 -6.734336,-1.933944 -9.819921,-3.557942 z"
id="path3955"
inkscape:connector-curvature="0"
transform="translate(0,1004.3622)"
sodipodi:nodetypes="ccccccccccccc" />
<g
id="g3929">
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3083"
d="m 3.2884874,1051.0662 c 3.1862139,-6.2911 11.3693156,-15.19 15.4471616,-20.0327 l 2.86533,3.0086 c -3.476851,3.6575 -10.192375,10.8664 -18.3124916,17.0241 z"
style="fill:url(#linearGradient3859);fill-opacity:1;stroke:#a5a5a5;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path3863"
d="m 11.10078,1023.3294 c 5.038264,10.1095 11.83652,14.8875 18.358981,18.2167 1.196291,-2.5422 1.454996,-5.6203 0,-9.6776 l -8.539061,-8.6814 c -3.704654,-1.8936 -6.871076,-1.3652 -9.81992,0.1423 z"
style="fill:url(#radialGradient3871);fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path3873"
d="m 33.729292,1011.5171 -13.235545,11.4952 c 2.869602,4.2703 6.221839,7.4544 9.108332,9.1408 l 11.385416,-13.0187 z"
style="fill:url(#linearGradient3881);fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path3893"
d="m 33.228885,1011.6148 c 1.843189,2.7806 3.431654,5.6597 7.19852,7.6953 l 5.398891,1.7423 c -7.6738,-4.7914 -10.989683,-9.5828 -13.947133,-14.3741 z"
style="fill:url(#linearGradient3927);fill-opacity:1;stroke:none" />
<path
transform="matrix(0.68275275,-0.5590416,0.45791123,0.47036287,17.42507,1012.2127)"
d="m 18.216664,22.596292 a 1.7789712,14.872199 0 1 1 -3.557943,0 1.7789712,14.872199 0 1 1 3.557943,0 z"
sodipodi:ry="14.872199"
sodipodi:rx="1.7789712"
sodipodi:cy="22.596292"
sodipodi:cx="16.437693"
id="path3901"
style="fill:url(#radialGradient3909);fill-opacity:1;stroke:none"
sodipodi:type="arc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

7
apps/files_pdfviewer/js/pdfjs/web/images/zoom-in.svg Executable file → Normal file
View File

@ -16,7 +16,8 @@
inkscape:version="0.46"
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
sodipodi:docname="list-add.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
inkscape:output_extension="org.inkscape.output.svg.inkscape"
viewbox="0 0 48 48">
<defs
id="defs6433">
<inkscape:perspective
@ -418,12 +419,12 @@
d="M 33.278212 34.94062 A 10.31934 2.320194 0 1 1 12.639532,34.94062 A 10.31934 2.320194 0 1 1 33.278212 34.94062 z"
transform="matrix(1.550487,0,0,1.978714,-12.4813,-32.49103)" />
<path
style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
style="fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
d="M 27.514356,37.542682 L 27.514356,28.515722 L 37.492820,28.475543 L 37.492820,21.480219 L 27.523285,21.480219 L 27.514356,11.520049 L 20.498082,11.531210 L 20.502546,21.462362 L 10.512920,21.536022 L 10.477206,28.504561 L 20.511475,28.475543 L 20.518171,37.515896 L 27.514356,37.542682 z "
id="text1314"
sodipodi:nodetypes="ccccccccccccc" />
<path
style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
style="opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
d="M 26.498702,36.533920 L 26.498702,27.499738 L 36.501304,27.499738 L 36.494607,22.475309 L 26.507630,22.475309 L 26.507630,12.480335 L 21.512796,12.498193 L 21.521725,22.475309 L 11.495536,22.493166 L 11.468750,27.466256 L 21.533143,27.475185 L 21.519750,36.502670 L 26.498702,36.533920 z "
id="path7076"
sodipodi:nodetypes="ccccccccccccc" />

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

7
apps/files_pdfviewer/js/pdfjs/web/images/zoom-out.svg Executable file → Normal file
View File

@ -16,7 +16,8 @@
inkscape:version="0.46"
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
sodipodi:docname="list-remove.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
inkscape:output_extension="org.inkscape.output.svg.inkscape"
viewbox="0 0 48 48">
<defs
id="defs6433">
<inkscape:perspective
@ -406,12 +407,12 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
style="fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
d="M 27.514356,28.359472 L 39.633445,28.475543 L 39.633445,21.480219 L 27.523285,21.480219 L 20.502546,21.462362 L 8.5441705,21.489147 L 8.5084565,28.457686 L 20.511475,28.475543 L 27.514356,28.359472 z "
id="text1314"
sodipodi:nodetypes="ccccccccc" />
<path
style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
style="opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
d="M 38.579429,27.484113 L 38.588357,22.475309 L 9.5267863,22.493166 L 9.5000003,27.466256 L 38.579429,27.484113 z "
id="path7076"
sodipodi:nodetypes="ccccc" />

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 13 KiB