3
ڸW<S                 @   s  d Z ddlmZmZ ddlZddlmZmZ ddlm	Z	 G dd de
ZG d	d
 d
eZG dd deZG dd deZG dd deeZG dd deZG dd deZG dd deeZG dd deZG dd deZG dd deeZG dd deZG dd  d eeZG d!d" d"eeZG d#d$ d$eeZG d%d& d&eZG d'd( d(eZG d)d* d*eZG d+d, d,eZG d-d. d.eZG d/d0 d0eZG d1d2 d2eZ G d3d4 d4eZ!G d5d6 d6eZ"dS )7a/  
    weasyprint.formatting_structure.boxes
    -------------------------------------

    Classes for all types of boxes in the CSS formatting structure / box model.

    See http://www.w3.org/TR/CSS21/visuren.html

    Names are the same as in CSS 2.1 with the exception of ``TextBox``. In
    WeasyPrint, any text is in a ``TextBox``. What CSS calls anonymous
    inline boxes are text boxes but not all text boxes are anonymous
    inline boxes.

    See http://www.w3.org/TR/CSS21/visuren.html#anonymous

    Abstract classes, should not be instantiated:

    * Box
    * BlockLevelBox
    * InlineLevelBox
    * BlockContainerBox
    * ReplacedBox
    * ParentBox
    * AtomicInlineLevelBox

    Concrete classes:

    * PageBox
    * BlockBox
    * InlineBox
    * InlineBlockBox
    * BlockReplacedBox
    * InlineReplacedBox
    * TextBox
    * LineBox
    * Various table-related Box subclasses

    All concrete box classes whose name contains "Inline" or "Block" have
    one of the following "outside" behavior:

    * Block-level (inherits from :class:`BlockLevelBox`)
    * Inline-level (inherits from :class:`InlineLevelBox`)

    and one of the following "inside" behavior:

    * Block container (inherits from :class:`BlockContainerBox`)
    * Inline content (InlineBox and :class:`TextBox`)
    * Replaced content (inherits from :class:`ReplacedBox`)

    ... with various combinasions of both.

    See respective docstrings for details.

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

    )divisionunicode_literalsN   )unichrxrange)ZERO_PIXELSc               @   s  e Zd ZdZdZdZdZdZdZdZ	dd Z
dd Zdd	 Zed
d Zdd Zd;ddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Z d1d2 Z!d3d4 Z"d5d6 Z#d7d8 Z$d9d: Z%dS )<Boxz"Abstract base class for all boxes.FNc             C   s   f S )N )selfr	   r	   e/var/www/html/enquirykeeper_venv/lib/python3.6/site-packages/weasyprint/formatting_structure/boxes.pyall_childrenU   s    zBox.all_childrenc             C   s   || _ || _|j | _d S )N)element_tag
sourcelinecopystyle)r
   r   r   r   r	   r	   r   __init__X   s    zBox.__init__c             C   s   dt | j| j| jf S )Nz
<%s %s %s>)type__name__r   r   )r
   r	   r	   r   __repr___   s    zBox.__repr__c             O   s   | |j |j|jj f||S )z6Return an anonymous box that inherits from ``parent``.)r   r   r   Zinherit_from)clsparentargskwargsr	   r	   r   anonymous_fromc   s    

zBox.anonymous_fromc             C   s0   t | }|j|}|jj| j | jj |_|S )zReturn shallow copy of the box.)r   __new____dict__updater   r   )r
   r   new_boxr	   r	   r   r   j   s
    
zBox.copyr   c             C   s>   |  j |7  _ |  j|7  _x| j D ]}|j|| q&W dS )uc   Change the box’s position.

        Also update the children’s positions accordingly.

        N)
position_x
position_yr   	translate)r
   dxdychildr	   r	   r   r    u   s    zBox.translatec             C   s   | j | j | j S )zWidth of the padding box.)widthpadding_leftpadding_right)r
   r	   r	   r   padding_width   s    zBox.padding_widthc             C   s   | j | j | j S )zHeight of the padding box.)heightpadding_toppadding_bottom)r
   r	   r	   r   padding_height   s    zBox.padding_heightc             C   s   | j  | j | j S )zWidth of the border box.)r'   border_left_widthborder_right_width)r
   r	   r	   r   border_width   s    zBox.border_widthc             C   s   | j  | j | j S )zHeight of the border box.)r+   border_top_widthborder_bottom_width)r
   r	   r	   r   border_height   s    zBox.border_heightc             C   s   | j  | j | j S )z)Width of the margin box (aka. outer box).)r.   margin_leftmargin_right)r
   r	   r	   r   margin_width   s    zBox.margin_widthc             C   s   | j  | j | j S )z*Height of the margin box (aka. outer box).)r1   
