B
    ]t\;7                 @   s   d 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
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d deZG dd deZG dd deZdS )z
Defines classes for path effects. The path effects are supported in
:class:`~matplotlib.text.Text`, :class:`~matplotlib.lines.Line2D`
and :class:`~matplotlib.patches.Patch`.
    )RendererBase)colors)patches)
transformsc               @   s4   e Zd ZdZdddZdd Zdd Zdd
dZd	S )AbstractPathEffectz
    A base class for path effects.

    Subclasses should override the ``draw_path`` method to add effect
    functionality.

    g        g        c             C   s   || _ t | _dS )z
        Parameters
        ----------
        offset : pair of floats
            The offset to apply to the path, measured in points.
        N)_offsetmtransformsAffine2D_offset_trans)selfoffset r   5lib/python3.7/site-packages/matplotlib/patheffects.py__init__   s    zAbstractPathEffect.__init__c             C   s6   | | jd }| | jd }|| j || S )z(Apply the offset to the given transform.r      )points_to_pixelsr   r   clear	translate)r   renderer	transformZoffset_xZoffset_yr   r   r   _offset_transform   s    z$AbstractPathEffect._offset_transformc             C   sl   |  }|dd}|r$|jf | xB| D ]6\}}t|d| d}t|s\td||| q.W |S )z
        Update the given GraphicsCollection with the given
        dictionary of properties. The keys in the dictionary are used to
        identify the appropriate set_ method on the gc.

        dashesNZset_zUnknown property {0})copypopZ
set_dashesitemsgetattrcallableAttributeErrorformat)r   gcZnew_gc_dictr   kvZ
set_methodr   r   r   
_update_gc&   s    zAbstractPathEffect._update_gcNc             C   s    t |tr|j}|||||S )z
        Derived should override this method. The arguments are the same
        as :meth:`matplotlib.backend_bases.RendererBase.draw_path`
        except the first argument is a renderer.

        )
isinstancePathEffectRenderer	_renderer	draw_path)r   r   r    tpathaffinergbFacer   r   r   r'   :   s    
zAbstractPathEffect.draw_path)r   )N)__name__
__module____qualname____doc__r   r   r#   r'   r   r   r   r   r      s
   

r   c               @   sZ   e Zd ZdZdd Z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S )r%   ax  
    Implements a Renderer which contains another renderer.

    This proxy then intercepts draw calls, calling the appropriate
    :class:`AbstractPathEffect` draw method.

    .. note::
        Not all methods have been overridden on this RendererBase subclass.
        It may be necessary to add further methods to extend the PathEffects
        capabilities further.

    c             C   s   || _ || _dS )z
        Parameters
        ----------
        path_effects : iterable of :class:`AbstractPathEffect`
            The path effects which this renderer represents.
        renderer : :class:`matplotlib.backend_bases.RendererBase` instance

        N)_path_effectsr&   )r   path_effectsr   r   r   r   r   T   s    	zPathEffectRenderer.__init__c             C   s
   | j  S )N)r&   new_gc)r   r   r   r   r1   `   s    zPathEffectRenderer.new_gcc             C   s   |  || jS )N)	__class__r&   )r   r0   r   r   r   copy_with_path_effectc   s    z(PathEffectRenderer.copy_with_path_effectNc             C   s(   x"| j D ]}|| j|||| qW d S )N)r/   r'   r&   )r   r    r(   r)   r*   path_effectr   r   r   r'   f   s    zPathEffectRenderer.draw_pathc       	      O   s`   t | jdkr(tj| ||||f||S x2| jD ](}| |g}|j||||f|| q0W d S )Nr   )lenr/   r   draw_markersr3   )	r   r    Zmarker_pathZmarker_transpathargskwargsr4   r   r   r   r   r6   k   s    

