
    <`0                     *   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	e          Z G d
 de          Zd Zd Zd Zd ZddZddZedk    r2ddlZ e            Z ej         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                   @    e Zd Zd
dZd Zd Zd Zd Zd Zd Z	d	 Z
dS )PerContourPenNc                 h    t          j        | |           || _        || _        d | _        g | _        d S N)r   __init__	_glyphset_Pen_penvalue)selfPenglyphsets      ?lib/python3.11/site-packages/fontTools/varLib/interpolatable.pyr   zPerContourPen.__init__   s5    x(((!		


    c                 b    |                                   | j                            |           d S r   )_newItemr   moveTo)r   p0s     r   _moveTozPerContourPen._moveTo   s+    	r   c                 :    | j                             |           d S r   )r   lineTo)r   p1s     r   _lineTozPerContourPen._lineTo   s    	r   c                 <    | j                             ||           d S r   )r   qCurveTo)r   r   p2s      r   _qCurveToOnezPerContourPen._qCurveToOne!   s     	2r"""""r   c                 >    | j                             |||           d S r   )r   curveTo)r   r   r"   p3s       r   _curveToOnezPerContourPen._curveToOne$   s"    	"b"%%%%%r   c                 F    | j                                          d | _         d S r   )r   	closePathr   s    r   
_closePathzPerContourPen._closePath'   s!    				r   c                 F    | j                                          d | _         d S r   )r   endPathr*   s    r   _endPathzPerContourPen._endPath+   s!    				r   c                 p    |                                  x| _        }| j                            |           d S r   )r   r   r   append)r   pens     r   r   zPerContourPen._newItem/   s2    ))++%	C
#r   r   )__name__
__module____qualname__r   r   r   r#   r'   r+   r.   r    r   r   r
   r
      s               # # #& & &        r   r
   c                       e Zd Zd ZdS )PerContourOrComponentPenc                 p    |                                   | j        d                             ||           d S )N)r   r   addComponent)r   	glyphNametransformations      r   r:   z%PerContourOrComponentPen.addComponent5   s1    
2##I~>>>>>r   N)r2   r3   r4   r:   r5   r   r   r7   r7   4   s#        ? ? ? ? ?r   r7   c                 P    t          d t          | |          D                       S )Nc              3   &   K   | ]\  }}||z
  V  d S r   r5   ).0abs      r   	<genexpr>z_vdiff.<locals>.<genexpr>;   s*      //41aQ//////r   )tuplezip)v0v1s     r   _vdiffrG   :   s'    //3r2;;//////r   c                 $    d}| D ]
}|||z  z  }|S )Nr   r5   )vecvxs      r   _vlenrL   >   s*    	A  	QU
Hr   c                 T     t           fdt          |          D                       S )Nc              3   :   K   | ]\  }}|         |         V  d S r   r5   )r?   ijGs      r   rB   z!_matching_cost.<locals>.<genexpr>F   s/      7741aqtAw777777r   )sum	enumerate)rQ   matchings   ` r   _matching_costrU   E   s.    77779X#6#6777777r   c                    t          |           }	 ddlm}  ||           \  }}|t          t	          |                    k                                    sJ t          |          t          | |          fS # t          $ r Y nw xY w	 ddlm	} d g|z  } |            
                    |           D ]
\  }}|||<   |t          | |          fS # t          $ r Y nw xY w|dk    rt          d          t          j        t	          |                    }t          t          |                    }	t          | |	          }
|D ])}t          | |          }||
k     rt          |          |}
}	*|	|
fS )Nr   )linear_sum_assignment)Munkres   z4Install Python module 'munkres' or 'scipy >= 0.17.0')lenscipy.optimizerW   listrangeallrU   ImportErrormunkresrX   compute	Exception	itertoolspermutationsnext)rQ   nrW   rowscolsrX   rowcolrd   best	best_costpcosts                r   #min_cost_perfect_bipartite_matchingro   I   s   AA888888**1--
dU1XX&++-----Dzz>!T2222   ######vz		))!,, 	 	HCDII^At,,,,    	1uuNOOO )%((33L\""##Dq$''I , ,a##)"1ggt)D?s%   A&A8 8
BB	AC 
CCc                 J
  #$ || }|| d                                          }g }t                      $$fd}|D ]}	 g }g }t          | |          D ]\  }}	||vr ||d|	d           ||         }
t          t          |          }|
                    |           |j        }~g }g }|                    |           |                    |           t          |          D ],\  }}|                    t          d |j        D                                  t          |          }	 |                    |           n'# t          $ r} |||	|dd           Y d }~}d }~ww xY wt          |j                  d	z  d	z  }t          |          t          |j                  t          |j                  t          |j        d
