o
    git                     @   st   d Z ddlZddlm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 G dd	 d	ejZG d
d dZdS )z
This file contains all the classes needed to perform layout.
This includes an Alignment Enum type, and the base implementation of LayoutElement
    N)Decimal)Color)HexColor)	Rectangle)BlobFactoryc                   @   s,   e Zd ZdZdZdZdZdZdZdZ	dZ
d	S )
	Alignmenta  
    In typesetting and page layout, alignment or range is the setting of text flow or image placement relative to a page,
    column (measure), table cell, or tab.
    The type alignment setting is sometimes referred to as text alignment,
    text justification, or type justification.
    The edge of a page or column is known as a margin, and a gap between columns is known as a gutter.
                         N)__name__
__module____qualname____doc__LEFTCENTEREDRIGHT	JUSTIFIEDTOPMIDDLEBOTTOM r   r   Y/home/ubuntu/.local/lib/python3.10/site-packages/borb/pdf/canvas/layout/layout_element.pyr      s    r   c                3   @   s  e Zd ZdZddeddededededddeddeddejededededededededdejfd	e	j
e d
edededededededededede	jdef dede	j
e dede	j
e de	j
e de	j
e de	j
e dededed ed!e	j
d  d"ef2d#d$Zd%ed&e	je	j
e	jeef   fd'd(Zd)ed&efd*d+Zd,d-d&efd.d/Zd0d-d1efd2d3Zd0d-d%efd4d5Zd0d-d6ed&dfd7d8Zd&efd9d:Zd&e	j
e fd;d<Zd&e	j
e fd=d>Zd&e	j
e fd?d@Zd)efdAdBZd&efdCdDZd&efdEdFZd&efdGdHZ d&efdIdJZ!d&e	j
e fdKdLZ"d&e	j
e fdMdNZ#d&e	j
e fdOdPZ$d0d-d)ed&dfdQdRZ%dS )SLayoutElementz
    This class contains the common base methods for any object that can be laid out on a Page.
    e.g. the placement of borders, margins, padding, background color, etc
    NF000000r      	Helveticaz#000000background_colorborder_bottomborder_colorborder_leftborder_radius_bottom_leftborder_radius_bottom_rightborder_radius_top_leftborder_radius_top_rightborder_right
border_topborder_widthfontFont
font_color	font_sizehorizontal_alignmentmargin_bottommargin_leftmargin_right
margin_toppadding_bottompadding_leftpadding_rightpadding_topparentvertical_alignmentc                 C   s  || _ |
| _|	| _|| _|| _|dksJ d|dksJ d|dks'J d|dks/J d|| _|| _|| _|| _|dksAJ || _	|| _
|| _|| _|| _|d u sZ|dksZJ |d u sd|dksdJ |d u sn|dksnJ |d u sx|dksxJ || _|| _|| _|| _|dksJ |dksJ |dksJ |dksJ || _|| _|| _|| _|tjtjtjtjfv sJ |tjtjtjfv sJ || _|| _d | _ d | _!|| _"d S )Nr   z6border_radius_top_right must be a non-negative integerz5border_radius_top_left must be a non-negative integerz8border_radius_bottom_left must be a non-negative integerz9border_radius_bottom_right must be a non-negative integer)#_background_color_border_top_border_right_border_bottom_border_left_border_radius_top_left_border_radius_top_right_border_radius_bottom_right_border_radius_bottom_left_border_width_border_color_font_font_color
_font_size_margin_top_margin_right_margin_bottom_margin_left_padding_top_padding_right_padding_bottom_padding_leftr   r   r   r   r   r   r   r   _horizontal_alignment_vertical_alignment_previous_layout_box_previous_paint_box_parent)selfr    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r   r   r   __init__/   sn   





zLayoutElement.__init__
border_boxreturnc                 C   sj  d}t | |}t | |}t | |  |}t | |  |}g }| jrV| jrV| jdkrV|||| j fgt	||| j f||f|| j |fgdd d  7 }| jro| jdkro|||| j fg7 }|||fg7 }| jr| jdkr||| j |fg7 }| jr||| j
 |fg7 }n|d g7 }| jr| jr| j
dkr|t	|| j
 |f||f||| j
 fgdd d 7 }| jr| j
dkr|||fg7 }| jr| j
dkr|||| j
 fg7 }| jr|||| j fg7 }n|d g7 }| jr| jr| jdkr|t	||| j f||f|| j |fgdd d 7 }| jr(| jdkr(|||fg7 }| jr<| jdkr<||| j |fg7 }| jrK||| j |fg7 }n|d g7 }| jry| jry| jdkry|t	|| j |f||f||| j fgdd d 7 }| jr| jdkr|||fg7 }| jr| jdkr|||| j fg7 }| jr|||| j fg7 }|S |d g7 }|S )Nr   r   i)roundget_xget_y	get_width
