3
WZ                 @   s(  d Z ddlmZmZ ddlZddlZddlZddlZddl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 dd
lmZ ddlmZ ddlmZ ddlmZmZ ddlmZ ddlmZm Z m!Z! dd Z"dd Z#G dd de$Z%dd Z&G dd de'Z(G dd de'Z)G dd de'Z*dS )z
    weasyprint.document
    -------------------

    :copyright: Copyright 2011-2014 Simon Sapin and contributors, see AUTHORS.
    :license: BSD, see LICENSE for details.

    )divisionunicode_literalsN   )CSS)images)LOGGER)get_all_computed_styles)boxes)build_formatting_structure)layout_document)
percentage)	draw_pagestacked)write_pdf_metadata)izip	iteritemsFILESYSTEM_ENCODINGc       
      C   sP  | j jot| tj rL| j }| j }| j j\}}| j t	|| }| j
 t	|| }tj }|j|| x| j jD ]\}}|dkr|j|  qv|dkr|j| qv|dkr|\}}	|jt	||t	|	| qv|dkrddtj|dddf}n0|dkrdtj|ddddf}n|dks ttj| | }qvW |j| |  || _|S d	S )
z}Return the matrix for the CSS transforms on this box.

    :returns: a :class:`cairocffi.Matrix` object or :obj:`None`.

    scalerotate	translateZskewxr   r   ZskewymatrixN)style	transform
isinstancer	   Z	InlineBoxborder_widthborder_heightZtransform_originZborder_box_xr   Zborder_box_ycairoZMatrixr   r   r   mathtanAssertionErrorZtransformation_matrix)
boxr   r   Zorigin_xZorigin_yr   nameargsZtranslate_xZtranslate_y r#   S/var/www/html/enquirykeeper_venv/lib/python3.6/site-packages/weasyprint/document.py_get_matrix!   s6    

r%   c             C   s   | j }|||\}}||| |\}}	|||| \}
}||| || \}}t|||
|}t||	||}t|||
|}t||	||}|||| || fS )zApply a transformation matrix to an axis-aligned rectangle
    and return its axis-aligned bounding box as ``(x, y, width, height)``

    )transform_pointminmax)r   pos_xpos_ywidthheightr&   x1y1Zx2y2Zx3Zy3Zx4Zy4Zbox_x1Zbox_y1Zbox_x2Zbox_y2r#   r#   r$   rectangle_aabbL   s    r0   c               @   s   e Zd ZdZdS )_TaggedTuplez|A tuple with a :attr:`sourceline` attribute,
    The line number in the HTML source for whatever the tuple represents.

    N)__name__
__module____qualname____doc__r#   r#   r#   r$   r1   ]   s   r1   c          	   C   s  t | }|r|r|| n|}| jj}| jjdkr6d }n| jj}| jj}| jj}	|oT|}
|oft| tj }|	or|	|k}t	| do| j
}|
s|s|rz| j \}}}}|r,|\}}t|tr|j|jdrtnd}|dkr|rd}|rt||t|||||f}nt||||||ff}| j|_|j| |rN|
s>|rN|j||\}}|
rh|j||||ff |rz||f||	< x"| j D ]}t||||| qW d S )NZnoneis_attachmentzfile:zutf-8Zexternal
attachment)r%   r   bookmark_labelbookmark_levellinkanchorr   r	   ZTextBoxhasattrr6   Zhit_areabytesdecode
startswithr   r1   r0   
sourcelineappendr&   Zall_children_gather_links_and_bookmarks)r    	bookmarkslinksanchorsr   r   r8   r9   r:   anchor_nameZhas_bookmarkZhas_linkZ
has_anchorr6   r)   r*   r+   r,   	link_typetargetchildr#   r#   r$   rB   d   sN    

rB   c               @   s$   e Zd ZdZd
ddZdddZd	S )PagezRepresents a single rendered page.

    .. versionadded:: 0.15

    Should be obtained from :attr:`Document.pages` but not
    instantiated directly.

    Fc             C   sT   |j  | _|j | _g  | _}g  | _}i  | _}t||||d d || _|| _	d S )N)r   )
Zmargin_widthr+   Zmargin_heightr,   rC   rD   rE   rB   	_page_box_enable_hinting)selfZpage_boxenable_hintingrC   rD   rE   r#   r#   r$   __init__   s    




zPage.__init__r   r   c             C   s   t | | jr@|j||\}}t|}t|}|j||\}}|j|| |j|| |r| j}| j}| jr|j	||\}}tt
j|}tt
j|}|j||\}}|jdd|| |j  t| j|| j W dQ R X dS )am  Paint the page in cairo, on any type of surface.

        :param cairo_context:
            Any :class:`cairocffi.Context` object.

            .. note::

                In case you get a :class:`cairo.Context` object
                (eg. form PyGTK),
                it is possible to :ref:`convert it to cairocffi
                <converting_pycairo>`.
        :param left_x:
            X coordinate of the left of the page, in cairo user units.
        :param top_y:
            Y coordinate of the top of the page, in cairo user units.
        :param scale:
            Zoom scale in cairo user units per CSS pixel.
        :param clip:
            Whether to clip/cut content outside the page. If false or
            not provided, content can overflow.
        :type left_x: float
        :type top_y: float
        :type scale: float
        :type clip: bool

        r   N)r   rL   Zuser_to_deviceintZdevice_to_userr   r   r+   r,   Zuser_to_device_distancer   ceilZdevice_to_user_distance	rectangleclipr   rK   )rM   Zcairo_contextZleft_xZtop_yr   rS   r+   r,   r#   r#   r$   paint   s&    
