Commits

Marcus von Appen  committed 9e4aac0

- added module documentation
- added tutorial documents

  • Participants
  • Parent commits 0d306a6

Comments (0)

Files changed (33)

File doc/modules/images/coordinate_rhs.dia

Binary file added.

File doc/modules/images/coordinate_rhs.png

Added
New image

File doc/modules/images/copprocessing.dia

Binary file added.

File doc/modules/images/copprocessing.png

Added
New image

File doc/modules/images/ebs.dia

Binary file added.

File doc/modules/images/ebs.png

Added
New image

File doc/modules/index.rst

+API reference
+=============
+This is the core documentation of the various modules, classes and functions
+PySDL2 offers. If you want to have a quick overview about the modules, use the
+:ref:`modindex`. If you just want to look up a specific class, method or
+function, use the :ref:`genindex` or :ref:`search`.
+
+.. toctree::
+   :maxdepth: 2
+
+   sdl2.rst
+   sdl2_sdlimage.rst
+   sdl2_sdlttf.rst
+   sdl2ext.rst

File doc/modules/sdl2.rst

+.. module:: sdl2
+   :synopsis: SDL2 library wrapper
+
+sdl2 - SDL2 library wrapper
+===========================
+The :mod:`sdl2` module is a :mod:`ctypes`-based wrapper around
+the SDL2 library. It wraps nearly all publicly accessible structures and
+functions of the SDL2 library to be accessible from Python code.
+
+A detailled documentation about the behaviour of the different functions
+can found within the `SDL2 documentation
+<http://wiki.libsdl.org/moin.cgi/CategoryAPI>`_.
+
+Missing interfaces
+------------------
+The following functions, classes, constants and macros of SDL2 are *not*
+available within :mod:`sdl2`. 
+
+* :c:data:`SDL_REVISION` and :c:data:`SDL_REVISION_NUMBER` from ``SDL_revision.h``
+* :c:data:`SDL_NAME()` from ``SDL_name.h``
+* :c:func:`SDL_MostSignificantBitIndex32` from ``SDL_bits.h``
+* Anything from ``SDL_main.h``
+* Anything from ``SDL_system.h``
+* Anything from ``SDL_assert.h``
+* Anything from ``SDL_thread.h``
+* Anything from ``SDL_atomic.h``
+* Anything from ``SDL_opengl.h``
+* Anything from ``SDL_mutex.h`` 
+
+Additional interfaces
+---------------------
+The following functions, classes, constants and macros are are *not* part of
+SDL2, but were introduced by :mod:`sdl2`.
+
+.. function:: sdl2.rwops.rw_from_object(obj : object) -> SDL_RWops
+
+   Creates a SDL_RWops from any Python object. The Python object must at least
+   support the following methods:
+
+   read(length) -> data
+   
+     length is the size in bytes to be read. A call to len(data) must
+     return the correct amount of bytes for the data, so that
+     len(data) / [size in bytes for a single element from data] returns
+     the amount of elements. Must raise an error on failure.
+
+   seek(offset, whence) -> int
+   
+     offset denotes the offset to move the read/write pointer of the
+     object to. whence indicates the movement behaviour and can be one
+     of the following values:
+                
+     * RW_SEEK_SET - move to offset from the start of the file
+     * RW_SEEK_CUR - move by offset from the relative location
+     * RW_SEEK_END - move to offset from the end of the file
+     
+     If it could not move read/write pointer to the desired location,
+     an error must be raised.
+
+   tell() -> int
+   
+     Must return the current offset. This method must only be
+     provided, if seek() does not return any value.
+
+   close() -> None
+   
+     Closes the object(or its internal data access methods). Must raise
+     an error on failure.
+
+   write(data) -> None
+   
+     Writes the passed data(which is a string of bytes) to the object.
+     Must raise an error on failure.
+
+     .. note::
+
+        The write() method is optional and only necessary, if the passed
+        object should be able to write data.
+
+   The returned :class:`sdl2.rwops.SDL_RWops` is a pure Python object and
+   **must not** be freed via :func:`sdl2.rwops.SDL_FreeRW()`.

File doc/modules/sdl2_sdlimage.rst

+.. module:: sdl2.sdlimage
+   :synopsis: SDL2_image library wrapper
+
+sdl2.sdlimage - SDL2_image library wrapper
+==========================================
+The :mod:`sdl2.sdlimage` module is a :mod:`ctypes`-based wrapper
+around the SDL2_image library. It wraps nearly all publicly accessible
+structures and functions of the SDL2_image library to be accessible from
+Python code.
+
+A detailled documentation about the behaviour of the different functions
+can found within the `SDL2_image documentation
+<http://www.libsdl.org/projects/SDL_image/docs/index.html>`_.

File doc/modules/sdl2_sdlttf.rst

+.. module:: sdl2.sdlttf
+   :synopsis: SDL2_ttf library wrapper
+
+sd2.sdlttf - SDL2_ttf library wrapper
+=====================================
+The :mod:`sdl2.sdlttf` module is a :mod:`ctypes`-based wrapper
+around the SDL2_image library. It wraps nearly all publicly accessible
+structures and functions of the SDL2_ttf library to be accessible from
+Python code.
+
+A detailled documentation about the behaviour of the different functions
+can found within the `SDL2_ttf documentation
+<http://www.libsdl.org/projects/SDL_ttf/docs/index.html>`_.

File doc/modules/sdl2ext.rst

+.. module:: sdl2.ext
+   :synopsis: Video and graphics routines
+
+sdl2.ext - Extended video and graphics routines
+===============================================
+The :mod:`sdl2.ext` module contains various classes and methods
+for creating, processing and manipulating on-screen graphics.
+
+Submodules
+----------
+All classes and methods of the modules below are directly included in
+the :mod:`sdl2.ext` module.
+
+.. toctree::
+   :maxdepth: 1
+
+   sdl2ext_algorithms.rst
+   sdl2ext_array.rst
+   sdl2ext_color.rst
+   sdl2ext_colorpalettes.rst
+   sdl2ext_common.rst
+   sdl2ext_compat.rst
+   sdl2ext_draw.rst
+   sdl2ext_ebs.rst
+   sdl2ext_events.rst
+   sdl2ext_font.rst
+   sdl2ext_gui.rst
+   sdl2ext_image.rst
+   sdl2ext_particles.rst
+   sdl2ext_pixelaccess.rst
+   sdl2ext_resources.rst
+   sdl2ext_scene.rst
+   sdl2ext_sprite.rst
+   sdl2ext_window.rst

File doc/modules/sdl2ext_algorithms.rst

+.. module:: sdl2.ext.algorithms
+   :synopsis: Common algorithms
+.. currentmodule:: sdl2.ext.algorithms
+
+sdl2.ext.algorithms - Common algorithms
+=======================================
+
+.. function:: cohensutherland(left : int, top : int, right : int, \
+   bottom : int, x1 : int, y1 : int, x2 : int, y2 : int) -> int, int, int, int
+
+   This implements the Cohen-Sutherland line clipping
+   algorithm. ``left``, ``top``, ``right`` and ``bottom`` denote the
+   clipping area, into which the line defined by ``x1``, ``y1`` (start
+   point) and ``x2``, ``y2`` (end point) will be clipped.
+
+   If the line does not intersect with the rectangular clipping area,
+   four ``None`` values will be returned as tuple. Otherwise a tuple of
+   the clipped line points will be returned in the form ``(cx1, cy1,
+   cx2, cy2)``.
+
+.. function:: liangbarsky(left : int, top : int, right : int, \
+   bottom : int, x1 : int, y1 : int, x2 : int, y2 : int) -> int, int, int, int
+
+   This implements the Liang-Barsky line clipping algorithm. ``left``,
+   ``top``, ``right`` and ``bottom`` denote the clipping area, into
+   which the line defined by ``x1``, ``y1`` (start point) and ``x2``,
+   ``y2`` (end point) will be clipped.
+
+   If the line does not intersect with the rectangular clipping area,
+   four ``None`` values will be returned as tuple. Otherwise a tuple of
+   the clipped line points will be returned in the form ``(cx1, cy1,
+   cx2, cy2)``.
+
+.. function:: clipline(left : int, top : int, right : int, \
+   bottom : int, x1 : int, y1 : int, x2 : int, \
+   y2 : int[,method=liangbarsky]) -> int, int, int, int
+
+   Clips a line to a rectangular area.

File doc/modules/sdl2ext_array.rst

