
     #eM                    <   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$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/ d dl0m1Z1m2Z2 e/e G d d                    Z3y)    )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_get_tempLib_set_lib_set_tempLib)BoundingBox_object_lib	getBoundsgetControlBoundsGlyphPointPen)serde)GlyphSetHasIdentifierc                     e Zd ZU dZdZded<   dZded<   	 dZded<   	  ee		      Z
d
ed<   	  ee	      Zded<    eee      Zded<   	 dZded<   	  ee		      Zded<    ee		      Zded<   	  ee		      Zded<   	  ee		      Zded<    eee      Zded<   	 dHdZdIdZdJdZdKdZdLdZ eee      Z eee       Z!edMd        Z"e"jF                  dNd!       Z"edOd"       Z$e$jF                  dPd#       Z$edQd$       Z%edRd%       Z&e&jF                  dSd&       Z&edTd'       Z'e'jF                  dUd(       Z'dVd)Z(dWd*Z)dWd+Z*dWd,Z+dWd-Z,dWd.Z-dXd/Z.dYd0Z/dZd1Z0d[d2Z1d\d]d3Z2d^d4Z3d_d5Z4d`d6Z5dad7Z6dbd8Z7dcd9Z8edQd:       Z9e9jF                  ddd;       Z9eded<       Z:e:jF                  dfd=       Z:d\dgd>Z;d\dgd?Z<d\dhd@Z=d\didAZ>d\dhdBZ?d\didCZ@d\dhdDZAd\didEZBd\dhdFZCd\didGZDy)j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,   	converterr   _libnotezList[Anchor]_anchorszList[Component]
componentszList[Contour]contourszList[Guideline]_guidelines_tempLibc                ,    t        | j                        S N)lenr4   selfs    7/usr/lib/python3/dist-packages/ufoLib2/objects/glyph.py__len__zGlyph.__len__a   s    4==!!    c                     | j                   |   S r8   r4   )r;   indexs     r<   __getitem__zGlyph.__getitem__d   s    }}U##r>   c                    || j                   v S r8   r@   r;   contours     r<   __contains__zGlyph.__contains__g   s    $--''r>   c                ,    t        | j                        S r8   )iterr4   r:   s    r<   __iter__zGlyph.__iter__j   s    DMM""r>   c           
         dj                  | j                  j                  | j                  j                  | j                  d| j                   dndt        t        |                   S )Nz<{}.{} {}at {}>'z'  )format	__class__
__module____name__r(   hexidr:   s    r<   __repr__zGlyph.__repr__m   sU     ''NN%%NN##"&**"8a

|2b4M	
 	
r>   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.
        r2   r:   s    r<   anchorszGlyph.anchorsy   s     }}r>   c                T    | j                          |D ]  }| j                  |        y r8   )clearAnchorsappendAnchor)r;   valueanchors      r<   rV   zGlyph.anchors   s+     	&Ff%	&r>   c                    | j                   S )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.
        r5   r:   s    r<   
guidelineszGlyph.guidelines   s     r>   c                T    | j                          |D ]  }| j                  |        y r8   )clearGuidelinesappendGuideline)r;   rZ   	guidelines      r<   r^   zGlyph.guidelines   s+     	,I  +	,r>   c                    | j                   S )zThe name of the glyph.)r(   r:   s    r<   namez
Glyph.name   s     zzr>   c                :    | j                   r| j                   d   S y)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-   r:   s    r<   unicodezGlyph.unicode   s     ====##r>   c                   |g | _         y | j                   rL| j                   d   |k(  ry 	 | j                   j                  |       | j                   j                  d|       y | j                   j	                  |       y # t        $ r Y Dw xY w)Nr   )r-   remove
ValueErrorinsertappendr;   rZ   s     r<   rf   zGlyph.unicode   s|    =DM}}==#u,MM((/ $$Q.$$U+	 " s   A? ?	B
Bc                    | j                   S )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.   r:   s    r<   imagezGlyph.image   s     {{r>   c                    || j                   j                          y t        |t              r|| _         y t        |d   t	        |d   |d   |d   |d   |d   |d         |j                  d      	      | _         y )
NfileNamexScalexyScaleyxScaleyScalexOffsetyOffsetcolor)rp   transformationrw   )r.   clear
isinstancer   r   get)r;   rn   s     r<   rn   zGlyph.image   s    =KKu%DKz*((O)$)$(O)$)$  ii(DKr>   c                .    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)r;   objects     r<   	objectLibzGlyph.objectLib   s    ( 488V,,r>   c                    | j                   dd= | j                  dd= | j                  dd= | j                  dd= | j                  j                          y)zRClears out anchors, components, contours, guidelines and image
        references.N)r2   r3   r4   r5   rn   ry   r:   s    r<   ry   zGlyph.clear   sF     MM!OOAMM!Q

