
    h5j                       d Z ddlmZ ddlZddlmZmZ ddlmZm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZ dd
lmZmZmZmZmZmZmZmZmZmZmZmZmZm Z  ddl!m"Z"m#Z#  ejH                  e%      Z& G d de'      Z( G d d      Z) G d d      Z* G d de*      Z+ G d de*      Z, G d de*      Z- G d d      Z. G d de*      Z/ G d de*      Z0 G d d      Z1 G d  d!e*      Z2 G d" d#e      Z3 G d$ d%e3      Z4 G d& d'e4      Z5d1d(Z6d1d)Z7d* Z8e G d+ d,             Z9ed2d-       Z:	 	 	 	 	 	 	 	 d3d.Z;	 	 	 	 	 	 	 	 	 	 d4d/Z<	 	 	 	 	 	 	 	 d5d0Z=y)6z+Support for working with interactive forms.    )annotationsN)ABCabstractmethod)	GeneratorSequence)contextmanager)	dataclass)Decimal)cast)AcroFormAcroFormFieldArray
DictionaryFormFieldFlagMatrixNameObjectOperatorPagePdf	RectangleStringparse_content_stream)ContentStreamBuilder
SimpleFontc                  2     e Zd ZdZd Z fdZ fdZ xZS )MultipleFieldProxya  A list of fields that share the same name.

    Behaves like a list, allowing access to all duplicate fields.
    Also behaves like the first field in the list, proxying attribute access,
    to maintain backward compatibility with code expecting a single field.
    c                     t        | d   |      S Nr   )getattrselfnames     B/var/www/html/qr/venv/lib/python3.12/site-packages/pikepdf/form.py__getattr__zMultipleFieldProxy.__getattr__-   s    tAw%%    c                    t        |       dkD  r t        | d   |      rt        | d   ||       y t        |   ||       y r   )lenhasattrsetattrsuper__setattr__)r"   r#   value	__class__s      r$   r,   zMultipleFieldProxy.__setattr__0   s<    t9q=WT!Wd3DGT5) Ge,r&   c                (    dt         |           dS )Nz<MultipleFieldProxy: >)r+   __repr__)r"   r.   s    r$   r1   zMultipleFieldProxy.__repr__8   s    &uw'7'9&:!<<r&   )__name__
__module____qualname____doc__r%   r,   r1   __classcell__r.   s   @r$   r   r   %   s    &-= =r&   r   c                      e Zd ZU dZdZded<   	 ded<   	 ded<   d	ed
<   ded<   	 ddd	 	 	 ddZd ZddZddZ	ddZ
d ZddZy)Forma  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-dict[str, _FieldWrapper | MultipleFieldProxy]_cacheF)r<   c                   || _         |j                  | _        i | _        |" || j                   | j                        | _        || _        y)zInitialize the form.N)r=   acroformr>   r?   r:   r<   )r"   pdfr:   r<   s       r$   __init__zForm.__init__\   sB     	+(<TYY(WD%!2r&   c                .    t        | j                  |      S N)r    r>   r!   s     r$   r%   zForm.__getattr__k   s    t~~t,,r&   c           	     P   || j                   v r| j                   |   S | j                  j                  |      }|st        |      t	        |      dkD  r:t        |D cg c]  }| j                  ||       c}      }|| j                   |<   |S | j                  |d   |      S c c}w )N   r   )r?   r>   get_fields_with_qualified_nameKeyErrorr(   r   _wrap)r"   r#   fieldsfwrappeds        r$   __getitem__zForm.__getitem__n   s    4;;;;t$$>>tD4. v;?(v)N!$**Q*=)NOG 'DKKNzz&)T**	 *Os   B#c                F    	 | j                  |       y# t        $ r Y yw xY w)NTF)rN   rI   r!   s     r$   __contains__zForm.__contains__}   s*    	T" 		s    	  c           
   #  <  K   t               }| j                  j                  D ]o  }|j                  }|| j                  v r)||vr%|j                  |       || j                  |   f G|| j                  v r3|j                  r'|j                  | j                  |   j                  k(  r|| j                  v r|j                  r| j                  j                  |      }t        |      dkD  rQt        |D cg c]  }| j                  ||       c}      }|| j                  |<   |j                  |       ||f |j                  |       || j                  |d   |      f I|j                  |       || j                  ||      f r yc c}w w)z6Yield (name, field) pairs for all fields in this form.rG   r   N)setr>   rK   fully_qualified_namer?   addis_radio_buttonparent_fieldrH   r(   r   rJ   )r"   seenfieldr#   rK   rL   rM   s          r$   itemsz
