
    ^j0                    D   d Z ddlmZ ddlmZmZmZ ddlZddlm	Z	 dZ
	 ddlmZ ddlmZ d	Z
n# e$ r Y nw xY werdd
lmZmZ ddlmZ  G d de	j                  Z G d de	j                  Z G d de          Z G d de          Z G d de          ZddZdZdS )a
  This module defines the usage and creation of user defined fonts in Pyglet.

Previously, pyglet only supported font renderers that are built into the operating system, such as
``FreeType``, ``DirectWrite``, or ``Quartz``. However, there are situations in which a user may not want or need all the
features a font can provide. They just need to put characters in a particular order without the hassle of exporting
into a separate file.

The :py:class:`~pyglet.font.user.UserDefinedMappingFont` is provided for most use cases, which will allow you to
make an internal font that can be used where a ``font_name`` is required to identify a font.

A user defined font is also identified by its name. The name you choose should be unique to ensure it will not conflict
with a system font. For example, do not use `Arial`, as that will collide with Windows systems.

With :py:class:`~pyglet.font.user.UserDefinedMappingFont` you can pass a mapping of characters that point to your
:py:class:`~pyglet.image.ImageData`.

.. code-block:: python

    mappings={'c': my_image_data, 'b': my_image_data, 'a': my_image_data}

For more custom behavior, a dict-like object can be used, such as a class.

.. code-block:: python

    class MyCustomMapping:
        def get(self, char: str) -> ImageData | None:
            # return ImageData if a character is found.
            # return None if no character is found

    mappings = MyCustomMapping()

Once your font is created, you also must register it within pyglet to use it. This can be done through the
 :py:func:`~pyglet.font.add_user_font` function.

When you register a user defined font, only those parameters will used to identify the font. If you have a font, but
want to have a ``italic`` enabled version. You must make a new instance of your font, but with the ``italic``
parameter set as ``True``. Same applies to the ``size`` parameter. The ``weight`` parameter can also be provided as
a string.

Scaling
=======
By default, user font's will not be scaled. In most use cases, you have a single font at a specific size that you
want to use.

There are cases where a user may want to scale their font to be used at any size. We provide the following function:
:py:func:`~pyglet.font.user.get_scaled_user_font`. By providing the user defined font instance, and a new size, you will
get back a new font instance that is scaled to the new size. This new instance must also be registered the same way as
the base font.

When specifying the ``size`` parameter, that value is used to determine the ratio of scaling between the new size. So
if your base font is a size of 12, creating a scaled version at size 24 will be double the size of the base.

.. warning::

    The ``PIL`` library is a required dependency to use the scaling functionality.

.. versionadded:: 2.0.15
    )annotations)TYPE_CHECKINGClassVarProtocolN)baseF)Image)
ResamplingT)GlyphGlyphPosition)	ImageDatac                  (     e Zd Zd
 fdZdd	Z xZS )UserDefinedGlyphRendererfontUserDefinedFontBasereturnNonec                X    t                                          |           || _        d S N)super__init___font)selfr   	__class__s     K/home/agentuser/manim-venv/lib/python3.11/site-packages/pyglet/font/user.pyr   z!UserDefinedGlyphRenderer.__init__Q   s&    


    
image_datar   r
   c                   | j         j        r,t          j        d|j        |j        f|                                                    d                    }| j         j        | j         j	        z  }|
                    t          |j        |z            t          |j        |z            ft          j                  }t          j                            |j        |j        d|                                          }| j                             |          }|                    | j         j         d|j                   nA| j                             |          }|                    | j         j         d|j                   |S )NRGBAr   )r   _scalingr   	frombyteswidthheightget_image_dataget_datasize
_base_sizeresizeintr	   NEARESTpygletimager   tobytescreate_glyphset_bearingsdescent)r   r   image_originalscale_ratioimage_resized	new_imageglyphs          r   renderzUserDefinedGlyphRenderer.renderU   sW   : 	I"_Vj6F
HY5Z-7-F-F-H-H-Q-QRX-Y-Y[ [N*/DJ,AAK*113z7G+7U3V3V36z7H;7V3W3W3YZdZln nM..}/BMDX/5}7L7L7N7NP PIJ++I66E
 22A}7JKKKKJ++J77E
 22Az7GHHHr   )r   r   r   r   )r   r   r   r
   )__name__
