U
    c                     @   s   d dl Z d dlZd dlmZ ddlmZmZmZmZm	Z	 ddl
mZ ddlmZ ddd	d
ddgZG dd deZG dd deZdd ZG dd	 d	ZG dd
 d
ZG dd deZG dd deZdS )    N)Enum   )DictionaryObject
NameObject	PdfObjectStreamObjectpdf_name)BoxConstraints)PdfFileReaderResourceTypeResourceManagementErrorPdfResources
PdfContent
RawContentImportedPdfPagec                   @   sH   e Zd ZdZedZedZedZedZedZ	edZ
edZd	S )
r   u|   
    Enum listing resources that can be used as keys in a resource dictionary.

    See ISO 32000-1, § 7.8.3 Table 34.
    z
/ExtGStatez/ColorSpacez/Patternz/Shadingz/XObjectz/Fontz/PropertiesN)__name__
__module____qualname____doc__r   ZEXT_G_STATEZCOLOR_SPACEZPATTERNZSHADINGZXOBJECTZFONTZ
PROPERTIES r   r   =/tmp/pip-unpacked-wheel-0kb_yl26/pyhanko/pdf_utils/content.pyr      s   c                   @   s   e Zd ZdZdS )r   z=
    Used to signal problems with resource dictionaries.
    N)r   r   r   r   r   r   r   r   r   J   s   c                 C   s6   |  D ](\}}|| kr(td| d|| |< q| S )NzResource with name z occurs in both dictionaries.)itemsr   )Zdict1Zdict2kZv2r   r   r   _res_merge_helperQ   s    

r   c                   @   s<   e Zd ZdZdd ZedddZeddd	Zd
d Z	dS )r   a8  
    Representation of a PDF resource dictionary.

    This class implements :meth:`__getitem__` with :class:`.ResourceType` keys
    for dynamic access to its attributes.
    To merge two instances of :class:`.PdfResources` into one another,
    the class overrides :meth:`__iadd__`, so you can write.

    .. code-block:: python

        res1 += res2

    *Note:* Merging two resource dictionaries with conflicting resource names
    will produce a :class:`.ResourceManagementError`.

    *Note:* This class is currently only used for new resource dictionaries.
    c                 C   s<   t  | _t  | _t  | _t  | _t  | _t  | _t  | _d S N)r   Zext_g_stateZcolor_spacepatternZshadingxobjectfontZ
propertiesselfr   r   r   __init__n   s    zPdfResources.__init__)itemc                 C   s   t | |j S r   )getattrnamelower)r   r!   r   r   r   __getitem__w   s    zPdfResources.__getitem__returnc                    s     fdd}t dd | D S )zj
        Render this instance of :class:`.PdfResources` to an actual resource
        dictionary.
        c                  3   s&   t D ]}  |  }|r| j|fV  qd S r   )r   value)r   valr   r   r   _gen   s    z(PdfResources.as_pdf_object.<locals>._genc                 S   s   i | ]\}}||qS r   r   ).0r   vr   r   r   
<dictcomp>   s      z.PdfResources.as_pdf_object.<locals>.<dictcomp>)r   )r   r*   r   r   r   as_pdf_objectz   s    zPdfResources.as_pdf_objectc                 C   s    t D ]}t| | ||  q| S )a(  
        Merge another resource dictionary into this one.
        :param other:
            Another instance of :class:`.PdfResources`
        :return:
            Always returns ``self``
        :raises ResourceManagementError:
            Raised when there is a resource name conflict.
        )r   r   )r   otherr   r   r   r   __iadd__   s    
zPdfResources.__iadd__N)
r   r   r   r   r    r   r%   r   r.   r0   r   r   r   r   r   [   s
   	c                   @   s|   e Zd ZdZdZdeedddZee	e
dddZed	d
dZeedddZedddZedddZdd ZdS )r   z
    Abstract representation of part of a PDF content stream.

    .. warning::

        Whether :class:`.PdfContent` instances can be reused or not
        is left up to the subclasses.
    N)	resourcesboxc                 C   s"   |pt  | _|pt | _|| _d S r   )r   
