o
    AeX                     @   s  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 d dlmZ d dlmZ d dlmZmZ ejZeej_d	d
 ZG dd deZedddZeej_dd Zeej _!dd Z"e"ej_#G dd deZ$dde% fddZ&e&ej_'dd Z(e(ej_)dd Z*dd Z+d d! Z,e,ej-_.e,ej/_.d"d# Z0d$d% Z1e1ej-_2e1ej/_2G d&d' d'eZ3G d(d) d)e4Z5d1d+d,Z6e6ej_7d2d.d/Z8e9d0krd d-l:Z:e;e:j<d*kre:=e8  d d-l>Z>e:=e>? j@ d-S d-S )3    )noRoundotRound	bit_count)otTables)supportScalar)buildVarRegionListbuildVarStorebuildVarRegionbuildVarData)partial)defaultdict)heappushheappopc                 C   s   t t|  dd dS )Nc                 S   s   | d S Nr    )kvr   r   Z/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/fontTools/varLib/varStore.py<lambda>   s    z!_getLocationKey.<locals>.<lambda>key)tuplesorteditems)locr   r   r   _getLocationKey   s   r   c                   @   sR   e Zd Zdd Zdd Zdd Zddd	Zd
d ZedddZ	edddZ
dS )OnlineVarStoreBuilderc                 C   sN   || _ i | _tg || _t| jg | _d | _d | _d | _i | _	i | _
i | _d S N)	_axisTags
_regionMapr   _regionListr	   _store_data_model	_supports_varDataIndices_varDataCaches_cache)selfZaxisTagsr   r   r   __init__   s   
zOnlineVarStoreBuilder.__init__c                 C   s   |  |j || _d S r   )setSupportssupportsr#   )r(   modelr   r   r   setModel%   s   
zOnlineVarStoreBuilder.setModelc                 C   s2   d | _ t|| _| jd s| jd= i | _d | _d S r   )r#   listr$   r'   r"   )r(   r+   r   r   r   r*   )   s   


z!OnlineVarStoreBuilder.setSupportsTc                 C   sL   t | jj| j_t | jj| j_| jjD ]}t |j|_|j	|d q| jS )Noptimize)
lenr    RegionRegionCountr!   VarDataVarDataCountItem	ItemCountcalculateNumShorts)r(   r0   datar   r   r   finish1   s   zOnlineVarStoreBuilder.finishc           
      C   s(  | j }| j}| j}g }|D ])}t|}||}|d u r1t|| j}t|j }||< |j	| |	| qt
|}| j|}	|	d ur_|	| _| jj|	 | _| j| | _t| jjdkr_d }	|	d u rt|g dd| _t| jj| _| jj	| j | j| j|< || jvri | j|< | j| | _d S d S )N  Fr/   )r   r    r$   r   getr
   r   r1   r2   appendr   r%   _outerr!   r4   r"   r&   r'   r6   r   )
r(   	regionMap
regionListregionsregionIndicesregionr   idxZ	varRegionZ
varDataIdxr   r   r   _add_VarData9   s:   


z"OnlineVarStoreBuilder._add_VarDataroundc                C   s,   | j j||d}|d}|| j|tdfS )NrF   r   )r#   Z	getDeltaspopstoreDeltasr   )r(   Zmaster_valuesrG   deltasbaser   r   r   storeMasters\   s   
z"OnlineVarStoreBuilder.storeMastersc                   s    fdd|D }t |t | jd krt|dd  }nt |t | jks(J t|}| j|}|d ur8|S | js?|   t | jj}|dkrR|   | |S | jj	|t
d | jd> | }|| j|< |S )Nc                       g | ]} |qS r   r   .0drF   r   r   
<listcomp>b       z5OnlineVarStoreBuilder.storeDeltas.<locals>.<listcomp>   r;   rF      )r1   r$   r   r'   r<   r"   rE   r6   rI   addItemr   r>   )r(   rJ   rG   varIdxinnerr   rF   r   rI   a   s$   

