Commits

Marcus von Appen  committed e5eef3c

- added SDL2_gfx library wrapper in module sdl2.sdlgfx and a brief example on
the drawing primitives
- fixed color argument handling in the RenderContext methods.
- minor documentation fixes

  • Participants
  • Parent commits 8a3e381

Comments (0)

Files changed (11)

File doc/copying.rst

    software, this software can be licensed under the zlib lincese as
    stated below:
 
-   Copyright (C) 2012 Marcus von Appen <marcus@sysfault.org>
+   Copyright (C) 2012-2013 Marcus von Appen <marcus@sysfault.org>
 
    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any damages

File doc/modules/index.rst

    :maxdepth: 2
 
    sdl2.rst
+   sdl2_sdlgfx.rst
    sdl2_sdlimage.rst
    sdl2_sdlttf.rst
    sdl2ext.rst

File doc/modules/sdl2_sdlgfx.rst

+.. module:: sdl2.sdlgfx
+   :synopsis: SDL2_gfx library wrapper
+
+sdl2.sdlgfx - SDL2_gfx library wrapper
+======================================
+The :mod:`sdl2.sdlgfx` module is a :mod:`ctypes`-based wrapper
+around the SDL2_gfx library. It wraps nearly all publicly accessible
+structures and functions of the SDL2_gfx library to be accessible from
+Python code.
+
+A detailled documentation about the behaviour of the different functions
+can found on the `SDL2_gfx project website
+<http://www.ferzkopp.net/Software/SDL_gfx-2.0/>`_.

File doc/tutorial/index.rst

-Learn to fly - the tutorials
-============================
-PySDL2 is easy to learn and a powerful multimedia programming framework. It
-features efficient high- and low-level structures and an excellent
-object-oriented programming layout.
-
-The following tutorials will guide you through your first applications
-written with PySDL2 and introduces certain parts of the PySDL2 packages to
-you. They will most likely *not* cover each single part of PySDL2, but
-instead show you the most noteworthy features.
-
-.. toctree::
-  :maxdepth: 2
-
-  helloworld.rst
-  pong.rst
+Learn to fly - the tutorials
+============================
+PySDL2 is easy to learn and a powerful multimedia programming framework. It
+features efficient high- and low-level structures and an excellent
+object-oriented programming layout.
+
+The following tutorials will guide you through your first applications
+written with PySDL2 and introduces certain parts of the PySDL2 packages to
+you. They will most likely *not* cover each single part of PySDL2, but
+instead show you the most noteworthy features.
+
+.. toctree::
+  :maxdepth: 2
+
+  helloworld.rst
+  pong.rst

File examples/draw.py

     sys.exit(1)
 
 
+# Draws random lines on the passed surface
 def draw_lines(surface, width, height):
+    # Fill the whole surface with a black color.
     sdl2ext.fill(surface, 0)
     for x in range(15):
+        # Create a set of four random points for drawing the line.
         x1, x2 = randint(0, width), randint(0, width)
         y1, y2 = randint(0, height), randint(0, height)
+        # Create a random color.
         color = sdl2ext.Color(randint(0, 255),
                               randint(0, 255),
                               randint(0, 255))
+        # Draw the line with the specified color on the surface.
+        # We also could create a set of points to be passed to the function
+        # in the form
+        #
+        # line(surface, color, (x1, y1, x2, y2, x3, y3, x4, y4, ...))
+        #                       ^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^
+        #                         first line     second line
         sdl2ext.line(surface, color, (x1, y1, x2, y2))
 
 
+# Draws random, filled rectangles on the passed surface
 def draw_rects(surface, width, height):
+    # Fill the whole surface with a black color.
     sdl2ext.fill(surface, 0)
     for k in range(15):
