Commits

Lenard Lindstrom committed 015c04a

add gfxdraw unit tests and fix uncovered bugs

Comments (0)

Files changed (9)

docs/ref/cursors.html

 <a name="pygame.cursors.load_xbm">
 <big><b>pygame.cursors.load_xbm</big></b><br><ul>
   <i>load cursor data from an xbm file</i><br>
-  <tt>pygame.cursors.load_xbm(cursorfile, maskfile=None): return cursor_args</tt><br>
+  <tt>pygame.cursors.load_xbm(cursorfile): return cursor_args</tt><br>
+  <tt>pygame.cursors.load_xbm(cursorfile, maskfile): return cursor_args</tt><br>
 <p>This loads cursors for a simple subset of <tt>XBM</tt> files. <tt>XBM</tt> files are traditionally used to store cursors on unix systems, they are an ascii format used to represent simple images. </p>
 <p>Sometimes the black and white color values will be split into two separate <tt>XBM</tt> files. You can pass a second maskfile argument to load the two images into a single cursor. </p>
 <p>The cursorfile and maskfile arguments can either be filenames or filelike object with the readlines method. </p>

docs/ref/gfxdraw.html

 <p><tt>EXPERIMENTAL!:</tt> meaning this api may change, or dissapear in later pygame releases. If you use this, your code will break with the next pygame release. </p>
 <p>Most of the functions accept a color argument that is an <tt>RGB</tt> triplet. These can also accept an <tt>RGBA</tt> quadruplet. The color argument can also be an integer pixel value that is already mapped to the Surface's pixel format. </p>
 <p>For all functions the arguments are strictly positional. Only integers are accepted for coordinates and radii. </p>
+<p>For functions like rectangle that accept a rect argument any (x, y, w, h) sequence is accepted, though <tt>pygame.Rect</tt> instances are prefered. Note that for a <tt>pygame.Rect</tt> the drawing will not include <tt>Rect.bottomright</tt>. The right and bottom attributes of a Rect lie one pixel outside of the Rect's boarder. </p>
 <p>New in pygame <tt>1.9.0</tt>. </p>
 <!--COMMENTS:pygame.gfxdraw--> &nbsp;<br> 
 
 <big><b>pygame.gfxdraw.textured_polygon</big></b><br><ul>
   <i>draw a textured polygon</i><br>
   <tt>pgyame.gfxdraw.textured_polygon(surface, points, texture, tx, ty): return None</tt><br>
- &nbsp;<br> 
+<p><tt>A</tt> per-pixel alpha texture blit to a per-pixel alpha surface will differ from a <tt><a href="surface.html#Surface.blit">Surface.blit</a> - <font size=-1>draw one image onto another</font></tt> blit. Also, a per-pixel alpha texture cannot be used with an 8-bit per pixel destination. </p>
 <!--COMMENTS:pygame.gfxdraw.textured_polygon--> &nbsp;<br> 
 <br></ul>
 

docs/ref/mask.html

 <a name="pygame.mask.from_threshold">
 <big><b>pygame.mask.from_threshold</big></b><br><ul>
   <i>Creates a mask by thresholding Surfaces</i><br>
-  <tt>pygame.mask.from_surface(Surface, color, threshold = (0,0,0,255), othersurface = None) -> Mask</tt><br>
+  <tt>pygame.mask.from_surface(Surface, color, threshold = (0,0,0,255), othersurface = None, palette_colors = 1) -> Mask</tt><br>
 <p>This is a more featureful method of getting a Mask from a Surface. If supplied with only one Surface, all pixels within the threshold of the supplied color are set in the Mask. If given the optional othersurface, all pixels in Surface that are within the threshold of the corresponding pixel in othersurface are set in the Mask. </p>
 <!--COMMENTS:pygame.mask.from_threshold--> &nbsp;<br> 
 <br></ul>

examples/aacircle.py

