B
    ]”t\ýE  ã               @   sÈ   d dl mZ d dlZd dlZd dlZd dlZd dlm	Z	m
Z
mZmZ d dlmZmZ d dlmZmZmZ d dlmZ d dlmZ d dlmZ e d	¡d
d„ ƒZG dd„ deƒZeƒ ZG dd„ deƒZdS )é    )ÚOrderedDictN)ÚcbookÚdvireadÚfont_managerÚrcParams)ÚFontPropertiesÚget_font)ÚKERNING_DEFAULTÚLOAD_NO_HINTINGÚLOAD_TARGET_LIGHT)ÚMathTextParser)ÚPath)ÚAffine2Dé   c              C   s(   t  d¡} t  | ¡}dd„ t|jƒD ƒS )Nz8a.encc             S   s   i | ]\}}||“qS © r   )Ú.0ÚiÚcr   r   ú2lib/python3.7/site-packages/matplotlib/textpath.pyú
<dictcomp>   s    z0_get_adobe_standard_encoding.<locals>.<dictcomp>)r   Úfind_tex_fileÚEncodingÚ	enumerateÚencoding)Zenc_nameÚencr   r   r   Ú_get_adobe_standard_encoding   s    

r   c               @   s®   e Zd ZdZdZdZdd„ Zee 	d¡dd„ ƒƒZ
d	d
„ Zdd„ Zdd„ Zdd„ Zd%dd„Zdd„ Zd&dd„Zd'dd„Zd(dd„Zdd„ Zd)d d!„Zee d"¡d#d$„ ƒƒZdS )*Ú
TextToPathzF
    A class that convert a given text to a path using ttf fonts.
    g      Y@éH   c             C   s   t dƒ| _d | _d S )NÚpath)r   Úmathtext_parserÚ_texmanager)Úselfr   r   r   Ú__init__    s    
zTextToPath.__init__z3.0c             C   s   t  t  d¡¡S )Nz
pdftex.map)r   Ú
PsfontsMapr   )r!   r   r   r   Útex_font_map$   s    zTextToPath.tex_font_mapc             C   s&   t  |¡}t|ƒ}| | j| j¡ |S )z"
        find a ttf font.
        )r   Zfindfontr   Úset_sizeÚ
FONT_SCALEÚDPI)r!   ÚpropÚfnameÚfontr   r   r   Ú	_get_font)   s    
zTextToPath._get_fontc             C   s   t S )N)r
   )r!   r   r   r   Ú_get_hinting_flag3   s    zTextToPath._get_hinting_flagc             C   s   t j d |j|¡¡S )zO
        Return a unique id for the given font and character-code set.
        z{}-{})ÚurllibÚparseÚquoteÚformatZpostscript_name)r!   r*   Úccoder   r   r   Ú_get_char_id6   s    zTextToPath._get_char_idc             C   s$   |  ¡ d }tj d||f ¡}|S )zY
        Return a unique id for the given font and character-code set (for tex).
        é   z%s-%d)Zget_ps_font_infor-   r.   r/   )r!   r*   r1   Zps_nameÚchar_idr   r   r   Ú_get_char_id_ps<   s    zTextToPath._get_char_id_psç        c             C   s4   |  ¡ \}}|dkr,|dd…df  |7  < ||fS )zB
        convert the ft2font glyph to vertices and codes.
        g        Nr   )Zget_path)r!   r*   ÚcurrxÚvertsÚcodesr   r   r   Úglyph_to_pathD   s    zTextToPath.glyph_to_pathc             C   sî   t d r8|  ¡ }| ¡ }|j||d d\}}}|||fS | ¡ }|| j }	|r’| ¡ }| | j¡ | j |d|¡\}
}}}}|
|	 ||	 ||	 fS |  	|¡}|j
|dtd | ¡ \}}|d }|d }| ¡ }|d }||	 ||	 ||	 fS )Nztext.usetex)Zrendererr   g        )Úflagsg      P@)r   Úget_texmanagerÚget_size_in_pointsÚget_text_width_height_descentr&   Úcopyr%   r   r.   r+   Zset_textr
   Zget_width_heightZget_descent)r!   Úsr(   ÚismathÚ
texmanagerÚfontsizeÚwÚhÚdÚscaleÚwidthÚheightÚdescentZtrashZused_charactersr*   r   r   r   r>   M   s*    


z(TextToPath.get_text_width_height_descentFc             C   sØ   |s:|s&|   |¡}|  ||¡\}}}qL|  ||¡\}}}n|  ||¡\}}}g g  }	}
xR|D ]J\}}}}|| \}}t|ƒr\t |¡| ||g }|	 |¡ |
 |¡ q\W x$|D ]\}}|	 |¡ |
 |¡ q°W |	|
