o
    aA                     @   sb  zd dl Z W n ey   d dlm Z  Y nw d dlZddlmZmZ ddgZdZ	e
dZe jr2d	Znd
Ze je je e je je je jddd Ze je je je je je je jde je je je je jddd Ze je je je je je je jde je je je je jddd Ze je je je je je jddd Ze je je je je je jde je je je je jde je je je je jde je je je je jddd Ze je je je je jde je je jddd Ze je je je je je jde je je je je jd dLd"d#Ze e je je je je je je jd$e je je jd%d&d' Ze e je je je je je jde je je je je jd(d)d* Ze je e je je je je je je jd+e je je jdd,d- Ze je je je jd.e je je je je je jd/dMd1d2Ze je je je je jd3e je jd4e je je je je jd5e je je je je je jd6dMd7d8Z e je jd9e je jd:d;d Z!e je je je jd<d=d Z"e#d>kr/d dl$Z$d dl%Z%d?Z&d@dA Z'dBdC Z(dDdE Z)	GdNdHdIZ*dJdK Z+e$,d e+  dS dS )O    N)cython   )ErrorApproxNotFoundErrorcurve_to_quadraticcurves_to_quadraticd   ZNaNTFZv1Zv2c                 C   s   | |   jS )zReturn the dot product of two vectors.

    Args:
        v1 (complex): First vector.
        v2 (complex): Second vector.

    Returns:
        double: Dot product.
    )	conjugaterealr	    r   7/usr/lib/python3/dist-packages/fontTools/cu2qu/cu2qu.pydot,   s   r   )abcd)_1_2_3_4c                 C   s<   |}|d | }|| d | }| | | | }||||fS N      @r   )r   r   r   r   r   r   r   r   r   r   r   calc_cubic_points=   s
   r   )p0p1p2p3c                 C   s<   ||  d }|| d | }| }|| | | }||||fS r   r   )r   r   r   r   r   r   r   r   r   r   r   calc_cubic_parametersI   s
   r   c                 C   s   |dkrt t| |||S |dkrt t| |||S |dkr1t| |||\}}t t| t|  S |dkrHt| |||\}}t t| t|  S t| ||||S )a  Split a cubic Bezier into n equal parts.

    Splits the curve into `n` equal parts by curve time.
    (t=0..1/n, t=1/n..2/n, ...)

    Args:
        p0 (complex): Start point of curve.
        p1 (complex): First handle of curve.
        p2 (complex): Second handle of curve.
        p3 (complex): End point of curve.

    Returns:
        An iterator yielding the control points (four complex values) of the
        subcurves.
                )itersplit_cubic_into_twosplit_cubic_into_three_split_cubic_into_n_gen)r   r   r   r   nr   r   r   r   r   split_cubic_into_n_iterU   s   r(   )r   r   r   r   r'   )dtdelta_2delta_3i)a1b1c1d1c                 c   s    t | |||\}}}}d| }	|	|	 }
