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