U
    i2e3s                     @   s   d dl mZmZmZmZm	Z	 d dl
mZ d dlZd dlmZmZ d dlZd dlZd dlZd dlZdZdZdZdZd	Zd
ZdZdZdZdZdZee Z!G dd de"Z#dd Z$ed fddZ%dddZ&dd Z'dd Z(dd Z)dS )    )fixedToFloatfloatToFixedfloatToFixedToStrstrToFixedToFloatotRound)safeEvalN)Counterdefaultdicti   i @  i       @   ?      i  c                   @   s  e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	i dfddZ
dd Zdd Zedd Zedd Zedd Zdd Z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d*d+ Zd,d- Zd.d/ Zd0d1 Zd;d4d5Zd6d7 Zd8d9 ZdS )<TupleVariationc                 C   s   |  | _t|| _d S N)copyaxeslistcoordinates)selfr   r    r   I/tmp/pip-unpacked-wheel-txsm8jh_/fontTools/ttLib/tables/TupleVariation.py__init__&   s    
zTupleVariation.__init__c                 C   s,   d tdd | j D }d|| jf S )N,c                 S   s   g | ]\}}d ||f qS )z%s=%sr   ).0namevaluer   r   r   
<listcomp>,   s     z+TupleVariation.__repr__.<locals>.<listcomp>z<TupleVariation %s %s>)joinsortedr   itemsr   )r   r   r   r   r   __repr__*   s    zTupleVariation.__repr__c                 C   s   | j |j ko| j|jkS r   )r   r   )r   otherr   r   r   __eq__0   s    zTupleVariation.__eq__c                 C   s4   d | j krt S tdd t| j D }|r0|S d S )Nc                 S   s   g | ]\}}|d k	r|qS r   r   )r   ipr   r   r   r   7   s      z0TupleVariation.getUsedPoints.<locals>.<listcomp>)r   	frozenset	enumerate)r   usedr   r   r   getUsedPoints3   s    
zTupleVariation.getUsedPointsc                 C   s   t dd | jD S )zReturns True if this TupleVariation has any visible impact.

        If the result is False, the TupleVariation can be omitted from the font
        without making any visible difference.
        c                 s   s   | ]}|d k	V  qd S r   r   r   cr   r   r   	<genexpr>A   s     z+TupleVariation.hasImpact.<locals>.<genexpr>)anyr   r   r   r   r   	hasImpact;   s    zTupleVariation.hasImpactc                 C   s  | d |  |D ]}| j|}|d k	r|\}}}t|d}t|d}||krt||krt|jd|t|dd n:d|fdt|dfdt|dfd	t|dfg}	|d|	 |  qd
}
t| j	D ]\}}t
|tkrt|dkr|jd||d |d d |  d}
qt
|tkr>|jd||d |  d}
q|d k	rtd |d|  |  d}
q|
s|d |  |d |  d S )Ntuple        coord   )axisr   r3   minr   maxF   deltar      )ptxyT)cvtr   zbad delta formatzbad delta #%dz	no deltas)Zbegintagnewliner   getr4   r5   Z	simpletagfl2strr&   r   typer/   lenintlogerrorcommentZendtag)r   writeraxisTagsr3   r   minValuemaxValuedefaultMinValuedefaultMaxValueattrsZwrote_any_deltasr#   r7   r   r   r   toXMLC   sJ    







zTupleVariation.toXMLc                 C   s   |dkrh|d }t |d d}t|d}t|d}t |d|d}t |d|d}	|||	f| j|< n|dkrd	|krt|d	 }
t|d
 }t|d }||f| j|
< nHd|krt|d }t|d }|| j|< ntdd	t
|   d S )Nr1   r3   r   r2   r0   r4   r5   r7   r9   r:   r;   r<   zbad delta format: %sz, )str2flr4   r5   r>   r   r   r   rC   warningr   r   keys)r   r   rL   _contentr3   r   rJ   rK   rH   rI   pointr:   r;   r<   r   r   r   fromXMLl   s&    

zTupleVariation.fromXMLNc           
      C   s   t | j t |ks*td| j |fg }g }|d krX|  }|d krNdS | |}| |}||}|d krt}|	| | 
