U
    :vhl                     @   s   d dl mZmZ d dlmZ d dlmZmZ ddlm	Z	m
Z
mZmZmZmZmZmZmZ ddlmZ ddlmZmZ ddlmZ ed	d
ZG dd dZG dd dZeddG dd dZeddG dd dZeddG dd dZdddZdS )    )	dataclassreplace)Number)OptionalUnion   )	AlignMethodReturnValueTableBordersLayoutTableCellFillModeTableHeadingsDisplayWrapModeVAlign	TableSpanCellBordersLayout)FPDFException)
CORE_FONTSFontFace)PaddingZBOLD)emphasisc                   @   s   e Zd ZdZdddejdejddddeddd	de	j
ddd
d
ddddZdddZdd Zdd Zdd ZdddZdddZdd ZdS ) Tablez
    Object that `fpdf.FPDF.table()` yields, used to build a table in the document.
    Detailed usage documentation: https://py-pdf.github.io/fpdf2/Tables.html
     ZCENTERZMIDDLENTr   FZJUSTIFYr   )alignv_alignborders_layoutcell_fill_colorcell_fill_mode
col_widthsfirst_row_as_headingsgutter_heightgutter_widthheadings_styleline_heightmarkdown
text_alignwidthwrapmodepaddingouter_border_widthnum_heading_rowsrepeat_headingsmin_row_heightc                C   s  || _ t|| _t|| _t|| _|| _|| _	t
|| _|| _|	| _|
| _|| _|| _|dkrrd|j n|| _|| _|| _|| _|| _|| _t|| _|| _d| _g | _|dkrtd| _nt|| _| jtj tj!fkr|dk	rt"dd| _| jr"||d  |
|d  f| _#nd| _#| jdkrn| jdkrP| jrPt"d| jdkr|| js|t"dn| js|d| _|D ]}| $| qdS )	a.  
        Args:
            fpdf (fpdf.FPDF): FPDF current instance
            rows: optional. Sequence of rows (iterable) of str to initiate the table cells with text content
            align (str, fpdf.enums.Align): optional, default to CENTER. Sets the table horizontal position relative to the page,
                when it's not using the full page width
            borders_layout (str, fpdf.enums.TableBordersLayout): optional, default to ALL. Control what cell borders are drawn
            cell_fill_color (float, tuple, fpdf.drawing.DeviceGray, fpdf.drawing.DeviceRGB): optional.
                Defines the cells background color
            cell_fill_mode (str, fpdf.enums.TableCellFillMode): optional. Defines which cells are filled with color in the background
            col_widths (float, tuple): optional. Sets column width. Can be a single number or a sequence of numbers.
                 When `col_widths` is a single number, it is interpreted as a fixed column width in document units.
                 When `col_widths` is provided as an array, the values are considered to be fractions of the full effective page width,
                 meaning that `col_widths=(1, 1, 2)` is strictly equivalent to `col_widths=(25, 25, 50)`.
            first_row_as_headings (bool): optional, default to True. If False, the first row of the table
                is not styled differently from the others
            gutter_height (float): optional vertical space between rows
            gutter_width (float): optional horizontal space between columns
            headings_style (fpdf.fonts.FontFace): optional, default to bold.
                Defines the visual style of the top headings row: size, color, emphasis...
            line_height (number): optional. Defines how much vertical space a line of text will occupy
            markdown (bool): optional, default to False. Enable markdown interpretation of cells textual content
            text_align (str, fpdf.enums.Align, tuple): optional, default to JUSTIFY. Control text alignment inside cells.
            v_align (str, fpdf.enums.VAlign): optional, default to CENTER. Control vertical alignment of cells content
            width (number): optional. Sets the table width
            wrapmode (fpdf.enums.WrapMode): "WORD" for word based line wrapping (default),
                "CHAR" for character based line wrapping.
            padding (number, tuple, Padding): optional. Sets the cell padding. Can be a single number or a sequence of numbers, default:0
                If padding for left and right ends up being non-zero then c_margin is ignored.
            outer_border_width (number): optional. Sets the width of the outer borders of the table.
                Only relevant when borders_layout is ALL or NO_HORIZONTAL_LINES. Otherwise, the border widths are controlled by FPDF.set_line_width()
            num_heading_rows (number): optional. Sets the number of heading rows, default value is 1. If this value is not 1,
                first_row_as_headings needs to be True if num_heading_rows>1 and False if num_heading_rows=0. For backwards compatibility,
                first_row_as_headings is used in case num_heading_rows is 1.
            repeat_headings (fpdf.enums.TableHeadingsDisplay): optional, indicates whether to print table headings on every page, default to 1.
        N   r   zTouter_border_width is only allowed when borders_layout is ALL or NO_HORIZONTAL_LINES)r   r   r   z@first_row_as_headings needs to be False if num_heading_rows == 0z>first_row_as_headings needs to be True if num_heading_rows > 0)%_fpdfr   coerce_table_alignr   _v_alignr
   _borders_layout_outer_border_width_cell_fill_colorr   _cell_fill_mode_col_widthsZ_first_row_as_headings_gutter_height_gutter_width_headings_styleZ	font_size_line_height	_markdown_text_align_width	_wrapmode_num_heading_rowsr   _repeat_headings_min_row_height_initial_stylerowsr   new_paddingALLNO_HORIZONTAL_LINES