margin_topmargin_bottom)r
   r	   r	   r   margin_height   s    zBox.margin_heightc             C   s   | j | j | j | j S )z0Absolute horizontal position of the content box.)r   r2   r%   r,   )r
   r	   r	   r   content_box_x   s    zBox.content_box_xc             C   s   | j | j | j | j S )z.Absolute vertical position of the content box.)r   r5   r)   r/   )r
   r	   r	   r   content_box_y   s    zBox.content_box_yc             C   s   | j | j | j S )z0Absolute horizontal position of the padding box.)r   r2   r,   )r
   r	   r	   r   padding_box_x   s    zBox.padding_box_xc             C   s   | j | j | j S )z.Absolute vertical position of the padding box.)r   r5   r/   )r
   r	   r	   r   padding_box_y   s    zBox.padding_box_yc             C   s   | j | j S )z/Absolute horizontal position of the border box.)r   r2   )r
   r	   r	   r   border_box_x   s    zBox.border_box_xc             C   s   | j | j S )z-Absolute vertical position of the border box.)r   r5   )r
   r	   r	   r   border_box_y   s    zBox.border_box_yc             C   s   | j  | j | j | j fS )z=Return the (x, y, w, h) rectangle where the box is clickable.)r<   r=   r.   r1   )r
   r	   r	   r   hit_area   s    zBox.hit_areac          
   C   sT  | j \}}| j\}}| j\}	}
| j\}}td|| }td|| }td|| }td|| }td|	| }	td|
| }
td|| }td|| }| j | }| j | }| j | | }| j | | }t	dgdd ||| f|||	 f||| f|||
 fgD  }|||||| || f|| || f|	| |
| f|| || ffS )zPosition, size and radii of a box inside the outer border box.

        bt, br, bb, and bl are distances from the outer border box,
        defining a rectangle to be rounded.

        r      c             S   s    g | ]\}}|d kr|| qS )r   r	   ).0ZextentZ	sum_radiir	   r	   r   
<listcomp>   s   z#Box.rounded_box.<locals>.<listcomp>)
Zborder_top_left_radiusZborder_top_right_radiusZborder_bottom_right_radiusZborder_bottom_left_radiusmaxr<   r=   r.   r1   min)r
   ZbtbrZbbZblZtlrxZtlryZtrrxZtrryZbrrxZbrryZblrxZblryxyr$   r(   ratior	   r	   r   rounded_box   s6    






zBox.rounded_boxc             C   s(   | j | j| | j| | j| | j| S )N)rH   r/   r-   r0   r,   )r
   rG   r	   r	   r   rounded_box_ratio   s
    zBox.rounded_box_ratioc             C   s   | j | j| j| j| jS )z?Return the position, size and radii of the rounded padding box.)rH   r/   r-   r0   r,   )r
   r	   r	   r   rounded_padding_box   s
    zBox.rounded_padding_boxc             C   s   | j ddddS )z>Return the position, size and radii of the rounded border box.r   )rH   )r
   r	   r	   r   rounded_border_box   s    zBox.rounded_border_boxc             C   s0   | j | j| j | j| j | j| j | j| j S )z?Return the position, size and radii of the rounded content box.)	rH   r/   r)   r-   r&   r0   r*   r,   r%   )r
   r	   r	   r   rounded_content_box  s
    


zBox.rounded_content_boxc             C   s   | j jdkS )z#Return whether this box is floated.none)r   float)r
   r	   r	   r   
is_floated  s    zBox.is_floatedc             C   s   | j jdkS )z>Return whether this box is in the absolute positioning scheme.absolutefixed)rP   rQ   )r   position)r
   r	   r	   r   is_absolutely_positioned  s    zBox.is_absolutely_positionedc             C   s   | j  p| j  S )z*Return whether this box is in normal flow.)rO   rS   )r
   r	   r	   r   is_in_normal_flow  s    zBox.is_in_normal_flow)r   r   )&r   
__module____qualname____doc__proper_table_childinternal_table_or_captiontabular_containeris_table_wrapperZis_for_root_elementZtransformation_matrixr   r   r   classmethodr   r   r    r'   r+   r.   r1   r4   r7   r8   r9   r:   r;   r<   r=   r>   rH   rI   rJ   rK   rL   rO   rS   rT   r	   r	   r	   r   r   G   sD   
-
r   c                   s\   e Zd ZdZ fddZdd ZdddZd	d
 Zdd ZdddZ	dd Z
