
     #e;                    "   d dl mZ d dlmZmZmZ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 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 m!Z!m"Z" d d	l#m$Z$ d d
l%m&Z& erd dl'm(Z(  ed      Z)ddZ*e$e G d d                    Z+ddZ,y)    )annotations)	TYPE_CHECKINGAnyDictIteratorKeysViewOptionalSequenceTypeoverload)definefield)GlyphSet)DEFAULT_LAYER_NAMEGlyph)Lib_convert_Lib_get_lib_get_tempLib_set_lib_set_tempLib)BoundingBox_deepcopy_unlazify_attrs_getstate_unlazify_attrs_prune_object_libs_setstate_attrsunionBounds)serde)T)	Converter___UFOLIB2_LAZY_GLYPH___)namec                   i }t        | t              rt               }| j                         D ]  \  }}t        |t              s!t        dt        |      j                         |t        urmt        |      }||v rt        |d      |j                  |       |j                  ||_        n+|j                  |k7  rt        d| d|j                   d      |||<    |S | D ]  }t        |t              s!t        dt        |      j                         |j                  t        |d      |j                  |v rt        d|j                   d      |||j                  <    |S )	NExpected Glyph, found z can't be added twicez$glyph has incorrect name: expected 'z
', found ''# has no name; can't add it to Layerglyph named '' already exists)
isinstancedictsetitemsr   	TypeErrortype__name___GLYPH_NOT_LOADEDidKeyErroraddr#   _name
ValueError)valueresult	glyph_idsr#   glyphglyph_ids         7/usr/lib/python3/dist-packages/ufoLib2/objects/layer.py_convert_glyphsr=   -   sz   !F%E	 ;;= 	!KD%eU+"8e9M9M8N OPP--e9y("eY.C#DEEh'::%"&EKZZ4'$%%)F*UZZLC  !F4L	!2 M  	'EeU+"8e9M9M8N OPPzz! E9,O!PQQzzV#uzzl:JKLL!&F5::	' M    c                     e Zd ZU dZ eeddi      Zded<    eee	      Z
ded	<   d
Zded<   	  eee      Zded<   	 dZded<   	  eee      Zded<   	  ed
dd      Zded<    ed
dd      Zded<   d3dZe	 d4	 	 	 	 	 	 	 	 	 d5d       Zd3dZeZeZeZd6dZd7dZd8dZd9dZ d:dZ!d;dZ"d<d Z#d=d>d!Z$d?d"Z%e&d@d#       Z'e&dAdBd$       Z'e(fdBd%Z'e)d<d&       Z* e)e+e,      Z- e)e.e/      Z0e)dCd'       Z1e)dDd(       Z2e)dDd)       Z3dEd*Z4	 	 	 dF	 	 	 	 	 	 	 	 	 dGd+Z5d8d,Z6d8d-Z7dHdId.Z8dJd/Z9dKdLd0Z:dMd1Z;e<	 	 	 	 	 	 	 	 dNd2       Z=y
)OLayera  Represents a Layer that holds Glyph objects.

    See http://unifiedfontobject.org/versions/ufo3/glyphs/layerinfo.plist/.

    Note:
        Various methods that work on Glyph objects take a ``layer`` attribute, because
        the UFO data model prescribes that Components within a Glyph object refer to
        glyphs *within the same layer*.

    Behavior:
        Layer behaves **partly** like a dictionary of type ``Dict[str, Glyph]``.
        Unless the font is loaded eagerly (with ``lazy=False``), the Glyph objects
        by default are only loaded into memory when accessed.

        To get the number of glyphs in the layer::

            glyphCount = len(layer)

        To iterate over all glyphs::

            for glyph in layer:
                ...

        To check if a specific glyph exists::

            exists = "myGlyphName" in layer

        To get a specific glyph::

            layer["myGlyphName"]

        To delete a specific glyph::

            del layer["myGlyphName"]
    omit_if_defaultF)defaultmetadatastrr5   )factory	converterzDict[str, Glyph]_glyphsNzOptional[str]colorr   _libbool_default_tempLib)rB   initeqzOptional[bool]_lazyr   	_glyphSetc                T    | j                   t        k(  r| j                  sd| _        y y y )NT)r5   r   rK   selfs    r<   __attrs_post_init__zLayer.__attrs_post_init__   s%    ::++DMM DM 5B+r>   c                *   |j                         }|r|D ci c]	  }|t         }}n:i }|D ]3  }t        |      }	|j                  ||	|	j	                                |	||<   5  | |||      }
