Home | History | Annotate | Download | only in Modules
      1 
      2 /* Font Manager module */
      3 
      4 #include "Python.h"
      5 
      6 #include <gl.h>
      7 #include <device.h>
      8 #include <fmclient.h>
      9 
     10 
     11 /* Font Handle object implementation */
     12 
     13 typedef struct {
     14     PyObject_HEAD
     15     fmfonthandle fh_fh;
     16 } fhobject;
     17 
     18 static PyTypeObject Fhtype;
     19 
     20 #define is_fhobject(v)          ((v)->ob_type == &Fhtype)
     21 
     22 static PyObject *
     23 newfhobject(fmfonthandle fh)
     24 {
     25     fhobject *fhp;
     26     if (fh == NULL) {
     27         PyErr_SetString(PyExc_RuntimeError,
     28                         "error creating new font handle");
     29         return NULL;
     30     }
     31     fhp = PyObject_New(fhobject, &Fhtype);
     32     if (fhp == NULL)
     33         return NULL;
     34     fhp->fh_fh = fh;
     35     return (PyObject *)fhp;
     36 }
     37 
     38 /* Font Handle methods */
     39 
     40 static PyObject *
     41 fh_scalefont(fhobject *self, PyObject *args)
     42 {
     43     double size;
     44     if (!PyArg_ParseTuple(args, "d", &size))
     45         return NULL;
     46     return newfhobject(fmscalefont(self->fh_fh, size));
     47 }
     48 
     49 /* XXX fmmakefont */
     50 
     51 static PyObject *
     52 fh_setfont(fhobject *self)
     53 {
     54     fmsetfont(self->fh_fh);
     55     Py_INCREF(Py_None);
     56     return Py_None;
     57 }
     58 
     59 static PyObject *
     60 fh_getfontname(fhobject *self)
     61 {
     62     char fontname[256];
     63     int len;
     64     len = fmgetfontname(self->fh_fh, sizeof fontname, fontname);
     65     if (len < 0) {
     66         PyErr_SetString(PyExc_RuntimeError, "error in fmgetfontname");
     67         return NULL;
     68     }
     69     return PyString_FromStringAndSize(fontname, len);
     70 }
     71 
     72 static PyObject *
     73 fh_getcomment(fhobject *self)
     74 {
     75     char comment[256];
     76     int len;
     77     len = fmgetcomment(self->fh_fh, sizeof comment, comment);
     78     if (len < 0) {
     79         PyErr_SetString(PyExc_RuntimeError, "error in fmgetcomment");
     80         return NULL;
     81     }
     82     return PyString_FromStringAndSize(comment, len);
     83 }
     84 
     85 static PyObject *
     86 fh_getfontinfo(fhobject *self)
     87 {
     88     fmfontinfo info;
     89     if (fmgetfontinfo(self->fh_fh, &info) < 0) {
     90         PyErr_SetString(PyExc_RuntimeError, "error in fmgetfontinfo");
     91         return NULL;
     92     }
     93     return Py_BuildValue("(llllllll)",
     94                          info.printermatched,
     95                          info.fixed_width,
     96                          info.xorig,
     97                          info.yorig,
     98                          info.xsize,
     99                          info.ysize,
    100                          info.height,
    101                          info.nglyphs);
    102 }
    103 
    104 #if 0
    105 static PyObject *
    106 fh_getwholemetrics(fhobject *self, PyObject *args)
    107 {
    108 }
    109 #endif
    110 
    111 static PyObject *
    112 fh_getstrwidth(fhobject *self, PyObject *args)
    113 {
    114     char *str;
    115     if (!PyArg_ParseTuple(args, "s", &str))
    116         return NULL;
    117     return PyInt_FromLong(fmgetstrwidth(self->fh_fh, str));
    118 }
    119 
    120 static PyMethodDef fh_methods[] = {
    121     {"scalefont",       (PyCFunction)fh_scalefont,   METH_VARARGS},
    122     {"setfont",         (PyCFunction)fh_setfont,     METH_NOARGS},
    123     {"getfontname",     (PyCFunction)fh_getfontname, METH_NOARGS},
    124     {"getcomment",      (PyCFunction)fh_getcomment,  METH_NOARGS},
    125     {"getfontinfo",     (PyCFunction)fh_getfontinfo, METH_NOARGS},
    126 #if 0
    127     {"getwholemetrics",         (PyCFunction)fh_getwholemetrics, METH_VARARGS},
    128 #endif
    129     {"getstrwidth",     (PyCFunction)fh_getstrwidth, METH_VARARGS},
    130     {NULL,              NULL}           /* sentinel */
    131 };
    132 
    133 static PyObject *
    134 fh_getattr(fhobject *fhp, char *name)
    135 {
    136     return Py_FindMethod(fh_methods, (PyObject *)fhp, name);
    137 }
    138 
    139 static void
    140 fh_dealloc(fhobject *fhp)
    141 {
    142     fmfreefont(fhp->fh_fh);
    143     PyObject_Del(fhp);
    144 }
    145 
    146 static PyTypeObject Fhtype = {
    147     PyObject_HEAD_INIT(&PyType_Type)
    148     0,                                  /*ob_size*/
    149     "fm.font handle",                   /*tp_name*/
    150     sizeof(fhobject),                   /*tp_size*/
    151     0,                                  /*tp_itemsize*/
    152     /* methods */
    153     (destructor)fh_dealloc,             /*tp_dealloc*/
    154     0,                                  /*tp_print*/
    155     (getattrfunc)fh_getattr,            /*tp_getattr*/
    156     0,                                  /*tp_setattr*/
    157     0,                                  /*tp_compare*/
    158     0,                                  /*tp_repr*/
    159 };
    160 
    161 
    162 /* Font Manager functions */
    163 
    164 static PyObject *
    165 fm_init(PyObject *self)
    166 {
    167     fminit();
    168     Py_INCREF(Py_None);
    169     return Py_None;
    170 }
    171 
    172 static PyObject *
    173 fm_findfont(PyObject *self, PyObject *args)
    174 {
    175     char *str;
    176     if (!PyArg_ParseTuple(args, "s", &str))
    177         return NULL;
    178     return newfhobject(fmfindfont(str));
    179 }
    180 
    181 static PyObject *
    182 fm_prstr(PyObject *self, PyObject *args)
    183 {
    184     char *str;
    185     if (!PyArg_ParseTuple(args, "s", &str))
    186         return NULL;
    187     fmprstr(str);
    188     Py_INCREF(Py_None);
    189     return Py_None;
    190 }
    191 
    192 /* XXX This uses a global variable as temporary! Not re-entrant! */
    193 
    194 static PyObject *fontlist;
    195 
    196 static void
    197 clientproc(char *fontname)
    198 {
    199     int err;
    200     PyObject *v;
    201     if (fontlist == NULL)
    202         return;
    203     v = PyString_FromString(fontname);
    204     if (v == NULL)
    205         err = -1;
    206     else {
    207         err = PyList_Append(fontlist, v);
    208         Py_DECREF(v);
    209     }
    210     if (err != 0) {
    211         Py_DECREF(fontlist);
    212         fontlist = NULL;
    213     }
    214 }
    215 
    216 static PyObject *
    217 fm_enumerate(PyObject *self)
    218 {
    219     PyObject *res;
    220     fontlist = PyList_New(0);
    221     if (fontlist == NULL)
    222         return NULL;
    223     fmenumerate(clientproc);
    224     res = fontlist;
    225     fontlist = NULL;
    226     return res;
    227 }
    228 
    229 static PyObject *
    230 fm_setpath(PyObject *self, PyObject *args)
    231 {
    232     char *str;
    233     if (!PyArg_ParseTuple(args, "s", &str))
    234         return NULL;
    235     fmsetpath(str);
    236     Py_INCREF(Py_None);
    237     return Py_None;
    238 }
    239 
    240 static PyObject *
    241 fm_fontpath(PyObject *self)
    242 {
    243     return PyString_FromString(fmfontpath());
    244 }
    245 
    246 static PyMethodDef fm_methods[] = {
    247     {"init",            fm_init,      METH_NOARGS},
    248     {"findfont",        fm_findfont,  METH_VARARGS},
    249     {"enumerate",       fm_enumerate, METH_NOARGS},
    250     {"prstr",           fm_prstr,     METH_VARARGS},
    251     {"setpath",         fm_setpath,   METH_VARARGS},
    252     {"fontpath",        fm_fontpath,  METH_NOARGS},
    253     {NULL,              NULL}           /* sentinel */
    254 };
    255 
    256 
    257 void
    258 initfm(void)
    259 {
    260 
    261     if (PyErr_WarnPy3k("the fm module has been removed in "
    262                        "Python 3.0", 2) < 0)
    263     return;
    264 
    265     Py_InitModule("fm", fm_methods);
    266     if (m == NULL)
    267         return;
    268     fminit();
    269 }
    270