Commits

Lenard Lindstrom committed 0aaf55f

freetype: some recent experiments; unit tests fail

Comments (0)

Files changed (8)

 static PyObject *_ft_autoinit(PyObject *self);
 static PyObject *_ft_get_default_resolution(PyObject *self);
 static PyObject *_ft_set_default_resolution(PyObject *self, PyObject *args);
+static PyObject *_ft_get_default_font(PyObject* self);
 
 /*
  * Constructor/init/destructor
 /*
  * Main methods
  */
-static PyObject *_ftfont_getsize(PyObject *self, PyObject *args, PyObject *kwds);
+static PyObject *_ftfont_getrect(PyObject *self, PyObject *args, PyObject *kwds);
 static PyObject *_ftfont_getmetrics(PyObject *self, PyObject *args, PyObject *kwds);
 static PyObject *_ftfont_render(PyObject *self, PyObject *args, PyObject *kwds);
 static PyObject *_ftfont_render_raw(PyObject *self, PyObject *args, PyObject *kwds);
+static PyObject *_ftfont_getsizedascender(PyFreeTypeFont *self, PyObject *args);
+static PyObject *_ftfont_getsizeddescender(PyFreeTypeFont *self, PyObject *args);
+static PyObject *_ftfont_getsizedheight(PyFreeTypeFont *self, PyObject *arg);
+static PyObject *_ftfont_getsizedglyphheight(PyFreeTypeFont *self, PyObject *args);
+static PyObject *_ftfont_gettransform(PyFreeTypeFont *self);
+static PyObject *_ftfont_settransform(PyFreeTypeFont *self, PyObject *args);
+static PyObject *_ftfont_deletetransform(PyFreeTypeFont *self);
 
 /* static PyObject *_ftfont_copy(PyObject *self); */
 
 static PyObject *_ftfont_getstyle(PyObject *self, void *closure);
 static int _ftfont_setstyle(PyObject *self, PyObject *value, void *closure);
 static PyObject *_ftfont_getheight(PyObject *self, void *closure);
+static PyObject *_ftfont_getascender(PyObject *self, void *closure);
+static PyObject *_ftfont_getdescender(PyObject *self, void *closure);
 static PyObject *_ftfont_getname(PyObject *self, void *closure);
 static PyObject *_ftfont_getpath(PyObject *self, void *closure);
 static PyObject *_ftfont_getfixedwidth(PyObject *self, void *closure);
         METH_VARARGS,
         DOC_PYGAMEFREETYPESETDEFAULTRESOLUTION
     },
+    {
+        "get_default_font",
+        (PyCFunction) _ft_get_default_font,
+        METH_NOARGS,
+        DOC_PYGAMEFREETYPEGETDEFAULTFONT
+    },
 
-    { NULL, NULL, 0, NULL },
+    { NULL, NULL, 0, NULL }
 };
 
 
 static PyMethodDef _ftfont_methods[] = 
 {
     {
-        "get_size", 
-        (PyCFunction) _ftfont_getsize,
+        "get_sized_height", 
+        (PyCFunction) _ftfont_getsizedheight,
+        METH_VARARGS,
+        DOC_FONTGETSIZEDHEIGHT
+    },
+    {
+        "get_sized_ascender",
+        (PyCFunction) _ftfont_getsizedascender,
+        METH_VARARGS,
+        DOC_FONTGETSIZEDASCENDER
+    },
+    {
+        "get_sized_descender",
+        (PyCFunction) _ftfont_getsizeddescender,
+        METH_VARARGS,
+        DOC_FONTGETSIZEDDESCENDER
+    },
+    {
+        "get_sized_glyph_height", 
+        (PyCFunction) _ftfont_getsizedglyphheight,
+        METH_VARARGS,
+        DOC_FONTGETSIZEDGLYPHHEIGHT
+    },
+    {
+        "get_rect", 
+        (PyCFunction) _ftfont_getrect,
         METH_VARARGS | METH_KEYWORDS,
-        DOC_FONTGETSIZE
+        DOC_FONTGETRECT
     },
     {
         "get_metrics", 
         METH_VARARGS | METH_KEYWORDS,
         DOC_FONTRENDERRAW
     },
+    { 
+        "get_transform", 
+        (PyCFunction)_ftfont_gettransform, 
+        METH_NOARGS,
+        DOC_FONTGETTRANSFORM
+    },
+    { 
+        "set_transform", 
+        (PyCFunction)_ftfont_settransform, 
+        METH_VARARGS,
+        DOC_FONTSETTRANSFORM
+    },
+    { 
+        "delete_transform", 
+        (PyCFunction)_ftfont_deletetransform, 
+        METH_NOARGS,
+        DOC_FONTDELETETRANSFORM
+    },
 
     { NULL, NULL, 0, NULL }
 };
         NULL,
         DOC_FONTHEIGHT,
         NULL
+    }, 
+    { 
+        "ascender",
+        _ftfont_getascender,  
+        NULL,
+        DOC_FONTASCENDER,
+        NULL
+    },
+    { 
+        "descender",
+        _ftfont_getdescender,  
+        NULL,
+        DOC_FONTASCENDER,
+        NULL
     },
     { 
         "name", 
         obj->antialias = 1;
         obj->kerning = 0;
         obj->ucs4 = 0;
-    obj->origin = 0;
-    }
+        obj->origin = 0;
+        obj->do_transform = 0;
+        obj->transform.xx = 0x00010000;
+        obj->transform.xy = 0x00000000;
+        obj->transform.yx = 0x00000000;
+        obj->transform.yy = 0x00010000;
+   }
     return (PyObject *)obj;
 }
  
 
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iiIiiIi", kwlist, 
                                      &file, &ptsize, &font_style, &face_index,
-                                     &vertical, &ucs4, &resolution,
-                     &origin))
+                                     &vertical, &ucs4, &resolution, &origin))
         return -1;
 
     original_file = file;
         }
     }
 
