
    OAi8                       S r SSKJr  SSKrSSKJrJr  SSKJrJ	r	J
r
  SSKJr  SSKJr  SSKJr  SS	KJrJrJrJrJrJrJrJrJrJrJrJrJrJr  SS
K J!r!J"r"  \RF                  " \$5      r% " S S5      r& " S S5      r' " S S\'5      r( " S S\'5      r) " S S\'5      r* " S S5      r+ " S S\'5      r, " S S\'5      r- " S S5      r. " S S\'5      r/ " S S \5      r0 " S! S"\05      r1 " S# S$\15      r2S.S% jr3S.S& jr4S' r5\ " S( S)5      5       r6\S/S* j5       r7        S0S+ jr8          S1S, jr9        S2S- jr:g)3z+Support for working with interactive forms.    )annotationsN)ABCabstractmethod)	GeneratorMappingSequence)contextmanager)	dataclass)Decimal)AcroFormAcroFormFieldArray
DictionaryFormFieldFlagMatrixNameObjectOperatorPagePdf	RectangleStringparse_content_stream)ContentStreamBuilder
SimpleFontc                      \ rS rSr% SrSrS\S'    S\S'    S\S	'   S
\S'   S\S'    SSS.   SS jjjrS rSS jr	SS jr
SS jrS rSS jrSrg)Form$   a  Utility class to make it easier to work with interactive forms.

This is easier to use than the core {class}`pikepdf.AcroForm` implementation, but is
higher-level, and abstracts over details in ways which do impose some limitations,
such as failing for PDFs which have multiple fields with the same name.

A non-exhaustive list of limitations:

* No support for signatures
* No support for password fields
* No support for rich text fields
* Multiselect choice fields are treated as single-select
* Generating appearance streams imposes additional limitations (see
  {class}`pikepdf.form.DefaultAppearanceStreamGenerator` and
  {class}`pikepdf.form.ExtendedAppearanceStreamGenerator` for details.)
Nz AppearanceStreamGenerator | Nonegenerate_appearancesboolignore_max_lengthr   _pdfr   	_acroformzMapping[str, _FieldWrapper]_cacheF)r!   c                   Xl         UR                  U l        0 U l        Ub"  U" U R                   U R                  5      U l        X0l        g)zInitialize the form.N)r"   acroformr#   r$   r   r!   )selfpdfr   r!   s       H/var/www/html/land-ocr/venv/lib/python3.13/site-packages/pikepdf/form.py__init__Form.__init__D   s>     	+(<TYY(WD%!2    c                .    [        U R                  U5      $ N)getattrr#   r'   names     r)   __getattr__Form.__getattr__S   s    t~~t,,r,   c                    XR                   ;   a  U R                   U   $ U R                  R                  U5      nU(       d  [        U5      e[	        U5      S:  a  [        SU 35      eU R                  US   U5      $ )N    Multiple fields with same name: r   )r$   r#   get_fields_with_qualified_nameKeyErrorlenRuntimeError_wrap)r'   r1   fieldss      r)   __getitem__Form.__getitem__V   so    ;;;;t$$>>tD4. v;?!A$HIIzz&)T**r,   c                H     U R                  U5        g! [         a     gf = f)NTF)r=   r8   r0   s     r)   __contains__Form.__contains__`   s*    	T" 		s    
!!c              #    #    [        5       nU R                  R                   GHI  nUR                  nX0R                  ;   a*  X1;  a%  UR                  U5        X0R                  U   4v   MI  X0R                  ;   a:  UR                  (       a)  UR                  U R                  U   R                  :X  a  M  X0R                  ;   a  [        SU 35      eUR                  (       ad  U R                  R                  U5      n[        U5      S:  a  [        SU 35      eUR                  U5        X0R                  US   U5      4v   GM$  UR                  U5        X0R                  X#5      4v   GML     g7f)z6Yield (name, field) pairs for all fields in this form.r6   r5   r   N)setr#   r<   fully_qualified_namer$   addis_radio_buttonparent_fieldr:   r7   r9   r;   )r'   seenfieldr1   r<   s        r)   items
Form.itemsg   s$    u^^**E--D{{"t'7KK---#))LLDKK$5$<$<< $"%EdV#LMM&& FFtLv;?&)I$'PQQJJvay$777JJu333= +s   E0E2c              #  F   #    U R                  5        H	  u  pUv   M     g 7fr.   )rK   )r'   r1   items      r)   __iter__Form.__iter__   s     **,JDJ 's   !c                   UR                   (       a  [        X5      nOUR                  (       a  [        X5      nOUR                  (       a  [        X5      nOoUR                  (       a  [        X5      nORUR                  (       a  [        X5      nO5UR                  [        R                  :X  a  [        X5      nO[        S5      eX0R                  U'   U$ )NzUnknown field type)is_text	TextFieldis_checkboxCheckboxFieldrF   RadioButtonGroupis_pushbuttonPushbuttonField	is_choiceChoiceField
field_typer   SigSignatureFieldr:   r$   )r'   rJ   r1   wrappeds       r)   r;   
Form._wrap   s    ==,G#D0G""&t3G  %d2G__!$.G)$T1G344#Dr,   )r#   r$   r"   r   r!   r.   )r(   r   r   z&type[AppearanceStreamGenerator] | None)r1   str)returnz$Generator[tuple[str, _FieldWrapper]])rJ   r   r1   r`   )__name__
__module____qualname____firstlineno____doc__r   __annotations__r*   r2   r=   r@   rK   rO   r;   __static_attributes__ r,   r)   r   r   $   s    " >B:A 
 I''
 HL3
  33 E3-+!4Fr,   r   c                  d    \ rS rSrSrS