_resourcesr	   r2   writer)r   r1   r2   r4   r   r   r   r       s    zPdfContent.__init__)categoryr#   r(   c                 C   s   || j | |< dS )a2  Set a value in the resource dictionary associated with this content
        fragment.

        :param category:
            The resource category to which the resource belongs.
        :param name:
            The resource's (internal) name.
        :param value:
            The resource's value.
        Nr3   )r   r5   r#   r(   r   r   r   set_resource   s    zPdfContent.set_resource)r1   c                 C   s   |  j |7  _ dS )zImport resources from another resource dictionary.

        :param resources:
            An instance of :class:`.PdfResources`.
        :raises ResourceManagementError:
            Raised when there is a resource name conflict.
        Nr6   )r   r1   r   r   r   import_resources   s    zPdfContent.import_resourcesr&   c                 C   s   | j S )z}
        :return:
            The :class:`.PdfResources` instance associated with this
            content fragment.
        r6   r   r   r   r   r1      s    zPdfContent.resourcesc                 C   s   t dS )z<
        Compile the content to graphics operators.
        N)NotImplementedErrorr   r   r   r   render   s    zPdfContent.renderc                 C   s2   ddl m} |  }||| jj| jj| j dS )u  
        Render the object to a form XObject to be referenced by another
        content stream. See ISO 32000-1, § 8.8.

        *Note:* Even if :attr:`writer` is set, the resulting form XObject will
        not be registered. This is left up to the caller.

        :return:
            A :class:`~.generic.StreamObject` instance representing
            the resulting form XObject.
        r   )init_xobject_dictionary)command_streamZ	box_widthZ
box_heightr1   )Zpyhanko.pdf_utils.writerr;   r:   r2   widthheightr3   r.   )r   r;   r<   r   r   r   as_form_xobject   s     zPdfContent.as_form_xobjectc                 C   s
   || _ dS )z
        Override the currently registered writer object.

        :param writer:
            An instance of :class:`~.writer.BasePdfFileWriter`.
        N)r4   )r   r4   r   r   r   
set_writer   s    zPdfContent.set_writer)NNN)r   r   r   r   r4   r   r	   r    r   r   r   r7   r8   propertyr1   bytesr:   r   r?   r@   r   r   r   r   r      s"   		    
c                       s:   e Zd ZdZd	eeed fddZedddZ  Z	S )
r   z,Raw byte sequence to be used as PDF content.N)datar1   r2   c                    s   t  || || _d S r   )superr    rC   )r   rC   r1   r2   	__class__r   r   r       s    zRawContent.__init__r&   c                 C   s   | j S r   )rC   r   r   r   r   r:      s    zRawContent.render)NN)
r   r   r   r   rB   r   r	   r    r:   __classcell__r   r   rE   r   r      s     c                       s0   e Zd ZdZd fdd	ZedddZ  ZS )	r   z,Import a page from another PDF file (lazily)r   c                    s   || _ || _t   d S r   )	file_namepage_ixrD   r    )r   rH   rI   rE   r   r   r      s    zImportedPdfPage.__init__r&   c              	   C   s   ddl m} | j }t| jd}t|}|j|| jd}W 5 Q R X dtt	
 j }|| jj|d< | d \}}}	}
tt||	 t||
 d| _|d	 S )
Nr   )BasePdfFileWriterrb)rI   s   /Importasciiz/BBox)r=   r>   s    Do)r4   rJ   openrH   r
   Zimport_page_as_xobjectrI   binasciihexlifyuuidZuuid4rB   r1   r   decodeZ
get_objectr	   absr2   )r   rJ   winfrZxobjresource_namex1y1Zx2y2r   r   r   r:     s    zImportedPdfPage.render)r   )r   r   r   r   r    rB   r:   rG   r   r   rE   r   r     s   )rN   rP   enumr   Zgenericr   r   r   r   r   Zlayoutr	   readerr
   __all__r   
ValueErrorr   r   r   r   r   r   r   r   r   r   <module>   s&       	2
;b