dd Z  ZS )	ParentBoxzA box that has children.c                s"   t t| j||| t|| _d S )N)superr]   r   tuplechildren)r
   r   r   r   r`   )	__class__r	   r   r     s    zParentBox.__init__c             C   s   | j S )N)r`   )r
   r	   r	   r   r     s    zParentBox.all_childrenr   c             c   s.   x(t |t| jD ]}|| j| fV  qW dS )zYield ``(child, child_index)`` tuples for each child.

        ``skip_num`` children are skipped before iterating over them.

        N)r   lenr`   )r
   Zskip_numindexr	   r	   r   enumerate_skip!  s    zParentBox.enumerate_skipc             C   s^   t | d| d t | d| d t | d| d t| jd| < t| jd| < d| jd| < dS )z4Set to 0 the margin, padding and border of ``side``.z	margin_%sr   z
padding_%szborder_%s_widthN)setattrr   r   )r
   Zsider	   r	   r   _reset_spacing*  s    zParentBox._reset_spacingc             C   s    |r| j d |r| j d d S )NtopZbottom)rf   )r
   startendr	   r	   r   _remove_decoration4  s    
zParentBox._remove_decorationTc             C   s0   | j  }t||_|sd|_|j| |  |S )z8Create a new equivalent box with given ``new_children``.N)r   r_   r`   outside_list_markerrj   )r
   Znew_childrenZis_startZis_endr   r	   r	   r   copy_with_children:  s    
zParentBox.copy_with_childrenc             c   sD   | V  x8| j D ].}t|dr6x|j D ]
}|V  q&W q|V  qW dS )z9A flat generator for a box, its children and descendants.descendantsN)r`   hasattrrm   )r
   r#   Zgrand_childr	   r	   r   rm   C  s    
zParentBox.descendantsc             C   s0   | j r,x$| jD ]}t|tr|S qW tddS )z!Get the table wrapped by the box.zTable wrapper without a tableN)r[   r`   
isinstanceTableBox
ValueError)r
   r#   r	   r	   r   get_wrapped_tableM  s
    
zParentBox.get_wrapped_table)r   )TT)r   rU   rV   rW   r   r   rd   rf   rj   rl   rm   rr   __classcell__r	   r	   )ra   r   r]     s   
	

	
r]   c               @   s   e Zd ZdZdZdS )BlockLevelBoxzA box that participates in an block formatting context.

    An element with a ``display`` value of ``block``, ``list-item`` or
    ``table`` generates a block-level box.

    N)r   rU   rV   rW   Z	clearancer	   r	   r	   r   rt   W  s   rt   c               @   s   e Zd ZdZdS )BlockContainerBoxaj  A box that contains only block-level boxes or only line boxes.

    A box that either contains only block-level boxes or establishes an inline
    formatting context and thus contains only line boxes.

    A non-replaced element with a ``display`` value of ``block``,
    ``list-item``, ``inline-block`` or 'table-cell' generates a block container
    box.

    N)r   rU   rV   rW   r	   r	   r	   r   ru   a  s   
ru   c               @   s   e Zd ZdZdd ZdS )BlockBoxzA block-level box that is also a block container.

    A non-replaced element with a ``display`` value of ``block``, ``list-item``
    generates a block box.

    c             C   s&   t | dd }|r tj| j|gS | jS )Nrk   )getattr	itertoolschainr`   )r
   markerr	   r	   r   r   v  s    zBlockBox.all_childrenN)r   rU   rV   rW   r   r	   r	   r	   r   rv   n  s   rv   c                   s    e Zd ZdZ fddZ  ZS )LineBoxaK  A box that represents a line in an inline formatting context.

    Can only contain inline-level boxes.

    In early stages of building the box tree a single line box contains many
    consecutive inline boxes. Later, during layout phase, each line boxes will
    be split into multiple line boxes, one for each actual line.

    c                s$   |j s
ttt| j|||| d S )N)	anonymousAssertionErrorr^   r{   r   )r
   r   r   r   r`   )ra   r	   r   r     s    
