o
    a'                     @   s   d dl m Z  d dlmZmZmZmZ d dlmZmZ d dl	m
Z
 d dlmZ d dlmZ d dlmZmZ d dlmZmZ d d	lmZ d d
lmZ d dlmZ d dlmZ ddgZG dd dZG dd deeZG dd dee
eZdS )    )array)AnyDictOptionalTuple)MAX_F2DOT14floatToFixedToFloat)LogMixin)AbstractPointPenotRound)
LoggingPenPenError)TransformPenTransformPointPen)	ttProgram)Glyph)GlyphComponent)GlyphCoordinates
TTGlyphPenTTGlyphPointPenc                   @   s   e Zd Z	ddeeeef  deddfddZded	e	e
e
e
e
e
e
f fd
dZdd ZdddZ	dded	e	e
e
e
e
e
e
f dee deddf
ddZdd ZddedefddZdS )_TTGlyphBasePenTglyphSethandleOverflowingTransformsreturnNc                 C   s   || _ || _|   dS )a  
        Construct a new pen.

        Args:
            glyphSet (Dict[str, Any]): A glyphset object, used to resolve components.
            handleOverflowingTransforms (bool): See below.

        If ``handleOverflowingTransforms`` is True, the components' transform values
        are checked that they don't overflow the limits of a F2Dot14 number:
        -2.0 <= v < +2.0. If any transform value exceeds these, the composite
        glyph is decomposed.

        An exception to this rule is done for values that are very close to +2.0
        (both for consistency with the -2.0 case, and for the relative frequency
        these occur in real fonts). When almost +2.0 values occur (and all other
        values are within the range -2.0 <= x <= +2.0), they are clamped to the
        maximum positive value that can still be encoded as an F2Dot14: i.e.
        1.99993896484375.

        If False, no check is done and all components are translated unmodified
        into the glyf table, followed by an inevitable ``struct.error`` once an
        attempt is made to compile them.

        If both contours and components are present in a glyph, the components
        are decomposed.
        N)r   r   init)selfr   r    r   ;/usr/lib/python3/dist-packages/fontTools/pens/ttGlyphPen.py__init__   s   z_TTGlyphBasePen.__init__	glyphNametransformationc                 C   s&   |  | |}t| j| | j| d S N)transformPengetattrr   
drawMethod)r   r    r!   Ztpenr   r   r   
_decompose6   s   z_TTGlyphBasePen._decomposec                 C      t )z6
        Check if the current path is closed.
        NotImplementedErrorr   r   r   r   	_isClosed>   s   z_TTGlyphBasePen._isClosedc                 C   s   g | _ g | _g | _g | _d S r"   )pointsendPtstypes
componentsr*   r   r   r   r   D   s   
z_TTGlyphBasePen.initbaseGlyphName
identifierkwargsc                 K   s   | j ||f dS )z"
        Add a sub glyph.
        N)r/   append)r   r0   r!   r1   r2   r   r   r   addComponentJ   s   
z_TTGlyphBasePen.addComponentc                 C   s  | j rtdd | jD }g }| jD ]s\}}|| jvr&| jd| d q| js.| j r5|r5| || qt }||_	dd |dd  D \|_
|_tdd |d d D }|dkr}| j rptd	d |D rptd
d |D }|d d |dd  f|_||_|| q|S )Nc                 s   s6    | ]\}}|d d D ]}|dkp|dk V  qqd S )N      r   ).0r    r!   sr   r   r   	<genexpr>Z   s    
z3_TTGlyphBasePen._buildComponents.<locals>.<genexpr>z skipped non-existing component ''c                 s   s    | ]}t |V  qd S r"   r   r8   vr   r   r   r:   k   s    r5   c                 s   s    | ]}t |d V  qdS )   N)r   r<   r   r   r   r:   n   s    

)   r   r   r?   c                 s   s(    | ]}t |  k od kn  V  qdS r6   Nr   r8   r9   r   r   r   r:   r   s    
c                 s   s0    | ]}t |  k rd krn nt n|V  qdS r@   rA   rB   r   r   r   r:   v   s
    
r6   )r   anyr/   r   logZwarningr,   r&   r   r    xytupleZ	transformflagsr3   )r   componentFlagsZoverflowingr/   r    r!   Z	componentr   r   r   _buildComponentsV   s:   

z _TTGlyphBasePen._buildComponentsr5   rI   c                 C   s   |   std| |}t }t| j|_|j  | j|_	t
d| j|_|   |r4||_d|_|S t|j	|_t |_|jd |S )zW
        Returns a :py:class:`~._g_l_y_f.Glyph` object representing the glyph.
        zDidn't close last contour.B    )r+   r   rJ   r   r   r,   ZcoordinatesZtoIntr-   ZendPtsOfContoursr   r.   rH   r   r/   ZnumberOfContourslenr   ZProgramZprogramZfromBytecode)r   rI   r/   glyphr   r   r   rO      s"   


