Merge pull request #4464 from bthorben/issue#4461
Fixes pages without Resources in their dictionary
This commit is contained in:
commit
329d0ec30b
@ -14,7 +14,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
/* globals assertWellFormed, calculateMD5, Catalog, error, info, isArray,
|
/* globals assertWellFormed, calculateMD5, Catalog, Dict, error, info, isArray,
|
||||||
isArrayBuffer, isName, isStream, isString, LegacyPromise,
|
isArrayBuffer, isName, isStream, isString, LegacyPromise,
|
||||||
Linearization, NullStream, PartialEvaluator, shadow, Stream, Lexer,
|
Linearization, NullStream, PartialEvaluator, shadow, Stream, Lexer,
|
||||||
StreamsSequenceStream, stringToPDFString, stringToBytes, Util, XRef,
|
StreamsSequenceStream, stringToPDFString, stringToBytes, Util, XRef,
|
||||||
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
var Page = (function PageClosure() {
|
var Page = (function PageClosure() {
|
||||||
|
|
||||||
|
var LETTER_SIZE_MEDIABOX = [0, 0, 612, 792];
|
||||||
|
|
||||||
function Page(pdfManager, xref, pageIndex, pageDict, ref, fontCache) {
|
function Page(pdfManager, xref, pageIndex, pageDict, ref, fontCache) {
|
||||||
this.pdfManager = pdfManager;
|
this.pdfManager = pdfManager;
|
||||||
this.pageIndex = pageIndex;
|
this.pageIndex = pageIndex;
|
||||||
@ -42,51 +44,69 @@ var Page = (function PageClosure() {
|
|||||||
getPageProp: function Page_getPageProp(key) {
|
getPageProp: function Page_getPageProp(key) {
|
||||||
return this.pageDict.get(key);
|
return this.pageDict.get(key);
|
||||||
},
|
},
|
||||||
inheritPageProp: function Page_inheritPageProp(key) {
|
|
||||||
|
getInheritedPageProp: function Page_inheritPageProp(key) {
|
||||||
var dict = this.pageDict;
|
var dict = this.pageDict;
|
||||||
var obj = dict.get(key);
|
var value = dict.get(key);
|
||||||
while (obj === undefined) {
|
while (value === undefined) {
|
||||||
dict = dict.get('Parent');
|
dict = dict.get('Parent');
|
||||||
if (!dict)
|
if (!dict) {
|
||||||
break;
|
break;
|
||||||
obj = dict.get(key);
|
}
|
||||||
|
value = dict.get(key);
|
||||||
}
|
}
|
||||||
return obj;
|
return value;
|
||||||
},
|
},
|
||||||
|
|
||||||
get content() {
|
get content() {
|
||||||
return this.getPageProp('Contents');
|
return this.getPageProp('Contents');
|
||||||
},
|
},
|
||||||
|
|
||||||
get resources() {
|
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() {
|
get mediaBox() {
|
||||||
var obj = this.inheritPageProp('MediaBox');
|
var obj = this.getInheritedPageProp('MediaBox');
|
||||||
// Reset invalid media box to letter size.
|
// Reset invalid media box to letter size.
|
||||||
if (!isArray(obj) || obj.length !== 4)
|
if (!isArray(obj) || obj.length !== 4) {
|
||||||
obj = [0, 0, 612, 792];
|
obj = LETTER_SIZE_MEDIABOX;
|
||||||
|
}
|
||||||
return shadow(this, 'mediaBox', obj);
|
return shadow(this, 'mediaBox', obj);
|
||||||
},
|
},
|
||||||
|
|
||||||
get view() {
|
get view() {
|
||||||
var mediaBox = this.mediaBox;
|
var mediaBox = this.mediaBox;
|
||||||
var cropBox = this.inheritPageProp('CropBox');
|
var cropBox = this.getInheritedPageProp('CropBox');
|
||||||
if (!isArray(cropBox) || cropBox.length !== 4)
|
if (!isArray(cropBox) || cropBox.length !== 4) {
|
||||||
return shadow(this, 'view', mediaBox);
|
return shadow(this, 'view', mediaBox);
|
||||||
|
}
|
||||||
|
|
||||||
// From the spec, 6th ed., p.963:
|
// From the spec, 6th ed., p.963:
|
||||||
// "The crop, bleed, trim, and art boxes should not ordinarily
|
// "The crop, bleed, trim, and art boxes should not ordinarily
|
||||||
// extend beyond the boundaries of the media box. If they do, they are
|
// extend beyond the boundaries of the media box. If they do, they are
|
||||||
// effectively reduced to their intersection with the media box."
|
// effectively reduced to their intersection with the media box."
|
||||||
cropBox = Util.intersect(cropBox, mediaBox);
|
cropBox = Util.intersect(cropBox, mediaBox);
|
||||||
if (!cropBox)
|
if (!cropBox) {
|
||||||
return shadow(this, 'view', mediaBox);
|
return shadow(this, 'view', mediaBox);
|
||||||
|
}
|
||||||
return shadow(this, 'view', cropBox);
|
return shadow(this, 'view', cropBox);
|
||||||
},
|
},
|
||||||
|
|
||||||
get annotationRefs() {
|
get annotationRefs() {
|
||||||
return shadow(this, 'annotationRefs', this.inheritPageProp('Annots'));
|
return shadow(this, 'annotationRefs',
|
||||||
|
this.getInheritedPageProp('Annots'));
|
||||||
},
|
},
|
||||||
|
|
||||||
get rotate() {
|
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
|
// Normalize rotation so it's a multiple of 90 and between 0 and 270
|
||||||
if (rotate % 90 !== 0) {
|
if (rotate % 90 !== 0) {
|
||||||
rotate = 0;
|
rotate = 0;
|
||||||
@ -99,6 +119,7 @@ var Page = (function PageClosure() {
|
|||||||
}
|
}
|
||||||
return shadow(this, 'rotate', rotate);
|
return shadow(this, 'rotate', rotate);
|
||||||
},
|
},
|
||||||
|
|
||||||
getContentStream: function Page_getContentStream() {
|
getContentStream: function Page_getContentStream() {
|
||||||
var content = this.content;
|
var content = this.content;
|
||||||
var stream;
|
var stream;
|
||||||
@ -118,9 +139,10 @@ var Page = (function PageClosure() {
|
|||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
},
|
},
|
||||||
|
|
||||||
loadResources: function(keys) {
|
loadResources: function(keys) {
|
||||||
if (!this.resourcesPromise) {
|
if (!this.resourcesPromise) {
|
||||||
// TODO: add async inheritPageProp and remove this.
|
// TODO: add async getInheritedPageProp and remove this.
|
||||||
this.resourcesPromise = this.pdfManager.ensure(this, 'resources');
|
this.resourcesPromise = this.pdfManager.ensure(this, 'resources');
|
||||||
}
|
}
|
||||||
var promise = new LegacyPromise();
|
var promise = new LegacyPromise();
|
||||||
@ -134,6 +156,7 @@ var Page = (function PageClosure() {
|
|||||||
}.bind(this));
|
}.bind(this));
|
||||||
return promise;
|
return promise;
|
||||||
},
|
},
|
||||||
|
|
||||||
getOperatorList: function Page_getOperatorList(handler, intent) {
|
getOperatorList: function Page_getOperatorList(handler, intent) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var promise = new LegacyPromise();
|
var promise = new LegacyPromise();
|
||||||
@ -153,7 +176,7 @@ var Page = (function PageClosure() {
|
|||||||
'Pattern',
|
'Pattern',
|
||||||
'Shading',
|
'Shading',
|
||||||
'XObject',
|
'XObject',
|
||||||
'Font',
|
'Font'
|
||||||
// ProcSet
|
// ProcSet
|
||||||
// Properties
|
// Properties
|
||||||
]);
|
]);
|
||||||
@ -201,6 +224,7 @@ var Page = (function PageClosure() {
|
|||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
},
|
},
|
||||||
|
|
||||||
extractTextContent: function Page_extractTextContent() {
|
extractTextContent: function Page_extractTextContent() {
|
||||||
var handler = {
|
var handler = {
|
||||||
on: function nullHandlerOn() {},
|
on: function nullHandlerOn() {},
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -67,3 +67,4 @@
|
|||||||
!issue3885.pdf
|
!issue3885.pdf
|
||||||
!bug859204.pdf
|
!bug859204.pdf
|
||||||
!issue4246.pdf
|
!issue4246.pdf
|
||||||
|
!issue4461.pdf
|
||||||
|
35
test/pdfs/issue4461.pdf
Normal file
35
test/pdfs/issue4461.pdf
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
%PDF-1.4
|
||||||
|
%μῦ
|
||||||
|
|
||||||
|
1 0 obj
|
||||||
|
<</Parent 2 0 R/MediaBox[0 0 30 20]/Type/Page/Contents 3 0 R>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
2 0 obj
|
||||||
|
<</Kids[1 0 R]/Type/Pages/Count 1>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
3 0 obj
|
||||||
|
<</Length 0>>
|
||||||
|
stream
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
|
||||||
|
4 0 obj
|
||||||
|
<</Pages 2 0 R/Type/Catalog>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
xref
|
||||||
|
0 5
|
||||||
|
0000000000 65536 f
|
||||||
|
0000000017 00000 n
|
||||||
|
0000000096 00000 n
|
||||||
|
0000000148 00000 n
|
||||||
|
0000000195 00000 n
|
||||||
|
|
||||||
|
trailer
|
||||||
|
<</Size 5/Root 4 0 R/ID[<1861E1AD51AD0FE751FE9A71F1C854F5><1861E1AD51AD0FE751FE9A71F1C854F5>]>>
|
||||||
|
|
||||||
|
startxref
|
||||||
|
241
|
||||||
|
%%EOF
|
@ -709,6 +709,13 @@
|
|||||||
"link": true,
|
"link": true,
|
||||||
"type": "eq"
|
"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",
|
{ "id": "issue1249-load",
|
||||||
"file": "pdfs/issue1249.pdf",
|
"file": "pdfs/issue1249.pdf",
|
||||||
"md5": "4f81339fa09422a7db980f34ea963609",
|
"md5": "4f81339fa09422a7db980f34ea963609",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user