U
    #vh^                     @   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ddZ&e&ej_'ddd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Z5d5d/d0Z6e6ej_7d6d2d3Z8e9d4krd d1l:Z:e;e:j<d.kre:=e8  d d1l>Z>e:=e>? j@ d1S )7    )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   =/tmp/pip-unpacked-wheel-1ufboor8/fontTools/varLib/varStore.py<lambda>       z!_getLocationKey.<locals>.<lambda>key)tuplesorteditems)locr   r   r   _getLocationKey   s    r   c                   @   sp   e Zd Zdd Zdd Zdd Zddd	ZdddZedddZ	ed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 | _
d | _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   s8   d | _ t|| _| jr(| jd s(| jd= d | _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)   r1   datar   r   r   finish1   s    zOnlineVarStoreBuilder.finish   c                 C   s,  | j }| j}| j}g }|D ]R}t|}||}|d krbt|| j}	t|j }||< |j	|	 |	| qt
|}| j|}
|
d k	r|
| _| jj|
 | _| j| | _t| jj| dkrd }
|
d kr(t|g dd| _t| jj| _| jj	| j | j| j|< || jkri | j|< | j| | _d S )N  Fr0   )r    r!   r%   r   getr
   r   r2   r3   appendr   r&   _outerr"   r5   r#   r'   r(   r7   r   )r)   Z	num_items	regionMap
regionListregionsregionIndicesZregionr   idxZ	varRegionZ
varDataIdxr   r   r   _add_VarData9   s8    


z"OnlineVarStoreBuilder._add_VarDataroundc                C   s,   | j j||d}|d}|| j|tdfS )NrG   r   )r$   	getDeltaspopstoreDeltasr   )r)   master_valuesrH   deltasbaser   r   r   storeMasters\   s    
z"OnlineVarStoreBuilder.storeMastersc                   s4    fdd|D }dd |D }|j |tdfS )Nc                    s   g | ]}j j| d qS )rG   )r$   rI   ).0rL   rH   r)   r   r   
<listcomp>b   s   z:OnlineVarStoreBuilder.storeMastersMany.<locals>.<listcomp>c                 S   s   g | ]}| d qS r   )rJ   rP   rM   r   r   r   rR   f   s     rG   )storeDeltasManyr   )r)   Zmaster_values_listrH   deltas_listZ	base_listr   rQ   r   storeMastersManya   s
    z&OnlineVarStoreBuilder.storeMastersManyc                   s    fdd|D }t |t | jd kr:t|dd  }nt |t | jksPtt|}| jsf|   | j|}|d k	r~|S t | jj}|dkr|   | j	|t
dS | jj|t
d | jd> | }|| j|< |S )Nc                    s   g | ]} |qS r   r   rP   drG   r   r   rR   j   s     z5OnlineVarStoreBuilder.storeDeltas.<locals>.<listcomp>r<   r=   rG      )r2   r%   r   AssertionErrorr#   rF   r(   r>   r7   rK   r   addItemr@   )r)   rM   rH   varIdxinnerr   rG   r   rK   i   s$    
z!OnlineVarStoreBuilder.storeDeltasc                   s    fdd|D }t dd |D }| js8| t| | j|}|d k	rP|S t| jj}|t| dkr| t| | j|tdS t	|D ]4\}}| jj
|td | jd> | | }|| j|< q| jd> | }|| j|< |S )Nc                    s   g | ]} fd d|D qS )c                    s   g | ]} |qS r   r   rX   rG   r   r   rR      s     zDOnlineVarStoreBuilder.storeDeltasMany.<locals>.<listcomp>.<listcomp>r   rT   rG   r   r   rR      s     z9OnlineVarStoreBuilder.storeDeltasMany.<locals>.<listcomp>c                 s   s   | ]}t |V  qd S r   )r   rT   r   r   r   	<genexpr>   s     z8OnlineVarStoreBuilder.storeDeltasMany.<locals>.<genexpr>r=   rG   rZ   )r   r#   rF   r2   r(   r>   r7   rU   r   	enumerater\   r@   )r)   rV   rH   r]   r^   irM   r   rG   r   rU      s$    
z%OnlineVarStoreBuilder.storeDeltasManyN)T)r<   )__name__
__module____qualname__r*   r.   r+   r;   rF   rH   rO   rW   rK   rU   r   r   r   r   r      s   

