o
    Ae+H                  
   @   s2  d dl Z d dl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mZmZ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 e eZee d ZdZ e!ej"Z#de$fddZ%dede$defddZ&dede$dej'ddfddZ(dede$dej'ddfddZ)dede$deej* deej* fddZ+dede$dej*deej* fddZ,dej-de.fd d!Z/eeee!d"f ee!d"f f eej0ej0f f Z1d#ee$ fd$d%Z2	&d4d'eeeee$e$f  e$e$f  d(ee$ fd)d*Z3ed+g d,Z4G d-d. d.Z5	/d5ded0e1d1e$dee1 fd2d3Z6dS )6    N)defaultdict
namedtuple)reduce)chain)log2)DefaultDictDictIterableListSequenceTuple)OPTIONS)	bit_countbit_indices)TTFont)otBaseotTablesz:COMPRESSION_LEVELZFONTTOOLS_GPOS_COMPACT_MODEreturnc                  C   sd   t } ttjv rdd l}|dt dt tjt } t| dkr(| dv r(t| S t	dt d|  )Nr   'z}' environment variable is deprecated. Please set the 'fontTools.otlLib.optimize.gpos:COMPRESSION_LEVEL' option in TTFont.cfg.   
0123456789zBad =)
GPOS_COMPACT_MODE_DEFAULTGPOS_COMPACT_MODE_ENV_KEYosenvironwarningswarnDeprecationWarninglenint
ValueError)Z	env_levelr    r"   _/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/fontTools/otlLib/optimize/gpos.py_compression_level_from_env   s   


r$   fontlevelc                 C   sZ   | d }|j jjD ]!}|jdkrt| || q	|jdkr*|jd jdkr*t| || q	| S )NZGPOS   	   r   )tableZ
LookupListLookupZ
LookupTypecompact_lookupSubTableZExtensionLookupTypecompact_ext_lookup)r%   r&   Zgposlookupr"   r"   r#   compact*   s   
r/   r.   c                 C   s"   t | ||j}||_t||_d S N)compact_pair_posr,   r   SubTableCount)r%   r&   r.   new_subtablesr"   r"   r#   r+   A   s   r+   c                 C   sX   t | |dd |jD }g }|D ]}t }d|_||_|| q||_t||_d S )Nc                 S   s   g | ]}|j qS r"   )ExtSubTable).0ext_subtabler"   r"   r#   
<listcomp>I   s    z&compact_ext_lookup.<locals>.<listcomp>r   )	r1   r,   r   ZExtensionPosFormatr4   appendr   r2   )r%   r&   r.   r3   Znew_ext_subtablessubtabler6   r"   r"   r#   r-   G   s   r-   	subtablesc                 C   sD   g }|D ]}|j dkr|| q|j dkr|t| || q|S )Nr   r'   )r8   r9   extendcompact_class_pairs)r%   r&   r;   r3   r:   r"   r"   r#   r1   U   s   

r1   r:   c              	   C   s  ddl m} g }tt}|jjD ]}||jj|d 	| qtt}|j
j D ]\}}|| 	| q*i }	t|jD ]/\}}
t|
jD ]%\}}t|rOqFt|dd t|dd f|	tt|| tt|| f< qFq=t| |	|}|D ]}|	|||   qu|S )Nr   )buildPairPosClassesSubtableValue1Value2)ZfontTools.otlLib.builderr>   r   listZCoverageZglyphsZ	ClassDef1Z	classDefsgetr9   Z	ClassDef2items	enumerateZClass1RecordClass2Recordis_really_zerogetattrtuplesorted,cluster_pairs_by_class2_coverage_custom_costgetReverseGlyphMap)r%   r&   r:   r>   r;   Zclasses1gZclasses2iZ	all_pairsclass1jclass2Zgrouped_pairspairsr"   r"   r#   r=   b   s*   