z
Page.paintN)F)r   r   r   F)r2   r3   r4   r5   rO   rT   r#   r#   r#   r$   rJ      s   
%rJ   c               @   s   e Zd ZdZdddZdS )DocumentMetadatau	  Contains meta-information about a :class:`Document`
    that do not belong to specific pages but to the whole document.

    New attributes may be added in future versions of WeasyPrint.

    .. _W3C’s profile of ISO 8601: http://www.w3.org/TR/NOTE-datetime

    Nc	       	      C   s@   || _ |pg | _|| _|pg | _|| _|| _|| _|p8g | _d S )N)titleauthorsdescriptionkeywords	generatorcreatedmodifiedattachments)	rM   rV   rW   rX   rY   rZ   r[   r\   r]   r#   r#   r$   rO     s    

zDocumentMetadata.__init__)NNNNNNNN)r2   r3   r4   r5   rO   r#   r#   r#   r$   rU      s     rU   c               @   s\   e Zd ZdZedd Zdd ZdddZd	d
 Zdd Z	dddZ
dddZdddZdS )DocumentaS  A rendered document, with access to individual pages
    ready to be painted on any cairo surfaces.

    Typically obtained from :meth:`HTML.render() <weasyprint.HTML.render>`,
    but can also be instantiated directly
    with a list of :class:`pages <Page>`,
    a set of :class:`metadata <DocumentMetadata>` and a ``url_fetcher``.

    c                sn   t fdd|pg D d}tjtji j}t ||tj||}|  fdd|D t	f j
 jS )Nc                s(   g | ] }t |d r|nt| jdqS )Zrules)Zguess
media_type)r<   r   r_   ).0css)htmlr#   r$   
<listcomp>>  s   z$Document._render.<locals>.<listcomp>)Zuser_stylesheetsc                s   g | ]}t | qS r#   )rJ   )r`   p)rN   r#   r$   rc   G  s    )r   	functoolspartialr   get_image_from_uriurl_fetcherr   r
   Zroot_elementrU   _get_metadata)clsrb   ZstylesheetsrN   Z	style_forrg   Z
page_boxesr#   )rN   rb   r$   _render;  s    
zDocument._renderc             C   s   || _ || _|| _d S )N)pagesmetadatarh   )rM   rl   rm   rh   r#   r#   r$   rO   J  s    zDocument.__init__allc             C   s6   |dkr| j }nt|ts"t|}t| || j| jS )a  Take a subset of the pages.

        :param pages:
            An iterable of :class:`Page` objects from :attr:`pages`.
        :return:
            A new :class:`Document` object.

        Examples:

        Write two PDF files for odd-numbered and even-numbered pages::

            # Python lists count from 0 but pages are numbered from 1.
            # [::2] is a slice of even list indexes but odd-numbered pages.
            document.copy(document.pages[::2]).write_pdf('odd_pages.pdf')
            document.copy(document.pages[1::2]).write_pdf('even_pages.pdf')

        Write each page to a numbred PNG file::

            for i, page in enumerate(document.pages):
                document.copy(page).write_png('page_%s.png' % i)

        Combine multiple documents into one PDF file,
        using metadata from the first::

            all_pages = [p for p in doc.pages for doc in documents]
            documents[0].copy(all_pages).write_pdf('combined.pdf')

        rn   )rl   r   listtyperm   rh   )rM   rl   r#   r#   r$   copyU  s
    
zDocument.copyc             c   s   i }xDt | jD ]6\}}x,t|jD ]\}\}}|j||||f q$W qW x~| jD ]t}g }xd|jD ]Z}|\}	}}
|	dkr|j|}|dkrtjd||j	f  q|j
|	||
f qb|j
| qbW |V  qRW dS )a  Resolve internal hyperlinks.

        Links to a missing anchor are removed with a warning.
        If multiple anchors have the same name, the first is used.

        :returns:
            A generator yielding lists (one per page) like :attr:`Page.links`,
            except that :obj:`target` for internal hyperlinks is
            ``(page_number, x, y)`` instead of an anchor name.
            The page number is an index (0-based) in the :attr:`pages` list,
            ``x, y`` are in CSS pixels from the top-left of the page.

        ZinternalNz3No anchor #%s for internal URI reference at line %s)	enumeraterl   r   rE   
setdefaultrD   getr   warningr@   rA   )rM   rE   ipagerF   point_xpoint_yZ
page_linksr:   rG   rR   rH   r#   r#   r$   resolve_linksx  s"    

