o
    a^                     @   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d8d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d9d4d5Zd6d7 ZdS ):TupleVariationc                 C   s   |  | _t|| _d S N)copyaxeslistcoordinates)selfr   r    r   G/usr/lib/python3/dist-packages/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>,       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__/   s   zTupleVariation.__eq__c                 C   s4   d | j vrt S tdd t| j D }|r|S d S )Nc                 S   s   g | ]
\}}|d ur|qS r   r   )r   ipr   r   r   r   6   r   z0TupleVariation.getUsedPoints.<locals>.<listcomp>)r   	frozenset	enumerate)r   usedr   r   r   getUsedPoints2   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 uV  qd S r   r   r   cr   r   r   	<genexpr>@       z+TupleVariation.hasImpact.<locals>.<genexpr>)anyr   r   r   r   r   	hasImpact:   s   zTupleVariation.hasImpactc                 C   s  | d |  |D ]P}| j|}|d ur[|\}}}t|d}t|d}||kr:||kr:|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 ]O\}}t
|tkrt|dkr|jd||d |d d |  d}
qct
|tkr|jd||d |  d}
qc|d urtd |d|  |  d}
qc|
s|d |  |d |  d S )Ntuple        coord   )axisr   r5   minr   maxF   deltar      )ptxyT)cvtr   zbad delta formatzbad delta #%dz	no deltas)Zbegintagnewliner   getr6   r7   Z	simpletagfl2strr'   r   typer1   lenintlogerrorZcommentZendtag)r   writeraxisTagsr5   r   minValuemaxValuedefaultMinValuedefaultMaxValueattrsZwrote_any_deltasr$   r9   r   r   r   toXMLB   sN   






zTupleVariation.toXMLc                 C   s  |dkr5|d }t |d d}t|d}t|d}t |d|d}t |d|d}	|||	f| j|< d S |dkrd	|v rXt|d	 }
t|d
 }t|d }||f| j|
< d S d|v rot|d }t|d }|| j|< d S tdd	t
|   d S d S )Nr3   r5   r   r4   r2   r6   r7   r9   r;   r<   r=   r>   zbad delta format: %sz, )str2flr6   r7   r@   r   r   r   rE   warningr   r   keys)r   r   rM   Z_contentr5   r   rK   rL   rI   rJ   pointr<   r=   r>   r   r   r   fromXMLk   s,   


zTupleVariation.fromXMLNc           
      C   s   t | j t |ksJ d| j |fg }g }|d u r,|  }|d u r'dS | |}| |}||}|d u rAt}|| | 	|}	|	d urS|t
O }||	 |r^|tO }|| ||   d|}|dtdt|| d||fS )NzUnknown axis tag found.)    rT   rT   r   >HH)setr   rQ   r)   compilePointscompileCoordr@   EMBEDDED_PEAK_TUPLEappendcompileIntermediateCoordINTERMEDIATE_REGIONPRIVATE_POINT_NUMBERScompileDeltasr   insertstructpackrC   )
r   rH   ZsharedCoordIndices	pointData	tupleDataauxDataZ
usedPointsr3   flagsZintermediateCoordr   r   r   compile   s0   *







zTupleVariation.compilec              	   C   sX   t  }| j}|D ]}||}|d u r|d q|tdt|d d qt|S )Ns     >hr:   r4   )	bytearrayr   r@   extendr`   ra   fl2fibytes)r   rH   resultr   r5   Ztripler   r   r   rX      s   
zTupleVariation.compileCoordc              	   C   s   d}|D ]"}| j |d\}}}t|d}t|d}||ks"||kr&d} nq|s+d S t }	t }
|D ]$}| j |d\}}}|	tdt|d |
tdt|d q3|	|
 S )NFr2   r2   r2   r2   Trg   r4   )	r   r@   r6   r7   rh   ri   r`   ra   rj   )r   rH   Zneededr5   rI   r   rJ   rK   rL   Z	minCoordsZ	maxCoordsr   r   r   r[      s$   

z'TupleVariation.compileIntermediateCoordc              	   C   sH   i }|}| D ]}t td|||d  d d||< |d7 }q||fS )Nrg   r8   r   r4   )fi2flr`   unpack)rH   dataoffsetr3   posr5   r   r   r   decompileCoord_   s   &
zTupleVariation.decompileCoord_c                 C   s\  | sdS t | } |   t| }t }|dk r|| n||d? dB  ||d@  d}d}d}||k rd}t|}|d d }||k r||kr| | }	|	| }
|d u rdd|
  koadkn  }|ro|
