U
    DvfS9                     @   s:  zd dl Z e jZW n( eefk
r:   d dlm Z  dZY nX d dlmZmZm	Z	 d dl
mZmZ eeef Zeeef Zee Zee Ze	edf Zee Zee ZdZe je je je je je je je je je je jd	eeeeedd	d
ZeeedddZeeeedddZe je je je je je je je je jde eeeeeedddZe je je je je je je je jedd)eeeedddZ e je je je je je jee jde d dfeeeedddZ!e"edddZ#eeed d!d"Z$d*eeeedd$d%Z%d+eeeeed&d'd(Z&dS ),    N)cythonF)SequenceTupleUnion)IntegralReal   )	jnx1x2d1d2scalexd)coordsrc1rd1rc2rd2c                 C   s   ddg}dD ]}g  ||< }|| || || || f\}}	}
}||	kr|t | }|
|krj||
g|  q|dg|  q||	kr|	| }}	||
 }
}||
 |	|  }| D ]B}|| }||kr|
}n||	kr|}n|
|| |  }|| qqt| S )zGiven two reference coordinates `rc1` & `rc2` and their respective
    delta vectors `rd1` & `rd2`, returns interpolated deltas for the set of
    coordinates `coords`.Nr      r   )lenextendappendzip)r   r   r   r   r   Z
out_arraysr	   outr   r   r   r   r
   r   pairr   r    r   8/tmp/pip-unpacked-wheel-qlge9rch/fontTools/varLib/iup.pyiup_segment   s.    $

r!   )deltasr   returnc              
   C   s  t | t |kstd| kr | S t | }dd t| D }|sHdg| S g }t|}t|}|dkrd|||d f\}}}	}
|t||| ||	 | |	 ||
 | |
  || |  |D ]j}|| dkr|d |||f\}}}	}
|t||| ||	 | |	 ||
 | |
  || |  |}q||d kr|d |||d f\}}}	}
|t||| ||	 | |	 ||
 | |
  t | t |kstt | t |f|S )zFor the contour given in `coords`, interpolate any missing
    delta values in delta vector `deltas`.

    Returns fully filled-out delta vector.Nc                 S   s   g | ]\}}|d k	r|qS Nr   ).0ivr   r   r    
<listcomp>c   s      ziup_contour.<locals>.<listcomp>)r   r   r   r   )r   AssertionError	enumerateiternextr   r!   r   )r"   r   r
   indicesr   itstarti1i2Zri1Zri2endr   r   r    iup_contourW   sb    

    
    
    &r4   )r"   r   endsr#   c                 C   s   t ||kr,t||r"|d d ndd ks0tt|}||d |d |d |d g }g }d}|D ]4}|d7 }t| || ||| }|| |}qd|S )zFor the outline given in `coords`, with contour endpoints given
    in sorted increasing order in `ends`, interpolate any missing
    delta values in delta vector `deltas`.

    Returns fully filled-out delta vector.r)   r   r            )sortedr   r*   r4   r   )r"   r   r5   r
   r   r0   r3   contourr   r   r    	iup_delta   s    	0 
r;   )r&   r	   r   ypq)r"   r   r&   r	   	tolerancec                    sh   || dkst t||d | || | | || | | }| |d | } t fddt| |D S )zReturn true if the deltas for points at `i` and `j` (`i < j`) can be
    successfully used to interpolate deltas for points in between them within
    provided error tolerance.r8   r   c                 3   s4   | ],\\}}\}}t t|| ||  kV  qd S r$   abscomplex)r%   r   r<   r=   r>   r?   r   r    	<genexpr>   s   z%can_iup_in_between.<locals>.<genexpr>)r*   r!   allr   )r"   r   r&   r	   r?   Zinterpr   rC   r    can_iup_in_between   s    ,rF   )cjdjlcjldjncjndjforceforced)r"   r   r?   r#   c                 C   s  t | t |kstt | }t }tt | d ddD ]}| |d  ||d   }}| | ||  }}	| || d  ||| d   }
}dD ]}|	| }|| }|| }|| }|| }|
| }||kr|| }}|| }}n|| }}|| }}d}||kr*t|| |krt||krd}n||  krB|krzn n4t||| |  krrt||| ksn d}n||kr||k rt||krt|| |kr|| |k ||k krd}n:t||krt|| |kr||| k ||k krd}|r||  q6qq6|S )a  The forced set is a conservative set of points on the contour that must be encoded
    explicitly (ie. cannot be interpolated).  Calculating this set allows for significantly
    speeding up the dynamic-programming, as well as resolve circularity in DP.

    The set is precise; that is, if an index is in the returned set, then there is no way
    that IUP can generate delta for that point, given `coords` and `deltas`.
    r   r)   r   FT)r   r*   setrangerA   minmaxadd)r"   r   r?   r
   rN   r&   Zldlcr   cZndZncr	   rG   rH   rI   rJ   rK   rL   Zc1c2r   r   rM   r   r   r    _iup_contour_bound_forced_set   s\    "




 .




