U
    #vh,                     @   s  d dl mZ d dlmZmZmZ d dlmZmZ 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 d dlmZ d d	lZd d	lZed
ZG dd dZdd Zdd ZG dd deZG dd deZ G dd deZ!dd Z"dd Z#dd Z$dd Z%dd  Z&d!d" Z'zd d#l(m)Z) e%Z*W nF e+k
rr   zd d$l,m-Z- e&Z*W n e+k
rl   e'Z*Y nX Y nX d%d& Z.d'd( Z/d)d* Z0d+Z1d,d- Z2d.d/ Z3e4 d0d1d2Z5d6d4d5Z6d	S )7    )LerpGlyphSet)AbstractPenBasePenDecomposingPen)AbstractPointPenSegmentToPointPen)RecordingPenDecomposingRecordingPen)	Transform)defaultdictdeque)sqrtcopysignatan2pi)EnumNzfontTools.varLib.interpolatablec                   @   sh   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZededededede	de
dedededediZdS )InterpolatableProblemZnothingmissingZ	open_pathZ
path_countZ
node_countZnode_incompatibilityZcontour_orderZwrong_start_pointZkinkZunderweightZ
overweight                        	   
      N)__name__
__module____qualname__ZNOTHINGMISSINGZ	OPEN_PATHZ
PATH_COUNTZ
NODE_COUNTZNODE_INCOMPATIBILITYZCONTOUR_ORDERZWRONG_START_POINTZKINKZUNDERWEIGHTZ
OVERWEIGHTseverity r$   r$   J/tmp/pip-unpacked-wheel-1ufboor8/fontTools/varLib/interpolatableHelpers.pyr      sD              r   c                 C   s   t t|  dd ddS )zGSort problems by severity, then by glyph name, then by problem message.c                 S   s   t dd | d D  S )Nc                 s   s(   | ] }t j|d   |dd V  qdS )typeZ	tolerancer   N)r   r#   get).0pr$   r$   r%   	<genexpr>2   s   z2sort_problems.<locals>.<lambda>.<locals>.<genexpr>r   )min)_r$   r$   r%   <lambda>1   s   zsort_problems.<locals>.<lambda>T)keyreverse)dictsorteditems)problemsr$   r$   r%   sort_problems,   s    r4   c                 C   s   | | d | d|   S )z{Rotate list by k items forward.  Ie. item at position 0 will be
    at position k in returned list.  Negative k is allowed.Nr$   )lkr$   r$   r%   rot_list<   s    r7   c                   @   sN   e Zd ZdddZdd Zdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dS )PerContourPenNc                 C   s(   t | | || _|| _d | _g | _d S N)r   __init__Z	_glyphset_Pen_penvalue)selfZPenZglyphsetr$   r$   r%   r:   C   s
    zPerContourPen.__init__c                 C   s   |    | j| d S r9   )_newItemr<   ZmoveTo)r>   p0r$   r$   r%   _moveToJ   s    zPerContourPen._moveToc                 C   s   | j | d S r9   )r<   ZlineTo)r>   p1r$   r$   r%   _lineToN   s    zPerContourPen._lineToc                 C   s   | j || d S r9   )r<   ZqCurveTo)r>   rB   p2r$   r$   r%   _qCurveToOneQ   s    zPerContourPen._qCurveToOnec                 C   s   | j ||| d S r9   )r<   ZcurveTo)r>   rB   rD   Zp3r$   r$   r%   _curveToOneT   s    zPerContourPen._curveToOnec                 C   s   | j   d | _ d S r9   )r<   Z	closePathr>   r$   r$   r%   
_closePathW   s    
zPerContourPen._closePathc                 C   s   | j   d | _ d S r9   )r<   endPathrG   r$   r$   r%   _endPath[   s    
zPerContourPen._endPathc                 C   s   |    | _}| j| d S r9   )r;   r<   r=   append)r>   Zpenr$   r$   r%   r?   _   s    zPerContourPen._newItem)N)r   r    r!   r:   rA   rC   rE   rF   rH   rJ   r?   r$   r$   r$   r%   r8   B   s   
r8   c                   @   s   e Zd Zdd ZdS )PerContourOrComponentPenc                 C   s   |    | jd || d S )N)r?   r=   addComponent)r>   Z	glyphNameZtransformationr$   r$   r%   rN   e   s    z%PerContourOrComponentPen.addComponentN)r   r    r!   rN   r$   r$   r$   r%   rL   d   s   rL   c                   @   s6   e Zd Zdd ZdddZddddZdd	d
ZdS )SimpleRecordingPointPenc                 C   s
   g | _ d S r9   )r=   rG   r$   r$   r%   r:   k   s    z SimpleRecordingPointPen.__init__Nc                 K   s   d S r9   r$   )r>   