z_TTGlyphBasePen.glyph)Tr   Nr"   )r5   )__name__
__module____qualname__r   r   strr   boolr   r   floatr&   r+   r   r4   rJ   intr   rO   r   r   r   r   r      s<    
#



)r   c                   @   s   e Zd ZdZdZeZdeeef de	ddfddZ
dd	d
ZdefddZdeeef ddfddZdeeef ddfddZdddZdddZdddZdddZdS )r   a  
    Pen used for drawing to a TrueType glyph.

    This pen can be used to construct or modify glyphs in a TrueType format
    font. After using the pen to draw, use the ``.glyph()`` method to retrieve
    a :py:class:`~._g_l_y_f.Glyph` object representing the glyph.
    ZdrawptonCurver   Nc                 C   s   | j | | j| d S r"   )r,   r3   r.   )r   rX   rY   r   r   r   	_addPoint   s   zTTGlyphPen._addPointc                 C   s   | j   | j  d S r"   )r,   popr.   r*   r   r   r   	_popPoint   s   
zTTGlyphPen._popPointc                 C   s&   | j  p| jo| jd t| j d kS )NrL   r?   )r,   r-   rN   r*   r   r   r   r+      s   zTTGlyphPen._isClosedc                 C   s   |  |d d S )Nr?   )rZ   r   rX   r   r   r   lineTo   s   zTTGlyphPen.lineToc                 C   s    |   std| |d d S )Nz+"move"-type point must begin a new contour.r?   )r+   r   rZ   r]   r   r   r   moveTo   s   zTTGlyphPen.moveToc                 G   r'   r"   r(   )r   r,   r   r   r   curveTo   s   zTTGlyphPen.curveToc                 G   sR   t |dksJ |d d D ]}| |d q|d d ur'| |d d d S d S )Nr?   rL   r   )rN   rZ   )r   r,   rX   r   r   r   qCurveTo   s   zTTGlyphPen.qCurveToc                 C   s   t | jd }|dks| jr|| jd d kr|   d S d}| jr)| jd d }| j| | j| kr;|   |d8 }| j| d S )Nr?   r   rL   )rN   r,   r-   r\   r3   )r   ZendPtZstartPtr   r   r   	closePath   s    zTTGlyphPen.closePathc                 C   s   |    d S r"   )rb   r*   r   r   r   endPath   s   zTTGlyphPen.endPathrP   )rQ   rR   rS   __doc__r%   r   r#   r   rV   rW   rZ   r\   rU   r+   r^   r_   r`   ra   rb   rc   r   r   r   r   r      s    



	c                       s   e Zd ZdZdZeZd fddZdefddZ	dd	e
e d
eddfddZdddZ				ddeeef de
e dede
e d	e
e d
eddfddZ  ZS )r   a  
    Point pen used for drawing to a TrueType glyph.

    This pen can be used to construct or modify glyphs in a TrueType format
    font. After using the pen to draw, use the ``.glyph()`` method to retrieve
    a :py:class:`~._g_l_y_f.Glyph` object representing the glyph.
    Z
drawPointsr   Nc                    s   t    d | _d S r"   )superr   _currentContourStartIndexr*   	__class__r   r   r      s   

zTTGlyphPointPen.initc                 C   s
   | j d u S r"   )rf   r*   r   r   r   r+      s   
zTTGlyphPointPen._isClosedr1   r2   c                 K   s    |   stdt| j| _dS )z'
        Start a new sub path.
        zDidn't close previous contour.N)r+   r   rN   r,   rf   )r   r1   r2   r   r   r   	beginPath   s   zTTGlyphPointPen.beginPathc                 C   sH   |   rtd| jt| jkrtd| jt| jd  d| _dS )z+
        End the current sub path.
        zContour is already closed.zTried to end an empty contour.r?   N)r+   r   rf   rN   r,   r-   r3   r*   r   r   r   rc      s   
zTTGlyphPointPen.endPathFrX   segmentTypesmoothnamec                 K   sd   |   rtd|du r| jd n|dv r| jd n|dkr&tdt|| j| dS )z6
        Add a point to the current sub path.
        z&Can't add a point to a closed contour.Nr   )Zqcurvelinemover?   Zcurvezcubic curves are not supported)r+   r   r.   r3   r)   AssertionErrorr,   )r   rX   rj   rk   rl   r1   r2   r   r   r   addPoint  s   zTTGlyphPointPen.addPointrP   r"   )NFNN)rQ   rR   rS   rd   r%   r   r#   r   rU   r+   r   rT   r   ri   rc   r   rV   rp   __classcell__r   r   rg   r   r      s6    

N)r   typingr   r   r   r   ZfontTools.misc.fixedToolsr   r   ZfontTools.misc.loggingToolsr	   ZfontTools.pens.pointPenr
   ZfontTools.misc.roundToolsr   ZfontTools.pens.basePenr   r   ZfontTools.pens.transformPenr   r   ZfontTools.ttLib.tablesr   ZfontTools.ttLib.tables._g_l_y_fr   r   r   __all__r   r   r   r   r   r   r   <module>   s"     
D