/Modules/fmmodule.c

http://unladen-swallow.googlecode.com/ · C · 269 lines · 224 code · 38 blank · 7 comment · 25 complexity · c3365b25b42056c60f688d3dc3ac8e59 MD5 · raw file

  1. /* Font Manager module */
  2. #include "Python.h"
  3. #include <gl.h>
  4. #include <device.h>
  5. #include <fmclient.h>
  6. /* Font Handle object implementation */
  7. typedef struct {
  8. PyObject_HEAD
  9. fmfonthandle fh_fh;
  10. } fhobject;
  11. static PyTypeObject Fhtype;
  12. #define is_fhobject(v) ((v)->ob_type == &Fhtype)
  13. static PyObject *
  14. newfhobject(fmfonthandle fh)
  15. {
  16. fhobject *fhp;
  17. if (fh == NULL) {
  18. PyErr_SetString(PyExc_RuntimeError,
  19. "error creating new font handle");
  20. return NULL;
  21. }
  22. fhp = PyObject_New(fhobject, &Fhtype);
  23. if (fhp == NULL)
  24. return NULL;
  25. fhp->fh_fh = fh;
  26. return (PyObject *)fhp;
  27. }
  28. /* Font Handle methods */
  29. static PyObject *
  30. fh_scalefont(fhobject *self, PyObject *args)
  31. {
  32. double size;
  33. if (!PyArg_ParseTuple(args, "d", &size))
  34. return NULL;
  35. return newfhobject(fmscalefont(self->fh_fh, size));
  36. }
  37. /* XXX fmmakefont */
  38. static PyObject *
  39. fh_setfont(fhobject *self)
  40. {
  41. fmsetfont(self->fh_fh);
  42. Py_INCREF(Py_None);
  43. return Py_None;
  44. }
  45. static PyObject *
  46. fh_getfontname(fhobject *self)
  47. {
  48. char fontname[256];
  49. int len;
  50. len = fmgetfontname(self->fh_fh, sizeof fontname, fontname);
  51. if (len < 0) {
  52. PyErr_SetString(PyExc_RuntimeError, "error in fmgetfontname");
  53. return NULL;
  54. }
  55. return PyString_FromStringAndSize(fontname, len);
  56. }
  57. static PyObject *
  58. fh_getcomment(fhobject *self)
  59. {
  60. char comment[256];
  61. int len;
  62. len = fmgetcomment(self->fh_fh, sizeof comment, comment);
  63. if (len < 0) {
  64. PyErr_SetString(PyExc_RuntimeError, "error in fmgetcomment");
  65. return NULL;
  66. }
  67. return PyString_FromStringAndSize(comment, len);
  68. }
  69. static PyObject *
  70. fh_getfontinfo(fhobject *self)
  71. {
  72. fmfontinfo info;
  73. if (fmgetfontinfo(self->fh_fh, &info) < 0) {
  74. PyErr_SetString(PyExc_RuntimeError, "error in fmgetfontinfo");
  75. return NULL;
  76. }
  77. return Py_BuildValue("(llllllll)",
  78. info.printermatched,
  79. info.fixed_width,
  80. info.xorig,
  81. info.yorig,
  82. info.xsize,
  83. info.ysize,
  84. info.height,
  85. info.nglyphs);
  86. }
  87. #if 0
  88. static PyObject *
  89. fh_getwholemetrics(fhobject *self, PyObject *args)
  90. {
  91. }
  92. #endif
  93. static PyObject *
  94. fh_getstrwidth(fhobject *self, PyObject *args)
  95. {
  96. char *str;
  97. if (!PyArg_ParseTuple(args, "s", &str))
  98. return NULL;
  99. return PyInt_FromLong(fmgetstrwidth(self->fh_fh, str));
  100. }
  101. static PyMethodDef fh_methods[] = {
  102. {"scalefont", (PyCFunction)fh_scalefont, METH_VARARGS},
  103. {"setfont", (PyCFunction)fh_setfont, METH_NOARGS},
  104. {"getfontname", (PyCFunction)fh_getfontname, METH_NOARGS},
  105. {"getcomment", (PyCFunction)fh_getcomment, METH_NOARGS},
  106. {"getfontinfo", (PyCFunction)fh_getfontinfo, METH_NOARGS},
  107. #if 0
  108. {"getwholemetrics", (PyCFunction)fh_getwholemetrics, METH_VARARGS},
  109. #endif
  110. {"getstrwidth", (PyCFunction)fh_getstrwidth, METH_VARARGS},
  111. {NULL, NULL} /* sentinel */
  112. };
  113. static PyObject *
  114. fh_getattr(fhobject *fhp, char *name)
  115. {
  116. return Py_FindMethod(fh_methods, (PyObject *)fhp, name);
  117. }
  118. static void
  119. fh_dealloc(fhobject *fhp)
  120. {
  121. fmfreefont(fhp->fh_fh);
  122. PyObject_Del(fhp);
  123. }
  124. static PyTypeObject Fhtype = {
  125. PyObject_HEAD_INIT(&PyType_Type)
  126. 0, /*ob_size*/
  127. "fm.font handle", /*tp_name*/
  128. sizeof(fhobject), /*tp_size*/
  129. 0, /*tp_itemsize*/
  130. /* methods */
  131. (destructor)fh_dealloc, /*tp_dealloc*/
  132. 0, /*tp_print*/
  133. (getattrfunc)fh_getattr, /*tp_getattr*/
  134. 0, /*tp_setattr*/
  135. 0, /*tp_compare*/
  136. 0, /*tp_repr*/
  137. };
  138. /* Font Manager functions */
  139. static PyObject *
  140. fm_init(PyObject *self)
  141. {
  142. fminit();
  143. Py_INCREF(Py_None);
  144. return Py_None;
  145. }
  146. static PyObject *
  147. fm_findfont(PyObject *self, PyObject *args)
  148. {
  149. char *str;
  150. if (!PyArg_ParseTuple(args, "s", &str))
  151. return NULL;
  152. return newfhobject(fmfindfont(str));
  153. }
  154. static PyObject *
  155. fm_prstr(PyObject *self, PyObject *args)
  156. {
  157. char *str;
  158. if (!PyArg_ParseTuple(args, "s", &str))
  159. return NULL;
  160. fmprstr(str);
  161. Py_INCREF(Py_None);
  162. return Py_None;
  163. }
  164. /* XXX This uses a global variable as temporary! Not re-entrant! */
  165. static PyObject *fontlist;
  166. static void
  167. clientproc(char *fontname)
  168. {
  169. int err;
  170. PyObject *v;
  171. if (fontlist == NULL)
  172. return;
  173. v = PyString_FromString(fontname);
  174. if (v == NULL)
  175. err = -1;
  176. else {
  177. err = PyList_Append(fontlist, v);
  178. Py_DECREF(v);
  179. }
  180. if (err != 0) {
  181. Py_DECREF(fontlist);
  182. fontlist = NULL;
  183. }
  184. }
  185. static PyObject *
  186. fm_enumerate(PyObject *self)
  187. {
  188. PyObject *res;
  189. fontlist = PyList_New(0);
  190. if (fontlist == NULL)
  191. return NULL;
  192. fmenumerate(clientproc);
  193. res = fontlist;
  194. fontlist = NULL;
  195. return res;
  196. }
  197. static PyObject *
  198. fm_setpath(PyObject *self, PyObject *args)
  199. {
  200. char *str;
  201. if (!PyArg_ParseTuple(args, "s", &str))
  202. return NULL;
  203. fmsetpath(str);
  204. Py_INCREF(Py_None);
  205. return Py_None;
  206. }
  207. static PyObject *
  208. fm_fontpath(PyObject *self)
  209. {
  210. return PyString_FromString(fmfontpath());
  211. }
  212. static PyMethodDef fm_methods[] = {
  213. {"init", fm_init, METH_NOARGS},
  214. {"findfont", fm_findfont, METH_VARARGS},
  215. {"enumerate", fm_enumerate, METH_NOARGS},
  216. {"prstr", fm_prstr, METH_VARARGS},
  217. {"setpath", fm_setpath, METH_VARARGS},
  218. {"fontpath", fm_fontpath, METH_NOARGS},
  219. {NULL, NULL} /* sentinel */
  220. };
  221. void
  222. initfm(void)
  223. {
  224. if (PyErr_WarnPy3k("the fm module has been removed in "
  225. "Python 3.0", 2) < 0)
  226. return;
  227. Py_InitModule("fm", fm_methods);
  228. if (m == NULL)
  229. return;
  230. fminit();
  231. }