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