S jrS r\SS j5       r\SS j5       r	\SS j5       r
Srg	)_FieldWrapper   zBase class for other field types.

In addition to the methods and properties documented here, all fields expose the
same properties and methods defined on `pikepdf.AcroFormField`. These are forwarded
to the underlying field object.
c                    Xl         X l        g r.   )_formrH   )r'   formrJ   s      r)   r*   _FieldWrapper.__init__   s    
r,   c                .    [        U R                  U5      $ r.   )r/   rH   r0   s     r)   r2   _FieldWrapper.__getattr__   s    t{{D))r,   c                b    [        U R                  R                  [        R                  -  5      $ )zIs this a required field?)r    rH   flagsr   requiredr'   s    r)   is_required_FieldWrapper.is_required   $     DKK%%(>(>>??r,   c                b    [        U R                  R                  [        R                  -  5      $ )zIs this a read-only field?)r    rH   rt   r   	read_onlyrv   s    r)   is_read_only_FieldWrapper.is_read_only   s$     DKK%%(?(??@@r,   c                Z    U R                   R                  [        R                  -  (       + $ )zGShould this field's value be included when exporting data from the PDF?)rH   rt   r   	no_exportrv   s    r)   export_enabled_FieldWrapper.export_enabled   s"     ;;$$}'>'>>>>r,   )rH   rn   N)ro   r   rJ   r   ra   r    )rb   rc   rd   re   rf   r*   r2   propertyrw   r|   r   rh   ri   r,   r)   rk   rk      sQ    * @ @ A A ? ?r,   rk   c                     \ rS rSrSr\SS j5       r\SS j5       r\SS j5       r\SS j5       r	\SS j5       r
\SS j5       r\SS	 j5       r\SS
 j5       r\SS j5       r\SS j5       r\R                   SS j5       rSrg)rS      z"Represents an editable text field.c                b    [        U R                  R                  [        R                  -  5      $ )zIs this a multiline text field?

If True, text will be wrapped and newlines will be allowed. If False, text will
not be wrapped and newlines are stripped.
)r    rH   rt   r   tx_multilinerv   s    r)   is_multilineTextField.is_multiline   $     DKK%%(B(BBCCr,   c                b    [        U R                  R                  [        R                  -  5      $ )zIs this a combed text field?

If True, the field will be split into equal-length segments, based on
``max_length``, containing one character each.
)r    rH   rt   r   tx_combrv   s    r)   	is_combedTextField.is_combed   s$     DKK%%(=(==>>r,   c                b    [        U R                  R                  [        R                  -  5      $ )zIs this a rich text field?

Rich text functionality is not currently implemented, but this flag is presented
for your information.
)r    rH   rt   r   tx_rich_textrv   s    r)   is_rich_textTextField.is_rich_text   r   r,   c                b    [        U R                  R                  [        R                  -  5      $ )z{Is this a password field?

Password fields are not currently implemented, but this flag is presented for
your information.
)r    rH   rt   r   tx_passwordrv   s    r)   is_passwordTextField.is_password   s$     DKK%%(A(AABBr,   c                b    [        U R                  R                  [        R                  -  5      $ )zIs this a file select field?

File select fields are not currently implemented, but this flag is presented for
your information.
)r    rH   rt   r   tx_file_selectrv   s    r)   is_file_selectTextField.is_file_select   s$     DKK%%(D(DDEEr,   c                Z    U R                   R                  [        R                  -  (       + $ )z/Should spell-checking be enabled in this field?)rH   rt   r   tx_do_not_spell_checkrv   s    r)   spell_check_enabledTextField.spell_check_enabled   s"     ;;$$}'J'JJJJr,   c                Z    U R                   R                  [        R                  -  (       + $ )zCShould scrolling (horizontal or vertical) be allowed in this field?)rH   rt   r   tx_do_not_scrollrv   s    r)   scrolling_enabledTextField.scrolling_enabled   s"     ;;$$}'E'EEEEr,   c                8    U R                   R                  S5      $ )z-The maximum length of the text in this field./MaxLen)rH   get_inheritable_field_valuerv   s    r)   
max_lengthTextField.max_length   s     {{66yAAr,   c                .    U R                   R                  $ )z2The default (placeholder) value of the text field.)rH   default_value_as_stringrv   s    r)   default_valueTextField.default_value   s     {{222r,   c                .    U R                   R                  $ )zThe value of the text field.)rH   value_as_stringrv   s    r)   valueTextField.value  s     {{***r,   c                   U R                   (       d  UR                  SS5      nU R                  nU R                  R                  (       d,  Ub)  [        U5      U:  a  US U n[        R                  S5        U R                  R                  XR                  R                  S L 5        U R                  R                  b0  U R                  R                  R                  U R                  5        g g )N
 z7Value is too long for text field and is being truncated)r   replacer   rn   r!   r9   logwarningrH   	set_valuer   generate_text)r'   r   r   s      r)   r   r   	  s       MM$+E__


,,&E
Z'+:&EKKQReZZ%D%D%LM::**6JJ++99$++F 7r,   ri   Nr   )ra   
int | None)ra   r`   )r   r`   )rb   rc   rd   re   rf   r   r   r   r   r   r   r   r   r   r   r   setterrh   ri   r,   r)   rS   rS      s    ,D D ? ? D D C C F F K K F F B B 3 3 + + \\G Gr,   rS   c                      \ rS rSrSr\S
S j5       r\SS j5       r\SS j5       r\SS j5       r	\	R                  SS j5       r	Srg	)rU   i  zRepresents a checkbox field.c                    [        S U R                  R                  R                  R                  R                  5        5       5      $ )zList the possible states for this checkbox.

