Skip to content

Add .point_size attribute modifier for fonts #1961

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Jul 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
43bcd5c
Add pointsize attribute modifier for fonts
andrewhong04 Mar 1, 2023
f16cf97
Add negative input handlers
andrewhong04 Mar 1, 2023
03b421a
Add unittests for pointsize
andrewhong04 Mar 1, 2023
9d5fc3c
Fix multiple bugs
andrewhong04 Mar 1, 2023
302790a
add ftfont handler
andrewhong04 Mar 3, 2023
1c4ab5f
pointsize -> point_size
andrewhong04 Mar 4, 2023
5b411c8
Merge remote-tracking branch 'upstream/main' into pointsize
andrewhong04 Apr 8, 2023
b783f93
Solve some merge conflicts
andrewhong04 Apr 8, 2023
b5cccff
Grammar fix
andrewhong04 Apr 8, 2023
8f75449
Clarified when font is None
andrewhong04 Apr 8, 2023
3e97df1
Load a valid font instead a default one
andrewhong04 Apr 8, 2023
058680b
Merge branch 'main' into pointsize
andrewhong04 May 17, 2023
3ebfb4b
Add return NULL after SDL error handling
andrewhong04 May 17, 2023
58b9852
Update documentation
andrewhong04 May 17, 2023
28ee0c4
Updated versionadded
andrewhong04 May 22, 2023
d437dcd
Forgot to return -1
andrewhong04 May 23, 2023
d5b5243
Clarify point_size
andrewhong04 Jul 13, 2023
e2cff08
Remove useless functions
andrewhong04 Jul 13, 2023
3c5aef1
2.3 -> 2.3.1 (woops)
andrewhong04 Jul 13, 2023
b928edd
Remove unsigned
andrewhong04 Jul 22, 2023
1af6125
Resolved conversations, improved tests and docs
Matiiss Jul 29, 2023
9130c13
Update font_doc.h
Matiiss Jul 29, 2023
e66cb3e
Merge branch 'main' into pointsize
Matiiss Jul 29, 2023
5b0fe2d
Update font_test.py
Matiiss Jul 29, 2023
3cc7d37
Merge branch 'pointsize' of https://github.com/novialriptide/pygame-c…
Matiiss Jul 29, 2023
7e2d65d
typo
Matiiss Jul 29, 2023
5fe0b1a
Fixes failing tests
Matiiss Jul 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions buildconfig/stubs/pygame/font.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Font:
strikethrough: bool
align: int
style_name: str
point_size: int
def __init__(self, filename: Optional[FileArg] = None, size: int = 20) -> None: ...
def render(
self,
Expand Down Expand Up @@ -62,5 +63,7 @@ class Font:
def get_descent(self) -> int: ...
def set_script(self, script_code: str) -> None: ...
def set_direction(self, direction: int) -> None: ...
def get_point_size(self) -> int: ...
def set_point_size(self, val: int) -> None: ...

FontType = Font
37 changes: 37 additions & 0 deletions docs/reST/ref/font.rst
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,18 @@ solves no longer exists, it will likely be removed in the future.

.. ## Font.align ##

.. attribute:: point_size

| :sl:`Gets or sets the font's point size`
| :sg:`point_size -> int`

Returns the point size of the font. Will not be accurate upon initializing
the font object when the font name is initalized as ``None``.

.. versionadded:: 2.3.1

.. ## Font.point_size ##

.. method:: render

| :sl:`draw text on a new Surface`
Expand Down Expand Up @@ -509,6 +521,31 @@ solves no longer exists, it will likely be removed in the future.

.. ## Font.get_height ##

.. method:: set_point_size

| :sl:`set the point size of the font`
| :sg:`set_point_size(size) -> int`

Sets the point size of the font, which is the value that was used to
initalize this font.

.. versionadded:: 2.3.1

.. ## Font.set_point_size ##

.. method:: get_point_size

| :sl:`get the point size of the font`
| :sg:`get_point_size() -> int`

Returns the point size of the font. Will not be accurate upon
initializing the font object when the font name is initalized
as ``None``.

.. versionadded:: 2.3.1

.. ## Font.get_point_size ##

.. method:: get_ascent

| :sl:`get the ascent of the font`
Expand Down
3 changes: 3 additions & 0 deletions src_c/doc/font_doc.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define DOC_FONT_FONT_UNDERLINE "underline -> bool\nGets or sets whether the font should be rendered with an underline."
#define DOC_FONT_FONT_STRIKETHROUGH "strikethrough -> bool\nGets or sets whether the font should be rendered with a strikethrough."
#define DOC_FONT_FONT_ALIGN "align -> int\nSet how rendered text is aligned when given a wrap length."
#define DOC_FONT_FONT_POINTSIZE "point_size -> int\nGets or sets the font's point size"
#define DOC_FONT_FONT_RENDER "render(text, antialias, color, bgcolor=None, wraplength=0) -> Surface\ndraw text on a new Surface"
#define DOC_FONT_FONT_SIZE "size(text) -> (width, height)\ndetermine the amount of space needed to render text"
#define DOC_FONT_FONT_SETUNDERLINE "set_underline(bool) -> None\ncontrol if text is rendered with an underline"
Expand All @@ -29,6 +30,8 @@
#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_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"
#define DOC_FONT_FONT_GETASCENT "get_ascent() -> int\nget the ascent of the font"
#define DOC_FONT_FONT_GETDESCENT "get_descent() -> int\nget the descent of the font"
#define DOC_FONT_FONT_SETSCRIPT "set_script(str) -> None\nset the script code for text shaping"
Expand Down
92 changes: 92 additions & 0 deletions src_c/font.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,92 @@ font_size(PyObject *self, PyObject *text)
return Py_BuildValue("(ii)", w, h);
}

