Commits

Anonymous committed 9d6c5d4

Added FT constants module.
Modified get_metrics to use constants instead of named args.

Comments (0)

Files changed (7)

         sources = [
             "src/freetype/ft_mod.c",
             "src/freetype/ft_font.c",
-            "src/freetype/ft_wrap.c"
+            "src/freetype/ft_wrap.c",
         ],
         instheaders = ["src/freetype/pgfreetype.h"],
         docfile = "freetypebase.xml",
-        depends = ['freetype', 'SDL']),
+        depends = ['freetype']),
+
+    Module ("freetype.constants",
+        sources = [ "src/freetype/ft_constants.c" ],
+        depends = ['freetype']),
 
     ]
 

src/freetype/ft_constants.c

+/*
+  pygame - Python Game Library
+  Copyright (C) 2009 Vicent Marti
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Library General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Library General Public License for more details.
+
+  You should have received a copy of the GNU Library General Public
+  License along with this library; if not, write to the Free
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+#include "ft_mod.h"
+#include "ft_wrap.h"
+#include "pgfreetype.h"
+#include "pgtypes.h"
+#include "freetypebase_doc.h"
+
+#define DEC_CONST(x)  PyModule_AddIntConstant(module, #x, (int)FT_##x)
+
+#ifdef IS_PYTHON_3
+PyMODINIT_FUNC PyInit_constants (void)
+#else
+PyMODINIT_FUNC initconstants (void)
+#endif
+{
+    PyObject *module;
+
+#ifdef IS_PYTHON_3
+    static struct PyModuleDef _module = {
+        PyModuleDef_HEAD_INIT,
+        "constants",
+        "Pygame FreeType constants"
+            -1,
+        NULL, NULL, NULL, NULL, NULL
+    };
+
+    module = PyModule_Create (&_module);
+#else
+    module = Py_InitModule3 ("constants", NULL, "Pygame FreeType constants");
+#endif
+
+    if (!module)
+        goto fail;
+
+    DEC_CONST(STYLE_NORMAL);
+    DEC_CONST(STYLE_BOLD);
+    DEC_CONST(STYLE_ITALIC);
+    DEC_CONST(STYLE_UNDERLINE);
+
+    DEC_CONST(BBOX_EXACT);
+    DEC_CONST(BBOX_EXACT_GRIDFIT);
+    DEC_CONST(BBOX_PIXEL);
+    DEC_CONST(BBOX_PIXEL_GRIDFIT);
+    
+    MODINIT_RETURN(module);
+
+fail:
+    Py_XDECREF (module);
+    MODINIT_RETURN (NULL);
+}

src/freetype/ft_font.c

 static PyObject *
 _ftfont_getmetrics(PyObject *self, PyObject* args, PyObject *kwds)
 {
-    PyFreeTypeFont *font = (PyFreeTypeFont *)self;
-    PyObject *text, *list, *bpixel = NULL, *bgrid = NULL;
-    void *buf = NULL;
-    int isunicode = 0, istrue, char_stat;
-    int ptsize = -1, char_id, length, i, pixel_coords, grid_fitted;
-
-
+    /* keyword list */
     static char *kwlist[] = 
     { 
-        "text", "ptsize", "pixel_coords", "grid_fitted", NULL
+        "text", "ptsize", "bbmode", NULL
     };
 
+    PyFreeTypeFont *font = (PyFreeTypeFont *)self;
+
+    /* aux vars */
+    void *buf = NULL;
+    int char_id, length, i, isunicode = 0;
+
+    /* arguments */
+    PyObject *text, *list;
+    int ptsize = -1;
+    int bbmode = FT_BBOX_PIXEL_GRIDFIT;
+
+    /* grab freetype */
     FreeTypeInstance *ft;
     ASSERT_GRAB_FREETYPE(ft, NULL);
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iOO", kwlist,
-                &text, &ptsize, &bpixel, &bgrid))
+    /* parse args */
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|ii", kwlist,
+                &text, &ptsize, &bbmode))
         return NULL;
 
-    pixel_coords = 1;
-    grid_fitted = 1;
-
-    if (bpixel)
-        pixel_coords = PyObject_IsTrue(bpixel);
-
-    if (bgrid)
-        grid_fitted = PyObject_IsTrue(bgrid);
-
-
+    /* check ptsize */
     if (ptsize == -1)
     {
         if (font->default_ptsize == -1)
         ptsize = font->default_ptsize;
     }
 