Form.items   sa    u^^** "	4E--Dt{{"t4'7DKK---#))LLDKK$5$<$<< $&& FFtLv;?0v1V!$**Q2E1VWG(/DKK%HHTN-'HHTN

6!9d ;;;DJJud333E"	42 2Ws   C6F8F
BFc              #  D   K   | j                         D ]	  \  }}|  y wrE   )rZ   )r"   r#   items      r$   __iter__zForm.__iter__   s$     **, 	JD$J	s    c                   |j                   rt        | |      }n|j                  rt        | |      }n|j                  rt        | |      }ng|j                  rt        | |      }nN|j                  rt        | |      }n5|j                  t        j                  k(  rt        | |      }nt        d      || j                  |<   |S )NzUnknown field type)is_text	TextFieldis_checkboxCheckboxFieldrU   RadioButtonGroupis_pushbuttonPushbuttonField	is_choiceChoiceField
field_typer   SigSignatureFieldRuntimeErrorr?   )r"   rY   r#   rM   s       r$   rJ   z
Form._wrap   s    ==e,G#D%0G""&tU3G  %dE2G__!$.G)$T51G344#Dr&   rE   )rB   r   r:   z&type[AppearanceStreamGenerator] | None)r#   str)returnz9Generator[tuple[str, _FieldWrapper | MultipleFieldProxy]])rY   r   r#   rl   rm   _FieldWrapper)r2   r3   r4   r5   r:   __annotations__rC   r%   rN   rP   rZ   r]   rJ    r&   r$   r9   r9   <   s    " >B:A 
 I99
 HL3
  33 E3-+%4Nr&   r9   c                  T    e Zd ZdZddZd Zed	d       Zed	d       Zed	d       Z	y)