-#!/usr/bin/env python
-
-"""Proof of concept gfxdraw example"""
-
-import pygame
-import pygame.gfxdraw
-
-def main():
-    pygame.init()
-    screen = pygame.display.set_mode((500,500))
-    screen.fill((255, 0, 0))
-    s = pygame.Surface(screen.get_size(), pygame.SRCALPHA, 32)
-    pygame.gfxdraw.aacircle(s, 250, 250, 200, (0, 0, 0))
-    screen.blit(s, (0, 0))
-    pygame.display.flip()
-    try:
-        while 1:
-            event = pygame.event.wait()
-            if event.type == pygame.QUIT:
-                break
-            if event.type == pygame.KEYDOWN:
-                if event.key == pygame.K_ESCAPE or event.unicode == 'q':
-                    break
-            pygame.display.flip()
-    finally:
-        pygame.quit()
-
-if __name__ == '__main__':
-    main()
+#!/usr/bin/env python
+
+"""Proof of concept gfxdraw example"""
+
+import pygame
+import pygame.gfxdraw
+
+def main():
+    pygame.init()
+    screen = pygame.display.set_mode((500,500))
+    screen.fill((255, 0, 0))
+    s = pygame.Surface(screen.get_size(), pygame.SRCALPHA, 32)
+    pygame.gfxdraw.aacircle(s, 250, 250, 200, (0, 0, 0))
+    screen.blit(s, (0, 0))
+    pygame.display.flip()
+    try:
+        while 1:
+            event = pygame.event.wait()
+            if event.type == pygame.QUIT:
+                break
+            if event.type == pygame.KEYDOWN:
+                if event.key == pygame.K_ESCAPE or event.unicode == 'q':
+                    break
+            pygame.display.flip()
+    finally:
+        pygame.quit()
+
+if __name__ == '__main__':
+    main()
 _gfx_rectanglecolor (PyObject *self, PyObject* args)
 {
     PyObject *surface, *color, *rect;
-    GAME_Rect sdlrect;
+    GAME_Rect temprect, *sdlrect;
     Sint16 x1, x2, _y1, y2;
     Uint8 rgba[4];
 
     ASSERT_VIDEO_INIT (NULL);
 
-    if (!PyArg_ParseTuple (args, "OOO:rectangle", &surface, &rect, &color))
+    if (!PyArg_ParseTuple (args, "OOO:rectangle", &surface, &rect, &color)) {
         return NULL;
+    }
     
-    if (!PySurface_Check (surface))
-    {
+    if (!PySurface_Check (surface)) {
         PyErr_SetString (PyExc_TypeError, "surface must be a Surface");
         return NULL;
     }
-    if (!GameRect_FromObject (rect, &sdlrect))
+    sdlrect = GameRect_FromObject (rect, &temprect);
+    if (sdlrect == NULL) {
         return NULL;
+    }
 
-    if (!RGBAFromObj (color, rgba))
-    {
+    if (!RGBAFromObj (color, rgba)) {
         PyErr_SetString (PyExc_TypeError, "invalid color argument");
         return NULL;
     }
 
-    x1 = sdlrect.x;
-    _y1 = sdlrect.y;
-    x2 = (Sint16) (sdlrect.x + sdlrect.w);
-    y2 = (Sint16) (sdlrect.y + sdlrect.h);
+    x1 = sdlrect->x;
+    _y1 = sdlrect->y;
+    x2 = (Sint16) (sdlrect->x + sdlrect->w - 1);
+    y2 = (Sint16) (sdlrect->y + sdlrect->h - 1);
 
-    if (rectangleRGBA (PySurface_AsSurface (surface), x1, x2, _y1, y2,
+    if (rectangleRGBA (PySurface_AsSurface (surface), x1, _y1, x2, y2,
 		       rgba[0], rgba[1], rgba[2], rgba[3]) ==
-        -1)
-    {
+        -1) {
         PyErr_SetString (PyExc_SDLError, SDL_GetError ());
         return NULL;
     }
 _gfx_boxcolor (PyObject *self, PyObject* args)
 {
     PyObject *surface, *color, *rect;
-    GAME_Rect sdlrect;
+    GAME_Rect temprect, *sdlrect;
     Sint16 x1, x2, _y1, y2;
     Uint8 rgba[4];
 
     ASSERT_VIDEO_INIT (NULL);
 
-    if (!PyArg_ParseTuple (args, "OOO:box", &surface, &rect, &color))
+    if (!PyArg_ParseTuple (args, "OOO:box", &surface, &rect, &color)) {
         return NULL;
+    }
     
-    if (!PySurface_Check (surface))
-    {
+    if (!PySurface_Check (surface)) {
         PyErr_SetString (PyExc_TypeError, "surface must be a Surface");
         return NULL;
     }
-    if (!GameRect_FromObject (rect, &sdlrect))
+    sdlrect = GameRect_FromObject (rect, &temprect);
+    if (sdlrect == NULL) {
         return NULL;
-
-    if (!RGBAFromObj (color, rgba))
-    {
+    }
+    if (!RGBAFromObj (color, rgba)) {
         PyErr_SetString (PyExc_TypeError, "invalid color argument");
         return NULL;
     }
 
-    x1 = sdlrect.x;
-    _y1 = sdlrect.y;
-    x2 = (Sint16) (sdlrect.x + sdlrect.w);
-    y2 = (Sint16) (sdlrect.y + sdlrect.h);
+    x1 = sdlrect->x;
+    _y1 = sdlrect->y;
+    x2 = (Sint16) (sdlrect->x + sdlrect->w - 1);
+    y2 = (Sint16) (sdlrect->y + sdlrect->h - 1);
 
-    if (rectangleRGBA (PySurface_AsSurface (surface), x1, x2, _y1, y2,
+    if (boxRGBA (PySurface_AsSurface (surface), x1, _y1, x2, y2,
 		       rgba[0], rgba[1], rgba[2], rgba[3]) ==
-        -1)
-    {
+        -1) {
         PyErr_SetString (PyExc_SDLError, SDL_GetError ());
         return NULL;
     }
 _gfx_texturedpolygon (PyObject *self, PyObject* args)
 {
     PyObject *surface, *texture, *points, *item;
+    SDL_Surface *s_surface, *s_texture;
     Sint16 *vx, *vy, x, y, tdx, tdy;
     Py_ssize_t count, i;
     int ret;
         PyErr_SetString (PyExc_TypeError, "surface must be a Surface");
         return NULL;
     }
+    s_surface = PySurface_AsSurface (surface);
     if (!PySurface_Check (texture))
     {
         PyErr_SetString (PyExc_TypeError, "texture must be a Surface");
         return NULL;
     }
+    s_texture = PySurface_AsSurface (texture);
     if (!PySequence_Check (points))
     {
         PyErr_SetString (PyExc_TypeError, "points must be a sequence");
         return NULL;
     }
+    if (s_surface->format->BytesPerPixel == 1 &&
+        (s_texture->format->Amask || s_texture->flags & SDL_SRCALPHA)) {
+        PyErr_SetString (PyExc_ValueError,
+                           "Per-byte alpha texture unsupported "
+                           "for 8 bit surfaces");
+        return NULL;
+    }
 
     count = PySequence_Size (points);
     if (count < 3)
     }
 
     Py_BEGIN_ALLOW_THREADS;
-    ret = texturedPolygon (PySurface_AsSurface (surface), vx, vy, (int)count,
-			   PySurface_AsSurface (texture), tdx, tdy);
+    ret = texturedPolygon (s_surface, vx, vy, (int)count,
+                           s_texture, tdx, tdy);
     Py_END_ALLOW_THREADS;
 
     PyMem_Free (vx);
 For all functions the arguments are strictly positional. Only integers are
 accepted for coordinates and radii.
 
+For functions like rectangle that accept a rect argument any (x, y, w, h)
+sequence is accepted, though pygame.Rect instances are prefered. Note that
+for a pygame.Rect the drawing will not include Rect.bottomright. The right
+and bottom attributes of a Rect lie one pixel outside of the Rect's boarder.
+
 New in pygame 1.9.0.
 <SECTION>
 
 textured_polygon
 draw a textured polygon
 pgyame.gfxdraw.textured_polygon(surface, points, texture, tx, ty): return None
+
+A per-pixel alpha texture blit to a per-pixel alpha surface will differ from a
+Surface.blit() blit. Also, a per-pixel alpha texture cannot be used with an
+8-bit per pixel destination.
 <END>
 
 
     ((x)->ob_type == (PyTypeObject*)                                    \
         PyGAME_C_API[PYGAMEAPI_COLOR_FIRSTSLOT + 0])
 #define PyColor_New                                                     \
-    (*(PyObject*(*)) PyGAME_C_API[PYGAMEAPI_COLOR_FIRSTSLOT + 1])
+    (*(PyObject *(*)(Uint8*)) PyGAME_C_API[PYGAMEAPI_COLOR_FIRSTSLOT + 1])
 #define RGBAFromColorObj                                                \
     (*(int(*)(PyObject*, Uint8*)) PyGAME_C_API[PYGAMEAPI_COLOR_FIRSTSLOT + 2])
 #define import_pygame_color()                                           \
 
 #define DOC_PYGAMECURSORSCOMPILE "pygame.cursor.compile(strings, black='X', white='.', xor='o'): return data, mask\ncreate binary cursor data from simple strings"
 
-#define DOC_PYGAMECURSORSLOADXBM "pygame.cursors.load_xbm(cursorfile, maskfile=None): return cursor_args\nload cursor data from an xbm file"
+#define DOC_PYGAMECURSORSLOADXBM "pygame.cursors.load_xbm(cursorfile): return cursor_args\npygame.cursors.load_xbm(cursorfile, maskfile): return cursor_args\nload cursor data from an xbm file"
 
 #define DOC_PYGAMEDISPLAY "pygame module to control the display window and screen"
 
 
 #define DOC_PYGAMEMASKFROMSURFACE "pygame.mask.from_surface(Surface, threshold = 127) -> Mask\nReturns a Mask from the given surface."
 
-#define DOC_PYGAMEMASKFROMTHRESHOLD "pygame.mask.from_surface(Surface, color, threshold = (0,0,0,255), othersurface = None) -> Mask\nCreates a mask by thresholding Surfaces"
+#define DOC_PYGAMEMASKFROMTHRESHOLD "pygame.mask.from_surface(Surface, color, threshold = (0,0,0,255), othersurface = None, palette_colors = 1) -> Mask\nCreates a mask by thresholding Surfaces"
 
 #define DOC_PYGAMEMASKMASK "pygame.Mask((width, height)): return Mask\npygame object for representing 2d bitmasks"
 
 
 
 pygame.cursors.load_xbm
- pygame.cursors.load_xbm(cursorfile, maskfile=None): return cursor_args
+ pygame.cursors.load_xbm(cursorfile): return cursor_args
+pygame.cursors.load_xbm(cursorfile, maskfile): return cursor_args
 load cursor data from an xbm file
 
 
 
 
 pygame.mask.from_threshold
- pygame.mask.from_surface(Surface, color, threshold = (0,0,0,255), othersurface = None) -> Mask
+ pygame.mask.from_surface(Surface, color, threshold = (0,0,0,255), othersurface = None, palette_colors = 1) -> Mask
 Creates a mask by thresholding Surfaces
 
 

test/gfxdraw_test.py

+if __name__ == '__main__':
+    import sys
+    import os
+    pkg_dir = os.path.split(os.path.abspath(__file__))[0]
+    parent_dir, pkg_name = os.path.split(pkg_dir)
+    is_pygame_pkg = (pkg_name == 'tests' and
+                     os.path.split(parent_dir)[1] == 'pygame')
+    if not is_pygame_pkg:
+        sys.path.insert(0, parent_dir)
+else:
+    is_pygame_pkg = __name__.startswith('pygame.tests.')
+
+if is_pygame_pkg:
+    from pygame.tests.test_utils import unittest
+else:
+    from test.test_utils import unittest
+import pygame
+import pygame.gfxdraw
+from pygame.locals import *
+
+def intensity(c, i):
+    """Return color c changed by intensity i
+
+    For 0 <= i <= 127 the color is a shade, with 0 being black, 127 being the
+    unaltered color.
+
+    For 128 <= i <= 255 the color is a tint, with 255 being white, 128 the
+    unaltered color.
+
+    """
+    r, g, b = c[0:3]
+    if 0 <= i <= 127:
+        # Darken
+        return ((r * i) // 127, (g * i) // 127, (b * i) // 127)
+    # Lighten
+    return (r + ((255 - r) * (255 - i)) // 127,
+            g + ((255 - g) * (255 - i)) // 127,
+            b + ((255 - b) * (255 - i)) // 127)
+
+class GfxdrawDefaultTest( unittest.TestCase ):
+
+    is_started = False
+
+    foreground_color = (128, 64, 8)
+    background_color = (255, 255, 255)
+
+    def make_palette(base_color):
+        """Return color palette that is various intensities of base_color"""
+        # Need this function for Python 3.x so the base_color
+        # is within the scope of the list comprehension.
+        return [intensity(base_color, i) for i in range(0, 256)]
+
+    default_palette = make_palette(foreground_color)
+
+    default_size = (100, 100)
+
+    def check_at(self, surf, posn, color):
+        sc = surf.get_at(posn)
+        fail_msg = ("%s != %s at %s, bitsize: %i, flags: %i, masks: %s" %
+                    (sc, color, posn, surf.get_bitsize(), surf.get_flags(),
+                     surf.get_masks()))
+        self.failUnlessEqual(sc, color, fail_msg)
+
+    def check_not_at(self, surf, posn, color):
+        sc = surf.get_at(posn)
+        fail_msg = ("%s != %s at %s, bitsize: %i, flags: %i, masks: %s" %
+                    (sc, color, posn, surf.get_bitsize(), surf.get_flags(),
+                     surf.get_masks()))
+        self.failIfEqual(sc, color, fail_msg)
+
+    def setUp(self):
+        Surface = pygame.Surface
+        size = self.default_size
+        palette = self.default_palette
+        if not self.is_started:
+            # Necessary for Surface.set_palette.
+            pygame.init()
+            pygame.display.set_mode((1, 1))
+            # Create test surfaces
+            self.surfaces = [Surface(size, 0, 8),
+                             Surface(size, 0, 16),
+                             Surface(size, 0, 24),
+                             Surface(size, 0, 32),
+                             Surface(size, SRCALPHA, 16),
+                             Surface(size, SRCALPHA, 32)]
+            self.surfaces[0].set_palette(palette)
+            # Special pixel formats
+            for i in range(1, 6):
+                s = self.surfaces[i]
+                flags = s.get_flags()
+                bitsize = s.get_bitsize()
+                masks = s.get_masks()
+                if flags:
+                    masks = (masks[1], masks[2], masks[3], masks[0])
+                else:
+                    masks = (masks[1], masks[2], masks[0], masks[3])
+                self.surfaces.append(Surface(size, flags, bitsize, masks))
+        for surf in self.surfaces:
+            surf.fill(self.background_color)
+
+    def test_pixel(self):
+        """pixel(surface, x, y, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.pixel(surf, 2, 2, fg)
+            for x in range(1, 4):
+                for y in range(1, 4):
+                    if x == 2 and y == 2:
+                        self.check_at(surf, (x, y), fg_adjusted)
+                    else:
+                        self.check_at(surf, (x, y), bg_adjusted)
+
+    def test_hline(self):
+        """hline(surface, x1, x2, y, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        startx = 10
+        stopx = 80
+        y = 50
+        fg_test_points = [(startx, y), (stopx, y), ((stopx - startx) // 2, y)]
+        bg_test_points = [(startx - 1, y), (stopx + 1, y),
+                          (startx, y - 1), (startx, y + 1),
+                          (stopx, y - 1), (stopx, y + 1)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.hline(surf, startx, stopx, y, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_vline(self):
+        """vline(surface, x, y1, y2, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x = 50
+        starty = 10
+        stopy = 80
+        fg_test_points = [(x, starty), (x, stopy), (x, (stopy - starty) // 2)]
+        bg_test_points = [(x, starty - 1), (x, stopy + 1),
+                          (x - 1, starty), (x + 1, starty),
+                          (x - 1, stopy), (x + 1, stopy)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.vline(surf, x, starty, stopy, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_rectangle(self):
+        """rectangle(surface, rect, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        rect = pygame.Rect(10, 15, 55, 62)
+        rect_tuple = tuple(rect)
+        fg_test_points = [rect.topleft,
+                          (rect.right - 1, rect.top),
+                          (rect.left, rect.bottom - 1),
+                          (rect.right - 1, rect.bottom - 1)]
+        bg_test_points = [(rect.left - 1, rect.top - 1),
+                          (rect.left + 1, rect.top + 1),
+                          (rect.right, rect.top - 1),
+                          (rect.right - 2, rect.top + 1),
+                          (rect.left - 1, rect.bottom),
+                          (rect.left + 1, rect.bottom - 2),
+                          (rect.right, rect.bottom),
+                          (rect.right - 2, rect.bottom - 2)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.rectangle(surf, rect, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+            surf.fill(bg)
+            pygame.gfxdraw.rectangle(surf, rect_tuple, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_box(self):
+        """box(surface, rect, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        rect = pygame.Rect(10, 15, 55, 62)
+        rect_tuple = tuple(rect)
+        fg_test_points = [rect.topleft,
+                          (rect.left + 1, rect.top + 1),
+                          (rect.right - 1, rect.top),
+                          (rect.right - 2, rect.top + 1),
+                          (rect.left, rect.bottom - 1),
+                          (rect.left + 1, rect.bottom - 2),
+                          (rect.right - 1, rect.bottom - 1),
+                          (rect.right - 2, rect.bottom - 2)]
+        bg_test_points = [(rect.left - 1, rect.top - 1),
+                          (rect.right, rect.top - 1),
+                          (rect.left - 1, rect.bottom),
+                          (rect.right, rect.bottom)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.box(surf, rect, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+            surf.fill(bg)
+            pygame.gfxdraw.box(surf, rect_tuple, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_line(self):
+        """line(surface, x1, y1, x2, y2, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x1 = 10
+        y1 = 15
+        x2 = 92
+        y2 = 77
+        fg_test_points = [(x1, y1), (x2, y2)]
+        bg_test_points = [(x1 - 1, y1), (x1, y1 - 1), (x1 - 1, y1 - 1),
+                          (x2 + 1, y2), (x2, y2 + 1), (x2 + 1, y2 + 1)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.line(surf, x1, y1, x2, y2, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_circle(self):
+        """circle(surface, x, y, r, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x = 45
+        y = 40
+        r = 30
+        fg_test_points = [(x, y - r),
+                          (x, y + r),
+                          (x - r, y),
+                          (x + r, y)]
+        bg_test_points = [(x, y),
+                          (x, y - r + 1),
+                          (x, y - r - 1),
+                          (x, y + r + 1),
+                          (x, y + r - 1),
+                          (x - r - 1, y),
+                          (x - r + 1, y),
+                          (x + r + 1, y),
+                          (x + r - 1, y)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.circle(surf, x, y, r, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_arc(self):
+        """arc(surface, x, y, r, start, end, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x = 45
+        y = 40
+        r = 30
+        start = 0  # +x direction, but not (x + r, y) (?)
+        end = 90   # -y direction, including (x, y + r)
+        fg_test_points = [(x, y + r), (x + r, y + 1)]
+        bg_test_points = [(x, y),
+                          (x, y - r),
+                          (x - r, y),
+                          (x, y + r + 1),
+                          (x, y + r - 1),
+                          (x - 1, y + r),
+                          (x + r + 1, y),
+                          (x + r - 1, y),
+                          (x + r, y)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.arc(surf, x, y, r, start, end, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_aacircle(self):
+        """aacircle(surface, x, y, r, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x = 45
+        y = 40
+        r = 30
+        fg_test_points = [(x, y - r),
+                          (x, y + r),
+                          (x - r, y),
+                          (x + r, y)]
+        bg_test_points = [(x, y),
+                          (x, y - r + 1),
+                          (x, y - r - 1),
+                          (x, y + r + 1),
+                          (x, y + r - 1),
+                          (x - r - 1, y),
+                          (x - r + 1, y),
+                          (x + r + 1, y),
+                          (x + r - 1, y)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.aacircle(surf, x, y, r, fg)
+            for posn in fg_test_points:
+                self.check_not_at(surf, posn, bg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_filled_circle(self):
+        """filled_circle(surface, x, y, r, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x = 45
+        y = 40
+        r = 30
+        fg_test_points = [(x, y - r),
+                          (x, y - r + 1),
+                          (x, y + r),
+                          (x, y + r - 1),
+                          (x - r, y),
+                          (x - r + 1, y),
+                          (x + r, y),
+                          (x + r - 1, y),
+                          (x, y)]
+        bg_test_points = [(x, y - r - 1),
+                          (x, y + r + 1),
+                          (x - r - 1, y),
+                          (x + r + 1, y)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.filled_circle(surf, x, y, r, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_ellipse(self):
+        """ellipse(surface, x, y, rx, ry, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x = 45
+        y = 40
+        rx = 30
+        ry = 35
+        fg_test_points = [(x, y - ry),
+                          (x, y + ry),
+                          (x - rx, y),
+                          (x + rx, y)]
+        bg_test_points = [(x, y),
+                          (x, y - ry + 1),
+                          (x, y - ry - 1),
+                          (x, y + ry + 1),
+                          (x, y + ry - 1),
+                          (x - rx - 1, y),
+                          (x - rx + 1, y),
+                          (x + rx + 1, y),
+                          (x + rx - 1, y)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.ellipse(surf, x, y, rx, ry, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_aaellipse(self):
+        """aaellipse(surface, x, y, rx, ry, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x = 45
+        y = 40
+        rx = 30
+        ry = 35
+        fg_test_points = [(x, y - ry),
+                          (x, y + ry),
+                          (x - rx, y),
+                          (x + rx, y)]
+        bg_test_points = [(x, y),
+                          (x, y - ry + 1),
+                          (x, y - ry - 1),
+                          (x, y + ry + 1),
+                          (x, y + ry - 1),
+                          (x - rx - 1, y),
+                          (x - rx + 1, y),
+                          (x + rx + 1, y),
+                          (x + rx - 1, y)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.aaellipse(surf, x, y, rx, ry, fg)
+            for posn in fg_test_points:
+                self.check_not_at(surf, posn, bg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_filled_ellipse(self):
+        """filled_ellipse(surface, x, y, rx, ry, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x = 45
+        y = 40
+        rx = 30
+        ry = 35
+        fg_test_points = [(x, y - ry),
+                          (x, y - ry + 1),
+                          (x, y + ry),
+                          (x, y + ry - 1),
+                          (x - rx, y),
+                          (x - rx + 1, y),
+                          (x + rx, y),
+                          (x + rx - 1, y),
+                          (x, y)]
+        bg_test_points = [(x, y - ry - 1),
+                          (x, y + ry + 1),
+                          (x - rx - 1, y),
+                          (x + rx + 1, y)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.filled_ellipse(surf, x, y, rx, ry, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_pie(self):
+        """pie(surface, x, y, r, start, end, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x = 45
+        y = 40
+        r = 30
+        start = 0  # +x direction, including (x + r, y)
+        end = 90   # -y direction, but not (x, y + r) (?)
+        fg_test_points = [(x, y),
+                          (x + 1, y),
+                          (x, y + 1),
+                          (x + r, y)]
+        bg_test_points = [(x - 1, y),
+                          (x, y - 1),
+                          (x - 1, y - 1),
+                          (x + 1, y + 1),
+                          (x + r + 1, y),
+                          (x + r, y - 1),
+                          (x, y + r)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.pie(surf, x, y, r, start, end, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_trigon(self):
+        """trigon(surface, x1, y1, x2, y2, x3, y3, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x1 = 10
+        y1 = 15
+        x2 = 92
+        y2 = 77
+        x3 = 20
+        y3 = 60
+        fg_test_points = [(x1, y1), (x2, y2), (x3, y3)]
+        bg_test_points = [(x1 - 1, y1 - 1),
+                          (x2 + 1, y2 + 1),
+                          (x3 - 1, y3 + 1),
+                          (x1 + 10, y1 + 30)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.trigon(surf, x1, y1, x2, y2, x3, y3, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_aatrigon(self):
+        """aatrigon(surface, x1, y1, x2, y2, x3, y3, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x1 = 10
+        y1 = 15
+        x2 = 92
+        y2 = 77
+        x3 = 20
+        y3 = 60
+        fg_test_points = [(x1, y1), (x2, y2), (x3, y3)]
+        bg_test_points = [(x1 - 1, y1 - 1),
+                          (x2 + 1, y2 + 1),
+                          (x3 - 1, y3 + 1),
+                          (x1 + 10, y1 + 30)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.aatrigon(surf, x1, y1, x2, y2, x3, y3, fg)
+            for posn in fg_test_points:
+                self.check_not_at(surf, posn, bg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_filled_trigon(self):
+        """filled_trigon(surface, x1, y1, x2, y2, x3, y3, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        x1 = 10
+        y1 = 15
+        x2 = 92
+        y2 = 77
+        x3 = 20
+        y3 = 60
+        fg_test_points = [(x1, y1), (x2, y2), (x3, y3),
+                          (x1 + 10, y1 + 30)]
+        bg_test_points = [(x1 - 1, y1 - 1),
+                          (x2 + 1, y2 + 1),
+                          (x3 - 1, y3 + 1)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.filled_trigon(surf, x1, y1, x2, y2, x3, y3, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_polygon(self):
+        """polygon(surface, points, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        points = [(10, 80), (10, 15), (92, 25), (92, 80)]
+        fg_test_points = (points +
+                          [(points[0][0], points[0][1] - 1),
+                           (points[0][0] + 1, points[0][1]),
+                           (points[3][0] - 1, points[3][1]),
+                           (points[3][0], points[3][1] - 1),
+                           (points[2][0], points[2][1] + 1)])
+        bg_test_points = [(points[0][0] - 1, points[0][1]),
+                          (points[0][0], points[0][1] + 1),
+                          (points[0][0] - 1, points[0][1] + 1),
+                          (points[0][0] + 1, points[0][1] - 1),
+                          (points[3][0] + 1, points[3][1]),
+                          (points[3][0], points[3][1] + 1),
+                          (points[3][0] + 1, points[3][1] + 1),
+                          (points[3][0] - 1, points[3][1] - 1),
+                          (points[2][0] + 1, points[2][1]),
+                          (points[2][0] - 1, points[2][1] + 1),
+                          (points[1][0] - 1, points[1][1]),
+                          (points[1][0], points[1][1] - 1),
+                          (points[1][0] - 1, points[1][1] - 1)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.polygon(surf, points, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_aapolygon(self):
+        """aapolygon(surface, points, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        points = [(10, 80), (10, 15), (92, 25), (92, 80)]
+        fg_test_points = (points +
+                          [(points[0][0], points[0][1] - 1),
+                           (points[0][0] + 1, points[0][1]),
+                           (points[3][0] - 1, points[3][1]),
+                           (points[3][0], points[3][1] - 1),
+                           (points[2][0], points[2][1] + 1)])
+        bg_test_points = [(points[0][0] - 1, points[0][1]),
+                          (points[0][0], points[0][1] + 1),
+                          (points[0][0] - 1, points[0][1] + 1),
+                          (points[0][0] + 1, points[0][1] - 1),
+                          (points[3][0] + 1, points[3][1]),
+                          (points[3][0], points[3][1] + 1),
+                          (points[3][0] + 1, points[3][1] + 1),
+                          (points[3][0] - 1, points[3][1] - 1),
+                          (points[2][0] + 1, points[2][1]),
+                          (points[2][0] - 1, points[2][1] + 1),
+                          (points[1][0] - 1, points[1][1]),
+                          (points[1][0], points[1][1] - 1),
+                          (points[1][0] - 1, points[1][1] - 1)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.aapolygon(surf, points, fg)
+            for posn in fg_test_points:
+                self.check_not_at(surf, posn, bg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_filled_polygon(self):
+        """filled_polygon(surface, points, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        points = [(10, 80), (10, 15), (92, 25), (92, 80)]
+        fg_test_points = (points +
+                          [(points[0][0], points[0][1] - 1),
+                           (points[0][0] + 1, points[0][1]),
+                           (points[0][0] + 1, points[0][1] - 1),
+                           (points[3][0] - 1, points[3][1]),
+                           (points[3][0], points[3][1] - 1),
+                           (points[3][0] - 1, points[3][1] - 1),
+                           (points[2][0], points[2][1] + 1),
+                           (points[2][0] - 1, points[2][1] + 1)])
+        bg_test_points = [(points[0][0] - 1, points[0][1]),
+                          (points[0][0], points[0][1] + 1),
+                          (points[0][0] - 1, points[0][1] + 1),
+                          (points[3][0] + 1, points[3][1]),
+                          (points[3][0], points[3][1] + 1),
+                          (points[3][0] + 1, points[3][1] + 1),
+                          (points[2][0] + 1, points[2][1]),
+                          (points[1][0] - 1, points[1][1]),
+                          (points[1][0], points[1][1] - 1),
+                          (points[1][0] - 1, points[1][1] - 1)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.filled_polygon(surf, points, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+    def test_textured_polygon(self):
+        """textured_polygon(surface, points, texture, tx, ty): return None"""
+        w, h = self.default_size
+        fg = self.foreground_color
+        bg = self.background_color
+        tx = 0
+        ty = 0
+        texture = pygame.Surface((w + tx, h + ty), 0, 24)
+        texture.fill(fg, (0, 0, w, h))
+        points = [(10, 80), (10, 15), (92, 25), (92, 80)]
+        # Don't know how to really check this as boarder points may
+        # or may not be included in the textured polygon.
+        fg_test_points = [(points[1][0] + 30, points[1][1] + 40)]
+        bg_test_points = [(points[0][0] - 1, points[0][1]),
+                          (points[0][0], points[0][1] + 1),
+                          (points[0][0] - 1, points[0][1] + 1),
+                          (points[3][0] + 1, points[3][1]),
+                          (points[3][0], points[3][1] + 1),
+                          (points[3][0] + 1, points[3][1] + 1),
+                          (points[2][0] + 1, points[2][1]),
+                          (points[1][0] - 1, points[1][1]),
+                          (points[1][0], points[1][1] - 1),
+                          (points[1][0] - 1, points[1][1] - 1)]
+        for surf in self.surfaces[1:]:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.textured_polygon(surf, points, texture, -tx, -ty)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+        # Alpha blit to 8 bits-per-pixel surface forbidden.
+        texture = pygame.Surface(self.default_size, SRCALPHA, 32)
+        self.failUnlessRaises(ValueError,
+                              pygame.gfxdraw.textured_polygon,
+                              self.surfaces[0],
+                              points,
+                              texture, 0, 0)
+
+    def test_bezier(self):
+        """bezier(surface, points, steps, color): return None"""
+        fg = self.foreground_color
+        bg = self.background_color
+        points = [(10, 50), (25, 15), (60, 80), (92, 30)]
+        fg_test_points = [points[0], points[3]]
+        bg_test_points = [(points[0][0] - 1, points[0][1]),
+                          (points[3][0] + 1, points[3][1]),
+                          (points[1][0], points[1][1] + 3),
+                          (points[2][0], points[2][1] - 3)]
+        for surf in self.surfaces:
+            fg_adjusted = surf.unmap_rgb(surf.map_rgb(fg))
+            bg_adjusted = surf.unmap_rgb(surf.map_rgb(bg))
+            pygame.gfxdraw.bezier(surf, points, 30, fg)
+            for posn in fg_test_points:
+                self.check_at(surf, posn, fg_adjusted)
+            for posn in bg_test_points:
+                self.check_at(surf, posn, bg_adjusted)
+
+
+
+if __name__ == '__main__':
+    unittest.main()