o
    %e                     @   s|  d Z ddlT ddlmZ ddlmZ ddlmZmZm	Z	 ddl
mZ ddlmZmZ dd	l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mZ ddl m!Z!m"Z"m#Z# ddl$Z$ddl%Z%e$&dZ'dZ(dZ)dZ*dZ+G dd dZ,			d'de(e)e+ddddZ-ee-dd Z.d d! Z/d"d# Z0d(d$d%Z1e2d&krddl3Z3e1 Z4e35e6e7e4 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 ...
   )*)test_contour_order)test_starting_point    )RecordingPenDecomposingRecordingPenlerpRecordings)TransformPen)StatisticsPenStatisticsControlPen)OpenContourError)piecewiseLinearMapnormalizeLocation)floatToFixedToStr)	Transform)defaultdict)SimpleNamespace)wraps)pformat)sqrtatan2piNzfontTools.varLib.interpolatablegffffff?g      ?gMb`?i  c                   @   s2   e Zd ZdZdd Zdd Zdd Zdd	d
ZdS )Glyph)	
recordings
greenStatscontrolStatsgreenVectorscontrolVectors	nodeTypesisomorphismspointsopenContoursc                 C   s,   || _ | jD ]}t| |g  q| | d S N)nameITEMSsetattr	_populate)self	glyphnameglyphsetitem r+   R/var/www/html/venv/lib/python3.10/site-packages/fontTools/varLib/interpolatable.py__init__4   s   
zGlyph.__init__c                 C   s2   | j D ]}tt| ||krt| |d  qd S r"   )r$   lengetattrappend)r'   ixr*   r+   r+   r,   _fill_in:   s
   
zGlyph._fill_inc                 C   s  || j  }|d u | _| jrd S tt|d}z	|j|dd W n ty,   || Y nw |j| _~t| jD ]\}}dd |jD }| j	
| t|d}t|d}z|| || | j
d W n ty }	 z| j
d | | W Y d }	~	q7d }	~	ww | j
| | j
| | j
t| | j
t| |d dkr| | q7|d d	ksJ |d
 dv sJ t }
t|
d}|| | j
|
j g }| j
| t|
j|d t|
j|d q7d S )Nr)   T)outputImpliedClosingLinec                 S   s   g | ]\}}|qS r+   r+   ).0opargr+   r+   r,   
<listcomp>N       z#Glyph._populate.<locals>.<listcomp>Fr   addComponentmoveTo)	closePathendPath)r#   doesnt_existPerContourOrComponentPenr   draw	TypeErrorvaluer   	enumerater   r0   r
   r   replayr!   r   r2   r   r   r   contour_vector_from_statsr   SimpleRecordingPointPenSegmentToPointPenr    r   add_isomorphisms)r'   r)   glyphperContourPenr1   contourr   r   r   er    	converterr   r+   r+   r,   r&   ?   sZ   









zGlyph._populateNc                 C   s6   |d u r| j D ]}|| qd S | j | | d S r"   )r   rA   )r'   pencountor_idxrL   r+   r+   r,   rA   w   s
   
z
Glyph.drawr"   )__name__
__module____qualname__r$   r-   r2   r&   rA   r+   r+   r+   r,   r   '   s    8r   F)	locations	tolerance	kinkinessupemshow_allc          U      #   sB
   |dkr	|d9 }d|  krdksJ  J |dkr|d9 }d|ks%J |p-dd D }|d u r9dd D }t |\}	fd	d
}
|D ]ԉ td   fddD }tdd |D dkrgqItt||D ]6\}\}}}|jr|s tj||dfV  qod}t|j	D ]\}}|sqd} tj
|||dfV  q|rqoqod gt }|	D ]m}|| }|d u s|jsq|
| }|d u rq|| }|d u s|jsq|j|j}t|tkr tj|| || ||t|tdfV  q|kr`tt|D ]Z\}\}}||krqt|t|kr4 tj||| || ||t|t|dfV  qtt||D ]"\}\}}||kr\ tj|||| || ||||d	fV  q;q;qt||\}} ||k r tj|| || ||ttt| | |dfV  | ||< |j}!|j|j}"|j|j}#|j|| } | d urrfdd| D fdd| D fdd| D g }$t|#D ])\}%}&zt }'tt|%j|&j|'_|$|' W q ty   |$d  Y qw tt|!D ] \}\}(})|(d u s|)d u st|(dkst|(t|)krqt||||| \}}*}+||k rB tj||| || ||d|*|+|d
fV  |$| },|,r|"| d dk | d dk krtd d}-|,|- t|-}.|"| }/| }0|/d |/d  }1|0d |0d  }2|.d |.d  }3ttj tj!fD ]i\}4}5|4rt"|1|2}6qt#|1|2 }6t$d|5|3|6|1|2 |4s|6| |3d ks|4rd|6|  |3k rz|4r|6|3 }n|3|6 }W n t%y   d}Y nw t$d|  |5||| || |||dfV  qq|j&}|j&|| d urrfdd|| D d }7|t' t( | }8tt|D ]\}\}(})|(d u sI|)d u sIt|(dksIt|(t|)krKq(tt|(D ]}9|(|9 }:|)|9 };|:d rf|;d shqQ|(|9d  }<|)|9d  }=|(|9d t|(  }>|)|9d t|)  }?|<d r|=d rqQ|<d r|=d rqQt)|:d  }:t)|;d  };t)|<d  }<t)|=d  }=t)|>d  }>t)|?d  }?|:|< }@|>|: }A|;|= }B|?|; }C|@j*|Aj+ |@j+|Aj*  }D|Bj*|Cj+ |Bj+|Cj*  }Ez|Dt,|@t,|A  }D|Et,|Bt,|C  }EW n t%y   Y qQw t,|D|7kst,|E|7krqQ|@j*|Aj* |@j+|Aj+  }F|Bj*|Cj* |Bj+|Cj+  }G|Fdk s@|Gdk rBqQt,|@t,|@t,|A  }Ht,|Bt,|Bt,|C  }It,|H|I }Jt,|J|7k riqQ|:|; d! }K|<|= d! }L|>|? d! }M|K|L }N|M|K }O|Nj*|Oj+ |Nj+|Oj*  }Pz|Pt,|Nt,|O  }PW n t%y   Y qQw t,|P||  |7krqQ|Pt,|N t,|O }Qt,|N|O }Rt,|Q|R }S|S|8k rѐqQ|S|R }T|T|7krܐqQ|7t,|P|  }t$d"|S|T|P|J t$d|  tj-||| || |||9|d#fV  qQq(|r tj.|| || ||d$fV  qqId S )%N
   g{Gz?r   r   c                 S   s   g | ]}t |qS r+   )repr)r5   gr+   r+   r,   r8      r9   ztest_gen.<locals>.<listcomp>c                 S   s   h | ]}|  D ]}|qqS r+   keys)r5   r)   r[   r+   r+   r,   	<setcomp>       ztest_gen.<locals>.<setcomp>c                    sd   | d u rd S |  } | d u rd S |  d ur0 |  | d u r0|  } |  d ur0 |  | d u s| S r"   r+   )ir(   )	glyphsetsparentsr+   r,   grand_parent   s   ztest_gen.<locals>.grand_parentzTesting glyph %sc                    s   g | ]}t  |qS r+   )r   )r5   r)   )
