15
15
16
16
import {
17
17
assert ,
18
+ bytesToString ,
18
19
FormatError ,
19
20
info ,
20
21
InvalidPDFException ,
@@ -28,6 +29,7 @@ import {
28
29
shadow ,
29
30
stringToBytes ,
30
31
stringToPDFString ,
32
+ stringToUTF8String ,
31
33
unreachable ,
32
34
Util ,
33
35
warn ,
@@ -732,6 +734,53 @@ class PDFDocument {
732
734
} ) ;
733
735
}
734
736
737
+ get xfaData ( ) {
738
+ const acroForm = this . catalog . acroForm ;
739
+ if ( ! acroForm ) {
740
+ return shadow ( this , "xfaData" , null ) ;
741
+ }
742
+
743
+ const xfa = acroForm . get ( "XFA" ) ;
744
+ const entries = {
745
+ "xdp:xdp" : "" ,
746
+ template : "" ,
747
+ datasets : "" ,
748
+ config : "" ,
749
+ connectionSet : "" ,
750
+ localeSet : "" ,
751
+ stylesheet : "" ,
752
+ "/xdp:xdp" : "" ,
753
+ } ;
754
+ if ( isStream ( xfa ) && ! xfa . isEmpty ) {
755
+ entries [ "xdp:xdp" ] = stringToUTF8String ( bytesToString ( xfa . getBytes ( ) ) ) ;
756
+ return shadow ( this , "xfaData" , entries ) ;
757
+ }
758
+
759
+ if ( Array . isArray ( xfa ) && xfa . length > 0 ) {
760
+ for ( let i = 0 , ii = xfa . length ; i < ii ; i += 2 ) {
761
+ let name ;
762
+ if ( i === 0 ) {
763
+ name = "xdp:xdp" ;
764
+ } else if ( i === ii - 2 ) {
765
+ name = "/xdp:xdp" ;
766
+ } else {
767
+ name = xfa [ i ] ;
768
+ }
769
+
770
+ if ( ! entries . hasOwnProperty ( name ) ) {
771
+ continue ;
772
+ }
773
+ const data = this . xref . fetchIfRef ( xfa [ i + 1 ] ) ;
774
+ if ( ! isStream ( data ) || data . isEmpty ) {
775
+ continue ;
776
+ }
777
+ entries [ name ] = stringToUTF8String ( bytesToString ( data . getBytes ( ) ) ) ;
778
+ }
779
+ return shadow ( this , "xfaData" , entries ) ;
780
+ }
781
+ return shadow ( this , "xfaData" , null ) ;
782
+ }
783
+
735
784
get formInfo ( ) {
736
785
const formInfo = { hasFields : false , hasAcroForm : false , hasXfa : false } ;
737
786
const acroForm = this . catalog . acroForm ;
0 commit comments