zPathEffectRenderer.draw_markersc             O   s\   t | jdkr&tj| |||f||S x0| jD ]&}| |g}|j|||f|| q.W d S )Nr   )r5   r/   r   draw_path_collectionr3   )r   r    Zmaster_transformpathsr8   r9   r4   r   r   r   r   r:   ~   s    
z'PathEffectRenderer.draw_path_collectionc             C   s   | j |S )N)r&   r   )r   Zpointsr   r   r   r      s    z#PathEffectRenderer.points_to_pixelsc             C   s@   |  ||||||\}}	| }
|d | j|||	|
d d S )Ng        )r*   )Z_get_text_path_transformZget_rgbset_linewidthr'   )r   r    xysZpropZangleZismathr7   r   Zcolorr   r   r   _draw_text_as_path   s
    
z%PathEffectRenderer._draw_text_as_pathc             C   s$   |dkrt | j|S t| |S d S )N)Z
_text2pathZflipyZheightwidth)r   r&   object__getattribute__)r   namer   r   r   rC      s    z#PathEffectRenderer.__getattribute__)N)r+   r,   r-   r.   r   r1   r3   r'   r6   r:   r   r@   rC   r   r   r   r   r%   G   s   
r%   c               @   s   e Zd ZdZdS )Normalz
    The "identity" PathEffect.

    The Normal PathEffect's sole purpose is to draw the original artist with
    no special path effect.
    N)r+   r,   r-   r.   r   r   r   r   rE      s   rE   c                   s*   e Zd ZdZd fdd	Zdd Z  ZS )Strokez0A line based PathEffect which re-draws a stroke.r   r   c                s   t  | || _dS )z
        The path will be stroked with its gc updated with the given
        keyword arguments, i.e., the keyword arguments should be valid
        gc parameter values.
        N)superr   _gc)r   r   r9   )r2   r   r   r      s    zStroke.__init__c             C   sH   |  }|| | || j}| ||}||||| |  dS )z0
        draw the path with updated gc.
        N)r1   copy_propertiesr#   rI   r   r'   restore)r   r   r    r(   r)   r*   gc0Ztransr   r   r   r'      s    
zStroke.draw_path)rG   )r+   r,   r-   r.   r   r'   __classcell__r   r   )r2   r   rF      s   	rF   c               @   s   e Zd ZdZdd ZdS )
withStrokezy
    Adds a simple :class:`Stroke` and then draws the
    original Artist to avoid needing to call :class:`Normal`.

    c             C   s(   t | ||||| ||||| d S )N)rF   r'   )r   r   r    r(   r)   r*   r   r   r   r'      s    zwithStroke.draw_pathN)r+   r,   r-   r.   r'   r   r   r   r   rN      s   rN   c                   s*   e Zd ZdZd	 fdd	Zdd Z  ZS )
SimplePatchShadowz#A simple shadow via a filled patch.   N333333?c                sT   t  | |dkr|| _nt|| _|dkr4d}|| _|| _|| _t	 | _
dS )a  
        Parameters
        ----------
        offset : pair of floats
            The offset of the shadow in points.
        shadow_rgbFace : color
            The shadow color.
        alpha : float
            The alpha transparency of the created shadow patch.
            Default is 0.3.
            http://matplotlib.1069221.n5.nabble.com/path-effects-question-td27630.html
        rho : float
            A scale factor to apply to the rgbFace color if `shadow_rgbFace`
            is not specified. Default is 0.3.
        **kwargs
            Extra keywords are stored and passed through to
            :meth:`AbstractPathEffect._update_gc`.

        Ng333333?)rH   r   _shadow_rgbFacemcolorsto_rgba_alpha_rhorI   r	   r
   _offset_tran)r   r   shadow_rgbFacealpharhor9   )r2   r   r   r      s    zSimplePatchShadow.__init__c             C   s   |  ||}| }|| | jdkr\|p.ddd \}}	}
|| j |	| j |
| j f}n| j}|d || j |d | 	|| j
}||||| |  dS )z
        Overrides the standard draw_path to add the shadow offset and
        necessary color changes for the shadow.

        N)g      ?g      ?g      ?   Znoner   )r   r1   rJ   rT   rX   set_foreground	set_alpharW   r<   r#   rI   r'   rK   )r   r   r    r(   r)   r*   affine0rL   rgbrZ   r   r   r   r'      s    



