U
    #vh}                     @   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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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                   @   s4  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ddZ
dd Zdd Zedd Zedd Zedd Zd?ddZed@ddd d!Zed"d# ZedAd$d%ZedBd&d'ZedCd(d)ZedDd+d,Zed-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 ZdEd9d:Zd;d< Zd=d> ZdS )FTupleVariationc                 C   s   |  | _t|| _d S N)copyaxeslistcoordinates)selfr   r    r   I/tmp/pip-unpacked-wheel-1ufboor8/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__2   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   9   s      z0TupleVariation.getUsedPoints.<locals>.<listcomp>)r   	frozenset	enumerate)r   usedr   r   r   getUsedPoints5   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>C   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   r4   minr   maxF   deltar      )ptxyT)cvtr   zbad delta formatzbad delta #%dz	no deltas)Zbegintagnewliner   getr5   r6   Z	simpletagfl2strr'   r   typer0   lenintlogerrorcommentZendtag)r   writeraxisTagsr4   r   minValuemaxValuedefaultMinValuedefaultMaxValueattrsZwrote_any_deltasr$   r8   r   r   r   toXMLE   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 )Nr2   r4   r   r3   r1   r5   r6   r8   r:   r;   r<   r=   zbad delta format: %sz, )str2flr5   r6   r?   r   r   r   rD   warningr   r   keys)r   r   rM   _contentr4   r   rK   rL   rI   rJ   pointr;   r<   r=   r   r   r   fromXMLn   s&    

zTupleVariation.fromXMLNToptimizeSizec                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 }	|	| |	| j|d d|}|dtdt||	 d||fS )NzUnknown axis tag found.)    rW   rU   rW   r   >HH)setr   rQ   AssertionErrorr)   compilePointscompileCoordr?   EMBEDDED_PEAK_TUPLEappendcompileIntermediateCoordINTERMEDIATE_REGIONPRIVATE_POINT_NUMBERScompileDeltasr   insertstructpackrB   )r   rH   ZsharedCoordIndices	pointDatarV   	tupleDataauxDataZ
usedPointsr2   flagsZintermediateCoordr   r   r   compile   s8    







zTupleVariation.compilec              	   C   sX   g }| j }|D ]>}||}|d kr0|d q|tdt|d d qd|S )Ns     >hr9   r3   rW   )r   r?   r^   rd   re   fl2fir   )r   rH   resultr   r4   Ztripler   r   r   r\      s    
zTupleVariation.compileCoordc              	   C   s   d}|D ]D}| j |d\}}}t|d}t|d}||ksD||krd} qNq|sVd S g }	g }
|D ]H}| j |d\}}}|	tdt|d |
tdt|d qbd|	|
 S )NFr1   r1   r1   r1   Trk   r3   rW   )	r   r?   r5   r6   r^   rd   re   rl   r   )r   rH   neededr4   rI   r   rJ   rK   rL   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 )Nrk   r7   r   r3   )fi2flrd   unpack)rH   dataoffsetr2   posr4   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   r9   )r   sortrB   	bytearrayr^   POINTS_ARE_WORDS)points	numPointsrm   ZMAX_RUN_LENGTHrt   Z	lastValue	runLengthZ	headerPosZuseByteEncodingZcurValuer8   r   r   r   r[      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gvarr9   r   rw   Hr7   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   )rZ   r{   POINT_RUN_COUNT_MASKrangerB   array	frombytessys	byteorderbyteswapextendr^   rD   rP   r   r   )r}   rr   rs   tableTagrt   ZnumPointsInDatarm   	runHeaderZnumPointsInRunrS   r|   Z
pointsSizeabsolutecurrentr8   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 }| j|||d | j|||d |S )Nr7   r   r9   rU   )getCoordWidthr   r^   rz   compileDeltaValues_)r   rV   ZdeltaXZdeltaYr+   bytearrr   r   r   rb   G  s     

