a
    èÝEbñ0  ã                   @   sÔ   d Z ddlmZmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlZddl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d„Zddd„ZedkrÐddlZeƒ Ze eeeƒƒ¡ dS )z¯
Tool to find wrong contour order between different masters, and
other interpolatability (or lack thereof) issues.

Call as:
$ fonttools varLib.interpolatable font1 font2 ...
é    )ÚAbstractPenÚBasePen)ÚRecordingPen)ÚStatisticsPen)ÚOpenContourError)ÚOrderedDictNc                   @   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PenÚglyphset© r   ú_/home/ja/django-apps/lartica_env/lib/python3.9/site-packages/fontTools/varLib/interpolatable.pyr
      s
    zPerContourPen.__init__c                 C   s   |   ¡  | j |¡ d S r	   )Ú_newItemr   ZmoveTo)r   Úp0r   r   r   Ú_moveTo   s    zPerContourPen._moveToc                 C   s   | j  |¡ d S r	   )r   ZlineTo)r   Úp1r   r   r   Ú_lineTo   s    zPerContourPen._lineToc                 C   s   | j  ||¡ d S r	   )r   ZqCurveTo)r   r   Úp2r   r   r   Ú_qCurveToOne!   s    zPerContourPen._qCurveToOnec                 C   s   | j  |||¡ d S r	   )r   ZcurveTo)r   r   r   Zp3r   r   r   Ú_curveToOne$   s    zPerContourPen._curveToOnec                 C   s   | j  ¡  d | _ d S r	   )r   Z	closePath©r   r   r   r   Ú
_closePath'   s    
zPerContourPen._closePathc                 C   s   | j  ¡  d | _ d S r	   )r   ZendPathr   r   r   r   Ú_endPath+   s    
zPerContourPen._endPathc                 C   s   |   ¡  | _}| j |¡ d S r	   )r   r   r   Úappend)r   Úpenr   r   r   r   /   s    zPerContourPen._newItem)N)Ú__name__Ú
__module__Ú__qualname__r
   r   r   r   r   r   r   r   r   r   r   r   r      s   
r   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   r$   5   s    z%PerContourOrComponentPen.addComponentN)r   r    r!   r$   r   r   r   r   r"   4   s   r"   c                 C   s   t dd„ t| |ƒD ƒƒS )Nc                 s   s   | ]\}}|| V  qd S r	   r   )Ú.0ÚaÚbr   r   r   Ú	<genexpr>;   ó    z_vdiff.<locals>.<genexpr>)ÚtupleÚzip)Úv0Úv1r   r   r   Ú_vdiff:   s    r.   c                 C   s   d}| D ]}||| 7 }q|S )Nr   r   )ZvecÚvÚxr   r   r   Ú_vlen>   s    r1   c                    s   t ‡ fdd„t|ƒD ƒƒS )Nc                 3   s   | ]\}}ˆ | | V  qd S r	   r   )r%   ÚiÚj©ÚGr   r   r(   F   r)   z!_matching_cost.<locals>.<genexpr>)ÚsumÚ	enumerate)r5   Úmatchingr   r4   r   Ú_matching_costE   s    r9   c                 C   s  t | ƒ}zDddlm} || ƒ\}}|tt|ƒƒk ¡ s:J ‚t|ƒt| |ƒfW S  ty^   Y n0 zDddlm	} d g| }|ƒ  
| ¡D ]\}}|||< q„|t| |ƒfW S  ty¶   Y n0 |dkrÈtdƒ‚t t|ƒ¡}tt|ƒƒ}	t| |	ƒ}
|D ]$}t| |ƒ}||
k rðt|ƒ| }	}
qð|	|
fS )Nr   )Úlinear_sum_assignment)ÚMunkresé   z4Install Python module 'munkres' or 'scipy >= 0.17.0')ÚlenZscipy.optimizer:   ÚlistÚrangeÚallr9   ÚImportErrorZmunkresr;   ZcomputeÚ	ExceptionÚ	itertoolsÚpermutationsÚnext)r5   Únr:   ÚrowsÚcolsr;   ÚrowÚcolrD   ÚbestZ	best_costÚpZcostr   r   r   Ú#min_cost_perfect_bipartite_matchingI   s4    



rM   c           #         s:  |d u r| }|d u r | d   ¡ }g }tƒ ‰‡fdd„}|D �]ø}�z¸g }g }t| |ƒD �]H\}}	||vrz||d|	dœƒ qV|| }
tt|d�}|
 |¡ |j}~g }g }| |¡ | |¡ t|ƒD ]Ú\}}| t	dd„ |jD ƒƒ¡ t
|d�}z| |¡ W nD t�yB } z*|||	|d	d
œƒ W Y d }~qÄW Y d }~n
d }~0 0 t|jƒd d }t|ƒt|jƒt|jƒt|jd ƒt|jd ƒt|j| ƒf}| |¡ qÄqVtt|d d… |dd … ƒƒD �]\}\}‰ t|ƒtˆ ƒk�r
||d|| ||d  t|ƒtˆ ƒdœƒ |ˆ k�r�qÀtt|ˆ ƒƒD ]°\}\}}||k�r@�q&t|ƒt|ƒk�r‚||d||| ||d  t|ƒt|ƒdœƒ �q&tt||ƒƒD ]B\}\}}||k�r�||d|||| ||d  ||dœƒ �q��q��q&�qÀtt|d d… |dd … ƒƒD ]ü\}\}‰ t|ƒtˆ ƒk�r�qú|�s&�qú‡ fdd„|D ƒ}t|ƒ\}}|ttt|ƒƒƒk�rŽ||d|| ||d  ttt|ƒƒƒ|dœƒ  �qød} t|t|ƒ t|d ƒ d |  d ƒ}!| |!¡ d}"|!|"k�rú||d|| ||d  |!|"dœƒ �qúW q: t�y2 } z||d|	|dœƒ W Y d }~q:d }~0 0 q:ˆS )Nr   c                    s   ˆ   | g ¡ |¡ d S r	   )Ú
setdefaultr   )Z	glyphnameÚproblem)Úproblemsr   r   Úadd_problemv   s    ztest.<locals>.add_problemÚmissing)ÚtypeÚmaster)r   c                 s   s   | ]}|d  V  qdS )r   Nr   )r%   Zinstructionr   r   r   r(   ”   r)   ztest.<locals>.<genexpr>Ú	open_path)rT   ÚcontourrS   g      à?é   r#   é   Ú
path_count)rS   Úmaster_1Úmaster_2Úvalue_1Úvalue_2Ú
node_count)rS   ÚpathrZ   r[   r\   r]   Únode_incompatibility)rS   r_   ÚnoderZ   r[   r\   r]   c                    s   g | ]‰ ‡ fd d„ˆD ƒ‘qS )c                    s   g | ]}t tˆ |ƒƒ‘qS r   )r1   r.   )r%   r-   ©r,   r   r   Ú
<listcomp>à   r)   z#test.<locals>.<listcomp>.<listcomp>r   )r%   )Úm1rb   r   rc   à   r)   ztest.<locals>.<listcomp>Úcontour_orderi   éd   é   Ú	high_costZ
math_error)rS   rT   Úerror)Úkeysr   r+   r"   r   Zdrawr   r   r7   r*   r   Zreplayr   ÚabsÚareaÚintZmeanXZmeanYZstddevXZstddevYZcorrelationr=   rM   r>   r?   ÚroundÚ
ValueError)#Ú	glyphsetsÚglyphsÚnamesÚhistrQ   Z
glyph_nameZ
allVectorsZallNodeTypesr   ÚnameÚglyphZperContourPenZcontourPensZcontourVectorsZ	nodeTypesÚixrV   ÚstatsÚeÚsizeZvectorr2   Zm0ZpathIxZnodes1Znodes2ZnodeIxZn1Zn2Zcostsr8   Zmatching_costZupemZ	item_costÚ	thresholdr   )rd   rP   r   Útestl   s   
ÿ


ÿ

þ"ú,
ûþ



úþ

ùþ*
ûþ
"ÿ


ûþ
þr{   c                    s~  ddl }|jdtjd�}|jdddd� |jd	d
tddd� | | ¡} d}ddlm‰  ‡ fdd„| j	D ƒ}g }| j	D ]D}| 
d¡ržddlm} | ||ƒ¡ qtddlm} | ||ƒ¡ qtdd„ |D ƒ}	t|	||d�}
| jröddl}t| |
¡ƒ �nz|
 ¡ D �]n\}}td|› d�ƒ |D �]N}|d dk�r@td|d  ƒ |d dk�r^td|d  ƒ |d dk�r�td|d  |d! |d" |d# f ƒ |d d$k�rÈtd%|d& |d  |d! |d" |d# f ƒ |d d'k�rtd(|d) |d& |d  |d! |d" |d# f ƒ |d d*k�r8td+|d  |d! |d" |d# f ƒ |d d,k�rtd-|d! |d# |d  |d" f ƒ �qqþ|
�rz|
S dS ).z/Test for interpolatability issues between fontsr   Nzfonttools varLib.interpolatable)Údescriptionz--jsonÚ
store_truezOutput report in JSON format)ÚactionÚhelpÚinputsÚFILEú+zInput TTF/UFO files)ÚmetavarrS   Únargsr   ©Úbasenamec                    s    g | ]}ˆ |ƒ  d d¡d ‘qS )Ú.rX   r   )Úrsplit)r%   Úfilenamer…   r   r   rc   !  r)   zmain.<locals>.<listcomp>z.ufo)Ú	UFOReader)ÚTTFontc                 S   s   g | ]}|  ¡ ‘qS r   )ZgetGlyphSet)r%   Úfontr   r   r   rc   .  r)   )rq   rr   zGlyph z was not compatible: rS   rR   z"    Glyph was missing in master %srT   rU   z'    Glyph has an open path in master %srY   z*    Path count differs: %i in %s, %i in %sr\   rZ   r]   r[   r^   z5    Node count differs in path %i: %i in %s, %i in %sr_   r`   z7    Node %o incompatible in path %i: %s in %s, %s in %sra   re   z-    Contour order differs: %s in %s, %s in %srh   zD    Interpolation has high cost: cost of %s to %s = %i, threshold %i)ÚargparseÚArgumentParserÚmainÚ__doc__Úadd_argumentÚstrÚ
parse_argsÚos.pathr†   r€   ÚendswithZfontTools.ufoLibrŠ   r   ZfontTools.ttLibr‹   r{   ÚjsonÚprintÚdumpsÚitems)Úargsr�   Úparserrq   rr   Zfontsr‰   rŠ   r‹   rp   rP   r–   ru   Zglyph_problemsrL   r   r…   r   r�     s®    þý
ÿ



ÿÿûÿÿ
úÿÿüÿÿ	üÿÿ
	r�   Ú__main__)NN)N)r�   ZfontTools.pens.basePenr   r   ZfontTools.pens.recordingPenr   ZfontTools.pens.statisticsPenr   ZfontTools.pens.momentsPenr   Úcollectionsr   rC   Úsysr   r"   r.   r1   r9   rM   r{   r�   r   rP   Úexitrm   Úboolr   r   r   r   Ú<module>   s(   "#
 
h