
    #Vf]                        d Z ddlmZm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	lZdd	lZ ej*                  d
      Zd Z G d de      Z G d de      Z G d de      Zd Zd Zd Zd Zd Zd Z 	 ddl!m"Z" eZ#ddZ'ddZ(d Z)d dZ*e+dk(  r*dd	lZ e*       Z, ejZ                   e. e/e,                   y	y	# e$$ r 	 ddl%m&Z& eZ#n# e$$ r e Z#Y nw xY wY ]w xY w)!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)AbstractPointPenSegmentToPointPen)RecordingPen)StatisticsPen)OpenContourErrorpiecewiseLinearMap)defaultdictNzfontTools.varLib.interpolatablec                     | | d | d|  z   S )z{Rotate list by k items forward.  Ie. item at position 0 will be
    at position k in returned list.  Negative k is allowed.N )lks     h/var/www/html/software/conda/envs/catlas/lib/python3.12/site-packages/fontTools/varLib/interpolatable.py	_rot_listr      s     aRS6AcrF?    c                   >    e Zd Zd
dZd Zd Zd Zd Zd Zd Z	d	 Z
y)PerContourPenNc                 h    t        j                  | |       || _        || _        d | _        g | _        y N)r   __init__	_glyphset_Pen_penvalue)selfPenglyphsets      r   r   zPerContourPen.__init__   s.    x(!		
r   c                 Z    | j                          | j                  j                  |       y r   )_newItemr   moveTo)r   p0s     r   _moveTozPerContourPen._moveTo&   s    		r   c                 :    | j                   j                  |       y r   )r   lineTo)r   p1s     r   _lineTozPerContourPen._lineTo*   s    		r   c                 <    | j                   j                  ||       y r   )r   qCurveTo)r   r'   p2s      r   _qCurveToOnezPerContourPen._qCurveToOne-   s    		2r"r   c                 >    | j                   j                  |||       y r   )r   curveTo)r   r'   r+   p3s       r   _curveToOnezPerContourPen._curveToOne0   s    		"b"%r   c                 F    | j                   j                          d | _         y r   )r   	closePathr   s    r   
_closePathzPerContourPen._closePath3   s    			r   c                 F    | j                   j                          d | _         y r   )r   endPathr3   s    r   _endPathzPerContourPen._endPath7   s    			r   c                 h    | j                         x| _        }| j                  j                  |       y r   )r   r   r   append)r   pens     r   r!   zPerContourPen._newItem;   s&    ))+%	C

#r   r   )__name__
__module____qualname__r   r$   r(   r,   r0   r4   r7   r!   r   r   r   r   r      s*    #&r   r   c                       e Zd Zd Zy)PerContourOrComponentPenc                 b    | j                          | j                  d   j                  ||       y )N)r!   r   addComponent)r   	glyphNametransformations      r   rB   z%PerContourOrComponentPen.addComponentA   s#    

2##I~>r   N)r;   r<   r=   rB   r   r   r   r?   r?   @   s    ?r   r?   c                   *    e Zd Zd ZddZddZddZy)RecordingPointPenc                     g | _         y r   )r   r3   s    r   r   zRecordingPointPen.__init__G   s	    
r   Nc                      y r   r   )r   
identifierkwargss      r   	beginPathzRecordingPointPen.beginPathJ       r   c                      y r   r   r3   s    r   r6   zRecordingPointPen.endPathM   rL   r   c                 R    | j                   j                  ||df       y df       y )NFT)r   r9   )r   ptsegmentTypes      r   addPointzRecordingPointPen.addPointP   s&    

