o
    bL                     @  s  d dl mZ d dlmZ d dlmZmZ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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lmZ d dl m!Z!m"Z"m#Z#m$Z$ d dl%m&Z&m'Z'm(Z(m)Z) d dl*m+Z+ d dl,m-Z-m.Z. eG dd dZ/dS )    )annotations)deepcopy)AnyIteratorListMappingOptionalcast)definefield)	Transform)AbstractPen)AbstractPointPenPointToSegmentPenSegmentToPointPen)Anchor)	Component)Contour)	Guideline)Image)Lib_convert_Lib_get_lib_set_lib)BoundingBox_object_lib	getBoundsgetControlBoundsGlyphPointPen)GlyphSetHasIdentifierc                   @  s  e Zd ZU dZdZded< dZded< 	 dZded< 	 ee	d	Z
d
ed< 	 eed	Zded< eeedZded< 	 dZded< 	 ee	d	Zded< ee	d	Zded< 	 ee	d	Zded< 	 ee	d	Zded< dddZdd d!Zdd$d%Zdd'd(Zdd*d+ZeeeZedd-d.Zejdd1d.Zedd3d4Z e jdd5d4Z edd7d8Z!edd:d;Z"e"jdd<d;Z"edd=d>Z#e#jddAd>Z#ddEdFZ$ddGdHZ%ddIdJZ&ddKdLZ'ddMdNZ(ddOdPZ)ddSdTZ*ddWdXZ+dd[d\Z,dd]d^Z-ddd`daZ.ddcddZ/ddgdhZ0ddkdlZ1ddodpZ2ddqdrZ3ddsdtZ4eddudvZ5e5jddwdvZ5eddydzZ6e6jdd{dzZ6ddddZ7ddddZ8ddddZ9ddddZ:ddddZ;ddddZ<ddddZ=ddddZ>ddddZ?ddddZ@dS )Glypha0  Represents a glyph, containing contours, components, anchors and various
    other bits of data concerning it.

    See http://unifiedfontobject.org/versions/ufo3/glyphs/glif/.

    Behavior:
        The Glyph object has list-like behavior. This behavior allows you to interact
        with contour data directly. For example, to get a particular contour::

            contour = glyph[0]

        To iterate over all contours::

            for contour in glyph:
                ...

        To get the number of contours::

            contourCount = len(glyph)

        To check if a :class:`.Contour` object is in glyph::

            exists = contour in glyph

        To interact with components or anchors in a similar way, use the
        :attr:`.Glyph.components` and :attr:`.Glyph.anchors` attributes.
    NzOptional[str]_namer   floatwidthheight)factoryz	List[int]unicodesr   _image)r'   Z	converterr   _libnotezList[Anchor]_anchorszList[Component]
componentszList[Contour]contourszList[Guideline]_guidelinesreturnintc                 C  
   t | jS N)lenr.   self r7   7/usr/lib/python3/dist-packages/ufoLib2/objects/glyph.py__len__U      
zGlyph.__len__indexr   c                 C  s
   | j | S r3   r.   )r6   r;   r7   r7   r8   __getitem__X   r:   zGlyph.__getitem__contourboolc                 C  s
   || j v S r3   r<   r6   r>   r7   r7   r8   __contains__[   r:   zGlyph.__contains__Iterator[Contour]c                 C  r2   r3   )iterr.   r5   r7   r7   r8   __iter__^   r:   zGlyph.__iter__strc                 C  s8   d | jj| jj| jd urd| j dndtt| S )Nz<{}.{} {}at {}>'z'  )format	__class__
__module____name__r#   hexidr5   r7   r7   r8   __repr__a   s   
zGlyph.__repr__list[Anchor]c                 C     | j S )a  The list of anchors the glyph contains.

        Getter:
            Returns a list of anchors the glyph contains. Modifications of the list
            modify the Glyph object.

        Setter:
            Clears current anchors and sets the new ones.
        r,   r5   r7   r7   r8   anchorsk      zGlyph.anchorsvalueNonec                 C      |    |D ]}| | qd S r3   )clearAnchorsappendAnchor)r6   rT   anchorr7   r7   r8   rR   x      list[Guideline]c                 C  rP   )a  The list of guidelines the glyph contains.

        Getter:
            Returns a list of guidelines the glyph contains. Modifications of the list
            modify the Glyph object.

        Setter:
            Clears current guidelines and sets the new ones.
        r/   r5   r7   r7   r8   
guidelines~   rS   zGlyph.guidelinesc                 C  rV   r3   )clearGuidelinesappendGuideline)r6   rT   	guideliner7   r7   r8   r]      rZ   
str | Nonec                 C  rP   )zThe name of the glyph.)r#   r5   r7   r7   r8   name   s   z
Glyph.name
int | Nonec                 C  s   | j r| j d S dS )aY  The first assigned Unicode code point or None.

        See http://unifiedfontobject.org/versions/ufo3/glyphs/glif/#unicode.

        Setter:
            Sets the value to be the first of the assigned Unicode code points. Will
            remove a duplicate if exists. Will clear the list of Unicode points if
            value is None.
        r   N)r(   r5   r7   r7   r8   unicode   s   
zGlyph.unicodec                 C  sp   |d u r	g | _ d S | j r0| j d |krd S z| j | W n	 ty&   Y nw | j d| d S | j | d S )Nr   )r(   remove
ValueErrorinsertappendr6   rT   r7   r7   r8   rd      s   
c                 C  rP   )zThe background image reference associated with the glyph.

        See http://unifiedfontobject.org/versions/ufo3/glyphs/glif/#image.

        Setter:
            Sets the background image reference. Clears it if value is None.
        )r)   r5   r7   r7   r8   image   s   	zGlyph.imagerj    Image | Mapping[str, Any] | Nonec              
   C  sn   |d u r| j   d S t|tr|| _ d S t|d t|d |d |d |d |d |d |dd	| _ d S )
NfileNameZxScaleZxyScaleZyxScaleZyScaleZxOffsetZyOffsetcolor)rl   Ztransformationrm   )r)   clear
isinstancer   r   get)r6   rj   r7   r7   r8   rj      s    

objectr!   dict[str, Any]c                 C  s   t | j|S )a$  Return the lib for an object with an identifier, as stored in a glyph's lib.

        If the object does not yet have an identifier, a new one is assigned to it. If
        the font lib does not yet contain the object's lib, a new one is inserted and
        returned.

        .. doctest::

            >>> from ufoLib2.objects import Font, Guideline
            >>> font = Font()
            >>> glyph = font.newGlyph("a")
            >>> glyph.guidelines = [Guideline(x=100)]
            >>> guideline_lib = glyph.objectLib(glyph.guidelines[0])
            >>> guideline_lib["com.test.foo"] = 1234
            >>> guideline_id = glyph.guidelines[0].identifier
            >>> assert guideline_id is not None
            >>> assert glyph.lib["public.objectLibs"][guideline_id] is guideline_lib
        )r   lib)r6   rq   r7   r7   r8   	objectLib   s   zGlyph.objectLibc                 C  s>   | j dd= | jdd= | jdd= | jdd= | j  dS )zRClears out anchors, components, contours, guidelines and image
        references.N)r,   r-   r.   r/   rj   rn   r5   r7   r7   r8   rn      s
   zGlyph.clearc                 C     | j dd= dS )zClears out anchors.NrQ   r5   r7   r7   r8   rW         zGlyph.clearAnchorsc                 C  ru   )zClears out contours.Nr<   r5   r7   r7   r8   clearContours   rv   zGlyph.clearContoursc                 C  ru   )zClears out components.N)r-   r5   r7   r7   r8   clearComponents   rv   zGlyph.clearComponentsc                 C  ru   )zClears out guidelines.Nr\   r5   r7   r7   r8   r^      rv   zGlyph.clearGuidelines	componentr   c                 C  s   | j | dS )zGRemoves :class:`.Component` object from the glyph's list of components.N)r-   re   )r6   ry   r7   r7   r8   removeComponent  rv   zGlyph.removeComponentrY   Anchor | Mapping[str, Any]c                 C  H   t |tst |tstddt|j tdi |}| j| dS )zAppends an :class:`.Anchor` object to glyph's list of anchors.

        Args:
            anchor: An :class:`.Anchor` object or mapping for the Anchor constructor.
        z,Expected Anchor object or a Mapping for the zAnchor constructor, found Nr7   )ro   r   r   	TypeErrortyperK   rR   rh   )r6   rY   r7   r7   r8   rX     s   

zGlyph.appendAnchorr`   Guideline | Mapping[str, Any]c                 C  r|   )zAppends a :class:`.Guideline` object to glyph's list of guidelines.

        Args:
            guideline: A :class:`.Guideline` object or a mapping for the Guideline
                constructor.
        z/Expected Guideline object or a Mapping for the zGuideline constructor, found Nr7   )ro   r   r   r}   r~   rK   r/   rh   )r6   r`   r7   r7   r8   r_     s   

zGlyph.appendGuidelinec                 C  s.   t |tstdt|j | j| dS )z?Appends a :class:`.Contour` object to glyph's list of contours.zExpected Contour, found N)ro   r   r}   r~   rK   r.   rh   r@   r7   r7   r8   appendContour&  s   
zGlyph.appendContourrb   c                 C  s   t | }|dur||_|S )zPReturns a new Glyph (deep) copy, optionally override the new glyph
        name.N)r   r#   )r6   rb   otherr7   r7   r8   copy,  s   z
Glyph.copyglyphc                 C  sz   |j | _ |j| _t|j| _t|j| _|j| _t|j| _t|j| _t|j	| _	| 
  |   |  }|| dS )zDeep-copies everything from the other glyph into self, except for
        the name.

        Existing glyph data is overwritten.

        |defcon_compat|
        N)r%   r&   listr(   r   rj   r+   rs   rR   r]   rw   rx   getPointPen
drawPoints)r6   r   pointPenr7   r7   r8   copyDataFromGlyph4  s   zGlyph.copyDataFromGlyphdeltatuple[float, float]c                 C  sF   | j D ]}|| q| jD ]}|| q| jD ]}|| qdS )z@Moves all contours, components and anchors by (x, y) font units.N)r.   mover-   rR   )r6   r   r>   ry   rY   r7   r7   r8   r   K  s   


z
Glyph.movepenr   c                 C  s   t |}| | dS )zDraws glyph into given pen.N)r   r   )r6   r   r   r7   r7   r8   drawX  s   z
Glyph.drawr   r   c                 C  s0   | j D ]}|| q| jD ]}|| qdS )z+Draws points of glyph into given point pen.N)r.   r   r-   )r6   r   r>   ry   r7   r7   r8   r   ^  s
   

zGlyph.drawPointsc                 C  s   t |  }|S )z+Returns a pen for others to draw into self.)r   r   )r6   r   r7   r7   r8   getPene  s   zGlyph.getPenc                 C  s   t | }|S )z8Returns a point pen for others to draw points into self.r   )r6   r   r7   r7   r8   r   j  s   zGlyph.getPointPenc                 C     t tt | jdS )a5  The color assigned to the glyph.

        See http://unifiedfontobject.org/versions/ufo3/glyphs/glif/#publicmarkcolor.

        Getter:
            Returns the mark color or None.

        Setter:
            Sets the mark color. If value is None, deletes the key from the lib if
            present.
        public.markColor)r	   r   rE   rs   rp   r5   r7   r7   r8   	markColorq     zGlyph.markColorc                 C  0   |d ur|| j d< d S d| j v r| j d= d S d S )Nr   rs   ri   r7   r7   r8   r     
   
float | Nonec                 C  r   )aE  The vertical origin of the glyph.

        See http://unifiedfontobject.org/versions/ufo3/glyphs/glif/#publicverticalorigin.

        Getter:
            Returns the vertical origin or None.

        Setter:
            Sets the vertical origin. If value is None, deletes the key from the lib if
            present.
        public.verticalOrigin)r	   r   r$   rs   rp   r5   r7   r7   r8   verticalOrigin  r   zGlyph.verticalOriginc                 C  r   )Nr   r   ri   r7   r7   r8   r     r   layerGlyphSet | NoneBoundingBox | Nonec                 C      |du r| j rtdt| |S )a  Returns the (xMin, yMin, xMax, yMax) bounding box of the glyph,
        taking the actual contours into account.

        Args:
            layer: The layer of the glyph to look up components, if any. Not needed for
                pure-contour glyphs.
        N1layer is required to compute bounds of components)r-   r}   r   r6   r   r7   r7   r8   r        
zGlyph.getBoundsc                 C  r   )a	  Returns the (xMin, yMin, xMax, yMax) bounding box of the glyph,
        taking only the control points into account.

        Args:
            layer: The layer of the glyph to look up components, if any. Not needed for
                pure-contour glyphs.
        Nr   )r-   r}   r   r   r7   r7   r8   r     r   zGlyph.getControlBoundsc                 C  s   |  |}|du rdS |jS )zReturns the the space in font units from the point of origin to the
        left side of the glyph.

        Args:
            layer: The layer of the glyph to look up components, if any. Not needed for
                pure-contour glyphs.
        N)r   xMinr6   r   boundsr7   r7   r8   getLeftMargin  s   
zGlyph.getLeftMarginc                 C  sH   |  |}|du rdS ||j }|r"|  j|7  _| |df dS dS )a/  Sets the the space in font units from the point of origin to the
        left side of the glyph.

        Args:
            value: The desired left margin in font units.
            layer: The layer of the glyph to look up components, if any. Not needed for
                pure-contour glyphs.
        Nr   )r   r   r%   r   )r6   rT   r   r   diffr7   r7   r8   setLeftMargin  s   
	
zGlyph.setLeftMarginc                 C  s"   |  |}|du rdS | j|j S )zReturns the the space in font units from the glyph's advance width
        to the right side of the glyph.

        Args:
            layer: The layer of the glyph to look up components, if any. Not needed for
                pure-contour glyphs.
        N)r   r%   xMaxr   r7   r7   r8   getRightMargin  s   
zGlyph.getRightMarginc                 C  s&   |  |}|du rdS |j| | _dS )a7  Sets the the space in font units from the glyph's advance width to
        the right side of the glyph.

        Args:
            value: The desired right margin in font units.
            layer: The layer of the glyph to look up components, if any. Not needed for
                pure-contour glyphs.
        N)r   r   r%   )r6   rT   r   r   r7   r7   r8   setRightMargin  s   
	zGlyph.setRightMarginc                 C  s8   |  |}|du rdS | jdu r|jS |j| j| j  S )zReturns the the space in font units from the bottom of the canvas to
        the bottom of the glyph.

        Args:
            layer: The layer of the glyph to look up components, if any. Not needed for
                pure-contour glyphs.
        Nr   r   ZyMinr&   r   r7   r7   r8   getBottomMargin  s   

zGlyph.getBottomMarginc                 C  sd   |  |}|du rdS | jdu r|j}| j| _n	|j| j| j  }|| }|r0|  j|7  _dS dS )a3  Sets the the space in font units from the bottom of the canvas to
        the bottom of the glyph.

        Args:
            value: The desired bottom margin in font units.
            layer: The layer of the glyph to look up components, if any. Not needed for
                pure-contour glyphs.
        Nr   r6   rT   r   r   ZoldValuer   r7   r7   r8   setBottomMargin  s   
	

zGlyph.setBottomMarginc                 C  s8   |  |}|du rdS | jdu r| j|j S | j|j S )zReturns the the space in font units from the top of the canvas to
        the top of the glyph.

        Args:
            layer: The layer of the glyph to look up components, if any. Not needed for
                pure-contour glyphs.
        Nr   r   r&   ZyMaxr   r7   r7   r8   getTopMargin  s   

zGlyph.getTopMarginc                 C  sl   |  |}|du rdS | jdu r| j|j }n| j|j }|| }||kr4|j| | _|  j|7  _dS dS )a*  Sets the the space in font units from the top of the canvas to the
        top of the glyph.

        Args:
            value: The desired top margin in font units.
            layer: The layer of the glyph to look up components, if any. Not needed for
                pure-contour glyphs.
        Nr   r   r7   r7   r8   setTopMargin(  s   
	
zGlyph.setTopMargin)r0   r1   )r;   r1   r0   r   )r>   r   r0   r?   )r0   rB   )r0   rE   )r0   rO   )rT   rO   r0   rU   )r0   r[   )rT   r[   r0   rU   )r0   ra   )r0   rc   )rT   rc   r0   rU   )r0   r   )rj   rk   r0   rU   )rq   r!   r0   rr   )r0   rU   )ry   r   r0   rU   )rY   r{   r0   rU   )r`   r   r0   rU   )r>   r   r0   rU   r3   )rb   ra   r0   r"   )r   r"   r0   rU   )r   r   r0   rU   )r   r   r0   rU   )r   r   r0   rU   )r0   r   )r0   r   )rT   ra   r0   rU   )r0   r   )rT   r   r0   rU   )r   r   r0   r   )r   r   r0   r   )rT   r$   r   r   r0   rU   )ArK   rJ   __qualname____doc__r#   __annotations__r%   r&   r   r   r(   r   r)   r   r   r*   r+   r,   r-   r.   r/   r9   r=   rA   rD   rN   propertyr   r   rs   rR   setterr]   rb   rd   rj   rt   rn   rW   rw   rx   r^   rz   rX   r_   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r7   r7   r7   r8   r"      s   
 









	












r"   N)0Z
__future__r   r   r   typingr   r   r   r   r   r	   attrr
   r   ZfontTools.misc.transformr   ZfontTools.pens.basePenr   ZfontTools.pens.pointPenr   r   r   ZufoLib2.objects.anchorr   ZufoLib2.objects.componentr   ZufoLib2.objects.contourr   ZufoLib2.objects.guideliner   ZufoLib2.objects.imager   ZufoLib2.objects.libr   r   r   r   ZufoLib2.objects.miscr   r   r   r   ZufoLib2.pointPens.glyphPointPenr   ZufoLib2.typingr    r!   r"   r7   r7   r7   r8   <module>   s$     