o
    j'                     @  s   d Z ddlmZ ddlmZ ddlmZ er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Zdd ZdS )z?Objects related to layout of rendered text, such as TextFitter.    )annotations)TYPE_CHECKING)	ImageFont)Lengthc                   @  s   e Zd ZdZdd Zed!ddZdd Zdd Zdd Z	e
dd Ze
dd Ze
dd Ze
dd Ze
dd Zdd Zd S )"
TextFitterzGValue object that knows how to fit text into given rectangular extents.c                 C  s   |\}}t | ||||fS Ntuple__new__)clsline_sourceextents	font_filewidthheight r   P/home/air/Certificate/back/venv/lib/python3.10/site-packages/pptx/text/layout.pyr
      s   zTextFitter.__new__textstrr   tuple[Length, Length]max_sizeintr   returnc                 C  s   t |}| |||}||S )a+  Return whole-number best fit point size less than or equal to `max_size`.

        The return value is the largest whole-number point size less than or equal to
        `max_size` that allows `text` to fit completely within `extents` when rendered
        using font defined in `font_file`.
        )_LineSource_best_fit_font_size)r   r   r   r   r   r   text_fitterr   r   r   best_fit_font_size   s   

zTextFitter.best_fit_font_sizec                 C  s(   | j }ttdt|d }||S )z
        Return the largest whole-number point size less than or equal to
        *max_size* that this fitter can fit.
           )_fits_inside_predicate_BinarySearchTreefrom_ordered_sequenceranger   find_max)selfr   	predicatesizesr   r   r   r   "   s   
zTextFitter._best_fit_font_sizec                 C  s   t |}| |}||S )z
        Return a (line, remainder) pair where *line* is the longest line in
        *line_source* that will fit in this fitter's width and *remainder* is
        a |_LineSource| object containing the text following the break point.
        )r   r    _fits_in_width_predicater"   )r#   r   
point_sizelinesr$   r   r   r   _break_line+   s   


zTextFitter._break_linec                   s    fdd}|S )z
        Return a function taking a text string value and returns |True| if
        that text fits in this fitter when rendered at *point_size*. Used as
        predicate for _break_line()
        c                   s   t | j jd }|jkS )zp
            Return |True| if *line* fits in this fitter when rendered at
            *point_size*.
            r   )_rendered_sizer   
_font_file_width)linecxr'   r#   r   r   r$   <   s   
z6TextFitter._fits_in_width_predicate.<locals>.predicater   )r#   r'   r$   r   r/   r   r&   5   s   z#TextFitter._fits_in_width_predicatec                   s    fdd}|S )zReturn  function taking an integer point size argument.

        The function returns |True| if the text in this fitter can be wrapped to fit
        entirely within its extents when rendered at that point size.
        c                   s2      j| }td|  jd }|t|  jkS )zReturn |True| when text in `line_source` can be wrapped to fit.

            Fit means text can be broken into lines that fit entirely within `extents`
            when rendered at `point_size` using the font defined in `font_file`.
            Tyr   )_wrap_lines_line_sourcer*   r+   len_height)r'   
text_linescyr#   r   r   r$   N   s   z4TextFitter._fits_inside_predicate.<locals>.predicater   )r#   r$   r   r7   r   r   F   s   
z!TextFitter._fits_inside_predicatec                 C     | d S )N   r   r7   r   r   r   r+   Z      zTextFitter._font_filec                 C  r8   )N   r   r7   r   r   r   r4   ^   r:   zTextFitter._heightc                 C  r8   Nr   r   r7   r   r   r   r2   b   r:   zTextFitter._line_sourcec                 C  r8   Nr   r   r7   r   r   r   r,   f   r:   zTextFitter._widthc                 C  s0   |  ||\}}|g}|r|| || |S )z
        Return a sequence of str values representing the text in
        *line_source* wrapped within this fitter when rendered at
        *point_size*.
        )r)   extendr1   )r#   r   r'   r   	remainderr(   r   r   r   r1   j   s
   zTextFitter._wrap_linesN)
r   r   r   r   r   r   r   r   r   r   )__name__
__module____qualname____doc__r
   classmethodr   r   r)   r&   propertyr   r+   r4   r2   r,   r1   r   r   r   r   r      s&    	