static PyObject *
font_getter_point_size(PyFontObject *self, void *closure)
{
#if SDL_TTF_VERSION_ATLEAST(2, 0, 18)
return PyLong_FromLong(self->ptsize);
#else
PyErr_SetString(pgExc_SDLError,
"Incorrect SDL_TTF version (requires 2.0.18)");
return NULL;
#endif
}

static int
font_setter_point_size(PyFontObject *self, PyObject *value, void *closure)
{
#if SDL_TTF_VERSION_ATLEAST(2, 0, 18)
TTF_Font *font = PyFont_AsFont(self);
int val = PyLong_AsLong(value);

if (PyErr_Occurred() && val == -1) {
return -1;
}

if (val <= 0) {
PyErr_SetString(PyExc_ValueError,
"point_size cannot be equal to, or less than 0");
return -1;
}

if (TTF_SetFontSize(font, val) == -1) {
PyErr_SetString(pgExc_SDLError, SDL_GetError());
return -1;
}
self->ptsize = val;

return 0;
#else
PyErr_SetString(pgExc_SDLError,
"Incorrect SDL_TTF version (requires 2.0.18)");
return -1;
#endif
}

static PyObject *
font_get_ptsize(PyObject *self, PyObject *args)
{
#if SDL_TTF_VERSION_ATLEAST(2, 0, 18)
return PyLong_FromLong(((PyFontObject *)self)->ptsize);
#else
PyErr_SetString(pgExc_SDLError,
"Incorrect SDL_TTF version (requires 2.0.18)");
return NULL;
#endif
}

static PyObject *
font_set_ptsize(PyObject *self, PyObject *arg)
{
#if SDL_TTF_VERSION_ATLEAST(2, 0, 18)
TTF_Font *font = PyFont_AsFont(self);
int val = PyLong_AsLong(arg);

if (PyErr_Occurred() && val == -1) {
return NULL;
}

if (val <= 0) {
PyErr_SetString(PyExc_ValueError,
"point_size cannot be equal to, or less than 0");
return NULL;
}

if (TTF_SetFontSize(font, val) == -1) {
PyErr_SetString(pgExc_SDLError, SDL_GetError());
return NULL;
}
((PyFontObject *)self)->ptsize = val;

Py_RETURN_NONE;
#else
PyErr_SetString(pgExc_SDLError,
"Incorrect SDL_TTF version (requires 2.0.18)");
return NULL;
#endif
}