-    file = RWopsEncodeFilePath(file, PyExc_ValueError);
+    file = RWopsEncodeFilePath(file, NULL);
     if (file == NULL)
     {
         return -1;
         {
             goto end;
         }
-    if (PyUnicode_Check(original_file))
+
+        if (PyUnicode_Check(original_file))
         {
             /* Make sure to save a pure Unicode object to prevent possible
              * cycles from a derived class. This means no tp_traverse or
         else
         {
             font->path = PyUnicode_FromEncodedObject(file, "raw_unicode_escape",
-                             "replace");
+                                                     "replace");
         }
     }
     else
                 Py_DECREF(str);
             }
         }
-    else if (PyUnicode_Check(path))
+        else if (PyUnicode_Check(path))
         {
             /* Make sure to save a pure Unicode object to prevent possible
              * cycles from a derived class. This means no tp_traverse or
         }
         else if (Bytes_Check(path))
         {
-            font->path = PyUnicode_FromEncodedObject(file,
+            font->path = PyUnicode_FromEncodedObject(path,
                                                "unicode_escape", "replace");
         }
         else
 }
 
 PyObject *
+_ftfont_getascender(PyObject *self, void *closure)
+{
+    FreeTypeInstance *ft;
+    long height;
+    ASSERT_GRAB_FREETYPE(ft, NULL);
+
+    ASSERT_SELF_IS_ALIVE(self);
+    height = PGFT_Face_GetAscender(ft, (PyFreeTypeFont *)self);
+    if (!height && PyErr_Occurred())
+    {
+        return NULL;
+    }
+    return PyInt_FromLong(height);
+}
+
+PyObject *
+_ftfont_getdescender(PyObject *self, void *closure)
+{
+    FreeTypeInstance *ft;
+    long height;
+    ASSERT_GRAB_FREETYPE(ft, NULL);
+
+    ASSERT_SELF_IS_ALIVE(self);
+    height = PGFT_Face_GetDescender(ft, (PyFreeTypeFont *)self);
+    if (!height && PyErr_Occurred())
+    {
+        return NULL;
+    }
+    return PyInt_FromLong(height);
+}
+
+PyObject *
 _ftfont_getheight(PyObject *self, void *closure)
 {
     FreeTypeInstance *ft;
 
     ASSERT_SELF_IS_ALIVE(self);
     height = PGFT_Face_GetHeight(ft, (PyFreeTypeFont *)self);
-    return height >= 0 ? PyInt_FromLong(height) : NULL;
+    if (!height && PyErr_Occurred())
+    {
+        return NULL;
+    }
+    return PyInt_FromLong(height);
 }
 
 PyObject *
  * MAIN METHODS
  ****************************************************/
 PyObject *
-_ftfont_getsize(PyObject *self, PyObject *args, PyObject *kwds)
+_ftfont_getrect(PyObject *self, PyObject *args, PyObject *kwds)
 {
 /* MODIFIED
  */
     PyFreeTypeFont *font = (PyFreeTypeFont *)self;
     PyObject *textobj;
     PGFT_String *text;
-    PyObject *rtuple = NULL;
+    PyObject *rectobj = NULL;
     FT_Error error;
     int ptsize = -1;
-    int width, height;
+    SDL_Rect r;
 
     FontRenderMode render;
     int rotation = 0;
         return NULL;
     }
 
-    error = PGFT_GetTextSize(ft, font, &render, text, &width, &height);
+    error = PGFT_GetTextRect(ft, font, &render, text, &r);
     PGFT_FreeString(text);
 
     if (!error)
-        rtuple = Py_BuildValue ("ii", width, height);
+        rectobj = PyRect_New(&r);
 
-    return rtuple;
+    return rectobj;
 }
 
 PyObject *
     Py_ssize_t length = PGFT_String_GET_LENGTH(text);
     PGFT_char *data = PGFT_String_GET_DATA(text);
     PyObject *list, *item;
+    FT_UInt gindex;
     long minx, miny;
     long maxx, maxy;
     double advance_x;
     }
     for (i = 0; i < length; ++i) {
         if (PGFT_GetMetrics(ft, font, data[i], render,
-                &minx, &maxx, &miny, &maxy,
+                &gindex, &minx, &maxx, &miny, &maxy,
                 &advance_x, &advance_y) == 0) {
-            item = Py_BuildValue("lllldd", minx, maxx, miny, maxy,
-                 advance_x, advance_y);
+            if (gindex == 0)
+            {
+                Py_INCREF(Py_None);
+                item = Py_None;
+            }
+            else
+            {
+                item = Py_BuildValue("lllldd", minx, maxx, miny, maxy,
+                                     advance_x, advance_y);
+            }
             if (!item) {
                 Py_DECREF(list);
                 return NULL;
     return list;
 }
 
+static PyObject *
+_ftfont_getsizedascender(PyFreeTypeFont *self, PyObject *args)
+{
+    int pt_size = -1;
+    long value;
+
+    FreeTypeInstance *ft;
+    ASSERT_GRAB_FREETYPE(ft, NULL);
+
+    if (!PyArg_ParseTuple(args, "|i", &pt_size))
+    {
+        return NULL;
+    }
+    
+    if (pt_size == -1)
+    {
+        if (self->ptsize == -1)
+        {
+            RAISE(PyExc_ValueError,
+                  "No font point size specified"
+                  " and no default font size in typeface");
+            return NULL;
+        }
+
+        pt_size = self->ptsize;
+    }
+
+    if (pt_size <= 0)
+    {
+        RAISE(PyExc_ValueError, "Invalid point size for font.");
+        return NULL;
+    }
+    value = (long)PGFT_Face_GetAscenderSized(ft, self, (FT_UInt16)pt_size);
+    if (!value && PyErr_Occurred())
+    {
+        return NULL;
+    }
+    return PyInt_FromLong(value);
+}
+
+static PyObject *
+_ftfont_getsizeddescender(PyFreeTypeFont *self, PyObject *args)
+{
+    int pt_size = -1;
+    long value;
+
+    FreeTypeInstance *ft;
+    ASSERT_GRAB_FREETYPE(ft, NULL);
+
+    if (!PyArg_ParseTuple(args, "|i", &pt_size))
+    {
+        return NULL;
+    }
+    
+    if (pt_size == -1)
+    {
+        if (self->ptsize == -1)
+        {
+            RAISE(PyExc_ValueError,
+                  "No font point size specified"
+                  " and no default font size in typeface");
+            return NULL;
+        }
+
+        pt_size = self->ptsize;
+    }
+
+    if (pt_size <= 0)
+    {
+        RAISE(PyExc_ValueError, "Invalid point size for font.");
+        return NULL;
+    }
+    value = (long)PGFT_Face_GetDescenderSized(ft, self, (FT_UInt16)pt_size);
+    if (!value && PyErr_Occurred())
+    {
+        return NULL;
+    }
+    return PyInt_FromLong(value);
+}
+
+static PyObject *
+_ftfont_getsizedheight(PyFreeTypeFont *self, PyObject *args)
+{
+    int pt_size = -1;
+    long value;
+
+    FreeTypeInstance *ft;
+    ASSERT_GRAB_FREETYPE(ft, NULL);
+
+    if (!PyArg_ParseTuple(args, "|i", &pt_size))
+    {
+        return NULL;
+    }
+    
+    if (pt_size == -1)
+    {
+        if (self->ptsize == -1)
+        {
+            RAISE(PyExc_ValueError,
+                  "No font point size specified"
+                  " and no default font size in typeface");
+            return NULL;
+        }
+
+        pt_size = self->ptsize;
+    }
+
+    if (pt_size <= 0)
+    {
+        RAISE(PyExc_ValueError, "Invalid point size for font.");
+        return NULL;
+    }
+    value = (long)PGFT_Face_GetHeightSized(ft, self, (FT_UInt16)pt_size);
+    if (!value && PyErr_Occurred())
+    {
+        return NULL;
+    }
+    return PyInt_FromLong(value);
+}
+
+static PyObject *
+_ftfont_getsizedglyphheight(PyFreeTypeFont *self, PyObject *args)
+{
+    int pt_size = -1;
+    long value;
+
+    FreeTypeInstance *ft;
+    ASSERT_GRAB_FREETYPE(ft, NULL);
+
+    if (!PyArg_ParseTuple(args, "|i", &pt_size))
+    {
+        return NULL;
+    }
+    
+    if (pt_size == -1)
+    {
+        if (self->ptsize == -1)
+        {
+            RAISE(PyExc_ValueError,
+                  "No font point size specified"
+                  " and no default font size in typeface");
+            return NULL;
+        }
+
+        pt_size = self->ptsize;
+    }
+
+    if (pt_size <= 0)
+    {
+        RAISE(PyExc_ValueError, "Invalid point size for font.");
+        return NULL;
+    }
+    value = (long)PGFT_Face_GetGlyphHeightSized(ft, self, (FT_UInt16)pt_size);
+    if (!value && PyErr_Occurred())
+    {
+        return NULL;
+    }
+    return PyInt_FromLong(value);
+}
+
 PyObject *
 _ftfont_render_raw(PyObject *self, PyObject *args, PyObject *kwds)
 {
 
     /* output arguments */
     PyObject *rtuple = NULL;
-    int width, height;
-    FontMetrics metrics;
+    SDL_Rect r;
     PyObject *rect_obj;
 
     FontColor fg_color;
         SDL_Surface *r_surface = NULL;
 
         r_surface = PGFT_Render_NewSurface(ft, font, &render, text,
-                &fg_color, bg_color_obj ? &bg_color : NULL, 
-                &width, &height);
+                        &fg_color, bg_color_obj ? &bg_color : NULL, &r);
         PGFT_FreeString(text);
 
         if (!r_surface)
         rcode = PGFT_Render_ExistingSurface(ft, font, &render, 
                         text, surface, xpos, ypos,
                         &fg_color,
-                        bg_color_obj ? &bg_color : NULL,
-                        &width, &height, &metrics);
-        PGFT_FreeString(text);
+                        bg_color_obj ? &bg_color : NULL, &r);
+         PGFT_FreeString(text);
         if (rcode)
         {
             Py_DECREF(surface_obj);
             return NULL;
         }
-    xpos = PGFT_TRUNC(PGFT_CEIL(metrics.bearing_rotated.x));
-    ypos = PGFT_TRUNC(PGFT_CEIL(metrics.bearing_rotated.y));
     }
     else
     {
                             " got type %.1024s",
                             Py_TYPE(dest)->tp_name);
     }
