Commits

illume  committed f10c634

Marcus has added in blend modes for the surface.fill function.

Also sped up the alphablit code.

surface.c has had stuff moved around, and indented.

surface_fill.c was added to Setup.in so you need to remove your Setup file.

  • Participants
  • Parent commits a9bcb71

Comments (0)

Files changed (8)

 mouse src/mouse.c $(SDL) $(DEBUG)
 rect src/rect.c $(SDL) $(DEBUG)
 rwobject src/rwobject.c $(SDL) $(DEBUG)
-surface src/surface.c src/alphablit.c $(SDL) $(DEBUG)
+surface src/surface.c src/alphablit.c src/surface_fill.c $(SDL) $(DEBUG)
 surflock src/surflock.c $(SDL) $(DEBUG)
 time src/time.c $(SDL) $(DEBUG)
 joystick src/joystick.c $(SDL) $(DEBUG)

File docs/ref/surface.html

 <a name="Surface.fill">
 <big><b>Surface.fill</big></b><br><ul>
   <i>fill Surface with a solid color</i><br>
-  <tt>Surface.fill(color, rect=None): return Rect</tt><br>
+  <tt>Surface.fill(color, rect=None, special_flags=0): return Rect</tt><br>
 <p>Fill the Surface with a solid color. If no rect argument is given the entire Surface will be filled. The rect argument will limit the fill to a specific area. The fill will also be contained by the Surface clip area. </p>
 <p>The color argument can be either an <tt>RGB</tt> sequence or a mapped color index. </p>
+<p>An optional special_flags is for passing in <tt>BLEND_ADD</tt>, <tt>BLEND_SUB</tt>, <tt>BLEND_MULT</tt>, <tt>BLEND_MIN</tt>, <tt>BLEND_MAX</tt> With other special blitting flags perhaps added in the future. </p>
 <p>This will return the affected Surface area. </p>
 <!--COMMENTS:Surface.fill--> &nbsp;<br> 
 <br></ul>

File examples/blend_fill.py

+import sys, os
+import pygame
+from pygame.locals import *
+
+def usage ():
+    print "Press R, G, B to increase the color channel values,"
+    print "1-9 to set the step range for the increment,"
+    print "A - ADD, S- SUB, M- MULT, - MIN, + MAX"
+    print "  to change the blend modes"
+
+color = [0, 0, 0]
+changed = False
+blendtype = 0
+step = 5
+
+pygame.init ()
+screen = pygame.display.set_mode ((640, 480), 0, 32)
+screen.fill ((100, 100, 100))
+
+image = pygame.image.load (os.path.join ("data", "liquid.bmp")).convert()
+blendimage = pygame.image.load (os.path.join ("data", "liquid.bmp")).convert()
+screen.blit (image, (10, 10))
+screen.blit (blendimage, (200, 10))
+
+pygame.display.flip ()
+pygame.key.set_repeat (500, 30)
+usage()
+
+while 1:
+    for event in pygame.event.get ():
+        if event.type == QUIT:
+            sys.exit()
+
+        if event.type == KEYDOWN:
+            usage ()
+
+            if event.key == K_ESCAPE:
+                sys.exit ()
+            
+            if event.key == K_r:
+                color[0] += step
+                if color[0] > 255:
+                    color[0] = 0
+                changed = True
+
+            elif event.key == K_g:
+                color[1] += step
+                if color[1] > 255:
+                    color[1] = 0
+                changed = True
+
+            elif event.key == K_b:
+                color[2] += step
+                if color[2] > 255:
+                    color[2] = 0
+                changed = True
+
+            elif event.key == K_a:
+                blendtype = BLEND_ADD
+                changed = True
+            elif event.key == K_s:
+                blendtype = BLEND_SUB
+                changed = True
+            elif event.key == K_m:
+                blendtype = BLEND_MULT
+                changed = True
+            elif event.key == K_PLUS:
+                blendtype = BLEND_MAX
+                changed = True
+            elif event.key == K_MINUS:
+                blendtype = BLEND_MIN
+                changed = True
+
+            elif event.key in (K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9):
+                step = int (event.unicode)
+
+        if changed:
+            screen.fill ((100, 100, 100))
+            screen.blit (image, (10, 10))
+            blendimage.blit (image, (0, 0))
+            #blendimage.fill (color, (0, 0, 20, 20), blendtype)
+            blendimage.fill (color, None, blendtype)
+            screen.blit (blendimage, (200, 10))
+            print "Color: %s, Pixel (0,0): %s" % (tuple(color),
+                                                  [blendimage.get_at ((0, 0))])
+            changed = False
+            pygame.display.flip ()

File src/alphablit.c

 /*
-    pygame - Python Game Library
-    Copyright (C) 2000-2001  Pete Shinners
-    Copyright (C) 2006  Rene Dudfield
+  pygame - Python Game Library
+  Copyright (C) 2000-2001  Pete Shinners
+  Copyright (C) 2006 Rene Dudfield
+  Copyright (C) 2007 Marcus von Appen
 
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Library General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or (at your option) any later version.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Library General Public License for more details.
 
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  You should have received a copy of the GNU Library General Public
+  License along with this library; if not, write to the Free
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-    Pete Shinners
-    pete@shinners.org
+  Pete Shinners
+  pete@shinners.org
 */
 
-#include <SDL.h>
-#include <SDL.h>
-
-
-#define PYGAME_BLEND_ADD  0x1
-#define PYGAME_BLEND_SUB  0x2
-#define PYGAME_BLEND_MULT 0x3
-#define PYGAME_BLEND_MIN  0x4
-#define PYGAME_BLEND_MAX  0x5
-
-
+#include "surface.h"
 
 /* The structure passed to the low level blit functions */