rn   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                     || _         || _        y rE   )_formrW   )r"   formrY   s      r$   rC   z_FieldWrapper.__init__   s    
r&   c                .    t        | j                  |      S rE   )r    rW   r!   s     r$   r%   z_FieldWrapper.__getattr__   s    t{{D))r&   c                b    t        | j                  j                  t        j                  z        S )zIs this a required field?)r;   rW   flagsr   requiredr"   s    r$   is_requiredz_FieldWrapper.is_required   $     DKK%%(>(>>??r&   c                b    t        | j                  j                  t        j                  z        S )zIs this a read-only field?)r;   rW   rw   r   	read_onlyry   s    r$   is_read_onlyz_FieldWrapper.is_read_only   s$     DKK%%(?(??@@r&   c                R    | j                   j                  t        j                  z   S )zGShould this field's value be included when exporting data from the PDF?)rW   rw   r   	no_exportry   s    r$   export_enabledz_FieldWrapper.export_enabled   s"     ;;$$}'>'>>>>r&   N)rt   r9   rY   r   rm   r;   )
r2   r3   r4   r5   rC   r%   propertyrz   r~   r   rp   r&   r$   rn   rn      sQ    * @ @ A A ? ?r&   rn   c                      e Zd ZdZedd       Zedd       Zedd       Zedd       Zedd       Z	edd       Z
edd       Zedd	       Zedd
       Zedd       Zej                  dd       Zy)r`   z"Represents an editable text field.c                b    t        | j                  j                  t        j                  z        S )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;   rW   rw   r   tx_multilinery   s    r$   is_multilinezTextField.is_multiline   $     DKK%%(B(BBCCr&   c                b    t        | j                  j                  t        j                  z        S )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;   rW   rw   r   tx_combry   s    r$   	is_combedzTextField.is_combed   s$     DKK%%(=(==>>r&   c                b    t        | j                  j                  t        j                  z        S )zIs this a rich text field?

        Rich text functionality is not currently implemented, but this flag is presented
        for your information.
        )r;   rW   rw   r   tx_rich_textry   s    r$   is_rich_textzTextField.is_rich_text   r   r&   c                b    t        | j                  j                  t        j                  z        S )zIs this a password field?

        Password fields are not currently implemented, but this flag is presented for
        your information.
        )r;   rW   rw   r   tx_passwordry   s    r$   is_passwordzTextField.is_password   s$     DKK%%(A(AABBr&   c                b    t        | j                  j                  t        j                  z        S )zIs this a file select field?

        File select fields are not currently implemented, but this flag is presented for
        your information.
        )r;   rW   rw   r   tx_file_selectry   s    r$   is_file_selectzTextField.is_file_select	  s$     DKK%%(D(DDEEr&   c                R    | j                   j                  t        j                  z   S )z/Should spell-checking be enabled in this field?)rW   rw   r   tx_do_not_spell_checkry   s    r$   spell_check_enabledzTextField.spell_check_enabled  s"     ;;$$}'J'JJJJr&   c                R    | j                   j                  t        j                  z   S )zCShould scrolling (horizontal or vertical) be allowed in this field?)rW   rw   r   tx_do_not_scrollry   s    r$   scrolling_enabledzTextField.scrolling_enabled  s"     ;;$$}'E'EEEEr&   c                8    | j                   j                  d      S )z-The maximum length of the text in this field./MaxLen)rW   get_inheritable_field_valuery   s    r$   
max_lengthzTextField.max_length  s     {{66yAAr&   c                .    | j                   j                  S )z2The default (placeholder) value of the text field.)rW   default_value_as_stringry   s    r$   default_valuezTextField.default_value!  s     {{222r&   c                .    | j                   j                  S )zThe value of the text field.)rW   value_as_stringry   s    r$   r-   zTextField.value&  s     {{***r&   c                   | j                   s|j                  dd      }| j                  }| j                  j                  s*|(t        |      |kD  r|d | }t        j                  d       | j                  j                  || j                  j                  d u        | j                  j                  0| j                  j                  j                  | j                         y y )N
 z7Value is too long for text field and is being truncated)r   replacer   rs   r<   r(   logwarningrW   	set_valuer:   generate_text)r"   r-   r   s      r$   r-   zTextField.value+  s       MM$+E__


,,&E
Z'+:&EKKQReTZZ%D%D%LM::**6JJ++99$++F 7r&   Nr   )rm   
int | None)rm   rl   )r-   rl   )r2   r3   r4   r5   r   r   r   r   r   r   r   r   r   r   r-   setterrp   r&   r$   r`   r`      s    ,D D ? ? D D C C F F K K F F B B 3 3 + + \\G Gr&   r`   c                  ~    e Zd ZdZedd       Zed	d       Zed
d       Zedd       Zej                  dd       Zy)rb   zRepresents a checkbox field.c                    t        d | j                  j                  j                  j                  j                         D              S )zList the possible states for this checkbox.

        Typically this will be /Off plus one additional arbitrary value representing the
        on state.
        c              3  2   K   | ]  }t        |        y wrE   r   .0keys     r$   	<genexpr>z'CheckboxField.states.<locals>.<genexpr>I  s     F3T#YF   )tuplerW   objAPNkeysry   s    r$   stateszCheckboxField.statesB  s2     F$++//*<*<*>*>*C*C*EFFFr&   c                    | j                   j                  j                  j                  j	                         D ]"  }|t
        j                  k7  st        |      c S  t        d      )z@The underlying value associated with this checkbox's "on" state.zCheckbox has no on state)rW   r   r   r   r   r   Offrk   r!   s     r$   on_valuezCheckboxField.on_valueK  sT     KKOO&&((--/ 	"DtxxDz!	" 566r&   c                .    | j                   j                  S )z1The actual current stored value of this checkbox.rW   r-   ry   s    r$   r-   zCheckboxField.valueS       {{   r&   c                .    | j                   j                  S )zIs this checkbox checked?)rW   
