2
pygame - Python Game Library
3
Copyright (C) 2000-2001 Pete Shinners
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Library General Public
7
License as published by the Free Software Foundation; either
8
version 2 of the License, or (at your option) any later version.
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Library General Public License for more details.
15
You should have received a copy of the GNU Library General Public
16
License along with this library; if not, write to the Free
17
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
* font module for pygame
26
#define PYGAMEAPI_FONT_INTERNAL
33
staticforward PyTypeObject PyFont_Type;
34
static PyObject* PyFont_New(TTF_Font*);
35
#define PyFont_Check(x) ((x)->ob_type == &PyFont_Type)
37
static int font_initialized = 0;
38
static char* font_defaultname = "bluebold.ttf";
39
static char* font_defaultpath = NULL;
40
static PyObject* self_module = NULL;
42
static void font_autoquit(void)
51
PyMem_Free(font_defaultpath);
52
font_defaultpath = NULL;
57
static PyObject* font_autoinit(PyObject* self, PyObject* arg)
59
if(!PyArg_ParseTuple(arg, ""))
64
PyGame_RegisterQuit(font_autoquit);
67
return PyInt_FromLong(0);
72
char* path = PyModule_GetFilename(self_module);
79
char* end = strstr(path, "font.");
82
font_defaultpath = PyMem_Malloc(strlen(path) + 16);
85
strcpy(font_defaultpath, path);
86
end = strstr(font_defaultpath, "font.");
87
strcpy(end, font_defaultname);
94
font_defaultpath = PyMem_Malloc(strlen(font_defaultname) + 1);
96
strcpy(font_defaultpath, font_defaultname);
100
return PyInt_FromLong(font_defaultpath != NULL);
104
/*DOC*/ static char doc_quit[] =
105
/*DOC*/ "pygame.font.quit() -> none\n"
106
/*DOC*/ "uninitialize the font module\n"
108
/*DOC*/ "Manually uninitialize SDL's video subsystem. It is safe to call\n"
109
/*DOC*/ "this if font is currently not initialized.\n"
112
static PyObject* font_quit(PyObject* self, PyObject* arg)
114
if(!PyArg_ParseTuple(arg, ""))
123
/*DOC*/ static char doc_init[] =
124
/*DOC*/ "pygame.font.init() -> None\n"
125
/*DOC*/ "initialize the display module\n"
127
/*DOC*/ "Manually initialize the font module. Will raise an exception if\n"
128
/*DOC*/ "it cannot be initialized. It is safe to call this function if\n"
129
/*DOC*/ "font is currently initialized.\n"
132
static PyObject* font_init(PyObject* self, PyObject* arg)
137
if(!PyArg_ParseTuple(arg, ""))
140
result = font_autoinit(self, arg);
141
istrue = PyObject_IsTrue(result);
144
return RAISE(PyExc_SDLError, SDL_GetError());
151
/*DOC*/ static char doc_get_init[] =
152
/*DOC*/ "pygame.font.get_init() -> bool\n"
153
/*DOC*/ "get status of font module initialization\n"
155
/*DOC*/ "Returns true if the font module is currently intialized.\n"
158
static PyObject* get_init(PyObject* self, PyObject* arg)
160
if(!PyArg_ParseTuple(arg, ""))
163
return PyInt_FromLong(font_initialized);
170
/* font object methods */
172
/*DOC*/ static char doc_font_get_height[] =
173
/*DOC*/ "Font.get_height() -> int\n"
174
/*DOC*/ "average height of font glyph\n"
176
/*DOC*/ "Returns the average size of each glyph in the font.\n"
179
static PyObject* font_get_height(PyObject* self, PyObject* args)
181
TTF_Font* font = PyFont_AsFont(self);
183
if(!PyArg_ParseTuple(args, ""))
186
return PyInt_FromLong(TTF_FontHeight(font));
191
/*DOC*/ static char doc_font_get_descent[] =
192
/*DOC*/ "Font.get_descent() -> int\n"
193
/*DOC*/ "gets the font descent\n"
195
/*DOC*/ "Returns the descent for the font. The descent is the number of\n"
196
/*DOC*/ "pixels from the font baseline to the bottom of the font.\n"
199
static PyObject* font_get_descent(PyObject* self, PyObject* args)
201
TTF_Font* font = PyFont_AsFont(self);
203
if(!PyArg_ParseTuple(args, ""))
206
return PyInt_FromLong(TTF_FontDescent(font));
211
/*DOC*/ static char doc_font_get_ascent[] =
212
/*DOC*/ "Font.get_ascent() -> int\n"
213
/*DOC*/ "gets the font ascent\n"
215
/*DOC*/ "Returns the ascent for the font. The ascent is the number of\n"
216
/*DOC*/ "pixels from the font baseline to the top of the font.\n"
219
static PyObject* font_get_ascent(PyObject* self, PyObject* args)
221
TTF_Font* font = PyFont_AsFont(self);
223
if(!PyArg_ParseTuple(args, ""))
226
return PyInt_FromLong(TTF_FontAscent(font));
231
/*DOC*/ static char doc_font_get_linesize[] =
232
/*DOC*/ "Font.get_linesize() -> int\n"
233
/*DOC*/ "gets the font recommended linesize\n"
235
/*DOC*/ "Returns the linesize for the font. Each font comes with it's own\n"
236
/*DOC*/ "recommendation for the spacing number of pixels between each line\n"
237
/*DOC*/ "of the font.\n"
240
static PyObject* font_get_linesize(PyObject* self, PyObject* args)
242
TTF_Font* font = PyFont_AsFont(self);
244
if(!PyArg_ParseTuple(args, ""))
247
return PyInt_FromLong(TTF_FontLineSkip(font));
252
/*DOC*/ static char doc_font_get_bold[] =
253
/*DOC*/ "Font.get_bold() -> bool\n"
254
/*DOC*/ "status of the bold attribute\n"
256
/*DOC*/ "Get the current status of the font's bold attribute\n"
259
static PyObject* font_get_bold(PyObject* self, PyObject* args)
261
TTF_Font* font = PyFont_AsFont(self);
263
if(!PyArg_ParseTuple(args, ""))
266
return PyInt_FromLong((TTF_GetFontStyle(font)&TTF_STYLE_BOLD) != 0);
271
/*DOC*/ static char doc_font_set_bold[] =
272
/*DOC*/ "Font.set_bold(bool) -> None\n"
273
/*DOC*/ "assign the bold attribute\n"
275
/*DOC*/ "Enables or disables the bold attribute for the font. Making the\n"
276
/*DOC*/ "font bold does not work as well as you expect.\n"
279
static PyObject* font_set_bold(PyObject* self, PyObject* args)
281
TTF_Font* font = PyFont_AsFont(self);
284
if(!PyArg_ParseTuple(args, "i", &val))
287
style = TTF_GetFontStyle(font);
289
style |= TTF_STYLE_BOLD;
291
style &= ~TTF_STYLE_BOLD;
292
TTF_SetFontStyle(font, style);
299
/*DOC*/ static char doc_font_get_italic[] =
300
/*DOC*/ "Font.get_italic() -> bool\n"
301
/*DOC*/ "status of the italic attribute\n"
303
/*DOC*/ "Get the current status of the font's italic attribute\n"
306
static PyObject* font_get_italic(PyObject* self, PyObject* args)
308
TTF_Font* font = PyFont_AsFont(self);
310
if(!PyArg_ParseTuple(args, ""))
313
return PyInt_FromLong((TTF_GetFontStyle(font)&TTF_STYLE_ITALIC) != 0);
318
/*DOC*/ static char doc_font_set_italic[] =
319
/*DOC*/ "Font.set_italic(bool) -> None\n"
320
/*DOC*/ "assign the italic attribute\n"
322
/*DOC*/ "Enables or disables the italic attribute for the font.\n"
325
static PyObject* font_set_italic(PyObject* self, PyObject* args)
327
TTF_Font* font = PyFont_AsFont(self);
330
if(!PyArg_ParseTuple(args, "i", &val))
333
style = TTF_GetFontStyle(font);
335
style |= TTF_STYLE_ITALIC;
337
style &= ~TTF_STYLE_ITALIC;
338
TTF_SetFontStyle(font, style);
345
/*DOC*/ static char doc_font_get_underline[] =
346
/*DOC*/ "Font.get_underline() -> bool\n"
347
/*DOC*/ "status of the underline attribute\n"
349
/*DOC*/ "Get the current status of the font's underline attribute\n"
352
static PyObject* font_get_underline(PyObject* self, PyObject* args)
354
TTF_Font* font = PyFont_AsFont(self);
356
if(!PyArg_ParseTuple(args, ""))
359
return PyInt_FromLong((TTF_GetFontStyle(font)&TTF_STYLE_UNDERLINE) != 0);
364
/*DOC*/ static char doc_font_set_underline[] =
365
/*DOC*/ "Font.set_underline(bool) -> None\n"
366
/*DOC*/ "assign the underline attribute\n"
368
/*DOC*/ "Enables or disables the underline attribute for the font.\n"
371
static PyObject* font_set_underline(PyObject* self, PyObject* args)
373
TTF_Font* font = PyFont_AsFont(self);
376
if(!PyArg_ParseTuple(args, "i", &val))
379
style = TTF_GetFontStyle(font);
381
style |= TTF_STYLE_UNDERLINE;
383
style &= ~TTF_STYLE_UNDERLINE;
384
TTF_SetFontStyle(font, style);
391
/*DOC*/ static char doc_font_render[] =
392
/*DOC*/ "Font.render(text, antialias, fore_RGBA, [back_RGBA]) -> Surface\n"
393
/*DOC*/ "render text to a new image\n"
395
/*DOC*/ "Render the given text onto a new image surface. The given text\n"
396
/*DOC*/ "can be standard python text or unicode. Antialiasing will smooth\n"
397
/*DOC*/ "the edges of the font for a much cleaner look. The foreground\n"
398
/*DOC*/ "and background color are both RGBA, the alpha component is ignored\n"
399
/*DOC*/ "if given. If the background color is omitted, the text will have a\n"
400
/*DOC*/ "transparent background.\n"
402
/*DOC*/ "Note that font rendering is not thread safe, therefore only one\n"
403
/*DOC*/ "thread can render text at any given time.\n"
405
/*DOC*/ "Also, rendering smooth text with underlines will crash with SDL_ttf\n"
406
/*DOC*/ "less that version 2.0, be careful.\n"
409
static PyObject* font_render(PyObject* self, PyObject* args)
411
TTF_Font* font = PyFont_AsFont(self);
413
PyObject* text, *final;
414
PyObject* fg_rgba_obj, *bg_rgba_obj = NULL;
417
SDL_Color foreg, backg;
418
if(!PyArg_ParseTuple(args, "OiO|O", &text, &aa, &fg_rgba_obj, &bg_rgba_obj))
421
if(!RGBAFromObj(fg_rgba_obj, rgba))
422
return RAISE(PyExc_TypeError, "Invalid foreground RGBA argument");
423
foreg.r = rgba[0]; foreg.g = rgba[1]; foreg.b = rgba[2];
426
if(!RGBAFromObj(bg_rgba_obj, rgba))
427
return RAISE(PyExc_TypeError, "Invalid background RGBA argument");
428
backg.r = rgba[0]; backg.g = rgba[1]; backg.b = rgba[2];
431
if(PyUnicode_Check(text))
433
Py_UNICODE* string = PyUnicode_AsUnicode(text);
437
surf = TTF_RenderUNICODE_Blended(font, string, foreg);
439
surf = TTF_RenderUNICODE_Shaded(font, string, foreg, backg);
442
surf = TTF_RenderUNICODE_Solid(font, string, foreg);
444
else if(PyString_Check(text))
446
char* string = PyString_AsString(text);
450
surf = TTF_RenderText_Blended(font, string, foreg);
452
surf = TTF_RenderText_Shaded(font, string, foreg, backg);
455
surf = TTF_RenderText_Solid(font, string, foreg);
458
return RAISE(PyExc_TypeError, "text must be a string or unicode");
461
return RAISE(PyExc_SDLError, SDL_GetError());
463
if(!aa && bg_rgba_obj) /*turn off transparancy*/
465
SDL_SetColorKey(surf, 0, 0);
466
surf->format->palette->colors[0].r = backg.r;
467
surf->format->palette->colors[0].g = backg.g;
468
surf->format->palette->colors[0].b = backg.b;
471
final = PySurface_New(surf);
473
SDL_FreeSurface(surf);
479
/*DOC*/ static char doc_font_size[] =
480
/*DOC*/ "Font.size(text) -> width, height\n"
481
/*DOC*/ "size of rendered text\n"
483
/*DOC*/ "Computes the rendered size of the given text. The text can be\n"
484
/*DOC*/ "standard python text or unicode. Changing the bold and italic\n"
485
/*DOC*/ "attributes can change the size of the rendered text.\n"
488
static PyObject* font_size(PyObject* self, PyObject* args)
490
TTF_Font* font = PyFont_AsFont(self);
494
if(!PyArg_ParseTuple(args, "O", &text))
497
if(PyUnicode_Check(text))
499
Py_UNICODE* string = PyUnicode_AsUnicode(text);
500
TTF_SizeUNICODE(font, string, &w, &h);
502
else if(PyString_Check(text))
504
char* string = PyString_AsString(text);
505
TTF_SizeText(font, string, &w, &h);
508
return RAISE(PyExc_TypeError, "text must be a string or unicode");
510
return Py_BuildValue("(ii)", w, h);
515
static PyMethodDef fontobj_builtins[] =
517
{ "get_height", font_get_height, 1, doc_font_get_height },
518
{ "get_descent", font_get_descent, 1, doc_font_get_descent },
519
{ "get_ascent", font_get_ascent, 1, doc_font_get_ascent },
520
{ "get_linesize", font_get_linesize, 1, doc_font_get_linesize },
522
{ "get_bold", font_get_bold, 1, doc_font_get_bold },
523
{ "set_bold", font_set_bold, 1, doc_font_set_bold },
524
{ "get_italic", font_get_italic, 1, doc_font_get_italic },
525
{ "set_italic", font_set_italic, 1, doc_font_set_italic },
526
{ "get_underline", font_get_underline, 1, doc_font_get_underline },
527
{ "set_underline", font_set_underline, 1, doc_font_set_underline },
529
{ "render", font_render, 1, doc_font_render },
530
{ "size", font_size, 1, doc_font_size },
537
/*font object internals*/
539
static void font_dealloc(PyObject* self)
541
TTF_Font* font = PyFont_AsFont(self);
550
static PyObject* font_getattr(PyObject* self, char* attrname)
553
return Py_FindMethod(fontobj_builtins, self, attrname);
555
PyErr_SetString(PyExc_NameError, attrname);
560
/*DOC*/ static char doc_Font_MODULE[] =
561
/*DOC*/ "The font object is created only from pygame.font.Font(). Once a\n"
562
/*DOC*/ "font is created it's size and TTF file cannot be changed. The\n"
563
/*DOC*/ "Font objects are mainly used to render() text into a new Surface.\n"
564
/*DOC*/ "The Font objects also have a few states that can be set with\n"
565
/*DOC*/ "set_underline(bool), set_bold(bool), set_italic(bool). Each of\n"
566
/*DOC*/ "these functions contains an equivalent get_XXX() routine to find\n"
567
/*DOC*/ "the current state. There are also many routines to query the\n"
568
/*DOC*/ "dimensions of the text. The rendering functions work with both\n"
569
/*DOC*/ "normal python strings, as well as with unicode strings.\n"
572
static PyTypeObject PyFont_Type =
574
PyObject_HEAD_INIT(NULL)
577
sizeof(PyFontObject),
592
doc_Font_MODULE /* Documentation string */
597
/*font module methods*/
599
/*DOC*/ static char doc_Font[] =
600
/*DOC*/ "pygame.font.Font(file, size) -> Font\n"
601
/*DOC*/ "create a new font object\n"
603
/*DOC*/ "This will create a new font object. The given file must be a\n"
604
/*DOC*/ "filename to a TTF file. The font loader does not work with python\n"
605
/*DOC*/ "file-like objects. The size represents the height of the font in\n"
606
/*DOC*/ "pixels. The file argument can be 'None', which will use a plain\n"
607
/*DOC*/ "default font.\n"
610
static PyObject* Font(PyObject* self, PyObject* args)
617
if(!PyArg_ParseTuple(args, "Oi", &fileobj, &fontsize))
620
if(!font_initialized)
621
return RAISE(PyExc_SDLError, "font not initialized");
623
if(fileobj == Py_None)
625
if(!font_defaultpath)
626
return RAISE(PyExc_RuntimeError, "default font not found");
627
filename = font_defaultpath;
629
else if(PyString_Check(fileobj) || PyUnicode_Check(fileobj))
631
if(!PyArg_ParseTuple(args, "si", &filename, &fontsize))
635
return RAISE(PyExc_TypeError, "font name must be string or None");
637
Py_BEGIN_ALLOW_THREADS
638
font = TTF_OpenFont(filename, fontsize);
642
return RAISE(PyExc_RuntimeError, SDL_GetError());
644
fontobj = PyFont_New(font);
652
static PyMethodDef font_builtins[] =
654
{ "__PYGAMEinit__", font_autoinit, 1, doc_init },
655
{ "init", font_init, 1, doc_init },
656
{ "quit", font_quit, 1, doc_quit },
657
{ "get_init", get_init, 1, doc_get_init },
659
{ "Font", Font, 1, doc_Font },
666
static PyObject* PyFont_New(TTF_Font* font)
668
PyFontObject* fontobj;
671
return RAISE(PyExc_RuntimeError, "unable to load font.");
673
fontobj = PyObject_NEW(PyFontObject, &PyFont_Type);
675
fontobj->font = font;
677
return (PyObject*)fontobj;
682
/*DOC*/ static char doc_pygame_font_MODULE[] =
683
/*DOC*/ "The font module allows for rendering TrueType fonts into a new\n"
684
/*DOC*/ "Surface object. This module is optional and requires SDL_ttf as a\n"
685
/*DOC*/ "dependency. You may want to check for pygame.font to import and\n"
686
/*DOC*/ "initialize before attempting to use the module.\n"
688
/*DOC*/ "Most of the work done with fonts are done by using the actual\n"
689
/*DOC*/ "Font objects. The module by itself only has routines to\n"
690
/*DOC*/ "initialize the module and create Font objects with\n"
691
/*DOC*/ "pygame.font.Font().\n"
697
PyObject *module, *dict, *apiobj;
698
static void* c_api[PYGAMEAPI_FONT_NUMSLOTS];
700
PyFONT_C_API[0] = PyFONT_C_API[0]; /*clean an unused warning*/
702
PyType_Init(PyFont_Type);
704
/* create the module */
705
module = Py_InitModule3("font", font_builtins, doc_pygame_font_MODULE);
706
dict = PyModule_GetDict(module);
707
self_module = module;
709
PyDict_SetItemString(dict, "FontType", (PyObject *)&PyFont_Type);
711
/* export the c api */
712
c_api[0] = &PyFont_Type;
713
c_api[1] = PyFont_New;
714
c_api[2] = &font_initialized;
715
apiobj = PyCObject_FromVoidPtr(c_api, NULL);
716
PyDict_SetItemString(dict, PYGAMEAPI_LOCAL_ENTRY, apiobj);
719
/*imported needed apis*/
720
import_pygame_base();
721
import_pygame_surface();