zSimplePatchShadow.draw_path)rP   NNrS   )r+   r,   r-   r.   r   r'   rM   r   r   )r2   r   rO      s
     (rO   c               @   s   e Zd ZdZdd ZdS )withSimplePatchShadowz
    Adds a simple :class:`SimplePatchShadow` and then draws the
    original Artist to avoid needing to call :class:`Normal`.

    c             C   s(   t | ||||| ||||| d S )N)rO   r'   )r   r   r    r(   r)   r*   r   r   r   r'     s    zwithSimplePatchShadow.draw_pathN)r+   r,   r-   r.   r'   r   r   r   r   rd     s   rd   c                   s*   e Zd ZdZd	 fdd	Zdd Z  ZS )
SimpleLineShadowzA simple shadow via a line.rQ   rR   r!   333333?c                sH   t  | |dkr|| _nt|| _|| _|| _|| _t	 | _
dS )a  
        Parameters
        ----------
        offset : pair of floats
            The offset to apply to the path, in points.
        shadow_color : color
            The shadow color. Default is black.
            A value of ``None`` takes the original artist's color
            with a scale factor of `rho`.
        alpha : float
            The alpha transparency of the created shadow patch.
            Default is 0.3.
        rho : float
            A scale factor to apply to the rgbFace color if `shadow_rgbFace`
            is ``None``. Default is 0.3.
        **kwargs
            Extra keywords are stored and passed through to
            :meth:`AbstractPathEffect._update_gc`.

        N)rH   r   _shadow_colorrU   rV   rW   rX   rI   r	   r
   rY   )r   r   Zshadow_colorr[   r\   r9   )r2   r   r   r   &  s    zSimpleLineShadow.__init__c             C   s   |  ||}| }|| | jdkr`| p2ddd \}}	}
|| j |	| j |
| j f}n| j}d}|| || j | 	|| j
}||||| |  dS )z
        Overrides the standard draw_path to add the shadow offset and
        necessary color changes for the shadow.

        N)g      ?g      ?g      ?r]   )r   r1   rJ   rh   Zget_foregroundrX   r^   r_   rW   r#   rI   r'   rK   )r   r   r    r(   r)   r*   r`   rL   ra   rb   rc   rZ   Z
fill_colorr   r   r   r'   K  s    


zSimpleLineShadow.draw_path)rf   r!   rg   rg   )r+   r,   r-   r.   r   r'   rM   r   r   )r2   r   re   $  s    $re   c                   s*   e Zd ZdZd fdd	Zdd Z  ZS )PathPatchEffectz|
    Draws a :class:`~matplotlib.patches.PathPatch` instance whose Path
    comes from the original PathEffect artist.

    r   r   c                s"   t  j|d tjg f|| _dS )a  
        Parameters
        ----------
        offset : pair of floats
            The offset to apply to the path, in points.
        **kwargs :
            All keyword arguments are passed through to the
            :class:`~matplotlib.patches.PathPatch` constructor. The
            properties which cannot be overridden are "path", "clip_box"
            "transform" and "clip_path".
        )r   N)rH   r   mpatchesZ	PathPatchpatch)r   r   r9   )r2   r   r   r   m  s    zPathPatchEffect.__init__c             C   sX   |  ||}|| j_| j| | j|  | }|rH| jj|  | j| d S )N)	r   rl   _pathZset_transformZset_clip_boxZget_clip_rectangleZget_clip_pathZset_clip_pathZdraw)r   r   r    r(   r)   r*   Z	clip_pathr   r   r   r'   |  s    zPathPatchEffect.draw_path)rj   )r+   r,   r-   r.   r   r'   rM   r   r   )r2   r   ri   g  s   ri   N)r.   Zmatplotlib.backend_basesr   Z
matplotlibr   rU   r   rk   r   r	   rB   r   r%   rE   rF   rN   rO   rd   re   ri   r   r   r   r   <module>   s   :\
GC