From c3122ec695e5d1dc28d4b16ad7780db848773859 Mon Sep 17 00:00:00 2001 From: itzpr3d4t0r <103119829+itzpr3d4t0r@users.noreply.github.com> Date: Sun, 5 Jan 2025 14:02:22 +0100 Subject: [PATCH] Add Font.set_linesize() (TTF 2.24.0 feature) --- buildconfig/stubs/pygame/font.pyi | 1 + docs/reST/ref/font.rst | 10 ++++++++++ src_c/doc/font_doc.h | 1 + src_c/font.c | 24 ++++++++++++++++++++++++ test/font_test.py | 20 ++++++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/buildconfig/stubs/pygame/font.pyi b/buildconfig/stubs/pygame/font.pyi index 931d8ceeba..e2e073b4fb 100644 --- a/buildconfig/stubs/pygame/font.pyi +++ b/buildconfig/stubs/pygame/font.pyi @@ -79,6 +79,7 @@ class Font: ) -> list[tuple[int, int, int, int, int]]: ... def get_italic(self) -> bool: ... def get_linesize(self) -> int: ... + def set_linesize(self, linesize: int, /) -> None: ... def get_height(self) -> int: ... def get_ascent(self) -> int: ... def get_descent(self) -> int: ... diff --git a/docs/reST/ref/font.rst b/docs/reST/ref/font.rst index a538a48aec..ca22b5e9b5 100644 --- a/docs/reST/ref/font.rst +++ b/docs/reST/ref/font.rst @@ -511,6 +511,16 @@ solves no longer exists, it will likely be removed in the future. .. ## Font.get_linesize ## + .. method:: set_linesize + + | :sl:`set the line space of the font text` + | :sg:`set_linesize(linesize) -> int` + + Set the height in pixels for a line of text with the font. When rendering + multiple lines of text this refers to the amount of space between lines. + + .. ## Font.set_linesize ## + .. method:: get_height | :sl:`get the height of the font` diff --git a/src_c/doc/font_doc.h b/src_c/doc/font_doc.h index 64ddb16c1d..fb21603c75 100644 --- a/src_c/doc/font_doc.h +++ b/src_c/doc/font_doc.h @@ -29,6 +29,7 @@ #define DOC_FONT_FONT_METRICS "metrics(text, /) -> list\ngets the metrics for each character in the passed string" #define DOC_FONT_FONT_GETITALIC "get_italic() -> bool\ncheck if the text will be rendered italic" #define DOC_FONT_FONT_GETLINESIZE "get_linesize() -> int\nget the line space of the font text" +#define DOC_FONT_FONT_SETLINESIZE "set_linesize(linesize) -> int\nset the line space of the font text" #define DOC_FONT_FONT_GETHEIGHT "get_height() -> int\nget the height of the font" #define DOC_FONT_FONT_SETPOINTSIZE "set_point_size(size, /) -> int\nset the point size of the font" #define DOC_FONT_FONT_GETPOINTSIZE "get_point_size() -> int\nget the point size of the font" diff --git a/src_c/font.c b/src_c/font.c index 8530bcd3e1..3758825d1f 100644 --- a/src_c/font.c +++ b/src_c/font.c @@ -205,6 +205,29 @@ font_get_linesize(PyObject *self, PyObject *_null) return PyLong_FromLong(TTF_FontLineSkip(font)); } +static PyObject * +font_set_linesize(PyObject *self, PyObject *arg) +{ + if (!PgFont_GenerationCheck(self)) { + return RAISE_FONT_QUIT_ERROR(); + } + +#if SDL_TTF_VERSION_ATLEAST(2, 24, 0) + TTF_Font *font = PyFont_AsFont(self); + int linesize = PyLong_AsLong(arg); + if (linesize < 0 || PyErr_Occurred()) { + return RAISE(PyExc_ValueError, "linesize must be >= 0"); + } + TTF_SetFontLineSkip(font, linesize); + + Py_RETURN_NONE; +#else + return RAISE( + PyExc_NotImplementedError, + "TTF_SetFontLineSkip is not available in this version of SDL_ttf"); +#endif +} + static PyObject * _font_get_style_flag_as_py_bool(PyObject *self, int flag) { @@ -1053,6 +1076,7 @@ static PyMethodDef font_methods[] = { {"get_ascent", font_get_ascent, METH_NOARGS, DOC_FONT_FONT_GETASCENT}, {"get_linesize", font_get_linesize, METH_NOARGS, DOC_FONT_FONT_GETLINESIZE}, + {"set_linesize", font_set_linesize, METH_O, DOC_FONT_FONT_SETLINESIZE}, {"get_bold", font_get_bold, METH_NOARGS, DOC_FONT_FONT_GETBOLD}, {"set_bold", font_set_bold, METH_O, DOC_FONT_FONT_SETBOLD}, {"get_italic", font_get_italic, METH_NOARGS, DOC_FONT_FONT_GETITALIC}, diff --git a/test/font_test.py b/test/font_test.py index f008da2e69..cb613d494d 100644 --- a/test/font_test.py +++ b/test/font_test.py @@ -385,6 +385,24 @@ def test_get_linesize(self): self.assertTrue(isinstance(linesize, int)) self.assertTrue(linesize > 0) + def test_set_linesize(self): + f = pygame_font.Font(None, 20) + linesize = f.get_linesize() + + # check increasing linesize + f.set_linesize(linesize + 1) + self.assertEqual(f.get_linesize(), linesize + 1) + + # check random linesize + expected_linesizes = [30, 1, 22, 34, 5, 10, 0] + for expected_size in expected_linesizes: + f.set_linesize(expected_size) + self.assertEqual(f.get_linesize(), expected_size) + + # check invalid linesize + with self.assertRaises(ValueError): + f.set_linesize(-1) + def test_metrics(self): # Ensure bytes decoding works correctly. Can only compare results # with unicode for now. @@ -867,6 +885,7 @@ def test_font_method_should_raise_exception_after_quit(self): ("get_height", ()), ("get_italic", ()), ("get_linesize", ()), + ("set_linesize", (2,)), ("get_sized_descender", ()), ("get_underline", ()), ("metrics", ("any text",)), @@ -882,6 +901,7 @@ def test_font_method_should_raise_exception_after_quit(self): ("get_descent", ()), ("get_ascent", ()), ("get_linesize", ()), + ("set_linesize", (2,)), ("get_bold", ()), ("set_bold", (True,)), ("get_italic", ()),