glyph_namer+   r,   r8          c                 S   s   g | ]}|d urdqS )Nr   r+   )r5   rJ   r+   r+   r,   r8          )typemaster
master_idxFT)rg   rh   ri   rL   )rg   master_1master_2master_1_idxmaster_2_idxvalue_1value_2)rg   pathrj   rk   rl   rm   rn   ro   )	rg   rp   noderj   rk   rl   rm   rn   ro   )rg   rj   rk   rl   rm   rn   ro   rU   c                       g | ]} | qS r+   r+   r5   r`   )m1Isomorphismsr+   r,   r8   6  r9   c                    rr   r+   r+   rs   )	m1Vectorsr+   r,   r8   7  r9   c                    rr   r+   r+   rs   )
recording1r+   r,   r8   8  r9   )
rg   rL   rj   rk   rl   rm   rn   ro   reversedrU   r3   z;%s: actual size %g; threshold size %g, master sizes: %g, %ggh㈵>ztolerance %g)rg   rL   rj   rk   rl   rm   rU   c                    rr   r+   r+   rs   )m1r+   r,   r8     r9   g?   z=kink: deviation %g; deviation_ratio %g; sin_mid %g; r_diff %g)rg   rL   rj   rk   rl   rm   rC   rU   )rg   rj   rk   rl   rm   )/find_parents_and_orderloginfor.   rD   zipr?   InterpolatableProblemMISSINGr!   	OPEN_PATHr   
PATH_COUNT
NODE_COUNTNODE_INCOMPATIBILITYr   CONTOUR_ORDERlistranger   r   r   r   r   rC   r0   
ValueErrorr   WRONG_START_POINTr
   rE   rF   UNDERWEIGHT
OVERWEIGHTmaxr   debugZeroDivisionErrorr    DEFAULT_KINKINESS_LENGTHDEFAULT_KINKINESScomplexrealimagabsKINKNOTHING)Ura   glyphsnamesignore_missingrT   rU   rV   rW   rX   orderrc   	allGlyphsri   rJ   r)   r#   has_openr1   open	matchingsm1idxglyph1m0idxglyph0m0pathIxnodes1nodes2nodeIxn1n2this_tolerancematchingm0Isomorphisms	m0Vectors
recording0midRecordingc0c1rcontour0contour1proposed_pointreverserL   midStats	midVectorm0Vecm1Vecsize0size1midSize
overweightproblem_typeexpectedSizetdeviation_thresholdr`   pt0pt1pt0_prevpt1_prevpt0_nextpt1_nextd0_prevd0_nextd1_prevd1_nextsin0sin1dot0dot1r0r1r_diffmidmid_prevmid_nextmid_d0mid_d1sin_midcrossarc_len	deviationdeviation_ratior+   )rd   ra   rx   rt   ru   rb   rv   r,   test_gen   s  


	