is_checkedry   s    r$   checkedzCheckboxField.checkedX  s     {{%%%r&   c                   |rt        | j                  j                  j                  j                  j                               }|j                  t        t        j                               | j                  j                  t        |j                                      y | j                  j                  t        j                         y rE   )rR   rW   r   r   r   r   discardrl   r   r   r   pop)r"   r   r   s      r$   r   zCheckboxField.checked]  ss    ++--2245FNN3txx=)KK!!$vzz|"45KK!!$((+r&   Nrm   zSequence[Name]rm   r   rm   zName | Noner   )r   r;   )
r2   r3   r4   r5   r   r   r   r-   r   r   rp   r&   r$   rb   rb   ?  sm    &G G 7 7 ! ! & & ^^, ,r&   rb   c                      e Zd ZdZed        Zed
d       Zedd       Zedd       Zej                  dd       Zedd       Z
e
j                  dd       Z
y	)rc   z Represents a radio button group.c                R    | j                   j                  t        j                  z   S )z<If radio buttons in this group are allowed to be togged off.)rW   rw   r   btn_no_toggle_offry   s    r$   can_toggle_offzRadioButtonGroup.can_toggle_offl  s"     ;;$$}'F'FFFFr&   c                   t         j                  | j                  j                  vryt	               }| j                  j                  j                  D ]5  }|j                  |j                  j                  j                                7 |j                  t        t         j                               t        d |D              S )zIList the possible on states of all component radio buttons in this group.rp   c              3  2   K   | ]  }t        |        y wrE   r   )r   states     r$   r   z*RadioButtonGroup.states.<locals>.<genexpr>z  s     5UT%[5r   )r   KidsrW   r   rR   updater   r   r   r   rl   r   r   )r"   r   kids      r$   r   zRadioButtonGroup.statesq  s~     99DKKOO+5;;??'' 	+CMM#&&((--/*	+s488}%5f555r&   c                     t         j                   j                  j                  vryt	         fdt         j                  j                  j                        D              S ) A list of all available options.rp   c              3  Z   K   | ]"  \  }}t        t        t        |      |       $ y wrE   )RadioButtonOptionr   r   )r   indexr   r"   s      r$   r   z+RadioButtonGroup.options.<locals>.<genexpr>  s-      
s dDS$95A
s   (+)r   r   rW   r   r   	enumeratery   s   `r$   optionszRadioButtonGroup.options|  sI     99DKKOO+ 
'(<(<=
 
 	
r&   c                .    | j                   j                  S )+The value of the currently selected option.r   ry   s    r$   r-   zRadioButtonGroup.value  r   r&   c                   |t         j                  k(  r| j                  st        d      | j                  j
                  | j                  j                  |       y || j                  j                  _        | j                  j                  j                  D ]U  }t        |j                  j                  j                               }||v r||_        <d|v sAt         j                  |_        W y )Nz)To uncheck a radio button, check another.z/AS)r   r   r   
ValueErrorrW   rV   r   r   Vr   rR   r   r   r   AS)r"   r-   r   r   s       r$   r-   zRadioButtonGroup.value  s    DHHT%8%8HII;;%KK!!%( !&DKKOO{{++ &SVVXX]]_-F?"CFc\!XXCF&r&   c                   | j                   j                  }||t        j                  k(  ryt        j                  | j                   j
                  vryt        | j                   j
                  j                        D ]:  \  }}||j                  j                  v st        | t        t        |      |      c S  t        j                  d       y)zThe currently selected option.Nz9Radio button group value does not match any radio buttons)rW   r-   r   r   r   r   r   r   r   r   r   r   r   r   )r"   r-   r   r   s       r$   selectedzRadioButtonGroup.selected  s     !!=ETXX-99DKKOO+#DKKOO$8$89 	MJE3 (tJ/DeLL	M 	OPr&   c                X    |j                   | urt        d      |j                  | _        y )Nz$Option does not belong to this group)_groupr   r   r-   r"   options     r$   r   zRadioButtonGroup.selected  s%    ==$CDD__
r&   Nr   )rm   zSequence[RadioButtonOption]r   )r-   r   )rm   zRadioButtonOption | None)r   r   )r2   r3   r4   r5   r   r   r   r   r-   r   r   rp   r&   r$   rc   rc   i  s    *G G 6 6 
 
 ! ! \\& &.   __% %r&   rc   c                      e Zd ZU dZded<   ded<   ddZedd       Zedd       Zd	 Z	edd
       Z
e
j                  dd       Z
y)r   z9Represents a single radio button in a radio button group.rc   r   r   _annot_dictc                .    || _         || _        || _        y)z-Create a new option for a radio button group.N)r   r   _index)r"   group
annot_dictr   s       r$   rC   zRadioButtonOption.__init__  s    %r&   c                ~    t        d | j                  j                  j                  j	                         D              S )zList the possible states for this radio button.

        Typically this will be /Off plus one additional arbitrary value representing the
        on state.
        c              3  2   K   | ]  }t        |        y wrE   r   r   s     r$   r   z+RadioButtonOption.states.<locals>.<genexpr>  s     G3T#YGr   )r   r   r   r   r   ry   s    r$   r   zRadioButtonOption.states  s0     G$*:*:*=*=*?*?*D*D*FGGGr&   c                    | j                   j                  j                  j                         D ]"  }|t        j
                  k7  st	        |      c S  t        d      )z>The underlying value associated with this button's "on" state.zRadio button has no on state)r   r   r   r   r   r   rk   r!   s     r$   r   zRadioButtonOption.on_value  sR     $$''))..0 	"DtxxDz!	" 9::r&   c                :    | j                   | j                  _        y)z!Mark this as the selected option.Nr   r   r-   ry   s    r$   selectzRadioButtonOption.select  s     MMr&   c                H    | j                   | j                  j                  k(  S )z)Is this is the currently selected option?r   ry   s    r$   r   zRadioButtonOption.checked  s     }} 1 111r&   c                ~    |r| j                   | j                  _        y t        j                  | j                  _        y rE   )r   r   r-   r   r   )r"   r-   s     r$   r   zRadioButtonOption.checked  s%     $DKK $DKKr&   N)r   rc   r   r   r   intr   r   r   )r-   r;   )r2   r3   r4   r5   ro   rC   r   r   r   r   r   r   rp   r&   r$   r   r     sq    C H H ; ;* 2 2 ^^) )r&   r   c                      e Zd ZdZy)re   zRepresents a pushbutton field.

    Pushbuttons retain no permanent state, so this class is merely a placeholder. It
    exposes no functionality.
    N)r2   r3   r4   r5   rp   r&   r$   re   re     s    r&   re   c                      e Zd ZdZedd       Zedd       Zedd       Zedd       Zedd       Z	edd       Z
e
j                  dd       Z
edd	       Zej                  dd
       Zy)rg   zRepresents a choice field.

    Multiselect is not currently supported; multiselect fields will still only allow
    selecting a single value.
    c                b    t        | j                  j                  t        j                  z        S )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;   rW   rw   r   ch_multi_selectry   s    r$   is_multiselectzChoiceField.is_multiselect  s$     DKK%%(E(EEFFr&   c                b    t        | j                  j                  t        j                  z        S )z?Is this a combobox field? If false, this is instead a list box.)r;   rW   rw   r   ch_combory   s    r$   is_comboboxzChoiceField.is_combobox  r{   r&   c                b    t        | j                  j                  t        j                  z        S )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;   rW   rw   r   ch_editry   s    r$   
allow_editzChoiceField.allow_edit  s$     DKK%%(=(==>>r&   c                R    | j                   j                  t        j                  z   S )zsShould spell-checking be enabled in this field?

        This is only valid for fields that allow editing.
        )rW   rw   r   ch_do_not_spell_checkry   s    r$   r   zChoiceField.spell_check_enabled  s"     ;;$$}'J'JJJJr&   c                     t         j                   j                  j                  vryt	         fdt         j                  j                  j                  j                               D              S )r   rp   c              3  R   K   | ]  \  }}t        t        d |      |         yw)String | ArrayN)ChoiceFieldOptionr   )r   r   optr"   s      r$   r   z&ChoiceField.options.<locals>.<genexpr>!  s.      
s dD)93$?G
s   $')r   OptrW   r   r   r   as_listry   s   `r$   r   zChoiceField.options  sR     884;;??* 
'(;(;(C(C(EF
 
 	
r&   c                   t         j                  | j                  j                  v rst	        | j                  j                  j                  j                               D ]9  \  }}t        | t        d|      |      }|j                  | j                  k(  s7|c S  | j                  yt        | t        | j                        d      S )z@The currently selected option, or None if no option is selected.r  N)r   r
  rW   r   r   r  r  r   export_valuer-   r   )r"   r   r	  r   s       r$   r   zChoiceField.selected&  s     88t{{&'(;(;(C(C(EF "