identifierkwargsr$   r$   r%   	beginPathn   s    z!SimpleRecordingPointPen.beginPath)returnc                 C   s   d S r9   r$   rG   r$   r$   r%   rI   q   s    zSimpleRecordingPointPen.endPathc                 C   s    | j ||d krdndf d S )NFT)r=   rK   )r>   ptZsegmentTyper$   r$   r%   addPointt   s    z SimpleRecordingPointPen.addPoint)N)N)r   r    r!   r:   rR   rI   rU   r$   r$   r$   r%   rO   j   s   
rO   c                 C   s0   d}t | |D ]\}}|| }||| 7 }q|S Nr   )zipv0v1sZx0x1dr$   r$   r%   vdiff_hypot2x   s
    r^   c                 C   s@   d}t | |D ],\}}|| }||j|j |j|j  7 }q|S rV   )rW   realimagrX   r$   r$   r%   vdiff_hypot2_complex   s
    ra   c                    s   t  fddt|D S )Nc                 3   s   | ]\}} | | V  qd S r9   r$   )r(   ijGr$   r%   r*      s     z matching_cost.<locals>.<genexpr>)sum	enumerate)re   matchingr$   rd   r%   matching_cost   s    ri   c                 C   sP   t | }t| \}}|tt|k s,ttdd |D }t|t| |fS )Nc                 s   s   | ]}t |V  qd S r9   )int)r(   er$   r$   r%   r*      s     z<min_cost_perfect_bipartite_matching_scipy.<locals>.<genexpr>)lenlinear_sum_assignmentlistrangeallAssertionErrorri   )re   nrowscolsr$   r$   r%   )min_cost_perfect_bipartite_matching_scipy   s
    ru   c                 C   s>   t | }d g| }t | D ]\}}|||< q|t| |fS r9   )rl   MunkresZcomputeri   )re   rr   rt   rowcolr$   r$   r%   +min_cost_perfect_bipartite_matching_munkres   s
    

ry   c                 C   sn   t | }|dkrtdtt|}tt|}t| |}|D ]$}t| |}||k r@t|| }}q@||fS )Nr   z4Install Python module 'munkres' or 'scipy >= 0.17.0')rl   	Exception	itertoolspermutationsro   rn   nextri   )re   rr   r|   bestZ	best_costr)   Zcostr$   r$   r%   .min_cost_perfect_bipartite_matching_bruteforce   s    

r   )rm   )rv   c                 C   s<   t t| j}t|| j| j| j| jd | jd | j| fS )Nr   )	r   absarear   meanXmeanYZstddevXZstddevYZcorrelation)statssizer$   r$   r%   contour_vector_from_stats   s    
r   c                    sV   t | }tt|}fdd| D  t \}}t fddt|D }|||fS )Nc                    s   g | ]  fd dD qS )c                    s   g | ]}t  |qS r$   )r^   )r(   rZ   rY   r$   r%   
<listcomp>   s     z3matching_for_vectors.<locals>.<listcomp>.<listcomp>r$   r(   )m1r   r%   r      s     z(matching_for_vectors.<locals>.<listcomp>c                 3   s   | ]} | | V  qd S r9   r$   )r(   rb   )costsr$   r%   r*      s     z'matching_for_vectors.<locals>.<genexpr>)rl   rn   ro   #min_cost_perfect_bipartite_matchingrf   )Zm0r   rr   Zidentity_matchingrh   ri   Zidentity_costr$   )r   r   r%   matching_for_vectors   s    r   c                 C   s&   d}t | D ]\}}|d> |B }q|S )Nr   r   )reversed)pointsbitsrT   br$   r$   r%   points_characteristic_bits   s    r   r   c           
      C   s  g }| s|S dd | D } t | }tdks.t| | d td   t | tk rh| | d td   qDt|D ]}| | }|| | |d  }|| }||d  | |d  }|| }|||  |j|j |j|j  }	tt	t
