Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes pages without Resources in their dictionary #4464

Merged
merged 3 commits into from
Mar 18, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
62 changes: 43 additions & 19 deletions src/core/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* globals assertWellFormed, calculateMD5, Catalog, error, info, isArray,
/* globals assertWellFormed, calculateMD5, Catalog, Dict, error, info, isArray,
isArrayBuffer, isName, isStream, isString, LegacyPromise,
Linearization, NullStream, PartialEvaluator, shadow, Stream, Lexer,
StreamsSequenceStream, stringToPDFString, stringToBytes, Util, XRef,
Expand All @@ -25,6 +25,8 @@

var Page = (function PageClosure() {

var LETTER_SIZE_MEDIABOX = [0, 0, 612, 792];

function Page(pdfManager, xref, pageIndex, pageDict, ref, fontCache) {
this.pdfManager = pdfManager;
this.pageIndex = pageIndex;
Expand All @@ -42,51 +44,69 @@ var Page = (function PageClosure() {
getPageProp: function Page_getPageProp(key) {
return this.pageDict.get(key);
},
inheritPageProp: function Page_inheritPageProp(key) {

getInheritedPageProp: function Page_inheritPageProp(key) {
var dict = this.pageDict;
var obj = dict.get(key);
while (obj === undefined) {
var value = dict.get(key);
while (value === undefined) {
dict = dict.get('Parent');
if (!dict)
if (!dict) {
break;
obj = dict.get(key);
}
value = dict.get(key);
}
return obj;
return value;
},

get content() {
return this.getPageProp('Contents');
},

get resources() {
return shadow(this, 'resources', this.inheritPageProp('Resources'));
var value = this.getInheritedPageProp('Resources');
// For robustness: The spec states that a \Resources entry has to be
// present, but can be empty. Some document omit it still. In this case
// return an empty dictionary:
if (value === undefined) {
value = new Dict();
}
return shadow(this, 'resources', value);
},

get mediaBox() {
var obj = this.inheritPageProp('MediaBox');
var obj = this.getInheritedPageProp('MediaBox');
// Reset invalid media box to letter size.
if (!isArray(obj) || obj.length !== 4)
obj = [0, 0, 612, 792];
if (!isArray(obj) || obj.length !== 4) {
obj = LETTER_SIZE_MEDIABOX;
}
return shadow(this, 'mediaBox', obj);
},

get view() {
var mediaBox = this.mediaBox;
var cropBox = this.inheritPageProp('CropBox');
if (!isArray(cropBox) || cropBox.length !== 4)
var cropBox = this.getInheritedPageProp('CropBox');
if (!isArray(cropBox) || cropBox.length !== 4) {
return shadow(this, 'view', mediaBox);
}

// 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)
if (!cropBox) {
return shadow(this, 'view', mediaBox);

}
return shadow(this, 'view', cropBox);
},

get annotationRefs() {
return shadow(this, 'annotationRefs', this.inheritPageProp('Annots'));
return shadow(this, 'annotationRefs',
this.getInheritedPageProp('Annots'));
},

get rotate() {
var rotate = this.inheritPageProp('Rotate') || 0;
var rotate = this.getInheritedPageProp('Rotate') || 0;
// Normalize rotation so it's a multiple of 90 and between 0 and 270
if (rotate % 90 !== 0) {
rotate = 0;
Expand All @@ -99,6 +119,7 @@ var Page = (function PageClosure() {
}
return shadow(this, 'rotate', rotate);
},

getContentStream: function Page_getContentStream() {
var content = this.content;
var stream;
Expand All @@ -118,9 +139,10 @@ var Page = (function PageClosure() {
}
return stream;
},

loadResources: function(keys) {
if (!this.resourcesPromise) {
// TODO: add async inheritPageProp and remove this.
// TODO: add async getInheritedPageProp and remove this.
this.resourcesPromise = this.pdfManager.ensure(this, 'resources');
}
var promise = new LegacyPromise();
Expand All @@ -134,6 +156,7 @@ var Page = (function PageClosure() {
}.bind(this));
return promise;
},

getOperatorList: function Page_getOperatorList(handler, intent) {
var self = this;
var promise = new LegacyPromise();
Expand All @@ -153,7 +176,7 @@ var Page = (function PageClosure() {
'Pattern',
'Shading',
'XObject',
'Font',
'Font'
// ProcSet
// Properties
]);
Expand Down Expand Up @@ -201,6 +224,7 @@ var Page = (function PageClosure() {

return promise;
},

extractTextContent: function Page_extractTextContent() {
var handler = {
on: function nullHandlerOn() {},
Expand Down
1 change: 1 addition & 0 deletions test/pdfs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@
!issue3885.pdf
!bug859204.pdf
!issue4246.pdf
!issue4461.pdf
Binary file added test/pdfs/issue4461.pdf
Binary file not shown.
7 changes: 7 additions & 0 deletions test/test_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,13 @@
"link": true,
"type": "eq"
},
{ "id": "issue4461-load",
"file": "pdfs/issue4461.pdf",
"md5": "9df4ecaae429adb5dc93d9342a53159d",
"rounds": 1,
"type": "load",
"about": "Document without /Resources entry in page dictionary"
},
{ "id": "issue1249-load",
"file": "pdfs/issue1249.pdf",
"md5": "4f81339fa09422a7db980f34ea963609",
Expand Down