o
    b8                     @  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
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 d dlmZmZmZmZ d d	lm Z  er\d d
l!m"Z" eddZ#dddZ$eG dd dZ%dddZ&dS )    )annotations)	TYPE_CHECKINGAnyDictIteratorKeysViewOptionalSequenceTypeoverload)definefield)GlyphSet)DEFAULT_LAYER_NAMEGlyph)Lib_convert_Lib_get_lib_set_lib)BoundingBox_deepcopy_unlazify_attrs_prune_object_libsunionBounds)T)GenConverterZ___UFOLIB2_LAZY_GLYPH___)namevalue"dict[str, Glyph] | Sequence[Glyph]returndict[str, Glyph]c                 C  s  i }t | trZt }|  D ]I\}}t |ts!tdt|j |turSt	|}||v r4t
|d|| |jd u rB||_n|j|krStd| d|j d|||< q|S | D ]0}t |tsmtdt|j |jd u ryt|d|j|v rt
d|j d|||j< q\|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)r   resultZ	glyph_idsr   glyphZglyph_id r5   7/usr/lib/python3/dist-packages/ufoLib2/objects/layer.py_convert_glyphs#   s@   









r7   c                   @  s  e Zd ZU dZeeddidZded< eee	dZ
ded	< d
Zded< 	 eeedZded< 	 dZded< 	 ed
dddZded< diddZe	djdkddZdid d!ZeZdld#d$Zdmd%d&Zdnd(d)Zdod+d,Zdpd.d/Zdqd1d2Zdrd3d4Zdsdtd7d8Zdud:d;Ze dvd=d>Z!e dwdxdAd>Z!e"fdxdBd>Z!e#drdCdDZ$e#e%e&Z'e#dydEdFZ(e#dzdHdIZ)e#dzdJdKZ*d{dLdMZ+	
		d|d}dQdRZ,dndSdTZ-dndUdVZ.d~ddXdYZ/ddZd[Z0ddd]d^Z1ddbdcZ2e3ddgdhZ4d
S )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)defaultZmetadatastrr1   )factory	converterzDict[str, Glyph]_glyphsNzOptional[str]colorr   _libbool_default)r:   Ziniteqr   	_glyphSetr   Nonec                 C  s"   | j tkr| jsd| _d S d S d S )NT)r1   r   rB   selfr5   r5   r6   __attrs_post_init__x   s   
zLayer.__attrs_post_init__Tr   glyphSetr   lazyr:   c           
      C  sr   |  }|rdd |D }ni }|D ]}t|}||||  |||< q| |||d}	|r2||	_||	 |	S )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.
        c                 S  s   i | ]}|t qS r5   )r-   ).0Zgnr5   r5   r6   
<dictcomp>   s    zLayer.read.<locals>.<dictcomp>)r:   )keysr   	readGlyphgetPointPenrD   ZreadLayerInfo)
clsr   rI   rJ   r:   Z
glyphNamesglyphsZ	glyphNamer4   rG   r5   r5   r6   read}   s   

z
Layer.readc                 C  s   | D ]}qdS )zLoad all glyphs into memory.Nr5   )rG   _r5   r5   r6   unlazify   s   zLayer.unlazifyobjectc                 C  s
   || j v S Nr>   rG   r   r5   r5   r6   __contains__      
zLayer.__contains__c                 C  s   | j |= d S rV   rW   rX   r5   r5   r6   __delitem__   s   zLayer.__delitem__r   c                 C  s    | j | }|tu r| |S |S rV   )r>   r-   	loadGlyph)rG   r   Zglyph_objectr5   r5   r6   __getitem__   s   

zLayer.__getitem__r4   c                 C  s2   t |tstdt|j ||_|| j|< d S )Nr!   )r&   r   r*   r+   r,   r1   r>   rG   r   r4   r5   r5   r6   __setitem__   s   
zLayer.__setitem__Iterator[Glyph]c                 c  s    | j D ]}| | V  qd S rV   rW   rX   r5   r5   r6   __iter__   s   
zLayer.__iter__intc                 C  s
   t | jS rV   )lenr>   rF   r5   r5   r6   __len__   rZ   zLayer.__len__c                 C  sZ   t | j}d| jj| jj| j| jrdnd|dkrdnd||dkr$dndtt	| S )	Nz<{}.{} '{}' ({}{}) at {}>z	default,  r   emptyz
{} glyph{}   s)
rc   r>   format	__class__
__module__r,   r1   rB   hexr.   )rG   nr5   r5   r6   __repr__   s   
"
zLayer.__repr__T | NoneT | Glyph | Nonec                 C  s"   z| | W S  t y   | Y S w )zfReturn the Glyph object for name if it is present in this layer,
        otherwise return ``default``.r/   )rG   r   r:   r5   r5   r6   get   s
   
z	Layer.getKeysView[str]c                 C  s
   | j  S )zReturns a list of glyph names.)r>   rM   rF   r5   r5   r6   rM      s   
z
Layer.keyskeyc                 C     d S rV   r5   )rG   rt   r5   r5   r6   pop      z	Layer.pop.	Glyph | Tc                 C  ru   rV   r5   )rG   rt   r:   r5   r5   r6   rv      rw   c                 C  s:   z| | }W n t y   |t u r |}Y |S w | |= |S )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.
        rq   )rG   rt   r:   r4   r5   r5   r6   rv      s   c                 C     | j S )zThe name of the layer.)r1   rF   r5   r5   r6   r      s   z