+.. module:: sdl2.ext.array
+   :synopsis: Conversion routines for sequences.
+
+sdl2.ext.array - Converting sequences
+=====================================
+This module provides various functions and classes to access sequences and
+buffer-style objects in different ways. It also provides conversion routines
+to improve the interoperability of sequences with :mod:`ctypes` data types.
+
+Providing read-write access for sequential data
+-----------------------------------------------
+Two classes allow you to access sequential data in different ways. The
+:class:`CTypesView` provides byte-wise access to iterable objects and allows
+you to convert the object representation to matching byte-widths for
+:mod:`ctypes` or other modules.
+
+Depending on the the underlying object and the chosen size of each particular
+item of the object, the :class:`CTypesView` allows you to operate directly
+on different representations of the object's contents. ::
+
+    >>> text = bytearray("Hello, I am a simple ASCII string!")
+    >>> ctview = CTypesView(text, itemsize=1)
+    >>> ctview.view[0] = 0x61
+    >>> print(text)
+    aello, I am a simple ASCII string!"
+    >>> ctview.to_uint16()[3] = 0x6554
+    >>> print(text)
+    aello,Te am a simple ASCII string!"
+
+The snippet above provides a single-byte sized view on a :func:`bytearray`
+object. Afterwards, the first item of the view is changed, which causes a
+change on the :func:`bytearray`, on the first item as well, since both, the
+:class:`CTypesView` and the :func:`bytearray` provide a byte-wise access to
+the contents.
+
+By using :meth:`CTypesView.to_uint16()`, we change the access representation to
+a 2-byte unsigned integer :mod:`ctypes` pointer and change the fourth 2-byte
+value, *I* to something else. ::
+
+    >>> text = bytearray("Hello, I am a simple ASCII string!")
+    >>> ctview = CTypesView(text, itemsize=2)
+    >>> ctview.view[0] = 0x61
+    >>> print(text)
+    aello, I am a simple ASCII string!"
+    >>> ctview.to_uint16()[3] = 0x6554
+    >>> print(text)
+    aello,Te am a simple ASCII string!"
+
+If the encapsuled object does not provide a (writeable) :func:`buffer`
+interface, but is iterable, the :class:`CTypesView` will create an
+internal copy of the object data using Python's :mod:`array` module and
+perform all operations on that copy. ::
+
+    >>> mylist = [18, 52, 86, 120, 154, 188, 222, 240]
+    >>> ctview = CTypesView(mylist, itemsize=1, docopy=True)
+    >>> print(ctview.object)
+    array('B', [18, 52, 86, 120, 154, 188, 222, 240])
+    >>> ctview.view[3] = 0xFF
+    >>> print(mylist)
+    [18, 52, 86, 120, 154, 188, 222, 240]
+    >>> print(ctview.object)
+    array('B', [18, 52, 86, 255, 154, 188, 222, 240])
+
+As for directly accessible objects, you can define your own itemsize to
+be used. If the iterable does not provide a direct byte access to their
+contents, this won't have any effect except for resizing the item
+widths. ::
+
+    >>> mylist = [18, 52, 86, 120, 154, 188, 222, 240]
+    >>> ctview = CTypesView(mylist, itemsize=4, docopy=True)
+    >>> print(ctview.object)
+    array('I', [18L, 52L, 86L, 120L, 154L, 188L, 222L, 240L])
+
+Accessing data over multiple dimensions
+---------------------------------------
+
+The second class, :class:`MemoryView` provides an interface to access
+data over multiple dimensions. You can layout and access a simple
+byte stream over e.g. two or more axes, providing a greater flexibility
+for functional operations and complex data.
+
+Let's assume, we are reading image data from a file stream into some buffer
+object and want to access and manipulate the image data. Images feature two
+axes, one being the width, the other being the height, defining a rectangular
+graphics area.
+
+When we read all data from the file, we have an one-dimensional view of the
+image graphics. The :class:`MemoryView` allows us to define a
+two-dimensional view over the image graphics, so that we can operate on
+both, rows and columns of the image. ::
+
+    >>> imagedata = bytearray("some 1-byte graphics data")
+    >>> view = MemoryView(imagedata, 1, (5, 5))
+    >>> print(view)
+    [[s, o, m, e,  ], [1, -, b, y, t], [e,  , g, r, a], [p, h, i, c, s], [ , d, a, t, a]]
+    >>> for row in view:
+    ...     print(row)
+    ...
+    [s, o, m, e,  ]
+    [1, -, b, y, t]
+    [e,  , g, r, a]
+    [p, h, i, c, s]
+    [ , d, a, t, a]
+    >>> for row in view:
+    ...    row[1] = "X"
+    ...    print row
+    ...
+    [s, X, m, e,  ]
+    [1, X, b, y, t]
+    [e, X, g, r, a]
+    [p, X, i, c, s]
+    [ , X, a, t, a]
+    >>> print(imagedata)
+    sXme 1XbyteXgrapXics Xata
+
+On accessing a particular dimension of a :class:`MemoryView`, a new
+:class:`MemoryView` is created, if it does not access a single
+element. ::
+
+    >>> firstrow = view[0]
+    >>> type(firstrow)
+    <class 'mule.array.MemoryView'>
+    >>> type(firstrow[0])
+    <type 'bytearray'>
+
+A :class:`MemoryView` features, similar to Python's builtin
+:class:`memoryview`, dimensions and strides, accessible via the
+:attr:`MemoryView.ndim` and :attr:`MemoryView.strides` attributes.
+
+    >>> view.ndim
+    2
+    >>> view.strides
+    (5, 5)
+
+The :attr:`MemoryView.strides`, which have to be passed on creating a
+new :class:`MemoryView`, define the layout of the data over different
+dimensions. In the example above, we created a 5x5 two-dimensional view
+to the image graphics. ::
+
+    >>> twobytes = MemoryView(imagedata, 2, (5, 1))
+    >>> print(twobytes)
+    [[sX, me,  1, Xb, yt], [eX, gr, ap, Xi, cs]]
+
+
+Array API
+---------
+
+.. class:: CTypesView(obj : iterable[, itemsize=1[, docopy=False[, objsize=None]]])
+
+   A proxy class for byte-wise accessible data types to be used in
+   ctypes bindings. The CTypesView provides a read-write access to
+   arbitrary objects that are iterable.
+
+   In case the object does not provide a :func:`buffer()` interface for
+   direct access, the CTypesView can copy the object's contents into an
+   internal buffer, from which data can be retrieved, once the necessary
+   operations have been performed.
+
+   Depending on the item type stored in the iterable object, you might
+   need to provide a certain *itemsize*, which denotes the size per
+   item in bytes. The *objsize* argument might be necessary of iterables,
+   for which len() does not return the correct amount of objects or is not
+   implemented.
+
+   .. attribute:: bytesize
+
+      Returns the length of the encapsuled object in bytes.
+
+   .. attribute:: is_shared
+
+      Indicates, if changes on the CTypesView data effect the encapsuled
+      object directly. if not, this means that the object was copied
+      internally and needs to be updated by the user code outside of the
+      CTypesView.
+
+   .. attribute:: object
+
+      The encapsuled object.
+
+   .. attribute:: view
+
+      Provides a read-write aware view of the encapsuled object data
+      that is suitable for usage from :mod:`ctypes`.
+
+   .. method:: to_bytes() -> ctypes.POINTER
+
+      Returns a byte representation of the encapsuled object. The return
+      value allows a direct read-write access to the object data, if it
+      is not copied. The :func:`ctypes.POINTER` points to an array of
+      :class:`ctypes.c_ubyte`.
+
+   .. method:: to_uint16() -> ctypes.POINTER
+
+      Returns a 16-bit representation of the encapsuled object. The return
+      value allows a direct read-write access to the object data, if it
+      is not copied. The :func:`ctypes.POINTER` points to an array of
+      :class:`ctypes.c_ushort`.
+
+   .. method:: to_uint32() -> ctypes.POINTER
+
+      Returns a 32-bit representation of the encapsuled object. The return
+      value allows a direct read-write access to the object data, if it
+      is not copied. The :func:`ctypes.POINTER` points to an array of
+      :class:`ctypes.c_uint`.
+
+   .. method:: to_uint64() -> ctypes.POINTER
+
+      Returns a 64-bit representation of the encapsuled object. The return
+      value allows a direct read-write access to the object data, if it
+      is not copied. The :func:`ctypes.POINTER` points to an array of
+      :class:`ctypes.c_ulonglong`.
+
+.. class:: MemoryView(source : object, itemsize : int, strides : tuple[, getfunc=None[, setfunc=None[, srcsize=None]]])
+
+   The :class:`MemoryView` provides a read-write access to arbitrary
+   data objects, which can be indexed.
+
+   *itemsize* denotes the size of a single item. *strides* defines
+   the dimensions and the length (n items * *itemsize*) for each
+   dimension. *getfunc* and *setfunc* are optional parameters to
+   provide specialised read and write access to the underlying
+   *source*. *srcsize* can be used to provide the correct source
+   size, if ``len(source)`` does not return the absolute size of the
+   source object in all dimensions.
+
+   .. note::
+
+      The MemoryView is a pure Python-based implementation and makes
+      heavy use of recursion for multi-dimensional access. If you aim
+      for speed on accessing a n-dimensional object, you want to
+      consider using a specialised library such as numpy. If you need
+      n-dimensional access support, where such a library is not
+      supported, or if you need to provide access to objects, which do
+      not fulfill the requirements of that particular libray,
+      :class:`MemoryView` can act as solid fallback solution.
+
+   .. attribute:: itemsize
+
+      The size of a single item in bytes.
+
+   .. attribute:: ndim
+
+      The number of dimensions of the :class:`MemoryView`.
+
+   .. attribute:: size
+
+      The size in bytes of the underlying source object.
+
+   .. attribute:: source
+
+      The underlying data source.
+
+   .. attribute:: strides
+
+      A tuple defining the length in bytes for accessing all
+      elements in each dimension of the :class:`MemoryView`.
+
+.. function:: to_ctypes(dataseq : iterable, dtype[, mcount=0]) -> array, int
+
+    Converts an arbitrary sequence to a ctypes array of the specified
+    *dtype* and returns the ctypes array and amount of items as
+    two-value tuple.
+
+    Raises a :exc:`TypeError`, if one or more elements in the passed
+    sequence do not match the passed *dtype*.
+
+.. function:: to_list(dataseq : iterable) -> list
+
+   Converts a ctypes array to a list.
+
+.. function:: to_tuple(dataseq : iterable) -> tuple
+
+   Converts a ctypes array to a tuple.
+
+.. function:: create_array(obj : object, itemsize : int) -> array.array
+
+   Creates an :class:`array.array` based copy of the passed object.
+   *itemsize* denotes the size in bytes for a single element within
+   *obj*.