2(;uFGFGr   r   )returnN)r;   r<   r=   r   rK   r6   rQ   r   r   r   rF   rF   F   s    Hr   rF   c                 L    d}t        | |      D ]  \  }}||z
  }|||z  z  } |S Nr   )zipv0v1sx0x1ds         r   _vdiff_hypot2r]   T   s=    	Ab"+ BG	QU
 Hr   c                     d}t        | |      D ]@  \  }}||z
  }||j                  |j                  z  |j                  |j                  z  z   z  }B |S rT   )rU   realimagrV   s         r   _vdiff_hypot2_complexra   \   sW    	Ab"+ /BG	QVVaff_qvv../ Hr   c                 >     t         fdt        |      D              S )Nc              3   4   K   | ]  \  }}|   |     y wr   r   ).0ijGs      r   	<genexpr>z!_matching_cost.<locals>.<genexpr>e   s     741aqtAw7s   )sum	enumerate)rg   matchings   ` r   _matching_costrl   d   s    79X#6777r   c                     t        |       }t        |       \  }}|t        t        |            k(  j	                         sJ t        |      t        | |      fS r   )lenlinear_sum_assignmentlistrangeallrl   )rg   nrowscolss       r   )min_cost_perfect_bipartite_matching_scipyrv   h   sN    AA&q)JD$DqN"''))):~a...r   c                     t        |       }d g|z  }t               j                  |       D ]
  \  }}|||<    |t        | |      fS r   )rn   Munkrescomputerl   )rg   rs   ru   rowcols        r   +min_cost_perfect_bipartite_matching_munkresr|   o   sQ    AA6A:DI%%a( SS	4(((r   c                    t        |       }|dkD  rt        d      t        j                  t	        |            }t        t        |            }t        | |      }|D ]!  }t        | |      }||k  st        |      |}}# ||fS )N   z4Install Python module 'munkres' or 'scipy >= 0.17.0')rn   	Exception	itertoolspermutationsrq   rp   nextrl   )rg   rs   r   best	best_costpcosts          r   .min_cost_perfect_bipartite_matching_bruteforcer   w   s    AA1uNOO ))%(3L\"#Dq$'I ,a#)"1gt)D, ?r   )ro   )rx   c              #   ,  <K   || }|&| D ch c]  }|j                         D ]  }|  }}}g }|D ]  }	 d}g }	g }
g }| D cg c]  }||   	 }}t        |D cg c]  }|d	 c}      dk  r?t        || |      D ]H  \  }}}|?|s	|d|df |
j                  d        |	j                  d        |j                  d        It	        t
        |      }	 |j                  |d       |j                  }~g }g }g }|
j                  |       |	j                  |       |j                  |       t        |      D ]  \  }}t        d |j                  D              }|j                  |       t        |      }	 |j                  |       t        j                  t!        |j"                              dz  }t%        |      t%        |j&                        t%        |j(                        t%        |j*                  dz        t%        |j,                  dz        t%        |j.                  |z        f}|j                  |       |d   dk(  r|d   dk(  sJ |d   dv sJ t1               }t3        |d      }|j                  |       d}|j                  D ]  \  }}|dz  |z  } t        |j                        } d| z  dz
  }!g }"|j                  |"       |j                  D #cg c]  \  }}#t5        |  }$}}#t7        |       D ]4  }%||%z  |!z  || |%z
  z	  z  }||k(  s|"j                  t9        |$|%             6 t;        t=        |j                              }&d}'|&D ]  \  }}|'dz  |z  }' t;        t=        |$            }$t7        |       D ]4  }%|'|%z  |!z  |'| |%z
  z	  z  }||k(  s|"j                  t9        |$|%             6  K t?        d t        |
      D        t        |
      dz
        }|
|   }(t        |
|dz   d        D ]  \  }%})|)	t        |(      t        |)      k7  r*|d||   |||%z   dz      t        |(      t        |)      df |(|)k(  rPt        t        |(|)            D ]  \  }*\  }+},|+|,k(  rt        |+      t        |,      k7  r,|d|*||   |||%z   dz      t        |+      t        |,      df Rt        t        |+|,            D ](  \  }-\  }.}/|.|/k7  s|d|*|-||   |||%z   dz      |.|/df *   t?        d t        |	      D        t        |	      dz
        }|	|   }(|( t        |(      dkD  rt        |	|dz   d        D ]  \  }%})|)	t        |(      t        |)      k7  r!|(D 01cg c]  }0|)D 1cg c]  }1tA        |0|1       c}1 c}1}0<tC        <      \  }2}3t;        t7        t        |(                  }4tE        <fdt7        t        |(            D              }5|2|4k7  s|3|5dz  k  s|d||   |||%z   dz      t;        t7        t        |(                  |2df  n t?        d t        |      D        t        |	      dz
        }||   }(|(rt        ||dz   d        D ]  \  }%})|)	t        |(      t        |)      k7  r!t        t        |(|)            D ]W  \  }\  }6}7|6d   }8|7D 9cg c]  }9tG        |8|9       c}9<tI        <      }:<d   };|:|;dz  k  sA|d|||   |||%z   dz      df Y   y c c}}w c c}w c c}w # t        $ r |j                  |       Y Jw xY w# t        $ r}|||d	d