&r=   rP   c                 C   s@   t | dd }t | dd }|d u s| dko|d u p| dkS )Nr?   r@   r   )rG   getEffectiveFormat)rP   v1v2r"   r"   r#   rF   }   s
   rF   .glyphIDsc                 C   st   t | } | d }|gg}| dd  D ]}||d kr'|d | ||g |}q|d | || d | d fS )Nr   r   )rI   r9   )rU   lastrangesZglyphIDr"   r"   r#   _getClassRanges   s   rY   F
class_data	class_idsc                 C   s   |sdS | |d  \}}}t |}|dd  D ]}| | }|t |d 7 }t||d }t||d }q|| d }	d|	d  }
d|d  }t|
|S )Nr   r   r'         )r   minmax)rZ   r[   ZcoverageZfirst_rangesZmin_glyph_idZmax_glyph_idZrange_countrM   dataZ
glyphCountformat1_bytesformat2_bytesr"   r"   r#   _classDef_bytes   s   
rc   ClusteringContext)lines
all_class1all_class1_dataall_class2_datavalueFormat1_bytesvalueFormat2_bytesc                   @   sv   e Zd ZdZdedefddZedd Zedd	 Z	ed
d Z
edd Zedd Zedd Zedd ZdS )Clusterctxindices_bitmask_indices_column_indices_costrm   rn   c                 C   s"   || _ || _d | _d | _d | _d S r0   rl   )selfrm   rn   r"   r"   r#   __init__   s
   
zCluster.__init__c                 C   s   | j d u rt| j| _ | j S r0   )ro   r   rn   rr   r"   r"   r#   indices   s   
zCluster.indicesc                    s6    j d u rttj fdd jD }t| _  j S )Nc                 3   s    | ]	} j j| V  qd S r0   )rm   re   r5   rM   rt   r"   r#   	<genexpr>   s    z)Cluster.column_indices.<locals>.<genexpr>)rp   r   r    __or__ru   r   )rr   Zbitmaskr"   rt   r#   column_indices   s   

zCluster.column_indicesc                 C   s   t | jd S )Nr   )r   ry   rt   r"   r"   r#   width   s   zCluster.widthc                 C   s`   | j d u r-d| j d d d | j d | j d d | jj| jj t| j | j	  | _ | j S )Nr\   r'   )
rq   coverage_bytesclassDef1_bytesclassDef2_bytesrm   ri   rj   r   ru   rz   rt   r"   r"   r#   cost   s8   
	zCluster.costc                    s   dt  fdd jD d  }tt fdd jD }d}d }|D ]\}}|d ur7||d kr7|d7 }|}q%d|d  }t||S )	Nr]   c                 3   s     | ]}t  jj| V  qd S r0   r   rm   rf   rv   rt   r"   r#   rw         z)Cluster.coverage_bytes.<locals>.<genexpr>r'   c                 3   s     | ]} j j| d  V  qdS r   N)rm   rg   rv   rt   r"   r#   rw     r   r   r   r\   )sumru   rI   r   from_iterabler^   )rr   ra   rX   Zmerged_range_countrW   startendrb   r"   rt   r#   r{     s$   
zCluster.coverage_bytesc                    s4   t jfddd tjj fddjD S )Nc                    s   t  jj|  S r0   r   )rM   rt   r"   r#   <lambda>-  s    z)Cluster.classDef1_bytes.<locals>.<lambda>)keyc                    s   g | ]}| kr|qS r"   r"   rv   )biggest_indexr"   r#   r7   /      z+Cluster.classDef1_bytes.<locals>.<listcomp>)r_   ru   rc   rm   rg   rt   r"   )r   rr   r#   r|   &  s   zCluster.classDef1_bytesc                 C   s   t | jj| jS r0   )rc   rm   rh   ry   rt   r"   r"   r#   r}   2  s   zCluster.classDef2_bytesN)__name__
__module____qualname__	__slots__rd   r    rs   propertyru   ry   rz   r~   r{   r|   r}   r"   r"   r"   r#   rk      s"    



!

