import PDFObject from 'src/core/objects/PDFObject' ; import PDFNumber from 'src/core/objects/PDFNumber' ; import PDFDict from 'src/core/objects/PDFDict' ; import PDFName from 'src/core/objects/PDFName' ; import PDFArray from 'src/core/objects/PDFArray' ; import PDFRef from 'src/core/objects/PDFRef' ; import PDFAcroField from 'src/core/acroform/PDFAcroField' ; import PDFAcroTerminal from 'src/core/acroform/PDFAcroTerminal' ; import PDFAcroNonTerminal from 'src/core/acroform/PDFAcroNonTerminal' ; import PDFAcroButton from 'src/core/acroform/PDFAcroButton' ; import PDFAcroSignature from 'src/core/acroform/PDFAcroSignature' ; import PDFAcroChoice from 'src/core/acroform/PDFAcroChoice' ; import PDFAcroText from 'src/core/acroform/PDFAcroText' ; import PDFAcroPushButton from 'src/core/acroform/PDFAcroPushButton' ; import PDFAcroRadioButton from 'src/core/acroform/PDFAcroRadioButton' ; import PDFAcroCheckBox from 'src/core/acroform/PDFAcroCheckBox' ; import PDFAcroComboBox from 'src/core/acroform/PDFAcroComboBox' ; import PDFAcroListBox from 'src/core/acroform/PDFAcroListBox' ; import { AcroButtonFlags , AcroChoiceFlags } from 'src/core/acroform/flags' ; export const createPDFAcroFields = ( kidDicts ? ) : [ PDFAcroField , PDFRef ] [ ] => { if ( ! kidDicts ) return [ ] ; const kids = [ ] ; for ( let idx = 0 , len = kidDicts . size ( ) ; idx < len ; idx ++ ) { const ref = kidDicts . get ( idx ) ; const dict = kidDicts . lookup ( idx ) ; if ( ref instanceof PDFRef && dict instanceof PDFDict ) { kids . push ( [ createPDFAcroField ( dict , ref ) , ref ] ) ; } } return kids ; } ; export const createPDFAcroField = ( dict , ref ) : PDFAcroField => { const isNonTerminal = isNonTerminalAcroField ( dict ) ; if ( isNonTerminal ) return PDFAcroNonTerminal . fromDict ( dict , ref ) ; return createPDFAcroTerminal ( dict , ref ) ; } ; const isNonTerminalAcroField = ( dict ) : boolean => { const kids = dict . lookup ( PDFName . of ( 'Kids' ) ) ; if ( kids instanceof PDFArray ) { for ( let idx = 0 , len = kids . size ( ) ; idx < len ; idx ++ ) { const kid = kids . lookup ( idx ) ; const kidIsField = kid instanceof PDFDict && kid . has ( PDFName . of ( 'T' ) ) ; if ( kidIsField ) return true ; } } return false ; } ; const createPDFAcroTerminal = ( dict , ref ) : PDFAcroTerminal => { const ftNameOrRef = getInheritableAttribute ( dict , PDFName . of ( 'FT' ) ) ; const type = dict . context . lookup ( ftNameOrRef , PDFName ) ; if ( type === PDFName . of ( 'Btn' ) ) return createPDFAcroButton ( dict , ref ) ; if ( type === PDFName . of ( 'Ch' ) ) return createPDFAcroChoice ( dict , ref ) ; if ( type === PDFName . of ( 'Tx' ) ) return PDFAcroText . fromDict ( dict , ref ) ; if ( type === PDFName . of ( 'Sig' ) ) return PDFAcroSignature . fromDict ( dict , ref ) ; return PDFAcroTerminal . fromDict ( dict , ref ) ; } ; const createPDFAcroButton = ( dict , ref ) : PDFAcroButton => { const ffNumberOrRef = getInheritableAttribute ( dict , PDFName . of ( 'Ff' ) ) ; const ffNumber = dict . context . lookupMaybe ( ffNumberOrRef , PDFNumber ) ; const flags = ffNumber ?. asNumber ( ) ?? 0 ; if ( flagIsSet ( flags , AcroButtonFlags . PushButton ) ) { return PDFAcroPushButton . fromDict ( dict , ref ) ; } else if ( flagIsSet ( flags , AcroButtonFlags . Radio ) ) { return PDFAcroRadioButton . fromDict ( dict , ref ) ; } else { return PDFAcroCheckBox . fromDict ( dict , ref ) ; } } ; const createPDFAcroChoice = ( dict , ref ) : PDFAcroChoice => { const ffNumberOrRef = getInheritableAttribute ( dict , PDFName . of ( 'Ff' ) ) ; const ffNumber = dict . context . lookupMaybe ( ffNumberOrRef , PDFNumber ) ; const flags = ffNumber ?. asNumber ( ) ?? 0 ; if ( flagIsSet ( flags , AcroChoiceFlags . Combo ) ) { return PDFAcroComboBox . fromDict ( dict , ref ) ; } else { return PDFAcroListBox . fromDict ( dict , ref ) ; } } ; const flagIsSet = ( flags , flag ) : boolean => ( flags & flag ) !== 0 ; const getInheritableAttribute = ( startNode , name ) => { let attribute ; ascend ( startNode , ( node ) => { if ( ! attribute ) attribute = node . get ( name ) ; } ) ; return attribute ; } ; const ascend = ( startNode , visitor ) => { visitor ( startNode ) ; const Parent = startNode . lookupMaybe ( PDFName . of ( 'Parent' ) , PDFDict ) ; if ( Parent ) ascend ( Parent , visitor ) ; } ;