Typically this will be /Off plus one additional arbitrary value representing the
on state.
c              3  8   #    U  H  n[        U5      v   M     g 7fr.   r   .0keys     r)   	<genexpr>'CheckboxField.states.<locals>.<genexpr>'  s     F*E3T#YY*E   )tuplerH   objAPNkeysrv   s    r)   statesCheckboxField.states   s2     F$++//*<*<*>*>*C*C*EFFFr,   c                    U R                   R                  R                  R                  R	                  5        H$  nU[
        R                  :w  d  M  [        U5      s  $    g)z@The underlying value associated with this checkbox's "on" state.N)rH   r   r   r   r   r   Offr0   s     r)   on_valueCheckboxField.on_value)  sA     KKOO&&((--/DtxxDz! 0r,   c                .    U R                   R                  $ )z1The actual current stored value of this checkbox.rH   r   rv   s    r)   r   CheckboxField.value0       {{   r,   c                .    U R                   R                  $ )zIs this checkbox checked?)rH   
is_checkedrv   s    r)   checkedCheckboxField.checked5  s     {{%%%r,   c                   U(       a  [        U R                  R                  R                  R                  R                  5       5      nUR                  [        R                  5        U R                  R                  [        UR                  5       5      5        g U R                  R                  [        R                  5        g r.   )rC   rH   r   r   r   r   discardr   r   r   pop)r'   r   r   s      r)   r   r   :  so    ++--2245FNN488$KK!!$vzz|"45KK!!$((+r,   ri   Nra   zSequence[Name]ra   r   ra   zName | Noner   )r   r    )rb   rc   rd   re   rf   r   r   r   r   r   r   rh   ri   r,   r)   rU   rU     sm    &G G " " ! ! & & ^^, ,r,   rU   c                      \ rS rSrSr\S 5       r\SS j5       r\SS j5       r\SS j5       r	\	R                  SS j5       r	\SS j5       r\R                  SS	 j5       rS
rg)rV   iF  z Represents a radio button group.c                Z    U R                   R                  [        R                  -  (       + $ )z<If radio buttons in this group are allowed to be togged off.)rH   rt   r   btn_no_toggle_offrv   s    r)   can_toggle_offRadioButtonGroup.can_toggle_offI  s"     ;;$$}'F'FFFFr,   c                ~   [         R                  U R                  R                  ;  a  g[	        5       nU R                  R                  R                   H6  nUR                  UR                  R                  R                  5       5        M8     UR                  [         R                  5        [        S U 5       5      $ )zIList the possible on states of all component radio buttons in this group.ri   c              3  8   #    U  H  n[        U5      v   M     g 7fr.   r   )r   states     r)   r   *RadioButtonGroup.states.<locals>.<genexpr>W  s     5fUT%[[fr   )r   KidsrH   r   rC   updater   r   r   r   r   r   )r'   r   kids      r)   r   RadioButtonGroup.statesN  su     99DKKOO+;;??''CMM#&&((--/* (txx 5f555r,   c                   ^  [         R                  T R                  R                  ;  a  g[	        U 4S j[        T R                  R                  R                  5       5       5      $ ) A list of all available options.ri   c              3  @   >#    U  H  u  p[        TX!5      v   M     g 7fr.   )RadioButtonOption)r   indexr   r'   s      r)   r   +RadioButtonGroup.options.<locals>.<genexpr>^  s$      
=
 dC//=   )r   r   rH   r   r   	enumeraterv   s   `r)   optionsRadioButtonGroup.optionsY  sI     99DKKOO+ 
'(<(<=
 
 	
r,   c                .    U R                   R                  $ )+The value of the currently selected option.r   rv   s    r)   r   RadioButtonGroup.valuec  r   r,   c                   U[         R                  :X  a  U R                  (       d  [        S5      eU R                  R
                  c  U R                  R                  U5        g XR                  R                  l        U R                  R                  R                   HZ  n[        UR                  R                  R                  5       5      nX;   a  Xl        M=  SU;   d  ME  [         R                  Ul        M\     g )Nz)To uncheck a radio button, check another.z/AS)r   r   r   
ValueErrorrH   rG   r   r   Vr   rC   r   r   r   AS)r'   r   r   r   s       r)   r   r   h  s    DHHT%8%8HII;;%KK!!%( !&KKOO{{++SVVXX]]_-?"Fc\!XXCF ,r,   c                   U R                   R                  nUb  U[        R                  :X  a  g[        R                  U R                   R
                  ;  a  g[        U R                   R
                  R                  5       H,  u  p#XR                  R                  ;   d  M   [        XU5      s  $    [        R                  S5        g)zThe currently selected option.Nz9Radio button group value does not match any radio buttons)rH   r   r   r   r   r   r   r   r   r   r   r   )r'   r   r   r   s       r)   selectedRadioButtonGroup.selected  s     !!=ETXX-99DKKOO+#DKKOO$8$89JE (E:: : 	OPr,   c                Z    UR                   U La  [        S5      eUR                  U l        g )Nz$Option does not belong to this group)_groupr   r   r   r'   options     r)   r   r     s%    ==$CDD__
r,   )r   Nr   )ra   zSequence[RadioButtonOption]r   )r   r   )ra   zRadioButtonOption | None)r  r   )rb   rc   rd   re   rf   r   r   r   r   r   r   r   rh   ri   r,   r)   rV   rV   F  s    *G G 6 6 
 
 ! ! \\& &.   __% %r,   rV   c                      \ rS rSr% SrS\S'   S\S'   SS jr\SS j5       r\SS	 j5       r	S
 r