r>   c                "    | j                   dd= y)zClears out anchors.NrU   r:   s    r<   rX   zGlyph.clearAnchors      MM!r>   c                "    | j                   dd= y)zClears out contours.Nr@   r:   s    r<   clearContourszGlyph.clearContours  r   r>   c                "    | j                   dd= y)zClears out components.N)r3   r:   s    r<   clearComponentszGlyph.clearComponents	  s    OOAr>   c                "    | j                   dd= y)zClears out guidelines.Nr]   r:   s    r<   r`   zGlyph.clearGuidelines  s    Qr>   c                :    | j                   j                  |       y)zGRemoves :class:`.Component` object from the glyph's list of components.N)r3   rh   )r;   	components     r<   removeComponentzGlyph.removeComponent  s    y)r>   c                    t        |t              s=t        |t              s"t        ddt	        |      j
                         t        di |}| j                  j                  |       y)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 N )rz   r   r   	TypeErrortyperP   rV   rk   )r;   r[   s     r<   rY   zGlyph.appendAnchor  s^     &&)fg.B0f1F1F0GH  %f%FF#r>   c                    t        |t              s=t        |t              s"t        ddt	        |      j
                         t        di |}| j                  j                  |       y)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 Nr   )rz   r   r   r   r   rP   r5   rk   )r;   rb   s     r<   ra   zGlyph.appendGuideline$  s`     )Y/i1E3DO4L4L3MN  ".I.I	*r>   c                    t        |t              s!t        dt        |      j                         | j
                  j                  |       y)z?Appends a :class:`.Contour` object to glyph's list of contours.zExpected Contour, found N)rz   r   r   r   rP   r4   rk   rD   s     r<   appendContourzGlyph.appendContour4  s<    '7+6tG}7M7M6NOPPW%r>   c                .    t        |       }|||_        |S )zPReturns a new Glyph (deep) copy, optionally override the new glyph
        name.)r   r(   )r;   rd   others      r<   copyz
Glyph.copy:  s     EKr>   c                   |j                   | _         |j                  | _        t        |j                        | _        t	        |j
                        | _        |j                  | _        t	        |j                        | _        t	        |j                        | _        t	        |j                        | _	        | j                          | j                          | j                         }|j                  |       y)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   rn   r1   r}   rV   r^   r   r   getPointPen
