static PyObject* _gfx_rotate90 (PyObject *self, PyObject *args) { PyObject *surface, *retval; SDL_Surface *orig, *result; int times; if (!PyArg_ParseTuple (args, "Oi:rotate_90", &surface, ×)) return NULL; if (!PySDLSurface_Check (surface)) { PyErr_SetString (PyExc_TypeError, "surface must be a Surface"); return NULL; } orig = ((PySDLSurface*)surface)->surface; result = rotateSurface90Degrees (orig, times); if (!result) { PyErr_SetString (PyExc_PyGameError, SDL_GetError ()); return NULL; } retval = PySDLSurface_NewFromSDLSurface (result); if (!retval) { SDL_FreeSurface (result); return NULL; } return retval; }
SDL_Surface* getRotatedOptimized(SDL_Surface* surface, float angle) { #if IS_SDL_GFX_ROTOZOOM_SURFACE_90_DEGREES_AVAILABLE // use rotateSurface90Degrees() only when its available (SDL_gfx 2.0.17 or higher) double turns; if(fabs(modf(angle / M_PI_2, &turns)) <= epsilon_ratio // angle sufficiently close to pi/2 multiples and surface->format->BitsPerPixel == 32) // rotateSurface90Degrees only supports 32bit RGBA/ABGR // use optimized 90-degree rotations return rotateSurface90Degrees(surface, (int) -turns); else // use standard rotation function #endif return rotozoomSurface(surface, angle*toDegree, 1.0, SMOOTHING_OFF); }
void RotatePicture90Degrees (SDL_Surface *screen, SDL_Surface *picture) { SDL_Surface *rotozoom_picture; SDL_Rect dest; int framecount, framemax, frameinc; int numClockwiseTurns; fprintf(stderr, "%s\n", messageText); /* Rotate and display the picture */ framemax = 21; frameinc = 1; numClockwiseTurns = -4; for (framecount=0; framecount<framemax; framecount += frameinc) { HandleEvent(); ClearScreen(screen); printf (" Frame: %i Rotate90: %i clockwise turns\n",framecount,numClockwiseTurns+4); if ((rotozoom_picture=rotateSurface90Degrees(picture, numClockwiseTurns))!=NULL) { dest.x = (screen->w - rotozoom_picture->w)/2;; dest.y = (screen->h - rotozoom_picture->h)/2; dest.w = rotozoom_picture->w; dest.h = rotozoom_picture->h; if ( SDL_BlitSurface(rotozoom_picture, NULL, screen, &dest) < 0 ) { fprintf(stderr, "Blit failed: %s\n", SDL_GetError()); break; } SDL_FreeSurface(rotozoom_picture); } stringRGBA(screen, 8, 8, messageText, 255, 255, 255, 255); /* Display by flipping screens */ SDL_Flip(screen); /* Always delay */ SDL_Delay(333); if (delay>0) { SDL_Delay(delay); } numClockwiseTurns++; } /* Pause for a sec */ SDL_Delay(1000); }
xyz_image *xyz_turn_image(xyz_image *source, int num_turns_clockwise) { xyz_image *ret = xyz_new(xyz_image); ret->image = rotateSurface90Degrees(source->image, 2); return ret; }
int main(int argc, char *argv[]) { SDL_Surface *screen = NULL, *image = NULL, *scaledImage = NULL, *name = NULL; SDL_Rect picturePortion; TTF_Font *font = NULL; double scale = 1.0; int currentImageNumber = 1, showFileName = TRUE, runSlideShow = FALSE, isRunning = TRUE; SDL_TimerID slideShowTimer = 0; // Process command line if (argc < 2) { fprintf(stderr, "\n" " imgv v%s. Syntax: imgv <image files>\n\n" " Hotkeys:\n" " 'f' fit to screen\n" " 'z' zoom at pixel level\n" " 'i' zoom in 'o' zoom out\n" " 'l' rotate left 'r' rotate right\n" " 'n' next image 'p' previous image\n" " 'd' show / hide file name\n" " 's' start / stop slide show\n" " 'arrows' pan 'ESC' quit\n\n", VERSION); exit(0); } screen = initScreen(); font = TTF_OpenFont("font.ttf", 11); if (font == (TTF_Font *) (NULL)) { font = TTF_OpenFont("/usr/share/imgv/font.ttf", 11); } if (font == (TTF_Font *) (NULL)) { font = TTF_OpenFont("/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf", 11); } picturePortion.w = SCREENWIDTH; picturePortion.h = SCREENHEIGHT; image = loadImage(argv[1]); if (image->w < SCREENWIDTH && image->h < SCREENHEIGHT) { scaledImage = zoom100(image, &picturePortion, &scale); } else { scaledImage = zoomFit(image, &picturePortion, &scale); } name = drawFileName(argv[currentImageNumber], font, runSlideShow); drawImage(scaledImage, &picturePortion, screen, name); do { SDL_Event event; if (SDL_WaitEvent(&event) && event.type == SDL_KEYDOWN) { switch (event.key.keysym.sym) { case SDLK_LEFT: // PAN LEFT pan(scaledImage, &picturePortion, -PANSTEP, 0); break; case SDLK_RIGHT: // PAN RIGHT pan(scaledImage, &picturePortion, PANSTEP, 0); break; case SDLK_UP: // PAN UP pan(scaledImage, &picturePortion, 0, -PANSTEP); break; case SDLK_DOWN: // PAN DOWN pan(scaledImage, &picturePortion, 0, PANSTEP); break; case SDLK_i: // ZOOM IN SDL_FreeSurface(scaledImage); scaledImage = zoomIn(image, &picturePortion, &scale); break; case SDLK_o: // ZOOM OUT SDL_FreeSurface(scaledImage); scaledImage = zoomOut(image, &picturePortion, &scale); break; case SDLK_f: // ZOOM TO FIT SCREEN SDL_FreeSurface(scaledImage); scaledImage = zoomFit(image, &picturePortion, &scale); break; case SDLK_z: // ZOOM TO ORIGINAL SIZE SDL_FreeSurface(scaledImage); scaledImage = zoom100(image, &picturePortion, &scale); break; case SDLK_l: // ROTATE LEFT { SDL_FreeSurface(scaledImage); SDL_Surface *tmp = rotateSurface90Degrees(image, 3); SDL_FreeSurface(image); image = tmp; scaledImage = zoomSurface(image, scale, scale, SMOOTHING_ON); int x = picturePortion.x; picturePortion.x = picturePortion.y + SCREENHEIGHT/2 - SCREENWIDTH/2; picturePortion.y = scaledImage->h - x - SCREENHEIGHT/2 - SCREENWIDTH/2; pan(scaledImage, &picturePortion, 0, 0); } break; case SDLK_r: // ROTATE RIGHT { SDL_FreeSurface(scaledImage); SDL_Surface *tmp = rotateSurface90Degrees(image, 1); SDL_FreeSurface(image); image = tmp; scaledImage = zoomSurface(image, scale, scale, SMOOTHING_ON); int x = picturePortion.x; picturePortion.x = scaledImage->w - picturePortion.y - SCREENWIDTH/2 - SCREENHEIGHT/2; picturePortion.y = x + SCREENWIDTH/2 - SCREENHEIGHT/2; pan(scaledImage, &picturePortion, 0, 0); } break; case SDLK_n: // NEXT IMAGE if (currentImageNumber < argc-1) { ++currentImageNumber; SDL_FreeSurface(image); SDL_FreeSurface(scaledImage); SDL_FreeSurface(name); image = loadImage(argv[currentImageNumber]); if (image->w < SCREENWIDTH && image->h < SCREENHEIGHT) { scaledImage = zoom100(image, &picturePortion, &scale); } else { scaledImage = zoomFit(image, &picturePortion, &scale); } name = drawFileName(argv[currentImageNumber], font, runSlideShow); } else { if (runSlideShow) { SDL_RemoveTimer(slideShowTimer); runSlideShow = FALSE; name = drawFileName(argv[currentImageNumber], font, runSlideShow); } } break; case SDLK_p: // PREVIOUS IMAGE if (currentImageNumber > 1) { --currentImageNumber; SDL_FreeSurface(image); SDL_FreeSurface(scaledImage); SDL_FreeSurface(name); image = loadImage(argv[currentImageNumber]); if (image->w < SCREENWIDTH && image->h < SCREENHEIGHT) { scaledImage = zoom100(image, &picturePortion, &scale); } else { scaledImage = zoomFit(image, &picturePortion, &scale); } name = drawFileName(argv[currentImageNumber], font, runSlideShow); } break; case SDLK_s: // START / STOP SLIDESHOW runSlideShow = 1 - runSlideShow; name = drawFileName(argv[currentImageNumber], font, runSlideShow); if (runSlideShow) { slideShowTimer = SDL_AddTimer(SLIDESHOWTIMEOUT, timerCallback, NULL); } else { SDL_RemoveTimer(slideShowTimer); } break; case SDLK_d: // SHOW / HIDE FILENAME showFileName = 1 - showFileName; break; case SDLK_ESCAPE: // QUIT case SDLK_q: isRunning = FALSE; break; default: break; } // end of switch (event.key.keysym.sym) } // end of if(SDL_WaitEvent()) drawImage(scaledImage, &picturePortion, screen, showFileName ? name : 0); } while(isRunning); // end of do SDL_FreeSurface(image); SDL_FreeSurface(scaledImage); SDL_FreeSurface(screen); TTF_CloseFont(font); TTF_Quit(); SDL_Quit(); return 0; }