\SS j5       r\R                  SS j5       rSrg)r   i  z9Represents a single radio button in a radio button group.rV   r   r   _annot_dictc                (    Xl         X l        X0l        g)z-Create a new option for a radio button group.N)r   r  _index)r'   group
annot_dictr   s       r)   r*   RadioButtonOption.__init__  s    %r,   c                    S U R                   R                  R                  R                  R	                  5        5       $ )zList the possible states for this radio button.

Typically this will be /Off plus one additional arbitrary value representing the
on state.
c              3  8   #    U  H  n[        U5      v   M     g 7fr.   r   r   s     r)   r   +RadioButtonOption.states.<locals>.<genexpr>  s     A%@cS		%@r   )rH   r   r   r   r   rv   s    r)   r   RadioButtonOption.states  s-     BT[[__%7%7%9%9%>%>%@AAr,   c                    U R                   R                  R                  R                  5        H$  nU[        R
                  :w  d  M  [	        U5      s  $    g)z>The underlying value associated with this button's "on" state.N)r  r   r   r   r   r   r0   s     r)   r   RadioButtonOption.on_value  s?     $$''))..0DtxxDz! 1r,   c                :    U R                   U R                  l        g)z!Mark this as the selected option.Nr   r   r   rv   s    r)   selectRadioButtonOption.select  s     MMr,   c                H    U R                   U R                  R                  :H  $ )z)Is this is the currently selected option?r  rv   s    r)   r   RadioButtonOption.checked  s     }} 1 111r,   c                    U(       a  U R                   U R                  l        g [        R                  U R                  l        g r.   )r   r   r   r   r   )r'   r   s     r)   r   r    s%     $DKK $DKKr,   )r  r   r  N)r  rV   r  r   r   intr   r   r   )r   r    )rb   rc   rd   re   rf   rg   r*   r   r   r   r  r   r   rh   ri   r,   r)   r   r     sq    C B B " "* 2 2 ^^) )r,   r   c                      \ rS rSrSrSrg)rX   i  zRepresents a pushbutton field.

Pushbuttons retain no permanent state, so this class is merely a placeholder. It
exposes no functionality.
ri   N)rb   rc   rd   re   rf   rh   ri   r,   r)   rX   rX     s    r,   rX   c                      \ rS rSrSr\SS j5       r\SS j5       r\SS j5       r\SS j5       r	\SS j5       r
\SS j5       r\R                  SS	 j5       r\SS
 j5       r\R                  SS j5       rSrg)rZ   i  zRepresents a choice field.