get_heightr;   r>   r?   r   smooth_closed_polygonr@   r<   rA   r=   rB   )rU   rW   nxllyllxuryurpointsr   r   r   _get_border_outline   s   




z!LayoutElement._get_border_outlineavailable_spacec                 C   s&   t | | |  tdtdS )Nr   )r   rZ   r[   r]   r   )rU   rf   r   r   r   _get_content_box  s   zLayoutElement._get_content_boxpPagec                 C   s8   |  }|du r
dS |  }|du rdS | dv S )z
        This function returns whether this LayoutElement needs to be tagged
        :param p:   the Page on which this LayoutElement is to be painted
        :return:    true if this LayoutElement needs to be tagged, False otherwise
        NF)AU)get_documentget_document_info!get_conformance_level_upon_createget_conformance_level)rU   rh   documentconformance_levelr   r   r   _needs_to_be_tagged  s   z!LayoutElement._needs_to_be_taggedpagebackground_boxc                 C   s  | j sd S | j s
J | j  }| jdkrl| jdkrl| jdkrl| jdkrldt|jt|jt|j	|
 | |  |
 |  | |  |
 |  | |
 | |
 | |  f }|| d S | j| j| j| jg}d| _d| _d| _d| _| |}|d d usJ |d | _|d | _|d | _|d | _dt|jt|jt|j	t|d d t|d d f }|D ]}|d usJ |dt|d t|d f 7 }q|d	7 }|| d S )
Nr   z
                q %f %f %f rg %f %f m
                %f %f l
                %f %f l
                %f %f l
                %f %f l
                f
                Q
                Tr   r   r	   z/
            q %f %f %f rg %f %f m
            z %f %f lz f Q)r:   to_rgbr@   r?   rB   rA   floatredgreenbluerZ   r[   r]   r\   append_to_content_streamr;   r<   r=   r>   re   )rU   rs   rt   	rgb_colorcontentbeforeoutline_pointsrh   r   r   r   _paint_background$  sl   





	





	"zLayoutElement._paint_backgroundc           
   	   C   s  | j | j  kr| j  kr| j  krdkrd S  | jdkr!d S | j }dt|jt|j	t|j
t| jf }| |}t|d d D ]/\}}|}||d  }	|d u s[|	d u r\qG|dt|d t|d t|	d t|	d f 7 }qG|d7 }|| d S )NFr   zq %f %f %f RG %f w r   z %d %d m %d %d l sz Q)r;   r<   r=   r>   rC   rD   ru   rv   rw   rx   ry   re   	enumeraterz   )
rU   rs   rW   r{   r|   rd   irh   p0p1r   r   r   _paint_borders{  sD   
	






zLayoutElement._paint_borderscontent_boxc                 C   s   d S )Nr   )rU   rs   r   r   r   r   _paint_content_box  s   z LayoutElement._paint_content_boxc                 C      | j ptdS )zK
        This function returns the font size of this LayoutElement
        r   )rG   r   rU   r   r   r   get_font_size     zLayoutElement.get_font_sizec              	   C   s   t d}t d| }d}tdddD ]U}zN| tt dt dt |t || }| |kr1W q|du r9|}W q| |  }| |  }t|| t|| k rY|}W q||kraW  |S W q   Y q|S )a	  
        This function returns the layout box that fits this LayoutElement
        and whose ratio of dimensions (width / height) are closest to the golden ratio.
        :return:    the layout box (in landscape mode) with ratio closest to the golden ratio
        S?r   Nr      
   )r   rangeget_layout_boxr   r\   r]   abs)rU   GOLDEN_RATIOINVERSE_GOLDEN_RATIObest_landscape_boxwlandscape_boxratio
best_ratior   r   r   get_golden_ratio_landscape_box  s>   
z,LayoutElement.get_golden_ratio_landscape_boxc              	   C   s   t d}t d| }d}tdddD ]U}zN| tt dt dt || t |}| |kr1W q|du r9|}W q| |  }| |  }t|| t|| k rY|}W q||k raW  |S W q   Y q|S )a  
        This function returns the layout box that fits this LayoutElement
        and whose ratio of dimensions (height / width) are closest to the golden ratio.
        :return:    the layout box (in portrait mode) with ratio closest to the golden ratio
        r   r   Nr   r   r   )r   r   r   r   r]   r\   r   )rU   r   r   best_portrait_boxhportrait_boxr   r   r   r   r   get_golden_ratio_portrait_box  s>   
