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 *
newfhobject(fmfonthandle fh)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 *
fh_scalefont(fhobject * self,PyObject * args)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 *
fh_setfont(fhobject * self)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 *
fh_getfontname(fhobject * self)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 *
fh_getcomment(fhobject * self)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 *
fh_getfontinfo(fhobject * self)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 *
fh_getstrwidth(fhobject * self,PyObject * args)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 *
fh_getattr(fhobject * fhp,char * name)134 fh_getattr(fhobject *fhp, char *name)
135 {
136 return Py_FindMethod(fh_methods, (PyObject *)fhp, name);
137 }
138
139 static void
fh_dealloc(fhobject * fhp)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 *
fm_init(PyObject * self)165 fm_init(PyObject *self)
166 {
167 fminit();
168 Py_INCREF(Py_None);
169 return Py_None;
170 }
171
172 static PyObject *
fm_findfont(PyObject * self,PyObject * args)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 *
fm_prstr(PyObject * self,PyObject * args)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
clientproc(char * fontname)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 *
fm_enumerate(PyObject * self)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 *
fm_setpath(PyObject * self,PyObject * args)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 *
fm_fontpath(PyObject * self)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
initfm(void)258 initfm(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