--- Begin Message ---
Hi,

I patched SDL-gfx to support vertical and horizontal flipping. I tryed
to keep old API to don't brake compatibility and do a patch as small as
possible :-).

You may add some #define (or change API version ?) to aware programs
that the new API support rotozoom and zoomSurface with flipping.

To use flipping, just use negative zoom ;-) E.g. zoom=(-1, 1) means
vertical flipping.

TODO :
- Test it :-(
- Write smooth version
- Optimize it ??? (a if statement in double for isn't the fastest way to
do a flipping :-()

I tested :
- zoomSurfaceRGBA without smooth with 32 bits surface (RGBA)
- transformSurfaceRGBA without smooth with 32 bits surface (RGBA)

Bye, Haypo
--- SDL_gfx-2.0.12/SDL_rotozoom.h	2004-06-01 18:20:57.000000000 +0200
+++ SDL_gfx-haypo/SDL_rotozoom.h	2004-10-03 04:16:23.000000000 +0200
@@ -67,12 +67,18 @@
 
     DLLINTERFACE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth);
 
+    DLLINTERFACE SDL_Surface *rotozoomSurfaceXY
+    (SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth);
 
 /* Returns the size of the target surface for a rotozoomSurface() call */
 
     DLLINTERFACE void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth,
 					  int *dstheight);
 
+    DLLINTERFACE void rotozoomSurfaceSizeXY
+    (int width, int height, double angle, double zoomx, double zoomy, 
+     int *dstwidth, int *dstheight);
+
 /* 
  
  zoomSurface()
--- SDL_gfx-2.0.12/SDL_rotozoom.c	2004-06-01 18:20:57.000000000 +0200
+++ SDL_gfx-haypo/SDL_rotozoom.c	2004-10-03 04:38:33.000000000 +0200
@@ -25,12 +25,12 @@
  
 */
 
-int zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int smooth)
+int zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth)
 {
     int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep;
     tColorRGBA *c00, *c01, *c10, *c11;
     tColorRGBA *sp, *csp, *dp;
-    int sgap, dgap;
+    int dgap;
 
     /*
      * Variable setup 
@@ -63,6 +63,12 @@
     /*
      * Precalculate row increments 
      */
+    sp = csp = (tColorRGBA *) src->pixels;
+    dp = (tColorRGBA *) dst->pixels;
+
+    if (flipx) csp += (src->w-1);
+    if (flipy) csp  = (tColorRGBA*)( (Uint8*)csp + src->pitch*(src->h-1) );
+
     csx = 0;
     csax = sax;
     for (x = 0; x <= dst->w; x++) {
@@ -80,12 +86,6 @@
 	csy += sy;
     }
 
-    /*
-     * Pointer setup 
-     */
-    sp = csp = (tColorRGBA *) src->pixels;
-    dp = (tColorRGBA *) dst->pixels;
-    sgap = src->pitch - src->w * 4;
     dgap = dst->pitch - dst->w * 4;
 
     /*
@@ -176,7 +176,9 @@
 		 * Advance source pointers 
 		 */
 		csax++;
-		sp += (*csax >> 16);
+		sstep = (*csax >> 16);
+		if (flipx) sstep = -sstep;
+		sp += sstep;
 		/*
 		 * Advance destination pointer 
 		 */
@@ -186,7 +188,10 @@
 	     * Advance source pointer 
 	     */
 	    csay++;
-	    csp = (tColorRGBA *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
+	    sstep = (*csay >> 16) * src->pitch;
+	    if (flipy) sstep = -sstep;
+	    csp = (tColorRGBA *) ((Uint8 *) csp + sstep);
+
 	    /*
 	     * Advance destination pointers 
 	     */
@@ -212,7 +217,7 @@
  
 */
 
-int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst)
+int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy)
 {
     Uint32 x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy;
     Uint8 *sp, *dp, *csp;
@@ -327,7 +332,7 @@
  
 */
 
-void transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int smooth)
+void transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth)
 {
     int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh;
     tColorRGBA c00, c01, c10, c11;
@@ -460,6 +465,8 @@
 	    for (x = 0; x < dst->w; x++) {
 		dx = (short) (sdx >> 16);
 		dy = (short) (sdy >> 16);
+		if (flipx) dx = (src->w-1)-dx;
+		if (flipy) dy = (src->h-1)-dy;
 		if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
 		    sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
 		    sp += dx;
@@ -542,7 +549,7 @@
 
 /* Local rotozoom-size function with trig result return */
 
-void rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight,
+void rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight, 
 			     double *canglezoom, double *sanglezoom)
 {
     double x, y, cx, cy, sx, sy;
@@ -555,8 +562,8 @@
     radangle = angle * (M_PI / 180.0);
     *sanglezoom = sin(radangle);
     *canglezoom = cos(radangle);
-    *sanglezoom *= zoom;
-    *canglezoom *= zoom;
+    *sanglezoom *= zoomx;
+    *canglezoom *= zoomx;
     x = width / 2;
     y = height / 2;
     cx = *canglezoom * x;
@@ -574,18 +581,33 @@
 
 /* Publically available rotozoom-size function */
 
-void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight)
+void rotozoomSurfaceSizeXY(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight)
 {
     double dummy_sanglezoom, dummy_canglezoom;
 
-    rotozoomSurfaceSizeTrig(width, height, angle, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
+    rotozoomSurfaceSizeTrig(width, height, angle, zoomx, zoomy, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
 }
 
+/* Publically available rotozoom-size function */
+
+void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight)
+{
+    double dummy_sanglezoom, dummy_canglezoom;
+
+    rotozoomSurfaceSizeTrig(width, height, angle, zoom, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
+}
 
 /* Publically available rotozoom function */
 
 SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth)
 {
+  return rotozoomSurfaceXY(src, angle, zoom, zoom, smooth);
+}
+
+/* Publically available rotozoom function */
+
+SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth)
+{
     SDL_Surface *rz_src;
     SDL_Surface *rz_dst;
     double zoominv;
@@ -594,6 +616,7 @@
     double x, y, cx, cy, sx, sy;
     int is32bit;
     int i, src_converted;
+    int flipx,flipy;
 
     /*
      * Sanity check 
@@ -625,10 +648,13 @@
     /*
      * Sanity check zoom factor 
      */
-    if (zoom < VALUE_LIMIT) {
-	zoom = VALUE_LIMIT;
-    }
-    zoominv = 65536.0 / (zoom * zoom);
+    flipx = (zoomx<0);
+    if (flipx) zoomx=-zoomx;
+    flipy = (zoomy<0);
+    if (flipy) zoomy=-zoomy;
+    if (zoomx < VALUE_LIMIT) zoomx = VALUE_LIMIT;
+    if (zoomy < VALUE_LIMIT) zoomy = VALUE_LIMIT;
+    zoominv = 65536.0 / (zoomx * zoomx);
 
     /*
      * Check if we have a rotozoom or just a zoom 
@@ -643,7 +669,7 @@
 	 */
 
 	/* Determine target size */
-	rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoom, &dstwidth, &dstheight, &canglezoom, &sanglezoom);
+	rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoomx, zoomy, &dstwidth, &dstheight, &canglezoom, &sanglezoom);
 
 	/*
 	 * Calculate target factors from sin/cos and zoom 
@@ -688,7 +714,9 @@
 	     * Call the 32bit transformation routine to do the rotation (using alpha) 
 	     */
 	    transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