-    rect_obj = PyRect_New4(xpos, ypos, width, height);
+    rect_obj = PyRect_New(&r);
     if (rect_obj != NULL)
     {
         rtuple = PyTuple_Pack(2, surface_obj, rect_obj);
 #endif // HAVE_PYGAME_SDL_VIDEO
 }
 
+static PyObject *
+_ftfont_gettransform(PyFreeTypeFont *self)
+{
+    const double scale_factor = 1.5259e-5; /* 1 / 65536.0 */ 
+
+    if (!self->do_transform)
+    {
+        Py_RETURN_NONE;
+    }
+    return Py_BuildValue("dddd",
+                         self->transform.xx * scale_factor,
+                         self->transform.xy * scale_factor,
+                         self->transform.yx * scale_factor,
+                         self->transform.yy * scale_factor);
+}
+
+static PyObject *
+_ftfont_settransform(PyFreeTypeFont *self, PyObject *args)
+{
+    const double scale_factor = 65536.0;
+    double xx;
+    double xy;
+    double yx;
+    double yy;
+
+    if (!PyArg_ParseTuple(args, "dddd", &xx, &xy, &yx, &yy))
+    {
+        return NULL;
+    }
+    /* Sanity check: only accept numbers between -2.0 and 2.0 inclusive */
+    if (xx < -2.0 || xx > 2.0 || xy < -2.0 || xy > 2.0 ||
+        yx < -2.0 || yx > 2.0 || yy < -2.0 || yy > 2.0)
+    {
+        PyErr_SetString(PyExc_ValueError,
+                        "received a value outside range [-2.0,2.0]");
+        return NULL;
+    }
+    self->transform.xx = (FT_Fixed)(xx * scale_factor);  
+    self->transform.xy = (FT_Fixed)(xy * scale_factor);
+    self->transform.yx = (FT_Fixed)(yx * scale_factor);
+    self->transform.yy = (FT_Fixed)(yy * scale_factor);
+    self->do_transform = 1;
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+_ftfont_deletetransform(PyFreeTypeFont *self)
+{
+    self->do_transform = 0;
+    self->transform.xx = 0x00010000;
+    self->transform.xy = 0x00000000;
+    self->transform.yx = 0x00000000;
+    self->transform.yy = 0x00010000;
+    Py_RETURN_NONE;
+}
+
 /****************************************************
  * C API CALLS
  ****************************************************/
     return PyBool_FromLong((FREETYPE_MOD_STATE (self)->freetype != NULL));
 }
 
+static PyObject*
+_ft_get_default_font(PyObject* self)
+{
+    return Text_FromUTF8(DEFAULT_FONT_NAME);
+}
+
 #if PY3
 static int
 _ft_traverse (PyObject *mod, visitproc visit, void *arg)
 #define FT_RFLAG_VERTICAL       (1 << 2)
 #define FT_RFLAG_HINTED         (1 << 3)
 #define FT_RFLAG_KERNING        (1 << 4)
+#define FT_RFLAG_TRANSFORM      (1 << 5)
 #define FT_RFLAG_DEFAULTS       (FT_RFLAG_NONE | FT_RFLAG_HINTED)
 
 
     FT_Byte ucs4;
     FT_UInt resolution;
     FT_Byte origin;
+    FT_Byte do_transform;
+    FT_Matrix transform;
 
     void *_internals;
 } PyFreeTypeFont;