File doc/modules/sdl2ext_color.rst

+.. module:: sdl2.ext.color
+   :synopsis: RGB-based color handling.
+
+sdl2.ext.color - Color handling
+===============================
+
+.. class:: Color(r=255, g=255, b=255, a=255)
+
+   A simple RGBA-based color implementation. The Color class uses a
+   byte-wise representation of the 4 channels red, green, blue and alpha
+   transparency, so that the values range from 0 to 255. It allows basic
+   arithmetic operations, e.g. color addition or subtraction and
+   conversions to other color spaces such as HSV or CMY.
+
+   .. attribute:: r
+
+      The red channel value of the Color.
+
+   .. attribute:: g
+
+      The green channel value of the Color.
+
+   .. attribute:: b
+
+      The blue channel value of the Color.
+
+   .. attribute:: a
+
+      The alpha channel value of the Color.
+
+   .. attribute:: cmy
+
+      The CMY representation of the Color. The CMY components are in the
+      ranges C = [0, 1], M = [0, 1], Y = [0, 1]. Note that this will not
+      return the absolutely exact CMY values for the set RGB values in
+      all cases. Due to the RGB mapping from 0-255 and the CMY mapping
+      from 0-1 rounding errors may cause the CMY values to differ
+      slightly from what you might expect.
+
+   .. attribute:: hsla
+
+      The HSLA representation of the Color. The HSLA components are in
+      the ranges H = [0, 360], S = [0, 100], L = [0, 100], A = [0,
+      100]. Note that this will not return the absolutely exact HSL
+      values for the set RGB values in all cases. Due to the RGB mapping
+      from 0-255 and the HSL mapping from 0-100 and 0-360 rounding
+      errors may cause the HSL values to differ slightly from what you
+      might expect.
+
+   .. attribute:: hsva
+
+      The HSVA representation of the Color. The HSVA components are in
+      the ranges H = [0, 360], S = [0, 100], V = [0, 100], A = [0,
+      100]. Note that this will not return the absolutely exact HSV
+      values for the set RGB values in all cases. Due to the RGB mapping
+      from 0-255 and the HSV mapping from 0-100 and 0-360 rounding
+      errors may cause the HSV values todiffer slightly from what you
+      might expect.
+
+   .. attribute:: i1i2i3
+
+      The I1I2I3 representation of the Color. The I1I2I3 components are
+      in the ranges I1 = [0, 1], I2 = [-0.5, 0.5], I3 = [-0.5,
+      0.5]. Note that this will not return the absolutely exact I1I2I3
+      values for the set RGB values in all cases. Due to the RGB mapping
+      from 0-255 and the I1I2I3 from 0-1 rounding errors may cause the
+      I1I2I3 values to differ slightly from what you might expect.
+
+   .. method:: normalize() -> (float, float, float, float)
+
+      Returns the normalized RGBA values of the Color as floating point
+      values in the range [0, 1].
+
+   .. method:: __add__(self, color) -> Color
+               __sub__(self, color) -> Color
+               __mul__(self, color) -> Color
+               __div__(self, color) -> Color
+               __truediv__(self, color) -> Color
+               __mod__(self, color) -> Color
+   
+      Basic arithmetic functions for :class:`Color` values. The arithmetic
+      operations ``+, -, *, /, %`` are supported by the :class:`Color` class
+      and work on a per-channel basis. This means, that the operation ::
+      
+         color = color1 + color2
+      
+      is the same as ::
+      
+         color = Color()
+         color.r = min(color1.r + color2.r, 255)
+         color.g = min(color1.g + color2.g, 255)
+         ...
+      
+      The operations guarantee that the channel values stay in the allowed
+      range of [0, 255].
+
+.. function:: argb_to_color(v : int) -> Color
+              ARGB(v : int) -> Color
+
+   Converts an integer value to a Color, assuming the integer represents
+   a 32-bit ARGB value.
+
+.. function:: convert_to_color(v : object) -> Color
+              COLOR(v : object) -> Color
+
+   Tries to convert the passed value to a Color object. The value can be
+   an arbitrary Python object, which is passed to the different other
+   conversion functions. If one of them succeeds, the Color will be
+   returned to the caller. If none succeeds, a :exc:`ValueError` will be
+   raised.
+
+   If the color is an integer value, it is assumed to be in ARGB layout.
+
+.. function:: rgba_to_color(v : int) -> Color
+              RGBA(v : int) -> Color
+
+   Converts an integer value to a Color, assuming the integer represents
+   a 32-bit RGBA value.
+
+.. function:: is_rgb_color(v : object) -> bool
+
+   Checks, if the passed value is an item that could be converted to a
+   RGB color.
+
+.. function:: is_rgba_color(v : object) -> bool
+
+   Checks, if the passed value is an item that could be converted to a
+   RGBA color.
+
+.. function:: string_to_color(v : string) -> Color
+
+   Converts a hex color string or color name to a Color value. Supported
+   hex values are:
+
+   * #RGB
+   * #RGBA
+   * #RRGGBB
+   * #RRGGBBAA
+   * 0xRGB
+   * 0xRGBA
+   * 0xRRGGBB
+   * 0xRRGGBBAA

File doc/modules/sdl2ext_colorpalettes.rst

+.. module:: sdl2.ext.colorpalettes
+   :synopsis: Predefined sets of colors.
+
+sdl2.ext.colorpalettes - predefined sets of colors
+==================================================
+Indexed color palettes. Each palette is a tuple of
+:class:`sdl2.ext.color.Color` objects.
+
+The following palettes are currently available:
+
+================== ===================================================
+Palette Identifier Description
+================== ===================================================
+MONOPALETTE        1-bit monochrome palette (black and white).
+
+GRAY2PALETTE       2-bit grayscale palette with black, white and two
+                   shades of gray.
+GRAY4PALETTE       4-bit grayscale palette with black, white and 14
+                   shades shades of gray.
+GRAY8PALETTE       8-bit grayscale palette with black, white and 254
+                   shades shades of gray.
+RGB3PALETTE        3-bit RGB color palette with pure red, green and
+                   blue and their complementary colors as well as black
+                   and white.
+CGAPALETTE         CGA color palette.
+EGAPALETTE         EGA color palette.
+VGAPALETTE         8-bit VGA color palette.
+WEBPALETTE         "Safe" web color palette with 225 colors.
+================== ===================================================

File doc/modules/sdl2ext_common.rst