#r   rG   c                   sv    fdd|D }| j }t|}|d |kr>t|dd  }n||ksRt||ft|}| j| t| j| _d S )Nc                    s   g | ]} |qS r   r   rX   rG   r   r   rR      s     z#VarData_addItem.<locals>.<listcomp>r<   )VarRegionCountr2   r/   r[   r7   r?   r8   )r)   rM   rH   ZcountUsZ	countThemr   rG   r   VarData_addItem   s    rf   c                    s    fddt | jD S )Nc                    s2   i | ]*\}}|j d kr | j|j|j |jfqS rS   )Z	PeakCoordZaxisTagZ
StartCoordZEndCoord)rP   ra   reg	fvar_axesr   r   
<dictcomp>   s   
 z)VarRegion_get_support.<locals>.<dictcomp>)r`   ZVarRegionAxis)r)   ri   r   rh   r   VarRegion_get_support   s    
rk   c                 C   s
   t | jS r   )boolr5   r)   r   r   r   VarStore___bool__   s    rn   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 ks|jdkst|r&|jng | _|r8|jjng | _| | d S )Nr<   )	ri   ZFormatr[   r5   _varDataVarRegionListr3   _regionssetLocation)r)   Zvarstoreri   locationr   r   r   r*      s
    zVarStoreInstancer.__init__c                 C   s   t || _|   d S r   )dictrt   _clearCaches)r)   rt   r   r   r   rs      s    
zVarStoreInstancer.setLocationc                 C   s
   i | _ d S r   )_scalarsrm   r   r   r   rv      s    zVarStoreInstancer._clearCachesc                 C   s@   | j |}|d kr<| j| | j}t| j|}|| j |< |S r   )rw   r>   rr   get_supportri   r   rt   )r)   	regionIdxZscalarZsupportr   r   r   
_getScalar   s    
zVarStoreInstancer._getScalarc                 C   s.   d}t | |D ]\}}|sq||| 7 }q|S )N        )zip)rM   scalarsdeltarY   sr   r   r   interpolateFromDeltasAndScalars   s    z1VarStoreInstancer.interpolateFromDeltasAndScalarsc                    sV   |d? |d@  }}|t krdS  j} fdd|| jD }|| j| } ||S )NrZ   r=   r{   c                    s   g | ]}  |qS r   rz   rP   rirm   r   r   rR      s     z1VarStoreInstancer.__getitem__.<locals>.<listcomp>)NO_VARIATION_INDEXrp   VarRegionIndexr7   r   )r)   ZvaridxmajorminorvarDatar}   rM   r   rm   r   __getitem__   s    zVarStoreInstancer.__getitem__c                    s*    j } fdd|| jD } ||S )Nc                    s   g | ]}  |qS r   r   r   rm   r   r   rR      s     z;VarStoreInstancer.interpolateFromDeltas.<locals>.<listcomp>)rp   r   r   )r)   ZvarDataIndexrM   r   r}   r   rm   r   interpolateFromDeltas   s    z'VarStoreInstancer.interpolateFromDeltasN)rb   rc   rd   r*   rs   rv   rz   staticmethodr   r   r   r   r   r   r   ro      s   
	ro   TFr5   )r5   c                C   s  t t}|D ],}|tkrq|d? }|d@ }	|| |	 q~t| |}
g }tti}t|
D ]\}}||}|d krxqZt|}|| |j	}g }|dkr|rt
t|D ]4}	||	|kr||	 ndgt||	   |	||	< qnb|dkrt|t||  }nt|}|D ]4}	t|}|||	  |d> | ||d> |	 < q||_	t|j	|_|dkrZ|j|d qZt| || t| |d t| |   |S )NrZ   r=   r   r5   r0   ZCount)r   setr   addgetattrr`   r>   r2   r?   r7   ranger   r8   r9   setattrprune_regions)r)   ZvarIdxesr1   ZretainFirstMapZadvIdxesr5   usedr]   r   r   r   Z
newVarDataZ
varDataMapr:   Z
usedMinorsZnewMajorr   ZnewItemsZminorsZnewMinorr   r   r   VarStore_subset_varidxes   sP    



 
r   rq   )r5   rq   c          	         s   t  }t| |D ]}||j qt| |}|j}g }i  t|D ]}t| |< |||  qB||_t|j|_t| |D ]} fdd|jD |_q~dS )zRemove unused VarRegions.c                    s   g | ]} | qS r   r   )rP   ra   rA   r   r   rR   R  s     z*VarStore_prune_regions.<locals>.<listcomp>N)	r   r   updater   r3   r   r2   r?   r4   )	r)   r5   rq   ZusedRegionsr:   rB   rC   Z
newRegionsra   r   r   r   VarStore_prune_regions<  s    
r   c                 C   s   t | tjkr||  nt| tr8| D ]}t|| q&njt| dr|t| ds||  D ]$}t| |j	d}|dk	rTt|| qTn&t| tj
r| j D ]}t|| qd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   r   nameZValueRecord__dict__values)r)   functhatconvr   r   r   r   X  s    