-				 (int) (sanglezoominv), (int) (canglezoominv), smooth);
+				 (int) (sanglezoominv), (int) (canglezoominv), 
+				 flipx, flipy,
+				 smooth);
 	    /*
 	     * Turn on source-alpha support 
 	     */
@@ -725,7 +753,7 @@
 	/*
 	 * Calculate target size
 	 */
-	zoomSurfaceSize(rz_src->w, rz_src->h, zoom, zoom, &dstwidth, &dstheight);
+	zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
 
 	/*
 	 * Alloc space to completely contain the zoomed surface 
@@ -757,7 +785,7 @@
 	    /*
 	     * Call the 32bit transformation routine to do the zooming (using alpha) 
 	     */
-	    zoomSurfaceRGBA(rz_src, rz_dst, smooth);
+	    zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
 	    /*
 	     * Turn on source-alpha support 
 	     */
@@ -773,7 +801,7 @@
 	    /*
 	     * Call the 8bit transformation routine to do the zooming 
 	     */
-	    zoomSurfaceY(rz_src, rz_dst);
+	    zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
 	    SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
 	}
 	/*
@@ -840,6 +868,7 @@
     int dstwidth, dstheight;
     int is32bit;
     int i, src_converted;
+    int flipx, flipy;
 
     /*
      * Sanity check 
@@ -868,6 +897,11 @@
 	is32bit = 1;
     }
 
+    flipx = (zoomx<0);
+    if (flipx) zoomx = -zoomx;
+    flipy = (zoomy<0);
+    if (flipy) zoomy = -zoomy;
+
     /* Get size if target */
     zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
 
@@ -901,7 +935,7 @@
 	/*
 	 * Call the 32bit transformation routine to do the zooming (using alpha) 
 	 */
-	zoomSurfaceRGBA(rz_src, rz_dst, smooth);
+	zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
 	/*
 	 * Turn on source-alpha support 
 	 */
@@ -917,7 +951,7 @@
 	/*
 	 * Call the 8bit transformation routine to do the zooming 
 	 */
-	zoomSurfaceY(rz_src, rz_dst);
+	zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
 	SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
     }
     /*

--- End Message ---

Répondre à