Make Dict handle all the fetching of Refs.
This commit is contained in:
parent
6ec62cd148
commit
8a45177be0
@ -70,7 +70,7 @@ var ColorSpace = (function ColorSpaceClosure() {
|
|||||||
|
|
||||||
ColorSpace.parseToIR = function colorSpaceParseToIR(cs, xref, res) {
|
ColorSpace.parseToIR = function colorSpaceParseToIR(cs, xref, res) {
|
||||||
if (isName(cs)) {
|
if (isName(cs)) {
|
||||||
var colorSpaces = xref.fetchIfRef(res.get('ColorSpace'));
|
var colorSpaces = res.get('ColorSpace');
|
||||||
if (isDict(colorSpaces)) {
|
if (isDict(colorSpaces)) {
|
||||||
var refcs = colorSpaces.get(cs.name);
|
var refcs = colorSpaces.get(cs.name);
|
||||||
if (refcs)
|
if (refcs)
|
||||||
@ -152,7 +152,7 @@ var ColorSpace = (function ColorSpaceClosure() {
|
|||||||
var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3]));
|
var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3]));
|
||||||
return ['AlternateCS', numComps, alt, tintFnIR];
|
return ['AlternateCS', numComps, alt, tintFnIR];
|
||||||
case 'Lab':
|
case 'Lab':
|
||||||
var params = cs[1].map;
|
var params = cs[1].getAll();
|
||||||
return ['LabCS', params];
|
return ['LabCS', params];
|
||||||
default:
|
default:
|
||||||
error('unimplemented color space object "' + mode + '"');
|
error('unimplemented color space object "' + mode + '"');
|
||||||
|
37
src/core.js
37
src/core.js
@ -73,13 +73,13 @@ var Page = (function PageClosure() {
|
|||||||
|
|
||||||
Page.prototype = {
|
Page.prototype = {
|
||||||
getPageProp: function pageGetPageProp(key) {
|
getPageProp: function pageGetPageProp(key) {
|
||||||
return this.xref.fetchIfRef(this.pageDict.get(key));
|
return this.pageDict.get(key);
|
||||||
},
|
},
|
||||||
inheritPageProp: function pageInheritPageProp(key) {
|
inheritPageProp: function pageInheritPageProp(key) {
|
||||||
var dict = this.pageDict;
|
var dict = this.pageDict;
|
||||||
var obj = dict.get(key);
|
var obj = dict.get(key);
|
||||||
while (obj === undefined) {
|
while (obj === undefined) {
|
||||||
dict = this.xref.fetchIfRef(dict.get('Parent'));
|
dict = dict.get('Parent');
|
||||||
if (!dict)
|
if (!dict)
|
||||||
break;
|
break;
|
||||||
obj = dict.get(key);
|
obj = dict.get(key);
|
||||||
@ -199,8 +199,8 @@ var Page = (function PageClosure() {
|
|||||||
this.stats.time('Build IR Queue');
|
this.stats.time('Build IR Queue');
|
||||||
|
|
||||||
var xref = this.xref;
|
var xref = this.xref;
|
||||||
var content = xref.fetchIfRef(this.content);
|
var content = this.content;
|
||||||
var resources = xref.fetchIfRef(this.resources);
|
var resources = this.resources;
|
||||||
if (isArray(content)) {
|
if (isArray(content)) {
|
||||||
// fetching items
|
// fetching items
|
||||||
var i, n = content.length;
|
var i, n = content.length;
|
||||||
@ -242,8 +242,8 @@ var Page = (function PageClosure() {
|
|||||||
var stats = this.stats;
|
var stats = this.stats;
|
||||||
stats.time('Rendering');
|
stats.time('Rendering');
|
||||||
var xref = this.xref;
|
var xref = this.xref;
|
||||||
var resources = xref.fetchIfRef(this.resources);
|
var resources = this.resources;
|
||||||
var mediaBox = xref.fetchIfRef(this.mediaBox);
|
var mediaBox = this.mediaBox;
|
||||||
assertWellFormed(isDict(resources), 'invalid page resources');
|
assertWellFormed(isDict(resources), 'invalid page resources');
|
||||||
|
|
||||||
gfx.xref = xref;
|
gfx.xref = xref;
|
||||||
@ -307,7 +307,7 @@ var Page = (function PageClosure() {
|
|||||||
function getInheritableProperty(annotation, name) {
|
function getInheritableProperty(annotation, name) {
|
||||||
var item = annotation;
|
var item = annotation;
|
||||||
while (item && !item.has(name)) {
|
while (item && !item.has(name)) {
|
||||||
item = xref.fetchIfRef(item.get('Parent'));
|
item = item.get('Parent');
|
||||||
}
|
}
|
||||||
if (!item)
|
if (!item)
|
||||||
return null;
|
return null;
|
||||||
@ -330,7 +330,7 @@ var Page = (function PageClosure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var annotations = xref.fetchIfRef(this.annotations) || [];
|
var annotations = this.annotations || [];
|
||||||
var i, n = annotations.length;
|
var i, n = annotations.length;
|
||||||
var items = [];
|
var items = [];
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
@ -353,7 +353,7 @@ var Page = (function PageClosure() {
|
|||||||
item.height = Math.abs(topLeftCorner.y - bottomRightCorner.y);
|
item.height = Math.abs(topLeftCorner.y - bottomRightCorner.y);
|
||||||
switch (subtype.name) {
|
switch (subtype.name) {
|
||||||
case 'Link':
|
case 'Link':
|
||||||
var a = this.xref.fetchIfRef(annotation.get('A'));
|
var a = annotation.get('A');
|
||||||
if (a) {
|
if (a) {
|
||||||
switch (a.get('S').name) {
|
switch (a.get('S').name) {
|
||||||
case 'URI':
|
case 'URI':
|
||||||
@ -386,21 +386,22 @@ var Page = (function PageClosure() {
|
|||||||
var fieldName = [];
|
var fieldName = [];
|
||||||
var namedItem = annotation, ref = annotationRef;
|
var namedItem = annotation, ref = annotationRef;
|
||||||
while (namedItem) {
|
while (namedItem) {
|
||||||
var parentRef = namedItem.get('Parent');
|
var parent = namedItem.get('Parent');
|
||||||
var parent = xref.fetchIfRef(parentRef);
|
var parentRef = namedItem.getRaw('Parent');
|
||||||
var name = namedItem.get('T');
|
var name = namedItem.get('T');
|
||||||
if (name)
|
if (name) {
|
||||||
fieldName.unshift(stringToPDFString(name));
|
fieldName.unshift(stringToPDFString(name));
|
||||||
else {
|
} else {
|
||||||
// The field name is absent, that means more than one field
|
// The field name is absent, that means more than one field
|
||||||
// with the same name may exist. Replacing the empty name
|
// with the same name may exist. Replacing the empty name
|
||||||
// with the '`' plus index in the parent's 'Kids' array.
|
// with the '`' plus index in the parent's 'Kids' array.
|
||||||
// This is not in the PDF spec but necessary to id the
|
// This is not in the PDF spec but necessary to id the
|
||||||
// the input controls.
|
// the input controls.
|
||||||
var kids = xref.fetchIfRef(parent.get('Kids'));
|
var kids = parent.get('Kids');
|
||||||
var j, jj;
|
var j, jj;
|
||||||
for (j = 0, jj = kids.length; j < jj; j++) {
|
for (j = 0, jj = kids.length; j < jj; j++) {
|
||||||
if (kids[j].num == ref.num && kids[j].gen == ref.gen)
|
var kidRef = kids[j];
|
||||||
|
if (kidRef.num == ref.num && kidRef.gen == ref.gen)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fieldName.unshift('`' + j);
|
fieldName.unshift('`' + j);
|
||||||
@ -490,7 +491,7 @@ var PDFDocModel = (function PDFDocModelClosure() {
|
|||||||
assertWellFormed(stream.length > 0, 'stream must have data');
|
assertWellFormed(stream.length > 0, 'stream must have data');
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
this.setup();
|
this.setup();
|
||||||
this.acroForm = this.xref.fetchIfRef(this.catalog.catDict.get('AcroForm'));
|
this.acroForm = this.catalog.catDict.get('AcroForm');
|
||||||
}
|
}
|
||||||
|
|
||||||
function find(stream, needle, limit, backwards) {
|
function find(stream, needle, limit, backwards) {
|
||||||
@ -597,7 +598,7 @@ var PDFDocModel = (function PDFDocModelClosure() {
|
|||||||
getDocumentInfo: function pdfDocGetDocumentInfo() {
|
getDocumentInfo: function pdfDocGetDocumentInfo() {
|
||||||
var info;
|
var info;
|
||||||
if (this.xref.trailer.has('Info'))
|
if (this.xref.trailer.has('Info'))
|
||||||
info = this.xref.fetch(this.xref.trailer.get('Info'));
|
info = this.xref.trailer.get('Info');
|
||||||
|
|
||||||
return shadow(this, 'getDocumentInfo', info);
|
return shadow(this, 'getDocumentInfo', info);
|
||||||
},
|
},
|
||||||
@ -605,7 +606,7 @@ var PDFDocModel = (function PDFDocModelClosure() {
|
|||||||
var xref = this.xref, fileID;
|
var xref = this.xref, fileID;
|
||||||
if (xref.trailer.has('ID')) {
|
if (xref.trailer.has('ID')) {
|
||||||
fileID = '';
|
fileID = '';
|
||||||
var id = xref.fetchIfRef(xref.trailer.get('ID'))[0];
|
var id = xref.trailer.get('ID')[0];
|
||||||
id.split('').forEach(function(el) {
|
id.split('').forEach(function(el) {
|
||||||
fileID += Number(el.charCodeAt(0)).toString(16);
|
fileID += Number(el.charCodeAt(0)).toString(16);
|
||||||
});
|
});
|
||||||
|
@ -131,16 +131,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSetFont(fontName, fontRef) {
|
function handleSetFont(fontName, font) {
|
||||||
var loadedName = null;
|
var loadedName = null;
|
||||||
|
|
||||||
var fontRes = resources.get('Font');
|
var fontRes = resources.get('Font');
|
||||||
|
|
||||||
assert(fontRes, 'fontRes not available');
|
assert(fontRes, 'fontRes not available');
|
||||||
|
|
||||||
fontRes = xref.fetchIfRef(fontRes);
|
font = xref.fetchIfRef(font) || fontRes.get(fontName);
|
||||||
fontRef = fontRef || fontRes.get(fontName);
|
|
||||||
var font = xref.fetchIfRef(fontRef);
|
|
||||||
assertWellFormed(isDict(font));
|
assertWellFormed(isDict(font));
|
||||||
if (!font.translated) {
|
if (!font.translated) {
|
||||||
font.translated = self.translateFont(font, xref, resources,
|
font.translated = self.translateFont(font, xref, resources,
|
||||||
@ -250,10 +248,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
var fnArray = queue.fnArray, argsArray = queue.argsArray;
|
var fnArray = queue.fnArray, argsArray = queue.argsArray;
|
||||||
var dependencyArray = dependency || [];
|
var dependencyArray = dependency || [];
|
||||||
|
|
||||||
resources = xref.fetchIfRef(resources) || new Dict();
|
resources = resources || new Dict();
|
||||||
var xobjs = xref.fetchIfRef(resources.get('XObject')) || new Dict();
|
var xobjs = resources.get('XObject') || new Dict();
|
||||||
var patterns = xref.fetchIfRef(resources.get('Pattern')) || new Dict();
|
var patterns = resources.get('Pattern') || new Dict();
|
||||||
var parser = new Parser(new Lexer(stream), false);
|
var parser = new Parser(new Lexer(stream), false, xref);
|
||||||
var res = resources;
|
var res = resources;
|
||||||
var args = [], obj;
|
var args = [], obj;
|
||||||
var getObjBt = function getObjBt() {
|
var getObjBt = function getObjBt() {
|
||||||
@ -285,7 +283,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
var patternName = args[args.length - 1];
|
var patternName = args[args.length - 1];
|
||||||
// SCN/scn applies patterns along with normal colors
|
// SCN/scn applies patterns along with normal colors
|
||||||
if (isName(patternName)) {
|
if (isName(patternName)) {
|
||||||
var pattern = xref.fetchIfRef(patterns.get(patternName.name));
|
var pattern = patterns.get(patternName.name);
|
||||||
if (pattern) {
|
if (pattern) {
|
||||||
var dict = isStream(pattern) ? pattern.dict : pattern;
|
var dict = isStream(pattern) ? pattern.dict : pattern;
|
||||||
var typeNum = dict.get('PatternType');
|
var typeNum = dict.get('PatternType');
|
||||||
@ -303,7 +301,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
args = TilingPattern.getIR(operatorList, dict, args);
|
args = TilingPattern.getIR(operatorList, dict, args);
|
||||||
}
|
}
|
||||||
else if (typeNum == SHADING_PATTERN) {
|
else if (typeNum == SHADING_PATTERN) {
|
||||||
var shading = xref.fetchIfRef(dict.get('Shading'));
|
var shading = dict.get('Shading');
|
||||||
var matrix = dict.get('Matrix');
|
var matrix = dict.get('Matrix');
|
||||||
var pattern = Pattern.parseShading(shading, matrix, xref, res,
|
var pattern = Pattern.parseShading(shading, matrix, xref, res,
|
||||||
null /*ctx*/);
|
null /*ctx*/);
|
||||||
@ -318,7 +316,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
var name = args[0].name;
|
var name = args[0].name;
|
||||||
var xobj = xobjs.get(name);
|
var xobj = xobjs.get(name);
|
||||||
if (xobj) {
|
if (xobj) {
|
||||||
xobj = xref.fetchIfRef(xobj);
|
|
||||||
assertWellFormed(isStream(xobj), 'XObject should be a stream');
|
assertWellFormed(isStream(xobj), 'XObject should be a stream');
|
||||||
|
|
||||||
var type = xobj.dict.get('Subtype');
|
var type = xobj.dict.get('Subtype');
|
||||||
@ -369,11 +366,11 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
args = [ColorSpace.parseToIR(args[0], xref, resources)];
|
args = [ColorSpace.parseToIR(args[0], xref, resources)];
|
||||||
break;
|
break;
|
||||||
case 'shadingFill':
|
case 'shadingFill':
|
||||||
var shadingRes = xref.fetchIfRef(res.get('Shading'));
|
var shadingRes = res.get('Shading');
|
||||||
if (!shadingRes)
|
if (!shadingRes)
|
||||||
error('No shading resource found');
|
error('No shading resource found');
|
||||||
|
|
||||||
var shading = xref.fetchIfRef(shadingRes.get(args[0].name));
|
var shading = shadingRes.get(args[0].name);
|
||||||
if (!shading)
|
if (!shading)
|
||||||
error('No shading object found');
|
error('No shading object found');
|
||||||
|
|
||||||
@ -385,12 +382,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
break;
|
break;
|
||||||
case 'setGState':
|
case 'setGState':
|
||||||
var dictName = args[0];
|
var dictName = args[0];
|
||||||
var extGState = xref.fetchIfRef(resources.get('ExtGState'));
|
var extGState = resources.get('ExtGState');
|
||||||
|
|
||||||
if (!isDict(extGState) || !extGState.has(dictName.name))
|
if (!isDict(extGState) || !extGState.has(dictName.name))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
var gsState = xref.fetchIfRef(extGState.get(dictName.name));
|
var gsState = extGState.get(dictName.name);
|
||||||
|
|
||||||
// This array holds the converted/processed state data.
|
// This array holds the converted/processed state data.
|
||||||
var gsStateObj = [];
|
var gsStateObj = [];
|
||||||
@ -469,7 +466,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
|
|
||||||
if (properties.composite) {
|
if (properties.composite) {
|
||||||
// CIDSystemInfo helps to match CID to glyphs
|
// CIDSystemInfo helps to match CID to glyphs
|
||||||
var cidSystemInfo = xref.fetchIfRef(dict.get('CIDSystemInfo'));
|
var cidSystemInfo = dict.get('CIDSystemInfo');
|
||||||
if (isDict(cidSystemInfo)) {
|
if (isDict(cidSystemInfo)) {
|
||||||
properties.cidSystemInfo = {
|
properties.cidSystemInfo = {
|
||||||
registry: cidSystemInfo.get('Registry'),
|
registry: cidSystemInfo.get('Registry'),
|
||||||
@ -478,7 +475,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var cidToGidMap = xref.fetchIfRef(dict.get('CIDToGIDMap'));
|
var cidToGidMap = dict.get('CIDToGIDMap');
|
||||||
if (isStream(cidToGidMap))
|
if (isStream(cidToGidMap))
|
||||||
properties.cidToGidMap = this.readCidToGidMap(cidToGidMap);
|
properties.cidToGidMap = this.readCidToGidMap(cidToGidMap);
|
||||||
}
|
}
|
||||||
@ -489,7 +486,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
Encodings.symbolsEncoding : Encodings.StandardEncoding;
|
Encodings.symbolsEncoding : Encodings.StandardEncoding;
|
||||||
var hasEncoding = dict.has('Encoding');
|
var hasEncoding = dict.has('Encoding');
|
||||||
if (hasEncoding) {
|
if (hasEncoding) {
|
||||||
var encoding = xref.fetchIfRef(dict.get('Encoding'));
|
var encoding = dict.get('Encoding');
|
||||||
if (isDict(encoding)) {
|
if (isDict(encoding)) {
|
||||||
var baseName = encoding.get('BaseEncoding');
|
var baseName = encoding.get('BaseEncoding');
|
||||||
if (baseName)
|
if (baseName)
|
||||||
@ -523,7 +520,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
|
|
||||||
readToUnicode:
|
readToUnicode:
|
||||||
function partialEvaluatorReadToUnicode(toUnicode, xref) {
|
function partialEvaluatorReadToUnicode(toUnicode, xref) {
|
||||||
var cmapObj = xref.fetchIfRef(toUnicode);
|
var cmapObj = toUnicode;
|
||||||
var charToUnicode = [];
|
var charToUnicode = [];
|
||||||
if (isName(cmapObj)) {
|
if (isName(cmapObj)) {
|
||||||
var isIdentityMap = cmapObj.name.substr(0, 9) == 'Identity-';
|
var isIdentityMap = cmapObj.name.substr(0, 9) == 'Identity-';
|
||||||
@ -666,9 +663,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
var glyphsWidths = [];
|
var glyphsWidths = [];
|
||||||
var defaultWidth = 0;
|
var defaultWidth = 0;
|
||||||
if (properties.composite) {
|
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) {
|
if (widths) {
|
||||||
var start = 0, end = 0;
|
var start = 0, end = 0;
|
||||||
for (var i = 0, ii = widths.length; i < ii; i++) {
|
for (var i = 0, ii = widths.length; i < ii; i++) {
|
||||||
@ -689,7 +686,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var firstChar = properties.firstChar;
|
var firstChar = properties.firstChar;
|
||||||
var widths = xref.fetchIfRef(dict.get('Widths'));
|
var widths = dict.get('Widths');
|
||||||
if (widths) {
|
if (widths) {
|
||||||
var j = firstChar;
|
var j = firstChar;
|
||||||
for (var i = 0, ii = widths.length; i < ii; i++)
|
for (var i = 0, ii = widths.length; i < ii; i++)
|
||||||
@ -742,10 +739,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
if (!df)
|
if (!df)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (isRef(df))
|
dict = isArray(df) ? xref.fetchIfRef(df[0]) : df;
|
||||||
df = xref.fetch(df);
|
|
||||||
|
|
||||||
dict = xref.fetchIfRef(isRef(df) ? df : df[0]);
|
|
||||||
|
|
||||||
type = dict.get('Subtype');
|
type = dict.get('Subtype');
|
||||||
assertWellFormed(isName(type), 'invalid font Subtype');
|
assertWellFormed(isName(type), 'invalid font Subtype');
|
||||||
@ -753,7 +747,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
}
|
}
|
||||||
var maxCharIndex = composite ? 0xFFFF : 0xFF;
|
var maxCharIndex = composite ? 0xFFFF : 0xFF;
|
||||||
|
|
||||||
var descriptor = xref.fetchIfRef(dict.get('FontDescriptor'));
|
var descriptor = dict.get('FontDescriptor');
|
||||||
if (!descriptor) {
|
if (!descriptor) {
|
||||||
if (type.name == 'Type3') {
|
if (type.name == 'Type3') {
|
||||||
// FontDescriptor is only required for Type3 fonts when the document
|
// FontDescriptor is only required for Type3 fonts when the document
|
||||||
@ -802,9 +796,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
// to ignore this rule when a variant of a standart font is used.
|
// 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
|
// TODO Fill the width array depending on which of the base font this is
|
||||||
// a variant.
|
// a variant.
|
||||||
var firstChar = xref.fetchIfRef(dict.get('FirstChar')) || 0;
|
var firstChar = dict.get('FirstChar') || 0;
|
||||||
var lastChar = xref.fetchIfRef(dict.get('LastChar')) || maxCharIndex;
|
var lastChar = dict.get('LastChar') || maxCharIndex;
|
||||||
var fontName = xref.fetchIfRef(descriptor.get('FontName'));
|
var fontName = descriptor.get('FontName');
|
||||||
// Some bad pdf's have a string as the font name.
|
// Some bad pdf's have a string as the font name.
|
||||||
if (isString(fontName))
|
if (isString(fontName))
|
||||||
fontName = new Name(fontName);
|
fontName = new Name(fontName);
|
||||||
@ -812,19 +806,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
|
|
||||||
var fontFile = descriptor.get('FontFile', 'FontFile2', 'FontFile3');
|
var fontFile = descriptor.get('FontFile', 'FontFile2', 'FontFile3');
|
||||||
if (fontFile) {
|
if (fontFile) {
|
||||||
fontFile = xref.fetchIfRef(fontFile);
|
|
||||||
if (fontFile.dict) {
|
if (fontFile.dict) {
|
||||||
var subtype = fontFile.dict.get('Subtype');
|
var subtype = fontFile.dict.get('Subtype');
|
||||||
if (subtype)
|
if (subtype)
|
||||||
subtype = subtype.name;
|
subtype = subtype.name;
|
||||||
|
|
||||||
var length1 = fontFile.dict.get('Length1');
|
var length1 = fontFile.dict.get('Length1');
|
||||||
if (!isInt(length1))
|
|
||||||
length1 = xref.fetchIfRef(length1);
|
|
||||||
|
|
||||||
var length2 = fontFile.dict.get('Length2');
|
var length2 = fontFile.dict.get('Length2');
|
||||||
if (!isInt(length2))
|
|
||||||
length2 = xref.fetchIfRef(length2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -853,12 +842,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
|
|
||||||
if (type.name === 'Type3') {
|
if (type.name === 'Type3') {
|
||||||
properties.coded = true;
|
properties.coded = true;
|
||||||
var charProcs = xref.fetchIfRef(dict.get('CharProcs'));
|
var charProcs = dict.get('CharProcs').getAll();
|
||||||
var fontResources = xref.fetchIfRef(dict.get('Resources')) || resources;
|
var fontResources = dict.get('Resources') || resources;
|
||||||
properties.resources = fontResources;
|
properties.resources = fontResources;
|
||||||
properties.charProcOperatorList = {};
|
properties.charProcOperatorList = {};
|
||||||
for (var key in charProcs.map) {
|
for (var key in charProcs) {
|
||||||
var glyphStream = xref.fetchIfRef(charProcs.map[key]);
|
var glyphStream = charProcs[key];
|
||||||
properties.charProcOperatorList[key] =
|
properties.charProcOperatorList[key] =
|
||||||
this.getOperatorList(glyphStream, fontResources, dependency);
|
this.getOperatorList(glyphStream, fontResources, dependency);
|
||||||
}
|
}
|
||||||
|
@ -268,13 +268,13 @@ var PDFFunction = (function PDFFunctionClosure() {
|
|||||||
if (inputSize != 1)
|
if (inputSize != 1)
|
||||||
error('Bad domain for stiched function');
|
error('Bad domain for stiched function');
|
||||||
|
|
||||||
var fnRefs = xref.fetchIfRef(dict.get('Functions'));
|
var fnRefs = dict.get('Functions');
|
||||||
var fns = [];
|
var fns = [];
|
||||||
for (var i = 0, ii = fnRefs.length; i < ii; ++i)
|
for (var i = 0, ii = fnRefs.length; i < ii; ++i)
|
||||||
fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i])));
|
fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i])));
|
||||||
|
|
||||||
var bounds = xref.fetchIfRef(dict.get('Bounds'));
|
var bounds = dict.get('Bounds');
|
||||||
var encode = xref.fetchIfRef(dict.get('Encode'));
|
var encode = dict.get('Encode');
|
||||||
|
|
||||||
return [CONSTRUCT_STICHED, domain, bounds, encode, fns];
|
return [CONSTRUCT_STICHED, domain, bounds, encode, fns];
|
||||||
},
|
},
|
||||||
|
@ -94,7 +94,7 @@ var PDFImage = (function PDFImageClosure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var mask = xref.fetchIfRef(dict.get('Mask'));
|
var mask = dict.get('Mask');
|
||||||
|
|
||||||
if (mask) {
|
if (mask) {
|
||||||
TODO('masked images');
|
TODO('masked images');
|
||||||
@ -120,7 +120,7 @@ var PDFImage = (function PDFImageClosure() {
|
|||||||
|
|
||||||
handleImageData(handler, xref, res, image, imageDataPromise);
|
handleImageData(handler, xref, res, image, imageDataPromise);
|
||||||
|
|
||||||
var smask = xref.fetchIfRef(image.dict.get('SMask'));
|
var smask = image.dict.get('SMask');
|
||||||
if (smask)
|
if (smask)
|
||||||
handleImageData(handler, xref, res, smask, smaskPromise);
|
handleImageData(handler, xref, res, smask, smaskPromise);
|
||||||
else
|
else
|
||||||
|
88
src/obj.js
88
src/obj.js
@ -34,23 +34,39 @@ var Cmd = (function CmdClosure() {
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
var Dict = (function DictClosure() {
|
var Dict = (function DictClosure() {
|
||||||
function Dict() {
|
// xref is optional
|
||||||
|
function Dict(xref) {
|
||||||
|
// Map should only be used internally, use functions below to access.
|
||||||
this.map = Object.create(null);
|
this.map = Object.create(null);
|
||||||
|
this.xref = xref;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dict.prototype = {
|
Dict.prototype = {
|
||||||
|
// automatically dereferences Ref objects
|
||||||
get: function dictGet(key1, key2, key3) {
|
get: function dictGet(key1, key2, key3) {
|
||||||
var value;
|
var value;
|
||||||
|
var xref = this.xref;
|
||||||
if (typeof (value = this.map[key1]) != 'undefined' || key1 in this.map ||
|
if (typeof (value = this.map[key1]) != 'undefined' || key1 in this.map ||
|
||||||
typeof key2 == 'undefined') {
|
typeof key2 == 'undefined') {
|
||||||
return value;
|
return xref ? this.xref.fetchIfRef(value) : value;
|
||||||
}
|
}
|
||||||
if (typeof (value = this.map[key2]) != 'undefined' || key2 in this.map ||
|
if (typeof (value = this.map[key2]) != 'undefined' || key2 in this.map ||
|
||||||
typeof key3 == 'undefined') {
|
typeof key3 == 'undefined') {
|
||||||
return value;
|
return xref ? this.xref.fetchIfRef(value) : value;
|
||||||
}
|
}
|
||||||
|
value = this.map[key3] || null;
|
||||||
return this.map[key3] || null;
|
return xref ? this.xref.fetchIfRef(value) : value;
|
||||||
|
},
|
||||||
|
// no dereferencing
|
||||||
|
getRaw: function dictGetRaw(key) {
|
||||||
|
return this.map[key];
|
||||||
|
},
|
||||||
|
// creates new map and dereferences all Refs
|
||||||
|
getAll: function dictGetAll() {
|
||||||
|
var all = {};
|
||||||
|
for (var key in this.map)
|
||||||
|
all[key] = this.get(key);
|
||||||
|
return all;
|
||||||
},
|
},
|
||||||
|
|
||||||
set: function dictSet(key, value) {
|
set: function dictSet(key, value) {
|
||||||
@ -63,7 +79,7 @@ var Dict = (function DictClosure() {
|
|||||||
|
|
||||||
forEach: function dictForEach(callback) {
|
forEach: function dictForEach(callback) {
|
||||||
for (var key in this.map) {
|
for (var key in this.map) {
|
||||||
callback(key, this.map[key]);
|
callback(key, this.get(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -112,8 +128,7 @@ var Catalog = (function CatalogClosure() {
|
|||||||
|
|
||||||
Catalog.prototype = {
|
Catalog.prototype = {
|
||||||
get metadata() {
|
get metadata() {
|
||||||
var ref = this.catDict.get('Metadata');
|
var stream = this.catDict.get('Metadata');
|
||||||
var stream = this.xref.fetchIfRef(ref);
|
|
||||||
var metadata;
|
var metadata;
|
||||||
if (stream && isDict(stream.dict)) {
|
if (stream && isDict(stream.dict)) {
|
||||||
var type = stream.dict.get('Type');
|
var type = stream.dict.get('Type');
|
||||||
@ -129,40 +144,39 @@ var Catalog = (function CatalogClosure() {
|
|||||||
},
|
},
|
||||||
get toplevelPagesDict() {
|
get toplevelPagesDict() {
|
||||||
var pagesObj = this.catDict.get('Pages');
|
var pagesObj = this.catDict.get('Pages');
|
||||||
assertWellFormed(isRef(pagesObj), 'invalid top-level pages reference');
|
assertWellFormed(isDict(pagesObj), 'invalid top-level pages dictionary');
|
||||||
var xrefObj = this.xref.fetch(pagesObj);
|
|
||||||
assertWellFormed(isDict(xrefObj), 'invalid top-level pages dictionary');
|
|
||||||
// shadow the prototype getter
|
// shadow the prototype getter
|
||||||
return shadow(this, 'toplevelPagesDict', xrefObj);
|
return shadow(this, 'toplevelPagesDict', pagesObj);
|
||||||
},
|
},
|
||||||
get documentOutline() {
|
get documentOutline() {
|
||||||
var xref = this.xref;
|
var xref = this.xref;
|
||||||
var obj = xref.fetchIfRef(this.catDict.get('Outlines'));
|
var obj = this.catDict.get('Outlines');
|
||||||
var root = { items: [] };
|
var root = { items: [] };
|
||||||
if (isDict(obj)) {
|
if (isDict(obj)) {
|
||||||
|
var ref = obj.getRaw('First');
|
||||||
obj = obj.get('First');
|
obj = obj.get('First');
|
||||||
var processed = new RefSet();
|
var processed = new RefSet();
|
||||||
if (isRef(obj)) {
|
if (isRef(ref)) {
|
||||||
var queue = [{obj: obj, parent: root}];
|
var queue = [{obj: obj, parent: root}];
|
||||||
// to avoid recursion keeping track of the items
|
// to avoid recursion keeping track of the items
|
||||||
// in the processed dictionary
|
// in the processed dictionary
|
||||||
processed.put(obj);
|
processed.put(ref);
|
||||||
while (queue.length > 0) {
|
while (queue.length > 0) {
|
||||||
var i = queue.shift();
|
var i = queue.shift();
|
||||||
var outlineDict = xref.fetch(i.obj);
|
var outlineDict = i.obj;
|
||||||
if (outlineDict === null)
|
if (outlineDict === null)
|
||||||
continue;
|
continue;
|
||||||
if (!outlineDict.has('Title'))
|
if (!outlineDict.has('Title'))
|
||||||
error('Invalid outline item');
|
error('Invalid outline item');
|
||||||
var dest = outlineDict.get('A');
|
var dest = outlineDict.get('A');
|
||||||
if (dest)
|
if (dest)
|
||||||
dest = xref.fetchIfRef(dest).get('D');
|
dest = dest.get('D');
|
||||||
else if (outlineDict.has('Dest')) {
|
else if (outlineDict.has('Dest')) {
|
||||||
dest = outlineDict.get('Dest');
|
dest = outlineDict.getRaw('Dest');
|
||||||
if (isName(dest))
|
if (isName(dest))
|
||||||
dest = dest.name;
|
dest = dest.name;
|
||||||
}
|
}
|
||||||
var title = xref.fetchIfRef(outlineDict.get('Title'));
|
var title = outlineDict.get('Title');
|
||||||
var outlineItem = {
|
var outlineItem = {
|
||||||
dest: dest,
|
dest: dest,
|
||||||
title: stringToPDFString(title),
|
title: stringToPDFString(title),
|
||||||
@ -173,15 +187,17 @@ var Catalog = (function CatalogClosure() {
|
|||||||
items: []
|
items: []
|
||||||
};
|
};
|
||||||
i.parent.items.push(outlineItem);
|
i.parent.items.push(outlineItem);
|
||||||
obj = outlineDict.get('First');
|
ref = outlineDict.getRaw('First');
|
||||||
if (isRef(obj) && !processed.has(obj)) {
|
if (isRef(ref) && !processed.has(ref)) {
|
||||||
|
obj = outlineDict.get('First');
|
||||||
queue.push({obj: obj, parent: outlineItem});
|
queue.push({obj: obj, parent: outlineItem});
|
||||||
processed.put(obj);
|
processed.put(ref);
|
||||||
}
|
}
|
||||||
obj = outlineDict.get('Next');
|
ref = outlineDict.getRaw('Next');
|
||||||
if (isRef(obj) && !processed.has(obj)) {
|
if (isRef(ref) && !processed.has(ref)) {
|
||||||
|
obj = outlineDict.get('Next');
|
||||||
queue.push({obj: obj, parent: i.parent});
|
queue.push({obj: obj, parent: i.parent});
|
||||||
processed.put(obj);
|
processed.put(ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,7 +222,7 @@ var Catalog = (function CatalogClosure() {
|
|||||||
for (var i = 0, ii = kids.length; i < ii; ++i) {
|
for (var i = 0, ii = kids.length; i < ii; ++i) {
|
||||||
var kid = kids[i];
|
var kid = kids[i];
|
||||||
assertWellFormed(isRef(kid),
|
assertWellFormed(isRef(kid),
|
||||||
'page dictionary kid is not a reference');
|
'page dictionary kid is not a reference');
|
||||||
var obj = this.xref.fetch(kid);
|
var obj = this.xref.fetch(kid);
|
||||||
if (isDict(obj, 'Page') || (isDict(obj) && !obj.has('Kids'))) {
|
if (isDict(obj, 'Page') || (isDict(obj) && !obj.has('Kids'))) {
|
||||||
pageCache.push(new Page(this.xref, pageCache.length, obj, kid));
|
pageCache.push(new Page(this.xref, pageCache.length, obj, kid));
|
||||||
@ -221,7 +237,7 @@ var Catalog = (function CatalogClosure() {
|
|||||||
},
|
},
|
||||||
get destinations() {
|
get destinations() {
|
||||||
function fetchDestination(xref, ref) {
|
function fetchDestination(xref, ref) {
|
||||||
var dest = xref.fetchIfRef(ref);
|
var dest = ref;
|
||||||
return isDict(dest) ? dest.get('D') : dest;
|
return isDict(dest) ? dest.get('D') : dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,13 +245,13 @@ var Catalog = (function CatalogClosure() {
|
|||||||
var dests = {}, nameTreeRef, nameDictionaryRef;
|
var dests = {}, nameTreeRef, nameDictionaryRef;
|
||||||
var obj = this.catDict.get('Names');
|
var obj = this.catDict.get('Names');
|
||||||
if (obj)
|
if (obj)
|
||||||
nameTreeRef = xref.fetchIfRef(obj).get('Dests');
|
nameTreeRef = obj.getRaw('Dests');
|
||||||
else if (this.catDict.has('Dests'))
|
else if (this.catDict.has('Dests'))
|
||||||
nameDictionaryRef = this.catDict.get('Dests');
|
nameDictionaryRef = this.catDict.get('Dests');
|
||||||
|
|
||||||
if (nameDictionaryRef) {
|
if (nameDictionaryRef) {
|
||||||
// reading simple destination dictionary
|
// reading simple destination dictionary
|
||||||
obj = xref.fetchIfRef(nameDictionaryRef);
|
obj = nameDictionaryRef;
|
||||||
obj.forEach(function catalogForEach(key, value) {
|
obj.forEach(function catalogForEach(key, value) {
|
||||||
if (!value) return;
|
if (!value) return;
|
||||||
dests[key] = fetchDestination(xref, value);
|
dests[key] = fetchDestination(xref, value);
|
||||||
@ -287,6 +303,7 @@ var XRef = (function XRefClosure() {
|
|||||||
this.entries = [];
|
this.entries = [];
|
||||||
this.xrefstms = {};
|
this.xrefstms = {};
|
||||||
var trailerDict = this.readXRef(startXRef);
|
var trailerDict = this.readXRef(startXRef);
|
||||||
|
trailerDict.xref = this;
|
||||||
this.trailer = trailerDict;
|
this.trailer = trailerDict;
|
||||||
// prepare the XRef cache
|
// prepare the XRef cache
|
||||||
this.cache = [];
|
this.cache = [];
|
||||||
@ -294,12 +311,12 @@ var XRef = (function XRefClosure() {
|
|||||||
var encrypt = trailerDict.get('Encrypt');
|
var encrypt = trailerDict.get('Encrypt');
|
||||||
if (encrypt) {
|
if (encrypt) {
|
||||||
var fileId = trailerDict.get('ID');
|
var fileId = trailerDict.get('ID');
|
||||||
this.encrypt = new CipherTransformFactory(this.fetch(encrypt),
|
this.encrypt = new CipherTransformFactory(encrypt,
|
||||||
fileId[0] /*, password */);
|
fileId[0] /*, password */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the root dictionary (catalog) object
|
// get the root dictionary (catalog) object
|
||||||
if (!isRef(this.root = trailerDict.get('Root')))
|
if (!(this.root = trailerDict.get('Root')))
|
||||||
error('Invalid root reference');
|
error('Invalid root reference');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,7 +531,7 @@ var XRef = (function XRefClosure() {
|
|||||||
var dict;
|
var dict;
|
||||||
for (var i = 0, ii = trailers.length; i < ii; ++i) {
|
for (var i = 0, ii = trailers.length; i < ii; ++i) {
|
||||||
stream.pos = trailers[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();
|
var obj = parser.getObj();
|
||||||
if (!isCmd(obj, 'trailer'))
|
if (!isCmd(obj, 'trailer'))
|
||||||
continue;
|
continue;
|
||||||
@ -536,7 +553,7 @@ var XRef = (function XRefClosure() {
|
|||||||
stream.pos = startXRef;
|
stream.pos = startXRef;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var parser = new Parser(new Lexer(stream), true);
|
var parser = new Parser(new Lexer(stream), true, null);
|
||||||
var obj = parser.getObj();
|
var obj = parser.getObj();
|
||||||
var dict;
|
var dict;
|
||||||
|
|
||||||
@ -596,6 +613,7 @@ var XRef = (function XRefClosure() {
|
|||||||
return this.fetch(obj);
|
return this.fetch(obj);
|
||||||
},
|
},
|
||||||
fetch: function xRefFetch(ref, suppressEncryption) {
|
fetch: function xRefFetch(ref, suppressEncryption) {
|
||||||
|
assertWellFormed(isRef(ref), 'ref object is not a reference');
|
||||||
var num = ref.num;
|
var num = ref.num;
|
||||||
if (num in this.cache)
|
if (num in this.cache)
|
||||||
return this.cache[num];
|
return this.cache[num];
|
||||||
@ -657,7 +675,7 @@ var XRef = (function XRefClosure() {
|
|||||||
if (!isInt(first) || !isInt(n)) {
|
if (!isInt(first) || !isInt(n)) {
|
||||||
error('invalid first and n parameters for ObjStm stream');
|
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 = [];
|
var i, entries = [], nums = [];
|
||||||
// read the object numbers to populate cache
|
// read the object numbers to populate cache
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
@ -683,7 +701,7 @@ var XRef = (function XRefClosure() {
|
|||||||
return e;
|
return e;
|
||||||
},
|
},
|
||||||
getCatalogObj: function xRefGetCatalogObj() {
|
getCatalogObj: function xRefGetCatalogObj() {
|
||||||
return this.fetch(this.root);
|
return this.root;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ var Parser = (function ParserClosure() {
|
|||||||
}
|
}
|
||||||
if (isCmd(this.buf1, '<<')) { // dictionary or stream
|
if (isCmd(this.buf1, '<<')) { // dictionary or stream
|
||||||
this.shift();
|
this.shift();
|
||||||
var dict = new Dict();
|
var dict = new Dict(this.xref);
|
||||||
while (!isCmd(this.buf1, '>>') && !isEOF(this.buf1)) {
|
while (!isCmd(this.buf1, '>>') && !isEOF(this.buf1)) {
|
||||||
if (!isName(this.buf1))
|
if (!isName(this.buf1))
|
||||||
error('Dictionary key must be a name object');
|
error('Dictionary key must be a name object');
|
||||||
@ -564,7 +564,7 @@ var Lexer = (function LexerClosure() {
|
|||||||
|
|
||||||
var Linearization = (function LinearizationClosure() {
|
var Linearization = (function LinearizationClosure() {
|
||||||
function Linearization(stream) {
|
function Linearization(stream) {
|
||||||
this.parser = new Parser(new Lexer(stream), false);
|
this.parser = new Parser(new Lexer(stream), false, null);
|
||||||
var obj1 = this.parser.getObj();
|
var obj1 = this.parser.getObj();
|
||||||
var obj2 = this.parser.getObj();
|
var obj2 = this.parser.getObj();
|
||||||
var obj3 = this.parser.getObj();
|
var obj3 = this.parser.getObj();
|
||||||
|
@ -79,7 +79,6 @@ Shadings.RadialAxial = (function RadialAxialClosure() {
|
|||||||
this.extendEnd = extendEnd;
|
this.extendEnd = extendEnd;
|
||||||
|
|
||||||
var fnObj = dict.get('Function');
|
var fnObj = dict.get('Function');
|
||||||
fnObj = xref.fetchIfRef(fnObj);
|
|
||||||
if (isArray(fnObj))
|
if (isArray(fnObj))
|
||||||
error('No support for array of functions');
|
error('No support for array of functions');
|
||||||
if (!isPDFFunction(fnObj))
|
if (!isPDFFunction(fnObj))
|
||||||
|
Loading…
Reference in New Issue
Block a user