dksn|
dk ron(|rw||
 n||
d?  ||
d@  |	}|d7 }|d7 }||k r||ksL|r|d ||< n|d tB ||< ||k s7|S )N    r
         r   r   r:   )r   sortrC   rh   rZ   POINTS_ARE_WORDS)points	numPointsrl   ZMAX_RUN_LENGTHrr   Z	lastValue	runLengthZ	headerPosZuseByteEncodingZcurValuer9   r   r   r   rW      sL   
zTupleVariation.compilePointsc                    st  |dv sJ |}|| }|d7 }|t @ dkr$|t@ d> || B }|d7 }|dkr.t |fS g }t||k r|| }|d7 }|t@ d }d}	|t @ dkrVtd}
|d }ntd}
|}|
||||   tjdkrq|
  t|
|ksyJ ||7 }|	|
 t||k s6g }d}|D ]}||7 }|
| q|}~ fd	d
|D }|rtddt||f  ||fS )zJ(numPoints, data, offset, tableTag) --> ([point1, point2, ...], newOffset)cvargvarr:   r   ru   Hr8   Bbigc                    s$   h | ]}|d k s| krt |qS )r   )str)r   r%   rz   r   r   	<setcomp>6  s   $ z2TupleVariation.decompilePoints_.<locals>.<setcomp>z#point %s out of range in '%s' tabler   )rx   POINT_RUN_COUNT_MASKrangerC   array	frombytessys	byteorderbyteswapri   rZ   rE   rP   r   r   )rz   rp   rq   tableTagrr   ZnumPointsInDatarl   	runHeaderZnumPointsInRunrR   ry   Z
pointsSizeZabsoluteZcurrentr9   Z	badPointsr   r   r   decompilePoints_  sN   



zTupleVariation.decompilePoints_c                 C   s   g }g }|   dkr$| jD ]}|d u rq||d  ||d  qn| jD ]}|d u r.q'|| q't }| || | || |S )Nr8   r   r:   )getCoordWidthr   rZ   rh   compileDeltaValues_)r   ZdeltaXZdeltaYr+   bytearrr   r   r   r^   <  s"   

zTupleVariation.compileDeltasc                 C   s   |du rt  }d}t| }||k r@| | }|dkr!t| ||}nd|  kr+dkr5n nt| ||}nt| ||}||k s|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   )rh   rC   r   encodeDeltaRunAsZeroes_encodeDeltaRunAsBytes_encodeDeltaRunAsWords_)deltasr   rr   	numDeltasr   r   r   r   r   O  s   z"TupleVariation.compileDeltaValues_c                 C   s   |}t | }||k r| | dkr|d7 }||k r| | dks|| }|dkr5|tdB  |d8 }|dks&|r@|t|d B  |S )Nr   r:   r   r   )rC   rZ   DELTAS_ARE_ZERO)r   rq   r   rr   r   r{   r   r   r   r   n  s   z&TupleVariation.encodeDeltaRunAsZeroes_c              	   C   s   |}t | }||k r5| | }d|  krdksn n|dkr-|d |k r-| |d  dkr-n|d7 }||k s
|| }|dkr]|d |td| ||d   |d7 }|d8 }|dks=|rs||d  |td| ||  |S )Nr   r   r   r:   r   r   b)rC   rZ   ri   r   )r   rq   r   rr   r   r   r{   r   r   r   r   |  s*   $	
z%TupleVariation.encodeDeltaRunAsBytes_c                 C   s0  |}t | }||k r>| | }|dkrn+d|  krdkr6n n|d |k r6d| |d    kr3dkr6n nn|d7 }||k s
|| }|dkrs|tdB  td| ||d  }tjdkrb|  || |d7 }|d8 }|dksF|r|t|d B  td| || }tjdkr|  || |S )	Nr   r   r   r:   r   r   hr   )rC   rZ   DELTAS_ARE_WORDSr   r   r   r   ri   )r   rq   r   rr   r   r   r{   ar   r   r   r     s2   D

z%TupleVariation.encodeDeltaRunAsWords_c           	      C   s   g }|}t || k ri|| }|d7 }|t@ d }|t@ dkr'|dg|  n<|t@ dkr7td}|d }ntd}|}|||||   tjdkrR|	  t ||ksZJ ||7 }|| t || k s
t || ksqJ ||fS )z>(numDeltas, data, offset) --> ([delta, delta, ...], newOffset)r:   r   r   r8   r   r   )
rC   DELTA_RUN_COUNT_MASKr   ri   r   r   r   r   r   r   )	r   rp   rq   rl   rr   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r||d 7 }|S )N   r   r8   )rY   r\   )re   Z	axisCountsizer   r   r   getTupleSize_  s   zTupleVariation.getTupleSize_c                 C   s^   t dd | jD d}|du rdS t|ttfv rdS t|tu r)t|dkr)dS td| )zb Return 2 if coordinates are (x, y) as in gvar, 1 if single values
		as in cvar, or 0 if empty.
		c                 s   s    | ]	}|d ur|V  qd S r   r   r*   r   r   r   r,     s    z/TupleVariation.getCoordWidth.<locals>.<genexpr>Nr   r:   r8   zSinvalid type of delta; expected (int or float) number, or Tuple[number, number]: %r)nextr   rB   rD   floatr1   rC   	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 | ]}|d u r