||
_        |r||
_        |j                  |
       |
S c c}w )a@  Instantiates a Layer object from a
        :class:`fontTools.ufoLib.glifLib.GlyphSet`.

        Args:
            name: The name of the layer.
            glyphSet: The GlyphSet object to read from.
            lazy: If True, load glyphs as they are accessed. If False, load everything
                up front.
        )rB   )keysr1   r   	readGlyphgetPointPenrO   rP   readLayerInfo)clsr#   glyphSetlazyrB   
glyphNamesgnglyphs	glyphNamer:   rS   s              r<   readz
Layer.read   s     ]]_
6@Ab++AFAF' *	i(""9eU5F5F5HI$)y!* 41
%DNt$ Bs   Bc                8    | j                   r| D ]  } d| _         y)zLoad all glyphs into memory.FN)rO   )rS   _s     r<   unlazifyzLayer.unlazify   s"    :: 
r>   c                    || j                   v S NrG   rS   r#   s     r<   __contains__zLayer.__contains__   s    t||##r>   c                    | j                   |= y rf   rg   rh   s     r<   __delitem__zLayer.__delitem__   s    LLr>   c                V    | j                   |   }|t        u r| j                  |      S |S rf   )rG   r1   	loadGlyph)rS   r#   glyph_objects      r<   __getitem__zLayer.__getitem__   s.    ||D),,>>$''r>   c                    t        |t              s!t        dt        |      j                         ||_        || j                  |<   y )Nr%   )r*   r   r.   r/   r0   r5   rG   rS   r#   r:   s      r<   __setitem__zLayer.__setitem__   s?    %'4T%[5I5I4JKLL"Tr>   c              #  <   K   | j                   D ]	  }| |     y wrf   rg   rh   s     r<   __iter__zLayer.__iter__   s#     LL 	Dt*	s   c                ,    t        | j                        S rf   )lenrG   rR   s    r<   __len__zLayer.__len__   s    4<<  r>   c                8   t        | j                        }dj                  | j                  j                  | j                  j
                  | j                  | j                  rdnd|dk(  rdndj                  ||dkD  rdnd      t        t        |                   S )	Nz<{}.{} '{}' ({}{}) at {}>z	default,  r   emptyz
{} glyph{}   s)
rv   rG   format	__class__
__module__r0   r5   rK   hexr2   )rS   ns     r<   __repr__zLayer.__repr__   sz    *11NN%%NN##JJ==KbAvG<#6#6qQ#B#O4M
 	
r>   c                0    	 | |   S # t         $ r |cY S w xY w)zfReturn the Glyph object for name if it is present in this layer,
        otherwise return ``default``.r3   )rS   r#   rB   s      r<   getz	Layer.get   s%    	: 	N	s    c                6    | j                   j                         S )zReturns a list of glyph names.)rG   rV   rR   s    r<   rV   z