ValueError_outer_border_marginrow)selfZfpdfrB   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   rI   r   r   ./tmp/pip-unpacked-wheel-dvf6lv8i/fpdf/table.py__init__   sh    >

zTable.__init__c                 C   sb   | j dkr| j | _ t| |||d}| j| |D ]&}t|trR|jf | q6|| q6|S )z0Adds a row to the table. Returns a `Row` object.N)styler   
min_height)	rA   r-   	font_faceRowrB   append
isinstancedictcell)rJ   cellsrM   r   rN   rI   rT   r   r   rK   rI      s    

z	Table.rowc                    s  | j rtdd | j D nd| _| jdkrX| jrLt| jtrL| j| j | _q| jj| _n<| jrt| jtr| j| j | jkrt	d| j d| j | j| jjkrt	d| j d| jj | j
tjkrt	d| jdkrT| jst	d	| jj}|dk	rT| jjp| jj}| |jd
d }|tkrT|| jjkrTtd| d|j d| jj| jj| jj  }}}| j
tjkr| jj| j d | j_| jj| j_nT| j
tjkr| jj| jj | j | j_| jj| j_n| jj| jjkr| jj| j_| jj| jd  }|g}| j rLt | jD ]*}	|| !d|	7 }|| j"7 }|#| q t$| %  | j&t'j(k}
| j j| jd 7  _t)| j | j  krdkrn n(| j*t+ fddt | jd D  t t)| j D ]}	 |	 j,}| j*|}|r2| jj| | jj-kr2|| j_|| j_|| j_t	d|	 d|r|
r|	| jkr| j j| jd 7  _t | jD ]}| j.| | |d qj|	dkr| j j| j/7  _| .|	 |	 | q|| j_| jj| j_dS )zSThis is an internal method called by `fpdf.FPDF.table()` once the table is finishedc                 s   s   | ]}|j V  qd S N)
cols_count.0rI   r   r   rK   	<genexpr>   s     zTable.render.<locals>.<genexpr>r   NzInvalid value provided width=z$ should be a multiple of col_widths=z: effective page width is z>JUSTIFY is an invalid value for FPDF.table() 'align' parameterzcheadings_style must be provided to FPDF.table() if num_heading_rows>1 or first_row_as_headings=TrueU zUsing font 'z' with emphasis 'zU' in table headings require the corresponding font style to be added using add_font()r,   r   c                 3   s   | ]} | j V  qd S rV   )pagebreak_height)rY   iZ	rows_infor   rK   rZ      s   zThe row with index z4 is too high and cannot be rendered on a single page)cell_x_positions)0rB   max_cols_countr<   r5   rR   r   r-   ZepwrG   r/   r   Jr>   r8   r   familyZfont_familylowerrM   r   r   fontsr   xyl_marginCwRZr_marginrH   range_get_col_widthr7   rQ   list_compute_rows_infor?   r   ZON_TOP_OF_EVERY_PAGElenZ_perform_page_break_if_need_besumr]   page_break_trigger_render_table_rowr6   )rJ   r   rd   Zfont_keyZprev_xZprev_yZprev_l_marginZxxr`   r^   r*   r]   Z
page_breakZrow_idxr   r_   rK   render   s     



$



zTable.renderc                 C   s  |j tjkrt|j S | jtjkr&dS | jtjkr6dS ||j t	| j
| jk}t	| j
}||j |k}td}| jtjkr|dkr|d |r|d |dkr|d |r|d | jtjkr,|dks|| jks|dkr|d || jd kr|d |dkr|d |r,|d | jtjkr`|| jkrP|d |s`|d | jtjkr|dkr|dS td}|dkrd|kr|d n|r|d | jtjkr|dkrdS || jk rdS dS d	|S )
z
        Defines which cell borders should be drawn.
        Returns a string containing some or all of the letters L/R/T/B,
        to be passed to `fpdf.FPDF.multi_cell()`.
        Can be overridden to customize this logic
        r   r   ZLRTBTBLrl   ZTBr\   )borderr   INHERITstrr1   r
   rE   NONEcolspanrq   rB   rU   rowspanro   ZINTERNALremoveZMINIMALr>   rF   ZHORIZONTAL_LINESZSINGLE_TOP_LINEjoin)rJ   r^   jrT   Zis_rightmost_columnZ
rows_countZis_bottom_rowry   r   r   rK   get_cell_border  s\    















zTable.get_cell_borderc           	      K   sn   | j | }| jj}t|jD ]>\}}|d kr.q| j|||f| j||d| | j| q| j|j	 d S )N)
row_heightcell_height_infor`   )
rB   r-   rh   	enumeraterU   _render_table_cellr9   Zset_ylnheight)	rJ   r^   Zrow_layout_infor`   kwargsrI   rh   r   rT   r   r   rK   rt   O  s$    
	zTable._render_table_rowc           "      K   s0  |d krd }d}	n&|j dkr.|j|j  }d}	n
|j}d}	d}
d}| j| }| |||j}d}|jph| j}t|t	t
fs|| }| j}| j||}|r| jr|j| jd}|| jk rt|| j}t||j}t||j}|jrt|jn| j}|j}|s
|j}|s| j}|	r"d}n|| }| j| |	sf| jj}| jj}|| }|| }t| j|||||  ||||r|j!nd d | j"rf| jj#}| j$| j" | jj%}|| j& }|| j'd  }|| j'd  }|dkr| j(|||| ||j | j)krZ| j(|||| |dkr2| j(|||| ||j  t*| jkrZ| j(|||| | j$| |j+rJ| jj| jj }}|j,p|d k}| jj#}| j j|j-|d  7  _| j j|j.|d  7  _| jj/|j+||j- |j0 | |rdn||j. |j1 | d|j2d}|j3|j. |j1 | }|| | jj4kr<d}| j5|| |j6rd}|d k	r|j7| } |t8j9kr||  d }n|t8j:kr||  }| j j|7  _| j;|L | jj<f |||j6| j=d|d	d
d| j>t?j@t?jAB | jB||j2d|\}
}W 5 Q R X | j j|8  _nd}|
p$|}!|!||fS )NTr   Fr   )
fill_color)ry   r   r,   )rk   hZkeep_aspect_ratiolinkRIGHTZTOP)rk   r   textZmax_line_heightry   r   Znew_xZnew_yfillr#   outputr&   r'   r   )Cr~   merged_heightsr   rB   rn   r}   r   r;   rR   r   r{   rA   r4   Zshould_fill_cellr3   r   r>   r   combiner8   rM   r'   r   rC   rD   r   r0   r-   Zset_xrg   rh   draw_box_bordersr   r   r2   
line_widthZset_line_widthri   r<   rH   linerb   rq   imgimg_fill_widthlefttopimagerightZbottomr   Zrendered_heightrs   Zset_xyr   rendered_heightsr   Mrw   Zuse_font_faceZ
multi_cellr9   r:   r	   Z
PAGE_BREAKZHEIGHTr=   )"rJ   r^   r   rT   r   r   r`   r   Zcell_heightZheight_query_onlyZpage_break_textZpage_break_imagerI   	col_width
img_heightr$   rM   Zcell_mode_fillr'   r   Zcell_xx1y1x2y2Z_remember_linewidthrg   rh   Zauto_heightZcell_border_line_widthr   ZdyZactual_text_heightZdo_pagebreakr   r   rK   r   c  s   



	






