o
    a9F                  
   @   s  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mZ d dlmZ d d	lmZmZ d
ZdZe 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j(ej(f f Z)d!ee* fd"d#Z+	$d2d%eeeee*e*f  e*e*f  d&ee* fd'd(Z,ed)g d*Z-G d+d, d,Z.	-d3ded.e)d/e*dee) fd0d1Z/dS )4    N)defaultdict
namedtuple)reduce)chain)log2)DefaultDictDictIterableListSequenceTuple)	bit_countbit_indices)TTFont)otBaseotTablesZFONTTOOLS_GPOS_COMPACT_MODE0zfontTools.otlLib.optimize.gposfontmodereturnc                 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lookup r   @/usr/lib/python3/dist-packages/fontTools/otlLib/optimize/gpos.pycompact   s   
r    r   c                 C   s"   t | ||j}||_t||_d S N)compact_pair_posr   lenSubTableCount)r   r   r   new_subtablesr   r   r   r   ,   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>4   s    z&compact_ext_lookup.<locals>.<listcomp>   )	r"   r   r   ZExtensionPosFormatr&   appendr#   r$   )r   r   r   r%   Znew_ext_subtablessubtabler(   r   r   r   r   2   s   r   	subtablesc                 C   sD   g }|D ]}|j dkr|| q|j dkr|t| || q|S )Nr*   r   )r+   r,   extendcompact_class_pairs)r   r   r.   r%   r-   r   r   r   r"   @   s   

r"   r-   c              	   C   s4  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kr|dv rt| |	t|}|D ]}|	|||   q|S tdt d| )	Nr   )buildPairPosClassesSubtableValue1Value2r*   Z	123456789zBad =)ZfontTools.otlLib.builderr1   r   listZCoverageZglyphsZ	ClassDef1Z	classDefsgetr,   Z	ClassDef2items	enumerateZClass1RecordClass2Recordis_really_zerogetattrtuplesortedr#   ,cluster_pairs_by_class2_coverage_custom_costintgetReverseGlyphMap
ValueErrorGPOS_COMPACT_MODE_ENV_KEY)r   r   r-   r1   r.   Zclasses1gZclasses2iZ	all_pairsclass1jclass2Zgrouped_pairspairsr   r   r   r0   M   s6   

&
r0   rG   c                 C   s@   t | dd }t | dd }|d u s| dko|d u p| dkS )Nr2   r3   r   )r;   getEffectiveFormat)rG   Zv1Zv2r   r   r   r:   p   s
   r:   .glyphIDsc                 C   st   t | } | d }|gg}| dd  D ]}||d kr'|d | ||g |}q|d | || d | d fS )Nr   r*   )r=   r,   )rJ   lastrangesZglyphIDr   r   r   _getClassRanges~   s   rN   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)rO   rP   ZcoverageZfirst_rangesZmin_glyph_idZmax_glyph_idZrange_countrD   dataZ
glyphCountformat1_bytesformat2_bytesr   r   r   _classDef_bytes   s   
rX   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_costrb   rc   c                 C   s"   || _ || _d | _d | _d | _d S r!   ra   )selfrb   rc   r   r   r   __init__   s
   
zCluster.__init__c                 C   s   | j d u rt| j| _ | j S r!   )rd   r   rc   rg   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 r!   )rb   rZ   r'   rD   ri   r   r   	<genexpr>   s    z)Cluster.column_indices.<locals>.<genexpr>)re   r   r?   __or__rj   r   )rg   Zbitmaskr   ri   r   column_indices   s   