|	|
 }t|D ]@}||	 }|| }|| }d| | | |
 }d| | | d| |  |	 }|| | ||  ||  | }t||||V  qd S )Nr   r    r   )r   ranger   )r   r   r   r   r'   r   r   r   r   r)   r*   r+   r,   t1Zt1_2r-   r.   r/   r0   r   r   r   r&   v   s     r&   )midderiv3c                 C   s\   | d||   | d }|| | |  d }| | | d || |f||| || d |ffS )a  Split a cubic Bezier into two equal parts.

    Splits the curve into two equal parts at t = 0.5

    Args:
        p0 (complex): Start point of curve.
        p1 (complex): First handle of curve.
        p2 (complex): Second handle of curve.
        p3 (complex): End point of curve.

    Returns:
        tuple: Two cubic Beziers (each expressed as a tuple of four complex
        values).
    r          ?      ?r   )r   r   r   r   r3   r4   r   r   r   r$      s
   r$   )r   r   r   r   _27)mid1deriv1mid2deriv2h/?c           	      C   s   d|  d|  d|  | | }|d|  d|   | }| d|  d|  d|  | }d| d|  |  | }| d|  | d || |f||| || |f||| |d|  d |ffS )a  Split a cubic Bezier into three equal parts.

    Splits the curve into three equal parts at t = 1/3 and t = 2/3

    Args:
        p0 (complex): Start point of curve.
        p1 (complex): First handle of curve.
        p2 (complex): Second handle of curve.
        p3 (complex): End point of curve.

    Returns:
        tuple: Three cubic Beziers (each expressed as a tuple of four complex
        values).
          r"   r    r!   r   r   r   )	r   r   r   r   r7   r8   r9   r:   r;   r   r   r   r%      s     r%   )tr   r   r   r   )_p1_p2c                 C   s0   ||| d  }||| d  }||| |   S )ax  Approximate a cubic Bezier using a quadratic one.

    Args:
        t (double): Position of control point.
        p0 (complex): Start point of curve.
        p1 (complex): First handle of curve.
        p2 (complex): Second handle of curve.
        p3 (complex): End point of curve.

    Returns:
        complex: Location of candidate control point on quadratic curve.
    g      ?r   )r?   r   r   r   r   r@   rA   r   r   r   cubic_approx_control   s   rB   )abcdphc                 C   s^   ||  }|| }|d }zt || | t || }W n ty(   ttt Y S w |||  S )ay  Calculate the intersection of two lines.

    Args:
        a (complex): Start point of first line.
        b (complex): End point of first line.
        c (complex): Start point of second line.
        d (complex): End point of second line.

    Returns:
        complex: Location of intersection if one present, ``complex(NaN,NaN)``
        if no intersection was found.
    y              ?)r   ZeroDivisionErrorcomplexNAN)r   r   r   r   rC   rD   rE   rF   r   r   r   calc_intersect   s   rJ   )	tolerancer   r   r   r   c                 C   s   t ||krt ||krdS | d||   | d }t ||kr"dS || | |  d }t| | | d || ||oGt||| || d ||S )a  Check if a cubic Bezier lies within a given distance of the origin.

    "Origin" means *the* origin (0,0), not the start of the curve. Note that no
    checks are made on the start and end positions of the curve; this function
    only checks the inside of the curve.

    Args:
        p0 (complex): Start point of curve.
        p1 (complex): First handle of curve.
        p2 (complex): Second handle of curve.
        p3 (complex): End point of curve.
        tolerance (double): Distance from origin.

    Returns:
        bool: True if the cubic Bezier ``p`` entirely lies within a distance
        ``tolerance`` of the origin, False otherwise.
    Tr    r5   Fr6   )abscubic_farthest_fit_inside)r   r   r   r   rK   r3   r4   r   r   r   rM      s   rM   )rK   _2_3)q1c0r/   c2c3UUUUUU?c                 C   sv   t |  }t|jrdS | d }| d }||| |  }||| |  }td|| d  || d  d|s6dS |||fS )a  Approximate a cubic Bezier with a single quadratic within a given tolerance.

    Args:
        cubic (sequence): Four complex numbers representing control points of
            the cubic Bezier curve.
        tolerance (double): Permitted deviation from the original curve.

    Returns:
        Three complex numbers representing control points of the quadratic
        curve if it fits within the given tolerance, or ``None`` if no suitable
        curve could be calculated.
    Nr   r    r   r   )rJ   mathZisnanimagrM   )cubicrK   rN   rO   rP   rR   r/   rQ   r   r   r   cubic_approx_quadratic  s   


rW   )r'   rK   rN   )r,   )rP   r/   rQ   rR   )q0rO   next_q1q2r0   c                 C   s.  |dkr	t | |S t| d | d | d | d |}t|}tdg|R  }| d }d}| d |g}	td|d D ]U}
|\}}}}|}|}|
|k rdt|}t|
|d  g|R  }|	| || d }n|}|}|| }t||kst|||| |  | ||| |  | ||s dS q8|	| d  |	S )a'  Approximate a cubic Bezier curve with a spline of n quadratics.

    Args:
        cubic (sequence): Four complex numbers representing control points of
            the cubic Bezier curve.
        n (int): Number of quadratic Bezier curves in the spline.
        tolerance (double): Permitted deviation from the original curve.

    Returns:
        A list of ``n+2`` complex numbers, representing control points of the
        quadratic spline if it fits within the given tolerance, or ``None`` if
        no suitable spline could be calculated.
    r   r   r   r    y                r6   N)rW   r(   nextrB   r1   appendrL   rM   )rV   r'   rK   rN   ZcubicsZ
next_cubicrY   rZ   r0   spliner,   rP   r/   rQ   rR   rX   rO   Zd0r   r   r   cubic_approx_spline1  s@   
 
r^   )max_err)r'   c                 C   sP   dd | D } t dtd D ]}t| ||}|dur#dd |D   S qt| )a  Approximate a cubic Bezier curve with a spline of n quadratics.

    Args:
        cubic (sequence): Four 2D tuples representing control points of
            the cubic Bezier curve.
        max_err (double): Permitted deviation from the original curve.

    Returns:
        A list of 2D tuples, representing control points of the quadratic
        spline if it fits within the given tolerance, or ``None`` if no
        suitable spline could be calculated.
    c                 S      g | ]}t | qS r   rH   .0rE   r   r   r   