z+LayoutElement.get_golden_ratio_portrait_boxc                 C   s4   z|  ttdtdtdtdW S    Y dS )a%  
        This function returns the largest (in landscape mode) box that will fit this LayoutElement.
        For most (all) LayoutElements, this also ought to be the layout box with the smallest height, and largest width.
        :return:    the largest layout box (in landscape mode)
        r   r   N)r   r   r   r   r   r   r   get_largest_landscape_box$  s   z'LayoutElement.get_largest_landscape_boxc                 C   s"  t d}| jr|| j7 }| jr|| j7 }t d}| jr || j7 }| jr(|| j7 }t| | j | jr5| jnt d |	 | j
 | jrE| jnt d tt d| | j | j | tt d| | j | j
 | }| |}t d}t d}| jtjkr| |  t d }| j|8  _| jtjkr| |  }| j|8  _| jtjkr| |  t d }| j|7  _| jtjkr| |  }| j|7  _t| | j | jr| jnt d |	 | j
 | jr| jnt d | | j | j | | | j | j
 | | _| jS )z
        This function returns the previous result of layout
        :return:    the Rectangle that was the result of the previous layout operation
        r   r   )r   r>   rC   r<   r;   r=   r   rZ   rO   r[   rN   maxr\   rM   r]   rL   rg   rQ   r   r   yr   rP   r   xr   rR   )rU   rf   horizontal_border_widthvertical_border_widthcbox_available_spacecboxdelta_xdelta_yr   r   r   r   1  s   




  zLayoutElement.get_layout_boxc                 C   r   )zO
        This function returns the bottom margin of this LayoutElement
        r   )rJ   r   r   r   r   r   get_margin_bottom{  r   zLayoutElement.get_margin_bottomc                 C   r   )zM
        This function returns the left margin of this LayoutElement
        r   )rK   r   r   r   r   r   get_margin_left  r   zLayoutElement.get_margin_leftc                 C   r   )zN
        This function returns the right margin of this LayoutElement
        r   )rI   r   r   r   r   r   get_margin_right  r   zLayoutElement.get_margin_rightc                 C   r   )zL
        This function returns the top margin of this LayoutElement
        r   )rH   r   r   r   r   r   get_margin_top  r   zLayoutElement.get_margin_topc                 C      | j S )z
        This function returns the previous result of layout of this LayoutElement
        :return:    the Rectangle that was the result of the previous layout operation
        )rR   r   r   r   r   get_previous_layout_box     z%LayoutElement.get_previous_layout_boxc                 C   r   )z
        This function returns the previous result of painting this LayoutElement
        :return:    the Rectangle that was the result of the previous paint operation
        )rS   r   r   r   r   get_previous_paint_box  r   z$LayoutElement.get_previous_paint_boxc                 C   s   t d}t d}|| t d }d}t|| t dkrXz+| tt dt d|t d}|dus3J | |kr<|}n|}|| t d }W n   Y |S t|| t dks|S )a'  
        This function returns the smallest (in landscape mode) box that will fit this LayoutElement.
        For most (all) LayoutElements, this also ought to be the layout box with the smallest width, and largest height.
        :return:    the smallest layout box (in landscape mode)
        r   r   r   Nr   )r   r   r   r   r\   )rU   	max_width	min_widthmidpoint_widthr   r   r   r   get_smallest_landscape_box  s&   z(LayoutElement.get_smallest_landscape_boxc           
      C   s  t d}| jr|| j7 }| jr|| j7 }t d}| jr || j7 }| jr(|| j7 }t| | j | jr5| jnt d |	 | j
 | jrE| jnt d tt d| | j | j | tt d| | j | j
 | }| |}t| dt| dkrJ | jj dt| d dt| d dt| dt| dkr| | J | jj dt| d dt| d dt d}t d}| jtjkr| |  t d }| j|8  _| jtjkr| |  }| j|8  _| jtjkr| |  t d }| j|7  _| jtjkr)| |  }| j|7  _t| | j | jr7| jnt d |	 | j
 | jrH| jnt d | | j | j | | | j | j
 | }	| ||	 | ||	 | || |	| _ dS )	aJ  
        This method paints this LayoutElement on the given Page, in the available space
        :param page:                the Page on which to paint this LayoutElement
        :param available_space:     the available space (as a Rectangle) on which to paint this LayoutElement
        :return:                    None
        r   r   Fz1 is too tall to fit inside column / page. Needed z pts, only z pts available.z1 is too wide to fit inside column / page. Needed N)!r   r>   rC   r<   r;   r=   r   rZ   rO   r[   rN   r   r\   rM   r]   rL   rg   rY   	__class__r   rQ   r   r   r   r   rP   r   r   r   r   r   r   rS   )
rU   rs   rf   r   r   r   r   r   r   bgboxr   r   r   paint  s`   	



    
	2
2""
zLayoutElement.paint)&r   r   r   r   r   r   r   r   r   typingOptionalr   boolUnionstrrV   r   ListTuplere   rg   rr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   %   s    	

k
r
W(::Jr   )r   r   decimalr   enumborb.pdf.canvas.color.colorr   r   "borb.pdf.canvas.geometry.rectangler   %borb.pdf.canvas.line_art.blob_factoryr   Enumr   r   r   r   r   r   <module>   s   