static PyObject *
font_getter_name(PyObject *self, void *closure)
{
Expand Down Expand Up @@ -892,6 +978,8 @@ static PyGetSetDef font_getsets[] = {
(setter)font_setter_strikethrough, DOC_FONT_FONT_STRIKETHROUGH, NULL},
{"align", (getter)font_getter_align, (setter)font_setter_align,
DOC_FONT_FONT_ALIGN, NULL},
{"point_size", (getter)font_getter_point_size,
(setter)font_setter_point_size, DOC_FONT_FONT_POINTSIZE, NULL},
{NULL, NULL, NULL, NULL, NULL}};

static PyMethodDef font_methods[] = {
Expand All @@ -911,6 +999,9 @@ static PyMethodDef font_methods[] = {
DOC_FONT_FONT_GETSTRIKETHROUGH},
{"set_strikethrough", font_set_strikethrough, METH_O,
DOC_FONT_FONT_SETSTRIKETHROUGH},
{"get_point_size", font_get_ptsize, METH_NOARGS,
DOC_FONT_FONT_GETPOINTSIZE},
{"set_point_size", font_set_ptsize, METH_O, DOC_FONT_FONT_SETPOINTSIZE},
{"metrics", font_metrics, METH_O, DOC_FONT_FONT_METRICS},
{"render", (PyCFunction)font_render, METH_VARARGS | METH_KEYWORDS,
DOC_FONT_FONT_RENDER},
Expand Down Expand Up @@ -1024,6 +1115,7 @@ font_init(PyFontObject *self, PyObject *args, PyObject *kwds)

Py_DECREF(obj);
self->font = font;
self->ptsize = fontsize;
self->ttf_init_generation = current_ttf_generation;

return 0;
Expand Down
1 change: 1 addition & 0 deletions src_c/include/pygame_font.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct TTF_Font;
typedef struct {
PyObject_HEAD TTF_Font *font;
PyObject *weakreflist;
int ptsize;
unsigned int ttf_init_generation;
} PyFontObject;
#define PyFont_AsFont(x) (((PyFontObject *)x)->font)
Expand Down
58 changes: 58 additions & 0 deletions test/font_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,64 @@ def test_size(self):

self.assertNotEqual(size, bsize)

def test_point_size_property(self):
if pygame_font.__name__ == "pygame.ftfont":
return # not a pygame.ftfont feature

pygame_font.init()
font_path = os.path.join(
os.path.split(pygame.__file__)[0], pygame_font.get_default_font()
)
f = pygame_font.Font(pathlib.Path(font_path), 25)

ttf_version = pygame_font.get_sdl_ttf_version()
if ttf_version < (2, 0, 18):
with self.assertRaises(pygame.error):
f.point_size = 25
with self.assertRaises(pygame.error):
f.point_size
return

self.assertEqual(25, f.point_size)
f.point_size = 10
self.assertEqual(10, f.point_size)
f.point_size += 23
self.assertEqual(33, f.point_size)
f.point_size -= 2
self.assertEqual(31, f.point_size)

def test_neg():
f.point_size = -500

def test_incorrect_type():
f.point_size = "15"

self.assertRaises(ValueError, test_neg)
self.assertRaises(TypeError, test_incorrect_type)

def test_point_size_method(self):
if pygame_font.__name__ == "pygame.ftfont":
return # not a pygame.ftfont feature

pygame_font.init()
font_path = os.path.join(
os.path.split(pygame.__file__)[0], pygame_font.get_default_font()
)
f = pygame_font.Font(pathlib.Path(font_path), 25)

ttf_version = pygame_font.get_sdl_ttf_version()
if ttf_version < (2, 0, 18):
self.assertRaises(pygame.error, f.get_point_size)
self.assertRaises(pygame.error, f.set_point_size, 25)
return

self.assertEqual(25, f.get_point_size())
f = pygame_font.Font(None, 25)
f.set_point_size(10)
self.assertEqual(10, f.get_point_size())
self.assertRaises(ValueError, f.set_point_size, -500)
self.assertRaises(TypeError, f.set_point_size, "15")

def test_font_name(self):
f = pygame_font.Font(None, 20)
self.assertEqual(f.name, "FreeSans")
Expand Down