Commits

Anonymous committed feeee63

Font loading using file names now works.
Added FreeType error message handling.

  • Participants
  • Parent commits 1b15594
  • Branches pgreloaded

Comments (0)

Files changed (4)

src/freetype/ft_font.c

 #include "pgfreetype.h"
 #include "freetypebase_doc.h"
 
-/* Externs */
-extern int PyFile_Check(PyObject *);
-extern PyObject* PyFile_FromString(char *, char *);
-
 /*
  * Constructor/init/destructor
  */
 static PyObject *_ftfont_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
 static int _ftfont_init(PyObject *chunk, PyObject *args, PyObject *kwds);
 static void _ftfont_dealloc(PyFreeTypeFont *self);
+static PyObject *_ftfont_repr(PyObject *self);
 
 /*
  * Main methods
     0,                          /* tp_getattr */
     0,                          /* tp_setattr */
     0,                          /* tp_compare */
-    0,                          /* tp_repr */
+    (reprfunc)_ftfont_repr,     /* tp_repr */
     0,                          /* tp_as_number */
     0,                          /* tp_as_sequence */
     0,                          /* tp_as_mapping */
     if ((ft = _get_freetype()) != NULL)
         PGFT_UnloadFont(ft, self);
 
-    Py_XDECREF(self->id.file_ptr);
-
     ((PyObject*)self)->ob_type->tp_free((PyObject *)self);
 }
 
 
     font->id.face_index = face_index;
 
-    if (PyFile_Check(file))
-    {
-        Py_INCREF(file);
-        font->id.file_ptr = file;
-    }
-    else if (IsTextObj(file))
+    /*
+     * TODO: Handle file-like objects
+     */
+
+    if (IsTextObj(file))
     {
         PyObject *tmp;
         char *filename;
             return -1;
         }
         
-        font->id.file_ptr = PyFile_FromString(filename, "rb");
+        font->id.open_args.flags = FT_OPEN_PATHNAME;
+        font->id.open_args.pathname = filename; 
         Py_XDECREF(tmp);
     }
     else
     {
         PyErr_SetString(PyExc_ValueError, 
-                "Invalid 'file' parameter (must be a File object or a file name");
+                "Invalid 'file' parameter (must be a File object or a file name)");
         return -1;
     }
 
     if (PGFT_TryLoadFont(ft, font) != 0)
     {
         /* TODO: Get a proper error string */
-        PyErr_SetString(PyExc_ValueError, "Failed to load font");
+        PyErr_SetString(PyExc_RuntimeError, PGFT_GetError(ft));
         return -1;
     }
 
     return 0;
 }
 
+static PyObject*
+_ftfont_repr(PyObject *self)
+{
+    /* TODO: Print actual information about the font */
+    return Text_FromUTF8("FreeType Font");
+}
 
 
 /****************************************************

src/freetype/ft_wrap.c

 #include "pgsdl.h"
 #include "freetypebase_doc.h"
 
-/* Externals */
-FILE *PyFile_AsFile(PyObject *p);
-
-
-void    _PGTF_SetError(const char *error_msg, FT_Error error_id);
-
-
-static unsigned long 
-_RWread(FT_Stream stream, 
-        unsigned long offset, 
-        unsigned char* buffer, 
-        unsigned long count)
-{
-    PyObject *obj;
-    FILE *file;
-    unsigned long readc;
-
-    obj = (PyObject *)stream->descriptor.pointer;
-
-    Py_BEGIN_ALLOW_THREADS;
-
-        file = PyFile_AsFile(obj);
-        fseek(file, (long int)offset, SEEK_SET);
-
-        readc = count ? fread(buffer, 1, count, file) : 0;
-
-    Py_END_ALLOW_THREADS;
-
-    return readc;
-}
+void    _PGTF_SetError(FreeTypeInstance *, const char *, FT_Error);
 
 static FT_Error
 _PGTF_face_request(FTC_FaceID face_id, 
         FT_Face *aface)
 {
     FontId *id = GET_FONT_ID(face_id); 
-
     FT_Error error = 0;
-    FT_Stream stream = NULL;
-    FILE *file;
-
-    stream = malloc(sizeof(FT_Stream));
-
-	if (stream == NULL) 
-        goto error_cleanup;
-
-	memset(stream, 0, sizeof(FT_Stream));
-
-	stream->read = _RWread;
-    /* do not let FT close the stream, Python will take care of it */
-    stream->close = NULL; 
-
-	stream->descriptor.pointer = id->file_ptr;
-
+    
     Py_BEGIN_ALLOW_THREADS;
-        file = PyFile_AsFile(id->file_ptr);
-        
-        stream->size = (unsigned long)fseek(file, 0, SEEK_END);
-        stream->pos = (unsigned long)fseek(file, 0, SEEK_SET);
+        error = FT_Open_Face(library, &id->open_args, id->face_index, aface);
     Py_END_ALLOW_THREADS;
 
-	id->open_args.flags = FT_OPEN_STREAM;
-	id->open_args.stream = stream;
-
-	error = FT_Open_Face(library, &id->open_args, id->face_index, aface);
-
-    if (error)
-        goto error_cleanup;
-
-    return 0;
-
-error_cleanup:
-    free(stream);
-    return error ? error : -1;
+    return error;
 }
 
 void
