Commits

illume  committed 286423e

Included a couple of files from SDL_gfx for the gfxdraw module.

  • Participants
  • Parent commits c5a7fed

Comments (0)

Files changed (4)

 #proposed SDL_gfx module backported from pgreloaded. requires SDL_gfx.
 #if accepted, then move GFX def to StartConfig section and add SDL_gfx
 #search to configure modules for Unix, Darwin and Windows.
-GFX = -lSDL_gfx
+#GFX = -lSDL_gfx
 #gfxdraw src/gfxdraw.c $(SDL) $(GFX) $(DEBUG)
 
+GFX = src/SDL_gfx/SDL_gfxPrimitives.c 
+#GFX = src/SDL_gfx/SDL_gfxBlitFunc.c src/SDL_gfx/SDL_gfxPrimitives.c 
+gfxdraw src/gfxdraw.c $(SDL) $(GFX) $(DEBUG)
+
+
+
 #experimental new movie movie. requires libavcodec and libavformat.
 #add any necessary compile flags to this line and uncomment.
 #movieext src/movie.c  src/ffmovie.c $(SDL) -lavcodec -lavformat

File config_unix.py

         Dependency('SCRAP', '', 'libX11', ['X11']),
         Dependency('PORTMIDI', 'portmidi.h', 'libportmidi.so', ['portmidi']),
         Dependency('PORTTIME', 'porttime.h', 'libporttime.so', ['porttime']),
+        #Dependency('GFX', 'SDL_gfxPrimitives.h', 'libSDL_gfx.so', ['SDL_gfx']),
     ]
 
     if not DEPS[0].found:

File src/SDL_gfx/SDL_gfxPrimitives.c