-typedef struct {
-        Uint8 *s_pixels;
-        int s_width;
-        int s_height;
-        int s_skip;
-        Uint8 *d_pixels;
-        int d_width;
-        int d_height;
-        int d_skip;
-        void *aux_data;
-        SDL_PixelFormat *src;
-        Uint8 *table;
-        SDL_PixelFormat *dst;
+typedef struct
+{
+    Uint8          *s_pixels;
+    int             s_width;
+    int             s_height;
+    int             s_skip;
+    Uint8          *d_pixels;
+    int             d_width;
+    int             d_height;
+    int             d_skip;
+    void           *aux_data;
+    SDL_PixelFormat *src;
+    Uint8          *table;
+    SDL_PixelFormat *dst;
 } SDL_BlitInfo;
-static void alphablit_alpha(SDL_BlitInfo *info);
-static void alphablit_colorkey(SDL_BlitInfo *info);
-static void alphablit_solid(SDL_BlitInfo *info);
-static void blit_blend_THEM(SDL_BlitInfo *info, int the_args);
 
+static void alphablit_alpha (SDL_BlitInfo * info);
+static void alphablit_colorkey (SDL_BlitInfo * info);
+static void alphablit_solid (SDL_BlitInfo * info);
+static void blit_blend_add (SDL_BlitInfo * info);
+static void blit_blend_sub (SDL_BlitInfo * info);
+static void blit_blend_mul (SDL_BlitInfo * info);
+static void blit_blend_min (SDL_BlitInfo * info);
+static void blit_blend_max (SDL_BlitInfo * info);
 
+static int 
+SoftBlitPyGame (SDL_Surface * src, SDL_Rect * srcrect,
+                SDL_Surface * dst, SDL_Rect * dstrect, int the_args);
+extern int  SDL_RLESurface (SDL_Surface * surface);
+extern void SDL_UnRLESurface (SDL_Surface * surface, int recode);
 
-static int SoftBlitPyGame(SDL_Surface *src, SDL_Rect *srcrect,
-                          SDL_Surface *dst, SDL_Rect *dstrect, int the_args);
-extern int SDL_RLESurface(SDL_Surface *surface);
-extern void SDL_UnRLESurface(SDL_Surface *surface, int recode);
-
-
-
-
-
-
-
-
-
-
-
-
-static int SoftBlitPyGame(SDL_Surface *src, SDL_Rect *srcrect,
-                        SDL_Surface *dst, SDL_Rect *dstrect, int the_args)
+static int 
+SoftBlitPyGame (SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst,
+                SDL_Rect * dstrect, int the_args)
 {
-        int okay;
-        int src_locked;
-        int dst_locked;
+    int okay;
+    int src_locked;
+    int dst_locked;
 
     /* Everything is okay at the beginning...  */
-        okay = 1;
+    okay = 1;
 
-        /* Lock the destination if it's in hardware */
-        dst_locked = 0;
-        if ( SDL_MUSTLOCK(dst) ) {
-                if ( SDL_LockSurface(dst) < 0 )
-                        okay = 0;
-                else
-                        dst_locked = 1;
+    /* Lock the destination if it's in hardware */
+    dst_locked = 0;
+    if (SDL_MUSTLOCK (dst))
+    {
+        if (SDL_LockSurface (dst) < 0)
+            okay = 0;
+        else
+            dst_locked = 1;
+    }
+    /* Lock the source if it's in hardware */
+    src_locked = 0;
+    if (SDL_MUSTLOCK (src))
+    {
+        if (SDL_LockSurface (src) < 0)
+            okay = 0;
+        else
+            src_locked = 1;
+    }
+
+    /* Set up source and destination buffer pointers, and BLIT! */
+    if (okay && srcrect->w && srcrect->h)
+    {
+        SDL_BlitInfo    info;
+
+        /* Set up the blit information */
+        info.s_pixels = (Uint8 *) src->pixels + src->offset +
+            (Uint16) srcrect->y * src->pitch +
+            (Uint16) srcrect->x * src->format->BytesPerPixel;
+        info.s_width = srcrect->w;
+        info.s_height = srcrect->h;
+        info.s_skip = src->pitch - info.s_width * src->format->BytesPerPixel;
+        info.d_pixels = (Uint8 *) dst->pixels + dst->offset +
+            (Uint16) dstrect->y * dst->pitch +
+            (Uint16) dstrect->x * dst->format->BytesPerPixel;
+        info.d_width = dstrect->w;
+        info.d_height = dstrect->h;
+        info.d_skip = dst->pitch - info.d_width * dst->format->BytesPerPixel;
+        info.src = src->format;
+        info.dst = dst->format;
+
+        switch (the_args)
+        {
+        case 0:
+        {
+            if (src->flags & SDL_SRCALPHA && src->format->Amask)
+                alphablit_alpha (&info);
+            else if (src->flags & SDL_SRCCOLORKEY)
+                alphablit_colorkey (&info);
+            else
+                alphablit_solid (&info);
+            break;
         }
-        /* Lock the source if it's in hardware */
-        src_locked = 0;
-        if ( SDL_MUSTLOCK(src) ) {
-                if ( SDL_LockSurface(src) < 0 )
-                        okay = 0;
-                else
-                        src_locked = 1;
+        case PYGAME_BLEND_ADD:
+        {
+            blit_blend_add (&info);
+            break;
         }
+        case PYGAME_BLEND_SUB:
+        {
+            blit_blend_sub (&info);
+            break;
+        }
+        case PYGAME_BLEND_MULT:
+        {
+            blit_blend_mul (&info);
+            break;
+        }
+        case PYGAME_BLEND_MIN:
+        {
+            blit_blend_min (&info);
+            break;
+        }
+        case PYGAME_BLEND_MAX:
+        {
+            blit_blend_max (&info);
+            break;
+        }
+        default:
+        {
+            SDL_SetError ("Invalid argument passed to blit.");
+            okay = 0;
+            break;
+        }
+        }
+    }
+    /* We need to unlock the surfaces if they're locked */
+    if (dst_locked)
+        SDL_UnlockSurface (dst);
+    if (src_locked)
+        SDL_UnlockSurface (src);
+    /* Blit is done! */
+    return (okay ? 0 : -1);
+}
 
-        /* Set up source and destination buffer pointers, and BLIT! */
-        if ( okay  && srcrect->w && srcrect->h ) {
-                SDL_BlitInfo info;
+static void
+blit_blend_add (SDL_BlitInfo * info)
+{
+    int             n;
+    int             width = info->d_width;
+    int             height = info->d_height;
+    Uint8          *src = info->s_pixels;
+    int             srcskip = info->s_skip;
+    Uint8          *dst = info->d_pixels;
+    int             dstskip = info->d_skip;
+    SDL_PixelFormat *srcfmt = info->src;
+    SDL_PixelFormat *dstfmt = info->dst;
+    int             srcbpp = srcfmt->BytesPerPixel;
+    int             dstbpp = dstfmt->BytesPerPixel;
+    Uint8           dR, dG, dB, dA, sR, sG, sB, sA;
+    Uint32          pixel;
+    Uint32          tmp;
 
-                /* Set up the blit information */
-                info.s_pixels = (Uint8 *)src->pixels + src->offset +
-                                (Uint16)srcrect->y*src->pitch +
-                                (Uint16)srcrect->x*src->format->BytesPerPixel;
-                info.s_width = srcrect->w;
-                info.s_height = srcrect->h;
-                info.s_skip=src->pitch-info.s_width*src->format->BytesPerPixel;
-                info.d_pixels = (Uint8 *)dst->pixels + dst->offset +
-                                (Uint16)dstrect->y*dst->pitch +
-                                (Uint16)dstrect->x*dst->format->BytesPerPixel;
-                info.d_width = dstrect->w;
-                info.d_height = dstrect->h;
-                info.d_skip=dst->pitch-info.d_width*dst->format->BytesPerPixel;
-                info.src = src->format;
-                info.dst = dst->format;
+    if (srcbpp == 4 && dstbpp == 4)
+    {
+        while (height--)
+        {
+            LOOP_UNROLLED4(
+            {
+                REPEAT_3(
+                {
+                    tmp = (*dst) + (*src);
+                    (*dst) = (tmp <= 255 ? tmp : 255);
+                    src++;
+                    dst++;
+                });
+                src++;
+                dst++;
+            }, n, width);
+            src += srcskip;
+            dst += dstskip;
+        }
+        return;
+    }
 
-                switch(the_args) {
-                    case 0:
-                    {
-                        if(src->flags&SDL_SRCALPHA && src->format->Amask)
-                            alphablit_alpha(&info);
-                        else if(src->flags & SDL_SRCCOLORKEY)
-                            alphablit_colorkey(&info);
-                        else
-                            alphablit_solid(&info);
-                        break;
-                    }
-                    case PYGAME_BLEND_ADD:
-                    case PYGAME_BLEND_SUB:
-                    case PYGAME_BLEND_MULT:
-                    case PYGAME_BLEND_MIN:
-                    case PYGAME_BLEND_MAX: {
-                        blit_blend_THEM(&info, the_args); 
-                        break;
-                    }
-                    default:
-                    {
-                        SDL_SetError("Invalid argument passed to blit.");
-                        okay = 0;
-                        break;
-                    }
-                }
+    if (srcbpp == 1)
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    BLEND_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    BLEND_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
+    else /* srcbpp > 1 */
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    BLEND_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
 
         }
-
-        /* We need to unlock the surfaces if they're locked */
-        if ( dst_locked )
-                SDL_UnlockSurface(dst);
-        if ( src_locked )
-                SDL_UnlockSurface(src);
-        /* Blit is done! */
-        return(okay ? 0 : -1);
-}
-
-
-
-/*
- * Macros below are for the blit blending functions.
- */
-
-
-#define GET_PIXEL(buf, bpp, fmt, pixel)                                 \
-    do {                                                                \
-        switch (bpp) {                                                  \
-        case 1:                                                         \
-            pixel = *((Uint8 *)(buf));                                  \
-            break;                                                      \
-        case 2:                                                         \
-            pixel = *((Uint16 *)(buf));                                 \
-            break;                                                      \
-        case 4:                                                         \
-            pixel = *((Uint32 *)(buf));                                 \
-            break;                                                      \
-        default:        {/* case 3: FIXME: broken code (no alpha) */    \
-            Uint8 *b = (Uint8 *)buf;                                    \
-            if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {                       \
-                pixel = b[0] + (b[1] << 8) + (b[2] << 16);              \
-            } else {                                                    \
-                pixel = (b[0] << 16) + (b[1] << 8) + b[2];              \
-            }                                                           \
-        }                                                               \
-            break;                                                      \
-        }                                                               \
-    } while(0)
-
-
-#define DISEMBLE_RGBA(buf, bpp, fmt, _pixel, R, G, B, A)                \
-    do {                                                                \
-        if(bpp==1){                                                     \
-            _pixel = *((Uint8 *)(buf));                                 \
-            R = fmt->palette->colors[_pixel].r;                         \
-            G = fmt->palette->colors[_pixel].g;                         \
-            B = fmt->palette->colors[_pixel].b;                         \
-            A = 255;                                                    \
-        } else {                                                        \
-            switch (bpp) {                                              \
-            case 2:                                                     \
-                _pixel = *((Uint16 *)(buf));                            \
-                break;                                                  \
-            case 4:                                                     \
-                _pixel = *((Uint32 *)(buf));                            \
-                break;                                                  \
-            default:        {/* case 3: FIXME: broken code (no alpha) */ \
-                Uint8 *b = (Uint8 *)buf;                                \
-                if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {                   \
-                    _pixel = b[0] + (b[1] << 8) + (b[2] << 16);         \
-                } else {                                                \
-                    _pixel = (b[0] << 16) + (b[1] << 8) + b[2];         \
-                }                                                       \
-            }                                                           \
-                break;                                                  \
-            }                                                           \
-            R = ((_pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss;         \
-            G = ((_pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss;         \
-            B = ((_pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss;         \
-            A = ((_pixel&fmt->Amask)>>fmt->Ashift)<<fmt->Aloss;         \
-        }                                                               \
-    } while(0)
-
-
-#define DISEMBLE_RGBA4(buf, bpp, fmt, pxl, R, G, B, A)                  \
-    pixel = *((Uint32 *)(buf));                                         \
-    R = ((pxl&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss;                    \
-    G = ((pxl&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss;                    \
-    B = ((pxl&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss;                    \
-    A = ((pxl&fmt->Amask)>>fmt->Ashift)<<fmt->Aloss;                    \
-    
-
-#define PIXEL_FROM_RGBA(px, fmt, r, g, b, a)                            \
-    {                                                                   \
-        px = ((r>>fmt->Rloss)<<fmt->Rshift)|                            \
-            ((g>>fmt->Gloss)<<fmt->Gshift)|                             \
-            ((b>>fmt->Bloss)<<fmt->Bshift)|                             \
-            ((a<<fmt->Aloss)<<fmt->Ashift);                             \
-    }
-#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a)                        \
-    {                                                                   \
-        switch (bpp) {                                                  \
-        case 2: {                                                       \
-            Uint16 __pixel;                                             \
-            PIXEL_FROM_RGBA(__pixel, fmt, r, g, b, a);                  \
-            *((Uint16 *)(buf)) = __pixel;                               \
-        }                                                               \
-            break;                                                      \
-        case 4: {                                                       \
-            Uint32 __pixel;                                             \
-            PIXEL_FROM_RGBA(__pixel, fmt, r, g, b, a);                  \
-            *((Uint32 *)(buf)) = __pixel;                               \
-        }                                                               \
-            break;                                                      \
-        }                                                               \
-    }
-
-
-#define ASSEMBLE_RGBA4(buf, bpp, fmt, r, g, b, a)                       \
-    Uint32 pixel1;                                                      \
-    PIXEL_FROM_RGBA(pixel1, fmt, r, g, b, a);                           \
-    *((Uint32 *)(buf)) = pixel1;                                        \
-    
-
-
-#if 0
-#define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA)     \
-    do {                                                \
-        dR = (((sR-dR)*(sA))>>8)+dR;                    \
-        dG = (((sG-dG)*(sA))>>8)+dG;                    \
-        dB = (((sB-dB)*(sA))>>8)+dB;                    \
-        dA = sA+dA - ((sA*dA)/255);                     \
-    } while(0)
-#else
-#define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA)     \
-    do {   if(dA){                                      \
-            dR = ((dR<<8) + (sR-dR)*sA + sR) >> 8;      \
-            dG = ((dG<<8) + (sG-dG)*sA + sG) >> 8;      \
-            dB = ((dB<<8) + (sB-dB)*sA + sB) >> 8;      \
-            dA = sA+dA - ((sA*dA)/255);                 \
-        }else{                                          \
-            dR = sR;                                    \
-            dG = sG;                                    \
-            dB = sB;                                    \
-            dA = sA;                                    \
-        }                                               \
-    } while(0)
-#endif
-
-
-#define BLEND_TOP_VARS                        \
-    int n,ii;                                 \
-    int width = info->d_width;                \
-    int height = info->d_height;              \
-    Uint8 *src = info->s_pixels;              \
-    int srcskip = info->s_skip;               \
-    Uint8 *dst = info->d_pixels;              \
-    int dstskip = info->d_skip;               \
-    SDL_PixelFormat *srcfmt = info->src;      \
-    SDL_PixelFormat *dstfmt = info->dst;      \
-    int srcbpp = srcfmt->BytesPerPixel;       \
-    int dstbpp = dstfmt->BytesPerPixel;       \
-    Uint8 dR, dG, dB, dA, sR, sG, sB, sA;     \
-    Uint32 pixel;                             \
-    Uint32 tmp;                               \
-    Sint32 tmp2;                              \
-    ii = tmp = tmp2 = 0 ;                     \
-
-
-#define BLEND_TOP                  \
-    while ( height-- )             \
-    {                              \
-        for(n=width; n>0; --n)     \
-        {                          \
-            
-
-#define BLEND_TOP_GENERIC                       \
-    BLEND_TOP;                                                     \
-    DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA);     \
-    DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);     \
-    
-
-#define BLEND_BOTTOM                            \
-    }                                           \
-    src += srcskip;                             \
-    dst += dstskip;                             \
-    }                                           \
-    
-#define BLEND_BOTTOM_GENERIC                                        \
-    ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);             \
-    src += srcbpp;                                                  \
-    dst += dstbpp;                                                  \
-    BLEND_BOTTOM;                                                   \
-    
-
-#define BLEND_TOP_4                                                \
-    if(srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4) { \
-        BLEND_TOP;                                                 \
-        for(ii=0;ii < 3; ii++){                                    \
-            
-#define BLEND_START_GENERIC                     \
-    src++;dst++;                                \
-    }                                           \
-    src++;dst++;                                \
-    BLEND_BOTTOM;                               \
-    } else {                                    \
-        BLEND_TOP_GENERIC;                      \
-// NOTE: we don't touch alpha.
-
-
-#define BLEND_END_GENERIC     \
-    BLEND_BOTTOM_GENERIC;     \
-    }                         \
-    
-
-/*
- * Blending functions for the 32bit routines.
- */
-
-#define BLEND_ADD4(S,D)                              \
-    tmp = (D) + (S);  (D) = (tmp <= 255 ? tmp: 255); \
-    
-#define BLEND_SUB4(S,D)                                 \
-    tmp2 = (D)-(S); (D) = (tmp2 >= 0 ? tmp2 : 0);       \
-    
-#define BLEND_MULT4(S,D)                                    \
-    tmp = ((D) * (S)) >> 8;  (D) = (tmp <= 255 ? tmp: 255); \
-
-#define BLEND_MIN4(S,D)           \
-    if ((S) < (D)) { (D) = (S); } \
-
-#define BLEND_MAX4(S,D)           \
-    if ((S) > (D)) { (D) = (S); } \
-
-
-/*
- * These are the dissasembled blending functions.
- */
-
-#define BLEND_ADD(sR, sG, sB, sA, dR, dG, dB, dA)  \
-    dR = (dR+sR <= 255 ? dR+sR: 255);              \
-    dG = (dG+sG <= 255 ? dG+sG : 255);             \
-    dB = (dB+sB <= 255 ? dB+sB : 255);             \
-
-
-#define BLEND_SUB(sR, sG, sB, sA, dR, dG, dB, dA)       \
-    tmp2 = dR - sR; dR = (tmp2 >= 0 ? tmp2 : 0);        \
-    tmp2 = dG - sG; dG = (tmp2 >= 0 ? tmp2 : 0);        \
-    tmp2 = dB - sB; dB = (tmp2 >= 0 ? tmp2 : 0);        \
-    
-
-#define BLEND_MULT(sR, sG, sB, sA, dR, dG, dB, dA)      \
-    dR = (dR * sR) >> 8;                                \
-    dG = (dG * sG) >> 8;                                \
-    dB = (dB * sB) >> 8;                                \
-    
-#define BLEND_MIN(sR, sG, sB, sA, dR, dG, dB, dA)       \
-    if(sR < dR) { dR = sR; }                            \
-    if(sG < dG) { dG = sG; }                            \
-    if(sB < dB) { dB = sB; }                            \
-    
-#define BLEND_MAX(sR, sG, sB, sA, dR, dG, dB, dA)       \
-    if(sR > dR) { dR = sR; }                            \
-    if(sG > dG) { dG = sG; }                            \
-    if(sB > dB) { dB = sB; }                            \
-
-
-/*
- * blit_blend takes the blending args, and then uses that to select the 
- *  correct code for blending with.
- */
-static void blit_blend_THEM(SDL_BlitInfo *info, int the_args) {
-    BLEND_TOP_VARS;
-
-    switch(the_args) {
-        /*
-         * We use macros to keep the code shorter.
-         * First we see if it is a 32bit RGBA surface.  If so we have some 
-         *  special case code for that.  Otherwise we use the generic code.
-         */
-        case PYGAME_BLEND_ADD: {
-            BLEND_TOP_4;
-            BLEND_ADD4(*src,*dst); 
-            BLEND_START_GENERIC; 
-            BLEND_ADD(sR, sG, sB, sA, dR, dG, dB, dA); 
-            BLEND_END_GENERIC;
-            break;
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    BLEND_ADD (tmp, sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
         }
-        case PYGAME_BLEND_SUB: {
-            BLEND_TOP_4;
-            BLEND_SUB4(*src,*dst); 
-            BLEND_START_GENERIC; 
-            BLEND_SUB(sR, sG, sB, sA, dR, dG, dB, dA); 
-            BLEND_END_GENERIC;
-            break;
-        }
-        case PYGAME_BLEND_MULT: {
-            BLEND_TOP_4;
-            BLEND_MULT4(*src,*dst); 
-            BLEND_START_GENERIC; 
-            BLEND_MULT(sR, sG, sB, sA, dR, dG, dB, dA); 
-            BLEND_END_GENERIC;
-            break;
-        }
-        case PYGAME_BLEND_MIN: {
-            BLEND_TOP_4;
-            BLEND_MIN4(*src,*dst); 
-            BLEND_START_GENERIC; 
-            BLEND_MIN(sR, sG, sB, sA, dR, dG, dB, dA); 
-            BLEND_END_GENERIC;
-            break;
-        }
-        case PYGAME_BLEND_MAX: {
-            BLEND_TOP_4;
-            BLEND_MAX4(*src,*dst); 
-            BLEND_START_GENERIC; 
-            BLEND_MAX(sR, sG, sB, sA, dR, dG, dB, dA); 
-            BLEND_END_GENERIC;
-            break;
-        }
-
     }
 }
 
+static void
+blit_blend_sub (SDL_BlitInfo * info)
+{
+    int             n;
+    int             width = info->d_width;
+    int             height = info->d_height;
+    Uint8          *src = info->s_pixels;
+    int             srcskip = info->s_skip;
+    Uint8          *dst = info->d_pixels;
+    int             dstskip = info->d_skip;
+    SDL_PixelFormat *srcfmt = info->src;
+    SDL_PixelFormat *dstfmt = info->dst;
+    int             srcbpp = srcfmt->BytesPerPixel;
+    int             dstbpp = dstfmt->BytesPerPixel;
+    Uint8           dR, dG, dB, dA, sR, sG, sB, sA;
+    Uint32          pixel;
+    Sint32          tmp2;
 
-
-
-
-static void alphablit_alpha(SDL_BlitInfo *info)
-{
-        int n;
-        int width = info->d_width;
-        int height = info->d_height;
-        Uint8 *src = info->s_pixels;
-        int srcskip = info->s_skip;
-        Uint8 *dst = info->d_pixels;
-        int dstskip = info->d_skip;
-        SDL_PixelFormat *srcfmt = info->src;
-        SDL_PixelFormat *dstfmt = info->dst;
-        int srcbpp = srcfmt->BytesPerPixel;
-        int dstbpp = dstfmt->BytesPerPixel;
-        int dR, dG, dB, dA, sR, sG, sB, sA;
-
-        while ( height-- )
+    if (srcbpp == 4 && dstbpp == 4)
+    {
+        while (height--)
         {
-            for(n=width; n>0; --n)
+            LOOP_UNROLLED4(
             {
-                Uint32 apixel;
-                DISEMBLE_RGBA(src, srcbpp, srcfmt, apixel, sR, sG, sB, sA);
-                DISEMBLE_RGBA(dst, dstbpp, dstfmt, apixel, dR, dG, dB, dA);
-                ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA);
-                ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
-                src += srcbpp;
-                dst += dstbpp;
-            }
+                REPEAT_3(
+                {
+                    tmp2 = (*dst) - (*src);
+                    (*dst) = (tmp2 >= 0 ? tmp2 : 0);
+                    src++;
+                    dst++;
+                });
+                src++;
+                dst++;
+            }, n, width);
             src += srcskip;
             dst += dstskip;
         }
+        return;
+    }
+
+    if (srcbpp == 1)
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    BLEND_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    BLEND_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
+    else /* srcbpp > 1 */
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    BLEND_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    BLEND_SUB (tmp2, sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
 }
 
-static void alphablit_colorkey(SDL_BlitInfo *info)
+static void
+blit_blend_mul (SDL_BlitInfo * info)
 {
-        int n;
-        int width = info->d_width;
-        int height = info->d_height;
-        Uint8 *src = info->s_pixels;
-        int srcskip = info->s_skip;
-        Uint8 *dst = info->d_pixels;
-        int dstskip = info->d_skip;
-        SDL_PixelFormat *srcfmt = info->src;
-        SDL_PixelFormat *dstfmt = info->dst;
-        int srcbpp = srcfmt->BytesPerPixel;
-        int dstbpp = dstfmt->BytesPerPixel;
-        int dR, dG, dB, dA, sR, sG, sB, sA;
-        int alpha = srcfmt->alpha;
-        Uint32 colorkey = srcfmt->colorkey;
+    int             n;
+    int             width = info->d_width;
+    int             height = info->d_height;
+    Uint8          *src = info->s_pixels;
+    int             srcskip = info->s_skip;
+    Uint8          *dst = info->d_pixels;
+    int             dstskip = info->d_skip;
+    SDL_PixelFormat *srcfmt = info->src;
+    SDL_PixelFormat *dstfmt = info->dst;
+    int             srcbpp = srcfmt->BytesPerPixel;
+    int             dstbpp = dstfmt->BytesPerPixel;
+    Uint8           dR, dG, dB, dA, sR, sG, sB, sA;
+    Uint32          pixel;
+    Uint32          tmp;
 
-        while ( height-- )
+    if (srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4)
+    {
+        while (height--)
         {
-            for(n=width; n>0; --n)
+            LOOP_UNROLLED4(
             {
-                Uint32 apixel;
-                DISEMBLE_RGBA(dst, dstbpp, dstfmt, apixel, dR, dG, dB, dA);
-                DISEMBLE_RGBA(src, srcbpp, srcfmt, apixel, sR, sG, sB, sA);
-                sA = (apixel == colorkey) ? 0 : alpha;
-                ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA);
-                ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
-                src += srcbpp;
-                dst += dstbpp;
-            }
+                REPEAT_3(
+                {
+                    tmp = ((*dst) && (*src)) ? ((*dst) * (*src)) >> 8 : 0;
+                    (*dst) = (tmp <= 255 ? tmp : 255);
+                    src++;
+                    dst++;
+                });
+                src++;
+                dst++;
+            }, n, width);
             src += srcskip;
             dst += dstskip;
         }
+        return;
+    }
+
+    if (srcbpp == 1)
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    BLEND_MULT (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    BLEND_MULT (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
+    else /* srcbpp > 1 */
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    BLEND_MULT (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    BLEND_MULT (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
 }
 
+static void
+blit_blend_min (SDL_BlitInfo * info)
+{
+    int             n;
+    int             width = info->d_width;
+    int             height = info->d_height;
+    Uint8          *src = info->s_pixels;
+    int             srcskip = info->s_skip;
+    Uint8          *dst = info->d_pixels;
+    int             dstskip = info->d_skip;
+    SDL_PixelFormat *srcfmt = info->src;
+    SDL_PixelFormat *dstfmt = info->dst;
+    int             srcbpp = srcfmt->BytesPerPixel;
+    int             dstbpp = dstfmt->BytesPerPixel;
+    Uint8           dR, dG, dB, dA, sR, sG, sB, sA;
+    Uint32          pixel;
 
-static void alphablit_solid(SDL_BlitInfo *info)
-{
-        int n;
-        int width = info->d_width;
-        int height = info->d_height;
-        Uint8 *src = info->s_pixels;
-        int srcskip = info->s_skip;
-        Uint8 *dst = info->d_pixels;
-        int dstskip = info->d_skip;
-        SDL_PixelFormat *srcfmt = info->src;
-        SDL_PixelFormat *dstfmt = info->dst;
-        int srcbpp = srcfmt->BytesPerPixel;
-        int dstbpp = dstfmt->BytesPerPixel;
-        int dR, dG, dB, dA, sR, sG, sB, sA;
-        int alpha = srcfmt->alpha;
-
-        while ( height-- )
+    if (srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4)
+    {
+        while (height--)
         {
-            for(n=width; n>0; --n)
+            LOOP_UNROLLED4(
             {
-                int apixel;
-                DISEMBLE_RGBA(dst, dstbpp, dstfmt, apixel, dR, dG, dB, dA);
-                DISEMBLE_RGBA(src, srcbpp, srcfmt, apixel, sR, sG, sB, sA);
-                ALPHA_BLEND(sR, sG, sB, alpha, dR, dG, dB, dA);
-                ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
-                src += srcbpp;
-                dst += dstbpp;
-            }
+                REPEAT_3(
+                {
+                    if ((*src) < (*dst))
+                        (*dst) = (*src);
+                    src++;
+                    dst++;
+                });
+                src++;
+                dst++;
+            }, n, width);
             src += srcskip;
             dst += dstskip;
         }
+        return;
+    }
+
+    if (srcbpp == 1)
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    BLEND_MIN (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    BLEND_MIN (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
+    else /* srcbpp > 1 */
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    BLEND_MIN (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    BLEND_MIN (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
 }
 
+static void
+blit_blend_max (SDL_BlitInfo * info)
+{
+    int             n;
+    int             width = info->d_width;
+    int             height = info->d_height;
+    Uint8          *src = info->s_pixels;
+    int             srcskip = info->s_skip;
+    Uint8          *dst = info->d_pixels;
+    int             dstskip = info->d_skip;
+    SDL_PixelFormat *srcfmt = info->src;
+    SDL_PixelFormat *dstfmt = info->dst;
+    int             srcbpp = srcfmt->BytesPerPixel;
+    int             dstbpp = dstfmt->BytesPerPixel;
+    Uint8           dR, dG, dB, dA, sR, sG, sB, sA;
+    Uint32          pixel;
 
+    if (srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4)
+    {
+        while (height--)
+        {
+            LOOP_UNROLLED4(
+            {
+                REPEAT_3(
+                {
+                    if ((*src) > (*dst))
+                        (*dst) = (*src);
+                    src++;
+                    dst++;
+                });
+                src++;
+                dst++;
+            }, n, width);
+            src += srcskip;
+            dst += dstskip;
+        }
+        return;
+    }
+
+
+    if (srcbpp == 1)
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    BLEND_MAX (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    BLEND_MAX (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
+    else /* srcbpp > 1 */
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    BLEND_MAX (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    BLEND_MAX (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
+}
+
+
+static void 
+alphablit_alpha (SDL_BlitInfo * info)
+{
+    int             n;
+    int             width = info->d_width;
+    int             height = info->d_height;
+    Uint8          *src = info->s_pixels;
+    int             srcskip = info->s_skip;
+    Uint8          *dst = info->d_pixels;
+    int             dstskip = info->d_skip;
+    SDL_PixelFormat *srcfmt = info->src;
+    SDL_PixelFormat *dstfmt = info->dst;
+    int             srcbpp = srcfmt->BytesPerPixel;
+    int             dstbpp = dstfmt->BytesPerPixel;
+    int             dR, dG, dB, dA, sR, sG, sB, sA;
+    Uint32          pixel;
+
+    printf ("Alpha blit with %d and %d\n", srcbpp, dstbpp);
+
+    if (srcbpp == 1)
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
+    else /* srcbpp > 1 */
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
+}
+
+static void 
+alphablit_colorkey (SDL_BlitInfo * info)
+{
+    int             n;
+    int             width = info->d_width;
+    int             height = info->d_height;
+    Uint8          *src = info->s_pixels;
+    int             srcskip = info->s_skip;
+    Uint8          *dst = info->d_pixels;
+    int             dstskip = info->d_skip;
+    SDL_PixelFormat *srcfmt = info->src;
+    SDL_PixelFormat *dstfmt = info->dst;
+    int             srcbpp = srcfmt->BytesPerPixel;
+    int             dstbpp = dstfmt->BytesPerPixel;
+    int             dR, dG, dB, dA, sR, sG, sB, sA;
+    int             alpha = srcfmt->alpha;
+    Uint32          colorkey = srcfmt->colorkey;
+    Uint32          pixel;
+
+    printf ("Colorkey blit with %d and %d\n", srcbpp, dstbpp);
+
+    if (srcbpp == 1)
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    sA = (pixel == colorkey) ? 0 : alpha;
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    sA = (pixel == colorkey) ? 0 : alpha;
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
+    else /* srcbpp > 1 */
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    sA = (pixel == colorkey) ? 0 : alpha;
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    sA = (pixel == colorkey) ? 0 : alpha;
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    ALPHA_BLEND (sR, sG, sB, sA, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
+}
+
+static void 
+alphablit_solid (SDL_BlitInfo * info)
+{
+    int             n;
+    int             width = info->d_width;
+    int             height = info->d_height;
+    Uint8          *src = info->s_pixels;
+    int             srcskip = info->s_skip;
+    Uint8          *dst = info->d_pixels;
+    int             dstskip = info->d_skip;
+    SDL_PixelFormat *srcfmt = info->src;
+    SDL_PixelFormat *dstfmt = info->dst;
+    int             srcbpp = srcfmt->BytesPerPixel;
+    int             dstbpp = dstfmt->BytesPerPixel;
+    int             dR, dG, dB, dA, sR, sG, sB, sA;
+    int             alpha = srcfmt->alpha;
+    int             pixel;
+
+    printf ("Solid blit with %d and %d\n", srcbpp, dstbpp);
+
+    if (srcbpp == 1)
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    ALPHA_BLEND (sR, sG, sB, alpha, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXELVALS_1(sR, sG, sB, sA, pixel, src, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    ALPHA_BLEND (sR, sG, sB, alpha, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
+    else /* srcbpp > 1 */
+    {
+        if (dstbpp == 1)
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXELVALS_1(dR, dG, dB, dA, pixel, dst, dstfmt);
+                    ALPHA_BLEND (sR, sG, sB, alpha, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n, width);
+                src += srcskip;
+                dst += dstskip;
+            }
+
+        }
+        else /* dstbpp > 1 */
+        {
+            while (height--)
+            {
+                LOOP_UNROLLED4(
+                {
+                    GET_PIXEL(pixel, srcbpp, src);
+                    GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt);
+                    GET_PIXEL (pixel, dstbpp, dst);
+                    GET_PIXELVALS (dR, dG, dB, dA, pixel, dstfmt);
+                    ALPHA_BLEND (sR, sG, sB, alpha, dR, dG, dB, dA);
+                    CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt);
+                    src += srcbpp;
+                    dst += dstbpp;
+                }, n ,width);
+                src += srcskip;
+                dst += dstskip;
+            }
+        }
+    }
+}
 
 /*we assume the "dst" has pixel alpha*/
-int pygame_Blit(SDL_Surface *src, SDL_Rect *srcrect,
-                   SDL_Surface *dst, SDL_Rect *dstrect, int the_args)
+int 
+pygame_Blit (SDL_Surface * src, SDL_Rect * srcrect,
+             SDL_Surface * dst, SDL_Rect * dstrect, int the_args)
 {
-        SDL_Rect fulldst;
-        int srcx, srcy, w, h;
+    SDL_Rect        fulldst;
+    int             srcx, srcy, w, h;
 
-        /* Make sure the surfaces aren't locked */
-        if ( ! src || ! dst ) {
-                SDL_SetError("SDL_UpperBlit: passed a NULL surface");
-                return(-1);
+    /* Make sure the surfaces aren't locked */
+    if (!src || !dst)
+    {
+        SDL_SetError ("SDL_UpperBlit: passed a NULL surface");
+        return (-1);
+    }
+    if (src->locked || dst->locked)
+    {
+        SDL_SetError ("Surfaces must not be locked during blit");
+        return (-1);
+    }
+
+    /* If the destination rectangle is NULL, use the entire dest surface */
+    if (dstrect == NULL)
+    {
+        fulldst.x = fulldst.y = 0;
+        dstrect = &fulldst;
+    }
+
+    /* clip the source rectangle to the source surface */
+    if (srcrect)
+    {
+        int             maxw, maxh;
+
+        srcx = srcrect->x;
+        w = srcrect->w;
+        if (srcx < 0)
+        {
+            w += srcx;
+            dstrect->x -= srcx;
+            srcx = 0;
         }
-        if ( src->locked || dst->locked ) {
-                SDL_SetError("Surfaces must not be locked during blit");
-                return(-1);
+        maxw = src->w - srcx;
+        if (maxw < w)
+            w = maxw;
+
+        srcy = srcrect->y;
+        h = srcrect->h;
+        if (srcy < 0)
+        {
+            h += srcy;
+            dstrect->y -= srcy;
+            srcy = 0;
         }
+        maxh = src->h - srcy;
+        if (maxh < h)
+            h = maxh;
 
-        /* If the destination rectangle is NULL, use the entire dest surface */
-        if ( dstrect == NULL ) {
-                fulldst.x = fulldst.y = 0;
-                dstrect = &fulldst;
+    }
+    else
+    {
+        srcx = srcy = 0;
+        w = src->w;
+        h = src->h;
+    }
+
+    /* clip the destination rectangle against the clip rectangle */
+    {
+        SDL_Rect       *clip = &dst->clip_rect;
+        int             dx, dy;
+
+        dx = clip->x - dstrect->x;
+        if (dx > 0)
+        {
+            w -= dx;
+            dstrect->x += dx;
+            srcx += dx;
         }
+        dx = dstrect->x + w - clip->x - clip->w;
+        if (dx > 0)
+            w -= dx;
 
-        /* clip the source rectangle to the source surface */
-        if(srcrect) {
-                int maxw, maxh;
+        dy = clip->y - dstrect->y;
+        if (dy > 0)
+        {
+            h -= dy;
+            dstrect->y += dy;
+            srcy += dy;
+        }
+        dy = dstrect->y + h - clip->y - clip->h;
+        if (dy > 0)
+            h -= dy;
+    }
 
-                srcx = srcrect->x;
-                w = srcrect->w;
-                if(srcx < 0) {
-                        w += srcx;
-                        dstrect->x -= srcx;
-                        srcx = 0;
-                }
-                maxw = src->w - srcx;
-                if(maxw < w)
-                        w = maxw;
+    if (w > 0 && h > 0)
+    {
+        SDL_Rect        sr;
 
-                srcy = srcrect->y;
-                h = srcrect->h;
-                if(srcy < 0) {
-                        h += srcy;
-                        dstrect->y -= srcy;
-                        srcy = 0;
-                }
-                maxh = src->h - srcy;
-                if(maxh < h)
-                        h = maxh;
-
-        } else {
-                srcx = srcy = 0;
-                w = src->w;
-                h = src->h;
-        }
-
-        /* clip the destination rectangle against the clip rectangle */
-        {
-                SDL_Rect *clip = &dst->clip_rect;
-                int dx, dy;
-
-                dx = clip->x - dstrect->x;
-                if(dx > 0) {
-                        w -= dx;
-                        dstrect->x += dx;
-                        srcx += dx;
-                }
-                dx = dstrect->x + w - clip->x - clip->w;
-                if(dx > 0)
-                        w -= dx;
-
-                dy = clip->y - dstrect->y;
-                if(dy > 0) {
-                        h -= dy;
-                        dstrect->y += dy;
-                        srcy += dy;
-                }
-                dy = dstrect->y + h - clip->y - clip->h;
-                if(dy > 0)
-                        h -= dy;
-        }
-
-        if(w > 0 && h > 0) {
-                SDL_Rect sr;
-                sr.x = srcx;
-                sr.y = srcy;
-                sr.w = dstrect->w = w;
-                sr.h = dstrect->h = h;
-                return SoftBlitPyGame(src, &sr, dst, dstrect, the_args);
-        }
-        dstrect->w = dstrect->h = 0;
-        return 0;
+        sr.x = srcx;
+        sr.y = srcy;
+        sr.w = dstrect->w = w;
+        sr.h = dstrect->h = h;
+        return SoftBlitPyGame (src, &sr, dst, dstrect, the_args);
+    }
+    dstrect->w = dstrect->h = 0;
+    return 0;
 }
 
-
-int pygame_AlphaBlit (SDL_Surface *src, SDL_Rect *srcrect,
-                   SDL_Surface *dst, SDL_Rect *dstrect)
+int 
+pygame_AlphaBlit (SDL_Surface * src, SDL_Rect * srcrect,
+                  SDL_Surface * dst, SDL_Rect * dstrect)
 {
-    return pygame_Blit(src, srcrect, dst, dstrect, 0);
+    return pygame_Blit (src, srcrect, dst, dstrect, 0);
 }
-
-

File src/pygamedocs.h

 
 #define DOC_FONTGETDESCENT "Font.get_descent(): return int\nget the descent of the font"
 
-#define DOC_FONTMETRICS \
-  "Font.metrics(text): return list\n" \
-  "Gets the metrics for each character in the pased string.\n" \
-  "\n" \
-  "The list contains tuples for each character, which contain the minimum\n" \
-  "X offset, the maximum X offset, the minimum Y offset, the maximum\n" \
-  "Y offset and the advance offset (bearing plus width) of the character.\n" \
-  "[(minx, maxx, miny, maxy, advance), (minx, maxx, miny, maxy, advance), ...]"
- 
 #define DOC_PYGAMEIMAGE "pygame module for image transfer"
 
 #define DOC_PYGAMEIMAGELOAD "pygame.image.load(filename): return Surface\npygame.image.load(fileobj, namehint=""): return Surface\nload new image from a file"
 
 #define DOC_SURFACECOPY "Surface.copy(): return Surface\ncreate a new copy of a Surface"
 
-#define DOC_SURFACEFILL "Surface.fill(color, rect=None): return Rect\nfill Surface with a solid color"
+#define DOC_SURFACEFILL "Surface.fill(color, rect=None, special_flags=0): return Rect\nfill Surface with a solid color"
 
 #define DOC_SURFACESETCOLORKEY "Surface.set_colorkey(Color, flags=0): return None\nSurface.set_colorkey(None): return None\nSet the transparent colorkey"
 

File src/surface.c

 /*
-    pygame - Python Game Library
-    Copyright (C) 2000-2001  Pete Shinners
+  pygame - Python Game Library
+  Copyright (C) 2000-2001  Pete Shinners
+  Copyright (C) 2007 Marcus von Appen
 
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Library General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or (at your option) any later version.
 
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Library General Public License for more details.
 
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  You should have received a copy of the GNU Library General Public
+  License along with this library; if not, write to the Free
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-    Pete Shinners
-    pete@shinners.org
+  Pete Shinners
+  pete@shinners.org
 */
 
-/*
- *  pygame Surface module
- */
 #define PYGAMEAPI_SURFACE_INTERNAL
-#include "pygame.h"
+
+#include "surface.h"
 #include "pygamedocs.h"
 #include "structmember.h"
 
-staticforward PyTypeObject PySurface_Type;
-static PyObject* PySurface_New(SDL_Surface* info);
-#define PySurface_Check(x) ((x)->ob_type == &PySurface_Type)
-extern int pygame_AlphaBlit(SDL_Surface *src, SDL_Rect *srcrect,
-                        SDL_Surface *dst, SDL_Rect *dstrect);
-extern int pygame_Blit(SDL_Surface *src, SDL_Rect *srcrect,
-                        SDL_Surface *dst, SDL_Rect *dstrect, int the_args);
+int
+PySurface_Blit (PyObject * dstobj, PyObject * srcobj, SDL_Rect * dstrect,
+                SDL_Rect * srcrect, int the_args);
 
-static PyObject* surface_new(PyTypeObject *type, PyObject *args,
-                             PyObject *kwds);
-static intptr_t surface_init(PySurfaceObject *self, PyObject *args,
-                             PyObject *kwds);
+/* statics */
+static PyObject *PySurface_New (SDL_Surface * info);
+static PyObject *surface_new (PyTypeObject *type, PyObject *args,
+                              PyObject *kwds);
+static intptr_t surface_init (PySurfaceObject *self, PyObject *args,
+                              PyObject *kwds);
+static PyObject* surface_str (PyObject *self);
+static void surface_dealloc (PyObject *self);
+static void surface_cleanup (PySurfaceObject * self);
 
-/* surface object methods */
-static PyObject* surf_get_at(PyObject* self, PyObject* arg)
-{
-    SDL_Surface* surf = PySurface_AsSurface(self);
-    SDL_PixelFormat* format = surf->format;
-    Uint8* pixels = (Uint8*)surf->pixels;
-    int x, y;
-    Uint32 color;
-    Uint8* pix;
-    Uint8 r, g, b, a;
-    
-    if(!PyArg_ParseTuple(arg, "(ii)", &x, &y))
-        return NULL;
-    if(!surf)
-        return RAISE(PyExc_SDLError, "display Surface quit");
-    
-    if(surf->flags & SDL_OPENGL)
-        return RAISE(PyExc_SDLError, "Cannot call on OPENGL Surfaces");
-
-    if(x < 0 || x >= surf->w || y < 0 || y >= surf->h)
-        return RAISE(PyExc_IndexError, "pixel index out of range");
-
-    if(format->BytesPerPixel < 1 || format->BytesPerPixel > 4)
-        return RAISE(PyExc_RuntimeError, "invalid color depth for surface");
-    
-    if(!PySurface_Lock(self))
-        return NULL;
-    pixels = (Uint8*)surf->pixels;
-
-    switch(format->BytesPerPixel)
-    {
-    case 1:
-        color = (Uint32)*((Uint8*)pixels + y * surf->pitch + x);
-        break;
-    case 2:
-        color = (Uint32)*((Uint16*)(pixels + y * surf->pitch) + x);
-        break;
-    case 3:
-        pix = ((Uint8*)(pixels + y * surf->pitch) + x * 3);
-#if SDL_BYTEORDER == SDL_LIL_ENDIAN
-        color = (pix[0]) + (pix[1]<<8) + (pix[2]<<16);
-#else
-        color = (pix[2]) + (pix[1]<<8) + (pix[0]<<16);
-#endif
-        break;
-    default: /*case 4:*/
-        color = *((Uint32*)(pixels + y * surf->pitch) + x);
-        break;
-    }
-    if(!PySurface_Unlock(self))
-        return NULL;
-
-    SDL_GetRGBA(color, format, &r, &g, &b, &a);
-    return Py_BuildValue("(bbbb)", r, g, b, a);
-}
-
-static PyObject* surf_set_at(PyObject* self, PyObject* args)
-{
-    SDL_Surface* surf = PySurface_AsSurface(self);
-    SDL_PixelFormat* format = surf->format;
-    Uint8* pixels;
-    int x, y;
-    Uint32 color;
-    Uint8 rgba[4];
-    PyObject* rgba_obj;
-    Uint8* byte_buf;
-    
-    if(!PyArg_ParseTuple(args, "(ii)O", &x, &y, &rgba_obj))
-        return NULL;
-    if(!surf)
-        return RAISE(PyExc_SDLError, "display Surface quit");
-
-    if(surf->flags & SDL_OPENGL)
-        return RAISE(PyExc_SDLError, "Cannot call on OPENGL Surfaces");
-
-    if(format->BytesPerPixel < 1 || format->BytesPerPixel > 4)
-        return RAISE(PyExc_RuntimeError, "invalid color depth for surface");
-
-    if(x < surf->clip_rect.x || x >= surf->clip_rect.x + surf->clip_rect.w ||
-       y < surf->clip_rect.y || y >= surf->clip_rect.y + surf->clip_rect.h)
-    {
-        /*out of clip area*/
-        Py_RETURN_NONE;
-    }
-
-    if(PyInt_Check(rgba_obj))
-        color = (Uint32)PyInt_AsLong(rgba_obj);
-    else if(RGBAFromObj(rgba_obj, rgba))
-        color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]);
-    else
-        return RAISE(PyExc_TypeError, "invalid color argument");
-
-    if(!PySurface_Lock(self))
-        return NULL;
-    pixels = (Uint8*)surf->pixels;
-
-    switch(format->BytesPerPixel)
-    {
-    case 1:
-        *((Uint8*)pixels + y * surf->pitch + x) = (Uint8)color;
-        break;
-    case 2:
-        *((Uint16*)(pixels + y * surf->pitch) + x) = (Uint16)color;
-        break;
-    case 3:
-        byte_buf = (Uint8*)(pixels + y * surf->pitch) + x * 3;
-#if (SDL_BYTEORDER == SDL_LIL_ENDIAN)
-        *(byte_buf + (format->Rshift >> 3)) = rgba[0];
-        *(byte_buf + (format->Gshift >> 3)) = rgba[1];
-        *(byte_buf + (format->Bshift >> 3)) = rgba[2];
-#else
-        *(byte_buf + 2 - (format->Rshift >> 3)) = rgba[0];
-        *(byte_buf + 2 - (format->Gshift >> 3)) = rgba[1];
-        *(byte_buf + 2 - (format->Bshift >> 3)) = rgba[2];
-#endif
-        break;
-    default: /*case 4:*/
-        *((Uint32*)(pixels + y * surf->pitch) + x) = color;
-        break;
-    }
-
-    if(!PySurface_Unlock(self))
-        return NULL;
-    Py_RETURN_NONE;
-}
-
-static PyObject* surf_map_rgb(PyObject* self,PyObject* args)
-{
-    SDL_Surface* surf = PySurface_AsSurface(self);
-    Uint8 rgba[4];
-    int color;
-    
-    if(!RGBAFromObj(args, rgba))
-        return RAISE(PyExc_TypeError, "Invalid RGBA argument");
-    if(!surf)
-        return RAISE(PyExc_SDLError, "display Surface quit");
-
-    color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]);
-    return PyInt_FromLong(color);
-}
-
-static PyObject* surf_unmap_rgb(PyObject* self,PyObject* args)
-{
-    SDL_Surface* surf = PySurface_AsSurface(self);
-    Uint32 col;
-    Uint8 r, g, b, a;
-    
-    if(!PyArg_ParseTuple(args, "i", &col))
-        return NULL;
-    if(!surf)
-        return RAISE(PyExc_SDLError, "display Surface quit");
-    
-    SDL_GetRGBA(col,surf->format, &r, &g, &b, &a);
-    
-    return Py_BuildValue("(bbbb)", r, g, b, a);
-}
-
-static PyObject* surf_lock(PyObject* self, PyObject* args)
-{
-    if(!PyArg_ParseTuple(args, ""))
-        return NULL;
-
-    if(!PySurface_Lock(self))
-        return NULL;
-
-    Py_RETURN_NONE;
-}
-
-static PyObject* surf_unlock(PyObject* self, PyObject* args)
-{
-    if(!PyArg_ParseTuple(args, ""))
-        return NULL;
-
-    if(!PySurface_Unlock(self))
-        return NULL;
-
-    Py_RETURN_NONE;
-}
-
-static PyObject* surf_mustlock(PyObject* self, PyObject* args)
-{
<