-_PGTF_SetError(const char *error_msg, FT_Error error_id)
+_PGTF_SetError(FreeTypeInstance *ft, const char *error_msg, FT_Error error_id)
 {
+#undef __FTERRORS_H__
+#define FT_ERRORDEF( e, v, s )  { e, s },
+#define FT_ERROR_START_LIST     {
+#define FT_ERROR_END_LIST       {0, 0}};
+	static const struct
+	{
+	  int          err_code;
+	  const char*  err_msg;
+	} ft_errors[] = 
+#include FT_ERRORS_H
 
+	int i;
+	const char *ft_msg;
+
+	ft_msg = NULL;
+	for (i = 0; ft_errors[i].err_msg != NULL; ++i)
+    {
+		if (error_id == ft_errors[i].err_code) 
+        {
+			ft_msg = ft_errors[i].err_msg;
+			break;
+		}
+	}
+
+	if (ft_msg)
+        sprintf(ft->_error_msg, "%s: %s", error_msg, ft_msg);
+    else
+        strcpy(ft->_error_msg, error_msg);
+}
+
+const char *
+PGFT_GetError(FreeTypeInstance *ft)
+{
+    return ft->_error_msg;
 }
 
 int
 
     if (error)
     {
-        _PGTF_SetError("Failed to load font", error);
+        _PGTF_SetError(ft, "Failed to load font", error);
         return error;
     }
 
 
     FTC_Manager_Done(ft->cache_manager);
     FT_Done_FreeType(ft->library);
+
+    free(ft->_error_msg);
     free(ft);
 }
 
 
     if (!inst)
         goto error_cleanup;
+
+    memset(inst, 0, sizeof(FreeTypeInstance));
+    inst->_error_msg = malloc(1024);
     
     error = FT_Init_FreeType(&inst->library);
 
     if (error)
         goto error_cleanup;
 
+    *_instance = inst;
     return 0;
 
 error_cleanup:
     free(inst);
     *_instance = NULL;
 
-    return error;
+    return error ? error : -1;
 }

src/freetype/ft_wrap.h

     FTC_Manager cache_manager;
     FTC_SBitCache cache_bitmap;
     FTC_CMapCache cache_charmap;
+
+    char *_error_msg;
 } FreeTypeInstance;
 
 FreeTypeInstance *_get_freetype(void);
 
 #define GET_FONT_ID(f) (&((PyFreeTypeFont *)f)->id)
 
-
+const char *PGFT_GetError(FreeTypeInstance *);
 void    PGFT_Quit(FreeTypeInstance *);
 int     PGFT_Init(FreeTypeInstance **);
-int     PGFT_TryLoadFont(FreeTypeInstance *ft, PyFreeTypeFont *font);
+int     PGFT_TryLoadFont(FreeTypeInstance *, PyFreeTypeFont *);
 void    PGFT_UnloadFont(FreeTypeInstance *, PyFreeTypeFont *);
 
 

src/freetype/pgfreetype.h

 
 typedef struct
 {
-    PyObject *file_ptr;
     int face_index;
     FT_Open_Args open_args;
 } FontId;