-
+    /* check text */
     if (PyUnicode_Check(text))
     {
         buf = PyUnicode_AsUnicode(text);
     if (length == 0)
         Py_RETURN_NONE;
 
-    list = PyList_New(length);
-    if (!list)
-        return NULL;
+#define _GET_METRICS(_mt, _tuple_format) {              \
+    for (i = 0; i < length; i++)                        \
+    {                                                   \
+        _mt minx_##_mt, miny_##_mt;                     \
+        _mt maxx_##_mt, maxy_##_mt;                     \
+        _mt advance_##_mt;                              \
+                                                        \
+        if (isunicode) char_id = ((Py_UNICODE *)buf)[i];\
+        else char_id = ((char *)buf)[i];                \
+                                                        \
+        if (PGFT_GetMetrics(ft,                         \
+                (PyFreeTypeFont *)self, char_id,        \
+                ptsize, bbmode,                         \
+                &minx_##_mt, &maxx_##_mt,               \
+                &miny_##_mt, &maxy_##_mt,               \
+                &advance_##_mt) == 0)                   \
+        {                                               \
+            PyList_SetItem (list, i,                    \
+                    Py_BuildValue(_tuple_format,        \
+                        minx_##_mt, maxx_##_mt,         \
+                        miny_##_mt, maxy_##_mt,         \
+                        advance_##_mt));                \
+        }                                               \
+        else                                            \
+        {                                               \
+            Py_INCREF (Py_None);                        \
+            PyList_SetItem (list, i, Py_None);          \
+        }                                               \
+    }}
 
-    if (pixel_coords)
+    /* get metrics */
+    if (bbmode == FT_BBOX_EXACT || bbmode == FT_BBOX_EXACT_GRIDFIT)
     {
-        int minx_int, miny_int, maxx_int, maxy_int, advance_int;
-
-        for (i = 0; i < length; i++)
-        {
-            if (isunicode)
-                char_id = ((Py_UNICODE *)buf)[i];
-            else
-                char_id = ((char *)buf)[i];
-    
-            char_stat = PGFT_GetMetrics(ft, (PyFreeTypeFont *)self, char_id, 
-                    ptsize, 1, grid_fitted, 
-                    &minx_int, &maxx_int, &miny_int, &maxy_int, &advance_int);
-
-            if (char_stat == 0)
-            {
-                PyList_SetItem (list, i, Py_BuildValue("(iiiii)",
-                            minx_int, maxx_int, miny_int, maxy_int, advance_int));
-            }
-            else
-            {
-                Py_INCREF (Py_None);
-                PyList_SetItem (list, i, Py_None); 
-            }
-        }
+        list = PyList_New(length);
+        _GET_METRICS(float, "(fffff)");
+    }
+    else if (bbmode == FT_BBOX_PIXEL || bbmode == FT_BBOX_PIXEL_GRIDFIT)
+    {
+        list = PyList_New(length);
+        _GET_METRICS(int, "(iiiii)");
     }
     else
     {
-        float minx_fl, miny_fl, maxx_fl, maxy_fl, advance_fl;
+        PyErr_SetString(PyExc_ValueError, "Invalid bbox mode specified");
+        return NULL;
+    }
 
-        for (i = 0; i < length; i++)
-        {
-            if (isunicode)
-                char_id = ((Py_UNICODE *)buf)[i];
-            else
-                char_id = ((char *)buf)[i];
-    
-            char_stat = PGFT_GetMetrics(ft, (PyFreeTypeFont *)self, char_id, 
-                    ptsize, 0, grid_fitted, 
-                    &minx_fl, &maxx_fl, &miny_fl, &maxy_fl, &advance_fl);
-
-            if (char_stat == 0)
-            {
-                PyList_SetItem (list, i, Py_BuildValue("(fffff)",
-                            minx_fl, maxx_fl, miny_fl, maxy_fl, advance_fl));
-            }
-            else
-            {
-                Py_INCREF (Py_None);
-                PyList_SetItem (list, i, Py_None); 
-            }
-        }
-    }
+#undef _GET_METRICS
 
     return list;
 }

src/freetype/ft_wrap.c

 
 
 int PGFT_GetMetrics(FreeTypeInstance *ft, PyFreeTypeFont *font,
-        int character, int font_size, int pixel_coords, int grid_fitted,
+        int character, int font_size, int bbmode,
         void *minx, void *maxx, void *miny, void *maxy, void *advance)
 {
     FT_Error error;
     FTC_ScalerRec scale;
     FT_Glyph glyph;
-    FT_UInt bbmode;
 
     _PGFT_BuildScaler(font, &scale, font_size);
 
         return error;
     }
 
-    /*
-     * FT_GLYPH_BBOX_SUBPIXELS = 0,
-     * FT_GLYPH_BBOX_GRIDFIT   = 1,
-     * FT_GLYPH_BBOX_TRUNCATE  = 2,
-     * FT_GLYPH_BBOX_PIXELS    = 3
-     */
-    bbmode = (pixel_coords << 1) | grid_fitted;
-
     _PGFT_GetMetrics_INTERNAL(glyph, bbmode, minx, maxx, miny, maxy, advance);
 
-    if (pixel_coords == 0)
+    if (bbmode == FT_BBOX_EXACT || bbmode == FT_BBOX_EXACT_GRIDFIT)
     {
-        *(float *)minx = (float)(FP_266_FLOAT(*(int *)minx));
-        *(float *)miny = (float)(FP_266_FLOAT(*(int *)miny));
-        *(float *)maxx = (float)(FP_266_FLOAT(*(int *)maxx));
-        *(float *)maxy = (float)(FP_266_FLOAT(*(int *)maxy));
-        *(float *)advance = (float)(FP_1616_FLOAT(*(int *)advance));
+        *(float *)minx =    (FP_266_FLOAT(*(int *)minx));
+        *(float *)miny =    (FP_266_FLOAT(*(int *)miny));
+        *(float *)maxx =    (FP_266_FLOAT(*(int *)maxx));
+        *(float *)maxy =    (FP_266_FLOAT(*(int *)maxy));
+        *(float *)advance = (FP_1616_FLOAT(*(int *)advance));
     }
 
     return 0;

src/freetype/ft_wrap.h

             const FT_UInt16 *, int, int *, int *);
 
 int     PGFT_GetMetrics(FreeTypeInstance *ft, PyFreeTypeFont *font,
-            int character, int font_size, int pixel_coords, int grid_fitted,
+            int character, int font_size, int bbmode, 
             void *minx, void *maxx, void *miny, void *maxy, void *advance);
 
 #endif

src/freetype/pgfreetype.h

 extern "C" {
 #endif
 
+#define FT_STYLE_NORMAL     0x00
+#define FT_STYLE_BOLD		0x01
+#define FT_STYLE_ITALIC     0x02
+#define FT_STYLE_UNDERLINE  0x04
+
+/* Sane constant names */
+#define FT_BBOX_EXACT           FT_GLYPH_BBOX_SUBPIXELS
+#define FT_BBOX_EXACT_GRIDFIT   FT_GLYPH_BBOX_GRIDFIT
+#define FT_BBOX_PIXEL           FT_GLYPH_BBOX_TRUNCATE
+#define FT_BBOX_PIXEL_GRIDFIT   FT_GLYPH_BBOX_PIXELS
+
 #define PYGAME_FREETYPE_FIRSTSLOT 0
 #define PYGAME_FREETYPE_NUMSLOTS 0
 

test/freetype_font_test.py

 
 import pygame2
 import pygame2.freetype as ft
+import pygame2.freetype.constants as ft_const
 
 ft.init()
 
         for (ptsize, test_data) in TEST_VALUES_SANS.items():
             self.assertEqual(f.get_metrics('ABCDabcd', ptsize=ptsize), test_data)
 
+        metrics = f.get_metrics('ABCD', ptsize=24, bbmode=ft_const.BBOX_EXACT)
+        self.assertEqual(len(metrics), len('ABCD'))
+        self.assertTrue(isinstance(metrics[0], tuple))
+
+        for m in metrics[0]:
+            self.assertTrue(isinstance(m, float))
+
+
     def todo_test_pygame2_freetype_Font_get_size(self):
 
         # __doc__ (as of 2009-05-25) for pygame2.freetype.Font.get_size:
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.