@@ -45,6 +45,8 @@ import {
4545 lookupNormalRect ,
4646 MissingDataException ,
4747 PDF_VERSION_REGEXP ,
48+ RESOURCES_KEYS_OPERATOR_LIST ,
49+ RESOURCES_KEYS_TEXT_CONTENT ,
4850 validateCSSFont ,
4951 XRefEntryException ,
5052 XRefParseException ,
@@ -419,6 +421,25 @@ class Page {
419421 await objectLoader . load ( ) ;
420422 }
421423
424+ async #getMergedResources( streamDict , keys ) {
425+ // In rare cases /Resources are also found in the /Contents stream-dict,
426+ // in addition to in the /Page dict, hence we need to prefer those when
427+ // available (see issue18894.pdf).
428+ const localResources = streamDict ?. get ( "Resources" ) ;
429+
430+ if ( ! ( localResources instanceof Dict ) ) {
431+ return this . resources ;
432+ }
433+ const objectLoader = new ObjectLoader ( localResources , keys , this . xref ) ;
434+ await objectLoader . load ( ) ;
435+
436+ return Dict . merge ( {
437+ xref : this . xref ,
438+ dictArray : [ localResources , this . resources ] ,
439+ mergeSubDicts : true ,
440+ } ) ;
441+ }
442+
422443 async getOperatorList ( {
423444 handler,
424445 sink,
@@ -429,15 +450,7 @@ class Page {
429450 modifiedIds = null ,
430451 } ) {
431452 const contentStreamPromise = this . getContentStream ( ) ;
432- const resourcesPromise = this . loadResources ( [
433- "ColorSpace" ,
434- "ExtGState" ,
435- "Font" ,
436- "Pattern" ,
437- "Properties" ,
438- "Shading" ,
439- "XObject" ,
440- ] ) ;
453+ const resourcesPromise = this . loadResources ( RESOURCES_KEYS_OPERATOR_LIST ) ;
441454
442455 const partialEvaluator = new PartialEvaluator ( {
443456 xref : this . xref ,
@@ -525,11 +538,15 @@ class Page {
525538 contentStreamPromise ,
526539 resourcesPromise ,
527540 ] ) . then ( async ( [ contentStream ] ) => {
541+ const resources = await this . #getMergedResources(
542+ contentStream . dict ,
543+ RESOURCES_KEYS_OPERATOR_LIST
544+ ) ;
528545 const opList = new OperatorList ( intent , sink ) ;
529546
530547 handler . send ( "StartRenderPage" , {
531548 transparency : partialEvaluator . hasBlendModes (
532- this . resources ,
549+ resources ,
533550 this . nonBlendModesSet
534551 ) ,
535552 pageIndex : this . pageIndex ,
@@ -539,7 +556,7 @@ class Page {
539556 await partialEvaluator . getOperatorList ( {
540557 stream : contentStream ,
541558 task,
542- resources : this . resources ,
559+ resources,
543560 operatorList : opList ,
544561 } ) ;
545562 return opList ;
@@ -642,19 +659,19 @@ class Page {
642659 sink,
643660 } ) {
644661 const contentStreamPromise = this . getContentStream ( ) ;
645- const resourcesPromise = this . loadResources ( [
646- "ExtGState" ,
647- "Font" ,
648- "Properties" ,
649- "XObject" ,
650- ] ) ;
662+ const resourcesPromise = this . loadResources ( RESOURCES_KEYS_TEXT_CONTENT ) ;
651663 const langPromise = this . pdfManager . ensureCatalog ( "lang" ) ;
652664
653665 const [ contentStream , , lang ] = await Promise . all ( [
654666 contentStreamPromise ,
655667 resourcesPromise ,
656668 langPromise ,
657669 ] ) ;
670+ const resources = await this . #getMergedResources(
671+ contentStream . dict ,
672+ RESOURCES_KEYS_TEXT_CONTENT
673+ ) ;
674+
658675 const partialEvaluator = new PartialEvaluator ( {
659676 xref : this . xref ,
660677 handler,
@@ -672,7 +689,7 @@ class Page {
672689 return partialEvaluator . getTextContent ( {
673690 stream : contentStream ,
674691 task,
675- resources : this . resources ,
692+ resources,
676693 includeMarkedContent,
677694 disableNormalization,
678695 sink,
0 commit comments