s*46F1LeT&&$**4!M" :: vdjj'94@@r&   c                :   |j                   | urt        d      | j                   j                  |j                  | j                  j
                  d u        | j                  j
                  0| j                  j
                  j                  | j                          y y )Nz$Option does not belong to this field)rW   r   r   r  rs   r:   generate_choicer   s     r$   r   zChoiceField.selected2  s{    ==$CDD 	!@!@D!H	
 ::**6JJ++;;DKKH 7r&   c                \    | j                   j                  | j                   j                  S y)r   N)rW   r-   r   ry   s    r$   r-   zChoiceField.valueC  s'     ;;(;;...r&   c                   | j                   skd}t        | j                  j                  j                        D ]/  \  }}t        | t        d|      |      }|j                  |k(  s-d} n |st        d|      | j                  j                  || j                  j                  d u        | j                  j                  0| j                  j                  j                  | j                         y y )NFr  Tz)Not a valid option for this choice field:)r  r   rW   r   r
  r  r   r  r   r   rs   r:   r  )r"   r-   okayr   r	  r   s         r$   r-   zChoiceField.valueJ  s     D'(;(;< 
s*46F1LeT&&%/D	
  !LeTTeTZZ%D%D%LM::**6JJ++;;DKKH 7r&   Nr   )rm   zSequence[ChoiceFieldOption])rm   zChoiceFieldOption | None)r   r  )rm   