Multiselect is not currently supported; multiselect fields will still only allow
selecting a single value.
c                b    [        U R                  R                  [        R                  -  5      $ )zIs this a multiselect field?

Multiselect fields are currently treated as single-selection fields. True
multiselect is not yet supported, but this flag is presented for your
information.
)r    rH   rt   r   ch_multi_selectrv   s    r)   is_multiselectChoiceField.is_multiselect  s$     DKK%%(E(EEFFr,   c                b    [        U R                  R                  [        R                  -  5      $ )z?Is this a combobox field? If false, this is instead a list box.)r    rH   rt   r   ch_comborv   s    r)   is_comboboxChoiceField.is_combobox  ry   r,   c                b    [        U R                  R                  [        R                  -  5      $ )zDoes this field include an editable text box in addition to the dropdown?

The field must be a comboxbox; this option is not valid for list boxes.
)r    rH   rt   r   ch_editrv   s    r)   
allow_editChoiceField.allow_edit  s$     DKK%%(=(==>>r,   c                Z    U R                   R                  [        R                  -  (       + $ )zcShould spell-checking be enabled in this field?

This is only valid for fields that allow editing.
)rH   rt   r   ch_do_not_spell_checkrv   s    r)   r   ChoiceField.spell_check_enabled  s"     ;;$$}'J'JJJJr,   c                   ^  [         R                  T R                  R                  ;  a  g[	        U 4S j[        T R                  R                  R                  R                  5       5       5       5      $ )r   ri   c              3  @   >#    U  H  u  p[        TX!5      v   M     g 7fr.   )ChoiceFieldOption)r   r   optr'   s      r)   r   &ChoiceField.options.<locals>.<genexpr>  s$      
F
 dC//Fr   )r   OptrH   r   r   r   as_listrv   s   `r)   r   ChoiceField.options  sR     884;;??* 
'(;(;(C(C(EF
 
 	
r,   c                R   [         R                  U R                  R                  ;   aj  [	        U R                  R                  R                  R                  5       5       H/  u  p[        XU5      nUR                  U R                  :X  d  M-  Us  $    [        X R                  S5      $ )z@The currently selected option, or None if no option is selected.N)	r   r-  rH   r   r   r.  r*  export_valuer   )r'   r   r+  s      r)   r   ChoiceField.selected  sw     88t{{&'(;(;(C(C(EF
'59##tzz1J G !zz488r,   c                >   UR                   U La  [        S5      eU R                   R                  UR                  U R                  R
                  S L 5        U R                  R
                  b0  U R                  R
                  R                  U R                   5        g g )Nz$Option does not belong to this field)rH   r   r   r1  rn   r   generate_choicer   s     r)   r   r2    s{    ==$CDD 	!@!@D!H	
 ::**6JJ++;;DKKH 7r,   c                ^    U R                   R                  b  U R                   R                  $ g)r   N)rH   r   r   rv   s    r)   r   ChoiceField.value  s'     ;;(;;...r,   c                   U R                   (       dg  Sn[        U R                  R                  R                  5       H%  u  p4[        XU5      nUR                  U:X  d  M#  Sn  O   U(       d  [        SU5      eU R                  R                  XR                  R                  S L 5        U R                  R                  b0  U R                  R                  R                  U R                  5        g g )NFTz)Not a valid option for this choice field:)r#  r   rH   r   r-  r*  r1  r   r   rn   r   r4  )r'   r   okayr   r+  s        r)   r   r6  $  s     D'(;(;<
'59##u,D	 =
  !LeTTeZZ%D%D%LM::**6JJ++;;DKKH 7r,   ri   Nr   )ra   zSequence[ChoiceFieldOption])ra   zChoiceFieldOption | None)r  r*  )ra   
str | None)r   r9  )rb   rc   rd   re   rf   r   r  r  r#  r   r   r   r   r   rh   ri   r,   r)   rZ   rZ     s     G G @ @ ? ? K K 
 
 9 9 __I I    \\I Ir,   rZ   c                      \ rS rSrSrSS jr\S 5       r\S 5       r\SS j5       r	\SS j5       r