src/freetype/ft_cache.c

 
 /* The key is the UTF character, point size (unsigned short),
  * style flags (unsigned short), render flags (unsigned short),
- * and rotation (in whole degrees, unsigned short). Byte order
- * is little-endian.
+ * and rotation (in whole degrees, unsigned short), transform.xx,
+ * transform.xy, transform.yx, transform.yy. Byte order is little-endian.
  */
-#define MINKEYLEN (sizeof(PGFT_char) + 2 + 2 + 2 + 2)
+#define MINKEYLEN (sizeof(PGFT_char) + 2 + 2 + 2 + 2 + 4 + 4 + 4 + 4)
 #define KEYLEN ((MINKEYLEN + 3) & 0xFFFC)
 
 typedef union __cachenodekey
     key->bytes[i++] = (FT_Byte)((render->render_flags & rflag_mask) >> 8);
     key->bytes[i++] = (FT_Byte)rot;
     key->bytes[i++] = (FT_Byte)(rot >> 8);
+    key->bytes[i++] = (FT_Byte)render->transform.xx;
+    key->bytes[i++] = (FT_Byte)(render->transform.xx >> 8);
+    key->bytes[i++] = (FT_Byte)(render->transform.xx >> 16);
+    key->bytes[i++] = (FT_Byte)(render->transform.xx >> 24);
+    key->bytes[i++] = (FT_Byte)render->transform.xy;
+    key->bytes[i++] = (FT_Byte)(render->transform.xy >> 8);
+    key->bytes[i++] = (FT_Byte)(render->transform.xy >> 16);
+    key->bytes[i++] = (FT_Byte)(render->transform.xy >> 24);
+    key->bytes[i++] = (FT_Byte)render->transform.yx;
+    key->bytes[i++] = (FT_Byte)(render->transform.yx >> 8);
+    key->bytes[i++] = (FT_Byte)(render->transform.yx >> 16);
+    key->bytes[i++] = (FT_Byte)(render->transform.yx >> 24);
+    key->bytes[i++] = (FT_Byte)render->transform.yy;
+    key->bytes[i++] = (FT_Byte)(render->transform.yy >> 8);
+    key->bytes[i++] = (FT_Byte)(render->transform.yy >> 16);
+    key->bytes[i++] = (FT_Byte)(render->transform.yy >> 24);
 }
 
 static int

src/freetype/ft_render.c

     while (angle < 0) angle += 360;
     mode->rotation_angle = PGFT_INT_TO_16(angle);
 
+    if (font->do_transform)
+        mode->render_flags |= FT_RFLAG_TRANSFORM;
+    mode->transform = font->transform;
+
     return 0;
 }
 
 int PGFT_Render_ExistingSurface(
     FreeTypeInstance *ft, PyFreeTypeFont *font,
     const FontRenderMode *render, PGFT_String *text, SDL_Surface *surface,
-    int x, int y, FontColor *fgcolor, FontColor *bgcolor,
-    int *_width, int *_height, FontMetrics *metrics)
+    int x, int y, FontColor *fgcolor, FontColor *bgcolor, SDL_Rect *r)
 {
     static const FontRenderPtr __SDLrenderFuncs[] =
     {
     if (PGFT_String_GET_LENGTH(text) == 0)
     {
         /* No rendering */
-        *_width = 0;
-        *_height = PGFT_Face_GetHeight(ft, font);
+        r->x = 0;
+        r->y = 0;
+        r->w = 0;
+        r->h = PGFT_Face_GetHeightSized(ft, font, render->pt_size);
         return 0;
     }
 
         return -1;
     }
 
+    width = font_text->width;
+    height = font_text->height;
     if (PGFT_GetSurfaceSize(ft, font, render, font_text, &width, &height) != 0)
     {
         if (locked)
         /* Nothing more to do. */
         if (locked)
             SDL_UnlockSurface(surface);
-        *_width = 0;
-        *_height = PGFT_Face_GetHeight(ft, font);
+	r->x = 0;
+	r->y = 0;
+	r->w = 0;
+        r->h = PGFT_Face_GetHeightSized(ft, font, render->pt_size);
         return 0;
     }
     
         return -1;
     }
 
-    *_width = width;
-    *_height = height;
-    metrics->bearing_rotated.x = font_text->offset.x;
-    metrics->bearing_rotated.y = font_text->offset.y;
-    metrics->advance_rotated.x = font_text->advance.x;
-    metrics->advance_rotated.y = font_text->advance.y;
+    r->x = -(Sint16)PGFT_TRUNC(PGFT_FLOOR(font_text->offset.x));
+    r->y = (Sint16)PGFT_TRUNC(PGFT_CEIL(font_text->offset.y));
+    r->w = (Uint16)width;
+    r->h = (Uint16)height;
 
     if (locked)
         SDL_UnlockSurface(surface);
 
 SDL_Surface *PGFT_Render_NewSurface(FreeTypeInstance *ft, PyFreeTypeFont *font, 
     const FontRenderMode *render, PGFT_String *text,
-    FontColor *fgcolor, FontColor *bgcolor, int *_width, int *_height)
+    FontColor *fgcolor, FontColor *bgcolor, SDL_Rect *r)
 {
 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
     FT_UInt32 rmask = 0xff000000;
     FontColor mono_fgcolor = {0, 0, 0, 1};
     FontColor mono_bgcolor = {0, 0, 0, 0};
 
-    if (PGFT_String_GET_LENGTH(text) == 0)
-    {
-        /* Empty surface */
-        *_width = 0;
-        *_height = PGFT_Face_GetHeight(ft, font);
-        surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, *_height, 32,
-                                       rmask, gmask, bmask, amask);
-        if (!surface)
-        {
-            PyErr_NoMemory(); /* Everything else should be Okay */
-            return NULL;
-        }
-    }
-
     /* build font text */
     font_text = PGFT_LoadFontText(ft, font, render, text);
 
     if (!font_text)
         return NULL;
 
-    if (PGFT_GetSurfaceSize(ft, font, render, font_text, &width, &height) != 0)
-        return NULL;
+    width = font_text->width;
+    height = font_text->height;
     if (height <= 0)
     {
-        height = PGFT_Face_GetHeight(ft, font);
+        height = PGFT_Face_GetHeightSized(ft, font, render->pt_size);
+    }
+    if (width < 0)
+    {
+        width = 0;
     }
 
     surface = SDL_CreateRGBSurface(surface_flags, width, height,
                    bits_per_pixel, rmask, gmask, bmask,
-                                   bits_per_pixel == 32 ? amask : 0);
+                   bits_per_pixel == 32 ? amask : 0);
     if (!surface)
     {
         PyErr_NoMemory(); /* Everything else should be Okay */
         return NULL;
     }
 