zTable._render_table_cellc           
      C   s   | j }| j|d | j  d| jd   }t|d | j d}| jsR|||  | S t| jtrl|| j | S |t| jkrt	d|d  d|d  d}t
||| D ]6}| j| t| j }	||	| 7 }||kr|| j7 }q|S )zGets width of a column in a table, this excludes the outer gutter (outside the table) but includes the inner gutter
        between columns if the cell spans multiple columns.r   r,   r   z@Invalid .col_widths specified: missing width for table() column z on row )rb   r<   r7   rH   ra   r5   rR   r   rq   rG   rm   rr   )
rJ   r^   r   r}   rW   r%   Zgutter_within_cellr   kZ	col_ratior   r   rK   rn   .  s.    zTable._get_col_widthc           #   
   c   s>  i }i }t | jD ]\}}||\}}|D ]6}|| }|d k	r,|j| }t||jd d|j|< q,t |jD ]<\}	}t|trn|||	< t|	d |	|j	 D ]}
d ||
< qqnqt
|dkrtdg }g }g }g }| j v t | jD ]b\}}g }g }|i  t |jD ]\}	}|d kr&q| j||	|| jd\}}}|jrN|}n|}||| |	< |jdkr|t|	||j|p| || jk }||j | jk}|r|rtdn|| || qd}|rt|}|dkrt|}|dkr| j}|jr||jk r8|j}n| jr8|| jk r8| j}|| ||j qW 5 Q R X t|dd d	}d
d | jD }|D ]}d}| j|jd  }d}| D ],}t||| }||| 7 }||| 7 }q|| |jk r~|j||j|  kr |j| |j }| D ]}|||< qn4|j| | }| D ]}||  ||j 7  < q6q~t | jD ]\}}|| ||  }d|g} t|d |||  D ]*}	| | d | j ||	  ||	   q|}!|||  }"|d }	|	|"k rt|"|	||	  }"|!| j||	  ||	  7 }!|	d7 }	qt| d |!|| | V  qbd S )Nr   r~   r   z#Rowspan extends beyond end of table)r   z:Heading includes rowspan beyond the number of heading rowsc                 S   s   | j S rV   )length)spanr   r   rK   <lambda>      z*Table._compute_rows_info.<locals>.<lambda>)keyc                 S   s   g | ]}d qS )r   r   rX   r   r   rK   
<listcomp>  s     z,Table._compute_rows_info.<locals>.<listcomp>)r   rB   convert_spansrU   r   r~   rR   Cellrm   r}   rq   r   r-   Z_disable_writingrQ   r   r9   r   RowSpanLayoutInfor>   ra   rN   r@   max_rowspansortedr6   r   	row_rangecontents_heightRowLayoutInfo)#rJ   active_rowspansZprev_row_in_colr^   rI   Zprior_rowspansZcol_idxprev_rowrT   r   r   Zrowspan_listZrow_min_heightsZrow_span_maxr   Zdictated_heightsZimg_heights_r   Ztext_heightZdictated_heightZ
is_headingZspan_outside_headingrN   Zrow_span_paddingr   Zmax_paddingZassigned_heightZassigned_paddingr'   extrar   Zmerged_sizesr]   Zpagebreak_rowr   r   rK   rp   J  s    



   




	
   zTable._compute_rows_info)r   )r   NNN)NN)r   )__name__