str | None)r-   r  )r2   r3   r4   r5   r   r   r   r  r   r   r   r   r-   rp   r&   r$   rg   rg     s     G G @ @ ? ? K K 
 
 	A 	A __I I    \\I Ir&   rg   c                  t    e Zd ZdZd
dZed        Zed        Zedd       Zedd       Z	d Z
edd       Zy	)r  z.Represents a single option for a choice field.c                .    || _         || _        || _        y)z'Create a new option for a choice field.N)rW   _optr   )r"   rY   r	  r   s       r$   rC   zChoiceFieldOption.__init__`  s    	r&   c                l    t        | j                  t              r| j                  d   S | j                  S )zGThe value that will be displayed on-screen to the user in a PDF reader.rG   
isinstancer  r   ry   s    r$   display_valuezChoiceFieldOption.display_valuef  *     dii'99Q<99r&   c                l    t        | j                  t              r| j                  d   S | j                  S )z?The value that will be used when exporting data from this form.r   r  ry   s    r$   r  zChoiceFieldOption.export_valuen  r  r&   c                    | j                   duxrT | j                   t        | j                  j                  j                  j	                  t
        j                  d            k  S )zIs this option hidden?

        Hidden options are still settable via code, but are not shown to users in PDF
        reader applications.
        Nr   )r   r   rW   r   getr   TIry   s    r$   	is_hiddenzChoiceFieldOption.is_hiddenv  sP     {{$& 
4;;KK""&&tww2:
 ,
 	
r&   c                    | j                   duS )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   ry   s    r$   	is_presetzChoiceFieldOption.is_preset  s     {{$&&r&   c                &    | | j                   _        y)z'Set this option as the selected option.N)rW   r   ry   s    r$   r   zChoiceFieldOption.select  s    #r&   c                H    | j                   j                  | j                  k(  S )z&Is this the currently selected option?)rW   r-   r  ry   s    r$   r   zChoiceFieldOption.selected  s     {{  D$5$555r&   N)rY   rg   r	  r  r   r   r   )r2   r3   r4   r5   rC   r   r  r  r   r"  r   r   rp   r&   r$   r  r  ]  ss    8     
 
 ' '$ 6 6r&   r  c                  8    e Zd ZdZdd	 	 	 	 	 ddZ	 	 	 	 ddZy)rj   zKRepresents a signature field.

    Signatures are not truly supported.
    N)expand_rectc          	     N   | j                   j                  j                  | j                        d   }t        j
                  |j                  v rIt        |j                  j
                        j                  || j                  |j                  |             | j                   j                  j                  D ]a  }| j                   j                  j                  |      D ]7  }||k(  s	|j                  || j                  |j                  |            c c S  c t        d      )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)rs   r>   get_annotations_for_fieldrW   r   Pr   r   add_overlay_expand_rectrectr=   pagesget_widget_annotations_for_pager   )r"   overlayr&  field_annotpageannots         r$   stamp_overlayzSignatureField.stamp_overlay  s    B jj**DDT[[QRST66[__$""#//**;+;+;[I JJOO)) 	D--MMdS K'++!2!25::{!K 	 HIIr&   c           
        ||S t        |t        t        t        f      r||||f}n3t	        |      dk(  r|d   |d   |d   |d   f}n|d   |d   |d   |d   f}t        |j                  t        |d         z
  |j                  t        |d         z
  |j                  t        |d         z   |j                  t        |d         z         S )N   r   rG      )
r  r   floatr
   r(   r   llxllyurxury)r"   r,  	expand_byexpands       r$   r+  zSignatureField._expand_rect  s    
 K i#ug!67IyAF^q lIaL)A,	!MFlIaL)A,	!MFHHuVAY''HHuVAY''HHuVAY''HHuVAY''	
 	