-    if (width <= 0)
+    if (width == 0)
     {
         /* Nothing more to do. */
-        *_width = 0;
-        *_height = height;
+        r->x = 0;
+        r->y = 0;
+        r->w = 0;
+        r->h = height;
         return surface;
     }
 
         return NULL;
     }
 
-    *_width = width;
-    *_height = height;
+    r->x = -(Sint16)PGFT_TRUNC(PGFT_FLOOR(font_text->offset.x));
+    r->y = (Sint16)PGFT_TRUNC(PGFT_CEIL(font_text->offset.y));
+    r->w = (Uint16)width;
+    r->h = (Uint16)height;
 
     if (locked)
         SDL_UnlockSurface(surface);

src/freetype/ft_text.c

 #include FT_MODULE_H
 #include FT_TRIGONOMETRY_H
 #include FT_OUTLINE_H
+#include FT_BITMAP_H
 #include FT_CACHE_H
 
 #define SLANT_FACTOR    0.22
 
 typedef struct __fonttextcontext
 {
+    FT_Library lib;
     FTC_FaceID id;
     FT_Face face;
     FTC_CMapCache charmap;
     PGFT_char * buffer_end;
     PGFT_char * ch;
 
-    FT_Fixed    y_scale;
-
     FontText    *ftext = &(PGFT_INTERNALS(font)->active_text);
     FontGlyph   *glyph = NULL;
     FontGlyph   **glyph_array = NULL;
         return NULL;
     }
 
+    context.lib = ft->library;
     context.id = (FTC_FaceID)&(font->id);
     context.face = face;
     context.charmap = ft->cache_charmap;
         }
 
         _PGFT_free(ftext->posns);
-    ftext->posns = (FT_Vector *)
-            _PGFT_malloc((size_t)string_length * sizeof(FT_Vector));
+        ftext->posns = (FT_Vector *)
+        _PGFT_malloc((size_t)string_length * sizeof(FT_Vector));
         if (!ftext->posns)
         {
             PyErr_NoMemory();
     ftext->length = string_length;
     ftext->underline_pos = ftext->underline_size = 0;
 
-    y_scale = face->size->metrics.y_scale;
-
     /* fill it with the glyphs */
     glyph_array = ftext->glyphs;
 
         *glyph_array++ = glyph;
         ++next_pos;
     }
-    if (pen.x > max_x)
-        max_x = pen.x;
-    if (pen.x < min_x)
-        min_x = pen.x;
-    if (pen.y > max_y)
-        max_y = pen.y;
-    if (pen.y < min_y)
-        min_y = pen.y;
 
     if (render->style & FT_STYLE_UNDERLINE && !vertical && angle == 0)
     {
 
 int PGFT_GetMetrics(FreeTypeInstance *ft, PyFreeTypeFont *font,
                     PGFT_char character, const FontRenderMode *render,
-                    long *minx, long *maxx, long *miny, long *maxy,
+                    FT_UInt *gindex, long *minx, long *maxx,
+                    long *miny, long *maxy,
                     double *advance_x, double *advance_y)
 { 
     FontGlyph *glyph = NULL;
         return -1;
     }
 
+    context.lib = ft->library;
     context.id = (FTC_FaceID)&(font->id);
     context.face = face;
     context.charmap = ft->cache_charmap;
         return -1;
     }
 
+    *gindex = glyph->glyph_index;
     *minx = (long)glyph->image->left;
     *maxx = (long)(glyph->image->left + glyph->image->bitmap.width);
     *maxy = (long)glyph->image->top;
 }
 
 int
-PGFT_GetTextSize(FreeTypeInstance *ft, PyFreeTypeFont *font,
-    const FontRenderMode *render, PGFT_String *text, int *w, int *h)
+PGFT_GetTextRect(FreeTypeInstance *ft, PyFreeTypeFont *font,
+    const FontRenderMode *render, PGFT_String *text, SDL_Rect *r)
 {
     FontText *font_text;
 
     if (!font_text)
         return -1;
 
-    return PGFT_GetSurfaceSize(ft, font, render, font_text, w, h);
+    r->x = -(Sint16)PGFT_TRUNC(PGFT_FLOOR(font_text->offset.x));
+    r->y = (Sint16)PGFT_TRUNC(PGFT_CEIL(font_text->offset.y));
+    r->w = (Uint16)font_text->width;
+    r->h = (Uint16)font_text->height;
+    return 0;
 }
 
 int
 
     int oblique = render->style & FT_STYLE_OBLIQUE;
     int embolden = render->style & FT_STYLE_BOLD;