f Y d }~d }~ww xY wc c}#}w c c}1w c c}1}0w c c}9w # tJ        $ r}|d |d!f Y d }~Xd }~ww xY ww)"Nr      missing)typemaster)r   T)outputImpliedClosingLinec              3   &   K   | ]	  }|d      yw)r   Nr   )rd   instructions     r   rh   ztest_gen.<locals>.<genexpr>   s     $U[^$Us   	open_path)r   contourr   g      ?   rB   r"   rA   )r2   r6   Fc              3   ,   K   | ]  \  }}|	|  y wr   r   rd   re   xs      r   rh   ztest_gen.<locals>.<genexpr>  s     Htq!!-H   

path_count)r   master_1master_2value_1value_2
node_count)r   pathr   r   r   r   node_incompatibility)r   r   noder   r   r   r   c              3   ,   K   | ]  \  }}|	|  y wr   r   r   s      r   rh   ztest_gen.<locals>.<genexpr>;  s     Ftq!Fr   c              3   .   K   | ]  }|   |     y wr   r   )rd   re   costss     r   rh   ztest_gen.<locals>.<genexpr>J  s     'La'Ls   gffffff?contour_orderc              3   ,   K   | ]  \  }}|	|  y wr   r   r   s      r   rh   ztest_gen.<locals>.<genexpr>^  s     Rtq!AMRr   wrong_start_point)r   r   r   r   
math_error)r   r   error)&keysrn   rU   r9   r?   r   draw	TypeErrorr   rj   tupler   replayr	   mathsqrtabsareaintmeanXmeanYstddevXstddevYcorrelationrF   r   complexrq   r   rp   reversedr   r]   #min_cost_perfect_bipartite_matchingri   ra   min
ValueError)=	glyphsetsglyphsnamesignore_missingr   ghist
glyph_namem0idx
allVectorsallNodeTypesallContourIsomorphisms	allGlyphsglyphnameperContourPencontourPenscontourVectorscontourIsomorphisms	nodeTypesixr   nodeVecsstatsesizevectorpoints	converterbitsrO   brs   maskisomorphismsblcomplexPointsre   mirroredreversed_bitsm0m1pathIxnodes1nodes2nodeIxn1n2rW   rX   rk   matching_costidentity_matchingidentity_costcontour0contour1c0c1min_cost
first_costr   s=                                                               @r   test_genr      s    }~ %.Gx}}G!!G!GGD [
Z	EJL%'">GH(*-HIH9B%0AABCqH),Y	5)I RM%x=))I+NOO ''-%%d+*11$7 8 8!.JJ}tJL ,11!!#&(#	##I.!!.1&--.AB#,[#9 9MKB$$Uw}}$UUH$$X.)8<E!u-  99S_5;DD	EKK(EKK(EMMA-.EMMA-.E--45F #))&1  {n4 #A;(222#B<+CCCC.0F 1&% @INN9- D!' /A $	Q/FLL)AFa<D#%L'..|<@F$Mfb"Wb\$MM$M"1X M"ai4/Ta!e_F9(//	-0KLM
  $HV\\$:;H$%M!) AA)6!);q(@A$(-)@$AM"1X M+q0D8mPQTUPU>VX9(//	-0KLMm9M3RMl Hy6HL!A%E
 e$B"<	#<= .%2:r7c"g%"$0(-e(-eai!m(<'*2w'*2w	 	 809#b"+0F %,F,VV' 6{c&k1&(4(.,1%L,1%!)a-,@+.v;+.v;
 
 !,5c&&6I,J %(R8 *,B,2,205e05eai!m0D/1/1!"#  %%!%!.%d Fy4FJ!#E
 E"B~#b'A+&z%!)+'>? EArz 2w#b') LNObbAmB3AOE.QRW.X+Hm(,U3r7^(<%$''LU3r7^'L$LM $55)MD,@@ '(7,1%L,1%!)a-,@+/c"g+?+3	 	 18 Ry)?@RJ!#E
 (.B&'=eaik'JK EArz 2w#b') 4=c"bk4J 00Xx%a[IQ R2!6r2!> R#&u:%*1X
#j4&77 *,?/105e05eai!m0D	!"# C[	 H IB  ! .JJ}-.$ , !&'+KP  !!H %Nn BOJ !S  	%B  	s  ^\^]3\]3\
$\
(
]32^3A']3\.B]3 \<E]3']9']3!B]3)D;]3%B]3:	](
]#](
A]36]3?B>]3=].
]3,]3
^
]3\95]38\99]3<	]	
]	]3]		]3#](
(]33	^<
^^^^c                 x    t        t              }t        | |||      D ]  \  }}||   j                  |        |S r   )r   rp   r   r9   )r   r   r   r   problems	glyphnameproblems          r   testr     sC    4 H&y&%P ,	7""7+,Or   c                 x    | |v ry ||    || <   t        ||    dg       D ]  }t        |j                  |||        y )N
components)getattrrecursivelyAddGlyphrC   )r   r   
ttGlyphSetglyf	components        r   r   r     sN    H$Y/HYT)_lB? M	I//:tLMr   c                   3 ddl }|j                  dt        j                        }|j	                  ddd       |j	                  d	d
d       |j	                  dd
d       |j	                  dd
d       |j	                  ddt
        dd       |j	                  ddd
