Skip to content

Commit c7bf3e2

Browse files
committed
Adjust code to reviews from Robert Pfeiffer and Charlie Hayden
1 parent 52c51ba commit c7bf3e2

File tree

6 files changed

+90
-82
lines changed

6 files changed

+90
-82
lines changed

buildconfig/stubs/pygame/font.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ class Font:
5757
@point_size.setter
5858
def point_size(self, value: int) -> None: ...
5959
@property
60-
def outline_size(self) -> int: ...
61-
@outline_size.setter
62-
def outline_size(self, value: int) -> None: ...
60+
def outline_width(self) -> int: ...
61+
@outline_width.setter
62+
def outline_width(self, value: int) -> None: ...
6363
@property
6464
def outline_color(self) -> ColorValue: ...
6565
@outline_color.setter

docs/reST/ref/font.rst

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -306,23 +306,25 @@ solves no longer exists, it will likely be removed in the future.
306306

307307
.. ## Font.point_size ##
308308
309-
.. attribute:: outline_size
309+
.. attribute:: outline_width
310310

311-
| :sl:`Gets or sets the font's outline size`
312-
| :sg:`outline_size -> int`
311+
| :sl:`Gets or sets the font's outline radius size`
312+
| :sg:`outline_width -> int`
313313
314-
Returns the size of the outline.
314+
Gets or sets the radius size of the outline in pixels defaulting to 0.
315+
316+
If the value is set to 0, it shows no outline.
315317

316318
.. versionadded:: 2.5.0
317319

318-
.. ## Font.outline_size ##
320+
.. ## Font.outline_width ##
319321
320322
.. attribute:: outline_color
321323

322324
| :sl:`Gets or sets the font's outline color`
323-
| :sg:`outline_size -> RGB`
325+
| :sg:`outline_width -> RGB`
324326
325-
Returns the color of the outline.
327+
Gets or sets the color of the outline defaulting to (0, 0, 0, 255)
326328

327329
.. versionadded:: 2.5.0
328330

src_c/doc/font_doc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
#define DOC_FONT_FONT_STRIKETHROUGH "strikethrough -> bool\nGets or sets whether the font should be rendered with a strikethrough."
1818
#define DOC_FONT_FONT_ALIGN "align -> int\nSet how rendered text is aligned when given a wrap length."
1919
#define DOC_FONT_FONT_POINTSIZE "point_size -> int\nGets or sets the font's point size"
20-
#define DOC_FONT_FONT_OUTLINESIZE "outline_size -> int\nGets or sets the font's outline size"
21-
#define DOC_FONT_FONT_OUTLINECOLOR "outline_size -> RGB\nGets or sets the font's outline color"
20+
#define DOC_FONT_FONT_OUTLINEWIDTH "outline_width -> int\nGets or sets the font's outline radius size"
21+
#define DOC_FONT_FONT_OUTLINECOLOR "outline_width -> RGB\nGets or sets the font's outline color"
2222
#define DOC_FONT_FONT_RENDER "render(text, antialias, color, bgcolor=None, wraplength=0) -> Surface\ndraw text on a new Surface"
2323
#define DOC_FONT_FONT_SIZE "size(text, /) -> (width, height)\ndetermine the amount of space needed to render text"
2424
#define DOC_FONT_FONT_SETUNDERLINE "set_underline(bool, /) -> None\ncontrol if text is rendered with an underline"

src_c/font.c

Lines changed: 65 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@
3838
#include "structmember.h"
3939

4040
#define RAISE_TEXT_TYPE_ERROR() \
41-
RAISE(PyExc_TypeError, "text must be a unicode or bytes")
41+
RAISE(PyExc_TypeError, "text must be a unicode or bytes");
4242

4343
#define RAISE_FONT_QUIT_ERROR_RETURN(r) \
4444
RAISERETURN(pgExc_SDLError, \
45-
"Invalid font (font module quit since font created)", r);
45+
"Invalid font (font module quit since font created)", r)
4646

4747
#define RAISE_FONT_QUIT_ERROR() \
4848
RAISE(pgExc_SDLError, \
@@ -539,74 +539,46 @@ font_set_strikethrough(PyObject *self, PyObject *arg)
539539
}
540540