z!OnlineVarStoreBuilder.storeDeltasN)T)__name__
__module____qualname__r)   r-   r*   r:   rE   rG   rL   rI   r   r   r   r   r      s    
#r   rF   c                   sz    fdd|D }| j }t|}|d |krt|dd  }n||ks)J ||ft|}| jt| t| j| _d S )Nc                    rM   r   r   rN   rF   r   r   rQ   |   rR   z#VarData_addItem.<locals>.<listcomp>rS   )VarRegionCountr1   r   r6   r=   r.   r7   )r(   rJ   rG   ZcountUsZ	countThemr   rF   r   VarData_addItem{   s   r\   c                    s    fddt | jD S )Nc                    s2   i | ]\}}|j d kr | j|j|j |jfqS )r   )Z	PeakCoordZaxisTagZ
StartCoordZEndCoord)rO   ireg	fvar_axesr   r   
<dictcomp>   s    z)VarRegion_get_support.<locals>.<dictcomp>)	enumerateZVarRegionAxis)r(   r`   r   r_   r   VarRegion_get_support   s   
rc   c                 C   s
   t | jS r   )boolr4   r(   r   r   r   VarStore___bool__      
rf   c                   @   sL   e Zd Zi fddZdd Zdd Zdd Zed	d
 Zdd Z	dd Z
dS )VarStoreInstancerc                 C   sL   || _ |d u s|jdksJ |r|jng | _|r|jjng | _| | d S )NrS   )r`   ZFormatr4   _varDataVarRegionListr2   _regionssetLocation)r(   Zvarstorer`   locationr   r   r   r)      s
   zVarStoreInstancer.__init__c                 C   s   t || _|   d S r   )dictrm   _clearCaches)r(   rm   r   r   r   rl      s   
zVarStoreInstancer.setLocationc                 C   s
   i | _ d S r   )_scalarsre   r   r   r   ro      rg   zVarStoreInstancer._clearCachesc                 C   s@   | j |}|d u r| j| | j}t| j|}|| j |< |S r   )rp   r<   rk   get_supportr`   r   rm   )r(   	regionIdxZscalarZsupportr   r   r   
_getScalar   s   
zVarStoreInstancer._getScalarc                 C   s.   d}t | |D ]\}}|sq||| 7 }q|S )N        )zip)rJ   scalarsdeltarP   sr   r   r   interpolateFromDeltasAndScalars   s   z1VarStoreInstancer.interpolateFromDeltasAndScalarsc                    sV   |d? |d@ }}|t krdS  j} fdd|| jD }|| j| } ||S )NrT   r;   rt   c                       g | ]}  |qS r   rs   rO   rire   r   r   rQ          z1VarStoreInstancer.__getitem__.<locals>.<listcomp>)NO_VARIATION_INDEXri   VarRegionIndexr6   ry   )r(   ZvaridxmajorminorvarDatarv   rJ   r   re   r   __getitem__   s   zVarStoreInstancer.__getitem__c                    s*    j } fdd|| jD } ||S )Nc                    rz   r   r{   r|   re   r   r   rQ      r~   z;VarStoreInstancer.interpolateFromDeltas.<locals>.<listcomp>)ri   r   ry   )r(   ZvarDataIndexrJ   r   rv   r   re   r   interpolateFromDeltas   s   z'VarStoreInstancer.interpolateFromDeltasN)rX   rY   rZ   r)   rl   ro   rs   staticmethodry   r   r   r   r   r   r   rh      s    
	rh   TFc                 C   s  i }|D ]$}|t krq|d? }|d@ }||}	|	d u r#t  }	||< |	| q~| j}
g }t t i}t|
D ]\}}||}|d u rEq7t|}|| |j}g }|dkr{|r{t	t|D ]}|||v rk|| ndgt||   |||< q_n/|dkrt
|t
||  }nt
|}|D ]}t|}|||  |d> | ||d> | < q||_t|j|_|j|d q7|| _t| j| _|   |S )NrT   r;   r   r/   )r   r<   setaddr4   rb   r1   r=   r6   ranger   r7   r8   r5   prune_regions)r(   ZvarIdxesr0   ZretainFirstMapZadvIdxesusedrV   r   r   rP   r   Z
newVarDataZ
varDataMapr9   Z
usedMinorsZnewMajorr   ZnewItemsZminorsZnewMinorr   r   r   VarStore_subset_varidxes   sV   


 
r   c                    s   t  }| jD ]}||j q| j}|j}g }i  t|D ]}t| |< |||  q||_t|j|_	| jD ]} fdd|jD |_q9dS )zRemove unused VarRegions.c                    s   g | ]} | qS r   r   )rO   r]   r?   r   r   rQ   *  rR   z*VarStore_prune_regions.<locals>.<listcomp>N)
r   r4   updater   rj   r2   r   r1   r=   r3   )r(   ZusedRegionsr9   r@   rA   Z
newRegionsr]   r   r   r   VarStore_prune_regions  s   

