|  | 
 | /* Font Manager module */ | 
 |  | 
 | #include "Python.h" | 
 |  | 
 | #include <gl.h> | 
 | #include <device.h> | 
 | #include <fmclient.h> | 
 |  | 
 |  | 
 | /* Font Handle object implementation */ | 
 |  | 
 | typedef struct { | 
 |     PyObject_HEAD | 
 |     fmfonthandle fh_fh; | 
 | } fhobject; | 
 |  | 
 | static PyTypeObject Fhtype; | 
 |  | 
 | #define is_fhobject(v)          ((v)->ob_type == &Fhtype) | 
 |  | 
 | static PyObject * | 
 | newfhobject(fmfonthandle fh) | 
 | { | 
 |     fhobject *fhp; | 
 |     if (fh == NULL) { | 
 |         PyErr_SetString(PyExc_RuntimeError, | 
 |                         "error creating new font handle"); | 
 |         return NULL; | 
 |     } | 
 |     fhp = PyObject_New(fhobject, &Fhtype); | 
 |     if (fhp == NULL) | 
 |         return NULL; | 
 |     fhp->fh_fh = fh; | 
 |     return (PyObject *)fhp; | 
 | } | 
 |  | 
 | /* Font Handle methods */ | 
 |  | 
 | static PyObject * | 
 | fh_scalefont(fhobject *self, PyObject *args) | 
 | { | 
 |     double size; | 
 |     if (!PyArg_ParseTuple(args, "d", &size)) | 
 |         return NULL; | 
 |     return newfhobject(fmscalefont(self->fh_fh, size)); | 
 | } | 
 |  | 
 | /* XXX fmmakefont */ | 
 |  | 
 | static PyObject * | 
 | fh_setfont(fhobject *self) | 
 | { | 
 |     fmsetfont(self->fh_fh); | 
 |     Py_INCREF(Py_None); | 
 |     return Py_None; | 
 | } | 
 |  | 
 | static PyObject * | 
 | fh_getfontname(fhobject *self) | 
 | { | 
 |     char fontname[256]; | 
 |     int len; | 
 |     len = fmgetfontname(self->fh_fh, sizeof fontname, fontname); | 
 |     if (len < 0) { | 
 |         PyErr_SetString(PyExc_RuntimeError, "error in fmgetfontname"); | 
 |         return NULL; | 
 |     } | 
 |     return PyString_FromStringAndSize(fontname, len); | 
 | } | 
 |  | 
 | static PyObject * | 
 | fh_getcomment(fhobject *self) | 
 | { | 
 |     char comment[256]; | 
 |     int len; | 
 |     len = fmgetcomment(self->fh_fh, sizeof comment, comment); | 
 |     if (len < 0) { | 
 |         PyErr_SetString(PyExc_RuntimeError, "error in fmgetcomment"); | 
 |         return NULL; | 
 |     } | 
 |     return PyString_FromStringAndSize(comment, len); | 
 | } | 
 |  | 
 | static PyObject * | 
 | fh_getfontinfo(fhobject *self) | 
 | { | 
 |     fmfontinfo info; | 
 |     if (fmgetfontinfo(self->fh_fh, &info) < 0) { | 
 |         PyErr_SetString(PyExc_RuntimeError, "error in fmgetfontinfo"); | 
 |         return NULL; | 
 |     } | 
 |     return Py_BuildValue("(llllllll)", | 
 |                          info.printermatched, | 
 |                          info.fixed_width, | 
 |                          info.xorig, | 
 |                          info.yorig, | 
 |                          info.xsize, | 
 |                          info.ysize, | 
 |                          info.height, | 
 |                          info.nglyphs); | 
 | } | 
 |  | 
 | #if 0 | 
 | static PyObject * | 
 | fh_getwholemetrics(fhobject *self, PyObject *args) | 
 | { | 
 | } | 
 | #endif | 
 |  | 
 | static PyObject * | 
 | fh_getstrwidth(fhobject *self, PyObject *args) | 
 | { | 
 |     char *str; | 
 |     if (!PyArg_ParseTuple(args, "s", &str)) | 
 |         return NULL; | 
 |     return PyInt_FromLong(fmgetstrwidth(self->fh_fh, str)); | 
 | } | 
 |  | 
 | static PyMethodDef fh_methods[] = { | 
 |     {"scalefont",       (PyCFunction)fh_scalefont,   METH_VARARGS}, | 
 |     {"setfont",         (PyCFunction)fh_setfont,     METH_NOARGS}, | 
 |     {"getfontname",     (PyCFunction)fh_getfontname, METH_NOARGS}, | 
 |     {"getcomment",      (PyCFunction)fh_getcomment,  METH_NOARGS}, | 
 |     {"getfontinfo",     (PyCFunction)fh_getfontinfo, METH_NOARGS}, | 
 | #if 0 | 
 |     {"getwholemetrics",         (PyCFunction)fh_getwholemetrics, METH_VARARGS}, | 
 | #endif | 
 |     {"getstrwidth",     (PyCFunction)fh_getstrwidth, METH_VARARGS}, | 
 |     {NULL,              NULL}           /* sentinel */ | 
 | }; | 
 |  | 
 | static PyObject * | 
 | fh_getattr(fhobject *fhp, char *name) | 
 | { | 
 |     return Py_FindMethod(fh_methods, (PyObject *)fhp, name); | 
 | } | 
 |  | 
 | static void | 
 | fh_dealloc(fhobject *fhp) | 
 | { | 
 |     fmfreefont(fhp->fh_fh); | 
 |     PyObject_Del(fhp); | 
 | } | 
 |  | 
 | static PyTypeObject Fhtype = { | 
 |     PyObject_HEAD_INIT(&PyType_Type) | 
 |     0,                                  /*ob_size*/ | 
 |     "fm.font handle",                   /*tp_name*/ | 
 |     sizeof(fhobject),                   /*tp_size*/ | 
 |     0,                                  /*tp_itemsize*/ | 
 |     /* methods */ | 
 |     (destructor)fh_dealloc,             /*tp_dealloc*/ | 
 |     0,                                  /*tp_print*/ | 
 |     (getattrfunc)fh_getattr,            /*tp_getattr*/ | 
 |     0,                                  /*tp_setattr*/ | 
 |     0,                                  /*tp_compare*/ | 
 |     0,                                  /*tp_repr*/ | 
 | }; | 
 |  | 
 |  | 
 | /* Font Manager functions */ | 
 |  | 
 | static PyObject * | 
 | fm_init(PyObject *self) | 
 | { | 
 |     fminit(); | 
 |     Py_INCREF(Py_None); | 
 |     return Py_None; | 
 | } | 
 |  | 
 | static PyObject * | 
 | fm_findfont(PyObject *self, PyObject *args) | 
 | { | 
 |     char *str; | 
 |     if (!PyArg_ParseTuple(args, "s", &str)) | 
 |         return NULL; | 
 |     return newfhobject(fmfindfont(str)); | 
 | } | 
 |  | 
 | static PyObject * | 
 | fm_prstr(PyObject *self, PyObject *args) | 
 | { | 
 |     char *str; | 
 |     if (!PyArg_ParseTuple(args, "s", &str)) | 
 |         return NULL; | 
 |     fmprstr(str); | 
 |     Py_INCREF(Py_None); | 
 |     return Py_None; | 
 | } | 
 |  | 
 | /* XXX This uses a global variable as temporary! Not re-entrant! */ | 
 |  | 
 | static PyObject *fontlist; | 
 |  | 
 | static void | 
 | clientproc(char *fontname) | 
 | { | 
 |     int err; | 
 |     PyObject *v; | 
 |     if (fontlist == NULL) | 
 |         return; | 
 |     v = PyString_FromString(fontname); | 
 |     if (v == NULL) | 
 |         err = -1; | 
 |     else { | 
 |         err = PyList_Append(fontlist, v); | 
 |         Py_DECREF(v); | 
 |     } | 
 |     if (err != 0) { | 
 |         Py_DECREF(fontlist); | 
 |         fontlist = NULL; | 
 |     } | 
 | } | 
 |  | 
 | static PyObject * | 
 | fm_enumerate(PyObject *self) | 
 | { | 
 |     PyObject *res; | 
 |     fontlist = PyList_New(0); | 
 |     if (fontlist == NULL) | 
 |         return NULL; | 
 |     fmenumerate(clientproc); | 
 |     res = fontlist; | 
 |     fontlist = NULL; | 
 |     return res; | 
 | } | 
 |  | 
 | static PyObject * | 
 | fm_setpath(PyObject *self, PyObject *args) | 
 | { | 
 |     char *str; | 
 |     if (!PyArg_ParseTuple(args, "s", &str)) | 
 |         return NULL; | 
 |     fmsetpath(str); | 
 |     Py_INCREF(Py_None); | 
 |     return Py_None; | 
 | } | 
 |  | 
 | static PyObject * | 
 | fm_fontpath(PyObject *self) | 
 | { | 
 |     return PyString_FromString(fmfontpath()); | 
 | } | 
 |  | 
 | static PyMethodDef fm_methods[] = { | 
 |     {"init",            fm_init,      METH_NOARGS}, | 
 |     {"findfont",        fm_findfont,  METH_VARARGS}, | 
 |     {"enumerate",       fm_enumerate, METH_NOARGS}, | 
 |     {"prstr",           fm_prstr,     METH_VARARGS}, | 
 |     {"setpath",         fm_setpath,   METH_VARARGS}, | 
 |     {"fontpath",        fm_fontpath,  METH_NOARGS}, | 
 |     {NULL,              NULL}           /* sentinel */ | 
 | }; | 
 |  | 
 |  | 
 | void | 
 | initfm(void) | 
 | { | 
 |  | 
 |     if (PyErr_WarnPy3k("the fm module has been removed in " | 
 |                        "Python 3.0", 2) < 0) | 
 |     return; | 
 |  | 
 |     Py_InitModule("fm", fm_methods); | 
 |     if (m == NULL) | 
 |         return; | 
 |     fminit(); | 
 | } |