mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-26 10:08:06 +02:00
Merge branch 'master' into faxstream
This commit is contained in:
commit
2d88566163
13 changed files with 672 additions and 424 deletions
184
pdf.js
184
pdf.js
|
@ -56,6 +56,14 @@ function bytesToString(bytes) {
|
|||
return str;
|
||||
}
|
||||
|
||||
function stringToBytes(str) {
|
||||
var length = str.length;
|
||||
var bytes = new Uint8Array(length);
|
||||
for (var n = 0; n < length; ++n)
|
||||
bytes[n] = str.charCodeAt(n) & 0xFF;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
var Stream = (function() {
|
||||
function constructor(arrayBuffer, start, length, dict) {
|
||||
this.bytes = new Uint8Array(arrayBuffer);
|
||||
|
@ -71,14 +79,14 @@ var Stream = (function() {
|
|||
get length() {
|
||||
return this.end - this.start;
|
||||
},
|
||||
getByte: function() {
|
||||
getByte: function stream_getByte() {
|
||||
if (this.pos >= this.end)
|
||||
return;
|
||||
return null;
|
||||
return this.bytes[this.pos++];
|
||||
},
|
||||
// returns subarray of original buffer
|
||||
// should only be read
|
||||
getBytes: function(length) {
|
||||
getBytes: function stream_getBytes(length) {
|
||||
var bytes = this.bytes;
|
||||
var pos = this.pos;
|
||||
var strEnd = this.end;
|
||||
|
@ -93,28 +101,28 @@ var Stream = (function() {
|
|||
this.pos = end;
|
||||
return bytes.subarray(pos, end);
|
||||
},
|
||||
lookChar: function() {
|
||||
lookChar: function stream_lookChar() {
|
||||
if (this.pos >= this.end)
|
||||
return;
|
||||
return null;
|
||||
return String.fromCharCode(this.bytes[this.pos]);
|
||||
},
|
||||
getChar: function() {
|
||||
getChar: function stream_getChar() {
|
||||
if (this.pos >= this.end)
|
||||
return;
|
||||
return null;
|
||||
return String.fromCharCode(this.bytes[this.pos++]);
|
||||
},
|
||||
skip: function(n) {
|
||||
skip: function stream_skip(n) {
|
||||
if (!n)
|
||||
n = 1;
|
||||
this.pos += n;
|
||||
},
|
||||
reset: function() {
|
||||
reset: function stream_reset() {
|
||||
this.pos = this.start;
|
||||
},
|
||||
moveStart: function() {
|
||||
moveStart: function stream_moveStart() {
|
||||
this.start = this.pos;
|
||||
},
|
||||
makeSubStream: function(start, length, dict) {
|
||||
makeSubStream: function stream_makeSubstream(start, length, dict) {
|
||||
return new Stream(this.bytes.buffer, start, length, dict);
|
||||
}
|
||||
};
|
||||
|
@ -146,7 +154,7 @@ var DecodeStream = (function() {
|
|||
}
|
||||
|
||||
constructor.prototype = {
|
||||
ensureBuffer: function(requested) {
|
||||
ensureBuffer: function decodestream_ensureBuffer(requested) {
|
||||
var buffer = this.buffer;
|
||||
var current = buffer ? buffer.byteLength : 0;
|
||||
if (requested < current)
|
||||
|
@ -159,16 +167,16 @@ var DecodeStream = (function() {
|
|||
buffer2[i] = buffer[i];
|
||||
return this.buffer = buffer2;
|
||||
},
|
||||
getByte: function() {
|
||||
getByte: function decodestream_getByte() {
|
||||
var pos = this.pos;
|
||||
while (this.bufferLength <= pos) {
|
||||
if (this.eof)
|
||||
return;
|
||||
return null;
|
||||
this.readBlock();
|
||||
}
|
||||
return this.buffer[this.pos++];
|
||||
},
|
||||
getBytes: function(length) {
|
||||
getBytes: function decodestream_getBytes(length) {
|
||||
var pos = this.pos;
|
||||
|
||||
if (length) {
|
||||
|
@ -191,25 +199,25 @@ var DecodeStream = (function() {
|
|||
this.pos = end;
|
||||
return this.buffer.subarray(pos, end)
|
||||
},
|
||||
lookChar: function() {
|
||||
lookChar: function decodestream_lookChar() {
|
||||
var pos = this.pos;
|
||||
while (this.bufferLength <= pos) {
|
||||
if (this.eof)
|
||||
return;
|
||||
return null;
|
||||
this.readBlock();
|
||||
}
|
||||
return String.fromCharCode(this.buffer[this.pos]);
|
||||
},
|
||||
getChar: function() {
|
||||
getChar: function decodestream_getChar() {
|
||||
var pos = this.pos;
|
||||
while (this.bufferLength <= pos) {
|
||||
if (this.eof)
|
||||
return;
|
||||
return null;
|
||||
this.readBlock();
|
||||
}
|
||||
return String.fromCharCode(this.buffer[this.pos++]);
|
||||
},
|
||||
skip: function(n) {
|
||||
skip: function decodestream_skip(n) {
|
||||
if (!n)
|
||||
n = 1;
|
||||
this.pos += n;
|
||||
|
@ -635,6 +643,7 @@ var PredictorStream = (function() {
|
|||
var rowBytes = this.rowBytes = (columns * colors * bits + 7) >> 3;
|
||||
|
||||
DecodeStream.call(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
constructor.prototype = Object.create(DecodeStream.prototype);
|
||||
|
@ -707,7 +716,7 @@ var PredictorStream = (function() {
|
|||
var rawBytes = this.stream.getBytes(rowBytes);
|
||||
|
||||
var bufferLength = this.bufferLength;
|
||||
var buffer = this.ensureBuffer(bufferLength + pixBytes);
|
||||
var buffer = this.ensureBuffer(bufferLength + rowBytes);
|
||||
|
||||
var currentRow = buffer.subarray(bufferLength, bufferLength + rowBytes);
|
||||
var prevRow = buffer.subarray(bufferLength - rowBytes, bufferLength);
|
||||
|
@ -799,11 +808,34 @@ var JpegStream = (function() {
|
|||
return constructor;
|
||||
})();
|
||||
var DecryptStream = (function() {
|
||||
function constructor(str, fileKey, encAlgorithm, keyLength) {
|
||||
TODO("decrypt stream is not implemented");
|
||||
function constructor(str, decrypt) {
|
||||
this.str = str;
|
||||
this.dict = str.dict;
|
||||
this.decrypt = decrypt;
|
||||
|
||||
DecodeStream.call(this);
|
||||
}
|
||||
|
||||
constructor.prototype = Stream.prototype;
|
||||
const chunkSize = 512;
|
||||
|
||||
constructor.prototype = Object.create(DecodeStream.prototype);
|
||||
constructor.prototype.readBlock = function() {
|
||||
var chunk = this.str.getBytes(chunkSize);
|
||||
if (!chunk || chunk.length == 0) {
|
||||
this.eof = true;
|
||||
return;
|
||||
}
|
||||
var decrypt = this.decrypt;
|
||||
chunk = decrypt(chunk);
|
||||
|
||||
var bufferLength = this.bufferLength;
|
||||
var i, n = chunk.length;
|
||||
var buffer = this.ensureBuffer(bufferLength + n);
|
||||
for (i = 0; i < n; i++)
|
||||
buffer[bufferLength++] = chunk[i];
|
||||
this.bufferLength = bufferLength;
|
||||
this.eof = n < chunkSize;
|
||||
};
|
||||
|
||||
return constructor;
|
||||
})();
|
||||
|
@ -1883,7 +1915,9 @@ var Dict = (function() {
|
|||
|
||||
constructor.prototype = {
|
||||
get: function(key) {
|
||||
return this.map[key];
|
||||
if (key in this.map)
|
||||
return this.map[key];
|
||||
return null;
|
||||
},
|
||||
get2: function(key1, key2) {
|
||||
return this.get(key1) || this.get(key2);
|
||||
|
@ -1954,7 +1988,7 @@ function IsArray(v) {
|
|||
}
|
||||
|
||||
function IsStream(v) {
|
||||
return typeof v == "object" && "getChar" in v;
|
||||
return typeof v == "object" && v != null && ("getChar" in v);
|
||||
}
|
||||
|
||||
function IsRef(v) {
|
||||
|
@ -2023,10 +2057,10 @@ var Lexer = (function() {
|
|||
|
||||
function ToHexDigit(ch) {
|
||||
if (ch >= "0" && ch <= "9")
|
||||
return ch - "0";
|
||||
ch = ch.toLowerCase();
|
||||
if (ch >= "a" && ch <= "f")
|
||||
return ch - "a";
|
||||
return ch.charCodeAt(0) - 48;
|
||||
ch = ch.toUpperCase();
|
||||
if (ch >= "A" && ch <= "F")
|
||||
return ch.charCodeAt(0) - 55;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -2320,7 +2354,7 @@ var Parser = (function() {
|
|||
// don't buffer inline image data
|
||||
this.buf2 = (this.inlineImg > 0) ? null : this.lexer.getObj();
|
||||
},
|
||||
getObj: function() {
|
||||
getObj: function(cipherTransform) {
|
||||
// refill buffer after inline image data
|
||||
if (this.inlineImg == 2)
|
||||
this.refill();
|
||||
|
@ -2346,7 +2380,7 @@ var Parser = (function() {
|
|||
this.shift();
|
||||
if (IsEOF(this.buf1))
|
||||
break;
|
||||
dict.set(key, this.getObj());
|
||||
dict.set(key, this.getObj(cipherTransform));
|
||||
}
|
||||
}
|
||||
if (IsEOF(this.buf1))
|
||||
|
@ -2355,7 +2389,7 @@ var Parser = (function() {
|
|||
// stream objects are not allowed inside content streams or
|
||||
// object streams
|
||||
if (this.allowStreams && IsCmd(this.buf2, "stream")) {
|
||||
return this.makeStream(dict);
|
||||
return this.makeStream(dict, cipherTransform);
|
||||
} else {
|
||||
this.shift();
|
||||
}
|
||||
|
@ -2374,17 +2408,8 @@ var Parser = (function() {
|
|||
} else if (IsString(this.buf1)) { // string
|
||||
var str = this.buf1;
|
||||
this.shift();
|
||||
if (this.fileKey) {
|
||||
var decrypt = new DecryptStream(new StringStream(str),
|
||||
this.fileKey,
|
||||
this.encAlgorithm,
|
||||
this.keyLength);
|
||||
var str = "";
|
||||
var pos = decrypt.pos;
|
||||
var length = decrypt.length;
|
||||
while (pos++ > length)
|
||||
str += decrypt.getChar();
|
||||
}
|
||||
if (cipherTransform)
|
||||
str = cipherTransform.decryptString(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -2393,7 +2418,7 @@ var Parser = (function() {
|
|||
this.shift();
|
||||
return obj;
|
||||
},
|
||||
makeStream: function(dict) {
|
||||
makeStream: function(dict, cipherTransform) {
|
||||
var lexer = this.lexer;
|
||||
var stream = lexer.stream;
|
||||
|
||||
|
@ -2420,12 +2445,8 @@ var Parser = (function() {
|
|||
this.shift();
|
||||
|
||||
stream = stream.makeSubStream(pos, length, dict);
|
||||
if (this.fileKey) {
|
||||
stream = new DecryptStream(stream,
|
||||
this.fileKey,
|
||||
this.encAlgorithm,
|
||||
this.keyLength);
|
||||
}
|
||||
if (cipherTransform)
|
||||
stream = cipherTransform.createStream(stream);
|
||||
stream = this.filter(stream, dict, length);
|
||||
stream.parameters = dict;
|
||||
return stream;
|
||||
|
@ -2559,16 +2580,22 @@ var XRef = (function() {
|
|||
this.xrefstms = {};
|
||||
var trailerDict = this.readXRef(startXRef);
|
||||
|
||||
// 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), fileId[0] /*, password */);
|
||||
}
|
||||
|
||||
// get the root dictionary (catalog) object
|
||||
if (!IsRef(this.root = trailerDict.get("Root")))
|
||||
error("Invalid root reference");
|
||||
|
||||
// prepare the XRef cache
|
||||
this.cache = [];
|
||||
}
|
||||
|
||||
constructor.prototype = {
|
||||
readXRefTable: function(parser) {
|
||||
readXRefTable: function readXRefTable(parser) {
|
||||
var obj;
|
||||
while (true) {
|
||||
if (IsCmd(obj = parser.getObj(), "trailer"))
|
||||
|
@ -2639,7 +2666,7 @@ var XRef = (function() {
|
|||
|
||||
return dict;
|
||||
},
|
||||
readXRefStream: function(stream) {
|
||||
readXRefStream: function readXRefStream(stream) {
|
||||
var streamParameters = stream.parameters;
|
||||
var length = streamParameters.get("Length");
|
||||
var byteWidths = streamParameters.get("W");
|
||||
|
@ -2691,7 +2718,7 @@ var XRef = (function() {
|
|||
this.readXRef(prev);
|
||||
return streamParameters;
|
||||
},
|
||||
readXRef: function(startXRef) {
|
||||
readXRef: function readXref(startXRef) {
|
||||
var stream = this.stream;
|
||||
stream.pos = startXRef;
|
||||
var parser = new Parser(new Lexer(stream), true);
|
||||
|
@ -2709,6 +2736,7 @@ var XRef = (function() {
|
|||
return this.readXRefStream(obj);
|
||||
}
|
||||
error("Invalid XRef");
|
||||
return null;
|
||||
},
|
||||
getEntry: function(i) {
|
||||
var e = this.entries[i];
|
||||
|
@ -2752,7 +2780,11 @@ var XRef = (function() {
|
|||
}
|
||||
error("bad XRef entry");
|
||||
}
|
||||
e = parser.getObj();
|
||||
if (this.encrypt) {
|
||||
e = parser.getObj(this.encrypt.createCipherTransform(num, gen));
|
||||
} else {
|
||||
e = parser.getObj();
|
||||
}
|
||||
// Don't cache streams since they are mutable.
|
||||
if (!IsStream(e))
|
||||
this.cache[num] = e;
|
||||
|
@ -3374,7 +3406,7 @@ var CanvasGraphics = (function() {
|
|||
if (!fd)
|
||||
// XXX deprecated "special treatment" for standard
|
||||
// fonts? What do we need to do here?
|
||||
return;
|
||||
return null;
|
||||
var descriptor = xref.fetch(fd);
|
||||
|
||||
var fontName = descriptor.get("FontName");
|
||||
|
@ -3386,16 +3418,9 @@ var CanvasGraphics = (function() {
|
|||
error("FontFile not found for font: " + fontName);
|
||||
fontFile = xref.fetchIfRef(fontFile);
|
||||
|
||||
// Fonts with an embedded cmap but without any assignment in
|
||||
// it are not yet supported, so ask the fonts loader to ignore
|
||||
// them to not pay a stupid one sec latence.
|
||||
var ignoreFont = false;
|
||||
|
||||
var encodingMap = {};
|
||||
var charset = [];
|
||||
if (fontDict.has("Encoding")) {
|
||||
ignoreFont = false;
|
||||
|
||||
var encoding = xref.fetchIfRef(fontDict.get("Encoding"));
|
||||
if (IsDict(encoding)) {
|
||||
// Build a map between codes and glyphs
|
||||
|
@ -3418,9 +3443,8 @@ var CanvasGraphics = (function() {
|
|||
error("Unknown font encoding");
|
||||
|
||||
var index = 0;
|
||||
for (var j = 0; j < encoding.length; j++) {
|
||||
for (var j = 0; j < encoding.length; j++)
|
||||
encodingMap[index++] = GlyphsUnicode[encoding[j]];
|
||||
}
|
||||
|
||||
var firstChar = xref.fetchIfRef(fontDict.get("FirstChar"));
|
||||
var widths = xref.fetchIfRef(fontDict.get("Widths"));
|
||||
|
@ -3444,13 +3468,7 @@ var CanvasGraphics = (function() {
|
|||
var tokens = [];
|
||||
var token = "";
|
||||
|
||||
var length = cmapObj.length;
|
||||
if (cmapObj instanceof FlateStream) {
|
||||
cmapObj.readBlock();
|
||||
length = cmapObj.bufferLength;
|
||||
}
|
||||
|
||||
var cmap = cmapObj.getBytes(length);
|
||||
var cmap = cmapObj.getBytes(cmapObj.length);
|
||||
for (var i =0; i < cmap.length; i++) {
|
||||
var byte = cmap[i];
|
||||
if (byte == 0x20 || byte == 0x0A || byte == 0x3C || byte == 0x3E) {
|
||||
|
@ -3460,7 +3478,6 @@ var CanvasGraphics = (function() {
|
|||
break;
|
||||
|
||||
case "beginbfrange":
|
||||
ignoreFont = false;
|
||||
case "begincodespacerange":
|
||||
token = "";
|
||||
tokens = [];
|
||||
|
@ -3507,16 +3524,19 @@ var CanvasGraphics = (function() {
|
|||
}
|
||||
|
||||
var subType = fontDict.get("Subtype");
|
||||
var bbox = descriptor.get("FontBBox");
|
||||
assertWellFormed(IsName(subType) && IsArray(bbox),
|
||||
"invalid font Subtype or FontBBox");
|
||||
assertWellFormed(IsName(subType), "invalid font Subtype");
|
||||
|
||||
var properties = {
|
||||
type: subType.name,
|
||||
encoding: encodingMap,
|
||||
charset: charset,
|
||||
bbox: bbox,
|
||||
ignore: ignoreFont
|
||||
bbox: descriptor.get("FontBBox"),
|
||||
ascent: descriptor.get("Ascent"),
|
||||
descent: descriptor.get("Descent"),
|
||||
xHeight: descriptor.get("XHeight"),
|
||||
capHeight: descriptor.get("CapHeight"),
|
||||
flags: descriptor.get("Flags"),
|
||||
italicAngle: descriptor.get("ItalicAngle")
|
||||
};
|
||||
|
||||
return {
|
||||
|
@ -4027,7 +4047,7 @@ var CanvasGraphics = (function() {
|
|||
this.restore();
|
||||
|
||||
TODO("Inverse pattern is painted");
|
||||
var pattern = this.ctx.createPattern(tmpCanvas, "repeat");
|
||||
pattern = this.ctx.createPattern(tmpCanvas, "repeat");
|
||||
this.ctx.fillStyle = pattern;
|
||||
},
|
||||
setStrokeGray: function(gray) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue