
    \
j\'                         d Z ddlZddlmZ  G d de          Z G d d          Z G d d	          Z G d
 d          Z G d d          Z	dS )a  Group multiple small images into larger textures.

This module is used by :py:mod:`pyglet.resource` to efficiently pack small
images into larger textures.  :py:class:`~pyglet.image.atlas.TextureAtlas` maintains one texture;
:py:class:`TextureBin` manages a collection of atlases of a given size.

Example usage::

    # Load images from disk
    car_image = pyglet.image.load('car.png')
    boat_image = pyglet.image.load('boat.png')

    # Pack these images into one or more textures
    bin = TextureBin()
    car_texture = bin.add(car_image)
    boat_texture = bin.add(boat_image)

The result of :py:meth:`TextureBin.add` is a :py:class:`TextureRegion`
containing the image. Once added, an image cannot be removed from a bin (or an 
atlas); nor can a list of images be obtained from a given bin or atlas -- it is 
the application's responsibility to keep track of the regions returned by the
``add`` methods.

.. versionadded:: 1.1
    N)GL_RGBAc                       e Zd ZdZdS )AllocatorExceptionzSThe allocator does not have sufficient free space for the requested
    image size.N)__name__
__module____qualname____doc__     L/DATA/AppData/hermes/venv/lib/python3.11/site-packages/pyglet/image/atlas.pyr   r   C   s         Dr   r   c                   $    e Zd ZdZd Zd Zd ZdS )_Stripxy
max_heighty2c                 >    d| _         || _        || _        || _        d S Nr   r   )selfr   r   s      r   __init__z_Strip.__init__L   s"    $r   c                     |dk    r|dk    sJ || j         k    sJ | j        | j        }}| xj        |z  c_        t          | j        |z   | j                  | _        ||fS r   )r   r   r   maxr   )r   widthheightr   r   s        r   addz
_Strip.addR   si    qyyVaZZZ'((((vtv1%dfvotw//!tr   c                 .    | j         | j        z
  | _        d S )N)r   r   r   r   s    r   compactz_Strip.compact[   s    'DF*r   N)r   r   r   	__slots__r   r   r   r
   r   r   r   r   I   sF        ,I    + + + + +r   r   c                   .    e Zd ZdZdZd Zd Zd Zd ZdS )	Allocatorai  Rectangular area allocation algorithm.

    Initialise with a given ``width`` and ``height``, then repeatedly
    call `alloc` to retrieve free regions of the area and protect that
    area from future allocations.

    `Allocator` uses a fairly simple strips-based algorithm.  It performs best
    when rectangles are allocated in decreasing height order.
    )r   r   strips	used_areac                 x    |dk    r|dk    sJ || _         || _        t          d|          g| _        d| _        dS )zCreate an `Allocator` of the given size.

        :Parameters:
            `width` : int
                Width of the allocation region.
            `height` : int
                Height of the allocation region.

        r   N)r   r   r   r#   r$   )r   r   r   s      r   r   zAllocator.__init__k   sG     qyyVaZZZ'
a(()r   c                     | j         D ]K}| j        |j        z
  |k    r6|j        |k    r+| xj        ||z  z  c_        |                    ||          c S L| j        |k    r| j        |j        z
  |k    ry| xj        ||z  z  c_        |                                 t          |j        | j        |j        z
            }| j         
                    |           |                    ||          S t          d| ||fz            )a  Get a free area in the allocator of the given size.

        After calling `alloc`, the requested area will no longer be used.
        If there is not enough room to fit the given area `AllocatorException`
        is raised.

        :Parameters:
            `width` : int
                Width of the area to allocate.
            `height` : int
                Height of the area to allocate.

        :rtype: int, int
        :return: The X and Y coordinates of the bottom-left corner of the
            allocated region.
        z!No more space in %r for box %dx%d)r#   r   r   r   r$   r   r   r   r   r   appendr   )r   r   r   stripnewstrips        r   alloczAllocator.alloc{   s   " [ 	0 	0EzEG#u,,1AV1K1K%&.0yy/////:4;#9V#C#CNNefn,NNMMOOOeheh(>??HKx(((<<v... !DeU[G\!\]]]r   c                 J    | j         t          | j        | j        z            z  S )zGet the fraction of area already allocated.

        This method is useful for debugging and profiling only.

        :rtype: float
        )r$   floatr   r   r   s    r   	get_usagezAllocator.get_usage   s"     ~dj4;&> ? ???r   c                 |    | j         sdS | j         d         j        | j        z  }d| j        t	          |          z  z
  S )zGet the fraction of area that's unlikely to ever be used, based on
        current allocation behaviour.

        This method is useful for debugging and profiling only.

        :rtype: float
        g        g      ?)r#   r   r   r$   r,   )r   possible_areas     r   get_fragmentationzAllocator.get_fragmentation   sB     { 	3B*TZ7T^eM&:&::::r   N)	r   r   r   r	   r    r   r*   r-   r1   r
   r   r   r"   r"   _   sg          9I   ^ ^ ^>@ @ @; ; ; ; ;r   r"   c                   "    e Zd ZdZddZddZdS )	TextureAtlasz&Collection of images within a texture.   c                    t           j                                        }t          ||          }t          ||          }t           j        j                            ||t          d          | _        t          ||          | _	        dS )zCreate a texture atlas of the given size.

        :Parameters:
            `width` : int
                Width of the underlying texture.
            `height` : int
                Height of the underlying texture.

        T)	rectangleN)
