@@ -72,6 +72,18 @@ static const char resourcefunc_name[] = "getResource";
7272#endif
7373static const char font_defaultname [] = "freesansbold.ttf" ;
7474
75+ #ifndef SDL_TTF_VERSION_ATLEAST
76+ /**
77+ * This macro will evaluate to true if compiled with SDL_ttf at least X.Y.Z.
78+ * New in SDL_ttf 2.0.15 so here it is in pygame for compat
79+ */
80+ #define SDL_TTF_VERSION_ATLEAST (X , Y , Z ) \
81+ ((SDL_TTF_MAJOR_VERSION >= X) && \
82+ (SDL_TTF_MAJOR_VERSION > X || SDL_TTF_MINOR_VERSION >= Y) && \
83+ (SDL_TTF_MAJOR_VERSION > X || SDL_TTF_MINOR_VERSION > Y || \
84+ SDL_TTF_PATCHLEVEL >= Z))
85+ #endif
86+
7587/*
7688 */
7789#if !SDL_TTF_VERSION_ATLEAST (2 , 0 , 15 )
@@ -393,6 +405,52 @@ font_setter_strikethrough(PyObject *self, PyObject *value, void *closure)
393405 return 0 ;
394406}
395407
408+ /* Implements getter for the align attribute */
409+ static PyObject *
410+ font_getter_align (PyObject * self , void * closure )
411+ {
412+ #if SDL_TTF_VERSION_ATLEAST (2 , 20 , 0 )
413+ TTF_Font * font = PyFont_AsFont (self );
414+ return PyLong_FromLong (TTF_GetFontWrappedAlign (font ));
415+ #else
416+ return RAISE (pgExc_SDLError ,
417+ "pygame.font not compiled with a new enough SDL_ttf version. "
418+ "Needs SDL_ttf 2.20.0 or above." );
419+ #endif
420+ }
421+
422+ /* Implements setter for the align attribute */
423+ static int
424+ font_setter_align (PyObject * self , PyObject * value , void * closure )
425+ {
426+ #if SDL_TTF_VERSION_ATLEAST (2 , 20 , 0 )
427+ TTF_Font * font = PyFont_AsFont (self );
428+
429+ DEL_ATTR_NOT_SUPPORTED_CHECK ("align" , value );
430+
431+ long val = PyLong_AsLong (value );
432+ if (val == -1 && PyErr_Occurred ()) {
433+ PyErr_SetString (PyExc_TypeError , "font.align should be an integer" );
434+ return -1 ;
435+ }
436+
437+ if (val < 0 || val > 2 ) {
438+ PyErr_SetString (
439+ pgExc_SDLError ,
440+ "font.align should be FONT_LEFT, FONT_CENTER, or FONT_RIGHT" );
441+ return -1 ;
442+ }
443+
444+ TTF_SetFontWrappedAlign (font , val );
445+ return 0 ;
446+ #else
447+ PyErr_SetString (pgExc_SDLError ,
448+ "pygame.font not compiled with a new enough SDL_ttf "
449+ "version. Needs SDL_ttf 2.20.0 or above." );
450+ return -1 ;
451+ #endif
452+ }
453+
396454/* Implements get_strikethrough() */
397455static PyObject *
398456font_get_strikethrough (PyObject * self , PyObject * args )
@@ -425,9 +483,10 @@ font_render(PyObject *self, PyObject *args)
425483 Uint8 rgba [] = {0 , 0 , 0 , 0 };
426484 SDL_Surface * surf ;
427485 const char * astring = "" ;
486+ int wraplength = 0 ;
428487
429- if (!PyArg_ParseTuple (args , "OpO|O " , & text , & antialias , & fg_rgba_obj ,
430- & bg_rgba_obj )) {
488+ if (!PyArg_ParseTuple (args , "OpO|Oi " , & text , & antialias , & fg_rgba_obj ,
489+ & bg_rgba_obj , & wraplength )) {
431490 return NULL ;
432491 }
433492
@@ -452,6 +511,11 @@ font_render(PyObject *self, PyObject *args)
452511 return RAISE_TEXT_TYPE_ERROR ();
453512 }
454513
514+ if (wraplength < 0 ) {
515+ return RAISE (PyExc_ValueError ,
516+ "wraplength parameter must be positive" );
517+ }
518+
455519 if (PyUnicode_Check (text )) {
456520 Py_ssize_t _size = -1 ;
457521 astring = PyUnicode_AsUTF8AndSize (text , & _size );
@@ -484,19 +548,34 @@ font_render(PyObject *self, PyObject *args)
484548#if !SDL_TTF_VERSION_ATLEAST (2 , 0 , 15 )
485549 if (utf_8_needs_UCS_4 (astring )) {
486550 return RAISE (PyExc_UnicodeError ,
487- "A Unicode character above '\\uFFFF' was found;"
551+ "a Unicode character above '\\uFFFF' was found;"
488552 " not supported with SDL_ttf version below 2.0.15" );
489553 }
490554#endif
491555
492556 if (antialias && bg_rgba_obj == Py_None ) {
557+ #if SDL_TTF_VERSION_ATLEAST (2 , 0 , 18 )
558+ surf = TTF_RenderUTF8_Blended_Wrapped (font , astring , foreg ,
559+ wraplength );
560+ #else
493561 surf = TTF_RenderUTF8_Blended (font , astring , foreg );
562+ #endif
494563 }
495564 else if (antialias ) {
565+ #if SDL_TTF_VERSION_ATLEAST (2 , 0 , 18 )
566+ surf = TTF_RenderUTF8_Shaded_Wrapped (font , astring , foreg , backg ,
567+ wraplength );
568+ #else
496569 surf = TTF_RenderUTF8_Shaded (font , astring , foreg , backg );
570+ #endif
497571 }
498572 else {
573+ #if SDL_TTF_VERSION_ATLEAST (2 , 0 , 18 )
574+ surf =
575+ TTF_RenderUTF8_Solid_Wrapped (font , astring , foreg , wraplength );
576+ #else
499577 surf = TTF_RenderUTF8_Solid (font , astring , foreg );
578+ #endif
500579 /* If an explicit background was provided and the rendering options
501580 resolve to Render_Solid, that needs to be explicitly handled. */
502581 if (surf != NULL && bg_rgba_obj != Py_None ) {
@@ -679,6 +758,8 @@ static PyGetSetDef font_getsets[] = {
679758 DOC_FONTUNDERLINE , NULL },
680759 {"strikethrough" , (getter )font_getter_strikethrough ,
681760 (setter )font_setter_strikethrough , DOC_FONTSTRIKETHROUGH , NULL },
761+ {"align" , (getter )font_getter_align , (setter )font_setter_align ,
762+ DOC_FONTALIGN , NULL },
682763 {NULL , NULL , NULL , NULL , NULL }};
683764
684765static PyMethodDef font_methods [] = {
0 commit comments