o
    tBh<                     @   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mZ ddlZddl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dZd!ddZedkrd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)SegmentToPointPen)RecordingPen)StatisticsPen)OpenContourError)OrderedDictNc                 C   s8   t | }||; }|s| S | || d | d||   S )zxRotate list by k items forward.  Ie. item at position 0 will be
	at position k in returned list.  Negative k is allowed.N)len)lkn r   v/var/www/html/riverr-enterprise-integrations-main/venv/lib/python3.10/site-packages/fontTools/varLib/interpolatable.py	_rot_list   s    r   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__	_glyphset_Pen_penvalue)selfPenglyphsetr   r   r   r      s
   
zPerContourPen.__init__c                 C   s   |    | j| d S r   )_newItemr   moveTo)r   p0r   r   r   _moveTo#   s   zPerContourPen._moveToc                 C   s   | j | d S r   )r   lineTo)r   p1r   r   r   _lineTo'   s   zPerContourPen._lineToc                 C   s   | j || d S r   )r   qCurveTo)r   r   p2r   r   r   _qCurveToOne*   s   zPerContourPen._qCurveToOnec                 C   s   | j ||| d S r   )r   curveTo)r   r   r"   p3r   r   r   _curveToOne-   s   zPerContourPen._curveToOnec                 C      | j   d | _ d S r   )r   	closePathr   r   r   r   
_closePath0      

zPerContourPen._closePathc                 C   r'   r   )r   endPathr)   r   r   r   _endPath4   r+   zPerContourPen._endPathc                 C   s   |    | _}| j| d S r   )r   r   r   append)r   penr   r   r   r   8   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   	glyphNametransformationr   r   r   r5   >   s   z%PerContourOrComponentPen.addComponentN)r0   r1   r2   r5   r   r   r   r   r3   =   s    r3   c                   @   s2   e Zd Zdd ZdddZdddZdd	d
ZdS )RecordingPointPenc                 C   s
   g | _ d S r   )r   r)   r   r   r   r   E   s   
zRecordingPointPen.__init__Nc                 K      d S r   r   )r   
identifierkwargsr   r   r   	beginPathH      zRecordingPointPen.beginPathreturnc                 C   r9   r   r   r)   r   r   r   r,   K   r=   zRecordingPointPen.endPathc                 C   s    | j ||d u r
dndf d S )NFT)r   r.   )r   ptsegmentTyper   r   r   addPointN   s    zRecordingPointPen.addPointr   )r>   N)r0   r1   r2   r   r<   r,   rA   r   r   r   r   r8   C   s
    

