o
    l^Uf*                     @   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 n e+y   z
d d$l,m-Z- e&Z*W n e+y   e'Z*Y nw Y nw d%d& Z.d'd( Z/d)d* Z0d+Z1d,d- Z2d.d/ Z3d0d1 Z4d5d3d4Z5d	S )6    )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$   Flib/python3.10/site-packages/fontTools/varLib/interpolatableHelpers.pyr      s0    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)Zproblemsr$   r$   r%   sort_problems,   s   r3   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   r6   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%   r9   C   s
   
zPerContourPen.__init__c                 C   s   |    | j| d S r8   )_newItemr;   ZmoveTo)r=   p0r$   r$   r%   _moveToJ   s   zPerContourPen._moveToc                 C   s   | j | d S r8   )r;   ZlineTo)r=   p1r$   r$   r%   _lineToN   s   zPerContourPen._lineToc                 C   s   | j || d S r8   )r;   ZqCurveTo)r=   rA   p2r$   r$   r%   _qCurveToOneQ   s   zPerContourPen._qCurveToOnec                 C   s   | j ||| d S r8   )r;   ZcurveTo)r=   rA   rC   Zp3r$   r$   r%   _curveToOneT   s   zPerContourPen._curveToOnec                 C      | j   d | _ d S r8   )r;   Z	closePathr=   r$   r$   r%   
_closePathW      

zPerContourPen._closePathc                 C   rF   r8   )r;   endPathrG   r$   r$   r%   _endPath[   rI   zPerContourPen._endPathc                 C   s   |    | _}| j| d S r8   )r:   r;   r<   append)r=   Zpenr$   r$   r%   r>   _   s   zPerContourPen._newItemr8   )r   r    r!   r9   r@   rB   rD   rE   rH   rK   r>   r$   r$   r$   r%   r7   B   s    
r7   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%   rO   e   s   z%PerContourOrComponentPen.addComponentN)r   r    r!   rO   r$   r$   r$   r%   rM   d   s    rM   c                   @   s2   e Zd Zdd ZdddZdddZdd	d
ZdS )SimpleRecordingPointPenc                 C   s
   g | _ d S r8   )r<   rG   r$   r$   r%   r9   k   s   
z SimpleRecordingPointPen.__init__Nc                 K      d S r8   r$   )r=   Z
identifierkwargsr$   r$   r%   	beginPathn      z!SimpleRecordingPointPen.beginPathreturnc                 C   rQ   r8   r$   rG   r$   r$   r%   rJ   q   rT   zSimpleRecordingPointPen.endPathc                 C   s    | j ||d u r
dndf d S )NFT)r<   rL   )r=   ptZsegmentTyper$   r$   r%   addPointt   s    z SimpleRecordingPointPen.addPointr8   )rU   N)r   r    r!   r9   rS   rJ   rW   r$   r$   r$   r%   rP   j   s
    

rP   c                 C   s0   d}t | |D ]\}}|| }||| 7 }q|S Nr   )zipv0v1sZx0Zx1dr$   r$   r%   vdiff_hypot2x   s
   r_   c                 C   s@   d}t | |D ]\}}|| }||j|j |j|j  7 }q|S rX   )rY   realimagrZ   r$   r$   r%   vdiff_hypot2_complex   s
   rb   c                    s   t  fddt|D S )Nc                 3   s     | ]\}} | | V  qd S r8   r$   )r(   ijGr$   r%   r*      s    z matching_cost.<locals>.<genexpr>)sum	enumerate)rf   matchingr$   re   r%   matching_cost   s   rj   c                 C   sP   t | }t| \}}|tt|k sJ tdd |D }t|t| |fS )Nc                 s   s    | ]}t |V  qd S r8   )int)r(   er$   r$   r%   r*          z<min_cost_perfect_bipartite_matching_scipy.<locals>.<genexpr>)lenlinear_sum_assignmentlistrangeallrj   )rf   nrowscolsr$   r$   r%   )min_cost_perfect_bipartite_matching_scipy   s
   rv   c                 C   s>   t | }d g| }t | D ]\}}|||< q|t| |fS r8   )rn   MunkresZcomputerj   )rf   rs   ru   rowcolr$   r$   r%   +min_cost_perfect_bipartite_matching_munkres   s
   

rz   c                 C   sn   t | }|dkrtdtt|}tt|}t| |}|D ]}t| |}||k r2t||}}q ||fS )Nr   z4Install Python module 'munkres' or 'scipy >= 0.17.0')rn   	Exception	itertoolspermutationsrq   rp   nextrj   )rf   rs   r}   ZbestZ	best_costr)   Zcostr$   r$   r%   .min_cost_perfect_bipartite_matching_bruteforce   s   