+    int do_transform = render->render_flags & FT_RFLAG_TRANSFORM;
     FT_Render_Mode rmode = (render->render_flags & FT_RFLAG_ANTIALIAS ?
                             FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
     FT_Fixed bold_str = 0;
-    FT_Fixed bold_advance = 0;
+    FT_Vector bold_delta = {0, 0};
     FT_Glyph image = NULL;
 
     FT_Glyph_Metrics *ft_metrics;
 
     FT_Fixed rotation_angle = render->rotation_angle;
     FT_Vector unit;
-    FT_Matrix transform;
+    /* FT_Matrix transform; */
     FT_Vector h_bearing_rotated;
     FT_Vector v_bearing_rotated;
     FT_Vector h_advance_rotated;
     FT_Vector v_advance_rotated;
 
+    FT_Matrix transform = {PGFT_INT_TO_16(1), 0, 0, PGFT_INT_TO_16(1)};
+
     FT_Error error = 0;
 
     /*
         FT_Get_Glyph(context->face->glyph, &image))
         goto cleanup;
 
-    if (embolden && character != UNICODE_SPACE)
+    /*
+     * Perform any outline transformations
+     */
+    if (embolden)
     {
-        if (FT_Outline_Embolden(&((FT_OutlineGlyph)image)->outline,
-                BOLD_STRENGTH))
+        FT_BBox before;
+        FT_BBox after;
+
+        bold_str = BOLD_STRENGTH;
+        FT_Outline_Get_CBox(&((FT_OutlineGlyph)image)->outline, &before);
+        if (FT_Outline_Embolden(&((FT_OutlineGlyph)image)->outline, bold_str))
             goto cleanup;
-    bold_str = BOLD_STRENGTH;
-    bold_advance = BOLD_ADVANCE;
+        FT_Outline_Get_CBox(&((FT_OutlineGlyph)image)->outline, &after);
+        bold_delta.x += (after.xMax - after.xMin) - (before.xMax - before.xMin);
+        bold_delta.y += (after.yMax - after.yMin) - (before.yMax - before.yMin);
     }
 
-    /*
-     * Collect useful metric values
-     */
-    ft_metrics = &context->face->glyph->metrics;
-    h_advance_rotated.x = ft_metrics->horiAdvance + bold_advance;
-    h_advance_rotated.y = 0;
-    v_advance_rotated.x = 0;
-    v_advance_rotated.y = ft_metrics->vertAdvance + bold_advance;
-
-    /*
-     * Perform any transformations
-     */
     if (oblique)
     {
-        FT_Outline_Transform(&(((FT_OutlineGlyph)image)->outline),
-                             &PGFT_SlantMatrix);
+        FT_Matrix_Multiply(&PGFT_SlantMatrix, &transform);
+        do_transform = 1;
+        /* FT_Outline_Transform(&(((FT_OutlineGlyph)image)->outline), */
+        /*                      &PGFT_SlantMatrix); */
     }
 
     if (rotation_angle != 0)
     {
-        FT_Angle counter_rotation =
-            rotation_angle ? PGFT_INT_TO_6(360) - rotation_angle : 0;
+        FT_Matrix rotate;
 
         FT_Vector_Unit(&unit, rotation_angle);
-        transform.xx = unit.x;  /*  cos(angle) */
-        transform.xy = -unit.y; /* -sin(angle) */
-        transform.yx = unit.y;  /*  sin(angle) */
-        transform.yy = unit.x;  /*  cos(angle) */
+        rotate.xx = unit.x;  /*  cos(angle) */
+        rotate.xy = -unit.y; /* -sin(angle) */
+        rotate.yx = unit.y;  /*  sin(angle) */
+        rotate.yy = unit.x;  /*  cos(angle) */
+        FT_Matrix_Multiply(&rotate, &transform);
+        do_transform = 1;
+    }
+
+    if (do_transform)
+    {
         if (FT_Glyph_Transform(image, &transform, &delta))
         {
             goto cleanup;
         }
-        FT_Vector_Rotate(&h_advance_rotated, rotation_angle);
-        FT_Vector_Rotate(&v_advance_rotated, counter_rotation);
     }
 
     /*
-     * Finished with transformations, now replace with a bitmap
+     * Finished with outline transformations, now replace with a bitmap
      */
     error = FT_Glyph_To_Bitmap(&image, rmode, 0, 1);
     if (error)
         goto cleanup;
     }
 
+    /* if (wide) */
+    /* { */
+    /*     int w = ((FT_BitmapGlyph)image)->bitmap.width; */
+
+    /*     if (w) */
+    /*     { */
+    /*         error = FT_Bitmap_Embolden(context->lib, */
+    /*                                    &((FT_BitmapGlyph)image)->bitmap, */
+    /*                                    (FT_Pos)0x80, (FT_Pos)0); */
+    /*         if (error) */
+    /*         { */
+    /*             goto cleanup; */
+    /*         } */
+    /*         bold_delta.x += PGFT_INT_TO_6(((FT_BitmapGlyph)image)->bitmap.width */
+    /*                                       - w); */
+    /*     } */
+    /*     else */
+    /*     { */
+    /*         bold_delta.x += BOLD_ADVANCE; */
+    /*     } */
+    /* } */
+
     /* Fill the glyph */
+    ft_metrics = &context->face->glyph->metrics;
+
+    h_advance_rotated.x = ft_metrics->horiAdvance + bold_delta.x;
+    h_advance_rotated.y = 0;
+    v_advance_rotated.x = 0;
+    v_advance_rotated.y = ft_metrics->vertAdvance + bold_delta.y;
+    if (rotation_angle != 0)
+    {
+        FT_Angle counter_rotation = PGFT_INT_TO_6(360) - rotation_angle;
+
+        FT_Vector_Rotate(&h_advance_rotated, rotation_angle);
+        FT_Vector_Rotate(&v_advance_rotated, counter_rotation);
+    }
+
     glyph->image = (FT_BitmapGlyph)image;
     glyph->width = PGFT_INT_TO_6(glyph->image->bitmap.width);
     glyph->height = PGFT_INT_TO_6(glyph->image->bitmap.rows);
     h_bearing_rotated.x = PGFT_INT_TO_6(glyph->image->left);
     h_bearing_rotated.y = PGFT_INT_TO_6(glyph->image->top);
     fill_metrics(&glyph->h_metrics,
-                 ft_metrics->horiBearingX + bold_advance,
-                 ft_metrics->horiBearingY + bold_advance,
+                 ft_metrics->horiBearingX,
+                 ft_metrics->horiBearingY,
                  &h_bearing_rotated, &h_advance_rotated);
 
     if (rotation_angle == 0)
     {
-        v_bearing_rotated.x = ft_metrics->vertBearingX - bold_advance / 2;
+        v_bearing_rotated.x = ft_metrics->vertBearingX - bold_delta.x / 2;
         v_bearing_rotated.y = ft_metrics->vertBearingY;
     }
     else
         FT_Vector v_origin;
 
         v_origin.x = (glyph->h_metrics.bearing_x -
-                      ft_metrics->vertBearingX + bold_advance / 2);
+                      ft_metrics->vertBearingX + bold_delta.x / 2);
         v_origin.y = (glyph->h_metrics.bearing_y +
                       ft_metrics->vertBearingY);
         FT_Vector_Rotate(&v_origin, rotation_angle);
         v_bearing_rotated.y = v_origin.y - glyph->h_metrics.bearing_rotated.y;
     }
     fill_metrics(&glyph->v_metrics,
-                 ft_metrics->vertBearingX + bold_advance,
-                 ft_metrics->vertBearingY + bold_advance,
+                 ft_metrics->vertBearingX,
+                 ft_metrics->vertBearingY,
                  &v_bearing_rotated, &v_advance_rotated);
 
     return 0;

src/freetype/ft_wrap.c

     return face->family_name; 
 }
 
-int
+/* All the face metric functions raise an exception and return 0 on an error.
+ * It is up to the caller to check PyErr_Occurred for a 0 return value.
+ */
+long
 PGFT_Face_GetHeight(FreeTypeInstance *ft, PyFreeTypeFont *font)
 {
-    FT_Face face;
-    face = _PGFT_GetFace(ft, font);
+    FT_Face face = _PGFT_GetFace(ft, font);
 
     if (face == NULL) {
         RAISE(PyExc_RuntimeError, PGFT_GetError(ft));
-        return -1;
+        return 0;
     }
-    return face->height;
+    return (long)face->height;
 }
 