|}	|	d k	r|tO }|	|	 |r|tO }|	| |	|   d|}|dtdt|| d||fS )NzUnknown axis tag found.)    rT   rT   r   >HH)setr   rP   AssertionErrorr(   compilePointscompileCoordr>   EMBEDDED_PEAK_TUPLEappendcompileIntermediateCoordINTERMEDIATE_REGIONPRIVATE_POINT_NUMBERScompileDeltasr   insertstructpackrA   )
r   rG   ZsharedCoordIndices	pointData	tupleDataauxDataZ
usedPointsr1   flagsZintermediateCoordr   r   r   compile   s8    







zTupleVariation.compilec              	   C   sX   t  }| j}|D ]>}||}|d kr2|d q|tdt|d d qt|S )Ns     >hr8   r2   )	bytearrayr   r>   extendra   rb   fl2fibytes)r   rG   resultr   r3   Ztripler   r   r   rY      s    
zTupleVariation.compileCoordc              	   C   s   d}|D ]D}| j |d\}}}t|d}t|d}||ksD||krd} qNq|sVd S t }	t }
|D ]H}| j |d\}}}|	tdt|d |
tdt|d qf|	|
 S )NFr0   r0   r0   r0   Trh   r2   )	r   r>   r4   r5   ri   rj   ra   rb   rk   )r   rG   neededr3   rH   r   rI   rJ   rK   Z	minCoordsZ	maxCoordsr   r   r   r\      s"    

z'TupleVariation.compileIntermediateCoordc              	   C   sH   i }|}| D ]2}t td|||d  d d||< |d7 }q||fS )Nrh   r6   r   r2   )fi2flra   unpack)rG   dataoffsetr1   posr3   r   r   r   decompileCoord_   s    &
zTupleVariation.decompileCoord_c                 C   sR  | sdS t | } |   t| }t }|dk r:|| n ||d? dB  ||d@  d}d}d}||k rNd}t|}|d d }||k r(||kr(| | }	|	| }
|d krd|
  kodkn  }|r|
dks|
dk rq(|r||
 n||
d?  ||
d@  |	}|d7 }|d7 }q|r<|d ||< qf|d tB ||< qf|S )N    r
         r   r   r8   )r   sortrA   ri   r[   POINTS_ARE_WORDS)points	numPointsrm   ZMAX_RUN_LENGTHrt   Z	lastValue	runLengthZ	headerPosZuseByteEncodingZcurValuer7   r   r   r   rX      sH    


zTupleVariation.compilePointsc                    sp  |dkst |}|| }|d7 }|t@ dkrH|t@ d> || B }|d7 }|dkr\t |fS g }t||k r|| }|d7 }|t@ d }d}	|t@ dkrtd}
|d }ntd}
|}|
||||   tjdkr|
	  t|