r   )ro   )rw   c                 C   s<   t t| j}t|| j| j| j| jd | jd | j| fS )Nr   )	r   absZ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(   r\   r[   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 r8   r$   )r(   rc   )costsr$   r%   r*          z'matching_for_vectors.<locals>.<genexpr>)rn   rp   rq   #min_cost_perfect_bipartite_matchingrg   )Zm0r   rs   Zidentity_matchingri   rj   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bitsrV   br$   r$   r%   points_characteristic_bits   s   r   r   c           
      C   s  g }| s|S dd | D } t | }tdksJ | | d td   t | tk r9| | d td   t | tk s(t|D ]I}| | }|| | |d  }|| }||d  | |d  }|| }|||  |j|j |j|j  }	ttt	|	|	}	||	d  q=|S )Nc                 S   s   g | ]\}}t | qS r$   )complex)r(   rV   r,   r$   r$   r%   r      s    z)points_complex_vector.<locals>.<listcomp>r   r   r   r   )
rn   $_NUM_ITEMS_PER_POINTS_COMPLEX_VECTORextendrq   rL   r`   ra   r   r   r   )
r   vectorrs   rc   r?   rA   Zd0rC   Zd1Zcrossr$   r$   r%   points_complex_vector   s.   
r   c                 C   s   t | }t| }|r| d d d } t | }n|}t| }t|| dks&J t|| }d|> d }t|D ](}	|||	 > |@ ||	? B }
|
|kr^|t||	 | |rY|d |	 n|	|f q6d S )NrN   r   r   )r   rn   r   rq   rL   r6   )r   Zisomorphismsr/   Zreference_bitsrs   r   r   Zmultmaskrc   r   r$   r$   r%   add_isomorphisms  s$   
$r   c                    s  d gt tt| d  }t tt| }rdd tD }|r0t|}td||  nd}td zddlm	} fdd	ttD }t
  D ]	} |  qPt   fd
d	D }	tttdD ]\}
}t|	|
 |	| ||
 |< qq||}| \}}tt
}t||D ]\}}|| | || | qd gt }g }t
 }t|g}|r| }
||
 ||
 t||
 D ]}||vr|
||< || q|sW n	 ty   Y nw td| td| ||fS )Nr   c                 s   s.    | ]\}}t d d | D r|V  qdS )c                 s   s    | ]}|d kV  qdS r   Nr$   )r(   vr$   r$   r%   r*   -  rm   z3find_parents_and_order.<locals>.<genexpr>.<genexpr>N)rr   values)r(   rc   r4   r$   r$   r%   r*   -  s   , z)find_parents_and_order.<locals>.<genexpr>z!Base master index %s, location %sr   zNo base master location found)minimum_spanning_treec                    s   g | ]	}d gt   qS )r   )rn   )r(   r,   )	locationsr$   r%   r   9  s    z*find_parents_and_order.<locals>.<listcomp>c                    s"   g | ] t  fd dD qS )c                 3   s    | ]	}  |d V  qdS r   )r'   )r(   r5   r4   r$   r%   r*   >  r   z4find_parents_and_order.<locals>.<listcomp>.<genexpr>)tupler   )axesr   r%   r   >  s   " r   zParents: %sz	Order: %s)rp   rq   rn   rh   r~   logginginfoZwarningZscipy.sparse.csgraphr   setupdatekeysr1   r|   combinationsr_   Znonzeror   rY   addr   popleftrL   ImportErrorlog)Z	glyphsetsr   parentsZorderbasesbaser   Zgraphr4   Zvectorsrc   rd   Ztreert   ru   rx   ry   Zvisitedqueuer$   )r   r   r%   find_parents_and_order(  s\   




	r   Fc           
      C   s   | j }| j}| j}|| d d ||  d }|| d | }|| d | }|dkr2t|| |n	||k r:td nd}t }	|dk rEd}|rg|	| j | j }	|		| }	|	
dt| dt| }	|	S |	
t|t|}	|		|}	|	| j| j}	|	S )Ng      ?r   r   r   )Z	varianceXZ
covarianceZ	varianceYr   r   r
   	translater   r   rotateZscaler   )
r   Zinversear   cZdeltaZlambda1Zlambda2ZthetaZtransr$   r$   r%   transform_from_stats_  s&   *	
r   )F)6Z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   Zmathr   r   r   r   enumr   r|   r   Z	getLoggerr   r   r3   r6   r7   rM   rP   r_   rb   rj   rv   rz   r   Zscipy.optimizero   r   r   Zmunkresrw   r   r   r   r   r   r   r   r   r$   r$   r$   r%   <module>   sZ    
"

$7