+.. module:: sdl2.ext.common
+   :synopsis: Video and graphics routines
+
+sdl2.ext.common - Initialization routines
+=========================================
+The :mod:`sdl2.ext.common` module contains various classes and methods
+for creating, processing and manipulating on-screen graphics.
+
+API
+---
+
+.. exception:: SDLError(msg=None)
+
+   An SDL2 specific :class:?Exception` class. if no *msg* is provided,
+   the message will be set to the value of :func:`sdl2.error.SDL_GetError()`
+
+.. function:: init() -> None
+
+   Initializes the underlying SDL2 video subsystem. Raises a
+   :exc:`mule.sdl.SDLError`, if the SDL2 video subsystem could not be
+   initialised.
+
+.. function:: quit() -> None
+
+   Quits the underlying SDL2 video subysystem. If no other SDL2 subsystems are
+   active, this will also call :func:`mule.sdl.quit()`.
+
+.. function:: get_events() -> [SDL_Event, SDL_Event, ...]
+
+   Gets all SDL events that are currently on the event queue.
+
+.. class:: TestEventProcessor()
+
+   A simple event processor for testing purposes.
+
+   .. method:: run(window : Window) -> None
+
+      Starts an event loop without actually processing any event. The method
+      will run endlessly until a ``SDL_QUIT`` event occurs.

File doc/modules/sdl2ext_compat.rst

+.. module:: sdl2.ext.compat
+   :synopsis: Python compatibility helpers.
+
+sdl2.ext.compat - Python compatibility helpers
+==============================================
+The :mod:`sdl2.ext.compat` module is for internal purposes of the :mod:`sdl2`
+package and should not be used outside of the package. Classes, methods and
+interfaces might change between versions and there is no guarantee of API
+compatibility on different platforms and python implementations or between
+releases.
+
+.. data:: ISPYTHON2
+
+   ``True``, if executed in a Python 2.x compatible interpreter, ``False``
+   otherwise.
+
+.. data:: ISPYTHON3
+
+   ``True``, if executed in a Python 3.x compatible interpreter, ``False``
+   otherwise.
+
+.. function:: long([x[, base]])
+
+   .. note::
+
+      Only defined for Python 3.x, for which it is the same as :func:`int()`.
+
+.. function:: unichr(i)
+
+   .. note::
+
+      Only defined for Python 3.x, for which it is the same as :func:`chr()`.
+
+.. function:: callable(x) -> bool
+
+   .. note::
+
+      Only defined for Python 3.x, for which it is the same as
+      ``isinstance(x, collections.Callable)``
+
+.. function:: byteify(x : string, enc : string) -> bytes
+
+   Converts a string to a :func:`bytes` object.
+
+.. function:: stringify(x : bytes, enc : string) -> string
+
+   Converts a :func:`bytes` to a string object.
+
+.. function:: isiterable(x) -> bool
+
+   Shortcut for ``isinstance(x, collections.Iterable)``.
+
+.. function:: platform_is_64bit() -> bool
+
+   Checks, if the interpreter is 64-bit capable.
+
+.. decorator:: deprecated
+
+   A simple decorator to mark functions and methods as deprecated. This will
+   print a deprecation message each time the function or method is invoked.
+
+.. function:: deprecation(message : string) -> None
+
+   Prints a deprecation message using the :meth:`warnings.warn()` method.
+
+.. exception:: UnsupportedError(obj : object[, msg=None])
+
+   Indicates that a certain class, function or behaviour is not supported in
+   the specific execution environment.
+
+.. decorator:: experimental
+
+   A simple decorator to mark functions and methods as
+   experimental. This will print a warning each time the function or
+   method is invoked.
+
+.. exception:: ExperimentalWarning(obj : object[, msg=None])
+
+   Indicates that a certain class, function or behaviour is in an
+   experimental state.

File doc/modules/sdl2ext_draw.rst

+.. module:: sdl2.ext.draw
+   :synopsis: 2D drawing routines for software surfaces
+
+sdl2.ext.draw - 2D drawing routines for software surfaces
+=========================================================
+
+.. function:: prepare_color(color : object, target : object) -> int
+
+   Prepares the passed *color* for a specific *target*. *color* can be any
+   object type that can be processed by
+   :func:`sdl2.ext.color.convert_to_color()`. *target* can be any
+   :class:`sdl2.pixels.SDL_PixelFormat`,
+   :class:`sdl2.surface.SDL_Surface` or
+   :class:`sdl2.ext.sprite.SoftwareSprite` instance.
+
+   The returned integer will be a color value matching the target's pixel
+   format.
+
+.. function:: fill(target : object, color : object[, area=None]) -> None
+
+   Fills a certain area on the passed *target* with a *color*. If no *area* is
+   provided, the entire target will be filled with  the passed color. If an
+   iterable item is provided as *area* (such as a list or tuple), it will be
+   first checked, if the item denotes a single rectangular area
+   (4 integer values) before assuming it to be a sequence of rectangular areas
+   to fill with the color.
+
+   *target* can be any :class:`sdl2.surface.SDL_Surface` or
+   :class:`sdl2.ext.sprite.SoftwareSprite` instance.
+
+.. function:: line(target : object, color : object[, width=1]) -> None
+
+   Draws one or multiple lines on the passed *target*. *line* can be a
+   sequence of four integers for a single line in the form ``(x1, y1,
+   x2, y2)`` or a sequence of a multiple of 4 for drawing multiple lines
+   at once, e.g. ``(x1, y1, x2, y2, x3, y3, x4, y4, ...)``.
+
+   *target* can be any :class:`sdl2.surface.SDL_Surface` or
+   :class:`sdl2.ext.sprite.SoftwareSprite` instance.

File doc/modules/sdl2ext_ebs.rst

+.. module:: sdl2.ext.ebs
+   :synopsis: A component-based entity system framework.
+
+sdl2.ext.ebs - A component-based entity system framework
+========================================================
+This module loosely follows a component oriented pattern to separate
+object instances, carried data and processing logic within applications
+or games. It uses an entity based approach, in which object instances are
+unique identifiers, while their data is managed within components, which
+are separately stored. For each individual component type a processing
+system will take care of all necessary updates on running the application.
+
+Component-based patterns
+------------------------
+Component-based means that - instead of a traditional OOP approach - object
+information are split up into separate data bags for reusability and that those
+data bags are separated from any application logic.
+
+Behavioural design
+^^^^^^^^^^^^^^^^^^
+Imagine a car game class in traditional OOP, which might look like ::
+
+   class Car:
+       def __init__(self):
+           self.color = "red"
+           self.position = 0, 0
+           self.velocity = 0, 0
+           self.sprite = get_some_car_image()
+           ...
+       def drive(self, timedelta):
+           self.position[0] = self.velocity[0] * timedelta
+           self.position[1] = self.velocity[1] * timedelta
+           ...
+       def stop(self):
+           self.velocity = 0, 0
+           ...
+       def render(self, screen):
+           screen.display(self.sprite)
+
+   mycar = new Car()
+   mycar.color = "green"
+   mycar.velocity = 10, 0
+
+The car features information stored in attributes (``color``, ``position``,
+...) and behaviour (application logic, ``drive()``, ``stop()`` ...).
+
+A component-based approach aims to split and reduce the car to a set of
+information and external systems providing the application logic. ::
+
+   class Car:
+       def __init__(self):
+           self.color = "red"
+           self.position = 0, 0
+           self.velocity = 0, 0
+           self.sprite = get_some_car_image()
+
+   class CarMovement:
+       def drive(self, car, timedelta):
+           car.position[0] = car.velocity[0] * timedelta
+           car.position[1] = car.velocity[1] * timedelta
+           ...
+       def stop(self):
+           car.velocity = 0, 0
+
+   class CarRenderer:
+       def render(self, car, screen):
+           screen.display(car.sprite)
+
+At this point of time, there is no notable difference between both approaches,
+except that the latter one adds additional overhead.
+
+The benefit comes in, when you
+
+* use subclassing in your OOP design
+* want to change behavioural patterns on a global scale or based on states
+* want to refactor code logic in central locations
+* want to cascade application behaviours
+
+The initial ``Car`` class from above defines, how it should be displayed
+on the screen. If you now want to add a feature for rescaling the screen
+size after the user activates the magnifier mode, you need to refactor
+the ``Car`` and all other classes that render things on the screen, have
+to consider all subclasses that override the method and so on.
+Refactoring the ``CarRenderer`` code by adding a check for the magnifier
+mode sounds quite simple in contrast to that, not?
+
+The same applies to the movement logic - inverting the movement logic
+requires you to refactor all your classes instead of a single piece of
+application code.
+
+Information design
+^^^^^^^^^^^^^^^^^^
+Subclassing with traditional OOP for behavioural changes also might
+bloat your classes with unnecessary information, causing the memory
+footprint for your application to rise without any need. Let's assume
+you have a ``Truck`` class that inherits from ``Car``. Let's further
+assume that all trucks in your application look the same. Why should any
+of those carry a ``sprite`` or ``color`` attribute? You would need to
+refactor your ``Car`` class to get rid of those superfluous information,
+adding another level of subclassing. If at a later point of time you
+decide to give your trucks different colors, you need to refactor
+everything again.
+
+Wouldn't it be easier to deal with colors, if they are available on the
+truck and leave them out, if they are not? We initially stated that the
+component-based approach aims to separate data (information) from code
+logic.  That said, if the truck has a color, we can handle it easily, if
+it has not, we will do as usual.
+
+Also, checking for the color of an object (regardless, if it is a truck,
+car, airplane or death star) allows us to apply the same or similar
+behaviour for every object. If the information is available, we will
+process it, if it is not, we will not do anything.
+
+All in all
+^^^^^^^^^^
+Once we split up the previously OOP-style classes into pure data containers and
+some separate processing code for the behaviour, we are talking about components
+and (processing) systems. A component is a data container, ideally grouping
+related information on a granular level, so that it is easy to (re)use.
+When you combine different components to build your in-application objects and
+instantiate those, we are talking about entities.
+
+.. image:: images/ebs.png
+
+*Component*
+   provides information (data bag)
+
+*Entity*
+   In-application instance that consists of *component* items
+
+*System*
+   Application logic for working with *Entity* items and their
+   *component* data
+
+*World*
+   The environment that contains the different *System* instances and
+   all *Entity* items with their *component* data
+
+Within a strict COP design, the application logic (ideally) only knows about
+data to process. It does not know anything about entities or complex classes
+and only operates on the data.
+
+.. image:: images/copprocessing.png
+
+To keep things simple, modular and easy to maintain and change, you usually
+create small processing systems, which perform the necessary operations on the
+data they shall handle. That said, a ``MovementSystem`` for our car entity would
+only operate on the position and velocity component of the car entity. It does
+not know anything about the the car's sprite or sounds that the car makes,
+since *this is nothing it has to deal with*.
+
+To display the car on the screen, a ``RenderSystem`` might pick up the sprite
+component of the car, maybe along with the position information (so it know,
+where to place the sprite) and render it on the screen.
+
+If you want the car to play sounds, you would add an audio playback system,
+that can perform the task. Afterwards you can add the necessary audio
+information via a sound component to the car and it will make noise.
+
+Component-based design with sdl2.ext.ebs
+----------------------------------------
+
+.. note::
+
+   This section will deal with the specialities of COP patterns and
+   :class:`sdl2.ext.ebs` and provide the bare minimum of information.
+   If you are just starting with such a design, it is recommended to
+   read through the :ref:`pong-tutorial` tutorial.
+
+:mod:`sdl2.ext.ebs` provides a :class:`World` class in which all other objects
+will reside. The :class:`World` will maintain both, :class:`Entity` and
+component items, and allows you to set up the processing logic via
+the :class:`System` and :class:`Applicator` classes. ::
+
+   >>> appworld = World()
+
+Components can be created from any class that inherits from the
+:class:`object` type and represent the data bag of information for the
+entity. and application world. Ideally, they should avoid any
+application logic (except from getter and setter properties). ::
+
+   class Position2D(object):
+       def __init__(self, x=0, y=0):
+           self.x = x
+           self.y = y
+
+:class:`Entity` objects define the in-application objects and only consist of
+component-based attributes. They also require a :class:`World` at
+object instantiation time. ::
+
+   class CarEntity(Entity):
+       def __init__(self, world, x=0, y=0):
+           self.position2d = Position2D(x, y)
+
+.. note::
+
+   The *world* argument in ``__init__()`` is necessary. It will be
+   passed to the internal ``__new__()`` constructor of the
+   :class:`Entity` and stores a reference to the :class:`World` and also
+   allows the :class:`Entity` to store its information in the
+   :class:`World`.
+
+The :class:`Entity` also requries its attributes to be named exactly as
+their component class name, but in lowercase letters. If you name a
+component ``MyAbsolutelyAwesomeDataContainer``, an :class:`Entity` will
+force you to write the following: ::
+
+   class SomeEntity(Entity):
+       def __init__(self, world):
+           self.myabsolutelyawesomedatacontainer = MyAbsolutelyAwesomeDataContainer()
+
+.. note::
+
+   This is not entirely true. A reference of the object will be stored on a
+   per-class-in-mro basis. This means that if ``MyAbsolutelyAwesomeDataContainer``
+   inherits from ``ShortName``, you can also do: ::
+
+     class SomeEntity(Entity):
+         def __init__(self, world):
+             self.shortname = MyAbsolutelyAwesomeDataContainer()
+
+Components should be as atomic as possible and avoid complex
+inheritance. Since each value of an :class:`Entity` is stored per class
+in its mro list, components inheriting from the same class(es) will
+overwrite each other on conflicting classes: ::
+
+  class Vector(Position2D):
+      def __init__(self, x=0, y=0, z=0):
+          super(Vector, self).__init__(x, y)
+
+
+  class SomeEntity(Entity):
+      def __init__(self, world):
+          # This will associate self.position2d with the new Position2D
+          # value, while the previous Vector association is overwritten
+          self.position2d = Position2D(4, 4)
+
+          # self.vector will also associate a self.position2d attribute
+          # with the Entity, since Vector inherits from Position2D. The
+          # original association will vanish, and each call to
+          # entity.position2d will effectively manipulate the vector!
+          self.vector = Vector(1,2,3)
+
+API
+---
+
+.. class:: Entity(world : World)
+
+    An entity is a specific object living in the application world. It
+    does not carry any data or application logic, but merely acts as
+    identifier label for data that is maintained in the application
+    world itself.
+
+    As such, it is an composition of components, which would not exist
+    without the entity identifier. The entity itself is non-existent to
+    the application world as long as it does not carry any data that can
+    be processed by a system within the application world.
+
+   .. attribute:: id
+
+      The id of the Entity. Every Entity has a unique id, that is
+      represented by a :class:`uuid.UUID` instance.
+
+   .. attribute:: world
+
+      The :class:`World` the entity resides in.
+
+   .. method:: delete() -> None
+
+      Deletes the :class:`Entity` from its :class:`World`. This
+      basically calls :meth:`World.delete()` with the :class:`Entity`.
+
+.. class:: Applicator()
+
+   A processing system for combined data sets. The :class:`Applicator`
+   is an enhanced :class:`System` that receives combined data sets based
+   on its set :attr:`System.componenttypes`
+
+   .. attribute:: is_applicator
+   
+      A boolean flag indicating that this class operates on combined data sets.
+   
+   .. attribute:: componenttypes
+
+      A tuple of class identifiers that shall be processed by the
+      :class:`Applicator`.
+
+  .. function:: process(world : World, componentsets : iterable)
+
+      Processes tuples of component items. ``componentsets`` will
+      contain object tuples, that match the :attr:`componenttypes`
+      of the :class:`Applicator`. If, for example, the :class:`Applicator`
+      is defined as ::
+
+        class MyApplicator(Applicator):
+            def __init__(self):
+                self.componenttypes = (Foo, Bar)
+
+      its process method will receive ``(Foo, Bar)`` tuples ::
+
+            def process(self, world, componentsets):
+                for foo_item, bar_item in componentsets:
+                    ...
+
+      Additionally, the :class:`Applicator` will not process all possible
+      combinations of valid components, but only those, which are associated
+      with the same :class:`Entity`. That said, an :class:`Entity` *must*
+      contain a ``Foo`` as well as a ``Bar`` component in order to
+      have them both processed by the :class:`Applicator` (while a
+      :class:`System` with the same ``componenttypes`` would pick either of
+      them, depending on their availability).
+
+.. class:: System()
+
+   A processing system within an application world consumes the
+   components of all entities, for which it was set up. At time of
+   processing, the system does not know about any other component type
+   that might be bound to any entity.
+
+   Also, the processing system does not know about any specific entity,
+   but only is aware of the data carried by all entities.
+
+   .. attribute:: componenttypes
+
+      A tuple of class identifiers that shall be processed by the
+      :class:`System`
+
+   .. method:: process(world : World, components : iterable)
+
+      Processes component items.
+
+      This method has to be implemented by inheriting classes.
+
+
+.. class:: World()
+
+   An application world defines the combination of application data and
+   processing logic and how the data will be processed. As such, it is a
+   container object in which the application is defined.
+
+   The application world maintains a set of entities and their related
+   components as well as a set of systems that process the data of the
+   entities. Each processing system within the application world only
+   operates on a certain set of components, but not all components of an
+   entity at once.
+
+   The order in which data is processed depends on the order of the
+   added systems.
+
+   .. attribute:: systems
+
+      The processing system objects bound to the world.
+
+   .. method:: add_system(system : object)
+
+      Adds a processing system to the world. The system will be
+      added as last item in the processing order.
+      
+      The passed system does not have to inherit from :class:`System`, but
+      must feature a ``componenttypes`` attribute and a ``process()`` method,
+      which match the signatures of the :class:`System` class ::
+      
+        class MySystem(object):
+            def __init__(self):
+                # componenttypes can be any iterable as long as it
+                # contains the classes the system should take care of
+                self.componenttypes = [AClass, AnotherClass, ...]
+            
+            def process(self, world, components):
+                ...
+
+      If the system shall operate on combined component sets as specified
+      by the :class:`Applicator`, the class instance must contain a
+      ``is_applicator`` property, that evaluates to ``True`` ::
+      
+        class MyApplicator(object):
+            def __init__(self):
+                self.is_applicator = True
+                self.componenttypes = [...]
+            
+            def process(self, world, components):
+                pass
+      
+      The behaviour can be changed at run-time. The ``is_applicator`` attribute
+      is evaluated for every call to :meth:`World.process()`.
+      
+   .. method:: delete(entity : Entity)
+
+      Removes an :class:`Entity` from the World, including all its
+      component data.
+
+   .. method:: delete_entities(entities : iterable)
+
+      Removes a set of :class:`Entity` instances from the World,
+      including all their component data.
+
+   .. method:: insert_system(index : int, system : System)
+
+      Adds a processing :class:`System` to the world. The system will be
+      added at the specified position in the processing order.
+
+   .. method:: get_entities(component : object) -> [Entity, ...]
+
+      Gets the entities using the passed component.
+
+      .. note::
+
+         This will not perform an identity check on the component
+         but rely on its ``__eq__`` implementation instead.
+
+   .. method:: process()
+
+      Processes all component items within their corresponding
+      :class:`System` instances.
+
+   .. method:: remove_system(system : System)
+
+      Removes a processing :class:`System` from the world.

File doc/modules/sdl2ext_events.rst

+.. module:: sdl2.ext.events
+   :synopsis: General purpose event handling routines.
+
+sdl2.ext.events - General purpose event handling routines
+=========================================================
+
+.. class:: EventHandler(sender)
+
+   A simple event handling class, which manages callbacks to be
+   executed.
+
+   The EventHandler does not need to be kept as separate instance, but
+   is mainly intended to be used as attribute in event-aware class
+   objects. ::
+
+       >>> def myfunc(sender):
+       ...     print("event triggered by %s" % sender)
+       ...
+       >>> class MyClass(object):
+       ...     def __init__(self):
+       ...         self.anevent = EventHandler(self)
+       ...
+       >>> myobj = MyClass()
+       >>> myobj.anevent += myfunc
+       >>> myobj.anevent()
+       event triggered by <__main__.MyClass object at 0x801864e50>
+
+   .. attribute:: callbacks
+
+      A list of callbacks currently bound to the :class:`EventHandler`.
+
+   .. attribute:: sender
+
+      The responsible object that executes the :class:`EventHandler`.
+
+   .. method:: add(callback : Callable)
+
+      Adds a callback to the :class:`EventHandler`.
+
+   .. method:: remove(callback : Callable)
+
+      Removes a callback from the :class:`EventHandler`.
+
+   .. method:: __call__(*args) -> [ ... ]
+
+      Executes all connected callbacks in the order of addition,
+      passing the :attr:`sender` of the :class:`EventHandler` as first
+      argument and the optional args as second, third, ... argument to
+      them.
+      
+      This will return a list containing the return values of the callbacks
+      in the order of their execution.
+
+
+.. class:: MPEventHandler(sender)
+
+   An asynchronous event handling class based on :class:`EventHandler`,
+   in which callbacks are executed in parallel. It is the responsibility
+   of the caller code to ensure that every object used maintains a
+   consistent state. The :class:`MPEventHandler` class will not apply
+   any locks, synchronous state changes or anything else to the
+   arguments or callbacks being used. Consider it a "fire-and-forget" event
+   handling strategy.
+
+   .. note::
+
+      The :class:`MPEventHandler` relies on the :mod:`multiprocessing`
+      module. If the module is not available in the target environment,
+      a :exc:`mule.compat.UnsupportedError` is raised.
+      
+      Also, please be aware of the restrictions that apply to the
+      :mod:`multiprocessing` module; arguments and callback functions for
+      example have to be pickable, etc.
+
+   .. method:: __call__(*args) -> AsyncResult
+
+      Executes all connected callbacks within a :class:`multiprocessing.Pool`,
+      passing the :attr:`sender` as first argument and the optional *args* as
+      second, third, ... argument to them.
+      
+      This will return a :class:`multiprocessing.pool.AsyncResult` containing
+      the return values of the callbacks in the order of their execution.

File doc/modules/sdl2ext_font.rst

+.. module:: sdl2.ext.font
+   :synopsis: text rendering routines
+
+sdl2.ext.font - Text rendering routines
+=======================================
+
+.. class:: BitmapFont(surface : Sprite, size : iterable[, mapping=None)
+
+   A bitmap graphics to character mapping. The :class:`BitmapFont` class
+   uses an image *surface* to find and render font character glyphs for
+   text. It requires a mapping table, which denotes the characters
+   available on the image.
+
+   The mapping table is a list of strings, where each string reflects a
+   *line* of characters on the image. Each character within each line
+   has the same size as specified by the size argument.
+
+   A typical mapping table might look like ::
+
+      [ '0123456789',
+        'ABCDEFGHIJ',
+        'KLMNOPQRST',
+        'UVWXYZ    ',
+        'abcdefghij',
+        'klmnopqrst',
+        'uvwxyz    ',
+        ',;.:!?+-()' ]
+
+   .. attribute:: surface
+
+      The :class:`sdl2.surface.SDL_Surface` containing the
+      character bitmaps.
+
+   .. attribute:: offsets
+
+      A dict containing the character offsets on the
+      :attr:`surface`.
+
+   .. attribute:: mapping
+
+      The character mapping table, a list of strings.
+
+   .. attribute:: size
+
+      The size of an individual glyph bitmap on the font.
+
+   .. method:: render(text : string[, bpp=None]) -> Sprite
+
+      Renders the passed text on a new :class:`Sprite` and returns it.
+      If no explicit *bpp* are provided, the bpp settings of the
+      :attr:`.surface` are used.
+
+   .. method:: render_on(surface : Sprite, text : string[, \
+                         offset=(0, 0)]) -> (int, int, int, int)
+
+      Renders a text on the passed sprite, starting at a specific
+      offset. The top-left start position of the text will be the
+      passed *offset* and a 4-value tuple with the changed area will be
+      returned.
+
+   .. method:: contains(c : string) -> bool
+
+      Checks, whether a certain character exists in the font.
+
+   .. method:: can_render(text : string) -> bool
+
+      Checks, whether all characters in the passed *text* can be rendered.

File doc/modules/sdl2ext_gui.rst

+.. module:: sdl2.ext.gui
+   :synopsis: User interface elements
+
+sdl2.ext.gui - User interface elements
+======================================
+User interface elements within the :mod:`sdl2.ext.gui` module are simple
+:class:`sdl2.ext.sprite.Sprite` objects, which are enhanced by certain
+input hooks; as such, they are not classes on their own. The user input itself
+is handled by an :class:`UIProcessor` object, which take care of delegating
+input events, such as mouse movements, clicks and keyboard input, to the
+correct UI element.
+
+Depending on the event type (e.g. moving the mouse cursor), the UIProcessor
+will execute its matching method (e.g. ``mousemotion()``) with only those UI
+elements, which support the event type.
+
+TODO
+
+.. _ui-elem-types:
+
+UI element types
+----------------
+As said earlier, every :class:`sdl2.ext.gui` UI element is a simple
+:class:`sdl2.ext.sprite.Sprite` object, to which additional attributes and
+methods are bound.
+
+Every UI element features the following attributes
+
+``element.uitype``
+
+   The ``uitype`` attribute can have one of the following values, identifying the
+   UI element:
+
+   * ``BUTTON`` - a UI element, which can react on mouse input
+   * ``CHECKBUTTON`` - as ``BUTTON``, but it retains its state on clicks
+   * ``TEXTENTRY`` - a UI element that reacts on keyboard input
+
+``element.events``
+
+   A dictionary containing the SDL2 event mappings. Each supported SDL2 event
+   (e.g. ``SDL_MOUSEMOTION``) is associated with a bound
+   :class:`sdl2.ext.events.EventHandler` acting as callback for user code
+   (e.g. ``mousemotion()``).
+
+Depending on the exact type of the element, it will feature additional methods
+and attributes explained below.
+
+Button elements
+^^^^^^^^^^^^^^^
+``BUTTON`` UI elements feature a ``state`` attribute, which can be one of the
+following values.
+
+  ======== =====================================================================
+  state    Description
+  ======== =====================================================================
+  RELEASED Indicates that the UI element is not pressed.
+  HOVERED  Indicates that the mouse cursor is currently hovering the UI element.
+  PRESSED  Indicates that a mouse button is pressed on the UI element.
+  ======== =====================================================================
+
+``BUTTON`` UI elements react with the following event handlers on events:
+
+``button.motion(event : sdl2.events.SDL_Event)``
+
+  A :class:`sdl2.ext.events.EventHandler` that is invoked, if the mouse
+  moves around while being over the ``BUTTON``.
+
+``button.pressed(event : sdl2.events.SDL_Event)``
+
+  A :class:`sdl2.ext.events.EventHandler` that is invoked, if a mouse button
+  is pressed on the ``BUTTON``.
+
+``button.released(event : sdl2.events.SDL_Event)``
+
+  A :class:`sdl2.ext.events.EventHandler` that is invoked, if a mouse button
+  is released on the ``BUTTON``.
+
+``button.click(event : sdl2.events.SDL_Event)``
+
+  A :class:`sdl2.ext.events.EventHandler` that is invoked, if a mouse
+  button is pressed and released on the ``BUTTON``.
+
+Besides the ``BUTTON`` a special ``CHECKBUTTON`` UI element type exists,
+which enhances the ``BUTTON`` bindings by an additional ``checked`` attribute.
+The ``checked`` attribute switches its status (``False`` to ``True`` and
+``True``  to ``False``) every time the UI element is clicked.
+
+Text input elements
+^^^^^^^^^^^^^^^^^^^
+``TEXTENTRY`` elements react on text input, once they are activated. Text being
+input, once a ``TEXTENTRY`` has been activated, is stored in its ``text``
+attribute.
+
+The ``TEXTENTRY`` reacts with the following event handlers on events:
+
+``textentry.motion(event : sdl2.events.SDL_Event)``
+
+  A :class:`sdl2.ext.events.EventHandler` that is invoked, if the mouse
+  moves around while being over the ``TEXTENTRY``.
+
+``textentry.pressed(event : sdl2.events.SDL_Event)``
+
+  A :class:`sdl2.ext.events.EventHandler` that is invoked, if a mouse button
+  is pressed on the ``TEXTENTRY``.
+
+``textentry.released(event : sdl2.events.SDL_Event)``
+
+  A :class:`sdl2.ext.events.EventHandler` that is invoked, if a mouse button
+  is released on the ``TEXTENTRY``.
+
+``textentry.keydown(event : sdl2.events.SDL_Event)``
+
+  A :class:`sdl2.ext.events.EventHandler` that is invoked on pressing a key.
+
+``textentry.keyup(event : sdl2.events.SDL_Event)``
+
+  A :class:`sdl2.ext.events.EventHandler` that is invoked on releasing a key.
+
+``textentry.input(event : sdl2.events.SDL_Event)``
+
+  A :class:`sdl2.ext.events.EventHandler` that is invoked on text input events.
+  Text input events are automatically created, once the :class:`UIProcessor`
+  activates a ``TEXTENTRY`` UI element.
+
+``textentry.editing(event : sdl2.events.SDL_Event)``
+
+  A :class:`sdl2.ext.events.EventHandler` that is invoked on text editing
+  events. Text editing events are automatically created, once the
+  :class:`UIProcessor` activates a ``TEXTENTRY`` UI element.
+
+  Text editing events are however only raised, if an IME system is involved,
+  which combines glyphs and symbols to characters or word fragments.
+
+API
+---
+
+.. class:: UIFactory(spritefactory : SpriteFactory[, **kwargs])
+
+   A factory class for creating UI elements. The :class:`UIFactory`
+   allows you to create UI elements based on the
+   :class:`sdl2.ext.sprite.Sprite` class. To do this, it requires
+   a :class:`sdl2.ext.sprite.SpriteFactory`, which will create the
+   sprites, to which the :class:`UIFactory` then binds the additional methods
+   and attributes-
+
+   The additional *kwargs* are used as default arguments for creating
+   **sprites** within the factory methods.
+
+   .. attribute:: default_args
+
+      A dictionary containing the default arguments to be passed to the
+      sprite creation methods of the bound
+      :class:`sdl2.ext.sprite.SpriteFactory`.
+
+   .. attribute:: spritefactory
+
+      The :class:`sdl2.ext.sprite.SpriteFactory` being used for creating
+      new :class:`Sprite` objects.
+
+   .. method:: create_button(**kwargs) -> Sprite
+
+      Creates a new button UI element.
+
+      *kwargs* are the arguments to be passed for the sprite
+      construction and can vary depending on the sprite type.
+      See :class:`sdl2.ext.sprite.SpriteFactory.create_sprite()` for
+      further details.
+
+   .. method:: create_check_button(**kwargs) -> Sprite
+
+      Creates a new checkbutton UI element.
+
+      *kwargs* are the arguments to be passed for the sprite
+      construction and can vary depending on the sprite type.
+      See :class:`sdl2.ext.sprite.SpriteFactory.create_sprite()` for
+      further details.
+
+   .. method:: create_text_entry(**kwargs) -> Sprite
+
+      Creates a new textentry UI element.
+
+      *kwargs* are the arguments to be passed for the sprite
+      construction and can vary depending on the sprite type.
+      See :class:`sdl2.ext.sprite.SpriteFactory.create_sprite()` for
+      further details.
+
+   .. method:: from_image(uitype : int, fname : str) -> Sprite
+
+      Creates a UI element from an image file. The image must be
+      loadable via :func:`sdl2.ext.image.load_image()`.
+
+      *uitype* must be one of the supported :ref:`ui-elem-types` classifying
+      the type of UI element to be created.
+
+   .. method:: from_object(uitype : int, obj: object) -> Sprite
+
+      Creates a UI element from an object. The object will be passed through
+      :func:`sdl2.rwops.rwops_from_object()` in
+      order to try to load image data from it.
+
+      *uitype* must be one of the supported :ref:`ui-elem-types` classifying
+      the type of UI element to be created.
+
+   .. method:: from_surface(uitype : int,  surface : SDL_Surface[, \
+      free=False]) -> Sprite
+
+      Creates a UI element from the passed
+      :class:`sdl2.surface.SDL_Surface`. If *free* is set to
+      ``True``, the passed *surface* will be freed automatically.
+
+      *uitype* must be one of the supported :ref:`ui-elem-types` classifying
+      the type of UI element to be created.
+
+.. class:: UIProcessor()
+
+   A processing system for user interface elements and events.
+
+   .. attribute:: handlers
+
+      A dict containing the mapping of SDL2 events to the available
+      :class:`sdl2.ext.events.EventHandler` bindings of the
+      :class:`UIProcessor`.
+
+   .. method:: activate(component : object) -> None
+
+      Activates a UI control to receive text input.
+
+   .. method:: deactivate(component : object) -> None
+
+      Deactivate the currently active UI control.
+
+   .. method:: passevent(component : object, event : SDL_Event) -> None
+
+      Passes the *event* to a *component* without any additional checks or
+      restrictions.
+
+   .. method:: mousemotion(component : object, event : SDL_Event) -> None
+
+      Checks, if the event's motion position is on the *component* and
+      executes the component's event handlers on demand. If the motion event
+      position is not within the area of the *component*, nothing will be
+      done. In case the component is a :class:`Button`, its
+      :attr:`Button.state` will be adjusted to reflect, if it is
+      currently hovered or not.
+
+   .. method:: mousedown(component : object, event : SDL_Event) -> None
+
+      Checks, if the event's button press position is on the *component* and
+      executes the component's event handlers on demand. If the button press
+      position is not within the area of the component, nothing will be done.
+
+      In case the component is a :class:`Button`, its :attr:`Button.state`
+      will be adjusted to reflect, if it is currently pressed or not.
+
+      In case the component is a :class:`TextEntry` and the pressed button is
+      the primary mouse button, the component will be marked as the next
+      control to activate for text input.
+
+   .. method:: mouseup(self, component, event) -> None
+
+      Checks, if the event's button release position is on the *component* and
+      executes the component's event handlers on demand. If the button release
+      position is not within the area of the component, nothing will be done.
+
+      In case the component is a :class:`Button`, its :attr:`Button.state`
+      will be adjusted to reflect, whether it is hovered or not.
+
+      If the button release followed a button press on the same component and
+      if the button is the primary button, the click() event handler is invoked,
+      if the component is a :class:`Button`.
+
+   .. method:: dispatch(obj : object, event : SDL_Event) -> None
+
+      Passes an event to the given object. If *obj* is a
+      :class:`sdl2.ext.ebs.World` object, UI relevant components will receive
+      the event, if they support the event type. If *obj* is a single object,
+      ``obj.events`` **must** be a dict consisting of SDL event type
+      identifiers and :class:`sdl2.ext.events.EventHandler` instances bound
+      to the object. If *obj* is a iterable, such as a list or set, every
+      item within *obj* **must** feature an ``events`` attribute as
+      described above.
+
+   .. method:: process(world : World, components : iterable) -> None
+
+      The :class:`UIProcessor` class does not implement the process()``
+      method by default. Instead it uses :meth:`dispatch()` to send events
+      around to components. :meth:`process()` does nothing.

File doc/modules/sdl2ext_image.rst

+.. module:: sdl2.ext.image
+   :synopsis: Image loaders
+
+sdl2.ext.image - Image loaders
+==============================
+
+.. function:: get_image_formats() -> (str, str, ...)
+
+   Gets the formats supported by PyMule in the default installation.
+
+.. function:: load_image(fname : str[, renderer=None[,assurface=False[, enforce=None]]]) -> SDL_Surface, Sprite or SoftSprite
+
+   Creates a :class:`sdl2.surface.SDL_Surface` from an image file.
+
+   This function makes use of the `Python Imaging Library
+   <http://www.pythonware.com/products/pil/>`_, if it is available on
+   the target execution environment. The function will try to load the
+   file via :mod:`mule.sdlimage` first. If the file could not be
+   loaded, it will try to load it via PIL.
+
+   You can force the function to use only one of them, by passing the
+   *enforce* as either ``"PIL"`` or ``"SDL"``.
+
+   .. note::
+
+      This will call :func:`sdl2.sdlimage.init()` implicitly with the
+      default arguments, if the module is available.