drawPoints)r;   glyphpointPens      r<   copyDataFromGlyphzGlyph.copyDataFromGlyphB  s     [[
llU^^,ekk*
JJ	EII&."5#3#34 	##%"r>   c                    | j                   D ]  }|j                  |        | j                  D ]  }|j                  |        | j                  D ]  }|j                  |        y)z@Moves all contours, components and anchors by (x, y) font units.N)r4   mover3   rV   )r;   deltarE   r   r[   s        r<   r   z
Glyph.moveY  s_    }} 	 GLL	  	"INN5!	"ll 	FKK	r>   c                <    t        |      }| j                  |       y)zDraws glyph into given pen.N)r   r   )r;   penr   s      r<   drawz
Glyph.drawf  s     %S)!r>   c                    | j                   D ]  }|j                  |        | j                  D ]  }|j                  |        y)z+Draws points of glyph into given point pen.N)r4   r   r3   )r;   r   rE   r   s       r<   r   zGlyph.drawPointsl  sD    }} 	)Gx(	) 	+I  *	+r>   c                8    t        | j                               }|S )z+Returns a pen for others to draw into self.)r   r   )r;   r   s     r<   getPenzGlyph.getPens  s     0 0 23
r>   c                    t        |       }|S )z8Returns a point pen for others to draw points into self.r!   )r;   r   s     r<   r   zGlyph.getPointPenx  s     &r>   c                b    t        t        t           | j                  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	   strr}   r{   r:   s    r<   	markColorzGlyph.markColor  s#     HSM488<<0B#CDDr>   c                `    ||| j                   d<   y d| j                   v r| j                   d= y y )Nr   r}   rl   s     r<   r   zGlyph.markColor  s5    +0DHH'(488++, ,r>   c                b    t        t        t           | j                  j	                  d            S )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)   r}   r{   r:   s    r<   verticalOriginzGlyph.verticalOrigin  s#     HUOTXX\\2I%JKKr>   c                `    ||| j                   d<   y d| j                   v r| j                   d= y y )Nr   r   rl   s     r<   r   zGlyph.verticalOrigin  s5    05DHH,-$001 1r>   c                L    || 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.
        1layer is required to compute bounds of components)r3   r   r   r;   layers     r<   r   zGlyph.getBounds  s(     =T__OPPu%%r>   c                L    || j                   rt        d      t        | |      S )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.
        r   )r3   r   r    r   s     r<   r    zGlyph.getControlBounds  s(     =T__OPPe,,r>   c                B    | j                  |      }|y|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r;   r   boundss      r<   getLeftMarginzGlyph.getLeftMargin  s$     &>{{r>   c                    | j                  |      }|y||j                  z
  }|r)| xj                  |z  c_        | j                  |df       yy)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   )r;   rZ   r   r   diffs        r<   setLeftMarginzGlyph.setLeftMargin  sN     &>v{{"JJ$JIItQi  r>   c                \    | j                  |      }|y| j                  |j                  z
  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   s      r<   getRightMarginzGlyph.getRightMargin  s-     &>zzFKK''r>   c                T    | j                  |      }|y|j                  |z   | _        y)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*   )r;   rZ   r   r   s       r<   setRightMarginzGlyph.setRightMargin  s*     &>[[5(
r>   c                    | j                  |      }|y| j                  |j                  S |j                  | j                  | j                  z
  z
  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   yMinr+   r   s      r<   getBottomMarginzGlyph.getBottomMargin   sN     &>&;;;;$"5"5"CDDr>   c                   | j                  |      }|y| j                  |j                  }| j                  | _        n&|j                  | j                  | j                  z
  z
  }||z
  }|r| xj                  |z  c_        yy)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   r;   rZ   r   r   oldValuer   s         r<   setBottomMarginzGlyph.setBottomMargin  sx     &>&{{H"&++D{{d&9&9DKK&GHHxKK4K r>   c                    | j                  |      }|y| j                  | j                  |j                  z
  S | j                  |j                  z
  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+   yMaxr   s      r<   getTopMarginzGlyph.getTopMargin&  sN     &>&;;,,&&44r>   c                   | j                  |      }|y| j                  | j                  |j                  z
  }n| j                  |j                  z
  }||z
  }||k7  r*|j                  |z   | _        | xj                  |z  c_        yy)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   s         r<   setTopMarginzGlyph.setTopMargin6  s     &>&{{V[[0H**V[[8Hxu"(++"5DKK4K r>   )returnint)rA   r   r   r   )rE   r   r   bool)r   zIterator[Contour])r   r   )r   list[Anchor])rZ   r   r   None)r   list[Guideline])rZ   r   r   r   )r   
str | None)r   
int | None)rZ   r   r   r   )r   r   )rn   z Image | Mapping[str, Any] | Noner   r   )r~   r%   r   zdict[str, Any])r   r   )r   r   r   r   )r[   zAnchor | Mapping[str, Any]r   r   )rb   zGuideline | Mapping[str, Any]r   r   )rE   r   r   r   r8   )rd   r   r   r'   )r   r'   r   r   )r   ztuple[float, float]r   r   )r   r   r   r   )r   r   r   r   )r   r   )r   r   )rZ   r   r   r   )r   float | None)rZ   r   r   r   )r   GlyphSet | Noner   zBoundingBox | None)r   r   r   r   )rZ   r)   r   r   r   r   )ErP   rO   __qualname____doc__r(   __annotations__r*   r+   r   r   r-   r   r.   r   r   r0   r1   r2   r3   r4   r5   r6   r=   rB   rF   rI   rS   propertyr   r   r}   r   r   tempLibrV   setterr^   rd   rf   rn   r   ry   rX   r   r   r`   r   rY   ra   r   r   r   r   r   r   r   r   r   r   r   r    r   r   r   r   r   r   r   r   r   r>   r<   r'   r'   "   s   8  E=E5!FE"-Hi- %(FE(c\:D#:?D-0"40Hl0"'"5J54#D1Hm12#(#6K6#>Hc>4"$(#
 8X
&C|\2G
 
 ^^& &
 
  
  , ,
     ^^, ,   \\ &-, *$+ &#."+
 E E - - L L 2 2&-!"()E  ,5  r>   r'   N)4
__future__r   r   r   typingr   r   r   r   r	   r
   attrsr   r   fontTools.misc.transformr   fontTools.pens.basePenr   fontTools.pens.pointPenr   r   r   ufoLib2.objects.anchorr   ufoLib2.objects.componentr   ufoLib2.objects.contourr   ufoLib2.objects.guideliner   ufoLib2.objects.imager   ufoLib2.objects.libr   r   r   r   r   r   ufoLib2.objects.miscr   r   r   r    ufoLib2.pointPens.glyphPointPenr"   ufoLib2.serder#   ufoLib2.typingr$   r%   r'   r   r>   r<   <module>r      su    "  ? ?  . .  * / + / '  W V 9  2 f  f   f r>   