(









t  r   c                  O   s2   t t}t| i |D ]\}}|| | q|S r"   )r   r   r   r0   )argskwargsproblemsr(   problemr+   r+   r,   testF  s   r   c                 C   sB   | |v rd S ||  || < t ||  dg D ]
}t|j||| qd S )N
components)r/   recursivelyAddGlyph	glyphName)r(   r)   
ttGlyphSetglyf	componentr+   r+   r,   r   N  s   r   c                 C   s"   t j| }|rt j|dd | S )NT)exist_ok)osrp   dirnamemakedirs)rp   r   r+   r+   r,   ensure_parent_dirW  s   r   c           H         s  ddl }ddl}|jdtjd}|jdddd |jd	d
dd |jddtdt d |jddtdt d |jdd
dd |jdddd |jdddd |jdddd |jdd
dd |jdddd |jdd
dd |jdd t	d!d"d# |jd$d%t	d&d'd( |jd)d*d
d+d |jd,d
d-d |
| } dd.lm} || jrd/nd0d1 | jr|d2d1 | jr| j nd}dd3lm} g }g }g }	t}
t| j}t| jd4krd}| jd d5rdd6lm} || jd }d7d8 |jD | _d9d8 |jD }	d:d; |jD d<d; |jD fd=d; D np| jd d>rrdd?lm}m } || jd }|j!}
||}d@d8 |jD }dAd8 |D }g | _dBd8 |jD }	dCd; |jD dDd; |jD fdEd; D n| jd dFrddGl"m#} || jd }|dH j$}
dI|v ri |dJ }|jD ]}|j%|j&|j'dK|j(< qdL|v r|dL }|j) D ]\}}| * }| D ]\}}t+||| |< qǐq|dI }|dM }i }t,t-}|du rt.|j/0 }|D ]J}|j/| D ]A} i }!g }"t.| j D ]\}#}$|$d4 |!|#< |"1|#|$d4 f qt|"}%|%|vr0|j2|!dNdOdP||%< t3|||% ||% | qqdQg}|2 g}i g}	dRd; t.0 D t.|0 dSdT dUD ]&}%dVdW4fdXdY|%D  dV }&|1|& |1||%  |	1t-|% q_dN| _5g | _|	sdZd8 |D }	| jD ]E}'|'d[rdd\l6m7}( |(|'}t8 })|9|) |)j$}
|1| nddGl"m#} ||'}|dH j$}
|1| |1||':d]d4d  qg }|D ]}t;|d^r|2 n||1fd_d;0 D  q| j<r,t=| j<  fd`d8t>||D } fdad8t>||	D }	 fdbd8|D }|s:t.t=dcd8 |D }t=|}*|D ]t=0 }+|*|+ },|,rY|,D ]}-d|-< qQq@fddd8|	D }	| j?pit}.| j@durs| j@nt}/z4tABdet| tABdftC|	 tD||||	|
| j5|.|/| jEdg	}0t,tF}1| jGdu r|jHntItJ| jGdh}2| jKsb| jLrddlL}3|0D ]\}}4|1| 1|4 qtM|3N|1|2di nd}5|0D ]\}}6|1| 1|6 ||5krtMdj| dk|2di |}5d}7dl|6v r|6dl n|6dm |6dn f}8|8|7kr(do|6v r|6do n|6dp |6dq f}9tMdrds4|9 |2di |8}7|6dt tOjPkr<tMdu|6do  |2di q|6dt tOjQkrPtMdv|6do  |2di q|6dt tOjRkrntMdw|6dx |6dp |6dy |6dq f |2di q|6dt tOjSkrtMdz|6d{ |6dx |6dp |6dy |6dq f |2di q|6dt tOjTkrtMd||6d} |6d{ |6dx |6dp |6dy |6dq f |2di q|6dt tOjUkrtMd~|6dx |6dp |6dy |6dq f |2di q|6dt tOjVkrtMd|6d |6dx |6dp |6dy |6dq |6d f |2di q|6dt tOjWkrtMd|6d |6dp |6dq f |2di q|6dt tOjXkr+tMd|6d |6dp |6dq f |2di q|6dt tOjYkrItMd|6d |6d |6dp |6dq f |2di q|6dt tOjZkr_tMd|6dp |6dq f |2di qn|0D ]\}}4|1| 1|4 qdt[|1}1dD ]n}6t\| |6}:|:du rqwtABd|6] |: d4dl^m_};m`}< |6dkr|;n|<}=|=tJ|:||d3}>|>ja||.|/d |1r|>b|1 |>c|1 |1s| jKs|>d  |1r|>e  |>f  W d   n	1 sw   Y  qw| jgrtABd| jg d4dl^mh}? g }@i }A|?|@||d6}B|Bja|dO|.|/d |1 D ]\}C}D|C|At|@< |Bjc|C|DidOdOd q|1s1| jKs1|Bd  W d   n	1 s<w   Y  ddli}EtItJ| jgdS}2|2jd |2jd |2jd tk|@D ]2\}F}B|F|Av rx|2jd|A|F  dld |2jdld |2j|Em|B |2jd |2jd qa|2jd W d   n	1 sw   Y  W n tny }G z|G jo|7  _otAp|G  d}G~Gww |1r|1S dS )z/Test for interpolatability issues between fontsr   Nzfonttools varLib.interpolatable)descriptionz--glyphsstorez&Space-separate name of glyphs to check)actionhelpz
--show-all
store_truez3Show all glyph pairs, even if no problems are foundz--tolerancez,Error tolerance. Between 0 and 1. Default %s)r   rg   r   z--kinkinessz)How aggressively report kinks. Default %sz--jsonzOutput report in JSON formatz--pdfzOutput report in PDF formatz--psz"Output report in PostScript formatz--htmlzOutput report in HTML formatz--quietz%Only exit with code 1 or 0, no outputz--outputz3Output file for the problem report; Default: stdoutz--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)metavarrg   nargsr   z--nameNAMEr0   zGName of the master to use in the report. If not provided, all are used.)r   rg   r   r   z-vz	--verbosezRun verbosely.z--debugzRun with debug output.)configLoggerINFOERROR)levelDEBUG)basenamer   z.designspace)DesignSpaceDocumentc                 S      g | ]}|j qS r+   )rp   r5   rh   r+   r+   r,   r8         zmain.<locals>.<listcomp>c                 S   r   r+   locationr  r+   r+   r,   r8     r  c                 S       i | ]}|j |j|j|jfqS r+   r#   minimumdefaultmaximumr5   ar+   r+   r,   
<dictcomp>      zmain.<locals>.<dictcomp>c                 S      i | ]}|j |jqS r+   r#   mapr
  r+   r+   r,   r    re   c                    *   i | ]\ } t  fd d|D qS )c                 3   "    | ]}t |t  V  qd S r"   r   dictr5   vaxis_mappingskr+   r,   	<genexpr>       "main.<locals>.<dictcomp>.<genexpr>tupler5   vvr  r  r,   r        )z.glyphsz.glyphspackage)GSFontto_designspacec                 S   r   r+   )font)r5   sourcer+   r+   r,   r8     r  c                 S   s    g | ]}d |j j|j jf qS )z%s-%s)r|   
familyName	styleName)r5   fr+   r+   r,   r8     s     c                 S   r   r+   r  r  r+   r+   r,   r8     r  c                 S   r  r+   r  r
  r+   r+   r,   r    r  c                 S   r  r+   r  r
  r+   r+   r,   r    re   c                    r  )c                 3   r  r"   r  r  r  r+   r,   r    r  r  r  r  r!  r"  r,   r    r#  z.ttf)TTFontheadgvarfvarr<   r   r   avarr   TF)r  
normalizedrecalcBoundsz''c                 S   s   i | ]}|d qS )r/  r+   r
  r+   r+   r,   r    r  c                 S   s   t | | fS r"   )r.   )r  r+   r+   r,   <lambda>  s    zmain.<locals>.<lambda>)key' c                 3   s0    | ]\}}d |t t| | df V  qdS )z%s=%s   N)r   r   )r5   r  r  )axisMappingr+   r,   r  "  s    
zmain.<locals>.<genexpr>c                 S   s   g | ]}i qS r+   r+   )r5   _r+   r+   r,   r8   5  s    z.ufo)	UFOReader.getGlyphSetc                    s   i | ]}| | qS r+   r+   )r5   r  r3   r+   r,   r  O  re   c                       g | ]
\}}| v r|qS r+   r+   )r5   r#   r)   accepted_namesr+   r,   r8   S  
    c                    r=  r+   r+   )r5   r#   r  r>  r+   r,   r8   X  r@  c                    s   g | ]}| v r|qS r+   r+   )r5   r#   r>  r+   r,   r8   ]  rf   c                 S   s   g | ]}|  D ]}|qqS r+   r\   )r5   r)   gnr+   r+   r,   r8   `  r_   c                    s   g | ]}t | qS r+   )r   )r5   loc)axis_triplesr+   r,   r8   k  re   zRunning on %d glyphsetszLocations: %s)r   r   rT   rW   r   rU   rV   rX   w)filezGlyph z was not compatible:ri   rl   rm   rh   rj   rk   z  Masters: %s:z, rg   z"    Glyph was missing in master %sz'    Glyph has an open path in master %sz*    Path count differs: %i in %s, %i in %srn   ro   z5    Node count differs in path %i: %i in %s, %i in %srp   z7    Node %o incompatible in path %i: %s in %s, %s in %srq   z-    Contour order differs: %s in %s, %s in %szD    Contour %d start point differs: %s in %s, %s in %s; reversed: %srL   rw   z3    Contour %d interpolation is underweight: %s, %sz2    Contour %d interpolation is overweight: %s, %sz'    Contour %d has a kink at %s: %s, %srC   z    Showing %s and %s)pspdfzWriting %s to %s)InterpolatablePSInterpolatablePDFrF  )ra   r   )rU   rV   zWriting HTML to %s)InterpolatableSVG)show_tolerancerU   rV   )rK  show_page_numberwbs   <!DOCTYPE html>
