
     #e4                       d dl mZ d dl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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 d d	lmZ d d
lmZ erd dlmZ d dl m!Z!  ed      Z"ddZ#ee G d d                    Z$y)    )annotations)TYPE_CHECKINGAbstractSetAnyDictIterableIteratorOptionalSized)definefield)	UFOReader	UFOWriter)DEFAULT_LAYER_NAME)Error)Layer)_deepcopy_unlazify_attrs_getstate_unlazify_attrs_setstate_attrs)serde)T)Type)	Converter___UFOLIB2_LAZY_LAYER___)namec                0    t        |      st        d      y )Nz"value must have at least one item.)len
ValueError)self	attributevalues      :/usr/lib/python3/dist-packages/ufoLib2/objects/layerSet.py_must_have_at_least_one_itemr#   $   s    u:=>>     c                  "   e Zd ZU dZ ee      Zded<    eed      Z	ded<    ed	dd
      Z
ded<    ed	dd
      Zded<   d(dZed)d       Zeef	 	 	 	 	 d*d       Zed+d,d       Zd(dZeZeZeZe	 d-	 	 	 	 	 	 	 	 	 d.d       Zd+d/dZed0d       Zej<                  d1d       Zd2dZd3dZ d4dZ!d5dZ"d6dZ#d7d8dZ$d9dZ%d:dZ&ed;d        Z'e'j<                  d<d!       Z'd=d"Z(d>d?d#Z)d>d?d$Z*d7d@d%Z+dAd&Z,e	 	 	 	 	 	 	 	 dBd'       Z-y	)CLayerSeta  Represents a mapping of layer names to Layer objects.

    See http://unifiedfontobject.org/versions/ufo3/layercontents.plist/ for layer
    semantics.

    Behavior:
        LayerSet behaves **partly** like a dictionary of type ``Dict[str, Layer]``,
        but creating and loading layers is done through their own methods. Unless the
        font is loaded eagerly (with ``lazy=False``), the layer objects and their
        glyphs are by default only loaded into memory when accessed.

        To get the number of layers in the font::

            layerCount = len(font.layers)

        To iterate over all layers::

            for layer in font.layers:
                ...

        To check if a specific layer exists::

            exists = "myLayerName" in font.layers

        To get a specific layer::

            font.layers["myLayerName"]

        To delete a specific layer::

            del font.layers["myLayerName"]
    )	validatorzDict[str, Layer]_layersF)defaulteqr   _defaultLayerN)r)   initr*   zOptional[bool]_lazyzOptional[UFOReader]_readerc                     j                   t        k(  rRd} j                  j                         D ]%  }|j                  s|rt        d      d}| _         ' |st        d      y t         fd j                  j                         D              s"t        dt         j                          d       j                   j                  sJ y )NF%more than one layer marked as defaultTno layer marked as defaultc              3  :   K   | ]  }|j                   u   y wNr+   ).0layerr   s     r"   	<genexpr>z/LayerSet.__attrs_post_init__.<locals>.<genexpr>b   s     Vuu 2 22Vs   zdefault layer z must be in layer set.)r+   _LAYER_NOT_LOADEDr(   values_defaultr   anyrepr)r   foundr6   s   `  r"   __attrs_post_init__zLayerSet.__attrs_post_init__V   s    !22E,,. />>()PQQ E).D&/  !=>>  V@S@S@UVV $T$*<*<%=$>>TU  %%....r$   c                6    | j                  t               g      S )z2Return a new LayerSet with an empty default Layer.)from_iterabler   )clss    r"   r)   zLayerSet.defaulth   s       %'++r$   c                   |t         k7  rddl}|j                  dt               i }d}|D ]  }t	        |t
              s"t        dt        |      j                   d      |j                  |v rt        d|j                   d      |j                  |k(  s|j                  r"|t        d      |j                  sd|_        |}|||j                  <    |t        d	      |J  | ||
      S )zInstantiates a LayerSet from an iterable of :class:`.Layer` objects.

        Args:
            value: an iterable of :class:`.Layer` objects.
            defaultLayerName: the name of the default layer of the ones in ``value``.
        r   NzO'defaultLayerName' parameter is deprecated; use Layer.default attribute insteadzexpected 'Layer', found ''zduplicate layer name: 'r0   Tr1   layersdefaultLayer)r   warningswarnDeprecationWarning
