o
    b3                     @  s   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 d d	lmZ erVd d
lmZ d dlmZ eddZdddZeG dd dZ dS )    )annotations)TYPE_CHECKINGAbstractSetAnyDictIterableIteratorOptionalSized)definefield)	UFOReader	UFOWriter)DEFAULT_LAYER_NAME)Error)Layer)_deepcopy_unlazify_attrs)T)Type)GenConverterZ___UFOLIB2_LAZY_LAYER___nameselfr   	attributevaluer
   returnNonec                 C  s   t |stdd S )Nz"value must have at least one item.)len
ValueError)r   r   r    r   :/usr/lib/python3/dist-packages/ufoLib2/objects/layerSet.py_must_have_at_least_one_item   s   r!   c                   @  s  e Zd ZU dZeedZded< eeddZ	ded< ed	ddd
Z
ded< daddZedbddZeefdcddZedddeddZdad d!ZeZe	dfdgd$d%Zdddhd&d'Zedid(d)Zejdjd+d)Zdkd-d.Zdld/d0Zdmd1d2Zdnd4d5Zdod7d8Zdpdqd;d<Zdrd>d?Z dsd@dAZ!edtdCdDZ"e"jdudFdDZ"dvdIdJZ#dwdxdMdNZ$dwdxdOdPZ%dpdydUdVZ&dzdZd[Z'ed{d_d`Z(d	S )|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"]
    )Z	validatorzDict[str, Layer]_layersF)defaulteqr   _defaultLayerN)r$   Zinitr%   zOptional[UFOReader]_readerr   r   c                   s    j tkr%d} j D ]}|jr|rtdd}| _ q|s#tdd S t fdd j D s>tdt j  d j jsDJ d S )	NF%more than one layer marked as defaultTno layer marked as defaultc                 3  s    | ]}| j u V  qd S Nr&   .0layerr   r   r    	<genexpr>[   s    z/LayerSet.__attrs_post_init__.<locals>.<genexpr>zdefault layer z must be in layer set.)r&   _LAYER_NOT_LOADEDr#   values_defaultr   anyrepr)r   foundr.   r   r/   r    __attrs_post_init__O   s"   
zLayerSet.__attrs_post_init__c                 C  s   |  t gS )z2Return a new LayerSet with an empty default Layer.)from_iterabler   )clsr   r   r    r$   a   s   zLayerSet.defaultr   Iterable[Layer]defaultLayerNamestrc                 C  s   |t krddl}|dt i }d}|D ]=}t|ts&tdt|j d|j	|v r4t
d|j	 d|j	|ks<|jrL|durDtd|jsJd|_|}|||j	< q|du rZtd	|dus`J | ||d
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: 'r(   Tr)   layersdefaultLayer)r   warningswarnDeprecationWarning
isinstancer   	TypeErrortype__name__r   KeyErrorr3   r   )r9   r   r;   rA   r?   r@   r.   r   r   r    r8   f   s0   


zLayerSet.from_iterableTreaderr   lazyboolc           
      C  s~   i }d}|  }| D ]}||k}|s|s'| ||||}|r"|}|||< qt||< q|dus2J | ||d}	|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.
        Nr>   )ZgetDefaultLayerNamegetLayerNames
_loadLayerr1   r'   )
r9   rI   rJ   r?   r@   r;   	layerNameZ	isDefaultr.   r   r   r   r    read   s    	

zLayerSet.readc                 C  s   | D ]}|   qdS )zLoad all layers into memory.N)unlazifyr   r.   r   r   r    rP      s   
zLayerSet.unlazifyrN   r$   c                 C  s   |  |}tj||||dS )N)rJ   r$   )getGlyphSetr   rO   )rI   rN   rJ   r$   glyphSetr   r   r    rM      s   
zLayerSet._loadLayerc                 C  s>   | j d usJ || jvrt|| | j ||}|| j|< |S r*   )r'   r#   rH   rM   )r   rN   rJ   r.   r   r   r    	loadLayer   s   

zLayerSet.loadLayerc                 C  s   | j S r*   r+   r/   r   r   r    r@      s   zLayerSet.defaultLayerr.   c                 C  sX   || j u rd S || j vrtd|d| j jtkr tdd| j _d|_|| _ d S )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#   r2   r   r   r   r3   rQ   r   r   r    r@      s   


r   c                 C  s
   || j v S r*   r#   r   r   r   r   r    __contains__      
zLayerSet.__contains__c                 C  s.   | j d ur|| j jkrtd| | j|= d S )Nzcannot delete default layer %r)r@   r   rH   r#   rV   r   r   r    __delitem__   s   
zLayerSet.__delitem__c                 C  s    | j | }|tu r| |S |S r*   )r#   r1   rT   )r   r   layer_objectr   r   r    __getitem__   s   