__module____qualname__r   r5   __classcell__r   s   @r   r   r   P   sQ                    r   r   c                  b     e Zd ZU dZeZded<   	 	 dd fdZed d            Z	d!dZ
d"dZ xZS )#r   zMUsed as a base for all user defined fonts.

    .. versionadded:: 2.0.15
    z"ClassVar[type[base.GlyphRenderer]]glyph_renderer_classNnormalF`   namestrdefault_charr%   r(   ascent
int | Noner/   weightitalicboolstretchdpilocale
str | Noner   r   c                    t                                                       || _        || _        || _        || _        || _        || _        || _        || _	        |	| _
        |
| _        d| _        d| _        dS )a  Initialize a user defined font.

        Args:
            name:
                Name of the font. Used to identify the font. Must be unique to ensure it does not
                collide with any system fonts.
            default_char:
                If a character in a string is not found in the font, it will use this as fallback.
            size:
                Font size, usually in pixels.
            ascent:
                Maximum ascent above the baseline, in pixels. If None, the image height is used.
            descent:
                Maximum descent below the baseline, in pixels. Usually negative.
            weight:
                The font weight, as a string. Defaults to "normal".
            italic:
                If True, this font will be used when ``italic`` is enabled for the font name.
            stretch:
                If True, this font will be used when ``stretch`` is enabled for the font name.
            dpi:
                The assumed resolution of the display device, for the purposes of determining the pixel size of the
                font. Use a default of 96 for standard sizing.
            locale:
                Used to specify the locale of this font.
        r   FN)r   r   _namerA   rB   r/   r%   rD   rE   rG   rH   rI   r&   r   )r   r?   rA   r%   rB   r/   rD   rE   rG   rH   rI   r   s              r   r   zUserDefinedFontBase.__init__m   st    < 	
(	r   c                    | j         S r   )rL   r   s    r   r?   zUserDefinedFontBase.name   s
    zr   	base_sizec                R    t           sd}t          |          || _        d| _        d S )Nz5PIL is not installed. User Font Scaling requires PIL.T)SCALING_ENABLEDImportErrorr&   r   )r   rO   msgs      r   enable_scalingz"UserDefinedFontBase.enable_scaling   s/     	#ICc"""#r   c                L    | j         s|                     |           | _         dS dS )zInitialize the glyph renderer and cache it on the Font.

        This way renderers for fonts that have been loaded but not used will not have unnecessary loaders.
        N)_glyph_rendererr<   rN   s    r   _initialize_rendererz(UserDefinedFontBase._initialize_renderer   s8    
 # 	C#'#<#<T#B#BD   	C 	Cr   NNr=   FFr>   N)r?   r@   rA   r@   r%   r(   rB   rC   r/   rC   rD   r@   rE   rF   rG   rF   rH   r(   rI   rJ   r   r   )r   r@   rO   r(   r   r   )r   r   )r6   r7   r8   __doc__r   r<   __annotations__r   propertyr?   rT   rW   r9   r:   s   @r   r   r   f   s           @XWWWW mquy+ + + + + + +Z    X   C C C C C C C Cr   r   c                      e Zd ZdZdS )UserDefinedFontExceptionz+An exception related to user font creation.N)r6   r7   r8   rZ    r   r   r^   r^      s        5555r   r^   c                      e Zd ZddZdS )DictLikeObjectcharr@   r   ImageData | Nonec                    d S r   r_   )r   rb   s     r   getzDictLikeObject.get   s    r   N)rb   r@   r   rc   )r6   r7   r8   re   r_   r   r   ra   ra      s(             r   ra   c                  J     e Zd ZU dZded<   	 	 d!d" fdZd# fdZd$d Z xZS )%UserDefinedMappingFontznThe class allows the creation of user defined fonts from a set of mappings.

    .. versionadded:: 2.0.15
    r   rV   Nr=   Fr>   r?   r@   rA   r%   r(   mappingsra   rB   rC   r/   rD   rE   rF   rG   rH   rI   rJ   r   r   c                    || _         | j                             |          }|sd| d}t          |          ||||j        }|d}t	                                          ||||||||	|
