Merge with master
This commit is contained in:
parent
d923953ee3
commit
ab4ecdcb73
133
pdf.js
133
pdf.js
@ -48,6 +48,14 @@ function shadow(obj, prop, value) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bytesToString(bytes) {
|
||||||
|
var str = "";
|
||||||
|
var length = bytes.length;
|
||||||
|
for (var n = 0; n < length; ++n)
|
||||||
|
str += String.fromCharCode(bytes[n]);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
var Stream = (function() {
|
var Stream = (function() {
|
||||||
function constructor(arrayBuffer, start, length, dict) {
|
function constructor(arrayBuffer, start, length, dict) {
|
||||||
this.bytes = Uint8Array(arrayBuffer);
|
this.bytes = Uint8Array(arrayBuffer);
|
||||||
@ -74,9 +82,9 @@ var Stream = (function() {
|
|||||||
var pos = this.pos;
|
var pos = this.pos;
|
||||||
var end = pos + length;
|
var end = pos + length;
|
||||||
var strEnd = this.end;
|
var strEnd = this.end;
|
||||||
if (end > strEnd)
|
if (!end || end > strEnd)
|
||||||
end = strEnd;
|
end = strEnd;
|
||||||
|
|
||||||
this.pos = end;
|
this.pos = end;
|
||||||
return bytes.subarray(pos, end);
|
return bytes.subarray(pos, end);
|
||||||
},
|
},
|
||||||
@ -233,10 +241,12 @@ var FlateStream = (function() {
|
|||||||
]), 5];
|
]), 5];
|
||||||
|
|
||||||
function constructor(stream) {
|
function constructor(stream) {
|
||||||
this.stream = stream;
|
var bytes = stream.getBytes();
|
||||||
|
var bytesPos = 0;
|
||||||
|
|
||||||
this.dict = stream.dict;
|
this.dict = stream.dict;
|
||||||
var cmf = stream.getByte();
|
var cmf = bytes[bytesPos++];
|
||||||
var flg = stream.getByte();
|
var flg = bytes[bytesPos++];
|
||||||
if (cmf == -1 || flg == -1)
|
if (cmf == -1 || flg == -1)
|
||||||
error("Invalid header in flate stream");
|
error("Invalid header in flate stream");
|
||||||
if ((cmf & 0x0f) != 0x08)
|
if ((cmf & 0x0f) != 0x08)
|
||||||
@ -245,6 +255,9 @@ var FlateStream = (function() {
|
|||||||
error("Bad FCHECK in flate stream");
|
error("Bad FCHECK in flate stream");
|
||||||
if (flg & 0x20)
|
if (flg & 0x20)
|
||||||
error("FDICT bit set in flate stream");
|
error("FDICT bit set in flate stream");
|
||||||
|
|
||||||
|
this.bytes = bytes;
|
||||||
|
this.bytesPos = bytesPos;
|
||||||
this.eof = false;
|
this.eof = false;
|
||||||
this.codeSize = 0;
|
this.codeSize = 0;
|
||||||
this.codeBuf = 0;
|
this.codeBuf = 0;
|
||||||
@ -255,12 +268,14 @@ var FlateStream = (function() {
|
|||||||
|
|
||||||
constructor.prototype = {
|
constructor.prototype = {
|
||||||
getBits: function(bits) {
|
getBits: function(bits) {
|
||||||
var stream = this.stream;
|
|
||||||
var codeSize = this.codeSize;
|
var codeSize = this.codeSize;
|
||||||
var codeBuf = this.codeBuf;
|
var codeBuf = this.codeBuf;
|
||||||
|
var bytes = this.bytes;
|
||||||
|
var bytesPos = this.bytesPos;
|
||||||
|
|
||||||
var b;
|
var b;
|
||||||
while (codeSize < bits) {
|
while (codeSize < bits) {
|
||||||
if ((b = stream.getByte()) == -1)
|
if (typeof (b = bytes[bytesPos++]) == "undefined")
|
||||||
error("Bad encoding in flate stream");
|
error("Bad encoding in flate stream");
|
||||||
codeBuf |= b << codeSize;
|
codeBuf |= b << codeSize;
|
||||||
codeSize += 8;
|
codeSize += 8;
|
||||||
@ -268,6 +283,7 @@ var FlateStream = (function() {
|
|||||||
b = codeBuf & ((1 << bits) - 1);
|
b = codeBuf & ((1 << bits) - 1);
|
||||||
this.codeBuf = codeBuf >> bits;
|
this.codeBuf = codeBuf >> bits;
|
||||||
this.codeSize = codeSize -= bits;
|
this.codeSize = codeSize -= bits;
|
||||||
|
this.bytesPos = bytesPos;
|
||||||
return b;
|
return b;
|
||||||
},
|
},
|
||||||
getCode: function(table) {
|
getCode: function(table) {
|
||||||
@ -275,10 +291,12 @@ var FlateStream = (function() {
|
|||||||
var maxLen = table[1];
|
var maxLen = table[1];
|
||||||
var codeSize = this.codeSize;
|
var codeSize = this.codeSize;
|
||||||
var codeBuf = this.codeBuf;
|
var codeBuf = this.codeBuf;
|
||||||
var stream = this.stream;
|
var bytes = this.bytes;
|
||||||
|
var bytesPos = this.bytesPos;
|
||||||
|
|
||||||
while (codeSize < maxLen) {
|
while (codeSize < maxLen) {
|
||||||
var b;
|
var b;
|
||||||
if ((b = stream.getByte()) == -1)
|
if (typeof (b = bytes[bytesPos++]) == "undefined")
|
||||||
error("Bad encoding in flate stream");
|
error("Bad encoding in flate stream");
|
||||||
codeBuf |= (b << codeSize);
|
codeBuf |= (b << codeSize);
|
||||||
codeSize += 8;
|
codeSize += 8;
|
||||||
@ -290,6 +308,7 @@ var FlateStream = (function() {
|
|||||||
error("Bad encoding in flate stream");
|
error("Bad encoding in flate stream");
|
||||||
this.codeBuf = (codeBuf >> codeLen);
|
this.codeBuf = (codeBuf >> codeLen);
|
||||||
this.codeSize = (codeSize - codeLen);
|
this.codeSize = (codeSize - codeLen);
|
||||||
|
this.bytesPos = bytesPos;
|
||||||
return codeVal;
|
return codeVal;
|
||||||
},
|
},
|
||||||
ensureBuffer: function(requested) {
|
ensureBuffer: function(requested) {
|
||||||
@ -306,9 +325,8 @@ var FlateStream = (function() {
|
|||||||
return this.buffer = buffer2;
|
return this.buffer = buffer2;
|
||||||
},
|
},
|
||||||
getByte: function() {
|
getByte: function() {
|
||||||
var bufferLength = this.bufferLength;
|
|
||||||
var pos = this.pos;
|
var pos = this.pos;
|
||||||
if (bufferLength <= pos) {
|
while (this.bufferLength <= pos) {
|
||||||
if (this.eof)
|
if (this.eof)
|
||||||
return;
|
return;
|
||||||
this.readBlock();
|
this.readBlock();
|
||||||
@ -331,9 +349,8 @@ var FlateStream = (function() {
|
|||||||
return this.buffer.subarray(pos, end)
|
return this.buffer.subarray(pos, end)
|
||||||
},
|
},
|
||||||
lookChar: function() {
|
lookChar: function() {
|
||||||
var bufferLength = this.bufferLength;
|
|
||||||
var pos = this.pos;
|
var pos = this.pos;
|
||||||
if (bufferLength <= pos) {
|
while (this.bufferLength <= pos) {
|
||||||
if (this.eof)
|
if (this.eof)
|
||||||
return;
|
return;
|
||||||
this.readBlock();
|
this.readBlock();
|
||||||
@ -342,16 +359,15 @@ var FlateStream = (function() {
|
|||||||
},
|
},
|
||||||
getChar: function() {
|
getChar: function() {
|
||||||
var ch = this.lookChar();
|
var ch = this.lookChar();
|
||||||
if (!ch)
|
// shouldnt matter what the position is if we get past the eof
|
||||||
return;
|
// so no need to check if ch is undefined
|
||||||
this.pos++;
|
this.pos++;
|
||||||
return ch;
|
return ch;
|
||||||
},
|
},
|
||||||
skip: function(n) {
|
skip: function(n) {
|
||||||
if (!n)
|
if (!n)
|
||||||
n = 1;
|
n = 1;
|
||||||
while (n-- > 0)
|
this.pos += n;
|
||||||
this.getChar();
|
|
||||||
},
|
},
|
||||||
generateHuffmanTable: function(lengths) {
|
generateHuffmanTable: function(lengths) {
|
||||||
var n = lengths.length;
|
var n = lengths.length;
|
||||||
@ -397,7 +413,8 @@ var FlateStream = (function() {
|
|||||||
array[i++] = what;
|
array[i++] = what;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stream = this.stream;
|
var bytes = this.bytes;
|
||||||
|
var bytesPos = this.bytesPos;
|
||||||
|
|
||||||
// read block header
|
// read block header
|
||||||
var hdr = this.getBits(3);
|
var hdr = this.getBits(3);
|
||||||
@ -407,16 +424,16 @@ var FlateStream = (function() {
|
|||||||
|
|
||||||
var b;
|
var b;
|
||||||
if (hdr == 0) { // uncompressed block
|
if (hdr == 0) { // uncompressed block
|
||||||
if ((b = stream.getByte()) == -1)
|
if (typeof (b = bytes[bytesPos++]) == "undefined")
|
||||||
error("Bad block header in flate stream");
|
error("Bad block header in flate stream");
|
||||||
var blockLen = b;
|
var blockLen = b;
|
||||||
if ((b = stream.getByte()) == -1)
|
if (typeof (b = bytes[bytesPos++]) == "undefined")
|
||||||
error("Bad block header in flate stream");
|
error("Bad block header in flate stream");
|
||||||
blockLen |= (b << 8);
|
blockLen |= (b << 8);
|
||||||
if ((b = stream.getByte()) == -1)
|
if (typeof (b = bytes[bytesPos++]) == "undefined")
|
||||||
error("Bad block header in flate stream");
|
error("Bad block header in flate stream");
|
||||||
var check = b;
|
var check = b;
|
||||||
if ((b = stream.getByte()) == -1)
|
if (typeof (b = bytes[bytesPos++]) == "undefined")
|
||||||
error("Bad block header in flate stream");
|
error("Bad block header in flate stream");
|
||||||
check |= (b << 8);
|
check |= (b << 8);
|
||||||
if (check != (~this.blockLen & 0xffff))
|
if (check != (~this.blockLen & 0xffff))
|
||||||
@ -425,7 +442,7 @@ var FlateStream = (function() {
|
|||||||
var buffer = this.ensureBuffer(bufferLength + blockLen);
|
var buffer = this.ensureBuffer(bufferLength + blockLen);
|
||||||
this.bufferLength = bufferLength + blockLen;
|
this.bufferLength = bufferLength + blockLen;
|
||||||
for (var n = bufferLength; n < blockLen; ++n) {
|
for (var n = bufferLength; n < blockLen; ++n) {
|
||||||
if ((b = stream.getByte()) == -1) {
|
if (typeof (b = bytes[bytesPos++]) == "undefined") {
|
||||||
this.eof = true;
|
this.eof = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -509,9 +526,32 @@ var FlateStream = (function() {
|
|||||||
return constructor;
|
return constructor;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// A JpegStream can't be read directly. We use the platform to render the underlying
|
||||||
|
// JPEG data for us.
|
||||||
|
var JpegStream = (function() {
|
||||||
|
function constructor(bytes, dict) {
|
||||||
|
// TODO: per poppler, some images may have "junk" before that need to be removed
|
||||||
|
this.dict = dict;
|
||||||
|
|
||||||
|
// create DOM image
|
||||||
|
var img = new Image();
|
||||||
|
img.src = "data:image/jpeg;base64," + window.btoa(bytesToString(bytes));
|
||||||
|
this.domImage = img;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor.prototype = {
|
||||||
|
getImage: function() {
|
||||||
|
return this.domImage;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return constructor;
|
||||||
|
})();
|
||||||
|
|
||||||
var PredictorStream = (function() {
|
var PredictorStream = (function() {
|
||||||
function constructor(stream, params) {
|
function constructor(stream, params) {
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
|
this.dict = stream.dict;
|
||||||
this.predictor = params.get("Predictor") || 1;
|
this.predictor = params.get("Predictor") || 1;
|
||||||
if (this.predictor <= 1) {
|
if (this.predictor <= 1) {
|
||||||
return stream; // no prediction
|
return stream; // no prediction
|
||||||
@ -1177,15 +1217,15 @@ var Parser = (function() {
|
|||||||
this.encAlgorithm,
|
this.encAlgorithm,
|
||||||
this.keyLength);
|
this.keyLength);
|
||||||
}
|
}
|
||||||
stream = this.filter(stream, dict);
|
stream = this.filter(stream, dict, length);
|
||||||
stream.parameters = dict;
|
stream.parameters = dict;
|
||||||
return stream;
|
return stream;
|
||||||
},
|
},
|
||||||
filter: function(stream, dict) {
|
filter: function(stream, dict, length) {
|
||||||
var filter = dict.get2("Filter", "F");
|
var filter = dict.get2("Filter", "F");
|
||||||
var params = dict.get2("DecodeParms", "DP");
|
var params = dict.get2("DecodeParms", "DP");
|
||||||
if (IsName(filter))
|
if (IsName(filter))
|
||||||
return this.makeFilter(stream, filter.name, params);
|
return this.makeFilter(stream, filter.name, length, params);
|
||||||
if (IsArray(filter)) {
|
if (IsArray(filter)) {
|
||||||
var filterArray = filter;
|
var filterArray = filter;
|
||||||
var paramsArray = params;
|
var paramsArray = params;
|
||||||
@ -1196,18 +1236,21 @@ var Parser = (function() {
|
|||||||
params = null;
|
params = null;
|
||||||
if (IsArray(paramsArray) && (i in paramsArray))
|
if (IsArray(paramsArray) && (i in paramsArray))
|
||||||
params = paramsArray[i];
|
params = paramsArray[i];
|
||||||
stream = this.makeFilter(stream, filter.name, params);
|
stream = this.makeFilter(stream, filter.name, length, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
},
|
},
|
||||||
makeFilter: function(stream, name, params) {
|
makeFilter: function(stream, name, length, params) {
|
||||||
if (name == "FlateDecode" || name == "Fl") {
|
if (name == "FlateDecode" || name == "Fl") {
|
||||||
if (params) {
|
if (params) {
|
||||||
return new PredictorStream(new FlateStream(stream), params);
|
return new PredictorStream(new FlateStream(stream), params);
|
||||||
}
|
}
|
||||||
return new FlateStream(stream);
|
return new FlateStream(stream);
|
||||||
|
} else if (name == "DCTDecode") {
|
||||||
|
var bytes = stream.getBytes(length);
|
||||||
|
return new JpegStream(bytes, stream.dict);
|
||||||
} else {
|
} else {
|
||||||
error("filter '" + name + "' not supported yet");
|
error("filter '" + name + "' not supported yet");
|
||||||
}
|
}
|
||||||
@ -2475,12 +2518,19 @@ var CanvasGraphics = (function() {
|
|||||||
|
|
||||||
var fontName = "";
|
var fontName = "";
|
||||||
var fontDescriptor = font.get("FontDescriptor");
|
var fontDescriptor = font.get("FontDescriptor");
|
||||||
if (fontDescriptor.num) {
|
if (fontDescriptor && fontDescriptor.num) {
|
||||||
var fontDescriptor = this.xref.fetchIfRef(fontDescriptor);
|
var fontDescriptor = this.xref.fetchIfRef(fontDescriptor);
|
||||||
fontName = fontDescriptor.get("FontName").name.replace("+", "_");
|
fontName = fontDescriptor.get("FontName").name.replace("+", "_");
|
||||||
Fonts.active = fontName;
|
Fonts.active = fontName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fontName) {
|
||||||
|
// TODO: fontDescriptor is not available, fallback to default font
|
||||||
|
this.current.fontSize = size;
|
||||||
|
this.ctx.font = this.current.fontSize + 'px sans-serif';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.current.fontSize = size;
|
this.current.fontSize = size;
|
||||||
this.ctx.font = this.current.fontSize +'px "' + fontName + '", Symbol';
|
this.ctx.font = this.current.fontSize +'px "' + fontName + '", Symbol';
|
||||||
},
|
},
|
||||||
@ -2508,9 +2558,9 @@ var CanvasGraphics = (function() {
|
|||||||
},
|
},
|
||||||
showText: function(text) {
|
showText: function(text) {
|
||||||
this.ctx.save();
|
this.ctx.save();
|
||||||
this.ctx.translate(0, 2 * this.current.y);
|
|
||||||
this.ctx.scale(1, -1);
|
|
||||||
this.ctx.transform.apply(this.ctx, this.current.textMatrix);
|
this.ctx.transform.apply(this.ctx, this.current.textMatrix);
|
||||||
|
this.ctx.scale(1, -1);
|
||||||
|
this.ctx.translate(0, -2 * this.current.y);
|
||||||
this.ctx.fillText(Fonts.chars2Unicode(text), this.current.x, this.current.y);
|
this.ctx.fillText(Fonts.chars2Unicode(text), this.current.x, this.current.y);
|
||||||
this.current.x += this.ctx.measureText(text).width;
|
this.current.x += this.ctx.measureText(text).width;
|
||||||
|
|
||||||
@ -2882,10 +2932,21 @@ var CanvasGraphics = (function() {
|
|||||||
|
|
||||||
if (w < 1 || h < 1)
|
if (w < 1 || h < 1)
|
||||||
error("Invalid image width or height");
|
error("Invalid image width or height");
|
||||||
|
|
||||||
var ctx = this.ctx;
|
var ctx = this.ctx;
|
||||||
// scale the image to the unit square
|
// scale the image to the unit square
|
||||||
ctx.scale(1/w, 1/h);
|
ctx.scale(1/w, -1/h);
|
||||||
|
|
||||||
|
// If the platform can render the image format directly, the
|
||||||
|
// stream has a getImage property which directly returns a
|
||||||
|
// suitable DOM Image object.
|
||||||
|
if (image.getImage) {
|
||||||
|
var domImage = image.getImage();
|
||||||
|
ctx.drawImage(domImage, 0, 0, domImage.width, domImage.height,
|
||||||
|
0, -h, w, h);
|
||||||
|
this.restore();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var interpolate = dict.get2("Interpolate", "I");
|
var interpolate = dict.get2("Interpolate", "I");
|
||||||
if (!IsBool(interpolate))
|
if (!IsBool(interpolate))
|
||||||
@ -2991,7 +3052,7 @@ var CanvasGraphics = (function() {
|
|||||||
switch (numComps) {
|
switch (numComps) {
|
||||||
case 1:
|
case 1:
|
||||||
for (var i = 0; i < length; i += 4) {
|
for (var i = 0; i < length; i += 4) {
|
||||||
var p = imgArray[imageIdx++];
|
var p = imgArray[imgIdx++];
|
||||||
pixels[i] = p;
|
pixels[i] = p;
|
||||||
pixels[i+1] = p;
|
pixels[i+1] = p;
|
||||||
pixels[i+2] = p;
|
pixels[i+2] = p;
|
||||||
@ -3018,7 +3079,7 @@ var CanvasGraphics = (function() {
|
|||||||
switch (numComps) {
|
switch (numComps) {
|
||||||
case 1:
|
case 1:
|
||||||
for (var i = 0; i < length; i += 4) {
|
for (var i = 0; i < length; i += 4) {
|
||||||
var p = imgArray[imageIdx++];
|
var p = imgArray[imgIdx++];
|
||||||
pixels[i] = p;
|
pixels[i] = p;
|
||||||
pixels[i+1] = p;
|
pixels[i+1] = p;
|
||||||
pixels[i+2] = p;
|
pixels[i+2] = p;
|
||||||
@ -3038,7 +3099,7 @@ var CanvasGraphics = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tmpCtx.putImageData(imgData, 0, 0);
|
tmpCtx.putImageData(imgData, 0, 0);
|
||||||
ctx.drawImage(tmpCanvas, 0, 0);
|
ctx.drawImage(tmpCanvas, 0, -h);
|
||||||
this.restore();
|
this.restore();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user