z            t          |j        d
z            t          |j        |z            f}|                    |           .t          t          |d d         |dd                              D ]E\  }\  }#t+          |          t+          #          k    r; ||d||         ||dz            t+          |          t+          #          d           |#k    rkt          t          |#                    D ]\  }\  }}||k    rt+          |          t+          |          k    r= ||d|||         ||dz            t+          |          t+          |          d           lt          t          ||                    D ]2\  }\  }}||k    r$ ||d||||         ||dz            ||d           23Gt          t          |d d         |dd                              D ]B\  }\  }#t+          |          t+          #          k    r*|s-#fd|D             }t-          |          \  }}|t/          t1          t+          |                              k    rJ ||d||         ||dz            t/          t1          t+          |                              |d            nd} t3          |t+          |          z  t+          |d                   z  d	z  | z  dz            }!|                    |!           d}"|!|"k    r! ||d||         ||dz            |!|"d           D# t4          $ r} ||d|	|d           Y d }~d }~ww xY w$S )Nr   c                 Z                         | g                               |           d S r   )
setdefaultr0   )	glyphnameproblemproblemss     r   add_problemztest.<locals>.add_problemv   s-    Ir**11':::::r   missing)typemaster)r   c              3   &   K   | ]}|d          V  dS )r   Nr5   )r?   instructions     r   rB   ztest.<locals>.<genexpr>   s&      NNk!nNNNNNNr   	open_path)ry   contourrx   g      ?   r9      
path_count)rx   master_1master_2value_1value_2
node_count)rx   pathr   r   r   r   node_incompatibility)rx   r   noder   r   r   r   c                 .    g | ]fd D             S )c                 J    g | ]}t          t          |                     S r5   )rL   rG   )r?   rF   rE   s     r   
<listcomp>z#test.<locals>.<listcomp>.<listcomp>   s)    ===B%r2//===r   r5   )r?   rE   m1s    @r   r   ztest.<locals>.<listcomp>   s/    KKK"===="===KKKr   contour_orderi   d      	high_cost
math_error)rx   ry   error)keysr   rD   r7   r   drawr   r0   rS   rC   r   replayr   absareaintmeanXmeanYstddevXstddevYcorrelationrZ   ro   r\   r]   round
ValueError)%	glyphsetsglyphsnameshistrv   
glyph_name
allVectorsallNodeTypesr   nameglyphperContourPencontourPenscontourVectors	nodeTypesixr}   statsesizevectorrO   m0pathIxnodes1nodes2nodeIxn1n2costsrT   matching_costupem	item_cost	thresholdr   ru   s%                                      @@r   testr   l   sh   }~1""$$D}}H; ; ; ; ;  K K
G	JL"%i"7"7 (2 (2$X--K
Y$,O,OPPP , 8 8! ! ! 

=)))+1!!#	##I...!!.111#,[#9#9 2 2KB$$NNNNNNN   *8<<<E!u----+ ! ! !#&'+KPP   !! uz??c1C7DD		EK((EK((EMA-..EMA-..E-455F #))&1111-24  )\#2#->QRR@P)Q)QRR ,% ,%8Br77c"gg%%K"$0(-a(-a!e'*2ww'*2ww 	 	 	 8809#b"++0F0F % %,F,VV'' 6{{c&kk11#&(4(.,1!H,1!a%L+.v;;+.v;; 
 
 
 !,5c&&6I6I,J,J % %(R88'K *,B,2,205a05a!e/1/1!" !"   % $%!%@  )Z_jn)M)MNN $ $8Br77c"gg%% KKKKKKK*Me*T*T'-tE#b''NN3333K"$3(-a(-a!e'+E#b''NN';';'/ 	 	 	 E!"SWW,s2a5zz9cADH3N 	 I&&&		))K"$/(-a(-a!e'0'0 	 	 	  	 	 	K%BB       	
 OsC   C-S;,ES;
E&	E!	S;!E&	&NS;;
T TT c                 
   ddl }|                    dt          j                  }|                    ddd           |                    d	d
t
          dd           |                    |           } d}ddlm fd| j	        D             }g }| j	        D ]`}|
                    d          r%ddlm} |                     ||                     <ddlm} |                     ||                     ad |D             }	t!          |	||          }
| j        r(ddl}t%          |                    |
                     n|
                                D ]\  }}t%          d| d           |D ]}|d         dk    rt%          d|d         z             |d         dk    rt%          d|d         z             |d         dk    r.t%          d|d         |d          |d!         |d"         fz             |d         d#k    r5t%          d$|d%         |d         |d          |d!         |d"         fz             |d         d&k    r<t%          d'|d(         |d%         |d         |d          |d!         |d"         fz             |d         d)k    r3t%          d*|d         d+|d          d,|d!         d+|d"                    |d         d-k    r.t%          d.|d          |d"         |d         |d!         fz             |
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)metavarrx   nargsr   )basenamec                 Z    g | ]'} |                               d d          d         (S ).r   r   )rsplit)r?   filenamer   s     r   r   zmain.<locals>.<listcomp>!  s8    NNNhXXh&&sA..q1NNNr   z.ufo)	UFOReader)TTFontc                 6    g | ]}|                                 S r5   )getGlyphSet)r?   fonts     r   r   zmain.<locals>.<listcomp>.  s$    666!!##666r   )r   r   zGlyph z was not compatible: rx   rw   z"    Glyph was missing in master %sry   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: z in z, r   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   endswithfontTools.ufoLibr   r0   fontTools.ttLibr   r   jsonprintdumpsitems)argsr   parserr   r   fontsr   r   r   r   ru   r   r   glyph_problemsrm   r   s                  @r   r   r     s   OOO$$)L %  F +    
 &s#<Q     T""DF
 !     NNNN$+NNNEEK + +V$$ 	+222222LL8,,----......LL))****66666IIfE:::Hy ;djj""####%-^^%5%5 6	 6	!E>75777888# 4 4V9	))>8LMMMV9++CakQRRRV9,,DY<:)a
mTU   V9,,OfIiLjMiLjM	 	 	 V9 666QfIfIiLjMiLjM
 
 
 V9//E iLLLjMMMiLLLjMM   V9++^jMjMiLiL	  Y4j   r   __main__)NNr   )r   fontTools.pens.basePenr   r   fontTools.pens.recordingPenr   fontTools.pens.statisticsPenr   fontTools.pens.momentsPenr   collectionsr   rc   sysr
   r7   rG   rL   rU   ro   r   r   r2   ru   exitr   boolr5   r   r   <module>r      s    8 7 7 7 7 7 7 7 4 4 4 4 4 4 6 6 6 6 6 6 6 6 6 6 6 6 # # # # # #     



    G   D? ? ? ? ?} ? ? ?0 0 0  8 8 8     FY Y Y Yxe e e eP zJJJtvvHCHSSh  !!!!!	 r   