Skip to content

Commit

Permalink
Fix issue #2446: rotozoom keeps the colorkey flag. (#2491)
Browse files Browse the repository at this point in the history
Co-authored-by: Joras <[email protected]>
Co-authored-by: Antonio <[email protected]>
Co-authored-by: João <[email protected]>
Co-authored-by: Caio <[email protected]>
Co-authored-by: Cícero <[email protected]>
Co-authored-by: Natália <[email protected]>
Co-authored-by: Dan Lawrence <[email protected]>
  • Loading branch information
8 people authored Oct 28, 2023
1 parent 6157363 commit 56f30c3
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src_c/_pygame.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
#define PG_ConvertSurface SDL_ConvertSurface
#define PG_ConvertSurfaceFormat SDL_ConvertSurfaceFormat

#define PG_SurfaceHasRLE SDL_SurfaceHasRLE

#else /* ~SDL_VERSION_ATLEAST(3, 0, 0)*/
#define PG_ShowCursor() SDL_ShowCursor(SDL_ENABLE)
#define PG_HideCursor() SDL_ShowCursor(SDL_DISABLE)
Expand Down Expand Up @@ -100,6 +102,44 @@
#define PG_ConvertSurface(src, fmt) SDL_ConvertSurface(src, fmt, 0)
#define PG_ConvertSurfaceFormat(src, pixel_format) \
SDL_ConvertSurfaceFormat(src, pixel_format, 0)
#if SDL_VERSION_ATLEAST(2, 0, 14)
#define PG_SurfaceHasRLE SDL_HasSurfaceRLE
#else
// vendored in until our lowest SDL version is 2.0.14
typedef struct {
Uint8 *src;
int src_w, src_h;
int src_pitch;
int src_skip;
Uint8 *dst;
int dst_w, dst_h;
int dst_pitch;
int dst_skip;
SDL_PixelFormat *src_fmt;
SDL_PixelFormat *dst_fmt;
Uint8 *table;
int flags;
Uint32 colorkey;
Uint8 r, g, b, a;
} SDL_InternalBlitInfo;

struct SDL_BlitMap {
SDL_Surface *dst;
int identity;
SDL_blit blit;
void *data;
SDL_InternalBlitInfo info;

/* the version count matches the destination; mismatch indicates
an invalid mapping */
Uint32 dst_palette_version;
Uint32 src_palette_version;
};
#define SDL_COPY_RLE_DESIRED 0x00001000

SDL_bool
PG_SurfaceHasRLE(SDL_Surface *surface);
#endif

#endif

Expand Down
41 changes: 41 additions & 0 deletions src_c/rotozoom.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,23 @@
*/

#include "_pygame.h"

#if !SDL_VERSION_ATLEAST(2, 0, 14)
SDL_bool
PG_SurfaceHasRLE(SDL_Surface *surface)
{
if (surface == NULL) {
return SDL_FALSE;
}

if (!(surface->map->info.flags & SDL_COPY_RLE_DESIRED)) {
return SDL_FALSE;
}

return SDL_TRUE;
}
#endif
#define NO_PYGAME_C_API
#include "pygame.h"

Expand Down Expand Up @@ -511,6 +528,7 @@ rotozoomSurface(SDL_Surface *src, double angle, double zoom, int smooth)
int dstwidth, dstheight;
int is32bit;
int src_converted;
Uint32 colorkey;

/*
* Sanity check
Expand Down Expand Up @@ -583,6 +601,17 @@ rotozoomSurface(SDL_Surface *src, double angle, double zoom, int smooth)
* Target surface is 32bit with source RGBA/ABGR ordering
*/
rz_dst = PG_CreateSurface(dstwidth, dstheight, rz_src->format->format);
if (SDL_GetColorKey(src, &colorkey) == 0) {
if (SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey) != 0) {
SDL_FreeSurface(rz_dst);
return NULL;
}
if (PG_SurfaceHasRLE(src) &&
SDL_SetSurfaceRLE(rz_dst, SDL_TRUE) != 0) {
SDL_FreeSurface(rz_dst);
return NULL;
}
}

/*
* Lock source surface
Expand Down Expand Up @@ -628,7 +657,19 @@ rotozoomSurface(SDL_Surface *src, double angle, double zoom, int smooth)
/*
* Target surface is 32bit with source RGBA/ABGR ordering
*/

rz_dst = PG_CreateSurface(dstwidth, dstheight, rz_src->format->format);
if (SDL_GetColorKey(src, &colorkey) == 0) {
if (SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey) != 0) {
SDL_FreeSurface(rz_dst);
return NULL;
}
if (PG_SurfaceHasRLE(src) &&
SDL_SetSurfaceRLE(rz_dst, SDL_TRUE) != 0) {
SDL_FreeSurface(rz_dst);
return NULL;
}
}

/*
* Lock source surface
Expand Down
4 changes: 4 additions & 0 deletions src_c/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,10 @@ surf_rotozoom(PyObject *self, PyObject *args, PyObject *kwargs)
Py_BEGIN_ALLOW_THREADS;
newsurf = rotozoomSurface(surf32, angle, scale, 1);
Py_END_ALLOW_THREADS;
if (newsurf == NULL) {
PyErr_SetString(pgExc_SDLError, SDL_GetError());
return NULL;
}

if (surf32 == surf)
pgSurface_Unlock(surfobj);
Expand Down
11 changes: 11 additions & 0 deletions test/transform_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,17 @@ def test_rotozoom(self):
self.assertEqual(s1.get_rect(), pygame.Rect(0, 0, 0, 0))
self.assertEqual(s2.get_rect(), pygame.Rect(0, 0, 0, 0))

def test_rotozoom_keeps_colorkey(self):
image = pygame.Surface((64, 64))
image.set_colorkey("black")
pygame.draw.circle(image, "red", (32, 32), 32, width=0)

no_rot = pygame.transform.rotozoom(image, 0, 1.1)
self.assertEqual(image.get_colorkey(), no_rot.get_colorkey())

with_rot = pygame.transform.rotozoom(image, 5, 1.1)
self.assertEqual(image.get_colorkey(), with_rot.get_colorkey())

def test_invert(self):
surface = pygame.Surface((10, 10), depth=32)

Expand Down

0 comments on commit 56f30c3

Please sign in to comment.