zLineBox.__init__)r   rU   rV   rW   r   rs   r	   r	   )ra   r   r{   |  s   	r{   c               @   s   e Zd ZdZdd ZdS )InlineLevelBoxaQ  A box that participates in an inline formatting context.

    An inline-level box that is not an inline box is said to be "atomic". Such
    boxes are inline blocks, replaced elements and inline tables.

    An element with a ``display`` value of ``inline``, ``inline-table``, or
    ``inline-block`` generates an inline-level box.

    c             C   s<   | j jdk}|r"| j|rdnd |r8| j|r2dnd d S )Nltrleftright)r   	directionrf   )r
   rh   ri   r   r	   r	   r   rj     s
    z!InlineLevelBox._remove_decorationN)r   rU   rV   rW   rj   r	   r	   r	   r   r~     s   	r~   c               @   s   e Zd ZdZdd ZdS )	InlineBoxa  An inline box with inline children.

    A box that participates in an inline formatting context and whose content
    also participates in that inline formatting context.

    A non-replaced element with a ``display`` value of ``inline`` generates an
    inline box.

    c             C   s   | j  | j| j | j fS )z=Return the (x, y, w, h) rectangle where the box is clickable.)r<   r   r.   r7   )r
   r	   r	   r   r>     s    
zInlineBox.hit_areaN)r   rU   rV   rW   r>   r	   r	   r	   r   r     s   	r   c                   sP   e Zd ZdZedd eddD Zejddd  fd	d
Zdd Z	  Z
S )TextBoxzA box that contains only text and has no box children.

    Any text in the document ends up in a text box. What CSS calls "anonymous
    inline boxes" are also text boxes.

    c             c   s   | ]}|t |d  fV  qdS )i  N)r   )r@   ir	   r	   r   	<genexpr>  s    zTextBox.<genexpr>!      u   　u   −)    -   c                s~   |j s
t|sttt j||| |j}|dkr^dd dd dd  fddd| |}|jdkrt|jdd	}| _d S )
NrM   c             S   s   | j  S )N)upper)tr	   r	   r   <lambda>  s    z"TextBox.__init__.<locals>.<lambda>c             S   s   | j  S )N)lower)r   r	   r	   r   r     s    c             S   s   | j  S )N)title)r   r	   r	   r   r     s    c                s   | j  jS )N)r    ascii_to_wide)r   )r
   r	   r   r     s    )Z	uppercaseZ	lowercase
capitalizez
full-width   ­ )	r|   r}   r^   r   r   text_transformZhyphensreplacetext)r
   r   r   r   r   r   )ra   )r
   r   r     s    


zTextBox.__init__c             C   s   |st | j }||_|S )z?Return a new TextBox identical to this one except for the text.)r}   r   r   )r
   r   r   r	   r	   r   copy_with_text  s    zTextBox.copy_with_text)r   rU   rV   rW   dictranger   r   r   r   rs   r	   r	   )ra   r   r     s
   r   c               @   s   e Zd ZdZdS )AtomicInlineLevelBoxzpAn atomic box in an inline formatting context.

    This inline-level box cannot be split for line breaks.

    N)r   rU   rV   rW   r	   r	   r	   r   r     s   r   c               @   s   e Zd ZdZdS )InlineBlockBoxzA box that is both inline-level and a block container.

    It behaves as inline on the outside and as a block on the inside.

    A non-replaced element with a 'display' value of 'inline-block' generates
    an inline-block box.

    N)r   rU   rV   rW   r	   r	   r	   r   r     s   r   c                   s    e Zd ZdZ fddZ  ZS )ReplacedBoxu   A box whose content is replaced.

    For example, ``<img>`` are replaced: their content is rendered externally
    and is opaque from CSS’s point of view.

    c                s   t t| j||| || _d S )N)r^   r   r   replacement)r
   r   r   r   r   )ra   r	   r   r     s    zReplacedBox.__init__)r   rU   rV   rW   r   rs   r	   r	   )ra   r   r     s   r   c               @   s   e Zd ZdZdS )BlockReplacedBoxzA box that is both replaced and block-level.

    A replaced element with a ``display`` value of ``block``, ``liste-item`` or
    ``table`` generates a block-level replaced box.

    N)r   rU   rV   rW   r	   r	   r	   r   r     s   r   c               @   s   e Zd ZdZdS )InlineReplacedBoxzA box that is both replaced and inline-level.

    A replaced element with a ``display`` value of ``inline``,
    ``inline-table``, or ``inline-block`` generates an inline-level replaced
    box.

    N)r   rU   rV   rW   r	   r	   r	   r   r     s   r   c                   s.   e Zd ZdZdZdd Zd fdd	Z  ZS )	rp   z(Box for elements with ``display: table``Tc             C   s   t j| j| jS )N)rx   ry   r`   Zcolumn_groups)r
   r	   r	   r   r   
  s    zTableBox.all_childrenr   c                s(    fdd| j D | _ tt| j |S )Nc                s   g | ]}|  qS r	   r	   )r@   rR   )r!   r	   r   rA     s    z&TableBox.translate.<locals>.<listcomp>)Zcolumn_positionsr^   rp   r    )r
   r!   r"   )ra   )r!   r   r      s    zTableBox.translate)r   r   )r   rU   rV   rW   rZ   r   r    rs   r	   r	   )ra   r   rp     s   rp   c               @   s   e Zd ZdZdS )InlineTableBoxz/Box for elements with ``display: inline-table``N)r   rU   rV   rW   r	   r	   r	   r   r     s   r   c               @   s,   e Zd ZdZdZdZdZeefZ	dZ
dZdS )TableRowGroupBoxz2Box for elements with ``display: table-row-group``TFN)r   rU   rV   rW   rX   rY   rZ   rp   r   proper_parentsZ	is_headerZ	is_footerr	   r	   r	   r   r     s   r   c               @   s&   e Zd ZdZdZdZdZeee	fZ
dS )TableRowBoxz,Box for elements with ``display: table-row``TN)r   rU   rV   rW   rX   rY   rZ   rp   r   r   r   r	   r	   r	   r   r   #  s
   r   c               @   sL   e Zd ZdZdZdZeefZdZ	dZ
dZdZdZdZdZdZdZdd ZdS )TableColumnGroupBoxz5Box for elements with ``display: table-column-group``Tr?   r   c             C   s   dd | j D S )z3Return cells that originate in the group's columns.c             S   s   g | ]}|j  D ]}|qqS r	   )	get_cells)r@   columncellr	   r	   r   rA   B  s    z1TableColumnGroupBox.get_cells.<locals>.<listcomp>)r`   )r
   r	   r	   r   r   ?  s    zTableColumnGroupBox.get_cellsN)r   rU   rV   rW   rX   rY   rp   r   r   spanr5   r6   r2   r3   r)   r*   r%   r&   r   r	   r	   r	   r   r   +  s   r   c               @   sN   e Zd ZdZdZdZeeefZ	dZ