r&   )r/  zObject | Pager&  >int | float | Decimal | Sequence[int | float | Decimal] | Nonerm   r   )r,  r   r<  r>  )r2   r3   r4   r5   r3  r+  rp   r&   r$   rj   rj     sJ     .J.J	.J 
.J`

 R
r&   rj   c                  R    e Zd ZU dZded<   ded<   d
dZedd       Zedd       Zy	)AppearanceStreamGeneratorzAppearance 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   rB   r   rt   c                     || _         || _        y)z+Initialize the appearance stream generator.N)rB   rt   )r"   rB   rt   s      r$   rC   z"AppearanceStreamGenerator.__init__  s    	r&   c                     yz0Generate the appearance stream for a text field.Nrp   r"   rY   s     r$   r   z'AppearanceStreamGenerator.generate_text      r&   c                     yz2Generate the appearance stream for a choice field.Nrp   rD  s     r$   r  z)AppearanceStreamGenerator.generate_choice  rE  r&   N)rB   r   rt   r   rY   r   )	r2   r3   r4   r5   ro   rC   r   r   r  rp   r&   r$   r@  r@    sB     
H
N
 ? ? A Ar&   r@  c                       e Zd ZdZddZddZy) DefaultAppearanceStreamGeneratora  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                f    | j                   j                  |      D ]  }|j                  |        yrC  rt   r(  generate_appearancer"   rY   r2  s      r$   r   z.DefaultAppearanceStreamGenerator.generate_text  .    YY88? 	-E%%e,	-r&   c                f    | j                   j                  |      D ]  }|j                  |        yrG  rL  rN  s      r$   r  z0DefaultAppearanceStreamGenerator.generate_choice  rO  r&   NrH  )r2   r3   r4   r5   r   r  rp   r&   r$   rJ  rJ    s    8-
-r&   rJ  c                  $     e Zd ZdZd fdZ xZS )!ExtendedAppearanceStreamGeneratora  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                    |j                   t        j                  z  r"t        | j                  | j
                  |       y|j                   t        j                  z  r"t        | j                  | j
                  |       yt        | %  |       yrC  )
rw   r   r   _text_appearance_multilinerB   rt   r   _text_appearance_combedr+   r   )r"   rY   r.   s     r$   r   z/ExtendedAppearanceStreamGenerator.generate_text<  s^    ;;333&txxEB[[=000#DHHdii? G!%(r&   rH  )r2   r3   r4   r5   r   r6   r7   s   @r$   rR  rR  %  s    ,) )r&   rR  c           
        t         j                  |      }|j                  |      D ]  }|j                  j	                         }t        |j                        5 }|j                  |j                  j                  }||j                  xs d}n&|j                  j                  ||j                        }|j                  t        j                         j!                  |j"                  t%        |j&                        |z
               t)        ||j*                  ||       d d d        t-        | |||        y # 1 sw Y   xY wr   )_DaInfodecode_for_fieldr(  r,  to_bbox_text_stream_builderdatext_matrixfontascentline_spacingconvert_width	font_sizeset_text_matrixr   identity
translatedr8  r
   r;  _layout_multiline_textr   _apply_appearance_stream)	rB   rt   rY   da_infor2  bboxcsr^  
top_offsets	            r$   rT  rT  W  s   &&u-G//6 @zz!!#!'**- 	M""* !,,>!(!5!5!:J ")!;!; 1 1"J ""OO%00'$(("3j"@
 #2u'<'<gtL'	M( 	!eRw?/@	M 	Ms   CD<<E	c                   t         j                  |      }|j                  |      D ]  }|j                  j	                         }t        |j                        5 }|j                  |j                  j                  xs d}|j                  j                  ||j                        }|j                  t        j                         j                  |j                   t#        |j$                        |z
               t'        ||j(                  |||j+                  d             d d d        t-        | |||        y # 1 sw Y   xY w)Nr   r   )rW  rX  r(  r,  rY  rZ  r[  r\  r]  descentr`  ra  rb  r   rc  rd  r8  r
   r9  _layout_combed_textr   r   rf  )rB   rt   rY   rg  r2  rh  ri  bottom_offsets           r$   rU  rU  s  s   &&u-G//6 @zz!!#!'**- 	""* !( 4 4 9 ' : :!7#4#4! ""OO%00'$(("3m"C
  %%11)<	, 	!eRw?3@	 	s   CD==E	c                B   t               }|j                  j                  |       ||j                  <   t        |      }t	        | |||      }t
        j                  |j                  v r||j                  j                  _        yt        |      |j                  _        y)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   )rB   r2  ri  rh  rg  
fonts_dict	resourcesxobjs           r$   rf  rf    ss     J$+LL$9$9#$>Jw  !
+IT2y9Dww%))		!D)		r&   c                      e Zd ZU ded<   ded<   ded<   ded<   d	Zd
ed<   d	Zd
ed<   d	Zd
ed<   d	Zded<   edd       Z	y	)rW  bytesr[  r   r]  r   rr  r
   ra  NzDecimal | Nonechar_spacingword_spacingr_  zMatrix | Noner\  c           
        |j                   }t        j                         }|j                  |      }t	        |      }t        d      }t        d      }d}d}	|D ]%  }