d n dkr| n|d  |d  fqS Nr:   r   r   r   d
coordWidthscalarr   r   r         
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 | ]}|d u r
d n dkrt |nt |d t |d fqS r   )r   r   r   r   r   r     r   z.TupleVariation.roundDeltas.<locals>.<listcomp>r   r/   r   r   r   roundDeltas  s   
zTupleVariation.roundDeltasc                 C   sn   ddl m} |  dkrtdd | jv r5t| jt|kr+tdt| jt|f || j||| _d S d S )Nr   )	iup_deltar:   z3Only 'gvar' TupleVariation can have inferred deltasz(Expected len(origCoords) == %d; found %d)fontTools.varLib.iupr   r   r   r   rC   
ValueError)r   
origCoordsendPtsr   r   r   r   calcInferredDeltas  s   
z!TupleVariation.calcInferredDeltas      ?Fc                 C   s   ddl m} d | jv rd S || j|||d}d |v rf|r1tdd |D r1dgd gt|d   }t| j|}t| j }| 	|\}	}
t|	t|
 }|	|\}	}
t|	t|
 }||k rh|j| _d S d S d S )Nr   )iup_delta_optimize)	tolerancec                 s   s    | ]}|d u V  qd S r   r   r   r   r   r   r,   &  r-   z*TupleVariation.optimize.<locals>.<genexpr>)r   r   r:   )
r   r   r   allrC   r   r   r   rQ   rf   )r   r   r   r   ZisCompositer   ZdeltaOptZvarOptrH   rc   rd   ZunoptimizedLengthZoptimizedLengthr   r   r   optimize  s&   

zTupleVariation.optimizec              	   C   s   t |tstS | j}t|}|j}t||krtd|  dkrRtt||D ]'\}}|| }z|d |d  |d |d  f||< W q( t	yO   tdw | S tt||D ]#\}}|| }|d urp|d urp|| ||< qY|d u r||d ur||||< qY| S )Nz7cannot sum TupleVariation deltas with different lengthsr8   r   r:   z+cannot sum gvar deltas with inferred points)

isinstancer   NotImplementedr   rC   r   r   zipr   r   )r   r"   Zdeltas1lengthZdeltas2r$   Zd2Zd1r   r   r   __iadd__7  s8   
(zTupleVariation.__iadd__r   )r   F)__name__
__module____qualname__r   r!   r#   r)   r0   rN   rS   rf   rX   r[   staticmethodrs   rW   r   r^   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   %   sH    )"

@
/


'