fS )a(  
        Convert text *s* to path (a tuple of vertices and codes for
        matplotlib.path.Path).

        Parameters
        ----------

        prop : `matplotlib.font_manager.FontProperties` instance
            The font properties for the text.

        s : str
            The text to be converted.

        usetex : bool, optional
            Whether to use tex rendering. Defaults to ``False``.

        ismath : bool, optional
            If True, use mathtext parser. Effective only if
            ``usetex == False``.

        Returns
        -------

        verts, codes : tuple of lists
            *verts*  is a list of numpy arrays containing the x and y
            coordinates of the vertices. *codes* is a list of path codes.

        Examples
        --------

        Create a list of vertices and codes from a text, and create a `Path`
        from those::

            from matplotlib.path import Path
            from matplotlib.textpath import TextToPath
            from matplotlib.font_manager import FontProperties

            fp = FontProperties(family="Humor Sans", style="italic")
            verts, codes = TextToPath().get_text_path(fp, "ABC")
            path = Path(verts, codes, closed=False)

        Also see `TextPath` for a more direct way to create a path from a text.
        )r+   Úget_glyphs_with_fontÚget_glyphs_mathtextÚget_glyphs_texÚlenÚnpZarrayÚextend)r!   r(   r@   rA   Úusetexr*   Z
glyph_infoÚ	glyph_mapÚrectsr8   r9   Zglyph_idZ	xpositionZ	ypositionrG   Zverts1Zcodes1r   r   r   Úget_text_pathi   s&    ,



zTextToPath.get_text_pathNc             C   s  d}d}g }g }|dkrt ƒ }|r*t ƒ }	n|}	x´|D ]¬}
t|
ƒ}| |¡}|dkr^tdƒ}d}|dk	rv| ||t¡}nd}|j|td}|jd }|  ||¡}||kr´|  	|¡|	|< ||d 7 }| 
|¡ | 
|¡ ||7 }|}q4W dgt|ƒ }dgt|ƒ }g }tt||||ƒƒ|	|fS )zW
        Convert string *s* to vertices and codes using the provided ttf font.
        Nr   ú?)r;   i   é@   g      ð?)r   ÚordZget_char_indexZget_kerningr	   Ú	load_charr
   ZlinearHoriAdvancer2   r:   ÚappendrN   ÚlistÚzip)r!   r*   r@   rR   Úreturn_new_glyphs_onlyZlastgindr7   Ú
xpositionsÚ	glyph_idsÚglyph_map_newr   r1   ZgindZkernÚglyphZhoriz_advancer4   Ú
ypositionsÚsizesrS   r   r   r   rK   ¯   sB    