<listcomp>      z&curve_to_quadratic.<locals>.<listcomp>r   Nc                 S      g | ]}|j |jfqS r   r   rU   rc   sr   r   r   rd         )r1   MAX_Nr^   r   )curver_   r'   r]   r   r   r   r   r  s   )llast_ir,   c                 C   s   dd | D } t |t | ksJ t | }dg| }d }}d}	 t| | ||| }|du r?|tkr8	 t| |d7 }|}q |||< |d | }||krTdd |D S q!)a  Return quadratic Bezier splines approximating the input cubic Beziers.

    Args:
        curves: A sequence of *n* curves, each curve being a sequence of four
            2D tuples.
        max_errors: A sequence of *n* floats representing the maximum permissible
            deviation from each of the cubic Bezier curves.

    Example::

        >>> curves_to_quadratic( [
        ...   [ (50,50), (100,100), (150,100), (200,50) ],
        ...   [ (75,50), (120,100), (150,75),  (200,60) ]
        ... ], [1,1] )
        [[(50.0, 50.0), (75.0, 75.0), (125.0, 91.66666666666666), (175.0, 75.0), (200.0, 50.0)], [(75.0, 50.0), (97.5, 75.0), (135.41666666666666, 82.08333333333333), (175.0, 67.5), (200.0, 60.0)]]

    The returned splines have "implied oncurve points" suitable for use in
    TrueType ``glif`` outlines - i.e. in the first spline returned above,
    the first quadratic segment runs from (50,50) to
    ( (75 + 125)/2 , (120 + 91.666..)/2 ) = (100, 83.333...).

    Returns:
        A list of splines, each spline being a list of 2D tuples.

    Raises:
        fontTools.cu2qu.Errors.ApproxNotFoundError: if no suitable approximation
        can be found for all curves with the given parameters.
    c                 S      g | ]	}d d |D qS )c                 S   r`   r   ra   rb   r   r   r   rd     re   2curves_to_quadratic.<locals>.<listcomp>.<listcomp>r   rc   rl   r   r   r   rd         z'curves_to_quadratic.<locals>.<listcomp>Nr   r   Tc                 S   ro   )c                 S   rf   r   rg   rh   r   r   r   rd     rj   rp   r   )rc   r]   r   r   r   rd     rr   )lenr^   rk   r   )ZcurvesZ
max_errorsrm   Zsplinesrn   r,   r'   r]   r   r   r   r     s(   

__main__   c                   C   s   dd t dD S )Nc                 S   s"   g | ]}t d d tdD qS )c                 s   s     | ]}t td dV  qdS )r   i   N)floatrandomZrandint)rc   Zcoordr   r   r   	<genexpr>  s    z,generate_curve.<locals>.<listcomp>.<genexpr>r   )tupler1   )rc   Zpointr   r   r   rd     s    z"generate_curve.<locals>.<listcomp>r!   )r1   r   r   r   r   generate_curve  s   rz   c                   C   s
   t  tfS N)rz   MAX_ERRr   r   r   r   setup_curve_to_quadratic     
r}   c                  C   s    d} dd t | D tg|  fS )Nr    c                 S   s   g | ]}t  qS r   )rz   rq   r   r   r   rd     s    z-setup_curves_to_quadratic.<locals>.<listcomp>)r1   r|   )Z
num_curvesr   r   r   setup_curves_to_quadratic  s   r      c           	      C   sx   d| }|rt d||f dd |d| 7 }nt d| dd dd }tj|||||d	}t d
t|d |   d S )NZsetup_z%s with %s:r   )end_z%s:c                    s&   t     t    fdd}|S )Nc                      s
      S r{   r   r   function
setup_funcr   r   wrapped  r~   z/run_benchmark.<locals>.wrapper.<locals>.wrapped)globals)r   r   r   r   r   r   wrapper  s   

zrun_benchmark.<locals>.wrapper)repeatnumberz	%5.1fusg    .A)printtimeitr   min)	Zbenchmark_modulemoduler   Zsetup_suffixr   r   r   r   resultsr   r   r   run_benchmark  s   r   c                   C   s   t ddd t ddd d S )Nzcu2qu.benchmarkZcu2qur   r   )r   r   r   r   r   main  s   r   )r<   )rS   )r   ru   r   )-r   ImportErrorZfontTools.miscrT   errorsr   Z
Cu2QuErrorr   __all__rk   rv   rI   ZcompiledZCOMPILEDZcfuncZinlinereturnsZdoublelocalsrH   r   r   r   r(   intr&   r$   r%   rB   rJ   rM   rW   r^   r   r   __name__rw   r   r|   rz   r}   r   r   r   Zseedr   r   r   r   <module>   s   



<

6


