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 13typedef struct { 14 PyObject_HEAD 15 fmfonthandle fh_fh; 16} fhobject; 17 18static PyTypeObject Fhtype; 19 20#define is_fhobject(v) ((v)->ob_type == &Fhtype) 21 22static PyObject * 23newfhobject(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 40static PyObject * 41fh_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 51static PyObject * 52fh_setfont(fhobject *self) 53{ 54 fmsetfont(self->fh_fh); 55 Py_INCREF(Py_None); 56 return Py_None; 57} 58 59static PyObject * 60fh_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 72static PyObject * 73fh_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 85static PyObject * 86fh_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 105static PyObject * 106fh_getwholemetrics(fhobject *self, PyObject *args) 107{ 108} 109#endif 110 111static PyObject * 112fh_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 120static 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 133static PyObject * 134fh_getattr(fhobject *fhp, char *name) 135{ 136 return Py_FindMethod(fh_methods, (PyObject *)fhp, name); 137} 138 139static void 140fh_dealloc(fhobject *fhp) 141{ 142 fmfreefont(fhp->fh_fh); 143 PyObject_Del(fhp); 144} 145 146static 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 164static PyObject * 165fm_init(PyObject *self) 166{ 167 fminit(); 168 Py_INCREF(Py_None); 169 return Py_None; 170} 171 172static PyObject * 173fm_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 181static PyObject * 182fm_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 194static PyObject *fontlist; 195 196static void 197clientproc(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 216static PyObject * 217fm_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 229static PyObject * 230fm_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 240static PyObject * 241fm_fontpath(PyObject *self) 242{ 243 return PyString_FromString(fmfontpath()); 244} 245 246static 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 257void 258initfm(void) 259{ 260 if (PyErr_WarnPy3k("the fm module has been removed in " 261 "Python 3.0", 2) < 0) 262 return; 263 264 Py_InitModule("fm", fm_methods); 265 if (m == NULL) 266 return; 267 fminit(); 268} 269