|
j                  |k(  r|
}|
j                  |k(  s$|
}	' |t        d|j                         |j                  \  }}|dk(  r|j                  dd      }t        d      }nt        t        |      }t        t        |      }t        j                  ||j                         }|	t        t"        |	j                  d         nd}|j$                  rt        |j$                        n|} | ||||dd||      S )	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   operatorrk   rS   operandsr   r
   r   r   r   loaddefault_resourcesr   leading)clsrY   r[  tmp_pdf
tmp_streaminstructionstf_optm_optf_insttm_instinstfont_family_objfont_size_objra  font_familyr]  matrixr_  s                     r$   rX  z_DaInfo.decode_for_field  sd    %%'')((,
+J7   	D}}%}}%		
 ? H--.0 
 *1)9)9&A GX.BI Wm4I41{E,C,CD181DD))!,-$ 	 15wt||,)2t[)T4vVVr&   )rY   r   rm   rW  )
r2   r3   r4   ro   ry  rz  r_  r\  classmethodrX  rp   r&   r$   rW  rW    sT    I
O#'L.'#'L.'#'L.'!%K%<W <Wr&   rW  c              #  (  K   t               }|j                  t        j                         |j	                          |j                          |j                  |        | |j                          |j                          |j                          yw)a  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$   rZ  rZ    st       +,O((1
  2
&&(s   BBc                >   |j                   }|j                  }t        |j                  d|            |j                  xs t        d      z   }| j                  |j                  xs |       |j                  }	 |j                  |      }t        |j                               D ]  \  }	}
|	dk7  r| j                          t        d      }g }|
j                         D ]w  }t        |j                  ||            }||z   |z   |kD  r6| j                  dj                  |             | j                          |}|g}_|j!                  |       |||z   z  }y |s| j                  dj                  |              y# t        $ r |j                  dd      }Y w xY w)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]  ra  r
   
text_widthrz  set_text_leadingr_  widthencodeNotImplementedErrorr   
splitlinesmove_cursor_new_linesplit	show_textjoinappend)contenttextrg  rh  r]  ra  rz  r  encoded_textlinenoline
line_width
line_wordswordword_lens                  r$   re  re    s   $ <<D!!I 4??3	:;*
L W11>Y?JJE>{{4(
 ","9"9";< 5Q;((*%aj
"$
JJL 	6DttY?@HL(83e;!!$))J"78,,.%
"V
 !!$'lX55
	6 dii
34)5	  > {{79{=>s   :E< <FFc                   |j                   }|j                  }|j                  }t        |      |z  }t        |j	                  ||            }	g }
t        d      }|D ]R  }	 |j                  |      }|j                  |      |	z
  dz  }|
j                  ||z          |
j                  |       |}T  | j                  |
  y# t        $ r |j                  dd      }Y nw xY w)a\  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  r5  N)
r]  ra  r  r
   convert_width_reverser  r  unscaled_char_widthr  show_text_with_kerning)r  r  rg  rh  r   r]  ra  r  	comb_sizecomb_size_gsparts
last_widthcharencoded_charspace_neededs                  r$   rm  rm  E  s    " <<D!!IJJE+I455iKLL13E!!*J 
"	B;;t,L
 00>MQRRZ,./\"!

" #G""E* # 	B  ;;wy;AL	Bs   !CC! C!c                L    | j                  |j                         ddd||      S )z-Convert a content stream into a Form XObject.XObjectr9   rG   )TypeSubtypeFormTypeBBox	Resources)r  build)rB   rh  r  ru  s       r$   rs  rs  k  s2     ??   r&   )rB   r   rt   r   rY   r   )r[  rx  )r  r   r  rl   rg  rW  rh  r   )
r  r   r  rl   rg  rW  rh  r   r   zint | Decimal)rB   r   rh  r   r  r   ru  r   )>r5   
__future__r   loggingabcr   r   collections.abcr   r   
contextlibr   dataclassesr	   decimalr
   typingr   pikepdfr   r   r   r   r   r   r   r   r   r   r   r   r   r   pikepdf.canvasr   r   	getLoggerr2   r   listr   r9   rn   r`   rb   rc   r   re   rg   r  rj   r@  rJ  rR  rT  rU  rf  rW  rZ  re  rm  rs  rp   r&   r$   <module>r     s   2 "  # / % !       <g!= =.D DN? ?>ZG ZGz%,M %,TL%} L%^+) +)\m lI- lI^46 46nN
] N
bA A0%-'@ %-P)(H )d@8@<*  GW GW GWT ) )<75!75),757>75FO75t#+!#+
#+ #+ 	#+
 #+L	(<ISr&   