a
    ׶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rd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   o/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-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   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   Z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    r/   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)r3   matchingr   r2   r   _matching_costE   s    r7   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rtdtt|}tt|}	t| |	}
|D ]$}t| |}||
k rt|| }	}
q|	|
fS )Nr   )linear_sum_assignment)Munkres   z4Install Python module 'munkres' or 'scipy >= 0.17.0')lenZscipy.optimizer8   listrangeallr7   ImportErrorZmunkresr9   Zcompute	Exception	itertoolspermutationsnext)r3   nr8   rowscolsr9   rowcolrB   bestZ	best_costpZcostr   r   r   #min_cost_perfect_bipartite_matchingI   s4    



rK   c           #         s:  |d u r| }|d u r | d   }g }t fdd}|D ]}zg }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 }~qW Y d }~n
d }~0 0 t|jd d }t|t|jt|jt|jd t|jd t|j| f}|| qqVtt|d d |dd  D ]\}\} t|t kr
||d|| ||d  t|t d | krqt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&qt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  qd} t|t| t|d  d |  d }!||! d}"|!|"kr||d|| ||d  |!|"d qW 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)rR   contourrQ   g      ?   r!      
path_count)rQ   master_1master_2value_1value_2
node_count)rQ   pathrX   rY   rZ   r[   node_incompatibility)rQ   r]   noderX   rY   rZ   r[   c                    s   g | ]  fd dD qS )c                    s   g | ]}t t |qS r   )r/   r,   )r#   r+   r*   r   r   
<listcomp>   r'   z#test.<locals>.<listcomp>.<listcomp>r   )r#   )m1r`   r   ra      r'   ztest.<locals>.<listcomp>contour_orderi   d      	high_costZ
math_error)rQ   rR   error)keysr   r)   r    r   Zdrawr   r   r5   r(   r   Zreplayr   absareaintZmeanXZmeanYZstddevXZstddevYZcorrelationr;   rK   r<   r=   round
ValueError)#	glyphsetsglyphsnameshistrO   Z
glyph_nameZ
allVectorsZallNodeTypesr   nameglyphZperContourPenZcontourPensZcontourVectorsZ	nodeTypesixrT   statsesizeZvectorr0   Zm0ZpathIxZnodes1Znodes2ZnodeIxZn1Zn2Zcostsr6   Zmatching_costZupemZ	item_cost	thresholdr   )rb   rN   r   testl   s   





",






*

"



ry   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rddlm} ||| qtddlm} ||| qtdd |D }	t|	||d}
| jrd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rtd|d  |d! |d" |d# f  |d d$krt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)metavarrQ   nargsr}   basenamec                    s    g | ]} | d dd qS ).rV   r   )rsplit)r#   filenamer   r   r   ra   !  r'   zmain.<locals>.<listcomp>z.ufo)	UFOReader)TTFontc                 S   s   g | ]}|  qS r   )ZgetGlyphSet)r#   fontr   r   r   ra   .  r'   )ro   rp   zGlyph z was not compatible: rQ   rP   z"    Glyph was missing in master %srR   rS   z'    Glyph has an open path in master %srW   z*    Path count differs: %i in %s, %i in %srZ   rX   r[   rY   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 %sr_   rc   z-    Contour order differs: %s in %s, %s in %srf   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   ry   jsonprintdumpsitems)argsr   parserro   rp   Zfontsr   r   r   rn   rN   r   rs   Zglyph_problemsrJ   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   rA   sysr   r    r,   r/   r7   rK   ry   r   r   rN   exitrk   boolr   r   r   r   <module>   s(   "#
 
h