o
    a0                     @   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rjddlZe Zeeee dS 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   A/usr/lib/python3/dist-packages/fontTools/varLib/interpolatable.pyr
      s
   
zPerContourPen.__init__c                 C   s   |    | j| d S r	   )_newItemr   ZmoveTo)r   Z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      | j   d | _ d S r	   )r   Z	closePathr   r   r   r   
_closePath'      

zPerContourPen._closePathc                 C   r   r	   )r   ZendPathr   r   r   r   _endPath+   r   zPerContourPen._endPathc                 C   s   |    | _}| j| d S r	   )r   r   r   append)r   Zpenr   r   r   r   /   s   zPerContourPen._newItemr	   )__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>;   s    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   r0   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   s    z!_matching_cost.<locals>.<genexpr>)sum	enumerate)r4   matchingr   r3   r   _matching_costE   s   r8   c                 C   s  t | }z"ddlm} || \}}|tt|k sJ t|t| |fW S  ty/   Y nw z"ddlm	} d g| }| 
| D ]\}}|||< qB|t| |fW S  ty[   Y nw |dkrdtdtt|}tt|}	t| |	}
|D ]}t| |}||
k rt||}	}
qx|	|
fS )Nr   )linear_sum_assignment)Munkres   z4Install Python module 'munkres' or 'scipy >= 0.17.0')lenZscipy.optimizer9   listrangeallr8   ImportErrorZmunkresr:   Zcompute	Exception	itertoolspermutationsnext)r4   nr9   ZrowsZcolsr:   rowcolrC   ZbestZ	best_costpZcostr   r   r   #min_cost_perfect_bipartite_matchingI   s:   



rI   c           #         s  |d u r| }|d u r| d   }g }t fdd}|D ]}zg }g }t| |D ]\}}	||vr<||d|	d q+|| }
tt|d}|
| |j}~g }g }|| || t|D ]f\}}|t	dd |jD  t
|d}z|| W n ty } z|||	|d	d
 W Y d }~qad }~ww t|jd d }t|t|jt|jt|jd t|jd t|j| f}|| qaq+tt|d d |dd  D ]\}\} t|t kr||d|| ||d  t|t d | krqtt| D ]X\}\}}||krqt|t|kr6||d||| ||d  t|t|d qtt||D ]!\}\}}||kr]||d|||| ||d  ||d q=q=qqtt|d d |dd  D ]}\}\} t|t krqq|sqq fdd|D }t|\}}|ttt|kr||d|| ||d  ttt||d  n5d} t|t| t|d  d |  d }!||! d}"|!|"kr||d|| ||d  |!|"d qqW q ty } z||d|	|d W Y d }~qd }~ww S )Nr   c                    s     | g | d S r	   )
setdefaultr   )Z	glyphnameZ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(      s    ztest.<locals>.<genexpr>	open_path)rO   contourrN   g      ?   r#      
path_count)rN   master_1master_2value_1value_2
node_count)rN   pathrU   rV   rW   rX   node_incompatibility)rN   rZ   noderU   rV   rW   rX   c                    s   g | ]  fd dD qS )c                    s   g | ]	}t t |qS r   )r0   r-   )r%   r,   r+   r   r   
<listcomp>   s    z#test.<locals>.<listcomp>.<listcomp>r   )r%   )m1r]   r   r^      s    ztest.<locals>.<listcomp>contour_orderi   d      	high_costZ
math_error)rN   rO   error)keysr   r*   r"   r   Zdrawr   r   r6   r)   r   Zreplayr   absZareaintZmeanXZmeanYZstddevXZstddevYZcorrelationr<   rI   r=   r>   round
ValueError)#	glyphsetsglyphsnamesZhistrL   Z
glyph_nameZ
allVectorsZallNodeTypesr   nameglyphZperContourPenZcontourPensZcontourVectorsZ	nodeTypesZixrQ   ZstatsesizeZvectorr1   Zm0ZpathIxZnodes1Znodes2ZnodeIxZn1Zn2Zcostsr7   Zmatching_costZupemZ	item_costZ	thresholdr   )r_   rK   r   testl   s  





*






* 

"



rq   c                    sl  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rOddlm} ||| q:ddlm} ||| q:dd |D }	t|	||d}
| jrzddl}t||
 n|
 D ]\}}td| d |D ]}|d dkrtd|d   |d dkrtd|d   |d dkrtd|d  |d! |d" |d# f  |d d$krtd%|d& |d  |d! |d" |d# f  |d d'krtd(|d) |d& |d  |d! |d" |d# f  |d d*krtd+|d  |d! |d" |d# f  |d d,kr-td-|d! |d# |d  |d" f  qq~|
r4|
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inputsZFILE+zInput TTF/UFO files)metavarrN   nargsru   basenamec                    s    g | ]} | d dd qS ).rS   r   )rsplit)r%   filenamerz   r   r   r^   !  s     zmain.<locals>.<listcomp>z.ufo)	UFOReader)TTFontc                 S   s   g | ]}|  qS r   )ZgetGlyphSet)r%   Zfontr   r   r   r^   .  s    )rk   rl   zGlyph z was not compatible: rN   rM   z"    Glyph was missing in master %srO   rP   z'    Glyph has an open path in master %srT   z*    Path count differs: %i in %s, %i in %srW   rU   rX   rV   rY   z5    Node count differs in path %i: %i in %s, %i in %srZ   r[   z7    Node %o incompatible in path %i: %s in %s, %s in %sr\   r`   z-    Contour order differs: %s in %s, %s in %src   zD    Interpolation has high cost: cost of %s to %s = %i, threshold %i)argparseArgumentParsermain__doc__add_argumentstr
parse_argsos.pathr{   rv   endswithZfontTools.ufoLibr   r   ZfontTools.ttLibr   rq   jsonprintdumpsitems)argsr   parserrk   rl   Zfontsr~   r   r   rj   rK   r   rn   Zglyph_problemsrH   r   rz   r   r     s   




	5r   __main__)NNr	   )r   ZfontTools.pens.basePenr   r   ZfontTools.pens.recordingPenr   ZfontTools.pens.statisticsPenr   ZfontTools.pens.momentsPenr   collectionsr   rB   sysr   r"   r-   r0   r8   rI   rq   r   r   rK   exitrg   boolr   r   r   r   <module>   s,    "
# 
h