a
    
d-                     @   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dZd"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   \/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/fontTools/cu2qu/ufo.py	<genexpr><       zzip.<locals>.<genexpr>r   )r   setr   list_zip)argsr   r   r   zip7   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__H   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_segmentL   s    
zGetSegmentsPen._add_segmentc                 C   s   |  d| d S )Nr"   r)   r    ptr   r   r   moveToQ   s    zGetSegmentsPen.moveToc                 C   s   |  d| d S )Nr#   r*   r+   r   r   r   lineToT   s    zGetSegmentsPen.lineToc                 G   s   | j d| jg|R   d S )Nr$   r)   r   r    Zpointsr   r   r   qCurveToW   s    zGetSegmentsPen.qCurveToc                 G   s   | j d| jg|R   d S )Nr%   r/   r0   r   r   r   curveToZ   s    zGetSegmentsPen.curveToc                 C   s   |  d d S )Ncloser*   r   r   r   r   	closePath]   s    zGetSegmentsPen.closePathc                 C   s   |  d d S )Nendr*   r   r   r   r   endPath`   s    zGetSegmentsPen.endPathc                 C   s   d S r   r   )r    Z	glyphNameZtransformationr   r   r   addComponentc   s    zGetSegmentsPen.addComponentN)__name__
__module____qualname____doc__r!   r)   r-   r.   r1   r2   r4   r6   r7   r   r   r   r   r   A   s   r   c                 C   s"   t  }t|dd}| | |jS )z6Get a glyph's segments as extracted by GetSegmentsPen.T)ZoutputImpliedClosingLine)r   r   Z
drawPointsr   )glyphpenZpointPenr   r   r   _get_segmentsg   s    
r>   c                 C   s   |    |  }|rt|}|D ]\}}|dkr<|j|  q |dkrP|j|  q |dkrl|j|dd   q |dkr|j|dd   q |dkr|  q |dkr|  q t	d	| q dS )
z=Draw segments as extracted by GetSegmentsPen back to a glyph.r"   r#   r%   r   Nr$   r3   r5   zUnhandled segment type "%s")
ZclearContoursZgetPenr   r-   r.   r2   r1   r4   r6   AssertionError)r<   r   reverse_directionr=   r(   r   r   r   r   _set_segmentsz   s$    

rA   Tc                    s   t dd | D sJ dtdd | D ||}t|d  t  fdd|dd	 D sbJ d
t d }||dd ||< |s dkrdd |D S dd |D S 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      r   z)_segments_to_quadratic.<locals>.<genexpr>zNon-cubic given to convertc                 S   s   g | ]}|d  qS )r   r   rB   r   r   r   
<listcomp>   r   z*_segments_to_quadratic.<locals>.<listcomp>r   c                 3   s   | ]}t | kV  qd S r   r   rB   nr   r   r      r   r   NzConverted incompatibly      c                 S   s   g | ]}d |fqS )r$   r   r   pr   r   r   rD      r   c                 S   s   g | ]}d |fqS )r%   r   rI   r   r   r   rD      r   )allr   r   strget)r   max_errstatsall_quadraticZ
new_pointsZspline_lengthr   rE   r   _segments_to_quadratic   s    &rQ   c                    s  zt dd | D  }W n ty0   t| Y n0 t|s>dS |}g }i }t|D ]z\}	}
|
d d  t fdd|
dd D sd	d |
D ||	< n* d
krt|
|||}|s||
krd}|}
||
 qR|rt | }t | |D ]\}}t||| q|rt	| |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   )r>   )r   gr   r   r   rD      r   z(_glyphs_to_quadratic.<locals>.<listcomp>Fr   c                 3   s   | ]}|d   kV  qdS )r   Nr   rB   r(   r   r   r      r   z'_glyphs_to_quadratic.<locals>.<genexpr>r   Nc                 S   s   g | ]}|d  qS )r   r   rB   r   r   r   rD      r   r%   T)r   )
r   r   r   any	enumeraterK   rQ   r'   rA   r	   )glyphsrN   r@   rO   rP   Zsegments_by_locationZglyphs_modifiedZnew_segments_by_locationZincompatibleir   Znew_segmentsZnew_segments_by_glyphr<   r   rS   r   _glyphs_to_quadratic   s8    rX   Fc                 C   s^   |du ri }|st d }t|ttfr,|}n|gt|  }t|t| ksNJ 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   rX   )rV   rN   r@   rO   rP   
max_errorsr   r   r   glyphs_to_quadratic   s    
r]   c                    sh  |rjdd | D }t |dkrTtt|}	|	dv r@td dS |	dkrJqjt|	nt |dkrjtd d	u rvi  r|rtd
 s|st t	|t
tfrt |t | ksJ |}
n|r|gt |  }
t	 t
tfrt | t  ksJ dd t|  D }
n r fdd| D }
d}i }t jdd | D  D ]}g }g }t| |
D ],\}}||v rR|||  || qRz|t||||O }W n8 ty } zt| |||< W Y d	}~n
d	}~0 0 q<|rt||r|rt }tddfdd|D   |rd| D ]:}|jtd}	|rDdnd}|	|kr(||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)librM   CURVE_TYPE_LIB_KEYr   fr   r   r   	<setcomp>	  r   z%fonts_to_quadratic.<locals>.<setcomp>r   )	quadraticmixedz%Curves already converted to quadraticFr^   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   infoZ
unitsPerEm)r   rb   er   r   r   rD   '  r   z&fonts_to_quadratic.<locals>.<listcomp>c                    s   g | ]}|j j  qS r   rf   ra   )
max_err_emr   r   rD   )  r   c                 s   s   | ]}|  V  qd S r   )keysra   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)rO   r   r   r   C  r   rd   re   T)r   nextiterloggerrg   NotImplementedErrorwarning	TypeErrorrY   rZ   r   r[   r   r   unionr'   rX   r
   errorr   sortedrj   joinr_   rM   r`   )Zfontsri   rN   r@   rO   Z
dump_statsZremember_curve_typerP   Zcurve_typesZ
curve_typer\   modifiedZglyph_errorsnamerV   Zcur_max_errorsfontrs   excZspline_lengthsZnew_curve_typer   )ri   rO   r   r      sz    






"

c                 K   s   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.
    )r]   )r<   kwargsr   r   r   glyph_to_quadraticP  s    r{   c                 K   s   t | gfi |S )zConvenience wrapper around fonts_to_quadratic, for just one font.
    Return True if the font was modified, else return False.
    )r   )rx   rz   r   r   r   r   X  s    )T)T)NFNT)NNFNFTT)!r;   loggingZfontTools.pens.basePenr   ZfontTools.pens.pointPenr   Z fontTools.pens.reverseContourPenr    r   errorsr   r   r	   r
   r   __all__rY   r`   	getLoggerr8   rn   r   r   r   r>   rA   rQ   rX   r]   r   r{   r   r   r   r   r   <module>   s:   
	

&

+ 
!       
c