From e062becad59a4bf46c542b6f7025caacb9416133 Mon Sep 17 00:00:00 2001 From: Starbuck5 <46412508+Starbuck5@users.noreply.github.com> Date: Wed, 9 Oct 2024 00:22:43 -0700 Subject: [PATCH] Adjust pg_MappedColorFromObj API for SDL3-porting In SDL3, surf->format is not a good enough source of information about the surface to do things like MapRGB, because it doesn't have palette information. Therefore I think it makes sense to pass around surfaces instead of SDL_PixelFormats. This commit gets the color module compiling in SDL3. --- docs/reST/c_api/color.rst | 4 ++-- src_c/color.c | 11 +++++++---- src_c/draw.c | 8 ++++---- src_c/include/_pygame.h | 4 ++-- src_c/mask.c | 9 ++++----- src_c/meson.build | 3 --- src_c/pixelarray.c | 8 ++++---- src_c/pixelarray_methods.c | 11 +++++------ src_c/surface.c | 8 +++----- src_c/transform.c | 20 +++++++++----------- 10 files changed, 40 insertions(+), 46 deletions(-) diff --git a/docs/reST/c_api/color.rst b/docs/reST/c_api/color.rst index dc91db8feb..f6349fe805 100644 --- a/docs/reST/c_api/color.rst +++ b/docs/reST/c_api/color.rst @@ -44,8 +44,8 @@ Header file: src_c/include/pygame.h instances and tuples. It can also handle integer and string color inputs based on ``handle_flags``. -.. c:function:: int pg_MappedColorFromObj(PyObject *val, SDL_PixelFormat *format, Uint32 *color, pgColorHandleFlags handle_flags) +.. c:function:: int pg_MappedColorFromObj(PyObject *val, SDL_Surface *surf, Uint32 *color, pgColorHandleFlags handle_flags) Like above function, but returns mapped color instead. One notable point of difference is the way in which ints are handled (this function directly interprets the int passed as the - mapped color) + mapped color on the surface ``surf```) diff --git a/src_c/color.c b/src_c/color.c index 845a4c0314..97abed4c45 100644 --- a/src_c/color.c +++ b/src_c/color.c @@ -219,7 +219,7 @@ static int pg_RGBAFromObjEx(PyObject *color, Uint8 rgba[], pgColorHandleFlags handle_flags); static int -pg_MappedColorFromObj(PyObject *val, SDL_PixelFormat *format, Uint32 *color, +pg_MappedColorFromObj(PyObject *val, SDL_Surface *surf, Uint32 *color, pgColorHandleFlags handle_flags); /** @@ -2386,7 +2386,7 @@ pg_RGBAFromObjEx(PyObject *obj, Uint8 *rgba, pgColorHandleFlags handle_flags) } static int -pg_MappedColorFromObj(PyObject *val, SDL_PixelFormat *format, Uint32 *color, +pg_MappedColorFromObj(PyObject *val, SDL_Surface *surf, Uint32 *color, pgColorHandleFlags handle_flags) { Uint8 rgba[] = {0, 0, 0, 0}; @@ -2401,8 +2401,11 @@ pg_MappedColorFromObj(PyObject *val, SDL_PixelFormat *format, Uint32 *color, /* int is already handled, unset it */ handle_flags &= ~PG_COLOR_HANDLE_INT; if (pg_RGBAFromObjEx(val, rgba, handle_flags)) { - *color = - (Uint32)SDL_MapRGBA(format, rgba[0], rgba[1], rgba[2], rgba[3]); +#if SDL_VERSION_ATLEAST(3, 0, 0) + *color = SDL_MapSurfaceRGBA(surf, rgba[0], rgba[1], rgba[2], rgba[3]); +#else + *color = SDL_MapRGBA(surf->format, rgba[0], rgba[1], rgba[2], rgba[3]); +#endif return 1; } return 0; diff --git a/src_c/draw.c b/src_c/draw.c index 84138bc077..0d6b9fc8a8 100644 --- a/src_c/draw.c +++ b/src_c/draw.c @@ -100,10 +100,10 @@ draw_round_rect(SDL_Surface *surf, int x1, int y1, int x2, int y2, int radius, int bottom_left, int bottom_right, int *drawn_area); // validation of a draw color -#define CHECK_LOAD_COLOR(colorobj) \ - if (!pg_MappedColorFromObj((colorobj), surf->format, &color, \ - PG_COLOR_HANDLE_ALL)) { \ - return NULL; \ +#define CHECK_LOAD_COLOR(colorobj) \ + if (!pg_MappedColorFromObj((colorobj), surf, &color, \ + PG_COLOR_HANDLE_ALL)) { \ + return NULL; \ } /* Definition of functions that get called in Python */ diff --git a/src_c/include/_pygame.h b/src_c/include/_pygame.h index 5ff4882dfb..bcfb0fdc8c 100644 --- a/src_c/include/_pygame.h +++ b/src_c/include/_pygame.h @@ -466,8 +466,8 @@ typedef struct pgColorObject pgColorObject; (*(int (*)(PyObject *, Uint8 *, pgColorHandleFlags))PYGAMEAPI_GET_SLOT( \ color, 2)) -#define pg_MappedColorFromObj \ - (*(int (*)(PyObject *, SDL_PixelFormat *, Uint32 *, \ +#define pg_MappedColorFromObj \ + (*(int (*)(PyObject *, SDL_Surface *, Uint32 *, \ pgColorHandleFlags))PYGAMEAPI_GET_SLOT(color, 4)) #define pgColor_AsArray(x) (((pgColorObject *)x)->data) diff --git a/src_c/mask.c b/src_c/mask.c index 020291edc2..074ddfd383 100644 --- a/src_c/mask.c +++ b/src_c/mask.c @@ -1129,14 +1129,14 @@ mask_from_threshold(PyObject *self, PyObject *args, PyObject *kwargs) surf2 = pgSurface_AsSurface(surfobj2); } - if (!pg_MappedColorFromObj(rgba_obj_color, surf->format, &color, + if (!pg_MappedColorFromObj(rgba_obj_color, surf, &color, PG_COLOR_HANDLE_INT)) { return NULL; } if (rgba_obj_threshold) { - if (!pg_MappedColorFromObj(rgba_obj_threshold, surf->format, - &color_threshold, PG_COLOR_HANDLE_INT)) { + if (!pg_MappedColorFromObj(rgba_obj_threshold, surf, &color_threshold, + PG_COLOR_HANDLE_INT)) { return NULL; } } @@ -1927,8 +1927,7 @@ extract_color(SDL_Surface *surf, PyObject *color_obj, Uint8 rgba_color[], return 1; } - return pg_MappedColorFromObj(color_obj, surf->format, color, - PG_COLOR_HANDLE_ALL); + return pg_MappedColorFromObj(color_obj, surf, color, PG_COLOR_HANDLE_ALL); } /* Draws a mask on a surface. diff --git a/src_c/meson.build b/src_c/meson.build index 6972b28f0f..4be6a4683a 100644 --- a/src_c/meson.build +++ b/src_c/meson.build @@ -12,8 +12,6 @@ base = py.extension_module( ) endif -# TODO: support SDL3 -if sdl_api != 3 color = py.extension_module( 'color', 'color.c', @@ -22,7 +20,6 @@ color = py.extension_module( install: true, subdir: pg, ) -endif # TODO: support SDL3 if sdl_api != 3 diff --git a/src_c/pixelarray.c b/src_c/pixelarray.c index 26e631576d..53c32a41f5 100644 --- a/src_c/pixelarray.c +++ b/src_c/pixelarray.c @@ -1112,7 +1112,7 @@ _array_assign_sequence(pgPixelArrayObject *array, Py_ssize_t low, } for (x = 0; x < val_dim0; ++x) { item = PySequence_ITEM(val, x); - if (!_get_color_from_object(item, format, (val_colors + x))) { + if (!_get_color_from_object(item, surf, (val_colors + x))) { Py_DECREF(item); free(val_colors); return -1; @@ -1299,7 +1299,7 @@ _pxarray_ass_item(pgPixelArrayObject *array, Py_ssize_t index, PyObject *value) bpp = PG_SURF_BytesPerPixel(surf); - if (!_get_color_from_object(value, surf->format, &color)) { + if (!_get_color_from_object(value, surf, &color)) { if (PyTuple_Check(value)) { return -1; } @@ -1425,7 +1425,7 @@ _pxarray_ass_slice(pgPixelArrayObject *array, Py_ssize_t low, Py_ssize_t high, return _array_assign_array(array, low, high, (pgPixelArrayObject *)value); } - if (_get_color_from_object(value, surf->format, &color)) { + if (_get_color_from_object(value, surf, &color)) { return _array_assign_slice(array, low, high, color); } if (PyTuple_Check(value)) { @@ -1460,7 +1460,7 @@ _pxarray_contains(pgPixelArrayObject *array, PyObject *value) bpp = PG_SURF_BytesPerPixel(surf); - if (!_get_color_from_object(value, surf->format, &color)) { + if (!_get_color_from_object(value, surf, &color)) { return -1; } diff --git a/src_c/pixelarray_methods.c b/src_c/pixelarray_methods.c index 235a5b4b64..8ecbebdb91 100644 --- a/src_c/pixelarray_methods.c +++ b/src_c/pixelarray_methods.c @@ -36,15 +36,14 @@ * Tries to retrieve a valid color for a Surface. */ static int -_get_color_from_object(PyObject *val, SDL_PixelFormat *format, Uint32 *color) +_get_color_from_object(PyObject *val, SDL_Surface *surf, Uint32 *color) { if (!val) { return 0; } return pg_MappedColorFromObj( - val, format, color, - PG_COLOR_HANDLE_INT | PG_COLOR_HANDLE_RESTRICT_SEQ); + val, surf, color, PG_COLOR_HANDLE_INT | PG_COLOR_HANDLE_RESTRICT_SEQ); } /** @@ -376,8 +375,8 @@ _replace_color(pgPixelArrayObject *array, PyObject *args, PyObject *kwds) format = surf->format; bpp = PG_SURF_BytesPerPixel(surf); - if (!_get_color_from_object(delcolor, format, &dcolor) || - !_get_color_from_object(replcolor, format, &rcolor)) { + if (!_get_color_from_object(delcolor, surf, &dcolor) || + !_get_color_from_object(replcolor, surf, &rcolor)) { return 0; } @@ -582,7 +581,7 @@ _extract_color(pgPixelArrayObject *array, PyObject *args, PyObject *kwds) black = SDL_MapRGBA(format, 0, 0, 0, 255); white = SDL_MapRGBA(format, 255, 255, 255, 255); - if (!_get_color_from_object(excolor, format, &color)) { + if (!_get_color_from_object(excolor, surf, &color)) { Py_DECREF(new_array); return 0; } diff --git a/src_c/surface.c b/src_c/surface.c index 072aa09b5c..1330f6b93b 100644 --- a/src_c/surface.c +++ b/src_c/surface.c @@ -809,8 +809,7 @@ surf_set_at(PyObject *self, PyObject *const *args, Py_ssize_t nargs) Py_RETURN_NONE; } - if (!pg_MappedColorFromObj(rgba_obj, surf->format, &color, - PG_COLOR_HANDLE_ALL)) { + if (!pg_MappedColorFromObj(rgba_obj, surf, &color, PG_COLOR_HANDLE_ALL)) { return NULL; } @@ -1207,7 +1206,7 @@ surf_set_colorkey(pgSurfaceObject *self, PyObject *args) SURF_INIT_CHECK(surf) if (rgba_obj && rgba_obj != Py_None) { - if (!pg_MappedColorFromObj(rgba_obj, surf->format, &color, + if (!pg_MappedColorFromObj(rgba_obj, surf, &color, PG_COLOR_HANDLE_ALL)) { return NULL; } @@ -1748,8 +1747,7 @@ surf_fill(pgSurfaceObject *self, PyObject *args, PyObject *keywds) return NULL; SURF_INIT_CHECK(surf) - if (!pg_MappedColorFromObj(rgba_obj, surf->format, &color, - PG_COLOR_HANDLE_ALL)) { + if (!pg_MappedColorFromObj(rgba_obj, surf, &color, PG_COLOR_HANDLE_ALL)) { return NULL; } diff --git a/src_c/transform.c b/src_c/transform.c index c584de990c..e665455e8f 100644 --- a/src_c/transform.c +++ b/src_c/transform.c @@ -1825,11 +1825,11 @@ Returns 0 if ok, and sets color to the color. If rgba_default is NULL, do not use a default color, return -1. */ int -_color_from_obj(PyObject *color_obj, SDL_PixelFormat *format, - Uint8 rgba_default[4], Uint32 *color) +_color_from_obj(PyObject *color_obj, SDL_Surface *surf, Uint8 rgba_default[4], + Uint32 *color) { if (color_obj) { - if (!pg_MappedColorFromObj(color_obj, format, color, + if (!pg_MappedColorFromObj(color_obj, surf, color, PG_COLOR_HANDLE_INT)) { return -1; } @@ -1837,7 +1837,7 @@ _color_from_obj(PyObject *color_obj, SDL_PixelFormat *format, else { if (!rgba_default) return -1; - *color = SDL_MapRGBA(format, rgba_default[0], rgba_default[1], + *color = SDL_MapRGBA(surf->format, rgba_default[0], rgba_default[1], rgba_default[2], rgba_default[3]); } return 0; @@ -1961,17 +1961,16 @@ surf_threshold(PyObject *self, PyObject *args, PyObject *kwds) } if (search_color_obj != Py_None) { - if (_color_from_obj(search_color_obj, surf->format, NULL, - &color_search_color)) + if (_color_from_obj(search_color_obj, surf, NULL, &color_search_color)) return RAISE(PyExc_TypeError, "invalid search_color argument"); } - if (_color_from_obj(threshold_obj, surf->format, rgba_threshold_default, + if (_color_from_obj(threshold_obj, surf, rgba_threshold_default, &color_threshold)) return RAISE(PyExc_TypeError, "invalid threshold argument"); if (set_color_obj != Py_None) { - if (_color_from_obj(set_color_obj, surf->format, - rgba_set_color_default, &color_set_color)) + if (_color_from_obj(set_color_obj, surf, rgba_set_color_default, + &color_set_color)) return RAISE(PyExc_TypeError, "invalid set_color argument"); } @@ -2416,8 +2415,7 @@ surf_solid_overlay(PyObject *self, PyObject *args, PyObject *kwargs) surf = pgSurface_AsSurface(surfobj); - if (!pg_MappedColorFromObj(colorobj, surf->format, &color, - PG_COLOR_HANDLE_ALL)) { + if (!pg_MappedColorFromObj(colorobj, surf, &color, PG_COLOR_HANDLE_ALL)) { return RAISE(PyExc_TypeError, "invalid color argument"); }