isinstancer   	TypeErrortype__name__r   KeyErrorr:   r   )rA   r!   defaultLayerNamerG   rE   rF   r6   s          r"   r@   zLayerSet.from_iterablem   s    11MM6"
 $& 	'EeU+";DK<P<P;QQR STTzzV#!8AFGGzz--+$%LMM~~%)EN$!&F5::	' 9::'''&|<<r$   c                    i }d}|j                         }|j                         D ]2  }||k(  }|s|s| j                  ||||      }|r|}|||<   *t        ||<   4 |J  | ||      }	||	_        |r||	_        |	S )a  Instantiates a LayerSet object from a :class:`fontTools.ufoLib.UFOReader`.

        Args:
            path: The path to the UFO to load.
            lazy: If True, load glyphs, data files and images as they are accessed. If
                False, load everything up front.
        NrD   )getDefaultLayerNamegetLayerNames
_loadLayerr8   r-   r.   )
rA   readerlazyrE   rF   rO   	layerName	isDefaultr6   r   s
             r"   readzLayerSet.read   s     $&!557--/ 	6I!%55Ivy$	J#(L$)y!$5y!	6 '''&|<
!DLr$   c                X    | j                   r| D ]  }|j                           d| _         y)zLoad all layers into memory.FN)r-   unlazifyr   r6   s     r"   rZ   zLayerSet.unlazify   s)    :: ! !
r$   c                V    | j                  |      }t        j                  ||||      S )N)rU   r)   )getGlyphSetr   rX   )rT   rV   rU   r)   glyphSets        r"   rS   zLayerSet._loadLayer   s)     %%i0zz)XD'JJr$   c                    | j                   J || j                  vrt        |      | j                  | j                   ||      }|| j                  |<   |S r3   )r.   r(   rN   rS   )r   rV   rU   r6   s       r"   	loadLayerzLayerSet.loadLayer   sT     ||'''DLL(9%%i>"'Yr$   c                    | j                   S r3   r4   r   s    r"   rF   zLayerSet.defaultLayer   s    !!!r$   c                   || j                   u ry || j                  j                         vrt        d|d      | j                   j                  t
        k(  rt        d      d| j                   _        d|_        || _         y )NzLayer z- not found in layer set; can't set as defaultzFthere's already a layer named 'public.default' which must stay defaultFT)r+   r(   r9   r   r   r   r:   r[   s     r"   rF   zLayerSet.defaultLayer   s    D&&&++--	!NO  ""&88X  ',#"r$   c                    || j                   v S r3   )r(   r   r   s     r"   __contains__zLayerSet.__contains__   s    t||##r$   c                    | j                   '|| j                   j                  k(  rt        d|z        | j                  |= y )Nzcannot delete default layer %r)rF   r   rN   r(   re   s     r"   __delitem__zLayerSet.__delitem__   s?    (t((---?$FGGLLr$   c                V    | j                   |   }|t        u r| j                  |      S |S r3   )r(   r8   r`   )r   r   layer_objects      r"   __getitem__zLayerSet.__getitem__   s.    ||D),,>>$''r$   c              #     K   | j                   j                         D ]%  \  }}|t        u r| j                  |       "| ' y wr3   )r(   itemsr8   r`   )r   
layer_namerj   s      r"   __iter__zLayerSet.__iter__   sE     (,(:(:(< 	#$J00nnZ00""		#s   AAc                ,    t        | j                        S r3   )r   r(   rb   s    r"   __len__zLayerSet.__len__   s    4<<  r$   c                0    	 | |   S # t         $ r |cY S w xY wr3   )rN   )r   r   r)   s      r"   getzLayerSet.get   s%    	: 	N	s    c                6    | j                   j                         S r3   )r(   keysrb   s    r"   ru   zLayerSet.keys  s    ||  ""r$   c                    t        | j                        }dj                  | j                  j                  | j                  j
                  ||dkD  rdndt        t        |                   S )Nz<{}.{} ({} layer{}) at {}>   s )r   r(   format	__class__
__module__rM   hexid)r   ns     r"   __repr__zLayerSet.__repr__  sV    +22NN%%NN##q5Cb4M
 	
r$   c                ,    t        | j                        S )an  The font's layer order.

        Getter:
            Returns the font's layer order.

        Note:
            The getter always returns a new list, modifications to it do not change
            the LayerSet.

        Setter:
            Sets the font's layer order. The set order value must contain all layers
            that are present in the LayerSet.
        )listr(   rb   s    r"   
layerOrderzLayerSet.layerOrder  s     DLL!!r$   c                    t        |      t        | j                        k7  rt        d      |D ci c]  }|| j                  |    c}| _        y c c}w )Nz@`order` must contain the same layers that are currently present.)setr(   r   )r   orderr   s      r"   r   zLayerSet.layerOrder#  sM    u:T\\**R  >CCTdll400CCs   Ac                    || j                   v rt        d|z        t        |fi |x| j                   |<   }|j                  r|| _        |S )zCreates and returns a named layer.

        Args:
            name: The layer name.
            kwargs: Arguments passed to the constructor of Layer.
        zlayer %r already exists)r(   rN   r   r:   rF   )r   r   kwargsr6   s       r"   newLayerzLayerSet.newLayer+  sR     4<<4t;<<%*4%:6%::TU>> %Dr$   c                    |k(  ryt        fd| D              st        dz        | D ]  }||v s|r||= t        d|z         | D ]$  }|v s|j                        x||<   }||_        & y)a#  Renames a glyph across all layers.

        Args:
            name: The old name.
            newName: The new name.
            overwrite: If False, raises exception if newName is already taken in any
                layer. If True, overwrites (read: deletes) the old Glyph object.
        Nc              3  &   K   | ]  }|v  
 y wr3    )r5   r6   r   s     r"   r7   z'LayerSet.renameGlyph.<locals>.<genexpr>F  s     3U45=3s   zname %r is not in layer settarget name %r already exists)r;   rN   pop_name)r   r   newName	overwriter6   glyphs    `    r"   renameGlyphzLayerSet.renameGlyph9  s     7?3d3384?@@ 	NE%g"#BW#LMM	N  	&Eu}).48g%	&r$   c                    ||k(  ry|s|| j                   v rt        d|z        | |   }| j                   |= || j                   |<   ||_        |t        k(  r|| _        yy)a  Renames a 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 Layer object.
        Nr   )r(   rN   r   r   rF   )r   r   r   r   r6   s        r"   renameLayerzLayerSet.renameLayerU  sm     7?W4:WDEET
LL %W(( %D )r$   c                   || j                   |u}| j                  }|s>t        |j                               j	                  |      D ]  }|j                  |        | j                  }|j                         D ]N  \  }}||u }|t        u r|r| j                  |d      }n)|j                  ||      }|j                  ||       P |j                  | j                         y)af  Writes this LayerSet to a :class:`fontTools.ufoLib.UFOWriter`.

        Args:
            writer(fontTools.ufoLib.UFOWriter): The writer 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.
        NF)rU   )rF   )saveAs)r.   r(   r   rR   
differencedeleteGlyphSetrF   rm   r8   r`   r]   writewriteLayerContentsr   )	r   writerr   rE   r   rF   r6   r)   r^   s	            r"   r   zLayerSet.writei  s     >\\/FF0023>>vF ,%%d+, ((!<<> 	1KD%|+G)) NN4eN<E))$W)EHKKK0	1 	!!$//2r$   c                J    | D cg c]  }|j                  |       c}S c c}w r3   )unstructure)r   	converterr6   s      r"   _unstructurezLayerSet._unstructure  s!    :>?	%%e,???s    c                8    |j                  fd| D              S )Nc              3  J   K   | ]  }j                  |t                y wr3   )	structurer   )r5   r6   r   s     r"   r7   z&LayerSet._structure.<locals>.<genexpr>  s      Uu!4!4UE!B Us    #)r@   )datarA   r   s     `r"   
_structurezLayerSet._structure  s        UPT UUUr$   )returnNone)r   r&   )r!   zIterable[Layer]rO   strr   r&   )T)rT   r   rU   boolr   r&   )TF)
rT   r   rV   r   rU   r   r)   r   r   r   )rV   r   rU   r   r   r   )r   r   )r6   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   zIterator[Layer])r   intr3   )r   r   r)   zT | Noner   zT | Layer | None)r   zAbstractSet[str])r   r   )r   	list[str])r   r   r   r   )r   r   r   r   r   r   )F)r   r   r   r   r   r   r   r   )r   r   r   zbool | Noner   r   )r   r   r   list[dict[str, Any]])r   r   rA   zType[LayerSet]r   r   r   r&   ).rM   r|   __qualname____doc__r   r#   r(   __annotations__r8   r+   r-   r.   r>   classmethodr)   r   r@   rX   rZ   r   __deepcopy__r   __getstate__r   __setstate__staticmethodrS   r`   propertyrF   setterrf   rh   rk   ro   rq   rs   ru   r   r   r   r   r   r   r   r   r   r$   r"   r&   r&   )   s   B !&.!G  !):uEM5E!$UuEE>E#(Ee#LG L/$ , , =O$=#$=7:$=	$= $=L  @ ,L+L"LNSKK&)K15KGKK	K K " " # #$#!#
 " "  D D&8&(3:@ V"V)7VDMV	V Vr$   r&   N)r   r   r    r   r!   r   r   r   )%
__future__r   typingr   r   r   r   r   r	   r
   r   attrsr   r   fontTools.ufoLibr   r   ufoLib2.constantsr   ufoLib2.errorsr   ufoLib2.objects.layerr   ufoLib2.objects.miscr   r   r   ufoLib2.serder   ufoLib2.typingr   r   cattrsr   r8   r#   r&   r   r$   r"   <module>r      s{    "	 	 	   1 0   ' 
    9: ?
 bV bV  bVr$   