zTextToPath.get_glyphs_with_fontc             C   s„  |  ¡ }| | j¡ | j || j|¡\}}}}}	|s:tƒ }|rFtƒ }
n|}
g }g }g }g }d\}}x|D ]ˆ\}}}}}|  ||¡}||kr¾| ¡  | | j| j¡ |j	|t
d}|  |¡|
|< | |¡ | |¡ | |¡ || j }| |¡ qhW g }xr|	D ]j\}}}}||f||| f|| || f|| |f||fdg}tjtjtjtjtjtjg}| ||f¡ qþW tt||||ƒƒ|
|fS )zc
        convert the string *s* to vertices and codes by parsing it with
        mathtext.
        )r   r   )r;   )r?   r%   r&   r   r.   r'   r   r2   ÚclearrX   r
   r:   rY   r   ÚMOVETOÚLINETOÚ	CLOSEPOLYrZ   r[   )r!   r(   r@   rR   r\   rH   rI   rJ   ZglyphsrS   r_   r]   ra   r^   rb   r7   Zcurryr*   rC   r1   ÚoxÚoyr4   r`   ÚsizeÚmyrectsrD   rE   Úvert1Úcode1r   r   r   rL   ë   sH    



zTextToPath.get_glyphs_mathtextc             C   s$   | j dkrddlm} |ƒ | _ | j S )zO
        return the :class:`matplotlib.texmanager.TexManager` instance
        Nr   )Ú
TexManager)r    Zmatplotlib.texmanagerrm   )r!   rm   r   r   r   r<      s    
zTextToPath.get_texmanagerc       "   	   C   s$  |   ¡ }| ¡ }t|dƒr8| || j¡}t || j¡}n| || j¡}	t 	|	| j¡}| t
t|ƒƒ}
W dQ R X |dkr~tƒ }|rŠtƒ }n|}g g g g f\}}}}xì|
jD ]â\}}}}}|  |j¡\}}|  ||¡}||kr\| ¡  | | j| j¡ |r
| |d¡}n|}t}|dk	r,|j||d}n"t d||jf ¡ |j||d}|  |¡||< | |¡ | |¡ | |¡ | |j| j ¡ qªW g }xv|
jD ]l\}}}}||f|| |f|| || f||| f||fdg} tjtjtjtjtjtj g}!| | |!f¡ qœW t!t"||||ƒƒ||fS )zf
        convert the string *s* to vertices and codes using matplotlib's usetex
        mode.
        Úget_dviN)r;   zUThe glyph (%d) of font (%s) cannot be converted with the encoding. Glyph may be wrong)r   r   )#r<   r=   Úhasattrrn   r&   r   ZDviFromFileLiker'   Zmake_dviZDviÚnextÚiterr   ÚtextÚ_get_ps_font_and_encodingÚtexnamer5   rc   r%   Úgetr   rX   ÚwarningsÚwarnr)   r:   rY   ri   Zboxesr   rd   re   rf   rZ   r[   )"r!   r(   r@   rR   r\   rB   rC   ZdvifilelikeZdviZdvifileZpager_   r^   r]   ra   rb   Zx1Zy1Zdvifontr`   rH   r*   r   r4   ZcharcodeZft2font_flagZglyph0rj   rg   rh   rE   rD   rk   rl   r   r   r   rM   )  sZ    	





zTextToPath.get_glyphs_texé2   c          
   C   sÊ   t  t  d¡¡}||  }|jd kr4td|j| f ƒ‚t|jƒ}xNdD ]2\}}y| |¡ W n ttfk
rr   Y qDX P qDW d}t	 
d|j ¡ |dkr¾|jr¾t  |j¡}dd„ t|jƒD ƒ}ni }||fS )	Nz
pdftex.mapzJNo usable font file found for %s (%s). The font may lack a Type-1 version.))ZADOBE_CUSTOMiCBDA)ÚADOBE_STANDARDiBODAÚ z#No supported encoding in font (%s).ry   c             S   s    i | ]\}}t ƒ  |d ¡|“qS )N)r   ru   )r   r   r   r   r   r   r   ‘  s   z8TextToPath._get_ps_font_and_encoding.<locals>.<dictcomp>)r   r#   r   ÚfilenameÚ
ValueErrorZpsnamer   Zselect_charmapÚRuntimeErrorrv   rw   r   r   r   )rt   r$   Z
font_bunchr*   Zcharmap_nameZcharmap_codeZenc0r   r   r   r   rs   u  s,    


z$TextToPath._get_ps_font_and_encoding)r6   )FF)NF)NF)NF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r&   r'   r"   Úpropertyr   Z
deprecatedr$   r+   r,   r2   r5   r:   r>   rT   rK   rL   r<   rM   ÚstaticmethodÚ	functoolsÚ	lru_cachers   r   r   r   r   r      s,   

	
F 
; 
4	 
Kr   c               @   sb   e Zd ZdZddd„Zdd„ Zd	d
„ Zdd„ Zdd„ Ze	eƒZ
e	eƒZdd„ Zdd„ Zdd„ ZdS )ÚTextPathz&
    Create a path from the text.
    Nr   Fc       	      O   sl   |dkrt ƒ }|dkr| ¡ }|| _|  |¡ d| _| j|||d\| _| _d| _t	d | _