r   c                 C   s$   | j dkr || jd> | j  dS )z6Add VarIdx in this Device table (if any) to the set s.   rZ   N)DeltaFormatr   	StartSizeEndSize)r)   r   r   r   r   _Device_recordVarIdxn  s    
r   c                 C   s   t t|d}t| | d S )N)r   )r   r   r   )r)   ZvaridxesZadderr   r   r   Object_collect_device_varidxest  s    r   c                 C   sT   t | |krdS |t |  | jdkrP|| jd> | j  }|d? | _|d@ | _dS )z9Map VarIdx in this Device table (if any) through mapping.Nr   rZ   r=   )idr   r   r   r   )r)   mappingdoner]   r   r   r   _Device_mapVarIdx}  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                   @   sL   e Zd Zdd Zdd 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*     s
    
z_Encoding.__init__c                 C   s   | j | d S r   )r   r   )r)   rowr   r   r   r?     s    z_Encoding.appendc                 C   s   | j | d S r   )r   r   )r)   lstr   r   r   extend  s    z_Encoding.extendc                 C   s   | j | jfS r   )r   r   rm   r   r   r   width_sort_key  s    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   s2   d}d}| r.| d@ r||O }| dL } |dK }q|S )Nr   r<         r   )r   colsra   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   r2   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)rb   rc   rd   r*   r?   r   r   r   r   r   r   r   r   r   r   r     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 ]X}|r ||7 }d|  kr4dksBn ||d 7 }d|  krVdks`n d	} qj|d
K }q|rd}d}| D ]>}|r||d 7 }d|  krdksn ||d 7 }|d
K }qz|S )z+Returns encoding characteristics for a row.Fr   r<   i   r   i i  Tr         r   )r   Z	longWordsr   ra   vr   r   r   r     s,    

z"_EncodingDict._row_characteristicsN)rb   rc   rd   r   r   r   r   r   r   r   r   r     s   r   r<   c              	   C   s  t | jj}dg| }i }t }t| jD ]\}}|j}	t|jD ]\}
}t|}|dkrt	|	|D ]\}}||  |7  < qdn0t	|	|D ]$\}}||  t
|| | 7  < qt|}|rt|sd||d> |
 < qB|| |||d> |
 < qBq*t| tjd}~g }t|D ]R\}}t|d t |D ]4}|| }||}|dkr.t|| ||f q.q|rht|\}}}|| dksh|| dkrqh|| ||  }}d\||< ||< |j|jB }t|}||j ||j t|D ]f\}}|dkrq|j|kr,||j d||< q||}|dkrt|| |t |f q|| qhdd |D }i }|jtjd g | _|D ]}t|j}|rt | j}t }| j| t||_t |j|_|dd	 |d	d  |_}t|jD ]\}
}|d> |
 ||< q qqtti}| D ]$\}}|dk	rN|| nt||< q4t | jj| j_t | j| _| jD ]}t |j|_ |!  q|| "  |S )
z@Optimize storage. Returns mapping from old VarIdxes to new ones.r   r<   NrZ   r   )NNc                 S   s   g | ]}|d k	r|qS r   r   )rP   encodingr   r   r   rR     s      z%VarStore_optimize.<locals>.<listcomp>r=   )#r2   rq   r3   r   r`   r5   r   r7   r/   r|   rH   r   anyr   r   r   r   r   r   r   r   r   r   r   r   r?   sortr   re   r   r4   r6   r8   r1   r   )r)   Zuse_NO_VARIATION_INDEXquantizationnZzeroesZfront_mapping	encodingsr   r:   rD   r   itemr   ry   r   todoheapra   r   jr   Zcombining_gain_r   Zcombined_encodingkencZback_mappingr   
varidx_mapr   r   r   VarStore_optimize  s    L










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k	r>|j| d|
kr4|
d j| |
|	 dS )z&Optimize a font's GDEF variation storer   )ArgumentParser)configLogger)TTFont)OTTableWriterzvarLib.varStore)progdescriptionz--quantizationr<   )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compiler2   Z
getAllDataprintr1   remap_device_varidxessave)argsr   r   r   r   parseroptionsr   r   r   fontZgdefstorewritersizer   r   r   r   r     s<    




r   __main__)Tr<   )N)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   rH   rf   r5   r\   rk   Z	VarRegionrx   rn   __bool__ro   r   r   Zsubset_varidxesr   r   r   r   r   r   Zcollect_device_varidxesr   r   r   r   r   ru   r   r   r1   r   rb   sysr2   argvexitdoctesttestmodfailedr   r   r   r   <module>   sb    9A3(
 B
,
