U
    i2e+H                     @   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-txsm8jh_/fontTools/otlLib/optimize/gpos.py_compression_level_from_env   s    


r$   )fontlevelr   c                 C   sZ   | d }|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   )tableZ
LookupListLookupZ
LookupTypecompact_lookupSubTableZExtensionLookupTypecompact_ext_lookup)r%   r&   Zgposlookupr"   r"   r#   compact*   s    
r/   )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+   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-   )r%   r&   	subtablesr   c                 C   sD   g }|D ]6}|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%   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	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   r   c                 C   s@   t | dd }t | dd }|d ks,| dko>|d kp>| dkS )Nr?   r@   r   )rG   getEffectiveFormat)rP   Z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   r9   )rS   lastrangesZglyphIDr"   r"   r#   _getClassRanges   s    rW   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)rX   rY   ZcoverageZfirst_rangesZmin_glyph_idZmax_glyph_idZrange_countrM   dataZ
glyphCountformat1_bytesformat2_bytesr"   r"   r#   _classDef_bytes   s    ra   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)rk   rl   c                 C   s"   || _ || _d | _d | _d | _d S r0   rj   )selfrk   rl   r"   r"   r#   __init__   s
    zCluster.__init__c                 C   s   | j d krt| j| _ | j S r0   )rm   r   rl   rp   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 r0   )rk   rc   r5   rM   rr   r"   r#   	<genexpr>   s     z)Cluster.column_indices.<locals>.<genexpr>)rn   r   r    __or__rs   r   )rp   Zbitmaskr"   rr   r#   column_indices   s    

zCluster.column_indicesc                 C   s   t | jd S )Nr   )r   rw   rr   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 )NrZ   r'   )
ro   coverage_bytesclassDef1_bytesclassDef2_bytesrk   rg   rh   r   rs   rx   rr   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 r0   r   rk   rd   rt   rr   r"   r#   ru     s     z)Cluster.coverage_bytes.<locals>.<genexpr>r'   c                 3   s   | ]} j j| d  V  qdS r   N)rk   re   rt   rr   r"   r#   ru     s     r   r   rZ   )sumrs   rI   r   from_iterabler\   )rp   r_   rV   Zmerged_range_countrU   startendr`   r"   rr   r#   ry     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   rr   r"   r#   <lambda>-      z)Cluster.classDef1_bytes.<locals>.<lambda>)keyc                    s   g | ]}| kr|qS r"   r"   rt   )biggest_indexr"   r#   r7   /  s      z+Cluster.classDef1_bytes.<locals>.<listcomp>)r]   rs   ra   rk   re   rr   r"   )r   rp   r#   rz   &  s
     zCluster.classDef1_bytesc                 C   s   t | jj| jS r0   )ra   rk   rf   rw   rr   r"   r"   r#   r{   2  s    zCluster.classDef2_bytesN)__name__
__module____qualname__	__slots__rb   r    rq   propertyrs   rw   rx   r|   ry   rz   r{   r"   r"   r"   r#   ri      s    



!

ri      )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"   r5   pairr"   r"   r#   ru   B  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#   ru   C  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"   )r5   rM   rP   )rN   rQ   r"   r#   ru   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                    s"   g | ]}t  fd d|D qS )c                 3   s   | ]} | V  qd S r0   r"   r5   name
name_to_idr"   r#   ru   R  s     r   rW   r5   clsr   r"   r#   r7   Q  s    c                    s"   g | ]}t  fd d|D qS )c                 3   s   | ]} | V  qd S r0   r"   r   r   r"   r#   ru   U  s     r   r   r   r   r"   r#   r7   T  s    r   r   r'   )rs   r   c                    s.     | d }|d k	r|S t| }| | < |S r0   )rB   ri   )rs   cluster)cluster_cacherk   r"   r#   make_clusterk  s    
zBcluster_pairs_by_class2_coverage_custom_cost.<locals>.make_cluster)r   otherr   c                    s    | j |j B S r0   )rl   )r   r   r   r"   r#   merges  s    z;cluster_pairs_by_class2_coverage_custom_cost.<locals>.mergec                    s   g | ]} d |> qS )r   r"   rt   r   r"   r#   r7   z  s     z        len(clusters) = c                 s   s   | ]}|j V  qd S r0   )r|   )r5   cr"   r"   r#   ru     s     z            len(clusters) = Z3dz    size_reduction=z5.2fz    max_new_subtables=r(   )rI   setrK   rC   rR   r   rb   r    ri   ranger   r|   logdebugrD   AssertionErrorr   r   r   dictrs   updater9   )"r%   rQ   r   rd   rc   re   rf   Zformat1Zformat2r   valuerg   rh   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   rk   r   r   rQ   r#   rJ   8  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$   r/   r*   r+   r-   ZPairPosr1   r=   rE   boolrF   ZValueRecordZPairsrW   ra   rb   ri   rJ   r"   r"   r"   r#   <module>   st    

      