/* 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(); | |
} |