r8   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   _vdiffR   s   rK   c                 C   s   d}| D ]}||| 7 }q|S Nr   r   vecvxr   r   r   _vlenV   s   rQ   c                 C   s&   d}| D ]}|t |t | 7 }q|S rL   )absrM   r   r   r   _complex_vlen\   s   rS   c                    s   t  fddt|D S )Nc                 3   s     | ]\}} | | V  qd S r   r   )rB   ijGr   r   rE   d   s    z!_matching_cost.<locals>.<genexpr>)sum	enumerate)rW   matchingr   rV   r   _matching_costc   s   r[   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')r	   scipy.optimizer\   listrangeallr[   ImportErrormunkresr]   compute	Exception	itertoolspermutationsnext)rW   r   r\   rowscolsr]   rowcolrh   best	best_costpcostr   r   r   #min_cost_perfect_bipartite_matchingg   s:   



rr   c           2         sH  |d u r| }|d u r| d   }g }t fdd}|D ]}zg }g }g }t| |D ]e\}	}
||	vr?||d|
d q-|	| }tt|	d}z	|j|dd W n ty`   || Y nw |j}~g }g }g }|| || || t	|D ]\}}t
d	d
 |jD }|| t|	d}z|| W n ty } z|||
|dd W Y d }~q~d }~ww t|jd d }t|t|jt|jt|jd t|jd t|j| f}|| |d dkrq~|d dksJ |d dv sJ t }t|d}|| d}|jD ]\}}|d> |B }qt|j}d|> d }g }|| t|D ]"} || > |@ |||  ? B }||krS|tdd |jD |  q2tt|j}!d}"|!D ]\}}|"d> |B }"q`t|D ]!} |"| > |@ |"||  ? B }||kr|tdd |!D |  qpq~q-t	t|d d |dd  D ]\} \}#t|#tkr||d||  || d  t|#td |#krΐqt	t|#D ]X\}$\}%}&|%|&krqt|%t|&kr||d|$||  || d  t|%t|&d qt	t|%|&D ]!\}'\}(})|(|)kr*||d|$|'||  || d  |(|)d q
q
qՐqt	t|d d |dd  D ]b\} \}#t|#tkrPq?|#sUq?fdd|#D t\}*}+ttt|#},tfdd
tt|#D }-|*|,kr|+|-d  k r||d!||  || d  ttt|#|*d  nq?t	t|d d |dd  D ]R\} \}#t|#tkrq|#sǐqt|#D ]5\}.}/|.d  d"d  fd#d
|/D D t}0d }1|0|1d  k r ||d$||  || d  d% q̐qW q t y! } z||d&|
|d' W Y d }~qd }~ww S )(Nr   c                    s     | g | d S r   )
setdefaultr.   )	glyphnameproblem)problemsr   r   add_problem   s   ztest.<locals>.add_problemmissing)typemaster)r   T)outputImpliedClosingLinec                 s   s    | ]}|d  V  qdS )r   Nr   )rB   instructionr   r   r   rE      s    ztest.<locals>.<genexpr>	open_path)rz   contourry   g      ?   r5   r   r4   )r(   r,   F   c                 S      g | ]\}}t | qS r   complexrB   r?   blr   r   r   
<listcomp>       ztest.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   r      r   
path_count)ry   master_1master_2value_1value_2
node_count)ry   pathr   r   r   r   node_incompatibility)ry   r   noder   r   r   r   c                    s   g | ]  fd dD qS )c                    s   g | ]	}t t |qS r   )rQ   rK   )rB   rJ   rI   r   r   r   %  s    z#test.<locals>.<listcomp>.<listcomp>r   )rB   )m1r   r   r   %  s    c                 3   s    | ]	} | | V  qd S r   r   )rB   rT   )costsr   r   rE   (  rF   gffffff?contour_orderc                 S   s   g | ]}|qS r   r   )rB   rO   r   r   r   r   >  s    c                 3   s    | ]
}t t |V  qd S r   )rS   rK   )rB   c1)c0r   r   rE   >  s    wrong_start_point)ry   r   r   
math_error)ry   rz   error)!keysr   rH   r3   r   draw	TypeErrorr   r.   rY   rG   r   replayr   rR   areaintmeanXmeanYstddevXstddevYcorrelationr8   r   r	   ra   r   r`   reversedrr   rX   min
ValueError)2	glyphsetsglyphsnameshistrw   
glyph_name
allVectorsallNodeTypesallContourIsomorphismsr   nameglyphperContourPencontourPenscontourVectorscontourIsomorphisms	nodeTypesixr~   nodeVecsstatsesizevectorpoints	converterbitsr?   rD   r   maskisomorphismsrT   mirroredreversed_bitsm0pathIxnodes1nodes2nodeIxn1n2rZ   matching_costidentity_matchingidentity_costcontour0contour1min_cost
first_costr   )r   r   r   rv   r   test   sj  













*;






* 

*

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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# f  qq~|
r.|
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)metavarry   nargsr   basenamec                    s    g | ]} | d dd qS ).r   r   )rsplit)rB   filenamer   r   r   r   l  s     zmain.<locals>.<listcomp>z.ufo)	UFOReader)TTFontc                 S   s   g | ]}|  qS r   )getGlyphSet)rB   fontr   r   r   r   y  s    )r   r   zGlyph z was not compatible: ry   rx   z"    Glyph was missing in master %srz   r}   z'    Glyph has an open path in master %sr   z*    Path count differs: %i in %s, %i in %sr   r   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 %sr   r   z-    Contour order differs: %s in %s, %s in %sr   z'    Contour start point differs: %s, %s)argparseArgumentParsermain__doc__add_argumentstr
parse_argsos.pathr   r   endswithfontTools.ufoLibr   r.   fontTools.ttLibr   r   jsonprintdumpsitems)argsr   parserr   r   fontsr   r   r   r   rv   r   r   glyph_problemsrp   r   r   r   r   S  s   




	3r   __main__)NNr   ) r   fontTools.pens.basePenr   r   fontTools.pens.pointPenr   fontTools.pens.recordingPenr   fontTools.pens.statisticsPenr   fontTools.pens.momentsPenr   collectionsr   rg   sysr   r   r3   r8   rK   rQ   rS   r[   rr   r   r   r0   rv   exitr   boolr   r   r   r   <module>   s4    	"
# 
Jf