Skip to content
Open
4 changes: 4 additions & 0 deletions buildconfig/stubs/pygame/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,10 @@ from .constants import (
K_y as K_y,
K_z as K_z,
LIL_ENDIAN as LIL_ENDIAN,
LINE_RENDER_DEFAULT as LINE_RENDER_DEFAULT,
LINE_RENDER_GEOMETRY as LINE_RENDER_GEOMETRY,
LINE_RENDER_LINE as LINE_RENDER_LINE,
LINE_RENDER_POINT as LINE_RENDER_POINT,
LOCALECHANGED as LOCALECHANGED,
MIDIIN as MIDIIN,
MIDIOUT as MIDIOUT,
Expand Down
3 changes: 3 additions & 0 deletions buildconfig/stubs/pygame/_render.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,6 @@ class Texture:
@final
class Image:
pass

def get_line_render_method() -> int: ...
def set_line_render_method(method: int) -> bool: ...
8 changes: 8 additions & 0 deletions buildconfig/stubs/pygame/constants.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,10 @@ K_x: int
K_y: int
K_z: int
LIL_ENDIAN: int
LINE_RENDER_DEFAULT: int
LINE_RENDER_GEOMETRY: int
LINE_RENDER_LINE: int
LINE_RENDER_POINT: int
LOCALECHANGED: int
MIDIIN: int
MIDIOUT: int
Expand Down Expand Up @@ -1191,4 +1195,8 @@ __all__ = [
"FLASH_CANCEL",
"FLASH_BRIEFLY",
"FLASH_UNTIL_FOCUSED",
"LINE_RENDER_DEFAULT",
"LINE_RENDER_POINT",
"LINE_RENDER_LINE",
"LINE_RENDER_GEOMETRY",
]
8 changes: 8 additions & 0 deletions buildconfig/stubs/pygame/locals.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,10 @@ K_x: int
K_y: int
K_z: int
LIL_ENDIAN: int
LINE_RENDER_DEFAULT: int
LINE_RENDER_GEOMETRY: int
LINE_RENDER_LINE: int
LINE_RENDER_POINT: int
LOCALECHANGED: int
MIDIIN: int
MIDIOUT: int
Expand Down Expand Up @@ -1193,6 +1197,10 @@ __all__ = [
"FLASH_CANCEL",
"FLASH_BRIEFLY",
"FLASH_UNTIL_FOCUSED",
"LINE_RENDER_DEFAULT",
"LINE_RENDER_POINT",
"LINE_RENDER_LINE",
"LINE_RENDER_GEOMETRY",
"Rect",
"Color",
]
5 changes: 5 additions & 0 deletions src_c/constants.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,11 @@ MODINIT_DEFINE(constants)
DEC_CONSTS(FLASH_UNTIL_FOCUSED, -1);
#endif

DEC_CONSTS(LINE_RENDER_DEFAULT, 0)
DEC_CONSTS(LINE_RENDER_POINT, 1)
DEC_CONSTS(LINE_RENDER_LINE, 2)
DEC_CONSTS(LINE_RENDER_GEOMETRY, 3)

if (PyModule_AddObject(module, "__all__", all_list)) {
Py_DECREF(all_list);
Py_DECREF(module);
Expand Down
58 changes: 57 additions & 1 deletion src_c/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,56 @@ image_renderer_draw(pgImageObject *self, PyObject *area, PyObject *dest)
return 1;
}

#if (SDL_VERSION_ATLEAST(2, 0, 20) && !SDL_VERSION_ATLEAST(3, 0, 0)) || SDL_VERSION_ATLEAST(3, 2, 0)
static PyObject *
get_line_render_method(PyObject *self, PyObject *Py_UNUSED(ignored))
{
const char *hint = SDL_GetHint(SDL_HINT_RENDER_LINE_METHOD);
return PyLong_FromLong(
hint == NULL ? 0 : hint[0] - '0'); // hint is a char between 0-3
}

static PyObject *
set_line_render_method(PyObject *self, PyObject *args)
{
int method;
if (!PyArg_ParseTuple(args, "i", &method)) {
return NULL;
}
if (method < 0 || 3 < method) {
return RAISE(PyExc_ValueError,
"Invalid line render method: must be between"
" 0 and 3 (use LINE_RENDER_* constants)");
}

// SDL_SetHint expects the method as a string
char hint[2];
hint[0] = method + '0'; // ascii char manipulation
hint[1] = '\0';

if (SDL_SetHint(SDL_HINT_RENDER_LINE_METHOD, hint)) {
Py_RETURN_TRUE;
}
Py_RETURN_FALSE;
}
#else
static PyObject *
get_line_render_method(PyObject *self, PyObject *Py_UNUSED(ignored))
{
return RAISE(PyExc_NotImplementedError, "Setting/getting the "
"line render method is only available when built with SDL2 2.0.20"
" or SDL3 3.2.0")
}

static PyObject *
set_line_render_method(PyObject *self, PyObject *args)
{
return RAISE(PyExc_NotImplementedError, "Setting/getting the "
"line render method is only available when built with SDL2 2.0.20"
" or SDL3 3.2.0")
}
#endif

/* Module definition */
static PyMethodDef renderer_methods[] = {
{"draw_point", (PyCFunction)renderer_draw_point,
Expand Down Expand Up @@ -1307,7 +1357,13 @@ static PyTypeObject pgImage_Type = {
//.tp_init = (initproc)image_init,
.tp_new = PyType_GenericNew, .tp_getset = image_getset};

static PyMethodDef _render_methods[] = {{NULL, NULL, 0, NULL}};
static PyMethodDef _render_methods[] = {
{"get_line_render_method", (PyCFunction)get_line_render_method,
METH_NOARGS, NULL},
{"set_line_render_method", (PyCFunction)set_line_render_method,
METH_VARARGS, NULL},

{NULL, NULL, 0, NULL}};

MODINIT_DEFINE(_render)
{
Expand Down
26 changes: 26 additions & 0 deletions test/render_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,3 +482,29 @@ def test_update(self):
result = self.renderer.to_surface()
for x in range(25, 75):
self.assertEqual(pygame.Color(80, 120, 160, 255), result.get_at((x, 50)))


class LineRenderMethodTest(unittest.TestCase):
def test_correct_argument(self):
with self.assertRaises(ValueError):
_render.set_line_render_method(-1)
with self.assertRaises(ValueError):
_render.set_line_render_method(10)
with self.assertRaises(ValueError):
_render.set_line_render_method("foo")
with self.assertRaises(ValueError):
_render.set_line_render_method(None)

def test_get_set_line_render_method(self):
if _render.set_line_render_method(pygame.LINE_RENDER_DEFAULT):
self.assertEqual(
pygame.LINE_RENDER_DEFAULT, _render.get_line_render_method()
)
if _render.set_line_render_method(pygame.LINE_RENDER_POINT):
self.assertEqual(pygame.LINE_RENDER_POINT, _render.get_line_render_method())
if _render.set_line_render_method(pygame.LINE_RENDER_LINE):
self.assertEqual(pygame.LINE_RENDER_LINE, _render.get_line_render_method())
if _render.set_line_render_method(pygame.LINE_RENDER_GEOMETRY):
self.assertEqual(
pygame.LINE_RENDER_GEOMETRY, _render.get_line_render_method()
)