zDocument.resolve_linksc             C   s  g }g }|g}d}xt | jD ]\}}x|jD ]\}}\}	}
||krX|j|| d  n<|}x||k rx|d|j  7 }q^W ||kr|j|| d  |}|t| }|t|kst|dkstg }|||	|
f|f}||d  j| ||d= |j| q.W qW |S )ab  Make a tree of all bookmarks in the document.

        :return: a list of bookmark subtrees.
            A subtree is ``(label, target, children)``. :obj:`label` is
            a string, :obj:`target` is ``(page_number, x, y)`` like in
            :meth:`resolve_links`, and :obj:`children` is itself a (recursive)
            list of subtrees.

        r   r   N)rr   rl   rC   rA   popsumlenr   )rM   rootZskipped_levelsZlast_by_depthZprevious_levelZpage_numberrw   levellabelrx   ry   tempdepthchildrenZsubtreer#   r#   r$   make_bookmark_tree  s.    


zDocument.make_bookmark_treeNr   c       
   
   C   s   |d }t j }tj|dd}tj|}xH| jD ]>}|jtj|j	| tj|j
|  |j||d |j  q0W |j  t| ||| j|| j |dkr|j S |jd t|drtj|| n"t|d}	tj||	 W dQ R X dS )u  Paint the pages in a PDF file, with meta-data.

        PDF files written directly by cairo do not have meta-data such as
        bookmarks/outlines and hyperlinks.

        :param target:
            A filename, file-like object, or :obj:`None`.
        :type zoom: float
        :param zoom:
            The zoom factor in PDF units per CSS units.
            **Warning**: All CSS units (even physical, like ``cm``)
            are affected.
            For values other than 1, physical CSS units will thus be “wrong”.
            Page size declarations are affected too, even with keyword values
            like ``@page { size: A3 landscape; }``
        :param attachments: A list of additional file attachments for the
            generated PDF document or :obj:`None`. The list's elements are
            :class:`Attachment` objects, filenames, URLs or file-like objects.
        :returns:
            The PDF as byte string if :obj:`target` is :obj:`None`, otherwise
            :obj:`None` (the PDF is written to :obj:`target`.)

        g      ?r   )r   Nr   writewb)ioBytesIOr   Z
PDFSurfaceContextrl   Zset_sizer   floorr+   r,   rT   Z	show_pagefinishr   rm   rh   getvalueseekr<   shutilcopyfileobjopen)
rM   rH   Zzoomr]   r   Zfile_objsurfacecontextrw   fdr#   r#   r$   	write_pdf  s(    


zDocument.write_pdf`   c                s   |d   fdd| j D } fdd| j D }t|}t|}tjtj||}tj|}d}xDt| j ||D ]2\}	}
}||
 d }|	j||| dd ||7 }qnW |||fS )	Nr   c                s    g | ]}t tj|j  qS r#   )rP   r   rQ   r+   )r`   rd   )dppxr#   r$   rc     s    z0Document.write_image_surface.<locals>.<listcomp>c                s    g | ]}t tj|j  qS r#   )rP   r   rQ   r,   )r`   rd   )r   r#   r$   rc     s    r      T)r   rS   )	rl   r(   r|   r   ZImageSurfaceZFORMAT_ARGB32r   r   rT   )rM   
resolutionZwidthsZheights	max_widthsum_heightsr   r   r*   rw   r+   r,   r)   r#   )r   r$   write_image_surface  s    
zDocument.write_image_surfacec             C   sL   | j |\}}}|dkr4tj }|j| |j }n|j| d}|||fS )a  Paint the pages vertically to a single PNG image.

        There is no decoration around pages other than those specified in CSS
        with ``@page`` rules. The final image is as wide as the widest page.
        Each page is below the previous one, centered horizontally.

        :param target:
            A filename, file-like object, or :obj:`None`.
        :type resolution: float
        :param resolution:
            The output resolution in PNG pixels per CSS inch. At 96 dpi
            (the default), PNG pixels match the CSS ``px`` unit.
        :returns:
            A ``(png_bytes, png_width, png_height)`` tuple. :obj:`png_bytes`
            is a byte string if :obj:`target` is :obj:`None`, otherwise
            :obj:`None` (the image is written to :obj:`target`.)
            :obj:`png_width` and :obj:`png_height` are the size of the
            final image, in PNG pixels.

        N)r   r   r   Zwrite_to_pngr   )rM   rH   r   r   r   r   Z	png_bytesr#   r#   r$   	write_png  s    


zDocument.write_png)rn   )Nr   N)r   )Nr   )r2   r3   r4   r5   classmethodrk   rO   rq   rz   r   r   r   r   r#   r#   r#   r$   r^   1  s   	
##-
5
r^   )+r5   
__future__r   r   r   r   r   re   Z	cairocffir    r   r   loggerr   ra   r   Zformatting_structurer	   Zformatting_structure.buildr
   Zlayoutr   Zlayout.backgroundsr   Zdrawr   r   Zpdfr   compatr   r   r   r%   r0   tupler1   rB   objectrJ   rU   r^   r#   r#   r#   r$   <module>	   s0   +4d5