+long
+PGFT_Face_GetHeightSized(FreeTypeInstance *ft, PyFreeTypeFont *font,
+			 FT_UInt16 ptsize)
+{
+    FT_Face face = _PGFT_GetFaceSized(ft, font, ptsize);
+
+    if (face == NULL) {
+        RAISE(PyExc_RuntimeError, PGFT_GetError(ft));
+        return 0;
+    }
+    return (long)PGFT_TRUNC(PGFT_CEIL(face->size->metrics.height));
+}
+
+long
+PGFT_Face_GetAscender(FreeTypeInstance *ft, PyFreeTypeFont *font)
+{
+    FT_Face face = _PGFT_GetFace(ft, font);
+
+    if (face == NULL) {
+        RAISE(PyExc_RuntimeError, PGFT_GetError(ft));
+        return 0;
+    }
+    return (long)face->ascender;
+}
+
+long
+PGFT_Face_GetAscenderSized(FreeTypeInstance *ft, PyFreeTypeFont *font,
+			   FT_UInt16 ptsize)
+{
+    FT_Face face = _PGFT_GetFaceSized(ft, font, ptsize);
+
+    if (face == NULL) {
+        RAISE(PyExc_RuntimeError, PGFT_GetError(ft));
+        return 0;
+    }
+    return (long)PGFT_TRUNC(PGFT_CEIL(face->size->metrics.ascender));
+}
+
+long
+PGFT_Face_GetDescender(FreeTypeInstance *ft, PyFreeTypeFont *font)
+{
+    FT_Face face = _PGFT_GetFace(ft, font);
+
+    if (face == NULL) {
+        RAISE(PyExc_RuntimeError, PGFT_GetError(ft));
+        return 0;
+    }
+    return (long)face->descender;
+}
+
+long
+PGFT_Face_GetDescenderSized(FreeTypeInstance *ft, PyFreeTypeFont *font,
+			    FT_UInt16 ptsize)
+{
+    FT_Face face = _PGFT_GetFaceSized(ft, font, ptsize);
+
+    if (face == NULL) {
+        RAISE(PyExc_RuntimeError, PGFT_GetError(ft));
+        return 0;
+    }
+    return (long)PGFT_TRUNC(PGFT_FLOOR(face->size->metrics.descender));
+}
+
+long
+PGFT_Face_GetGlyphHeightSized(FreeTypeInstance *ft, PyFreeTypeFont *font,
+			      FT_UInt16 ptsize)
+{
+    /*
+     * Based on the SDL_ttf height calculation.
+     */
+    FT_Face face = _PGFT_GetFaceSized(ft, font, ptsize);
+    FT_Size_Metrics *metrics;
+
+    if (face == NULL) {
+        RAISE(PyExc_RuntimeError, PGFT_GetError(ft));
+        return 0;
+    }
+    metrics = &face->size->metrics;
+    return (long)PGFT_TRUNC(PGFT_CEIL(metrics->ascender) -
+                            PGFT_FLOOR(metrics->descender)) + /* baseline */ 1;
+}
 
 
 
 
     if (!_PGFT_GetFace(ft, font))
     {
-        RAISE(PyExc_RuntimeError, PGFT_GetError(ft));
+        RAISE(PyExc_IOError, PGFT_GetError(ft));
         return -1;
     }
 

src/freetype/ft_wrap.h

     FT_Angle    rotation_angle;
     FT_UInt16   render_flags;
     FT_UInt16   style;
+    FT_Matrix   transform;
 } FontRenderMode;
 
 #if defined(Py_DEBUG) && !defined(PGFT_DEBUG_CACHE)
 void        PGFT_Quit(FreeTypeInstance *);
 int         PGFT_Init(FreeTypeInstance **, int cache_size);
 
-int         PGFT_Face_GetHeight(FreeTypeInstance *ft, PyFreeTypeFont *);
+long        PGFT_Face_GetAscender(FreeTypeInstance *, PyFreeTypeFont *);
+long        PGFT_Face_GetAscenderSized(FreeTypeInstance *, PyFreeTypeFont *,
+				       FT_UInt16);
+long        PGFT_Face_GetDescender(FreeTypeInstance *, PyFreeTypeFont *);
+long        PGFT_Face_GetDescenderSized(FreeTypeInstance *, PyFreeTypeFont *,
+					FT_UInt16);
+long        PGFT_Face_GetHeight(FreeTypeInstance *ft, PyFreeTypeFont *);
+long        PGFT_Face_GetHeightSized(FreeTypeInstance *ft, PyFreeTypeFont *,
+				     FT_UInt16);
+long        PGFT_Face_GetGlyphHeightSized(FreeTypeInstance *, PyFreeTypeFont *,
+					  FT_UInt16);
 int         PGFT_Face_IsFixedWidth(FreeTypeInstance *ft, PyFreeTypeFont *);
 const char *PGFT_Face_GetName(FreeTypeInstance *ft, PyFreeTypeFont *);
 
 
 
 /********************************************************* Metrics management ****/