zCluster.column_indicesc                 C   s   t | jd S )Nr*   )r#   rn   ri   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 )NrQ   r   )
rf   coverage_bytesclassDef1_bytesclassDef2_bytesrb   r^   r_   r#   rj   ro   ri   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 )	NrR   c                 3   s     | ]}t  jj| V  qd S r!   r#   rb   r[   rk   ri   r   r   rl         z)Cluster.coverage_bytes.<locals>.<genexpr>r   c                 3   s     | ]} j j| d  V  qdS r   N)rb   r\   rk   ri   r   r   rl     ru   r   r*   rQ   )sumrj   r=   r   from_iterablerS   )rg   rV   rM   Zmerged_range_countrL   startendrW   r   ri   r   rp      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 r!   rt   )rD   ri   r   r   <lambda>   s    z)Cluster.classDef1_bytes.<locals>.<lambda>)keyc                    s   g | ]}| kr|qS r   r   rk   )biggest_indexr   r   r)   "      z+Cluster.classDef1_bytes.<locals>.<listcomp>)rT   rj   rX   rb   r\   ri   r   )r}   rg   r   rq     s   zCluster.classDef1_bytesc                 C   s   t | jj| jS r!   )rX   rb   r]   rn   ri   r   r   r   rr   %  s   zCluster.classDef2_bytesN)__name__
__module____qualname__	__slots__rY   r?   rh   propertyrj   rn   ro   rs   rp   rq   rr   r   r   r   r   r`      s"    



!

r`      rH   compressionc           "         sH  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rjd }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]n||= |||< t
|d	kstt} D ]\}	}|||	d  |	< qrg }|D ]}t } |jD ]}|| }!| ||!  q||  q|S )Nc                 s       | ]}|d  V  qdS rv   r   r'   pairr   r   r   rl   5      z?cluster_pairs_by_class2_coverage_custom_cost.<locals>.<genexpr>c                 s   r   )r*   Nr   r   r   r   r   rl   6  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   )r'   rD   rG   )rE   rH   r   r   rl   :  s
    
Jcluster_pairs_by_class2_coverage_custom_cost.<locals>.<listcomp>.<genexpr>)rw   r8   )r'   )
all_class2rH   )rE   r   r)   9  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 r!   r   r'   name
name_to_idr   r   rl   E  r   r   rN   r'   clsr   r   r   r)   D      c                    r   )c                 3   r   r!   r   r   r   r   r   rl   H  r   r   r   r   r   r   r   r)   G  r   r   r*   r   rj   r   c                    s.     | d }|d ur|S t| }| | < |S r!   )r6   r`   )rj   cluster)cluster_cacherb   r   r   make_cluster^  s   
zBcluster_pairs_by_class2_coverage_custom_cost.<locals>.make_clusterr   otherc                    s    | j |j B S r!   )rc   )r   r   r   r   r   mergef  s   z;cluster_pairs_by_class2_coverage_custom_cost.<locals>.mergec                    s   g | ]} d |> qS )r*   r   rk   r   r   r   r)   m  r~   z        len(clusters) = c                 s   s    | ]}|j V  qd S r!   )rs   )r'   cr   r   r   rl     s    z            len(clusters) = Z3dz    size_reduction=z5.2fz    max_new_subtables=r   )r=   setr@   r7   rI   r   rY   r?   r`   ranger#   rs   logdebugr8   rw   r   r   dictrj   updater,   )"r   rH   r   r[   rZ   r\   r]   Zformat1Zformat2r   valuer^   r_   r   ZclustersZcost_before_splittingZlowest_cost_changeZbest_cluster_indexZbest_other_indexZbest_mergedrD   r   rF   r   ZmergedZcost_changeZcost_after_splittingZsize_reductionZmax_new_subtablesZpairs_by_class1valuesZpairs_groupsZpairs_grouprE   r   )r   r   rb   r   r   rH   r   r>   +  s   	

	

	
9
r>   )F)r   )0Zloggingcollectionsr   r   	functoolsr   	itertoolsr   Zmathr   typingr   r   r	   r
   r   r   ZfontTools.misc.intToolsr   r   ZfontTools.ttLibr   ZfontTools.ttLib.tablesr   r   rB   ZGPOS_COMPACT_MODE_DEFAULTZ	getLoggerr   strr    r   r   r   ZPairPosr"   r0   r9   boolr:   ZValueRecordZPairsr?   rN   rX   rY   r`   r>   r   r   r   r   <module>   sz     


#