zLayerSet.__getitem__Iterator[Layer]c                 c  s6    | j  D ]\}}|tu r| |V  q|V  qd S r*   )r#   itemsr1   rT   )r   Z
layer_namerZ   r   r   r    __iter__   s   zLayerSet.__iter__intc                 C  
   t | jS r*   )r   r#   r/   r   r   r    __len__   rX   zLayerSet.__len__T | NoneT | Layer | Nonec                 C  s"   z| | W S  t y   | Y S w r*   )rH   )r   r   r$   r   r   r    get   s
   
zLayerSet.getAbstractSet[str]c                 C  s
   | j  S r*   )r#   keysr/   r   r   r    rf      rX   zLayerSet.keysc              	   C  s8   t | j}d| jj| jj||dkrdndtt| S )Nz<{}.{} ({} layer{}) at {}>   s )r   r#   format	__class__
__module__rG   hexid)r   nr   r   r    __repr__   s   

zLayerSet.__repr__	list[str]c                 C  r`   )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#   r/   r   r   r    
layerOrder  s   
zLayerSet.layerOrderorderc                   s2   t |t  jkrtd fdd|D  _d S )Nz@`order` must contain the same layers that are currently present.c                   s   i | ]}| j | qS r   rU   )r-   r   r/   r   r    
<dictcomp>  s    z'LayerSet.layerOrder.<locals>.<dictcomp>)setr#   r   )r   rt   r   r/   r    rs     s
   kwargsr   c                 K  s@   || j v rtd| t|fi | | 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#   rH   r   r3   r@   )r   r   rw   r.   r   r   r    newLayer  s   
zLayerSet.newLayernewName	overwritec                   s    |krdS t  fdd| D std  | D ]}||v r+|r%||= qtd| q| D ]} |v r@|  ||< }||_q.dS )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  s    | ]} |v V  qd S r*   r   r,   r   r   r    r0   9  s    z'LayerSet.renameGlyph.<locals>.<genexpr>zname %r is not in layer settarget name %r already exists)r4   rH   pop_name)r   r   ry   rz   r.   Zglyphr   r   r    renameGlyph,  s    
zLayerSet.renameGlyphc                 C  s\   ||krdS |s|| j v rtd| | | }| j |= || j |< ||_|tkr,|| _dS dS )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#   rH   r}   r   r@   )r   r   ry   rz   r.   r   r   r    renameLayerH  s   	

zLayerSet.renameLayerwriterr   saveAsbool | Nonec           	      C  s   |du r	| j |u}| j}|st| |D ]}|| q| j}| D ]%\}}||u }|tu r=|r<| j	|dd}nq&|j
||d}|j||d q&|| j dS )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)rJ   )r@   )r   )r'   r#   rv   rL   
differenceZdeleteGlyphSetr@   r]   r1   rT   rR   writeZwriteLayerContentsrs   )	r   r   r   r?   r   r@   r.   r$   rS   r   r   r    r   \  s    	
zLayerSet.write	converterr   list[dict[str, Any]]c                   s    fdd| D S )Nc                   s   g | ]}  |qS r   )Zunstructurer,   r   r   r    
<listcomp>z  s    z)LayerSet._unstructure.<locals>.<listcomp>r   )r   r   r   r   r    _unstructurey  s   zLayerSet._unstructuredatar9   Type[LayerSet]c                   s   |  fdd| D S )Nc                 3  s    | ]	}  |tV  qd S r*   )Z	structurer   r,   r   r   r    r0     s    z&LayerSet._structure.<locals>.<genexpr>)r8   )r   r9   r   r   r   r    
_structure|  s   zLayerSet._structure)r   r   )r   r"   )r   r:   r;   r<   r   r"   )T)rI   r   rJ   rK   r   r"   )TF)
rI   r   rN   r<   rJ   rK   r$   rK   r   r   )rN   r<   rJ   rK   r   r   )r   r   )r.   r   r   r   )r   r<   r   rK   )r   r<   r   r   )r   r<   r   r   )r   r\   )r   r_   r*   )r   r<   r$   rb   r   rc   )r   re   )r   r<   )r   rq   )rt   rq   r   r   )r   r<   rw   r   r   r   )F)r   r<   ry   r<   rz   rK   r   r   )r   r   r   r   r   r   )r   r   r   r   )r   r   r9   r   r   r   r   r"   ))rG   rl   __qualname____doc__r   r!   r#   __annotations__r1   r&   r'   r7   classmethodr$   r   r8   rO   rP   r   __deepcopy__staticmethodrM   rT   propertyr@   setterrW   rY   r[   r^   ra   rd   rf   rp   rs   rx   r~   r   r   r   r   r   r   r   r    r"   $   sX   
 !
&











r"   N)r   r   r   r   r   r
   r   r   )!Z
__future__r   typingr   r   r   r   r   r   r	   r
   attrr   r   ZfontTools.ufoLibr   r   ZufoLib2.constantsr   ZufoLib2.errorsr   ZufoLib2.objects.layerr   ZufoLib2.objects.miscr   ZufoLib2.typingr   r   Zcattrr   r1   r!   r"   r   r   r   r    <module>   s     (