|	|	}	||	d  qp|S )Nc                 S   s   g | ]\}}t | qS r$   )complex)r(   rT   r,   r$   r$   r%   r      s     z)points_complex_vector.<locals>.<listcomp>r   r   r   r   )rl   $_NUM_ITEMS_PER_POINTS_COMPLEX_VECTORrq   extendro   rK   r_   r`   r   r   r   )
r   vectorrr   rb   r@   rB   Zd0rD   d1Zcrossr$   r$   r%   points_complex_vector   s,    
r   c                 C   s   t | }t| }|r,| d d d } t | }n|}t| }t|| dksLtt|| }d|> d }t|D ]P}	|||	 > |@ ||	? B }
|
|krl|t||	 | |r|d |	 n|	|f qld S )NrM   r   r   )r   rl   r   rq   ro   rK   r7   )r   Zisomorphismsr/   Zreference_bitsrr   r   r   Zmultmaskrb   r   r$   r$   r%   add_isomorphisms  s     
$r   discrete_axesc                   sb  d gt tt| d  }t tt| }rZfddtD }|r^tdt|| n
td zddlm} fddttD }t	  D ]} 
|  qt   fd	dD }	tttd
D ]f\}
}fddt |	|
 D }fddt |	| D }||kr*qt|	|
 |	| ||
 |< q||dd}| \}}tt	}t||D ]&\}}|| | || | qpd gt }g }t	 }t|}|r| }
||
 ||
 t||
 D ]"}||kr|
||< || qqt|t|ks(tdW n tk
r@   Y nX td| td| ||fS )Nr   c                    s.   g | ]&\}}t  fd d| D r|qS )c                 3   s"   | ]\}}| kr|d kV  qdS r   Nr$   r(   r6   vr   r$   r%   r*   0  s      4find_parents_and_order.<locals>.<listcomp>.<genexpr>)rp   r2   )r(   rb   r5   r   r$   r%   r   -  s   z*find_parents_and_order.<locals>.<listcomp>zFound %s base masters: %szNo base master location foundr   )minimum_spanning_treec                    s   g | ]}d gt   qS )r   )rl   )r(   r,   )	locationsr$   r%   r   ;  s     c                    s"   g | ] t  fd dD qS )c                 3   s   | ]}  |d V  qdS r   )r'   )r(   r6   r5   r$   r%   r*   @  s     r   )tupler   )axesr   r%   r   @  s     r   c                    s   i | ]\}}| kr||qS r$   r$   r   r   r$   r%   
<dictcomp>B  s      z*find_parents_and_order.<locals>.<dictcomp>c                    s   i | ]\}}| kr||qS r$   r$   r   r   r$   r%   r   E  s      T)	overwritez.Not all masters are reachable; report an issuezParents: %sz	Order: %s)rn   ro   rl   rg   logginginfowarningZscipy.sparse.csgraphr   setupdatekeysr1   r{   combinationsrW   r^   Znonzeror   addr   popleftrK   rq   ImportErrorlog)Z	glyphsetsr   r   parentsorderbasesr   graphr5   Zvectorsrb   rc   Zi_discrete_locationZj_discrete_locationtreers   rt   rw   rx   visitedqueuer$   )r   r   r   r%   find_parents_and_order(  sn    








r   Fc           
      C   s   | j }| j}| j}|| d d ||  d }|| d | }|| d | }|dkrdt|| |n||k rttd nd}t }	|dk rd}|r|	| j | j }	|		| }	|	
dt| dt| }	n.|	
t|t|}	|		|}	|	| j| j}	|	S )Ng      ?r   r   r   )Z	varianceXZ
covarianceZ	varianceYr   r   r
   	translater   r   rotateZscaler   )
r   Zinversear   cdeltaZlambda1Zlambda2thetaZtransr$   r$   r%   transform_from_statsl  s$    *	
r   )F)7ZfontTools.ttLib.ttGlyphSetr   ZfontTools.pens.basePenr   r   r   ZfontTools.pens.pointPenr   r   ZfontTools.pens.recordingPenr   r	   ZfontTools.misc.transformr
   collectionsr   r   mathr   r   r   r   enumr   r{   r   	getLoggerr   r   r4   r7   r8   rL   rO   r^   ra   ri   ru   ry   r   Zscipy.optimizerm   r   r   Zmunkresrv   r   r   r   r   r   r   r   r   r   r$   r$   r$   r%   <module>   sR   
"

$D