-int         PGFT_GetTextSize(FreeTypeInstance *ft, PyFreeTypeFont *font,
-                const FontRenderMode *render, PGFT_String *text, int *w, int *h);
+int         PGFT_GetTextRect(FreeTypeInstance *ft, PyFreeTypeFont *font,
+                const FontRenderMode *render, PGFT_String *text, SDL_Rect *r);
 
 int         PGFT_GetMetrics(FreeTypeInstance *ft, PyFreeTypeFont *font,
                 PGFT_char character, const FontRenderMode *render,
-                long *minx, long *maxx, long *miny, long *maxy,
+                FT_UInt *gindex, long *minx, long *maxx, long *miny, long *maxy,
                 double *advance_x, double *advance_y);
 
 int         PGFT_GetSurfaceSize(FreeTypeInstance *ft, PyFreeTypeFont *font,
 
 SDL_Surface *PGFT_Render_NewSurface(FreeTypeInstance *ft, PyFreeTypeFont *font,
                 const FontRenderMode *render, PGFT_String *text,
-                FontColor *fgcolor, FontColor *bgcolor, int *_width, int *_height);
+                FontColor *fgcolor, FontColor *bgcolor, SDL_Rect *r);
 
 int         PGFT_Render_ExistingSurface(FreeTypeInstance *ft, PyFreeTypeFont *font,
                 const FontRenderMode *render, PGFT_String *text, 
                 SDL_Surface *_surface, int x, int y,
-                FontColor *fgcolor, FontColor *bgcolor,
-        int *_width, int *_height, FontMetrics *metrics);
+                FontColor *fgcolor, FontColor *bgcolor, SDL_Rect *r);
 
 int         PGFT_BuildRenderMode(FreeTypeInstance *ft, 
                 PyFreeTypeFont *font, FontRenderMode *mode, int pt_size, 

test/freetype_font_test.py

 
     def test_freetype_Font_init(self):
 
-        self.assertRaises(RuntimeError, ft.Font, os.path.join (FONTDIR, 'nonexistant.ttf'))
+        self.assertRaises(IOError, ft.Font, os.path.join (FONTDIR, 'nonexistant.ttf'))
 
         f = self._TEST_FONTS['sans']
         self.assertTrue(isinstance(f, ft.Font))
 
         f = ft.Font(None, ptsize=24)
         self.assert_(f.height > 0)
-        self.assertRaises(RuntimeError, f.__init__,
+        self.assertRaises(IOError, f.__init__,
                           os.path.join(FONTDIR, 'nonexistant.ttf'))
-        self.assertRaises(RuntimeError, f.get_size, 'a', ptsize=24)
+        self.assertRaises(RuntimeError, f.get_rect, 'a', ptsize=24)
         
         # Test attribute preservation during reinitalization
         f = ft.Font(self._sans_path, ptsize=24, ucs4=True)
         self.assertRaises(RuntimeError, nullfont().get_metrics,
                           'a', ptsize=24)
 
-    def test_freetype_Font_get_size(self):
+    def test_freetype_Font_get_rect(self):
 
         font = self._TEST_FONTS['sans']
 
-        def test_size(s):
-            self.assertTrue(isinstance(s, tuple))
-            self.assertEqual(len(s), 2)
-            self.assertTrue(isinstance(s[0], int))
-            self.assertTrue(isinstance(s[1], int))
+        def test_rect(r):
+            self.assertTrue(isinstance(r, pygame.Rect))
 
-        size_default = font.get_size("ABCDabcd", ptsize=24)
-        test_size(size_default)
-        self.assertTrue(size_default > (0, 0))
-        self.assertTrue(size_default[0] > size_default[1])
+        rect_default = font.get_rect("ABCDabcd", ptsize=24)
+        test_rect(rect_default)
+        self.assertTrue(rect_default.size > (0, 0))
+        self.assertTrue(rect_default.width > rect_default.height)
 
-        size_bigger = font.get_size("ABCDabcd", ptsize=32)
-        test_size(size_bigger)
-        self.assertTrue(size_bigger > size_default)
+        rect_bigger = font.get_rect("ABCDabcd", ptsize=32)
+        test_rect(rect_bigger)
+        self.assertTrue(rect_bigger.size > rect_default.size)
 
-        size_bolden = font.get_size("ABCDabcd", ptsize=24, style=ft.STYLE_BOLD)
-        test_size(size_bolden)
-        self.assertTrue(size_bolden > size_default)
+        rect_bolden = font.get_rect("ABCDabcd", ptsize=24, style=ft.STYLE_BOLD)
+        test_rect(rect_bolden)
+        self.assertTrue(rect_bolden.size > rect_default.size)
 
         font.vertical = True
-        size_vert = font.get_size("ABCDabcd", ptsize=24)
-        test_size(size_vert)
-        self.assertTrue(size_vert[0] < size_vert[1])
+        rect_vert = font.get_rect("ABCDabcd", ptsize=24)
+        test_rect(rect_vert)
+        self.assertTrue(rect_vert.width < rect_vert.height)
         font.vertical = False
 
-        size_oblique = font.get_size("ABCDabcd", ptsize=24, style=ft.STYLE_OBLIQUE)
-        test_size(size_oblique)
-        self.assertTrue(size_oblique[0] > size_default[0])
-        self.assertTrue(size_oblique[1] == size_default[1])
+        rect_oblique = font.get_rect("ABCDabcd", ptsize=24, style=ft.STYLE_OBLIQUE)
+        test_rect(rect_oblique)
+        self.assertTrue(rect_oblique.width > rect_default.width)
+        self.assertTrue(rect_oblique.height == rect_default.height)
 
-        size_under = font.get_size("ABCDabcd", ptsize=24, style=ft.STYLE_UNDERLINE)
-        test_size(size_under)
-        self.assertTrue(size_under[0] == size_default[0])
-        self.assertTrue(size_under[1] > size_default[1])
+        rect_under = font.get_rect("ABCDabcd", ptsize=24, style=ft.STYLE_UNDERLINE)
+        test_rect(rect_under)
+        self.assertTrue(rect_under.width == rect_default.width)
+        self.assertTrue(rect_under.height > rect_default.height)
 
 #        size_utf32 = font.get_size(as_unicode(r'\U000130A7'), ptsize=24)
 #        size_utf16 = font.get_size(as_unicode(r'\uD80C\uDCA7'), ptsize=24)
 #        self.assertNotEqual(size_utf16[0], size_utf32[0]);
         
         self.assertRaises(RuntimeError,
-                          nullfont().get_size, 'a', ptsize=24)
+                          nullfont().get_rect, 'a', ptsize=24)
 
     def test_freetype_Font_height(self):
 
         self.assertEqual(len(rend), 2)
         self.assertTrue(isinstance(rend[0], pygame.Surface))
         self.assertTrue(isinstance(rend[1], pygame.Rect))
-        self.assertEqual(rend[0].get_rect(), rend[1])
+        self.assertEqual(rend[0].get_rect().size, rend[1].size)
         s, r = font.render(None, '', pygame.Color(0, 0, 0), None, ptsize=24)
         self.assertFalse(r, str(r))
         self.assertEqual(r.height, font.height)
         font = self._TEST_FONTS['sans']
         
         text = "abc"
-        size = font.get_size(text, ptsize=24)
+        size = font.get_rect(text, ptsize=24).size
         rend = font.render_raw(text, ptsize=24)
         self.assertTrue(isinstance(rend, tuple))
         self.assertEqual(len(rend), 2)
         resolution = ft.get_default_resolution()
         new_font = ft.Font(self._sans_path, resolution=2 * resolution)
         self.assertEqual(new_font.resolution, 2 * resolution)
-        size_normal = self._TEST_FONTS['sans'].get_size(text, ptsize=24)
-        size_scaled = new_font.get_size(text, ptsize=24)
+        size_normal = self._TEST_FONTS['sans'].get_rect(text, ptsize=24).size
+        size_scaled = new_font.get_rect(text, ptsize=24).size
         size_by_2 = size_normal[0] * 2
         self.assertTrue(size_by_2 + 2 >= size_scaled[0] >= size_by_2 - 2,
                         "%i not equal %i" % (size_scaled[1], size_by_2))