U
    #vhH                     @   s  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#e$dddZ%ee$edddZ&ee$ej'ddddZ(ee$ej'ddddZ)ee$eej* eej* dddZ+ee$ej*eej* dddZ,ej-e.ddd Z/eeee!d!f ee!d!f f eej0ej0f f Z1ee$ d"d#d$Z2d6eeeee$e$f  e$e$f  ee$ d&d'd(Z3ed)d*d+d,d-d.d/gZ4G d0d1 d1Z5d7ee1e$ee1 d3d4d5Z6dS )8    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   sh   t } ttjkr4dd l}|dt dt tjt } t| dkrP| dkrPt| S t	dt d|  d S )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"   B/tmp/pip-unpacked-wheel-1ufboor8/fontTools/otlLib/optimize/gpos.py_compression_level_from_env   s    


r$   )fontlevelr   c                 C   sh   |  d}|d kr| S |jjjD ]B}|jdkr<t| || q |jdkr |jd jdkr t| || q | S )NZGPOS   	   r   )	gettableZ
LookupListLookupZ
LookupTypecompact_lookupSubTableZExtensionLookupTypecompact_ext_lookup)r%   r&   Zgposlookupr"   r"   r#   compact*   s    

r0   )r%   r&   r/   r   c                 C   s"   t | ||j}||_t||_d S N)compact_pair_posr-   r   SubTableCount)r%   r&   r/   new_subtablesr"   r"   r#   r,   G   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>O   s     z&compact_ext_lookup.<locals>.<listcomp>r   )	r2   r-   r   ZExtensionPosFormatr5   appendr   r3   )r%   r&   r/   r4   Znew_ext_subtablessubtabler7   r"   r"   r#   r.   M   s      r.   )r%   r&   	subtablesr   c                 C   sD   g }|D ]6}|j dkr"|| q|j dkr|t| || q|S )Nr   r'   )r9   r:   extendcompact_class_pairs)r%   r&   r<   r4   r;   r"   r"   r#   r2   [   s    

r2   )r%   r&   r;   r   c              	   C   s  ddl m} g }tt}|jjD ]}||jj|d 	| q tt}|j
j D ]\}}|| 	| qTi }	t|jD ]^\}}
t|
jD ]J\}}t|rqt|dd t|dd f|	tt|| tt|| f< qqzt| |	|}|D ]}|	|||   q|S )Nr   )buildPairPosClassesSubtableValue1Value2)ZfontTools.otlLib.builderr?   r   listZCoverageZglyphsZ	ClassDef1Z	classDefsr)   r:   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>   h   s(    

(r>   )rP   r   c                 C   s@   t | dd }t | dd }|d ks,| dko>|d kp>| dkS )Nr@   rA   r   )rG   getEffectiveFormat)rP   v1Zv2r"   r"   r#   rF      s
    rF   .)glyphIDsc                 C   st   t | } | d }|gg}| dd  D ].}||d krN|d | ||g |}q$|d | || d | d fS )Nr   r   )rI   r:   )rT   lastrangesZglyphIDr"   r"   r#   _getClassRanges   s    rX   F)
class_data	class_idsc                 C   s   |sdS | |d  \}}}t |}|dd  D ]8}| | }|t |d 7 }t||d }t||d }q.|| d }	d|	d  }
d|d  }t|
|S )Nr   r   r'         )r   minmax)rY   rZ   ZcoverageZfirst_rangesZmin_glyph_idZmax_glyph_idZrange_countrM   dataZ
glyphCountformat1_bytesformat2_bytesr"   r"   r#   _classDef_bytes   s    rb   ClusteringContextlines
all_class1all_class1_dataall_class2_datavalueFormat1_bytesvalueFormat2_bytesc                   @   st   e Zd ZdZeed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_cost)rl   rm   c                 C   s"   || _ || _d | _d | _d | _d S r1   rk   )selfrl   rm   r"   r"   r#   __init__   s
    zCluster.__init__c                 C   s   | j d krt| j| _ | j S r1   )rn   r   rm   rq   r"   r"   r#   indices   s    
zCluster.indicesc                    s6    j d kr0ttj fdd jD }t| _  j S )Nc                 3   s   | ]} j j| V  qd S r1   )rl   rd   r6   rM   rs   r"   r#   	<genexpr>   s     z)Cluster.column_indices.<locals>.<genexpr>)ro   r   r    __or__rt   r   )rq   Zbitmaskr"   rs   r#   column_indices   s    