__module____qualname____doc__r
   rE   r   r|   DEFAULT_HEADINGS_STYLEr   ZWORDrL   rI   ru   r   rt   r   rn   rp   r   r   r   rK   r      sD    
m9  
 L
r   c                   @   s\   e Zd ZdZdddZedd Zedd Zd	d
 Zdddddddddde	j
fddZdS )rP   z@Object that `Table.row()` yields, used to build a row in a tableNc                 C   s0   || _ g | _|| _|r t|n|| _|| _d S rV   )_tablerU   rM   r   r.   r   rN   )rJ   tablerM   r   rN   r   r   rK   rL     s
    zRow.__init__c                 C   s   t dd | jD S )Nc                 s   s   | ]}t |d |dk	V  qdS )r}   N)getattrrY   rT   r   r   rK   rZ     s     z!Row.cols_count.<locals>.<genexpr>)rr   rU   rJ   r   r   rK   rW     s    zRow.cols_countc                 C   s$   dd | j D }t|r t|S dS )Nc                 S   s   h | ]}|d k	r|j qS rV   r   r   r   r   rK   	<setcomp>  s      z"Row.max_rowspan.<locals>.<setcomp>r   )rU   rq   ra   )rJ   Zspansr   r   rK   r     s    zRow.max_rowspanc                 C   sZ  d}g }t | jD ]\}}|d kr$q|tjkrj|| }t|tsHtdt||jd d||< |	d  q|	| |}t|tr|jdkr|
d g|jd   qi }| D ](\}}	||d  |	dkr|	d ||< qg }
t |D ]d\}}t|tr.|jdkr.t|||j D ]}|jd ||< qq|tjkr|
	| d ||< q|| _||
