o
    tBh,                     @   s   d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZmZmZmZmZ d	d
gZdZdZeeZeZdd ZG dd deZdd Zdd Zdd Zdd Z	d!ddZ		d"dd	Zdd Zd d
 Z dS )#a  Converts cubic bezier curves to quadratic splines.

Conversion is performed such that the quadratic splines keep the same end-curve
tangents as the original cubics. The approach is iterative, increasing the
number of segments for a spline until the error gets below a bound.

Respective curves from multiple fonts will be converted at once to ensure that
the resulting splines are interpolation-compatible.
    N)AbstractPen)PointToSegmentPen)ReverseContourPen   )curves_to_quadratic)UnequalZipLengthsErrorIncompatibleSegmentNumberErrorIncompatibleSegmentTypesErrorIncompatibleGlyphsErrorIncompatibleFontsErrorfonts_to_quadraticfont_to_quadraticgMbP?z&com.github.googlei18n.cu2qu.curve_typec                  G   s.   t tdd | D dkrt|  tt|  S )zyEnsure each argument to zip has the same length. Also make sure a list is
    returned for python 2/3 compatibility.
    c                 s   s    | ]}t |V  qd S Nlen).0a r   j/var/www/html/riverr-enterprise-integrations-main/venv/lib/python3.10/site-packages/fontTools/cu2qu/ufo.py	<genexpr>7       zzip.<locals>.<genexpr>r   )r   setr   list_zip)argsr   r   r   zip2   s   r   c                   @   sX   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd ZdS )GetSegmentsPenzPen to collect segments into lists of points for conversion.

    Curves always include their initial on-curve point, so some points are
    duplicated between segments.
    c                 C   s   d | _ g | _d S r   )_last_ptsegmentsselfr   r   r   __init__C   s   
zGetSegmentsPen.__init__c                 G   s&   |dv r	|d | _ | j||f d S )N)movelineqcurvecurve)r   r   append)r    tagr   r   r   r   _add_segmentG   s   
zGetSegmentsPen._add_segmentc                 C      |  d| d S )Nr"   r)   r    ptr   r   r   moveToL      zGetSegmentsPen.moveToc                 C   r*   )Nr#   r+   r,   r   r   r   lineToO   r/   zGetSegmentsPen.lineToc                 G      | j d| jg|R   d S )Nr$   r)   r   r    pointsr   r   r   qCurveToR      zGetSegmentsPen.qCurveToc                 G   r1   )Nr%   r2   r3   r   r   r   curveToU   r6   zGetSegmentsPen.curveToc                 C      |  d d S )Ncloser+   r   r   r   r   	closePathX      zGetSegmentsPen.closePathc                 C   r8   )Nendr+   r   r   r   r   endPath[   r;   zGetSegmentsPen.endPathc                 C   s   d S r   r   )r    	glyphNametransformationr   r   r   addComponent^   s   zGetSegmentsPen.addComponentN)__name__
__module____qualname____doc__r!   r)   r.   r0   r5   r7   r:   r=   r@   r   r   r   r   r   <   s    r   c                 C   s"   t  }t|dd}| | |jS )z6Get a glyph's segments as extracted by GetSegmentsPen.T)outputImpliedClosingLine)r   r   
drawPointsr   )glyphpenpointPenr   r   r   _get_segmentsb   s   
rJ   c                 C   s   |    |  }|rt|}|D ]K\}}|dkr|j|  q|dkr(|j|  q|dkr6|j|dd   q|dkrD|j|dd   q|dkrM|  q|dkrV|  qt	d	| dS )
z=Draw segments as extracted by GetSegmentsPen back to a glyph.r"   r#   r%   r   Nr$   r9   r<   zUnhandled segment type "%s")
clearContoursgetPenr   r.   r0   r7   r5   r:   r=   AssertionError)rG   r   reverse_directionrH   r(   r   r   r   r   _set_segmentsu   s&   

rO   c                    s   t dd | D sJ dtdd | D |}t|d  t  fdd|dd	 D s0J d
t d }||dd ||< dd |D S )z2Return quadratic approximations of cubic segments.c                 s   s    | ]	}|d  dkV  qdS )r   r%   Nr   r   sr   r   r   r          z)_segments_to_quadratic.<locals>.<genexpr>zNon-cubic given to convertc                 S      g | ]}|d  qS )r   r   rP   r   r   r   
<listcomp>       z*_segments_to_quadratic.<locals>.<listcomp>r   c                 3   s    | ]	}t | kV  qd S r   r   rP   nr   r   r      rR   r   NzConverted incompatibly   c                 S   s   g | ]}d |fqS )r$   r   )r   pr   r   r   rT      rU   )allr   r   strget)r   max_errstats
new_pointsspline_lengthr   rV   r   _segments_to_quadratic   s   &ra   c                    s   zt dd | D  }W n ty   t| w t|sdS |}g }i }t|D ]4\}}	|	d d  t fdd|	dd D sJd	d |	D ||< n d
krVt|	||}	d}||	 q'|rrt | }
t | |
D ]
\}}t||| qg|rzt	| |d|S )zDo the actual conversion of a set of compatible glyphs, after arguments
    have been set up.

    Return True if the glyphs were modified, else return False.
    c                 S   s   g | ]}t |qS r   )rJ   )r   gr   r   r   rT      rU   z(_glyphs_to_quadratic.<locals>.<listcomp>Fr   c                 3   s    | ]	}|d   kV  qdS )r   Nr   rP   r(   r   r   r      rR   z'_glyphs_to_quadratic.<locals>.<genexpr>r   Nc                 S   rS   )r   r   rP   r   r   r   rT      rU   r%   T)r   )
r   r   r   any	enumeraterZ   ra   r'   rO   r	   )glyphsr]   rN   r^   segments_by_locationglyphs_modifiednew_segments_by_locationincompatibleir   new_segments_by_glyphrG   new_segmentsr   rc   r   _glyphs_to_quadratic   s2   rn   Fc                 C   s\   |du ri }|st d }t|ttfr|}n|gt|  }t|t| ks'J t| |||S )a  Convert the curves of a set of compatible of glyphs to quadratic.

    All curves will be converted to quadratic at once, ensuring interpolation
    compatibility. If this is not required, calling glyphs_to_quadratic with one
    glyph at a time may yield slightly more optimized results.

    Return True if glyphs were modified, else return False.

    Raises IncompatibleGlyphsError if glyphs have non-interpolatable outlines.
    Ni  )DEFAULT_MAX_ERR