File doc/modules/sdl2ext_particles.rst

+.. module:: sdl2.ext.particles
+   :synopsis: A simple particle system.
+
+sdl2.ext.particles - A simple particle system
+=============================================
+
+.. class:: ParticleEngine()
+
+   A simple particle processing system. The :class:`ParticleEngine`
+   takes care of creating, updating and deleting particles via callback
+   functions. It only decreases the life of the particles by itself and
+   marks them as dead, once the particle's life attribute has reached 0
+   or below.
+
+   .. attribute:: createfunc
+
+      Function for creating new particles. The function needs to take
+      two arguments, the ``world`` argument passed to :meth:`process()`
+      and a list of the particles considered dead (:attr:`Particle.life`
+      <= 0). ::
+
+        def creation_func(world, deadparticles):
+            ...
+
+   .. attribute:: updatefunc
+
+      Function for updating existing, living particles. The function
+      needs to take two arguments, the ``world`` argument passed to
+      :meth:`process()` and a :class:`set` of the still living
+      particles. ::
+
+        def update_func(world, livingparticles):
+            ...
+
+   .. attribute:: deletefunc
+
+      Function for deleting dead particles. The function needs to take
+      two arguments, the ``world`` argument passed to :meth:`process()`
+      and a list of the particles considered dead (:attr:`Particle.life`
+      <= 0). ::
+
+        def deletion_func(world, deadparticles):
+            ...
+
+   .. method:: process(world : World, components : iterable) -> None
+   
+      Processes all particle components, decreasing their life by 1.
+
+      Once the life of all particle components has been decreased
+      properly and the particles considered dead (life <= 0) are
+      identified, the creation, update and deletion callbacks are
+      invoked.
+
+      The creation callback takes the passed world as first and the
+      list of dead particles as second argument. ::
+
+        def particle_createfunc(world, list_of_dead_ones):
+            ...
+
+      Afterwards the still living particles are passed to the update
+      callback, which also take the passed world as first and the
+      living particles as set as second argument. ::
+
+        def particle_updatefunc(world, set_of_living_ones):
+            ...
+
+      Finally, the dead particles need to be deleted in some way or
+      another, which is done by the deletion callback, taking the
+      passed world as first and the list of dead particles as second
+      argument. ::
+
+        def particle_deletefunc(world, list_of_dead_ones):
+            ...   
+
+.. class:: Particle(x, y, life : int)
+
+   A simple particle component type. It only contains information about
+   a x- and y-coordinate and its current life time. The life time will
+   be decreased by 1, everytime the particle is processed by the
+   :class:`ParticleEngine`.
+
+   .. attribute:: x
+
+      The x coordinate of the particle.
+
+   .. attribute:: y
+
+      The y coordinate of the particle.
+
+   .. attribute:: life
+
+      The remaining life time of the particle.
+
+   .. attribute:: position
+
+      The x- and y-coordinate of the particle as tuple.