d| _|| _dS )a  
        Create a path from the text. Note that it simply is a path,
        not an artist. You need to use the `~.PathPatch` (or other artists)
        to draw this path onto the canvas.

        Parameters
        ----------

        xy : tuple or array of two float values
            Position of the text. For no offset, use ``xy=(0, 0)``.

        s : str
            The text to convert to a path.

        size : float, optional
            Font size in points. Defaults to the size specified via the font
            properties *prop*.

        prop : `matplotlib.font_manager.FontProperties`, optional
            Font property. If not provided, will use a default
            ``FontProperties`` with parameters from the
            :ref:`rcParams <matplotlib-rcparams>`.

        _interpolation_steps : integer, optional
            (Currently ignored)

        usetex : bool, optional
            Whether to use tex rendering. Defaults to ``False``.

        Examples
        --------

        The following creates a path from the string "ABC" with Helvetica
        font face; and another path from the latex fraction 1/2::

            from matplotlib.textpath import TextPath
            from matplotlib.font_manager import FontProperties

            fp = FontProperties(family="Helvetica", style="italic")
            path1 = TextPath((12,12), "ABC", size=12, prop=fp)
            path2 = TextPath((0,0), r"$\frac{1}{2}$", size=12, usetex=True)

        Also see :doc:`/gallery/text_labels_and_annotations/demo_text_path`.
        N)rQ   Fzpath.simplify_threshold)r   r=   Ú_xyr%   Ú_cached_verticesÚtext_get_vertices_codesÚ	_verticesÚ_codesZ_should_simplifyr   Z_simplify_thresholdZ_has_nonfiniteÚ_interpolation_steps)	r!   Zxyr@   ri   r(   rŒ   rQ   ZklÚkwargsr   r   r   r"   ¡  s    0

zTextPath.__init__c             C   s   || _ d| _dS )z*
        set the size of the text
        TN)Ú_sizeÚ_invalid)r!   ri   r   r   r   r%   å  s    zTextPath.set_sizec             C   s   | j S )z*
        get the size of the text
        )rŽ   )r!   r   r   r   Úget_sizeì  s    zTextPath.get_sizec             C   s   |   ¡  | jS )zH
        Return the cached path after updating it if necessary.
        )Ú_revalidate_pathrˆ   )r!   r   r   r   Ú_get_verticesò  s    zTextPath._get_verticesc             C   s   | j S )z"
        Return the codes
        )r‹   )r!   r   r   r   Ú
_get_codesù  s    zTextPath._get_codesc             C   sN   | j s| jdkrJtƒ  | jtj | jtj ¡j| jŽ }| 	| j
¡| _d| _ dS )zÍ
        update the path if necessary.

        The path for the text is initially create with the font size
        of FONT_SCALE, and this path is rescaled to other size when
        necessary.

        NF)r   rˆ   r   rG   rŽ   Útext_to_pathr&   Ú	translater‡   Z	transformrŠ   )r!   Ztrr   r   r   r‘     s    	
zTextPath._revalidate_pathc             C   sX   |  d¡|  d¡ }|dko&|d dk}td r8|dfS |rD|dfS | dd¡dfS d	S )
zM
        Returns True if the given string *s* contains any mathtext.
        ú$z\$r   r3   ztext.usetexZTeXTFN)Úcountr   Úreplace)r!   r@   Zdollar_countZeven_dollarsr   r   r   Úis_math_text  s    zTextPath.is_math_textc             C   sD   |rt j||dd\}}n"|  |¡\}}t j|||d\}}||fS )zš
        convert the string *s* to vertices and codes using the
        provided font property *prop*. Mostly copied from
        backend_svg.py.
        T)rQ   )rA   )r”   rT   r™   )r!   r(   r@   rQ   r8   r9   Z
clean_linerA   r   r   r   r‰   %  s    z TextPath.text_get_vertices_codes)NNr   F)r~   r   r€   r   r"   r%   r   r’   r“   r‚   Zverticesr9   r‘   r™   r‰   r   r   r   r   r†   œ  s    
Cr†   ) Úcollectionsr   r„   Zurllib.parser-   rv   ZnumpyrO   Z
matplotlibr   r   r   r   Zmatplotlib.font_managerr   r   Zmatplotlib.ft2fontr	   r
   r   Zmatplotlib.mathtextr   Zmatplotlib.pathr   Zmatplotlib.transformsr   r…   r   Úobjectr   r”   r†   r   r   r   r   Ú<module>   s"      