d       |j                  |       } ddlm}  || j                  rdnd       | j                  r| j                  j                         nd}ddlm} g }g }t        | j                        dk(  r]| j                  d   j!                  d      rOddlm} |j'                  | j                  d         }	|	j(                  D 
cg c]  }
|
j*                   c}
| _        n| j                  d   j!                  d       rydd!lm}m}  || j                  d         }|j3                   ||             |D cg c]1  }|j4                  j6                  d"|j4                  j8                  3 }}g | _        nY| j                  d   j!                  d#      r:dd$lm}  || j                  d         }d%|v ri 3|d&   }|j>                  D ]3  }|j@                  |jB                  |jD                  d'3|jF                  <   5 d(|v rd|d(   }|jH                  jK                         D ]B  \  }}3|   jM                         }|jK                         D ]  \  }}tO        ||      3|   |<    D |d%   }|d)   }i }tQ        tR              }|#tU        |jV                  jY                               }|D ]  }|jV                  |   D ]  }i }g } tU        |j>                  jK                               D ]#  \  }!}"|"d   ||!<   | j[                  |!|"d   f       % t]        |       }#|#|vr|j_                  |d*+      ||#<   ta        |||#   ||#   |         d,g}|j_                         g}tU        |jY                         d- .      D ]G  }#d/d0jc                  3fd1|#D              z   d/z   }$|j[                  |$       |j[                  ||#          I d*| _2        g | _        | j                  D ]x  }%|%j!                  d2      rdd3l3m4}& |j[                   |&|%             ndd$lm} |j[                   ||%             |j[                   ||%      jk                  d4d      d          z g }|D ]R  }tm        |d5      r|j_                         }'n|}'|j[                  |'jY                         D (ci c]  }(|(|'|(   
 c}(       T |s9tU        to        |D ')cg c]  }'|'jY                         D ]  })|)  c})}'            }to        |      }*|D ]/  }'to        |'jY                               }+|*|+z
  },|,s$|,D ]  })d|'|)<   	 1 tp        j5                  d6t        |             ts        |||| jd                  7      }-tQ        tt              }.| jv                  s| jx                  r>ddl<}/|-D ]  \  }}0|.|   j[                  |0        t{        |/j}                  |.             nud}1|-D ]N  \  }}2|.|   j[                  |2       ||1k7  rt{        d8| d9       |}1|2d:   d;k(  rt{        d<|2d=   z         |2d:   d>k(  rt{        d?|2d=   z         |2d:   d@k(  rt{        dA|2dB   |2dC   |2dD   |2dE   fz         |2d:   dFk(  r"t{        dG|2dH   |2dB   |2dC   |2dD   |2dE   fz         |2d:   dIk(  r&t{        dJ|2dK   |2dH   |2dB   |2dC   |2dD   |2dE   fz         |2d:   dLk(  r#t{        dM|2dB   dN|2dC   dO|2dD   dN|2dE          |2d:   dPk(  rt{        dQ|2dR   |2dC   |2dE   fz         |2d:   dSk(  s8t{        dT|2d=   dU|2dV          Q n|-D ]  \  }}0|.|   j[                  |0        |.r|.S yc c}