r   c                   @  s`   e Zd ZdZdd ZdddZedd Zd	d
 ZdddZ	e
dd Zedd Zdd ZdS )r   z]
    A node in a binary search tree. Uniform for root, subtree root, and leaf
    nodes.
    c                 C  s   || _ d | _d | _d S r   )_value_lesser_greater)r#   valuer   r   r   __init__}   s   
z_BinarySearchTree.__init__Nc                 C  s6   || j r| j }| j}n| j}|du r|S |||S )zc
        Return the largest item in or under this node that satisfies
        *predicate*.
        N)rI   rH   rG   r"   )r#   r$   max_	next_noder   r   r   r"      s   
z_BinarySearchTree.find_maxc                 C  s"   t |}| | }|| |S )zx
        Return the root of a balanced binary search tree populated with the
        values in iterable *iseq*.
        )listpop_insert_from_ordered_sequence)r   iseqseqbstr   r   r   r       s   
z'_BinarySearchTree.from_ordered_sequencec                 C  sF   || j k rdnd}t| |}|du rt| |t| dS || dS )z
        Insert a new node containing *value* into this tree such that its
        structure as a binary search tree is preserved.
        rG   rH   N)rI   getattrsetattrr   insert)r#   rI   sidechildr   r   r   rU      s
   
z_BinarySearchTree.insertr    c                 C  sX   d|| j jf }dd|  }| jr|| j|d |7 }| jr*|| j|d |7 }|S )zq
        A string representation of the tree rooted in this node, useful for
        debugging purposes.
        z%s%s
u   %s└── z    r   )rI   r   rG   treerH   )r#   levelprefixr   r   r   r   rY      s   z_BinarySearchTree.treec                 C  s   | j S )z:
        The value object contained in this node.
        )rF   r7   r   r   r   rI      s   z_BinarySearchTree.valuec                 C  sT   t | dkrg dg fS tt | d }| | }| |d d }| d| }|||fS )z~
        Return a (medial_value, greater_values, lesser_values) 3-tuple
        obtained by bisecting sequence *seq*.
        r   Nr;   r   )r3   r   )rQ   mid_idxmidgreaterlesserr   r   r   _bisect   s   

z_BinarySearchTree._bisectc                 C  sB   t |dkrdS | |\}}}| | | | | | dS )zx
        Insert the new values contained in *seq* into this tree such that
        a balanced tree is produced.
        r   N)r3   r`   rU   rO   )r#   rQ   r]   r^   r_   r   r   r   rO      s   

z/_BinarySearchTree._insert_from_ordered_sequencer   )r   rX   )r@   rA   rB   rC   rJ   r"   rD   r    rU   rY   rE   rI   staticmethodr`   rO   r   r   r   r   r   w   s    




r   c                   @  s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )r   aj  
    Generates all the possible even-word line breaks in a string of text,
    each in the form of a (line, remainder) 2-tuple where *line* contains the
    text before the break and *remainder* the text after as a |_LineSource|
    object. Its boolean value is |True| when it contains text, |False| when
    its text is the empty string or whitespace only.
    c                 C  s
   || _ d S r   _text)r#   r   r   r   r   rJ         
z_LineSource.__init__c                 C     | j  dkS )z
        Gives this object boolean behaviors (in Python 3). bool(line_source)
        is False if it contains the empty string or whitespace only.
        rX   rc   stripr7   r   r   r   __bool__      z_LineSource.__bool__c                 C  s   | j |j kS r   rb   r#   otherr   r   r   __eq__      z_LineSource.__eq__c                 c  s`    | j  }tdt|d D ]}d|d| }d||d }t|}t||V  qdS )z
        Generate a (text, remainder) pair for each possible even-word line
        break in this line source, where *text* is a str value and remainder
        is a |_LineSource| value.
        r    N)rc   splitr!   r3   joinr   _Line)r#   wordsidx	line_textremainder_textr?   r   r   r   __iter__   s   
z_LineSource.__iter__c                 C  re   )z
        Gives this object boolean behaviors (in Python 2). bool(line_source)
        is False if it contains the empty string or whitespace only.
        rX   rf   r7   r   r   r   __nonzero__   ri   z_LineSource.__nonzero__c                 C  s
   d| j  S )Nz<_LineSource('%s')>rb   r7   r   r   r   __repr__  rd   z_LineSource.__repr__N)
r@   rA   rB   rC   rJ   rh   rl   rv   rw   rx   r   r   r   r   r      s    r   c                   @  sP   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Ze	dd Z
e	dd ZdS )rq   z
    A candidate line broken at an even word boundary from a string of text,
    and a |_LineSource| value containing the text that remains after the line
    is broken at this spot.
    c                 C  s   t | ||fS r   r   )r   r   r?   r   r   r   r
        z_Line.__new__c                 C  s   t | jt |jkS r   r3   r   rj   r   r   r   __gt__  s   z_Line.__gt__c                 C  s   |  | S r   )r{   rj   r   r   r   __lt__  rm   z_Line.__lt__c                 C  s
   t | jS r   rz   r7   r   r   r   __len__  rd   z_Line.__len__c                 C  s   d| j | jf S )Nz'%s' => '%s')r   r?   r7   r   r   r   rx     ry   z_Line.__repr__c                 C  r8   r=   r   r7   r   r   r   r?     r:   z_Line.remainderc                 C  r8   r<   r   r7   r   r   r   r     r:   z
_Line.textN)r@   rA   rB   rC   r
   r{   r|   r}   rx   rE   r?   r   r   r   r   r   rq     s    
rq   c                   @  s    e Zd ZdZi Zedd ZdS )_Fontsz2
    A memoizing cache for ImageFont objects.
    c                 C  s2   ||f| j vrt||| j ||f< | j ||f S r   )fontsr   truetype)r   	font_pathr'   r   r   r   font+  s   z_Fonts.fontN)r@   rA   rB   rC   r   rD   r   r   r   r   r   r~   $  s
    r~   c                 C  s   d}d}t ||}z	|| \}}W n ty.   || \}}	}
}|
| ||	 }}Y nw t|| | }t|| | }||fS )z
    Return a (width, height) pair representing the size of *text* in English
    Metric Units (EMU) when rendered at *point_size* in the font defined in
    *font_file*.
    i g      R@)r~   r   getsizeAttributeErrorgetbboxr   )r   r'   r   emu_per_inchpx_per_inchr   px_width	px_heightlefttoprightbottom	emu_width
emu_heightr   r   r   r*   2  s   r*   N)rC   
__future__r   typingr   PILr   	pptx.utilr   r	   r   objectr   r   rq   r~   r*   r   r   r   r   <module>   s    j`.