zCluster.column_indicesc                 C   s   t | jd S )Nr   )r   rx   rs   r"   r"   r#   width   s    zCluster.widthc                 C   s`   | j d krZd| j d d d | j d | j d d | jj| jj t| j | j	  | _ | j S )Nr[   r'   )
rp   coverage_bytesclassDef1_bytesclassDef2_bytesrl   rh   ri   r   rt   ry   rs   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 k	rn||d krn|d7 }|}qJd|d  }t||S )	Nr\   c                 3   s   | ]}t  jj| V  qd S r1   r   rl   re   ru   rs   r"   r#   rv     s     z)Cluster.coverage_bytes.<locals>.<genexpr>r'   c                 3   s   | ]} j j| d  V  qdS r   N)rl   rf   ru   rs   r"   r#   rv     s     r   r   r[   )sumrt   rI   r   from_iterabler]   )rq   r`   rW   Zmerged_range_countrV   startendra   r"   rs   r#   rz     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 r1   r~   )rM   rs   r"   r#   <lambda>4      z)Cluster.classDef1_bytes.<locals>.<lambda>)keyc                    s   g | ]}| kr|qS r"   r"   ru   )biggest_indexr"   r#   r8   6  s      z+Cluster.classDef1_bytes.<locals>.<listcomp>)r^   rt   rb   rl   rf   rs   r"   )r   rq   r#   r{   -  s
     zCluster.classDef1_bytesc                 C   s   t | jj| jS r1   )rb   rl   rg   rx   rs   r"   r"   r#   r|   9  s    zCluster.classDef2_bytesN)__name__
__module____qualname__	__slots__rc   r    rr   propertyrt   rx   ry   r}   rz   r{   r|   r"   r"   r"   r#   rj      s    



!

rj      )r%   rQ   compressionr   c           "         sD  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 r|
d  ndO }||
d	 r|
d	  ndO }qt|d
 }t|d
 }t||||||i ttdfddtttdfdd}fddt	t
|D }d	t
|> d	 j}tdt
|  t
|d	krd }d }d }d }t|D ]r\}}t||d	 d  D ]R\}}|||}|j|j |j }|d ks||k r|}|}|d	 | }|}qq|d k	st|d k	st|d k	s*t|d k	s8t|dkrtdd |D }d	||  }td	|  | }tdt
|dd|dd|  |dkrt
|}t
||d	 krq||= |||< qftt} D ]\}	}|||	d  |	< qg }|D ]:}t } |jD ]}|| }!| ||!  q||  q|S )Nc                 s   s   | ]}|d  V  qdS r   r"   r6   pairr"   r"   r#   rv   I  s     z?cluster_pairs_by_class2_coverage_custom_cost.<locals>.<genexpr>c                 s   s   | ]}|d  V  qdS )r   Nr"   r   r"   r"   r#   rv   J  s     c                    s(   g | ]  t  fd dtD qS )c                 3   s*   | ]"\}} |fkrd |> ndV  qdS )r   r   Nr"   )r6   rM   rP   )rN   rQ   r"   r#   rv   N  s   Jcluster_pairs_by_class2_coverage_custom_cost.<locals>.<listcomp>.<genexpr>)r   rD   )r6   )
all_class2rQ   )rN   r#   r8   M  s   z@cluster_pairs_by_class2_coverage_custom_cost.<locals>.<listcomp>c                    s"   g | ]}t  fd d|D qS )c                 3   s   | ]} | V  qd S r1   r"   r6   name
name_to_idr"   r#   rv   Y  s     r   rX   r6   clsr   r"   r#   r8   X  s    c                    s"   g | ]}t  fd d|D qS )c                 3   s   | ]} | V  qd S r1   r"   r   r   r"   r#   rv   \  s     r   r   r   r   r"   r#   r8   [  s    r   r   r'   )rt   r   c                    s.     | d }|d k	r|S t| }| | < |S r1   )r)   rj   )rt   cluster)cluster_cacherl   r"   r#   make_clusterr  s    
zBcluster_pairs_by_class2_coverage_custom_cost.<locals>.make_cluster)r   otherr   c                    s    | j |j B S r1   )rm   )r   r   r   r"   r#   mergez  s    z;cluster_pairs_by_class2_coverage_custom_cost.<locals>.mergec                    s   g | ]} d |> qS )r   r"   ru   r   r"   r#   r8     s     z        len(clusters) = c                 s   s   | ]}|j V  qd S r1   )r}   )r6   cr"   r"   r#   rv     s     z            len(clusters) = Z3dz    size_reduction=z5.2fz    max_new_subtables=r(   )rI   setrK   rC   rR   r   rc   r    rj   ranger   r}   logdebugrD   AssertionErrorr   r   r   dictrt   updater:   )"r%   rQ   r   re   rd   rf   rg   Zformat1Zformat2r   valuerh   ri   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   rl   r   r   rQ   r#   rJ   ?  s    	

	

	

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$   r0   r+   r,   r.   ZPairPosr2   r>   rE   boolrF   ZValueRecordZPairsrX   rb   rc   rj   rJ   r"   r"   r"   r#   <module>   st    

      