w c c}w c c}(w c c})}'w )Wz/Test for interpolatability issues between fontsr   Nzfonttools varLib.interpolatable)descriptionz--glyphsstorez&Space-separate name of glyphs to check)actionhelpz--json
store_truezOutput report in JSON formatz--quietz%Only exit with code 1 or 0, no outputz--ignore-missingz<Will not report glyphs missing from sparse masters as errorsinputsFILE+zSInput a single variable font / DesignSpace / Glyphs file, or multiple TTF/UFO files)metavarr   nargsr  z-vz	--verbosezRun verbosely.)configLoggerINFOERROR)level)basenamer   z.designspace)DesignSpaceDocumentz.glyphs)GSFontto_ufos-z.ttf)TTFontgvarfvar)rA   r   r   avarr   T)location
normalizedz''c                     t        |       | fS r   )rn   )vs    r   <lambda>zmain.<locals>.<lambda>  s    APQ{ r   )key' c              3   L   K   | ]  \  }}|d t        ||           yw)=Nr
   )rd   r   r  axisMappings      r   rh   zmain.<locals>.<genexpr>	  s.      # $1 ()*<QA*OP#s   !$z.ufo)	UFOReader.getGlyphSetzRunning on %d glyphsets)r   r   r   zGlyph z was not compatible: r   r   z"    Glyph was missing in master %sr   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   z*    Contour %d start point differs: %s, %sr   r   z    Miscellaneous error in z: r   )?argparseArgumentParsermain__doc__add_argumentstr
parse_args	fontToolsr  verboser   splitos.pathr  rn   r  endswithfontTools.designspaceLibr  fromfilesourcesr   	glyphsLibr  r  extendinfo
familyName	styleNamefontTools.ttLibr  axesminValuedefaultValuemaxValueaxisTagsegmentsitemscopyr   r   dictsorted
variationsr   r9   r   r"  r   joinr   fontTools.ufoLibr   rsplithasattrsetlogr   rp   quietjsonprintdumps)4argsr#  parserr  r   r  fontsr   r  designspacer   r  r  gsfontfr  fontr  axisr  r<  r=  fvarMappingr  r   r  r   ttGlyphSetsr   r   varlocDictloctagvallocTupler   filenamer   r   r   gn	glyphsSetglyphSetGlyphNamesdiffproblems_genr   rJ  r   last_glyphnamer   r  s4                                                      @r   r%  r%    s   $$)LL % F 5  
 +  
 4  
 K  
 b   k,EUVT"D&$,,G=$(KKT[[ TF EE
4;;1;;q>"">2D-66t{{1~FK5@5H5HI66;;IDK[[^$$Y/1DKKN+FLL)NST 1 11663C3CDTETDK[[^$$V,.$++a.)D~ !F| II D MM,,==1K- T><D-1]]-@-@-B )&1'&:&?&?&A/7~~/? OHe:L (+;K07 F|F| '-	>#DOO$8$8$:;F!' I#y9 "$ (.sxx~~/?(@ 6HC+.q6GCLJJSV}56 $):#;6484D4D)0T 5E 5K1 ,%y':K<QSW$ ))+, &y~~'7=R S 
6H(( #(0# 
   LL&LL8!45
6 '+# KK 
;V$2LL8,-.LL)*Xh'..sA6q9:
; I D4''')HH(--/BQ!Xa[.BCD 	THHMMOTbRTRTUVFI $ 1-- $#$	$ HH&I7&d>Q>QL 4 H::99&2 4"	7#**734 $**X&'!N , A	1#**1-.F9+-BCD%.NV9	)>8LMV9+CakQRV9,DY<:)a
mTU V9,OfIiLjMiLjM	 V9 66QfIfIiLjMiLjM
 V9/ iLjMiLjM V9 33DiLjMjM V9, hKgJwAF #/ 	0IwY&&w/	0  C J Un C Us   /_."6_3_8
-_=__main__)NNFr   )0r&  fontTools.pens.basePenr   r   fontTools.pens.pointPenr   r   fontTools.pens.recordingPenr   fontTools.pens.statisticsPenr   fontTools.pens.momentsPenr	   fontTools.varLib.modelsr   collectionsr   r   r   syslogging	getLoggerrH  r   r   r?   rF   r]   ra   rl   rv   r|   r   scipy.optimizero   r   ImportErrormunkresrx   r   r   r   r%  r;   r   exitr   boolr   r   r   <module>rt     s   8 G 4 6 6 6 #   
 g9:G D?} ?H( H8/)"
4*S'ePMyx zvHCHHSh !	 C  

	
# 8 	,  
: 	,


s6   
C C0C C0 C*'C0)C**C0/C0