rk      rQ   compressionc           "         sJ  sgS t tdd D }t tdd D   fdd|D }|  fdd|D }fdd D }d}d} D ] \}	}
||
d rR|
d  ndO }||
d	 r`|
d	  ndO }qCt|d
 }t|d
 }t||||||i dtdtffdddtdtdtffdd}fddt	t
|D }d	t
|> d	 j}tdt
|  t
|d	krkd }d }d }d }t|D ]5\}}t||d	 d  D ]&\}}|||}|j|j |j }|d u s||k r|}|}|d	 | }|}qq|d usJ |d usJ |d usJ |d usJ |dkr^tdd |D }d	||  }td	|  | }tdt
|dd|dd|  |dkrSt
|}t
||d	 kr^qk||= |||< t
|d	kstt} D ]\}	}|||	d  |	< qsg }|D ]}t } |jD ]}|| }!| ||!  q||  q|S )Nc                 s       | ]}|d  V  qdS r   r"   r5   pairr"   r"   r#   rw   B      z?cluster_pairs_by_class2_coverage_custom_cost.<locals>.<genexpr>c                 s   r   )r   Nr"   r   r"   r"   r#   rw   C  r   c                    s(   g | ] t  fd dtD qS )c                 3   s,    | ]\}} |fv rd |> ndV  qdS )r   r   Nr"   )r5   rM   rP   )rN   rQ   r"   r#   rw   G  s
    
Jcluster_pairs_by_class2_coverage_custom_cost.<locals>.<listcomp>.<genexpr>)r   rD   )r5   )
all_class2rQ   )rN   r#   r7   F  s    z@cluster_pairs_by_class2_coverage_custom_cost.<locals>.<listcomp>c                    "   g | ]}t  fd d|D qS )c                 3       | ]} | V  qd S r0   r"   r5   name
name_to_idr"   r#   rw   R  r   r   rY   r5   clsr   r"   r#   r7   Q      c                    r   )c                 3   r   r0   r"   r   r   r"   r#   rw   U  r   r   r   r   r   r"   r#   r7   T  r   r   r   r'   ru   r   c                    s.     | d }|d ur|S t| }| | < |S r0   )rB   rk   )ru   cluster)cluster_cacherm   r"   r#   make_clusterk  s   
zBcluster_pairs_by_class2_coverage_custom_cost.<locals>.make_clusterr   otherc                    s    | j |j B S r0   )rn   )r   r   r   r"   r#   merges  s   z;cluster_pairs_by_class2_coverage_custom_cost.<locals>.mergec                    s   g | ]} d |> qS )r   r"   rv   r   r"   r#   r7   z  r   z        len(clusters) = c                 s   s    | ]}|j V  qd S r0   )r~   )r5   cr"   r"   r#   rw     s    z            len(clusters) = Z3dz    size_reduction=z5.2fz    max_new_subtables=r(   )rI   setrK   rC   rR   r   rd   r    rk   ranger   r~   logdebugrD   r   r   r   dictru   updater9   )"r%   rQ   r   rf   re   rg   rh   Zformat1Zformat2r   valueri   rj   r   ZclustersZcost_before_splittingZlowest_cost_changeZbest_cluster_indexZbest_other_indexZbest_mergedrM   r   rO   r   mergedZcost_changeZcost_after_splittingZsize_reductionZmax_new_subtablesZpairs_by_class1valuesZpairs_groupsZpairs_grouprN   r"   )r   r   rm   r   r   rQ   r#   rJ   8  s   	

	

	
9
rJ   )F)r   )7loggingr   collectionsr   r   	functoolsr   	itertoolsr   mathr   typingr   r   r	   r
   r   r   ZfontTools.configr   ZfontTools.misc.intToolsr   r   ZfontTools.ttLibr   ZfontTools.ttLib.tablesr   r   	getLoggerr   r   ZCOMPRESSION_LEVELr   strdefaultr   r    r$   r/   r*   r+   r-   ZPairPosr1   r=   rE   boolrF   ZValueRecordZPairsrY   rc   rd   rk   rJ   r"   r"   r"   r#   <module>   s     




