Skip to content

Commit

Permalink
Adjust pg_MappedColorFromObj API for SDL3-porting
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Starbuck5 committed Oct 10, 2024
1 parent 8ee07ff commit e062bec
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 46 deletions.
4 changes: 2 additions & 2 deletions docs/reST/c_api/color.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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```)
11 changes: 7 additions & 4 deletions src_c/color.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/**
Expand Down Expand Up @@ -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};
Expand All @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions src_c/draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
4 changes: 2 additions & 2 deletions src_c/include/_pygame.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 4 additions & 5 deletions src_c/mask.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 0 additions & 3 deletions src_c/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ base = py.extension_module(
)
endif

# TODO: support SDL3
if sdl_api != 3
color = py.extension_module(
'color',
'color.c',
Expand All @@ -22,7 +20,6 @@ color = py.extension_module(
install: true,
subdir: pg,
)
endif

# TODO: support SDL3
if sdl_api != 3
Expand Down
8 changes: 4 additions & 4 deletions src_c/pixelarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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;
}

Expand Down
11 changes: 5 additions & 6 deletions src_c/pixelarray_methods.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down
8 changes: 3 additions & 5 deletions src_c/surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down
20 changes: 9 additions & 11 deletions src_c/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -1825,19 +1825,19 @@ 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;
}
}
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;
Expand Down Expand Up @@ -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");
}

Expand Down Expand Up @@ -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");
}

Expand Down

0 comments on commit e062bec

Please sign in to comment.