541541
static int
542-
_create_font_surface(TTF_Font *font, PyObject *text, int antialias,
542+
_create_font_surface(TTF_Font *font, const char *text, int antialias,
543543
SDL_Color foreg, SDL_Color backg, int draw_backg,
544544
int wraplength, SDL_Surface **dst_surf)
545545
{
546-
const char *astring = "";
547-
548-
if (!PyUnicode_Check(text) && !PyBytes_Check(text) && text != Py_None) {
549-
PyErr_Format(PyExc_TypeError, "text must be a unicode or bytes");
550-
return 0;
551-
}
552-
553546
if (wraplength < 0) {
554547
PyErr_Format(PyExc_ValueError,
555548
"The wraplength parameter must be positive.");
556549
return 0;
557550
}
558551

559-
if (PyUnicode_Check(text)) {
560-
Py_ssize_t _size = -1;
561-
astring = PyUnicode_AsUTF8AndSize(text, &_size);
562-
if (astring == NULL) {
563-
return 0; // exception already set.
564-
}
565-
if (strlen(astring) != (size_t)_size) {
566-
PyErr_Format(PyExc_ValueError,
567-
"A null character was found in the text.");
568-
return 0;
569-
}
570-
}
571-
572-
else if (PyBytes_Check(text)) {
573-
/* Bytes_AsStringAndSize with NULL arg for length emits
574-
ValueError if internal NULL bytes are present */
575-
if (PyBytes_AsStringAndSize(text, (char **)&astring, NULL) == -1) {
576-
return 0; // exception already set.
577-
}
578-
}
579-
580-
/* if text is Py_None, leave astring as a null byte to represent 0
552+
/* if text is Py_None, leave text as a null byte to represent 0
581553
length string */
582554

583-
if (strlen(astring) == 0) { /* special 0 string case */
555+
if (strlen(text) == 0) { /* special 0 string case */
584556
int height = TTF_FontHeight(font);
585557
*dst_surf = PG_CreateSurface(0, height, PG_PIXELFORMAT_XRGB8888);
586558
}
587559
else { /* normal case */
588560
if (antialias && !draw_backg) {
589561
#if SDL_TTF_VERSION_ATLEAST(2, 0, 18)
590-
*dst_surf = TTF_RenderUTF8_Blended_Wrapped(font, astring, foreg,
591-
wraplength);
562+
*dst_surf =
563+
TTF_RenderUTF8_Blended_Wrapped(font, text, foreg, wraplength);
592564
#else
593-
*dst_surf = TTF_RenderUTF8_Blended(font, astring, foreg);
565+
*dst_surf = TTF_RenderUTF8_Blended(font, text, foreg);
594566
#endif
595567
}
596568
else if (antialias) {
597569
#if SDL_TTF_VERSION_ATLEAST(2, 0, 18)
598-
*dst_surf = TTF_RenderUTF8_Shaded_Wrapped(font, astring, foreg,
599-
backg, wraplength);
570+
*dst_surf = TTF_RenderUTF8_Shaded_Wrapped(font, text, foreg, backg,
571+
wraplength);
600572
#else
601-
*dst_surf = TTF_RenderUTF8_Shaded(font, astring, foreg, backg);
573+
*dst_surf = TTF_RenderUTF8_Shaded(font, text, foreg, backg);
602574
#endif
603575
}
604576
else {
605577
#if SDL_TTF_VERSION_ATLEAST(2, 0, 18)
606578
*dst_surf =
607-
TTF_RenderUTF8_Solid_Wrapped(font, astring, foreg, wraplength);
579+
TTF_RenderUTF8_Solid_Wrapped(font, text, foreg, wraplength);
608580
#else
609-
*dst_surf = TTF_RenderUTF8_Solid(font, astring, foreg);
581+
*dst_surf = TTF_RenderUTF8_Solid(font, text, foreg);
610582
#endif
611583
/* If an explicit background was provided and the rendering options
612584
resolve to Render_Solid, that needs to be explicitly handled. */
@@ -641,7 +613,7 @@ font_render(PyObject *self, PyObject *args, PyObject *kwds)
641613
SDL_Surface *outline_surf = NULL;
642614
int wraplength = 0;
643615
TTF_Font *font = PyFont_AsFont(self);
644-
int outline_size = ((PyFontObject *)self)->outline_size;
616+
int outline_width = ((PyFontObject *)self)->outline_width;
645617
SDL_Color outline_color = ((PyFontObject *)self)->outline_color;
646618
Uint8 rgba[] = {0, 0, 0, 0};
647619

@@ -658,7 +630,6 @@ font_render(PyObject *self, PyObject *args, PyObject *kwds)
658630
return NULL;
659631
}
660632

661-
// 글꼴 생성
662633
if (!pg_RGBAFromObjEx(fg_rgba_obj, rgba, PG_COLOR_HANDLE_ALL)) {
663634
return 0; // exception already set
664635
}
@@ -678,23 +649,55 @@ font_render(PyObject *self, PyObject *args, PyObject *kwds)
678649
draw_backg = 0;
679650
}
680651

681-
if (!_create_font_surface(font, text, antialias, foreg, backg, draw_backg,
682-
wraplength, &surf)) {
652+
const char *astring = "";
653+
654+
if (!PyUnicode_Check(text) && !PyBytes_Check(text) && text != Py_None) {
655+
PyErr_Format(PyExc_TypeError, "text must be a unicode or bytes");
656+
return 0;
657+
}
658+
659+
if (PyUnicode_Check(text)) {
660+
Py_ssize_t _size = -1;
661+
astring = PyUnicode_AsUTF8AndSize(text, &_size);
662+
if (astring == NULL) {
663+
return 0; // exception already set.
664+
}
665+
if (strlen(astring) != (size_t)_size) {
666+
PyErr_Format(PyExc_ValueError,
667+
"A null character was found in the text.");
668+
return 0;
669+
}
670+
}
671+
672+
else if (PyBytes_Check(text)) {
673+
/* Bytes_AsStringAndSize with NULL arg for length emits
674+
ValueError if internal NULL bytes are present */
675+
if (PyBytes_AsStringAndSize(text, (char **)&astring, NULL) == -1) {
676+
return 0; // exception already set.
677+
}
678+
}
679+
680+
if (!_create_font_surface(font, astring, antialias, foreg, backg,
681+
draw_backg, wraplength, &surf)) {
683682
return NULL;
684683
}
685684

686685
SDL_Surface *filled_with_outline_surf = NULL;
687686

688-
if (outline_size > 0) {
689-
TTF_SetFontOutline(font, outline_size);
687+
if (outline_width > 0) {
688+
TTF_SetFontOutline(font, outline_width);
690689

691-
if (!_create_font_surface(font, text, antialias, outline_color, backg,
692-
draw_backg, wraplength, &outline_surf)) {
690+
if (!_create_font_surface(font, astring, antialias, outline_color,
691+
backg, draw_backg, wraplength,
692+
&outline_surf)) {
693693
return NULL;
694694
}
695695

696696
TTF_SetFontOutline(font, 0);
697697

698+
// Order for rendering the outline and the actual font matters.
699+
// Blitting foreground over outline results in smaller outline than
700+
// otherwise.
698701
filled_with_outline_surf = PG_CreateSurface(
699702
outline_surf->w, outline_surf->h, SDL_PIXELFORMAT_RGBA32);
700703

@@ -894,21 +897,21 @@ font_getter_style_name(PyObject *self, void *closure)
894897
}
895898

896899
static PyObject *
897-
font_getter_outline_size(PyFontObject *self, void *closure)
900+
font_getter_outline_width(PyFontObject *self, void *closure)
898901
{
899902
if (!PgFont_GenerationCheck(self))
900903
return RAISE_FONT_QUIT_ERROR();
901904

902905
#if SDL_TTF_VERSION_ATLEAST(2, 0, 12)
903-
return PyLong_FromLong(self->outline_size);
906+
return PyLong_FromLong(self->outline_width);
904907
#else
905908
return RAISE(pgExc_SDLError,
906909
"Incorrect SDL_TTF version (requires 2.0.12)");
907910
#endif
908911
}
909912

910913
static int
911-
font_setter_outline_size(PyFontObject *self, PyObject *value, void *closure)
914+
font_setter_outline_width(PyFontObject *self, PyObject *value, void *closure)
912915
{
913916
if (!PgFont_GenerationCheck(self)) {
914917
RAISE_FONT_QUIT_ERROR_RETURN(-1);
@@ -920,13 +923,18 @@ font_setter_outline_size(PyFontObject *self, PyObject *value, void *closure)
920923
if (PyErr_Occurred() && val == -1)
921924
return -1;
922925

926+
if (!PyLong_Check(value)) {
927+
PyErr_SetString(PyExc_TypeError, "outline_width cannot be a float");
928+
return -1;
929+
}
930+
923931
if (val < 0) {
924932
PyErr_SetString(PyExc_ValueError,
925-
"outline_size cannot be less than 0");
933+
"outline_width cannot be less than 0");
926934
return -1;
927935
}
928936

929-
self->outline_size = val;
937+
self->outline_width = val;
930938

931939
return 0;
932940
#else
@@ -1211,8 +1219,8 @@ static PyGetSetDef font_getsets[] = {
12111219
(setter)font_setter_point_size, DOC_FONT_FONT_POINTSIZE, NULL},
12121220
{"outline_color", (getter)font_getter_outline_color,
12131221
(setter)font_setter_outline_color, DOC_FONT_FONT_OUTLINECOLOR, NULL},
1214-
{"outline_size", (getter)font_getter_outline_size,
1215-
(setter)font_setter_outline_size, DOC_FONT_FONT_OUTLINESIZE, NULL},
1222+
{"outline_width", (getter)font_getter_outline_width,
1223+
(setter)font_setter_outline_width, DOC_FONT_FONT_OUTLINEWIDTH, NULL},
12161224
{NULL, NULL, NULL, NULL, NULL}};
12171225

12181226
static PyMethodDef font_methods[] = {
@@ -1356,7 +1364,7 @@ font_init(PyFontObject *self, PyObject *args, PyObject *kwds)
13561364
Py_DECREF(obj);
13571365
self->font = font;
13581366
self->ptsize = fontsize;
1359-
self->outline_size = 0;
1367+
self->outline_width = 0;
13601368
SDL_Color init_color = {0, 0, 0, SDL_ALPHA_OPAQUE};
13611369
self->outline_color = init_color;
13621370
self->ttf_init_generation = current_ttf_generation;

src_c/include/pygame_font.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,8 @@ typedef struct {
2929
PyObject_HEAD TTF_Font *font;
3030
PyObject *weakreflist;
3131
int ptsize;
32-
3332
SDL_Color outline_color;
34-
int outline_size;
35-
33+
int outline_width;
3634
unsigned int ttf_init_generation;
3735
} PyFontObject;
3836
#define PyFont_AsFont(x) (((PyFontObject *)x)->font)

test/font_test.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ def test_font_property_should_raise_exception_after_quit(self):
981981
("italic", True),
982982
("underline", True),
983983
("strikethrough", True),
984-
("outline_size", 5),
984+
("outline_width", 5),
985985
(
986986
"outline_color",
987987
(
@@ -1066,7 +1066,7 @@ def query(
10661066
underline=False,
10671067
strikethrough=False,
10681068
antialiase=False,
1069-
outline_size=0,
1069+
outline_width=0,
10701070
outline_color=(0, 0, 0),
10711071
):
10721072
if self.aborted:
@@ -1079,7 +1079,7 @@ def query(
10791079
screen.fill((255, 255, 255))
10801080
pygame.display.flip()
10811081
if not (
1082-
bold or italic or underline or strikethrough or antialiase or outline_size
1082+
bold or italic or underline or strikethrough or antialiase or outline_width
10831083
):
10841084
text = "normal"
10851085
else:
@@ -1094,14 +1094,14 @@ def query(
10941094
modes.append("strikethrough")
10951095
if antialiase:
10961096
modes.append("antialiased")
1097-
if outline_size:
1098-
modes.append("outline_size")
1097+
if outline_width:
1098+
modes.append("outline_width")
10991099
text = f"{'-'.join(modes)} (y/n):"
11001100
f.set_bold(bold)
11011101
f.set_italic(italic)
11021102
f.set_underline(underline)
11031103
f.set_strikethrough(strikethrough)
1104-
f.outline_size = outline_size
1104+
f.outline_width = outline_width
11051105
f.outline_color = outline_color
11061106
s = f.render(text, antialiase, (0, 0, 0))
11071107
screen.blit(s, (offset, y))
@@ -1142,11 +1142,11 @@ def test_strikethrough(self):
11421142
def test_antialiase(self):
11431143
self.assertTrue(self.query(antialiase=True))
11441144

1145-
def test_outline_size(self):
1146-
self.assertTrue(self.query(outline_size=1, outline_color=(255, 0, 255)))
1145+
def test_outline_width(self):
1146+
self.assertTrue(self.query(outline_width=1, outline_color=(255, 0, 255)))
11471147

1148-
def test_outline_size_huge(self):
1149-
self.assertTrue(self.query(outline_size=10, outline_color=(0, 0, 255)))
1148+
def test_outline_width_huge(self):
1149+
self.assertTrue(self.query(outline_width=10, outline_color=(0, 0, 255)))
11501150

11511151
def test_bold_antialiase(self):
11521152
self.assertTrue(self.query(bold=True, antialiase=True))

0 commit comments

Comments
 (0)