r   c                 C   s2   g }t |D ]}t| ||\}}|| q|S r   )r   r   rs   rZ   )rH   ZsharedTupleCountrp   rq   rl   _tr   r   r   decompileSharedTuples]  s
   r   r:   c                 C   sN   t  }|D ]}|| }||  d7  < qt||dd d}dd |D S )Nr:   c                 S   s   | d  | d fS r   r   )itemr   r   r   <lambda>o  s    z%compileSharedTuples.<locals>.<lambda>keyc                 S   s    g | ]}|d  d kr|d qS )r:   r   r   r*   r   r   r   r   q  s     z'compileSharedTuples.<locals>.<listcomp>)r   rX   r   most_common)rH   
variationsZMAX_NUM_SHARED_COORDSZ
coordCountvarr3   ZsharedCoordsr   r   r   compileSharedTuplese  s   
r   Tc                    sT  g }g }d t t}| D ]}| }	|	d u rq||	  d7  < || ||	 q|} ~| s1dS t| d jtfdd| D sGJ ddd |D  t| }
g }g }|rs fd	d
}t| |dd |   |
t	O }
 fdd|D }t
| |D ]\}}|j|||d\}}|| || qd|}d|}|
||fS )Nr:   )r   rT   rT   r   c                 3   s    | ]
}t |j kV  qd S r   )rC   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   rW   )r   pointSetr   r   r   
<dictcomp>  s    z.compileTupleVariationStore.<locals>.<dictcomp>c                    s$   | d }| d }t  | |d  S )Nr   r:   )rC   )Zpnr   count)compiledPointsr   r   r     s   z'compileTupleVariationStore.<locals>.keyr   c                    s    g | ]}|kr | nd qS )rT   r   )r   ry   )r   sharedPointsr   r   r     s    z.compileTupleVariationStore.<locals>.<listcomp>)rb   rT   )r	   rD   r)   rZ   rC   r   r   r7   r    TUPLES_SHARE_POINT_NUMBERSr   rf   r   )r   
pointCountrH   ZsharedTupleIndicesZuseSharedPointsZnewVariationsZ
pointDatasZpointSetCountr   ry   tupleVariationCountZtuplesrp   r   r%   Z	thisTupleZthisDatar   )r   r   r   r   compileTupleVariationStoret  sL   




r   c                 C   s   t |}g }	|t@ dkrt|||| \}
}ng }
t|t@ D ];}td|||d  \}}t||}||||  }||||  }|		t
|||
| ||| ||7 }||7 }q|	S )Nr   rU   r   )rC   r   r   r   r   TUPLE_COUNT_MASKr`   ro   r   rZ   decompileTupleVariation_)r   rH   r   r   sharedTuplesrp   rr   ZdataPosZnumAxesrl   r   r   ZdataSizere   Z	tupleSizerc   ZpointDeltaDatar   r   r   decompileTupleVariationStore  s&   

r   c                 C   s  |dv sJ |t d|dd d }d}|t@ dkr#||t@  }	n	t|||\}	}|t@ dkrEt|||\}
}t|||\}}nt|	\}
}i }|D ]}|
| |	| || f}|dkrd|||< qOd}|t@ dkrxt	| |||\}}n|}d g|  }|dkrt
t|||\}}t||D ]\}}d|  kr| k rn q|||< qn8|dkrt
t|||\}}t
t|||\}}t|||D ]\}}}d|  kr| k rn q||f||< qt||S )	Nr|   z>Hr8   r   r   rm   r}   r~   )r`   ro   rY   TUPLE_INDEX_MASKr   rs   r\   inferRegion_r]   r   r   rC   r   )r   r   r   r   rH   rp   rc   re   rr   peakstartendr   r5   Zregionry   r   Z
deltas_cvtr%   r9   Zdeltas_xZdeltas_yr<   r=   r   r   r   r     sX   





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.
    r2   )r    r6   r7   )r   r   r   r5   r   r   r   r   r     s
   
r   )T)*ZfontTools.misc.fixedToolsr   rn   r   rj   r   rA   r   rO   r   ZfontTools.misc.textToolsr   r   collectionsr   r	   ioZloggingr`   r   rY   r\   r]   r   r   r   rx   r   r   r   r   Z	getLoggerr   rE   objectr   r   r   r   r   r   r   r   r   r   r   <module>   sB    
    <	

;/