File doc/modules/sdl2ext_pixelaccess.rst

+.. module:: sdl2.ext.pixelaccess
+   :synopsis: 2D and 3D direct pixel access
+
+sdl2.ext.pixelaccess - 2D and 3D direct pixel access
+====================================================
+
+.. class:: PixelView(source : object)
+
+   2D :class:`sdl2.ext.array.MemoryView` for
+   :class:`sdl2.ext.sprite.SoftwareSprite` and 
+   :class:`sdl2.surface.SDL_surface` pixel access.
+  
+   .. note::
+
+      If necessary, the *source* surface will be locked for accessing its
+      pixel data. The lock will be removed once the :class:`PixelView` is
+      garbage-collected or deleted.
+
+    The :class:`PixelView?  uses a y/x-layout. Accessing ``view[N]`` will
+    operate on the Nth row of the underlying surface. To access a specific
+    column within that row, ``view[N][C]`` has to be used.
+    
+    .. note:: 
+    
+       :class`PixelView` is implemented on top of the
+       :class:`sdl2.ext.array.MemoryView` class. As such it makes heavy use of
+       recursion to access rows and columns and can be considered as slow in
+       contrast to optimised ndim-array solutions such as :mod:`numpy`.
+
+.. function:: pixels2d(source : object)
+
+   Creates a 2D pixel array, based on ``numpy.ndarray``, from the passed
+   *source*. *source* can be a :class:`sdl2.ext.sprite.SoftwareSprite` or
+   :class:`sdl2.surface.SDL_Surface`. The *source* its
+   ``SDL_Surface`` will be locked and unlocked automatically.
+
+   The *source* pixels will be accessed and manipulated directly.
+
+   .. note::
+
+      :func:`pixels2d` is only usable, if the numpy package is available
+      within the target environment. If numpy could not be imported, a
+      :exc:`sdl2.ext.compat.UnsupportedError` will be raised.
+
+.. function:: pixels3d(source : object)
+
+   Creates a 3D pixel array, based on ``numpy.ndarray``, from the passed
+   *source*. *source* can be a :class:`sdl2.ext.sprite.SoftwareSprite`
+   or :class:`sdl2.surface.SDL_Surface`. The *source* its
+   ``SDL_Surface`` will be locked and unlocked automatically.
+
+   The *source* pixels will be accessed and manipulated directly.
+
+   .. note::
+
+      :func:`pixels3d` is only usable, if the numpy package is available
+      within the target environment. If numpy could not be imported, a
+      :exc:`sdl2.ext.compat.UnsupportedError` will be raised.

File doc/modules/sdl2ext_resources.rst

+.. module:: sdl2.ext.resources
+   :synopsis: Resource management.
+
+sdl2.ext.resources - Resource management
+========================================
+Every application usually ships with various resources, such as image and data
+files, configuration files and so on. Accessing those files in the folder
+hierarchy or in a bundled format for various platforms can become a comple
+task, for which the :mod:`sdl2.ext.resources` module can provide ideal
+supportive application components.
+
+The :class:`Resources` class allows you to manage different application data
+in a certain directory, providing a dictionary-style access functionality for
+your in-application resources.
+
+Let's assume, your application has the following installation layout ::
+
+    Application Directory
+        Application.exe
+        Application.conf
+        data/
+            background.jpg
+            button1.jpg
+            button2.jpg
+            info.dat
+
+Within the ``Application.exe`` code, you can - completely system-agnostic -
+define a new resource that keeps track of all ``data`` items. ::
+
+    apppath = os.path.dirname(os.path.abspath(__file__))
+    appresources = Resources(os.path.join(apppath, "data"))
+    # Access some images
+    bgimage = appresources.get("background.jpg")
+    btn1image = appresources.get("button1.jpg")
+    ...
+
+To access individual files, you do not need to concat paths the whole
+time and regardless of the current directory, your application operates
+on, you can access your resource files at any time through the
+:class:`Resources` instance, you created initially.
+
+The :class:`Resources` class is also able to scan an index archived files,
+compressed via ZIP or TAR (gzip or bzip2 compression), and subdiectories
+automatically. ::
+
+    Application Directory
+        Application.exe
+        Application.conf
+        data/
+            audio/
+                example.wav
+            background.jpg
+            button1.jpg
+            button2.jpg
+            graphics.zip
+                [tileset1.bmp
+                 tileset2.bmp
+                 tileset3.bmp
+                 ]
+            info.dat
+
+    tilesimage = appresources.get("tileset1.bmp")
+    audiofile = appresources.get("example.wav")
+
+If you request an indexed file via :meth:`Resources.get`, you will receive
+a :class:`io.BytesIO` stream, containing the file data, for further processing.
+
+.. note::
+
+   The scanned files act as keys within the :class:`Resources` class. This
+   means that two files, that have the same name, but are located in different
+   directories, will not be indexed. Only one of them will be accessible
+   through the :class:`Resources` class.
+
+API
+---
+
+.. class:: Resources([path=None[, subdir=None[, excludepattern=None]]])
+
+   The Resources class manages a set of file resources and eases
+   accessing them by using relative paths, scanning archives
+   automatically and so on.
+
+   .. method:: add(filename : string)
+
+      Adds a file to the resource container. Depending on the
+      file type (determined by the file suffix or name) the file will be
+      automatically scanned (if it is an archive) or checked for
+      availability (if it is a stream or network resource).
+
+   .. method:: add_archive(filename : string[, typehint="zip"])
+
+      Adds an archive file to the resource container. This will scan the
+      passed archive and add its contents to the list of available and
+      accessible resources.
+
+   .. method:: add_file(filename : string)
+
+      Adds a file to the resource container. This will only add the
+      passed file and do not scan an archive or check the file for
+      availability.
+