|kst ||7 }|
|
 q`g }d}|D ]}||7 }|| q|}~ fd	d
|D }|rhtddt||f  ||fS )zJ(numPoints, data, offset, tableTag) --> ([point1, point2, ...], newOffset)cvargvarr8   r   rw   Hr6   Bbigc                    s$   h | ]}|d k s| krt |qS )r   )str)r   r$   r|   r   r   	<setcomp>;  s       z2TupleVariation.decompilePoints_.<locals>.<setcomp>z#point %s out of range in '%s' tabler   )rW   rz   POINT_RUN_COUNT_MASKrangerA   array	frombytessys	byteorderbyteswaprj   r[   rC   rO   r   r   )r|   rr   rs   tableTagrt   ZnumPointsInDatarm   	runHeaderZnumPointsInRunrR   r{   Z
pointsSizeabsolutecurrentr7   Z	badPointsr   r   r   decompilePoints_  sR    



zTupleVariation.decompilePoints_c                 C   s   g }g }|   dkrH| jD ]*}|d kr(q||d  ||d  qn | jD ]}|d kr\qN|| qNt }| || | || |S )Nr6   r   r8   )getCoordWidthr   r[   ri   compileDeltaValues_)r   ZdeltaXZdeltaYr*   bytearrr   r   r   r_   C  s     

zTupleVariation.compileDeltasc                 C   s~   |dkrt  }d}t| }||k rz| | }|dkrBt| ||}qd|  krVdkrjn nt| ||}qt| ||}q|S )a  [value1, value2, value3, ...] --> bytearray

        Emits a sequence of runs. Each run starts with a
        byte-sized header whose 6 least significant bits
        (header & 0x3F) indicate how many values are encoded
        in this run. The stored length is the actual length
        minus one; run lengths are thus in the range [1..64].
        If the header byte has its most significant bit (0x80)
        set, all values in this run are zero, and no data
        follows. Otherwise, the header byte is followed by
        ((header & 0x3F) + 1) signed values.  If (header &
        0x40) is clear, the delta values are stored as signed
        bytes; if (header & 0x40) is set, the delta values are
        signed 16-bit integers.
        Nr   r   )ri   rA   r   encodeDeltaRunAsZeroes_encodeDeltaRunAsBytes_encodeDeltaRunAsWords_)deltasr   rt   	numDeltasr   r   r   r   r   V  s    z"TupleVariation.compileDeltaValues_c                 C   sl   |}t | }||k r*| | dkr*|d7 }q|| }|dkrR|tdB  |d8 }q2|rh|t|d B  |S )Nr   r8   r   r   )rA   r[   DELTAS_ARE_ZERO)r   rs   r   rt   r   r}   r   r   r   r   u  s    

z&TupleVariation.encodeDeltaRunAsZeroes_c              	   C   s   |}t | }||k rd| | }d|  kr0dks4qd qd|dkrZ|d |k rZ| |d  dkrZqd|d7 }q|| }|dkr|d |td| ||d   |d7 }|d8 }ql|r||d  |td| ||  |S )Nr   r   r   r8   r   r   b)rA   r[   rj   r   )r   rs   r   rt   r   r   r}   r   r   r   r     s&    	$


z%TupleVariation.encodeDeltaRunAsBytes_c                 C   s(  |}t | }||k rv| | }|dkr&qvd|  kr:dkrln n.|d |k rld| |d    krfdkrlqv nqv|d7 }q|| }|dkr|tdB  td| ||d  }tjdkr|  || |d7 }|d8 }q~|r$|t|d B  td| || }tjdkr|  || |S )	Nr   r   r   r8   r   r   hr   )rA   r[   DELTAS_ARE_WORDSr   r   r   r   rj   )r   rs   r   rt   r   r   r}   ar   r   r   r     sH    	 

 






z%TupleVariation.encodeDeltaRunAsWords_c           	      C   s   g }|}t || k r|| }|d7 }|t@ d }|t@ dkrN|dg|  q|t@ dkrntd}|d }ntd}|}|||||   tjdkr|	  t ||kst
||7 }|| qt || kst
||fS )z>(numDeltas, data, offset) --> ([delta, delta, ...], newOffset)r8   r   r   r6   r   r   )rA   DELTA_RUN_COUNT_MASKr   rj   r   r   r   r   r   r   rW   )	r   rr   rs   rm   rt   r   ZnumDeltasInRunr   Z
deltasSizer   r   r   decompileDeltas_  s*    



zTupleVariation.decompileDeltas_c                 C   s8   d}| t @ dkr||d 7 }| t@ dkr4||d 7 }|S )N   r   r6   )rZ   r]   )rf   Z	axisCountsizer   r   r   getTupleSize_  s    zTupleVariation.getTupleSize_c                 C   sb   t dd | jD d}|dkr"dS t|ttfkr6dS t|tkrRt|dkrRdS td| dS )zmReturn 2 if coordinates are (x, y) as in gvar, 1 if single values
        as in cvar, or 0 if empty.
        c                 s   s   | ]}|d k	r|V  qd S r   r   r)   r   r   r   r+     s      z/TupleVariation.getCoordWidth.<locals>.<genexpr>Nr   r8   r6   zSinvalid type of delta; expected (int or float) number, or Tuple[number, number]: %r)nextr   r@   rB   floatr/   rA   	TypeError)r   Z
firstDeltar   r   r   r     s    zTupleVariation.getCoordWidthc                    s0   dkrd S |     fdd| jD | _d S )Ng      ?c                    s@   g | ]8}|d krd n& dkr$| n|d  |d  fqS Nr8   r   r   r   d
coordWidthscalarr   r   r     s   
z.TupleVariation.scaleDeltas.<locals>.<listcomp>r   r   r   r   r   r   r   scaleDeltas  s    zTupleVariation.scaleDeltasc                    s"   |     fdd| jD | _d S )Nc                    s@   g | ]8}|d krd n& dkr$t |nt |d t |d fqS r   )r   r   r   r   r   r     s   
z.TupleVariation.roundDeltas.<locals>.<listcomp>r   r-   r   r   r   roundDeltas  s    
zTupleVariation.roundDeltasc                 C   sj   ddl m} |  dkr tdd | jkrft| jt|krVtdt| jt|f || j||| _d S )Nr   )	iup_deltar8   z3Only 'gvar' TupleVariation can have inferred deltasz(Expected len(origCoords) == %d; found %d)fontTools.varLib.iupr   r   r   r   rA   
ValueError)r   
origCoordsendPtsr   r   r   r   calcInferredDeltas  s    
z!TupleVariation.calcInferredDeltas      ?Fc                 C   s   ddl m} d | jkrd S || j|||d}d |kr|rbtdd |D rbdgd gt|d   }t| j|}t| j }| 	|\}	}
t|	t|
 }|	|\}	}
t|	t|
 }||k r|j| _d S )Nr   )iup_delta_optimize)	tolerancec                 s   s   | ]}|d kV  qd S r   r   r   r   r   r   r+   2  s     z*TupleVariation.optimize.<locals>.<genexpr>)r   r   r8   )
r   r   r   allrA   r   r   r   rP   rg   )r   r   r   r   ZisCompositer   ZdeltaOptZvarOptrG   rd   re   ZunoptimizedLengthZoptimizedLengthr   r   r   optimize(  s(    
   zTupleVariation.optimizec                 C   s   |  | | S r   )r   r   r   r   r   __imul__C  s    
zTupleVariation.__imul__c              	   C   s  t |tstS | j}t|}|j}t||kr6td|  dkrtt||D ]V\}}|| }z(|d |d  |d |d  f||< W qP t	k
r   tdY qPX qPnVtt||D ]F\}}|| }|d k	r|d k	r|| ||< q|d kr|d k	r|||< q| S )Nz7cannot sum TupleVariation deltas with different lengthsr6   r   r8   z+cannot sum gvar deltas with inferred points)

isinstancer   NotImplementedr   rA   r   r   zipr   r   )r   r!   Zdeltas1lengthZdeltas2r#   Zd2d1r   r   r   __iadd__G  s*    
	(
zTupleVariation.__iadd__)N)r   F)__name__
__module____qualname__r   r    r"   r(   r.   rM   rS   rg   rY   r\   staticmethodru   rX   r   r_   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   %   sH   )&

@
2


-


r   c                 C   s2   g }t |D ] }t| ||\}}|| q|S r   )r   r   ru   r[   )rG   ZsharedTupleCountrr   rs   rm   _tr   r   r   decompileSharedTuplesi  s
    r   r8   c                 C   sN   t  }|D ]}|| }||  d7  < q
t||dd d}dd |D S )Nr8   c                 S   s   | d  | d fS r   r   )itemr   r   r   <lambda>|  rT   z%compileSharedTuples.<locals>.<lambda>keyc                 S   s    g | ]}|d  d kr|d qS )r8   r   r   r)   r   r   r   r   ~  s      z'compileSharedTuples.<locals>.<listcomp>)r   rY   r   most_common)rG   
variationsZMAX_NUM_SHARED_COORDSZ
coordCountvarr1   ZsharedCoordsr   r   r   compileSharedTuplesq  s    
r   Tc                    sX  ~g }g }d t t}| D ]:}| }	|	d kr0q||	  d7  < || ||	 q|} ~| sddS t| d jtfdd| D stddd |D  t| }
g }g }|r fd	d
}t|	 |dd |   |
t
O }
 fdd|D }t| |D ]2\}}|j|||d\}}|| || qd|}d|}|
||fS )Nr8   )r   rT   rT   r   c                 3   s   | ]}t |j kV  qd S r   )rA   r   )r   v)nr   r   r+     s    z-compileTupleVariationStore.<locals>.<genexpr>z#Variation sets have different sizesc                 S   s   i | ]}|t |qS r   )r   rX   )r   pointSetr   r   r   
<dictcomp>  s     z.compileTupleVariationStore.<locals>.<dictcomp>c                    s$   | d }| d }t  | |d  S )Nr   r8   )rA   )Zpnr   count)compiledPointsr   r   r     s    z'compileTupleVariationStore.<locals>.keyr   c                    s    g | ]}|kr | nd qS )rT   r   )r   r{   )r   sharedPointsr   r   r     s   z.compileTupleVariationStore.<locals>.<listcomp>)rc   rT   )r	   rB   r(   r[   rA   r   r   rW   r5   r   TUPLES_SHARE_POINT_NUMBERSr   rg   r   )r   
pointCountrG   ZsharedTupleIndicesZuseSharedPointsZnewVariationsZ
pointDatasZpointSetCountr   r{   tupleVariationCountZtuplesrr   r   r$   Z	thisTupleZthisDatar   )r   r   r   r   compileTupleVariationStore  sV    




r   c                 C   s   t |}g }	|t@ dkr.t|||| \}
}ng }
t|t@ D ]v}td|||d  \}}t||}||||  }||||  }|		t
|||
| ||| ||7 }||7 }q>|	S )Nr   rU   r   )rA   r   r   r   r   TUPLE_COUNT_MASKra   rq   r   r[   decompileTupleVariation_)r   rG   r   r   sharedTuplesrr   rt   ZdataPosZnumAxesrm   r   r   ZdataSizerf   Z	tupleSizerd   ZpointDeltaDatar   r   r   decompileTupleVariationStore  s:    
   

r   c                 C   s  |dkst |td|dd d }d}|t@ dkrF||t@  }	nt|||\}	}|t@ dkrt|||\}
}t|||\}}nt|	\}
}i }|D ]*}|
| |	| || f}|dkr|||< qd}|t	@ dkrt
| |||\}}n|}d g|  }|dkrZtt|||\}}t||D ].\}}d|  krH| k r(n n|||< q(nx|dkrtt|||\}}tt|||\}}t|||D ]4\}}}d|  kr| k rn n||f||< qt||S )	Nr~   z>Hr6   r   r   rn   r   r   )rW   ra   rq   rZ   TUPLE_INDEX_MASKr   ru   r]   inferRegion_r^   r   r   rA   r   )r   r   r   r   rG   rr   rd   rf   rt   peakstartendr   r3   Zregionr{   r   Z
deltas_cvtr$   r7   Zdeltas_xZdeltas_yr:   r;   r   r   r   r     sJ    
   



r   c                 C   s@   i i  }}|   D ]$\}}t|d||< t|d||< q||fS )a  Infer start and end for a (non-intermediate) region

    This helper function computes the applicability region for
    variation tuples whose INTERMEDIATE_REGION flag is not set in the
    TupleVariationHeader structure.  Variation tuples apply only to
    certain regions of the variation space; outside that region, the
    tuple has no effect.  To make the binary encoding more compact,
    TupleVariationHeaders can omit the intermediateStartTuple and
    intermediateEndTuple fields.
    r0   )r   r4   r5   )r   r   r   r3   r   r   r   r   r     s
    
r   )T)*ZfontTools.misc.fixedToolsr   rp   r   rk   r   r?   r   rN   r   ZfontTools.misc.textToolsr   r   collectionsr   r	   iologgingra   r   rZ   r]   r^   r   r   r   rz   r   r   r   r   	getLoggerr   rC   objectr   r   r   r   r   r   r   r   r   r   r   <module>   s@   
    H	
 
C'.