dZdZdZdZdZdZdZdZdd ZdS )TableColumnBoxz/Box for elements with ``display: table-column``Tr?   r   c             C   s   g S )z\Return cells that originate in the column.

        May be overriden on instances.

        r	   )r
   r	   r	   r   r   Z  s    zTableColumnBox.get_cellsN)r   rU   rV   rW   rX   rY   rp   r   r   r   r   r5   r6   r2   r3   r)   r*   r%   r&   r   r	   r	   r	   r   r   F  s   
r   c               @   s   e Zd ZdZdZdZdZdS )TableCellBoxz-Box for elements with ``display: table-cell``Tr?   N)r   rU   rV   rW   rY   ZcolspanZrowspanr	   r	   r	   r   r   c  s   r   c               @   s    e Zd ZdZdZdZeefZdS )TableCaptionBoxz0Box for elements with ``display: table-caption``TN)	r   rU   rV   rW   rX   rY   rp   r   r   r	   r	   r	   r   r   l  s   r   c                   s(   e Zd ZdZ fddZdd Z  ZS )PageBoxzBox for a page.

    Initially the whole document will be in the box for the root element.
    During layout a new page box is created after every page break.

    c                s"   || _ tt| jd d |g d d S )N)r   r   r   r`   )	page_typer^   r   r   )r
   r   r   )ra   r	   r   r   z  s    
zPageBox.__init__c             C   s   dt | j| jf S )Nz<%s %s>)r   r   r   )r
   r	   r	   r   r     s    zPageBox.__repr__)r   rU   rV   rW   r   r   rs   r	   r	   )ra   r   r   s  s   r   c                   s,   e Zd ZdZg f fdd	Zdd Z  ZS )	MarginBoxz3Box in page margins, as defined in CSS3 Paged Mediac                s"   || _ tt| jd d ||d d S )N)r   r   r   r`   )
at_keywordr^   r   r   )r
   r   r   r`   )ra   r	   r   r     s    
zMarginBox.__init__c             C   s   dt | j| jf S )Nz<%s %s>)r   r   r   )r
   r	   r	   r   r     s    zMarginBox.__repr__)r   rU   rV   rW   r   r   rs   r	   r	   )ra   r   r     s   r   )#rW   
__future__r   r   rx   compatr   r   Zcss.computed_valuesr   objectr   r]   rt   ru   rv   r{   r~   r   r   r   r   r   r   r   rp   r   r   r   r   r   r   r   r   r   r	   r	   r	   r   <module>:   s:    R?
$	
	