Layer.namec                 C  ry   )zmRead-only property. To change the font's default layer use the
        LayerSet.defaultLayer property setter.)rB   rF   r5   r5   r6   r:      s   zLayer.defaultBoundingBox | Nonec                 C  "   d}| D ]
}t ||| }q|S )zReturns the (xMin, yMin, xMax, yMax) bounding box of the layer,
        taking the actual contours into account.

        |defcon_compat|
        N)r   Z	getBoundsrG   boundsr4   r5   r5   r6   r}         zLayer.boundsc                 C  r{   )zReturns the (xMin, yMin, xMax, yMax) bounding box of the layer,
        taking only the control points into account.

        |defcon_compat|
        N)r   ZgetControlBoundsr|   r5   r5   r6   controlPointBounds  r~   zLayer.controlPointBoundsc                 C  s   | j |ddd dS )zPAppends glyph object to the this layer unless its name is already
        taken.F)	overwritecopyN)insertGlyph)rG   r4   r5   r5   r6   addGlyph  s   zLayer.addGlyph
str | Noner   r   c                 C  sd   |r|  }|dur||_|jdu rt|d|s*|j| jv r*td|j d|| j|j< dS )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   r1   r   r2   r>   r/   )rG   r4   r   r   r   r5   r5   r6   r     s   
zLayer.insertGlyphc                 C  s*   t |}| j|||  || j|< |S )zLoad and return Glyph object.)r   rD   rN   rO   r>   r^   r5   r5   r6   r\   0  s   
zLayer.loadGlyphc                 C  s0   || j v rtd| dt| | j |< }|S )z=Creates and returns new Glyph object in this layer with name.r$   r%   )r>   r/   r   r^   r5   r5   r6   newGlyph8  s   
zLayer.newGlyphnewNamec                 C  sH   ||krdS |s|| j v rtd| d| |}||_|| j |< dS )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%   )r>   r/   rv   r1   )rG   r   r   r   r4   r5   r5   r6   renameGlyph?  s   	
zLayer.renameGlyphc                 C  s   t  S )z?Returns a new Glyph instance.

        |defcon_compat|
        r   rF   r5   r5   r6   instantiateGlyphObjectR  s   zLayer.instantiateGlyphObjectsaveAsc                 C  s   | j }|st|j|D ]}|| q| D ]"\}}|tu r*|r)| |}nqt|j	t
| |j|||jd q|  ||  |rLd| _dS dS )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.
        )ZglyphObjectZdrawPointsFuncN)r>   r(   contents
differenceZdeleteGlyphr)   r-   r\   r   lib_fetch_glyph_identifiersZ
writeGlyphZ
drawPointsZwriteContentsZwriteLayerInforD   )rG   rI   r   rQ   r   r4   r5   r5   r6   writeY  s$   	

zLayer.writer=   r   dict[str, Any]c           	      C  s   i }| j D ]}|| | }||dksJ |||< qd| ji}d| j| jtkfd|i fd| ji ffD ]\}}}|jr@||krD|||< q4| jd urO| j|d< |S )Nr   r:   rQ   r   r?   )	r>   Zunstructurerv   r1   rB   r   r@   r9   r?   )	rG   r=   rQ   Z
glyph_namegdrt   r   r:   r5   r5   r6   _unstructurev  s"   




zLayer._unstructuredatarP   Type[Layer]c              
     sR   ||  dt fdd|  di  D |  d |  di t|  ddd	S )
Nr   c                   s   i | ]\}}|  |tqS r5   )	structurer   )rK   kvr=   r5   r6   rL     s    z$Layer._structure.<locals>.<dictcomp>rQ   r?   r   r:   F)r   rQ   r?   r   r:   )rr   r   r)   r   r   )r   rP   r=   r5   r   r6   
_structure  s   


zLayer._structure)r   rE   )TF)
r   r;   rI   r   rJ   rA   r:   rA   r   r8   )r   rU   r   rA   )r   r;   r   rE   )r   r;   r   r   )r   r;   r4   r   r   rE   )r   r`   )r   rb   )r   r;   rV   )r   r;   r:   ro   r   rp   )r   rs   )rt   r;   r   r   ).)rt   r;   r:   rx   r   rx   )r   rA   )r   rz   )r4   r   r   rE   )NTT)
r4   r   r   r   r   rA   r   rA   r   rE   )F)r   r;   r   r;   r   rA   r   rE   )r   r   )T)rI   r   r   rA   r   rE   )r=   r   r   r   )r   r   rP   r   r=   r   r   r8   )5r,   rk   __qualname____doc__r   r   r1   __annotations__r'   r7   r>   r?   r   r   r@   rB   rD   rH   classmethodrR   rT   r   __deepcopy__rY   r[   r]   r_   ra   rd   rn   rr   rM   r   rv   r/   propertyr   r   r   r   r:   r}   r   r   r   r\   r   r   r   r   r   staticmethodr   r5   r5   r5   r6   r8   C   sj   
 $















r8   r4   r   set[str]c                 C  s   t  }| jD ]}|jdur||j q| jD ]}|jdur$||j q| jD ]}|jdur5||j |D ]}|jdurD||j q7q(| jD ]}|jdurV||j qI|S )z*Returns all identifiers in use in a glyph.N)r(   ZanchorsZ
identifierr0   Z
guidelinesZcontoursZ
components)r4   ZidentifiersZanchorZ	guidelineZcontourZpointZ	componentr5   r5   r6   r     s,   








r   N)r   r   r   r    )r4   r   r   r   )'Z
__future__r   typingr   r   r   r   r   r   r	   r
   r   attrr   r   ZfontTools.ufoLib.glifLibr   ZufoLib2.constantsr   ZufoLib2.objects.glyphr   ZufoLib2.objects.libr   r   r   r   ZufoLib2.objects.miscr   r   r   r   ZufoLib2.typingr   Zcattrr   r-   r7   r8   r   r5   r5   r5   r6   <module>   s$    ,

   \