+        # Create a set of four random points for the edges of the rectangle.
         x, y = randint(0, width), randint(0, height)
         w, h = randint(1, width // 2), randint(1, height // 2)
+        # Create a random color.
         color = sdl2ext.Color(randint(0, 255),
                               randint(0, 255),
                               randint(0, 255))
+        # Draw the filled rect with the specified color on the surface.
+        # We also could create a set of points to be passed to the function
+        # in the form
+        #
+        # fill(surface, color, ((x1, y1, x2, y2), (x3, y3, x4, y4), ...))
+        #                        ^^^^^^^^^^^^^^    ^^^^^^^^^^^^^^
+        #                          first rect        second rect
         sdl2ext.fill(surface, color, (x, y, w, h))
 
 

File examples/gfxdrawing.py

+"""2D drawing examples utilising the SDL2_gfx functions."""
+import sys
+import ctypes
+from random import randint
+
+# Try to import SDL2 and SDL2_gfx. The import might fail, if either of the
+# libraries could not be loaded. In that case, just print the error and exit
+# with a proper error code.
+try:
+    from sdl2 import SDL_QUIT, SDL_MOUSEBUTTONDOWN, Sint16
+    import sdl2.sdlgfx as sdlgfx
+    import sdl2.ext as sdl2ext
+except ImportError:
+    import traceback
+    traceback.print_exc()
+    sys.exit(1)
+
+
+# Draws random lines using the passed rendering context
+def draw_lines(context, width, height):
+    # Reset the visible area with a black color.
+    context.clear(0)
+    # Split the visible area
+    whalf = width // 2 - 2
+    hhalf = height // 2 - 2
+    lw = 5
+    x0, x1 = whalf, whalf
+    y0, y1 = 0, height
+    sdlgfx.thickLineColor(context.renderer, x0, y0, x1, y1, lw, 0xFFFFFFFF)
+    x0, x1 = 0, width
+    y0, y1 = hhalf, hhalf
+    sdlgfx.thickLineColor(context.renderer, x0, y0, x1, y1, lw, 0xFFFFFFFF)
+    for x in range(15):
+        # In the first quadrant, draw normal lines
+        color = randint(0, 0xFFFFFFFF)
+        x0, x1 = randint(0, whalf), randint(0, whalf)
+        y0, y1 = randint(0, hhalf), randint(0, hhalf)
+        sdlgfx.lineColor(context.renderer, x0, y0, x1, y1, color)
+        # In the second quadrant, draw aa lines
+        color = randint(0, 0xFFFFFFFF)
+        x0, x1 = randint(whalf + lw, width), randint(whalf + lw, width)
+        y0, y1 = randint(0, hhalf), randint(0, hhalf)
+        sdlgfx.aalineColor(context.renderer, x0, y0, x1, y1, color)
+        # In the third quadrant, draw horizontal lines
+        color = randint(0, 0xFFFFFFFF)
+        x0, x1 = randint(0, whalf), randint(0, whalf)
+        y0 = randint(hhalf + lw, height)
+        sdlgfx.hlineColor(context.renderer, x0, x1, y0, color)
+        # In the fourth quadrant, draw vertical lines
+        color = randint(0, 0xFFFFFFFF)
+        x0 = randint(whalf + lw, width)
+        y0, y1 = randint(hhalf + lw, height), randint(hhalf + lw, height)
+        sdlgfx.vlineColor(context.renderer, x0, y0, y1, color)
+
+
+# Draws random circles using the passed rendering context
+def draw_circles(context, width, height):
+    # Reset the visible area with a black color.
+    context.clear(0)
+    # Split the visible area
+    wthird = width // 3 - 1
+    lw = 3
+    sdlgfx.thickLineColor(context.renderer, wthird, 0, wthird, height, lw,
+                          0xFFFFFFFF)
+    sdlgfx.thickLineColor(context.renderer, (2 * wthird + lw), 0,
+                          (2 * wthird + lw), height, lw, 0xFFFFFFFF)
+    for x in range(15):
+        # In the first part, draw circles
+        color = randint(0, 0xFFFFFFFF)
+        x, y = randint(0, wthird), randint(0, height)
+        r = randint(1, max(min(x, wthird - x), 2))
+        sdlgfx.circleColor(context.renderer, x, y, r, color)
+        # In the second part, draw aa circles
+        color = randint(0, 0xFFFFFFFF)
+        x, y = randint(0, wthird), randint(0, height)
+        r = randint(1, max(min(x, wthird - x), 2))
+        sdlgfx.aacircleColor(context.renderer, x + wthird + lw, y, r, color)
+        # In the third part, draw filled circles
+        color = randint(0, 0xFFFFFFFF)
+        x, y = randint(0, wthird), randint(0, height)
+        r = randint(1, max(min(x, wthird - x), 2))
+        sdlgfx.filledCircleColor(context.renderer, x + 2 * (wthird + lw), y, r,
+                                 color)
+
+
+# Draws random ellipsis using the passed rendering context
+def draw_ellipsis(context, width, height):
+    # Reset the visible area with a black color.
+    context.clear(0)
+    # Split the visible area
+    wthird = width // 3 - 1
+    eheight = height // 4
+    lw = 3
+    sdlgfx.thickLineColor(context.renderer, wthird, 0, wthird, height, lw,
+                          0xFFFFFFFF)
+    sdlgfx.thickLineColor(context.renderer, (2 * wthird + lw), 0,
+                          (2 * wthird + lw), height, lw, 0xFFFFFFFF)
+    for x in range(15):
+        # In the first part, draw ellipsis
+        color = randint(0, 0xFFFFFFFF)
+        x, y = randint(0, wthird), randint(0, height)
+        rx, ry = randint(1, max(min(x, wthird - x), 2)), randint(0, eheight)
+        sdlgfx.ellipseColor(context.renderer, x, y, rx, ry, color)
+        # In the second part, draw aa ellipsis
+        color = randint(0, 0xFFFFFFFF)
+        x, y = randint(0, wthird), randint(0, height)
+        rx, ry = randint(1, max(min(x, wthird - x), 2)), randint(0, eheight)
+        sdlgfx.aaellipseColor(context.renderer, x + wthird + lw, y, rx, ry,
+                              color)
+        # In the third part, draw filled ellipsis
+        color = randint(0, 0xFFFFFFFF)
+        x, y = randint(0, wthird), randint(0, height)
+        rx, ry = randint(1, max(min(x, wthird - x), 2)), randint(0, eheight)
+        sdlgfx.filledEllipseColor(context.renderer, x + 2 * (wthird + lw), y,
+                                  rx, ry, color)
+
+
+# Draws random rectangles using the passed rendering context
+def draw_rects(context, width, height):
+    # Reset the visible area with a black color.
+    context.clear(0)
+    # Split the visible area
+    whalf = width // 2 - 2
+    hhalf = height // 2 - 2
+    lw = 5
+    x0, x1 = whalf, whalf
+    y0, y1 = 0, height
+    sdlgfx.thickLineColor(context.renderer, x0, y0, x1, y1, lw, 0xFFFFFFFF)
+    x0, x1 = 0, width
+    y0, y1 = hhalf, hhalf
+    sdlgfx.thickLineColor(context.renderer, x0, y0, x1, y1, lw, 0xFFFFFFFF)
+    for x in range(15):
+        # In the first quadrant, draw normal rectangles
+        color = randint(0, 0xFFFFFFFF)
+        x0, x1 = randint(0, whalf), randint(0, whalf)
+        y0, y1 = randint(0, hhalf), randint(0, hhalf)
+        sdlgfx.rectangleColor(context.renderer, x0, y0, x1, y1, color)
+        # In the second quadrant, draw rounded rectangles
+        color = randint(0, 0xFFFFFFFF)
+        x0, x1 = randint(whalf + lw, width), randint(whalf + lw, width)
+        y0, y1 = randint(0, hhalf), randint(0, hhalf)
+        r = randint(0, max(x1 - x0, x0 - x1))
+        sdlgfx.roundedRectangleColor(context.renderer, x0, y0, x1, y1, r,
+                                     color)
+        # In the third quadrant, draw horizontal lines
+        color = randint(0, 0xFFFFFFFF)
+        x0, x1 = randint(0, whalf), randint(0, whalf)
+        y0, y1 = randint(hhalf + lw, height), randint(hhalf + lw, height)
+        sdlgfx.boxColor(context.renderer, x0, y0, x1, y1, color)
+        # In the fourth quadrant, draw vertical lines
+        color = randint(0, 0xFFFFFFFF)
+        x0, x1 = randint(whalf + lw, width), randint(whalf + lw, width)
+        y0, y1 = randint(hhalf + lw, height), randint(hhalf + lw, height)
+        r = randint(1, max(x1 - x0, x0 - x1))
+        sdlgfx.roundedBoxColor(context.renderer, x0, y0, x1, y1, r, color)
+
+
+# Draws random triangles using the passed rendering context
+def draw_trigons(context, width, height):
+    # Reset the visible area with a black color.
+    context.clear(0)
+    # Split the visible area
+    wthird = width // 3 - 1
+    lw = 3
+    sdlgfx.thickLineColor(context.renderer, wthird, 0, wthird, height, lw,
+                          0xFFFFFFFF)
+    sdlgfx.thickLineColor(context.renderer, (2 * wthird + lw), 0,
+                          (2 * wthird + lw), height, lw, 0xFFFFFFFF)
+    for x in range(15):
+        # In the first part, draw triangles
+        color = randint(0, 0xFFFFFFFF)
+        x0, y0 = randint(0, wthird), randint(0, height)
+        x1, y1 = randint(0, wthird), randint(0, height)
+        x2, y2 = randint(0, wthird), randint(0, height)
+        sdlgfx.trigonColor(context.renderer, x0, y0, x1, y1, x2, y2, color)
+        # In the second part, draw aa triangles
+        color = randint(0, 0xFFFFFFFF)
+        x0, y0 = randint(0, wthird) + wthird + lw, randint(0, height)
+        x1, y1 = randint(0, wthird) + wthird + lw, randint(0, height)
+        x2, y2 = randint(0, wthird) + wthird + lw, randint(0, height)
+        sdlgfx.aatrigonColor(context.renderer, x0, y0, x1, y1, x2, y2, color)
+        # In the third part, draw filled triangles
+        color = randint(0, 0xFFFFFFFF)
+        x0, y0 = randint(0, wthird) + 2 * (wthird + lw), randint(0, height)
+        x1, y1 = randint(0, wthird) + 2 * (wthird + lw), randint(0, height)
+        x2, y2 = randint(0, wthird) + 2 * (wthird + lw), randint(0, height)
+        sdlgfx.filledTrigonColor(context.renderer, x0, y0, x1, y1, x2, y2,
+                                 color)
+
+
+# Draws random polygons using the passed rendering context
+def draw_polygons(context, width, height):
+    # Reset the visible area with a black color.
+    context.clear(0)
+    # Split the visible area
+    wthird = width // 3 - 1
+    lw = 3
+    sdlgfx.thickLineColor(context.renderer, wthird, 0, wthird, height, lw,
+                          0xFFFFFFFF)
+    sdlgfx.thickLineColor(context.renderer, (2 * wthird + lw), 0,
+                          (2 * wthird + lw), height, lw, 0xFFFFFFFF)
+    for x in range(5):
+        # In the first part, draw polygons
+        color = randint(0, 0xFFFFFFFF)
+        ptcount = randint(3, 10)
+        xlist, ylist = (Sint16 * ptcount)(), (Sint16 * ptcount)()
+        for k in range(ptcount):
+            xlist[k] = randint(0, wthird)
+            ylist[k] = randint(0, height)
+        xptr = ctypes.cast(xlist, ctypes.POINTER(Sint16))
+        yptr = ctypes.cast(ylist, ctypes.POINTER(Sint16))
+        sdlgfx.polygonColor(context.renderer, xptr, yptr, ptcount, color)
+        # In the second part, draw aa polygons
+        color = randint(0, 0xFFFFFFFF)
+        ptcount = randint(3, 10)
+        xlist, ylist = (Sint16 * ptcount)(), (Sint16 * ptcount)()
+        for k in range(ptcount):
+            xlist[k] = randint(0, wthird) + wthird + lw
+            ylist[k] = randint(0, height)
+        xptr = ctypes.cast(xlist, ctypes.POINTER(Sint16))
+        yptr = ctypes.cast(ylist, ctypes.POINTER(Sint16))
+        sdlgfx.aapolygonColor(context.renderer, xptr, yptr, ptcount, color)
+        # In the third part, draw filled polygons
+        color = randint(0, 0xFFFFFFFF)
+        ptcount = randint(3, 10)
+        xlist, ylist = (Sint16 * ptcount)(), (Sint16 * ptcount)()
+        for k in range(ptcount):
+            xlist[k] = randint(0, wthird) + 2 * (wthird + lw)
+            ylist[k] = randint(0, height)
+        xptr = ctypes.cast(xlist, ctypes.POINTER(Sint16))
+        yptr = ctypes.cast(ylist, ctypes.POINTER(Sint16))
+        sdlgfx.filledPolygonColor(context.renderer, xptr, yptr, ptcount, color)
+
+
+# Draw random elements using the passed rendering context
+def draw_mixed(context, width, height):
+    # Reset the visible area with a black color.
+    context.clear(0)
+    # Split the visible area
+    whalf = width // 2 - 2
+    hhalf = height // 2 - 2
+    lw = 5
+    x0, x1 = whalf, whalf
+    y0, y1 = 0, height
+    sdlgfx.thickLineColor(context.renderer, x0, y0, x1, y1, lw, 0xFFFFFFFF)
+    x0, x1 = 0, width
+    y0, y1 = hhalf, hhalf
+    sdlgfx.thickLineColor(context.renderer, x0, y0, x1, y1, lw, 0xFFFFFFFF)
+    for x in range(15):
+        # In the first quadrant, draw arcs
+        color = randint(0, 0xFFFFFFFF)
+        x0, y0 = randint(0, whalf), randint(0, hhalf)
+        rad = randint(0, min(whalf - x0, hhalf - y0))
+        start, end = randint(0, 360), randint(0, 360)
+        sdlgfx.arcColor(context.renderer, x0, y0, rad, start, end, color)
+        # In the second quadrant, draw bezier curves
+        color = randint(0, 0xFFFFFFFF)
+        ptcount = randint(3, 10)
+        xlist, ylist = (Sint16 * ptcount)(), (Sint16 * ptcount)()
+        for k in range(ptcount):
+            xlist[k] = randint(whalf, width)
+            ylist[k] = randint(0, hhalf)
+        steps = randint(2, 10)
+        xptr = ctypes.cast(xlist, ctypes.POINTER(Sint16))
+        yptr = ctypes.cast(ylist, ctypes.POINTER(Sint16))
+        sdlgfx.bezierColor(context.renderer, xptr, yptr, ptcount, steps, color)
+        # In the third quadrant, draw pies
+        color = randint(0, 0xFFFFFFFF)
+        x0, y0 = randint(0, whalf), randint(hhalf + lw, height)
+        rad = randint(0, min(whalf - x0, y0 - (hhalf + lw)))
+        start, end = randint(0, 360), randint(0, 360)
+        sdlgfx.pieColor(context.renderer, x0, y0, rad, start, end, color)
+        # In the fourth quadrant, draw filled pies
+        color = randint(0, 0xFFFFFFFF)
+        x0, y0 = randint(whalf + lw, width), randint(hhalf + lw, height)
+        rad = randint(0, min(x0 - (whalf + lw), y0 - (hhalf + lw)))
+        start, end = randint(0, 360), randint(0, 360)
+        sdlgfx.filledPieColor(context.renderer, x0, y0, rad, start, end, color)
+
+
+def run():
+    # You know those from the helloworld.py example.
+    # Initialize the video subsystem, create a window and make it visible.
+    sdl2ext.init()
+    window = sdl2ext.Window("sdlgfx drawing examples", size=(800, 600))
+    window.show()
+
+    # Create a rendering context for the window. The sdlgfx module require it.
+    context = sdl2ext.RenderContext(window)
+
+    # We implement the functionality as it was done in colorpalettes.py and
+    # utilise a mapping table to look up the function to be executed, together
+    # with the arguments they should receive
+    functions = ((draw_lines, (context, 800, 600)),
+                 (draw_circles, (context, 800, 600)),
+                 (draw_ellipsis, (context, 800, 600)),
+                 (draw_rects, (context, 800, 600)),
+                 (draw_trigons, (context, 800, 600)),
+                 (draw_polygons, (context, 800, 600)),
+                 (draw_mixed, (context, 800, 600))
+                 )
+
+    # A storage variable for the function we are currently on, so that we know
+    # which function to execute next.
+    curindex = 0
+    draw_lines(context, 800, 600)
+
+    # The event loop is nearly the same as we used in colorpalettes.py. If you
+    # do not know, what happens here, take a look at colorpalettes.py for a
+    # detailed description.
+    running = True
+    while running:
+        events = sdl2ext.get_events()
+        for event in events:
+            if event.type == SDL_QUIT:
+                running = False
+                break
+            if event.type == SDL_MOUSEBUTTONDOWN:
+                curindex += 1
+                if curindex >= len(functions):
+                    curindex = 0
+                # In contrast to colorpalettes.py, our mapping table consists
+                # of functions and their arguments. Thus, we get the currently
+                # requested function and argument tuple and execute the
+                # function with the arguments.
+                func, args = functions[curindex]
+                func(*args)
+                break
+        context.present()
+    sdl2ext.quit()
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(run())

File examples/pixelaccess.py

     # A storage variable for the function we are currently on, so that we know
     # which function to execute next.
     curindex = 0
+    draw_horizontal_stripes(windowsurface, 300, 500, 200, 400)
 
     # The event loop is nearly the same as we used in colorpalettes.py. If you
     # do not know, what happens here, take a look at colorpalettes.py for a

File sdl2/ext/sprite.py

     def clear(self, color=None):
         """Clears the rendering context with the currently set or passed
         color."""
-        if color:
+        if color is not None:
             tmp = self.color
             self.color = color
         ret = render.SDL_RenderClear(self.renderer)
-        if color:
+        if color is not None:
             self.color = tmp
         if ret == -1:
             raise SDLError()
         if (pcount % 4) != 0:
             raise ValueError("points does not contain a valid set of points")
         if pcount == 4:
-            if color:
+            if color is not None:
                 tmp = self.color
                 self.color = color
             x1, y1, x2, y2 = points
             ret = render.SDL_RenderDrawLine(self.renderer, x1, y1, x2, y2)
-            if color:
+            if color is not None:
                 self.color = tmp
             if ret == -1:
                 raise SDLError()
                 ptlist[off] = SDL_Point(points[x], points[x + 1])
                 x += 2
                 off += 1
-            if color:
+            if color is not None:
                 tmp = self.color
                 self.color = color
             ptr = cast(ptlist, POINTER(SDL_Point))
             ret = render.SDL_RenderDrawLines(self.renderer, ptr, pcount / 2)
-            if color:
+            if color is not None:
                 self.color = tmp
             if ret == -1:
                 raise SDLError()
         if (pcount % 2) != 0:
             raise ValueError("points does not contain a valid set of points")
         if pcount == 2:
-            if color:
+            if color is not None:
                 tmp = self.color
                 self.color = color
             ret = render.SDL_RenderDrawPoint(self.renderer, points[0],
                                              points[1])
-            if color:
+            if color is not None:
                 self.color = tmp
             if ret == -1:
                 raise SDLError()
                 ptlist[off] = SDL_Point(points[x], points[x + 1])
                 x += 2
                 off += 1
-            if color:
+            if color is not None:
                 tmp = self.color
                 self.color = color
             ptr = cast(ptlist, POINTER(SDL_Point))
             ret = render.SDL_RenderDrawPoints(self.renderer, ptr)
-            if color:
+            if color is not None:
                 self.color = tmp
             if ret == -1:
                 raise SDLError()
         # ((x, y, w, h), ...)
         if type(rects[0]) == int:
             # single rect
-            if color:
+            if color is not None:
                 tmp = self.color
                 self.color = color
             x, y, w, h = rects
             ret = render.SDL_RenderDrawRect(self.renderer, x, y, w, h)
-            if color:
+            if color is not None:
                 self.color = tmp
             if ret == -1:
                 raise SDLError()
             rlist = (SDL_Rect * len(rects))()
             for idx, r in enumerate(rects):
                 rlist[idx] = SDL_Rect(r[0], r[1], r[2], r[3])
-            if color:
+            if color is not None:
                 tmp = self.color
                 self.color = color
             ptr = cast(rlist, SDL_Rect)
             ret = render.SDL_RenderDrawRects(self.renderer, ptr)
-            if color:
+            if color is not None:
                 self.color = tmp
             if ret == -1:
                 raise SDLError()
         # ((x, y, w, h), ...)
         if type(rects[0]) == int:
             # single rect
-            if color:
+            if color is not None:
                 tmp = self.color
                 self.color = color
             x, y, w, h = rects
             ret = render.SDL_RenderFillRect(self.renderer, x, y, w, h)
-            if color:
+            if color is not None:
                 self.color = tmp
             if ret == -1:
                 raise SDLError()
             rlist = (SDL_Rect * len(rects))()
             for idx, r in enumerate(rects):
                 rlist[idx] = SDL_Rect(r[0], r[1], r[2], r[3])
-            if color:
+            if color is not None:
                 tmp = self.color
                 self.color = color
             ptr = cast(rlist, SDL_Rect)
             ret = render.SDL_RenderFillRects(self.renderer, ptr)
-            if color:
+            if color is not None:
                 self.color = tmp
             if ret == -1:
                 raise SDLError()

File sdl2/sdlgfx.py

+import os
+from ctypes import Structure, POINTER, c_int, c_float, c_void_p, c_char, \
+    c_char_p, c_double
+from .dll import _DLL
+from .stdinc import Uint8, Uint32, Sint16
+from .render import SDL_Renderer
+from .surface import SDL_Surface
+
+__all__ = ["get_dll_file", "FPS_UPPER_LIMIT", "FPS_LOWER_LIMIT", "FPS_DEFAULT",
+           "FPSManager", "SDL_initFramerate", "SDL_getFramerate",
+           "SDL_setFramerate", "SDL_getFramecount", "SDL_framerateDelay",
+           "SDL2_GFXPRIMITIVES_MAJOR", "SDL2_GFXPRIMITIVES_MAJOR",
+           "SDL2_GFXPRIMITIVES_MICRO", "pixelColor", "pixelRGBA", "hlineColor",
+           "hlineRGBA", "vlineColor", "vlineRGBA", "rectangleColor",
+           "rectangleRGBA", "roundedRectangleColor", "roundedRectangleRGBA",
+           "boxColor", "boxRGBA", "roundedBoxColor", "roundedBoxRGBA",
+           "lineColor", "lineRGBA", "aalineColor", "aalineRGBA",
+           "thickLineColor", "thickLineRGBA", "circleColor", "circleRGBA",
+           "arcColor", "arcRGBA", "aacircleColor", "aacircleRGBA",
+           "filledCircleColor", "filledCircleRGBA", "ellipseColor",
+           "ellipseRGBA", "aaellipseColor", "aaellipseRGBA",
+           "filledEllipseColor", "filledEllipseRGBA", "pieColor", "pieRGBA",
+           "filledPieColor", "filledPieRGBA", "trigonColor", "trigonRGBA",
+           "aatrigonColor", "aatrigonRGBA", "filledTrigonColor",
+           "filledTrigonRGBA", "polygonColor", "polygonRGBA", "aapolygonColor",
+           "aapolygonRGBA", "filledPolygonColor", "filledPolygonRGBA",
+           "texturedPolygon", "bezierColor", "bezierRGBA",
+           "gfxPrimitivesSetFont", "gfxPrimitivesSetFontRotation",
+           "characterColor", "characterRGBA", "stringColor", "stringRGBA",
+           "SMOOTHING_OFF", "SMOOTHING_ON", "rotozoomSurface",
+           "rotozoomSurfaceXY", "rotozoomSurfaceSize", "rotozoomSurfaceSizeXY",
+           "zoomSurface", "zoomSurfaceSize", "shrinkSurface",
+           "rotateSurface90Degrees"
+           ]
+
+dll = _DLL("SDL2_gfx", ["SDL2_gfx", "SDL2_gfx-1.0"],
+           os.getenv("PYSDL2_DLL_PATH"))
+
+
+def get_dll_file():
+    """Gets the file name of the loaded SDL2_gfx library."""
+    return dll.libfile
+
+_bind = dll.bind_function
+
+
+FPS_UPPER_LIMIT = 200
+FPS_LOWER_LIMIT = 1
+FPS_DEFAULT = 30
+
+
+class FPSManager(Structure):
+    _fields_ = [("framecount", Uint32),
+                ("rateticks", c_float),
+                ("baseticks", Uint32),
+                ("lastticks", Uint32),
+                ("rate", Uint32)
+                ]
+
+SDL_initFramerate = _bind("SDL_initFramerate", [POINTER(FPSManager)])
+SDL_setFramerate = _bind("SDL_setFramerate", [POINTER(FPSManager), Uint32], c_int)
+SDL_getFramerate = _bind("SDL_getFramerate", [POINTER(FPSManager)], c_int)
+SDL_getFramecount = _bind("SDL_getFramecount", [POINTER(FPSManager)], Uint32)
+SDL_framerateDelay = _bind("SDL_framerateDelay", [POINTER(FPSManager)], Uint32)
+
+SDL2_GFXPRIMITIVES_MAJOR = 1
+SDL2_GFXPRIMITIVES_MINOR = 0
+SDL2_GFXPRIMITIVES_MICRO = 0
+
+pixelColor = _bind("pixelColor", [POINTER(SDL_Renderer), Sint16, Sint16, Uint32], c_int)
+pixelRGBA = _bind("pixelRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+hlineColor = _bind("hlineColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint32], c_int)
+hlineRGBA = _bind("hlineRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+vlineColor = _bind("vlineColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint32], c_int)
+vlineRGBA = _bind("vlineRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+rectangleColor = _bind("rectangleColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+rectangleRGBA = _bind("rectangleRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+roundedRectangleColor = _bind("roundedRectangleColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+roundedRectangleRGBA = _bind("roundedRectangleRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+boxColor = _bind("boxColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+boxRGBA = _bind("boxRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+roundedBoxColor = _bind("roundedBoxColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+roundedBoxRGBA = _bind("roundedBoxRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+lineColor = _bind("lineColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+lineRGBA = _bind("lineRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+aalineColor = _bind("aalineColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+aalineRGBA = _bind("aalineRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+thickLineColor = _bind("thickLineColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint32], c_int)
+thickLineRGBA = _bind("thickLineRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8, Uint8], c_int)
+circleColor = _bind("circleColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint32], c_int)
+circleRGBA = _bind("circleRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+arcColor = _bind("arcColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+arcRGBA = _bind("arcRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+aacircleColor = _bind("aacircleColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint32], c_int)
+aacircleRGBA = _bind("aacircleRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+filledCircleColor = _bind("filledCircleColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint32], c_int)
+filledCircleRGBA = _bind("filledCircleRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+ellipseColor = _bind("ellipseColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+ellipseRGBA = _bind("ellipseRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+aaellipseColor = _bind("aaellipseColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+aaellipseRGBA = _bind("aaellipseRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+filledEllipseColor = _bind("filledEllipseColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+filledEllipseRGBA = _bind("filledEllipseRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+pieColor = _bind("pieColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+pieRGBA = _bind("pieRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+filledPieColor = _bind("filledPieColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+filledPieRGBA = _bind("filledPieRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+trigonColor = _bind("trigonColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+trigonRGBA = _bind("trigonRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+aatrigonColor = _bind("aatrigonColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+aatrigonRGBA = _bind("aatrigonRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+filledTrigonColor = _bind("filledTrigonColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int)
+filledTrigonRGBA = _bind("filledTrigonRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int)
+polygonColor = _bind("polygonColor", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, Uint32], c_int)
+polygonRGBA = _bind("polygonRGBA", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, Uint8, Uint8, Uint8, Uint8], c_int) 
+aapolygonColor = _bind("aapolygonColor", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, Uint32], c_int)
+aapolygonRGBA = _bind("aapolygonRGBA", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, Uint8, Uint8, Uint8, Uint8], c_int) 
+filledPolygonColor = _bind("filledPolygonColor", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, Uint32], c_int)
+filledPolygonRGBA = _bind("filledPolygonRGBA", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, Uint8, Uint8, Uint8, Uint8], c_int) 
+texturedPolygon = _bind("texturedPolygon", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, POINTER(SDL_Surface), c_int, c_int], c_int)
+bezierColor = _bind("bezierColor", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, c_int, Uint32], c_int)
+bezierRGBA = _bind("bezierRGBA", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, c_int, Uint8, Uint8, Uint8, Uint8], c_int)
+gfxPrimitivesSetFont = _bind("gfxPrimitivesSetFont", [c_void_p, Uint32, Uint32])
+gfxPrimitivesSetFontRotation = _bind("gfxPrimitivesSetFontRotation", [Uint32])
+characterColor = _bind("characterColor", [POINTER(SDL_Renderer), Sint16, Sint16, c_char, Uint32], c_int)
+characterRGBA = _bind("characterRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, c_char, Uint8, Uint8, Uint8, Uint8], c_int)
+stringColor = _bind("stringColor", [POINTER(SDL_Renderer), Sint16, Sint16, c_char_p, Uint32], c_int)
+stringRGBA = _bind("stringRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, c_char_p, Uint8, Uint8, Uint8, Uint8], c_int)
+
+SMOOTHING_OFF = 0
+SMOOTHING_ON = 1
+rotozoomSurface = _bind("rotozoomSurface", [POINTER(SDL_Surface), c_double, c_double, c_int], POINTER(SDL_Surface))
+rotozoomSurfaceXY = _bind("rotozoomSurfaceXY", [POINTER(SDL_Surface), c_double, c_double, c_double, c_int], POINTER(SDL_Surface))
+rotozoomSurfaceSize = _bind("rotozoomSurfaceSize", [c_int, c_int, c_double, c_double, POINTER(c_int), POINTER(c_int)])
+rotozoomSurfaceSizeXY = _bind("rotozoomSurfaceSizeXY", [c_int, c_int, c_double, c_double, c_double, POINTER(c_int), POINTER(c_int)])
+zoomSurface = _bind("zoomSurface", [POINTER(SDL_Surface), c_double, c_double, c_int], POINTER(SDL_Surface))
+zoomSurfaceSize = _bind("zoomSurfaceSize", [c_int, c_int, c_double, c_double, POINTER(c_int), POINTER(c_int)])
+shrinkSurface = _bind("shrinkSurface", [POINTER(SDL_Surface), c_int, c_int], POINTER(SDL_Surface))
+rotateSurface90Degrees = _bind("rotateSurface90Degrees", [POINTER(SDL_Surface), c_int], POINTER(SDL_Surface))

File sdl2/sdlimage.py

 dll = _DLL("SDL2_image", ["SDL2_image", "SDL2_image-2.0"],
            os.getenv("PYSDL2_DLL_PATH"))
 
+
 def get_dll_file():
-    """Gets the file name of the loaded SDL2 library."""
+    """Gets the file name of the loaded SDL2_image library."""
     return dll.libfile
 
 _bind = dll.bind_function
 SDL_IMAGE_MINOR_VERSION = 0
 SDL_IMAGE_PATCHLEVEL = 0
 
+
 def SDL_IMAGE_VERSION(x):
     x.major = SDL_IMAGE_MAJOR_VERSION
     x.minor = SDL_IMAGE_MINOR_VERSION

File sdl2/sdlttf.py

 from .rwops import SDL_RWops
 from .stdinc import Uint16, Uint32
 from .pixels import SDL_Color
-from .surface import SDL_Surface 
+from .surface import SDL_Surface
 from .error import SDL_GetError, SDL_SetError
 
-__all__= ["get_dll_file", "SDL_TTF_MAJOR_VERSION", "SDL_TTF_MINOR_VERSION",
+__all__ = ["get_dll_file", "SDL_TTF_MAJOR_VERSION", "SDL_TTF_MINOR_VERSION",
           "SDL_TTF_PATCHLEVEL", "SDL_TTF_VERSION", "TTF_MAJOR_VERSION",
           "TTF_MINOR_VERSION", "TTF_PATCHLEVEL", "TTF_VERSION",
           "TTF_Linked_Version", "UNICODE_BOM_NATIVE", "UNICODE_BOM_SWAPPED",
 dll = _DLL("SDL2_ttf", ["SDL2_ttf", "SDL2_ttf-2.0"],
            os.getenv("PYSDL2_DLL_PATH"))
 
+
 def get_dll_file():
-    """Gets the file name of the loaded SDL2 library."""
+    """Gets the file name of the loaded SDL2_ttf library."""
     return dll.libfile
 
 _bind = dll.bind_function
 SDL_TTF_MINOR_VERSION = 0
 SDL_TTF_PATCHLEVEL = 12
 
+
 def SDL_TTF_VERSION(x):
     x.major = SDL_TTF_MAJOR_VERSION
     x.minor = SDL_TTF_MINOR_VERSION
 
 TTF_ByteSwappedUNICODE = _bind("TTF_ByteSwappedUNICODE", [c_int])
 
+
 class TTF_Font(Structure):
     pass