+/* 
+
+ SDL_gfxPrimitives - Graphics primitives for SDL surfaces
+
+ LGPL (c) A. Schiffler
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "SDL_gfxPrimitives.h"
+#include "SDL_gfxPrimitives_font.h"
+
+/* -===================- */
+
+#define DEFAULT_ALPHA_PIXEL_ROUTINE
+
+/* ----- Defines for pixel clipping tests */
+
+#define clip_xmin(surface) surface->clip_rect.x
+#define clip_xmax(surface) surface->clip_rect.x+surface->clip_rect.w-1
+#define clip_ymin(surface) surface->clip_rect.y
+#define clip_ymax(surface) surface->clip_rect.y+surface->clip_rect.h-1
+
+/* ----- Pixel - fast, no blending, no locking, clipping */
+
+int fastPixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
+{
+    int bpp;
+    Uint8 *p;
+
+    /*
+     * Honor clipping setup at pixel level 
+     */
+    if ((x >= clip_xmin(dst)) && (x <= clip_xmax(dst)) && (y >= clip_ymin(dst)) && (y <= clip_ymax(dst))) {
+
+	/*
+	 * Get destination format 
+	 */
+	bpp = dst->format->BytesPerPixel;
+	p = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
+	switch (bpp) {
+	case 1:
+	    *p = color;
+	    break;
+	case 2:
+	    *(Uint16 *) p = color;
+	    break;
+	case 3:
+	    if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+		p[0] = (color >> 16) & 0xff;
+		p[1] = (color >> 8) & 0xff;
+		p[2] = color & 0xff;
+	    } else {
+		p[0] = color & 0xff;
+		p[1] = (color >> 8) & 0xff;
+		p[2] = (color >> 16) & 0xff;
+	    }
+	    break;
+	case 4:
+	    *(Uint32 *) p = color;
+	    break;
+	}			/* switch */
+
+
+    }
+
+    return (0);
+}
+
+/* ----- Pixel - fast, no blending, no locking, no clipping */
+
+/* (faster but dangerous, make sure we stay in surface bounds) */
+
+int fastPixelColorNolockNoclip(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
+{
+    int bpp;
+    Uint8 *p;
+
+    /*
+     * Get destination format 
+     */
+    bpp = dst->format->BytesPerPixel;
+    p = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
+    switch (bpp) {
+    case 1:
+	*p = color;
+	break;
+    case 2:
+	*(Uint16 *) p = color;
+	break;
+    case 3:
+	if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+	    p[0] = (color >> 16) & 0xff;
+	    p[1] = (color >> 8) & 0xff;
+	    p[2] = color & 0xff;
+	} else {
+	    p[0] = color & 0xff;
+	    p[1] = (color >> 8) & 0xff;
+	    p[2] = (color >> 16) & 0xff;
+	}
+	break;
+    case 4:
+	*(Uint32 *) p = color;
+	break;
+    }				/* switch */
+
+    return (0);
+}
+
+/* ----- Pixel - fast, no blending, locking, clipping */
+
+int fastPixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
+{
+    int result;
+
+    /*
+     * Lock the surface 
+     */
+    if (SDL_MUSTLOCK(dst)) {
+	if (SDL_LockSurface(dst) < 0) {
+	    return (-1);
+	}
+    }
+
+    result = fastPixelColorNolock(dst, x, y, color);
+
+    /*
+     * Unlock surface 
+     */
+    if (SDL_MUSTLOCK(dst)) {
+	SDL_UnlockSurface(dst);
+    }
+
+    return (result);
+}
+
+/* ----- Pixel - fast, no blending, locking, RGB input */
+
+int fastPixelRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    Uint32 color;
+
+    /*
+     * Setup color 
+     */
+    color = SDL_MapRGBA(dst->format, r, g, b, a);
+
+    /*
+     * Draw 
+     */
+    return (fastPixelColor(dst, x, y, color));
+
+}
+
+/* ----- Pixel - fast, no blending, no locking RGB input */
+
+int fastPixelRGBANolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    Uint32 color;
+
+    /*
+     * Setup color 
+     */
+    color = SDL_MapRGBA(dst->format, r, g, b, a);
+
+    /*
+     * Draw 
+     */
+    return (fastPixelColorNolock(dst, x, y, color));
+}
+
+/* PutPixel routine with alpha blending, input color in destination format */
+
+/* New, faster routine - default blending pixel */
+
+int _putPixelAlpha(SDL_Surface * surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha)
+{
+    Uint32 Rmask = surface->format->Rmask, Gmask =
+	surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
+    Uint32 R = 0, G = 0, B = 0, A = 0;
+
+    if (x >= clip_xmin(surface) && x <= clip_xmax(surface)
+	&& y >= clip_ymin(surface) && y <= clip_ymax(surface)) {
+
+	switch (surface->format->BytesPerPixel) {
+	case 1:{		/* Assuming 8-bpp */
+		if (alpha == 255) {
+		    *((Uint8 *) surface->pixels + y * surface->pitch + x) = color;
+		} else {
+		    Uint8 *pixel = (Uint8 *) surface->pixels + y * surface->pitch + x;
+
+		    Uint8 dR = surface->format->palette->colors[*pixel].r;
+		    Uint8 dG = surface->format->palette->colors[*pixel].g;
+		    Uint8 dB = surface->format->palette->colors[*pixel].b;
+		    Uint8 sR = surface->format->palette->colors[color].r;
+		    Uint8 sG = surface->format->palette->colors[color].g;
+		    Uint8 sB = surface->format->palette->colors[color].b;
+
+		    dR = dR + ((sR - dR) * alpha >> 8);
+		    dG = dG + ((sG - dG) * alpha >> 8);
+		    dB = dB + ((sB - dB) * alpha >> 8);
+
+		    *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
+		}
+	    }
+	    break;
+
+	case 2:{		/* Probably 15-bpp or 16-bpp */
+		if (alpha == 255) {
+		    *((Uint16 *) surface->pixels + y * surface->pitch / 2 + x) = color;
+		} else {
+		    Uint16 *pixel = (Uint16 *) surface->pixels + y * surface->pitch / 2 + x;
+		    Uint32 dc = *pixel;
+
+		    R = ((dc & Rmask) + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask;
+		    G = ((dc & Gmask) + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask;
+		    B = ((dc & Bmask) + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask;
+		    if (Amask)
+			A = ((dc & Amask) + (((color & Amask) - (dc & Amask)) * alpha >> 8)) & Amask;
+
+		    *pixel = R | G | B | A;
+		}
+	    }
+	    break;
+
+	case 3:{		/* Slow 24-bpp mode, usually not used */
+		Uint8 *pix = (Uint8 *) surface->pixels + y * surface->pitch + x * 3;
+		Uint8 rshift8 = surface->format->Rshift / 8;
+		Uint8 gshift8 = surface->format->Gshift / 8;
+		Uint8 bshift8 = surface->format->Bshift / 8;
+		Uint8 ashift8 = surface->format->Ashift / 8;
+
+
+		if (alpha == 255) {
+		    *(pix + rshift8) = color >> surface->format->Rshift;
+		    *(pix + gshift8) = color >> surface->format->Gshift;
+		    *(pix + bshift8) = color >> surface->format->Bshift;
+		    *(pix + ashift8) = color >> surface->format->Ashift;
+		} else {
+		    Uint8 dR, dG, dB, dA = 0;
+		    Uint8 sR, sG, sB, sA = 0;
+
+		    pix = (Uint8 *) surface->pixels + y * surface->pitch + x * 3;
+
+		    dR = *((pix) + rshift8);
+		    dG = *((pix) + gshift8);
+		    dB = *((pix) + bshift8);
+		    dA = *((pix) + ashift8);
+
+		    sR = (color >> surface->format->Rshift) & 0xff;
+		    sG = (color >> surface->format->Gshift) & 0xff;
+		    sB = (color >> surface->format->Bshift) & 0xff;
+		    sA = (color >> surface->format->Ashift) & 0xff;
+
+		    dR = dR + ((sR - dR) * alpha >> 8);
+		    dG = dG + ((sG - dG) * alpha >> 8);
+		    dB = dB + ((sB - dB) * alpha >> 8);
+		    dA = dA + ((sA - dA) * alpha >> 8);
+
+		    *((pix) + rshift8) = dR;
+		    *((pix) + gshift8) = dG;
+		    *((pix) + bshift8) = dB;
+		    *((pix) + ashift8) = dA;
+		}
+	    }
+	    break;
+
+#ifdef DEFAULT_ALPHA_PIXEL_ROUTINE
+
+	case 4:{		/* Probably :-) 32-bpp */
+		if (alpha == 255) {
+		    *((Uint32 *) surface->pixels + y * surface->pitch / 4 + x) = color;
+		} else {
+		    Uint32 Rshift, Gshift, Bshift, Ashift;
+		    Uint32 *pixel = (Uint32 *) surface->pixels + y * surface->pitch / 4 + x;
+		    Uint32 dc = *pixel;
+
+		    Rshift = surface->format->Rshift;
+		    Gshift = surface->format->Gshift;
+		    Bshift = surface->format->Bshift;
+		    Ashift = surface->format->Ashift;
+
+		    R = ((dc & Rmask) + (((((color & Rmask) - (dc & Rmask)) >> Rshift) * alpha >> 8) << Rshift)) & Rmask;
+		    G = ((dc & Gmask) + (((((color & Gmask) - (dc & Gmask)) >> Gshift) * alpha >> 8) << Gshift)) & Gmask;
+		    B = ((dc & Bmask) + (((((color & Bmask) - (dc & Bmask)) >> Bshift) * alpha >> 8) << Bshift)) & Bmask;
+		    if (Amask)
+			A = ((dc & Amask) + (((((color & Amask) - (dc & Amask)) >> Ashift) * alpha >> 8) << Ashift)) & Amask;
+
+		    *pixel = R | G | B | A;
+		}
+	    }
+	    break;
+#endif
+
+#ifdef EXPERIMENTAL_ALPHA_PIXEL_ROUTINE
+
+	case 4:{		/* Probably :-) 32-bpp */
+		if (alpha == 255) {
+		    *((Uint32 *) surface->pixels + y * surface->pitch / 4 + x) = color;
+		} else {
+		    Uint32 Rshift, Gshift, Bshift, Ashift;
+		    Uint32 *pixel = (Uint32 *) surface->pixels + y * surface->pitch / 4 + x;
+		    Uint32 dc = *pixel;
+		    Uint32 dR = (color & Rmask), dG = (color & Gmask), dB = (color & Bmask), dA = (color & Amask);
+		    Uint32 surfaceAlpha, preMultR, preMultG, preMultB;
+		    Uint32 aTmp;
+
+		    Rshift = surface->format->Rshift;
+		    Gshift = surface->format->Gshift;
+		    Bshift = surface->format->Bshift;
+		    Ashift = surface->format->Ashift;
+
+                    preMultR = (alpha * (dR>>Rshift));
+                    preMultG = (alpha * (dG>>Gshift));
+                    preMultB = (alpha * (dB>>Bshift));
+
+                    surfaceAlpha = ((dc & Amask) >> Ashift);
+                    aTmp = (255 - alpha);
+                    if (A = 255 - ((aTmp * (255 - surfaceAlpha)) >> 8 )) {
+                      aTmp *= surfaceAlpha;
+                      R = (preMultR + ((aTmp * ((dc & Rmask) >> Rshift)) >> 8)) / A << Rshift & Rmask;
+                      G = (preMultG + ((aTmp * ((dc & Gmask) >> Gshift)) >> 8)) / A << Gshift & Gmask;
+                      B = (preMultB + ((aTmp * ((dc & Bmask) >> Bshift)) >> 8)) / A << Bshift & Bmask;
+                    }
+		    *pixel = R | G | B | (A << Ashift & Amask);
+
+		}
+	    }
+	    break;
+#endif
+	}
+    }
+
+    return (0);
+}
+
+/* ----- Pixel - pixel draw with blending enabled if a<255 */
+
+int pixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
+{
+    Uint8 alpha;
+    Uint32 mcolor;
+    int result = 0;
+
+    /*
+     * Lock the surface 
+     */
+    if (SDL_MUSTLOCK(dst)) {
+	if (SDL_LockSurface(dst) < 0) {
+	    return (-1);
+	}
+    }
+
+    /*
+     * Setup color 
+     */
+    alpha = color & 0x000000ff;
+    mcolor =
+	SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
+		    (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
+
+    /*
+     * Draw 
+     */
+    result = _putPixelAlpha(dst, x, y, mcolor, alpha);
+
+    /*
+     * Unlock the surface 
+     */
+    if (SDL_MUSTLOCK(dst)) {
+	SDL_UnlockSurface(dst);
+    }
+
+    return (result);
+}
+
+int pixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
+{
+    Uint8 alpha;
+    Uint32 mcolor;
+    int result = 0;
+
+    /*
+     * Setup color 
+     */
+    alpha = color & 0x000000ff;
+    mcolor =
+	SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
+		    (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
+
+    /*
+     * Draw 
+     */
+    result = _putPixelAlpha(dst, x, y, mcolor, alpha);
+
+    return (result);
+}
+
+
+/* Filled rectangle with alpha blending, color in destination format */
+
+int _filledRectAlpha(SDL_Surface * surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
+{
+    Uint32 Rmask = surface->format->Rmask, Gmask =
+	surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
+    Uint32 R, G, B, A = 0;
+    Sint16 x, y;
+
+    switch (surface->format->BytesPerPixel) {
+    case 1:{			/* Assuming 8-bpp */
+	    Uint8 *row, *pixel;
+	    Uint8 dR, dG, dB;
+
+	    Uint8 sR = surface->format->palette->colors[color].r;
+	    Uint8 sG = surface->format->palette->colors[color].g;
+	    Uint8 sB = surface->format->palette->colors[color].b;
+
+	    for (y = y1; y <= y2; y++) {
+		row = (Uint8 *) surface->pixels + y * surface->pitch;
+		for (x = x1; x <= x2; x++) {
+		    pixel = row + x;
+
+		    dR = surface->format->palette->colors[*pixel].r;
+		    dG = surface->format->palette->colors[*pixel].g;
+		    dB = surface->format->palette->colors[*pixel].b;
+
+		    dR = dR + ((sR - dR) * alpha >> 8);
+		    dG = dG + ((sG - dG) * alpha >> 8);
+		    dB = dB + ((sB - dB) * alpha >> 8);
+
+		    *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
+		}
+	    }
+	}
+	break;
+
+    case 2:{			/* Probably 15-bpp or 16-bpp */
+	    Uint16 *row, *pixel;
+	    Uint32 dR = (color & Rmask), dG = (color & Gmask), dB = (color & Bmask), dA = (color & Amask);
+
+	    for (y = y1; y <= y2; y++) {
+		row = (Uint16 *) surface->pixels + y * surface->pitch / 2;
+		for (x = x1; x <= x2; x++) {
+		    pixel = row + x;
+
+		    R = ((*pixel & Rmask) + ((dR - (*pixel & Rmask)) * alpha >> 8)) & Rmask;
+		    G = ((*pixel & Gmask) + ((dG - (*pixel & Gmask)) * alpha >> 8)) & Gmask;
+		    B = ((*pixel & Bmask) + ((dB - (*pixel & Bmask)) * alpha >> 8)) & Bmask;
+		    if (Amask)
+			A = ((*pixel & Amask) + ((dA - (*pixel & Amask)) * alpha >> 8)) & Amask;
+
+		    *pixel = R | G | B | A;
+		}
+	    }
+	}
+	break;
+
+    case 3:{			/* Slow 24-bpp mode, usually not used */
+	    Uint8 *row, *pix;
+	    Uint8 dR, dG, dB, dA;
+	    Uint8 rshift8 = surface->format->Rshift / 8;
+	    Uint8 gshift8 = surface->format->Gshift / 8;
+	    Uint8 bshift8 = surface->format->Bshift / 8;
+	    Uint8 ashift8 = surface->format->Ashift / 8;
+
+	    Uint8 sR = (color >> surface->format->Rshift) & 0xff;
+	    Uint8 sG = (color >> surface->format->Gshift) & 0xff;
+	    Uint8 sB = (color >> surface->format->Bshift) & 0xff;
+	    Uint8 sA = (color >> surface->format->Ashift) & 0xff;
+
+	    for (y = y1; y <= y2; y++) {
+		row = (Uint8 *) surface->pixels + y * surface->pitch;
+		for (x = x1; x <= x2; x++) {
+		    pix = row + x * 3;
+
+		    dR = *((pix) + rshift8);
+		    dG = *((pix) + gshift8);
+		    dB = *((pix) + bshift8);
+		    dA = *((pix) + ashift8);
+
+		    dR = dR + ((sR - dR) * alpha >> 8);
+		    dG = dG + ((sG - dG) * alpha >> 8);
+		    dB = dB + ((sB - dB) * alpha >> 8);
+		    dA = dA + ((sA - dA) * alpha >> 8);
+
+		    *((pix) + rshift8) = dR;
+		    *((pix) + gshift8) = dG;
+		    *((pix) + bshift8) = dB;
+		    *((pix) + ashift8) = dA;
+		}
+	    }
+
+	}
+	break;
+
+#ifdef DEFAULT_ALPHA_PIXEL_ROUTINE
+    case 4:{			/* Probably :-) 32-bpp */
+	    Uint32 Rshift, Gshift, Bshift, Ashift;
+	    Uint32 *row, *pixel;
+	    Uint32 dR = (color & Rmask), dG = (color & Gmask), dB = (color & Bmask), dA = (color & Amask);
+
+	    Rshift = surface->format->Rshift;
+	    Gshift = surface->format->Gshift;
+	    Bshift = surface->format->Bshift;
+	    Ashift = surface->format->Ashift;
+
+	    for (y = y1; y <= y2; y++) {
+		row = (Uint32 *) surface->pixels + y * surface->pitch / 4;
+		for (x = x1; x <= x2; x++) {
+		    pixel = row + x;
+
+		    R = ((*pixel & Rmask) + ((((dR - (*pixel & Rmask)) >> Rshift) * alpha >> 8) << Rshift)) & Rmask;
+		    G = ((*pixel & Gmask) + ((((dG - (*pixel & Gmask)) >> Gshift) * alpha >> 8) << Gshift)) & Gmask;
+		    B = ((*pixel & Bmask) + ((((dB - (*pixel & Bmask)) >> Bshift) * alpha >> 8) << Bshift)) & Bmask;
+		    if (Amask)
+			A = ((*pixel & Amask) + ((((dA - (*pixel & Amask)) >> Ashift) * alpha >> 8) << Ashift)) & Amask;
+
+		    *pixel = R | G | B | A;
+		}
+	    }
+	}
+	break;
+#endif
+
+#ifdef EXPERIMENTAL_ALPHA_PIXEL_ROUTINE
+    case 4:{			/* Probably :-) 32-bpp */
+	    Uint32 Rshift, Gshift, Bshift, Ashift;
+	    Uint32 *row, *pixel;
+	    Uint32 dR = (color & Rmask), dG = (color & Gmask), dB = (color & Bmask), dA = (color & Amask);
+            Uint32 dc;
+            Uint32 surfaceAlpha, preMultR, preMultG, preMultB;
+            Uint32 aTmp;
+
+	    Rshift = surface->format->Rshift;
+	    Gshift = surface->format->Gshift;
+	    Bshift = surface->format->Bshift;
+	    Ashift = surface->format->Ashift;
+
+            preMultR = (alpha * (dR>>Rshift));
+            preMultG = (alpha * (dG>>Gshift));
+            preMultB = (alpha * (dB>>Bshift));
+
+	    for (y = y1; y <= y2; y++) {
+		row = (Uint32 *) surface->pixels + y * surface->pitch / 4;
+		for (x = x1; x <= x2; x++) {
+		    pixel = row + x;
+		    dc = *pixel;
+
+                    surfaceAlpha = ((dc & Amask) >> Ashift);
+                    aTmp = (255 - alpha);
+                    if (A = 255 - ((aTmp * (255 - surfaceAlpha)) >> 8 )) {
+                      aTmp *= surfaceAlpha;
+                      R = (preMultR + ((aTmp * ((dc & Rmask) >> Rshift)) >> 8)) / A << Rshift & Rmask;
+                      G = (preMultG + ((aTmp * ((dc & Gmask) >> Gshift)) >> 8)) / A << Gshift & Gmask;
+                      B = (preMultB + ((aTmp * ((dc & Bmask) >> Bshift)) >> 8)) / A << Bshift & Bmask;
+                    }
+		    *pixel = R | G | B | (A << Ashift & Amask);
+		    
+		}
+	    }
+	}
+	break;
+#endif
+	
+    }
+
+    return (0);
+}
+
+/* Draw rectangle with alpha enabled from RGBA color. */
+
+int filledRectAlpha(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
+{
+    Uint8 alpha;
+    Uint32 mcolor;
+    int result = 0;
+
+    /*
+     * Lock the surface 
+     */
+    if (SDL_MUSTLOCK(dst)) {
+	if (SDL_LockSurface(dst) < 0) {
+	    return (-1);
+	}
+    }
+
+    /*
+     * Setup color 
+     */
+    alpha = color & 0x000000ff;
+    mcolor =
+	SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
+		    (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
+
+    /*
+     * Draw 
+     */
+    result = _filledRectAlpha(dst, x1, y1, x2, y2, mcolor, alpha);
+
+    /*
+     * Unlock the surface 
+     */
+    if (SDL_MUSTLOCK(dst)) {
+	SDL_UnlockSurface(dst);
+    }
+
+    return (result);
+}
+
+/* Draw horizontal line with alpha enabled from RGBA color */
+
+int HLineAlpha(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
+{
+    return (filledRectAlpha(dst, x1, y, x2, y, color));
+}
+
+
+/* Draw vertical line with alpha enabled from RGBA color */
+
+int VLineAlpha(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
+{
+    return (filledRectAlpha(dst, x, y1, x, y2, color));
+}
+
+
+/* Pixel - using alpha weight on color for AA-drawing */
+
+int pixelColorWeight(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight)
+{
+    Uint32 a;
+
+    /*
+     * Get alpha 
+     */
+    a = (color & (Uint32) 0x000000ff);
+
+    /*
+     * Modify Alpha by weight 
+     */
+    a = ((a * weight) >> 8);
+
+    return (pixelColor(dst, x, y, (color & (Uint32) 0xffffff00) | (Uint32) a));
+}
+
+/* Pixel - using alpha weight on color for AA-drawing - no locking */
+
+int pixelColorWeightNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight)
+{
+    Uint32 a;
+
+    /*
+     * Get alpha 
+     */
+    a = (color & (Uint32) 0x000000ff);
+
+    /*
+     * Modify Alpha by weight 
+     */
+    a = ((a * weight) >> 8);
+
+    return (pixelColorNolock(dst, x, y, (color & (Uint32) 0xffffff00) | (Uint32) a));
+}
+
+int pixelRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    Uint32 color;
+
+    /*
+     * Check Alpha 
+     */
+    if (a == 255) {
+	/*
+	 * No alpha blending required 
+	 */
+	/*
+	 * Setup color 
+	 */
+	color = SDL_MapRGBA(dst->format, r, g, b, a);
+	/*
+	 * Draw 
+	 */
+	return (fastPixelColor(dst, x, y, color));
+    } else {
+	/*
+	 * Alpha blending required 
+	 */
+	/*
+	 * Draw 
+	 */
+	return (pixelColor(dst, x, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
+    }
+}
+
+/* ----- Horizontal line */
+
+/* Just store color including alpha, no blending */
+
+int hlineColorStore(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
+{
+    Sint16 left, right, top, bottom;
+    Uint8 *pixel, *pixellast;
+    int dx;
+    int pixx, pixy;
+    Sint16 w;
+    Sint16 xtmp;
+    int result = -1;
+
+    /*
+     * Check visibility of clipping rectangle
+     */
+    if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
+     return(0);
+    }
+    
+    /*
+     * Swap x1, x2 if required to ensure x1<=x2
+     */
+    if (x1 > x2) {
+	xtmp = x1;
+	x1 = x2;
+	x2 = xtmp;
+    }
+
+    /*
+     * Get clipping boundary and
+     * check visibility of hline 
+     */
+    left = dst->clip_rect.x;
+    if (x2<left) {
+     return(0);
+    }
+    right = dst->clip_rect.x + dst->clip_rect.w - 1;
+    if (x1>right) {
+     return(0);
+    }
+    top = dst->clip_rect.y;
+    bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
+    if ((y<top) || (y>bottom)) {
+     return (0);
+    }
+
+    /*
+     * Clip x 
+     */
+    if (x1 < left) {
+	x1 = left;
+    }
+    if (x2 > right) {
+	x2 = right;
+    }
+
+    /*
+     * Calculate width 
+     */
+    w = x2 - x1;
+
+    /*
+     * Lock surface 
+     */
+    SDL_LockSurface(dst);
+
+    /*
+     * More variable setup 
+     */
+    dx = w;
+    pixx = dst->format->BytesPerPixel;
+	pixy = dst->pitch;
+	pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
+
+	/*
+	 * Draw 
+	 */
+	switch (dst->format->BytesPerPixel) {
+	case 1:
+	    memset(pixel, color, dx);
+	    break;
+	case 2:
+	    pixellast = pixel + dx + dx;
+	    for (; pixel <= pixellast; pixel += pixx) {
+		*(Uint16 *) pixel = color;
+	    }
+	    break;
+	case 3:
+	    pixellast = pixel + dx + dx + dx;
+	    for (; pixel <= pixellast; pixel += pixx) {
+		if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+		    pixel[0] = (color >> 16) & 0xff;
+		    pixel[1] = (color >> 8) & 0xff;
+		    pixel[2] = color & 0xff;
+		} else {
+		    pixel[0] = color & 0xff;
+		    pixel[1] = (color >> 8) & 0xff;
+		    pixel[2] = (color >> 16) & 0xff;
+		}
+	    }
+	    break;
+	default:		/* case 4 */
+	    dx = dx + dx;
+	    pixellast = pixel + dx + dx;
+	    for (; pixel <= pixellast; pixel += pixx) {
+		*(Uint32 *) pixel = color;
+	    }
+	    break;
+	}
+
+	/*
+	 * Unlock surface 
+	 */
+	SDL_UnlockSurface(dst);
+
+	/*
+	 * Set result code 
+	 */
+	result = 0;
+
+    return (result);
+}
+
+int hlineRGBAStore(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    /*
+     * Draw 
+     */
+    return (hlineColorStore(dst, x1, x2, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
+}
+
+int hlineColor(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
+{
+    Sint16 left, right, top, bottom;
+    Uint8 *pixel, *pixellast;
+    int dx;
+    int pixx, pixy;
+    Sint16 w;
+    Sint16 xtmp;
+    int result = -1;
+    Uint8 *colorptr;
+
+    /*
+     * Check visibility of clipping rectangle
+     */
+    if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
+     return(0);
+    }
+    
+    /*
+     * Swap x1, x2 if required to ensure x1<=x2
+     */
+    if (x1 > x2) {
+	xtmp = x1;
+	x1 = x2;
+	x2 = xtmp;
+    }
+
+    /*
+     * Get clipping boundary and
+     * check visibility of hline 
+     */
+    left = dst->clip_rect.x;
+    if (x2<left) {
+     return(0);
+    }
+    right = dst->clip_rect.x + dst->clip_rect.w - 1;
+    if (x1>right) {
+     return(0);
+    }
+    top = dst->clip_rect.y;
+    bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
+    if ((y<top) || (y>bottom)) {
+     return (0);
+    }
+
+    /*
+     * Clip x 
+     */
+    if (x1 < left) {
+	x1 = left;
+    }
+    if (x2 > right) {
+	x2 = right;
+    }
+
+    /*
+     * Calculate width 
+     */
+    w = x2 - x1;
+
+    /*
+     * Alpha check 
+     */
+    if ((color & 255) == 255) {
+
+	/*
+	 * No alpha-blending required 
+	 */
+
+	/*
+	 * Setup color 
+	 */
+	colorptr = (Uint8 *) & color;
+	if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+	    color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
+	} else {
+	    color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
+	}
+
+	/*
+	 * Lock surface 
+	 */
+	SDL_LockSurface(dst);
+
+	/*
+	 * More variable setup 
+	 */
+	dx = w;
+	pixx = dst->format->BytesPerPixel;
+	pixy = dst->pitch;
+	pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
+
+	/*
+	 * Draw 
+	 */
+	switch (dst->format->BytesPerPixel) {
+	case 1:
+	    memset(pixel, color, dx+1);
+	    break;
+	case 2:
+	    pixellast = pixel + dx + dx;
+	    for (; pixel <= pixellast; pixel += pixx) {
+		*(Uint16 *) pixel = color;
+	    }
+	    break;
+	case 3:
+	    pixellast = pixel + dx + dx + dx;
+	    for (; pixel <= pixellast; pixel += pixx) {
+		if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+		    pixel[0] = (color >> 16) & 0xff;
+		    pixel[1] = (color >> 8) & 0xff;
+		    pixel[2] = color & 0xff;
+		} else {
+		    pixel[0] = color & 0xff;
+		    pixel[1] = (color >> 8) & 0xff;
+		    pixel[2] = (color >> 16) & 0xff;
+		}
+	    }
+	    break;
+	default:		/* case 4 */
+	    dx = dx + dx;
+	    pixellast = pixel + dx + dx;
+	    for (; pixel <= pixellast; pixel += pixx) {
+		*(Uint32 *) pixel = color;
+	    }
+	    break;
+	}
+
+	/*
+	 * Unlock surface 
+	 */
+	SDL_UnlockSurface(dst);
+
+	/*
+	 * Set result code 
+	 */
+	result = 0;
+
+    } else {
+
+	/*
+	 * Alpha blending blit 
+	 */
+
+	result = HLineAlpha(dst, x1, x1 + w, y, color);
+
+    }
+
+    return (result);
+}
+
+int hlineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    /*
+     * Draw 
+     */
+    return (hlineColor(dst, x1, x2, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
+}
+
+/* ----- Vertical line */
+
+int vlineColor(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
+{
+    Sint16 left, right, top, bottom;
+    Uint8 *pixel, *pixellast;
+    int dy;
+    int pixx, pixy;
+    Sint16 h;
+    Sint16 ytmp;
+    int result = -1;
+    Uint8 *colorptr;
+
+    /*
+     * Check visibility of clipping rectangle
+     */
+    if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
+     return(0);
+    }
+    
+    /*
+     * Swap y1, y2 if required to ensure y1<=y2
+     */
+    if (y1 > y2) {
+	ytmp = y1;
+	y1 = y2;
+	y2 = ytmp;
+    }
+
+    /*
+     * Get clipping boundary and
+     * check visibility of vline 
+     */
+    left = dst->clip_rect.x;
+    right = dst->clip_rect.x + dst->clip_rect.w - 1;
+    if ((x<left) || (x>right)) {
+     return (0);
+    }    
+    top = dst->clip_rect.y;
+    if (y2<top) {
+     return(0);
+    }
+    bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
+    if (y1>bottom) {
+     return(0);
+    }
+
+    /*
+     * Clip x 
+     */
+    if (y1 < top) {
+	y1 = top;
+    }
+    if (y2 > bottom) {
+	y2 = bottom;
+    }
+
+    /*
+     * Calculate height
+     */
+    h = y2 - y1;
+
+    /*
+     * Alpha check 
+     */
+    if ((color & 255) == 255) {
+
+	/*
+	 * No alpha-blending required 
+	 */
+
+	/*
+	 * Setup color 
+	 */
+	colorptr = (Uint8 *) & color;
+	if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+	    color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
+	} else {
+	    color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
+	}
+
+	/*
+	 * Lock surface 
+	 */
+	SDL_LockSurface(dst);
+
+	/*
+	 * More variable setup 
+	 */
+	dy = h;
+	pixx = dst->format->BytesPerPixel;
+	pixy = dst->pitch;
+	pixel = ((Uint8 *) dst->pixels) + pixx * (int) x + pixy * (int) y1;
+	pixellast = pixel + pixy * dy;
+
+	/*
+	 * Draw 
+	 */
+	switch (dst->format->BytesPerPixel) {
+	case 1:
+	    for (; pixel <= pixellast; pixel += pixy) {
+		*(Uint8 *) pixel = color;
+	    }
+	    break;
+	case 2:
+	    for (; pixel <= pixellast; pixel += pixy) {
+		*(Uint16 *) pixel = color;
+	    }
+	    break;
+	case 3:
+	    for (; pixel <= pixellast; pixel += pixy) {
+		if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+		    pixel[0] = (color >> 16) & 0xff;
+		    pixel[1] = (color >> 8) & 0xff;
+		    pixel[2] = color & 0xff;
+		} else {
+		    pixel[0] = color & 0xff;
+		    pixel[1] = (color >> 8) & 0xff;
+		    pixel[2] = (color >> 16) & 0xff;
+		}
+	    }
+	    break;
+	default:		/* case 4 */
+	    for (; pixel <= pixellast; pixel += pixy) {
+		*(Uint32 *) pixel = color;
+	    }
+	    break;
+	}
+
+	/*
+	 * Unlock surface 
+	 */
+	SDL_UnlockSurface(dst);
+
+	/*
+	 * Set result code 
+	 */
+	result = 0;
+
+    } else {
+
+	/*
+	 * Alpha blending blit 
+	 */
+
+	result = VLineAlpha(dst, x, y1, y1 + h, color);
+
+    }
+
+    return (result);
+}
+
+int vlineRGBA(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    /*
+     * Draw 
+     */
+    return (vlineColor(dst, x, y1, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
+}
+
+/* ----- Rectangle */
+
+int rectangleColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
+{
+    int result;
+    Sint16 w, h, xtmp, ytmp;
+
+    /*
+     * Check visibility of clipping rectangle
+     */
+    if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
+     return(0);
+    }
+
+    /*
+     * Swap x1, x2 if required 
+     */
+    if (x1 > x2) {
+	xtmp = x1;
+	x1 = x2;
+	x2 = xtmp;
+    }
+
+    /*
+     * Swap y1, y2 if required 
+     */
+    if (y1 > y2) {
+	ytmp = y1;
+	y1 = y2;
+	y2 = ytmp;
+    }
+
+    /*
+     * Calculate width&height 
+     */
+    w = x2 - x1;
+    h = y2 - y1;
+
+    /*
+     * Sanity check 
+     */
+    if ((w < 0) || (h < 0)) {
+	return (0);
+    }
+
+    /*
+     * Test for special cases of straight lines or single point 
+     */
+    if (x1 == x2) {
+	if (y1 == y2) {
+	    return (pixelColor(dst, x1, y1, color));
+	} else {
+	    return (vlineColor(dst, x1, y1, y2, color));
+	}
+    } else {
+	if (y1 == y2) {
+	    return (hlineColor(dst, x1, x2, y1, color));
+	}
+    }
+
+    /*
+     * Draw rectangle 
+     */
+    result = 0;
+    result |= hlineColor(dst, x1, x2, y1, color);
+    result |= hlineColor(dst, x1, x2, y2, color);
+    y1 += 1;
+    y2 -= 1;
+    if (y1<=y2) {
+     result |= vlineColor(dst, x1, y1, y2, color);
+     result |= vlineColor(dst, x2, y1, y2, color);
+    }
+    return (result);
+
+}
+
+int rectangleRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    /*
+     * Draw 
+     */
+    return (rectangleColor
+	    (dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
+}
+
+/* --------- Clipping routines for line */
+
+/* Clipping based heavily on code from                       */
+/* http://www.ncsa.uiuc.edu/Vis/Graphics/src/clipCohSuth.c   */
+
+#define CLIP_LEFT_EDGE   0x1
+#define CLIP_RIGHT_EDGE  0x2
+#define CLIP_BOTTOM_EDGE 0x4
+#define CLIP_TOP_EDGE    0x8
+#define CLIP_INSIDE(a)   (!a)
+#define CLIP_REJECT(a,b) (a&b)
+#define CLIP_ACCEPT(a,b) (!(a|b))
+
+static int clipEncode(Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom)
+{
+    int code = 0;
+
+    if (x < left) {
+	code |= CLIP_LEFT_EDGE;
+    } else if (x > right) {
+	code |= CLIP_RIGHT_EDGE;
+    }
+    if (y < top) {
+	code |= CLIP_TOP_EDGE;
+    } else if (y > bottom) {
+	code |= CLIP_BOTTOM_EDGE;
+    }
+    return code;
+}
+
+static int clipLine(SDL_Surface * dst, Sint16 * x1, Sint16 * y1, Sint16 * x2, Sint16 * y2)
+{
+    Sint16 left, right, top, bottom;
+    int code1, code2;
+    int draw = 0;
+    Sint16 swaptmp;
+    float m;
+
+    /*
+     * Get clipping boundary 
+     */
+    left = dst->clip_rect.x;
+    right = dst->clip_rect.x + dst->clip_rect.w - 1;
+    top = dst->clip_rect.y;
+    bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
+
+    while (1) {
+	code1 = clipEncode(*x1, *y1, left, top, right, bottom);
+	code2 = clipEncode(*x2, *y2, left, top, right, bottom);
+	if (CLIP_ACCEPT(code1, code2)) {
+	    draw = 1;
+	    break;
+	} else if (CLIP_REJECT(code1, code2))
+	    break;
+	else {
+	    if (CLIP_INSIDE(code1)) {
+		swaptmp = *x2;
+		*x2 = *x1;
+		*x1 = swaptmp;
+		swaptmp = *y2;
+		*y2 = *y1;
+		*y1 = swaptmp;
+		swaptmp = code2;
+		code2 = code1;
+		code1 = swaptmp;
+	    }
+	    if (*x2 != *x1) {
+		m = (*y2 - *y1) / (float) (*x2 - *x1);
+	    } else {
+		m = 1.0f;
+	    }
+	    if (code1 & CLIP_LEFT_EDGE) {
+		*y1 += (Sint16) ((left - *x1) * m);
+		*x1 = left;
+	    } else if (code1 & CLIP_RIGHT_EDGE) {
+		*y1 += (Sint16) ((right - *x1) * m);
+		*x1 = right;
+	    } else if (code1 & CLIP_BOTTOM_EDGE) {
+		if (*x2 != *x1) {
+		    *x1 += (Sint16) ((bottom - *y1) / m);
+		}
+		*y1 = bottom;
+	    } else if (code1 & CLIP_TOP_EDGE) {
+		if (*x2 != *x1) {
+		    *x1 += (Sint16) ((top - *y1) / m);
+		}
+		*y1 = top;
+	    }
+	}
+    }
+
+    return draw;
+}
+
+/* ----- Filled rectangle (Box) */
+
+int boxColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
+{
+    Sint16 left, right, top, bottom;
+    Uint8 *pixel, *pixellast;
+    int x, dx;
+    int dy;
+    int pixx, pixy;
+    Sint16 w, h, tmp;
+    int result;
+    Uint8 *colorptr;
+
+    /*
+     * Check visibility of clipping rectangle
+     */
+    if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
+     return(0);
+    }
+
+    /*
+     * Order coordinates to ensure that
+     * x1<=x2 and y1<=y2 
+     */
+    if (x1 > x2) {
+	tmp = x1;
+	x1 = x2;
+	x2 = tmp;
+    }
+    if (y1 > y2) {
+	tmp = y1;
+	y1 = y2;
+	y2 = tmp;
+    }
+
+    /* 
+     * Get clipping boundary and 
+     * check visibility 
+     */
+    left = dst->clip_rect.x;
+    if (x2<left) {
+     return(0);
+    }
+    right = dst->clip_rect.x + dst->clip_rect.w - 1;
+    if (x1>right) {
+     return(0);
+    }
+    top = dst->clip_rect.y;
+    if (y2<top) {
+     return(0);
+    }
+    bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
+    if (y1>bottom) {
+     return(0);
+    }
+     
+    /* Clip all points */
+    if (x1<left) { 
+     x1=left; 
+    } else if (x1>right) {
+     x1=right;
+    }
+    if (x2<left) { 
+     x2=left; 
+    } else if (x2>right) {
+     x2=right;
+    }
+    if (y1<top) { 
+     y1=top; 
+    } else if (y1>bottom) {
+     y1=bottom;
+    }
+    if (y2<top) { 
+     y2=top; 
+    } else if (y2>bottom) {
+     y2=bottom;
+    }
+
+    /*
+     * Test for special cases of straight line or single point 
+     */
+    if (x1 == x2) {
+	if (y1 == y2) {
+	    return (pixelColor(dst, x1, y1, color));
+	} else { 
+	    return (vlineColor(dst, x1, y1, y2, color));
+	}
+    }
+    if (y1 == y2) {
+	return (hlineColor(dst, x1, x2, y1, color));
+    }
+
+    /*
+     * Calculate width&height 
+     */
+    w = x2 - x1;
+    h = y2 - y1;
+
+    /*
+     * Alpha check 
+     */
+    if ((color & 255) == 255) {
+
+	/*
+	 * No alpha-blending required 
+	 */
+
+	/*
+	 * Setup color 
+	 */
+	colorptr = (Uint8 *) & color;
+	if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+	    color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
+	} else {
+	    color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
+	}
+
+	/*
+	 * Lock surface 
+	 */
+	SDL_LockSurface(dst);
+
+	/*
+	 * More variable setup 
+	 */
+	dx = w;
+	dy = h;
+	pixx = dst->format->BytesPerPixel;
+	pixy = dst->pitch;
+	pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1;
+	pixellast = pixel + pixx * dx + pixy * dy;
+	dx++;
+	
+	/*
+	 * Draw 
+	 */
+	switch (dst->format->BytesPerPixel) {
+	case 1:
+	    for (; pixel <= pixellast; pixel += pixy) {
+		memset(pixel, (Uint8) color, dx);
+	    }
+	    break;
+	case 2:
+	    pixy -= (pixx * dx);
+	    for (; pixel <= pixellast; pixel += pixy) {
+		for (x = 0; x < dx; x++) {
+		    *(Uint16*) pixel = color;
+		    pixel += pixx;
+		}
+	    }
+	    break;
+	case 3:
+	    pixy -= (pixx * dx);
+	    for (; pixel <= pixellast; pixel += pixy) {
+		for (x = 0; x < dx; x++) {
+		    if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+			pixel[0] = (color >> 16) & 0xff;
+			pixel[1] = (color >> 8) & 0xff;
+			pixel[2] = color & 0xff;
+		    } else {
+			pixel[0] = color & 0xff;
+			pixel[1] = (color >> 8) & 0xff;
+			pixel[2] = (color >> 16) & 0xff;
+		    }
+		    pixel += pixx;
+		}
+	    }
+	    break;
+	default:		/* case 4 */
+	    pixy -= (pixx * dx);
+	    for (; pixel <= pixellast; pixel += pixy) {
+		for (x = 0; x < dx; x++) {
+		    *(Uint32 *) pixel = color;
+		    pixel += pixx;
+		}
+	    }
+	    break;
+	}
+
+	/*
+	 * Unlock surface 
+	 */
+	SDL_UnlockSurface(dst);
+
+	result = 0;
+
+    } else {
+
+	result = filledRectAlpha(dst, x1, y1, x1 + w, y1 + h, color);
+
+    }
+
+    return (result);
+}
+
+int boxRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    /*
+     * Draw 
+     */
+    return (boxColor(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
+}
+
+/* ----- Line */
+
+/* Non-alpha line drawing code adapted from routine          */
+/* by Pete Shinners, pete@shinners.org                       */
+/* Originally from pygame, http://pygame.seul.org            */
+
+#define ABS(a) (((a)<0) ? -(a) : (a))
+
+int lineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
+{
+    int pixx, pixy;
+    int x, y;
+    int dx, dy;
+    int ax, ay;
+    int sx, sy;
+    int swaptmp;
+    Uint8 *pixel;
+    Uint8 *colorptr;
+
+    /*
+     * Clip line and test if we have to draw 
+     */
+    if (!(clipLine(dst, &x1, &y1, &x2, &y2))) {
+	return (0);
+    }
+
+    /*
+     * Test for special cases of straight lines or single point 
+     */
+    if (x1 == x2) {
+	if (y1 < y2) {
+	    return (vlineColor(dst, x1, y1, y2, color));
+	} else if (y1 > y2) {
+	    return (vlineColor(dst, x1, y2, y1, color));
+	} else {
+	    return (pixelColor(dst, x1, y1, color));
+	}
+    }
+    if (y1 == y2) {
+	if (x1 < x2) {
+	    return (hlineColor(dst, x1, x2, y1, color));
+	} else if (x1 > x2) {
+	    return (hlineColor(dst, x2, x1, y1, color));
+	}
+    }
+
+    /*
+     * Variable setup 
+     */
+    dx = x2 - x1;
+    dy = y2 - y1;
+    sx = (dx >= 0) ? 1 : -1;
+    sy = (dy >= 0) ? 1 : -1;
+
+    /* Lock surface */
+    if (SDL_MUSTLOCK(dst)) {
+	if (SDL_LockSurface(dst) < 0) {
+	    return (-1);
+	}
+    }
+
+    /*
+     * Check for alpha blending 
+     */
+    if ((color & 255) == 255) {
+
+	/*
+	 * No alpha blending - use fast pixel routines 
+	 */
+
+	/*
+	 * Setup color 
+	 */
+	colorptr = (Uint8 *) & color;
+	if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+	    color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
+	} else {
+	    color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
+	}
+
+	/*
+	 * More variable setup 
+	 */
+	dx = sx * dx + 1;
+	dy = sy * dy + 1;
+	pixx = dst->format->BytesPerPixel;
+	pixy = dst->pitch;
+	pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1;
+	pixx *= sx;
+	pixy *= sy;
+	if (dx < dy) {
+	    swaptmp = dx;
+	    dx = dy;
+	    dy = swaptmp;
+	    swaptmp = pixx;
+	    pixx = pixy;
+	    pixy = swaptmp;
+	}
+
+	/*
+	 * Draw 
+	 */
+	x = 0;
+	y = 0;
+	switch (dst->format->BytesPerPixel) {
+	case 1:
+	    for (; x < dx; x++, pixel += pixx) {
+		*pixel = color;
+		y += dy;
+		if (y >= dx) {
+		    y -= dx;
+		    pixel += pixy;
+		}
+	    }
+	    break;
+	case 2:
+	    for (; x < dx; x++, pixel += pixx) {
+		*(Uint16 *) pixel = color;
+		y += dy;
+		if (y >= dx) {
+		    y -= dx;
+		    pixel += pixy;
+		}
+	    }
+	    break;
+	case 3:
+	    for (; x < dx; x++, pixel += pixx) {
+		if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+		    pixel[0] = (color >> 16) & 0xff;
+		    pixel[1] = (color >> 8) & 0xff;
+		    pixel[2] = color & 0xff;
+		} else {
+		    pixel[0] = color & 0xff;
+		    pixel[1] = (color >> 8) & 0xff;
+		    pixel[2] = (color >> 16) & 0xff;
+		}
+		y += dy;
+		if (y >= dx) {
+		    y -= dx;
+		    pixel += pixy;
+		}
+	    }
+	    break;
+	default:		/* case 4 */
+	    for (; x < dx; x++, pixel += pixx) {
+		*(Uint32 *) pixel = color;
+		y += dy;
+		if (y >= dx) {
+		    y -= dx;
+		    pixel += pixy;
+		}
+	    }
+	    break;
+	}
+
+    } else {
+
+	/*
+	 * Alpha blending required - use single-pixel blits 
+	 */
+
+	ax = ABS(dx) << 1;
+	ay = ABS(dy) << 1;
+	x = x1;
+	y = y1;
+	if (ax > ay) {
+	    int d = ay - (ax >> 1);
+
+	    while (x != x2) {
+		pixelColorNolock (dst, x, y, color);
+		if (d > 0 || (d == 0 && sx == 1)) {
+		    y += sy;
+		    d -= ax;
+		}
+		x += sx;
+		d += ay;
+	    }
+	} else {
+	    int d = ax - (ay >> 1);
+
+	    while (y != y2) {
+		pixelColorNolock (dst, x, y, color);
+		if (d > 0 || ((d == 0) && (sy == 1))) {
+		    x += sx;
+		    d -= ay;
+		}
+		y += sy;
+		d += ax;
+	    }
+	}
+	pixelColorNolock (dst, x, y, color);
+
+    }
+
+    /* Unlock surface */
+    if (SDL_MUSTLOCK(dst)) {
+	SDL_UnlockSurface(dst);
+    }
+
+    return (0);
+}
+
+int lineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    /*
+     * Draw 
+     */
+    return (lineColor(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
+}
+
+/* AA Line */
+
+#define AAlevels 256
+#define AAbits 8
+
+/* 
+
+This implementation of the Wu antialiasing code is based on Mike Abrash's
+DDJ article which was reprinted as Chapter 42 of his Graphics Programming
+Black Book, but has been optimized to work with SDL and utilizes 32-bit
+fixed-point arithmetic. (A. Schiffler).
+
+*/
+
+int aalineColorInt(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, int draw_endpoint)
+{
+    Sint32 xx0, yy0, xx1, yy1;
+    int result;
+    Uint32 intshift, erracc, erradj;
+    Uint32 erracctmp, wgt, wgtcompmask;
+    int dx, dy, tmp, xdir, y0p1, x0pxdir;
+
+    /*
+     * Check visibility of clipping rectangle
+     */
+    if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
+     return(0);
+    }
+
+    /*
+     * Clip line and test if we have to draw 
+     */
+    if (!(clipLine(dst, &x1, &y1, &x2, &y2))) {
+	return (0);
+    }
+
+    /*
+     * Keep on working with 32bit numbers 
+     */
+    xx0 = x1;
+    yy0 = y1;
+    xx1 = x2;
+    yy1 = y2;
+
+    /*
+     * Reorder points if required 
+     */
+    if (yy0 > yy1) {
+	tmp = yy0;
+	yy0 = yy1;
+	yy1 = tmp;
+	tmp = xx0;
+	xx0 = xx1;
+	xx1 = tmp;
+    }
+
+    /*
+     * Calculate distance 
+     */
+    dx = xx1 - xx0;
+    dy = yy1 - yy0;
+
+    /*
+     * Adjust for negative dx and set xdir 
+     */
+    if (dx >= 0) {
+	xdir = 1;
+    } else {
+	xdir = -1;
+	dx = (-dx);
+    }
+
+    /*
+     * Check for special cases 
+     */
+    if (dx == 0) {
+	/*
+	 * Vertical line 
+	 */
+	return (vlineColor(dst, x1, y1, y2, color));
+    } else if (dy == 0) {
+	/*
+	 * Horizontal line 
+	 */
+	return (hlineColor(dst, x1, x2, y1, color));
+    } else if (dx == dy) {
+	/*
+	 * Diagonal line 
+	 */
+	return (lineColor(dst, x1, y1, x2, y2, color));
+    }
+
+    /*
+     * Line is not horizontal, vertical or diagonal 
+     */
+    result = 0;
+
+    /*
+     * Zero accumulator 
+     */
+    erracc = 0;
+
+    /*
+     * # of bits by which to shift erracc to get intensity level 
+     */
+    intshift = 32 - AAbits;
+    /*
+     * Mask used to flip all bits in an intensity weighting 
+     */
+    wgtcompmask = AAlevels - 1;
+
+    /* Lock surface */
+    if (SDL_MUSTLOCK(dst)) {
+	if (SDL_LockSurface(dst) < 0) {
+	    return (-1);
+	}
+    }
+
+    /*
+     * Draw the initial pixel in the foreground color 
+     */
+    result |= pixelColorNolock(dst, x1, y1, color);
+
+    /*
+     * x-major or y-major? 
+     */
+    if (dy > dx) {
+
+	/*
+	 * y-major.  Calculate 16-bit fixed point fractional part of a pixel that
+	 * X advances every time Y advances 1 pixel, truncating the result so that
+	 * we won't overrun the endpoint along the X axis 
+	 */
+	/*
+	 * Not-so-portable version: erradj = ((Uint64)dx << 32) / (Uint64)dy; 
+	 */
+	erradj = ((dx << 16) / dy) << 16;
+
+	/*
+	 * draw all pixels other than the first and last 
+	 */
+	x0pxdir = xx0 + xdir;
+	while (--dy) {
+	    erracctmp = erracc;
+	    erracc += erradj;
+	    if (erracc <= erracctmp) {
+		/*
+		 * rollover in error accumulator, x coord advances 
+		 */
+		xx0 = x0pxdir;
+		x0pxdir += xdir;
+	    }
+	    yy0++;		/* y-major so always advance Y */
+
+	    /*
+	     * the AAbits most significant bits of erracc give us the intensity
+	     * weighting for this pixel, and the complement of the weighting for
+	     * the paired pixel. 
+	     */
+	    wgt = (erracc >> intshift) & 255;
+	    result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt);
+	    result |= pixelColorWeightNolock (dst, x0pxdir, yy0, color, wgt);
+	}
+
+    } else {
+
+	/*
+	 * x-major line.  Calculate 16-bit fixed-point fractional part of a pixel
+	 * that Y advances each time X advances 1 pixel, truncating the result so
+	 * that we won't overrun the endpoint along the X axis. 
+	 */
+	/*
+	 * Not-so-portable version: erradj = ((Uint64)dy << 32) / (Uint64)dx; 
+	 */
+	erradj = ((dy << 16) / dx) << 16;
+
+	/*
+	 * draw all pixels other than the first and last 
+	 */
+	y0p1 = yy0 + 1;
+	while (--dx) {
+
+	    erracctmp = erracc;
+	    erracc += erradj;
+	    if (erracc <= erracctmp) {
+		/*
+		 * Accumulator turned over, advance y 
+		 */
+		yy0 = y0p1;
+		y0p1++;
+	    }
+	    xx0 += xdir;	/* x-major so always advance X */
+	    /*
+	     * the AAbits most significant bits of erracc give us the intensity
+	     * weighting for this pixel, and the complement of the weighting for
+	     * the paired pixel. 
+	     */
+	    wgt = (erracc >> intshift) & 255;
+	    result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt);
+	    result |= pixelColorWeightNolock (dst, xx0, y0p1, color, wgt);
+	}
+    }
+
+    /*
+     * Do we have to draw the endpoint 
+     */
+    if (draw_endpoint) {
+	/*
+	 * Draw final pixel, always exactly intersected by the line and doesn't
+	 * need to be weighted. 
+	 */
+	result |= pixelColorNolock (dst, x2, y2, color);
+    }
+
+    /* Unlock surface */
+    if (SDL_MUSTLOCK(dst)) {
+	SDL_UnlockSurface(dst);
+    }
+
+    return (result);
+}
+
+int aalineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
+{
+    return (aalineColorInt(dst, x1, y1, x2, y2, color, 1));
+}
+
+int aalineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    return (aalineColorInt
+	    (dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, 1));
+}
+
+
+/* ----- Circle */
+
+/* Note: Based on algorithm from sge library, modified by A. Schiffler */
+/* with multiple pixel-draw removal and other minor speedup changes.   */
+
+int circleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
+{
+    Sint16 left, right, top, bottom;
+    int result;
+    Sint16 x1, y1, x2, y2;
+    Sint16 cx = 0;
+    Sint16 cy = r;
+    Sint16 ocx = (Sint16) 0xffff;
+    Sint16 ocy = (Sint16) 0xffff;
+    Sint16 df = 1 - r;
+    Sint16 d_e = 3;
+    Sint16 d_se = -2 * r + 5;
+    Sint16 xpcx, xmcx, xpcy, xmcy;
+    Sint16 ypcy, ymcy, ypcx, ymcx;
+    Uint8 *colorptr;
+
+    /*
+     * Check visibility of clipping rectangle
+     */
+    if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
+     return(0);
+    }
+
+    /*
+     * Sanity check radius 
+     */
+    if (r < 0) {
+	return (-1);
+    }
+
+    /*
+     * Special case for r=0 - draw a point 
+     */
+    if (r == 0) {
+	return (pixelColor(dst, x, y, color));
+    }
+
+    /*
+     * Get circle and clipping boundary and 
+     * test if bounding box of circle is visible 
+     */
+    x2 = x + r;
+    left = dst->clip_rect.x;
+    if (x2<left) {
+     return(0);
+    } 
+    x1 = x - r;
+    right = dst->clip_rect.x + dst->clip_rect.w - 1;
+    if (x1>right) {
+     return(0);
+    } 
+    y2 = y + r;
+    top = dst->clip_rect.y;
+    if (y2<top) {
+     return(0);
+    } 
+    y1 = y - r;
+    bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
+    if (y1>bottom) {
+     return(0);
+    } 
+
+    /*
+     * Draw circle 
+     */
+    result = 0;
+
+    /* Lock surface */
+    if (SDL_MUSTLOCK(dst)) {
+	if (SDL_LockSurface(dst) < 0) {
+	    return (-1);
+	}
+    }
+
+    /*
+     * Alpha Check 
+     */
+    if ((color & 255) == 255) {
+
+	/*
+	 * No Alpha - direct memory writes 
+	 */
+
+	/*
+	 * Setup color 
+	 */
+	colorptr = (Uint8 *) & color;
+	if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+	    color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
+	} else {
+	    color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
+	}
+