zTupleVariation.compileDeltasc                C   s  |dkrt  }d}t| }|r||k r| | }|dkrFt| ||}qd|  krZdkrnn nt| ||}qd|  krdkrn nt| ||}qt| ||}qnt| t|  }}|d  kr|krn nt| ||}nd|  kr|  krdkrn ntj| ||dd}nNd|  krB|  krBdkrZn ntj| ||dd}ntj| ||dd}||kst	||f|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      FrU   )
rz   rB   r   encodeDeltaRunAsZeroes_encodeDeltaRunAsBytes_encodeDeltaRunAsWords_encodeDeltaRunAsLongs_r5   r6   rZ   )deltasr   rV   rt   	numDeltasr   ZminValZmaxValr   r   r   r   Z  sN    (   (      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   r9   r   r   )rB   r^   DELTAS_ARE_ZERO)r   rs   r   rt   r   r~   r   r   r   r     s    

z&TupleVariation.encodeDeltaRunAsZeroes_c              	   C   s   |}t | }||k rh| | }d|  kr0dks4qh qh|r^|dkr^|d |k r^| |d  dkr^qh|d7 }q|| }|dkr|d |td| ||d   |d7 }|d8 }qp|r||d  |td| ||  |S )Nr   r   r   r9   r   r   b)rB   r^   r   r   )r   rs   r   rV   rt   r   r   r~   r   r   r   r     s4    




z%TupleVariation.encodeDeltaRunAsBytes_c           	      C   sH  |}t | }||k r| | }|r*|dkr*q|rtd|  krBdkrtn n.|d |k rtd| |d    krndkrtq nqd|  krdksq q|d7 }q|| }|dkr|tdB  td	| ||d  }tjd
kr|  || |d7 }|d8 }q|rD|t|d B  td	| || }tjd
kr:|  || |S )Nr   r   r   r9   r   r   r   r   hr   )rB   r^   DELTAS_ARE_WORDSr   r   r   r   r   	r   rs   r   rV   rt   r   r   r~   ar   r   r   r     sP    		 

 






z%TupleVariation.encodeDeltaRunAsWords_c           	      C   s   |}t | }||k rD| | }|r:d|  kr4dkr:qD nqD|d7 }q|| }|dkr|tdB  td| ||d  }tjdkr|  || |d7 }|d8 }qL|r|t|d B  td| || }tjdkr|  || |S )Nr   r   r9   r   r   r$   r   )rB   r^   DELTAS_ARE_LONGSr   r   r   r   r   r   r   r   r   r     s.    





z%TupleVariation.encodeDeltaRunAsLongs_r   c           	      C   s2  g }|}| dk	r t || k rn|t |k r|| }|d7 }|t@ d }|t@ tkrh|dg|  q|t@ tkrtd}|d }n.|t@ tkrtd}|d }ntd}|}|||||   t	j
d	kr|  t ||kstt ||f||7 }|| q| dks*t || ks*t||fS )
z>(numDeltas, data, offset) --> ([delta, delta, ...], newOffset)Nr9   r   r$      r   r7   r   r   )rB   DELTA_RUN_COUNT_MASKDELTAS_SIZE_MASKr   r   r   r   r   r   r   r   r   rZ   )	r   rr   rs   rm   rt   r   ZnumDeltasInRunr   Z
deltasSizer   r   r   decompileDeltas_  s0    &





