a
    ׶aA                     @   s  d dl mZ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 ZG d	d
 d
eZed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 Z(d d! Z)e)ej%_*e)ej'_*G d"d# d#eZ+G d$d% d%e,Z-d&d' Z.e.ej_/d-d)d*Z0e1d+krd d(l2Z2e3e2j4d,kre25e0  d d(l6Z6e25e67 j8 d(S ).    )noRoundotRound)otTables)supportScalar)buildVarRegionListbuildVarStorebuildVarRegionbuildVarData)partial)defaultdictc                 C   s   t t|  dd dS )Nc                 S   s   | d S Nr    )kvr   r   i/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-packages/fontTools/varLib/varStore.py<lambda>       z!_getLocationKey.<locals>.<lambda>key)tuplesorteditems)locr   r   r   _getLocationKey
   s    r   c                   @   sL   e Zd Zdd Zdd Zdd Zddd	Zd
d Z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%   r-   datar   r   r   finish(   s    zOnlineVarStoreBuilder.finishc           
      C   s(  | j }| j}| j}g }|D ]R}t|}||}|d u rbt|| j}t|j }||< |j	| |	| qt
|}| j|}	|	d ur|	| _| jj|	 | _| j| | _t| jjdkrd }	|	d u r$t|g dd| _t| jj| _| jj	| j | j| j|< || jvri | j|< | j| | _d S )N  Fr,   )r   r   r!   r   getr   r   r.   r/   appendr   r"   _outerr   r1   r   r#   r$   r3   r	   )
r%   	regionMap
regionListregionsregionIndicesZregionr   idxZ	varRegionZ
varDataIdxr   r   r   _add_VarData0   s8    


z"OnlineVarStoreBuilder._add_VarDatac                 C   s,   | j j|td}|d}|| j|tdfS )Nroundr   )r    Z	getDeltasrC   popstoreDeltasr   )r%   Zmaster_valuesdeltasbaser   r   r   storeMastersT   s    
z"OnlineVarStoreBuilder.storeMastersrB   c                   s    fdd|D }t |t | jd kr:t|dd  }nt |t | jksPJ t|}| j|}|d urp|S | js~|   t | jj}|dkr|   | |S | jj	|t
d | jd> | }|| j|< |S )Nc                    s   g | ]} |qS r   r   .0drB   r   r   
<listcomp>Z   r   z5OnlineVarStoreBuilder.storeDeltas.<locals>.<listcomp>   r8   rB      )r.   r!   r   r$   r9   r   rA   r3   rE   addItemr   r;   )r%   rF   rC   varIdxinnerr   rB   r   rE   Y   s$    

z!OnlineVarStoreBuilder.storeDeltasN)T)__name__
__module____qualname__r&   r*   r'   r7   rA   rH   rC   rE   r   r   r   r   r      s   
$r   rB   c                   sz    fdd|D }| j }t|}|d |kr>t|dd  }n||ksRJ ||ft|}| jt| t| j| _d S )Nc                    s   g | ]} |qS r   r   rI   rB   r   r   rL   s   r   z#VarData_addItem.<locals>.<listcomp>rM   )VarRegionCountr.   r   r3   r:   r+   r4   )r%   rF   rC   ZcountUsZ	countThemr   rB   r   VarData_addItemr   s    rV   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)rJ   ireg	fvar_axesr   r   
<dictcomp>   s   
z)VarRegion_get_support.<locals>.<dictcomp>)	enumerateZVarRegionAxis)r%   rZ   r   rY   r   VarRegion_get_support   s    
r]   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 | _|r8|jjng | _| | d S NrM   )rZ   ZFormatr1   _varDataVarRegionListr/   _regionssetLocation)r%   ZvarstorerZ   locationr   r   r   r&      s
    zVarStoreInstancer.__init__c                 C   s   t || _|   d S r   )dictrd   _clearCaches)r%   rd   r   r   r   rc      s    
zVarStoreInstancer.setLocationc                 C   s
   i | _ d S r   )_scalarsr%   r   r   r   rf      s    zVarStoreInstancer._clearCachesc                 C   s@   | j |}|d u r<| j| | j}t| j|}|| j |< |S r   )rg   r9   rb   get_supportrZ   r   rd   )r%   	regionIdxZscalarZsupportr   r   r   