Layer.keys   s    ||  ""r>   c                     y rf    )rS   keys     r<   popz	Layer.pop       r>   c                     y rf   r   )rS   r   rB   s      r<   r   z	Layer.pop   r   r>   c                N    	 | |   }| |= |S # t         $ r |t         u r |}Y |S w xY w)zRemove and return glyph from layer.

        Args:
            key: The name of the glyph.
            default: What to return if there is no glyph with the given name.
        r   )rS   r   rB   r:   s       r<   r   z	Layer.pop   sF    	IE S	  	("E 	s    $$c                    | j                   S )zThe name of the layer.)r5   rR   s    r<   r#   z
Layer.name   s     zzr>   c                    | j                   S )zmRead-only property. To change the font's default layer use the
        LayerSet.defaultLayer property setter.)rK   rR   s    r<   rB   zLayer.default	  s     }}r>   c                N    d}| D ]  }t        ||j                  |             } |S )zReturns the (xMin, yMin, xMax, yMax) bounding box of the layer,
        taking the actual contours into account.

        |defcon_compat|
        N)r   	getBoundsrS   boundsr:   s      r<   r   zLayer.bounds  s4      	@E )>?F	@r>   c                N    d}| D ]  }t        ||j                  |             } |S )zReturns the (xMin, yMin, xMax, yMax) bounding box of the layer,
        taking only the control points into account.

        |defcon_compat|
        N)r   getControlBoundsr   s      r<   controlPointBoundszLayer.controlPointBounds  s6      	GE )?)?)EFF	Gr>   c                ,    | j                  |dd       y)zPAppends glyph object to the this layer unless its name is already
        taken.F)	overwritecopyN)insertGlyph)rS   r:   s     r<   addGlyphzLayer.addGlyph'  s     	%e<r>   c                   |r|j                         }|||_        |j                  t        |d      |s1|j                  | j                  v rt        d|j                   d      || j                  |j                  <   y)a  Inserts Glyph object into this layer.

        Args:
            glyph: The Glyph object.
            name: The name of the glyph.
            overwrite: If True, overwrites (read: deletes) glyph with the same name if
                it exists. If False, raises KeyError.
            copy: If True, copies the Glyph object before insertion. If False, inserts
                as is.
        Nr'   r(   r)   )r   r5   r#   r6   rG   r3   )rS   r:   r#   r   r   s        r<   r   zLayer.insertGlyph,  sy    " JJLEEK::y(KLMMUZZ4<<7]5::,6FGHH#(UZZ r>   c                    t        |      }| j                  j                  |||j                                || j                  |<   |S )zLoad and return Glyph object.)r   rP   rW   rX   rG   rq   s      r<   rm   zLayer.loadGlyphG  s?     d  ue.?.?.AB"Tr>   c                t    || j                   v rt        d| d      t        |      x| j                   |<   }|S )z=Creates and returns new Glyph object in this layer with name.r(   r)   )rG   r3   r   rq   s      r<   newGlyphzLayer.newGlyphO  s?    4<<]4&0@ABB%*4[0TUr>   c                    ||k(  ry|s|| j                   v rt        d| d      | j                  |      }||_        || j                   |<   y)a  Renames a Glyph object in this layer.

        Args:
            name: The old name.
            newName: The new name.
            overwrite: If False, raises exception if newName is already taken.
                If True, overwrites (read: deletes) the old Glyph object.
        Nztarget glyph named 'r)   )rG   r3   r   r5   )rS   r#   newNamer   r:   s        r<   renameGlyphzLayer.renameGlyphV  sT     7?W41':JKLL %Wr>   c                    t               S )z?Returns a new Glyph instance.

        |defcon_compat|
        r   rR   s    r<   instantiateGlyphObjectzLayer.instantiateGlyphObjecti  s    
 wr>   c                   | j                   }|s:t        |j                        j                  |      D ]  }|j	                  |        |j                         D ]_  \  }}|t        u r|r| j                  |      }n#t        |j                  t        |             |j                  |||j                         a |j                          |j                  |        |rd| _        yy)aS  Write Layer to a :class:`fontTools.ufoLib.glifLib.GlyphSet`.

        Args:
            glyphSet: The GlyphSet object to write to.
            saveAs: If True, tells the writer to save out-of-place. If False, tells the
                writer to save in-place. This affects how resources are cleaned before
                writing.
        )glyphObjectdrawPointsFuncN)rG   r,   contents
differencedeleteGlyphr-   r1   rm   r   lib_fetch_glyph_identifiers
writeGlyph
drawPointswriteContentswriteLayerInforP   )rS   r[   saveAsr_   r#   r:   s         r<   writezLayer.writep  s     H--.99&A +$$T*+!<<> 		KD%)) NN40Euyy*B5*IJ%8H8H   		 	 %!DN r>   c                   i }| j                   D ]1  }|j                  | |         }||j                  d      k(  sJ |||<   3 d| j                  i}d| j                  | j                  t
        k(  fd|i fd| j                  i fd| j                  i ffD ]  \  }}}|j                  r||k7  s|||<    | j                  | j                  |d<   |S )Nr#   rB   r_   r   tempLibrH   )