pygletimageget_max_texture_sizeminTexturecreater   texturer"   	allocator)r   r   r   max_texture_sizes       r   r   zTextureAtlas.__init__   sq     "<<<>>E+,,V-..|+225&'UY2ZZ"5&11r   r   c                 
   | j                             |j        |dz  z   |j        |dz  z             \  }}| j                            |||z   ||z   d           | j                            ||z   ||z   |j        |j                  S )a  Add an image to the atlas.

        This method will fail if the given image cannot be transferred
        directly to a texture (for example, if it is another texture).
        :py:class:`~pyglet.image.ImageData` is the usual image type for this method.

        `AllocatorException` will be raised if there is no room in the atlas
        for the image.

        :Parameters:
            `img` : `~pyglet.image.AbstractImage`
                The image to add.
            `border` : int
                Leaves specified pixels of blank space around
                each image added to the Atlas.

        :rtype: :py:class:`~pyglet.image.TextureRegion`
        :return: The region of the atlas containing the newly added image.
           r   )r>   r*   r   r   r=   	blit_into
get_region)r   imgborderr   r   s        r   r   zTextureAtlas.add   s    ( ~##CIq$8#*vax:OPP1sAfHah:::|&&qx639cjQQQr   Nr4   r4   r   r   r   r   r	   r   r   r
   r   r   r3   r3      sH        002 2 2 2"R R R R R Rr   r3   c                   "    e Zd ZdZddZddZdS )	
TextureBinzCollection of texture atlases.

    :py:class:`~pyglet.image.atlas.TextureBin` maintains a collection of texture atlases, and creates new
    ones as necessary to accommodate images added to the bin.
    r4   c                     t           j                                        }t          ||          | _        t          ||          | _        g | _        dS )a  Create a texture bin for holding atlases of the given size.

        :Parameters:
            `texture_width` : int
                Width of texture atlases to create.
            `texture_height` : int
                Height of texture atlases to create.
            `border` : int
                Leaves specified pixels of blank space around
                each image added to the Atlases.

        N)r7   r8   r9   r:   texture_widthtexture_heightatlases)r   rL   rM   r?   s       r   r   zTextureBin.__init__   sI     "<<<>> 0@AA!.2BCCr   r   c                 t   t          | j                  D ]Z}	 |                    ||          c S # t          $ r3 |j        dk     r%|j        dk     r| j                            |           Y Ww xY wt          | j        | j	                  }| j        
                    |           |                    ||          S )a  Add an image into this texture bin.

        This method calls `TextureAtlas.add` for the first atlas that has room
        for the image.

        `AllocatorException` is raised if the image exceeds the dimensions of
        ``texture_width`` and ``texture_height``.

        :Parameters:
            `img` : `~pyglet.image.AbstractImage`
                The image to add.
            `border` : int
                Leaves specified pixels of blank space around
                each image added to the Atlas.

        :rtype: :py:class:`~pyglet.image.TextureRegion`
        :return: The region of an atlas containing the newly added image.
        @   )listrN   r   r   r   r   remover3   rL   rM   r'   )r   rD   rE   atlass       r   r   zTextureBin.add   s    & $,'' 	/ 	/E/yyf-----% / / / 9r>>cj2ooL''.../ T/1DEEE"""yyf%%%s   0:A-,A-NrF   rG   rH   r
   r   r   rJ   rJ      sF            $& & & & & &r   rJ   )
r	   r7   	pyglet.glr   	Exceptionr   r   r"   r3   rJ   r
   r   r   <module>rV      s  H 4       	 	 	 	 	 	 	 	+ + + + + + + +,P; P; P; P; P; P; P; P;f*R *R *R *R *R *R *R *RZ8& 8& 8& 8& 8& 8& 8& 8& 8& 8&r   