_getScalar   s    
zVarStoreInstancer._getScalarc                 C   s.   d}t | |D ]\}}|sq||| 7 }q|S )Ng        )zip)rF   scalarsdeltarK   sr   r   r   interpolateFromDeltasAndScalars   s
    z1VarStoreInstancer.interpolateFromDeltasAndScalarsc                    sJ   |d? |d@  }} j } fdd|| jD }|| j| } ||S )NrN   r8   c                    s   g | ]}  |qS r   rk   rJ   rirh   r   r   rL      r   z1VarStoreInstancer.__getitem__.<locals>.<listcomp>)r`   VarRegionIndexr3   rp   )r%   ZvaridxmajorminorvarDatarm   rF   r   rh   r   __getitem__   s
    zVarStoreInstancer.__getitem__c                    s*    j } fdd|| jD } ||S )Nc                    s   g | ]}  |qS r   rq   rr   rh   r   r   rL      r   z;VarStoreInstancer.interpolateFromDeltas.<locals>.<listcomp>)r`   rt   rp   )r%   ZvarDataIndexrF   rw   rm   r   rh   r   interpolateFromDeltas   s
    
z'VarStoreInstancer.interpolateFromDeltasN)rR   rS   rT   r&   rc   rf   rk   staticmethodrp   rx   ry   r   r   r   r   r^      s   
r^   TFc                 C   s  i }|D ]>}|d? }|d@ }| |}	|	d u r<t  }	||< |	| q~| j}
g }i }t|
D ]\}}| |}|d u r~q`t|}|| |j}g }|dkr|rtt|D ]4}|||v r|| ndgt||   |||< qnb|dkr
t	|t	||  }nt	|}|D ]4}t|}|||  |d> | ||d> | < q||_t|j|_
|j|d q`|| _t| j| _|   |S )NrN   r8   r   r,   )r9   setaddr1   r\   r.   r:   r3   ranger   r4   r5   r2   prune_regions)r%   ZvarIdxesr-   ZretainFirstMapZadvIdxesusedrP   ru   rv   rK   rw   Z
newVarDataZ
varDataMapr6   Z
usedMinorsZnewMajorr   ZnewItemsZminorsZnewMinorr   r   r   VarStore_subset_varidxes   sL    


(
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 |_qrdS )zRemove unused VarRegions.c                    s   g | ]} | qS r   r   )rJ   rW   r<   r   r   rL     r   z*VarStore_prune_regions.<locals>.<listcomp>N)
r{   r1   updatert   ra   r/   r   r.   r:   r0   )r%   ZusedRegionsr6   r=   r>   Z
newRegionsrW   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urTt|| qTn&t| tj
r| j D ]}t|| qdS )znRecurse 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     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.   rN   N)DeltaFormatr|   	StartSizeEndSize)r%   ro   r   r   r   _Device_recordVarIdx'  s    
r   c                 C   s   t t|d}t| | d S )N)ro   )r
   r   r   )r%   ZvaridxesZadderr   r   r   Object_collect_device_varidxes,  s    r   c                 C   sT   t | |v 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   rN   r8   )idr|   r   r   r   )r%   mappingdonerP   r   r   r   _Device_mapVarIdx3  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                   @   s   e Zd Zdd Zdd Zdd Zdd ZeeZed	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   s*   || _ | || _| || _t | _d S r   )chars	_popcountwidth_characteristic_overheadoverheadr{   r   r%   r   r   r   r   r&   G  s    z_Encoding.__init__c                 C   s   | j | d S r   )r   r|   )r%   rowr   r   r   r:   M  s    z_Encoding.appendc                 C   s   | j | d S r   )r   r   )r%   lstr   r   r   extendP  s    z_Encoding.extendc                 C   s$   t | j}td| jd | | j S )zxMaximum number of bytes that can be added to characteristic
		while still being beneficial to merge it into another one.r   rM   r.   r   maxr   r   r%   countr   r   r   get_roomS  s    
z_Encoding.get_roomc                 C   s$   t | j}td| j|| jd   S )zKMaximum possible byte gain from merging this into another
		characteristic.r   rM   r   r   r   r   r   gainZ  s    
z_Encoding.gainc                 C   s   | j | jfS r   )r   r   rh   r   r   r   sort_keya  s    z_Encoding.sort_keyc                 C   s
   t | jS r   )r.   r   rh   r   r   r   __len__d  s    z_Encoding.__len__c                 C   s   || j  @  S r   )r   r   r   r   r   