isinstancer   tupler   rn   )rf   r]   rN   r^   
max_errorsr   r   r   glyphs_to_quadratic   s   rs   Tc                    sF  |r4dd | D }t |dkr)tt|}|dkr td dS |dkr%nt|t |dkr4td d	u r:i  rB|rBtd
 sH|sHt t	|t
tfr\t |t | ksYJ |}	n	|re|gt |  }	t	 t
tfrt | t  ksvJ dd t|  D }	n r fdd| D }	d}
i }t jdd | D  D ]F}g }g }t| |	D ]\}}||v r|||  || qz|
t|||O }
W q ty } zt| |||< W Y d	}~qd	}~ww |rt||
r|rt }tddfdd|D   |r!| D ]}|jtd}|dkrd|jt< d}
q
|
S )a  Convert the curves of a collection of fonts to quadratic.

    All curves will be converted to quadratic at once, ensuring interpolation
    compatibility. If this is not required, calling fonts_to_quadratic with one
    font at a time may yield slightly more optimized results.

    Return True if fonts were modified, else return False.

    By default, cu2qu stores the curve type in the fonts' lib, under a private
    key "com.github.googlei18n.cu2qu.curve_type", and will not try to convert
    them again if the curve type is already set to "quadratic".
    Setting 'remember_curve_type' to False disables this optimization.

    Raises IncompatibleFontsError if same-named glyphs from different fonts
    have non-interpolatable outlines.
    c                 S   s   h | ]	}|j td qS )cubic)libr\   CURVE_TYPE_LIB_KEYr   fr   r   r   	<setcomp>   s    z%fonts_to_quadratic.<locals>.<setcomp>r   	quadraticz%Curves already converted to quadraticFrt   z'fonts may contain different curve typesNz4Only one of max_err and max_err_em can be specified.c                 S   s   g | ]
\}}|j j| qS r   info
unitsPerEm)r   rx   er   r   r   rT     s    z&fonts_to_quadratic.<locals>.<listcomp>c                    s   g | ]}|j j  qS r   r{   rw   )
max_err_emr   r   rT     s    c                 s   s    | ]}|  V  qd S r   )keysrw   r   r   r   r     r   z%fonts_to_quadratic.<locals>.<genexpr>zNew spline lengths: %sz, c                 3   s     | ]}d | | f V  qdS )z%s: %dNr   )r   l)r^   r   r   r   +  s    
T)r   nextiterloggerr|   NotImplementedErrorwarning	TypeErrorro   rp   r   rq   r   r   unionr'   rn   r
   errorr   sortedr   joinru   r\   rv   )fontsr   r]   rN   r^   
dump_statsremember_curve_typecurve_types
curve_typerr   modifiedglyph_errorsnamerf   cur_max_errorsfontr   excspline_lengthsr   )r   r^   r   r      s   






c                 K      t | gfi |S )zConvenience wrapper around glyphs_to_quadratic, for just one glyph.
    Return True if the glyph was modified, else return False.
    )rs   )rG   kwargsr   r   r   glyph_to_quadratic7     r   c                 K   r   )zConvenience wrapper around fonts_to_quadratic, for just one font.
    Return True if the font was modified, else return False.
    )r   )r   r   r   r   r   r   ?  r   )NFN)NNFNFT)!rD   loggingfontTools.pens.basePenr   fontTools.pens.pointPenr    fontTools.pens.reverseContourPenr    r   errorsr   r   r	   r
   r   __all__ro   rv   	getLoggerrA   r   r   r   r   rJ   rO   ra   rn   rs   r   r   r   r   r   r   r   <module>   s2   


&'

Y