rW   )r&   r	   	best_costZbest_jcostrN   r?   )r"   r   r?   lookbackc                 C   s   t | }|dkr|}t|t}ddi}ddi}td|D ]}||d  d }	|	||< |d ||< |d |krnq8t|d t|| ddD ]H}
||
 d }||	k rt| ||
||r| ||< }	|
||< |
|kr q8qq8||fS )a  Straightforward Dynamic-Programming.  For each index i, find least-costly encoding of
    points 0 to i where i is explicitly encoded.  We find this by considering all previous
    explicit points j and check whether interpolation can fill points between j and i.

    Note that solution always encodes last point explicitly.  Higher-level is responsible
    for removing that restriction.

    As major speedup, we stop looking further whenever we see a "forced" point.Nr)   r   r   r8   )r   rQ   MAX_LOOKBACKrP   rR   rF   )r"   r   rN   r?   rZ   r
   costschainr&   rX   r	   rY   r   r   r    _iup_contour_optimize_dp!  s(    
r_   )lkc                 C   s8   t | }||; }|s| S | || d | d||   S )z{Rotate list by k items forward.  Ie. item at position 0 will be
    at position k in returned list.  Negative k is allowed.N)r   )r`   ra   r
   r   r   r    	_rot_listV  s
    rb   sra   r
   c                    s$    ;   s| S  fdd| D S )Nc                    s   h | ]}|   qS r   r   )r%   r'   ra   r
   r   r    	<setcomp>d  s     z_rot_set.<locals>.<setcomp>r   rc   r   re   r    _rot_set`  s    rg           c                    s  t }tfddD r(dg| S |dkr4S d tfddD rfgdg|d   S t|}|r6|d t| }|dkstt|t||}t|||}t||\}}t |d }|dk	r	| || }qԈ
d |kst|ffdd	t|D t| nt || ||\}}d|d   }	t|d t |d D ]n}
t |
}||
| kr	||  || }q||
| krv||
 ||
|   }||	krv|  }	qv| kst| f fd
d	t|D S )zFor contour with coordinates `coords`, optimize a set of delta
    values `deltas` within error `tolerance`.

    Returns delta vector that has most number of None items instead of
    the input delta.
    c                 3   s   | ]}t t|  kV  qd S r$   r@   )r%   r=   rC   r   r    rD   v  s     z'iup_contour_optimize.<locals>.<genexpr>Nr   r   c                 3   s   | ]} |kV  qd S r$   r   )r%   r   )d0r   r    rD     s     r)   c                    s    g | ]}|kr | nd qS r$   r   r%   r&   )r"   solutionr   r    r(     s     z(iup_contour_optimize.<locals>.<listcomp>c                    s    g | ]}| kr| nd qS r$   r   rj   )best_solr"   r   r    r(     s     )r   rE   rW   rR   r*   rb   rg   r_   rO   rS   removerP   )r"   r   r?   r
   rN   ra   r^   r]   r&   rX   r0   rY   r   )rl   ri   r"   rk   r?   r    iup_contour_optimizeg  s\    

	




    
rn   )r"   r   r5   r?   r#   c           	      C   s   t ||kr,t||r"|d d ndd ks0tt|}||d |d |d |d g }g }d}|D ]R}t| ||d  |||d  |}t||| d kst|| |d }qd|S )a  For the outline given in `coords`, with contour endpoints given
    in sorted increasing order in `ends`, optimize a set of delta
    values `deltas` within error `tolerance`.

    Returns delta vector that has most number of None items instead of
    the input delta.
    r)   r   r   r6   r7   r8   )r9   r   r*   rn   r   )	r"   r   r5   r?   r
   r   r0   r3   r:   r   r   r    iup_delta_optimize  s    0   

ro   )r   )rh   )rh   )'r   ZcompiledZCOMPILEDAttributeErrorImportErrorZfontTools.misctypingr   r   r   Znumbersr   r   Z_PointZ_DeltaZ_PointSegmentZ_DeltaSegmentZ_DeltaOrNoneZ_DeltaOrNoneSegmentZ
_Endpointsr\   Zcfunclocalsintdoubler!   r4   r;   inlineZreturnsrF   rO   rW   r_   listrb   rg   rn   ro   r   r   r   r    <module>   s   

    ,5  	   Q,
   i 