Skip to content
Open
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: ...
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
42 changes: 41 additions & 1 deletion src_c/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,38 @@ image_renderer_draw(pgImageObject *self, PyObject *area, PyObject *dest)
return 1;
}

#if SDL_VERSION_ATLEAST(2, 0, 20)
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 RAISE(PyExc_ValueError, "Invalid line render method: must be an int"
" (use LINE_RENDER_* constants)");
}
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;
}
#endif

/* Module definition */
static PyMethodDef renderer_methods[] = {
{"draw_point", (PyCFunction)renderer_draw_point,
Expand Down Expand Up @@ -1307,7 +1339,15 @@ 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[] = {
#if SDL_VERSION_ATLEAST(2, 0, 20)
{"get_line_render_method", (PyCFunction)get_line_render_method,
METH_NOARGS, NULL},
{"set_line_render_method", (PyCFunction)set_line_render_method,
METH_VARARGS, NULL},
#endif

{NULL, NULL, 0, NULL}};

MODINIT_DEFINE(_render)
{
Expand Down
7 changes: 7 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from pygame import _render

import pygame


pygame.init()
_render.set_line_render_method("test")
22 changes: 22 additions & 0 deletions test/render_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,3 +482,25 @@ 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())