rG   unstructurer   r5   rK   r   rI   rL   rA   rH   )	rS   rF   r_   
glyph_namegdr   r7   rB   s	            r<   _unstructurezLayer._unstructure  s    ,.,, 	#J%%d:&67Av...!"F:	# DJJ
 tzz5G'GHvr"DIIr"r*	$
 	C ,,0@#	 ::!AgJr>   c                    || j                  dt              | j                  di       j                         D ci c]  \  }}||j                  |t               c}}| j                  d      |j                  | j                  di       t
              | j                  dd      |j                  | j                  di       t
                    S c c}}w )	Nr#   r_   rH   r   rB   Fr   )r#   r_   rH   r   rB   r   )r   r   r-   	structurer   r   )datarZ   rF   kvs        r<   
_structurezLayer._structure  s     &"45 !HHXr288:Aq 9&&q%00 ((7###DHHUB$7=HHY.''B(?E

 
	
s   !C)returnNone)TF)
r#   rD   r[   r   r\   rJ   rB   rJ   r   r@   )r#   objectr   rJ   )r#   rD   r   r   )r#   rD   r   r   )r#   rD   r:   r   r   r   )r   zIterator[Glyph])r   int)r   rD   rf   )r#   rD   rB   zT | Noner   zT | Glyph | None)r   zKeysView[str])r   rD   r   r   ).)r   rD   rB   	Glyph | Tr   r   )r   rJ   )r   zBoundingBox | None)r:   r   r   r   )NTT)
r:   r   r#   z
str | Noner   rJ   r   rJ   r   r   )F)r#   rD   r   rD   r   rJ   r   r   )r   r   )T)r[   r   r   rJ   r   r   )rF   r!   r   dict[str, Any])r   r   rZ   zType[Layer]rF   r!   r   r@   )>r0   r   __qualname____doc__r   r   r5   __annotations__r+   r=   rG   rH   r   r   rI   rK   rL   rO   rP   rT   classmethodra   rd   r   __deepcopy__r   __getstate__r   __setstate__ri   rk   ro   rr   rt   rw   r   r   rV   r   r   r3   propertyr#   r   r   r   r   r   r   rB   r   r   r   r   rm   r   r   r   r   r   staticmethodr   r   r>   r<   r@   r@   M   sY   "H 1=NPU<VWE3W %do NGNE=*c\:D#:DHd #>Hc>4!$UuEE>E4e>Is>!
 OT"*26HL	 : ,L+L"L$#!	
#     2: $   8X
&C|\2G 
 	 	 	 	=  )) ) 	)
 ) 
)6&&":2 

#.
;D
	
 
r>   r@   c                >   t               }| j                  D ]*  }|j                  |j                  |j                         , | j                  D ]*  }|j                  |j                  |j                         , | j
                  D ]X  }|j                  |j                  |j                         |D ]*  }|j                  |j                  |j                         , Z | j                  D ]*  }|j                  |j                  |j                         , |S )z*Returns all identifiers in use in a glyph.)r,   anchors
identifierr4   
guidelinescontours
components)r:   identifiersanchor	guidelinecontourpoint	components          r<   r   r     s    %K-- /(OOF--./ %% 2	+OOI0012 >> 2)OOG../ 	2E+ 0 01	22 %% 2	+OOI0012 r>   N)r7   z"dict[str, Glyph] | Sequence[Glyph]r   zdict[str, Glyph])r:   r   r   zset[str])-
__future__r   typingr   r   r   r   r   r	   r
   r   r   attrsr   r   fontTools.ufoLib.glifLibr   ufoLib2.constantsr   ufoLib2.objects.glyphr   ufoLib2.objects.libr   r   r   r   r   r   ufoLib2.objects.miscr   r   r   r   r   r   ufoLib2.serder   ufoLib2.typingr    cattrsr!   r1   r=   r@   r   r   r>   r<   <module>r      s    "
 
 
   - 0 '      9: @ e
 e
  e
Pr>   