zTupleVariation.decompileDeltas_c                 C   s8   d}| t @ dkr||d 7 }| t@ dkr4||d 7 }|S )Nr   r   r7   )r]   r`   )ri   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   r9   r7   zSinvalid type of delta; expected (int or float) number, or Tuple[number, number]: %r)nextr   rA   rC   floatr0   rB   	TypeError)r   Z
firstDeltar   r   r   r   7  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 Nr9   r   r   r   d
coordWidthscalarr   r   r   K  s   z.TupleVariation.scaleDeltas.<locals>.<listcomp>r   r   r   r   r   r   r   scaleDeltasG  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   V  s   z.TupleVariation.roundDeltas.<locals>.<listcomp>r   r.   r   r   r   roundDeltasT  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_deltar9   z3Only 'gvar' TupleVariation can have inferred deltasz(Expected len(origCoords) == %d; found %d)fontTools.varLib.iupr   r   r   r   rB   
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,   v  s     z*TupleVariation.optimize.<locals>.<genexpr>)r   r   r9   )
r   r   r   allrB   r   r   r   rQ   rj   )r   r   r   r   ZisCompositer   ZdeltaOptZvarOptrH   rg   rh   ZunoptimizedLengthZoptimizedLengthr   r   r   optimizel  s(    
   zTupleVariation.optimizec                 C   s   |  | | S r   )r   r   r   r   r   __imul__  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 lengthsr7   r   r9   z+cannot sum gvar deltas with inferred points)

isinstancer   NotImplementedr   rB   r   r   zipr   r   )r   r"   Zdeltas1lengthZdeltas2r$   Zd2d1r   r   r   __iadd__  s*    
	(
zTupleVariation.__iadd__)T)N)T)T)T)r   )r   F) __name__
__module____qualname__r   r!   r#   r)   r/   rN   rT   rj   r\   r_   staticmethodru   r[   r   rb   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   '   sT   ) (

@
2
6
"3

r   c                 C   s2   g }t |D ] }t| ||\}}|| q|S r   )r   r   ru   r^   )rH   ZsharedTupleCountrr   rs   rm   _tr   r   r   decompileSharedTuples  s
    r   r9   c                 C   sN   t  }|D ]}|| }||  d7  < q
t||dd d}dd |D S )Nr9   c                 S   s   | d  | d fS r   r   )itemr   r   r   <lambda>  rW   z%compileSharedTuples.<locals>.<lambda>keyc                 S   s    g | ]}|d  d kr|d qS )r9   r   r   r*   r   r   r   r     s      z'compileSharedTuples.<locals>.<listcomp>)r   r\   r   most_common)rH   
variationsZMAX_NUM_SHARED_COORDSZ
coordCountvarr2   ZsharedCoordsr   r   r   compileSharedTuples  s    
r   TrU   c                   sZ  ~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 ]4\}	}|	j||||d\}}|| || qd|}d|}|||fS )Nr9   )r   rW   rW   r   c                 3   s   | ]}t |j kV  qd S r   )rB   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   r[   )r   pointSetr   r   r   
<dictcomp>  s     z.compileTupleVariationStore.<locals>.<dictcomp>c                    s$   | d }| d }t  | |d  S )Nr   r9   )rB   )Zpnr   count)compiledPointsr   r   r     s    z'compileTupleVariationStore.<locals>.keyr   c                    s    g | ]}|kr | nd qS )rW   r   )r   r|   )r   sharedPointsr   r   r     s   z.compileTupleVariationStore.<locals>.<listcomp>)rf   rV   rW   )r	   rC   r)   r^   rB   r   r   rZ   r6   r    TUPLES_SHARE_POINT_NUMBERSr   rj   r   )r   
pointCountrH   ZsharedTupleIndicesZuseSharedPointsrV   ZnewVariationsZ
pointDatasZpointSetCountr   r|   tupleVariationCountZtuplesrr   r   r%   Z	thisTupleZthisDatar   )r   r   r   r   compileTupleVariationStore  s`    


   



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   rX   r   )rB   r   r   r   r   TUPLE_COUNT_MASKrd   rq   r   r^   decompileTupleVariation_)r   rH   r   r   sharedTuplesrr   rt   ZdataPosZnumAxesrm   r   r   ZdataSizeri   Z	tupleSizerg   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>Hr7   r   r   rn   r   r   )rZ   rd   rq   r]   TUPLE_INDEX_MASKr   ru   r`   inferRegion_ra   r   r   rB   r   )r   r   r   r   rH   rr   rg   ri   rt   peakstartendr   r4   Zregionr|   r   Z
deltas_cvtr%   r8   Zdeltas_xZdeltas_yr;   r<   r   r   r   r   7  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.
    r1   )r    r5   r6   )r   r   r   r4   r   r   r   r   r   e  s
    
r   )T),ZfontTools.misc.fixedToolsr   rp   r   rl   r   r@   r   rO   r   ZfontTools.misc.textToolsr   r   collectionsr   r	   iologgingrd   r   r]   r`   ra   r   r   r   r   r   r{   r   r   r   r   	getLoggerr   rD   objectr   r   r   r   r   r   r   r   r   r   r   <module>   sJ   
     	
 K'.