fS )Nr   z4Invalid location for TableSpan.COL placeholder entryr   )r}   )r   rU   r   ZCOLrR   r   r   r   r}   rQ   extenditemsinsertr~   rm   ZROW)rJ   r   prev_colrU   r^   rT   Z	prev_cellZremaining_rowspansr   vZreverse_rowspansr   r   rK   r     s@    





zRow.convert_spansr\   Fr   c                 C   s   |r|rt dt|tr*| j| |S |sP| jj }|| j| jj	fkrP|}t
|||rdt|n|||||||	|
t|}| j| |S )a  
        Adds a cell to the row.

        Args:
            text (str): string content, can contain several lines.
                In that case, the row height will grow proportionally.
            align (str, fpdf.enums.Align): optional text alignment.
            v_align (str, fpdf.enums.VAlign): optional vertical text alignment.
            style (fpdf.fonts.FontFace): optional text style.
            img: optional. Either a string representing a file path to an image,
                an URL to an image, an io.BytesIO, or a instance of `PIL.Image.Image`.
            img_fill_width (bool): optional, defaults to False. Indicates to render the image
                using the full width of the current table column.
            colspan (int): optional number of columns this cell should span.
            rowspan (int): optional number of rows this cell should span.
            padding (tuple): optional padding (left, top, right, bottom) for the cell.
            link (str, int): optional link, either an URL or an integer returned by `FPDF.add_link`, defining an internal link to a page
            border (fpdf.enums.CellBordersLayout): optional cell borders, defaults to `CellBordersLayout.INHERIT`

        u   fpdf2 currently does not support inserting text with an image in the same table cell. Pull Requests are welcome to implement this 😊)NotImplementedErrorrR   r   rU   rQ   r   r-   rO   rM   rA   r   r   r.   r   )rJ   r   r   r   rM   r   r   r}   r~   r'   r   ry   rO   rT   r   r   rK   rT     s4    "
zRow.cell)NNN)r   r   r   r   rL   propertyrW   r   r   r   rz   rT   r   r   r   rK   rP     s&   


(rP   T)frozenc                   @   s   e Zd ZU dZdZeed< eeee	f  ed< eeee
f  ed< ee ed< ee ed< eed< eed	< eed
< eeeeedf  ed< eeeef  ed< ee ed< dddZdS )r   z'Internal representation of a table cell)r   r   r   rM   r   r   r}   r~   r'   r   ry   r   r   r   rM   r   r   r}   r~   Nr'   r   ry   c                 C   s   t dd S )NzNot implemented yet)r   )rJ   r   r   r   r   rK   write~  s    z
Cell.write)N)r   r   r   r   	__slots__r{   __annotations__r   r   r   r   r   boolinttupletyper   r   r   r   r   rK   r   a  s   
r   c                   @   s.   e Zd ZU eed< eed< eed< eed< dS )r   r   r]   r   r   N)r   r   r   floatr   rS   ro   r   r   r   rK   r     s   
r   c                   @   s6   e Zd ZU eed< eed< eed< eed< dd ZdS )r   columnstartr   r   c                 C   s   t | j| j| j S rV   )rm   r   r   r   r   r   rK   r     s    zRowSpanLayoutInfo.row_rangeN)r   r   r   r   r   r   r   r   r   r   rK   r     s
   
r   Nc                 C   s  |r| j }| | g }| j}	| j| }| j| }||	9 }||	9 }||	9 }||	9 }t|trnt|drnd}|r|dkr~dnd}
||dd|dd|| dd|| dd|
 	 n:|dkr||dd|dd|| dd|| dd t|trd	|kr4||dd|dd
|dd|dd d|krh||dd|dd
|dd|dd d|kr||dd|dd
|dd|dd d|kr||dd|dd
|dd|dd d	|}| 
| |r| | dS )a  Draws a box using the provided style - private helper used by table for drawing the cell and table borders.
    Difference between this and rect() is that border can be defined as "L,R,T,B" to draw only some of the four borders;
    compatible with get_border(i,k)

    See Also: rect()ZLTRBr   rw   fz.2f z re z re Srx   z m z l Srl   rv   N)r   Zset_fill_colorr   r   rR   r{   set
issupersetrQ   r   Z_out)Zpdfr   r   r   r   ry   r   Zprev_fill_colorslr   opsr   r   rK   r     s>    


82
*
*
*
*

r   )N) dataclassesr   r   Znumbersr   typingr   r   enumsr   r	   r
   r   r   r   r   r   r   errorsr   rf   r   r   utilr   r   r   rP   r   r   r   r   r   r   r   rK   <module>   s*   ,
     Q~ 	