can_encodeg  s    z_Encoding.can_encodec                 C   s   |  | j|j @ S r   )r   r   )r%   otherr   r   r   __sub__j  s    z_Encoding.__sub__c                 C   s   t | dS )N1)binr   )nr   r   r   r   m  s    z_Encoding._popcountc                 C   s&   d}| r"| d@ r|d7 }| dL } q|S )zIReturns overhead in bytes of encoding this characteristic
		as a VarData.            r   )r   cr   r   r   r   s  s    
z"_Encoding._characteristic_overheadc                 C   sT   d | _ t| jd | j| j d D ],}|| D ]}|| jr. qHq.d }|| _ q"d S r_   )best_new_encodingr}   r   roomr   r   )r%   done_by_widthZ	new_widthZnew_encodingr   r   r    _find_yourself_best_new_encoding~  s     z*_Encoding._find_yourself_best_new_encodingN)rR   rS   rT   r&   r:   r   r   propertyr   r   r   r   r   r   rz   r   r   r   r   r   r   r   r   E  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   rM   i   r   i i  Tr         r   )r   Z	longWordsr   rW   vr   r   r   r     s,    

z"_EncodingDict._row_characteristicsN)rR   rS   rT   r   r   rz   r   r   r   r   r   r     s   r   c                 C   sv  t | jj}dg| }i }t }t| jD ]p\}}|j}t|jD ]V\}}	t|}
t	||	D ]\}}|
|  |7  < q\t
|
}
||
 |
||d> | < qBq*t| tjdd}tt}g }|D ]&}|js||j | q|| q|jtjd |D ]}|| q|rr| }d}d}t|D ]\}}|j|jB }t|}t|}|j
 |j | ||j t |  ||j t |  }|jdu rdn|j
 |jj|j t |  }|jdu rdn|j
 |jj|j t |  }|| }||kr(|}|| }q(|du r ||j | nN|| }|j|jB }t|}||j ||j || ||= || q
i }t| g }|jtj d g | _t|D ]f\}}t! }| j| t"||_t |j|_#t|j|_t|jD ]\}}	|d> | ||	< qqi }| D ]\}}|| ||< q| $  t | jj| j_%t | j| _&| jD ]}t |j|_'|(  qV|S )z@Optimize storage. Returns mapping from old VarIdxes to new ones.r   rN   T)r   reverser   N))r.   ra   r/   r   r\   r1   rt   r3   r+   rl   r   r   r   r   r   r   r   r   r   r:   sortr   r   rD   r   r   r   r   r   r   r   sumr   r   r}   rU   r~   r0   r2   r4   r-   )r%   r   ZzeroesZfront_mapping	encodingsru   r6   r?   rv   itemr   rj   r   r   todoencodingZbest_idxZ	best_gainrW   Zother_encodingZcombined_charsZcombined_widthZcombined_overheadZcombined_gainZ	this_gainZ
other_gainZseparate_gainZcombined_encodingZback_mapping
varidx_mapkr   r   r   VarStore_optimize  s    








r   Nc                 C   s&  ddl m} ddlm} ddlm} ddlm} |dtj	d}|
d |j
d	d
d || }|dd |j}|j}||}	|	d }
|
jj}| }|||	 t| }td|  | }|
j| d|	v r|	d j| | }|||	 t| }td|  |dur"|	| dS )z&Optimize a font's GDEF variation storer   )ArgumentParser)configLogger)TTFont)OTTableWriterzvarLib.varStore)progdescriptionfontfileoutfile?)nargsINFO)levelGDEFzBefore: %7d bytesGPOSzAfter:  %7d bytesN)argparser   Z	fontToolsr   ZfontTools.ttLibr   ZfontTools.ttLib.tables.otBaser   main__doc__add_argument
parse_argsr   r   tableVarStorecompiler.   Z
getAllDataprintr-   remap_device_varidxessave)argsr   r   r   r   parseroptionsr   r   fontZgdefstorewritersizer   r   r   r   r   /  s8    



r   __main__rM   )N)9ZfontTools.misc.roundToolsr   r   ZfontTools.ttLib.tablesr   r   ZfontTools.varLib.modelsr   ZfontTools.varLib.builderr   r   r   r	   	functoolsr
   collectionsr   r   objectr   rC   rV   r1   rO   r]   Z	VarRegionri   r^   r{   r   r   Zsubset_varidxesr   r~   r   r   r   r   Zcollect_device_varidxesr   r   r   r   r   re   r   r   r-   r   rR   sysr.   argvexitdoctesttestmodfailedr   r   r   r   <module>   sH   d47
D)z
*
