/* * call-seq: * flip(horz, vert) -> Surface * * Flips the source surface horizontally (if +horz+ is true), vertically * (if +vert+ is true), or both (if both are true). This operation is * non-destructive; the original image can be perfectly reconstructed by * flipping the resultant image again. * * This operation does NOT require SDL_gfx. * * A similar effect can (supposedly) be achieved by giving X or Y zoom * factors of -1 to #rotozoom (only if compiled with SDL_gfx 2.0.13 or * greater). Your mileage may vary. */ VALUE rbgm_transform_flip(int argc, VALUE *argv, VALUE self) { SDL_Surface *surf, *newsurf; int xaxis, yaxis; int loopx, loopy; int pixsize, srcpitch, dstpitch; Uint8 *srcpix, *dstpix; xaxis = argv[0]; yaxis = argv[1]; if(argc < 2) rb_raise(rb_eArgError,"wrong number of arguments (%d for 2)",argc); Data_Get_Struct(self,SDL_Surface,surf); /* Borrowed from Pygame: */ newsurf = newsurf_fromsurf(surf, surf->w, surf->h); if(!newsurf) return Qnil; pixsize = surf->format->BytesPerPixel; srcpitch = surf->pitch; dstpitch = newsurf->pitch; SDL_LockSurface(newsurf); srcpix = (Uint8*)surf->pixels; dstpix = (Uint8*)newsurf->pixels; if(!xaxis) { if(!yaxis) { for(loopy = 0; loopy < surf->h; ++loopy) memcpy(dstpix+loopy*dstpitch, srcpix+loopy*srcpitch, surf->w*surf->format->BytesPerPixel); } else { for(loopy = 0; loopy < surf->h; ++loopy) memcpy(dstpix+loopy*dstpitch, srcpix+(surf->h-1-loopy)*srcpitch, surf->w*surf->format->BytesPerPixel); } } else /*if (xaxis)*/ { if(yaxis) { switch(surf->format->BytesPerPixel) { case 1: for(loopy = 0; loopy < surf->h; ++loopy) { Uint8* dst = (Uint8*)(dstpix+loopy*dstpitch); Uint8* src = ((Uint8*)(srcpix+(surf->h-1-loopy)*srcpitch)) + surf->w - 1; for(loopx = 0; loopx < surf->w; ++loopx) *dst++ = *src--; }break; case 2: for(loopy = 0; loopy < surf->h; ++loopy) { Uint16* dst = (Uint16*)(dstpix+loopy*dstpitch); Uint16* src = ((Uint16*)(srcpix+(surf->h-1-loopy)*srcpitch)) + surf->w - 1; for(loopx = 0; loopx < surf->w; ++loopx) *dst++ = *src--; }break; case 4: for(loopy = 0; loopy < surf->h; ++loopy) { Uint32* dst = (Uint32*)(dstpix+loopy*dstpitch); Uint32* src = ((Uint32*)(srcpix+(surf->h-1-loopy)*srcpitch)) + surf->w - 1; for(loopx = 0; loopx < surf->w; ++loopx) *dst++ = *src--; }break; case 3: for(loopy = 0; loopy < surf->h; ++loopy) { Uint8* dst = (Uint8*)(dstpix+loopy*dstpitch); Uint8* src = ((Uint8*)(srcpix+(surf->h-1-loopy)*srcpitch)) + surf->w*3 - 3; for(loopx = 0; loopx < surf->w; ++loopx) { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst += 3; src -= 3; } }break; } } else { switch(surf->format->BytesPerPixel) { case 1: for(loopy = 0; loopy < surf->h; ++loopy) { Uint8* dst = (Uint8*)(dstpix+loopy*dstpitch); Uint8* src = ((Uint8*)(srcpix+loopy*srcpitch)) + surf->w - 1; for(loopx = 0; loopx < surf->w; ++loopx) *dst++ = *src--; }break; case 2: for(loopy = 0; loopy < surf->h; ++loopy) { Uint16* dst = (Uint16*)(dstpix+loopy*dstpitch); Uint16* src = ((Uint16*)(srcpix+loopy*srcpitch)) + surf->w - 1; for(loopx = 0; loopx < surf->w; ++loopx) *dst++ = *src--; }break; case 4: for(loopy = 0; loopy < surf->h; ++loopy) { Uint32* dst = (Uint32*)(dstpix+loopy*dstpitch); Uint32* src = ((Uint32*)(srcpix+loopy*srcpitch)) + surf->w - 1; for(loopx = 0; loopx < surf->w; ++loopx) *dst++ = *src--; }break; case 3: for(loopy = 0; loopy < surf->h; ++loopy) { Uint8* dst = (Uint8*)(dstpix+loopy*dstpitch); Uint8* src = ((Uint8*)(srcpix+loopy*srcpitch)) + surf->w*3 - 3; for(loopx = 0; loopx < surf->w; ++loopx) { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst += 3; src -= 3; } }break; } } } SDL_UnlockSurface(newsurf); /* Thanks, Pygame :) */ if(newsurf == NULL) rb_raise(eSDLError,"Could not flip surface: %s",SDL_GetError()); return Data_Wrap_Struct(cSurface,0,SDL_FreeSurface,newsurf); }