r   c                 C   s   t | tjkr||  dS t| tr| D ]}t|| qdS t| drAt| dsA|  D ]}t| |j	d}|dur>t|| q,dS t| tj
rT| j D ]	}t|| qLdS dS )zqRecurse down from self, if type of an object is ot.Device,
    call func() on it.  Works on otData-style classes.getConvertersZpostReadN)typeotZDevice
isinstancer.   _visithasattrr   getattrnameZValueRecord__dict__values)r(   functhatconvr   r   r   r   0  s$   

r   c                 C   s(   | j dkr|| jd> | j  dS dS )z6Add VarIdx in this Device table (if any) to the set s.   rT   N)DeltaFormatr   	StartSizeEndSize)r(   rx   r   r   r   _Device_recordVarIdxF  s   
r   c                 C   s   t t|d}t| | d S )N)rx   )r   r   r   )r(   ZvaridxesZadderr   r   r   Object_collect_device_varidxesL  s   r   c                 C   sX   t | |v rdS |t |  | jdkr*|| jd> | j  }|d? | _|d@ | _dS dS )z9Map VarIdx in this Device table (if any) through mapping.Nr   rT   r;   )idr   r   r   r   )r(   mappingdonerV   r   r   r   _Device_mapVarIdxU  s   

r   c                 C   s   t t|t d}t| | d S )N)r   r   )r   r   r   r   )r(   Zvaridxes_mapZmapperr   r   r   Object_remap_device_varidxes`  s   r   c                   @   st   e Zd Zdd Zdd Zdd Zdd ZeeZd	d
 Z	ee	Z
dd Zdd Zedd Zedd Zdd ZdS )	_Encodingc                 C   s6   || _ t|| _| || _| | j| _t | _d S r   )	charsr   width_columnscolumns_characteristic_overheadoverheadr   r   )r(   r   r   r   r   r)   j  s
   
z_Encoding.__init__c                 C      | j | d S r   )r   r   )r(   rowr   r   r   r=   q     z_Encoding.appendc                 C   r   r   )r   r   )r(   lstr   r   r   extendt  r   z_Encoding.extendc                 C   s$   t | j}td| jd | | j S )z~Maximum number of bytes that can be added to characteristic
        while still being beneficial to merge it into another one.r   rS   )r1   r   maxr   r   r(   countr   r   r   get_roomw  s   
z_Encoding.get_roomc                 C   s   t | j}td| j| S )zQMaximum possible byte gain from merging this into another
        characteristic.r   )r1   r   r   r   r   r   r   r   get_gain  s   
z_Encoding.get_gainc                 C      | j | jfS r   )gainr   re   r   r   r   gain_sort_key     z_Encoding.gain_sort_keyc                 C   r   r   )r   r   re   r   r   r   width_sort_key  r   z_Encoding.width_sort_keyc                 C   s   d}|t | d 7 }|S )zOReturns overhead in bytes of encoding this characteristic
        as a VarData.
      r   )r   cr   r   r   r     s   z"_Encoding._characteristic_overheadc                 C   s4   d}d}| r| d@ r||O }| dL } |dK }| s|S )Nr   rS         r   )r   colsr]   r   r   r   r     s   z_Encoding._columnsc                 C   sh   |j | j B }t|}| j|jB }t|}| j
 |j | || j t| j  ||j t|j  }|S r   )	r   r   r   r   r   r   r   r1   r   )r(   other_encodingcombined_charsZcombined_widthZcombined_columnsZcombined_overheadZcombined_gainr   r   r   gain_from_merging  s   
z_Encoding.gain_from_mergingN)rX   rY   rZ   r)   r=   r   r   propertyroomr   r   r   r   r   r   r   r   r   r   r   r   r   i  s    


r   c                   @   s(   e Zd Zdd Zdd Zedd ZdS )_EncodingDictc                 C   s   t | }| |< |S r   )r   )r(   r   rr   r   r   __missing__  s   z_EncodingDict.__missing__c                 C   s   |  |}| | | d S r   )_row_characteristicsr=   )r(   r   r   r   r   r   add_row  s   
z_EncodingDict.add_rowc                 C   s   d}d}d}| D ],}|r||7 }d|  krdks!n ||d 7 }d|  kr+dks0n d	} q5|d
K }q|r]d}d}| D ]}|rG||d 7 }d|  krQdksXn ||d 7 }|d
K }q=|S )z+Returns encoding characteristics for a row.Fr   rS   i   r   i i  Tr         r   )r   Z	longWordsr   r]   vr   r   r   r     s,   

z"_EncodingDict._row_characteristicsN)rX   rY   rZ   r   r   r   r   r   r   r   r   r     s
    r   rS   c              	   C   sj  t | jj}dg| }i }t }t| jD ]d\}}|j}	t|jD ]W\}
}t|}|dkr@t	|	|D ]\}}||  |7  < q2nt	|	|D ]\}}||  t
|| | 7  < qEt|}|rkt|skd||d> |
 < q!|| |||d> |
 < q!qt| tjd}~g }t|D ]&\}}t|d t |D ]}|| }||}|dkrt|| ||f qq|r*t|\}}}|| du s|| du rq|| || }}d\||< ||< |j|jB }t|}||j ||j t|D ]/\}}|du rq|j|kr||j d||< q||}|dkr"t|| |t |f q|| |sdd |D }i }|jtjd g | _t|D ]3\}}t }| j| t||_t |j|_t|j|_t|jD ]\}
}|d> |
 ||< qeqAtti}| D ]\}}|dur|| nt||< q}t | jj| j_t | j| _ | jD ]}t |j|_!|"  q| #  |S )	z@Optimize storage. Returns mapping from old VarIdxes to new ones.r   rS   NrT   r   )NNc                 S   s   g | ]}|d ur|qS r   r   )rO   encodingr   r   r   rQ   h  s    z%VarStore_optimize.<locals>.<listcomp>)$r1   rj   r2   r   rb   r4   r   r6   r.   ru   rG   r   anyr   r   r   r   r   r   r   r   r   r   r   r   r=   sortr   r   r[   r   r3   r5   r7   r0   r   )r(   Zuse_NO_VARIATION_INDEXquantizationnZzeroesZfront_mapping	encodingsr   r9   rB   r   itemr   rr   r   todoheapr]   r   jr   Zcombining_gain_r   Zcombined_encodingkencZback_mapping
varidx_mapr   r   r   VarStore_optimize  s   D







r   Nc                 C   sB  ddl m} ddlm} ddlm} ddlm} |dtj	d}|j
dtd	d
 |
d |j
ddd || }|dd |j}|j}|j}	||}
|
d }|jj}| }|||
 t| }td|  |j|d}| }|||
 t| }td|  |	dur|j| d|
v r|
d j| |
|	 dS dS )z&Optimize a font's GDEF variation storer   )ArgumentParser)configLogger)TTFont)OTTableWriterzvarLib.varStore)progdescriptionz--quantizationrS   )r   defaultfontfileoutfile?)nargsINFO)levelGDEFzBefore: %7d bytes)r   zAfter:  %7d bytesNGPOS)argparser   Z	fontToolsr   ZfontTools.ttLibr   ZfontTools.ttLib.tables.otBaser   main__doc__add_argumentint
parse_argsr   r   r   tableVarStorecompiler1   Z
getAllDataprintr0   remap_device_varidxessave)argsr   r   r   r   parseroptionsr   r   r   ZfontZgdefstorewritersizer   r   r   r   r     s>   


r   __main__)TrS   r   )AZfontTools.misc.roundToolsr   r   ZfontTools.misc.intToolsr   ZfontTools.ttLib.tablesr   r   ZfontTools.varLib.modelsr   ZfontTools.varLib.builderr   r	   r
   r   	functoolsr   collectionsr   heapqr   r   r   r   r   objectr   rG   r\   r4   rU   rc   Z	VarRegionrq   rf   __bool__rh   r   r   Zsubset_varidxesr   r   r   r   r   r   Zcollect_device_varidxesr   r   r   r   r   rn   r   r   r0   r   rX   sysr1   argvexitdoctesttestmodfailedr   r   r   r   <module>   s\    c7
=F
( 3
,