sN   <html><body align="center" style="font-family: sans-serif; text-color: #222">
s6   <title>fonttools varLib.interpolatable report</title>
z
<h1>Glyph z</h1>
zutf-8z$<img src='data:image/svg+xml;base64,s   ' />
s   <hr>
s   </body></html>
)qargparsesysArgumentParsermain__doc__add_argumentfloatDEFAULT_TOLERANCEr   str
parse_args	fontToolsr   verboser   r   splitos.pathr   DEFAULT_UPEMr  r   r.   endswithfontTools.designspaceLibr   fromfilesourcesaxesitems	glyphsLibr$  r%  upmfontTools.ttLibr+  
unitsPerEmminValuedefaultValuemaxValueaxisTagsegmentscopyr   r   r  sorted
variationsr]   r0   r<  r   joinr   fontTools.ufoLibr:  r   readInforsplithasattrr#   setr}   rU   rV   r{   r|   r   r   rX   r   outputstdoutr   r   quietjsonprintdumpsr~   r   r   r   r   r   r   r   r   r   r   r   sort_problemsr/   upperinterpolatablePlotrH  rI  add_title_pageadd_summaryadd_problemsdraw_cupcake	add_indexadd_table_of_contentshtmlrJ  base64writerD   encode	b64encode	Exceptionr   error)Hr   rN  rO  parserr   r   r   fontsr   rT   rW   original_args_inputsdesignspacer   r$  r%  gsfontr+  r&  r.  axisr0  rj  rk  fvarMappingr  rC   r-  r   ttGlyphSetsra   r(   varlocDictrB  tagvallocTupler#   filenamer:  r|   	glyphsSetglyphSetGlyphNamesdiffrA  rU   rV   problems_genr   r*  rx  r   last_glyphnameplast_master_idxsmaster_idxsmaster_namesr7   rH  rI  PlotterClassdocrJ  svgsglyph_startssvgrJ   glyph_problemsr  r`   rM   r+   )r?  r8  r  rC  r)   r,   rQ  ^  s  




















 












	


	

	
	

 










rQ  __main__)NNFr"   )8rR  interpolatableHelpersinterpolatableTestContourOrderr   interpolatableTestStartingPointr   fontTools.pens.recordingPenr   r   r   fontTools.pens.transformPenr	   fontTools.pens.statisticsPenr
   r   fontTools.pens.momentsPenr   fontTools.varLib.modelsr   r   fontTools.misc.fixedToolsr   fontTools.misc.transformr   collectionsr   typesr   	functoolsr   pprintr   mathr   r   r   loggingr   	getLoggerr{   rU  r   r   r\  r   r   r   r   r   rQ  rQ   rO  r   exitintboolr+   r+   r+   r,   <module>   sf    
Z   J
	
    