Merge branch 'master' of https://github.com/andreasgal/pdf.js.git into links
This commit is contained in:
commit
18172c1b4d
52
fonts.js
52
fonts.js
@ -1469,7 +1469,7 @@ var Type1Parser = function() {
|
|||||||
var value = '';
|
var value = '';
|
||||||
var count = array.length;
|
var count = array.length;
|
||||||
for (var i = 0; i < count; i++) {
|
for (var i = 0; i < count; i++) {
|
||||||
value = parseInt(array[i]);
|
value = array[i];
|
||||||
|
|
||||||
if (value < 32) {
|
if (value < 32) {
|
||||||
var command = null;
|
var command = null;
|
||||||
@ -1480,7 +1480,8 @@ var Type1Parser = function() {
|
|||||||
if (escape == 16) {
|
if (escape == 16) {
|
||||||
var index = charstring.pop();
|
var index = charstring.pop();
|
||||||
var argc = charstring.pop();
|
var argc = charstring.pop();
|
||||||
var data = charstring.pop();
|
for (var j = 0; j < argc; j++)
|
||||||
|
charstring.push('drop');
|
||||||
|
|
||||||
// If the flex mechanishm is not used in a font program, Adobe
|
// If the flex mechanishm is not used in a font program, Adobe
|
||||||
// state that that entries 0, 1 and 2 can simply be replace by
|
// state that that entries 0, 1 and 2 can simply be replace by
|
||||||
@ -1532,11 +1533,11 @@ var Type1Parser = function() {
|
|||||||
|
|
||||||
value = command;
|
value = command;
|
||||||
} else if (value <= 246) {
|
} else if (value <= 246) {
|
||||||
value = parseInt(value) - 139;
|
value = value - 139;
|
||||||
} else if (value <= 250) {
|
} else if (value <= 250) {
|
||||||
value = ((value - 247) * 256) + parseInt(array[++i]) + 108;
|
value = ((value - 247) * 256) + array[++i] + 108;
|
||||||
} else if (value <= 254) {
|
} else if (value <= 254) {
|
||||||
value = -((value - 251) * 256) - parseInt(array[++i]) - 108;
|
value = -((value - 251) * 256) - array[++i] - 108;
|
||||||
} else {
|
} else {
|
||||||
value = (array[++i] & 0xff) << 24 | (array[++i] & 0xff) << 16 |
|
value = (array[++i] & 0xff) << 24 | (array[++i] & 0xff) << 16 |
|
||||||
(array[++i] & 0xff) << 8 | (array[++i] & 0xff) << 0;
|
(array[++i] & 0xff) << 8 | (array[++i] & 0xff) << 0;
|
||||||
@ -1598,6 +1599,17 @@ var Type1Parser = function() {
|
|||||||
var c = '';
|
var c = '';
|
||||||
var count = eexecStr.length;
|
var count = eexecStr.length;
|
||||||
for (var i = 0; i < count; i++) {
|
for (var i = 0; i < count; i++) {
|
||||||
|
var getToken = function() {
|
||||||
|
while(i < count && (eexecStr[i] == ' ' || eexecStr[i] == '\n'))
|
||||||
|
++i;
|
||||||
|
|
||||||
|
var t = '';
|
||||||
|
while(i < count && !(eexecStr[i] == ' ' || eexecStr[i] == '\n'))
|
||||||
|
t += eexecStr[i++];
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
var c = eexecStr[i];
|
var c = eexecStr[i];
|
||||||
|
|
||||||
if ((glyphsSection || subrsSection) && c == 'R') {
|
if ((glyphsSection || subrsSection) && c == 'R') {
|
||||||
@ -1627,7 +1639,25 @@ var Type1Parser = function() {
|
|||||||
glyphsSection = true;
|
glyphsSection = true;
|
||||||
break;
|
break;
|
||||||
case '/Subrs':
|
case '/Subrs':
|
||||||
subrsSection = true;
|
++i;
|
||||||
|
var num = parseInt(getToken());
|
||||||
|
getToken(); // read in 'array'
|
||||||
|
for (var j = 0; j < num; ++j) {
|
||||||
|
var t = getToken(); // read in 'dup'
|
||||||
|
if (t == 'ND')
|
||||||
|
break;
|
||||||
|
var index = parseInt(getToken());
|
||||||
|
if (index > j)
|
||||||
|
j = index;
|
||||||
|
var length = parseInt(getToken());
|
||||||
|
getToken(); // read in 'RD'
|
||||||
|
var data = eexec.slice(i + 1, i + 1 + length);
|
||||||
|
var encoded = decrypt(data, kCharStringsEncryptionKey, 4);
|
||||||
|
var str = decodeCharString(encoded);
|
||||||
|
i = i + 1 + length;
|
||||||
|
getToken(); //read in 'NP'
|
||||||
|
program.subrs[index] = str.charstring;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case '/BlueValues':
|
case '/BlueValues':
|
||||||
case '/OtherBlues':
|
case '/OtherBlues':
|
||||||
@ -1909,8 +1939,13 @@ CFF.prototype = {
|
|||||||
for (var i = 0; i < bias; i++)
|
for (var i = 0; i < bias; i++)
|
||||||
type2Subrs.push([0x0B]);
|
type2Subrs.push([0x0B]);
|
||||||
|
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++) {
|
||||||
type2Subrs.push(this.flattenCharstring(type1Subrs[i], this.commandsMap));
|
var subr = type1Subrs[i];
|
||||||
|
if (!subr)
|
||||||
|
subr = [0x0B];
|
||||||
|
|
||||||
|
type2Subrs.push(this.flattenCharstring(subr, this.commandsMap));
|
||||||
|
}
|
||||||
|
|
||||||
return type2Subrs;
|
return type2Subrs;
|
||||||
},
|
},
|
||||||
@ -1932,6 +1967,7 @@ CFF.prototype = {
|
|||||||
'sub': [12, 11],
|
'sub': [12, 11],
|
||||||
'div': [12, 12],
|
'div': [12, 12],
|
||||||
'pop': [1, 12, 18],
|
'pop': [1, 12, 18],
|
||||||
|
'drop' : [12, 18],
|
||||||
'endchar': 14,
|
'endchar': 14,
|
||||||
'rmoveto': 21,
|
'rmoveto': 21,
|
||||||
'hmoveto': 22,
|
'hmoveto': 22,
|
||||||
|
169
pdf.js
169
pdf.js
@ -806,6 +806,11 @@ var JpegStream = (function() {
|
|||||||
|
|
||||||
// create DOM image
|
// create DOM image
|
||||||
var img = new Image();
|
var img = new Image();
|
||||||
|
img.onload = (function() {
|
||||||
|
this.loaded = true;
|
||||||
|
if (this.onLoad)
|
||||||
|
this.onLoad();
|
||||||
|
}).bind(this);
|
||||||
img.src = 'data:image/jpeg;base64,' + window.btoa(bytesToString(bytes));
|
img.src = 'data:image/jpeg;base64,' + window.btoa(bytesToString(bytes));
|
||||||
this.domImage = img;
|
this.domImage = img;
|
||||||
}
|
}
|
||||||
@ -822,6 +827,44 @@ var JpegStream = (function() {
|
|||||||
return constructor;
|
return constructor;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// Simple object to track the loading images
|
||||||
|
// Initialy for every that is in loading call imageLoading()
|
||||||
|
// and, when images onload is fired, call imageLoaded()
|
||||||
|
// When all images are loaded, the onLoad event is fired.
|
||||||
|
var ImagesLoader = (function() {
|
||||||
|
function constructor() {
|
||||||
|
this.loading = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor.prototype = {
|
||||||
|
imageLoading: function() {
|
||||||
|
++this.loading;
|
||||||
|
},
|
||||||
|
|
||||||
|
imageLoaded: function() {
|
||||||
|
if (--this.loading == 0 && this.onLoad) {
|
||||||
|
this.onLoad();
|
||||||
|
delete this.onLoad;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
bind: function(jpegStream) {
|
||||||
|
if (jpegStream.loaded)
|
||||||
|
return;
|
||||||
|
this.imageLoading();
|
||||||
|
jpegStream.onLoad = this.imageLoaded.bind(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
notifyOnLoad: function(callback) {
|
||||||
|
if (this.loading == 0)
|
||||||
|
callback();
|
||||||
|
this.onLoad = callback;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return constructor;
|
||||||
|
})();
|
||||||
|
|
||||||
var DecryptStream = (function() {
|
var DecryptStream = (function() {
|
||||||
function constructor(str, decrypt) {
|
function constructor(str, decrypt) {
|
||||||
this.str = str;
|
this.str = str;
|
||||||
@ -1990,7 +2033,7 @@ var LZWStream = (function() {
|
|||||||
this.cachedData = 0;
|
this.cachedData = 0;
|
||||||
this.bitsCached = 0;
|
this.bitsCached = 0;
|
||||||
|
|
||||||
var maxLzwDictionarySize = 4097;
|
var maxLzwDictionarySize = 4096;
|
||||||
var lzwState = {
|
var lzwState = {
|
||||||
earlyChange: earlyChange,
|
earlyChange: earlyChange,
|
||||||
codeLength: 9,
|
codeLength: 9,
|
||||||
@ -2036,6 +2079,9 @@ var LZWStream = (function() {
|
|||||||
var i, j, q;
|
var i, j, q;
|
||||||
|
|
||||||
var lzwState = this.lzwState;
|
var lzwState = this.lzwState;
|
||||||
|
if (!lzwState)
|
||||||
|
return; // eof was found
|
||||||
|
|
||||||
var earlyChange = lzwState.earlyChange;
|
var earlyChange = lzwState.earlyChange;
|
||||||
var nextCode = lzwState.nextCode;
|
var nextCode = lzwState.nextCode;
|
||||||
var dictionaryValues = lzwState.dictionaryValues;
|
var dictionaryValues = lzwState.dictionaryValues;
|
||||||
@ -2073,6 +2119,7 @@ var LZWStream = (function() {
|
|||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
this.eof = true;
|
this.eof = true;
|
||||||
|
delete this.lzwState;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3123,6 +3170,7 @@ var Page = (function() {
|
|||||||
create: Date.now(),
|
create: Date.now(),
|
||||||
compile: 0.0,
|
compile: 0.0,
|
||||||
fonts: 0.0,
|
fonts: 0.0,
|
||||||
|
images: 0.0,
|
||||||
render: 0.0
|
render: 0.0
|
||||||
};
|
};
|
||||||
this.xref = xref;
|
this.xref = xref;
|
||||||
@ -3200,25 +3248,33 @@ var Page = (function() {
|
|||||||
|
|
||||||
var gfx = new CanvasGraphics(canvasCtx);
|
var gfx = new CanvasGraphics(canvasCtx);
|
||||||
var fonts = [];
|
var fonts = [];
|
||||||
|
var images = new ImagesLoader()
|
||||||
|
|
||||||
this.compile(gfx, fonts);
|
this.compile(gfx, fonts, images);
|
||||||
stats.compile = Date.now();
|
stats.compile = Date.now();
|
||||||
|
|
||||||
|
var displayContinuation = function() {
|
||||||
|
// Always defer call to display() to work around bug in
|
||||||
|
// Firefox error reporting from XHR callbacks.
|
||||||
|
setTimeout(function() {
|
||||||
|
var exc = null;
|
||||||
|
try {
|
||||||
|
self.display(gfx);
|
||||||
|
stats.render = Date.now();
|
||||||
|
} catch (e) {
|
||||||
|
exc = e.toString();
|
||||||
|
}
|
||||||
|
continuation(exc);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
var fontObjs = FontLoader.bind(
|
var fontObjs = FontLoader.bind(
|
||||||
fonts,
|
fonts,
|
||||||
function() {
|
function() {
|
||||||
stats.fonts = Date.now();
|
stats.fonts = Date.now();
|
||||||
// Always defer call to display() to work around bug in
|
images.notifyOnLoad(function() {
|
||||||
// Firefox error reporting from XHR callbacks.
|
stats.images = Date.now();
|
||||||
setTimeout(function() {
|
displayContinuation();
|
||||||
var exc = null;
|
|
||||||
try {
|
|
||||||
self.display(gfx);
|
|
||||||
stats.render = Date.now();
|
|
||||||
} catch (e) {
|
|
||||||
exc = e.toString();
|
|
||||||
}
|
|
||||||
continuation(exc);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3227,7 +3283,7 @@ var Page = (function() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
compile: function(gfx, fonts) {
|
compile: function(gfx, fonts, images) {
|
||||||
if (this.code) {
|
if (this.code) {
|
||||||
// content was compiled
|
// content was compiled
|
||||||
return;
|
return;
|
||||||
@ -3239,14 +3295,14 @@ var Page = (function() {
|
|||||||
if (!IsArray(this.content)) {
|
if (!IsArray(this.content)) {
|
||||||
// content is not an array, shortcut
|
// content is not an array, shortcut
|
||||||
content = xref.fetchIfRef(this.content);
|
content = xref.fetchIfRef(this.content);
|
||||||
this.code = gfx.compile(content, xref, resources, fonts);
|
this.code = gfx.compile(content, xref, resources, fonts, images);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// the content is an array, compiling all items
|
// the content is an array, compiling all items
|
||||||
var i, n = this.content.length, compiledItems = [];
|
var i, n = this.content.length, compiledItems = [];
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
content = xref.fetchIfRef(this.content[i]);
|
content = xref.fetchIfRef(this.content[i]);
|
||||||
compiledItems.push(gfx.compile(content, xref, resources, fonts));
|
compiledItems.push(gfx.compile(content, xref, resources, fonts, images));
|
||||||
}
|
}
|
||||||
// creating the function that executes all compiled items
|
// creating the function that executes all compiled items
|
||||||
this.code = function(gfx) {
|
this.code = function(gfx) {
|
||||||
@ -3836,7 +3892,7 @@ var PartialEvaluator = (function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
constructor.prototype = {
|
constructor.prototype = {
|
||||||
eval: function(stream, xref, resources, fonts) {
|
eval: function(stream, xref, resources, fonts, images) {
|
||||||
resources = xref.fetchIfRef(resources) || new Dict();
|
resources = xref.fetchIfRef(resources) || new Dict();
|
||||||
var xobjs = xref.fetchIfRef(resources.get('XObject')) || new Dict();
|
var xobjs = xref.fetchIfRef(resources.get('XObject')) || new Dict();
|
||||||
var patterns = xref.fetchIfRef(resources.get('Pattern')) || new Dict();
|
var patterns = xref.fetchIfRef(resources.get('Pattern')) || new Dict();
|
||||||
@ -3881,8 +3937,10 @@ var PartialEvaluator = (function() {
|
|||||||
|
|
||||||
if ('Form' == type.name) {
|
if ('Form' == type.name) {
|
||||||
args[0].code = this.eval(xobj, xref, xobj.dict.get('Resources'),
|
args[0].code = this.eval(xobj, xref, xobj.dict.get('Resources'),
|
||||||
fonts);
|
fonts, images);
|
||||||
}
|
}
|
||||||
|
if (xobj instanceof JpegStream)
|
||||||
|
images.bind(xobj); // monitoring image load
|
||||||
}
|
}
|
||||||
} else if (cmd == 'Tf') { // eagerly collect all fonts
|
} else if (cmd == 'Tf') { // eagerly collect all fonts
|
||||||
var fontRes = resources.get('Font');
|
var fontRes = resources.get('Font');
|
||||||
@ -4202,7 +4260,11 @@ var CanvasExtraState = (function() {
|
|||||||
constructor.prototype = {
|
constructor.prototype = {
|
||||||
clone: function canvasextra_clone() {
|
clone: function canvasextra_clone() {
|
||||||
return Object.create(this);
|
return Object.create(this);
|
||||||
}
|
},
|
||||||
|
setCurrentPoint: function canvasextra_setCurrentPoint(x, y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
return constructor;
|
return constructor;
|
||||||
})();
|
})();
|
||||||
@ -4254,9 +4316,9 @@ var CanvasGraphics = (function() {
|
|||||||
this.ctx.scale(cw / mediaBox.width, ch / mediaBox.height);
|
this.ctx.scale(cw / mediaBox.width, ch / mediaBox.height);
|
||||||
},
|
},
|
||||||
|
|
||||||
compile: function(stream, xref, resources, fonts) {
|
compile: function(stream, xref, resources, fonts, images) {
|
||||||
var pe = new PartialEvaluator();
|
var pe = new PartialEvaluator();
|
||||||
return pe.eval(stream, xref, resources, fonts);
|
return pe.eval(stream, xref, resources, fonts, images);
|
||||||
},
|
},
|
||||||
|
|
||||||
execute: function(code, xref, resources) {
|
execute: function(code, xref, resources) {
|
||||||
@ -4329,18 +4391,24 @@ var CanvasGraphics = (function() {
|
|||||||
// Path
|
// Path
|
||||||
moveTo: function(x, y) {
|
moveTo: function(x, y) {
|
||||||
this.ctx.moveTo(x, y);
|
this.ctx.moveTo(x, y);
|
||||||
|
this.current.setCurrentPoint(x, y);
|
||||||
},
|
},
|
||||||
lineTo: function(x, y) {
|
lineTo: function(x, y) {
|
||||||
this.ctx.lineTo(x, y);
|
this.ctx.lineTo(x, y);
|
||||||
|
this.current.setCurrentPoint(x, y);
|
||||||
},
|
},
|
||||||
curveTo: function(x1, y1, x2, y2, x3, y3) {
|
curveTo: function(x1, y1, x2, y2, x3, y3) {
|
||||||
this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
|
this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
|
||||||
|
this.current.setCurrentPoint(x3, y3);
|
||||||
},
|
},
|
||||||
curveTo2: function(x2, y2, x3, y3) {
|
curveTo2: function(x2, y2, x3, y3) {
|
||||||
TODO("'v' operator: need current point in gfx context");
|
var current = this.current;
|
||||||
|
this.ctx.bezierCurveTo(current.x, current.y, x2, y2, x3, y3);
|
||||||
|
current.setCurrentPoint(x3, y3);
|
||||||
},
|
},
|
||||||
curveTo3: function(x1, y1, x3, y3) {
|
curveTo3: function(x1, y1, x3, y3) {
|
||||||
this.curveTo(x1, y1, x3, y3, x3, y3);
|
this.curveTo(x1, y1, x3, y3, x3, y3);
|
||||||
|
this.current.setCurrentPoint(x3, y3);
|
||||||
},
|
},
|
||||||
closePath: function() {
|
closePath: function() {
|
||||||
this.ctx.closePath();
|
this.ctx.closePath();
|
||||||
@ -5757,7 +5825,7 @@ var PDFFunction = (function() {
|
|||||||
if (!typeFn)
|
if (!typeFn)
|
||||||
error('Unknown type of function');
|
error('Unknown type of function');
|
||||||
|
|
||||||
typeFn.call(this, fn, dict);
|
typeFn.call(this, fn, dict, xref);
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor.prototype = {
|
constructor.prototype = {
|
||||||
@ -5902,9 +5970,58 @@ var PDFFunction = (function() {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
constructStiched: function() {
|
constructStiched: function(fn, dict, xref) {
|
||||||
TODO('unhandled type of function');
|
var domain = dict.get('Domain');
|
||||||
this.func = function() { return [255, 105, 180]; }
|
var range = dict.get('Range');
|
||||||
|
|
||||||
|
if (!domain)
|
||||||
|
error('No domain');
|
||||||
|
|
||||||
|
var inputSize = domain.length / 2;
|
||||||
|
if (inputSize != 1)
|
||||||
|
error('Bad domain for stiched function');
|
||||||
|
|
||||||
|
var fnRefs = dict.get('Functions');
|
||||||
|
var fns = [];
|
||||||
|
for (var i = 0, ii = fnRefs.length; i < ii; ++i)
|
||||||
|
fns.push(new PDFFunction(xref, xref.fetchIfRef(fnRefs[i])));
|
||||||
|
|
||||||
|
var bounds = dict.get('Bounds');
|
||||||
|
var encode = dict.get('Encode');
|
||||||
|
|
||||||
|
this.func = function(args) {
|
||||||
|
var clip = function(v, min, max) {
|
||||||
|
if (v > max)
|
||||||
|
v = max;
|
||||||
|
else if (v < min)
|
||||||
|
v = min;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clip to domain
|
||||||
|
var v = clip(args[0], domain[0], domain[1]);
|
||||||
|
// calulate which bound the value is in
|
||||||
|
for (var i = 0, ii = bounds.length; i < ii; ++i) {
|
||||||
|
if (v < bounds[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// encode value into domain of function
|
||||||
|
var dmin = domain[0];
|
||||||
|
if (i > 0)
|
||||||
|
dmin = bounds[i - 1];
|
||||||
|
var dmax = domain[1];
|
||||||
|
if (i < bounds.length)
|
||||||
|
dmax = bounds[i];
|
||||||
|
|
||||||
|
var rmin = encode[2 * i];
|
||||||
|
var rmax = encode[2 * i + 1];
|
||||||
|
|
||||||
|
var v2 = rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin);
|
||||||
|
|
||||||
|
// call the appropropriate function
|
||||||
|
return fns[i].func([v2]);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
constructPostScript: function() {
|
constructPostScript: function() {
|
||||||
TODO('unhandled type of function');
|
TODO('unhandled type of function');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user