|
  
         dS )a  Initialize the default parameters of your font.

        Args:
            name:
                Name of the font. Must be unique to ensure it does not collide with any system fonts.
            default_char:
                If a character in a string is not found in the font, it will use this as fallback.
            size:
                Font size. Should be in pixels. This value will affect scaling if enabled.
            mappings:
                A dict or dict-like object with a ``get`` function.
                The ``get`` function must take a string character, and output :py:class:`~pyglet.image.ImageData` if
                found. It also must return ``None`` if no character is found.
            ascent:
                Maximum ascent above the baseline, in pixels. If None, the image height is used.
            descent:
                Maximum descent below the baseline, in pixels. Usually negative.
            weight:
                The font weight, as a string. Defaults to "normal".
            italic:
                If ``True``, this font will be used when ``italic`` is enabled for the font name.
            stretch:
                If ``True``, this font will be used when ``stretch`` is enabled for the font name.
            dpi:
                The assumed resolution of the display device, for the purposes of determining the pixel size of the
                font. Use a default of 96 for standard sizing.
            locale:
                Used to specify the locale of this font.
        zDefault character 'z"' must exist within your mappings.Nr   )rh   re   r^   r"   r   r   )r   r?   rA   r%   rh   rB   r/   rD   rE   rG   rH   rI   default_imagerS   r   s                 r   r   zUserDefinedMappingFont.__init__   s    @ !)),77 	0XXXXC*3///>W_~&-|T67FFT[]`bhiiiiir   rO   c                    t                                          |           |                     | j                  \  }}|d         j        | _        d| _        dS )zEnables scaling the font size.

        Args:
            base_size:
                The base size is used to calculate the ratio between new sizes and the original.
        r   N)r   rT   
get_glyphsrA   r"   rB   r/   )r   rO   glyphsoffsetsr   s       r   rT   z%UserDefinedMappingFont.enable_scaling   sN     	y)))//$*;<<Qi&r   text'tuple[list[Glyph], list[GlyphPosition]]c           	        |                                   g }g }t          j        |          D ]}|dk    rd}|| j        vrF| j                            |          }|s| j        }n"| j                            |          | j        |<   |	                    | j        |                    |	                    t          j
        dddd                     ||fS )zCreate and return a list of Glyphs for `text`.

        If any characters do not have a known glyph representation in this font, a substitution will be made with
        the ``default_char``.
        	 r   )rW   r   get_grapheme_clustersrm   rh   re   rA   rV   r5   appendr   )r   ro   rn   rm   cr   s         r   rl   z!UserDefinedMappingFont.get_glyphs   s     	!!###+D11 	; 	;A Dyy##!]..q11
! M)AA%)%9%@%@%L%LDKNMM$+a.)))NN4-aAq99::::wr   rX   )r?   r@   rA   r@   r%   r(   rh   ra   rB   rC   r/   rC   rD   r@   rE   rF   rG   rF   rH   r(   rI   rJ   r   r   rY   )ro   r@   r   rp   )	r6   r7   r8   rZ   r[   r   rT   rl   r9   r:   s   @r   rg   rg      s           .--- kpGK,j ,j ,j ,j ,j ,j ,j\
 
 
 
 
 
       r   rg   	font_baser%   r(   r   c                    t          | j        | j        || j        | j        | j        | j        | j        | j        | j	        | j
                  }|                    | j                   |S )a  This function will return a new font instance which can scale it's size based off the original base font.

    .. note:: The scaling functionality requires the PIL library to be installed.

    .. versionadded:: 2.0.15

    Args:
        font_base:
            The base font object to create a new size from.
        size:
            The new font size. This will be scaled based on the ratio between the base size and the new size.
    )rg   r?   rA   rh   rB   r/   rD   rE   rG   rH   rI   rT   r%   )rw   r%   new_fonts      r   get_scaled_user_fontrz     sh     &ini6LdT]Tf&/&6	8I9K[]f]m&/&7	HXZ ZH IN+++Or   )r   r^   rg   rz   )rw   rg   r%   r(   r   rg   )rZ   
__future__r   typingr   r   r   r*   pyglet.fontr   rQ   PILr   	PIL.Imager	   rR   pyglet.font.baser
   r   pyglet.imager   GlyphRendererr   Fontr   	Exceptionr^   ra   rg   rz   __all__r_   r   r   <module>r      s  9 9t # " " " " " 4 4 4 4 4 4 4 4 4 4       	$$$$$$OO 	 	 	D	  '55555555&&&&&&    t1   ,FC FC FC FC FC$) FC FC FCP6 6 6 6 6y 6 6 6    X   
W W W W W0 W W Wt   *s   / 77