S r\SS	 j5       rS
rg)r*  i7  z.Represents a single option for a choice field.c                (    Xl         X l        X0l        g)z'Create a new option for a choice field.N)rH   _optr  )r'   rJ   r+  r   s       r)   r*   ChoiceFieldOption.__init__:  s    	r,   c                v    [        U R                  [        5      (       a  U R                  S   $ U R                  $ )zGThe value that will be displayed on-screen to the user in a PDF reader.r5   
isinstancer<  r   rv   s    r)   display_valueChoiceFieldOption.display_value@  -     dii''99Q<99r,   c                v    [        U R                  [        5      (       a  U R                  S   $ U R                  $ )z?The value that will be used when exporting data from this form.r   r?  rv   s    r)   r1  ChoiceFieldOption.export_valueH  rC  r,   c                    U R                   SL=(       aK    U R                   U R                  R                  R                  R                  [        R
                  S5      :  $ )z{Is this option hidden?

Hidden options are still settable via code, but are not shown to users in PDF
reader applications.
Nr   )r  rH   r   getr   TIrv   s    r)   	is_hiddenChoiceFieldOption.is_hiddenP  sK     {{$& 
4;;9K9K9O9O9S9SGGQ:
 ,
 	
r,   c                    U R                   SL$ )zIs this option one of the field's preset options?

If false, this is a manually entered value typed by the user in an editable
choice field.
N)r  rv   s    r)   	is_presetChoiceFieldOption.is_preset[  s     {{$&&r,   c                $    X R                   l        g)z'Set this option as the selected option.N)rH   r   rv   s    r)   r  ChoiceFieldOption.selectd  s    #r,   c                H    U R                   R                  U R                  :H  $ )z&Is this the currently selected option?)rH   r   r1  rv   s    r)   r   ChoiceFieldOption.selectedh  s     {{  D$5$555r,   )rH   r  r<  N)rJ   rZ   r+  zString | Arrayr   r   r   )rb   rc   rd   re   rf   r*   r   rA  r1  rI  rL  r  r   rh   ri   r,   r)   r*  r*  7  ss    8     
 
 ' '$ 6 6r,   r*  c                  >    \ rS rSrSrSS.     SS jjrS	S jrSrg)
r]   in  zCRepresents a signature field.

Signatures are not truly supported.
N)expand_rectc          	     V   U R                   R                  R                  U R                  5      S   n[        R
                  UR                  ;   aH  [        UR                  R
                  5      R                  XR                  UR                  U5      5        U R                   R                  R                   Hc  nU R                   R                  R                  U5       H7  nXS:X  d  M
  UR                  XR                  UR                  U5      5      s  s  $    Me     [        S5      e)a{  Stamp an image over the top of a signature field.

This is *not* true support for PDF signatures. Rather, it is merely a utility
for adding an image to the PDF at the location of a signature field.

This uses `pikepdf.Page.add_overlay` under the hood, see that method for
additional usage information.

If the bounding box of the signature field is smaller than the "visual"
signature area in the PDF, you may use the ``expand_rect`` parameter to increase
the dimensions of the rectangle when stamping. This may be any of the
following types:

* A number, which will be added equally to all sides of the box
* A sequence of two numbers, which will be added on the X and Y axis,
  respectively
* A sequence of four numbers, which will be added to the left, bottom, right,
  and top sides respectively

Positive numbers will increase the size of the box, and negative numbers will
decease it.
r   z-Could not find annotation for signature field)rn   r#   get_annotations_for_fieldrH   r   Pr   r   add_overlay_expand_rectrectr"   pagesget_widget_annotations_for_pager   )r'   overlayrS  field_annotpageannots         r)   stamp_overlaySignatureField.stamp_overlayt  s    B jj**DDT[[QRST66[__$""#//**;+;+;[I JJOO))D--MMdS'++!2!25::{!K  T * HIIr,   c           
     j   Uc  U$ [        U[        [        -  [        -  5      (       a  X"X"4n[	        U5      S:X  a  / UQUQ7n[        UR                  [        US   5      -
  UR                  [        US   5      -
  UR                  [        US   5      -   UR                  [        US   5      -   5      $ )N   r   r5      )
r@  r  floatr   r9   r   llxllyurxury)r'   rY  	expand_bys      r)   rX  SignatureField._expand_rect  s    Kiuw!677"yDIy>Q0)0i0IHHuYq\**HHuYq\**HHuYq\**HHuYq\**	
 	
r,   ri   )r\  zObject | PagerS  z>int | float | Decimal | Sequence[int | float | Decimal] | Nonera   r   )rY  r   rj  zint | float | Decimal | None)rb   rc   rd   re   rf   r`  rX  rh   ri   r,   r)   r]   r]   n  s7     .J.J	.J 
.J`
r,   r]   c                  `    \ rS rSr% SrS\S'   S\S'   SS jr\SS j5       r\SS	 j5       r	S
r
g)AppearanceStreamGeneratori  zAppearance stream generators are used to render forms.

They are used by the `pikepdf.form.Form` class to optionally generate appearance
streams as forms are filled.
r   r(   r   ro   c                    Xl         X l        g)z+Initialize the appearance stream generator.N)r(   ro   )r'   r(   ro   s      r)   r*   "AppearanceStreamGenerator.__init__  s    	r,   c                    gz0Generate the appearance stream for a text field.Nri   r'   rJ   s     r)   r   'AppearanceStreamGenerator.generate_text      r,   c                    gz2Generate the appearance stream for a choice field.Nri   rr  s     r)   r4  )AppearanceStreamGenerator.generate_choice  rt  r,   )ro   r(   N)r(   r   ro   r   rJ   r   )rb   rc   rd   re   rf   rg   r*   r   r   r4  rh   ri   r,   r)   rm  rm    sB     
H
N
 ? ? A Ar,   rm  c                  ,    \ rS rSrSrSS jrSS jrSrg) DefaultAppearanceStreamGeneratori  aI  Basic appearance stream generator using QPDF's default algorithm.

It is thus subject to all the same
`limitations <https://qpdf.readthedocs.io/en/stable/cli.html#option-generate-appearances>`_.

Briefly summarized, these limitations are:

* Cannot generate appearance streams using encodings other than ASCII, WinAnsi, or
  MacRoman
* No support for multiline text
* No support for auto-sized text
* Does not respect quadding

Using this class will produce the same results as the following code:

.. code-block:: python

    form = Form(pdf, generate_appearances = None)
    ...
    pdf.generate_appearances()

However, unlike the above, appearances will be generated on the fly as the form is
filled out, rather than all at once at the end.

You may extend this class to customize appearance streams or add support for
features you need.
c                j    U R                   R                  U5       H  nUR                  U5        M     grq  ro   rU  generate_appearancer'   rJ   r_  s      r)   r   .DefaultAppearanceStreamGenerator.generate_text  *    YY88?E%%e, @r,   c                j    U R                   R                  U5       H  nUR                  U5        M     grv  r|  r~  s      r)   r4  0DefaultAppearanceStreamGenerator.generate_choice  r  r,   ri   Nrx  )rb   rc   rd   re   rf   r   r4  rh   ri   r,   r)   rz  rz    s    8-
-r,   rz  c                  0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )!ExtendedAppearanceStreamGeneratori  a]  Alternate appearance stream generator to address limitations of the default one.

Improved features include:
  * Supports multiline text fields, with caveats:

  * Word wrap does not take scaling factors (other than font size) into account

  * Spacing operators not taken into consideration either

  * Quadding is still ignored

  * Due to limitations in Firefox's PDF viewer, the font and the line breaks will be
    incorrect when viewed in Firefox. PDFs filled by full-fat PDF readers, including
    Adobe Acrobat Reader, exhibit the same behavior when viewed in Firefox.

  * Supports combed text fields, with most of the same caveats as above

Otherwise, this implementation has most of the same limitations as the default
implementation. Unlike the default implementation, this is implemented in Python
rather than C++, so will also be less performant.
c                4  > UR                   [        R                  -  (       a"  [        U R                  U R
                  U5        gUR                   [        R                  -  (       a"  [        U R                  U R
                  U5        g[        TU ]%  U5        grq  )
rt   r   r   _text_appearance_multiliner(   ro   r   _text_appearance_combedsuperr   )r'   rJ   	__class__s     r)   r   /ExtendedAppearanceStreamGenerator.generate_text
  s^    ;;333&txxEB[[=000#DHHdii? G!%(r,   ri   rx  )rb   rc   rd   re   rf   r   rh   __classcell__)r  s   @r)   r  r    s    ,) )r,   r  c           
        [         R                  U5      nUR                  U5       GH  nUR                  R	                  5       n[        UR                  5       nUR                  c  UR                  R                  nUc  UR                  nO%UR                  R                  XsR                  5      nUR                  [        R                  " 5       R!                  UR"                  [%        UR&                  5      U-
  5      5        [)        XbR*                  X55        S S S 5        [-        XWXS5        GM     g ! , (       d  f       N!= fr.   )_DaInfodecode_for_fieldrU  rY  to_bbox_text_stream_builderdatext_matrixfontascentline_spacingconvert_width	font_sizeset_text_matrixr   identity
translatedrf  r   ri  _layout_multiline_textr   _apply_appearance_stream)r(   ro   rJ   da_infor_  bboxcs
top_offsets           r)   r  r  %  s    &&u-G//6zz!!#!'**-""* %\\00
%!(!5!5J ")!;!;"$5$5"J ""OO%00'$(("3j"@
 #2'<'<gL% .& 	!R?- 7 .-s   CD88
E	c                   [         R                  U5      nUR                  U5       GH  nUR                  R	                  5       n[        UR                  5       nUR                  c  UR                  R                  =(       d    SnUR                  R                  XsR                  5      nUR                  [        R                  " 5       R                  UR                   [#        UR$                  5      U-
  5      5        ['        UUR(                  UUUR+                  S5      5        S S S 5        [-        XWXS5        GM     g ! , (       d  f       N!= f)Nr   r   )r  r  rU  rY  r  r  r  r  r  descentr  r  r  r   r  r  rf  r   rg  _layout_combed_textr   r   r  )r(   ro   rJ   r  r_  r  r  bottom_offsets           r)   r  r  @  s   &&u-G//6zz!!#!'**-""* !( 4 4 9 ' : :!#4#4! ""OO%00'$(("3m"C
  %%11)< ., 	!R?3 7 .-s   CE
E	c                2   [        5       nUR                  R                  U 5      XTR                  '   [        US9n[	        XX&5      n[
        R                  UR                  ;   a  XqR                  R                  l        g[        US9UR                  l        g)zConvert content stream to a Form XObject and save in annotation.

The appearance stream is saved in the annotation dictionary (AP) under the normal
(N) key.
)Font)r   N)	r   r  register	font_name_create_form_xobjectr   r   r   r   )r(   r_  r  r  r  
fonts_dict	resourcesxobjs           r)   r  r  ^  sk     J$+LL$9$9#$>J  !
+I29Dww%))		!D)		r,   c                      \ rS rSr% S\S'   S\S'   S\S'   S\S	'   S
rS\S'   S
rS\S'   S
rS\S'   S
rS\S'   \	SS j5       r
Srg
)r  in  bytesr  r   r  r   r  r   r  NzDecimal | Nonechar_spacingword_spacingr  zMatrix | Noner  c           
     >   UR                   n[        R                  " 5       nUR                  U5      n[	        U5      n[        S5      n[        S5      nSnSn	U H)  n
U
R                  U:X  a  U
nU
R                  U:X  d  M'  U
n	M+     Uc  [        SUR                   35      eUR                  u  pUS:X  a  UR                  SS5      nSn[        R                  " XR                  5      nU	b  U	R                  S   OSnUR                  =(       d    UnU " X-XSSX5      $ )	a  Parse the default appearance, returning it and the font styling information.

The default appearance is a value that is used to initialize the content stream
for text fields. It must at minimum contain a `Tf` operator, which indicates the
font family and size.
TfTmNz6No Tf operator found in default appearance stream for r   s   0 Tfs   11 Tf   )default_appearancer   newmake_streamr   r   operatorr:   rD   operandsr   r   loaddefault_resourcesleading)clsrJ   r  tmp_pdf
tmp_streaminstructionstf_optm_optf_insttm_instinstfont_familyr  r  matrixr  s                   r)   r  _DaInfo.decode_for_fieldy  s$    %%'')((,
+J7  D}}%}}%	 !
 ? H--.0 
 ")!1!1> GX.BI{,C,CD(/(;!!!$ ||0y2[T4VVr,   ri   )rJ   r   ra   r  )rb   rc   rd   re   rg   r  r  r  r  classmethodr  rh   ri   r,   r)   r  r  n  sT    I
O#'L.'#'L.'#'L.'!%K%5W 5Wr,   r  c              #  (  #    [        5       nUR                  [        R                  5        UR	                  5         UR                  5         UR                  U 5        Uv   UR                  5         UR                  5         UR                  5         g7f)au  Utility to build text content streams for variable text fields.

Example:

.. code-block:: python

    with _text_stream_builder(da) as cs:
        # Make calls against cs, e.g.:
        cs.show_text(b'some text')
        ...

    # Now cs is complete. (Make sure you are outside the context manager; additional
    # operations are added once the context manager closes.)
N)
r   begin_marked_contentr   Txpush
begin_textextendend_textr   end_marked_content)r  content_builders     r)   r  r    ss       +,O((1
  2
&&(s   BBc                *   UR                   nUR                  nUR                  SU5      UR                  =(       d    S-   nU R	                  UR
                  =(       d    U5        UR                  n UR                  U5      n[        UR                  5       5       H  u  pUS:w  a  U R                  5         [        S5      n
/ nU	R                  5        Hn  nUR                  X5      nX-   U-   U:  a7  U R                  SR                  U5      5        U R                  5         Un
U/nMV  UR!                  U5        XU-   -  n
Mp     U(       d  M  U R                  SR                  U5      5        M     g! [         a    UR                  SSS9n GNf = f)a  Lay out the given text, wrapping at the edges of the bounding box.

This layout algorithm is incomplete and somewhat rudimentary, but should produce
acceptable results for most common use cases.

Known issues:

* Does not respect field-defined alignment (quadding) and spacing.
* The text may overflow out the bottom of the box. We don't try to prevent this
  currently, though a correct implementation would do so if scrolling was
  disabled.
* Words which are longer than the box width may overflow out the right side.
* Does not allow line breaks other than at ' ' or '\n' characters.
* Only ASCII, WinAnsi, and MacRoman encodings are supported.
 r   asciir   errors    N)r  r  
text_widthr  set_text_leadingr  widthencodeNotImplementedErrorr   
splitlinesmove_cursor_new_liner   split	show_textjoinappend)contenttextr  r  r  r  r  r  linenoline
line_width
line_wordswordword_lens                 r)   r  r    sg   $ <<D!!I ??3	2g6J6J6OaPLW11>Y?JJE6{{4 
 "$//"34Q;((*QZ

JJLDt7H(83e;!!$))J"78,,.%
"V
 !!$'X55
 ! :dii
34) 5	  6 {{79{56s   2E4 4FFc                   UR                   nUR                  nUR                  n[        U5      U-  nUR	                  X5      n	/ n
SnU HR  n UR                  U5      nUR                  U5      U	-
  S-  nU
R                  X-   5        U
R                  U5        UnMT     U R                  " U
6   g! [         a    UR                  SSS9n Nmf = f)aD  Lay out text, spacing characters evenly according to comb size.

This layout algorithm is incomplete and somewhat rudimentary, but should produce
acceptable results for most common use cases.

Known issues:

* Does not respect field-defined alignment (quadding).
* Only ASCII, WinAnsi, and MacRoman encodings are supported.
r   r  r   r  rc  N)
r  r  r  r   convert_width_reverser  r  unscaled_char_widthr  show_text_with_kerning)r  r  r  r  r   r  r  r  	comb_sizecomb_size_gsparts
last_widthcharspace_neededs                 r)   r  r  	  s    " <<D!!IJJE+I--iCLEJ	:;;t$D
 006EJZ./T!
  ""E* # 	: ;;wy;9D	:s   B00CCc           	     F    U R                  UR                  5       SSSUUS9$ )z-Convert a content stream into a Form XObject.XObjectr   r5   )TypeSubtypeFormTypeBBox	Resources)r  build)r(   r  r  r  s       r)   r  r  /  s2     ??   r,   )r(   r   ro   r   rJ   r   )r  r  )r  r   r  r`   r  r  r  r   )
r  r   r  r`   r  r  r  r   r   zint | Decimal)r(   r   r  r   r  r   r  r   );rf   
__future__r   loggingabcr   r   collections.abcr   r   r   
contextlibr	   dataclassesr
   decimalr   pikepdfr   r   r   r   r   r   r   r   r   r   r   r   r   r   pikepdf.canvasr   r   	getLoggerrb   r   r   rk   rS   rU   rV   r   rX   rZ   r*  r]   rm  rz  r  r  r  r  r  r  r  r  r  ri   r,   r)   <module>r     s   2 "  # 8 8 % !      <!z zz? ?>ZG ZGz$,M $,RL%} L%^*) *)Zm jI- jIZ46 46nB
] B
JA A0%-'@ %-P)(H )d@6@<*  @W @W @WF ) )<55!55),557>55FO55p#+!#+
#+ #+ 	#+
 #+L	(<ISr,   